[KERNEL32]: Fix the handle APIs. DuplicateHandle was pretty broken w.r.t console handles, and the Query/Set APIs didn't handle those at all.

svn path=/trunk/; revision=53069
This commit is contained in:
Alex Ionescu 2011-08-04 22:21:39 +00:00
parent 4e634556d9
commit 1ba986ca27

View file

@ -1,209 +1,206 @@
/* $Id$ /*
* * PROJECT: ReactOS Win32 Base API
* COPYRIGHT: See COPYING in the top level directory * LICENSE: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * FILE: dll/win32/kernel32/client/handle.c
* FILE: lib/kernel32/misc/handle.c * PURPOSE: Object Handle Functions
* PURPOSE: Object functions * PROGRAMMERS: Ariadne ( ariadne@xs4all.nl)
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
* UPDATE HISTORY:
* Created 01/11/98
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES *******************************************************************/
#include <k32.h> #include <k32.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* GLOBALS *******************************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
HANDLE WINAPI HANDLE
DuplicateConsoleHandle (HANDLE hConsole, FASTCALL
DWORD dwDesiredAccess, TranslateStdHandle(IN HANDLE hHandle)
BOOL bInheritHandle,
DWORD dwOptions);
/* FUNCTIONS *****************************************************************/
HANDLE FASTCALL
TranslateStdHandle(HANDLE hHandle)
{ {
PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters; PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
switch ((ULONG)hHandle) switch ((ULONG)hHandle)
{ {
case STD_INPUT_HANDLE: return Ppb->StandardInput; case STD_INPUT_HANDLE: return Ppb->StandardInput;
case STD_OUTPUT_HANDLE: return Ppb->StandardOutput; case STD_OUTPUT_HANDLE: return Ppb->StandardOutput;
case STD_ERROR_HANDLE: return Ppb->StandardError; case STD_ERROR_HANDLE: return Ppb->StandardError;
} }
return hHandle; return hHandle;
} }
/* PUBLIC FUNCTIONS ***********************************************************/
/* /*
* @implemented * @implemented
*/ */
BOOL WINAPI BOOL
GetHandleInformation (HANDLE hObject, WINAPI
LPDWORD lpdwFlags) GetHandleInformation(IN HANDLE hObject,
OUT LPDWORD lpdwFlags)
{ {
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo; OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
ULONG BytesWritten; ULONG BytesWritten;
NTSTATUS Status; NTSTATUS Status;
DWORD Flags; DWORD Flags;
hObject = TranslateStdHandle(hObject); hObject = TranslateStdHandle(hObject);
Status = NtQueryObject (hObject, if (IsConsoleHandle(hObject))
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
&BytesWritten);
if (NT_SUCCESS(Status))
{
Flags = 0;
if (HandleInfo.Inherit)
Flags |= HANDLE_FLAG_INHERIT;
if (HandleInfo.ProtectFromClose)
Flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
*lpdwFlags = Flags;
return TRUE;
}
else
{
BaseSetLastNTError (Status);
return FALSE;
}
}
/*
* @implemented
*/
BOOL WINAPI
SetHandleInformation (HANDLE hObject,
DWORD dwMask,
DWORD dwFlags)
{
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
ULONG BytesWritten;
NTSTATUS Status;
hObject = TranslateStdHandle(hObject);
Status = NtQueryObject (hObject,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
&BytesWritten);
if (NT_SUCCESS(Status))
{
if (dwMask & HANDLE_FLAG_INHERIT)
HandleInfo.Inherit = (dwFlags & HANDLE_FLAG_INHERIT) != 0;
if (dwMask & HANDLE_FLAG_PROTECT_FROM_CLOSE)
HandleInfo.ProtectFromClose = (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != 0;
Status = NtSetInformationObject (hObject,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION));
if(!NT_SUCCESS(Status))
{ {
BaseSetLastNTError (Status); /* FIXME: GetConsoleHandleInformation required */
return FALSE; UNIMPLEMENTED;
} BaseSetLastNTError(STATUS_NOT_IMPLEMENTED);
return TRUE;
}
else
{
BaseSetLastNTError (Status);
return FALSE;
}
}
/*
* @implemented
*/
BOOL WINAPI CloseHandle(HANDLE hObject)
/*
* FUNCTION: Closes an open object handle
* PARAMETERS:
* hObject = Identifies an open object handle
* RETURNS: If the function succeeds, the return value is nonzero
* If the function fails, the return value is zero
*/
{
NTSTATUS Status;
hObject = TranslateStdHandle(hObject);
if (IsConsoleHandle(hObject))
{
return(CloseConsoleHandle(hObject));
}
Status = NtClose(hObject);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError (Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL WINAPI DuplicateHandle(HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
LPHANDLE lpTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions)
{
DWORD SourceProcessId, TargetProcessId;
NTSTATUS Status;
hSourceHandle = TranslateStdHandle(hSourceHandle);
if (IsConsoleHandle(hSourceHandle))
{
SourceProcessId = GetProcessId(hSourceProcessHandle);
TargetProcessId = GetProcessId(hTargetProcessHandle);
if (!SourceProcessId || !TargetProcessId ||
SourceProcessId != TargetProcessId ||
SourceProcessId != GetCurrentProcessId())
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*lpTargetHandle = DuplicateConsoleHandle(hSourceHandle, dwDesiredAccess, bInheritHandle, dwOptions); Status = NtQueryObject(hObject,
return *lpTargetHandle != INVALID_HANDLE_VALUE; ObjectHandleFlagInformation,
} &HandleInfo,
sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
&BytesWritten);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
Status = NtDuplicateObject(hSourceProcessHandle, Flags = 0;
hSourceHandle, if (HandleInfo.Inherit) Flags |= HANDLE_FLAG_INHERIT;
hTargetProcessHandle, if (HandleInfo.ProtectFromClose) Flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
lpTargetHandle, *lpdwFlags = Flags;
dwDesiredAccess, return TRUE;
bInheritHandle ? OBJ_INHERIT : 0, }
dwOptions);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError (Status);
return FALSE;
}
return TRUE; /*
* @implemented
*/
BOOL
WINAPI
SetHandleInformation(IN HANDLE hObject,
IN DWORD dwMask,
IN DWORD dwFlags)
{
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
ULONG BytesWritten;
NTSTATUS Status;
hObject = TranslateStdHandle(hObject);
if (IsConsoleHandle(hObject))
{
/* FIXME: SetConsoleHandleInformation required */
UNIMPLEMENTED;
BaseSetLastNTError(STATUS_NOT_IMPLEMENTED);
return FALSE;
}
Status = NtQueryObject(hObject,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
&BytesWritten);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
if (dwMask & HANDLE_FLAG_INHERIT)
{
HandleInfo.Inherit = (dwFlags & HANDLE_FLAG_INHERIT) != 0;
}
if (dwMask & HANDLE_FLAG_PROTECT_FROM_CLOSE)
{
HandleInfo.ProtectFromClose = (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != 0;
}
Status = NtSetInformationObject(hObject,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(HandleInfo));
if (NT_SUCCESS(Status)) return TRUE;
BaseSetLastNTError(Status);
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
CloseHandle(IN HANDLE hObject)
{
NTSTATUS Status;
hObject = TranslateStdHandle(hObject);
if (IsConsoleHandle(hObject)) return CloseConsoleHandle(hObject);
Status = NtClose(hObject);
if (NT_SUCCESS(Status)) return TRUE;
BaseSetLastNTError(Status);
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
DuplicateHandle(IN HANDLE hSourceProcessHandle,
IN HANDLE hSourceHandle,
IN HANDLE hTargetProcessHandle,
OUT LPHANDLE lpTargetHandle,
IN DWORD dwDesiredAccess,
IN BOOL bInheritHandle,
IN DWORD dwOptions)
{
NTSTATUS Status;
HANDLE hTargetHandle;
hSourceHandle = TranslateStdHandle(hSourceHandle);
if ((IsConsoleHandle(hSourceHandle)) &&
((hSourceHandle != NtCurrentProcess()) &&
(hSourceHandle != NtCurrentThread())))
{
if ((hSourceProcessHandle != NtCurrentProcess()) &&
(hTargetProcessHandle != NtCurrentProcess()))
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return FALSE;
}
hTargetHandle = DuplicateConsoleHandle(hSourceHandle,
dwDesiredAccess,
bInheritHandle,
dwOptions);
if (hTargetHandle != INVALID_HANDLE_VALUE)
{
if (lpTargetHandle) *lpTargetHandle = hTargetHandle;
return TRUE;
}
return FALSE;
}
Status = NtDuplicateObject(hSourceProcessHandle,
hSourceHandle,
hTargetProcessHandle,
lpTargetHandle,
dwDesiredAccess,
bInheritHandle ? OBJ_INHERIT : 0,
dwOptions);
if (NT_SUCCESS(Status)) return Status;
BaseSetLastNTError(Status);
return FALSE;
} }
/* /*
@ -211,9 +208,9 @@ BOOL WINAPI DuplicateHandle(HANDLE hSourceProcessHandle,
*/ */
UINT UINT
WINAPI WINAPI
SetHandleCount(UINT nCount) SetHandleCount(IN UINT nCount)
{ {
return nCount; return nCount;
} }
/* /*
@ -240,7 +237,6 @@ CreateSocketHandle(VOID)
DbgPrintEx(0, 0, "Unsupported API - kernel32!CreateSocketHandle() called\n"); DbgPrintEx(0, 0, "Unsupported API - kernel32!CreateSocketHandle() called\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
} }
/* /*