[OLEAUT32]

- Sync to Wine-1.1.40.

svn path=/trunk/; revision=46093
This commit is contained in:
Aleksey Bragin 2010-03-11 10:28:34 +00:00
parent 0b49f57301
commit 3b52f6a934
43 changed files with 1896 additions and 928 deletions

View file

@ -130,10 +130,14 @@ HRESULT WINAPI DispGetParam(
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;
@ -141,10 +145,27 @@ HRESULT WINAPI DispGetParam(
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;
}
@ -234,8 +255,8 @@ static HRESULT WINAPI StdDispatch_QueryInterface(
IsEqualIID(riid, &IID_IUnknown))
{
*ppvObject = This;
IUnknown_AddRef((LPUNKNOWN)*ppvObject);
return S_OK;
IUnknown_AddRef((LPUNKNOWN)*ppvObject);
return S_OK;
}
return E_NOINTERFACE;
}

View file

@ -294,19 +294,17 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
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
@ -696,6 +694,7 @@ HRESULT WINAPI OleTranslateColor(
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 *);
@ -728,7 +727,7 @@ static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface, IUnk
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);
@ -746,7 +745,7 @@ static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface, REFII
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);
@ -790,11 +789,6 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
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);
@ -805,6 +799,12 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *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);
}

View file

@ -9,7 +9,7 @@
<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"/>
@ -54,7 +54,7 @@
</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"/>

View file

