diff options
| author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2022-06-20 00:00:00 +0000 |
|---|---|---|
| committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-12-17 13:35:20 +0500 |
| commit | a3e1d227377188734b82f023f96f8e25dc40f3e6 (patch) | |
| tree | 23cad8d47eb23d26ea727b4f7f4a65124f724065 /CPP/Windows/PropVariant.cpp | |
| parent | f19f813537c7aea1c20749c914e756b54a9c3cf5 (diff) | |
| download | 7zip-a3e1d227377188734b82f023f96f8e25dc40f3e6.tar.gz 7zip-a3e1d227377188734b82f023f96f8e25dc40f3e6.tar.bz2 7zip-a3e1d227377188734b82f023f96f8e25dc40f3e6.zip | |
22.0022.00
Diffstat (limited to 'CPP/Windows/PropVariant.cpp')
| -rw-r--r-- | CPP/Windows/PropVariant.cpp | 132 |
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 | ||
| 198 | void CPropVariant::Set_Int32(Int32 value) throw() | 198 | void 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) |
| 218 | SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime) | 218 | SET_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 | |||
| 248 | CPropVariant::~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 | |||
| 220 | HRESULT PropVariant_Clear(PROPVARIANT *prop) throw() | 259 | HRESULT 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 | ||
| 253 | HRESULT CPropVariant::Clear() throw() | 281 | HRESULT 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 | ||
| 260 | HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw() | 291 | HRESULT 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 | ||
| 288 | HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw() | 304 | HRESULT 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 | ||
| 313 | HRESULT CPropVariant::InternalClear() throw() | 331 | HRESULT 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 | ||
| 326 | void CPropVariant::InternalCopy(const PROPVARIANT *pSrc) | 347 | void 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 | |||
| 338 | int CPropVariant::Compare(const CPropVariant &a) throw() | 360 | int 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 | } |
