PARSE.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:14k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4.     Parse.cpp
  5. Abstract:
  6.     DS Pathname Parser
  7.     The Pathname Parser is a key component in ADs providers. It checks for
  8.     syntactic validity of an ADs pathname that has been passed to this
  9.     provider. If the syntax is valid, then an OBJECTINFO structure is
  10.     constructed. This OBJECTINFO structure contains a componentized version
  11.     of the ADs pathname for this object.
  12.     Note all that is being done is a syntax check. Rather than special-case
  13.     every single new nuance to pathnames, all path checking must conform to
  14.     the grammar rules laid out by the parser.
  15. Author:
  16. Environment:
  17.     User mode
  18. Revision History :
  19. --*/
  20. #include "adssmp.h"
  21. #pragma hdrstop
  22. //+---------------------------------------------------------------------------
  23. //  Function:   ADsObject
  24. //
  25. //  Synopsis:   parses an ADs pathname passed to this provider. This function
  26. //              parses the following grammar rules
  27. //
  28. //              <ADsObject> -> <ProviderName> <SampleDSObject>
  29. //
  30. //
  31. //  Arguments:  [CLexer * pTokenizer] - a lexical analyzer object
  32. //              [POBJECTINFO pObjectInfo] - a pointer to an OBJECTINFO structure
  33. //
  34. //  Returns:    [HRESULT] 0 if successful, error HRESULT if not
  35. //
  36. //  Modifies:   pTokenizer (consumes the input buffer)
  37. //
  38. //----------------------------------------------------------------------------
  39. HRESULT
  40. ADsObject(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  41. {
  42.     WCHAR szToken[MAX_TOKEN_LENGTH];
  43.     DWORD dwToken;
  44.     HRESULT hr;
  45.     hr = ProviderName(pTokenizer, pObjectInfo);
  46.     BAIL_IF_ERROR(hr);
  47.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  48.     BAIL_IF_ERROR(hr);
  49.     switch (dwToken) {
  50.     case TOKEN_END:
  51.         RRETURN(S_OK);
  52.     case TOKEN_COMMA:
  53.         hr = Type(pTokenizer, pObjectInfo);
  54.         BAIL_IF_ERROR(hr);
  55.         hr = pTokenizer->GetNextToken(szToken, &dwToken);
  56.         BAIL_IF_ERROR(hr);
  57.         if (dwToken == TOKEN_END) {
  58.             RRETURN(S_OK);
  59.         }else {
  60.             RRETURN(E_ADS_BAD_PATHNAME);
  61.         }
  62.     default:
  63.         hr = pTokenizer->PushBackToken();
  64.         hr = SampleDSObject(pTokenizer, pObjectInfo);
  65.         BAIL_IF_ERROR(hr);
  66.         hr = pTokenizer->GetNextToken(szToken, &dwToken);
  67.         BAIL_IF_ERROR(hr);
  68.         switch (dwToken) {
  69.         case TOKEN_END:
  70.             RRETURN(S_OK);
  71.         case TOKEN_COMMA:
  72.             hr = Type(pTokenizer, pObjectInfo);
  73.             BAIL_IF_ERROR(hr);
  74.             hr = pTokenizer->GetNextToken(szToken, &dwToken);
  75.             BAIL_IF_ERROR(hr);
  76.             if (dwToken == TOKEN_END) {
  77.                 RRETURN(S_OK);
  78.             }else {
  79.                 RRETURN(E_ADS_BAD_PATHNAME);
  80.             }
  81.         default:
  82.             RRETURN(E_FAIL);
  83.         }
  84.     }
  85. cleanup:
  86.     RRETURN(hr);
  87. }
  88. //+---------------------------------------------------------------------------
  89. //  Function:   SampleDSObject
  90. //
  91. //  Synopsis:   parses an ADs pathname passed to this provider. This function
  92. //              parses the following grammar rules
  93. //
  94. //              <SampleDSObject> -> "\""identifier""" <SampleDSObject>
  95. //
  96. //
  97. //  Arguments:  [CLexer * pTokenizer] - a lexical analyzer object
  98. //              [POBJECTINFO pObjectInfo] - a pointer to an OBJECTINFO structure
  99. //
  100. //  Returns:    [HRESULT] 0 if successful, error HRESULT if not
  101. //
  102. //  Modifies:   pTokenizer (consumes the input buffer)
  103. //
  104. //  History:    11-3-95   krishnag     Created.
  105. //
  106. //----------------------------------------------------------------------------
  107. HRESULT
  108. SampleDSObject(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  109. {
  110.     WCHAR szToken[MAX_TOKEN_LENGTH];
  111.     DWORD dwToken;
  112.     HRESULT hr;
  113.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  114.     BAIL_IF_ERROR(hr);
  115.     if ((dwToken != TOKEN_FSLASH) &&  (dwToken != TOKEN_BSLASH)) {
  116.         RRETURN(E_ADS_BAD_PATHNAME);
  117.     }
  118.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  119.     BAIL_IF_ERROR(hr);
  120.     if ((dwToken != TOKEN_FSLASH) && (dwToken != TOKEN_BSLASH)) {
  121.         RRETURN(E_ADS_BAD_PATHNAME);
  122.     }
  123.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  124.     BAIL_IF_ERROR(hr);
  125.     if (dwToken != TOKEN_IDENTIFIER) {
  126.         RRETURN(E_ADS_BAD_PATHNAME);
  127.     }
  128.     hr = AddRootRDN(pObjectInfo, szToken);
  129.     BAIL_IF_ERROR(hr);
  130.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  131.     BAIL_IF_ERROR(hr);
  132.     //
  133.     // If we get an TOKEN_END, then we have a tree name only \<tree_name>
  134.     //
  135.     if (dwToken == TOKEN_END || dwToken == TOKEN_COMMA) {
  136.         hr = pTokenizer->PushBackToken();
  137.         RRETURN(S_OK);
  138.     }
  139.     if ((dwToken != TOKEN_BSLASH) && (dwToken != TOKEN_FSLASH)) {
  140.         RRETURN(E_ADS_BAD_PATHNAME);
  141.     }
  142.     hr = PathName(pTokenizer, pObjectInfo);
  143.     BAIL_IF_ERROR(hr);
  144. cleanup:
  145.     RRETURN(hr);
  146. }
  147. HRESULT
  148. ProviderName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  149. {
  150.     WCHAR szToken[MAX_TOKEN_LENGTH];
  151.     DWORD dwToken;
  152.     HRESULT hr;
  153.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  154.     BAIL_IF_ERROR(hr);
  155.     if (dwToken == TOKEN_ATSIGN) {
  156.         hr = pTokenizer->GetNextToken(szToken, &dwToken);
  157.         BAIL_IF_ERROR(hr);
  158.         if (dwToken != TOKEN_IDENTIFIER) {
  159.             RRETURN(E_ADS_BAD_PATHNAME);
  160.         }
  161.         hr = AddProviderName(pObjectInfo, szToken);
  162.         hr = pTokenizer->GetNextToken(szToken, &dwToken);
  163.         BAIL_IF_ERROR(hr);
  164.         if (dwToken != TOKEN_EXCLAMATION) {
  165.             RRETURN(E_ADS_BAD_PATHNAME);
  166.         }
  167.     }else if (dwToken == TOKEN_IDENTIFIER) {
  168.         hr = AddProviderName(pObjectInfo, szToken);
  169.         hr = pTokenizer->GetNextToken(szToken, &dwToken);
  170.         BAIL_IF_ERROR(hr);
  171.         if (dwToken != TOKEN_COLON) {
  172.             RRETURN(E_ADS_BAD_PATHNAME);
  173.         }
  174.     }else {
  175.         RRETURN(E_ADS_BAD_PATHNAME);
  176.     }
  177.     RRETURN(S_OK);
  178. cleanup:
  179.     RRETURN(hr);
  180. }
  181. // PathName -> Component \ PathName
  182. // PathName -> Component
  183. HRESULT
  184. DsPathName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  185. {
  186.     WCHAR szToken[MAX_TOKEN_LENGTH];
  187.     DWORD dwToken;
  188.     HRESULT hr;
  189.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  190.     BAIL_IF_ERROR(hr);
  191.     if ((dwToken != TOKEN_FSLASH) || (dwToken != TOKEN_BSLASH)) {
  192.         RRETURN(E_ADS_BAD_PATHNAME);
  193.     }
  194.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  195.     BAIL_IF_ERROR(hr);
  196.     if ((dwToken != TOKEN_FSLASH) || (dwToken != TOKEN_BSLASH)) {
  197.         RRETURN(E_ADS_BAD_PATHNAME);
  198.     }
  199.     hr = PathName(pTokenizer, pObjectInfo);
  200.     BAIL_IF_ERROR(hr);
  201.     RRETURN(S_OK);
  202. cleanup:
  203.     RRETURN(hr);
  204. }
  205. HRESULT
  206. PathName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  207. {
  208.     HRESULT hr;
  209.     WCHAR szToken[MAX_TOKEN_LENGTH];
  210.     DWORD dwToken;
  211.     hr = Component(pTokenizer, pObjectInfo);
  212.     BAIL_IF_ERROR(hr);
  213.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  214.     if ((dwToken == TOKEN_BSLASH) || (dwToken == TOKEN_FSLASH)) {
  215.         RRETURN (PathName(pTokenizer, pObjectInfo));
  216.     }else {
  217.         hr = pTokenizer->PushBackToken();
  218.         RRETURN (S_OK);
  219.     }
  220. cleanup:
  221.     RRETURN(hr);
  222. }
  223. HRESULT
  224. Component(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  225. {
  226.     WCHAR szValue[MAX_TOKEN_LENGTH];
  227.     WCHAR szEqual[MAX_TOKEN_LENGTH];
  228.     WCHAR szComponent[MAX_TOKEN_LENGTH];
  229.     DWORD dwToken;
  230.     HRESULT hr;
  231.     hr = pTokenizer->GetNextToken(szComponent, &dwToken);
  232.     BAIL_IF_ERROR(hr);
  233.     if (dwToken != TOKEN_IDENTIFIER) {
  234.         RRETURN(E_ADS_BAD_PATHNAME);
  235.     }
  236.     hr = pTokenizer->GetNextToken(szEqual, &dwToken);
  237.     BAIL_IF_ERROR(hr);
  238.     if (dwToken == TOKEN_EQUAL) {
  239.         hr = pTokenizer->GetNextToken(szValue, &dwToken);
  240.         BAIL_IF_ERROR(hr);
  241.         if (dwToken != TOKEN_IDENTIFIER) {
  242.             RRETURN(E_ADS_BAD_PATHNAME);
  243.         }
  244.         hr = AddComponent(pObjectInfo, szComponent, szValue);
  245.         BAIL_IF_ERROR(hr);
  246.     }else {
  247.         hr = AddComponent(pObjectInfo, szComponent, NULL);
  248.         BAIL_IF_ERROR(hr);
  249.         hr = pTokenizer->PushBackToken();
  250.         BAIL_IF_ERROR(hr);
  251.     }
  252.     RRETURN(S_OK);
  253. cleanup:
  254.     RRETURN(hr);
  255. }
  256. CLexer::CLexer(LPWSTR szBuffer):
  257.                 _ptr(NULL),
  258.                 _Buffer(NULL),
  259.                 _dwLastTokenLength(0),
  260.                 _dwLastToken(0),
  261.                 _dwEndofString(0)
  262. {
  263.     if (!szBuffer || !*szBuffer) {
  264.         return;
  265.     }
  266.     _Buffer = AllocProvStr(szBuffer);
  267.     _ptr = _Buffer;
  268. }
  269. CLexer::~CLexer()
  270. {
  271.     FreeProvStr(_Buffer);
  272. }
  273. HRESULT
  274. CLexer::GetNextToken(LPWSTR szToken, LPDWORD pdwToken)
  275. {
  276.     WCHAR c;
  277.     DWORD state = 0;
  278.     LPWSTR pch = szToken;
  279.     memset(szToken, 0, sizeof(WCHAR) * MAX_TOKEN_LENGTH);
  280.     _dwLastTokenLength = 0;
  281.     while (1) {
  282.         c = NextChar();
  283.         switch (state) {
  284.         case  0:
  285.             *pch++ = c;
  286.             _dwLastTokenLength++;
  287.             if (c == L'\') {
  288.                 *pdwToken = TOKEN_BSLASH;
  289.                 _dwLastToken = *pdwToken;
  290.                 RRETURN(S_OK);
  291.             }else if (c == L'/') {
  292.                 *pdwToken = TOKEN_FSLASH;
  293.                 _dwLastToken = *pdwToken;
  294.                 RRETURN(S_OK);
  295.             }else if (c == L',') {
  296.                 *pdwToken = TOKEN_COMMA;
  297.                 _dwLastToken = *pdwToken;
  298.                 RRETURN(S_OK);
  299.             }else if (c == L'@'){
  300.                 *pdwToken = TOKEN_ATSIGN;
  301.                 _dwLastToken = *pdwToken;
  302.                 RRETURN(S_OK);
  303.             }else if (c == L'='){
  304.                 *pdwToken = TOKEN_EQUAL;
  305.                 _dwLastToken = *pdwToken;
  306.                 RRETURN(S_OK);
  307.             }else if (c == L'.'){
  308.                 *pdwToken = TOKEN_PERIOD;
  309.                 _dwLastToken = *pdwToken;
  310.                 RRETURN(S_OK);
  311.             }else if (c == L'!'){
  312.                 *pdwToken = TOKEN_EXCLAMATION;
  313.                 _dwLastToken = *pdwToken;
  314.                 RRETURN(S_OK);
  315.             }else if (c == L':'){
  316.                 *pdwToken = TOKEN_COLON;
  317.                 _dwLastToken = *pdwToken;
  318.                 RRETURN(S_OK);
  319.             }else if (c == L''){
  320.                 *pdwToken = TOKEN_END;
  321.                 _dwLastToken = *pdwToken;
  322.                 RRETURN(S_OK);
  323.             }else {
  324.                 state = 1;
  325.             }
  326.             break;
  327.         case 1:
  328.             if (c == L'\' || c == L'' || c == L',' ||
  329.                     c == L'@' || c == L'!'|| c == L'=' || c == L'.' ||
  330.                     c == L':' || c == L'/') {
  331.                 PushbackChar();
  332.                 *pdwToken = TOKEN_IDENTIFIER;
  333.                 _dwLastToken = *pdwToken;
  334.                 RRETURN (S_OK);
  335.             }else {
  336.                 *pch++ = c;
  337.                 _dwLastTokenLength++;
  338.                 state = 1;
  339.                 break;
  340.             }
  341.         default:
  342.             RRETURN(E_FAIL);
  343.         }
  344.     }
  345. }
  346. WCHAR
  347. CLexer::NextChar()
  348. {
  349.     if (_ptr == NULL || *_ptr == L'') {
  350.         _dwEndofString = TRUE;
  351.         return(L'');
  352.     }
  353.     return(*_ptr++);
  354. }
  355. HRESULT
  356. CLexer::PushBackToken()
  357. {
  358.     if (_dwLastToken == TOKEN_END) {
  359.         RRETURN(S_OK);
  360.     }
  361.     _ptr -= _dwLastTokenLength;
  362.     RRETURN(S_OK);
  363. }
  364. void
  365. CLexer::PushbackChar()
  366. {
  367.     if (_dwEndofString) {
  368.         return;
  369.     }
  370.     _ptr--;
  371. }
  372. BOOL
  373. CLexer::IsKeyword(LPWSTR szToken, LPDWORD pdwToken)
  374. {
  375.     DWORD i = 0;
  376.     for (i = 0; i < MAX_KEYWORDS; i++) {
  377.         if (!_wcsicmp(szToken, KeywordList[i].Keyword)) {
  378.             *pdwToken = KeywordList[i].dwTokenId;
  379.             return(TRUE);
  380.         }
  381.     }
  382.     *pdwToken = 0;
  383.     return(FALSE);
  384. }
  385. HRESULT
  386. AddComponent(POBJECTINFO pObjectInfo, LPWSTR szComponent, LPWSTR szValue)
  387. {
  388.     if (!szComponent || !*szComponent) {
  389.         RRETURN(E_FAIL);
  390.     }
  391.     if (pObjectInfo->NumComponents < MAXCOMPONENTS) {
  392.         pObjectInfo->ComponentArray[pObjectInfo->NumComponents].szComponent =
  393.                         AllocProvStr(szComponent);
  394.         pObjectInfo->ComponentArray[pObjectInfo->NumComponents].szValue =
  395.                         AllocProvStr(szValue);
  396.         pObjectInfo->NumComponents++;
  397.         RRETURN(S_OK);
  398.     }else {
  399.         RRETURN(E_FAIL);
  400.     }
  401. }
  402. HRESULT
  403. AddProviderName(POBJECTINFO pObjectInfo, LPWSTR szToken)
  404. {
  405.     if (!szToken || !*szToken) {
  406.         RRETURN(E_FAIL);
  407.     }
  408.     pObjectInfo->ProviderName = AllocProvStr(szToken);
  409.     RRETURN(S_OK);
  410. }
  411. HRESULT
  412. AddRootRDN(POBJECTINFO pObjectInfo, LPWSTR szToken)
  413. {
  414.     if (!szToken || !*szToken) {
  415.         RRETURN(E_FAIL);
  416.     }
  417.     pObjectInfo->RootRDN = AllocProvStr(szToken);
  418.     RRETURN(S_OK);
  419. }
  420. HRESULT
  421. SetType(POBJECTINFO pObjectInfo, DWORD dwToken)
  422. {
  423.     pObjectInfo->ObjectType = dwToken;
  424.     RRETURN(S_OK);
  425. }
  426. // Type -> "user", "group","printer","service", "fileservice"
  427. //+---------------------------------------------------------------------------
  428. // Function:    Type
  429. //
  430. // Synopsis:    Parses Type-> "user" | "group" etc
  431. //
  432. // Arguments:   [CLexer * pTokenizer]
  433. //              [POBJECTINFo pObjectInfo]
  434. //
  435. // Returns:     HRESULT
  436. //
  437. // Modifies:    
  438. //
  439. // History:    
  440. //
  441. //----------------------------------------------------------------------------
  442. HRESULT
  443. Type(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
  444. {
  445.     WCHAR szToken[MAX_PATH];
  446.     DWORD dwToken;
  447.     HRESULT hr;
  448.     hr = pTokenizer->GetNextToken(szToken, &dwToken);
  449.     BAIL_IF_ERROR(hr);
  450.     if (dwToken == TOKEN_IDENTIFIER ) {
  451.         RRETURN(hr);
  452.     }
  453.     RRETURN(E_FAIL);
  454. cleanup:
  455.     RRETURN(hr);
  456. }