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

📄 typelib2.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
 *
 *  Success: 0.
 *  Failure: -1.
 */
static int ctl2_encode_typedesc(
	ICreateTypeLib2Impl *This, /* [I] The type library in which to encode the TYPEDESC. */
	TYPEDESC *tdesc,           /* [I] The type description to encode. */
	int *encoded_tdesc,        /* [O] The encoded type description. */
	int *width,                /* [O] The width of the type, or NULL. */
	int *alignment,            /* [O] The alignment of the type, or NULL. */
	int *decoded_size)         /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
{
    int default_tdesc;
    int scratch;
    int typeoffset;
    int arrayoffset;
    int *typedata;
    int *arraydata;
    int target_type;
    int child_size;

    default_tdesc = 0x80000000 | (tdesc->vt << 16) | tdesc->vt;
    if (!width) width = &scratch;
    if (!alignment) alignment = &scratch;
    if (!decoded_size) decoded_size = &scratch;

    *decoded_size = 0;

    switch (tdesc->vt) {
    case VT_UI1:
    case VT_I1:
	*encoded_tdesc = default_tdesc;
	*width = 1;
	*alignment = 1;
	break;

    case VT_INT:
	*encoded_tdesc = 0x80000000 | (VT_I4 << 16) | VT_INT;
	if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) {
	    *width = 2;
	    *alignment = 2;
	} else {
	    *width = 4;
	    *alignment = 4;
	}
	break;

    case VT_UINT:
	*encoded_tdesc = 0x80000000 | (VT_UI4 << 16) | VT_UINT;
	if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) {
	    *width = 2;
	    *alignment = 2;
	} else {
	    *width = 4;
	    *alignment = 4;
	}
	break;

    case VT_UI2:
    case VT_I2:
    case VT_BOOL:
	*encoded_tdesc = default_tdesc;
	*width = 2;
	*alignment = 2;
	break;

    case VT_I4:
    case VT_UI4:
    case VT_R4:
    case VT_ERROR:
    case VT_BSTR:
    case VT_HRESULT:
	*encoded_tdesc = default_tdesc;
	*width = 4;
	*alignment = 4;
	break;

    case VT_CY:
	*encoded_tdesc = default_tdesc;
	*width = 8;
	*alignment = 4; /* guess? */
	break;

    case VT_VOID:
	*encoded_tdesc = 0x80000000 | (VT_EMPTY << 16) | tdesc->vt;
	*width = 0;
	*alignment = 1;
	break;

    case VT_PTR:
	/* FIXME: Make with the error checking. */
	FIXME("PTR vartype, may not work correctly.\n");

	ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);

	for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
	    if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break;
	}

	if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
	    int mix_field;
	    
	    if (target_type & 0x80000000) {
		mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
	    } else {
		typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
		mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe;
	    }

	    typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];

	    typedata[0] = (mix_field << 16) | VT_PTR;
	    typedata[1] = target_type;
	}

	*encoded_tdesc = typeoffset;

	*width = 4;
	*alignment = 4;
	*decoded_size = sizeof(TYPEDESC) + child_size;
	break;

    case VT_SAFEARRAY:
	/* FIXME: Make with the error checking. */
	FIXME("SAFEARRAY vartype, may not work correctly.\n");

	ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);

	for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
	    if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break;
	}

	if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
	    int mix_field;
	    
	    if (target_type & 0x80000000) {
		mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY;
	    } else {
		typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
		mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe;
	    }

	    typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];

	    typedata[0] = (mix_field << 16) | VT_SAFEARRAY;
	    typedata[1] = target_type;
	}

	*encoded_tdesc = typeoffset;

	*width = 4;
	*alignment = 4;
	*decoded_size = sizeof(TYPEDESC) + child_size;
	break;

    case VT_CARRAY:
      {
	/* FIXME: Make with the error checking. */
        int num_dims = tdesc->u.lpadesc->cDims, elements = 1, dim;

	ctl2_encode_typedesc(This, &tdesc->u.lpadesc->tdescElem, &target_type, width, alignment, NULL);
	arrayoffset = ctl2_alloc_segment(This, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
	arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];

	arraydata[0] = target_type;
	arraydata[1] = num_dims;
        arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16);
        arraydata += 2;

        for(dim = 0; dim < num_dims; dim++) {
            arraydata[0] = tdesc->u.lpadesc->rgbounds[dim].cElements;
            arraydata[1] = tdesc->u.lpadesc->rgbounds[dim].lLbound;
            elements *= tdesc->u.lpadesc->rgbounds[dim].cElements;
            arraydata += 2;
        }
	typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
	typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];

	typedata[0] = (0x7ffe << 16) | VT_CARRAY;
	typedata[1] = arrayoffset;

	*encoded_tdesc = typeoffset;
	*width = *width * elements;
	*decoded_size = sizeof(ARRAYDESC) + (num_dims - 1) * sizeof(SAFEARRAYBOUND);

	break;
      }
    case VT_USERDEFINED:
	TRACE("USERDEFINED.\n");
	for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
	    if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break;
	}

	if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
	    typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
	    typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];

	    typedata[0] = (0x7fff << 16) | VT_USERDEFINED;
	    typedata[1] = tdesc->u.hreftype;
	}

	*encoded_tdesc = typeoffset;
	*width = 0;
	*alignment = 1;
	break;

    default:
	FIXME("Unrecognized type %d.\n", tdesc->vt);
	*encoded_tdesc = default_tdesc;
	*width = 0;
	*alignment = 1;
	break;
    }

    return 0;
}

