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 UpperFiltersU = RTL_CONSTANT_STRING(L"UpperFilters");
+ PWSTR keyboardClass = L"kbdclass\0";
+
UNICODE_STRING StringU;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hService;
INFCONTEXT Context;
- LPWSTR Driver, ClassGuid, ImagePath, FullImagePath;
+ PCWSTR Driver, ClassGuid, ImagePath;
+ PWSTR FullImagePath;
ULONG dwValue;
ULONG Disposition;
NTSTATUS Status;
BOOLEAN deviceInstalled = FALSE;
- UNICODE_STRING UpperFiltersU = RTL_CONSTANT_STRING(L"UpperFilters");
- LPWSTR keyboardClass = L"kbdclass\0";
/* Check if we know the hardware */
- if (!SetupFindFirstLineW(hInf, L"HardwareIdsDatabase", HardwareId, &Context))
+ if (!SpInfFindFirstLine(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"BusExtenders.Load", Driver, &Context)
- && !SetupFindFirstLineW(hInf, L"SCSI.Load", Driver, &Context)
- && !SetupFindFirstLineW(hInf, L"InputDevicesSupport.Load", Driver, &Context)
- && !SetupFindFirstLineW(hInf, L"Keyboard.Load", Driver, &Context))
+ if (!SpInfFindFirstLine(hInf, L"BootBusExtenders.Load", Driver, &Context)
+ && !SpInfFindFirstLine(hInf, L"BusExtenders.Load", Driver, &Context)
+ && !SpInfFindFirstLine(hInf, L"SCSI.Load", Driver, &Context)
+ && !SpInfFindFirstLine(hInf, L"InputDevicesSupport.Load", Driver, &Context)
+ && !SpInfFindFirstLine(hInf, L"Keyboard.Load", Driver, &Context))
{
+ INF_FreeData(ClassGuid);
+ INF_FreeData(Driver);
return FALSE;
}
if (!INF_GetDataField(&Context, 1, &ImagePath))
+ {
+ INF_FreeData(ClassGuid);
+ INF_FreeData(Driver);
return FALSE;
+ }
/* Prepare full driver path */
dwValue = PathPrefix.MaximumLength + wcslen(ImagePath) * sizeof(WCHAR);
- FullImagePath = (LPWSTR)RtlAllocateHeap(ProcessHeap, 0, dwValue);
+ FullImagePath = (PWSTR)RtlAllocateHeap(ProcessHeap, 0, dwValue);
if (!FullImagePath)
{
DPRINT1("RtlAllocateHeap() failed\n");
+ INF_FreeData(ImagePath);
+ INF_FreeData(ClassGuid);
+ INF_FreeData(Driver);
return FALSE;
}
RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength);
- wcscat(FullImagePath, ImagePath);
+ ConcatPaths(FullImagePath, dwValue / sizeof(WCHAR), 1, 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);
+ InitializeObjectAttributes(&ObjectAttributes, &StringU, OBJ_CASE_INSENSITIVE, hServices, NULL);
+ Status = NtCreateKey(&hService, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n", &StringU, Status);
RtlFreeHeap(ProcessHeap, 0, FullImagePath);
+ INF_FreeData(ImagePath);
+ INF_FreeData(ClassGuid);
+ INF_FreeData(Driver);
return FALSE;
}
if (Disposition == REG_CREATED_NEW_KEY)
{
dwValue = 0;
- NtSetValueKey(
- hService,
- &ErrorControlU,
- 0,
- REG_DWORD,
- &dwValue,
- sizeof(dwValue));
+ NtSetValueKey(hService,
+ &ErrorControlU,
+ 0,
+ REG_DWORD,
+ &dwValue,
+ sizeof(dwValue));
+
dwValue = 0;
- NtSetValueKey(
- hService,
- &StartU,
- 0,
- REG_DWORD,
- &dwValue,
- sizeof(dwValue));
+ NtSetValueKey(hService,
+ &StartU,
+ 0,
+ REG_DWORD,
+ &dwValue,
+ sizeof(dwValue));
+
dwValue = SERVICE_KERNEL_DRIVER;
- NtSetValueKey(
- hService,
- &TypeU,
- 0,
- REG_DWORD,
- &dwValue,
- sizeof(dwValue));
+ 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));
+ NtSetValueKey(hService,
+ &ImagePathU,
+ 0,
+ REG_SZ,
+ (PVOID)ImagePath,
+ (wcslen(ImagePath) + 1) * sizeof(WCHAR));
+
+ INF_FreeData(ImagePath);
if (ClassGuid &&_wcsicmp(ClassGuid, L"{4D36E96B-E325-11CE-BFC1-08002BE10318}") == 0)
{
(wcslen(keyboardClass) + 2) * sizeof(WCHAR));
}
+ INF_FreeData(ClassGuid);
+
/* Associate device with the service we just filled */
- Status = NtSetValueKey(
- hDeviceKey,
- &ServiceU,
- 0,
- REG_SZ,
- Driver,
- (wcslen(Driver) + 1) * sizeof(WCHAR));
+ Status = NtSetValueKey(hDeviceKey,
+ &ServiceU,
+ 0,
+ REG_SZ,
+ (PVOID)Driver,
+ (wcslen(Driver) + 1) * sizeof(WCHAR));
if (NT_SUCCESS(Status))
{
/* Restart the device, so it will use the driver we registered */
deviceInstalled = ResetDevice(DeviceId);
}
+ INF_FreeData(Driver);
+
/* HACK: Update driver path */
- NtSetValueKey(
- hService,
- &ImagePathU,
- 0,
- REG_SZ,
- FullImagePath,
- (wcslen(FullImagePath) + 1) * sizeof(WCHAR));
+ NtSetValueKey(hService,
+ &ImagePathU,
+ 0,
+ REG_SZ,
+ FullImagePath,
+ (wcslen(FullImagePath) + 1) * sizeof(WCHAR));
RtlFreeHeap(ProcessHeap, 0, FullImagePath);
+
NtClose(hService);
return deviceInstalled;
{
UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
UNICODE_STRING CompatibleIDsU = RTL_CONSTANT_STRING(L"CompatibleIDs");
+
UNICODE_STRING DeviceIdU;
OBJECT_ATTRIBUTES ObjectAttributes;
LPCWSTR HardwareID;
NTSTATUS Status;
RtlInitUnicodeString(&DeviceIdU, DeviceId);
- InitializeObjectAttributes(&ObjectAttributes, &DeviceIdU, 0, hEnum, NULL);
+ InitializeObjectAttributes(&ObjectAttributes, &DeviceIdU, OBJ_CASE_INSENSITIVE, hEnum, NULL);
Status = NtOpenKey(&hDeviceKey, KEY_QUERY_VALUE | KEY_SET_VALUE, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
{
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;
+
+ PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG PnpEventSize;
HINF hInf;
HANDLE hEnum, hServices;
NTSTATUS Status;
- hInf = *(HINF *)lpParameter;
+ hInf = *(HINF*)lpParameter;
InitializeObjectAttributes(&ObjectAttributes, &EnumU, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = NtOpenKey(&hEnum, KEY_QUERY_VALUE, &ObjectAttributes);
}
InitializeObjectAttributes(&ObjectAttributes, &ServicesU, OBJ_CASE_INSENSITIVE, NULL, NULL);
- Status = NtCreateKey(&hServices, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL);
+ Status = NtCreateKey(&hServices, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateKey('%wZ') failed with status 0x%08lx\n", &ServicesU, Status);
}
PnpEventSize = 0x1000;
- PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
+ PnpEvent = RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
if (PnpEvent == NULL)
{
- NtClose(hEnum);
- NtClose(hServices);
- return STATUS_NO_MEMORY;
+ Status = STATUS_NO_MEMORY;
+ goto Quit;
}
for (;;)
{
DPRINT("Calling NtGetPlugPlayEvent()\n");
- /* Wait for the next pnp event */
+ /* Wait for the next PnP event */
Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
- /* Resize the buffer for the PnP event if it's too small. */
+ /* Resize the buffer for the PnP event if it's too small */
if (Status == STATUS_BUFFER_TOO_SMALL)
{
PnpEventSize += 0x400;
- RtlFreeHeap(ProcessHeap, 0, PnpEvent);
- PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
- if (PnpEvent == NULL)
+ NewPnpEvent = RtlReAllocateHeap(ProcessHeap, 0, PnpEvent, PnpEventSize);
+ if (NewPnpEvent == NULL)
{
- NtClose(hEnum);
- NtClose(hServices);
- return STATUS_NO_MEMORY;
+ Status = STATUS_NO_MEMORY;
+ goto Quit;
}
+ PnpEvent = NewPnpEvent;
continue;
}
break;
}
- /* Process the pnp event */
+ /* Process the PnP event */
DPRINT("Received PnP Event\n");
if (IsEqualIID(&PnpEvent->EventGuid, (REFGUID)&GUID_DEVICE_ENUMERATED))
{
DPRINT("Unknown event\n");
}
- /* Dequeue the current pnp event and signal the next one */
+ /* Dequeue the current PnP event and signal the next one */
NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
}
- RtlFreeHeap(ProcessHeap, 0, PnpEvent);
- NtClose(hEnum);
+ Status = STATUS_SUCCESS;
+
+Quit:
+ if (PnpEvent)
+ RtlFreeHeap(ProcessHeap, 0, PnpEvent);
+
NtClose(hServices);
+ NtClose(hEnum);
- return STATUS_SUCCESS;
+ return Status;
}
DWORD WINAPI