Getstdhandle c что это
Перейти к содержимому

Getstdhandle c что это

Getstdhandle c что это

Функция GetStdHandle извлекает дескриптор для стандартного ввода данных, стандартного вывода или стандартной ошибки устройства.

HANDLE GetStdHandle(

DWORD nStdHandle // ввод, вывод или ошибка устройства

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

Дескриптор стандартного устройства ввода данных. Вначале, это — дескриптор консольного буфера ввода, CONIN $.

Дескриптор устройства стандартного вывода. Вначале, это — дескриптор активного экранного буфера консоли, CONOUT $.

Дескриптор стандартной ошибки устройства. Вначале, это — дескриптор активного экранного буфера консоли, CONOUT $.

Если функция завершается успешно, возвращаемое значение — дескриптор определяемого устройства. Дескриптор имеет права доступа GENERIC_READ и GENERIC_WRITE , если приложение не использовало функцию SetStdHandle , чтобы установить стандартный дескриптор с меньшими правами доступа.

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

Дескрипторы, возвращенные функцией GetStdHandle, могут быть использованы прикладными программами, которым нужно читают из или записывать в консоль. Когда консоль создана, дескриптором стандартного ввода является дескриптор буфера ввода консоли, а стандартного вывода и обработки стандартной ошибки является дескриптор активного экранного буфера консоли. Эти дескрипторы могут быть использованы функциями ReadFile и WriteFile , или любой из консольных функций, которые обращаются к консольному буферу ввода или экранному буферу (например, функциям ReadConsoleInput , WriteConsole , или GetConsoleScreenBufferInfo ).

Стандартные дескрипторы процесса могут быть переназначен вызовом функции SetStdHandle , в этом случае функция GetStdHandle возвращает переназначенный дескриптор. Если стандартные дескрипторы были переназначены, Вы можете задать значение CONIN $ при вызове к функции CreateFile , чтобы получить дескриптор для буфера ввода консоли. Точно так же Вы можете задать значение CONOUT $, чтобы получить дескриптор для активного экранного буфера консоли.

Функция GetStdHandle

Извлекает дескриптор для указанного стандартного устройства (стандартный ввод, стандартный вывод или стандартная ошибка).

Синтаксис

Параметры

nStdHandle [ввод]
Стандартное устройство. Этот параметр может принимать одно из указанных ниже значений.

Значение Значение
STD_INPUT_HANDLE ((DWORD)-10) Стандартное устройство ввода. Изначально это входной буфер консоли, CONIN$ .
STD_OUTPUT_HANDLE ((DWORD)-11) Стандартное выходное устройство. Изначально это активный буфер экрана консоли, CONOUT$ .
STD_ERROR_HANDLE ((DWORD)-12) Устройство стандартных ошибок. Изначально это активный буфер экрана консоли, CONOUT$ .

Значения этих констант являются числами без знака, но определяются в файлах заголовков как приведение из числа со знаком и используют компилятор C для их преобразования к 32-разрядному значению, которое ниже максимального. При взаимодействии с этими дескрипторами на языке, который не анализирует заголовки и переопределяет константы, следует учитывать это ограничение. В качестве примера ((DWORD)-10) — это число 4294967286 без знака.

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

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

По завершении работы удалять этот дескриптор с помощью CloseHandle необязательно. Дополнительные сведения см. в примечаниях.

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

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

Комментарии

Дескрипторы, возвращаемые методом GetStdHandle, могут использоваться приложениями, которые должны выполнять чтение или запись данных в консоли. При создании консоли стандартный дескриптор ввода представляет собой дескриптор для входного буфера консоли, а стандартный дескриптор вывода и стандартный дескриптор ошибок являются дескрипторами активного буфера экрана консоли. Эти дескрипторы могут использоваться функциями ReadFile и WriteFile или любыми консольными функциями, которые обращаются к входному буферу консоли или буферу экрана (например, функции ReadConsoleInput, WriteConsole или GetConsoleScreenBufferInfo).

Стандартные дескрипторы процесса могут перенаправляться с помощью вызова SetStdHandle. В этом случае GetStdHandle возвращает перенаправленный дескриптор. Если стандартные дескрипторы были перенаправлены, можно указать значение CONIN$ в вызове функции CreateFile, чтобы получить дескриптор для входного буфера консоли. Аналогичным образом можно указать значение CONOUT$ , чтобы получить дескриптор для активного буфера экрана консоли.

Стандартные дескрипторы процесса вначале метода main определяются конфигурацией флага /SUBSYSTEM, переданного компоновщику при создании приложения. Если указать /SUBSYSTEM:CONSOLE, операционная система получит запрос на заполнение дескрипторов данными сеанса консоли при запуске, если родительский объект еще не заполнил стандартную таблицу дескрипторов путем наследования. /SUBSYSTEM:WINDOWS, в свою очередь, означает, что приложению не нужна консоль и, скорее всего, не будут использоваться стандартные дескрипторы. Дополнительные сведения о наследовании дескриптора можно найти в документации по STARTF_USESTDHANDLES.

Некоторые приложения работают за пределами границ объявленной подсистемы. Например, приложение /SUBSYSTEM:WINDOWS может проверять или использовать стандартные дескрипторы для ведения журнала или отладки, но нормально работать с графическим пользовательским интерфейсом. Эти приложения должны тщательно проверять состояние стандартных дескрипторов при запуске и использовать AttachConsole, AllocConsole и FreeConsole, чтобы добавить или удалить консоль при необходимости.

Некоторые приложения могут также изменять свое поведение в зависимости от типа унаследованного дескриптора. Устранить неоднозначности типа консоли, конвейера, файла и других элементов можно с помощью GetFileType.

Освобождение дескриптора

По завершении работы с дескриптором, полученным от GetStdHandle, использовать CloseHandle необязательно. Возвращаемое значение — это просто копия значения, хранимого в таблице процессов. Сам процесс, как правило, считается владельцем этих дескрипторов и их времени существования. Каждый дескриптор помещается в таблицу при создании в зависимости от наследования. При этом выполняется определенный вызов CreateProcess, и дескриптор будет освобожден при уничтожении процесса.

Изменение времени существования этих дескрипторов вручную может быть желательным для приложения, которое намеренно пытается заменить или заблокировать их использование другими частями процесса. Так как HANDLE можно кэшировать путем выполнения кода, этот код не обязательно будет получать изменения, внесенные через SetStdHandle. Закрытие дескриптора явным образом с помощью CloseHandle закроет его на уровне процесса, и при следующем использовании любой кэшированной ссылки возникнет ошибка.

Действия по замене стандартного дескриптора в таблице процессов заключаются в получении существующего экземпляра HANDLE из таблицы с помощью GetStdHandle. Используйте SetStdHandle для размещения нового экземпляра HANDLE в экземпляр, открытый с помощью CreateFile (или аналогичной функции), а затем закрытия полученного дескриптора.

Проверка значений, хранимых в виде дескрипторов в таблице процессов, функциями GetStdHandle или SetStdHandle не выполняется. Проверка выполняется во время фактической операции чтения или записи, такой как ReadFile или WriteFile.

Поведение при подключении и отключении

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

Если имеющееся значение стандартного дескриптора равно NULL или выглядит как псевдодескриптор консоли, этот дескриптор заменяется дескриптором консоли.

Если родительский элемент для создания консольного процесса использует CREATE_NEW_CONSOLE и STARTF_USESTDHANDLES, стандартные дескрипторы не будут заменены, если только стандартный дескриптор не имеет значение NULL или имеющееся значение не является псевдодескриптором.

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

GetStdHandle function

Retrieves a handle to the specified standard device (standard input, standard output, or standard error).

Syntax

Parameters

nStdHandle [in]
The standard device. This parameter can be one of the following values.

Value Meaning
STD_INPUT_HANDLE ((DWORD)-10) The standard input device. Initially, this is the console input buffer, CONIN$ .
STD_OUTPUT_HANDLE ((DWORD)-11) The standard output device. Initially, this is the active console screen buffer, CONOUT$ .
STD_ERROR_HANDLE ((DWORD)-12) The standard error device. Initially, this is the active console screen buffer, CONOUT$ .

The values for these constants are unsigned numbers, but are defined in the header files as a cast from a signed number and take advantage of the C compiler rolling them over to just under the maximum 32-bit value. When interfacing with these handles in a language that does not parse the headers and is re-defining the constants, please be aware of this constraint. As an example, ((DWORD)-10) is actually the unsigned number 4294967286 .

Return value

If the function succeeds, the return value is a handle to the specified device, or a redirected handle set by a previous call to SetStdHandle. The handle has GENERIC_READ and GENERIC_WRITE access rights, unless the application has used SetStdHandle to set a standard handle with lesser access.

It is not required to dispose of this handle with CloseHandle when done. See Remarks for more information.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

If an application does not have associated standard handles, such as a service running on an interactive desktop, and has not redirected them, the return value is NULL.

Remarks

Handles returned by GetStdHandle can be used by applications that need to read from or write to the console. When a console is created, the standard input handle is a handle to the console’s input buffer, and the standard output and standard error handles are handles of the console’s active screen buffer. These handles can be used by the ReadFile and WriteFile functions, or by any of the console functions that access the console input buffer or a screen buffer (for example, the ReadConsoleInput, WriteConsole, or GetConsoleScreenBufferInfo functions).

The standard handles of a process may be redirected by a call to SetStdHandle, in which case GetStdHandle returns the redirected handle. If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile function to get a handle to a console’s input buffer. Similarly, you can specify the CONOUT$ value to get a handle to a console’s active screen buffer.

The standard handles of a process on entry of the main method are dictated by the configuration of the /SUBSYSTEM flag passed to the linker when the application was built. Specifying /SUBSYSTEM:CONSOLE requests that the operating system fill the handles with a console session on startup, if the parent didn’t already fill the standard handle table by inheritance. On the contrary, /SUBSYSTEM:WINDOWS implies that the application does not need a console and will likely not be making use of the standard handles. More information on handle inheritance can be found in the documentation for STARTF_USESTDHANDLES.

Some applications operate outside the boundaries of their declared subsystem; for instance, a /SUBSYSTEM:WINDOWS application might check/use standard handles for logging or debugging purposes but operate normally with a graphical user interface. These applications will need to carefully probe the state of standard handles on startup and make use of AttachConsole, AllocConsole, and FreeConsole to add/remove a console if desired.

Some applications may also vary their behavior on the type of inherited handle. Disambiguating the type between console, pipe, file, and others can be performed with GetFileType.

Handle disposal

It is not required to CloseHandle when done with the handle retrieved from GetStdHandle. The returned value is simply a copy of the value stored in the process table. The process itself is generally considered the owner of these handles and their lifetime. Each handle is placed in the table on creation depending on the inheritance and launch specifics of the CreateProcess call and will be freed when the process is destroyed.

Manual manipulation of the lifetime of these handles may be desirable for an application intentionally trying to replace them or block other parts of the process from using them. As a HANDLE can be cached by running code, that code will not necessarily pick up changes made via SetStdHandle. Closing the handle explicitly via CloseHandle will close it process-wide and the next usage of any cached reference will encounter an error.

Guidance for replacing a standard handle in the process table would be to get the existing HANDLE from the table with GetStdHandle, use SetStdHandle to place a new HANDLE in that is opened with CreateFile (or a similar function), then to close the retrieved handle.

There is no validation of the values stored as handles in the process table by either the GetStdHandle or SetStdHandle functions. Validation is performed at the time of the actual read/write operation such as ReadFile or WriteFile.

Attach/detach behavior

When attaching to a new console, standard handles are always replaced with console handles unless STARTF_USESTDHANDLES was specified during process creation.

If the existing value of the standard handle is NULL, or the existing value of the standard handle looks like a console pseudohandle, the handle is replaced with a console handle.

When a parent uses both CREATE_NEW_CONSOLE and STARTF_USESTDHANDLES to create a console process, standard handles will not be replaced unless the existing value of the standard handle is NULL or a console pseudohandle.

Console processes must start with the standard handles filled or they will be filled automatically with appropriate handles to a new console. Graphical user interface (GUI) applications can be started without the standard handles and they will not be automatically filled.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *