1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

offene (windows-)filehandles und prozesse

  • seHaas
  • 18. November 2008 um 16:47
  • Unerledigt
  • seHaas
    11
    seHaas
    Mitglied
    Reaktionen
    3
    Punkte
    1.238
    Beiträge
    206
    • 18. November 2008 um 16:47
    • #1

    Hallo,

    ich wöchte von einem java programm aus bestehende files austauschen.
    werden die files gerade von einem anderen programm verwendet, sollte der benutzer informiert werden, dass er zuerst dieses beenden muss/soll.

    ich hab also eine liste von filenames, die ich tauschen will und ich möchte eine liste der prozesse, die diese files verwenden.
    das ganze soll unter win32 laufen.

    da ich von java aus noch keine möglichkeit gefunden habe diese systeminfos auszulesen, hab ich es per JavaNativeInterface und einer kleinen DLL probiert. der code dafür hab ich z.t. aus der MSDN und aus anderen samples. zum teil funktionierts, nur bekomm ich nicht den vollständigen pfad für file bzw prozess (laufwerksbuchstabe fehlt).

    ich hab schon lösungen gefunden, die dann einfach alle laufwerke durchgehen und schaut ob es das file dort gibt, aber das ist mir zu unsicher.

    gibts vielleicht eine möglichkeit das ohne DLL zu lösen oder fertige libraries?

    mfg seHaas

    anbei der c-code.

    C
    #include <stdio.h>
    #include <windows.h>
    #include <wchar.h>
    #include <process.h>
    #include "SystemHandles.h"
    
    
    HANDLE OpenProcessWrapper(DWORD processId)
    {
        // Open the process for handle duplication
        return OpenProcess( PROCESS_DUP_HANDLE, TRUE, processId );
    }
    
    
    HANDLE DuplicateHandleWrapper(HANDLE hProcess, HANDLE hRemote)
    {
        HANDLE hDup = NULL;
        // Duplicate the remote handle for our process
        DuplicateHandle( hProcess, hRemote, GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS );
        return hDup;
    }
    
    
    void GetFileNameThread( PVOID pParam )
    {
        int len;
        GetFileNameThreadParam* p = (GetFileNameThreadParam*)pParam;
        p->rc = FALSE;
    
        UCHAR lpBuffer[MAX_PATH*2];
        PFILE_NAME_INFORMATION pFNI = (PFILE_NAME_INFORMATION)lpBuffer; 
        DWORD iob[2];
    
        DWORD ntRet = NtQueryInformationFile( p->hFile, iob, lpBuffer, MAX_PATH*2, 9 );
        if ( ntRet == STATUS_SUCCESS){
            len  = pFNI->FileNameLength/2;
            if (len > MAX_PATH)
            {
                len = MAX_PATH-1;
            }
            wcsncpy(p->pName,  pFNI->FileName, len );
            p->pName [len] = L'\0';
            p->rc  = TRUE;
        }
    }
    
    
    BOOL GetFileName(HANDLE h, PWCHAR pName, DWORD processId )
    {
        ULONG size = 0x2000;
        UCHAR* lpBuffer = NULL;
        BOOL ret = FALSE;
    
        HANDLE handle;
        HANDLE hRemoteProcess = NULL;
        BOOL remote = processId != GetCurrentProcessId();
    
        if ( remote )
        {
            // Open the remote process
            hRemoteProcess = OpenProcessWrapper( processId );
            if ( hRemoteProcess == NULL )
            {
                return FALSE;
            }
            // Duplicate the handle
            handle = DuplicateHandleWrapper( hRemoteProcess, h );
        }
        else
        {
            handle = h;
        }
    
    
            // Query the info size
        NtQueryObject( handle, 2, NULL, 0, &size );
    
    
        lpBuffer = (UCHAR*)VirtualAlloc(NULL, sizeof(UCHAR)*size, MEM_COMMIT, PAGE_READWRITE );
        // Query the info size ( type = 2 = ObjectTypeInformation)
        if ( NtQueryObject( handle, 2, lpBuffer, size, NULL ) == 0 )
        {
            int i = _wcsicmp (L"File", (wchar_t*)(lpBuffer+0x60)); // * 0x60 to skip data from OBJECT_INFORMATION_CLASS
            if (i == 0)
            {
                GetFileNameThreadParam tp;
                tp.hFile = handle;
                tp.pName = pName;
    
    
                //Start the thread to get the file name
                HANDLE hThread = (HANDLE)_beginthread( GetFileNameThread, 0, &tp );
                if ( hThread != NULL )
                {
                    if ( WaitForSingleObject(hThread, 50 ) == WAIT_TIMEOUT)
                    {     
                        // Access denied, terminate the thread
                        TerminateThread(  hThread, 0 );
                        wcscpy(pName,  L"");
                        ret  = FALSE;
                    }
                    else
                    {
                        ret = tp.rc;
                    }
                } // else goto cleanup;
            } // else goto cleanup;
         }
    
    
    //cleanup:
        if ( remote )
        {
            if ( hRemoteProcess != NULL )
                CloseHandle( hRemoteProcess );
    
    
            if ( handle != NULL )
                CloseHandle( handle );
        }
        if ( lpBuffer != NULL )
            VirtualFree(lpBuffer, 0, MEM_RELEASE);
        return ret;
    }
    
    
    
    
    JNIEXPORT jboolean JNICALL Java_SystemHandles_initNative (JNIEnv *env, jobject self)
    {
        HANDLE ntdll = LoadLibrary("ntdll.dll");
        NtQuerySystemInformation = (PNtQuerySystemInformation)
                                GetProcAddress((HINSTANCE)ntdll,     "NtQuerySystemInformation" );
        NtQueryObject = (PNtQueryObject)
                                GetProcAddress((HINSTANCE)ntdll,     "NtQueryObject");
        NtQueryInformationFile = (PNtQueryInformationFile)
                                GetProcAddress((HINSTANCE)ntdll,     "NtQueryInformationFile" );
        HANDLE psapi = LoadLibrary("PSAPI.DLL");
        GetProcessImageFileName = (PGetProcessImageFileName)
                                GetProcAddress((HINSTANCE)psapi,    "GetProcessImageFileNameW");
    
        EnumProcessModules = (PEnumProcessModules)
                                GetProcAddress((HINSTANCE)psapi, "EnumProcessModules");
    
    
        GetModuleBaseName = (PGetModuleBaseName)
                                GetProcAddress((HINSTANCE)psapi, "GetModuleBaseNameW");
    
        GetMappedFileName = (PGetMappedFileName)                        
                                GetProcAddress((HINSTANCE)psapi, "GetMappedFileNameW");
    
        jboolean ret = NtQuerySystemInformation && NtQueryObject && NtQueryInformationFile && 
            GetProcessImageFileName && EnumProcessModules && GetModuleBaseName && GetMappedFileName;
        return ret;
    }
    
    
    PSYSTEM_HANDLE_INFORMATION SystemSnapshot()
    {
        DWORD size = 0x6000;
        DWORD needed = 0;
        PSYSTEM_HANDLE_INFORMATION pHI;
    
        pHI = (PSYSTEM_HANDLE_INFORMATION)
                 VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_READWRITE );
        if (! pHI)
        {
            return NULL;
        }
    
        // SYSTEM_INFORMATION_CLASS SystemHandleInformation <-- 16
        if ( NtQuerySystemInformation( 16, pHI, size, &needed ) != 0 )
        {
               if ( needed == 0 )
               {
                    VirtualFree(  pHI, 0, MEM_RELEASE );
                    return NULL;
               }
    
               // The size was not enough
               VirtualFree( pHI, 0, MEM_RELEASE );
    
               pHI = (PSYSTEM_HANDLE_INFORMATION)
                              VirtualAlloc( NULL, size = needed + 256, MEM_COMMIT, PAGE_READWRITE );
        }
        if ( pHI == NULL )
        {
            return NULL;
        }
    
        // Query the objects ( system wide )
        if ( NtQuerySystemInformation( 16, pHI, size, NULL ) != 0 ) {
               VirtualFree( pHI, 0, MEM_RELEASE );
               return NULL;
        }
    
        return pHI; 
    }
    
    
    JNIEXPORT jobject JNICALL Java_SystemHandles_getOpenFilesNative (JNIEnv *env, jobject self)
    {
        jclass cls;
        jmethodID constructor;
        jmethodID addFkt;
        jvalue args[3];
        jobject list;
    
        // reference of the class SystemHandleList
        cls = (*env)->FindClass(env, "SystemFileHandleList");
        // get a reference to the constructor; the name is <init>
        constructor = (*env)->GetMethodID(env, cls, "<init>", "()V");
        // get a reference to the add(String, int, int) method
        addFkt = (*env)->GetMethodID(env, cls, "add", "(Ljava/lang/String;II)V");
        // create a new instance of the class
        list = (*env)->NewObject(env, cls, constructor);
    
    
        
    
        PSYSTEM_HANDLE_INFORMATION pHI = SystemSnapshot();
        if (pHI != NULL)
        {
            int i = 0;
            for (i = 0; i < pHI->NumberOfHandles; i++ )
            {    
                SYSTEM_HANDLE_TABLE_ENTRY_INFO  h = pHI->Handles[i];
    
                WCHAR fileName[MAX_PATH];
                if (!GetFileName((HANDLE)h.HandleValue, fileName, h.UniqueProcessId))
                {
                    continue;
                }
    
    //            WCHAR fn[MAX_PATH];
    //            GetFileNameFromHandle(h.HandleValue, h.UniqueProcessId, fn);
    
                args[0].l = (*env)->NewString(env, fileName, wcslen(fileName));
                args[1].i = h.HandleValue;
                args[2].i = h.UniqueProcessId;
    
                (*env)->CallVoidMethodA(env, list, addFkt, args);
            }
        }
        return list;
    }
    
    
    
    
    JNIEXPORT jstring JNICALL Java_SystemHandles_getProcessFullNameNative (JNIEnv *env, jobject self, jint pid)
    {
        BOOL res;
        int k = 0;
        WCHAR name[MAX_PATH];
        HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
        int count = GetProcessImageFileName(hProcess, name, MAX_PATH);
    
    
        res = count  != 0;
        if (! res)
        {
            k = GetLastError();
            return (*env)->NewStringUTF(env, "<unknown>");
        }
    
        return (*env)->NewString(env, name, wcslen(name));
    }
    
    
    JNIEXPORT jstring JNICALL Java_SystemHandles_getProcessNameNative (JNIEnv *env, jobject self, jint processID)
    {
        WCHAR szProcessName[MAX_PATH] = L"<unknown>";
    
        // Get a handle to the process.
    
        HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                       PROCESS_VM_READ,
                                       FALSE, processID );
    
        // Get the process name.
    
        if (hProcess != NULL)
        {
            HMODULE hMod;
            DWORD cbNeeded;
    
            if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
            {
                GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR) );
            }
            CloseHandle( hProcess );
        }
        return (*env)->NewString(env, szProcessName, wcslen(szProcessName));
    }
    Alles anzeigen
  • Ringding
    11
    Ringding
    Mitglied
    Reaktionen
    12
    Punkte
    1.237
    Beiträge
    244
    • 18. November 2008 um 16:55
    • #2

    Würde mich sehr wundern, wenn's da was fertiges gäbe, nachdem das ja sehr Win32-spezifisch ist. Auf anderen Plattformen kann man die Files ja beliebig "unter dem Hintern" wegziehen.

    Eine Menge Arbeit hast du dir da jedenfalls gemacht ;).

  • a9bejo
    21
    a9bejo
    Mitglied
    Reaktionen
    42
    Punkte
    4.697
    Beiträge
    913
    • 18. November 2008 um 18:04
    • #3

    Du koenntest vielleicht handle mitinstallieren, und die prozessliste dann aus java heraus ueber die shell aufrufen und einlesen. Keine Ahnung ob das funktioniert - ich hab nur mal gegoogelt und ausprobieren kann ich es nicht.

    Ansonsten halt die MSDN library abgrasen. Auf jeden Fall wuerde ich das 'Java' bei deinen Recherchen aus der Problembeschreibung nehmen, denn mit der Java plattform hat das ja nicht mehr viel zu tun: Die Stichworte sind hier wohl eher win32, windows, file handle oder .NET.

    lg, Benjamin Ferrari, bookworm.at

  • seHaas
    11
    seHaas
    Mitglied
    Reaktionen
    3
    Punkte
    1.238
    Beiträge
    206
    • 20. November 2008 um 09:50
    • #4

    danke für die infos.

    ich dachte nicht dass das so ein problem wird :winking_face:
    irgendwie hab ich in erinnerung, dass es bei manchen installer so eine info gibt, welche programme beendet werden sollten. die müssen das ja auch irgendwo auslesen.

    ich werd mit auf jedenfall den code zu filemon anschaun.

    mfg seHaas

  • Maximilian Rupp 27. Dezember 2024 um 12:04

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Benutzer online in diesem Thema

  • 1 Besucher

Rechtliches

Impressum

Datenschutzerklärung