[OLEAUT32_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912

svn path=/trunk/; revision=70904
This commit is contained in:
Amine Khaldi 2016-03-04 09:33:46 +00:00
parent 5567f3cf36
commit 182031e324
9 changed files with 417 additions and 27 deletions

View file

@ -1056,7 +1056,9 @@ static void test_load_save_bmp(void)
DWORD *mem;
IPersistStream *src_stream;
IStream *dst_stream;
LARGE_INTEGER offset;
HRESULT hr;
LONG size;
desc.cbSizeofstruct = sizeof(desc);
desc.picType = PICTYPE_BITMAP;
@ -1078,6 +1080,27 @@ static void test_load_save_bmp(void)
hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
size = -1;
hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
todo_wine
ok(size == 66, "expected 66, got %d\n", size);
mem = GlobalLock(hmem);
todo_wine
ok(!memcmp(&mem[0], "BM", 2), "got wrong bmp header %04x\n", mem[0]);
GlobalUnlock(hmem);
size = -1;
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
todo_wine
ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
todo_wine
ok(size == -1, "expected -1, got %d\n", size);
offset.QuadPart = 0;
hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL);
ok(hr == S_OK, "IStream_Seek %#x\n", hr);
hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
ok(hr == S_OK, "QueryInterface error %#x\n", hr);
@ -1109,7 +1132,9 @@ static void test_load_save_icon(void)
DWORD *mem;
IPersistStream *src_stream;
IStream *dst_stream;
LARGE_INTEGER offset;
HRESULT hr;
LONG size;
desc.cbSizeofstruct = sizeof(desc);
desc.picType = PICTYPE_ICON;
@ -1130,6 +1155,27 @@ static void test_load_save_icon(void)
hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
size = -1;
hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
todo_wine
ok(size == 766, "expected 766, got %d\n", size);
mem = GlobalLock(hmem);
todo_wine
ok(mem[0] == 0x00010000, "got wrong icon header %04x\n", mem[0]);
GlobalUnlock(hmem);
size = -1;
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
todo_wine
ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
todo_wine
ok(size == -1, "expected -1, got %d\n", size);
offset.QuadPart = 0;
hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL);
ok(hr == S_OK, "IStream_Seek %#x\n", hr);
hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
ok(hr == S_OK, "QueryInterface error %#x\n", hr);
@ -1164,6 +1210,7 @@ static void test_load_save_empty_picture(void)
IStream *dst_stream, *stream;
LARGE_INTEGER offset;
HRESULT hr;
LONG size;
memset(&pic, 0, sizeof(pic));
desc.cbSizeofstruct = sizeof(desc);
@ -1173,7 +1220,7 @@ static void test_load_save_empty_picture(void)
type = -1;
hr = IPicture_get_Type(pic, &type);
ok(hr == S_OK,"get_Type error %#8x\n", hr);
ok(hr == S_OK, "get_Type error %#x\n", hr);
ok(type == PICTYPE_NONE,"expected picture type PICTYPE_NONE, got %d\n", type);
handle = (OLE_HANDLE)0xdeadbeef;
@ -1185,6 +1232,18 @@ static void test_load_save_empty_picture(void)
hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
size = -1;
hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
todo_wine
ok(size == -1, "expected -1, got %d\n", size);
size = -1;
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
todo_wine
ok(size == -1, "expected -1, got %d\n", size);
hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
ok(hr == S_OK, "QueryInterface error %#x\n", hr);

View file

