Função DuplicateHandle (handleapi.h)

Duplica um identificador de objeto.

Sintaxe

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

Parâmetros

[in] hSourceProcessHandle

Um identificador para o processo com o identificador a ser duplicado.

O identificador deve ter o direito de acesso PROCESS_DUP_HANDLE. Para obter mais informações, consulte Direitos de acesso e segurança do processo.

[in] hSourceHandle

O identificador a ser duplicado. Esse é um identificador de objeto aberto válido no contexto do processo de origem. Para obter uma lista de objetos cujos identificadores podem ser duplicados, consulte a seção Comentários a seguir.

[in] hTargetProcessHandle

Um identificador para o processo que deve receber o identificador duplicado. O identificador deve ter o direito de acesso PROCESS_DUP_HANDLE.

Esse parâmetro é opcional e pode ser especificado como NULL se o sinalizador DUPLICATE_CLOSE_SOURCE estiver definido em Opções.

[out] lpTargetHandle

Um ponteiro para uma variável que recebe o identificador duplicado. Esse valor de identificador é válido no contexto do processo de destino.

Se hSourceHandle for um pseudo-identificador retornado por GetCurrentProcess ou GetCurrentThread, DuplicateHandle o converterá em um identificador real em um processo ou thread, respectivamente.

Se lpTargetHandle for NULL, a função duplicará o identificador, mas não retornará o valor do identificador duplicado para o chamador. Esse comportamento existe apenas para compatibilidade com versões anteriores dessa função. Você não deve usar esse recurso, pois perderá recursos do sistema até que o processo de destino seja encerrado.

Esse parâmetro será ignorado se hTargetProcessHandle for NULL.

[in] dwDesiredAccess

O acesso solicitado para o novo identificador. Para os sinalizadores que podem ser especificados para cada tipo de objeto, consulte a seção Comentários a seguir.

Esse parâmetro será ignorado se o parâmetro dwOptions especificar o sinalizador DUPLICATE_SAME_ACCESS. Caso contrário, os sinalizadores que podem ser especificados dependem do tipo de objeto cujo identificador deve ser duplicado.

Esse parâmetro será ignorado se hTargetProcessHandle for NULL.

[in] bInheritHandle

Uma variável que indica se o identificador é herdável. Se TRUE, o identificador duplicado poderá ser herdado por novos processos criados pelo processo de destino. Se FALSE, o novo identificador não poderá ser herdado.

Esse parâmetro será ignorado se hTargetProcessHandle for NULL.

[in] dwOptions

Ações opcionais. Esse parâmetro pode ser zero ou qualquer combinação dos valores a seguir.

Valor Significado
DUPLICATE_CLOSE_SOURCE
0x00000001
Fecha o identificador de origem. Isso ocorre independentemente de qualquer erro status retornado.
DUPLICATE_SAME_ACCESS
0x00000002
Ignora o parâmetro dwDesiredAccess . O identificador duplicado tem o mesmo acesso que o identificador de origem.

Valor retornado

Se a função for bem-sucedida, o valor retornado será diferente de zero.

Se a função falhar, o valor retornado será zero. Para obter informações de erro estendidas, chame GetLastError.

Comentários

O identificador duplicado refere-se ao mesmo objeto que o identificador original. Portanto, todas as alterações no objeto são refletidas por meio de ambos os identificadores. Por exemplo, se você duplicar um identificador de arquivo, a posição do arquivo atual será sempre a mesma para ambos os identificadores. Para que os identificadores de arquivo tenham posições de arquivo diferentes, use a função CreateFile para criar identificadores de arquivo que compartilham o acesso ao mesmo arquivo.

DuplicateHandle pode ser chamado pelo processo de origem ou pelo processo de destino (ou um processo que é o processo de origem e de destino). Por exemplo, um processo pode usar DuplicateHandle para criar uma duplicata não herdável de um identificador herdável ou um identificador com acesso diferente do identificador original.

O processo de origem usa a função GetCurrentProcess para obter um identificador para si mesmo. Esse identificador é um pseudo-identificador, mas DuplicateHandle o converte em um identificador de processo real. Para obter o identificador do processo de destino, pode ser necessário usar alguma forma de comunicação entre processos (por exemplo, um pipe nomeado ou memória compartilhada) para comunicar o identificador de processo ao processo de origem. O processo de origem pode usar esse identificador na função OpenProcess para obter um identificador para o processo de destino.

Se o processo que chama DuplicateHandle também não for o processo de destino, o processo de origem deverá usar a comunicação entre processos para passar o valor do identificador duplicado para o processo de destino.

DuplicateHandle pode ser usado para duplicar um identificador entre um processo de 32 bits e um processo de 64 bits. O identificador resultante é dimensionado adequadamente para funcionar no processo de destino. Para obter mais informações, consulte Interoperabilidade do processo.

DuplicateHandle pode duplicar identificadores para os seguintes tipos de objetos.

