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

📄 typelib.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
        case VT_UI2 :
        case VT_UI4 :
        case VT_INT :
        case VT_UINT    :
        case VT_VOID    : /* FIXME: is this right? */
        case VT_HRESULT :
            size=4; break;
        case VT_R8  :
        case VT_CY  :
        case VT_DATE    :
        case VT_I8  :
        case VT_UI8 :
        case VT_DECIMAL :  /* FIXME: is this right? */
        case VT_FILETIME :
            size=8;break;
            /* pointer types with known behaviour */
        case VT_BSTR    :{
            char * ptr;
            MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
	    if(size < 0) {
                char next;
                DWORD origPos = MSFT_Tell(pcx), nullPos;

                do {
                    MSFT_Read(&next, 1, pcx, DO_NOT_SEEK);
                } while (next);
                nullPos = MSFT_Tell(pcx);
                size = nullPos - origPos;
                MSFT_Seek(pcx, origPos);
	    }
            ptr=TLB_Alloc(size);/* allocate temp buffer */
            MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */
            V_BSTR(pVar)=SysAllocStringLen(NULL,size);
            /* FIXME: do we need a AtoW conversion here? */
            V_UNION(pVar, bstrVal[size])='\0';
            while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
            TLB_Free(ptr);
	}
	size=-4; break;
    /* FIXME: this will not work AT ALL when the variant contains a pointer */
        case VT_DISPATCH :
        case VT_VARIANT :
        case VT_UNKNOWN :
        case VT_PTR :
        case VT_SAFEARRAY :
        case VT_CARRAY  :
        case VT_USERDEFINED :
        case VT_LPSTR   :
        case VT_LPWSTR  :
        case VT_BLOB    :
        case VT_STREAM  :
        case VT_STORAGE :
        case VT_STREAMED_OBJECT :
        case VT_STORED_OBJECT   :
        case VT_BLOB_OBJECT :
        case VT_CF  :
        case VT_CLSID   :
        default:
            size=0;
            FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
                V_VT(pVar));
    }

    if(size>0) /* (big|small) endian correct? */
        MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );
    return;
}
/*
 * create a linked list with custom data
 */
static int MSFT_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
{
    MSFT_CDGuid entry;
    TLBCustData* pNew;
    int count=0;

    TRACE_(typelib)("\n");

    while(offset >=0){
        count++;
        pNew=TLB_Alloc(sizeof(TLBCustData));
        MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset);
        MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
        MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
        /* add new custom data at head of the list */
        pNew->next=*ppCustData;
        *ppCustData=pNew;
        offset = entry.next;
    }
    return count;
}

static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd,
			  ITypeInfoImpl *pTI)
{
    if(type <0)
        pTd->vt=type & VT_TYPEMASK;
    else
        *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];

    if(pTd->vt == VT_USERDEFINED)
      MSFT_DoRefType(pcx, pTI->pTypeLib, pTd->u.hreftype);

    TRACE_(typelib)("vt type = %X\n", pTd->vt);
}

static void MSFT_ResolveReferencedTypes(TLBContext *pcx, ITypeInfoImpl *pTI, TYPEDESC *lpTypeDesc)
{
    /* resolve referenced type if any */
    while (lpTypeDesc)
    {
        switch (lpTypeDesc->vt)
        {
        case VT_PTR:
            lpTypeDesc = lpTypeDesc->u.lptdesc;
            break;

        case VT_CARRAY:
            lpTypeDesc = & (lpTypeDesc->u.lpadesc->tdescElem);
            break;

        case VT_USERDEFINED:
            MSFT_DoRefType(pcx, pTI->pTypeLib,
                           lpTypeDesc->u.hreftype);

            lpTypeDesc = NULL;
            break;

        default:
            lpTypeDesc = NULL;
        }
    }
}

