Implement mouse driver autodetection and installation.
authorEric Kohl <eric.kohl@reactos.org>
Mon, 7 Jun 2004 12:24:00 +0000 (12:24 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 7 Jun 2004 12:24:00 +0000 (12:24 +0000)
svn path=/trunk/; revision=9640

reactos/Makefile
reactos/bootdata/hiveinst.inf [new file with mode: 0644]
reactos/bootdata/hivesys.inf
reactos/bootdata/txtsetup.sif
reactos/subsys/system/usetup/console.c
reactos/subsys/system/usetup/settings.c
reactos/subsys/system/usetup/settings.h
reactos/subsys/system/usetup/usetup.c

index db3d625..27e64d5 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.228 2004/06/05 13:39:02 chorns Exp $
+# $Id: Makefile,v 1.229 2004/06/07 12:24:00 ekohl Exp $
 #
 # Global makefile
 #
@@ -228,7 +228,7 @@ ubootcd: bootcd_basic ubootcd_unattend bootcd_makecd
 livecd: livecd_basic livecd_makecd
 
 registry: tools
-       $(TOOLS_PATH)/mkhive/mkhive$(EXE_POSTFIX) bootdata $(INSTALL_DIR)/system32/config
+       $(TOOLS_PATH)/mkhive/mkhive$(EXE_POSTFIX) bootdata $(INSTALL_DIR)/system32/config bootdata/hiveinst.inf
 
 .PHONY: all depends implib clean clean_before install freeldr bootcd_directory_layout \
 bootcd_bootstrap_files bootcd_install_before bootcd_basic bootcd_makecd ubootcd_unattend bootcd
diff --git a/reactos/bootdata/hiveinst.inf b/reactos/bootdata/hiveinst.inf
new file mode 100644 (file)
index 0000000..362628c
--- /dev/null
@@ -0,0 +1,15 @@
+[Version]
+Signature = "$ReactOS$"
+
+[AddReg]
+; Enable _one_ driver per section by removing the leading semicolon.
+
+;
+; Mouse driver section
+;
+
+; PS/2 mouse port driver
+HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","Start",0x00010001,0x00000001
+
+; Serial mouse driver
+;HKLM,"SYSTEM\CurrentControlSet\Services\Sermouse","Start",0x00010001,0x00000001
index db1ce60..a5314ab 100644 (file)
@@ -495,7 +495,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Pice","Type",0x00010001,0x00000001
 HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","ErrorControl",0x00010001,0x00000000
 HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","Group",0x00000000,"Pointer Port"
 HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","ImagePath",0x00020000,"system32\drivers\psaux.sys"
-HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","Start",0x00010001,0x00000001
+HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","Start",0x00010001,0x00000004
 HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","Type",0x00010001,0x00000001
 HKLM,"SYSTEM\CurrentControlSet\Services\Psaux\Parameters","DisableExtensionDetection",0x00010001,0x00000000
 
index daec1ee..7740f50 100644 (file)
@@ -73,8 +73,19 @@ Default = "XT-, AT- or extended keyboard (83-105 keys)"
 00000809 = kgbgb.dll
 
 [Mouse]
-ps2mouse = "Mouse Port mouse (PS/2 mouse)"
-sermouse = "Serial mouse"
+;<id> = <user friendly name>,<spare>,<service key name>
+msps2 = "Microsoft PS2 Mouse",,psaux
+msser = "Microsoft Serial Mouse",,sermouse
+mswhs = "Microsoft Serial Wheel Mouse",,sermouse
+none  = "No Mouse"
+
+[Map.Mouse]
+;<id> = <pnp id string>
+msps2 = "MICROSOFT PS2 MOUSE"
+msser = "MICROSOFT SERIAL MOUSE"
+mswhs = "MICROSOFT MOUSE WITH WHEEL"
+none  = "NO MOUSE"
+
 
 [HiveInfs.Install]
 AddReg=hivecls.inf,AddReg
index ea6e546..d14f174 100644 (file)
@@ -108,7 +108,7 @@ AllocConsole(VOID)
 VOID
 FreeConsole(VOID)
 {
-  DPRINT1("FreeConsole() called\n");
+  DPRINT("FreeConsole() called\n");
 
   if (StdInput != INVALID_HANDLE_VALUE)
     NtClose(StdInput);
@@ -116,7 +116,7 @@ FreeConsole(VOID)
   if (StdOutput != INVALID_HANDLE_VALUE)
     NtClose(StdOutput);
 
-  DPRINT1("FreeConsole() done\n");
+  DPRINT("FreeConsole() done\n");
 }
 
 
index b5ed512..b44191c 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: settings.c,v 1.2 2004/06/02 22:18:06 ekohl Exp $
+/* $Id: settings.c,v 1.3 2004/06/07 12:21:36 ekohl Exp $
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS text-mode setup
  * FILE:            subsys/system/usetup/settings.c
@@ -28,6 +28,7 @@
 
 #include <ddk/ntddk.h>
 #include <ntdll/rtl.h>
+#include <ntos/minmax.h>
 
 #include "usetup.h"
 #include "infcache.h"
@@ -356,11 +357,231 @@ ProcessKeyboardLayoutRegistry(PGENERIC_LIST List)
 }
 
 
+#if 0
 BOOLEAN
 ProcessKeyboardLayoutFiles(PGENERIC_LIST List)
 {
   return TRUE;
 }
+#endif
+
+
+static BOOLEAN
+GetMouseIdentifier(PWSTR ControllerType,
+                  PWSTR Identifier,
+                  ULONG IdentifierLength)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  UNICODE_STRING KeyName;
+  WCHAR Buffer[32];
+  HANDLE BusKey;
+  HANDLE BusInstanceKey;
+  HANDLE ControllerKey;
+  HANDLE ControllerInstanceKey;
+  HANDLE PeripheralKey;
+  HANDLE PeripheralInstanceKey;
+  ULONG BusInstance;
+  ULONG ControllerInstance;
+  ULONG PeripheralInstance;
+  ULONG BufferLength;
+  ULONG ReturnedLength;
+  PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
+  NTSTATUS Status;
+
+  DPRINT("GetMouseIdentifier() called\n");
+
+  /* Open the bus key */
+  RtlInitUnicodeString(&KeyName,
+                      L"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &KeyName,
+                            OBJ_CASE_INSENSITIVE,
+                            NULL,
+                            NULL);
+  Status = NtOpenKey(&BusKey,
+                    KEY_ALL_ACCESS,
+                    &ObjectAttributes);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
+      return FALSE;
+    }
+
+  BusInstance = 0;
+  while (TRUE)
+    {
+      swprintf(Buffer, L"%lu", BusInstance);
+      RtlInitUnicodeString(&KeyName,
+                          Buffer);
+      InitializeObjectAttributes(&ObjectAttributes,
+                                &KeyName,
+                                OBJ_CASE_INSENSITIVE,
+                                BusKey,
+                                NULL);
+      Status = NtOpenKey(&BusInstanceKey,
+                        KEY_ALL_ACCESS,
+                        &ObjectAttributes);
+      if (!NT_SUCCESS(Status))
+       {
+         DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
+         NtClose(BusKey);
+         return FALSE;
+       }
+
+      /* Open the controller type key */
+      RtlInitUnicodeString(&KeyName,
+                          ControllerType);
+      InitializeObjectAttributes(&ObjectAttributes,
+                                &KeyName,
+                                OBJ_CASE_INSENSITIVE,
+                                BusInstanceKey,
+                                NULL);
+      Status = NtOpenKey(&ControllerKey,
+                        KEY_ALL_ACCESS,
+                        &ObjectAttributes);
+      if (NT_SUCCESS(Status))
+       {
+         ControllerInstance = 0;
+         while (TRUE)
+           {
+             /* Open the pointer controller instance key */
+             swprintf(Buffer, L"%lu", ControllerInstance);
+             RtlInitUnicodeString(&KeyName,
+                                  Buffer);
+             InitializeObjectAttributes(&ObjectAttributes,
+                                        &KeyName,
+                                        OBJ_CASE_INSENSITIVE,
+                                        ControllerKey,
+                                        NULL);
+             Status = NtOpenKey(&ControllerInstanceKey,
+                                KEY_ALL_ACCESS,
+                                &ObjectAttributes);
+             if (!NT_SUCCESS(Status))
+               {
+                 DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
+                 NtClose(ControllerKey);
+                 NtClose(BusInstanceKey);
+                 NtClose(BusKey);
+                 return FALSE;
+               }
+
+             /* Open the 'PointerPeripheral' key */
+             RtlInitUnicodeString(&KeyName,
+                                  L"PointerPeripheral");
+             InitializeObjectAttributes(&ObjectAttributes,
+                                        &KeyName,
+                                        OBJ_CASE_INSENSITIVE,
+                                        ControllerInstanceKey,
+                                        NULL);
+             Status = NtOpenKey(&PeripheralKey,
+                                KEY_ALL_ACCESS,
+                                &ObjectAttributes);
+             if (NT_SUCCESS(Status))
+               {
+                 PeripheralInstance = 0;
+                 while (TRUE)
+                   {
+                     /* Open the pointer peripheral instance key */
+                     swprintf(Buffer, L"%lu", PeripheralInstance);
+                     RtlInitUnicodeString(&KeyName,
+                                          Buffer);
+                     InitializeObjectAttributes(&ObjectAttributes,
+                                                &KeyName,
+                                                OBJ_CASE_INSENSITIVE,
+                                                PeripheralKey,
+                                                NULL);
+                     Status = NtOpenKey(&PeripheralInstanceKey,
+                                        KEY_ALL_ACCESS,
+                                        &ObjectAttributes);
+                     if (!NT_SUCCESS(Status))
+                       {
+                         DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
+                         NtClose(PeripheralKey);
+                         NtClose(ControllerInstanceKey);
+                         NtClose(ControllerKey);
+                         NtClose(BusInstanceKey);
+                         NtClose(BusKey);
+                         return FALSE;
+                       }
+
+                     /* Get peripheral identifier */
+                     RtlInitUnicodeString(&KeyName,
+                                          L"Identifier");
+
+                     BufferLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
+                                    256 * sizeof(WCHAR);
+                     ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
+                                                 0,
+                                                 BufferLength);
+                     if (ValueInfo == NULL)
+                       {
+                         DPRINT("RtlAllocateHeap() failed\n");
+                         NtClose(PeripheralInstanceKey);
+                         NtClose(PeripheralKey);
+                         NtClose(ControllerInstanceKey);
+                         NtClose(ControllerKey);
+                         NtClose(BusInstanceKey);
+                         NtClose(BusKey);
+                         return FALSE;
+                       }
+
+                     Status = NtQueryValueKey(PeripheralInstanceKey,
+                                              &KeyName,
+                                              KeyValuePartialInformation,
+                                              ValueInfo,
+                                              BufferLength,
+                                              &ReturnedLength);
+                     if (NT_SUCCESS(Status))
+                       {
+                         DPRINT("Identifier: %S\n", (PWSTR)ValueInfo->Data);
+
+                         BufferLength = min(ValueInfo->DataLength / sizeof(WCHAR), IdentifierLength);
+                         RtlCopyMemory (Identifier,
+                                        ValueInfo->Data,
+                                        BufferLength * sizeof(WCHAR));
+                         Identifier[BufferLength] = 0;
+
+                         RtlFreeHeap(RtlGetProcessHeap(),
+                                     0,
+                                     ValueInfo);
+                         NtClose(PeripheralInstanceKey);
+                         NtClose(PeripheralKey);
+                         NtClose(ControllerInstanceKey);
+                         NtClose(ControllerKey);
+                         NtClose(BusInstanceKey);
+                         NtClose(BusKey);
+                         return TRUE;
+                       }
+
+                     RtlFreeHeap(RtlGetProcessHeap(),
+                                 0,
+                                 ValueInfo);
+
+                     NtClose(PeripheralInstanceKey);
+
+                     PeripheralInstance++;
+                   }
+
+                 NtClose(PeripheralKey);
+               }
+
+             NtClose(ControllerInstanceKey);
+
+             ControllerInstance++;
+           }
+
+         NtClose(ControllerKey);
+       }
+
+      NtClose(BusInstanceKey);
+
+      BusInstance++;
+    }
+
+  NtClose(BusKey);
+
+  return FALSE;
+}
 
 
 PGENERIC_LIST
