aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows/PropVariant.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CPP/Windows/PropVariant.cpp132
1 files changed, 81 insertions, 51 deletions
diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp
index 6e43c7b..2b17950 100644
--- a/CPP/Windows/PropVariant.cpp
+++ b/CPP/Windows/PropVariant.cpp
@@ -193,7 +193,7 @@ BSTR CPropVariant::AllocBstr(unsigned numChars)
193} 193}
194 194
195#define SET_PROP_id_dest(id, dest) \ 195#define SET_PROP_id_dest(id, dest) \
196 if (vt != id) { InternalClear(); vt = id; } dest = value; 196 if (vt != id) { InternalClear(); vt = id; } dest = value; wReserved1 = 0;
197 197
198void CPropVariant::Set_Int32(Int32 value) throw() 198void CPropVariant::Set_Int32(Int32 value) throw()
199{ 199{
@@ -217,67 +217,83 @@ SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
217// SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart) 217// SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
218SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime) 218SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
219 219
220#define CASE_SIMPLE_VT_VALUES \
221 case VT_EMPTY: \
222 case VT_BOOL: \
223 case VT_FILETIME: \
224 case VT_UI8: \
225 case VT_UI4: \
226 case VT_UI2: \
227 case VT_UI1: \
228 case VT_I8: \
229 case VT_I4: \
230 case VT_I2: \
231 case VT_I1: \
232 case VT_UINT: \
233 case VT_INT: \
234 case VT_NULL: \
235 case VT_ERROR: \
236 case VT_R4: \
237 case VT_R8: \
238 case VT_CY: \
239 case VT_DATE: \
240
241
242/*
243 ::VariantClear() and ::VariantCopy() don't work, if (vt == VT_FILETIME)
244 So we handle VT_FILETIME and another simple types directly
245 we call system functions for VT_BSTR and for unknown typed
246*/
247
248CPropVariant::~CPropVariant()
249{
250 switch ((unsigned)vt)
251 {
252 CASE_SIMPLE_VT_VALUES
253 // vt = VT_EMPTY; // it's optional
254 return;
255 }
256 ::VariantClear((tagVARIANT *)this);
257}
258
220HRESULT PropVariant_Clear(PROPVARIANT *prop) throw() 259HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
221{ 260{
222 switch (prop->vt) 261 switch ((unsigned)prop->vt)
223 { 262 {
224 case VT_EMPTY: 263 CASE_SIMPLE_VT_VALUES
225 case VT_UI1:
226 case VT_I1:
227 case VT_I2:
228 case VT_UI2:
229 case VT_BOOL:
230 case VT_I4:
231 case VT_UI4:
232 case VT_R4:
233 case VT_INT:
234 case VT_UINT:
235 case VT_ERROR:
236 case VT_FILETIME:
237 case VT_UI8:
238 case VT_R8:
239 case VT_CY:
240 case VT_DATE:
241 prop->vt = VT_EMPTY; 264 prop->vt = VT_EMPTY;
242 prop->wReserved1 = 0; 265 break;
243 prop->wReserved2 = 0; 266 default:
244 prop->wReserved3 = 0; 267 {
245 prop->uhVal.QuadPart = 0; 268 const HRESULT res = ::VariantClear((VARIANTARG *)prop);
246 return S_OK; 269 if (res != S_OK || prop->vt != VT_EMPTY)
270 return res;
271 break;
272 }
247 } 273 }
248 return ::VariantClear((VARIANTARG *)prop); 274 prop->wReserved1 = 0;
249 // return ::PropVariantClear(prop); 275 prop->wReserved2 = 0;
250 // PropVariantClear can clear VT_BLOB. 276 prop->wReserved3 = 0;
277 prop->uhVal.QuadPart = 0;
278 return S_OK;
251} 279}
252 280
253HRESULT CPropVariant::Clear() throw() 281HRESULT CPropVariant::Clear() throw()
254{ 282{
255 if (vt == VT_EMPTY) 283 if (vt == VT_EMPTY)
284 {
285 wReserved1 = 0;
256 return S_OK; 286 return S_OK;
287 }
257 return PropVariant_Clear(this); 288 return PropVariant_Clear(this);
258} 289}
259 290
260HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw() 291HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
261{ 292{
262 ::VariantClear((tagVARIANT *)this); 293 Clear();
263 switch (pSrc->vt) 294 switch ((unsigned)pSrc->vt)
264 { 295 {
265 case VT_UI1: 296 CASE_SIMPLE_VT_VALUES
266 case VT_I1:
267 case VT_I2:
268 case VT_UI2:
269 case VT_BOOL:
270 case VT_I4:
271 case VT_UI4:
272 case VT_R4:
273 case VT_INT:
274 case VT_UINT:
275 case VT_ERROR:
276 case VT_FILETIME:
277 case VT_UI8:
278 case VT_R8:
279 case VT_CY:
280 case VT_DATE:
281 memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); 297 memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
282 return S_OK; 298 return S_OK;
283 } 299 }
@@ -287,12 +303,13 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
287 303
288HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw() 304HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw()
289{ 305{
290 HRESULT hr = Clear(); 306 const HRESULT hr = Clear();
291 if (FAILED(hr)) 307 if (FAILED(hr))
292 return hr; 308 return hr;
293 // memcpy((PROPVARIANT *)this, pSrc, sizeof(PROPVARIANT)); 309 // memcpy((PROPVARIANT *)this, pSrc, sizeof(PROPVARIANT));
294 *(PROPVARIANT *)this = *pSrc; 310 *(PROPVARIANT *)this = *pSrc;
295 pSrc->vt = VT_EMPTY; 311 pSrc->vt = VT_EMPTY;
312 pSrc->wReserved1 = 0;
296 return S_OK; 313 return S_OK;
297} 314}
298 315
@@ -300,21 +317,25 @@ HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw()
300{ 317{
301 if (pDest->vt != VT_EMPTY) 318 if (pDest->vt != VT_EMPTY)
302 { 319 {
303 HRESULT hr = PropVariant_Clear(pDest); 320 const HRESULT hr = PropVariant_Clear(pDest);
304 if (FAILED(hr)) 321 if (FAILED(hr))
305 return hr; 322 return hr;
306 } 323 }
307 // memcpy(pDest, this, sizeof(PROPVARIANT)); 324 // memcpy(pDest, this, sizeof(PROPVARIANT));
308 *pDest = *(PROPVARIANT *)this; 325 *pDest = *(PROPVARIANT *)this;
309 vt = VT_EMPTY; 326 vt = VT_EMPTY;
327 wReserved1 = 0;
310 return S_OK; 328 return S_OK;
311} 329}
312 330
313HRESULT CPropVariant::InternalClear() throw() 331HRESULT CPropVariant::InternalClear() throw()
314{ 332{
315 if (vt == VT_EMPTY) 333 if (vt == VT_EMPTY)
334 {
335 wReserved1 = 0;
316 return S_OK; 336 return S_OK;
317 HRESULT hr = Clear(); 337 }
338 const HRESULT hr = Clear();
318 if (FAILED(hr)) 339 if (FAILED(hr))
319 { 340 {
320 vt = VT_ERROR; 341 vt = VT_ERROR;
@@ -325,7 +346,7 @@ HRESULT CPropVariant::InternalClear() throw()
325 346
326void CPropVariant::InternalCopy(const PROPVARIANT *pSrc) 347void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
327{ 348{
328 HRESULT hr = Copy(pSrc); 349 const HRESULT hr = Copy(pSrc);
329 if (FAILED(hr)) 350 if (FAILED(hr))
330 { 351 {
331 if (hr == E_OUTOFMEMORY) 352 if (hr == E_OUTOFMEMORY)
@@ -335,11 +356,12 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
335 } 356 }
336} 357}
337 358
359
338int CPropVariant::Compare(const CPropVariant &a) throw() 360int CPropVariant::Compare(const CPropVariant &a) throw()
339{ 361{
340 if (vt != a.vt) 362 if (vt != a.vt)
341 return MyCompare(vt, a.vt); 363 return MyCompare(vt, a.vt);
342 switch (vt) 364 switch ((unsigned)vt)
343 { 365 {
344 case VT_EMPTY: return 0; 366 case VT_EMPTY: return 0;
345 // case VT_I1: return MyCompare(cVal, a.cVal); 367 // case VT_I1: return MyCompare(cVal, a.cVal);
@@ -352,7 +374,15 @@ int CPropVariant::Compare(const CPropVariant &a) throw()
352 case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart); 374 case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
353 case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart); 375 case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
354 case VT_BOOL: return -MyCompare(boolVal, a.boolVal); 376 case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
355 case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime); 377 case VT_FILETIME:
378 {
379 const int res = CompareFileTime(&filetime, &a.filetime);
380 if (res != 0)
381 return res;
382 const unsigned v1 = Get_Ns100();
383 const unsigned v2 = a.Get_Ns100();
384 return MyCompare(v1, v2);
385 }
356 case VT_BSTR: return 0; // Not implemented 386 case VT_BSTR: return 0; // Not implemented
357 default: return 0; 387 default: return 0;
358 } 388 }