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


Функция 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

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

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

[in] hTargetProcessHandle

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

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

[out] lpTargetHandle

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

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

Если значение 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 для создания дескрипторов файлов, которые совместно используют доступ к одному файлу.

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

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

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

ДубликатHandle можно использовать для дублирования дескриптора между 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 .
Мьютекс Дескриптор возвращается CreateMutex или [OpenMutex](.). Функция /synchapi/nf-synchapi-openmutexw.md.
Труба Именованный дескриптор канала возвращается функцией CreateNamedPipe или CreateFile . Анонимный дескриптор канала возвращается функцией CreatePipe .
Процедура Дескриптор возвращается функцией CreateProcess, GetCurrentProcess или OpenProcess .
Ключ реестра Дескриптор возвращается функцией RegCreateKey, RegCreateKeyEx, RegOpenKey или RegOpenKeyEx. Обратите внимание, что дескриптор раздела реестра, возвращаемый функцией RegConnectRegistry , нельзя использовать в вызове DuplicateHandle.
Семафор Дескриптор возвращается функцией CreateSemaphore или OpenSemaphore .
Нить Дескриптор возвращается функцией CreateProcess, CreateThread, CreateRemoteThread или GetCurrentThread
Таймер Дескриптор возвращается функцией CreateWaitableTimerW или OpenWaitableTimerW .
Транзакция Дескриптор возвращается функцией CreateTransaction .
Станция окон Дескриптор возвращается функцией GetProcessWindowStation .
 

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

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

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

  • Задайте 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]
целевая платформа Виндоус
Заголовок handleapi.h (include Windows.h)
Библиотека Файл Kernel32.lib
Библиотека dll Kernel32.dll

См. также

CloseHandle

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

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