@ -1969,40 +1969,99 @@ static void test_SafeArrayChangeTypeEx(void)
static void test_SafeArrayDestroyData (void)
{
SAFEARRAYBOUND sab;
SAFEARRAYBOUND sab[2];
SAFEARRAY *sa;
HRESULT hres;
int value = 0xdeadbeef;
LONG index[1];
void *temp_pvData;
USHORT features;
sab.lLbound = 0;
sab.cElements = 10;
sa = SafeArrayCreate(VT_INT, 1, &sab);
sab[0].lLbound = 0;
sab[0].cElements = 10;
sa = SafeArrayCreate(VT_INT, 1, sab);
ok(sa != NULL, "Create() failed.\n");
if (!sa)
return;
ok(sa->fFeatures == FADF_HAVEVARTYPE, "got 0x%x\n", sa->fFeatures);
index[0] = 1;
SafeArrayPutElement (sa, index, &value);
/* SafeArrayDestroyData shouldn't free pvData if FADF_STATIC is set. */
sa->fFeatures |= FADF_STATIC;
features = (sa->fFeatures |= FADF_STATIC);
temp_pvData = sa->pvData;
hres = SafeArrayDestroyData(sa);
ok(hres == S_OK, "SADData FADF_STATIC failed, error code %x.\n",hres);
ok(features == sa->fFeatures, "got 0x%x\n", sa->fFeatures);
ok(sa->pvData == temp_pvData, "SADData FADF_STATIC: pvData=%p, expected %p (fFeatures = %d).\n",
sa->pvData, temp_pvData, sa->fFeatures);
SafeArrayGetElement (sa, index, &value);
ok(value == 0, "Data not cleared after SADData\n");
/* Clear FADF_STATIC, now really destroy the data. */
sa->fFeatures ^= FADF_STATIC;
features = (sa->fFeatures ^= FADF_STATIC);
hres = SafeArrayDestroyData(sa);
ok(hres == S_OK, "SADData !FADF_STATIC failed, error code %x.\n",hres);
ok(features == sa->fFeatures, "got 0x%x\n", sa->fFeatures);
ok(sa->pvData == NULL, "SADData !FADF_STATIC: pvData=%p, expected NULL.\n", sa->pvData);
hres = SafeArrayDestroy(sa);
ok(hres == S_OK, "SAD failed, error code %x.\n", hres);
/* two dimensions */
sab[0].lLbound = 0;
sab[0].cElements = 10;
sab[1].lLbound = 0;
sab[1].cElements = 10;
sa = SafeArrayCreate(VT_INT, 2, sab);
ok(sa != NULL, "Create() failed.\n");
ok(sa->fFeatures == FADF_HAVEVARTYPE, "got 0x%x\n", sa->fFeatures);
features = sa->fFeatures;
hres = SafeArrayDestroyData(sa);
ok(hres == S_OK, "got 0x%08x\n",hres);
ok(features == sa->fFeatures, "got 0x%x\n", sa->fFeatures);
SafeArrayDestroy(sa);
/* try to destroy data from descriptor */
hres = SafeArrayAllocDescriptor(1, &sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
ok(sa->fFeatures == 0, "got 0x%x\n", sa->fFeatures);
hres = SafeArrayDestroyData(sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
ok(sa->fFeatures == 0, "got 0x%x\n", sa->fFeatures);
hres = SafeArrayDestroyDescriptor(sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
hres = SafeArrayAllocDescriptor(2, &sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
ok(sa->fFeatures == 0, "got 0x%x\n", sa->fFeatures);
hres = SafeArrayDestroyData(sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
ok(sa->fFeatures == 0, "got 0x%x\n", sa->fFeatures);
hres = SafeArrayDestroyDescriptor(sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
/* vector case */
sa = SafeArrayCreateVector(VT_I4, 0, 10);
ok(sa != NULL, "got %p\n", sa);
ok(sa->fFeatures == (FADF_CREATEVECTOR|FADF_HAVEVARTYPE), "got 0x%x\n", sa->fFeatures);
ok(sa->pvData != NULL, "got %p\n", sa->pvData);
hres = SafeArrayDestroyData(sa);
ok(hres == S_OK, "got 0x%08x\n", hres);
todo_wine
ok(sa->fFeatures == FADF_HAVEVARTYPE, "got 0x%x\n", sa->fFeatures);
ok(sa->pvData != NULL, "got %p\n", sa->pvData);
/* There seems to be a bug on windows, especially visible on 64bit systems,
probably double-free of similar issue. */
sa->pvData = NULL;
SafeArrayDestroy(sa);
}
static void test_safearray_layout(void)

View file

@ -141,6 +141,8 @@ library register_test
LONG testprop([in] LONG *i);
[propputref, id(2)]
LONG testprop2([in] IUnknown *i);
[id(3)]
HRESULT testfunc([in] int i, [out, retval] int *p);
}
/* uuid is same as for test_struct2 in test_tlb.idl, fields are different */

View file

@ -919,11 +919,10 @@ static HRESULT WINAPI Widget_VarArg_Ref_Run(
}
static HRESULT WINAPI Widget_Coclass(
IWidget *iface,
ApplicationObject2 *p)
IWidget *iface, ApplicationObject2 *param)
{
trace("Coclass(%p)\n", p);
ok(p == (ApplicationObject2 *)iface, "expected p == %p, got %p\n", iface, p);
trace("Coclass(%p)\n", param);
ok(param == (ApplicationObject2 *)iface, "expected param == %p, got %p\n", iface, param);
return S_OK;
}
@ -1515,7 +1514,7 @@ static void test_typelibmarshal(void)
ok(V_VT(&varresult) == VT_DISPATCH, "V_VT(&varresult) was %d instead of VT_DISPATCH\n", V_VT(&varresult));
ok(V_DISPATCH(&varresult) != NULL, "expected V_DISPATCH(&varresult) != NULL\n");
/* call CoClass with VT_DISPATCH type */
/* call Coclass with VT_DISPATCH type */
vararg[0] = varresult;
dispparams.cNamedArgs = 0;
dispparams.rgdispidNamedArgs = NULL;

View file

@ -187,7 +187,7 @@ library TestTypelib
HRESULT VarArg_Ref_Run([in] BSTR name, [in] SAFEARRAY(VARIANT) *params, [out, retval] VARIANT *result);
[id(DISPID_TM_COCLASS)]
HRESULT Coclass([in] ApplicationObject2 *p);
HRESULT Coclass([in] ApplicationObject2 *param);
}
[

View file

@ -39,6 +39,7 @@
//#include "ocidl.h"
//#include "shlwapi.h"
#include <tmarshal.h>
#include <olectl.h>
#include <test_reg.h>
#include <test_tlb.h>
@ -158,6 +159,12 @@ static LONG WINAPI invoketest_putref_testprop2(IInvokeTest *iface, IUnknown *i)
return 6;
}
static HRESULT WINAPI invoketest_testfunc(IInvokeTest *iface, int i, int *p)
{
*p = i+1;
return S_OK;
}
static const IInvokeTestVtbl invoketestvtbl = {
invoketest_QueryInterface,
invoketest_AddRef,
@ -168,7 +175,8 @@ static const IInvokeTestVtbl invoketestvtbl = {
invoketest_Invoke,
invoketest_get_test,
invoketest_putref_testprop,
invoketest_putref_testprop2
invoketest_putref_testprop2,
invoketest_testfunc
};
static IInvokeTest invoketest = { &invoketestvtbl };
@ -204,7 +212,8 @@ static void ref_count_test(LPCWSTR type_lib)
hRes = ITypeLib_GetTypeInfo(iface, 1, &iti1);
ok(hRes == S_OK, "ITypeLib_GetTypeInfo failed on index = 1\n");
ok(ref_count=ITypeLib_Release(iface) > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
ref_count = ITypeLib_Release(iface);
ok(ref_count > 0, "ITypeLib destroyed while ITypeInfo has back pointer\n");
if(!ref_count)
return;
@ -669,6 +678,33 @@ static void write_typelib(int res_no, const char *filename)
CloseHandle( file );
}
static void test_invoke_func(ITypeInfo *typeinfo)
{
DISPID named_args[3] = { DISPID_THIS };
VARIANT args[3], res;
DISPPARAMS dp = {args, named_args, 1, 0};
UINT i;
HRESULT hres;
V_VT(args) = VT_INT;
V_INT(args) = 3;
V_VT(&res) = VT_ERROR;
hres = ITypeInfo_Invoke(typeinfo, &invoketest, 3, DISPATCH_METHOD, &dp, &res, NULL, &i);
ok(hres == S_OK, "got 0x%08x\n", hres);
ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res));
ok(V_I4(&res) == 4, "got %d\n", V_I4(&res));
V_VT(args) = VT_DISPATCH;
V_DISPATCH(args) = (IDispatch*)&invoketest;
V_VT(args+1) = VT_INT;
V_INT(args+1) = 3;
V_VT(&res) = VT_ERROR;
dp.cNamedArgs = 1;
dp.cArgs = 2;
hres = ITypeInfo_Invoke(typeinfo, &invoketest, 3, DISPATCH_METHOD, &dp, &res, NULL, &i);
ok(hres == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hres);
}
static const char *create_test_typelib(int res_no)
{
static char filename[MAX_PATH];
@ -961,6 +997,8 @@ static void test_TypeInfo(void)
hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 2, DISPATCH_PROPERTYPUT, &dispparams, &res, NULL, &i);
ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x, %d\n", hr, i);
test_invoke_func(pTypeInfo);
ITypeInfo_Release(pTypeInfo);
ITypeLib_Release(pTypeLib);
DeleteFileA(filenameA);
@ -1621,7 +1659,6 @@ static void test_CreateTypeLib(SYSKIND sys) {
static OLECHAR dualW[] = {'d','u','a','l',0};
static OLECHAR coclassW[] = {'c','o','c','l','a','s','s',0};
static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0x3213,0};
static const WCHAR defaultQW[] = {'d','e','f','a','u','l','t','?',0};
static OLECHAR func1W[] = {'f','u','n','c','1',0};
static OLECHAR func2W[] = {'f','u','n','c','2',0};
static OLECHAR prop1W[] = {'P','r','o','p','1',0};
@ -1633,6 +1670,7 @@ static void test_CreateTypeLib(SYSKIND sys) {
static OLECHAR *names1[] = {func1W, param1W, param2W};
static OLECHAR *names2[] = {func2W, param1W, param2W};
static OLECHAR *propname[] = {prop1W, param1W};
static const GUID tlcustguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x69}};
static const GUID custguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x70}};
static const GUID bogusguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x71}};
static const GUID interfaceguid = {0x3b9ff02f,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcc}};
@ -1644,6 +1682,7 @@ static void test_CreateTypeLib(SYSKIND sys) {
ICreateTypeInfo *createti;
ICreateTypeInfo2 *createti2;
ITypeLib *tl, *stdole;
ITypeLib2 *tl2;
ITypeInfo *interface1, *interface2, *dual, *unknown, *dispatch, *ti;
ITypeInfo *tinfos[2];
ITypeInfo2 *ti2;
@ -1666,6 +1705,8 @@ static void test_CreateTypeLib(SYSKIND sys) {
TYPEKIND kind;
DESCKIND desckind;
BINDPTR bindptr;
char nameA[16];
WCHAR nameW[16];
switch(sys){
case SYS_WIN32:
@ -1760,6 +1801,23 @@ static void test_CreateTypeLib(SYSKIND sys) {
SysFreeString(name);
SysFreeString(helpfile);
V_VT(&cust_data) = VT_I4;
V_I4(&cust_data) = 1;
hres = ICreateTypeLib2_SetCustData(createtl, &tlcustguid, &cust_data);
ok(hres == S_OK, "got %08x\n", hres);
hres = ITypeLib_QueryInterface(tl, &IID_ITypeLib2, (void**)&tl2);
ok(hres == S_OK, "no ITypeLib2 interface (%x)\n", hres);
V_VT(&cust_data) = VT_EMPTY;
V_I4(&cust_data) = 0;
hres = ITypeLib2_GetCustData(tl2, &tlcustguid, &cust_data);
ok(hres == S_OK, "got %08x\n", hres);
ok(V_VT(&cust_data) == VT_I4, "V_VT(&cust_data) = %d\n", V_VT(&cust_data));
ok(V_I4(&cust_data) == 1, "V_I4(&cust_data) = %d\n", V_I4(&cust_data));
ITypeLib2_Release(tl2);
/* invalid parameters */
hres = ICreateTypeLib2_CreateTypeInfo(createtl, NULL, TKIND_INTERFACE, &createti);
ok(hres == E_INVALIDARG, "got %08x\n", hres);
@ -2162,6 +2220,9 @@ static void test_CreateTypeLib(SYSKIND sys) {
ok(hres == S_OK, "got %08x\n", hres);
SysFreeString(V_BSTR(&paramdescex.varDefaultValue));
WideCharToMultiByte(CP_ACP, 0, defaultW, -1, nameA, sizeof(nameA), NULL, NULL);
MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, sizeof(nameW)/sizeof(nameW[0]));
hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc);
ok(hres == S_OK, "got %08x\n", hres);
@ -2187,7 +2248,7 @@ static void test_CreateTypeLib(SYSKIND sys) {
U(*edesc).paramdesc.pparamdescex->cBytes);
ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW),
"got: %s\n",
wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
@ -2199,7 +2260,7 @@ static void test_CreateTypeLib(SYSKIND sys) {
U(*edesc).paramdesc.pparamdescex->cBytes);
ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW),
"got: %s\n",
wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
@ -2821,6 +2882,16 @@ static void test_CreateTypeLib(SYSKIND sys) {
SysFreeString(name);
SysFreeString(helpfile);
hres = ITypeLib_QueryInterface(tl, &IID_ITypeLib2, (void**)&tl2);
ok(hres == S_OK, "no ITypeLib2 interface (%x)\n", hres);
V_VT(&cust_data) = VT_EMPTY;
V_I4(&cust_data) = 0;
hres = ITypeLib2_GetCustData(tl2, &tlcustguid, &cust_data);
ok(hres == S_OK, "got %08x\n", hres);
ok(V_VT(&cust_data) == VT_I4, "V_VT(&cust_data) = %d\n", V_VT(&cust_data));
ok(V_I4(&cust_data) == 1, "V_I4(&cust_data) = %d\n", V_I4(&cust_data));
ITypeLib2_Release(tl2);
hres = ITypeLib_GetTypeInfo(tl, 0, &ti);
ok(hres == S_OK, "got %08x\n", hres);
@ -2985,7 +3056,7 @@ static void test_CreateTypeLib(SYSKIND sys) {
U(*edesc).paramdesc.pparamdescex->cBytes);
ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW),
"got: %s\n",
wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
@ -2997,7 +3068,7 @@ static void test_CreateTypeLib(SYSKIND sys) {
U(*edesc).paramdesc.pparamdescex->cBytes);
ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n",
V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue));
ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW),
ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW),
"got: %s\n",
wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)));
@ -5591,6 +5662,11 @@ static void test_LoadRegTypeLib(void)
ok(hr == TYPE_E_LIBNOTREGISTERED || broken(hr == S_OK) /* winxp */, "got 0x%08x\n", hr);
SysFreeString(path);
path = NULL;
hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 0xffff, 0xffff, LOCALE_NEUTRAL, &path);
ok(hr == S_OK, "got 0x%08x\n", hr);
SysFreeString(path);
/* manifest version is 2.0, actual is 1.0 */
hr = LoadRegTypeLib(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, &tl);
ok(hr == TYPE_E_LIBNOTREGISTERED || broken(hr == S_OK) /* winxp */, "got 0x%08x\n", hr);
@ -5636,6 +5712,20 @@ static void test_LoadRegTypeLib(void)
hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 7, LOCALE_NEUTRAL, &tl);
ok(hr == TYPE_E_LIBNOTREGISTERED, "got 0x%08x\n", hr);
hr = LoadRegTypeLib(&LIBID_TestTypelib, 0xffff, 0xffff, LOCALE_NEUTRAL, &tl);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = ITypeLib_GetLibAttr(tl, &attr);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(attr->lcid == 0, "got %x\n", attr->lcid);
ok(attr->wMajorVerNum == 2, "got %d\n", attr->wMajorVerNum);
ok(attr->wMinorVerNum == 5, "got %d\n", attr->wMinorVerNum);
ok(attr->wLibFlags == LIBFLAG_FHASDISKIMAGE, "got %x\n", attr->wLibFlags);
ITypeLib_ReleaseTLibAttr(tl, attr);
ITypeLib_Release(tl);
DeleteFileA("test_actctx_tlb.tlb");
DeleteFileA("test_actctx_tlb2.tlb");

