언젠가는 쓸데가 있겠지... 훗
interface
...
...
const
STATUS_SUCCESS = $00000000;
{$EXTERNALSYM STATUS_SUCCESS}
type
NT_STATUS = LongInt;
IO_STATUS_BLOCK = record
case integer of
0:
(Status: NT_STATUS);
1:
(Pointer: Pointer;
Information: ULONG); // 'Information' does not belong to the union!
end;
PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
_FILE_INTERNAL_INFORMATION = record // Information Class 6
FileId: LARGE_INTEGER;
end;
FILE_INTERNAL_INFORMATION = _FILE_INTERNAL_INFORMATION;
PFILE_INTERNAL_INFORMATION = ^FILE_INTERNAL_INFORMATION;
_FILE_NAME_INFORMATION = record
dwLen: DWORD;
sFileName: array [0..0] of WideChar;
end;
FILE_NAME_INFORMATION = _FILE_NAME_INFORMATION;
PFILE_NAME_INFORMATION = ^FILE_NAME_INFORMATION;
_FILE_INFORMATION_CLASS = (
FileFiller0,
FileDirectoryInformation, // 1
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4 wdm
FileStandardInformation, // 5 wdm
FileInternalInformation, // 6
FileEaInformation, // 7
FileAccessInformation, // 8
FileNameInformation, // 9
FileRenameInformation, // 10
FileLinkInformation, // 11
FileNamesInformation, // 12
FileDispositionInformation, // 13
FilePositionInformation, // 14 wdm
FileFullEaInformation, // 15
FileModeInformation, // 16
FileAlignmentInformation, // 17
FileAllInformation, // 18
FileAllocationInformation, // 19
FileEndOfFileInformation, // 20 wdm
FileAlternateNameInformation, // 21
FileStreamInformation, // 22
FilePipeInformation, // 23
FilePipeLocalInformation, // 24
FilePipeRemoteInformation, // 25
FileMailslotQueryInformation, // 26
FileMailslotSetInformation, // 27
FileCompressionInformation, // 28
FileObjectIdInformation, // 29
FileCompletionInformation, // 30
FileMoveClusterInformation, // 31
FileQuotaInformation, // 32
FileReparsePointInformation, // 33
FileNetworkOpenInformation, // 34
FileAttributeTagInformation, // 35
FileTrackingInformation, // 36
FileMaximumInformation);
FILE_INFORMATION_CLASS = _FILE_INFORMATION_CLASS;
PFILE_INFORMATION_CLASS = ^FILE_INFORMATION_CLASS;
..
..
..
implementation
..
..
procedure TDlgScanMain.sButton2Click(Sender: TObject);
var
NtQueryInformationFile: function(FileHandle:DWORD;
IoStatusBlock: PIO_STATUS_BLOCK;
FileInformation: Pointer;//PFILE_INTERNAL_INFORMATION;
Length:DWORD;
FileInformationClass:FILE_INFORMATION_CLASS):DWORD; stdcall;
FileName: string;
hFile: THandle;
io: IO_STATUS_BLOCK;
FileInfo: FILE_INTERNAL_INFORMATION;
Res: NT_STATUS;
FileRecInput: TNtfsFileRecordInputBuffer;
FileRecOutput: PNtfsFileRecordOutputBuffer;
Read: DWORD;
hDevice: THandle;
VolumeDataBuff: NTFS_VOLUME_DATA_BUFFER;
Size: DWORD;
rec: PFileRecordHeader;
pName: PFILE_NAME_INFORMATION;
begin
FileName:='E:\테스트\DOC';
NtQueryInformationFile := GetProcAddress(GetModuleHandle('ntdll.dll'), 'NtQueryInformationFile');
if Assigned(NtQueryInformationFile)=false then
exit;
if FileExists(FileName) then
hFile := CreateFile(PChar(FileName),
GENERIC_READ or
GENERIC_WRITE,
FILE_SHARE_READ or
FILE_SHARE_WRITE or
FILE_SHARE_DELETE,
nil, OPEN_EXISTING, 0, 0)
else if DirectoryExists(FileName) then
hFile := CreateFile(PChar(FileName),
GENERIC_READ or
GENERIC_WRITE,
FILE_SHARE_READ or
FILE_SHARE_WRITE or
FILE_SHARE_DELETE,
nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
else ASSERT(false);
if hFile <> INVALID_HANDLE_VALUE then
begin
ZeroMemory(@FileInfo, sizeof(FileInfo));
Res := NtQueryInformationFile(hFile, @io, @FileInfo, sizeof(FileInfo), FileInternalInformation);
if Res <> STATUS_SUCCESS then Exit;
hDevice := CreateFile(PChar('\\.\'+FileName[1]+':'), GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or
FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if not(DeviceIoControl(hDevice, FSCTL_GET_NTFS_VOLUME_DATA, nil, 0,
@VolumeDataBuff, sizeof(VolumeDataBuff), Read, nil))
then RaiseLastWin32Error();
Size := sizeof(TNtfsFileRecordOutputBuffer) + VolumeDataBuff.BytesPerFileRecordSegment-1;
GetMem(FileRecOutput, Size);
ZeroMemory(FileRecOutput, Size);
ZeroMemory(@FileRecInput, sizeof(FileRecInput));
FileRecInput.FileReferenceNumber:=FileInfo.FileId;
if not(DeviceIoControl(hFile,
FSCTL_GET_NTFS_FILE_RECORD,
@FileRecInput,
sizeof(FileRecInput),
FileRecOutput,
Size,
Read,
nil)) then
begin
RaiseLastWin32Error();
end;
rec := @FileRecOutput.FileRecordBuffer;
sMemo1.Lines.Add(IntToStr(rec.SequenceNumber));
FreeMem(FileRecOutput);
CloseHandle(hDevice);
end else
RaiseLastWin32Error();
end;