Add display type (VGA or VESA) selection.
[reactos.git] / reactos / subsys / system / usetup / settings.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: settings.c,v 1.4 2004/06/20 12:14:23 ekohl Exp $
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/settings.c
23 * PURPOSE: Device settings support functions
24 * PROGRAMMER: Eric Kohl
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #include <ddk/ntddk.h>
30 #include <ntdll/rtl.h>
31 #include <ntos/minmax.h>
32
33 #include "usetup.h"
34 #include "infcache.h"
35 #include "genlist.h"
36 #include "settings.h"
37
38 #define NDEBUG
39 #include <debug.h>
40
41
42 /* FUNCTIONS ****************************************************************/
43
44 PGENERIC_LIST
45 CreateComputerTypeList(HINF InfFile)
46 {
47 CHAR Buffer[128];
48 PGENERIC_LIST List;
49 INFCONTEXT Context;
50 PWCHAR KeyName;
51 PWCHAR KeyValue;
52 PWCHAR UserData;
53
54 List = CreateGenericList();
55 if (List == NULL)
56 return NULL;
57
58 if (!InfFindFirstLine (InfFile, L"Computer", NULL, &Context))
59 {
60 DestroyGenericList(List, FALSE);
61 return NULL;
62 }
63
64 do
65 {
66 if (!InfGetData (&Context, &KeyName, &KeyValue))
67 {
68 /* FIXME: Handle error! */
69 DPRINT("InfGetData() failed\n");
70 break;
71 }
72
73 UserData = RtlAllocateHeap(ProcessHeap,
74 0,
75 (wcslen(KeyName) + 1) * sizeof(WCHAR));
76 if (UserData == NULL)
77 {
78 /* FIXME: Handle error! */
79 }
80
81 wcscpy(UserData, KeyName);
82
83 sprintf(Buffer, "%S", KeyValue);
84 AppendGenericListEntry(List, Buffer, UserData, FALSE);
85 }
86 while (InfFindNextLine(&Context, &Context));
87
88 return List;
89 }
90
91
92 static BOOLEAN
93 GetDisplayIdentifier(PWSTR Identifier,
94 ULONG IdentifierLength)
95 {
96 OBJECT_ATTRIBUTES ObjectAttributes;
97 UNICODE_STRING KeyName;
98 WCHAR Buffer[32];
99 HANDLE BusKey;
100 HANDLE BusInstanceKey;
101 HANDLE ControllerKey;
102 HANDLE ControllerInstanceKey;
103 ULONG BusInstance;
104 ULONG ControllerInstance;
105 ULONG BufferLength;
106 ULONG ReturnedLength;
107 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
108 NTSTATUS Status;
109
110 DPRINT("GetDisplayIdentifier() called\n");
111
112 /* Open the bus key */
113 RtlInitUnicodeString(&KeyName,
114 L"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
115 InitializeObjectAttributes(&ObjectAttributes,
116 &KeyName,
117 OBJ_CASE_INSENSITIVE,
118 NULL,
119 NULL);
120 Status = NtOpenKey(&BusKey,
121 KEY_ALL_ACCESS,
122 &ObjectAttributes);
123 if (!NT_SUCCESS(Status))
124 {
125 DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
126 return FALSE;
127 }
128
129 BusInstance = 0;
130 while (TRUE)
131 {
132 swprintf(Buffer, L"%lu", BusInstance);
133 RtlInitUnicodeString(&KeyName,
134 Buffer);
135 InitializeObjectAttributes(&ObjectAttributes,
136 &KeyName,
137 OBJ_CASE_INSENSITIVE,
138 BusKey,
139 NULL);
140 Status = NtOpenKey(&BusInstanceKey,
141 KEY_ALL_ACCESS,
142 &ObjectAttributes);
143 if (!NT_SUCCESS(Status))
144 {
145 DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
146 NtClose(BusKey);
147 return FALSE;
148 }
149
150 /* Open the controller type key */
151 RtlInitUnicodeString(&KeyName,
152 L"DisplayController");
153 InitializeObjectAttributes(&ObjectAttributes,
154 &KeyName,
155 OBJ_CASE_INSENSITIVE,
156 BusInstanceKey,
157 NULL);
158 Status = NtOpenKey(&ControllerKey,
159 KEY_ALL_ACCESS,
160 &ObjectAttributes);
161 if (NT_SUCCESS(Status))
162 {
163 ControllerInstance = 0;
164 while (TRUE)
165 {
166 /* Open the pointer controller instance key */
167 swprintf(Buffer, L"%lu", ControllerInstance);
168 RtlInitUnicodeString(&KeyName,
169 Buffer);
170 InitializeObjectAttributes(&ObjectAttributes,
171 &KeyName,
172 OBJ_CASE_INSENSITIVE,
173 ControllerKey,
174 NULL);
175 Status = NtOpenKey(&ControllerInstanceKey,
176 KEY_ALL_ACCESS,
177 &ObjectAttributes);
178 if (!NT_SUCCESS(Status))
179 {
180 DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
181 NtClose(ControllerKey);
182 NtClose(BusInstanceKey);
183 NtClose(BusKey);
184 return FALSE;
185 }
186
187 /* Get controller identifier */
188 RtlInitUnicodeString(&KeyName,
189 L"Identifier");
190
191 BufferLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
192 256 * sizeof(WCHAR);
193 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
194 0,
195 BufferLength);
196 if (ValueInfo == NULL)
197 {
198 DPRINT("RtlAllocateHeap() failed\n");
199 NtClose(ControllerInstanceKey);
200 NtClose(ControllerKey);
201 NtClose(BusInstanceKey);
202 NtClose(BusKey);
203 return FALSE;
204 }
205
206 Status = NtQueryValueKey(ControllerInstanceKey,
207 &KeyName,
208 KeyValuePartialInformation,
209 ValueInfo,
210 BufferLength,
211 &ReturnedLength);
212 if (NT_SUCCESS(Status))
213 {
214 DPRINT("Identifier: %S\n", (PWSTR)ValueInfo->Data);
215
216 BufferLength = min(ValueInfo->DataLength / sizeof(WCHAR), IdentifierLength);
217 RtlCopyMemory (Identifier,
218 ValueInfo->Data,
219 BufferLength * sizeof(WCHAR));
220 Identifier[BufferLength] = 0;
221
222 RtlFreeHeap(RtlGetProcessHeap(),
223 0,
224 ValueInfo);
225 NtClose(ControllerInstanceKey);
226 NtClose(ControllerKey);
227 NtClose(BusInstanceKey);
228 NtClose(BusKey);
229 return TRUE;
230 }
231
232 NtClose(ControllerInstanceKey);
233
234 ControllerInstance++;
235 }
236
237 NtClose(ControllerKey);
238 }
239
240 NtClose(BusInstanceKey);
241
242 BusInstance++;
243 }
244
245 NtClose(BusKey);
246
247 return FALSE;
248 }
249
250
251 PGENERIC_LIST
252 CreateDisplayDriverList(HINF InfFile)
253 {
254 CHAR Buffer[128];
255 PGENERIC_LIST List;
256 INFCONTEXT Context;
257 PWCHAR KeyName;
258 PWCHAR KeyValue;
259 PWCHAR UserData;
260 WCHAR DisplayIdentifier[128];
261 WCHAR DisplayKey[32];
262
263 /* Get the display identification */
264 if (!GetDisplayIdentifier(DisplayIdentifier, 128))
265 {
266 DisplayIdentifier[0] = 0;
267 }
268
269 DPRINT("Display identifier: '%S'\n", DisplayIdentifier);
270
271 /* Search for matching device identifier */
272 if (!InfFindFirstLine(InfFile, L"Map.Display", NULL, &Context))
273 {
274 /* FIXME: error message */
275 return NULL;
276 }
277
278 do
279 {
280 if (!InfGetDataField(&Context, 1, &KeyValue))
281 {
282 /* FIXME: Handle error! */
283 DPRINT("InfGetDataField() failed\n");
284 return NULL;
285 }
286
287 DPRINT("KeyValue: %S\n", KeyValue);
288 if (wcsstr(DisplayIdentifier, KeyValue))
289 {
290 if (!InfGetDataField(&Context, 0, &KeyName))
291 {
292 /* FIXME: Handle error! */
293 DPRINT("InfGetDataField() failed\n");
294 return NULL;
295 }
296
297 DPRINT("Display key: %S\n", KeyName);
298 wcscpy(DisplayKey, KeyName);
299 }
300 }
301 while (InfFindNextLine(&Context, &Context));
302
303
304 List = CreateGenericList();
305 if (List == NULL)
306 return NULL;
307
308 if (!InfFindFirstLine (InfFile, L"Display", NULL, &Context))
309 {
310 DestroyGenericList(List, FALSE);
311 return NULL;
312 }
313
314 do
315 {
316 if (!InfGetDataField(&Context, 0, &KeyName))
317 {
318 DPRINT1("InfGetDataField() failed\n");
319 break;
320 }
321
322 if (!InfGetDataField(&Context, 1, &KeyValue))
323 {
324 DPRINT1("InfGetDataField() failed\n");
325 break;
326 }
327
328 UserData = RtlAllocateHeap(ProcessHeap,
329 0,
330 (wcslen(KeyName) + 1) * sizeof(WCHAR));
331 if (UserData == NULL)
332 {
333 DPRINT1("RtlAllocateHeap() failed\n");
334 DestroyGenericList(List, TRUE);
335 return NULL;
336 }
337
338 wcscpy(UserData, KeyName);
339
340 sprintf(Buffer, "%S", KeyValue);
341 AppendGenericListEntry(List,
342 Buffer,
343 UserData,
344 _wcsicmp(KeyName, DisplayKey) ? FALSE : TRUE);
345 }
346 while (InfFindNextLine(&Context, &Context));
347
348 #if 0
349 AppendGenericListEntry(List, "Other display driver", NULL, TRUE);
350 #endif
351
352 return List;
353 }
354
355
356 BOOLEAN
357 ProcessDisplayRegistry(HINF InfFile, PGENERIC_LIST List)
358 {
359 PGENERIC_LIST_ENTRY Entry;
360 INFCONTEXT Context;
361 PWCHAR ServiceName;
362 ULONG StartValue;
363 NTSTATUS Status;
364
365 DPRINT("ProcessDisplayRegistry() called\n");
366
367 Entry = GetGenericListEntry(List);
368 if (Entry == NULL)
369 {
370 DPRINT("GetGenericListEntry() failed\n");
371 return FALSE;
372 }
373
374 if (!InfFindFirstLine(InfFile, L"Display", Entry->UserData, &Context))
375 {
376 DPRINT("InfFindFirstLine() failed\n");
377 return FALSE;
378 }
379
380 if (!InfGetDataField(&Context, 3, &ServiceName))
381 {
382 DPRINT("InfGetDataField() failed\n");
383 return FALSE;
384 }
385
386 DPRINT("Service name: %S\n", ServiceName);
387
388 StartValue = 1;
389 Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
390 ServiceName,
391 L"Start",
392 REG_DWORD,
393 &StartValue,
394 sizeof(ULONG));
395 if (!NT_SUCCESS(Status))
396 {
397 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status);
398 return FALSE;
399 }
400
401 DPRINT("ProcessDisplayRegistry() done\n");
402
403 return TRUE;
404 }
405
406
407 PGENERIC_LIST
408 CreateKeyboardDriverList(HINF InfFile)
409 {
410 CHAR Buffer[128];
411 PGENERIC_LIST List;
412 INFCONTEXT Context;
413 PWCHAR KeyName;
414 PWCHAR KeyValue;
415 PWCHAR UserData;
416
417 List = CreateGenericList();
418 if (List == NULL)
419 return NULL;
420
421 if (!InfFindFirstLine (InfFile, L"Keyboard", NULL, &Context))
422 {
423 DestroyGenericList(List, FALSE);
424 return NULL;
425 }
426
427 do
428 {
429 if (!InfGetData (&Context, &KeyName, &KeyValue))
430 {
431 /* FIXME: Handle error! */
432 DPRINT("InfGetData() failed\n");
433 break;
434 }
435
436 UserData = RtlAllocateHeap(ProcessHeap,
437 0,
438 (wcslen(KeyName) + 1) * sizeof(WCHAR));
439 if (UserData == NULL)
440 {
441 /* FIXME: Handle error! */
442 }
443
444 wcscpy(UserData, KeyName);
445
446 sprintf(Buffer, "%S", KeyValue);
447 AppendGenericListEntry(List, Buffer, UserData, FALSE);
448 }
449 while (InfFindNextLine(&Context, &Context));
450
451 return List;
452 }
453
454
455 PGENERIC_LIST
456 CreateKeyboardLayoutList(HINF InfFile)
457 {
458 CHAR Buffer[128];
459 PGENERIC_LIST List;
460 INFCONTEXT Context;
461 PWCHAR KeyName;
462 PWCHAR KeyValue;
463 PWCHAR UserData;
464 WCHAR DefaultLayout[20];
465
466 /* Get default layout id */
467 if (!InfFindFirstLine (InfFile, L"NLS", L"DefaultLayout", &Context))
468 return NULL;
469
470 if (!InfGetData (&Context, NULL, &KeyValue))
471 return NULL;
472
473 wcscpy(DefaultLayout, KeyValue);
474
475 List = CreateGenericList();
476 if (List == NULL)
477 return NULL;
478
479 if (!InfFindFirstLine (InfFile, L"KeyboardLayout", NULL, &Context))
480 {
481 DestroyGenericList(List, FALSE);
482 return NULL;
483 }
484
485 do
486 {
487 if (!InfGetData (&Context, &KeyName, &KeyValue))
488 {
489 /* FIXME: Handle error! */
490 DPRINT("InfGetData() failed\n");
491 break;
492 }
493
494 UserData = RtlAllocateHeap(ProcessHeap,
495 0,
496 (wcslen(KeyName) + 1) * sizeof(WCHAR));
497 if (UserData == NULL)
498 {
499 /* FIXME: Handle error! */
500 }
501
502 wcscpy(UserData, KeyName);
503
504 sprintf(Buffer, "%S", KeyValue);
505 AppendGenericListEntry(List,
506 Buffer,
507 UserData,
508 _wcsicmp(KeyName, DefaultLayout) ? FALSE : TRUE);
509 }
510 while (InfFindNextLine(&Context, &Context));
511
512 return List;
513 }
514
515
516 BOOLEAN
517 ProcessKeyboardLayoutRegistry(PGENERIC_LIST List)
518 {
519 PGENERIC_LIST_ENTRY Entry;
520 PWCHAR LanguageId;
521 OBJECT_ATTRIBUTES ObjectAttributes;
522 UNICODE_STRING KeyName;
523 UNICODE_STRING ValueName;
524 HANDLE KeyHandle;
525 NTSTATUS Status;
526
527 Entry = GetGenericListEntry(List);
528 if (Entry == NULL)
529 return FALSE;
530
531 LanguageId = (PWCHAR)Entry->UserData;
532 if (LanguageId == NULL)
533 return FALSE;
534
535 /* Open the nls language key */
536 RtlInitUnicodeString(&KeyName,
537 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");
538 InitializeObjectAttributes(&ObjectAttributes,
539 &KeyName,
540 OBJ_CASE_INSENSITIVE,
541 NULL,
542 NULL);
543 Status = NtOpenKey(&KeyHandle,
544 KEY_ALL_ACCESS,
545 &ObjectAttributes);
546 if (!NT_SUCCESS(Status))
547 {
548 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
549 return FALSE;
550 }
551
552 /* Set default language */
553 RtlInitUnicodeString(&ValueName,
554 L"Default");
555 Status = NtSetValueKey (KeyHandle,
556 &ValueName,
557 0,
558 REG_SZ,
559 (PVOID)(LanguageId + 4),
560 8);
561 if (!NT_SUCCESS(Status))
562 {
563 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
564 NtClose(KeyHandle);
565 return FALSE;
566 }
567
568 /* Set install language */
569 RtlInitUnicodeString(&ValueName,
570 L"InstallLanguage");
571 Status = NtSetValueKey (KeyHandle,
572 &ValueName,
573 0,
574 REG_SZ,
575 (PVOID)(LanguageId + 4),
576 8);
577 if (!NT_SUCCESS(Status))
578 {
579 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
580 NtClose(KeyHandle);
581 return FALSE;
582 }
583
584 NtClose(KeyHandle);
585
586 /* Open the nls locale key */
587 RtlInitUnicodeString(&KeyName,
588 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale");
589 InitializeObjectAttributes(&ObjectAttributes,
590 &KeyName,
591 OBJ_CASE_INSENSITIVE,
592 NULL,
593 NULL);
594 Status = NtOpenKey(&KeyHandle,
595 KEY_ALL_ACCESS,
596 &ObjectAttributes);
597 if (!NT_SUCCESS(Status))
598 {
599 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
600 return FALSE;
601 }
602
603 /* Set default locale */
604 RtlInitUnicodeString(&ValueName,
605 L"(Default)");
606 Status = NtSetValueKey (KeyHandle,
607 &ValueName,
608 0,
609 REG_SZ,
610 (PVOID)LanguageId,
611 16);
612 if (!NT_SUCCESS(Status))
613 {
614 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
615 NtClose(KeyHandle);
616 return FALSE;
617 }
618
619 NtClose(KeyHandle);
620
621 return TRUE;
622 }
623
624
625 #if 0
626 BOOLEAN
627 ProcessKeyboardLayoutFiles(PGENERIC_LIST List)
628 {
629 return TRUE;
630 }
631 #endif
632
633
634 static BOOLEAN
635 GetMouseIdentifier(PWSTR ControllerType,
636 PWSTR Identifier,
637 ULONG IdentifierLength)
638 {
639 OBJECT_ATTRIBUTES ObjectAttributes;
640 UNICODE_STRING KeyName;
641 WCHAR Buffer[32];
642 HANDLE BusKey;
643 HANDLE BusInstanceKey;
644 HANDLE ControllerKey;
645 HANDLE ControllerInstanceKey;
646 HANDLE PeripheralKey;
647 HANDLE PeripheralInstanceKey;
648 ULONG BusInstance;
649 ULONG ControllerInstance;
650 ULONG PeripheralInstance;
651 ULONG BufferLength;
652 ULONG ReturnedLength;
653 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
654 NTSTATUS Status;
655
656 DPRINT("GetMouseIdentifier() called\n");
657
658 /* Open the bus key */
659 RtlInitUnicodeString(&KeyName,
660 L"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
661 InitializeObjectAttributes(&ObjectAttributes,
662 &KeyName,
663 OBJ_CASE_INSENSITIVE,
664 NULL,
665 NULL);
666 Status = NtOpenKey(&BusKey,
667 KEY_ALL_ACCESS,
668 &ObjectAttributes);
669 if (!NT_SUCCESS(Status))
670 {
671 DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
672 return FALSE;
673 }
674
675 BusInstance = 0;
676 while (TRUE)
677 {
678 swprintf(Buffer, L"%lu", BusInstance);
679 RtlInitUnicodeString(&KeyName,
680 Buffer);
681 InitializeObjectAttributes(&ObjectAttributes,
682 &KeyName,
683 OBJ_CASE_INSENSITIVE,
684 BusKey,
685 NULL);
686 Status = NtOpenKey(&BusInstanceKey,
687 KEY_ALL_ACCESS,
688 &ObjectAttributes);
689 if (!NT_SUCCESS(Status))
690 {
691 DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
692 NtClose(BusKey);
693 return FALSE;
694 }
695
696 /* Open the controller type key */
697 RtlInitUnicodeString(&KeyName,
698 ControllerType);
699 InitializeObjectAttributes(&ObjectAttributes,
700 &KeyName,
701 OBJ_CASE_INSENSITIVE,
702 BusInstanceKey,
703 NULL);
704 Status = NtOpenKey(&ControllerKey,
705 KEY_ALL_ACCESS,
706 &ObjectAttributes);
707 if (NT_SUCCESS(Status))
708 {
709 ControllerInstance = 0;
710 while (TRUE)
711 {
712 /* Open the pointer controller instance key */
713 swprintf(Buffer, L"%lu", ControllerInstance);
714 RtlInitUnicodeString(&KeyName,
715 Buffer);
716 InitializeObjectAttributes(&ObjectAttributes,
717 &KeyName,
718 OBJ_CASE_INSENSITIVE,
719 ControllerKey,
720 NULL);
721 Status = NtOpenKey(&ControllerInstanceKey,
722 KEY_ALL_ACCESS,
723 &ObjectAttributes);
724 if (!NT_SUCCESS(Status))
725 {
726 DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
727 NtClose(ControllerKey);
728 NtClose(BusInstanceKey);
729 NtClose(BusKey);
730 return FALSE;
731 }
732
733 /* Open the 'PointerPeripheral' key */
734 RtlInitUnicodeString(&KeyName,
735 L"PointerPeripheral");
736 InitializeObjectAttributes(&ObjectAttributes,
737 &KeyName,
738 OBJ_CASE_INSENSITIVE,
739 ControllerInstanceKey,
740 NULL);
741 Status = NtOpenKey(&PeripheralKey,
742 KEY_ALL_ACCESS,
743 &ObjectAttributes);
744 if (NT_SUCCESS(Status))
745 {
746 PeripheralInstance = 0;
747 while (TRUE)
748 {
749 /* Open the pointer peripheral instance key */
750 swprintf(Buffer, L"%lu", PeripheralInstance);
751 RtlInitUnicodeString(&KeyName,
752 Buffer);
753 InitializeObjectAttributes(&ObjectAttributes,
754 &KeyName,
755 OBJ_CASE_INSENSITIVE,
756 PeripheralKey,
757 NULL);
758 Status = NtOpenKey(&PeripheralInstanceKey,
759 KEY_ALL_ACCESS,
760 &ObjectAttributes);
761 if (!NT_SUCCESS(Status))
762 {
763 DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
764 NtClose(PeripheralKey);
765 NtClose(ControllerInstanceKey);
766 NtClose(ControllerKey);
767 NtClose(BusInstanceKey);
768 NtClose(BusKey);
769 return FALSE;
770 }
771
772 /* Get peripheral identifier */
773 RtlInitUnicodeString(&KeyName,
774 L"Identifier");
775
776 BufferLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
777 256 * sizeof(WCHAR);
778 ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
779 0,
780 BufferLength);
781 if (ValueInfo == NULL)
782 {
783 DPRINT("RtlAllocateHeap() failed\n");
784 NtClose(PeripheralInstanceKey);
785 NtClose(PeripheralKey);
786 NtClose(ControllerInstanceKey);
787 NtClose(ControllerKey);
788 NtClose(BusInstanceKey);
789 NtClose(BusKey);
790 return FALSE;
791 }
792
793 Status = NtQueryValueKey(PeripheralInstanceKey,
794 &KeyName,
795 KeyValuePartialInformation,
796 ValueInfo,
797 BufferLength,
798 &ReturnedLength);
799 if (NT_SUCCESS(Status))
800 {
801 DPRINT("Identifier: %S\n", (PWSTR)ValueInfo->Data);
802
803 BufferLength = min(ValueInfo->DataLength / sizeof(WCHAR), IdentifierLength);
804 RtlCopyMemory (Identifier,
805 ValueInfo->Data,
806 BufferLength * sizeof(WCHAR));
807 Identifier[BufferLength] = 0;
808
809 RtlFreeHeap(RtlGetProcessHeap(),
810 0,
811 ValueInfo);
812 NtClose(PeripheralInstanceKey);
813 NtClose(PeripheralKey);
814 NtClose(ControllerInstanceKey);
815 NtClose(ControllerKey);
816 NtClose(BusInstanceKey);
817 NtClose(BusKey);
818 return TRUE;
819 }
820
821 RtlFreeHeap(RtlGetProcessHeap(),
822 0,
823 ValueInfo);
824
825 NtClose(PeripheralInstanceKey);
826
827 PeripheralInstance++;
828 }
829
830 NtClose(PeripheralKey);
831 }
832
833 NtClose(ControllerInstanceKey);
834
835 ControllerInstance++;
836 }
837
838 NtClose(ControllerKey);
839 }
840
841 NtClose(BusInstanceKey);
842
843 BusInstance++;
844 }
845
846 NtClose(BusKey);
847
848 return FALSE;
849 }
850
851
852 PGENERIC_LIST
853 CreateMouseDriverList(HINF InfFile)
854 {
855 CHAR Buffer[128];
856 PGENERIC_LIST List;
857 INFCONTEXT Context;
858 PWCHAR KeyName;
859 PWCHAR KeyValue;
860 PWCHAR UserData;
861 WCHAR MouseIdentifier[128];
862 WCHAR MouseKey[32];
863
864 /* Get the mouse identification */
865 if (!GetMouseIdentifier(L"SerialController", MouseIdentifier, 128))
866 {
867 if (!GetMouseIdentifier(L"PointerController", MouseIdentifier, 128))
868 {
869 wcscpy (MouseIdentifier, L"NO MOUSE");
870 }
871 }
872
873 DPRINT("Mouse identifier: '%S'\n", MouseIdentifier);
874
875 /* Search for matching device identifier */
876 if (!InfFindFirstLine(InfFile, L"Map.Mouse", NULL, &Context))
877 {
878 /* FIXME: error message */
879 return NULL;
880 }
881
882 do
883 {
884 if (!InfGetDataField(&Context, 1, &KeyValue))
885 {
886 /* FIXME: Handle error! */
887 DPRINT("InfGetDataField() failed\n");
888 return NULL;
889 }
890
891 DPRINT("KeyValue: %S\n", KeyValue);
892 if (wcsstr(MouseIdentifier, KeyValue))
893 {
894 if (!InfGetDataField(&Context, 0, &KeyName))
895 {
896 /* FIXME: Handle error! */
897 DPRINT("InfGetDataField() failed\n");
898 return NULL;
899 }
900
901 DPRINT("Mouse key: %S\n", KeyName);
902 wcscpy(MouseKey, KeyName);
903 }
904 }
905 while (InfFindNextLine(&Context, &Context));
906
907
908 List = CreateGenericList();
909 if (List == NULL)
910 return NULL;
911
912 if (!InfFindFirstLine(InfFile, L"Mouse", NULL, &Context))
913 {
914 DestroyGenericList(List, FALSE);
915 return NULL;
916 }
917
918 do
919 {
920 if (!InfGetDataField(&Context, 0, &KeyName))
921 {
922 DPRINT1("InfGetDataField() failed\n");
923 break;
924 }
925
926 if (!InfGetDataField(&Context, 1, &KeyValue))
927 {
928 DPRINT1("InfGetDataField() failed\n");
929 break;
930 }
931
932 UserData = RtlAllocateHeap(ProcessHeap,
933 0,
934 (wcslen(KeyName) + 1) * sizeof(WCHAR));
935 if (UserData == NULL)
936 {
937 DPRINT1("RtlAllocateHeap() failed\n");
938 DestroyGenericList(List, TRUE);
939 return NULL;
940 }
941
942 wcscpy(UserData, KeyName);
943
944 sprintf(Buffer, "%S", KeyValue);
945 AppendGenericListEntry(List,
946 Buffer,
947 UserData,
948 _wcsicmp(KeyName, MouseKey) ? FALSE : TRUE);
949 }
950 while (InfFindNextLine(&Context, &Context));
951
952 return List;
953 }
954
955
956 BOOLEAN
957 ProcessMouseRegistry(HINF InfFile, PGENERIC_LIST List)
958 {
959 PGENERIC_LIST_ENTRY Entry;
960 INFCONTEXT Context;
961 PWCHAR ServiceName;
962 ULONG StartValue;
963 NTSTATUS Status;
964
965 DPRINT("ProcessMouseRegistry() called\n");
966
967 Entry = GetGenericListEntry(List);
968 if (Entry == NULL)
969 {
970 DPRINT("GetGenericListEntry() failed\n");
971 return FALSE;
972 }
973
974 if (!InfFindFirstLine(InfFile, L"Mouse", Entry->UserData, &Context))
975 {
976 DPRINT("InfFindFirstLine() failed\n");
977 return FALSE;
978 }
979
980 if (!InfGetDataField(&Context, 3, &ServiceName))
981 {
982 DPRINT("InfGetDataField() failed\n");
983 return FALSE;
984 }
985
986 DPRINT("Service name: %S\n", ServiceName);
987
988 StartValue = 1;
989 Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
990 ServiceName,
991 L"Start",
992 REG_DWORD,
993 &StartValue,
994 sizeof(ULONG));
995 if (!NT_SUCCESS(Status))
996 {
997 DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status);
998 return FALSE;
999 }
1000
1001 DPRINT("ProcessMouseRegistry() done\n");
1002
1003 return TRUE;
1004 }
1005
1006
1007 #if 0
1008 BOOLEAN
1009 ProcessMouseFiles(PGENERIC_LIST List)
1010 {
1011 return TRUE;
1012 }
1013 #endif
1014
1015 /* EOF */