View file

@ -282,6 +282,7 @@ static void test_marshal_LPSAFEARRAY(void)
ok(lpsa2->cLocks == 0, "got lock count %u, expected 0\n", lpsa2->cLocks);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
ok(!lpsa2, "lpsa2 was not set to 0 by LPSAFEARRAY_UserFree\n");
HeapFree(GetProcessHeap(), 0, buffer);
lpsa->cLocks = 0;
hr = SafeArrayDestroy(lpsa);
@ -771,10 +772,10 @@ static void test_marshal_VARIANT(void)
double d;
void *mem;
DWORD *wirev;
BSTR b;
BSTR b, b2;
WCHAR str[] = {'m','a','r','s','h','a','l',' ','t','e','s','t',0};
SAFEARRAYBOUND sab;
LPSAFEARRAY lpsa;
LPSAFEARRAY lpsa, lpsa2, lpsa_copy;
DECIMAL dec, dec2;
HeapUnknown *heap_unknown;
DWORD expected;
@ -1241,15 +1242,21 @@ static void test_marshal_VARIANT(void)
ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is b. winxp: this is (char*)b + 1 */
wirev++;
check_bstr(wirev, b);
b2 = SysAllocString(str);
b2[0] = 0;
V_VT(&v2) = VT_BSTR | VT_BYREF;
V_BSTRREF(&v2) = &b2;
mem = b2;
VariantInit(&v2);
stubMsg.Buffer = buffer;
next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
ok(mem == b2, "BSTR should be reused\n");
ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
ok(SysStringByteLen(*V_BSTRREF(&v)) == SysStringByteLen(*V_BSTRREF(&v2)), "bstr string lens differ\n");
ok(!memcmp(*V_BSTRREF(&v), *V_BSTRREF(&v2), SysStringByteLen(*V_BSTRREF(&v))), "bstrs differ\n");
VARIANT_UserFree(&umcb.Flags, &v2);
SysFreeString(b2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
SysFreeString(b);
@ -1341,6 +1348,59 @@ static void test_marshal_VARIANT(void)
}
VARIANT_UserFree(&umcb.Flags, &v2);
HeapFree(GetProcessHeap(), 0, oldbuffer);
/*** ARRAY BYREF ***/
VariantInit(&v);
V_VT(&v) = VT_UI4 | VT_ARRAY | VT_BYREF;
V_ARRAYREF(&v) = &lpsa;
lpsa->fFeatures |= FADF_STATIC;
rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
expected = 152;
ok(stubMsg.BufferLength == expected || stubMsg.BufferLength == expected + 16, /* win64 */
"size %u instead of %u\n", stubMsg.BufferLength, expected);
buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
next = VARIANT_UserMarshal(&umcb.Flags, buffer, &v);
ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
wirev = (DWORD*)buffer;
wirev = check_variant_header(wirev, &v, expected);
ok(*wirev == 4, "wv[5] %08x\n", *wirev);
wirev++;
ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */
wirev++;
check_safearray(wirev, lpsa);
lpsa_copy = lpsa2 = SafeArrayCreate(VT_I8, 1, &sab);
/* set FADF_STATIC feature to make sure lpsa2->pvData pointer changes if new data buffer is allocated */
lpsa2->fFeatures |= FADF_STATIC;
mem = lpsa2->pvData;
V_VT(&v2) = VT_UI4 | VT_ARRAY | VT_BYREF;
V_ARRAYREF(&v2) = &lpsa2;
stubMsg.Buffer = buffer;
next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2);
ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
ok(lpsa2 == lpsa_copy, "safearray should be reused\n");
ok(mem == lpsa2->pvData, "safearray data should be reused\n");
ok(SafeArrayGetDim(*V_ARRAYREF(&v)) == SafeArrayGetDim(*V_ARRAYREF(&v2)), "array dims differ\n");
SafeArrayGetLBound(*V_ARRAYREF(&v), 1, &bound);
SafeArrayGetLBound(*V_ARRAYREF(&v2), 1, &bound2);
ok(bound == bound2, "array lbounds differ\n");
SafeArrayGetUBound(*V_ARRAYREF(&v), 1, &bound);
SafeArrayGetUBound(*V_ARRAYREF(&v2), 1, &bound2);
ok(bound == bound2, "array ubounds differ\n");
if (pSafeArrayGetVartype)
{
pSafeArrayGetVartype(*V_ARRAYREF(&v), &vt);
pSafeArrayGetVartype(*V_ARRAYREF(&v2), &vt2);
ok(vt == vt2, "array vts differ %x %x\n", vt, vt2);
}
lpsa2->fFeatures &= ~FADF_STATIC;
hr = SafeArrayDestroy(*V_ARRAYREF(&v2));
ok(hr == S_OK, "got 0x%08x\n", hr);
HeapFree(GetProcessHeap(), 0, oldbuffer);
lpsa->fFeatures &= ~FADF_STATIC;
hr = SafeArrayDestroy(lpsa);
ok(hr == S_OK, "got 0x%08x\n", hr);

