ReactOS 0.4.16-dev-117-g38f21f9
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#if !defined(__REACTOS__) || defined(_MSC_VER)
17// suppress empty compile unit warning
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
28static NTSTATUS
29VfdReportDevice(
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
45static 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//
60VfdPlugAndPlay(
62 IN PIRP Irp)
63{
64 PIO_STACK_LOCATION io_stack;
67 BOOLEAN lockHeld = TRUE;
68
69 //
70 // setup necessary pointers
71 //
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
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
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//
305VfdPowerControl(
307 IN PIRP Irp)
308{
309 PIO_STACK_LOCATION io_stack;
312
313 io_stack = IoGetCurrentIrpStackLocation( Irp );
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//
348VfdSystemControl(
350 IN PIRP Irp)
351{
352 PIO_STACK_LOCATION io_stack;
355
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//
378VfdAddDevice(
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//
425VfdReportDevice(
427{
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
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
struct _device_extension device_extension
Definition: list.h:37
_In_ PIRP Irp
Definition: csq.h:116
#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
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
@ Internal
Definition: hwresource.cpp:137
#define ASSERT(a)
Definition: mode.c:44
static const WCHAR desc[]
Definition: protectdata.c:36
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
long LONG
Definition: pedump.c:60
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
#define STATUS_SUCCESS
Definition: shellext.h:65
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
struct _IO_STACK_LOCATION::@3974::@3999 QueryDeviceRelations
union _IO_STACK_LOCATION::@1575 Parameters
Definition: ps.c:97
const char * PCSTR
Definition: typedefs.h:52
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
NTSTATUS VfdCreateDevice(IN PDRIVER_OBJECT DriverObject, OUT PVOID Parameter)
Definition: vfddev.c:23
#define VFD_POOL_TAG
Definition: vfddrv.h:25
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ PDEVICE_OBJECT PhysicalDevice
Definition: wdfdevice.h:2323
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
@ CmResourceShareShared
Definition: cmtypes.h:243
#define IoAcquireRemoveLock(RemoveLock, Tag)
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2774
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IoInitializeRemoveLock(Lock, AllocateTag, MaxLockedMinutes, HighWatermark)
Definition: iofuncs.h:2833
#define IRP_MN_CANCEL_STOP_DEVICE
@ EjectionRelations
Definition: iotypes.h:2153
@ RemovalRelations
Definition: iotypes.h:2155
@ BusRelations
Definition: iotypes.h:2152
@ TargetDeviceRelation
Definition: iotypes.h:2156
@ PowerRelations
Definition: iotypes.h:2154
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_REMOVE_DEVICE
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define DO_POWER_PAGABLE
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
#define IRP_MN_QUERY_REMOVE_DEVICE