ReactOS  0.4.15-dev-2354-g9e947e2
vfdpnp.c
Go to the documentation of this file.
1 /*
2  vfdpnp.c
3 
4  Virtual Floppy Drive for Windows NT platform
5  Kernel mode driver: Plug & Play functions
6 
7  Copyright (C) 2003-2005 Ken Kato
8 */
9 
10 #ifndef VFD_PNP
11 /*
12  Not in working order for the time being
13  so DO NOT define VFD_PNP macro
14  unless you know exactly what you are doing...
15 */
16 // suppress empty compile unit warning
17 #ifdef _MSC_VER
18 #pragma warning (disable: 4206)
19 #pragma message ("Plug and play support feature is disabled.")
20 #endif
21 
22 #else // VFD_PNP
23 
24 #include "imports.h"
25 #include "vfddrv.h"
26 #include "vfddbg.h"
27 
28 static NTSTATUS
29 VfdReportDevice(
31 
32 #ifdef ALLOC_PRAGMA
33 #pragma alloc_text(PAGE, VfdPlugAndPlay)
34 #pragma alloc_text(PAGE, VfdPowerControl)
35 #pragma alloc_text(PAGE, VfdSystemControl)
36 #pragma alloc_text(PAGE, VfdAddDevice)
37 #pragma alloc_text(PAGE, VfdReportDevice)
38 #endif // ALLOC_PRAGMA
39 
40 #define REMLOCK_TAG 'LdfV' // "VfdL"
41 #define REMLOCK_MAXIMUM 1 // Max minutes system allows lock to be held
42 #define REMLOCK_HIGHWATER 10 // Max number of irps holding lock at one time
43 
44 #if DBG
45 static PCSTR StateTable[] ={
46  { "STOPPED" },
47  { "WORKING" },
48  { "PENDINGSTOP" },
49  { "PENDINGREMOVE" },
50  { "SURPRISEREMOVED" },
51  { "REMOVED" },
52  { "UNKNOWN" }
53 };
54 #endif // DBG
55 
56 //
57 // PnP I/O request dispatch
58 //
60 VfdPlugAndPlay(
62  IN PIRP Irp)
63 {
64  PIO_STACK_LOCATION io_stack;
67  BOOLEAN lockHeld = TRUE;
68 
69  //
70  // setup necessary pointers
71  //
72  io_stack = IoGetCurrentIrpStackLocation( Irp );
73  device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
74 
75  ASSERT(device_extension->DeviceState < VFD_MAX_STATE);
76 
77  VFDTRACE(VFDINFO, ("[VFD] VfdPlugAndPlay - IN. %ws %s Device State=%s\n",
78  device_extension->device_name.Buffer,
79  GetPnpIrpName(io_stack->MinorFunction),
80  StateTable[device_extension->DeviceState]));
81 
82  //
83  // Acquire remove lock
84  //
86 
87  if (!NT_SUCCESS(status)) {
88  VFDTRACE(0, ("Acquire RemoveLock failed - %s\n", NtStatusToStr(status)));
89 
90  Irp->IoStatus.Status = status;
91  Irp->IoStatus.Information = 0;
93  return status;
94  }
95 
96  //
97  // Process the PnP I/O request
98  //
99  switch (io_stack->MinorFunction) {
100  case IRP_MN_START_DEVICE: // 0x00
101  //
102  // Start the device
103  //
104  device_extension->DeviceState = VFD_WORKING;
106 
107  Irp->IoStatus.Status = status;
108  Irp->IoStatus.Information = 0;
110  break;
111 
112  case IRP_MN_QUERY_REMOVE_DEVICE: // 0x01
113  //
114  // Prepare device removal
115  //
116  device_extension->DeviceState = VFD_PENDINGREMOVE;
118 
119  Irp->IoStatus.Status = status;
120  Irp->IoStatus.Information = 0;
122  break;
123 
124  case IRP_MN_REMOVE_DEVICE: // 0x02
125  //
126  // Remove the device
127  //
129 
130  // complete the current request
131  Irp->IoStatus.Status = status;
132  Irp->IoStatus.Information = 0;
134 
135  //
136  // Set the device status to REMOVED and wait for other drivers
137  // to release the lock, then delete the device object
138  //
139  device_extension->DeviceState = VFD_REMOVED;
141  lockHeld = FALSE;
142 
143  VfdRemoveDevice(DeviceObject);
144  break;
145 
146  case IRP_MN_CANCEL_REMOVE_DEVICE: // 0x03
147  //
148  // Before sending the IRP down make sure we have received
149  // a IRP_MN_QUERY_REMOVE_DEVICE. We may get Cancel Remove
150  // without receiving a Query Remove earlier, if the
151  // driver on top fails a Query Remove and passes down the
152  // Cancel Remove.
153  //
154 
155  if (device_extension->DeviceState == VFD_PENDINGREMOVE) {
156  device_extension->DeviceState = VFD_WORKING;
157  }
158 
160  Irp->IoStatus.Status = status;
161  Irp->IoStatus.Information = 0;
163 
164  break;
165 
166  case IRP_MN_STOP_DEVICE: // 0x04
167  device_extension->DeviceState = VFD_STOPPED;
168 
170  Irp->IoStatus.Status = status;
171  Irp->IoStatus.Information = 0;
173  break;
174 
175  case IRP_MN_QUERY_STOP_DEVICE: // 0x05
176  device_extension->DeviceState = VFD_PENDINGSTOP;
177 
179  Irp->IoStatus.Status = status;
180  Irp->IoStatus.Information = 0;
182  break;
183 
184  case IRP_MN_CANCEL_STOP_DEVICE: // 0x06
185  //
186  // Before sending the IRP down make sure we have received
187  // a IRP_MN_QUERY_STOP_DEVICE. We may get Cancel Stop
188  // without receiving a Query Stop earlier, if the
189  // driver on top fails a Query Stop and passes down the
190  // Cancel Stop.
191  //
192 
193  if (device_extension->DeviceState == VFD_PENDINGSTOP ) {
194  device_extension->DeviceState = VFD_WORKING;
195  }
196 
198  Irp->IoStatus.Status = status;
199  Irp->IoStatus.Information = 0;
201  break;
202 
203  case IRP_MN_QUERY_DEVICE_RELATIONS: // 0x07
205  Irp->IoStatus.Information = 0;
206 
207  switch (io_stack->Parameters.QueryDeviceRelations.Type) {
208  case BusRelations:
209  VFDTRACE(VFDINFO, ("------- BusRelations Query\n"));
210  break;
211 
212  case EjectionRelations:
213  VFDTRACE(VFDINFO, ("------- EjectionRelations Query\n"));
214  break;
215 
216  case PowerRelations:
217  VFDTRACE(VFDINFO, ("------- PowerRelations Query\n"));
218  break;
219 
220  case RemovalRelations:
221  VFDTRACE(VFDINFO, ("------- RemovalRelations Query\n"));
222  break;
223 
225  VFDTRACE(VFDINFO, ("------- TargetDeviceRelation Query\n"));
226 
227  Irp->IoStatus.Information = (LONG)ExAllocatePoolWithTag(
229 
230  if (Irp->IoStatus.Information) {
231  PDEVICE_RELATIONS rel = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
232 
233  rel->Count = 1;
234  rel->Objects[0] = device_extension->device_object;
235 
237  }
238  else {
240  }
241  break;
242 
243  default:
244  VFDTRACE(VFDINFO, ("------- Unknown Query\n"));
245  break;
246  }
247  Irp->IoStatus.Status = status;
249 
250  break;
251 
252 // case IRP_MN_QUERY_INTERFACE: // 0x08
253 // case IRP_MN_QUERY_CAPABILITIES: // 0x09
254 // case IRP_MN_QUERY_RESOURCES: // 0x0A
255 // case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: // 0x0B
256 // case IRP_MN_QUERY_DEVICE_TEXT: // 0x0C
257 // case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: // 0x0D
258 // case IRP_MN_READ_CONFIG: // 0x0F
259 // case IRP_MN_WRITE_CONFIG: // 0x10
260 // case IRP_MN_EJECT: // 0x11
261 // case IRP_MN_SET_LOCK: // 0x12
262 // case IRP_MN_QUERY_ID: // 0x13
263 // case IRP_MN_QUERY_PNP_DEVICE_STATE: // 0x14
264 // case IRP_MN_QUERY_BUS_INFORMATION: // 0x15
265 // case IRP_MN_DEVICE_USAGE_NOTIFICATION: // 0x16
266 
267  case IRP_MN_SURPRISE_REMOVAL: // 0x17
268  device_extension->DeviceState = VFD_SURPRISEREMOVED;
269 
271  Irp->IoStatus.Status = status;
272  Irp->IoStatus.Information = 0;
274  break;
275 
276 // case IRP_MN_QUERY_LEGACY_BUS_INFORMATION: // 0x18
277 
278  default:
279  //
280  // unknown request -- simply pass it to the lower device
281  //
283  Irp->IoStatus.Status = status;
284  Irp->IoStatus.Information = 0;
286  break;
287  }
288 
289  //
290  // Device Extenion is gone if the current IRP is IRP_MN_REMOVE_DEVICE
291  //
292  if (lockHeld == TRUE) {
294  }
295 
296  VFDTRACE(VFDINFO, ("[VFD] VfdPlugAndPlay - %s\n", NtStatusToStr(status)));
297 
298  return status;
299 }
300 
301 //
302 // Power management I/O request dispatch
303 //
304 NTSTATUS
305 VfdPowerControl(
307  IN PIRP Irp)
308 {
309  PIO_STACK_LOCATION io_stack;
312 
313  io_stack = IoGetCurrentIrpStackLocation( Irp );
314  device_extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
315 
316  VFDTRACE(VFDINFO, ("[VFD] VfdPowerControl - IN. %ws %s Device State=%s\n",
317  device_extension->device_name.Buffer,
318  GetPnpIrpName(io_stack->MinorFunction),
319  StateTable[device_extension->DeviceState]));
320 
322 
323  //
324  // If the device has been removed, the driver should not pass
325  // the IRP down to the next lower driver.
326  //
327 
328  if (device_extension->DeviceState == VFD_REMOVED) {
330  }
331  else {
333  }
334 
335  Irp->IoStatus.Status = status;
336  Irp->IoStatus.Information = 0;
338 
339  VFDTRACE(VFDINFO, ("[VFD] VfdPowerControl - %s\n", NtStatusToStr(status)));
340 
341  return status;
342 }
343 
344 //
345 // WMI I/O request dispatch
346 //
347 NTSTATUS
348 VfdSystemControl(
350  IN PIRP Irp)
351 {
352  PIO_STACK_LOCATION io_stack;
355 
356  io_stack = IoGetCurrentIrpStackLocation(Irp);
357  device_extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
358 
359  VFDTRACE(VFDINFO, ("[VFD] VfdSystemControl - IN. %ws %s Device State=%s\n",
360  device_extension->device_name.Buffer,
361  GetPnpIrpName(io_stack->MinorFunction),
362  StateTable[device_extension->DeviceState]));
363 
365  Irp->IoStatus.Status = status;
366  Irp->IoStatus.Information = 0;
368 
369  VFDTRACE(VFDINFO, ("[VFD] VfdSystemControl - %s\n", NtStatusToStr(status)));
370 
371  return status;
372 }
373 
374 //
375 // PnP AddDevice function
376 //
377 NTSTATUS
378 VfdAddDevice(
381 {
382  PDEVICE_OBJECT device_object;
385 
386  VFDTRACE(VFDINFO, ("[VFD] VfdAddDevice - IN\n"));
387 
388  status = VfdCreateDevice(DriverObject, &device_object);
389 
390  if (NT_SUCCESS(status)) {
391 
392  device_object->Flags |= DO_POWER_PAGABLE;
393 
395  (PDEVICE_EXTENSION)device_object->DeviceExtension;
396 
397  // Device starts in Stopped state
398  device_extension->DeviceState = VFD_STOPPED;
399 
400  VFDTRACE(VFDINFO, ("[VFD] Initializing the remove lock\n"));
401 
403  &device_extension->RemoveLock,
404  REMLOCK_TAG,
405  REMLOCK_MAXIMUM,
406  REMLOCK_HIGHWATER);
407 
408  if (PhysicalDevice) {
409  device_extension->PhysicalDevice = PhysicalDevice;
410  }
411  else {
412  VfdReportDevice(device_extension);
413  }
414  VfdRegisterInterface(device_extension);
415  VfdMountMgrNotifyVolume(device_extension);
416  }
417 
418  return status;
419 }
420 
421 //
422 // Report a VFD device to the PnP manager
423 //
424 NTSTATUS
425 VfdReportDevice(
427 {
429  CM_RESOURCE_LIST list = {0};
430  PCM_FULL_RESOURCE_DESCRIPTOR full = &(list.List[0]);
433 
434  list.Count = 1;
435 
436  full->InterfaceType = Internal;
437  full->BusNumber = device_extension->device_number;
438 
439  part->Version = 1;
440  part->Revision = 1;
441  part->Count = 1;
442 
444  desc->ShareDisposition = CmResourceShareShared;
445  desc->Flags = 0;
446 
447  VFDTRACE(VFDINFO,("[VFD] Reporting device %lu to the PnP manager\n",
448  device_extension->device_number));
449 
451  device_extension->device_object->DriverObject, // IN PDRIVER_OBJECT DriverObject,
452  Internal, // IN INTERFACE_TYPE LegacyBusType,
453  (ULONG)-1, // IN ULONG BusNumber,
454  (ULONG)-1, // IN ULONG SlotNumber,
455  &list, // IN PCM_RESOURCE_LIST ResourceList,
456  NULL, // IN PIO_RESOURCE_REQUIREMENTS_LIST OPTIONAL,
457  TRUE, // IN BOOLEAN ResourceAssigned,
458  &(device_extension->PhysicalDevice) // IN OUT PDEVICE_OBJECT *DeviceObject
459  );
460 
461  if (!NT_SUCCESS(status)) {
462  VFDTRACE(0,
463  ("[VFD] IoReportDetectedDevice - %s\n",
464  NtStatusToStr(status)));
465  }
466 
468  device_extension->device_object,
469  device_extension->PhysicalDevice);
470 
471  return status;
472 }
473 
474 #endif // VFD_PNP
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define DO_POWER_PAGABLE
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
#define IN
Definition: typedefs.h:39
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TRUE
Definition: types.h:120
#define IoInitializeRemoveLock(Lock, AllocateTag, MaxLockedMinutes, HighWatermark)
Definition: iofuncs.h:2829
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
struct _device_extension device_extension
LONG NTSTATUS
Definition: precomp.h:26
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2760
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
NTSTATUS VfdCreateDevice(IN PDRIVER_OBJECT DriverObject, OUT PVOID Parameter)
Definition: vfddev.c:23
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define IRP_MN_QUERY_REMOVE_DEVICE
long LONG
Definition: pedump.c:60
static const WCHAR desc[]
Definition: protectdata.c:36
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define IoCompleteRequest
Definition: irp.c:1240
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IRP_MN_STOP_DEVICE
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IRP_MN_START_DEVICE
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
Definition: _list.h:228
NTSTATUS NTAPI IoReportDetectedDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ INTERFACE_TYPE LegacyBusType, _In_ ULONG BusNumber, _In_ ULONG SlotNumber, _In_opt_ PCM_RESOURCE_LIST ResourceList, _In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, _In_ BOOLEAN ResourceAssigned, _Inout_ PDEVICE_OBJECT *DeviceObject)
Definition: pnpreport.c:148
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define VFD_POOL_TAG
Definition: vfddrv.h:25
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:737
#define NULL
Definition: types.h:112
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2770
const char * PCSTR
Definition: typedefs.h:52
#define IRP_MN_CANCEL_STOP_DEVICE
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3127
static SERVICE_STATUS status
Definition: service.c:31
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
#define IoAcquireRemoveLock(RemoveLock, Tag)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PDEVICE_OBJECT PhysicalDevice
Definition: wdfdevice.h:2320
Definition: ps.c:97