ReactOS 0.4.16-dev-257-g6aa11ac
vfddrv.c
Go to the documentation of this file.
1/*
2 vfddrv.c
3
4 Virtual Floppy Drive for Windows NT platform
5 Kernel mode driver: miscellaneous driver functions
6
7 Copyright (C) 2003-2005 Ken Kato
8*/
9
10#include "imports.h"
11#include "vfddrv.h"
12#include "vfddbg.h"
13
14//
15// driver reinitialize routine
16// -- create a drive letter for each device
17//
18#ifdef __cplusplus
19extern "C"
20#endif // __cplusplus
21static VOID
26 IN ULONG Count);
27
28//
29// specify code segment
30//
31#ifdef ALLOC_PRAGMA
32#pragma alloc_text(INIT, DriverEntry)
33#pragma alloc_text(PAGE, VfdReinitialize)
34#pragma alloc_text(PAGE, VfdUnloadDriver)
35#pragma alloc_text(PAGE, VfdCreateClose)
36#pragma alloc_text(PAGE, VfdCopyUnicode)
37#pragma alloc_text(PAGE, VfdFreeUnicode)
38#endif // ALLOC_PRAGMA
39
40//
41// operating system version
42//
43#ifndef __REACTOS__
44extern ULONG OsMajorVersion = 0;
45extern ULONG OsMinorVersion = 0;
46extern ULONG OsBuildNumber = 0;
47#else
51#endif
52
53//
54// Trace level flag
55//
56#if DBG
57#ifndef __REACTOS__
58extern ULONG TraceFlags = (ULONG)-1;
59#else
60ULONG TraceFlags = (ULONG)-1;
61#endif
62#endif // DBG
63
64//
65// Driver Entry routine
66//
72{
74 PVFD_DRIVER_EXTENSION driver_extension;
75 ULONG number_of_devices = VFD_DEFAULT_DEVICES;
76
78
79 // Get operating system version
80
82
83#ifdef VFD_PNP
84#define VFD_PNP_TAG "(Plug & Play version)"
85#else
86#define VFD_PNP_TAG
87#endif
88
89 VFDTRACE(0, ("[VFD] %s %s" VFD_PNP_TAG "\n",
91
92 VFDTRACE(0,
93 ("[VFD] Running on Windows NT %lu.%lu build %lu\n",
95
96 VFDTRACE(0,
97 ("[VFD] Build Target Environment: %d\n", VER_PRODUCTBUILD));
98
99#ifdef VFD_PNP
100
101 // Create device_extension for the driver object to store driver specific
102 // information. Device specific information are stored in device extension
103 // for each device object.
104
107 VFD_DRIVER_EXTENSION_ID,
108 sizeof(VFD_DRIVER_EXTENSION),
109 &driver_extension);
110
111 if(!NT_SUCCESS(status)) {
112 VFDTRACE(0, ("[VFD] IoAllocateDriverObjectExtension - %s\n",
113 GetStatusName(status)));
114 return status;
115 }
116
117#else // VFD_PNP
118
119 // Windows NT doesn't have the IoAllocateDriverObjectExtension
120 // function and I think there's little point in making a non-PnP
121 // driver incompatible with Windows NT.
122
125
126 if (!driver_extension) {
127 VFDTRACE(0, ("[VFD] failed to allocate the driver extension.\n"));
129 }
130
131#endif // VFD_PNP
132
133 RtlZeroMemory(driver_extension, sizeof(VFD_DRIVER_EXTENSION));
134
135 //
136 // Copy the registry path into the driver extension so we can use it later
137 //
138 if (VfdCopyUnicode(&(driver_extension->RegistryPath), RegistryPath)) {
139
140 //
141 // Read config values from the registry
142 //
144 ULONG default_devs = VFD_DEFAULT_DEVICES;
145#if DBG
146 ULONG default_trace = (ULONG)-1;
147#endif
148
149 RtlZeroMemory(params, sizeof(params));
150
151 VFDTRACE(0, ("[VFD] Registry Path: %ws\n",
152 driver_extension->RegistryPath.Buffer));
153
156 params[0].EntryContext = &number_of_devices;
157 params[0].DefaultType = REG_DWORD;
158 params[0].DefaultData = &default_devs;
159 params[0].DefaultLength = sizeof(ULONG);
160
161#if DBG
163 params[1].Name = VFD_REG_TRACE_FLAGS;
164 params[1].EntryContext = &TraceFlags;
165 params[1].DefaultType = REG_DWORD;
166 params[1].DefaultData = &default_trace;
167 params[1].DefaultLength = sizeof(ULONG);
168#endif // DBG
169
172 driver_extension->RegistryPath.Buffer,
173 params, NULL, NULL);
174
175 if (!NT_SUCCESS(status) ||
176 number_of_devices == 0 ||
177 number_of_devices > VFD_MAXIMUM_DEVICES) {
178 number_of_devices = VFD_DEFAULT_DEVICES;
179 }
180
181 VFDTRACE(0,("[VFD] NumberOfDevices = %lu\n", number_of_devices));
182 VFDTRACE(0,("[VFD] TraceFlags = 0x%08x\n", TraceFlags));
183 }
184 else {
185 VFDTRACE(0, ("[VFD] failed to allocate the registry path buffer.\n"));
186 // this error is not fatal
187 }
188
189 //
190 // Create VFD device objects
191 //
192 do {
193#ifdef VFD_PNP
195#else // VFD_PNP
196 status = VfdCreateDevice(DriverObject, driver_extension);
197#endif // VFD_PNP
198
199 if (!NT_SUCCESS(status)) {
200 break;
201 }
202 }
203 while (driver_extension->NumberOfDevices < number_of_devices);
204
205 if (!driver_extension->NumberOfDevices) {
206
207 // Failed to create even one device
208
209 VfdFreeUnicode(&(driver_extension->RegistryPath));
210
211 return status;
212 }
213
214 // Setup dispatch table
215
216 DriverObject->MajorFunction[IRP_MJ_CREATE] = VfdCreateClose;
217 DriverObject->MajorFunction[IRP_MJ_CLOSE] = VfdCreateClose;
218 DriverObject->MajorFunction[IRP_MJ_READ] = VfdReadWrite;
219 DriverObject->MajorFunction[IRP_MJ_WRITE] = VfdReadWrite;
221
222#ifdef VFD_PNP
223 DriverObject->MajorFunction[IRP_MJ_PNP] = VfdPlugAndPlay;
224 DriverObject->MajorFunction[IRP_MJ_POWER] = VfdPowerControl;
225 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = VfdSystemControl;
226 DriverObject->DriverExtension->AddDevice = VfdAddDevice;
227#endif // VFDPNP
228
229 DriverObject->DriverUnload = VfdUnloadDriver;
230
231 // Register the driver reinitialize routine to be called
232 // *after* the DriverEntry routine returns
233
236
237 VFDTRACE(VFDINFO,
238 ("[VFD] driver initialized with %lu devices.\n",
239 driver_extension->NumberOfDevices));
240
241 return STATUS_SUCCESS;
242}
243
244//
245// Driver unload routine
246// Cleans up the device objects and other resources
247//
248VOID
249NTAPI
252{
253 PDEVICE_OBJECT device_object;
254 PVFD_DRIVER_EXTENSION driver_extension;
255
256 VFDTRACE(VFDINFO, ("[VFD] VfdUnloadDriver - IN\n"));
257
258 device_object = DriverObject->DeviceObject;
259
260#ifdef VFD_PNP
261 driver_extension = IoGetDriverObjectExtension(
262 DriverObject, VFD_DRIVER_EXTENSION_ID);
263#else
264 if (device_object && device_object->DeviceExtension) {
265 driver_extension =
267 }
268 else {
269 driver_extension = NULL;
270 }
271#endif // VFD_PNP
272
273 //
274 // Delete all remaining device objects
275 //
276 while (device_object) {
277
278 PDEVICE_OBJECT next_device = device_object->NextDevice;
279
280 VfdDeleteDevice(device_object);
281
282 device_object = next_device;
283 }
284
285 //
286 // Release the driver extension and the registry path buffer
287 //
288 if (driver_extension) {
289
290 if (driver_extension->RegistryPath.Buffer) {
291 VFDTRACE(0, ("[VFD] Releasing the registry path buffer\n"));
292 ExFreePool(driver_extension->RegistryPath.Buffer);
293 }
294
295#ifndef VFD_PNP
296 // The system takes care of freeing the driver extension
297 // allocated with IoAllocateDriverObjectExtension in a PnP driver.
298 VFDTRACE(0, ("[VFD] Releasing the driver extension\n"));
299 ExFreePool(driver_extension);
300#endif // VFD_PNP
301 }
302
303 VFDTRACE(VFDINFO, ("[VFD] VfdUnloadDriver - OUT\n"));
304}
305
306//
307// IRP_MJ_CREATE and IRP_MJ_CLOSE handler
308// Really nothing to do here...
309//
311NTAPI
314 IN PIRP Irp)
315{
316#if DBG
317 if (DeviceObject && DeviceObject->DeviceExtension &&
318 ((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->DeviceName.Buffer) {
319
320 VFDTRACE(VFDINFO, ("[VFD] %-40s %ws\n",
322 ((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->DeviceName.Buffer));
323 }
324 else {
325 VFDTRACE(VFDINFO, ("[VFD] %-40s %p\n",
327 DeviceObject));
328 }
329#endif // DBG
330
331 Irp->IoStatus.Status = STATUS_SUCCESS;
332 Irp->IoStatus.Information = FILE_OPENED;
333
335
336 return STATUS_SUCCESS;
337}
338
339//
340// Called after the DriverEntry routine has returned
341// (Re)Create a persistent drive letter for each device
342//
343VOID
344NTAPI
348 IN ULONG Count)
349{
350 PDEVICE_OBJECT device_object;
352
355
356 VFDTRACE(VFDINFO, ("[VFD] VfdReinitialize - IN\n"));
357
358 device_object = DriverObject->DeviceObject;
359
360 while (device_object) {
362
363#ifdef VFD_MOUNT_MANAGER
364 if (OsMajorVersion >= 5) {
365 // Windows 2000 / XP
366 // Notify the mount manager of a VFD volume arrival
367 VfdMountMgrNotifyVolume(device_extension);
368
369 if (device_extension->DriveLetter) {
370 // Create a drive letter via the mount manager.
371 // The mount manager may have created a drive letter
372 // in response to the volume arrival notification above.
373 // In that case, the following call just fails.
374 VfdMountMgrMountPoint(
375 device_extension, device_extension->DriveLetter);
376 // ignoring the error for it is not fatal here
377 }
378 }
379 else
380#endif // VFD_MOUNT_MANAGER
381 {
382 // Windows NT style drive letter assignment
383 // Simply create a symbolic link here
384 if (device_extension->DriveLetter) {
386 device_extension, device_extension->DriveLetter);
387 // ignoring the error for it is not fatal here
388 }
389 }
390
391 device_object = device_object->NextDevice;
392 }
393
394 VFDTRACE(VFDINFO, ("[VFD] VfdReinitialize - OUT\n"));
395}
396
397//
398// Device dedicated thread routine
399// Dispatch read, write and device I/O request
400// redirected from the driver dispatch routines
401//
402VOID
403NTAPI
405 IN PVOID ThreadContext)
406{
407 PDEVICE_OBJECT device_object;
410 PIRP irp;
411 PIO_STACK_LOCATION io_stack;
412
413 ASSERT(ThreadContext != NULL);
414
415 device_object = (PDEVICE_OBJECT)ThreadContext;
416
418
420
421 for (;;) {
422 // wait for the request event to be signalled
424 &device_extension->RequestEvent,
425 Executive,
427 FALSE,
428 NULL);
429
430 // terminate request ?
431 if (device_extension->TerminateThread) {
432 VFDTRACE(0, ("[VFD] Exitting the I/O thread\n"));
434 }
435
436 // perform requested tasks
437
439 &device_extension->ListHead,
440 &device_extension->ListLock)) != NULL)
441 {
442 irp = CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry);
443
445
446 irp->IoStatus.Information = 0;
447
448 switch (io_stack->MajorFunction) {
449 case IRP_MJ_READ:
451 io_stack->Parameters.Read.Length,
452 &io_stack->Parameters.Read.ByteOffset);
453 break;
454
455 case IRP_MJ_WRITE:
457 io_stack->Parameters.Write.Length,
458 &io_stack->Parameters.Write.ByteOffset);
459 break;
460
463 io_stack->Parameters.DeviceIoControl.IoControlCode);
464 break;
465
466 default:
467 // This shouldn't happen...
468 VFDTRACE(0,
469 ("[VFD] %s passed to the I/O thread\n",
470 GetMajorFuncName(io_stack->MajorFunction)));
471
472 irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
473 }
474
476 (CCHAR)(NT_SUCCESS(irp->IoStatus.Status) ?
478
479#ifdef VFD_PNP
481#endif // VFD_PNP
482 } // while
483 } // for (;;)
484}
485
486//
487// Copy a UNICODE_STRING adding a trailing NULL characer
488//
492{
494
495 dst->MaximumLength =
496 (USHORT)(src->MaximumLength + sizeof(UNICODE_NULL));
497
499 PagedPool, dst->MaximumLength, VFD_POOL_TAG);
500
501 if(dst->Buffer) {
502 dst->Length = src->Length;
503 RtlZeroMemory(dst->Buffer, dst->MaximumLength);
504
505 if (src->Length) {
506 RtlCopyMemory(dst->Buffer, src->Buffer, src->Length);
507 }
508 }
509
510 return dst->Buffer;
511}
512
513//
514// Free a UNICODE_STRING buffer
515//
518{
519 if (str->Buffer) {
520 ExFreePool(str->Buffer);
521 }
523}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
struct _device_extension device_extension
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define PsGetVersion(a, b, c, d)
Definition: env_spec_w32.h:83
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
FxIrp * irp
GLenum src
Definition: glext.h:6340
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLenum dst
Definition: glext.h:6340
#define KeGetCurrentThread
Definition: hal.h:55
#define VER_PRODUCTBUILD
Definition: ieverp.h:6
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define LOW_REALTIME_PRIORITY
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define KernelMode
Definition: asm.h:34
int Count
Definition: noreturn.cpp:7
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define FILE_OPENED
Definition: nt_native.h:769
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1904
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1797
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1826
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1145
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
unsigned short USHORT
Definition: pedump.c:61
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID DeviceExtension
Definition: env_spec_w32.h:418
struct _IO_STACK_LOCATION::@1579::@1580 DeviceIoControl
union _IO_STACK_LOCATION::@1579 Parameters
struct _IO_STACK_LOCATION::@3978::@3983 Write
struct _IO_STACK_LOCATION::@3978::@3982 Read
Definition: typedefs.h:120
UNICODE_STRING RegistryPath
Definition: vfddrv.h:64
ULONG NumberOfDevices
Definition: vfddrv.h:65
Definition: tftpd.h:86
Definition: ps.c:97
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1319
uint16_t * PWSTR
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
char CCHAR
Definition: typedefs.h:51
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
VOID VfdDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: vfddev.c:296
NTSTATUS VfdCreateDevice(IN PDRIVER_OBJECT DriverObject, OUT PVOID Parameter)
Definition: vfddev.c:23
VOID NTAPI VfdDeviceThread(IN PVOID ThreadContext)
Definition: vfddrv.c:404
ULONG OsBuildNumber
VOID NTAPI VfdUnloadDriver(IN PDRIVER_OBJECT DriverObject)
Definition: vfddrv.c:250
VOID VfdFreeUnicode(PUNICODE_STRING str)
Definition: vfddrv.c:516
NTSTATUS NTAPI VfdCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: vfddrv.c:312
#define VFD_PNP_TAG
PWSTR VfdCopyUnicode(PUNICODE_STRING dst, PUNICODE_STRING src)
Definition: vfddrv.c:489
ULONG OsMajorVersion
ULONG OsMinorVersion
static VOID NTAPI VfdReinitialize(IN PDRIVER_OBJECT DriverObject, IN PVOID Context, IN ULONG Count)
Definition: vfddrv.c:345
struct _VFD_DRIVER_EXTENSION * PVFD_DRIVER_EXTENSION
NTSTATUS NTAPI VfdDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: vfdioctl.c:29
VOID VfdReadData(IN PDEVICE_EXTENSION DeviceExtension, IN OUT PIRP Irp, IN ULONG Length, IN PLARGE_INTEGER Offset)
Definition: vfdrdwr.c:217
NTSTATUS NTAPI VfdReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: vfdrdwr.c:24
#define VFD_POOL_TAG
Definition: vfddrv.h:25
NTSTATUS VfdSetLink(IN PDEVICE_EXTENSION DeviceExtension, IN CHAR DriveLetter)
Definition: vfdlink.c:24
VOID VfdIoCtlThread(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN ULONG ControlCode)
Definition: vfdioctl.c:542
VOID VfdWriteData(IN PDEVICE_EXTENSION DeviceExtension, IN OUT PIRP Irp, IN ULONG Length, IN PLARGE_INTEGER Offset)
Definition: vfdrdwr.c:287
#define VFD_REG_TRACE_FLAGS
Definition: vfdio.h:29
#define VFD_REG_DEVICE_NUMBER
Definition: vfdio.h:28
#define VFD_MAXIMUM_DEVICES
Definition: vfdtypes.h:75
#define VFD_DEFAULT_DEVICES
Definition: vfdtypes.h:74
#define VFD_PRODUCT_NAME
Definition: vfdver.h:14
#define VFD_DRIVER_VERSION_STR
Definition: vfdver.h:59
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_SYSTEM_CONTROL
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define IRP_MJ_POWER
@ Executive
Definition: ketypes.h:415