diff --git a/rdtk/librdtk/test/TestRdTkNinePatch.c b/rdtk/librdtk/test/TestRdTkNinePatch.c index fb50dee8c..0550488fd 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 dd1e3868f..b107b31c5 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 24380448b..ed680a9d2 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 1ef553404..238e5a22e 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 d18a77802..7641367d7 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 a318c9482..9c8278807 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 7b114acd0..2aa5881d2 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 653b7521d..6d9dde908 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; + PWSTR wbuf = NULL; - DestinationString->Buffer = (PWSTR) malloc(DestinationString->MaximumLength); - if (!DestinationString->Buffer) - return STATUS_NO_MEMORY; - - 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; } - return 0; + for (index = 0; index < SourceString->MaximumLength; index++) + { + DestinationString->Buffer[index] = (WCHAR) SourceString->Buffer[index]; + } + + 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() +static INIT_ONCE ntdllInitOnce = INIT_ONCE_STATIC_INIT; + +static BOOL CALLBACK NtdllModuleInit(PINIT_ONCE once, PVOID param, PVOID *context) { - if (moduleInitialized) - return; + HMODULE NtdllModule = LoadLibraryA("ntdll.dll"); - NtdllModule = LoadLibraryA("ntdll.dll"); - moduleInitialized = TRUE; - - if (!NtdllModule) - return; - - 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 d91bf228f..2097177eb 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 0d8a6b6b0..399c2d4ca 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 21b4fb30a..4595784bd 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 ecb8bdf5b..2ce09b2dc 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); - - if (!hNamedPipe) + status = WaitForSingleObject(serverReadyEvent, PIPE_TIMEOUT_MS); + if (status != WAIT_OBJECT_0) { - printf("Named Pipe CreateFile failure: NULL handle\n"); + printf("client: failed to wait for server ready event: %u\n", status); goto finish; } + + /* 1: initialize overlapped structure */ + + ZeroMemory(&overlapped, sizeof(OVERLAPPED)); + if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + 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) - { - printf("Error allocating memory\n"); - goto finish; - } - ZeroMemory(&overlapped, sizeof(OVERLAPPED)); - if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) - { - printf("CreateEvent failure: (%d)\n", GetLastError()); - goto finish; - } + /* 3: write to named pipe */ - overlapped.hEvent = hEvent; nNumberOfBytesToWrite = PIPE_BUFFER_SIZE; - FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x59); - fSuccess = WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, NULL, &overlapped); + NumberOfBytesTransferred = 0; + + fSuccess = WriteFile(hNamedPipe, CLIENT_MESSAGE, nNumberOfBytesToWrite, NULL, &overlapped); if (!fSuccess) fSuccess = (GetLastError() == ERROR_IO_PENDING); if (!fSuccess) { - printf("Client NamedPipe WriteFile failure: %d\n", GetLastError()); + printf("client: NamedPipe WriteFile failure (initial): %u\n", GetLastError()); + goto finish; + } + + status = WaitForSingleObject(hEvent, PIPE_TIMEOUT_MS); + if (status != WAIT_OBJECT_0) + { + printf("client: failed to wait for overlapped event (write): %u\n", status); + goto finish; + } + + fSuccess = GetOverlappedResult(hNamedPipe, &overlapped, &NumberOfBytesTransferred, FALSE); + if (!fSuccess) + { + printf("client: NamedPipe WriteFile failure (final): %u\n", GetLastError()); + goto finish; + } + printf("client: WriteFile transferred %u bytes:\n", NumberOfBytesTransferred); + + + /* 4: read from named pipe */ + + if (!(lpReadBuffer = (BYTE*)calloc(1, PIPE_BUFFER_SIZE))) + { + 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; - if (!(ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) +#ifndef _WIN32 + printf("Note: %s result may currently only be trusted on Win32\n", __FUNCTION__); + eFailure = eSuccess; +#endif + + 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 8cca3e3cc..b705101f0 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 5f970fd86..a85797f48 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 3b77735ec..761eafc14 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 41fa92981..b8a4dc622 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 39eaa3584..54b4310e6 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)