* Sync with Wine 1.5.19.
svn path=/trunk/; revision=57892
-add_definitions(
- -D__ROS_LONG64__
- -D_DLL -D__USE_CRTIMP)
-
+add_definitions(-D__ROS_LONG64__)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
-
add_typelib(test_reg.idl test_tlb.idl tmarshal.idl)
-
add_idl_Headers(oleaut32_idlheaders test_reg.idl tmarshal.idl)
-generate_idl_iids(tmarshal.idl)
+generate_idl_iids(tmarshal.idl test_reg.idl)
list(APPEND SOURCE
dispatch.c
safearray.c
testlist.c
tmarshal.c
- tmarshal.rc
typelib.c
usrmarshal.c
varformat.c
vartest.c
vartype.c
+ ${CMAKE_CURRENT_BINARY_DIR}/test_reg_i.c
${CMAKE_CURRENT_BINARY_DIR}/tmarshal_i.c)
-add_executable(oleaut32_winetest ${SOURCE})
+add_executable(oleaut32_winetest ${SOURCE} tmarshal.rc)
target_link_libraries(oleaut32_winetest uuid wine)
set_module_type(oleaut32_winetest win32cui)
add_importlibs(oleaut32_winetest oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 msvcrt kernel32 ntdll)
static HRESULT (WINAPI *pOleCreateFontIndirect)(LPFONTDESC,REFIID,LPVOID*);
-#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
+#define EXPECT_HR(hr,hr_exp) \
+ ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
/* Create a font with cySize given by lo_size, hi_size, */
/* SetRatio to ratio_logical, ratio_himetric, */
/* check that resulting hfont has height hfont_height. */
/* Various checks along the way. */
-
-static void test_ifont_sizes(LONG lo_size, LONG hi_size,
+static void test_ifont_size(LONG lo_size, LONG hi_size,
LONG ratio_logical, LONG ratio_himetric,
LONG hfont_height, const char * test_name)
{
LOGFONT lf;
CY psize;
HRESULT hres;
+ DWORD rtnval;
fd.cbSizeofstruct = sizeof(FONTDESC);
- fd.lpstrName = system_font;
+ fd.lpstrName = arial_font; /* using scalable instead of bitmap font reduces errors due to font realization */
S(fd.cySize).Lo = lo_size;
S(fd.cySize).Hi = hi_size;
fd.sWeight = 0;
test_name, hres);
ok(pvObj != NULL,"%s: OCFI returns NULL.\n", test_name);
- /* Read back size. Hi part was ignored. */
+ /* If scaling ration specified, change ratio. */
+ if(ratio_logical && ratio_himetric)
+ {
+ hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric);
+ ok(hres == S_OK,"%s: IFont_SetRatio returns 0x%08x instead of S_OK.\n",
+ test_name, hres);
+ }
+
+ /* Read back size. */
hres = IFont_get_Size(ifnt, &psize);
ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
test_name, hres);
- ok(S(psize).Lo == lo_size && S(psize).Hi == 0,
- "%s: get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=0.\n",
- test_name, S(psize).Lo, S(psize).Hi, lo_size);
- /* Change ratio, check size unchanged. Standard is 72, 2540. */
- hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric);
- ok(hres == S_OK,"%s: IFont_SR returns 0x%08x instead of S_OK.\n",
- test_name, hres);
- hres = IFont_get_Size(ifnt, &psize);
- ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
- test_name, hres);
- ok(S(psize).Lo == lo_size && S(psize).Hi == 0,
- "%s: gS after SR: Lo=%d, Hi=%d; expected Lo=%d, Hi=0.\n",
- test_name, S(psize).Lo, S(psize).Hi, lo_size);
+ /* Check returned size - allow for errors due to rounding & font realization. */
+ ok((abs(S(psize).Lo - lo_size) < 10000) && S(psize).Hi == hi_size,
+ "%s: IFont_get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=%d.\n",
+ test_name, S(psize).Lo, S(psize).Hi, lo_size, hi_size);
- /* Check hFont size with this ratio. This tests an important */
- /* conversion for which MSDN is very wrong. */
+ /* Check hFont size. */
hres = IFont_get_hFont (ifnt, &hfont);
ok(hres == S_OK, "%s: IFont_get_hFont returns 0x%08x instead of S_OK.\n",
test_name, hres);
- hres = GetObject (hfont, sizeof(LOGFONT), &lf);
- ok(lf.lfHeight == hfont_height,
+ rtnval = GetObject (hfont, sizeof(LOGFONT), &lf);
+ ok(rtnval > 0, "GetObject(hfont) failed\n");
+
+ /* Since font scaling may encounter rounding errors, allow 1 pixel deviation. */
+ ok(abs(lf.lfHeight - hfont_height) <= 1,
"%s: hFont has lf.lfHeight=%d, expected %d.\n",
test_name, lf.lfHeight, hfont_height);
IFont_Release(ifnt);
}
+static void test_ifont_sizes(void)
+{
+ /* Test various size operations and conversions. */
+ /* Add more as needed. */
+
+ /* Results of first 2 tests depend on display resolution. */
+ HDC hdc = GetDC(0);
+ LONG dpi = GetDeviceCaps(hdc, LOGPIXELSY); /* expected results depend on display DPI */
+ ReleaseDC(0, hdc);
+ if(dpi == 96) /* normal resolution display */
+ {
+ test_ifont_size(180000, 0, 0, 0, -24, "default"); /* normal font */
+ test_ifont_size(186000, 0, 0, 0, -25, "rounding"); /* test rounding */
+ } else if(dpi == 72) /* low resolution display */
+ {
+ test_ifont_size(180000, 0, 0, 0, -18, "default"); /* normal font */
+ test_ifont_size(186000, 0, 0, 0, -19, "rounding"); /* test rounding */
+ } else if(dpi == 120) /* high resolution display */
+ {
+ test_ifont_size(180000, 0, 0, 0, -30, "default"); /* normal font */
+ test_ifont_size(186000, 0, 0, 0, -31, "rounding"); /* test rounding */
+ } else
+ skip("Skipping resolution dependent font size tests - display resolution is %d\n", dpi);
+
+ /* Next 4 tests specify a scaling ratio, so display resolution is not a factor. */
+ test_ifont_size(180000, 0, 72, 2540, -18, "ratio1"); /* change ratio */
+ test_ifont_size(180000, 0, 144, 2540, -36, "ratio2"); /* another ratio */
+ test_ifont_size(180000, 0, 72, 1270, -36, "ratio3"); /* yet another ratio */
+ test_ifont_size(186000, 0, 72, 2540, -19, "rounding+ratio"); /* test rounding with ratio */
+}
+
static void test_QueryInterface(void)
{
- LPVOID pvObj = NULL;
- HRESULT hres;
- IFont* font = NULL;
- LONG ret;
+ LPVOID pvObj = NULL;
+ HRESULT hr;
+ IFont* font = NULL;
+ LONG ref;
+
+ hr = pOleCreateFontIndirect(NULL, &IID_IFont, NULL);
+ EXPECT_HR(hr, E_POINTER);
- hres = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
- font = pvObj;
+ hr = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
+ font = pvObj;
- ok(hres == S_OK,"OCFI (NULL,..) does not return 0, but 0x%08x\n",hres);
- ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n");
+ EXPECT_HR(hr, S_OK);
+ ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n");
- pvObj = NULL;
- hres = IFont_QueryInterface( font, &IID_IFont, &pvObj);
+ pvObj = NULL;
+ hr = IFont_QueryInterface( font, &IID_IFont, &pvObj);
+ EXPECT_HR(hr, S_OK);
- /* Test if QueryInterface increments ref counter for IFONTs */
- ret = IFont_AddRef(font);
- ok(ret == 3 ||
- broken(ret == 1), /* win95 */
- "IFont_QI expected ref value 3 but instead got %d\n",ret);
- IFont_Release(font);
+ /* Test if QueryInterface increments ref counter for IFONTs */
+ ref = IFont_AddRef(font);
+ ok(ref == 3 ||
+ broken(ref == 1), /* win95 */
+ "IFont_QI expected ref value 3 but instead got %d\n", ref);
+ 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");
+ ok(pvObj != NULL,"IFont_QI does return NULL, instead of a ptr\n");
- /* Original ref and QueryInterface ref both have to be released */
- IFont_Release(font);
- IFont_Release(font);
+ IFont_Release(font);
+ IFont_Release(font);
}
static void test_type_info(void)
{
if (IsEqualIID(riid, &IID_IFontEventsDisp) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
{
- IUnknown_AddRef(iface);
+ IFontEventsDisp_AddRef(iface);
*ppvObject = iface;
return S_OK;
}
fontdesc.fStrikethrough = FALSE;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
hr = IFont_QueryInterface(pFont, &IID_IConnectionPointContainer, (void **)&pCPC);
- ok_ole_success(hr, "IFont_QueryInterface");
+ EXPECT_HR(hr, S_OK);
hr = IConnectionPointContainer_FindConnectionPoint(pCPC, &IID_IFontEventsDisp, &pCP);
- ok_ole_success(hr, "IConnectionPointContainer_FindConnectionPoint");
+ EXPECT_HR(hr, S_OK);
IConnectionPointContainer_Release(pCPC);
hr = IConnectionPoint_Advise(pCP, (IUnknown *)&FontEventsDisp, &dwCookie);
- ok_ole_success(hr, "IConnectionPoint_Advise");
+ EXPECT_HR(hr, S_OK);
IConnectionPoint_Release(pCP);
hr = IFont_put_Bold(pFont, TRUE);
- ok_ole_success(hr, "IFont_put_Bold");
+ EXPECT_HR(hr, S_OK);
ok(fonteventsdisp_invoke_called == 1, "IFontEventDisp::Invoke wasn't called once\n");
hr = IFont_QueryInterface(pFont, &IID_IFontDisp, (void **)&pFontDisp);
- ok_ole_success(hr, "IFont_QueryInterface");
+ EXPECT_HR(hr, S_OK);
V_VT(&vararg) = VT_BOOL;
V_BOOL(&vararg) = VARIANT_FALSE;
dispparams.cArgs = 1;
dispparams.rgvarg = &vararg;
hr = IFontDisp_Invoke(pFontDisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
+ EXPECT_HR(hr, S_OK);
IFontDisp_Release(pFontDisp);
fonteventsdisp_invoke_called);
hr = IFont_Clone(pFont, &pFont2);
- ok_ole_success(hr, "IFont_Clone");
+ EXPECT_HR(hr, S_OK);
IFont_Release(pFont);
hr = IFont_put_Bold(pFont2, FALSE);
- ok_ole_success(hr, "IFont_put_Bold");
+ EXPECT_HR(hr, S_OK);
/* this test shows that the notification routine isn't called again */
ok(fonteventsdisp_invoke_called == 2, "IFontEventDisp::Invoke was called %d times instead of twice\n",
VARIANT varresult;
hr = pOleCreateFontIndirect(NULL, &IID_IFontDisp, (void **)&fontdisp);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
V_VT(&vararg) = VT_BOOL;
V_BOOL(&vararg) = VARIANT_FALSE;
dispparams.cArgs = 1;
dispparams.rgvarg = &vararg;
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_IFontDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
- ok(hr == DISP_E_UNKNOWNINTERFACE, "IFontDisp_Invoke should have returned DISP_E_UNKNOWNINTERFACE instead of 0x%08x\n", hr);
+ EXPECT_HR(hr, DISP_E_UNKNOWNINTERFACE);
dispparams.cArgs = 0;
dispparams.rgvarg = NULL;
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
- ok(hr == DISP_E_BADPARAMCOUNT, "IFontDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
+ EXPECT_HR(hr, DISP_E_BADPARAMCOUNT);
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
- ok(hr == DISP_E_PARAMNOTOPTIONAL, "IFontDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
+ EXPECT_HR(hr, DISP_E_PARAMNOTOPTIONAL);
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
- ok(hr == DISP_E_PARAMNOTOPTIONAL, "IFontDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
+ EXPECT_HR(hr, DISP_E_PARAMNOTOPTIONAL);
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
- ok_ole_success(hr, "IFontDisp_Invoke");
+ EXPECT_HR(hr, S_OK);
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_METHOD, NULL, &varresult, NULL, NULL);
- ok(hr == DISP_E_MEMBERNOTFOUND, "IFontDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
+ EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND);
hr = IFontDisp_Invoke(fontdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
- ok(hr == DISP_E_MEMBERNOTFOUND, "IFontDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
+ EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND);
dispparams.cArgs = 1;
dispparams.rgvarg = &vararg;
hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
- ok_ole_success(hr, "IFontDisp_Invoke");
+ EXPECT_HR(hr, S_OK);
IFontDisp_Release(fontdisp);
}
fontdesc.fStrikethrough = FALSE;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
hr = IFont_put_Name(pFont, NULL);
- ok(hr == CTL_E_INVALIDPROPERTYVALUE,
- "IFont::put_Name: Expected CTL_E_INVALIDPROPERTYVALUE got 0x%08x\n",
- hr);
+ EXPECT_HR(hr, CTL_E_INVALIDPROPERTYVALUE);
hr = IFont_get_Name(pFont, NULL);
- ok(hr == E_POINTER,
- "IFont::get_Name: Expected E_POINTER got 0x%08x\n",
- hr);
+ EXPECT_HR(hr, E_POINTER);
hr = IFont_get_Size(pFont, NULL);
- ok(hr == E_POINTER,
- "IFont::get_Size: Expected E_POINTER got 0x%08x\n",
- hr);
+ EXPECT_HR(hr, E_POINTER);
hr = IFont_get_Bold(pFont, NULL);
- ok(hr == E_POINTER,
- "IFont::get_Bold: Expected E_POINTER got 0x%08x\n",
- hr);
+ EXPECT_HR(hr, E_POINTER);
IFont_Release(pFont);
}
fontdesc.fStrikethrough = FALSE;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
hr = IFont_get_hFont(font, &hfont);
- ok_ole_success(hr, "get_hFont");
+ EXPECT_HR(hr, S_OK);
/* show that if the font is updated the old hfont is deleted when the
new font is realized */
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_put_Size(font, size);
- ok_ole_success(hr, "put_Size");
+ EXPECT_HR(hr, S_OK);
/* put_Size doesn't cause the new font to be realized */
obj_type = GetObjectType(last_hfont);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_get_hFont(font, &hfont);
- ok_ole_success(hr, "get_hFont");
+ EXPECT_HR(hr, S_OK);
obj_type = GetObjectType(last_hfont);
ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
until the font object is released */
for(i = 0; i < 100; i++)
{
-
size.int64 = (i + 10) * 20000;
obj_type = GetObjectType(hfont);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_put_Size(font, size);
- ok_ole_success(hr, "put_Size");
+ EXPECT_HR(hr, S_OK);
hr = IFont_get_hFont(font, &hfont);
- ok_ole_success(hr, "get_hFont");
+ EXPECT_HR(hr, S_OK);
hr = IFont_AddRefHfont(font, hfont);
- ok_ole_success(hr, "AddRefHfont");
+ EXPECT_HR(hr, S_OK);
if(i == 0) first_hfont = hfont;
obj_type = GetObjectType(first_hfont);
through re-realization */
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
hr = IFont_get_hFont(font, &hfont);
- ok_ole_success(hr, "get_hFont");
+ EXPECT_HR(hr, S_OK);
for(i = 0; i < 100; i++)
{
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_put_Size(font, size);
- ok_ole_success(hr, "put_Size");
+ EXPECT_HR(hr, S_OK);
/* put_Size doesn't cause the new font to be realized */
obj_type = GetObjectType(last_hfont);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_get_hFont(font, &hfont);
- ok_ole_success(hr, "get_hFont");
+ EXPECT_HR(hr, S_OK);
hr = IFont_AddRefHfont(font, hfont);
- ok_ole_success(hr, "AddRefHfont");
+ EXPECT_HR(hr, S_OK);
hr = IFont_ReleaseHfont(font, hfont);
- ok_ole_success(hr, "ReleaseHfont");
+ EXPECT_HR(hr, S_OK);
obj_type = GetObjectType(last_hfont);
ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
hr = IFont_put_Size(font, size);
- ok_ole_success(hr, "put_Size");
+ EXPECT_HR(hr, S_OK);
hr = IFont_get_hFont(font, &hfont);
- ok_ole_success(hr, "get_hFont");
+ EXPECT_HR(hr, S_OK);
hr = IFont_ReleaseHfont(font, hfont);
- ok_ole_success(hr, "ReleaseHfont");
+ EXPECT_HR(hr, S_OK);
if(i == 0) first_hfont = hfont;
obj_type = GetObjectType(first_hfont);
that includes internal and external references */
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font2);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
hr = IFont_get_hFont(font, &hfont);
- ok_ole_success(hr, "get_hFont");
+ EXPECT_HR(hr, S_OK);
hr = IFont_get_hFont(font2, &first_hfont);
- ok_ole_success(hr, "get_hFont");
+ EXPECT_HR(hr, S_OK);
todo_wine
ok(hfont == first_hfont, "fonts differ\n");
hr = IFont_ReleaseHfont(font, hfont);
- ok(hr == S_OK, "got %08x\n", hr);
+ EXPECT_HR(hr, S_OK);
hr = IFont_ReleaseHfont(font, hfont);
todo_wine
- ok(hr == S_OK, "got %08x\n", hr);
+ EXPECT_HR(hr, S_OK);
hr = IFont_ReleaseHfont(font, hfont);
- ok(hr == S_FALSE, "got %08x\n", hr);
+ EXPECT_HR(hr, S_FALSE);
obj_type = GetObjectType(hfont);
ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
fontdesc.fStrikethrough = FALSE;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
hr = IFont_get_Charset(font, &cs);
- ok_ole_success(hr, "get_Charset");
+ EXPECT_HR(hr, S_OK);
ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
IFont_Release(font);
fontdesc.lpstrName = arial_font;
hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
- ok_ole_success(hr, "OleCreateFontIndirect");
+ EXPECT_HR(hr, S_OK);
hr = IFont_get_Charset(font, &cs);
- ok_ole_success(hr, "get_Charset");
+ EXPECT_HR(hr, S_OK);
ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
name = SysAllocString(marlett_font);
hr = IFont_put_Name(font, name);
- ok_ole_success(hr, "put_Name");
+ EXPECT_HR(hr, S_OK);
SysFreeString(name);
hr = IFont_get_Name(font, &name);
- ok_ole_success(hr, "get_Name");
+ EXPECT_HR(hr, S_OK);
ok(!lstrcmpiW(name, marlett_font), "got name %s\n", wine_dbgstr_w(name));
SysFreeString(name);
hr = IFont_get_Charset(font, &cs);
- ok_ole_success(hr, "get_Charset");
+ EXPECT_HR(hr, S_OK);
ok(cs == SYMBOL_CHARSET, "got charset %d\n", cs);
IFont_Release(font);
}
+static void test_OleCreateFontIndirect(void)
+{
+ FONTDESC fontdesc;
+ IFont *font;
+ HRESULT hr;
+
+ fontdesc.cbSizeofstruct = sizeof(fontdesc);
+ fontdesc.lpstrName = arial_font;
+ fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
+ fontdesc.sWeight = FW_NORMAL;
+ fontdesc.sCharset = ANSI_CHARSET;
+ fontdesc.fItalic = FALSE;
+ fontdesc.fUnderline = FALSE;
+ fontdesc.fStrikethrough = FALSE;
+
+ hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
+ EXPECT_HR(hr, S_OK);
+ IFont_Release(font);
+
+ /* play with cbSizeofstruct value */
+ fontdesc.cbSizeofstruct = sizeof(fontdesc)-1;
+ hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
+ EXPECT_HR(hr, S_OK);
+ IFont_Release(font);
+
+ fontdesc.cbSizeofstruct = sizeof(fontdesc)+1;
+ hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
+ EXPECT_HR(hr, S_OK);
+ IFont_Release(font);
+
+ fontdesc.cbSizeofstruct = 0;
+ hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font);
+ EXPECT_HR(hr, S_OK);
+ IFont_Release(font);
+}
+
START_TEST(olefont)
{
- hOleaut32 = GetModuleHandleA("oleaut32.dll");
- pOleCreateFontIndirect = (void*)GetProcAddress(hOleaut32, "OleCreateFontIndirect");
- if (!pOleCreateFontIndirect)
- {
- win_skip("OleCreateFontIndirect not available\n");
- return;
- }
-
- test_QueryInterface();
- test_type_info();
-
- /* Test various size operations and conversions. */
- /* Add more as needed. */
- 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();
- test_Invoke();
- test_IsEqual();
- test_ReleaseHfont();
- test_AddRefHfont();
- test_returns();
- test_hfont_lifetime();
- test_realization();
+ hOleaut32 = GetModuleHandleA("oleaut32.dll");
+ pOleCreateFontIndirect = (void*)GetProcAddress(hOleaut32, "OleCreateFontIndirect");
+ if (!pOleCreateFontIndirect)
+ {
+ win_skip("OleCreateFontIndirect not available\n");
+ return;
+ }
+
+ test_QueryInterface();
+ test_type_info();
+ test_ifont_sizes();
+ test_font_events_disp();
+ test_GetIDsOfNames();
+ test_Invoke();
+ test_IsEqual();
+ test_ReleaseHfont();
+ test_AddRefHfont();
+ test_returns();
+ test_hfont_lifetime();
+ test_realization();
+ test_OleCreateFontIndirect();
}
* OLEPICTURE test program
*
* Copyright 2005 Marcus Meissner
- *
+ * Copyright 2012 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <float.h>
#define COBJMACROS
+#define CONST_VTABLE
#define NONAMELESSUNION
#include "wine/test.h"
static HMODULE hOleaut32;
static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*);
-static HRESULT (WINAPI *pOleCreatePictureIndirect)(PICTDESC*,REFIID,BOOL,LPVOID*);
+static HRESULT (WINAPI *pOleLoadPictureEx)(LPSTREAM,LONG,BOOL,REFIID,DWORD,DWORD,DWORD,LPVOID*);
#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
};
-struct NoStatStreamImpl
+typedef struct NoStatStreamImpl
{
- const IStreamVtbl *lpVtbl;
+ IStream IStream_iface;
LONG ref;
HGLOBAL supportHandle;
ULARGE_INTEGER streamSize;
ULARGE_INTEGER currentPosition;
-};
-typedef struct NoStatStreamImpl NoStatStreamImpl;
-static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal);
+} NoStatStreamImpl;
+
+static IStream* NoStatStream_Construct(HGLOBAL hGlobal);
static void
test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
if (handle)
{
BITMAP bmp;
- GetObject((HGDIOBJ)handle, sizeof(BITMAP), &bmp);
+ GetObject(UlongToHandle(handle), sizeof(BITMAP), &bmp);
todo_wine ok(bmp.bmBits != 0, "not a dib\n");
}
IStream_Release(stream);
/* again with Non Statable and Non Seekable stream */
- stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
+ stream = NoStatStream_Construct(hglob);
hglob = 0; /* Non-statable impl always deletes on release */
test_pic_with_stream(stream, 0);
IStream_Release(stream);
/* again with Non Statable and Non Seekable stream */
- stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
+ stream = NoStatStream_Construct(hglob);
hglob = 0; /* Non-statable impl always deletes on release */
test_pic_with_stream(stream, 0);
static void test_OleCreatePictureIndirect(void)
{
+ OLE_HANDLE handle;
IPicture *pict;
HRESULT hr;
short type;
- OLE_HANDLE handle;
- if(!pOleCreatePictureIndirect)
- {
- win_skip("Skipping OleCreatePictureIndirect tests\n");
- return;
- }
+if (0)
+{
+ /* crashes on native */
+ OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, NULL);
+}
- hr = pOleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict);
+ hr = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict);
ok(hr == S_OK, "hr %08x\n", hr);
+ type = PICTYPE_NONE;
hr = IPicture_get_Type(pict, &type);
ok(hr == S_OK, "hr %08x\n", hr);
ok(type == PICTYPE_UNINITIALIZED, "type %d\n", type);
+ handle = 0xdeadbeef;
hr = IPicture_get_Handle(pict, &handle);
ok(hr == S_OK, "hr %08x\n", hr);
ok(handle == 0, "handle %08x\n", handle);
short type;
if(!winetest_interactive) {
- skip("Bug 5000: oleaut_winetest:olepicture crashes with Page Fault.\n");
+ skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n");
return;
}
memcpy(data, apmdata, sizeof(apmdata));
ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
- ole_check(OleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict));
+ ole_check(pOleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict));
ole_check(IPicture_get_Handle(pict, &handle));
ok(handle != 0, "handle is null\n");
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);
+ ole_expect(pOleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
IStream_Release(stream);
}
short type;
if(!winetest_interactive) {
- skip("Bug 5000: oleaut_winetest:olepicture crashes with Page Fault.\n");
+ skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n");
return;
}
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(pOleLoadPictureEx(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");
IPicture_get_Width(pic, &pWidth);
IPicture_get_Height(pic, &pHeight);
- SetPixelV(hdc, 0, 0, 0x00F0F0F0);
- SetPixelV(hdc, 5, 5, 0x00F0F0F0);
- SetPixelV(hdc, 10, 10, 0x00F0F0F0);
+ SetPixelV(hdc, 0, 0, 0x00223344);
+ SetPixelV(hdc, 5, 5, 0x00223344);
+ SetPixelV(hdc, 10, 10, 0x00223344);
expected = GetPixel(hdc, 0, 0);
hres = IPicture_Render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL);
hres = OleLoadPicturePath(emptyW, NULL, 0, 0, NULL, (void **)&pic);
todo_wine
ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
- hres == E_UNEXPECTED || /* NT4/Win95 */
- hres == E_FAIL || /* Win95 OSR2 */
- hres == E_OUTOFMEMORY, /* Win98/Win2k/Win2k3 */
+ broken(hres == E_UNEXPECTED) || /* NT4 */
+ broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */
"Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
ok(pic == NULL,
"Expected the output interface pointer to be NULL, got %p\n", pic);
hres = OleLoadPicturePath(emptyW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
todo_wine
ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
- hres == E_UNEXPECTED || /* NT4/Win95 */
- hres == E_FAIL || /* Win95 OSR2 */
- hres == E_OUTOFMEMORY, /* Win98/Win2k/Win2k3 */
+ broken(hres == E_UNEXPECTED) || /* NT4 */
+ broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */
"Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
ok(pic == NULL,
"Expected the output interface pointer to be NULL, got %p\n", pic);
/* Try a normal DOS path. */
hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == S_OK ||
- broken(hres == E_UNEXPECTED), /* NT4/Win95 */
+ broken(hres == E_UNEXPECTED), /* NT4 */
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
if (pic)
IPicture_Release(pic);
/* Try a DOS path with tacked on "file:". */
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == S_OK ||
- broken(hres == E_UNEXPECTED), /* NT4/Win95 */
+ broken(hres == E_UNEXPECTED), /* NT4 */
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
if (pic)
IPicture_Release(pic);
/* Try with a nonexistent file. */
hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
- hres == E_UNEXPECTED || /* NT4/Win95 */
- hres == E_FAIL, /* Win9x/Win2k */
+ broken(hres == E_UNEXPECTED) || /* NT4 */
+ broken(hres == E_FAIL), /*Win2k */
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
- hres == E_UNEXPECTED || /* NT4/Win95 */
- hres == E_FAIL, /* Win9x/Win2k */
+ broken(hres == E_UNEXPECTED) || /* NT4 */
+ broken(hres == E_FAIL), /* Win2k */
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == S_OK ||
- broken(hres == E_UNEXPECTED), /* NT4/Win95 */
+ broken(hres == E_UNEXPECTED), /* NT4 */
"Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
if (pic)
IPicture_Release(pic);
/* Try with a nonexistent file. */
hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
- hres == E_UNEXPECTED || /* NT4/Win95 */
- hres == E_FAIL, /* Win9x/Win2k */
+ broken(hres == E_UNEXPECTED) || /* NT4 */
+ broken(hres == E_FAIL), /* Win2k */
"Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
}
+static void test_himetric(void)
+{
+ static const BYTE bmp_bits[1024];
+ OLE_XSIZE_HIMETRIC cx;
+ OLE_YSIZE_HIMETRIC cy;
+ IPicture *pic;
+ PICTDESC desc;
+ HBITMAP bmp;
+ HRESULT hr;
+ HICON icon;
+ HDC hdc;
+ INT d;
+
+ desc.cbSizeofstruct = sizeof(desc);
+ desc.picType = PICTYPE_BITMAP;
+ desc.u.bmp.hpal = NULL;
+
+ hdc = CreateCompatibleDC(0);
+
+ bmp = CreateBitmap(1.9 * GetDeviceCaps(hdc, LOGPIXELSX),
+ 1.9 * GetDeviceCaps(hdc, LOGPIXELSY), 1, 1, NULL);
+
+ desc.u.bmp.hbitmap = bmp;
+
+ /* size in himetric units reported rounded up to next integer value */
+ hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ cx = 0;
+ d = MulDiv((INT)(1.9 * GetDeviceCaps(hdc, LOGPIXELSX)), 2540, GetDeviceCaps(hdc, LOGPIXELSX));
+ hr = IPicture_get_Width(pic, &cx);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(cx == d, "got %d, expected %d\n", cx, d);
+
+ cy = 0;
+ d = MulDiv((INT)(1.9 * GetDeviceCaps(hdc, LOGPIXELSY)), 2540, GetDeviceCaps(hdc, LOGPIXELSY));
+ hr = IPicture_get_Height(pic, &cy);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(cy == d, "got %d, expected %d\n", cy, d);
+
+ DeleteObject(bmp);
+ IPicture_Release(pic);
+
+ /* same thing with icon */
+ icon = CreateIcon(NULL, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
+ 1, 1, bmp_bits, bmp_bits);
+ ok(icon != NULL, "failed to create icon\n");
+
+ desc.picType = PICTYPE_ICON;
+ desc.u.icon.hicon = icon;
+
+ hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ cx = 0;
+ d = MulDiv(GetSystemMetrics(SM_CXICON), 2540, GetDeviceCaps(hdc, LOGPIXELSX));
+ hr = IPicture_get_Width(pic, &cx);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(cx == d, "got %d, expected %d\n", cx, d);
+
+ cy = 0;
+ d = MulDiv(GetSystemMetrics(SM_CYICON), 2540, GetDeviceCaps(hdc, LOGPIXELSY));
+ hr = IPicture_get_Height(pic, &cy);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(cy == d, "got %d, expected %d\n", cy, d);
+
+ IPicture_Release(pic);
+ DestroyIcon(icon);
+
+ DeleteDC(hdc);
+}
+
+static void test_load_save_bmp(void)
+{
+ IPicture *pic;
+ PICTDESC desc;
+ short type;
+ OLE_HANDLE handle;
+ HGLOBAL hmem;
+ DWORD *mem;
+ IPersistStream *src_stream;
+ IStream *dst_stream;
+ HRESULT hr;
+
+ desc.cbSizeofstruct = sizeof(desc);
+ desc.picType = PICTYPE_BITMAP;
+ desc.u.bmp.hpal = 0;
+ desc.u.bmp.hbitmap = CreateBitmap(1, 1, 1, 1, NULL);
+ hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
+ ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
+
+ type = -1;
+ hr = IPicture_get_Type(pic, &type);
+ ok(hr == S_OK,"get_Type error %#8x\n", hr);
+ ok(type == PICTYPE_BITMAP,"expected picture type PICTYPE_BITMAP, got %d\n", type);
+
+ hr = IPicture_get_Handle(pic, &handle);
+ ok(hr == S_OK,"get_Handle error %#8x\n", hr);
+ ok(IntToPtr(handle) == desc.u.bmp.hbitmap, "get_Handle returned wrong handle %#x\n", handle);
+
+ hmem = GlobalAlloc(GMEM_ZEROINIT, 4096);
+ hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
+ ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
+
+ hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
+ ok(hr == S_OK, "QueryInterface error %#x\n", hr);
+
+ hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
+ ok(hr == S_OK, "Save error %#x\n", hr);
+
+ IPersistStream_Release(src_stream);
+ IStream_Release(dst_stream);
+
+ mem = GlobalLock(hmem);
+ ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
+ ok(mem[1] == 66, "expected stream size 66, got %u\n", mem[1]);
+ ok(!memcmp(&mem[2], "BM", 2), "got wrong bmp header %04x\n", mem[2]);
+
+ GlobalUnlock(hmem);
+ GlobalFree(hmem);
+
+ DeleteObject(desc.u.bmp.hbitmap);
+ IPicture_Release(pic);
+}
+
+static void test_load_save_icon(void)
+{
+ IPicture *pic;
+ PICTDESC desc;
+ short type;
+ OLE_HANDLE handle;
+ HGLOBAL hmem;
+ DWORD *mem;
+ IPersistStream *src_stream;
+ IStream *dst_stream;
+ HRESULT hr;
+
+ desc.cbSizeofstruct = sizeof(desc);
+ desc.picType = PICTYPE_ICON;
+ desc.u.icon.hicon = LoadIcon(0, IDI_APPLICATION);
+ hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
+ ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
+
+ type = -1;
+ hr = IPicture_get_Type(pic, &type);
+ ok(hr == S_OK,"get_Type error %#8x\n", hr);
+ ok(type == PICTYPE_ICON,"expected picture type PICTYPE_ICON, got %d\n", type);
+
+ hr = IPicture_get_Handle(pic, &handle);
+ ok(hr == S_OK,"get_Handle error %#8x\n", hr);
+ ok(IntToPtr(handle) == desc.u.icon.hicon, "get_Handle returned wrong handle %#x\n", handle);
+
+ hmem = GlobalAlloc(GMEM_ZEROINIT, 8192);
+ hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
+ ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
+
+ hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
+ ok(hr == S_OK, "QueryInterface error %#x\n", hr);
+
+ hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
+ ok(hr == S_OK, "Saveerror %#x\n", hr);
+
+ IPersistStream_Release(src_stream);
+ IStream_Release(dst_stream);
+
+ mem = GlobalLock(hmem);
+ ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
+todo_wine
+ ok(mem[1] == 766, "expected stream size 766, got %u\n", mem[1]);
+ ok(mem[2] == 0x00010000, "got wrong icon header %04x\n", mem[2]);
+
+ GlobalUnlock(hmem);
+ GlobalFree(hmem);
+
+ DestroyIcon(desc.u.icon.hicon);
+ IPicture_Release(pic);
+}
+
+static void test_load_save_empty_picture(void)
+{
+ IPicture *pic;
+ PICTDESC desc;
+ short type;
+ OLE_HANDLE handle;
+ HGLOBAL hmem;
+ DWORD *mem;
+ IPersistStream *src_stream;
+ IStream *dst_stream;
+ HRESULT hr;
+
+ memset(&pic, 0, sizeof(pic));
+ desc.cbSizeofstruct = sizeof(desc);
+ desc.picType = PICTYPE_NONE;
+ hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void **)&pic);
+ ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
+
+ type = -1;
+ hr = IPicture_get_Type(pic, &type);
+ ok(hr == S_OK,"get_Type error %#8x\n", hr);
+ ok(type == PICTYPE_NONE,"expected picture type PICTYPE_NONE, got %d\n", type);
+
+ handle = (OLE_HANDLE)0xdeadbeef;
+ hr = IPicture_get_Handle(pic, &handle);
+ ok(hr == S_OK,"get_Handle error %#8x\n", hr);
+ ok(!handle, "get_Handle returned wrong handle %#x\n", handle);
+
+ hmem = GlobalAlloc(GMEM_ZEROINIT, 4096);
+ hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
+ ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
+
+ hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
+ ok(hr == S_OK, "QueryInterface error %#x\n", hr);
+
+ hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
+ ok(hr == S_OK, "Save error %#x\n", hr);
+
+ mem = GlobalLock(hmem);
+ ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
+ ok(mem[1] == 0, "expected stream size 0, got %u\n", mem[1]);
+ GlobalUnlock(hmem);
+
+ IPersistStream_Release(src_stream);
+ IStream_Release(dst_stream);
+
+ GlobalFree(hmem);
+ IPicture_Release(pic);
+}
+
START_TEST(olepicture)
{
- hOleaut32 = GetModuleHandleA("oleaut32.dll");
- pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
- pOleCreatePictureIndirect = (void*)GetProcAddress(hOleaut32, "OleCreatePictureIndirect");
- if (!pOleLoadPicture)
- {
- win_skip("OleLoadPicture is not available\n");
- return;
- }
+ hOleaut32 = GetModuleHandleA("oleaut32.dll");
+ pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
+ pOleLoadPictureEx = (void*)GetProcAddress(hOleaut32, "OleLoadPictureEx");
+ if (!pOleLoadPicture)
+ {
+ win_skip("OleLoadPicture is not available\n");
+ return;
+ }
- /* Test regular 1x1 pixel images of gif, jpg, bmp type */
- test_pic(gifimage, sizeof(gifimage));
- test_pic(jpgimage, sizeof(jpgimage));
- test_pic(bmpimage, sizeof(bmpimage));
- test_pic(gif4pixel, sizeof(gif4pixel));
- /* FIXME: No PNG support in Windows... */
- if (0) test_pic(pngimage, sizeof(pngimage));
- test_empty_image();
- test_empty_image_2();
+ /* Test regular 1x1 pixel images of gif, jpg, bmp type */
+ test_pic(gifimage, sizeof(gifimage));
+ test_pic(jpgimage, sizeof(jpgimage));
+ test_pic(bmpimage, sizeof(bmpimage));
+ test_pic(gif4pixel, sizeof(gif4pixel));
+ /* FIXME: No PNG support in Windows... */
+ if (0) test_pic(pngimage, sizeof(pngimage));
+ test_empty_image();
+ test_empty_image_2();
+ if (pOleLoadPictureEx)
+ {
test_apm();
test_metafile();
test_enhmetafile();
-
+ }
+ else
+ win_skip("OleLoadPictureEx is not available\n");
test_Invoke();
test_OleCreatePictureIndirect();
test_Render();
test_get_Handle();
test_get_Type();
test_OleLoadPicturePath();
+ test_himetric();
+ test_load_save_bmp();
+ test_load_save_icon();
+ test_load_save_empty_picture();
}
/* Helper functions only ... */
+static inline NoStatStreamImpl *impl_from_IStream(IStream *iface)
+{
+ return CONTAINING_RECORD(iface, NoStatStreamImpl, IStream_iface);
+}
+
static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
{
GlobalFree(This->supportHandle);
static ULONG WINAPI NoStatStreamImpl_AddRef(
IStream* iface)
{
- NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
+ NoStatStreamImpl* const This = impl_from_IStream(iface);
return InterlockedIncrement(&This->ref);
}
REFIID riid, /* [in] */
void** ppvObject) /* [iid_is][out] */
{
- NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
+ NoStatStreamImpl* const This = impl_from_IStream(iface);
if (ppvObject==0) return E_INVALIDARG;
*ppvObject = 0;
if (IsEqualIID(&IID_IUnknown, riid))
static ULONG WINAPI NoStatStreamImpl_Release(
IStream* iface)
{
- NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
+ NoStatStreamImpl* const This = impl_from_IStream(iface);
ULONG newRef = InterlockedDecrement(&This->ref);
if (newRef==0)
NoStatStreamImpl_Destroy(This);
ULONG cb, /* [in] */
ULONG* pcbRead) /* [out] */
{
- NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
+ NoStatStreamImpl* const This = impl_from_IStream(iface);
void* supportBuffer;
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
ULONG cb, /* [in] */
ULONG* pcbWritten) /* [out] */
{
- NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
+ NoStatStreamImpl* const This = impl_from_IStream(iface);
void* supportBuffer;
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
DWORD dwOrigin, /* [in] */
ULARGE_INTEGER* plibNewPosition) /* [out] */
{
- NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
+ NoStatStreamImpl* const This = impl_from_IStream(iface);
ULARGE_INTEGER newPosition;
switch (dwOrigin)
{
IStream* iface,
ULARGE_INTEGER libNewSize) /* [in] */
{
- NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
+ NoStatStreamImpl* const This = impl_from_IStream(iface);
HGLOBAL supportHandle;
if (libNewSize.u.HighPart != 0)
return STG_E_INVALIDFUNCTION;
In any case the object takes ownership of memory handle and will free it on
object release.
*/
-static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal)
+static IStream* NoStatStream_Construct(HGLOBAL hGlobal)
{
NoStatStreamImpl* newStream;
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl));
if (newStream!=0)
{
- newStream->lpVtbl = &NoStatStreamImpl_Vtbl;
+ newStream->IStream_iface.lpVtbl = &NoStatStreamImpl_Vtbl;
newStream->ref = 1;
newStream->supportHandle = hGlobal;
newStream->streamSize.u.HighPart = 0;
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
}
- return newStream;
+ return &newStream->IStream_iface;
}
#include <float.h>
#define COBJMACROS
+#define CONST_VTABLE
#include "wine/test.h"
#include "windef.h"
#include "winbase.h"
*/
typedef struct IRecordInfoImpl
{
- const IRecordInfoVtbl *lpvtbl;
+ IRecordInfo IRecordInfo_iface;
LONG ref;
DWORD sizeCalled;
DWORD clearCalled;
static const IRecordInfoVtbl IRecordInfoImpl_VTable;
+static inline IRecordInfoImpl *impl_from_IRecordInfo(IRecordInfo *iface)
+{
+ return CONTAINING_RECORD(iface, IRecordInfoImpl, IRecordInfo_iface);
+}
+
static IRecordInfoImpl *IRecordInfoImpl_Construct(void)
{
IRecordInfoImpl *rec;
rec = HeapAlloc(GetProcessHeap(), 0, sizeof(IRecordInfoImpl));
- rec->lpvtbl = &IRecordInfoImpl_VTable;
+ rec->IRecordInfo_iface.lpVtbl = &IRecordInfoImpl_VTable;
rec->ref = START_REF_COUNT;
rec->clearCalled = 0;
rec->sizeCalled = 0;
static ULONG CALLBACK IRecordInfoImpl_AddRef(IRecordInfo *iface)
{
- IRecordInfoImpl* This=(IRecordInfoImpl*)iface;
+ IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
return InterlockedIncrement(&This->ref);
}
static ULONG CALLBACK IRecordInfoImpl_Release(IRecordInfo *iface)
{
- IRecordInfoImpl* This=(IRecordInfoImpl*)iface;
- return InterlockedDecrement(&This->ref);
+ IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ if (!ref)
+ HeapFree(GetProcessHeap(), 0, This);
+
+ return ref;
}
static BOOL fail_GetSize; /* Whether to fail the GetSize call */
static HRESULT CALLBACK IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvExisting)
{
- IRecordInfoImpl* This=(IRecordInfoImpl*)iface;
+ IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
This->clearCalled++;
return S_OK;
}
static HRESULT CALLBACK IRecordInfoImpl_GetSize(IRecordInfo *iface, ULONG* size)
{
- IRecordInfoImpl* This=(IRecordInfoImpl*)iface;
+ IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
This->sizeCalled++;
- *size = 17;
if (fail_GetSize)
+ {
+ *size = RECORD_SIZE_FAIL;
return E_UNEXPECTED;
+ }
*size = RECORD_SIZE;
return S_OK;
}
bound.lLbound = 0;
a = SafeArrayCreate(VT_INT_PTR, 1, &bound);
if (a) {
+ HRESULT hres;
trace("VT_INT_PTR is supported\n");
HAVE_OLEAUT32_INT_PTR = TRUE;
- SafeArrayDestroy(a);
+ hres = SafeArrayDestroy(a);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
else {
trace("VT_INT_PTR is not supported\n");
LONG indices[2];
HRESULT hres;
SAFEARRAYBOUND bound, bounds[2];
- VARIANT v;
+ VARIANT v,d;
LPVOID data;
IID iid;
VARTYPE vt;
ok(hres == S_OK || hres == E_OUTOFMEMORY,
"SAR to a 0 elements dimension failed with hres %x\n", hres);
hres = SafeArrayDestroy(a);
- ok(hres == S_OK,"SAD of 0 dim array faild with hres %x\n", hres);
+ ok(hres == S_OK,"SAD of 0 dim array failed with hres %x\n", hres);
SafeArrayAllocDescriptor(2, &a);
a->rgsabound[0].cElements = 2;
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);
+ ok(hres == S_OK,"SAD failed with hres %x\n", hres);
bounds[0].cElements = 0; bounds[0].lLbound = 1;
bounds[1].cElements = 2; bounds[1].lLbound = 23;
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);
+ ok(hres == S_OK,"SAD failed 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);
+ ok(hres == S_OK,"SAD failed with hres %x\n", hres);
bounds[0].cElements = 42; bounds[0].lLbound = 1;
bounds[1].cElements = 2; bounds[1].lLbound = 23;
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);
+ ok(hres == S_OK,"SAD failed 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)
}
hres = SafeArrayDestroy(c);
- ok(hres == S_OK,"SAD faild with hres %x\n", hres);
+ ok(hres == S_OK,"SAD failed 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);
ok(V_BSTR(&v)[0] == 0x6548,"First letter are not 'He', but %x\n", V_BSTR(&v)[0]);
VariantClear(&v);
+ VariantInit(&d);
+ V_VT(&v) = VT_BSTR;
+ V_BSTR(&v) = SysAllocStringLen(NULL, 0);
+ hres = VariantChangeTypeEx(&d, &v, 0, 0, VT_UI1|VT_ARRAY);
+ ok(hres==S_OK, "CTE VT_BSTR -> VT_UI1|VT_ARRAY failed with %x\n",hres);
+ ok(V_VT(&d) == (VT_UI1|VT_ARRAY),"CTE BSTR -> VT_UI1|VT_ARRAY did not return VT_UI1|VT_ARRAY, but %d.v\n",V_VT(&v));
+ VariantClear(&v);
+ VariantClear(&d);
+
/* check locking functions */
a = SafeArrayCreate(VT_I4, 1, &bound);
ok(a!=NULL,"SAC should not fail\n");
ok(hres == E_INVALIDARG,"SafeArraySetIID of non IID capable safearray did not return E_INVALIDARG, but %x\n",hres);
hres = SafeArrayAllocDescriptor(1,&a);
+ ok(hres == S_OK,"SafeArrayAllocDescriptor should return S_OK, but got %x\n",hres);
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);
+ ok(hres == E_INVALIDARG,"SafeArraySetIID of newly allocated descriptor with SAAD should return E_INVALIDARG, but got %x\n",hres);
hres = SafeArrayDestroyDescriptor(a);
ok(hres == S_OK,"SADD failed with hres %x\n",hres);
for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
a = NULL;
hres = pSafeArrayAllocDescriptorEx(vttypes[i].vt,1,&a);
+ ok(hres == S_OK, "SafeArrayAllocDescriptorEx gave hres 0x%x\n", hres);
ok(a->fFeatures == vttypes[i].expflags,"SAADE(%d) resulted with flags %x, expected %x\n", vttypes[i].vt, a->fFeatures, vttypes[i].expflags);
if (a->fFeatures & FADF_HAVEIID) {
hres = pSafeArrayGetIID(a, &iid);
int element;
if (!pSafeArrayCreateVector)
+ {
+ win_skip("SafeArrayCreateVector not supported\n");
return;
+ }
sa = pSafeArrayCreateVector(VT_UI1, 0, 0);
ok(sa != NULL, "SACV with 0 elements failed.\n");
bVector ? "vector " : "\n", count, hres);
}
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
if (bVector == FALSE && pSafeArrayCreateVector)
}
}
}
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
static void test_SafeArrayGetPutElement_BSTR(void)
ok(hres == S_OK, "Failed to get bstr element at hres 0x%x\n", hres);
if (hres == S_OK)
ok(SysStringLen(value) == SysStringLen(gotvalue), "Got len %d instead of %d\n", SysStringLen(gotvalue), SysStringLen(value));
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
SysFreeString(value);
SysFreeString(gotvalue);
}
-static int tunk_xref = 0;
-static HRESULT WINAPI tunk_QueryInterface(LPUNKNOWN punk,REFIID riid, LPVOID *x) {
- return E_FAIL;
+struct xtunk_impl {
+ IUnknown IUnknown_iface;
+ LONG ref;
+};
+static const IUnknownVtbl xtunk_vtbl;
+
+static struct xtunk_impl xtunk = {{&xtunk_vtbl}, 0};
+
+static HRESULT WINAPI tunk_QueryInterface(IUnknown *punk, REFIID riid, void **x)
+{
+ return E_FAIL;
}
-static ULONG WINAPI tunk_AddRef(LPUNKNOWN punk) {
- return ++tunk_xref;
+
+static ULONG WINAPI tunk_AddRef(IUnknown *punk)
+{
+ return ++xtunk.ref;
}
-static ULONG WINAPI tunk_Release(LPUNKNOWN punk) {
- return --tunk_xref;
+static ULONG WINAPI tunk_Release(IUnknown *punk)
+{
+ return --xtunk.ref;
}
static const IUnknownVtbl xtunk_vtbl = {
tunk_Release
};
-static struct xtunk_iface {
- const IUnknownVtbl *lpvtbl;
-} xtunk_iface;
-
-
static void test_SafeArrayGetPutElement_IUnknown(void)
{
SAFEARRAYBOUND sab;
LONG indices[1];
SAFEARRAY *sa;
HRESULT hres;
- LPUNKNOWN value = 0, gotvalue;
+ IUnknown *gotvalue;
sab.lLbound = 1;
sab.cElements = 1;
return;
indices[0] = sab.lLbound;
- xtunk_iface.lpvtbl = &xtunk_vtbl;
- value = (LPUNKNOWN)&xtunk_iface;
- tunk_xref = 1;
- ok (value != NULL, "Expected non-NULL\n");
- hres = SafeArrayPutElement(sa, indices, value);
+ xtunk.ref = 1;
+ hres = SafeArrayPutElement(sa, indices, &xtunk.IUnknown_iface);
ok(hres == S_OK, "Failed to put bstr element hres 0x%x\n", hres);
- ok(tunk_xref == 2,"Failed to increment refcount of iface.\n");
+ ok(xtunk.ref == 2,"Failed to increment refcount of iface.\n");
gotvalue = NULL;
hres = SafeArrayGetElement(sa, indices, &gotvalue);
- ok(tunk_xref == 3,"Failed to increment refcount of iface.\n");
+ ok(xtunk.ref == 3,"Failed to increment refcount of iface.\n");
ok(hres == S_OK, "Failed to get bstr element at hres 0x%x\n", hres);
if (hres == S_OK)
- ok(value == gotvalue, "Got %p instead of %p\n", gotvalue, value);
- SafeArrayDestroy(sa);
- ok(tunk_xref == 2,"Failed to decrement refcount of iface.\n");
+ ok(gotvalue == &xtunk.IUnknown_iface, "Got %p instead of %p\n", gotvalue, &xtunk.IUnknown_iface);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+ ok(xtunk.ref == 2,"Failed to decrement refcount of iface.\n");
}
static void test_SafeArrayRedim_IUnknown(void)
LONG indices[1];
SAFEARRAY *sa;
HRESULT hres;
- LPUNKNOWN value;
sab.lLbound = 1;
sab.cElements = 2;
return;
indices[0] = 2;
- xtunk_iface.lpvtbl = &xtunk_vtbl;
- value = (LPUNKNOWN)&xtunk_iface;
- tunk_xref = 1;
- hres = SafeArrayPutElement(sa, indices, value);
+ xtunk.ref = 1;
+ hres = SafeArrayPutElement(sa, indices, &xtunk.IUnknown_iface);
ok(hres == S_OK, "Failed to put IUnknown element hres 0x%x\n", hres);
- ok(tunk_xref == 2,"Failed to increment refcount of iface.\n");
+ ok(xtunk.ref == 2,"Failed to increment refcount of iface.\n");
sab.cElements = 1;
hres = SafeArrayRedim(sa, &sab);
ok(hres == S_OK, "Failed to shrink array hres 0x%x\n", hres);
- ok(tunk_xref == 1, "Failed to decrement refcount\n");
- SafeArrayDestroy(sa);
+ ok(xtunk.ref == 1, "Failed to decrement refcount\n");
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
static void test_SafeArrayGetPutElement_VARIANT(void)
if (V_VT(&value) == V_VT(&gotvalue))
ok(V_I4(&value) == V_I4(&gotvalue), "Got %d instead of %d\n", V_I4(&value), V_VT(&gotvalue));
}
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
int dimension,size=1;
if (!pSafeArrayCopyData)
+ {
+ win_skip("SafeArrayCopyData not supported\n");
return;
+ }
for (dimension = 0; dimension < NUM_DIMENSIONS; dimension++)
{
ok(hres == E_INVALIDARG, "Smaller copy last dimension hres 0x%x\n", hres);
sacopy->rgsabound[3].cElements += 1;
- SafeArrayDestroy(sacopy);
+ hres = SafeArrayDestroy(sacopy);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
sacopy = NULL;
hres = pSafeArrayCopyData(sa, sacopy);
ok(hres == E_INVALIDARG, "->Null copy hres 0x%x\n", hres);
ok(SafeArrayGetElemsize(sa) == SafeArrayGetElemsize(sacopy),"elemsize wrong\n");
ok(SafeArrayGetDim(sa) == SafeArrayGetDim(sacopy),"dimensions wrong\n");
ok(!memcmp(sa->pvData, sacopy->pvData, size * sizeof(int)), "compared different\n");
- SafeArrayDestroy(sacopy);
+ hres = SafeArrayDestroy(sacopy);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
static void test_SafeArrayCreateEx(void)
int dimension;
if (!pSafeArrayCreateEx)
+ {
+ win_skip("SafeArrayCreateEx not supported\n");
return;
+ }
for (dimension = 0; dimension < NUM_DIMENSIONS; dimension++)
{
ok(hres == S_OK && IsEqualGUID(&guid, &IID_IUnknown), "Set bad IID\n");
}
}
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
sa = pSafeArrayCreateEx(VT_DISPATCH, 1, sab, NULL);
ok(IsEqualGUID(&guid, &IID_IDispatch), "CreateEx (NULL) bad IID\n");
}
}
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
sa = pSafeArrayCreateEx(VT_UNKNOWN, 1, sab, NULL);
ok(IsEqualGUID(&guid, &IID_IUnknown), "CreateEx (NULL-Unk) bad IID\n");
}
}
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
/* VT_RECORD failure case */
sa = pSafeArrayCreateEx(VT_RECORD, 1, sab, NULL);
- ok(sa == NULL, "CreateEx (NULL-Rec) succeded\n");
+ ok(sa == NULL, "CreateEx (NULL-Rec) succeeded\n");
iRec = IRecordInfoImpl_Construct();
if (sa)
{
ok(sa->cbElements == RECORD_SIZE_FAIL, "Altered size to %d\n", sa->cbElements);
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
ok(iRec->clearCalled == sab[0].cElements, "Destroy->Clear called %d times\n", iRec->clearCalled);
+ ok(iRec->ref == START_REF_COUNT, "got %d, expected %d\n", iRec->ref, START_REF_COUNT);
}
/* Test VT_RECORD array */
hres = pSafeArrayGetRecordInfo(sa, &saRec);
ok(hres == S_OK,"GRI failed\n");
- ok(saRec == (IRecordInfo*)iRec,"Different saRec\n");
+ ok(saRec == &iRec->IRecordInfo_iface, "Different saRec\n");
ok(iRec->ref == START_REF_COUNT + 2, "Didn't AddRef %d\n", iRec->ref);
if (iRec->ref == START_REF_COUNT + 2)
IRecordInfo_Release(saRec);
ok(sa->cbElements == RECORD_SIZE,"Elemsize is %d\n", sa->cbElements);
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
ok(iRec->sizeCalled == 1, "Destroy->GetSize called %d times\n", iRec->sizeCalled);
ok(iRec->clearCalled == sab[0].cElements, "Destroy->Clear called %d times\n", iRec->clearCalled);
ok(iRec->ref == START_REF_COUNT, "Wrong iRec refcount %d\n", iRec->ref);
}
+ else
+ {
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+ }
+
+ IRecordInfo_Release(&iRec->IRecordInfo_iface);
}
static void test_SafeArrayClear(void)
hres = VariantClear(&v);
ok(hres == DISP_E_BADVARTYPE, "VariantClear: hres 0x%x\n", hres);
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
static void test_SafeArrayCopy(void)
"VariantCopy: hres 0x%x, Type %d\n", hres, V_VT(&vDst));
ok(V_ARRAY(&vDst) != sa, "VariantClear: Performed shallow copy\n");
- SafeArrayDestroy(V_ARRAY(&vSrc));
- SafeArrayDestroy(V_ARRAY(&vDst));
+ hres = SafeArrayDestroy(V_ARRAY(&vSrc));
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+ hres = SafeArrayDestroy(V_ARRAY(&vDst));
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+
+ hres = SafeArrayAllocDescriptor(1, &sa);
+ ok(hres == S_OK, "SafeArrayAllocDescriptor failed with error 0x%08x\n", hres);
+
+ sa->cbElements = 16;
+ hres = SafeArrayCopy(sa, &sa2);
+ ok(hres == S_OK, "SafeArrayCopy failed with error 0x%08x\n", hres);
+ ok(sa != sa2, "SafeArrayCopy performed shallow copy\n");
+
+ hres = SafeArrayDestroy(sa2);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+
+ sa2 = (void*)0xdeadbeef;
+ hres = SafeArrayCopy(NULL, &sa2);
+ ok(hres == S_OK, "SafeArrayCopy failed with error 0x%08x\n", hres);
+ ok(!sa2, "SafeArrayCopy didn't return NULL for output array\n");
hres = SafeArrayAllocDescriptor(1, &sa);
ok(hres == S_OK, "SafeArrayAllocDescriptor failed with error 0x%08x\n", hres);
+ sa2 = (void*)0xdeadbeef;
hres = SafeArrayCopy(sa, &sa2);
ok(hres == E_INVALIDARG,
"SafeArrayCopy with empty array should have failed with error E_INVALIDARG instead of 0x%08x\n",
hres);
- sa->cbElements = 16;
- hres = SafeArrayCopy(sa, &sa2);
- ok(hres == S_OK, "SafeArrayCopy failed with error 0x%08x\n", hres);
+ ok(!sa2, "SafeArrayCopy didn't return NULL for output array\n");
- SafeArrayDestroy(sa2);
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa2);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
}
#define MKARRAY(low,num,typ) sab.lLbound = low; sab.cElements = num; \
}
/* VT_VECTOR|VT_UI1 -> VT_BSTR */
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
if (pSafeArrayCreateVector)
{
sa = pSafeArrayCreateVector(VT_UI1, 0, strlen(szHello)+1);
}
/* To/from BSTR only works with arrays of VT_UI1 */
- for (vt = 0; vt <= VT_CLSID; vt++)
+ for (vt = VT_EMPTY; vt <= VT_CLSID; vt++)
{
if (vt == VT_UI1)
continue;
- MKARRAYCONT(0,1,vt);
+ sab.lLbound = 0;
+ sab.cElements = 1;
+ sa = SafeArrayCreate(vt, 1, &sab);
+ if (!sa) continue;
+
+ V_VT(&v) = VT_ARRAY|vt;
+ V_ARRAY(&v) = sa;
+ VariantInit(&v2);
+
hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_BSTR);
- ok(hres != S_OK, "CTE VT_ARRAY|VT %d->BSTR succeeded\n", vt);
+ if (vt == VT_INT_PTR || vt == VT_UINT_PTR)
+ {
+ ok(hres == DISP_E_BADVARTYPE, "expected DISP_E_BADVARTYPE, got 0x%08x\n", hres);
+ SafeArrayDestroy(sa);
+ }
+ else
+ {
+ ok(hres == DISP_E_TYPEMISMATCH, "got 0x%08x for vt=%d, instead of DISP_E_TYPEMISMATCH\n", hres, vt);
+ hres = VariantClear(&v);
+ ok(hres == S_OK, "expected S_OK, got 0x%08x\n", hres);
+ }
VariantClear(&v2);
- VariantClear(&v);
}
/* Can't change an array of one type into array of another type , even
ok(hres == DISP_E_TYPEMISMATCH, "CTE VT_ARRAY|VT_UI1->VT_ARRAY|VT_I1 returned %x\n", hres);
/* But can change to the same array type */
- SafeArrayDestroy(sa);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
sa = pSafeArrayCreateVector(VT_UI1, 0, 1);
ok(sa != NULL, "CreateVector() failed.\n");
if (!sa)
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);
+ hres = SafeArrayDestroy(sa);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
VariantClear(&v2);
}
hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_EMPTY);
ok(hres == DISP_E_TYPEMISMATCH, "CTE VT_ARRAY|VT_UI1 returned %x\n", hres);
VariantClear(&v);
-
}
static void test_SafeArrayDestroyData (void)
GETPTR(SafeArrayGetVartype);
GETPTR(SafeArrayCreateEx);
GETPTR(SafeArrayCreateVector);
+ GETPTR(SafeArrayGetRecordInfo);
check_for_VT_INT_PTR();
test_safearray();
#include "tmarshal.h"
#include "tmarshal_dispids.h"
+static HRESULT (WINAPI *pVarAdd)(LPVARIANT,LPVARIANT,LPVARIANT);
+
+
#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_BYVAL = {0x12345678, ULL_CONST(0xdeadbeef, 0x98765432), {0,1,2,3,4,5,6,7}};
+const MYSTRUCT MYSTRUCT_BYPTR = {0x91827364, ULL_CONST(0x88776655, 0x44332211), {0,1,2,3,4,5,6,7}};
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)},
+ {0x1a1b1c1d, ULL_CONST(0x1e1f1011, 0x12131415), {0,1,2,3,4,5,6,7}},
+ {0x2a2b2c2d, ULL_CONST(0x2e2f2021, 0x22232425), {0,1,2,3,4,5,6,7}},
+ {0x3a3b3c3d, ULL_CONST(0x3e3f3031, 0x32333435), {0,1,2,3,4,5,6,7}},
+ {0x4a4b4c4d, ULL_CONST(0x4e4f4041, 0x42434445), {0,1,2,3,4,5,6,7}},
+ {0x5a5b5c5d, ULL_CONST(0x5e5f5051, 0x52535455), {0,1,2,3,4,5,6,7}},
};
static ItestDual TestDual, TestDualDisp;
+static HRESULT WINAPI TestSecondIface_QueryInterface(ITestSecondIface *iface, REFIID riid, void **ppv)
+{
+ return ItestDual_QueryInterface(&TestDual, riid, ppv);
+}
+
+static ULONG WINAPI TestSecondIface_AddRef(ITestSecondIface *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI TestSecondIface_Release(ITestSecondIface *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI TestSecondIface_test(ITestSecondIface *iface)
+{
+ return 1;
+}
+
+static const ITestSecondIfaceVtbl TestSecondIfaceVtbl = {
+ TestSecondIface_QueryInterface,
+ TestSecondIface_AddRef,
+ TestSecondIface_Release,
+ TestSecondIface_test
+};
+
+static ITestSecondIface TestSecondIface = { &TestSecondIfaceVtbl };
+
static HRESULT WINAPI TestDual_QueryInterface(ItestDual *iface, REFIID riid, void **ppvObject)
{
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch)) {
}else if(IsEqualGUID(riid, &IID_ItestDual)) {
*ppvObject = &TestDual;
return S_OK;
+ }else if(IsEqualGUID(riid, &IID_ITestSecondIface)) {
+ *ppvObject = &TestSecondIface;
+ return S_OK;
}
*ppvObject = NULL;
typedef struct Widget
{
- const IWidgetVtbl *lpVtbl;
+ IWidget IWidget_iface;
LONG refs;
IUnknown *pDispatchUnknown;
} Widget;
+static inline Widget *impl_from_IWidget(IWidget *iface)
+{
+ return CONTAINING_RECORD(iface, Widget, IWidget_iface);
+}
+
static HRESULT WINAPI Widget_QueryInterface(
IWidget *iface,
/* [in] */ REFIID riid,
static ULONG WINAPI Widget_AddRef(
IWidget *iface)
{
- Widget *This = (Widget *)iface;
+ Widget *This = impl_from_IWidget(iface);
return InterlockedIncrement(&This->refs);
}
static ULONG WINAPI Widget_Release(
IWidget *iface)
{
- Widget *This = (Widget *)iface;
+ Widget *This = impl_from_IWidget(iface);
ULONG refs = InterlockedDecrement(&This->refs);
if (!refs)
{
IWidget *iface,
/* [out] */ UINT __RPC_FAR *pctinfo)
{
- Widget *This = (Widget *)iface;
+ Widget *This = impl_from_IWidget(iface);
IDispatch *pDispatch;
HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch);
if (SUCCEEDED(hr))
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
{
- Widget *This = (Widget *)iface;
+ Widget *This = impl_from_IWidget(iface);
IDispatch *pDispatch;
HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch);
if (SUCCEEDED(hr))
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
{
- Widget *This = (Widget *)iface;
+ Widget *This = impl_from_IWidget(iface);
IDispatch *pDispatch;
HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch);
if (SUCCEEDED(hr))
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
/* [out] */ UINT __RPC_FAR *puArgErr)
{
- Widget *This = (Widget *)iface;
+ Widget *This = impl_from_IWidget(iface);
IDispatch *pDispatch;
HRESULT hr = IUnknown_QueryInterface(This->pDispatchUnknown, &IID_IDispatch, (void **)&pDispatch);
if (SUCCEEDED(hr))
return S_OK;
}
+static HRESULT WINAPI Widget_VariantCArray(
+ IWidget * iface,
+ ULONG count,
+ VARIANT values[])
+{
+ ULONG i;
+
+ trace("VariantCArray(%u,%p)\n", count, values);
+
+ ok(count == 2, "count is %d\n", count);
+ for (i = 0; i < count; i++)
+ ok(V_VT(&values[i]) == VT_I4, "values[%d] is not VT_I4\n", i);
+
+ if (pVarAdd)
+ {
+ VARIANT inc, res;
+ HRESULT hr;
+
+ V_VT(&inc) = VT_I4;
+ V_I4(&inc) = 1;
+ for (i = 0; i < count; i++) {
+ VariantInit(&res);
+ hr = pVarAdd(&values[i], &inc, &res);
+ if (FAILED(hr)) {
+ ok(0, "VarAdd failed at %u with error 0x%x\n", i, hr);
+ return hr;
+ }
+ hr = VariantCopy(&values[i], &res);
+ if (FAILED(hr)) {
+ ok(0, "VariantCopy failed at %u with error 0x%x\n", i, hr);
+ return hr;
+ }
+ }
+ }
+ else
+ win_skip("VarAdd is not available\n");
+
+ return S_OK;
+}
+
static HRESULT WINAPI Widget_Variant(
IWidget __RPC_FAR * iface,
VARIANT var)
return S_OK;
}
+
+static BOOL mystruct_uint_ordered(MYSTRUCT *mystruct)
+{
+ int i;
+ for (i = 0; i < sizeof(mystruct->uarr)/sizeof(mystruct->uarr[0]); i++)
+ if (mystruct->uarr[i] != i)
+ return 0;
+
+ return 1;
+}
+
static HRESULT WINAPI Widget_StructArgs(
IWidget * iface,
MYSTRUCT byval,
{
int i, diff = 0;
ok(byval.field1 == MYSTRUCT_BYVAL.field1 &&
- byval.field2 == MYSTRUCT_BYVAL.field2,
+ byval.field2 == MYSTRUCT_BYVAL.field2 &&
+ mystruct_uint_ordered(&byval),
"Struct parameter passed by value corrupted\n");
ok(byptr->field1 == MYSTRUCT_BYPTR.field1 &&
- byptr->field2 == MYSTRUCT_BYPTR.field2,
+ byptr->field2 == MYSTRUCT_BYPTR.field2 &&
+ mystruct_uint_ordered(byptr),
"Struct parameter passed by pointer corrupted\n");
for (i = 0; i < 5; i++)
if (arr[i].field1 != MYSTRUCT_ARRAY[i].field1 ||
- arr[i].field2 != MYSTRUCT_ARRAY[i].field2)
+ arr[i].field2 != MYSTRUCT_ARRAY[i].field2 ||
+ ! mystruct_uint_ordered(&arr[i]))
diff++;
ok(diff == 0, "Array of structs corrupted\n");
return S_OK;
return S_OK;
}
+static HRESULT WINAPI Widget_do_restrict(IWidget* iface, INT *i)
+{
+ trace("restrict\n");
+ *i = DISPID_TM_RESTRICTED;
+ return S_OK;
+}
+
+static HRESULT WINAPI Widget_neg_restrict(IWidget* iface, INT *i)
+{
+ trace("neg_restrict\n");
+ *i = DISPID_TM_NEG_RESTRICTED;
+ return S_OK;
+}
+
static const struct IWidgetVtbl Widget_VTable =
{
Widget_QueryInterface,
Widget_Value,
Widget_Array,
Widget_VariantArrayPtr,
+ Widget_VariantCArray,
Widget_Variant,
Widget_VarArg,
Widget_StructArgs,
Widget_ByRefUInt,
Widget_put_prop_opt_arg,
Widget_put_prop_req_arg,
+ Widget_do_restrict,
+ Widget_neg_restrict
};
static HRESULT WINAPI StaticWidget_QueryInterface(IStaticWidget *iface, REFIID riid, void **ppvObject)
static HRESULT WINAPI StaticWidget_TestDual(IStaticWidget *iface, ItestDual *p)
{
trace("TestDual()\n");
- todo_wine
ok(p == &TestDual, "wrong ItestDual\n");
return S_OK;
}
+static HRESULT WINAPI StaticWidget_TestSecondIface(IStaticWidget *iface, ITestSecondIface *p)
+{
+ trace("TestSecondIface()\n");
+ ok(p == &TestSecondIface, "wrong ItestSecondIface\n");
+ return S_OK;
+}
+
static const IStaticWidgetVtbl StaticWidgetVtbl = {
StaticWidget_QueryInterface,
StaticWidget_AddRef,
StaticWidget_GetTypeInfo,
StaticWidget_GetIDsOfNames,
StaticWidget_Invoke,
- StaticWidget_TestDual
+ StaticWidget_TestDual,
+ StaticWidget_TestSecondIface
};
static IStaticWidget StaticWidget = { &StaticWidgetVtbl };
typedef struct KindaEnum
{
- const IKindaEnumWidgetVtbl *lpVtbl;
+ IKindaEnumWidget IKindaEnumWidget_iface;
LONG refs;
} KindaEnum;
+static inline KindaEnum *impl_from_IKindaEnumWidget(IKindaEnumWidget *iface)
+{
+ return CONTAINING_RECORD(iface, KindaEnum, IKindaEnumWidget_iface);
+}
+
static HRESULT register_current_module_typelib(void)
{
WCHAR path[MAX_PATH];
return NULL;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
- This->lpVtbl = &Widget_VTable;
+ This->IWidget_iface.lpVtbl = &Widget_VTable;
This->refs = 1;
This->pDispatchUnknown = NULL;
- hr = CreateStdDispatch((IUnknown *)&This->lpVtbl, This, pTypeInfo, &This->pDispatchUnknown);
+ hr = CreateStdDispatch((IUnknown *)&This->IWidget_iface, This, pTypeInfo,
+ &This->pDispatchUnknown);
ok_ole_success(hr, CreateStdDispatch);
ITypeInfo_Release(pTypeInfo);
if (SUCCEEDED(hr))
- return (IWidget *)&This->lpVtbl;
+ return &This->IWidget_iface;
else
{
HeapFree(GetProcessHeap(), 0, This);
static ULONG WINAPI KindaEnum_AddRef(
IKindaEnumWidget *iface)
{
- KindaEnum *This = (KindaEnum *)iface;
+ KindaEnum *This = impl_from_IKindaEnumWidget(iface);
return InterlockedIncrement(&This->refs);
}
static ULONG WINAPI KindaEnum_Release(
IKindaEnumWidget *iface)
{
- KindaEnum *This = (KindaEnum *)iface;
+ KindaEnum *This = impl_from_IKindaEnumWidget(iface);
ULONG refs = InterlockedDecrement(&This->refs);
if (!refs)
{
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This) return NULL;
- This->lpVtbl = &KindaEnumWidget_VTable;
+ This->IKindaEnumWidget_iface.lpVtbl = &KindaEnumWidget_VTable;
This->refs = 1;
- return (IKindaEnumWidget *)This;
+ return &This->IKindaEnumWidget_iface;
}
static HRESULT WINAPI NonOleAutomation_QueryInterface(INonOleAutomation *iface, REFIID riid, void **ppv)
IKindaEnumWidget_Release(pKEW);
+ /* call GetTypeInfoCount (direct) */
+ hr = IWidget_GetTypeInfoCount(pWidget, &uval);
+ ok_ole_success(hr, IWidget_GetTypeInfoCount);
+ hr = IWidget_GetTypeInfoCount(pWidget, &uval);
+ ok_ole_success(hr, IWidget_GetTypeInfoCount);
+
hr = IWidget_QueryInterface(pWidget, &IID_IDispatch, (void **)&pDispatch);
+ ok_ole_success(hr, IWidget_QueryInterface);
/* call put_Name */
VariantInit(&vararg[0]);
VariantClear(&varresult);
/* call get_Name (direct) */
- bstr = NULL;
+ bstr = (void *)0xdeadbeef;
hr = IWidget_get_Name(pWidget, &bstr);
ok_ole_success(hr, IWidget_get_Name);
ok(!lstrcmpW(bstr, szCat), "IWidget_get_Name should have returned string \"Cat\" instead of %s\n", wine_dbgstr_w(bstr));
ok(V_VT(&varresult) == VT_BSTR, "Return value should be of type BSTR instead of %d\n", V_VT(&varresult));
ok(!lstrcmpW(V_BSTR(&varresult), szTestTest), "Return value should have been \"TestTest\" instead of %s\n", wine_dbgstr_w(V_BSTR(&varresult)));
VariantClear(&varresult);
+ SysFreeString(bstr);
/* call SetOleColor with large negative VT_I4 param */
VariantInit(&vararg[0]);
ok_ole_success(hr, IDispatch_Invoke);
VariantClear(&varresult);
+ /* call VariantCArray - test marshaling of variant arrays */
+ V_VT(&vararg[0]) = VT_I4;
+ V_I4(&vararg[0]) = 1;
+ V_VT(&vararg[1]) = VT_I4;
+ V_I4(&vararg[1]) = 2;
+ hr = IWidget_VariantCArray(pWidget, 2, vararg);
+ ok_ole_success(hr, IWidget_VariantCArray);
+ todo_wine
+ ok(V_VT(&vararg[0]) == VT_I4 && V_I4(&vararg[0]) == 2, "vararg[0] = %d[%d]\n", V_VT(&vararg[0]), V_I4(&vararg[0]));
+ todo_wine
+ ok(V_VT(&vararg[1]) == VT_I4 && V_I4(&vararg[1]) == 3, "vararg[1] = %d[%d]\n", V_VT(&vararg[1]), V_I4(&vararg[1]));
+
/* call VarArg */
VariantInit(&vararg[3]);
V_VT(&vararg[3]) = VT_I4;
ok_ole_success(hr, ITypeInfo_Invoke);
VariantClear(&varresult);
+ /* restricted member */
+ dispparams.cNamedArgs = 0;
+ dispparams.rgdispidNamedArgs = NULL;
+ dispparams.cArgs = 0;
+ dispparams.rgvarg = NULL;
+ VariantInit(&varresult);
+ hr = IDispatch_Invoke(pDispatch, DISPID_TM_RESTRICTED, &IID_NULL, 0x40c, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
+ ok( hr == DISP_E_MEMBERNOTFOUND, "got %08x\n", hr );
+ VariantClear(&varresult);
+
+ /* restricted member with -ve memid (not restricted) */
+ dispparams.cNamedArgs = 0;
+ dispparams.rgdispidNamedArgs = NULL;
+ dispparams.cArgs = 0;
+ dispparams.rgvarg = NULL;
+ VariantInit(&varresult);
+ hr = IDispatch_Invoke(pDispatch, DISPID_TM_NEG_RESTRICTED, &IID_NULL, 0x40c, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok(V_VT(&varresult) == VT_I4, "got %x\n", V_VT(&varresult));
+ ok(V_I4(&varresult) == DISPID_TM_NEG_RESTRICTED, "got %x\n", V_I4(&varresult));
+ VariantClear(&varresult);
+
IDispatch_Release(pDispatch);
IWidget_Release(pWidget);
ok(V_VT(&varresult) == VT_EMPTY, "vt %x\n", V_VT(&varresult));
VariantClear(&varresult);
+ /* call TestSecondIface */
+ 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_TESTSECONDIFACE, 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)
{
HRESULT hr;
+ HANDLE hOleaut32 = GetModuleHandleA("oleaut32.dll");
+ pVarAdd = (void*)GetProcAddress(hOleaut32, "VarAdd");
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hr = register_current_module_typelib();
- ok_ole_success(hr, register_current_module_typelib);
+ if (FAILED(hr))
+ {
+ CoUninitialize();
+ win_skip("Registration of the test typelib failed, skipping tests\n");
+ return;
+ }
test_typelibmarshal();
test_DispCallFunc();
{
INT field1;
ULONGLONG field2;
+ UINT uarr[8];
} MYSTRUCT;
coclass ApplicationObject2;
HRESULT test();
}
+ [
+ odl,
+ uuid(3f7e06fe-0bce-46f0-8b7d-3a68393c7968)
+ ]
+ interface ITestSecondIface : IUnknown
+ {
+ HRESULT test();
+ }
+
[
odl,
uuid(a1f8cae3-c947-4c5f-b57d-c87b9b5f3586),
[id(DISPID_TM_VARARRAYPTR)]
HRESULT VariantArrayPtr([in] SAFEARRAY(VARIANT) *values);
+ [id(DISPID_TM_VARCARRAY)]
+ HRESULT VariantCArray([in] ULONG count, [in, out] VARIANT values[2]);
+
[id(DISPID_TM_VARIANT)]
HRESULT Variant([in] VARIANT var);
[id(DISPID_TM_PROP_REQ_ARG), propput]
HRESULT prop_req_arg([in] INT req, [in] INT i);
+
+ [id(DISPID_TM_RESTRICTED), restricted]
+ HRESULT do_restrict([out, retval] INT *i);
+
+ [id(DISPID_TM_NEG_RESTRICTED), restricted]
+ HRESULT neg_restrict([out, retval] INT *i);
}
[
{
[id(DISPID_TM_TESTDUAL)]
HRESULT TestDual([in] ItestDual *p);
+
+ [id(DISPID_TM_TESTSECONDIFACE)]
+ HRESULT TestSecondIface([in] ITestSecondIface *p);
}
[
#define DISPID_TM_BYREF_UINT 21
#define DISPID_TM_PROP_OPT_ARG 22
#define DISPID_TM_PROP_REQ_ARG 23
+#define DISPID_TM_VARCARRAY 24
+#define DISPID_TM_RESTRICTED 25
+#define DISPID_TM_NEG_RESTRICTED -26
+#define DISPID_TM_TESTSECONDIFACE 27
#define DISPID_NOA_BSTRRET 1
#define DISPID_NOA_ERROR 2
#include "ocidl.h"
#include "shlwapi.h"
#include "tmarshal.h"
-#include "initguid.h"
#include "test_reg.h"
static HRESULT (WINAPI *pUnRegisterTypeLibForUser)(REFGUID,WORD,WORD,LCID,SYSKIND);
static const WCHAR wszStdOle2[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
+static WCHAR wszGUID[] = {'G','U','I','D',0};
+static WCHAR wszguid[] = {'g','u','i','d',0};
+
+static const int is_win64 = sizeof(void *) > sizeof(int);
static void init_function_pointers(void)
{
BINDPTR bindptr;
ITypeInfo *pTypeInfo;
ITypeInfo *pFontTypeInfo;
+ ITypeComp *pTypeComp_tmp;
static WCHAR wszStdFunctions[] = {'S','t','d','F','u','n','c','t','i','o','n','s',0};
static WCHAR wszSavePicture[] = {'S','a','v','e','P','i','c','t','u','r','e',0};
static WCHAR wszOLE_TRISTATE[] = {'O','L','E','_','T','R','I','S','T','A','T','E',0};
static WCHAR wszUnchecked[] = {'U','n','c','h','e','c','k','e','d',0};
static WCHAR wszIUnknown[] = {'I','U','n','k','n','o','w','n',0};
static WCHAR wszFont[] = {'F','o','n','t',0};
- static WCHAR wszGUID[] = {'G','U','I','D',0};
static WCHAR wszStdPicture[] = {'S','t','d','P','i','c','t','u','r','e',0};
static WCHAR wszOLE_COLOR[] = {'O','L','E','_','C','O','L','O','R',0};
static WCHAR wszClone[] = {'C','l','o','n','e',0};
static WCHAR wszclone[] = {'c','l','o','n','e',0};
static WCHAR wszJunk[] = {'J','u','n','k',0};
+ static WCHAR wszAddRef[] = {'A','d','d','R','e','f',0};
hr = LoadTypeLib(wszStdOle2, &pTypeLib);
ok_ole_success(hr, LoadTypeLib);
ok(!pTypeInfo, "pTypeInfo should have been set to NULL\n");
ok(!bindptr.lptcomp, "bindptr should have been set to NULL\n");
+ /* test basic BindType argument handling */
+ ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
+ hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, NULL, NULL);
+ ok(hr == E_INVALIDARG, "Got %08x\n", hr);
+
+ ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
+ pTypeInfo = (void*)0xdeadbeef;
+ hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, &pTypeInfo, NULL);
+ ok(hr == E_INVALIDARG, "Got %08x\n", hr);
+ ok(pTypeInfo == (void*)0xdeadbeef, "Got %p\n", pTypeInfo);
+
+ ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
+ pTypeComp_tmp = (void*)0xdeadbeef;
+ hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, NULL, &pTypeComp_tmp);
+ ok(hr == E_INVALIDARG, "Got %08x\n", hr);
+ ok(pTypeComp_tmp == (void*)0xdeadbeef, "Got %p\n", pTypeComp_tmp);
+
+ ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
+ pTypeComp_tmp = (void*)0xdeadbeef;
+ pTypeInfo = (void*)0xdeadbeef;
+ hr = ITypeComp_BindType(pTypeComp, NULL, ulHash, &pTypeInfo, &pTypeComp_tmp);
+ ok(hr == E_INVALIDARG, "Got %08x\n", hr);
+ ok(pTypeInfo == (void*)0xdeadbeef, "Got %p\n", pTypeInfo);
+ ok(pTypeComp_tmp == (void*)0xdeadbeef, "Got %p\n", pTypeComp_tmp);
+
+ ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszGUID);
+ pTypeComp_tmp = (void*)0xdeadbeef;
+ pTypeInfo = (void*)0xdeadbeef;
+ hr = ITypeComp_BindType(pTypeComp, wszGUID, ulHash, &pTypeInfo, &pTypeComp_tmp);
+ ok_ole_success(hr, ITypeComp_BindType);
+ ok(pTypeInfo != NULL, "Got NULL pTypeInfo\n");
+ todo_wine ok(pTypeComp_tmp == NULL, "Got pTypeComp_tmp %p\n", pTypeComp_tmp);
+ ITypeInfo_Release(pTypeInfo);
+ if(pTypeComp_tmp) ITypeComp_Release(pTypeComp_tmp); /* fixme */
+
+ /* test BindType case-insensitivity */
+ ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszguid);
+ pTypeComp_tmp = (void*)0xdeadbeef;
+ pTypeInfo = (void*)0xdeadbeef;
+ hr = ITypeComp_BindType(pTypeComp, wszguid, ulHash, &pTypeInfo, &pTypeComp_tmp);
+ ok_ole_success(hr, ITypeComp_BindType);
+ ok(pTypeInfo != NULL, "Got NULL pTypeInfo\n");
+ todo_wine ok(pTypeComp_tmp == NULL, "Got pTypeComp_tmp %p\n", pTypeComp_tmp);
+ ITypeInfo_Release(pTypeInfo);
+ if(pTypeComp_tmp) ITypeComp_Release(pTypeComp_tmp); /* fixme */
+
ITypeComp_Release(pTypeComp);
/* tests for ITypeComp on an interface */
ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
ITypeInfo_Release(pTypeInfo);
- /* tests non-existent members */
+ /* tests nonexistent members */
desckind = 0xdeadbeef;
bindptr.lptcomp = (ITypeComp*)0xdeadbeef;
pTypeInfo = (ITypeInfo*)0xdeadbeef;
ok(pTypeInfo == NULL, "pTypeInfo should have been NULL, was: %p\n", pTypeInfo);
ok(bindptr.lptcomp == NULL, "bindptr should have been NULL, was: %p\n", bindptr.lptcomp);
+ /* tests inherited members */
+ desckind = 0xdeadbeef;
+ bindptr.lpfuncdesc = NULL;
+ pTypeInfo = NULL;
+ ulHash = LHashValOfNameSys(SYS_WIN32, LOCALE_NEUTRAL, wszAddRef);
+ hr = ITypeComp_Bind(pTypeComp, wszAddRef, ulHash, 0, &pTypeInfo, &desckind, &bindptr);
+ ok_ole_success(hr, ITypeComp_Bind);
+ ok(desckind == DESCKIND_FUNCDESC, "desckind should have been DESCKIND_FUNCDESC, was: %d\n", desckind);
+ ok(pTypeInfo != NULL, "pTypeInfo should not have been NULL, was: %p\n", pTypeInfo);
+ ok(bindptr.lpfuncdesc != NULL, "bindptr should not have been NULL, was: %p\n", bindptr.lpfuncdesc);
+ ITypeInfo_ReleaseFuncDesc(pTypeInfo, bindptr.lpfuncdesc);
+ ITypeInfo_Release(pTypeInfo);
+
ITypeComp_Release(pTypeComp);
ITypeInfo_Release(pFontTypeInfo);
ITypeLib_Release(pTypeLib);
DISPPARAMS dispparams;
GUID bogusguid = {0x806afb4f,0x13f7,0x42d2,{0x89,0x2c,0x6c,0x97,0xc3,0x6a,0x36,0xc1}};
VARIANT var;
+ UINT count;
+ TYPEKIND kind;
hr = LoadTypeLib(wszStdOle2, &pTypeLib);
ok_ole_success(hr, LoadTypeLib);
+ count = ITypeLib_GetTypeInfoCount(pTypeLib);
+ ok(count > 0, "got %d\n", count);
+
+ /* invalid index */
+ hr = ITypeLib_GetTypeInfo(pTypeLib, count, &pTypeInfo);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hr);
+
+ hr = ITypeLib_GetTypeInfo(pTypeLib, 0, NULL);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ hr = ITypeLib_GetLibAttr(pTypeLib, NULL);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ hr = ITypeLib_GetTypeInfoType(pTypeLib, count, &kind);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hr);
+
+ hr = ITypeLib_GetTypeInfoType(pTypeLib, count, NULL);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ hr = ITypeLib_GetTypeInfoType(pTypeLib, 0, NULL);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, &IID_IFont, &pTypeInfo);
ok_ole_success(hr, ITypeLib_GetTypeInfoOfGuid);
dispparams.cNamedArgs = 0;
hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_PROPERTYGET, &dispparams, NULL, NULL, NULL);
ok(hr == DISP_E_MEMBERNOTFOUND, "ITypeInfo_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
- /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs
+ /* correct member id -- correct flags -- cNamedArgs not bigger than cArgs */
hr = ITypeInfo_Invoke(pTypeInfo, (void *)0xdeadbeef, dispidMember, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
- ok(hr == 0x8002000e, "ITypeInfo_Invoke should have returned 0x8002000e instead of 0x%08x\n", hr); */
+ ok(hr == DISP_E_BADPARAMCOUNT, "ITypeInfo_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
/* correct member id -- wrong flags -- cNamedArgs bigger than cArgs */
dispparams.cNamedArgs = 1;
ITypeLib_Release(pTypeLib);
}
+static int WINAPI int_func( int a0, int a1, int a2, int a3, int a4 )
+{
+ ok( a0 == 1, "wrong arg0 %x\n", a0 );
+ ok( a1 == -1, "wrong arg1 %x\n", a1 );
+ ok( a2 == (0x55550000 | 1234), "wrong arg2 %x\n", a2 );
+ ok( a3 == 0xdeadbeef, "wrong arg3 %x\n", a3 );
+ ok( a4 == 0x555555fd, "wrong arg4 %x\n", a4 );
+ return 4321;
+}
+
+static double WINAPI double_func( double a0, float a1, double a2, int a3 )
+{
+ ok( a0 == 1.2, "wrong arg0 %f\n", (double)a0 );
+ ok( a1 == 3.25, "wrong arg1 %f\n", (double)a1 );
+ ok( a2 == 1.2e12, "wrong arg2 %f\n", (double)a2);
+ ok( a3 == -4433.0, "wrong arg3 %f\n", (double)a3 );
+ return 4321;
+}
+
+static LONGLONG WINAPI longlong_func( LONGLONG a0, CY a1 )
+{
+ ok( a0 == (((ULONGLONG)0xdead << 32) | 0xbeef), "wrong arg0 %08x%08x\n", (DWORD)(a0 >> 32), (DWORD)a0);
+ ok( a1.int64 == ((ULONGLONG)10000 * 12345678), "wrong arg1 %08x%08x\n",
+ (DWORD)(a1.int64 >> 32), (DWORD)a1.int64 );
+ return ((ULONGLONG)4321 << 32) | 8765;
+}
+
+static VARIANT WINAPI variant_func( int a0, BOOL a1, DECIMAL a2, VARIANT a3 )
+{
+ VARIANT var;
+ ok( a0 == 2233, "wrong arg0 %x\n", a0 );
+ ok( a1 == 1 || broken(a1 == 0x55550001), "wrong arg1 %x\n", a1 );
+ V_VT(&var) = VT_LPWSTR;
+ V_UI4(&var) = 0xbabe;
+ ok( a2.Hi32 == 1122, "wrong arg2.Hi32 %x\n", a2.Hi32 );
+ ok( U1(a2).Lo64 == 3344, "wrong arg2.Lo64 %08x%08x\n", (DWORD)(U1(a2).Lo64 >> 32), (DWORD)U1(a2).Lo64 );
+ ok( V_VT(&a3) == VT_EMPTY, "wrong arg3 type %x\n", V_VT(&a3) );
+ ok( V_UI4(&a3) == 0xdeadbeef, "wrong arg3 value %x\n", V_UI4(&a3) );
+ return var;
+}
+
+static int CDECL void_func( int a0, int a1 )
+{
+ if (is_win64) /* VT_EMPTY is passed as real arg on win64 */
+ {
+ ok( a0 == 0x55555555, "wrong arg0 %x\n", a0 );
+ ok( a1 == 1111, "wrong arg1 %x\n", a1 );
+ }
+ else
+ {
+ ok( a0 == 1111, "wrong arg0 %x\n", a0 );
+ ok( a1 == 0, "wrong arg1 %x\n", a1 );
+ }
+ return 12;
+}
+
+static int WINAPI stdcall_func( int a )
+{
+ return 0;
+}
+
+static int WINAPI inst_func( void *inst, int a )
+{
+ ok( (*(void ***)inst)[3] == inst_func, "wrong ptr %p\n", inst );
+ ok( a == 3, "wrong arg %x\n", a );
+ return a * 2;
+}
+
+static const void *vtable[] = { NULL, NULL, NULL, inst_func };
+
+static void test_DispCallFunc(void)
+{
+ const void **inst = vtable;
+ HRESULT res;
+ VARIANT result, args[5];
+ VARIANTARG *pargs[5];
+ VARTYPE types[5];
+ int i;
+
+ for (i = 0; i < 5; i++) pargs[i] = &args[i];
+
+ memset( args, 0x55, sizeof(args) );
+ types[0] = VT_UI4;
+ V_UI4(&args[0]) = 1;
+ types[1] = VT_I4;
+ V_I4(&args[1]) = -1;
+ types[2] = VT_I2;
+ V_I2(&args[2]) = 1234;
+ types[3] = VT_UI4;
+ V_UI4(&args[3]) = 0xdeadbeef;
+ types[4] = VT_UI4;
+ V_I1(&args[4]) = -3;
+ memset( &result, 0xcc, sizeof(result) );
+ res = DispCallFunc( NULL, (ULONG_PTR)int_func, CC_STDCALL, VT_UI4, 5, types, pargs, &result );
+ ok( res == S_OK, "DispCallFunc failed %x\n", res );
+ ok( V_VT(&result) == VT_UI4, "wrong result type %d\n", V_VT(&result) );
+ ok( V_UI4(&result) == 4321, "wrong result %u\n", V_UI4(&result) );
+
+ /* the function checks the argument sizes for stdcall */
+ if (!is_win64) /* no stdcall on 64-bit */
+ {
+ res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 0, types, pargs, &result );
+ ok( res == DISP_E_BADCALLEE, "DispCallFunc wrong error %x\n", res );
+ res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 1, types, pargs, &result );
+ ok( res == S_OK, "DispCallFunc failed %x\n", res );
+ res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 2, types, pargs, &result );
+ ok( res == DISP_E_BADCALLEE, "DispCallFunc wrong error %x\n", res );
+ }
+
+ memset( args, 0x55, sizeof(args) );
+ types[0] = VT_R8;
+ V_R8(&args[0]) = 1.2;
+ types[1] = VT_R4;
+ V_R4(&args[1]) = 3.25;
+ types[2] = VT_R8;
+ V_R8(&args[2]) = 1.2e12;
+ types[3] = VT_I4;
+ V_I4(&args[3]) = -4433;
+ memset( &result, 0xcc, sizeof(result) );
+ res = DispCallFunc( NULL, (ULONG_PTR)double_func, CC_STDCALL, VT_R8, 4, types, pargs, &result );
+ ok( res == S_OK, "DispCallFunc failed %x\n", res );
+ ok( V_VT(&result) == VT_R8, "wrong result type %d\n", V_VT(&result) );
+ ok( V_R8(&result) == 4321, "wrong result %f\n", V_R8(&result) );
+
+ memset( args, 0x55, sizeof(args) );
+ types[0] = VT_I8;
+ V_I8(&args[0]) = ((ULONGLONG)0xdead << 32) | 0xbeef;
+ types[1] = VT_CY;
+ V_CY(&args[1]).int64 = (ULONGLONG)10000 * 12345678;
+ memset( &result, 0xcc, sizeof(result) );
+ res = DispCallFunc( NULL, (ULONG_PTR)longlong_func, CC_STDCALL, VT_I8, 2, types, pargs, &result );
+ ok( res == S_OK || broken(res == E_INVALIDARG), /* longlong not supported on <= win2k */
+ "DispCallFunc failed %x\n", res );
+ if (res == S_OK)
+ {
+ ok( V_VT(&result) == VT_I8, "wrong result type %d\n", V_VT(&result) );
+ ok( V_I8(&result) == (((ULONGLONG)4321 << 32) | 8765), "wrong result %08x%08x\n",
+ (DWORD)(V_I8(&result) >> 32), (DWORD)V_I8(&result) );
+ }
+
+ memset( args, 0x55, sizeof(args) );
+ types[0] = VT_I4;
+ V_I4(&args[0]) = 2233;
+ types[1] = VT_BOOL;
+ V_BOOL(&args[1]) = 1;
+ types[2] = VT_DECIMAL;
+ V_DECIMAL(&args[2]).Hi32 = 1122;
+ U1(V_DECIMAL(&args[2])).Lo64 = 3344;
+ types[3] = VT_VARIANT;
+ V_VT(&args[3]) = VT_EMPTY;
+ V_UI4(&args[3]) = 0xdeadbeef;
+ types[4] = VT_EMPTY;
+ memset( &result, 0xcc, sizeof(result) );
+ res = DispCallFunc( NULL, (ULONG_PTR)variant_func, CC_STDCALL, VT_VARIANT, 5, types, pargs, &result );
+ ok( res == S_OK, "DispCallFunc failed %x\n", res );
+ ok( V_VT(&result) == VT_LPWSTR, "wrong result type %d\n", V_VT(&result) );
+ ok( V_UI4(&result) == 0xbabe, "wrong result %08x\n", V_UI4(&result) );
+
+ memset( args, 0x55, sizeof(args) );
+ types[0] = VT_EMPTY;
+ types[1] = VT_I4;
+ V_I4(&args[1]) = 1111;
+ types[2] = VT_EMPTY;
+ types[3] = VT_I4;
+ V_I4(&args[3]) = 0;
+ types[4] = VT_EMPTY;
+ memset( &result, 0xcc, sizeof(result) );
+ res = DispCallFunc( NULL, (ULONG_PTR)void_func, CC_CDECL, VT_EMPTY, 5, types, pargs, &result );
+ ok( res == S_OK, "DispCallFunc failed %x\n", res );
+ ok( V_VT(&result) == VT_EMPTY, "wrong result type %d\n", V_VT(&result) );
+ if (is_win64)
+ ok( V_UI4(&result) == 12, "wrong result %08x\n", V_UI4(&result) );
+ else
+ ok( V_UI4(&result) == 0xcccccccc, "wrong result %08x\n", V_UI4(&result) );
+
+ memset( args, 0x55, sizeof(args) );
+ types[0] = VT_I4;
+ V_I4(&args[0]) = 3;
+ memset( &result, 0xcc, sizeof(result) );
+ res = DispCallFunc( &inst, 3 * sizeof(void*), CC_STDCALL, VT_I4, 1, types, pargs, &result );
+ ok( res == S_OK, "DispCallFunc failed %x\n", res );
+ ok( V_VT(&result) == VT_I4, "wrong result type %d\n", V_VT(&result) );
+ ok( V_I4(&result) == 6, "wrong result %08x\n", V_I4(&result) );
+}
+
/* RegDeleteTreeW from dlls/advapi32/registry.c */
static LSTATUS myRegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
{
return ret;
}
-static BOOL do_typelib_reg_key(GUID *uid, WORD maj, WORD min, LPCWSTR base, BOOL remove)
+static BOOL do_typelib_reg_key(GUID *uid, WORD maj, WORD min, DWORD arch, LPCWSTR base, BOOL remove)
{
static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
- static const WCHAR formatW[] = {'\\','%','u','.','%','u','\\','0','\\','w','i','n','3','2',0};
+ static const WCHAR formatW[] = {'\\','%','u','.','%','u','\\','0','\\','w','i','n','%','u',0};
static const WCHAR format2W[] = {'%','s','_','%','u','_','%','u','.','d','l','l',0};
WCHAR buf[128];
HKEY hkey;
return TRUE;
}
- wsprintfW(buf + lstrlenW(buf), formatW, maj, min );
+ wsprintfW(buf + lstrlenW(buf), formatW, maj, min, arch);
SetLastError(0xdeadbeef);
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
if (res != ERROR_SUCCESS)
{
- trace("RegCreateKeyExW failed\n");
+ trace("RegCreateKeyExW failed: %u\n", res);
return FALSE;
}
return ret;
}
-static void test_QueryPathOfRegTypeLib(void)
+static void test_QueryPathOfRegTypeLib(DWORD arch)
{
static const struct test_data
{
{ 4, 0, TYPE_E_LIBNOTREGISTERED, { 0 } }
};
static const WCHAR base[] = {'f','a','k','e',0};
+ static const WCHAR wrongW[] = {'w','r','o','n','g',0};
UINT i;
RPC_STATUS status;
GUID uid;
StringFromGUID2(&uid, uid_str, 40);
/*trace("GUID: %s\n", wine_dbgstr_w(uid_str));*/
- if (!do_typelib_reg_key(&uid, 3, 0, base, 0)) return;
- if (!do_typelib_reg_key(&uid, 3, 1, base, 0)) return;
- if (!do_typelib_reg_key(&uid, 3, 37, base, 0)) return;
- if (!do_typelib_reg_key(&uid, 5, 37, base, 0)) return;
+ if (!do_typelib_reg_key(&uid, 3, 0, arch, base, 0)) return;
+ if (!do_typelib_reg_key(&uid, 3, 1, arch, base, 0)) return;
+ if (!do_typelib_reg_key(&uid, 3, 37, arch, base, 0)) return;
+ if (!do_typelib_reg_key(&uid, 5, 37, arch, base, 0)) return;
+ if (arch == 64 && !do_typelib_reg_key(&uid, 5, 37, 32, wrongW, 0)) return;
for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
{
}
}
- do_typelib_reg_key(&uid, 0, 0, NULL, 1);
+ do_typelib_reg_key(&uid, 0, 0, arch, NULL, 1);
}
static void test_inheritance(void)
hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
ok(hr == S_OK, "hr %08x\n", hr);
hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
+ ok(hr == S_OK, "got %08x\n", hr);
ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
ITypeInfo_Release(pTI_p);
hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
ok(hr == S_OK, "hr %08x\n", hr);
hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
+ ok(hr == S_OK, "got %08x\n", hr);
ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
ITypeInfo_Release(pTI_p);
hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
ok(hr == S_OK, "hr %08x\n", hr);
hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
+ ok(hr == S_OK, "got %08x\n", hr);
ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
ITypeInfo_Release(pTI_p);
hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
ok(hr == S_OK, "hr %08x\n", hr);
hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
+ ok(hr == S_OK, "got %08x\n", hr);
ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
ITypeInfo_Release(pTI_p);
hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
ok(hr == S_OK, "hr %08x\n", hr);
hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
+ ok(hr == S_OK, "got %08x\n", hr);
ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
ITypeInfo_Release(pTI_p);
hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
ok(hr == S_OK, "hr %08x\n", hr);
hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
+ ok(hr == S_OK, "got %08x\n", hr);
ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1);
ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
ITypeInfo_Release(pTI_p);
href = U(pFD->lprgelemdescParam[0].tdesc).hreftype;
ok((href & 0xff000000) == 0x04000000, "href 0x%08x\n", href);
hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
- ok(SUCCEEDED(hr), "hr %08x\n", hr);
+ ok(hr == S_OK, "hr %08x\n", hr);
if (SUCCEEDED(hr)) ITypeInfo_Release(pTI_p);
ITypeInfo_ReleaseFuncDesc(pTI, pFD);
}
static OLECHAR dualW[] = {'d','u','a','l',0};
static OLECHAR coclassW[] = {'c','o','c','l','a','s','s',0};
static WCHAR defaultW[] = {'d','e','f','a','u','l','t',0x3213,0};
+ static WCHAR defaultQW[] = {'d','e','f','a','u','l','t','?',0};
static OLECHAR func1W[] = {'f','u','n','c','1',0};
static OLECHAR func2W[] = {'f','u','n','c','2',0};
static OLECHAR prop1W[] = {'P','r','o','p','1',0};
static OLECHAR param1W[] = {'p','a','r','a','m','1',0};
static OLECHAR param2W[] = {'p','a','r','a','m','2',0};
+ static OLECHAR asdfW[] = {'A','s','d','f',0};
static OLECHAR *names1[] = {func1W, param1W, param2W};
static OLECHAR *names2[] = {func2W, param1W, param2W};
static OLECHAR *propname[] = {prop1W, param1W};
static const GUID custguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x70}};
+ static const GUID bogusguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x71}};
char filename[MAX_PATH];
WCHAR filenameW[MAX_PATH];
ITypeLib *tl, *stdole;
ITypeInfo *interface1, *interface2, *dual, *unknown, *dispatch, *ti;
ITypeInfo2 *ti2;
- FUNCDESC funcdesc;
- ELEMDESC elemdesc[5];
+ FUNCDESC funcdesc, *pfuncdesc;
+ ELEMDESC elemdesc[5], *edesc;
PARAMDESCEX paramdescex;
TYPEDESC typedesc1, typedesc2;
TYPEATTR *typeattr;
int impltypeflags;
VARIANT cust_data;
HRESULT hres;
+ TYPEKIND kind;
trace("CreateTypeLib tests\n");
hres = CreateTypeLib2(SYS_WIN32, filenameW, &createtl);
ok(hres == S_OK, "got %08x\n", hres);
- hres = ICreateTypeLib_QueryInterface(createtl, &IID_ITypeLib, (void**)&tl);
+ hres = ICreateTypeLib2_QueryInterface(createtl, &IID_ITypeLib, (void**)&tl);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeLib_GetTypeInfo(tl, 0, NULL);
+ ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
+
+ hres = ITypeLib_GetTypeInfoType(tl, 0, &kind);
+ ok(hres == TYPE_E_ELEMENTNOTFOUND, "got 0x%08x\n", hres);
+
+ hres = ITypeLib_GetTypeInfoType(tl, 0, NULL);
+ ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
+
+ hres = ITypeLib_GetTypeInfoType(tl, 0, NULL);
+ ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
+
+ hres = ITypeLib_GetLibAttr(tl, NULL);
+ ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
hres = ITypeLib_GetLibAttr(tl, &libattr);
ok(hres == S_OK, "got %08x\n", hres);
hres = ITypeLib_GetDocumentation(tl, 0, &name, NULL, NULL, NULL);
ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
- hres = ICreateTypeLib_SetName(createtl, typelibW);
+ hres = ICreateTypeLib2_SetName(createtl, typelibW);
ok(hres == S_OK, "got %08x\n", hres);
- hres = ICreateTypeLib_SetHelpFileName(createtl, helpfileW);
+ hres = ICreateTypeLib2_SetHelpFileName(createtl, helpfileW);
ok(hres == S_OK, "got %08x\n", hres);
hres = ITypeLib_GetDocumentation(tl, -1, NULL, NULL, NULL, NULL);
SysFreeString(name);
SysFreeString(helpfile);
- hres = ICreateTypeLib_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
+ /* invalid parameters */
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, NULL, TKIND_INTERFACE, &createti);
+ ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, NULL);
+ ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, NULL, TKIND_INTERFACE, NULL);
+ ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&interface1);
hres = ITypeInfo_GetRefTypeOfImplType(interface1, -1, &hreftype);
ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+ ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo2, (void**)&ti2);
+
memset(&funcdesc, 0, sizeof(FUNCDESC));
funcdesc.funckind = FUNC_PUREVIRTUAL;
funcdesc.invkind = INVOKE_PROPERTYGET;
hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 0, NULL);
+ ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
+ hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
+ ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+
+ hres = ITypeInfo2_GetFuncDesc(ti2, 0, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_PROPERTYGET, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 12 ||
+ broken(pfuncdesc->oVft == 24) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_BSTR, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
hres = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0xabcdefab);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_SetFuncHelpContext(createti, 1, 0xabcdefab);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, propname, 0);
+ ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+
+ hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, NULL, 1);
+ ok(hres == E_INVALIDARG, "got %08x\n", hres);
+
hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, propname, 1);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 1, propname, 2);
ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_PROPERTYPUT, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 16 ||
+ broken(pfuncdesc->oVft == 28) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
+ ok(U(*edesc).idldesc.wIDLFlags == IDLFLAG_FIN, "got: %x\n", U(*edesc).idldesc.wIDLFlags);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
funcdesc.invkind = INVOKE_PROPERTYPUTREF;
hres = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc);
hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 1, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 1, "got %d\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam == NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 0, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 16 ||
+ broken(pfuncdesc->oVft == 28), /* xp64 */
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
funcdesc.memid = MEMBERID_NIL;
hres = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 4, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x60010004, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 28 ||
+ broken(pfuncdesc->oVft == 40) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_PTR, "got: %d\n", edesc->tdesc.vt);
+ ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
+ ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
+ ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
+ ok(U(edesc->tdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
U(elemdesc[0].tdesc).lptdesc = &typedesc2;
typedesc2.vt = VT_PTR;
U(typedesc2).lptdesc = &typedesc1;
hres = ICreateTypeInfo_AddFuncDesc(createti, 4, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 4, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x60010007, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 28 ||
+ broken(pfuncdesc->oVft == 40) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_PTR, "got: %d\n", edesc->tdesc.vt);
+ ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
+ ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
+ ok(U(edesc->tdesc).lptdesc != NULL, "got: %p\n", U(edesc->tdesc).lptdesc);
+ ok(U(edesc->tdesc).lptdesc->vt == VT_PTR, "got: %d\n", U(edesc->tdesc).lptdesc->vt);
+ ok(U(*U(edesc->tdesc).lptdesc).lptdesc != NULL, "got: %p\n", U(*U(edesc->tdesc).lptdesc).lptdesc);
+ ok(U(*U(edesc->tdesc).lptdesc).lptdesc->vt == VT_BSTR, "got: %d\n", U(*U(edesc->tdesc).lptdesc).lptdesc->vt);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
elemdesc[0].tdesc.vt = VT_INT;
U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
U(elemdesc[0]).paramdesc.pparamdescex = ¶mdescex;
hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x60010003, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 24 ||
+ broken(pfuncdesc->oVft == 36) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
+ ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
+ ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
+ ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
+ U(*edesc).paramdesc.pparamdescex->cBytes);
+ ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_I4, "got: %d\n",
+ V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
+ ok(V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0x123, "got: 0x%x\n",
+ V_I4(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
U(elemdesc[0]).idldesc.dwReserved = 0;
U(elemdesc[0]).idldesc.wIDLFlags = IDLFLAG_FIN;
elemdesc[1].tdesc.vt = VT_UI2;
hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x60010009, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 24 ||
+ broken(pfuncdesc->oVft == 36) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_INT, "got: %d\n", edesc->tdesc.vt);
+ ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FIN, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
+ ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
+
+ edesc = pfuncdesc->lprgelemdescParam + 1;
+ ok(edesc->tdesc.vt == VT_UI2, "got: %d\n", edesc->tdesc.vt);
+ ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
+ ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
+ ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
+ U(*edesc).paramdesc.pparamdescex->cBytes);
+ ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_UI2, "got: %d\n",
+ V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
+ ok(V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == 0xFFFF, "got: 0x%x\n",
+ V_UI2(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
U(elemdesc[0]).paramdesc.wParamFlags = PARAMFLAG_FHASDEFAULT;
U(elemdesc[0]).paramdesc.pparamdescex = ¶mdescex;
elemdesc[1].tdesc.vt = VT_INT;
V_BSTR(¶mdescex.varDefaultValue) = SysAllocString(defaultW);
hres = ICreateTypeInfo_AddFuncDesc(createti, 3, &funcdesc);
ok(hres == S_OK, "got %08x\n", hres);
+ SysFreeString(V_BSTR(¶mdescex.varDefaultValue));
+
+ hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x6001000b, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 2, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 24 ||
+ broken(pfuncdesc->oVft == 36) /* xp64 */,
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
+ ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
+ ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
+ ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
+ U(*edesc).paramdesc.pparamdescex->cBytes);
+ ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
+ V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
+ ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
+ "got: %s\n",
+ wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
+
+ edesc = pfuncdesc->lprgelemdescParam + 1;
+ ok(edesc->tdesc.vt == VT_BSTR, "got: %d\n", edesc->tdesc.vt);
+ ok(U(*edesc).paramdesc.wParamFlags == PARAMFLAG_FHASDEFAULT, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
+ ok(U(*edesc).paramdesc.pparamdescex != NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
+ ok(U(*edesc).paramdesc.pparamdescex->cBytes == sizeof(PARAMDESCEX), "got: %d\n",
+ U(*edesc).paramdesc.pparamdescex->cBytes);
+ ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
+ V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
+ ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
+ "got: %s\n",
+ wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
+
+ elemdesc[0].tdesc.vt = VT_USERDEFINED;
+ U(elemdesc[0].tdesc).hreftype = hreftype;
+ U(elemdesc[0]).paramdesc.pparamdescex = NULL;
+ U(elemdesc[0]).paramdesc.wParamFlags = 0;
+
+ funcdesc.lprgelemdescParam = elemdesc;
+ funcdesc.invkind = INVOKE_FUNC;
+ funcdesc.cParams = 1;
+ funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
+
+ hres = ICreateTypeInfo_AddFuncDesc(createti, 5, &funcdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ hres = ITypeInfo2_GetFuncDesc(ti2, 5, &pfuncdesc);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(pfuncdesc->memid == 0x60010005, "got %x\n", pfuncdesc->memid);
+ ok(pfuncdesc->lprgscode == NULL, "got %p\n", pfuncdesc->lprgscode);
+ ok(pfuncdesc->lprgelemdescParam != NULL, "got %p\n", pfuncdesc->lprgelemdescParam);
+ ok(pfuncdesc->funckind == FUNC_PUREVIRTUAL, "got 0x%x\n", pfuncdesc->funckind);
+ ok(pfuncdesc->invkind == INVOKE_FUNC, "got 0x%x\n", pfuncdesc->invkind);
+ ok(pfuncdesc->callconv == CC_STDCALL, "got 0x%x\n", pfuncdesc->callconv);
+ ok(pfuncdesc->cParams == 1, "got %d\n", pfuncdesc->cParams);
+ ok(pfuncdesc->cParamsOpt == 0, "got %d\n", pfuncdesc->cParamsOpt);
+ todo_wine ok(pfuncdesc->oVft == 32 ||
+ broken(pfuncdesc->oVft == 44), /* xp64 */
+ "got %d\n", pfuncdesc->oVft);
+ ok(pfuncdesc->cScodes == 0, "got %d\n", pfuncdesc->cScodes);
+ ok(pfuncdesc->elemdescFunc.tdesc.vt == VT_VOID, "got %d\n", pfuncdesc->elemdescFunc.tdesc.vt);
+ ok(pfuncdesc->wFuncFlags == 0, "got 0x%x\n", pfuncdesc->wFuncFlags);
+
+ edesc = pfuncdesc->lprgelemdescParam;
+ ok(U(*edesc).paramdesc.pparamdescex == NULL, "got: %p\n", U(*edesc).paramdesc.pparamdescex);
+ ok(U(*edesc).paramdesc.wParamFlags == 0, "got: 0x%x\n", U(*edesc).paramdesc.wParamFlags);
+ ok(edesc->tdesc.vt == VT_USERDEFINED, "got: %d\n", edesc->tdesc.vt);
+ ok(U(edesc->tdesc).hreftype == hreftype, "got: 0x%x\n", U(edesc->tdesc).hreftype);
+
+ ITypeInfo2_ReleaseFuncDesc(ti2, pfuncdesc);
hres = ITypeInfo_GetDocumentation(interface1, 0, &name, &docstring, &helpcontext, &helpfile);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_SetFuncAndParamNames(createti, 3, names1, 3);
ok(hres == TYPE_E_AMBIGUOUSNAME, "got %08x\n", hres);
+ ITypeInfo2_Release(ti2);
ICreateTypeInfo_Release(createti);
- hres = ICreateTypeLib_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
ok(hres == TYPE_E_NAMECONFLICT, "got %08x\n", hres);
- hres = ICreateTypeLib_CreateTypeInfo(createtl, interface2W, TKIND_INTERFACE, &createti);
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface2W, TKIND_INTERFACE, &createti);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&interface2);
VariantInit(&cust_data);
- hres = ICreateTypeLib_CreateTypeInfo(createtl, interface3W, TKIND_INTERFACE, &createti);
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, interface3W, TKIND_INTERFACE, &createti);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_QueryInterface(createti, &IID_ICreateTypeInfo2, (void**)&createti2);
ok(hres == S_OK, "got %08x\n", hres);
hres = ITypeInfo2_GetCustData(ti2, NULL, NULL);
- todo_wine
ok(hres == E_INVALIDARG, "got %08x\n", hres);
hres = ITypeInfo2_GetCustData(ti2, &custguid, NULL);
- todo_wine
ok(hres == E_INVALIDARG, "got %08x\n", hres);
hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
- todo_wine
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo2_SetCustData(createti2, NULL, NULL);
V_VT(&cust_data) = VT_EMPTY;
hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
- todo_wine
ok(hres == S_OK, "got %08x\n", hres);
- todo_wine
ok(V_VT(&cust_data) == VT_UI4, "got %d\n", V_VT(&cust_data));
- todo_wine
ok(V_I4(&cust_data) == 0xdeadbeef, "got 0x%08x\n", V_I4(&cust_data));
V_VT(&cust_data) = VT_UI4;
V_VT(&cust_data) = VT_EMPTY;
hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
- todo_wine
ok(hres == S_OK, "got %08x\n", hres);
- todo_wine
ok(V_VT(&cust_data) == VT_UI4, "got %d\n", V_VT(&cust_data));
- todo_wine
ok(V_I4(&cust_data) == 12345678, "got 0x%08x\n", V_I4(&cust_data));
+ V_VT(&cust_data) = VT_BSTR;
+ V_BSTR(&cust_data) = SysAllocString(asdfW);
+
+ hres = ICreateTypeInfo2_SetCustData(createti2, &custguid, &cust_data);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ SysFreeString(V_BSTR(&cust_data));
+ V_I4(&cust_data) = 0;
+ V_VT(&cust_data) = VT_EMPTY;
+
+ hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(V_VT(&cust_data) == VT_BSTR, "got %d\n", V_VT(&cust_data));
+ ok(!lstrcmpW(V_BSTR(&cust_data), asdfW), "got %s\n", wine_dbgstr_w(V_BSTR(&cust_data)));
+ SysFreeString(V_BSTR(&cust_data));
+
+ V_VT(&cust_data) = VT_UI4;
+ V_UI4(&cust_data) = 17;
+
+ hres = ITypeInfo2_GetCustData(ti2, &bogusguid, &cust_data);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ ok(V_VT(&cust_data) == VT_EMPTY, "got: %d\n", V_VT(&cust_data));
+
ITypeInfo2_Release(ti2);
ICreateTypeInfo2_Release(createti2);
ICreateTypeInfo_Release(createti);
- hres = ICreateTypeLib_CreateTypeInfo(createtl, coclassW, TKIND_COCLASS, &createti);
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, coclassW, TKIND_COCLASS, &createti);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_AddRefTypeInfo(createti, interface1, &hreftype);
ICreateTypeInfo_Release(createti);
- hres = ICreateTypeLib_CreateTypeInfo(createtl, dualW, TKIND_INTERFACE, &createti);
+ hres = ICreateTypeLib2_CreateTypeInfo(createtl, dualW, TKIND_INTERFACE, &createti);
ok(hres == S_OK, "got %08x\n", hres);
hres = ICreateTypeInfo_SetTypeFlags(createti, TYPEFLAG_FDUAL);
ok(hres == S_OK, "got %08x\n", hres);
ok(typeattr->cbSizeInstance == 4, "cbSizeInstance = %d\n", typeattr->cbSizeInstance);
ok(typeattr->typekind == 3, "typekind = %d\n", typeattr->typekind);
- ok(typeattr->cFuncs == 11, "cFuncs = %d\n", typeattr->cFuncs);
+ ok(typeattr->cFuncs == 12, "cFuncs = %d\n", typeattr->cFuncs);
ok(typeattr->cVars == 0, "cVars = %d\n", typeattr->cVars);
ok(typeattr->cImplTypes == 1, "cImplTypes = %d\n", typeattr->cImplTypes);
- ok(typeattr->cbSizeVft == 56 || broken(typeattr->cbSizeVft == 3 * sizeof(void *) + 44), /* xp64 */
+ ok(typeattr->cbSizeVft == 60 || broken(typeattr->cbSizeVft == 3 * sizeof(void *) + 48), /* xp64 */
"cbSizeVft = %d\n", typeattr->cbSizeVft);
ok(typeattr->cbAlignment == 4, "cbAlignment = %d\n", typeattr->cbAlignment);
ok(typeattr->wTypeFlags == 0, "wTypeFlags = %d\n", typeattr->wTypeFlags);
ok(hr == S_OK, "got %08x\n", hr);
hr = ICreateTypeLib2_SaveAllChanges(tl);
+ ok(hr == S_OK, "got %08x\n", hr);
+
ICreateTypeLib2_Release(tl);
file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
hr = LoadTypeLibEx(filename, REGKIND_NONE, &typelib);
- ok(SUCCEEDED(hr), "got %08x\n", hr);
+ ok(hr == S_OK, "got %08x\n", hr);
if (system_registration)
hr = RegisterTypeLib(typelib, filename, NULL);
DeleteFileA(filenameA);
return;
}
- ok(SUCCEEDED(hr), "got %08x\n", hr);
+ ok(hr == S_OK, "got %08x\n", hr);
count = ITypeLib_GetTypeInfoCount(typelib);
ok(count == 11, "got %d\n", count);
TYPEATTR *attr;
hr = ITypeLib_GetTypeInfo(typelib, i, &typeinfo);
- ok(SUCCEEDED(hr), "got %08x\n", hr);
+ ok(hr == S_OK, "got %08x\n", hr);
hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
- ok(SUCCEEDED(hr), "got %08x\n", hr);
+ ok(hr == S_OK, "got %08x\n", hr);
ok(attr->typekind == attrs[i].kind, "%d: got kind %d\n", i, attr->typekind);
ok(attr->wTypeFlags == attrs[i].flags, "%d: got flags %04x\n", i, attr->wTypeFlags);
TYPEATTR *dual_attr;
hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, -1, &reftype);
- ok(SUCCEEDED(hr), "got %08x\n", hr);
+ ok(hr == S_OK, "got %08x\n", hr);
hr = ITypeInfo_GetRefTypeInfo(typeinfo, reftype, &dual_info);
- ok(SUCCEEDED(hr), "got %08x\n", hr);
+ ok(hr == S_OK, "got %08x\n", hr);
hr = ITypeInfo_GetTypeAttr(dual_info, &dual_attr);
- ok(SUCCEEDED(hr), "got %08x\n", hr);
+ ok(hr == S_OK, "got %08x\n", hr);
ok(dual_attr->typekind == TKIND_INTERFACE, "%d: got kind %d\n", i, dual_attr->typekind);
ok(dual_attr->wTypeFlags == (TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDUAL), "%d: got flags %04x\n", i, dual_attr->wTypeFlags);
}
if (system_registration)
- hr = UnRegisterTypeLib(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32);
+ hr = UnRegisterTypeLib(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, is_win64 ? SYS_WIN64 : SYS_WIN32);
else
- hr = pUnRegisterTypeLibForUser(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32);
- ok(SUCCEEDED(hr), "got %08x\n", hr);
+ hr = pUnRegisterTypeLibForUser(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, is_win64 ? SYS_WIN64 : SYS_WIN32);
+ ok(hr == S_OK, "got %08x\n", hr);
ITypeLib_Release(typelib);
DeleteFileA( filenameA );
}
+static void test_LoadTypeLib(void)
+{
+ ITypeLib *tl;
+ HRESULT hres;
+
+ static const WCHAR kernel32_dllW[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
+
+ hres = LoadTypeLib(kernel32_dllW, &tl);
+ ok(hres == TYPE_E_CANTLOADLIBRARY, "LoadTypeLib returned: %08x, expected TYPE_E_CANTLOADLIBRARY\n", hres);
+}
+
+static void test_SetVarHelpContext(void)
+{
+ static OLECHAR nameW[] = {'n','a','m','e',0};
+ CHAR filenameA[MAX_PATH];
+ WCHAR filenameW[MAX_PATH];
+ ICreateTypeLib2 *ctl;
+ ICreateTypeInfo *cti;
+ VARDESC desc;
+ HRESULT hr;
+ VARIANT v;
+
+ GetTempFileNameA(".", "tlb", 0, filenameA);
+ MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
+
+ hr = CreateTypeLib2(SYS_WIN32, filenameW, &ctl);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ hr = ICreateTypeLib2_CreateTypeInfo(ctl, nameW, TKIND_ENUM, &cti);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ hr = ICreateTypeInfo_SetVarHelpContext(cti, 0, 0);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
+
+ memset(&desc, 0, sizeof(desc));
+ desc.elemdescVar.tdesc.vt = VT_INT;
+ desc.varkind = VAR_CONST;
+
+ V_VT(&v) = VT_INT;
+ V_INT(&v) = 1;
+ U(desc).lpvarValue = &v;
+ hr = ICreateTypeInfo_AddVarDesc(cti, 0, &desc);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ hr = ICreateTypeInfo_SetVarHelpContext(cti, 0, 0);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ /* another time */
+ hr = ICreateTypeInfo_SetVarHelpContext(cti, 0, 1);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ /* wrong index now */
+ hr = ICreateTypeInfo_SetVarHelpContext(cti, 1, 0);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
+
+ ICreateTypeInfo_Release(cti);
+ ICreateTypeLib2_Release(ctl);
+ DeleteFileA(filenameA);
+}
+
+static void test_SetFuncAndParamNames(void)
+{
+ static OLECHAR nameW[] = {'n','a','m','e',0};
+ static OLECHAR prop[] = {'p','r','o','p',0};
+ static OLECHAR *propW[] = {prop};
+ CHAR filenameA[MAX_PATH];
+ WCHAR filenameW[MAX_PATH];
+ ICreateTypeLib2 *ctl;
+ ICreateTypeInfo *cti;
+ FUNCDESC funcdesc;
+ ELEMDESC edesc;
+ HRESULT hr;
+
+ GetTempFileNameA(".", "tlb", 0, filenameA);
+ MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
+
+ hr = CreateTypeLib2(SYS_WIN32, filenameW, &ctl);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ hr = ICreateTypeLib2_CreateTypeInfo(ctl, nameW, TKIND_DISPATCH, &cti);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ /* get method */
+ memset(&funcdesc, 0, sizeof(FUNCDESC));
+ funcdesc.funckind = FUNC_DISPATCH;
+ funcdesc.callconv = CC_STDCALL;
+ funcdesc.elemdescFunc.tdesc.vt = VT_VOID;
+ funcdesc.wFuncFlags = FUNCFLAG_FBINDABLE;
+
+ /* put method */
+ memset(&edesc, 0, sizeof(edesc));
+ edesc.tdesc.vt = VT_BSTR;
+ U(edesc).idldesc.dwReserved = 0;
+ U(edesc).idldesc.wIDLFlags = IDLFLAG_FIN;
+
+ funcdesc.lprgelemdescParam = &edesc;
+ funcdesc.invkind = INVOKE_PROPERTYPUT;
+ funcdesc.cParams = 1;
+
+ hr = ICreateTypeInfo_AddFuncDesc(cti, 0, &funcdesc);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* setter name */
+ hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 0, propW, 1);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* putref method */
+ funcdesc.invkind = INVOKE_PROPERTYPUTREF;
+ hr = ICreateTypeInfo_AddFuncDesc(cti, 1, &funcdesc);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* putref name */
+ hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 1, propW, 1);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ funcdesc.invkind = INVOKE_PROPERTYGET;
+ funcdesc.cParams = 0;
+ hr = ICreateTypeInfo_AddFuncDesc(cti, 2, &funcdesc);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* getter name */
+ hr = ICreateTypeInfo_SetFuncAndParamNames(cti, 2, propW, 1);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ ICreateTypeInfo_Release(cti);
+ ICreateTypeLib2_Release(ctl);
+ DeleteFileA(filenameA);
+}
+
+static void test_SetVarDocString(void)
+{
+ static OLECHAR nameW[] = {'n','a','m','e',0};
+ static OLECHAR doc1W[] = {'d','o','c','1',0};
+ static OLECHAR doc2W[] = {'d','o','c','2',0};
+ CHAR filenameA[MAX_PATH];
+ WCHAR filenameW[MAX_PATH];
+ ICreateTypeLib2 *ctl;
+ ICreateTypeInfo *cti;
+ VARDESC desc;
+ HRESULT hr;
+ VARIANT v;
+
+ GetTempFileNameA(".", "tlb", 0, filenameA);
+ MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);
+
+ hr = CreateTypeLib2(SYS_WIN32, filenameW, &ctl);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ hr = ICreateTypeLib2_CreateTypeInfo(ctl, nameW, TKIND_ENUM, &cti);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ hr = ICreateTypeInfo_SetVarDocString(cti, 0, doc1W);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
+
+ hr = ICreateTypeInfo_SetVarDocString(cti, 0, NULL);
+ ok(hr == E_INVALIDARG, "got %08x\n", hr);
+
+ memset(&desc, 0, sizeof(desc));
+ desc.elemdescVar.tdesc.vt = VT_INT;
+ desc.varkind = VAR_CONST;
+
+ V_VT(&v) = VT_INT;
+ V_INT(&v) = 1;
+ U(desc).lpvarValue = &v;
+ hr = ICreateTypeInfo_AddVarDesc(cti, 0, &desc);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ hr = ICreateTypeInfo_SetVarDocString(cti, 0, NULL);
+ ok(hr == E_INVALIDARG, "got %08x\n", hr);
+
+ hr = ICreateTypeInfo_SetVarDocString(cti, 0, doc1W);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ /* already set */
+ hr = ICreateTypeInfo_SetVarDocString(cti, 0, doc2W);
+ ok(hr == S_OK, "got %08x\n", hr);
+
+ /* wrong index now */
+ hr = ICreateTypeInfo_SetVarDocString(cti, 1, doc1W);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hr);
+
+ ICreateTypeInfo_Release(cti);
+ ICreateTypeLib2_Release(ctl);
+ DeleteFileA(filenameA);
+}
+
+static void test_FindName(void)
+{
+ static const WCHAR invalidW[] = {'i','n','v','a','l','i','d',0};
+ WCHAR buffW[100];
+ MEMBERID memid;
+ ITypeInfo *ti;
+ ITypeLib *tl;
+ HRESULT hr;
+ UINT16 c;
+
+ hr = LoadTypeLib(wszStdOle2, &tl);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = ITypeLib_FindName(tl, NULL, 0, NULL, NULL, NULL);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ lstrcpyW(buffW, wszGUID);
+ hr = ITypeLib_FindName(tl, buffW, 0, NULL, NULL, NULL);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ c = 0;
+ ti = (void*)0xdeadbeef;
+ hr = ITypeLib_FindName(tl, buffW, 0, &ti, NULL, &c);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+ ok(c == 0, "got %d\n", c);
+ ok(ti == (void*)0xdeadbeef, "got %p\n", ti);
+
+ c = 1;
+ ti = (void*)0xdeadbeef;
+ hr = ITypeLib_FindName(tl, buffW, 0, &ti, NULL, &c);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+ ok(c == 1, "got %d\n", c);
+ ok(ti == (void*)0xdeadbeef, "got %p\n", ti);
+
+ c = 1;
+ memid = 0;
+ ti = (void*)0xdeadbeef;
+ hr = ITypeLib_FindName(tl, buffW, 0, &ti, &memid, &c);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+todo_wine
+ ok(memid == -1, "got %d\n", memid);
+ ok(!lstrcmpW(buffW, wszGUID), "got %s\n", wine_dbgstr_w(buffW));
+ ok(c == 1, "got %d\n", c);
+ ITypeInfo_Release(ti);
+
+ c = 1;
+ memid = 0;
+ lstrcpyW(buffW, wszguid);
+ ti = (void*)0xdeadbeef;
+ hr = ITypeLib_FindName(tl, buffW, 0, &ti, &memid, &c);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+todo_wine {
+ ok(memid == -1, "got %d\n", memid);
+ ok(!lstrcmpW(buffW, wszGUID), "got %s\n", wine_dbgstr_w(buffW));
+ ok(c == 1, "got %d\n", c);
+}
+ if (c == 1)
+ ITypeInfo_Release(ti);
+
+ c = 1;
+ memid = -1;
+ lstrcpyW(buffW, invalidW);
+ ti = (void*)0xdeadbeef;
+ hr = ITypeLib_FindName(tl, buffW, 0, &ti, &memid, &c);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(memid == -1, "got %d\n", memid);
+ ok(!lstrcmpW(buffW, invalidW), "got %s\n", wine_dbgstr_w(buffW));
+ ok(c == 0, "got %d\n", c);
+ ok(ti == (void*)0xdeadbeef, "got %p\n", ti);
+
+ ITypeLib_Release(tl);
+}
+
START_TEST(typelib)
{
const char *filename;
test_TypeComp();
test_CreateDispTypeInfo();
test_TypeInfo();
- test_QueryPathOfRegTypeLib();
+ test_DispCallFunc();
+ test_QueryPathOfRegTypeLib(32);
+ if(sizeof(void*) == 8)
+ test_QueryPathOfRegTypeLib(64);
test_inheritance();
test_CreateTypeLib();
+ test_SetVarHelpContext();
+ test_SetFuncAndParamNames();
+ test_SetVarDocString();
+ test_FindName();
if ((filename = create_test_typelib(2)))
{
test_register_typelib(TRUE);
test_register_typelib(FALSE);
test_create_typelibs();
-
+ test_LoadTypeLib();
}
*/
#define COBJMACROS
+#define CONST_VTABLE
#include <stdarg.h>
# define V_U2(A) (*(A))
#endif
-#define LPSAFEARRAY_UNMARSHAL_WORKS 1
-#define BSTR_UNMARSHAL_WORKS 1
-#define VARIANT_UNMARSHAL_WORKS 1
+static HRESULT (WINAPI *pSafeArrayGetIID)(SAFEARRAY*,GUID*);
+static HRESULT (WINAPI *pSafeArrayGetVartype)(SAFEARRAY*,VARTYPE*);
+static HRESULT (WINAPI *pVarBstrCmp)(BSTR,BSTR,LCID,ULONG);
static inline SF_TYPE get_union_type(SAFEARRAY *psa)
{
VARTYPE vt;
HRESULT hr;
- hr = SafeArrayGetVartype(psa, &vt);
+ hr = pSafeArrayGetVartype(psa, &vt);
if (FAILED(hr))
{
if(psa->fFeatures & FADF_VARIANT) return SF_VARIANT;
static void check_safearray(void *buffer, LPSAFEARRAY lpsa)
{
unsigned char *wiresa = buffer;
+ const SAFEARRAYBOUND *bounds;
VARTYPE vt;
SF_TYPE sftype;
ULONG cell_count;
+ int i;
if(!lpsa)
{
return;
}
- if(FAILED(SafeArrayGetVartype(lpsa, &vt)))
+ if (!pSafeArrayGetVartype || !pSafeArrayGetIID)
+ return;
+
+ if(FAILED(pSafeArrayGetVartype(lpsa, &vt)))
vt = 0;
sftype = get_union_type(lpsa);
if(sftype == SF_HAVEIID)
{
GUID guid;
- SafeArrayGetIID(lpsa, &guid);
+ pSafeArrayGetIID(lpsa, &guid);
ok(IsEqualGUID(&guid, wiresa), "guid mismatch\n");
wiresa += sizeof(GUID);
}
- ok(!memcmp(wiresa, lpsa->rgsabound, sizeof(lpsa->rgsabound[0]) * lpsa->cDims), "bounds mismatch\n");
+
+ /* bounds are marshaled in natural dimensions order */
+ bounds = (SAFEARRAYBOUND*)wiresa;
+ for(i=0; i<lpsa->cDims; i++)
+ {
+ ok(memcmp(bounds, &lpsa->rgsabound[lpsa->cDims-i-1], sizeof(SAFEARRAYBOUND)) == 0,
+ "bounds mismatch for dimension %d, got (%d,%d), expected (%d,%d)\n", i,
+ bounds->lLbound, bounds->cElements, lpsa->rgsabound[lpsa->cDims-i-1].lLbound,
+ lpsa->rgsabound[lpsa->cDims-i-1].cElements);
+ bounds++;
+ }
+
wiresa += sizeof(lpsa->rgsabound[0]) * lpsa->cDims;
ok(*(DWORD *)wiresa == cell_count, "wiresa + 0x28 should be %u instead of %u\n", cell_count, *(DWORD*)wiresa);
ULONG size, expected;
LPSAFEARRAY lpsa;
LPSAFEARRAY lpsa2 = NULL;
- SAFEARRAYBOUND sab;
+ SAFEARRAYBOUND sab[2];
RPC_MESSAGE rpc_msg;
MIDL_STUB_MESSAGE stub_msg;
USER_MARSHAL_CB umcb;
HRESULT hr;
- VARTYPE vt;
+ VARTYPE vt, vt2;
OLECHAR *values[10];
int expected_bstr_size;
int i;
LONG indices[1];
- sab.lLbound = 5;
- sab.cElements = 10;
+ sab[0].lLbound = 5;
+ sab[0].cElements = 10;
- lpsa = SafeArrayCreate(VT_I2, 1, &sab);
+ lpsa = SafeArrayCreate(VT_I2, 1, sab);
*(DWORD *)lpsa->pvData = 0xcafebabe;
lpsa->cLocks = 7;
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
expected = (44 + 1 + sizeof(ULONG) - 1) & ~(sizeof(ULONG) - 1);
- expected += sab.cElements * sizeof(USHORT);
+ expected += sab[0].cElements * sizeof(USHORT);
+ ok(size == expected || size == expected + 12, /* win64 */
+ "size should be %u bytes, not %u\n", expected, size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
+ expected = 44 + sab[0].cElements * sizeof(USHORT);
+ ok(size == expected || size == expected + 12, /* win64 */
+ "size should be %u bytes, not %u\n", expected, size);
+ buffer = HeapAlloc(GetProcessHeap(), 0, size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
+ ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
+ ok(lpsa->cLocks == 7, "got lock count %u\n", lpsa->cLocks);
+
+ check_safearray(buffer, lpsa);
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
+ ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal\n");
+ if (pSafeArrayGetVartype)
+ {
+ pSafeArrayGetVartype(lpsa, &vt);
+ pSafeArrayGetVartype(lpsa2, &vt2);
+ ok(vt == vt2, "vts differ %x %x\n", vt, vt2);
+ }
+ ok(lpsa2->cLocks == 0, "got lock count %u, expected 0\n", lpsa2->cLocks);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
+ HeapFree(GetProcessHeap(), 0, buffer);
+ lpsa->cLocks = 0;
+ hr = SafeArrayDestroy(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* use two dimensions */
+ sab[0].lLbound = 5;
+ sab[0].cElements = 10;
+ sab[1].lLbound = 1;
+ sab[1].cElements = 2;
+
+ lpsa = SafeArrayCreate(VT_I2, 2, sab);
+ *(DWORD *)lpsa->pvData = 0xcafebabe;
+
+ lpsa->cLocks = 7;
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
+ expected = (44 + 1 + +sizeof(SAFEARRAYBOUND) + sizeof(ULONG) - 1) & ~(sizeof(ULONG) - 1);
+ expected += max(sab[0].cElements, sab[1].cElements) * lpsa->cDims * sizeof(USHORT);
ok(size == expected || size == expected + 12, /* win64 */
"size should be %u bytes, not %u\n", expected, size);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
- expected = 44 + sab.cElements * sizeof(USHORT);
+ expected = 52 + max(sab[0].cElements, sab[1].cElements) * lpsa->cDims * sizeof(USHORT);
ok(size == expected || size == expected + 12, /* win64 */
"size should be %u bytes, not %u\n", expected, size);
buffer = HeapAlloc(GetProcessHeap(), 0, size);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
+ ok(lpsa->cLocks == 7, "got lock count %u\n", lpsa->cLocks);
check_safearray(buffer, lpsa);
- if (LPSAFEARRAY_UNMARSHAL_WORKS)
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
+ ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal\n");
+ if (pSafeArrayGetVartype)
{
- VARTYPE vt, vt2;
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
- LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
- ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal\n");
- SafeArrayGetVartype(lpsa, &vt);
- SafeArrayGetVartype(lpsa2, &vt2);
+ pSafeArrayGetVartype(lpsa, &vt);
+ pSafeArrayGetVartype(lpsa2, &vt2);
ok(vt == vt2, "vts differ %x %x\n", vt, vt2);
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
- LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
}
+ ok(lpsa2->cLocks == 0, "got lock count %u, expected 0\n", lpsa2->cLocks);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
HeapFree(GetProcessHeap(), 0, buffer);
lpsa->cLocks = 0;
- SafeArrayDestroy(lpsa);
+ hr = SafeArrayDestroy(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
/* test NULL safe array */
lpsa = NULL;
ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
check_safearray(buffer, lpsa);
- if (LPSAFEARRAY_UNMARSHAL_WORKS)
- {
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
- LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
- ok(lpsa2 == NULL, "NULL LPSAFEARRAY didn't unmarshal\n");
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
- LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
- }
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
+ ok(lpsa2 == NULL, "NULL LPSAFEARRAY didn't unmarshal\n");
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
HeapFree(GetProcessHeap(), 0, buffer);
- sab.lLbound = 5;
- sab.cElements = 10;
+ sab[0].lLbound = 5;
+ sab[0].cElements = 10;
- lpsa = SafeArrayCreate(VT_R8, 1, &sab);
+ lpsa = SafeArrayCreate(VT_R8, 1, sab);
*(double *)lpsa->pvData = 3.1415;
lpsa->cLocks = 7;
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
expected = (44 + 1 + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
- expected += sab.cElements * sizeof(double);
+ expected += sab[0].cElements * sizeof(double);
ok(size == expected || size == expected + 16, /* win64 */
"size should be %u bytes, not %u\n", expected, size);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
expected = (44 + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
- expected += sab.cElements * sizeof(double);
+ expected += sab[0].cElements * sizeof(double);
size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
ok(size == expected || size == expected + 8, /* win64 */
"size should be %u bytes, not %u\n", expected, size);
HeapFree(GetProcessHeap(), 0, buffer);
lpsa->cLocks = 0;
- SafeArrayDestroy(lpsa);
+ hr = SafeArrayDestroy(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
/* VARTYPE-less arrays can be marshaled if cbElements is 1,2,4 or 8 as type SF_In */
hr = SafeArrayAllocDescriptor(1, &lpsa);
hr = SafeArrayAllocData(lpsa);
ok(hr == S_OK, "saad failed %08x\n", hr);
- hr = SafeArrayGetVartype(lpsa, &vt);
- ok(hr == E_INVALIDARG, "ret %08x\n", hr);
+ if (pSafeArrayGetVartype)
+ {
+ hr = pSafeArrayGetVartype(lpsa, &vt);
+ ok(hr == E_INVALIDARG, "ret %08x\n", hr);
+ }
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
"Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
check_safearray(buffer, lpsa);
HeapFree(GetProcessHeap(), 0, buffer);
- SafeArrayDestroyData(lpsa);
- SafeArrayDestroyDescriptor(lpsa);
+ hr = SafeArrayDestroyData(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = SafeArrayDestroyDescriptor(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
/* Test an array of VT_BSTR */
- sab.lLbound = 3;
- sab.cElements = sizeof(values) / sizeof(values[0]);
+ sab[0].lLbound = 3;
+ sab[0].cElements = sizeof(values) / sizeof(values[0]);
- lpsa = SafeArrayCreate(VT_BSTR, 1, &sab);
+ lpsa = SafeArrayCreate(VT_BSTR, 1, sab);
expected_bstr_size = 0;
- for (i = 0; i < sab.cElements; i++)
+ for (i = 0; i < sab[0].cElements; i++)
{
int j;
WCHAR buf[128];
for (j = 0; j <= i; j++)
buf[j] = 'a' + j;
buf[j] = 0;
- indices[0] = i + sab.lLbound;
+ indices[0] = i + sab[0].lLbound;
values[i] = SysAllocString(buf);
hr = SafeArrayPutElement(lpsa, indices, values[i]);
ok(hr == S_OK, "Failed to put bstr element hr 0x%x\n", hr);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
- expected = 44 + (sab.cElements * sizeof(DWORD)) + expected_bstr_size;
+ expected = 44 + (sab[0].cElements * sizeof(DWORD)) + expected_bstr_size;
todo_wine
ok(size == expected + sizeof(DWORD) || size == (expected + sizeof(DWORD) + 12 /* win64 */),
"size should be %u bytes, not %u\n", expected + (ULONG) sizeof(DWORD), size);
check_safearray(buffer, lpsa);
lpsa2 = NULL;
- if (LPSAFEARRAY_UNMARSHAL_WORKS)
- {
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
- next = LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
- todo_wine
- ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
- ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal, result %p\n", next);
- }
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ next = LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
+ todo_wine
+ ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
+ ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal, result %p\n", next);
for (i = 0; i < sizeof(values) / sizeof(values[0]); i++)
{
if (lpsa2)
{
- indices[0] = i + sab.lLbound;
+ indices[0] = i + sab[0].lLbound;
hr = SafeArrayGetElement(lpsa2, indices, &gotvalue);
ok(hr == S_OK, "Failed to get bstr element at hres 0x%x\n", hr);
if (hr == S_OK)
{
- ok(VarBstrCmp(values[i], gotvalue, 0, 0) == VARCMP_EQ, "String %d does not match\n", i);
+ if (pVarBstrCmp)
+ ok(pVarBstrCmp(values[i], gotvalue, 0, 0) == VARCMP_EQ, "String %d does not match\n", i);
SysFreeString(gotvalue);
}
}
SysFreeString(values[i]);
}
- if (LPSAFEARRAY_UNMARSHAL_WORKS)
- {
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
- LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
- }
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
HeapFree(GetProcessHeap(), 0, buffer);
- SafeArrayDestroy(lpsa);
-
+ hr = SafeArrayDestroy(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
/* VARTYPE-less arrays with FADF_VARIANT */
hr = SafeArrayAllocDescriptor(1, &lpsa);
hr = SafeArrayAllocData(lpsa);
ok(hr == S_OK, "saad failed %08x\n", hr);
- hr = SafeArrayGetVartype(lpsa, &vt);
- ok(hr == E_INVALIDARG, "ret %08x\n", hr);
+ if (pSafeArrayGetVartype)
+ {
+ hr = pSafeArrayGetVartype(lpsa, &vt);
+ ok(hr == E_INVALIDARG, "ret %08x\n", hr);
+ }
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
lpsa->cbElements = 16; /* VARIANT wire size */
check_safearray(buffer, lpsa);
HeapFree(GetProcessHeap(), 0, buffer);
- SafeArrayDestroyData(lpsa);
- SafeArrayDestroyDescriptor(lpsa);
+ hr = SafeArrayDestroyData(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = SafeArrayDestroyDescriptor(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
}
static void check_bstr(void *buffer, BSTR b)
ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
check_bstr(buffer, b);
- if (BSTR_UNMARSHAL_WORKS)
- {
- b2 = NULL;
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
- next = BSTR_UserUnmarshal(&umcb.Flags, buffer, &b2);
- ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
- ok(b2 != NULL, "BSTR didn't unmarshal\n");
- ok(!memcmp(b, b2, (len + 1) * 2), "strings differ\n");
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
- BSTR_UserFree(&umcb.Flags, &b2);
- }
+ b2 = NULL;
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ next = BSTR_UserUnmarshal(&umcb.Flags, buffer, &b2);
+ ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
+ ok(b2 != NULL, "BSTR didn't unmarshal\n");
+ ok(!memcmp(b, b2, (len + 1) * 2), "strings differ\n");
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ BSTR_UserFree(&umcb.Flags, &b2);
HeapFree(GetProcessHeap(), 0, buffer);
SysFreeString(b);
ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
check_bstr(buffer, b);
- if (BSTR_UNMARSHAL_WORKS)
- {
- b2 = NULL;
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
- next = BSTR_UserUnmarshal(&umcb.Flags, buffer, &b2);
- ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
- ok(b2 == NULL, "NULL BSTR didn't unmarshal\n");
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
- BSTR_UserFree(&umcb.Flags, &b2);
- }
+ b2 = NULL;
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ next = BSTR_UserUnmarshal(&umcb.Flags, buffer, &b2);
+ ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
+ ok(b2 == NULL, "NULL BSTR didn't unmarshal\n");
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ BSTR_UserFree(&umcb.Flags, &b2);
HeapFree(GetProcessHeap(), 0, buffer);
b = SysAllocStringByteLen("abc", 3);
check_bstr(buffer, b);
ok(buffer[15] == 'd', "buffer[15] %02x\n", buffer[15]);
- if (BSTR_UNMARSHAL_WORKS)
- {
- b2 = NULL;
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
- next = BSTR_UserUnmarshal(&umcb.Flags, buffer, &b2);
- ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
- ok(b2 != NULL, "BSTR didn't unmarshal\n");
- ok(!memcmp(b, b2, len), "strings differ\n");
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
- BSTR_UserFree(&umcb.Flags, &b2);
- }
+ b2 = NULL;
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ next = BSTR_UserUnmarshal(&umcb.Flags, buffer, &b2);
+ ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
+ ok(b2 != NULL, "BSTR didn't unmarshal\n");
+ ok(!memcmp(b, b2, len), "strings differ\n");
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ BSTR_UserFree(&umcb.Flags, &b2);
HeapFree(GetProcessHeap(), 0, buffer);
SysFreeString(b);
ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
check_bstr(buffer, b);
- if (BSTR_UNMARSHAL_WORKS)
- {
- b2 = NULL;
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
- next = BSTR_UserUnmarshal(&umcb.Flags, buffer, &b2);
- ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
- ok(b2 != NULL, "NULL LPSAFEARRAY didn't unmarshal\n");
- len = SysStringByteLen(b2);
- ok(len == 0, "byte len %d\n", len);
- init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
- BSTR_UserFree(&umcb.Flags, &b2);
- }
+ b2 = NULL;
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ next = BSTR_UserUnmarshal(&umcb.Flags, buffer, &b2);
+ ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
+ ok(b2 != NULL, "NULL LPSAFEARRAY didn't unmarshal\n");
+ len = SysStringByteLen(b2);
+ ok(len == 0, "byte len %d\n", len);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ BSTR_UserFree(&umcb.Flags, &b2);
HeapFree(GetProcessHeap(), 0, buffer);
SysFreeString(b);
}
typedef struct
{
- const IUnknownVtbl *lpVtbl;
+ IUnknown IUnknown_iface;
ULONG refs;
} HeapUnknown;
+static inline HeapUnknown *impl_from_IUnknown(IUnknown *iface)
+{
+ return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface);
+}
+
static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
if (IsEqualIID(riid, &IID_IUnknown))
static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
{
- HeapUnknown *This = (HeapUnknown *)iface;
+ HeapUnknown *This = impl_from_IUnknown(iface);
return InterlockedIncrement((LONG*)&This->refs);
}
static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
{
- HeapUnknown *This = (HeapUnknown *)iface;
+ HeapUnknown *This = impl_from_IUnknown(iface);
ULONG refs = InterlockedDecrement((LONG*)&This->refs);
if (!refs) HeapFree(GetProcessHeap(), 0, This);
return refs;
static void test_marshal_VARIANT(void)
{
- VARIANT v, v2;
+ VARIANT v, v2, v3;
MIDL_STUB_MESSAGE stubMsg = { 0 };
RPC_MESSAGE rpcMsg = { 0 };
USER_MARSHAL_CB umcb = { 0 };
ULONG ul;
short s;
double d;
+ void *mem;
DWORD *wirev;
BSTR b;
WCHAR str[] = {'m','a','r','s','h','a','l',' ','t','e','s','t',0};
DECIMAL dec, dec2;
HeapUnknown *heap_unknown;
DWORD expected;
+ HRESULT hr;
+ LONG bound, bound2;
+ VARTYPE vt, vt2;
stubMsg.RpcMsg = &rpcMsg;
check_variant_header(wirev, &v, stubMsg.BufferLength);
wirev += 5;
ok(*(char*)wirev == V_I1(&v), "wv[5] %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));
- ok(V_I1(&v) == V_I1(&v2), "got i1 %x expect %x\n", V_I1(&v), V_I1(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(V_I1(&v) == V_I1(&v2), "got i1 %x expect %x\n", V_I1(&v), V_I1(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** I2 ***/
check_variant_header(wirev, &v, stubMsg.BufferLength);
wirev += 5;
ok(*(short*)wirev == V_I2(&v), "wv[5] %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));
- ok(V_I2(&v) == V_I2(&v2), "got i2 %x expect %x\n", V_I2(&v), V_I2(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(V_I2(&v) == V_I2(&v2), "got i2 %x expect %x\n", V_I2(&v), V_I2(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** I2 BYREF ***/
ok(*wirev == 0x4, "wv[5] %08x\n", *wirev);
wirev++;
ok(*(short*)wirev == s, "wv[6] %08x\n", *wirev);
- if (VARIANT_UNMARSHAL_WORKS)
- {
- 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);
- }
+ 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);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** I4 ***/
wirev += 5;
ok(*wirev == V_I4(&v), "wv[5] %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));
- ok(V_I4(&v) == V_I4(&v2), "got i4 %x expect %x\n", V_I4(&v), V_I4(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(V_I4(&v) == V_I4(&v2), "got i4 %x expect %x\n", V_I4(&v), V_I4(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** UI4 ***/
check_variant_header(wirev, &v, stubMsg.BufferLength);
wirev += 5;
ok(*wirev == 0x1234, "wv[5] %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));
- ok(V_UI4(&v) == V_UI4(&v2), "got ui4 %x expect %x\n", V_UI4(&v), V_UI4(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(V_UI4(&v) == V_UI4(&v2), "got ui4 %x expect %x\n", V_UI4(&v), V_UI4(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** UI4 BYREF ***/
wirev++;
ok(*wirev == ul, "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));
- ok(*V_UI4REF(&v) == *V_UI4REF(&v2), "got ui4 ref %x expect ui4 ref %x\n", *V_UI4REF(&v), *V_UI4REF(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(*V_UI4REF(&v) == *V_UI4REF(&v2), "got ui4 ref %x expect ui4 ref %x\n", *V_UI4REF(&v), *V_UI4REF(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** R4 ***/
check_variant_header(wirev, &v, stubMsg.BufferLength);
wirev += 5;
ok(*(float*)wirev == V_R4(&v), "wv[5] %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));
- ok(V_R4(&v) == V_R4(&v2), "got r4 %f expect %f\n", V_R4(&v), V_R4(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(V_R4(&v) == V_R4(&v2), "got r4 %f expect %f\n", V_R4(&v), V_R4(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** R8 ***/
ok(*wirev == 0xcccccccc, "wv[5] %08x\n", *wirev); /* pad */
wirev++;
ok(*(double*)wirev == V_R8(&v), "wv[6] %08x, wv[7] %08x\n", *wirev, *(wirev+1));
- 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));
- ok(V_R8(&v) == V_R8(&v2), "got r8 %f expect %f\n", V_R8(&v), V_R8(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(V_R8(&v) == V_R8(&v2), "got r8 %f expect %f\n", V_R8(&v), V_R8(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** R8 BYREF ***/
ok(*wirev == 8, "wv[5] %08x\n", *wirev);
wirev++;
ok(*(double*)wirev == d, "wv[6] %08x wv[7] %08x\n", *wirev, *(wirev+1));
- 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));
- ok(*V_R8REF(&v) == *V_R8REF(&v2), "got r8 ref %f expect %f\n", *V_R8REF(&v), *V_R8REF(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(*V_R8REF(&v) == *V_R8REF(&v2), "got r8 ref %f expect %f\n", *V_R8REF(&v), *V_R8REF(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** VARIANT_BOOL ***/
check_variant_header(wirev, &v, stubMsg.BufferLength);
wirev += 5;
ok(*(short*)wirev == V_BOOL(&v), "wv[5] %04x\n", *(WORD*)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));
- ok(V_BOOL(&v) == V_BOOL(&v2), "got bool %x expect %x\n", V_BOOL(&v), V_BOOL(&v2));
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(V_BOOL(&v) == V_BOOL(&v2), "got bool %x expect %x\n", V_BOOL(&v), V_BOOL(&v2));
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** DECIMAL ***/
dec2.wReserved = VT_DECIMAL;
ok(!memcmp(wirev, &dec2, sizeof(dec2)), "wirev[6] %08x wirev[7] %08x wirev[8] %08x wirev[9] %08x\n",
*wirev, *(wirev + 1), *(wirev + 2), *(wirev + 3));
- 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));
- ok(!memcmp(&V_DECIMAL(&v), & V_DECIMAL(&v2), sizeof(DECIMAL)), "decimals differ\n");
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(!memcmp(&V_DECIMAL(&v), & V_DECIMAL(&v2), sizeof(DECIMAL)), "decimals differ\n");
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** DECIMAL BYREF ***/
ok(*wirev == 16, "wv[5] %08x\n", *wirev);
wirev++;
ok(!memcmp(wirev, &dec, sizeof(dec)), "wirev[6] %08x wirev[7] %08x wirev[8] %08x wirev[9] %08x\n", *wirev, *(wirev + 1), *(wirev + 2), *(wirev + 3));
- 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);
- ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
- ok(!memcmp(V_DECIMALREF(&v), V_DECIMALREF(&v2), sizeof(DECIMAL)), "decimals differ\n");
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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);
+ ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
+ ok(!memcmp(V_DECIMALREF(&v), V_DECIMALREF(&v2), sizeof(DECIMAL)), "decimals differ\n");
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** EMPTY ***/
wirev = (DWORD*)buffer;
check_variant_header(wirev, &v, stubMsg.BufferLength);
- 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));
+ 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));
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** NULL ***/
wirev = (DWORD*)buffer;
check_variant_header(wirev, &v, stubMsg.BufferLength);
- 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));
+ 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));
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** BSTR ***/
ok(*wirev, "wv[5] %08x\n", *wirev); /* win2k: this is b. winxp: this is (char*)b + 1 */
wirev++;
check_bstr(wirev, V_BSTR(&v));
- 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));
- ok(SysStringByteLen(V_BSTR(&v)) == SysStringByteLen(V_BSTR(&v2)), "bstr string lens differ\n");
- ok(!memcmp(V_BSTR(&v), V_BSTR(&v2), SysStringByteLen(V_BSTR(&v))), "bstrs differ\n");
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(SysStringByteLen(V_BSTR(&v)) == SysStringByteLen(V_BSTR(&v2)), "bstr string lens differ\n");
+ ok(!memcmp(V_BSTR(&v), V_BSTR(&v2), SysStringByteLen(V_BSTR(&v))), "bstrs differ\n");
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** BSTR BYREF ***/
ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is b. winxp: this is (char*)b + 1 */
wirev++;
check_bstr(wirev, b);
- 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));
- ok(SysStringByteLen(*V_BSTRREF(&v)) == SysStringByteLen(*V_BSTRREF(&v2)), "bstr string lens differ\n");
- ok(!memcmp(*V_BSTRREF(&v), *V_BSTRREF(&v2), SysStringByteLen(*V_BSTRREF(&v))), "bstrs differ\n");
-
- VARIANT_UserFree(&umcb.Flags, &v2);
- }
+ 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));
+ ok(SysStringByteLen(*V_BSTRREF(&v)) == SysStringByteLen(*V_BSTRREF(&v2)), "bstr string lens differ\n");
+ ok(!memcmp(*V_BSTRREF(&v), *V_BSTRREF(&v2), SysStringByteLen(*V_BSTRREF(&v))), "bstrs differ\n");
+
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
SysFreeString(b);
ok(*wirev, "wv[5] %08x\n", *wirev); /* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */
wirev++;
check_safearray(wirev, lpsa);
- if (VARIANT_UNMARSHAL_WORKS)
+ VariantInit(&v2);
+ stubMsg.Buffer = buffer;
+ next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
+ ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
+ ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
+ ok(SafeArrayGetDim(V_ARRAY(&v)) == SafeArrayGetDim(V_ARRAY(&v2)), "array dims differ\n");
+ SafeArrayGetLBound(V_ARRAY(&v), 1, &bound);
+ SafeArrayGetLBound(V_ARRAY(&v2), 1, &bound2);
+ ok(bound == bound2, "array lbounds differ\n");
+ SafeArrayGetUBound(V_ARRAY(&v), 1, &bound);
+ SafeArrayGetUBound(V_ARRAY(&v2), 1, &bound2);
+ ok(bound == bound2, "array ubounds differ\n");
+ if (pSafeArrayGetVartype)
{
- LONG bound, bound2;
- VARTYPE vt, vt2;
- VariantInit(&v2);
- stubMsg.Buffer = buffer;
- next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
- ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
- ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
- ok(SafeArrayGetDim(V_ARRAY(&v)) == SafeArrayGetDim(V_ARRAY(&v)), "array dims differ\n");
- SafeArrayGetLBound(V_ARRAY(&v), 1, &bound);
- SafeArrayGetLBound(V_ARRAY(&v2), 1, &bound2);
- ok(bound == bound2, "array lbounds differ\n");
- SafeArrayGetUBound(V_ARRAY(&v), 1, &bound);
- SafeArrayGetUBound(V_ARRAY(&v2), 1, &bound2);
- ok(bound == bound2, "array ubounds differ\n");
- SafeArrayGetVartype(V_ARRAY(&v), &vt);
- SafeArrayGetVartype(V_ARRAY(&v2), &vt2);
+ pSafeArrayGetVartype(V_ARRAY(&v), &vt);
+ pSafeArrayGetVartype(V_ARRAY(&v2), &vt2);
ok(vt == vt2, "array vts differ %x %x\n", vt, vt2);
- VARIANT_UserFree(&umcb.Flags, &v2);
}
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** ARRAY BYREF ***/
ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */
wirev++;
check_safearray(wirev, lpsa);
- if (VARIANT_UNMARSHAL_WORKS)
+ VariantInit(&v2);
+ stubMsg.Buffer = buffer;
+ next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
+ ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
+ ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
+ ok(SafeArrayGetDim(*V_ARRAYREF(&v)) == SafeArrayGetDim(*V_ARRAYREF(&v2)), "array dims differ\n");
+ SafeArrayGetLBound(*V_ARRAYREF(&v), 1, &bound);
+ SafeArrayGetLBound(*V_ARRAYREF(&v2), 1, &bound2);
+ ok(bound == bound2, "array lbounds differ\n");
+ SafeArrayGetUBound(*V_ARRAYREF(&v), 1, &bound);
+ SafeArrayGetUBound(*V_ARRAYREF(&v2), 1, &bound2);
+ ok(bound == bound2, "array ubounds differ\n");
+ if (pSafeArrayGetVartype)
{
- LONG bound, bound2;
- VARTYPE vt, vt2;
- VariantInit(&v2);
- stubMsg.Buffer = buffer;
- next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
- ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
- ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
- ok(SafeArrayGetDim(*V_ARRAYREF(&v)) == SafeArrayGetDim(*V_ARRAYREF(&v)), "array dims differ\n");
- SafeArrayGetLBound(*V_ARRAYREF(&v), 1, &bound);
- SafeArrayGetLBound(*V_ARRAYREF(&v2), 1, &bound2);
- ok(bound == bound2, "array lbounds differ\n");
- SafeArrayGetUBound(*V_ARRAYREF(&v), 1, &bound);
- SafeArrayGetUBound(*V_ARRAYREF(&v2), 1, &bound2);
- ok(bound == bound2, "array ubounds differ\n");
- SafeArrayGetVartype(*V_ARRAYREF(&v), &vt);
- SafeArrayGetVartype(*V_ARRAYREF(&v2), &vt2);
+ pSafeArrayGetVartype(*V_ARRAYREF(&v), &vt);
+ pSafeArrayGetVartype(*V_ARRAYREF(&v2), &vt2);
ok(vt == vt2, "array vts differ %x %x\n", vt, vt2);
- VARIANT_UserFree(&umcb.Flags, &v2);
}
+ VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
- SafeArrayDestroy(lpsa);
+ hr = SafeArrayDestroy(lpsa);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
/*** VARIANT BYREF ***/
VariantInit(&v);
ok(*wirev == 0xcccccccc, "wv[13] %08x\n", *wirev); /* pad for VT_R8 */
wirev++;
ok(*(double*)wirev == V_R8(&v2), "wv[6] %08x wv[7] %08x\n", *wirev, *(wirev+1));
- if (VARIANT_UNMARSHAL_WORKS)
- {
- VARIANT v3;
- VariantInit(&v3);
- stubMsg.Buffer = buffer;
- next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v3);
- ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
- 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");
- VARIANT_UserFree(&umcb.Flags, &v3);
- }
+ VariantInit(&v3);
+ stubMsg.Buffer = buffer;
+ next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v3);
+ ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
+ 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");
+ VARIANT_UserFree(&umcb.Flags, &v3);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** UNKNOWN ***/
heap_unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*heap_unknown));
- heap_unknown->lpVtbl = &HeapUnknown_Vtbl;
+ heap_unknown->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
heap_unknown->refs = 1;
VariantInit(&v);
VariantInit(&v2);
V_VT(&v) = VT_UNKNOWN;
- V_UNKNOWN(&v) = (IUnknown *)heap_unknown;
+ V_UNKNOWN(&v) = &heap_unknown->IUnknown_iface;
rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
ok(stubMsg.BufferLength > 32, "size %d\n", stubMsg.BufferLength);
wirev++;
todo_wine
ok(*wirev == 0x574f454d, "wv[8] %08x\n", *wirev);
- if (VARIANT_UNMARSHAL_WORKS)
- {
- VARIANT v3;
- VariantInit(&v3);
- V_VT(&v3) = VT_UNKNOWN;
- V_UNKNOWN(&v3) = (IUnknown *)heap_unknown;
- IUnknown_AddRef(V_UNKNOWN(&v3));
- 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_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);
- }
+ VariantInit(&v3);
+ V_VT(&v3) = VT_UNKNOWN;
+ V_UNKNOWN(&v3) = &heap_unknown->IUnknown_iface;
+ IUnknown_AddRef(V_UNKNOWN(&v3));
+ 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_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(&heap_unknown->IUnknown_iface);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** NULL UNKNOWN ***/
/*** UNKNOWN BYREF ***/
heap_unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*heap_unknown));
- heap_unknown->lpVtbl = &HeapUnknown_Vtbl;
+ heap_unknown->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
heap_unknown->refs = 1;
VariantInit(&v);
VariantInit(&v2);
wirev++;
todo_wine
ok(*wirev == 0x574f454d, "wv[9] %08x\n", *wirev);
- if (VARIANT_UNMARSHAL_WORKS)
- {
- VARIANT v3;
- VariantInit(&v3);
- V_VT(&v3) = VT_UNKNOWN;
- V_UNKNOWN(&v3) = (IUnknown *)heap_unknown;
- IUnknown_AddRef(V_UNKNOWN(&v3));
- 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_UNKNOWNREF(&v) == *V_UNKNOWNREF(&v3), "got %p expect %p\n", *V_UNKNOWNREF(&v), *V_UNKNOWNREF(&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);
- }
+
+ VariantInit(&v3);
+ V_VT(&v3) = VT_UNKNOWN;
+ V_UNKNOWN(&v3) = &heap_unknown->IUnknown_iface;
+ IUnknown_AddRef(V_UNKNOWN(&v3));
+ 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_UNKNOWNREF(&v) == *V_UNKNOWNREF(&v3), "got %p expect %p\n", *V_UNKNOWNREF(&v), *V_UNKNOWNREF(&v3));
+ VARIANT_UserFree(&umcb.Flags, &v3);
+ ok(heap_unknown->refs == 1, "%d refcounts of IUnknown leaked\n", heap_unknown->refs - 1);
+ IUnknown_Release(&heap_unknown->IUnknown_iface);
HeapFree(GetProcessHeap(), 0, oldbuffer);
}
START_TEST(usrmarshal)
{
+ HANDLE hOleaut32 = GetModuleHandleA("oleaut32.dll");
+#define GETPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func)
+ GETPTR(SafeArrayGetIID);
+ GETPTR(SafeArrayGetVartype);
+ GETPTR(VarBstrCmp);
+#undef GETPTR
+
+ if (!pSafeArrayGetIID || !pSafeArrayGetVartype)
+ win_skip("SafeArrayGetIID and/or SafeArrayGetVartype is not available, some tests will be skipped\n");
+
CoInitialize(NULL);
test_marshal_LPSAFEARRAY();
static HMODULE hOleaut32;
+static HRESULT (WINAPI *pVarBstrCmp)(BSTR,BSTR,LCID,ULONG);
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*);
/* Get a conversion function ptr, return if function not available */
#define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
- if (!p##func) { trace("function " # func " not available, not testing it\n"); return; }
+ if (!p##func) { win_skip("function " # func " not available, not testing it\n"); return; }
static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 )
{
{ 2.525, "hh :mm:mm", "12 :36:01" },
{ 2.525, "dd :mm:mm", "01 :01:01" },
{ 2.525, "dd :mm:nn", "01 :01:36" },
- { 2.725, "hh:nn:ss A/P", "05:24:00 P" }
+ { 2.725, "hh:nn:ss A/P", "05:24:00 P" },
+ { 40531.0, "dddd", "Sunday" },
+ { 40531.0, "ddd", "Sun" }
+};
+
+/* The following tests require that the time separator is a colon (:) */
+static const FMTDATERES VarFormat_namedtime_results[] =
+{
+ { 2.525, "short time", "12:36" },
+ { 2.525, "medium time", "12:36 PM" },
+ { 2.525, "long time", "12:36:00 PM" }
};
#define VNUMFMT(vt,v) \
if (PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())) != LANG_ENGLISH)
{
- skip("Skipping VarFormat tests for non english language\n");
+ skip("Skipping VarFormat tests for non English language\n");
return;
}
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
VarFormat_date_results[i].res);
}
+ /* Named time formats */
+ GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, buff, sizeof(buff)/sizeof(char));
+ if (strcmp(buff, "h:mm:ss tt"))
+ {
+ skip("Skipping named time tests as time format is '%s'\n", buff);
+ }
+ else
+ {
+ for (i = 0; i < sizeof(VarFormat_namedtime_results)/sizeof(FMTDATERES); i++)
+ {
+ fd = 0;
+ VARFMT(VT_DATE,V_DATE,VarFormat_namedtime_results[i].val,
+ VarFormat_namedtime_results[i].fmt,S_OK,
+ VarFormat_namedtime_results[i].res);
+ }
+ }
+
/* Strings */
bstrin = SysAllocString(szTesting);
VARFMT(VT_BSTR,V_BSTR,bstrin,"",S_OK,"testing");
"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)
+ pVarBstrCmp = (void*)GetProcAddress(hOleaut32, "VarBstrCmp");
+ if (pVarBstrCmp)
+ for (iWeekday = 1; iWeekday <= 7; ++iWeekday)
{
- /* 0 = Default, 1 = Sunday, 2 = Monday, .. */
- for (iFirstDay = 0; iFirstDay <= 7; ++iFirstDay)
+ for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev)
{
- 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);
+ /* 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 == pVarBstrCmp(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)
#include <math.h>
#include <float.h>
+#define CONST_VTABLE
+
#include "windef.h"
#include "winbase.h"
#include "winsock.h"
/* Get a conversion function ptr, return if function not available */
#define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
- if (!p##func) { trace("function " # func " not available, not testing it\n"); return; }
+ if (!p##func) { win_skip("function " # func " not available, not testing it\n"); return; }
/* Have IRecordInfo data type? */
static int HAVE_OLEAUT32_RECORD = 0;
HRESULT res;
res = VarBstrFromBool(VARIANT_TRUE, LANG_USER_DEFAULT, VAR_LOCALBOOL, &bstr);
- ok(SUCCEEDED(res) && (lstrlenW(bstr) > 0),
+ ok(res == S_OK && (lstrlenW(bstr) > 0),
"Expected localized string for 'True'\n");
/* lstrcpyW / lstrcatW do not work on win95 */
memcpy(sz12_true, sz12, sizeof(sz12));
SysFreeString(bstr);
res = VarBstrFromBool(VARIANT_FALSE, LANG_USER_DEFAULT, VAR_LOCALBOOL, &bstr);
- ok(SUCCEEDED(res) && (lstrlenW(bstr) > 0),
+ ok(res == S_OK && (lstrlenW(bstr) > 0),
"Expected localized string for 'False'\n");
memcpy(sz12_false, sz12, sizeof(sz12));
if (bstr) memcpy(&sz12_false[2], bstr, SysStringByteLen(bstr) + sizeof(WCHAR));
VariantClear( &result );
}
+static int strcmp_wa(const WCHAR *strw, const char *stra)
+{
+ WCHAR buf[512];
+ MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(buf[0]));
+ return lstrcmpW(strw, buf);
+}
+
+#define test_bstr_var(a,b) _test_bstr_var(__LINE__,a,b)
+static void _test_bstr_var(unsigned line, const VARIANT *v, const char *str)
+{
+ ok_(__FILE__,line)(V_VT(v) == VT_BSTR, "unexpected vt=%d\n", V_VT(v));
+ if(V_VT(v) == VT_BSTR)
+ ok(!strcmp_wa(V_BSTR(v), str), "v=%s, expected %s\n", wine_dbgstr_w(V_BSTR(v)), str);
+}
static void test_VariantInit(void)
{
typedef struct
{
- const IUnknownVtbl *lpVtbl;
- LONG ref;
- LONG events;
+ IUnknown IUnknown_iface;
+ LONG ref;
+ LONG events;
} test_VariantClearImpl;
+static inline test_VariantClearImpl *impl_from_IUnknown(IUnknown *iface)
+{
+ return CONTAINING_RECORD(iface, test_VariantClearImpl, IUnknown_iface);
+}
+
static HRESULT WINAPI VC_QueryInterface(LPUNKNOWN iface,REFIID riid,LPVOID *ppobj)
{
- test_VariantClearImpl *This = (test_VariantClearImpl *)iface;
+ test_VariantClearImpl *This = impl_from_IUnknown(iface);
This->events |= 0x1;
return E_NOINTERFACE;
}
static ULONG WINAPI VC_AddRef(LPUNKNOWN iface) {
- test_VariantClearImpl *This = (test_VariantClearImpl *)iface;
+ test_VariantClearImpl *This = impl_from_IUnknown(iface);
This->events |= 0x2;
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI VC_Release(LPUNKNOWN iface) {
- test_VariantClearImpl *This = (test_VariantClearImpl *)iface;
+ test_VariantClearImpl *This = impl_from_IUnknown(iface);
/* static class, won't be freed */
This->events |= 0x4;
return InterlockedDecrement(&This->ref);
VC_Release,
};
-static test_VariantClearImpl test_myVariantClearImpl = {&test_VariantClear_vtbl, 1, 0};
+static test_VariantClearImpl test_myVariantClearImpl = {{&test_VariantClear_vtbl}, 1, 0};
static void test_VariantClear(void)
{
IUnknown *punk;
/* Crashes: Native does not test input for NULL, so neither does Wine */
- if (0) hres = VariantClear(NULL);
+ if (0)
+ VariantClear(NULL);
/* Only the type field is set, to VT_EMPTY */
V_VT(&v) = VT_UI4;
/* UNKNOWN */
V_VT(&v) = VT_UNKNOWN;
- V_UNKNOWN(&v) = (IUnknown*)&test_myVariantClearImpl;
+ V_UNKNOWN(&v) = &test_myVariantClearImpl.IUnknown_iface;
test_myVariantClearImpl.events = 0;
hres = VariantClear(&v);
ok(hres == S_OK, "ret %08x\n", hres);
ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
- ok(V_UNKNOWN(&v) == (IUnknown*)&test_myVariantClearImpl, "unknown %p\n", V_UNKNOWN(&v));
+ ok(V_UNKNOWN(&v) == &test_myVariantClearImpl.IUnknown_iface, "unknown %p\n", V_UNKNOWN(&v));
/* Check that Release got called, but nothing else */
ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
/* UNKNOWN BYREF */
- punk = (IUnknown*)&test_myVariantClearImpl;
+ punk = &test_myVariantClearImpl.IUnknown_iface;
V_VT(&v) = VT_UNKNOWN | VT_BYREF;
V_UNKNOWNREF(&v) = &punk;
test_myVariantClearImpl.events = 0;
ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
/* DISPATCH BYREF */
- punk = (IUnknown*)&test_myVariantClearImpl;
+ punk = &test_myVariantClearImpl.IUnknown_iface;
V_VT(&v) = VT_DISPATCH | VT_BYREF;
V_DISPATCHREF(&v) = (IDispatch**)&punk;
test_myVariantClearImpl.events = 0;
VariantInit(&vDst);
hres = VariantCopyInd(&vDst, &vSrc);
+ ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x77,
"CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
VariantInit(&vDst);
hres = VariantCopyInd(&vDst, &vSrc);
+ ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x88,
"CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
memset(&ud, 0, sizeof(ud));
res = pVarUdateFromDate(dt, flags, &ud);
- ok_(__FILE__,line)(r == res, "Wrong result %x/%x\n", r, res);
- if (SUCCEEDED(res))
- ok_(__FILE__,line)(ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d &&
- ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s &&
- ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy,
- "%.16g expected %d,%d,%d,%d,%d,%d,%d %d %d, got %d,%d,%d,%d,%d,%d,%d %d %d\n",
- dt, d, m, y, h, mn, s, ms, dw, dy,
- ud.st.wDay, ud.st.wMonth, ud.st.wYear, ud.st.wHour, ud.st.wMinute,
- ud.st.wSecond, ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear );
+ ok_(__FILE__,line)(r == res && (res != S_OK || (ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d &&
+ ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s &&
+ ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy)),
+ "%.16g expected res(%x) %d,%d,%d,%d,%d,%d,%d %d %d, got res(%x) %d,%d,%d,%d,%d,%d,%d %d %d\n",
+ dt, r, d, m, y, h, mn, s, ms, dw, dy,
+ res, ud.st.wDay, ud.st.wMonth, ud.st.wYear, ud.st.wHour, ud.st.wMinute,
+ ud.st.wSecond, ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear );
}
#define DT2UD(dt,flags,r,d,m,y,h,mn,s,ms,dw,dy) test_UdateFromDate(__LINE__,dt,flags,r,d,m,y,h,mn,s,ms,dw,dy)
DT2UD(29221.5,0,S_OK,1,1,1980,12,0,0,0,2,1); /* 12 AM */
DT2UD(29221.9888884444,0,S_OK,1,1,1980,23,44,0,0,2,1); /* 11:44 PM */
DT2UD(29221.7508765432,0,S_OK,1,1,1980,18,1,16,0,2,1); /* 6:18:02 PM */
+
+ /* Test handling of times on dates prior to the epoch */
+ DT2UD(-5.25,0,S_OK,25,12,1899,6,0,0,0,1,359);
+ DT2UD(-5.9999884259259,0,S_OK,25,12,1899,23,59,59,0,1,359);
+ /* This just demonstrates the non-linear nature of values prior to the epoch */
+ DT2UD(-4.0,0,S_OK,26,12,1899,0,0,0,0,2,360);
+ /* Numerical oddity: for 0.0 < x < 1.0, x and -x represent the same datetime */
+ DT2UD(-0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
+ DT2UD(0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
}
ud.st.wDayOfWeek = dw;
ud.wDayOfYear = dy;
res = pVarDateFromUdate(&ud, flags, &out);
- ok_(__FILE__,line)(r == res && (FAILED(r) || EQ_DOUBLE(out, dt)),
+ ok_(__FILE__,line)(r == res && (r != S_OK || EQ_DOUBLE(out, dt)),
"expected %x, %.16g, got %x, %.16g\n", r, dt, res, out);
}
#define UD2T(d,m,y,h,mn,s,ms,dw,dy,flags,r,dt) test_DateFromUDate(__LINE__,d,m,y,h,mn,s,ms,dw,dy,flags,r,dt)
UD2T(1,1,-1,18,1,16,0,0,0,0,S_OK,36161.75087962963); /* Test year -1 = 1999 */
UD2T(1,-1,1980,18,1,16,0,0,0,0,S_OK,29160.7508796296); /* Test month -1 = 11 */
UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0); /* Rolls fwd to 1/1/1981 */
+
+ /* Test handling of times on dates prior to the epoch */
+ UD2T(25,12,1899,6,0,0,0,1,359,0,S_OK,-5.25);
+ UD2T(25,12,1899,23,59,59,0,1,359,0,S_OK,-5.9999884259259);
+ /* This just demonstrates the non-linear nature of values prior to the epoch */
+ UD2T(26,12,1899,0,0,0,0,2,360,0,S_OK,-4.0);
+ /* for DATE values 0.0 < x < 1.0, x and -x represent the same datetime */
+ /* but when converting to DATE, prefer the positive versions */
+ UD2T(30,12,1899,6,0,0,0,6,364,0,S_OK,0.25);
}
static void test_st2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0);
ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0); /* Rolls back to 31 Dec 1899 */
ST2DT(1,13,1980,0,0,0,0,FALSE,29587.0); /* Fails on invalid month */
- ST2DT(31,12,90,0,0,0,0,TRUE,33238.0); /* year < 100 is 1900+year! */
+ ST2DT(31,12,90,0,0,0,0,TRUE,33238.0); /* 30 <= year < 100 is 1900+year */
+ ST2DT(1,1,30,0,0,0,0,TRUE,10959.0); /* 30 <= year < 100 is 1900+year */
+ ST2DT(1,1,29,0,0,0,0,TRUE,47119.0); /* 0 <= year < 30 is 2000+year */
+ ST2DT(1,1,0,0,0,0,0,TRUE,36526.0); /* 0 <= year < 30 is 2000+year */
}
static void test_dt2st(int line, double dt, INT r, WORD d, WORD m, WORD y,
{
static const WCHAR szNum0[] = {'0','\0' };
static const WCHAR szNum1[] = {'1','\0' };
+ static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
+ static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
HRESULT hres;
VARIANT v, exp, vDst;
DECIMAL *pdec = &V_DECIMAL(&v);
ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum0, "VarNot(0): changed input\n");
VARNOT(BSTR,(BSTR)szNum1,I4,-2);
ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum1, "VarNot(1): changed input\n");
+ VARNOT(BSTR, (BSTR)szTrue, BOOL, VARIANT_FALSE);
+ VARNOT(BSTR, (BSTR)szFalse, BOOL, VARIANT_TRUE);
V_VT(&v) = VT_DECIMAL;
S(U(*pdec)).sign = DECIMAL_NEG;
if (rightvt == VT_BSTR)
V_BSTR(&right) = rbstr;
V_VT(&result) = VT_EMPTY;
- resvt = VT_ERROR;
/* All extra flags produce errors */
if (ExtraFlags[i] == (VT_VECTOR|VT_BYREF|VT_RESERVED) ||
V_BSTR(&left) = lbstr;
V_VT(&right) = VT_BSTR;
V_BSTR(&right) = rbstr;
- hres = VarSub(&left, &right, &result);
+ hres = pVarSub(&left, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_R8,
"VarSub: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 0),
V_VT(&right) = VT_UI1;
V_UI1(&right) = 9;
- hres = VarSub(&cy, &right, &result);
+ hres = pVarSub(&cy, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_CY,
"VarSub: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromCy(V_CY(&result), &r);
ok(hres == S_OK && EQ_DOUBLE(r, 4702),
"VarSub: CY value %f, expected %f\n", r, (double)4720);
- hres = VarSub(&left, &dec, &result);
+ hres = pVarSub(&left, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
"VarSub: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromDec(&V_DECIMAL(&result), &r);
V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
test_Round( __LINE__, &v, deci, &exp )
+struct decimal_t {
+ BYTE scale;
+ BYTE sign;
+ ULONG Hi32;
+ ULONG Mid32;
+ ULONG Lo32;
+};
+
+struct decimal_round_t {
+ struct decimal_t source;
+ struct decimal_t ret;
+ int dec;
+};
+
+static const struct decimal_round_t decimal_round_data[] = {
+ {{ 0, DECIMAL_NEG, 0, 0, 1 }, { 0, DECIMAL_NEG, 0, 0, 1 }, 0},
+ {{ 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 1 }, 0},
+ {{ 2, 0, 0, 0, 155 }, { 0, 0, 0, 0, 16 }, 1},
+ {{ 2, 0, 0, 0, 155 }, { 1, 0, 0, 0, 2 }, 0},
+ {{ 2, 0, 0, 0, 199 }, { 1, 0, 0, 0, 20 }, 1},
+ {{ 2, 0, 0, 0, 199 }, { 2, 0, 0, 0, 199 }, 2},
+ {{ 2, DECIMAL_NEG, 0, 0, 199 }, { 2, DECIMAL_NEG, 0, 0, 199 }, 2},
+ {{ 2, DECIMAL_NEG, 0, 0, 55 }, { 2, DECIMAL_NEG, 0, 0, 6 }, 1},
+ {{ 2, 0, 0, 0, 55 }, { 2, 0, 0, 0, 6 }, 1}
+};
+
static void test_VarRound(void)
{
static WCHAR szNumMin[] = {'-','1','.','4','4','9','\0' };
VARIANT v, exp, vDst;
CY *pcy = &V_CY(&v);
char buff[8];
+ int i;
CHECKPTR(VarRound);
ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
"VarRound: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
- /* not yet implemented so no use testing yet
- todo_wine {
- DECIMAL *pdec = &V_DECIMAL(&v);
+ /* VT_DECIMAL */
+ for (i = 0; i < sizeof(decimal_round_data)/sizeof(struct decimal_round_t); i++)
+ {
+ const struct decimal_round_t *ptr = &decimal_round_data[i];
+ DECIMAL *pdec;
+
+ pdec = &V_DECIMAL(&v);
V_VT(&v) = VT_DECIMAL;
- S(U(*pdec)).sign = DECIMAL_NEG;
- S(U(*pdec)).scale = 0;
- pdec->Hi32 = 0;
- S1(U1(*pdec)).Mid32 = 0;
- S1(U1(*pdec)).Lo32 = 1;
- hres = pVarRound(&v,0,&vDst);
- ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
- S(U(V_DECIMAL(&vDst))).sign == 0,
- "VarRound: expected 0x0,%d,0x00, got 0x%X,%d,%02x\n", VT_DECIMAL,
- hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
-
- S(U(*pdec)).sign = 0;
- hres = pVarRound(&v,0,&vDst);
- ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
- S(U(V_DECIMAL(&vDst))).sign == DECIMAL_NEG,
- "VarRound: expected 0x0,%d,0x7f, got 0x%X,%d,%02x\n", VT_DECIMAL,
- hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
- }
- */
+ S(U(*pdec)).sign = ptr->source.sign;
+ S(U(*pdec)).scale = ptr->source.scale;
+ pdec->Hi32 = ptr->source.Hi32;
+ S1(U1(*pdec)).Mid32 = ptr->source.Mid32;
+ S1(U1(*pdec)).Lo32 = ptr->source.Lo32;
+ VariantInit(&vDst);
+ hres = pVarRound(&v, ptr->dec, &vDst);
+ todo_wine
+ ok(hres == S_OK, "%d: got 0x%08x\n", i, hres);
+ if (hres == S_OK)
+ {
+ ok(V_VT(&vDst) == VT_DECIMAL, "%d: got VT %d, expected VT_DECIMAL\n", i, V_VT(&vDst));
+ ok(S(U(V_DECIMAL(&vDst))).sign == ptr->ret.sign, "%d: got sign 0x%02x, expected 0x%02x\n",
+ i, S(U(V_DECIMAL(&vDst))).sign, ptr->ret.sign);
+ ok(V_DECIMAL(&vDst).Hi32 == ptr->ret.Hi32, "%d: got Hi32 %d, expected %d\n",
+ i, V_DECIMAL(&vDst).Hi32, ptr->ret.Hi32);
+ ok(S1(U1(V_DECIMAL(&vDst))).Mid32 == ptr->ret.Mid32, "%d: got Mid32 %d, expected %d\n",
+ i, S1(U1(V_DECIMAL(&vDst))).Mid32, ptr->ret.Mid32);
+ ok(S1(U1(V_DECIMAL(&vDst))).Lo32 == ptr->ret.Lo32, "%d: got Lo32 %d, expected %d\n",
+ i, S1(U1(V_DECIMAL(&vDst))).Lo32, ptr->ret.Lo32);
+ }
+ }
+ /* VT_CY */
V_VT(&v) = VT_CY;
pcy->int64 = 10000;
hres = pVarRound(&v,0,&vDst);
V_VT(&right) = VT_UI1;
V_UI1(&right) = 9;
- hres = VarMul(&cy, &right, &result);
+ hres = pVarMul(&cy, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_CY, "VarMul: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromCy(V_CY(&result), &r);
ok(hres == S_OK && EQ_DOUBLE(r, 42399), "VarMul: CY value %f, expected %f\n", r, (double)42399);
- hres = VarMul(&left, &dec, &result);
+ hres = pVarMul(&left, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_DECIMAL, "VarMul: 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, 46.2), "VarMul: DECIMAL value %f, expected %f\n", r, (double)46.2);
V_BSTR(&left) = lbstr;
V_VT(&right) = VT_BSTR;
V_BSTR(&right) = rbstr;
- hres = VarAdd(&left, &right, &result);
+ hres = pVarAdd(&left, &right, &result);
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);
V_VT(&right) = VT_UI1;
V_UI1(&right) = 9;
- hres = VarAdd(&cy, &right, &result);
+ hres = pVarAdd(&cy, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_CY, "VarAdd: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromCy(V_CY(&result), &r);
ok(hres == S_OK && EQ_DOUBLE(r, 4720), "VarAdd: CY value %f, expected %f\n", r, (double)4720);
- hres = VarAdd(&left, &dec, &result);
+ hres = pVarAdd(&left, &dec, &result);
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);
SysFreeString(rbstr);
}
+static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
+static HRESULT (WINAPI *pVarCat)(LPVARIANT,LPVARIANT,LPVARIANT);
+
static void test_VarCat(void)
{
LCID lcid;
HRESULT hres;
HRESULT expected_error_num;
+ CHECKPTR(VarCat);
+
/* Set date format for testing */
lcid = LOCALE_USER_DEFAULT;
GetLocaleInfo(lcid,LOCALE_SSHORTDATE,orig_date_format,128);
V_I8(&right) = 0;
}
- hres = VarCat(&left, &right, &result);
+ hres = pVarCat(&left, &right, &result);
/* Determine the error code for the vt combination */
ok(hres == expected_error_num,
V_BSTR(&left) = SysAllocString(sz12);
V_BSTR(&right) = SysAllocString(sz34);
V_BSTR(&expected) = SysAllocString(sz1234);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&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_BSTR concat with VT_BSTR failed to return correct result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
+ "VarCat: VT_BSTR concat with VT_BSTR failed to return correct result\n");
VariantClear(&left);
VariantClear(&right);
V_VT(&left) = VT_ERROR;
V_VT(&right) = VT_BSTR;
V_BSTR(&right) = SysAllocString(sz1234);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == DISP_E_TYPEMISMATCH, "VarCat should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hres);
ok(V_VT(&result) == VT_EMPTY,
"VarCat: VT_ERROR concat with VT_BSTR should have returned VT_EMPTY\n");
V_VT(&left) = VT_BSTR;
V_VT(&right) = VT_ERROR;
V_BSTR(&left) = SysAllocString(sz1234);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == DISP_E_TYPEMISMATCH, "VarCat should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hres);
ok(V_VT(&result) == VT_EMPTY,
"VarCat: VT_BSTR concat with VT_ERROR should have returned VT_EMPTY\n");
V_INT(&left) = 12;
V_BOOL(&right) = TRUE;
V_BSTR(&expected) = SysAllocString(sz12_true);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- hres = VarCmp(&result,&expected,lcid,0);
- ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
- hres, variantstr(&result), variantstr(&expected));
+ if (pVarCmp)
+ {
+ hres = pVarCmp(&result,&expected,lcid,0);
+ ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
+ hres, variantstr(&result), variantstr(&expected));
+ }
VariantClear(&left);
VariantClear(&right);
V_INT(&left) = 12;
V_BOOL(&right) = FALSE;
V_BSTR(&expected) = SysAllocString(sz12_false);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- hres = VarCmp(&result,&expected,lcid,0);
- ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
- hres, variantstr(&result), variantstr(&expected));
+ if (pVarCmp)
+ {
+ hres = pVarCmp(&result,&expected,lcid,0);
+ ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
+ hres, variantstr(&result), variantstr(&expected));
+ }
VariantClear(&left);
VariantClear(&right);
V_INT(&left) = 12;
V_INT(&right) = 34;
V_BSTR(&expected) = SysAllocString(sz1234);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
- "VarCat: NUMBER concat with NUMBER returned incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
+ "VarCat: NUMBER concat with NUMBER returned incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_VT(&right) = VT_BSTR;
V_INT(&left) = 12;
V_BSTR(&right) = SysAllocString(sz34);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
- "VarCat: NUMBER concat with VT_BSTR, incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
+ "VarCat: NUMBER concat with VT_BSTR, incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_VT(&right) = VT_INT;
V_BSTR(&left) = SysAllocString(sz12);
V_INT(&right) = 34;
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&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_BSTR concat with NUMBER, incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
+ "VarCat: VT_BSTR concat with NUMBER, incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_DATE(&right) = 29494.0;
V_BSTR(&expected)= SysAllocString(sz12_date);
V_BSTR(&expected_broken)= SysAllocString(sz12_date_broken);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
- broken(VarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
- "VarCat: VT_BSTR concat with VT_DATE returned incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
+ broken(pVarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
+ "VarCat: VT_BSTR concat with VT_DATE returned incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_BSTR(&right) = SysAllocString(sz12);
V_BSTR(&expected)= SysAllocString(date_sz12);
V_BSTR(&expected_broken)= SysAllocString(date_sz12_broken);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
- broken(VarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
- "VarCat: VT_DATE concat with VT_BSTR returned incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
+ broken(pVarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
+ "VarCat: VT_DATE concat with VT_BSTR returned incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_BSTR(&left) = SysAllocString(sz_empty);
V_BSTR(&right) = SysAllocString(sz_empty);
V_BSTR(&expected)= SysAllocString(sz_empty);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&left,lcid,0) == VARCMP_EQ,
- "VarCat: EMPTY concat with EMPTY did not return empty VT_BSTR\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&left,lcid,0) == VARCMP_EQ,
+ "VarCat: EMPTY concat with EMPTY did not return empty VT_BSTR\n");
/* Restore original date format settings */
SetLocaleInfo(lcid,LOCALE_SSHORTDATE,orig_date_format);
VariantClear(&right);
VariantClear(&result);
VariantClear(&expected);
+
+ /* Test boolean conversion */
+ V_VT(&left) = VT_BOOL;
+ V_BOOL(&left) = VARIANT_TRUE;
+ V_VT(&right) = VT_BSTR;
+ V_BSTR(&right) = SysAllocStringLen(NULL,0);
+ hres = pVarCat(&left, &right, &result);
+ ok(hres == S_OK, "VarCat failed: %08x\n", hres);
+ if(!strcmp_wa(V_BSTR(&result), "True")) {
+ V_VT(&right) = VT_BOOL;
+ V_BOOL(&right) = 100;
+ hres = pVarCat(&left, &right, &result);
+ ok(hres == S_OK, "VarCat failed: %08x\n", hres);
+ test_bstr_var(&result, "TrueTrue");
+ VariantClear(&result);
+
+ V_BOOL(&right) = VARIANT_FALSE;
+ hres = pVarCat(&left, &right, &result);
+ ok(hres == S_OK, "VarCat failed: %08x\n", hres);
+ test_bstr_var(&result, "TrueFalse");
+ VariantClear(&result);
+ }else {
+ skip("Got %s as True, assuming non-English locale\n", wine_dbgstr_w(V_BSTR(&result)));
+ }
}
static HRESULT (WINAPI *pVarAnd)(LPVARIANT,LPVARIANT,LPVARIANT);
SysFreeString(false_str);
}
-static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
-
static void test_cmp( int line, LCID lcid, UINT flags, VARIANT *left, VARIANT *right, HRESULT result )
{
HRESULT hres;
+ CHECKPTR(VarCmp);
+
hres = pVarCmp(left,right,lcid,flags);
ok_(__FILE__,line)(hres == result, "VarCmp(%s,%s): expected 0x%x, got hres=0x%x\n",
variantstr(left), variantstr(right), result, hres );
V_VT(&right) = VT_I8;
V_UI1(&right) = 2;
- hres = VarIdiv(&cy, &cy, &result);
+ hres = pVarIdiv(&cy, &cy, &result);
ok(hres == S_OK && V_VT(&result) == VT_I4,
"VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
if (HAVE_OLEAUT32_I8)
{
- hres = VarIdiv(&cy, &right, &result);
+ hres = pVarIdiv(&cy, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_I8,
"VARIDIV: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
(DWORD)(V_I8(&result) >>32), (DWORD)V_I8(&result), 5000);
}
- hres = VarIdiv(&left, &cy, &result);
+ hres = pVarIdiv(&left, &cy, &result);
ok(hres == S_OK && V_VT(&result) == VT_I4,
"VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
ok(hres == S_OK && V_I4(&result) == 0,
"VARIDIV: CY value %d, expected %d\n", V_I4(&result), 0);
- hres = VarIdiv(&left, &dec, &result);
+ hres = pVarIdiv(&left, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_I4,
"VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
ok(hres == S_OK && V_I4(&result) == 50,
"VARIDIV: DECIMAL value %d, expected %d\n", V_I4(&result), 50);
- hres = VarIdiv(&dec, &dec, &result);
+ hres = pVarIdiv(&dec, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_I4,
"VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
if (HAVE_OLEAUT32_I8)
{
- hres = VarIdiv(&dec, &right, &result);
+ hres = pVarIdiv(&dec, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_I8,
"VARIDIV: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
test_VarEqv();
test_VarMul();
test_VarAdd();
+ test_VarCmp(); /* Before test_VarCat() which needs VarCmp() */
test_VarCat();
- test_VarCmp();
test_VarAnd();
test_VarDiv();
test_VarIdiv();
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define CONST_VTABLE
+
#include "wine/test.h"
#include "oleauto.h"
#include <math.h>
/* Macros for converting and testing results */
#define CONVVARS(typ) HRESULT hres; CONV_TYPE out; typ in
+#define _EXPECT_NO_OUT(res) ok(hres == res, "expected " #res ", got hres=0x%08x\n", hres)
+#define EXPECT_OVERFLOW _EXPECT_NO_OUT(DISP_E_OVERFLOW)
+#define EXPECT_MISMATCH _EXPECT_NO_OUT(DISP_E_TYPEMISMATCH)
+#define EXPECT_BADVAR _EXPECT_NO_OUT(DISP_E_BADVARTYPE)
+#define EXPECT_INVALID _EXPECT_NO_OUT(E_INVALIDARG)
+#define EXPECT_LT _EXPECT_NO_OUT(VARCMP_LT)
+#define EXPECT_GT _EXPECT_NO_OUT(VARCMP_GT)
+#define EXPECT_EQ _EXPECT_NO_OUT(VARCMP_EQ)
+
#define _EXPECTRES(res, x, fs) \
- ok((hres == S_OK && out == (CONV_TYPE)(x)) || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
- "expected " #x ", got " fs "; hres=0x%08x\n", out, hres)
+ ok(hres == S_OK && out == (CONV_TYPE)(x), "expected " #x ", got " fs "; hres=0x%08x\n", out, hres)
#define EXPECT(x) EXPECTRES(S_OK, (x))
-#define EXPECT_OVERFLOW EXPECTRES(DISP_E_OVERFLOW, DISP_E_OVERFLOW)
-#define EXPECT_MISMATCH EXPECTRES(DISP_E_TYPEMISMATCH,DISP_E_TYPEMISMATCH)
-#define EXPECT_BADVAR EXPECTRES(DISP_E_BADVARTYPE, DISP_E_BADVARTYPE)
-#define EXPECT_INVALID EXPECTRES(E_INVALIDARG, E_INVALIDARG)
-#define EXPECT_LT EXPECTRES(VARCMP_LT, VARCMP_LT)
-#define EXPECT_GT EXPECTRES(VARCMP_GT, VARCMP_GT)
-#define EXPECT_EQ EXPECTRES(VARCMP_EQ, VARCMP_EQ)
#define EXPECT_DBL(x) \
ok(hres == S_OK && fabs(out-(x))<=1e-14*(x), "expected %16.16g, got %16.16g; hres=0x%08x\n", (x), out, hres)
ok(hres == S_OK && V_VT(&vDst) == typ && (CONV_TYPE)res == in, \
"hres=0x%X, type=%d (should be %d(" #typ ")), value=%d (should be 1)\n", \
hres, V_VT(&vDst), typ, (int)res);
-#define BADVAR(typ) CHANGETYPEEX(typ); out = (CONV_TYPE)hres; EXPECT_BADVAR
-#define MISMATCH(typ) CHANGETYPEEX(typ); out = (CONV_TYPE)hres; EXPECT_MISMATCH
+#define BADVAR(typ) CHANGETYPEEX(typ); EXPECT_BADVAR
+#define MISMATCH(typ) CHANGETYPEEX(typ); EXPECT_MISMATCH
#define INITIAL_TYPETEST(vt, val, fs) \
VariantInit(&vSrc); \
static HRESULT (WINAPI *pVarBstrFromCy)(CY,LCID,ULONG,BSTR*);
static HRESULT (WINAPI *pVarBstrFromDec)(DECIMAL*,LCID,ULONG,BSTR*);
static HRESULT (WINAPI *pVarBstrCmp)(BSTR,BSTR,LCID,ULONG);
+static HRESULT (WINAPI *pVarBstrCat)(BSTR,BSTR,BSTR*);
static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
static void (WINAPI *pClearCustData)(LPCUSTDATA);
typedef struct
{
- const IDispatchVtbl *lpVtbl;
+ IDispatch IDispatch_iface;
LONG ref;
VARTYPE vt;
BOOL bFailInvoke;
static DummyDispatch dispatch;
+static inline DummyDispatch *impl_from_IDispatch(IDispatch *iface)
+{
+ return CONTAINING_RECORD(iface, DummyDispatch, IDispatch_iface);
+}
+
static ULONG WINAPI DummyDispatch_AddRef(LPDISPATCH iface)
{
+ DummyDispatch *This = impl_from_IDispatch(iface);
+
trace("AddRef(%p)\n", iface);
- return InterlockedIncrement(&((DummyDispatch*)iface)->ref);
+ return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI DummyDispatch_Release(LPDISPATCH iface)
{
+ DummyDispatch *This = impl_from_IDispatch(iface);
+
trace("Release(%p)\n", iface);
- return InterlockedDecrement(&((DummyDispatch*)iface)->ref);
+ return InterlockedDecrement(&This->ref);
}
static HRESULT WINAPI DummyDispatch_QueryInterface(LPDISPATCH iface,
DummyDispatch_Invoke
};
-static DummyDispatch dispatch = { &DummyDispatch_VTable, 1, 0, 0 };
+static DummyDispatch dispatch = { { &DummyDispatch_VTable }, 1, 0, 0 };
/*
* VT_I1/VT_UI1
static void test_VarI1ChangeTypeEx(void)
{
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ signed char in;
VARIANTARG vSrc, vDst;
in = 1;
VariantInit(&vDst);
V_VT(&vSrc) = VT_DISPATCH;
- V_DISPATCH(&vSrc) = (IDispatch*)&dispatch;
+ V_DISPATCH(&vSrc) = &dispatch.IDispatch_iface;
dispatch.vt = VT_UI1;
dispatch.bFailInvoke = FALSE;
- hres = pVarUI1FromDisp((IDispatch*)&dispatch, in, &out);
+ hres = pVarUI1FromDisp(&dispatch.IDispatch_iface, in, &out);
trace("0x%08x\n", hres);
hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_UI1);
dispatch.bFailInvoke = TRUE;
- hres = pVarUI1FromDisp((IDispatch*)&dispatch, in, &out);
+ hres = pVarUI1FromDisp(&dispatch.IDispatch_iface, in, &out);
trace("0x%08x\n", hres);
hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_UI1);
static void test_VarUI1ChangeTypeEx(void)
{
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ BYTE in;
VARIANTARG vSrc, vDst;
in = 1;
#undef CONV_TYPE
#define CONV_TYPE SHORT
-#undef EXPECTRES
-#define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
static void test_VarI2FromI1(void)
{
static void test_VarI2ChangeTypeEx(void)
{
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ SHORT in;
VARIANTARG vSrc, vDst;
in = 1;
static void test_VarUI2ChangeTypeEx(void)
{
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ USHORT in;
VARIANTARG vSrc, vDst;
in = 1;
#undef CONV_TYPE
#define CONV_TYPE LONG
-#undef EXPECTRES
-#define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
-
static void test_VarI4FromI1(void)
{
static void test_VarI4ChangeTypeEx(void)
{
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ LONG in;
VARIANTARG vSrc, vDst;
in = 1;
static void test_VarUI4ChangeTypeEx(void)
{
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ ULONG in;
VARIANTARG vSrc, vDst;
in = 1;
#undef CONV_TYPE
#define CONV_TYPE LONG64
-#undef EXPECTRES
-#define EXPECTRES(res, x) \
- ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
- "expected hres " #x ", got hres=0x%08x\n", hres)
#define EXPECTI8(x) \
ok((hres == S_OK && out == (CONV_TYPE)(x)), \
static void test_VarI8ChangeTypeEx(void)
{
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ LONG64 in;
VARIANTARG vSrc, vDst;
if (!HAVE_OLEAUT32_I8)
int i;
CHECKPTR(VarUI8FromBool);
- CONVERTRANGE(VarUI8FromBool, -32768, 32768);
+ for (i = -32768; i < 32768; i++)
+ {
+ CONVERT(VarUI8FromBool, i); EXPECTI8(i);
+ }
}
static void test_VarUI8FromI8(void)
CHECKPTR(VarUI8FromStr);
- CONVERT_STR(VarUI8FromStr,NULL,0); EXPECT_MISMATCH;
- CONVERT_STR(VarUI8FromStr,"0",0); EXPECTI8(0);
- CONVERT_STR(VarUI8FromStr,"-1",0); EXPECT_OVERFLOW;
- CONVERT_STR(VarUI8FromStr,"2147483647",0); EXPECTI8(2147483647);
+ CONVERT_STR(VarUI8FromStr,NULL,0); EXPECT_MISMATCH;
+ CONVERT_STR(VarUI8FromStr,"0",0); EXPECTI8(0);
+ CONVERT_STR(VarUI8FromStr,"-1",0); EXPECT_OVERFLOW;
+ CONVERT_STR(VarUI8FromStr,"2147483647",0); EXPECTI8(2147483647);
+ CONVERT_STR(VarUI8FromStr,"18446744073709551614",0); EXPECTI864(0xFFFFFFFF,0xFFFFFFFE);
+ CONVERT_STR(VarUI8FromStr,"18446744073709551615",0); EXPECTI864(0xFFFFFFFF,0xFFFFFFFF);
+ CONVERT_STR(VarUI8FromStr,"18446744073709551616",0); EXPECT_OVERFLOW;
CONVERT_STR(VarUI8FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
CONVERT_STR(VarUI8FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
static void test_VarUI8ChangeTypeEx(void)
{
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ ULONG64 in;
VARIANTARG vSrc, vDst;
if (!HAVE_OLEAUT32_I8)
static void test_VarR4ChangeTypeEx(void)
{
#ifdef HAS_UINT64_TO_FLOAT
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ float in;
VARIANTARG vSrc, vDst;
in = 1.0f;
#undef CONV_TYPE
#define CONV_TYPE double
-#undef EXPECTRES
-#define EXPECTRES(res, x) _EXPECTRES(res, x, "%15.15f")
static void test_VarR8FromI1(void)
{
static void test_VarR8ChangeTypeEx(void)
{
#ifdef HAS_UINT64_TO_FLOAT
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ double in;
VARIANTARG vSrc, vDst;
in = 1.0;
DFS("1 2 1970"); EXPECT_DBL(25570.0);
DFS("1/2/1970"); EXPECT_DBL(25570.0);
DFS("1-2-1970"); EXPECT_DBL(25570.0);
+ DFS("13-1-1970"); EXPECT_DBL(25581.0);
+ DFS("1970-1-13"); EXPECT_DBL(25581.0);
/* Native fails "1999 January 3, 9AM". I consider that a bug in native */
/* test a non-english data string */
DFS("02.01.1970 00:00:00"); EXPECT_MISMATCH;
lcid = MAKELCID(MAKELANGID(LANG_GERMAN,SUBLANG_GERMAN),SORT_DEFAULT);
DFS("02.01.1970"); EXPECT_DBL(25570.0);
+ DFS("02.13.1970"); EXPECT_DBL(25612.0);
+ DFS("02-13-1970"); EXPECT_DBL(25612.0);
+ DFS("2020-01-11"); EXPECT_DBL(43841.0);
+ DFS("2173-10-14"); EXPECT_DBL(100000.0);
+
DFS("02.01.1970 00:00:00"); EXPECT_DBL(25570.0);
lcid = MAKELCID(MAKELANGID(LANG_SPANISH,SUBLANG_SPANISH),SORT_DEFAULT);
DFS("02.01.1970"); EXPECT_MISMATCH;
'1','/','2','/','7','0','\0' };
static const WCHAR sz25570Nls[] = {
'1','/','2','/','1','9','7','0',' ','1','2',':','0','0',':','0','0',' ','A','M','\0' };
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ DATE in;
VARIANTARG vSrc, vDst;
LCID lcid;
#undef CONV_TYPE
#define CONV_TYPE CY
-#undef EXPECTRES
-#define EXPECTRES(res, x) \
- ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
- "expected hres " #x ", got hres=0x%08x\n", hres)
#define EXPECTCY(x) \
ok((hres == S_OK && out.int64 == (LONGLONG)(x*CY_MULTIPLIER)), \
CONVERT(VarCyFromUI8, 0); EXPECTCY(0);
CONVERT(VarCyFromUI8, 1); EXPECTCY(1);
CONVERT_I8(VarCyFromUI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
- CONVERT_I8(VarCyFromUI8, 214748, 1566804069); EXPECT_OVERFLOW;
+ CONVERT_I8(VarCyFromUI8, 214748, 1566804069); EXPECTCY64(2147483647ul, 4294961488ul);
+ CONVERT_I8(VarCyFromUI8, 214748, 1566804070); EXPECT_OVERFLOW;
+ CONVERT_I8(VarCyFromUI8, 214749, 1566804068); EXPECT_OVERFLOW;
}
static void test_VarCyFromDec(void)
CONVERT_DEC(VarCyFromDec,0,0,0,1); EXPECTCY(1);
CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
- CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804069); EXPECT_OVERFLOW;
+ CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804069); EXPECTCY64(2147483647ul, 4294961488ul);
+ CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804070); EXPECT_OVERFLOW;
+ CONVERT_DEC64(VarCyFromDec,0,0,0,214749, 1566804068); EXPECT_OVERFLOW;
CONVERT_DEC(VarCyFromDec,2,0,0,100); EXPECTCY(1);
CONVERT_DEC(VarCyFromDec,2,0x80,0,100); EXPECTCY(-1);
}
#define MATHCMP(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
- hres = pVarCyCmp(cyLeft, cyRight); out.int64 = hres
+ hres = pVarCyCmp(cyLeft, cyRight)
static void test_VarCyCmp(void)
{
- MATHVARS2;
+ HRESULT hres;
+ double left = 0.0, right = 0.0;
+ CY cyLeft, cyRight;
CHECKPTR(VarCyCmp);
MATHCMP(-1.0, -1.0); EXPECT_EQ;
}
#define MATHCMPR8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
- hres = pVarCyCmpR8(cyLeft, right); out.int64 = hres
+ hres = pVarCyCmpR8(cyLeft, right);
static void test_VarCyCmpR8(void)
{
- MATHVARS1;
+ HRESULT hres;
+ double left = 0.0;
+ CY cyLeft;
double right;
CHECKPTR(VarCyCmpR8);
#undef CONV_TYPE
#define CONV_TYPE DECIMAL
-#undef EXPECTRES
-#define EXPECTRES(res, x) \
- ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
- "expected hres " #x ", got hres=0x%08x\n", hres)
#define EXPECTDEC(scl, sgn, hi, lo) ok(hres == S_OK && \
S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
#undef CONV_TYPE
#define CONV_TYPE VARIANT_BOOL
-#undef _EXPECTRES
-#define _EXPECTRES(res, x, fs) \
- ok((hres == S_OK && out == (CONV_TYPE)(x)) || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
- "expected " #x ", got " fs "; hres=0x%08x\n", out, hres)
#undef EXPECTRES
#define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
#undef CONVERTRANGE
static const WCHAR szTrue[] = { 'T','r','u','e','\0' };
static const WCHAR szFalse[] = { 'F','a','l','s','e','\0' };
static const WCHAR szFaux[] = { 'F','a','u','x','\0' };
- CONVVARS(CONV_TYPE);
+ HRESULT hres;
+ VARIANT_BOOL in;
VARIANTARG vSrc, vDst;
LCID lcid;
}
}
-#define BSTR_DATE(dt,str) \
- bstr = NULL; \
- hres = pVarBstrFromDate(dt,lcid,LOCALE_NOUSEROVERRIDE,&bstr); \
- if (bstr) {WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0); SysFreeString(bstr);} \
- else buff[0] = 0; \
- ok(hres == S_OK && !strcmp(str,buff), "Expected '%s', got '%s', hres = 0x%08x\n", \
- str, buff, hres)
-
-static void test_VarBstrFromDate(void)
+static void _BSTR_DATE(DATE dt, const char *str, int line)
{
+ LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
char buff[256];
- LCID lcid;
+ BSTR bstr = NULL;
HRESULT hres;
- BSTR bstr;
+
+ hres = pVarBstrFromDate(dt, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
+ if (bstr)
+ {
+ WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
+ SysFreeString(bstr);
+ }
+ else
+ buff[0] = 0;
+ ok_(__FILE__, line)(hres == S_OK && !strcmp(str, buff),
+ "Expected '%s', got '%s', hres = 0x%08x\n", str, buff, hres);
+}
+
+static void test_VarBstrFromDate(void)
+{
+#define BSTR_DATE(dt,str) _BSTR_DATE(dt,str,__LINE__)
CHECKPTR(VarBstrFromDate);
- lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
BSTR_DATE(0.0, "12:00:00 AM");
BSTR_DATE(3.34, "1/2/1900 8:09:36 AM");
BSTR_DATE(1461.5, "12/31/1903 12:00:00 PM");
todo_wine { BSTR_DATE(-657434.0, "1/1/100"); }
BSTR_DATE(2958465.0, "12/31/9999");
-}
-#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));\
- SysFreeString(bstr);\
- }
+#undef BSTR_DATE
+}
-static void test_VarBstrFromCy(void)
+static void _BSTR_CY(LONG a, LONG b, const char *str, LCID lcid, int line)
{
- LCID lcid;
- HRESULT hres;
+ HRESULT hr;
BSTR bstr = NULL;
+ char buff[256];
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);
+ S(l).Lo = b;
+ S(l).Hi = a;
+ hr = pVarBstrFromCy(l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
+ ok(hr == S_OK, "got hr 0x%08x\n", hr);
- /* check one point five */
- BSTR_CY(l, 0, 15000, szOnePointFive);
-
- /* check minus one point five */
- BSTR_CY(l, 0xffffffff, ((15000)^0xffffffff)+1, szMinusOnePointFive);
+ if(bstr)
+ {
+ WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
+ SysFreeString(bstr);
+ }
+ else
+ buff[0] = 0;
- /* check bignum (1) */
- BSTR_CY(l, 0, 0xffffffff, szBigNum1);
+ if(hr == S_OK)
+ {
+ ok_(__FILE__, line)(!strcmp(str, buff), "Expected '%s', got '%s'\n", str, buff);
+ }
+}
- /* check bignum (2) */
- BSTR_CY(l, 1,0, szBigNum2);
+static void test_VarBstrFromCy(void)
+{
+#define BSTR_CY(a, b, str, lcid) _BSTR_CY(a, b, str, lcid, __LINE__)
- /* check bignum (3) */
- BSTR_CY(l, 0x7fffffff,0xffffffff, szBigNum3);
+ LCID en_us, sp;
- /* check leading zeros and decimal sep. for English locale */
- BSTR_CY(l, 0,9, szSmallNumber_English);
+ CHECKPTR(VarBstrFromCy);
- lcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
+ en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
+ sp = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
+
+ BSTR_CY(0, 0, "0", en_us);
+ BSTR_CY(0, 10000, "1", en_us);
+ BSTR_CY(0, 15000, "1.5", en_us);
+ BSTR_CY(0xffffffff, ((15000)^0xffffffff)+1, "-1.5", en_us);
+ /* (1 << 32) - 1 / 1000 */
+ BSTR_CY(0, 0xffffffff, "429496.7295", en_us);
+ /* (1 << 32) / 1000 */
+ BSTR_CY(1, 0, "429496.7296", en_us);
+ /* ((1 << 63) - 1)/10000 */
+ BSTR_CY(0x7fffffff, 0xffffffff, "922337203685477.5807", en_us);
+ BSTR_CY(0, 9, "0.0009", en_us);
+ BSTR_CY(0, 9, "0,0009", sp);
- /* check leading zeros and decimal sep. for Spanish locale */
- BSTR_CY(l, 0,9, szSmallNumber_Spanish);
+#undef BSTR_CY
}
-#undef BSTR_CY
+static void _BSTR_DEC(BYTE scale, BYTE sign, ULONG hi, ULONG mid, ULONGLONG lo, const char *str,
+ LCID lcid, int line)
+{
+ char buff[256];
+ HRESULT hr;
+ BSTR bstr = NULL;
+ DECIMAL dec;
+
+ SETDEC64(dec, scale, sign, hi, mid, lo);
+ hr = pVarBstrFromDec(&dec, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
+ ok_(__FILE__, line)(hr == S_OK, "got hr 0x%08x\n", hr);
-#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));\
- SysFreeString(bstr);\
+ if(bstr)
+ {
+ WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
+ SysFreeString(bstr);
}
+ else
+ buff[0] = 0;
-#define BSTR_DEC64(l, a, b, c, x, d, e) \
- SETDEC64(l, a,b,c,x,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));\
- SysFreeString(bstr);\
+ if(hr == S_OK)
+ {
+ ok_(__FILE__, line)(!strcmp(str, buff), "Expected '%s', got '%s'\n", str, buff);
}
+}
static void test_VarBstrFromDec(void)
{
- LCID lcid;
- HRESULT hres;
- BSTR bstr = NULL;
- DECIMAL l;
+#define BSTR_DEC(scale, sign, hi, lo, str, lcid) _BSTR_DEC(scale, sign, hi, 0, lo, str, lcid, __LINE__)
+#define BSTR_DEC64(scale, sign, hi, mid, lo, str, lcid) _BSTR_DEC(scale, sign, hi, mid, lo, str, lcid, __LINE__)
- 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 */
- static const WCHAR szBigNum2[] = {'4','2','9','4','9','6','7','2','9','6','\0'}; /* (1 << 32) */
- static const WCHAR szBigNum3[] = {'1','8','4','4','6','7','4','4','0','7','3','7','0','9','5','5','1','6','1','5','\0'}; /* (1 << 64) - 1 */
- static const WCHAR szBigNum4[] = {'1','8','4','4','6','7','4','4','0','7','3','7','0','9','5','5','1','6','1','6','\0'}; /* (1 << 64) */
- static const WCHAR szBigNum5[] = {'7','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','3','5','4','3','9','5','0','3','3','5','\0'}; /* (1 << 96) - 1 */
- static const WCHAR szBigScale1[] = {'0','.','0','0','0','0','0','0','0','0','0','1','\0'}; /* 1 * 10^-10 */
- static const WCHAR szBigScale2[] = {'7','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','.','3','5','4','3','9','5','0','3','3','5','\0'}; /* ((1 << 96) - 1) * 10^-10 */
- static const WCHAR szBigScale3[] = {'7','.','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','3','5','4','3','9','5','0','3','3','5','\0'}; /* ((1 << 96) - 1) * 10^-28 */
-
- static const WCHAR szSmallNumber_English[] = {'0','.','0','0','0','9','\0'};
- static const WCHAR szSmallNumber_Spanish[] = {'0',',','0','0','0','9','\0'};
+ LCID en_us, sp;
CHECKPTR(VarBstrFromDec);
- lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
-
- /* check zero */
- BSTR_DEC(l, 0,0,0,0, szZero);
-
- /* check one */
- BSTR_DEC(l, 0,0,0,1, szOne);
- BSTR_DEC(l, 1,0,0,10,szOne);
- BSTR_DEC(l, 2,0,0,100,szOne);
- BSTR_DEC(l, 3,0,0,1000,szOne);
- /* check one point five */
- BSTR_DEC(l, 1,0,0,15, szOnePointFive);
- BSTR_DEC(l, 2,0,0,150, szOnePointFive);
- BSTR_DEC(l, 3,0,0,1500, szOnePointFive);
-
- /* check minus one point five */
- BSTR_DEC(l, 1,0x80,0,15, szMinusOnePointFive);
-
- /* check bignum (1) */
- BSTR_DEC(l, 0,0,0,0xffffffff, szBigNum1);
-
- /* check bignum (2) */
- BSTR_DEC64(l, 0,0,0,1,0, szBigNum2);
-
- /* check bignum (3) */
- BSTR_DEC64(l, 0,0,0,0xffffffff,0xffffffff, szBigNum3);
-
- /* check bignum (4) */
- BSTR_DEC(l, 0,0,1,0, szBigNum4);
-
- /* check bignum (5) */
- BSTR_DEC64(l, 0,0,0xffffffff,0xffffffff,0xffffffff, szBigNum5);
-
- /* check bigscale (1) */
- BSTR_DEC(l, 10,0,0,1, szBigScale1);
-
- /* check bigscale (2) */
- BSTR_DEC64(l, 10,0,0xffffffffUL,0xffffffff,0xffffffff, szBigScale2);
-
- /* check bigscale (3) */
- BSTR_DEC64(l, 28,0,0xffffffffUL,0xffffffff,0xffffffff, szBigScale3);
+ en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
+ sp = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
+
+ BSTR_DEC(0,0,0,0, "0", en_us);
+
+ BSTR_DEC(0,0,0,1, "1", en_us);
+ BSTR_DEC(1,0,0,10, "1", en_us);
+ BSTR_DEC(2,0,0,100, "1", en_us);
+ BSTR_DEC(3,0,0,1000,"1", en_us);
+
+ BSTR_DEC(1,0,0,15, "1.5", en_us);
+ BSTR_DEC(2,0,0,150, "1.5", en_us);
+ BSTR_DEC(3,0,0,1500,"1.5", en_us);
+
+ BSTR_DEC(1,0x80,0,15, "-1.5", en_us);
+
+ /* (1 << 32) - 1 */
+ BSTR_DEC(0,0,0,0xffffffff, "4294967295", en_us);
+ /* (1 << 32) */
+ BSTR_DEC64(0,0,0,1,0, "4294967296", en_us);
+ /* (1 << 64) - 1 */
+ BSTR_DEC64(0,0,0,0xffffffff,0xffffffff, "18446744073709551615", en_us);
+ /* (1 << 64) */
+ BSTR_DEC(0,0,1,0, "18446744073709551616", en_us);
+ /* (1 << 96) - 1 */
+ BSTR_DEC64(0,0,0xffffffff,0xffffffff,0xffffffff, "79228162514264337593543950335", en_us);
+ /* 1 * 10^-10 */
+ BSTR_DEC(10,0,0,1, "0.0000000001", en_us);
+ /* ((1 << 96) - 1) * 10^-10 */
+ BSTR_DEC64(10,0,0xffffffffUL,0xffffffff,0xffffffff, "7922816251426433759.3543950335", en_us);
+ /* ((1 << 96) - 1) * 10^-28 */
+ BSTR_DEC64(28,0,0xffffffffUL,0xffffffff,0xffffffff, "7.9228162514264337593543950335", en_us);
/* check leading zeros and decimal sep. for English locale */
- BSTR_DEC(l, 4,0,0,9, szSmallNumber_English);
- BSTR_DEC(l, 5,0,0,90, szSmallNumber_English);
- BSTR_DEC(l, 6,0,0,900, szSmallNumber_English);
- BSTR_DEC(l, 7,0,0,9000, szSmallNumber_English);
-
- lcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
+ BSTR_DEC(4,0,0,9, "0.0009", en_us);
+ BSTR_DEC(5,0,0,90, "0.0009", en_us);
+ BSTR_DEC(6,0,0,900, "0.0009", en_us);
+ BSTR_DEC(7,0,0,9000, "0.0009", en_us);
/* check leading zeros and decimal sep. for Spanish locale */
- BSTR_DEC(l, 4,0,0,9, szSmallNumber_Spanish);
- BSTR_DEC(l, 5,0,0,90, szSmallNumber_Spanish);
- BSTR_DEC(l, 6,0,0,900, szSmallNumber_Spanish);
- BSTR_DEC(l, 7,0,0,9000, szSmallNumber_Spanish);
-}
+ BSTR_DEC(4,0,0,9, "0,0009", sp);
+ BSTR_DEC(5,0,0,90, "0,0009", sp);
+ BSTR_DEC(6,0,0,900, "0,0009", sp);
+ BSTR_DEC(7,0,0,9000, "0,0009", sp);
+
#undef BSTR_DEC
#undef BSTR_DEC64
+}
#define _VARBSTRCMP(left,right,lcid,flags,result) \
hres = pVarBstrCmp(left,right,lcid,flags); \
SysFreeString(bstr);
bstr = SysAllocStringByteLen(sbchr0, sizeof(sbchr0));
- bstr2 = SysAllocStringByteLen(sbchr0, sizeof(sbchr00));
+ bstr2 = SysAllocStringByteLen(sbchr00, sizeof(sbchr00));
VARBSTRCMP(bstr,bstrempty,0,VARCMP_GT);
VARBSTRCMP(bstrempty,bstr,0,VARCMP_LT);
VARBSTRCMP(bstr2,bstrempty,0,VARCMP_GT);
SysFreeString(bstr);
bstr = SysAllocStringByteLen(sbchr0, sizeof(sbchr0));
- bstr2 = SysAllocStringByteLen(sbchr0, sizeof(sbchr00));
+ bstr2 = SysAllocStringByteLen(sbchr00, sizeof(sbchr00));
VARBSTRCMP(bstr,bstrempty,0,VARCMP_GT);
VARBSTRCMP(bstrempty,bstr,0,VARCMP_LT);
VARBSTRCMP(bstr2,bstrempty,0,VARCMP_GT);
BSTR str1, str2, res;
UINT len;
+ CHECKPTR(VarBstrCat);
+
if (0)
{
/* Crash */
- ret = VarBstrCat(NULL, NULL, NULL);
+ pVarBstrCat(NULL, NULL, NULL);
}
/* Concatenation of two NULL strings works */
- ret = VarBstrCat(NULL, NULL, &res);
+ ret = pVarBstrCat(NULL, NULL, &res);
ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
ok(res != NULL, "Expected a string\n");
ok(SysStringLen(res) == 0, "Expected a 0-length string\n");
str1 = SysAllocString(sz1);
/* Concatenation with one NULL arg */
- ret = VarBstrCat(NULL, str1, &res);
+ ret = pVarBstrCat(NULL, str1, &res);
ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
ok(res != NULL, "Expected a string\n");
ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n");
ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n");
SysFreeString(res);
- ret = VarBstrCat(str1, NULL, &res);
+ ret = pVarBstrCat(str1, NULL, &res);
ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
ok(res != NULL, "Expected a string\n");
ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n");
/* Concatenation of two zero-terminated strings */
str2 = SysAllocString(sz2);
- ret = VarBstrCat(str1, str2, &res);
+ ret = pVarBstrCat(str1, str2, &res);
ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
ok(res != NULL, "Expected a string\n");
ok(SysStringLen(res) == sizeof(sz1sz2) / sizeof(WCHAR) - 1,
str1 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR));
str2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR));
- ret = VarBstrCat(str1, str2, &res);
+ ret = pVarBstrCat(str1, str2, &res);
ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
ok(res != NULL, "Expected a string\n");
ok(SysStringLen(res) == sizeof(s1s2) / sizeof(WCHAR),
len = SysStringLen(str2);
ok(len == (sizeof(str2A)-1)/sizeof(WCHAR), "got length %u\n", len);
- ret = VarBstrCat(str1, str2, &res);
+ ret = pVarBstrCat(str1, str2, &res);
ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
ok(res != NULL, "Expected a string\n");
len = (sizeof(str1A) + sizeof(str2A) - 2)/sizeof(WCHAR);
len = SysStringLen(str2);
ok(len == 0, "got length %u\n", len);
- ret = VarBstrCat(str1, str2, &res);
+ ret = pVarBstrCat(str1, str2, &res);
ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
ok(res != NULL, "Expected a string\n");
ok(SysStringLen(res) == 1, "got %d, expected 1\n", SysStringLen(res));
{
HRESULT hres;
VARIANTARG v;
- DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
- IUnknown* pu = (IUnknown*)&u;
+ DummyDispatch u = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
+ IUnknown* pu = (IUnknown*)&u.IDispatch_iface;
/* Test that IUnknown_Release is called on by-value */
V_VT(&v) = VT_UNKNOWN;
- V_UNKNOWN(&v) = (IUnknown*)&u;
+ V_UNKNOWN(&v) = (IUnknown*)&u.IDispatch_iface;
hres = VariantClear(&v);
ok(hres == S_OK && u.ref == 0 && V_VT(&v) == VT_EMPTY,
"clear unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
{
HRESULT hres;
VARIANTARG vSrc, vDst;
- DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
- IUnknown* pu = (IUnknown*)&u;
+ DummyDispatch u = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
+ IUnknown* pu = (IUnknown*)&u.IDispatch_iface;
/* AddRef is called on by-value copy */
VariantInit(&vDst);
VARIANTARG vSrc, vDst;
LCID lcid;
VARTYPE vt;
- DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
- IUnknown* pu = (IUnknown*)&u;
+ DummyDispatch u = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
+ IUnknown* pu = (IUnknown*)&u.IDispatch_iface;
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
{
HRESULT hres;
VARIANTARG v;
- DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
- IDispatch* pd = (IDispatch*)&d;
+ DummyDispatch d = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
+ IDispatch* pd = &d.IDispatch_iface;
/* As per IUnknown */
{
HRESULT hres;
VARIANTARG vSrc, vDst;
- DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
- IDispatch* pd = (IDispatch*)&d;
+ DummyDispatch d = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
+ IDispatch* pd = &d.IDispatch_iface;
/* As per IUnknown */
HRESULT hres;
VARIANTARG vSrc, vDst;
LCID lcid;
- DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
- IDispatch* pd = (IDispatch*)&d;
+ DummyDispatch d = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
+ IDispatch* pd = &d.IDispatch_iface;
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
V_INT(&v2) = 4;
hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_INT);
ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08x\n", hres);
- ok(V_VT(&v2) == VT_INT && V_INT(&v2) == 4, "VariantChangeTypeEx changed dst variant\n");
+ ok(V_VT(&v2) == VT_INT && V_INT(&v2) == 4, "VariantChangeTypeEx changed dst variant\n");
SysFreeString(bstr);
}
{
hOleaut32 = GetModuleHandleA("oleaut32.dll");
- trace("LCID's: System=0x%08x, User=0x%08x\n", GetSystemDefaultLCID(),
+ trace("LCIDs: System=0x%08x, User=0x%08x\n", GetSystemDefaultLCID(),
GetUserDefaultLCID());
test_VarI1FromI2();