@@ -372,12 +593,58 @@ CreateMouseDriverList(HINF InfFile)
   PWCHAR KeyName;
   PWCHAR KeyValue;
   PWCHAR UserData;
+  WCHAR MouseIdentifier[128];
+  WCHAR MouseKey[32];
+
+  /* Get the mouse identification */
+  if (!GetMouseIdentifier(L"SerialController", MouseIdentifier, 128))
+    {
+      if (!GetMouseIdentifier(L"PointerController", MouseIdentifier, 128))
+       {
+         wcscpy (MouseIdentifier, L"NO MOUSE");
+       }
+    }
+
+  DPRINT("Mouse identifier: '%S'\n", MouseIdentifier);
+
+  /* Search for matching device identifier */
+  if (!InfFindFirstLine(InfFile, L"Map.Mouse", NULL, &Context))
+    {
+      /* FIXME: error message */
+      return NULL;
+    }
+
+  do
+    {
+      if (!InfGetDataField(&Context, 1, &KeyValue))
+       {
+         /* FIXME: Handle error! */
+         DPRINT("InfGetDataField() failed\n");
+         return NULL;
+       }
+
+      DPRINT("KeyValue: %S\n", KeyValue);
+      if (wcsstr(MouseIdentifier, KeyValue))
+       {
+         if (!InfGetDataField(&Context, 0, &KeyName))
+           {
+             /* FIXME: Handle error! */
+             DPRINT("InfGetDataField() failed\n");
+             return NULL;
+           }
+
+         DPRINT("Mouse key: %S\n", KeyName);
+         wcscpy(MouseKey, KeyName);
+       }
+    }
+  while (InfFindNextLine(&Context, &Context));
+
 
   List = CreateGenericList();
   if (List == NULL)
     return NULL;
 
