Funzione DuplicateHandle (handleapi.h)

Duplica un handle di oggetti.

Sintassi

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

Parametri

[in] hSourceProcessHandle

Handle per il processo con l'handle da duplicare.

L'handle deve avere il diritto di accesso PROCESS_DUP_HANDLE. Per altre informazioni, vedere Elaborare diritti di sicurezza e accesso.

[in] hSourceHandle

Handle da duplicare. Si tratta di un handle oggetto aperto valido nel contesto del processo di origine. Per un elenco di oggetti i cui handle possono essere duplicati, vedere la sezione Osservazioni seguenti.

[in] hTargetProcessHandle

Handle per il processo che deve ricevere l'handle duplicato. L'handle deve avere il diritto di accesso PROCESS_DUP_HANDLE.

Questo parametro è facoltativo e può essere specificato come NULL se il flag di DUPLICATE_CLOSE_SOURCE è impostato in Opzioni.

[out] lpTargetHandle

Puntatore a una variabile che riceve l'handle duplicato. Questo valore di handle è valido nel contesto del processo di destinazione.

Se hSourceHandle è uno pseudo handle restituito rispettivamente da GetCurrentProcess o GetCurrentThread, DuplicateHandle lo converte in un handle reale in un processo o in un thread.

Se lpTargetHandle è NULL, la funzione duplica l'handle, ma non restituisce il valore di handle duplicato al chiamante. Questo comportamento esiste solo per la compatibilità con le versioni precedenti di questa funzione. Questa funzionalità non deve essere usata, perché non si perderanno risorse di sistema fino al termine del processo di destinazione.

Questo parametro viene ignorato se hTargetProcessHandle è NULL.

[in] dwDesiredAccess

Accesso richiesto per il nuovo handle. Per i flag che possono essere specificati per ogni tipo di oggetto, vedere la sezione Osservazioni seguente.

Questo parametro viene ignorato se il parametro dwOptions specifica il flag di DUPLICATE_SAME_ACCESS. In caso contrario, i flag che possono essere specificati dipendono dal tipo di oggetto il cui handle deve essere duplicato.

Questo parametro viene ignorato se hTargetProcessHandle è NULL.

[in] bInheritHandle

Variabile che indica se l'handle è ereditabile. Se TRUE, l'handle duplicato può essere ereditato dai nuovi processi creati dal processo di destinazione. Se FALSE, non è possibile ereditare il nuovo handle.

Questo parametro viene ignorato se hTargetProcessHandle è NULL.

[in] dwOptions

Azioni facoltative. Questo parametro può essere zero o qualsiasi combinazione dei valori seguenti.

Valore Significato
DUPLICATE_CLOSE_SOURCE
0x00000001
Chiude l'handle di origine. Ciò si verifica indipendentemente dallo stato di errore restituito.
DUPLICATE_SAME_ACCESS
0x00000002
Ignora il parametro dwDesiredAccess . L'handle duplicato ha lo stesso accesso dell'handle di origine.

Valore restituito

Se la funzione ha esito positivo, il valore restituito è diverso da zero.

Se la funzione ha esito negativo, il valore restituito è zero. Per informazioni dettagliate sull'errore, chiamare GetLastError.

Commenti

L'handle duplicato fa riferimento allo stesso oggetto dell'handle originale. Pertanto, tutte le modifiche apportate all'oggetto vengono riflesse tramite entrambi gli handle. Ad esempio, se si duplica un handle di file, la posizione del file corrente è sempre la stessa per entrambi gli handle. Per gli handle di file in modo che abbiano posizioni file diverse, usare la funzione CreateFile per creare handle di file che condividono l'accesso allo stesso file.

DuplicateHandle può essere chiamato dal processo di origine o dal processo di destinazione o da un processo che è sia il processo di origine che quello di destinazione. Ad esempio, un processo può usare DuplicateHandle per creare un duplicato nonheritable di un handle ereditabile o un handle con accesso diverso rispetto all'handle originale.

Il processo di origine usa la funzione GetCurrentProcess per ottenere un handle a se stesso. Questo handle è uno pseudo handle, ma DuplicateHandle lo converte in un handle di processo reale. Per ottenere l'handle del processo di destinazione, potrebbe essere necessario usare una forma di comunicazione tra processi (ad esempio una pipe denominata o una memoria condivisa) per comunicare l'identificatore del processo al processo di origine. Il processo di origine può usare questo identificatore nella funzione OpenProcess per ottenere un handle per il processo di destinazione.

Se il processo che chiama DuplicateHandle non è anche il processo di destinazione, il processo di origine deve usare la comunicazione interprocesso per passare il valore dell'handle duplicato al processo di destinazione.

DuplicateHandle può essere usato per duplicare un handle tra un processo a 32 bit e un processo a 64 bit. L'handle risultante è di dimensioni appropriate per il funzionamento nel processo di destinazione. Per altre informazioni, vedere Interoperabilità dei processi.

DuplicateHandle può duplicare gli handle ai tipi di oggetti seguenti.

