Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431/* vfddev.c
Virtual Floppy Drive for Windows NT platform Kernel mode driver: device create/delete functions
Copyright (C) 2003-2005 Ken Kato*/
#include "imports.h"#include "vfddrv.h"#include "vfddbg.h"
#ifdef ALLOC_PRAGMA#pragma alloc_text(PAGE, VfdCreateDevice)#pragma alloc_text(PAGE, VfdDeleteDevice)#endif // ALLOC_PRAGMA
//// Create a VFD device object//NTSTATUSVfdCreateDevice( IN PDRIVER_OBJECT DriverObject, OUT PVOID Parameter){ NTSTATUS status; ULONG physical_num;
UNICODE_STRING unicode_name; WCHAR name_buffer[40];
PVFD_DRIVER_EXTENSION driver_extension = NULL; PDEVICE_OBJECT device_object = NULL; PDEVICE_EXTENSION device_extension = NULL; HANDLE thread_handle = NULL;
VFDTRACE(VFDINFO | VFDDEV, ("[VFD] VfdCreateDevice - IN\n"));
#ifdef VFD_PNP
// Get the driver device_extension for the driver object driver_extension = IoGetDriverObjectExtension( DriverObject, VFD_DRIVER_EXTENSION_ID);
#else // VFD_PNP
// The driver device_extension is passed as the Parameter driver_extension = (PVFD_DRIVER_EXTENSION)Parameter;
#endif // VFD_PNP
if (driver_extension == NULL) { VFDTRACE(VFDERR, ("[VFD] Failed to get the driver extension\n")); return STATUS_DRIVER_INTERNAL_ERROR; }
// // Create a device object // \Device\Floppy<n> // physical_num = 0;
do {#ifndef __REACTOS__ name_buffer[sizeof(name_buffer) - 1] = UNICODE_NULL;
_snwprintf(name_buffer, sizeof(name_buffer) - 1, L"\\Device\\Floppy%lu", physical_num);#else name_buffer[ARRAYSIZE(name_buffer) - 1] = UNICODE_NULL;
_snwprintf(name_buffer, ARRAYSIZE(name_buffer) - 1, L"\\Device\\Floppy%lu", physical_num);#endif
RtlInitUnicodeString(&unicode_name, name_buffer);
status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), &unicode_name, FILE_DEVICE_DISK, FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE | FILE_DEVICE_SECURE_OPEN, FALSE, &device_object);
if (status != STATUS_OBJECT_NAME_EXISTS && status != STATUS_OBJECT_NAME_COLLISION) { break; } } while (++physical_num < 100);
if (!NT_SUCCESS(status)) { VFDTRACE(VFDERR, ("[VFD] IoCreateDevice() %s\n", GetStatusName(status))); return status; }
IoGetConfigurationInformation()->FloppyCount++;
VFDTRACE(VFDINFO | VFDDEV, ("[VFD] Created a device object %ws\n", name_buffer));
// // Initialize the device object / device extension //
device_object->Flags |= DO_DIRECT_IO;
device_extension = (PDEVICE_EXTENSION)device_object->DeviceExtension;
RtlZeroMemory(device_extension, sizeof(DEVICE_EXTENSION));
// Store the back pointer to the device object
device_extension->DeviceObject = device_object;
// Store the logical device number
device_extension->DeviceNumber = driver_extension->NumberOfDevices;
// Store the device name
if (!VfdCopyUnicode(&(device_extension->DeviceName), &unicode_name)) { VFDTRACE(VFDERR, ("[VFD] Failed to allocate device name buffer\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; }
// set the default disk geometry (3.5" 1.44M)
device_extension->Geometry = &geom_tbl[0];
// Create the interface link (\??\VirtualFD<n>)
#ifndef __REACTOS__ name_buffer[sizeof(name_buffer) - 1] = UNICODE_NULL;
_snwprintf(name_buffer, sizeof(name_buffer) - 1, L"\\??\\" VFD_DEVICE_BASENAME L"%lu", device_extension->DeviceNumber);#else name_buffer[ARRAYSIZE(name_buffer) - 1] = UNICODE_NULL;
_snwprintf(name_buffer, ARRAYSIZE(name_buffer) - 1, L"\\??\\" VFD_DEVICE_BASENAME L"%lu", device_extension->DeviceNumber);#endif
RtlInitUnicodeString(&unicode_name, name_buffer);
status = IoCreateSymbolicLink( &unicode_name, &device_extension->DeviceName);
if (!NT_SUCCESS(status)) { VFDTRACE(VFDERR, ("[VFD] IoCreateSymbolicLink(%ws) %s\n", name_buffer, GetStatusName(status))); goto cleanup; }
VFDTRACE(VFDINFO|VFDDEV, ("[VFD] Created a symbolic link %ws\n", name_buffer));
// Prepare the IRP queue list for the device thread
InitializeListHead(&device_extension->ListHead);
KeInitializeSpinLock(&device_extension->ListLock);
KeInitializeEvent( &device_extension->RequestEvent, SynchronizationEvent, FALSE);
// Create the device thread
device_extension->TerminateThread = FALSE;
status = PsCreateSystemThread( &thread_handle, (ACCESS_MASK) 0L, NULL, NULL, NULL, VfdDeviceThread, device_object);
if (!NT_SUCCESS(status)) { VFDTRACE(VFDERR, ("[VFD] PsCreateSystemThread() %s\n", GetStatusName(status))); goto cleanup; }
// get a reference pointer to the thread
status = ObReferenceObjectByHandle( thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &device_extension->ThreadPointer, NULL);
ZwClose(thread_handle);
if (!NT_SUCCESS(status)) { VFDTRACE(VFDERR, ("[VFD] ObReferenceObjectByHandle() %s\n", GetStatusName(status))); goto cleanup; }
// // Load the persistent drive letter from the registry // if (driver_extension->RegistryPath.Buffer) { VfdLoadLink(device_extension, driver_extension->RegistryPath.Buffer); // error is not fatal here }
// increment the number of devices in the driver extension
driver_extension->NumberOfDevices++;
if (DriverObject->DriverUnload) { // not called from the DriverEntry routine device_object->Flags &= ~DO_DEVICE_INITIALIZING; }
#ifdef VFD_PNP if (Parameter) { // return the device object pointer *(PDEVICE_OBJECT *)Parameter = device_object; }#else // VFD_PNP device_extension->DriverExtension = driver_extension;#endif // VFD_PNP
VFDTRACE(VFDINFO | VFDDEV, ("[VFD] VfdCreateDevice - OK\n"));
return STATUS_SUCCESS;
cleanup: // // Something went wrong at one point // Delete all resources that might be created in this function // if (thread_handle) {
// terminate the device thread device_extension->TerminateThread = TRUE;
KeSetEvent( &device_extension->RequestEvent, (KPRIORITY) 0, FALSE);
if (device_extension->ThreadPointer) { ObDereferenceObject(device_extension->ThreadPointer); } }
VFDTRACE(VFDINFO|VFDDEV, ("[VFD] Deleting symbolic link %ws\n", name_buffer));
IoDeleteSymbolicLink(&unicode_name);
if (device_extension->DeviceName.Buffer) { VFDTRACE(VFDINFO|VFDDEV, ("[VFD] Deleting device %ws\n", device_extension->DeviceName.Buffer));
ExFreePool(device_extension->DeviceName.Buffer); }
IoDeleteDevice(device_object); IoGetConfigurationInformation()->FloppyCount--;
VFDTRACE(VFDINFO|VFDDEV, ("[VFD] VfdCreateDevice - %s\n", GetStatusName(status)));
return status;}
//// delete a VFD device object//VOIDVfdDeleteDevice( IN PDEVICE_OBJECT DeviceObject){ PDEVICE_EXTENSION device_extension; PVFD_DRIVER_EXTENSION driver_extension; UNICODE_STRING unicode_name; WCHAR name_buffer[40];
VFDTRACE(VFDINFO|VFDDEV, ("[VFD] VfdDeleteDevice - IN\n"));
device_extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
// // decrement the number of device in the driver extension //#ifdef VFD_PNP driver_extension = IoGetDriverObjectExtension( DeviceObject->DriverObject, VFD_DRIVER_EXTENSION_ID);#else // VFD_PNP driver_extension = device_extension->DriverExtension;#endif // VFD_PNP
if (driver_extension) { driver_extension->NumberOfDevices--; }
// // cleanup the device object //
// Terminate the device thread
device_extension->TerminateThread = TRUE;
KeSetEvent( &device_extension->RequestEvent, (KPRIORITY) 0, FALSE);
KeWaitForSingleObject( device_extension->ThreadPointer, Executive, KernelMode, FALSE, NULL);
ObDereferenceObject( device_extension->ThreadPointer);
// Delete security context object
if (device_extension->SecurityContext) { SeDeleteClientSecurity(device_extension->SecurityContext); ExFreePool(device_extension->SecurityContext); }
// Close the image file or free the image buffer
if (device_extension->FileHandle) { ZwClose(device_extension->FileHandle); }
if (device_extension->FileBuffer) { ExFreePool(device_extension->FileBuffer); }
// Release the image path buffer
if (device_extension->FileName.Buffer) { ExFreePool(device_extension->FileName.Buffer); }
// Remove the interface symbolic link
#ifndef __REACTOS__ name_buffer[sizeof(name_buffer) - 1] = UNICODE_NULL;
_snwprintf(name_buffer, sizeof(name_buffer) - 1, L"\\??\\" VFD_DEVICE_BASENAME L"%lu", device_extension->DeviceNumber);#else name_buffer[ARRAYSIZE(name_buffer) - 1] = UNICODE_NULL;
_snwprintf(name_buffer, ARRAYSIZE(name_buffer) - 1, L"\\??\\" VFD_DEVICE_BASENAME L"%lu", device_extension->DeviceNumber);#endif
RtlInitUnicodeString(&unicode_name, name_buffer);
VFDTRACE(VFDINFO|VFDDEV, ("[VFD] Deleting link %ws\n", name_buffer));
IoDeleteSymbolicLink(&unicode_name);
// Remove the persistent drive letter
if (device_extension->DriveLetter) {#ifdef VFD_MOUNT_MANAGER if (OsMajorVersion >= 5) { // Request the mount manager to remove the drive letter. // This will cause the mount manager to update its database // and it won't arbitrarily assign the drive letter the next // time the driver starts. VfdMountMgrMountPoint(device_extension, 0); } else#endif // VFD_MOUNT_MANAGER { // Windows NT style drive letter handling // Simply remove the symbolic link VfdSetLink(device_extension, 0); } }
// Release the device name buffer
if (device_extension->DeviceName.Buffer) { VFDTRACE(VFDINFO|VFDDEV, ("[VFD] Deleting device %ws\n", device_extension->DeviceName.Buffer));
ExFreePool(device_extension->DeviceName.Buffer); }
// Delete the device object
IoDeleteDevice(DeviceObject); IoGetConfigurationInformation()->FloppyCount--;
VFDTRACE(VFDINFO|VFDDEV, ("[VFD] VfdDeleteDevice - OUT\n"));
return;}