ReactOS  0.4.15-dev-3440-g915569a
pnpstatemachineum.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft. All rights reserved.
4 
5 Module Name:
6 
7  PnpStateMachineUm.cpp
8 
9 Abstract:
10 
11  This module implements the PnP state machine for the driver framework.
12  This code was split out from FxPkgPnp.cpp.
13 
14 Author:
15 
16 
17 
18 
19 
20 Environment:
21 
22  User mode only
23 
24 Revision History:
25 
26 --*/
27 
28 #include "../pnppriv.hpp"
29 
30 extern "C" {
31 #if defined(EVENT_TRACING)
32 #include "PnpStateMachineUM.tmh"
33 #endif
34 }
35 
36 BOOLEAN
38  VOID
39  )
40 /*++
41 
42 Routine 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 
48 Arguments:
49  None
50 
51 Return 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 
84 BOOLEAN
86  __in KIRQL CurrentIrql,
87  __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread
88  )
89 /*++
90 Routine 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 
120 Arguments:
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 
128 Returns:
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 
146 NTSTATUS
148  VOID
149  )
150 /*++
151 Routine description:
152  If needed, creates a thread for processing power IRPs
153 
154 Arguments:
155  None
156 
157 Return 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 
167 NTSTATUS
169  VOID
170  )
171 {
172  //
173  // Update maximum interrupt thread count now that we know how many
174  // total interrupts we have.
175  //
177 }
178 
__inline CfxDevice * GetDevice(VOID)
Definition: fxpackage.hpp:46
HRESULT hr
Definition: shlfolder.c:183
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
NTSTATUS UpdateInterruptThreadpoolLimits(VOID)
Definition: fxdevice.hpp:1841
LONG NTSTATUS
Definition: precomp.h:26
IWudfDeviceStack * deviceStack
FxDevice * device
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
Definition: devices.h:37
_Must_inspect_result_ NTSTATUS PnpPrepareHardwareInternal(VOID)
unsigned char BOOLEAN
void restart(int argc, const char *argv[])
Definition: cmds.c:2115
_Must_inspect_result_ NTSTATUS CreatePowerThreadIfNeeded(VOID)
LONG HRESULT
Definition: typedefs.h:79
BOOLEAN ShouldProcessPnpEventOnDifferentThread(__in KIRQL CurrentIrql, __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread)
#define _Must_inspect_result_
Definition: ms_sal.h:558
BOOLEAN PnpIncrementRestartCountLogic(_In_ HANDLE RestartKey, _In_ BOOLEAN CreatedNewKey)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BOOLEAN PnpCheckAndIncrementRestartCount(VOID)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define __in
Definition: dbghelp.h:35