Source code of Windows XP (NT5)
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.

830 lines
17 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: parse.cxx
  7. //
  8. // Contents: Windows NT 3.5 GetObject functionality
  9. //
  10. // History:
  11. //----------------------------------------------------------------------------
  12. #include "nwcompat.hxx"
  13. #pragma hdrstop
  14. KWDLIST KeywordList[MAX_KEYWORDS] =
  15. {
  16. { TOKEN_DOMAIN, L"domain"},
  17. { TOKEN_USER, L"user"},
  18. { TOKEN_GROUP, L"group"},
  19. { TOKEN_COMPUTER, L"computer"},
  20. { TOKEN_PRINTER, L"printqueue"},
  21. { TOKEN_SERVICE, L"service"},
  22. { TOKEN_FILESERVICE, L"fileservice"},
  23. { TOKEN_FILESHARE, L"fileshare"},
  24. { TOKEN_NAMESPACE, L"namespace"},
  25. { TOKEN_SCHEMA, L"schema"},
  26. { TOKEN_CLASS, L"class"},
  27. { TOKEN_PROPERTY, L"property"},
  28. { TOKEN_SYNTAX, L"syntax" }
  29. };
  30. WCHAR * szProviderName = L"NWCOMPAT";
  31. // Object -> PathName, Type, eos
  32. // Object -> PathName, eos
  33. //+---------------------------------------------------------------------------
  34. // Function:
  35. //
  36. // Synopsis:
  37. //
  38. // Arguments:
  39. //
  40. // Returns:
  41. //
  42. // Modifies:
  43. //
  44. // History: 11-3-95 krishnag Created.
  45. //
  46. //----------------------------------------------------------------------------
  47. HRESULT
  48. Object(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  49. {
  50. WCHAR szToken[MAX_TOKEN_LENGTH];
  51. DWORD dwToken;
  52. HRESULT hr;
  53. hr = ProviderName(pTokenizer, pObjectInfo);
  54. BAIL_IF_ERROR(hr);
  55. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  56. BAIL_IF_ERROR(hr);
  57. switch (dwToken) {
  58. case TOKEN_END:
  59. RRETURN(S_OK);
  60. case TOKEN_COMMA:
  61. hr = Type(pTokenizer, pObjectInfo);
  62. BAIL_IF_ERROR(hr);
  63. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  64. BAIL_IF_ERROR(hr);
  65. if (dwToken == TOKEN_END) {
  66. RRETURN(S_OK);
  67. }else {
  68. RRETURN(E_ADS_BAD_PATHNAME);
  69. }
  70. default:
  71. hr = pTokenizer->PushBackToken();
  72. hr = DsPathName(pTokenizer, pObjectInfo);
  73. BAIL_IF_ERROR(hr);
  74. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  75. BAIL_IF_ERROR(hr);
  76. switch (dwToken) {
  77. case TOKEN_END:
  78. RRETURN(S_OK);
  79. case TOKEN_COMMA:
  80. hr = Type(pTokenizer, pObjectInfo);
  81. BAIL_IF_ERROR(hr);
  82. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  83. BAIL_IF_ERROR(hr);
  84. if (dwToken == TOKEN_END) {
  85. RRETURN(S_OK);
  86. }else {
  87. RRETURN(E_ADS_BAD_PATHNAME);
  88. }
  89. default:
  90. RRETURN(E_FAIL);
  91. }
  92. }
  93. cleanup:
  94. RRETURN(hr);
  95. }
  96. HRESULT
  97. ProviderName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  98. {
  99. WCHAR szToken[MAX_TOKEN_LENGTH];
  100. DWORD dwToken;
  101. HRESULT hr;
  102. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  103. BAIL_IF_ERROR(hr);
  104. if (dwToken == TOKEN_ATSIGN) {
  105. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  106. BAIL_IF_ERROR(hr);
  107. if (dwToken != TOKEN_IDENTIFIER) {
  108. RRETURN(E_ADS_BAD_PATHNAME);
  109. }
  110. hr = AddProviderName(pObjectInfo, szToken);
  111. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  112. BAIL_IF_ERROR(hr);
  113. if (dwToken != TOKEN_EXCLAMATION) {
  114. RRETURN(E_ADS_BAD_PATHNAME);
  115. }
  116. }else if (dwToken == TOKEN_IDENTIFIER) {
  117. hr = AddProviderName(pObjectInfo, szToken);
  118. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  119. BAIL_IF_ERROR(hr);
  120. if (dwToken != TOKEN_COLON) {
  121. RRETURN(E_ADS_BAD_PATHNAME);
  122. }
  123. }else {
  124. RRETURN(E_ADS_BAD_PATHNAME);
  125. }
  126. //
  127. // You can now disable the processing for "@" and "!" treat them
  128. // as ordinary characters.
  129. //
  130. pTokenizer->SetAtDisabler(TRUE);
  131. RRETURN(S_OK);
  132. cleanup:
  133. RRETURN(hr);
  134. }
  135. // PathName -> Component \\ PathName
  136. // PathName -> Component
  137. HRESULT
  138. DsPathName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  139. {
  140. WCHAR szToken[MAX_TOKEN_LENGTH];
  141. DWORD dwToken;
  142. HRESULT hr;
  143. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  144. BAIL_IF_ERROR(hr);
  145. if (dwToken != TOKEN_FSLASH) {
  146. RRETURN(E_ADS_BAD_PATHNAME);
  147. }
  148. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  149. BAIL_IF_ERROR(hr);
  150. if (dwToken != TOKEN_FSLASH) {
  151. RRETURN(E_ADS_BAD_PATHNAME);
  152. }
  153. hr = PathName(pTokenizer, pObjectInfo);
  154. BAIL_IF_ERROR(hr);
  155. RRETURN(S_OK);
  156. cleanup:
  157. RRETURN(hr);
  158. }
  159. //+---------------------------------------------------------------------------
  160. // Function:
  161. //
  162. // Synopsis:
  163. //
  164. // Arguments:
  165. //
  166. // Returns:
  167. //
  168. // Modifies:
  169. //
  170. // History: 11-3-95 krishnag Created.
  171. //
  172. //----------------------------------------------------------------------------
  173. HRESULT
  174. PathName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  175. {
  176. HRESULT hr;
  177. WCHAR szToken[MAX_TOKEN_LENGTH];
  178. DWORD dwToken;
  179. hr = Component(pTokenizer, pObjectInfo);
  180. BAIL_IF_ERROR(hr);
  181. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  182. if (dwToken == TOKEN_FSLASH) {
  183. RRETURN (PathName(pTokenizer, pObjectInfo));
  184. }else {
  185. hr = pTokenizer->PushBackToken();
  186. RRETURN (S_OK);
  187. }
  188. cleanup:
  189. RRETURN(hr);
  190. }
  191. // Component -> <identifier>
  192. //+---------------------------------------------------------------------------
  193. // Function:
  194. //
  195. // Synopsis:
  196. //
  197. // Arguments:
  198. //
  199. // Returns:
  200. //
  201. // Modifies:
  202. //
  203. // History: 11-3-95 krishnag Created.
  204. //
  205. //----------------------------------------------------------------------------
  206. HRESULT
  207. Component(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  208. {
  209. WCHAR szToken[MAX_TOKEN_LENGTH];
  210. WCHAR szDisplayToken[MAX_TOKEN_LENGTH];
  211. DWORD dwToken;
  212. HRESULT hr;
  213. hr = pTokenizer->GetNextToken(szToken, szDisplayToken, &dwToken);
  214. BAIL_IF_ERROR(hr);
  215. if (dwToken != TOKEN_IDENTIFIER) {
  216. RRETURN(E_ADS_BAD_PATHNAME);
  217. }
  218. hr = AddComponent(pObjectInfo, szToken, szDisplayToken);
  219. BAIL_IF_ERROR(hr);
  220. RRETURN(S_OK);
  221. cleanup:
  222. RRETURN(hr);
  223. }
  224. // Type -> "user", "group","printer","service"
  225. //+---------------------------------------------------------------------------
  226. // Function: Type
  227. //
  228. // Synopsis: Parses Type-> "user" | "group" etc
  229. //
  230. // Arguments: [CLexer * pTokenizer]
  231. // [POBJECTINFo pObjectInfo]
  232. //
  233. // Returns: HRESULT
  234. //
  235. // Modifies: -
  236. //
  237. // History: 11-3-95 krishnag Created.
  238. //
  239. //----------------------------------------------------------------------------
  240. HRESULT
  241. Type(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  242. {
  243. WCHAR szToken[MAX_PATH];
  244. DWORD dwToken;
  245. HRESULT hr;
  246. hr = pTokenizer->GetNextToken(szToken, &dwToken);
  247. BAIL_IF_ERROR(hr);
  248. if (dwToken == TOKEN_IDENTIFIER ) {
  249. if (pTokenizer->IsKeyword(szToken, &dwToken)) {
  250. hr = SetType(pObjectInfo, dwToken);
  251. RRETURN(hr);
  252. }
  253. }
  254. RRETURN(E_FAIL);
  255. cleanup:
  256. RRETURN(hr);
  257. }
  258. //+---------------------------------------------------------------------------
  259. // Function:
  260. //
  261. // Synopsis:
  262. //
  263. // Arguments:
  264. //
  265. // Returns:
  266. //
  267. // Modifies:
  268. //
  269. // History: 11-3-95 krishnag Created.
  270. //
  271. //----------------------------------------------------------------------------
  272. CLexer::CLexer(LPWSTR szBuffer):
  273. _ptr(NULL),
  274. _Buffer(NULL),
  275. _dwLastTokenLength(0),
  276. _dwLastToken(0),
  277. _dwEndofString(0),
  278. _bAtDisabled(FALSE)
  279. {
  280. if (!szBuffer || !*szBuffer) {
  281. return;
  282. }
  283. _Buffer = AllocADsStr(szBuffer);
  284. _ptr = _Buffer;
  285. }
  286. //+---------------------------------------------------------------------------
  287. // Function:
  288. //
  289. // Synopsis:
  290. //
  291. // Arguments:
  292. //
  293. // Returns:
  294. //
  295. // Modifies:
  296. //
  297. // History: 08-12-96 t-danal Created.
  298. //
  299. //----------------------------------------------------------------------------
  300. CLexer::~CLexer()
  301. {
  302. FreeADsStr(_Buffer);
  303. }
  304. //+---------------------------------------------------------------------------
  305. // Function:
  306. //
  307. // Synopsis:
  308. //
  309. // Arguments:
  310. //
  311. // Returns:
  312. //
  313. // Modifies:
  314. //
  315. // History: 11-3-95 krishnag Created.
  316. //
  317. //----------------------------------------------------------------------------
  318. HRESULT
  319. CLexer::GetNextToken(LPWSTR szToken, LPWSTR szDisplayToken, LPDWORD pdwToken)
  320. {
  321. WCHAR c;
  322. DWORD state = 0;
  323. LPWSTR pch = szToken;
  324. LPWSTR pDisplayCh = szDisplayToken;
  325. BOOL fEscapeOn = FALSE, fQuotingOn = FALSE;
  326. memset(szToken, 0, sizeof(WCHAR) * MAX_TOKEN_LENGTH);
  327. if (szDisplayToken) {
  328. memset(szDisplayToken, 0, sizeof(TCHAR) * MAX_TOKEN_LENGTH);
  329. }
  330. _dwLastTokenLength = 0;
  331. while (1) {
  332. c = NextChar();
  333. switch (state) {
  334. case 0:
  335. *pch++ = c;
  336. _dwLastTokenLength++;
  337. if (c == TEXT('"')) {
  338. //
  339. // Quoting;
  340. //
  341. fQuotingOn = TRUE;
  342. pch--;
  343. state = 1;
  344. }else if (c == TEXT('\\')) {
  345. //
  346. // Escaping; Ignore the '\' in the token and check to make
  347. // sure that the next character exists
  348. //
  349. pch--;
  350. fEscapeOn = TRUE;
  351. state = 1;
  352. }else if (c == L'/') {
  353. *pdwToken = TOKEN_FSLASH;
  354. _dwLastToken = *pdwToken;
  355. RRETURN(S_OK);
  356. }else if (c == L',') {
  357. *pdwToken = TOKEN_COMMA;
  358. _dwLastToken = *pdwToken;
  359. RRETURN(S_OK);
  360. }else if (c == L':'){
  361. if (!_bAtDisabled) {
  362. *pdwToken = TOKEN_COLON;
  363. _dwLastToken = *pdwToken;
  364. RRETURN(S_OK);
  365. }else {
  366. state = 1;
  367. }
  368. }else if (c == TEXT('<')) {
  369. RRETURN(E_FAIL);
  370. }else if (c == TEXT('>')) {
  371. RRETURN(E_FAIL);
  372. }else if (c == L'\0'){
  373. *pdwToken = TOKEN_END;
  374. _dwLastToken = *pdwToken;
  375. RRETURN(S_OK);
  376. }else if (c == L'@') {
  377. if (!_bAtDisabled) {
  378. *pdwToken = TOKEN_ATSIGN;
  379. _dwLastToken = *pdwToken;
  380. RRETURN(S_OK);
  381. }else {
  382. state = 1;
  383. }
  384. }else if (c == L'!'){
  385. if (!_bAtDisabled) {
  386. *pdwToken = TOKEN_EXCLAMATION;
  387. _dwLastToken = *pdwToken;
  388. RRETURN(S_OK);
  389. }else {
  390. state = 1;
  391. }
  392. }else {
  393. state = 1;
  394. }
  395. break;
  396. case 1:
  397. if ((fEscapeOn || fQuotingOn) && c == TEXT('\0') ) {
  398. RRETURN(E_FAIL);
  399. }
  400. else if (fEscapeOn) {
  401. fEscapeOn = FALSE;
  402. *pch++ = c;
  403. _dwLastTokenLength++;
  404. state = 1;
  405. break;
  406. }
  407. else if (fQuotingOn) {
  408. if (c == TEXT('"')) {
  409. fQuotingOn = FALSE;
  410. }
  411. *pch++ = c;
  412. _dwLastTokenLength++;
  413. break;
  414. }
  415. else if (c == TEXT('\\') ) {
  416. fEscapeOn = TRUE;
  417. _dwLastTokenLength++;
  418. break;
  419. }
  420. else if (c == TEXT('"')) {
  421. fQuotingOn = TRUE;
  422. _dwLastTokenLength++;
  423. break;
  424. }
  425. if (c == L'\0' || c == L',' || c == L'/') {
  426. PushbackChar();
  427. *pdwToken = TOKEN_IDENTIFIER;
  428. _dwLastToken = *pdwToken;
  429. RRETURN (S_OK);
  430. }else if (c == L'@' || c == L'!' || c == L':') {
  431. if (!_bAtDisabled) {
  432. PushbackChar();
  433. *pdwToken = TOKEN_IDENTIFIER;
  434. _dwLastToken = *pdwToken;
  435. RRETURN(S_OK);
  436. }else {
  437. *pch++ = c;
  438. _dwLastTokenLength++;
  439. state = 1;
  440. break;
  441. }
  442. }else {
  443. *pch++ = c;
  444. _dwLastTokenLength++;
  445. state = 1;
  446. break;
  447. }
  448. default:
  449. RRETURN(E_FAIL);
  450. }
  451. if (pDisplayCh) {
  452. *pDisplayCh++ = c;
  453. }
  454. }
  455. }
  456. HRESULT
  457. CLexer::GetNextToken(LPWSTR szToken, LPDWORD pdwToken)
  458. {
  459. RRETURN (GetNextToken(szToken, NULL, pdwToken));
  460. }
  461. //+---------------------------------------------------------------------------
  462. // Function:
  463. //
  464. // Synopsis:
  465. //
  466. // Arguments:
  467. //
  468. // Returns:
  469. //
  470. // Modifies:
  471. //
  472. // History: 11-3-95 krishnag Created.
  473. //
  474. //----------------------------------------------------------------------------
  475. WCHAR
  476. CLexer::NextChar()
  477. {
  478. if (_ptr == NULL || *_ptr == L'\0') {
  479. _dwEndofString = TRUE;
  480. return(L'\0');
  481. }
  482. return(*_ptr++);
  483. }
  484. //+---------------------------------------------------------------------------
  485. // Function:
  486. //
  487. // Synopsis:
  488. //
  489. // Arguments:
  490. //
  491. // Returns:
  492. //
  493. // Modifies:
  494. //
  495. // History: 11-3-95 krishnag Created.
  496. //
  497. //----------------------------------------------------------------------------
  498. HRESULT
  499. CLexer::PushBackToken()
  500. {
  501. if (_dwLastToken == TOKEN_END) {
  502. RRETURN(S_OK);
  503. }
  504. _ptr -= _dwLastTokenLength;
  505. RRETURN(S_OK);
  506. }
  507. //+---------------------------------------------------------------------------
  508. // Function:
  509. //
  510. // Synopsis:
  511. //
  512. // Arguments:
  513. //
  514. // Returns:
  515. //
  516. // Modifies:
  517. //
  518. // History: 11-3-95 krishnag Created.
  519. //
  520. //----------------------------------------------------------------------------
  521. void
  522. CLexer::PushbackChar()
  523. {
  524. if (_dwEndofString) {
  525. return;
  526. }
  527. _ptr--;
  528. }
  529. //+---------------------------------------------------------------------------
  530. // Function:
  531. //
  532. // Synopsis:
  533. //
  534. // Arguments:
  535. //
  536. // Returns:
  537. //
  538. // Modifies:
  539. //
  540. // History: 11-3-95 krishnag Created.
  541. //
  542. //----------------------------------------------------------------------------
  543. BOOL
  544. CLexer::IsKeyword(LPWSTR szToken, LPDWORD pdwToken)
  545. {
  546. DWORD i = 0;
  547. for (i = 0; i < MAX_KEYWORDS; i++) {
  548. if (!_wcsicmp(szToken, KeywordList[i].Keyword)) {
  549. *pdwToken = KeywordList[i].dwTokenId;
  550. return(TRUE);
  551. }
  552. }
  553. *pdwToken = 0;
  554. return(FALSE);
  555. }
  556. //+---------------------------------------------------------------------------
  557. //Function:
  558. //
  559. //Synopsis:
  560. //
  561. //Arguments:
  562. //
  563. //Returns:
  564. //
  565. //Modifies:
  566. //
  567. //History: 11-3-95 krishnag Created.
  568. //
  569. //----------------------------------------------------------------------------
  570. HRESULT
  571. AddComponent(POBJECTINFO pObjectInfo, LPWSTR szToken, LPWSTR szDisplayToken)
  572. {
  573. if (!szToken || !*szToken) {
  574. }
  575. pObjectInfo->ComponentArray[pObjectInfo->NumComponents] =
  576. AllocADsStr(szToken);
  577. pObjectInfo->DisplayComponentArray[pObjectInfo->NumComponents] =
  578. AllocADsStr(szToken);
  579. pObjectInfo->NumComponents++;
  580. RRETURN(S_OK);
  581. }
  582. HRESULT
  583. AddProviderName(POBJECTINFO pObjectInfo, LPWSTR szToken)
  584. {
  585. if (!szToken || !*szToken) {
  586. RRETURN(E_FAIL);
  587. }
  588. pObjectInfo->ProviderName = AllocADsStr(szToken);
  589. RRETURN(S_OK);
  590. }
  591. //+---------------------------------------------------------------------------
  592. // Function:
  593. //
  594. // Synopsis:
  595. //
  596. // Arguments:
  597. //
  598. // Returns:
  599. //
  600. // Modifies:
  601. //
  602. // History: 11-3-95 krishnag Created.
  603. //
  604. //----------------------------------------------------------------------------
  605. HRESULT
  606. SetType(POBJECTINFO pObjectInfo, DWORD dwToken)
  607. {
  608. pObjectInfo->ObjectType = dwToken;
  609. RRETURN(S_OK);
  610. }
  611. void
  612. CLexer::SetAtDisabler(
  613. BOOL bFlag
  614. )
  615. {
  616. _bAtDisabled = bFlag;
  617. }
  618. BOOL
  619. CLexer::GetAtDisabler()
  620. {
  621. return(_bAtDisabled);
  622. }
  623. HRESULT
  624. GetDisplayName(
  625. LPWSTR szName,
  626. LPWSTR *ppszDisplayName
  627. )
  628. {
  629. HRESULT hr = S_OK;
  630. DWORD len = 0;
  631. LPWSTR pch = szName;
  632. LPWSTR pszDisplayCh = NULL, pszDisplay = NULL;
  633. BOOL fQuotingOn = FALSE;
  634. if (!ppszDisplayName ) {
  635. RRETURN (E_INVALIDARG);
  636. }
  637. *ppszDisplayName = NULL;
  638. if (!szName) {
  639. RRETURN (S_OK);
  640. }
  641. pch = szName;
  642. fQuotingOn = FALSE;
  643. for (len=0; *pch; pch++, len++) {
  644. if ((!(pch > szName && *(pch-1) == '\\')) &&
  645. (*pch == L'"') ) {
  646. fQuotingOn = ~fQuotingOn;
  647. }
  648. else if (!fQuotingOn && (!(pch > szName && *(pch-1) == '\\')) &&
  649. (*pch == L'/' || *pch == L'<' || *pch == L'>') ) {
  650. len++;
  651. }
  652. }
  653. pszDisplay = (LPWSTR) AllocADsMem((len+1) * sizeof(WCHAR));
  654. if (!pszDisplay) {
  655. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  656. }
  657. pch = szName;
  658. pszDisplayCh = pszDisplay;
  659. fQuotingOn = FALSE;
  660. for (; *pch; pch++, pszDisplayCh++) {
  661. if ((!(pch > szName && *(pch-1) == '\\')) &&
  662. (*pch == L'"') ) {
  663. fQuotingOn = ~fQuotingOn;
  664. }
  665. else if (!fQuotingOn && (!(pch > szName && *(pch-1) == '\\')) &&
  666. (*pch == L'/' || *pch == L'<' || *pch == L'>') ) {
  667. *pszDisplayCh++ = L'\\';
  668. }
  669. *pszDisplayCh = *pch;
  670. }
  671. *pszDisplayCh = L'\0';
  672. *ppszDisplayName = pszDisplay;
  673. error:
  674. RRETURN(hr);
  675. }