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

📄 flexptmi.cpp

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

    DEBUGGERMSG (OXZONE_FLEXI, (L"--MarshalProcessesAsModules: 0x%.08x, Idx:%d, Cnt:%d, Offset:%d\r\n",
        hr, rdwIdx, cModElements, riOut));
    return hr;
}

static HRESULT WriteModuleData (MODULE *pmod, DWORD &riOut, const DWORD cbOut, BYTE *pbOut)
{
    FlexiModule mod = {0};
    HRESULT hr = S_OK;

    if (pmod->lpSelf == pmod)
    {
        __try
        {
            WideToAnsi (pmod->lpszModName, mod.szModuleName, CCH_MODULENAME);
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            strcpy (mod.szModuleName, "Unknown");
        }
        DEBUGGERMSG (OXZONE_FLEXI, (L"  WriteModuleData: Module:%a\r\n", mod.szModuleName));

        mod.dwBasePointer = static_cast <DWORD> (ZeroPtr (pmod->BasePtr));
        mod.dwModuleSize = pmod->e32.e32_vsize;
        mod.dwRdWrDataStart = pmod->rwLow;
        mod.dwRdWrDataEnd = pmod->rwHigh;
        mod.dwTimeStamp = pmod->e32.e32_timestamp;

        static ModuleSignature ms;

        // Ignore failure from GetModuleDebugInfo, since some modules may have no debug info
        if (SUCCEEDED (GetModuleDebugInfo( pmod, &ms )))
        {
            mod.dwPdbFormat = ms.dwType;
            mod.PdbGuid = ms.guid;
            mod.dwPdbAge = ms.dwAge;
        }

        mod.dwDllHandle = reinterpret_cast <DWORD> (pmod);
        mod.dwInUse = pmod->inuse;
        mod.wFlags = pmod->wFlags;
        mod.bTrustLevel = pmod->bTrustLevel;

        memcpy (mod.rgwRefCount, pmod->refcnt, sizeof (mod.rgwRefCount));
        mod.dwAddr = reinterpret_cast <DWORD> (pmod);

        hr = Write (&mod, sizeof (mod), riOut, cbOut, pbOut);
    }
    else
    {
        DBGRETAILMSG (OXZONE_ALERT, (L"!!WriteModuleData: 0x%08x is not pointing to a module.\r\n", pmod));
        hr = E_FAIL;
    }
    return hr;
}



static HRESULT MarshalModules (FLEXI_REQUEST *pRequest, DWORD &rdwIdx, 
    DWORD &riOut, const DWORD cbOut, BYTE *pbOut, DWORD *pcElements)
{
    HRESULT hr = S_OK;
    MODULE *pmod = NULL;
    DWORD dwProcMask = 0xFFFFFFFF;
    struct KDataStruct *pKData;
    DWORD cModElements = 0;

    DEBUGGERMSG (OXZONE_FLEXI, (L"++MarshalModules: Idx:%d, Offset:%d\r\n", rdwIdx, riOut));

    pKData = FetchKData ();
    if (!pKData)
        hr = E_FAIL;

    if (SUCCEEDED (hr))
        pmod = (MODULE *)pKData->aInfo[KINX_MODULES];

    // If the user is interested in culling based on process, then find the process
    // that corresponds to this handle.
    if (pRequest->dwRequest & FLEXI_FILTER_PROCESS_HANDLE)
    {
        DWORD i;
        PROCESS *pProcArray = FetchProcArray();

        // By default fail, unless the process can be found.
        hr = E_FAIL;

        for (i = 0; i < MAX_PROCESSES; i++)
        {
            if (pProcArray[i].dwVMBase)
            {
                if (reinterpret_cast<DWORD>(pProcArray[i].hProc) == pRequest->dwHProc)
                {
                    hr = S_OK;
                    dwProcMask = 1 << pProcArray[i].procnum;
                    break;
                }
            }
        }
    }

    while (SUCCEEDED (hr) && pmod && rdwIdx <= pRequest->Mod.dwEnd)
    {
        if (!(pRequest->dwRequest & FLEXI_FILTER_MODULE_HANDLE) || (reinterpret_cast<DWORD>(pmod) == pRequest->dwHMod))
        {
            if (!(pRequest->dwRequest & FLEXI_FILTER_PROCESS_HANDLE) || (pmod->inuse & dwProcMask))
            {
                if (rdwIdx >= pRequest->Mod.dwStart)
                {
                    hr = WriteModuleData (pmod, riOut, cbOut, pbOut);
                    if (SUCCEEDED(hr))
                        cModElements++;
                }
                rdwIdx++;
            }
            else
            {
                DEBUGGERMSG(OXZONE_FLEXI, (L"  MarshalModules: Mod 0x%.08x is not being used by proc 0x%.08x\r\n",
                                           pmod, pRequest->dwHProc));
            }
        }
        else
        {
            DEBUGGERMSG(OXZONE_FLEXI, (L"  MarshalModules: pmod 0x%.08x <> handle 0x%.08x\r\n",
                                       pmod, pRequest->dwHMod));
        }
        pmod = pmod->pMod;
    }

    if (pcElements)
        *pcElements = (SUCCEEDED (hr))? cModElements : 0;

    DEBUGGERMSG (OXZONE_FLEXI, (L"--MarshalModules: 0x%.08x, Idx:%d, Cnt:%d, Offset:%d\r\n",
        hr, rdwIdx, cModElements, riOut));
    return hr;
}


