
Постоялец

Профиль
Группа: Участник
Сообщений: 56
Регистрация: 18.2.2011
Репутация: нет Всего: нет
|
Привет! Проблема: Код для извлечения флешки(представлен ниже) не корректно работает с внешним HDD( если HDD раздроблен) Вопрос: В чём косячок? Заранее спасибо! | Код | const GUID_DEVINTERFACE_DISK: TGUID=( D1: $53F56307; D2: $B6BF; D3: $11D0; D4: ($94, $F2, $00, $A0, $C9, $1E, $FB, $8B));
type TStorageDeviceNumber=packed record DeviceType: DWORD; DeviceNumber: DWORD; PartitionNumber: DWORD; end;
type PSPDevInfoData=^SP_DEVINFO_DATA; //TSPDevInfoData; SP_DEVINFO_DATA=packed record cbSize: DWORD; ClassGuid: TGUID; DevInst: DWORD; // DEVINST handle Reserved: ULONG_PTR; end;
PSPDeviceInterfaceData=^TSPDeviceInterfaceData; SP_DEVICE_INTERFACE_DATA=packed record cbSize: DWORD; InterfaceClassGuid: TGUID; Flags: DWORD; Reserved: ULONG_PTR; end; TSPDeviceInterfaceData=SP_DEVICE_INTERFACE_DATA;
PSPDeviceInterfaceDetailDataA=^TSPDeviceInterfaceDetailDataA; PSPDeviceInterfaceDetailData=PSPDeviceInterfaceDetailDataA; SP_DEVICE_INTERFACE_DETAIL_DATA_A=packed record cbSize: DWORD; DevicePath: array[0..1024-1] of AnsiChar; end; TSPDeviceInterfaceDetailDataA=SP_DEVICE_INTERFACE_DETAIL_DATA_A; TSPDeviceInterfaceDetailData=TSPDeviceInterfaceDetailDataA;
function SetupDiGetClassDevsA(ClassGuid: PGUID; const Enumerator: PAnsiChar; hwndParent: HWND; Flags: DWORD): THandle; stdcall; external'SetupApi.dll';
function SetupDiDestroyDeviceInfoList( DeviceInfoSet: THandle): LongBool; stdcall; external'SetupApi.dll';
function SetupDiEnumDeviceInterfaces(DeviceInfoSet: THandle; DeviceInfoData: PSPDevInfoData; const InterfaceClassGuid: TGUID; MemberIndex: DWORD; var DeviceInterfaceData: TSPDeviceInterfaceData): LongBool; stdcall; external'SetupApi.dll';
function SetupDiGetDeviceInterfaceDetailA(DeviceInfoSet: THandle; DeviceInterfaceData: PSPDeviceInterfaceData; DeviceInterfaceDetailData: PSPDeviceInterfaceDetailDataA; DeviceInterfaceDetailDataSize: DWORD; var RequiredSize: DWORD; Device: PSPDevInfoData): LongBool; stdcall; external'SetupApi.dll';
function CM_Get_Parent(var dnDevInstParent: DWORD; dnDevInst: DWORD; ulFlags: ULONG): DWORD; stdcall; external'cfgmgr32.dll';
function CM_Request_Device_EjectA(dnDevInst: DWORD; pVetoType: DWORD; pszVetoName: PWideChar; ulNameLength: ULONG; ulFlags: ULONG): DWORD; stdcall; external'SetupApi.dll';
function GetTempDir: string; var Buffer: array[0..1023] of Char; begin SetString(Result, Buffer, GetTempPath(SizeOf(Buffer), Buffer)); end;
function NormalDir(const DirName: string): string; begin Result := DirName; if (Result <> '') and not (AnsiLastChar(Result)^ in ['\']) then Result := Result + '\'; end;
function RemoveFlash(const Value: PChar): Boolean; var hFile, hDevInfo, hDrive, hDevInstance, hDevInstanceParent: THandle; sdn: TStorageDeviceNumber; dwDeviceNumber, dwBytesReturned, dwSize: DWORD; FlashGuid: TGUID; I: Integer; DeviceInfoData: SP_DEVINFO_DATA; DeviceInterfaceData: TSPDeviceInterfaceData; DeviceInterfaceDetailData: TSPDeviceInterfaceDetailData; nTryLockCount: Integer; begin Result := False;
hDevInstance := INVALID_HANDLE_VALUE;
hFile := CreateFile(PChar('\\.\' + Value), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hFile=INVALID_HANDLE_VALUE then begin Exit; end; try if not DeviceIoControl(hFile, ($0000002D shl 16)or ($00000000 shl 14)or($0420 shl 2)or $00000000, nil, 0, @sdn, SizeOf(TStorageDeviceNumber), dwBytesReturned, nil) then begin Exit; end; dwDeviceNumber := sdn.DeviceNumber; FlashGuid := GUID_DEVINTERFACE_DISK; hDevInfo := SetupDiGetClassDevsA(@FlashGuid, nil, 0, $00000002 or $00000010); if hDevInfo=INVALID_HANDLE_VALUE then begin Exit; end; try I := 0; DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData); while SetupDiEnumDeviceInterfaces( hDevInfo, nil, FlashGuid, I, DeviceInterfaceData) do begin
Inc(I); SetupDiGetDeviceInterfaceDetailA(hDevInfo, @DeviceInterfaceData, nil, 0, dwSize, nil); if dwSize=0 then begin Exit; end;
DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA); DeviceInterfaceDetailData.cbSize := 5; if not SetupDiGetDeviceInterfaceDetailA(hDevInfo, @DeviceInterfaceData, @DeviceInterfaceDetailData, dwSize, dwSize, @DeviceInfoData) then begin Exit; end; hDrive := CreateFile(PChar(@DeviceInterfaceDetailData.DevicePath[0]), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if hFile=INVALID_HANDLE_VALUE then begin Exit; end; try if not DeviceIoControl(hDrive, ($0000002D shl 16)or($00000000 shl 14)or($0420 shl 2)or $00000000, nil, 0, @sdn, SizeOf(TStorageDeviceNumber), dwBytesReturned, nil) then begin Exit; end; if sdn.DeviceNumber=dwDeviceNumber then begin hDevInstance := DeviceInfoData.DevInst; Break; end;
finally CloseHandle(hDrive); end; end; finally SetupDiDestroyDeviceInfoList(hDevInfo); end; finally CloseHandle(hFile); end; if hDevInstance <> INVALID_HANDLE_VALUE then begin if CM_Get_Parent(hDevInstanceParent, hDevInstance, 0) <> 0 then begin Exit; end;
nTryLockCount := 0; while nTryLockCount < 5 do begin if CM_Request_Device_EjectA( hDevInstanceParent, Cardinal(nil), nil, 0, 0) = 0 then Break; Inc(nTryLockCount); end; if nTryLockCount = 5 then begin Exit; end else Result := True; end; end;
|
P.S Относительно кода: Я знаю, что представленый вариант не самый лучший, НО... - но он работает (и только с флешкой) ! Это сообщение отредактировал(а) Artem148 - 19.5.2011, 20:11
|