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.

806 lines
23 KiB

  1. //***************************************************************************
  2. //
  3. // ANALYSER.CPP
  4. //
  5. // Module: OLE MS Provider Framework
  6. //
  7. // Copyright (c) 1996-2001 Microsoft Corporation, All Rights Reserved
  8. //
  9. //***************************************************************************
  10. #include "precomp.h"
  11. #include <instpath.h>
  12. #include <provexpt.h>
  13. #include <strsafe.h>
  14. WbemLexicon :: WbemLexicon () : position ( 0 ) , tokenStream ( NULL )
  15. {
  16. value.string = NULL ;
  17. value.token = NULL ;
  18. }
  19. WbemLexicon :: ~WbemLexicon ()
  20. {
  21. switch ( token )
  22. {
  23. case TOKEN_ID:
  24. {
  25. delete [] value.token ;
  26. }
  27. break ;
  28. case STRING_ID:
  29. {
  30. delete [] value.string ;
  31. }
  32. break ;
  33. default:
  34. {
  35. } ;
  36. }
  37. }
  38. WbemLexicon :: LexiconToken WbemLexicon :: GetToken ()
  39. {
  40. return token ;
  41. }
  42. WbemLexiconValue *WbemLexicon :: GetValue ()
  43. {
  44. return &value ;
  45. }
  46. WbemAnalyser :: WbemAnalyser ( WCHAR *tokenStream ) : status ( TRUE ) , position ( 0 ) , stream ( NULL )
  47. {
  48. if ( tokenStream )
  49. {
  50. DWORD t_TextLength = wcslen ( tokenStream ) + 1 ;
  51. stream = new WCHAR [ t_TextLength ] ;
  52. StringCchCopyW ( stream , t_TextLength , tokenStream ) ;
  53. }
  54. }
  55. WbemAnalyser :: ~WbemAnalyser ()
  56. {
  57. delete [] stream ;
  58. }
  59. void WbemAnalyser :: Set ( WCHAR *tokenStream )
  60. {
  61. status = 0 ;
  62. position = NULL ;
  63. delete [] stream ;
  64. DWORD t_TextLength = wcslen ( tokenStream ) + 1 ;
  65. stream = new WCHAR [ t_TextLength ] ;
  66. StringCchCopyW ( stream , t_TextLength , tokenStream ) ;
  67. }
  68. void WbemAnalyser :: PutBack ( WbemLexicon *token )
  69. {
  70. position = token->position ;
  71. }
  72. BOOL WbemAnalyser :: IsLeadingDecimal ( WCHAR token )
  73. {
  74. return iswdigit ( token ) && ( token != L'0' ) ;
  75. }
  76. BOOL WbemAnalyser :: IsDecimal ( WCHAR token )
  77. {
  78. return iswdigit ( token ) ;
  79. }
  80. BOOL WbemAnalyser :: IsHex ( WCHAR token )
  81. {
  82. return iswxdigit ( token ) ;
  83. }
  84. BOOL WbemAnalyser :: IsWhitespace ( WCHAR token )
  85. {
  86. return iswspace ( token ) ;
  87. }
  88. BOOL WbemAnalyser :: IsOctal ( WCHAR token )
  89. {
  90. return ( token >= L'0' && token <= L'7' ) ;
  91. }
  92. BOOL WbemAnalyser :: IsAlpha ( WCHAR token )
  93. {
  94. return iswalpha ( token ) ;
  95. }
  96. BOOL WbemAnalyser :: IsAlphaNumeric ( WCHAR token )
  97. {
  98. return iswalnum ( token ) || ( token == L'_' ) || ( token == L'-' ) ;
  99. }
  100. BOOL WbemAnalyser :: IsEof ( WCHAR token )
  101. {
  102. return token == 0 ;
  103. }
  104. LONG WbemAnalyser :: OctToDec ( WCHAR token )
  105. {
  106. return token - L'0' ;
  107. }
  108. LONG WbemAnalyser :: HexToDec ( WCHAR token )
  109. {
  110. if ( token >= L'0' && token <= L'9' )
  111. {
  112. return token - L'0' ;
  113. }
  114. else if ( token >= L'a' && token <= L'f' )
  115. {
  116. return token - L'a' + 10 ;
  117. }
  118. else if ( token >= L'A' && token <= L'F' )
  119. {
  120. return token - L'A' + 10 ;
  121. }
  122. else
  123. {
  124. return 0 ;
  125. }
  126. }
  127. WbemAnalyser :: operator void * ()
  128. {
  129. return status ? this : NULL ;
  130. }
  131. #define DEC_INTEGER_START 1000
  132. #define HEX_INTEGER_START 2000
  133. #define OCT_INTEGER_START 3000
  134. #define STRING_START 4000
  135. #define TOKEN_START 5000
  136. #define OID_START 6000
  137. #define OID_STATE 9000
  138. #define TOKEN_STATE 9001
  139. #define STRING_STATE 9002
  140. #define EOF_STATE 9003
  141. #define DEC_INTEGER_STATE 9004
  142. #define HEX_INTEGER_STATE 9005
  143. #define OCT_INTEGER_STATE 9006
  144. #define ACCEPT_STATE 10000
  145. #define REJECT_STATE 10001
  146. WbemLexicon *WbemAnalyser :: Get ()
  147. {
  148. WbemLexicon *lexicon = NULL ;
  149. if ( stream )
  150. {
  151. lexicon = GetToken () ;
  152. }
  153. else
  154. {
  155. lexicon = new WbemLexicon ;
  156. lexicon->position = position ;
  157. lexicon->token = WbemLexicon :: EOF_ID ;
  158. }
  159. return lexicon ;
  160. }
  161. WbemLexicon *WbemAnalyser :: GetToken ()
  162. {
  163. WbemLexicon *lexicon = new WbemLexicon ;
  164. lexicon->position = position ;
  165. ULONG state = 0 ;
  166. /*
  167. * Integer Definitions
  168. */
  169. BOOL negative = FALSE ;
  170. LONG magicMult = ( LONG ) ( ( ( ULONG ) ( 1L << 31L ) ) / 10L ) ;
  171. LONG magicNegDigit = 8 ;
  172. LONG magicPosDigit = 7 ;
  173. LONG datum = 0 ;
  174. /*
  175. * String Definitions
  176. */
  177. ULONG string_start = 0 ;
  178. ULONG string_length = 0 ;
  179. WCHAR *string = NULL ;
  180. /*
  181. * Token Definitions
  182. */
  183. ULONG token_start = 0 ;
  184. /*
  185. * OID Definitions
  186. */
  187. ULONG hex_datum = 0 ;
  188. ULONG brace_position = 0 ;
  189. ULONG hex_repetitions = 0 ;
  190. ULONG nybbleRepetitions = 0 ;
  191. while ( state != REJECT_STATE && state != ACCEPT_STATE )
  192. {
  193. WCHAR token = stream [ position ] ;
  194. switch ( state )
  195. {
  196. case 0:
  197. {
  198. if ( IsLeadingDecimal ( token ) )
  199. {
  200. state = DEC_INTEGER_START + 1 ;
  201. datum = ( token - 48 ) ;
  202. }
  203. else if ( token == L'@' )
  204. {
  205. lexicon->token = WbemLexicon :: AT_ID ;
  206. state = ACCEPT_STATE ;
  207. }
  208. else if ( token == L'\\' )
  209. {
  210. lexicon->token = WbemLexicon :: BACKSLASH_ID ;
  211. state = ACCEPT_STATE ;
  212. }
  213. else if ( token == L'\"' )
  214. {
  215. state = STRING_START ;
  216. string_start = position + 1 ;
  217. }
  218. else if ( token == L'{' )
  219. {
  220. state = OID_START ;
  221. hex_datum = 0 ;
  222. brace_position = position ;
  223. hex_repetitions = 0 ;
  224. nybbleRepetitions = 0 ;
  225. }
  226. else if ( token == L'}' )
  227. {
  228. lexicon->token = WbemLexicon :: CLOSE_BRACE_ID ;
  229. state = ACCEPT_STATE ;
  230. }
  231. else if ( token == L'=' )
  232. {
  233. lexicon->token = WbemLexicon :: EQUALS_ID ;
  234. state = ACCEPT_STATE ;
  235. }
  236. else if ( token == L'.' )
  237. {
  238. lexicon->token = WbemLexicon :: DOT_ID ;
  239. state = ACCEPT_STATE ;
  240. }
  241. else if ( token == L',' )
  242. {
  243. lexicon->token = WbemLexicon :: COMMA_ID ;
  244. state = ACCEPT_STATE ;
  245. }
  246. else if ( token == L':' )
  247. {
  248. lexicon->token = WbemLexicon :: COLON_ID ;
  249. state = ACCEPT_STATE ;
  250. }
  251. else if ( token == L'+' )
  252. {
  253. state = DEC_INTEGER_START ;
  254. }
  255. else if ( token == L'-' )
  256. {
  257. negative = TRUE ;
  258. state = DEC_INTEGER_START ;
  259. }
  260. else if ( token == L'0' )
  261. {
  262. state = 1 ;
  263. }
  264. else if ( IsWhitespace ( token ) )
  265. {
  266. state = 0 ;
  267. }
  268. else if ( IsEof ( token ) )
  269. {
  270. lexicon->token = WbemLexicon :: EOF_ID ;
  271. state = ACCEPT_STATE ;
  272. }
  273. else if ( IsAlpha ( token ) )
  274. {
  275. state = TOKEN_START ;
  276. token_start = position ;
  277. }
  278. else state = REJECT_STATE ;
  279. }
  280. break ;
  281. case 1:
  282. {
  283. if ( token == L'x' || token == L'X' )
  284. {
  285. state = HEX_INTEGER_START ;
  286. }
  287. else if ( IsOctal ( token ) )
  288. {
  289. state = OCT_INTEGER_START ;
  290. datum = ( token - 48 ) ;
  291. }
  292. else
  293. {
  294. lexicon->token = WbemLexicon :: INTEGER_ID ;
  295. lexicon->value.integer = 0 ;
  296. position -- ;
  297. state = ACCEPT_STATE ;
  298. }
  299. }
  300. break ;
  301. case STRING_START:
  302. {
  303. if ( token == L'\"' )
  304. {
  305. lexicon->token = WbemLexicon :: STRING_ID ;
  306. state = ACCEPT_STATE ;
  307. if ( position == string_start )
  308. {
  309. lexicon->value.string = new WCHAR [ 1 ] ;
  310. lexicon->value.string [ 0 ] = 0 ;
  311. }
  312. else
  313. {
  314. lexicon->value.string = new WCHAR [ string_length + 1 ] ;
  315. wcsncpy (
  316. lexicon->value.string ,
  317. string ,
  318. string_length
  319. ) ;
  320. lexicon->value.string [ string_length ] = 0 ;
  321. free (string);
  322. }
  323. }
  324. else if ( token == IsEof ( token ) )
  325. {
  326. state = REJECT_STATE ;
  327. free (string);
  328. }
  329. else
  330. {
  331. realloc_throw ( &string , sizeof ( WCHAR ) * ( string_length + 1 ) ) ;
  332. string [ string_length ] = token ;
  333. string_length ++ ;
  334. state = STRING_START ;
  335. }
  336. }
  337. break ;
  338. case STRING_START+1:
  339. {
  340. if ( token == L'\"' )
  341. {
  342. realloc_throw ( &string , sizeof ( WCHAR ) * ( string_length + 1 ) ) ;
  343. string [ string_length ] = L'\"' ;
  344. string_length ++ ;
  345. state = STRING_START ;
  346. }
  347. else if ( token == IsEof ( token ) )
  348. {
  349. state = REJECT_STATE ;
  350. }
  351. else
  352. {
  353. realloc_throw ( &string , sizeof ( WCHAR ) * ( string_length + 1 ) ) ;
  354. string [ string_length ] = token ;
  355. string_length ++ ;
  356. state = STRING_START ;
  357. }
  358. }
  359. break ;
  360. case TOKEN_START:
  361. {
  362. if ( IsAlphaNumeric ( token ) )
  363. {
  364. state = TOKEN_START ;
  365. }
  366. else
  367. {
  368. state = ACCEPT_STATE ;
  369. lexicon->token = WbemLexicon :: TOKEN_ID ;
  370. lexicon->value.token = new WCHAR [ position - token_start + 1 ] ;
  371. wcsncpy (
  372. lexicon->value.token ,
  373. & stream [ token_start ] ,
  374. position - token_start
  375. ) ;
  376. lexicon->value.token [ position - token_start ] = 0 ;
  377. position -- ;
  378. }
  379. }
  380. break ;
  381. case HEX_INTEGER_START:
  382. {
  383. if ( IsHex ( token ) )
  384. {
  385. datum = HexToDec ( token ) ;
  386. state = HEX_INTEGER_START + 1 ;
  387. }
  388. else
  389. {
  390. state = REJECT_STATE ;
  391. }
  392. }
  393. break ;
  394. case HEX_INTEGER_START+1:
  395. {
  396. if ( IsHex ( token ) )
  397. {
  398. state = HEX_INTEGER_START + 1 ;
  399. if ( datum > magicMult )
  400. {
  401. state = REJECT_STATE ;
  402. }
  403. else if ( datum == magicMult )
  404. {
  405. if ( HexToDec ( token ) > magicPosDigit )
  406. {
  407. state = REJECT_STATE ;
  408. }
  409. }
  410. datum = ( datum << 4 ) + HexToDec ( token ) ;
  411. }
  412. else
  413. {
  414. lexicon->token = WbemLexicon :: INTEGER_ID ;
  415. lexicon->value.integer = datum ;
  416. state = ACCEPT_STATE ;
  417. position -- ;
  418. }
  419. }
  420. break ;
  421. case OCT_INTEGER_START:
  422. {
  423. if ( IsOctal ( token ) )
  424. {
  425. state = OCT_INTEGER_START ;
  426. if ( datum > magicMult )
  427. {
  428. state = REJECT_STATE ;
  429. }
  430. else if ( datum == magicMult )
  431. {
  432. if ( OctToDec ( token ) > magicPosDigit )
  433. {
  434. state = REJECT_STATE ;
  435. }
  436. }
  437. datum = ( datum << 3 ) + OctToDec ( token ) ;
  438. }
  439. else
  440. {
  441. lexicon->token = WbemLexicon :: INTEGER_ID ;
  442. lexicon->value.integer = datum ;
  443. state = ACCEPT_STATE ;
  444. position -- ;
  445. }
  446. }
  447. break ;
  448. case DEC_INTEGER_START:
  449. {
  450. if ( IsDecimal ( token ) )
  451. {
  452. state = DEC_INTEGER_START + 1 ;
  453. datum = ( token - 48 ) ;
  454. }
  455. else
  456. if ( IsWhitespace ( token ) )
  457. {
  458. state = DEC_INTEGER_START ;
  459. }
  460. else state = REJECT_STATE ;
  461. }
  462. break ;
  463. case DEC_INTEGER_START+1:
  464. {
  465. if ( IsDecimal ( token ) )
  466. {
  467. state = DEC_INTEGER_START + 1 ;
  468. if ( datum > magicMult )
  469. {
  470. state = REJECT_STATE ;
  471. }
  472. else if ( datum == magicMult )
  473. {
  474. if ( negative )
  475. {
  476. if ( ( token - 48 ) > magicNegDigit )
  477. {
  478. state = REJECT_STATE ;
  479. }
  480. }
  481. else
  482. {
  483. if ( ( token - 48 ) > magicPosDigit )
  484. {
  485. state = REJECT_STATE ;
  486. }
  487. }
  488. }
  489. datum = datum * 10 + ( token - 48 ) ;
  490. }
  491. else
  492. {
  493. lexicon->token = WbemLexicon :: INTEGER_ID ;
  494. if ( negative )
  495. {
  496. lexicon->value.integer = datum * -1 ;
  497. }
  498. else
  499. {
  500. lexicon->value.integer = datum ;
  501. }
  502. state = ACCEPT_STATE ;
  503. position -- ;
  504. }
  505. }
  506. break ;
  507. case OID_START: // {xxxxxxxx
  508. {
  509. if ( IsHex ( token ) )
  510. {
  511. hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 7 - hex_repetitions ) << 2 ) ) ;
  512. hex_repetitions ++ ;
  513. if ( hex_repetitions == 8 )
  514. {
  515. state = OID_START + 1 ;
  516. lexicon->value.guid.Data1 = hex_datum ;
  517. hex_repetitions = 0 ;
  518. hex_datum = 0 ;
  519. }
  520. }
  521. else
  522. {
  523. state = ACCEPT_STATE ;
  524. position = brace_position ;
  525. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  526. }
  527. }
  528. break ;
  529. case OID_START+1: // {xxxxxxxx-
  530. {
  531. if ( token == L'-' )
  532. {
  533. state = OID_START + 2 ;
  534. }
  535. else
  536. {
  537. state = ACCEPT_STATE ;
  538. position = brace_position ;
  539. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  540. }
  541. }
  542. break ;
  543. case OID_START+2: // {xxxxxxxx-xxxx
  544. {
  545. if ( IsHex ( token ) )
  546. {
  547. hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 3 - hex_repetitions ) << 2 ) ) ;
  548. hex_repetitions ++ ;
  549. if ( hex_repetitions == 4 )
  550. {
  551. lexicon->value.guid.Data2 = ( USHORT ) hex_datum ;
  552. hex_repetitions = 0 ;
  553. hex_datum = 0 ;
  554. state = OID_START + 3 ;
  555. }
  556. }
  557. else
  558. {
  559. state = ACCEPT_STATE ;
  560. position = brace_position ;
  561. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  562. }
  563. }
  564. break ;
  565. case OID_START+3: // {xxxxxxxx-xxxx-
  566. {
  567. if ( token == L'-' )
  568. {
  569. state = OID_START + 4 ;
  570. }
  571. else
  572. {
  573. state = ACCEPT_STATE ;
  574. position = brace_position ;
  575. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  576. }
  577. }
  578. break ;
  579. case OID_START+4: // {xxxxxxxx-xxxx-xxxx
  580. {
  581. if ( IsHex ( token ) )
  582. {
  583. hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 3 - hex_repetitions ) <<2 ) ) ;
  584. hex_repetitions ++ ;
  585. if ( hex_repetitions == 4 )
  586. {
  587. lexicon->value.guid.Data3 = ( USHORT ) hex_datum ;
  588. hex_repetitions = 0 ;
  589. hex_datum = 0 ;
  590. state = OID_START + 5 ;
  591. }
  592. }
  593. else
  594. {
  595. state = ACCEPT_STATE ;
  596. position = brace_position ;
  597. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  598. }
  599. }
  600. break ;
  601. case OID_START+5: // {xxxxxxxx-xxxx-xxxx-
  602. {
  603. if ( token == L'-' )
  604. {
  605. state = OID_START + 6 ;
  606. }
  607. else
  608. {
  609. state = ACCEPT_STATE ;
  610. position = brace_position ;
  611. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  612. }
  613. }
  614. break ;
  615. case OID_START+6: // {xxxxxxxx-xxxx-xxxx-xxxx
  616. {
  617. if ( IsHex ( token ) )
  618. {
  619. hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 1 - nybbleRepetitions ) << 2 ) ) ;
  620. hex_repetitions ++ ;
  621. nybbleRepetitions ++ ;
  622. if ( hex_repetitions == 2 )
  623. {
  624. lexicon->value.guid.Data4 [ 0 ] = ( char ) hex_datum ;
  625. hex_datum = 0 ;
  626. nybbleRepetitions = 0 ;
  627. }
  628. else if ( hex_repetitions == 4 )
  629. {
  630. lexicon->value.guid.Data4 [ 1 ] = ( char ) hex_datum ;
  631. hex_repetitions = 0 ;
  632. hex_datum = 0 ;
  633. nybbleRepetitions = 0 ;
  634. state = OID_START + 7 ;
  635. }
  636. }
  637. else
  638. {
  639. state = ACCEPT_STATE ;
  640. position = brace_position ;
  641. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  642. }
  643. }
  644. break ;
  645. case OID_START+7: // {xxxxxxxx-xxxx-xxxx-xxxx-
  646. {
  647. if ( token == L'-' )
  648. {
  649. state = OID_START + 8 ;
  650. }
  651. else
  652. {
  653. state = ACCEPT_STATE ;
  654. position = brace_position ;
  655. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  656. }
  657. }
  658. break ;
  659. case OID_START+8: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  660. {
  661. if ( IsHex ( token ) )
  662. {
  663. hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 1 - nybbleRepetitions ) << 2 ) ) ;
  664. hex_repetitions ++ ;
  665. nybbleRepetitions ++ ;
  666. if ( hex_repetitions == 12 )
  667. {
  668. lexicon->value.guid.Data4 [ 7 ] = ( char ) hex_datum ;
  669. hex_repetitions = 0 ;
  670. nybbleRepetitions = 0 ;
  671. hex_datum = 0 ;
  672. state = OID_START + 9 ;
  673. }
  674. else if ( hex_repetitions % 2 == 0 )
  675. {
  676. lexicon->value.guid.Data4 [ 1 + ( hex_repetitions >> 1 ) ] = ( char ) hex_datum ;
  677. hex_datum = 0 ;
  678. nybbleRepetitions = 0 ;
  679. }
  680. }
  681. else
  682. {
  683. state = ACCEPT_STATE ;
  684. position = brace_position ;
  685. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  686. }
  687. }
  688. break ;
  689. case OID_START+9: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
  690. {
  691. if ( token == L'}' )
  692. {
  693. lexicon->token = WbemLexicon :: OID_ID ;
  694. state = ACCEPT_STATE ;
  695. }
  696. else
  697. {
  698. state = ACCEPT_STATE ;
  699. position = brace_position ;
  700. lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
  701. }
  702. }
  703. break ;
  704. case ACCEPT_STATE:
  705. case REJECT_STATE:
  706. default:
  707. {
  708. state = REJECT_STATE ;
  709. } ;
  710. break ;
  711. }
  712. position ++ ;
  713. }
  714. status = ( state != REJECT_STATE ) ;
  715. return lexicon ;
  716. }