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.

861 lines
20 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. #include "precomp.h"
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include <wbemcli.h>
  12. #include "cimval.h"
  13. BOOL SecondsToInterval( long double ldbSeconds, LPWSTR wszText, size_t cchSize )
  14. {
  15. int nDay, nHour, nMinute, nSecond, nMicro;
  16. nDay = int(ldbSeconds / 86400);
  17. ldbSeconds -= nDay * 86400;
  18. nHour = int(ldbSeconds / 3600);
  19. ldbSeconds -= nHour * 3600;
  20. nMinute = int(ldbSeconds / 60);
  21. ldbSeconds -= nMinute * 60;
  22. nSecond = int(ldbSeconds);
  23. ldbSeconds -= nSecond;
  24. nMicro = int(ldbSeconds * 1000000);
  25. if(FAILED(StringCchPrintfW( wszText, cchSize, L"%08.8d%02.2d%02.2d%02.2d.%06.6d:000",
  26. nDay, nHour, nMinute, nSecond, nMicro )))
  27. return FALSE;
  28. return TRUE;
  29. }
  30. // this should be a WBEM common thing ...
  31. BOOL FileTimeToDateTime( FILETIME* pft, LPWSTR wszText, size_t cchSize )
  32. {
  33. SYSTEMTIME st;
  34. __int64 llnss = *(__int64*)pft;
  35. if ( !FileTimeToSystemTime( pft, &st ) )
  36. {
  37. return FALSE;
  38. }
  39. //
  40. // have to account for microseconds as well (probably a much better way
  41. // to do this.)
  42. //
  43. st.wMilliseconds = 0;
  44. FILETIME ft;
  45. if ( !SystemTimeToFileTime( &st, &ft ) )
  46. {
  47. return FALSE;
  48. }
  49. __int64 llnss2 = *(__int64*)&ft;
  50. int nMicro = int((llnss - llnss2)/10);
  51. if (FAILED(StringCchPrintfW( wszText, cchSize,
  52. L"%04.4d%02.2d%02.2d%02.2d%02.2d%02.2d.%06.6d+000",
  53. st.wYear, st.wMonth, st.wDay, st.wHour,
  54. st.wMinute, st.wSecond, nMicro )))
  55. return FALSE;
  56. return TRUE;
  57. }
  58. BOOL SecondsToDateTime( long double ldbSeconds, LPWSTR wszText, size_t cchSize )
  59. {
  60. FILETIME* pft;
  61. __int64 llnss = __int64(ldbSeconds * 10000000);
  62. pft = (FILETIME*)&llnss;
  63. return FileTimeToDateTime( pft, wszText, cchSize );
  64. }
  65. BOOL IntervalToSeconds( LPCWSTR wszText, long double& rldbSeconds )
  66. {
  67. int nDay, nHour, nMinute, nSecond, nMicro;
  68. int nRes = swscanf( wszText, L"%8d%2d%2d%2d.%6d",
  69. &nDay, &nHour, &nMinute, &nSecond, &nMicro );
  70. if ( nRes != 5 )
  71. {
  72. return FALSE;
  73. }
  74. rldbSeconds = nSecond + 60*nMinute + 3600*nHour + 86400*nDay;
  75. rldbSeconds += nMicro / 1000000.0;
  76. return TRUE;
  77. }
  78. BOOL DateTimeToSeconds( LPCWSTR wszText, long double& rldbSeconds )
  79. {
  80. WORD nYear, nMonth, nDay, nHour, nMinute, nSecond, nMicro, nOffset;
  81. WCHAR wchSep;
  82. int nRes = swscanf( wszText, L"%4d%2d%2d%2d%2d%2d.%6d%c%3d",
  83. &nYear, &nMonth, &nDay, &nHour, &nMinute,
  84. &nSecond, &nMicro, &wchSep, &nOffset );
  85. if(nRes != 9)
  86. {
  87. return FALSE;
  88. }
  89. int nSign;
  90. if( wchSep == L'+' )
  91. {
  92. nSign = -1;
  93. }
  94. else if ( wchSep == L'-' )
  95. {
  96. nSign = 1;
  97. }
  98. else
  99. {
  100. return FALSE;
  101. }
  102. // Convert it to SYSTEMTIME
  103. // ========================
  104. SYSTEMTIME st;
  105. st.wYear = nYear;
  106. st.wMonth = nMonth;
  107. st.wDay = nDay;
  108. st.wHour = nHour;
  109. st.wMinute = nMinute;
  110. st.wSecond = nSecond;
  111. st.wMilliseconds = 0;
  112. //
  113. // convert SYSTEMTIME to FILETIME
  114. //
  115. FILETIME ft;
  116. if ( !SystemTimeToFileTime( &st, &ft ) )
  117. {
  118. return FALSE;
  119. }
  120. rldbSeconds = (long double)*(__int64*)&ft;
  121. rldbSeconds += nMicro*10;
  122. rldbSeconds /= 10000000;
  123. // Now adjust for the offset
  124. // =========================
  125. rldbSeconds += nSign * nOffset * 60;
  126. return TRUE;
  127. }
  128. BOOL DMTFToSeconds( LPCWSTR wszText, long double& rldbSeconds )
  129. {
  130. if( wcslen(wszText) != 25 )
  131. {
  132. return FALSE;
  133. }
  134. if ( wszText[21] != ':' )
  135. {
  136. return DateTimeToSeconds( wszText, rldbSeconds );
  137. }
  138. return IntervalToSeconds( wszText, rldbSeconds );
  139. }
  140. CCimValue::CCimValue( ) : m_eType( e_Int ), m_iVal( 0 ) { }
  141. HRESULT CCimValue::GetValue( VARIANT& rvValue, ULONG lCimType )
  142. {
  143. VariantInit( &rvValue );
  144. WCHAR achBuff[255];
  145. BOOL bRes;
  146. switch( lCimType )
  147. {
  148. case CIM_SINT8:
  149. case CIM_SINT16:
  150. case CIM_SINT32:
  151. case CIM_BOOLEAN:
  152. CoerceToInt();
  153. V_VT(&rvValue) = VT_I4;
  154. V_I4(&rvValue) = m_iVal;
  155. break;
  156. case CIM_UINT8:
  157. case CIM_UINT16:
  158. case CIM_UINT32:
  159. CoerceToUnsignedInt();
  160. V_VT(&rvValue) = VT_I4;
  161. V_I4(&rvValue) = m_uiVal;
  162. break;
  163. case CIM_SINT64:
  164. case CIM_STRING:
  165. CoerceToLong();
  166. _i64tow( m_lVal, achBuff, 10 );
  167. V_VT(&rvValue) = VT_BSTR;
  168. V_BSTR(&rvValue) = SysAllocString(achBuff);
  169. break;
  170. case CIM_REAL32:
  171. CoerceToFloat();
  172. V_VT(&rvValue) = VT_R4;
  173. V_R4(&rvValue) = m_fVal;
  174. break;
  175. case CIM_REAL64:
  176. CoerceToDouble();
  177. V_VT(&rvValue) = VT_R8;
  178. V_R8(&rvValue) = m_dbVal;
  179. break;
  180. case CIM_UINT64:
  181. CoerceToUnsignedLong();
  182. _ui64tow( m_ulVal, achBuff, 10 );
  183. V_VT(&rvValue) = VT_BSTR;
  184. V_BSTR(&rvValue) = SysAllocString(achBuff);
  185. break;
  186. case CIM_INTERVAL:
  187. CoerceToLongDouble();
  188. bRes = SecondsToInterval( m_ldbVal, achBuff, 255 );
  189. if ( !bRes ) { return WBEM_E_TYPE_MISMATCH; }
  190. V_VT(&rvValue) = VT_BSTR;
  191. V_BSTR(&rvValue) = SysAllocString(achBuff);
  192. break;
  193. case CIM_DATETIME:
  194. CoerceToLongDouble();
  195. bRes = SecondsToDateTime( m_ldbVal, achBuff, 255 );
  196. if ( !bRes ) { return WBEM_E_TYPE_MISMATCH; }
  197. V_VT(&rvValue) = VT_BSTR;
  198. V_BSTR(&rvValue) = SysAllocString(achBuff);
  199. break;
  200. default:
  201. return WBEM_E_TYPE_MISMATCH;
  202. };
  203. return WBEM_S_NO_ERROR;
  204. }
  205. HRESULT CCimValue::SetValue( VARIANT& rvValue, ULONG lCimType )
  206. {
  207. HRESULT hr;
  208. VARIANT vValue;
  209. VariantInit( &vValue );
  210. if ( lCimType == CIM_EMPTY )
  211. {
  212. //
  213. // must be a numeric value.
  214. //
  215. switch( V_VT(&rvValue) )
  216. {
  217. case VT_R4:
  218. m_eType = e_Float;
  219. m_fVal = V_R4(&rvValue);
  220. break;
  221. case VT_R8:
  222. m_eType = e_Double;
  223. m_dbVal = V_R8(&rvValue);
  224. break;
  225. case VT_BSTR:
  226. m_lVal = (__int64)_wtoi64( V_BSTR(&rvValue) );
  227. break;
  228. default:
  229. hr = VariantChangeType( &vValue, &rvValue, 0, VT_I4 );
  230. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  231. m_eType = e_Int;
  232. m_iVal = V_I4(&vValue);
  233. };
  234. return WBEM_S_NO_ERROR;
  235. }
  236. switch( lCimType )
  237. {
  238. case CIM_SINT8:
  239. case CIM_SINT16:
  240. case CIM_SINT32:
  241. case CIM_BOOLEAN:
  242. hr = VariantChangeType( &vValue, &rvValue, 0, VT_I4 );
  243. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  244. m_eType = e_Int;
  245. m_iVal = V_I4(&vValue);
  246. break;
  247. case CIM_UINT8:
  248. case CIM_UINT16:
  249. case CIM_UINT32:
  250. hr = VariantChangeType( &vValue, &rvValue, 0, VT_UI4 );
  251. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  252. m_eType = e_UnsignedInt;
  253. m_uiVal = V_UI4(&vValue);
  254. break;
  255. case CIM_SINT64:
  256. case CIM_STRING:
  257. if ( V_VT(&rvValue) == VT_BSTR )
  258. {
  259. m_lVal = _wtoi64( V_BSTR(&rvValue) );
  260. }
  261. else
  262. {
  263. return WBEM_E_TYPE_MISMATCH;
  264. }
  265. m_eType = e_Long;
  266. break;
  267. case CIM_UINT64:
  268. if ( V_VT(&rvValue) == VT_BSTR )
  269. {
  270. m_ulVal = (unsigned __int64)_wtoi64( V_BSTR(&rvValue) );
  271. }
  272. else
  273. {
  274. return WBEM_E_TYPE_MISMATCH;
  275. }
  276. m_eType = e_UnsignedLong;
  277. break;
  278. case CIM_REAL32:
  279. hr = VariantChangeType( &vValue, &rvValue, 0, VT_R4 );
  280. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  281. m_eType = CCimValue::e_Float;
  282. m_fVal = V_R4(&vValue);
  283. break;
  284. case CIM_REAL64:
  285. hr = VariantChangeType( &vValue, &rvValue, 0, VT_R8 );
  286. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  287. m_eType = CCimValue::e_Double;
  288. m_dbVal = V_R8(&vValue);
  289. break;
  290. case CIM_DATETIME:
  291. case CIM_INTERVAL:
  292. if ( V_VT(&rvValue) == VT_BSTR )
  293. {
  294. BOOL bRes = DMTFToSeconds( V_BSTR(&rvValue), m_ldbVal );
  295. if ( !bRes )
  296. {
  297. return WBEM_E_TYPE_MISMATCH;
  298. }
  299. }
  300. else
  301. {
  302. return WBEM_E_TYPE_MISMATCH;
  303. }
  304. m_eType = e_LongDouble;
  305. break;
  306. default:
  307. return WBEM_E_TYPE_MISMATCH;
  308. };
  309. return WBEM_S_NO_ERROR;
  310. }
  311. void CCimValue::CoerceToLongDouble()
  312. {
  313. switch( m_eType )
  314. {
  315. case e_Int:
  316. m_ldbVal = (long double)m_iVal;
  317. break;
  318. case e_UnsignedInt:
  319. m_ldbVal = (long double)m_uiVal;
  320. break;
  321. case e_Float:
  322. m_ldbVal = (long double)m_fVal;
  323. break;
  324. case e_Double:
  325. m_ldbVal = (long double)m_dbVal;
  326. break;
  327. case e_Long:
  328. m_ldbVal = (long double)m_lVal;
  329. break;
  330. case e_UnsignedLong:
  331. m_ldbVal = (long double)(__int64)m_ulVal;
  332. break;
  333. };
  334. m_eType = e_LongDouble;
  335. }
  336. void CCimValue::CoerceToDouble()
  337. {
  338. switch( m_eType )
  339. {
  340. case e_Int:
  341. m_dbVal = (double)m_iVal;
  342. break;
  343. case e_UnsignedInt:
  344. m_dbVal = (double)m_uiVal;
  345. break;
  346. case e_Float:
  347. m_dbVal = (double)m_fVal;
  348. break;
  349. case e_LongDouble:
  350. m_dbVal = (double)m_ldbVal;
  351. break;
  352. case e_Long:
  353. m_dbVal = (double)m_lVal;
  354. break;
  355. case e_UnsignedLong:
  356. m_dbVal = (double)(__int64)m_ulVal;
  357. break;
  358. };
  359. m_eType = e_Double;
  360. }
  361. void CCimValue::CoerceToFloat()
  362. {
  363. switch( m_eType )
  364. {
  365. case e_Int:
  366. m_fVal = (float)m_iVal;
  367. break;
  368. case e_UnsignedInt:
  369. m_fVal = (float)m_uiVal;
  370. break;
  371. case e_LongDouble:
  372. m_fVal = (float)m_ldbVal;
  373. break;
  374. case e_Double:
  375. m_fVal = (float)m_dbVal;
  376. break;
  377. case e_Long:
  378. m_fVal = (float)m_lVal;
  379. break;
  380. case e_UnsignedLong:
  381. m_fVal = (float)(__int64)m_ulVal;
  382. break;
  383. };
  384. m_eType = e_Float;
  385. }
  386. void CCimValue::CoerceToUnsignedLong()
  387. {
  388. switch( m_eType )
  389. {
  390. case e_Int:
  391. m_ulVal = (unsigned __int64)m_iVal;
  392. break;
  393. case e_UnsignedInt:
  394. m_ulVal = (unsigned __int64)m_uiVal;
  395. break;
  396. case e_Float:
  397. m_ulVal = (unsigned __int64)m_fVal;
  398. break;
  399. case e_Double:
  400. m_ulVal = (unsigned __int64)m_dbVal;
  401. break;
  402. case e_Long:
  403. m_ulVal = (unsigned __int64)m_lVal;
  404. break;
  405. case e_LongDouble:
  406. m_ulVal = (unsigned __int64)m_ldbVal;
  407. break;
  408. };
  409. m_eType = e_UnsignedLong;
  410. }
  411. void CCimValue::CoerceToLong()
  412. {
  413. switch( m_eType )
  414. {
  415. case e_Int:
  416. m_lVal = (__int64)m_iVal;
  417. break;
  418. case e_UnsignedInt:
  419. m_lVal = (__int64)m_uiVal;
  420. break;
  421. case e_Float:
  422. m_lVal = (__int64)m_fVal;
  423. break;
  424. case e_Double:
  425. m_lVal = (__int64)m_dbVal;
  426. break;
  427. case e_UnsignedLong:
  428. m_lVal = (__int64)m_ulVal;
  429. break;
  430. case e_LongDouble:
  431. m_lVal = (__int64)m_ldbVal;
  432. break;
  433. };
  434. m_eType = e_Long;
  435. }
  436. void CCimValue::CoerceToUnsignedInt()
  437. {
  438. switch( m_eType )
  439. {
  440. case e_Int:
  441. m_uiVal = (unsigned __int32)m_iVal;
  442. break;
  443. case e_Float:
  444. m_uiVal = (unsigned __int32)m_fVal;
  445. break;
  446. case e_Double:
  447. m_uiVal = (unsigned __int32)m_dbVal;
  448. break;
  449. case e_Long:
  450. m_uiVal = (unsigned __int32)m_lVal;
  451. break;
  452. case e_UnsignedLong:
  453. m_uiVal = (unsigned __int32)m_ulVal;
  454. break;
  455. case e_LongDouble:
  456. m_uiVal = (unsigned __int32)m_ldbVal;
  457. break;
  458. };
  459. m_eType = e_UnsignedInt;
  460. }
  461. void CCimValue::CoerceToInt()
  462. {
  463. switch( m_eType )
  464. {
  465. case e_Long:
  466. m_iVal = (__int32)m_lVal;
  467. break;
  468. case e_UnsignedInt:
  469. m_iVal = (__int32)m_uiVal;
  470. break;
  471. case e_Float:
  472. m_iVal = (__int32)m_fVal;
  473. break;
  474. case e_Double:
  475. m_iVal = (__int32)m_dbVal;
  476. break;
  477. case e_UnsignedLong:
  478. m_iVal = (__int32)m_ulVal;
  479. break;
  480. case e_LongDouble:
  481. m_iVal = (__int32)m_ldbVal;
  482. break;
  483. };
  484. m_eType = e_Int;
  485. }
  486. void HandleConversion( CCimValue& rValA, CCimValue& rValB )
  487. {
  488. if ( rValA.m_eType == rValB.m_eType )
  489. {
  490. return;
  491. }
  492. if ( rValA.m_eType == CCimValue::e_LongDouble )
  493. {
  494. rValB.CoerceToLongDouble();
  495. return;
  496. }
  497. if ( rValB.m_eType == CCimValue::e_LongDouble )
  498. {
  499. rValA.CoerceToLongDouble();
  500. return;
  501. }
  502. if ( rValA.m_eType == CCimValue::e_Double )
  503. {
  504. rValB.CoerceToDouble();
  505. return;
  506. }
  507. if ( rValB.m_eType == CCimValue::e_Double )
  508. {
  509. rValA.CoerceToDouble();
  510. return;
  511. }
  512. if ( rValA.m_eType == CCimValue::e_Float )
  513. {
  514. rValB.CoerceToFloat();
  515. return;
  516. }
  517. if ( rValB.m_eType == CCimValue::e_Float )
  518. {
  519. rValA.CoerceToFloat();
  520. return;
  521. }
  522. if ( rValA.m_eType == CCimValue::e_UnsignedLong )
  523. {
  524. rValB.CoerceToUnsignedLong();
  525. return;
  526. }
  527. if ( rValB.m_eType == CCimValue::e_UnsignedLong )
  528. {
  529. rValA.CoerceToUnsignedLong();
  530. return;
  531. }
  532. if ( rValA.m_eType == CCimValue::e_Long &&
  533. rValB.m_eType == CCimValue::e_UnsignedInt ||
  534. rValB.m_eType == CCimValue::e_Long &&
  535. rValA.m_eType == CCimValue::e_UnsignedInt )
  536. {
  537. rValA.CoerceToUnsignedLong();
  538. rValB.CoerceToUnsignedLong();
  539. return;
  540. }
  541. if ( rValA.m_eType == CCimValue::e_Long )
  542. {
  543. rValB.CoerceToLong();
  544. return;
  545. }
  546. if ( rValB.m_eType == CCimValue::e_Long )
  547. {
  548. rValA.CoerceToLong();
  549. return;
  550. }
  551. if ( rValA.m_eType == CCimValue::e_UnsignedInt )
  552. {
  553. rValB.CoerceToUnsignedInt();
  554. return;
  555. }
  556. if ( rValB.m_eType == CCimValue::e_UnsignedInt )
  557. {
  558. rValA.CoerceToUnsignedInt();
  559. return;
  560. }
  561. // this means both must be e_Int, but our check in the beginning
  562. // should have handled this...
  563. assert( 0 );
  564. }
  565. CCimValue operator+ ( CCimValue ValA, CCimValue ValB )
  566. {
  567. HandleConversion( ValA, ValB );
  568. assert( ValA.m_eType == ValB.m_eType );
  569. switch( ValA.m_eType )
  570. {
  571. case CCimValue::e_Int:
  572. ValA.m_iVal += ValB.m_iVal;
  573. break;
  574. case CCimValue::e_UnsignedInt:
  575. ValA.m_uiVal += ValB.m_uiVal;
  576. break;
  577. case CCimValue::e_Float:
  578. ValA.m_fVal += ValB.m_fVal;
  579. break;
  580. case CCimValue::e_Double:
  581. ValA.m_dbVal += ValB.m_dbVal;
  582. break;
  583. case CCimValue::e_LongDouble:
  584. ValA.m_ldbVal += ValB.m_ldbVal;
  585. break;
  586. case CCimValue::e_Long:
  587. ValA.m_lVal += ValB.m_lVal;
  588. break;
  589. case CCimValue::e_UnsignedLong:
  590. ValA.m_ulVal += ValB.m_ulVal;
  591. break;
  592. default:
  593. assert(0);
  594. };
  595. return ValA;
  596. }
  597. CCimValue operator- ( CCimValue ValA, CCimValue ValB )
  598. {
  599. HandleConversion( ValA, ValB );
  600. assert( ValA.m_eType == ValB.m_eType );
  601. switch( ValA.m_eType )
  602. {
  603. case CCimValue::e_Int:
  604. ValA.m_iVal -= ValB.m_iVal;
  605. break;
  606. case CCimValue::e_UnsignedInt:
  607. ValA.m_uiVal -= ValB.m_uiVal;
  608. break;
  609. case CCimValue::e_Float:
  610. ValA.m_fVal -= ValB.m_fVal;
  611. break;
  612. case CCimValue::e_Double:
  613. ValA.m_dbVal -= ValB.m_dbVal;
  614. break;
  615. case CCimValue::e_Long:
  616. ValA.m_lVal -= ValB.m_lVal;
  617. break;
  618. case CCimValue::e_UnsignedLong:
  619. ValA.m_ulVal -= ValB.m_ulVal;
  620. break;
  621. case CCimValue::e_LongDouble:
  622. ValA.m_ldbVal -= ValB.m_ldbVal;
  623. break;
  624. default:
  625. assert(0);
  626. };
  627. return ValA;
  628. }
  629. CCimValue operator* ( CCimValue ValA, CCimValue ValB )
  630. {
  631. HandleConversion( ValA, ValB );
  632. assert( ValA.m_eType == ValB.m_eType );
  633. switch( ValA.m_eType )
  634. {
  635. case CCimValue::e_Int:
  636. ValA.m_iVal *= ValB.m_iVal;
  637. break;
  638. case CCimValue::e_UnsignedInt:
  639. ValA.m_uiVal *= ValB.m_uiVal;
  640. break;
  641. case CCimValue::e_Float:
  642. ValA.m_fVal *= ValB.m_fVal;
  643. break;
  644. case CCimValue::e_Double:
  645. ValA.m_dbVal *= ValB.m_dbVal;
  646. break;
  647. case CCimValue::e_Long:
  648. ValA.m_lVal *= ValB.m_lVal;
  649. break;
  650. case CCimValue::e_UnsignedLong:
  651. ValA.m_ulVal *= ValB.m_ulVal;
  652. break;
  653. case CCimValue::e_LongDouble:
  654. ValA.m_ldbVal *= ValB.m_ldbVal;
  655. break;
  656. default:
  657. assert(0);
  658. };
  659. return ValA;
  660. }
  661. CCimValue operator/ ( CCimValue ValA, CCimValue ValB )
  662. {
  663. HandleConversion( ValA, ValB );
  664. assert( ValA.m_eType == ValB.m_eType );
  665. //
  666. // will raise a structured exception if div by 0.
  667. // caller is expected to handle this..
  668. //
  669. switch( ValA.m_eType )
  670. {
  671. case CCimValue::e_Int:
  672. if ( ValB.m_iVal == 0 ) throw CX_DivideByZeroException();
  673. ValA.m_iVal /= ValB.m_iVal;
  674. break;
  675. case CCimValue::e_UnsignedInt:
  676. if ( ValB.m_uiVal == 0 ) throw CX_DivideByZeroException();
  677. ValA.m_uiVal /= ValB.m_uiVal;
  678. break;
  679. case CCimValue::e_Float:
  680. if ( ValB.m_fVal == 0 ) throw CX_DivideByZeroException();
  681. ValA.m_fVal /= ValB.m_fVal;
  682. break;
  683. case CCimValue::e_Double:
  684. if ( ValB.m_dbVal == 0 ) throw CX_DivideByZeroException();
  685. ValA.m_dbVal /= ValB.m_dbVal;
  686. break;
  687. case CCimValue::e_Long:
  688. if ( ValB.m_lVal == 0 ) throw CX_DivideByZeroException();
  689. ValA.m_lVal /= ValB.m_lVal;
  690. break;
  691. case CCimValue::e_UnsignedLong:
  692. if ( ValB.m_ulVal == 0 ) throw CX_DivideByZeroException();
  693. ValA.m_ulVal /= ValB.m_ulVal;
  694. break;
  695. case CCimValue::e_LongDouble:
  696. if ( ValB.m_ldbVal == 0 ) throw CX_DivideByZeroException();
  697. ValA.m_ldbVal /= ValB.m_ldbVal;
  698. break;
  699. default:
  700. assert(0);
  701. };
  702. return ValA;
  703. }
  704. CCimValue operator% ( CCimValue ValA, CCimValue ValB )
  705. {
  706. HandleConversion( ValA, ValB );
  707. assert( ValA.m_eType == ValB.m_eType );
  708. //
  709. // will raise a structured exception if div by 0.
  710. // caller is expected to handle this..
  711. //
  712. switch( ValA.m_eType )
  713. {
  714. case CCimValue::e_Int:
  715. if ( ValB.m_iVal == 0 ) throw CX_DivideByZeroException();
  716. ValA.m_iVal %= ValB.m_iVal;
  717. break;
  718. case CCimValue::e_UnsignedInt:
  719. if ( ValB.m_uiVal == 0 ) throw CX_DivideByZeroException();
  720. ValA.m_uiVal %= ValB.m_uiVal;
  721. break;
  722. case CCimValue::e_Float:
  723. case CCimValue::e_Double:
  724. case CCimValue::e_LongDouble:
  725. throw CX_InvalidFloatingPointOperationException();
  726. case CCimValue::e_Long:
  727. if ( ValB.m_lVal == 0 ) throw CX_DivideByZeroException();
  728. ValA.m_lVal %= ValB.m_lVal;
  729. break;
  730. case CCimValue::e_UnsignedLong:
  731. if ( ValB.m_ulVal == 0 ) throw CX_DivideByZeroException();
  732. ValA.m_ulVal %= ValB.m_ulVal;
  733. break;
  734. default:
  735. assert(0);
  736. };
  737. return ValA;
  738. }