mirror of
https://github.com/reactos/reactos.git
synced 2024-11-01 04:11:30 +00:00
308 lines
7.4 KiB
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
|
|
|