Поделиться через


Функция DuplicateHandle (handleapi.h)

Дублирует дескриптор объекта.

Синтаксис

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

Параметры

[in] hSourceProcessHandle

Дескриптор процесса с дескриптором для дублирования.

Дескриптор должен иметь право доступа к PROCESS_DUP_HANDLE. Дополнительные сведения см. в разделе Управление правами на доступ и безопасность процесса.

[in] hSourceHandle

Повторяющийся дескриптор. Это открытый дескриптор объекта, допустимый в контексте исходного процесса. Список объектов, дескрипторы которых можно дублировать, см. в следующем разделе Примечания.

[in] hTargetProcessHandle

Дескриптор процесса, который получает дублированный дескриптор. Дескриптор должен иметь право доступа к PROCESS_DUP_HANDLE.

Этот параметр является необязательным и может быть указан как NULL, если флаг DUPLICATE_CLOSE_SOURCE установлен в разделе Параметры.

[out] lpTargetHandle

Указатель на переменную, которая получает повторяющийся дескриптор. Это значение дескриптора допустимо в контексте целевого процесса.

Если hSourceHandle является псевдо дескриптором, возвращаемым GetCurrentProcess или GetCurrentThread, DuplicateHandle преобразует его в реальный дескриптор в процесс или поток соответственно.

Если lpTargetHandle имеет значение NULL, функция дублирует дескриптор, но не возвращает значение повторяющегося дескриптора вызывающей объекту. Такое поведение существует только для обратной совместимости с предыдущими версиями этой функции. Не следует использовать эту функцию, так как системные ресурсы будут потеряны до завершения целевого процесса.

Этот параметр игнорируется, если hTargetProcessHandle имеет значение NULL.

[in] dwDesiredAccess

Доступ, запрошенный для нового дескриптора. Флаги, которые можно указать для каждого типа объекта, см. в следующем разделе Примечания.

Этот параметр игнорируется, если параметр dwOptions задает флаг DUPLICATE_SAME_ACCESS. В противном случае флаги, которые можно указать, зависят от типа объекта, дескриптор которого должен дублироваться.

Этот параметр игнорируется, если hTargetProcessHandle имеет значение NULL.

[in] bInheritHandle

Переменная, указывающая, наследуется ли дескриптор. Если значение РАВНО TRUE, повторяющийся дескриптор может быть унаследован новыми процессами, созданными целевым процессом. При значении FALSE новый дескриптор не может быть унаследован.

Этот параметр игнорируется, если hTargetProcessHandle имеет значение NULL.

[in] dwOptions

Необязательные действия. Этот параметр может иметь нулевое значение или любое сочетание следующих значений.

Значение Значение
DUPLICATE_CLOSE_SOURCE
0x00000001
Закрывает исходный дескриптор. Это происходит независимо от возвращаемого состояния ошибки.
DUPLICATE_SAME_ACCESS
0x00000002
Игнорирует параметр dwDesiredAccess . Повторяющийся дескриптор имеет тот же доступ, что и исходный дескриптор.

Возвращаемое значение

Если функция выполняется успешно, возвращается ненулевое значение.

Если функция выполняется неудачно, возвращается нулевое значение. Дополнительные сведения об ошибке можно получить, вызвав GetLastError.

Комментарии

Повторяющийся дескриптор ссылается на тот же объект, что и исходный дескриптор. Поэтому любые изменения объекта отражаются через оба дескриптора. Например, если дублировать дескриптор файла, текущее положение файла всегда будет одинаковым для обоих дескрипторов. Чтобы дескрипторы файлов имели разные позиции, используйте функцию CreateFile , чтобы создать дескрипторы файлов, которые совместно используют доступ к одному файлу.

DuplicateHandle может вызываться либо исходным процессом, либо целевым процессом (или процессом, который является как исходным, так и целевым процессом). Например, процесс может использовать DuplicateHandle для создания неустранимой копии наследуемого дескриптора или дескриптора с доступом, отличным от исходного дескриптора.

Исходный процесс использует функцию GetCurrentProcess для получения дескриптора к себе. Этот дескриптор является псевдо дескриптором, но DuplicateHandle преобразует его в реальный дескриптор процесса. Чтобы получить целевой дескриптор процесса, может потребоваться использовать определенную форму межпроцессного взаимодействия (например, именованный канал или общую память) для передачи идентификатора процесса исходному процессу. Исходный процесс может использовать этот идентификатор в функции OpenProcess для получения дескриптора целевого процесса.

Если процесс, вызывающий DuplicateHandle , также не является целевым процессом, исходный процесс должен использовать межпроцессное взаимодействие для передачи значения дубликата дескриптора целевому процессу.

DuplicateHandle можно использовать для дублирования дескриптора между 32-разрядным и 64-разрядным процессами. Результирующий дескриптор имеет соответствующий размер для работы в целевом процессе. Дополнительные сведения см. в разделе Взаимодействие процессов.