-  if (!InfFindFirstLine (InfFile, L"Mouse", NULL, &Context))
+  if (!InfFindFirstLine(InfFile, L"Mouse", NULL, &Context))
     {
       DestroyGenericList(List, FALSE);
       return NULL;
@@ -385,10 +652,15 @@ CreateMouseDriverList(HINF InfFile)
 
   do
     {
-      if (!InfGetData (&Context, &KeyName, &KeyValue))
+      if (!InfGetDataField(&Context, 0, &KeyName))
        {
-         /* FIXME: Handle error! */
-         DPRINT("InfGetData() failed\n");
+         DPRINT1("InfGetDataField() failed\n");
+         break;
+       }
+
+      if (!InfGetDataField(&Context, 1, &KeyValue))
+       {
+         DPRINT1("InfGetDataField() failed\n");
          break;
        }
 
@@ -397,17 +669,82 @@ CreateMouseDriverList(HINF InfFile)
                                 (wcslen(KeyName) + 1) * sizeof(WCHAR));
       if (UserData == NULL)
        {
-         /* FIXME: Handle error! */
+         DPRINT1("RtlAllocateHeap() failed\n");
+         DestroyGenericList(List, TRUE);
+         return NULL;
        }
 
       wcscpy(UserData, KeyName);
 
       sprintf(Buffer, "%S", KeyValue);
-      AppendGenericListEntry(List, Buffer, UserData, FALSE);
+      AppendGenericListEntry(List,
+                            Buffer,
+                            UserData,
+                            _wcsicmp(KeyName, MouseKey) ? FALSE : TRUE);
     }
   while (InfFindNextLine(&Context, &Context));
 
   return List;
 }
 
