mirror of
https://github.com/reactos/reactos.git
synced 2024-10-08 02:13:56 +00:00
25c7e1a8d0
floppy drives in ReactOS and mount images on them. Only the cmd got imported. The GUI interface may come later on. Note that, as for vcdrom, the driver is left disabled and you need to explicitely start it through vfd command line interface. CORE-14090
227 lines
5 KiB
C
227 lines
5 KiB
C
/*
|
|
vfdlink.c
|
|
|
|
Virtual Floppy Drive for Windows NT platform
|
|
Kernel mode driver: persistent drive letter functions
|
|
|
|
Copyright (C) 2003-2005 Ken Kato
|
|
*/
|
|
|
|
#include "imports.h"
|
|
#include "vfddrv.h"
|
|
#include "vfddbg.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, VfdSetLink)
|
|
#pragma alloc_text(PAGE, VfdLoadLink)
|
|
#pragma alloc_text(PAGE, VfdStoreLink)
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
//
|
|
// create or remove the persistent drive letter (Windows NT)
|
|
//
|
|
NTSTATUS
|
|
VfdSetLink(
|
|
IN PDEVICE_EXTENSION DeviceExtension,
|
|
IN CHAR DriveLetter)
|
|
{
|
|
UNICODE_STRING unicode_name;
|
|
WCHAR name_buf[15];
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
VFDTRACE(VFDINFO, ("[VFD] VfdSetLink - IN\n"));
|
|
|
|
// convert lower case into upper case
|
|
|
|
if (DriveLetter >= 'a' && DriveLetter <= 'z') {
|
|
DriveLetter -= ('a' - 'A');
|
|
}
|
|
|
|
// check the drive letter range
|
|
|
|
if (DriveLetter != 0 &&
|
|
(DriveLetter < 'A' || DriveLetter > 'Z')) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (DeviceExtension->DriveLetter &&
|
|
DeviceExtension->DriveLetter != DriveLetter) {
|
|
//
|
|
// Delete the old drive letter
|
|
//
|
|
name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
|
|
|
|
_snwprintf(name_buf, sizeof(name_buf) - 1,
|
|
L"\\??\\%wc:", DeviceExtension->DriveLetter);
|
|
|
|
RtlInitUnicodeString(&unicode_name, name_buf);
|
|
|
|
status = IoDeleteSymbolicLink(&unicode_name);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
VFDTRACE(VFDINFO,
|
|
("[VFD] Link %ws deleted\n", name_buf));
|
|
|
|
DeviceExtension->DriveLetter = 0;
|
|
}
|
|
else if (status != STATUS_OBJECT_NAME_NOT_FOUND) {
|
|
// the driver letter did not exist in the first place
|
|
|
|
VFDTRACE(VFDINFO,
|
|
("[VFD] Link %ws not found\n", name_buf));
|
|
|
|
DeviceExtension->DriveLetter = 0;
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else {
|
|
VFDTRACE(VFDWARN,
|
|
("[VFD] IoDeleteSymbolicLink %ws - %s\n",
|
|
name_buf, GetStatusName(status)));
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(status) && DriveLetter) {
|
|
//
|
|
// Create a new drive letter
|
|
//
|
|
|
|
name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
|
|
|
|
_snwprintf(name_buf, sizeof(name_buf) - 1,
|
|
(OsMajorVersion >= 5) ?
|
|
L"\\??\\Global\\%wc:" : L"\\??\\%wc:",
|
|
DriveLetter);
|
|
|
|
RtlInitUnicodeString(&unicode_name, name_buf);
|
|
|
|
status = IoCreateSymbolicLink(
|
|
&unicode_name, &(DeviceExtension->DeviceName));
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
VFDTRACE(VFDINFO, ("[VFD] Link %ws created\n", name_buf));
|
|
|
|
DeviceExtension->DriveLetter = DriveLetter;
|
|
}
|
|
else {
|
|
VFDTRACE(VFDWARN,
|
|
("[VFD] IoCreateSymbolicLink %ws - %s\n",
|
|
name_buf, GetStatusName(status)));
|
|
}
|
|
}
|
|
|
|
VFDTRACE(VFDINFO,
|
|
("[VFD] VfdSetLink - %s\n", GetStatusName(status)));
|
|
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// load the persistent drive letter from the registry
|
|
//
|
|
NTSTATUS
|
|
VfdLoadLink(
|
|
IN PDEVICE_EXTENSION DeviceExtension,
|
|
IN PWSTR RegistryPath)
|
|
{
|
|
RTL_QUERY_REGISTRY_TABLE params[2];
|
|
WCHAR name_buf[20];
|
|
ULONG letter;
|
|
ULONG zero = 0;
|
|
NTSTATUS status;
|
|
|
|
VFDTRACE(VFDINFO, ("[VFD] VfdLoadLink - IN\n"));
|
|
|
|
RtlZeroMemory(params, sizeof(params));
|
|
|
|
name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
|
|
|
|
_snwprintf(name_buf, sizeof(name_buf) - 1,
|
|
VFD_REG_DRIVE_LETTER L"%lu",
|
|
DeviceExtension->DeviceNumber);
|
|
|
|
params[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
params[0].Name = name_buf;
|
|
params[0].EntryContext = &letter;
|
|
params[0].DefaultType = REG_DWORD;
|
|
params[0].DefaultData = &zero;
|
|
params[0].DefaultLength = sizeof(ULONG);
|
|
|
|
status = RtlQueryRegistryValues(
|
|
RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
|
|
RegistryPath, ¶ms[0], NULL, NULL);
|
|
|
|
VFDTRACE(VFDINFO,
|
|
("[VFD] Drive letter '%wc' loaded from the registry\n",
|
|
letter ? letter : ' '));
|
|
|
|
DeviceExtension->DriveLetter = (CHAR)letter;
|
|
|
|
VFDTRACE(VFDINFO,
|
|
("[VFD] VfdLoadLink - %s\n", GetStatusName(status)));
|
|
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// store the persistent drive letter into the registry
|
|
//
|
|
NTSTATUS
|
|
VfdStoreLink(
|
|
IN PDEVICE_EXTENSION DeviceExtension)
|
|
{
|
|
PVFD_DRIVER_EXTENSION driver_extension;
|
|
WCHAR name_buf[20];
|
|
ULONG letter;
|
|
NTSTATUS status;
|
|
|
|
VFDTRACE(VFDINFO, ("[VFD] VfdStoreLink - IN\n"));
|
|
|
|
#ifdef VFD_PNP
|
|
driver_extension = IoGetDriverObjectExtension(
|
|
DeviceExtension->device_object->DriverObject,
|
|
VFD_DRIVER_EXTENSION_ID);
|
|
#else // VFD_PNP
|
|
driver_extension = DeviceExtension->DriverExtension;
|
|
#endif // VFD_PNP
|
|
|
|
if (!driver_extension ||
|
|
!driver_extension->RegistryPath.Buffer) {
|
|
|
|
VFDTRACE(VFDWARN, ("[VFD] Registry Path not present.\n"));
|
|
VFDTRACE(VFDINFO, ("[VFD] VfdStoreLinks - OUT\n"));
|
|
return STATUS_DRIVER_INTERNAL_ERROR;
|
|
}
|
|
|
|
name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
|
|
|
|
_snwprintf(name_buf, sizeof(name_buf) - 1,
|
|
VFD_REG_DRIVE_LETTER L"%lu",
|
|
DeviceExtension->DeviceNumber);
|
|
|
|
letter = DeviceExtension->DriveLetter;
|
|
|
|
status = RtlWriteRegistryValue(
|
|
RTL_REGISTRY_ABSOLUTE,
|
|
driver_extension->RegistryPath.Buffer,
|
|
name_buf,
|
|
REG_DWORD,
|
|
&letter,
|
|
sizeof(ULONG));
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
VFDTRACE(VFDWARN,
|
|
("[VFD] RtlWriteRegistryValue - %s\n",
|
|
GetStatusName(status)));
|
|
}
|
|
else {
|
|
VFDTRACE(VFDINFO,
|
|
("[VFD] Drive letter '%wc' stored into the registry\n",
|
|
letter ? letter : L' '));
|
|
}
|
|
|
|
VFDTRACE(VFDINFO,
|
|
("[VFD] VfdStoreLink - %s\n", GetStatusName(status)));
|
|
|
|
return status;
|
|
}
|