AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi How know what process is using a determinated file through NtQueryInformationFile?

How know what process is using a determinated file through NtQueryInformationFile?

Ein Thema von flashcoder · begonnen am 6. Apr 2018 · letzter Beitrag vom 9. Apr 2018
Antwort Antwort
flashcoder

Registriert seit: 10. Nov 2013
83 Beiträge
 
#1

How know what process is using a determinated file through NtQueryInformationFile?

  Alt 6. Apr 2018, 17:11
Delphi-Version: XE5
I want know how make this? i already have a c++ code example but still is missing somethings eg: _FILE_PROCESS_IDS_USING_FILE_INFORMATION in Delphi and how loop through ProcessIdList for example.

Here is my initial code:

Delphi-Quellcode:
type
  NTSTATUS = Cardinal;
  TFileInformationClass = (
    FileDirectoryInformation = 1,
    FileFullDirectoryInformation,
    FileBothDirectoryInformation,
    FileBasicInformation,
    FileStandardInformation,
    FileInternalInformation,
    FileEaInformation,
    FileAccessInformation,
    FileNameInformation,
    FileRenameInformation,
    FileLinkInformation,
    FileNamesInformation,
    FileDispositionInformation,
    FilePositionInformation,
    FileFullEaInformation,
    FileModeInformation,
    FileAlignmentInformation,
    FileAllInformation,
    FileAllocationInformation,
    FileEndOfFileInformation,
    FileAlternateNameInformation,
    FileStreamInformation,
    FilePipeInformation,
    FilePipeLocalInformation,
    FilePipeRemoteInformation,
    FileMailslotQueryInformation,
    FileMailslotSetInformation,
    FileCompressionInformation,
    FileObjectIdInformation,
    FileCompletionInformation,
    FileMoveClusterInformation,
    FileQuotaInformation,
    FileReparsePointInformation,
    FileNetworkOpenInformation,
    FileAttributeTagInformation,
    FileTrackingInformation,
    FileIdBothDirectoryInformation,
    FileIdFullDirectoryInformation,
    FileValidDataLengthInformation,
    FileShortNameInformation,
    FileIoCompletionNotificationInformation,
    FileIoStatusBlockRangeInformation,
    FileIoPriorityHintInformation,
    FileSfioReserveInformation,
    FileSfioVolumeInformation,
    FileHardLinkInformation,
    FileProcessIdsUsingFileInformation,
    FileNormalizedNameInformation,
    FileNetworkPhysicalNameInformation,
    FileIdGlobalTxDirectoryInformation,
    FileIsRemoteDeviceInformation,
    FileAttributeCacheInformation,
    FileNumaNodeInformation,
    FileStandardLinkInformation,
    FileRemoteProtocolInformation,
    FileMaximumInformation
  );

  PIOStatusBlock = ^TIOStatusBlock;
  TIOStatusBlock = packed record
    case Boolean of
      False: (Status: NTSTATUS; P: Pointer;);
      True: (Information: ULONG_PTR);
  end;

type
  TNtQueryInformationFile = function(FileHandle: THandle; IoStatusBlock: PIOStatusBlock;
  FileInformation: Pointer; Length: ULONG; FileInformationClass: TFileInformationClass): NTSTATUS; stdcall;

 procedure GetAlternateFileStreamNames(const FileName: string);
var
  hNT, hFile: THandle;
  NtQueryInformationFile: TNtQueryInformationFile;
  ioStatus: TIOStatusBlock;
  P: PFILE_PROCESS_IDS_USING_FILE_INFORMATION; // missing declaration
