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

📄 typelib2.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
	foo.next_hash = -1;
	guidoffset = ctl2_alloc_guid(This->typelib, &foo);
	if (guidoffset == -1) return E_OUTOFMEMORY;

	fileoffset =  ctl2_alloc_importfile(This->typelib, guidoffset, 2, 0, stdole2tlb);
	if (fileoffset == -1) return E_OUTOFMEMORY;

	foo.guid = IID_IDispatch;
	foo.hreftype = 1;
	foo.next_hash = -1;
	guidoffset = ctl2_alloc_guid(This->typelib, &foo);
	if (guidoffset == -1) return E_OUTOFMEMORY;

	impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID;
	impinfo.oImpFile = fileoffset;
	impinfo.oGuid = guidoffset;
	ctl2_alloc_importinfo(This->typelib, &impinfo);

	This->typelib->typelib_header.dispatchpos = 1;

	This->typeinfo->typekind |= 0x10;
	This->typeinfo->typekind &= ~0x0f;
	This->typeinfo->typekind |= TKIND_DISPATCH;
    }

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetDocString {OLEAUT32}
 *
 *  See ICreateTypeInfo_SetDocString.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(
        ICreateTypeInfo2* iface,
        LPOLESTR pStrDoc)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_w(pStrDoc));

    offset = ctl2_alloc_string(This->typelib, pStrDoc);
    if (offset == -1) return E_OUTOFMEMORY;
    This->typeinfo->docstringoffs = offset;
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetHelpContext {OLEAUT32}
 *
 *  See ICreateTypeInfo_SetHelpContext.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(
        ICreateTypeInfo2* iface,
        DWORD dwHelpContext)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    TRACE("(%p,%d)\n", iface, dwHelpContext);

    This->typeinfo->helpcontext = dwHelpContext;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetVersion {OLEAUT32}
 *
 *  See ICreateTypeInfo_SetVersion.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(
        ICreateTypeInfo2* iface,
        WORD wMajorVerNum,
        WORD wMinorVerNum)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);

    This->typeinfo->version = wMajorVerNum | (wMinorVerNum << 16);
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_AddRefTypeInfo {OLEAUT32}
 *
 *  See ICreateTypeInfo_AddRefTypeInfo.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(
        ICreateTypeInfo2* iface,
        ITypeInfo* pTInfo,
        HREFTYPE* phRefType)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    ITypeLib *container;
    UINT index;
    HRESULT res;

    TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType);

    /*
     * If this is one of ours, we set *phRefType to the TYPEINFO offset of
     * the referred TypeInfo. Otherwise, we presumably have more magic to do.
     *
     * Unfortunately, we can't rely on the passed-in TypeInfo even having the
     * same internal structure as one of ours. It could be from another
     * implementation of ITypeInfo. So we need to do the following...
     */
    res = ITypeInfo_GetContainingTypeLib(pTInfo, &container, &index);
    if (!SUCCEEDED(res)) {
	TRACE("failed to find containing typelib.\n");
	return res;
    }

    if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) {
	*phRefType = This->typelib->typelib_typeinfo_offsets[index];
    } else {
	FIXME("(%p,%p,%p), pTInfo from different typelib.\n", iface, pTInfo, phRefType);
    }

    ITypeLib_Release(container);
    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_AddFuncDesc {OLEAUT32}
 *
 *  See ICreateTypeInfo_AddFuncDesc.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
        ICreateTypeInfo2* iface,
        UINT index,
        FUNCDESC* pFuncDesc)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    int offset;
    int *typedata;
    int i;
    int decoded_size;

    FIXME("(%p,%d,%p), stub!\n", iface, index, pFuncDesc);
    FIXME("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
/*     FIXME("{%d, %d}\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt, pFuncDesc->lprgelemdescParam[1].tdesc.vt); */
/*     return E_OUTOFMEMORY; */
    
    if (!This->typedata) {
	This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000);
	This->typedata[0] = 0;
    }

    /* allocate type data space for us */
    offset = This->typedata[0];
    This->typedata[0] += 0x18 + (pFuncDesc->cParams * 12);
    typedata = This->typedata + (offset >> 2) + 1;

    /* fill out the basic type information */
    typedata[0] = (0x18 + (pFuncDesc->cParams * 12)) | (index << 16);
    ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size);
    typedata[2] = pFuncDesc->wFuncFlags;
    typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | This->typeinfo->cbSizeVft;
    typedata[4] = (index << 16) | (pFuncDesc->callconv << 8) | 9;
    typedata[5] = pFuncDesc->cParams;

    /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */
    /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */
    typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16;

    for (i = 0; i < pFuncDesc->cParams; i++) {
	ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc, &typedata[6+(i*3)], NULL, NULL, &decoded_size);
	typedata[7+(i*3)] = -1;
	typedata[8+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
	typedata[3] += decoded_size << 16;

#if 0
	/* FIXME: Doesn't work. Doesn't even come up with usable VTs for varDefaultValue. */
	if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
	    ctl2_alloc_custdata(This->typelib, &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
	}
#endif
    }

    /* update the index data */
    This->indices[index] = ((0x6000 | This->typeinfo->cImplTypes) << 16) | index;
    This->names[index] = -1;
    This->offsets[index] = offset;

    /* ??? */
    if (!This->typeinfo->res2) This->typeinfo->res2 = 0x20;
    This->typeinfo->res2 <<= 1;

    /* ??? */
    if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0;
    This->typeinfo->res3 += 0x38;

    /* ??? */
    if (index < 2) This->typeinfo->res2 += pFuncDesc->cParams << 4;
    This->typeinfo->res3 += pFuncDesc->cParams << 4;

    /* adjust size of VTBL */
    This->typeinfo->cbSizeVft += 4;

    /* Increment the number of function elements */
    This->typeinfo->cElement += 1;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_AddImplType {OLEAUT32}
 *
 *  See ICreateTypeInfo_AddImplType.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
        ICreateTypeInfo2* iface,
        UINT index,
        HREFTYPE hRefType)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    TRACE("(%p,%d,%d)\n", iface, index, hRefType);

    if ((This->typeinfo->typekind & 15) == TKIND_COCLASS) {
	int offset;
	MSFT_RefRecord *ref;

	if (index == 0) {
	    if (This->typeinfo->datatype1 != -1) return TYPE_E_ELEMENTNOTFOUND;

	    offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
	    if (offset == -1) return E_OUTOFMEMORY;

	    This->typeinfo->datatype1 = offset;
	} else {
	    int lastoffset;

	    lastoffset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index - 1);
	    if (lastoffset == -1) return TYPE_E_ELEMENTNOTFOUND;

	    ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][lastoffset];
	    if (ref->onext != -1) return TYPE_E_ELEMENTNOTFOUND;

	    offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
	    if (offset == -1) return E_OUTOFMEMORY;

	    ref->onext = offset;
	}

	ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];

	ref->reftype = hRefType;
	ref->flags = 0;
	ref->oCustData = -1;
	ref->onext = -1;
    } else if ((This->typeinfo->typekind & 15) == TKIND_DISPATCH) {
	FIXME("dispatch case unhandled.\n");
    } else if ((This->typeinfo->typekind & 15) == TKIND_INTERFACE) {
	if (This->typeinfo->cImplTypes) {
	    return (index == 1)? TYPE_E_BADMODULEKIND: TYPE_E_ELEMENTNOTFOUND;
	}

	if (index != 0)  return TYPE_E_ELEMENTNOTFOUND;

	This->typeinfo->cImplTypes++;

	/* hacked values for IDispatch only, and maybe only for stdole. */
	This->typeinfo->cbSizeVft += 0x0c; /* hack */
	This->typeinfo->datatype1 = hRefType;
	This->typeinfo->datatype2 = (3 << 16) | 1; /* ? */
    } else {
	FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15);
	return E_OUTOFMEMORY;
    }

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetImplTypeFlags {OLEAUT32}
 *
 *  See ICreateTypeInfo_SetImplTypeFlags.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(
        ICreateTypeInfo2* iface,
        UINT index,
        INT implTypeFlags)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
    int offset;
    MSFT_RefRecord *ref;

    TRACE("(%p,%d,0x%x)\n", iface, index, implTypeFlags);

    if ((This->typeinfo->typekind & 15) != TKIND_COCLASS) {
	return TYPE_E_BADMODULEKIND;
    }

    offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
    if (offset == -1) return TYPE_E_ELEMENTNOTFOUND;

    ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
    ref->flags = implTypeFlags;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetAlignment {OLEAUT32}
 *
 *  See ICreateTypeInfo_SetAlignment.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(
        ICreateTypeInfo2* iface,
        WORD cbAlignment)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    TRACE("(%p,%d)\n", iface, cbAlignment);

    if (!cbAlignment) return E_INVALIDARG;
    if (cbAlignment > 16) return E_INVALIDARG;

    This->typeinfo->typekind &= ~0xffc0;
    This->typeinfo->typekind |= cbAlignment << 6;

    /* FIXME: There's probably some way to simplify this. */
    switch (This->typeinfo->typekind & 15) {
    case TKIND_ALIAS:
    default:
	break;

    case TKIND_ENUM:
    case TKIND_INTERFACE:
    case TKIND_DISPATCH:
    case TKIND_COCLASS:
	if (cbAlignment > 4) cbAlignment = 4;
	break;

    case TKIND_RECORD:
    case TKIND_MODULE:
    case TKIND_UNION:
	cbAlignment = 1;
	break;
    }

    This->typeinfo->typekind |= cbAlignment << 11;

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetSchema {OLEAUT32}
 *
 *  See ICreateTypeInfo_SetSchema.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(
        ICreateTypeInfo2* iface,
        LPOLESTR pStrSchema)
{
    FIXME("(%p,%s), stub!\n", iface, debugstr_w(pStrSchema));
    return E_OUTOFMEMORY;
}

