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
);

Parameter

[in] hSourceProcessHandle

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

Das Handle muss über das zugriffsrecht PROCESS_DUP_HANDLE verfügen. Weitere Informationen finden Sie unter Prozesssicherheit und Zugriffsrechte.

[in] hSourceHandle

Das zu duplizierende Handle. Dies ist ein offenes Objekthandle, das im Kontext des Quellprozesses gültig ist. Eine Liste der Objekte, deren Handles dupliziert werden können, finden Sie im folgenden Abschnitt hinweise.

[in] hTargetProcessHandle

Ein Handle für den Prozess, der das duplizierte Handle empfangen soll. Das Handle muss über das zugriffsrecht PROCESS_DUP_HANDLE verfügen.

Dieser Parameter ist optional und kann als NULL angegeben werden, wenn das flag DUPLICATE_CLOSE_SOURCE unter Optionen festgelegt ist.

[out] lpTargetHandle

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

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

Wenn lpTargetHandleNULL ist, dupliziert die Funktion das Handle, gibt jedoch nicht den doppelten Handlewert an den Aufrufer zurück. Dieses Verhalten ist nur für die 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 für das neue Handle angeforderte Zugriff. Die Flags, die für jeden Objekttyp angegeben werden können, finden Sie im folgenden Abschnitt Hinweise.

Dieser Parameter wird ignoriert, wenn der dwOptions-Parameter das flag DUPLICATE_SAME_ACCESS angibt. Andernfalls hängen die Flags, 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 das 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 geschieht unabhängig von den zurückgegebenen Fehlern status.
DUPLICATE_SAME_ACCESS
0x00000002
Ignoriert den dwDesiredAccess-Parameter . Das doppelte Handle hat den gleichen Zugriff wie das Quellhandle.

Rückgabewert

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

Wenn die Funktion fehlerhaft ist, ist der Rückgabewert null. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.

Hinweise

Das doppelte Handle bezieht sich auf dasselbe Objekt wie das ursprüngliche Handle. Daher werden alle Änderungen am Objekt durch beide Handles übernommen. Wenn Sie beispielsweise ein Dateihandle duplizieren, ist die aktuelle Dateiposition für beide Handles immer gleich. Damit Dateihandles unterschiedliche Dateipositionen aufweisen, verwenden Sie die CreateFile-Funktion , um Dateihandles zu erstellen, die den Zugriff auf dieselbe Datei gemeinsam nutzen.

DuplicateHandle kann entweder vom Quell- oder Zielprozess (oder einem Prozess, der sowohl der Quell- als auch der Zielprozess ist) aufgerufen werden. Beispielsweise kann ein Prozess DuplicateHandle verwenden, um ein nicht vererbbares Duplikat eines vererbbaren Handles oder ein Handle mit einem anderen Zugriff als das ursprüngliche 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 ein echtes Prozesshandle.This handle is a pseudo handle, but duplicateHandle converts it to a real process handle. Um das Zielprozesshandle abzurufen, kann es erforderlich sein, eine Form der prozessübergreifenden Kommunikation (z. B. eine Named Pipe oder einen freigegebenen Arbeitsspeicher) 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 prozessübergreifende Kommunikation verwenden, um den Wert des doppelten Handles an den Zielprozess zu übergeben.

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

DuplicateHandle kann Handles auf die folgenden Objekttypen duplizieren.

Object 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 zur Verwendung 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 zur Verwendung im selben Prozess dupliziert werden.
Desktop 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.
Auftrag 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.
Pipe Ein Named Pipe-Handle wird von der CreateNamedPipe- oder CreateFile-Funktion zurückgegeben. Ein anonymes 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 von der RegConnectRegistry-Funktion zurückgegebene Registrierungsschlüsselhandles nicht in einem Aufruf von DuplicateHandle verwendet werden können.
Semaphore Das Handle wird von der CreateSemaphore - oder OpenSemaphore-Funktion zurückgegeben.
Thread Das Handle wird von der Funktion CreateProcess, CreateThread, CreateRemoteThread oder GetCurrentThread zurückgegeben.
Timer 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.
  • Sockets. Es wird kein Fehler zurückgegeben, aber das doppelte Handle wird von Winsock möglicherweise nicht im 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.
  • Andere Pseudohandles als die von den Funktionen GetCurrentProcess oder GetCurrentThread zurückgegebenen.
Der dwDesiredAccess-Parameter gibt die Zugriffsrechte des neuen Handles an. Alle Objekte unterstützen die Standardzugriffsrechte. Objekte können je nach Objekttyp auch zusätzliche Zugriffsrechte unterstützen. Weitere Informationen finden Sie in den folgenden Themen: In einigen Fällen kann das neue Handle über mehr Zugriffsrechte als das ursprüngliche Handle verfügen. In anderen Fällen kann DuplicateHandle jedoch kein Handle mit mehr Zugriffsrechten als das Original erstellen. Beispielsweise kann ein Dateihandle, das mit dem Zugriffsrecht GENERIC_READ erstellt wurde, nicht dupliziert werden, sodass es sowohl über das GENERIC_READ als auch über GENERIC_WRITE Zugriffsrecht verfügt.

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

  • Legen Sie hSourceProcessHandle auf den Zielprozess aus dem DuplicateHandle-Aufruf fest, der das Handle erstellt hat.
  • 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 das 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
Unterstützte Mindestversion (Client) Windows 2000 Professional [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows 2000 Server [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile handleapi.h (Einschließen von Windows.h)
Bibliothek Kernel32.lib
DLL Kernel32.dll

Siehe auch

CloseHandle

Vererbung von Handles

Handle- und Objektfunktionen