/* * UnloadKbdFile * * Destroys specified Keyboard File object */ static VOID UnloadKbdFile(_In_ PKBDFILE pkf) { PKBDFILE *ppkfLink = &gpkfList; NT_ASSERT(pkf != NULL); /* Find previous object */ while (*ppkfLink) { if (*ppkfLink == pkf) break; ppkfLink = &(*ppkfLink)->pkfNext; } if (*ppkfLink == pkf) *ppkfLink = pkf->pkfNext; EngUnloadImage(pkf->hBase); UserDeleteObject(pkf->head.h, TYPE_KBDFILE); }
VOID REINITIALIZE_ADAPTER( PVOID ) /*++ Routine Description This routine re-initializes display driver to obtains its DrvCoptBits pointer. This routine executed as a separate thread in the context of CSRSS.EXE Arguments PVOID Thread context, always NULL Return Value None, thread terminates by call PsTerminateSystemThread Environment Separate thread of CSRSS process --*/ { // // This routine runs in the context of csrss.exe // KdPrint(("REINITIALIZE_ADAPTER enter\n")); HANDLE hDrv = EngLoadImage (L"vid_copy.dll"); KdPrint(("vid_copy is %X\n", hDrv)); if (hDrv) { BOOLEAN (NTAPI *pOriginalDrvEnableDriver)( ULONG iEngineVersion, ULONG cj, PDRVENABLEDATA pded ); *(PVOID*)&pOriginalDrvEnableDriver = EngFindImageProcAddress (hDrv, "DrvEnableDriver"); KdPrint(("pOriginalDrvEnableDriver = %X\n", pOriginalDrvEnableDriver)); if (pOriginalDrvEnableDriver) { BOOLEAN Ret; DRVENABLEDATA DrvEnableData = {0}; Ret = pOriginalDrvEnableDriver (DDI_DRIVER_VERSION_NT5_01_SP1, sizeof(DrvEnableData), &DrvEnableData); KdPrint(("pOriginalDrvEnableDriver returned %X\n", Ret)); if (Ret) { for (ULONG i = 0; i<DrvEnableData.c; i++) { if (DrvEnableData.pdrvfn[i].iFunc == INDEX_DrvCopyBits) { KdPrint(("Found DrvCopyBits: %X\n", DrvEnableData.pdrvfn[i].pfn)); HANDLE hKey; wchar_t value[512]; hKey = RegOpenKey (L"\\Registry\\Machine\\Software\\NGdbg", KEY_QUERY_VALUE); if (hKey) { ULONG Len = sizeof(value); if (RegQueryValue (hKey, L"DisplayDriver", REG_SZ, value, &Len)) { KdPrint(("Display driver: %S\n", value)); wcscat (value, L".dll"); PVOID OrigBase = FindImage (value); PVOID VidBase = FindImage (L"vid_copy.dll"); if (OrigBase && VidBase) { ULONG Offset = (ULONG)DrvEnableData.pdrvfn[i].pfn - (ULONG)VidBase; KdPrint(("Offset %X\n", Offset)); pDrvCopyBits = (PUCHAR)OrigBase + Offset; KdPrint(("DrvCopyBits %X\n", pDrvCopyBits)); } else { KdPrint(("FindImage failed: OrigBase %X, VidBase %X\n", OrigBase, VidBase)); } } else { KdPrint(("RegQueryValue failed\n")); } ZwClose (hKey); } else { KdPrint(("RegOpenKey failed\n")); } } } } } EngUnloadImage (hDrv); } KdPrint(("REINITIALIZE_ADAPTER exit\n")); PsTerminateSystemThread (0); }
/* * UserLoadKbdDll * * Loads keyboard layout DLL and gets address to KbdTables */ static BOOL UserLoadKbdDll(WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables) { PFN_KBDLAYERDESCRIPTOR pfnKbdLayerDescriptor; /* Load keyboard layout DLL */ TRACE("Loading Keyboard DLL %ws\n", pwszLayoutPath); *phModule = EngLoadImage(pwszLayoutPath); if (!(*phModule)) { ERR("Failed to load dll %ws\n", pwszLayoutPath); return FALSE; } /* Find KbdLayerDescriptor function and get layout tables */ TRACE("Loaded %ws\n", pwszLayoutPath); pfnKbdLayerDescriptor = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor"); /* FIXME: Windows reads file instead of executing! It's not safe to kbdlayout DLL in kernel mode! */ if (pfnKbdLayerDescriptor) *pKbdTables = pfnKbdLayerDescriptor(); else ERR("Error: %ws has no KbdLayerDescriptor()\n", pwszLayoutPath); if (!pfnKbdLayerDescriptor || !*pKbdTables) { ERR("Failed to load the keyboard layout.\n"); EngUnloadImage(*phModule); return FALSE; } #if 0 /* Dump keyboard layout */ { unsigned i; PVK_TO_BIT pVkToBit = (*pKbdTables)->pCharModifiers->pVkToBit; PVK_TO_WCHAR_TABLE pVkToWchTbl = (*pKbdTables)->pVkToWcharTable; PVSC_VK pVscVk = (*pKbdTables)->pVSCtoVK_E0; DbgPrint("Kbd layout: fLocaleFlags %x bMaxVSCtoVK %x\n", (*pKbdTables)->fLocaleFlags, (*pKbdTables)->bMaxVSCtoVK); DbgPrint("wMaxModBits %x\n", (*pKbdTables)->pCharModifiers->wMaxModBits); while (pVkToBit->Vk) { DbgPrint("VkToBit %x -> %x\n", pVkToBit->Vk, pVkToBit->ModBits); ++pVkToBit; } for (i = 0; i <= (*pKbdTables)->pCharModifiers->wMaxModBits; ++i) DbgPrint("ModNumber %x -> %x\n", i, (*pKbdTables)->pCharModifiers->ModNumber[i]); while (pVkToWchTbl->pVkToWchars) { PVK_TO_WCHARS1 pVkToWch = pVkToWchTbl->pVkToWchars; DbgPrint("pVkToWchTbl nModifications %x cbSize %x\n", pVkToWchTbl->nModifications, pVkToWchTbl->cbSize); while (pVkToWch->VirtualKey) { DbgPrint("pVkToWch VirtualKey %x Attributes %x wc { ", pVkToWch->VirtualKey, pVkToWch->Attributes); for (i = 0; i < pVkToWchTbl->nModifications; ++i) DbgPrint("%x ", pVkToWch->wch[i]); DbgPrint("}\n"); pVkToWch = (PVK_TO_WCHARS1)(((PBYTE)pVkToWch) + pVkToWchTbl->cbSize); } ++pVkToWchTbl; } DbgPrint("pusVSCtoVK: { "); for (i = 0; i < (*pKbdTables)->bMaxVSCtoVK; ++i) DbgPrint("%x -> %x, ", i, (*pKbdTables)->pusVSCtoVK[i]); DbgPrint("}\n"); DbgPrint("pVSCtoVK_E0: { "); while (pVscVk->Vsc) { DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk); ++pVscVk; } DbgPrint("}\n"); pVscVk = (*pKbdTables)->pVSCtoVK_E1; DbgPrint("pVSCtoVK_E1: { "); while (pVscVk->Vsc) { DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk); ++pVscVk; } DbgPrint("}\n"); DbgBreakPoint(); } #endif return TRUE; }