Partager via


Fonction DuplicateHandle (handleapi.h)

Dupliquer un handle d’objet.

Syntaxe

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

Paramètres

[in] hSourceProcessHandle

Handle du processus avec le handle à dupliquer.

Le handle doit disposer du droit d’accès PROCESS_DUP_HANDLE. Pour plus d’informations, consultez Traiter les droits de sécurité et d’accès.

[in] hSourceHandle

Handle à dupliquer. Il s’agit d’un handle d’objet ouvert qui est valide dans le contexte du processus source. Pour obtenir la liste des objets dont les handles peuvent être dupliqués, consultez la section Remarques suivante.

[in] hTargetProcessHandle

Handle du processus qui doit recevoir le handle dupliqué. Le handle doit disposer du droit d’accès PROCESS_DUP_HANDLE.

Ce paramètre est facultatif et peut être spécifié comme NULL si l’indicateur DUPLICATE_CLOSE_SOURCE est défini dans Options.

[out] lpTargetHandle

Pointeur vers une variable qui reçoit le handle dupliqué. Cette valeur de handle est valide dans le contexte du processus cible.

Si hSourceHandle est un pseudo handle retourné par GetCurrentProcess ou GetCurrentThread, DuplicateHandle le convertit en handle réel en processus ou thread, respectivement.

Si lpTargetHandle a la valeur NULL, la fonction dupliquera le handle, mais ne retourne pas la valeur du handle dupliquée à l’appelant. Ce comportement existe uniquement pour la compatibilité descendante avec les versions précédentes de cette fonction. Vous ne devez pas utiliser cette fonctionnalité, car vous perdrez des ressources système jusqu’à ce que le processus cible se termine.

Ce paramètre est ignoré si hTargetProcessHandle a la valeur NULL.

[in] dwDesiredAccess

Accès demandé pour le nouveau handle. Pour connaître les indicateurs qui peuvent être spécifiés pour chaque type d’objet, consultez la section Remarques suivante.

Ce paramètre est ignoré si le paramètre dwOptions spécifie l’indicateur DUPLICATE_SAME_ACCESS. Sinon, les indicateurs qui peuvent être spécifiés dépendent du type d’objet dont le handle doit être dupliqué.

Ce paramètre est ignoré si hTargetProcessHandle a la valeur NULL.

[in] bInheritHandle

Variable qui indique si le handle est héritable. Si la valeur est TRUE, le handle en double peut être hérité par de nouveaux processus créés par le processus cible. Si la valeur est FALSE, le nouveau handle ne peut pas être hérité.

Ce paramètre est ignoré si hTargetProcessHandle a la valeur NULL.

[in] dwOptions

Actions facultatives. Ce paramètre peut être égal à zéro ou à n’importe quelle combinaison des valeurs suivantes.

Valeur Signification
DUPLICATE_CLOSE_SOURCE
0x00000001
Ferme le handle source. Cela se produit quelle que soit l’erreur status retournée.
DUPLICATE_SAME_ACCESS
0x00000002
Ignore le paramètre dwDesiredAccess . Le handle dupliqué a le même accès que le handle source.

Valeur retournée

Si la fonction réussit, la valeur de retour est différente de zéro.

Si la fonction échoue, la valeur de retour est égale à zéro. Pour obtenir des informations détaillées sur l’erreur, appelez GetLastError.

Remarques

Le handle dupliqué fait référence au même objet que le handle d’origine. Par conséquent, toutes les modifications apportées à l’objet sont reflétées dans les deux handles. Par exemple, si vous dupliquez un handle de fichier, la position de fichier actuelle est toujours la même pour les deux handles. Pour que les handles de fichiers aient des positions de fichiers différentes, utilisez la fonction CreateFile pour créer des handles de fichiers qui partagent l’accès au même fichier.

DuplicateHandle peut être appelé par le processus source ou le processus cible (ou par un processus qui est à la fois le processus source et le processus cible). Par exemple, un processus peut utiliser DuplicateHandle pour créer un doublon non inhéritable d’un handle pouvant être hérité, ou un handle avec un accès différent du handle d’origine.

Le processus source utilise la fonction GetCurrentProcess pour obtenir un handle. Ce handle est un pseudo handle, mais DuplicateHandle le convertit en un vrai handle de processus. Pour obtenir le handle de processus cible, il peut être nécessaire d’utiliser une forme de communication interprocess (par exemple, un canal nommé ou une mémoire partagée) pour communiquer l’identificateur du processus au processus source. Le processus source peut utiliser cet identificateur dans la fonction OpenProcess pour obtenir un handle pour le processus cible.

Si le processus qui appelle DuplicateHandle n’est pas également le processus cible, le processus source doit utiliser la communication interprocess pour passer la valeur du handle dupliqué au processus cible.

DuplicateHandle peut être utilisé pour dupliquer un handle entre un processus 32 bits et un processus 64 bits. Le handle résultant est correctement dimensionné pour fonctionner dans le processus cible. Pour plus d’informations, consultez Interopérabilité des processus.

DuplicateHandle peut dupliquer des handles dans les types d’objets suivants.