/****************************************************************************
 *	ctl2_find_nth_reference
 *
 *  Finds a reference by index into the linked list of reference records.
 *
 * RETURNS
 *
 *  Success: Offset of the desired reference record.
 *  Failure: -1.
 */
static int ctl2_find_nth_reference(
	ICreateTypeLib2Impl *This, /* [I] The type library in which to search. */
	int offset,                /* [I] The starting offset of the reference list. */
	int index)                 /* [I] The index of the reference to find. */
{
    MSFT_RefRecord *ref;

    for (; index && (offset != -1); index--) {
	ref = (MSFT_RefRecord *)&This->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
	offset = ref->onext;
    }

    return offset;
}

/****************************************************************************
 *	ctl2_find_typeinfo_from_offset
 *
 *  Finds an ITypeInfo given an offset into the TYPEINFO segment.
 *
 * RETURNS
 *
 *  Success: S_OK.
 *  Failure: TYPE_E_ELEMENTNOTFOUND.
 */
static HRESULT ctl2_find_typeinfo_from_offset(
	ICreateTypeLib2Impl *This, /* [I] The typelib to find the typeinfo in. */
	int offset,                /* [I] The offset of the desired typeinfo. */
	ITypeInfo **ppTinfo)       /* [I] The typeinfo found. */
{
    void *typeinfodata;
    ICreateTypeInfo2Impl *typeinfo;

    typeinfodata = &This->typelib_segment_data[MSFT_SEG_TYPEINFO][offset];

    for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
	if (typeinfo->typeinfo == typeinfodata) {
	    *ppTinfo = (ITypeInfo *)&typeinfo->lpVtblTypeInfo2;
	    ITypeInfo2_AddRef(*ppTinfo);
	    return S_OK;
	}
    }

    ERR("Failed to find typeinfo, invariant varied.\n");

    return TYPE_E_ELEMENTNOTFOUND;
}

/*================== ICreateTypeInfo2 Implementation ===================================*/

/******************************************************************************
 * ICreateTypeInfo2_QueryInterface {OLEAUT32}
 *
 *  See IUnknown_QueryInterface.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(
	ICreateTypeInfo2 * iface,
	REFIID riid,
	VOID **ppvObject)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));

    *ppvObject=NULL;
    if(IsEqualIID(riid, &IID_IUnknown) ||
       IsEqualIID(riid,&IID_ICreateTypeInfo)||
       IsEqualIID(riid,&IID_ICreateTypeInfo2))
    {
        *ppvObject = This;
    } else if (IsEqualIID(riid, &IID_ITypeInfo) ||
	       IsEqualIID(riid, &IID_ITypeInfo2)) {
	*ppvObject = &This->lpVtblTypeInfo2;
    }

    if(*ppvObject)
    {
        ICreateTypeLib2_AddRef(iface);
        TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
        return S_OK;
    }
    TRACE("-- Interface: E_NOINTERFACE\n");
    return E_NOINTERFACE;
}

/******************************************************************************
 * ICreateTypeInfo2_AddRef {OLEAUT32}
 *
 *  See IUnknown_AddRef.
 */
static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->ref was %u\n",This, ref - 1);

    return ref;
}

/******************************************************************************
 * ICreateTypeInfo2_Release {OLEAUT32}
 *
 *  See IUnknown_Release.
 */
static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%u)\n",This, ref);

    if (!ref) {
	if (This->typelib) {
	    ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib);
	    This->typelib = NULL;
	}

	/* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
	/* HeapFree(GetProcessHeap(),0,This); */
	return 0;
    }

    return ref;
}


/******************************************************************************
 * ICreateTypeInfo2_SetGuid {OLEAUT32}
 *
 *  See ICreateTypeInfo_SetGuid.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    MSFT_GuidEntry guidentry;
    int offset;

    TRACE("(%p,%s)\n", iface, debugstr_guid(guid));

    guidentry.guid = *guid;
    guidentry.hreftype = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
    guidentry.next_hash = -1;

    offset = ctl2_alloc_guid(This->typelib, &guidentry);
    
    if (offset == -1) return E_OUTOFMEMORY;

    This->typeinfo->posguid = offset;

    if (IsEqualIID(guid, &IID_IDispatch)) {
	This->typelib->typelib_header.dispatchpos = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
    }

    return S_OK;
}

/******************************************************************************
 * ICreateTypeInfo2_SetTypeFlags {OLEAUT32}
 *
 *  See ICreateTypeInfo_SetTypeFlags.
 */
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT uTypeFlags)
{
    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;

    TRACE("(%p,0x%x)\n", iface, uTypeFlags);

    This->typeinfo->flags = uTypeFlags;

    if (uTypeFlags & 0x1000) {
	MSFT_GuidEntry foo;
	int guidoffset;
	int fileoffset;
	MSFT_ImpInfo impinfo;
	static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 };

	foo.guid = IID_StdOle;
	foo.hreftype = 2;

⌨️ 快捷键说明

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