static void
MSFT_DoFuncs(TLBContext*     pcx,
	    ITypeInfoImpl*  pTI,
            int             cFuncs,
            int             cVars,
            int             offset,
            TLBFuncDesc**   pptfd)
{
    /*
     * member information is stored in a data structure at offset
     * indicated by the memoffset field of the typeinfo structure
     * There are several distinctive parts.
     * The first part starts with a field that holds the total length
     * of this (first) part excluding this field. Then follow the records,
     * for each member there is one record.
     *
     * The first entry is always the length of the record (including this
     * length word).
     * The rest of the record depends on the type of the member. If there is
     * a field indicating the member type (function, variable, interface, etc)
     * I have not found it yet. At this time we depend on the information
     * in the type info and the usual order how things are stored.
     *
     * Second follows an array sized nrMEM*sizeof(INT) with a member id
     * for each member;
     *
     * Third is an equal sized array with file offsets to the name entry
     * of each member.
     *
     * The fourth and last (?) part is an array with offsets to the records
     * in the first part of this file segment.
     */

    int infolen, nameoffset, reclength, nrattributes, i;
    int recoffset = offset + sizeof(INT);

    char *recbuf = HeapAlloc(GetProcessHeap(), 0, 0xffff);
    MSFT_FuncRecord * pFuncRec=(MSFT_FuncRecord *) recbuf;
    TLBFuncDesc *ptfd_prev = NULL;

    TRACE_(typelib)("\n");

    MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);

    for ( i = 0; i < cFuncs ; i++ )
    {
        *pptfd = TLB_Alloc(sizeof(TLBFuncDesc));

        /* name, eventually add to a hash table */
        MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
                          offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));

        /* nameoffset is sometimes -1 on the second half of a propget/propput
         * pair of functions */
        if ((nameoffset == -1) && (i > 0))
            (*pptfd)->Name = SysAllocString(ptfd_prev->Name);
        else
            (*pptfd)->Name = MSFT_ReadName(pcx, nameoffset);

        /* read the function information record */
        MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);

        reclength &= 0xffff;

        MSFT_ReadLEDWords(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);

        /* do the attributes */
        nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18)
                       / sizeof(int);

        if ( nrattributes > 0 )
        {
            (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;

            if ( nrattributes > 1 )
            {
                (*pptfd)->HelpString = MSFT_ReadString(pcx,
                                                      pFuncRec->OptAttr[1]) ;

                if ( nrattributes > 2 )
                {
                    if ( pFuncRec->FKCCIC & 0x2000 )
                    {
                       if (HIWORD(pFuncRec->OptAttr[2]) != 0)
                           ERR("ordinal 0x%08x invalid, HIWORD != 0\n", pFuncRec->OptAttr[2]);
                       (*pptfd)->Entry = (BSTR)pFuncRec->OptAttr[2];
                    }
                    else
                    {
                        (*pptfd)->Entry = MSFT_ReadString(pcx,
                                                         pFuncRec->OptAttr[2]);
                    }
                    if( nrattributes > 5 )
                    {
                        (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;

                        if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 )
                        {
                            MSFT_CustData(pcx,
					  pFuncRec->OptAttr[6],
					  &(*pptfd)->pCustData);
                        }
                    }
                }
                else
                {
                    (*pptfd)->Entry = (BSTR)-1;
                }
            }
        }

        /* fill the FuncDesc Structure */
        MSFT_ReadLEDWords( & (*pptfd)->funcdesc.memid, sizeof(INT), pcx,
                           offset + infolen + ( i + 1) * sizeof(INT));

        (*pptfd)->funcdesc.funckind   =  (pFuncRec->FKCCIC)      & 0x7;
        (*pptfd)->funcdesc.invkind    =  (pFuncRec->FKCCIC) >> 3 & 0xF;
        (*pptfd)->funcdesc.callconv   =  (pFuncRec->FKCCIC) >> 8 & 0xF;
        (*pptfd)->funcdesc.cParams    =   pFuncRec->nrargs  ;
        (*pptfd)->funcdesc.cParamsOpt =   pFuncRec->nroargs ;
        (*pptfd)->funcdesc.oVft       =   pFuncRec->VtableOffset ;
        (*pptfd)->funcdesc.wFuncFlags =   LOWORD(pFuncRec->Flags) ;

        MSFT_GetTdesc(pcx,
		      pFuncRec->DataType,
		      &(*pptfd)->funcdesc.elemdescFunc.tdesc,
		      pTI);
        MSFT_ResolveReferencedTypes(pcx, pTI, &(*pptfd)->funcdesc.elemdescFunc.tdesc);

        /* do the parameters/arguments */
        if(pFuncRec->nrargs)
        {
            int j = 0;
            MSFT_ParameterInfo paraminfo;

            (*pptfd)->funcdesc.lprgelemdescParam =
                TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));

            (*pptfd)->pParamDesc =
                TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc));

            MSFT_ReadLEDWords(&paraminfo, sizeof(paraminfo), pcx,
                              recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));

            for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
            {
                ELEMDESC *elemdesc = &(*pptfd)->funcdesc.lprgelemdescParam[j];

                MSFT_GetTdesc(pcx,
			      paraminfo.DataType,
			      &elemdesc->tdesc,
			      pTI);

                elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags;

                /* name */
                if (paraminfo.oName == -1)
                    /* this occurs for [propput] or [propget] methods, so
                     * we should just set the name of the parameter to the
                     * name of the method. */
                    (*pptfd)->pParamDesc[j].Name = SysAllocString((*pptfd)->Name);
                else
                    (*pptfd)->pParamDesc[j].Name =
                        MSFT_ReadName( pcx, paraminfo.oName );
                TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w((*pptfd)->pParamDesc[j].Name));

                MSFT_ResolveReferencedTypes(pcx, pTI, &elemdesc->tdesc);

                /* default value */
                if ( (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) &&
                     (pFuncRec->FKCCIC & 0x1000) )
                {
                    INT* pInt = (INT *)((char *)pFuncRec +
                                   reclength -
                                   (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );

                    PARAMDESC* pParamDesc = &elemdesc->u.paramdesc;

                    pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
                    pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);

		    MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
                        pInt[j], pcx);
                }
                else
                    elemdesc->u.paramdesc.pparamdescex = NULL;
                /* custom info */
                if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 )
                {
                    MSFT_CustData(pcx,
				  pFuncRec->OptAttr[7+j],
				  &(*pptfd)->pParamDesc[j].pCustData);
                }

                /* SEEK value = jump to offset,
                 * from there jump to the end of record,
                 * go back by (j-1) arguments
                 */
                MSFT_ReadLEDWords( &paraminfo ,
			   sizeof(MSFT_ParameterInfo), pcx,
			   recoffset + reclength - ((pFuncRec->nrargs - j - 1)
					       * sizeof(MSFT_ParameterInfo)));
            }
        }

        /* scode is not used: archaic win16 stuff FIXME: right? */
        (*pptfd)->funcdesc.cScodes   = 0 ;
        (*pptfd)->funcdesc.lprgscode = NULL ;

        ptfd_prev = *pptfd;
        pptfd      = & ((*pptfd)->next);
        recoffset += reclength;
    }
    HeapFree(GetProcessHeap(), 0, recbuf);
}

