Цитата(developer2007 @ 3.5.2009, 21:09 ) | | Хм, нечто воцарилась ненормальная тишина и покой |
А что ты ожидал, если задаешь, в сущности, один и тот же вопрос, причем и палец о палец не ударив, чтобы его хотя бы грамотно сформулировать. Достаточно было посмотреть Help к данной команде и там черным по белому на чистейшем буржуинском  написано что "надо открывать". Плюс к этому дается целая куча функций типа: FindFirstPartition, FindFirstVolume, FindFirstVolumeMountPoint, FindFirstDevice и иже с ними. Выбирай ту, что тебе нужна и вперед. Там и примеры для них есть.
Ну да ладно. "Дело было вечером - делать было нечего"  Посему набросала небольшой пример. Сразу оговариваюсь: писалось "на коленке", серьезно не тестировалось (работает и ладно, ибо ленивая я очень) И, разумеется это не единственный путь решения данной задачи.
| Код | type PNAMED_GUID = ^_NAMED_GUID; _NAMED_GUID = packed record _Guid: TGUID; NameU: UNICODE_STRING; end;
type TCheckGUID_CallBack = function(const pCheckGUID: PGUID): ULONG; TEnumDevDescrip_CallBack = function(const pStgDescript: PSTORAGE_DEVICE_DESCRIPTOR; const Status: NTSTATUS): NTSTATUS;
const //_Floppy Disk Drives _FloppyDisk = 'FloppyDisk'; SysClassGuid_FloppyDisk: _NAMED_GUID = (_Guid: '{4d36e980-e325-11ce-bfc1-08002be10318}'; NameU: (Length: Length(_FloppyDisk) shl SHR_WCHAR; MaximumLength: Length(_FloppyDisk) shl SHR_WCHAR + SizeOf(WideChar); Buffer: _FloppyDisk)); // This class includes floppy disk drives.
//_CD-ROM Drives _CDROM = 'CDROM'; // CDROM SysClassGuid_CDROM: _NAMED_GUID = (_Guid: '{4d36e965-e325-11ce-bfc1-08002be10318}'; NameU: (Length: Length(_CDROM) shl SHR_WCHAR; MaximumLength: Length(_CDROM) shl SHR_WCHAR + SizeOf(WideChar); Buffer: _CDROM)); // This class includes CD-ROM drives, including SCSI CD-ROM drives. By default, the system's CD-ROM class installer also installs a system-supplied CD audio driver and CD-ROM changer driver as Plug and Play filters.
//_Disk Drives _DiskDrive = 'DiskDrive'; // DiskDrive SysClassGuid_DiskDrive: _NAMED_GUID = (_Guid: '{4d36e967-e325-11ce-bfc1-08002be10318}'; NameU: (Length: Length(_DiskDrive) shl SHR_WCHAR; MaximumLength: Length(_DiskDrive) shl SHR_WCHAR + SizeOf(WideChar); Buffer: _DiskDrive)); // This class includes hard disk drives. See also the HDC and SCSIAdapter classes.
const DeviceClassFS: array[0..2] of PNAMED_GUID = (@SysClassGuid_CDROM, @SysClassGuid_DiskDrive, @SysClassGuid_FloppyDisk);
DEVICE_DESCRIPTOR_INC = 512 - SizeOf(STORAGE_DEVICE_DESCRIPTOR);
function StorageQueryPropertyEx(const ObjHandle: THANDLE; const pPropQuery: PSTORAGE_PROPERTY_QUERY; const BytesPerQuery: ULONG; var pStgDevDescript: PVOID; var BytesPerStgDevDescript: ULONG): NTSTATUS; var BytesReturn: ULONG; begin if BytesPerStgDevDescript < SizeOf(STORAGE_DESCRIPTOR_HEADER) then begin BytesPerStgDevDescript := SizeOf(STORAGE_DESCRIPTOR_HEADER);// + DEVICE_DESCRIPTOR_INC; ReallocMem(pStgDevDescript, BytesPerStgDevDescript); end; Result := Zw_DeviceIoControlFile(ObjHandle, IOCTL_STORAGE_QUERY_PROPERTY, pPropQuery, BytesPerQuery, pStgDevDescript, BytesPerStgDevDescript, @BytesReturn); if NT_SUCCESS(Result) and (BytesReturn >= SizeOf(STORAGE_DESCRIPTOR_HEADER)) then with PSTORAGE_DESCRIPTOR_HEADER(pStgDevDescript)^ do if Size >= BytesReturn then begin BytesPerStgDevDescript := ROUND_UP64(Size); ReallocMem(pStgDevDescript, BytesPerStgDevDescript); Result := Zw_DeviceIoControlFile(ObjHandle, IOCTL_STORAGE_QUERY_PROPERTY, pPropQuery, BytesPerQuery, pStgDevDescript, BytesPerStgDevDescript, @BytesReturn); end; end;
function StorageQueryProperty(const ObjHandle: THANDLE; var pStgDevDescript: PVOID; var BytesPerStgDevDescript: ULONG): NTSTATUS; var PropQuery: STORAGE_PROPERTY_QUERY; begin RtlZero(@PropQuery, SizeOf(STORAGE_PROPERTY_QUERY)); PropQuery.PropertyId := StorageDeviceProperty; PropQuery.QueryType := PropertyStandardQuery; Result := StorageQueryPropertyEx(ObjHandle, @PropQuery, SizeOf(STORAGE_PROPERTY_QUERY), pStgDevDescript, BytesPerStgDevDescript); end;
function StorageQueryPropertyByDevName(const pDevName: PUNICODE_STRING; var pStgDevDescript: PVOID; var BytesPerStgDevDescript: ULONG): NTSTATUS; var ObjAttr: OBJECT_ATTRIBUTES; IoBlock: IO_STATUS_BLOCK; hObject: THANDLE; begin InitializeObjectAttributesKrnlObj(@ObjAttr, pDevName, OBJ_CASE_INSENSITIVE, nil, nil); Result := ZwOpenFile(@hObject, READ_CONTROL, @ObjAttr, @IoBlock, FILE_SHARE_SH_ALL, FILE_NON_DIRECTORY_FILE); if NT_SUCCESS(Result) then try Result := StorageQueryProperty(hObject, pStgDevDescript, BytesPerStgDevDescript); finally ZwClose(hObject); end; end;
function SetupDiGetDeviceRegistryPropertyMemW(const DeviceInfoSet: HDEVINFO; const DeviceInfoData: TSPDevInfoData; const PropertyCode: ULONG; var PropertyRegDataType: ULONG; var pBuffer: PVOID; var cbBufferSize, RequiredSize: ULONG): ULONG; begin RequiredSize := 0; if not SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, PropertyCode, PropertyRegDataType, pBuffer, cbBufferSize, RequiredSize) then begin Result := GetLastError; case Result of ERROR_INSUFFICIENT_BUFFER: begin Assert(RequiredSize > cbBufferSize, 'RequiredSize > cbBufferSize'); cbBufferSize := RequiredSize; ReallocMem(pBuffer, cbBufferSize); if SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, PropertyCode, PropertyRegDataType, pBuffer, cbBufferSize, RequiredSize) then Result := ERROR_SUCCESS else Result := GetLastError; end; end; end else Result := ERROR_SUCCESS; end;
function EnumDevicesDescriptors(const hSysDevices: HDEVINFO; const CheckGUID: TCheckGUID_CallBack; const EnumDevDescrip_CallBack: TEnumDevDescrip_CallBack): ULONG; const AVERAGE_DEVICE_INFO_SIZE = 512; var Index, cbDataType: DWORD; DeviceInfoData: SP_DEVINFO_DATA; pBuffer, pStgDevDescript: PVOID; BytesPerBuffer, BytesRequired, BytesPerStgDevDescript: ULONG; Us: UNICODE_STRING; RetStatus: NTSTATUS; begin Result := ERROR_SERVICE_NOT_FOUND; BytesPerBuffer := AVERAGE_DEVICE_INFO_SIZE; pBuffer := GetMemory(BytesPerBuffer); if pBuffer <> nil then try Index := 0; BytesPerStgDevDescript := 0; pStgDevDescript := nil; RtlZero(@DeviceInfoData, SizeOf(SP_DEVINFO_DATA)); DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA); while SetupDiEnumDeviceInfo(hSysDevices, Index, DeviceInfoData) do begin if CheckGUID(@DeviceInfoData.ClassGuid) <> FILE_DEVICE_ERROR then begin Result := SetupDiGetDeviceRegistryPropertyMemW(hSysDevices, DeviceInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, cbDataType, pBuffer, BytesPerBuffer, BytesRequired); if Result = ERROR_SUCCESS then begin Us_InitLen_(@Us, pBuffer, BytesRequired); Us_TrimRight(@Us); RetStatus := StorageQueryPropertyByDevName(@Us, pStgDevDescript, BytesPerStgDevDescript); if not NT_SUCCESS(EnumDevDescrip_CallBack(pStgDevDescript, RetStatus)) then Break; end end; Inc(Index); end; finally ReallocMem(pStgDevDescript, 0); ReallocMem(pBuffer, 0); end else Result := ERROR_NO_SYSTEM_RESOURCES; end;
function EnumDevDescriptorsByClass(const Flag: ULONG; const CheckGUID: TCheckGUID_CallBack; const EnumDevDescrip_CallBack: TEnumDevDescrip_CallBack): ULONG; var hSysDevices: HDEVINFO; begin hSysDevices := SetupDiGetClassDevsExW(nil, nil, 0, Flag, nil, nil, nil); if hSysDevices <> PINVALID_HANDLE_VALUE then try Result := EnumDevicesDescriptors(hSysDevices, CheckGUID, EnumDevDescrip_CallBack); finally SetupDiDestroyDeviceInfoList(hSysDevices); end else Result := GetLastError; end;
function Int128_IsEqual(const pFirst, pSecond: PVOID): BOOLEAN; inline; begin Result := (PInt64(pFirst)^ = PInt64(pSecond)^) and (PInt64(IncPtr(pFirst, SizeOf(Int64)))^ = PInt64(IncPtr(pSecond, SizeOf(Int64)))^); end;
function IsGUID_FS(const pCheckGUID: PGUID): ULONG; var i: integer; begin for i := Low(DeviceClassFS) to High(DeviceClassFS) do if Int128_IsEqual(@DeviceClassFS[i]._Guid, pCheckGUID) then begin if i = 0 then Result := FILE_DEVICE_CD_ROM else if i = 1 then Result := FILE_DEVICE_DISK else if i = 2 then Result := FILE_DEVICE_FLOPPY else Result := FILE_DEVICE_ERROR; Exit; end; Result := FILE_DEVICE_ERROR; end;
function EnumDevDescrip_CallBack(const pStgDescript: PSTORAGE_DEVICE_DESCRIPTOR; const Status: NTSTATUS): NTSTATUS; begin Result := STATUS_SUCCESS; if NT_SUCCESS(Status) then with pStgDescript^ do if ProductIdOffset > 0 then MessBox_Inf(PAnsiChar(IncPtr(pStgDescript, ProductIdOffset))) else else MessBox_Inf(SysErrorMessage(RtlNtStatusToDosError(Status))); end;
function CallEnumDevDescrip(): ULONG; begin Result := EnumDevDescriptorsByClass(DIGCF_ALLCLASSES or DIGCF_DEVICEINTERFACE or DIGCF_PRESENT, IsGUID_FS, EnumDevDescrip_CallBack); end;
|
P.S. В примере используется несколько простейших собственнолапных ф-ий (например IncPtr). Распишешь их сам (по смыслу понятно что они делают) |