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

📄 iorm.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:

        // look for the resource domain structure
        for (pdom = g_DomainList, pdomPrevious = NULL; pdom; pdomPrevious = pdom, pdom = pdom->pNext) {
            if (pdom->dwResId == dwResId) {
                break;      // found a match, exit the loop
            }
        }
        
        if(pdom == NULL) {
            dwError = ERROR_FILE_NOT_FOUND;
            goto done;  // no such resource
        }

        // handle deletion differently for dense and sparse tables
        if (pdom->table.dwSize <= gdwMaxDenseResources) {
            // make sure nobody is using the resources
            DWORD dwTrav = 0;
            DenseTable *ptab = &pdom->table.dt;
            for(dwTrav = 0; dwTrav < pdom->table.dwSize; dwTrav++) {
                if(ptab->pUseCount[dwTrav] != 0
                && RBMIsSet(ptab->dwResMax, dwTrav, ptab->prvValid)) {
                    dwError = ERROR_BUSY;
                    break;
                }
            }
        } else {
            // deallocate the list of free ranges -- we don't keep track
            // of which non-free resources have already been handed out.
            SparseTableNode *pnode = pdom->table.st.pFirst;
            while(pnode != NULL) {
                SparseTableNode *pNext = pnode->pNext;
                LocalFree(pnode);
                pnode = pNext;
            }
        }

        // can we delete the entry?
        if(dwError == ERROR_SUCCESS) {
            // yes, remove it from the list and free it
            if(pdomPrevious != NULL) {
                DEBUGCHK(pdomPrevious->pNext == pdom);
                pdomPrevious->pNext = pdom->pNext;
            } else {
                g_DomainList = pdom->pNext;
            }
            LocalFree(pdom);
        }

done:
        ;   // need this to keep the compiler happy
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        dwError = ERROR_GEN_FAILURE;
    }
    
    LeaveCriticalSection(&gcsIORM);

    if(dwError != ERROR_SUCCESS) {
        SetLastError(dwError);
        fOk = FALSE;
    } else {
        fOk = TRUE;
    }

    DEBUGMSG(!fOk && (ZONE_WARNING || ZONE_RESMGR), 
        (_T("IORM: destruction of list id 0x%08x returned %d, error code %d\r\n"), 
        dwResId, fOk, dwError));

    return fOk;
}


// Parse a registry key to set up initially available resources
// Looks like:
//      ResourceName\
//              "Identifier"=dword:1
//              "Minimum"=dword:1
//              "Space"=dword:16
//              "Ranges"="1-15"
//              "Shared"="5,7-9"

static BOOL ScanRange (WCHAR **ps, DWORD *a, DWORD *b)
{
    if (**ps == L'\0')
        return FALSE;  // end of string
    
    *a = wcstoul(*ps, ps, 0);
    if (**ps == L'-')
        *b = wcstoul(*ps+1, ps, 0);
    else
        *b = *a;

    if (*b < *a)
        return FALSE; // invalid range
    else
        *b -= *a - 1;  // turn it into a length

    // incr past the comma (if present) and make
    // sure the char after the comma is not \0.
    // it's ok for **ps to be \0 imm after a conversion.
    if (**ps == L'\0' || **ps == L',' && *++*ps != L'\0')
        return TRUE;
    
    return FALSE; // malformed range
}

static void ResourceInitFromKey (HKEY hk)
{
    DWORD valsz, rsz;
    WCHAR *valbuf, *p;
    DWORD a[3];  // no Resource API takes more than 3 parms

    if (RegQueryInfoKey(hk, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &valsz, NULL, NULL) != ERROR_SUCCESS)
        return;
    __try {
        valbuf = alloca(valsz);
    } 
    __except(EXCEPTION_EXECUTE_HANDLER) {
        valbuf = NULL;
    }

    // create a default 
    if (valbuf == NULL ||
        RegQueryValueEx(hk, L"Identifier", NULL, NULL, (PBYTE)&a[0], ((rsz = sizeof(DWORD)), &rsz)) != ERROR_SUCCESS ||
        RegQueryValueEx(hk, L"Minimum", NULL, NULL, (PBYTE)&a[1], ((rsz = sizeof(DWORD)), &rsz)) != ERROR_SUCCESS ||
        RegQueryValueEx(hk, L"Space", NULL, NULL, (PBYTE)&a[2], ((rsz = sizeof(DWORD)), &rsz)) != ERROR_SUCCESS ||
        IORM_ResourceCreateList(a[0], a[1], a[2]) == FALSE) {
        return;
    }

    // initialize resources based on the registry

    if (RegQueryValueEx(hk, L"Ranges", NULL, NULL, (PBYTE)valbuf, ((rsz = valsz), &rsz)) == ERROR_SUCCESS) {
        p = valbuf;
        while (ScanRange(&p, &a[1], &a[2]))
            IORM_ResourceAdjust(a[0], a[1], a[2], FALSE);	// mark ranges as valid
    }
    if (RegQueryValueEx(hk, L"Shared", NULL, NULL, (PBYTE)valbuf, ((rsz = valsz), &rsz)) == ERROR_SUCCESS) {
        p = valbuf;
        while (ScanRange(&p, &a[1], &a[2])) {
            BOOL fOk = IORM_ResourceMarkAsShareable(a[0], a[1], a[2], TRUE);
            DEBUGCHK(fOk);
        }
    }
}

