ReactOS 0.4.16-dev-92-g0c2cdca
interruptobjectum.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 InterruptObjectUm.cpp
8
9Abstract:
10
11 This module implements a frameworks managed interrupt object
12
13Author:
14
15Environment:
16
17 User mode only
18
19Revision History:
20
21
22
23--*/
24
25#include "fxmin.hpp"
26#include "FxInterruptThreadpoolUm.hpp"
27
28extern "C" {
29#include "InterruptObjectUm.tmh"
30}
31
32#define STRSAFE_LIB
33#include <strsafe.h>
34
40 )
41{
42 IWudfDeviceStack *deviceStack;
43 HRESULT hr;
46 CM_SHARE_DISPOSITION shareVector;
47
49
51
52 switch (m_ShareVector) {
53 case WdfTrue:
54 //
55 // Override the bus driver's value, explicitly sharing this interrupt.
56 //
57 shareVector = CmResourceShareShared;
58 break;
59
60 case WdfFalse:
61 //
62 // Override the bus driver's value, explicitly claiming this interrupt
63 // as non-shared.
64 //
66 break;
67
68 case WdfUseDefault:
69 default:
70 //
71 // Leave the bus driver's value alone.
72 //
73 shareVector = CmResourceShareUndetermined;
74 break;
75 }
76
77 //
78 // Create a thread pool if not already created. An interrupt is created in
79 // one of the pnp callbacks (OnAddDevice, OnPrepareHarwdare etc) so there is
80 // no race in getting and setting the theradpool pointer.
81 //
83 if (pool == NULL) {
85 &pool);
86 if (FAILED(hr))
87 {
88 goto exit;
89 }
90
92 }
93
94 //
95 // create an instance of interruypt wait block
96 //
98 this,
101 if (FAILED(hr)) {
104 "Waitblock creation failed for CWdfInterrupt object"
105 " %!hresult!", hr);
106 goto exit;
107 }
108
109 //
110 // Send an IOCTL to redirector to create and initialize an interrupt object
111 //
113
114 hr = deviceStack->InitializeInterrupt((WUDF_INTERRUPT_CONTEXT) this,
116 shareVector,
118 );
119
120 if (SUCCEEDED(hr))
121 {
123 }
124 else
125 {
126 PUMDF_VERSION_DATA driverVersion = deviceStack->GetMinDriverVersion();
127
128 BOOL preserveCompat =
129 deviceStack->ShouldPreserveIrpCompletionStatusCompatibility();
130
131 status = CHostFxUtil::NtStatusFromHr(
132 hr,
133 driverVersion->MajorNumber,
134 driverVersion->MinorNumber,
135 preserveCompat
136 );
137 }
138
139 if (!NT_SUCCESS(status)) {
142 "failed to initialize interrupt "
143 "%!STATUS!", status);
144
145 goto exit;
146 }
147
148exit:
149
150 //
151 // Dispose will do cleanup. No need to cleanup here.
152 //
153
154 return status;
155}
156
159 VOID
160 )
161{
162 HRESULT hr;
164 IWudfDeviceStack2 *deviceStack;
166 BOOLEAN isRdConnectingOrConnected = FALSE;
167
170
171 //
172 // reset the interrupt event to non-signaled state to start with a
173 // clean slate.
174 //
176
177 //
178 // Open the queue and enqueue an interrupt event wait to the threadpool
179 // before connecting the interrupt in the reflector. This minimizes the
180 // processing delay for interrupts that fire as soon as they are connected,
181 // like GPIO button devices that have no means to explicitly enable and
182 // disable interrupts at the hardware level.
183 //
184 StartThreadpoolWaitQueue();
185
186 //
187 // Tell the PnP Manager to connect the interrupt. Send a message to
188 // redirector to do so. When ConnectInterrupt returns a failure code,
189 // we use isRdConnectingOrConnected to check if the failure was due
190 // to an already connected or currently connecting interrupt.
191 //
192 hr = deviceStack->ConnectInterrupt(m_RdInterruptContext,
193 &isRdConnectingOrConnected);
194 if (FAILED(hr))
195 {
196 if (isRdConnectingOrConnected) {
197 //
198 // The connect call failed because we asked the Reflector to connect
199 // an already connected or currently connecting interrupt. Perhaps the
200 // client made a redundant call to WdfInterruptEnable. In this case,
201 // we want to keep the threadpool active so that we continue to receive
202 // and acknowledge interrupts - otherwise RdIsrPassiveLevel may time out.
203 //
206 "Multiple connection attempts for !WDFINTERRUPT 0x%p",
207 GetHandle());
208
210 FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO),
211 CHECK("Multiple interrupt connection attempts", FALSE),
212 pFxDriverGlobals->Public.DriverName);
213 }
214 }
215 else {
216 //
217 // Connecting the interrupt in the reflector failed, which means
218 // that IoConnectInterruptEx either failed or was not called at all.
219 // All we need to do in this case is revert the actions done by
220 // StartThreadpoolWaitQueue above, which are closing the queue
221 // and removing the enqueued interrupt event wait.
222 //
223 StopAndFlushThreadpoolWaitQueue();
224 }
225
226 PUMDF_VERSION_DATA driverVersion = deviceStack->GetMinDriverVersion();
227 BOOL preserveCompat =
228 deviceStack->ShouldPreserveIrpCompletionStatusCompatibility();
229
230 status = CHostFxUtil::NtStatusFromHr(
231 hr,
232 driverVersion->MajorNumber,
233 driverVersion->MinorNumber,
234 preserveCompat
235 );
236
239 "Connect message to reflector returned failure "
240 "%!hresult!", hr);
241
242 return status;
243 }
244
246
247 return status;
248}
249
250VOID
252 VOID
253 )
254{
255 IWudfDeviceStack *deviceStack;
256 HRESULT hr;
257 InterruptControlType controlType;
258
259 //
260 // Tell the PnP Manager to disconnect the interrupt.
261 // Send a message to redirector to do so.
262 //
264
265 controlType = InterruptControlTypeDisconnect;
266 hr = deviceStack->ControlInterrupt(m_RdInterruptContext, controlType);
267 if (FAILED(hr))
268 {
271 "Disconnect message to reflector returned failure "
272 "%!hresult!", hr);
273
274 FX_VERIFY_WITH_NAME(INTERNAL, TRAPMSG("Disconnect message to reflector returned failure. "),
275 GetDriverGlobals()->Public.DriverName);
276 }
277
278 //
279 // Now that interrupt has been disconnected, flush the threadpool. Note that
280 // we need to do this after disconnect because if we did it before disconnect,
281 // we might drop any spurious interrupts that were generated after
282 // the driver disabled interrupt generation in its Disable callback,
283 // and after the DPCs were flushed. Fx can't drop spurious interrupt
284 // because if the interrupt is level-triggered then refelctor would be waiting
285 // for acknowledgement. The fact that disconnect command to reflector has
286 // returned to fx guarantees that there are no more interrupts pending in
287 // reflector.
288 //
289 StopAndFlushThreadpoolWaitQueue();
290
291 //
292 // There might still be WorkItemForIsr running as a result of
293 // the handling of spurious interrupt by driver, so we need to flush the
294 // workitem as well.
295 //
297
298 return;
299}
300
301VOID
306 )
307{
308 IWudfDeviceStack *deviceStack;
309 HRESULT hr;
310
312
313 //
314 // Tell reflector to set the policy of interrupt.
315 //
316 hr = deviceStack->SetInterruptPolicy(m_RdInterruptContext,
317 Policy,
318 Priority,
320 if (FAILED(hr))
321 {
324 "SetPolicy message to reflector returned failure "
325 "%!hresult!", hr);
326 }
327
328 FX_VERIFY_WITH_NAME(INTERNAL, CHECK_HR(hr), GetDriverGlobals()->Public.DriverName);
329
330 return;
331}
332
333VOID
335 __inout PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor
336 )
337/*++
338
339Routine Description:
340
341 This function allows an interrupt object to change the
342 IoResourceRequirementsList that the PnP Manager sends during
343 IRP_MN_FILTER_RESOURCE_REQUIREMENTS. This function takes a single
344 IoResourceDescriptor and applies default or user specified policy.
345
346Arguments:
347
348 IoResourceDescriptor - Pointer to descriptor that matches this interrupt object
349
350Return Value:
351
352 VOID
353
354--*/
355{
356 UNREFERENCED_PARAMETER(IoResourceDescriptor);
357
358 ASSERTMSG("Not implemented for UMDF\n", FALSE);
359}
360
361VOID
363 VOID
364 )
365{
366 IWudfDeviceStack *deviceStack;
367 InterruptControlType controlType;
368 HRESULT hr;
369
370 if (m_RdInterruptContext == NULL) {
371 //
372 // Reflector hasn't yet created a partner interrupt object so nothing
373 // to do.
374 //
375 return;
376 }
377
378 //
379 // Send a message to redirector to reset interrupt info.
380 //
382
383 controlType = InterruptControlTypeResetInterruptInfo;
384 hr = deviceStack->ControlInterrupt(m_RdInterruptContext, controlType);
385 if (FAILED(hr))
386 {
389 "ResetInterruptInfo message to reflector returned failure "
390 "%!hresult!", hr);
391 }
392
393 FX_VERIFY_WITH_NAME(INTERNAL, CHECK_HR(hr), GetDriverGlobals()->Public.DriverName);
394
395 return;
396}
397
398VOID
400 VOID
401 )
402{
403 IWudfDeviceStack *deviceStack;
404 InterruptControlType controlType;
405 HRESULT hr;
406
407 if (m_RdInterruptContext == NULL) {
408 //
409 // Reflector hasn't yet created a partner interrupt object so nothing
410 // to do.
411 //
412 return;
413 }
414
415 //
416 // Send a message to redirector to revoke interrupt resources.
417 //
419
420 controlType = InterruptControlTypeRevokeResources;
421 hr = deviceStack->ControlInterrupt(m_RdInterruptContext, controlType);
422 if (FAILED(hr))
423 {
426 "RevokeResources message to reflector returned failure "
427 "%!hresult!", hr);
428 }
429
430 FX_VERIFY_WITH_NAME(INTERNAL, CHECK_HR(hr), GetDriverGlobals()->Public.DriverName);
431
432 return;
433}
434
435VOID
437 VOID
438 )
439{
440 IWudfDeviceStack *deviceStack;
441 HRESULT hr;
442
443 //
444 // Send a message to redirector to flush DPCs.
445 //
447 hr = deviceStack->ControlInterrupt(m_RdInterruptContext,
448 InterruptControlTypeFlushQueuedDpcs);
449 if (FAILED(hr))
450 {
453 "FlushQueuedDpcs message to reflector returned failure "
454 "%!hresult!", hr);
455
456 FX_VERIFY_WITH_NAME(INTERNAL,
457 TRAPMSG("FlushQueuedDpcs message to reflector returned failure"),
458 GetDriverGlobals()->Public.DriverName);
459 }
460
461 return;
462}
463
464VOID
468 __in PWDF_INTERRUPT_INFO InterruptInfo
469 )
470{
471 IWudfDeviceStack *deviceStack;
472 HRESULT hr;
473
474 //
475 // level-triggered interrupt handling is supported only on win8 and newer.
476 //
477 if (IsLevelTriggered(CmDescTrans->Flags) &&
482 "Failed to assign interrupt resource to interrupt object"
483 "because interrupt resource is for level-triggered interrupt"
484 "which is not supported on this platform. See the docs for info on"
485 "supported platforms. %!hresult!\n", hr);
486
487 FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), TRAPMSG(
488 "Failed to assign interrupt resource to interrupt object"
489 "because interrupt resource is for level-triggered interrupt"
490 "which is not supported on this platform. See the docs for info on"
491 "supported platforms."),
492 GetDriverGlobals()->Public.DriverName);
493 }
494
495 //
496 // Sharing is only supported for level-triggered interrupts. We allow
497 // shared latched interrupts in order to accomodate incorrect device
498 // firmwares that mistakenly declare their exclusive resources as shared.
499 // Genuinely shared edge-triggered interrupts will cause a deadlock
500 // because of how the OS handles non-passive latched interrupts with
501 // multiple registered handlers. See RdInterrupt::AssignResources
502 // for details.
503 //
504 if (IsLevelTriggered(CmDescTrans->Flags) == FALSE &&
505 CmDescTrans->ShareDisposition != CmResourceShareDeviceExclusive) {
506
509 "The resource descriptor indicates that this is a shared "
510 "edge-triggered interrupt. UMDF only supports sharing of "
511 "level-triggered interrupts. Please check if your device "
512 "firmware mistakenly declares this resource as shared "
513 "instead of device exclusive. If the resource is in fact "
514 "shared, then UMDF does not support this device.\n");
515 }
516
517 //
518 // Tell the PnP Manager to assign resources to the interrupt.
519 // Send a message to redirector to do so.
520 //
522
523 hr = deviceStack->AssignInterruptResources(m_RdInterruptContext,
524 CmDescRaw,
525 CmDescTrans,
526 InterruptInfo,
528 if (FAILED(hr))
529 {
532 "AssignResources message to reflector returned failure "
533 "%!hresult!\n", hr);
534 }
535
536 FX_VERIFY_WITH_NAME(INTERNAL, CHECK_HR(hr),
537 GetDriverGlobals()->Public.DriverName);
538
539}
540
541VOID
542FxInterrupt::ThreadpoolWaitCallback(
543 VOID
544 )
545{
546 BOOLEAN claimed;
547
548 //
549 // ETW event for performance measurement
550 //
551 EventWriteEVENT_UMDF_FX_INTERRUPT_NOTIFICATION_RECEIVED(
553 );
554
555 //
556 // Invoke the ISR callback under interrupt lock.
557 //
558 if (IsWakeCapable()) {
559 //
560 // if it is a wake capable interrupt, we will hand it off
561 // to the state machine so that it can power up the device
562 // if required and then invoke the ISR callback
563 //
564 claimed = WakeInterruptIsr();
565 } else {
566 AcquireLock();
567 claimed = m_EvtInterruptIsr(GetHandle(),
569 );
570 ReleaseLock();
571 }
572
573 //
574 // Queue another wait. MSDN: You must re-register the event with the
575 // wait object before signaling it each time to trigger the wait callback.
576 //
577 if (m_CanQueue) {
578 QueueSingleWaitOnInterruptEvent();
579 }
580
581 //
582 // Return acknowledgement to reflector if it's handled at passive level
583 // by reflector.
584 //
586 IWudfDeviceStack *deviceStack;
587 HRESULT hr;
588
590
591 hr = deviceStack->AcknowledgeInterrupt(m_RdInterruptContext, claimed);
592
593 if (FAILED(hr)) {
596 "AcknowledgeInterrupt message to reflector returned "
597 "failure. Check UMDF log for failure reason. %!hresult!", hr);
598
599 FX_VERIFY_WITH_NAME(INTERNAL, TRAPMSG("AcknowledgeInterrupt message to "
600 "reflector returned failure. Check UMDF log for failure reason. "),
601 GetDriverGlobals()->Public.DriverName);
602 }
603 }
604
605 return;
606}
607
608VOID
609FxInterrupt::QueueSingleWaitOnInterruptEvent(
610 VOID
611 )
612{
614}
615
616VOID
617FxInterrupt::StartThreadpoolWaitQueue(
618 VOID
619 )
620{
622
623 QueueSingleWaitOnInterruptEvent();
624}
625
626VOID
627FxInterrupt::StopAndFlushThreadpoolWaitQueue(
628 VOID
629 )
630{
631 //
632 // We need to stop the threadpool wait queue and accomplish the following:
633 // 1) Prevent any new waits from being queued.
634 // 2) Removed any waits already queued.
635 // 3) Wait for interrupt isr callback to complete.
636 //
637
638 //
639 // Prevent any more enquing now that interrupt has been disconnected.
640 //
642
643 //
644 // wait for isr callback
645 //
647
648 //
649 // remove any waits already queued
650 //
652
653 //
654 // wait for callback. This additional wait for callback is needed to
655 // handle the follwoing race:
656 // - CanQueue is set to false in this thread
657 // - Callback is executing at statement after CanQueue check so it did not
658 // see false.
659 // - this thread waits for callback
660 // - callback thread queues a wait and returns
661 // - the wait earlier queued is satisfied and callback runs
662 // - this thread clears the queue (there is nothing to clear) but there is
663 // still a callback runnning and this thread needs to wait.
664 //
666}
667
668VOID
673 PTP_WAIT Wait,
674 TP_WAIT_RESULT WaitResult
675 )
676{
677 FxInterrupt* fxInterrupt = (FxInterrupt*) Parameter;
678
681 UNREFERENCED_PARAMETER(WaitResult);
682
683 fxInterrupt->ThreadpoolWaitCallback();
684
685 return;
686}
687
688VOID
690 VOID
691 )
692{
693 //
694 // flush the threadpool callbacks
695 //
696 StopAndFlushThreadpoolWaitQueue();
697
698 //
699 // Rundown the workitem.
700 //
701 if (m_SystemWorkItem != NULL) {
704 }
705
706 //
707 // If present, delete the default passive-lock.
708 //
709 if (m_DisposeWaitLock) {
714 }
715
716 //
717 // waitblock destructor will ensure event and waitblock cleanup.
718 //
719 if (m_InterruptWaitblock != NULL) {
722 }
723
724 //
725 // No need to explicitly delete the COM wrapper (CWdfInterrupt).
726 // The COM wrapper will get deleted in fxInterrupt's destroy callback when
727 // the object tree reference taken during creation will be released.
728 //
729}
730
733 VOID
734 )
735{
736 FX_VERIFY_WITH_NAME(INTERNAL, TRAPMSG("Not implemented"),
737 GetDriverGlobals()->Public.DriverName);
738 return FALSE;
739}
740
741VOID
743 VOID
744 )
745{
746 //
747 // For UMDF, we allow drivers to call WdfInterruptQueueDpcdForIsr, and
748 // internally we queue a workitem and invoke EvtInterruptDpc. Only
749 // one of the callbacks EvtInterruptDpc or EvtInterruptWorkitem is
750 // allowed.
751 //
754
756
757 //
758 // Call the drivers registered WorkItemForIsr event callback
759 //
760 if (m_CallbackLock != NULL) {
761 KIRQL irql = 0;
762
766 }
767 else {
769 }
771 }
772 else {
775 }
776 else {
778 }
779 }
780
781 return;
782}
783
789 )
790{
792 BOOLEAN isPassive;
793
795
797 isPassive = pParams->Interrupt->IsPassiveHandling();
798 FX_VERIFY(INTERNAL, CHECK("Must be Passive Interrupt", isPassive));
799
800 //
801 // The internal synchronize routine will call the routine under lock
802 //
804}
#define CHECK(hwndTarget)
static KSYNCHRONIZE_ROUTINE SynchronizeRoutine
Definition: IoInterrupt.c:30
unsigned char BOOLEAN
#define TODO
Definition: SAX2.c:44
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
LONG NTSTATUS
Definition: precomp.h:26
virtual void Lock(__out PKIRQL PreviousIrql)=0
virtual void Unlock(__in KIRQL PreviousIrql)=0
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
FxInterruptThreadpool * GetInterruptThreadpool(VOID)
Definition: fxdevice.hpp:1057
IWudfDeviceStack2 * GetDeviceStack2(VOID)
Definition: fxdeviceum.hpp:444
VOID SetInterruptThreadpool(_In_ FxInterruptThreadpool *Pool)
Definition: fxdevice.hpp:1049
IWudfDeviceStack * GetDeviceStack(VOID)
Definition: fxdeviceum.hpp:435
static HRESULT _CreateAndInit(_In_ PFX_DRIVER_GLOBALS DriverGlobals, _Out_ FxInterruptThreadpool **ppThreadpool)
static HRESULT _CreateAndInit(_In_ FxInterruptThreadpool *Threadpool, _In_ FxInterrupt *Interrupt, _In_ PTP_WAIT_CALLBACK WaitCallback, _Out_ FxInterruptWaitblock **Waitblock)
BOOLEAN m_DisposeWaitLock
Definition: fxinterrupt.hpp:98
VOID FlushQueuedDpcs(VOID)
BOOLEAN IsLevelTriggered(__in ULONG Flags)
FxCallbackLock * m_CallbackLock
Definition: fxinterrupt.hpp:93
VOID FlushQueuedWorkitem(VOID)
FxWaitLock * m_WaitLock
Definition: fxinterrupt.hpp:77
RD_INTERRUPT_CONTEXT m_RdInterruptContext
PFN_WDF_INTERRUPT_DPC m_EvtInterruptDpc
__inline BOOLEAN IsPassiveHandling(VOID)
VOID AcquireLock(VOID)
__inline BOOLEAN IsWakeCapable(VOID)
VOID ReleaseLock(VOID)
VOID SetPolicyInternal(__in WDF_INTERRUPT_POLICY Policy, __in WDF_INTERRUPT_PRIORITY Priority, __in PGROUP_AFFINITY TargetProcessorSet)
PFN_WDF_INTERRUPT_ISR m_EvtInterruptIsr
BOOLEAN WakeInterruptIsr(VOID)
BOOLEAN m_PassiveHandlingByRedirector
FxInterruptWaitblock * m_InterruptWaitblock
static MdInterruptServiceRoutineType _InterruptThunk
VOID DisconnectInternal(VOID)
WDF_TRI_STATE m_ShareVector
Definition: fxinterrupt.hpp:54
VOID FlushAndRundownInternal(VOID)
VOID AssignResourcesInternal(__in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescRaw, __in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescTrans, __in PWDF_INTERRUPT_INFO InterruptConfig)
_Must_inspect_result_ NTSTATUS ConnectInternal(VOID)
VOID WorkItemHandler(VOID)
BOOLEAN QueueDpcForIsr(VOID)
_Must_inspect_result_ NTSTATUS InitializeInternal(__in FxObject *Parent, __in PWDF_INTERRUPT_CONFIG Configuration)
VOID ResetInternal(VOID)
FxSystemWorkItem * m_SystemWorkItem
Definition: fxinterrupt.hpp:87
VOID FilterResourceRequirements(__inout PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor)
WDF_INTERRUPT_INFO m_InterruptInfo
PFN_WDF_INTERRUPT_WORKITEM m_EvtInterruptWorkItem
VOID RevokeResourcesInternal(VOID)
BOOLEAN m_CanQueue
virtual VOID DeleteObject(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define TRACINGPNP
Definition: dbgtrace.h:67
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define CALLBACK
Definition: compat.h:35
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
unsigned int BOOL
Definition: ntddk_ex.h:94
FX_VERIFY(INTERNAL, CHECK_NOT_NULL(LoaderInterface->pIWudfHost))
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
FX_TRACK_DRIVER(fxDriverGlobals)
IWudfDeviceStack * deviceStack
FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), CHECK(ERROR_STRING_HW_ACCESS_NOT_ALLOWED,(pDevice->IsDirectHardwareAccessAllowed()==TRUE)), DriverGlobals->DriverName)
_Must_inspect_result_ __inline BOOLEAN FxIsPassiveLevelInterruptSupported(VOID)
Definition: fxglobals.h:1081
BOOLEAN _SynchronizeExecution(__in MdInterrupt Interrupt, __in MdInterruptSynchronizeRoutine SynchronizeRoutine, __in PVOID SynchronizeContext)
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
KSYNCHRONIZE_ROUTINE * MdInterruptSynchronizeRoutine
Definition: mxgeneralkm.h:38
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define exit(n)
Definition: config.h:202
#define STATUS_SUCCESS
Definition: shellext.h:65
HRESULT hr
Definition: shlfolder.c:183
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
Definition: ps.c:97
#define GetHandle(h)
Definition: treelist.c:116
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY _In_ KAFFINITY TargetProcessorSet
Definition: wdfinterrupt.h:658
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG Configuration
Definition: wdfinterrupt.h:374
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
enum _WDF_INTERRUPT_PRIORITY WDF_INTERRUPT_PRIORITY
enum _WDF_INTERRUPT_POLICY WDF_INTERRUPT_POLICY
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY Policy
Definition: wdfinterrupt.h:653
@ WdfTrue
Definition: wdftypes.h:88
@ WdfUseDefault
Definition: wdftypes.h:89
@ WdfFalse
Definition: wdftypes.h:87
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_opt_ WDFWMIINSTANCE * Instance
Definition: wdfwmi.h:481
struct _TP_CALLBACK_INSTANCE * PTP_CALLBACK_INSTANCE
Definition: winnt_old.h:4453
enum _CM_SHARE_DISPOSITION CM_SHARE_DISPOSITION
@ CmResourceShareDeviceExclusive
Definition: cmtypes.h:241
@ CmResourceShareShared
Definition: cmtypes.h:243
@ CmResourceShareUndetermined
Definition: cmtypes.h:240
_In_ PKSYNCHRONIZE_ROUTINE _In_opt_ __drv_aliasesMem PVOID SynchronizeContext
Definition: kefuncs.h:525
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336