Oggetto Descrizione
Token di accesso L'handle viene restituito dalla funzione CreateRestrictedToken, DuplicateToken,DuplicateTokenEx, OpenProcessToken o OpenThreadToken .
Notifica di modifica L'handle viene restituito dalla funzione FindFirstChangeNotification .
Dispositivo di comunicazione L'handle viene restituito dalla funzione CreateFile .
Input della console L'handle viene restituito dalla funzione CreateFile quando viene specificato CONIN$ o dalla funzione GetStdHandle quando viene specificato STD_INPUT_HANDLE. Gli handle della console possono essere duplicati per l'uso solo nello stesso processo.
Buffer dello schermo della console L'handle viene restituito dalla funzione CreateFile quando viene specificato CONOUT$ o dalla funzione GetStdHandle quando viene specificato STD_OUTPUT_HANDLE. Gli handle della console possono essere duplicati per l'uso solo nello stesso processo.
Desktop L'handle viene restituito dalla funzione GetThreadDesktop .
Evento L'handle viene restituito dalla funzione CreateEvent o OpenEvent .
File L'handle viene restituito dalla funzione CreateFile .
Mapping dei file L'handle viene restituito dalla funzione CreateFileMapping .
Processo L'handle viene restituito dalla funzione CreateJobObject .
Mailslot L'handle viene restituito dalla funzione CreateMailslot .
Mutex L'handle viene restituito da CreateMutex o [OpenMutex ](.. Funzione /synchapi/nf-synchapi-openmutexw.md).
Pipe Un handle pipe denominato viene restituito dalla funzione CreateNamedPipe o CreateFile . Un handle pipe anonimo viene restituito dalla funzione CreatePipe .
Processo L'handle viene restituito dalla funzione CreateProcess, GetCurrentProcess o OpenProcess .
Chiave del Registro di sistema L'handle viene restituito dalla funzione RegCreateKey,RegCreateKeyEx, RegOpenKey o RegOpenKeyEx. Si noti che gli handle delle chiavi del Registro di sistema restituiti dalla funzione RegConnectRegistry non possono essere usati in una chiamata a DuplicateHandle.
Semaphore L'handle viene restituito dalla funzione CreateSemaphore o OpenSemaphore .
Thread L'handle viene restituito dalla funzione CreateProcess, CreateThread, CreateRemoteThread o GetCurrentThread
Timer L'handle viene restituito dalla funzione CreateWaitableTimerW o OpenWaitableTimerW .
Transazione L'handle viene restituito dalla funzione CreateTransaction .
Stazione finestra L'handle viene restituito dalla funzione GetProcessWindowStation .
 

Non usare DuplicateHandle per duplicare gli handle per gli oggetti seguenti:

  • Porte di completamento di I/O. Non viene restituito alcun errore, ma non è possibile usare l'handle duplicato.
  • Socket. Non viene restituito alcun errore, ma l'handle duplicato potrebbe non essere riconosciuto da Winsock nel processo di destinazione. Inoltre, l'uso di DuplicateHandle interferisce con il conteggio dei riferimenti interni sull'oggetto sottostante. Per duplicare un handle socket, usare la funzione WSADuplicateSocket .
  • Pseudo-handle diversi da quelli restituiti dalle funzioni GetCurrentProcess o GetCurrentThread .
Il parametro dwDesiredAccess specifica i diritti di accesso del nuovo handle. Tutti gli oggetti supportano i diritti di accesso standard. Gli oggetti possono anche supportare diritti di accesso aggiuntivi a seconda del tipo di oggetto. Per altre informazioni, vedere gli argomenti seguenti: In alcuni casi, il nuovo handle può avere più diritti di accesso rispetto all'handle originale. In altri casi, tuttavia, DuplicateHandle non può creare un handle con più diritti di accesso rispetto all'originale. Ad esempio, un handle di file creato con il diritto di accesso GENERIC_READ non può essere duplicato in modo che abbia sia il GENERIC_READ che GENERIC_WRITE diritto di accesso.

In genere il processo di destinazione chiude un handle duplicato al termine dell'utilizzo dell'handle. Per chiudere un handle duplicato dal processo di origine, chiamare DuplicateHandle con i parametri seguenti:

  • Impostare hSourceProcessHandle sul processo di destinazione dalla chiamata DuplicateHandle che ha creato l'handle.
  • Impostare hSourceHandle sull'handle duplicato da chiudere.
  • Impostare hTargetProcessHandle suNULL.
  • Impostare dwOptions su DUPLICATE_CLOSE_SOURCE.

Esempio

L'esempio seguente crea un mutex, duplica un handle per il mutex e lo passa a un altro thread. La duplicazione dell'handle garantisce che il conteggio dei riferimenti venga aumentato in modo che l'oggetto mutex non venga eliminato definitivamente finché entrambi i thread non hanno chiuso l'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;
}

Requisiti

Requisito Valore
Client minimo supportato Windows 2000 Professional [app desktop | App UWP]
Server minimo supportato Windows 2000 Server [app desktop | App UWP]
Piattaforma di destinazione Windows
Intestazione handleapi.h (include Windows.h)
Libreria Kernel32.lib
DLL Kernel32.dll

Vedere anche

Closehandle

Gestire l'ereditarietà

Funzioni handle e oggetti