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

📄 objdisp.c

📁 windows ce 3.00 嵌入式操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

// Returns FALSE if handle is not valid.
BOOL SetUserInfo(HANDLE h, DWORD info)
{
    PHDATA phd;

    h2p(h, phd);
    if (phd) {
        phd->dwInfo = info;
        return TRUE;
    }
    return FALSE;
}

// Returns NULL if handle is not valid.
PVOID GetObjectPtr(HANDLE h)
{
    PHDATA phd;

    h2p(h, phd);
    return phd ? phd->pvObj : 0;
}

// Returns NULL if handle is not valid or not correct type.
PVOID GetObjectPtrByType(HANDLE h, int type)
{
    PHDATA phd;

    h2p(h, phd);
    return (phd && phd->pci && phd->pci->type==type) ? phd->pvObj : 0;
}

PVOID GetObjectPtrByTypePermissioned(HANDLE h, int type)
{
    PHDATA phd;

    h2p(h, phd);
    return (phd && phd->pci && phd->pci->type==type && TestAccess(&phd->lock, &pCurThread->aky)) ? phd->pvObj : 0;
}

// Returns FALSE if handle is not valid.
BOOL SetObjectPtr(HANDLE h, PVOID pvObj)
{
    PHDATA phd;

    h2p(h, phd);
    if (phd) {
        phd->pvObj = pvObj;
        return TRUE;
    }
    return FALSE;
}

// Returns 0 if handle is not valid.
int GetHandleType(HANDLE h)
{
    PHDATA phd;

    h2p(h, phd);
    return (phd && phd->pci != 0) ? phd->pci->type : 0;
}

// SetHandleOwner - switch ownership of a handle
//
//      SetHandleOwner will take a handle that the current process has exclusive
// permission to access and give exclusive access to another process. This is used
// by the file system to switch ownership of handles which are returned by forwarded
// api calls.
//
// NOTE: The handle reference count must be 1.

BOOL SC_SetHandleOwner(HANDLE h, HANDLE hProc)
{
    PPROCESS pprc;
    PHDATA phd;

    if ((phd = HandleToPointer(h)) != 0 && phd->ref.count == 1
            && TestAccess(&phd->lock, &CurAKey)
            && (pprc = HandleToProc(hProc)) != 0) {
        // Zap the old lock with the key from the new owner.
		LockFromKey(&phd->lock, &pprc->aky);
		return TRUE;
    }
    return FALSE;
}


// @func HANDLE | CreateAPISet | Creates an API set
// @rdesc Returns the handle to the API set
// @parm char[4] | acName | class name (for debugging)
// @parm USHORT | cFunctions | # of functions in set
// @parm PFNVOID* | ppfnMethods | array of API functions
// @parm LPDWORD | pdwSig | array of signatures for API functions
// @comm Creates an API set from the list of functions passed in

HANDLE
SC_CreateAPISet(
char acName[4],             /* 'class name' for debugging & QueryAPISetID() */
USHORT cFunctions,          /* # of functions in set */
const PFNVOID *ppfnMethods,       /* array of API functions */
const DWORD *pdwSig)             /* array of signatures for API functions */
{
    PAPISET pas;
    HANDLE hSet;
	if (pCurProc->bTrustLevel != KERN_TRUST_FULL) {
		ERRORMSG(1,(L"SC_CreateAPISet failed due to insufficient trust\r\n"));
	    KSetLastError(pCurThread, ERROR_ACCESS_DENIED);
    	return 0;
	}
    if ((pas = AllocMem(HEAP_APISET)) != 0
            && (hSet = AllocHandle(&cinfAPISet, pas, pCurProc)) != 0) {
        *(PDWORD)pas->cinfo.acName = *(PDWORD)acName;
        pas->cinfo.disp = DISPATCH_PSL;
        pas->cinfo.type = NUM_SYS_HANDLES;
        pas->cinfo.cMethods = cFunctions;
        pas->cinfo.ppfnMethods = ppfnMethods;
        pas->cinfo.pdwSig = pdwSig;
        pas->cinfo.pServer = pCurProc;
        pas->iReg = -1;     /* not a registered handle */
        return hSet;
    } else if (pas != 0)
        FreeMem(pas, HEAP_APISET);
    KSetLastError(pCurThread, ERROR_NOT_ENOUGH_MEMORY);
    return 0;
}


void
SC_CloseAPISet(HANDLE hSet)
{
    PAPISET pas;

    if (DecRef(hSet, pCurProc, FALSE) && (pas = HandleToAPISet(hSet)) != 0) {
        if (pas->iReg != -1 && pas->cinfo.type == 0) {
            SystemAPISets[pas->iReg] = 0;
            KInfoTable[KINX_API_MASK] &= ~(1ul << pas->iReg);
        }
        FreeMem(pas, HEAP_APISET);
        FreeHandle(hSet);
    }
    return;
}

