From 3d27a0b5ace7e368631981a9cac4b17dab2520bd Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Thu, 24 Apr 2014 15:12:07 +0000 Subject: [PATCH] [OLEAUT32] * Sync with Wine 1.7.17. CORE-8080 svn path=/trunk/; revision=62942 --- reactos/dll/win32/oleaut32/connpt.c | 10 +- reactos/dll/win32/oleaut32/dispatch.c | 85 ++--- reactos/dll/win32/oleaut32/oleaut.c | 5 +- reactos/dll/win32/oleaut32/oleaut32.spec | 138 +++---- reactos/dll/win32/oleaut32/oleaut32_oaidl.idl | 3 + reactos/dll/win32/oleaut32/oleaut32_ocidl.idl | 3 + reactos/dll/win32/oleaut32/olefont.c | 32 +- reactos/dll/win32/oleaut32/olepicture.c | 72 +++- reactos/dll/win32/oleaut32/recinfo.c | 94 ++++- reactos/dll/win32/oleaut32/safearray.c | 253 +++++++------ reactos/dll/win32/oleaut32/tmarshal.c | 23 +- reactos/dll/win32/oleaut32/typelib.c | 345 +++++++++++------- reactos/dll/win32/oleaut32/usrmarshal.c | 3 +- reactos/dll/win32/oleaut32/varformat.c | 2 +- reactos/dll/win32/oleaut32/variant.c | 86 +++-- reactos/dll/win32/oleaut32/variant.h | 2 +- reactos/dll/win32/oleaut32/vartype.c | 139 ++++--- reactos/media/doc/README.WINE | 2 +- 18 files changed, 786 insertions(+), 511 deletions(-) diff --git a/reactos/dll/win32/oleaut32/connpt.c b/reactos/dll/win32/oleaut32/connpt.c index 487a0b8d40b..656aee47bbc 100644 --- a/reactos/dll/win32/oleaut32/connpt.c +++ b/reactos/dll/win32/oleaut32/connpt.c @@ -241,9 +241,7 @@ static HRESULT WINAPI ConnectionPointImpl_GetConnectionPointContainer( ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); TRACE("(%p)->(%p)\n", This, ppCPC); - return IUnknown_QueryInterface(This->Obj, - &IID_IConnectionPointContainer, - (LPVOID)ppCPC); + return IUnknown_QueryInterface(This->Obj, &IID_IConnectionPointContainer, (void**)ppCPC); } /************************************************************************ @@ -260,7 +258,7 @@ static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface, TRACE("(%p)->(%p, %p)\n", This, lpUnk, pdwCookie); *pdwCookie = 0; - if(FAILED(IUnknown_QueryInterface(lpUnk, &This->iid, (LPVOID)&lpSink))) + if(FAILED(IUnknown_QueryInterface(lpUnk, &This->iid, (void**)&lpSink))) return CONNECT_E_CANNOTCONNECT; for(i = 0; i < This->maxSinks; i++) { @@ -336,7 +334,7 @@ static HRESULT WINAPI ConnectionPointImpl_EnumConnections( EnumObj = EnumConnectionsImpl_Construct((IUnknown*)This, This->nSinks, pCD); hr = IEnumConnections_QueryInterface(&EnumObj->IEnumConnections_iface, - &IID_IEnumConnections, (LPVOID)ppEnum); + &IID_IEnumConnections, (void**)ppEnum); IEnumConnections_Release(&EnumObj->IEnumConnections_iface); HeapFree(GetProcessHeap(), 0, pCD); @@ -610,7 +608,7 @@ HRESULT CreateConnectionPoint(IUnknown *pUnk, REFIID riid, if(!Obj) return E_OUTOFMEMORY; hr = IConnectionPoint_QueryInterface(&Obj->IConnectionPoint_iface, - &IID_IConnectionPoint, (LPVOID)pCP); + &IID_IConnectionPoint, (void**)pCP); IConnectionPoint_Release(&Obj->IConnectionPoint_iface); return hr; } diff --git a/reactos/dll/win32/oleaut32/dispatch.c b/reactos/dll/win32/oleaut32/dispatch.c index a3324178c04..1331d1c447d 100644 --- a/reactos/dll/win32/oleaut32/dispatch.c +++ b/reactos/dll/win32/oleaut32/dispatch.c @@ -23,8 +23,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); -static IDispatch * StdDispatch_Construct(IUnknown * punkOuter, void * pvThis, ITypeInfo * pTypeInfo); - /****************************************************************************** * DispInvoke (OLEAUT32.30) * @@ -153,32 +151,6 @@ done: return hr; } -/****************************************************************************** - * CreateStdDispatch [OLEAUT32.32] - * - * Create and return a standard IDispatch object. - * - * RETURNS - * Success: S_OK. ppunkStdDisp contains the new object. - * Failure: An HRESULT error code. - * - * NOTES - * Outer unknown appears to be completely ignored. - */ -HRESULT WINAPI CreateStdDispatch( - IUnknown* punkOuter, - void* pvThis, - ITypeInfo* ptinfo, - IUnknown** ppunkStdDisp) -{ - TRACE("(%p, %p, %p, %p)\n", punkOuter, pvThis, ptinfo, ppunkStdDisp); - - *ppunkStdDisp = (LPUNKNOWN)StdDispatch_Construct(punkOuter, pvThis, ptinfo); - if (!*ppunkStdDisp) - return E_OUTOFMEMORY; - return S_OK; -} - /****************************************************************************** * IDispatch {OLEAUT32} @@ -238,13 +210,15 @@ static HRESULT WINAPI StdDispatch_QueryInterface( void** ppvObject) { StdDispatch *This = impl_from_IDispatch(iface); - TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); + + *ppvObject = NULL; if (IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) { - *ppvObject = This; - IUnknown_AddRef((LPUNKNOWN)*ppvObject); + *ppvObject = iface; + IDispatch_AddRef(iface); return S_OK; } return E_NOINTERFACE; @@ -305,10 +279,8 @@ static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface) */ static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo) { - StdDispatch *This = impl_from_IDispatch(iface); TRACE("(%p)\n", pctinfo); - - *pctinfo = This->pTypeInfo ? 1 : 0; + *pctinfo = 1; return S_OK; } @@ -339,11 +311,9 @@ static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCI if (iTInfo != 0) return DISP_E_BADINDEX; - if (This->pTypeInfo) - { - *ppTInfo = This->pTypeInfo; - ITypeInfo_AddRef(*ppTInfo); - } + *ppTInfo = This->pTypeInfo; + ITypeInfo_AddRef(*ppTInfo); + return S_OK; } @@ -435,25 +405,44 @@ static const IDispatchVtbl StdDispatch_VTable = StdDispatch_Invoke }; -static IDispatch * StdDispatch_Construct( - IUnknown * punkOuter, - void * pvThis, - ITypeInfo * pTypeInfo) +/****************************************************************************** + * CreateStdDispatch [OLEAUT32.32] + * + * Create and return a standard IDispatch object. + * + * RETURNS + * Success: S_OK. ppunkStdDisp contains the new object. + * Failure: An HRESULT error code. + * + * NOTES + * Outer unknown appears to be completely ignored. + */ +HRESULT WINAPI CreateStdDispatch( + IUnknown* punkOuter, + void* pvThis, + ITypeInfo* ptinfo, + IUnknown** stddisp) { - StdDispatch * pStdDispatch; + StdDispatch *pStdDispatch; + + TRACE("(%p, %p, %p, %p)\n", punkOuter, pvThis, ptinfo, stddisp); + + if (!pvThis || !ptinfo || !stddisp) + return E_INVALIDARG; pStdDispatch = CoTaskMemAlloc(sizeof(StdDispatch)); if (!pStdDispatch) - return &pStdDispatch->IDispatch_iface; + return E_OUTOFMEMORY; pStdDispatch->IDispatch_iface.lpVtbl = &StdDispatch_VTable; pStdDispatch->pvThis = pvThis; - pStdDispatch->pTypeInfo = pTypeInfo; + pStdDispatch->pTypeInfo = ptinfo; pStdDispatch->ref = 1; /* we keep a reference to the type info so prevent it from * being destroyed until we are done with it */ - ITypeInfo_AddRef(pTypeInfo); + ITypeInfo_AddRef(ptinfo); + *stddisp = (IUnknown*)&pStdDispatch->IDispatch_iface; - return &pStdDispatch->IDispatch_iface; + return S_OK; } diff --git a/reactos/dll/win32/oleaut32/oleaut.c b/reactos/dll/win32/oleaut32/oleaut.c index 8f77d18c8b7..961f40c856c 100644 --- a/reactos/dll/win32/oleaut32/oleaut.c +++ b/reactos/dll/win32/oleaut32/oleaut.c @@ -860,7 +860,8 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved) { static const WCHAR oanocacheW[] = {'o','a','n','o','c','a','c','h','e',0}; - bstr_cache_enabled = !GetEnvironmentVariableW(oanocacheW, NULL, 0); + if(fdwReason == DLL_PROCESS_ATTACH) + bstr_cache_enabled = !GetEnvironmentVariableW(oanocacheW, NULL, 0); return OLEAUTPS_DllMain( hInstDll, fdwReason, lpvReserved ); } @@ -887,6 +888,6 @@ HRESULT WINAPI DllUnregisterServer(void) HCURSOR WINAPI OleIconToCursor( HINSTANCE hinstExe, HICON hIcon) { FIXME("(%p,%p), partially implemented.\n",hinstExe,hIcon); - /* FIXME: make a extended conversation from HICON to HCURSOR */ + /* FIXME: make an extended conversation from HICON to HCURSOR */ return CopyCursor(hIcon); } diff --git a/reactos/dll/win32/oleaut32/oleaut32.spec b/reactos/dll/win32/oleaut32/oleaut32.spec index a86486fecac..a68eb0c4eaf 100644 --- a/reactos/dll/win32/oleaut32/oleaut32.spec +++ b/reactos/dll/win32/oleaut32/oleaut32.spec @@ -46,9 +46,9 @@ 47 stdcall VarNumFromParseNum(ptr ptr long ptr) 48 stdcall VarI2FromUI1(long ptr) 49 stdcall VarI2FromI4(long ptr) -50 stdcall VarI2FromR4(long ptr) +50 stdcall VarI2FromR4(float ptr) 51 stdcall VarI2FromR8(double ptr) -52 stdcall VarI2FromCy(double ptr) +52 stdcall VarI2FromCy(int64 ptr) 53 stdcall VarI2FromDate(double ptr) 54 stdcall VarI2FromStr(wstr long long ptr) 55 stdcall VarI2FromDisp(ptr long ptr) @@ -56,9 +56,9 @@ 57 stdcall SafeArraySetIID(ptr ptr) 58 stdcall VarI4FromUI1(long ptr) 59 stdcall VarI4FromI2(long ptr) -60 stdcall VarI4FromR4(long ptr) +60 stdcall VarI4FromR4(float ptr) 61 stdcall VarI4FromR8(double ptr) -62 stdcall VarI4FromCy(double ptr) +62 stdcall VarI4FromCy(int64 ptr) 63 stdcall VarI4FromDate(double ptr) 64 stdcall VarI4FromStr(wstr long long ptr) 65 stdcall VarI4FromDisp(ptr long ptr) @@ -68,7 +68,7 @@ 69 stdcall VarR4FromI2(long ptr) 70 stdcall VarR4FromI4(long ptr) 71 stdcall VarR4FromR8(double ptr) -72 stdcall VarR4FromCy(double ptr) +72 stdcall VarR4FromCy(int64 ptr) 73 stdcall VarR4FromDate(double ptr) 74 stdcall VarR4FromStr(wstr long long ptr) 75 stdcall VarR4FromDisp(ptr long ptr) @@ -77,8 +77,8 @@ 78 stdcall VarR8FromUI1(long ptr) 79 stdcall VarR8FromI2(long ptr) 80 stdcall VarR8FromI4(long ptr) -81 stdcall VarR8FromR4(long ptr) -82 stdcall VarR8FromCy(double ptr) +81 stdcall VarR8FromR4(float ptr) +82 stdcall VarR8FromCy(int64 ptr) 83 stdcall VarR8FromDate(double ptr) 84 stdcall VarR8FromStr(wstr long long ptr) 85 stdcall VarR8FromDisp(ptr long ptr) @@ -87,9 +87,9 @@ 88 stdcall VarDateFromUI1(long ptr) 89 stdcall VarDateFromI2(long ptr) 90 stdcall VarDateFromI4(long ptr) -91 stdcall VarDateFromR4(long ptr) +91 stdcall VarDateFromR4(float ptr) 92 stdcall VarDateFromR8(double ptr) -93 stdcall VarDateFromCy(double ptr) +93 stdcall VarDateFromCy(int64 ptr) 94 stdcall VarDateFromStr(wstr long long ptr) 95 stdcall VarDateFromDisp(ptr long ptr) 96 stdcall VarDateFromBool(long ptr) @@ -97,7 +97,7 @@ 98 stdcall VarCyFromUI1(long ptr) 99 stdcall VarCyFromI2(long ptr) 100 stdcall VarCyFromI4(long ptr) -101 stdcall VarCyFromR4(long ptr) +101 stdcall VarCyFromR4(float ptr) 102 stdcall VarCyFromR8(double ptr) 103 stdcall VarCyFromDate(double ptr) 104 stdcall VarCyFromStr(wstr long long ptr) @@ -107,9 +107,9 @@ 108 stdcall VarBstrFromUI1(long long long ptr) 109 stdcall VarBstrFromI2(long long long ptr) 110 stdcall VarBstrFromI4(long long long ptr) -111 stdcall VarBstrFromR4(long long long ptr) +111 stdcall VarBstrFromR4(float long long ptr) 112 stdcall VarBstrFromR8(double long long ptr) -113 stdcall VarBstrFromCy(double long long ptr) +113 stdcall VarBstrFromCy(int64 long long ptr) 114 stdcall VarBstrFromDate(double long long ptr) 115 stdcall VarBstrFromDisp(ptr long long ptr) 116 stdcall VarBstrFromBool(long long long ptr) @@ -117,10 +117,10 @@ 118 stdcall VarBoolFromUI1(long ptr) 119 stdcall VarBoolFromI2(long ptr) 120 stdcall VarBoolFromI4(long ptr) -121 stdcall VarBoolFromR4(long ptr) +121 stdcall VarBoolFromR4(float ptr) 122 stdcall VarBoolFromR8(double ptr) 123 stdcall VarBoolFromDate(double ptr) -124 stdcall VarBoolFromCy(double ptr) +124 stdcall VarBoolFromCy(int64 ptr) 125 stdcall VarBoolFromStr(wstr long long ptr) 126 stdcall VarBoolFromDisp(ptr long ptr) 127 stdcall VarFormatCurrency(ptr long long long long long ptr) @@ -128,9 +128,9 @@ 129 stdcall VarMonthName(long long long ptr) 130 stdcall VarUI1FromI2(long ptr) 131 stdcall VarUI1FromI4(long ptr) -132 stdcall VarUI1FromR4(long ptr) +132 stdcall VarUI1FromR4(float ptr) 133 stdcall VarUI1FromR8(double ptr) -134 stdcall VarUI1FromCy(double ptr) +134 stdcall VarUI1FromCy(int64 ptr) 135 stdcall VarUI1FromDate(double ptr) 136 stdcall VarUI1FromStr(wstr long long ptr) 137 stdcall VarUI1FromDisp(ptr long ptr) @@ -187,10 +187,10 @@ 190 stdcall VarDecFromUI1(long ptr) 191 stdcall VarDecFromI2(long ptr) 192 stdcall VarDecFromI4(long ptr) -193 stdcall VarDecFromR4(long ptr) +193 stdcall VarDecFromR4(float ptr) 194 stdcall VarDecFromR8(double ptr) 195 stdcall VarDecFromDate(double ptr) -196 stdcall VarDecFromCy(double ptr) +196 stdcall VarDecFromCy(int64 ptr) 197 stdcall VarDecFromStr(wstr long long ptr) 198 stdcall VarDecFromDisp(ptr long ptr) 199 stdcall VarDecFromBool(long ptr) @@ -241,10 +241,10 @@ 244 stdcall VarI1FromUI1(long ptr) 245 stdcall VarI1FromI2(long ptr) 246 stdcall VarI1FromI4(long ptr) -247 stdcall VarI1FromR4(long ptr) +247 stdcall VarI1FromR4(float ptr) 248 stdcall VarI1FromR8(double ptr) 249 stdcall VarI1FromDate(double ptr) -250 stdcall VarI1FromCy(double ptr) +250 stdcall VarI1FromCy(int64 ptr) 251 stdcall VarI1FromStr(wstr long long ptr) 252 stdcall VarI1FromDisp(ptr long ptr) 253 stdcall VarI1FromBool(long ptr) @@ -254,10 +254,10 @@ 257 stdcall VarUI2FromUI1(long ptr) 258 stdcall VarUI2FromI2(long ptr) 259 stdcall VarUI2FromI4(long ptr) -260 stdcall VarUI2FromR4(long ptr) +260 stdcall VarUI2FromR4(float ptr) 261 stdcall VarUI2FromR8(double ptr) 262 stdcall VarUI2FromDate(double ptr) -263 stdcall VarUI2FromCy(double ptr) +263 stdcall VarUI2FromCy(int64 ptr) 264 stdcall VarUI2FromStr(wstr long long ptr) 265 stdcall VarUI2FromDisp(ptr long ptr) 266 stdcall VarUI2FromBool(long ptr) @@ -267,10 +267,10 @@ 270 stdcall VarUI4FromUI1(long ptr) 271 stdcall VarUI4FromI2(long ptr) 272 stdcall VarUI4FromI4(long ptr) -273 stdcall VarUI4FromR4(long ptr) +273 stdcall VarUI4FromR4(float ptr) 274 stdcall VarUI4FromR8(double ptr) 275 stdcall VarUI4FromDate(double ptr) -276 stdcall VarUI4FromCy(double ptr) +276 stdcall VarUI4FromCy(int64 ptr) 277 stdcall VarUI4FromStr(wstr long long ptr) 278 stdcall VarUI4FromDisp(ptr long ptr) 279 stdcall VarUI4FromBool(long ptr) @@ -293,21 +293,21 @@ 296 stub LPSAFEARRAY_Marshal 297 stub LPSAFEARRAY_Unmarshal 298 stdcall VarDecCmpR8(ptr double) -299 stdcall VarCyAdd(double double ptr) -303 stdcall VarCyMul(double double ptr) -304 stdcall VarCyMulI4(double long ptr) -305 stdcall VarCySub(double double ptr) -306 stdcall VarCyAbs(double ptr) -307 stdcall VarCyFix(double ptr) -308 stdcall VarCyInt(double ptr) -309 stdcall VarCyNeg(double ptr) -310 stdcall VarCyRound(double long ptr) -311 stdcall VarCyCmp(double double) -312 stdcall VarCyCmpR8(double double) +299 stdcall VarCyAdd(int64 int64 ptr) +303 stdcall VarCyMul(int64 int64 ptr) +304 stdcall VarCyMulI4(int64 long ptr) +305 stdcall VarCySub(int64 int64 ptr) +306 stdcall VarCyAbs(int64 ptr) +307 stdcall VarCyFix(int64 ptr) +308 stdcall VarCyInt(int64 ptr) +309 stdcall VarCyNeg(int64 ptr) +310 stdcall VarCyRound(int64 long ptr) +311 stdcall VarCyCmp(int64 int64) +312 stdcall VarCyCmpR8(int64 double) 313 stdcall VarBstrCat(wstr wstr ptr) 314 stdcall VarBstrCmp(wstr wstr long long) 315 stdcall VarR8Pow(double double ptr) -316 stdcall VarR4CmpR8(long double) +316 stdcall VarR4CmpR8(float double) 317 stdcall VarR8Round(double long ptr) 318 stdcall VarCat(ptr ptr ptr) 319 stdcall VarDateFromUdateEx(ptr long long ptr) @@ -316,15 +316,15 @@ 325 stub SetVarConversionLocaleSetting 326 stub GetVarConversionLocaleSetting 327 stdcall SetOaNoCache() -329 stdcall VarCyMulI8(double double ptr) +329 stdcall VarCyMulI8(int64 int64 ptr) 330 stdcall VarDateFromUdate(ptr long ptr) 331 stdcall VarUdateFromDate(double long ptr) 332 stub GetAltMonthNames 333 stdcall VarI8FromUI1(long long) 334 stdcall VarI8FromI2(long long) -335 stdcall VarI8FromR4(long long) +335 stdcall VarI8FromR4(float long) 336 stdcall VarI8FromR8(double long) -337 stdcall VarI8FromCy(double ptr) +337 stdcall VarI8FromCy(int64 ptr) 338 stdcall VarI8FromDate(double long) 339 stdcall VarI8FromStr(wstr long long ptr) 340 stdcall VarI8FromDisp(ptr long ptr) @@ -333,30 +333,30 @@ 343 stdcall VarI8FromUI2(long long) 344 stdcall VarI8FromUI4(long long) 345 stdcall VarI8FromDec(ptr ptr) -346 stdcall VarI2FromI8(double ptr) -347 stdcall VarI2FromUI8(double ptr) -348 stdcall VarI4FromI8(double ptr) -349 stdcall VarI4FromUI8(double ptr) -360 stdcall VarR4FromI8(double ptr) -361 stdcall VarR4FromUI8(double ptr) -362 stdcall VarR8FromI8(double ptr) -363 stdcall VarR8FromUI8(double ptr) -364 stdcall VarDateFromI8(double ptr) -365 stdcall VarDateFromUI8(double ptr) -366 stdcall VarCyFromI8(double ptr) -367 stdcall VarCyFromUI8(double ptr) -368 stdcall VarBstrFromI8(double long long ptr) -369 stdcall VarBstrFromUI8(double long long ptr) -370 stdcall VarBoolFromI8(double ptr) -371 stdcall VarBoolFromUI8(double ptr) -372 stdcall VarUI1FromI8(double ptr) -373 stdcall VarUI1FromUI8(double ptr) -374 stdcall VarDecFromI8(double ptr) -375 stdcall VarDecFromUI8(double ptr) -376 stdcall VarI1FromI8(double ptr) -377 stdcall VarI1FromUI8(double ptr) -378 stdcall VarUI2FromI8(double ptr) -379 stdcall VarUI2FromUI8(double ptr) +346 stdcall VarI2FromI8(int64 ptr) +347 stdcall VarI2FromUI8(int64 ptr) +348 stdcall VarI4FromI8(int64 ptr) +349 stdcall VarI4FromUI8(int64 ptr) +360 stdcall VarR4FromI8(int64 ptr) +361 stdcall VarR4FromUI8(int64 ptr) +362 stdcall VarR8FromI8(int64 ptr) +363 stdcall VarR8FromUI8(int64 ptr) +364 stdcall VarDateFromI8(int64 ptr) +365 stdcall VarDateFromUI8(int64 ptr) +366 stdcall VarCyFromI8(int64 ptr) +367 stdcall VarCyFromUI8(int64 ptr) +368 stdcall VarBstrFromI8(int64 long long ptr) +369 stdcall VarBstrFromUI8(int64 long long ptr) +370 stdcall VarBoolFromI8(int64 ptr) +371 stdcall VarBoolFromUI8(int64 ptr) +372 stdcall VarUI1FromI8(int64 ptr) +373 stdcall VarUI1FromUI8(int64 ptr) +374 stdcall VarDecFromI8(int64 ptr) +375 stdcall VarDecFromUI8(int64 ptr) +376 stdcall VarI1FromI8(int64 ptr) +377 stdcall VarI1FromUI8(int64 ptr) +378 stdcall VarUI2FromI8(int64 ptr) +379 stdcall VarUI2FromUI8(int64 ptr) 380 stub UserHWND_from_local 381 stub UserHWND_to_local 382 stub UserHWND_free_inst @@ -393,15 +393,15 @@ 422 stub OleLoadPictureFile 423 stub OleSavePictureFile 424 stdcall OleLoadPicturePath(wstr ptr long long ptr ptr) -425 stdcall VarUI4FromI8(double ptr) -426 stdcall VarUI4FromUI8(double ptr) -427 stdcall VarI8FromUI8(double ptr) -428 stdcall VarUI8FromI8(double ptr) +425 stdcall VarUI4FromI8(int64 ptr) +426 stdcall VarUI4FromUI8(int64 ptr) +427 stdcall VarI8FromUI8(int64 ptr) +428 stdcall VarUI8FromI8(int64 ptr) 429 stdcall VarUI8FromUI1(long ptr) 430 stdcall VarUI8FromI2(long ptr) -431 stdcall VarUI8FromR4(long ptr) +431 stdcall VarUI8FromR4(float ptr) 432 stdcall VarUI8FromR8(double ptr) -433 stdcall VarUI8FromCy(double ptr) +433 stdcall VarUI8FromCy(int64 ptr) 434 stdcall VarUI8FromDate(double ptr) 435 stdcall VarUI8FromStr(wstr long long ptr) 436 stdcall VarUI8FromDisp(ptr long ptr) diff --git a/reactos/dll/win32/oleaut32/oleaut32_oaidl.idl b/reactos/dll/win32/oleaut32/oleaut32_oaidl.idl index 3574d081ab2..2874be0603f 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_oaidl.idl +++ b/reactos/dll/win32/oleaut32/oleaut32_oaidl.idl @@ -20,6 +20,9 @@ including oaidl.h at some point. This will cause all sorts of errors so the easiest thing to do is just comment out our entire header. */ +#pragma makedep proxy +#pragma makedep register + cpp_quote("#if 0 /* oleaut32_oaidl.idl hack */") #include "oaidl.idl" cpp_quote("#endif /* oleaut32_oaidl.idl hack */") diff --git a/reactos/dll/win32/oleaut32/oleaut32_ocidl.idl b/reactos/dll/win32/oleaut32/oleaut32_ocidl.idl index fad374183e2..5f7664e0fb3 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_ocidl.idl +++ b/reactos/dll/win32/oleaut32/oleaut32_ocidl.idl @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep proxy +#pragma makedep register + #include "ocidl.idl" [ diff --git a/reactos/dll/win32/oleaut32/olefont.c b/reactos/dll/win32/oleaut32/olefont.c index e6102195aec..ad9351d1d25 100644 --- a/reactos/dll/win32/oleaut32/olefont.c +++ b/reactos/dll/win32/oleaut32/olefont.c @@ -333,9 +333,9 @@ HRESULT WINAPI OleCreateFontIndirect( fd.cySize.s.Hi = 0; fd.sWeight = 0; fd.sCharset = 0; - fd.fItalic = 0; - fd.fUnderline = 0; - fd.fStrikethrough = 0; + fd.fItalic = FALSE; + fd.fUnderline = FALSE; + fd.fStrikethrough = FALSE; lpFontDesc = &fd; } @@ -368,7 +368,7 @@ static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID) static const WCHAR wszUnder[] = {'U','n','d','e','r','l','i','n','e',0}; static const WCHAR wszStrike[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0}; static const WCHAR wszWeight[] = {'W','e','i','g','h','t',0}; - static const WCHAR wszCharset[] = {'C','h','a','r','s','s','e','t',0}; + static const WCHAR wszCharset[] = {'C','h','a','r','s','e','t',0}; static const LPCWSTR dispid_mapping[] = { wszName, @@ -394,7 +394,7 @@ static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID) while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { IPropertyNotifySink *sink; - IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink); + IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (void**)&sink); IPropertyNotifySink_OnChanged(sink, dispID); IPropertyNotifySink_Release(sink); IUnknown_Release(CD.pUnk); @@ -420,7 +420,7 @@ static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID) while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { IFontEventsDisp *disp; - IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp); + IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (void**)&disp); IFontEventsDisp_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL, LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL, NULL, NULL); @@ -1063,7 +1063,12 @@ static HRESULT WINAPI OLEFontImpl_SetRatio( TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric); if(cyLogical == 0 || cyHimetric == 0) - return E_INVALIDARG; + return E_FAIL; + + /* cyLogical and cyHimetric both set to 1 is a special case that + does not change the scaling but also does not fail */ + if(cyLogical == 1 && cyHimetric == 1) + return S_OK; this->cyLogical = cyLogical; this->cyHimetric = cyHimetric; @@ -1280,9 +1285,6 @@ static HRESULT WINAPI OLEFontImpl_GetIDsOfNames( /************************************************************************ * OLEFontImpl_Invoke (IDispatch) * - * Note: Do not call _put_Xxx methods, since setting things here - * should not call notify functions as I found out debugging the generic - * MS VB5 installer. */ static HRESULT WINAPI OLEFontImpl_Invoke( IDispatch* iface, @@ -1828,13 +1830,11 @@ static HRESULT WINAPI OLEFontImpl_FindConnectionPoint( TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppCp); if(IsEqualIID(riid, &IID_IPropertyNotifySink)) { - return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP, - &IID_IConnectionPoint, - (LPVOID)ppCp); + return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP, &IID_IConnectionPoint, + (void**)ppCp); } else if(IsEqualIID(riid, &IID_IFontEventsDisp)) { - return IConnectionPoint_QueryInterface(this->pFontEventsCP, - &IID_IConnectionPoint, - (LPVOID)ppCp); + return IConnectionPoint_QueryInterface(this->pFontEventsCP, &IID_IConnectionPoint, + (void**)ppCp); } else { FIXME("no connection point for %s\n", debugstr_guid(riid)); return CONNECT_E_NOCONNECTION; diff --git a/reactos/dll/win32/oleaut32/olepicture.c b/reactos/dll/win32/oleaut32/olepicture.c index 47667bf6480..4b4bb307614 100644 --- a/reactos/dll/win32/oleaut32/olepicture.c +++ b/reactos/dll/win32/oleaut32/olepicture.c @@ -902,7 +902,7 @@ static HRESULT WINAPI OLEPictureImpl_FindConnectionPoint( return E_POINTER; *ppCP = NULL; if (IsEqualGUID(riid,&IID_IPropertyNotifySink)) - return IConnectionPoint_QueryInterface(This->pCP,&IID_IConnectionPoint,(LPVOID)ppCP); + return IConnectionPoint_QueryInterface(This->pCP, &IID_IConnectionPoint, (void**)ppCP); FIXME("no connection point for %s\n",debugstr_guid(riid)); return CONNECT_E_NOCONNECTION; } @@ -1369,12 +1369,17 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) } headerread += xread; xread = 0; - + if (!memcmp(&(header[0]),"lt\0\0", 4) && (statfailed || (header[1] + headerread <= statstg.cbSize.QuadPart))) { if (toread != 0 && toread != header[1]) FIXME("varying lengths of image data (prev=%u curr=%u), only last one will be used\n", toread, header[1]); toread = header[1]; + if (statfailed) + { + statstg.cbSize.QuadPart = header[1] + 8; + statfailed = FALSE; + } if (toread == 0) break; } else { if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */ @@ -1506,9 +1511,9 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) return hr; } -static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength) +static BOOL serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength) { - int iSuccess = 0; + BOOL success = FALSE; HDC hDC; BITMAPINFO * pInfoBitmap; int iNumPaletteEntries; @@ -1564,17 +1569,17 @@ static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLengt sizeof(BITMAPINFOHEADER) + iNumPaletteEntries * sizeof(RGBQUAD), pPixelData, pInfoBitmap->bmiHeader.biSizeImage); - iSuccess = 1; + success = TRUE; HeapFree(GetProcessHeap(), 0, pPixelData); HeapFree(GetProcessHeap(), 0, pInfoBitmap); - return iSuccess; + return success; } -static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) +static BOOL serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) { ICONINFO infoIcon; - int iSuccess = 0; + BOOL success = FALSE; *ppBuffer = NULL; *pLength = 0; if (GetIconInfo(hIcon, &infoIcon)) { @@ -1696,7 +1701,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) /* Write out everything produced so far to the stream */ *ppBuffer = pIconData; *pLength = iDataSize; - iSuccess = 1; + success = TRUE; } else { /* printf("ERROR: unable to get bitmap information via GetDIBits() (error %u)\n", @@ -1719,7 +1724,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) printf("ERROR: Unable to get icon information (error %u)\n", GetLastError()); } - return iSuccess; + return success; } static HRESULT WINAPI OLEPictureImpl_Save( @@ -1730,7 +1735,7 @@ static HRESULT WINAPI OLEPictureImpl_Save( unsigned int iDataSize; DWORD header[2]; ULONG dummy; - int iSerializeResult = 0; + BOOL serializeResult = FALSE; OLEPictureImpl *This = impl_from_IPersistStream(iface); TRACE("%p %p %d\n", This, pStm, fClearDirty); @@ -1764,7 +1769,7 @@ static HRESULT WINAPI OLEPictureImpl_Save( if (This->bIsDirty || !This->data) { switch (This->keepOrigFormat ? This->loadtime_format : BITMAP_FORMAT_BMP) { case BITMAP_FORMAT_BMP: - iSerializeResult = serializeBMP(This->desc.u.bmp.hbitmap, &pIconData, &iDataSize); + serializeResult = serializeBMP(This->desc.u.bmp.hbitmap, &pIconData, &iDataSize); break; case BITMAP_FORMAT_JPEG: FIXME("(%p,%p,%d), PICTYPE_BITMAP (format JPEG) not implemented!\n",This,pStm,fClearDirty); @@ -1780,7 +1785,7 @@ static HRESULT WINAPI OLEPictureImpl_Save( break; } - if (!iSerializeResult) + if (!serializeResult) { hResult = E_FAIL; break; @@ -1974,6 +1979,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( UINT* puArgErr) { OLEPictureImpl *This = impl_from_IDispatch(iface); + HRESULT hr; /* validate parameters */ @@ -2031,7 +2037,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( else if (wFlags & DISPATCH_PROPERTYPUT) { VARIANTARG vararg; - HRESULT hr; + TRACE("DISPID_PICT_HPAL\n"); VariantInit(&vararg); @@ -2069,6 +2075,40 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( return IPicture_get_Height(&This->IPicture_iface, &V_I4(pVarResult)); } break; + case DISPID_PICT_RENDER: + if (wFlags & DISPATCH_METHOD) + { + VARIANTARG *args = pDispParams->rgvarg; + int i; + + TRACE("DISPID_PICT_RENDER\n"); + + if (pDispParams->cArgs != 10) + return DISP_E_BADPARAMCOUNT; + + /* All parameters are supposed to be VT_I4 (on 64 bits too). */ + for (i = 0; i < pDispParams->cArgs; i++) + if (V_VT(&args[i]) != VT_I4) + { + ERR("DISPID_PICT_RENDER: wrong argument type %d:%d\n", i, V_VT(&args[i])); + return DISP_E_TYPEMISMATCH; + } + + /* FIXME: rectangle pointer argument handling seems broken on 64 bits, + currently Render() doesn't use it at all so for now NULL is passed. */ + return IPicture_Render(&This->IPicture_iface, + LongToHandle(V_I4(&args[9])), + V_I4(&args[8]), + V_I4(&args[7]), + V_I4(&args[6]), + V_I4(&args[5]), + V_I4(&args[4]), + V_I4(&args[3]), + V_I4(&args[2]), + V_I4(&args[1]), + NULL); + } + break; } ERR("invalid dispid 0x%x or wFlags 0x%x\n", dispIdMember, wFlags); @@ -2252,7 +2292,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, HANDLE hFile; DWORD dwFileSize; HGLOBAL hGlobal = NULL; - DWORD dwBytesRead = 0; + DWORD dwBytesRead; IStream *stream; BOOL bRead; IPersistStream *pStream; @@ -2296,7 +2336,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, hGlobal = GlobalAlloc(GMEM_FIXED,dwFileSize); if ( hGlobal) { - bRead = ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL); + bRead = ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL) && dwBytesRead == dwFileSize; if (!bRead) { GlobalFree(hGlobal); diff --git a/reactos/dll/win32/oleaut32/recinfo.c b/reactos/dll/win32/oleaut32/recinfo.c index 22a889ba0b4..f10755eff2d 100644 --- a/reactos/dll/win32/oleaut32/recinfo.c +++ b/reactos/dll/win32/oleaut32/recinfo.c @@ -135,6 +135,8 @@ static HRESULT WINAPI IRecordInfoImpl_QueryInterface(IRecordInfo *iface, REFIID { TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); + *ppvObject = NULL; + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRecordInfo, riid)) { *ppvObject = iface; IRecordInfo_AddRef(iface); @@ -223,6 +225,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvEx case VT_UI8: case VT_INT: case VT_UINT: + case VT_HRESULT: break; case VT_INT_PTR: case VT_UINT_PTR: @@ -231,6 +234,15 @@ static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvEx case VT_SAFEARRAY: SafeArrayDestroy(var); break; + case VT_UNKNOWN: + case VT_DISPATCH: + { + IUnknown *unk = *(IUnknown**)var; + if (unk) + IUnknown_Release(unk); + *(void**)var = NULL; + break; + } default: FIXME("Not supported vt = %d\n", This->fields[i].vt); break; @@ -240,18 +252,75 @@ static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvEx return S_OK; } -static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExisting, - PVOID pvNew) +static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, void *src_rec, void *dest_rec) { IRecordInfoImpl *This = impl_from_IRecordInfo(iface); + HRESULT hr = S_OK; + int i; - TRACE("(%p)->(%p %p)\n", This, pvExisting, pvNew); - - if(!pvExisting || !pvNew) + TRACE("(%p)->(%p %p)\n", This, src_rec, dest_rec); + + if(!src_rec || !dest_rec) return E_INVALIDARG; - memcpy(pvExisting, pvNew, This->size); - return S_OK; + /* release already stored data */ + IRecordInfo_RecordClear(iface, dest_rec); + + for (i = 0; i < This->n_vars; i++) + { + void *src, *dest; + + if (This->fields[i].varkind != VAR_PERINSTANCE) { + ERR("varkind != VAR_PERINSTANCE\n"); + continue; + } + + src = ((BYTE*)src_rec) + This->fields[i].offset; + dest = ((BYTE*)dest_rec) + This->fields[i].offset; + switch (This->fields[i].vt) + { + case VT_BSTR: + { + BSTR src_str = *(BSTR*)src; + + if (src_str) + { + BSTR str = SysAllocString(*(BSTR*)src); + if (!str) hr = E_OUTOFMEMORY; + + *(BSTR*)dest = str; + } + else + *(BSTR*)dest = NULL; + break; + } + case VT_UNKNOWN: + case VT_DISPATCH: + { + IUnknown *unk = *(IUnknown**)src; + *(IUnknown**)dest = unk; + if (unk) IUnknown_AddRef(unk); + break; + } + case VT_SAFEARRAY: + hr = SafeArrayCopy(src, dest); + break; + default: + { + /* copy directly for types that don't need deep copy */ + int len = get_type_size(NULL, This->fields[i].vt); + memcpy(dest, src, len); + break; + } + } + + if (FAILED(hr)) break; + } + + if (FAILED(hr)) + IRecordInfo_RecordClear(iface, dest_rec); + + return hr; } static HRESULT WINAPI IRecordInfoImpl_GetGuid(IRecordInfo *iface, GUID *pguid) @@ -445,10 +514,14 @@ static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInf static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface) { IRecordInfoImpl *This = impl_from_IRecordInfo(iface); + void *record; TRACE("(%p)\n", This); - return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->size); + record = HeapAlloc(GetProcessHeap(), 0, This->size); + IRecordInfo_RecordInit(iface, record); + TRACE("created record at %p\n", record); + return record; } static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource, @@ -518,8 +591,8 @@ HRESULT WINAPI GetRecordInfoFromGuids(REFGUID rGuidTypeLib, ULONG uVerMajor, ITypeLib *pTypeLib; HRESULT hres; - TRACE("(%p,%d,%d,%d,%p,%p)\n", rGuidTypeLib, uVerMajor, uVerMinor, - lcid, rGuidTypeInfo, ppRecInfo); + TRACE("(%p,%d,%d,%d,%s,%p)\n", rGuidTypeLib, uVerMajor, uVerMinor, + lcid, debugstr_guid(rGuidTypeInfo), ppRecInfo); hres = LoadRegTypeLib(rGuidTypeLib, uVerMajor, uVerMinor, lcid, &pTypeLib); if(FAILED(hres)) { @@ -618,6 +691,7 @@ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo NULL, NULL, NULL); if(FAILED(hres)) WARN("GetDocumentation failed: %08x\n", hres); + TRACE("field=%s, offset=%d\n", debugstr_w(ret->fields[i].name), ret->fields[i].offset); ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc); } diff --git a/reactos/dll/win32/oleaut32/safearray.c b/reactos/dll/win32/oleaut32/safearray.c index 88a7e13f3b2..14eb269a439 100644 --- a/reactos/dll/win32/oleaut32/safearray.c +++ b/reactos/dll/win32/oleaut32/safearray.c @@ -73,6 +73,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(variant); /* Undocumented hidden space before the start of a SafeArray descriptor */ #define SAFEARRAY_HIDDEN_SIZE sizeof(GUID) +/* features listed here are not propagated to newly created array or data copy + created with SafeArrayCopy()/SafeArrayCopyData() */ +static const USHORT ignored_copy_features = + FADF_AUTO | + FADF_STATIC | + FADF_EMBEDDED | + FADF_FIXEDSIZE | + FADF_CREATEVECTOR; + /* Allocate memory */ static inline LPVOID SAFEARRAY_Malloc(ULONG ulSize) { @@ -165,7 +174,7 @@ static HRESULT SAFEARRAY_AllocDescriptor(ULONG ulSize, SAFEARRAY **ppsaOut) if (!ptr) { *ppsaOut = NULL; - return E_UNEXPECTED; + return E_OUTOFMEMORY; } *ppsaOut = (SAFEARRAY*)(ptr + SAFEARRAY_HIDDEN_SIZE); @@ -285,7 +294,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell) lpUnknown++; } } - else if (psa->fFeatures & (FADF_RECORD)) + else if (psa->fFeatures & FADF_RECORD) { IRecordInfo *lpRecInfo; @@ -326,86 +335,104 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell) return S_OK; } -/* Copy data items from one array to another */ +/* Copy data items from one array to another. Destination data is freed before copy. */ static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest) { + HRESULT hr = S_OK; + if (!psa->pvData) return S_OK; - else if (!dest->pvData || psa->fFeatures & FADF_DATADELETED) + + if (!dest->pvData || psa->fFeatures & FADF_DATADELETED) return E_INVALIDARG; else { ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); - dest->fFeatures = (dest->fFeatures & FADF_CREATEVECTOR) | - (psa->fFeatures & ~(FADF_CREATEVECTOR|FADF_DATADELETED)); + dest->fFeatures = (dest->fFeatures & FADF_CREATEVECTOR) | (psa->fFeatures & ~ignored_copy_features); if (psa->fFeatures & FADF_VARIANT) { - VARIANT* lpVariant = psa->pvData; - VARIANT* lpDest = dest->pvData; + VARIANT *src_var = psa->pvData; + VARIANT *dest_var = dest->pvData; while(ulCellCount--) { HRESULT hRet; - hRet = VariantCopy(lpDest, lpVariant); - if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet); - lpVariant++; - lpDest++; + /* destination is cleared automatically */ + hRet = VariantCopy(dest_var, src_var); + if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%08x, element %u\n", hRet, ulCellCount); + src_var++; + dest_var++; } } else if (psa->fFeatures & FADF_BSTR) { - BSTR* lpBstr = psa->pvData; - BSTR* lpDest = dest->pvData; + BSTR *src_bstr = psa->pvData; + BSTR *dest_bstr = dest->pvData; while(ulCellCount--) { - if (*lpBstr) + SysFreeString(*dest_bstr); + if (*src_bstr) { - *lpDest = SysAllocStringByteLen((char*)*lpBstr, SysStringByteLen(*lpBstr)); - if (!*lpDest) + *dest_bstr = SysAllocStringByteLen((char*)*src_bstr, SysStringByteLen(*src_bstr)); + if (!*dest_bstr) return E_OUTOFMEMORY; } else - *lpDest = NULL; - lpBstr++; - lpDest++; + *dest_bstr = NULL; + src_bstr++; + dest_bstr++; + } + } + else if (psa->fFeatures & FADF_RECORD) + { + BYTE *dest_data = dest->pvData; + BYTE *src_data = psa->pvData; + IRecordInfo *record; + + SafeArrayGetRecordInfo(psa, &record); + while (ulCellCount--) + { + /* RecordCopy() clears destination record */ + hr = IRecordInfo_RecordCopy(record, src_data, dest_data); + if (FAILED(hr)) break; + src_data += psa->cbElements; + dest_data += psa->cbElements; + } + + SafeArraySetRecordInfo(dest, record); + /* This value is set to 32 bytes by default on descriptor creation, + update with actual structure size. */ + dest->cbElements = psa->cbElements; + IRecordInfo_Release(record); + } + else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) + { + IUnknown **dest_unk = dest->pvData; + IUnknown **src_unk = psa->pvData; + + /* release old iface, addref new one */ + while (ulCellCount--) + { + if (*dest_unk) + IUnknown_Release(*dest_unk); + *dest_unk = *src_unk; + if (*dest_unk) + IUnknown_AddRef(*dest_unk); + src_unk++; + dest_unk++; } } else { /* Copy the data over */ memcpy(dest->pvData, psa->pvData, ulCellCount * psa->cbElements); - - if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) - { - LPUNKNOWN *lpUnknown = dest->pvData; - - while(ulCellCount--) - { - if (*lpUnknown) - IUnknown_AddRef(*lpUnknown); - lpUnknown++; - } - } } - if (psa->fFeatures & FADF_RECORD) - { - IRecordInfo* pRecInfo = NULL; - - SafeArrayGetRecordInfo(psa, &pRecInfo); - SafeArraySetRecordInfo(dest, pRecInfo); - - if (pRecInfo) - { - /* Release because Get() adds a reference */ - IRecordInfo_Release(pRecInfo); - } - } - else if (psa->fFeatures & FADF_HAVEIID) + if (psa->fFeatures & FADF_HAVEIID) { GUID guid; SafeArrayGetIID(psa, &guid); @@ -416,7 +443,8 @@ static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest) SAFEARRAY_SetHiddenDWORD(dest, SAFEARRAY_GetHiddenDWORD(psa)); } } - return S_OK; + + return hr; } /************************************************************************* @@ -438,6 +466,7 @@ static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest) HRESULT WINAPI SafeArrayAllocDescriptor(UINT cDims, SAFEARRAY **ppsaOut) { LONG allocSize; + HRESULT hr; TRACE("(%d,%p)\n", cDims, ppsaOut); @@ -450,8 +479,9 @@ HRESULT WINAPI SafeArrayAllocDescriptor(UINT cDims, SAFEARRAY **ppsaOut) /* We need enough space for the header and its bounds */ allocSize = sizeof(SAFEARRAY) + sizeof(SAFEARRAYBOUND) * (cDims - 1); - if (FAILED(SAFEARRAY_AllocDescriptor(allocSize, ppsaOut))) - return E_UNEXPECTED; + hr = SAFEARRAY_AllocDescriptor(allocSize, ppsaOut); + if (FAILED(hr)) + return hr; (*ppsaOut)->cDims = cDims; @@ -481,7 +511,7 @@ HRESULT WINAPI SafeArrayAllocDescriptor(UINT cDims, SAFEARRAY **ppsaOut) HRESULT WINAPI SafeArrayAllocDescriptorEx(VARTYPE vt, UINT cDims, SAFEARRAY **ppsaOut) { ULONG cbElements; - HRESULT hRet = E_UNEXPECTED; + HRESULT hRet; TRACE("(%d->%s,%d,%p)\n", vt, debugstr_vt(vt), cDims, ppsaOut); @@ -846,8 +876,6 @@ HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData VARIANT* lpVariant = pvData; VARIANT* lpDest = lpvDest; - hRet = VariantClear(lpDest); - if (FAILED(hRet)) FIXME("VariantClear failed with 0x%x\n", hRet); hRet = VariantCopy(lpDest, lpVariant); if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet); } @@ -862,23 +890,27 @@ HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData if (!*lpDest) hRet = E_OUTOFMEMORY; } - else + else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { - if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) - { - LPUNKNOWN lpUnknown = pvData; - LPUNKNOWN *lpDest = lpvDest; + IUnknown *lpUnknown = pvData; + IUnknown **lpDest = lpvDest; - if (lpUnknown) - IUnknown_AddRef(lpUnknown); - if (*lpDest) - IUnknown_Release(*lpDest); - *lpDest = lpUnknown; - } else { - /* Copy the data over */ - memcpy(lpvDest, pvData, psa->cbElements); - } + if (lpUnknown) + IUnknown_AddRef(lpUnknown); + if (*lpDest) + IUnknown_Release(*lpDest); + *lpDest = lpUnknown; } + else if (psa->fFeatures & FADF_RECORD) + { + IRecordInfo *record; + + SafeArrayGetRecordInfo(psa, &record); + hRet = IRecordInfo_RecordCopy(record, pvData, lpvDest); + IRecordInfo_Release(record); + } else + /* Copy the data over */ + memcpy(lpvDest, pvData, psa->cbElements); } SafeArrayUnlock(psa); } @@ -946,18 +978,26 @@ HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData else *lpDest = NULL; } - else + else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { - if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) - { - LPUNKNOWN *lpUnknown = lpvSrc; + IUnknown **src_unk = lpvSrc; + IUnknown **dest_unk = pvData; - if (*lpUnknown) - IUnknown_AddRef(*lpUnknown); - } + if (*src_unk) + IUnknown_AddRef(*src_unk); + *dest_unk = *src_unk; + } + else if (psa->fFeatures & FADF_RECORD) + { + IRecordInfo *record; + + SafeArrayGetRecordInfo(psa, &record); + hRet = IRecordInfo_RecordCopy(record, lpvSrc, pvData); + IRecordInfo_Release(record); + } + else /* Copy the data over */ memcpy(pvData, lpvSrc, psa->cbElements); - } } SafeArrayUnlock(psa); } @@ -1087,18 +1127,17 @@ UINT WINAPI SafeArrayGetElemsize(SAFEARRAY *psa) */ HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData) { + HRESULT hr; + TRACE("(%p,%p)\n", psa, ppvData); if(!psa || !ppvData) return E_INVALIDARG; - if (SUCCEEDED(SafeArrayLock(psa))) - { - *ppvData = psa->pvData; - return S_OK; - } - *ppvData = NULL; - return E_UNEXPECTED; + hr = SafeArrayLock(psa); + *ppvData = SUCCEEDED(hr) ? psa->pvData : NULL; + + return hr; } @@ -1207,6 +1246,8 @@ HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvDa */ HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa) { + HRESULT hr; + TRACE("(%p)\n", psa); if (!psa) @@ -1216,8 +1257,9 @@ HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa) return DISP_E_ARRAYISLOCKED; /* Can't delete a locked array */ /* Delete the actual item data */ - if (FAILED(SAFEARRAY_DestroyData(psa, 0))) - return E_UNEXPECTED; + hr = SAFEARRAY_DestroyData(psa, 0); + if (FAILED(hr)) + return hr; if (psa->pvData) { @@ -1276,10 +1318,7 @@ HRESULT WINAPI SafeArrayCopyData(SAFEARRAY *psaSource, SAFEARRAY *psaTarget) psaTarget->rgsabound[dim].cElements) return E_INVALIDARG; - if (SUCCEEDED(SAFEARRAY_DestroyData(psaTarget, 0)) && - SUCCEEDED(SAFEARRAY_CopyData(psaSource, psaTarget))) - return S_OK; - return E_UNEXPECTED; + return SAFEARRAY_CopyData(psaSource, psaTarget); } /************************************************************************ @@ -1349,9 +1388,9 @@ HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut) if (psa->fFeatures & (FADF_RECORD|FADF_HAVEIID|FADF_HAVEVARTYPE)) { VARTYPE vt; - if (FAILED(SafeArrayGetVartype(psa, &vt))) - hRet = E_UNEXPECTED; - else + + hRet = SafeArrayGetVartype(psa, &vt); + if (SUCCEEDED(hRet)) hRet = SafeArrayAllocDescriptorEx(vt, psa->cDims, ppsaOut); } else @@ -1359,7 +1398,7 @@ HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut) hRet = SafeArrayAllocDescriptor(psa->cDims, ppsaOut); if (SUCCEEDED(hRet)) { - (*ppsaOut)->fFeatures = psa->fFeatures & ~FADF_CREATEVECTOR; + (*ppsaOut)->fFeatures = psa->fFeatures & ~ignored_copy_features; (*ppsaOut)->cbElements = psa->cbElements; } } @@ -1370,19 +1409,23 @@ HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut) memcpy((*ppsaOut)->rgsabound, psa->rgsabound, psa->cDims * sizeof(SAFEARRAYBOUND)); (*ppsaOut)->pvData = SAFEARRAY_Malloc(SAFEARRAY_GetCellCount(psa) * psa->cbElements); - - if ((*ppsaOut)->pvData) + if (!(*ppsaOut)->pvData) { - hRet = SAFEARRAY_CopyData(psa, *ppsaOut); - - if (SUCCEEDED(hRet)) - return hRet; - - SAFEARRAY_Free((*ppsaOut)->pvData); + SafeArrayDestroyDescriptor(*ppsaOut); + *ppsaOut = NULL; + return E_OUTOFMEMORY; + } + + hRet = SAFEARRAY_CopyData(psa, *ppsaOut); + if (FAILED(hRet)) + { + SAFEARRAY_Free((*ppsaOut)->pvData); + SafeArrayDestroyDescriptor(*ppsaOut); + *ppsaOut = NULL; + return hRet; } - SafeArrayDestroyDescriptor(*ppsaOut); } - *ppsaOut = NULL; + return hRet; } @@ -1405,6 +1448,7 @@ HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut) HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound) { SAFEARRAYBOUND *oldBounds; + HRESULT hr; TRACE("(%p,%p)\n", psa, psabound); @@ -1414,8 +1458,9 @@ HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound) if (psa->cLocks > 0) return DISP_E_ARRAYISLOCKED; - if (FAILED(SafeArrayLock(psa))) - return E_UNEXPECTED; + hr = SafeArrayLock(psa); + if (FAILED(hr)) + return hr; oldBounds = psa->rgsabound; oldBounds->lLbound = psabound->lLbound; @@ -1448,7 +1493,7 @@ HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound) if (!(pvNewData = SAFEARRAY_Malloc(ulNewSize))) { SafeArrayUnlock(psa); - return E_UNEXPECTED; + return E_OUTOFMEMORY; } memcpy(pvNewData, psa->pvData, ulOldSize); diff --git a/reactos/dll/win32/oleaut32/tmarshal.c b/reactos/dll/win32/oleaut32/tmarshal.c index efeeb25aec2..40647964801 100644 --- a/reactos/dll/win32/oleaut32/tmarshal.c +++ b/reactos/dll/win32/oleaut32/tmarshal.c @@ -281,8 +281,16 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) { sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win%u",tlguid,ver,(sizeof(void*) == 8) ? 64 : 32); tlfnlen = sizeof(tlfn); if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) { - ERR("Could not get typelib fn?\n"); - return E_FAIL; +#ifdef _WIN64 + sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win32",tlguid,ver); + tlfnlen = sizeof(tlfn); + if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) { +#endif + ERR("Could not get typelib fn?\n"); + return E_FAIL; +#ifdef _WIN64 + } +#endif } MultiByteToWideChar(CP_ACP, 0, tlfn, -1, tlfnW, sizeof(tlfnW) / sizeof(tlfnW[0])); hres = LoadTypeLib(tlfnW,&tl); @@ -622,14 +630,11 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) { } /* Whether we pass this type by reference or by value */ -static int +static BOOL _passbyref(const TYPEDESC *td, ITypeInfo *tinfo) { - if (td->vt == VT_USERDEFINED || - td->vt == VT_VARIANT || - td->vt == VT_PTR) - return 1; - - return 0; + return (td->vt == VT_USERDEFINED || + td->vt == VT_VARIANT || + td->vt == VT_PTR); } static HRESULT diff --git a/reactos/dll/win32/oleaut32/typelib.c b/reactos/dll/win32/oleaut32/typelib.c index 451c43f16da..95d29864545 100644 --- a/reactos/dll/win32/oleaut32/typelib.c +++ b/reactos/dll/win32/oleaut32/typelib.c @@ -325,10 +325,23 @@ static WCHAR *get_lcid_subkey( LCID lcid, SYSKIND syskind, WCHAR *buffer ) static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib); +struct tlibredirect_data +{ + ULONG size; + DWORD res; + ULONG name_len; + ULONG name_offset; + LANGID langid; + WORD flags; + ULONG help_len; + ULONG help_offset; + WORD major_version; + WORD minor_version; +}; /* Get the path to a registered type library. Helper for QueryPathOfRegTypeLib. */ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin, - SYSKIND syskind, LCID lcid, LPBSTR path ) + SYSKIND syskind, LCID lcid, BSTR *path, BOOL redir ) { HRESULT hr = TYPE_E_LIBNOTREGISTERED; LCID myLCID = lcid; @@ -339,6 +352,30 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin, TRACE_(typelib)("(%s, %x.%x, 0x%x, %p)\n", debugstr_guid(guid), wMaj, wMin, lcid, path); + if (redir) + { + ACTCTX_SECTION_KEYED_DATA data; + + data.cbSize = sizeof(data); + if (FindActCtxSectionGuid( 0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, guid, &data )) + { + struct tlibredirect_data *tlib = (struct tlibredirect_data*)data.lpData; + WCHAR *nameW; + DWORD len; + + if (tlib->major_version != wMaj || tlib->minor_version < wMin) + return TYPE_E_LIBNOTREGISTERED; + + nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset); + len = SearchPathW( NULL, nameW, NULL, sizeof(Path)/sizeof(WCHAR), Path, NULL ); + if (!len) return TYPE_E_LIBNOTREGISTERED; + + TRACE_(typelib)("got path from context %s\n", debugstr_w(Path)); + *path = SysAllocString( Path ); + return S_OK; + } + } + if (!find_typelib_key( guid, &wMaj, &wMin )) return TYPE_E_LIBNOTREGISTERED; get_typelib_key( guid, wMaj, wMin, buffer ); @@ -410,12 +447,14 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin, */ HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path ) { + BOOL redir = TRUE; #ifdef _WIN64 - HRESULT hres = query_typelib_path( guid, wMaj, wMin, SYS_WIN64, lcid, path ); + HRESULT hres = query_typelib_path( guid, wMaj, wMin, SYS_WIN64, lcid, path, TRUE ); if(SUCCEEDED(hres)) return hres; + redir = FALSE; #endif - return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path ); + return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path, redir ); } /****************************************************************************** @@ -536,6 +575,20 @@ HRESULT WINAPI LoadRegTypeLib( { res= LoadTypeLib(bstr, ppTLib); SysFreeString(bstr); + + if (*ppTLib) + { + TLIBATTR *attr; + + res = ITypeLib_GetLibAttr(*ppTLib, &attr); + if (res == S_OK && (attr->wMajorVerNum != wVerMajor || attr->wMinorVerNum < wVerMinor)) + { + ITypeLib_ReleaseTLibAttr(*ppTLib, attr); + ITypeLib_Release(*ppTLib); + *ppTLib = NULL; + res = TYPE_E_LIBNOTREGISTERED; + } + } } TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib); @@ -551,6 +604,57 @@ static const WCHAR HELPDIRW[] = {'H','E','L','P','D','I','R',0}; static const WCHAR ProxyStubClsidW[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d',0}; static const WCHAR ProxyStubClsid32W[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0}; +static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *tattr, DWORD flag) +{ + WCHAR keyName[60]; + HKEY key, subKey; + + static const WCHAR PSOA[] = {'{','0','0','0','2','0','4','2','4','-', + '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-', + '0','0','0','0','0','0','0','0','0','0','4','6','}',0}; + + get_interface_key( &tattr->guid, keyName ); + if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0, + KEY_WRITE | flag, NULL, &key, NULL) == ERROR_SUCCESS) + { + if (name) + RegSetValueExW(key, NULL, 0, REG_SZ, + (BYTE *)name, (strlenW(name)+1) * sizeof(OLECHAR)); + + if (RegCreateKeyExW(key, ProxyStubClsidW, 0, NULL, 0, + KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) { + RegSetValueExW(subKey, NULL, 0, REG_SZ, + (const BYTE *)PSOA, sizeof PSOA); + RegCloseKey(subKey); + } + + if (RegCreateKeyExW(key, ProxyStubClsid32W, 0, NULL, 0, + KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) { + RegSetValueExW(subKey, NULL, 0, REG_SZ, + (const BYTE *)PSOA, sizeof PSOA); + RegCloseKey(subKey); + } + + if (RegCreateKeyExW(key, TypeLibW, 0, NULL, 0, + KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) + { + WCHAR buffer[40]; + static const WCHAR fmtver[] = {'%','x','.','%','x',0 }; + static const WCHAR VersionW[] = {'V','e','r','s','i','o','n',0}; + + StringFromGUID2(&libattr->guid, buffer, 40); + RegSetValueExW(subKey, NULL, 0, REG_SZ, + (BYTE *)buffer, (strlenW(buffer)+1) * sizeof(WCHAR)); + sprintfW(buffer, fmtver, libattr->wMajorVerNum, libattr->wMinorVerNum); + RegSetValueExW(subKey, VersionW, 0, REG_SZ, + (BYTE*)buffer, (strlenW(buffer)+1) * sizeof(WCHAR)); + RegCloseKey(subKey); + } + + RegCloseKey(key); + } +} + /****************************************************************************** * RegisterTypeLib [OLEAUT32.163] * Adds information about a type library to the System Registry @@ -569,9 +673,6 @@ HRESULT WINAPI RegisterTypeLib( OLECHAR * szHelpDir) /* [in] dir to the helpfile for the library, may be NULL*/ { - static const WCHAR PSOA[] = {'{','0','0','0','2','0','4','2','4','-', - '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-', - '0','0','0','0','0','0','0','0','0','0','4','6','}',0}; HRESULT res; TLIBATTR *attr; WCHAR keyName[60]; @@ -744,47 +845,16 @@ HRESULT WINAPI RegisterTypeLib( if ((kind == TKIND_INTERFACE && (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) || kind == TKIND_DISPATCH) { - /* register interface<->typelib coupling */ - get_interface_key( &tattr->guid, keyName ); - if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0, - KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) - { - if (name) - RegSetValueExW(key, NULL, 0, REG_SZ, - (BYTE *)name, (strlenW(name)+1) * sizeof(OLECHAR)); + BOOL is_wow64; + DWORD opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); - if (RegCreateKeyExW(key, ProxyStubClsidW, 0, NULL, 0, - KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) { - RegSetValueExW(subKey, NULL, 0, REG_SZ, - (const BYTE *)PSOA, sizeof PSOA); - RegCloseKey(subKey); - } + /* register interface<->typelib coupling */ + TLB_register_interface(attr, name, tattr, 0); - if (RegCreateKeyExW(key, ProxyStubClsid32W, 0, NULL, 0, - KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) { - RegSetValueExW(subKey, NULL, 0, REG_SZ, - (const BYTE *)PSOA, sizeof PSOA); - RegCloseKey(subKey); - } - - if (RegCreateKeyExW(key, TypeLibW, 0, NULL, 0, - KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) - { - WCHAR buffer[40]; - static const WCHAR fmtver[] = {'%','x','.','%','x',0 }; - static const WCHAR VersionW[] = {'V','e','r','s','i','o','n',0}; - - StringFromGUID2(&attr->guid, buffer, 40); - RegSetValueExW(subKey, NULL, 0, REG_SZ, - (BYTE *)buffer, (strlenW(buffer)+1) * sizeof(WCHAR)); - sprintfW(buffer, fmtver, attr->wMajorVerNum, attr->wMinorVerNum); - RegSetValueExW(subKey, VersionW, 0, REG_SZ, - (BYTE*)buffer, (strlenW(buffer)+1) * sizeof(WCHAR)); - RegCloseKey(subKey); - } - - RegCloseKey(key); - } + /* register TLBs into the opposite registry view, too */ + if(opposite == KEY_WOW64_32KEY || + (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)) + TLB_register_interface(attr, name, tattr, opposite); } ITypeInfo_ReleaseTypeAttr(tinfo, tattr); @@ -847,7 +917,7 @@ HRESULT WINAPI UnRegisterTypeLib( } /* get the path to the typelib on disk */ - if (query_typelib_path(libid, wVerMajor, wVerMinor, syskind, lcid, &tlibPath) != S_OK) { + if (query_typelib_path(libid, wVerMajor, wVerMinor, syskind, lcid, &tlibPath, FALSE) != S_OK) { result = E_INVALIDARG; goto end; } @@ -1928,6 +1998,9 @@ static TLBString *TLB_append_str(struct list *string_list, BSTR new_str) { TLBString *str; + if(!new_str) + return NULL; + LIST_FOR_EACH_ENTRY(str, string_list, TLBString, entry) { if (strcmpW(str->str, new_str) == 0) return str; @@ -2297,24 +2370,17 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx ) case VT_BSTR :{ char * ptr; MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK ); - if(size < 0) { - char next; - DWORD origPos = MSFT_Tell(pcx), nullPos; - - do { - MSFT_Read(&next, 1, pcx, DO_NOT_SEEK); - } while (next); - nullPos = MSFT_Tell(pcx); - size = nullPos - origPos; - MSFT_Seek(pcx, origPos); - } - ptr = heap_alloc_zero(size);/* allocate temp buffer */ - MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */ - V_BSTR(pVar)=SysAllocStringLen(NULL,size); - /* FIXME: do we need a AtoW conversion here? */ - V_UNION(pVar, bstrVal[size])='\0'; - while(size--) V_UNION(pVar, bstrVal[size])=ptr[size]; - heap_free(ptr); + if(size == -1){ + V_BSTR(pVar) = NULL; + }else{ + ptr = heap_alloc_zero(size); + MSFT_Read(ptr, size, pcx, DO_NOT_SEEK); + V_BSTR(pVar)=SysAllocStringLen(NULL,size); + /* FIXME: do we need a AtoW conversion here? */ + V_UNION(pVar, bstrVal[size])='\0'; + while(size--) V_UNION(pVar, bstrVal[size])=ptr[size]; + heap_free(ptr); + } } size=-4; break; /* FIXME: this will not work AT ALL when the variant contains a pointer */ @@ -2380,7 +2446,7 @@ static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd) TRACE_(typelib)("vt type = %X\n", pTd->vt); } -static int TLB_is_propgetput(INVOKEKIND invkind) +static BOOL TLB_is_propgetput(INVOKEKIND invkind) { return (invkind == INVOKE_PROPERTYGET || invkind == INVOKE_PROPERTYPUT || @@ -3110,7 +3176,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid, /* Read in NE header */ nehdoffset = LZSeek( lzfd, 0, SEEK_CUR ); - if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return 0; + if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return FALSE; resTabSize = nehd.ne_restab - nehd.ne_rsrctab; if ( !resTabSize ) @@ -3378,8 +3444,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath if(file != pszFileName) heap_free(file); - h = CreateFileW(pszPath, GENERIC_READ, 0, NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); + h = CreateFileW(pszPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(h != INVALID_HANDLE_VALUE){ FILE_NAME_INFORMATION *info; char data[MAX_PATH * sizeof(WCHAR) + sizeof(info->FileNameLength)]; @@ -3519,7 +3584,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) cx.length = dwTLBLength; /* read header */ - MSFT_ReadLEDWords((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0); + MSFT_ReadLEDWords(&tlbHeader, sizeof(tlbHeader), &cx, 0); TRACE_(typelib)("header:\n"); TRACE_(typelib)("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 ); if (tlbHeader.magic1 != MSFT_SIGNATURE) { @@ -3558,7 +3623,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind); pTypeLibImpl->ver_major = LOWORD(tlbHeader.version); pTypeLibImpl->ver_minor = HIWORD(tlbHeader.version); - pTypeLibImpl->libflags = (WORD) tlbHeader.flags & 0xffff;/* check mask */ + pTypeLibImpl->libflags = ((WORD) tlbHeader.flags & 0xffff) /* check mask */ | LIBFLAG_FHASDISKIMAGE; pTypeLibImpl->set_lcid = tlbHeader.lcid2; pTypeLibImpl->lcid = tlbHeader.lcid; @@ -4514,7 +4579,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) len = SLTG_ReadLibBlk(pLibBlk, pTypeLibImpl); - /* Now there's 0x40 bytes of 0xffff with the numbers 0 to TypeInfoCount + /* Now there are 0x40 bytes of 0xffff with the numbers 0 to TypeInfoCount interspersed */ len += 0x40; @@ -5119,8 +5184,8 @@ static HRESULT WINAPI ITypeLib2_fnIsName( *pfName=FALSE; ITypeLib2_fnIsName_exit: - TRACE("(%p)slow! search for %s: %s found!\n", This, - debugstr_w(szNameBuf), *pfName?"NOT":""); + TRACE("(%p)slow! search for %s: %sfound!\n", This, + debugstr_w(szNameBuf), *pfName ? "" : "NOT "); return S_OK; } @@ -5150,26 +5215,30 @@ static HRESULT WINAPI ITypeLib2_fnFindName( return E_INVALIDARG; len = (lstrlenW(name) + 1)*sizeof(WCHAR); - for(tic = 0; tic < This->TypeInfoCount; ++tic) { + for(tic = 0; count < *found && tic < This->TypeInfoCount; ++tic) { ITypeInfoImpl *pTInfo = This->typeinfos[tic]; TLBVarDesc *var; UINT fdc; - if(!TLB_str_memcmp(name, pTInfo->Name, len)) goto ITypeLib2_fnFindName_exit; + if(!TLB_str_memcmp(name, pTInfo->Name, len)) { + memid[count] = MEMBERID_NIL; + goto ITypeLib2_fnFindName_exit; + } + for(fdc = 0; fdc < pTInfo->cFuncs; ++fdc) { TLBFuncDesc *func = &pTInfo->funcdescs[fdc]; - int pc; - if(!TLB_str_memcmp(name, func->Name, len)) goto ITypeLib2_fnFindName_exit; - for(pc = 0; pc < func->funcdesc.cParams; pc++) { - if(!TLB_str_memcmp(name, func->pParamDesc[pc].Name, len)) - goto ITypeLib2_fnFindName_exit; + if(!TLB_str_memcmp(name, func->Name, len)) { + memid[count] = func->funcdesc.memid; + goto ITypeLib2_fnFindName_exit; } } var = TLB_get_vardesc_by_name(pTInfo->vardescs, pTInfo->cVars, name); - if (var) + if (var) { + memid[count] = var->vardesc.memid; goto ITypeLib2_fnFindName_exit; + } continue; ITypeLib2_fnFindName_exit: @@ -5317,7 +5386,7 @@ static HRESULT TLB_copy_all_custdata(struct list *custdata_list, CUSTDATA *pCust ct = list_count(custdata_list); - pCustData->prgCustData = heap_alloc_zero(ct * sizeof(CUSTDATAITEM)); + pCustData->prgCustData = CoTaskMemAlloc(ct * sizeof(CUSTDATAITEM)); if(!pCustData->prgCustData) return E_OUTOFMEMORY; @@ -5401,9 +5470,10 @@ static HRESULT WINAPI ITypeLibComp_fnBind( BINDPTR * pBindPtr) { ITypeLibImpl *This = impl_from_ITypeComp(iface); - int typemismatch=0, i; + BOOL typemismatch = FALSE; + int i; - TRACE("(%s, 0x%x, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr); + TRACE("(%p)->(%s, 0x%x, 0x%x, %p, %p, %p)\n", This, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr); *pDescKind = DESCKIND_NONE; pBindPtr->lptcomp = NULL; @@ -5442,7 +5512,7 @@ static HRESULT WINAPI ITypeLibComp_fnBind( return S_OK; } else if (hr == TYPE_E_TYPEMISMATCH) - typemismatch = 1; + typemismatch = TRUE; } if ((pTypeInfo->typekind == TKIND_COCLASS) && @@ -5513,7 +5583,7 @@ static HRESULT WINAPI ITypeLibComp_fnBind( return S_OK; } else if (hr == TYPE_E_TYPEMISMATCH) - typemismatch = 1; + typemismatch = TRUE; } } @@ -7687,7 +7757,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( ref_type->pImpTLInfo->wVersionMajor, ref_type->pImpTLInfo->wVersionMinor, This->pTypeLib->syskind, - ref_type->pImpTLInfo->lcid, &libnam); + ref_type->pImpTLInfo->lcid, &libnam, TRUE); if(FAILED(result)) libnam = SysAllocString(ref_type->pImpTLInfo->name); @@ -8514,7 +8584,7 @@ static HRESULT WINAPI ITypeComp_fnBind( for(fdc = 0; fdc < This->cFuncs; ++fdc){ pFDesc = &This->funcdescs[fdc]; - if (!strcmpiW(TLB_get_bstr(pFDesc->Name), szName)) { + if (!lstrcmpiW(TLB_get_bstr(pFDesc->Name), szName)) { if (!wFlags || (pFDesc->funcdesc.invkind & wFlags)) break; else @@ -8547,7 +8617,7 @@ static HRESULT WINAPI ITypeComp_fnBind( return S_OK; } } - /* FIXME: search each inherited interface, not just the first */ + if (hr == DISP_E_MEMBERNOTFOUND && This->impltypes) { /* recursive search */ ITypeInfo *pTInfo; @@ -8563,6 +8633,13 @@ static HRESULT WINAPI ITypeComp_fnBind( { hr = ITypeComp_Bind(pTComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr); ITypeComp_Release(pTComp); + if (SUCCEEDED(hr) && *pDescKind == DESCKIND_FUNCDESC && + This->typekind == TKIND_DISPATCH) + { + FUNCDESC *tmp = pBindPtr->lpfuncdesc; + hr = TLB_AllocAndInitFuncDesc(tmp, &pBindPtr->lpfuncdesc, TRUE); + SysFreeString((BSTR)tmp); + } return hr; } WARN("Could not search inherited interface!\n"); @@ -9181,41 +9258,6 @@ static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *o out_size = &junk2; vt = desc->vt & VT_TYPEMASK; - switch(vt){ - case VT_INT: - subtype = VT_I4; - break; - case VT_UINT: - subtype = VT_UI4; - break; - case VT_VOID: - subtype = VT_EMPTY; - break; - default: - subtype = vt; - break; - } - - switch(vt){ - case VT_INT: - case VT_UINT: - case VT_I1: - case VT_UI1: - case VT_I2: - case VT_UI2: - case VT_I4: - case VT_UI4: - case VT_BOOL: - case VT_R4: - case VT_ERROR: - case VT_BSTR: - case VT_HRESULT: - case VT_CY: - case VT_VOID: - case VT_VARIANT: - *out_mix = subtype; - return 0x80000000 | (subtype << 16) | desc->vt; - } if(vt == VT_PTR || vt == VT_SAFEARRAY){ DWORD mix; @@ -9232,9 +9274,25 @@ static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *o encoded[1] = desc->u.hreftype; *out_mix = 0x7FFF; /* FIXME: Should get TYPEKIND of the hreftype, e.g. TKIND_ENUM => VT_I4 */ }else{ - FIXME("Don't know what to do! VT: 0x%x\n", desc->vt); - *out_mix = desc->vt; - return 0x80000000 | (desc->vt << 16) | desc->vt; + TRACE("Mixing in-place, VT: 0x%x\n", desc->vt); + + switch(vt){ + case VT_INT: + subtype = VT_I4; + break; + case VT_UINT: + subtype = VT_UI4; + break; + case VT_VOID: + subtype = VT_EMPTY; + break; + default: + subtype = vt; + break; + } + + *out_mix = subtype; + return 0x80000000 | (subtype << 16) | desc->vt; } data = file->typdesc_seg.data; @@ -9626,7 +9684,7 @@ static DWORD WMSFT_compile_typeinfo(ITypeInfoImpl *info, INT16 index, WMSFT_TLBF size = sizeof(MSFT_TypeInfoBase); if(data){ - MSFT_TypeInfoBase *base = (void*)data; + MSFT_TypeInfoBase *base = (MSFT_TypeInfoBase*)data; if(info->wTypeFlags & TYPEFLAG_FDUAL) base->typekind = TKIND_DISPATCH; else @@ -10727,8 +10785,17 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(ICreateTypeInfo2 *iface, UINT index, LPOLESTR name) { ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); - FIXME("%p %u %s - stub\n", This, index, wine_dbgstr_w(name)); - return E_NOTIMPL; + + TRACE("%p %u %s\n", This, index, wine_dbgstr_w(name)); + + if(!name) + return E_INVALIDARG; + + if(index >= This->cVars) + return TYPE_E_ELEMENTNOTFOUND; + + This->vardescs[index].Name = TLB_append_str(&This->pTypeLib->name_list, name); + return S_OK; } static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(ICreateTypeInfo2 *iface, @@ -10768,8 +10835,19 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(ICreateTypeInfo2 *ifac UINT index, LPOLESTR docString) { ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); - FIXME("%p %u %s - stub\n", This, index, wine_dbgstr_w(docString)); - return E_NOTIMPL; + TLBFuncDesc *func_desc = &This->funcdescs[index]; + + TRACE("%p %u %s\n", This, index, wine_dbgstr_w(docString)); + + if(!docString) + return E_INVALIDARG; + + if(index >= This->cFuncs) + return TYPE_E_ELEMENTNOTFOUND; + + func_desc->HelpString = TLB_append_str(&This->pTypeLib->string_list, docString); + + return S_OK; } static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(ICreateTypeInfo2 *iface, @@ -11195,8 +11273,7 @@ void WINAPI ClearCustData(CUSTDATA *lpCust) for (i = 0; i < lpCust->cCustData; i++) VariantClear(&lpCust->prgCustData[i].varValue); - /* FIXME - Should be using a per-thread IMalloc */ - heap_free(lpCust->prgCustData); + CoTaskMemFree(lpCust->prgCustData); lpCust->prgCustData = NULL; } lpCust->cCustData = 0; diff --git a/reactos/dll/win32/oleaut32/usrmarshal.c b/reactos/dll/win32/oleaut32/usrmarshal.c index 37e6e617c62..48c9625120c 100644 --- a/reactos/dll/win32/oleaut32/usrmarshal.c +++ b/reactos/dll/win32/oleaut32/usrmarshal.c @@ -181,7 +181,7 @@ typedef struct DWORD switch_is; } variant_wire_t; -static unsigned int get_type_size(ULONG *pFlags, VARTYPE vt) +unsigned int get_type_size(ULONG *pFlags, VARTYPE vt) { if (vt & VT_ARRAY) return 4; @@ -197,6 +197,7 @@ static unsigned int get_type_size(ULONG *pFlags, VARTYPE vt) return sizeof(SHORT); case VT_I4: case VT_UI4: + case VT_HRESULT: return sizeof(LONG); case VT_INT: case VT_UINT: diff --git a/reactos/dll/win32/oleaut32/varformat.c b/reactos/dll/win32/oleaut32/varformat.c index 18279093c93..7d092ee9050 100644 --- a/reactos/dll/win32/oleaut32/varformat.c +++ b/reactos/dll/win32/oleaut32/varformat.c @@ -2397,7 +2397,7 @@ HRESULT WINAPI VarFormatPercent(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT if (SUCCEEDED(hRet)) { DWORD dwLen = strlenW(*pbstrOut); - BOOL bBracket = (*pbstrOut)[dwLen] == ')' ? TRUE : FALSE; + BOOL bBracket = (*pbstrOut)[dwLen] == ')'; dwLen -= bBracket; memcpy(buff, *pbstrOut, dwLen * sizeof(WCHAR)); diff --git a/reactos/dll/win32/oleaut32/variant.c b/reactos/dll/win32/oleaut32/variant.c index 189840dbdeb..e6f6372102a 100644 --- a/reactos/dll/win32/oleaut32/variant.c +++ b/reactos/dll/win32/oleaut32/variant.c @@ -559,7 +559,8 @@ void WINAPI VariantInit(VARIANTARG* pVarg) { TRACE("(%p)\n", pVarg); - V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */ + /* Win8.1 zeroes whole struct. Previous implementations don't set any other fields. */ + V_VT(pVarg) = VT_EMPTY; } HRESULT VARIANT_ClearInd(VARIANTARG *pVarg) @@ -678,34 +679,32 @@ HRESULT WINAPI VariantClear(VARIANTARG* pVarg) /****************************************************************************** * Copy an IRecordInfo object contained in a variant. */ -static HRESULT VARIANT_CopyIRecordInfo(struct __tagBRECORD* pBr) +static HRESULT VARIANT_CopyIRecordInfo(VARIANT *dest, VARIANT *src) { - HRESULT hres = S_OK; + struct __tagBRECORD *dest_rec = &V_UNION(dest, brecVal); + struct __tagBRECORD *src_rec = &V_UNION(src, brecVal); + HRESULT hr = S_OK; + ULONG size; - if (pBr->pRecInfo) + if (!src_rec->pRecInfo) { - ULONG ulSize; - - hres = IRecordInfo_GetSize(pBr->pRecInfo, &ulSize); - if (SUCCEEDED(hres)) - { - PVOID pvRecord = HeapAlloc(GetProcessHeap(), 0, ulSize); - if (!pvRecord) - hres = E_OUTOFMEMORY; - else - { - memcpy(pvRecord, pBr->pvRecord, ulSize); - pBr->pvRecord = pvRecord; - - hres = IRecordInfo_RecordCopy(pBr->pRecInfo, pvRecord, pvRecord); - if (SUCCEEDED(hres)) - IRecordInfo_AddRef(pBr->pRecInfo); - } - } + if (src_rec->pvRecord) return E_INVALIDARG; + return S_OK; } - else if (pBr->pvRecord) - hres = E_INVALIDARG; - return hres; + + hr = IRecordInfo_GetSize(src_rec->pRecInfo, &size); + if (FAILED(hr)) return hr; + + /* This could look cleaner if only RecordCreate() was used, but native doesn't use it. + Memory should be allocated in a same way as RecordCreate() does, so RecordDestroy() + could free it later. */ + dest_rec->pvRecord = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (!dest_rec->pvRecord) return E_OUTOFMEMORY; + + dest_rec->pRecInfo = src_rec->pRecInfo; + IRecordInfo_AddRef(src_rec->pRecInfo); + + return IRecordInfo_RecordCopy(src_rec->pRecInfo, src_rec->pvRecord, dest_rec->pvRecord); } /****************************************************************************** @@ -755,29 +754,25 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc) if (!V_ISBYREF(pvargSrc)) { - if (V_ISARRAY(pvargSrc)) - { - if (V_ARRAY(pvargSrc)) - hres = SafeArrayCopy(V_ARRAY(pvargSrc), &V_ARRAY(pvargDest)); - } - else if (V_VT(pvargSrc) == VT_BSTR) + switch (V_VT(pvargSrc)) { + case VT_BSTR: V_BSTR(pvargDest) = SysAllocStringByteLen((char*)V_BSTR(pvargSrc), SysStringByteLen(V_BSTR(pvargSrc))); if (!V_BSTR(pvargDest)) - { - TRACE("!V_BSTR(pvargDest), SysAllocStringByteLen() failed to allocate %d bytes\n", SysStringByteLen(V_BSTR(pvargSrc))); hres = E_OUTOFMEMORY; - } - } - else if (V_VT(pvargSrc) == VT_RECORD) - { - hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal)); - } - else if (V_VT(pvargSrc) == VT_DISPATCH || - V_VT(pvargSrc) == VT_UNKNOWN) - { + break; + case VT_RECORD: + hres = VARIANT_CopyIRecordInfo(pvargDest, pvargSrc); + break; + case VT_DISPATCH: + case VT_UNKNOWN: + V_UNKNOWN(pvargDest) = V_UNKNOWN(pvargSrc); if (V_UNKNOWN(pvargSrc)) IUnknown_AddRef(V_UNKNOWN(pvargSrc)); + break; + default: + if (V_ISARRAY(pvargSrc)) + hres = SafeArrayCopy(V_ARRAY(pvargSrc), &V_ARRAY(pvargDest)); } } } @@ -896,8 +891,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc) } else if (V_VT(pSrc) == (VT_RECORD|VT_BYREF)) { - V_UNION(pvargDest,brecVal) = V_UNION(pvargSrc,brecVal); - hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal)); + hres = VARIANT_CopyIRecordInfo(pvargDest, pvargSrc); } else if (V_VT(pSrc) == (VT_DISPATCH|VT_BYREF) || V_VT(pSrc) == (VT_UNKNOWN|VT_BYREF)) @@ -1296,6 +1290,10 @@ INT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME lpSt, double *pDateOut) if (lpSt->wMonth > 12) return FALSE; + if (lpSt->wDay > 31) + return FALSE; + if ((short)lpSt->wYear < 0) + return FALSE; ud.st = *lpSt; return VarDateFromUdate(&ud, 0, pDateOut) == S_OK; diff --git a/reactos/dll/win32/oleaut32/variant.h b/reactos/dll/win32/oleaut32/variant.h index b2c0d614e41..dceac5c7e56 100644 --- a/reactos/dll/win32/oleaut32/variant.h +++ b/reactos/dll/win32/oleaut32/variant.h @@ -121,7 +121,7 @@ typedef struct tagVARIANT_NUMBER_CHARS WCHAR cCurrencyDigitSeparator; } VARIANT_NUMBER_CHARS; - +unsigned int get_type_size(ULONG*, VARTYPE); BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *) DECLSPEC_HIDDEN; HRESULT VARIANT_ClearInd(VARIANTARG *) DECLSPEC_HIDDEN; BOOL get_date_format(LCID, DWORD, const SYSTEMTIME *, diff --git a/reactos/dll/win32/oleaut32/vartype.c b/reactos/dll/win32/oleaut32/vartype.c index 78cd6e32f82..a3103872844 100644 --- a/reactos/dll/win32/oleaut32/vartype.c +++ b/reactos/dll/win32/oleaut32/vartype.c @@ -112,6 +112,7 @@ static HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut, return DISP_E_BADVARTYPE; /* Get the default 'value' property from the IDispatch */ + VariantInit(&srcVar); hRet = IDispatch_Invoke(pdispIn, DISPID_VALUE, &IID_NULL, lcid, DISPATCH_PROPERTYGET, &emptyParams, &srcVar, NULL, NULL); @@ -351,7 +352,7 @@ HRESULT WINAPI VarI1FromR4(FLOAT fltIn, signed char* pcOut) */ HRESULT WINAPI VarI1FromR8(double dblIn, signed char* pcOut) { - if (dblIn < (double)I1_MIN || dblIn > (double)I1_MAX) + if (dblIn < I1_MIN - 0.5 || dblIn >= I1_MAX + 0.5) return DISP_E_OVERFLOW; VARIANT_DutchRound(CHAR, dblIn, *pcOut); return S_OK; @@ -641,7 +642,7 @@ HRESULT WINAPI VarUI1FromR4(FLOAT fltIn, BYTE* pbOut) */ HRESULT WINAPI VarUI1FromR8(double dblIn, BYTE* pbOut) { - if (dblIn < -0.5 || dblIn > (double)UI1_MAX) + if (dblIn < -0.5 || dblIn >= UI1_MAX + 0.5) return DISP_E_OVERFLOW; VARIANT_DutchRound(BYTE, dblIn, *pbOut); return S_OK; @@ -947,7 +948,7 @@ HRESULT WINAPI VarI2FromR4(FLOAT fltIn, SHORT* psOut) */ HRESULT WINAPI VarI2FromR8(double dblIn, SHORT* psOut) { - if (dblIn < (double)I2_MIN || dblIn > (double)I2_MAX) + if (dblIn < I2_MIN - 0.5 || dblIn >= I2_MAX + 0.5) return DISP_E_OVERFLOW; VARIANT_DutchRound(SHORT, dblIn, *psOut); return S_OK; @@ -1259,7 +1260,7 @@ HRESULT WINAPI VarUI2FromR4(FLOAT fltIn, USHORT* pusOut) */ HRESULT WINAPI VarUI2FromR8(double dblIn, USHORT* pusOut) { - if (dblIn < -0.5 || dblIn > (double)UI2_MAX) + if (dblIn < -0.5 || dblIn >= UI2_MAX + 0.5) return DISP_E_OVERFLOW; VARIANT_DutchRound(USHORT, dblIn, *pusOut); return S_OK; @@ -1539,7 +1540,7 @@ HRESULT WINAPI VarI4FromR4(FLOAT fltIn, LONG *piOut) */ HRESULT WINAPI VarI4FromR8(double dblIn, LONG *piOut) { - if (dblIn < (double)I4_MIN || dblIn > (double)I4_MAX) + if (dblIn < I4_MIN - 0.5 || dblIn >= I4_MAX + 0.5) return DISP_E_OVERFLOW; VARIANT_DutchRound(LONG, dblIn, *piOut); return S_OK; @@ -1848,7 +1849,7 @@ HRESULT WINAPI VarUI4FromR4(FLOAT fltIn, ULONG *pulOut) */ HRESULT WINAPI VarUI4FromR8(double dblIn, ULONG *pulOut) { - if (dblIn < -0.5 || dblIn > (double)UI4_MAX) + if (dblIn < -0.5 || dblIn >= UI4_MAX + 0.5) return DISP_E_OVERFLOW; VARIANT_DutchRound(ULONG, dblIn, *pulOut); return S_OK; @@ -4484,19 +4485,19 @@ static ULONG VARIANT_Add(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh) /* Subtract two unsigned 32 bit values with underflow */ static ULONG VARIANT_Sub(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh) { - int invert = 0; + BOOL invert = FALSE; ULARGE_INTEGER ul64; ul64.QuadPart = (LONG64)ulLeft - (ULONG64)ulRight; if (ulLeft < ulRight) - invert = 1; + invert = TRUE; if (ul64.QuadPart > (ULONG64)*pulHigh) ul64.QuadPart -= (ULONG64)*pulHigh; else { ul64.QuadPart -= (ULONG64)*pulHigh; - invert = 1; + invert = TRUE; } if (invert) ul64.u.HighPart = -ul64.u.HighPart ; @@ -4672,10 +4673,10 @@ static unsigned char VARIANT_int_divbychar(DWORD * p, unsigned int n, unsigned c } /* check to test if encoded number is a zero. Returns 1 if zero, 0 for nonzero */ -static int VARIANT_int_iszero(const DWORD * p, unsigned int n) +static BOOL VARIANT_int_iszero(const DWORD * p, unsigned int n) { - for (; n > 0; n--) if (*p++ != 0) return 0; - return 1; + for (; n > 0; n--) if (*p++ != 0) return FALSE; + return TRUE; } /* multiply two DECIMALS, without changing either one, and place result in third @@ -4685,7 +4686,7 @@ static int VARIANT_int_iszero(const DWORD * p, unsigned int n) */ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI * result) { - int r_overflow = 0; + BOOL r_overflow = FALSE; DWORD running[6]; signed int mulstart; @@ -4776,12 +4777,12 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI } /* cast DECIMAL into string. Any scale should be handled properly. en_US locale is - hardcoded (period for decimal separator, dash as negative sign). Returns 0 for - success, nonzero if insufficient space in output buffer. + hardcoded (period for decimal separator, dash as negative sign). Returns TRUE for + success, FALSE if insufficient space in output buffer. */ -static int VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n) +static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n) { - int overflow = 0; + BOOL overflow = FALSE; DWORD quotient[3]; unsigned char remainder; unsigned int i; @@ -4792,7 +4793,7 @@ static int VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n) *s++ = '-'; n--; } - else overflow = 1; + else overflow = TRUE; } /* prepare initial 0 */ @@ -4800,7 +4801,7 @@ static int VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n) if (n >= 2) { s[0] = '0'; s[1] = '\0'; - } else overflow = 1; + } else overflow = TRUE; } i = 0; @@ -4808,7 +4809,7 @@ static int VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n) while (!overflow && !VARIANT_int_iszero(quotient, sizeof(quotient) / sizeof(DWORD))) { remainder = VARIANT_int_divbychar(quotient, sizeof(quotient) / sizeof(DWORD), 10); if (i + 2 > n) { - overflow = 1; + overflow = TRUE; } else { s[i++] = '0' + remainder; s[i] = '\0'; @@ -4829,7 +4830,7 @@ static int VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n) if (i <= a->scale) { unsigned int numzeroes = a->scale + 1 - i; if (i + 1 + numzeroes >= n) { - overflow = 1; + overflow = TRUE; } else { memmove(s + numzeroes, s, (i + 1) * sizeof(WCHAR)); i += numzeroes; @@ -4843,7 +4844,7 @@ static int VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n) if (a->scale > 0) { unsigned int periodpos = i - a->scale; if (i + 2 >= n) { - overflow = 1; + overflow = TRUE; } else { memmove(s + periodpos + 1, s + periodpos, (i + 1 - periodpos) * sizeof(WCHAR)); s[periodpos] = '.'; i++; @@ -4855,7 +4856,7 @@ static int VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n) } } - return overflow; + return !overflow; } /* shift the bits of a DWORD array to the left. p[0] is assumed LSB */ @@ -5127,7 +5128,7 @@ static int VARIANT_int_addlossy( in case of quotient overflow. */ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * divisor, - VARIANT_DI * quotient) + VARIANT_DI * quotient, BOOL round_remainder) { HRESULT r_overflow = S_OK; @@ -5170,8 +5171,21 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di underflow = VARIANT_int_addlossy( quotient->bitsnum, "ientscale, sizeof(quotient->bitsnum) / sizeof(DWORD), remainderplusquotient, &tempquotientscale, 4); - VARIANT_int_mulbychar(remainderplusquotient + 4, 4, 10); - memcpy(remainderplusquotient, remainderplusquotient + 4, 4 * sizeof(DWORD)); + if (round_remainder) { + if(remainderplusquotient[4] >= 5){ + unsigned int i; + unsigned char remainder = 1; + for (i = 0; i < sizeof(quotient->bitsnum) / sizeof(DWORD) && remainder; i++) { + ULONGLONG digit = quotient->bitsnum[i] + 1; + remainder = (digit > 0xFFFFFFFF) ? 1 : 0; + quotient->bitsnum[i] = digit & 0xFFFFFFFF; + } + } + memset(remainderplusquotient, 0, sizeof(remainderplusquotient)); + } else { + VARIANT_int_mulbychar(remainderplusquotient + 4, 4, 10); + memcpy(remainderplusquotient, remainderplusquotient + 4, 4 * sizeof(DWORD)); + } tempquotientscale = ++remainderscale; } while (!underflow && !VARIANT_int_iszero(remainderplusquotient + 4, 4)); @@ -5204,7 +5218,7 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di into the VARIANT_DI and is therefore no longer necessary. Returns S_OK if successful, or DISP_E_OVERFLOW if the represented value is too big to fit into a DECIMAL. */ -static HRESULT VARIANT_DI_normalize(VARIANT_DI * val, int exponent2, int isDouble) +static HRESULT VARIANT_DI_normalize(VARIANT_DI * val, int exponent2, BOOL isDouble) { HRESULT hres = S_OK; int exponent5, exponent10; @@ -5408,7 +5422,7 @@ static HRESULT VARIANT_DI_FromR4(float source, VARIANT_DI * dest) compensate. */ exponent2 -= 23; - hres = VARIANT_DI_normalize(dest, exponent2, 0); + hres = VARIANT_DI_normalize(dest, exponent2, FALSE); } return hres; @@ -5469,37 +5483,22 @@ static HRESULT VARIANT_DI_FromR8(double source, VARIANT_DI * dest) compensate. */ exponent2 -= 52; - hres = VARIANT_DI_normalize(dest, exponent2, 1); + hres = VARIANT_DI_normalize(dest, exponent2, TRUE); } return hres; } -/************************************************************************ - * VarDecDiv (OLEAUT32.178) - * - * Divide one DECIMAL by another. - * - * PARAMS - * pDecLeft [I] Source - * pDecRight [I] Value to divide by - * pDecOut [O] Destination - * - * RETURNS - * Success: S_OK. - * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination - */ -HRESULT WINAPI VarDecDiv(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut) +static HRESULT VARIANT_do_division(const DECIMAL *pDecLeft, const DECIMAL *pDecRight, DECIMAL *pDecOut, + BOOL round) { HRESULT hRet = S_OK; VARIANT_DI di_left, di_right, di_result; HRESULT divresult; - if (!pDecLeft || !pDecRight || !pDecOut) return E_INVALIDARG; - VARIANT_DIFromDec(pDecLeft, &di_left); VARIANT_DIFromDec(pDecRight, &di_right); - divresult = VARIANT_DI_div(&di_left, &di_right, &di_result); + divresult = VARIANT_DI_div(&di_left, &di_right, &di_result, round); if (divresult != S_OK) { /* division actually overflowed */ @@ -5546,6 +5545,27 @@ HRESULT WINAPI VarDecDiv(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI return hRet; } +/************************************************************************ + * VarDecDiv (OLEAUT32.178) + * + * Divide one DECIMAL by another. + * + * PARAMS + * pDecLeft [I] Source + * pDecRight [I] Value to divide by + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarDecDiv(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut) +{ + if (!pDecLeft || !pDecRight || !pDecOut) return E_INVALIDARG; + + return VARIANT_do_division(pDecLeft, pDecRight, pDecOut, FALSE); +} + /************************************************************************ * VarDecMul (OLEAUT32.179) * @@ -5755,6 +5775,10 @@ HRESULT WINAPI VarDecNeg(const DECIMAL* pDecIn, DECIMAL* pDecOut) */ HRESULT WINAPI VarDecRound(const DECIMAL* pDecIn, int cDecimals, DECIMAL* pDecOut) { + DECIMAL divisor, tmp; + HRESULT hr; + unsigned int i; + if (cDecimals < 0 || (DEC_SIGN(pDecIn) & ~DECIMAL_NEG) || DEC_SCALE(pDecIn) > DEC_MAX_SCALE) return E_INVALIDARG; @@ -5764,9 +5788,26 @@ HRESULT WINAPI VarDecRound(const DECIMAL* pDecIn, int cDecimals, DECIMAL* pDecOu return S_OK; } - FIXME("semi-stub!\n"); + /* truncate significant digits and rescale */ + memset(&divisor, 0, sizeof(divisor)); + DEC_LO64(&divisor) = 1; - return DISP_E_OVERFLOW; + memset(&tmp, 0, sizeof(tmp)); + DEC_LO64(&tmp) = 10; + for (i = 0; i < DEC_SCALE(pDecIn) - cDecimals; ++i) + { + hr = VarDecMul(&divisor, &tmp, &divisor); + if (FAILED(hr)) + return hr; + } + + hr = VARIANT_do_division(pDecIn, &divisor, pDecOut, TRUE); + if (FAILED(hr)) + return hr; + + DEC_SCALE(pDecOut) = cDecimals; + + return S_OK; } /************************************************************************ diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index d8e4a2cc3a8..a6e7d4bad8b 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -147,7 +147,7 @@ reactos/dll/win32/odbc32 # Synced to Wine-1.7.17. Depends on port o reactos/dll/win32/odbccp32 # Synced to Wine-1.7.1 reactos/dll/win32/ole32 # Synced to Wine-1.7.17 reactos/dll/win32/oleacc # Synced to Wine-1.7.17 -reactos/dll/win32/oleaut32 # Synced to Wine-1.7.1 +reactos/dll/win32/oleaut32 # Synced to Wine-1.7.17 reactos/dll/win32/olecli32 # Synced to Wine-1.7.1 reactos/dll/win32/oledlg # Synced to Wine-1.7.1 reactos/dll/win32/olepro32 # Synced to Wine-1.7.1