From e718fb324b4e6966d83d33eafb26d343b03ed5dc Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Wed, 1 Jun 2016 16:26:26 +0200 Subject: [PATCH] fix race conditions, tests and some invalid return values Since the current winpr implementation for overlapped operations is incomplete and buggy, all affected functions will now fail if they are called with a set FILE_FLAG_OVERLAPPED flag or a non-null pointer to a OVERLAPPED structure. winpr/nt: - use proper one-time initialization on win32 - fix TestNtCreateFile - fix broken/incomplete _RtlAnsiStringToUnicodeString - unimplemented functions return appropriate error codes winpr/pipe: - improved TestPipeCreateNamedPipe - rewrite the completely broken TestPipeCreateNamedPipeOverlapped test rdtk: - improve test and don't blindly return success winpr/synch: - fix race condition in TestSynchTimerQueue winpr/ssspi: - fix TestEnumerateSecurityPackages printf output - fix TestQuerySecurityPackageInfo printf output winpr/environment: - fix GetEnvironmentStrings printf output winpr/comm: - unimplemented functions return appropriate error codes winpr/io: - unimplemented functions return appropriate error codes winpr/thread: - implement SwitchToThread() via sched_yield() --- rdtk/librdtk/test/TestRdTkNinePatch.c | 48 ++- winpr/libwinpr/comm/comm.c | 84 ++++-- winpr/libwinpr/comm/comm_ioctl.c | 8 +- .../test/TestEnvironmentGetEnvironmentStrings.c | 2 +- winpr/libwinpr/file/file.c | 51 ++-- winpr/libwinpr/file/namedPipeClient.c | 7 + winpr/libwinpr/io/io.c | 67 ++++- winpr/libwinpr/nt/nt.c | 148 ++++++---- winpr/libwinpr/nt/test/TestNtCreateFile.c | 34 ++- winpr/libwinpr/pipe/pipe.c | 56 +++- winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c | 11 + .../pipe/test/TestPipeCreateNamedPipeOverlapped.c | 326 ++++++++++++++------- .../sspi/test/TestEnumerateSecurityPackages.c | 5 +- .../sspi/test/TestQuerySecurityPackageInfo.c | 5 +- winpr/libwinpr/synch/test/TestSynchTimerQueue.c | 10 +- winpr/libwinpr/synch/wait.c | 12 +- winpr/libwinpr/thread/thread.c | 11 +- 17 files changed, 635 insertions(+), 250 deletions(-) diff --git a/rdtk/librdtk/test/TestRdTkNinePatch.c b/rdtk/librdtk/test/TestRdTkNinePatch.c index fb50dee..0550488 100644 --- a/rdtk/librdtk/test/TestRdTkNinePatch.c +++ b/rdtk/librdtk/test/TestRdTkNinePatch.c @@ -3,11 +3,53 @@ int TestRdTkNinePatch(int argc, char* argv[]) { - rdtkEngine* engine; + rdtkEngine* engine = NULL; + rdtkSurface* surface = NULL; + DWORD scanline; + DWORD width; + DWORD height; + BYTE* data = NULL; + int ret = -1; - engine = rdtk_engine_new(); + if (!(engine = rdtk_engine_new())) + { + printf("%s: error creating rdtk engine (%u)\n", __FUNCTION__, GetLastError()); + goto out; + } + width = 1024; + height = 768; + scanline = width * 4; + + /* let rdtk allocate the surface buffer */ + if (!(surface = rdtk_surface_new(engine, NULL, width, height, scanline))) + { + printf("%s: error creating auto-allocated surface (%u)\n", __FUNCTION__, GetLastError()); + goto out; + } + rdtk_surface_free(surface); + surface = NULL; + + + /* test self-allocated buffer */ + if (!(data = calloc(height, scanline))) + { + printf("%s: error allocating surface buffer (%u)\n", __FUNCTION__, GetLastError()); + goto out; + } + + if (!(surface = rdtk_surface_new(engine, data, width, height, scanline))) + { + printf("%s: error creating self-allocated surface (%u)\n", __FUNCTION__, GetLastError()); + goto out; + } + + ret = 0; + +out: + rdtk_surface_free(surface); rdtk_engine_free(engine); + free(data); - return 0; + return ret; } diff --git a/winpr/libwinpr/comm/comm.c b/winpr/libwinpr/comm/comm.c index dd1e386..b107b31 100644 --- a/winpr/libwinpr/comm/comm.c +++ b/winpr/libwinpr/comm/comm.c @@ -149,7 +149,9 @@ BOOL BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB) /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB) @@ -159,7 +161,9 @@ BOOL BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB) /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts) @@ -169,7 +173,9 @@ BOOL BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTi /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL BuildCommDCBAndTimeoutsW(LPCWSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts) @@ -179,7 +185,9 @@ BOOL BuildCommDCBAndTimeoutsW(LPCWSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommT /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL CommConfigDialogA(LPCSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC) @@ -189,7 +197,9 @@ BOOL CommConfigDialogA(LPCSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC) /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL CommConfigDialogW(LPCWSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC) @@ -199,7 +209,9 @@ BOOL CommConfigDialogW(LPCWSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC) /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL GetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, LPDWORD lpdwSize) @@ -214,7 +226,9 @@ BOOL GetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, LPDWORD lpdwSize) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL SetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, DWORD dwSize) @@ -229,7 +243,9 @@ BOOL SetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, DWORD dwSize) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL GetCommMask(HANDLE hFile, PDWORD lpEvtMask) @@ -244,7 +260,9 @@ BOOL GetCommMask(HANDLE hFile, PDWORD lpEvtMask) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL SetCommMask(HANDLE hFile, DWORD dwEvtMask) @@ -259,7 +277,9 @@ BOOL SetCommMask(HANDLE hFile, DWORD dwEvtMask) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL GetCommModemStatus(HANDLE hFile, PDWORD lpModemStat) @@ -274,7 +294,9 @@ BOOL GetCommModemStatus(HANDLE hFile, PDWORD lpModemStat) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /** @@ -781,7 +803,9 @@ BOOL GetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize) /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL GetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize) @@ -791,7 +815,9 @@ BOOL GetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL SetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize) @@ -801,7 +827,9 @@ BOOL SetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize) /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL SetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize) @@ -811,7 +839,9 @@ BOOL SetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize) /* TODO: not implemented */ - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL SetCommBreak(HANDLE hFile) @@ -826,7 +856,9 @@ BOOL SetCommBreak(HANDLE hFile) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL ClearCommBreak(HANDLE hFile) @@ -841,7 +873,9 @@ BOOL ClearCommBreak(HANDLE hFile) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL ClearCommError(HANDLE hFile, PDWORD lpErrors, LPCOMSTAT lpStat) @@ -856,7 +890,9 @@ BOOL ClearCommError(HANDLE hFile, PDWORD lpErrors, LPCOMSTAT lpStat) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } @@ -923,7 +959,9 @@ BOOL EscapeCommFunction(HANDLE hFile, DWORD dwFunc) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL TransmitCommChar(HANDLE hFile, char cChar) @@ -938,7 +976,9 @@ BOOL TransmitCommChar(HANDLE hFile, char cChar) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL WaitCommEvent(HANDLE hFile, PDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) @@ -953,7 +993,9 @@ BOOL WaitCommEvent(HANDLE hFile, PDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) if (!pComm) return FALSE; - return TRUE; + CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } diff --git a/winpr/libwinpr/comm/comm_ioctl.c b/winpr/libwinpr/comm/comm_ioctl.c index 2438044..ed680a9 100644 --- a/winpr/libwinpr/comm/comm_ioctl.c +++ b/winpr/libwinpr/comm/comm_ioctl.c @@ -78,9 +78,6 @@ static BOOL _CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID l WINPR_COMM* pComm = (WINPR_COMM*) hDevice; SERIAL_DRIVER* pServerSerialDriver = NULL; - /* clear any previous last error */ - SetLastError(ERROR_SUCCESS); - if (hDevice == INVALID_HANDLE_VALUE) { SetLastError(ERROR_INVALID_HANDLE); @@ -93,7 +90,7 @@ static BOOL _CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID l return FALSE; } - if (lpOverlapped != NULL) + if (lpOverlapped) { SetLastError(ERROR_NOT_SUPPORTED); return FALSE; @@ -105,6 +102,9 @@ static BOOL _CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID l return FALSE; } + /* clear any previous last error */ + SetLastError(ERROR_SUCCESS); + *lpBytesReturned = 0; /* will be ajusted if required ... */ CommLog_Print(WLOG_DEBUG, "CommDeviceIoControl: IoControlCode: 0x%0.8x", dwIoControlCode); diff --git a/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c b/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c index 1ef5534..238e5a2 100644 --- a/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c +++ b/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c @@ -16,7 +16,7 @@ int TestEnvironmentGetEnvironmentStrings(int argc, char* argv[]) while (p[0] && p[1]) { - printf("%s\n", p); + _tprintf(_T("%s\n"), p); length = _tcslen(p); p += (length + 1); } diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index d18a778..7641367 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -150,15 +150,16 @@ static BOOL FileRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, WINPR_FILE* file; BOOL status = TRUE; - if (!Object) - return FALSE; - if (lpOverlapped) { - WLog_ERR(TAG, "Overlapping write not supported."); + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); return FALSE; } + if (!Object) + return FALSE; + file = (WINPR_FILE *)Object; io_status = fread(lpBuffer, nNumberOfBytesToRead, 1, file->fp); @@ -186,15 +187,16 @@ static BOOL FileWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrit size_t io_status; WINPR_FILE* file; - if (!Object) - return FALSE; - if (lpOverlapped) { - WLog_ERR(TAG, "Overlapping write not supported."); + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); return FALSE; } + if (!Object) + return FALSE; + file = (WINPR_FILE *)Object; io_status = fwrite(lpBuffer, nNumberOfBytesToWrite, 1, file->fp); @@ -260,6 +262,13 @@ static BOOL FileLockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved, int lock; WINPR_FILE* pFile = (WINPR_FILE*)hFile; + if (lpOverlapped) + { + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + if (!hFile) return FALSE; @@ -269,12 +278,6 @@ static BOOL FileLockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved, return FALSE; } - if (lpOverlapped) - { - WLog_ERR(TAG, "lpOverlapped not implemented!"); - return FALSE; - } - if (dwFlags & LOCKFILE_EXCLUSIVE_LOCK) lock = LOCK_EX; else @@ -324,6 +327,13 @@ static BOOL FileUnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfByte { WINPR_FILE* pFile = (WINPR_FILE*)hFile; + if (lpOverlapped) + { + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + if (!hFile) return FALSE; @@ -333,12 +343,6 @@ static BOOL FileUnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfByte return FALSE; } - if (lpOverlapped) - { - WLog_ERR(TAG, "lpOverlapped not implemented!"); - return FALSE; - } - if (flock(fileno(pFile->fp), LOCK_UN) < 0) { WLog_ERR(TAG, "flock(LOCK_UN) %s failed with %s [%08X]", @@ -554,6 +558,13 @@ static HANDLE FileCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dw int lock = 0; FILE* fp = NULL; + if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) + { + WLog_ERR(TAG, "WinPR %s does not support the FILE_FLAG_OVERLAPPED flag", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return INVALID_HANDLE_VALUE; + } + pFile = (WINPR_FILE*) calloc(1, sizeof(WINPR_FILE)); if (!pFile) { diff --git a/winpr/libwinpr/file/namedPipeClient.c b/winpr/libwinpr/file/namedPipeClient.c index a318c94..9c82788 100644 --- a/winpr/libwinpr/file/namedPipeClient.c +++ b/winpr/libwinpr/file/namedPipeClient.c @@ -137,6 +137,13 @@ static HANDLE NamedPipeClientCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAcces struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe; + if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) + { + WLog_ERR(TAG, "WinPR %s does not support the FILE_FLAG_OVERLAPPED flag", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return INVALID_HANDLE_VALUE; + } + if (!lpFileName) return INVALID_HANDLE_VALUE; diff --git a/winpr/libwinpr/io/io.c b/winpr/libwinpr/io/io.c index 7b114ac..2aa5881 100644 --- a/winpr/libwinpr/io/io.c +++ b/winpr/libwinpr/io/io.c @@ -42,13 +42,21 @@ #include #include +#include #include "../handle/handle.h" - #include "../pipe/pipe.h" +#include "../log.h" + +#define TAG WINPR_TAG("io") BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait) { +#if 1 + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +#else ULONG Type; WINPR_HANDLE* Object; @@ -118,54 +126,73 @@ BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumb } return TRUE; +#endif } BOOL GetOverlappedResultEx(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, DWORD dwMilliseconds, BOOL bAlertable) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } HANDLE CreateIoCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads) { + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return NULL; } BOOL GetQueuedCompletionStatus(HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred, PULONG_PTR lpCompletionKey, LPOVERLAPPED* lpOverlapped, DWORD dwMilliseconds) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL GetQueuedCompletionStatusEx(HANDLE CompletionPort, LPOVERLAPPED_ENTRY lpCompletionPortEntries, ULONG ulCount, PULONG ulNumEntriesRemoved, DWORD dwMilliseconds, BOOL fAlertable) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL PostQueuedCompletionStatus(HANDLE CompletionPort, DWORD dwNumberOfBytesTransferred, ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL CancelIo(HANDLE hFile) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL CancelIoEx(HANDLE hFile, LPOVERLAPPED lpOverlapped) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL CancelSynchronousIo(HANDLE hThread) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } #endif @@ -180,29 +207,39 @@ BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumb BOOL DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } HANDLE CreateIoCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads) { + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return NULL; } BOOL GetQueuedCompletionStatus(HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred, PULONG_PTR lpCompletionKey, LPOVERLAPPED* lpOverlapped, DWORD dwMilliseconds) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL GetQueuedCompletionStatusEx(HANDLE CompletionPort, LPOVERLAPPED_ENTRY lpCompletionPortEntries, ULONG ulCount, PULONG ulNumEntriesRemoved, DWORD dwMilliseconds, BOOL fAlertable) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL PostQueuedCompletionStatus(HANDLE CompletionPort, DWORD dwNumberOfBytesTransferred, ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL CancelIo(HANDLE hFile) @@ -212,7 +249,9 @@ BOOL CancelIo(HANDLE hFile) BOOL CancelSynchronousIo(HANDLE hThread) { - return TRUE; + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } #endif diff --git a/winpr/libwinpr/nt/nt.c b/winpr/libwinpr/nt/nt.c index 653b752..6d9dde9 100644 --- a/winpr/libwinpr/nt/nt.c +++ b/winpr/libwinpr/nt/nt.c @@ -25,9 +25,13 @@ #include #include - +#include #include +#include "../log.h" +#define TAG WINPR_TAG("nt") + + /** * NtXxx Routines: * http://msdn.microsoft.com/en-us/library/windows/hardware/ff557720/ @@ -160,31 +164,35 @@ NTSTATUS _RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, int index; if (!SourceString) - { - _RtlInitUnicodeString(DestinationString, NULL); - return 0; - } + return STATUS_INVALID_PARAMETER; if (AllocateDestinationString) { - DestinationString->Length = SourceString->Length * 2; - DestinationString->MaximumLength = SourceString->MaximumLength * 2; - - DestinationString->Buffer = (PWSTR) malloc(DestinationString->MaximumLength); - if (!DestinationString->Buffer) - return STATUS_NO_MEMORY; + PWSTR wbuf = NULL; - for (index = 0; index < SourceString->MaximumLength; index++) + if (SourceString->MaximumLength) { - DestinationString->Buffer[index] = (WCHAR) SourceString->Buffer[index]; + if (!(wbuf = (PWSTR) malloc(SourceString->MaximumLength * 2))) + return STATUS_NO_MEMORY; } + + DestinationString->MaximumLength = SourceString->MaximumLength * 2; + DestinationString->Buffer = wbuf; } else { + if (DestinationString->MaximumLength < SourceString->MaximumLength * 2) + return STATUS_BUFFER_OVERFLOW; + } + for (index = 0; index < SourceString->MaximumLength; index++) + { + DestinationString->Buffer[index] = (WCHAR) SourceString->Buffer[index]; } - return 0; + DestinationString->Length = SourceString->Length * 2; + + return STATUS_SUCCESS; } /** @@ -223,6 +231,10 @@ NTSTATUS _NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength) { +#if 1 + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + return STATUS_NOT_SUPPORTED; +#else WINPR_NT_FILE* pFileHandle; pFileHandle = (WINPR_NT_FILE*) calloc(1, sizeof(WINPR_NT_FILE)); @@ -243,6 +255,7 @@ NTSTATUS _NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, //STATUS_OBJECT_NAME_NOT_FOUND return STATUS_SUCCESS; +#endif } /** @@ -254,6 +267,10 @@ NTSTATUS _NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions) { +#if 1 + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + return STATUS_NOT_SUPPORTED; +#else WINPR_NT_FILE* pFileHandle; pFileHandle = (WINPR_NT_FILE*) calloc(1, sizeof(WINPR_NT_FILE)); @@ -267,6 +284,7 @@ NTSTATUS _NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, *((PULONG_PTR) FileHandle) = (ULONG_PTR) pFileHandle; return STATUS_SUCCESS; +#endif } /** @@ -277,7 +295,12 @@ NTSTATUS _NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, NTSTATUS _NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key) { +#if 1 + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + return STATUS_NOT_SUPPORTED; +#else return STATUS_SUCCESS; +#endif } /** @@ -288,7 +311,12 @@ NTSTATUS _NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine NTSTATUS _NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key) { +#if 1 + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + return STATUS_NOT_SUPPORTED; +#else return STATUS_SUCCESS; +#endif } /** @@ -301,7 +329,12 @@ NTSTATUS _NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength) { - return 0; +#if 1 + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + return STATUS_NOT_SUPPORTED; +#else + return STATUS_SUCCESS; +#endif } /** @@ -311,16 +344,21 @@ NTSTATUS _NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, NTSTATUS _NtClose(HANDLE Handle) { +#if 1 + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + return STATUS_NOT_SUPPORTED; +#else WINPR_NT_FILE* pFileHandle; if (!Handle) - return 0; + return STATUS_SUCCESS; pFileHandle = (WINPR_NT_FILE*) Handle; free(pFileHandle); return STATUS_SUCCESS; +#endif } /** @@ -330,14 +368,17 @@ NTSTATUS _NtClose(HANDLE Handle) NTSTATUS _NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout) { - return 0; +#if 1 + WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + return STATUS_NOT_SUPPORTED; +#else + return STATUS_SUCCESS; +#endif } #else -static HMODULE NtdllModule = NULL; -static BOOL moduleAvailable = FALSE; -static BOOL moduleInitialized = FALSE; +#include typedef VOID (WINAPI * RTL_INIT_ANSI_STRING_FN)(PANSI_STRING DestinationString, PCSZ SourceString); @@ -387,36 +428,33 @@ static NT_DEVICE_IO_CONTROL_FILE_FN pNtDeviceIoControlFile = NULL; static NT_CLOSE_FN pNtClose = NULL; static NT_WAIT_FOR_SINGLE_OBJECT_FN pNtWaitForSingleObject = NULL; -static void NtdllModuleInit() -{ - if (moduleInitialized) - return; - - NtdllModule = LoadLibraryA("ntdll.dll"); - moduleInitialized = TRUE; +static INIT_ONCE ntdllInitOnce = INIT_ONCE_STATIC_INIT; - if (!NtdllModule) - return; +static BOOL CALLBACK NtdllModuleInit(PINIT_ONCE once, PVOID param, PVOID *context) +{ + HMODULE NtdllModule = LoadLibraryA("ntdll.dll"); - moduleAvailable = TRUE; - - pRtlInitAnsiString = (RTL_INIT_ANSI_STRING_FN) GetProcAddress(NtdllModule, "RtlInitAnsiString"); - pRtlInitUnicodeString = (RTL_INIT_UNICODE_STRING_FN) GetProcAddress(NtdllModule, "RtlInitUnicodeString"); - pRtlAnsiStringToUnicodeString = (RTL_ANSI_STRING_TO_UNICODE_STRING_FN) GetProcAddress(NtdllModule, "RtlAnsiStringToUnicodeString"); - pRtlFreeUnicodeString = (RTL_FREE_UNICODE_STRING_FN) GetProcAddress(NtdllModule, "RtlFreeUnicodeString"); - pRtlNtStatusToDosError = (RTL_NT_STATUS_TO_DOS_ERROR_FN) GetProcAddress(NtdllModule, "RtlNtStatusToDosError"); - pNtCreateFile = (NT_CREATE_FILE_FN) GetProcAddress(NtdllModule, "NtCreateFile"); - pNtOpenFile = (NT_OPEN_FILE_FN) GetProcAddress(NtdllModule, "NtOpenFile"); - pNtReadFile = (NT_READ_FILE_FN) GetProcAddress(NtdllModule, "NtReadFile"); - pNtWriteFile = (NT_WRITE_FILE_FN) GetProcAddress(NtdllModule, "NtWriteFile"); - pNtDeviceIoControlFile = (NT_DEVICE_IO_CONTROL_FILE_FN) GetProcAddress(NtdllModule, "NtDeviceIoControlFile"); - pNtClose = (NT_CLOSE_FN) GetProcAddress(NtdllModule, "NtClose"); - pNtWaitForSingleObject = (NT_WAIT_FOR_SINGLE_OBJECT_FN) GetProcAddress(NtdllModule, "NtWaitForSingleObject"); + if (NtdllModule) + { + pRtlInitAnsiString = (RTL_INIT_ANSI_STRING_FN)GetProcAddress(NtdllModule, "RtlInitAnsiString"); + pRtlInitUnicodeString = (RTL_INIT_UNICODE_STRING_FN)GetProcAddress(NtdllModule, "RtlInitUnicodeString"); + pRtlAnsiStringToUnicodeString = (RTL_ANSI_STRING_TO_UNICODE_STRING_FN)GetProcAddress(NtdllModule, "RtlAnsiStringToUnicodeString"); + pRtlFreeUnicodeString = (RTL_FREE_UNICODE_STRING_FN)GetProcAddress(NtdllModule, "RtlFreeUnicodeString"); + pRtlNtStatusToDosError = (RTL_NT_STATUS_TO_DOS_ERROR_FN)GetProcAddress(NtdllModule, "RtlNtStatusToDosError"); + pNtCreateFile = (NT_CREATE_FILE_FN)GetProcAddress(NtdllModule, "NtCreateFile"); + pNtOpenFile = (NT_OPEN_FILE_FN)GetProcAddress(NtdllModule, "NtOpenFile"); + pNtReadFile = (NT_READ_FILE_FN)GetProcAddress(NtdllModule, "NtReadFile"); + pNtWriteFile = (NT_WRITE_FILE_FN)GetProcAddress(NtdllModule, "NtWriteFile"); + pNtDeviceIoControlFile = (NT_DEVICE_IO_CONTROL_FILE_FN)GetProcAddress(NtdllModule, "NtDeviceIoControlFile"); + pNtClose = (NT_CLOSE_FN)GetProcAddress(NtdllModule, "NtClose"); + pNtWaitForSingleObject = (NT_WAIT_FOR_SINGLE_OBJECT_FN)GetProcAddress(NtdllModule, "NtWaitForSingleObject"); + } + return TRUE; } VOID _RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pRtlInitAnsiString) return; @@ -426,7 +464,7 @@ VOID _RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString) VOID _RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pRtlInitUnicodeString) return; @@ -437,7 +475,7 @@ VOID _RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceStrin NTSTATUS _RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PCANSI_STRING SourceString, BOOLEAN AllocateDestinationString) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pRtlAnsiStringToUnicodeString) return STATUS_INTERNAL_ERROR; @@ -448,7 +486,7 @@ NTSTATUS _RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, VOID _RtlFreeUnicodeString(PUNICODE_STRING UnicodeString) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pRtlFreeUnicodeString) return; @@ -458,7 +496,7 @@ VOID _RtlFreeUnicodeString(PUNICODE_STRING UnicodeString) ULONG _RtlNtStatusToDosError(NTSTATUS status) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pRtlNtStatusToDosError) return status; @@ -471,7 +509,7 @@ NTSTATUS _NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pNtCreateFile) return STATUS_INTERNAL_ERROR; @@ -485,7 +523,7 @@ NTSTATUS _NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pNtOpenFile) return STATUS_INTERNAL_ERROR; @@ -497,7 +535,7 @@ NTSTATUS _NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, NTSTATUS _NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pNtReadFile) return STATUS_INTERNAL_ERROR; @@ -509,7 +547,7 @@ NTSTATUS _NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine NTSTATUS _NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pNtWriteFile) return STATUS_INTERNAL_ERROR; @@ -523,7 +561,7 @@ NTSTATUS _NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pNtDeviceIoControlFile) return STATUS_INTERNAL_ERROR; @@ -535,7 +573,7 @@ NTSTATUS _NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, NTSTATUS _NtClose(HANDLE Handle) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pNtClose) return STATUS_INTERNAL_ERROR; @@ -545,7 +583,7 @@ NTSTATUS _NtClose(HANDLE Handle) NTSTATUS _NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout) { - NtdllModuleInit(); + InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL); if (!pNtWaitForSingleObject) return STATUS_INTERNAL_ERROR; diff --git a/winpr/libwinpr/nt/test/TestNtCreateFile.c b/winpr/libwinpr/nt/test/TestNtCreateFile.c index d91bf22..2097177 100644 --- a/winpr/libwinpr/nt/test/TestNtCreateFile.c +++ b/winpr/libwinpr/nt/test/TestNtCreateFile.c @@ -3,6 +3,12 @@ #include +#ifdef _WIN32 +#define TESTFILE "\\??\\C:\\Documents and Settings\\All Users\\winpr_test_nt_create_file.txt" +#else +#define TESTFILE "/tmp/winpr_test_nt_create_file.txt" +#endif + int TestNtCreateFile(int argc, char* argv[]) { HANDLE handle; @@ -15,8 +21,22 @@ int TestNtCreateFile(int argc, char* argv[]) OBJECT_ATTRIBUTES attributes; IO_STATUS_BLOCK ioStatusBlock; - _RtlInitAnsiString(&aString, "\\??\\C:\\Users\\Public\\foo.txt"); - _RtlAnsiStringToUnicodeString(&uString, &aString, TRUE); + int eFailure = -1; + int eSuccess = 0; + +#ifndef _WIN32 + printf("Note: %s result may currently only be trusted on Win32\n", __FUNCTION__); + eFailure = eSuccess; +#endif + + _RtlInitAnsiString(&aString, TESTFILE); + + ntstatus = _RtlAnsiStringToUnicodeString(&uString, &aString, TRUE); + if (ntstatus != STATUS_SUCCESS) + { + printf("_RtlAnsiStringToUnicodeString failure: 0x%08X\n", ntstatus); + return eFailure; + } handle = NULL; ZeroMemory(&ioStatusBlock, sizeof(IO_STATUS_BLOCK)); @@ -32,8 +52,8 @@ int TestNtCreateFile(int argc, char* argv[]) if (ntstatus != STATUS_SUCCESS) { - printf("NtCreateFile failure: 0x%04X\n", ntstatus); - return -1; + printf("_NtCreateFile failure: 0x%08X\n", ntstatus); + return eFailure; } _RtlFreeUnicodeString(&uString); @@ -42,9 +62,9 @@ int TestNtCreateFile(int argc, char* argv[]) if (ntstatus != STATUS_SUCCESS) { - printf("NtClose failure: 0x%04X\n", ntstatus); - return -1; + printf("_NtClose failure: 0x%08X\n", ntstatus); + return eFailure; } - return 0; + return eSuccess; } diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 0d8a6b6..399c2d4 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -125,6 +125,13 @@ static BOOL PipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, WINPR_PIPE* pipe; BOOL status = TRUE; + if (lpOverlapped) + { + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + pipe = (WINPR_PIPE *)Object; do { @@ -156,6 +163,13 @@ static BOOL PipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrit int io_status; WINPR_PIPE* pipe; + if (lpOverlapped) + { + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + pipe = (WINPR_PIPE *)Object; do @@ -253,6 +267,13 @@ BOOL NamedPipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, WINPR_NAMED_PIPE* pipe; BOOL status = TRUE; + if (lpOverlapped) + { + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + pipe = (WINPR_NAMED_PIPE *)Object; if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) @@ -340,6 +361,13 @@ BOOL NamedPipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, WINPR_NAMED_PIPE* pipe; BOOL status = TRUE; + if (lpOverlapped) + { + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + pipe = (WINPR_NAMED_PIPE*) Object; if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) @@ -537,6 +565,13 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD int serverfd = -1; NamedPipeServerSocketEntry* baseSocket = NULL; + if (dwOpenMode & FILE_FLAG_OVERLAPPED) + { + WLog_ERR(TAG, "WinPR %s does not support the FILE_FLAG_OVERLAPPED flag", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return INVALID_HANDLE_VALUE; + } + if (!lpName) return INVALID_HANDLE_VALUE; @@ -688,6 +723,8 @@ out: HANDLE CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { + WLog_ERR(TAG, "%s is not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return NULL; } @@ -698,6 +735,13 @@ BOOL ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped) struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe; + if (lpOverlapped) + { + WLog_ERR(TAG, "WinPR %s does not support the lpOverlapped parameter", __FUNCTION__); + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + if (!hNamedPipe) return FALSE; @@ -755,14 +799,16 @@ BOOL PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage) { WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); - return TRUE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL TransactNamedPipe(HANDLE hNamedPipe, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped) { WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); - return TRUE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL WaitNamedPipeA(LPCSTR lpNamedPipeName, DWORD nTimeOut) @@ -805,7 +851,8 @@ BOOL WaitNamedPipeA(LPCSTR lpNamedPipeName, DWORD nTimeOut) BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut) { WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); - return TRUE; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout) @@ -850,18 +897,21 @@ BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCol BOOL ImpersonateNamedPipeClient(HANDLE hNamedPipe) { WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } BOOL GetNamedPipeClientComputerNameA(HANDLE Pipe, LPCSTR ClientComputerName, ULONG ClientComputerNameLength) { WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } BOOL GetNamedPipeClientComputerNameW(HANDLE Pipe, LPCWSTR ClientComputerName, ULONG ClientComputerNameLength) { WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } diff --git a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c index 21b4fb3..4595784 100644 --- a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c +++ b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c @@ -446,6 +446,17 @@ int TestPipeCreateNamedPipe(int argc, char* argv[]) HANDLE SingleThread; HANDLE ClientThread; HANDLE ServerThread; + HANDLE hPipe; + + /* Verify that CreateNamedPipe returns INVALID_HANDLE_VALUE on failure */ + hPipe = CreateNamedPipeA(NULL, 0, 0, 0, 0, 0, 0, NULL); + if (hPipe != INVALID_HANDLE_VALUE) + { + printf("CreateNamedPipe unexpectedly returned %p instead of INVALID_HANDLE_VALUE (%p)\n", + hPipe, INVALID_HANDLE_VALUE); + return -1; + } + #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); #endif diff --git a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c index ecb8bdf..2ce09b2 100644 --- a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c +++ b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c @@ -11,8 +11,15 @@ #include #define PIPE_BUFFER_SIZE 32 +#define PIPE_TIMEOUT_MS 20000 // 20 seconds -static HANDLE ReadyEvent; +BYTE SERVER_MESSAGE[PIPE_BUFFER_SIZE]; +BYTE CLIENT_MESSAGE[PIPE_BUFFER_SIZE]; + +BOOL bClientSuccess = FALSE; +BOOL bServerSuccess = FALSE; + +static HANDLE serverReadyEvent; static LPTSTR lpszPipeName = _T("\\\\.\\pipe\\winpr_test_pipe_overlapped"); @@ -22,65 +29,86 @@ static void* named_pipe_client_thread(void* arg) HANDLE hEvent = NULL; HANDLE hNamedPipe = NULL; BYTE* lpReadBuffer = NULL; - BYTE* lpWriteBuffer = NULL; BOOL fSuccess = FALSE; OVERLAPPED overlapped; DWORD nNumberOfBytesToRead; DWORD nNumberOfBytesToWrite; DWORD NumberOfBytesTransferred; - WaitForSingleObject(ReadyEvent, INFINITE); - hNamedPipe = CreateFile(lpszPipeName, GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + status = WaitForSingleObject(serverReadyEvent, PIPE_TIMEOUT_MS); + if (status != WAIT_OBJECT_0) + { + printf("client: failed to wait for server ready event: %u\n", status); + goto finish; + } + - if (!hNamedPipe) + /* 1: initialize overlapped structure */ + + ZeroMemory(&overlapped, sizeof(OVERLAPPED)); + if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { - printf("Named Pipe CreateFile failure: NULL handle\n"); + printf("client: CreateEvent failure: %u\n", GetLastError()); goto finish; } + overlapped.hEvent = hEvent; + + + /* 2: connect to server named pipe */ + + hNamedPipe = CreateFile(lpszPipeName, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (hNamedPipe == INVALID_HANDLE_VALUE) { - printf("Named Pipe CreateFile failure: INVALID_HANDLE_VALUE\n"); + printf("client: Named Pipe CreateFile failure: %u\n", GetLastError()); goto finish; } - lpReadBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE); - lpWriteBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE); - if (!lpReadBuffer || !lpWriteBuffer) + + /* 3: write to named pipe */ + + nNumberOfBytesToWrite = PIPE_BUFFER_SIZE; + NumberOfBytesTransferred = 0; + + fSuccess = WriteFile(hNamedPipe, CLIENT_MESSAGE, nNumberOfBytesToWrite, NULL, &overlapped); + + if (!fSuccess) + fSuccess = (GetLastError() == ERROR_IO_PENDING); + + if (!fSuccess) { - printf("Error allocating memory\n"); + printf("client: NamedPipe WriteFile failure (initial): %u\n", GetLastError()); goto finish; } - ZeroMemory(&overlapped, sizeof(OVERLAPPED)); - if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + status = WaitForSingleObject(hEvent, PIPE_TIMEOUT_MS); + if (status != WAIT_OBJECT_0) { - printf("CreateEvent failure: (%d)\n", GetLastError()); + printf("client: failed to wait for overlapped event (write): %u\n", status); goto finish; } - overlapped.hEvent = hEvent; - nNumberOfBytesToWrite = PIPE_BUFFER_SIZE; - FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x59); - fSuccess = WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, NULL, &overlapped); - + fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, FALSE); if (!fSuccess) - fSuccess = (GetLastError() == ERROR_IO_PENDING); + { + printf("client: NamedPipe WriteFile failure (final): %u\n", GetLastError()); + goto finish; + } + printf("client: WriteFile transferred %u bytes:\n", NumberOfBytesTransferred); - if (!fSuccess) + + /* 4: read from named pipe */ + + if (!(lpReadBuffer = (BYTE*)calloc(1, PIPE_BUFFER_SIZE))) { - printf("Client NamedPipe WriteFile failure: %d\n", GetLastError()); + printf("client: Error allocating read buffer\n"); goto finish; } - status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE); - NumberOfBytesTransferred = 0; - fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE); - printf("Client GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", - fSuccess, NumberOfBytesTransferred); nNumberOfBytesToRead = PIPE_BUFFER_SIZE; - ZeroMemory(lpReadBuffer, PIPE_BUFFER_SIZE); + NumberOfBytesTransferred = 0; + fSuccess = ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, NULL, &overlapped); if (!fSuccess) @@ -88,21 +116,38 @@ static void* named_pipe_client_thread(void* arg) if (!fSuccess) { - printf("Client NamedPipe ReadFile failure: %d\n", GetLastError()); + printf("client: NamedPipe ReadFile failure (initial): %u\n", GetLastError()); + goto finish; + } + + status = WaitForMultipleObjects(1, &hEvent, FALSE, PIPE_TIMEOUT_MS); + if (status != WAIT_OBJECT_0) + { + printf("client: failed to wait for overlapped event (read): %u\n", status); goto finish; } - status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE); - NumberOfBytesTransferred = 0; fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE); - printf("Client GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", - fSuccess, NumberOfBytesTransferred); - printf("Client ReadFile (%d):\n", NumberOfBytesTransferred); + if (!fSuccess) + { + printf("client: NamedPipe ReadFile failure (final): %u\n", GetLastError()); + goto finish; + } + + printf("client: ReadFile transferred %u bytes:\n", NumberOfBytesTransferred); winpr_HexDump("pipe.test", WLOG_DEBUG, lpReadBuffer, NumberOfBytesTransferred); + if (NumberOfBytesTransferred != PIPE_BUFFER_SIZE || memcmp(lpReadBuffer, SERVER_MESSAGE, PIPE_BUFFER_SIZE)) + { + printf("client: received unexpected data from server\n"); + goto finish; + } + + printf("client: finished successfully\n"); + bClientSuccess = TRUE; + finish: free(lpReadBuffer); - free(lpWriteBuffer); if (hNamedPipe) CloseHandle(hNamedPipe); if (hEvent) @@ -114,71 +159,103 @@ finish: static void* named_pipe_server_thread(void* arg) { DWORD status; - HANDLE hEvent; - HANDLE hNamedPipe; - BYTE* lpReadBuffer; - BYTE* lpWriteBuffer; + HANDLE hEvent = NULL; + HANDLE hNamedPipe = NULL; + BYTE* lpReadBuffer = NULL; OVERLAPPED overlapped; BOOL fSuccess = FALSE; BOOL fConnected = FALSE; DWORD nNumberOfBytesToRead; DWORD nNumberOfBytesToWrite; DWORD NumberOfBytesTransferred; - hNamedPipe = CreateNamedPipe(lpszPipeName, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL); - if (!hNamedPipe) + /* 1: initialize overlapped structure */ + + ZeroMemory(&overlapped, sizeof(OVERLAPPED)); + if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { - printf("CreateNamedPipe failure: NULL handle\n"); - return NULL; + printf("server: CreateEvent failure: %u\n", GetLastError()); + SetEvent(serverReadyEvent); /* unblock client thread */ + goto finish; } + overlapped.hEvent = hEvent; + + + /* 2: create named pipe and set ready event */ + + hNamedPipe = CreateNamedPipe(lpszPipeName, + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL); if (hNamedPipe == INVALID_HANDLE_VALUE) { - printf("CreateNamedPipe failure: INVALID_HANDLE_VALUE (%d)\n", GetLastError()); - return NULL; + printf("server: CreateNamedPipe failure: %u\n", GetLastError()); + SetEvent(serverReadyEvent); /* unblock client thread */ + goto finish; } - SetEvent(ReadyEvent); - ZeroMemory(&overlapped, sizeof(OVERLAPPED)); + SetEvent(serverReadyEvent); - if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) - { - printf("CreateEvent failure: (%d)\n", GetLastError()); - return NULL; - } + /* 3: connect named pipe */ + +#if 0 + /* This sleep will most certainly cause ERROR_PIPE_CONNECTED below */ + Sleep(2000); +#endif - overlapped.hEvent = hEvent; fConnected = ConnectNamedPipe(hNamedPipe, &overlapped); - printf("ConnectNamedPipe status: %d\n", GetLastError()); + status = GetLastError(); + + /** + * At this point if fConnected is FALSE, we have to check GetLastError() for: + * ERROR_PIPE_CONNECTED: + * client has already connected before we have called ConnectNamedPipe. + * this is quite common depending on the timings and indicates success + * ERROR_IO_PENDING: + * Since we're using ConnectNamedPipe asynchronously here, the function returns + * immediately and this error code simply indicates that the operation is + * still in progress. Hence we have to wait for the completion event and use + * GetOverlappedResult to query the actual result of the operation (note that + * the lpNumberOfBytesTransferred parameter is undefined/useless for a + * ConnectNamedPipe operation) + */ if (!fConnected) - fConnected = (GetLastError() == ERROR_IO_PENDING); + fConnected = (status == ERROR_PIPE_CONNECTED); - status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE); - NumberOfBytesTransferred = 0; - fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE); - printf("Server GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", fSuccess, NumberOfBytesTransferred); + printf("server: ConnectNamedPipe status: %u\n", status); + + if (!fConnected && status == ERROR_IO_PENDING) + { + DWORD dwDummy; + printf("server: waiting up to %u ms for connection ...\n", PIPE_TIMEOUT_MS); + status = WaitForSingleObject(hEvent, PIPE_TIMEOUT_MS); + if (status == WAIT_OBJECT_0) + fConnected = GetOverlappedResult(hNamedPipe, &overlapped, &dwDummy, FALSE); + else + printf("server: failed to wait for overlapped event (connect): %u\n", status); + } if (!fConnected) { - printf("ConnectNamedPipe failure: %d\n", GetLastError()); - CloseHandle(hNamedPipe); - CloseHandle(hEvent); - return NULL; + printf("server: ConnectNamedPipe failed: %u\n", status); + goto finish; } - lpReadBuffer = (BYTE*) calloc(1, PIPE_BUFFER_SIZE); - lpWriteBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE); - if (!lpReadBuffer || !lpWriteBuffer) + printf("server: named pipe successfully connected\n"); + + + /* 4: read from named pipe */ + + if (!(lpReadBuffer = (BYTE*)calloc(1, PIPE_BUFFER_SIZE))) { - printf("Error allocating memory\n"); - free(lpReadBuffer); - free(lpWriteBuffer); - return NULL; + printf("server: Error allocating read buffer\n"); + goto finish; } + nNumberOfBytesToRead = PIPE_BUFFER_SIZE; + NumberOfBytesTransferred = 0; + fSuccess = ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, NULL, &overlapped); if (!fSuccess) @@ -186,45 +263,74 @@ static void* named_pipe_server_thread(void* arg) if (!fSuccess) { - printf("Server NamedPipe ReadFile failure: %d\n", GetLastError()); - free(lpReadBuffer); - free(lpWriteBuffer); - CloseHandle(hNamedPipe); - CloseHandle(hEvent); - return NULL; + printf("server: NamedPipe ReadFile failure (initial): %u\n", GetLastError()); + goto finish; } - status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE); - NumberOfBytesTransferred = 0; - fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE); - printf("Server GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", fSuccess, NumberOfBytesTransferred); - printf("Server ReadFile (%d):\n", NumberOfBytesTransferred); + status = WaitForSingleObject(hEvent, PIPE_TIMEOUT_MS); + if (status != WAIT_OBJECT_0) + { + printf("server: failed to wait for overlapped event (read): %u\n", status); + goto finish; + } + + fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, FALSE); + if (!fSuccess) + { + printf("server: NamedPipe ReadFile failure (final): %u\n", GetLastError()); + goto finish; + } + + printf("server: ReadFile transferred %u bytes:\n", NumberOfBytesTransferred); winpr_HexDump("pipe.test", WLOG_DEBUG, lpReadBuffer, NumberOfBytesTransferred); + + if (NumberOfBytesTransferred != PIPE_BUFFER_SIZE || memcmp(lpReadBuffer, CLIENT_MESSAGE, PIPE_BUFFER_SIZE)) + { + printf("server: received unexpected data from client\n"); + goto finish; + } + + + /* 5: write to named pipe */ + nNumberOfBytesToWrite = PIPE_BUFFER_SIZE; - FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x45); - fSuccess = WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, NULL, &overlapped); + NumberOfBytesTransferred = 0; + + fSuccess = WriteFile(hNamedPipe, SERVER_MESSAGE, nNumberOfBytesToWrite, NULL, &overlapped); if (!fSuccess) fSuccess = (GetLastError() == ERROR_IO_PENDING); if (!fSuccess) { - printf("Server NamedPipe WriteFile failure: %d\n", GetLastError()); - free(lpReadBuffer); - free(lpWriteBuffer); - CloseHandle(hNamedPipe); - CloseHandle(hEvent); - return NULL; + printf("server: NamedPipe WriteFile failure (initial): %u\n", GetLastError()); + goto finish; } - status = WaitForMultipleObjects(1, &hEvent, FALSE, INFINITE); - NumberOfBytesTransferred = 0; - fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, TRUE); - printf("Server GetOverlappedResult: fSuccess: %d NumberOfBytesTransferred: %d\n", fSuccess, NumberOfBytesTransferred); - free(lpReadBuffer); - free(lpWriteBuffer); + status = WaitForSingleObject(hEvent, PIPE_TIMEOUT_MS); + if (status != WAIT_OBJECT_0) + { + printf("server: failed to wait for overlapped event (write): %u\n", status); + goto finish; + } + + fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, FALSE); + if (!fSuccess) + { + printf("server: NamedPipe WriteFile failure (final): %u\n", GetLastError()); + goto finish; + } + + printf("server: WriteFile transferred %u bytes:\n", NumberOfBytesTransferred); + //winpr_HexDump("pipe.test", WLOG_DEBUG, lpWriteBuffer, NumberOfBytesTransferred); + + bServerSuccess = TRUE; + printf("server: finished successfully\n"); + +finish: CloseHandle(hNamedPipe); CloseHandle(hEvent); + free(lpReadBuffer); return NULL; } @@ -232,26 +338,38 @@ int TestPipeCreateNamedPipeOverlapped(int argc, char* argv[]) { HANDLE ClientThread; HANDLE ServerThread; + int eFailure = -1; + int eSuccess = 0; + +#ifndef _WIN32 + printf("Note: %s result may currently only be trusted on Win32\n", __FUNCTION__); + eFailure = eSuccess; +#endif - if (!(ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + FillMemory(SERVER_MESSAGE, PIPE_BUFFER_SIZE, 0xAA); + FillMemory(CLIENT_MESSAGE, PIPE_BUFFER_SIZE, 0xBB); + + if (!(serverReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { printf("CreateEvent failed: %d\n", GetLastError()); - return -1; + return eFailure; } if (!(ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL))) { printf("CreateThread (client) failed: %d\n", GetLastError()); - return -1; + return eFailure; } if (!(ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL))) { printf("CreateThread (server) failed: %d\n", GetLastError()); - return -1; + return eFailure; } WaitForSingleObject(ClientThread, INFINITE); WaitForSingleObject(ServerThread, INFINITE); - /* FIXME: Since this function always returns 0 this test is very much useless */ - return 0; + if (bClientSuccess && bServerSuccess) + return eSuccess; + + return eFailure; } diff --git a/winpr/libwinpr/sspi/test/TestEnumerateSecurityPackages.c b/winpr/libwinpr/sspi/test/TestEnumerateSecurityPackages.c index 8cca3e3..b705101 100644 --- a/winpr/libwinpr/sspi/test/TestEnumerateSecurityPackages.c +++ b/winpr/libwinpr/sspi/test/TestEnumerateSecurityPackages.c @@ -3,6 +3,7 @@ #include #include #include +#include int TestEnumerateSecurityPackages(int argc, char* argv[]) { @@ -21,11 +22,11 @@ int TestEnumerateSecurityPackages(int argc, char* argv[]) return -1; } - printf("\nEnumerateSecurityPackages (%d):\n", (unsigned int)cPackages); + _tprintf(_T("\nEnumerateSecurityPackages (%d):\n"), (unsigned int)cPackages); for (index = 0; index < (int) cPackages; index++) { - printf("\"%s\", \"%s\"\n", pPackageInfo[index].Name, pPackageInfo[index].Comment); + _tprintf(_T("\"%s\", \"%s\"\n"), pPackageInfo[index].Name, pPackageInfo[index].Comment); } FreeContextBuffer(pPackageInfo); diff --git a/winpr/libwinpr/sspi/test/TestQuerySecurityPackageInfo.c b/winpr/libwinpr/sspi/test/TestQuerySecurityPackageInfo.c index 5f970fd..a85797f 100644 --- a/winpr/libwinpr/sspi/test/TestQuerySecurityPackageInfo.c +++ b/winpr/libwinpr/sspi/test/TestQuerySecurityPackageInfo.c @@ -2,6 +2,7 @@ #include #include #include +#include int TestQuerySecurityPackageInfo(int argc, char* argv[]) { @@ -18,8 +19,8 @@ int TestQuerySecurityPackageInfo(int argc, char* argv[]) return -1; } - printf("\nQuerySecurityPackageInfo:\n"); - printf("\"%s\", \"%s\"\n", pPackageInfo->Name, pPackageInfo->Comment); + _tprintf(_T("\nQuerySecurityPackageInfo:\n")); + _tprintf(_T("\"%s\", \"%s\"\n"), pPackageInfo->Name, pPackageInfo->Comment); sspi_GlobalFinish(); diff --git a/winpr/libwinpr/synch/test/TestSynchTimerQueue.c b/winpr/libwinpr/synch/test/TestSynchTimerQueue.c index 3b77735..761eafc 100644 --- a/winpr/libwinpr/synch/test/TestSynchTimerQueue.c +++ b/winpr/libwinpr/synch/test/TestSynchTimerQueue.c @@ -1,7 +1,7 @@ #include #include - +#include #include #define FIRE_COUNT 5 @@ -92,16 +92,20 @@ int TestSynchTimerQueue(int argc, char* argv[]) printf("Failed to wait for timer queue timer #%u (%u)\n", index, GetLastError()); return -1; } - CloseHandle(apcData[index].CompletionEvent); } for (index = 0; index < TIMER_COUNT; index++) { - if (!DeleteTimerQueueTimer(hTimerQueue, hTimers[index], NULL)) + /** + * Note: If the CompletionEvent parameter is INVALID_HANDLE_VALUE, the function waits + * for any running timer callback functions to complete before returning. + */ + if (!DeleteTimerQueueTimer(hTimerQueue, hTimers[index], INVALID_HANDLE_VALUE)) { printf("DeleteTimerQueueTimer failed (%u)\n", GetLastError()); return -1; } + CloseHandle(apcData[index].CompletionEvent); } if (!DeleteTimerQueue(hTimerQueue)) diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 41fa929..b8a4dc6 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -285,9 +285,9 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable) { - WLog_ERR(TAG, "Function not implemented."); - assert(0); - return WAIT_OBJECT_0; + WLog_ERR(TAG, "%s: Not implemented."); + SetLastError(ERROR_NOT_SUPPORTED); + return WAIT_FAILED; } DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds) @@ -525,9 +525,9 @@ DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE *lpHandles, BOOL bWait DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable) { - WLog_ERR(TAG, "Function not implemented."); - assert(0); - return 0; + WLog_ERR(TAG, "%s: Not implemented."); + SetLastError(ERROR_NOT_SUPPORTED); + return WAIT_FAILED; } #endif diff --git a/winpr/libwinpr/thread/thread.c b/winpr/libwinpr/thread/thread.c index 39eaa35..54b4310 100644 --- a/winpr/libwinpr/thread/thread.c +++ b/winpr/libwinpr/thread/thread.c @@ -566,7 +566,8 @@ BOOL ThreadCloseHandle(HANDLE handle) HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) { - WLog_ERR(TAG, "not implemented"); + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return NULL; } @@ -698,14 +699,14 @@ DWORD ResumeThread(HANDLE hThread) DWORD SuspendThread(HANDLE hThread) { - WLog_ERR(TAG, "Function not implemented!"); - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return (DWORD)-1; } BOOL SwitchToThread(VOID) { - WLog_ERR(TAG, "Function not implemented!"); - return TRUE; + return (sched_yield() == 0); } BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode) -- 2.7.4