From 916b14c816ab32d2b620cc3114256591871ca170 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 6 Mar 2003 13:01:15 +0000 Subject: [PATCH] Implemented SignalObjectAndWait(). Added some checks for console handles. svn path=/trunk/; revision=4247 --- reactos/lib/kernel32/file/file.c | 119 +++++++------- reactos/lib/kernel32/synch/wait.c | 259 ++++++++++++++++++++++-------- 2 files changed, 249 insertions(+), 129 deletions(-) diff --git a/reactos/lib/kernel32/file/file.c b/reactos/lib/kernel32/file/file.c index 4d7bd33ffa9..21c215ad6e3 100644 --- a/reactos/lib/kernel32/file/file.c +++ b/reactos/lib/kernel32/file/file.c @@ -1,4 +1,4 @@ -/* $Id: file.c,v 1.41 2003/02/12 00:39:31 hyperion Exp $ +/* $Id: file.c,v 1.42 2003/03/06 13:00:51 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -245,75 +245,72 @@ SetFilePointer(HANDLE hFile, DWORD STDCALL GetFileType(HANDLE hFile) { - FILE_FS_DEVICE_INFORMATION DeviceInfo; - IO_STATUS_BLOCK StatusBlock; - NTSTATUS Status; + FILE_FS_DEVICE_INFORMATION DeviceInfo; + IO_STATUS_BLOCK StatusBlock; + NTSTATUS Status; - /* get real handle */ - switch ((ULONG)hFile) - { - case STD_INPUT_HANDLE: - hFile = NtCurrentPeb()->ProcessParameters->hStdInput; + /* Get real handle */ + switch ((ULONG)hFile) + { + case STD_INPUT_HANDLE: + hFile = NtCurrentPeb()->ProcessParameters->hStdInput; + break; - break; + case STD_OUTPUT_HANDLE: + hFile = NtCurrentPeb()->ProcessParameters->hStdOutput; + break; - case STD_OUTPUT_HANDLE: - hFile = NtCurrentPeb()->ProcessParameters->hStdOutput; + case STD_ERROR_HANDLE: + hFile = NtCurrentPeb()->ProcessParameters->hStdError; + break; + } - break; + /* Check for console handle */ + if (IsConsoleHandle(hFile)) + { + if (VerifyConsoleIoHandle(hFile)) + return FILE_TYPE_CHAR; + } - case STD_ERROR_HANDLE: - hFile = NtCurrentPeb()->ProcessParameters->hStdError; + Status = NtQueryVolumeInformationFile(hFile, + &StatusBlock, + &DeviceInfo, + sizeof(FILE_FS_DEVICE_INFORMATION), + FileFsDeviceInformation); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FILE_TYPE_UNKNOWN; + } - break; - } + switch (DeviceInfo.DeviceType) + { + case FILE_DEVICE_CD_ROM: + case FILE_DEVICE_CD_ROM_FILE_SYSTEM: + case FILE_DEVICE_CONTROLLER: + case FILE_DEVICE_DATALINK: + case FILE_DEVICE_DFS: + case FILE_DEVICE_DISK: + case FILE_DEVICE_DISK_FILE_SYSTEM: + case FILE_DEVICE_VIRTUAL_DISK: + return FILE_TYPE_DISK; - /* check console handles */ - if (IsConsoleHandle(hFile)) - { -// if (VerifyConsoleHandle(hFile)) - return FILE_TYPE_CHAR; - } + case FILE_DEVICE_KEYBOARD: + case FILE_DEVICE_MOUSE: + case FILE_DEVICE_NULL: + case FILE_DEVICE_PARALLEL_PORT: + case FILE_DEVICE_PRINTER: + case FILE_DEVICE_SERIAL_PORT: + case FILE_DEVICE_SCREEN: + case FILE_DEVICE_SOUND: + case FILE_DEVICE_MODEM: + return FILE_TYPE_CHAR; - Status = NtQueryVolumeInformationFile(hFile, - &StatusBlock, - &DeviceInfo, - sizeof(FILE_FS_DEVICE_INFORMATION), - FileFsDeviceInformation); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return FILE_TYPE_UNKNOWN; - } + case FILE_DEVICE_NAMED_PIPE: + return FILE_TYPE_PIPE; + } - switch (DeviceInfo.DeviceType) - { - case FILE_DEVICE_CD_ROM: - case FILE_DEVICE_CD_ROM_FILE_SYSTEM: - case FILE_DEVICE_CONTROLLER: - case FILE_DEVICE_DATALINK: - case FILE_DEVICE_DFS: - case FILE_DEVICE_DISK: - case FILE_DEVICE_DISK_FILE_SYSTEM: - case FILE_DEVICE_VIRTUAL_DISK: - return FILE_TYPE_DISK; - - case FILE_DEVICE_KEYBOARD: - case FILE_DEVICE_MOUSE: - case FILE_DEVICE_NULL: - case FILE_DEVICE_PARALLEL_PORT: - case FILE_DEVICE_PRINTER: - case FILE_DEVICE_SERIAL_PORT: - case FILE_DEVICE_SCREEN: - case FILE_DEVICE_SOUND: - case FILE_DEVICE_MODEM: - return FILE_TYPE_CHAR; - - case FILE_DEVICE_NAMED_PIPE: - return FILE_TYPE_PIPE; - } - - return FILE_TYPE_UNKNOWN; + return FILE_TYPE_UNKNOWN; } diff --git a/reactos/lib/kernel32/synch/wait.c b/reactos/lib/kernel32/synch/wait.c index 9b8a36591c6..0080bba5dd5 100644 --- a/reactos/lib/kernel32/synch/wait.c +++ b/reactos/lib/kernel32/synch/wait.c @@ -1,4 +1,4 @@ -/* $Id: wait.c,v 1.20 2003/02/27 15:40:46 gdalsnes Exp $ +/* $Id: wait.c,v 1.21 2003/03/06 13:01:15 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -33,50 +33,77 @@ WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable) { - NTSTATUS errCode; - PLARGE_INTEGER TimePtr; - LARGE_INTEGER Time; + PLARGE_INTEGER TimePtr; + LARGE_INTEGER Time; + NTSTATUS Status; - if (dwMilliseconds == INFINITE) - { - TimePtr = NULL; - } - else - { - Time.QuadPart = -10000 * dwMilliseconds; - TimePtr = &Time; - } + /* Get real handle */ + switch ((ULONG)hHandle) + { + case STD_INPUT_HANDLE: + hHandle = NtCurrentPeb()->ProcessParameters->hStdInput; + break; - errCode = NtWaitForSingleObject(hHandle, - (BOOLEAN) bAlertable, - TimePtr); - if (errCode == STATUS_TIMEOUT) - { - return WAIT_TIMEOUT; - } - else if ((errCode == WAIT_OBJECT_0) || - (errCode == WAIT_ABANDONED_0)) - { - return(errCode); - } + case STD_OUTPUT_HANDLE: + hHandle = NtCurrentPeb()->ProcessParameters->hStdOutput; + break; - SetLastErrorByStatus (errCode); + case STD_ERROR_HANDLE: + hHandle = NtCurrentPeb()->ProcessParameters->hStdError; + break; + } - return(WAIT_FAILED); + /* Check for console handle */ + if (IsConsoleHandle(hHandle)) + { + if (VerifyConsoleIoHandle(hHandle)) + { + DPRINT1("Console handles are not supported yet!\n"); + SetLastError(ERROR_INVALID_HANDLE); + return WAIT_FAILED; + } + } + + if (dwMilliseconds == INFINITE) + { + TimePtr = NULL; + } + else + { + Time.QuadPart = -10000 * dwMilliseconds; + TimePtr = &Time; + } + + Status = NtWaitForSingleObject(hHandle, + (BOOLEAN) bAlertable, + TimePtr); + if (Status == STATUS_TIMEOUT) + { + return WAIT_TIMEOUT; + } + else if ((Status == WAIT_OBJECT_0) || + (Status == WAIT_ABANDONED_0)) + { + return Status; + } + + SetLastErrorByStatus (Status); + + return WAIT_FAILED; } DWORD STDCALL WaitForMultipleObjects(DWORD nCount, - CONST HANDLE *lpHandles, - BOOL bWaitAll, - DWORD dwMilliseconds) + CONST HANDLE *lpHandles, + BOOL bWaitAll, + DWORD dwMilliseconds) { - return WaitForMultipleObjectsEx(nCount, - lpHandles, - bWaitAll, - dwMilliseconds, - FALSE); + return WaitForMultipleObjectsEx(nCount, + lpHandles, + bWaitAll, + dwMilliseconds, + FALSE); } @@ -87,44 +114,89 @@ WaitForMultipleObjectsEx(DWORD nCount, DWORD dwMilliseconds, BOOL bAlertable) { - NTSTATUS errCode; - LARGE_INTEGER Time; - PLARGE_INTEGER TimePtr; + PLARGE_INTEGER TimePtr; + LARGE_INTEGER Time; + PHANDLE HandleBuffer; + DWORD i; + NTSTATUS Status; - DPRINT("nCount %lu\n", nCount); + DPRINT("nCount %lu\n", nCount); - if (dwMilliseconds == INFINITE) - { - TimePtr = NULL; - } - else - { - Time.QuadPart = -10000 * dwMilliseconds; - TimePtr = &Time; - } + HandleBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nCount * sizeof(HANDLE)); + if (HandleBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return WAIT_FAILED; + } - errCode = NtWaitForMultipleObjects (nCount, - (PHANDLE)lpHandles, - bWaitAll ? WaitAll : WaitAny, - (BOOLEAN)bAlertable, - TimePtr); + for (i = 0; i < nCount; i++) + { + switch ((DWORD)lpHandles[i]) + { + case STD_INPUT_HANDLE: + HandleBuffer[i] = NtCurrentPeb()->ProcessParameters->hStdInput; + break; - if (errCode == STATUS_TIMEOUT) - { - return WAIT_TIMEOUT; - } - else if (((errCode >= WAIT_OBJECT_0) && - (errCode <= WAIT_OBJECT_0 + nCount - 1)) || - ((errCode >= WAIT_ABANDONED_0) && - (errCode <= WAIT_ABANDONED_0 + nCount - 1))) - { - return(errCode); - } + case STD_OUTPUT_HANDLE: + HandleBuffer[i] = NtCurrentPeb()->ProcessParameters->hStdOutput; + break; - DPRINT("errCode %lx\n", errCode); - SetLastErrorByStatus (errCode); + case STD_ERROR_HANDLE: + HandleBuffer[i] = NtCurrentPeb()->ProcessParameters->hStdError; + break; - return(WAIT_FAILED); + default: + HandleBuffer[i] = lpHandles[i]; + break; + } + + /* Check for console handle */ + if (IsConsoleHandle(HandleBuffer[i])) + { + if (VerifyConsoleIoHandle(HandleBuffer[i])) + { + DPRINT1("Console handles are not supported yet!\n"); + RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer); + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + } + } + + if (dwMilliseconds == INFINITE) + { + TimePtr = NULL; + } + else + { + Time.QuadPart = -10000 * dwMilliseconds; + TimePtr = &Time; + } + + Status = NtWaitForMultipleObjects (nCount, + HandleBuffer, + bWaitAll ? WaitAll : WaitAny, + (BOOLEAN)bAlertable, + TimePtr); + + RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer); + + if (Status == STATUS_TIMEOUT) + { + return WAIT_TIMEOUT; + } + else if (((Status >= WAIT_OBJECT_0) && + (Status <= WAIT_OBJECT_0 + nCount - 1)) || + ((Status >= WAIT_ABANDONED_0) && + (Status <= WAIT_ABANDONED_0 + nCount - 1))) + { + return Status; + } + + DPRINT("Status %lx\n", Status); + SetLastErrorByStatus (Status); + + return WAIT_FAILED; } @@ -134,7 +206,58 @@ SignalObjectAndWait(HANDLE hObjectToSignal, DWORD dwMilliseconds, BOOL bAlertable) { - UNIMPLEMENTED + PLARGE_INTEGER TimePtr; + LARGE_INTEGER Time; + NTSTATUS Status; + + /* Get real handle */ + switch ((ULONG)hObjectToWaitOn) + { + case STD_INPUT_HANDLE: + hObjectToWaitOn = NtCurrentPeb()->ProcessParameters->hStdInput; + break; + + case STD_OUTPUT_HANDLE: + hObjectToWaitOn = NtCurrentPeb()->ProcessParameters->hStdOutput; + break; + + case STD_ERROR_HANDLE: + hObjectToWaitOn = NtCurrentPeb()->ProcessParameters->hStdError; + break; + } + + /* Check for console handle */ + if (IsConsoleHandle(hObjectToWaitOn)) + { + if (VerifyConsoleIoHandle(hObjectToWaitOn)) + { + DPRINT1("Console handles are not supported yet!\n"); + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + } + + if (dwMilliseconds == INFINITE) + { + TimePtr = NULL; + } + else + { + Time.QuadPart = -10000 * dwMilliseconds; + TimePtr = &Time; + } + + Status = NtSignalAndWaitForSingleObject (hObjectToSignal, + hObjectToWaitOn, + TimePtr, + (BOOLEAN)bAlertable); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus (Status); + return FALSE; + } + + return TRUE; } /* EOF */