3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: drivers/dd/sndblst/settings.c
6 * PURPOSE: MPU-401 MIDI device driver setting management
7 * PROGRAMMER: Andrew Greenwood
9 * Sept 28, 2003: Created
14 #include "sbdebug.h" // our own debug helper
20 IN PWSTR RegistryPath
,
24 Create a volatile key under this driver's Services node to contain
28 RegistryPath The location of the registry entry
29 Key The key in the registry
32 NT status STATUS_SUCCESS if successful (duh...)
40 // Attempt to open the key
42 RtlInitUnicodeString(&uStr
, RegistryPath
);
44 InitializeObjectAttributes(&oa
, &uStr
, OBJ_CASE_INSENSITIVE
, NULL
,
45 (PSECURITY_DESCRIPTOR
)NULL
);
47 s
= ZwOpenKey(&hKey
, KEY_CREATE_SUB_KEY
, &oa
);
55 RtlInitUnicodeString(&uStr
, (PWSTR
) DEVICE_SUBKEY
);
57 InitializeObjectAttributes(&oa
, &uStr
, OBJ_CASE_INSENSITIVE
, hKey
,
58 (PSECURITY_DESCRIPTOR
)NULL
);
60 s
= ZwCreateKey(Key
, KEY_ALL_ACCESS
, &oa
, 0, NULL
, REG_OPTION_VOLATILE
,
70 NTSTATUS STDCALL
EnumDeviceKeys(
71 IN PUNICODE_STRING RegistryPath
,
73 IN PREGISTRY_CALLBACK_ROUTINE Callback
,
77 Enumerate the device subkeys in the driver's registry entry, and
78 call the specified callback routine for each device.
81 RegistryPath The location of the registry entry
82 Subkey The device's subkey
83 Callback A routine called for each device
87 NT status STATUS_SUCCESS if successful
93 UNICODE_STRING SubkeyName
;
96 // Attempt to open the key
98 InitializeObjectAttributes(&oa
, RegistryPath
, OBJ_CASE_INSENSITIVE
,
99 NULL
, (PSECURITY_DESCRIPTOR
)NULL
);
101 s
= ZwOpenKey(&hKey
, KEY_READ
, &oa
);
103 TEST_STATUS(s
); // debugging
108 RtlInitUnicodeString(&SubkeyName
, SubKey
);
110 DPRINT("Subkey: %wZ\n", &SubkeyName
);
112 InitializeObjectAttributes(&oa
, &SubkeyName
, OBJ_CASE_INSENSITIVE
,
113 hKey
, (PSECURITY_DESCRIPTOR
)NULL
);
115 s
= ZwOpenKey(&hSubKey
, KEY_ENUMERATE_SUB_KEYS
, &oa
);
119 TEST_STATUS(s
); // debugging
125 // And now, the enumeration
129 KEY_BASIC_INFORMATION Info
;
130 PKEY_BASIC_INFORMATION pInfo
;
131 ULONG ResultLength
= 0;
136 // Find the length of the subkey data
138 // Info.NameLength = 0; // TEMPORARY!
140 s
= ZwEnumerateKey(hSubKey
, i
, KeyBasicInformation
, &Info
,
141 sizeof(Info
), &ResultLength
);
143 if (s
== STATUS_NO_MORE_ENTRIES
)
146 DPRINT("Found an entry, allocating memory...\n");
148 // Size = Info.NameLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
149 Size
= ResultLength
+ FIELD_OFFSET(KEY_BASIC_INFORMATION
, Name
[0]);
151 DPRINT("Size is %d\n", Size
);
153 pInfo
= (PKEY_BASIC_INFORMATION
) ExAllocatePool(PagedPool
, Size
);
157 DPRINT("INSUFFICIENT RESOURCES!\n");
158 s
= STATUS_INSUFFICIENT_RESOURCES
;
162 DPRINT("Re-enumerating...\n");
164 s
= ZwEnumerateKey(hSubKey
, i
, KeyBasicInformation
, pInfo
, Size
,
167 // TEST_STATUS(s); // debugging
171 ExFreePool((PVOID
) pInfo
);
172 s
= STATUS_INTERNAL_ERROR
;
176 DPRINT("Allocating memory for name...\n");
178 Name
= ExAllocatePool(PagedPool
,
179 RegistryPath
->Length
+ sizeof(WCHAR
) +
180 SubkeyName
.Length
+ sizeof(WCHAR
) +
181 pInfo
->NameLength
+ sizeof(UNICODE_NULL
));
185 DPRINT("INSUFFICIENT RESOURCES!");
186 ExFreePool((PVOID
) pInfo
);
187 return STATUS_INSUFFICIENT_RESOURCES
;
191 RtlCopyMemory((PVOID
)Name
, (PVOID
)RegistryPath
->Buffer
, RegistryPath
->Length
);
192 Pos
= Name
+ (RegistryPath
->Length
/ sizeof(WCHAR
));
196 // Copy the parameters sub key name
197 RtlCopyMemory((PVOID
)Pos
, (PVOID
)SubKey
, SubkeyName
.Length
); //SubkeyName?
198 Pos
+= SubkeyName
.Length
/ sizeof(WCHAR
);
202 // Copy the device sub key name
203 RtlCopyMemory((PVOID
)Pos
, (PVOID
)pInfo
->Name
, pInfo
->NameLength
);
204 Pos
+= pInfo
->NameLength
/ sizeof(WCHAR
);
205 Pos
[0] = UNICODE_NULL
;
207 ExFreePool((PVOID
)pInfo
);
209 DPRINT("Calling callback...\n");
211 s
= (*Callback
)(Name
, Context
);
214 { DPRINT("Callback FAILED\n");
220 DPRINT("%d device registry keys found\n", i
);
222 if ((i
== 0) && (s
== STATUS_NO_MORE_ENTRIES
))
223 return STATUS_DEVICE_CONFIGURATION_ERROR
;
225 return s
== STATUS_NO_MORE_ENTRIES
? STATUS_SUCCESS
: s
;
230 NTSTATUS STDCALL
LoadSettings(
234 IN ULONG ValueLength
,
236 IN PVOID EntryContext
)
239 Read the settings for a particular device
242 ValueName The value to read from the registry
246 Context The configuration structure to write to
250 NT status STATUS_SUCCESS if successful
253 PDEVICE_EXTENSION DeviceInfo
= Context
;
255 if (ValueType
== REG_DWORD
)
257 if (! _wcsicmp(ValueName
, REGISTRY_PORT
))
259 DeviceInfo
->Port
= *(PULONG
) ValueData
;
260 DPRINT("Registry port = 0x%x\n", DeviceInfo
->Port
);
263 // More to come... (config.c)
271 return STATUS_SUCCESS
;
276 NTSTATUS
SaveSettings(
277 IN PWSTR RegistryPath
,
283 Saves the settings for a particular device
286 RegistryPath Where to save the settings to
287 Port The device's port number
288 IRQ The device's interrupt number
289 DMA The device's DMA channel
292 NT status STATUS_SUCCESS if successful
295 DPRINT("SaveSettings() unimplemented\n");
299 return STATUS_SUCCESS
;