@ -26,7 +26,6 @@
#include "oleaut32_Bg.rc"
#include "oleaut32_Da.rc"
#include "oleaut32_De.rc"
#include "oleaut32_El.rc"
#include "oleaut32_En.rc"
#include "oleaut32_Eo.rc"
@ -41,14 +40,17 @@
#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:

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,10 @@
* 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

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_GREEK, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -0,0 +1,36 @@
/*
* 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"
}

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
STRINGTABLE DISCARDABLE

View file

@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE

View file

@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
#pragma code_page(65001)
@ -30,5 +32,3 @@ STRINGTABLE DISCARDABLE
IDS_ON "Activat"
IDS_OFF "Dezactivat"
}
#pragma code_page(default)

View file

@ -18,14 +18,19 @@
* 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 "Выключено"
}

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
#pragma code_page(65001)
LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
@ -31,5 +33,3 @@ STRINGTABLE DISCARDABLE
IDS_ON "Vključeno"
IDS_OFF "Izključeno"
}
#pragma code_page(default)

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_THAI, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE

View file

@ -1,7 +1,9 @@
/*
* 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
@ -15,17 +17,22 @@
*
* 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 "Вимкнено"
}

View file

@ -18,6 +18,8 @@
* 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)
@ -44,5 +46,3 @@ STRINGTABLE DISCARDABLE
IDS_ON "開"
IDS_OFF "關"
}
#pragma code_page(default)

View file

@ -1,74 +0,0 @@
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 "‚Í‚¢"
+ IDS_NO "‚¢‚¢‚¦"
+ IDS_ON "ƒIƒ“"
+ IDS_OFF "ƒIƒt"
+}
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:

View file

@ -53,6 +53,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
#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
@ -62,10 +63,13 @@ typedef struct _HFONTItem
{
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;
/* Contain the font associated with this object. */
/* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
LONG total_refs;
/* The font associated with this object. */
HFONT gdiFont;
} HFONTItem, *PHFONTItem;
@ -88,6 +92,28 @@ static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug =
};
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);
@ -95,6 +121,123 @@ static void HFONTItem_Delete(PHFONTItem item)
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
*/
@ -128,7 +271,7 @@ struct OLEFontImpl
* Contain the font associated with this object.
*/
HFONT gdiFont;
BOOL dirty;
/*
* Size ratio
*/
@ -277,7 +420,8 @@ static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
CONNECTDATA CD;
HRESULT hres;
this->gdiFont = 0;
this->dirty = TRUE;
hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum);
if (SUCCEEDED(hres))
{
@ -402,7 +546,6 @@ static ULONG WINAPI OLEFontImpl_Release(
{
OLEFontImpl *this = (OLEFontImpl *)iface;
ULONG ret;
PHFONTItem ptr, next;
TRACE("(%p)->(ref=%d)\n", this, this->ref);
/* Decrease the reference count for current interface */
@ -412,13 +555,21 @@ static ULONG WINAPI OLEFontImpl_Release(
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);
}
@ -426,6 +577,109 @@ static ULONG WINAPI OLEFontImpl_Release(
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)
*
@ -443,6 +697,8 @@ static HRESULT WINAPI OLEFontImpl_get_Name(
if (pname==0)
return E_POINTER;
if(this->dirty) realize_font(this);
if (this->description.lpstrName!=0)
*pname = SysAllocString(this->description.lpstrName);
else
@ -463,6 +719,9 @@ static HRESULT WINAPI OLEFontImpl_put_Name(
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(),
@ -504,6 +763,8 @@ static HRESULT WINAPI OLEFontImpl_get_Size(
if (psize==0)
return E_POINTER;
if(this->dirty) realize_font(this);
psize->s.Hi = 0;
psize->s.Lo = this->description.cySize.s.Lo;
@ -545,6 +806,8 @@ static HRESULT WINAPI OLEFontImpl_get_Bold(
if (pbold==0)
return E_POINTER;
if(this->dirty) realize_font(this);
*pbold = this->description.sWeight > 550;
return S_OK;
@ -584,6 +847,8 @@ static HRESULT WINAPI OLEFontImpl_get_Italic(
if (pitalic==0)
return E_POINTER;
if(this->dirty) realize_font(this);
*pitalic = this->description.fItalic;
return S_OK;
@ -625,6 +890,8 @@ static HRESULT WINAPI OLEFontImpl_get_Underline(
if (punderline==0)
return E_POINTER;
if(this->dirty) realize_font(this);
*punderline = this->description.fUnderline;
return S_OK;
@ -666,6 +933,8 @@ static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
if (pstrikethrough==0)
return E_POINTER;
if(this->dirty) realize_font(this);
*pstrikethrough = this->description.fStrikethrough;
return S_OK;
@ -707,6 +976,8 @@ static HRESULT WINAPI OLEFontImpl_get_Weight(
if (pweight==0)
return E_POINTER;
if(this->dirty) realize_font(this);
*pweight = this->description.sWeight;
return S_OK;
@ -748,6 +1019,8 @@ static HRESULT WINAPI OLEFontImpl_get_Charset(
if (pcharset==0)
return E_POINTER;
if(this->dirty) realize_font(this);
*pcharset = this->description.sCharset;
return S_OK;
@ -785,53 +1058,7 @@ static HRESULT WINAPI OLEFontImpl_get_hFont(
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);
@ -848,12 +1075,8 @@ static HRESULT WINAPI OLEFontImpl_Clone(
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)
@ -879,36 +1102,12 @@ static HRESULT WINAPI OLEFontImpl_Clone(
(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));
/* Increment internal ref in hfont item list */
if(newObject->gdiFont) inc_int_ref(newObject->gdiFont);
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);
/* 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;
@ -1021,29 +1220,13 @@ static HRESULT WINAPI OLEFontImpl_AddRefHfont(
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);
}
/************************************************************************
@ -1055,34 +1238,13 @@ static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
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)
{
/* 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);
return hres;
return dec_ext_ref(hfont);
}
/************************************************************************
@ -1675,7 +1837,7 @@ static HRESULT WINAPI OLEFontImpl_Load(
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;
@ -2247,6 +2409,7 @@ static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
* Initializing all the other members.
*/
newObject->gdiFont = 0;
newObject->dirty = TRUE;
newObject->cyLogical = 72L;
newObject->cyHimetric = 2540L;
newObject->pPropertyNotifyCP = NULL;
@ -2280,9 +2443,6 @@ static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
if (fontDesc->gdiFont!=0)
DeleteObject(fontDesc->gdiFont);
if (fontDesc->pPropertyNotifyCP)
IConnectionPoint_Release(fontDesc->pPropertyNotifyCP);
if (fontDesc->pFontEventsCP)

View file

@ -684,7 +684,7 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
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:

View file

@ -21,6 +21,7 @@
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
@ -377,6 +378,32 @@ static LONG register_key_defvalueA(
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
*/
@ -386,9 +413,6 @@ static GUID const CLSID_RecordInfo = {
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",
@ -456,12 +480,6 @@ static struct regsvr_coclass const coclass_list[] = {
"Obsolete Font",
"OldFont"
},
{ &CLSID_PSFactoryBuffer,
"PSFactoryBuffer",
NULL,
"oleaut32.dll",
"Both"
},
{ NULL } /* list terminator */
};
@ -470,7 +488,6 @@ static struct regsvr_coclass const coclass_list[] = {
*/
#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[] = {
@ -481,43 +498,10 @@ 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 */
};
@ -538,6 +522,13 @@ HRESULT WINAPI DllRegisterServer(void)
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;
}

View file

@ -615,8 +615,6 @@ serialize_param(
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:
@ -652,56 +650,23 @@ serialize_param(
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)
@ -709,25 +674,20 @@ serialize_param(
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;
@ -888,12 +848,14 @@ serialize_param(
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: {
@ -905,6 +867,11 @@ serialize_param(
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:
@ -934,34 +901,15 @@ deserialize_param(
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:
@ -1006,76 +954,14 @@ deserialize_param(
}
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;
}
@ -1247,6 +1133,7 @@ deserialize_param(
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,
@ -1254,7 +1141,7 @@ deserialize_param(
debugout,
alloc,
&adesc->tdescElem,
(DWORD*)((LPBYTE)(arg)+i*_xsize(&adesc->tdescElem, tinfo)),
(DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)),
buf
);
return S_OK;
@ -2037,6 +1924,7 @@ static HRESULT WINAPI
TMStubImpl_Invoke(
LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
{
#ifdef __i386__
int i;
const FUNCDESC *fdesc;
TMStubImpl *This = (TMStubImpl *)iface;
@ -2103,7 +1991,7 @@ TMStubImpl_Invoke(
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;
@ -2201,6 +2089,10 @@ exit:
TRACE("returning\n");
return hres;
#else
FIXME( "not implemented on non-i386\n" );
return E_FAIL;
#endif
}
static LPRPCSTUBBUFFER WINAPI

View file

@ -552,7 +552,9 @@ HRESULT WINAPI RegisterTypeLib(
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)
@ -560,8 +562,6 @@ HRESULT WINAPI RegisterTypeLib(
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;
@ -1013,7 +1013,7 @@ typedef struct tagTLBFuncDesc
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;
@ -1048,7 +1048,7 @@ typedef struct tagITypeInfoImpl
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; */
@ -1085,6 +1085,7 @@ static const ITypeInfo2Vtbl tinfvt;
static const ITypeCompVtbl tcompvt;
static ITypeInfo2 * ITypeInfo_Constructor(void);
static void ITypeInfo_fnDestroy(ITypeInfoImpl *This);
typedef struct tagTLBContext
{
@ -1898,8 +1899,8 @@ MSFT_DoFuncs(TLBContext* pcx,
{
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
@ -2492,7 +2493,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
/* 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)
@ -2523,7 +2524,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
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++)
@ -2947,7 +2948,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
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];
@ -2991,6 +2992,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
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;
@ -3676,6 +3678,9 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
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 */
@ -3935,6 +3940,9 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
(*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)
@ -4083,6 +4091,7 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
TLBRefType *ref_type;
void *cursor2;
int i;
ITypeInfoImpl *pTI, *pTINext;
/* remove cache entry */
if(This->path)
@ -4139,8 +4148,11 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
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;
}
@ -4835,8 +4847,29 @@ static HRESULT WINAPI ITypeLibComp_fnBindType(
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 =
@ -4860,7 +4893,7 @@ static ITypeInfo2 * ITypeInfo_Constructor(void)
{
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;
@ -4902,12 +4935,78 @@ static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
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;
}
static void ITypeInfo_fnDestroy(ITypeInfoImpl *This)
{
TLBFuncDesc *pFInfo, *pFInfoNext;
TLBVarDesc *pVInfo, *pVInfoNext;
TLBImplType *pImpl, *pImplNext;
TRACE("destroying ITypeInfo(%p)\n",This);
SysFreeString(This->Name);
This->Name = NULL;
SysFreeString(This->DocString);
This->DocString = NULL;
SysFreeString(This->DllName);
This->DllName = 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);
HeapFree(GetProcessHeap(), 0, This);
}
/* ITypeInfo::Release
*/
static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
@ -4917,82 +5016,15 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
TRACE("(%p)->(%u)\n",This, ref);
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;
TRACE("destroying ITypeInfo(%p)\n",This);
if (This->no_free_data)
goto finish_free;
SysFreeString(This->Name);
This->Name = NULL;
SysFreeString(This->DocString);
This->DocString = NULL;
SysFreeString(This->DllName);
This->DllName = 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 (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);
finish_free:
if (This->next)
{
ITypeInfo_Release((ITypeInfo*)This->next);
}
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;
}
@ -5345,7 +5377,7 @@ static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue);
if (FAILED(hr))
{
SysFreeString((BSTR)dest_ptr);
SysFreeString((BSTR)dest);
return hr;
}
}
@ -5476,8 +5508,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
*/
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;
}
@ -5600,6 +5631,41 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
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
@ -5618,106 +5684,8 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
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);
@ -5754,6 +5722,7 @@ static int _dispargsize(VARTYPE vt)
return 1;
}
}
#endif /* __i386__ */
static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
{
@ -5933,6 +5902,7 @@ DispCallFunc(
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;
@ -5988,9 +5958,13 @@ DispCallFunc(
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 \
@ -6177,7 +6151,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
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];
@ -6215,8 +6190,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
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];
}
@ -6299,6 +6276,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
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;
@ -6317,33 +6295,23 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
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) &&
@ -6382,6 +6350,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
if (wParamFlags & PARAMFLAG_FHASDEFAULT)
VariantClear(&rgvarg[i]);
}
VariantClear(&missing_arg[i]);
}
if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
@ -6601,7 +6571,7 @@ static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid
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)
@ -6689,20 +6659,18 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
*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);

View file

@ -155,6 +155,7 @@ typedef struct tagMSFT_TypeInfoBase {
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;
@ -413,7 +414,7 @@ typedef struct {
/*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*/

File diff suppressed because it is too large Load diff

View file

@ -256,20 +256,21 @@ static unsigned int get_type_alignment(ULONG *pFlags, VARTYPE vt)
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)
@ -322,6 +323,12 @@ static unsigned char* interface_variant_marshal(const ULONG *pFlags, unsigned ch
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.
@ -378,6 +385,12 @@ static unsigned char *interface_variant_unmarshal(const ULONG *pFlags, unsigned
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;
@ -552,14 +565,29 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
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;
@ -748,6 +776,26 @@ static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa)
}
}
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;
@ -853,13 +901,15 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf
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);
@ -868,7 +918,6 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf
*(ULONG *)Buffer = (USHORT)psa->cLocks | (vt << 16);
Buffer += sizeof(ULONG);
sftype = SAFEARRAY_GetUnionType(psa);
*(ULONG *)Buffer = sftype;
Buffer += sizeof(ULONG);
@ -1028,7 +1077,7 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
(*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
@ -1180,6 +1229,8 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
if (V_ISBYREF(arg)) {
rgVarRefIdx[cVarRef] = u;
VariantInit(&rgVarRef[cVarRef]);
VariantCopy(&rgVarRef[cVarRef], arg);
VariantClear(arg);
cVarRef++;
}
}
@ -1265,6 +1316,12 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
}
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,
@ -1277,14 +1334,10 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
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]);
}
}

View file

@ -1264,13 +1264,11 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
/* 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;
}
}
@ -1285,6 +1283,14 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
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 */
@ -1313,10 +1319,10 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
}
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);
@ -1957,7 +1963,7 @@ static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat,
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));

View file

@ -578,6 +578,66 @@ void WINAPI VariantInit(VARIANTARG* pVarg)
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]
*
@ -1069,71 +1129,66 @@ static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day
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;
TRACE("Raw date: %d/%d/%d %d:%d:%d\n", iDay, iMonth,
iYear, iHour, iMinute, iSecond);
if (iYear > 9999 || iYear < -9999)
return E_INVALIDARG; /* Invalid value */
/* Years < 100 are treated as 1900 + year */
if (lpUd->st.wYear < 100)
lpUd->st.wYear += 1900;
if (iYear > 0 && iYear < 100)
iYear += 1900;
if (!lpUd->st.wMonth)
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--;
}
else while (lpUd->st.wMonth > 12)
{
/* 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--;
}
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];
iMonth++;
iYear += iMonth / 12;
iMonth = iMonth % 12;
}
else if (lpUd->st.wDay > 28)
while (iDay <= 0)
{
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 */
iMonth--;
if (iMonth<=0) {iMonth+=12; iYear--;}
if (iMonth == 2 && IsLeapYear(iYear))
iDay += 29;
else
rollForward = lpUd->st.wDay - days[lpUd->st.wMonth];
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++;
}
}
iDay += days[iMonth];
}
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;
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;
@ -1190,6 +1245,8 @@ INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime,
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;
}
@ -1328,7 +1385,6 @@ HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DAT
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;
@ -2795,6 +2851,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
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 */
@ -2810,8 +2867,8 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
/* 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;

View file

@ -126,3 +126,4 @@ typedef struct tagVARIANT_NUMBER_CHARS
BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *);
HRESULT VARIANT_ClearInd(VARIANTARG *);

View file

@ -3420,7 +3420,8 @@ static const int CY_Divisors[5] = { CY_MULTIPLIER/10000, CY_MULTIPLIER/1000,
*/
HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
{
return VarCyFromR8(bIn, pCyOut);
pCyOut->int64 = (ULONG64)bIn * CY_MULTIPLIER;
return S_OK;
}
/************************************************************************
@ -3440,7 +3441,8 @@ HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
*/
HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut)
{
return VarCyFromR8(sIn, pCyOut);
pCyOut->int64 = (LONG64)sIn * CY_MULTIPLIER;
return S_OK;
}
/************************************************************************
@ -3460,7 +3462,8 @@ HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut)
*/
HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut)
{
return VarCyFromR8(lIn, pCyOut);
pCyOut->int64 = (LONG64)lIn * CY_MULTIPLIER;
return S_OK;
}
/************************************************************************
@ -3617,7 +3620,8 @@ HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut)
*/
HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut)
{
return VarCyFromR8(boolIn, pCyOut);
pCyOut->int64 = (LONG64)boolIn * CY_MULTIPLIER;
return S_OK;
}
/************************************************************************
@ -3637,7 +3641,8 @@ HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut)
*/
HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut)
{
return VarCyFromR8(cIn, pCyOut);
pCyOut->int64 = (LONG64)cIn * CY_MULTIPLIER;
return S_OK;
}
/************************************************************************
@ -3657,7 +3662,8 @@ HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut)
*/
HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut)
{
return VarCyFromR8(usIn, pCyOut);
pCyOut->int64 = (ULONG64)usIn * CY_MULTIPLIER;
return S_OK;
}
/************************************************************************
@ -3677,7 +3683,8 @@ HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut)
*/
HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pCyOut)
{
return VarCyFromR8(ulIn, pCyOut);
pCyOut->int64 = (ULONG64)ulIn * CY_MULTIPLIER;
return S_OK;
}
/************************************************************************
@ -3757,7 +3764,9 @@ HRESULT WINAPI VarCyFromI8(LONG64 llIn, CY* pCyOut)
*/
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;
}
/************************************************************************
@ -7598,6 +7607,14 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
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))))
@ -7690,6 +7707,13 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
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)))

View file

@ -123,7 +123,7 @@ reactos/dll/win32/odbc32 # Out of sync. Depends on port of Linux ODBC.
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