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.

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