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

📄 unkhook.cpp

📁 VB圣经
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    return DoMapIID((IID*)iid);
}
STDMETHODIMP
CUnkHookAggregate::get_Flags(UnkHookFlags* puhFlags)
{
    *puhFlags = GetFlags();
    return NOERROR;
}
STDMETHODIMP
CUnkHookAggregate::put_Flags(UnkHookFlags uhFlags)
{
    // This is not allowed externally when an UnknownHook is
    // created by an AggregateUnknown call.
    return CTL_E_SETNOTSUPPORTED; // Facility control, error 383
}

CAggregator::PreAllocData::PreAllocData(AggregateData* pAggData, ULONG cAggElems, ULONG cIIDElems, HRESULT& hrLaunch)
{
    ULONG i;                  // Loop counter
    AggregateData* pCurData;  // Current aggdata for loop
    ULONG cElems;             // A local for counting elements

    ZeroMemory(this, sizeof(*this));

    // Initialize launch as successful
    hrLaunch = NOERROR;

    // Make a pass to get the required IID count
    i = cAggElems;
    pCurData = pAggData;
    while (i--)
    {
        ADFlags& Flags = pCurData->Flags;

        // If we have an object, then we always count the entry
        if (pCurData->pObject &&
            (0 == (Flags & adDontQuery)))
        {
            // Do some flag validation. You can't specify both of these.
            if ((Flags & (adWeakRefRaw | adWeakRefBalanced)) == (adWeakRefRaw | adWeakRefBalanced))
            {
                hrLaunch = E_INVALIDARG;
                return;        
            }

            if ((Flags & adPrimaryDispatch) &&
                !fHaveDispHook)
            {
                cIIDs++;
                fHaveDispHook = true;
            }
            if (Flags & adUseIIDs)
            {
                // Ignore LastIID if Last < First
                cElems = (pCurData->LastIID <= pCurData->FirstIID) ? 
                           1 : pCurData->LastIID - pCurData->FirstIID + 1;
                if (((Flags & adFullyResolved) && cElems != 1) ||
                    ((cElems + (ULONG)pCurData->FirstIID) > cIIDElems))
                {
                    hrLaunch = DISP_E_BADINDEX;
                    return;
                }
                cIIDs += cElems;
            }
            else
            {
                // Can't delay create without adUseIIDs
                if (Flags & adDelayCreation)
                {
                    hrLaunch = E_INVALIDARG;
                    return;
                }

                cUnfiltered++;
                if (Flags & adBeforeHookedUnknown)
                {
                    cUnfilteredBefore++;
                }
                if (Flags & adNoDelegator)
                {
                    cUnfilteredNoDelegator++;
                }
            }
        }
        // If we don't have an object, then this is an attempt to
        // change the primary dispatch to something other than the primary object.
        else if (pCurData->pObject == NULL &&
                 ((Flags & (adPrimaryDispatch | adUseIIDs)) == (adPrimaryDispatch | adUseIIDs)) &&
                 !fHaveDispHook)
        {
            // We only use the first IID
            if ((ULONG)pCurData->FirstIID >= cIIDElems)
            {
                hrLaunch = DISP_E_BADINDEX;
                return;
            }
            cIIDs++;
            fHaveDispHook = true;
        }
        else if (Flags & adMapIID)
        {
            if ((ULONG)pCurData->FirstIID >= cIIDElems ||
                (ULONG)pCurData->LastIID >= cIIDElems)
            {
                hrLaunch = DISP_E_BADINDEX;
                return;
            }
            cIIDMaps++;
            cIIDMapAndBlockElems++;
        }
        else if (Flags & adBlockIIDs)
        {
            // Ignore LastIID if Last < First
            cElems = (pCurData->LastIID <= pCurData->FirstIID) ? 
                       1 : pCurData->LastIID - pCurData->FirstIID + 1;
            if ((cElems + (ULONG)pCurData->FirstIID) > cIIDElems)
            {
                hrLaunch = DISP_E_BADINDEX;
                return;
            }
            cIIDBlocks += cElems;
            cIIDMapAndBlockElems++;
        }
        pCurData++;
    }

    // Figure out bytes count for the Unknown elements, as well as the
    // IID maps.  These are all of the items in CAggregator that are
    // created with the object instead of the FSMM.
    cExtraBytes = (cAggElems - cIIDMapAndBlockElems) * sizeof(CAggregator::CHoldUnk)
                   + cIIDMaps * sizeof(CAggregator::IIDMapEntry)
                   + cIIDBlocks * sizeof(IID);
}
CAggregator::CAggregator(AggregateData* pAggData, ULONG cAggElems, IID* pIIDs, PreAllocData& rPAD, HRESULT& hrLaunch, IUnknown* punkControlling)
      // Put anything here that would cause a problem
      // in the destructor if it weren't initialized.
    : m_pUnks(NULL),
      m_pIIDMaps(NULL),
      m_pBlockIIDs(NULL),
      m_pFSMMNodes(NULL)
{
    ULONG i;              // Loop counter
    AggregateData* pCurData;  // Current aggdata for loop
    ULONG cElems;             // A local for counting elements
    ULONG cFiltered;      // The number of encountered filtered objects.  Order in these doesn't matter, so they're tossed at the end.
    ULONG iCurEntry;      // The location in the m_pUnks array where the current element is stored
    IIDHookNode* pCurNode; // The node currently being worked on.
    IID* pCurIID;         // A loop iterator for items in the IID array
    IIDMapEntry* pCurMap; // The current position in the m_pIIDMaps array
    IID* pCurBlockIID;    // The current position in the m_pBlockIIDs array

    // Initialize launch as successful
    hrLaunch = NOERROR;

    m_cIIDMaps = rPAD.cIIDMaps;
    m_cBlockIIDs = rPAD.cIIDBlocks;
    m_cUnks = cAggElems - rPAD.cIIDMapAndBlockElems;

    // Start allocating our memory
    cElems = rPAD.cIIDs;
    if (i = rPAD.cUnfiltered - rPAD.cUnfilteredNoDelegator)
    {
        cElems += 2 * i;
        if (cElems < 4) cElems = 4;
    }
    if (cElems)
    {
        if (FAILED(hrLaunch = CFixedMemMgr::CreateInstance(sizeof(IIDHookNode), 
            // Try to alloc enough to get us through this routine up front,
            // plus two slots for each unfiltered item.  If this succeeds, then
            // we don't have to worry about FSMM->Alloc calls failing in this routine.
            cElems,
            &m_pFSMMNodes)))
        {
            return;
        }
    }

    if (rPAD.cExtraBytes)
    {
        // Zeroing is sufficient.  CHoldUnk and IIDMapNode
        // both need to be zero initialized.
        ZeroMemory(rPAD.pExtraBytes, rPAD.cExtraBytes);
    }

    if (m_cUnks)
    {
        //Change this block of code if CHoldUnk's constructor changes
        //CHoldUnk* pHoldUnk;   // A loop iterator for CHoldUnk items
        m_pUnks = (CHoldUnk*)rPAD.pExtraBytes;
        //i = m_cUnks;
        //pHoldUnk = m_pUnks;
        //while (i--)
        //{
        //    new ((void*)pHoldUnk) CHoldUnk;            
        //    pHoldUnk++;
        //}
        rPAD.pExtraBytes = (BYTE*)rPAD.pExtraBytes + m_cUnks * sizeof(CHoldUnk);
    }

    if (m_cIIDMaps)
    {
        // These are sufficiently constructed with the ZeroMemory on
        // the extra bytes
        pCurMap = m_pIIDMaps = (IIDMapEntry*)rPAD.pExtraBytes;
        rPAD.pExtraBytes = (BYTE*)rPAD.pExtraBytes + m_cIIDMaps * sizeof(IIDMapEntry);
    }

    if (m_cBlockIIDs)
    {
        pCurBlockIID = m_pBlockIIDs = (IID*)rPAD.pExtraBytes;
    }
    m_cUnfilteredBefore = m_cUnfilteredAfter = 0;

    // Now, actually fill the arrays
    i = cAggElems;
    pCurData = pAggData;
    cFiltered = 0;
    while (i--)
    {
        ADFlags& Flags = pCurData->Flags;
        if (pCurData->pObject)
        {
            if (Flags & adDontQuery)
            {
                // Just toss it near the end of the list.  This entry won't be referenced by
                // any IIDData, so it doesn't hurt anything.
                m_pUnks[m_cUnks - cFiltered - 1] = pCurData->pObject;
                cFiltered++;
            }
            else
            {
                if (Flags & adUseIIDs)
                {
                    // We have a filtered item (it gets sent only predefined IIDs)

                    // Find out how many IIDs we have.
                    // Ignore LastIID if Last < First
                    cElems = (pCurData->LastIID <= pCurData->FirstIID) ? 
                               1 : pCurData->LastIID - pCurData->FirstIID + 1;
                    
                    // We just throw this anywhere at the end of the array.
                    iCurEntry = m_cUnks - cFiltered - 1;
                    cFiltered++;
                    pCurIID = &pIIDs[pCurData->FirstIID];
                    IIDHookNodeList& rNodeList = (Flags & adBeforeHookedUnknown) ? m_BeforeNodes : m_AfterNodes;
                    while (cElems--)
                    {
                        // FSMM allocates the first chunk with the object,
                        // so this can't fail.
                        m_pFSMMNodes->Alloc((long*)&pCurNode);
                        pCurNode->iid = *pCurIID;
                        pCurNode->iUnk = (short)iCurEntry;
                        rNodeList.AddTail(pCurNode);
                        pCurIID++;
                    }

                    // The delayed creation flag is ignored if no IID's are specified, so
                    // we must check it in here.
                    if (Flags & adDelayCreation)
                    {
                        // If we're delaying creation, then there's some
                        // more work to do.
                        IDelayCreation* pDelay;
                        IUnknown* pTest = NULL;
                        HRESULT hr;
                        if (SUCCEEDED(hr = pCurData->pObject->QueryInterface(IID_IDelayCreation, (void**)&pDelay)))
                        {
                            m_pUnks[iCurEntry] = pDelay;
                            if (punkControlling &&
                                SUCCEEDED(hr = pDelay->QueryInterface(IID_IUnknown, (void**)&pTest)))
                            {
                                if (pTest == punkControlling)
                                {
                                    m_pUnks[iCurEntry].SetWeakRef();
                                    // Keep the reference on pDelay and release
                                    // a reference on the controlling IUnknown to
                                    // stay balanced.
                                    pTest->Release();
                                }
                                pTest->Release();
                            }
                            m_pUnks[iCurEntry].SetDelayedCreation();
                            if ((Flags & adDelayDontCacheResolved) == adDelayDontCacheResolved) // Two bit flag, need ==
                            {
                                m_pUnks[iCurEntry].SetKeepDelayed();
                            }
                            pDelay->Release();

                            if (Flags & adWeakRefBalanced)
                            {
                                m_pUnks[iCurEntry].SetExplicitWeakRef();
                            }
                            else if (Flags & adWeakRefRaw)
                            {
                                m_pUnks[iCurEntry].SetRawWeakRef();
                            }
                        }
                        if (FAILED(hr))
                        {
                            hrLaunch = DISP_E_TYPEMISMATCH;
                            return;
                        }
                    }

                    // Flag if we're fully resolved. This applies to items that
                    // are delay created as well as items with a single IID.
                    if (Flags & adFullyResolved)
                    {
                        m_pUnks[iCurEntry].SetFullyResolved();
                    }
                }
                else
                {
                    // This is an unfiltered item (it gets blindly sent IIDs)
                    if (Flags & adBeforeHookedUnknown)
                    {
                        iCurEntry = m_cUnfilteredBefore;
                        m_cUnfilteredBefore++;
                    }
                    else
                    {
                        iCurEntry = rPAD.cUnfilteredBefore + m_cUnfilteredAfter;
                        m_cUnfilteredAfter++;
                    }
                }

                // Share object assignment code for both filtered and blind cases.
                if (0 == (Flags & adDelayCreation))
                {
                    CHoldUnk& rHoldUnk = m_pUnks[iCurEntry];
                    if (Flags & adWeakRefRaw)
                    {
                        rHoldUnk.AssignRawWeakRef(pCurData->pObject);
                    }
                    else
                    {
                        rHoldUnk = pCurData->pObject;
                        if (Flags & adWeakRefBalanced)
                        {
                            IUnknown* punkControl = NULL;
                            pCurData->pObject->QueryInterface(IID_IUnknown, (void**)&punkControl);
                            if (punkControl)
                            {
                                punkControl->Release();
                                punkControl->Release();
                                rHoldUnk.SetWeakRef();
                            }
                        }
                    }
                }

                // See if the blind delegation has been
                // explicitly turned off.
                if (Flags & adNoDelegator)
                {
                    m_pUnks[iCurEntry].SetNoDelegator();
                }

                
                // If we found a primary dispatch request
                // during the initial pass and we haven't found
                // one yet, then deal with it the same as a 
                // before request.  An IDispatch can come on
                // a filtered or unfiltered object, and always
                // comes before.
                if (rPAD.fHaveDispHook &&
                    (Flags & adPrimaryDispatch))
                {
                    m_pFSMMNodes->Alloc((long*)&pCurNode);
                    pCurNode->iid = IID_IDispatch;
                    pCurNode->iUnk = (short)iCurEntry;
                    m_BeforeNodes.AddTail(pCurNode);
                    rPAD.fHaveDispHook = false;
                }
            }
        }
        else if (rPAD.fHaveDispHook &&
                 ((Flags & (adPrimaryDispatch | adUseIIDs)) == (adPrimaryDispatch | adUseIIDs)))
        {
            // This is a special case.  We're remapping the

⌨️ 快捷键说明

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