Имеется тестовая прожка, которая просто читает файлики с использованием "нативных" ф-ий (Zw*). Думал ранее что она работает нормально, но тут случайно обнаружил, что на некоторых файликах ZwReadFile спотыкается. Покурил немного wasm, но так и не понял причину этой ошибки. Вот сам кодес: Код (Text): function NtFileCreateEx(FileName: PWideChar): THandle; var usName: TUnicodeString; oa: TOBJECTATTRIBUTES; Status: NTSTATUS; IoStatusBlock: IO_STATUS_BLOCK; begin Result := INVALID_HANDLE_VALUE; RtlInitUnicodeString(@usName, FileName); InitializeObjectAttributes(@oa, @usName, OBJ_CASE_INSENSITIVE, 0, nil); Status := ZwCreateFile(@Result, GENERIC_READ or SYNCHRONIZE, @oa, @IoStatusBlock, nil, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE or FILE_NO_INTERMEDIATE_BUFFERING or FILE_SYNCHRONOUS_IO_NONALERT, nil, 0 ); if Status <> STATUS_SUCCESS then begin SetLastError(RtlNtStatusToDosError(Status)); Result := INVALID_HANDLE_VALUE; end; end; function NtGetFileSize(hFile: THandle): Int64; var errCode: NTSTATUS; FileStandard: PFILE_STANDARD_INFORMATION; IoStatusBlock: IO_STATUS_BLOCK; begin GetMem(FileStandard, SizeOf(FileStandard^)+4); errCode := ZwQueryInformationFile(hFile, @IoStatusBlock, FileStandard, SizeOf(FileStandard^)+4, FileStandardInformation); if errCode <> STATUS_SUCCESS then begin SetLastError(RtlNtStatusToDosError(errCode)); Result := -1; end else begin Result := FileStandard^.EndOfFile.QuadPart; end; FreeMem(FileStandard); end; function MD5FileNative(FileName: PWideChar; Hash: PMD5Digest): Integer; const FileBufSize = $20000; var hFile: THandle; fsz: LARGE_INTEGER; md5c: TMD5Context; ByteOffset: LARGE_INTEGER; rdlen, h: DWORD; ns: NTSTATUS; StatusBlock: IO_STATUS_BLOCK; tbuf: PChar; begin Result := -1; hFile := NtFileCreateEx(FileName); if (hFile = 0) or (hFile = INVALID_HANDLE_VALUE) then Exit; tbuf := nil; try fsz.QuadPart := NtGetFileSize(hFile); if fsz.QuadPart <= 0 then Exit; Result := -2; if (fsz.QuadPart > 20*1024*1024) then Exit; Form1.Memo1.Lines.Add('FileSize = '+IntToHex(fsz.LowPart, 8)); GetMem(tbuf, FileBufSize); MD5Init(md5c); ByteOffset.HighPart := 0; ByteOffset.LowPart := 0; rdlen := FileBufSize; repeat if (ByteOffset.LowPart + FileBufSize) > fsz.LowPart then rdlen := fsz.LowPart - ByteOffset.LowPart; Form1.Memo1.Lines.Add('L = '+IntToHex(ByteOffset.LowPart, 8)+' rdlen = '+IntToHex(rdlen, 8)); ns := ZwReadFile(hFile, 0, nil, nil, @StatusBlock, tbuf, rdlen, @ByteOffset, 0); if Integer(ns) < 0 then begin Result := -3; Form1.Memo1.Lines.Add('ERROR = '+IntToHex(ns, 8)+' rdlen = '+IntToHex(rdlen, 8)+' H = '+IntToStr(ByteOffset.HighPart)+' L = '+IntToHex(ByteOffset.LowPart, 8)); Exit; end; if (StatusBlock.Information <> rdlen) then begin Result := -4; Exit; end; MD5Update(md5c, tbuf^, rdlen); Inc(ByteOffset.LowPart, rdlen); until ((ByteOffset.LowPart >= fsz.LowPart) or (rdlen <> FileBufSize)); MD5Final(md5c); Hash^ := md5c.Digest; Result := fsz.LowPart; finally CloseHandle(hFile); // ZwClose(hFile); if tbuf <> nil then FreeMem(tbuf); end; end; ..... Memo1.Lines.Add(String(ws)); sz := MD5FileNative(@ws[1], @md5); Memo1.Lines.Add('NT sz = '+IntToStr(sz)+' md5 = '+MD5DigestToStr(md5)); ..... Вот примеры чтения некоторых проблемных файлов: Код (Text): \Device\HarddiskVolume1\Program Files\Common Files\Microsoft Shared\VS7DEBUG\MDM.EXE FileSize = 0004EA48 L = 00000000 rdlen = 00020000 L = 00020000 rdlen = 00020000 L = 00040000 rdlen = 0000EA48 ERROR = C000000D rdlen = 0000EA48 H = 0 L = 00040000 NT sz = -3 md5 = 00000000000000000000000000000000 \Device\HarddiskVolume1\ntldr FileSize = 0003D0B0 L = 00000000 rdlen = 00020000 L = 00020000 rdlen = 0001D0B0 ERROR = C000000D rdlen = 0001D0B0 H = 0 L = 00020000 NT sz = -3 md5 = 00000000000000000000000000000000 При этом, если зачитывать байтики через стандартные ф-ии для работы с файлами (те что из kernel32), то все читается на ура. Привилегии и права все выставляются. Уже и не знаю куда копать.
Редко я обращаюсь к MSDN. Надо приучать себя. Написано там следующее: После того, как rdlen "выровнил" на 512, всё заработало. Надо бы более основательно о ZwReadFile почитать на досуге. Что то много там нюансов. Всем спасибо.