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
;
107 DefaultTimeout
.QuadPart
= -50 * 1000 * 10;
109 return NpCreatePipeEx(ServerHandle
,
118 SYNCHRONIZE
| GENERIC_READ
| GENERIC_WRITE
,
120 FILE_SYNCHRONOUS_IO_NONALERT
,
126 OUT PHANDLE ClientHandle
,
128 IN ACCESS_MASK DesiredAccess
,
129 IN ULONG ShareAccess
,
130 IN ULONG Disposition
,
131 IN ULONG CreateOptions
)
133 UNICODE_STRING ObjectName
;
134 OBJECT_ATTRIBUTES ObjectAttributes
;
136 IO_STATUS_BLOCK IoStatusBlock
;
138 RtlInitUnicodeString(&ObjectName
, PipePath
);
139 InitializeObjectAttributes(&ObjectAttributes
,
141 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
145 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
146 Status
= IoCreateFile(ClientHandle
,
150 NULL
, /* AllocationSize */
151 0, /* FileAttributes */
160 if (NT_SUCCESS(Status
))
162 ok(Status
!= STATUS_PENDING
, "IoCreateFile returned pending\n");
163 ok_eq_hex(IoStatusBlock
.Status
, Status
);
164 ok_eq_ulongptr(IoStatusBlock
.Information
, FILE_OPENED
);
168 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
169 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
176 OUT PHANDLE ClientHandle
,
178 IN ULONG NamedPipeConfiguration
)
182 if (NamedPipeConfiguration
== FILE_PIPE_INBOUND
)
183 ShareAccess
= FILE_SHARE_WRITE
;
184 else if (NamedPipeConfiguration
== FILE_PIPE_OUTBOUND
)
185 ShareAccess
= FILE_SHARE_READ
;
186 else if (NamedPipeConfiguration
== FILE_PIPE_FULL_DUPLEX
)
187 ShareAccess
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
189 return NpOpenPipeEx(ClientHandle
,
191 SYNCHRONIZE
| GENERIC_READ
| GENERIC_WRITE
,
194 FILE_SYNCHRONOUS_IO_NONALERT
);
199 IN HANDLE ServerHandle
,
200 IN ULONG FsControlCode
,
201 IN PVOID InputBuffer
,
202 IN ULONG InputBufferLength
)
205 IO_STATUS_BLOCK IoStatusBlock
;
207 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
208 Status
= ZwFsControlFile(ServerHandle
,
218 if (Status
== STATUS_PENDING
)
220 Status
= ZwWaitForSingleObject(ServerHandle
,
223 ok_eq_hex(Status
, STATUS_SUCCESS
);
224 Status
= IoStatusBlock
.Status
;
226 if (NT_SUCCESS(Status
))
228 ok_eq_hex(IoStatusBlock
.Status
, Status
);
229 ok_eq_ulongptr(IoStatusBlock
.Information
, 0);
233 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
234 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
242 IN PLARGE_INTEGER Timeout
)
246 UNICODE_STRING RootDirectoryName
= RTL_CONSTANT_STRING(DEVICE_NAMED_PIPE
);
247 OBJECT_ATTRIBUTES ObjectAttributes
;
248 IO_STATUS_BLOCK IoStatusBlock
;
249 PFILE_PIPE_WAIT_FOR_BUFFER WaitForBuffer
;
253 InitializeObjectAttributes(&ObjectAttributes
,
255 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
259 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
260 Status
= IoCreateFile(&RootHandle
,
261 FILE_READ_ATTRIBUTES
| SYNCHRONIZE
,
266 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
268 FILE_SYNCHRONOUS_IO_NONALERT
,
274 if (!NT_SUCCESS(Status
))
276 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
277 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
280 ok(Status
!= STATUS_PENDING
, "IoCreateFile returned pending\n");
281 ok_eq_hex(IoStatusBlock
.Status
, Status
);
282 ok_eq_ulongptr(IoStatusBlock
.Information
, FILE_OPENED
);
284 NameLength
= wcslen(PipeName
) * sizeof(WCHAR
);
285 BufferSize
= FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER
,
286 Name
[NameLength
/ sizeof(WCHAR
)]);
287 WaitForBuffer
= ExAllocatePoolWithTag(NonPagedPool
, BufferSize
, 'WPmK');
288 if (WaitForBuffer
== NULL
)
289 return STATUS_INSUFFICIENT_RESOURCES
;
293 WaitForBuffer
->Timeout
.QuadPart
= Timeout
->QuadPart
;
294 WaitForBuffer
->TimeoutSpecified
= TRUE
;
298 WaitForBuffer
->Timeout
.QuadPart
= 0;
299 WaitForBuffer
->TimeoutSpecified
= FALSE
;
301 WaitForBuffer
->NameLength
= NameLength
;
302 RtlCopyMemory(WaitForBuffer
->Name
, PipeName
, NameLength
);
303 Status
= NpControlPipe(RootHandle
,
307 ExFreePoolWithTag(WaitForBuffer
, 'WPmK');
313 IN HANDLE PipeHandle
,
316 OUT PULONG_PTR BytesRead
)
319 IO_STATUS_BLOCK IoStatusBlock
;
320 BOOLEAN PendingReturned
= FALSE
;
322 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
323 Status
= ZwReadFile(PipeHandle
,
332 if (Status
== STATUS_PENDING
)
334 Status
= ZwWaitForSingleObject(PipeHandle
,
337 ok_eq_hex(Status
, STATUS_SUCCESS
);
338 Status
= IoStatusBlock
.Status
;
339 PendingReturned
= TRUE
;
341 if (NT_SUCCESS(Status
))
343 ok_eq_hex(IoStatusBlock
.Status
, Status
);
344 *BytesRead
= IoStatusBlock
.Information
;
350 ok_eq_hex(IoStatusBlock
.Status
, Status
);
351 ok_eq_ulongptr(IoStatusBlock
.Information
, 0);
355 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
356 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
365 IN HANDLE PipeHandle
,
366 IN
const VOID
*Buffer
,
368 OUT PULONG_PTR BytesWritten
)
371 IO_STATUS_BLOCK IoStatusBlock
;
373 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
374 Status
= ZwWriteFile(PipeHandle
,
383 if (Status
== STATUS_PENDING
)
385 Status
= ZwWaitForSingleObject(PipeHandle
,
388 ok_eq_hex(Status
, STATUS_SUCCESS
);
389 Status
= IoStatusBlock
.Status
;
391 if (NT_SUCCESS(Status
))
393 ok_eq_hex(IoStatusBlock
.Status
, Status
);
394 *BytesWritten
= IoStatusBlock
.Information
;
398 ok_eq_hex(IoStatusBlock
.Status
, 0x55555555UL
);
399 ok_eq_ulongptr(IoStatusBlock
.Information
, 0x5555555555555555ULL
);
412 PUCHAR Array
= Buffer
;
415 for (i
= 0; i
< Size
; i
++)
416 if (Array
[i
] != Value
)
418 trace("Expected %x, found %x at offset %lu\n", Value
, Array
[i
], (ULONG
)i
);
424 #define ok_eq_print_(value, expected, spec, FileAndLine) \
425 KmtOk((value) == (expected), FileAndLine, #value " = " spec ", expected " spec "\n", value, expected)
426 #define ok_eq_ulong_(value, expected) ok_eq_print_(value, expected, "%lu", FileAndLine)
427 #define ok_eq_ulonglong_(value, expected) ok_eq_print_(value, expected, "%I64u", FileAndLine)
429 #define ok_eq_ulongptr_(value, expected) ok_eq_print_(value, (ULONG_PTR)(expected), "%lu", FileAndLine)
431 #define ok_eq_ulongptr_(value, expected) ok_eq_print_(value, (ULONG_PTR)(expected), "%I64u", FileAndLine)
433 #define ok_eq_hex_(value, expected) ok_eq_print_(value, expected, "0x%08lx", FileAndLine)
437 IN HANDLE ServerHandle
,
438 /* PipeInformation */
440 IN ULONG CompletionMode
,
441 /* PipeLocalInformation */
442 IN ULONG NamedPipeType
,
443 IN ULONG NamedPipeConfiguration
,
444 IN ULONG MaximumInstances
,
445 IN ULONG CurrentInstances
,
446 IN ULONG InboundQuota
,
447 IN ULONG ReadDataAvailable
,
448 IN ULONG OutboundQuota
,
449 IN ULONG WriteQuotaAvailable
,
450 IN ULONG NamedPipeState
,
451 /* PipeRemoteInformation */
453 IN PCSTR FileAndLine
)
456 IO_STATUS_BLOCK IoStatusBlock
;
457 FILE_PIPE_INFORMATION PipeInfo
;
458 FILE_PIPE_LOCAL_INFORMATION PipeLocalInfo
;
459 FILE_PIPE_REMOTE_INFORMATION PipeRemoteInfo
;
461 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
462 RtlFillMemory(&PipeInfo
, sizeof(PipeInfo
), 0x55);
463 Status
= ZwQueryInformationFile(ServerHandle
,
467 FilePipeInformation
);
468 ok_eq_hex_(Status
, STATUS_SUCCESS
);
469 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
470 ok_eq_ulongptr_(IoStatusBlock
.Information
, sizeof(PipeInfo
));
471 ok_eq_ulong_(PipeInfo
.ReadMode
, ReadMode
);
472 ok_eq_ulong_(PipeInfo
.CompletionMode
, CompletionMode
);
474 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
475 RtlFillMemory(&PipeLocalInfo
, sizeof(PipeLocalInfo
), 0x55);
476 Status
= ZwQueryInformationFile(ServerHandle
,
479 sizeof(PipeLocalInfo
),
480 FilePipeLocalInformation
);
481 ok_eq_hex_(Status
, STATUS_SUCCESS
);
482 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
483 ok_eq_ulongptr_(IoStatusBlock
.Information
, sizeof(PipeLocalInfo
));
484 ok_eq_ulong_(PipeLocalInfo
.NamedPipeType
, NamedPipeType
);
485 ok_eq_ulong_(PipeLocalInfo
.NamedPipeConfiguration
, NamedPipeConfiguration
);
486 ok_eq_ulong_(PipeLocalInfo
.MaximumInstances
, MaximumInstances
);
487 ok_eq_ulong_(PipeLocalInfo
.CurrentInstances
, CurrentInstances
);
488 ok_eq_ulong_(PipeLocalInfo
.InboundQuota
, InboundQuota
);
489 ok_eq_ulong_(PipeLocalInfo
.ReadDataAvailable
, ReadDataAvailable
);
490 ok_eq_ulong_(PipeLocalInfo
.OutboundQuota
, OutboundQuota
);
491 ok_eq_ulong_(PipeLocalInfo
.WriteQuotaAvailable
, WriteQuotaAvailable
);
492 ok_eq_ulong_(PipeLocalInfo
.NamedPipeState
, NamedPipeState
);
493 ok_eq_ulong_(PipeLocalInfo
.NamedPipeEnd
, (ULONG
)FILE_PIPE_SERVER_END
);
495 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
496 RtlFillMemory(&PipeRemoteInfo
, sizeof(PipeRemoteInfo
), 0x55);
497 Status
= ZwQueryInformationFile(ServerHandle
,
500 sizeof(PipeRemoteInfo
),
501 FilePipeInformation
);
502 ok_eq_hex_(Status
, STATUS_SUCCESS
);
503 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
504 ok_eq_ulongptr_(IoStatusBlock
.Information
, RTL_SIZEOF_THROUGH_FIELD(FILE_PIPE_REMOTE_INFORMATION
, CollectDataTime
));
505 ok_eq_ulonglong_(PipeRemoteInfo
.CollectDataTime
.QuadPart
, 0ULL);
506 ok_eq_ulong_(PipeRemoteInfo
.MaximumCollectionCount
, 0x55555555UL
);
511 IN HANDLE ClientHandle
,
512 /* PipeInformation */
514 IN ULONG CompletionMode
,
515 /* PipeLocalInformation */
516 IN ULONG NamedPipeType
,
517 IN ULONG NamedPipeConfiguration
,
518 IN ULONG MaximumInstances
,
519 IN ULONG CurrentInstances
,
520 IN ULONG InboundQuota
,
521 IN ULONG ReadDataAvailable
,
522 IN ULONG OutboundQuota
,
523 IN ULONG WriteQuotaAvailable
,
524 IN ULONG NamedPipeState
,
525 /* PipeRemoteInformation */
527 IN PCSTR FileAndLine
)
530 IO_STATUS_BLOCK IoStatusBlock
;
531 FILE_PIPE_INFORMATION PipeInfo
;
532 FILE_PIPE_LOCAL_INFORMATION PipeLocalInfo
;
533 FILE_PIPE_REMOTE_INFORMATION PipeRemoteInfo
;
535 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
536 RtlFillMemory(&PipeInfo
, sizeof(PipeInfo
), 0x55);
537 Status
= ZwQueryInformationFile(ClientHandle
,
541 FilePipeInformation
);
542 ok_eq_hex_(Status
, STATUS_SUCCESS
);
543 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
544 ok_eq_ulongptr_(IoStatusBlock
.Information
, sizeof(PipeInfo
));
545 ok_eq_ulong_(PipeInfo
.ReadMode
, ReadMode
);
546 ok_eq_ulong_(PipeInfo
.CompletionMode
, CompletionMode
);
548 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
549 RtlFillMemory(&PipeLocalInfo
, sizeof(PipeLocalInfo
), 0x55);
550 Status
= ZwQueryInformationFile(ClientHandle
,
553 sizeof(PipeLocalInfo
),
554 FilePipeLocalInformation
);
555 ok_eq_hex_(Status
, STATUS_SUCCESS
);
556 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
557 ok_eq_ulongptr_(IoStatusBlock
.Information
, sizeof(PipeLocalInfo
));
558 ok_eq_ulong_(PipeLocalInfo
.NamedPipeType
, NamedPipeType
);
559 ok_eq_ulong_(PipeLocalInfo
.NamedPipeConfiguration
, NamedPipeConfiguration
);
560 ok_eq_ulong_(PipeLocalInfo
.MaximumInstances
, MaximumInstances
);
561 ok_eq_ulong_(PipeLocalInfo
.CurrentInstances
, CurrentInstances
);
562 ok_eq_ulong_(PipeLocalInfo
.InboundQuota
, InboundQuota
);
563 ok_eq_ulong_(PipeLocalInfo
.ReadDataAvailable
, ReadDataAvailable
);
564 ok_eq_ulong_(PipeLocalInfo
.OutboundQuota
, OutboundQuota
);
565 ok_eq_ulong_(PipeLocalInfo
.WriteQuotaAvailable
, WriteQuotaAvailable
);
566 ok_eq_ulong_(PipeLocalInfo
.NamedPipeState
, NamedPipeState
);
567 ok_eq_ulong_(PipeLocalInfo
.NamedPipeEnd
, (ULONG
)FILE_PIPE_CLIENT_END
);
569 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
570 RtlFillMemory(&PipeRemoteInfo
, sizeof(PipeRemoteInfo
), 0x55);
571 Status
= ZwQueryInformationFile(ClientHandle
,
574 sizeof(PipeRemoteInfo
),
575 FilePipeInformation
);
576 ok_eq_hex_(Status
, STATUS_SUCCESS
);
577 ok_eq_hex_(IoStatusBlock
.Status
, STATUS_SUCCESS
);
578 ok_eq_ulongptr_(IoStatusBlock
.Information
, RTL_SIZEOF_THROUGH_FIELD(FILE_PIPE_REMOTE_INFORMATION
, CollectDataTime
));
579 ok_eq_ulonglong_(PipeRemoteInfo
.CollectDataTime
.QuadPart
, 0ULL);
580 ok_eq_ulong_(PipeRemoteInfo
.MaximumCollectionCount
, 0x55555555UL
);
585 IN HANDLE PipeHandle
,
586 IN NTSTATUS ExpectedStatus
,
587 IN PCSTR FileAndLine
)
590 IO_STATUS_BLOCK IoStatusBlock
;
591 FILE_PIPE_INFORMATION PipeInfo
;
592 FILE_PIPE_LOCAL_INFORMATION PipeLocalInfo
;
593 FILE_PIPE_REMOTE_INFORMATION PipeRemoteInfo
;
595 ASSERT(!NT_SUCCESS(ExpectedStatus
));
597 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
598 RtlFillMemory(&PipeInfo
, sizeof(PipeInfo
), 0x55);
599 Status
= ZwQueryInformationFile(PipeHandle
,
603 FilePipeInformation
);
604 ok_eq_hex_(Status
, ExpectedStatus
);
605 ok_bool_true(CheckBuffer(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55), "CheckBuffer returned");
606 ok_bool_true(CheckBuffer(&PipeInfo
, sizeof(PipeInfo
), 0x55), "CheckBuffer returned");
608 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
609 RtlFillMemory(&PipeLocalInfo
, sizeof(PipeLocalInfo
), 0x55);
610 Status
= ZwQueryInformationFile(PipeHandle
,
613 sizeof(PipeLocalInfo
),
614 FilePipeLocalInformation
);
615 ok_eq_hex_(Status
, ExpectedStatus
);
616 ok_bool_true(CheckBuffer(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55), "CheckBuffer returned");
617 ok_bool_true(CheckBuffer(&PipeLocalInfo
, sizeof(PipeLocalInfo
), 0x55), "CheckBuffer returned");
619 RtlFillMemory(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55);
620 RtlFillMemory(&PipeRemoteInfo
, sizeof(PipeRemoteInfo
), 0x55);
621 Status
= ZwQueryInformationFile(PipeHandle
,
624 sizeof(PipeRemoteInfo
),
625 FilePipeInformation
);
626 ok_eq_hex_(Status
, ExpectedStatus
);
627 ok_bool_true(CheckBuffer(&IoStatusBlock
, sizeof(IoStatusBlock
), 0x55), "CheckBuffer returned");
628 ok_bool_true(CheckBuffer(&PipeRemoteInfo
, sizeof(PipeRemoteInfo
), 0x55), "CheckBuffer returned");
631 static KSTART_ROUTINE PipeWorkerThread
;
636 IN PVOID ThreadContext
)
638 PTHREAD_CONTEXT Context
= ThreadContext
;
639 PVOID WaitEvents
[2] = { &Context
->ThreadDoneEvent
,
640 &Context
->StartWorkEvent
};
645 Status
= KeWaitForMultipleObjects(RTL_NUMBER_OF(WaitEvents
),
653 if (Status
== STATUS_WAIT_0
)
655 ASSERT(Status
== STATUS_WAIT_1
);
657 Context
->Work(Context
);
659 KeSetEvent(&Context
->WorkCompleteEvent
, IO_NO_INCREMENT
, TRUE
);
665 OUT PTHREAD_CONTEXT Context
)
667 KeInitializeEvent(&Context
->ThreadDoneEvent
, NotificationEvent
, FALSE
);
668 KeInitializeEvent(&Context
->StartWorkEvent
, SynchronizationEvent
, FALSE
);
669 KeInitializeEvent(&Context
->WorkCompleteEvent
, NotificationEvent
, TRUE
);
671 Context
->Thread
= KmtStartThread(PipeWorkerThread
, Context
);
676 IN PTHREAD_CONTEXT Context
)
678 KmtFinishThread(Context
->Thread
, &Context
->ThreadDoneEvent
);
683 IN PTHREAD_CONTEXT Context
,
684 IN ULONG MilliSeconds
)
686 LARGE_INTEGER Timeout
;
689 Timeout
.QuadPart
= -10 * 1000 * (LONGLONG
)MilliSeconds
;
690 Status
= KeWaitForSingleObject(&Context
->WorkCompleteEvent
,
695 ok(Status
== STATUS_SUCCESS
|| Status
== STATUS_TIMEOUT
, "Wait status %lx\n", Status
);
696 return Status
!= STATUS_TIMEOUT
;
701 IN PTHREAD_CONTEXT Context
,
702 IN ULONG MilliSeconds
)
706 Status
= KeWaitForSingleObject(&Context
->WorkCompleteEvent
,
711 ok_eq_hex(Status
, STATUS_SUCCESS
);
712 KeResetEvent(&Context
->WorkCompleteEvent
);
713 KeSetEvent(&Context
->StartWorkEvent
, IO_NO_INCREMENT
, TRUE
);
714 return WaitForWork(Context
, MilliSeconds
);
719 IN PKSTART_ROUTINE StartRoutine
,
720 IN PVOID StartContext OPTIONAL
)
723 OBJECT_ATTRIBUTES ObjectAttributes
;
725 PVOID ThreadObject
= NULL
;
727 InitializeObjectAttributes(&ObjectAttributes
,
732 ThreadHandle
= INVALID_HANDLE_VALUE
;
733 Status
= PsCreateSystemThread(&ThreadHandle
,
740 ok_eq_hex(Status
, STATUS_SUCCESS
);
741 if (!skip(NT_SUCCESS(Status
) && ThreadHandle
!= NULL
&& ThreadHandle
!= INVALID_HANDLE_VALUE
, "No thread\n"))
743 Status
= ObReferenceObjectByHandle(ThreadHandle
,
749 ok_eq_hex(Status
, STATUS_SUCCESS
);
750 ObCloseHandle(ThreadHandle
, KernelMode
);
757 IN PKTHREAD Thread OPTIONAL
,
758 IN PKEVENT Event OPTIONAL
)
762 if (skip(Thread
!= NULL
, "No thread\n"))
766 KeSetEvent(Event
, IO_NO_INCREMENT
, TRUE
);
767 Status
= KeWaitForSingleObject(Thread
,
772 ok_eq_hex(Status
, STATUS_SUCCESS
);
773 ObDereferenceObject(Thread
);