2 * PROJECT: ReactOS Keyboard class driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/kbdclass/setup.c
5 * PURPOSE: Create a legacy PDO during ReactOS installation
6 * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
10 * All this file is a big hack and should be removed one day...
13 /* INCLUDES ******************************************************************/
17 /* GLOBALS *******************************************************************/
19 #define KEYBOARD_DATA_PORT 0x60
20 #define KEYBOARD_CONTROL_PORT 0x64
21 #define KEYBOARD_IRQ 1
23 /* FUNCTIONS *****************************************************************/
29 UNICODE_STRING PathU
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup");
30 OBJECT_ATTRIBUTES ObjectAttributes
;
31 HANDLE hSetupKey
= (HANDLE
)NULL
;
35 InitializeObjectAttributes(&ObjectAttributes
, &PathU
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
36 Status
= ZwOpenKey(&hSetupKey
, KEY_QUERY_VALUE
, &ObjectAttributes
);
38 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
43 if (hSetupKey
!= (HANDLE
)NULL
)
45 INFO_(CLASS_NAME
, "IsFirstStageSetup() returns %s\n", ret
? "YES" : "NO");
51 IN PDRIVER_OBJECT DriverObject
,
52 IN PDEVICE_OBJECT Pdo
)
54 PCM_RESOURCE_LIST AllocatedResources
= NULL
;
55 PCM_RESOURCE_LIST AllocatedResourcesTranslated
= NULL
;
56 PDEVICE_OBJECT TopDeviceObject
= NULL
;
58 IO_STATUS_BLOCK IoStatusBlock
;
60 PIO_STACK_LOCATION Stack
;
61 ULONG ResourceListSize
;
64 TRACE_(CLASS_NAME
, "SendStartDevice(%p)\n", Pdo
);
66 /* Create default resource list */
67 ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
68 AllocatedResources
= ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, CLASS_TAG
);
69 if (!AllocatedResources
)
71 WARN_(CLASS_NAME
, "ExAllocatePoolWithTag() failed\n");
72 Status
= STATUS_NO_MEMORY
;
75 AllocatedResources
->Count
= 1;
76 AllocatedResources
->List
[0].PartialResourceList
.Version
= 1;
77 AllocatedResources
->List
[0].PartialResourceList
.Revision
= 1;
78 AllocatedResources
->List
[0].PartialResourceList
.Count
= 3;
80 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[0].Type
= CmResourceTypePort
;
81 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[0].ShareDisposition
= CmResourceShareDeviceExclusive
;
82 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[0].Flags
= 0; /* FIXME */
83 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[0].u
.Port
.Start
.u
.HighPart
= 0;
84 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[0].u
.Port
.Start
.u
.LowPart
= KEYBOARD_DATA_PORT
;
85 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[0].u
.Port
.Length
= 1;
87 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[1].Type
= CmResourceTypePort
;
88 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[1].ShareDisposition
= CmResourceShareDeviceExclusive
;
89 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[1].Flags
= 0; /* FIXME */
90 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[1].u
.Port
.Start
.u
.HighPart
= 0;
91 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[1].u
.Port
.Start
.u
.LowPart
= KEYBOARD_CONTROL_PORT
;
92 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[1].u
.Port
.Length
= 1;
94 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[2].Type
= CmResourceTypeInterrupt
;
95 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[2].ShareDisposition
= CmResourceShareDeviceExclusive
;
96 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[2].Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
97 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[2].u
.Interrupt
.Level
= KEYBOARD_IRQ
;
98 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[2].u
.Interrupt
.Vector
= 0;
99 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[2].u
.Interrupt
.Affinity
= (KAFFINITY
)-1;
101 /* Create default resource list translated */
102 AllocatedResourcesTranslated
= ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, CLASS_TAG
);
103 if (!AllocatedResourcesTranslated
)
105 WARN_(CLASS_NAME
, "ExAllocatePoolWithTag() failed\n");
106 Status
= STATUS_NO_MEMORY
;
109 RtlCopyMemory(AllocatedResourcesTranslated
, AllocatedResources
, ResourceListSize
);
110 AllocatedResourcesTranslated
->List
[0].PartialResourceList
.PartialDescriptors
[2].u
.Interrupt
.Vector
= HalGetInterruptVector(
112 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[2].u
.Interrupt
.Level
,
113 AllocatedResources
->List
[0].PartialResourceList
.PartialDescriptors
[2].u
.Interrupt
.Vector
,
114 (PKIRQL
)&AllocatedResourcesTranslated
->List
[0].PartialResourceList
.PartialDescriptors
[2].u
.Interrupt
.Level
,
115 &AllocatedResourcesTranslated
->List
[0].PartialResourceList
.PartialDescriptors
[2].u
.Interrupt
.Affinity
);
117 /* Send IRP_MN_START_DEVICE */
118 TopDeviceObject
= IoGetAttachedDeviceReference(Pdo
);
123 Irp
= IoBuildSynchronousFsdRequest(
131 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
132 Irp
->IoStatus
.Information
= 0;
133 Stack
= IoGetNextIrpStackLocation(Irp
);
134 Stack
->MinorFunction
= IRP_MN_START_DEVICE
;
135 Stack
->Parameters
.StartDevice
.AllocatedResources
= AllocatedResources
;
136 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
= AllocatedResourcesTranslated
;
137 Status
= IoCallDriver(TopDeviceObject
, Irp
);
138 if (Status
== STATUS_PENDING
)
140 KeWaitForSingleObject(
146 Status
= IoStatusBlock
.Status
;
148 if (!NT_SUCCESS(Status
))
150 WARN_(CLASS_NAME
, "IoCallDriver() failed with status 0x%08lx\n", Status
);
156 ObDereferenceObject(TopDeviceObject
);
157 if (AllocatedResources
)
158 ExFreePoolWithTag(AllocatedResources
, CLASS_TAG
);
159 if (AllocatedResourcesTranslated
)
160 ExFreePoolWithTag(AllocatedResourcesTranslated
, CLASS_TAG
);