Freigeben über


DuplicateHandle-Funktion (handleapi.h)

Dupliziert ein Objekthandle.

Syntax

BOOL DuplicateHandle(
  [in]  HANDLE   hSourceProcessHandle,
  [in]  HANDLE   hSourceHandle,
  [in]  HANDLE   hTargetProcessHandle,
  [out] LPHANDLE lpTargetHandle,
  [in]  DWORD    dwDesiredAccess,
  [in]  BOOL     bInheritHandle,
  [in]  DWORD    dwOptions
);

Die Parameter

[in] hSourceProcessHandle

Ein Handle für den Prozess mit dem zu duplizierenden Handle.

Das Handle muss über das PROCESS_DUP_HANDLE Zugriffsrecht verfügen. Weitere Informationen finden Sie unter Prozesssicherheits- und Zugriffsberechtigungen.

[in] hSourceHandle

Das zu duplizierende Handle. Dies ist ein geöffnetes Objekthandle, das im Kontext des Quellprozesses gültig ist. Eine Liste von Objekten, deren Ziehpunkte dupliziert werden können, finden Sie im folgenden Abschnitt "Hinweise".

Wenn hSourceHandle ein Pseudohandle ist, das von GetCurrentProcess oder GetCurrentThread zurückgegeben wird, sollte hSourceProcessHandle ein Handle für den Prozess sein, der DuplicateHandle aufruft.

[in] hTargetProcessHandle

Ein Handle für den Prozess, der das duplizierte Handle empfängt. Das Handle muss über das PROCESS_DUP_HANDLE Zugriffsrecht verfügen.

Dieser Parameter ist optional und kann als NULL angegeben werden, wenn das DUPLICATE_CLOSE_SOURCE Flag in Optionsfestgelegt ist.

[out] lpTargetHandle

Ein Zeiger auf eine Variable, die das duplizierte Handle empfängt. Dieser Handlewert ist im Kontext des Zielprozesses gültig.

Wenn hSourceHandle ein Pseudohandle ist, der von GetCurrentProcess oder GetCurrentThread zurückgegeben wird, konvertiert DuplicateHandle es in einen echten Handle in einen Prozess oder Thread.

Wenn lpTargetHandleNULL ist, dupliziert die Funktion das Handle, gibt jedoch nicht den doppelten Handlewert an den Aufrufer zurück. Dieses Verhalten ist nur aus Gründen der Abwärtskompatibilität mit früheren Versionen dieser Funktion vorhanden. Sie sollten dieses Feature nicht verwenden, da Systemressourcen verloren gehen, bis der Zielprozess beendet wird.

Dieser Parameter wird ignoriert, wenn hTargetProcessHandleNULL ist.

[in] dwDesiredAccess

Der Zugriff, der für das neue Handle angefordert wurde. Die Kennzeichnungen, die für jeden Objekttyp angegeben werden können, finden Sie im folgenden Abschnitt "Hinweise".

Dieser Parameter wird ignoriert, wenn der parameter dwOptions das DUPLICATE_SAME_ACCESS Flag angibt. Andernfalls hängen die kennzeichnungen, die angegeben werden können, vom Typ des Objekts ab, dessen Handle dupliziert werden soll.

Dieser Parameter wird ignoriert, wenn hTargetProcessHandleNULL ist.

[in] bInheritHandle

Eine Variable, die angibt, ob das Handle vererbbar ist. Wenn TRUE, kann das duplizierte Handle von neuen Prozessen geerbt werden, die vom Zielprozess erstellt wurden. Wenn FALSE, kann der neue Handle nicht geerbt werden.

Dieser Parameter wird ignoriert, wenn hTargetProcessHandleNULL ist.

[in] dwOptions

Optionale Aktionen. Dieser Parameter kann null oder eine beliebige Kombination der folgenden Werte sein.

Wert Bedeutung
DUPLICATE_CLOSE_SOURCE
0x00000001
Schließt das Quellhandle. Dies tritt unabhängig vom zurückgegebenen Fehlerstatus auf.
DUPLICATE_SAME_ACCESS
0x00000002
Ignoriert den dwDesiredAccess-Parameter . Das duplizierte Handle hat denselben Zugriff wie das Quellhandle.

Rückgabewert

Wenn die Funktion erfolgreich ist, ist der Rückgabewert ungleich Null.

Wenn die Funktion fehlschlägt, ist der Rückgabewert null. Rufen Sie GetLastErrorauf, um erweiterte Fehlerinformationen zu erhalten.

Bemerkungen