//      @func BOOL | RegisterAPISet | Registers a global APIset
//      @rdesc Returns TRUE on success, else FALSE
//      @parm HANDLE | hASet | handle to API set
//      @parm DWORD | dwSetID | constant identifying which API set to register as
//      @comm Associates the APIset with a slot in the global APIset table

BOOL
SC_RegisterAPISet(HANDLE hSet, DWORD dwSetID)
{
    PAPISET pas;
    BOOL typeOnly, bKPSL;
    int err = ERROR_INVALID_PARAMETER;
	if (pCurProc->bTrustLevel != KERN_TRUST_FULL) {
		ERRORMSG(1,(L"SC_RegisterAPISet failed due to insufficient trust\r\n"));
		KSetLastError(pCurThread,ERROR_ACCESS_DENIED);
		return 0;
	}
    typeOnly = dwSetID >> 31;
    bKPSL = (dwSetID >> 30) & 1;
    dwSetID = dwSetID & 0x3fffffff;
    if (dwSetID == 0) {
        err = ERROR_NO_PROC_SLOTS;
        dwSetID = NUM_SYS_HANDLES;
        while ((dwSetID - 1) > SH_LASTRESERVED)
            if (!SystemAPISets[--dwSetID])
            	break;
    } else
        dwSetID &= 0x7fffffff;
    if ((pas = HandleToAPISet(hSet)) && (pas->iReg == -1) &&
    	(typeOnly ? (dwSetID < SH_LAST_NOTIFY && SystemAPISets[dwSetID] && 
    				 SystemAPISets[dwSetID]->type == dwSetID) :
        			((dwSetID >= SH_LAST_NOTIFY) && (dwSetID < NUM_SYS_HANDLES) && 
        			 !SystemAPISets[dwSetID]))) {
        if (typeOnly) {
            pas->iReg = dwSetID;
            pas->cinfo.type = (uchar)dwSetID;
        } else {
            pas->iReg = dwSetID;
            pas->cinfo.disp = bKPSL ? DISPATCH_I_KPSL : DISPATCH_I_PSL;
            pas->cinfo.type = 0;
            SystemAPISets[dwSetID] = &pas->cinfo;
            KInfoTable[KINX_API_MASK] |= 1ul << dwSetID;
        }
        return TRUE;
    } else {
        RETAILMSG(1, (TEXT("RegisterAPISet failed for api set id %d.\r\n"),dwSetID));
        KSetLastError(pCurThread, err);
    }
    return FALSE;
}

PPROCESS CalcHandleOwner(void) {
	if (pCurThread->pcstkTop) {
		if ((DWORD)pCurThread->pcstkTop->pprcLast >= 0x10000)
			return pCurThread->pcstkTop->pprcLast;
		if ((pCurThread->pcstkTop->pcstkNext) && ((DWORD)pCurThread->pcstkTop->pcstkNext->pprcLast >= 0x10000))
    		return pCurThread->pcstkTop->pcstkNext->pprcLast;
	}    		
	return pCurProc;
}

HANDLE
SC_CreateAPIHandle(HANDLE hSet, LPVOID pvData)
{
    PAPISET pas;
    HANDLE hRet;

    if ((pas = (bAllKMode ? HandleToAPISetPerm(hSet) : HandleToAPISet(hSet))) && (pas->cinfo.disp == DISPATCH_PSL)) {
        if ((hRet = AllocHandle(&pas->cinfo, pvData, CalcHandleOwner())) != 0)
            return hRet;
        KSetLastError(pCurThread, ERROR_NOT_ENOUGH_MEMORY);
    } else
        KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
    return 0;
}


LPVOID
SC_VerifyAPIHandle(HANDLE hSet, HANDLE h)
{
    PAPISET pas;
    PHDATA phd;

    if ((pas = HandleToAPISet(hSet)) != 0) {
        if ((phd = HandleToPointer(h)) != 0
                && TestAccess(&phd->lock, &pCurThread->aky)
                && phd->pci == &pas->cinfo)
            return phd->pvObj;
	    KSetLastError(pCurThread, ERROR_INVALID_HANDLE);
    } else
	    KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
    return 0;
}


// @func int | QueryAPISetID | Lookup an API Set index
// @rdesc Returns the index of the requested API set (-1 if not found)
// @parm PCHAR | pName | the name of the API Set (4 characters or less)
// @comm Looks in the table of registered API Sets to find an API set with
//       the requested name. If one is found, the index of that set is returned.
//       If no matching set is found, then -1 is returned.

