Einzelnen Beitrag anzeigen

Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#29

Re: Auf Dateien zugreifen die gerade in Gebracuh sind (?)

  Alt 14. Nov 2008, 11:10
Wie versprochen der Code. Es sollten keine Lock Ups produziert werden. Angezeigt werden alle Object Names aller Handles, sofern diese verfügbar sind. Das sind nicht nur Namen von geöffneten Dateien sondern auch die Namen von Memory Mapped Files, Mutexes, Registry Keys etc.. Wenn man nur eine bestimmte Art von Handle haben möchte, liesse sich das allerdings filtern. Würde den Beispiel Quellcode nur unnötig komplex machen .

Delphi-Quellcode:
program lon;

{$APPTYPE CONSOLE}

uses
  JwaWinType,
  JwaWinNT,
  JwaWinBase,
  JwaNtStatus,
  JwaNative,
  TlHelp32,
  sysutils;

procedure NTSetPrivilege(Privilege: string; Enabled: Boolean);
var
  Token: THandle;
  TokenPriv: TOKEN_PRIVILEGES;
  PrevTokenPriv: TOKEN_PRIVILEGES;
  ReturnLength: Cardinal;
begin
  if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
    try
      if LookupPrivilegeValue(nil, PChar(Privilege), TokenPriv.Privileges[0].Luid) then
        begin
          TokenPriv.PrivilegeCount := 1;

          case Enabled of
            True: TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
            False: TokenPriv.Privileges[0].Attributes := 0;
          end;

          ReturnLength := 0;
          PrevTokenPriv := TokenPriv;

          AdjustTokenPrivileges(Token, False, @TokenPriv, SizeOf(PrevTokenPriv), @PrevTokenPriv, @ReturnLength);
      end;
    finally
      CloseHandle(Token);
    end;
end;

procedure ListAllHandleNames;
const
  MaximumHandleCount = 100000;
var
  Buffer : Pointer;
  MemoryNeeded : ULong;
  Unused : ULong;
  HandleInformation : PSystemHandleInformation;
  HandleCount : PULong;
  ObjectName : PObjectNameInformation;
  LocalHandle : THandle;
  ProcessHandle : THandle;
  ObjectString : string;
  i : Integer;
begin

  // Initialisierung
  MemoryNeeded := MaximumHandleCount * SizeOf(TSystemHandleInformation);

  // Handle Liste holen
  GetMem(Buffer, MemoryNeeded);
  if not NT_SUCCESS(NtQuerySystemInformation(SystemHandleInformation, Buffer, MemoryNeeded, nil)) then
    begin
      writeln('NtQuerySystemInformation fehlgeschlagen (Handle Array zu klein?).');
      FreeMem(Buffer);
      Exit;
    end;

  HandleCount := Buffer;
  HandleInformation := Pointer(LongWord(Buffer) + 4);
  for i := 0 to HandleCount^ - 1 do
    begin
      ProcessHandle := OpenProcess(PROCESS_DUP_HANDLE, false, HandleInformation^.ProcessId);
      if ProcessHandle <> 0 then
        begin
          // Spezielle Named Pipes machen Probleme bei der Abfrage. Diese Pipes haben
          // als Access Mask 0x12019F. Entsprechend werden nur Handles abgefragt, die
          // nicht 0x12019F als Access Mask haben.
          if HandleInformation^.GrantedAccess <> $12019F then
            begin
              GetMem(ObjectName, 65536);
              if DuplicateHandle(ProcessHandle, HandleInformation^.Handle, GetCurrentProcess(), @LocalHandle, 0, false, DUPLICATE_SAME_ACCESS) and (ObjectName^.Name.Buffer <> nil)then
                begin
                  if NT_SUCCESS(NtQueryObject(LocalHandle, ObjectNameInformation, ObjectName, 65536, @Unused)) and (ObjectName^.Name.Buffer <> nil) then
                    begin
                      ObjectString := LowerCase(WideString(ObjectName^.Name.Buffer));
                      writeln(Format('Process: %.8x - Handle: %.8x ObjectName: %s', [HandleInformation^.ProcessId, HandleInformation^.Handle, ObjectString]));
                    end;
                  CloseHandle(LocalHandle);
                end;
              FreeMem(ObjectName);
            end;
          CloseHandle(ProcessHandle);
        end;
      inc(HandleInformation);
    end;
  FreeMem(Buffer);
end;

begin
  NTSetPrivilege('SeDebugPrivilege', True);
  ListAllHandleNames;
end.
[EDIT]Memory Leak gefixt.[/EDIT]
Fridolin Walther
  Mit Zitat antworten Zitat