[ros-diffs] [cwittich] 38570: sync oleaut32_winetest with wine 1.1.12

cwittich at svn.reactos.org cwittich at svn.reactos.org
Sun Jan 4 20:19:06 CET 2009


Author: cwittich
Date: Sun Jan  4 13:19:05 2009
New Revision: 38570

URL: http://svn.reactos.org/svn/reactos?rev=38570&view=rev
Log:
sync oleaut32_winetest with wine 1.1.12

Modified:
    trunk/rostests/winetests/oleaut32/oleaut32.rbuild
    trunk/rostests/winetests/oleaut32/olefont.c
    trunk/rostests/winetests/oleaut32/olepicture.c
    trunk/rostests/winetests/oleaut32/safearray.c
    trunk/rostests/winetests/oleaut32/tmarshal.c
    trunk/rostests/winetests/oleaut32/tmarshal.idl
    trunk/rostests/winetests/oleaut32/tmarshal.rc
    trunk/rostests/winetests/oleaut32/tmarshal_dispids.h
    trunk/rostests/winetests/oleaut32/typelib.c
    trunk/rostests/winetests/oleaut32/usrmarshal.c
    trunk/rostests/winetests/oleaut32/varformat.c
    trunk/rostests/winetests/oleaut32/vartest.c
    trunk/rostests/winetests/oleaut32/vartype.c

Modified: trunk/rostests/winetests/oleaut32/oleaut32.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/oleaut32.rbuild?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/oleaut32.rbuild [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/oleaut32.rbuild [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -4,10 +4,11 @@
 <module name="oleaut32_winetest" type="win32cui" installbase="bin" installname="oleaut32_winetest.exe" allowwarnings="true">
 	<compilerflag compiler="cc">-Wno-format</compilerflag>
 	<include base="oleaut32_winetest">.</include>
+	<include base="ReactOS">include/reactos/wine</include>
+	<include base="oleaut32_winetest" root="intermediate">.</include>
 	<library>wine</library>
 	<library>oleaut32</library>
 	<library>ole32</library>
-	<library>shlwapi</library>
 	<library>rpcrt4</library>
 	<library>user32</library>
 	<library>gdi32</library>
@@ -26,5 +27,18 @@
 	<file>vartype.c</file>
 	<file>tmarshal.rc</file>
 	<file>testlist.c</file>
+	<dependency>tmarshal_header</dependency>
+	<dependency>tmarshal</dependency>
+	<dependency>test_tlb</dependency>
+	<dependency>stdole2.tlb</dependency>
+</module>
+<module name="tmarshal_header" type="idlheader">
+	<file>tmarshal.idl</file>
+</module>
+<module name="test_tlb" type="embeddedtypelib" allowwarnings="true">
+	<file>test_tlb.idl</file>
+</module>
+<module name="tmarshal" type="embeddedtypelib" allowwarnings="true">
+	<file>tmarshal.idl</file>
 </module>
 </group>

Modified: trunk/rostests/winetests/oleaut32/olefont.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/olefont.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/olefont.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/olefont.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -24,7 +24,6 @@
 #include <stdio.h>
 #include <math.h>
 #include <float.h>
-#include <time.h>
 
 #define COBJMACROS
 
@@ -36,9 +35,12 @@
 #include <winnls.h>
 #include <winerror.h>
 #include <winnt.h>
+#include <initguid.h>
 #include <wtypes.h>
 #include <olectl.h>
 #include <ocidl.h>
+
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 
 static WCHAR MSSansSerif_font[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f',0};
 static WCHAR system_font[] = { 'S','y','s','t','e','m',0 };
@@ -135,13 +137,15 @@
 
         /* Test if QueryInterface increments ref counter for IFONTs */
         ret = IFont_AddRef(font);
-        ok(ret == 3, "IFont_QI expected ref value 3 but instead got %12u\n",ret);
+        ok(ret == 3 ||
+           broken(ret == 1), /* win95 */
+           "IFont_QI expected ref value 3 but instead got %d\n",ret);
         IFont_Release(font);
 
         ok(hres == S_OK,"IFont_QI does not return S_OK, but 0x%08x\n", hres);
         ok(pvObj != NULL,"IFont_QI does return NULL, instead of a ptr\n");
 
-        /* Orignial ref and QueryInterface ref both have to be released */
+        /* Original ref and QueryInterface ref both have to be released */
         IFont_Release(font);
         IFont_Release(font);
 }
@@ -171,6 +175,7 @@
 	ok(hres == S_OK, "GetNames returned 0x%08x instead of S_OK.\n", hres);
 	ok(n == 1, "GetNames returned %d names instead of 1.\n", n);
 	ok(!lstrcmpiW(names[0],name_Name), "DISPID_FONT_NAME doesn't get 'Names'.\n");
+	SysFreeString(names[0]);
 
 	ITypeInfo_Release(pTInfo);
 
@@ -768,8 +773,9 @@
 
     /* Decrement reference for destroyed hfnt1 */
     hres = IFont_ReleaseHfont(ifnt2,hfnt1);
-    ok(hres == S_OK,
-        "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
+    ok(hres == S_OK ||
+       hres == S_FALSE, /* <= win2k */
+        "IFont_AddRefHfont: (Release ref) Expected S_OK or S_FALSE but got 0x%08x\n",
         hres);
 
     /* Shows that releasing all IFONT's does clear the HFONT cache. */
@@ -811,13 +817,16 @@
 
 	/* Test various size operations and conversions. */
 	/* Add more as needed. */
-	test_ifont_sizes(180000, 0, 72, 2540, -18, "default");
-	test_ifont_sizes(180000, 0, 144, 2540, -36, "ratio1");		/* change ratio */
-	test_ifont_sizes(180000, 0, 72, 1270, -36, "ratio2");		/* 2nd part of ratio */
-
-	/* These depend on details of how IFont rounds sizes internally. */
-	test_ifont_sizes(0, 0, 72, 2540, 0, "zero size");          /* zero size */
-	test_ifont_sizes(186000, 0, 72, 2540, -19, "rounding");   /* test rounding */
+	if (0) /* FIXME: failing tests */
+	{
+	    test_ifont_sizes(180000, 0, 72, 2540, -18, "default");
+	    test_ifont_sizes(180000, 0, 144, 2540, -36, "ratio1");		/* change ratio */
+	    test_ifont_sizes(180000, 0, 72, 1270, -36, "ratio2");		/* 2nd part of ratio */
+
+	    /* These depend on details of how IFont rounds sizes internally. */
+	    test_ifont_sizes(0, 0, 72, 2540, 0, "zero size");          /* zero size */
+	    test_ifont_sizes(186000, 0, 72, 2540, -19, "rounding");   /* test rounding */
+	}
 
 	test_font_events_disp();
 	test_GetIDsOfNames();

Modified: trunk/rostests/winetests/oleaut32/olepicture.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/olepicture.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/olepicture.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/olepicture.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -23,9 +23,9 @@
 #include <stdio.h>
 #include <math.h>
 #include <float.h>
-#include <time.h>
 
 #define COBJMACROS
+#define NONAMELESSUNION
 
 #include "wine/test.h"
 #include <windef.h>
@@ -121,6 +121,53 @@
 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
 };
 
+/* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
+static const unsigned char metafile[] = {
+    0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
+    0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
+    0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x00, 0x00
+};
+
+/* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
+static const unsigned char enhmetafile[] = {
+    0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
+    0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+    0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+    0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
+    0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
+    0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
+    0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
+    0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+    0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x00
+};
+
+
 struct NoStatStreamImpl
 {
 	const IStreamVtbl	*lpVtbl;   
@@ -480,6 +527,124 @@
     IStream_Release(stream);
 }
 
+static void test_metafile(void)
+{
+    LPSTREAM stream;
+    IPicture *pict;
+    HGLOBAL hglob;
+    LPBYTE *data;
+
+    hglob = GlobalAlloc (0, sizeof(metafile));
+    data = GlobalLock(hglob);
+    memcpy(data, metafile, sizeof(metafile));
+
+    ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
+    /* Windows does not load simple metafiles */
+    ole_expect(OleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
+
+    IStream_Release(stream);
+}
+
+static void test_enhmetafile(void)
+{
+    OLE_HANDLE handle;
+    LPSTREAM stream;
+    IPicture *pict;
+    HGLOBAL hglob;
+    LPBYTE *data;
+    LONG cxy;
+    BOOL keep;
+    short type;
+
+    hglob = GlobalAlloc (0, sizeof(enhmetafile));
+    data = GlobalLock(hglob);
+    memcpy(data, enhmetafile, sizeof(enhmetafile));
+
+    ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
+    ole_check(OleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict));
+
+    ole_check(IPicture_get_Handle(pict, &handle));
+    ok(handle != 0, "handle is null\n");
+
+    ole_check(IPicture_get_Type(pict, &type));
+    expect_eq(type, PICTYPE_ENHMETAFILE, short, "%d");
+
+    ole_check(IPicture_get_Height(pict, &cxy));
+    expect_eq(cxy, -23, LONG, "%d");
+
+    ole_check(IPicture_get_Width(pict, &cxy));
+    expect_eq(cxy, -25, LONG, "%d");
+
+    ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
+    todo_wine expect_eq(keep, FALSE, LONG, "%d");
+
+    IPicture_Release(pict);
+    IStream_Release(stream);
+}
+
+static void test_Render(void)
+{
+    IPicture *pic;
+    HRESULT hres;
+    short type;
+    PICTDESC desc;
+    HDC hdc = GetDC(0);
+
+    /* test IPicture::Render return code on uninitialized picture */
+    OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
+    hres = IPicture_get_Type(pic, &type);
+    ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
+    ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
+    /* zero dimensions */
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    /* nonzero dimensions, PICTYPE_UNINITIALIZED */
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 10, NULL);
+    ole_expect(hres, S_OK);
+    IPicture_Release(pic);
+
+    desc.cbSizeofstruct = sizeof(PICTDESC);
+    desc.picType = PICTYPE_ICON;
+    desc.u.icon.hicon = LoadIcon(NULL, IDI_APPLICATION);
+    if(!desc.u.icon.hicon){
+        win_skip("LoadIcon failed. Skipping...\n");
+        ReleaseDC(NULL, hdc);
+        return;
+    }
+
+    OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (VOID**)&pic);
+    /* zero dimensions, PICTYPE_ICON */
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    IPicture_Release(pic);
+
+    ReleaseDC(NULL, hdc);
+}
+
 START_TEST(olepicture)
 {
 	hOleaut32 = GetModuleHandleA("oleaut32.dll");
@@ -501,9 +666,12 @@
 	test_empty_image();
 	test_empty_image_2();
         test_apm();
+        test_metafile();
+        test_enhmetafile();
 
 	test_Invoke();
         test_OleCreatePictureIndirect();
+        test_Render();
 }
 
 

Modified: trunk/rostests/winetests/oleaut32/safearray.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/safearray.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/safearray.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/safearray.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -23,7 +23,6 @@
 #include <stdio.h>
 #include <math.h>
 #include <float.h>
-#include <time.h>
 
 #define COBJMACROS
 #include "wine/test.h"
@@ -355,14 +354,23 @@
         SafeArrayPtrOfIndex(a, indices, (void **)&ptr1);
         ok(*(WORD *)ptr1 == 0x55aa, "Data not preserved when resizing array\n");
 
+        hres = SafeArrayDestroy(a);
+        ok(hres == S_OK,"SAD faild with hres %x\n", hres);
+
 	bounds[0].cElements = 0;	bounds[0].lLbound =  1;
 	bounds[1].cElements =  2;	bounds[1].lLbound = 23;
     	a = SafeArrayCreate(VT_I4,2,bounds);
     	ok(a != NULL,"SAC(VT_INT32,2,...) with 0 element dim failed.\n");
+
+        hres = SafeArrayDestroy(a);
+        ok(hres == S_OK,"SAD faild with hres %x\n", hres);
 	bounds[0].cElements = 1;	bounds[0].lLbound =  1;
 	bounds[1].cElements = 0;	bounds[1].lLbound = 23;
     	a = SafeArrayCreate(VT_I4,2,bounds);
     	ok(a != NULL,"SAC(VT_INT32,2,...) with 0 element dim failed.\n");
+
+        hres = SafeArrayDestroy(a);
+        ok(hres == S_OK,"SAD faild with hres %x\n", hres);
 
 	bounds[0].cElements = 42;	bounds[0].lLbound =  1;
 	bounds[1].cElements =  2;	bounds[1].lLbound = 23;
@@ -442,6 +450,9 @@
 
 	hres = SafeArrayUnaccessData(a);
 	ok(S_OK == hres, "SAUAD failed with 0x%x\n", hres);