static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
		       int cVars, int offset, TLBVarDesc ** pptvd)
{
    int infolen, nameoffset, reclength;
    char recbuf[256];
    MSFT_VarRecord * pVarRec=(MSFT_VarRecord *) recbuf;
    int i;
    int recoffset;

    TRACE_(typelib)("\n");

    MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
    MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
                      ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
    recoffset += offset+sizeof(INT);
    for(i=0;i<cVars;i++){
        *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
    /* name, eventually add to a hash table */
        MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
                          offset + infolen + (2*cFuncs + cVars + i + 1) * sizeof(INT));
        (*pptvd)->Name=MSFT_ReadName(pcx, nameoffset);
    /* read the variable information record */
        MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
        reclength &=0xff;
        MSFT_ReadLEDWords(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
    /* Optional data */
        if(reclength >(6*sizeof(INT)) )
            (*pptvd)->HelpContext=pVarRec->HelpContext;
        if(reclength >(7*sizeof(INT)) )
            (*pptvd)->HelpString = MSFT_ReadString(pcx, pVarRec->oHelpString) ;
        if(reclength >(8*sizeof(INT)) )
        if(reclength >(9*sizeof(INT)) )
            (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
    /* fill the VarDesc Structure */
        MSFT_ReadLEDWords(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
                          offset + infolen + (cFuncs + i + 1) * sizeof(INT));
        (*pptvd)->vardesc.varkind = pVarRec->VarKind;
        (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
        MSFT_GetTdesc(pcx, pVarRec->DataType,
            &(*pptvd)->vardesc.elemdescVar.tdesc, pTI);
/*   (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
        if(pVarRec->VarKind == VAR_CONST ){
            (*pptvd)->vardesc.u.lpvarValue=TLB_Alloc(sizeof(VARIANT));
            MSFT_ReadValue((*pptvd)->vardesc.u.lpvarValue,
                pVarRec->OffsValue, pcx);
        } else
            (*pptvd)->vardesc.u

⌨️ 快捷键说明

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