Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599/* * PROJECT: ReactOS kernel-mode tests * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory * PURPOSE: Kernel-Mode Test Suite NPFS Read/Write test * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org> */
#include <kmt_test.h>#include "npfs.h"
typedef struct _READ_WRITE_TEST_CONTEXT{ PCWSTR PipePath; BOOLEAN ServerSynchronous; BOOLEAN ClientSynchronous;} READ_WRITE_TEST_CONTEXT, *PREAD_WRITE_TEST_CONTEXT;
#define MAX_INSTANCES 5#define IN_QUOTA 4096#define OUT_QUOTA 4096
#define MakeServer(ServerHandle, PipePath, ServerSynchronous) \ NpCreatePipeEx(ServerHandle, \ PipePath, \ BYTE_STREAM, \ QUEUE, \ BYTE_STREAM, \ FILE_SHARE_READ | FILE_SHARE_WRITE, \ MAX_INSTANCES, \ IN_QUOTA, \ OUT_QUOTA, \ SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, \ FILE_OPEN_IF, \ (ServerSynchronous) ? FILE_SYNCHRONOUS_IO_NONALERT \ : 0, \ &DefaultTimeout)
#define CheckServer(ServerHandle, State) \ NpCheckServerPipe(ServerHandle, \ BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \ MAX_INSTANCES, 1, \ IN_QUOTA, 0, \ OUT_QUOTA, OUT_QUOTA, \ State)
#define CheckClient(ClientHandle, State) \ NpCheckClientPipe(ClientHandle, \ BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \ MAX_INSTANCES, 1, \ IN_QUOTA, 0, \ OUT_QUOTA, OUT_QUOTA, \ State)
#define CheckServerQuota(ServerHandle, InQ, OutQ) \ NpCheckServerPipe(ServerHandle, \ BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \ MAX_INSTANCES, 1, \ IN_QUOTA, InQ, \ OUT_QUOTA, OUT_QUOTA - (OutQ), \ FILE_PIPE_CONNECTED_STATE)
#define CheckClientQuota(ClientHandle, InQ, OutQ) \ NpCheckClientPipe(ClientHandle, \ BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \ MAX_INSTANCES, 1, \ IN_QUOTA, InQ, \ OUT_QUOTA, OUT_QUOTA - (OutQ), \ FILE_PIPE_CONNECTED_STATE)
#define CheckPipeContext(Context, ExpectedStatus, ExpectedBytes) do \{ \ ok_bool_true(Okay, "CheckPipeContext"); \ ok_eq_hex((Context)->ReadWrite.Status, ExpectedStatus); \ ok_eq_ulongptr((Context)->ReadWrite.BytesTransferred, ExpectedBytes); \} while (0)
staticVOIDConnectPipe( IN OUT PTHREAD_CONTEXT Context){ HANDLE ClientHandle;
ClientHandle = NULL; Context->Connect.Status = NpOpenPipeEx(&ClientHandle, Context->Connect.PipePath, SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, Context->Connect.ClientSynchronous ? FILE_SYNCHRONOUS_IO_NONALERT : 0); Context->Connect.ClientHandle = ClientHandle;}
staticVOIDListenPipe( IN OUT PTHREAD_CONTEXT Context){ Context->Listen.Status = NpListenPipe(Context->Listen.ServerHandle);}
staticVOIDReadPipe( IN OUT PTHREAD_CONTEXT Context){ Context->ReadWrite.Status = NpReadPipe(Context->ReadWrite.PipeHandle, Context->ReadWrite.Buffer, Context->ReadWrite.BufferSize, (PULONG_PTR)&Context->ReadWrite.BytesTransferred);}
staticVOIDWritePipe( IN OUT PTHREAD_CONTEXT Context){ Context->ReadWrite.Status = NpWritePipe(Context->ReadWrite.PipeHandle, Context->ReadWrite.Buffer, Context->ReadWrite.BufferSize, (PULONG_PTR)&Context->ReadWrite.BytesTransferred);}
staticBOOLEANCheckConnectPipe( IN PTHREAD_CONTEXT Context, IN PCWSTR PipePath, IN BOOLEAN ClientSynchronous, IN ULONG MilliSeconds){ Context->Work = ConnectPipe; Context->Connect.PipePath = PipePath; Context->Connect.ClientSynchronous = ClientSynchronous; return TriggerWork(Context, MilliSeconds);}
staticBOOLEANCheckListenPipe( IN PTHREAD_CONTEXT Context, IN HANDLE ServerHandle, IN ULONG MilliSeconds){ Context->Work = ListenPipe; Context->Listen.ServerHandle = ServerHandle; return TriggerWork(Context, MilliSeconds);}
staticBOOLEANCheckReadPipe( IN PTHREAD_CONTEXT Context, IN HANDLE PipeHandle, OUT PVOID Buffer, IN ULONG BufferSize, IN ULONG MilliSeconds){ Context->Work = ReadPipe; Context->ReadWrite.PipeHandle = PipeHandle; Context->ReadWrite.Buffer = Buffer; Context->ReadWrite.BufferSize = BufferSize; return TriggerWork(Context, MilliSeconds);}
staticBOOLEANCheckWritePipe( IN PTHREAD_CONTEXT Context, IN HANDLE PipeHandle, IN const VOID *Buffer, IN ULONG BufferSize, IN ULONG MilliSeconds){ Context->Work = WritePipe; Context->ReadWrite.PipeHandle = PipeHandle; Context->ReadWrite.Buffer = (PVOID)Buffer; Context->ReadWrite.BufferSize = BufferSize; return TriggerWork(Context, MilliSeconds);}
static KSTART_ROUTINE TestReadWrite;staticVOIDNTAPITestReadWrite( IN PVOID Context){ PREAD_WRITE_TEST_CONTEXT TestContext = Context; PCWSTR PipePath = TestContext->PipePath; BOOLEAN ServerSynchronous = TestContext->ServerSynchronous; BOOLEAN ClientSynchronous = TestContext->ClientSynchronous; NTSTATUS Status; HANDLE ServerHandle; LARGE_INTEGER DefaultTimeout; THREAD_CONTEXT ConnectContext; THREAD_CONTEXT ListenContext; THREAD_CONTEXT ClientReadContext; THREAD_CONTEXT ClientWriteContext; THREAD_CONTEXT ServerReadContext; THREAD_CONTEXT ServerWriteContext; BOOLEAN Okay; HANDLE ClientHandle; UCHAR ReadBuffer[128]; UCHAR WriteBuffer[128];
StartWorkerThread(&ConnectContext); StartWorkerThread(&ListenContext); StartWorkerThread(&ClientReadContext); StartWorkerThread(&ClientWriteContext); StartWorkerThread(&ServerReadContext); StartWorkerThread(&ServerWriteContext);
DefaultTimeout.QuadPart = -50 * 1000 * 10;
/* Server should start out listening */ Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous); ok_eq_hex(Status, STATUS_SUCCESS); CheckServer(ServerHandle, FILE_PIPE_LISTENING_STATE);
Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, NULL, 0, 100); ok_bool_true(Okay, "CheckWritePipe returned"); ok_eq_ulongptr(ServerWriteContext.ReadWrite.BytesTransferred, 0); ok_eq_hex(ServerWriteContext.ReadWrite.Status, STATUS_PIPE_LISTENING);
Okay = CheckReadPipe(&ServerReadContext, ServerHandle, NULL, 0, 100); ok_bool_true(Okay, "CheckReadPipe returned"); ok_eq_ulongptr(ServerReadContext.ReadWrite.BytesTransferred, 0); ok_eq_hex(ServerReadContext.ReadWrite.Status, STATUS_PIPE_LISTENING);
/* Connect a client */ Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100); ok_bool_true(Okay, "CheckConnectPipe returned"); ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS); ClientHandle = ConnectContext.Connect.ClientHandle; CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE); CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
/** Server to client, write first, 1 byte */ WriteBuffer[0] = 'A'; ReadBuffer[0] = 'X'; Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100); CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1); CheckServerQuota(ServerHandle, 0, 1); CheckClientQuota(ClientHandle, 1, 0); Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 1); ok_eq_uint(ReadBuffer[0], 'A'); CheckServerQuota(ServerHandle, 0, 0); CheckClientQuota(ClientHandle, 0, 0);
/** Server to client, read first, 1 byte */ WriteBuffer[0] = 'B'; ReadBuffer[0] = 'X'; Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); ok_bool_false(Okay, "CheckReadPipe returned"); CheckServerQuota(ServerHandle, 0, 1); Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100); CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1); Okay = WaitForWork(&ClientReadContext, 100); CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 1); ok_eq_uint(ReadBuffer[0], 'B'); CheckServerQuota(ServerHandle, 0, 0); CheckClientQuota(ClientHandle, 0, 0);
/** Client to server, write first, 1 byte */ WriteBuffer[0] = 'C'; ReadBuffer[0] = 'X'; Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100); CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1); CheckClientQuota(ClientHandle, 0, 1); CheckServerQuota(ServerHandle, 1, 0); Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 1); ok_eq_uint(ReadBuffer[0], 'C'); CheckClientQuota(ClientHandle, 0, 0); CheckServerQuota(ServerHandle, 0, 0);
/** Client to server, read first, 1 byte */ WriteBuffer[0] = 'D'; ReadBuffer[0] = 'X'; Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); ok_bool_false(Okay, "CheckReadPipe returned"); CheckClientQuota(ClientHandle, 0, 1); Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100); CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1); Okay = WaitForWork(&ServerReadContext, 100); CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 1); ok_eq_uint(ReadBuffer[0], 'D'); CheckClientQuota(ClientHandle, 0, 0); CheckServerQuota(ServerHandle, 0, 0);
/** Server to client, write 0 bytes */ Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, (PVOID)1, 0, 100); CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 0); CheckServerQuota(ServerHandle, 0, 0); CheckClientQuota(ClientHandle, 0, 0);
/** Client to Server, write 0 bytes */ Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, (PVOID)1, 0, 100); CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 0); CheckClientQuota(ClientHandle, 0, 0); CheckServerQuota(ServerHandle, 0, 0);
/** Server to client, read 0 bytes blocks, write 0 bytes does not unblock, write 1 byte unblocks */ WriteBuffer[0] = 'E'; ReadBuffer[0] = 'X'; Okay = CheckReadPipe(&ClientReadContext, ClientHandle, (PVOID)1, 0, 100); ok_bool_false(Okay, "CheckReadPipe returned"); CheckServerQuota(ServerHandle, 0, 0); Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, (PVOID)1, 0, 100); CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 0); Okay = WaitForWork(&ClientReadContext, 100); ok_bool_false(Okay, "WaitForWork returned"); CheckServerQuota(ServerHandle, 0, 0); Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100); CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1); Okay = WaitForWork(&ClientReadContext, 100); CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 0); ok_eq_uint(ReadBuffer[0], 'X'); CheckServerQuota(ServerHandle, 0, 1); CheckClientQuota(ClientHandle, 1, 0); Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 1); ok_eq_uint(ReadBuffer[0], 'E'); CheckServerQuota(ServerHandle, 0, 0); CheckClientQuota(ClientHandle, 0, 0);
/** Client to server, read 0 bytes blocks, write 0 bytes does not unblock, write 1 byte unblocks */ WriteBuffer[0] = 'F'; ReadBuffer[0] = 'X'; Okay = CheckReadPipe(&ServerReadContext, ServerHandle, (PVOID)1, 0, 100); ok_bool_false(Okay, "CheckReadPipe returned"); CheckClientQuota(ClientHandle, 0, 0); Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, (PVOID)1, 0, 100); CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 0); Okay = WaitForWork(&ServerReadContext, 100); ok_bool_false(Okay, "WaitForWork returned"); CheckClientQuota(ClientHandle, 0, 0); Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100); CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1); Okay = WaitForWork(&ServerReadContext, 100); CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 0); ok_eq_uint(ReadBuffer[0], 'X'); CheckClientQuota(ClientHandle, 0, 1); CheckServerQuota(ServerHandle, 1, 0); Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 1); ok_eq_uint(ReadBuffer[0], 'F'); CheckClientQuota(ClientHandle, 0, 0); CheckServerQuota(ServerHandle, 0, 0);
/** Disconnect server with pending read on client */ WriteBuffer[0] = 'G'; ReadBuffer[0] = 'X'; Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); ok_bool_false(Okay, "CheckReadPipe returned"); CheckServerQuota(ServerHandle, 0, 1); Status = NpDisconnectPipe(ServerHandle); ok_eq_hex(Status, STATUS_SUCCESS); Okay = WaitForWork(&ClientReadContext, 100); CheckPipeContext(&ClientReadContext, STATUS_PIPE_DISCONNECTED, 0); ok_eq_uint(ReadBuffer[0], 'X');
/* Read from server when disconnected */ Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); CheckPipeContext(&ServerReadContext, STATUS_PIPE_DISCONNECTED, 0);
/* Write to server when disconnected */ Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100); CheckPipeContext(&ServerWriteContext, STATUS_PIPE_DISCONNECTED, 0);
/* Read from client when disconnected */ Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); CheckPipeContext(&ClientReadContext, STATUS_PIPE_DISCONNECTED, 0);
/* Write to client when disconnected */ Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100); CheckPipeContext(&ClientWriteContext, STATUS_PIPE_DISCONNECTED, 0); Status = ObCloseHandle(ClientHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS);
/* Restore the connection */ Okay = CheckListenPipe(&ListenContext, ServerHandle, 100); ok_bool_false(Okay, "CheckListenPipe returned"); Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100); ok_bool_true(Okay, "CheckConnectPipe returned"); ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS); Okay = WaitForWork(&ListenContext, 100); ok_bool_true(Okay, "WaitForWork returned"); ok_eq_hex(ListenContext.Listen.Status, STATUS_SUCCESS); ClientHandle = ConnectContext.Connect.ClientHandle; CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE); CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
/** Close server with pending read on client */ WriteBuffer[0] = 'H'; ReadBuffer[0] = 'X'; Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); ok_bool_false(Okay, "CheckReadPipe returned"); Status = ObCloseHandle(ServerHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); Okay = WaitForWork(&ClientReadContext, 100); CheckPipeContext(&ClientReadContext, STATUS_PIPE_BROKEN, 0); ok_eq_uint(ReadBuffer[0], 'X');
/* Read from client when closed */ Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); CheckPipeContext(&ClientReadContext, STATUS_PIPE_BROKEN, 0);
/* Write to client when closed */ Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100); CheckPipeContext(&ClientWriteContext, STATUS_PIPE_CLOSING, 0); Status = ObCloseHandle(ClientHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS);
/* Restore the connection */ Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous); ok_eq_hex(Status, STATUS_SUCCESS); Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100); ok_bool_true(Okay, "CheckConnectPipe returned"); ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS); ClientHandle = ConnectContext.Connect.ClientHandle; CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE); CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
/** Close client with pending read on server */ WriteBuffer[0] = 'I'; ReadBuffer[0] = 'X'; Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); ok_bool_false(Okay, "CheckReadPipe returned"); Status = ObCloseHandle(ClientHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); Okay = WaitForWork(&ServerReadContext, 100); CheckPipeContext(&ServerReadContext, STATUS_PIPE_BROKEN, 0); ok_eq_uint(ReadBuffer[0], 'X');
/* Read from server when closed */ Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); CheckPipeContext(&ServerReadContext, STATUS_PIPE_BROKEN, 0);
/* Write to server when closed */ Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100); CheckPipeContext(&ServerWriteContext, STATUS_PIPE_CLOSING, 0); Status = ObCloseHandle(ServerHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS);
/* Restore the connection */ Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous); ok_eq_hex(Status, STATUS_SUCCESS); Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100); ok_bool_true(Okay, "CheckConnectPipe returned"); ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS); ClientHandle = ConnectContext.Connect.ClientHandle; CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE); CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
/** Write to server and disconnect, then read from client */ WriteBuffer[0] = 'J'; ReadBuffer[0] = 'X'; Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100); CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1); CheckServerQuota(ServerHandle, 0, 1); CheckClientQuota(ClientHandle, 1, 0); Status = NpDisconnectPipe(ServerHandle); ok_eq_hex(Status, STATUS_SUCCESS); NpQueryPipe(ClientHandle, STATUS_PIPE_DISCONNECTED); CheckServer(ServerHandle, FILE_PIPE_DISCONNECTED_STATE); Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); CheckPipeContext(&ClientReadContext, STATUS_PIPE_DISCONNECTED, 0); ok_eq_uint(ReadBuffer[0], 'X'); Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); CheckPipeContext(&ClientReadContext, STATUS_PIPE_DISCONNECTED, 0); Status = ObCloseHandle(ClientHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS);
/* Restore the connection */ Okay = CheckListenPipe(&ListenContext, ServerHandle, 100); ok_bool_false(Okay, "CheckListenPipe returned"); Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100); ok_bool_true(Okay, "CheckConnectPipe returned"); ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS); Okay = WaitForWork(&ListenContext, 100); ok_bool_true(Okay, "WaitForWork returned"); ok_eq_hex(ListenContext.Listen.Status, STATUS_SUCCESS); ClientHandle = ConnectContext.Connect.ClientHandle; CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE); CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
/** Write to server and close, then read from client */ WriteBuffer[0] = 'K'; ReadBuffer[0] = 'X'; Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100); CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1); CheckServerQuota(ServerHandle, 0, 1); CheckClientQuota(ClientHandle, 1, 0); Status = ObCloseHandle(ServerHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); NpCheckClientPipe(ClientHandle, BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, MAX_INSTANCES, 1, IN_QUOTA, 1, OUT_QUOTA, OUT_QUOTA, FILE_PIPE_CLOSING_STATE); Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 1); ok_eq_uint(ReadBuffer[0], 'K'); Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100); CheckPipeContext(&ClientReadContext, STATUS_PIPE_BROKEN, 0); Status = ObCloseHandle(ClientHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS);
/* Restore the connection */ Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous); ok_eq_hex(Status, STATUS_SUCCESS); Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100); ok_bool_true(Okay, "CheckConnectPipe returned"); ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS); ClientHandle = ConnectContext.Connect.ClientHandle; CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE); CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
/** Write to client and close, then read from server */ WriteBuffer[0] = 'L'; ReadBuffer[0] = 'X'; Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100); CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1); CheckClientQuota(ClientHandle, 0, 1); CheckServerQuota(ServerHandle, 1, 0); Status = ObCloseHandle(ClientHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); NpCheckServerPipe(ServerHandle, BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, MAX_INSTANCES, 1, IN_QUOTA, 1, OUT_QUOTA, OUT_QUOTA, FILE_PIPE_CLOSING_STATE); Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 1); ok_eq_uint(ReadBuffer[0], 'L'); Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); CheckPipeContext(&ServerReadContext, STATUS_PIPE_BROKEN, 0); Status = ObCloseHandle(ServerHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS);
/* Restore the connection */ Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous); ok_eq_hex(Status, STATUS_SUCCESS); Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100); ok_bool_true(Okay, "CheckConnectPipe returned"); ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS); ClientHandle = ConnectContext.Connect.ClientHandle; CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE); CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
/** Write to client and disconnect server, then read from server */ WriteBuffer[0] = 'M'; ReadBuffer[0] = 'X'; Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100); CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1); CheckClientQuota(ClientHandle, 0, 1); CheckServerQuota(ServerHandle, 1, 0); Status = NpDisconnectPipe(ServerHandle); ok_eq_hex(Status, STATUS_SUCCESS); NpQueryPipe(ClientHandle, STATUS_PIPE_DISCONNECTED); CheckServer(ServerHandle, FILE_PIPE_DISCONNECTED_STATE); Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); CheckPipeContext(&ServerReadContext, STATUS_PIPE_DISCONNECTED, 0); ok_eq_uint(ReadBuffer[0], 'X'); Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100); CheckPipeContext(&ServerReadContext, STATUS_PIPE_DISCONNECTED, 0); Status = ObCloseHandle(ClientHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS);
Status = ObCloseHandle(ServerHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS);
FinishWorkerThread(&ServerWriteContext); FinishWorkerThread(&ServerReadContext); FinishWorkerThread(&ClientWriteContext); FinishWorkerThread(&ClientReadContext); FinishWorkerThread(&ListenContext); FinishWorkerThread(&ConnectContext);}
START_TEST(NpfsReadWrite){ PKTHREAD Thread; READ_WRITE_TEST_CONTEXT TestContext;
TestContext.PipePath = DEVICE_NAMED_PIPE L"\\KmtestNpfsReadWriteTestPipe";
TestContext.ServerSynchronous = TRUE; TestContext.ClientSynchronous = TRUE; Thread = KmtStartThread(TestReadWrite, &TestContext); KmtFinishThread(Thread, NULL);
TestContext.ServerSynchronous = FALSE; TestContext.ClientSynchronous = TRUE; Thread = KmtStartThread(TestReadWrite, &TestContext); KmtFinishThread(Thread, NULL);
TestContext.ServerSynchronous = TRUE; TestContext.ClientSynchronous = FALSE; Thread = KmtStartThread(TestReadWrite, &TestContext); KmtFinishThread(Thread, NULL);
TestContext.ServerSynchronous = FALSE; TestContext.ClientSynchronous = FALSE; Thread = KmtStartThread(TestReadWrite, &TestContext); KmtFinishThread(Thread, NULL);}