static HRESULT MarshalOneModule (FLEXI_REQUEST *pRequest, DWORD &riOut, const DWORD cbOut, BYTE *pbOut)
{
    HRESULT hr = S_OK;

    DEBUGGERMSG (OXZONE_FLEXI, (L"++MarshalOneModule\r\n"));
    if (pRequest->dwRequest & FLEXI_FILTER_MODULE_POINTER)
    {
        PPROCESS pProcArray = FetchProcArray ();
        void *pv = reinterpret_cast <void *> (pRequest->dwHMod);

        if (pv >= pProcArray && pv < &pProcArray [MAX_PROCESSES])
            hr = WriteProcessDataAsModule (reinterpret_cast <PPROCESS> (pv), riOut, cbOut, pbOut);
        else
            hr = WriteModuleData (reinterpret_cast <MODULE *> (pv), riOut, cbOut, pbOut);
    }
    else
        hr = E_FAIL;

    DEBUGGERMSG (OXZONE_FLEXI, (L"--MarshalOneModule: hr=0x%08x\r\n", hr));
    return hr;
}


static HRESULT MarshalModuleData (FLEXI_REQUEST *pRequest, DWORD &riOut, 
    const DWORD cbOut, BYTE *pbOut, DWORD *pcElements)
{
    HRESULT hr;
    DWORD iModule = 0;
    DWORD cProc = 0;
    DWORD cDll = 0;

    DEBUGGERMSG (OXZONE_FLEXI, (L"++MarshalModuleData: Offset:%d\r\n", riOut));
    hr = MarshalProcessesAsModules (pRequest, iModule, riOut, cbOut, pbOut, &cProc);
    if (SUCCEEDED (hr))
        hr = MarshalModules (pRequest, iModule, riOut, cbOut, pbOut, &cDll);

    if (pcElements)
        *pcElements = (SUCCEEDED (hr))? (cProc + cDll) : 0;

    DEBUGGERMSG (OXZONE_FLEXI, (L"--MarshalModuleData: 0x%.08x, Offset:%d\r\n", hr, riOut));
    return hr;
}


/*++

Routine Name:

    WritePTMResponseHeader

Routine Description:

    Generate the appropriate flexi header for a particular request.  This
    header contains:
    * Size of Header (16-bit) 
    * Size of Field Info Record (16-bit) 
    * Number of Field Info Records (32-bit)
    * Number of Data Elements (32-bit)
    * Offset of Elements from start of buffer (32-bit)

Arguments:
    
    cFieldInfo      - Count of Field Records
    cElements       - Count of Data Elements
    dwElementOffset - Offset of start of Data Elements
    riOut           - Referenced current offset in output buffer.
    cbOut           - Size of the output buffer in bytes.
    pbOut           - Pointer to the start of the output buffer.

Return Values:

    S_OK : Success,
    E_FAIL : General failure,
    E_OUTOFMEMORY : Output buffer is of insufficient size.

--*/
HRESULT WritePTMResponseHeader (DWORD cFieldInfo, DWORD cElements, DWORD dwElementOffset,
    DWORD &riOut, const DWORD cbOut, BYTE *pbOut)
{
    HRESULT hr;

    DEBUGGERMSG (OXZONE_FLEXI, (L"++WritePTMResponseHeader: FieldCnt:%d, ElementCnt:%d, RVA:0x%.08x, Offset:%d\r\n",
        cFieldInfo, cElements, dwElementOffset, riOut));

    hr = Write((WORD)CB_FLEXIPTM_HEADER, riOut, cbOut, pbOut);
    if (SUCCEEDED (hr))
        hr = Write((WORD)CB_FIELDINFO, riOut, cbOut, pbOut);
    if (SUCCEEDED (hr))
        hr = Write(cFieldInfo, riOut, cbOut, pbOut);
    if (SUCCEEDED (hr))
        hr = Write(cElements, riOut, cbOut, pbOut);
    if (SUCCEEDED (hr))
        hr = Write(dwElementOffset, riOut, cbOut, pbOut);

    DEBUGGERMSG (OXZONE_FLEXI, (L"--WritePTMResponseHeader: 0x%.08x\r\n", hr));
    return hr;
}


