2017-09-21 2 views
0

Ich habe DuplicateHandle verwendet, um ein Kernel-Objekt für den Kindprozess freizugeben. Ich muss Handle dieses Objekts an diesen Prozess übergeben. Wie geht das?Wie wird das duplizierte Handle in den Child-Prozess übertragen?

int main() { 
    STARTUPINFO cif; 
    ZeroMemory(&cif, sizeof(STARTUPINFO)); 
    PROCESS_INFORMATION pi; 
    CreateProcess("sp.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, 
    &cif, &pi); 

    HANDLE Semaphore = CreateSemaphore(NULL, 0, 1, NULL); 

    DuplicateHandle(GetCurrentProcess(), Semaphore, pi.hProcess, NULL, 
    DUPLICATE_SAME_ACCESS, FALSE, 0); 

    WaitForSingleObject(Semaphore, INFINITE); 
    cout << "Test3: access granted"; 

    CloseHandle(pi.hProcess); 
    CloseHandle(Semaphore); 
} 
+0

Schreiben an stdin des Kindprozesses; Verwenden Sie eine gespeicherte Datei; Verwenden Sie eine Pragma "shared" Variable in einer gemeinsamen dll zwischen Prozessen; Windows-Nachricht; Sockets ... – VuVirt

+1

https://blogs.msdn.microsoft.com/oldnewthing/20111216-00/?p=8873 –

+0

@VuVirt Nein, nichts davon ist gut, müssen Sie das Handle erben –

Antwort

2

Wenn Sie DuplicateHandle() in den übergeordneten Prozess aufrufen, müssen Sie das Kind Prozess als Zielprozess angeben, akzeptieren Sie die neu duplizierten Griff, und dann einen IPC-Mechanismus Ihrer Wahl verwenden, um die duplizierten Griff, um das Kind zu schicken Verfahren, zum Beispiel:

int main() { 
    STARTUPINFO cif; 
    ZeroMemory(&cif, sizeof(cif)); 
    cif.cb = sizeof(cif); 

    PROCESS_INFORMATION pi; 
    ZeroMemory(&pi, sizeof(pi)); 

    if (!CreateProcess("sp.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, 
    &cif, &pi)) 
    { 
     cout << "Test3: CreateProcess failed"; 
    } 
    else 
    { 
     HANDLE hSemaphore = CreateSemaphore(NULL, 0, 1, NULL); 
     if (!hSemaphore) 
     { 
      cout << "Test3: CreateSemaphore failed"; 
     } 
     else 
     { 
      HANDLE hDupSemaphore = NULL; 

      if (!DuplicateHandle(GetCurrentProcess(), hSemaphore, pi.hProcess, &hDupSemaphore, DUPLICATE_SAME_ACCESS, FALSE, 0)) 
      { 
       cout << "Test3: DuplicateHandle failed"; 
      } 
      else 
      { 
       // send hDupSemaphore to child process via IPC ... 

       if (WaitForSingleObject(hSemaphore, INFINITE) == WAIT_OBJECT_0) 
       { 
        cout << "Test3: access granted"; 
        ReleaseSemaphore(hSemaphore, 1, NULL); 
       } 
       else 
        cout << "Test3: WaitForSingleObject failed"; 

       CloseHandle(hDupSemaphore); 
      } 

      CloseHandle(hSemaphore); 
     } 

     CloseHandle(pi.hThread); 
     CloseHandle(pi.hProcess); 
    } 

    return 0; 
} 

Ansonsten hat das Kind Prozess denjenigen seine DuplicateHandle() statt zu nennen. Sie können die Prozess-ID des Elterns und den gewünschten Handle-Wert über die Befehlszeile oder einen anderen IPC-Mechanismus an den untergeordneten Prozess übergeben. Anschließend muss der untergeordnete Prozess die Prozess-ID mit OpenProcess() öffnen und DuplicateHandle() aufrufen, wenn das Quell-Handle dupliziert werden kann.

Andernfalls können Sie den gewünschten Griff als vererbbar erstellen (oder SetHandleInformation() verwenden Sie es als vererbbar zu markieren, nachdem es erstellt wird), und rufen Sie dann CreateProcess() mit dem bInheritHandles Parameter auf TRUE gesetzt. Beachten Sie, dass dies ALLE vererbbaren Handles erbt, es sei denn, Sie verwenden programmatically specify which handles the child process can inherit mit STARTUPINFOEX anstelle von STARTUPINFO (nur Vista und später).

Auf der anderen Seite versuchen Sie, einen Semaphor zu teilen, dem ein Name zugewiesen werden kann. Sie sollten also den Semaphor mit einem zugewiesenen Namen erstellen und ihn dann an den untergeordneten Prozess übergeben, damit er ihn erstellen kann/Öffnen Sie ein eigenes Semaphor-Handle mit demselben Namen. Dies ist documented behavior, und ist der bevorzugte Weg, Kernel-Objekte über Prozessgrenzen hinweg zu teilen:

Wenn die Funktion erfolgreich ist, ist der Rückgabewert ein Handle auf das Semaphore-Objekt. Wenn das benannte Semaphorobjekt vor dem Funktionsaufruf existiert, gibt die Funktion einen Handle für das vorhandene Objekt zurück und GetLastError gibt ERROR_ALREADY_EXISTS zurück.

+0

Ok, also übergab ich den Handle-Wert an den Child-Prozess und rief dann 'DuplicateHandle (Parent_Process_Handle, Handle, GetCurrentProcess(), ...)' Aber wenn ich versuche, Semaphor wiederzuerlangen bekomme ich ERROR_INVALID_HANDLE ... – Aver

+0

muss ich tun das genau mit 'DuplicateHandle()' Ich bin nicht an anderen Lösungen interessiert. – Aver

+0

@Auch warum? Was versuchen Sie genau zu lösen, was keine andere Lösung lösen kann? Die Verwendung von 'DuplicateHandle()' ist keine optimale oder bevorzugte Lösung zum Teilen von Semaphoren. Das Zuweisen eines Nicht-NULL-Namens, sodass er direkt vom untergeordneten Prozess geöffnet werden kann, ist die beste Lösung. –

Verwandte Themen