/******************************************************************************
 * ICreateTypeInfo2_AddVarDesc {OLEAUT32}
 *
 *  See ICreateTypeInfo_AddVarDesc.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
        ICreateTypeInfo2* iface,
        UINT index,
        VARDESC* pVarDesc)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
    int offset;
    INT *typedata;
    int var_datawidth;
    int var_alignment;
    int var_type_size;
    int alignment;

    TRACE("(%p,%d,%p), stub!\n", iface, index, pVarDesc);
    TRACE("%d, %p, %d, {{%x, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst,
	  pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt,
	  pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags,
	  pVarDesc->wVarFlags, pVarDesc->varkind);

    if ((This->typeinfo->cElement >> 16) != index) {
	TRACE("Out-of-order element.\n");
	return TYPE_E_ELEMENTNOTFOUND;
    }

    if (!This->typedata) {
	This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000);
	This->typedata[0] = 0;
    }

    /* allocate type data space for us */
    offset = This->typedata[0];
    This->typedata[0] += 0x14;
    typedata = This->typedata + (offset >> 2) + 1;

    /* fill out the basic type information */
    typedata[0] = 0x14 | (index << 16);
    typedata[2] = pVarDesc->wVarFlags;
    typedata[3] = (sizeof(VARDESC) << 16) | 0;

    /* update the index data */
    This->indices[index] = 0x40000000 + index;

⌨️ 快捷键说明

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