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-22.00.tar.gz 7zip-22.00.tar.bz2 7zip-22.00.zip |
22.0022.00
Diffstat (limited to '')
-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 | } |