|
|
//--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996
//
// File: parse.cxx
//
// Contents: LDAP Pathname Parser
//
// The Pathname Parser is a key component in ADs providers. It checks for
// syntactic validity of an ADs pathname that has been passed to this
// provider. If the syntax is valid, then an OBJECTINFO structure is
// constructed. This OBJECTINFO structure contains a componentized version
// of the ADs pathname for this object.
//
// Note all that is being done is a syntax check. Rather than special-case
// every single new nuance to pathnames, all path checking must conform to
// the grammar rules laid out by the parser.
//
//
//
// History:
//----------------------------------------------------------------------------
#include <stdlib.h>
#include "ldapc.hxx"
#pragma hdrstop
// Object -> PathName, Type, eos
// Object -> PathName, eos
KWDLIST KeywordList[] = { { TOKEN_DOMAIN, DOMAIN_CLASS_NAME }, { TOKEN_USER, USER_CLASS_NAME }, { TOKEN_GROUP, GROUP_CLASS_NAME }, { TOKEN_COMPUTER, COMPUTER_CLASS_NAME }, { TOKEN_PRINTER, PRINTER_CLASS_NAME }, { TOKEN_SERVICE, SERVICE_CLASS_NAME }, { TOKEN_FILESERVICE, FILESERVICE_CLASS_NAME }, { TOKEN_FILESHARE, FILESHARE_CLASS_NAME }, { TOKEN_SCHEMA, SCHEMA_CLASS_NAME }, { TOKEN_CLASS, CLASS_CLASS_NAME }, { TOKEN_PROPERTY, PROPERTY_CLASS_NAME }, { TOKEN_SYNTAX, SYNTAX_CLASS_NAME }, { TOKEN_LOCALITY, LOCALITY_CLASS_NAME }, { TOKEN_ORGANIZATION, ORGANIZATION_CLASS_NAME }, { TOKEN_ORGANIZATIONUNIT, ORGANIZATIONUNIT_CLASS_NAME }, { TOKEN_COUNTRY, COUNTRY_CLASS_NAME }, { TOKEN_ROOTDSE, ROOTDSE_CLASS_NAME} };
DWORD gdwKeywordListSize = sizeof(KeywordList)/sizeof(KWDLIST);
HRESULT InitObjectInfo( LPWSTR pszADsPathName, POBJECTINFO pObjectInfo ) { DWORD dwLen = 0; HRESULT hr = S_OK;
ADsAssert(pObjectInfo); ADsAssert(pszADsPathName);
memset(pObjectInfo, 0x0, sizeof(OBJECTINFO));
dwLen = wcslen(pszADsPathName) * sizeof(WCHAR) * 3; if( dwLen ) { pObjectInfo->szStrBuf = (LPWSTR) AllocADsMem(dwLen); pObjectInfo->szDisplayStrBuf = (LPWSTR) AllocADsMem(dwLen);
if (!pObjectInfo->szStrBuf || !pObjectInfo->szDisplayStrBuf) { RRETURN(E_OUTOFMEMORY); }
pObjectInfo->szStrBufPtr = pObjectInfo->szStrBuf; pObjectInfo->szDisplayStrBufPtr = pObjectInfo->szDisplayStrBuf; }
RRETURN(hr); }
VOID FreeObjectInfo( POBJECTINFO pObjectInfo ) { if ( !pObjectInfo ) return;
if (pObjectInfo->szStrBuf) { FreeADsStr( pObjectInfo->szStrBuf ); } if (pObjectInfo->szDisplayStrBuf) { FreeADsStr( pObjectInfo->szDisplayStrBuf ); } }
HRESULT ADsObject( LPWSTR pszADsPathName, POBJECTINFO pObjectInfo ) { HRESULT hr = S_OK;
CLexer Lexer(pszADsPathName);
hr = InitObjectInfo(pszADsPathName, pObjectInfo); BAIL_ON_FAILURE(hr);
pObjectInfo->ObjectType = TOKEN_LDAPOBJECT;
hr = ADsObjectParse(&Lexer, pObjectInfo);
error:
RRETURN(hr); }
HRESULT GetNextToken( CLexer *pTokenizer, POBJECTINFO pObjectInfo, LPWSTR *ppszToken, LPWSTR *ppszDisplayToken, DWORD *pdwToken ) {
HRESULT hr = S_OK;
ADsAssert(ppszToken); *ppszToken = NULL;
if (ppszDisplayToken) { *ppszDisplayToken = NULL; }
hr = pTokenizer->GetNextToken( pObjectInfo->szStrBufPtr, pObjectInfo->szDisplayStrBufPtr, pdwToken ); BAIL_ON_FAILURE(hr);
*ppszToken = pObjectInfo->szStrBufPtr;
if (ppszDisplayToken) { *ppszDisplayToken = pObjectInfo->szDisplayStrBufPtr; }
pObjectInfo->szStrBufPtr += wcslen(pObjectInfo->szStrBufPtr) + 1; pObjectInfo->szDisplayStrBufPtr += wcslen(pObjectInfo->szDisplayStrBufPtr) + 1;
error:
RRETURN (hr);
}
HRESULT GetNextToken( CLexer *pTokenizer, POBJECTINFO pObjectInfo, LPWSTR *ppszToken, DWORD *pdwToken ) { return (GetNextToken( pTokenizer, pObjectInfo, ppszToken, NULL, pdwToken ));
} //+---------------------------------------------------------------------------
// Function: ADsObject
//
// Synopsis: parses an ADs pathname passed to this provider. This function
// parses the following grammar rules
//
// <ADsObject> -> <ProviderName> <LDAPObject>
//
//
// Arguments: [CLexer * pTokenizer] - a lexical analyzer object
// [POBJECTINFO pObjectInfo] - a pointer to an OBJECTINFO structure
//
// Returns: [HRESULT] 0 if successful, error HRESULT if not
//
// Modifies: pTokenizer (consumes the input buffer)
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT ADsObjectParse(CLexer * pTokenizer, POBJECTINFO pObjectInfo) { LPWSTR szToken = NULL; DWORD dwToken; HRESULT hr;
hr = ProviderName(pTokenizer, pObjectInfo); BAIL_IF_ERROR(hr);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
switch ( dwToken ) { case TOKEN_END: RRETURN(S_OK);
default: hr = pTokenizer->PushBackToken(); BAIL_IF_ERROR(hr);
hr = LDAPObject(pTokenizer, pObjectInfo); BAIL_IF_ERROR(hr); break; }
cleanup:
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: LDAPObject
//
// Synopsis: parses an ADs pathname passed to this provider. This function
// parses the following grammar rules
//
// <LDAPObject> -> "\\""identifier""\" <LDAPObject>
//
//
// Arguments: [CLexer * pTokenizer] - a lexical analyzer object
// [POBJECTINFO pObjectInfo] - a pointer to an OBJECTINFO structure
//
// Returns: [HRESULT] 0 if successful, error HRESULT if not
//
// Modifies: pTokenizer (consumes the input buffer)
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT LDAPObject(CLexer * pTokenizer, POBJECTINFO pObjectInfo) { LPWSTR szToken = NULL; LPWSTR szDisplayToken; DWORD dwToken, dwPort; HRESULT hr; WCHAR c = L'\0';
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr); if (dwToken != TOKEN_FSLASH) { RRETURN(E_ADS_BAD_PATHNAME); }
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr); if (dwToken != TOKEN_FSLASH) { RRETURN(E_ADS_BAD_PATHNAME); }
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &szDisplayToken, &dwToken); BAIL_IF_ERROR(hr); if (dwToken != TOKEN_IDENTIFIER) { RRETURN(E_ADS_BAD_PATHNAME); }
if (!_wcsicmp(szToken, L"schema")) {
hr = pTokenizer->PushBackToken(); // push back the identifier
BAIL_IF_ERROR(hr);
pObjectInfo->dwServerPresent = FALSE;
hr = PathName(pTokenizer, pObjectInfo); BAIL_IF_ERROR(hr);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
} else if (!_wcsicmp(szToken, L"rootdse")) {
hr = pTokenizer->PushBackToken(); // push back the identifier
BAIL_IF_ERROR(hr);
pObjectInfo->dwServerPresent = FALSE;
hr = PathName(pTokenizer, pObjectInfo); BAIL_IF_ERROR(hr);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
} else if (((c = (CHAR)pTokenizer->NextChar()) == TEXT('=')) || (c == TEXT(',')) || (c == TEXT(';'))) { pTokenizer->PushbackChar(); // push back =
hr = pTokenizer->PushBackToken(); // push back the identifier
BAIL_IF_ERROR(hr);
pObjectInfo->dwServerPresent = FALSE;
hr = PathName(pTokenizer, pObjectInfo); BAIL_IF_ERROR(hr);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr); } else { pTokenizer->PushbackChar();
hr = AddTreeName(pObjectInfo, szToken, szDisplayToken); BAIL_IF_ERROR(hr);
pObjectInfo->dwServerPresent = TRUE;
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
//
// Check if we have an explicit port number
//
if ( dwToken == TOKEN_COLON) {
//
// Get the port number and set it in the ObjectInfo structure
//
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken == TOKEN_END) { RRETURN(E_ADS_BAD_PATHNAME); }
dwPort = _wtoi(szToken); if (dwPort == 0) { RRETURN(E_ADS_BAD_PATHNAME); }
AddPortNumber(pObjectInfo, dwPort);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
}
//
// If we get an TOKEN_END, then we have a tree name only \\<tree_name>
//
if (dwToken == TOKEN_END) { RRETURN(S_OK); }
if (dwToken == TOKEN_FSLASH) {
hr = PathName(pTokenizer, pObjectInfo); BAIL_IF_ERROR(hr);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
} else if ( dwToken == TOKEN_COMMA || dwToken == TOKEN_SEMICOLON ) { // do nothing here
} else { RRETURN(E_ADS_BAD_PATHNAME); } }
switch (dwToken) { case TOKEN_END: RRETURN(S_OK);
default: RRETURN(E_ADS_BAD_PATHNAME);
} cleanup: RRETURN(hr); }
HRESULT ProviderName(CLexer * pTokenizer, POBJECTINFO pObjectInfo) { LPWSTR szToken = NULL; DWORD dwToken; HRESULT hr; DWORD dwPort;
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken == TOKEN_ATSIGN) {
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken != TOKEN_IDENTIFIER) { RRETURN(E_ADS_BAD_PATHNAME); }
hr = AddProviderName(pObjectInfo, szToken); hr = AddNamespaceName(pObjectInfo, szToken);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken != TOKEN_EXCLAMATION) { RRETURN(E_ADS_BAD_PATHNAME); } }else if (dwToken == TOKEN_IDENTIFIER) {
hr = AddProviderName(pObjectInfo, szToken); hr = AddNamespaceName(pObjectInfo, szToken);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken != TOKEN_COLON) { RRETURN(E_ADS_BAD_PATHNAME); }
}else { RRETURN(E_ADS_BAD_PATHNAME); }
//
// Add the default port number depending on the namespace.
// If an explicit port number is specified, that will override
//
if ( _wcsicmp( pObjectInfo->NamespaceName, szGCNamespaceName) == 0 ) { dwPort = (DWORD) USE_DEFAULT_GC_PORT; } else { dwPort = (DWORD) USE_DEFAULT_LDAP_PORT; }
AddPortNumber(pObjectInfo, dwPort);
//
// You can now disable the processing for "@" and "!" treat them
// as ordinary characters.
//
pTokenizer->SetAtDisabler(TRUE);
RRETURN(S_OK);
cleanup:
RRETURN(hr); }
// PathName -> Component \\ PathName
// PathName -> Component
HRESULT DsPathName(CLexer * pTokenizer, POBJECTINFO pObjectInfo) { LPWSTR szToken = NULL; DWORD dwToken; HRESULT hr;
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr); if (dwToken != TOKEN_FSLASH) { RRETURN(E_ADS_BAD_PATHNAME); }
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr); if (dwToken != TOKEN_FSLASH) { RRETURN(E_ADS_BAD_PATHNAME); }
hr = PathName(pTokenizer, pObjectInfo); BAIL_IF_ERROR(hr);
RRETURN(S_OK);
cleanup:
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT PathName(CLexer * pTokenizer, POBJECTINFO pObjectInfo) { HRESULT hr; LPWSTR szToken = NULL; DWORD dwToken;
hr = Component(pTokenizer, pObjectInfo); BAIL_IF_ERROR(hr);
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
if (!pObjectInfo->dwPathType) {
if (dwToken == TOKEN_FSLASH) {
pObjectInfo->dwPathType = PATHTYPE_WINDOWS; RRETURN (PathName(pTokenizer, pObjectInfo)); }else if (dwToken == TOKEN_COMMA || dwToken == TOKEN_SEMICOLON){
pObjectInfo->dwPathType = PATHTYPE_X500; RRETURN (PathName(pTokenizer, pObjectInfo)); }else{ hr = pTokenizer->PushBackToken(); RRETURN (S_OK); } }else if (pObjectInfo->dwPathType == PATHTYPE_WINDOWS){
if (dwToken == TOKEN_FSLASH) { RRETURN (PathName(pTokenizer, pObjectInfo)); }else{ hr = pTokenizer->PushBackToken(); RRETURN (S_OK); } }else if (pObjectInfo->dwPathType == PATHTYPE_X500){
if (dwToken == TOKEN_COMMA || dwToken == TOKEN_SEMICOLON) { RRETURN (PathName(pTokenizer, pObjectInfo)); }else{ hr = pTokenizer->PushBackToken(); RRETURN (S_OK); } }else {
//
// We should never hit this point
//
hr = E_FAIL; }
cleanup:
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis: Component -> <identifier>
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT Component(CLexer * pTokenizer, POBJECTINFO pObjectInfo) { LPWSTR szValue = NULL; LPWSTR szDisplayValue = NULL; LPWSTR szEqual = NULL; LPWSTR szComponent = NULL; LPWSTR szDisplayComponent = NULL; DWORD dwToken; HRESULT hr = S_OK;
hr = GetNextToken(pTokenizer, pObjectInfo, &szComponent, &szDisplayComponent, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken != TOKEN_IDENTIFIER) { BAIL_IF_ERROR( hr = E_ADS_BAD_PATHNAME); }
hr = GetNextToken(pTokenizer, pObjectInfo, &szEqual, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken == TOKEN_EQUAL) {
hr = GetNextToken(pTokenizer, pObjectInfo, &szValue, &szDisplayValue, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken != TOKEN_IDENTIFIER) { BAIL_IF_ERROR(hr = E_ADS_BAD_PATHNAME); }
hr = AddComponent(pObjectInfo, szComponent, szValue, szDisplayComponent, szDisplayValue); BAIL_IF_ERROR(hr);
}else {
hr = AddComponent(pObjectInfo, szComponent, NULL, szDisplayComponent, NULL); BAIL_IF_ERROR(hr);
hr = pTokenizer->PushBackToken(); BAIL_IF_ERROR(hr); }
cleanup:
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: Type
//
// Synopsis: Parses Type-> "user" | "group" etc
//
// Arguments: [CLexer * pTokenizer]
// [POBJECTINFo pObjectInfo]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT Type(CLexer * pTokenizer, POBJECTINFO pObjectInfo) { LPWSTR szToken = NULL; DWORD dwToken; HRESULT hr;
hr = GetNextToken(pTokenizer, pObjectInfo, &szToken, &dwToken); BAIL_IF_ERROR(hr);
if (dwToken == TOKEN_IDENTIFIER ) { if (pTokenizer->IsKeyword(szToken, &dwToken)) { hr = SetType(pObjectInfo, dwToken); BAIL_IF_ERROR(hr); } pObjectInfo->ObjectClass = szToken; }
cleanup:
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
__declspec(dllexport) CLexer::CLexer(LPTSTR szBuffer): _ptr(NULL), _Buffer(NULL), _dwLastTokenLength(0), _dwLastToken(0), _dwEndofString(0), _bAtDisabled(FALSE), _bFSlashDisabled(FALSE), _bExclaimDisabled(FALSE) { if (!szBuffer || !*szBuffer) { return; } _Buffer = AllocADsStr(szBuffer); _ptr = _Buffer; }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 08-12-96 t-danal Created.
//
//----------------------------------------------------------------------------
__declspec(dllexport) CLexer::~CLexer() { FreeADsStr(_Buffer); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT CLexer::GetNextToken(LPTSTR szToken, LPTSTR szDisplayToken, LPDWORD pdwToken) { TCHAR c, cnext; DWORD state = 0; LPTSTR pch = szToken; LPTSTR pDisplayCh = szDisplayToken; BOOL fEscapeOn = FALSE, fQuotingOn = FALSE;
if (!szToken) { RRETURN(E_ADS_BAD_PATHNAME); }
_dwLastTokenLength = 0; while (1) { c = NextChar();
switch (state) { case 0: *pch++ = c; _dwLastTokenLength++;
switch (c) {
case TEXT('"') : //
// Quoting;
//
fQuotingOn = TRUE;
state = 1; break;
case TEXT('\\') : //
// Escaping; Ignore the '\' in the token and check to make
// sure that the next character exists
//
cnext = NextChar(); if (cnext == TEXT('/')) { pch--; } PushbackChar();
fEscapeOn = TRUE;
state = 1; break;
case TEXT('/') : if (!_bFSlashDisabled) { *pdwToken = TOKEN_FSLASH; _dwLastToken = *pdwToken; RRETURN(S_OK); } else { state = 1; } break; case TEXT(',') : *pdwToken = TOKEN_COMMA; _dwLastToken = *pdwToken; RRETURN(S_OK); break;
case TEXT(';') : *pdwToken = TOKEN_SEMICOLON; _dwLastToken = *pdwToken; RRETURN(S_OK); break;
case TEXT('=') : *pdwToken = TOKEN_EQUAL; _dwLastToken = *pdwToken; RRETURN(S_OK); break;
case TEXT(':') : if (!_bAtDisabled && !_bExclaimDisabled) { *pdwToken = TOKEN_COLON; _dwLastToken = *pdwToken; RRETURN(S_OK); }else { state = 1; } break;
case TEXT('\0') : *pdwToken = TOKEN_END; _dwLastToken = *pdwToken; RRETURN(S_OK); break;
case TEXT('@') :
if (!_bAtDisabled) { *pdwToken = TOKEN_ATSIGN; _dwLastToken = *pdwToken; RRETURN(S_OK); }else { state = 1; } break;
case TEXT('!') :
if (!_bAtDisabled && !_bExclaimDisabled) { *pdwToken = TOKEN_EXCLAMATION; _dwLastToken = *pdwToken; RRETURN(S_OK); }else { state = 1; } break;
case TEXT(' ') : pch--; _dwLastTokenLength--; break;
default: state = 1; break;
} break;
case 1:
if ((fEscapeOn || fQuotingOn) && c == TEXT('\0') ) { RRETURN(E_ADS_BAD_PATHNAME); } else if (fEscapeOn) { fEscapeOn = FALSE; *pch++ = c; _dwLastTokenLength++; state = 1; break; } else if (fQuotingOn) { if (c == TEXT('"')) { fQuotingOn = FALSE; } else if (c == TEXT('\\')) { //
// This is a special case, where a \ is
// being passed in to escape something inside
// quotes.
//
fEscapeOn = TRUE; _dwLastTokenLength++;
*pch++ = c;
cnext = NextChar(); if (cnext == '/') { pch--; } PushbackChar(); state = 1; break; } *pch++ = c; _dwLastTokenLength++; break; } //
// Ok to put a switch here as all have breaks above.
//
switch (c) { case TEXT('\\') :
fEscapeOn = TRUE; _dwLastTokenLength++;
*pch++ = c;
cnext = NextChar(); if (cnext == '/') { pch--; } PushbackChar();
break;
case TEXT('"') : fQuotingOn = TRUE; *pch++ = c; _dwLastTokenLength++; break;
case TEXT('\0'): case TEXT(',') : case TEXT('=') : case TEXT(';') : PushbackChar();
*pdwToken = TOKEN_IDENTIFIER; _dwLastToken = *pdwToken; RRETURN (S_OK); break;
case TEXT('/') : if (!_bFSlashDisabled) { PushbackChar();
*pdwToken = TOKEN_IDENTIFIER; _dwLastToken = *pdwToken; RRETURN(S_OK); } else { *pch++ = c; _dwLastTokenLength++; state = 1; } break; case TEXT('!') : case TEXT(':') : if (!_bAtDisabled && !_bExclaimDisabled) {
PushbackChar(); *pdwToken = TOKEN_IDENTIFIER; _dwLastToken = *pdwToken; RRETURN(S_OK);
}else {
*pch++ = c; _dwLastTokenLength++; state = 1; break;
} case TEXT('@') : if (!_bAtDisabled) {
PushbackChar(); *pdwToken = TOKEN_IDENTIFIER; _dwLastToken = *pdwToken; RRETURN(S_OK);
}else {
*pch++ = c; _dwLastTokenLength++; state = 1; break;
}
default : *pch++ = c; _dwLastTokenLength++; state = 1; break; } break; default: RRETURN(E_ADS_BAD_PATHNAME); }
if (pDisplayCh) { *pDisplayCh++ = c; }
} }
__declspec(dllexport) HRESULT CLexer::GetNextToken(LPTSTR szToken, LPDWORD pdwToken) { RRETURN (GetNextToken(szToken, NULL, pdwToken)); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
TCHAR CLexer::NextChar() { if (_ptr == NULL || *_ptr == TEXT('\0')) { _dwEndofString = TRUE; return(TEXT('\0')); } return(*_ptr++); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT CLexer::PushBackToken() { if (_dwLastToken == TOKEN_END) { RRETURN(S_OK); } _ptr -= _dwLastTokenLength;
RRETURN(S_OK); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
void CLexer::PushbackChar() { if (_dwEndofString) { return; } _ptr--;
}
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
BOOL CLexer::IsKeyword(LPTSTR szToken, LPDWORD pdwToken) { DWORD i = 0;
for (i = 0; i < gdwKeywordListSize; i++) { if (!_tcsicmp(szToken, KeywordList[i].Keyword)) { *pdwToken = KeywordList[i].dwTokenId; return(TRUE); } } *pdwToken = 0; return(FALSE); }
//+---------------------------------------------------------------------------
//Function:
//
//Synopsis:
//
//Arguments:
//
//Returns:
//
//Modifies:
//
//History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT AddComponent(POBJECTINFO pObjectInfo, LPTSTR szComponent, LPTSTR szValue, LPTSTR szDisplayComponent, LPTSTR szDisplayValue ) { if (!szComponent || !*szComponent || !szDisplayComponent || !*szDisplayComponent) { RRETURN(E_FAIL); }
if ( pObjectInfo->NumComponents < MAXCOMPONENTS ) {
pObjectInfo->ComponentArray[pObjectInfo->NumComponents].szComponent = szComponent;
pObjectInfo->ComponentArray[pObjectInfo->NumComponents].szValue = szValue;
pObjectInfo->DisplayComponentArray[pObjectInfo->NumComponents].szComponent = szDisplayComponent;
pObjectInfo->DisplayComponentArray[pObjectInfo->NumComponents].szValue = szDisplayValue;
pObjectInfo->NumComponents++;
RRETURN(S_OK);
} else {
RRETURN(E_ADS_BAD_PATHNAME); }
}
HRESULT AddProviderName(POBJECTINFO pObjectInfo, LPTSTR szToken) { if (!szToken || !*szToken) { RRETURN(E_FAIL); }
if (_tcscmp(szToken, szLDAPNamespaceName) == 0 || _tcscmp(szToken, szGCNamespaceName) == 0) {
//
// szProviderName is the provider name for both LDAP and GC namespaces
//
pObjectInfo->ProviderName = szProviderName; } else {
//
// Not one of the namespaces we handle, just copy
//
pObjectInfo->ProviderName = szToken; }
RRETURN(S_OK); }
HRESULT AddNamespaceName(POBJECTINFO pObjectInfo, LPTSTR szToken) { if (!szToken || !*szToken) { RRETURN(E_FAIL); }
pObjectInfo->NamespaceName = szToken;
RRETURN(S_OK); }
HRESULT AddTreeName(POBJECTINFO pObjectInfo, LPTSTR szToken, LPWSTR szDisplayToken) { if (!szToken || !*szToken || !szDisplayToken || !*szDisplayToken) { RRETURN(E_FAIL); }
pObjectInfo->TreeName = szToken; pObjectInfo->DisplayTreeName = szDisplayToken;
RRETURN(S_OK); }
HRESULT AddPortNumber(POBJECTINFO pObjectInfo, DWORD dwPort) { pObjectInfo->PortNumber = dwPort;
RRETURN(S_OK); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT SetType(POBJECTINFO pObjectInfo, DWORD dwToken) { pObjectInfo->ObjectType = dwToken; RRETURN(S_OK); }
void CLexer::SetAtDisabler( BOOL bFlag ) { _bAtDisabled = bFlag; }
BOOL CLexer::GetAtDisabler() { return(_bAtDisabled); }
void CLexer::SetFSlashDisabler( BOOL bFlag ) { _bFSlashDisabled = bFlag; }
BOOL CLexer::GetFSlashDisabler() { return(_bFSlashDisabled); }
void CLexer::SetExclaimnationDisabler( BOOL bFlag ) { _bExclaimDisabled = bFlag; }
BOOL CLexer::GetExclaimnationDisabler() { return(_bExclaimDisabled); }
HRESULT GetDisplayName( LPWSTR szName, LPWSTR *ppszDisplayName ) {
HRESULT hr = S_OK; DWORD len = 0; LPWSTR pch = szName; LPWSTR pszDisplayCh = NULL, pszDisplay = NULL;
BOOL fQuoteMode = FALSE; // TRUE means we're processing between
// quotation marks
BOOL fEscaped = FALSE; // TRUE means next one char to be
// processed should be treated as literal
if (!ppszDisplayName ) { RRETURN (E_INVALIDARG); }
*ppszDisplayName = NULL;
if (!szName) { RRETURN (S_OK); }
pch = szName;
//
// Parsing Algorithm:
//
// If this char follows an unescaped backslash:
// Treat as literal, treat next char regularly (set fEscaped = FALSE)
// Else, if we're between quotation marks:
// If we see a quotation mark, leave quote mode
// Else, treat as literal
// Else, if we're not between quote marks, and we see a quote mark:
// Enter quote mode
// Else, if we see a backslash (and we're not already in escape or quote
// mode):
// Treat next char as literal (set fEscaped = TRUE)
// Else, if we see a forward-slash (and we're not in escape or quote mode):
// We need to escape it by prefixing with a backslash
// Else:
// Do nothing, just a plain old character
// Go on to next character, and repeat
//
// Backslashes inside quotation marks are always treated as literals,
// since that is the definition of being inside quotation marks
//
while (*pch) { if (fEscaped) { fEscaped = FALSE; } else if (fQuoteMode) { if (*pch == L'"') { fQuoteMode = FALSE; } } else if (*pch == L'"') { fQuoteMode = TRUE; } else if (*pch == L'\\') { fEscaped = TRUE; } else if (*pch == L'/') { //
// include space for the escape char
// we'll need to add
//
len++; }
len++;
pch++; }
pszDisplay = (LPWSTR) AllocADsMem((len+1) * sizeof(WCHAR));
if (!pszDisplay) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
pch = szName; pszDisplayCh = pszDisplay;
fEscaped = FALSE; fQuoteMode = FALSE;
while (*pch) { if (fEscaped) { fEscaped = FALSE; } else if (fQuoteMode) { if (*pch == L'"') { fQuoteMode = FALSE; } } else if (*pch == L'"') { fQuoteMode = TRUE; } else if (*pch == L'\\') { fEscaped = TRUE; } else if (*pch == L'/') { //
// unescaped forward slash needs to get escaped
//
*pszDisplayCh++ = L'\\'; }
*pszDisplayCh++ = *pch;
pch++; } *pszDisplayCh = L'\0';
*ppszDisplayName = pszDisplay;
error:
RRETURN(hr);
}
//
// Convert an ADs path to LDAP path
//
HRESULT GetLDAPTypeName( LPWSTR szName, LPWSTR *ppszDisplayName ) { HRESULT hr = S_OK; DWORD len = 0; LPWSTR pch = NULL; LPWSTR pszDisplayCh = NULL; LPWSTR pszDisplay = NULL;
if (!ppszDisplayName ) { RRETURN(E_ADS_BAD_PATHNAME); }
*ppszDisplayName = NULL;
if (!szName) { RRETURN (E_ADS_BAD_PATHNAME); }
pch = szName;
//
// Parsing algorithm
// if this character is an escaped back slash
// if next character is a forward slash (we know this is a kind of ADsPath)
// we will remove the back slash
// accepts the current character
// goes on to process the next character
//
while (*pch) { if(*pch == L'\\') {
pch++; //
// If next character is /, we need to remove the escape character
//
if(*pch != L'/') { len++; } }
if(*pch) { len++; pch++; } }
pszDisplay = (LPWSTR) AllocADsMem((len+1) * sizeof(WCHAR));
if (!pszDisplay) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
pch = szName; pszDisplayCh = pszDisplay;
while (*pch) { if(*pch == L'\\') { //
// If next character is /, we need to remove the escape character
//
pch++; if(*pch != L'/') { *pszDisplayCh++ = L'\\'; } }
if(*pch) { *pszDisplayCh++ = *pch; pch++; } }
*pszDisplayCh = L'\0';
*ppszDisplayName = pszDisplay;
error:
RRETURN(hr); }
|