+
+	hres = SafeArrayDestroy(a);
+	ok(hres == S_OK,"SAD faild with hres %x\n", hres);
 
 	for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
 	if ((i == VT_I8 || i == VT_UI8) && HAVE_OLEAUT32_I8)
@@ -478,12 +489,8 @@
         {
             hres = pSafeArrayGetVartype(a, &vt);
             ok(hres == S_OK, "SAGVT of arra y with vt %d failed with %x\n", vttypes[i].vt, hres);
-            if (vttypes[i].vt == VT_DISPATCH) {
-        		/* Special case. Checked against Windows. */
-		        ok(vt == VT_UNKNOWN, "SAGVT of a        rray with VT_DISPATCH returned not VT_UNKNOWN, but %d\n", vt);
-            } else {
-		        ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt);
-            }
+            /* Windows prior to Vista returns VT_UNKNOWN instead of VT_DISPATCH */
+            ok(broken(vt == VT_UNKNOWN) || vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt);
         }
 
 		hres = SafeArrayCopy(a, &c);
@@ -497,12 +504,8 @@
         if (pSafeArrayGetVartype) {
             hres = pSafeArrayGetVartype(c, &vt);
             ok(hres == S_OK, "SAGVT of array with vt %d failed with %x\n", vttypes[i].vt, hres);
-            if (vttypes[i].vt == VT_DISPATCH) {
-                /* Special case. Checked against Windows. */
-                ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d\n", vt);
-            } else {
-                ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt);
-            }
+            /* Windows prior to Vista returns VT_UNKNOWN instead of VT_DISPATCH */
+            ok(broken(vt == VT_UNKNOWN) || vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt);
         }
 
         if (pSafeArrayCopyData) {
@@ -512,6 +515,9 @@
             hres = SafeArrayDestroyData(c);
             ok(hres == S_OK,"SADD of copy of array with vt %d failed with hres %x\n", vttypes[i].vt, hres);
         }
+
+		hres = SafeArrayDestroy(c);
+		ok(hres == S_OK,"SAD faild with hres %x\n", hres);
 
 		hres = SafeArrayDestroy(a);
 		ok(hres == S_OK,"SAD of array with vt %d failed with hres %x\n", vttypes[i].vt, hres);
@@ -531,6 +537,7 @@
 	ok(hres==S_OK, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR failed with %x\n",hres);
 	ok(V_VT(&v) == VT_BSTR,"CTE VT_ARRAY|VT_UI1 -> VT_BSTR did not return VT_BSTR, but %d.v\n",V_VT(&v));
 	ok(V_BSTR(&v)[0] == 0x6548,"First letter are not 'He', but %x\n", V_BSTR(&v)[0]);
+	VariantClear(&v);
 
 	/* check locking functions */
 	a = SafeArrayCreate(VT_I4, 1, &bound);
@@ -559,7 +566,6 @@
 	ok(a!=NULL,"SAC should not fail\n");
 	hres = SafeArrayDestroyDescriptor(a);
 	ok(hres == S_OK,"SADD with data in array failed with hres %x\n",hres);
-
 
 	/* IID functions */
 	/* init a small stack safearray */
@@ -574,6 +580,9 @@
         ok((a->fFeatures & FADF_HAVEIID) == 0,"newly allocated descriptor with SAAD should not have FADF_HAVEIID\n");
         hres = pSafeArraySetIID(a,&iid);
         ok(hres == E_INVALIDARG,"SafeArraySetIID of newly allocated descriptor with SAAD should return E_INVALIDARG, but %x\n",hres);
+
+        hres = SafeArrayDestroyDescriptor(a);
+        ok(hres == S_OK,"SADD failed with hres %x\n",hres);
     }
 
     if (!pSafeArrayAllocDescriptorEx)
@@ -692,6 +701,9 @@
 
   hres = SafeArrayAllocData(sa);
   ok(hres == S_OK, "SafeArrayAllocData gave hres 0x%x\n", hres);
+
+  hres = SafeArrayDestroy(sa);
+  ok(hres == S_OK,"SafeArrayDestroy failed with hres %x\n",hres);
 }
 
 static void test_SafeArrayCreateLockDestroy(void)
@@ -808,7 +820,7 @@
           ok(hres == S_OK, "Unlock VARTYPE %d (@%d dims) hres 0x%x\n",
              vt, dimension, hres);
 
-          hres = SafeArrayDestroyDescriptor(sa);
+          hres = SafeArrayDestroy(sa);
           ok(hres == S_OK, "destroy VARTYPE %d (@%d dims) hres 0x%x\n",
              vt, dimension, hres);
         }
@@ -828,6 +840,9 @@
     return;
   sa = pSafeArrayCreateVector(VT_UI1, 0, 0);
   ok(sa != NULL, "SACV with 0 elements failed.\n");
+
+  hres = SafeArrayDestroy(sa);
+  ok(hres == S_OK, "SafeArrayDestroy failed with hres %x\n",hres);
 
   /* Test all VARTYPES in different lengths */
   for (element = 1; element <= 101; element += 10)
@@ -861,7 +876,7 @@
           ok(hres == S_OK, "Unlock VARTYPE %d (@%d elements) failed; hres 0x%x\n",
              vt, element, hres);
 
-          hres = SafeArrayDestroyDescriptor(sa);
+          hres = SafeArrayDestroy(sa);
           ok(hres == S_OK, "destroy VARTYPE %d (@%d elements) failed; hres 0x%x\n",
              vt, element, hres);
         }
@@ -1085,6 +1100,8 @@
   if (hres == S_OK)
     ok(SysStringLen(value) == SysStringLen(gotvalue), "Got len %d instead of %d\n", SysStringLen(gotvalue), SysStringLen(value));
   SafeArrayDestroy(sa);
+  SysFreeString(value);
+  SysFreeString(gotvalue);
 }
 
 static int tunk_xref = 0;
@@ -1603,6 +1620,7 @@
     hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_BSTR);
     ok(hres != S_OK, "CTE VT_ARRAY|VT %d->BSTR succeeded\n", vt);
     VariantClear(&v2);
+    VariantClear(&v);
   }
 
   /* Can't change an array of one type into array of another type , even
@@ -1630,6 +1648,7 @@
     V_ARRAY(&v) = sa;
     hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_ARRAY|VT_UI1);
     ok(hres == S_OK, "CTE VT_ARRAY|VT_UI1->VT_ARRAY|VT_UI1 returned %x\n", hres);
+    SafeArrayDestroy(sa);
   }
 
   /* NULL/EMPTY */

Modified: trunk/rostests/winetests/oleaut32/tmarshal.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/tmarshal.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/tmarshal.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/tmarshal.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -18,17 +18,31 @@
  */
 
 #define COBJMACROS
+#define CONST_VTABLE
 
 #include <windows.h>
 #include <ocidl.h>
 #include <stdio.h>
 
-#include <wine/test.h>
+#include "wine/test.h"
 
 #include "tmarshal.h"
 #include "tmarshal_dispids.h"
 
 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08lx\n", (unsigned long int)hr)
+
+/* ULL suffix is not portable */
+#define ULL_CONST(dw1, dw2) ((((ULONGLONG)dw1) << 32) | (ULONGLONG)dw2)
+
+const MYSTRUCT MYSTRUCT_BYVAL = {0x12345678, ULL_CONST(0xdeadbeef, 0x98765432)};
+const MYSTRUCT MYSTRUCT_BYPTR = {0x91827364, ULL_CONST(0x88776655, 0x44332211)};
+const MYSTRUCT MYSTRUCT_ARRAY[5] = {
+    {0x1a1b1c1d, ULL_CONST(0x1e1f1011, 0x12131415)},
+    {0x2a2b2c2d, ULL_CONST(0x2e2f2021, 0x22232425)},
+    {0x3a3b3c3d, ULL_CONST(0x3e3f3031, 0x32333435)},
+    {0x4a4b4c4d, ULL_CONST(0x4e4f4041, 0x42434445)},
+    {0x5a5b5c5d, ULL_CONST(0x5e5f5051, 0x52535455)},
+};
 
 /* Debugging functions from wine/libs/wine/debug.c */
 
@@ -210,6 +224,72 @@
     CloseHandle(thread);
 }
 
