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

📄 objdisp.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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];
        }
    }

    // fAll is TRUE only for closing a process handle while process is exiting. We need to set
    // pvobj to 0 if we don't free the handle. The reason is that other processes still
    // have a handle the the exited process, and we need to make sure that they don't have
    // access to the object anymore.
    if (fAll && phd) {
        DEBUGCHK (phd->pci && (phd->pci->type==SH_CURPROC));
#ifdef DEBUG
        phd->pvObj = (PVOID) 0xabababef;
#else
        phd->pvObj = NULL;
#endif
    }
    KCALLPROFOFF(30);
    return FALSE;
}

//------------------------------------------------------------------------------
// This function MUST BE CALLED Within KCall
// it decrements the ref count of a handle and return the pointer to the HDATA
// *pfFree will be set to TRUE if the handle can be freed, FALSE otherwise
//------------------------------------------------------------------------------
PHDATA TryDecRef (HANDLE h, PPROCESS pprc, BOOL *pfFree)
{
    PHDATA phd;
    h2p (h, phd);
    if (!phd || !TestAccess (&phd->lock, &pprc->aky))
        return NULL;
    *pfFree = DoDecRef (h, pprc, FALSE);
    return phd;
}



//------------------------------------------------------------------------------
// Returns TRUE if all references removed.
//------------------------------------------------------------------------------
BOOL 
DecRef(
    HANDLE h,
    PPROCESS pprc,
    BOOL fAll
    )
{
    return KCall(DoDecRef, h, pprc, fAll);
}


//
// Decrement ref count of a thread
//
BOOL DecThreadRef (HANDLE hTh, PPROCESS pprc)
{
    PHDATA phd;
    BOOL bRet = FALSE;
    ACCESSKEY aky = pprc->aky;
    ushort minref;      // minimum ref count
    KCALLPROFON (49);
    h2p (hTh, phd);
    if (phd && TestAccess(&phd->lock, &aky) && (&cinfThread == phd->pci)) {
        PTHREAD pth = phd->pvObj;

        // min ref count for owner proc is 1 if the thread is still alive
        minref = (pth 
#ifdef DEBUG
            && ((PVOID) 0xabababcd != pth)
#endif
            && (pth->pOwnerProc == pprc))? 1 : 0;

        if (phd->ref.count < 0x10000) {                     // fullref structure?

            // no fullref structure
            if ((phd->ref.count > minref)                   // greater than min ref count?
                && (bRet = !(-- phd->ref.count))) {         // decrement to 0?
                phd->lock = 0;                              // set lock to 0 if true
            }
        } else {

            // fullref structure
            int inx = pprc->procnum;

            bRet = (phd->ref.pFr->usRefs[inx] > minref)     // greater than min ref count?
                && !(-- phd->ref.pFr->usRefs[inx])          // decrement to 0?
                && !RemoveAccess(&phd->lock, aky);          // last process accessing it?

        }
        
    }
    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;
}



//------------------------------------------------------------------------------
// 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);
#ifdef DEBUG
    if (phd && (((PVOID) 0xabababcd == phd->pvObj) || ((PVOID) 0xabababef == phd->pvObj)))
        return 0;
#endif
    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);
#ifdef DEBUG
    if (phd && (((PVOID) 0xabababcd == phd->pvObj) || ((PVOID) 0xabababef == phd->pvObj)))
        return 0;
#endif
    return (phd && phd->pci && phd->pci->type==type) ? phd->pvObj : 0;
}



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

    h2p(h, phd);
#ifdef DEBUG
    if (phd && (((PVOID) 0xabababcd == phd->pvObj) || ((PVOID) 0xabababef == phd->pvObj)))
        return 0;
#endif
    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;

    TRUSTED_API (L"SC_CreateAPISet", NULL);

    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 = (const PFNVOID *) MapPtr (ppfnMethods);
        pas->cinfo.pdwSig = (const DWORD *) MapPtr (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;

    TRUSTED_API (L"SC_RegisterAPISet", FALSE);

    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) 
{
    PCALLSTACK pcstk = pCurThread->pcstkTop;
    
    while (pcstk && (pcstk->dwPrcInfo & CST_IN_KERNEL) && (pcstk->pprcLast != ProcArray)) {
        pcstk = pcstk->pcstkNext;
    }
    return pcstk? pcstk->pprcLast : pCurProc;
}



⌨️ 快捷键说明

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