- Update to r53061
[reactos.git] / drivers / multimedia / audio / mpu401_nt4 / settings.c
1 /*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/dd/mpu401/settings.c
6 * PURPOSE: MPU-401 MIDI device driver setting management
7 * PROGRAMMER: Andrew Greenwood
8 * UPDATE HISTORY:
9 * Sept 27, 2003: Created
10 */
11
12 #include <ntddk.h>
13
14 #include "mpu401.h"
15
16 #define NDEBUG
17 #include <debug.h>
18 #include "sbdebug.h" // our own debug helper
19
20 #if 0
21 static NTSTATUS
22 OpenDevicesKey(
23 IN PWSTR RegistryPath,
24 OUT PHANDLE Key)
25 /*
26 Description:
27 Create a volatile key under this driver's Services node to contain
28 the device name list.
29
30 Parameters:
31 RegistryPath The location of the registry entry
32 Key The key in the registry
33
34 Return Value:
35 NT status STATUS_SUCCESS if successful (duh...)
36 */
37 {
38 NTSTATUS s;
39 HANDLE hKey;
40 OBJECT_ATTRIBUTES oa;
41 UNICODE_STRING uStr;
42
43 // Attempt to open the key
44
45 RtlInitUnicodeString(&uStr, RegistryPath);
46
47 InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, NULL,
48 (PSECURITY_DESCRIPTOR)NULL);
49
50 s = ZwOpenKey(&hKey, KEY_CREATE_SUB_KEY, &oa);
51
52 if (! NT_SUCCESS(s))
53 return s; // Problem
54
55
56 // Now create sub key
57
58 RtlInitUnicodeString(&uStr, (PWSTR) DEVICE_SUBKEY);
59
60 InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, hKey,
61 (PSECURITY_DESCRIPTOR)NULL);
62
63 s = ZwCreateKey(Key, KEY_ALL_ACCESS, &oa, 0, NULL, REG_OPTION_VOLATILE,
64 NULL);
65
66 ZwClose(hKey);
67
68 return s;
69 }
70 #endif
71
72
73 NTSTATUS NTAPI EnumDeviceKeys(
74 IN PUNICODE_STRING RegistryPath,
75 IN PWSTR SubKey,
76 IN PREGISTRY_CALLBACK_ROUTINE Callback,
77 IN PVOID Context)
78 /*
79 Description:
80 Enumerate the device subkeys in the driver's registry entry, and
81 call the specified callback routine for each device.
82
83 Parameters:
84 RegistryPath The location of the registry entry
85 Subkey The device's subkey
86 Callback A routine called for each device
87 Context ???
88
89 Return Value:
90 NT status STATUS_SUCCESS if successful
91 */
92 {
93 NTSTATUS s;
94 OBJECT_ATTRIBUTES oa;
95 HANDLE hKey, hSubKey;
96 UNICODE_STRING SubkeyName;
97 ULONG i;
98
99 // Attempt to open the key
100
101 InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE,
102 NULL, (PSECURITY_DESCRIPTOR)NULL);
103
104 s = ZwOpenKey(&hKey, KEY_READ, &oa);
105
106 TEST_STATUS(s); // debugging
107
108 if (! NT_SUCCESS(s))
109 return s; // Problem
110
111 RtlInitUnicodeString(&SubkeyName, SubKey);
112
113 DPRINT("Subkey: %wZ\n", &SubkeyName);
114
115 InitializeObjectAttributes(&oa, &SubkeyName, OBJ_CASE_INSENSITIVE,
116 hKey, (PSECURITY_DESCRIPTOR)NULL);
117
118 s = ZwOpenKey(&hSubKey, KEY_ENUMERATE_SUB_KEYS, &oa);
119
120 ZwClose(hKey);
121
122 TEST_STATUS(s); // debugging
123
124 if (! NT_SUCCESS(s))
125 return s;
126
127
128 // And now, the enumeration
129
130 for (i = 0;; i ++)
131 {
132 KEY_BASIC_INFORMATION Info;
133 PKEY_BASIC_INFORMATION pInfo;
134 ULONG ResultLength = 0;
135 ULONG Size = 0;
136 PWSTR Pos;
137 PWSTR Name;
138
139 // Find the length of the subkey data
140
141 // Info.NameLength = 0; // TEMPORARY!
142
143 s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, &Info,
144 sizeof(Info), &ResultLength);
145
146 if (s == STATUS_NO_MORE_ENTRIES)
147 break;
148
149 DPRINT("Found an entry, allocating memory...\n");
150
151 // Size = Info.NameLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
152 Size = ResultLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
153
154 DPRINT("Size is %d\n", Size);
155
156 pInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, Size);
157
158 if (pInfo == NULL)
159 {
160 DPRINT("INSUFFICIENT RESOURCES!\n");
161 s = STATUS_INSUFFICIENT_RESOURCES;
162 break;
163 }
164
165 DPRINT("Re-enumerating...\n");
166
167 s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, pInfo, Size,
168 &ResultLength);
169
170 // TEST_STATUS(s); // debugging
171
172 if (! NT_SUCCESS(s))
173 {
174 ExFreePool((PVOID) pInfo);
175 s = STATUS_INTERNAL_ERROR;
176 break;
177 }
178
179 DPRINT("Allocating memory for name...\n");
180
181 Name = ExAllocatePool(PagedPool,
182 RegistryPath->Length + sizeof(WCHAR) +
183 SubkeyName.Length + sizeof(WCHAR) +
184 pInfo->NameLength + sizeof(UNICODE_NULL));
185
186 if (Name == NULL)
187 {
188 DPRINT("INSUFFICIENT RESOURCES!");
189 ExFreePool((PVOID) pInfo);
190 return STATUS_INSUFFICIENT_RESOURCES;
191 }
192
193 // Copy the key name
194 RtlCopyMemory((PVOID)Name, (PVOID)RegistryPath->Buffer, RegistryPath->Length);
195 Pos = Name + (RegistryPath->Length / sizeof(WCHAR));
196 Pos[0] = '\\';
197 Pos++;
198
199 // Copy the parameters sub key name
200 RtlCopyMemory((PVOID)Pos, (PVOID)SubKey, SubkeyName.Length); //SubkeyName?
201 Pos += SubkeyName.Length / sizeof(WCHAR);
202 Pos[0] = '\\';
203 Pos ++;
204
205 // Copy the device sub key name
206 RtlCopyMemory((PVOID)Pos, (PVOID)pInfo->Name, pInfo->NameLength);
207 Pos += pInfo->NameLength / sizeof(WCHAR);
208 Pos[0] = UNICODE_NULL;
209
210 ExFreePool((PVOID)pInfo);
211
212 DPRINT("Calling callback...\n");
213
214 s = (*Callback)(Name, Context);
215
216 if (! NT_SUCCESS(s))
217 { DPRINT("Callback FAILED\n");
218 break;}
219 }
220
221 ZwClose(hSubKey);
222
223 DPRINT("%d device registry keys found\n", i);
224
225 if ((i == 0) && (s == STATUS_NO_MORE_ENTRIES))
226 return STATUS_DEVICE_CONFIGURATION_ERROR;
227
228 return s == STATUS_NO_MORE_ENTRIES ? STATUS_SUCCESS : s;
229 }
230
231
232
233 NTSTATUS NTAPI LoadSettings(
234 IN PWSTR ValueName,
235 IN ULONG ValueType,
236 IN PVOID ValueData,
237 IN ULONG ValueLength,
238 IN PVOID Context,
239 IN PVOID EntryContext)
240 /*
241 Description:
242 Read the settings for a particular device
243
244 Parameters:
245 ValueName The value to read from the registry
246 ValueType ?
247 ValueData ?
248 ValueLength ?
249 Context The configuration structure to write to
250 EntryContext ?
251
252 Return Value:
253 NT status STATUS_SUCCESS if successful
254 */
255 {
256 PDEVICE_EXTENSION DeviceInfo = Context;
257
258 if (ValueType == REG_DWORD)
259 {
260 if (! _wcsicmp(ValueName, REGISTRY_PORT))
261 {
262 DeviceInfo->Port = *(PULONG) ValueData;
263 DPRINT("Registry port = 0x%x\n", DeviceInfo->Port);
264 }
265
266 // More to come... (config.c)
267 }
268
269 else
270 {
271 // ?
272 }
273
274 return STATUS_SUCCESS;
275 }
276
277
278 #if 0
279 static NTSTATUS SaveSettings(
280 IN PWSTR RegistryPath,
281 IN ULONG Port,
282 IN ULONG IRQ,
283 IN ULONG DMA)
284 /*
285 Description:
286 Saves the settings for a particular device
287
288 Parameters:
289 RegistryPath Where to save the settings to
290 Port The device's port number
291 IRQ The device's interrupt number
292 DMA The device's DMA channel
293
294 Return Value:
295 NT status STATUS_SUCCESS if successful
296 */
297 {
298 // NTSTATUS s;
299
300 DPRINT("SaveSettings() unimplemented\n");
301
302 // UNIMPLEMENTED;
303
304 return STATUS_SUCCESS;
305 }
306 #endif
307