Objeto Descrição
Token de acesso O identificador é retornado pela função CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken ou OpenThreadToken .
Notificação de alteração O identificador é retornado pela função FindFirstChangeNotification .
Dispositivo de comunicações O identificador é retornado pela função CreateFile .
Entrada do console O identificador é retornado pela função CreateFile quando CONIN$ é especificado ou pela função GetStdHandle quando STD_INPUT_HANDLE é especificado. Os identificadores de console podem ser duplicados para uso somente no mesmo processo.
Buffer de tela do console O identificador é retornado pela função CreateFile quando CONOUT$ é especificado ou pela função GetStdHandle quando STD_OUTPUT_HANDLE é especificado. Os identificadores de console podem ser duplicados para uso somente no mesmo processo.
Área de Trabalho O identificador é retornado pela função GetThreadDesktop .
Evento O identificador é retornado pela função CreateEvent ou OpenEvent .
Arquivo O identificador é retornado pela função CreateFile .
Mapeamento de arquivo O identificador é retornado pela função CreateFileMapping .
Trabalho O identificador é retornado pela função CreateJobObject .
Maillot O identificador é retornado pela função CreateMailslot .
Mutex O identificador é retornado por CreateMutex ou [OpenMutex](.. Função /synchapi/nf-synchapi-openmutexw.md).
Pipe Um identificador de pipe nomeado é retornado pela função CreateNamedPipe ou CreateFile . Um identificador de pipe anônimo é retornado pela função CreatePipe .
Processar O identificador é retornado pela função CreateProcess, GetCurrentProcess ou OpenProcess .
Chave do Registro O identificador é retornado pela função RegCreateKey, RegCreateKeyEx, RegOpenKey ou RegOpenKeyEx . Observe que os identificadores de chave do Registro retornados pela função RegConnectRegistry não podem ser usados em uma chamada para DuplicateHandle.
Sinal O identificador é retornado pela função CreateSemaphore ou OpenSemaphore .
Thread O identificador é retornado pela função CreateProcess, CreateThread, CreateRemoteThread ou GetCurrentThread
Timer O identificador é retornado pela função CreateWaitableTimerW ou OpenWaitableTimerW .
Transação O identificador é retornado pela função CreateTransaction .
Estação de janela O identificador é retornado pela função GetProcessWindowStation .
 

Você não deve usar DuplicateHandle para duplicar identificadores para os seguintes objetos:

  • Portas de conclusão de E/S. Nenhum erro é retornado, mas o identificador duplicado não pode ser usado.
  • Soquetes. Nenhum erro é retornado, mas o identificador duplicado pode não ser reconhecido pelo Winsock no processo de destino. Além disso, o uso de DuplicateHandle interfere na contagem de referência interna no objeto subjacente. Para duplicar um identificador de soquete, use a função WSADuplicateSocket .
  • Pseudo-identificadores diferentes dos retornados pelas funções GetCurrentProcess ou GetCurrentThread .
O parâmetro dwDesiredAccess especifica os direitos de acesso do novo identificador. Todos os objetos dão suporte aos direitos de acesso padrão. Os objetos também podem dar suporte a direitos de acesso adicionais, dependendo do tipo de objeto. Para obter mais informações, consulte estes tópicos: Em alguns casos, o novo identificador pode ter mais direitos de acesso do que o identificador original. No entanto, em outros casos, DuplicateHandle não pode criar um identificador com mais direitos de acesso do que o original. Por exemplo, um identificador de arquivo criado com o direito de acesso GENERIC_READ não pode ser duplicado para que ele tenha o direito de acesso GENERIC_READ e GENERIC_WRITE.

Normalmente, o processo de destino fecha um identificador duplicado quando esse processo é concluído usando o identificador . Para fechar um identificador duplicado do processo de origem, chame DuplicateHandle com os seguintes parâmetros:

  • Defina hSourceProcessHandle como o processo de destino da chamada DuplicateHandle que criou o identificador.
  • Defina hSourceHandle como o identificador duplicado para fechar.
  • Defina hTargetProcessHandle como NULL.
  • Defina dwOptions como DUPLICATE_CLOSE_SOURCE.

Exemplos

O exemplo a seguir cria um mutex, duplica um identificador para o mutex e o passa para outro thread. Duplicar o identificador garante que a contagem de referência seja aumentada para que o objeto mutex não seja destruído até que ambos os threads tenham fechado o identificador.

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

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 2000 Professional [aplicativos da área de trabalho | Aplicativos UWP]
Servidor mínimo com suporte Windows 2000 Server [aplicativos da área de trabalho | Aplicativos UWP]
Plataforma de Destino Windows
Cabeçalho handleapi.h (inclua Windows.h)
Biblioteca Kernel32.lib
DLL Kernel32.dll

Confira também

CloseHandle

Herança de identificador

Funções handle e object