diff --git a/rostests/winetests/scrrun/CMakeLists.txt b/rostests/winetests/scrrun/CMakeLists.txt index fd12af11829..23ce6e2ec2c 100644 --- a/rostests/winetests/scrrun/CMakeLists.txt +++ b/rostests/winetests/scrrun/CMakeLists.txt @@ -11,5 +11,5 @@ add_idl_headers(scrrun_idlheader_test scrrun.idl) add_dependencies(scrrun_winetest scrrun_idlheader_test) target_link_libraries(scrrun_winetest uuid) set_module_type(scrrun_winetest win32cui) -add_importlibs(scrrun_winetest ole32 oleaut32 msvcrt kernel32) +add_importlibs(scrrun_winetest ole32 oleaut32 user32 msvcrt kernel32) add_cd_file(TARGET scrrun_winetest DESTINATION reactos/bin FOR all) diff --git a/rostests/winetests/scrrun/dictionary.c b/rostests/winetests/scrrun/dictionary.c index e28bbb18cab..20c6d80e2a5 100644 --- a/rostests/winetests/scrrun/dictionary.c +++ b/rostests/winetests/scrrun/dictionary.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 Alistair Leslie-Hughes + * Copyright 2015 Nikolay Sivov for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,6 +23,7 @@ #include "windows.h" #include "ole2.h" #include "oleauto.h" +#include "olectl.h" #include "dispex.h" #include "wine/test.h" @@ -44,10 +46,7 @@ static void test_interfaces(void) hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IDispatch, (void**)&disp); - if(FAILED(hr)) { - win_skip("Could not create FileSystem object: %08x\n", hr); - return; - } + ok(hr == S_OK, "got 0x%08x\n", hr); VariantInit(&key); VariantInit(&value); @@ -66,37 +65,1003 @@ static void test_interfaces(void) V_VT(&value) = VT_BSTR; V_BSTR(&value) = SysAllocString(key_add_value); hr = IDictionary_Add(dict, &key, &value); - todo_wine ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); + ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); VariantClear(&value); exists = VARIANT_FALSE; hr = IDictionary_Exists(dict, &key, &exists); - todo_wine ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); - todo_wine ok(exists == VARIANT_TRUE, "Expected TRUE but got FALSE.\n"); + ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); + ok(exists == VARIANT_TRUE, "Expected TRUE but got FALSE.\n"); VariantClear(&key); exists = VARIANT_TRUE; V_VT(&key) = VT_BSTR; V_BSTR(&key) = SysAllocString(key_non_exist); hr = IDictionary_Exists(dict, &key, &exists); - todo_wine ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); - todo_wine ok(exists == VARIANT_FALSE, "Expected FALSE but got TRUE.\n"); + ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); + ok(exists == VARIANT_FALSE, "Expected FALSE but got TRUE.\n"); VariantClear(&key); hr = IDictionary_get_Count(dict, &count); ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); - todo_wine ok(count == 1, "got %d, expected 1\n", count); + ok(count == 1, "got %d, expected 1\n", count); IDictionary_Release(dict); IDispatch_Release(disp); } +static void test_comparemode(void) +{ + CompareMethod method; + IDictionary *dict; + VARIANT key, item; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x\n", hr); + +if (0) /* crashes on native */ + hr = IDictionary_get_CompareMode(dict, NULL); + + method = 10; + hr = IDictionary_get_CompareMode(dict, &method); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(method == BinaryCompare, "got %d\n", method); + + /* invalid mode value is not checked */ + hr = IDictionary_put_CompareMode(dict, 10); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDictionary_get_CompareMode(dict, &method); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(method == 10, "got %d\n", method); + + hr = IDictionary_put_CompareMode(dict, DatabaseCompare); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDictionary_get_CompareMode(dict, &method); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(method == DatabaseCompare, "got %d\n", method); + + /* try to change mode of a non-empty dict */ + V_VT(&key) = VT_I2; + V_I2(&key) = 0; + VariantInit(&item); + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDictionary_put_CompareMode(dict, BinaryCompare); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr); + + IDictionary_Release(dict); +} + +static DWORD get_str_hash(const WCHAR *str, CompareMethod method) +{ + DWORD hash = 0; + + while (*str) { + WCHAR ch; + + if (method == TextCompare || method == DatabaseCompare) + ch = PtrToInt(CharLowerW(IntToPtr(*str))); + else + ch = *str; + + hash += (hash << 4) + ch; + str++; + } + + return hash % 1201; +} + +static DWORD get_num_hash(FLOAT num) +{ + return (*((DWORD*)&num)) % 1201; +} + +static DWORD get_ptr_hash(void *ptr) +{ + return PtrToUlong(ptr) % 1201; +} + +typedef union +{ + struct + { + unsigned int m : 23; + unsigned int exp_bias : 8; + unsigned int sign : 1; + } i; + float f; +} R4_FIELDS; + +typedef union +{ + struct + { + unsigned int m_lo : 32; /* 52 bits of precision */ + unsigned int m_hi : 20; + unsigned int exp_bias : 11; /* bias == 1023 */ + unsigned int sign : 1; + } i; + double d; +} R8_FIELDS; + +static HRESULT WINAPI test_unk_QI(IUnknown *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown)) { + *obj = iface; + return S_OK; + } + + ok(0, "unexpected %s\n", wine_dbgstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static HRESULT WINAPI test_unk_no_QI(IUnknown *iface, REFIID riid, void **obj) +{ + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_unk_AddRef(IUnknown *iface) +{ + ok(0, "unxpected\n"); + return 2; +} + +static ULONG WINAPI test_unk_Release(IUnknown *iface) +{ + return 1; +} + +static IUnknownVtbl test_unk_vtbl = { + test_unk_QI, + test_unk_AddRef, + test_unk_Release +}; + +static IUnknownVtbl test_unk_no_vtbl = { + test_unk_no_QI, + test_unk_AddRef, + test_unk_Release +}; + +static HRESULT WINAPI test_disp_QI(IDispatch *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) { + *obj = iface; + return S_OK; + } + + ok(0, "unexpected %s\n", wine_dbgstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_disp_AddRef(IDispatch *iface) +{ + ok(0, "unxpected\n"); + return 2; +} + +static ULONG WINAPI test_disp_Release(IDispatch *iface) +{ + return 1; +} + +static HRESULT WINAPI test_disp_GetTypeInfoCount(IDispatch *iface, UINT *count) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_disp_GetTypeInfo(IDispatch *iface, UINT index, LCID lcid, ITypeInfo **ti) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_disp_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names, + UINT name_count, LCID lcid, DISPID *dispid) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_disp_Invoke(IDispatch *iface, DISPID dispid, REFIID riid, + LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *arg_err) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static IDispatchVtbl test_disp_vtbl = { + test_disp_QI, + test_disp_AddRef, + test_disp_Release, + test_disp_GetTypeInfoCount, + test_disp_GetTypeInfo, + test_disp_GetIDsOfNames, + test_disp_Invoke +}; + +static IUnknown test_unk = { &test_unk_vtbl }; +static IUnknown test_unk2 = { &test_unk_no_vtbl }; +static IDispatch test_disp = { &test_disp_vtbl }; + +static void test_hash_value(void) +{ + /* string test data */ + static const WCHAR str_hash_tests[][10] = { + {'a','b','c','d',0}, + {'a','B','C','d','1',0}, + {'1','2','3',0}, + {'A',0}, + {'a',0}, + { 0 } + }; + + static const int int_hash_tests[] = { + 0, -1, 100, 1, 255 + }; + + static const FLOAT float_hash_tests[] = { + 0.0, -1.0, 100.0, 1.0, 255.0, 1.234 + }; + + IDictionary *dict; + VARIANT key, hash; + IDispatch *disp; + DWORD expected; + IUnknown *unk; + R8_FIELDS fx8; + R4_FIELDS fx4; + HRESULT hr; + unsigned i; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&key) = VT_BSTR; + V_BSTR(&key) = NULL; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == 0, "got %d\n", V_I4(&hash)); + + for (i = 0; i < sizeof(str_hash_tests)/sizeof(str_hash_tests[0]); i++) { + expected = get_str_hash(str_hash_tests[i], BinaryCompare); + + hr = IDictionary_put_CompareMode(dict, BinaryCompare); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&key) = VT_BSTR; + V_BSTR(&key) = SysAllocString(str_hash_tests[i]); + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: binary mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + VariantClear(&key); + + expected = get_str_hash(str_hash_tests[i], TextCompare); + hr = IDictionary_put_CompareMode(dict, TextCompare); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&key) = VT_BSTR; + V_BSTR(&key) = SysAllocString(str_hash_tests[i]); + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: text mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + VariantClear(&key); + + expected = get_str_hash(str_hash_tests[i], DatabaseCompare); + hr = IDictionary_put_CompareMode(dict, DatabaseCompare); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&key) = VT_BSTR; + V_BSTR(&key) = SysAllocString(str_hash_tests[i]); + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: db mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + VariantClear(&key); + } + + V_VT(&key) = VT_INT; + V_INT(&key) = 1; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash)); + + V_VT(&key) = VT_UINT; + V_UINT(&key) = 1; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash)); + + V_VT(&key) = VT_I1; + V_I1(&key) = 1; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0xa1), "got hash 0x%08x\n", V_I4(&hash)); + + V_VT(&key) = VT_I8; + V_I8(&key) = 1; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash)); + + V_VT(&key) = VT_UI2; + V_UI2(&key) = 1; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash)); + + V_VT(&key) = VT_UI4; + V_UI4(&key) = 1; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash)); + + for (i = 0; i < sizeof(int_hash_tests)/sizeof(int_hash_tests[0]); i++) { + SHORT i2; + BYTE ui1; + LONG i4; + + expected = get_num_hash(int_hash_tests[i]); + + V_VT(&key) = VT_I2; + V_I2(&key) = int_hash_tests[i]; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + i2 = int_hash_tests[i]; + V_VT(&key) = VT_I2|VT_BYREF; + V_I2REF(&key) = &i2; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + V_VT(&key) = VT_I4; + V_I4(&key) = int_hash_tests[i]; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + i4 = int_hash_tests[i]; + V_VT(&key) = VT_I4|VT_BYREF; + V_I4REF(&key) = &i4; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + expected = get_num_hash((FLOAT)(BYTE)int_hash_tests[i]); + V_VT(&key) = VT_UI1; + V_UI1(&key) = int_hash_tests[i]; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + ui1 = int_hash_tests[i]; + V_VT(&key) = VT_UI1|VT_BYREF; + V_UI1REF(&key) = &ui1; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + } + + /* nan */ + fx4.f = 10.0; + fx4.i.exp_bias = 0xff; + + V_VT(&key) = VT_R4; + V_R4(&key) = fx4.f; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ || + V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash)); + + /* inf */ + fx4.f = 10.0; + fx4.i.m = 0; + fx4.i.exp_bias = 0xff; + + V_VT(&key) = VT_R4; + V_R4(&key) = fx4.f; + V_I4(&hash) = 10; + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash)); + + /* nan */ + fx8.d = 10.0; + fx8.i.exp_bias = 0x7ff; + + V_VT(&key) = VT_R8; + V_R8(&key) = fx8.d; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ || + V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash)); + + V_VT(&key) = VT_DATE; + V_DATE(&key) = fx8.d; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ || + V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash)); + + /* inf */ + fx8.d = 10.0; + fx8.i.m_lo = 0; + fx8.i.m_hi = 0; + fx8.i.exp_bias = 0x7ff; + + V_VT(&key) = VT_R8; + V_R8(&key) = fx8.d; + V_I4(&hash) = 10; + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash)); + + V_VT(&key) = VT_DATE; + V_DATE(&key) = fx8.d; + V_I4(&hash) = 10; + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash)); + + for (i = 0; i < sizeof(float_hash_tests)/sizeof(float_hash_tests[0]); i++) { + double dbl; + FLOAT flt; + DATE date; + + expected = get_num_hash(float_hash_tests[i]); + + V_VT(&key) = VT_R4; + V_R4(&key) = float_hash_tests[i]; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + flt = float_hash_tests[i]; + V_VT(&key) = VT_R4|VT_BYREF; + V_R4REF(&key) = &flt; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + V_VT(&key) = VT_R8; + V_R8(&key) = float_hash_tests[i]; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + dbl = float_hash_tests[i]; + V_VT(&key) = VT_R8|VT_BYREF; + V_R8REF(&key) = &dbl; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + V_VT(&key) = VT_DATE; + V_DATE(&key) = float_hash_tests[i]; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + + V_VT(&key) = VT_DATE|VT_BYREF; + date = float_hash_tests[i]; + V_DATEREF(&key) = &date; + VariantInit(&hash); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash), + expected); + } + + /* interface pointers as keys */ + V_VT(&key) = VT_UNKNOWN; + V_UNKNOWN(&key) = 0; + VariantInit(&hash); + V_I4(&hash) = 1; + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash)); + + /* QI doesn't work */ + V_VT(&key) = VT_UNKNOWN; + V_UNKNOWN(&key) = &test_unk2; + VariantInit(&hash); + expected = get_ptr_hash(&test_unk2); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == ~0u, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected); + + V_VT(&key) = VT_UNKNOWN; + V_UNKNOWN(&key) = &test_unk; + VariantInit(&hash); + expected = get_ptr_hash(&test_unk); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected); + + /* interface without IDispatch support */ + V_VT(&key) = VT_DISPATCH; + V_DISPATCH(&key) = (IDispatch*)&test_unk; + VariantInit(&hash); + expected = get_ptr_hash(&test_unk); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected); + + V_VT(&key) = VT_DISPATCH; + V_DISPATCH(&key) = &test_disp; + VariantInit(&hash); + expected = get_ptr_hash(&test_disp); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected); + + /* same with BYREF */ +if (0) { /* crashes on native */ + V_VT(&key) = VT_UNKNOWN|VT_BYREF; + V_UNKNOWNREF(&key) = 0; + hr = IDictionary_get_HashVal(dict, &key, &hash); +} + unk = NULL; + V_VT(&key) = VT_UNKNOWN|VT_BYREF; + V_UNKNOWNREF(&key) = &unk; + VariantInit(&hash); + V_I4(&hash) = 1; + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash)); + + V_VT(&key) = VT_UNKNOWN|VT_BYREF; + unk = &test_unk; + V_UNKNOWNREF(&key) = &unk; + VariantInit(&hash); + expected = get_ptr_hash(&test_unk); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected); + + /* interface without IDispatch support */ + V_VT(&key) = VT_DISPATCH|VT_BYREF; + unk = &test_unk; + V_DISPATCHREF(&key) = (IDispatch**)&unk; + VariantInit(&hash); + expected = get_ptr_hash(&test_unk); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected); + + V_VT(&key) = VT_DISPATCH|VT_BYREF; + disp = &test_disp; + V_DISPATCHREF(&key) = &disp; + VariantInit(&hash); + expected = get_ptr_hash(&test_disp); + hr = IDictionary_get_HashVal(dict, &key, &hash); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); + ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected); + + IDictionary_Release(dict); +} + +static void test_Exists(void) +{ + VARIANT_BOOL exists; + IDictionary *dict; + VARIANT key, item; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x\n", hr); + +if (0) /* crashes on native */ + hr = IDictionary_Exists(dict, NULL, NULL); + + V_VT(&key) = VT_I2; + V_I2(&key) = 0; + hr = IDictionary_Exists(dict, &key, NULL); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr); + + V_VT(&key) = VT_I2; + V_I2(&key) = 0; + exists = VARIANT_TRUE; + hr = IDictionary_Exists(dict, &key, &exists); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(exists == VARIANT_FALSE, "got %x\n", exists); + + VariantInit(&item); + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&key) = VT_R4; + V_R4(&key) = 0.0; + hr = IDictionary_Add(dict, &key, &item); + ok(hr == CTL_E_KEY_ALREADY_EXISTS, "got 0x%08x\n", hr); + + V_VT(&key) = VT_I2; + V_I2(&key) = 0; + hr = IDictionary_Exists(dict, &key, NULL); + ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr); + + V_VT(&key) = VT_I2; + V_I2(&key) = 0; + exists = VARIANT_FALSE; + hr = IDictionary_Exists(dict, &key, &exists); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(exists == VARIANT_TRUE, "got %x\n", exists); + + /* key of different type, but resolves to same hash value */ + V_VT(&key) = VT_R4; + V_R4(&key) = 0.0; + exists = VARIANT_FALSE; + hr = IDictionary_Exists(dict, &key, &exists); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(exists == VARIANT_TRUE, "got %x\n", exists); + + IDictionary_Release(dict); +} + +static void test_Keys(void) +{ + VARIANT key, keys, item; + IDictionary *dict; + LONG index; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDictionary_Keys(dict, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + VariantInit(&keys); + hr = IDictionary_Keys(dict, &keys); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys)); + VariantClear(&keys); + + V_VT(&key) = VT_R4; + V_R4(&key) = 0.0; + VariantInit(&item); + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + VariantInit(&keys); + hr = IDictionary_Keys(dict, &keys); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys)); + + VariantInit(&key); + index = 0; + hr = SafeArrayGetElement(V_ARRAY(&keys), &index, &key); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&key) == VT_R4, "got %d\n", V_VT(&key)); + + index = SafeArrayGetDim(V_ARRAY(&keys)); + ok(index == 1, "got %d\n", index); + + hr = SafeArrayGetUBound(V_ARRAY(&keys), 1, &index); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(index == 0, "got %d\n", index); + + VariantClear(&keys); + + IDictionary_Release(dict); +} + +static void test_Remove(void) +{ + VARIANT key, item; + IDictionary *dict; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x\n", hr); + +if (0) + hr = IDictionary_Remove(dict, NULL); + + /* nothing added yet */ + V_VT(&key) = VT_R4; + V_R4(&key) = 0.0; + hr = IDictionary_Remove(dict, &key); + ok(hr == CTL_E_ELEMENT_NOT_FOUND, "got 0x%08x\n", hr); + + VariantInit(&item); + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDictionary_Remove(dict, &key); + ok(hr == S_OK, "got 0x%08x\n", hr); + + IDictionary_Release(dict); +} + +static void test_Item(void) +{ + VARIANT key, item; + IDictionary *dict; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&key) = VT_I2; + V_I2(&key) = 10; + V_VT(&item) = VT_I2; + V_I2(&item) = 123; + hr = IDictionary_get_Item(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item)); + + V_VT(&key) = VT_I2; + V_I2(&key) = 10; + V_VT(&item) = VT_I2; + hr = IDictionary_get_Item(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item)); + + IDictionary_Release(dict); +} + +static void test_Add(void) +{ + static const WCHAR testW[] = {'t','e','s','t','W',0}; + VARIANT key, item; + IDictionary *dict; + HRESULT hr; + BSTR str; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = SysAllocString(testW); + V_VT(&key) = VT_I2; + V_I2(&key) = 1; + V_VT(&item) = VT_BSTR|VT_BYREF; + V_BSTRREF(&item) = &str; + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDictionary_get_Item(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&item) == VT_BSTR, "got %d\n", V_VT(&item)); + + SysFreeString(str); + + IDictionary_Release(dict); +} + +static void test_IEnumVARIANT(void) +{ + IUnknown *enum1, *enum2; + IEnumVARIANT *enumvar; + VARIANT key, item; + IDictionary *dict; + ULONG fetched; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x\n", hr); + +if (0) /* crashes on native */ + hr = IDictionary__NewEnum(dict, NULL); + + hr = IDictionary__NewEnum(dict, &enum1); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDictionary__NewEnum(dict, &enum2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(enum1 != enum2, "got %p, %p\n", enum2, enum1); + IUnknown_Release(enum2); + + hr = IUnknown_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enumvar); + ok(hr == S_OK, "got 0x%08x\n", hr); + IUnknown_Release(enum1); + + /* dictionary is empty */ + hr = IEnumVARIANT_Skip(enumvar, 1); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + hr = IEnumVARIANT_Skip(enumvar, 0); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&key) = VT_I2; + V_I2(&key) = 1; + V_VT(&item) = VT_I4; + V_I4(&item) = 100; + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IEnumVARIANT_Skip(enumvar, 0); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IEnumVARIANT_Reset(enumvar); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IEnumVARIANT_Skip(enumvar, 1); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IEnumVARIANT_Skip(enumvar, 1); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + V_VT(&key) = VT_I2; + V_I2(&key) = 4000; + V_VT(&item) = VT_I4; + V_I4(&item) = 200; + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&key) = VT_I2; + V_I2(&key) = 0; + V_VT(&item) = VT_I4; + V_I4(&item) = 300; + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IEnumVARIANT_Reset(enumvar); + ok(hr == S_OK, "got 0x%08x\n", hr); + + VariantInit(&key); + hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key)); + ok(V_I2(&key) == 1, "got %d\n", V_I2(&key)); + ok(fetched == 1, "got %u\n", fetched); + + hr = IEnumVARIANT_Reset(enumvar); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDictionary_Remove(dict, &key); + ok(hr == S_OK, "got 0x%08x\n", hr); + + VariantInit(&key); + hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key)); + ok(V_I2(&key) == 4000, "got %d\n", V_I2(&key)); + ok(fetched == 1, "got %u\n", fetched); + + VariantInit(&key); + hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key)); + ok(V_I2(&key) == 0, "got %d\n", V_I2(&key)); + ok(fetched == 1, "got %u\n", fetched); + + /* enumeration reached the bottom, add one more pair */ + VariantInit(&key); + hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + V_VT(&key) = VT_I2; + V_I2(&key) = 13; + V_VT(&item) = VT_I4; + V_I4(&item) = 350; + hr = IDictionary_Add(dict, &key, &item); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* still doesn't work until Reset() */ + VariantInit(&key); + hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + IEnumVARIANT_Release(enumvar); + IDictionary_Release(dict); +} + START_TEST(dictionary) { + IDispatch *disp; + HRESULT hr; + CoInitialize(NULL); - test_interfaces(); + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDispatch, (void**)&disp); + if(FAILED(hr)) { + win_skip("Dictionary object is not supported: %08x\n", hr); + CoUninitialize(); + return; + } + IDispatch_Release(disp); + test_interfaces(); + test_comparemode(); + test_hash_value(); + test_Exists(); + test_Keys(); + test_Remove(); + test_Item(); + test_Add(); + test_IEnumVARIANT(); CoUninitialize(); } diff --git a/rostests/winetests/scrrun/filesystem.c b/rostests/winetests/scrrun/filesystem.c index 9bab10ae7b6..28242ce46bf 100644 --- a/rostests/winetests/scrrun/filesystem.c +++ b/rostests/winetests/scrrun/filesystem.c @@ -20,6 +20,7 @@ #define COBJMACROS #include +#include #include "windows.h" #include "ole2.h" @@ -34,6 +35,9 @@ static IFileSystem3 *fs3; +/* w2k and 2k3 error code. */ +#define E_VAR_NOT_SET 0x800a005b + static inline ULONG get_refcount(IUnknown *iface) { IUnknown_AddRef(iface); @@ -537,11 +541,11 @@ static void test_GetAbsolutePathName(void) static void test_GetFile(void) { static const WCHAR slW[] = {'\\',0}; - BSTR path; + BSTR path, str; WCHAR pathW[MAX_PATH]; FileAttribute fa; VARIANT size; - DWORD gfa; + DWORD gfa, new_gfa; IFile *file; HRESULT hr; HANDLE hf; @@ -571,10 +575,38 @@ static void test_GetFile(void) hr = IFileSystem3_GetFile(fs3, path, &file); ok(hr == S_OK, "GetFile returned %x, expected S_OK\n", hr); + hr = IFile_get_Path(file, NULL); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + + hr = IFile_get_Path(file, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, pathW), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + +#define FILE_ATTR_MASK (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \ + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE | \ + FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED) + + hr = IFile_get_Attributes(file, &fa); + gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK; + ok(hr == S_OK, "get_Attributes returned %x, expected S_OK\n", hr); + ok(fa == gfa, "fa = %x, expected %x\n", fa, gfa); + + hr = IFile_put_Attributes(file, gfa | FILE_ATTRIBUTE_READONLY); + ok(hr == S_OK, "put_Attributes failed: %08x\n", hr); + new_gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK; + ok(new_gfa == (gfa|FILE_ATTRIBUTE_READONLY), "new_gfa = %x, expected %x\n", new_gfa, gfa|FILE_ATTRIBUTE_READONLY); + + hr = IFile_get_Attributes(file, &fa); + ok(hr == S_OK, "get_Attributes returned %x, expected S_OK\n", hr); + ok(fa == new_gfa, "fa = %x, expected %x\n", fa, new_gfa); + + hr = IFile_put_Attributes(file, gfa); + ok(hr == S_OK, "put_Attributes failed: %08x\n", hr); + new_gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK; + ok(new_gfa == gfa, "new_gfa = %x, expected %x\n", new_gfa, gfa); + hr = IFile_get_Attributes(file, &fa); - gfa = GetFileAttributesW(pathW) & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | - FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE | - FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED); ok(hr == S_OK, "get_Attributes returned %x, expected S_OK\n", hr); ok(fa == gfa, "fa = %x, expected %x\n", fa, gfa); @@ -1349,6 +1381,15 @@ static void test_CreateTextFile(void) hr = ITextStream_Read(stream, 1, &str); ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr); + hr = ITextStream_Close(stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextStream_Read(stream, 1, &str); + ok(hr == CTL_E_BADFILEMODE || hr == E_VAR_NOT_SET, "got 0x%08x\n", hr); + + hr = ITextStream_Close(stream); + ok(hr == S_FALSE || hr == E_VAR_NOT_SET, "got 0x%08x\n", hr); + ITextStream_Release(stream); /* check it's created */ @@ -1864,6 +1905,88 @@ static void test_SerialNumber(void) IEnumVARIANT_Release(iter); } +static const struct extension_test { + WCHAR path[20]; + WCHAR ext[10]; +} extension_tests[] = { + { {'n','o','e','x','t',0}, {0} }, + { {'n','.','o','.','e','x','t',0}, {'e','x','t',0} }, + { {'n','.','o','.','e','X','t',0}, {'e','X','t',0} }, + { { 0 } } +}; + +static void test_GetExtensionName(void) +{ + BSTR path, ext; + HRESULT hr; + int i; + + for (i = 0; i < sizeof(extension_tests)/sizeof(extension_tests[0]); i++) { + + path = SysAllocString(extension_tests[i].path); + ext = NULL; + hr = IFileSystem3_GetExtensionName(fs3, path, &ext); + ok(hr == S_OK, "got 0x%08x\n", hr); + if (*extension_tests[i].ext) + ok(!lstrcmpW(ext, extension_tests[i].ext), "%d: path %s, got %s, expected %s\n", i, + wine_dbgstr_w(path), wine_dbgstr_w(ext), wine_dbgstr_w(extension_tests[i].ext)); + else + ok(ext == NULL, "%d: path %s, got %s, expected %s\n", i, + wine_dbgstr_w(path), wine_dbgstr_w(ext), wine_dbgstr_w(extension_tests[i].ext)); + + SysFreeString(path); + SysFreeString(ext); + } +} + +static void test_GetSpecialFolder(void) +{ + WCHAR pathW[MAX_PATH]; + IFolder *folder; + HRESULT hr; + DWORD ret; + BSTR path; + + hr = IFileSystem3_GetSpecialFolder(fs3, WindowsFolder, NULL); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + + hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder+1, NULL); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + + hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder+1, &folder); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = IFileSystem3_GetSpecialFolder(fs3, WindowsFolder, &folder); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IFolder_get_Path(folder, &path); + ok(hr == S_OK, "got 0x%08x\n", hr); + GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR)); + ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW)); + SysFreeString(path); + IFolder_Release(folder); + + hr = IFileSystem3_GetSpecialFolder(fs3, SystemFolder, &folder); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IFolder_get_Path(folder, &path); + ok(hr == S_OK, "got 0x%08x\n", hr); + GetSystemDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR)); + ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW)); + SysFreeString(path); + IFolder_Release(folder); + + hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder, &folder); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IFolder_get_Path(folder, &path); + ok(hr == S_OK, "got 0x%08x\n", hr); + ret = GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW); + if (ret && pathW[ret-1] == '\\') + pathW[ret-1] = 0; + + ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW)); + SysFreeString(path); + IFolder_Release(folder); +} + START_TEST(filesystem) { HRESULT hr; @@ -1898,6 +2021,8 @@ START_TEST(filesystem) test_Read(); test_GetDriveName(); test_SerialNumber(); + test_GetExtensionName(); + test_GetSpecialFolder(); IFileSystem3_Release(fs3); diff --git a/rostests/winetests/scrrun/scrrun.idl b/rostests/winetests/scrrun/scrrun.idl index 96835c7579d..91e01517ae3 100644 --- a/rostests/winetests/scrrun/scrrun.idl +++ b/rostests/winetests/scrrun/scrrun.idl @@ -24,7 +24,10 @@ cpp_quote("#undef CopyFile") cpp_quote("#undef DeleteFile") cpp_quote("#undef MoveFile") cpp_quote("#endif") -cpp_quote("#define CTL_E_ENDOFFILE STD_CTL_SCODE(62)") /* this is not defined in public headers */ +/* this is not defined in public headers */ +cpp_quote("#define CTL_E_ENDOFFILE STD_CTL_SCODE(62)") +cpp_quote("#define CTL_E_KEY_ALREADY_EXISTS STD_CTL_SCODE(457)") +cpp_quote("#define CTL_E_ELEMENT_NOT_FOUND STD_CTL_SCODE(32811)") [ uuid(420B2830-E718-11CF-893D-00A0C9054228),