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