1 /* 2 * Unit tests for IPropertyStore and related interfaces 3 * 4 * Copyright 2012 Vincent Povirk 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include <stdarg.h> 24 #include <stdio.h> 25 26 #define NONAMELESSUNION 27 28 #include "windef.h" 29 #include "winbase.h" 30 #include "objbase.h" 31 #include "propsys.h" 32 #include "wine/test.h" 33 34 #include "initguid.h" 35 36 DEFINE_GUID(PKEY_WineTest, 0x7b317433, 0xdfa3, 0x4c44, 0xad, 0x3e, 0x2f, 0x80, 0x4b, 0x90, 0xdb, 0xf4); 37 DEFINE_GUID(DUMMY_GUID1, 0x12345678, 0x1234,0x1234, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19); 38 39 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__) 40 static void _expect_ref(IUnknown *obj, ULONG ref, int line) 41 { 42 ULONG rc; 43 IUnknown_AddRef(obj); 44 rc = IUnknown_Release(obj); 45 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); 46 } 47 48 static void test_inmemorystore(void) 49 { 50 IPropertyStoreCache *propcache; 51 HRESULT hr; 52 PROPERTYKEY pkey; 53 PROPVARIANT propvar; 54 DWORD count; 55 PSC_STATE state; 56 57 hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, 58 &IID_IPropertyStoreCache, (void**)&propcache); 59 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); 60 61 if (FAILED(hr)) 62 { 63 skip("CLSID_InMemoryPropertyStore not supported\n"); 64 return; 65 } 66 67 hr = IPropertyStoreCache_GetCount(propcache, NULL); 68 ok(hr == E_POINTER, "GetCount failed, hr=%x\n", hr); 69 70 hr = IPropertyStoreCache_GetCount(propcache, &count); 71 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); 72 ok(count == 0, "GetCount returned %i, expected 0\n", count); 73 74 hr = IPropertyStoreCache_Commit(propcache); 75 ok(hr == S_OK, "Commit failed, hr=%x\n", hr); 76 77 hr = IPropertyStoreCache_Commit(propcache); 78 ok(hr == S_OK, "Commit failed, hr=%x\n", hr); 79 80 hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); 81 ok(hr == E_INVALIDARG, "GetAt failed, hr=%x\n", hr); 82 83 pkey.fmtid = PKEY_WineTest; 84 pkey.pid = 4; 85 86 memset(&propvar, 0, sizeof(propvar)); 87 propvar.vt = VT_I4; 88 propvar.u.lVal = 12345; 89 90 if (0) 91 { 92 /* Crashes on Windows 7 */ 93 hr = IPropertyStoreCache_SetValue(propcache, NULL, &propvar); 94 ok(hr == E_POINTER, "SetValue failed, hr=%x\n", hr); 95 96 hr = IPropertyStoreCache_SetValue(propcache, &pkey, NULL); 97 ok(hr == E_POINTER, "SetValue failed, hr=%x\n", hr); 98 } 99 100 hr = IPropertyStoreCache_SetValue(propcache, &pkey, &propvar); 101 ok(hr == S_OK, "SetValue failed, hr=%x\n", hr); 102 103 hr = IPropertyStoreCache_GetCount(propcache, &count); 104 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); 105 ok(count == 1, "GetCount returned %i, expected 0\n", count); 106 107 memset(&pkey, 0, sizeof(pkey)); 108 109 hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); 110 ok(hr == S_OK, "GetAt failed, hr=%x\n", hr); 111 ok(IsEqualGUID(&pkey.fmtid, &PKEY_WineTest), "got wrong pkey\n"); 112 ok(pkey.pid == 4, "got pid of %i, expected 4\n", pkey.pid); 113 114 pkey.fmtid = PKEY_WineTest; 115 pkey.pid = 4; 116 117 memset(&propvar, 0, sizeof(propvar)); 118 119 if (0) 120 { 121 /* Crashes on Windows 7 */ 122 hr = IPropertyStoreCache_GetValue(propcache, NULL, &propvar); 123 ok(hr == E_POINTER, "GetValue failed, hr=%x\n", hr); 124 } 125 126 hr = IPropertyStoreCache_GetValue(propcache, &pkey, NULL); 127 ok(hr == E_POINTER, "GetValue failed, hr=%x\n", hr); 128 129 hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); 130 ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); 131 ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); 132 ok(propvar.u.lVal == 12345, "expected 12345, got %d\n", propvar.u.lVal); 133 134 pkey.fmtid = PKEY_WineTest; 135 pkey.pid = 10; 136 137 /* Get information for field that isn't set yet */ 138 propvar.vt = VT_I2; 139 hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); 140 ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); 141 ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); 142 143 state = 0xdeadbeef; 144 hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); 145 ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetState failed, hr=%x\n", hr); 146 ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); 147 148 propvar.vt = VT_I2; 149 state = 0xdeadbeef; 150 hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); 151 ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetValueAndState failed, hr=%x\n", hr); 152 ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); 153 ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); 154 155 /* Set state on an unset field */ 156 hr = IPropertyStoreCache_SetState(propcache, &pkey, PSC_NORMAL); 157 ok(hr == TYPE_E_ELEMENTNOTFOUND, "SetState failed, hr=%x\n", hr); 158 159 /* Manipulate state on already set field */ 160 pkey.fmtid = PKEY_WineTest; 161 pkey.pid = 4; 162 163 state = 0xdeadbeef; 164 hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); 165 ok(hr == S_OK, "GetState failed, hr=%x\n", hr); 166 ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); 167 168 hr = IPropertyStoreCache_SetState(propcache, &pkey, 10); 169 ok(hr == S_OK, "SetState failed, hr=%x\n", hr); 170 171 state = 0xdeadbeef; 172 hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); 173 ok(hr == S_OK, "GetState failed, hr=%x\n", hr); 174 ok(state == 10, "expected 10, got %d\n", state); 175 176 propvar.vt = VT_I4; 177 propvar.u.lVal = 12346; 178 hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, 5); 179 ok(hr == S_OK, "SetValueAndState failed, hr=%x\n", hr); 180 181 memset(&propvar, 0, sizeof(propvar)); 182 state = 0xdeadbeef; 183 hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); 184 ok(hr == S_OK, "GetValueAndState failed, hr=%x\n", hr); 185 ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); 186 ok(propvar.u.lVal == 12346, "expected 12346, got %d\n", propvar.vt); 187 ok(state == 5, "expected 5, got %d\n", state); 188 189 /* Set new field with state */ 190 pkey.fmtid = PKEY_WineTest; 191 pkey.pid = 8; 192 193 propvar.vt = VT_I4; 194 propvar.u.lVal = 12347; 195 hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, PSC_DIRTY); 196 ok(hr == S_OK, "SetValueAndState failed, hr=%x\n", hr); 197 198 memset(&propvar, 0, sizeof(propvar)); 199 state = 0xdeadbeef; 200 hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); 201 ok(hr == S_OK, "GetValueAndState failed, hr=%x\n", hr); 202 ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); 203 ok(propvar.u.lVal == 12347, "expected 12347, got %d\n", propvar.vt); 204 ok(state == PSC_DIRTY, "expected PSC_DIRTY, got %d\n", state); 205 206 IPropertyStoreCache_Release(propcache); 207 } 208 209 static void test_persistserialized(void) 210 { 211 IPropertyStore *propstore; 212 IPersistSerializedPropStorage *serialized; 213 HRESULT hr; 214 SERIALIZEDPROPSTORAGE *result; 215 DWORD result_size; 216 217 hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, 218 &IID_IPropertyStore, (void**)&propstore); 219 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); 220 221 hr = IPropertyStore_QueryInterface(propstore, &IID_IPersistSerializedPropStorage, 222 (void**)&serialized); 223 todo_wine ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); 224 225 if (FAILED(hr)) 226 { 227 IPropertyStore_Release(propstore); 228 skip("IPersistSerializedPropStorage not supported\n"); 229 return; 230 } 231 232 hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, NULL, &result_size); 233 ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%x\n", hr); 234 235 hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, NULL); 236 ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%x\n", hr); 237 238 hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, &result_size); 239 ok(hr == S_OK, "GetPropertyStorage failed, hr=%x\n", hr); 240 241 if (SUCCEEDED(hr)) 242 { 243 ok(result_size == 0, "expected 0 bytes, got %i\n", result_size); 244 245 CoTaskMemFree(result); 246 } 247 248 hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 4); 249 ok(hr == E_POINTER, "SetPropertyStorage failed, hr=%x\n", hr); 250 251 hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 0); 252 ok(hr == S_OK, "SetPropertyStorage failed, hr=%x\n", hr); 253 254 hr = IPropertyStore_GetCount(propstore, &result_size); 255 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); 256 ok(result_size == 0, "expecting 0, got %d\n", result_size); 257 258 IPropertyStore_Release(propstore); 259 IPersistSerializedPropStorage_Release(serialized); 260 } 261 262 static void test_PSCreateMemoryPropertyStore(void) 263 { 264 IPropertyStore *propstore, *propstore1; 265 IPersistSerializedPropStorage *serialized; 266 IPropertyStoreCache *propstorecache; 267 HRESULT hr; 268 269 /* PSCreateMemoryPropertyStore(&IID_IPropertyStore, NULL); crashes */ 270 271 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); 272 ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); 273 ok(propstore != NULL, "got %p.\n", propstore); 274 EXPECT_REF(propstore, 1); 275 276 hr = PSCreateMemoryPropertyStore(&IID_IPersistSerializedPropStorage, (void **)&serialized); 277 todo_wine ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); 278 todo_wine ok(serialized != NULL, "got %p.\n", serialized); 279 EXPECT_REF(propstore, 1); 280 if(serialized) 281 { 282 EXPECT_REF(serialized, 1); 283 IPersistSerializedPropStorage_Release(serialized); 284 } 285 286 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStoreCache, (void **)&propstorecache); 287 ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); 288 ok(propstorecache != NULL, "got %p.\n", propstore); 289 ok(propstorecache != (IPropertyStoreCache *)propstore, "pointer are equal: %p, %p.\n", propstorecache, propstore); 290 EXPECT_REF(propstore, 1); 291 EXPECT_REF(propstorecache, 1); 292 293 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore1); 294 ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); 295 ok(propstore1 != NULL, "got %p.\n", propstore); 296 ok(propstore1 != propstore, "pointer are equal: %p, %p.\n", propstore1, propstore); 297 EXPECT_REF(propstore, 1); 298 EXPECT_REF(propstore1, 1); 299 EXPECT_REF(propstorecache, 1); 300 301 IPropertyStore_Release(propstore1); 302 IPropertyStore_Release(propstore); 303 IPropertyStoreCache_Release(propstorecache); 304 } 305 306 static void test_propertystore(void) 307 { 308 IPropertyStore *propstore; 309 HRESULT hr; 310 PROPVARIANT propvar, ret_propvar; 311 PROPERTYKEY propkey; 312 DWORD count = 0; 313 314 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); 315 ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); 316 ok(propstore != NULL, "got %p.\n", propstore); 317 318 hr = IPropertyStore_GetCount(propstore, &count); 319 ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); 320 ok(!count, "got wrong property count: %d, expected 0.\n", count); 321 322 PropVariantInit(&propvar); 323 propvar.vt = VT_I4; 324 U(propvar).lVal = 123; 325 propkey.fmtid = DUMMY_GUID1; 326 propkey.pid = PID_FIRST_USABLE; 327 hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); 328 ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08x.\n", hr); 329 hr = IPropertyStore_Commit(propstore); 330 ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08x.\n", hr); 331 hr = IPropertyStore_GetCount(propstore, &count); 332 ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); 333 ok(count == 1, "got wrong property count: %d, expected 1.\n", count); 334 PropVariantInit(&ret_propvar); 335 ret_propvar.vt = VT_I4; 336 hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); 337 ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08x.\n", hr); 338 ok(ret_propvar.vt == VT_I4, "got wrong property type: %x.\n", ret_propvar.vt); 339 ok(U(ret_propvar).lVal == 123, "got wrong value: %d, expected 123.\n", U(ret_propvar).lVal); 340 PropVariantClear(&propvar); 341 PropVariantClear(&ret_propvar); 342 343 PropVariantInit(&propvar); 344 propkey.fmtid = DUMMY_GUID1; 345 propkey.pid = PID_FIRST_USABLE; 346 hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); 347 ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08x.\n", hr); 348 hr = IPropertyStore_Commit(propstore); 349 ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08x.\n", hr); 350 hr = IPropertyStore_GetCount(propstore, &count); 351 ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); 352 ok(count == 1, "got wrong property count: %d, expected 1.\n", count); 353 PropVariantInit(&ret_propvar); 354 hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); 355 ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08x.\n", hr); 356 ok(ret_propvar.vt == VT_EMPTY, "got wrong property type: %x.\n", ret_propvar.vt); 357 ok(!U(ret_propvar).lVal, "got wrong value: %d, expected 0.\n", U(ret_propvar).lVal); 358 PropVariantClear(&propvar); 359 PropVariantClear(&ret_propvar); 360 361 IPropertyStore_Release(propstore); 362 } 363 364 START_TEST(propstore) 365 { 366 CoInitialize(NULL); 367 368 test_inmemorystore(); 369 test_persistserialized(); 370 test_PSCreateMemoryPropertyStore(); 371 test_propertystore(); 372 373 CoUninitialize(); 374 } 375