BOOLEAN NTAPI i8042KbdInterruptService( IN PKINTERRUPT Interrupt, PVOID Context) { PI8042_KEYBOARD_EXTENSION DeviceExtension; PPORT_DEVICE_EXTENSION PortDeviceExtension; PKEYBOARD_INPUT_DATA InputData; ULONG Counter; UCHAR PortStatus = 0, Output = 0; BOOLEAN ToReturn = FALSE; NTSTATUS Status; UNREFERENCED_PARAMETER(Interrupt); DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer; Counter = PortDeviceExtension->Settings.PollStatusIterations; while (Counter) { Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); if (!NT_SUCCESS(Status)) { WARN_(I8042PRT, "i8042ReadStatus() failed with status 0x%08lx\n", Status); return FALSE; } Status = i8042ReadKeyboardData(PortDeviceExtension, &Output); if (NT_SUCCESS(Status)) break; KeStallExecutionProcessor(1); Counter--; } if (Counter == 0) { WARN_(I8042PRT, "Spurious i8042 keyboard interrupt\n"); return FALSE; } INFO_(I8042PRT, "Got: 0x%02x\n", Output); if (PortDeviceExtension->Settings.CrashOnCtrlScroll) { /* Test for CTRL + SCROLL LOCK twice */ static const UCHAR ScanCodes[] = { 0x1d, 0x46, 0xc6, 0x46, 0 }; if (Output == ScanCodes[DeviceExtension->ComboPosition]) { DeviceExtension->ComboPosition++; if (ScanCodes[DeviceExtension->ComboPosition] == 0) KeBugCheck(MANUALLY_INITIATED_CRASH); } else if (Output == 0xfa) { /* Ignore ACK */ } else if (Output == ScanCodes[0]) DeviceExtension->ComboPosition = 1; else DeviceExtension->ComboPosition = 0; /* Test for TAB + key combination */ if (InputData->MakeCode == 0x0F) DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK); else if (DeviceExtension->TabPressed) { DeviceExtension->TabPressed = FALSE; /* Check which action to do */ if (InputData->MakeCode == 0x25) { /* k - Breakpoint */ DbgBreakPoint(); } else if (InputData->MakeCode == 0x30) { /* b - Bugcheck */ KeBugCheck(MANUALLY_INITIATED_CRASH); } else { /* Send request to the kernel debugger. * Unknown requests will be ignored. */ KdSystemDebugControl(' soR', (PVOID)(ULONG_PTR)InputData->MakeCode, 0, NULL, 0, NULL, KernelMode); } } } if (i8042KbdCallIsrHook(DeviceExtension, PortStatus, Output, &ToReturn)) return ToReturn; if (i8042PacketIsr(PortDeviceExtension, Output)) { if (PortDeviceExtension->PacketComplete) { TRACE_(I8042PRT, "Packet complete\n"); KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); } TRACE_(I8042PRT, "Irq eaten by packet\n"); return TRUE; } TRACE_(I8042PRT, "Irq is keyboard input\n"); if (DeviceExtension->KeyboardScanState == Normal) { switch (Output) { case 0xe0: DeviceExtension->KeyboardScanState = GotE0; return TRUE; case 0xe1: DeviceExtension->KeyboardScanState = GotE1; return TRUE; default: break; } } /* Update InputData */ InputData->Flags = 0; switch (DeviceExtension->KeyboardScanState) { case GotE0: InputData->Flags |= KEY_E0; break; case GotE1: InputData->Flags |= KEY_E1; break; default: break; } DeviceExtension->KeyboardScanState = Normal; if (Output & 0x80) InputData->Flags |= KEY_BREAK; else InputData->Flags |= KEY_MAKE; InputData->MakeCode = Output & 0x7f; InputData->Reserved = 0; DeviceExtension->KeyboardHook.QueueKeyboardPacket(DeviceExtension->KeyboardHook.CallContext); return TRUE; }
/* * This definition doesn't work */ INIT_FUNCTION NTSTATUS APIENTRY DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS Status; BOOLEAN Result; WIN32_CALLOUTS_FPNS CalloutData = {0}; PVOID GlobalUserHeapBase = NULL; /* * Register user mode call interface * (system service table index = 1) */ Result = KeAddSystemServiceTable(Win32kSSDT, NULL, Win32kNumberOfSysCalls, Win32kSSPT, 1); if (Result == FALSE) { DPRINT1("Adding system services failed!\n"); return STATUS_UNSUCCESSFUL; } hModuleWin = MmPageEntireDriver(DriverEntry); DPRINT("Win32k hInstance 0x%p!\n",hModuleWin); /* Register Object Manager Callbacks */ CalloutData.ProcessCallout = Win32kProcessCallback; CalloutData.ThreadCallout = Win32kThreadCallback; CalloutData.WindowStationParseProcedure = IntWinStaObjectParse; CalloutData.WindowStationDeleteProcedure = IntWinStaObjectDelete; CalloutData.WindowStationOkToCloseProcedure = IntWinstaOkToClose; CalloutData.DesktopOkToCloseProcedure = IntDesktopOkToClose; CalloutData.DesktopDeleteProcedure = IntDesktopObjectDelete; CalloutData.DesktopCloseProcedure = IntDesktopObjectClose; CalloutData.DesktopOpenProcedure = IntDesktopObjectOpen; CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch; /* Register our per-process and per-thread structures. */ PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData); /* Register service hook callbacks */ #if DBG KdSystemDebugControl('CsoR', DbgPreServiceHook, ID_Win32PreServiceHook, 0, 0, 0, 0); KdSystemDebugControl('CsoR', DbgPostServiceHook, ID_Win32PostServiceHook, 0, 0, 0, 0); #endif /* Create the global USER heap */ GlobalUserHeap = UserCreateHeap(&GlobalUserHeapSection, &GlobalUserHeapBase, 1 * 1024 * 1024); /* FIXME: 1 MB for now... */ if (GlobalUserHeap == NULL) { DPRINT1("Failed to initialize the global heap!\n"); return STATUS_UNSUCCESSFUL; } /* Allocate global server info structure */ gpsi = UserHeapAlloc(sizeof(SERVERINFO)); if (!gpsi) { DPRINT1("Failed allocate server info structure!\n"); return STATUS_UNSUCCESSFUL; } RtlZeroMemory(gpsi, sizeof(SERVERINFO)); DPRINT("Global Server Data -> %p\n", gpsi); NT_ROF(InitGdiHandleTable()); NT_ROF(InitPaletteImpl()); /* Create stock objects, ie. precreated objects commonly used by win32 applications */ CreateStockObjects(); CreateSysColorObjects(); NT_ROF(InitBrushImpl()); NT_ROF(InitPDEVImpl()); NT_ROF(InitLDEVImpl()); NT_ROF(InitDeviceImpl()); NT_ROF(InitDcImpl()); NT_ROF(InitUserImpl()); NT_ROF(InitWindowStationImpl()); NT_ROF(InitDesktopImpl()); NT_ROF(InitInputImpl()); NT_ROF(InitKeyboardImpl()); NT_ROF(MsqInitializeImpl()); NT_ROF(InitTimerImpl()); NT_ROF(InitDCEImpl()); /* Initialize FreeType library */ if (!InitFontSupport()) { DPRINT1("Unable to initialize font support\n"); return Status; } gusLanguageID = UserGetLanguageID(); return STATUS_SUCCESS; }