2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Helper functions for NPFS tests
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
13 OUT PHANDLE ServerHandle
,
16 IN ULONG CompletionMode
,
17 IN ULONG NamedPipeType
,
19 IN ULONG MaximumInstances
,
20 IN ULONG InboundQuota
,
21 IN ULONG OutboundQuota
,
22 IN ACCESS_MASK DesiredAccess
,
24 IN ULONG CreateOptions
,
25 IN PLARGE_INTEGER DefaultTimeout OPTIONAL
)
27 UNICODE_STRING ObjectName
;
28 OBJECT_ATTRIBUTES ObjectAttributes
;
29 NAMED_PIPE_CREATE_PARAMETERS Params
;
30 IO_STATUS_BLOCK IoStatusBlock
;
33 RtlInitUnicodeString(&ObjectName
, PipePath
);
34 InitializeObjectAttributes(&ObjectAttributes
,
36 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
40 Params
.NamedPipeType
= NamedPipeType
;
41 Params
.ReadMode
= ReadMode
;
42 Params
.CompletionMode
= CompletionMode
;
43 Params
.MaximumInstances
= MaximumInstances
;
44 Params
.InboundQuota
= InboundQuota
;
45 Params
.OutboundQuota
= OutboundQuota
;
48 Params
.DefaultTimeout
.QuadPart
= DefaultTimeout
->QuadPart
;
49 Params
.TimeoutSpecified
= TRUE
;
53 Params
.DefaultTimeout
.QuadPart
= 0;
54 Params
.TimeoutSpecified
= FALSE
;
57 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
58 Status
= IoCreateFile(ServerHandle
,
62 NULL
, /* AllocationSize */
63 0, /* FileAttributes */
69 CreateFileTypeNamedPipe
,
72 if (NT_SUCCESS(Status
))
74 ok_eq_hex(IoStatusBlock
.Status
, Status
);
75 ok_eq_ulongptr(IoStatusBlock
.Information
, FILE_CREATED
);
79 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
80 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
87 OUT PHANDLE ServerHandle
,
92 ULONG NamedPipeConfiguration
,
93 ULONG MaximumInstances
,
98 LARGE_INTEGER DefaultTimeout
;
100 if (NamedPipeConfiguration
== FILE_PIPE_INBOUND
)
101 ShareAccess
= FILE_SHARE_WRITE
;
102 else if (NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
)
103 ShareAccess
= FILE_SHARE_READ
;
104 else if (NamedPipeConfiguration
== FILE_PIPE_FULL_DUPLEX
)
105 ShareAccess
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
108 ASSERTMSG("Invalid NamedPipeConfiguration parameter value!", FALSE
);
109 return STATUS_INVALID_PARAMETER_6
;
112 DefaultTimeout
.QuadPart
= -50 * 1000 * 10;
114 return NpCreatePipeEx(ServerHandle
,
123 SYNCHRONIZE
| GENERIC_READ
| GENERIC_WRITE
,
125 FILE_SYNCHRONOUS_IO_NONALERT
,
131 OUT PHANDLE ClientHandle
,
133 IN ACCESS_MASK DesiredAccess
,
134 IN ULONG ShareAccess
,
135 IN ULONG Disposition
,
136 IN ULONG CreateOptions
)
138 UNICODE_STRING ObjectName
;
139 OBJECT_ATTRIBUTES ObjectAttributes
;
141 IO_STATUS_BLOCK IoStatusBlock
;
143 RtlInitUnicodeString(&ObjectName
, PipePath
);
144 InitializeObjectAttributes(&ObjectAttributes
,
146 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
150 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
151 Status
= IoCreateFile(ClientHandle
,
155 NULL
, /* AllocationSize */
156 0, /* FileAttributes */
165 if (NT_SUCCESS(Status
))
167 ok(Status
!= STATUS_PENDING
, "IoCreateFile returned pending\n");
168 ok_eq_hex(IoStatusBlock
.Status
, Status
);
169 ok_eq_ulongptr(IoStatusBlock
.Information
, FILE_OPENED
);
173 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
174 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
181 OUT PHANDLE ClientHandle
,
183 IN ULONG NamedPipeConfiguration
)
187 if (NamedPipeConfiguration
== FILE_PIPE_INBOUND
)
188 ShareAccess
= FILE_SHARE_WRITE
;
189 else if (NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
)
190 ShareAccess
= FILE_SHARE_READ
;
191 else if (NamedPipeConfiguration
== FILE_PIPE_FULL_DUPLEX
)
192 ShareAccess
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
195 ASSERTMSG("Invalid NamedPipeConfiguration parameter value!", FALSE
);
196 return STATUS_INVALID_PARAMETER_3
;
199 return NpOpenPipeEx(ClientHandle
,
201 SYNCHRONIZE
| GENERIC_READ
| GENERIC_WRITE
,
204 FILE_SYNCHRONOUS_IO_NONALERT
);
209 IN HANDLE ServerHandle
,
210 IN ULONG FsControlCode
,
211 IN PVOID InputBuffer
,
212 IN ULONG InputBufferLength
)
215 IO_STATUS_BLOCK IoStatusBlock
;
217 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
218 Status
= ZwFsControlFile(ServerHandle
,
228 if (Status
== STATUS_PENDING
)
230 Status
= ZwWaitForSingleObject(ServerHandle
,
233 ok_eq_hex(Status
, STATUS_SUCCESS
);
234 Status
= IoStatusBlock
.Status
;
236 if (NT_SUCCESS(Status
))
238 ok_eq_hex(IoStatusBlock
.Status
, Status
);
239 ok_eq_ulongptr(IoStatusBlock
.Information
, 0);
243 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
244 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
252 IN PLARGE_INTEGER Timeout
)
256 UNICODE_STRING RootDirectoryName
= RTL_CONSTANT_STRING(DEVICE_NAMED_PIPE
);
257 OBJECT_ATTRIBUTES ObjectAttributes
;
258 IO_STATUS_BLOCK IoStatusBlock
;
259 PFILE_PIPE_WAIT_FOR_BUFFER WaitForBuffer
;
263 InitializeObjectAttributes(&ObjectAttributes
,
265 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
269 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
270 Status
= IoCreateFile(&RootHandle
,
271 FILE_READ_ATTRIBUTES
| SYNCHRONIZE
,
276 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
278 FILE_SYNCHRONOUS_IO_NONALERT
,
284 if (!NT_SUCCESS(Status
))
286 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
287 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
290 ok(Status
!= STATUS_PENDING
, "IoCreateFile returned pending\n");
291 ok_eq_hex(IoStatusBlock
.Status
, Status
);
292 ok_eq_ulongptr(IoStatusBlock
.Information
, FILE_OPENED
);
294 NameLength
= wcslen(PipeName
) * sizeof(WCHAR
);
295 BufferSize
= FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER
,
296 Name
[NameLength
/ sizeof(WCHAR
)]);
297 WaitForBuffer
= ExAllocatePoolWithTag(NonPagedPool
, BufferSize
, 'WPmK');
298 if (WaitForBuffer
== NULL
)
299 return STATUS_INSUFFICIENT_RESOURCES
;
303 WaitForBuffer
->Timeout
.QuadPart
= Timeout
->QuadPart
;
304 WaitForBuffer
->TimeoutSpecified
= TRUE
;
308 WaitForBuffer
->Timeout
.QuadPart
= 0;
309 WaitForBuffer
->TimeoutSpecified
= FALSE
;
311 WaitForBuffer
->NameLength
= NameLength
;
312 RtlCopyMemory(WaitForBuffer
->Name
, PipeName
, NameLength
);
313 Status
= NpControlPipe(RootHandle
,
317 ExFreePoolWithTag(WaitForBuffer
, 'WPmK');
323 IN HANDLE PipeHandle
,
326 OUT PULONG_PTR BytesRead
)
329 IO_STATUS_BLOCK IoStatusBlock
;
330 BOOLEAN PendingReturned
= FALSE
;
332 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
333 Status
= ZwReadFile(PipeHandle
,
342 if (Status
== STATUS_PENDING
)
344 Status
= ZwWaitForSingleObject(PipeHandle
,
347 ok_eq_hex(Status
, STATUS_SUCCESS
);
348 Status
= IoStatusBlock
.Status
;
349 PendingReturned
= TRUE
;
351 if (NT_SUCCESS(Status
))
353 ok_eq_hex(IoStatusBlock
.Status
, Status
);
354 *BytesRead
= IoStatusBlock
.Information
;
360 ok_eq_hex(IoStatusBlock
.Status
, Status
);
361 ok_eq_ulongptr(IoStatusBlock
.Information
, 0);
365 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
366 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
375 IN HANDLE PipeHandle
,
376 IN
const VOID
*Buffer
,
378 OUT PULONG_PTR BytesWritten
)
381 IO_STATUS_BLOCK IoStatusBlock
;
383 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
384 Status
= ZwWriteFile(PipeHandle
,
393 if (Status
== STATUS_PENDING
)
395 Status
= ZwWaitForSingleObject(PipeHandle
,
398 ok_eq_hex(Status
, STATUS_SUCCESS
);
399 Status
= IoStatusBlock
.Status
;
401 if (NT_SUCCESS(Status
))
403 ok_eq_hex(IoStatusBlock
.Status
, Status
);
404 *BytesWritten
= IoStatusBlock
.Information
;
408 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
409 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
422 PUCHAR Array
= Buffer
;
425 for (i
= 0; i
< Size
; i
++)
426 if (Array
[i
] != Value
)
428 trace("Expected %x, found %x at offset %lu\n", Value
, Array
[i
], (ULONG
)i
);
434 #define ok_eq_print_(value, expected, spec, FileAndLine) \
435 KmtOk((value) == (expected), FileAndLine, #value " = " spec ", expected " spec "\n", value, expected)
436 #define ok_eq_ulong_(value, expected) ok_eq_print_(value, expected, "%lu", FileAndLine)
437 #define ok_eq_ulonglong_(value, expected) ok_eq_print_(value, expected, "%I64u", FileAndLine)
439 #define ok_eq_ulongptr_(value, expected) ok_eq_print_(value, (ULONG_PTR)(expected), "%lu", FileAndLine)
441 #define ok_eq_ulongptr_(value, expected) ok_eq_print_(value, (ULONG_PTR)(expected), "%I64u", FileAndLine)
443 #define ok_eq_hex_(value, expected) ok_eq_print_(value, expected, "0x%08lx", FileAndLine)
447 IN HANDLE ServerHandle
,
448 /* PipeInformation */
450 IN ULONG CompletionMode
,
451 /* PipeLocalInformation */
452 IN ULONG NamedPipeType
,
453 IN ULONG NamedPipeConfiguration
,
454 IN ULONG MaximumInstances
,
455 IN ULONG CurrentInstances
,
456 IN ULONG InboundQuota
,
457 IN ULONG ReadDataAvailable
,
458 IN ULONG OutboundQuota
,
459 IN ULONG WriteQuotaAvailable
,
460 IN ULONG NamedPipeState
,
461 /* PipeRemoteInformation */
463 IN PCSTR FileAndLine
)
466 IO_STATUS_BLOCK IoStatusBlock
;
467 FILE_PIPE_INFORMATION PipeInfo
;
468 FILE_PIPE_LOCAL_INFORMATION PipeLocalInfo
;
469 FILE_PIPE_REMOTE_INFORMATION PipeRemoteInfo
;
471 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
472 RtlFillMemory(&PipeInfo
, sizeof(PipeInfo
), 0x55);
473 Status
= ZwQueryInformationFile(ServerHandle
,
477 FilePipeInformation
);
478 ok_eq_hex_(Status
, STATUS_SUCCESS
);
479 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
480 ok_eq_ulongptr_(IoStatusBlock
.Information
, sizeof(PipeInfo
));
481 ok_eq_ulong_(PipeInfo
.ReadMode
, ReadMode
);
482 ok_eq_ulong_(PipeInfo
.CompletionMode
, CompletionMode
);
484 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
485 RtlFillMemory(&PipeLocalInfo
, sizeof(PipeLocalInfo
), 0x55);
486 Status
= ZwQueryInformationFile(ServerHandle
,
489 sizeof(PipeLocalInfo
),
490 FilePipeLocalInformation
);
491 ok_eq_hex_(Status
, STATUS_SUCCESS
);
492 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
493 ok_eq_ulongptr_(IoStatusBlock
.Information
, sizeof(PipeLocalInfo
));
494 ok_eq_ulong_(PipeLocalInfo
.NamedPipeType
, NamedPipeType
);
495 ok_eq_ulong_(PipeLocalInfo
.NamedPipeConfiguration
, NamedPipeConfiguration
);
496 ok_eq_ulong_(PipeLocalInfo
.MaximumInstances
, MaximumInstances
);
497 ok_eq_ulong_(PipeLocalInfo
.CurrentInstances
, CurrentInstances
);
498 ok_eq_ulong_(PipeLocalInfo
.InboundQuota
, InboundQuota
);
499 ok_eq_ulong_(PipeLocalInfo
.ReadDataAvailable
, ReadDataAvailable
);
500 ok_eq_ulong_(PipeLocalInfo
.OutboundQuota
, OutboundQuota
);
501 ok_eq_ulong_(PipeLocalInfo
.WriteQuotaAvailable
, WriteQuotaAvailable
);
502 ok_eq_ulong_(PipeLocalInfo
.NamedPipeState
, NamedPipeState
);
503 ok_eq_ulong_(PipeLocalInfo
.NamedPipeEnd
, (ULONG
)FILE_PIPE_SERVER_END
);
505 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
506 RtlFillMemory(&PipeRemoteInfo
, sizeof(PipeRemoteInfo
), 0x55);
507 Status
= ZwQueryInformationFile(ServerHandle
,
510 sizeof(PipeRemoteInfo
),
511 FilePipeInformation
);
512 ok_eq_hex_(Status
, STATUS_SUCCESS
);
513 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
514 ok_eq_ulongptr_(IoStatusBlock
.Information
, RTL_SIZEOF_THROUGH_FIELD(FILE_PIPE_REMOTE_INFORMATION
, CollectDataTime
));
515 ok_eq_ulonglong_(PipeRemoteInfo
.CollectDataTime
.QuadPart
, 0ULL);
516 ok_eq_ulong_(PipeRemoteInfo
.MaximumCollectionCount
, 0x55555555UL
);
521 IN HANDLE ClientHandle
,
522 /* PipeInformation */
524 IN ULONG CompletionMode
,
525 /* PipeLocalInformation */
526 IN ULONG NamedPipeType
,
527 IN ULONG NamedPipeConfiguration
,
528 IN ULONG MaximumInstances
,
529 IN ULONG CurrentInstances
,
530 IN ULONG InboundQuota
,
531 IN ULONG ReadDataAvailable
,
532 IN ULONG OutboundQuota
,
533 IN ULONG WriteQuotaAvailable
,
534 IN ULONG NamedPipeState
,
535 /* PipeRemoteInformation */
537 IN PCSTR FileAndLine
)
540 IO_STATUS_BLOCK IoStatusBlock
;
541 FILE_PIPE_INFORMATION PipeInfo
;
542 FILE_PIPE_LOCAL_INFORMATION PipeLocalInfo
;
543 FILE_PIPE_REMOTE_INFORMATION PipeRemoteInfo
;
545 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
546 RtlFillMemory(&PipeInfo
, sizeof(PipeInfo
), 0x55);
547 Status
= ZwQueryInformationFile(ClientHandle
,
551 FilePipeInformation
);
552 ok_eq_hex_(Status
, STATUS_SUCCESS
);
553 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
554 ok_eq_ulongptr_(IoStatusBlock
.Information
, sizeof(PipeInfo
));
555 ok_eq_ulong_(PipeInfo
.ReadMode
, ReadMode
);
556 ok_eq_ulong_(PipeInfo
.CompletionMode
, CompletionMode
);
558 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
559 RtlFillMemory(&PipeLocalInfo
, sizeof(PipeLocalInfo
), 0x55);
560 Status
= ZwQueryInformationFile(ClientHandle
,
563 sizeof(PipeLocalInfo
),
564 FilePipeLocalInformation
);
565 ok_eq_hex_(Status
, STATUS_SUCCESS
);
566 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
567 ok_eq_ulongptr_(IoStatusBlock
.Information
, sizeof(PipeLocalInfo
));
568 ok_eq_ulong_(PipeLocalInfo
.NamedPipeType
, NamedPipeType
);
569 ok_eq_ulong_(PipeLocalInfo
.NamedPipeConfiguration
, NamedPipeConfiguration
);
570 ok_eq_ulong_(PipeLocalInfo
.MaximumInstances
, MaximumInstances
);
571 ok_eq_ulong_(PipeLocalInfo
.CurrentInstances
, CurrentInstances
);
572 ok_eq_ulong_(PipeLocalInfo
.InboundQuota
, InboundQuota
);
573 ok_eq_ulong_(PipeLocalInfo
.ReadDataAvailable
, ReadDataAvailable
);
574 ok_eq_ulong_(PipeLocalInfo
.OutboundQuota
, OutboundQuota
);
575 ok_eq_ulong_(PipeLocalInfo
.WriteQuotaAvailable
, WriteQuotaAvailable
);
576 ok_eq_ulong_(PipeLocalInfo
.NamedPipeState
, NamedPipeState
);
577 ok_eq_ulong_(PipeLocalInfo
.NamedPipeEnd
, (ULONG
)FILE_PIPE_CLIENT_END
);
579 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
580 RtlFillMemory(&PipeRemoteInfo
, sizeof(PipeRemoteInfo
), 0x55);
581 Status
= ZwQueryInformationFile(ClientHandle
,
584 sizeof(PipeRemoteInfo
),
585 FilePipeInformation
);
586 ok_eq_hex_(Status
, STATUS_SUCCESS
);
587 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
588 ok_eq_ulongptr_(IoStatusBlock
.Information
, RTL_SIZEOF_THROUGH_FIELD(FILE_PIPE_REMOTE_INFORMATION
, CollectDataTime
));
589 ok_eq_ulonglong_(PipeRemoteInfo
.CollectDataTime
.QuadPart
, 0ULL);
590 ok_eq_ulong_(PipeRemoteInfo
.MaximumCollectionCount
, 0x55555555UL
);
595 IN HANDLE PipeHandle
,
596 IN NTSTATUS ExpectedStatus
,
597 IN PCSTR FileAndLine
)
600 IO_STATUS_BLOCK IoStatusBlock
;
601 FILE_PIPE_INFORMATION PipeInfo
;
602 FILE_PIPE_LOCAL_INFORMATION PipeLocalInfo
;
603 FILE_PIPE_REMOTE_INFORMATION PipeRemoteInfo
;
605 ASSERT(!NT_SUCCESS(ExpectedStatus
));
607 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
608 RtlFillMemory(&PipeInfo
, sizeof(PipeInfo
), 0x55);
609 Status
= ZwQueryInformationFile(PipeHandle
,
613 FilePipeInformation
);
614 ok_eq_hex_(Status
, ExpectedStatus
);
615 ok_bool_true(CheckBuffer(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55), "CheckBuffer returned");
616 ok_bool_true(CheckBuffer(&PipeInfo
, sizeof(PipeInfo
), 0x55), "CheckBuffer returned");
618 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
619 RtlFillMemory(&PipeLocalInfo
, sizeof(PipeLocalInfo
), 0x55);
620 Status
= ZwQueryInformationFile(PipeHandle
,
623 sizeof(PipeLocalInfo
),
624 FilePipeLocalInformation
);
625 ok_eq_hex_(Status
, ExpectedStatus
);
626 ok_bool_true(CheckBuffer(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55), "CheckBuffer returned");
627 ok_bool_true(CheckBuffer(&PipeLocalInfo
, sizeof(PipeLocalInfo
), 0x55), "CheckBuffer returned");
629 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
630 RtlFillMemory(&PipeRemoteInfo
, sizeof(PipeRemoteInfo
), 0x55);
631 Status
= ZwQueryInformationFile(PipeHandle
,
634 sizeof(PipeRemoteInfo
),
635 FilePipeInformation
);
636 ok_eq_hex_(Status
, ExpectedStatus
);
637 ok_bool_true(CheckBuffer(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55), "CheckBuffer returned");
638 ok_bool_true(CheckBuffer(&PipeRemoteInfo
, sizeof(PipeRemoteInfo
), 0x55), "CheckBuffer returned");
641 static KSTART_ROUTINE PipeWorkerThread
;
646 IN PVOID ThreadContext
)
648 PTHREAD_CONTEXT Context
= ThreadContext
;
649 PVOID WaitEvents
[2] = { &Context
->ThreadDoneEvent
,
650 &Context
->StartWorkEvent
};
655 Status
= KeWaitForMultipleObjects(RTL_NUMBER_OF(WaitEvents
),
663 if (Status
== STATUS_WAIT_0
)
665 ASSERT(Status
== STATUS_WAIT_1
);
667 Context
->Work(Context
);
669 KeSetEvent(&Context
->WorkCompleteEvent
, IO_NO_INCREMENT
, TRUE
);
675 OUT PTHREAD_CONTEXT Context
)
677 KeInitializeEvent(&Context
->ThreadDoneEvent
, NotificationEvent
, FALSE
);
678 KeInitializeEvent(&Context
->StartWorkEvent
, SynchronizationEvent
, FALSE
);
679 KeInitializeEvent(&Context
->WorkCompleteEvent
, NotificationEvent
, TRUE
);
681 Context
->Thread
= KmtStartThread(PipeWorkerThread
, Context
);
686 IN PTHREAD_CONTEXT Context
)
688 KmtFinishThread(Context
->Thread
, &Context
->ThreadDoneEvent
);
693 IN PTHREAD_CONTEXT Context
,
694 IN ULONG MilliSeconds
)
696 LARGE_INTEGER Timeout
;
699 Timeout
.QuadPart
= -10 * 1000 * (LONGLONG
)MilliSeconds
;
700 Status
= KeWaitForSingleObject(&Context
->WorkCompleteEvent
,
705 ok(Status
== STATUS_SUCCESS
|| Status
== STATUS_TIMEOUT
, "Wait status %lx\n", Status
);
706 return Status
!= STATUS_TIMEOUT
;
711 IN PTHREAD_CONTEXT Context
,
712 IN ULONG MilliSeconds
)
716 Status
= KeWaitForSingleObject(&Context
->WorkCompleteEvent
,
721 ok_eq_hex(Status
, STATUS_SUCCESS
);
722 KeClearEvent(&Context
->WorkCompleteEvent
);
723 KeSetEvent(&Context
->StartWorkEvent
, IO_NO_INCREMENT
, TRUE
);
724 return WaitForWork(Context
, MilliSeconds
);