Текущий архив: 2007.06.24;
Скачать: CL | DM;
Вниз
Установка "правильного" размера для структур из С++. Найти похожие ветки
← →
Riply © (2007-06-02 10:28) [0]Здравствуйте !
Взяла из заголовочных файлов определения следующих структур:typedef enum _STORAGE_BUS_TYPE {
BusTypeUnknown = 0x00,
BusTypeScsi,
BusTypeAtapi,
BusTypeAta,
BusType1394,
BusTypeSsa,
BusTypeFibre,
BusTypeUsb,
BusTypeRAID,
BusTypeMaxReserved = 0x7F
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0, // Retrieves the descriptor
PropertyExistsQuery, // Used to test whether the descriptor is supported
PropertyMaskQuery, // Used to retrieve a mask of writeable fields in the descriptor
PropertyQueryMaxDefined // use to validate the value
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
typedef enum _STORAGE_PROPERTY_ID {
StorageDeviceProperty = 0,
StorageAdapterProperty,
StorageDeviceIdProperty
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
и попробовала перевести их на "человеческий язык" :)
Вот что получилось:type
PSTORAGE_BUS_TYPE = ^STORAGE_BUS_TYPE;
_STORAGE_BUS_TYPE = (BusTypeUnknown = 0, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394,
BusTypeSsa, BusTypeFibre, BusTypeUsb, BusTypeRAID, BusTypeiScsi,
BusTypeSas, BusTypeSata, BusTypeMaxReserved = $7F);
STORAGE_BUS_TYPE = _STORAGE_BUS_TYPE;
type
PSTORAGE_QUERY_TYPE = ^STORAGE_QUERY_TYPE;
_STORAGE_QUERY_TYPE = (PropertyStandardQuery = 0, PropertyExistsQuery,
PropertyMaskQuery, PropertyQueryMaxDefined);
STORAGE_QUERY_TYPE = _STORAGE_QUERY_TYPE;
type
PSTORAGE_PROPERTY_ID = ^STORAGE_PROPERTY_ID;
_STORAGE_PROPERTY_ID = (StorageDeviceProperty = 0, StorageAdapterProperty, StorageDeviceIdProperty);
STORAGE_PROPERTY_ID = _STORAGE_PROPERTY_ID;
type
PSTORAGE_PROPERTY_QUERY = ^STORAGE_PROPERTY_QUERY;
_STORAGE_PROPERTY_QUERY = packed record
PropertyId: STORAGE_PROPERTY_ID;
QueryType: STORAGE_QUERY_TYPE;
AdditionalParameters: array[0..0] of Char;
end;
STORAGE_PROPERTY_QUERY = _STORAGE_PROPERTY_QUERY;
Проблема в следующем:
при передаче их в DeviceIoControl,
например, так:
DeviceIoControl(hDevice, cbIoControlCode, STORAGE_PROPERTY_QUERY, SizeOf(STORAGE_PROPERTY_QUERY)....
Получаем ошибку: INVALID_PARAMETR
Методом "научного тыка" выясняем, что ей не нравится SizeOf(STORAGE_PROPERTY_QUERY) = 3,
а ее, видите ли, подавай 12 :)
Если переопределить
_STORAGE_PROPERTY_QUERY = packed record
PropertyId: STORAGE_PROPERTY_ID;
QueryType: STORAGE_QUERY_TYPE;
AdditionalParameters: array[0..9] of Char;
end;
то все проходит. Но это уж слишком некузяво !
Подскажите, пожалуйста, как сохранить структуру в девственном(ну, почти(?)) виде,
так, чтобы ее размер стал "правильным" ? :)
P.S.
Далее в определении других структур используются эти,
и если что не так с размером, то они исказяться.
← →
Riply © (2007-06-02 10:36) [1]P.P.S.
Может я, просто, неправильно перевела ?
← →
Однокамушкин (2007-06-02 10:40) [2]Во-первых, не вижу исходного описания STORAGE_PROPERTY_QUERY на C++, сравнивать не с чем... во-вторых, это всё-таки имя типа или переменной? а то непонятно вот что:
> DeviceIoControl(hDevice, cbIoControlCode, STORAGE_PROPERTY_QUERY,
> SizeOf(STORAGE_PROPERTY_QUERY)
Второй параметр, наверное должен быть переменной, а не типом...
← →
Riply © (2007-06-02 10:58) [3]>[2] Однокамушкин (02.06.07 10:40)
>Во-первых, не вижу исходного описания STORAGE_PROPERTY_QUERY на C++, сравнивать не с чем...
Sorry, забыла. Вот:typedef struct _STORAGE_PROPERTY_QUERY {
STORAGE_PROPERTY_ID PropertyId; // ID of the property being retrieved
STORAGE_QUERY_TYPE QueryType; // Flags indicating the type of query being performed
UCHAR AdditionalParameters[1]; // Space for additional parameters if necessary
>во-вторых, это всё-таки имя типа или переменной? а то непонятно вот что:
>Второй параметр, наверное должен быть переменной, а не типом...
Да, там переменная StorageProp: _STORAGE_PROPERTY_QUERY;FillChar(StorageProp, SizeOf(STORAGE_PROPERTY_QUERY), 0);
DeviceIoControl(hDevice, cbIoControlCode, @StorageProp, SizeOf(STORAGE_PROPERTY_QUERY)....
← →
Riply © (2007-06-02 11:07) [4]>[3] Riply © (02.06.07 10:58)
Одна строчка куда-то потеряласьtypedef struct _STORAGE_PROPERTY_QUERY {
STORAGE_PROPERTY_ID PropertyId; // ID of the property being retrieved
STORAGE_QUERY_TYPE QueryType; // Flags indicating the type of query being performed
UCHAR AdditionalParameters[1]; // Space for additional parameters if necessary
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
← →
Однокамушкин (2007-06-02 11:07) [5]Ага, знаком с такими структурами... суть в том, что для таких структур память никогда не выделяется в стеке, она выделяется динамически... и каждый раз - ровно столько, сколько надо для данного конкретного вызова, а не столько, сколько занимает структура согласно объявлению... а потом массив заполняют, пользуясь тем, что в C++ нет никакого контроля за попаданием индекса в диапазон... вам надо поступать примерно так же... ну а то, что надо не меньше 12 байт - возможно, с теми параметрами, которые вы передаёте, так и должно быть, а с другими это число может быть как меньше, так и больше...
← →
Riply © (2007-06-02 11:21) [6]>[5] Однокамушкин (02.06.07 11:07)
Да, но потом идет такое:PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR;
_STORAGE_DEVICE_DESCRIPTOR = packed record
Version: DWord;
Size: DWord;
DeviceType: Char;
DeviceTypeModifier: Char;
RemovableMedia: Boolean;
CommandQueueing: Boolean;
VendorIdOffset: DWord;
ProductIdOffset: DWord;
ProductRevisionOffset: DWord;
SerialNumberOffset: DWord;
BusType: STORAGE_BUS_TYPE;
RawPropertiesLength: DWord;
RawDeviceProperties: array[0..0] of Char;
end;
STORAGE_DEVICE_DESCRIPTOR = _STORAGE_DEVICE_DESCRIPTOR;
Здесь какой размер должен быть у BusType ? SizeOf(Byte) или SizeOf(DWord) ?
>что в C++ нет никакого контроля за попаданием индекса в
>диапазон... вам надо поступать примерно так же...
Не понимаю :(
Допустим, вызванная нами ф-ия заполняет STORAGE_PROPERTY_QUERY
Первое значение она записывает по адресу PropertyId, а следующее(QueryType)
по какому ? DWord(@PropertyId) + SizeOf(Что) ?
← →
Однокамушкин (2007-06-02 11:31) [7]Не, если такая структура потом засовывается внутрь другой структуры, я тоже ничего не понимаю... самое лучшее, если у вас есть код на C++ по использованию всего этого хозяйства, который можно взять за образец...
а так, я имел ввиду примерно следующее...STORAGE_PROPERY_QUERY* p = malloc(<сколько надо>);
// Теперь, если памяти выделено достаточно, можно писать так:
p->AdditionalParameters[10] = 23;
Хотя в AdditionalParameters, согласно объявлению, всего 1 элемент, можно обращаться к любому, т.к. компилятор не следит за индексами... сам массив расположен сразу после основной части структуры...
А вот если SOTRAGE_BUS_TYPE засунута в середину другой структуры, тут всё совсем непонятно, потому что получается, что этот массив должен располагаться в той же области памяти, что следующие поля, т.е. RawPropertiesLength и RawDeviceLength... не знаю, может это особая задумка авторов библиотеки, чтобы в данном случае можно было к одной и той же памяти обращаться то как к массиву, то как к таким полям, нечто вроде union"а, одним словом... но тогда надо учесть, что формально в STORAGE_DEVICE_DESCRIPTOR после BusType идёт 5 байт, а вам надо как минимум 9, а значит, для STORAGE_DEVICE_DESCRIPTOR надо выделять память по тому же принципу...
но ещё раз повторяю, что это только догадки, а точный ответ надо искать в доках или в примерах...
← →
Riply © (2007-06-02 13:22) [8]С перечисляемыми типами, вроде, нашла выход: {$MINIMUMESIZE +4}
Но дальше...
"Будь проклят тот день, когда я впервые села за баранку этого пылесоса !" :)
(с) "Кавказкая пленница"
Страницы: 1 вся ветка
Текущий архив: 2007.06.24;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.034 c