Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Извлечь раздробленный HDD 
V
    Опции темы
Artem148
Дата 19.5.2011, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Постоялец
*


Профиль
Группа: Участник
Сообщений: 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
PM MAIL WWW   Вверх
MetalFan
Дата 20.5.2011, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



а что значит "некорректно работает"? ошибки выдает или как? отладка не помогает?

Код конечно "на высоте"...
Шедевр прям таки:
Цитата(Artem148 @  19.5.2011,  20:09 Найти цитируемый пост)
($0000002D shl 16)or
      ($00000000 shl 14)or($0420 shl 2)or $00000000





--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Artem148
Дата 20.5.2011, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Постоялец
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 18.2.2011

Репутация: нет
Всего: нет



Вылазиет сообщение: "Диск используется, ещё... пытайтесь позже" - хотя диск совершено пуст и ни одна программа его не использует
PM MAIL WWW   Вверх
EndErr
Дата 21.5.2011, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 9.12.2007

Репутация: нет
Всего: нет



Попрбуй Unlocker-ом посмотреть кто использует диск в этот момент.
У меня случалось что SYSTEM использовал $MFT в момент отключения.
PM MAIL   Вверх
Artem148
Дата 22.5.2011, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Постоялец
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 18.2.2011

Репутация: нет
Всего: нет



to EndErr: ни одна программа его не использует - ошибочка, поспешил сумничать  smile 

P.S: 1) это был explorer(при том ни одно обращение к диску), и запушен он был от системы.
       2) Не сочтите за наглость(  smile  ): Как этот код привести к компактному и цивильному виду?
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0473 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.