+static ItestDual TestDual, TestDualDisp;
+
+static HRESULT WINAPI TestDual_QueryInterface(ItestDual *iface, REFIID riid, void **ppvObject)
+{
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch)) {
+        *ppvObject = &TestDualDisp;
+        return S_OK;
+    }else if(IsEqualGUID(riid, &IID_ItestDual)) {
+        *ppvObject = &TestDual;
+        return S_OK;
+    }
+
+    *ppvObject = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI TestDual_AddRef(ItestDual *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI TestDual_Release(ItestDual *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI TestDual_GetTypeInfoCount(ItestDual *iface, UINT *pctinfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TestDual_GetTypeInfo(ItestDual *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TestDual_GetIDsOfNames(ItestDual *iface, REFIID riid, LPOLESTR *rgszNames,
+        UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TestDual_Invoke(ItestDual *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
+        WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
+        UINT *puArgErr)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static ItestDualVtbl TestDualVtbl = {
+    TestDual_QueryInterface,
+    TestDual_AddRef,
+    TestDual_Release,
+    TestDual_GetTypeInfoCount,
+    TestDual_GetTypeInfo,
+    TestDual_GetIDsOfNames,
+    TestDual_Invoke
+};
+
+static ItestDual TestDual = { &TestDualVtbl };
+static ItestDual TestDualDisp = { &TestDualVtbl };
+
 typedef struct Widget
 {
     const IWidgetVtbl *lpVtbl;
@@ -217,7 +297,7 @@
     IUnknown *pDispatchUnknown;
 } Widget;
 
-HRESULT WINAPI Widget_QueryInterface(
+static HRESULT WINAPI Widget_QueryInterface(
     IWidget *iface,
     /* [in] */ REFIID riid,
     /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
@@ -235,7 +315,7 @@
     }
 }
 
-ULONG WINAPI Widget_AddRef(
+static ULONG WINAPI Widget_AddRef(
     IWidget *iface)
 {
     Widget *This = (Widget *)iface;
@@ -243,7 +323,7 @@
     return InterlockedIncrement(&This->refs);
 }
 
-ULONG WINAPI Widget_Release(
+static ULONG WINAPI Widget_Release(
     IWidget *iface)
 {
     Widget *This = (Widget *)iface;
@@ -259,7 +339,7 @@
     return refs;
 }
 
-HRESULT WINAPI Widget_GetTypeInfoCount(
+static HRESULT WINAPI Widget_GetTypeInfoCount(
     IWidget *iface,
     /* [out] */ UINT __RPC_FAR *pctinfo)
 {
@@ -274,7 +354,7 @@
     return hr;
 }
 
-HRESULT WINAPI Widget_GetTypeInfo(
+static HRESULT WINAPI Widget_GetTypeInfo(
     IWidget __RPC_FAR * iface,
     /* [in] */ UINT iTInfo,
     /* [in] */ LCID lcid,
@@ -291,7 +371,7 @@
     return hr;
 }
 
-HRESULT WINAPI Widget_GetIDsOfNames(
+static HRESULT WINAPI Widget_GetIDsOfNames(
     IWidget __RPC_FAR * iface,
     /* [in] */ REFIID riid,
     /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
@@ -310,7 +390,7 @@
     return hr;
 }
 
-HRESULT WINAPI Widget_Invoke(
+static HRESULT WINAPI Widget_Invoke(
     IWidget __RPC_FAR * iface,
     /* [in] */ DISPID dispIdMember,
     /* [in] */ REFIID riid,
@@ -332,7 +412,7 @@
     return hr;
 }
 
-HRESULT WINAPI Widget_put_Name(
+static HRESULT WINAPI Widget_put_Name(
     IWidget __RPC_FAR * iface,
     /* [in] */ BSTR name)
 {
@@ -340,7 +420,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_get_Name(
+static HRESULT WINAPI Widget_get_Name(
     IWidget __RPC_FAR * iface,
     /* [out] */ BSTR __RPC_FAR *name)
 {
@@ -350,7 +430,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_DoSomething(
+static HRESULT WINAPI Widget_DoSomething(
     IWidget __RPC_FAR * iface,
     /* [in] */ double number,
     /* [out] */ BSTR *str1,
@@ -369,7 +449,7 @@
     return S_FALSE;
 }
 
-HRESULT WINAPI Widget_get_State(
+static HRESULT WINAPI Widget_get_State(
     IWidget __RPC_FAR * iface,
     /* [retval][out] */ STATE __RPC_FAR *state)
 {
@@ -378,7 +458,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_put_State(
+static HRESULT WINAPI Widget_put_State(
     IWidget __RPC_FAR * iface,
     /* [in] */ STATE state)
 {
@@ -386,7 +466,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_Map(
+static HRESULT WINAPI Widget_Map(
     IWidget * iface,
     BSTR bstrId,
     BSTR *sValue)
@@ -396,7 +476,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_SetOleColor(
+static HRESULT WINAPI Widget_SetOleColor(
     IWidget * iface,
     OLE_COLOR val)
 {
@@ -404,7 +484,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_GetOleColor(
+static HRESULT WINAPI Widget_GetOleColor(
     IWidget * iface,
     OLE_COLOR *pVal)
 {
@@ -413,7 +493,7 @@
     return S_FALSE;
 }
 
-HRESULT WINAPI Widget_Clone(
+static HRESULT WINAPI Widget_Clone(
     IWidget *iface,
     IWidget **ppVal)
 {
@@ -421,7 +501,7 @@
     return Widget_QueryInterface(iface, &IID_IWidget, (void **)ppVal);
 }
 
-HRESULT WINAPI Widget_CloneDispatch(
+static HRESULT WINAPI Widget_CloneDispatch(
     IWidget *iface,
     IDispatch **ppVal)
 {
@@ -429,7 +509,7 @@
     return Widget_QueryInterface(iface, &IID_IWidget, (void **)ppVal);
 }
 
-HRESULT WINAPI Widget_CloneCoclass(
+static HRESULT WINAPI Widget_CloneCoclass(
     IWidget *iface,
     ApplicationObject2 **ppVal)
 {
@@ -437,7 +517,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_Value(
+static HRESULT WINAPI Widget_Value(
     IWidget __RPC_FAR * iface,
     VARIANT *value,
     VARIANT *retval)
@@ -450,7 +530,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_Array(
+static HRESULT WINAPI Widget_Array(
     IWidget * iface,
     SAFEARRAY * values)
 {
@@ -458,7 +538,7 @@
     return S_OK;
 }
 
-HRESULT WINAPI Widget_VariantArrayPtr(
+static HRESULT WINAPI Widget_VariantArrayPtr(
     IWidget * iface,
     SAFEARRAY ** values)
 {
@@ -466,7 +546,7 @@
     return S_OK;
 }
 
-void WINAPI Widget_Variant(
+static void WINAPI Widget_Variant(
     IWidget __RPC_FAR * iface,
     VARIANT var)
 {
@@ -476,7 +556,7 @@
     ok(S(V_CY(&var)).Lo == 0xdeadbeef, "V_CY(&var).Lo was 0x%x\n", S(V_CY(&var)).Lo);
 }
 
-void WINAPI Widget_VarArg(
+static void WINAPI Widget_VarArg(
     IWidget * iface,
     int numexpect,
     SAFEARRAY * values)
@@ -508,14 +588,26 @@
     ok(hr == S_OK, "SafeArrayUnaccessData failed with %x\n", hr);
 }
 
-HRESULT WINAPI Widget_Error(
+static void WINAPI Widget_StructArgs(
+    IWidget * iface,
+    MYSTRUCT byval,
+    MYSTRUCT *byptr,
+    MYSTRUCT arr[5])
+{
+    ok(memcmp(&byval, &MYSTRUCT_BYVAL, sizeof(MYSTRUCT))==0, "Struct parameter passed by value corrupted\n");
+    ok(memcmp(byptr,  &MYSTRUCT_BYPTR, sizeof(MYSTRUCT))==0, "Struct parameter passed by pointer corrupted\n");
+    ok(memcmp(arr,    MYSTRUCT_ARRAY,  sizeof(MYSTRUCT_ARRAY))==0, "Array of structs corrupted\n");
+}
+
+
+static HRESULT WINAPI Widget_Error(
     IWidget __RPC_FAR * iface)
 {
     trace("Error()\n");
     return E_NOTIMPL;
 }
 
-HRESULT WINAPI Widget_CloneInterface(
+static HRESULT WINAPI Widget_CloneInterface(
     IWidget __RPC_FAR * iface,
     ISomethingFromDispatch **ppVal)
 {
@@ -549,10 +641,82 @@
     Widget_VariantArrayPtr,
     Widget_Variant,
     Widget_VarArg,
+    Widget_StructArgs,
     Widget_Error,
     Widget_CloneInterface
 };
 
+static HRESULT WINAPI StaticWidget_QueryInterface(IStaticWidget *iface, REFIID riid, void **ppvObject)
+{
+    if (IsEqualIID(riid, &IID_IStaticWidget) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
+    {
+        IStaticWidget_AddRef(iface);
+        *ppvObject = iface;
+        return S_OK;
+    }
+
+    *ppvObject = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI StaticWidget_AddRef(IStaticWidget *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI StaticWidget_Release(IStaticWidget *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI StaticWidget_GetTypeInfoCount(IStaticWidget *iface, UINT *pctinfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI StaticWidget_GetTypeInfo(IStaticWidget *iface, UINT iTInfo, LCID lcid,
+        ITypeInfo **ppTInfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI StaticWidget_GetIDsOfNames(IStaticWidget *iface, REFIID riid, LPOLESTR *rgszNames,
+        UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI StaticWidget_Invoke(IStaticWidget *iface, DISPID dispIdMember, REFIID riid,
+        LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
+         UINT *puArgErr)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI StaticWidget_TestDual(IStaticWidget *iface, ItestDual *p)
+{
+    trace("TestDual()\n");
+    todo_wine
+    ok(p == &TestDual, "wrong ItestDual\n");
+    return S_OK;
+}
+
+static const IStaticWidgetVtbl StaticWidgetVtbl = {
+    StaticWidget_QueryInterface,
+    StaticWidget_AddRef,
+    StaticWidget_Release,
+    StaticWidget_GetTypeInfoCount,
+    StaticWidget_GetTypeInfo,
+    StaticWidget_GetIDsOfNames,
+    StaticWidget_Invoke,
+    StaticWidget_TestDual
+};
+
+static IStaticWidget StaticWidget = { &StaticWidgetVtbl };
 
 typedef struct KindaEnum
 {
@@ -563,10 +727,12 @@
 static HRESULT register_current_module_typelib(void)
 {
     WCHAR path[MAX_PATH];
+    CHAR pathA[MAX_PATH];
     HRESULT hr;
     ITypeLib *typelib;
 
-    GetModuleFileNameW(NULL, path, MAX_PATH);
+    GetModuleFileNameA(NULL, pathA, MAX_PATH);
+    MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH);
 
     hr = LoadTypeLib(path, &typelib);
     if (SUCCEEDED(hr))
@@ -577,30 +743,44 @@
     return hr;
 }
 
+static ITypeInfo *get_type_info(REFIID riid)
+{
+    ITypeInfo *pTypeInfo;
+    ITypeLib *pTypeLib;
+    HRESULT hr;
+
+    hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &pTypeLib);
+    ok_ole_success(hr, LoadRegTypeLib);
+    if (FAILED(hr))
+        return NULL;
+
+    hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, riid, &pTypeInfo);
+    ITypeLib_Release(pTypeLib);
+    ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
+    if (FAILED(hr))
+        return NULL;
+
+    return pTypeInfo;
+}
+
 static IWidget *Widget_Create(void)
 {
-    Widget *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
-    HRESULT hr;
-    ITypeLib *pTypeLib;
-
+    Widget *This;
+    ITypeInfo *pTypeInfo;
+    HRESULT hr = E_FAIL;
+
+    pTypeInfo = get_type_info(&IID_IWidget);
+    if(!pTypeInfo)
+        return NULL;
+
+    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
     This->lpVtbl = &Widget_VTable;
     This->refs = 1;
-
-    hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, &pTypeLib);
-    ok_ole_success(hr, LoadRegTypeLib);
-    if (SUCCEEDED(hr))
-    {
-        ITypeInfo *pTypeInfo;
-        hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IWidget, &pTypeInfo);
-        ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
-        if (SUCCEEDED(hr))
-        {
-            This->pDispatchUnknown = NULL;
-            hr = CreateStdDispatch((IUnknown *)&This->lpVtbl, This, pTypeInfo, &This->pDispatchUnknown);
-            ok_ole_success(hr, CreateStdDispatch);
-            ITypeInfo_Release(pTypeInfo);
-        }
-    }
+    This->pDispatchUnknown = NULL;
+
+    hr = CreateStdDispatch((IUnknown *)&This->lpVtbl, This, pTypeInfo, &This->pDispatchUnknown);
+    ok_ole_success(hr, CreateStdDispatch);
+    ITypeInfo_Release(pTypeInfo);
 
     if (SUCCEEDED(hr))
         return (IWidget *)&This->lpVtbl;
@@ -611,7 +791,7 @@
     }
 }
 
-HRESULT WINAPI KindaEnum_QueryInterface(
+static HRESULT WINAPI KindaEnum_QueryInterface(
     IKindaEnumWidget *iface,
     /* [in] */ REFIID riid,
     /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
@@ -629,7 +809,7 @@
     }
 }
 
-ULONG WINAPI KindaEnum_AddRef(
+static ULONG WINAPI KindaEnum_AddRef(
     IKindaEnumWidget *iface)
 {
     KindaEnum *This = (KindaEnum *)iface;
@@ -637,7 +817,7 @@
     return InterlockedIncrement(&This->refs);
 }
 
-ULONG WINAPI KindaEnum_Release(
+static ULONG WINAPI KindaEnum_Release(
     IKindaEnumWidget *iface)
 {
     KindaEnum *This = (KindaEnum *)iface;
@@ -652,7 +832,7 @@
     return refs;
 }
 
-HRESULT WINAPI KindaEnum_Next(
+static HRESULT WINAPI KindaEnum_Next(
     IKindaEnumWidget *iface,
     /* [out] */ IWidget __RPC_FAR *__RPC_FAR *widget)
 {
@@ -663,20 +843,20 @@
         return E_OUTOFMEMORY;
 }
 
-HRESULT WINAPI KindaEnum_Count(
+static HRESULT WINAPI KindaEnum_Count(
     IKindaEnumWidget *iface,
     /* [out] */ unsigned long __RPC_FAR *count)
 {
     return E_NOTIMPL;
 }
 
-HRESULT WINAPI KindaEnum_Reset(
+static HRESULT WINAPI KindaEnum_Reset(
     IKindaEnumWidget *iface)
 {
     return E_NOTIMPL;
 }
 
-HRESULT WINAPI KindaEnum_Clone(
+static HRESULT WINAPI KindaEnum_Clone(
     IKindaEnumWidget *iface,
     /* [out] */ IKindaEnumWidget __RPC_FAR *__RPC_FAR *ppenum)
 {
@@ -778,12 +958,15 @@
     DWORD tid;
     BSTR bstr;
     ITypeInfo *pTypeInfo;
+    MYSTRUCT mystruct;
+    MYSTRUCT mystructArray[5];
 
     ok(pKEW != NULL, "Widget creation failed\n");
 
     hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
     ok_ole_success(hr, CreateStreamOnHGlobal);
     tid = start_host_object(pStream, &IID_IKindaEnumWidget, (IUnknown *)pKEW, MSHLFLAGS_NORMAL, &thread);
+    IKindaEnumWidget_Release(pKEW);
 
     IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
     hr = CoUnmarshalInterface(pStream, &IID_IKindaEnumWidget, (void **)&pKEW);
@@ -915,6 +1098,11 @@
     hr = IDispatch_Invoke(pDispatch, DISPID_TM_GETOLECOLOR, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
     ok_ole_success(hr, IDispatch_Invoke);
     VariantClear(&varresult);
+
+    /* call StructArgs (direct) */
+    mystruct = MYSTRUCT_BYPTR;
+    memcpy(mystructArray, MYSTRUCT_ARRAY, sizeof(mystructArray));
+    IWidget_StructArgs(pWidget, MYSTRUCT_BYVAL, &mystruct, mystructArray);
 
     /* call Clone */
     dispparams.cNamedArgs = 0;
@@ -1160,6 +1348,37 @@
     hr = DispCallFunc(pWidget, 36, CC_STDCALL, VT_UI4, 4, rgvt, rgpvarg, &varresult);
     ok_ole_success(hr, DispCallFunc);
     VariantClear(&varresult);
+    VariantClear(&vararg[1]);
+    VariantClear(&vararg[2]);
+    IWidget_Release(pWidget);
+}
+
+static void test_StaticWidget(void)
+{
+    ITypeInfo *type_info;
+    DISPPARAMS dispparams;
+    VARIANTARG vararg[4];
+    EXCEPINFO excepinfo;
+    VARIANT varresult;
+    HRESULT hr;
+
+    type_info = get_type_info(&IID_IStaticWidget);
+
+    /* call TestDual */
+    dispparams.cNamedArgs = 0;
+    dispparams.cArgs = 1;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = vararg;
+    V_VT(vararg) = VT_DISPATCH;
+    V_DISPATCH(vararg) = (IDispatch*)&TestDualDisp;
+    VariantInit(&varresult);
+    hr = ITypeInfo_Invoke(type_info, &StaticWidget, DISPID_TM_TESTDUAL, DISPATCH_METHOD,
+            &dispparams, &varresult, &excepinfo, NULL);
+    ok_ole_success(hr, IDispatch_Invoke);
+    ok(V_VT(&varresult) == VT_EMPTY, "vt %x\n", V_VT(&varresult));
+    VariantClear(&varresult);
+
+    ITypeInfo_Release(type_info);
 }
 
 START_TEST(tmarshal)
@@ -1173,6 +1392,10 @@
 
     test_typelibmarshal();
     test_DispCallFunc();
+    test_StaticWidget();
+
+    hr = UnRegisterTypeLib(&LIBID_TestTypelib, 1, 0, LOCALE_NEUTRAL, 1);
+    ok_ole_success(hr, UnRegisterTypeLib);
 
     CoUninitialize();
 }

Modified: trunk/rostests/winetests/oleaut32/tmarshal.idl
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/tmarshal.idl?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/tmarshal.idl [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/tmarshal.idl [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -35,6 +35,12 @@
         STATE_WIDGETIFIED
     } STATE;
 
+    typedef struct tagMYSTRUCT
+    {
+        INT field1;
+        ULONGLONG field2;
+    } MYSTRUCT;
+
     coclass ApplicationObject2;
 
     [
@@ -44,6 +50,17 @@
     interface ISomethingFromDispatch : IDispatch
     {
         HRESULT anotherfn(void);
+    }
+
+    [
+        odl,
+        oleautomation,
+        dual,
+        uuid(3f7e06fe-0bce-46f0-8b7d-3a68393c7967)
+    ]
+    interface ItestDual : IDispatch
+    {
+        HRESULT test();
     }
 
     [
@@ -100,12 +117,26 @@
         [vararg, id(DISPID_TM_VARARG)]
         void VarArg([in] int numexpect, [in] SAFEARRAY(VARIANT) values);
 
+        [id(DISPID_TM_STRUCTARGS)]
+        void StructArgs([in] MYSTRUCT byval, [in] MYSTRUCT *byptr, [in] MYSTRUCT arr[5]);
+
         [id(DISPID_TM_ERROR)]
         HRESULT Error();
 
         [propget, id(DISPID_TM_CLONEINTERFACE)]
         HRESULT CloneInterface([out, retval] ISomethingFromDispatch **ppVal);
-
+    }
+
+    [
+        odl,
+        uuid(a1f8cae3-c947-3c5f-a57c-c88b9b6f3586),
+        oleautomation,
+        dual
+    ]
+    interface IStaticWidget : IDispatch
+    {
+        [id(DISPID_TM_TESTDUAL)]
+        HRESULT TestDual([in] ItestDual *p);
     }
 
     [

Modified: trunk/rostests/winetests/oleaut32/tmarshal.rc
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/tmarshal.rc?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/tmarshal.rc [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/tmarshal.rc [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -27,4 +27,8 @@
 
 #include "wine/wine_common_ver.rc"
 
+/* @makedep: tmarshal.tlb */
 1 TYPELIB LOADONCALL DISCARDABLE tmarshal.tlb
+
+/* @makedep: test_tlb.tlb */
+2 TYPELIB LOADONCALL DISCARDABLE test_tlb.tlb

Modified: trunk/rostests/winetests/oleaut32/tmarshal_dispids.h
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/tmarshal_dispids.h?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/tmarshal_dispids.h [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/tmarshal_dispids.h [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -32,5 +32,7 @@
 #define DISPID_TM_VARARG 13
 #define DISPID_TM_ERROR 14
 #define DISPID_TM_CLONEINTERFACE 15
+#define DISPID_TM_TESTDUAL 16
+#define DISPID_TM_STRUCTARGS 17
 
 #define DISPID_NOA_BSTRRET 1

Modified: trunk/rostests/winetests/oleaut32/typelib.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/typelib.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/typelib.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/typelib.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -27,9 +27,11 @@
 
 #include "windef.h"
 #include "winbase.h"
+
 #include "oleauto.h"
 #include "ocidl.h"
 #include "shlwapi.h"
+#include "initguid.h"
 #include "tmarshal.h"
 
 #define expect_eq(expr, value, type, format) { type _ret = (expr); ok((value) == _ret, #expr " expected " format " got " format "\n", value, _ret); }
@@ -37,10 +39,10 @@
 #define expect_hex(expr, value) expect_eq(expr, (int)value, int, "0x%x")
 #define expect_null(expr) expect_eq(expr, NULL, const void *, "%p")
 
-#define expect_wstr_utf8val(expr, value) \
+#define expect_wstr_acpval(expr, value) \
     { \
         CHAR buf[260]; \
-        expect_eq(!WideCharToMultiByte(CP_UTF8, 0, (expr), -1, buf, 260, NULL, NULL), 0, int, "%d"); \
+        expect_eq(!WideCharToMultiByte(CP_ACP, 0, (expr), -1, buf, 260, NULL, NULL), 0, int, "%d"); \
         ok(lstrcmp(value, buf) == 0, #expr " expected \"%s\" got \"%s\"\n", value, buf); \
     }
 
@@ -513,6 +515,70 @@
     ITypeLib_Release(pTypeLib);
 }
 
+/* RegDeleteTreeW from dlls/advapi32/registry.c */
+static LSTATUS myRegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
+{
+    LONG ret;
+    DWORD dwMaxSubkeyLen, dwMaxValueLen;
+    DWORD dwMaxLen, dwSize;
+    WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
+    HKEY hSubKey = hKey;
+
+    if(lpszSubKey)
+    {
+        ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
+        if (ret) return ret;
+    }
+
+    ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
+            &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
+    if (ret) goto cleanup;
+
+    dwMaxSubkeyLen++;
+    dwMaxValueLen++;
+    dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
+    if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
+    {
+        /* Name too big: alloc a buffer for it */
+        if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
+        {
+            ret = ERROR_NOT_ENOUGH_MEMORY;
+            goto cleanup;
+        }
+    }
+
+    /* Recursively delete all the subkeys */
+    while (TRUE)
+    {
+        dwSize = dwMaxLen;
+        if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
+                          NULL, NULL, NULL)) break;
+
+        ret = myRegDeleteTreeW(hSubKey, lpszName);
+        if (ret) goto cleanup;
+    }
+
+    if (lpszSubKey)
+        ret = RegDeleteKeyW(hKey, lpszSubKey);
+    else
+        while (TRUE)
+        {
+            dwSize = dwMaxLen;
+            if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
+                  NULL, NULL, NULL, NULL)) break;
+
+            ret = RegDeleteValueW(hKey, lpszName);
+            if (ret) goto cleanup;
+        }
+
+cleanup:
+    if (lpszName != szNameBuf)
+        HeapFree(GetProcessHeap(), 0, lpszName);
+    if(lpszSubKey)
+        RegCloseKey(hSubKey);
+    return ret;
+}
+
 static BOOL do_typelib_reg_key(GUID *uid, WORD maj, WORD min, LPCWSTR base, BOOL remove)
 {
     static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
@@ -521,20 +587,29 @@
     WCHAR buf[128];
     HKEY hkey;
     BOOL ret = TRUE;
+    DWORD res;
 
     memcpy(buf, typelibW, sizeof(typelibW));
     StringFromGUID2(uid, buf + lstrlenW(buf), 40);
 
     if (remove)
     {
-        ok(SHDeleteKeyW(HKEY_CLASSES_ROOT, buf) == ERROR_SUCCESS, "SHDeleteKey failed\n");
+        ok(myRegDeleteTreeW(HKEY_CLASSES_ROOT, buf) == ERROR_SUCCESS, "SHDeleteKey failed\n");
         return TRUE;
     }
 
     wsprintfW(buf + lstrlenW(buf), formatW, maj, min );
 
-    if (RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
-                        KEY_WRITE, NULL, &hkey, NULL) != ERROR_SUCCESS)
+    SetLastError(0xdeadbeef);
+    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
+                          KEY_WRITE, NULL, &hkey, NULL);
+    if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        win_skip("W-calls are not implemented\n");
+        return FALSE;
+    }
+
+    if (res != ERROR_SUCCESS)
     {
         trace("RegCreateKeyExW failed\n");
         return FALSE;
@@ -576,7 +651,7 @@
     BSTR path;
 
     status = UuidCreate(&uid);
-    ok(!status, "UuidCreate error %08lx\n", status);
+    ok(!status || status == RPC_S_UUID_LOCAL_ONLY, "UuidCreate error %08lx\n", status);
 
     StringFromGUID2(&uid, uid_str, 40);
     /*trace("GUID: %s\n", wine_dbgstr_w(uid_str));*/
@@ -608,11 +683,13 @@
     HREFTYPE href;
     FUNCDESC *pFD;
     WCHAR path[MAX_PATH];
+    CHAR pathA[MAX_PATH];
     static const WCHAR tl_path[] = {'.','\\','m','i','d','l','_','t','m','a','r','s','h','a','l','.','t','l','b',0};
 
     BOOL use_midl_tlb = 0;
 
-    GetModuleFileNameW(NULL, path, MAX_PATH);
+    GetModuleFileNameA(NULL, pathA, MAX_PATH);
+    MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH);
 
     if(use_midl_tlb)
         memcpy(path, tl_path, sizeof(tl_path));
@@ -1204,7 +1281,7 @@
     int ifcount = sizeof(info)/sizeof(info[0]);
     int iface, func;
 
-    MultiByteToWideChar(CP_UTF8, 0, name, -1, wszName, MAX_PATH);
+    MultiByteToWideChar(CP_ACP, 0, name, -1, wszName, MAX_PATH);
     ole_check(LoadTypeLibEx(wszName, REGKIND_NONE, &typelib));
     expect_eq(ITypeLib_GetTypeInfoCount(typelib), ifcount, UINT, "%d");
     for (iface = 0; iface < ifcount; iface++)
@@ -1217,7 +1294,7 @@
         trace("Interface %s\n", if_info->name);
         ole_check(ITypeLib_GetTypeInfo(typelib, iface, &typeinfo));
         ole_check(ITypeLib_GetDocumentation(typelib, iface, &bstrIfName, NULL, NULL, NULL));
-        expect_wstr_utf8val(bstrIfName, if_info->name);
+        expect_wstr_acpval(bstrIfName, if_info->name);
         SysFreeString(bstrIfName);
 
         ole_check(ITypeInfo_GetTypeAttr(typeinfo, &typeattr));
@@ -1250,7 +1327,7 @@
             ole_check(ITypeInfo_GetNames(typeinfo, desc->memid, namesTab, 256, &cNames));
             for (i = 0; i < cNames; i++)
             {
-                expect_wstr_utf8val(namesTab[i], fn_info->names[i]);
+                expect_wstr_acpval(namesTab[i], fn_info->names[i]);
                 SysFreeString(namesTab[i]);
             }
             expect_null(fn_info->names[cNames]);
@@ -1273,13 +1350,41 @@
 
 #endif
 
+static const char *create_test_typelib(void)
+{
+    static char filename[MAX_PATH];
+    HANDLE file;
+    HRSRC res;
+    void *ptr;
+    DWORD written;
+
+    GetTempFileNameA( ".", "tlb", 0, filename );
+    file = CreateFile( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
+    ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
+    if (file == INVALID_HANDLE_VALUE) return NULL;
+    res = FindResource( GetModuleHandle(0), MAKEINTRESOURCE(2), "TYPELIB" );
+    ok( res != 0, "couldn't find resource\n" );
+    ptr = LockResource( LoadResource( GetModuleHandle(0), res ));
+    WriteFile( file, ptr, SizeofResource( GetModuleHandle(0), res ), &written, NULL );
+    ok( written == SizeofResource( GetModuleHandle(0), res ), "couldn't write resource\n" );
+    CloseHandle( file );
+    return filename;
+}
+
 START_TEST(typelib)
 {
+    const char *filename;
+
     ref_count_test(wszStdOle2);
     test_TypeComp();
     test_CreateDispTypeInfo();
     test_TypeInfo();
     test_QueryPathOfRegTypeLib();
     test_inheritance();
-    test_dump_typelib("test_tlb.tlb");
-}
+
+    if ((filename = create_test_typelib()))
+    {
+        test_dump_typelib( filename );
+        DeleteFile( filename );
+    }
+}

Modified: trunk/rostests/winetests/oleaut32/usrmarshal.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/usrmarshal.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/usrmarshal.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/usrmarshal.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -208,6 +208,7 @@
         LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
     }
     HeapFree(GetProcessHeap(), 0, buffer);
+    lpsa->cLocks = 0;
     SafeArrayDestroy(lpsa);
 
     /* test NULL safe array */
@@ -244,6 +245,7 @@
     check_safearray(buffer, lpsa);
 
     HeapFree(GetProcessHeap(), 0, buffer);
+    lpsa->cLocks = 0;
     SafeArrayDestroy(lpsa);
 
     /* VARTYPE-less arrays can be marshaled if cbElements is 1,2,4 or 8 as type SF_In */
@@ -526,6 +528,13 @@
     V_VT(&v) = VT_I1;
     V_I1(&v) = 0x12;
 
+    /* check_variant_header tests wReserved[123], so initialize to unique values.
+     * (Could probably also do this by setting the variant to a known DECIMAL.)
+     */
+    V_U2(&v).wReserved1 = 0x1234;
+    V_U2(&v).wReserved2 = 0x5678;
+    V_U2(&v).wReserved3 = 0x9abc;
+
     /* Variants have an alignment of 8 */
     rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 1, &v);
     ok(stubMsg.BufferLength == 29, "size %d\n", stubMsg.BufferLength);
@@ -607,11 +616,15 @@
     ok(*(short*)wirev == s, "wv[6] %08x\n", *wirev);
     if (VARIANT_UNMARSHAL_WORKS)
     {
-        VariantInit(&v2);
-        stubMsg.Buffer = buffer;
-        next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
-        ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
-        ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
+        void *mem;
+        VariantInit(&v2);
+        V_VT(&v2) = VT_I2 | VT_BYREF;
+        V_BYREF(&v2) = mem = CoTaskMemAlloc(sizeof(V_I2(&v2)));
+        stubMsg.Buffer = buffer;
+        next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
+        ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
+        ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
+        ok(V_BYREF(&v2) == mem, "didn't reuse existing memory\n");
         ok(*V_I2REF(&v) == *V_I2REF(&v2), "got i2 ref %x expect ui4 ref %x\n", *V_I2REF(&v), *V_I2REF(&v2));
 
         VARIANT_UserFree(&umcb.Flags, &v2);
@@ -843,6 +856,7 @@
 
     /*** DECIMAL ***/
     VarDecFromI4(0x12345678, &dec);
+    dec.wReserved = 0xfedc;          /* Also initialize reserved field, as we check it later */
     VariantInit(&v);
     V_DECIMAL(&v) = dec;
     V_VT(&v) = VT_DECIMAL;
@@ -900,6 +914,13 @@
     if (VARIANT_UNMARSHAL_WORKS)
     {
         VariantInit(&v2);
+        /* check_variant_header tests wReserved[123], so initialize to unique values.
+         * (Could probably also do this by setting the variant to a known DECIMAL.)
+         */
+        V_U2(&v2).wReserved1 = 0x0123;
+        V_U2(&v2).wReserved2 = 0x4567;
+        V_U2(&v2).wReserved3 = 0x89ab;
+
         stubMsg.Buffer = buffer;
         next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
         ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
@@ -1037,7 +1058,6 @@
     lpsa = SafeArrayCreate(VT_R8, 1, &sab);
     *(DWORD *)lpsa->pvData = 0xcafebabe;
     *((DWORD *)lpsa->pvData + 1) = 0xdeadbeef;
-    lpsa->cLocks = 7;
 
     VariantInit(&v);
     V_VT(&v) = VT_UI4 | VT_ARRAY;
@@ -1209,9 +1229,7 @@
         stubMsg.Buffer = buffer;
         next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v3);
         ok(V_VT(&v) == V_VT(&v3), "got vt %d expect %d\n", V_VT(&v), V_VT(&v3));
-        ok(V_VT(V_VARIANTREF(&v)) == V_VT(V_VARIANTREF(&v3)), "vts differ %x %x\n",
-           V_VT(V_VARIANTREF(&v)), V_VT(V_VARIANTREF(&v3)));
-        ok(V_R8(V_VARIANTREF(&v)) == V_R8(V_VARIANTREF(&v3)), "r8s differ\n");
+        ok(V_UNKNOWN(&v) == V_UNKNOWN(&v3), "got %p expect %p\n", V_UNKNOWN(&v), V_UNKNOWN(&v3));
         VARIANT_UserFree(&umcb.Flags, &v3);
         ok(heap_unknown->refs == 1, "%d refcounts of IUnknown leaked\n", heap_unknown->refs - 1);
         IUnknown_Release((IUnknown *)heap_unknown);

Modified: trunk/rostests/winetests/oleaut32/varformat.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/varformat.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/varformat.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/varformat.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -23,7 +23,6 @@
 #include <stdio.h>
 #include <math.h>
 #include <float.h>
-#include <time.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -42,6 +41,7 @@
 
 static HRESULT (WINAPI *pVarFormatNumber)(LPVARIANT,int,int,int,int,ULONG,BSTR*);
 static HRESULT (WINAPI *pVarFormat)(LPVARIANT,LPOLESTR,int,int,ULONG,BSTR*);
+static HRESULT (WINAPI *pVarWeekdayName)(int,int,int,ULONG,BSTR*);
 
 /* Have I8/UI8 data type? */
 #define HAVE_OLEAUT32_I8      HAVE_FUNC(VarI8FromI1)
@@ -63,9 +63,11 @@
   VariantInit(&v); V_VT(&v) = vt; val(&v) = 1; \
   hres = pVarFormatNumber(&v,2,0,0,0,0,&str); \
   ok(hres == S_OK, "VarFormatNumber (vt %d): returned %8x\n", vt, hres); \
-  if (hres == S_OK) \
+  if (hres == S_OK) { \
     ok(str && strcmpW(str,szResult1) == 0, \
-       "VarFormatNumber (vt %d): string different\n", vt)
+       "VarFormatNumber (vt %d): string different\n", vt); \
+    SysFreeString(str); \
+  }
 
 static void test_VarFormatNumber(void)
 {
@@ -125,7 +127,7 @@
 
 static const char *szVarFmtFail = "VT %d|0x%04x Format %s: expected 0x%08x, '%s', got 0x%08x, '%s'\n";
 #define VARFMT(vt,v,val,fmt,ret,str) do { \
-  if (out) SysFreeString(out); out = NULL; \
+  out = NULL; \
   V_VT(&in) = (vt); v(&in) = val; \
   if (fmt) MultiByteToWideChar(CP_ACP, 0, fmt, -1, buffW, sizeof(buffW)/sizeof(WCHAR)); \
   hres = pVarFormat(&in,fmt ? buffW : NULL,fd,fw,flags,&out); \
@@ -134,6 +136,7 @@
   ok(hres == ret && (FAILED(ret) || !strcmp(buff, str)), \
      szVarFmtFail, \
      (vt)&VT_TYPEMASK,(vt)&~VT_TYPEMASK,fmt?fmt:"<null>",ret,str,hres,buff); \
+  SysFreeString(out); \
   } while(0)
 
 typedef struct tagFMTRES
@@ -320,9 +323,12 @@
   VARFMT(VT_I4,V_I4,1,"000###",S_OK,"000001");
   VARFMT(VT_I4,V_I4,1,"#00##00#0",S_OK,"00000001");
   VARFMT(VT_I4,V_I4,1,"1#####0000",S_OK,"10001");
-  todo_wine {
   VARFMT(VT_I4,V_I4,100000,"#,###,###,###",S_OK,"100,000");
-  }
+  VARFMT(VT_I4,V_I4,1,"0,000,000,000",S_OK,"0,000,000,001");
+  VARFMT(VT_I4,V_I4,123456789,"#,#.#",S_OK,"123,456,789.");
+  VARFMT(VT_I4,V_I4,123456789,"###, ###, ###",S_OK,"123, 456, 789");
+  VARFMT(VT_I4,V_I4,1,"#;-#",S_OK,"1");
+  VARFMT(VT_I4,V_I4,-1,"#;-#",S_OK,"-1");
   VARFMT(VT_R8,V_R8,1.23456789,"0#.0#0#0#0#0",S_OK,"01.234567890");
   VARFMT(VT_R8,V_R8,1.2,"0#.0#0#0#0#0",S_OK,"01.200000000");
   VARFMT(VT_R8,V_R8,9.87654321,"#0.#0#0#0#0#",S_OK,"9.87654321");
@@ -364,6 +370,10 @@
   VARFMT(VT_R8,V_R8,1.0001e-27,"##00.0000e-0",S_OK,"1000.1000e-30");
   VARFMT(VT_R8,V_R8,47.11,".0000E+0",S_OK,".4711E+2");
   VARFMT(VT_R8,V_R8,3.0401e-13,"#####.####e-0%",S_OK,"30401.e-15%");
+  VARFMT(VT_R8,V_R8,1.57,"0.00",S_OK,"1.57");
+  VARFMT(VT_R8,V_R8,-1.57,"0.00",S_OK,"-1.57");
+  VARFMT(VT_R8,V_R8,-1.57,"#.##",S_OK,"-1.57");
+  VARFMT(VT_R8,V_R8,-0.1,".#",S_OK,"-.1");
 
 
   /* 'out' is not cleared */
@@ -392,10 +402,120 @@
   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
 }
 
+static const char *szVarWdnFail =
+    "VarWeekdayName (%d, %d, %d, %d, %x): returned %8x, expected %8x\n";
+#define VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, ret, buff, out, freeOut) \
+do { \
+  hres = pVarWeekdayName(iWeekday, fAbbrev, iFirstDay, dwFlags, &out); \
+  if (SUCCEEDED(hres)) { \
+    WideCharToMultiByte(CP_ACP, 0, out, -1, buff, sizeof(buff), 0, 0); \
+    if (freeOut) SysFreeString(out); \
+  } else { \
+    buff[0] = '\0'; \
+  } \
+  ok(hres == ret, \
+     szVarWdnFail, \
+     iWeekday, fAbbrev, iFirstDay, dwFlags, &out, hres, ret \
+     ); \
+} while(0)
+
+#define VARWDN_F(iWeekday, fAbbrev, iFirstDay, dwFlags, ret) \
+  VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, ret, buff, out, 1)
+
+#define VARWDN_O(iWeekday, fAbbrev, iFirstDay, dwFlags) \
+  VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, S_OK, buff, out, 0)
+
+static void test_VarWeekdayName(void)
+{
+  char buff[256];
+  BSTR out = NULL;
+  HRESULT hres;
+  int iWeekday, fAbbrev, iFirstDay;
+  BSTR dayNames[7][2]; /* Monday-Sunday, full/abbr */
+  DWORD defaultFirstDay;
+  int firstDay;
+  int day;
+  int size;
+  DWORD localeValue;
+
+  CHECKPTR(VarWeekdayName);
+
+  SetLastError(0xdeadbeef);
+  GetLocaleInfoW(LOCALE_USER_DEFAULT, 0, NULL, 0);
+  if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+  {
+    skip("GetLocaleInfoW is not implemented\n");
+    return;
+  }
+
+  /* Initialize days' names */
+  for (day = 0; day <= 6; ++day)
+  {
+    for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev)
+    {
+      localeValue = fAbbrev ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1;
+      localeValue += day;
+      size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, NULL, 0);
+      dayNames[day][fAbbrev] = SysAllocStringLen(NULL, size - 1);
+      GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue,
+                     dayNames[day][fAbbrev], size);
+    }
+  }
+
+  /* Get the user's first day of week. 0=Monday, .. */
+  GetLocaleInfoW(
+      LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER,
+      (LPWSTR)&defaultFirstDay, sizeof(defaultFirstDay) / sizeof(WCHAR));
+
+  /* Check invalid arguments */
+  VARWDN_F(0, 0, 4, 0, E_INVALIDARG);
+  VARWDN_F(8, 0, 4, 0, E_INVALIDARG);
+  VARWDN_F(4, 0, -1, 0, E_INVALIDARG);
+  VARWDN_F(4, 0, 8, 0, E_INVALIDARG);
+
+  hres = pVarWeekdayName(1, 0, 0, 0, NULL);
+  ok(E_INVALIDARG == hres,
+     "Null pointer: expected E_INVALIDARG, got 0x%08x\n", hres);
+
+  /* Check all combinations */
+  for (iWeekday = 1; iWeekday <= 7; ++iWeekday)
+  {
+    for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev)
+    {
+      /* 0 = Default, 1 = Sunday, 2 = Monday, .. */
+      for (iFirstDay = 0; iFirstDay <= 7; ++iFirstDay)
+      {
+        VARWDN_O(iWeekday, fAbbrev, iFirstDay, 0);
+        if (iFirstDay == 0)
+          firstDay = defaultFirstDay;
+        else
+          /* Translate from 0=Sunday to 0=Monday in the modulo 7 space */
+          firstDay = iFirstDay - 2;
+        day = (7 + iWeekday - 1 + firstDay) % 7;
+        ok(VARCMP_EQ == VarBstrCmp(out, dayNames[day][fAbbrev],
+                                   LOCALE_USER_DEFAULT, 0),
+           "VarWeekdayName(%d,%d,%d): got wrong dayname: '%s'\n",
+           iWeekday, fAbbrev, iFirstDay, buff);
+        SysFreeString(out);
+      }
+    }
+  }
+
+  /* Cleanup */
+  for (day = 0; day <= 6; ++day)
+  {
+    for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev)
+    {
+      SysFreeString(dayNames[day][fAbbrev]);
+    }
+  }
+}
+
 START_TEST(varformat)
 {
   hOleaut32 = GetModuleHandleA("oleaut32.dll");
 
   test_VarFormatNumber();
   test_VarFormat();
+  test_VarWeekdayName();
 }

Modified: trunk/rostests/winetests/oleaut32/vartest.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/vartest.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/vartest.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/vartest.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -23,7 +23,6 @@
 #include <stdio.h>
 #include <math.h>
 #include <float.h>
-#include <time.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -298,6 +297,7 @@
                             "got %s expected %s\n", variantstr(&result), variantstr(expected) );
     ok_(__FILE__,line)( is_expected_variant( arg, &old_arg ), "Modified argument %s / %s\n",
                         variantstr(&old_arg), variantstr(arg));
+    VariantClear( &result );
 }
 
 static void test_var_call2( int line, HRESULT (WINAPI *func)(LPVARIANT,LPVARIANT,LPVARIANT),
@@ -317,6 +317,7 @@
                         variantstr(&old_left), variantstr(left));
     ok_(__FILE__,line)( is_expected_variant( right, &old_right ), "Modified right argument %s / %s\n",
                         variantstr(&old_right), variantstr(right));
+    VariantClear( &result );
 }
 
 
@@ -621,9 +622,12 @@
          "Copy(bad src): expected 0x%X, got 0x%X for src vt %d|0x%X\n",
          hExpected, hres, vt, ExtraFlags[i]);
       if (hres == S_OK)
+      {
         ok(V_VT(&vDst) == (vt|ExtraFlags[i]),
            "Copy(bad src): expected vt = %d, got %d\n",
            vt | ExtraFlags[i], V_VT(&vDst));
+        VariantClear(&vDst);
+      }
     }
   }
   
@@ -642,6 +646,7 @@
     {
       ok(*V_BSTR(&vDst) == 0, "Copy(NULL BSTR): result not empty\n");
     }
+    VariantClear(&vDst);
   }
 }
 
@@ -813,6 +818,7 @@
              vt, ExtraFlags[i] & ~VT_BYREF,
              V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
         }
+        VariantClear(&vDst);
       }
     }
   }
@@ -1050,7 +1056,7 @@
   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
   EXPECT2(0,FAILDIG);
 
-  /* Doesn't recognise hex in .asm sytax */
+  /* Doesn't recognise hex in .asm syntax */
   CONVERT("0h", NUMPRS_HEX_OCT);
   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
   EXPECT2(0,FAILDIG);
@@ -1060,7 +1066,7 @@
   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
   EXPECT2(0,FAILDIG);
 
-  /* Doesn't recognise hex format humbers at all! */
+  /* Doesn't recognise hex format numbers at all! */
   CONVERT("0x0", NUMPRS_HEX_OCT);
   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
   EXPECT2(0,FAILDIG);
@@ -2078,7 +2084,12 @@
                     leftvt == VT_RECORD || rightvt == VT_RECORD)
                 {
                     if (leftvt == VT_RECORD && rightvt == VT_I8)
-                        expectedhres = DISP_E_TYPEMISMATCH;
+                    {
+                        if (HAVE_OLEAUT32_I8)
+                            expectedhres = DISP_E_TYPEMISMATCH;
+                        else
+                            expectedhres = DISP_E_BADVARTYPE;
+                    }
                     else if (leftvt < VT_UI1 && rightvt == VT_RECORD)
                         expectedhres = DISP_E_TYPEMISMATCH;
                     else if (leftvt >= VT_UI1 && rightvt == VT_RECORD)
@@ -2726,6 +2737,9 @@
   hres = pVarMod(&v1,&v2,&vDst);
   ok(hres == DISP_E_BADVARTYPE && V_VT(&vDst) == VT_EMPTY,
      "VarMod: expected 0x%x,%d, got 0x%X,%d\n", DISP_E_BADVARTYPE, VT_EMPTY, hres, V_VT(&vDst));
+
+  SysFreeString(strNum0);
+  SysFreeString(strNum1);
 }
 
 static HRESULT (WINAPI *pVarFix)(LPVARIANT,LPVARIANT);
@@ -3104,8 +3118,8 @@
 
 static void test_VarRound(void)
 {
-    static WCHAR szNumMin[] = {'-','1','.','4','5','\0' };
-    static WCHAR szNum[] = {'1','.','4','5','\0' };
+    static WCHAR szNumMin[] = {'-','1','.','4','4','9','\0' };
+    static WCHAR szNum[] = {'1','.','4','5','1','\0' };
     HRESULT hres;
     VARIANT v, exp, vDst;
     CY *pcy = &V_CY(&v);
@@ -3140,7 +3154,7 @@
     /* floating point numbers aren't exactly equal and we can't just
      * compare the first few digits. */
     VARROUND(DATE,1.451,1,DATE,1.5);
-    VARROUND(DATE,-1.45,1,DATE,-1.4);
+    VARROUND(DATE,-1.449,1,DATE,-1.4);
 
     /* replace the decimal separator */
     GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
@@ -3148,7 +3162,7 @@
         szNumMin[2] = buff[0];
         szNum[1] = buff[0];
         VARROUND(BSTR,(BSTR)szNumMin,1,R8,-1.40);
-        if (0) { VARROUND(BSTR,(BSTR)szNum,1,R8,1.50); }
+        VARROUND(BSTR,(BSTR)szNum,1,R8,1.50);
     } else {
         skip("Skipping VarRound(BSTR) as decimal separator is '%s'\n", buff);
     }
@@ -3381,9 +3395,11 @@
     VARXOR(EMPTY,0,R8,1,I4,1);
     rbstr = SysAllocString(szFalse);
     VARXOR(EMPTY,0,BSTR,rbstr,I2,0);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(EMPTY,0,BSTR,rbstr,I2,-1);
     VARXORCY(EMPTY,0,10000,I4,1);
+    SysFreeString(rbstr);
 
     /* NULL OR 0 = NULL. NULL OR n = n */
     VARXOR(NULL,0,NULL,0,NULL,0);
@@ -3419,8 +3435,10 @@
     VARXOR(NULL,0,R8,1,NULL,0);
     rbstr = SysAllocString(szFalse);
     VARXOR(NULL,0,BSTR,rbstr,NULL,0);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(NULL,0,BSTR,rbstr,NULL,0);
+    SysFreeString(rbstr);
     VARXORCY(NULL,0,10000,NULL,0);
     VARXORCY(NULL,0,0,NULL,0);
 
@@ -3477,9 +3495,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_FALSE);
     VARXOR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_TRUE);
     VARXOR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_FALSE);
+    SysFreeString(rbstr);
     VARXORCY(BOOL,VARIANT_TRUE,10000,I4,-2);
     VARXORCY(BOOL,VARIANT_TRUE,0,I4,-1);
     VARXORCY(BOOL,VARIANT_FALSE,0,I4,0);
@@ -3528,9 +3548,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(I1,0,BSTR,rbstr,I4,0);
     VARXOR(I1,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(I1,0,BSTR,rbstr,I4,-1);
     VARXOR(I1,-1,BSTR,rbstr,I4,0);
+    SysFreeString(rbstr);
     VARXORCY(I1,-1,10000,I4,-2);
     VARXORCY(I1,-1,0,I4,-1);
     VARXORCY(I1,0,0,I4,0);
@@ -3576,9 +3598,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(UI1,0,BSTR,rbstr,I2,0);
     VARXOR(UI1,255,BSTR,rbstr,I2,255);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(UI1,0,BSTR,rbstr,I2,-1);
     VARXOR(UI1,255,BSTR,rbstr,I2,-256);
+    SysFreeString(rbstr);
     VARXORCY(UI1,255,10000,I4,254);
     VARXORCY(UI1,255,0,I4,255);
     VARXORCY(UI1,0,0,I4,0);
@@ -3621,9 +3645,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(I2,0,BSTR,rbstr,I2,0);
     VARXOR(I2,-1,BSTR,rbstr,I2,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(I2,0,BSTR,rbstr,I2,-1);
     VARXOR(I2,-1,BSTR,rbstr,I2,0);
+    SysFreeString(rbstr);
     VARXORCY(I2,-1,10000,I4,-2);
     VARXORCY(I2,-1,0,I4,-1);
     VARXORCY(I2,0,0,I4,0);
@@ -3663,9 +3689,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(UI2,0,BSTR,rbstr,I4,0);
     VARXOR(UI2,65535,BSTR,rbstr,I4,65535);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(UI2,0,BSTR,rbstr,I4,-1);
     VARXOR(UI2,65535,BSTR,rbstr,I4,-65536);
+    SysFreeString(rbstr);
     VARXORCY(UI2,65535,10000,I4,65534);
     VARXORCY(UI2,65535,0,I4,65535);
     VARXORCY(UI2,0,0,I4,0);
@@ -3702,9 +3730,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(I4,0,BSTR,rbstr,I4,0);
     VARXOR(I4,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(I4,0,BSTR,rbstr,I4,-1);
     VARXOR(I4,-1,BSTR,rbstr,I4,0);
+    SysFreeString(rbstr);
     VARXORCY(I4,-1,10000,I4,-2);
     VARXORCY(I4,-1,0,I4,-1);
     VARXORCY(I4,0,0,I4,0);
@@ -3738,9 +3768,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(UI4,0,BSTR,rbstr,I4,0);
     VARXOR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(UI4,0,BSTR,rbstr,I4,-1);
     VARXOR(UI4,0xffffffff,BSTR,rbstr,I4,0);
+    SysFreeString(rbstr);
     VARXORCY(UI4,0xffffffff,10000,I4,-2);
     VARXORCY(UI4,0xffffffff,0,I4,-1);
     VARXORCY(UI4,0,0,I4,0);
@@ -3771,9 +3803,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(R4,0,BSTR,rbstr,I4,0);
     VARXOR(R4,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(R4,0,BSTR,rbstr,I4,-1);
     VARXOR(R4,-1,BSTR,rbstr,I4,0);
+    SysFreeString(rbstr);
     VARXORCY(R4,-1,10000,I4,-2);
     VARXORCY(R4,-1,0,I4,-1);
     VARXORCY(R4,0,0,I4,0);
@@ -3801,9 +3835,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(R8,0,BSTR,rbstr,I4,0);
     VARXOR(R8,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(R8,0,BSTR,rbstr,I4,-1);
     VARXOR(R8,-1,BSTR,rbstr,I4,0);
+    SysFreeString(rbstr);
     VARXORCY(R8,-1,10000,I4,-2);
     VARXORCY(R8,-1,0,I4,-1);
     VARXORCY(R8,0,0,I4,0);
@@ -3828,9 +3864,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(DATE,0,BSTR,rbstr,I4,0);
     VARXOR(DATE,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(DATE,0,BSTR,rbstr,I4,-1);
     VARXOR(DATE,-1,BSTR,rbstr,I4,0);
+    SysFreeString(rbstr);
     VARXORCY(DATE,-1,10000,I4,-2);
     VARXORCY(DATE,-1,0,I4,-1);
     VARXORCY(DATE,0,0,I4,0);
@@ -3847,9 +3885,11 @@
         rbstr = SysAllocString(szFalse);
         VARXOR(I8,0,BSTR,rbstr,I8,0);
         VARXOR(I8,-1,BSTR,rbstr,I8,-1);
+        SysFreeString(rbstr);
         rbstr = SysAllocString(szTrue);
         VARXOR(I8,0,BSTR,rbstr,I8,-1);
         VARXOR(I8,-1,BSTR,rbstr,I8,0);
+        SysFreeString(rbstr);
         VARXORCY(I8,-1,10000,I8,-2);
         VARXORCY(I8,-1,0,I8,-1);
         VARXORCY(I8,0,0,I8,0);
@@ -3866,9 +3906,11 @@
         rbstr = SysAllocString(szFalse);
         VARXOR(UI8,0,BSTR,rbstr,I4,0);
         VARXOR(UI8,0xffff,BSTR,rbstr,I4,0xffff);
+        SysFreeString(rbstr);
         rbstr = SysAllocString(szTrue);
         VARXOR(UI8,0,BSTR,rbstr,I4,-1);
         VARXOR(UI8,0xffff,BSTR,rbstr,I4,-65536);
+        SysFreeString(rbstr);
         VARXORCY(UI8,0xffff,10000,I4,65534);
         VARXORCY(UI8,0xffff,0,I4,0xffff);
         VARXORCY(UI8,0,0,I4,0);
@@ -3883,9 +3925,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(INT,0,BSTR,rbstr,I4,0);
     VARXOR(INT,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(INT,0,BSTR,rbstr,I4,-1);
     VARXOR(INT,-1,BSTR,rbstr,I4,0);
+    SysFreeString(rbstr);
     VARXORCY(INT,-1,10000,I4,-2);
     VARXORCY(INT,-1,0,I4,-1);
     VARXORCY(INT,0,0,I4,0);
@@ -3896,9 +3940,11 @@
     rbstr = SysAllocString(szFalse);
     VARXOR(UINT,0,BSTR,rbstr,I4,0);
     VARXOR(UINT,0xffff,BSTR,rbstr,I4,0xffff);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(UINT,0,BSTR,rbstr,I4,-1);
     VARXOR(UINT,0xffff,BSTR,rbstr,I4,-65536);
+    SysFreeString(rbstr);
     VARXORCY(UINT,0xffff,10000,I4,65534);
     VARXORCY(UINT,0xffff,0,I4,0xffff);
     VARXORCY(UINT,0,0,I4,0);
@@ -3906,13 +3952,18 @@
     lbstr = SysAllocString(szFalse);
     rbstr = SysAllocString(szFalse);
     VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,0);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
+    SysFreeString(lbstr);
     lbstr = SysAllocString(szTrue);
     VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_FALSE);
     VARXORCY(BSTR,lbstr,10000,I4,-2);
+    SysFreeString(lbstr);
     lbstr = SysAllocString(szFalse);
     VARXORCY(BSTR,lbstr,10000,I4,1);
+    SysFreeString(lbstr);
+    SysFreeString(rbstr);
 }
 
 static HRESULT (WINAPI *pVarOr)(LPVARIANT,LPVARIANT,LPVARIANT);
@@ -4080,8 +4131,10 @@
     VAROR(EMPTY,0,R8,1,I4,1);
     rbstr = SysAllocString(szFalse);
     VAROR(EMPTY,0,BSTR,rbstr,I2,0);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(EMPTY,0,BSTR,rbstr,I2,-1);
+    SysFreeString(rbstr);
     VARORCY(EMPTY,0,10000,I4,1);
 
     /* NULL OR 0 = NULL. NULL OR n = n */
@@ -4118,8 +4171,10 @@
     VAROR(NULL,0,R8,1,I4,1);
     rbstr = SysAllocString(szFalse);
     VAROR(NULL,0,BSTR,rbstr,NULL,0);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(NULL,0,BSTR,rbstr,BOOL,VARIANT_TRUE);
+    SysFreeString(rbstr);
     VARORCY(NULL,0,10000,I4,1);
     VARORCY(NULL,0,0,NULL,0);
 
@@ -4176,9 +4231,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_FALSE);
     VAROR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_TRUE);
     VAROR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
+    SysFreeString(rbstr);
     VARORCY(BOOL,VARIANT_TRUE,10000,I4,-1);
     VARORCY(BOOL,VARIANT_TRUE,0,I4,-1);
     VARORCY(BOOL,VARIANT_FALSE,0,I4,0);
@@ -4227,9 +4284,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(I1,0,BSTR,rbstr,I4,0);
     VAROR(I1,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(I1,0,BSTR,rbstr,I4,-1);
     VAROR(I1,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(I1,-1,10000,I4,-1);
     VARORCY(I1,-1,0,I4,-1);
     VARORCY(I1,0,0,I4,0);
@@ -4275,9 +4334,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(UI1,0,BSTR,rbstr,I2,0);
     VAROR(UI1,255,BSTR,rbstr,I2,255);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(UI1,0,BSTR,rbstr,I2,-1);
     VAROR(UI1,255,BSTR,rbstr,I2,-1);
+    SysFreeString(rbstr);
     VARORCY(UI1,255,10000,I4,255);
     VARORCY(UI1,255,0,I4,255);
     VARORCY(UI1,0,0,I4,0);
@@ -4320,9 +4381,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(I2,0,BSTR,rbstr,I2,0);
     VAROR(I2,-1,BSTR,rbstr,I2,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(I2,0,BSTR,rbstr,I2,-1);
     VAROR(I2,-1,BSTR,rbstr,I2,-1);
+    SysFreeString(rbstr);
     VARORCY(I2,-1,10000,I4,-1);
     VARORCY(I2,-1,0,I4,-1);
     VARORCY(I2,0,0,I4,0);
@@ -4362,9 +4425,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(UI2,0,BSTR,rbstr,I4,0);
     VAROR(UI2,65535,BSTR,rbstr,I4,65535);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(UI2,0,BSTR,rbstr,I4,-1);
     VAROR(UI2,65535,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(UI2,65535,10000,I4,65535);
     VARORCY(UI2,65535,0,I4,65535);
     VARORCY(UI2,0,0,I4,0);
@@ -4401,9 +4466,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(I4,0,BSTR,rbstr,I4,0);
     VAROR(I4,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(I4,0,BSTR,rbstr,I4,-1);
     VAROR(I4,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(I4,-1,10000,I4,-1);
     VARORCY(I4,-1,0,I4,-1);
     VARORCY(I4,0,0,I4,0);
@@ -4437,9 +4504,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(UI4,0,BSTR,rbstr,I4,0);
     VAROR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(UI4,0,BSTR,rbstr,I4,-1);
     VAROR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(UI4,0xffffffff,10000,I4,-1);
     VARORCY(UI4,0xffffffff,0,I4,-1);
     VARORCY(UI4,0,0,I4,0);
@@ -4470,9 +4539,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(R4,0,BSTR,rbstr,I4,0);
     VAROR(R4,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(R4,0,BSTR,rbstr,I4,-1);
     VAROR(R4,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(R4,-1,10000,I4,-1);
     VARORCY(R4,-1,0,I4,-1);
     VARORCY(R4,0,0,I4,0);
@@ -4500,9 +4571,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(R8,0,BSTR,rbstr,I4,0);
     VAROR(R8,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(R8,0,BSTR,rbstr,I4,-1);
     VAROR(R8,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(R8,-1,10000,I4,-1);
     VARORCY(R8,-1,0,I4,-1);
     VARORCY(R8,0,0,I4,0);
@@ -4527,9 +4600,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(DATE,0,BSTR,rbstr,I4,0);
     VAROR(DATE,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(DATE,0,BSTR,rbstr,I4,-1);
     VAROR(DATE,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(DATE,-1,10000,I4,-1);
     VARORCY(DATE,-1,0,I4,-1);
     VARORCY(DATE,0,0,I4,0);
@@ -4551,9 +4626,11 @@
         rbstr = SysAllocString(szFalse);
         VAROR(I8,0,BSTR,rbstr,I8,0);
         VAROR(I8,-1,BSTR,rbstr,I8,-1);
+        SysFreeString(rbstr);
         rbstr = SysAllocString(szTrue);
         VAROR(I8,0,BSTR,rbstr,I8,-1);
         VAROR(I8,-1,BSTR,rbstr,I8,-1);
+        SysFreeString(rbstr);
         VARORCY(I8,-1,10000,I8,-1);
         VARORCY(I8,-1,0,I8,-1);
         VARORCY(I8,0,0,I8,0);
@@ -4570,9 +4647,11 @@
         rbstr = SysAllocString(szFalse);
         VAROR(UI8,0,BSTR,rbstr,I4,0);
         VAROR(UI8,0xffff,BSTR,rbstr,I4,0xffff);
+        SysFreeString(rbstr);
         rbstr = SysAllocString(szTrue);
         VAROR(UI8,0,BSTR,rbstr,I4,-1);
         VAROR(UI8,0xffff,BSTR,rbstr,I4,-1);
+        SysFreeString(rbstr);
         VARORCY(UI8,0xffff,10000,I4,0xffff);
         VARORCY(UI8,0xffff,0,I4,0xffff);
         VARORCY(UI8,0,0,I4,0);
@@ -4587,9 +4666,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(INT,0,BSTR,rbstr,I4,0);
     VAROR(INT,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(INT,0,BSTR,rbstr,I4,-1);
     VAROR(INT,-1,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(INT,-1,10000,I4,-1);
     VARORCY(INT,-1,0,I4,-1);
     VARORCY(INT,0,0,I4,0);
@@ -4600,9 +4681,11 @@
     rbstr = SysAllocString(szFalse);
     VAROR(UINT,0,BSTR,rbstr,I4,0);
     VAROR(UINT,0xffff,BSTR,rbstr,I4,0xffff);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(UINT,0,BSTR,rbstr,I4,-1);
     VAROR(UINT,0xffff,BSTR,rbstr,I4,-1);
+    SysFreeString(rbstr);
     VARORCY(UINT,0xffff,10000,I4,0xffff);
     VARORCY(UINT,0xffff,0,I4,0xffff);
     VARORCY(UINT,0,0,I4,0);
@@ -4610,13 +4693,18 @@
     lbstr = SysAllocString(szFalse);
     rbstr = SysAllocString(szFalse);
     VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,0);
+    SysFreeString(rbstr);
     rbstr = SysAllocString(szTrue);
     VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
+    SysFreeString(lbstr);
     lbstr = SysAllocString(szTrue);
     VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
     VARORCY(BSTR,lbstr,10000,I4,-1);
+    SysFreeString(lbstr);
     lbstr = SysAllocString(szFalse);
     VARORCY(BSTR,lbstr,10000,I4,1);
+    SysFreeString(lbstr);
+    SysFreeString(rbstr);
 }
 
 static HRESULT (WINAPI *pVarEqv)(LPVARIANT,LPVARIANT,LPVARIANT);
@@ -5049,6 +5137,8 @@
                        leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
                        V_VT(&result));
                 }
+                /* Note, we don't clear left/right deliberately here */
+                VariantClear(&result);
             }
         }
     }
@@ -5090,6 +5180,7 @@
     ok(hres == S_OK && V_VT(&result) == VT_BSTR, "VarAdd: expected coerced type VT_BSTR, got %s!\n", vtstr(V_VT(&result)));
     hres = VarR8FromStr(V_BSTR(&result), 0, 0, &r);
     ok(hres == S_OK && EQ_DOUBLE(r, 1212), "VarAdd: BSTR value %f, expected %f\n", r, (double)1212);
+    VariantClear(&result);
 
     /* Manuly test some VT_CY and VT_DECIMAL variants */
     V_VT(&cy) = VT_CY;
@@ -5114,6 +5205,7 @@
     ok(hres == S_OK && V_VT(&result) == VT_DECIMAL, "VarAdd: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
     hres = VarR8FromDec(&V_DECIMAL(&result), &r);
     ok(hres == S_OK && EQ_DOUBLE(r, -15.2), "VarAdd: DECIMAL value %f, expected %f\n", r, (double)-15.2);
+    VariantClear(&result);
 
     SysFreeString(lbstr);
     SysFreeString(rbstr);
@@ -5230,18 +5322,27 @@
             V_VT(&left) = leftvt;
             V_VT(&right) = rightvt;
 
-            if (leftvt == VT_BSTR)
-                V_BSTR(&left) = SysAllocString(sz_empty);
-            if (rightvt == VT_BSTR)
-                V_BSTR(&right) = SysAllocString(sz_empty);
-            if (leftvt == VT_DATE)
-                V_DATE(&left) = 0.0;
-            if (rightvt == VT_DATE)
-                V_DATE(&right) = 0.0;
-            if (leftvt == VT_DECIMAL)
-                VarDecFromR8(0.0, &V_DECIMAL(&left));
-            if (rightvt == VT_DECIMAL)
-                VarDecFromR8(0.0, &V_DECIMAL(&right));
+            switch (leftvt) {
+            case VT_BSTR:
+                V_BSTR(&left) = SysAllocString(sz_empty); break;
+            case VT_DATE:
+                V_DATE(&left) = 0.0; break;
+            case VT_DECIMAL:
+                VarDecFromR8(0.0, &V_DECIMAL(&left)); break;
+            default:
+                V_I8(&left) = 0;
+            }
+
+            switch (rightvt) {
+            case VT_BSTR:
+                V_BSTR(&right) = SysAllocString(sz_empty); break;
+            case VT_DATE:
+                V_DATE(&right) = 0.0; break;
+            case VT_DECIMAL:
+                VarDecFromR8(0.0, &V_DECIMAL(&right)); break;
+            default:
+                V_I8(&right) = 0;
+            }
 
             hres = VarCat(&left, &right, &result);
 
@@ -5261,7 +5362,7 @@
         }
     }
 
-    /* Runnning single comparison tests to compare outputs */
+    /* Running single comparison tests to compare outputs */
 
     /* Test concat strings */
     V_VT(&left) = VT_BSTR;
@@ -5314,8 +5415,9 @@
     V_BSTR(&expected) = SysAllocString(sz12_true);
     hres = VarCat(&left,&right,&result);
     ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
-    ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
-        "VarCat: VT_INT concat with VT_BOOL (TRUE) returned incorrect result\n");
+    hres = VarCmp(&result,&expected,lcid,0);
+    ok(hres == VARCMP_EQ ||
+       broken(hres == VARCMP_GT), "Expected VARCMP_EQ, got %08x\n", hres);
 
     VariantClear(&left);
     VariantClear(&right);
@@ -5330,8 +5432,9 @@
     V_BSTR(&expected) = SysAllocString(sz12_false);
     hres = VarCat(&left,&right,&result);
     ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
-    ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
-        "VarCat: VT_INT concat with VT_BOOL (FALSE) returned inncorrect result\n");
+    hres = VarCmp(&result,&expected,lcid,0);
+    ok(hres == VARCMP_EQ ||
+       broken(hres == VARCMP_GT), "Expected VARCMP_EQ, got %08x\n", hres);
 
     VariantClear(&left);
     VariantClear(&right);
@@ -5380,6 +5483,7 @@
     VariantClear(&left);
     VariantClear(&right);
     VariantClear(&result);
+    VariantClear(&expected);
 
     /* Test concat dates with strings */
     V_VT(&left) = VT_BSTR;
@@ -6273,7 +6377,7 @@
         }
     }
 
-    /* VARCMP{,EX} run each 4 tests with a permutation of all posible
+    /* VARCMP{,EX} run each 4 tests with a permutation of all possible
        input variants with (1) and without (0) VT_RESERVED set. The order
        of the permutations is (0,0); (1,0); (0,1); (1,1) */
     VARCMP(INT,4711,I2,4711,VARCMP_EQ);
@@ -6859,11 +6963,20 @@
         "VARPOW: CY value %f, expected %f\n", V_R8(&result), 4.0);
 
     hres = pVarPow(&cy, &right, &result);
-    ok(hres == S_OK && V_VT(&result) == VT_R8,
-        "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
-        S_OK, hres, vtstr(V_VT(&result)));
-    ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 4.0),
-        "VARPOW: CY value %f, expected %f\n", V_R8(&result), 4.0);
+    if (hres == S_OK)
+    {
+        ok(hres == S_OK && V_VT(&result) == VT_R8,
+           "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
+           S_OK, hres, vtstr(V_VT(&result)));
+        ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 4.0),
+           "VARPOW: CY value %f, expected %f\n", V_R8(&result), 4.0);
+    }
+    else
+    {
+        ok(hres == DISP_E_BADVARTYPE && V_VT(&result) == VT_EMPTY,
+           "VARPOW: expected coerced hres 0x%X type VT_EMPTY, got hres 0x%X type %s!\n",
+           DISP_E_BADVARTYPE, hres, vtstr(V_VT(&result)));
+    }
 
     hres = pVarPow(&left, &cy, &result);
     ok(hres == S_OK && V_VT(&result) == VT_R8,
@@ -6887,11 +7000,20 @@
         "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 4.0);
 
     hres = pVarPow(&dec, &right, &result);
-    ok(hres == S_OK && V_VT(&result) == VT_R8,
-        "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
-        S_OK, hres, vtstr(V_VT(&result)));
-    ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 4.0),
-        "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 4.0);
+    if (hres == S_OK)
+    {
+        ok(hres == S_OK && V_VT(&result) == VT_R8,
+           "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
+           S_OK, hres, vtstr(V_VT(&result)));
+        ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 4.0),
+           "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 4.0);
+    }
+    else
+    {
+        ok(hres == DISP_E_BADVARTYPE && V_VT(&result) == VT_EMPTY,
+           "VARPOW: expected coerced hres 0x%X type VT_EMPTY, got hres 0x%X type %s!\n",
+           DISP_E_BADVARTYPE, hres, vtstr(V_VT(&result)));
+    }
 
     SysFreeString(num2_str);
     SysFreeString(num3_str);

Modified: trunk/rostests/winetests/oleaut32/vartype.c
URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/oleaut32/vartype.c?rev=38570&r1=38569&r2=38570&view=diff
==============================================================================
--- trunk/rostests/winetests/oleaut32/vartype.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/oleaut32/vartype.c [iso-8859-1] Sun Jan  4 13:19:05 2009
@@ -498,6 +498,7 @@
 
 static HRESULT (WINAPI *pVarBstrFromR4)(FLOAT,LCID,ULONG,BSTR*);
 static HRESULT (WINAPI *pVarBstrFromDate)(DATE,LCID,ULONG,BSTR*);
+static HRESULT (WINAPI *pVarBstrFromCy)(CY,LCID,ULONG,BSTR*);
 static HRESULT (WINAPI *pVarBstrFromDec)(DECIMAL*,LCID,ULONG,BSTR*);
 static HRESULT (WINAPI *pVarBstrCmp)(BSTR,BSTR,LCID,ULONG);
 
@@ -1097,7 +1098,7 @@
   dispatch.vt = VT_UI1;
   dispatch.bFailInvoke = FALSE;
 
-  hres = VarUI1FromDisp((IDispatch*)&dispatch, in, &out);
+  hres = pVarUI1FromDisp((IDispatch*)&dispatch, in, &out);
   trace("0x%08x\n", hres);
 
   hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_UI1);
@@ -1105,7 +1106,7 @@
 
   dispatch.bFailInvoke = TRUE;
 
-  hres = VarUI1FromDisp((IDispatch*)&dispatch, in, &out);
+  hres = pVarUI1FromDisp((IDispatch*)&dispatch, in, &out);
   trace("0x%08x\n", hres);
 
   hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_UI1);
@@ -3322,7 +3323,7 @@
   CHECKPTR(VarDateFromStr);
   CHECKPTR(SystemTimeToVariantTime);
 
-  /* Some date formats are relative, so we need to find the cuurent year */
+  /* Some date formats are relative, so we need to find the current year */
   GetSystemTime(&st);
   st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;
   DFS(NULL); EXPECT_MISMATCH;
@@ -4800,18 +4801,80 @@
   BSTR_DATE(2958465.0, "12/31/9999");
 }
 
-#define BSTR_DEC(l, a, b, c, d, e) \
-  SETDEC(l, a,b,c,d);\
-  hres = VarBstrFromDec(&l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
+#define BSTR_CY(l, a, b, e) \
+  S(l).Lo = b; S(l).Hi = a; \
+  hres = pVarBstrFromCy(l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
   ok(hres == S_OK, "got hres 0x%08x\n", hres);\
   if (hres== S_OK && bstr)\
   {\
     ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\
   }
 
+static void test_VarBstrFromCy(void)
+{
+  LCID lcid;
+  HRESULT hres;
+  BSTR bstr = NULL;
+  CY l;
+
+  static const WCHAR szZero[] = {'0', '\0'};
+  static const WCHAR szOne[] = {'1', '\0'};
+  static const WCHAR szOnePointFive[] = {'1','.','5','\0'};
+  static const WCHAR szMinusOnePointFive[] = {'-','1','.','5','\0'};
+  static const WCHAR szBigNum1[] = {'4','2','9','4','9','6','.','7','2','9','5','\0'};    /* (1 << 32) - 1 / 1000 */
+  static const WCHAR szBigNum2[] = {'4','2','9','4','9','6','.','7','2','9','6','\0'};    /* (1 << 32) / 1000 */
+  static const WCHAR szBigNum3[] = {'9','2','2','3','3','7','2','0','3','6','8','5','4','7','7','.','5','8','0','7','\0'};    /* ((1 << 63) - 1)/10000 */
+
+  static const WCHAR szSmallNumber_English[] = {'0','.','0','0','0','9','\0'};
+  static const WCHAR szSmallNumber_Spanish[] = {'0',',','0','0','0','9','\0'};
+
+  CHECKPTR(VarBstrFromCy);
+  lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
+
+  /* check zero */
+  BSTR_CY(l, 0,0, szZero);
+
+  /* check one */
+  BSTR_CY(l, 0, 10000, szOne);
+
+  /* check one point five */
+  BSTR_CY(l, 0, 15000, szOnePointFive);
+
+  /* check minus one point five */
+  BSTR_CY(l, 0xffffffff, ((15000)^0xffffffff)+1, szMinusOnePointFive);
+
+  /* check bignum (1) */
+  BSTR_CY(l, 0, 0xffffffff, szBigNum1);
+
+  /* check bignum (2) */
+  BSTR_CY(l, 1,0, szBigNum2);
+
+  /* check bignum (3) */
+  BSTR_CY(l, 0x7fffffff,0xffffffff, szBigNum3);
+
+  /* check leading zeros and decimal sep. for English locale */
+  BSTR_CY(l, 0,9, szSmallNumber_English);
+
+  lcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
+
+  /* check leading zeros and decimal sep. for Spanish locale */
+  BSTR_CY(l, 0,9, szSmallNumber_Spanish);
+}
+
+#undef BSTR_CY
+
+#define BSTR_DEC(l, a, b, c, d, e) \
+  SETDEC(l, a,b,c,d);\
+  hres = pVarBstrFromDec(&l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
+  ok(hres == S_OK, "got hres 0x%08x\n", hres);\
+  if (hres== S_OK && bstr)\
+  {\
+    ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\
+  }
+
 #define BSTR_DEC64(l, a, b, c, x, d, e) \
   SETDEC64(l, a,b,c,x,d);\
-  hres = VarBstrFromDec(&l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
+  hres = pVarBstrFromDec(&l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
   ok(hres == S_OK, "got hres 0x%08x\n", hres);\
   if (hres== S_OK && bstr)\
   {\
@@ -4928,12 +4991,12 @@
     bstr = SysAllocString(sz);
     bstrempty = SysAllocString(szempty);
     
-    /* NULL handling. Yepp, MSDN is totaly wrong here */
+    /* NULL handling. Yepp, MSDN is totally wrong here */
     VARBSTRCMP(NULL,NULL,0,VARCMP_EQ);
     VARBSTRCMP(bstr,NULL,0,VARCMP_GT);
     VARBSTRCMP(NULL,bstr,0,VARCMP_LT);
 
-    /* NULL and empty string comparisions */
+    /* NULL and empty string comparisons */
     VARBSTRCMP(bstrempty,NULL,0,VARCMP_EQ);
     VARBSTRCMP(NULL,bstrempty,0,VARCMP_EQ);
 
@@ -5139,7 +5202,8 @@
 
     changed = SysReAllocString(&str, szSmaller);
     ok (changed == 1, "Expected 1, got %d\n", changed);
-    ok (str == oldstr, "Created new string\n");
+    /* Vista creates a new string, but older versions reuse the existing string. */
+    /*ok (str == oldstr, "Created new string\n");*/
     bstr = Get(str);
     ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen);
     ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
@@ -5178,7 +5242,8 @@
 
     changed = SysReAllocStringLen(&str, szSmaller, 1);
     ok (changed == 1, "Expected 1, got %d\n", changed);
-    ok (str == oldstr, "Created new string\n");
+    /* Vista creates a new string, but older versions reuse the existing string. */
+    /*ok (str == oldstr, "Created new string\n");*/
     bstr = Get(str);
     ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen);
     ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
@@ -5717,7 +5782,7 @@
    * its memory, while Wine uses HeapAlloc(). Doing this ensures we allocate
    * using the correct function whether with native or builtin.
    */
-  ci.prgCustData = (LPCUSTDATAITEM)SysAllocStringByteLen((LPCSTR)buff, sizeof(buff));
+  ci.prgCustData = (LPCUSTDATAITEM)Get(SysAllocStringByteLen((LPCSTR)buff, sizeof(buff)));
   for (i = 0; i < NUM_CUST_ITEMS; i++)
     VariantInit(&ci.prgCustData[i].varValue);
   pClearCustData(&ci);
@@ -5729,8 +5794,8 @@
   VARIANT v1, v2;
   HRESULT hRes;
 
-  VariantClear(&v1);
-  VariantClear(&v2);
+  VariantInit(&v1);
+  VariantInit(&v2);
   V_VT(&v1) = VT_BYREF|VT_VARIANT;
   V_BYREF(&v1) = 0;
 
@@ -5763,8 +5828,8 @@
      HRESULT hres;
 
      bstr = SysAllocString(testW);
-     VariantClear(&v1);
-     VariantClear(&v2);
+     VariantInit(&v1);
+     VariantInit(&v2);
      V_VT(&v1) = VT_BSTR;
      V_BSTR(&v1) = bstr;
      hres = VariantChangeTypeEx(&v1, &v1, 0, 0, VT_INT);
@@ -6042,6 +6107,7 @@
 
   test_VarBstrFromR4();
   test_VarBstrFromDate();
+  test_VarBstrFromCy();
   test_VarBstrFromDec();
   test_VarBstrCmp();
   test_SysStringLen();



More information about the Ros-diffs mailing list