📄 typelib2.c
字号:
*
* 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 + -