⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objdisp.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved. *//*+    objdisp.c - object call dispatch routines.    This file contains the routines for dispatching method calls to objects    implemented by protected system libraries, direct kernel functions,    and kernel mode threads.*/#include "kernel.h"#include "xtime.h"#include "winsock.h"#ifdef XTIME							//XTIMEvoid SyscallTime(DWORD);				//XTIME record exception elapsed time#endif									//XTIMEvoid SC_CloseAPISet(HANDLE hSet);BOOL SC_RegisterAPISet(HANDLE hSet, DWORD dwSetID);LPVOID SC_VerifyAPIHandle(HANDLE hSet, HANDLE h);void GoToUserTime(void);void GoToKernTime(void);extern CRITICAL_SECTION LLcs;const PFNVOID APISetMethods[] = {    (PFNVOID)SC_CloseAPISet,    (PFNVOID)SC_NotSupported,    (PFNVOID)SC_RegisterAPISet,    (PFNVOID)SC_CreateAPIHandle,    (PFNVOID)SC_VerifyAPIHandle,};const CINFO cinfAPISet = {	"APIS",	DISPATCH_KERNEL_PSL,	HT_APISET,	sizeof(APISetMethods)/sizeof(APISetMethods[0]),	APISetMethods,};// Head of double linked list of active handles in the system.DList HandleList = { &HandleList, &HandleList };// Serial # for handle values.unsigned int HandleSerial;// Array of pointers to system api sets.const CINFO *SystemAPISets[NUM_SYSTEM_SETS];// Find a process index from an access lock.int IndexFromLock(ulong lock){    ulong mask;    int inxRet;    int inx;    mask = 0x0000FFFFul;    for (inxRet = 0, inx = 16 ; inx ; inx >>= 1, mask >>= inx) {        if ((lock & mask) == 0) {            inxRet += inx;            lock >>= inx;        }    }    return inxRet;}// Insert an item into a double linked listvoid AddToDList(DList *head, DList *item){    item->back = head;    item->fwd = head->fwd;    head->fwd->back = item;    head->fwd = item;}// Remove an item from a double linked listvoid RemoveDList(DList *item){    item->fwd->back = item->back;    item->back->fwd = item->fwd;}// Convert a HANDLE to an HDATA pointer.//// HandleToPointer() is a function which can be used by other kernel modules.////  h2p() is an private macro used to speed up the internal processing of// ObjectCall() and the various GetXXX/SetXXX functions.#define h2p(h, phdRet) \    do { \        if ((ulong)h < NUM_SYS_HANDLES+SYS_HANDLE_BASE && (ulong)h >= SYS_HANDLE_BASE) \             h = KData.ahSys[(uint)h-SYS_HANDLE_BASE]; \        if (h) {            \            phdRet = (PHDATA)(((ulong)h & HANDLE_ADDRESS_MASK) + KData.handleBase); \            if (!IsValidKPtr(phdRet) || phdRet->hValue != h) \                phdRet = 0; \        } else              \            phdRet = 0;     \    } while (0)PHDATA HandleToPointer(HANDLE h){    PHDATA phdRet;    h2p(h, phdRet);    return phdRet;}// Return the next handle to close.//// The active handle list is scanned for a handle which is referenced by the process// whose procnum is (id). (hLast) is the previous return value from this// routine.  If a handle is found, its reference count for the process is forced// to 1 so that it will be closed by a single call to CloseHandle(). To speed up the// iterative process of scanning the entire table, a pointer to the next handle in// the list is retained. The next call will use that value if the list is unchanged,// except for the possible freeing of the handle previously returned. If the list// has changed, the scan will restart at the beginning of the list.////NOTE: This function is called via KCall().PHDATA PhdPrevReturn, PhdNext;PHDATA NextCloseHandle(PHDATA *phdLast, int ixProc) {    PHDATA phd;	KCALLPROFON(7);	if (!PhdPrevReturn || !PhdNext || (*phdLast != PhdNext))    	phd = (PHDATA)HandleList.fwd;    else    	phd = (PHDATA)PhdNext->linkage.fwd;    DEBUGCHK(phd != 0);    if (&phd->linkage == &HandleList) {        PhdPrevReturn = 0;		KCALLPROFOFF(7);        return 0;    }    PhdPrevReturn = phd;    if ((phd->lock & (1<<ixProc)) && (phd->hValue != hCurThread) && (phd->hValue != hCurProc)) {        // Force handle reference count for this process to one.        if (phd->ref.count < 0x10000)            phd->ref.count = 1;        else            phd->ref.pFr->usRefs[ixProc] = 1;    } else {	    PhdNext = *phdLast = phd;        phd = (PHDATA)((ulong)phd | 1);	}	KCALLPROFOFF(7);    return phd;}void SC_CloseAllHandles(void) {    PHDATA phd, next;    int ixProc;	next = 0;	ixProc = pCurProc->procnum;    while (phd = (PHDATA)KCall((PKFN)NextCloseHandle, &next, ixProc))    	if (!((DWORD)phd & 1))    		CloseHandle(phd->hValue);}// Non-preemtible handle setup for AllocHandle().BOOL SetupHandle(PHDATA phdNew, PPROCESS pprc) {	KCALLPROFON(8);	phdNew->hValue = (HANDLE)(((ulong)phdNew & HANDLE_ADDRESS_MASK) | 2 | ((ulong)phdNew->hValue & 0xE0000000));	LockFromKey(&phdNew->lock, &pprc->aky);    // Zap PhdPrevReturn so to force a restart the next time    // NextCloseHandle() is called.    PhdPrevReturn = 0;     AddToDList(&HandleList, &phdNew->linkage);	KCALLPROFOFF(8);    return TRUE;}// Non-preemtible handle cleanup for FreeHandle().PHDATA ZapHandle(HANDLE h) {    PHDATA phd;	KCALLPROFON(9);    h2p(h, phd);    if (phd) {        phd->lock = 0;        // make it so that the handle no longer matches existing handles given out        DEBUGCHK(((DWORD)phd->hValue & 0x1fffffff) == (((ulong)phd & HANDLE_ADDRESS_MASK) | 2));		phd->hValue = (HANDLE)((DWORD)phd->hValue+0x20000000);        // If freeing a handle other than the last one returned by        // NextCloseHandle(), then zap PhdPrevReturn so to force        // a restart the next time NextCloseHandle() is called.        if (phd != PhdPrevReturn)            PhdPrevReturn = 0;         if (phd == PhdNext)        	PhdNext = 0;        RemoveDList(&phd->linkage);    }	KCALLPROFOFF(9);    return phd;}// Create a new handle.HANDLE AllocHandle(const CINFO *pci, PVOID pvObj, PPROCESS pprc){    PHDATA phdNew;    DEBUGMSG(ZONE_MEMORY, (TEXT("AllocHandle: pci=%8.8lx pvObj=%8.8lx pprc=%8.8lx\r\n"),            pci, pvObj, pprc));    if ((phdNew = AllocMem(HEAP_HDATA)) != 0) {        phdNew->pci = pci;        phdNew->pvObj = pvObj;        phdNew->dwInfo = 0;        phdNew->ref.count = 1;        if (KCall((PKFN)SetupHandle, phdNew, pprc)) {            DEBUGMSG(ZONE_MEMORY, (TEXT("AllocHandle: phd=%8.8lx hValue=%8.8lx\r\n"),                    phdNew, phdNew->hValue));            return phdNew->hValue;        }        DEBUGMSG(ZONE_MEMORY, (TEXT("AllocHandle: SetupHandle Failed!\r\n")));        FreeMem(phdNew, HEAP_HDATA);    } else        DEBUGMSG(ZONE_MEMORY, (TEXT("AllocHandle: AllocMem Failed!\r\n")));    return 0;}// Destroy a handle.BOOL FreeHandle(HANDLE h){    PHDATA phd;    if ((phd = (PHDATA)KCall((PKFN)ZapHandle, h)) != 0) {        if (phd->ref.count >= 0x10000)            FreeMem(phd->ref.pFr, HEAP_FULLREF);        FreeMem(phd, HEAP_HDATA);        return TRUE;    }    return FALSE;}// Non-preemtible: copies single refcount to FULLREF.BOOL CopyRefs(HANDLE h, FULLREF *pFr) {    PHDATA phd;    int inx;    KCALLPROFON(12);    h2p(h, phd);    if (phd && phd->ref.count < 0x10000) {        inx = IndexFromLock(phd->lock);        pFr->usRefs[inx] = (ushort)phd->ref.count;        phd->ref.pFr = pFr;	    KCALLPROFOFF(12);        return FALSE;    }    KCALLPROFOFF(12);    return TRUE;}// Non-preemtible worker for IncRef().int DoIncRef(HANDLE h, PPROCESS pprc) {    PHDATA phd;    ACCESSKEY aky;    int inx;    KCALLPROFON(11);    aky = pprc->aky;    inx = pprc->procnum;    h2p(h, phd);    if (phd && phd->lock != 0) {        if (phd->ref.count < 0x10000) {                           if (TestAccess(&phd->lock, &aky)) {                ++phd->ref.count;			    KCALLPROFOFF(11);                return 1;            }		    KCALLPROFOFF(11);            return 2;   // Tell IncRef to allocate a FULLREF.        }        // There is a FULLREF structure. Increment the entry for this        // process and add it to the access key.        AddAccess(&phd->lock, aky);        ++phd->ref.pFr->usRefs[inx];	    KCALLPROFOFF(11);        return 1;    }    KCALLPROFOFF(11);    return 0;}// Returns FALSE if handle not valid or refcnt==0.BOOL IncRef(HANDLE h, PPROCESS pprc){    FULLREF *pFr;    int ret;    while ((ret = KCall(DoIncRef, h, pprc)) == 2) {        // Second process referencing handle. Must allocate        // a FULLREF structure to track references from        // multiple processes.        if ((pFr = AllocMem(HEAP_FULLREF)) == 0)            return FALSE;        memset(pFr,0,sizeof(FULLREF));        if (KCall(CopyRefs, h, pFr)) {            // Another thread already allocated a FULLREF for this handle.            FreeMem(pFr, HEAP_FULLREF);        }    }    return ret;}// Non-preemtible worker for DecRef().BOOL DoDecRef(HANDLE h, PPROCESS pprc, BOOL fAll) {    PHDATA phd;    ACCESSKEY aky;    int inx;    KCALLPROFON(30);    aky = pprc->aky;    inx = pprc->procnum;    h2p(h, phd);    if (phd && TestAccess(&phd->lock, &aky)) {        if (phd->ref.count < 0x10000) {                           if (fAll || phd->ref.count == 1) {                phd->lock = 0;                phd->ref.count = 0;			    KCALLPROFOFF(30);                return TRUE;            }            --phd->ref.count;        } else {            // There is a FULLREF structure. Decrement the entry for this            // process. If the last reference for this process is removed,            // remove its permission to access the handle.            if (fAll || phd->ref.pFr->usRefs[inx] == 1) {                phd->ref.pFr->usRefs[inx] = 0;                if (RemoveAccess(&phd->lock, aky) == 0) {				    KCALLPROFOFF(30);                    return TRUE;				}            } else                --phd->ref.pFr->usRefs[inx];        }    }    KCALLPROFOFF(30);    return FALSE;}// Returns TRUE if all references removed.BOOL DecRef(HANDLE h, PPROCESS pprc, BOOL fAll){    return KCall(DoDecRef, h, pprc, fAll);}BOOL CheckLastRef(HANDLE hTh) {	PHDATA phd;	BOOL bRet;	KCALLPROFON(49);	bRet = TRUE;	h2p(hTh,phd);	if (phd && phd->pvObj && (phd->pci->type==SH_CURTHREAD) && ((THREAD *)(phd->pvObj))->pOwnerProc == pCurProc) {		if (phd->ref.count < 0x10000) {			if (phd->ref.count == 1)				bRet = FALSE;		} else {        	if (phd->ref.pFr->usRefs[pCurProc->procnum] == 1)        		bRet = FALSE;        }    }	KCALLPROFOFF(49);	return bRet;}// Returns 0 if handle is not valid.DWORD GetUserInfo(HANDLE h){    PHDATA phd;    h2p(h, phd);    return phd ? phd->dwInfo : 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -