From 3b52f6a934a6d084b1c78fb65adf65e161721bd8 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 11 Mar 2010 10:28:34 +0000 Subject: [PATCH] [OLEAUT32] - Sync to Wine-1.1.40. svn path=/trunk/; revision=46093 --- reactos/dll/win32/oleaut32/dispatch.c | 31 +- reactos/dll/win32/oleaut32/oleaut.c | 32 +- reactos/dll/win32/oleaut32/oleaut32.rbuild | 4 +- reactos/dll/win32/oleaut32/oleaut32.rc | 12 +- reactos/dll/win32/oleaut32/oleaut32_Bg.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Cz.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Da.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_De.rc | 4 + reactos/dll/win32/oleaut32/oleaut32_El.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_En.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Eo.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Es.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Fr.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Hu.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_It.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Ko.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Lt.rc | 36 + reactos/dll/win32/oleaut32/oleaut32_Nl.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_No.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Pl.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Pt.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Ro.rc | 4 +- reactos/dll/win32/oleaut32/oleaut32_Ru.rc | 17 +- reactos/dll/win32/oleaut32/oleaut32_Si.rc | 4 +- reactos/dll/win32/oleaut32/oleaut32_Sv.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Th.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Tr.rc | 2 + reactos/dll/win32/oleaut32/oleaut32_Uk.rc | 23 +- reactos/dll/win32/oleaut32/oleaut32_Zh.rc | 4 +- reactos/dll/win32/oleaut32/oleaut32_ros.diff | 74 -- reactos/dll/win32/oleaut32/olefont.c | 432 +++++--- reactos/dll/win32/oleaut32/olepicture.c | 2 +- reactos/dll/win32/oleaut32/regsvr.c | 85 +- reactos/dll/win32/oleaut32/tmarshal.c | 220 +--- reactos/dll/win32/oleaut32/typelib.c | 422 ++++--- reactos/dll/win32/oleaut32/typelib.h | 3 +- reactos/dll/win32/oleaut32/typelib2.c | 1040 +++++++++++++++--- reactos/dll/win32/oleaut32/usrmarshal.c | 101 +- reactos/dll/win32/oleaut32/varformat.c | 22 +- reactos/dll/win32/oleaut32/variant.c | 173 ++- reactos/dll/win32/oleaut32/variant.h | 1 + reactos/dll/win32/oleaut32/vartype.c | 40 +- reactos/media/doc/README.WINE | 2 +- 43 files changed, 1896 insertions(+), 928 deletions(-) create mode 100644 reactos/dll/win32/oleaut32/oleaut32_Lt.rc delete mode 100644 reactos/dll/win32/oleaut32/oleaut32_ros.diff diff --git a/reactos/dll/win32/oleaut32/dispatch.c b/reactos/dll/win32/oleaut32/dispatch.c index 2fd8bb42d00..ed3fad47019 100644 --- a/reactos/dll/win32/oleaut32/dispatch.c +++ b/reactos/dll/win32/oleaut32/dispatch.c @@ -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; poscNamedArgs; 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; } diff --git a/reactos/dll/win32/oleaut32/oleaut.c b/reactos/dll/win32/oleaut32/oleaut.c index 0eaddb15b6d..89e1ab9dc2c 100644 --- a/reactos/dll/win32/oleaut32/oleaut.c +++ b/reactos/dll/win32/oleaut32/oleaut.c @@ -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); } diff --git a/reactos/dll/win32/oleaut32/oleaut32.rbuild b/reactos/dll/win32/oleaut32/oleaut32.rbuild index 8b117b93ace..1873cade868 100644 --- a/reactos/dll/win32/oleaut32/oleaut32.rbuild +++ b/reactos/dll/win32/oleaut32/oleaut32.rbuild @@ -9,7 +9,7 @@ include/reactos/wine 0x600 - CLSID_PSDispatch + {0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}} @@ -54,7 +54,7 @@ - CLSID_PSDispatch + {0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}} diff --git a/reactos/dll/win32/oleaut32/oleaut32.rc b/reactos/dll/win32/oleaut32/oleaut32.rc index e05528ee698..847da8beff4 100644 --- a/reactos/dll/win32/oleaut32/oleaut32.rc +++ b/reactos/dll/win32/oleaut32/oleaut32.rc @@ -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: diff --git a/reactos/dll/win32/oleaut32/oleaut32_Bg.rc b/reactos/dll/win32/oleaut32/oleaut32_Bg.rc index 7e930f41020..7f0180b2b09 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Bg.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Bg.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Cz.rc b/reactos/dll/win32/oleaut32/oleaut32_Cz.rc index 7075b43cc0e..48be0b70a82 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Cz.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Cz.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Da.rc b/reactos/dll/win32/oleaut32/oleaut32_Da.rc index 6f1dcbcad91..e28922fa1bf 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Da.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Da.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_De.rc b/reactos/dll/win32/oleaut32/oleaut32_De.rc index 9fb786cfca0..1dbee3ee8c7 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_De.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_De.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_El.rc b/reactos/dll/win32/oleaut32/oleaut32_El.rc index 145c1a12959..a0337950262 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_El.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_El.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_En.rc b/reactos/dll/win32/oleaut32/oleaut32_En.rc index e56eb11d6e3..6a98642e7ca 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_En.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_En.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Eo.rc b/reactos/dll/win32/oleaut32/oleaut32_Eo.rc index c00e2fd4f44..ae67139109e 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Eo.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Eo.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Es.rc b/reactos/dll/win32/oleaut32/oleaut32_Es.rc index 5cc25ca49d5..5c187db364f 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Es.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Es.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Fr.rc b/reactos/dll/win32/oleaut32/oleaut32_Fr.rc index 40e392ee162..d6136ef8cda 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Fr.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Fr.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Hu.rc b/reactos/dll/win32/oleaut32/oleaut32_Hu.rc index 35283c8314a..ec3b9827e3f 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Hu.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Hu.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_It.rc b/reactos/dll/win32/oleaut32/oleaut32_It.rc index 0dee161a217..69fa31a34a7 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_It.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_It.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Ko.rc b/reactos/dll/win32/oleaut32/oleaut32_Ko.rc index 0134c7a54b9..541380543a5 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Ko.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Ko.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Lt.rc b/reactos/dll/win32/oleaut32/oleaut32_Lt.rc new file mode 100644 index 00000000000..c568d93cb78 --- /dev/null +++ b/reactos/dll/win32/oleaut32/oleaut32_Lt.rc @@ -0,0 +1,36 @@ +/* + * Lithuanian resources for oleaut32 + * + * Copyright 2009 Aurimas Fišeras + * + * 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" +} diff --git a/reactos/dll/win32/oleaut32/oleaut32_Nl.rc b/reactos/dll/win32/oleaut32/oleaut32_Nl.rc index 6affb2d638c..e2ae3dea380 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Nl.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Nl.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_No.rc b/reactos/dll/win32/oleaut32/oleaut32_No.rc index 7ca883c350d..1f99f7bbe56 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_No.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_No.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Pl.rc b/reactos/dll/win32/oleaut32/oleaut32_Pl.rc index 8c250cbbb9f..7d34796fd0b 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Pl.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Pl.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Pt.rc b/reactos/dll/win32/oleaut32/oleaut32_Pt.rc index 1cbd389209a..de008bbd0f9 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Pt.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Pt.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Ro.rc b/reactos/dll/win32/oleaut32/oleaut32_Ro.rc index 52421a8cca2..3a37a69ddef 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Ro.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Ro.rc @@ -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) diff --git a/reactos/dll/win32/oleaut32/oleaut32_Ru.rc b/reactos/dll/win32/oleaut32/oleaut32_Ru.rc index 194ca9e1a8e..e7c31073e33 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Ru.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Ru.rc @@ -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 "Выключено" } diff --git a/reactos/dll/win32/oleaut32/oleaut32_Si.rc b/reactos/dll/win32/oleaut32/oleaut32_Si.rc index 365d877045c..32a80adefb6 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Si.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Si.rc @@ -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) diff --git a/reactos/dll/win32/oleaut32/oleaut32_Sv.rc b/reactos/dll/win32/oleaut32/oleaut32_Sv.rc index 387b25eb0c4..4362a068bab 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Sv.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Sv.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Th.rc b/reactos/dll/win32/oleaut32/oleaut32_Th.rc index 22f01f74ee3..8fcf212a969 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Th.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Th.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Tr.rc b/reactos/dll/win32/oleaut32/oleaut32_Tr.rc index cc2f3e6f878..08d841a92a4 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Tr.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Tr.rc @@ -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 diff --git a/reactos/dll/win32/oleaut32/oleaut32_Uk.rc b/reactos/dll/win32/oleaut32/oleaut32_Uk.rc index 557b4ec3284..d51b06eb72c 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Uk.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Uk.rc @@ -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 "Вимкнено" } diff --git a/reactos/dll/win32/oleaut32/oleaut32_Zh.rc b/reactos/dll/win32/oleaut32/oleaut32_Zh.rc index 320c40ff5dd..bbb9e06433e 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_Zh.rc +++ b/reactos/dll/win32/oleaut32/oleaut32_Zh.rc @@ -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) diff --git a/reactos/dll/win32/oleaut32/oleaut32_ros.diff b/reactos/dll/win32/oleaut32/oleaut32_ros.diff deleted file mode 100644 index 81c42a6eb98..00000000000 --- a/reactos/dll/win32/oleaut32/oleaut32_ros.diff +++ /dev/null @@ -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 "It" -+} -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: diff --git a/reactos/dll/win32/oleaut32/olefont.c b/reactos/dll/win32/oleaut32/olefont.c index a9b2c047abf..df7de87bfc2 100644 --- a/reactos/dll/win32/oleaut32/olefont.c +++ b/reactos/dll/win32/oleaut32/olefont.c @@ -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) diff --git a/reactos/dll/win32/oleaut32/olepicture.c b/reactos/dll/win32/oleaut32/olepicture.c index 052aa9a37f4..7a5bc29a4e5 100644 --- a/reactos/dll/win32/oleaut32/olepicture.c +++ b/reactos/dll/win32/oleaut32/olepicture.c @@ -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: diff --git a/reactos/dll/win32/oleaut32/regsvr.c b/reactos/dll/win32/oleaut32/regsvr.c index 3c5fabc0b20..12f64faa516 100644 --- a/reactos/dll/win32/oleaut32/regsvr.c +++ b/reactos/dll/win32/oleaut32/regsvr.c @@ -21,6 +21,7 @@ #include #include +#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; } diff --git a/reactos/dll/win32/oleaut32/tmarshal.c b/reactos/dll/win32/oleaut32/tmarshal.c index 72358503f8d..26babdbcfde 100644 --- a/reactos/dll/win32/oleaut32/tmarshal.c +++ b/reactos/dll/win32/oleaut32/tmarshal.c @@ -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)) : ""); - 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)(""); } - 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;itdescElem, (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 && (ibase + 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)("\n"); - return S_OK; - case VT_NULL: - if (debugout) TRACE_(olerelay)("\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)(""); - } 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)(""); - } 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;icDims;i++) arrsize *= adesc->rgbounds[i].cElements; + *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize); for (i=0;itdescElem, - (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;icParams;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 diff --git a/reactos/dll/win32/oleaut32/typelib.c b/reactos/dll/win32/oleaut32/typelib.c index 887c6bebc9e..445eac5c51e 100644 --- a/reactos/dll/win32/oleaut32/typelib.c +++ b/reactos/dll/win32/oleaut32/typelib.c @@ -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); diff --git a/reactos/dll/win32/oleaut32/typelib.h b/reactos/dll/win32/oleaut32/typelib.h index 1fe8ecf7619..058c6a2db8c 100644 --- a/reactos/dll/win32/oleaut32/typelib.h +++ b/reactos/dll/win32/oleaut32/typelib.h @@ -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*/ diff --git a/reactos/dll/win32/oleaut32/typelib2.c b/reactos/dll/win32/oleaut32/typelib2.c index 0f641d4103c..4544317a512 100644 --- a/reactos/dll/win32/oleaut32/typelib2.c +++ b/reactos/dll/win32/oleaut32/typelib2.c @@ -43,6 +43,7 @@ #include "windef.h" #include "winbase.h" #include "winnls.h" +#include "winreg.h" #include "winuser.h" #include "wine/unicode.h" @@ -116,6 +117,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(typelib2); /*================== 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 */ @@ -157,6 +170,9 @@ typedef struct tagICreateTypeLib2Impl 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; @@ -181,13 +197,7 @@ typedef struct tagICreateTypeInfo2Impl 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; @@ -388,6 +398,27 @@ static int ctl2_encode_name( 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>= 2; + + for(i=0; itypekind = (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; @@ -662,19 +716,20 @@ static int ctl2_alloc_string( * 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; offsettypelib_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++; @@ -701,6 +756,7 @@ static int ctl2_alloc_importinfo( 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. */ @@ -726,7 +782,7 @@ static int ctl2_alloc_importfile( 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); @@ -1103,6 +1159,131 @@ static HRESULT ctl2_find_typeinfo_from_offset( 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; itypelib_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 ===================================*/ /****************************************************************************** @@ -1170,7 +1351,8 @@ static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface) 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. */ @@ -1239,7 +1421,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U 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; @@ -1340,10 +1523,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( 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... @@ -1355,9 +1538,94 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( } 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); @@ -1376,71 +1644,131 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( { 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->cElementinvkind&(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; + insert->indice = pFuncDesc->memid; + insert->name = -1; - /* ??? */ - if (!This->typeinfo->res2) This->typeinfo->res2 = 0x20; - This->typeinfo->res2 <<= 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; inext; - /* ??? */ - if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0; - This->typeinfo->res3 += 0x38; + insert->next = iter->next; + iter->next = insert; + } - /* ??? */ - if (index < 2) This->typeinfo->res2 += pFuncDesc->cParams << 4; - This->typeinfo->res3 += pFuncDesc->cParams << 4; - - /* 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; @@ -1497,23 +1825,18 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType( } 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 (This->typeinfo->cImplTypes && index==1) + return TYPE_E_BADMODULEKIND; - if (index != 0) return TYPE_E_ELEMENTNOTFOUND; + if( index != 0) return TYPE_E_ELEMENTNOTFOUND; - This->typeinfo->cImplTypes++; - - /* hacked values for IDispatch only, and maybe only for stdole. */ - This->typeinfo->cbSizeVft += 0x0c; /* hack */ - This->typeinfo->datatype1 = hRefType; - This->typeinfo->datatype2 = (3 << 16) | 1; /* ? */ + 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; } @@ -1614,7 +1937,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( VARDESC* pVarDesc) { ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; - int offset; + + CyclicList *insert; INT *typedata; int var_datawidth; int var_alignment; @@ -1633,14 +1957,30 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( } 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); @@ -1648,9 +1988,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( 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, @@ -1707,28 +2046,50 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( 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); - offset = ctl2_alloc_name(This->typelib, rgszNames[0]); - This->names[index] = offset; + if(!rgszNames) + return E_INVALIDARG; - 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]; + 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++; } - for (i = 1; i < cNames; i++) { - /* FIXME: Almost certainly easy to break */ - int *paramdata = &This->typedata[This->offsets[index] >> 2]; + /* 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]); + if(offset == -1) + return E_OUTOFMEMORY; + + iter->name = offset; + + namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; + *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; + + 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; @@ -1745,7 +2106,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( 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)); @@ -1766,8 +2128,12 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( if ((This->typeinfo->typekind & 15) == TKIND_ENUM) { namedata[9] |= 0x20; } - This->names[index] = offset; + iter = This->typedata->next->next; + for(i=0; inext; + + iter->name = offset; return S_OK; } @@ -1912,8 +2278,161 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc( 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; itypelib->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; } @@ -2243,8 +2762,45 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( 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; } /****************************************************************************** @@ -2314,8 +2870,35 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType( 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; } /****************************************************************************** @@ -2328,8 +2911,30 @@ static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags( 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; } /****************************************************************************** @@ -2410,8 +3015,54 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( 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; } /****************************************************************************** @@ -2488,7 +3139,9 @@ static void WINAPI ITypeInfo2_fnReleaseTypeAttr( ITypeInfo2* iface, TYPEATTR* pTypeAttr) { - FIXME("(%p,%p), stub!\n", iface, pTypeAttr); + TRACE("(%p,%p)\n", iface, pTypeAttr); + + HeapFree(GetProcessHeap(), 0, pTypeAttr); } /****************************************************************************** @@ -3049,7 +3702,21 @@ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) 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); } @@ -3073,9 +3740,14 @@ static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo( 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; @@ -3260,17 +3932,25 @@ static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segme 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) @@ -3289,12 +3969,26 @@ static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile) 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; + } } } @@ -3310,6 +4004,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) int retval; int filepos; HANDLE hFile; + HRESULT hres; TRACE("(%p)\n", iface); @@ -3324,9 +4019,9 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * 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); @@ -3335,7 +4030,11 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) 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) @@ -3345,9 +4044,9 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) 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; @@ -3360,8 +4059,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) if (!CloseHandle(hFile)) return retval; - retval = S_OK; - return retval; + return S_OK; } @@ -3596,9 +4294,28 @@ static HRESULT WINAPI ITypeLib2_fnGetLibAttr( { 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; } /****************************************************************************** @@ -3631,10 +4348,71 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation( 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; } /****************************************************************************** @@ -3702,9 +4480,9 @@ static void WINAPI ITypeLib2_fnReleaseTLibAttr( 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); } /****************************************************************************** diff --git a/reactos/dll/win32/oleaut32/usrmarshal.c b/reactos/dll/win32/oleaut32/usrmarshal.c index 3172ebad5fc..402794ce333 100644 --- a/reactos/dll/win32/oleaut32/usrmarshal.c +++ b/reactos/dll/win32/oleaut32/usrmarshal.c @@ -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; urgvarg = 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= 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)); diff --git a/reactos/dll/win32/oleaut32/variant.c b/reactos/dll/win32/oleaut32/variant.c index e92a63dcdd7..450856fed41 100644 --- a/reactos/dll/win32/oleaut32/variant.c +++ b/reactos/dll/win32/oleaut32/variant.c @@ -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; diff --git a/reactos/dll/win32/oleaut32/variant.h b/reactos/dll/win32/oleaut32/variant.h index c881b24d60f..265fcc8041e 100644 --- a/reactos/dll/win32/oleaut32/variant.h +++ b/reactos/dll/win32/oleaut32/variant.h @@ -126,3 +126,4 @@ typedef struct tagVARIANT_NUMBER_CHARS BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *); +HRESULT VARIANT_ClearInd(VARIANTARG *); diff --git a/reactos/dll/win32/oleaut32/vartype.c b/reactos/dll/win32/oleaut32/vartype.c index 7f5325936b0..da1288d4a7c 100644 --- a/reactos/dll/win32/oleaut32/vartype.c +++ b/reactos/dll/win32/oleaut32/vartype.c @@ -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))) diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index d8eb71f78f1..7cd927d7b7a 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -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