// ************************************************************************** // // Copyright (c) 2001 Microsoft Corporation, All Rights Reserved // // File: QueryParser.cpp // // Description: // WMI Query Parser Sample. // This sample shows how to use the Query Parser. It takes a query as a command // line argument and passes it off to the parser to be parsed and then uses various // functions to get pieces of the path. // // ************************************************************************** #define _WIN32_WINNT 0x0400 #include #include #include LPWSTR g_pQuery = 0; //*************************************************************************** // // DumpFeatureMasks // // Purpose: Outputs the mask in readable format // //*************************************************************************** void DumpFeatureMasks(ULONG mask1, ULONG mask2) { printf("Query Features:\n"); if (mask1 & WMIQ_RPNF_WHERE_CLAUSE_PRESENT) printf("WMIQ_RPNF_WHERE_CLAUSE_PRESENT\n"); if (mask1 & WMIQ_RPNF_QUERY_IS_CONJUNCTIVE) printf("WMIQ_RPNF_QUERY_IS_CONJUNCTIVE\n"); if (mask1 & WMIQ_RPNF_QUERY_IS_DISJUNCTIVE) printf("WMIQ_RPNF_QUERY_IS_DISJUNCTIVE\n"); if (mask1 & WMIQ_RPNF_PROJECTION) printf("WMIQ_RPNF_PROJECTION\n"); if (mask1 & WMIQ_RPNF_FEATURE_SELECT_STAR) printf("WMIQ_RPNF_FEATURE_SELECT_STAR\n"); if (mask1 & WMIQ_RPNF_EQUALITY_TESTS_ONLY) printf("WMIQ_RPNF_EQUALITY_TESTS_ONLY\n"); if (mask1 & WMIQ_RPNF_COUNT_STAR) printf("WMIQ_RPNF_COUNT_STAR\n"); if (mask1 & WMIQ_RPNF_QUALIFIED_NAMES_IN_SELECT) printf("WMIQ_RPNF_QUALIFIED_NAMES_IN_SELECT\n"); if (mask1 & WMIQ_RPNF_QUALIFIED_NAMES_IN_WHERE) printf("WMIQ_RPNF_QUALIFIED_NAMES_IN_WHERE\n"); if (mask1 & WMIQ_RPNF_PROP_TO_PROP_TESTS) printf("WMIQ_RPNF_PROP_TO_PROP_TESTS\n"); if (mask1 & WMIQ_RPNF_ORDER_BY) printf("WMIQ_RPNF_ORDER_BY\n"); if (mask1 & WMIQ_RPNF_ISA_USED) printf("WMIQ_RPNF_ISA_USED\n"); if (mask1 & WMIQ_RPNF_ISNOTA_USED) printf("WMIQ_RPNF_ISNOTA_USED\n"); if (mask1 & WMIQ_RPNF_GROUP_BY_HAVING) printf("WMIQ_RPNF_GROUP_BY_HAVING\n"); if (mask1 & WMIQ_RPNF_WITHIN_INTERVAL) printf("WMIQ_RPNF_WITHIN_INTERVAL\n"); if (mask1 & WMIQ_RPNF_WITHIN_AGGREGATE) printf("WMIQ_RPNF_WITHIN_AGGREGATE\n"); if (mask1 & WMIQ_RPNF_SYSPROP_CLASS) printf("WMIQ_RPNF_SYSPROP_CLASS\n"); if (mask1 & WMIQ_RPNF_REFERENCE_TESTS) printf("WMIQ_RPNF_REFERENCE_TESTS\n"); if (mask1 & WMIQ_RPNF_DATETIME_TESTS) printf("WMIQ_RPNF_DATETIME_TESTS\n"); if (mask1 & WMIQ_RPNF_ARRAY_ACCESS) printf("WMIQ_RPNF_ARRAY_ACCESS\n"); if (mask1 & WMIQ_RPNF_QUALIFIER_FILTER) printf("WMIQ_RPNF_QUALIFIER_FILTER\n"); if (mask1 & WMIQ_RPNF_SELECTED_FROM_PATH) printf("WMIQ_RPNF_SELECTED_FROM_PATH\n"); } //*************************************************************************** // // DumpSelectList // // Purpose: Lists the selected columns // //*************************************************************************** void DumpSelectList(ULONG uCount, SWbemQueryQualifiedName **pNames) { unsigned u; printf("----BEGIN SELECT CLAUSE---\n"); printf("Selected target columns/props = "); for (u = 0; u < uCount; u++) { SWbemQueryQualifiedName *p = pNames[u]; // Print out current name. // Note that we support qualified names, // like p1.a, p2.b, etc. // For simple cases, the m_uNameListSize is 1. // =========================================== for (unsigned u2 = 0; u2 < p->m_uNameListSize; u2++) { if (u2 > 0) printf("."); printf("%S", p->m_ppszNameList[u2]); } printf(", "); } printf("\n"); printf("---END SELECT CLAUSE-----\n"); } //*************************************************************************** // // DumpSubexpression // // Purpose: dumps out one of the subexpressions that make up the where clause // //*************************************************************************** void DumpSubexpression(SWbemRpnQueryToken *pTemp) { printf("---SUBEXPRESSION TOKEN---\n"); if (pTemp->m_uSubexpressionShape & WMIQ_RPN_LEFT_PROPERTY_NAME) { printf(" WMIQ_RPN_LEFT_PROPERTY_NAME\n"); } if (pTemp->m_uSubexpressionShape & WMIQ_RPN_RIGHT_PROPERTY_NAME) { printf(" WMIQ_RPN_RIGHT_PROPERTY_NAME\n"); } if (pTemp->m_uSubexpressionShape & WMIQ_RPN_CONST2) { printf(" WMIQ_RPN_CONST2\n"); } if (pTemp->m_uSubexpressionShape & WMIQ_RPN_CONST) { printf(" WMIQ_RPN_CONST\n"); } if (pTemp->m_uSubexpressionShape & WMIQ_RPN_RELOP) { printf(" WMIQ_RPN_RELOP\n"); } if (pTemp->m_uSubexpressionShape & WMIQ_RPN_LEFT_FUNCTION) { printf(" WMIQ_RPN_LEFT_FUNCTION\n"); } if (pTemp->m_uSubexpressionShape & WMIQ_RPN_RIGHT_FUNCTION) { printf(" WMIQ_RPN_RIGHT_FUNCTION\n"); } switch (pTemp->m_uOperator) { case WMIQ_RPN_OP_UNDEFINED: printf(" Operator (Invalid) WMIQ_RPN_OP_UNDEFINED\n"); break; case WMIQ_RPN_OP_EQ : printf(" Operator = (WMIQ_RPN_OP_EQ)\n"); break; case WMIQ_RPN_OP_NE : printf(" Operator != (WMIQ_RPN_OP_NE)\n"); break; case WMIQ_RPN_OP_GE : printf(" Operator >= (WMIQ_RPN_OP_GE)\n"); break; case WMIQ_RPN_OP_LE : printf(" Operator <= (WMIQ_RPN_OP_LE)\n"); break; case WMIQ_RPN_OP_LT : printf(" Operator < (WMIQ_RPN_OP_LT)\n"); break; case WMIQ_RPN_OP_GT : printf(" Operator > (WMIQ_RPN_OP_GT)\n"); break; case WMIQ_RPN_OP_LIKE : printf(" Operator LIKE (WMIQ_RPN_OP_LIKE)\n"); break; case WMIQ_RPN_OP_ISA : printf(" Operator ISA (WMIQ_RPN_OP_ISA)\n"); break; case WMIQ_RPN_OP_ISNOTA : printf(" Operator ISNOTA (WMIQ_RPN_OP_ISNOTA)\n"); break; default: printf(" Operator \n"); break; } // Dump identifiers (propety names) if (pTemp->m_pRightIdent) { printf(" Right side identifier = "); SWbemQueryQualifiedName *p = pTemp->m_pRightIdent; for (unsigned u = 0; u < p->m_uNameListSize; u++) { if (u > 0) printf("."); printf("%S", p->m_ppszNameList[u]); } printf("\n"); } if (pTemp->m_pLeftIdent) { printf(" Left side identifier = "); SWbemQueryQualifiedName *p = pTemp->m_pLeftIdent; for (unsigned u = 0; u < p->m_uNameListSize; u++) { if (u > 0) printf("."); printf("%S", p->m_ppszNameList[u]); } printf("\n"); } printf(" Apparent Type of Query Constant is "); switch(pTemp->m_uConstApparentType) { case VT_NULL: printf("VT_NULL"); break; case VT_I4: printf("VT_I4, Value = %d\n", pTemp->m_Const.m_lLongVal); break; case VT_UI4: printf("VT_UI4, Value = %u\n", pTemp->m_Const.m_uLongVal); break; case VT_BOOL: printf("VT_BOOL, Value = %d\n", pTemp->m_Const.m_bBoolVal); break; case VT_R8: printf("VT_R8, Value = %f\n", pTemp->m_Const.m_dblVal); break; case VT_LPWSTR: printf("VT_LPWSTR, Value = %S\n", pTemp->m_Const.m_pszStrVal); break; } printf(" Function name applied to Left Side = %S\n", pTemp->m_pszLeftFunc); printf(" Function name applied to Right Side = %S\n", pTemp->m_pszRightFunc); printf("----END SUBEXPRESSION TOKEN---\n"); } //*************************************************************************** // // DumpWhereClause // // Purpose: Dumps out the where clause // //*************************************************************************** void DumpWhereClause(ULONG uCount, SWbemRpnQueryToken **pWhere) { printf("---BEGIN WHERE CLAUSE---\n"); unsigned u; for (u = 0; u < uCount; u++) { SWbemRpnQueryToken *pTemp = pWhere[u]; switch(pTemp->m_uTokenType) { case WMIQ_RPN_TOKEN_EXPRESSION: DumpSubexpression(pTemp); break; case WMIQ_RPN_TOKEN_AND: printf(" Operator: AND\n"); break; case WMIQ_RPN_TOKEN_OR: printf(" Operator: OR\n"); break; case WMIQ_RPN_TOKEN_NOT: printf(" Operator: NOT\n"); default: printf(" Operator: INVALID\n"); } } printf("---END WHERE CLAUSE---\n"); } //*************************************************************************** // // DumpFromClause // // Purpose: Dumps out the from clause // //*************************************************************************** void DumpFromClause(SWbemRpnEncodedQuery *pQuery) { printf("---FROM clause---\n"); if (pQuery->m_uFromTargetType & WMIQ_RPN_FROM_PATH) { printf(" Selected from container/scope [%S]\n", pQuery->m_pszOptionalFromPath); } if (pQuery->m_uFromTargetType & WMIQ_RPN_FROM_UNARY) { printf(" Single class select = %S\n", pQuery->m_ppszFromList[0]); } else if (pQuery->m_uFromTargetType & WMIQ_RPN_FROM_CLASS_LIST) { for (unsigned u = 0; u < pQuery->m_uFromListSize; u++) { printf(" Selected class = %S\n", pQuery->m_ppszFromList[u]); } } else { printf(" No target classes selected; select ALL\n"); } printf("---END FROM clause\n"); } //*************************************************************************** // // DumpRpn // // Purpose: Mainly calls the other routines which dump out the specific parts // //*************************************************************************** void DumpRpn(SWbemRpnEncodedQuery *pRpn) { printf("------------RPN Encoded Query-----------------\n"); printf("RPN Version = %d\n", pRpn->m_uVersion); printf("RPN Token Type = %d\n", pRpn->m_uTokenType); printf("Total detected features = %d Feature Set = { ", pRpn->m_uDetectedArraySize); for (unsigned i = 0; i < pRpn->m_uDetectedArraySize; i++) printf("%d ", pRpn->m_puDetectedFeatures[i]); printf("}\n\n"); DumpFeatureMasks(pRpn->m_uParsedFeatureMask1, pRpn->m_uParsedFeatureMask2); DumpSelectList(pRpn->m_uSelectListSize, pRpn->m_ppSelectList); DumpFromClause(pRpn); DumpWhereClause(pRpn->m_uWhereClauseSize, pRpn->m_ppRpnWhereClause); } //*************************************************************************** // // TestQuery // // Purpose: Calls the parser to parse the query, and if all is well, calls // the other routines to dump out the results. // //*************************************************************************** void TestQuery(IWbemQuery *pQuery) { HRESULT hRes; ULONG uFeatures[] = { WMIQ_LF1_BASIC_SELECT, WMIQ_LF2_CLASS_NAME_IN_QUERY }; hRes = pQuery->SetLanguageFeatures(0, sizeof(uFeatures)/sizeof(ULONG), uFeatures); hRes = pQuery->Parse(L"SQL", g_pQuery, 0); if (FAILED(hRes)) { printf("Parse failed with error 0x%X\n", hRes); return; } SWbemRpnEncodedQuery *pRpn = 0; hRes = pQuery->GetAnalysis( WMIQ_ANALYSIS_RPN_SEQUENCE, 0, (LPVOID *) &pRpn ); if (SUCCEEDED(hRes)) { printf("\n\nGot RPN Output\n"); DumpRpn(pRpn); pQuery->FreeMemory(pRpn); } } //*************************************************************************** // // main // // Purpose: Entry point for the application. // //*************************************************************************** void main(int argc, char *argv[]) { if (argc < 2) { printf("\nusage: QueryParser \"query\""); printf("\nexample; c:>QueryParser \"select RowA, RowB from tableName where propz=3\""); return; } printf("Query = %s\n", argv[1]); wchar_t buf[512]; swprintf(buf, L"%S", argv[1]); g_pQuery = buf; // Standard COM initialization stuff. // =================================== CoInitializeEx(0, COINIT_MULTITHREADED); // Get the QueryParser object call the test code // ============================================= IWbemQuery *pQuery = 0; DWORD dwRes = CoCreateInstance(CLSID_WbemQuery, 0, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (LPVOID *) &pQuery); if (dwRes != S_OK) printf("Failed to create Query object.\n"); else { printf("Got a query parser object\n"); TestQuery(pQuery); pQuery->Release(); } CoUninitialize(); }