Конференция "WinAPI" » Про диски.
 
  • Anatoly Podgoretsky © (21.01.10 17:05) [40]
    > Игорь Шевченко  (21.01.2010 16:03:34)  [34]

    Но 2003 -> ХР все стабильно.
  • Игорь Шевченко © (21.01.10 17:33) [41]
    Sha ©   (21.01.10 16:59) [39]

    Я все понимаю, но ты тоже пойми, что никто в MS в здравом уме не будет писать, тестировать и документировать сценарии, как у большинства пользователей, как у меньшинства пользователей, как на сервере, как на рабочей станции, и все это для одного алгоритма копирования файлов. Вот размер блока менять - это вполне разумно, так как не требует больших затрат, кешированием варьировать - это тоже приемлемо, а разветвлять алгоритм на зависимость от информации, которая может быть потенциально недостоверна или на набор частных случаев - это вряд ли. Хотя это только мое предположение. Нет в API функции, возвращающей принадлежит ли пользователь к большинству или не принадлежит.
  • Игорь Шевченко © (21.01.10 17:34) [42]
    Anatoly Podgoretsky ©   (21.01.10 17:05) [40]


    > Но 2003 -> ХР все стабильно.


    Лучшее - враг хорошего :)
  • Sha © (21.01.10 17:48) [43]
    Игорь Шевченко ©   (21.01.10 17:33) [41]

    Тех рычагов, что ты перечислил, вполне достаточно, а чудо-функция эта без надобности.
  • OlegNik © (26.01.10 17:05) [44]
    Ну блин развели дебаты, мне индекс необходим, чтобы обратится к MBR
  • Riply © (27.01.10 00:28) [45]
    > [44] OlegNik ©   (26.01.10 17:05)
    > Ну блин развели дебаты, мне индекс необходим, чтобы обратится к MBR

    Хорошо. Давай тогда попробуем поизвращаться таким образом:

    function Zw_DeviceIoControlFile(const ObjHandle: THANDLE; const IoControlCode: ULONG; const pInBuffer: PVOID; const InBufferLength: ULONG;                                 const pOutBuffer: PVOID; const OutBufferLength: ULONG; const pBytesReturned: PULONG = nil): NTSTATUS;
    var
    IoBlock: IO_STATUS_BLOCK;
    begin
    Result := ZwDeviceIoControlFile(ObjHandle, 0, nil, nil, @IoBlock, IoControlCode, pInBuffer, InBufferLength, pOutBuffer, OutBufferLength);
    if Result = STATUS_PENDING then
     begin
      Result := ZwWaitForSingleObject(ObjHandle, False, nil);
      if NT_SUCCESS(Result) or (Result = STATUS_ACCESS_DENIED) then Result := IoBlock.Status;
     end;
    if pBytesReturned <> nil then pBytesReturned^ := IoBlock.Information;
    end;

    function IoCtrl_StorageGetDeviceNumberEx(const hStorage: THANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
    var
    BytesPerBuffer: ULONG;
    begin
    BytesPerBuffer := SizeOf(STORAGE_DEVICE_NUMBER);
    Result := Zw_DeviceIoControlFile(hStorage, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, pDeviceNumber, BytesPerBuffer, nil);
    end;

    function IoCtrl_StorageGetDeviceNumber(const puStorageName: PUNICODE_STRING; const phParent: PHANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
    var
    ObjAttr: OBJECT_ATTRIBUTES;
    IoBlock: IO_STATUS_BLOCK;
    hObjHandle: THANDLE;
    begin
    InitializeObjectAttributesKrnlObj(@ObjAttr, puStorageName, OBJ_CASE_INSENSITIVE, phParent, nil);
    Result := ZwOpenFile(@hObjHandle, READ_CONTROL, @ObjAttr, @IoBlock, FILE_SHARE_SH_ALL, FILE_NON_DIRECTORY_FILE);
    if NT_SUCCESS(Result) then
     try
      Result := IoCtrl_StorageGetDeviceNumberEx(hObjHandle, pDeviceNumber);
     finally
      ZwClose(hObjHandle);
     end;
    end;



    А теперь попробуем вызвать все это безобразие:
    procedure TDeveloperForm.SpeedButton1Click(Sender: TObject);
    var
    DeviceNumber: STORAGE_DEVICE_NUMBER;
    Us: UNICODE_STRING;
    RetStatus: NTSTATUS;
    begin
     inherited;
     FillChar(DeviceNumber, SizeOf(STORAGE_DEVICE_NUMBER), 0);
     RtlInitUnicodeString(@Us, '\??\I:');
     RetStatus := IoCtrl_StorageGetDeviceNumber(@Us, nil, @DeviceNumber);
     MessBox_Status(RetStatus, 'DeviceNumber: ' + IntToStr(DeviceNumber.DeviceNumber) + ' PartitionNumber: ' +     IntToStr(DeviceNumber.PartitionNumber));
    end;

  • Riply © (27.01.10 00:30) [46]
    >  [45] Riply ©   (27.01.10 00:28)
    Вот черт ! Все время форматирование куда-то убегает :(
    Sorry
  • brother © (27.01.10 04:32) [47]
    ругается на типы (PVOID итд), где они объявлены?
    зы D6
  • Riply © (27.01.10 05:40) [48]
    > [47] brother ©   (27.01.10 04:32)
    > ругается на типы (PVOID итд), где они объявлены?
    > зы D6

    Уууу. Под D6 тебе придется кучу всего вручную объявлять.
    Я бы, в этой ситуации, попробовала использовать jwaapi модули (у них там почти все есть).
  • brother © (27.01.10 07:44) [49]
    подключил почти все (JEDI API 2.3 and JEDI WSCL 0.9.3), но
    InitializeObjectAttributesKrnlObj


    и
    FILE_SHARE_SH_ALL


    не нашел, гугление отправляет на твои ответы :)
    где найти?
  • Riply © (27.01.10 17:51) [50]
    > [49] brother ©   (27.01.10 07:44)
    > InitializeObjectAttributesKrnlObj и FILE_SHARE_SH_ALL

    Забыла, Sorry.
    В нашем случае, InitializeObjectAttributesKrnlObj = InitializeObjectAttributes
    и
    const
    FILE_SHARE_SH_ALL = FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE;
  • brother © (28.01.10 05:38) [51]
    вот, что у меня получилось:
    uses
     ...  
     JwaWinType, JwaNative, JwaWinCred, JwaWinIoctl,
     ...

    function Zw_DeviceIoControlFile(const ObjHandle: THANDLE; const IoControlCode: ULONG; const pInBuffer: PVOID; const InBufferLength: ULONG;                                 const pOutBuffer: PVOID; const OutBufferLength: ULONG; const pBytesReturned: PULONG = nil): NTSTATUS;
    var
    IoBlock: IO_STATUS_BLOCK;
    begin
    Result := ZwDeviceIoControlFile(ObjHandle, 0, nil, nil, @IoBlock, IoControlCode, pInBuffer, InBufferLength, pOutBuffer, OutBufferLength);
    if Result = STATUS_PENDING then
    begin
     Result := ZwWaitForSingleObject(ObjHandle, False, nil);
     if NT_SUCCESS(Result) or (Result = STATUS_ACCESS_DENIED) then Result := IoBlock.Status;
    end;
    if pBytesReturned <> nil then pBytesReturned^ := IoBlock.Information;
    end;

    function IoCtrl_StorageGetDeviceNumberEx(const hStorage: THANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
    var
    BytesPerBuffer: ULONG;
    begin
    BytesPerBuffer := SizeOf(STORAGE_DEVICE_NUMBER);
    Result := Zw_DeviceIoControlFile(hStorage, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, pDeviceNumber, BytesPerBuffer, nil);
    end;

    function IoCtrl_StorageGetDeviceNumberEx(const hStorage: THANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
    var
    BytesPerBuffer: ULONG;
    begin
    BytesPerBuffer := SizeOf(STORAGE_DEVICE_NUMBER);
    Result := Zw_DeviceIoControlFile(hStorage, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, pDeviceNumber, BytesPerBuffer, nil);
    end;

    function IoCtrl_StorageGetDeviceNumber(const puStorageName: PUNICODE_STRING; const phParent: HANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
    var
    ObjAttr: OBJECT_ATTRIBUTES;
    IoBlock: IO_STATUS_BLOCK;
    hObjHandle: THANDLE;
    begin
    InitializeObjectAttributes(@ObjAttr, puStorageName, OBJ_CASE_INSENSITIVE, phParent, nil);
    Result := ZwOpenFile(@hObjHandle, READ_CONTROL, @ObjAttr, @IoBlock, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE);
    if NT_SUCCESS(Result) then
    try
     Result := IoCtrl_StorageGetDeviceNumberEx(hObjHandle, pDeviceNumber);
    finally
     ZwClose(hObjHandle);
    end;
    end;
    ...
    procedure TForm1.Button1Click(Sender: TObject);
    var
    DeviceNumber: STORAGE_DEVICE_NUMBER;
    Us: UNICODE_STRING;
    RetStatus: NTSTATUS;
    begin
    inherited;
    FillChar(DeviceNumber, SizeOf(STORAGE_DEVICE_NUMBER), 0);
    RtlInitUnicodeString(@Us, '\??\C:');
    RetStatus := IoCtrl_StorageGetDeviceNumber(@Us, 0, @DeviceNumber);
    Memo1.Lines.Add( 'DeviceNumber: ' + IntToStr(DeviceNumber.DeviceNumber) + ' PartitionNumber: ' +     IntToStr(DeviceNumber.PartitionNumber));
    end;


    Рипли, поправь, если где не верно, но вроде показывает данные корректно...
  • Riply © (28.01.10 06:42) [52]
    > [51] brother ©   (28.01.10 05:38)
    > Рипли, поправь, если где не верно, но вроде показывает данные корректно...

    Ну, я могу, только внешне посмотреть, ибо нет у меня Jwa.
    А дважды опредеять ф-ию IoCtrl_StorageGetDeviceNumberEx эт обязатнльно ? :)

    Тут есть один момент, с которым я еще не разобралась как поступить:
    С одной стороны, хочется открывать диск с минимальными правами (в нашем случае READ_CONTROL),
    но тогда нам их не хватает на ZwWaitForSingleObject и приходится ставить заплатку (Result = STATUS_ACCESS_DENIED).
    Можно повысить запрашиваемые права, но тогда мы рискуем не всегда иметь возможность получить данные.
    Тут подумать надо как быть.
  • brother © (28.01.10 07:00) [53]
    > А дважды опредеять ф-ию IoCtrl_StorageGetDeviceNumberEx
    > эт обязатнльно ? :)

    перекопипастил ;)

    > Тут подумать надо как быть.

    если, что - постучись в личку...
  • OlegNik © (29.01.10 14:04) [54]
    Riply золото, спасибо реально работает.
  • имя (21.09.12 01:00) [55]
    Удалено модератором
  • имя (21.09.12 01:00) [56]
    Удалено модератором
  • имя (21.09.12 01:00) [57]
    Удалено модератором
  • имя (21.09.12 01:00) [58]
    Удалено модератором
  • Rouse_ © (21.09.12 01:41) [59]
    Товаришь с апишником 193.203.48.16, таки шо вам там не спится?
 
Конференция "WinAPI" » Про диски.
Есть новые Нет новых   [134430   +3][b:0][p:0.003]