Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1114 lines
26 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
  3. File: Utilities.cpp
  4. Content: Implementation of CUtilities.
  5. History: 11-15-99 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #include "stdafx.h"
  8. #include "CAPICOM.h"
  9. #include "Utilities.h"
  10. #include "Common.h"
  11. #include "Base64.h"
  12. #include "Convert.h"
  13. ////////////////////////////////////////////////////////////////////////////////
  14. //
  15. // CUtilities
  16. //
  17. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  18. Function : CUtilities::GetRandom
  19. Synopsis : Return a secure random number.
  20. Parameter: long Length - Number of bytes to generate.
  21. CAPICOM_ENCODING_TYPE EncodingType - Encoding type.
  22. BSTR * pVal - Pointer to BSTR to receive the random value.
  23. Remark :
  24. ------------------------------------------------------------------------------*/
  25. STDMETHODIMP CUtilities::GetRandom (long Length,
  26. CAPICOM_ENCODING_TYPE EncodingType,
  27. BSTR * pVal)
  28. {
  29. HRESULT hr = S_OK;
  30. DWORD dwFlags = 0;
  31. DATA_BLOB RandomData = {0, NULL};
  32. DebugTrace("Entering CUtilities::GetRandom().\n");
  33. try
  34. {
  35. //
  36. // Lock access to this object.
  37. //
  38. m_Lock.Lock();
  39. //
  40. // Check parameter.
  41. //
  42. if (NULL == pVal)
  43. {
  44. hr = E_INVALIDARG;
  45. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  46. goto ErrorExit;
  47. }
  48. //
  49. // Do we have a cached provider?
  50. //
  51. if (!m_hCryptProv)
  52. {
  53. if (IsWin2KAndAbove())
  54. {
  55. dwFlags = CRYPT_VERIFYCONTEXT;
  56. }
  57. //
  58. // Get a provider.
  59. //
  60. if (FAILED(hr = ::AcquireContext((LPSTR) NULL,
  61. (LPSTR) NULL,
  62. PROV_RSA_FULL,
  63. dwFlags,
  64. TRUE,
  65. &m_hCryptProv)) &&
  66. FAILED(hr = ::AcquireContext(MS_ENHANCED_PROV_A,
  67. (LPSTR) NULL,
  68. PROV_RSA_FULL,
  69. dwFlags,
  70. TRUE,
  71. &m_hCryptProv)) &&
  72. FAILED(hr = ::AcquireContext(MS_STRONG_PROV_A,
  73. (LPSTR) NULL,
  74. PROV_RSA_FULL,
  75. dwFlags,
  76. TRUE,
  77. &m_hCryptProv)) &&
  78. FAILED(hr = ::AcquireContext(MS_DEF_PROV_A,
  79. (LPSTR) NULL,
  80. PROV_RSA_FULL,
  81. dwFlags,
  82. TRUE,
  83. &m_hCryptProv)))
  84. {
  85. DebugTrace("Error [%#x]: AcquireContext() failed.\n", hr);
  86. goto ErrorExit;
  87. }
  88. }
  89. //
  90. // Sanity check.
  91. //
  92. ATLASSERT(m_hCryptProv);
  93. //
  94. // Allocate memory.
  95. //
  96. RandomData.cbData = (DWORD) Length;
  97. if (!(RandomData.pbData = (PBYTE) ::CoTaskMemAlloc(RandomData.cbData)))
  98. {
  99. hr = E_OUTOFMEMORY;
  100. DebugTrace("Error [%#x]: CoTaskMemAlloc(RandomData.cbData) failed.\n", hr);
  101. goto ErrorExit;
  102. }
  103. //
  104. // Now generate the random value.
  105. //
  106. if (!::CryptGenRandom(m_hCryptProv, RandomData.cbData, RandomData.pbData))
  107. {
  108. hr = HRESULT_FROM_WIN32(::GetLastError());
  109. DebugTrace("Error [%#x]: CryptGenRandom() failed.\n", hr);
  110. goto ErrorExit;
  111. }
  112. //
  113. // Export the random data.
  114. //
  115. if (FAILED(hr = ::ExportData(RandomData, EncodingType, pVal)))
  116. {
  117. DebugTrace("Error [%#x]: ExportData() failed.\n", hr);
  118. goto ErrorExit;
  119. }
  120. }
  121. catch(...)
  122. {
  123. hr = E_POINTER;
  124. DebugTrace("Exception: invalid parameter.\n");
  125. goto ErrorExit;
  126. }
  127. UnlockExit:
  128. //
  129. // Free resources.
  130. //
  131. if (RandomData.pbData)
  132. {
  133. ::CoTaskMemFree(RandomData.pbData);
  134. }
  135. //
  136. // Unlock access to this object.
  137. //
  138. m_Lock.Unlock();
  139. DebugTrace("Leaving CUtilities::GetRandom().\n");
  140. return hr;
  141. ErrorExit:
  142. //
  143. // Sanity check.
  144. //
  145. ATLASSERT(FAILED(hr));
  146. ReportError(hr);
  147. goto UnlockExit;
  148. }
  149. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  150. Function : Base64Encode
  151. Synopsis : Base64 encode the blob.
  152. Parameter: BSTR SrcString - Source string to be base64 encoded.
  153. BSTR * pVal - Pointer to BSTR to received base64 encoded string.
  154. Remark :
  155. ------------------------------------------------------------------------------*/
  156. STDMETHODIMP CUtilities::Base64Encode (BSTR SrcString, BSTR * pVal)
  157. {
  158. HRESULT hr = S_OK;
  159. DATA_BLOB DataBlob = {0, NULL};
  160. DebugTrace("Entering CUtilities::Base64Encode().\n");
  161. try
  162. {
  163. //
  164. // Lock access to this object.
  165. //
  166. m_Lock.Lock();
  167. //
  168. // Check parameter.
  169. //
  170. if ((NULL == (DataBlob.pbData = (LPBYTE) SrcString)) ||
  171. (0 == (DataBlob.cbData = ::SysStringByteLen(SrcString))))
  172. {
  173. hr = E_INVALIDARG;
  174. DebugTrace("Error [%#x]: Parameter SrcString is NULL or empty.\n", hr);
  175. goto ErrorExit;
  176. }
  177. if (NULL == pVal)
  178. {
  179. hr = E_INVALIDARG;
  180. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  181. goto ErrorExit;
  182. }
  183. //
  184. // Now base64 encode.
  185. //
  186. if (FAILED(hr = ::Base64Encode(DataBlob, pVal)))
  187. {
  188. DebugTrace("Error [%#x]: Base64Encode() failed.\n", hr);
  189. goto ErrorExit;
  190. }
  191. }
  192. catch(...)
  193. {
  194. hr = E_POINTER;
  195. DebugTrace("Exception: invalid parameter.\n");
  196. goto ErrorExit;
  197. }
  198. UnlockExit:
  199. //
  200. // Unlock access to this object.
  201. //
  202. m_Lock.Unlock();
  203. DebugTrace("Leaving CUtilities::Base64Encode().\n");
  204. return hr;
  205. ErrorExit:
  206. //
  207. // Sanity check.
  208. //
  209. ATLASSERT(FAILED(hr));
  210. ReportError(hr);
  211. goto UnlockExit;
  212. }
  213. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  214. Function : Base64Decode
  215. Synopsis : Base64 decode the blob.
  216. Parameter: BSTR EncodedString - Base64 encoded string.
  217. BSTR * pVal - Pointer to BSTR to received base64 decoded string.
  218. Remark :
  219. ------------------------------------------------------------------------------*/
  220. STDMETHODIMP CUtilities::Base64Decode (BSTR EncodedString, BSTR * pVal)
  221. {
  222. HRESULT hr = S_OK;
  223. DATA_BLOB DataBlob = {0, NULL};
  224. DebugTrace("Entering CUtilities::Base64Decode().\n");
  225. try
  226. {
  227. //
  228. // Lock access to this object.
  229. //
  230. m_Lock.Lock();
  231. //
  232. // Make sure parameters are valid.
  233. //
  234. if (0 == ::SysStringByteLen(EncodedString))
  235. {
  236. hr = E_INVALIDARG;
  237. DebugTrace("Error [%#x]: Parameter EncodedString is NULL or empty.\n", hr);
  238. goto ErrorExit;
  239. }
  240. if (NULL == pVal)
  241. {
  242. hr = E_INVALIDARG;
  243. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  244. goto ErrorExit;
  245. }
  246. //
  247. // Now base64 decode.
  248. //
  249. if (FAILED(hr = ::Base64Decode(EncodedString, &DataBlob)))
  250. {
  251. DebugTrace("Error [%#x]: Base64Decode() failed.\n", hr);
  252. goto ErrorExit;
  253. }
  254. //
  255. // Convert blob to BSTR.
  256. //
  257. if (FAILED(hr = ::BlobToBstr(&DataBlob, pVal)))
  258. {
  259. DebugTrace("Error [%#x]: BlobToBstr() failed.\n", hr);
  260. goto ErrorExit;
  261. }
  262. }
  263. catch(...)
  264. {
  265. hr = E_POINTER;
  266. DebugTrace("Exception: invalid parameter.\n");
  267. goto ErrorExit;
  268. }
  269. UnlockExit:
  270. //
  271. // Free resources.
  272. //
  273. if (DataBlob.pbData)
  274. {
  275. ::CoTaskMemFree((LPVOID) DataBlob.pbData);
  276. }
  277. //
  278. // Unlock access to this object.
  279. //
  280. m_Lock.Unlock();
  281. DebugTrace("Leaving CUtilities::Base64Decode().\n");
  282. return hr;
  283. ErrorExit:
  284. //
  285. // Sanity check.
  286. //
  287. ATLASSERT(FAILED(hr));
  288. ReportError(hr);
  289. goto UnlockExit;
  290. }
  291. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  292. Function : BinaryToHex
  293. Synopsis : Convert binary packed string to hex string.
  294. Parameter: BSTR BinaryString - Binary string to be converted.
  295. VARIANT * pVal - Pointer to BSTR to receive the converted string.
  296. Remark :
  297. ------------------------------------------------------------------------------*/
  298. STDMETHODIMP CUtilities::BinaryToHex (BSTR BinaryString, BSTR * pVal)
  299. {
  300. HRESULT hr = S_OK;
  301. DWORD cbData = 0;
  302. DebugTrace("Entering CUtilities::BinaryToHex().\n");
  303. try
  304. {
  305. //
  306. // Lock access to this object.
  307. //
  308. m_Lock.Lock();
  309. //
  310. // Make sure parameters are valid.
  311. //
  312. if (0 == (cbData = ::SysStringByteLen(BinaryString)))
  313. {
  314. hr = E_INVALIDARG;
  315. DebugTrace("Error [%#x]: Parameter BinaryString is NULL or empty.\n", hr);
  316. goto ErrorExit;
  317. }
  318. if (NULL == pVal)
  319. {
  320. hr = E_INVALIDARG;
  321. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  322. goto ErrorExit;
  323. }
  324. //
  325. // Convert to hex.
  326. //
  327. if (FAILED(hr = ::BinaryToHexString((LPBYTE) BinaryString,
  328. cbData,
  329. pVal)))
  330. {
  331. DebugTrace("Error [%#x]: BinaryToHexString() failed.\n", hr);
  332. goto ErrorExit;
  333. }
  334. }
  335. catch(...)
  336. {
  337. hr = E_POINTER;
  338. DebugTrace("Exception: invalid parameter.\n");
  339. goto ErrorExit;
  340. }
  341. UnlockExit:
  342. //
  343. // Unlock access to this object.
  344. //
  345. m_Lock.Unlock();
  346. DebugTrace("Leaving CUtilities::BinaryToHex().\n");
  347. return hr;
  348. ErrorExit:
  349. //
  350. // Sanity check.
  351. //
  352. ATLASSERT(FAILED(hr));
  353. ReportError(hr);
  354. goto UnlockExit;
  355. }
  356. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  357. Function : HexToBinary
  358. Synopsis : Convert hex string to binary packed string.
  359. Parameter: BSTR HexString - Hex string to be converted.
  360. VARIANT * pVal - Pointer to BSTR to receive the converted string.
  361. Remark :
  362. ------------------------------------------------------------------------------*/
  363. STDMETHODIMP CUtilities::HexToBinary (BSTR HexString, BSTR * pVal)
  364. {
  365. HRESULT hr = S_OK;
  366. DebugTrace("Entering CUtilities::HexToBinary().\n");
  367. try
  368. {
  369. //
  370. // Lock access to this object.
  371. //
  372. m_Lock.Lock();
  373. //
  374. // Make sure parameters are valid.
  375. //
  376. if (0 == ::SysStringByteLen(HexString))
  377. {
  378. hr = E_INVALIDARG;
  379. DebugTrace("Error [%#x]: Parameter HexString is NULL or empty.\n", hr);
  380. goto ErrorExit;
  381. }
  382. if (NULL == pVal)
  383. {
  384. hr = E_INVALIDARG;
  385. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  386. goto ErrorExit;
  387. }
  388. //
  389. // Convert to binary.
  390. //
  391. if (FAILED(hr = ::HexToBinaryString(HexString, pVal)))
  392. {
  393. DebugTrace("Error [%#x]: HexToBinaryString() failed.\n", hr);
  394. goto ErrorExit;
  395. }
  396. }
  397. catch(...)
  398. {
  399. hr = E_POINTER;
  400. DebugTrace("Exception: invalid parameter.\n");
  401. goto ErrorExit;
  402. }
  403. UnlockExit:
  404. //
  405. // Unlock access to this object.
  406. //
  407. m_Lock.Unlock();
  408. DebugTrace("Leaving CUtilities::HexToBinary().\n");
  409. return hr;
  410. ErrorExit:
  411. //
  412. // Sanity check.
  413. //
  414. ATLASSERT(FAILED(hr));
  415. ReportError(hr);
  416. goto UnlockExit;
  417. }
  418. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  419. Function : BinaryStringToByteArray
  420. Synopsis : Convert binary packed string to safearray of bytes.
  421. Parameter: BSTR BinaryString - Binary string to be converted.
  422. VARIANT * pVal - Pointer to VARIANT to receive the converted array.
  423. Remark :
  424. ------------------------------------------------------------------------------*/
  425. STDMETHODIMP CUtilities::BinaryStringToByteArray (BSTR BinaryString,
  426. VARIANT * pVal)
  427. {
  428. HRESULT hr = S_OK;
  429. DWORD dwLength = 0;
  430. LPBYTE pbByte = NULL;
  431. LPBYTE pbElement = NULL;
  432. SAFEARRAY * psa = NULL;
  433. SAFEARRAYBOUND bound[1] = {0, 0};
  434. DebugTrace("Entering CUtilities::BinaryStringToByteArray().\n");
  435. try
  436. {
  437. //
  438. // Lock access to this object.
  439. //
  440. m_Lock.Lock();
  441. //
  442. // Make sure parameters are valid.
  443. //
  444. if (0 == (dwLength = ::SysStringByteLen(BinaryString)))
  445. {
  446. hr = E_INVALIDARG;
  447. DebugTrace("Error [%#x]: Parameter BinaryString is NULL or empty.\n", hr);
  448. goto ErrorExit;
  449. }
  450. if (NULL == pVal)
  451. {
  452. hr = E_INVALIDARG;
  453. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  454. goto ErrorExit;
  455. }
  456. //
  457. // Initialize.
  458. //
  459. ::VariantInit(pVal);
  460. pbByte = (LPBYTE) BinaryString;
  461. //
  462. // Create the array.
  463. //
  464. bound[0].cElements = dwLength;
  465. if (!(psa = ::SafeArrayCreate(VT_UI1, 1, bound)))
  466. {
  467. hr = E_OUTOFMEMORY;
  468. DebugTrace("Error [%#x]: SafeArrayCreate() failed.\n", hr);
  469. goto ErrorExit;
  470. }
  471. //
  472. // Now convert each byte in source binary BSTR to variant of byte.
  473. //
  474. #ifdef _DEBUG
  475. VARTYPE vt = VT_EMPTY;
  476. if (S_OK == ::SafeArrayGetVartype(psa, &vt))
  477. {
  478. DebugTrace("Info: safearray vartype = %d.\n", vt);
  479. }
  480. #endif
  481. //
  482. // Point to array elements.
  483. //
  484. if (FAILED(hr = ::SafeArrayAccessData(psa, (void HUGEP **) &pbElement)))
  485. {
  486. DebugTrace("Error [%#x]: SafeArrayAccessData() failed.\n", hr);
  487. goto ErrorExit;
  488. }
  489. //
  490. // Fill the array.
  491. //
  492. while (dwLength--)
  493. {
  494. *pbElement++ = *pbByte++;
  495. }
  496. //
  497. // Unlock array.
  498. //
  499. if (FAILED(hr = ::SafeArrayUnaccessData(psa)))
  500. {
  501. DebugTrace("Error [%#x]: SafeArrayUnaccessData() failed.\n", hr);
  502. goto ErrorExit;
  503. }
  504. //
  505. // Return array to caller.
  506. //
  507. pVal->vt = VT_ARRAY | VT_UI1;
  508. pVal->parray = psa;
  509. }
  510. catch(...)
  511. {
  512. hr = E_POINTER;
  513. DebugTrace("Exception: invalid parameter.\n");
  514. goto ErrorExit;
  515. }
  516. UnlockExit:
  517. //
  518. // Unlock access to this object.
  519. //
  520. m_Lock.Unlock();
  521. DebugTrace("Leaving CUtilities::BinaryStringToByteArray().\n");
  522. return hr;
  523. ErrorExit:
  524. //
  525. // Sanity check.
  526. //
  527. ATLASSERT(FAILED(hr));
  528. //
  529. // Free resources.
  530. //
  531. if (psa)
  532. {
  533. ::SafeArrayDestroy(psa);
  534. }
  535. ReportError(hr);
  536. goto UnlockExit;
  537. }
  538. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  539. Function : ByteArrayToBinaryString
  540. Synopsis : Convert safearray of bytes to binary packed string.
  541. Parameter: VARIANT varByteArray - VARIANT byte array.
  542. BSTR * pVal - Pointer to BSTR to receive the converted values.
  543. Remark :
  544. ------------------------------------------------------------------------------*/
  545. STDMETHODIMP CUtilities::ByteArrayToBinaryString (VARIANT varByteArray,
  546. BSTR * pVal)
  547. {
  548. HRESULT hr = S_OK;
  549. VARIANT * pvarVal = NULL;
  550. SAFEARRAY * psa = NULL;
  551. LPBYTE pbElement = NULL;
  552. LPBYTE pbByte = NULL;
  553. long lLoBound = 0;
  554. long lUpBound = 0;
  555. BSTR bstrBinary = NULL;
  556. DebugTrace("Entering CUtilities::ByteArrayToBinaryString().\n");
  557. try
  558. {
  559. //
  560. // Lock access to this object.
  561. //
  562. m_Lock.Lock();
  563. //
  564. // Skip over BYREF.
  565. //
  566. for (pvarVal = &varByteArray;
  567. pvarVal && ((VT_VARIANT | VT_BYREF) == V_VT(pvarVal));
  568. pvarVal = V_VARIANTREF(pvarVal));
  569. //
  570. // Make sure parameters are valid.
  571. //
  572. if (!pvarVal)
  573. {
  574. hr = E_INVALIDARG;
  575. DebugTrace("Error [%#x]: Parameter varByteArray is NULL.\n", hr);
  576. goto ErrorExit;
  577. }
  578. if ((VT_ARRAY | VT_UI1) != V_VT(pvarVal))
  579. {
  580. hr = E_INVALIDARG;
  581. DebugTrace("Error [%#x]: Parameter varByteArray is not a VT_UI1 array, V_VT(pvarVal) = %d\n",
  582. hr, V_VT(pvarVal));
  583. goto ErrorExit;
  584. }
  585. if (NULL == pVal)
  586. {
  587. hr = E_INVALIDARG;
  588. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  589. goto ErrorExit;
  590. }
  591. //
  592. // Point to the array.
  593. //
  594. psa = V_ARRAY(pvarVal);
  595. //
  596. // Check dimension.
  597. //
  598. if (1 != ::SafeArrayGetDim(psa))
  599. {
  600. hr = E_INVALIDARG;
  601. DebugTrace("Error [%#x]: varByteArray is not 1 dimension, SafeArrayGetDim(psa) = %d.\n",
  602. hr, ::SafeArrayGetDim(psa));
  603. goto ErrorExit;
  604. }
  605. //
  606. // Get array bound.
  607. //
  608. if (FAILED(hr = ::SafeArrayGetLBound(psa, 1, &lLoBound)))
  609. {
  610. DebugTrace("Error [%#x]: SafeArrayGetLBound() failed.\n", hr);
  611. goto ErrorExit;
  612. }
  613. if (FAILED(hr = ::SafeArrayGetUBound(psa, 1, &lUpBound)))
  614. {
  615. DebugTrace("Error [%#x]: SafeArrayGetUBound() failed.\n", hr);
  616. goto ErrorExit;
  617. }
  618. //
  619. // Point to array elements.
  620. //
  621. if (FAILED(hr = ::SafeArrayAccessData(psa, (void HUGEP **) &pbElement)))
  622. {
  623. DebugTrace("Error [%#x]: SafeArrayAccessData() failed.\n", hr);
  624. goto ErrorExit;
  625. }
  626. //
  627. // Allocate memory for the BSTR.
  628. //
  629. if (!(bstrBinary = ::SysAllocStringByteLen(NULL, lUpBound - lLoBound + 1)))
  630. {
  631. hr = E_OUTOFMEMORY;
  632. DebugTrace("Error [%#x]: SysAllocStringByteLen() failed.\n", hr);
  633. goto ErrorExit;
  634. }
  635. //
  636. // Fill the BSTR.
  637. //
  638. for (pbByte = (LPBYTE) bstrBinary; lLoBound <= lUpBound; lLoBound++)
  639. {
  640. *pbByte++ = *pbElement++;
  641. }
  642. //
  643. // Unlock array.
  644. //
  645. if (FAILED(hr = ::SafeArrayUnaccessData(psa)))
  646. {
  647. DebugTrace("Error [%#x]: SafeArrayUnaccessData() failed.\n", hr);
  648. goto ErrorExit;
  649. }
  650. //
  651. // Return converted string to caller.
  652. //
  653. *pVal = bstrBinary;
  654. }
  655. catch(...)
  656. {
  657. hr = E_POINTER;
  658. DebugTrace("Exception: invalid parameter.\n");
  659. goto ErrorExit;
  660. }
  661. UnlockExit:
  662. //
  663. // Unlock access to this object.
  664. //
  665. m_Lock.Unlock();
  666. DebugTrace("Leaving CUtilities::ByteArrayToBinaryString().\n");
  667. return hr;
  668. ErrorExit:
  669. //
  670. // Sanity check.
  671. //
  672. ATLASSERT(FAILED(hr));
  673. //
  674. // Free resources.
  675. //
  676. if (bstrBinary)
  677. {
  678. ::SysFreeString(bstrBinary);
  679. }
  680. ReportError(hr);
  681. goto UnlockExit;
  682. }
  683. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  684. Function : LocalTimeToUTCTime
  685. Synopsis : Convert local time to UTC time.
  686. Parameter: DATE LocalTime - Local time to be converted.
  687. DATE * pVal - Pointer to DATE to receive the converted time.
  688. Remark :
  689. ------------------------------------------------------------------------------*/
  690. STDMETHODIMP CUtilities::LocalTimeToUTCTime (DATE LocalTime, DATE * pVal)
  691. {
  692. HRESULT hr = S_OK;
  693. SYSTEMTIME stLocal;
  694. SYSTEMTIME stUTC;
  695. FILETIME ftLocal;
  696. FILETIME ftUTC;
  697. DebugTrace("Entering CUtilities::LocalTimeToUTCTime().\n");
  698. try
  699. {
  700. //
  701. // Lock access to this object.
  702. //
  703. m_Lock.Lock();
  704. //
  705. // Convert to SYSTEMTIME format.
  706. //
  707. if (!::VariantTimeToSystemTime(LocalTime, &stLocal))
  708. {
  709. hr = E_INVALIDARG;
  710. DebugTrace("Error [%#x]: VariantTimeToSystemTime() failed.\n", hr);
  711. goto ErrorExit;
  712. }
  713. //
  714. // Convert to FILETIME format.
  715. //
  716. if (!::SystemTimeToFileTime(&stLocal, &ftLocal))
  717. {
  718. hr = HRESULT_FROM_WIN32(::GetLastError());
  719. DebugTrace("Error [%#x]: SystemTimeToFileTime() failed.\n", hr);
  720. goto ErrorExit;
  721. }
  722. //
  723. // Convert to UTC FILETIME.
  724. //
  725. if (!::LocalFileTimeToFileTime(&ftLocal, &ftUTC))
  726. {
  727. hr = HRESULT_FROM_WIN32(::GetLastError());
  728. DebugTrace("Error [%#x]: LocalFileTimeToFileTime() failed.\n", hr);
  729. goto ErrorExit;
  730. }
  731. //
  732. // Convert to UTC SYSTEMTIME.
  733. //
  734. if (!::FileTimeToSystemTime(&ftUTC, &stUTC))
  735. {
  736. hr = HRESULT_FROM_WIN32(::GetLastError());
  737. DebugTrace("Error [%#x]: FileTimeToSystemTime() failed.\n", hr);
  738. goto ErrorExit;
  739. }
  740. //
  741. // Finally convert it back to DATE format.
  742. //
  743. if (!::SystemTimeToVariantTime(&stUTC, pVal))
  744. {
  745. hr = E_INVALIDARG;
  746. DebugTrace("Error [%#x]: SystemTimeToVariantTime() failed.\n", hr);
  747. goto ErrorExit;
  748. }
  749. }
  750. catch(...)
  751. {
  752. hr = E_POINTER;
  753. DebugTrace("Exception: invalid parameter.\n");
  754. goto ErrorExit;
  755. }
  756. UnlockExit:
  757. //
  758. // Unlock access to this object.
  759. //
  760. m_Lock.Unlock();
  761. DebugTrace("Leaving CUtilities::LocalTimeToUTCTime().\n");
  762. return hr;
  763. ErrorExit:
  764. //
  765. // Sanity check.
  766. //
  767. ATLASSERT(FAILED(hr));
  768. ReportError(hr);
  769. goto UnlockExit;
  770. }
  771. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  772. Function : UTCTimeToLocalTime
  773. Synopsis : Convert UTC time to local time.
  774. Parameter: DATE UTCTime - UTC time to be converted.
  775. DATE * pVal - Pointer to DATE to receive the converted time.
  776. Remark :
  777. ------------------------------------------------------------------------------*/
  778. STDMETHODIMP CUtilities::UTCTimeToLocalTime (DATE UTCTime, DATE * pVal)
  779. {
  780. HRESULT hr = S_OK;
  781. SYSTEMTIME stLocal;
  782. SYSTEMTIME stUTC;
  783. FILETIME ftLocal;
  784. FILETIME ftUTC;
  785. DebugTrace("Entering CUtilities::UTCTimeToLocalTime().\n");
  786. try
  787. {
  788. //
  789. // Lock access to this object.
  790. //
  791. m_Lock.Lock();
  792. //
  793. // Convert to SYSTEMTIME format.
  794. //
  795. if (!::VariantTimeToSystemTime(UTCTime, &stUTC))
  796. {
  797. hr = E_INVALIDARG;
  798. DebugTrace("Error [%#x]: VariantTimeToSystemTime() failed.\n", hr);
  799. goto ErrorExit;
  800. }
  801. //
  802. // Convert to FILETIME format.
  803. //
  804. if (!::SystemTimeToFileTime(&stUTC, &ftUTC))
  805. {
  806. hr = HRESULT_FROM_WIN32(::GetLastError());
  807. DebugTrace("Error [%#x]: SystemTimeToFileTime() failed.\n", hr);
  808. goto ErrorExit;
  809. }
  810. //
  811. // Convert to local FILETIME.
  812. //
  813. if (!::FileTimeToLocalFileTime(&ftUTC, &ftLocal))
  814. {
  815. hr = HRESULT_FROM_WIN32(::GetLastError());
  816. DebugTrace("Error [%#x]: FileTimeToLocalFileTime() failed.\n", hr);
  817. goto ErrorExit;
  818. }
  819. //
  820. // Convert to local SYSTEMTIME.
  821. //
  822. if (!::FileTimeToSystemTime(&ftLocal, &stLocal))
  823. {
  824. hr = HRESULT_FROM_WIN32(::GetLastError());
  825. DebugTrace("Error [%#x]: FileTimeToSystemTime() failed.\n", hr);
  826. goto ErrorExit;
  827. }
  828. //
  829. // Finally convert it back to DATE format.
  830. //
  831. if (!::SystemTimeToVariantTime(&stLocal, pVal))
  832. {
  833. hr = E_INVALIDARG;
  834. DebugTrace("Error [%#x]: SystemTimeToVariantTime() failed.\n", hr);
  835. goto ErrorExit;
  836. }
  837. }
  838. catch(...)
  839. {
  840. hr = E_POINTER;
  841. DebugTrace("Exception: invalid parameter.\n");
  842. goto ErrorExit;
  843. }
  844. UnlockExit:
  845. //
  846. // Unlock access to this object.
  847. //
  848. m_Lock.Unlock();
  849. DebugTrace("Leaving CUtilities::UTCTimeToLocalTime().\n");
  850. return hr;
  851. ErrorExit:
  852. //
  853. // Sanity check.
  854. //
  855. ATLASSERT(FAILED(hr));
  856. ReportError(hr);
  857. goto UnlockExit;
  858. }