ReactOS 0.4.15-dev-8116-gf69e256
NpfsReadWrite.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite NPFS Read/Write test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8#include <kmt_test.h>
9#include "npfs.h"
10
12{
17
18#define MAX_INSTANCES 5
19#define IN_QUOTA 4096
20#define OUT_QUOTA 4096
21
22#define MakeServer(ServerHandle, PipePath, ServerSynchronous) \
23 NpCreatePipeEx(ServerHandle, \
24 PipePath, \
25 BYTE_STREAM, \
26 QUEUE, \
27 BYTE_STREAM, \
28 FILE_SHARE_READ | FILE_SHARE_WRITE, \
29 MAX_INSTANCES, \
30 IN_QUOTA, \
31 OUT_QUOTA, \
32 SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, \
33 FILE_OPEN_IF, \
34 (ServerSynchronous) ? FILE_SYNCHRONOUS_IO_NONALERT \
35 : 0, \
36 &DefaultTimeout)
37
38#define CheckServer(ServerHandle, State) \
39 NpCheckServerPipe(ServerHandle, \
40 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
41 MAX_INSTANCES, 1, \
42 IN_QUOTA, 0, \
43 OUT_QUOTA, OUT_QUOTA, \
44 State)
45
46#define CheckClient(ClientHandle, State) \
47 NpCheckClientPipe(ClientHandle, \
48 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
49 MAX_INSTANCES, 1, \
50 IN_QUOTA, 0, \
51 OUT_QUOTA, OUT_QUOTA, \
52 State)
53
54#define CheckServerQuota(ServerHandle, InQ, OutQ) \
55 NpCheckServerPipe(ServerHandle, \
56 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
57 MAX_INSTANCES, 1, \
58 IN_QUOTA, InQ, \
59 OUT_QUOTA, OUT_QUOTA - (OutQ), \
60 FILE_PIPE_CONNECTED_STATE)
61
62#define CheckClientQuota(ClientHandle, InQ, OutQ) \
63 NpCheckClientPipe(ClientHandle, \
64 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
65 MAX_INSTANCES, 1, \
66 IN_QUOTA, InQ, \
67 OUT_QUOTA, OUT_QUOTA - (OutQ), \
68 FILE_PIPE_CONNECTED_STATE)
69
70#define CheckPipeContext(Context, ExpectedStatus, ExpectedBytes) do \
71{ \
72 ok_bool_true(Okay, "CheckPipeContext"); \
73 ok_eq_hex((Context)->ReadWrite.Status, ExpectedStatus); \
74 ok_eq_ulongptr((Context)->ReadWrite.BytesTransferred, ExpectedBytes); \
75} while (0)
76
77static
78VOID
81{
82 HANDLE ClientHandle;
83
84 ClientHandle = NULL;
85 Context->Connect.Status = NpOpenPipeEx(&ClientHandle,
86 Context->Connect.PipePath,
90 Context->Connect.ClientSynchronous ? FILE_SYNCHRONOUS_IO_NONALERT
91 : 0);
92 Context->Connect.ClientHandle = ClientHandle;
93}
94
95static
96VOID
99{
100 Context->Listen.Status = NpListenPipe(Context->Listen.ServerHandle);
101}
102
103static
104VOID
107{
108 Context->ReadWrite.Status = NpReadPipe(Context->ReadWrite.PipeHandle,
109 Context->ReadWrite.Buffer,
110 Context->ReadWrite.BufferSize,
111 (PULONG_PTR)&Context->ReadWrite.BytesTransferred);
112}
113
114static
115VOID
118{
119 Context->ReadWrite.Status = NpWritePipe(Context->ReadWrite.PipeHandle,
120 Context->ReadWrite.Buffer,
121 Context->ReadWrite.BufferSize,
122 (PULONG_PTR)&Context->ReadWrite.BytesTransferred);
123}
124
125static
129 IN PCWSTR PipePath,
130 IN BOOLEAN ClientSynchronous,
131 IN ULONG MilliSeconds)
132{
133 Context->Work = ConnectPipe;
134 Context->Connect.PipePath = PipePath;
135 Context->Connect.ClientSynchronous = ClientSynchronous;
136 return TriggerWork(Context, MilliSeconds);
137}
138
139static
143 IN HANDLE ServerHandle,
144 IN ULONG MilliSeconds)
145{
146 Context->Work = ListenPipe;
147 Context->Listen.ServerHandle = ServerHandle;
148 return TriggerWork(Context, MilliSeconds);
149}
150
151static
158 IN ULONG MilliSeconds)
159{
160 Context->Work = ReadPipe;
161 Context->ReadWrite.PipeHandle = PipeHandle;
162 Context->ReadWrite.Buffer = Buffer;
163 Context->ReadWrite.BufferSize = BufferSize;
164 return TriggerWork(Context, MilliSeconds);
165}
166
167static
172 IN const VOID *Buffer,
174 IN ULONG MilliSeconds)
175{
176 Context->Work = WritePipe;
177 Context->ReadWrite.PipeHandle = PipeHandle;
178 Context->ReadWrite.Buffer = (PVOID)Buffer;
179 Context->ReadWrite.BufferSize = BufferSize;
180 return TriggerWork(Context, MilliSeconds);
181}
182
183static KSTART_ROUTINE TestReadWrite;
184static
185VOID
186NTAPI
189{
190 PREAD_WRITE_TEST_CONTEXT TestContext = Context;
191 PCWSTR PipePath = TestContext->PipePath;
192 BOOLEAN ServerSynchronous = TestContext->ServerSynchronous;
193 BOOLEAN ClientSynchronous = TestContext->ClientSynchronous;
195 HANDLE ServerHandle;
196 LARGE_INTEGER DefaultTimeout;
197 THREAD_CONTEXT ConnectContext;
198 THREAD_CONTEXT ListenContext;
199 THREAD_CONTEXT ClientReadContext;
200 THREAD_CONTEXT ClientWriteContext;
201 THREAD_CONTEXT ServerReadContext;
202 THREAD_CONTEXT ServerWriteContext;
203 BOOLEAN Okay;
204 HANDLE ClientHandle;
205 UCHAR ReadBuffer[128];
206 UCHAR WriteBuffer[128];
207
208 StartWorkerThread(&ConnectContext);
209 StartWorkerThread(&ListenContext);
210 StartWorkerThread(&ClientReadContext);
211 StartWorkerThread(&ClientWriteContext);
212 StartWorkerThread(&ServerReadContext);
213 StartWorkerThread(&ServerWriteContext);
214
215 DefaultTimeout.QuadPart = -50 * 1000 * 10;
216
217 /* Server should start out listening */
218 Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous);
221
222 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, NULL, 0, 100);
223 ok_bool_true(Okay, "CheckWritePipe returned");
224 ok_eq_ulongptr(ServerWriteContext.ReadWrite.BytesTransferred, 0);
225 ok_eq_hex(ServerWriteContext.ReadWrite.Status, STATUS_PIPE_LISTENING);
226
227 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, NULL, 0, 100);
228 ok_bool_true(Okay, "CheckReadPipe returned");
229 ok_eq_ulongptr(ServerReadContext.ReadWrite.BytesTransferred, 0);
230 ok_eq_hex(ServerReadContext.ReadWrite.Status, STATUS_PIPE_LISTENING);
231
232 /* Connect a client */
233 Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100);
234 ok_bool_true(Okay, "CheckConnectPipe returned");
235 ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
236 ClientHandle = ConnectContext.Connect.ClientHandle;
239
241 WriteBuffer[0] = 'A';
242 ReadBuffer[0] = 'X';
243 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100);
244 CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1);
245 CheckServerQuota(ServerHandle, 0, 1); CheckClientQuota(ClientHandle, 1, 0);
246 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
247 CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 1);
248 ok_eq_uint(ReadBuffer[0], 'A');
249 CheckServerQuota(ServerHandle, 0, 0); CheckClientQuota(ClientHandle, 0, 0);
250
252 WriteBuffer[0] = 'B';
253 ReadBuffer[0] = 'X';
254 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
255 ok_bool_false(Okay, "CheckReadPipe returned");
256 CheckServerQuota(ServerHandle, 0, 1);
257 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100);
258 CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1);
259 Okay = WaitForWork(&ClientReadContext, 100);
260 CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 1);
261 ok_eq_uint(ReadBuffer[0], 'B');
262 CheckServerQuota(ServerHandle, 0, 0); CheckClientQuota(ClientHandle, 0, 0);
263
265 WriteBuffer[0] = 'C';
266 ReadBuffer[0] = 'X';
267 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100);
268 CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1);
269 CheckClientQuota(ClientHandle, 0, 1); CheckServerQuota(ServerHandle, 1, 0);
270 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
271 CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 1);
272 ok_eq_uint(ReadBuffer[0], 'C');
273 CheckClientQuota(ClientHandle, 0, 0); CheckServerQuota(ServerHandle, 0, 0);
274
276 WriteBuffer[0] = 'D';
277 ReadBuffer[0] = 'X';
278 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
279 ok_bool_false(Okay, "CheckReadPipe returned");
280 CheckClientQuota(ClientHandle, 0, 1);
281 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100);
282 CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1);
283 Okay = WaitForWork(&ServerReadContext, 100);
284 CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 1);
285 ok_eq_uint(ReadBuffer[0], 'D');
286 CheckClientQuota(ClientHandle, 0, 0); CheckServerQuota(ServerHandle, 0, 0);
287
289 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, (PVOID)1, 0, 100);
290 CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 0);
291 CheckServerQuota(ServerHandle, 0, 0); CheckClientQuota(ClientHandle, 0, 0);
292
294 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, (PVOID)1, 0, 100);
295 CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 0);
296 CheckClientQuota(ClientHandle, 0, 0); CheckServerQuota(ServerHandle, 0, 0);
297
299 WriteBuffer[0] = 'E';
300 ReadBuffer[0] = 'X';
301 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, (PVOID)1, 0, 100);
302 ok_bool_false(Okay, "CheckReadPipe returned");
303 CheckServerQuota(ServerHandle, 0, 0);
304 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, (PVOID)1, 0, 100);
305 CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 0);
306 Okay = WaitForWork(&ClientReadContext, 100);
307 ok_bool_false(Okay, "WaitForWork returned");
308 CheckServerQuota(ServerHandle, 0, 0);
309 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100);
310 CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1);
311 Okay = WaitForWork(&ClientReadContext, 100);
312 CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 0);
313 ok_eq_uint(ReadBuffer[0], 'X');
314 CheckServerQuota(ServerHandle, 0, 1); CheckClientQuota(ClientHandle, 1, 0);
315 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
316 CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 1);
317 ok_eq_uint(ReadBuffer[0], 'E');
318 CheckServerQuota(ServerHandle, 0, 0); CheckClientQuota(ClientHandle, 0, 0);
319
321 WriteBuffer[0] = 'F';
322 ReadBuffer[0] = 'X';
323 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, (PVOID)1, 0, 100);
324 ok_bool_false(Okay, "CheckReadPipe returned");
325 CheckClientQuota(ClientHandle, 0, 0);
326 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, (PVOID)1, 0, 100);
327 CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 0);
328 Okay = WaitForWork(&ServerReadContext, 100);
329 ok_bool_false(Okay, "WaitForWork returned");
330 CheckClientQuota(ClientHandle, 0, 0);
331 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100);
332 CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1);
333 Okay = WaitForWork(&ServerReadContext, 100);
334 CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 0);
335 ok_eq_uint(ReadBuffer[0], 'X');
336 CheckClientQuota(ClientHandle, 0, 1); CheckServerQuota(ServerHandle, 1, 0);
337 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
338 CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 1);
339 ok_eq_uint(ReadBuffer[0], 'F');
340 CheckClientQuota(ClientHandle, 0, 0); CheckServerQuota(ServerHandle, 0, 0);
341
343 WriteBuffer[0] = 'G';
344 ReadBuffer[0] = 'X';
345 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
346 ok_bool_false(Okay, "CheckReadPipe returned");
347 CheckServerQuota(ServerHandle, 0, 1);
348 Status = NpDisconnectPipe(ServerHandle);
350 Okay = WaitForWork(&ClientReadContext, 100);
351 CheckPipeContext(&ClientReadContext, STATUS_PIPE_DISCONNECTED, 0);
352 ok_eq_uint(ReadBuffer[0], 'X');
353
354 /* Read from server when disconnected */
355 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
356 CheckPipeContext(&ServerReadContext, STATUS_PIPE_DISCONNECTED, 0);
357
358 /* Write to server when disconnected */
359 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100);
360 CheckPipeContext(&ServerWriteContext, STATUS_PIPE_DISCONNECTED, 0);
361
362 /* Read from client when disconnected */
363 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
364 CheckPipeContext(&ClientReadContext, STATUS_PIPE_DISCONNECTED, 0);
365
366 /* Write to client when disconnected */
367 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100);
368 CheckPipeContext(&ClientWriteContext, STATUS_PIPE_DISCONNECTED, 0);
369 Status = ObCloseHandle(ClientHandle, KernelMode);
371
372 /* Restore the connection */
373 Okay = CheckListenPipe(&ListenContext, ServerHandle, 100);
374 ok_bool_false(Okay, "CheckListenPipe returned");
375 Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100);
376 ok_bool_true(Okay, "CheckConnectPipe returned");
377 ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
378 Okay = WaitForWork(&ListenContext, 100);
379 ok_bool_true(Okay, "WaitForWork returned");
380 ok_eq_hex(ListenContext.Listen.Status, STATUS_SUCCESS);
381 ClientHandle = ConnectContext.Connect.ClientHandle;
384
386 WriteBuffer[0] = 'H';
387 ReadBuffer[0] = 'X';
388 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
389 ok_bool_false(Okay, "CheckReadPipe returned");
390 Status = ObCloseHandle(ServerHandle, KernelMode);
392 Okay = WaitForWork(&ClientReadContext, 100);
393 CheckPipeContext(&ClientReadContext, STATUS_PIPE_BROKEN, 0);
394 ok_eq_uint(ReadBuffer[0], 'X');
395
396 /* Read from client when closed */
397 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
398 CheckPipeContext(&ClientReadContext, STATUS_PIPE_BROKEN, 0);
399
400 /* Write to client when closed */
401 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100);
402 CheckPipeContext(&ClientWriteContext, STATUS_PIPE_CLOSING, 0);
403 Status = ObCloseHandle(ClientHandle, KernelMode);
405
406 /* Restore the connection */
407 Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous);
409 Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100);
410 ok_bool_true(Okay, "CheckConnectPipe returned");
411 ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
412 ClientHandle = ConnectContext.Connect.ClientHandle;
415
417 WriteBuffer[0] = 'I';
418 ReadBuffer[0] = 'X';
419 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
420 ok_bool_false(Okay, "CheckReadPipe returned");
421 Status = ObCloseHandle(ClientHandle, KernelMode);
423 Okay = WaitForWork(&ServerReadContext, 100);
424 CheckPipeContext(&ServerReadContext, STATUS_PIPE_BROKEN, 0);
425 ok_eq_uint(ReadBuffer[0], 'X');
426
427 /* Read from server when closed */
428 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
429 CheckPipeContext(&ServerReadContext, STATUS_PIPE_BROKEN, 0);
430
431 /* Write to server when closed */
432 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100);
433 CheckPipeContext(&ServerWriteContext, STATUS_PIPE_CLOSING, 0);
434 Status = ObCloseHandle(ServerHandle, KernelMode);
436
437 /* Restore the connection */
438 Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous);
440 Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100);
441 ok_bool_true(Okay, "CheckConnectPipe returned");
442 ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
443 ClientHandle = ConnectContext.Connect.ClientHandle;
446
448 WriteBuffer[0] = 'J';
449 ReadBuffer[0] = 'X';
450 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100);
451 CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1);
452 CheckServerQuota(ServerHandle, 0, 1); CheckClientQuota(ClientHandle, 1, 0);
453 Status = NpDisconnectPipe(ServerHandle);
457 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
458 CheckPipeContext(&ClientReadContext, STATUS_PIPE_DISCONNECTED, 0);
459 ok_eq_uint(ReadBuffer[0], 'X');
460 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
461 CheckPipeContext(&ClientReadContext, STATUS_PIPE_DISCONNECTED, 0);
462 Status = ObCloseHandle(ClientHandle, KernelMode);
464
465 /* Restore the connection */
466 Okay = CheckListenPipe(&ListenContext, ServerHandle, 100);
467 ok_bool_false(Okay, "CheckListenPipe returned");
468 Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100);
469 ok_bool_true(Okay, "CheckConnectPipe returned");
470 ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
471 Okay = WaitForWork(&ListenContext, 100);
472 ok_bool_true(Okay, "WaitForWork returned");
473 ok_eq_hex(ListenContext.Listen.Status, STATUS_SUCCESS);
474 ClientHandle = ConnectContext.Connect.ClientHandle;
477
479 WriteBuffer[0] = 'K';
480 ReadBuffer[0] = 'X';
481 Okay = CheckWritePipe(&ServerWriteContext, ServerHandle, WriteBuffer, 1, 100);
482 CheckPipeContext(&ServerWriteContext, STATUS_SUCCESS, 1);
483 CheckServerQuota(ServerHandle, 0, 1); CheckClientQuota(ClientHandle, 1, 0);
484 Status = ObCloseHandle(ServerHandle, KernelMode);
486 NpCheckClientPipe(ClientHandle,
488 MAX_INSTANCES, 1,
489 IN_QUOTA, 1,
492 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
493 CheckPipeContext(&ClientReadContext, STATUS_SUCCESS, 1);
494 ok_eq_uint(ReadBuffer[0], 'K');
495 Okay = CheckReadPipe(&ClientReadContext, ClientHandle, ReadBuffer, 1, 100);
496 CheckPipeContext(&ClientReadContext, STATUS_PIPE_BROKEN, 0);
497 Status = ObCloseHandle(ClientHandle, KernelMode);
499
500 /* Restore the connection */
501 Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous);
503 Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100);
504 ok_bool_true(Okay, "CheckConnectPipe returned");
505 ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
506 ClientHandle = ConnectContext.Connect.ClientHandle;
509
510
512 WriteBuffer[0] = 'L';
513 ReadBuffer[0] = 'X';
514 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100);
515 CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1);
516 CheckClientQuota(ClientHandle, 0, 1); CheckServerQuota(ServerHandle, 1, 0);
517 Status = ObCloseHandle(ClientHandle, KernelMode);
519 NpCheckServerPipe(ServerHandle,
521 MAX_INSTANCES, 1,
522 IN_QUOTA, 1,
525 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
526 CheckPipeContext(&ServerReadContext, STATUS_SUCCESS, 1);
527 ok_eq_uint(ReadBuffer[0], 'L');
528 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
529 CheckPipeContext(&ServerReadContext, STATUS_PIPE_BROKEN, 0);
530 Status = ObCloseHandle(ServerHandle, KernelMode);
532
533 /* Restore the connection */
534 Status = MakeServer(&ServerHandle, PipePath, ServerSynchronous);
536 Okay = CheckConnectPipe(&ConnectContext, PipePath, ClientSynchronous, 100);
537 ok_bool_true(Okay, "CheckConnectPipe returned");
538 ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
539 ClientHandle = ConnectContext.Connect.ClientHandle;
542
544 WriteBuffer[0] = 'M';
545 ReadBuffer[0] = 'X';
546 Okay = CheckWritePipe(&ClientWriteContext, ClientHandle, WriteBuffer, 1, 100);
547 CheckPipeContext(&ClientWriteContext, STATUS_SUCCESS, 1);
548 CheckClientQuota(ClientHandle, 0, 1); CheckServerQuota(ServerHandle, 1, 0);
549 Status = NpDisconnectPipe(ServerHandle);
553 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
554 CheckPipeContext(&ServerReadContext, STATUS_PIPE_DISCONNECTED, 0);
555 ok_eq_uint(ReadBuffer[0], 'X');
556 Okay = CheckReadPipe(&ServerReadContext, ServerHandle, ReadBuffer, 1, 100);
557 CheckPipeContext(&ServerReadContext, STATUS_PIPE_DISCONNECTED, 0);
558 Status = ObCloseHandle(ClientHandle, KernelMode);
560
561 Status = ObCloseHandle(ServerHandle, KernelMode);
563
564 FinishWorkerThread(&ServerWriteContext);
565 FinishWorkerThread(&ServerReadContext);
566 FinishWorkerThread(&ClientWriteContext);
567 FinishWorkerThread(&ClientReadContext);
568 FinishWorkerThread(&ListenContext);
569 FinishWorkerThread(&ConnectContext);
570}
571
572START_TEST(NpfsReadWrite)
573{
575 READ_WRITE_TEST_CONTEXT TestContext;
576
577 TestContext.PipePath = DEVICE_NAMED_PIPE L"\\KmtestNpfsReadWriteTestPipe";
578
579 TestContext.ServerSynchronous = TRUE;
580 TestContext.ClientSynchronous = TRUE;
581 Thread = KmtStartThread(TestReadWrite, &TestContext);
583
584 TestContext.ServerSynchronous = FALSE;
585 TestContext.ClientSynchronous = TRUE;
586 Thread = KmtStartThread(TestReadWrite, &TestContext);
588
589 TestContext.ServerSynchronous = TRUE;
590 TestContext.ClientSynchronous = FALSE;
591 Thread = KmtStartThread(TestReadWrite, &TestContext);
593
594 TestContext.ServerSynchronous = FALSE;
595 TestContext.ClientSynchronous = FALSE;
596 Thread = KmtStartThread(TestReadWrite, &TestContext);
598}
#define CheckServerQuota(ServerHandle, InQ, OutQ)
Definition: NpfsReadWrite.c:54
#define OUT_QUOTA
Definition: NpfsReadWrite.c:20
static BOOLEAN CheckListenPipe(IN PTHREAD_CONTEXT Context, IN HANDLE ServerHandle, IN ULONG MilliSeconds)
struct _READ_WRITE_TEST_CONTEXT * PREAD_WRITE_TEST_CONTEXT
static BOOLEAN CheckReadPipe(IN PTHREAD_CONTEXT Context, IN HANDLE PipeHandle, OUT PVOID Buffer, IN ULONG BufferSize, IN ULONG MilliSeconds)
#define CheckClientQuota(ClientHandle, InQ, OutQ)
Definition: NpfsReadWrite.c:62
#define CheckClient(ClientHandle, State)
Definition: NpfsReadWrite.c:46
static BOOLEAN CheckConnectPipe(IN PTHREAD_CONTEXT Context, IN PCWSTR PipePath, IN BOOLEAN ClientSynchronous, IN ULONG MilliSeconds)
#define CheckPipeContext(Context, ExpectedStatus, ExpectedBytes)
Definition: NpfsReadWrite.c:70
static VOID ListenPipe(IN OUT PTHREAD_CONTEXT Context)
Definition: NpfsReadWrite.c:97
#define CheckServer(ServerHandle, State)
Definition: NpfsReadWrite.c:38
#define MakeServer(ServerHandle, PipePath, ServerSynchronous)
Definition: NpfsReadWrite.c:22
static VOID ReadPipe(IN OUT PTHREAD_CONTEXT Context)
static KSTART_ROUTINE TestReadWrite
#define IN_QUOTA
Definition: NpfsReadWrite.c:19
static BOOLEAN CheckWritePipe(IN PTHREAD_CONTEXT Context, IN HANDLE PipeHandle, IN const VOID *Buffer, IN ULONG BufferSize, IN ULONG MilliSeconds)
#define MAX_INSTANCES
Definition: NpfsReadWrite.c:18
static VOID ConnectPipe(IN OUT PTHREAD_CONTEXT Context)
Definition: NpfsReadWrite.c:79
static VOID WritePipe(IN OUT PTHREAD_CONTEXT Context)
struct _READ_WRITE_TEST_CONTEXT READ_WRITE_TEST_CONTEXT
unsigned char BOOLEAN
#define ok_eq_hex(value, expected)
Definition: apitest.h:77
#define ok_bool_false(value, desc)
Definition: apitest.h:79
#define ok_eq_uint(value, expected)
Definition: apitest.h:61
#define ok_bool_true(value, desc)
Definition: apitest.h:78
#define ok_eq_ulongptr(value, expected)
Definition: apitest.h:71
#define WriteBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:344
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
#define BufferSize
Definition: mmc.h:75
static HANDLE PipeHandle
Definition: dhcpcsvc.c:22
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GENERIC_READ
Definition: compat.h:135
#define FILE_SHARE_READ
Definition: compat.h:136
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
#define FILE_PIPE_DISCONNECTED_STATE
Definition: winternl.h:790
#define FILE_PIPE_LISTENING_STATE
Definition: winternl.h:791
#define FILE_PIPE_CONNECTED_STATE
Definition: winternl.h:792
#define FILE_PIPE_CLOSING_STATE
Definition: winternl.h:793
PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL)
VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL)
NTSTATUS NpOpenPipeEx(OUT PHANDLE ClientHandle, IN PCWSTR PipePath, IN ACCESS_MASK DesiredAccess, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions)
Definition: NpfsHelpers.c:130
#define NpDisconnectPipe(ServerHandle)
Definition: npfs.h:74
BOOLEAN WaitForWork(IN PTHREAD_CONTEXT Context, IN ULONG MilliSeconds)
Definition: NpfsHelpers.c:692
#define BYTE_STREAM
Definition: npfs.h:13
NTSTATUS NpWritePipe(IN HANDLE PipeHandle, IN const VOID *Buffer, IN ULONG BufferSize, OUT PULONG_PTR BytesWritten)
Definition: NpfsHelpers.c:374
VOID FinishWorkerThread(IN PTHREAD_CONTEXT Context)
Definition: NpfsHelpers.c:685
#define DUPLEX
Definition: npfs.h:21
NTSTATUS NpReadPipe(IN HANDLE PipeHandle, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG_PTR BytesRead)
Definition: NpfsHelpers.c:322
BOOLEAN TriggerWork(IN PTHREAD_CONTEXT Context, IN ULONG MilliSeconds)
Definition: NpfsHelpers.c:710
#define DEVICE_NAMED_PIPE
Definition: npfs.h:11
VOID StartWorkerThread(OUT PTHREAD_CONTEXT Context)
Definition: NpfsHelpers.c:674
#define NpCheckServerPipe(h, rm, cm, npt, npc, mi, ci, iq, rsa, oq, wqa, nps)
Definition: npfs.h:95
#define NpListenPipe(ServerHandle)
Definition: npfs.h:73
#define QUEUE
Definition: npfs.h:17
#define NpQueryPipe(h, es)
Definition: npfs.h:147
#define NpCheckClientPipe(h, rm, cm, npt, npc, mi, ci, iq, rsa, oq, wqa, nps)
Definition: npfs.h:121
#define KernelMode
Definition: asm.h:34
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define GENERIC_WRITE
Definition: nt_native.h:90
#define STATUS_PIPE_DISCONNECTED
Definition: ntstatus.h:412
#define STATUS_PIPE_LISTENING
Definition: ntstatus.h:415
#define STATUS_PIPE_BROKEN
Definition: ntstatus.h:567
#define STATUS_PIPE_CLOSING
Definition: ntstatus.h:413
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _THREAD_CONTEXT::@1620::@1623 Listen
struct _THREAD_CONTEXT::@1620::@1622 Connect
struct _THREAD_CONTEXT::@1620::@1624 ReadWrite
uint32_t * PULONG_PTR
Definition: typedefs.h:65
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
unsigned char UCHAR
Definition: xmlstorage.h:181