-
> Игорь Шевченко (21.01.2010 16:03:34) [34]
Но 2003 -> ХР все стабильно.
-
Sha © (21.01.10 16:59) [39]
Я все понимаю, но ты тоже пойми, что никто в MS в здравом уме не будет писать, тестировать и документировать сценарии, как у большинства пользователей, как у меньшинства пользователей, как на сервере, как на рабочей станции, и все это для одного алгоритма копирования файлов. Вот размер блока менять - это вполне разумно, так как не требует больших затрат, кешированием варьировать - это тоже приемлемо, а разветвлять алгоритм на зависимость от информации, которая может быть потенциально недостоверна или на набор частных случаев - это вряд ли. Хотя это только мое предположение. Нет в API функции, возвращающей принадлежит ли пользователь к большинству или не принадлежит.
-
Anatoly Podgoretsky © (21.01.10 17:05) [40]
> Но 2003 -> ХР все стабильно.
Лучшее - враг хорошего :)
-
Игорь Шевченко © (21.01.10 17:33) [41]
Тех рычагов, что ты перечислил, вполне достаточно, а чудо-функция эта без надобности.
-
Ну блин развели дебаты, мне индекс необходим, чтобы обратится к MBR
-
> [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;
-
> [45] Riply © (27.01.10 00:28) Вот черт ! Все время форматирование куда-то убегает :( Sorry
-
ругается на типы (PVOID итд), где они объявлены? зы D6
-
> [47] brother © (27.01.10 04:32) > ругается на типы (PVOID итд), где они объявлены? > зы D6
Уууу. Под D6 тебе придется кучу всего вручную объявлять. Я бы, в этой ситуации, попробовала использовать jwaapi модули (у них там почти все есть).
-
подключил почти все (JEDI API 2.3 and JEDI WSCL 0.9.3), но InitializeObjectAttributesKrnlObj и FILE_SHARE_SH_ALL не нашел, гугление отправляет на твои ответы :) где найти?
-
> [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;
-
вот, что у меня получилось: 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;
Рипли, поправь, если где не верно, но вроде показывает данные корректно...
-
> [51] brother © (28.01.10 05:38) > Рипли, поправь, если где не верно, но вроде показывает данные корректно...
Ну, я могу, только внешне посмотреть, ибо нет у меня Jwa. А дважды опредеять ф-ию IoCtrl_StorageGetDeviceNumberEx эт обязатнльно ? :)
Тут есть один момент, с которым я еще не разобралась как поступить: С одной стороны, хочется открывать диск с минимальными правами (в нашем случае READ_CONTROL), но тогда нам их не хватает на ZwWaitForSingleObject и приходится ставить заплатку (Result = STATUS_ACCESS_DENIED). Можно повысить запрашиваемые права, но тогда мы рискуем не всегда иметь возможность получить данные. Тут подумать надо как быть.
-
> А дважды опредеять ф-ию IoCtrl_StorageGetDeviceNumberEx > эт обязатнльно ? :)
перекопипастил ;)
> Тут подумать надо как быть.
если, что - постучись в личку...
-
Riply золото, спасибо реально работает.
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Товаришь с апишником 193.203.48.16, таки шо вам там не спится?
|