DuplicateHandle может дублировать дескрипторы для следующих типов объектов.

Объект Описание
Маркер доступа Дескриптор возвращается функцией CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken или OpenThreadToken .
Уведомление об изменениях Дескриптор возвращается функцией FindFirstChangeNotification .
Устройство связи Дескриптор возвращается функцией CreateFile .
Входные данные консоли Дескриптор возвращается функцией CreateFile при указании CONIN$, или функцией GetStdHandle , когда задано STD_INPUT_HANDLE. Дескрипторы консоли можно дублировать для использования только в том же процессе.
Буфер экрана консоли Дескриптор возвращается функцией CreateFile при указании CONOUT$ или функцией GetStdHandle при указании STD_OUTPUT_HANDLE. Дескрипторы консоли можно дублировать для использования только в том же процессе.
Персональный компьютер Дескриптор возвращается функцией GetThreadDesktop .
Событие Дескриптор возвращается функцией CreateEvent или OpenEvent .
File Дескриптор возвращается функцией CreateFile .
Сопоставление файлов Дескриптор возвращается функцией CreateFileMapping .
Задание Дескриптор возвращается функцией CreateJobObject .
Mailslot Дескриптор возвращается функцией CreateMailslot .
Mutex Дескриптор возвращается методом CreateMutex или [OpenMutex](.. Функция /synchapi/nf-synchapi-openmutexw.md).
канал Дескриптор именованного канала возвращается функцией CreateNamedPipe или CreateFile . Анонимный дескриптор канала возвращается функцией CreatePipe .
Процесс Дескриптор возвращается функцией CreateProcess, GetCurrentProcess или OpenProcess .
Раздел реестра Дескриптор возвращается функцией RegCreateKey, RegCreateKeyEx, RegOpenKey или RegOpenKeyEx . Обратите внимание, что дескриптора раздела реестра, возвращаемые функцией RegConnectRegistry , нельзя использовать в вызове DuplicateHandle.
Semaphore Дескриптор возвращается функцией CreateSemaphore или OpenSemaphore .
Thread Дескриптор возвращается функцией CreateProcess, CreateThread, CreateRemoteThread или GetCurrentThread .
Таймер Дескриптор возвращается функцией CreateWaitableTimerW или OpenWaitableTimerW .
Транзакция Дескриптор возвращается функцией CreateTransaction .
Оконная станция Дескриптор возвращается функцией GetProcessWindowStation .
 

Не следует использовать DuplicateHandle для дублирования дескрипторов для следующих объектов:

  • Порты завершения ввода-вывода. Ошибка не возвращается, но дескриптор дубликата не может быть использован.
  • Сокеты. Ошибка не возвращается, но дескриптор дубликата может быть не распознан Winsock в целевом процессе. Кроме того, использование DuplicateHandle влияет на подсчет внутренних ссылок на базовый объект. Чтобы дублировать дескриптор сокета, используйте функцию WSADuplicateSocket .
  • Псевдообработки, отличные от тех, которые возвращаются функциями GetCurrentProcess или GetCurrentThread .
Параметр dwDesiredAccess указывает права доступа нового дескриптора. Все объекты поддерживают стандартные права доступа. Объекты также могут поддерживать дополнительные права доступа в зависимости от типа объекта. Дополнительные сведения см. в следующих разделах: В некоторых случаях новый дескриптор может иметь больше прав доступа, чем исходный дескриптор. Однако в других случаях DuplicateHandle не может создать дескриптор с большими правами доступа, чем исходный. Например, дескриптор файла, созданный с GENERIC_READ правом доступа, не может дублироваться таким образом, чтобы у него было право доступа GENERIC_READ и GENERIC_WRITE.

Обычно целевой процесс закрывает повторяющийся дескриптор после завершения этого процесса с помощью дескриптора. Чтобы закрыть дублированный дескриптор из исходного процесса, вызовите DuplicateHandle со следующими параметрами:

  • Присвойте hSourceProcessHandle целевому процессу из вызова DuplicateHandle , создавшего дескриптор.
  • Присвойте hSourceHandle повторяющийся дескриптор для закрытия.
  • Задайте для hTargetProcessHandleзначение NULL.
  • Задайте для dwOptions значение DUPLICATE_CLOSE_SOURCE.

Примеры

В следующем примере создается мьютекс, дублируется дескриптор мьютекса и передается в другой поток. Дублирование дескриптора гарантирует увеличение количества ссылок, чтобы объект мьютекса не был уничтожен до тех пор, пока оба потока не закроют дескриптор.

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

Требования

Требование Значение
Минимальная версия клиента Windows 2000 Профессиональная [классические приложения | Приложения UWP]
Минимальная версия сервера Windows 2000 Server [классические приложения | Приложения UWP]
Целевая платформа Windows
Header handleapi.h (включая Windows.h)
Библиотека Kernel32.lib
DLL Kernel32.dll

См. также

CloseHandle

Обработка наследования

Функции дескрипторов и объектов