859 lines
19 KiB
C
859 lines
19 KiB
C
/*++
|
||
|
||
Copyright (C) Microsoft Corporation, 1996 - 1999
|
||
|
||
Module Name:
|
||
|
||
map.c
|
||
|
||
Abstract:
|
||
|
||
This module contains routines for maintaining the SCSI device map in the
|
||
registry.
|
||
|
||
Authors:
|
||
|
||
Peter Wieland
|
||
|
||
Environment:
|
||
|
||
Kernel mode only
|
||
|
||
Notes:
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "port.h"
|
||
|
||
#define __FILE_ID__ 'map '
|
||
|
||
HANDLE ScsiDeviceMapKey = (HANDLE) -1;
|
||
|
||
VOID
|
||
SpDeleteLogicalUnitDeviceMapEntry(
|
||
PLOGICAL_UNIT_EXTENSION LogicalUnit
|
||
);
|
||
|
||
VOID
|
||
SpDeleteAdapterDeviceMap(
|
||
PADAPTER_EXTENSION Adapter
|
||
);
|
||
|
||
NTSTATUS
|
||
SpBuildAdapterDeviceMap(
|
||
IN PADAPTER_EXTENSION Adapter
|
||
);
|
||
|
||
NTSTATUS
|
||
SpBuildLogicalUnitDeviceMapEntry(
|
||
IN PLOGICAL_UNIT_EXTENSION LogicalUnit
|
||
);
|
||
|
||
NTSTATUS
|
||
SpCreateNumericKey(
|
||
IN HANDLE Root,
|
||
IN ULONG Name,
|
||
IN PWSTR Prefix,
|
||
IN BOOLEAN Create,
|
||
OUT PHANDLE NewKey,
|
||
OUT PULONG Disposition
|
||
);
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(INIT, SpInitDeviceMap)
|
||
|
||
#pragma alloc_text(PAGE, SpBuildDeviceMapEntry)
|
||
#pragma alloc_text(PAGE, SpBuildAdapterDeviceMap)
|
||
#pragma alloc_text(PAGE, SpBuildLogicalUnitDeviceMapEntry)
|
||
|
||
#pragma alloc_text(PAGE, SpDeleteLogicalUnitDeviceMapEntry)
|
||
#pragma alloc_text(PAGE, SpDeleteAdapterDeviceMap)
|
||
|
||
#pragma alloc_text(PAGE, SpUpdateLogicalUnitDeviceMapEntry)
|
||
|
||
#pragma alloc_text(PAGE, SpCreateNumericKey)
|
||
#endif
|
||
|
||
|
||
NTSTATUS
|
||
SpInitDeviceMap(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
status
|
||
|
||
--*/
|
||
|
||
{
|
||
UNICODE_STRING name;
|
||
|
||
OBJECT_ATTRIBUTES objectAttributes;
|
||
|
||
HANDLE mapKey;
|
||
|
||
ULONG disposition;
|
||
|
||
ULONG i;
|
||
|
||
NTSTATUS status;
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Open the SCSI key in the device map.
|
||
//
|
||
|
||
RtlInitUnicodeString(&name,
|
||
L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
|
||
|
||
InitializeObjectAttributes(&objectAttributes,
|
||
&name,
|
||
OBJ_CASE_INSENSITIVE,
|
||
NULL,
|
||
(PSECURITY_DESCRIPTOR) NULL);
|
||
|
||
//
|
||
// Create or open the key.
|
||
//
|
||
|
||
status = ZwCreateKey(&mapKey,
|
||
KEY_READ | KEY_WRITE,
|
||
&objectAttributes,
|
||
0,
|
||
(PUNICODE_STRING) NULL,
|
||
REG_OPTION_VOLATILE,
|
||
&disposition);
|
||
|
||
if(NT_SUCCESS(status)) {
|
||
ScsiDeviceMapKey = mapKey;
|
||
} else {
|
||
ScsiDeviceMapKey = NULL;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SpBuildDeviceMapEntry(
|
||
IN PCOMMON_EXTENSION CommonExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine will make an entry for the specified adapter or logical
|
||
unit in the SCSI device map in the registry. This table is maintained for
|
||
debugging and legacy use.
|
||
|
||
A handle to the device map key for this device will be stored in the
|
||
common device extension. This handle should only be used within the
|
||
context of a system thread.
|
||
|
||
Arguments:
|
||
|
||
Extension - the object we are adding to the device map.
|
||
|
||
Return Value:
|
||
|
||
status
|
||
|
||
--*/
|
||
|
||
{
|
||
PAGED_CODE();
|
||
|
||
if(CommonExtension->IsPdo) {
|
||
return SpBuildLogicalUnitDeviceMapEntry((PLOGICAL_UNIT_EXTENSION) CommonExtension);
|
||
} else {
|
||
return SpBuildAdapterDeviceMap((PADAPTER_EXTENSION) CommonExtension);
|
||
}
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SpBuildLogicalUnitDeviceMapEntry(
|
||
IN PLOGICAL_UNIT_EXTENSION LogicalUnit
|
||
)
|
||
{
|
||
PADAPTER_EXTENSION adapter = LogicalUnit->AdapterExtension;
|
||
|
||
HANDLE busKey;
|
||
|
||
PCWSTR typeString;
|
||
ANSI_STRING ansiString;
|
||
|
||
UNICODE_STRING name;
|
||
UNICODE_STRING unicodeString;
|
||
|
||
ULONG disposition;
|
||
NTSTATUS status;
|
||
|
||
PAGED_CODE();
|
||
|
||
ASSERT(LogicalUnit->IsTemporary == FALSE);
|
||
|
||
DebugPrint((1, "SpBuildDeviceMapEntry: Building map entry for lun %p\n",
|
||
LogicalUnit));
|
||
|
||
if(adapter->BusDeviceMapKeys == NULL) {
|
||
|
||
//
|
||
// We don't have keys built for the buses yet. Bail out.
|
||
//
|
||
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
//
|
||
// If we already have a target or LUN key for this device then we're done.
|
||
//
|
||
|
||
if((LogicalUnit->TargetDeviceMapKey != NULL) &&
|
||
(LogicalUnit->LunDeviceMapKey != NULL)) {
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
busKey = adapter->BusDeviceMapKeys[LogicalUnit->PathId].BusKey;
|
||
|
||
//
|
||
// Create a key for the target
|
||
//
|
||
|
||
status = SpCreateNumericKey(busKey,
|
||
LogicalUnit->TargetId,
|
||
L"Target Id ",
|
||
TRUE,
|
||
&(LogicalUnit->TargetDeviceMapKey),
|
||
&disposition);
|
||
|
||
if(!NT_SUCCESS(status)) {
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Create the LUN entry
|
||
//
|
||
|
||
status = SpCreateNumericKey(LogicalUnit->TargetDeviceMapKey,
|
||
LogicalUnit->Lun,
|
||
L"Logical Unit Id ",
|
||
TRUE,
|
||
&(LogicalUnit->LunDeviceMapKey),
|
||
&disposition);
|
||
|
||
if(!NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Create the identifier value
|
||
//
|
||
|
||
RtlInitUnicodeString(&name, L"Identifier");
|
||
|
||
//
|
||
// Get the identifier from the inquiry data
|
||
//
|
||
|
||
ansiString.MaximumLength = 28;
|
||
ansiString.Length = 28;
|
||
ansiString.Buffer = LogicalUnit->InquiryData.VendorId;
|
||
|
||
status = RtlAnsiStringToUnicodeString(&unicodeString,
|
||
&ansiString,
|
||
TRUE);
|
||
|
||
if(NT_SUCCESS(status)) {
|
||
|
||
status = ZwSetValueKey(LogicalUnit->LunDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_SZ,
|
||
unicodeString.Buffer,
|
||
unicodeString.Length + sizeof(WCHAR));
|
||
|
||
RtlFreeUnicodeString(&unicodeString);
|
||
}
|
||
|
||
//
|
||
// Determine the peripheral type
|
||
//
|
||
|
||
typeString =
|
||
SpGetDeviceTypeInfo(LogicalUnit->InquiryData.DeviceType)->DeviceMapString;
|
||
|
||
//
|
||
// Set type value.
|
||
//
|
||
|
||
RtlInitUnicodeString(&name, L"Type");
|
||
|
||
status = ZwSetValueKey(LogicalUnit->LunDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_SZ,
|
||
(PVOID) typeString,
|
||
(wcslen(typeString) + 1) * sizeof(WCHAR));
|
||
|
||
//
|
||
// Write the inquiry data into the device map for debugging purposes
|
||
//
|
||
|
||
RtlInitUnicodeString(&name, L"InquiryData");
|
||
|
||
status = ZwSetValueKey(LogicalUnit->LunDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_BINARY,
|
||
&(LogicalUnit->InquiryData),
|
||
INQUIRYDATABUFFERSIZE);
|
||
|
||
//
|
||
// Convert the serial number into unicode and write it out to the
|
||
// registry.
|
||
//
|
||
|
||
//
|
||
// Get the identifier from the inquiry data
|
||
//
|
||
|
||
if(LogicalUnit->SerialNumber.Length != 0) {
|
||
RtlInitUnicodeString(&name, L"SerialNumber");
|
||
|
||
status = RtlAnsiStringToUnicodeString(
|
||
&unicodeString,
|
||
&(LogicalUnit->SerialNumber),
|
||
TRUE);
|
||
|
||
if(NT_SUCCESS(status)) {
|
||
|
||
status = ZwSetValueKey(LogicalUnit->LunDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_SZ,
|
||
unicodeString.Buffer,
|
||
unicodeString.Length + sizeof(WCHAR));
|
||
|
||
RtlFreeUnicodeString(&unicodeString);
|
||
}
|
||
}
|
||
|
||
//
|
||
// If the device identifier page exists then write it out to the registry
|
||
//
|
||
|
||
if(LogicalUnit->DeviceIdentifierPage != NULL) {
|
||
RtlInitUnicodeString(&name, L"DeviceIdentifierPage");
|
||
|
||
status = ZwSetValueKey(LogicalUnit->LunDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_BINARY,
|
||
LogicalUnit->DeviceIdentifierPage,
|
||
LogicalUnit->DeviceIdentifierPageLength);
|
||
}
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SpBuildAdapterDeviceMap(
|
||
IN PADAPTER_EXTENSION Adapter
|
||
)
|
||
{
|
||
PSCSIPORT_DRIVER_EXTENSION driverExtension;
|
||
HANDLE mapKey;
|
||
|
||
UNICODE_STRING name;
|
||
|
||
OBJECT_ATTRIBUTES objectAttributes;
|
||
ULONG disposition;
|
||
|
||
ULONG i;
|
||
|
||
NTSTATUS status;
|
||
|
||
PUNICODE_STRING servicePath;
|
||
|
||
ULONG busNumber;
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Grab the handle to the SCSI device map out of the driver extension.
|
||
//
|
||
|
||
driverExtension = IoGetDriverObjectExtension(
|
||
Adapter->DeviceObject->DriverObject,
|
||
ScsiPortInitialize);
|
||
|
||
ASSERT(driverExtension != NULL);
|
||
|
||
mapKey = ScsiDeviceMapKey;
|
||
|
||
if(mapKey == NULL) {
|
||
|
||
//
|
||
// For some reason we were unable to create the root of the device map
|
||
// during scsiport initialization.
|
||
//
|
||
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
//
|
||
// Create a key beneath this for the port device
|
||
//
|
||
|
||
status = SpCreateNumericKey(mapKey,
|
||
Adapter->PortNumber,
|
||
L"Scsi Port ",
|
||
TRUE,
|
||
&(Adapter->PortDeviceMapKey),
|
||
&disposition);
|
||
|
||
if(!NT_SUCCESS(status)) {
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Indicate if it's a PCCARD
|
||
//
|
||
|
||
if(RtlEqualMemory(&GUID_BUS_TYPE_PCMCIA,
|
||
&(Adapter->BusTypeGuid),
|
||
sizeof(GUID))) {
|
||
|
||
RtlInitUnicodeString(&name, L"PCCARD");
|
||
|
||
i = 1;
|
||
|
||
status = ZwSetValueKey(Adapter->PortDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_DWORD,
|
||
&i,
|
||
sizeof(ULONG));
|
||
}
|
||
|
||
//
|
||
// Set the interrupt value
|
||
//
|
||
|
||
if(Adapter->InterruptLevel) {
|
||
RtlInitUnicodeString(&name, L"Interrupt");
|
||
|
||
i = Adapter->InterruptLevel;
|
||
|
||
status = ZwSetValueKey(Adapter->PortDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_DWORD,
|
||
&i,
|
||
sizeof(ULONG));
|
||
}
|
||
|
||
//
|
||
// Set the base I/O address value
|
||
//
|
||
|
||
if(Adapter->IoAddress) {
|
||
|
||
RtlInitUnicodeString(&name, L"IOAddress");
|
||
|
||
i = Adapter->IoAddress;
|
||
|
||
status = ZwSetValueKey(Adapter->PortDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_DWORD,
|
||
&i,
|
||
sizeof(ULONG));
|
||
|
||
}
|
||
|
||
if(Adapter->Dma64BitAddresses) {
|
||
RtlInitUnicodeString(&name, L"Dma64BitAddresses");
|
||
i = 0x1;
|
||
status = ZwSetValueKey(Adapter->PortDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_DWORD,
|
||
&i,
|
||
sizeof(ULONG));
|
||
}
|
||
|
||
servicePath = &driverExtension->RegistryPath;
|
||
|
||
ASSERT(servicePath != NULL);
|
||
|
||
//
|
||
// Add identifier value. This value is equal to the name of the driver
|
||
// in the service key. Note the service key name is not NULL terminated
|
||
//
|
||
|
||
{
|
||
PWSTR start;
|
||
WCHAR buffer[32];
|
||
|
||
RtlInitUnicodeString(&name, L"Driver");
|
||
|
||
//
|
||
// Get the name of the driver from the service key name.
|
||
//
|
||
|
||
start = (PWSTR) ((PCHAR) servicePath->Buffer + servicePath->Length);
|
||
|
||
start--;
|
||
|
||
while(*start != L'\\' && start > servicePath->Buffer) {
|
||
start--;
|
||
}
|
||
|
||
if(*start == L'\\') {
|
||
start++;
|
||
|
||
for(i = 0; i < 31; i++) {
|
||
buffer[i] = *start++;
|
||
|
||
if(start >= (servicePath->Buffer +
|
||
(servicePath->Length / sizeof(WCHAR)))) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
i++;
|
||
|
||
buffer[i] = L'\0';
|
||
|
||
status = ZwSetValueKey(Adapter->PortDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_SZ,
|
||
buffer,
|
||
(i + 1) * sizeof(WCHAR));
|
||
|
||
}
|
||
}
|
||
|
||
//
|
||
// Allocate storage for all the bus handles.
|
||
//
|
||
|
||
Adapter->BusDeviceMapKeys = SpAllocatePool(
|
||
PagedPool,
|
||
(sizeof(DEVICE_MAP_HANDLES) *
|
||
Adapter->NumberOfBuses),
|
||
SCSIPORT_TAG_DEVICE_MAP,
|
||
Adapter->DeviceObject->DriverObject);
|
||
|
||
if(Adapter->BusDeviceMapKeys == NULL) {
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
RtlZeroMemory(Adapter->BusDeviceMapKeys,
|
||
(sizeof(DEVICE_MAP_HANDLES) * Adapter->NumberOfBuses));
|
||
|
||
//
|
||
// Create a key for each bus. In each bus key create an empty key
|
||
// the initiator.
|
||
//
|
||
|
||
for(busNumber = 0;
|
||
busNumber < Adapter->NumberOfBuses;
|
||
busNumber++) {
|
||
|
||
PDEVICE_MAP_HANDLES busKeys;
|
||
|
||
HANDLE busKey;
|
||
HANDLE targetKey;
|
||
|
||
busKeys = &(Adapter->BusDeviceMapKeys[busNumber]);
|
||
|
||
//
|
||
// Create a key entry for the bus.
|
||
//
|
||
|
||
status = SpCreateNumericKey(
|
||
Adapter->PortDeviceMapKey,
|
||
busNumber,
|
||
L"Scsi Bus ",
|
||
TRUE,
|
||
&(busKeys->BusKey),
|
||
&disposition);
|
||
|
||
if(!NT_SUCCESS(status)) {
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// Now create a key for the initiator.
|
||
//
|
||
|
||
i = Adapter->PortConfig->InitiatorBusId[busNumber];
|
||
|
||
status = SpCreateNumericKey(busKeys->BusKey,
|
||
i,
|
||
L"Initiator Id ",
|
||
TRUE,
|
||
&(busKeys->InitiatorKey),
|
||
&disposition);
|
||
|
||
if(!NT_SUCCESS(status)) {
|
||
continue;
|
||
}
|
||
}
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
|
||
VOID
|
||
SpDeleteDeviceMapEntry(
|
||
IN PCOMMON_EXTENSION CommonExtension
|
||
)
|
||
{
|
||
if(CommonExtension->IsPdo) {
|
||
SpDeleteLogicalUnitDeviceMapEntry((PLOGICAL_UNIT_EXTENSION) CommonExtension);
|
||
} else {
|
||
SpDeleteAdapterDeviceMap((PADAPTER_EXTENSION) CommonExtension);
|
||
}
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
SpDeleteLogicalUnitDeviceMapEntry(
|
||
PLOGICAL_UNIT_EXTENSION LogicalUnit
|
||
)
|
||
{
|
||
if(LogicalUnit->LunDeviceMapKey != NULL) {
|
||
ASSERT(LogicalUnit->IsTemporary == FALSE);
|
||
|
||
ZwDeleteKey(LogicalUnit->LunDeviceMapKey);
|
||
ZwClose(LogicalUnit->LunDeviceMapKey);
|
||
LogicalUnit->LunDeviceMapKey = NULL;
|
||
}
|
||
|
||
if(LogicalUnit->TargetDeviceMapKey != NULL) {
|
||
ASSERT(LogicalUnit->IsTemporary == FALSE);
|
||
|
||
ZwDeleteKey(LogicalUnit->TargetDeviceMapKey);
|
||
ZwClose(LogicalUnit->TargetDeviceMapKey);
|
||
LogicalUnit->TargetDeviceMapKey = NULL;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
SpDeleteAdapterDeviceMap(
|
||
PADAPTER_EXTENSION Adapter
|
||
)
|
||
{
|
||
|
||
if(Adapter->BusDeviceMapKeys != NULL) {
|
||
|
||
ULONG busNumber;
|
||
|
||
//
|
||
// for each bus on the adapter.
|
||
//
|
||
|
||
for(busNumber = 0; busNumber < Adapter->NumberOfBuses; busNumber++) {
|
||
|
||
PDEVICE_MAP_HANDLES busKeys;
|
||
|
||
busKeys = &(Adapter->BusDeviceMapKeys[busNumber]);
|
||
|
||
//
|
||
// Attempt to delete the key for the initiator if it was created.
|
||
//
|
||
|
||
if(busKeys->InitiatorKey != NULL) {
|
||
ZwDeleteKey(busKeys->InitiatorKey);
|
||
ZwClose(busKeys->InitiatorKey);
|
||
}
|
||
|
||
//
|
||
// Attempt to delete the key for the bus if it was created.
|
||
//
|
||
|
||
if(busKeys->BusKey != NULL) {
|
||
ZwDeleteKey(busKeys->BusKey);
|
||
ZwClose(busKeys->BusKey);
|
||
}
|
||
}
|
||
|
||
ExFreePool(Adapter->BusDeviceMapKeys);
|
||
Adapter->BusDeviceMapKeys = NULL;
|
||
}
|
||
|
||
//
|
||
// Attempt to delete the key for the adapter if it was created.
|
||
//
|
||
|
||
if(Adapter->PortDeviceMapKey != NULL) {
|
||
ZwDeleteKey(Adapter->PortDeviceMapKey);
|
||
ZwClose(Adapter->PortDeviceMapKey);
|
||
Adapter->PortDeviceMapKey = NULL;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SpCreateNumericKey(
|
||
IN HANDLE Root,
|
||
IN ULONG Name,
|
||
IN PWSTR Prefix,
|
||
IN BOOLEAN Create,
|
||
OUT PHANDLE NewKey,
|
||
OUT PULONG Disposition
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function creates a registry key. The name of the key is a string
|
||
version of numeric value passed in.
|
||
|
||
Arguments:
|
||
|
||
RootKey - Supplies a handle to the key where the new key should be inserted.
|
||
|
||
Name - Supplies the numeric value to name the key.
|
||
|
||
Prefix - Supplies a prefix name to add to name.
|
||
|
||
Create - if TRUE the key will be created if it does not already exist.
|
||
|
||
NewKey - Returns the handle for the new key.
|
||
|
||
Disposition - the disposition value set by ZwCreateKey.
|
||
|
||
Return Value:
|
||
|
||
Returns the status of the operation.
|
||
|
||
--*/
|
||
|
||
{
|
||
UNICODE_STRING string;
|
||
UNICODE_STRING stringNum;
|
||
OBJECT_ATTRIBUTES objectAttributes;
|
||
WCHAR bufferNum[16];
|
||
WCHAR buffer[64];
|
||
NTSTATUS status;
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Copy the Prefix into a string.
|
||
//
|
||
|
||
string.Length = 0;
|
||
string.MaximumLength=64;
|
||
string.Buffer = buffer;
|
||
|
||
RtlInitUnicodeString(&stringNum, Prefix);
|
||
|
||
RtlCopyUnicodeString(&string, &stringNum);
|
||
|
||
//
|
||
// Create a port number key entry.
|
||
//
|
||
|
||
stringNum.Length = 0;
|
||
stringNum.MaximumLength = 16;
|
||
stringNum.Buffer = bufferNum;
|
||
|
||
status = RtlIntegerToUnicodeString(Name, 10, &stringNum);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Append the prefix and the numeric name.
|
||
//
|
||
|
||
RtlAppendUnicodeStringToString(&string, &stringNum);
|
||
|
||
InitializeObjectAttributes( &objectAttributes,
|
||
&string,
|
||
OBJ_CASE_INSENSITIVE,
|
||
Root,
|
||
(PSECURITY_DESCRIPTOR) NULL );
|
||
|
||
if(Create) {
|
||
status = ZwCreateKey(NewKey,
|
||
KEY_READ | KEY_WRITE,
|
||
&objectAttributes,
|
||
0,
|
||
(PUNICODE_STRING) NULL,
|
||
REG_OPTION_VOLATILE,
|
||
Disposition );
|
||
} else {
|
||
|
||
status = ZwOpenKey(NewKey,
|
||
KEY_READ | KEY_WRITE,
|
||
&objectAttributes);
|
||
|
||
*Disposition = REG_OPENED_EXISTING_KEY;
|
||
}
|
||
|
||
return(status);
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SpUpdateLogicalUnitDeviceMapEntry(
|
||
IN PLOGICAL_UNIT_EXTENSION LogicalUnit
|
||
)
|
||
{
|
||
UNICODE_STRING name;
|
||
|
||
PAGED_CODE();
|
||
|
||
if((LogicalUnit->TargetDeviceMapKey == NULL) ||
|
||
(LogicalUnit->LunDeviceMapKey == NULL)) {
|
||
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
//
|
||
// Write the inquiry data into the device map for debugging purposes
|
||
//
|
||
|
||
RtlInitUnicodeString(&name, L"InquiryData");
|
||
|
||
ZwSetValueKey(LogicalUnit->LunDeviceMapKey,
|
||
&name,
|
||
0,
|
||
REG_BINARY,
|
||
&(LogicalUnit->InquiryData),
|
||
INQUIRYDATABUFFERSIZE);
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|