[OLEAUT32_WINETEST]

* Sync with Wine 1.5.19.

svn path=/trunk/; revision=57892
This commit is contained in:
Amine Khaldi
2012-12-12 15:05:13 +00:00
parent 7e47495621
commit 74b1cd4a03
12 changed files with 2745 additions and 1097 deletions
+4 -9
View File
@@ -1,14 +1,9 @@
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
@@ -17,15 +12,15 @@ list(APPEND SOURCE
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)
+188 -137
View File
@@ -51,14 +51,14 @@ static HMODULE hOleaut32;
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)
{
@@ -69,9 +69,10 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size,
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;
@@ -87,32 +88,33 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size,
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);
@@ -120,35 +122,68 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size,
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;
hres = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
font = pvObj;
hr = pOleCreateFontIndirect(NULL, &IID_IFont, NULL);
EXPECT_HR(hr, E_POINTER);
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");
hr = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
font = pvObj;
pvObj = NULL;
hres = IFont_QueryInterface( font, &IID_IFont, &pvObj);
EXPECT_HR(hr, S_OK);
ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n");
/* 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);
pvObj = NULL;
hr = IFont_QueryInterface( font, &IID_IFont, &pvObj);
EXPECT_HR(hr, S_OK);
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");
/* 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);
/* Original ref and QueryInterface ref both have to be released */
IFont_Release(font);
IFont_Release(font);
ok(pvObj != NULL,"IFont_QI does return NULL, instead of a ptr\n");
IFont_Release(font);
IFont_Release(font);
}
static void test_type_info(void)
@@ -201,7 +236,7 @@ static HRESULT WINAPI FontEventsDisp_QueryInterface(
{
if (IsEqualIID(riid, &IID_IFontEventsDisp) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
{
IUnknown_AddRef(iface);
IFontEventsDisp_AddRef(iface);
*ppvObject = iface;
return S_OK;
}
@@ -284,26 +319,26 @@ static void test_font_events_disp(void)
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;
@@ -312,6 +347,7 @@ static void test_font_events_disp(void)
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);
@@ -319,11 +355,11 @@ static void test_font_events_disp(void)
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",
@@ -450,7 +486,7 @@ static void test_Invoke(void)
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;
@@ -459,32 +495,32 @@ static void test_Invoke(void)
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);
}
@@ -812,27 +848,19 @@ static void test_returns(void)
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);
}
@@ -857,10 +885,10 @@ static void test_hfont_lifetime(void)
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 */
@@ -874,14 +902,14 @@ static void test_hfont_lifetime(void)
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);
@@ -891,20 +919,19 @@ static void test_hfont_lifetime(void)
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);
@@ -920,10 +947,10 @@ static void test_hfont_lifetime(void)
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++)
{
@@ -935,20 +962,20 @@ static void test_hfont_lifetime(void)
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);
@@ -965,13 +992,13 @@ static void test_hfont_lifetime(void)
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);
@@ -988,23 +1015,23 @@ static void test_hfont_lifetime(void)
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);
@@ -1041,10 +1068,10 @@ static void test_realization(void)
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);
@@ -1054,62 +1081,86 @@ static void test_realization(void)
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;
}
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();
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();
}
+310 -68
View File
@@ -2,7 +2,7 @@
* 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
@@ -25,6 +25,7 @@
#include <float.h>
#define COBJMACROS
#define CONST_VTABLE
#define NONAMELESSUNION
#include "wine/test.h"
@@ -53,7 +54,7 @@
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)
@@ -169,17 +170,17 @@ static const unsigned char enhmetafile[] = {
};
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)
@@ -219,7 +220,7 @@ 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");
}
@@ -282,7 +283,7 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize)
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);
@@ -313,7 +314,7 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize)
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);
@@ -481,24 +482,26 @@ static void test_Invoke(void)
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);
@@ -518,7 +521,7 @@ static void test_apm(void)
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;
}
@@ -527,7 +530,7 @@ static void test_apm(void)
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");
@@ -562,7 +565,7 @@ static void test_metafile(void)
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);
}
@@ -579,7 +582,7 @@ static void test_enhmetafile(void)
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;
}
@@ -588,7 +591,7 @@ static void test_enhmetafile(void)
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");
@@ -675,9 +678,9 @@ static void test_Render(void)
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);
@@ -800,9 +803,8 @@ static void test_OleLoadPicturePath(void)
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);
@@ -811,9 +813,8 @@ static void test_OleLoadPicturePath(void)
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);
@@ -831,7 +832,7 @@ static void test_OleLoadPicturePath(void)
/* 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);
@@ -839,7 +840,7 @@ static void test_OleLoadPicturePath(void)
/* 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);
@@ -849,14 +850,14 @@ static void test_OleLoadPicturePath(void)
/* 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,
@@ -875,7 +876,7 @@ static void test_OleLoadPicturePath(void)
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);
@@ -885,35 +886,267 @@ static void test_OleLoadPicturePath(void)
/* 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();
@@ -921,12 +1154,21 @@ START_TEST(olepicture)
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);
@@ -937,7 +1179,7 @@ static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
static ULONG WINAPI NoStatStreamImpl_AddRef(
IStream* iface)
{
NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
NoStatStreamImpl* const This = impl_from_IStream(iface);
return InterlockedIncrement(&This->ref);
}
@@ -946,7 +1188,7 @@ static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
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))
@@ -967,7 +1209,7 @@ static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
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);
@@ -980,7 +1222,7 @@ static HRESULT WINAPI NoStatStreamImpl_Read(
ULONG cb, /* [in] */
ULONG* pcbRead) /* [out] */
{
NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
NoStatStreamImpl* const This = impl_from_IStream(iface);
void* supportBuffer;
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
@@ -1004,7 +1246,7 @@ static HRESULT WINAPI NoStatStreamImpl_Write(
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;
@@ -1032,7 +1274,7 @@ static HRESULT WINAPI NoStatStreamImpl_Seek(
DWORD dwOrigin, /* [in] */
ULARGE_INTEGER* plibNewPosition) /* [out] */
{
NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
NoStatStreamImpl* const This = impl_from_IStream(iface);
ULARGE_INTEGER newPosition;
switch (dwOrigin)
{
@@ -1061,7 +1303,7 @@ static HRESULT WINAPI NoStatStreamImpl_SetSize(
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;
@@ -1174,14 +1416,14 @@ static const IStreamVtbl NoStatStreamImpl_Vtbl;
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;
@@ -1193,7 +1435,7 @@ static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal)
newStream->streamSize.u.HighPart = 0;
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
}
return newStream;
return &newStream->IStream_iface;
}
+178 -79
View File
@@ -25,6 +25,7 @@
#include <float.h>
#define COBJMACROS
#define CONST_VTABLE
#include "wine/test.h"
#include "windef.h"
#include "winbase.h"
@@ -76,7 +77,7 @@ static BOOL HAVE_OLEAUT32_INT_PTR;
*/
typedef struct IRecordInfoImpl
{
const IRecordInfoVtbl *lpvtbl;
IRecordInfo IRecordInfo_iface;
LONG ref;
DWORD sizeCalled;
DWORD clearCalled;
@@ -84,12 +85,17 @@ typedef struct IRecordInfoImpl
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;
@@ -98,32 +104,39 @@ static IRecordInfoImpl *IRecordInfoImpl_Construct(void)
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;
}
@@ -211,9 +224,11 @@ static void check_for_VT_INT_PTR(void)
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");
@@ -279,7 +294,7 @@ static void test_safearray(void)
LONG indices[2];
HRESULT hres;
SAFEARRAYBOUND bound, bounds[2];
VARIANT v;
VARIANT v,d;
LPVOID data;
IID iid;
VARTYPE vt;
@@ -318,7 +333,7 @@ static void test_safearray(void)
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;
@@ -355,7 +370,7 @@ static void test_safearray(void)
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;
@@ -363,14 +378,14 @@ static void test_safearray(void)
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;
@@ -455,7 +470,7 @@ static void test_safearray(void)
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)
@@ -520,7 +535,7 @@ static void test_safearray(void)
}
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);
@@ -542,6 +557,15 @@ static void test_safearray(void)
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");
@@ -580,9 +604,10 @@ static void test_safearray(void)
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);
@@ -594,6 +619,7 @@ static void test_safearray(void)
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);
@@ -840,7 +866,10 @@ static void test_VectorCreateLockDestroy(void)
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");
@@ -933,7 +962,8 @@ test_LockUnlock_Vector:
bVector ? "vector " : "\n", count, hres);
}
SafeArrayDestroy(sa);
hres = SafeArrayDestroy(sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
}
if (bVector == FALSE && pSafeArrayCreateVector)
@@ -1068,7 +1098,8 @@ static void test_SafeArrayGetPutElement(void)
}
}
}
SafeArrayDestroy(sa);
hres = SafeArrayDestroy(sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
}
static void test_SafeArrayGetPutElement_BSTR(void)
@@ -1102,21 +1133,33 @@ 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;
}
static ULONG WINAPI tunk_AddRef(LPUNKNOWN punk) {
return ++tunk_xref;
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_Release(LPUNKNOWN punk) {
return --tunk_xref;
static ULONG WINAPI tunk_AddRef(IUnknown *punk)
{
return ++xtunk.ref;
}
static ULONG WINAPI tunk_Release(IUnknown *punk)
{
return --xtunk.ref;
}
static const IUnknownVtbl xtunk_vtbl = {
@@ -1125,18 +1168,13 @@ 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;
@@ -1150,21 +1188,19 @@ static void test_SafeArrayGetPutElement_IUnknown(void)
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)
@@ -1173,7 +1209,6 @@ static void test_SafeArrayRedim_IUnknown(void)
LONG indices[1];
SAFEARRAY *sa;
HRESULT hres;
LPUNKNOWN value;
sab.lLbound = 1;
sab.cElements = 2;
@@ -1187,17 +1222,16 @@ static void test_SafeArrayRedim_IUnknown(void)
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)
@@ -1237,7 +1271,8 @@ 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);
}
@@ -1250,7 +1285,10 @@ static void test_SafeArrayCopyData(void)
int dimension,size=1;
if (!pSafeArrayCopyData)
{
win_skip("SafeArrayCopyData not supported\n");
return;
}
for (dimension = 0; dimension < NUM_DIMENSIONS; dimension++)
{
@@ -1309,7 +1347,8 @@ static void test_SafeArrayCopyData(void)
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);
@@ -1321,10 +1360,12 @@ static void test_SafeArrayCopyData(void)
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)
@@ -1336,7 +1377,10 @@ static void test_SafeArrayCreateEx(void)
int dimension;
if (!pSafeArrayCreateEx)
{
win_skip("SafeArrayCreateEx not supported\n");
return;
}
for (dimension = 0; dimension < NUM_DIMENSIONS; dimension++)
{
@@ -1374,7 +1418,8 @@ static void test_SafeArrayCreateEx(void)
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);
@@ -1392,7 +1437,8 @@ static void test_SafeArrayCreateEx(void)
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);
@@ -1410,12 +1456,13 @@ static void test_SafeArrayCreateEx(void)
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();
@@ -1429,8 +1476,10 @@ static void test_SafeArrayCreateEx(void)
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 */
@@ -1449,18 +1498,26 @@ static void test_SafeArrayCreateEx(void)
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)
@@ -1499,7 +1556,8 @@ 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)
@@ -1535,22 +1593,43 @@ 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; \
@@ -1586,7 +1665,8 @@ static void test_SafeArrayChangeTypeEx(void)
}
/* 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);
@@ -1616,16 +1696,33 @@ static void test_SafeArrayChangeTypeEx(void)
}
/* 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
@@ -1644,7 +1741,8 @@ static void test_SafeArrayChangeTypeEx(void)
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)
@@ -1653,7 +1751,8 @@ static void test_SafeArrayChangeTypeEx(void)
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);
}
@@ -1666,7 +1765,6 @@ static void test_SafeArrayChangeTypeEx(void)
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)
@@ -1718,6 +1816,7 @@ START_TEST(safearray)
GETPTR(SafeArrayGetVartype);
GETPTR(SafeArrayCreateEx);
GETPTR(SafeArrayCreateVector);
GETPTR(SafeArrayGetRecordInfo);
check_for_VT_INT_PTR();
test_safearray();
+216 -29
View File
@@ -29,19 +29,22 @@
#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}},
};
@@ -150,6 +153,35 @@ static void end_host_object(DWORD tid, HANDLE thread)
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)) {
@@ -158,6 +190,9 @@ static HRESULT WINAPI TestDual_QueryInterface(ItestDual *iface, REFIID riid, voi
}else if(IsEqualGUID(riid, &IID_ItestDual)) {
*ppvObject = &TestDual;
return S_OK;
}else if(IsEqualGUID(riid, &IID_ITestSecondIface)) {
*ppvObject = &TestSecondIface;
return S_OK;
}
*ppvObject = NULL;
@@ -216,11 +251,16 @@ static ItestDual TestDualDisp = { &TestDualVtbl };
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,
@@ -242,7 +282,7 @@ static HRESULT WINAPI Widget_QueryInterface(
static ULONG WINAPI Widget_AddRef(
IWidget *iface)
{
Widget *This = (Widget *)iface;
Widget *This = impl_from_IWidget(iface);
return InterlockedIncrement(&This->refs);
}
@@ -250,7 +290,7 @@ static ULONG WINAPI Widget_AddRef(
static ULONG WINAPI Widget_Release(
IWidget *iface)
{
Widget *This = (Widget *)iface;
Widget *This = impl_from_IWidget(iface);
ULONG refs = InterlockedDecrement(&This->refs);
if (!refs)
{
@@ -267,7 +307,7 @@ static HRESULT WINAPI Widget_GetTypeInfoCount(
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))
@@ -284,7 +324,7 @@ static HRESULT WINAPI Widget_GetTypeInfo(
/* [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))
@@ -303,7 +343,7 @@ static HRESULT WINAPI Widget_GetIDsOfNames(
/* [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))
@@ -325,7 +365,7 @@ static HRESULT WINAPI Widget_Invoke(
/* [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))
@@ -470,6 +510,46 @@ static HRESULT WINAPI Widget_VariantArrayPtr(
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)
@@ -515,6 +595,17 @@ static HRESULT WINAPI Widget_VarArg(
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,
@@ -523,14 +614,17 @@ static HRESULT WINAPI Widget_StructArgs(
{
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;
@@ -612,6 +706,20 @@ static HRESULT WINAPI Widget_put_prop_req_arg(
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,
@@ -635,6 +743,7 @@ static const struct IWidgetVtbl Widget_VTable =
Widget_Value,
Widget_Array,
Widget_VariantArrayPtr,
Widget_VariantCArray,
Widget_Variant,
Widget_VarArg,
Widget_StructArgs,
@@ -647,6 +756,8 @@ static const struct IWidgetVtbl Widget_VTable =
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)
@@ -703,11 +814,17 @@ static HRESULT WINAPI StaticWidget_Invoke(IStaticWidget *iface, DISPID dispIdMem
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,
@@ -716,17 +833,23 @@ static const IStaticWidgetVtbl StaticWidgetVtbl = {
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];
@@ -777,16 +900,17 @@ static IWidget *Widget_Create(void)
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);
@@ -815,7 +939,7 @@ static HRESULT WINAPI KindaEnum_QueryInterface(
static ULONG WINAPI KindaEnum_AddRef(
IKindaEnumWidget *iface)
{
KindaEnum *This = (KindaEnum *)iface;
KindaEnum *This = impl_from_IKindaEnumWidget(iface);
return InterlockedIncrement(&This->refs);
}
@@ -823,7 +947,7 @@ static ULONG WINAPI KindaEnum_AddRef(
static ULONG WINAPI KindaEnum_Release(
IKindaEnumWidget *iface)
{
KindaEnum *This = (KindaEnum *)iface;
KindaEnum *This = impl_from_IKindaEnumWidget(iface);
ULONG refs = InterlockedDecrement(&This->refs);
if (!refs)
{
@@ -883,9 +1007,9 @@ static IKindaEnumWidget *KindaEnumWidget_Create(void)
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)
@@ -989,7 +1113,14 @@ static void test_typelibmarshal(void)
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]);
@@ -1026,7 +1157,7 @@ static void test_typelibmarshal(void)
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));
@@ -1088,6 +1219,7 @@ static void test_typelibmarshal(void)
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]);
@@ -1211,6 +1343,18 @@ static void test_typelibmarshal(void)
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;
@@ -1436,6 +1580,28 @@ static void test_typelibmarshal(void)
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);
@@ -1498,6 +1664,20 @@ static void test_StaticWidget(void)
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);
}
@@ -1527,11 +1707,18 @@ static void test_libattr(void)
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();
+22
View File
@@ -39,6 +39,7 @@ library TestTypelib
{
INT field1;
ULONGLONG field2;
UINT uarr[8];
} MYSTRUCT;
coclass ApplicationObject2;
@@ -63,6 +64,15 @@ library TestTypelib
HRESULT test();
}
[
odl,
uuid(3f7e06fe-0bce-46f0-8b7d-3a68393c7968)
]
interface ITestSecondIface : IUnknown
{
HRESULT test();
}
[
odl,
uuid(a1f8cae3-c947-4c5f-b57d-c87b9b5f3586),
@@ -111,6 +121,9 @@ library TestTypelib
[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);
@@ -146,6 +159,12 @@ library TestTypelib
[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);
}
[
@@ -158,6 +177,9 @@ library TestTypelib
{
[id(DISPID_TM_TESTDUAL)]
HRESULT TestDual([in] ItestDual *p);
[id(DISPID_TM_TESTSECONDIFACE)]
HRESULT TestSecondIface([in] ITestSecondIface *p);
}
[
@@ -40,6 +40,10 @@
#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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+51 -21
View File
@@ -39,6 +39,7 @@
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*);
@@ -51,7 +52,7 @@ 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 )
{
@@ -212,7 +213,17 @@ static const FMTDATERES VarFormat_date_results[] =
{ 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) \
@@ -245,7 +256,7 @@ static void test_VarFormat(void)
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));
@@ -299,6 +310,23 @@ static void test_VarFormat(void)
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");
@@ -498,28 +526,30 @@ static void test_VarWeekdayName(void)
"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)
+222 -99
View File
@@ -24,6 +24,8 @@
#include <math.h>
#include <float.h>
#define CONST_VTABLE
#include "windef.h"
#include "winbase.h"
#include "winsock.h"
@@ -53,7 +55,7 @@ static WCHAR sz12_true[32];
/* 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;
@@ -104,7 +106,7 @@ static void init(void)
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));
@@ -112,7 +114,7 @@ static void init(void)
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));
@@ -343,6 +345,20 @@ static void test_var_call2( int line, HRESULT (WINAPI *func)(LPVARIANT,LPVARIANT
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)
{
@@ -399,26 +415,31 @@ static int IsValidVariantClearVT(VARTYPE vt, VARTYPE extraFlags)
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);
@@ -430,7 +451,7 @@ static const IUnknownVtbl test_VariantClear_vtbl = {
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)
{
@@ -442,7 +463,8 @@ 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;
@@ -509,17 +531,17 @@ static void test_VariantClear(void)
/* 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;
@@ -542,7 +564,7 @@ static void test_VariantClear(void)
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;
@@ -854,6 +876,7 @@ static void test_VariantCopyInd(void)
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));
@@ -866,6 +889,7 @@ static void test_VariantCopyInd(void)
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));
@@ -1575,15 +1599,13 @@ static void test_UdateFromDate( int line, DATE dt, ULONG flags, HRESULT r, WORD
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)
@@ -1609,6 +1631,15 @@ static void test_VarUdateFromDate(void)
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);
}
@@ -1629,7 +1660,7 @@ static void test_DateFromUDate( int line, WORD d, WORD m, WORD y, WORD h, WORD m
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)
@@ -1672,6 +1703,15 @@ static void test_VarDateFromUdate(void)
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,
@@ -1702,7 +1742,10 @@ static void test_SystemTimeToVariantTime(void)
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,
@@ -1964,6 +2007,8 @@ static void test_VarNot(void)
{
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);
@@ -2059,6 +2104,8 @@ static void test_VarNot(void)
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;
@@ -2129,7 +2176,6 @@ static void test_VarSub(void)
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) ||
@@ -2273,7 +2319,7 @@ static void test_VarSub(void)
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),
@@ -2293,14 +2339,14 @@ static void test_VarSub(void)
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);
@@ -3194,6 +3240,32 @@ static void test_Round( int line, VARIANT *arg, int deci, VARIANT *expected )
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' };
@@ -3202,6 +3274,7 @@ static void test_VarRound(void)
VARIANT v, exp, vDst;
CY *pcy = &V_CY(&v);
char buff[8];
int i;
CHECKPTR(VarRound);
@@ -3278,30 +3351,38 @@ static void test_VarRound(void)
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);
@@ -5081,12 +5162,12 @@ static void test_VarMul(void)
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);
@@ -5252,7 +5333,7 @@ static void test_VarAdd(void)
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);
@@ -5272,12 +5353,12 @@ static void test_VarAdd(void)
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);
@@ -5287,6 +5368,9 @@ static void test_VarAdd(void)
SysFreeString(rbstr);
}
static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
static HRESULT (WINAPI *pVarCat)(LPVARIANT,LPVARIANT,LPVARIANT);
static void test_VarCat(void)
{
LCID lcid;
@@ -5303,6 +5387,8 @@ static void test_VarCat(void)
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);
@@ -5419,7 +5505,7 @@ static void test_VarCat(void)
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,
@@ -5446,10 +5532,11 @@ static void test_VarCat(void)
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);
@@ -5459,7 +5546,7 @@ static void test_VarCat(void)
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");
@@ -5471,7 +5558,7 @@ static void test_VarCat(void)
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");
@@ -5488,11 +5575,14 @@ static void test_VarCat(void)
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);
@@ -5505,11 +5595,14 @@ static void test_VarCat(void)
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);
@@ -5523,10 +5616,11 @@ static void test_VarCat(void)
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);
@@ -5537,10 +5631,11 @@ static void test_VarCat(void)
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);
@@ -5550,10 +5645,11 @@ static void test_VarCat(void)
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);
@@ -5569,11 +5665,12 @@ static void test_VarCat(void)
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);
@@ -5589,11 +5686,12 @@ static void test_VarCat(void)
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);
@@ -5608,10 +5706,11 @@ static void test_VarCat(void)
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);
@@ -5620,6 +5719,30 @@ static void test_VarCat(void)
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);
@@ -6300,12 +6423,12 @@ static void test_VarAnd(void)
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 );
@@ -7973,7 +8096,7 @@ static void test_VarIdiv(void)
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)));
@@ -7982,7 +8105,7 @@ static void test_VarIdiv(void)
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)));
@@ -7991,21 +8114,21 @@ static void test_VarIdiv(void)
(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)));
@@ -8014,7 +8137,7 @@ static void test_VarIdiv(void)
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)));
@@ -8637,8 +8760,8 @@ START_TEST(vartest)
test_VarEqv();
test_VarMul();
test_VarAdd();
test_VarCmp(); /* Before test_VarCat() which needs VarCmp() */
test_VarCat();
test_VarCmp();
test_VarAnd();
test_VarDiv();
test_VarIdiv();
+239 -235
View File
@@ -18,6 +18,8 @@
* 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>
@@ -70,17 +72,18 @@ static HMODULE hOleaut32;
/* 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)
@@ -149,8 +152,8 @@ static HMODULE hOleaut32;
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); \
@@ -501,6 +504,7 @@ static HRESULT (WINAPI *pVarBstrFromDate)(DATE,LCID,ULONG,BSTR*);
static HRESULT (WINAPI *pVarBstrFromCy)(CY,LCID,ULONG,BSTR*);
static HRESULT (WINAPI *pVarBstrFromDec)(DECIMAL*,LCID,ULONG,BSTR*);
static HRESULT (WINAPI *pVarBstrCmp)(BSTR,BSTR,LCID,ULONG);
static HRESULT (WINAPI *pVarBstrCat)(BSTR,BSTR,BSTR*);
static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
static void (WINAPI *pClearCustData)(LPCUSTDATA);
@@ -514,7 +518,7 @@ typedef struct tagINTERNAL_BSTR
typedef struct
{
const IDispatchVtbl *lpVtbl;
IDispatch IDispatch_iface;
LONG ref;
VARTYPE vt;
BOOL bFailInvoke;
@@ -522,16 +526,25 @@ typedef struct
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,
@@ -592,7 +605,7 @@ static const IDispatchVtbl DummyDispatch_VTable =
DummyDispatch_Invoke
};
static DummyDispatch dispatch = { &DummyDispatch_VTable, 1, 0, 0 };
static DummyDispatch dispatch = { { &DummyDispatch_VTable }, 1, 0, 0 };
/*
* VT_I1/VT_UI1
@@ -836,7 +849,8 @@ static void test_VarI1Copy(void)
static void test_VarI1ChangeTypeEx(void)
{
CONVVARS(CONV_TYPE);
HRESULT hres;
signed char in;
VARIANTARG vSrc, vDst;
in = 1;
@@ -1094,11 +1108,11 @@ static void test_VarUI1FromDisp(void)
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);
@@ -1106,7 +1120,7 @@ static void test_VarUI1FromDisp(void)
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);
@@ -1120,7 +1134,8 @@ static void test_VarUI1Copy(void)
static void test_VarUI1ChangeTypeEx(void)
{
CONVVARS(CONV_TYPE);
HRESULT hres;
BYTE in;
VARIANTARG vSrc, vDst;
in = 1;
@@ -1136,8 +1151,6 @@ static void test_VarUI1ChangeTypeEx(void)
#undef CONV_TYPE
#define CONV_TYPE SHORT
#undef EXPECTRES
#define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
static void test_VarI2FromI1(void)
{
@@ -1369,7 +1382,8 @@ static void test_VarI2Copy(void)
static void test_VarI2ChangeTypeEx(void)
{
CONVVARS(CONV_TYPE);
HRESULT hres;
SHORT in;
VARIANTARG vSrc, vDst;
in = 1;
@@ -1608,7 +1622,8 @@ static void test_VarUI2Copy(void)
static void test_VarUI2ChangeTypeEx(void)
{
CONVVARS(CONV_TYPE);
HRESULT hres;
USHORT in;
VARIANTARG vSrc, vDst;
in = 1;
@@ -1627,9 +1642,6 @@ static void test_VarUI2ChangeTypeEx(void)
#undef CONV_TYPE
#define CONV_TYPE LONG
#undef EXPECTRES
#define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
static void test_VarI4FromI1(void)
{
@@ -1863,7 +1875,8 @@ static void test_VarI4Copy(void)
static void test_VarI4ChangeTypeEx(void)
{
CONVVARS(CONV_TYPE);
HRESULT hres;
LONG in;
VARIANTARG vSrc, vDst;
in = 1;
@@ -2097,7 +2110,8 @@ static void test_VarUI4Copy(void)
static void test_VarUI4ChangeTypeEx(void)
{
CONVVARS(CONV_TYPE);
HRESULT hres;
ULONG in;
VARIANTARG vSrc, vDst;
in = 1;
@@ -2116,10 +2130,6 @@ static void test_VarUI4ChangeTypeEx(void)
#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)), \
@@ -2374,7 +2384,8 @@ static void test_VarI8Copy(void)
static void test_VarI8ChangeTypeEx(void)
{
CONVVARS(CONV_TYPE);
HRESULT hres;
LONG64 in;
VARIANTARG vSrc, vDst;
if (!HAVE_OLEAUT32_I8)
@@ -2524,7 +2535,10 @@ static void test_VarUI8FromBool(void)
int i;
CHECKPTR(VarUI8FromBool);
CONVERTRANGE(VarUI8FromBool, -32768, 32768);
for (i = -32768; i < 32768; i++)
{
CONVERT(VarUI8FromBool, i); EXPECTI8(i);
}
}
static void test_VarUI8FromI8(void)
@@ -2588,10 +2602,13 @@ static void test_VarUI8FromStr(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;
@@ -2636,7 +2653,8 @@ static void test_VarUI8Copy(void)
static void test_VarUI8ChangeTypeEx(void)
{
CONVVARS(CONV_TYPE);
HRESULT hres;
ULONG64 in;
VARIANTARG vSrc, vDst;
if (!HAVE_OLEAUT32_I8)
@@ -2844,7 +2862,8 @@ static void test_VarR4Copy(void)
static void test_VarR4ChangeTypeEx(void)
{
#ifdef HAS_UINT64_TO_FLOAT
CONVVARS(CONV_TYPE);
HRESULT hres;
float in;
VARIANTARG vSrc, vDst;
in = 1.0f;
@@ -2860,8 +2879,6 @@ static void test_VarR4ChangeTypeEx(void)
#undef CONV_TYPE
#define CONV_TYPE double
#undef EXPECTRES
#define EXPECTRES(res, x) _EXPECTRES(res, x, "%15.15f")
static void test_VarR8FromI1(void)
{
@@ -3055,7 +3072,8 @@ static void test_VarR8Copy(void)
static void test_VarR8ChangeTypeEx(void)
{
#ifdef HAS_UINT64_TO_FLOAT
CONVVARS(CONV_TYPE);
HRESULT hres;
double in;
VARIANTARG vSrc, vDst;
in = 1.0;
@@ -3433,6 +3451,8 @@ static void test_VarDateFromStr(void)
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 */
@@ -3440,6 +3460,11 @@ static void test_VarDateFromStr(void)
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;
@@ -3467,7 +3492,8 @@ static void test_VarDateChangeTypeEx(void)
'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;
@@ -3507,10 +3533,6 @@ static void test_VarDateChangeTypeEx(void)
#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)), \
@@ -3699,7 +3721,9 @@ static void test_VarCyFromUI8(void)
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)
@@ -3715,7 +3739,9 @@ 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);
@@ -3872,11 +3898,13 @@ static void test_VarCyMulI8(void)
}
#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;
@@ -3893,11 +3921,13 @@ static void test_VarCyCmp(void)
}
#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);
@@ -4006,10 +4036,6 @@ static void test_VarCyInt(void)
#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) && \
@@ -4534,10 +4560,6 @@ static void test_VarDecCmp(void)
#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
@@ -4794,7 +4816,8 @@ static void test_VarBoolChangeTypeEx(void)
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;
@@ -4896,23 +4919,30 @@ static void test_VarBstrFromR4(void)
}
}
#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 _BSTR_DATE(DATE dt, const char *str, int line)
{
LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
char buff[256];
BSTR bstr = NULL;
HRESULT hres;
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)
{
char buff[256];
LCID lcid;
HRESULT hres;
BSTR bstr;
#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");
@@ -4923,174 +4953,146 @@ static void test_VarBstrFromDate(void)
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");
#undef BSTR_DATE
}
#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);\
static void _BSTR_CY(LONG a, LONG b, const char *str, LCID lcid, int line)
{
HRESULT hr;
BSTR bstr = NULL;
char buff[256];
CY l;
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);
if(bstr)
{
WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
SysFreeString(bstr);
}
else
buff[0] = 0;
if(hr == S_OK)
{
ok_(__FILE__, line)(!strcmp(str, buff), "Expected '%s', got '%s'\n", str, buff);
}
}
static void test_VarBstrFromCy(void)
{
LCID lcid;
HRESULT hres;
BSTR bstr = NULL;
CY l;
#define BSTR_CY(a, b, str, lcid) _BSTR_CY(a, b, 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 / 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'};
LCID en_us, sp;
CHECKPTR(VarBstrFromCy);
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
/* check zero */
BSTR_CY(l, 0,0, szZero);
en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
sp = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
/* check one */
BSTR_CY(l, 0, 10000, szOne);
/* check one point five */
BSTR_CY(l, 0, 15000, szOnePointFive);
/* check minus one point five */
BSTR_CY(l, 0xffffffff, ((15000)^0xffffffff)+1, szMinusOnePointFive);
/* check bignum (1) */
BSTR_CY(l, 0, 0xffffffff, szBigNum1);
/* check bignum (2) */
BSTR_CY(l, 1,0, szBigNum2);
/* check bignum (3) */
BSTR_CY(l, 0x7fffffff,0xffffffff, szBigNum3);
/* check leading zeros and decimal sep. for English locale */
BSTR_CY(l, 0,9, szSmallNumber_English);
lcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
/* check leading zeros and decimal sep. for Spanish locale */
BSTR_CY(l, 0,9, szSmallNumber_Spanish);
}
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);
#undef BSTR_CY
}
#define BSTR_DEC(l, a, b, c, d, e) \
SETDEC(l, a,b,c,d);\
hres = pVarBstrFromDec(&l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
ok(hres == S_OK, "got hres 0x%08x\n", hres);\
if (hres== S_OK && bstr)\
{\
ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\
SysFreeString(bstr);\
}
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;
#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);\
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);
if(bstr)
{
WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
SysFreeString(bstr);
}
else
buff[0] = 0;
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);
en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
sp = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
/* 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);
BSTR_DEC(0,0,0,0, "0", en_us);
/* check minus one point five */
BSTR_DEC(l, 1,0x80,0,15, szMinusOnePointFive);
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);
/* check bignum (1) */
BSTR_DEC(l, 0,0,0,0xffffffff, szBigNum1);
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);
/* check bignum (2) */
BSTR_DEC64(l, 0,0,0,1,0, szBigNum2);
BSTR_DEC(1,0x80,0,15, "-1.5", en_us);
/* 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);
/* (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); \
@@ -5151,7 +5153,7 @@ static void test_VarBstrCmp(void)
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);
@@ -5170,7 +5172,7 @@ static void test_VarBstrCmp(void)
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);
@@ -5492,14 +5494,16 @@ static void test_VarBstrCat(void)
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");
@@ -5508,13 +5512,13 @@ if (0)
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");
@@ -5523,7 +5527,7 @@ if (0)
/* 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,
@@ -5538,7 +5542,7 @@ if (0)
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),
@@ -5557,7 +5561,7 @@ if (0)
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);
@@ -5576,7 +5580,7 @@ if (0)
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));
@@ -5593,12 +5597,12 @@ static void test_IUnknownClear(void)
{
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",
@@ -5618,8 +5622,8 @@ static void test_IUnknownCopy(void)
{
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);
@@ -5666,8 +5670,8 @@ static void test_IUnknownChangeTypeEx(void)
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);
@@ -5734,8 +5738,8 @@ static void test_IDispatchClear(void)
{
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 */
@@ -5759,8 +5763,8 @@ static void test_IDispatchCopy(void)
{
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 */
@@ -5804,8 +5808,8 @@ static void test_IDispatchChangeTypeEx(void)
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);
@@ -6064,7 +6068,7 @@ static void test_ChangeType_keep_dst(void)
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);
}
@@ -6072,7 +6076,7 @@ START_TEST(vartype)
{
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();