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