diff --git a/dlls/scrrun/dictionary.c b/dlls/scrrun/dictionary.c index d615426971d..b5edfc66af0 100644 --- a/dlls/scrrun/dictionary.c +++ b/dlls/scrrun/dictionary.c @@ -23,6 +23,7 @@ #include "windef.h" #include "winbase.h" #include "ole2.h" +#include "olectl.h" #include "dispex.h" #include "scrrun.h" #include "scrrun_private.h" @@ -309,6 +310,11 @@ static DWORD get_str_hash(const WCHAR *str, CompareMethod method) return hash % 1201; } +static DWORD get_num_hash(FLOAT num) +{ + return (*((DWORD*)&num)) % 1201; +} + static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *key, VARIANT *hash) { dictionary *This = impl_from_IDictionary(iface); @@ -321,6 +327,23 @@ static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *key, V case VT_BSTR: V_I4(hash) = get_str_hash(V_BSTR(key), This->method); break; + case VT_UI1: + V_I4(hash) = get_num_hash(V_UI1(key)); + break; + case VT_I2: + V_I4(hash) = get_num_hash(V_I2(key)); + break; + case VT_I4: + V_I4(hash) = get_num_hash(V_I4(key)); + break; + case VT_INT: + case VT_UINT: + case VT_I1: + case VT_I8: + case VT_UI2: + case VT_UI4: + V_I4(hash) = ~0u; + return CTL_E_ILLEGALFUNCTIONCALL; default: FIXME("not implemented for type %d\n", V_VT(key)); return E_NOTIMPL; diff --git a/dlls/scrrun/tests/dictionary.c b/dlls/scrrun/tests/dictionary.c index 1cb60b69e31..0a168e0549d 100644 --- a/dlls/scrrun/tests/dictionary.c +++ b/dlls/scrrun/tests/dictionary.c @@ -22,6 +22,7 @@ #include "windows.h" #include "ole2.h" #include "oleauto.h" +#include "olectl.h" #include "dispex.h" #include "wine/test.h" @@ -143,6 +144,11 @@ static DWORD get_str_hash(const WCHAR *str, CompareMethod method) return hash % 1201; } +static DWORD get_num_hash(FLOAT num) +{ + return (*((DWORD*)&num)) % 1201; +} + static void test_hash_value(void) { /* string test data */ @@ -155,6 +161,10 @@ static void test_hash_value(void) { 0 } }; + static const int int_hash_tests[] = { + 0, -1, 100, 1, 255 + }; + IDictionary *dict; VARIANT key, hash; HRESULT hr; @@ -217,6 +227,86 @@ static void test_hash_value(void) 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++) { + DWORD 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); + + 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); + + 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); + } + IDictionary_Release(dict); }