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.

813 lines
18 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ClassFac.cpp
  6. * Content: Parsing engine
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 02/04/2000 rmt Created
  12. * 02/17/2000 rmt Parameter validation work
  13. * 02/21/2000 rmt Updated to make core Unicode and remove ANSI calls
  14. * 03/21/2000 rmt Renamed all DirectPlayAddress8's to DirectPlay8Addresses
  15. * 07/21/2000 rmt Bug #39940 - Addressing library doesn't properly parse stopbits in URLs
  16. *@@END_MSINTERNAL
  17. *
  18. ***************************************************************************/
  19. #include "dnaddri.h"
  20. #undef DPF_MODNAME
  21. #define DPF_MODNAME "DP8ADDRESSPARSE::DP8ADDRESSPARSE"
  22. DP8ADDRESSPARSE::DP8ADDRESSPARSE(
  23. ): m_pwszCurrentLocation(NULL),
  24. m_pwszCurrentKey(NULL),
  25. m_pwszCurrentValue(NULL),
  26. m_pbUserData(NULL),
  27. m_dwUserDataSize(0),
  28. m_dp8State(DP8AP_IDLE),
  29. m_dwLenURL(0)
  30. {
  31. }
  32. #undef DPF_MODNAME
  33. #define DPF_MODNAME "DP8ADDRESSPARSE::~DP8ADDRESSPARSE"
  34. DP8ADDRESSPARSE::~DP8ADDRESSPARSE()
  35. {
  36. if( m_pwszCurrentKey != NULL )
  37. {
  38. DNFree(m_pwszCurrentKey);
  39. }
  40. if( m_pwszCurrentValue != NULL )
  41. {
  42. DNFree(m_pwszCurrentValue);
  43. }
  44. if ( m_pbUserData != NULL )
  45. {
  46. DNFree(m_pbUserData);
  47. }
  48. }
  49. #undef DPF_MODNAME
  50. #define DPF_MODNAME "DP8ADDRESSPARSE::ParseURL"
  51. HRESULT DP8ADDRESSPARSE::ParseURL( DP8ADDRESSOBJECT *dp8aObject, WCHAR *pstrURL )
  52. {
  53. HRESULT hr;
  54. if( m_pwszCurrentKey != NULL )
  55. {
  56. DNFree(m_pwszCurrentKey);
  57. m_pwszCurrentKey = NULL;
  58. }
  59. if( m_pwszCurrentValue != NULL )
  60. {
  61. DNFree(m_pwszCurrentValue);
  62. m_pwszCurrentValue = NULL;
  63. }
  64. if( m_pbUserData != NULL )
  65. {
  66. DNFree(m_pbUserData);
  67. m_pbUserData = NULL;
  68. }
  69. m_dwUserDataSize = 0;
  70. m_pwszCurrentLocation = pstrURL;
  71. m_dwLenURL = wcslen(pstrURL);
  72. if( m_dwLenURL < wcslen( DPNA_HEADER ) )
  73. {
  74. DPFX(DPFPREP, 0, "Invalid URL" );
  75. return DPNERR_INVALIDURL;
  76. }
  77. if( wcsncmp( pstrURL, DPNA_HEADER, wcslen(DPNA_HEADER) ) != 0 )
  78. {
  79. DPFX(DPFPREP, 0, "No header, invalid URL" );
  80. return DPNERR_INVALIDURL;
  81. }
  82. m_pwszCurrentLocation += wcslen( DPNA_HEADER );
  83. m_pwszCurrentKey = (WCHAR*) DNMalloc((m_dwLenURL+1)*sizeof(WCHAR));
  84. if( !m_pwszCurrentKey )
  85. {
  86. DPFX(DPFPREP, 0, "Error allocating memory" );
  87. return DPNERR_OUTOFMEMORY;
  88. }
  89. m_pwszCurrentValue = (WCHAR*) DNMalloc((m_dwLenURL+1)*sizeof(WCHAR));
  90. if( !m_pwszCurrentValue )
  91. {
  92. DNFree(m_pwszCurrentKey);
  93. m_pwszCurrentKey = NULL;
  94. DPFX(DPFPREP, 0, "Error allocating memory" );
  95. return DPNERR_OUTOFMEMORY;
  96. }
  97. m_pbUserData = (BYTE*) DNMalloc(m_dwLenURL+1);
  98. if( !m_pbUserData )
  99. {
  100. DNFree(m_pwszCurrentKey);
  101. DNFree(m_pwszCurrentValue);
  102. m_pwszCurrentKey = NULL;
  103. m_pwszCurrentValue = NULL;
  104. DPFX(DPFPREP, 0, "Error allocating memory" );
  105. return DPNERR_OUTOFMEMORY;
  106. }
  107. m_dp8State = DP8AP_IDLE;
  108. // Loop until the string is done
  109. while( *m_pwszCurrentLocation != L'\0' )
  110. {
  111. switch( m_dp8State )
  112. {
  113. case DP8AP_IDLE:
  114. if( *m_pwszCurrentLocation == DPNA_SEPARATOR_USERDATA )
  115. {
  116. m_dp8State = DP8AP_USERDATA;
  117. m_pwszCurrentLocation++;
  118. }
  119. else
  120. {
  121. m_dp8State = DP8AP_KEY;
  122. }
  123. break;
  124. case DP8AP_KEY:
  125. if( *m_pwszCurrentLocation == DPNA_SEPARATOR_USERDATA )
  126. {
  127. m_dp8State = DP8AP_USERDATA;
  128. m_pwszCurrentLocation++;
  129. break;
  130. }
  131. hr = FSM_Key();
  132. if( FAILED( hr ) )
  133. {
  134. DPFX(DPFPREP, 0, "Error parsing key hr = 0x%x", hr );
  135. return hr;
  136. }
  137. // Parse ended with an equals
  138. if( *m_pwszCurrentLocation == DPNA_SEPARATOR_KEYVALUE )
  139. {
  140. m_dp8State = DP8AP_VALUE;
  141. m_pwszCurrentLocation++;
  142. }
  143. else
  144. {
  145. DPFX(DPFPREP, 0, "keyname without associated value hr=0x%x", hr );
  146. return DPNERR_INVALIDURL;
  147. }
  148. break;
  149. case DP8AP_VALUE:
  150. hr = FSM_Value();
  151. if( FAILED( hr ) )
  152. {
  153. DPFX(DPFPREP, 0, "Error parsing value hr=0x%x", hr );
  154. return hr;
  155. }
  156. // Parse ended with an equals
  157. if( *m_pwszCurrentLocation == DPNA_SEPARATOR_COMPONENT )
  158. {
  159. m_dp8State = DP8AP_KEY;
  160. m_pwszCurrentLocation++;
  161. }
  162. else if( *m_pwszCurrentLocation == DPNA_SEPARATOR_USERDATA )
  163. {
  164. m_dp8State = DP8AP_USERDATA;
  165. m_pwszCurrentLocation++;
  166. }
  167. else if( *m_pwszCurrentLocation == L'\0' )
  168. {
  169. m_dp8State = DP8AP_IDLE;
  170. }
  171. else
  172. {
  173. DPFX(DPFPREP, 0, "Error parsing next key" );
  174. hr = DPNERR_INVALIDURL;
  175. return hr;
  176. }
  177. hr = FSM_CommitEntry(dp8aObject);
  178. if( hr == DPNERR_INVALIDPARAM )
  179. {
  180. DPFX(DPFPREP, 0, "Invalid value specified in URL hr=0x%x", hr );
  181. hr = DPNERR_INVALIDURL;
  182. return hr;
  183. }
  184. else if( FAILED( hr ) )
  185. {
  186. DPFX(DPFPREP, 0, "Error commiting entry hr=0x%x", hr );
  187. return hr;
  188. }
  189. break;
  190. case DP8AP_USERDATA:
  191. hr = FSM_UserData();
  192. if( FAILED( hr ) )
  193. {
  194. DPFX(DPFPREP, 0, "Error parsing user data hr=0x%x", hr );
  195. return hr;
  196. }
  197. hr = dp8aObject->SetUserData( m_pbUserData, m_dwUserDataSize );
  198. if( FAILED( hr ) )
  199. {
  200. DPFX(DPFPREP, 0, "Error setting user data hr=0x%x", hr );
  201. return hr;
  202. }
  203. break;
  204. }
  205. }
  206. if( m_dp8State != DP8AP_IDLE &&
  207. m_dp8State != DP8AP_USERDATA )
  208. {
  209. DPFX(DPFPREP, 0, "Parsing error hr=0x%x", hr );
  210. hr = DPNERR_INVALIDURL;
  211. return hr;
  212. }
  213. return DPN_OK;
  214. }
  215. #undef DPF_MODNAME
  216. #define DPF_MODNAME "DP8ADDRESSPARSE::IsValidKeyChar"
  217. BOOL DP8ADDRESSPARSE::IsValidKeyChar( WCHAR ch )
  218. {
  219. if( ch >= L'A' && ch <= L'Z' )
  220. return TRUE;
  221. if( ch >= L'a' && ch <= L'z' )
  222. return TRUE;
  223. if( ch >= L'0' && ch <= L'9' )
  224. return TRUE;
  225. if( ch == L'-' || ch == L'?' || ch == L'.' ||
  226. ch == L',' || ch == L'+' || ch == L'_' )
  227. return TRUE;
  228. return FALSE;
  229. }
  230. #undef DPF_MODNAME
  231. #define DPF_MODNAME "DP8ADDRESSPARSE::IsValidKeyTerminator"
  232. BOOL DP8ADDRESSPARSE::IsValidKeyTerminator( WCHAR ch )
  233. {
  234. if( ch == 0 )
  235. return TRUE;
  236. if( ch == DPNA_SEPARATOR_USERDATA )
  237. return TRUE;
  238. if( ch == DPNA_SEPARATOR_COMPONENT )
  239. return TRUE;
  240. if( ch == DPNA_SEPARATOR_KEYVALUE )
  241. return TRUE;
  242. return FALSE;
  243. }
  244. #undef DPF_MODNAME
  245. #define DPF_MODNAME "DP8ADDRESSPARSE::FSM_Key"
  246. // FSM_Key
  247. //
  248. // Parse a keyname, or return an error on error
  249. //
  250. HRESULT DP8ADDRESSPARSE::FSM_Key()
  251. {
  252. DWORD dwKeyLoc = 0;
  253. m_pwszCurrentKey[0] = 0;
  254. HRESULT hr = DPN_OK;
  255. while( 1 )
  256. {
  257. if( IsValidKeyChar(*m_pwszCurrentLocation) )
  258. {
  259. m_pwszCurrentKey[dwKeyLoc] = *m_pwszCurrentLocation;
  260. }
  261. else if( IsValidKeyTerminator(*m_pwszCurrentLocation) )
  262. {
  263. m_pwszCurrentKey[dwKeyLoc] = 0;
  264. break;
  265. }
  266. else
  267. {
  268. m_pwszCurrentKey[dwKeyLoc] = 0;
  269. hr = DPNERR_INVALIDURL;
  270. break;
  271. }
  272. dwKeyLoc++;
  273. m_pwszCurrentLocation++;
  274. }
  275. return hr;
  276. }
  277. #undef DPF_MODNAME
  278. #define DPF_MODNAME "DP8ADDRESSPARSE::IsValidNumber"
  279. BOOL DP8ADDRESSPARSE::IsValidNumber( WCHAR ch )
  280. {
  281. if( ch < L'0' ||
  282. ch > L'9' )
  283. {
  284. return FALSE;
  285. }
  286. else
  287. {
  288. return TRUE;
  289. }
  290. }
  291. #undef DPF_MODNAME
  292. #define DPF_MODNAME "DP8ADDRESSPARSE::IsValidHex"
  293. BOOL DP8ADDRESSPARSE::IsValidHex( WCHAR ch )
  294. {
  295. if( IsValidNumber( ch ) )
  296. return TRUE;
  297. if( ch >= L'A' || ch <= L'F' )
  298. return TRUE;
  299. if( ch >= L'a' || ch <= L'f' )
  300. return TRUE;
  301. return FALSE;
  302. }
  303. #undef DPF_MODNAME
  304. #define DPF_MODNAME "DP8ADDRESSPARSE::HexToChar"
  305. WCHAR DP8ADDRESSPARSE::HexToChar( const WCHAR *sz )
  306. {
  307. WCHAR chResult = sz[0];
  308. // First digit
  309. if( sz[0] >= L'0' && sz[0] <= L'9' )
  310. chResult = sz[0]-L'0';
  311. if( sz[0] >= L'A' && sz[0] <= L'F' )
  312. chResult = sz[0]-L'A'+10;
  313. if( sz[0] >= L'a' && sz[0] <= L'f' )
  314. chResult = sz[0]-L'a'+10;
  315. chResult <<= 4;
  316. // Second digit
  317. if( sz[1] >= L'0' && sz[1] <= L'9' )
  318. chResult += sz[1]-'0';
  319. if( sz[1] >= L'A' && sz[1] <= L'F' )
  320. chResult += sz[1]-L'A'+10;
  321. if( sz[1] >= L'a' && sz[1] <= L'f' )
  322. chResult += sz[1]-L'a'+10;
  323. return chResult;
  324. }
  325. #undef DPF_MODNAME
  326. #define DPF_MODNAME "DP8ADDRESSPARSE::FSM_Value"
  327. HRESULT DP8ADDRESSPARSE::FSM_Value()
  328. {
  329. m_fNonNumeric = FALSE;
  330. m_pwszCurrentValue[0] = 0;
  331. HRESULT hr = DPN_OK;
  332. m_dwValueLen = 0;
  333. while( 1 )
  334. {
  335. // Just add it
  336. if( IsValidKeyChar( *m_pwszCurrentLocation ) )
  337. {
  338. m_pwszCurrentValue[m_dwValueLen] = *m_pwszCurrentLocation;
  339. if( !IsValidNumber( *m_pwszCurrentLocation ) )
  340. {
  341. m_fNonNumeric = TRUE;
  342. }
  343. }
  344. // ESCAPE SEQUENCE
  345. else if( *m_pwszCurrentLocation == DPNA_ESCAPECHAR )
  346. {
  347. m_fNonNumeric = TRUE;
  348. if( *(m_pwszCurrentLocation+1) == DPNA_ESCAPECHAR )
  349. {
  350. m_pwszCurrentValue[m_dwValueLen] = DPNA_ESCAPECHAR;
  351. m_pwszCurrentLocation += 2;
  352. }
  353. if( wcslen( m_pwszCurrentLocation ) < 3 )
  354. {
  355. DPFX(DPFPREP, 0, "Unexpected end in escape sequence" );
  356. hr = DPNERR_INVALIDURL;
  357. break;
  358. }
  359. if( !IsValidHex( *(m_pwszCurrentLocation+1) ) ||
  360. !IsValidHex( *(m_pwszCurrentLocation+2) ) )
  361. {
  362. DPFX(DPFPREP, 0, "Invalid escape sequence" );
  363. hr = DPNERR_INVALIDURL;
  364. break;
  365. }
  366. m_pwszCurrentLocation ++;
  367. m_pwszCurrentValue[m_dwValueLen] = HexToChar(m_pwszCurrentLocation);
  368. m_pwszCurrentLocation ++;
  369. }
  370. else if( IsValidKeyTerminator(*m_pwszCurrentLocation) )
  371. {
  372. m_pwszCurrentValue[m_dwValueLen] = 0;
  373. break;
  374. }
  375. else
  376. {
  377. m_pwszCurrentValue[m_dwValueLen] = 0;
  378. DPFX(DPFPREP, 0, "Unexpected character in URL" );
  379. hr = DPNERR_INVALIDURL;
  380. break;
  381. }
  382. m_dwValueLen++;
  383. m_pwszCurrentLocation++;
  384. }
  385. if( m_dwValueLen < 1 )
  386. {
  387. DPFX(DPFPREP, DP8A_ERRORLEVEL, "0 length value" );
  388. return DPNERR_INVALIDURL;
  389. }
  390. return hr;
  391. }
  392. #undef DPF_MODNAME
  393. #define DPF_MODNAME "DP8ADDRESSPARSE::FSM_UserData"
  394. HRESULT DP8ADDRESSPARSE::FSM_UserData()
  395. {
  396. m_pwszCurrentValue[0] = 0;
  397. HRESULT hr = DPN_OK;
  398. DWORD dwValueLoc = 0;
  399. while( 1 )
  400. {
  401. // Just add it
  402. if( IsValidKeyChar( *m_pwszCurrentLocation ) )
  403. {
  404. m_pbUserData[dwValueLoc] = (CHAR) *m_pwszCurrentLocation;
  405. }
  406. // ESCAPE SEQUENCE
  407. else if( *m_pwszCurrentLocation == DPNA_ESCAPECHAR )
  408. {
  409. if( *(m_pwszCurrentLocation+1) == DPNA_ESCAPECHAR )
  410. {
  411. m_pbUserData[dwValueLoc] = DPNA_ESCAPECHAR;
  412. m_pwszCurrentLocation += 2;
  413. }
  414. if( wcslen( m_pwszCurrentLocation ) < 3 )
  415. {
  416. DPFX(DPFPREP, 0, "Unexpected end in escape sequence" );
  417. hr = DPNERR_INVALIDURL;
  418. break;
  419. }
  420. if( !IsValidHex( *(m_pwszCurrentLocation+1) ) ||
  421. !IsValidHex( *(m_pwszCurrentLocation+2) ) )
  422. {
  423. DPFX(DPFPREP, 0, "Invalid escape sequence" );
  424. hr = DPNERR_INVALIDURL;
  425. break;
  426. }
  427. m_pwszCurrentLocation ++;
  428. m_pbUserData[dwValueLoc] = (CHAR) HexToChar(m_pwszCurrentLocation);
  429. m_pwszCurrentLocation ++;
  430. }
  431. else if( IsValidKeyTerminator(*m_pwszCurrentLocation) )
  432. {
  433. m_pwszCurrentValue[dwValueLoc] = 0;
  434. break;
  435. }
  436. else
  437. {
  438. m_pwszCurrentValue[dwValueLoc] = 0;
  439. hr = DPNERR_INVALIDURL;
  440. break;
  441. }
  442. dwValueLoc++;
  443. m_pwszCurrentLocation++;
  444. }
  445. m_dwUserDataSize = dwValueLoc;
  446. return hr;
  447. }
  448. #undef DPF_MODNAME
  449. #define DPF_MODNAME "DP8ADDRESSPARSE::FSM_CommitEntry"
  450. HRESULT DP8ADDRESSPARSE::FSM_CommitEntry(DP8ADDRESSOBJECT *pdp8aObject)
  451. {
  452. DWORD dwDataType = 0xFFFFFFFF;
  453. // Ensure that datatype is correct in case the key is a reserved key
  454. for( DWORD dwIndex = 0; dwIndex < c_dwNumBaseStrings; dwIndex++ )
  455. {
  456. if( _wcsicmp( g_szBaseStrings[dwIndex], m_pwszCurrentKey ) == 0 )
  457. {
  458. dwDataType = g_dwBaseRequiredTypes[dwIndex] ;
  459. break;
  460. }
  461. }
  462. // If it's numeric
  463. if( (dwDataType == DPNA_DATATYPE_DWORD || dwDataType == 0xFFFFFFFF) && !m_fNonNumeric && wcslen(m_pwszCurrentValue)<=10)
  464. {
  465. DWORD dwTmpValue;
  466. dwTmpValue = wcstoul( m_pwszCurrentValue, NULL, 10 );
  467. return pdp8aObject->SetElement( m_pwszCurrentKey, &dwTmpValue, sizeof(DWORD), DPNA_DATATYPE_DWORD );
  468. }
  469. // We've read a GUID
  470. if (dwDataType == DPNA_DATATYPE_GUID || dwDataType == 0xFFFFFFFF)
  471. {
  472. // L"{%8X-%4X-%4X-%2X%2X-%2X%2X%2X%2X%2X%2X}"
  473. typedef enum
  474. {
  475. OpenBrace,
  476. HexDWord1,
  477. HexWord1,
  478. HexWord2,
  479. DoubleHexBytes,
  480. HexBytes,
  481. CloseBrace,
  482. Invalid,
  483. } GUID_PARSE_STATE;
  484. GUID guidValue;
  485. GUID_PARSE_STATE GuidParseState;
  486. BOOL fStateChange;
  487. ULARGE_INTEGER uliValue;
  488. WCHAR * pwcStateStart;
  489. WCHAR * pwcCurrent;
  490. DWORD_PTR dwLength;
  491. GuidParseState = OpenBrace;
  492. fStateChange = FALSE;
  493. uliValue.QuadPart = 0;
  494. pwcCurrent = m_pwszCurrentValue;
  495. pwcStateStart = pwcCurrent;
  496. //
  497. // Loop until we run out of string.
  498. //
  499. while ((*pwcCurrent) != 0)
  500. {
  501. switch (*pwcCurrent)
  502. {
  503. case L'0':
  504. case L'1':
  505. case L'2':
  506. case L'3':
  507. case L'4':
  508. case L'5':
  509. case L'6':
  510. case L'7':
  511. case L'8':
  512. case L'9':
  513. {
  514. uliValue.QuadPart = uliValue.QuadPart * 16 + ((*pwcCurrent) - L'0');
  515. break;
  516. }
  517. case L'a':
  518. case L'b':
  519. case L'c':
  520. case L'd':
  521. case L'e':
  522. case L'f':
  523. {
  524. uliValue.QuadPart = uliValue.QuadPart * 16 + ((*pwcCurrent) - L'a' + 10);
  525. break;
  526. }
  527. case L'A':
  528. case L'B':
  529. case L'C':
  530. case L'D':
  531. case L'E':
  532. case L'F':
  533. {
  534. uliValue.QuadPart = uliValue.QuadPart * 16 + ((*pwcCurrent) - L'A' + 10);
  535. break;
  536. }
  537. case L'{':
  538. case L'}':
  539. case L'-':
  540. {
  541. dwLength = ((DWORD_PTR) pwcCurrent) - ((DWORD_PTR) pwcStateStart);
  542. switch (GuidParseState)
  543. {
  544. case OpenBrace:
  545. {
  546. if (((*pwcCurrent) == L'{') &&
  547. (dwLength == 0))
  548. {
  549. fStateChange = TRUE;
  550. }
  551. else
  552. {
  553. GuidParseState = Invalid;
  554. }
  555. break;
  556. }
  557. case HexDWord1:
  558. {
  559. if (((*pwcCurrent) == L'-') &&
  560. (dwLength <= (sizeof(DWORD) * 2 * sizeof(WCHAR))))
  561. {
  562. guidValue.Data1 = uliValue.LowPart;
  563. fStateChange = TRUE;
  564. }
  565. else
  566. {
  567. GuidParseState = Invalid;
  568. }
  569. break;
  570. }
  571. case HexWord1:
  572. {
  573. if (((*pwcCurrent) == L'-') &&
  574. (dwLength <= (sizeof(WORD) * 2 * sizeof(WCHAR))))
  575. {
  576. guidValue.Data2 = (WORD) uliValue.LowPart;
  577. fStateChange = TRUE;
  578. }
  579. else
  580. {
  581. GuidParseState = Invalid;
  582. }
  583. break;
  584. }
  585. case HexWord2:
  586. {
  587. if (((*pwcCurrent) == L'-') &&
  588. (dwLength <= (sizeof(WORD) * 2 * sizeof(WCHAR))))
  589. {
  590. guidValue.Data3 = (WORD) uliValue.LowPart;
  591. fStateChange = TRUE;
  592. }
  593. else
  594. {
  595. GuidParseState = Invalid;
  596. }
  597. break;
  598. }
  599. case DoubleHexBytes:
  600. {
  601. if (((*pwcCurrent) == L'-') &&
  602. (dwLength == (2 * 2 * sizeof(WCHAR))))
  603. {
  604. guidValue.Data4[0] = (BYTE) ((uliValue.LowPart & 0x0000FF00) >> 8);
  605. guidValue.Data4[1] = (BYTE) (uliValue.LowPart & 0x000000FF);
  606. fStateChange = TRUE;
  607. }
  608. else
  609. {
  610. GuidParseState = Invalid;
  611. }
  612. break;
  613. }
  614. case HexBytes:
  615. {
  616. if (((*pwcCurrent) == L'}') &&
  617. (dwLength == (6 * 2 * sizeof(WCHAR))))
  618. {
  619. guidValue.Data4[2] = (BYTE) ((uliValue.HighPart & 0x0000FF00) >> 8);
  620. guidValue.Data4[3] = (BYTE) (uliValue.HighPart & 0x000000FF);
  621. guidValue.Data4[4] = (BYTE) ((uliValue.LowPart & 0xFF000000) >> 24);
  622. guidValue.Data4[5] = (BYTE) ((uliValue.LowPart & 0x00FF0000) >> 16);
  623. guidValue.Data4[6] = (BYTE) ((uliValue.LowPart & 0x0000FF00) >> 8);
  624. guidValue.Data4[7] = (BYTE) (uliValue.LowPart & 0x000000FF);
  625. fStateChange = TRUE;
  626. }
  627. else
  628. {
  629. GuidParseState = Invalid;
  630. }
  631. break;
  632. }
  633. default:
  634. {
  635. GuidParseState = Invalid;
  636. break;
  637. }
  638. } // end switch (on parse state)
  639. //
  640. // Move to next parse state (unless the string is bogus).
  641. //
  642. if (fStateChange)
  643. {
  644. fStateChange = FALSE;
  645. uliValue.QuadPart = 0;
  646. pwcStateStart = pwcCurrent + 1;
  647. (*((int*) (&GuidParseState)))++;
  648. }
  649. break;
  650. }
  651. default:
  652. {
  653. GuidParseState = Invalid;
  654. break;
  655. }
  656. } // end switch (on current character)
  657. if (GuidParseState == Invalid)
  658. {
  659. break;
  660. }
  661. pwcCurrent++;
  662. if ((pwcCurrent - m_pwszCurrentValue) > 38 * sizeof(WCHAR))
  663. {
  664. break;
  665. }
  666. } // end while (not at end of string)
  667. //
  668. // If we hit the end of the string when parsing the last element,
  669. // we've succeeded. Commit the GUID.
  670. //
  671. if (GuidParseState == CloseBrace)
  672. {
  673. return pdp8aObject->SetElement( m_pwszCurrentKey, &guidValue, sizeof(GUID), DPNA_DATATYPE_GUID );
  674. }
  675. }
  676. // If there are no NULLs it's probably a string
  677. if( (
  678. (dwDataType == DPNA_DATATYPE_STRING)
  679. || (dwDataType == 0xFFFFFFFF)
  680. #ifndef DPNBUILD_ONLYONESP
  681. || (wcscmp(DPNA_KEY_PROVIDER,m_pwszCurrentKey)==0)
  682. #endif // ! DPNBUILD_ONLYONESP
  683. ) &&
  684. wcslen( m_pwszCurrentValue ) == m_dwValueLen )
  685. {
  686. // Otherwise it's a string
  687. return pdp8aObject->SetElement( m_pwszCurrentKey, m_pwszCurrentValue, (wcslen(m_pwszCurrentValue)+1)*sizeof(WCHAR), DPNA_DATATYPE_STRING );
  688. }
  689. // Otherwise it's a binary (although the bytes were extended into WORDs/WCHARs.
  690. return pdp8aObject->SetElement( m_pwszCurrentKey, m_pwszCurrentValue, (m_dwValueLen * sizeof(WCHAR)), DPNA_DATATYPE_BINARY );
  691. }