View file

@ -562,6 +562,88 @@ static void test_VarWeekdayName(void)
}
}
static void test_VarFormatFromTokens(void)
{
static WCHAR number_fmt[] = {'#','#','#',',','#','#','0','.','0','0',0};
static const WCHAR number[] = {'6',',','9','0',0};
static const WCHAR number_us[] = {'6','9','0','.','0','0',0};
static WCHAR date_fmt[] = {'d','d','-','m','m',0};
static const WCHAR date[] = {'1','2','-','1','1',0};
static const WCHAR date_us[] = {'1','1','-','1','2',0};
static WCHAR string_fmt[] = {'@',0};
static const WCHAR string_de[] = {'1',',','5',0};
static const WCHAR string_us[] = {'1','.','5',0};
BYTE buff[256];
LCID lcid;
VARIANT var;
BSTR bstr;
HRESULT hres;
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(number);
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
hres = VarTokenizeFormatString(number_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
hres = VarFormatFromTokens(&var, number_fmt, buff, 0, &bstr, lcid);
ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
ok(!strcmpW(bstr, number_us), "incorrectly formatted number: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
lcid = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT);
hres = VarTokenizeFormatString(number_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
hres = VarFormatFromTokens(&var, number_fmt, buff, 0, &bstr, lcid);
ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
ok(!strcmpW(bstr, number), "incorrectly formatted number: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
VariantClear(&var);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(date);
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
hres = VarTokenizeFormatString(date_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
hres = VarFormatFromTokens(&var, date_fmt, buff, 0, &bstr, lcid);
ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
ok(!strcmpW(bstr, date_us), "incorrectly formatted date: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
lcid = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT);
hres = VarTokenizeFormatString(date_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
hres = VarFormatFromTokens(&var, date_fmt, buff, 0, &bstr, lcid);
ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
ok(!strcmpW(bstr, date), "incorrectly formatted date: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
VariantClear(&var);
V_VT(&var) = VT_R4;
V_R4(&var) = 1.5;
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
hres = VarTokenizeFormatString(string_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
hres = VarFormatFromTokens(&var, string_fmt, buff, 0, &bstr, lcid);
ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
ok(!strcmpW(bstr, string_us), "incorrectly formatted string: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
lcid = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT);
hres = VarTokenizeFormatString(string_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
hres = VarFormatFromTokens(&var, string_fmt, buff, 0, &bstr, lcid);
ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
ok(!strcmpW(bstr, string_de), "incorrectly formatted string: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
}
START_TEST(varformat)
{
hOleaut32 = GetModuleHandleA("oleaut32.dll");
@ -571,4 +653,5 @@ START_TEST(varformat)
test_VarFormatNumber();
test_VarFormat();
test_VarWeekdayName();
test_VarFormatFromTokens();
}

View file

@ -5403,9 +5403,12 @@ static void test_SysAllocString(void)
if (str)
{
LPINTERNAL_BSTR bstr = Get(str);
DWORD_PTR p = (DWORD_PTR)str;
int align = sizeof(void *);
ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
ok ((p & ~(align-1)) == p, "Not aligned to %d\n", align);
SysFreeString(str);
}
}
@ -5449,7 +5452,9 @@ static void test_SysAllocStringByteLen(void)
{
const OLECHAR szTest[10] = { 'T','e','s','t','\0' };
const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
char *buf;
BSTR str;
int i;
if (sizeof(void *) == 4) /* not limited to 0x80000000 on Win64 */
{
@ -5492,6 +5497,7 @@ static void test_SysAllocStringByteLen(void)
ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen);
ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
ok (!bstr->szString[2], "String not terminated\n");
SysFreeString(str);
}
@ -5505,6 +5511,32 @@ static void test_SysAllocStringByteLen(void)
ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
SysFreeString(str);
}
/* Make sure terminating null is aligned properly */
buf = HeapAlloc(GetProcessHeap(), 0, 1025);
ok (buf != NULL, "Expected non-NULL\n");
for (i = 0; i < 1024; i++)
{
LPINTERNAL_BSTR bstr;
str = SysAllocStringByteLen(NULL, i);
ok (str != NULL, "Expected non-NULL\n");
bstr = Get(str);
ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen);
ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n");
SysFreeString(str);
memset(buf, 0xaa, 1025);
str = SysAllocStringByteLen(buf, i);
ok (str != NULL, "Expected non-NULL\n");
bstr = Get(str);
ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen);
buf[i] = 0;
ok (!lstrcmpA((LPCSTR)bstr->szString, buf), "String different\n");
ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n");
SysFreeString(str);
}
HeapFree(GetProcessHeap(), 0, buf);
}
static void test_SysReAllocString(void)
@ -6342,9 +6374,15 @@ static void test_bstr_cache(void)
ok(str == str2, "str != str2\n");
SysFreeString(str2);
/* Fill the bucket with cached entries. */
/* Fill the bucket with cached entries.
We roll our own, to show that the cache doesn't use
the bstr length field to determine bucket allocation. */
for(i=0; i < sizeof(strs)/sizeof(*strs); i++)
strs[i] = SysAllocStringLen(NULL, 24);
{
DWORD_PTR *ptr = CoTaskMemAlloc(64);
ptr[0] = 0;
strs[i] = (BSTR)(ptr + 1);
}
for(i=0; i < sizeof(strs)/sizeof(*strs); i++)
SysFreeString(strs[i]);