reactos/drivers/multimedia/audio/mpu401_nt4/settings.c

308 lines
7.4 KiB
C

/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/dd/mpu401/settings.c
* PURPOSE: MPU-401 MIDI device driver setting management
* PROGRAMMER: Andrew Greenwood
* UPDATE HISTORY:
* Sept 27, 2003: Created
*/
#include <ntddk.h>
#include "mpu401.h"
#define NDEBUG
#include <debug.h>
#include "sbdebug.h" // our own debug helper
#if 0
static NTSTATUS
OpenDevicesKey(
IN PWSTR RegistryPath,
OUT PHANDLE Key)
/*
Description:
Create a volatile key under this driver's Services node to contain
the device name list.
Parameters:
RegistryPath The location of the registry entry
Key The key in the registry
Return Value:
NT status STATUS_SUCCESS if successful (duh...)
*/
{
NTSTATUS s;
HANDLE hKey;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uStr;
// Attempt to open the key
RtlInitUnicodeString(&uStr, RegistryPath);
InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, NULL,
(PSECURITY_DESCRIPTOR)NULL);
s = ZwOpenKey(&hKey, KEY_CREATE_SUB_KEY, &oa);
if (! NT_SUCCESS(s))
return s; // Problem
// Now create sub key
RtlInitUnicodeString(&uStr, (PWSTR) DEVICE_SUBKEY);
InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, hKey,
(PSECURITY_DESCRIPTOR)NULL);
s = ZwCreateKey(Key, KEY_ALL_ACCESS, &oa, 0, NULL, REG_OPTION_VOLATILE,
NULL);
ZwClose(hKey);
return s;
}
#endif
NTSTATUS NTAPI EnumDeviceKeys(
IN PUNICODE_STRING RegistryPath,
IN PWSTR SubKey,
IN PREGISTRY_CALLBACK_ROUTINE Callback,
IN PVOID Context)
/*
Description:
Enumerate the device subkeys in the driver's registry entry, and
call the specified callback routine for each device.
Parameters:
RegistryPath The location of the registry entry
Subkey The device's subkey
Callback A routine called for each device
Context ???
Return Value:
NT status STATUS_SUCCESS if successful
*/
{
NTSTATUS s;
OBJECT_ATTRIBUTES oa;
HANDLE hKey, hSubKey;
UNICODE_STRING SubkeyName;
ULONG i;
// Attempt to open the key
InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE,
NULL, (PSECURITY_DESCRIPTOR)NULL);
s = ZwOpenKey(&hKey, KEY_READ, &oa);
TEST_STATUS(s); // debugging
if (! NT_SUCCESS(s))
return s; // Problem
RtlInitUnicodeString(&SubkeyName, SubKey);
DPRINT("Subkey: %wZ\n", &SubkeyName);
InitializeObjectAttributes(&oa, &SubkeyName, OBJ_CASE_INSENSITIVE,
hKey, (PSECURITY_DESCRIPTOR)NULL);
s = ZwOpenKey(&hSubKey, KEY_ENUMERATE_SUB_KEYS, &oa);
ZwClose(hKey);
TEST_STATUS(s); // debugging
if (! NT_SUCCESS(s))
return s;
// And now, the enumeration
for (i = 0;; i ++)
{
KEY_BASIC_INFORMATION Info;
PKEY_BASIC_INFORMATION pInfo;
ULONG ResultLength = 0;
ULONG Size = 0;
PWSTR Pos;
PWSTR Name;
// Find the length of the subkey data
// Info.NameLength = 0; // TEMPORARY!
s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, &Info,
sizeof(Info), &ResultLength);
if (s == STATUS_NO_MORE_ENTRIES)
break;
DPRINT("Found an entry, allocating memory...\n");
// Size = Info.NameLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
Size = ResultLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
DPRINT("Size is %d\n", Size);
pInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, Size);
if (pInfo == NULL)
{
DPRINT("INSUFFICIENT RESOURCES!\n");
s = STATUS_INSUFFICIENT_RESOURCES;
break;
}
DPRINT("Re-enumerating...\n");
s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, pInfo, Size,
&ResultLength);
// TEST_STATUS(s); // debugging
if (! NT_SUCCESS(s))
{
ExFreePool((PVOID) pInfo);
s = STATUS_INTERNAL_ERROR;
break;
}
DPRINT("Allocating memory for name...\n");
Name = ExAllocatePool(PagedPool,
RegistryPath->Length + sizeof(WCHAR) +
SubkeyName.Length + sizeof(WCHAR) +
pInfo->NameLength + sizeof(UNICODE_NULL));
if (Name == NULL)
{
DPRINT("INSUFFICIENT RESOURCES!");
ExFreePool((PVOID) pInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
// Copy the key name
RtlCopyMemory((PVOID)Name, (PVOID)RegistryPath->Buffer, RegistryPath->Length);
Pos = Name + (RegistryPath->Length / sizeof(WCHAR));
Pos[0] = '\\';
Pos++;
// Copy the parameters sub key name
RtlCopyMemory((PVOID)Pos, (PVOID)SubKey, SubkeyName.Length); //SubkeyName?
Pos += SubkeyName.Length / sizeof(WCHAR);
Pos[0] = '\\';
Pos ++;
// Copy the device sub key name
RtlCopyMemory((PVOID)Pos, (PVOID)pInfo->Name, pInfo->NameLength);
Pos += pInfo->NameLength / sizeof(WCHAR);
Pos[0] = UNICODE_NULL;
ExFreePool((PVOID)pInfo);
DPRINT("Calling callback...\n");
s = (*Callback)(Name, Context);
if (! NT_SUCCESS(s))
{ DPRINT("Callback FAILED\n");
break;}
}
ZwClose(hSubKey);
DPRINT("%d device registry keys found\n", i);
if ((i == 0) && (s == STATUS_NO_MORE_ENTRIES))
return STATUS_DEVICE_CONFIGURATION_ERROR;
return s == STATUS_NO_MORE_ENTRIES ? STATUS_SUCCESS : s;
}
NTSTATUS NTAPI LoadSettings(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext)
/*
Description:
Read the settings for a particular device
Parameters:
ValueName The value to read from the registry
ValueType ?
ValueData ?
ValueLength ?
Context The configuration structure to write to
EntryContext ?
Return Value:
NT status STATUS_SUCCESS if successful
*/
{
PDEVICE_EXTENSION DeviceInfo = Context;
if (ValueType == REG_DWORD)
{
if (! _wcsicmp(ValueName, REGISTRY_PORT))
{
DeviceInfo->Port = *(PULONG) ValueData;
DPRINT("Registry port = 0x%x\n", DeviceInfo->Port);
}
// More to come... (config.c)
}
else
{
// ?
}
return STATUS_SUCCESS;
}
#if 0
static NTSTATUS SaveSettings(
IN PWSTR RegistryPath,
IN ULONG Port,
IN ULONG IRQ,
IN ULONG DMA)
/*
Description:
Saves the settings for a particular device
Parameters:
RegistryPath Where to save the settings to
Port The device's port number
IRQ The device's interrupt number
DMA The device's DMA channel
Return Value:
NT status STATUS_SUCCESS if successful
*/
{
// NTSTATUS s;
DPRINT("SaveSettings() unimplemented\n");
// UNIMPLEMENTED;
return STATUS_SUCCESS;
}
#endif