int
SC_QueryAPISetID(char *pName)
{
    const CINFO *pci;
    char acName[4];
    int inx;

    for (inx = 0 ; inx < sizeof(acName) ; ++inx) {
        if ((acName[inx] = *pName) != 0)
            pName++;
    }
    if (*pName == 0) {
        for (inx = 0 ; inx < NUM_SYS_HANDLES ; ++inx) {
            if ((pci = SystemAPISets[inx]) != 0
                    && *(PDWORD)pci->acName == *(PDWORD)acName)
                return inx;
        }
    }
    return -1;
}


// @func DWORD | PerformCallback | Performs a call into another address space
// @rdesc Returns the return value from the called function
// @parm PCALLBACKINFO | pcbi | the callback to perform
// @parmvar Zero or more parameters to pass to the function
// @comm Switches into the address space of the process specified in the callback,
//       and then calls the specified function

//NOTE: PerformCallBack() is implemented directly by ObjectCall().

// SetBadHandleError - set error code based upon handle type
//
//  SetBadHandleError uses the handle type from the API call and the method
// index to determine what value to return from an API call on an invalid handle.
// If there is not default behavior, then an exception is raised.

uint SetBadHandleError(int type, long iMethod) {
    RETAILMSG(1, (TEXT("Invalid handle: Set=%d Method=%d\r\n"), type, iMethod));
    KSetLastError(pCurThread, ERROR_INVALID_HANDLE);
    switch (type) {
    case HT_SOCKET:
	    return WSAENOTSOCK;

    case HT_WNETENUM:
        return ERROR_INVALID_HANDLE;
        
    case HT_FILE:
	    if (iMethod == 4 || iMethod == 5)
    	    return 0xFFFFFFFF;
    	return 0;

	case SH_CURTHREAD:
        switch (iMethod) {
	    case ID_THREAD_SUSPEND:
    	case ID_THREAD_RESUME:
            return 0xFFFFFFFF;

        case ID_THREAD_GETTHREADPRIO:
        case ID_THREAD_CEGETPRIO:
            return THREAD_PRIORITY_ERROR_RETURN;
        }
	    return 0;

    case SH_CURPROC:
		return FALSE;

    case HT_DBFILE:
    case HT_DBFIND:
    case HT_FIND:
	case HT_EVENT:
    case HT_APISET:
    case HT_MUTEX:
    case HT_FSMAP:
    case HT_SEMAPHORE:
    	return FALSE;	// just return FALSE
    }

    // Fault the thread.
    RaiseException(STATUS_INVALID_SYSTEM_SERVICE, EXCEPTION_NONCONTINUABLE, 1, &iMethod);
    DEBUGCHK(0);    /* shouldn't get here */
    return 0;
}

// ErrorReturn - return a error value from an invalid API call
//
//  This function is invoked via ObjectCall as a kernel PSL. It extracts a
// return value from the CALLSTACK's access key.

uint ErrorReturn(void) {
    uint ret;
    ret = pCurThread->pcstkTop->akyLast;
    pCurThread->pcstkTop->akyLast = 1;     // Make sure that ServerCallReturn frees the CALLSTACK
    return ret;
}

#ifdef NKPROF
extern BOOL bProfileObjCall;
extern void ProfilerHit(RETADDR ra);
#endif

BOOL TryCloseMappedHandle(HANDLE h);

RETADDR ObjectCall(int *pMode, RETADDR ra, void *args, long iMethod)
{
    const HDATA *phd;
    const CINFO *pci;
    int inx;
    HANDLE h;
    PPROCESS pprc;
    PCALLSTACK pcstk;
    PTHREAD pth;
    LPVOID lpvVal;
    register DWORD dwSig;
    DWORD dwVal, dwBase;
    ACCESSKEY akyCur;
    PCALLBACKINFO pcbi;
    PFNVOID pfn;

	randdw1 = ((randdw1<<5) | (randdw1>>27)) ^ (CurMSec & 0x1f);

    pth = pCurThread;
    /** Setup a kernel PSL CALLSTACK structure. This is done here so that
     * any exceptions are handled correctly.
     */
    // If this fails, we'll fault on setting the retAddr - but we'd only raise an exception if we
    // were checking, anyway.
    pcstk = AllocMem(HEAP_CALLSTACK);
	/* Save return address, previous access key, and extra CPU dependent info */
    pcstk->retAddr = ra;
    akyCur = pcstk->akyLast = pth->aky;
    pcstk->extra = pMode[1];

⌨️ 快捷键说明

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