Das duplizierte Handle bezieht sich auf dasselbe Objekt wie das ursprüngliche Handle. Daher werden alle Änderungen am Objekt über beide Handles wiedergegeben. Wenn Sie beispielsweise ein Dateihandle duplizieren, ist die aktuelle Dateiposition für beide Handles immer identisch. Verwenden Sie die CreateFile-Funktion , um Dateihandles zu erstellen, die den Zugriff auf dieselbe Datei gemeinsam nutzen.

DuplicateHandle kann entweder vom Quellprozess oder vom Zielprozess aufgerufen werden (oder ein Prozess, der sowohl der Quell- als auch der Zielprozess ist). Ein Prozess kann beispielsweise DuplicateHandle verwenden, um ein nicht vererbbares Duplikat eines vererbbaren Handles oder ein Handle mit einem anderen Zugriff als dem ursprünglichen Handle zu erstellen.

Der Quellprozess verwendet die GetCurrentProcess-Funktion , um ein Handle für sich selbst abzurufen. Dieses Handle ist ein Pseudohandle, aber DuplicateHandle konvertiert es in einen echten Prozesshandle. Um das Zielprozesshandle abzurufen, kann es erforderlich sein, eine Form der Interprocess-Kommunikation (z. B. eine benannte Pipe oder einen freigegebenen Speicher) zu verwenden, um den Prozessbezeichner an den Quellprozess zu kommunizieren. Der Quellprozess kann diesen Bezeichner in der OpenProcess-Funktion verwenden, um ein Handle für den Zielprozess abzurufen.

Wenn der Prozess, der DuplicateHandle aufruft, nicht auch der Zielprozess ist, muss der Quellprozess die Interprocess-Kommunikation verwenden, um den Wert des doppelten Handles an den Zielprozess zu übergeben.

DuplicateHandle kann verwendet werden, um einen Handle zwischen einem 32-Bit-Prozess und einem 64-Bit-Prozess zu duplizieren. Der resultierende Handle ist entsprechend angepasst, um im Zielprozess zu arbeiten. Weitere Informationen finden Sie unter "Prozessinteroperabilität".

DuplicateHandle kann Handles für die folgenden Objekttypen duplizieren.

Objekt BESCHREIBUNG
Zugriffstoken Das Handle wird von der Funktion CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken oder OpenThreadToken zurückgegeben.
Änderungsbenachrichtigung Das Handle wird von der FindFirstChangeNotification-Funktion zurückgegeben.
Kommunikationsgerät Das Handle wird von der CreateFile-Funktion zurückgegeben.
Konsoleneingabe Das Handle wird von der CreateFile-Funktion zurückgegeben, wenn CONIN$ angegeben wird, oder von der GetStdHandle-Funktion , wenn STD_INPUT_HANDLE angegeben wird. Konsolenhandles können nur im selben Prozess dupliziert werden.
Konsolenbildschirmpuffer Das Handle wird von der CreateFile-Funktion zurückgegeben, wenn CONOUT$ angegeben wird, oder von der GetStdHandle-Funktion , wenn STD_OUTPUT_HANDLE angegeben wird. Konsolenhandles können nur im selben Prozess dupliziert werden.
Arbeitsfläche Das Handle wird von der GetThreadDesktop-Funktion zurückgegeben.
Ereignis Das Handle wird von der CreateEvent - oder OpenEvent-Funktion zurückgegeben.
Datei Das Handle wird von der CreateFile-Funktion zurückgegeben.
Dateizuordnung Das Handle wird von der CreateFileMapping-Funktion zurückgegeben.
Beruf Das Handle wird von der CreateJobObject-Funktion zurückgegeben.
Mailslot Das Handle wird von der CreateMailslot-Funktion zurückgegeben.
Mutex Das Handle wird von CreateMutex oder [OpenMutex](.) zurückgegeben. /synchapi/nf-synchapi-openmutexw.md)-Funktion.
Rohr Ein benanntes Pipehandle wird von der CreateNamedPipe - oder CreateFile-Funktion zurückgegeben. Ein anonymer Pipehandle wird von der CreatePipe-Funktion zurückgegeben.
Prozess Das Handle wird von der CreateProcess-, GetCurrentProcess- oder OpenProcess-Funktion zurückgegeben.
Registrierungsschlüssel Das Handle wird von der RegCreateKey-, RegCreateKeyEx-, RegOpenKey- oder RegOpenKeyEx-Funktion zurückgegeben. Beachten Sie, dass registrierungsschlüsselhandles, die von der RegConnectRegistry-Funktion zurückgegeben werden, nicht in einem Aufruf von DuplicateHandle verwendet werden können.
Semaphor Der Handle wird von der Funktion CreateSemaphor oder OpenSemaphor zurückgegeben .
Faden Das Handle wird von der Funktion CreateProcess, CreateThread, CreateRemoteThread oder GetCurrentThread zurückgegeben.
Zeitschaltuhr Das Handle wird von der Funktion CreateWaitableTimerW oder OpenWaitableTimerW zurückgegeben.
Transaktion Das Handle wird von der CreateTransaction-Funktion zurückgegeben.
Fensterstation Das Handle wird von der GetProcessWindowStation-Funktion zurückgegeben.
 

