kkuzil.own@gmail.com

Posted
Filed under Development/Delphi

언젠가는 쓸데가 있겠지... 훗

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;

2010/07/29 15:56 2010/07/29 15:56