+
+BOOLEAN
+ProcessMouseRegistry(HINF InfFile, PGENERIC_LIST List)
+{
+  PGENERIC_LIST_ENTRY Entry;
+  INFCONTEXT Context;
+  PWCHAR ServiceName;
+  ULONG StartValue;
+  NTSTATUS Status;
+
+  DPRINT("ProcessMouseRegistry() called\n");
+
+  Entry = GetGenericListEntry(List);
+  if (Entry == NULL)
+    {
+      DPRINT("GetGenericListEntry() failed\n");
+      return FALSE;
+    }
+
+  if (!InfFindFirstLine(InfFile, L"Mouse", Entry->UserData, &Context))
+    {
+      DPRINT("InfFindFirstLine() failed\n");
+      return FALSE;
+    }
+
+  if (!InfGetDataField(&Context, 3, &ServiceName))
+    {
+      DPRINT("InfGetDataField() failed\n");
+      return FALSE;
+    }
+
+  DPRINT("Service name: %S\n", ServiceName);
+
+  StartValue = 1;
+  Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
+                                ServiceName,
+                                L"Start",
+                                REG_DWORD,
+                                &StartValue,
+                                sizeof(ULONG));
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status);
+      return FALSE;
+    }
+
+  DPRINT("ProcessMouseRegistry() done\n");
+
+  return TRUE;
+}
+
+
+#if 0
+BOOLEAN
+ProcessMouseFiles(PGENERIC_LIST List)
+{
+  return TRUE;
+}
+#endif
+
 /* EOF */