void ResourceInitFromRegistry (LPCTSTR key)
{
    HKEY hk, hk2;
    WCHAR *sknm;
    DWORD i, sksz, rsz;

    DEBUGCHK( key != NULL );    // not a published API so no need for a retail runtime check
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, 0, &hk) != ERROR_SUCCESS ||
        RegQueryInfoKey(hk, NULL, NULL, NULL, NULL, &sksz, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
        return;

    // get the max table size
    sksz = sizeof(i);
    if(RegQueryValueEx(hk, _T("MaxDenseResources"), NULL, NULL, (LPBYTE) &i, &sksz) == ERROR_SUCCESS) {
        DEBUGMSG(ZONE_INIT, (_T("ResourceInitFromRegistry: max resources set to %d\r\n"),
            gdwMaxDenseResources));
        gdwMaxDenseResources = i;
    }      
    
    sksz += 1; // account for termination
    sksz *= sizeof(*sknm); // convert to bytes
    __try {
        sknm = alloca(sksz);
    } 
    __except(EXCEPTION_EXECUTE_HANDLER) {
        sknm = NULL;
    }
    
    if (sknm != NULL) {
        for (i=0; RegEnumKeyEx(hk, i, sknm, ((rsz = sksz), &rsz), NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++i) {
            if (RegOpenKeyEx(hk, sknm, 0, 0, &hk2) == ERROR_SUCCESS) {
                ResourceInitFromKey(hk2);
                RegCloseKey(hk2);
            }
        }
    }
    
    RegCloseKey(hk);
}

// *** Must be first function called and should only be called once!
// Initializes global variables in this module.
void ResourceInitModule (void)
{
    DEBUGCHK(g_DomainList == NULL); // bss data must be initted to zero by the crt
    g_DomainList = NULL;
    InitializeCriticalSection(&gcsIORM);
    gdwMaxDenseResources = DEF_TABLE_THRESHOLD;
}


#ifdef DEBUG

#ifndef UNIT_TEST
#define OUTPUT(a) DEBUGMSG(1, a)
#else
#define OUTPUT(a) wprintf a
#endif

void ResourceDump (ResourceDomain *pdom)
{
    if (pdom->table.dwSize <= gdwMaxDenseResources) {
        DWORD dwVectorEntries = (pdom->table.dwSize + 31) / 32;
        DWORD dwTrav;
        OUTPUT((TEXT("Resource id 0x%08x has range 0x%x - 0x%x (size 0x%x (%u): DENSE)\n"), 
            pdom->dwResId, pdom->dwOffset, pdom->dwOffset + pdom->table.dwSize - 1, 
            pdom->table.dwSize, pdom->table.dwSize));
        for(dwTrav = 0; dwTrav < dwVectorEntries; dwTrav++) {
            DWORD dwInUse = 0;
            DWORD dwBaseId = dwTrav * 32;
            DWORD dwMaxId = dwBaseId + 32;
            DWORD dwId;

            // figure out which drivers are in use
            if(dwMaxId > pdom->table.dwSize) {
                dwMaxId = pdom->table.dwSize;
            }
            dwMaxId -= dwBaseId;
            for(dwId = 0; dwId < dwMaxId; dwId++) {
                if(RBMIsSet(pdom->table.dwSize, dwId + dwBaseId, pdom->table.dt.prvValid)
                && pdom->table.dt.pUseCount[dwId + dwBaseId] != 0) {
                    dwInUse |= (1 << dwId);
                }
            }

            // display the status
            OUTPUT((TEXT("\tValid/Allocated/Shareable/exclusive %d: 0x%08x 0x%08x 0x%08x\n"), 
                dwTrav, pdom->table.dt.prvValid[dwTrav], dwInUse, pdom->table.dt.prvShareable[dwTrav],
                pdom->table.dt.prvExclusive[dwTrav]));
        }
    } else {
        SparseTableNode *pnod;
        OUTPUT((TEXT("Resource id 0x%08x has range 0x%08x - 0x%08x  (size 0x%08x (%u): SPARSE)\n"), 
            pdom->dwResId, pdom->dwOffset, pdom->dwOffset + pdom->table.dwSize - 1, 
            pdom->table.dwSize, pdom->table.dwSize));
        OUTPUT((TEXT("\tAvailable resources:")));
        pnod = pdom->table.st.pFirst;
        if (pnod == NULL) OUTPUT((TEXT(" *none*")));
        while (pnod) {
            if (pnod->res.len == 0) OUTPUT((TEXT(" 0x%x/*ZEROLENGTH*"), pnod->res.id));
            else if (pnod->res.len == 1) OUTPUT((TEXT(" 0x%x"), pnod->res.id));
            else OUTPUT((TEXT(" 0x%x-0x%x"), pnod->res.id,  pnod->res.id + pnod->res.len - 1));
            pnod = pnod->pNext;
        }
    }
    OUTPUT((TEXT("\n")));
}

void ResourceDumpAll (void)
{
    ResourceDomain *pdom;

    EnterCriticalSection(&gcsIORM);

    pdom = g_DomainList;

    if (pdom == NULL)
        OUTPUT((TEXT("* There are no resource domains defined. *\n")));

    while (pdom) {
        ResourceDump(pdom);
        if (pdom = pdom->pNext)
            OUTPUT((TEXT("\n")));
    }

    LeaveCriticalSection(&gcsIORM);
}

#endif

#ifdef UNIT_TEST
main() {
    char buf[50], c;
    DWORD r, a[3];
    while (1) {
        printf("RES> "); fflush(stdout);
        if (fgets(buf, sizeof(buf), stdin) == NULL) exit(0);
        r = sscanf(buf, "%c %d %d %d", &c, &a[0], &a[1], &a[2]);
        if (r < 1) continue;
        switch (tolower(c)) {
          case 'd':
            if (r == 1)
                ResourceDumpAll();
            else {
                ResourceDomain *d = FindDomain(a[0]);
                if (d == NULL) OUTPUT((TEXT("* No resource domain with id %u. *\n"), a[0]));
                else ResourceDump(d);
            }
            break;
          case 'c':
            if (r < 4) {
                OUTPUT((TEXT("* Create resource domain: c resid min cnt *\n")));
                continue;
            }
            if (ResourceCreateList(a[0], a[1], a[2]))
                OUTPUT((TEXT("Created.\n")));
            else
                OUTPUT((TEXT("FAILED.\n")));
            break;
          case 'g':
            if (r < 3) {
                OUTPUT((TEXT("* Request resources: g resid id [len] *\n")));
                continue;
            }
            if (r < 4)
                a[2] = 1;
            if (ResourceRequest(a[0], a[1], a[2]))
                OUTPUT((TEXT("Granted.\n")));
            else
                OUTPUT((TEXT("DENIED.\n")));
            break;
          case 'f':
            if (r < 3) {
                OUTPUT((TEXT("* Release resources: f resid id [len] *\n")));
                continue;
            }
            if (r < 4)
                a[2] = 1;
            if (ResourceRelease(a[0], a[1], a[2]))
                OUTPUT((TEXT("Released.\n")));
            else
                OUTPUT((TEXT("DENIED.\n")));
            break;
          case 's':
            if (r < 3) {
                OUTPUT((TEXT("* Make resources shareable: s resid id [len] *\n")));
                continue;
            }
            if (r < 4)
                a[2] = 1;
            if (IORM_ResourceMarkAsShareable(a[0], a[1], a[2], TRUE))
                OUTPUT((TEXT("Done.\n")));
            else
                OUTPUT((TEXT("FAILED.\n")));
            break;
          case '$':
            exit(0);
          case '?': case 'h':
            OUTPUT((TEXT("c=create g=request f=release s=share d=dump $=exit\n")));
            break;
        }
    }
}
#endif /* UNIT_TEST */

⌨️ 快捷键说明

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