[OLEAUT32]
authorAmine Khaldi <amine.khaldi@reactos.org>
Thu, 24 Apr 2014 15:12:07 +0000 (15:12 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Thu, 24 Apr 2014 15:12:07 +0000 (15:12 +0000)
* Sync with Wine 1.7.17.
CORE-8080

svn path=/trunk/; revision=62942

18 files changed:
reactos/dll/win32/oleaut32/connpt.c
reactos/dll/win32/oleaut32/dispatch.c
reactos/dll/win32/oleaut32/oleaut.c
reactos/dll/win32/oleaut32/oleaut32.spec
reactos/dll/win32/oleaut32/oleaut32_oaidl.idl
reactos/dll/win32/oleaut32/oleaut32_ocidl.idl
reactos/dll/win32/oleaut32/olefont.c
reactos/dll/win32/oleaut32/olepicture.c
reactos/dll/win32/oleaut32/recinfo.c
reactos/dll/win32/oleaut32/safearray.c
reactos/dll/win32/oleaut32/tmarshal.c
reactos/dll/win32/oleaut32/typelib.c
reactos/dll/win32/oleaut32/usrmarshal.c
reactos/dll/win32/oleaut32/varformat.c
reactos/dll/win32/oleaut32/variant.c
reactos/dll/win32/oleaut32/variant.h
reactos/dll/win32/oleaut32/vartype.c
reactos/media/doc/README.WINE

index 487a0b8..656aee4 100644 (file)
@@ -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;
 }
index a332417..1331d1c 100644 (file)
@@ -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;
 }
index 8f77d18..961f40c 100644 (file)
@@ -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);
 }
index a86486f..a68eb0c 100644 (file)
@@ -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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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
 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)
index 3574d08..2874be0 100644 (file)
@@ -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 */")
index fad3741..5f7664e 100644 (file)
@@ -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"
 
 [
index e610219..ad9351d 100644 (file)
@@ -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;
index 47667bf..4b4bb30 100644 (file)
@@ -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);
index 22a889b..f10755e 100644 (file)
@@ -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);
     }
 
index 88a7e13..14eb269 100644 (file)
@@ -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
+    else if (psa->fFeatures & FADF_RECORD)
     {
-      /* Copy the data over */
-      memcpy(dest->pvData, psa->pvData, ulCellCount * psa->cbElements);
+      BYTE *dest_data = dest->pvData;
+      BYTE *src_data = psa->pvData;
+      IRecordInfo *record;
 
-      if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH))
+      SafeArrayGetRecordInfo(psa, &record);
+      while (ulCellCount--)
       {
-        LPUNKNOWN *lpUnknown = dest->pvData;
-
-        while(ulCellCount--)
-        {
-          if (*lpUnknown)
-            IUnknown_AddRef(*lpUnknown);
-          lpUnknown++;
-        }
+          /* RecordCopy() clears destination record */
+          hr = IRecordInfo_RecordCopy(record, src_data, dest_data);
+          if (FAILED(hr)) break;
+          src_data += psa->cbElements;
+          dest_data += psa->cbElements;
       }
-    }
 
-    if (psa->fFeatures & FADF_RECORD)
+      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))
     {
-      IRecordInfo* pRecInfo = NULL;
-
-      SafeArrayGetRecordInfo(psa, &pRecInfo);
-      SafeArraySetRecordInfo(dest, pRecInfo);
+      IUnknown **dest_unk = dest->pvData;
+      IUnknown **src_unk = psa->pvData;
 
-      if (pRecInfo)
+      /* release old iface, addref new one */
+      while (ulCellCount--)
       {
-        /* Release because Get() adds a reference */
-        IRecordInfo_Release(pRecInfo);
+          if (*dest_unk)
+              IUnknown_Release(*dest_unk);
+          *dest_unk = *src_unk;
+          if (*dest_unk)
+              IUnknown_AddRef(*dest_unk);
+          src_unk++;
+          dest_unk++;
       }
     }
-    else if (psa->fFeatures & FADF_HAVEIID)
+    else
+    {
+      /* Copy the data over */
+      memcpy(dest->pvData, psa->pvData, ulCellCount * psa->cbElements);
+    }
+
+    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;
-
-          if (lpUnknown)
-            IUnknown_AddRef(lpUnknown);
-          if (*lpDest)
-            IUnknown_Release(*lpDest);
-         *lpDest = lpUnknown;
-        } else {
-          /* Copy the data over */
-          memcpy(lpvDest, pvData, psa->cbElements);
-       }
+        IUnknown  *lpUnknown = pvData;
+        IUnknown **lpDest = lpvDest;
+
+        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;
+      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);
index efeeb25..4064796 100644 (file)
@@ -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
index 451c43f..95d2986 100644 (file)
@@ -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));
-
-                           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);
-                           }
-
-                           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);
-                       }
+                        BOOL is_wow64;
+                        DWORD opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
+
+                        /* register interface<->typelib coupling */
+                        TLB_register_interface(attr, name, tattr, 0);
+
+                        /* 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;
index 37e6e61..48c9625 100644 (file)
@@ -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:
index 1827909..7d092ee 100644 (file)
@@ -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));
index 189840d..e6f6372 100644 (file)
@@ -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;
+    if (src_rec->pvRecord) return E_INVALIDARG;
+    return S_OK;
+  }
 
-    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;
+  hr = IRecordInfo_GetSize(src_rec->pRecInfo, &size);
+  if (FAILED(hr)) return hr;
 
-        hres = IRecordInfo_RecordCopy(pBr->pRecInfo, pvRecord, pvRecord);
-        if (SUCCEEDED(hres))
-          IRecordInfo_AddRef(pBr->pRecInfo);
-      }
-    }
-  }
-  else if (pBr->pvRecord)
-    hres = E_INVALIDARG;
-  return hres;
+  /* 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;
index b2c0d61..dceac5c 100644 (file)
@@ -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 *,
index 78cd6e3..a310387 100644 (file)
@@ -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, &quotientscale, 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;
 }
 
 /************************************************************************
index d8e4a2c..a6e7d4b 100644 (file)
@@ -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