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.

897 lines
21 KiB

  1. /*++
  2. Copyright (C) 1999 Microsoft Corporation
  3. --*/
  4. #include <windows.h>
  5. #include <comdef.h>
  6. #include <stdio.h>
  7. #include <genlex.h>
  8. #include <qllex.h>
  9. #include <ql.h>
  10. #include "dnf.h"
  11. #include "datep.h"
  12. /******************************************************************/
  13. COrderedUniqueSet64::COrderedUniqueSet64(void)
  14. {
  15. m_BitField = SETEMPTY;
  16. }
  17. COrderedUniqueSet64 COrderedUniqueSet64::Set(ULONGLONG n)
  18. {
  19. m_BitField = n;
  20. return *this;
  21. }
  22. COrderedUniqueSet64 COrderedUniqueSet64::Add(ULONGLONG n)
  23. {
  24. ULONGLONG iBit = SETMIN;
  25. if((n <= 63))
  26. m_BitField |= iBit << n;
  27. return *this;
  28. }
  29. COrderedUniqueSet64 COrderedUniqueSet64::Remove(ULONGLONG n)
  30. {
  31. ULONGLONG iBit = SETMIN;
  32. if((n >= 1) && (n <= 64))
  33. m_BitField &= ~(iBit << n);
  34. return *this;
  35. }
  36. COrderedUniqueSet64 COrderedUniqueSet64::Union(COrderedUniqueSet64 n)
  37. {
  38. m_BitField |= n.m_BitField;
  39. return *this;
  40. }
  41. COrderedUniqueSet64 COrderedUniqueSet64::Intersection(COrderedUniqueSet64 n)
  42. {
  43. m_BitField &= n.m_BitField;
  44. return *this;
  45. }
  46. COrderedUniqueSet64 COrderedUniqueSet64::UpperBound(ULONGLONG n)
  47. {
  48. if((n <= 63))
  49. {
  50. n = 63 - n;
  51. m_BitField = (m_BitField << n) >> n;
  52. }
  53. return *this;
  54. }
  55. COrderedUniqueSet64 COrderedUniqueSet64::LowerBound(ULONGLONG n)
  56. {
  57. if((n <= 63))
  58. m_BitField = (m_BitField >> n) << n;
  59. return *this;
  60. }
  61. COrderedUniqueSet64 COrderedUniqueSet64::Rotate(int n)
  62. {
  63. while(n > 64) n -= 64;
  64. while(n < 0) n += 64;
  65. m_BitField = (m_BitField << n) | (m_BitField >> (64 - n));
  66. return *this;
  67. }
  68. BOOL COrderedUniqueSet64::Member(ULONGLONG n)
  69. {
  70. return ((n <= 63) ? m_BitField & (SETMIN << n) : 0);
  71. }
  72. unsigned COrderedUniqueSet64::Next(ULONGLONG n)
  73. {
  74. ULONGLONG nStart = n;
  75. ULONGLONG
  76. SetValue = SETMIN << n;
  77. if(0x0 == m_BitField)
  78. return -1;
  79. while(! (SetValue & m_BitField))
  80. {
  81. SetValue <<= 1;
  82. n++;
  83. if(SETEMPTY == SetValue)
  84. {
  85. SetValue = SETMIN;
  86. n = 0;
  87. }
  88. }
  89. return (unsigned)n;
  90. }
  91. unsigned COrderedUniqueSet64::Prev(ULONGLONG n)
  92. {
  93. ULONGLONG nStart = n;
  94. ULONGLONG SetValue = SETMIN << n;
  95. if(0x0 == m_BitField)
  96. return -1;
  97. while(! (SetValue & m_BitField))
  98. {
  99. SetValue >>= 1;
  100. n--;
  101. if(SETEMPTY == SetValue)
  102. {
  103. SetValue = SETMAX;
  104. n = 63;
  105. }
  106. }
  107. return (unsigned)n;
  108. }
  109. /******************************************************************/
  110. unsigned CPattern::GetNextValue(unsigned NextValue)
  111. {
  112. unsigned i;
  113. // **** perform quick sanity check
  114. if((m_FieldsUsed & LOWERBOUND) &&
  115. (m_FieldsUsed & UPPERBOUND) &&
  116. (m_UpperBound < m_LowerBound))
  117. return -1;
  118. if(m_FieldsUsed & EQUALTO)
  119. {
  120. if(NextValue > m_EqualTo)
  121. return -1;
  122. else
  123. NextValue = m_EqualTo;
  124. // **** perform sanity checks for equality
  125. if((m_FieldsUsed & LOWERBOUND) &&
  126. (m_EqualTo < m_LowerBound))
  127. return -1;
  128. if((m_FieldsUsed & UPPERBOUND) &&
  129. (m_EqualTo > m_UpperBound))
  130. return -1;
  131. if(m_FieldsUsed & NOTEQUALTO)
  132. {
  133. for(i = 0; i < m_CountNotEqualTo; i++)
  134. if(NextValue == m_NotEqualTo[i])
  135. return -1;
  136. }
  137. }
  138. else
  139. {
  140. if(m_FieldsUsed & LOWERBOUND)
  141. {
  142. if(NextValue < m_LowerBound)
  143. NextValue = m_LowerBound;
  144. }
  145. if(m_FieldsUsed & NOTEQUALTO)
  146. {
  147. int
  148. YearGotBumpedUp = 1;
  149. while(YearGotBumpedUp)
  150. {
  151. YearGotBumpedUp = 0;
  152. for(i = 0; i < m_CountNotEqualTo; i++)
  153. if(NextValue == m_NotEqualTo[i])
  154. {
  155. NextValue += 1;
  156. YearGotBumpedUp = 1;
  157. }
  158. }
  159. }
  160. if(m_FieldsUsed & UPPERBOUND)
  161. {
  162. if(NextValue > m_UpperBound)
  163. return -1;
  164. }
  165. }
  166. return NextValue;
  167. }
  168. /******************************************************************/
  169. // this belongs to CDatePattern but is stuck outside
  170. // of scope because of compiler bug (re: C2334)
  171. wchar_t* m_FieldName[] =
  172. {
  173. L"Year",
  174. L"Month",
  175. L"Day",
  176. L"DayOfWeek",
  177. L"WeekInMonth",
  178. L"Quarter",
  179. L"Hour",
  180. L"Minute",
  181. L"Second"
  182. };
  183. int CDatePattern::FieldIndx(const wchar_t *suName)
  184. {
  185. int
  186. iField;
  187. if(NULL == suName) return -1;
  188. for(iField = INDX_Year;
  189. (iField < INDX_MAX) && wbem_wcsicmp(m_FieldName[iField], suName);
  190. iField++);
  191. if(INDX_MAX == iField) iField = -1;
  192. return iField;
  193. }
  194. HRESULT CDatePattern::AugmentPattern(QL_LEVEL_1_TOKEN *pExp)
  195. {
  196. int
  197. i = pExp->PropertyName.GetNumElements(),
  198. iField = FieldIndx(pExp->PropertyName.GetStringAt(i - 1));
  199. unsigned
  200. j,
  201. testVal;
  202. VARIANT
  203. iValue;
  204. VariantInit(&iValue);
  205. if(-1 == iField)
  206. {
  207. if(wbem_wcsicmp(L"TargetInstance", pExp->PropertyName.GetStringAt(i - 1)))
  208. return WBEM_E_INVALID_PROPERTY;
  209. else
  210. return WBEM_S_NO_ERROR;
  211. }
  212. if(FAILED(VariantChangeType(&iValue, &(pExp->vConstValue), 0x0, VT_I4)))
  213. return WBEM_E_INVALID_QUERY;
  214. switch(pExp->nOperator)
  215. {
  216. case QL_LEVEL_1_TOKEN::OP_EQUAL :
  217. // **** first make sure that value can be in pattern
  218. testVal = m_Pattern[iField].GetNextValue(iValue.lVal);
  219. if(testVal == iValue.lVal)
  220. {
  221. m_Pattern[iField].m_FieldsUsed |= CPattern::EQUALTO;
  222. m_Pattern[iField].m_EqualTo = iValue.lVal;
  223. }
  224. break;
  225. case QL_LEVEL_1_TOKEN::OP_NOT_EQUAL :
  226. m_Pattern[iField].m_FieldsUsed |= CPattern::NOTEQUALTO;
  227. j = m_Pattern[iField].m_CountNotEqualTo;
  228. if(j < 64)
  229. {
  230. m_Pattern[iField].m_NotEqualTo[j] = iValue.lVal;
  231. m_Pattern[iField].m_CountNotEqualTo++;
  232. }
  233. else
  234. {
  235. return WBEM_E_FAILED;
  236. }
  237. break;
  238. case QL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN :
  239. if(! (m_Pattern[iField].m_FieldsUsed & CPattern::LOWERBOUND))
  240. {
  241. m_Pattern[iField].m_LowerBound = 0;
  242. m_Pattern[iField].m_FieldsUsed |= CPattern::LOWERBOUND;
  243. }
  244. if(m_Pattern[iField].m_LowerBound < iValue.lVal)
  245. m_Pattern[iField].m_LowerBound = iValue.lVal;
  246. break;
  247. case QL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN :
  248. if(! (m_Pattern[iField].m_FieldsUsed & CPattern::UPPERBOUND))
  249. {
  250. m_Pattern[iField].m_UpperBound = -1;
  251. m_Pattern[iField].m_FieldsUsed |= CPattern::UPPERBOUND;
  252. }
  253. m_Pattern[iField].m_FieldsUsed |= CPattern::UPPERBOUND;
  254. if(m_Pattern[iField].m_UpperBound > iValue.lVal)
  255. m_Pattern[iField].m_UpperBound = iValue.lVal;
  256. break;
  257. case QL_LEVEL_1_TOKEN::OP_LESSTHAN :
  258. if(! (m_Pattern[iField].m_FieldsUsed & CPattern::UPPERBOUND))
  259. {
  260. m_Pattern[iField].m_UpperBound = -1;
  261. m_Pattern[iField].m_FieldsUsed |= CPattern::UPPERBOUND;
  262. }
  263. m_Pattern[iField].m_FieldsUsed |= CPattern::UPPERBOUND;
  264. if(m_Pattern[iField].m_UpperBound >= iValue.lVal)
  265. m_Pattern[iField].m_UpperBound = iValue.lVal - 1;
  266. break;
  267. case QL_LEVEL_1_TOKEN::OP_GREATERTHAN :
  268. if(! (m_Pattern[iField].m_FieldsUsed & CPattern::LOWERBOUND))
  269. {
  270. m_Pattern[iField].m_LowerBound = 0;
  271. m_Pattern[iField].m_FieldsUsed |= CPattern::LOWERBOUND;
  272. }
  273. m_Pattern[iField].m_FieldsUsed |= CPattern::LOWERBOUND;
  274. if(m_Pattern[iField].m_LowerBound <= iValue.lVal)
  275. m_Pattern[iField].m_LowerBound = iValue.lVal + 1;
  276. break;
  277. case QL_LEVEL_1_TOKEN::OP_LIKE :
  278. default : ;
  279. return WBEM_E_INVALID_QUERY;
  280. }
  281. return WBEM_S_NO_ERROR;
  282. }
  283. HRESULT CDatePattern::BuildSetsFromPatterns(void)
  284. {
  285. // Second
  286. m_Set[INDX_Second].Set(SETFULL);
  287. MapPatternToSet(&m_Pattern[INDX_Second], &m_Set[INDX_Second]);
  288. m_Set[INDX_Second].UpperBound(59);
  289. // Minute
  290. m_Set[INDX_Minute].Set(SETFULL);
  291. MapPatternToSet(&m_Pattern[INDX_Minute], &m_Set[INDX_Minute]);
  292. m_Set[INDX_Minute].UpperBound(59);
  293. // Hour
  294. m_Set[INDX_Hour].Set(SETFULL);
  295. MapPatternToSet(&m_Pattern[INDX_Hour], &m_Set[INDX_Hour]);
  296. m_Set[INDX_Hour].UpperBound(23);
  297. // Quarter
  298. m_Set[INDX_Quarter].Set(SETFULL);
  299. MapPatternToSet(&m_Pattern[INDX_Quarter], &m_Set[INDX_Quarter]);
  300. m_Set[INDX_Quarter].LowerBound(1);
  301. m_Set[INDX_Quarter].UpperBound(4);
  302. // WeekInMonth
  303. m_Set[INDX_WeekInMonth].Set(SETFULL);
  304. MapPatternToSet(&m_Pattern[INDX_WeekInMonth], &m_Set[INDX_WeekInMonth]);
  305. m_Set[INDX_WeekInMonth].LowerBound(1);
  306. m_Set[INDX_WeekInMonth].UpperBound(7);
  307. // DayOfWeek
  308. m_Set[INDX_DayOfWeek].Set(SETFULL);
  309. MapPatternToSet(&m_Pattern[INDX_DayOfWeek], &m_Set[INDX_DayOfWeek]);
  310. m_Set[INDX_DayOfWeek].LowerBound(1);
  311. m_Set[INDX_DayOfWeek].UpperBound(7);
  312. // Day
  313. m_Set[INDX_Day].Set(SETEMPTY);
  314. // Month
  315. m_Set[INDX_Month].Set(SETFULL);
  316. MapPatternToSet(&m_Pattern[INDX_Month], &m_Set[INDX_Month]);
  317. m_Set[INDX_Month].LowerBound(1);
  318. m_Set[INDX_Month].UpperBound(12);
  319. // Year
  320. m_Set[INDX_Year].Set(SETEMPTY);
  321. return WBEM_S_NO_ERROR;
  322. }
  323. HRESULT CDatePattern::MapPatternToSet(CPattern *pPattern, COrderedUniqueSet64 *pSet)
  324. {
  325. unsigned i;
  326. if(pPattern->m_FieldsUsed & CPattern::EQUALTO)
  327. {
  328. pSet->Set(SETEMPTY);
  329. pSet->Add(pPattern->m_EqualTo);
  330. }
  331. else
  332. {
  333. if(pPattern->m_FieldsUsed & CPattern::NOTEQUALTO)
  334. {
  335. for(i = 0; i < pPattern->m_CountNotEqualTo; i++)
  336. pSet->Remove(pPattern->m_NotEqualTo[i]);
  337. }
  338. if(pPattern->m_FieldsUsed & CPattern::UPPERBOUND)
  339. {
  340. pSet->UpperBound(pPattern->m_UpperBound);
  341. }
  342. if(pPattern->m_FieldsUsed & CPattern::LOWERBOUND)
  343. {
  344. pSet->LowerBound(pPattern->m_LowerBound);
  345. }
  346. }
  347. return WBEM_S_NO_ERROR;
  348. }
  349. HRESULT CDatePattern::GetDaysInMonth(WORD iYear, WORD iMonth)
  350. {
  351. ULONGLONG
  352. Time1,
  353. Time2;
  354. int
  355. i, j, k,
  356. DayOfWeek,
  357. DaysInMonth;
  358. SYSTEMTIME
  359. SystemTime;
  360. FILETIME
  361. FileTime1,
  362. FileTime2;
  363. SystemTime.wYear = iYear;
  364. SystemTime.wMonth = iMonth;
  365. SystemTime.wDay = 1;
  366. SystemTime.wHour = 0;
  367. SystemTime.wMinute = 0;
  368. SystemTime.wSecond = 0;
  369. SystemTime.wMilliseconds = 0;
  370. if(m_Set[INDX_Month].Member(iMonth) &&
  371. m_Set[INDX_Quarter].Member(1 + (iMonth - 1) / 3))
  372. {
  373. // **** get DayOfWeek
  374. SystemTimeToFileTime(&SystemTime, &FileTime1);
  375. if(12 == SystemTime.wMonth)
  376. {
  377. SystemTime.wMonth = 1;
  378. SystemTime.wYear++;
  379. }
  380. else
  381. SystemTime.wMonth++;
  382. SystemTimeToFileTime(&SystemTime, &FileTime2);
  383. FileTimeToSystemTime(&FileTime1, &SystemTime);
  384. DayOfWeek = SystemTime.wDayOfWeek; // 0..6
  385. // **** get DaysInMonth
  386. Time1 = FileTime1.dwHighDateTime;
  387. Time1 = (Time1 << 32) + FileTime1.dwLowDateTime;
  388. Time2 = FileTime2.dwHighDateTime;
  389. Time2 = (Time2 << 32) + FileTime2.dwLowDateTime;
  390. DaysInMonth = (int) ((Time2 - Time1) / 864000000000);
  391. // **** get set for DaysInMonth
  392. m_Set[INDX_Day].Set(SETFULL);
  393. m_Set[INDX_Day].LowerBound(1);
  394. m_Set[INDX_Day].UpperBound(DaysInMonth);
  395. MapPatternToSet(&m_Pattern[INDX_Day], &m_Set[INDX_Day]);
  396. // build bitfield from DayOfWeek and WeekInMonth sets
  397. m_Set[INDX_MAX].Set(SETEMPTY);
  398. for(i = 0; i < DaysInMonth; i++)
  399. {
  400. j = (DayOfWeek + i) % 7 + 1; // Day of week
  401. k = (DayOfWeek + i) / 7 + 1; // Week in Month
  402. if(m_Set[INDX_DayOfWeek].Member(j) &&
  403. m_Set[INDX_WeekInMonth].Member(k))
  404. m_Set[INDX_MAX].Add(i + 1);
  405. }
  406. m_Set[INDX_Day].Intersection(m_Set[INDX_MAX]);
  407. }
  408. else
  409. m_Set[INDX_Day].Set(SETEMPTY);
  410. return WBEM_S_NO_ERROR;
  411. }
  412. ULONGLONG CDatePattern::GetNextTime(SYSTEMTIME *pSystemTime)
  413. {
  414. WORD
  415. wCurrValue,
  416. wCurrValue2,
  417. ThresholdYear = 12;
  418. FILETIME
  419. FileTime;
  420. ULONGLONG
  421. NewTime;
  422. /*
  423. Assumptions:
  424. 1. ASSUME EACH SET HAS AT LEAST ONE MEMBER EXCEPT 'Day'
  425. 2. set values start at 1 but hours, mins and secs start at 0
  426. */
  427. // **** second
  428. wCurrValue = m_CurrentTime.wSecond + 1;
  429. m_CurrentTime.wSecond = (USHORT) m_Set[INDX_Second].Next(wCurrValue);
  430. if(m_CurrentTime.wSecond < wCurrValue)
  431. {
  432. // **** minute
  433. wCurrValue = m_CurrentTime.wMinute + 1;
  434. m_CurrentTime.wMinute = (USHORT) m_Set[INDX_Minute].Next(wCurrValue);
  435. if(m_CurrentTime.wMinute < wCurrValue)
  436. {
  437. // **** hour
  438. wCurrValue = m_CurrentTime.wHour + 1;
  439. m_CurrentTime.wHour = (USHORT) m_Set[INDX_Hour].Next(wCurrValue);
  440. if(m_CurrentTime.wHour < wCurrValue)
  441. {
  442. // **** day
  443. wCurrValue = m_CurrentTime.wDay + 1;
  444. m_CurrentTime.wDay = (USHORT) m_Set[INDX_Day].Next(wCurrValue);
  445. while((SETEMPTY == m_Set[INDX_Day].m_BitField) ||
  446. (m_CurrentTime.wDay < wCurrValue))
  447. {
  448. // **** Month
  449. wCurrValue2 = m_CurrentTime.wMonth + 1;
  450. m_CurrentTime.wMonth = (USHORT) m_Set[INDX_Month].Next(wCurrValue2);
  451. if(m_CurrentTime.wMonth < wCurrValue2)
  452. {
  453. if(!ThresholdYear--)
  454. return -1;
  455. // **** year
  456. m_CurrentTime.wYear = (USHORT)
  457. m_Pattern[INDX_Year].GetNextValue(m_CurrentTime.wYear + 1);
  458. if((WORD)-1 == m_CurrentTime.wYear)
  459. return -1;
  460. }
  461. GetDaysInMonth(m_CurrentTime.wYear, m_CurrentTime.wMonth);
  462. wCurrValue = 1;
  463. m_CurrentTime.wDay = (USHORT) m_Set[INDX_Day].Next(wCurrValue);
  464. }
  465. }
  466. }
  467. }
  468. SystemTimeToFileTime(&m_CurrentTime, &FileTime);
  469. NewTime = FileTime.dwHighDateTime;
  470. NewTime = (NewTime << 32) + FileTime.dwLowDateTime;
  471. if(NULL != pSystemTime)
  472. *pSystemTime = m_CurrentTime;
  473. return NewTime;
  474. }
  475. ULONGLONG CDatePattern::SetStartTime(SYSTEMTIME StartTime)
  476. {
  477. WORD
  478. wCurrValue,
  479. ThresholdYear = 12;
  480. FILETIME
  481. FileTime;
  482. ULONGLONG
  483. NewTime;
  484. m_CurrentTime = StartTime;
  485. // **** check that there are at least one each of
  486. // **** year, month, hour, min and sec
  487. if((SETEMPTY == m_Set[INDX_Second].m_BitField) ||
  488. (SETEMPTY == m_Set[INDX_Minute].m_BitField) ||
  489. (SETEMPTY == m_Set[INDX_Hour].m_BitField) ||
  490. (SETEMPTY == m_Set[INDX_Quarter].m_BitField) ||
  491. (SETEMPTY == m_Set[INDX_WeekInMonth].m_BitField) ||
  492. (SETEMPTY == m_Set[INDX_DayOfWeek].m_BitField) ||
  493. (SETEMPTY == m_Set[INDX_Month].m_BitField))
  494. return -1;
  495. // **** find first Month/year combo following current time
  496. m_CurrentTime.wYear =
  497. (USHORT) m_Pattern[INDX_Year].GetNextValue(m_CurrentTime.wYear);
  498. if(m_CurrentTime.wYear == (USHORT)-1)
  499. return -1;
  500. if(m_CurrentTime.wYear != StartTime.wYear)
  501. m_CurrentTime.wMonth = (USHORT) m_Set[INDX_Month].Next(1);
  502. // **** now find first month/year that has at least
  503. // **** one day in it
  504. GetDaysInMonth(m_CurrentTime.wYear, m_CurrentTime.wMonth);
  505. while(SETEMPTY == m_Set[INDX_Day].m_BitField)
  506. {
  507. wCurrValue = m_CurrentTime.wMonth + 1;
  508. m_CurrentTime.wMonth = (USHORT) m_Set[INDX_Month].Next(wCurrValue);
  509. if(m_CurrentTime.wMonth < wCurrValue)
  510. m_CurrentTime.wYear
  511. = (USHORT) m_Pattern[INDX_Year].GetNextValue(m_CurrentTime.wYear + 1);
  512. if(m_CurrentTime.wYear == (USHORT)-1)
  513. return -1;
  514. GetDaysInMonth(m_CurrentTime.wYear, m_CurrentTime.wMonth);
  515. }
  516. // **** NOTE: it is still possible, at this point, to have a
  517. // **** day in month for the current year/month that is before
  518. // **** the current day. But, this is taken care of below.
  519. // **** align hour:min:sec to first valid date
  520. if((m_CurrentTime.wYear != StartTime.wYear) ||
  521. (m_CurrentTime.wMonth != StartTime.wMonth))
  522. {
  523. m_CurrentTime.wSecond = (USHORT) m_Set[INDX_Second].Next(0);
  524. m_CurrentTime.wMinute = (USHORT) m_Set[INDX_Minute].Next(0);
  525. m_CurrentTime.wHour = (USHORT) m_Set[INDX_Hour].Next(0);
  526. m_CurrentTime.wDay = (USHORT) m_Set[INDX_Day].Next(1);
  527. }
  528. else
  529. {
  530. wCurrValue = m_CurrentTime.wSecond;
  531. m_CurrentTime.wSecond = (USHORT) m_Set[INDX_Second].Next(wCurrValue);
  532. if(m_CurrentTime.wSecond < wCurrValue)
  533. m_CurrentTime.wMinute += 1;
  534. wCurrValue = m_CurrentTime.wMinute;
  535. m_CurrentTime.wMinute = (USHORT) m_Set[INDX_Minute].Next(wCurrValue);
  536. if(m_CurrentTime.wMinute < wCurrValue)
  537. m_CurrentTime.wHour += 1;
  538. wCurrValue = m_CurrentTime.wHour;
  539. m_CurrentTime.wHour = (USHORT) m_Set[INDX_Hour].Next(wCurrValue);
  540. if(m_CurrentTime.wHour < wCurrValue)
  541. m_CurrentTime.wDay += 1;
  542. wCurrValue = m_CurrentTime.wDay;
  543. m_CurrentTime.wDay = (USHORT) m_Set[INDX_Day].Next(wCurrValue);
  544. while((SETEMPTY == m_Set[INDX_Day].m_BitField) ||
  545. (m_CurrentTime.wDay < wCurrValue))
  546. {
  547. wCurrValue = m_CurrentTime.wMonth + 1;
  548. m_CurrentTime.wMonth = (USHORT) m_Set[INDX_Month].Next(wCurrValue);
  549. if(m_CurrentTime.wMonth < wCurrValue)
  550. m_CurrentTime.wYear
  551. = (USHORT) m_Pattern[INDX_Year].GetNextValue(m_CurrentTime.wYear + 1);
  552. if(m_CurrentTime.wYear == (USHORT)-1)
  553. return -1;
  554. GetDaysInMonth(m_CurrentTime.wYear, m_CurrentTime.wMonth);
  555. wCurrValue = 1;
  556. m_CurrentTime.wDay = (USHORT) m_Set[INDX_Day].Next(wCurrValue);
  557. }
  558. }
  559. SystemTimeToFileTime(&m_CurrentTime, &FileTime);
  560. NewTime = FileTime.dwHighDateTime;
  561. NewTime = (NewTime << 32) + FileTime.dwLowDateTime;
  562. return NewTime;
  563. }
  564. /******************************************************************/
  565. HRESULT WQLDateTime::Init(QL_LEVEL_1_RPN_EXPRESSION *pExp)
  566. {
  567. HRESULT
  568. hres = WBEM_S_NO_ERROR;
  569. int i, j;
  570. CDNFExpression
  571. DNFExpression;
  572. CConjunction
  573. *pConjunction;
  574. QL_LEVEL_1_TOKEN
  575. *pToken,
  576. *pTokens;
  577. pTokens = pExp->pArrayOfTokens + pExp->nNumTokens - 1;
  578. DNFExpression.CreateFromTokens(pTokens);
  579. if(pTokens != pExp->pArrayOfTokens - 1)
  580. return WBEM_E_CRITICAL_ERROR;
  581. DNFExpression.Sort();
  582. // **** first, if there is a previous definition, delete it
  583. if(m_NLeaves > 0)
  584. {
  585. m_NLeaves = 0;
  586. delete[] m_ParseTreeLeaves;
  587. }
  588. // **** now, build new logic
  589. m_NLeaves = DNFExpression.GetNumTerms();
  590. m_ParseTreeLeaves = new _DatePattern[m_NLeaves];
  591. if(NULL == m_ParseTreeLeaves)
  592. return WBEM_E_OUT_OF_MEMORY;
  593. for(i = 0; (i < m_NLeaves) && SUCCEEDED(hres); i++)
  594. {
  595. #ifdef WQLDEBUG
  596. if(i > 0) printf(" V ");
  597. #endif
  598. pConjunction = DNFExpression.GetTermAt(i);
  599. m_ParseTreeLeaves[i].m_Datum = new CDatePattern;
  600. if(NULL == m_ParseTreeLeaves[i].m_Datum)
  601. return WBEM_E_OUT_OF_MEMORY;
  602. #ifdef WQLDEBUG
  603. printf("(");
  604. #endif
  605. for(j = 0; j < pConjunction->GetNumTokens(); j++)
  606. {
  607. #ifdef WQLDEBUG
  608. if(j > 0) printf(" ^ ");
  609. #endif
  610. pToken = pConjunction->GetTokenAt(j);
  611. #ifdef WQLDEBUG
  612. wprintf(L"%s", pToken->GetText());
  613. #endif
  614. hres = m_ParseTreeLeaves[i].m_Datum->AugmentPattern(pToken);
  615. if(FAILED(hres)) return WBEM_E_INVALID_QUERY;
  616. }
  617. m_ParseTreeLeaves[i].m_Index = 0;
  618. m_ParseTreeLeaves[i].m_Next = NULL;
  619. #ifdef WQLDEBUG
  620. printf(")");
  621. #endif
  622. hres = m_ParseTreeLeaves[i].m_Datum->BuildSetsFromPatterns();
  623. if(FAILED(hres)) return WBEM_E_INVALID_QUERY;
  624. }
  625. return hres;
  626. }
  627. ULONGLONG WQLDateTime::SetStartTime(SYSTEMTIME *StartTime)
  628. {
  629. int i;
  630. if(NULL == StartTime)
  631. return -1;
  632. // **** insert all alternatives into ordered list
  633. m_ListHead = NULL;
  634. for(i = 0; i < m_NLeaves; i++)
  635. {
  636. m_ParseTreeLeaves[i].m_Next = NULL;
  637. m_ParseTreeLeaves[i].m_Index = m_ParseTreeLeaves[i].m_Datum->SetStartTime(*StartTime);
  638. if((ULONGLONG)-1 != m_ParseTreeLeaves[i].m_Index)
  639. InsertOrdered(m_ParseTreeLeaves + i);
  640. }
  641. return GetNextTime(StartTime);
  642. }
  643. void WQLDateTime::InsertOrdered(_DatePattern *pNode)
  644. {
  645. _DatePattern
  646. *pPrevDatePattern = NULL,
  647. *pDatePattern = m_ListHead;
  648. while(NULL != pDatePattern && (pNode->m_Index > pDatePattern->m_Index))
  649. {
  650. pPrevDatePattern = pDatePattern;
  651. pDatePattern = pDatePattern->m_Next;
  652. }
  653. pNode->m_Next = pDatePattern;
  654. if(NULL != pPrevDatePattern)
  655. pPrevDatePattern->m_Next = pNode;
  656. else
  657. m_ListHead = pNode;
  658. }
  659. ULONGLONG WQLDateTime::GetNextTime(SYSTEMTIME *NextTime)
  660. {
  661. _DatePattern
  662. *pDate;
  663. ULONGLONG
  664. FiringTime;
  665. if(NULL != m_ListHead)
  666. {
  667. pDate = m_ListHead;
  668. m_ListHead = m_ListHead->m_Next;
  669. FiringTime = pDate->m_Index;
  670. if(NULL != NextTime)
  671. *NextTime = pDate->m_Datum->m_CurrentTime;
  672. pDate->m_Index = pDate->m_Datum->GetNextTime();
  673. // **** if next time is -1 then there are no future times
  674. // **** so don't add back into list
  675. if((ULONGLONG)-1 != pDate->m_Index)
  676. InsertOrdered(pDate);
  677. return FiringTime;
  678. }
  679. return -1;
  680. }