📄 kdriver.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#include "kernel.h"
CRITICAL_SECTION IntChainCS;
extern ROMChain_t *ROMChain;
typedef DWORD (* IntChainHandler_t)(DWORD dwInstData);
typedef struct _INTCHAIN {
struct _INTCHAIN* pNext;
PKERNELMOD pkMod;
} INTCHAIN, *PINTCHAIN;
ERRFALSE(sizeof(INTCHAIN) <= sizeof(PROXY));
#define HEAP_INTCHAIN HEAP_PROXY
extern DWORD InDaylight;
static PINTCHAIN pIntChainTable[256];
BOOL SetDbgList (LPCWSTR pList, int nTotalLen);
//------------------------------------------------------------------------------
//
// If no CPU specific code is required to wrap for "C" calling convention,
// then it is directly called as NKCallIntChain, otherwise NKCallIntChainWrapped.
//
//------------------------------------------------------------------------------
DWORD
#if defined(x86) || defined(ARM)
NKCallIntChain(
#else
NKCallIntChainWrapped(
#endif
BYTE bIRQ
)
{
PINTCHAIN pChainTemp;
DWORD dwRet = SYSINTR_CHAIN;
pChainTemp = pIntChainTable[bIRQ];
while(pChainTemp && dwRet == SYSINTR_CHAIN) {
// don't think DEBUGCHK here will help since the system is hosed. Our
// last desparate attempt to get some information for debugging.
DEBUGCHK (pChainTemp->pkMod && pChainTemp->pkMod->pfnHandler);
dwRet = pChainTemp->pkMod->pfnHandler (pChainTemp->pkMod->dwInstData);
pChainTemp = pChainTemp->pNext;
}
return dwRet;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
HookIntChain(
BYTE bIRQ,
PKERNELMOD pkMod
)
{
PINTCHAIN pIntChain;
PINTCHAIN pWalk;
pIntChain = (PINTCHAIN) AllocMem(HEAP_INTCHAIN);
if (!pIntChain) {
KSetLastError(pCurThread,ERROR_OUTOFMEMORY);
return FALSE;
}
pIntChain->pkMod = pkMod;
pIntChain->pNext = NULL;
//
// Link it in at the end of the list.
//
EnterCriticalSection(&IntChainCS);
pWalk = pIntChainTable[bIRQ];
if (pWalk == NULL) {
// First node inserted
pIntChainTable[bIRQ] = pIntChain;
} else {
while (pWalk->pNext) {
pWalk = pWalk->pNext;
}
pWalk->pNext = pIntChain;
}
LeaveCriticalSection(&IntChainCS);
return TRUE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
UnhookIntChain(
BYTE bIRQ,
PKERNELMOD pkMod
)
{
PINTCHAIN pWalk;
PINTCHAIN* ppPrev;
BOOL fRet = FALSE;
EnterCriticalSection(&IntChainCS);
pWalk = pIntChainTable[bIRQ];
ppPrev = &(pIntChainTable[bIRQ]);
while(pWalk) {
if (pWalk->pkMod == pkMod) {
//
// Found it. Unhook it. Don't need to turn interrupt off because FreeMem
// is called AFTER we update the list.
//
*ppPrev = pWalk->pNext;
FreeMem(pWalk, HEAP_INTCHAIN);
pWalk = NULL; // break loop
fRet = TRUE;
} else {
ppPrev = &(pWalk->pNext);
pWalk = pWalk->pNext;
}
}
LeaveCriticalSection(&IntChainCS);
if (fRet == FALSE) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
}
return fRet;
}
static BOOL DoAllocShareMem (BOOL fIsFree, DWORD nPages, BOOL fNoCache, LPVOID *pVa, LPVOID *pPa)
{
ULONG physAddr;
DEBUGMSG (ZONE_ENTRY, (L"DoAllocShareMem (%d, %d, %d, %8.8lx, %8.8lx)\n", fIsFree, fNoCache, nPages, pVa, pPa));
if (!nPages || !pVa || !pPa) {
KSetLastError (pCurThread, ERROR_INVALID_PARAMETER);
return FALSE;
}
if (fIsFree) {
// pPa is unused for freeing
return SC_FreePhysMem (pVa);
}
// allocate the memory from process slot
if (*pVa = SC_AllocPhysMem(nPages * PAGE_SIZE, PAGE_READWRITE, 0, 0, &physAddr)) {
*pPa = (LPVOID) (Phys2VirtUC (PA2PFN (physAddr)));
}
// translate the physical address into statically mapped uncached address
return NULL != *pVa;
}
extern BOOL SetROMDllBase (DWORD cbSize, PROMINFO pInfo);
extern BOOL GetVMInfo (int idxProc, PPROCVMINFO pInfo);
extern DWORD JITGetCallStack (HANDLE hThrd, ULONG dwMaxFrames, CallSnapshot lpFrames[]);
extern BOOL NKSetMemoryAttributes (LPVOID pVirtualAddr, LPVOID pShiftedPhysAddr, DWORD cbSize, DWORD dwAttributes);
BOOL fDisableNoFault;
//---------------------------------------------------------------------------
// DW Watson support
//---------------------------------------------------------------------------
DWORD dwNKDrWatsonSize; // OEM must change this to enable Kernel Watson support
// must be multiple of PAGE_SIZE
static LPBYTE pDrWatsonDump; // pointer to Dr. Watson dump area.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void InitDrWatson (void)
{
if (dwNKDrWatsonSize) {
extern DWORD MainMemoryEndAddress;
dwNKDrWatsonSize = PAGEALIGN_UP (dwNKDrWatsonSize);
RETAILMSG (1, (L"Error Reporting Memory Reserved, dump size = %8.8lx\r\n", dwNKDrWatsonSize));
MainMemoryEndAddress -= dwNKDrWatsonSize;
pDrWatsonDump = (LPBYTE) MainMemoryEndAddress;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL RAMDrWatsonFlush (void)
{
return TRUE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL RAMDrWatsonClear (void)
{
memset (pDrWatsonDump, 0, dwNKDrWatsonSize);
return TRUE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD RAMDrWatsonWrite (DWORD dwOffset, LPVOID pData, DWORD cbSize)
{
if (!dwNKDrWatsonSize || (dwOffset > dwNKDrWatsonSize) || ((int) cbSize <= 0))
return 0;
if (cbSize + dwOffset > dwNKDrWatsonSize)
cbSize = dwNKDrWatsonSize - dwOffset;
memcpy (pDrWatsonDump + dwOffset, pData, cbSize);
return cbSize;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD RAMDrWatsonRead (DWORD dwOffset, LPVOID pData, DWORD cbSize)
{
if (!dwNKDrWatsonSize || (dwOffset > dwNKDrWatsonSize) || ((int) cbSize <= 0))
return 0;
if (cbSize + dwOffset > dwNKDrWatsonSize)
cbSize = dwNKDrWatsonSize - dwOffset;
memcpy (pData, pDrWatsonDump + dwOffset, cbSize);
return cbSize;
}
//------------------------------------------------------------------------------
// Default Dr. Watson implementation carves a range of ram, OEM can override the
// following pointers and dwNKDrWatsonSize to implement if he wishes to persist
// Dr. Watson Data across cold boot.
//------------------------------------------------------------------------------
BOOL (* pfnNKDrWatsonFlush) (void) = RAMDrWatsonFlush;
BOOL (* pfnNKDrWatsonClear) (void) = RAMDrWatsonClear;
DWORD (* pfnNKDrWatsonRead) (DWORD dwOffset, LPVOID pData, DWORD cbSize) = RAMDrWatsonRead;
DWORD (* pfnNKDrWatsonWrite) (DWORD dwOffset, LPVOID pData, DWORD cbSize) = RAMDrWatsonWrite;
extern BOOL SC_SetJITDebuggerPath (LPCWSTR pszDbgrPath);
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL KernelLibIoControl_Core(
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned
)
{
switch (dwIoControlCode) {
case IOCTL_KLIB_ALLOCSHAREMEM:
case IOCTL_KLIB_FREESHAREMEM:
return DoAllocShareMem (IOCTL_KLIB_FREESHAREMEM == dwIoControlCode, nInBufSize, nOutBufSize, lpInBuf, lpOutBuf);
// irregular usage.
case IOCTL_KLIB_GETROMCHAIN:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -