![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
DeviceIoControl c кодом FSCTL_FIND_FILES_BY_SID [D7, Win2k, WinXP]
Семен Сорокин © (2005-05-23 14:45:00)Добрый день мастера, есть вопросик:
Имеется следующий код для "быстрого" сканирования папки, однако результат DeviceIoControl всегда равен 1784 (ERROR_INVALID_USER_BUFFER) какие бы параметры я не пытался туда передать :(
type
TFIND_BY_SID_DATA = record
Restart : DWORD;
Sid : PSID;
end;
TFIND_BY_SID_OUTPUT = array [0..1024] of record
FileNameLength: ULONG;
FileName: array [0..MAX_PATH-1] of WCHAR;
end;
const
FSCTL_FIND_FILES_BY_SID: cardinal = $9008F;
procedure ScanFiles(ADrive: THandle; const APath: PAnsiChar);
var
_in: TFIND_BY_SID_DATA;
_out: TFIND_BY_SID_OUTPUT;
_bytes: cardinal;
_sd: pointer;
_own: pointer;
_default: LongBool;
_size: cardinal;
_err: cardinal;
_dir: THandle;
_res: boolean;
...
if (GetNamedSecurityInfo(APath, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, @_own, nil, nil, nil, _sd) = ERROR_SUCCESS) and
IsValidSid(_own) then begin
_in.Restart := 1;
_size := GetLengthSid(_own);
_in.Sid := SysGetMem(_size);
if CopySid(_size, _in.Sid, _own) and IsValidSid(_in.Sid) then begin
_dir := CreateFile(APath, FILE_READ_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
if _dir = INVALID_HANDLE_VALUE then
_dir := CreateFile(APath, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if _dir = INVALID_HANDLE_VALUE then begin
//
end
else begin
_err := ERROR_MORE_DATA;
while _err = ERROR_MORE_DATA do begin
_err := NO_ERROR;
_bytes := 0;
_res := DeviceIoControl(_dir, FSCTL_FIND_FILES_BY_SID, @_in, SizeOf(DWORD) + _size, @_out, SizeOf(_out), @_bytes, nil);
if not _res then begin
_err := GetLastError;
if _err <> ERROR_MORE_DATA then
Break
end;
FreeMem(__out, __sz);
_in.Restart := 0
end;
end;
CloseHandle(_dir)
end;
FreeMem(_in.Sid, _size)
end
end;
Если кто работал в этом направлении - может быть натолкнет на путь истинный.
С Уважением, Семен.
vidiv (2005-05-26 13:11:00) [1]
> Увы она работает на уровне драйвера
Выход за абстракцию... :)
NikNet (2005-05-25 20:30:00) [2]Я её передал вроде быстрее на много рабоает чем ты предлогал...
Я тебе на MAIL скину...
--------------------------------------
Увы она работает на уровне драйвера.
Я думаю драйвер ты сможешь найти...
n0name (2005-05-25 19:15:00) [3]То есть пошёл другим путём?
Без FSCTL_FIND_FILES_BY_SID?
Семен Сорокин (2005-05-25 19:07:00) [4]в данной интерпретации нашел
n0name (2005-05-25 17:42:00) [5]Нашёл решение, или забил?
Семен Сорокин (2005-05-25 15:49:00) [6]
> False_Delirium © (23.05.05 18:32) [6]
правильнее будет вот так:
type
PFIND_BY_SID_OUTPUT = ^TFIND_BY_SID_OUTPUT;
TFIND_BY_SID_OUTPUT = record
NextEntryOffset: DWORD;
FileIndex : DWORD;
FileNameLength : DWORD;
FileName : array [0..0] of WCHAR;
end;
NikNet © (23.05.05 21:22) [7]
стучись в Асю или на мыло.
2 All:
спасибо, вопрос закрыт.
NikNet (2005-05-24 15:35:00) [7]Удалено модератором
Примечание: Создание пустых сообщений
NikNet (2005-05-23 21:22:00) [8]Друг может даш полный код? Просто тоже хочу так :)
Вот делал файловый менеджер но он плохо сканировал
вообщем работал с функциями FindFirst,Find...
и плохо сканировал большие каталоги как например System32
Может даш? (Или кто разобрался скиньте пожалуйста =) )
False_Delirium (2005-05-23 18:32:00) [9]typedef struct _FIND_BY_SID_OUTPUT
{
DWORD NextEntryOffset;
DWORD FileIndex;
DWORD FileNameLength;
WCHAR FileName[1];
} FIND_BY_SID_OUTPUT,
*PFIND_BY_SID_OUTPUT;
это тоже самое, что и ?
TFIND_BY_SID_OUTPUT = array [0..1024] of record
NextEntryOffset: DWORD;
FileIndex : DWORD;
FileNameLength : DWORD;
FileName : array [0..MAX_PATH-1] of WCHAR;
end;
Семен Сорокин (2005-05-23 17:54:00) [10]нашел проблему, действительно во входном буфере :) сам дурак:
type
TFIND_BY_SID_DATA = record
Restart : DWORD;
Sid :array [0..1023] of byte;
end;
память выделялась не в стеке а в куче:
_in.Sid := SysGetMem(_size);
теперь результат - true, но _bytes почему-то всегда = 0 :(
Семен Сорокин (2005-05-23 17:35:00) [11]вот:
type
TFIND_BY_SID_OUTPUT = array [0..1024] of record
NextEntryOffset: DWORD;
FileIndex : DWORD;
FileNameLength : DWORD;
FileName : array [0..MAX_PATH-1] of WCHAR;
end;
пробовал через указатель задавать выходной буфер:
var
__out: Pointer;
__sz: cardinal;
...
__sz := 1024;
__out := SysGetMem(__sz);
_res := DeviceIoControl(_dir, FSCTL_FIND_FILES_BY_SID, @_in, SizeOf(DWORD) + _size, __out{@_out}, __sz{SizeOf(_out)}, _bytes, nil);
...
FreeMem(__out, __sz);
тот же результат, это наводит меня на мысли что проблема во входном буфере.
False_Delirium (2005-05-23 17:12:00) [12]Можно на код с исправлениями взглянуть ?
Семен Сорокин (2005-05-23 16:15:00) [13]
> False_Delirium © (23.05.05 15:43) [1]
хм. видать у меня устаревшая версия MSDN :( однако добавление этих параметров все равно проблемы не решило, я пробовал выделять память вручную (FreeMem(__out, __sz); - вот это лишнее в коде осталось) - всё равно эта же ошибка.
ЗЫ. Спасибо за помощь.
False_Delirium (2005-05-23 15:43:00) [14]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/find_by_sid_output.asp