8c56c1a5bdb5e2f7c6c0ca0119a9d002ee8c646d
[reactos.git] / rosapps / applications / sysutils / utils / pice / module / patch.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module Name:
6
7 patch.c
8
9 Abstract:
10
11 hooking of kernel internal keyboard interrupt handler
12
13 Environment:
14
15 Kernel mode only
16
17 Author:
18
19 Klaus P. Gerlicher
20 Reactos Port: Eugene Ingerman
21
22 Revision History:
23
24 10-Jul-1999: created
25 15-Nov-2000: general cleanup of source files
26 12/1/2001 reactos port
27
28 Copyright notice:
29
30 This file may be distributed under the terms of the GNU Public License.
31
32 --*/
33
34 ////////////////////////////////////////////////////
35 // INCLUDES
36 ////
37 #include "remods.h"
38 #include "precomp.h"
39
40 //#include <asm/system.h>
41
42 #include <ntddkbd.h>
43 #include <ntdd8042.h>
44 #include <rosrtl/string.h>
45
46 ////////////////////////////////////////////////////
47 // GLOBALS
48 ////
49
50 static PUCHAR pPatchAddress;
51 static ULONG ulOldOffset = 0;
52 static ULONG ulKeyPatchFlags;
53
54 void (*old_handle_scancode)(UCHAR,int);
55 char tempPatch[256];
56 UCHAR ucBreakKey = 'd'; // key that will break into debugger in combination with CTRL
57
58 ////////////////////////////////////////////////////
59 // FUNCTIONS
60 ////
61
62 //***********************************************************************************
63 // PiceKbdIsr - keyboard isr hook routine.
64 // IsrContext - context that we passed to keyboard driver in internal iocontrol
65 // pCurrentInput, pCurrentOutput - not implemented yet
66 // StatusByte - keyboard status register
67 // pByte - pointer to the byte read from keyboard data port. can be changed.
68 // pContinueProcessing - should keyboard driver continue processing this byte.
69 //***********************************************************************************
70 BOOLEAN PiceKbdIsr (
71 PVOID IsrContext,
72 PKEYBOARD_INPUT_DATA pCurrentInput,
73 POUTPUT_PACKET pCurrentOutput,
74 UCHAR StatusByte,
75 PUCHAR pByte,
76 PBOOLEAN pContinueProcessing,
77 PKEYBOARD_SCAN_STATE pScanState
78 )
79 {
80 static BOOLEAN bControl = FALSE;
81 BOOLEAN bForward=TRUE; // should we let keyboard driver process this keystroke
82 BOOLEAN isDown=!(*pByte & 0x80);
83 UCHAR ucKey = *pByte & 0x7f;
84
85 ENTER_FUNC();
86
87 // BUG?? should protect with spinlock since bControl is static.
88 DPRINT((0,"PiceKbdIsr(pByte: %x, val: %x,%u)\n",pByte,*pByte,isDown));
89 DPRINT((0,"PiceKbdIsr(1): bControl = %u bForward = %u bEnterNow = %u\n",bControl,bForward,bEnterNow));
90
91 if(isDown)
92 {
93 DPRINT((0,"bControl: %x, ucKey: %x, breakkey: %x\n", bControl, ucKey, AsciiToScan(ucBreakKey)));
94 // CTRL pressed
95 if(ucKey==0x1d)
96 {
97 bControl=TRUE;
98 }
99 else if(bControl==TRUE && ucKey==AsciiToScan(ucBreakKey)) // CTRL-D
100 {
101 // fake a CTRL-D release call
102 bEnterNow=TRUE;
103 bControl=FALSE;
104 // simulate an initial break
105 __asm__("\n\t \
106 pushfl\n\t \
107 pushl %cs\n\t \
108 pushl $returnpoint\n\t \
109 pushl $" STR(REASON_CTRLF) "\n\t \
110 jmp NewInt31Handler\n\t \
111 returnpoint:");
112 *pByte = 0x1d | 0x80 | 0x7f;
113 bForward=TRUE;
114 }
115 else if((ucKey == 66|| ucKey == 68) && bStepping)
116 {
117 bForward=FALSE;
118 }
119
120 }
121 else
122 {
123 // CTRL released
124 if(ucKey==0x1d)
125 {
126 bControl=FALSE;
127 }
128 else if((ucKey == 66|| ucKey == 68) && bStepping)
129 {
130 bForward=FALSE;
131 }
132 }
133 *pContinueProcessing = bForward;
134 DPRINT((5,"*pContinueProcessing: %d\n", *pContinueProcessing));
135 LEAVE_FUNC();
136 return TRUE;
137 }
138
139 //***********************************************************************************
140 // PiceSendIoctl - send internal_io_control to the driver
141 // Target - Device Object that receives control request
142 // Ioctl - request
143 // InputBuffer - Type3Buffer will be pointing here
144 // InputBufferLength - length of inputbuffer
145 //***********************************************************************************
146 NTSTATUS PiceSendIoctl(PDEVICE_OBJECT Target, ULONG Ioctl,
147 PVOID InputBuffer, ULONG InputBufferLength)
148 {
149 KEVENT event;
150 NTSTATUS status = STATUS_SUCCESS;
151 IO_STATUS_BLOCK iosb;
152 PIRP irp;
153
154 KeInitializeEvent(&event,
155 NotificationEvent,
156 FALSE
157 );
158
159 if (NULL == (irp = IoBuildDeviceIoControlRequest(Ioctl,
160 Target,
161 InputBuffer,
162 InputBufferLength,
163 0,
164 0,
165 TRUE,
166 &event,
167 &iosb))) {
168 DPRINT((0,"PiceSendIoctl: STATUS_INSUFFICIENT_RESOURCES\n"));
169 return STATUS_INSUFFICIENT_RESOURCES;
170 }
171
172 status = IoCallDriver(Target, irp);
173
174 if (STATUS_PENDING == status) {
175
176 status = KeWaitForSingleObject(&event,
177 Executive,
178 KernelMode,
179 FALSE,
180 NULL);
181
182 ASSERT(STATUS_SUCCESS == status);
183 status = iosb.Status;
184 }
185 DPRINT((0,"PiceSendIoctl: status: %d\n",NT_SUCCESS(status)));
186 return status;
187 }
188
189 //**************************************************
190 // PatchKeyboardDriver - set keyboard driver hook.
191 // We use interface supported by standard keyboard drivers.
192 //**************************************************
193 BOOLEAN PatchKeyboardDriver(void)
194 {
195 PINTERNAL_I8042_HOOK_KEYBOARD phkData;
196 //When we have i8042 driver this should be changed!!!!!!!
197 UNICODE_STRING DevName = ROS_STRING_INITIALIZER(L"\\Device\\Keyboard");
198 PDEVICE_OBJECT kbdDevice = NULL;
199 PFILE_OBJECT FO = NULL;
200 NTSTATUS status;
201
202 ENTER_FUNC();
203
204 //Get pointer to keyboard device
205 if( !NT_SUCCESS( status = IoGetDeviceObjectPointer( &DevName, FILE_READ_ACCESS, &FO, &kbdDevice ) ) )
206 {
207 DPRINT((0,"PatchKeyboardDriver: IoGetDeviceObjectPointer status: %x\n", status));
208 return FALSE;
209 }
210 phkData = ExAllocatePool( PagedPool, sizeof( INTERNAL_I8042_HOOK_KEYBOARD ) );
211 RtlZeroMemory( phkData, sizeof( INTERNAL_I8042_HOOK_KEYBOARD ) );
212
213 phkData->IsrRoutine = (PI8042_KEYBOARD_ISR) PiceKbdIsr;
214 phkData->Context = (PVOID) NULL; //DeviceObject;
215
216 //call keyboard device internal io control to hook keyboard input stream
217 status = PiceSendIoctl( kbdDevice, IOCTL_INTERNAL_I8042_HOOK_KEYBOARD,
218 phkData, sizeof( INTERNAL_I8042_HOOK_KEYBOARD ) );
219 DPRINT((0,"PatchKeyboardDriver: PiceSendIoctl status: %x\n", status));
220
221
222 ObDereferenceObject(FO);
223 ExFreePool(phkData);
224
225 LEAVE_FUNC();
226
227 return NT_SUCCESS(status);
228 }
229
230 void RestoreKeyboardDriver(void)
231 {
232 ENTER_FUNC();
233 DbgPrint("RestoreKeyboardDriver: Not Implemented yet!!!\n");
234 LEAVE_FUNC();
235 }