struct RespSt
{
    DWORD dwHeaderMask;         // Mask for header request
    DWORD dwDescMask;           // Mask for description request
    DWORD dwDataMask;           // Mask for data request
    DWORD dwAddressMask;        // Mask for address request

    HRESULT (*pfnMarshal) (FLEXI_REQUEST *pRequest, DWORD &riOut, 
        const DWORD cbOut, BYTE *pbOut, DWORD *pcElements);
    HRESULT (*pfnMarshalOne) (FLEXI_REQUEST *pRequest, DWORD &riOut,
        const DWORD cbOut, BYTE *pbOut);

    FLEXI_FIELD_INFO *pFields;
    DWORD cFields;
};


/*++

Routine Name:

    WritePTMResponse

Routine Description:

    All flexible api requests have the same format.  This function is generic
    so that if this general format changes, only one change needs to be made.

    This function will write out the header, description, and data (if requested)
    in the proper format.

    On a header only output, the header will be populated with information 
    as if all sections were being written out.

Arguments:
    
    pRequest - Pointer to original request, which is needed for ranges.
    prsp     - Pointer to structure that contains appropriate masks and function
               pointers to call to get data.
    riOut    - in/out The index of the buffer.
    cbOut    - The size of the output buffer.
    pbOut    - The beginning of the output buffer.

Return Value:

    S_OK: Success,
    E_FAIL: Generic error,
    E_OUTOFMEMORY: Output buffer was of insufficient size.

--*/
static HRESULT WritePTMResponse (FLEXI_REQUEST *pRequest, struct RespSt *prsp, 
    DWORD &riOut, const DWORD cbOut, BYTE *pbOut)
{
    HRESULT hr = S_OK;

    // Deterime based on bitflag in request structure which pieces of data to output
    const BOOL fHeader = (pRequest->dwRequest & prsp->dwHeaderMask)? TRUE : FALSE;
    const BOOL fDesc = (pRequest->dwRequest & prsp->dwDescMask)? TRUE : FALSE;
    const BOOL fData = (pRequest->dwRequest & prsp->dwDataMask)? TRUE : FALSE;

    // Header information to keep track of data.
    DWORD iHeaderStart = riOut;     // Remember where the header is supposed to be.
    DWORD iElementStart = 0;        // Remember the ElementRVA
    DWORD cElements = 0;            // Remember the number of elements
    DWORD cFields = 0;              // Remember the number of fields.
    DWORD iVirtualOut = riOut;      // Keep track of the virtual offset for ElementRVA (header only req)
                                    // This will assume that all data is going out.

    DEBUGGERMSG (OXZONE_FLEXI, (L"++WritePTMResponse, Hdr:%d, Desc:%d, Data:%d, Offset:%d\r\n",
        fHeader, fDesc, fData, riOut));
    
    // If the user asks for header, we need to run through the request once
    // to generate the header information.
    if (SUCCEEDED (hr) && fHeader)
    {
        DWORD iStart = riOut;
        hr = WritePTMResponseHeader (cFields, 0, 0, riOut, cbOut, pbOut);
        if (SUCCEEDED(hr))
        {
            // Update the virtual out.
            iVirtualOut += riOut - iStart;
        }
    }

    if (SUCCEEDED (hr))
    {
        BYTE *pbDescOut = NULL;
        DWORD iDescOut = riOut;
        DWORD iDescStart = riOut;

        // If the user asks for field info, then it is ok to use the actual output buffer.
        if (fDesc)
            pbDescOut = pbOut;
            
        // If the user didn't ask for header, we need to tell the user how many field
        // records are being outputed.  Write a 32-bit count.
        if (!fHeader)
            hr = Write (prsp->cFields, iDescOut, cbOut, pbDescOut);
        if (SUCCEEDED (hr))
            hr = WriteFieldInfo (prsp->pFields, prsp->cFields, iDescOut, cbOut, pbDescOut);
        if (SUCCEEDED (hr))
        {
            cFields = prsp->cFields;

            // Update the virtual out by incrementing by size of data output.
            // this allows the virtual out to be a completely different data
            // value from the actual out.  These two should be the same when
            // doing a complete write out.
            iVirtualOut += iDescOut - iDescStart;

            // If the descriptor is really going out, then remember it.
            if (fDesc)
                riOut = iDescOut;
        }
    }

    if (SUCCEEDED (hr))
    {
        BYTE *pbDataOut = NULL;
        DWORD iDataOut = riOut;
        DWORD iDataStart = riOut;

⌨️ 快捷键说明

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