Función DuplicateHandle (handleapi.h)
Duplica un identificador de objeto.
Sintaxis
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
Identificador del proceso con el identificador que se va a duplicar.
El identificador debe tener el derecho de acceso PROCESS_DUP_HANDLE. Para obtener más información, consulte Derechos de acceso y seguridad de procesos.
[in] hSourceHandle
Identificador que se va a duplicar. Se trata de un identificador de objeto abierto que es válido en el contexto del proceso de origen. Para obtener una lista de objetos cuyos identificadores se pueden duplicar, vea la siguiente sección Comentarios.
[in] hTargetProcessHandle
Identificador del proceso que va a recibir el identificador duplicado. El identificador debe tener el derecho de acceso PROCESS_DUP_HANDLE.
Este parámetro es opcional y se puede especificar como NULL si la marca DUPLICATE_CLOSE_SOURCE está establecida en Opciones.
[out] lpTargetHandle
Puntero a una variable que recibe el identificador duplicado. Este valor de identificador es válido en el contexto del proceso de destino.
Si hSourceHandle es un pseudo identificador devuelto por GetCurrentProcess o GetCurrentThread, DuplicateHandle lo convierte en un identificador real en un proceso o subproceso, respectivamente.
Si lpTargetHandle es NULL, la función duplica el identificador, pero no devuelve el valor de identificador duplicado al autor de la llamada. Este comportamiento solo existe para la compatibilidad con versiones anteriores de esta función. No debe usar esta característica, ya que perderá los recursos del sistema hasta que finalice el proceso de destino.
Este parámetro se omite si hTargetProcessHandle es NULL.
[in] dwDesiredAccess
El acceso solicitado para el nuevo identificador. Para ver las marcas que se pueden especificar para cada tipo de objeto, vea la sección Comentarios siguiente.
Este parámetro se omite si el parámetro dwOptions especifica la marca DUPLICATE_SAME_ACCESS. De lo contrario, las marcas que se pueden especificar dependen del tipo de objeto cuyo identificador se va a duplicar.
Este parámetro se omite si hTargetProcessHandle es NULL.
[in] bInheritHandle
Variable que indica si el identificador es heredable. Si es TRUE, los nuevos procesos creados por el proceso de destino pueden heredar el identificador duplicado. Si es FALSE, no se puede heredar el nuevo identificador.
Este parámetro se omite si hTargetProcessHandle es NULL.
[in] dwOptions
Acciones opcionales. Este parámetro puede ser cero o cualquier combinación de los valores siguientes.
Valor devuelto
Si la función se realiza correctamente, el valor devuelto es distinto de cero.
Si la función no se realiza correctamente, el valor devuelto es cero. Para obtener información de error extendida, llame a GetLastError.
Comentarios
El identificador duplicado hace referencia al mismo objeto que el identificador original. Por lo tanto, los cambios realizados en el objeto se reflejan a través de ambos identificadores. Por ejemplo, si duplica un identificador de archivo, la posición del archivo actual siempre es la misma para ambos identificadores. Para que los identificadores de archivo tengan diferentes posiciones de archivo, use la función CreateFile para crear identificadores de archivo que comparten el acceso al mismo archivo.
Se puede llamar a DuplicateHandle mediante el proceso de origen o el proceso de destino (o un proceso que sea el proceso de origen y de destino). Por ejemplo, un proceso puede usar DuplicateHandle para crear un duplicado no heredable de un identificador heredable o un identificador con acceso diferente al identificador original.
El proceso de origen usa la función GetCurrentProcess para obtener un identificador a sí mismo. Este identificador es un pseudo handle, pero DuplicateHandle lo convierte en un identificador de proceso real. Para obtener el identificador del proceso de destino, puede ser necesario usar alguna forma de comunicación entre procesos (por ejemplo, una canalización con nombre o memoria compartida) para comunicar el identificador de proceso al proceso de origen. El proceso de origen puede usar este identificador en la función OpenProcess para obtener un identificador para el proceso de destino.
Si el proceso que llama a DuplicateHandle no es también el proceso de destino, el proceso de origen debe usar la comunicación entre procesos para pasar el valor del identificador duplicado al proceso de destino.
DuplicateHandle se puede usar para duplicar un identificador entre un proceso de 32 bits y un proceso de 64 bits. El identificador resultante tiene el tamaño adecuado para funcionar en el proceso de destino. Para obtener más información, consulte Interoperabilidad de procesos.
DuplicateHandle puede duplicar identificadores para los siguientes tipos de objetos.
Object | Descripción |
---|---|
Access token | El identificador lo devuelve la función CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken o OpenThreadToken . |
Notificación de cambios | La función FindFirstChangeNotification devuelve el identificador. |
Dispositivo de comunicaciones | La función CreateFile devuelve el identificador. |
Entrada de la consola | La función CreateFile devuelve el identificador cuando se especifica CONIN$ o mediante la función GetStdHandle cuando se especifica STD_INPUT_HANDLE. Los identificadores de consola solo se pueden duplicar para su uso en el mismo proceso. |
Búfer de pantalla de la consola | La función CreateFile devuelve el identificador cuando se especifica CONOUT$ o mediante la función GetStdHandle cuando se especifica STD_OUTPUT_HANDLE. Los identificadores de consola solo se pueden duplicar para su uso en el mismo proceso. |
Escritorio | La función GetThreadDesktop devuelve el identificador. |
Evento | El identificador lo devuelve la función CreateEvent o OpenEvent . |
Archivo | La función CreateFile devuelve el identificador. |
Asignación de archivos | La función CreateFileMapping devuelve el identificador. |
Trabajo | La función CreateJobObject devuelve el identificador. |
Mailslot | La función CreateMailslot devuelve el identificador. |
Mutex | El identificador lo devuelve CreateMutex o [OpenMutex](.. Función /synchapi/nf-synchapi-openmutexw.md). |
Pipe | La función CreateNamedPipe o CreateFile devuelve un identificador de canalización con nombre. La función CreatePipe devuelve un identificador de canalización anónimo. |
Proceso | El identificador lo devuelve la función CreateProcess, GetCurrentProcess o OpenProcess . |
Clave del Registro | El identificador lo devuelve la función RegCreateKey, RegCreateKeyEx, RegOpenKey o RegOpenKeyEx . Tenga en cuenta que los identificadores de clave del Registro devueltos por la función RegConnectRegistry no se pueden usar en una llamada a DuplicateHandle. |
Semaphore | La función CreateSemaphore o OpenSemaphore devuelve el identificador. |
Thread | El identificador lo devuelve la función CreateProcess, CreateThread, CreateRemoteThread o GetCurrentThread . |
Temporizador | El identificador lo devuelve la función CreateWaitableTimerW o OpenWaitableTimerW . |
Transacción | La función CreateTransaction devuelve el identificador. |
Estación de ventana | La función GetProcessWindowStation devuelve el identificador. |
No debe usar DuplicateHandle para duplicar identificadores de los objetos siguientes:
- Puertos de finalización de E/S. No se devuelve ningún error, pero no se puede usar el identificador duplicado.
- Sockets. No se devuelve ningún error, pero Winsock no reconoce el identificador duplicado en el proceso de destino. Además, el uso de DuplicateHandle interfiere con el recuento de referencias internas en el objeto subyacente. Para duplicar un identificador de socket, use la función WSADuplicateSocket .
- Pseudo-handles distintos de los devueltos por las funciones GetCurrentProcess o GetCurrentThread .
- Derechos de acceso y seguridad de escritorio
- Seguridad y derechos de acceso de los archivos
- Derechos de acceso y seguridad de asignación de archivos
- Derechos de acceso y seguridad de objetos de trabajo
- Derechos de seguridad y acceso de procesos
- Derechos de acceso y seguridad de clave del Registro
- Derechos de acceso y seguridad de objetos de sincronización
- Derechos de acceso y seguridad de subprocesos
- Derechos de seguridad y acceso de la estación de ventanas
Normalmente, el proceso de destino cierra un identificador duplicado cuando ese proceso finaliza con el identificador . Para cerrar un identificador duplicado del proceso de origen, llame a DuplicateHandle con los parámetros siguientes:
- Establezca hSourceProcessHandle en el proceso de destino desde la llamada DuplicateHandle que creó el identificador.
- Establezca hSourceHandle en el identificador duplicado para cerrar.
- Establezca hTargetProcessHandle en NULL.
- Establezca dwOptions en DUPLICATE_CLOSE_SOURCE.
Ejemplos
En el ejemplo siguiente se crea una exclusión mutua, se duplica un identificador para la exclusión mutua y se pasa a otro subproceso. Duplicar el identificador garantiza que se aumente el recuento de referencias para que el objeto de exclusión mutua no se destruya hasta que ambos subprocesos hayan cerrado el 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 | Value |
---|---|
Cliente mínimo compatible | Windows 2000 Professional [aplicaciones de escritorio | Aplicaciones para UWP] |
Servidor mínimo compatible | Windows 2000 Server [aplicaciones de escritorio | Aplicaciones para UWP] |
Plataforma de destino | Windows |
Encabezado | handleapi.h (incluir Windows.h) |
Library | Kernel32.lib |
Archivo DLL | Kernel32.dll |