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>
11 typedef struct _READ_WRITE_TEST_CONTEXT
14 BOOLEAN ServerSynchronous
;
15 BOOLEAN ClientSynchronous
;
16 } READ_WRITE_TEST_CONTEXT
, *PREAD_WRITE_TEST_CONTEXT
;
18 #define MAX_INSTANCES 5
20 #define OUT_QUOTA 4096
22 #define MakeServer(ServerHandle, PipePath, ServerSynchronous) \
23 NpCreatePipeEx(ServerHandle, \
28 FILE_SHARE_READ | FILE_SHARE_WRITE, \
32 SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, \
34 (ServerSynchronous) ? FILE_SYNCHRONOUS_IO_NONALERT \
38 #define CheckServer(ServerHandle, State) \
39 NpCheckServerPipe(ServerHandle, \
40 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
43 OUT_QUOTA, OUT_QUOTA, \
46 #define CheckClient(ClientHandle, State) \
47 NpCheckClientPipe(ClientHandle, \
48 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
51 OUT_QUOTA, OUT_QUOTA, \
54 #define CheckServerQuota(ServerHandle, InQ, OutQ) \
55 NpCheckServerPipe(ServerHandle, \
56 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
59 OUT_QUOTA, OUT_QUOTA - (OutQ), \
60 FILE_PIPE_CONNECTED_STATE)
62 #define CheckClientQuota(ClientHandle, InQ, OutQ) \
63 NpCheckClientPipe(ClientHandle, \
64 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
67 OUT_QUOTA, OUT_QUOTA - (OutQ), \
68 FILE_PIPE_CONNECTED_STATE)
70 #define CheckPipeContext(Context, ExpectedStatus, ExpectedBytes) do \
72 ok_bool_true(Okay, "CheckPipeContext"); \
73 ok_eq_hex((Context)->ReadWrite.Status, ExpectedStatus); \
74 ok_eq_ulongptr((Context)->ReadWrite.BytesTransferred, ExpectedBytes); \
80 IN OUT PTHREAD_CONTEXT Context
)
85 Context
->Connect
.Status
= NpOpenPipeEx(&ClientHandle
,
86 Context
->Connect
.PipePath
,
87 SYNCHRONIZE
| GENERIC_READ
| GENERIC_WRITE
,
88 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
90 Context
->Connect
.ClientSynchronous
? FILE_SYNCHRONOUS_IO_NONALERT
92 Context
->Connect
.ClientHandle
= ClientHandle
;
98 IN OUT PTHREAD_CONTEXT Context
)
100 Context
->Listen
.Status
= NpListenPipe(Context
->Listen
.ServerHandle
);
106 IN OUT PTHREAD_CONTEXT Context
)
108 Context
->ReadWrite
.Status
= NpReadPipe(Context
->ReadWrite
.PipeHandle
,
109 Context
->ReadWrite
.Buffer
,
110 Context
->ReadWrite
.BufferSize
,
111 (PULONG_PTR
)&Context
->ReadWrite
.BytesTransferred
);
117 IN OUT PTHREAD_CONTEXT Context
)
119 Context
->ReadWrite
.Status
= NpWritePipe(Context
->ReadWrite
.PipeHandle
,
120 Context
->ReadWrite
.Buffer
,
121 Context
->ReadWrite
.BufferSize
,
122 (PULONG_PTR
)&Context
->ReadWrite
.BytesTransferred
);
128 IN PTHREAD_CONTEXT Context
,
130 IN BOOLEAN ClientSynchronous
,
131 IN ULONG MilliSeconds
)
133 Context
->Work
= ConnectPipe
;
134 Context
->Connect
.PipePath
= PipePath
;
135 Context
->Connect
.ClientSynchronous
= ClientSynchronous
;
136 return TriggerWork(Context
, MilliSeconds
);
142 IN PTHREAD_CONTEXT Context
,
143 IN HANDLE ServerHandle
,
144 IN ULONG MilliSeconds
)
146 Context
->Work
= ListenPipe
;
147 Context
->Listen
.ServerHandle
= ServerHandle
;
148 return TriggerWork(Context
, MilliSeconds
);
154 IN PTHREAD_CONTEXT Context
,
155 IN HANDLE PipeHandle
,
158 IN ULONG MilliSeconds
)
160 Context
->Work
= ReadPipe
;
161 Context
->ReadWrite
.PipeHandle
= PipeHandle
;
162 Context
->ReadWrite
.Buffer
= Buffer
;
163 Context
->ReadWrite
.BufferSize
= BufferSize
;
164 return TriggerWork(Context
, MilliSeconds
);
170 IN PTHREAD_CONTEXT Context
,
171 IN HANDLE PipeHandle
,
172 IN
const VOID
*Buffer
,
174 IN ULONG MilliSeconds
)
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
);
183 static KSTART_ROUTINE TestReadWrite
;
190 PREAD_WRITE_TEST_CONTEXT TestContext
= Context
;
191 PCWSTR PipePath
= TestContext
->PipePath
;
192 BOOLEAN ServerSynchronous
= TestContext
->ServerSynchronous
;
193 BOOLEAN ClientSynchronous
= TestContext
->ClientSynchronous
;
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
;
205 UCHAR ReadBuffer
[128];
206 UCHAR WriteBuffer
[128];
208 StartWorkerThread(&ConnectContext
);
209 StartWorkerThread(&ListenContext
);
210 StartWorkerThread(&ClientReadContext
);
211 StartWorkerThread(&ClientWriteContext
);
212 StartWorkerThread(&ServerReadContext
);
213 StartWorkerThread(&ServerWriteContext
);
215 DefaultTimeout
.QuadPart
= -50 * 1000 * 10;
217 /* Server should start out listening */
218 Status
= MakeServer(&ServerHandle
, PipePath
, ServerSynchronous
);
219 ok_eq_hex(Status
, STATUS_SUCCESS
);
220 CheckServer(ServerHandle
, FILE_PIPE_LISTENING_STATE
);
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
);
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
);
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
);
240 /** Server to client, write first, 1 byte */
241 WriteBuffer
[0] = 'A';
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);
251 /** Server to client, read first, 1 byte */
252 WriteBuffer
[0] = 'B';
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);
264 /** Client to server, write first, 1 byte */
265 WriteBuffer
[0] = 'C';
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);
275 /** Client to server, read first, 1 byte */
276 WriteBuffer
[0] = 'D';
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);
288 /** Server to client, write 0 bytes */
289 Okay
= CheckWritePipe(&ServerWriteContext
, ServerHandle
, (PVOID
)1, 0, 100);
290 CheckPipeContext(&ServerWriteContext
, STATUS_SUCCESS
, 0);
291 CheckServerQuota(ServerHandle
, 0, 0); CheckClientQuota(ClientHandle
, 0, 0);
293 /** Client to Server, write 0 bytes */
294 Okay
= CheckWritePipe(&ClientWriteContext
, ClientHandle
, (PVOID
)1, 0, 100);
295 CheckPipeContext(&ClientWriteContext
, STATUS_SUCCESS
, 0);
296 CheckClientQuota(ClientHandle
, 0, 0); CheckServerQuota(ServerHandle
, 0, 0);
298 /** Server to client, read 0 bytes blocks, write 0 bytes does not unblock, write 1 byte unblocks */
299 WriteBuffer
[0] = 'E';
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);
320 /** Client to server, read 0 bytes blocks, write 0 bytes does not unblock, write 1 byte unblocks */
321 WriteBuffer
[0] = 'F';
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);
342 /** Disconnect server with pending read on client */
343 WriteBuffer
[0] = 'G';
345 Okay
= CheckReadPipe(&ClientReadContext
, ClientHandle
, ReadBuffer
, 1, 100);
346 ok_bool_false(Okay
, "CheckReadPipe returned");
347 CheckServerQuota(ServerHandle
, 0, 1);
348 Status
= NpDisconnectPipe(ServerHandle
);
349 ok_eq_hex(Status
, STATUS_SUCCESS
);
350 Okay
= WaitForWork(&ClientReadContext
, 100);
351 CheckPipeContext(&ClientReadContext
, STATUS_PIPE_DISCONNECTED
, 0);
352 ok_eq_uint(ReadBuffer
[0], 'X');
354 /* Read from server when disconnected */
355 Okay
= CheckReadPipe(&ServerReadContext
, ServerHandle
, ReadBuffer
, 1, 100);
356 CheckPipeContext(&ServerReadContext
, STATUS_PIPE_DISCONNECTED
, 0);
358 /* Write to server when disconnected */
359 Okay
= CheckWritePipe(&ServerWriteContext
, ServerHandle
, WriteBuffer
, 1, 100);
360 CheckPipeContext(&ServerWriteContext
, STATUS_PIPE_DISCONNECTED
, 0);
362 /* Read from client when disconnected */
363 Okay
= CheckReadPipe(&ClientReadContext
, ClientHandle
, ReadBuffer
, 1, 100);
364 CheckPipeContext(&ClientReadContext
, STATUS_PIPE_DISCONNECTED
, 0);
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
);
370 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
385 /** Close server with pending read on client */
386 WriteBuffer
[0] = 'H';
388 Okay
= CheckReadPipe(&ClientReadContext
, ClientHandle
, ReadBuffer
, 1, 100);
389 ok_bool_false(Okay
, "CheckReadPipe returned");
390 Status
= ObCloseHandle(ServerHandle
, KernelMode
);
391 ok_eq_hex(Status
, STATUS_SUCCESS
);
392 Okay
= WaitForWork(&ClientReadContext
, 100);
393 CheckPipeContext(&ClientReadContext
, STATUS_PIPE_BROKEN
, 0);
394 ok_eq_uint(ReadBuffer
[0], 'X');
396 /* Read from client when closed */
397 Okay
= CheckReadPipe(&ClientReadContext
, ClientHandle
, ReadBuffer
, 1, 100);
398 CheckPipeContext(&ClientReadContext
, STATUS_PIPE_BROKEN
, 0);
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
);
404 ok_eq_hex(Status
, STATUS_SUCCESS
);
406 /* Restore the connection */
407 Status
= MakeServer(&ServerHandle
, PipePath
, ServerSynchronous
);
408 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
416 /** Close client with pending read on server */
417 WriteBuffer
[0] = 'I';
419 Okay
= CheckReadPipe(&ServerReadContext
, ServerHandle
, ReadBuffer
, 1, 100);
420 ok_bool_false(Okay
, "CheckReadPipe returned");
421 Status
= ObCloseHandle(ClientHandle
, KernelMode
);
422 ok_eq_hex(Status
, STATUS_SUCCESS
);
423 Okay
= WaitForWork(&ServerReadContext
, 100);
424 CheckPipeContext(&ServerReadContext
, STATUS_PIPE_BROKEN
, 0);
425 ok_eq_uint(ReadBuffer
[0], 'X');
427 /* Read from server when closed */
428 Okay
= CheckReadPipe(&ServerReadContext
, ServerHandle
, ReadBuffer
, 1, 100);
429 CheckPipeContext(&ServerReadContext
, STATUS_PIPE_BROKEN
, 0);
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
);
435 ok_eq_hex(Status
, STATUS_SUCCESS
);
437 /* Restore the connection */
438 Status
= MakeServer(&ServerHandle
, PipePath
, ServerSynchronous
);
439 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
447 /** Write to server and disconnect, then read from client */
448 WriteBuffer
[0] = 'J';
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
);
454 ok_eq_hex(Status
, STATUS_SUCCESS
);
455 NpQueryPipe(ClientHandle
, STATUS_PIPE_DISCONNECTED
);
456 CheckServer(ServerHandle
, FILE_PIPE_DISCONNECTED_STATE
);
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
);
463 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
478 /** Write to server and close, then read from client */
479 WriteBuffer
[0] = 'K';
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
);
485 ok_eq_hex(Status
, STATUS_SUCCESS
);
486 NpCheckClientPipe(ClientHandle
,
487 BYTE_STREAM
, QUEUE
, BYTE_STREAM
, DUPLEX
,
490 OUT_QUOTA
, OUT_QUOTA
,
491 FILE_PIPE_CLOSING_STATE
);
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
);
498 ok_eq_hex(Status
, STATUS_SUCCESS
);
500 /* Restore the connection */
501 Status
= MakeServer(&ServerHandle
, PipePath
, ServerSynchronous
);
502 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
511 /** Write to client and close, then read from server */
512 WriteBuffer
[0] = 'L';
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
);
518 ok_eq_hex(Status
, STATUS_SUCCESS
);
519 NpCheckServerPipe(ServerHandle
,
520 BYTE_STREAM
, QUEUE
, BYTE_STREAM
, DUPLEX
,
523 OUT_QUOTA
, OUT_QUOTA
,
524 FILE_PIPE_CLOSING_STATE
);
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
);
531 ok_eq_hex(Status
, STATUS_SUCCESS
);
533 /* Restore the connection */
534 Status
= MakeServer(&ServerHandle
, PipePath
, ServerSynchronous
);
535 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
543 /** Write to client and disconnect server, then read from server */
544 WriteBuffer
[0] = 'M';
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
);
550 ok_eq_hex(Status
, STATUS_SUCCESS
);
551 NpQueryPipe(ClientHandle
, STATUS_PIPE_DISCONNECTED
);
552 CheckServer(ServerHandle
, FILE_PIPE_DISCONNECTED_STATE
);
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
);
559 ok_eq_hex(Status
, STATUS_SUCCESS
);
561 Status
= ObCloseHandle(ServerHandle
, KernelMode
);
562 ok_eq_hex(Status
, STATUS_SUCCESS
);
564 FinishWorkerThread(&ServerWriteContext
);
565 FinishWorkerThread(&ServerReadContext
);
566 FinishWorkerThread(&ClientWriteContext
);
567 FinishWorkerThread(&ClientReadContext
);
568 FinishWorkerThread(&ListenContext
);
569 FinishWorkerThread(&ConnectContext
);
572 START_TEST(NpfsReadWrite
)
575 READ_WRITE_TEST_CONTEXT TestContext
;
577 TestContext
.PipePath
= DEVICE_NAMED_PIPE L
"\\KmtestNpfsReadWriteTestPipe";
579 TestContext
.ServerSynchronous
= TRUE
;
580 TestContext
.ClientSynchronous
= TRUE
;
581 Thread
= KmtStartThread(TestReadWrite
, &TestContext
);
582 KmtFinishThread(Thread
, NULL
);
584 TestContext
.ServerSynchronous
= FALSE
;
585 TestContext
.ClientSynchronous
= TRUE
;
586 Thread
= KmtStartThread(TestReadWrite
, &TestContext
);
587 KmtFinishThread(Thread
, NULL
);
589 TestContext
.ServerSynchronous
= TRUE
;
590 TestContext
.ClientSynchronous
= FALSE
;
591 Thread
= KmtStartThread(TestReadWrite
, &TestContext
);
592 KmtFinishThread(Thread
, NULL
);
594 TestContext
.ServerSynchronous
= FALSE
;
595 TestContext
.ClientSynchronous
= FALSE
;
596 Thread
= KmtStartThread(TestReadWrite
, &TestContext
);
597 KmtFinishThread(Thread
, NULL
);