Функция 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 .
Файловый Дескриптор возвращается функцией 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

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

Дескриптор и объектные функции