Von Handle auf Dateinamen schliessen?



  • Hi

    Kann man eigentlich irgendwie von einem HANDLE welches man von CreateFile bekommt auf den Namen der Datei schließen zu der das Handle gehört? Gibt es da irgendwelche Tricks dafür oder ist es unmöglich?

    Grüsse,
    Tiroler



  • Hab' gerade noch mal Google bemüht und diesen coolen Code Schnipsel gefunden mit dem es funktioniert:

    #include <windows.h>
    #include <stdio.h>
    #include <string>
    #include <strstream>
    #include <iostream>
    
    typedef struct _UNICODE_STRING {
        USHORT Length;
        USHORT MaximumLength;
    #ifdef MIDL_PASS
        [size_is(MaximumLength / 2), length_is((Length) / 2) ]
        USHORT * Buffer;
    #else // MIDL_PASS
        PWSTR  Buffer;
    #endif // MIDL_PASS
    } UNICODE_STRING;
    typedef UNICODE_STRING *PUNICODE_STRING;
    
    #define STATUS_SUCCESS  0
    typedef ULONG NTSTATUS;
    
    typedef enum _OBJECT_INFO_CLASS {
        ObjectBasicInfo,
        ObjectNameInfo,
        ObjectTypeInfo,
        ObjectAllTypesInfo,
        ObjectProtectionInfo
    } OBJECT_INFO_CLASS;
    
    typedef NTSTATUS (NTAPI * NTQUERYOBJECT)(HANDLE, OBJECT_INFO_CLASS, PVOID, ULONG, PULONG);
    
    typedef struct ObjectNameInfo_t {
        UNICODE_STRING ObjectName;
        WCHAR ObjectNameBuffer[1];
    } OBJECT_NAME_INFO, *POBJECT_NAME_INFO;
    
    int main(int argc, char **argv)
    {
    	HMODULE ntdll = GetModuleHandle("ntdll.dll");
    	NTQUERYOBJECT NtQueryObject = (NTQUERYOBJECT)GetProcAddress(ntdll, "NtQueryObject");
    
    	if(NtQueryObject == NULL) {
    		printf("GetProcAddress failed (errno %i)\n", GetLastError());
    		return 1;
    	}
    
    	HANDLE hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL,
    		OPEN_EXISTING, 0, NULL);
    
    	if( hFile == INVALID_HANDLE_VALUE ) {
    		printf("Couldn't open file %s\n", argv[1]);
    		return 1;
    	}
    
    	char Buffer[1024];
    	POBJECT_NAME_INFO pObjectNameInfo = (POBJECT_NAME_INFO) Buffer;
    
    	int rc = NtQueryObject(hFile, ObjectNameInfo, Buffer, sizeof(Buffer), NULL);
    	if( rc != STATUS_SUCCESS ) {
    		printf("NtQueryObject faield (errno %i)\n", GetLastError());
    		return 1;
    	}
    
    	printf("Filename from handle: %s\n", pObjectNameInfo->ObjectName.Buffer);
    
        return 0;
    }
    

    Nur kann jemand bestätigen ob das auch unter Windows 2000 funktioniert? Bei Win9x funktioniert es wohl nicht oder? Also ich habe Windows XP da funktioniert es.

    Tiroler



  • Ne, die NT API gibt's IMHO nicht auf 9x/ME. Aber in der ➡ JEDI API Library - listing of the NT Native API Functions kannst du nachschauen, welche Funktionen ab welcher Version von Windows NT (ab 3.51 bis 2003 Server) existieren.

    Greetz, Swordfish



  • GetModuleFileName() <-- Auch nur für WinNT/2000/XP



  • [edit] quatsch [/edit]

    Greetz, Swordfish



  • ach ihr piper ich sagte doch HANDLE nicht HMODULE^^



  • Entschuldige, dass ich dieser Aussage von WebFritzi beigepflichtet habe ^^
    Funktioniert natürlich nicht.

    Greetz, Swordfish



  • Grrr. 😉 Dann eben so:

    GetWindowThreadProcessId() --> Process-ID
    OpenProcess() --> Process-Handle
    GetModuleFileNameEx() mit hModule == NULL --> File-Name.

    So. Zufrieden? 😃



  • Nö, probier's mal selber...

    Greetz, Swordfish



  • OK, habsch jemacht. Ganz dörtie:

    typedef DWORD (WINAPI *GMFEX)(HANDLE hProcess, HMODULE hModule,
                                  LPTSTR lpstrFileName, DWORD nSize);
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
       HWND hwnd = FindWindow(NULL, "Unbenannt - Editor");
       DWORD dwPID;
       HANDLE hp;
       HMODULE hDll;
       TCHAR str[1024];
    
       GetWindowThreadProcessId(hwnd, &dwPID);
       hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
    
       hDll = LoadLibrary("Psapi.dll");
       GMFEX gmfex = (GMFEX)GetProcAddress(hDll, "GetModuleFileNameExA");
       gmfex(hp, NULL, str, 1024);
       FreeLibrary(hDll);
    
       CloseHandle(hp);
       Edit1->Text = str;
    }
    

    Ach ja, im Edit1 steht dann "C:\WINDOWS\system32\notepad.exe". 😉



  • TirolerMensch schrieb:

    Kann man eigentlich irgendwie von einem HANDLE welches man von CreateFile bekommt auf den Namen der Datei schließen zu der das Handle gehört? Gibt es da irgendwelche Tricks dafür oder ist es unmöglich?

    Was sagst du jetzt?? 😃 *lol*

    Greetz, Swordfish

    PS: Man beachte: Dateiname des durch CreateFile( ) geöffneten Handles.



  • Oha. Da hab ich aber voll daneben gelegen. 🙄



  • Swordfish schrieb:

    Entschuldige, dass ich dieser Aussage von WebFritzi beigepflichtet habe ^^
    Funktioniert natürlich nicht.

    Sag' ich schon seit 10 vor 3... Geh' schlafen 😃

    Greetz, Swordfish


Log in to reply