windows-nt/Source/XPSP1/NT/base/win32/client/handle.c
2020-09-26 16:20:57 +08:00

361 lines
9.8 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
handle.c
Abstract:
This module implements the Win32 handle management services.
Author:
Mark Lucovsky (markl) 21-Sep-1990
Revision History:
--*/
#include "basedll.h"
BOOL
CloseHandle(
HANDLE hObject
)
/*++
Routine Description:
An open handle to any object can be closed using CloseHandle.
This is a generic function and operates on the following object
types:
- Process Object
- Thread Object
- Mutex Object
- Event Object
- Semaphore Object
- File Object
Please note that Module Objects are not in this list.
Closing an open handle to an object causes the handle to become
invalid and the HandleCount of the associated object to be
decremented and object retention checks to be performed. Once the
last open handle to an object is closed, the object is removed from
the system.
Arguments:
hObject - An open handle to an object.
Return Value:
TRUE - The operation was successful.
FALSE/NULL - The operation failed. Extended error status is available
using GetLastError.
--*/
{
NTSTATUS Status;
PPEB Peb;
Peb = NtCurrentPeb();
switch( HandleToUlong(hObject) ) {
case STD_INPUT_HANDLE: hObject = Peb->ProcessParameters->StandardInput;
break;
case STD_OUTPUT_HANDLE: hObject = Peb->ProcessParameters->StandardOutput;
break;
case STD_ERROR_HANDLE: hObject = Peb->ProcessParameters->StandardError;
break;
}
if (CONSOLE_HANDLE(hObject)) {
return CloseConsoleHandle(hObject);
}
Status = NtClose(hObject);
if ( NT_SUCCESS(Status) ) {
return TRUE;
}
else {
BaseSetLastNTError(Status);
return FALSE;
}
}
BOOL
DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
LPHANDLE lpTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions
)
/*++
Routine Description:
A duplicate handle can be created with the DuplicateHandle function.
This is a generic function and operates on the following object
types:
- Process Object
- Thread Object
- Mutex Object
- Event Object
- Semaphore Object
- File Object
Please note that Module Objects are not in this list.
This function requires PROCESS_DUP_ACCESS to both the
SourceProcessHandle and the TargetProcessHandle. This function is
used to pass an object handle from one process to another. Once
this call is complete, the target process needs to be informed of
the value of the target handle. The target process can then operate
on the object using this handle value.
Arguments:
hSourceProcessHandle - An open handle to the process that contains the
handle to be duplicated. The handle must have been created with
PROCESS_DUP_HANDLE access to the process.
hSourceHandle - An open handle to any object that is valid in the
context of the source process.
hTargetProcessHandle - An open handle to the process that is to
receive the duplicated handle. The handle must have been
created with PROCESS_DUP_HANDLE access to the process.
lpTargetHandle - A pointer to a variable which receives the new handle
that points to the same object as SourceHandle does. This
handle value is valid in the context of the target process.
dwDesiredAccess - The access requested to for the new handle. This
parameter is ignored if the DUPLICATE_SAME_ACCESS option is
specified.
bInheritHandle - Supplies a flag that if TRUE, marks the target
handle as inheritable. If this is the case, then the target
handle will be inherited to new processes each time the target
process creates a new process using CreateProcess.
dwOptions - Specifies optional behaviors for the caller.
Options Flags:
DUPLICATE_CLOSE_SOURCE - The SourceHandle will be closed by
this service prior to returning to the caller. This occurs
regardless of any error status returned.
DUPLICATE_SAME_ACCESS - The DesiredAccess parameter is ignored
and instead the GrantedAccess associated with SourceHandle
is used as the DesiredAccess when creating the TargetHandle.
Return Value:
TRUE - The operation was successful.
FALSE/NULL - The operation failed. Extended error status is available
using GetLastError.
--*/
{
NTSTATUS Status;
PPEB Peb;
Peb = NtCurrentPeb();
switch( HandleToUlong(hSourceHandle) ) {
case STD_INPUT_HANDLE: hSourceHandle = Peb->ProcessParameters->StandardInput;
break;
case STD_OUTPUT_HANDLE: hSourceHandle = Peb->ProcessParameters->StandardOutput;
break;
case STD_ERROR_HANDLE: hSourceHandle = Peb->ProcessParameters->StandardError;
break;
}
if (CONSOLE_HANDLE(hSourceHandle) &&
(hSourceHandle != NtCurrentProcess() &&
hSourceHandle != NtCurrentThread()) ) {
HANDLE Target;
if (hSourceProcessHandle != NtCurrentProcess() ||
hTargetProcessHandle != NtCurrentProcess()) {
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return FALSE;
}
Target = DuplicateConsoleHandle(hSourceHandle,
dwDesiredAccess,
bInheritHandle,
dwOptions
);
if (Target == INVALID_HANDLE_VALUE) {
return FALSE;
}
else {
try {
if ( ARGUMENT_PRESENT(lpTargetHandle) ) {
*lpTargetHandle = Target;
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
return TRUE;
}
return TRUE;
}
}
Status = NtDuplicateObject(
hSourceProcessHandle,
hSourceHandle,
hTargetProcessHandle,
lpTargetHandle,
(ACCESS_MASK)dwDesiredAccess,
bInheritHandle ? OBJ_INHERIT : 0,
dwOptions
);
if ( NT_SUCCESS(Status) ) {
return TRUE;
}
else {
BaseSetLastNTError(Status);
return FALSE;
}
return FALSE;
}
BOOL
GetHandleInformation(
HANDLE hObject,
LPDWORD lpdwFlags
)
{
NTSTATUS Status;
OBJECT_HANDLE_FLAG_INFORMATION HandleInfo;
DWORD Result;
PPEB Peb;
Peb = NtCurrentPeb();
switch( HandleToUlong(hObject) ) {
case STD_INPUT_HANDLE: hObject = Peb->ProcessParameters->StandardInput;
break;
case STD_OUTPUT_HANDLE: hObject = Peb->ProcessParameters->StandardOutput;
break;
case STD_ERROR_HANDLE: hObject = Peb->ProcessParameters->StandardError;
break;
}
if (CONSOLE_HANDLE(hObject)) {
return GetConsoleHandleInformation(hObject,
lpdwFlags
);
}
Status = NtQueryObject( hObject,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof( HandleInfo ),
NULL
);
if (NT_SUCCESS( Status )) {
Result = 0;
if (HandleInfo.Inherit) {
Result |= HANDLE_FLAG_INHERIT;
}
if (HandleInfo.ProtectFromClose) {
Result |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
}
*lpdwFlags = Result;
return TRUE;
}
else {
BaseSetLastNTError( Status );
return FALSE;
}
}
BOOL
SetHandleInformation(
HANDLE hObject,
DWORD dwMask,
DWORD dwFlags
)
{
NTSTATUS Status;
OBJECT_HANDLE_FLAG_INFORMATION HandleInfo;
PPEB Peb;
Peb = NtCurrentPeb();
switch( HandleToUlong(hObject) ) {
case STD_INPUT_HANDLE: hObject = Peb->ProcessParameters->StandardInput;
break;
case STD_OUTPUT_HANDLE: hObject = Peb->ProcessParameters->StandardOutput;
break;
case STD_ERROR_HANDLE: hObject = Peb->ProcessParameters->StandardError;
break;
}
if (CONSOLE_HANDLE(hObject)) {
return SetConsoleHandleInformation(hObject,
dwMask,
dwFlags
);
}
Status = NtQueryObject( hObject,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof( HandleInfo ),
NULL
);
if (NT_SUCCESS( Status )) {
if (dwMask & HANDLE_FLAG_INHERIT) {
HandleInfo.Inherit = (dwFlags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
}
if (dwMask & HANDLE_FLAG_PROTECT_FROM_CLOSE) {
HandleInfo.ProtectFromClose = (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
}
Status = NtSetInformationObject( hObject,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof( HandleInfo )
);
if (NT_SUCCESS( Status )) {
return TRUE;
}
}
BaseSetLastNTError( Status );
return FALSE;
}