begin
  hNT := GetModuleHandle('ntdll.dll');
  if hNT = 0 then
    Exit;
  NtQueryInformationFile := GetProcAddress(hNT, 'NtQueryInformationFile');
  if @NtQueryInformationFile = nil then
    Exit;

  FillChar(Buffer, SizeOf(Buffer), 0);
  hFile := CreateFile(PChar(FileName), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  try
    if NtQueryInformationFile(hFile, @ioStatus, P, SizeOf(FILE_PROCESS_IDS_USING_FILE_INFORMATION), FileProcessIdsUsingFileInformation) = 0 then
    begin

      // loop throught P.ProcessIdList
      //compare all pid's (use CreateToolhelp32Snapshot instead PSYSTEM_PROCESS_INFORMATION)

    end;
  finally
    CloseHandle(hFile);
  end;
end;
  Mit Zitat antworten Zitat
flashcoder

Registriert seit: 10. Nov 2013
83 Beiträge
 
#2

AW: How know what process is using a determinated file through NtQueryInformationFile

  Alt 7. Apr 2018, 15:14
Solved, thank you. Below is complete solution.

Delphi-Quellcode:
uses
 TlHelp32;

type
  NTSTATUS = Cardinal;

const
  STATUS_SUCCESS = NTSTATUS($00000000);

type
  TFileInformationClass = (FileDirectoryInformation = 1,
    FileFullDirectoryInformation, FileBothDirectoryInformation,
    FileBasicInformation, FileStandardInformation, FileInternalInformation,
    FileEaInformation, FileAccessInformation, FileNameInformation,
    FileRenameInformation, FileLinkInformation, FileNamesInformation,
    FileDispositionInformation, FilePositionInformation, FileFullEaInformation,
    FileModeInformation, FileAlignmentInformation, FileAllInformation,
    FileAllocationInformation, FileEndOfFileInformation,
    FileAlternateNameInformation, FileStreamInformation, FilePipeInformation,
    FilePipeLocalInformation, FilePipeRemoteInformation,
    FileMailslotQueryInformation, FileMailslotSetInformation,
    FileCompressionInformation, FileObjectIdInformation,
    FileCompletionInformation, FileMoveClusterInformation, FileQuotaInformation,
    FileReparsePointInformation, FileNetworkOpenInformation,
    FileAttributeTagInformation, FileTrackingInformation,
    FileIdBothDirectoryInformation, FileIdFullDirectoryInformation,
    FileValidDataLengthInformation, FileShortNameInformation,
    FileIoCompletionNotificationInformation, FileIoStatusBlockRangeInformation,
    FileIoPriorityHintInformation, FileSfioReserveInformation,
    FileSfioVolumeInformation, FileHardLinkInformation,
    FileProcessIdsUsingFileInformation, FileNormalizedNameInformation,
    FileNetworkPhysicalNameInformation, FileIdGlobalTxDirectoryInformation,
    FileIsRemoteDeviceInformation, FileAttributeCacheInformation,
    FileNumaNodeInformation, FileStandardLinkInformation,
    FileRemoteProtocolInformation, FileMaximumInformation);

  PIOStatusBlock = ^TIOStatusBlock;

  TIOStatusBlock = packed record
    case Boolean of
      False:
        (Status: NTSTATUS; P: Pointer;);
      True:
        (Information: LongWord);
  end;

  PFILE_PROCESS_IDS_USING_FILE_INFORMATION = ^
    FILE_PROCESS_IDS_USING_FILE_INFORMATION;

  FILE_PROCESS_IDS_USING_FILE_INFORMATION = packed record
    NumberOfProcessIdsInList: Cardinal;
    ProcessIdList: array [0 .. MAX_PATH] of LongWord;
  end;

type
  TNtQueryInformationFile = function(FileHandle: THandle;
    IoStatusBlock: PIOStatusBlock; FileInformation: Pointer; Length: Cardinal;
    FileInformationClass: TFileInformationClass): NTSTATUS; stdcall;

implementation

{$R *.dfm}

procedure GetAllSubFolders(sPath: String);
var
  hNT, hFile: THandle;
  NtQueryInformationFile: TNtQueryInformationFile;
  ioStatus: TIOStatusBlock;
  P: FILE_PROCESS_IDS_USING_FILE_INFORMATION;
  Status: NTSTATUS;
  Path: String;
  Rec: TSearchRec;
  Snapshot: THandle;
  pe: TProcessEntry32;
  I: Integer;
begin
  hNT := GetModuleHandle('ntdll.dll');
  if hNT = 0 then
    Exit;
  NtQueryInformationFile := GetProcAddress(hNT, 'NtQueryInformationFile');
  if @NtQueryInformationFile = nil then
    Exit;
  try
    Path := IncludeTrailingPathDelimiter(sPath);
    Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
    pe.dwSize := SizeOf(pe);
    if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then
      try
        repeat
          if (Rec.Name <> '.') and (Rec.Name <> '..') then
          begin
            hFile := CreateFile(PChar(Path + Rec.Name), 0, FILE_SHARE_READ, nil,
              OPEN_EXISTING, 0, 0);
            if hFile <> INVALID_HANDLE_VALUE then
            begin
              try
                FillChar(P.ProcessIdList, SizeOf(P.ProcessIdList), 0);
                P.NumberOfProcessIdsInList := 0;
                Status := NtQueryInformationFile(hFile, @ioStatus, @P,
                  SizeOf(FILE_PROCESS_IDS_USING_FILE_INFORMATION) * 2 + 1,
                  FileProcessIdsUsingFileInformation);
                if Status = STATUS_SUCCESS then
                begin
                  if (P.NumberOfProcessIdsInList > 0) then
                  begin
                    try
                      Form1.mmo1.Lines.Add(Path + Rec.Name);
                      if Process32First(Snapshot, pe) then
                        while Process32Next(Snapshot, pe) do
                        begin
                          for I := 0 to High(P.ProcessIdList) do
                          begin
                            if P.ProcessIdList[I] = pe.th32ProcessID then
                            begin
                              Form1.mmo1.Lines.Add(pe.szExeFile);
                            end;
                          end;
                        end;
                    finally
                      CloseHandle(Snapshot);
                    end;
                  end;
                end
                else
                  Form1.mmo1.Lines.Add('NtQueryInformationFile() = 0x' +
                    IntToHex(Status, 8));
              finally
                CloseHandle(hFile);
              end;
            end;

            GetAllSubFolders(Path + Rec.Name);
          end;
        until FindNext(Rec) <> 0;
      finally
        FindClose(Rec);
      end;
  except
    on e: Exception do
      Showmessage('Err - ' + e.Message);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //
  Form1.mmo1.Clear;
  GetAllSubFolders('C:\Program Files\AVAST Software');
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: How know what process is using a determinated file through NtQueryInformationFile

  Alt 7. Apr 2018, 17:51
Hi there, i have to admit that i dont understand everthing yet, especially the "NtQueryInformationFile" call.
If you want to iterate files and folders i could give you a way shorter method.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
flashcoder

Registriert seit: 10. Nov 2013
83 Beiträge
 
#4

AW: How know what process is using a determinated file through NtQueryInformationFile

  Alt 9. Apr 2018, 12:55
Hi there, i have to admit that i dont understand everthing yet, especially the "NtQueryInformationFile" call.
If you want to iterate files and folders i could give you a way shorter method.
I want that when next file is verified and be the same(s) previous process(es) using this file, not show yours exe name.

My last attempt:

Delphi-Quellcode:
var
 currPid, oldPid : LongWord; // Global

...

for I := 0 to High(P.ProcessIdList) do
  begin
    if P.ProcessIdList[I] = pe.th32ProcessID then
    begin
      oldPid := currPid;
      currPid := pe.th32ProcessID;
      if currPid <> oldPid then
        Form1.mmo1.Lines.Add(pe.szExeFile);
      Break;
    end;
  end;
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz