ReactOS 0.4.15-dev-8434-g155a7c7
pnpstatemachineum.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft. All rights reserved.
4
5Module Name:
6
7 PnpStateMachineUm.cpp
8
9Abstract:
10
11 This module implements the PnP state machine for the driver framework.
12 This code was split out from FxPkgPnp.cpp.
13
14Author:
15
16
17
18
19
20Environment:
21
22 User mode only
23
24Revision History:
25
26--*/
27
28#include "../pnppriv.hpp"
29
30extern "C" {
31#if defined(EVENT_TRACING)
32#include "PnpStateMachineUM.tmh"
33#endif
34}
35
38 VOID
39 )
40/*++
41
42Routine Description:
43 This is a mode-dependent wrapper for PnpIncrementRestartCountLogic,
44 which determines if this device should ask the bus driver to
45 reenumerate the device. Please refer to PnpIncrementRestartCountLogic's
46 comment block for more information.
47
48Arguments:
49 None
50
51Return Value:
52 TRUE if a restart should be requested.
53
54--*/
55{
56 HRESULT hr;
59 IWudfDeviceStack* deviceStack;
60 UMINT::WDF_PROPERTY_STORE_ROOT propertyStore;
61 UMINT::WDF_PROPERTY_STORE_DISPOSITION disposition;
62
63 device = GetDevice();
64 deviceStack = device->GetDeviceStack();
65
66 propertyStore.LengthCb = sizeof(UMINT::WDF_PROPERTY_STORE_ROOT);
67 propertyStore.RootClass = UMINT::WdfPropertyStoreRootClassHardwareKey;
68 propertyStore.Qualifier.HardwareKey.ServiceName = L"WudfDiagnostics";
69
70 hr = deviceStack->CreateRegistryEntry(&propertyStore,
71 UMINT::WdfPropertyStoreCreateVolatile,
73 L"Restart",
74 (HKEY*)&restart.m_Key,
75 &disposition);
76 if (FAILED(hr)) {
77 return FALSE;
78 }
79
81 disposition == UMINT::CreatedNewStore);
82}
83
86 __in KIRQL CurrentIrql,
87 __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread
88 )
89/*++
90Routine Description:
91
92 This function returns whether the PnP state machine should process the
93 current event on the same thread or on a different one.
94
95 This function has been added to work around a bug in the state machines.
96 The idle state machine always calls PnpProcessEvent with the idle state
97 machine lock held. Some events sent by the idle state machine can cause the
98 Pnp state machine to invoke FxPowerIdleMachine::IoDecrement().
99 FxPowerIdleMachine::IoDecrement() will try to acquire the idle state
100 machine lock, which is already being held, so it will result in a recursive
101 acquire of the idle state machine lock.
102
103 The above bug only affects UMDF, but not KMDF. In KMDF, the idle state
104 machine lock is a spinlock. When PnpProcessEvent is called, it is called
105 with the spinlock held and hence at dispatch level. Note that if called at
106 a non-passive IRQL, PnpProcessEvent will always queue a work item to
107 process the event at passive IRQL later. Queuing a work item forces
108 processing to happen on a different thread and hence we don't attempt to
109 recursively acquire the spinlock. On the other hand, with UMDF we are
110 always at passive IRQL and hence we process the event on the same thread
111 and run into the recursive acquire problem.
112
113
114
115
116
117
118
119
120Arguments:
121
122 CurrentIrql - The current IRQL
123
124 CallerSpecifiedProcessingOnDifferentThread - Whether or not caller of
125 PnpProcessEvent specified that the event be processed on a different
126 thread.
127
128Returns:
129 TRUE if the PnP state machine should process the event on a different
130 thread.
131
132 FALSE if the PnP state machine should process the event on the same thread
133
134--*/
135{
136 //
137 // For UMDF, we ignore the IRQL and just do what the caller of
138 // PnpProcessEvent wants.
139 //
140 UNREFERENCED_PARAMETER(CurrentIrql);
141
142 return CallerSpecifiedProcessingOnDifferentThread;
143}
144
148 VOID
149 )
150/*++
151Routine description:
152 If needed, creates a thread for processing power IRPs
153
154Arguments:
155 None
156
157Return value:
158 An NTSTATUS code indicating success or failure of this function
159--*/
160{
161 //
162 // For UMDF, we never need a power thread, so just return success.
163 //
164 return STATUS_SUCCESS;
165}
166
169 VOID
170 )
171{
172 //
173 // Update maximum interrupt thread count now that we know how many
174 // total interrupts we have.
175 //
176 return GetDevice()->UpdateInterruptThreadpoolLimits();
177}
178
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
void restart(int argc, const char *argv[])
Definition: cmds.c:2115
BOOLEAN ShouldProcessPnpEventOnDifferentThread(__in KIRQL CurrentIrql, __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread)
BOOLEAN PnpCheckAndIncrementRestartCount(VOID)
_Must_inspect_result_ NTSTATUS CreatePowerThreadIfNeeded(VOID)
_Must_inspect_result_ NTSTATUS PnpPrepareHardwareInternal(VOID)
BOOLEAN PnpIncrementRestartCountLogic(_In_ HANDLE RestartKey, _In_ BOOLEAN CreatedNewKey)
#define __in
Definition: dbghelp.h:35
#define FALSE
Definition: types.h:117
UCHAR KIRQL
Definition: env_spec_w32.h:591
return pList GetDevice()
IWudfDeviceStack * deviceStack
#define FAILED(hr)
Definition: intsafe.h:51
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
HRESULT hr
Definition: shlfolder.c:183
Definition: devices.h:37