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;
}
/* 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)
/* 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)
/* 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)
/* 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)
/* 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)
/* 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)
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)
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)
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)
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)
if (!pComm)
return FALSE;
- return TRUE;
+ CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
/**
/* 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)
/* 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)
/* 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)
/* TODO: not implemented */
- return TRUE;
+ CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
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)
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)
if (!pComm)
return FALSE;
- return TRUE;
+ CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
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)
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)
if (!pComm)
return FALSE;
- return TRUE;
+ CommLog_Print(WLOG_ERROR, "%s: Not implemented", __FUNCTION__);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
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);
return FALSE;
}
- if (lpOverlapped != NULL)
+ if (lpOverlapped)
{
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE;
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);
while (p[0] && p[1])
{
- printf("%s\n", p);
+ _tprintf(_T("%s\n"), p);
length = _tcslen(p);
p += (length + 1);
}
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);
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);
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;
return FALSE;
}
- if (lpOverlapped)
- {
- WLog_ERR(TAG, "lpOverlapped not implemented!");
- return FALSE;
- }
-
if (dwFlags & LOCKFILE_EXCLUSIVE_LOCK)
lock = LOCK_EX;
else
{
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;
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]",
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)
{
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;
#include <sys/socket.h>
#include <winpr/crt.h>
+#include <winpr/wlog.h>
#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;
}
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
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)
BOOL CancelSynchronousIo(HANDLE hThread)
{
- return TRUE;
+ WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
#endif
#include <winpr/crt.h>
#include <winpr/library.h>
-
+#include <winpr/wlog.h>
#include <winpr/nt.h>
+#include "../log.h"
+#define TAG WINPR_TAG("nt")
+
+
/**
* NtXxx Routines:
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff557720/
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;
}
/**
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));
//STATUS_OBJECT_NAME_NOT_FOUND
return STATUS_SUCCESS;
+#endif
}
/**
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));
*((PULONG_PTR) FileHandle) = (ULONG_PTR) pFileHandle;
return STATUS_SUCCESS;
+#endif
}
/**
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
}
/**
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
}
/**
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
}
/**
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
}
/**
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 <winpr/synch.h>
typedef VOID (WINAPI * RTL_INIT_ANSI_STRING_FN)(PANSI_STRING DestinationString, PCSZ SourceString);
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;
VOID _RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
{
- NtdllModuleInit();
+ InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
if (!pRtlInitUnicodeString)
return;
NTSTATUS _RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString,
PCANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
{
- NtdllModuleInit();
+ InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
if (!pRtlAnsiStringToUnicodeString)
return STATUS_INTERNAL_ERROR;
VOID _RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
{
- NtdllModuleInit();
+ InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
if (!pRtlFreeUnicodeString)
return;
ULONG _RtlNtStatusToDosError(NTSTATUS status)
{
- NtdllModuleInit();
+ InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
if (!pRtlNtStatusToDosError)
return status;
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;
POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess, ULONG OpenOptions)
{
- NtdllModuleInit();
+ InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
if (!pNtOpenFile)
return STATUS_INTERNAL_ERROR;
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;
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;
ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength,
PVOID OutputBuffer, ULONG OutputBufferLength)
{
- NtdllModuleInit();
+ InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
if (!pNtDeviceIoControlFile)
return STATUS_INTERNAL_ERROR;
NTSTATUS _NtClose(HANDLE Handle)
{
- NtdllModuleInit();
+ InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
if (!pNtClose)
return STATUS_INTERNAL_ERROR;
NTSTATUS _NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout)
{
- NtdllModuleInit();
+ InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
if (!pNtWaitForSingleObject)
return STATUS_INTERNAL_ERROR;
#include <winpr/nt.h>
+#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;
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));
if (ntstatus != STATUS_SUCCESS)
{
- printf("NtCreateFile failure: 0x%04X\n", ntstatus);
- return -1;
+ printf("_NtCreateFile failure: 0x%08X\n", ntstatus);
+ return eFailure;
}
_RtlFreeUnicodeString(&uString);
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;
}
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
{
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
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))
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))
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;
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;
}
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;
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)
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)
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;
}
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
#include <winpr/thread.h>
#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");
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)
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)
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)
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;
}
{
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;
}
#include <winpr/crt.h>
#include <winpr/sspi.h>
#include <winpr/winpr.h>
+#include <winpr/tchar.h>
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);
#include <stdio.h>
#include <winpr/sspi.h>
#include <winpr/winpr.h>
+#include <winpr/tchar.h>
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();
#include <winpr/crt.h>
#include <winpr/sysinfo.h>
-
+#include <winpr/file.h>
#include <winpr/synch.h>
#define FIRE_COUNT 5
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))
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)
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
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;
}
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)