reactos/drivers/input/i8042prt/setup.c
Amine Khaldi c424146e2c Create a branch for cmake bringup.
svn path=/branches/cmake-bringup/; revision=48236
2010-07-24 18:52:44 +00:00

152 lines
4.3 KiB
C

/*
* PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/input/i8042prt/setup.c
* PURPOSE: Create a legacy PDO during ReactOS installation
* PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
*/
/* NOTE:
* All this file is a big hack and should be removed one day...
*/
/* INCLUDES ******************************************************************/
#include "i8042prt.h"
/* GLOBALS *******************************************************************/
#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_CONTROL_PORT 0x64
#define KEYBOARD_IRQ 1
/* FUNCTIONS *****************************************************************/
BOOLEAN
IsFirstStageSetup(
VOID)
{
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hSetupKey = (HANDLE)NULL;
NTSTATUS Status;
BOOLEAN ret = TRUE;
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes);
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
ret = TRUE;
else
ret = FALSE;
if (hSetupKey != (HANDLE)NULL)
ZwClose(hSetupKey);
INFO_(I8042PRT, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO");
return ret;
}
static NTSTATUS
AddRegistryEntry(
IN PCWSTR PortTypeName,
IN PUNICODE_STRING DeviceName,
IN PCWSTR RegistryPath)
{
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hDeviceMapKey = (HANDLE)-1;
HANDLE hPortKey = (HANDLE)-1;
UNICODE_STRING PortTypeNameU;
NTSTATUS Status;
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
WARN_(I8042PRT, "ZwOpenKey() failed with status 0x%08lx\n", Status);
goto cleanup;
}
RtlInitUnicodeString(&PortTypeNameU, PortTypeName);
InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL);
Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
if (!NT_SUCCESS(Status))
{
WARN_(I8042PRT, "ZwCreateKey() failed with status 0x%08lx\n", Status);
goto cleanup;
}
Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
if (!NT_SUCCESS(Status))
{
WARN_(I8042PRT, "ZwSetValueKey() failed with status 0x%08lx\n", Status);
goto cleanup;
}
Status = STATUS_SUCCESS;
cleanup:
if (hDeviceMapKey != (HANDLE)-1)
ZwClose(hDeviceMapKey);
if (hPortKey != (HANDLE)-1)
ZwClose(hPortKey);
return Status;
}
NTSTATUS
i8042AddLegacyKeyboard(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042");
PI8042_DEVICE_TYPE DeviceExtension = NULL;
PDEVICE_OBJECT Pdo = NULL;
NTSTATUS Status;
TRACE_(I8042PRT, "i8042AddLegacyKeyboard()\n");
/* Create a named PDO */
Status = IoCreateDevice(
DriverObject,
sizeof(I8042_DEVICE_TYPE),
&KeyboardName,
FILE_DEVICE_8042_PORT,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&Pdo);
if (!NT_SUCCESS(Status))
{
WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status);
goto cleanup;
}
/* Initialize device extension */
DeviceExtension = (PI8042_DEVICE_TYPE)Pdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(I8042_DEVICE_TYPE));
*DeviceExtension = PhysicalDeviceObject;
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
/* Add FDO at the top of the PDO */
Status = i8042AddDevice(DriverObject, Pdo);
if (!NT_SUCCESS(Status))
{
WARN_(I8042PRT, "i8042AddDevice() failed with status 0x%08lx\n", Status);
goto cleanup;
}
/* We will send the IRP_MN_START_DEVICE later when kbdclass looks for legacy drivers */
AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer);
Status = STATUS_SUCCESS;
/* Yes, completly forget the Pdo pointer, as we will never
* have to unload this driver during first stage setup.
*/
cleanup:
if (!NT_SUCCESS(Status))
{
if (Pdo)
IoDeleteDevice(Pdo);
}
return Status;
}