Sie sollten "DuplicateHandle" nicht verwenden, um Handles für die folgenden Objekte zu duplizieren:

  • E/A-Vervollständigungsports. Es wird kein Fehler zurückgegeben, aber das doppelte Handle kann nicht verwendet werden.
  • Steckdosen. Es wird kein Fehler zurückgegeben, aber das doppelte Handle wird möglicherweise nicht von Winsock beim Zielprozess erkannt. Außerdem beeinträchtigt die Verwendung von DuplicateHandle die interne Verweiszählung auf das zugrunde liegende Objekt. Verwenden Sie die WSADuplicateSocket-Funktion , um ein Sockethandle zu duplizieren.
  • Pseudohandles, die nicht von den Funktionen "GetCurrentProcess " oder "GetCurrentThread " zurückgegeben werden.
Der parameter dwDesiredAccess gibt die Zugriffsrechte des neuen Handles an. Alle Objekte unterstützen die Standardzugriffsrechte. Objekte unterstützen je nach Objekttyp möglicherweise auch zusätzliche Zugriffsrechte. Weitere Informationen finden Sie in den folgenden Themen: In einigen Fällen kann das neue Handle mehr Zugriffsrechte haben als das ursprüngliche Handle. In anderen Fällen kann DuplicateHandle jedoch kein Handle mit mehr Zugriffsrechten als das Original erstellen. Ein mit dem GENERIC_READ Zugriffsrecht erstelltes Dateihandle kann z. B. nicht dupliziert werden, sodass sowohl das GENERIC_READ als auch GENERIC_WRITE Zugriffsrecht vorhanden sind.

Normalerweise schließt der Zielprozess ein dupliziertes Handle, wenn dieser Prozess mit dem Handle fertig ist. Um ein dupliziertes Handle aus dem Quellprozess zu schließen, rufen Sie DuplicateHandle mit den folgenden Parametern auf:

  • Legen Sie "hSourceProcessHandle " aus dem DuplicateHandle-Aufruf , der das Handle erstellt hat, auf den Zielprozess fest.
  • Legen Sie "hSourceHandle " auf das duplizierte Handle fest, das geschlossen werden soll.
  • Legen Sie "hTargetProcessHandle " auf NULL fest.
  • Legen Sie dwOptions auf DUPLICATE_CLOSE_SOURCE fest.

Beispiele

Im folgenden Beispiel wird ein Mutex erstellt, ein Handle an den Mutex dupliziert und an einen anderen Thread übergeben. Durch das Duplizieren des Handles wird sichergestellt, dass die Verweisanzahl erhöht wird, sodass das Mutex-Objekt erst zerstört wird, wenn beide Threads den Handle geschlossen haben.

#include <windows.h>

DWORD CALLBACK ThreadProc(PVOID pvParam);

int main()
{
    HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
    HANDLE hMutexDup, hThread;
    DWORD dwThreadId;

    DuplicateHandle(GetCurrentProcess(), 
                    hMutex, 
                    GetCurrentProcess(),
                    &hMutexDup, 
                    0,
                    FALSE,
                    DUPLICATE_SAME_ACCESS);

    hThread = CreateThread(NULL, 0, ThreadProc, 
        (LPVOID) hMutexDup, 0, &dwThreadId);

    // Perform work here, closing the handle when finished with the
    // mutex. If the reference count is zero, the object is destroyed.
    CloseHandle(hMutex);

    // Wait for the worker thread to terminate and clean up.
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    return 0;
}

DWORD CALLBACK ThreadProc(PVOID pvParam)
{
    HANDLE hMutex = (HANDLE)pvParam;

    // Perform work here, closing the handle when finished with the
    // mutex. If the reference count is zero, the object is destroyed.
    CloseHandle(hMutex);
    return 0;
}

Anforderungen

Anforderung Wert
Mindestens unterstützter Client Windows 2000 Professional [Desktop-Apps | UWP-Apps]
Mindestanforderungen für unterstützte Server Windows 2000 Server [Desktop-Apps | UWP-Apps]
Zielplattform Fenster
Überschrift handleapi.h (include Windows.h)
Bibliothek Kernel32.lib
DLL Kernel32.dll

Siehe auch

CloseHandle-

Behandeln der Vererbung

Handle- und Objektfunktionen