Author: hpoussin
Date: Thu Dec 6 19:25:57 2007
New Revision: 31044
URL:
http://svn.reactos.org/svn/reactos?rev=31044&view=rev
Log:
After plug&play at 3rd boot since r18448, after plug&play in 2nd stage setup since
r22607, here is plug&play in 1st stage setup!
Added:
trunk/reactos/base/setup/usetup/interface/devinst.c (with props)
Modified:
trunk/reactos/base/setup/usetup/interface/usetup.c
trunk/reactos/base/setup/usetup/usetup.rbuild
trunk/reactos/boot/bootdata/txtsetup.sif
Added: trunk/reactos/base/setup/usetup/interface/devinst.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/interfac…
==============================================================================
--- trunk/reactos/base/setup/usetup/interface/devinst.c (added)
+++ trunk/reactos/base/setup/usetup/interface/devinst.c Thu Dec 6 19:25:57 2007
@@ -1,0 +1,396 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS text-mode setup
+ * FILE: subsys/system/usetup/interface/devinst.c
+ * PURPOSE: Device installation
+ * PROGRAMMER: Hervé Poussineau (hpoussin(a)reactos.org)
+ */
+
+#include "usetup.h"
+
+#define NDEBUG
+#include <debug.h>
+
+#define INITGUID
+#include <guiddef.h>
+#include <libs/umpnpmgr/sysguid.h>
+
+BOOLEAN
+ResetDevice(
+ IN LPCWSTR DeviceId)
+{
+ PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
+ NTSTATUS Status;
+
+ RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, DeviceId);
+ Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData,
sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtPlugPlayControl() failed with status 0x%08x\n", Status);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOLEAN
+InstallDriver(
+ IN HINF hInf,
+ IN HANDLE hServices,
+ IN HANDLE hDeviceKey,
+ IN LPCWSTR DeviceId,
+ IN LPCWSTR HardwareId)
+{
+ UNICODE_STRING PathPrefix = RTL_CONSTANT_STRING(L"System32\\DRIVERS\\");
+ UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service");
+ UNICODE_STRING ErrorControlU = RTL_CONSTANT_STRING(L"ErrorControl");
+ UNICODE_STRING ImagePathU = RTL_CONSTANT_STRING(L"ImagePath");
+ UNICODE_STRING StartU = RTL_CONSTANT_STRING(L"Start");
+ UNICODE_STRING TypeU = RTL_CONSTANT_STRING(L"Type");
+ UNICODE_STRING StringU;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hService;
+ INFCONTEXT Context;
+ LPWSTR Driver, ImagePath, FullImagePath;
+ ULONG dwValue;
+ ULONG Disposition;
+ NTSTATUS Status;
+ BOOLEAN deviceInstalled = FALSE;
+
+ /* Check if we know the hardware */
+ if (!SetupFindFirstLineW(hInf, L"HardwareIdsDatabase", HardwareId,
&Context))
+ return FALSE;
+ if (!INF_GetDataField(&Context, 1, &Driver))
+ return FALSE;
+
+ /* Find associated driver name */
+ /* FIXME: check in other sections too! */
+ if (!SetupFindFirstLineW(hInf, L"BootBusExtenders.Load", Driver,
&Context)
+ && !SetupFindFirstLineW(hInf, L"Keyboard.Load", Driver,
&Context))
+ return FALSE;
+ if (!INF_GetDataField(&Context, 1, &ImagePath))
+ return FALSE;
+
+ /* Prepare full driver path */
+ dwValue = PathPrefix.MaximumLength + wcslen(ImagePath) * sizeof(WCHAR);
+ FullImagePath = (LPWSTR)RtlAllocateHeap(ProcessHeap, 0, dwValue);
+ if (!FullImagePath)
+ {
+ DPRINT1("RtlAllocateHeap() failed\n");
+ return FALSE;
+ }
+ RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength);
+ wcscat(FullImagePath, ImagePath);
+
+ DPRINT1("Using driver '%S' for device '%S'\n", ImagePath,
DeviceId);;
+
+ /* Create service key */
+ RtlInitUnicodeString(&StringU, Driver);
+ InitializeObjectAttributes(&ObjectAttributes, &StringU, 0, hServices, NULL);
+ Status = NtCreateKey(&hService, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, 0,
&Disposition);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n",
&StringU, Status);
+ RtlFreeHeap(ProcessHeap, 0, FullImagePath);
+ return FALSE;
+ }
+
+ /* Fill service key */
+ if (Disposition == REG_CREATED_NEW_KEY)
+ {
+ dwValue = 0;
+ NtSetValueKey(
+ hService,
+ &ErrorControlU,
+ 0,
+ REG_DWORD,
+ &dwValue,
+ sizeof(dwValue));
+ dwValue = 0;
+ NtSetValueKey(
+ hService,
+ &StartU,
+ 0,
+ REG_DWORD,
+ &dwValue,
+ sizeof(dwValue));
+ dwValue = SERVICE_KERNEL_DRIVER;
+ NtSetValueKey(
+ hService,
+ &TypeU,
+ 0,
+ REG_DWORD,
+ &dwValue,
+ sizeof(dwValue));
+ }
+ /* HACK: don't put any path in registry */
+ NtSetValueKey(
+ hService,
+ &ImagePathU,
+ 0,
+ REG_SZ,
+ ImagePath,
+ (wcslen(ImagePath) + 1) * sizeof(WCHAR));
+
+ /* Associate device with the service we just filled */
+ Status = NtSetValueKey(
+ hDeviceKey,
+ &ServiceU,
+ 0,
+ REG_SZ,
+ Driver,
+ (wcslen(Driver) + 1) * sizeof(WCHAR));
+ if (NT_SUCCESS(Status))
+ {
+ /* Restart the device, so it will use the driver we registred */
+ deviceInstalled = ResetDevice(DeviceId);
+ }
+
+ /* HACK: Update driver path */
+ NtSetValueKey(
+ hService,
+ &ImagePathU,
+ 0,
+ REG_SZ,
+ FullImagePath,
+ (wcslen(FullImagePath) + 1) * sizeof(WCHAR));
+ RtlFreeHeap(ProcessHeap, 0, FullImagePath);
+ NtClose(hService);
+
+ return deviceInstalled;
+}
+
+VOID
+InstallDevice(
+ IN HINF hInf,
+ IN HANDLE hEnum,
+ IN HANDLE hServices,
+ IN LPCWSTR DeviceId)
+{
+ UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
+ UNICODE_STRING CompatibleIDsU = RTL_CONSTANT_STRING(L"CompatibleIDs");
+ UNICODE_STRING DeviceIdU;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ LPCWSTR HardwareID;
+ PKEY_VALUE_PARTIAL_INFORMATION pPartialInformation = NULL;
+ HANDLE hDeviceKey;
+ ULONG ulRequired;
+ BOOLEAN bDriverInstalled = FALSE;
+ NTSTATUS Status;
+
+ RtlInitUnicodeString(&DeviceIdU, DeviceId);
+ InitializeObjectAttributes(&ObjectAttributes, &DeviceIdU, 0, hEnum, NULL);
+ Status = NtOpenKey(&hDeviceKey, KEY_QUERY_VALUE | KEY_SET_VALUE,
&ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Unable to open subkey '%S'\n", DeviceId);
+ return;
+ }
+
+ Status = NtQueryValueKey(
+ hDeviceKey,
+ &HardwareIDU,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &ulRequired);
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ pPartialInformation =
(PKEY_VALUE_PARTIAL_INFORMATION)RtlAllocateHeap(ProcessHeap, 0, ulRequired);
+ if (!pPartialInformation)
+ {
+ DPRINT1("RtlAllocateHeap() failed\n");
+ NtClose(hDeviceKey);
+ return;
+ }
+ Status = NtQueryValueKey(
+ hDeviceKey,
+ &HardwareIDU,
+ KeyValuePartialInformation,
+ pPartialInformation,
+ ulRequired,
+ &ulRequired);
+ }
+ if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ /* Nothing to do */
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtQueryValueKey() failed with status 0x%08x\n", Status);
+ if (pPartialInformation)
+ RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
+ NtClose(hDeviceKey);
+ return;
+ }
+ else
+ {
+ for (HardwareID = (LPCWSTR)pPartialInformation->Data;
+ (PUCHAR)HardwareID < pPartialInformation->Data +
pPartialInformation->DataLength
+ && *HardwareID
+ && !bDriverInstalled;
+ HardwareID += wcslen(HardwareID) + 1)
+ {
+ bDriverInstalled = InstallDriver(hInf, hServices,hDeviceKey, DeviceId,
HardwareID);
+ }
+ }
+
+ if (!bDriverInstalled)
+ {
+ if (pPartialInformation)
+ {
+ RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
+ pPartialInformation = NULL;
+ }
+ Status = NtQueryValueKey(
+ hDeviceKey,
+ &CompatibleIDsU,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &ulRequired);
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ pPartialInformation =
(PKEY_VALUE_PARTIAL_INFORMATION)RtlAllocateHeap(ProcessHeap, 0, ulRequired);
+ if (!pPartialInformation)
+ {
+ DPRINT("RtlAllocateHeap() failed\n");
+ NtClose(hDeviceKey);
+ return;
+ }
+ Status = NtQueryValueKey(
+ hDeviceKey,
+ &CompatibleIDsU,
+ KeyValuePartialInformation,
+ pPartialInformation,
+ ulRequired,
+ &ulRequired);
+ }
+ if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ /* Nothing to do */
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ if (pPartialInformation)
+ RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
+ NtClose(hDeviceKey);
+ DPRINT1("NtQueryValueKey() failed with status 0x%08x\n", Status);
+ return;
+ }
+ else
+ {
+ for (HardwareID = (LPCWSTR)pPartialInformation->Data;
+ (PUCHAR)HardwareID < pPartialInformation->Data +
pPartialInformation->DataLength
+ && *HardwareID
+ && !bDriverInstalled;
+ HardwareID += wcslen(HardwareID) + 1)
+ {
+ bDriverInstalled = InstallDriver(hInf, hServices,hDeviceKey, DeviceId,
HardwareID);
+ }
+ }
+ }
+ if (!bDriverInstalled)
+ DPRINT("No driver available for %S\n", DeviceId);
+
+ RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
+ NtClose(hDeviceKey);
+}
+
+NTSTATUS
+EventThread(IN LPVOID lpParameter)
+{
+ UNICODE_STRING EnumU =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
+ UNICODE_STRING ServicesU =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
+ PPLUGPLAY_EVENT_BLOCK PnpEvent;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ULONG PnpEventSize;
+ HINF hInf;
+ HANDLE hEnum, hServices;
+ NTSTATUS Status;
+
+ hInf = *(HINF *)lpParameter;
+
+ InitializeObjectAttributes(&ObjectAttributes, &EnumU, OBJ_CASE_INSENSITIVE,
NULL, NULL);
+ Status = NtOpenKey(&hEnum, 0, &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtOpenKey('%wZ') failed with status 0x%08lx\n",
&EnumU, Status);
+ return Status;
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes, &ServicesU,
OBJ_CASE_INSENSITIVE, NULL, NULL);
+ Status = NtCreateKey(&hServices, 0, &ObjectAttributes, 0, NULL, 0, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateKey('%wZ') failed with status 0x%08lx\n",
&ServicesU, Status);
+ NtClose(hEnum);
+ return Status;
+ }
+
+ PnpEventSize = 0x1000;
+ PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
+ if (PnpEvent == NULL)
+ {
+ NtClose(hEnum);
+ NtClose(hServices);
+ return STATUS_NO_MEMORY;
+ }
+
+ for (;;)
+ {
+ DPRINT("Calling NtGetPlugPlayEvent()\n");
+
+ /* Wait for the next pnp event */
+ Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
+
+ /* Resize the buffer for the PnP event if it's too small. */
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ PnpEventSize += 0x400;
+ PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlReAllocateHeap(ProcessHeap, 0, PnpEvent,
PnpEventSize);
+ if (PnpEvent == NULL)
+ {
+ NtClose(hEnum);
+ NtClose(hServices);
+ return STATUS_NO_MEMORY;
+ }
+ continue;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status);
+ break;
+ }
+
+ /* Process the pnp event */
+ DPRINT("Received PnP Event\n");
+ if (IsEqualIID(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL))
+ {
+ DPRINT1("Device arrival event: %S\n",
PnpEvent->TargetDevice.DeviceIds);
+ InstallDevice(hInf, hEnum, hServices, PnpEvent->TargetDevice.DeviceIds);
+ }
+ else
+ {
+ DPRINT("Unknown event\n");
+ }
+
+ /* Dequeue the current pnp event and signal the next one */
+ NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
+ }
+
+ RtlFreeHeap(ProcessHeap, 0, PnpEvent);
+ NtClose(hEnum);
+ NtClose(hServices);
+
+ return STATUS_SUCCESS;
+}
+
+DWORD WINAPI
+PnpEventThread(IN LPVOID lpParameter)
+{
+ NTSTATUS Status;
+ Status = EventThread(lpParameter);
+ NtTerminateThread(NtCurrentThread(), Status);
+ return 0;
+}
Propchange: trunk/reactos/base/setup/usetup/interface/devinst.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/base/setup/usetup/interface/usetup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/interfac…
==============================================================================
--- trunk/reactos/base/setup/usetup/interface/usetup.c (original)
+++ trunk/reactos/base/setup/usetup/interface/usetup.c Thu Dec 6 19:25:57 2007
@@ -84,6 +84,7 @@
LONG AutoPartition = 0;
WCHAR UnattendInstallationDirectory[MAX_PATH];
BOOLEAN RepairUpdateFlag = FALSE;
+HANDLE hPnpThread = INVALID_HANDLE_VALUE;
/* LOCALS *******************************************************************/
@@ -697,6 +698,13 @@
"ENTER = Reboot computer",
Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
+ }
+
+ /* Start PnP thread */
+ if (hPnpThread != INVALID_HANDLE_VALUE)
+ {
+ NtResumeThread(hPnpThread, NULL);
+ hPnpThread = INVALID_HANDLE_VALUE;
}
CheckUnattendedSetup();
@@ -3630,15 +3638,22 @@
}
+DWORD WINAPI
+PnpEventThread(IN LPVOID lpParameter);
+
VOID
RunUSetup(VOID)
{
INPUT_RECORD Ir;
PAGE_NUMBER Page;
LARGE_INTEGER Time;
+ NTSTATUS Status;
NtQuerySystemTime(&Time);
+ Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, PnpEventThread,
&SetupInf, &hPnpThread, NULL);
+ if (!NT_SUCCESS(Status))
+ hPnpThread = INVALID_HANDLE_VALUE;
if (!CONSOLE_Init())
{
PrintString("Unable to open the console\n\n");
Modified: trunk/reactos/base/setup/usetup/usetup.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/usetup.r…
==============================================================================
--- trunk/reactos/base/setup/usetup/usetup.rbuild (original)
+++ trunk/reactos/base/setup/usetup/usetup.rbuild Thu Dec 6 19:25:57 2007
@@ -16,6 +16,7 @@
<library>ntdll</library>
<directory name="interface">
<file>consup.c</file>
+ <file>devinst.c</file>
<file>usetup.c</file>
</directory>
<directory name="native">
Modified: trunk/reactos/boot/bootdata/txtsetup.sif
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/txtsetup.sif…
==============================================================================
--- trunk/reactos/boot/bootdata/txtsetup.sif (original)
+++ trunk/reactos/boot/bootdata/txtsetup.sif Thu Dec 6 19:25:57 2007
@@ -29,11 +29,19 @@
kbdclass.sys=,,,,,,x,,,,,,4
l_intl.nls=,,,,,,,,,,,,2
ntfs.sys=,,,,,,,,,,,,4
-ntoskrnl.exe=,,,,,,,,,,,,2
pci.sys=,,,,,,,,,,,,4
scsiport.sys=,,,,,,x,,,,,,4
uniata.sys=,,,,,,,,,,,,4
vfatfs.sys=,,,,,,,,,,,,4
+
+[HardwareIdsDatabase]
+*PNP0C08 = acpi
+*PNP0A03 = pci
+PCI\CC_0604 = pci
+
+[BootBusExtenders.Load]
+acpi = acpi.sys
+pci = pci.sys
[Cabinets]
Cabinet=reactos.cab