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.

629 lines
22 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999.
  5. //
  6. // File: YYBase.cxx
  7. //
  8. // Contents: Custom base class for YYPARSER
  9. //
  10. // History: 30-Nov-1999 KyleP Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #pragma hdrstop
  14. #include "msidxtr.h"
  15. #include "yybase.hxx"
  16. //+-------------------------------------------------------------------------
  17. //
  18. // Member: CYYBase::CYYBase, public
  19. //
  20. // Synopsis: Constructor
  21. //
  22. // Arguments: [pParserSession] -- Session state
  23. // [pParserTreeProperties] -- Command properties
  24. // [yylex] -- Lexer
  25. //
  26. // History: 30-Nov-1999 KyleP Created
  27. //
  28. //--------------------------------------------------------------------------
  29. CYYBase::CYYBase( CImpIParserSession* pParserSession,
  30. CImpIParserTreeProperties* pParserTreeProperties,
  31. YYLEXER & yylex )
  32. : m_yylex( yylex ),
  33. m_pIPSession( pParserSession ),
  34. m_pIPTProperties( pParserTreeProperties )
  35. {
  36. }
  37. //+-------------------------------------------------------------------------
  38. //
  39. // Member: CYYBase::~CYYBase, public
  40. //
  41. // Synopsis: Destructor
  42. //
  43. // History: 30-Nov-1999 KyleP Created
  44. //
  45. //--------------------------------------------------------------------------
  46. CYYBase::~CYYBase()
  47. {
  48. }
  49. //+-------------------------------------------------------------------------
  50. //
  51. // Member: CYYBase::CoerceScalar, public
  52. //
  53. // Synopsis: Converts a scalar node to specified type.
  54. //
  55. // Arguments: [dbTypeExpected] -- Expected type
  56. // [ppct] -- Node to convert
  57. //
  58. // Returns: Error if conversion not possible
  59. //
  60. // History: 30-Nov-1999 KyleP Moved from YYPARSER
  61. //
  62. //--------------------------------------------------------------------------
  63. HRESULT CYYBase::CoerceScalar(
  64. DBTYPE dbTypeExpected, // @parm IN | DBTYPE that is expected in current context
  65. DBCOMMANDTREE** ppct ) // @parm IN/OUT | scalar node
  66. {
  67. Assert( VT_I8 == ((PROPVARIANT*)(*ppct)->value.pvValue)->vt ||
  68. VT_UI8 == ((PROPVARIANT*)(*ppct)->value.pvValue)->vt ||
  69. VT_R8 == ((PROPVARIANT*)(*ppct)->value.pvValue)->vt ||
  70. VT_BSTR == ((PROPVARIANT*)(*ppct)->value.pvValue)->vt ||
  71. VT_BOOL == ((PROPVARIANT*)(*ppct)->value.pvValue)->vt ||
  72. VT_FILETIME == ((PROPVARIANT*)(*ppct)->value.pvValue)->vt );
  73. DBTYPE dbType = dbTypeExpected & ~DBTYPE_VECTOR;
  74. if (DBTYPE_STR == (dbType & ~DBTYPE_BYREF))
  75. dbType = VT_LPSTR;
  76. if (DBTYPE_WSTR == (dbType & ~DBTYPE_BYREF))
  77. dbType = VT_LPWSTR;
  78. HRESULT hr = (*ppct)->hrError;
  79. if (S_OK != hr)
  80. goto error;
  81. if (dbType == ((PROPVARIANT*)(*ppct)->value.pvValue)->vt)
  82. return hr;
  83. switch ( ((PROPVARIANT*)(*ppct)->value.pvValue)->vt )
  84. {
  85. case VT_UI8:
  86. {
  87. ULONGLONG uhVal = ((PROPVARIANT*)(*ppct)->value.pvValue)->uhVal.QuadPart;
  88. switch ( dbType )
  89. {
  90. case VT_UI1:
  91. if (uhVal > UCHAR_MAX)
  92. hr = DISP_E_TYPEMISMATCH;
  93. else
  94. {
  95. ((PROPVARIANT*)(*ppct)->value.pvValue)->bVal = (UCHAR)uhVal;
  96. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_UI1;
  97. }
  98. break;
  99. case VT_I1:
  100. if (uhVal > CHAR_MAX)
  101. hr = DB_E_DATAOVERFLOW;
  102. else
  103. {
  104. ((PROPVARIANT*)(*ppct)->value.pvValue)->cVal = (CHAR)uhVal;
  105. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_I1;
  106. }
  107. break;
  108. case VT_UI2:
  109. if (uhVal > USHRT_MAX)
  110. hr = DB_E_DATAOVERFLOW;
  111. else
  112. {
  113. ((PROPVARIANT*)(*ppct)->value.pvValue)->uiVal = (USHORT)uhVal;
  114. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_UI2;
  115. }
  116. break;
  117. case VT_I2:
  118. if (uhVal > SHRT_MAX)
  119. hr = DB_E_DATAOVERFLOW;
  120. else
  121. {
  122. ((PROPVARIANT*)(*ppct)->value.pvValue)->iVal = (SHORT)uhVal;
  123. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_I2;
  124. }
  125. break;
  126. case VT_UI4:
  127. if (uhVal > ULONG_MAX)
  128. hr = DB_E_DATAOVERFLOW;
  129. else
  130. {
  131. ((PROPVARIANT*)(*ppct)->value.pvValue)->ulVal = (ULONG)uhVal;
  132. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_UI4;
  133. }
  134. break;
  135. case VT_I4:
  136. if (uhVal > LONG_MAX)
  137. hr = DB_E_DATAOVERFLOW;
  138. else
  139. {
  140. ((PROPVARIANT*)(*ppct)->value.pvValue)->lVal = (LONG)uhVal;
  141. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_I4;
  142. }
  143. break;
  144. case VT_I8:
  145. if (uhVal > _I64_MAX)
  146. hr = DB_E_DATAOVERFLOW;
  147. else
  148. {
  149. ((PROPVARIANT*)(*ppct)->value.pvValue)->hVal.QuadPart = (LONGLONG)uhVal;
  150. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_I8;
  151. }
  152. break;
  153. case VT_R4:
  154. ((PROPVARIANT*)(*ppct)->value.pvValue)->fltVal = (float)(LONGLONG)uhVal;
  155. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_R4;
  156. break;
  157. case VT_R8:
  158. ((PROPVARIANT*)(*ppct)->value.pvValue)->dblVal = (double)(LONGLONG)uhVal;
  159. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_R8;
  160. break;
  161. default:
  162. hr = DB_E_CANTCONVERTVALUE;
  163. }
  164. }
  165. break;
  166. case VT_I8:
  167. {
  168. LONGLONG hVal = ((PROPVARIANT*)(*ppct)->value.pvValue)->hVal.QuadPart;
  169. switch ( dbType )
  170. {
  171. case VT_UI1:
  172. case VT_UI2:
  173. case VT_UI4:
  174. case VT_UI8:
  175. hr = DB_E_CANTCONVERTVALUE;
  176. break;
  177. case VT_I1:
  178. if (hVal < CHAR_MIN || hVal > CHAR_MAX)
  179. hr = DB_E_DATAOVERFLOW;
  180. else
  181. {
  182. ((PROPVARIANT*)(*ppct)->value.pvValue)->cVal = (CHAR)hVal;
  183. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_I1;
  184. }
  185. break;
  186. case VT_I2:
  187. if (hVal < SHRT_MIN || hVal > SHRT_MAX)
  188. hr = DB_E_DATAOVERFLOW;
  189. else
  190. {
  191. ((PROPVARIANT*)(*ppct)->value.pvValue)->iVal = (SHORT)hVal;
  192. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_I2;
  193. }
  194. break;
  195. case VT_I4:
  196. if (hVal < LONG_MIN || hVal > LONG_MAX)
  197. hr = DB_E_DATAOVERFLOW;
  198. else
  199. {
  200. ((PROPVARIANT*)(*ppct)->value.pvValue)->lVal = (LONG)hVal;
  201. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_I4;
  202. }
  203. break;
  204. case VT_R4:
  205. ((PROPVARIANT*)(*ppct)->value.pvValue)->fltVal = (float)hVal;
  206. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_R4;
  207. break;
  208. case VT_R8:
  209. ((PROPVARIANT*)(*ppct)->value.pvValue)->dblVal = (double)hVal;
  210. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_R8;
  211. break;
  212. default:
  213. hr = DB_E_CANTCONVERTVALUE;
  214. }
  215. }
  216. break;
  217. case VT_R8:
  218. switch ( dbType )
  219. {
  220. case VT_R4:
  221. ((PROPVARIANT*)(*ppct)->value.pvValue)->fltVal =
  222. (float)((PROPVARIANT*)(*ppct)->value.pvValue)->dblVal;
  223. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_R4;
  224. break;
  225. case VT_CY:
  226. hr = VariantChangeTypeEx( (*ppct)->value.pvarValue, // convert in place
  227. (*ppct)->value.pvarValue,
  228. LOCALE_SYSTEM_DEFAULT,
  229. 0,
  230. VT_CY );
  231. break;
  232. default:
  233. hr = DB_E_CANTCONVERTVALUE;
  234. }
  235. break;
  236. case VT_BSTR:
  237. switch ( dbType )
  238. {
  239. case VT_R8:
  240. //
  241. // Our syntax doesn't allow for numeric separators in other
  242. // locales than US English. So, use the English US lcid for this
  243. // conversion.
  244. //
  245. hr = VariantChangeTypeEx((*ppct)->value.pvarValue, // convert in place
  246. (*ppct)->value.pvarValue,
  247. MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  248. SORT_DEFAULT),
  249. 0,
  250. VT_R8);
  251. break;
  252. case VT_LPSTR:
  253. {
  254. int cLen = WideCharToMultiByte(
  255. CP_ACP,
  256. 0,
  257. ((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal,
  258. SysStringLen(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal), // number of characters in string
  259. NULL, // address of buffer for new string
  260. 0, // size of buffer
  261. NULL, // address of default for unmappable characters
  262. NULL); // address of flag set when default char. used
  263. LPSTR pszVal = (LPSTR) CoTaskMemAlloc(cLen+1);
  264. if (NULL == pszVal)
  265. hr = E_OUTOFMEMORY;
  266. else
  267. {
  268. cLen = WideCharToMultiByte(
  269. CP_ACP,
  270. 0,
  271. ((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal,
  272. SysStringLen(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal), // number of characters in string
  273. pszVal, // address of buffer for new string
  274. cLen+1, // size of buffer
  275. NULL, // address of default for unmappable characters
  276. NULL); // address of flag set when default char. used
  277. SysFreeString(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal);
  278. pszVal[cLen] = '\0';
  279. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_LPSTR;
  280. ((PROPVARIANT*)(*ppct)->value.pvValue)->pszVal = pszVal;
  281. }
  282. }
  283. break;
  284. case VT_LPWSTR:
  285. {
  286. LPWSTR pwszVal = CoTaskStrDup(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal);
  287. if (NULL == pwszVal)
  288. hr = E_OUTOFMEMORY;
  289. else
  290. {
  291. SysFreeString(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal);
  292. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_LPWSTR;
  293. ((PROPVARIANT*)(*ppct)->value.pvValue)->pwszVal = pwszVal;
  294. }
  295. }
  296. break;
  297. case VT_CLSID:
  298. {
  299. GUID* pGuid = (GUID*) CoTaskMemAlloc(sizeof GUID);
  300. if (NULL == pGuid)
  301. hr = E_OUTOFMEMORY;
  302. else
  303. {
  304. BOOL bRet = ParseGuid(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal, *pGuid);
  305. if ( bRet && GUID_NULL != *pGuid )
  306. {
  307. SysFreeString(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal);
  308. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_CLSID;
  309. ((PROPVARIANT*)(*ppct)->value.pvValue)->puuid = pGuid;
  310. }
  311. else
  312. {
  313. CoTaskMemFree(pGuid);
  314. hr = DB_E_CANTCONVERTVALUE;
  315. }
  316. }
  317. }
  318. break;
  319. case VT_FILETIME:
  320. case VT_DATE:
  321. {
  322. SYSTEMTIME stValue = {0, 0, 0, 0, 0, 0, 0, 0};
  323. // convert a string to a filetime value
  324. int cItems = swscanf(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal,
  325. L"%4hd/%2hd/%2hd %2hd:%2hd:%2hd:%3hd",
  326. &stValue.wYear,
  327. &stValue.wMonth,
  328. &stValue.wDay,
  329. &stValue.wHour,
  330. &stValue.wMinute,
  331. &stValue.wSecond,
  332. &stValue.wMilliseconds);
  333. if (1 == cItems)
  334. cItems = swscanf(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal,
  335. L"%4hd-%2hd-%2hd %2hd:%2hd:%2hd:%3hd",
  336. &stValue.wYear,
  337. &stValue.wMonth,
  338. &stValue.wDay,
  339. &stValue.wHour,
  340. &stValue.wMinute,
  341. &stValue.wSecond,
  342. &stValue.wMilliseconds );
  343. if (cItems != 3 && cItems != 6 && cItems != 7)
  344. hr = E_FAIL;
  345. //
  346. // Make a sensible split for Year 2000 using the user's system settings
  347. //
  348. if ( stValue.wYear < 100 )
  349. {
  350. DWORD dwYearHigh = 0;
  351. if ( 0 == GetCalendarInfo ( m_pIPSession->GetLCID(),
  352. CAL_GREGORIAN,
  353. CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
  354. 0,
  355. 0,
  356. &dwYearHigh ) )
  357. {
  358. hr = HRESULT_FROM_WIN32 ( GetLastError() );
  359. }
  360. if ( ( dwYearHigh < 99 ) || ( dwYearHigh > 9999 ) )
  361. dwYearHigh = 2029;
  362. WORD wMaxDecade = (WORD) dwYearHigh % 100;
  363. WORD wMaxCentury = (WORD) dwYearHigh - wMaxDecade;
  364. if ( stValue.wYear <= wMaxDecade )
  365. stValue.wYear += wMaxCentury;
  366. else
  367. stValue.wYear += ( wMaxCentury - 100 );
  368. }
  369. SysFreeString(((PROPVARIANT*)(*ppct)->value.pvValue)->bstrVal);
  370. int iResult = 0;
  371. if (VT_FILETIME == dbType)
  372. iResult = SystemTimeToFileTime(&stValue, &((PROPVARIANT*)(*ppct)->value.pvValue)->filetime);
  373. else
  374. iResult = SystemTimeToVariantTime(&stValue, &((PROPVARIANT*)(*ppct)->value.pvValue)->date);
  375. if (0 == iResult)
  376. {
  377. // SystemTimeTo* conversion failed. Most likely we were given the date in a bogus format.
  378. (*ppct)->hrError = DB_E_CANTCONVERTVALUE;
  379. hr = DB_E_CANTCONVERTVALUE;
  380. }
  381. else
  382. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = dbType;
  383. }
  384. break;
  385. default:
  386. hr = DB_E_CANTCONVERTVALUE;
  387. }
  388. break;
  389. case VT_FILETIME:
  390. switch ( dbType )
  391. {
  392. case VT_DATE:
  393. {
  394. SYSTEMTIME stValue = {0, 0, 0, 0, 0, 0, 0, 0};
  395. if ( FileTimeToSystemTime(&((PROPVARIANT*)(*ppct)->value.pvValue)->filetime, &stValue) )
  396. {
  397. int iResult = SystemTimeToVariantTime(&stValue, &((PROPVARIANT*)(*ppct)->value.pvValue)->date);
  398. if (0 == iResult)
  399. {
  400. // SystemTimeToVariantTime failed. Most likely we were given the date in a bogus format.
  401. (*ppct)->hrError = DB_E_CANTCONVERTVALUE;
  402. hr = DB_E_CANTCONVERTVALUE;
  403. }
  404. else
  405. ((PROPVARIANT*)(*ppct)->value.pvValue)->vt = VT_DATE;
  406. }
  407. else
  408. hr = DISP_E_TYPEMISMATCH;
  409. }
  410. break;
  411. default:
  412. hr = DB_E_CANTCONVERTVALUE;
  413. }
  414. break;
  415. default:
  416. hr = DB_E_CANTCONVERTVALUE;
  417. break;
  418. }
  419. error:
  420. if (S_OK != hr)
  421. {
  422. switch ( hr )
  423. {
  424. case DB_E_DATAOVERFLOW:
  425. m_pIPTProperties->SetErrorHResult(hr, MONSQL_OUT_OF_RANGE);
  426. break;
  427. case E_OUTOFMEMORY:
  428. m_pIPTProperties->SetErrorHResult(hr, MONSQL_OUT_OF_MEMORY);
  429. break;
  430. default:
  431. m_pIPTProperties->SetErrorHResult(hr, MONSQL_CANNOT_CONVERT);
  432. }
  433. m_pIPTProperties->SetErrorToken((YY_CHAR*)m_yylex.YYText());
  434. switch ( dbType )
  435. {
  436. case DBTYPE_UI1:
  437. m_pIPTProperties->SetErrorToken(L"DBTYPE_UI1");
  438. break;
  439. case DBTYPE_I1:
  440. m_pIPTProperties->SetErrorToken(L"DBTYPE_I1");
  441. break;
  442. case DBTYPE_UI2:
  443. m_pIPTProperties->SetErrorToken(L"DBTYPE_UI2");
  444. break;
  445. case DBTYPE_UI4:
  446. m_pIPTProperties->SetErrorToken(L"DBTYPE_UI4");
  447. break;
  448. case DBTYPE_UI8:
  449. m_pIPTProperties->SetErrorToken(L"DBTYPE_UI8");
  450. break;
  451. case DBTYPE_I2:
  452. m_pIPTProperties->SetErrorToken(L"DBTYPE_I2");
  453. break;
  454. case DBTYPE_I4:
  455. m_pIPTProperties->SetErrorToken(L"DBTYPE_I4");
  456. break;
  457. case DBTYPE_I8:
  458. m_pIPTProperties->SetErrorToken(L"DBTYPE_I8");
  459. break;
  460. case DBTYPE_R4:
  461. m_pIPTProperties->SetErrorToken(L"DBTYPE_R4");
  462. break;
  463. case DBTYPE_R8:
  464. m_pIPTProperties->SetErrorToken(L"DBTYPE_R8");
  465. break;
  466. case DBTYPE_CY:
  467. m_pIPTProperties->SetErrorToken(L"DBTYPE_CY");
  468. break;
  469. case DBTYPE_DATE:
  470. m_pIPTProperties->SetErrorToken(L"DBTYPE_DATE");
  471. break;
  472. case DBTYPE_BSTR:
  473. m_pIPTProperties->SetErrorToken(L"DBTYPE_BSTR");
  474. break;
  475. case DBTYPE_BOOL:
  476. m_pIPTProperties->SetErrorToken(L"DBTYPE_BOOL");
  477. break;
  478. case DBTYPE_GUID:
  479. m_pIPTProperties->SetErrorToken(L"DBTYPE_GUID");
  480. break;
  481. case DBTYPE_STR:
  482. m_pIPTProperties->SetErrorToken(L"DBTYPE_STR");
  483. break;
  484. case DBTYPE_STR | DBTYPE_BYREF:
  485. m_pIPTProperties->SetErrorToken(L"DBTYPE_STR|DBTYPE_BYREF");
  486. break;
  487. case DBTYPE_WSTR:
  488. m_pIPTProperties->SetErrorToken(L"DBTYPE_WSTR");
  489. break;
  490. case DBTYPE_WSTR | DBTYPE_BYREF:
  491. m_pIPTProperties->SetErrorToken(L"DBTYPE_WSTR | DBTYPE_BYREF");
  492. break;
  493. case VT_FILETIME:
  494. m_pIPTProperties->SetErrorToken(L"VT_FILETIME");
  495. break;
  496. default:
  497. m_pIPTProperties->SetErrorToken(L"DBTYPE_NULL");
  498. break;
  499. }
  500. }
  501. return hr;
  502. }
  503. //+-------------------------------------------------------------------------
  504. //
  505. // Member: CYYBase::yyprimebuffer, public
  506. //
  507. // Synopsis: Prime lexer with text (passthrough to lexer)
  508. //
  509. // Arguments: [pszBuffer] -- Buffer
  510. //
  511. // History: 30-Nov-1999 KyleP Moved from YYPARSER
  512. //
  513. //--------------------------------------------------------------------------
  514. void CYYBase::yyprimebuffer(YY_CHAR *pszBuffer)
  515. {
  516. m_yylex.yyprimebuffer(pszBuffer);
  517. }
  518. //+-------------------------------------------------------------------------
  519. //
  520. // Member: CYYBase::yyprimelexer, public
  521. //
  522. // Synopsis: Prime lexer with initial token (passthrough to lexer)
  523. //
  524. // Arguments: [eToken] -- Token
  525. //
  526. // History: 30-Nov-1999 KyleP Moved from YYPARSER
  527. //
  528. //--------------------------------------------------------------------------
  529. void CYYBase::yyprimelexer(int eToken)
  530. {
  531. m_yylex.yyprimelexer(eToken);
  532. }
  533. //+-------------------------------------------------------------------------
  534. //
  535. // Member: CYYBase::yyerror, protected
  536. //
  537. // Synopsis: Report parsing errors
  538. //
  539. // Arguments: [szError] -- Error string
  540. //
  541. // History: 30-Nov-1999 KyleP Moved from YYPARSER
  542. //
  543. //--------------------------------------------------------------------------
  544. void CYYBase::yyerror( char const * szError )
  545. {
  546. }