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
9 * Sept 27, 2003: Created
12 #include <ddk/ntddk.h>
18 #include "sbdebug.h" // our own debug helper
23 IN PWSTR RegistryPath
,
27 Create a volatile key under this driver's Services node to contain
31 RegistryPath The location of the registry entry
32 Key The key in the registry
35 NT status STATUS_SUCCESS if successful (duh...)
43 // Attempt to open the key
45 RtlInitUnicodeString(&uStr
, RegistryPath
);
47 InitializeObjectAttributes(&oa
, &uStr
, OBJ_CASE_INSENSITIVE
, NULL
,
48 (PSECURITY_DESCRIPTOR
)NULL
);
50 s
= ZwOpenKey(&hKey
, KEY_CREATE_SUB_KEY
, &oa
);
58 RtlInitUnicodeString(&uStr
, (PWSTR
) DEVICE_SUBKEY
);
60 InitializeObjectAttributes(&oa
, &uStr
, OBJ_CASE_INSENSITIVE
, hKey
,
61 (PSECURITY_DESCRIPTOR
)NULL
);
63 s
= ZwCreateKey(Key
, KEY_ALL_ACCESS
, &oa
, 0, NULL
, REG_OPTION_VOLATILE
,
73 NTSTATUS STDCALL
EnumDeviceKeys(
74 IN PUNICODE_STRING RegistryPath
,
76 IN PREGISTRY_CALLBACK_ROUTINE Callback
,
80 Enumerate the device subkeys in the driver's registry entry, and
81 call the specified callback routine for each device.
84 RegistryPath The location of the registry entry
85 Subkey The device's subkey
86 Callback A routine called for each device
90 NT status STATUS_SUCCESS if successful
96 UNICODE_STRING SubkeyName
;
99 // Attempt to open the key
101 InitializeObjectAttributes(&oa
, RegistryPath
, OBJ_CASE_INSENSITIVE
,
102 NULL
, (PSECURITY_DESCRIPTOR
)NULL
);
104 s
= ZwOpenKey(&hKey
, KEY_READ
, &oa
);
106 TEST_STATUS(s
); // debugging
111 RtlInitUnicodeString(&SubkeyName
, SubKey
);
113 DPRINT("Subkey: %wZ\n", &SubkeyName
);
115 InitializeObjectAttributes(&oa
, &SubkeyName
, OBJ_CASE_INSENSITIVE
,
116 hKey
, (PSECURITY_DESCRIPTOR
)NULL
);
118 s
= ZwOpenKey(&hSubKey
, KEY_ENUMERATE_SUB_KEYS
, &oa
);
122 TEST_STATUS(s
); // debugging
128 // And now, the enumeration
132 KEY_BASIC_INFORMATION Info
;
133 PKEY_BASIC_INFORMATION pInfo
;
134 ULONG ResultLength
= 0;
139 // Find the length of the subkey data
141 // Info.NameLength = 0; // TEMPORARY!
143 s
= ZwEnumerateKey(hSubKey
, i
, KeyBasicInformation
, &Info
,
144 sizeof(Info
), &ResultLength
);
146 if (s
== STATUS_NO_MORE_ENTRIES
)
149 DPRINT("Found an entry, allocating memory...\n");
151 // Size = Info.NameLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
152 Size
= ResultLength
+ FIELD_OFFSET(KEY_BASIC_INFORMATION
, Name
[0]);
154 DPRINT("Size is %d\n", Size
);
156 pInfo
= (PKEY_BASIC_INFORMATION
) ExAllocatePool(PagedPool
, Size
);
160 DPRINT("INSUFFICIENT RESOURCES!\n");
161 s
= STATUS_INSUFFICIENT_RESOURCES
;
165 DPRINT("Re-enumerating...\n");
167 s
= ZwEnumerateKey(hSubKey
, i
, KeyBasicInformation
, pInfo
, Size
,
170 // TEST_STATUS(s); // debugging
174 ExFreePool((PVOID
) pInfo
);
175 s
= STATUS_INTERNAL_ERROR
;
179 DPRINT("Allocating memory for name...\n");
181 Name
= ExAllocatePool(PagedPool
,
182 RegistryPath
->Length
+ sizeof(WCHAR
) +
183 SubkeyName
.Length
+ sizeof(WCHAR
) +
184 pInfo
->NameLength
+ sizeof(UNICODE_NULL
));
188 DPRINT("INSUFFICIENT RESOURCES!");
189 ExFreePool((PVOID
) pInfo
);
190 return STATUS_INSUFFICIENT_RESOURCES
;
194 RtlCopyMemory((PVOID
)Name
, (PVOID
)RegistryPath
->Buffer
, RegistryPath
->Length
);
195 Pos
= Name
+ (RegistryPath
->Length
/ sizeof(WCHAR
));
199 // Copy the parameters sub key name
200 RtlCopyMemory((PVOID
)Pos
, (PVOID
)SubKey
, SubkeyName
.Length
); //SubkeyName?
201 Pos
+= SubkeyName
.Length
/ sizeof(WCHAR
);
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
;
210 ExFreePool((PVOID
)pInfo
);
212 DPRINT("Calling callback...\n");
214 s
= (*Callback
)(Name
, Context
);
217 { DPRINT("Callback FAILED\n");
223 DPRINT("%d device registry keys found\n", i
);
225 if ((i
== 0) && (s
== STATUS_NO_MORE_ENTRIES
))
226 return STATUS_DEVICE_CONFIGURATION_ERROR
;
228 return s
== STATUS_NO_MORE_ENTRIES
? STATUS_SUCCESS
: s
;
233 NTSTATUS STDCALL
LoadSettings(
237 IN ULONG ValueLength
,
239 IN PVOID EntryContext
)
242 Read the settings for a particular device
245 ValueName The value to read from the registry
249 Context The configuration structure to write to
253 NT status STATUS_SUCCESS if successful
256 PDEVICE_EXTENSION DeviceInfo
= Context
;
258 if (ValueType
== REG_DWORD
)
260 if (! _wcsicmp(ValueName
, REGISTRY_PORT
))
262 DeviceInfo
->Port
= *(PULONG
) ValueData
;
263 DPRINT("Registry port = 0x%x\n", DeviceInfo
->Port
);
266 // More to come... (config.c)
274 return STATUS_SUCCESS
;
279 NTSTATUS
SaveSettings(
280 IN PWSTR RegistryPath
,
286 Saves the settings for a particular device
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
295 NT status STATUS_SUCCESS if successful
300 DPRINT("SaveSettings() unimplemented\n");
304 return STATUS_SUCCESS
;