index 1ca3155..7d93996 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: settings.h,v 1.1 2004/05/30 14:54:02 ekohl Exp $
+/* $Id: settings.h,v 1.2 2004/06/07 12:21:37 ekohl Exp $
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS text-mode setup
  * FILE:            subsys/system/usetup/settings.h
@@ -48,6 +48,9 @@ ProcessKeyboardLayoutFiles(PGENERIC_LIST List);
 PGENERIC_LIST
 CreateMouseDriverList(HINF InfFile);
 
+BOOLEAN
+ProcessMouseRegistry(HINF InfFile, PGENERIC_LIST List);
+
 #endif /* __SETTINGS_H__ */
 
 /* EOF */
index 66db83a..65970f1 100644 (file)
@@ -3145,7 +3145,7 @@ RegistryPage(PINPUT_RECORD Ir)
       InfGetDataField (&InfContext, 1, &File);
       InfGetDataField (&InfContext, 2, &Section);
 
-      DPRINT1("Action: %S  File: %S  Section %S\n", Action, File, Section);
+      DPRINT("Action: %S  File: %S  Section %S\n", Action, File, Section);
 
       if (!_wcsicmp (Action, L"AddReg"))
        {
@@ -3200,6 +3200,24 @@ RegistryPage(PINPUT_RECORD Ir)
        }
     }
 
+  /* Update mouse registry settings */
+  SetStatusText("   Updating mouse registry settings...");
+  if (!ProcessMouseRegistry(SetupInf, PointerList))
+    {
+      PopupError("Setup failed to update mouse registry settings.",
+                "ENTER = Reboot computer");
+
+      while(TRUE)
+       {
+         ConInKey(Ir);
+
+         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
+           {
+             return QUIT_PAGE;
+           }
+       }
+    }
+
   SetStatusText("   Done...");
 
   return BOOT_LOADER_PAGE;