Object Description
Access token (Jeton d’accès) Le handle est retourné par la fonction CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken ou OpenThreadToken .
Notification de modification Le handle est retourné par la fonction FindFirstChangeNotification .
Appareil de communication Le handle est retourné par la fonction CreateFile .
Entrée console Le handle est retourné par la fonction CreateFile lorsque CONIN$ est spécifié, ou par la fonction GetStdHandle quand STD_INPUT_HANDLE est spécifié. Les handles de console peuvent être dupliqués pour une utilisation uniquement dans le même processus.
Mémoire tampon d’écran de console Le handle est retourné par la fonction CreateFile lorsque CONOUT$ est spécifié, ou par la fonction GetStdHandle quand STD_OUTPUT_HANDLE est spécifié. Les handles de console peuvent être dupliqués pour une utilisation uniquement dans le même processus.
Desktop (Expérience utilisateur) Le handle est retourné par la fonction GetThreadDesktop .
Événement Le handle est retourné par la fonction CreateEvent ou OpenEvent .
Fichier Le handle est retourné par la fonction CreateFile .
Mappage de fichiers Le handle est retourné par la fonction CreateFileMapping .
Travail Le handle est retourné par la fonction CreateJobObject .
Maillot Le handle est retourné par la fonction CreateMailslot .
Mutex Le handle est retourné par CreateMutex ou [OpenMutex](.. Fonction /synchapi/nf-synchapi-openmutexw.md).
Pipe Un handle de canal nommé est retourné par la fonction CreateNamedPipe ou CreateFile . Un handle de canal anonyme est retourné par la fonction CreatePipe .
Processus Le handle est retourné par la fonction CreateProcess, GetCurrentProcess ou OpenProcess .
Clé de Registre Le handle est retourné par la fonction RegCreateKey, RegCreateKeyEx, RegOpenKey ou RegOpenKeyEx . Notez que les handles de clé de Registre retournés par la fonction RegConnectRegistry ne peuvent pas être utilisés dans un appel à DuplicateHandle.
Semaphore Le handle est retourné par la fonction CreateSemaphore ou OpenSemaphore .
Thread Le handle est retourné par la fonction CreateProcess, CreateThread, CreateRemoteThread ou GetCurrentThread
Minuteur Le handle est retourné par la fonction CreateWaitableTimerW ou OpenWaitableTimerW .
Transaction Le handle est retourné par la fonction CreateTransaction .
Station de fenêtre Le handle est retourné par la fonction GetProcessWindowStation .
 

Vous ne devez pas utiliser DuplicateHandle pour dupliquer des handles sur les objets suivants :

  • Ports d’achèvement des E/S. Aucune erreur n’est retournée, mais le handle dupliqué ne peut pas être utilisé.
  • Sockets. Aucune erreur n’est retournée, mais le handle dupliqué peut ne pas être reconnu par Winsock au cours du processus cible. En outre, l’utilisation de DuplicateHandle interfère avec le comptage des références internes sur l’objet sous-jacent. Pour dupliquer un handle de socket, utilisez la fonction WSADuplicateSocket .
  • Pseudo-handles autres que ceux retournés par les fonctions GetCurrentProcess ou GetCurrentThread .
Le paramètre dwDesiredAccess spécifie les droits d’accès du nouveau handle. Tous les objets prennent en charge les droits d’accès standard. Les objets peuvent également prendre en charge des droits d’accès supplémentaires en fonction du type d’objet. Pour plus d'informations, voir les rubriques suivantes : Dans certains cas, le nouveau handle peut avoir plus de droits d’accès que le handle d’origine. Toutefois, dans d’autres cas, DuplicateHandle ne peut pas créer un handle avec plus de droits d’accès que l’original. Par exemple, un handle de fichier créé avec le droit d’accès GENERIC_READ ne peut pas être dupliqué afin qu’il dispose à la fois du droit d’accès GENERIC_READ et GENERIC_WRITE.

Normalement, le processus cible ferme un handle dupliqué lorsque ce processus est terminé à l’aide du handle. Pour fermer un handle dupliqué à partir du processus source, appelez DuplicateHandle avec les paramètres suivants :

  • Définissez hSourceProcessHandle sur le processus cible à partir de l’appel DuplicateHandle qui a créé le handle.
  • Définissez hSourceHandle sur le handle dupliqué à fermer.
  • Définissez hTargetProcessHandle sur NULL.
  • Définissez dwOptions sur DUPLICATE_CLOSE_SOURCE.

Exemples

L’exemple suivant crée un mutex, duplique un handle dans le mutex et le transmet à un autre thread. La duplication du handle garantit que le nombre de références est augmenté afin que l’objet mutex ne soit pas détruit tant que les deux threads n’ont pas fermé le handle.

#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;
}

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows 2000 Professionnel [applications de bureau | Applications UWP]
Serveur minimal pris en charge Windows 2000 Server [applications de bureau | Applications UWP]
Plateforme cible Windows
En-tête handleapi.h (inclure Windows.h)
Bibliothèque Kernel32.lib
DLL Kernel32.dll

Voir aussi

CloseHandle

Gestion de l’héritage

Fonctions de handle et d’objet