reactos/modules/rosapps/drivers/vfd/vfdlink.c
Timo Kreuzer 6b1ca75899
[REACTOS] Fix 64 bit build (#465)
* [HAL] Simplify HalpReboot() and make it portable
* [NTOS:MM] Cast constant to PVOID
* [BINPATCH] Fix 64 bit build
* [VFDDRV] Fix 64 bit build and buffer overruns
* [USBOHCI] Fix structure alignment issues
* [ATL_APITEST] Fix 64 bit build
* [XDK] Update unwind structures in winnt.h
* [NTDLL_APITEST] Fix 64 bit build
* [NTDLL_WINETEST] Fix 64 bit build
* [TFTPD] Fix x64 build
* [USBPORT] Fix a C_ASSERT
* [DSOUND] Fix x64 build
* [HAL] Remove obsolete GetPteAddress() macro
2018-04-03 15:13:17 -06:00

256 lines
5.7 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
//
#ifndef __REACTOS__
name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
#else
name_buf[ARRAYSIZE(name_buf) - 1] = UNICODE_NULL;
#endif
_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
//
#ifndef __REACTOS__
name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
_snwprintf(name_buf, sizeof(name_buf) - 1,
(OsMajorVersion >= 5) ?
L"\\??\\Global\\%wc:" : L"\\??\\%wc:",
DriveLetter);
#else
name_buf[ARRAYSIZE(name_buf) - 1] = UNICODE_NULL;
_snwprintf(name_buf, ARRAYSIZE(name_buf) - 1,
(OsMajorVersion >= 5) ?
L"\\??\\Global\\%wc:" : L"\\??\\%wc:",
DriveLetter);
#endif
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));
#ifndef __REACTOS__
name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
_snwprintf(name_buf, sizeof(name_buf) - 1,
VFD_REG_DRIVE_LETTER L"%lu",
DeviceExtension->DeviceNumber);
#else
name_buf[ARRAYSIZE(name_buf) - 1] = UNICODE_NULL;
_snwprintf(name_buf, ARRAYSIZE(name_buf) - 1,
VFD_REG_DRIVE_LETTER L"%lu",
DeviceExtension->DeviceNumber);
#endif
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, &params[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;
}
#ifndef __REACTOS__
name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
_snwprintf(name_buf, sizeof(name_buf) - 1,
VFD_REG_DRIVE_LETTER L"%lu",
DeviceExtension->DeviceNumber);
#else
name_buf[ARRAYSIZE(name_buf) - 1] = UNICODE_NULL;
_snwprintf(name_buf, ARRAYSIZE(name_buf) - 1,
VFD_REG_DRIVE_LETTER L"%lu",
DeviceExtension->DeviceNumber);
#endif
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;
}