ReactOS  0.4.13-dev-249-gcba1a2f
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 
77 static
78 VOID
81 {
82  HANDLE ClientHandle;
83 
84  ClientHandle = NULL;
85  Context->Connect.Status = NpOpenPipeEx(&ClientHandle,
86  Context->Connect.PipePath,
89  FILE_OPEN,
90  Context->Connect.ClientSynchronous ? FILE_SYNCHRONOUS_IO_NONALERT
91  : 0);
92  Context->Connect.ClientHandle = ClientHandle;
93 }
94 
95 static
96 VOID
99 {
100  Context->Listen.Status = NpListenPipe(Context->Listen.ServerHandle);
101 }
102 
103 static
104 VOID
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 
114 static
115 VOID
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 
125 static
126 BOOLEAN
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 
139 static
140 BOOLEAN
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 
151 static
152 BOOLEAN
156  OUT PVOID Buffer,
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 
167 static
168 BOOLEAN
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 
183 static KSTART_ROUTINE TestReadWrite;
184 static
185 VOID
186 NTAPI
188  IN PVOID Context)
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);
220  CheckServer(ServerHandle, FILE_PIPE_LISTENING_STATE);
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;
237  CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
238  CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
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;
382  CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
383  CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
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;
413  CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
414  CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
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;
444  CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
445  CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
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);
455  NpQueryPipe(ClientHandle, STATUS_PIPE_DISCONNECTED);
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;
475  CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
476  CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
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;
507  CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
508  CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
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;
540  CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
541  CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);
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);
551  NpQueryPipe(ClientHandle, STATUS_PIPE_DISCONNECTED);
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 
572 START_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 }
static BOOLEAN CheckWritePipe(IN PTHREAD_CONTEXT Context, IN HANDLE PipeHandle, IN const VOID *Buffer, IN ULONG BufferSize, IN ULONG MilliSeconds)
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL)
#define STATUS_PIPE_DISCONNECTED
Definition: ntstatus.h:398
#define CheckPipeContext(Context, ExpectedStatus, ExpectedBytes)
Definition: NpfsReadWrite.c:70
#define CheckClient(ClientHandle, State)
Definition: NpfsReadWrite.c:46
#define CheckServer(ServerHandle, State)
Definition: NpfsReadWrite.c:38
static KSTART_ROUTINE TestReadWrite
BOOLEAN TriggerWork(IN PTHREAD_CONTEXT Context, IN ULONG MilliSeconds)
Definition: NpfsHelpers.c:710
VOID StartWorkerThread(OUT PTHREAD_CONTEXT Context)
Definition: NpfsHelpers.c:674
LONG NTSTATUS
Definition: precomp.h:26
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define ok_eq_ulongptr(value, expected)
Definition: kmt_test.h:249
#define IN_QUOTA
Definition: NpfsReadWrite.c:19
#define DEVICE_NAMED_PIPE
Definition: npfs.h:11
#define OUT_QUOTA
Definition: NpfsReadWrite.c:20
#define FILE_PIPE_CONNECTED_STATE
Definition: winternl.h:792
struct _THREAD_CONTEXT::@1557::@1560 Listen
VOID FinishWorkerThread(IN PTHREAD_CONTEXT Context)
Definition: NpfsHelpers.c:685
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define STATUS_PIPE_CLOSING
Definition: ntstatus.h:399
#define CheckServerQuota(ServerHandle, InQ, OutQ)
Definition: NpfsReadWrite.c:54
#define FILE_SHARE_READ
Definition: compat.h:125
#define ok_bool_false(value, desc)
Definition: kmt_test.h:257
static BOOLEAN CheckReadPipe(IN PTHREAD_CONTEXT Context, IN HANDLE PipeHandle, OUT PVOID Buffer, IN ULONG BufferSize, IN ULONG MilliSeconds)
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
struct _THREAD_CONTEXT::@1557::@1559 Connect
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define NpCheckServerPipe(h, rm, cm, npt, npc, mi, ci, iq, rsa, oq, wqa, nps)
Definition: npfs.h:95
#define GENERIC_WRITE
Definition: nt_native.h:90
static VOID ReadPipe(IN OUT PTHREAD_CONTEXT Context)
static BOOLEAN CheckListenPipe(IN PTHREAD_CONTEXT Context, IN HANDLE ServerHandle, IN ULONG MilliSeconds)
unsigned char BOOLEAN
NTSTATUS NpReadPipe(IN HANDLE PipeHandle, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG_PTR BytesRead)
Definition: NpfsHelpers.c:322
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
static BOOLEAN CheckConnectPipe(IN PTHREAD_CONTEXT Context, IN PCWSTR PipePath, IN BOOLEAN ClientSynchronous, IN ULONG MilliSeconds)
#define FILE_PIPE_LISTENING_STATE
Definition: winternl.h:791
NTSTATUS NpWritePipe(IN HANDLE PipeHandle, IN const VOID *Buffer, IN ULONG BufferSize, OUT PULONG_PTR BytesWritten)
Definition: NpfsHelpers.c:374
#define STATUS_PIPE_LISTENING
Definition: ntstatus.h:401
struct _THREAD_CONTEXT::@1557::@1561 ReadWrite
#define BufferSize
Definition: classpnp.h:419
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define DUPLEX
Definition: npfs.h:21
#define NpDisconnectPipe(ServerHandle)
Definition: npfs.h:74
#define STATUS_PIPE_BROKEN
Definition: ntstatus.h:553
#define CheckClientQuota(ClientHandle, InQ, OutQ)
Definition: NpfsReadWrite.c:62
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
static const WCHAR L[]
Definition: oid.c:1250
START_TEST(NpfsReadWrite)
#define GENERIC_READ
Definition: compat.h:124
#define BYTE_STREAM
Definition: npfs.h:13
#define SYNCHRONIZE
Definition: nt_native.h:61
static VOID ListenPipe(IN OUT PTHREAD_CONTEXT Context)
Definition: NpfsReadWrite.c:97
VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL)
#define MakeServer(ServerHandle, PipePath, ServerSynchronous)
Definition: NpfsReadWrite.c:22
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
#define NpCheckClientPipe(h, rm, cm, npt, npc, mi, ci, iq, rsa, oq, wqa, nps)
Definition: npfs.h:121
BOOLEAN WaitForWork(IN PTHREAD_CONTEXT Context, IN ULONG MilliSeconds)
Definition: NpfsHelpers.c:692
#define FILE_PIPE_DISCONNECTED_STATE
Definition: winternl.h:790
#define NpQueryPipe(h, es)
Definition: npfs.h:147
static HANDLE PipeHandle
Definition: dhcpcsvc.c:21
struct _READ_WRITE_TEST_CONTEXT * PREAD_WRITE_TEST_CONTEXT
#define QUEUE
Definition: npfs.h:17
static VOID WritePipe(IN OUT PTHREAD_CONTEXT Context)
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_PIPE_CLOSING_STATE
Definition: winternl.h:793
#define OUT
Definition: typedefs.h:39
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#define ok_eq_hex(value, expected)
#define ok_eq_uint(value, expected)
Definition: kmt_test.h:239
static VOID ConnectPipe(IN OUT PTHREAD_CONTEXT Context)
Definition: NpfsReadWrite.c:79
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define WriteBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:344
LONGLONG QuadPart
Definition: typedefs.h:112
struct _READ_WRITE_TEST_CONTEXT READ_WRITE_TEST_CONTEXT
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 NpListenPipe(ServerHandle)
Definition: npfs.h:73
#define MAX_INSTANCES
Definition: NpfsReadWrite.c:18