- Sync to Wine-1.1.40.
svn path=/trunk/; revision=46093
TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n",
position, pdispparams->cArgs, pdispparams->cNamedArgs);
- if (position < pdispparams->cArgs) {
+
+ if (position < pdispparams->cArgs)
+ {
/* positional arg? */
pos = pdispparams->cArgs - position - 1;
- } else {
+ }
+ else
+ {
/* FIXME: is this how to handle named args? */
for (pos=0; pos<pdispparams->cNamedArgs; pos++)
if (pdispparams->rgdispidNamedArgs[pos] == position) break;
if (pos==pdispparams->cNamedArgs)
return DISP_E_PARAMNOTFOUND;
}
+
+ if (pdispparams->cArgs > 0 && !pdispparams->rgvarg)
+ {
+ hr = E_INVALIDARG;
+ goto done;
+ }
+
+ if (!pvarResult)
+ {
+ hr = E_INVALIDARG;
+ goto done;
+ }
+
hr = VariantChangeType(pvarResult,
&pdispparams->rgvarg[pos],
0, vtTarg);
- if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos;
+
+done:
+ if (FAILED(hr))
+ *puArgErr = pos;
+
return hr;
}
IsEqualIID(riid, &IID_IUnknown))
{
*ppvObject = This;
- IUnknown_AddRef((LPUNKNOWN)*ppvObject);
- return S_OK;
+ IUnknown_AddRef((LPUNKNOWN)*ppvObject);
+ return S_OK;
}
return E_NOINTERFACE;
}
return 0;
if (*old!=NULL) {
+ BSTR old_copy = *old;
DWORD newbytelen = len*sizeof(WCHAR);
DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD));
*old = (BSTR)(ptr+1);
*ptr = newbytelen;
- if (str) {
- memmove(*old, str, newbytelen);
- (*old)[len] = 0;
- } else {
- /* Subtle hidden feature: The old string data is still there
- * when 'in' is NULL!
- * Some Microsoft program needs it.
- */
- }
+ /* Subtle hidden feature: The old string data is still there
+ * when 'in' is NULL!
+ * Some Microsoft program needs it.
+ */
+ if (str && old_copy!=str) memmove(*old, str, newbytelen);
+ (*old)[len] = 0;
} else {
/*
* Allocate the new string
extern HRESULT WINAPI OLEAUTPS_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
+extern GUID const CLSID_PSFactoryBuffer DECLSPEC_HIDDEN;
extern void _get_STDFONT_CF(LPVOID *);
extern void _get_STDPIC_CF(LPVOID *);
HRESULT hr;
if (IsEqualIID(riid, &IID_IDispatch))
- hr = OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, &IID_IPSFactoryBuffer, (void **)&pPSFB);
+ hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB);
else
hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB);
HRESULT hr;
if (IsEqualIID(riid, &IID_IDispatch))
- hr = OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, &IID_IPSFactoryBuffer, (void **)&pPSFB);
+ hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB);
else
hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB);
return S_OK;
}
}
- if (IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
- IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
- IsEqualCLSID(rclsid, &CLSID_PSEnumVariant)) {
- return OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, iid, ppv);
- }
if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) && IsEqualIID(iid, &IID_IPSFactoryBuffer)) {
*ppv = &pPSDispatchFacBuf;
IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv);
return S_OK;
/*FALLTHROUGH*/
}
+ if (IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
+ IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
+ IsEqualCLSID(rclsid, &CLSID_PSDispatch) ||
+ IsEqualCLSID(rclsid, &CLSID_PSEnumVariant))
+ return OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, iid, ppv);
+
return OLEAUTPS_DllGetClassObject(rclsid, iid, ppv);
}
<include base="ReactOS">include/reactos/wine</include>
<define name="__WINESRC__" />
<redefine name="_WIN32_WINNT">0x600</redefine>
- <define name="PROXY_CLSID">CLSID_PSDispatch</define>
+ <define name="PROXY_CLSID_IS">{0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}}</define>
<define name="COM_NO_WINDOWS_H"/>
<define name="_OLEAUT32_"/>
<define name="PROXY_DELEGATION"/>
</module>
<module name="oleaut32_proxy" type="rpcproxy" allowwarnings="true">
<define name="COM_NO_WINDOWS_H"/>
- <define name="PROXY_CLSID">CLSID_PSDispatch</define>
+ <define name="PROXY_CLSID_IS">{0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}}</define>
<define name="_OLEAUT32_"/>
<define name="PROXY_DELEGATION"/>
<define name="REGISTER_PROXY_DLL"/>
#include "oleaut32_Bg.rc"
#include "oleaut32_Da.rc"
-#include "oleaut32_De.rc"
#include "oleaut32_El.rc"
#include "oleaut32_En.rc"
#include "oleaut32_Eo.rc"
#include "oleaut32_No.rc"
#include "oleaut32_Pl.rc"
#include "oleaut32_Pt.rc"
-#include "oleaut32_Ro.rc"
-#include "oleaut32_Ru.rc"
-#include "oleaut32_Si.rc"
#include "oleaut32_Sv.rc"
#include "oleaut32_Th.rc"
#include "oleaut32_Tr.rc"
-#include "oleaut32_Zh.rc"
+
+#include "oleaut32_De.rc"
+#include "oleaut32_Lt.rc"
+#include "oleaut32_Ro.rc"
+#include "oleaut32_Ru.rc"
+#include "oleaut32_Si.rc"
#include "oleaut32_Uk.rc"
+#include "oleaut32_Zh.rc"
/*
* FIXME:
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
+#pragma code_page(65001)
+
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_GREEK, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
--- /dev/null
+/*
+ * Lithuanian resources for oleaut32
+ *
+ * Copyright 2009 Aurimas Fišeras <aurimas@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+{
+ IDS_TRUE "Tiesa"
+ IDS_FALSE "Netiesa"
+ IDS_YES "Taip"
+ IDS_NO "Ne"
+ IDS_ON "Įjungta"
+ IDS_OFF "Išjungta"
+}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
#pragma code_page(65001)
IDS_ON "Activat"
IDS_OFF "Dezactivat"
}
-
-#pragma code_page(default)
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
{
- IDS_TRUE "Ïðàâäà"
- IDS_FALSE "Ëîæü"
- IDS_YES "Äà"
- IDS_NO "Íåò"
- IDS_ON "Âêëþ÷åíî"
- IDS_OFF "Âûêëþ÷åíî"
+ IDS_TRUE "Правда"
+ IDS_FALSE "Ложь"
+ IDS_YES "Да"
+ IDS_NO "Нет"
+ IDS_ON "Включено"
+ IDS_OFF "Выключено"
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
#pragma code_page(65001)
LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
IDS_ON "Vključeno"
IDS_OFF "Izključeno"
}
-
-#pragma code_page(default)
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_THAI, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
/*
* Ukrainian resources for oleaut32
*
- * Copyright 2006 Artem Reznikov
+ * Copyright 2003 Jon Griffiths
+ *
+ * Copyright 2007 Artem Reznikov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
{
- IDS_TRUE "²ñòèíà"
- IDS_FALSE "Íåïðàâäà"
- IDS_YES "Òàê"
- IDS_NO "ͳ"
- IDS_ON "Ââ³ìêíåíî"
- IDS_OFF "Âèìêíåíî"
+ IDS_TRUE "Істина"
+ IDS_FALSE "Неправда"
+ IDS_YES "Так"
+ IDS_NO "Ні"
+ IDS_ON "Ввімкнено"
+ IDS_OFF "Вимкнено"
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "resource.h"
+
/* Chinese text is encoded in UTF-8 */
#pragma code_page(65001)
IDS_ON "開"
IDS_OFF "關"
}
-
-#pragma code_page(default)
+++ /dev/null
-Index: oleaut32_Ja.rc
-===================================================================
---- oleaut32_Ja.rc (revision 23782)
-+++ oleaut32_Ja.rc (working copy)
-@@ -0,0 +1,11 @@
-+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
-+
-+STRINGTABLE DISCARDABLE
-+{
-+ IDS_TRUE "True"
-+ IDS_FALSE "False"
-+ IDS_YES "\82Í\82¢"
-+ IDS_NO "\82¢\82¢\82¦"
-+ IDS_ON "\83I\83\93"
-+ IDS_OFF "\83I\83t"
-+}
-Index: oleaut32_Uk.rc
-===================================================================
---- oleaut32_Uk.rc (revision 23782)
-+++ oleaut32_Uk.rc (working copy)
-@@ -0,0 +1,31 @@
-+/*
-+ * Ukrainian resources for oleaut32
-+ *
-+ * Copyright 2006 Artem Reznikov
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
-+
-+STRINGTABLE DISCARDABLE
-+{
-+ IDS_TRUE "²ñòèíà"
-+ IDS_FALSE "Íåïðàâäà"
-+ IDS_YES "Òàê"
-+ IDS_NO "ͳ"
-+ IDS_ON "Ââ³ìêíåíî"
-+ IDS_OFF "Âèìêíåíî"
-+}
-Index: oleaut32.rc
-===================================================================
---- oleaut32.rc (revision 23782)
-+++ oleaut32.rc (working copy)
-@@ -32,8 +32,9 @@
- #include "oleaut32_Es.rc"
- #include "oleaut32_Cz.rc"
- #include "oleaut32_Fr.rc"
- #include "oleaut32_Hu.rc"
- #include "oleaut32_It.rc"
-+#include "oleaut32_Ja.rc"
- #include "oleaut32_Ko.rc"
- #include "oleaut32_Nl.rc"
- #include "oleaut32_No.rc"
-@@ -43,6 +45,7 @@
- #include "oleaut32_Sv.rc"
- #include "oleaut32_Th.rc"
- #include "oleaut32_Tr.rc"
-+#include "oleaut32_Uk.rc"
-
- /*
- * FIXME:
#define FONTPERSIST_UNDERLINE 0x04
#define FONTPERSIST_STRIKETHROUGH 0x08
+static HDC olefont_hdc;
/***********************************************************************
* List of the HFONTs it has given out, with each one having a separate
{
struct list entry;
- /* Reference count for that instance of the class. */
- LONG ref;
+ /* Reference count of any IFont objects that own this hfont */
+ LONG int_refs;
+
+ /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
+ LONG total_refs;
- /* Contain the font associated with this object. */
+ /* The font associated with this object. */
HFONT gdiFont;
} HFONTItem, *PHFONTItem;
};
static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 };
+static HDC get_dc(void)
+{
+ HDC hdc;
+ EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+ if(!olefont_hdc)
+ olefont_hdc = CreateCompatibleDC(NULL);
+ hdc = olefont_hdc;
+ LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+ return hdc;
+}
+
+static void delete_dc(void)
+{
+ EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+ if(olefont_hdc)
+ {
+ DeleteDC(olefont_hdc);
+ olefont_hdc = NULL;
+ }
+ LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+}
+
static void HFONTItem_Delete(PHFONTItem item)
{
DeleteObject(item->gdiFont);
HeapFree(GetProcessHeap(), 0, item);
}
+/* Find hfont item entry in the list. Should be called while holding the crit sect */
+static HFONTItem *find_hfontitem(HFONT hfont)
+{
+ HFONTItem *item;
+
+ LIST_FOR_EACH_ENTRY(item, &OLEFontImpl_hFontList, HFONTItem, entry)
+ {
+ if (item->gdiFont == hfont)
+ return item;
+ }
+ return NULL;
+}
+
+/* Add an item to the list with one internal reference */
+static HRESULT add_hfontitem(HFONT hfont)
+{
+ HFONTItem *new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item));
+
+ if(!new_item) return E_OUTOFMEMORY;
+
+ new_item->int_refs = 1;
+ new_item->total_refs = 1;
+ new_item->gdiFont = hfont;
+ EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+ list_add_tail(&OLEFontImpl_hFontList,&new_item->entry);
+ LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+ return S_OK;
+}
+
+static HRESULT inc_int_ref(HFONT hfont)
+{
+ HFONTItem *item;
+ HRESULT hr = S_FALSE;
+
+ EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+ item = find_hfontitem(hfont);
+
+ if(item)
+ {
+ item->int_refs++;
+ item->total_refs++;
+ hr = S_OK;
+ }
+ LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+ return hr;
+}
+
+/* decrements the internal ref of a hfont item. If both refs are zero it'll
+ remove the item from the list and delete the hfont */
+static HRESULT dec_int_ref(HFONT hfont)
+{
+ HFONTItem *item;
+ HRESULT hr = S_FALSE;
+
+ EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+ item = find_hfontitem(hfont);
+
+ if(item)
+ {
+ item->int_refs--;
+ item->total_refs--;
+ if(item->int_refs == 0 && item->total_refs == 0)
+ HFONTItem_Delete(item);
+ hr = S_OK;
+ }
+ LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+ return hr;
+}
+
+static HRESULT inc_ext_ref(HFONT hfont)
+{
+ HFONTItem *item;
+ HRESULT hr = S_FALSE;
+
+ EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+ item = find_hfontitem(hfont);
+ if(item)
+ {
+ item->total_refs++;
+ hr = S_OK;
+ }
+ LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+ return hr;
+}
+
+static HRESULT dec_ext_ref(HFONT hfont)
+{
+ HFONTItem *item;
+ HRESULT hr = S_FALSE;
+
+ EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+ item = find_hfontitem(hfont);
+ if(item)
+ {
+ if(--item->total_refs >= 0) hr = S_OK;
+ }
+ LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+ return hr;
+}
+
+static WCHAR *strdupW(const WCHAR* str)
+{
+ WCHAR *ret;
+ DWORD size = (strlenW(str) + 1) * sizeof(WCHAR);
+
+ ret = HeapAlloc(GetProcessHeap(), 0, size);
+ if(ret)
+ memcpy(ret, str, size);
+ return ret;
+}
+
/***********************************************************************
* Declaration of the implementation class for the IFont interface
*/
* Contain the font associated with this object.
*/
HFONT gdiFont;
-
+ BOOL dirty;
/*
* Size ratio
*/
CONNECTDATA CD;
HRESULT hres;
- this->gdiFont = 0;
+ this->dirty = TRUE;
+
hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum);
if (SUCCEEDED(hres))
{
{
OLEFontImpl *this = (OLEFontImpl *)iface;
ULONG ret;
- PHFONTItem ptr, next;
TRACE("(%p)->(ref=%d)\n", this, this->ref);
/* Decrease the reference count for current interface */
if (ret == 0)
{
ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt);
- /* Check if all HFONT list refs are zero */
+
+ /* Final IFont object so destroy font cache */
if (fontlist_refs == 0)
{
+ HFONTItem *item, *cursor2;
+
EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
- LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
- HFONTItem_Delete(ptr);
+ LIST_FOR_EACH_ENTRY_SAFE(item, cursor2, &OLEFontImpl_hFontList, HFONTItem, entry)
+ HFONTItem_Delete(item);
LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+ delete_dc();
+ }
+ else
+ {
+ dec_int_ref(this->gdiFont);
}
OLEFontImpl_Destroy(this);
}
return ret;
}
+typedef struct
+{
+ short orig_cs;
+ short avail_cs;
+} enum_data;
+
+static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lp)
+{
+ enum_data *data = (enum_data*)lp;
+
+ if(elf->lfCharSet == data->orig_cs)
+ {
+ data->avail_cs = data->orig_cs;
+ return 0;
+ }
+ if(data->avail_cs == -1) data->avail_cs = elf->lfCharSet;
+ return 1;
+}
+
+static void realize_font(OLEFontImpl *This)
+{
+ if (This->dirty)
+ {
+ LOGFONTW logFont;
+ INT fontHeight;
+ WCHAR text_face[LF_FACESIZE];
+ HDC hdc = get_dc();
+ HFONT old_font;
+ TEXTMETRICW tm;
+
+ text_face[0] = 0;
+
+ if(This->gdiFont)
+ {
+ old_font = SelectObject(hdc, This->gdiFont);
+ GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+ SelectObject(hdc, old_font);
+ dec_int_ref(This->gdiFont);
+ This->gdiFont = 0;
+ }
+
+ memset(&logFont, 0, sizeof(LOGFONTW));
+
+ lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE);
+ logFont.lfCharSet = This->description.sCharset;
+
+ /* If the font name has been changed then enumerate all charsets
+ and pick one that'll result in the font specified being selected */
+ if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName))
+ {
+ enum_data data;
+ data.orig_cs = This->description.sCharset;
+ data.avail_cs = -1;
+ logFont.lfCharSet = DEFAULT_CHARSET;
+ EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0);
+ if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs;
+ }
+
+
+ /*
+ * The height of the font returned by the get_Size property is the
+ * height of the font in points multiplied by 10000... Using some
+ * simple conversions and the ratio given by the application, it can
+ * be converted to a height in pixels.
+ *
+ * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
+ * Ratio is applied here relative to the standard.
+ */
+
+ fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 );
+
+
+ logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 :
+ (-fontHeight/10000L);
+ logFont.lfItalic = This->description.fItalic;
+ logFont.lfUnderline = This->description.fUnderline;
+ logFont.lfStrikeOut = This->description.fStrikethrough;
+ logFont.lfWeight = This->description.sWeight;
+ logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
+ logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ logFont.lfQuality = DEFAULT_QUALITY;
+ logFont.lfPitchAndFamily = DEFAULT_PITCH;
+
+ This->gdiFont = CreateFontIndirectW(&logFont);
+ This->dirty = FALSE;
+
+ add_hfontitem(This->gdiFont);
+
+ /* Fixup the name and charset properties so that they match the
+ selected font */
+ old_font = SelectObject(get_dc(), This->gdiFont);
+ GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+ if(lstrcmpiW(text_face, This->description.lpstrName))
+ {
+ HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
+ This->description.lpstrName = strdupW(text_face);
+ }
+ GetTextMetricsW(hdc, &tm);
+ This->description.sCharset = tm.tmCharSet;
+ SelectObject(hdc, old_font);
+ }
+}
+
/************************************************************************
* OLEFontImpl_get_Name (IFont)
*
if (pname==0)
return E_POINTER;
+ if(this->dirty) realize_font(this);
+
if (this->description.lpstrName!=0)
*pname = SysAllocString(this->description.lpstrName);
else
OLEFontImpl *this = (OLEFontImpl *)iface;
TRACE("(%p)->(%p)\n", this, name);
+ if (!name)
+ return CTL_E_INVALIDPROPERTYVALUE;
+
if (this->description.lpstrName==0)
{
this->description.lpstrName = HeapAlloc(GetProcessHeap(),
if (psize==0)
return E_POINTER;
+ if(this->dirty) realize_font(this);
+
psize->s.Hi = 0;
psize->s.Lo = this->description.cySize.s.Lo;
if (pbold==0)
return E_POINTER;
+ if(this->dirty) realize_font(this);
+
*pbold = this->description.sWeight > 550;
return S_OK;
if (pitalic==0)
return E_POINTER;
+ if(this->dirty) realize_font(this);
+
*pitalic = this->description.fItalic;
return S_OK;
if (punderline==0)
return E_POINTER;
+ if(this->dirty) realize_font(this);
+
*punderline = this->description.fUnderline;
return S_OK;
if (pstrikethrough==0)
return E_POINTER;
+ if(this->dirty) realize_font(this);
+
*pstrikethrough = this->description.fStrikethrough;
return S_OK;
if (pweight==0)
return E_POINTER;
+ if(this->dirty) realize_font(this);
+
*pweight = this->description.sWeight;
return S_OK;
if (pcharset==0)
return E_POINTER;
+ if(this->dirty) realize_font(this);
+
*pcharset = this->description.sCharset;
return S_OK;
if (phfont==NULL)
return E_POINTER;
- /*
- * Realize the font if necessary
- */
- if (this->gdiFont==0)
-{
- LOGFONTW logFont;
- INT fontHeight;
- CY cySize;
- PHFONTItem newEntry;
-
- /*
- * The height of the font returned by the get_Size property is the
- * height of the font in points multiplied by 10000... Using some
- * simple conversions and the ratio given by the application, it can
- * be converted to a height in pixels.
- */
- IFont_get_Size(iface, &cySize);
-
- /* Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. */
- /* Ratio is applied here relative to the standard. */
- fontHeight = MulDiv( cySize.s.Lo, this->cyLogical*635, this->cyHimetric*18 );
-
- memset(&logFont, 0, sizeof(LOGFONTW));
-
- logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
- (-fontHeight/10000L);
- logFont.lfItalic = this->description.fItalic;
- logFont.lfUnderline = this->description.fUnderline;
- logFont.lfStrikeOut = this->description.fStrikethrough;
- logFont.lfWeight = this->description.sWeight;
- logFont.lfCharSet = this->description.sCharset;
- logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
- logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- logFont.lfQuality = DEFAULT_QUALITY;
- logFont.lfPitchAndFamily = DEFAULT_PITCH;
- strcpyW(logFont.lfFaceName,this->description.lpstrName);
-
- this->gdiFont = CreateFontIndirectW(&logFont);
-
- /* Add font to the cache */
- newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(HFONTItem));
- newEntry->ref = 1;
- newEntry->gdiFont = this->gdiFont;
- EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
- list_add_tail(&OLEFontImpl_hFontList,&newEntry->entry);
- LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
- }
+ if(this->dirty) realize_font(this);
*phfont = this->gdiFont;
TRACE("Returning %p\n", *phfont);
IFont** ppfont)
{
OLEFontImpl* newObject = 0;
- LOGFONTW logFont;
- INT fontHeight;
- CY cySize;
- PHFONTItem newEntry;
-
OLEFontImpl *this = (OLEFontImpl *)iface;
+
TRACE("(%p)->(%p)\n", this, ppfont);
if (ppfont == NULL)
(1+strlenW(this->description.lpstrName))*2
);
strcpyW(newObject->description.lpstrName, this->description.lpstrName);
- /* We need to clone the HFONT too. This is just cut & paste from above */
- IFont_get_Size(iface, &cySize);
-
- fontHeight = MulDiv(cySize.s.Lo, this->cyLogical*635,this->cyHimetric*18);
-
- memset(&logFont, 0, sizeof(LOGFONTW));
- logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
- (-fontHeight/10000L);
- logFont.lfItalic = this->description.fItalic;
- logFont.lfUnderline = this->description.fUnderline;
- logFont.lfStrikeOut = this->description.fStrikethrough;
- logFont.lfWeight = this->description.sWeight;
- logFont.lfCharSet = this->description.sCharset;
- logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
- logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- logFont.lfQuality = DEFAULT_QUALITY;
- logFont.lfPitchAndFamily = DEFAULT_PITCH;
- strcpyW(logFont.lfFaceName,this->description.lpstrName);
- newObject->gdiFont = CreateFontIndirectW(&logFont);
+ /* Increment internal ref in hfont item list */
+ if(newObject->gdiFont) inc_int_ref(newObject->gdiFont);
- /* Add font to the cache */
InterlockedIncrement(&ifont_cnt);
- newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(HFONTItem));
- newEntry->ref = 1;
- newEntry->gdiFont = newObject->gdiFont;
- EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
- list_add_tail(&OLEFontImpl_hFontList,&newEntry->entry);
- LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
/* create new connection points */
newObject->pPropertyNotifyCP = NULL;
IFont* iface,
HFONT hfont)
{
- OLEFontImpl *this = (OLEFontImpl *)iface;
- PHFONTItem ptr, next;
- HRESULT hres = S_FALSE; /* assume not present */
+ OLEFontImpl *this = (OLEFontImpl *)iface;
- TRACE("(%p)->(%p)\n", this, hfont);
+ TRACE("(%p)->(%p)\n", this, hfont);
- if (!hfont)
- return E_INVALIDARG;
+ if (!hfont) return E_INVALIDARG;
- /* Check of the hFont is already in the list */
- EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
- LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
- {
- if (ptr->gdiFont == hfont)
- {
- ptr->ref++;
- hres = S_OK;
- break;
- }
- }
- LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
-
- return hres;
+ return inc_ext_ref(hfont);
}
/************************************************************************
IFont* iface,
HFONT hfont)
{
- OLEFontImpl *this = (OLEFontImpl *)iface;
- PHFONTItem ptr, next;
- HRESULT hres = S_FALSE; /* assume not present */
+ OLEFontImpl *this = (OLEFontImpl *)iface;
- TRACE("(%p)->(%p)\n", this, hfont);
+ TRACE("(%p)->(%p)\n", this, hfont);
- if (!hfont)
- return E_INVALIDARG;
-
- /* Check of the hFont is already in the list */
- EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
- LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
- {
- if ((ptr->gdiFont == hfont) && ptr->ref)
- {
- /* Remove from cache and delete object if not referenced */
- if (!--ptr->ref)
- {
- if (ptr->gdiFont == this->gdiFont)
- this->gdiFont = NULL;
- }
- hres = S_OK;
- break;
- }
- }
- LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+ if (!hfont) return E_INVALIDARG;
- return hres;
+ return dec_ext_ref(hfont);
}
/************************************************************************
this->description.lpstrName[len] = 0;
/* Ensure use of this font causes a new one to be created @@@@ */
- DeleteObject(this->gdiFont);
+ dec_int_ref(this->gdiFont);
this->gdiFont = 0;
return S_OK;
* Initializing all the other members.
*/
newObject->gdiFont = 0;
+ newObject->dirty = TRUE;
newObject->cyLogical = 72L;
newObject->cyHimetric = 2540L;
newObject->pPropertyNotifyCP = NULL;
HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
- if (fontDesc->gdiFont!=0)
- DeleteObject(fontDesc->gdiFont);
-
if (fontDesc->pPropertyNotifyCP)
IConnectionPoint_Release(fontDesc->pPropertyNotifyCP);
if (fontDesc->pFontEventsCP)
break;
case PICTYPE_ICON:
FIXME("Not quite correct implementation of rendering icons...\n");
- DrawIcon(hdc,x,y,This->desc.u.icon.hicon);
+ DrawIconEx(hdc, x, y, This->desc.u.icon.hicon, cx, cy, 0, NULL, DI_NORMAL);
break;
case PICTYPE_METAFILE:
#include <stdarg.h>
#include <string.h>
+#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
return res;
}
+/***********************************************************************
+ * register_typelib
+ */
+static HRESULT register_typelib( const WCHAR *name )
+{
+ static const WCHAR backslash[] = {'\\',0};
+ HRESULT hr;
+ ITypeLib *typelib;
+ WCHAR *path;
+ DWORD len;
+
+ len = GetSystemDirectoryW( NULL, 0 ) + strlenW( name ) + 1;
+ if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
+ GetSystemDirectoryW( path, len );
+ strcatW( path, backslash );
+ strcatW( path, name );
+ hr = LoadTypeLib( path, &typelib );
+ if (SUCCEEDED(hr))
+ {
+ hr = RegisterTypeLib( typelib, path, NULL );
+ ITypeLib_Release( typelib );
+ }
+ HeapFree( GetProcessHeap(), 0, path );
+ return hr;
+}
+
/***********************************************************************
* coclass list
*/
static GUID const CLSID_OldFont = {
0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} };
-static GUID const CLSID_PSFactoryBuffer = {
- 0xB196B286, 0xBAB4, 0x101A, {0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07} };
-
static struct regsvr_coclass const coclass_list[] = {
{ &CLSID_RecordInfo,
"CLSID_RecordInfo",
"Obsolete Font",
"OldFont"
},
- { &CLSID_PSFactoryBuffer,
- "PSFactoryBuffer",
- NULL,
- "oleaut32.dll",
- "Both"
- },
{ NULL } /* list terminator */
};
*/
#define INTERFACE_ENTRY(interface, clsid16, clsid32) { &IID_##interface, #interface, NULL, sizeof(interface##Vtbl)/sizeof(void*), clsid16, clsid32 }
#define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL)
-#define PSFAC_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, &CLSID_PSFactoryBuffer)
#define CLSID_INTERFACE_ENTRY(interface,clsid) INTERFACE_ENTRY(interface, clsid, clsid)
static struct regsvr_interface const interface_list[] = {
CLSID_INTERFACE_ENTRY(ITypeComp,&CLSID_PSTypeComp),
CLSID_INTERFACE_ENTRY(ITypeInfo,&CLSID_PSTypeInfo),
CLSID_INTERFACE_ENTRY(ITypeLib,&CLSID_PSTypeLib),
- PSFAC_INTERFACE_ENTRY(IAdviseSinkEx),
- PSFAC_INTERFACE_ENTRY(IClassFactory2),
- PSFAC_INTERFACE_ENTRY(IConnectionPoint),
- PSFAC_INTERFACE_ENTRY(IConnectionPointContainer),
- PSFAC_INTERFACE_ENTRY(ICreateErrorInfo),
- PSFAC_INTERFACE_ENTRY(IEnumConnectionPoints),
- PSFAC_INTERFACE_ENTRY(IEnumConnections),
- PSFAC_INTERFACE_ENTRY(IEnumOleUndoUnits),
- PSFAC_INTERFACE_ENTRY(IErrorInfo),
- PSFAC_INTERFACE_ENTRY(IErrorLog),
- PSFAC_INTERFACE_ENTRY(IFont),
- PSFAC_INTERFACE_ENTRY(IObjectWithSite),
- PSFAC_INTERFACE_ENTRY(IOleControl),
- PSFAC_INTERFACE_ENTRY(IOleControlSite),
- PSFAC_INTERFACE_ENTRY(IOleInPlaceSiteEx),
- PSFAC_INTERFACE_ENTRY(IOleParentUndoUnit),
- PSFAC_INTERFACE_ENTRY(IOleUndoManager),
- PSFAC_INTERFACE_ENTRY(IOleUndoUnit),
- PSFAC_INTERFACE_ENTRY(IPerPropertyBrowsing),
- PSFAC_INTERFACE_ENTRY(IPersistMemory),
- PSFAC_INTERFACE_ENTRY(IPersistPropertyBag),
- PSFAC_INTERFACE_ENTRY(IPersistPropertyBag2),
- PSFAC_INTERFACE_ENTRY(IPersistStreamInit),
- PSFAC_INTERFACE_ENTRY(IPicture),
- PSFAC_INTERFACE_ENTRY(IPointerInactive),
- PSFAC_INTERFACE_ENTRY(IPropertyBag),
- PSFAC_INTERFACE_ENTRY(IPropertyBag2),
- PSFAC_INTERFACE_ENTRY(IPropertyNotifySink),
- PSFAC_INTERFACE_ENTRY(IPropertyPage),
- PSFAC_INTERFACE_ENTRY(IPropertyPage2),
- PSFAC_INTERFACE_ENTRY(IPropertyPageSite),
- PSFAC_INTERFACE_ENTRY(IProvideClassInfo),
- PSFAC_INTERFACE_ENTRY(IProvideClassInfo2),
- PSFAC_INTERFACE_ENTRY(IProvideMultipleClassInfo),
- PSFAC_INTERFACE_ENTRY(IQuickActivate),
- PSFAC_INTERFACE_ENTRY(ISimpleFrameSite),
- PSFAC_INTERFACE_ENTRY(ISpecifyPropertyPages),
+ INTERFACE_ENTRY(ISupportErrorInfo,NULL,&CLSID_PSDispatch),
+ INTERFACE_ENTRY(ITypeFactory,NULL,&CLSID_PSDispatch),
+ INTERFACE_ENTRY(ITypeInfo2,NULL,&CLSID_PSDispatch),
+ INTERFACE_ENTRY(ITypeLib2,NULL,&CLSID_PSDispatch),
{ NULL } /* list terminator */
};
hr = register_coclasses(coclass_list);
if (SUCCEEDED(hr))
hr = register_interfaces(interface_list);
+ if (SUCCEEDED(hr))
+ {
+ const WCHAR stdole32W[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0};
+ const WCHAR stdole2W[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
+ hr = register_typelib( stdole2W );
+ if (SUCCEEDED(hr)) hr = register_typelib( stdole32W );
+ }
return hr;
}
vartype = VT_SAFEARRAY;
switch (vartype) {
- case VT_EMPTY: /* nothing. empty variant for instance */
- return S_OK;
case VT_I8:
case VT_UI8:
case VT_R8:
if (writeit)
hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
return hres;
- case VT_I4|VT_BYREF:
- hres = S_OK;
- if (debugout) TRACE_(olerelay)("&0x%x\n",*arg);
- if (writeit)
- hres = xbuf_add(buf,(LPBYTE)(DWORD*)*arg,sizeof(DWORD));
- /* do not dealloc at this time */
- return hres;
case VT_VARIANT: {
- TYPEDESC tdesc2;
- VARIANT *vt = (VARIANT*)arg;
- DWORD vttype = V_VT(vt);
-
- if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(vttype),debugstr_vf(vttype));
- tdesc2.vt = vttype;
- if (writeit) {
- hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype));
- if (hres) return hres;
- }
- /* need to recurse since we need to free the stuff */
- hres = serialize_param(tinfo,writeit,debugout,dealloc,&tdesc2,(DWORD*)&(V_I4(vt)),buf);
- if (debugout) TRACE_(olerelay)(")");
- return hres;
- }
- case VT_BSTR|VT_BYREF: {
- if (debugout) TRACE_(olerelay)("[byref]'%s'", *(BSTR*)*arg ? relaystr(*((BSTR*)*arg)) : "<bstr NULL>");
- if (writeit) {
- /* ptr to ptr to magic widestring, basically */
- BSTR *bstr = (BSTR *) *arg;
- DWORD len;
- if (!*bstr) {
- /* -1 means "null string" which is equivalent to empty string */
- len = -1;
- hres = xbuf_add(buf, (LPBYTE)&len,sizeof(DWORD));
- if (hres) return hres;
- } else {
- len = *((DWORD*)*bstr-1)/sizeof(WCHAR);
- hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
- if (hres) return hres;
- hres = xbuf_add(buf,(LPBYTE)*bstr,len * sizeof(WCHAR));
- if (hres) return hres;
- }
+ if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(V_VT((VARIANT *)arg)),debugstr_vf(V_VT((VARIANT *)arg)));
+ if (writeit)
+ {
+ ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+ ULONG size = VARIANT_UserSize(&flags, buf->curoff, (VARIANT *)arg);
+ xbuf_resize(buf, size);
+ VARIANT_UserMarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg);
+ buf->curoff = size;
}
-
- if (dealloc && arg) {
- BSTR *str = *((BSTR **)arg);
- SysFreeString(*str);
+ if (dealloc)
+ {
+ ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+ VARIANT_UserFree(&flags, (VARIANT *)arg);
}
return S_OK;
}
-
case VT_BSTR: {
if (debugout) {
if (*arg)
else
TRACE_(olerelay)("<bstr NULL>");
}
- if (writeit) {
- BSTR bstr = (BSTR)*arg;
- DWORD len;
- if (!bstr) {
- len = -1;
- hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
- if (hres) return hres;
- } else {
- len = *((DWORD*)bstr-1)/sizeof(WCHAR);
- hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
- if (hres) return hres;
- hres = xbuf_add(buf,(LPBYTE)bstr,len * sizeof(WCHAR));
- if (hres) return hres;
- }
- }
-
- if (dealloc && arg)
- SysFreeString((BSTR)*arg);
- return S_OK;
+ if (writeit)
+ {
+ ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+ ULONG size = BSTR_UserSize(&flags, buf->curoff, (BSTR *)arg);
+ xbuf_resize(buf, size);
+ BSTR_UserMarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
+ buf->curoff = size;
+ }
+ if (dealloc)
+ {
+ ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+ BSTR_UserFree(&flags, (BSTR *)arg);
+ }
+ return S_OK;
}
case VT_PTR: {
DWORD cookie;
if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt));
if (debugout) TRACE_(olerelay)("[");
for (i=0;i<arrsize;i++) {
- hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)arg+i*_xsize(&adesc->tdescElem, tinfo)), buf);
+ hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), buf);
if (hres)
return hres;
if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
}
if (debugout) TRACE_(olerelay)("]");
+ if (dealloc)
+ HeapFree(GetProcessHeap(), 0, *(void **)arg);
return S_OK;
}
case VT_SAFEARRAY: {
LPSAFEARRAY_UserMarshal(&flags, buf->base + buf->curoff, (LPSAFEARRAY *)arg);
buf->curoff = size;
}
+ if (dealloc)
+ {
+ ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+ LPSAFEARRAY_UserFree(&flags, (LPSAFEARRAY *)arg);
+ }
return S_OK;
}
default:
while (1) {
switch (vartype) {
- case VT_EMPTY:
- if (debugout) TRACE_(olerelay)("<empty>\n");
- return S_OK;
- case VT_NULL:
- if (debugout) TRACE_(olerelay)("<null>\n");
- return S_OK;
case VT_VARIANT: {
- VARIANT *vt = (VARIANT*)arg;
-
- if (readit) {
- DWORD vttype;
- TYPEDESC tdesc2;
- hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype));
- if (hres) {
- FIXME("vt type not read?\n");
- return hres;
- }
- memset(&tdesc2,0,sizeof(tdesc2));
- tdesc2.vt = vttype;
- V_VT(vt) = vttype;
- if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(vttype),debugstr_vf(vttype));
- hres = deserialize_param(tinfo, readit, debugout, alloc, &tdesc2, (DWORD*)&(V_I4(vt)), buf);
- TRACE_(olerelay)(")");
- return hres;
- } else {
- VariantInit(vt);
- return S_OK;
+ if (readit)
+ {
+ ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+ unsigned char *buffer;
+ buffer = VARIANT_UserUnmarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg);
+ buf->curoff = buffer - buf->base;
}
+ return S_OK;
}
case VT_I8:
case VT_UI8:
}
if (debugout) TRACE_(olerelay)("%02x",*arg & 0xff);
return hres;
- case VT_I4|VT_BYREF:
- hres = S_OK;
- if (alloc)
- *arg = (DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));
- if (readit) {
- hres = xbuf_get(buf,(LPBYTE)*arg,sizeof(DWORD));
- if (hres) ERR("Failed to read integer 4 byte\n");
- }
- if (debugout) TRACE_(olerelay)("&0x%x",*(DWORD*)*arg);
- return hres;
- case VT_BSTR|VT_BYREF: {
- BSTR **bstr = (BSTR **)arg;
- WCHAR *str;
- DWORD len;
-
- if (readit) {
- hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));
- if (hres) {
- ERR("failed to read bstr klen\n");
- return hres;
- }
- if (len == -1) {
- *bstr = CoTaskMemAlloc(sizeof(BSTR *));
- **bstr = NULL;
- if (debugout) TRACE_(olerelay)("<bstr NULL>");
- } else {
- str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
- hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
- if (hres) {
- ERR("Failed to read BSTR.\n");
- HeapFree(GetProcessHeap(),0,str);
- return hres;
- }
- *bstr = CoTaskMemAlloc(sizeof(BSTR *));
- **bstr = SysAllocStringLen(str,len);
- if (debugout) TRACE_(olerelay)("%s",relaystr(str));
- HeapFree(GetProcessHeap(),0,str);
- }
- } else {
- *bstr = NULL;
- }
- return S_OK;
- }
case VT_BSTR: {
- WCHAR *str;
- DWORD len;
-
- if (readit) {
- hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));
- if (hres) {
- ERR("failed to read bstr klen\n");
- return hres;
- }
- if (len == -1) {
- *arg = 0;
- if (debugout) TRACE_(olerelay)("<bstr NULL>");
- } else {
- str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
- hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
- if (hres) {
- ERR("Failed to read BSTR.\n");
- HeapFree(GetProcessHeap(),0,str);
- return hres;
- }
- *arg = (DWORD)SysAllocStringLen(str,len);
- if (debugout) TRACE_(olerelay)("%s",relaystr(str));
- HeapFree(GetProcessHeap(),0,str);
- }
- } else {
- *arg = 0;
+ if (readit)
+ {
+ ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+ unsigned char *buffer;
+ buffer = BSTR_UserUnmarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
+ buf->curoff = buffer - buf->base;
+ if (debugout) TRACE_(olerelay)("%s",debugstr_w(*(BSTR *)arg));
}
return S_OK;
}
if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n");
for (i=0;i<adesc->cDims;i++)
arrsize *= adesc->rgbounds[i].cElements;
+ *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
for (i=0;i<arrsize;i++)
deserialize_param(
tinfo,
debugout,
alloc,
&adesc->tdescElem,
- (DWORD*)((LPBYTE)(arg)+i*_xsize(&adesc->tdescElem, tinfo)),
+ (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)),
buf
);
return S_OK;
TMStubImpl_Invoke(
LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
{
+#ifdef __i386__
int i;
const FUNCDESC *fdesc;
TMStubImpl *This = (TMStubImpl *)iface;
nrofargs = 0;
for (i=0;i<fdesc->cParams;i++)
nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo);
- args = HeapAlloc(GetProcessHeap(),0,(nrofargs+1)*sizeof(DWORD));
+ args = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(nrofargs+1)*sizeof(DWORD));
if (!args)
{
hres = E_OUTOFMEMORY;
TRACE("returning\n");
return hres;
+#else
+ FIXME( "not implemented on non-i386\n" );
+ return E_FAIL;
+#endif
}
static LPRPCSTUBBUFFER WINAPI
LPOLESTR doc;
/* Set the human-readable name of the typelib */
- if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
+ if (FAILED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
+ res = E_FAIL;
+ else if (doc)
{
if (RegSetValueExW(key, NULL, 0, REG_SZ,
(BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
SysFreeString(doc);
}
- else
- res = E_FAIL;
/* Make up the name of the typelib path subkey */
if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;
int helpcontext;
int HelpStringContext;
BSTR HelpString;
- BSTR Entry; /* if its Hiword==0, it numeric; -1 is not present*/
+ BSTR Entry; /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */
int ctCustData;
TLBCustData * pCustData; /* linked list to cust data; */
struct tagTLBFuncDesc * next;
const ITypeInfo2Vtbl *lpVtbl;
const ITypeCompVtbl *lpVtblTypeComp;
LONG ref;
- BOOL no_free_data; /* don't free data structures */
+ BOOL not_attached_to_typelib;
TYPEATTR TypeAttr ; /* _lots_ of type information. */
ITypeLibImpl * pTypeLib; /* back pointer to typelib */
int index; /* index in this typelib; */
static const ITypeCompVtbl tcompvt;
static ITypeInfo2 * ITypeInfo_Constructor(void);
+static void ITypeInfo_fnDestroy(ITypeInfoImpl *This);
typedef struct tagTLBContext
{
{
if ( pFuncRec->FKCCIC & 0x2000 )
{
- if (HIWORD(pFuncRec->OptAttr[2]) != 0)
- ERR("ordinal 0x%08x invalid, HIWORD != 0\n", pFuncRec->OptAttr[2]);
+ if (!IS_INTRESOURCE(pFuncRec->OptAttr[2]))
+ ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->OptAttr[2]);
(*pptfd)->Entry = (BSTR)pFuncRec->OptAttr[2];
}
else
/* Find resource */
typeInfo = (NE_TYPEINFO *)(resTab + 2);
- if (HIWORD(typeid) != 0) /* named type */
+ if (!IS_INTRESOURCE(typeid)) /* named type */
{
BYTE len = strlen( typeid );
while (typeInfo->type_id)
found_type:
nameInfo = (NE_NAMEINFO *)(typeInfo + 1);
- if (HIWORD(resid) != 0) /* named resource */
+ if (!IS_INTRESOURCE(resid)) /* named resource */
{
BYTE len = strlen( resid );
for (count = typeInfo->count; count > 0; count--, nameInfo++)
if(td[1]<0)
pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK;
else
- pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = stndTypeDesc[td[0]/8];
+ pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = cx.pLibInfo->pTypeDesc[td[0]/(2*sizeof(INT))];
pTypeLibImpl->pTypeDesc[i].u.lpadesc->cDims = td[2];
name = TLB_Alloc(size+1);
MSFT_Read(name, size, &cx, DO_NOT_SEEK);
(*ppImpLib)->name = TLB_MultiByteToBSTR(name);
+ TLB_Free(name);
MSFT_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3;
if (pTITail->funcs_off != 0xffff)
SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
+ if (pTITail->impls_off != 0xffff)
+ SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);
+
/* this is necessary to cope with MSFT typelibs that set cFuncs to the number
* of dispinterface functions including the IDispatch ones, so
* ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
(*ppTypeInfoImpl)->TypeAttr.wTypeFlags =
(pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5);
+ if((*ppTypeInfoImpl)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)
+ (*ppTypeInfoImpl)->TypeAttr.typekind = TKIND_DISPATCH;
+
if((pTIHeader->typeflags1 & 7) != 2)
FIXME_(typelib)("typeflags1 = %02x\n", pTIHeader->typeflags1);
if(pTIHeader->typeflags3 != 2)
TLBRefType *ref_type;
void *cursor2;
int i;
+ ITypeInfoImpl *pTI, *pTINext;
/* remove cache entry */
if(This->path)
TLB_Free(ref_type);
}
- if (This->pTypeInfo) /* can be NULL */
- ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
+ for (pTI = This->pTypeInfo; pTI; pTI = pTINext)
+ {
+ pTINext = pTI->next;
+ ITypeInfo_fnDestroy(pTI);
+ }
HeapFree(GetProcessHeap(),0,This);
return 0;
}
ITypeInfo ** ppTInfo,
ITypeComp ** ppTComp)
{
- FIXME("(%s, %x, %p, %p): stub\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
- return E_NOTIMPL;
+ ITypeLibImpl *This = impl_from_ITypeComp(iface);
+ ITypeInfoImpl *pTypeInfo;
+
+ TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
+
+ for (pTypeInfo = This->pTypeInfo; pTypeInfo; pTypeInfo = pTypeInfo->next)
+ {
+ /* FIXME: should use lHash to do the search */
+ if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name, szName))
+ {
+ TRACE("returning %p\n", pTypeInfo);
+ *ppTInfo = (ITypeInfo *)&pTypeInfo->lpVtbl;
+ ITypeInfo_AddRef(*ppTInfo);
+ *ppTComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp;
+ ITypeComp_AddRef(*ppTComp);
+ return S_OK;
+ }
+ }
+
+ TRACE("not found\n");
+ *ppTInfo = NULL;
+ *ppTComp = NULL;
+ return S_OK;
}
static const ITypeCompVtbl tlbtcvt =
{
pTypeInfoImpl->lpVtbl = &tinfvt;
pTypeInfoImpl->lpVtblTypeComp = &tcompvt;
- pTypeInfoImpl->ref=1;
+ pTypeInfoImpl->ref = 0;
pTypeInfoImpl->hreftype = -1;
pTypeInfoImpl->TypeAttr.memidConstructor = MEMBERID_NIL;
pTypeInfoImpl->TypeAttr.memidDestructor = MEMBERID_NIL;
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
- ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib);
-
TRACE("(%p)->ref is %u\n",This, ref);
+
+ if (ref == 1 /* incremented from 0 */)
+ ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib);
+
return ref;
}
-/* ITypeInfo::Release
- */
-static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
+static void ITypeInfo_fnDestroy(ITypeInfoImpl *This)
{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- ULONG ref = InterlockedDecrement(&This->ref);
+ TLBFuncDesc *pFInfo, *pFInfoNext;
+ TLBVarDesc *pVInfo, *pVInfoNext;
+ TLBImplType *pImpl, *pImplNext;
- TRACE("(%p)->(%u)\n",This, ref);
+ TRACE("destroying ITypeInfo(%p)\n",This);
- if (ref) {
- /* We don't release ITypeLib when ref=0 because
- it means that function is called by ITypeLib2_Release */
- ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
- } else {
- TLBFuncDesc *pFInfo, *pFInfoNext;
- TLBVarDesc *pVInfo, *pVInfoNext;
- TLBImplType *pImpl, *pImplNext;
+ SysFreeString(This->Name);
+ This->Name = NULL;
- TRACE("destroying ITypeInfo(%p)\n",This);
+ SysFreeString(This->DocString);
+ This->DocString = NULL;
- if (This->no_free_data)
- goto finish_free;
+ SysFreeString(This->DllName);
+ This->DllName = NULL;
- SysFreeString(This->Name);
- This->Name = NULL;
-
- SysFreeString(This->DocString);
- This->DocString = NULL;
+ for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
+ {
+ INT i;
+ for(i = 0;i < pFInfo->funcdesc.cParams; i++)
+ {
+ ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i];
+ if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
+ {
+ VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
+ TLB_Free(elemdesc->u.paramdesc.pparamdescex);
+ }
+ SysFreeString(pFInfo->pParamDesc[i].Name);
+ }
+ TLB_Free(pFInfo->funcdesc.lprgelemdescParam);
+ TLB_Free(pFInfo->pParamDesc);
+ TLB_FreeCustData(pFInfo->pCustData);
+ if (!IS_INTRESOURCE(pFInfo->Entry) && pFInfo->Entry != (BSTR)-1)
+ SysFreeString(pFInfo->Entry);
+ SysFreeString(pFInfo->HelpString);
+ SysFreeString(pFInfo->Name);
+
+ pFInfoNext = pFInfo->next;
+ TLB_Free(pFInfo);
+ }
+ for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext)
+ {
+ if (pVInfo->vardesc.varkind == VAR_CONST)
+ {
+ VariantClear(pVInfo->vardesc.u.lpvarValue);
+ TLB_Free(pVInfo->vardesc.u.lpvarValue);
+ }
+ TLB_FreeCustData(pVInfo->pCustData);
+ SysFreeString(pVInfo->Name);
+ pVInfoNext = pVInfo->next;
+ TLB_Free(pVInfo);
+ }
+ for (pImpl = This->impltypelist; pImpl; pImpl = pImplNext)
+ {
+ TLB_FreeCustData(pImpl->pCustData);
+ pImplNext = pImpl->next;
+ TLB_Free(pImpl);
+ }
+ TLB_FreeCustData(This->pCustData);
- SysFreeString(This->DllName);
- This->DllName = NULL;
+ HeapFree(GetProcessHeap(), 0, This);
+}
- for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
- {
- INT i;
- for(i = 0;i < pFInfo->funcdesc.cParams; i++)
- {
- ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i];
- if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
- {
- VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
- TLB_Free(elemdesc->u.paramdesc.pparamdescex);
- }
- SysFreeString(pFInfo->pParamDesc[i].Name);
- }
- TLB_Free(pFInfo->funcdesc.lprgelemdescParam);
- TLB_Free(pFInfo->pParamDesc);
- TLB_FreeCustData(pFInfo->pCustData);
- if (HIWORD(pFInfo->Entry) != 0 && pFInfo->Entry != (BSTR)-1)
- SysFreeString(pFInfo->Entry);
- SysFreeString(pFInfo->HelpString);
- SysFreeString(pFInfo->Name);
-
- pFInfoNext = pFInfo->next;
- TLB_Free(pFInfo);
- }
- for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext)
- {
- if (pVInfo->vardesc.varkind == VAR_CONST)
- {
- VariantClear(pVInfo->vardesc.u.lpvarValue);
- TLB_Free(pVInfo->vardesc.u.lpvarValue);
- }
- TLB_FreeCustData(pVInfo->pCustData);
- SysFreeString(pVInfo->Name);
- pVInfoNext = pVInfo->next;
- TLB_Free(pVInfo);
- }
- for(pImpl = This->impltypelist; pImpl; pImpl = pImplNext)
- {
- TLB_FreeCustData(pImpl->pCustData);
- pImplNext = pImpl->next;
- TLB_Free(pImpl);
- }
- TLB_FreeCustData(This->pCustData);
+/* ITypeInfo::Release
+ */
+static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
+{
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
+ ULONG ref = InterlockedDecrement(&This->ref);
-finish_free:
- if (This->next)
- {
- ITypeInfo_Release((ITypeInfo*)This->next);
- }
+ TRACE("(%p)->(%u)\n",This, ref);
- HeapFree(GetProcessHeap(),0,This);
- return 0;
+ if (!ref)
+ {
+ BOOL not_attached_to_typelib = This->not_attached_to_typelib;
+ ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
+ if (not_attached_to_typelib)
+ HeapFree(GetProcessHeap(), 0, This);
+ /* otherwise This will be freed when typelib is freed */
}
+
return ref;
}
hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue);
if (FAILED(hr))
{
- SysFreeString((BSTR)dest_ptr);
+ SysFreeString((BSTR)dest);
return hr;
}
}
*/
if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
- if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE &&
- This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL )
+ if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)
{
*pRefType = -1;
}
return DISP_E_UNKNOWNNAME;
}
+
+#ifdef __i386__
+
+extern DWORD CDECL call_method( void *func, int nb_args, const DWORD *args );
+__ASM_GLOBAL_FUNC( call_method,
+ "pushl %ebp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+ "movl %esp,%ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+ "pushl %esi\n\t"
+ __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
+ "pushl %edi\n\t"
+ __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
+ "movl 12(%ebp),%edx\n\t"
+ "shll $2,%edx\n\t"
+ "jz 1f\n\t"
+ "subl %edx,%esp\n\t"
+ "andl $~15,%esp\n\t"
+ "movl 12(%ebp),%ecx\n\t"
+ "movl 16(%ebp),%esi\n\t"
+ "movl %esp,%edi\n\t"
+ "cld\n\t"
+ "rep; movsl\n"
+ "1:\tcall *8(%ebp)\n\t"
+ "leal -8(%ebp),%esp\n\t"
+ "popl %edi\n\t"
+ __ASM_CFI(".cfi_same_value %edi\n\t")
+ "popl %esi\n\t"
+ __ASM_CFI(".cfi_same_value %esi\n\t")
+ "popl %ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
+ "ret" )
+
/* ITypeInfo::Invoke
*
* Invokes a method, or accesses a property of an object, that implements the
switch (callconv) {
case CC_STDCALL:
-
- switch (nrargs) {
- case 0:
- res = func();
- break;
- case 1:
- res = func(args[0]);
- break;
- case 2:
- res = func(args[0],args[1]);
- break;
- case 3:
- res = func(args[0],args[1],args[2]);
- break;
- case 4:
- res = func(args[0],args[1],args[2],args[3]);
- break;
- case 5:
- res = func(args[0],args[1],args[2],args[3],args[4]);
- break;
- case 6:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5]);
- break;
- case 7:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
- break;
- case 8:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
- break;
- case 9:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
- break;
- case 10:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]);
- break;
- case 11:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]);
- break;
- case 12:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]);
- break;
- case 13:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12]);
- break;
- case 14:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13]);
- break;
- case 15:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14]);
- break;
- case 16:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15]);
- break;
- case 17:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16]);
- break;
- case 18:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17]);
- break;
- case 19:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18]);
- break;
- case 20:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19]);
- break;
- case 21:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20]);
- break;
- case 22:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21]);
- break;
- case 23:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22]);
- break;
- case 24:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23]);
- break;
- case 25:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24]);
- break;
- case 26:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25]);
- break;
- case 27:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26]);
- break;
- case 28:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27]);
- break;
- case 29:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28]);
- break;
- case 30:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28],args[29]);
- break;
- default:
- FIXME("unsupported number of arguments %d in stdcall\n",nrargs);
- res = -1;
- break;
- }
+ case CC_CDECL:
+ res = call_method( func, nrargs, args );
break;
default:
FIXME("unsupported calling convention %d\n",callconv);
return 1;
}
}
+#endif /* __i386__ */
static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
{
void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
{
+#ifdef __i386__
int argsize, argspos;
UINT i;
DWORD *args;
V_VT(pvargResult) = vtReturn;
V_UI4(pvargResult) = hres;
}
-
HeapFree(GetProcessHeap(),0,args);
return S_OK;
+#else
+ FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
+ pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
+ return E_NOTIMPL;
+#endif
}
#define INVBUF_ELEMENT_SIZE \
else
{
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
- hres = VariantCopy(&missing_arg[i], src_arg);
+ if (wParamFlags & PARAMFLAG_FIN)
+ hres = VariantCopy(&missing_arg[i], src_arg);
V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
}
V_VT(&rgvarg[i]) = rgvt[i];
else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
{
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
- V_VT(&missing_arg[i]) = V_VT(src_arg);
- hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
+ if (wParamFlags & PARAMFLAG_FIN)
+ hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
+ else
+ V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF;
V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
V_VT(&rgvarg[i]) = rgvt[i];
}
for (i = 0; i < func_desc->cParams; i++)
{
USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+ VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
if (wParamFlags & PARAMFLAG_FLCID)
continue;
hres = VariantCopyInd(pVarResult, prgpvarg[i]);
}
- /* free data stored in varresult. Note that
- * VariantClear doesn't do what we want because we are
- * working with byref types. */
- /* FIXME: clear safearrays, bstrs, records and
- * variants here too */
- if ((V_VT(prgpvarg[i]) == (VT_UNKNOWN | VT_BYREF)) ||
- (V_VT(prgpvarg[i]) == (VT_DISPATCH | VT_BYREF)))
- {
- if(*V_UNKNOWNREF(prgpvarg[i]))
- IUnknown_Release(*V_UNKNOWNREF(prgpvarg[i]));
- }
- break;
+ VARIANT_ClearInd(prgpvarg[i]);
}
else if (vargs_converted < pDispParams->cArgs)
{
+ VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
if (wParamFlags & PARAMFLAG_FOUT)
{
- VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
-
- if ((rgvt[i] == VT_BYREF) && (V_VT(arg) != VT_BYREF))
+ if ((rgvt[i] & VT_BYREF) && !(V_VT(arg) & VT_BYREF))
+ {
hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg));
- if (FAILED(hres))
- {
- ERR("failed to convert param %d to vt %d\n", i,
- V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
- break;
+ if (FAILED(hres))
+ {
+ ERR("failed to convert param %d to vt %d\n", i,
+ V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
+ break;
+ }
}
}
else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
if (wParamFlags & PARAMFLAG_FHASDEFAULT)
VariantClear(&rgvarg[i]);
}
+
+ VariantClear(&missing_arg[i]);
}
if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
if (pBstrDllName)
*pBstrDllName = SysAllocString(This->DllName);
- if (HIWORD(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
+ if (!IS_INTRESOURCE(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
if (pBstrName)
*pBstrName = SysAllocString(pFDesc->Entry);
if (pwOrdinal)
*ppTInfo = (ITypeInfo*) pTypeInfoImpl;
- /* we use data structures from This, so we need to keep a reference
- * to it to stop it being destroyed and signal to the new instance to
+ /* the AddRef implicitly adds a reference to the parent typelib, which
+ * stops the copied data from being destroyed until the new typeinfo's
+ * refcount goes to zero, but we need to signal to the new instance to
* not free its data structures when it is destroyed */
- pTypeInfoImpl->no_free_data = TRUE;
- pTypeInfoImpl->next = This;
- ITypeInfo_AddRef((ITypeInfo*) This);
+ pTypeInfoImpl->not_attached_to_typelib = TRUE;
ITypeInfo_AddRef(*ppTInfo);
result = S_OK;
} else if ((hRefType != -1) && (hRefType & DISPATCH_HREF_MASK) &&
- (This->TypeAttr.typekind == TKIND_DISPATCH) &&
- (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL))
+ (This->TypeAttr.typekind == TKIND_DISPATCH))
{
HREFTYPE href_dispatch = hRefType;
result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo);
INT datatype2; /* if 0x8000, entry above is valid */
/* actually dunno */
/* else it is zero? */
+ /* if interface: inheritance level | no of inherited funcs */
INT res18; /* always? 0 */
/*060*/ INT res19; /* always? -1 */
} MSFT_TypeInfoBase;
/*0e*/ DWORD res0e; /* 0xffffffff */
/*12*/ WORD major_version; /* major version number */
/*14*/ WORD minor_version; /* minor version number */
-/*16*/ DWORD res16; /* 0xfffe0000 */
+/*16*/ DWORD res16; /* 0xfffe0000 or 0xfffc0000 (on dual interfaces?) */
/*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */
/*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */
/*1c*/ BYTE typeflags3;/* 0x02*/
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
+#include "winreg.h"
#include "winuser.h"
#include "wine/unicode.h"
/*================== Implementation Structures ===================================*/
+/* Used for storing cyclic list. Tail address is kept */
+typedef struct tagCyclicList {
+ struct tagCyclicList *next;
+ int indice;
+ int name;
+
+ union {
+ int val;
+ int *data;
+ }u;
+} CyclicList;
+
enum MSFT_segment_index {
MSFT_SEG_TYPEINFO = 0, /* type information */
MSFT_SEG_IMPORTINFO, /* import information */
char *typelib_segment_data[MSFT_SEG_MAX];
int typelib_segment_block_length[MSFT_SEG_MAX];
+ int typelib_guids; /* Number of defined typelib guids */
+ int typeinfo_guids; /* Number of defined typeinfo guids */
+
INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */
INT *typelib_namehash_segment;
ICreateTypeLib2Impl *typelib;
MSFT_TypeInfoBase *typeinfo;
- INT *typedata;
- int typedata_allocated;
- int typedata_length;
-
- int indices[42];
- int names[42];
- int offsets[42];
+ struct tagCyclicList *typedata; /* tail of cyclic list */
int datawidth;
return (length + 7) & ~3;
}
+/****************************************************************************
+ * ctl2_decode_name
+ *
+ * Converts string stored in typelib data to unicode.
+ */
+static void ctl2_decode_name(
+ char *data, /* [I] String to be decoded */
+ WCHAR **string) /* [O] Decoded string */
+{
+ int i, length;
+ static WCHAR converted_string[0x104];
+
+ length = data[0];
+
+ for(i=0; i<length; i++)
+ converted_string[i] = data[i+4];
+ converted_string[length] = '\0';
+
+ *string = converted_string;
+}
+
/****************************************************************************
* ctl2_encode_string
*
return (length + 5) & ~3;
}
+/****************************************************************************
+ * ctl2_decode_string
+ *
+ * Converts string stored in typelib data to unicode.
+ */
+static void ctl2_decode_string(
+ char *data, /* [I] String to be decoded */
+ WCHAR **string) /* [O] Decoded string */
+{
+ int i, length;
+ static WCHAR converted_string[0x104];
+
+ length = data[0] + (data[1]<<8);
+ if((length&0x3) == 1)
+ length >>= 2;
+
+ for(i=0; i<length; i++)
+ converted_string[i] = data[i+2];
+ converted_string[length] = '\0';
+
+ *string = converted_string;
+}
+
/****************************************************************************
* ctl2_alloc_segment
*
typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16;
typeinfo->memoffset = -1; /* should be EOF if no elements */
typeinfo->res2 = 0;
- typeinfo->res3 = -1;
+ typeinfo->res3 = 0;
typeinfo->res4 = 3;
typeinfo->res5 = 0;
typeinfo->cElement = 0;
* Failure: -1 (this is invariably an out of memory condition).
*/
static int ctl2_alloc_importinfo(
- ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
- MSFT_ImpInfo *impinfo) /* [I] The import information to store. */
+ ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
+ MSFT_ImpInfo *impinfo) /* [I] The import information to store. */
{
int offset;
MSFT_ImpInfo *impinfo_space;
- for (offset = 0;
- offset < This->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
- offset += sizeof(MSFT_ImpInfo)) {
- if (!memcmp(&(This->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]),
- impinfo, sizeof(MSFT_ImpInfo))) {
- return offset;
- }
+ impinfo_space = (MSFT_ImpInfo*)&This->typelib_segment_data[MSFT_SEG_IMPORTINFO][0];
+ for (offset=0; offset<This->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
+ offset+=sizeof(MSFT_ImpInfo)) {
+ if(impinfo_space->oImpFile == impinfo->oImpFile
+ && impinfo_space->oGuid == impinfo->oGuid)
+ return offset;
+
+ impinfo_space += 1;
}
impinfo->flags |= This->typelib_header.nimpinfos++;
static int ctl2_alloc_importfile(
ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
int guidoffset, /* [I] The offset to the GUID for the imported library. */
+ LCID lcid, /* [I] The LCID of imported library. */
int major_version, /* [I] The major version number of the imported library. */
int minor_version, /* [I] The minor version number of the imported library. */
const WCHAR *filename) /* [I] The filename of the imported library. */
importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset];
importfile->guid = guidoffset;
- importfile->lcid = This->typelib_header.lcid2;
+ importfile->lcid = lcid;
importfile->version = major_version | (minor_version << 16);
memcpy(importfile->filename, encoded_string, length);
return TYPE_E_ELEMENTNOTFOUND;
}
+/****************************************************************************
+ * ctl2_add_default_value
+ *
+ * Adds default value of an argument
+ *
+ * RETURNS
+ *
+ * Success: S_OK
+ * Failure: Error code from winerror.h
+ */
+static HRESULT ctl2_add_default_value(
+ ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */
+ int *encoded_value, /* [O] The encoded default value or data offset */
+ VARIANT *value, /* [I] Default value to be encoded */
+ VARTYPE arg_type) /* [I] Argument type */
+{
+ VARIANT v;
+ HRESULT hres;
+
+ TRACE("%p %d %d\n", This, V_VT(value), arg_type);
+
+ if(arg_type == VT_INT)
+ arg_type = VT_I4;
+ if(arg_type == VT_UINT)
+ arg_type = VT_UI4;
+
+ v = *value;
+ if(V_VT(value) != arg_type) {
+ hres = VariantChangeType(&v, value, 0, arg_type);
+ if(FAILED(hres))
+ return hres;
+ }
+
+ /* Check if default value can be stored in encoded_value */
+ switch(arg_type) {
+ int mask = 0;
+ case VT_I4:
+ case VT_UI4:
+ mask = 0x3ffffff;
+ if(V_UI4(&v)>0x3ffffff)
+ break;
+ case VT_I1:
+ case VT_UI1:
+ case VT_BOOL:
+ if(!mask)
+ mask = 0xff;
+ case VT_I2:
+ case VT_UI2:
+ if(!mask)
+ mask = 0xffff;
+ *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24);
+ return S_OK;
+ }
+
+ switch(arg_type) {
+ case VT_I4:
+ case VT_R4:
+ case VT_UI4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_HRESULT:
+ case VT_PTR: {
+ /* Construct the data to be allocated */
+ int data[2];
+ data[0] = arg_type + (V_UI4(&v)<<16);
+ data[1] = (V_UI4(&v)>>16) + 0x57570000;
+
+ /* Check if the data was already allocated */
+ /* Currently the structures doesn't allow to do it in a nice way */
+ for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-8; *encoded_value+=4)
+ if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8))
+ return S_OK;
+
+ /* Allocate the data */
+ *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0);
+ if(*encoded_value == -1)
+ return E_OUTOFMEMORY;
+
+ memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8);
+ return S_OK;
+ }
+ case VT_BSTR: {
+ /* Construct the data */
+ int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3;
+ char *data = HeapAlloc(GetProcessHeap(), 0, len);
+
+ if(!data)
+ return E_OUTOFMEMORY;
+
+ *((unsigned short*)data) = arg_type;
+ *((unsigned*)(data+2)) = SysStringLen(V_BSTR(&v));
+ for(i=0; i<SysStringLen(V_BSTR(&v)); i++) {
+ if(V_BSTR(&v)[i] <= 0x7f)
+ data[i+6] = V_BSTR(&v)[i];
+ else
+ data[i+6] = '?';
+ }
+ WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), SysStringLen(V_BSTR(&v)), &data[6], len-6, NULL, NULL);
+ for(i=6+SysStringLen(V_BSTR(&v)); i<len; i++)
+ data[i] = 0x57;
+
+ /* Check if the data was already allocated */
+ for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4)
+ if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) {
+ HeapFree(GetProcessHeap(), 0, data);
+ return S_OK;
+ }
+
+ /* Allocate the data */
+ *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0);
+ if(*encoded_value == -1) {
+ HeapFree(GetProcessHeap(), 0, data);
+ return E_OUTOFMEMORY;
+ }
+
+ memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len);
+ HeapFree(GetProcessHeap(), 0, data);
+ return S_OK;
+ }
+ default:
+ FIXME("Argument type not yet handled\n");
+ return E_NOTIMPL;
+ }
+}
+
/*================== ICreateTypeInfo2 Implementation ===================================*/
/******************************************************************************
if (!ref) {
if (This->typelib) {
ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib);
- This->typelib = NULL;
+ /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */
+ /* This->typelib = NULL; */
}
/* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
guidoffset = ctl2_alloc_guid(This->typelib, &foo);
if (guidoffset == -1) return E_OUTOFMEMORY;
- fileoffset = ctl2_alloc_importfile(This->typelib, guidoffset, 2, 0, stdole2tlb);
+ fileoffset = ctl2_alloc_importfile(This->typelib, guidoffset,
+ This->typelib->typelib_header.lcid2, 2, 0, stdole2tlb);
if (fileoffset == -1) return E_OUTOFMEMORY;
foo.guid = IID_IDispatch;
TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType);
+ if(!pTInfo || !phRefType)
+ return E_INVALIDARG;
+
/*
- * 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...
}
if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) {
+ /* Process locally defined TypeInfo */
*phRefType = This->typelib->typelib_typeinfo_offsets[index];
} else {
- FIXME("(%p,%p,%p), pTInfo from different typelib.\n", iface, pTInfo, phRefType);
+ static const WCHAR regkey[] = {'T','y','p','e','L','i','b','\\','{',
+ '%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%',
+ '0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x',
+ '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',
+ '}','\\','%','d','.','%','d','\\','0','\\','w','i','n','3','2',0};
+
+ WCHAR name[MAX_PATH], *p;
+ TLIBATTR *tlibattr;
+ TYPEATTR *typeattr;
+ MSFT_GuidEntry guid, *check_guid;
+ MSFT_ImpInfo impinfo;
+ int guid_offset, import_offset;
+ DWORD len;
+ HRESULT hres;
+
+ /* Allocate container GUID */
+ hres = ITypeLib_GetLibAttr(container, &tlibattr);
+ if(FAILED(hres))
+ return hres;
+
+ guid.guid = tlibattr->guid;
+ guid.hreftype = This->typelib->typelib_guids*12+2;
+ guid.next_hash = -1;
+
+ guid_offset = ctl2_alloc_guid(This->typelib, &guid);
+ if(guid_offset == -1) {
+ ITypeLib_ReleaseTLibAttr(container, tlibattr);
+ return E_OUTOFMEMORY;
+ }
+
+ check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
+ if(check_guid->hreftype == guid.hreftype)
+ This->typelib->typelib_guids++;
+
+ /* Get import file name */
+ /* Check HKEY_CLASSES_ROOT\TypeLib\{GUID}\{Ver}\0\win32 */
+ len = MAX_PATH;
+ sprintfW(name, regkey, guid.guid.Data1, guid.guid.Data2,
+ guid.guid.Data3, guid.guid.Data4[0], guid.guid.Data4[1],
+ guid.guid.Data4[2], guid.guid.Data4[3], guid.guid.Data4[4],
+ guid.guid.Data4[5], guid.guid.Data4[6], guid.guid.Data4[7],
+ tlibattr->wMajorVerNum, tlibattr->wMinorVerNum);
+
+ if(RegGetValueW(HKEY_CLASSES_ROOT, name, NULL, RRF_RT_REG_SZ, NULL, name, &len)!=ERROR_SUCCESS
+ || (p=strrchrW(name, '\\'))==NULL) {
+ ERR("Error guessing typelib filename\n");
+ ITypeLib_ReleaseTLibAttr(container, tlibattr);
+ return E_NOTIMPL;
+ }
+ memmove(name, p+1, strlenW(p)*sizeof(WCHAR));
+
+ /* Import file */
+ import_offset = ctl2_alloc_importfile(This->typelib, guid_offset,
+ tlibattr->lcid, tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, name);
+ ITypeLib_ReleaseTLibAttr(container, tlibattr);
+
+ if(import_offset == -1)
+ return E_OUTOFMEMORY;
+
+ /* Allocate referenced guid */
+ hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr);
+ if(FAILED(hres))
+ return hres;
+
+ guid.guid = typeattr->guid;
+ guid.hreftype = This->typelib->typeinfo_guids*12+1;
+ guid.next_hash = -1;
+ ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr);
+
+ guid_offset = ctl2_alloc_guid(This->typelib, &guid);
+ if(guid_offset == -1)
+ return E_OUTOFMEMORY;
+
+ check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
+ if(check_guid->hreftype == guid.hreftype)
+ This->typelib->typeinfo_guids++;
+
+ /* Allocate importinfo */
+ impinfo.flags = ((This->typeinfo->typekind&0xf)<<24) | MSFT_IMPINFO_OFFSET_IS_GUID;
+ impinfo.oImpFile = import_offset;
+ impinfo.oGuid = guid_offset;
+ *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1;
+
+ if(!memcmp(&guid.guid, &IID_IDispatch, sizeof(GUID)))
+ This->typelib->typelib_header.dispatchpos = *phRefType;
}
ITypeLib_Release(container);
{
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
- int offset;
+ CyclicList *iter, *insert;
int *typedata;
- int i;
+ int i, num_defaults = 0;
int decoded_size;
+ HRESULT hres;
+
+ TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);
+
+ if(!pFuncDesc || (pFuncDesc->memid>0x7fffffff && pFuncDesc->memid!=MEMBERID_NIL))
+ return E_INVALIDARG;
+
+ TRACE("{%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);
+
+ switch(This->typeinfo->typekind&0xf) {
+ case TKIND_MODULE:
+ if(pFuncDesc->funckind != FUNC_STATIC)
+ return TYPE_E_BADMODULEKIND;
+ break;
+ case TKIND_DISPATCH:
+ if(pFuncDesc->funckind != FUNC_DISPATCH)
+ return TYPE_E_BADMODULEKIND;
+ break;
+ default:
+ if(pFuncDesc->funckind != FUNC_PUREVIRTUAL)
+ return TYPE_E_BADMODULEKIND;
+ }
+
+ if(This->typeinfo->cElement<index)
+ return TYPE_E_ELEMENTNOTFOUND;
+
+ if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) &&
+ !pFuncDesc->cParams)
+ return TYPE_E_INCONSISTENTPROPFUNCS;
+
+ /* get number of arguments with default values specified */
+ for (i = 0; i < pFuncDesc->cParams; i++)
+ if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
+ num_defaults++;
- 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;
+ This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
+ if(!This->typedata)
+ return E_OUTOFMEMORY;
+
+ This->typedata->next = This->typedata;
+ This->typedata->u.val = 0;
}
/* allocate type data space for us */
- offset = This->typedata[0];
- This->typedata[0] += 0x18 + (pFuncDesc->cParams * 12);
- typedata = This->typedata + (offset >> 2) + 1;
+ insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
+ if(!insert)
+ return E_OUTOFMEMORY;
+ insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[6])+sizeof(int[(num_defaults?4:3)])*pFuncDesc->cParams);
+ if(!insert->u.data) {
+ HeapFree(GetProcessHeap(), 0, insert);
+ return E_OUTOFMEMORY;
+ }
/* fill out the basic type information */
- typedata[0] = (0x18 + (pFuncDesc->cParams * 12)) | (index << 16);
+ typedata = insert->u.data;
+ typedata[0] = 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
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[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind;
+ if(num_defaults) typedata[4] |= 0x1000;
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;
+ typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16;
+
+ /* add default values */
+ if(num_defaults) {
+ for (i = 0; i < pFuncDesc->cParams; i++)
+ if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
+ hres = ctl2_add_default_value(This->typelib, typedata+6+i,
+ &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue,
+ pFuncDesc->lprgelemdescParam[i].tdesc.vt);
+
+ if(FAILED(hres)) {
+ HeapFree(GetProcessHeap(), 0, insert->u.data);
+ HeapFree(GetProcessHeap(), 0, insert);
+ return hres;
+ }
+ } else
+ typedata[6+i] = 0xffffffff;
+
+ num_defaults = pFuncDesc->cParams;
+ }
+ /* add arguments */
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;
+ ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc,
+ &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size);
+ typedata[7+num_defaults+(i*3)] = -1;
+ typedata[8+num_defaults+(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;
+ insert->indice = pFuncDesc->memid;
+ insert->name = -1;
+
+ /* insert type data to list */
+ if(index == This->typeinfo->cElement) {
+ insert->next = This->typedata->next;
+ This->typedata->next = insert;
+ This->typedata = insert;
+ } else {
+ iter = This->typedata->next;
+ for(i=0; i<index; i++)
+ iter = iter->next;
- /* ??? */
- if (index < 2) This->typeinfo->res2 += pFuncDesc->cParams << 4;
- This->typeinfo->res3 += pFuncDesc->cParams << 4;
+ insert->next = iter->next;
+ iter->next = insert;
+ }
- /* adjust size of VTBL */
- This->typeinfo->cbSizeVft += 4;
+ /* update type data size */
+ This->typedata->next->u.val += 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
/* Increment the number of function elements */
This->typeinfo->cElement += 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;
+ if (This->typeinfo->cImplTypes && index==1)
+ return TYPE_E_BADMODULEKIND;
- This->typeinfo->cImplTypes++;
+ if( index != 0) return TYPE_E_ELEMENTNOTFOUND;
- /* 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; /* ? */
+ This->typeinfo->datatype1 = hRefType;
} else {
FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15);
return E_OUTOFMEMORY;
}
+ This->typeinfo->cImplTypes++;
return S_OK;
}
VARDESC* pVarDesc)
{
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
- int offset;
+
+ CyclicList *insert;
INT *typedata;
int var_datawidth;
int var_alignment;
}
if (!This->typedata) {
- This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000);
- This->typedata[0] = 0;
+ This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
+ if(!This->typedata)
+ return E_OUTOFMEMORY;
+
+ This->typedata->next = This->typedata;
+ This->typedata->u.val = 0;
}
/* allocate type data space for us */
- offset = This->typedata[0];
- This->typedata[0] += 0x14;
- typedata = This->typedata + (offset >> 2) + 1;
+ insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
+ if(!insert)
+ return E_OUTOFMEMORY;
+ insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[5]));
+ if(!insert->u.data) {
+ HeapFree(GetProcessHeap(), 0, insert);
+ return E_OUTOFMEMORY;
+ }
+
+ insert->next = This->typedata->next;
+ This->typedata->next = insert;
+ This->typedata = insert;
+
+ This->typedata->next->u.val += 0x14;
+ typedata = This->typedata->u.data;
/* fill out the basic type information */
typedata[0] = 0x14 | (index << 16);
typedata[3] = (sizeof(VARDESC) << 16) | 0;
/* update the index data */
- This->indices[index] = 0x40000000 + index;
- This->names[index] = -1;
- This->offsets[index] = offset;
+ insert->indice = 0x40000000 + index;
+ insert->name = -1;
/* figure out type widths and whatnot */
ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc,
UINT cNames)
{
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
-
- UINT i;
- int offset;
+ CyclicList *iter = NULL, *iter2;
+ int offset, len, i=0;
char *namedata;
- FIXME("(%p,%d,%s,%d), stub!\n", iface, index, debugstr_w(*rgszNames), cNames);
+ TRACE("(%p %d %p %d)\n", iface, index, rgszNames, cNames);
+
+ if(!rgszNames)
+ return E_INVALIDARG;
+
+ if(index >= This->typeinfo->cElement || !cNames)
+ return TYPE_E_ELEMENTNOTFOUND;
+
+ len = ctl2_encode_name(This->typelib, rgszNames[0], &namedata);
+ for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
+ if(i == index)
+ iter = iter2;
+ else if(iter2->name!=-1 && !memcmp(namedata,
+ This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len))
+ return TYPE_E_AMBIGUOUSNAME;
+
+ i++;
+ }
+
+ /* cNames == cParams for put or putref accessor, cParams+1 otherwise */
+ if(cNames != iter->u.data[5] + ((iter->u.data[4]>>3)&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1))
+ return TYPE_E_ELEMENTNOTFOUND;
offset = ctl2_alloc_name(This->typelib, rgszNames[0]);
- This->names[index] = offset;
+ if(offset == -1)
+ return E_OUTOFMEMORY;
+
+ iter->name = offset;
namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
- namedata[9] &= ~0x10;
- if (*((INT *)namedata) == -1) {
- *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
- }
+ *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
- for (i = 1; i < cNames; i++) {
- /* FIXME: Almost certainly easy to break */
- int *paramdata = &This->typedata[This->offsets[index] >> 2];
+ if(iter->u.data[4]&0x1000)
+ len = iter->u.data[5];
+ else
+ len = 0;
+ for (i = 1; i < cNames; i++) {
offset = ctl2_alloc_name(This->typelib, rgszNames[i]);
- paramdata[(i * 3) + 5] = offset;
+ iter->u.data[(i*3) + 4 + len] = offset;
}
return S_OK;
LPOLESTR szName)
{
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
- int offset;
+ CyclicList *iter;
+ int offset, i;
char *namedata;
TRACE("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szName));
if ((This->typeinfo->typekind & 15) == TKIND_ENUM) {
namedata[9] |= 0x20;
}
- This->names[index] = offset;
+ iter = This->typedata->next->next;
+ for(i=0; i<index; i++)
+ iter = iter->next;
+
+ iter->name = offset;
return S_OK;
}
static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
ICreateTypeInfo2* iface)
{
- TRACE("(%p), stub!\n", iface);
-/* return E_OUTOFMEMORY; */
+ ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
+ CyclicList *iter, *iter2, **typedata;
+ HREFTYPE hreftype;
+ HRESULT hres;
+ int i;
+
+ TRACE("(%p)\n", iface);
+
+ if((This->typeinfo->typekind&0xf) == TKIND_COCLASS)
+ return S_OK;
+
+ /* Validate inheritance */
+ This->typeinfo->datatype2 = 0;
+ hreftype = This->typeinfo->datatype1;
+
+ /* Process internally defined interfaces */
+ for(i=0; i<This->typelib->typelib_header.nrtypeinfos; i++) {
+ MSFT_TypeInfoBase *header;
+
+ if(hreftype&1)
+ break;
+
+ header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]);
+ This->typeinfo->datatype2 += (header->cElement<<16) + 1;
+ hreftype = header->datatype1;
+ }
+ if(i == This->typelib->typelib_header.nrtypeinfos)
+ return TYPE_E_CIRCULARTYPE;
+
+ /* Process externally defined interfaces */
+ if(hreftype != -1) {
+ ITypeInfo *cur, *next;
+ TYPEATTR *typeattr;
+
+ hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next);
+ if(FAILED(hres))
+ return hres;
+
+ hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur);
+ if(FAILED(hres))
+ return hres;
+
+ ITypeInfo_Release(next);
+
+ while(1) {
+ hres = ITypeInfo_GetTypeAttr(cur, &typeattr);
+ if(FAILED(hres))
+ return hres;
+
+ if(!memcmp(&typeattr->guid, &IID_IDispatch, sizeof(IDispatch)))
+ This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
+
+ This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1;
+ ITypeInfo_ReleaseTypeAttr(cur, typeattr);
+
+ hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype);
+ if(hres == TYPE_E_ELEMENTNOTFOUND)
+ break;
+ if(FAILED(hres))
+ return hres;
+
+ hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next);
+ if(FAILED(hres))
+ return hres;
+
+ ITypeInfo_Release(cur);
+ cur = next;
+ }
+ }
+
+ This->typeinfo->cbSizeVft = (This->typeinfo->datatype2>>16) * 4;
+ if(!This->typedata)
+ return S_OK;
+
+ typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff));
+ if(!typedata)
+ return E_OUTOFMEMORY;
+
+ /* Assign IDs and VTBL entries */
+ i = 0;
+ for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
+ /* Assign MEMBERID if MEMBERID_NIL was specified */
+ if(iter->indice == MEMBERID_NIL) {
+ iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16);
+
+ for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
+ if(iter == iter2) continue;
+ if(iter2->indice == iter->indice) {
+ iter->indice = 0x5fffffff + This->typeinfo->cElement + i + (This->typeinfo->datatype2<<16);
+
+ for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
+ if(iter == iter2) continue;
+ if(iter2->indice == iter->indice)
+ return E_ACCESSDENIED;
+ }
+
+ break;
+ }
+ }
+ }
+
+ typedata[i] = iter;
+
+ iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16);
+
+ if((This->typeinfo->typekind&0xf) != TKIND_MODULE) {
+ iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft;
+ This->typeinfo->cbSizeVft += 4;
+ }
+
+ /* Construct a list of elements with the same memberid */
+ iter->u.data[4] = (iter->u.data[4]&0xffff) | (i<<16);
+ for(iter2=This->typedata->next->next; iter2!=iter; iter2=iter2->next) {
+ if(iter->indice == iter2->indice) {
+ int v1, v2;
+
+ v1 = iter->u.data[4] >> 16;
+ v2 = iter2->u.data[4] >> 16;
+
+ iter->u.data[4] = (iter->u.data[4]&0xffff) | (v2<<16);
+ iter2->u.data[4] = (iter2->u.data[4]&0xffff) | (v1<<16);
+ break;
+ }
+ }
+
+ i++;
+ }
+
+ for(i=0; i<(This->typeinfo->cElement&0xffff); i++) {
+ if(typedata[i]->u.data[4]>>16 > i) {
+ int inv;
+
+ inv = (typedata[i]->u.data[4]>>3) & 0xf;
+ i = typedata[i]->u.data[4] >> 16;
+
+ while(i > typedata[i]->u.data[4]>>16) {
+ int invkind = (typedata[i]->u.data[4]>>3) & 0xf;
+
+ if(inv & invkind) {
+ HeapFree(GetProcessHeap(), 0, typedata);
+ return TYPE_E_DUPLICATEID;
+ }
+
+ i = typedata[i]->u.data[4] >> 16;
+ inv |= invkind;
+ }
+
+ if(inv & INVOKE_FUNC) {
+ HeapFree(GetProcessHeap(), 0, typedata);
+ return TYPE_E_INCONSISTENTPROPFUNCS;
+ }
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, typedata);
return S_OK;
}
ITypeInfo2* iface,
TYPEATTR** ppTypeAttr)
{
- FIXME("(%p,%p), stub!\n", iface, ppTypeAttr);
- return E_OUTOFMEMORY;
+ ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+ HRESULT hres;
+
+ TRACE("(%p,%p)\n", iface, ppTypeAttr);
+
+ if(!ppTypeAttr)
+ return E_INVALIDARG;
+
+ hres = ICreateTypeInfo_LayOut((ICreateTypeInfo*)This);
+ if(FAILED(hres))
+ return hres;
+
+ *ppTypeAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEATTR));
+ if(!*ppTypeAttr)
+ return E_OUTOFMEMORY;
+
+ if(This->typeinfo->posguid != -1) {
+ MSFT_GuidEntry *guid;
+
+ guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][This->typeinfo->posguid];
+ (*ppTypeAttr)->guid = guid->guid;
+ }
+
+ (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid;
+ (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size;
+ (*ppTypeAttr)->typekind = This->typeinfo->typekind&0xf;
+ (*ppTypeAttr)->cFuncs = This->typeinfo->cElement&0xffff;
+ (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16;
+ (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes;
+ (*ppTypeAttr)->cbSizeVft = This->typeinfo->cbSizeVft;
+ (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f;
+ (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags;
+ (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff;
+ (*ppTypeAttr)->wMinorVerNum = This->typeinfo->version>>16;
+
+ if((*ppTypeAttr)->typekind == TKIND_ALIAS)
+ FIXME("TKIND_ALIAS handling not implemented\n");
+
+ return S_OK;
}
/******************************************************************************
UINT index,
HREFTYPE* pRefType)
{
- FIXME("(%p,%d,%p), stub!\n", iface, index, pRefType);
- return E_OUTOFMEMORY;
+ ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+ MSFT_RefRecord *ref;
+ int offset;
+
+ TRACE("(%p,%d,%p)\n", iface, index, pRefType);
+
+ if(!pRefType)
+ return E_INVALIDARG;
+
+ if(index == -1) {
+ FIXME("Dual interfaces not handled yet\n");
+ return E_NOTIMPL;
+ }
+
+ if(index >= This->typeinfo->cImplTypes)
+ return TYPE_E_ELEMENTNOTFOUND;
+
+ if((This->typeinfo->typekind&0xf) == TKIND_INTERFACE) {
+ *pRefType = This->typeinfo->datatype1 + 2;
+ return S_OK;
+ }
+
+ 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];
+ *pRefType = ref->reftype;
+ return S_OK;
}
/******************************************************************************
UINT index,
INT* pImplTypeFlags)
{
- FIXME("(%p,%d,%p), stub!\n", iface, index, pImplTypeFlags);
- return E_OUTOFMEMORY;
+ ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+ int offset;
+ MSFT_RefRecord *ref;
+
+ TRACE("(%p,%d,%p)\n", iface, index, pImplTypeFlags);
+
+ if(!pImplTypeFlags)
+ return E_INVALIDARG;
+
+ if(index >= This->typeinfo->cImplTypes)
+ return TYPE_E_ELEMENTNOTFOUND;
+
+ if((This->typeinfo->typekind&0xf) != TKIND_COCLASS) {
+ *pImplTypeFlags = 0;
+ return S_OK;
+ }
+
+ 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];
+ *pImplTypeFlags = ref->flags;
+ return S_OK;
}
/******************************************************************************
HREFTYPE hRefType,
ITypeInfo** ppTInfo)
{
- FIXME("(%p,%d,%p), stub!\n", iface, hRefType, ppTInfo);
- return E_OUTOFMEMORY;
+ ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+
+ TRACE("(%p,%d,%p)\n", iface, hRefType, ppTInfo);
+
+ if(!ppTInfo)
+ return E_INVALIDARG;
+
+ if(hRefType&1) {
+ ITypeLib *tl;
+ MSFT_ImpInfo *impinfo;
+ MSFT_ImpFile *impfile;
+ MSFT_GuidEntry *guid;
+ WCHAR *filename;
+ HRESULT hres;
+
+ if((hRefType&(~0x3)) >= This->typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length)
+ return E_FAIL;
+
+ impinfo = (MSFT_ImpInfo*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][hRefType&(~0x3)];
+ impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile];
+ guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid];
+
+ ctl2_decode_string(impfile->filename, &filename);
+
+ hres = LoadTypeLib(filename, &tl);
+ if(FAILED(hres))
+ return hres;
+
+ hres = ITypeLib_GetTypeInfoOfGuid(tl, &guid->guid, ppTInfo);
+
+ ITypeLib_Release(tl);
+ return hres;
+ } else {
+ ICreateTypeInfo2Impl *iter;
+ int i = 0;
+
+ for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) {
+ if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) {
+ *ppTInfo = (ITypeInfo*)&iter->lpVtblTypeInfo2;
+
+ ITypeLib_AddRef(*ppTInfo);
+ return S_OK;
+ }
+ i++;
+ }
+ }
+
+ return E_FAIL;
}
/******************************************************************************
ITypeInfo2* iface,
TYPEATTR* pTypeAttr)
{
- FIXME("(%p,%p), stub!\n", iface, pTypeAttr);
+ TRACE("(%p,%p)\n", iface, pTypeAttr);
+
+ HeapFree(GetProcessHeap(), 0, pTypeAttr);
}
/******************************************************************************
while (This->typeinfos) {
ICreateTypeInfo2Impl *typeinfo = This->typeinfos;
This->typeinfos = typeinfo->next_typeinfo;
- HeapFree(GetProcessHeap(), 0, typeinfo->typedata);
+ if(typeinfo->typedata) {
+ CyclicList *iter, *rem;
+
+ rem = typeinfo->typedata->next;
+ typeinfo->typedata->next = NULL;
+ iter = rem->next;
+ HeapFree(GetProcessHeap(), 0, rem);
+
+ while(iter) {
+ rem = iter;
+ iter = iter->next;
+ HeapFree(GetProcessHeap(), 0, rem->u.data);
+ HeapFree(GetProcessHeap(), 0, rem);
+ }
+ }
HeapFree(GetProcessHeap(), 0, typeinfo);
}
ICreateTypeInfo **ppCTInfo)
{
ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
+ char *name;
TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo);
+ ctl2_encode_name(This, szName, &name);
+ if(ctl2_find_name(This, name) != -1)
+ return TYPE_E_NAMECONFLICT;
+
*ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind);
if (!*ppCTInfo) return E_OUTOFMEMORY;
return -1;
}
-static void ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
+static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
{
ICreateTypeInfo2Impl *typeinfo;
+ HRESULT hres;
for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
- typeinfo->typeinfo->memoffset = filesize;
- if (typeinfo->typedata) {
- ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
- filesize += typeinfo->typedata[0] + ((typeinfo->typeinfo->cElement >> 16) * 12) + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
- }
+ typeinfo->typeinfo->memoffset = filesize;
+
+ hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
+ if(FAILED(hres))
+ return hres;
+
+ if (typeinfo->typedata)
+ filesize += typeinfo->typedata->next->u.val
+ + ((typeinfo->typeinfo->cElement >> 16) * 12)
+ + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
}
+
+ return S_OK;
}
static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment)
ICreateTypeInfo2Impl *typeinfo;
for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
+ CyclicList *iter;
+ int offset = 0;
+
if (!typeinfo->typedata) continue;
- ctl2_write_chunk(hFile, typeinfo->typedata, typeinfo->typedata[0] + 4);
- ctl2_write_chunk(hFile, typeinfo->indices, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4);
- ctl2_write_chunk(hFile, typeinfo->names, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4);
- ctl2_write_chunk(hFile, typeinfo->offsets, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4);
+ iter = typeinfo->typedata->next;
+ ctl2_write_chunk(hFile, &iter->u.val, sizeof(int));
+ for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next)
+ ctl2_write_chunk(hFile, iter->u.data, iter->u.data[0] & 0xffff);
+
+ for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
+ ctl2_write_chunk(hFile, &iter->indice, sizeof(int));
+
+ for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
+ ctl2_write_chunk(hFile, &iter->name, sizeof(int));
+
+ for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) {
+ ctl2_write_chunk(hFile, &offset, sizeof(int));
+ offset += iter->u.data[0] & 0xffff;
+ }
}
}
int retval;
int filepos;
HANDLE hFile;
+ HRESULT hres;
TRACE("(%p)\n", iface);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID);
+ filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES);
- filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA);
filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID);
- ctl2_finalize_typeinfos(This, filepos);
+ hres = ctl2_finalize_typeinfos(This, filepos);
+ if(FAILED(hres)) {
+ CloseHandle(hFile);
+ return hres;
+ }
if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval;
if (This->typelib_header.varflags & HELPDLLFLAG)
if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO )) return retval;
if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH )) return retval;
if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID )) return retval;
+ if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES )) return retval;
if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO )) return retval;
if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval;
- if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES )) return retval;
if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH )) return retval;
if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME )) return retval;
if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING )) return retval;
if (!CloseHandle(hFile)) return retval;
- retval = S_OK;
- return retval;
+ return S_OK;
}
{
ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
- FIXME("(%p,%p), stub!\n", This, ppTLibAttr);
+ TRACE("(%p,%p)\n", This, ppTLibAttr);
- return E_OUTOFMEMORY;
+ if(!ppTLibAttr)
+ return E_INVALIDARG;
+
+ *ppTLibAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TLIBATTR));
+ if(!*ppTLibAttr)
+ return E_OUTOFMEMORY;
+
+ if(This->typelib_header.posguid != -1) {
+ MSFT_GuidEntry *guid;
+
+ guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid];
+ (*ppTLibAttr)->guid = guid->guid;
+ }
+
+ (*ppTLibAttr)->lcid = This->typelib_header.lcid;
+ (*ppTLibAttr)->syskind = This->typelib_header.varflags&0x3;
+ (*ppTLibAttr)->wMajorVerNum = This->typelib_header.version&0xffff;
+ (*ppTLibAttr)->wMinorVerNum = This->typelib_header.version>>16;
+ (*ppTLibAttr)->wLibFlags = This->typelib_header.flags;
+ return S_OK;
}
/******************************************************************************
BSTR* pBstrHelpFile)
{
ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
+ WCHAR *string;
- FIXME("(%p,%d,%p,%p,%p,%p), stub!\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
+ TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
- return E_OUTOFMEMORY;
+ if(index != -1) {
+ ICreateTypeInfo2Impl *iter;
+
+ for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo)
+ index--;
+
+ if(!iter)
+ return TYPE_E_ELEMENTNOTFOUND;
+
+ return ITypeInfo_GetDocumentation((ITypeInfo*)iter->lpVtblTypeInfo2,
+ -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
+ }
+
+ if(pBstrName) {
+ if(This->typelib_header.NameOffset == -1)
+ *pBstrName = NULL;
+ else {
+ MSFT_NameIntro *name = (MSFT_NameIntro*)&This->
+ typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset];
+
+ ctl2_decode_name((char*)&name->namelen, &string);
+
+ *pBstrName = SysAllocString(string);
+ if(!*pBstrName)
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ if(pBstrDocString) {
+ if(This->typelib_header.helpstring == -1)
+ *pBstrDocString = NULL;
+ else {
+ ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string);
+
+ *pBstrDocString = SysAllocString(string);
+ if(!*pBstrDocString) {
+ if(pBstrName) SysFreeString(*pBstrName);
+ return E_OUTOFMEMORY;
+ }
+ }
+ }
+
+ if(pdwHelpContext)
+ *pdwHelpContext = This->typelib_header.helpcontext;
+
+ if(pBstrHelpFile) {
+ if(This->typelib_header.helpfile == -1)
+ *pBstrHelpFile = NULL;
+ else {
+ ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string);
+
+ *pBstrHelpFile = SysAllocString(string);
+ if(!*pBstrHelpFile) {
+ if(pBstrName) SysFreeString(*pBstrName);
+ if(pBstrDocString) SysFreeString(*pBstrDocString);
+ return E_OUTOFMEMORY;
+ }
+ }
+ }
+
+ return S_OK;
}
/******************************************************************************
ITypeLib2 * iface,
TLIBATTR* pTLibAttr)
{
- ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
+ TRACE("(%p,%p)\n", iface, pTLibAttr);
- FIXME("(%p,%p), stub!\n", This, pTLibAttr);
+ HeapFree(GetProcessHeap(), 0, pTLibAttr);
}
/******************************************************************************
static unsigned interface_variant_size(const ULONG *pFlags, REFIID riid, IUnknown *punk)
{
- ULONG size;
- HRESULT hr;
- /* find the buffer size of the marshalled dispatch interface */
- hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
- if (FAILED(hr)) {
- if (!punk)
- WARN("NULL dispatch pointer\n");
- else
- ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%x\n", hr);
- return 0;
- }
- size += sizeof(ULONG); /* we have to store the buffersize in the stream */
- TRACE("wire-size extra of dispatch variant is %d\n", size);
- return size;
+ ULONG size = 0;
+ HRESULT hr;
+
+ if (punk)
+ {
+ hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
+ if (FAILED(hr))
+ {
+ ERR("interface variant buffer size calculation failed, HRESULT=0x%x\n", hr);
+ return 0;
+ }
+ }
+ size += sizeof(ULONG); /* we have to store the buffersize in the stream */
+ TRACE("wire-size extra of interface variant is %d\n", size);
+ return size;
}
static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar)
TRACE("pFlags=%d, Buffer=%p, pUnk=%p\n", *pFlags, Buffer, punk);
+ if(!punk)
+ {
+ memset(Buffer, 0, sizeof(ULONG));
+ return Buffer + sizeof(ULONG);
+ }
+
oldpos = Buffer;
/* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers.
memcpy(&size, Buffer, sizeof(ULONG));
TRACE("buffersize=%d\n", size);
+ if(!size)
+ {
+ *ppunk = NULL;
+ return Buffer + sizeof(ULONG);
+ }
+
working_mem = GlobalAlloc(0, size);
if (!working_mem) return oldpos;
if(header->vt & VT_BYREF)
{
+ ULONG mem_size;
Pos += 4;
+
+ switch (header->vt & ~VT_BYREF)
+ {
+ /* these types have a different memory size compared to wire size */
+ case VT_UNKNOWN:
+ case VT_DISPATCH:
+ case VT_BSTR:
+ mem_size = sizeof(void *);
+ break;
+ default:
+ mem_size = type_size;
+ break;
+ }
+
if (V_VT(pvar) != header->vt)
{
VariantClear(pvar);
- V_BYREF(pvar) = CoTaskMemAlloc(type_size);
+ V_BYREF(pvar) = CoTaskMemAlloc(mem_size);
}
else if (!V_BYREF(pvar))
- V_BYREF(pvar) = CoTaskMemAlloc(type_size);
+ V_BYREF(pvar) = CoTaskMemAlloc(mem_size);
memcpy(V_BYREF(pvar), Pos, type_size);
if((header->vt & VT_TYPEMASK) != VT_VARIANT)
Pos += type_size;
}
}
+static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype)
+{
+ if (sftype == SF_BSTR)
+ return sizeof(DWORD);
+ else if (sftype == SF_VARIANT)
+ return sizeof(variant_wire_t) - sizeof(DWORD);
+ else
+ return lpsa->cbElements;
+}
+
+static DWORD elem_mem_size(wireSAFEARRAY wiresa, SF_TYPE sftype)
+{
+ if (sftype == SF_BSTR)
+ return sizeof(BSTR);
+ else if (sftype == SF_VARIANT)
+ return sizeof(VARIANT);
+ else
+ return wiresa->cbElements;
+}
+
ULONG WINAPI LPSAFEARRAY_UserSize(ULONG *pFlags, ULONG StartingSize, LPSAFEARRAY *ppsa)
{
ULONG size = StartingSize;
SF_TYPE sftype;
GUID guid;
+ sftype = SAFEARRAY_GetUnionType(psa);
+
*(ULONG *)Buffer = psa->cDims;
Buffer += sizeof(ULONG);
*(USHORT *)Buffer = psa->cDims;
Buffer += sizeof(USHORT);
*(USHORT *)Buffer = psa->fFeatures;
Buffer += sizeof(USHORT);
- *(ULONG *)Buffer = psa->cbElements;
+ *(ULONG *)Buffer = elem_wire_size(psa, sftype);
Buffer += sizeof(ULONG);
hr = SafeArrayGetVartype(psa, &vt);
*(ULONG *)Buffer = (USHORT)psa->cLocks | (vt << 16);
Buffer += sizeof(ULONG);
- sftype = SAFEARRAY_GetUnionType(psa);
*(ULONG *)Buffer = sftype;
Buffer += sizeof(ULONG);
(*ppsa)->fFeatures &= FADF_AUTOSETFLAGS;
(*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS));
/* FIXME: there should be a limit on how large wiresa->cbElements can be */
- (*ppsa)->cbElements = wiresa->cbElements;
+ (*ppsa)->cbElements = elem_mem_size(wiresa, sftype);
(*ppsa)->cLocks = LOWORD(wiresa->cLocks);
/* SafeArrayCreateEx allocates the data for us, but
if (V_ISBYREF(arg)) {
rgVarRefIdx[cVarRef] = u;
VariantInit(&rgVarRef[cVarRef]);
+ VariantCopy(&rgVarRef[cVarRef], arg);
+ VariantClear(arg);
cVarRef++;
}
}
}
if (SUCCEEDED(hr)) {
+ /* copy ref args to arg array */
+ for (u=0; u<cVarRef; u++) {
+ unsigned i = rgVarRefIdx[u];
+ VariantCopy(&arg[i], &rgVarRef[u]);
+ }
+
pDispParams->rgvarg = arg;
hr = IDispatch_Invoke(This,
pExcepInfo,
pArgErr);
- /* copy ref args to out list */
+ /* copy ref args from arg array */
for (u=0; u<cVarRef; u++) {
unsigned i = rgVarRefIdx[u];
- VariantInit(&rgVarRef[u]);
VariantCopy(&rgVarRef[u], &arg[i]);
- /* clear original if equal, to avoid double-free */
- if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
- VariantClear(&rgvarg[i]);
}
}
/* Exponent format: length of the integral number part is fixed and
specified by the format. */
pad = need_int - have_int;
- if (pad >= 0)
- exponent -= pad;
- else
+ exponent -= pad;
+ if (pad < 0)
{
have_int = need_int;
have_frac -= pad;
- exponent -= pad;
pad = 0;
}
}
have_frac = -pad;
pad = 0;
}
+ if(exponent < 0 && exponent > (-256 + have_int + have_frac))
+ {
+ /* Remove exponent notation */
+ memmove(rgbDig - exponent, rgbDig, have_int + have_frac);
+ ZeroMemory(rgbDig, -exponent);
+ have_frac -= exponent;
+ exponent = 0;
+ }
}
/* Rounding the number */
}
else
(*prgbDig)++;
- /* We converted trailing digits to zeroes => have_frac has changed */
- while (have_frac > 0 && rgbDig[have_int + have_frac - 1] == 0)
- have_frac--;
}
+ /* We converted trailing digits to zeroes => have_frac has changed */
+ while (have_frac > 0 && rgbDig[have_int + have_frac - 1] == 0)
+ have_frac--;
}
TRACE("have_int=%d,need_int=%d,have_frac=%d,need_frac=%d,pad=%d,exp=%d\n",
have_int, need_int, have_frac, need_frac, pad, exponent);
if (FAILED(hRes))
return hRes;
- if (V_BSTR(pVarIn)[0] == '\0')
+ if (V_BSTR(&vStr)[0] == '\0')
strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header));
else
strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetPositive(header));
V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */
}
+HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
+{
+ HRESULT hres;
+
+ TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
+
+ hres = VARIANT_ValidateType(V_VT(pVarg));
+ if (FAILED(hres))
+ return hres;
+
+ switch (V_VT(pVarg))
+ {
+ case VT_DISPATCH:
+ case VT_UNKNOWN:
+ if (V_UNKNOWN(pVarg))
+ IUnknown_Release(V_UNKNOWN(pVarg));
+ break;
+ case VT_UNKNOWN | VT_BYREF:
+ case VT_DISPATCH | VT_BYREF:
+ if(*V_UNKNOWNREF(pVarg))
+ IUnknown_Release(*V_UNKNOWNREF(pVarg));
+ break;
+ case VT_BSTR:
+ SysFreeString(V_BSTR(pVarg));
+ break;
+ case VT_BSTR | VT_BYREF:
+ SysFreeString(*V_BSTRREF(pVarg));
+ break;
+ case VT_VARIANT | VT_BYREF:
+ VariantClear(V_VARIANTREF(pVarg));
+ break;
+ case VT_RECORD:
+ case VT_RECORD | VT_BYREF:
+ {
+ struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
+ if (pBr->pRecInfo)
+ {
+ IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord);
+ IRecordInfo_Release(pBr->pRecInfo);
+ }
+ break;
+ }
+ default:
+ if (V_ISARRAY(pVarg) || (V_VT(pVarg) & ~VT_BYREF) == VT_SAFEARRAY)
+ {
+ if (V_ISBYREF(pVarg))
+ {
+ if (*V_ARRAYREF(pVarg))
+ hres = SafeArrayDestroy(*V_ARRAYREF(pVarg));
+ }
+ else if (V_ARRAY(pVarg))
+ hres = SafeArrayDestroy(V_ARRAY(pVarg));
+ }
+ break;
+ }
+
+ V_VT(pVarg) = VT_EMPTY;
+ return hres;
+}
+
/******************************************************************************
* VariantClear [OLEAUT32.9]
*
static HRESULT VARIANT_RollUdate(UDATE *lpUd)
{
static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ short iYear, iMonth, iDay, iHour, iMinute, iSecond;
- TRACE("Raw date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
- lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
+ /* interpret values signed */
+ iYear = lpUd->st.wYear;
+ iMonth = lpUd->st.wMonth;
+ iDay = lpUd->st.wDay;
+ iHour = lpUd->st.wHour;
+ iMinute = lpUd->st.wMinute;
+ iSecond = lpUd->st.wSecond;
- /* Years < 100 are treated as 1900 + year */
- if (lpUd->st.wYear < 100)
- lpUd->st.wYear += 1900;
+ TRACE("Raw date: %d/%d/%d %d:%d:%d\n", iDay, iMonth,
+ iYear, iHour, iMinute, iSecond);
- if (!lpUd->st.wMonth)
+ if (iYear > 9999 || iYear < -9999)
+ return E_INVALIDARG; /* Invalid value */
+ /* Years < 100 are treated as 1900 + year */
+ if (iYear > 0 && iYear < 100)
+ iYear += 1900;
+
+ iMinute += iSecond / 60;
+ iSecond = iSecond % 60;
+ iHour += iMinute / 60;
+ iMinute = iMinute % 60;
+ iDay += iHour / 24;
+ iHour = iHour % 24;
+ iYear += iMonth / 12;
+ iMonth = iMonth % 12;
+ if (iMonth<=0) {iMonth+=12; iYear--;}
+ while (iDay > days[iMonth])
{
- /* Roll back to December of the previous year */
- lpUd->st.wMonth = 12;
- lpUd->st.wYear--;
+ if (iMonth == 2 && IsLeapYear(iYear))
+ iDay -= 29;
+ else
+ iDay -= days[iMonth];
+ iMonth++;
+ iYear += iMonth / 12;
+ iMonth = iMonth % 12;
}
- else while (lpUd->st.wMonth > 12)
+ while (iDay <= 0)
{
- /* Roll forward the correct number of months */
- lpUd->st.wYear++;
- lpUd->st.wMonth -= 12;
- }
-
- if (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 ||
- lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59)
- return E_INVALIDARG; /* Invalid values */
-
- if (!lpUd->st.wDay)
- {
- /* Roll back the date one day */
- if (lpUd->st.wMonth == 1)
- {
- /* Roll back to December 31 of the previous year */
- lpUd->st.wDay = 31;
- lpUd->st.wMonth = 12;
- lpUd->st.wYear--;
- }
+ iMonth--;
+ if (iMonth<=0) {iMonth+=12; iYear--;}
+ if (iMonth == 2 && IsLeapYear(iYear))
+ iDay += 29;
else
- {
- lpUd->st.wMonth--; /* Previous month */
- if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
- lpUd->st.wDay = 29; /* February has 29 days on leap years */
- else
- lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */
- }
+ iDay += days[iMonth];
}
- else if (lpUd->st.wDay > 28)
- {
- int rollForward = 0;
- /* Possibly need to roll the date forward */
- if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
- rollForward = lpUd->st.wDay - 29; /* February has 29 days on leap years */
- else
- rollForward = lpUd->st.wDay - days[lpUd->st.wMonth];
+ if (iSecond<0){iSecond+=60; iMinute--;}
+ if (iMinute<0){iMinute+=60; iHour--;}
+ if (iHour<0) {iHour+=24; iDay--;}
+ if (iYear<=0) iYear+=2000;
+
+ lpUd->st.wYear = iYear;
+ lpUd->st.wMonth = iMonth;
+ lpUd->st.wDay = iDay;
+ lpUd->st.wHour = iHour;
+ lpUd->st.wMinute = iMinute;
+ lpUd->st.wSecond = iSecond;
- if (rollForward > 0)
- {
- lpUd->st.wDay = rollForward;
- lpUd->st.wMonth++;
- if (lpUd->st.wMonth > 12)
- {
- lpUd->st.wMonth = 1; /* Roll forward into January of the next year */
- lpUd->st.wYear++;
- }
- }
- }
TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
return S_OK;
ud.st.wMinute = DOS_MINUTE(wDosTime);
ud.st.wSecond = DOS_SECOND(wDosTime);
ud.st.wDayOfWeek = ud.st.wMilliseconds = 0;
+ if (ud.st.wHour > 23 || ud.st.wMinute > 59 || ud.st.wSecond > 59)
+ return FALSE; /* Invalid values in Dos*/
return VarDateFromUdate(&ud, 0, pDateOut) == S_OK;
}
dateVal += ud.st.wHour / 24.0;
dateVal += ud.st.wMinute / 1440.0;
dateVal += ud.st.wSecond / 86400.0;
- dateVal += ud.st.wMilliseconds / 86400000.0;
TRACE("Returning %g\n", dateVal);
*pDateOut = dateVal;
if (FAILED(rc))
return rc;
rc = VarBstrCmp(V_BSTR(bstrv), V_BSTR(&rv), lcid, flags);
+ VariantClear(&rv);
} else if (V_BSTR(bstrv) && *V_BSTR(bstrv)) {
/* Non NULL nor empty BSTR */
/* If the BSTR is not a number the BSTR is greater */
/* Numeric comparison, will be handled below.
VARCMP_NULL used only to break out. */
rc = VARCMP_NULL;
- VariantClear(&lv);
- VariantClear(&rv);
+ VariantClear(&lv);
+ VariantClear(&rv);
} else
/* Empty or NULL BSTR */
rc = VARCMP_GT;
BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *);
+HRESULT VARIANT_ClearInd(VARIANTARG *);
*/
HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
{
- return VarCyFromR8(bIn, pCyOut);
+ pCyOut->int64 = (ULONG64)bIn * CY_MULTIPLIER;
+ return S_OK;
}
/************************************************************************
*/
HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut)
{
- return VarCyFromR8(sIn, pCyOut);
+ pCyOut->int64 = (LONG64)sIn * CY_MULTIPLIER;
+ return S_OK;
}
/************************************************************************
*/
HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut)
{
- return VarCyFromR8(lIn, pCyOut);
+ pCyOut->int64 = (LONG64)lIn * CY_MULTIPLIER;
+ return S_OK;
}
/************************************************************************
*/
HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut)
{
- return VarCyFromR8(boolIn, pCyOut);
+ pCyOut->int64 = (LONG64)boolIn * CY_MULTIPLIER;
+ return S_OK;
}
/************************************************************************
*/
HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut)
{
- return VarCyFromR8(cIn, pCyOut);
+ pCyOut->int64 = (LONG64)cIn * CY_MULTIPLIER;
+ return S_OK;
}
/************************************************************************
*/
HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut)
{
- return VarCyFromR8(usIn, pCyOut);
+ pCyOut->int64 = (ULONG64)usIn * CY_MULTIPLIER;
+ return S_OK;
}
/************************************************************************
*/
HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pCyOut)
{
- return VarCyFromR8(ulIn, pCyOut);
+ pCyOut->int64 = (ULONG64)ulIn * CY_MULTIPLIER;
+ return S_OK;
}
/************************************************************************
*/
HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut)
{
- return VarCyFromR8(ullIn, pCyOut);
+ if (ullIn >= (I8_MAX/CY_MULTIPLIER)) return DISP_E_OVERFLOW;
+ pCyOut->int64 = ullIn * CY_MULTIPLIER;
+ return S_OK;
}
/************************************************************************
break;
case 0x3: /* TTT TTTDD TTTDDD */
+ if (iDate && dp.dwCount == 3)
+ {
+ /* DDD */
+ if ((dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)) ||
+ (dp.dwFlags[2] & (DP_AM|DP_PM)))
+ hRet = DISP_E_TYPEMISMATCH;
+ break;
+ }
if (dp.dwCount > 4 &&
((dp.dwFlags[3] & (DP_AM|DP_PM)) || (dp.dwFlags[4] & (DP_AM|DP_PM)) ||
(dp.dwFlags[5] & (DP_AM|DP_PM))))
dp.dwCount -= 3;
break;
+ case 0x1B: /* localized DDDTTT */
+ if (!iDate)
+ {
+ hRet = DISP_E_TYPEMISMATCH;
+ break;
+ }
+ /* .. fall through .. */
case 0x18: /* DDDTTT */
if ((dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)) ||
(dp.dwFlags[2] & (DP_AM|DP_PM)))
reactos/dll/win32/odbccp32 # Autosync
reactos/dll/win32/ole32 # Autosync
reactos/dll/win32/oleacc # Autosync
-reactos/dll/win32/oleaut32 # Autosync ??
+reactos/dll/win32/oleaut32 # Autosync
reactos/dll/win32/olecli32 # Autosync
reactos/dll/win32/oledlg # Autosync
reactos/dll/win32/olepro32 # Autosync