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.
 
 
 
 
 
 

425 lines
13 KiB

/*++
Copyright (C) 1999-2001 Microsoft Corporation
Module Name:
ASSOCQP.CPP
Abstract:
Association query parser
History:
raymcc 04-Jul-99 Created.
raymcc 14-Aug-99 Resubmit due to VSS problem.
--*/
#include "precomp.h"
#include <stdio.h>
#include <stdlib.h>
#include <wbemcore.h>
// ==========================================================================
// ASSOCIATION QUERY PARSER.
// ==========================================================================
#define QASSOC_TOK_STRING 101
#define QASSOC_TOK_IDENT 102
#define QASSOC_TOK_DOT 103
#define QASSOC_TOK_EQU 104
#define QASSOC_TOK_COLON 105
#define QASSOC_TOK_ERROR 1
#define QASSOC_TOK_EOF 0
#define ST_IDENT 13
#define ST_STRING 19
#define ST_QSTRING 26
#define ST_QSTRING_ESC 30
// DFA State Table for Assoc query tokens.
// =======================================
LexEl AssocQuery_LexTable[] =
{
// State First Last New state, Return tok, Instructions
// =======================================================================
/* 0 */ L'A', L'Z', ST_IDENT, 0, GLEX_ACCEPT,
/* 1 */ L'a', L'z', ST_IDENT, 0, GLEX_ACCEPT,
/* 2 */ L'_', GLEX_EMPTY, ST_IDENT, 0, GLEX_ACCEPT,
/* 3 */ L'{', GLEX_EMPTY, ST_STRING, 0, GLEX_CONSUME,
/* 4 */ L'=', GLEX_EMPTY, 0, QASSOC_TOK_EQU, GLEX_ACCEPT|GLEX_RETURN,
/* 5 */ L'.', GLEX_EMPTY, 0, QASSOC_TOK_DOT, GLEX_ACCEPT|GLEX_RETURN,
/* 6 */ L':', GLEX_EMPTY, 0, QASSOC_TOK_COLON, GLEX_ACCEPT|GLEX_RETURN,
/* 7 */ L' ', GLEX_EMPTY, 0, 0, GLEX_CONSUME,
/* 8 */ L'\t', GLEX_EMPTY, 0, 0, GLEX_CONSUME,
/* 9 */ L'\n', GLEX_EMPTY, 0, 0, GLEX_CONSUME|GLEX_LINEFEED,
/* 10 */ L'\r', GLEX_EMPTY, 0, 0, GLEX_CONSUME,
/* 11 */ 0, GLEX_EMPTY, 0, QASSOC_TOK_EOF, GLEX_CONSUME|GLEX_RETURN, // Note forced return
/* 12 */ GLEX_ANY, GLEX_EMPTY, 0, QASSOC_TOK_ERROR, GLEX_ACCEPT|GLEX_RETURN,
/* ST_IDENT */
/* 13 */ L'a', L'z', ST_IDENT, 0, GLEX_ACCEPT,
/* 14 */ L'A', L'Z', ST_IDENT, 0, GLEX_ACCEPT,
/* 15 */ L'_', GLEX_EMPTY, ST_IDENT, 0, GLEX_ACCEPT,
/* 16 */ L'0', L'9', ST_IDENT, 0, GLEX_ACCEPT,
/* 17 */ GLEX_ANY, GLEX_EMPTY, 0, QASSOC_TOK_IDENT, GLEX_PUSHBACK|GLEX_RETURN,
/* ST_STRING */
/* 18 */ 0, GLEX_EMPTY, 0, QASSOC_TOK_ERROR, GLEX_ACCEPT|GLEX_RETURN,
/* 19 */ L'"', GLEX_EMPTY, ST_QSTRING, 0, GLEX_ACCEPT,
/* 20 */ L'}', GLEX_EMPTY, 0, QASSOC_TOK_STRING, GLEX_RETURN,
/* 21 */ L' ', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
/* 22 */ L'\r', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
/* 23 */ L'\n', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
/* 24 */ L'\t', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
/* 25 */ GLEX_ANY, GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
/* ST_QSTRING */
/* 26 */ 0, GLEX_EMPTY, 0, QASSOC_TOK_ERROR, GLEX_ACCEPT|GLEX_RETURN,
/* 27 */ L'"', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
/* 28 */ L'\\', GLEX_EMPTY, ST_QSTRING_ESC, 0, GLEX_ACCEPT,
/* 29 */ GLEX_ANY, GLEX_EMPTY, ST_QSTRING, 0, GLEX_ACCEPT,
/* ST_QSTRING_ESC */
/* 30 */ GLEX_ANY, GLEX_EMPTY, ST_QSTRING, 0, GLEX_ACCEPT,
};
/*----------------------------------------------------
References of {objpath} where
ResultClass=XXX
Role=YYY
RequiredQualifier=QualifierName
ClassDefsOnly
Associators of {objpath} where
ResultClass=XXX
AssocClass=YYY
Role=PPP
RequiredQualifier=QualifierName
RequiredAssocQualifier=QualifierName
ClassDefsOnly
------------------------------------------------------*/
static BOOL ParseAssocQuery(
IN LPWSTR Query,
OUT LPWSTR *pTargetObj,
OUT LPWSTR *pResultClass,
OUT LPWSTR *pAssocClass,
OUT LPWSTR *pRole,
OUT LPWSTR *pResultRole,
OUT LPWSTR *pRequiredQualifier,
OUT LPWSTR *pRequiredAssocQualifier,
OUT DWORD *pdwQueryType
)
{
*pTargetObj = 0;
*pResultClass = 0;
*pAssocClass = 0;
*pRole = 0;
*pResultRole = 0;
*pRequiredQualifier = 0;
*pRequiredAssocQualifier = 0;
*pdwQueryType = 0;
// SEC:REVIEWED 2002-03-22 : Enforce max query limit length here with a wcslen in an EH
// ...
// SEC:REVIEWED 2002-03-22 : Needs EH around these contructors in case they throw
CTextLexSource src(Query);
CGenLexer Lexer(AssocQuery_LexTable, &src);
int nTok = 0;
BOOL bHadTokens = FALSE;
// Get first token.
// TBD: Check for out-of-memory
// =============================
nTok = Lexer.NextToken(); // SEC:REVIEWED 2002-03-22 : Assume lexer enforces limit
if (nTok != QASSOC_TOK_IDENT)
goto Error;
// REFERENCES or ASSOCIATORS
// =========================
if (wbem_wcsicmp(L"References", Lexer.GetTokenText()) == 0) // SEC:REVIEWED 2002-03-22 : This and following occurrences are ok
*pdwQueryType |= QUERY_TYPE_GETREFS;
else if (wbem_wcsicmp(L"Associators", Lexer.GetTokenText()) == 0)
*pdwQueryType |= QUERY_TYPE_GETASSOCS;
else
goto Error;
// OF
// ==
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_IDENT)
goto Error;
if (wbem_wcsicmp(L"of", Lexer.GetTokenText()) != 0)
goto Error;
// {OBJECTPATH}
// ============
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_STRING)
goto Error;
*pTargetObj = Macro_CloneLPWSTR(Lexer.GetTokenText());
if (NULL == *pTargetObj)
goto Error;
// WHERE
// =====
nTok = Lexer.NextToken();
if (nTok == QASSOC_TOK_EOF)
goto Completed;
if (nTok != QASSOC_TOK_IDENT)
goto Error;
if (wbem_wcsicmp(L"where", Lexer.GetTokenText()) != 0)
goto Error;
// Check for RESULTCLASS, ROLE, ASSOCCLASS, CLASSDEFSONLY,
// REQUIREDQUALIFIER, REQUIREDASSOCQUALIFIER
// ======================================================
for (;;)
{
nTok = Lexer.NextToken();
if (nTok == QASSOC_TOK_ERROR)
goto Error;
if (nTok == QASSOC_TOK_EOF)
{
if(!bHadTokens)
goto Error;
else
goto Completed;
}
if (nTok != QASSOC_TOK_IDENT)
goto Error;
bHadTokens = TRUE;
if (wbem_wcsicmp(L"RESULTCLASS", Lexer.GetTokenText()) == 0)
{
if(*pResultClass)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_EQU)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_IDENT)
goto Error;
*pResultClass = Macro_CloneLPWSTR(Lexer.GetTokenText());
}
else if (wbem_wcsicmp(L"ROLE", Lexer.GetTokenText()) == 0)
{
if(*pRole)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_EQU)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_IDENT)
goto Error;
*pRole = Macro_CloneLPWSTR(Lexer.GetTokenText());
}
else if (wbem_wcsicmp(L"RESULTROLE", Lexer.GetTokenText()) == 0)
{
if(*pResultRole)
goto Error;
if(*pdwQueryType & QUERY_TYPE_GETREFS)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_EQU)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_IDENT)
goto Error;
*pResultRole = Macro_CloneLPWSTR(Lexer.GetTokenText());
}
else if (wbem_wcsicmp(L"ASSOCCLASS", Lexer.GetTokenText()) == 0)
{
if(*pAssocClass)
goto Error;
if(*pdwQueryType & QUERY_TYPE_GETREFS)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_EQU)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_IDENT)
goto Error;
*pAssocClass = Macro_CloneLPWSTR(Lexer.GetTokenText());
}
else if (wbem_wcsicmp(L"REQUIREDQUALIFIER", Lexer.GetTokenText()) == 0)
{
if(*pRequiredQualifier)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_EQU)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_IDENT)
goto Error;
*pRequiredQualifier = Macro_CloneLPWSTR(Lexer.GetTokenText());
}
else if (wbem_wcsicmp(L"REQUIREDASSOCQUALIFIER", Lexer.GetTokenText()) == 0)
{
if(*pRequiredAssocQualifier)
goto Error;
if(*pdwQueryType & QUERY_TYPE_GETREFS)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_EQU)
goto Error;
nTok = Lexer.NextToken();
if (nTok != QASSOC_TOK_IDENT)
goto Error;
*pRequiredAssocQualifier = Macro_CloneLPWSTR(Lexer.GetTokenText());
}
else if (wbem_wcsicmp(L"CLASSDEFSONLY", Lexer.GetTokenText()) == 0)
{
*pdwQueryType |= QUERY_TYPE_CLASSDEFS_ONLY;
}
else if (wbem_wcsicmp(L"KEYSONLY", Lexer.GetTokenText()) == 0)
{
*pdwQueryType |= QUERY_TYPE_KEYSONLY;
}
else if (wbem_wcsicmp(L"SCHEMAONLY", Lexer.GetTokenText()) == 0)
{
*pdwQueryType |= QUERY_TYPE_SCHEMA_ONLY;
}
else
{
goto Error;
}
}
Completed:
if( (*pdwQueryType & QUERY_TYPE_SCHEMA_ONLY) &&
(*pdwQueryType & QUERY_TYPE_CLASSDEFS_ONLY))
{
goto Error;
}
return TRUE;
Error:
delete *pTargetObj;
delete *pResultClass;
delete *pAssocClass;
delete *pRole;
delete *pResultRole;
delete *pRequiredQualifier;
delete *pRequiredAssocQualifier;
*pTargetObj = 0;
*pResultClass = 0;
*pAssocClass = 0;
*pRole = 0;
*pResultRole = 0;
*pdwQueryType = 0;
*pRequiredQualifier = 0;
*pRequiredAssocQualifier = 0;
return FALSE;
}
//***************************************************************************
//
//***************************************************************************
CAssocQueryParser::CAssocQueryParser()
{
m_pszQueryText = 0;
m_pszTargetObjPath = 0;
m_pszResultClass = 0;
m_pszAssocClass= 0;
m_pszRole = 0;
m_pszResultRole = 0;
m_pszRequiredQual = 0;
m_pszRequiredAssocQual = 0;
m_dwType = 0;
m_pPath = 0;
}
//***************************************************************************
//
//***************************************************************************
CAssocQueryParser::~CAssocQueryParser()
{
delete m_pszQueryText;
delete m_pszTargetObjPath;
delete m_pszResultClass;
delete m_pszAssocClass;
delete m_pszRole;
delete m_pszResultRole;
delete m_pszRequiredQual;
delete m_pszRequiredAssocQual;
if (m_pPath) m_PathParser.Free(m_pPath);
}
//***************************************************************************
//
//***************************************************************************
HRESULT CAssocQueryParser::Parse(LPWSTR pszQuery)
{
if (pszQuery == NULL)
return WBEM_E_INVALID_QUERY;
// Clone the query text for debugging.
// ===================================
DUP_STRING_NEW(m_pszQueryText, pszQuery);
if (m_pszQueryText == NULL)
return WBEM_E_OUT_OF_MEMORY;
// Parse it.
// =========
BOOL bRes = ParseAssocQuery(
m_pszQueryText,
&m_pszTargetObjPath,
&m_pszResultClass,
&m_pszAssocClass,
&m_pszRole,
&m_pszResultRole,
&m_pszRequiredQual,
&m_pszRequiredAssocQual,
&m_dwType
);
if (bRes == FALSE)
return WBEM_E_INVALID_QUERY;
// Parse the object path.
// ======================
if (m_pszTargetObjPath)
{
int nStatus = m_PathParser.Parse(m_pszTargetObjPath, &m_pPath);
if (nStatus != 0)
return WBEM_E_INVALID_OBJECT_PATH;
}
return WBEM_S_NO_ERROR;
}