2726 lines
		
	
	
		
			88 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			2726 lines
		
	
	
		
			88 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // **************************************************************************
 | |
| 
 | |
| //Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved 
 | |
| //
 | |
| // File:  wbemdump.cpp
 | |
| //
 | |
| // Description:
 | |
| //    dumps the contents of the cimom repository
 | |
| //    see wbemdump /? for command line switches
 | |
| //
 | |
| // History:
 | |
| //
 | |
| // **************************************************************************
 | |
| 
 | |
| #pragma warning(disable:4201)  // nonstandard extension nameless struct (used in windows.h)
 | |
| #pragma warning(disable:4514)  // unreferenced inline function has been removed (used in windows.h)
 | |
| #pragma warning(disable:4800)  // forcing value to bool 'true' or 'false' (performance warning)
 | |
| #pragma warning(disable:4100)  // unreferenced formal parameter warning
 | |
| #pragma warning(disable:4701)  // local variable may be used without having been initialized
 | |
| #pragma warning(disable:4710)  // function not inlined
 | |
| 
 | |
| #define TIMEOUT 150
 | |
| #define UNICODE_SIGNATURE "\xff\xfe"
 | |
| #define _WIN32_DCOM
 | |
| #define WIN32_LEAN_AND_MEAN 1
 | |
| #define UNREFERENCED(x)
 | |
| 
 | |
| //#include <windows.h>  not needed since it is re-included in wbemidl.h
 | |
| #include <wbemidl.h>     // wbem interface declarations
 | |
| #include <stdio.h>      // fprintf
 | |
| #include <locale.h>
 | |
| #include <sys/timeb.h>
 | |
| #include <wbemsec.h>
 | |
| #include <utillib.h>
 | |
| #include "wbemdump.h"
 | |
| 
 | |
| // Function declarations
 | |
| void DoIndent();
 | |
| BOOL CtrlHandler(DWORD fdwCtrlType);
 | |
| HRESULT ShowInstancesSync(IWbemServices *pIWbemServices, IEnumWbemClassObject *IEnumWbemClassObject, DWORD &dwCount, LPCWSTR pwszClassName);
 | |
| void EnumClasses(IWbemServices *pIWbemServices, LPCWSTR pwcsClass);
 | |
| void EnumClassesSync(IWbemServices *pIWbemServices, LPCWSTR pwcsClass);
 | |
| void EnumInstances(IWbemServices *pIWbemServices, LPCWSTR pwcsClassName );
 | |
| void EnumNamespaces(IWbemServices *pIWbemServices, LPCWSTR pwcsClassName);
 | |
| WCHAR *EnumProperties(IWbemClassObject *pIWbemClassObject);
 | |
| void Init(IWbemServices **ppIWbemServices, LPCWSTR pNamespace);
 | |
| IWbemClassObject *GetObj(IWbemServices *pIWbemServices, IWbemClassObject *pIWbemClassObject);
 | |
| DWORD ProcessCommandLine(int argc, wchar_t *argv[]);
 | |
| void ExecuteQuery(IWbemServices *pIWbemServices, LPCWSTR pwcsQueryLanguage, LPCWSTR pwcsQuery);
 | |
| void PrintMof(IWbemClassObject *pIWbemClassObject);
 | |
| void ShowClass(IWbemServices *pIWbemServices, IWbemClassObject *pIWbemClassObject);
 | |
| BOOL CheckQualifiers(IWbemClassObject *pIWbemClassObject);
 | |
| void ShowInstance(IWbemServices *pIWbemServices, IWbemClassObject *pIWbemClassObject);
 | |
| void CheckAssocEndPoints(IWbemServices *pIWbemServices, IWbemClassObject *pIWbemClassObject);
 | |
| int __cdecl BstrCmp(const void *arg1,const void *arg2);
 | |
| WCHAR *EscapeChars(LPCWSTR szInBuf);
 | |
| WCHAR *MyValueToString(VARIANT *pv);
 | |
| void ShowInstanceHeader(LPCWSTR pwcsClassName);
 | |
| void ResetGlobalFlags();
 | |
| bool ParseCommandLine(int *numargs, wchar_t **p);
 | |
| static void __cdecl wparse_cmdline (
 | |
|                                     WCHAR *cmdstart,
 | |
|                                     WCHAR **argv,
 | |
|                                     WCHAR *args,
 | |
|                                     int *numargs,
 | |
|                                     int *numchars
 | |
|                                     );
 | |
| 
 | |
| // Global flags
 | |
| BOOL g_bShowSystem = FALSE;     // Show system objects
 | |
| BOOL g_bShowSystem1 = FALSE;    // Show system objects except __SERVER or __PATH
 | |
| BOOL g_bShowInstance = FALSE;   // Show instance from ObjectPath
 | |
| BOOL g_bShowProperties = TRUE;  // Show properties
 | |
| BOOL g_bRecurseClass = FALSE;   // Recurse down class tree
 | |
| BOOL g_bRecurseNS = FALSE;      // Recurse down ns's
 | |
| BOOL g_bCheckGet = FALSE;       // Check the GetObject function
 | |
| BOOL g_bCheckAssoc = FALSE;     // Check Association endpoints
 | |
| BOOL g_bDoQuery = FALSE;        // Run a query instead of doing an enum
 | |
| BOOL g_bClassMofs = FALSE;      // Show mofs for classes
 | |
| BOOL g_bInstanceMofs = FALSE;   // Show mofs for instances
 | |
| BOOL g_bMofTemplate = FALSE;    // Show instance mof templates
 | |
| BOOL g_bUnicodeCmdFile = FALSE; // Whether the cmd file is unicode
 | |
| BOOL g_bTime1 = FALSE;          // Show timings for /Q queries
 | |
| BOOL g_bTime2 = FALSE;          // Alternate show timings for /Q queries
 | |
| BOOL g_bWarningContinue = FALSE; // Show warning and continue
 | |
| BOOL g_bWarning = FALSE;        // Show warning and ask
 | |
| BOOL g_bASync = FALSE;          // Use Async functions for instances
 | |
| 
 | |
| volatile bool g_bExit = false;           // Control C handling
 | |
| long g_lSFlags = 0;              // Security flags for ConnectServer
 | |
| long g_lImpFlag = RPC_C_IMP_LEVEL_IMPERSONATE;            // Impersonation level (-1 means use default)
 | |
| long g_lAuthFlag = -1;           // Impersonation level (-1 means use default)
 | |
| long g_lEFlags = 0;              // Flags for CreateXxxEnum
 | |
| long g_lGFlags = 0;              // Flags for GetObject
 | |
| DWORD g_dwErrorFlags = 0;          // Flags for error printing
 | |
| 
 | |
| //
 | |
| FILE *g_fOut = NULL;          // Handle for unicode file
 | |
| FILE *g_fCmdFile = NULL;      // Handle for command file
 | |
| 
 | |
| LPCWSTR g_pwcsNewLine = L"\n";    // Used to delimit lines
 | |
| LPCWSTR g_pwcsNamespace = NULL;   // NameSpace to start from
 | |
| LPCWSTR g_pwcsObjectPath = NULL;  // ObjectPath to show
 | |
| LPCWSTR g_pwcsQuery = NULL;        // Query (for /q commands)
 | |
| LPWSTR g_pwcsUserID = NULL;      // Userid for ConnectServer
 | |
| LPWSTR g_pwcsPassword = NULL;    // PW for ConnectServer
 | |
| LPWSTR g_pwcsAuthority = NULL;   // Authority for ConnectServer
 | |
| LPCWSTR g_pwcsLocale = NULL;      // Locale for ConnectServer
 | |
| BSTR g_bstrQualifierName = NULL; // Class Qualifier to filter on
 | |
| BSTR g_bstrQualifierValue = NULL; // Class Qualifier value to filter on
 | |
| DWORD g_dwLoopCnt = 1;           // Loop count
 | |
| DWORD g_dwIndent = 0;              // Current indention level
 | |
| 
 | |
| IWbemContext *g_pContext;      // Pointer to ClassContext object
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| // wmain - used wmain since the command line parameters come in as wchar_t
 | |
| //
 | |
| //***************************************************************************
 | |
| extern "C" int __cdecl wmain(int argc, wchar_t *argv[])
 | |
| {
 | |
|     setlocale(LC_ALL, "");
 | |
| 
 | |
|     // Init Com
 | |
|     int iRet = 0;
 | |
| 
 | |
|     SCODE sc = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 | |
|     if (sc != S_OK)
 | |
|     {
 | |
|         PrintErrorAndExit("OleInitialize Failed", sc, g_dwErrorFlags);  //exits program
 | |
|     }
 | |
| 
 | |
|     sc = CoInitializeSecurity(NULL, -1, NULL, NULL,
 | |
|         RPC_C_AUTHN_LEVEL_DEFAULT,
 | |
|         RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
 | |
| 
 | |
|     if (ProcessCommandLine(argc, argv) == S_OK)
 | |
|     {
 | |
|         // Catch control-c
 | |
|         SetConsoleCtrlHandler(
 | |
|                 (PHANDLER_ROUTINE) CtrlHandler,  // handler function
 | |
|                 TRUE);
 | |
| 
 | |
|         IWbemServicesPtr pIWbemServices;
 | |
|         Init(&pIWbemServices, g_pwcsNamespace);        // Connect to wbem
 | |
| 
 | |
|         try
 | |
|         {
 | |
|             if (g_fCmdFile)
 | |
|             {
 | |
|                 wchar_t *largv;
 | |
|                 int largc;
 | |
| 
 | |
|                 while (!feof(g_fCmdFile))
 | |
|                 {
 | |
|                     ResetGlobalFlags();
 | |
| 
 | |
|                     if (ParseCommandLine(&largc, &largv))
 | |
|                     {
 | |
|                         ProcessCommandLine(largc, (wchar_t **)largv);
 | |
|                         if (g_bDoQuery)
 | |
|                         {
 | |
|                             ExecuteQuery(pIWbemServices, g_pwcsObjectPath, g_pwcsQuery);
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             EnumNamespaces(pIWbemServices, g_pwcsObjectPath);   // Enumerate Namespaces
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (g_bDoQuery)
 | |
|                 {
 | |
|                     ExecuteQuery(pIWbemServices, g_pwcsObjectPath, g_pwcsQuery);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     EnumNamespaces(pIWbemServices, g_pwcsObjectPath);   // Enumerate Namespaces
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         catch ( ... )
 | |
|         {
 | |
|             iRet = 1;
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         iRet = 1;
 | |
|     }
 | |
| 
 | |
|     // Wrapup and exit
 | |
|     if (g_fOut)
 | |
|     {
 | |
|         fclose(g_fOut);
 | |
|     }
 | |
| 
 | |
|     if (g_fCmdFile)
 | |
|     {
 | |
|         fclose(g_fCmdFile);
 | |
|     }
 | |
| 
 | |
|     if (g_bstrQualifierName != NULL)
 | |
|     {
 | |
|         SysFreeString(g_bstrQualifierName);
 | |
|     }
 | |
| 
 | |
|     if (g_bstrQualifierValue != NULL)
 | |
|     {
 | |
|         SysFreeString(g_bstrQualifierValue);
 | |
|     }
 | |
| 
 | |
|     if (g_pContext != NULL)
 | |
|     {
 | |
|         g_pContext->Release();
 | |
|     }
 | |
| 
 | |
|     CoUninitialize();
 | |
| 
 | |
|     return iRet;
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| // Function:   Init
 | |
| //
 | |
| // Purpose:   1 - Create an instance of the WbemLocator interface
 | |
| //            2 - Use the pointer returned in step two to connect to
 | |
| //                the server using the specified namespace.
 | |
| //***************************************************************************
 | |
| void Init(IWbemServices **ppIWbemServices, LPCWSTR pNamespace)
 | |
| {
 | |
|     SCODE sc;
 | |
| 
 | |
|     // Use the IWbemLocatorEx?  Or IWbemLocator?
 | |
|     IWbemLocatorPtr pIWbemLocator;
 | |
| 
 | |
|     sc = CoCreateInstance(CLSID_WbemLocator,
 | |
|         NULL,
 | |
|         CLSCTX_INPROC_SERVER,
 | |
|         IID_IWbemLocator,
 | |
|         (LPVOID *) &pIWbemLocator);
 | |
| 
 | |
|     if (sc != S_OK)
 | |
|     {
 | |
|         PrintErrorAndExit("Failed to create IWbemLocator object", sc, g_dwErrorFlags); // exits program
 | |
|     }
 | |
| 
 | |
|     sc = pIWbemLocator->ConnectServer(
 | |
| 
 | |
|             bstr_t(pNamespace),  // Namespace
 | |
|             bstr_t(g_pwcsUserID),          // Userid
 | |
|             bstr_t(g_pwcsPassword),        // PW
 | |
|             bstr_t(g_pwcsLocale),          // Locale
 | |
|             g_lSFlags,                       // flags
 | |
|             g_pwcsAuthority,                 // Authority
 | |
|             g_pContext,                      // Context
 | |
|             ppIWbemServices
 | |
|         );
 | |
| 
 | |
|     if (sc != WBEM_NO_ERROR)
 | |
|     {
 | |
|         PrintErrorAndExit("Connect failed", sc, g_dwErrorFlags); //exits program
 | |
|     }
 | |
| 
 | |
|     DWORD dwAuthLevel, dwImpLevel;
 | |
|     sc = GetAuthImp(*ppIWbemServices, &dwAuthLevel, &dwImpLevel);
 | |
|     if (sc != S_OK)
 | |
|     {
 | |
|         PrintErrorAndExit("GetAuthImp Failed on ConnectServer", sc, g_dwErrorFlags);
 | |
|     }
 | |
| 
 | |
|     if (g_lImpFlag != -1)
 | |
|     {
 | |
|         dwImpLevel = g_lImpFlag;
 | |
|     }
 | |
| 
 | |
|     if (g_lAuthFlag != -1)
 | |
|     {
 | |
|         dwAuthLevel = g_lAuthFlag;
 | |
|     }
 | |
| 
 | |
|     sc = SetInterfaceSecurity(*ppIWbemServices, g_pwcsAuthority, g_pwcsUserID, g_pwcsPassword, dwAuthLevel, dwImpLevel);
 | |
|     if (sc != S_OK)
 | |
|     {
 | |
|         PrintErrorAndExit("SetInterfaceSecurity Failed on ConnectServer", sc, g_dwErrorFlags);
 | |
|     }
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| // Function:   EnumClasses
 | |
| //
 | |
| // Purpose:   Using either the sync or async CreateClassEnum call, walk
 | |
| //            the classes.
 | |
| //***************************************************************************
 | |
| void EnumClasses(IWbemServices *pIWbemServices, LPCWSTR pwcsClass)
 | |
| {
 | |
|     if (!g_bASync)
 | |
|     {
 | |
|         EnumClassesSync(pIWbemServices, pwcsClass);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         ClassQuerySinkPtr pMySink(new ClassQuerySink(pIWbemServices), false);
 | |
| 
 | |
|         SCODE sc = pIWbemServices->CreateClassEnumAsync(
 | |
| 
 | |
|                 bstr_t(pwcsClass),
 | |
|                 WBEM_FLAG_SHALLOW | g_lEFlags,
 | |
|                 g_pContext,
 | |
|                 pMySink
 | |
|             );
 | |
| 
 | |
|         if (sc != WBEM_NO_ERROR)
 | |
|         {
 | |
|             PrintErrorAndExit("Could not create Class enumerator", sc, g_dwErrorFlags);  //Exits program
 | |
|         }
 | |
| 
 | |
|         do
 | |
|         {
 | |
|             sc = WaitForSingleObject(pMySink->GetEvent(), TIMEOUT);
 | |
|             if (g_bExit)
 | |
|             {
 | |
|                 sc = pIWbemServices->CancelAsyncCall(pMySink);
 | |
|                 throw 1;
 | |
|             }
 | |
|         } while (sc == WAIT_TIMEOUT);
 | |
| 
 | |
|         sc = pMySink->GetResult();
 | |
|         if (sc != WBEM_NO_ERROR)
 | |
|         {
 | |
|             PrintErrorAndExit("Could not enum instances", sc, g_dwErrorFlags);  //Exits program
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   EnumClassesSync
 | |
| // Purpose:    Used by the Sync version of walking classes
 | |
| //*****************************************************************************
 | |
| void EnumClassesSync(IWbemServices *pIWbemServices, LPCWSTR pwcsClass)
 | |
| {
 | |
|     IEnumWbemClassObjectPtr pIEnumWbemClassObject;
 | |
| 
 | |
|     // Create an enumeration of all subclasses of pwcsClass
 | |
|     SCODE sc = pIWbemServices->CreateClassEnum(
 | |
| 
 | |
|             bstr_t(pwcsClass),
 | |
|             WBEM_FLAG_SHALLOW | g_lEFlags,
 | |
|             g_pContext,
 | |
|             &pIEnumWbemClassObject
 | |
|         );
 | |
| 
 | |
|     if (sc != WBEM_NO_ERROR)
 | |
|     {
 | |
|         PrintErrorAndExit("Could not create Class enumerator", sc, g_dwErrorFlags);  //Exits program
 | |
|     }
 | |
| 
 | |
|     DWORD dwAuthLevel, dwImpLevel;
 | |
|     sc = GetAuthImp(pIWbemServices, &dwAuthLevel, &dwImpLevel);
 | |
|     if (sc != S_OK)
 | |
|     {
 | |
|         PrintErrorAndExit("GetAuthImp Failed on CreateClassEnum", sc, g_dwErrorFlags);
 | |
|     }
 | |
| 
 | |
|     if (g_lImpFlag != -1)
 | |
|     {
 | |
|         dwImpLevel = g_lImpFlag;
 | |
|     }
 | |
| 
 | |
|     if (g_lAuthFlag != -1)
 | |
|     {
 | |
|         dwAuthLevel = g_lAuthFlag;
 | |
|     }
 | |
| 
 | |
|     sc = SetInterfaceSecurity(pIEnumWbemClassObject, g_pwcsAuthority, g_pwcsUserID, g_pwcsPassword, dwAuthLevel, dwImpLevel);
 | |
|     if (sc != S_OK)
 | |
|     {
 | |
|         PrintErrorAndExit("SetInterfaceSecurity Failed on CreateClassEnum", sc, g_dwErrorFlags);
 | |
|     }
 | |
| 
 | |
|     ULONG uReturned;
 | |
|     IWbemClassObjectPtr pIWbemClassObject;
 | |
| 
 | |
|     do
 | |
|     {
 | |
|         do
 | |
|         {
 | |
|             sc = pIEnumWbemClassObject->Next(
 | |
| 
 | |
|                     TIMEOUT,
 | |
|                     1,
 | |
|                     &pIWbemClassObject,
 | |
|                     &uReturned
 | |
|                 );
 | |
| 
 | |
|             if (g_bExit)
 | |
|             {
 | |
|                 throw 1;
 | |
|             }
 | |
|         } while (sc == WBEM_S_TIMEDOUT);
 | |
| 
 | |
|         if (sc == S_OK)
 | |
|         {
 | |
|             ShowClass(pIWbemServices, pIWbemClassObject);
 | |
|         }
 | |
|     } while (sc == S_OK);
 | |
| 
 | |
|     // Make sure we ended on a positive note
 | |
|     if (sc != S_FALSE)
 | |
|     {
 | |
|         PrintErrorAndExit("Could not get next class", sc, g_dwErrorFlags);  //Exits program
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   ShowClass
 | |
| // Purpose:    Calls the appropriate functions to show the passed in class
 | |
| // Note:       This routine calls EnumClasses, which leads to recursion
 | |
| //*****************************************************************************
 | |
| void ShowClass(IWbemServices *pIWbemServices, IWbemClassObject *pIWbemClassObject)
 | |
| {
 | |
|     variant_t varString;
 | |
| 
 | |
|     // Get the __class property
 | |
|     SCODE sc = pIWbemClassObject->Get(CLASSPROP, 0L, &varString, NULL, NULL);
 | |
|     if (sc != WBEM_NO_ERROR)
 | |
|     {
 | |
|         PrintErrorAndExit("Could not get __Class property for class", sc, g_dwErrorFlags);  // Exits program
 | |
|     }
 | |
| 
 | |
|     // we are showing system objs or this is not a system obj
 | |
|     if ((g_bShowSystem) || (wcsncmp(V_BSTR(&varString), SYSTEMPREFIX, 2) != 0))
 | |
|     {
 | |
|         if (CheckQualifiers(pIWbemClassObject))
 | |
|         {
 | |
|             // Either show the class mof, or show the instances
 | |
|             if (g_bClassMofs)
 | |
|             {
 | |
|                 PrintMof(pIWbemClassObject);
 | |
|                 if (g_bInstanceMofs)
 | |
|                 {
 | |
|                     EnumInstances(pIWbemServices, V_BSTR(&varString));
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 EnumInstances(pIWbemServices, V_BSTR(&varString));
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // If we are supposed to recurse
 | |
|     if (g_bRecurseClass)
 | |
|     {
 | |
|         if ((!g_bMofTemplate) && (g_bstrQualifierName == NULL))
 | |
|         {
 | |
|             g_dwIndent++;  // Increase indention level
 | |
|         }
 | |
| 
 | |
|         EnumClasses(pIWbemServices, V_BSTR(&varString));  // Enumerate all classes under this class
 | |
|         if ((!g_bMofTemplate) && (g_bstrQualifierName == NULL))
 | |
|         {
 | |
|             g_dwIndent--;  // Decrease indention level
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   EnumInstances
 | |
| // Purpose:    Enumerates all instances of the class passed in pwcsClassName
 | |
| //             and calls EnumProperties with each one.
 | |
| // Note:       Shows instances in one of four ways.
 | |
| //             1) Show the instance mof
 | |
| //             2) Show the instance values
 | |
| //             3) Show the wbemdump command line needed to dump this instance
 | |
| //             4) Show a template instance mof
 | |
| //*****************************************************************************
 | |
| void EnumInstances(IWbemServices *pIWbemServices, LPCWSTR pwcsClassName)
 | |
| {
 | |
|     SCODE sc;
 | |
| 
 | |
|     if (g_bMofTemplate)
 | |
|     {
 | |
|         IWbemClassObjectPtr pIWbemClassObject;
 | |
|         IWbemClassObjectPtr clObject;
 | |
| 
 | |
|         // For a template, all I need is a blank instance, so get the object...
 | |
|         sc = pIWbemServices->GetObject(
 | |
| 
 | |
|                 bstr_t(pwcsClassName),
 | |
|                 g_lGFlags,
 | |
|                 g_pContext,
 | |
|                 &pIWbemClassObject,
 | |
|                 NULL
 | |
|             );
 | |
| 
 | |
|         if (sc != WBEM_NO_ERROR)
 | |
|         {
 | |
|             PrintErrorAndExit("Failed to GetObject in EnumInstances", sc, g_dwErrorFlags);
 | |
|         }
 | |
| 
 | |
|         // ... And spawn a blank one
 | |
|         sc = pIWbemClassObject->SpawnInstance(0L, &clObject);
 | |
| 
 | |
|         if (sc != WBEM_NO_ERROR)
 | |
|         {
 | |
|             PrintErrorAndExit("Failed to SpawnInstance in EnumInstances", sc, g_dwErrorFlags);
 | |
|         }
 | |
| 
 | |
|         // Now, print the properties
 | |
|         ShowInstance(pIWbemServices, clObject);
 | |
| 
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         // Put this here so we can see what class we were
 | |
|         // working on if we get stuck.
 | |
|         ShowInstanceHeader(pwcsClassName);
 | |
| 
 | |
|         if (g_bShowProperties)
 | |
|         {
 | |
|             IEnumWbemClassObjectPtr IEnumWbemClassObject;
 | |
|             InstanceQuerySinkPtr pMySink;
 | |
| 
 | |
|             struct _timeb start, finish;
 | |
|             LARGE_INTEGER freq, start2;
 | |
|             QueryPerformanceFrequency(&freq);
 | |
| 			
 | |
| 
 | |
|             for (DWORD dwLoop = 0; dwLoop < g_dwLoopCnt; dwLoop++)
 | |
|             {
 | |
|                 if (g_bTime1)
 | |
|                 {
 | |
|                     _ftime(&start);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     memset(&start, 0, sizeof(start));
 | |
|                 }
 | |
| 
 | |
|                 if (!g_bTime2)
 | |
|                 {
 | |
|                     start2.QuadPart = 0;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     QueryPerformanceCounter(&start2);
 | |
|                 }
 | |
| 
 | |
|                 if (!g_bASync)
 | |
|                 {
 | |
|                     // Create the enum
 | |
|                     sc = pIWbemServices->CreateInstanceEnum(
 | |
| 
 | |
|                             bstr_t(pwcsClassName), // with this name
 | |
|                             WBEM_FLAG_SHALLOW | g_lEFlags,
 | |
|                             g_pContext,
 | |
|                             &IEnumWbemClassObject    // using this enumerator
 | |
|                         );
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     pMySink.Attach(new InstanceQuerySink(pIWbemServices, pwcsClassName));
 | |
|                     sc = pIWbemServices->CreateInstanceEnumAsync(
 | |
| 
 | |
|                             bstr_t(pwcsClassName), // with this name
 | |
|                             WBEM_FLAG_SHALLOW | g_lEFlags,
 | |
|                             g_pContext,
 | |
|                             pMySink
 | |
|                         );
 | |
|                 }
 | |
| 
 | |
|                 // If we are doing timings
 | |
|                 if (g_bTime1)
 | |
|                 {
 | |
|                     _ftime(&finish);
 | |
|                     fprintf(stdout, "CreateInstanceEnum: %6.4f seconds.\n", difftime(finish, start));
 | |
|                 }
 | |
|                 if (g_bTime2)
 | |
|                 {
 | |
|                     LARGE_INTEGER finish2;
 | |
|                     QueryPerformanceCounter(&finish2);
 | |
|                     fprintf(stdout, "CreateInstanceEnum: %I64d (%6.4f)\n", finish2.QuadPart - start2.QuadPart, (double)(finish2.QuadPart - start2.QuadPart)/freq.QuadPart);
 | |
|                 }
 | |
| 
 | |
|                 if (sc == WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     // If we are doing timings
 | |
|                     if (g_bTime1)
 | |
|                     {
 | |
|                         _ftime(&start);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         memset(&start, 0, sizeof(start));
 | |
|                     }
 | |
| 
 | |
|                     if (!g_bTime2)
 | |
|                     {
 | |
|                         start2.QuadPart = 0;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         QueryPerformanceCounter(&start2);
 | |
|                     }
 | |
| 
 | |
|                     DWORD dwCount = 0;
 | |
| 
 | |
|                     if (!g_bASync)
 | |
|                     {
 | |
|                         sc = ShowInstancesSync(pIWbemServices, IEnumWbemClassObject, dwCount, pwcsClassName);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         do
 | |
|                         {
 | |
|                             sc = WaitForSingleObject(pMySink->GetEvent(), TIMEOUT);
 | |
|                             if (g_bExit)
 | |
|                             {
 | |
|                                 sc = pIWbemServices->CancelAsyncCall(pMySink);
 | |
|                                 throw 1;
 | |
|                             }
 | |
|                         } while (sc == WAIT_TIMEOUT);
 | |
| 
 | |
|                         dwCount = pMySink->GetCount();
 | |
|                         sc = pMySink->GetResult();
 | |
|                         if (sc == WBEM_S_NO_ERROR)
 | |
|                         {
 | |
|                             sc = S_FALSE;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     // If we are doing timings
 | |
|                     if (g_bTime1)
 | |
|                     {
 | |
|                         _ftime(&finish);
 | |
|                         fprintf(stdout, "ShowInstances: %6.4f seconds, %d instances.\n", difftime(finish, start), dwCount);
 | |
|                     }
 | |
| 
 | |
|                     if (g_bTime2)
 | |
|                     {
 | |
|                         LARGE_INTEGER finish2;
 | |
|                         QueryPerformanceCounter(&finish2);
 | |
|                         fprintf(stdout, "ShowInstances: %I64d (%6.4f), %d instances.\n", finish2.QuadPart - start2.QuadPart, (double)(finish2.QuadPart - start2.QuadPart)/freq.QuadPart, dwCount);
 | |
|                     }
 | |
| 
 | |
|                     // Make sure we ended on a positive note
 | |
|                     if (sc != S_FALSE)
 | |
|                     {
 | |
|                         PrintErrorAndExit("Could not get next instance", sc, g_dwErrorFlags);  //Exits program
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     PrintErrorAndExit("Couldn't create instance enum", sc, g_dwErrorFlags);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   EnumProperties
 | |
| // Purpose:    Shows all property names of specified class
 | |
| //*****************************************************************************
 | |
| WCHAR *EnumProperties(IWbemClassObject *pIWbemClassObject)
 | |
| {
 | |
|     SCODE  sc;
 | |
|     SAFEARRAY *psaNames = NULL;
 | |
|     long lLower, lUpper, lCount;
 | |
|     IWbemQualifierSetPtr pQualSet;
 | |
|     MyString clMyBuff;
 | |
| 
 | |
|     // Get the property names
 | |
|     if (g_bShowSystem)
 | |
|     {
 | |
|         sc = pIWbemClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS, NULL, &psaNames);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         sc = pIWbemClassObject->GetNames(NULL, WBEM_FLAG_NONSYSTEM_ONLY, NULL, &psaNames);
 | |
|     }
 | |
| 
 | |
|     if (sc != WBEM_NO_ERROR)
 | |
|     {
 | |
|         PrintErrorAndExit("Couldn't GetNames", sc, g_dwErrorFlags); // Exits program
 | |
|     }
 | |
| 
 | |
|     // Get the upper and lower bounds of the Names array
 | |
|     sc = SafeArrayGetLBound(psaNames, 1, &lLower);
 | |
|     if (S_OK != sc)
 | |
|     {
 | |
|         PrintErrorAndExit("Couldn't get safe array lbound", sc, g_dwErrorFlags);  //Exits program
 | |
|     }
 | |
| 
 | |
|     sc = SafeArrayGetUBound(psaNames, 1, &lUpper);
 | |
|     if (S_OK != sc)
 | |
|     {
 | |
|         PrintErrorAndExit("Couldn't get safe array ubound", sc, g_dwErrorFlags);  //Exits program
 | |
|     }
 | |
| 
 | |
|     // Sort the array
 | |
|     qsort(psaNames->pvData, lUpper - lLower + 1, sizeof(BSTR), BstrCmp);
 | |
| 
 | |
|     // For an instance template, print the 'INSTANCE OF <CLASS>' header
 | |
|     if (g_bMofTemplate)
 | |
|     {
 | |
|         variant_t varString;
 | |
| 
 | |
|         sc = pIWbemClassObject->Get(CLASSPROP, 0L, &varString, NULL, NULL);
 | |
|         if (S_OK != sc)
 | |
|         {
 | |
|             PrintErrorAndExit("Couldn't get class property in enumproperties", sc, g_dwErrorFlags);  //Exits program
 | |
|         }
 | |
| 
 | |
|         for (DWORD x=0; x < g_dwIndent; x++)
 | |
|         {
 | |
|             clMyBuff += L"\t";
 | |
|         }
 | |
| 
 | |
|         clMyBuff += L"instance of ";
 | |
|         clMyBuff += V_BSTR(&varString);
 | |
|         clMyBuff += L" {";
 | |
|         clMyBuff += g_pwcsNewLine;
 | |
|         g_dwIndent++;
 | |
|     }
 | |
| 
 | |
|     BSTR PropName = NULL;
 | |
|     variant_t varString, varVal;
 | |
|     CIMTYPE dwType;
 | |
|     WCHAR *pBuf = NULL;
 | |
|     bool bKey = false;
 | |
|     BSTR bstrCimType = NULL;
 | |
|     IWbemClassObjectPtr clObject1, clObject2;
 | |
| 
 | |
|     // For all properties...
 | |
|     for (lCount = lLower; lCount <= lUpper; lCount++)
 | |
|     {
 | |
|         // get the property name for this element
 | |
|         sc = SafeArrayGetElement(psaNames, &lCount, &PropName);
 | |
|         if (S_OK != sc)
 | |
|         {
 | |
|             PrintErrorAndExit("Couldn't get safe array element", sc, g_dwErrorFlags);  //Exits program
 | |
|         }
 | |
| 
 | |
|         // Only print the property if
 | |
|         //   we are showing all properties except __SERVER and __PATH and this is not them
 | |
|         if (!((g_bShowSystem1) && ((_wcsicmp(PropName, SERVERPROP) == 0) || _wcsicmp(PropName, PATHPROP) == 0)))
 | |
|         {
 | |
|             for (DWORD x=0; x < g_dwIndent; x++)
 | |
|             {
 | |
|                 clMyBuff += L"\t";
 | |
|             }
 | |
| 
 | |
|             clMyBuff += PropName;
 | |
|             sc = pIWbemClassObject->Get(PropName, 0L, &varString, &dwType, NULL);  // Get the value for the property
 | |
|             if (sc != WBEM_NO_ERROR)
 | |
|             {
 | |
|                 PrintErrorAndExit("Couldn't get Property Value", sc, g_dwErrorFlags);  //Exits program
 | |
|             }
 | |
| 
 | |
|             // Get pointer to property qualifiers
 | |
|             sc = pIWbemClassObject->GetPropertyQualifierSet(PropName, &pQualSet);
 | |
| 
 | |
|             // Get the QualifierSet
 | |
|             if (sc == WBEM_NO_ERROR)
 | |
|             {
 | |
|                 // Get CIMTYPE attribute (if any)
 | |
|                 sc = pQualSet->Get(CIMTYPEQUAL, 0L, &varVal, NULL);
 | |
|                 if (sc == WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     bstrCimType = SysAllocString(V_BSTR(&varVal));
 | |
|                     varVal.Clear();
 | |
|                 }
 | |
|                 else if (sc != WBEM_E_NOT_FOUND)
 | |
|                 {  // some other error
 | |
|                     PrintErrorAndExit("Could not get CIMTYPE qualifier", sc, g_dwErrorFlags);  // Exits program
 | |
|                 }
 | |
| 
 | |
|                 // Determine if this is a key property
 | |
|                 sc = pQualSet->Get(KEYQUAL, 0L, &varVal, NULL);
 | |
|                 if (sc == WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     bKey = (bool)varVal.boolVal;
 | |
|                 }
 | |
|                 else if (sc == WBEM_E_NOT_FOUND)
 | |
|                 {  // not a key qualifier
 | |
|                     bKey = false;
 | |
|                 }
 | |
|                 else
 | |
|                 { // some other error
 | |
|                     PrintErrorAndExit("Could not get key qualifier", sc, g_dwErrorFlags);  // Exits program
 | |
|                 }
 | |
| 
 | |
|                 // this mess is due to the fact that system properties don't have qualifiers
 | |
|             } 
 | |
|             else if (sc != WBEM_E_SYSTEM_PROPERTY)
 | |
|             {
 | |
|                 PrintErrorAndExit("Could not GetPropertyQualifierSet", sc, g_dwErrorFlags);  // Exits program
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 bstrCimType = SysAllocString(L"");
 | |
|             }
 | |
| 
 | |
|             // print variable type and key indicatory for property value
 | |
|             if (!g_bMofTemplate)
 | |
|             {
 | |
|                 clMyBuff += L" (";
 | |
|                 clMyBuff += TypeToString(dwType);
 | |
| 
 | |
|                 if (bstrCimType != NULL)
 | |
|                 {
 | |
|                     clMyBuff += L"/";
 | |
|                     clMyBuff += bstrCimType;
 | |
|                 }
 | |
| 
 | |
|                 // Mark the key fields
 | |
|                 if (bKey)
 | |
|                 {
 | |
|                     clMyBuff += L")* ";
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     clMyBuff += L") ";
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // If we are showing a mof template, and this property is an embedded object and
 | |
|             // there is no default object, we will need to create a blank one.
 | |
|             if ((g_bMofTemplate) &&
 | |
|                 (V_VT(&varString) == VT_NULL) &&
 | |
|                 ((dwType == CIM_OBJECT) || (dwType == (CIM_OBJECT | CIM_FLAG_ARRAY))))
 | |
|             {
 | |
|                 IWbemServicesPtr pIWbemServices;
 | |
| 
 | |
|                 Init(&pIWbemServices, g_pwcsNamespace);        // Connect to wbem
 | |
| 
 | |
|                 // Get the object
 | |
|                 sc = pIWbemServices->GetObject(
 | |
| 
 | |
|                         bstr_t(&bstrCimType[7]),
 | |
|                         g_lGFlags,
 | |
|                         g_pContext,
 | |
|                         &clObject1,
 | |
|                         NULL
 | |
|                     );
 | |
|                 if (sc != WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     PrintErrorAndExit("Failed to GetObject in EnumProperties", sc, g_dwErrorFlags);
 | |
|                 }
 | |
| 
 | |
|                 // and spawn an instance of it
 | |
|                 sc = clObject1->SpawnInstance(0L, &clObject2);
 | |
|                 if (sc != WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     PrintErrorAndExit("Failed to SpawnInstance in EnumProperties", sc, g_dwErrorFlags);
 | |
|                 }
 | |
| 
 | |
|                 // If this is an array, create a safearray object
 | |
|                 if (dwType & CIM_FLAG_ARRAY)
 | |
|                 {
 | |
|                     // Create the array
 | |
|                     SAFEARRAYBOUND rgsabound[1];
 | |
|                     rgsabound[0].cElements = 1;
 | |
|                     rgsabound[0].lLbound = 0;
 | |
| 
 | |
|                     V_ARRAY(&varString) = SafeArrayCreate((VARTYPE)(dwType & (~CIM_FLAG_ARRAY)), 1, rgsabound);
 | |
| 
 | |
|                     // Put the object into the safearray
 | |
|                     void *vptr;
 | |
| 
 | |
|                     SafeArrayAccessData(V_ARRAY(&varString), &vptr);
 | |
|                     clObject2->QueryInterface(IID_IUnknown, (void **)vptr);
 | |
|                     SafeArrayUnaccessData(V_ARRAY(&varString));
 | |
| 
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     clObject2->QueryInterface(IID_IUnknown, (void **)&V_UNKNOWN(&varString));
 | |
|                 }
 | |
| 
 | |
|                 // Reset the type from null to dwType
 | |
|                 V_VT(&varString) = (VARTYPE)dwType;
 | |
|             }
 | |
| 
 | |
|             // Print the value
 | |
|             clMyBuff += L" = ";
 | |
|             if ((V_VT(&varString) == VT_UNKNOWN) || (V_VT(&varString) == (VT_UNKNOWN | VT_ARRAY)))
 | |
|             {
 | |
|                 clMyBuff += g_pwcsNewLine;
 | |
|                 clMyBuff += ValueToString(dwType, &varString, &pBuf, MyValueToString);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 // For mof templates, if this is an array, add the braces
 | |
|                 if ((g_bMofTemplate) && ((V_VT(&varString) & VT_ARRAY) != 0))
 | |
|                 {
 | |
|                     clMyBuff += L"{";
 | |
|                 }
 | |
|                 clMyBuff += ValueToString(dwType, &varString, &pBuf, MyValueToString);
 | |
|                 if ((g_bMofTemplate) && (V_VT(&varString) & VT_ARRAY) != 0)
 | |
|                 {
 | |
|                     clMyBuff += L"}";
 | |
|                 }
 | |
|                 // For mof templates, add the cimtype et al as a comment
 | |
|                 if (g_bMofTemplate)
 | |
|                 {
 | |
|                     clMyBuff += L"\t//\t";
 | |
|                     clMyBuff += TypeToString(dwType);
 | |
|                     clMyBuff += L"\t";
 | |
|                     clMyBuff += bstrCimType;
 | |
|                     clMyBuff += L"\t";
 | |
|                     BSTR bstrOrigin = NULL;
 | |
|                     pIWbemClassObject->GetPropertyOrigin(PropName, &bstrOrigin);
 | |
|                     clMyBuff += bstrOrigin;
 | |
|                     if (bKey)
 | |
|                     {
 | |
|                         clMyBuff += L"\t*";
 | |
|                     }
 | |
|                     SysFreeString(bstrOrigin);
 | |
|                 }
 | |
|                 clMyBuff += g_pwcsNewLine;
 | |
|             }
 | |
| 
 | |
|             // Release and reset for next pass
 | |
|             if (bstrCimType != NULL)
 | |
|             {
 | |
|                 SysFreeString(bstrCimType);
 | |
|                 bstrCimType = NULL;
 | |
|             }
 | |
|             bKey = false;
 | |
| 
 | |
|             free(pBuf);
 | |
| 
 | |
|             varString.Clear();
 | |
|             varVal.Clear();
 | |
|       }
 | |
|       SysFreeString(PropName);
 | |
|    }
 | |
| 
 | |
|    SafeArrayDestroy(psaNames);
 | |
| 
 | |
|    if (g_bMofTemplate)
 | |
|    {
 | |
|        g_dwIndent--;
 | |
|        for (DWORD x=0; x < g_dwIndent; x++)
 | |
|        {
 | |
|            clMyBuff += L"\t";
 | |
|        }
 | |
| 
 | |
|        clMyBuff += L"};";
 | |
|        clMyBuff += g_pwcsNewLine;
 | |
|    }
 | |
| 
 | |
|    return clMyBuff.GetCloneString();
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   EnumNamespaces
 | |
| // Purpose:    Enumerate NameSpaces
 | |
| //*****************************************************************************
 | |
| void EnumNamespaces(IWbemServices *pIWbemServices, LPCWSTR pwcsClassName)
 | |
| {
 | |
|     SCODE sc;
 | |
| 
 | |
|     // If we aren't showing mofs or command lines
 | |
|     if (!((g_bClassMofs) || (g_bInstanceMofs) || (g_bShowInstance) || (g_bMofTemplate)))
 | |
|     {
 | |
|         variant_t varString;
 | |
|         IWbemClassObjectPtr pIWbemClassObject;
 | |
| 
 | |
|         // Do this to get the right casing for the NameSpace
 | |
|         // Call GetObject with a known-to-exist class
 | |
|         sc = pIWbemServices->GetObject(
 | |
| 
 | |
|                 bstr_t(SYSTEMCLASS),
 | |
|                 g_lGFlags,
 | |
|                 g_pContext,
 | |
|                 &pIWbemClassObject,
 | |
|                 NULL
 | |
|             );
 | |
| 
 | |
|         if (sc != WBEM_NO_ERROR)
 | |
|         {
 | |
|             PrintErrorAndExit("Could not GetObject of __SystemClass in EnumNamespaces", sc, g_dwErrorFlags);  // Exits program
 | |
|         }
 | |
| 
 | |
|         sc = pIWbemClassObject->Get(NAMESPACEPROP, 0L, &varString, NULL, NULL);
 | |
|         if (sc != WBEM_NO_ERROR)
 | |
|         {
 | |
|             PrintErrorAndExit("Could not get __NameSpace property for class", sc, g_dwErrorFlags);  // Exits program
 | |
|         }
 | |
| 
 | |
|         // Indent appropriate number of spaces and print namespace
 | |
|         DoIndent();
 | |
|         FWPRINTF(g_fOut, L"<%wS>%wS", V_BSTR(&varString), g_pwcsNewLine);
 | |
| 
 | |
|         // Everything under this should be indented one more level
 | |
|         g_dwIndent++;
 | |
|     }
 | |
| 
 | |
|     // If we are enumerating a specific class or instance, specify the class else pass null
 | |
|     if (pwcsClassName != NULL)
 | |
|     {
 | |
|         IWbemClassObjectPtr pIWbemClassObject;
 | |
| 
 | |
|         // See if we are dealing with a single instance
 | |
|         if (wcschr(pwcsClassName, L'=') != NULL)
 | |
|         {
 | |
|             variant_t varString;
 | |
| 
 | |
|             for (DWORD x=0; x < g_dwLoopCnt; x++)
 | |
|             {
 | |
|                 sc = pIWbemServices->GetObject(
 | |
| 
 | |
|                         bstr_t(pwcsClassName),
 | |
|                         g_lGFlags,
 | |
|                         g_pContext,
 | |
|                         &pIWbemClassObject,
 | |
|                         NULL
 | |
|                     );
 | |
| 
 | |
|                 if (sc != WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     fprintf(stderr, "%S\n", pwcsClassName);
 | |
|                     PrintErrorAndExit("Could not GetObject of specified class in EnumNamespaces", sc, g_dwErrorFlags);  // Exits program
 | |
|                 }
 | |
| 
 | |
|                 sc = pIWbemClassObject->Get(CLASSPROP, 0L, &varString, NULL, NULL);
 | |
|                 if (sc != WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     PrintErrorAndExit("Could not get __Class property for class", sc, g_dwErrorFlags);  // Exits program
 | |
|                 }
 | |
| 
 | |
|                 ShowInstanceHeader(V_BSTR(&varString));
 | |
|                 ShowInstance(pIWbemServices, pIWbemClassObject);
 | |
|                 varString.Clear();
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             sc = pIWbemServices->GetObject(
 | |
| 
 | |
|                     bstr_t(pwcsClassName),
 | |
|                     g_lGFlags,
 | |
|                     g_pContext,
 | |
|                     &pIWbemClassObject,
 | |
|                     NULL
 | |
|                 );
 | |
| 
 | |
|             if (sc != WBEM_NO_ERROR)
 | |
|             {
 | |
|                 fprintf(stderr, "%S\n", pwcsClassName);
 | |
|                 PrintErrorAndExit("Could not GetObject of specified class in EnumNamespaces", sc, g_dwErrorFlags);  // Exits program
 | |
|             }
 | |
| 
 | |
|             ShowClass(pIWbemServices, pIWbemClassObject);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         EnumClasses(pIWbemServices, L"");
 | |
|     }
 | |
| 
 | |
|     // If the user did not specify /S on the command line, we're done
 | |
|     if (!g_bRecurseNS)
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     IEnumWbemClassObjectPtr IEnumWbemClassObject;
 | |
| 
 | |
|     //Find any namespaces under the current namespace
 | |
|     sc = pIWbemServices->CreateInstanceEnum(
 | |
| 
 | |
|             bstr_t(NAMESPACEPROP),         // with this name
 | |
|             WBEM_FLAG_DEEP | g_lEFlags,
 | |
|             g_pContext,
 | |
|             &IEnumWbemClassObject   // using this enumerator
 | |
|         );
 | |
| 
 | |
|     // If we find any namespaces, we'll want to enumerate them too
 | |
|     if (sc == WBEM_NO_ERROR)
 | |
|     {
 | |
|         DWORD dwAuthLevel, dwImpLevel;
 | |
|         sc = GetAuthImp(pIWbemServices, &dwAuthLevel, &dwImpLevel);
 | |
|         if (sc != S_OK)
 | |
|         {
 | |
|             PrintErrorAndExit("GetAuthImp Failed on CreateInstanceEnum (ns)", sc, g_dwErrorFlags);
 | |
|         }
 | |
| 
 | |
|         if (g_lImpFlag != -1)
 | |
|         {
 | |
|             dwImpLevel = g_lImpFlag;
 | |
|         }
 | |
| 
 | |
|         if (g_lAuthFlag != -1)
 | |
|         {
 | |
|             dwAuthLevel = g_lAuthFlag;
 | |
|         }
 | |
| 
 | |
|         sc = SetInterfaceSecurity(IEnumWbemClassObject, g_pwcsAuthority, g_pwcsUserID, g_pwcsPassword, dwAuthLevel, dwImpLevel);
 | |
|         if (sc != S_OK)
 | |
|         {
 | |
|             PrintErrorAndExit("SetInterfaceSecurity Failed on CreateInstanceEnum (ns)", sc, g_dwErrorFlags);
 | |
|         }
 | |
| 
 | |
|         ULONG uReturned;
 | |
|         IWbemClassObjectPtr pIWbemClassObject;
 | |
|         variant_t varString;
 | |
| 
 | |
|         do
 | |
|         {
 | |
|             do
 | |
|             {
 | |
|                 // Get the name of the next namespace
 | |
|                 sc = IEnumWbemClassObject->Next(
 | |
| 
 | |
|                         TIMEOUT,
 | |
|                         1,
 | |
|                         &pIWbemClassObject,
 | |
|                         &uReturned
 | |
|                     );
 | |
| 
 | |
|                 if (g_bExit)
 | |
|                 {
 | |
|                     throw 1;
 | |
|                 }
 | |
|             } while (sc == WBEM_S_TIMEDOUT);
 | |
| 
 | |
|             if (sc == S_OK)
 | |
|             {
 | |
|                 // Get the name
 | |
|                 sc = pIWbemClassObject->Get(NAMEPROP, 0L, &varString, NULL, NULL);
 | |
|                 if (sc != WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     PrintErrorAndExit("Could not get name property", sc, g_dwErrorFlags);  // Exits program
 | |
|                 }
 | |
| 
 | |
|                 IWbemServicesPtr pNewIWbemServices;
 | |
| 
 | |
|                 // Open it
 | |
|                 sc = pIWbemServices->OpenNamespace(
 | |
| 
 | |
|                         V_BSTR(&varString),
 | |
|                         0L,
 | |
|                         NULL,
 | |
|                         &pNewIWbemServices,
 | |
|                         NULL
 | |
|                     );
 | |
|                 if (sc != WBEM_NO_ERROR)
 | |
|                 {
 | |
|                     PrintErrorAndExit("Failed to Open Namespace", sc, g_dwErrorFlags);  // Exits program
 | |
|                 }
 | |
| 
 | |
|                 // Now show all the classes/instances in the new Namespace
 | |
|                 EnumNamespaces(pNewIWbemServices, pwcsClassName);
 | |
| 
 | |
|                 // Release
 | |
|                 varString.Clear();
 | |
|             }
 | |
|         } while (sc == S_OK);
 | |
| 
 | |
|         // Make sure we ended on a positive note
 | |
|         if (sc != S_FALSE)
 | |
|         {
 | |
|             PrintErrorAndExit("Could not get next namespace", sc, g_dwErrorFlags);  //Exits program
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         PrintErrorAndExit("Failed to CreateInstanceEnum", sc, g_dwErrorFlags);  // Exits program
 | |
|     }
 | |
| 
 | |
|     // Back up one level of indention
 | |
|     g_dwIndent--;
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   GetObj
 | |
| // Purpose:    This is useful to test both enumerate and getobject
 | |
| //*****************************************************************************
 | |
| IWbemClassObject *GetObj(IWbemServices *pIWbemServices, IWbemClassObject *pIWbemClassObject)
 | |
| {
 | |
|     SCODE sc;
 | |
|     variant_t varString;
 | |
|     IWbemClassObject *clObject = NULL;
 | |
| 
 | |
|     // Get the relative path of the current instance
 | |
|     sc = pIWbemClassObject->Get(RELPATHPROP, 0L, &varString, NULL, NULL);
 | |
|     if ((sc != WBEM_NO_ERROR) || (V_VT(&varString) != VT_BSTR))
 | |
|     {
 | |
|         if (g_bWarningContinue)
 | |
|         {
 | |
|             PrintError("Could not get path of class", sc, g_dwErrorFlags);
 | |
|         }
 | |
|         else if (g_bWarning)
 | |
|         {
 | |
|             PrintErrorAndAsk("Could not get path of class", sc, g_dwErrorFlags);  // might exit program
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             PrintErrorAndExit("Could not get path of class", sc, g_dwErrorFlags);  // might exit program
 | |
|         }
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     // Call GetObject with this path.  Obviously, this should succeed.
 | |
|     sc = pIWbemServices->GetObject(
 | |
| 
 | |
|             V_BSTR(&varString),
 | |
|             g_lGFlags,
 | |
|             g_pContext,
 | |
|             &clObject,
 | |
|             NULL
 | |
|         );
 | |
| 
 | |
|     if (sc != WBEM_NO_ERROR)
 | |
|     {
 | |
|         if (g_bWarningContinue)
 | |
|         {
 | |
|             PrintError("Could not GetObject on class", sc, g_dwErrorFlags);
 | |
|         }
 | |
|         else if (g_bWarning)
 | |
|         {
 | |
|             PrintErrorAndAsk("Could not GetObject on class", sc, g_dwErrorFlags);  // might exit program
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             PrintErrorAndExit("Could not GetObject on class", sc, g_dwErrorFlags);  // will exit program
 | |
|         }
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     return clObject;
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   ExecuteQuery
 | |
| // Purpose:    
 | |
| //*****************************************************************************
 | |
| void ExecuteQuery(IWbemServices *pIWbemServices, LPCWSTR pwcsQueryLanguage, LPCWSTR pwcsQuery)
 | |
| {
 | |
|     SCODE  sc;
 | |
|     IEnumWbemClassObjectPtr IEnumWbemClassObject;
 | |
|     InstanceQuerySinkPtr pMySink;
 | |
| 
 | |
|     struct _timeb start, finish;
 | |
|     LARGE_INTEGER freq, start2;
 | |
|     QueryPerformanceFrequency(&freq);
 | |
| 
 | |
|     DoIndent(); // Indent
 | |
|     FWPRINTF(g_fOut, L"(%wS) %wS%wS", pwcsQueryLanguage, pwcsQuery, g_pwcsNewLine); //Print class name
 | |
| 
 | |
|     for (DWORD dwLoop = 0; dwLoop < g_dwLoopCnt; dwLoop++)
 | |
|     {
 | |
|         // If we are doing timings
 | |
|         if (g_bTime1)
 | |
|         {
 | |
|             _ftime(&start);
 | |
|         }
 | |
| 
 | |
|         if (!g_bTime2)
 | |
|         {
 | |
|             start2.QuadPart = 0;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             QueryPerformanceCounter(&start2);
 | |
|         }
 | |
| 
 | |
|         if (!g_bASync)
 | |
|         {
 | |
|             sc = pIWbemServices->ExecQuery(
 | |
| 
 | |
|                     bstr_t(pwcsQueryLanguage),
 | |
|                     bstr_t(pwcsQuery),
 | |
|                     0L | g_lEFlags,
 | |
|                     g_pContext,
 | |
|                     &IEnumWbemClassObject   // using this enumerator
 | |
|                 );
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             pMySink.Attach(new InstanceQuerySink(pIWbemServices, false));
 | |
|             sc = pIWbemServices->ExecQueryAsync(
 | |
| 
 | |
|                     bstr_t(pwcsQueryLanguage),
 | |
|                     bstr_t(pwcsQuery),
 | |
|                     0L | g_lEFlags,
 | |
|                     g_pContext,
 | |
|                     pMySink
 | |
|                 );
 | |
|         }
 | |
| 
 | |
|         // If we are doing timings
 | |
|         if (g_bTime1)
 | |
|         {
 | |
|             _ftime(&finish);
 | |
|             fprintf(stdout, "ExecQuery %6.4f seconds.\n", difftime(finish, start));
 | |
|         }
 | |
|         if (g_bTime2)
 | |
|         {
 | |
|             LARGE_INTEGER finish2;
 | |
|             QueryPerformanceCounter(&finish2);
 | |
|             fprintf(stdout, "ExecQuery: %I64d (%6.4f)\n", finish2.QuadPart - start2.QuadPart, (double)(finish2.QuadPart - start2.QuadPart)/freq.QuadPart);
 | |
|         }
 | |
| 
 | |
|         if (sc == WBEM_NO_ERROR)
 | |
|         {
 | |
|             DWORD dwCount;
 | |
| 
 | |
|             // If we are doing timings
 | |
|             if (g_bTime1)
 | |
|             {
 | |
|                 _ftime(&start);
 | |
|             }
 | |
| 
 | |
|             if (!g_bTime2)
 | |
|             {
 | |
|                 start2.QuadPart = 0;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 QueryPerformanceCounter(&start2);
 | |
|             }
 | |
| 
 | |
|             if (!g_bASync)
 | |
|             {
 | |
|                 sc = ShowInstancesSync(pIWbemServices, IEnumWbemClassObject, dwCount, false);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 do
 | |
|                 {
 | |
|                     sc = WaitForSingleObject(pMySink->GetEvent(), TIMEOUT);
 | |
|                     if (g_bExit)
 | |
|                     {
 | |
|                         sc = pIWbemServices->CancelAsyncCall(pMySink);
 | |
|                         throw 1;
 | |
|                     }
 | |
|                 } while (sc == WAIT_TIMEOUT);
 | |
| 
 | |
|                 dwCount = pMySink->GetCount();
 | |
|                 sc = pMySink->GetResult();
 | |
|                 if (sc == WBEM_S_NO_ERROR)
 | |
|                 {
 | |
|                     sc = S_FALSE;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // If we are doing timings
 | |
|             if (g_bTime1)
 | |
|             {
 | |
|                 _ftime(&finish);
 | |
|                 fprintf(stdout, "ShowInstances %6.4f seconds, %d instances.\n", difftime(finish, start), dwCount);
 | |
|             }
 | |
| 
 | |
|             if (g_bTime2)
 | |
|             {
 | |
|                 LARGE_INTEGER finish2;
 | |
|                 QueryPerformanceCounter(&finish2);
 | |
|                 fprintf(stdout, "ShowInstances: %I64d (%6.4f), %d instances.\n", finish2.QuadPart - start2.QuadPart, (double)(finish2.QuadPart - start2.QuadPart)/freq.QuadPart, dwCount);
 | |
|             }
 | |
| 
 | |
|             // Make sure we ended on a positive note
 | |
|             if (sc != S_FALSE)
 | |
|             {
 | |
|                 PrintErrorAndExit("Could not get next query instance", sc, g_dwErrorFlags);  // Exits program
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             PrintErrorAndExit("Error on query", sc, g_dwErrorFlags);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   ShowInstancesSync
 | |
| // Purpose:    
 | |
| //*****************************************************************************
 | |
| HRESULT ShowInstancesSync(IWbemServices *pIWbemServices, IEnumWbemClassObject *IEnumWbemClassObject, DWORD &dwCount, LPCWSTR pwcsClassName)
 | |
| {
 | |
|     dwCount = 0;
 | |
| 
 | |
|     DWORD dwAuthLevel, dwImpLevel;
 | |
|     SCODE sc = GetAuthImp(pIWbemServices, &dwAuthLevel, &dwImpLevel);
 | |
|     if (sc != S_OK)
 | |
|     {
 | |
|         PrintErrorAndExit("GetAuthImp Failed on ExecQuery", sc, g_dwErrorFlags);
 | |
|     }
 | |
| 
 | |
|     if (g_lImpFlag != -1)
 | |
|     {
 | |
|         dwImpLevel = g_lImpFlag;
 | |
|     }
 | |
| 
 | |
|     if (g_lAuthFlag != -1)
 | |
|     {
 | |
|         dwAuthLevel = g_lAuthFlag;
 | |
|     }
 | |
| 
 | |
|     sc = SetInterfaceSecurity(IEnumWbemClassObject, g_pwcsAuthority, g_pwcsUserID, g_pwcsPassword, dwAuthLevel, dwImpLevel);
 | |
|     if (sc != S_OK)
 | |
|     {
 | |
|         PrintErrorAndExit("SetInterfaceSecurity Failed on ExecQuery", sc, g_dwErrorFlags);
 | |
|     }
 | |
| 
 | |
|     ULONG uReturned;
 | |
|     IWbemClassObjectPtr pIWbemClassObject;
 | |
| 
 | |
|     do
 | |
|     {
 | |
|         // Get the next instance
 | |
|         do
 | |
|         {
 | |
|             sc = IEnumWbemClassObject->Next(
 | |
| 
 | |
|                     TIMEOUT,
 | |
|                     1,
 | |
|                     &pIWbemClassObject,
 | |
|                     &uReturned
 | |
|                 );
 | |
| 
 | |
|             if (g_bExit)
 | |
|             {
 | |
|                 throw 1;
 | |
|             }
 | |
|         } while (sc == WBEM_S_TIMEDOUT);
 | |
| 
 | |
|         if(sc == S_OK)
 | |
|         {
 | |
|             if (pwcsClassName != NULL)
 | |
|             {
 | |
|                 ShowInstanceHeader(pwcsClassName);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 pwcsClassName = NULL;
 | |
|             }
 | |
| 
 | |
|             ShowInstance(pIWbemServices, pIWbemClassObject);
 | |
|             dwCount++;
 | |
|         }
 | |
|     } while (sc == S_OK);
 | |
| 
 | |
|     return sc;
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   PrintMof
 | |
| // Purpose:    Prints the mof file for the class that was passed in
 | |
| // Note:
 | |
| //*****************************************************************************
 | |
| void PrintMof(IWbemClassObject *clObject)
 | |
| {
 | |
|     SCODE sc;
 | |
|     BSTR pObjectText = NULL;
 | |
| 
 | |
|     // Get the mof
 | |
|     sc = clObject->GetObjectText(0L, &pObjectText);
 | |
|     if (sc != WBEM_NO_ERROR)
 | |
|     {
 | |
|         PrintErrorAndExit("Failed to print mof", sc, g_dwErrorFlags);  // Exits program
 | |
|     }
 | |
| 
 | |
|     // Print it
 | |
|     FWPRINTF(g_fOut, L"%wS", pObjectText);
 | |
| 
 | |
|     // Clean up
 | |
|     SysFreeString(pObjectText);
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   ShowInstance
 | |
| // Purpose:    Shows the appropriate info for one specific instance
 | |
| // Note:
 | |
| //*****************************************************************************
 | |
| void ShowInstance(IWbemServices *pIWbemServices, IWbemClassObject *pIWbemClassObject)
 | |
| {
 | |
|     IWbemClassObjectPtr clObject;
 | |
|     WCHAR *buf;
 | |
|     MyString clMyBuff;
 | |
|     SCODE sc;
 | |
|     variant_t varVal;
 | |
|     bool bGotOne = false;
 | |
| 
 | |
|     // Get Object (useful to test both enumerate and getobject)
 | |
|     if (g_bCheckGet)
 | |
|     {
 | |
|         clObject = GetObj(pIWbemServices, pIWbemClassObject);
 | |
|         if (clObject == NULL)
 | |
|         {
 | |
|             clObject = pIWbemClassObject;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             bGotOne = true;
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         clObject = pIWbemClassObject;
 | |
|     }
 | |
| 
 | |
|     if (g_bCheckAssoc)
 | |
|     {
 | |
|         CheckAssocEndPoints(pIWbemServices, pIWbemClassObject);
 | |
|     }
 | |
| 
 | |
|     // If we are just showing the mof for each instance
 | |
|     if (g_bInstanceMofs)
 | |
|     {
 | |
|         PrintMof(clObject);
 | |
| 
 | |
|         // If we are just printing the command line to show this instance
 | |
|     }
 | |
|     else if (g_bShowInstance)
 | |
|     {
 | |
|         // Start building the command line
 | |
|         clMyBuff += L" \"";
 | |
| 
 | |
|         // Get the ns
 | |
|         sc = clObject->Get(NAMESPACEPROP, 0L, &varVal, NULL, NULL);
 | |
|         if (sc != WBEM_NO_ERROR)
 | |
|         {
 | |
|             PrintErrorAndExit("Could not get __namespace", sc, g_dwErrorFlags);  // Exits program
 | |
|         }
 | |
|         varVal.Clear();
 | |
| 
 | |
|         // Add the relpath
 | |
|         sc = clObject->Get(RELPATHPROP, 0L, &varVal, NULL, NULL);
 | |
|         if (sc != WBEM_NO_ERROR)
 | |
|         {
 | |
|             PrintErrorAndExit("Could not get __relpath", sc, g_dwErrorFlags);  // Exits program
 | |
|         }
 | |
|         WCHAR *pW;
 | |
|         pW = wcschr(V_BSTR(&varVal), L'=') + 1;
 | |
|         buf = EscapeChars(pW);
 | |
|         *(pW) = L'\0';
 | |
|         clMyBuff += V_BSTR(&varVal);
 | |
|         clMyBuff += buf;
 | |
|         clMyBuff += L"\"";
 | |
| 
 | |
|         free(buf);
 | |
| 
 | |
|         // Print it and we're done
 | |
|         FWPRINTF(g_fOut, L"%wS%wS", clMyBuff.GetString(), g_pwcsNewLine); // Print the command line
 | |
|         clMyBuff.Empty();
 | |
| 
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         // Otherwise we want to show the instance details
 | |
|         if (!g_bMofTemplate)
 | |
|         {
 | |
|             g_dwIndent++;              // Increase indention level
 | |
|         }
 | |
|         buf = EnumProperties(clObject);
 | |
|         FWPRINTF(g_fOut, L"%wS%wS", buf, g_pwcsNewLine); // Print the properties
 | |
|         free(buf);
 | |
|         if (!g_bMofTemplate)
 | |
|         {
 | |
|             g_dwIndent--;              // Decrease the indention level
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   BstrCmp
 | |
| // Purpose:    Compares 2 bstr arguments
 | |
| // Note:       Used by the qsort routine
 | |
| //*****************************************************************************
 | |
| int __cdecl BstrCmp(const void *arg1,const void *arg2)
 | |
| {
 | |
|     return _wcsicmp( *(WCHAR **)arg1, *(WCHAR **)arg2 );
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   DoIndent
 | |
| // Purpose:    Indents g_dwIndent tabs
 | |
| //*****************************************************************************
 | |
| void DoIndent()
 | |
| {
 | |
|     for (DWORD x=0; x < g_dwIndent; x++)
 | |
|     {
 | |
|         fputws(L"\t", g_fOut);
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   ProcessCommandLine
 | |
| // Purpose:    This function processes the command line for the program,
 | |
| //             filling in the global variables determining what the program
 | |
| //             will do.
 | |
| //*****************************************************************************
 | |
| DWORD ProcessCommandLine(int argc, wchar_t *argv[])
 | |
| {
 | |
|     int iLoop, iPlace;
 | |
|     char *z;
 | |
|     WCHAR *pwcsName, *pwcsValue;
 | |
|     SCODE sc;
 | |
|     variant_t vValue;
 | |
|     char *szHelp = "WBEMDUMP - Dumps the contents of the CIMOM database.\n\n"
 | |
|         "Syntax: wbemdump [switches] [Namespace [Class|ObjectPath] ]\n"
 | |
|         "        wbemdump /Q [switches] Namespace QueryLanguage Query\n\n"
 | |
|         "Where:  'Namespace' is the namespace to dump (defaults to root\\default)\n"
 | |
|         "        'Class' is the name of a specific class to dump (defaults to none)\n"
 | |
|         "        'ObjectPath' is one instance (ex \"SClassA.KeyProp=\\\"foobar\\\"\")\n"
 | |
|         "        'QueryLanguage' is any WBEM supported query language (currently only\n"
 | |
|         "           \"WQL\" is supported).\n"
 | |
|         "        'Query' is a valid query for the specified language, enclosed in quotes\n"
 | |
|         "        'switches' is one of\n"
 | |
|         "           /S Recurse down the tree\n"
 | |
|         "           /S2 Recurse down Namespaces (implies /S)\n"
 | |
|         "           /E Show system classes and properties\n"
 | |
|         "           /E1 Like /E except don't show __SERVER or __PATH property\n"
 | |
|         "           /E2 Shows command lines for dumping instances (test mode)\n"
 | |
|         "           /D Don't show properties\n"
 | |
|         "           /G Do a GetObject on all enumerated instances\n"
 | |
|         "           /G2 Do a GetObject on all reference properties\n"
 | |
|         "           /G:<x> Like /G using x for flags (Amended=131072)\n"
 | |
|         "           /M Get Class MOFS instead of data values\n"
 | |
|         "           /M2 Get Instance MOFS instead of data values\n"
 | |
|         "           /M3 Produce instance template\n"
 | |
|         "           /B:<num> CreateEnum flags (SemiSync=16; Forward=32)\n"
 | |
|         "           /AS Use Async functions\n"
 | |
|         "           /W  Prompt to continue on warning errors\n"
 | |
|         "           /WY Print warnings and continue\n"
 | |
|         "           /W:1 Use IWbemClassObject::GetObjectText to show errors\n"
 | |
|         "           /H:<name>:<value> Specify context object value (test mode)\n"
 | |
|         "           /CQV:<name>[:value] Specify a class qualifier on which to filter\n"
 | |
|         "           /T Print times on enumerations\n"
 | |
|         "           /T2 Print times on enumerations using alternate timer\n"
 | |
|         "           /O:<file> File name for output (creates Unicode file)\n"
 | |
|         "           /C:<file> Command file containing multiple WBEMDUMP command lines\n"
 | |
|         "           /U:<UserID> UserID to connect with (default: NULL)\n"
 | |
|         "           /P:<Password> Password to connect with (default: NULL)\n"
 | |
|         "           /A:<Authority> Authority to connect with\n"
 | |
|         "           /I:<ImpLevel> Anonymous=1 Identify=2 Impersonate=3(dflt) Delegate=4\n"
 | |
|         "           /AL:<AuthenticationLevel> None=1 Conn=2 Call=3 Pkt=4 PktI=5 PktP=6\n"
 | |
|         "           /Locale:<localid> Locale to pass to ConnectServer\n"
 | |
|         "           /L:<LoopCnt> Number of times to enumerate instances (leak check)\n"
 | |
|         "\n"
 | |
|         "Notes:  - You can redirect the output to a file using standard redirection.\n"
 | |
|         "        - If the /C switch is used, the namespace on the command line must\n"
 | |
|         "          be the same namespace that is used for each of the command lines.\n"
 | |
|         "          It is not possible to use different namespaces on the different lines\n"
 | |
|         "          in the command file.\n"
 | |
|         "\n"
 | |
|         "EXAMPLES:\n"
 | |
|         "\n"
 | |
|         "  WBEMDUMP /S /E root\\default            - Dumps everything in root\\default\n"
 | |
|         "  WBEMDUMP /S /E /M /M2 root\\default     - Dump all class & instance mofs\n"
 | |
|         "  WBEMDUMP root\\default foo              - Dumps all instances of the foo class\n"
 | |
|         "  WBEMDUMP root\\default foo.name=\\\"bar\\\" - Dumps one instance of the foo class\n"
 | |
|         "  WBEMDUMP /S2 /M root    - Dumps mofs for all non-system classes in all NS's\n"
 | |
|         "  WBEMDUMP /Q root\\default WQL \"SELECT * FROM Environment WHERE Name=\\\"Path\\\"\""
 | |
|         "\n";
 | |
| 
 | |
|     // Process all the arguments.
 | |
|     // ==========================
 | |
|     if (g_pwcsNamespace != NULL)
 | |
|     {
 | |
|         // Only applies to scripts
 | |
|         iPlace = 1;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         iPlace = 0;
 | |
|     }
 | |
| 
 | |
|     // Set global flags depending on command line arguments
 | |
|     for (iLoop = 1; iLoop < argc; ++iLoop)
 | |
|     {
 | |
|         if (_wcsicmp(argv[iLoop], L"/HELP") == 0 || _wcsicmp(argv[iLoop],L"-HELP") == 0 ||
 | |
|             (wcscmp(argv[iLoop], L"/?") == 0) || (wcscmp(argv[iLoop], L"-?") == 0))
 | |
|         {
 | |
|             fputs(szHelp, stdout);
 | |
|             return(S_FALSE);
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/S") == 0 || _wcsicmp(argv[iLoop],L"-S") == 0)
 | |
|         {
 | |
|             g_bRecurseClass = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/S2") == 0 || _wcsicmp(argv[iLoop],L"-S2") == 0)
 | |
|         {
 | |
|             g_bRecurseClass = TRUE;
 | |
|             g_bRecurseNS = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/Q") == 0 || _wcsicmp(argv[iLoop],L"-Q") == 0)
 | |
|         {
 | |
|             g_bDoQuery = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/E") == 0 || _wcsicmp(argv[iLoop],L"-E") == 0)
 | |
|         {
 | |
|             g_bShowSystem = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/E1") == 0 || _wcsicmp(argv[iLoop],L"-E1") == 0)
 | |
|         {
 | |
|             g_bShowSystem = TRUE;
 | |
|             g_bShowSystem1 = TRUE;
 | |
|             g_bShowInstance = FALSE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/E2") == 0 || _wcsicmp(argv[iLoop],L"-E2") == 0)
 | |
|         {
 | |
|             g_bShowSystem1 = FALSE;
 | |
|             g_bShowInstance = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/D") == 0 || _wcsicmp(argv[iLoop],L"-D") == 0)
 | |
|         {
 | |
|             g_bShowProperties = FALSE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/G") == 0 || _wcsicmp(argv[iLoop],L"-G") == 0)
 | |
|         {
 | |
|             g_bCheckGet = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/G2") == 0 || _wcsicmp(argv[iLoop],L"-G2") == 0)
 | |
|         {
 | |
|             g_bCheckAssoc = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/M") == 0 || _wcsicmp(argv[iLoop],L"-M") == 0)
 | |
|         {
 | |
|             g_bClassMofs = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/M2") == 0 || _wcsicmp(argv[iLoop],L"-M2") == 0)
 | |
|         {
 | |
|             g_bInstanceMofs = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/M3") == 0 || _wcsicmp(argv[iLoop],L"-M3") == 0)
 | |
|         {
 | |
|             g_bMofTemplate = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/W") == 0 || _wcsicmp(argv[iLoop],L"-W") == 0)
 | |
|         {
 | |
|             g_bWarning = TRUE;
 | |
|             g_bWarningContinue = FALSE;
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/W:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-W:", 3) == 0)
 | |
|         {
 | |
|             g_dwErrorFlags = _wtoi((argv[iLoop])+3);
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/WY") == 0 || _wcsicmp(argv[iLoop],L"-WY") == 0)
 | |
|         {
 | |
|             g_bWarningContinue = TRUE;
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/T") == 0 || _wcsicmp(argv[iLoop],L"-T") == 0)
 | |
|         {
 | |
|             g_bTime1 = TRUE;
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/T2", 3) == 0 || _wcsnicmp(argv[iLoop],L"-T2", 3) == 0)
 | |
|         {
 | |
|             g_bTime2 = TRUE;
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/G:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-G:", 3) == 0)
 | |
|         {
 | |
|             g_lGFlags = _wtoi((argv[iLoop])+3);
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/H:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-H:", 3) == 0)
 | |
|         {
 | |
|             if (g_pContext == NULL)
 | |
|             {
 | |
|                 sc = CoCreateInstance(CLSID_WbemContext, NULL, CLSCTX_INPROC_SERVER, IID_IWbemContext, (void **)&g_pContext);
 | |
|                 if (S_OK != sc)
 | |
|                 {
 | |
|                     PrintErrorAndExit("Can't create context object", sc, g_dwErrorFlags);
 | |
|                 }
 | |
|             }
 | |
|             pwcsName = (argv[iLoop])+3;
 | |
|             pwcsValue = wcschr(pwcsName, L':');
 | |
|             if (pwcsValue == NULL)
 | |
|             {
 | |
|                 PrintErrorAndExit("Can't parse Context value", 0, g_dwErrorFlags);
 | |
|             }
 | |
|             *pwcsValue = L'\0';
 | |
|             pwcsValue++;
 | |
|             vValue = pwcsValue;
 | |
|             sc = g_pContext->SetValue(pwcsName, 0L, &vValue);
 | |
|             if (S_OK != sc)
 | |
|             {
 | |
|                 PrintErrorAndExit("Failed to SetValue on context object", 0, g_dwErrorFlags);
 | |
|             }
 | |
|         } 
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/U:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-U:", 3) == 0)
 | |
|         {
 | |
|             g_pwcsUserID = (argv[iLoop])+3;
 | |
|         } 
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/P:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-P:", 3) == 0)
 | |
|         {
 | |
|             g_pwcsPassword = (argv[iLoop])+3;
 | |
|             // Currently not implemented.
 | |
|             //      }
 | |
|             //      else if (_wcsnicmp(argv[iLoop], L"/F:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-F:", 3) == 0)
 | |
|             //      {
 | |
|             //         g_lSFlags = _wtoi((argv[iLoop])+3);
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/I:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-F:", 3) == 0)
 | |
|         {
 | |
|             g_lImpFlag = _wtoi((argv[iLoop])+3);
 | |
|         }
 | |
|         else if (_wcsicmp(argv[iLoop], L"/AS") == 0 || _wcsicmp(argv[iLoop],L"-AS") == 0)
 | |
|         {
 | |
|             g_bASync = TRUE;
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/AL:", 4) == 0 || _wcsnicmp(argv[iLoop],L"-AL:", 4) == 0)
 | |
|         {
 | |
|             g_lAuthFlag = _wtoi((argv[iLoop])+4);
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/B:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-B:", 3) == 0)
 | |
|         {
 | |
|             g_lEFlags = _wtoi((argv[iLoop])+3);
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/Locale:", 8) == 0 || _wcsnicmp(argv[iLoop],L"-Locale:", 8) == 0)
 | |
|         {
 | |
|             g_pwcsLocale = (argv[iLoop])+8;
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/L:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-L:", 3) == 0)
 | |
|         {
 | |
|             g_dwLoopCnt = _wtoi((argv[iLoop])+3);
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/A:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-A:", 3) == 0)
 | |
|         {
 | |
|             g_pwcsAuthority = (argv[iLoop])+3;
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/O:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-O:", 3) == 0)
 | |
|         {
 | |
|             g_pwcsNewLine = L"\r\n";
 | |
|             // must convert to oem string since w95 doesn't support _wfopen
 | |
|             //         g_fOut = _wfopen(argv[iLoop], L"wb");
 | |
|             g_fOut = fopen(cvt((argv[iLoop])+3, &z), "wb");
 | |
|             free(z);
 | |
|             if (g_fOut == NULL)
 | |
|             {
 | |
|                 fprintf(stdout, "Can't open output file: %S (%d)\n", (argv[iLoop])+3, GetLastError());
 | |
|                 return(S_FALSE);
 | |
|             }
 | |
|             fputs(UNICODE_SIGNATURE, g_fOut);
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/C:", 3) == 0 || _wcsnicmp(argv[iLoop],L"-C:", 3) == 0)
 | |
|         {
 | |
|             // must convert to oem string since w95 doesn't support _wfopen
 | |
|             g_fCmdFile = fopen(cvt((argv[iLoop])+3, &z), "rb");
 | |
|             free(z);
 | |
|             if (g_fCmdFile == NULL)
 | |
|             {
 | |
|                 fprintf(stdout, "Can't open command file: %S (%d)\n", (argv[iLoop])+3, GetLastError());
 | |
|                 return(S_FALSE);
 | |
|             }
 | |
| 
 | |
|             // Now, let's see if we are dealing with a unicode file here
 | |
|             char buff[2];
 | |
|             fread(buff, 2, 1, g_fCmdFile);
 | |
| 
 | |
|             if (memcmp(buff, UNICODE_SIGNATURE, 2) != 0)
 | |
|             {
 | |
|                 g_bUnicodeCmdFile = false;
 | |
|                 fseek(g_fCmdFile, 0, SEEK_SET);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 g_bUnicodeCmdFile = true;
 | |
|             }
 | |
|         }
 | |
|         else if (_wcsnicmp(argv[iLoop], L"/CQV:", 5) == 0 || _wcsnicmp(argv[iLoop],L"-CQV:", 5) == 0)
 | |
|         {
 | |
|             if (g_bstrQualifierName != NULL)
 | |
|             {
 | |
|                 PrintErrorAndExit("Only 1 qualifer name can be filtered on", 0, g_dwErrorFlags);
 | |
|             }
 | |
|             pwcsName = (argv[iLoop])+5;
 | |
|             pwcsValue = wcschr(pwcsName, L':');
 | |
| 
 | |
|             // all values
 | |
|             if (pwcsValue == NULL)
 | |
|             {
 | |
|                 g_bstrQualifierName = SysAllocString(pwcsName);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 // Only specified value
 | |
|                 *pwcsValue = L'\0';
 | |
|                 pwcsValue++;
 | |
|                 g_bstrQualifierValue = SysAllocString(pwcsValue);
 | |
|                 g_bstrQualifierName = SysAllocString(pwcsName);
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             switch (iPlace)
 | |
|             {
 | |
|                 case 0:
 | |
|                 {
 | |
|                     g_pwcsNamespace = argv[iLoop];
 | |
|                     break;
 | |
|                 }
 | |
|                 case 1:
 | |
|                 {
 | |
|                     g_pwcsObjectPath = argv[iLoop];
 | |
|                     break;
 | |
|                 }
 | |
|                 case 2:
 | |
|                 {
 | |
|                     g_pwcsQuery = argv[iLoop];
 | |
|                     break;
 | |
|                 }
 | |
|                 default:
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             ++iPlace;
 | |
|         }
 | |
|    }
 | |
| 
 | |
|    // See if we got enough arguments.
 | |
|    // ===============================
 | |
| 
 | |
|    if (((iPlace > 2) && !g_bDoQuery) || ((iPlace != 3) && g_bDoQuery))
 | |
|    {
 | |
|        fputs(szHelp, stdout);
 | |
|        return(S_FALSE);
 | |
|    }
 | |
| 
 | |
|    if (!g_fOut)
 | |
|    {
 | |
|        g_fOut = stdout;
 | |
|    }
 | |
| 
 | |
|    if (iPlace == 0)
 | |
|    {
 | |
|        g_pwcsNamespace = L"root\\default";
 | |
|    }
 | |
| 
 | |
|    // Finished.
 | |
|    // =========
 | |
| 
 | |
|    return(S_OK);
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   EscapeChars
 | |
| // Purpose:    'Escapes' characters in a string by placing '\' in front of
 | |
| //             the " and \ characters.
 | |
| // Notes:      Caller must free returned buffer
 | |
| //*****************************************************************************
 | |
| WCHAR *EscapeChars(LPCWSTR szInBuf)
 | |
| {
 | |
|     WCHAR *szOutBuf = NULL;
 | |
|     int x;
 | |
| 
 | |
|     // Adding escape characters can't do more than double the string size
 | |
|     szOutBuf = (WCHAR *)malloc(((wcslen(szInBuf) + 1) * sizeof(WCHAR)) * 2);
 | |
|     x = 0;
 | |
|     if(szOutBuf)
 | |
|     {
 | |
|         while (*szInBuf != 0)
 | |
|         {
 | |
|             if ((*szInBuf == L'\\') && (*(szInBuf + 1) == L'\"'))
 | |
|             {
 | |
|                 szOutBuf[x++] = '\\';
 | |
|             }
 | |
|             else if (*szInBuf == L'"')
 | |
|             {
 | |
|                 szOutBuf[x++] = '\\';
 | |
|             }
 | |
|             szOutBuf[x++] = *(szInBuf ++);
 | |
|         }
 | |
|         szOutBuf[x] = L'\0';
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         PrintErrorAndExit("Out of memory", 0, g_dwErrorFlags);
 | |
|     }
 | |
| 
 | |
|     return szOutBuf;
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   MyValueToString
 | |
| // Purpose:    A callback routine from utillib.  It is designed to handle any
 | |
| //             variant types that ValueToString doesn't.  Specifically it
 | |
| //             handles embedded objects.
 | |
| //*****************************************************************************
 | |
| WCHAR *MyValueToString(VARIANT *pv)
 | |
| {
 | |
|     WCHAR *buf = NULL;
 | |
|     WCHAR *vbuf = NULL;
 | |
| 
 | |
|     switch (V_VT(pv))
 | |
|     {
 | |
|         case VT_UNKNOWN: // Currently only used for embedded objects
 | |
|         {
 | |
|             extern DWORD g_dwIndent;
 | |
|             g_dwIndent++;
 | |
|             buf = EnumProperties((IWbemClassObject *)pv->punkVal);  // May result in recursion
 | |
|             g_dwIndent--;
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         case VT_UNKNOWN | VT_ARRAY:
 | |
|         {
 | |
|             g_dwIndent++;              // Increase indention level
 | |
| 
 | |
|             SAFEARRAY *pVec = pv->parray;
 | |
|             long iLBound, iUBound;
 | |
| 
 | |
|             SafeArrayGetLBound(pVec, 1, &iLBound);
 | |
|             SafeArrayGetUBound(pVec, 1, &iUBound);
 | |
|             if ((iUBound - iLBound + 1) == 0)
 | |
|             {
 | |
|                 buf = (WCHAR *)calloc(1, BLOCKSIZE);
 | |
|                 if (buf)
 | |
|                 {
 | |
|                     for (DWORD x=0; x < g_dwIndent; x++)
 | |
|                     {
 | |
|                         buf[x] = L'\t';
 | |
|                     }
 | |
|                     wcscat(buf, L"<empty array>");
 | |
|                     wcscat(buf, g_pwcsNewLine);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     PrintErrorAndExit("Out of memory", 0, g_dwErrorFlags);
 | |
|                 }
 | |
| 
 | |
|                 g_dwIndent--;              // Decrease indention level
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             buf = (WCHAR *)calloc(BLOCKSIZE, sizeof(WCHAR));
 | |
| 
 | |
|             if (buf)
 | |
|             {
 | |
|                 IUnknownPtr v;
 | |
|                 IWbemClassObjectPtr pCO;
 | |
|                 variant_t varString;
 | |
| 
 | |
|                 for (long i = iLBound; i <= iUBound; i++)
 | |
|                 {
 | |
|                     SafeArrayGetElement(pVec, &i, &v);
 | |
| 
 | |
|                     pCO = v; // QI to IWbemClassObject
 | |
|                     MyString clMyBuff;
 | |
| 
 | |
|                     HRESULT sc = pCO->Get(CLASSPROP, 0L, &varString, NULL, NULL);
 | |
|                     if (S_OK != sc)
 | |
|                     {
 | |
|                         PrintErrorAndExit("Couldn't get class property in enumproperties", sc, g_dwErrorFlags);  //Exits program
 | |
|                     }
 | |
| 
 | |
|                     //clMyBuff += g_pwcsNewLine;
 | |
|                     for (DWORD x=0; x < g_dwIndent; x++)
 | |
|                     {
 | |
|                         clMyBuff += L"\t";
 | |
|                     }
 | |
|                     clMyBuff += L"instance of ";
 | |
|                     clMyBuff += V_BSTR(&varString);
 | |
|                     clMyBuff += L" {";
 | |
|                     clMyBuff += g_pwcsNewLine;
 | |
|                     g_dwIndent++;
 | |
| 
 | |
|                     varString.Clear();
 | |
| 
 | |
|                     vbuf = clMyBuff.GetCloneString();
 | |
| 
 | |
|                     // Copy into buffer
 | |
|                     buf = (WCHAR *)realloc(buf, (wcslen(buf) + wcslen(vbuf) + 1) * sizeof(WCHAR));
 | |
|                     if (buf)
 | |
|                     {
 | |
|                         wcscat(buf, vbuf);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         PrintErrorAndExit("Out of memory", 0, g_dwErrorFlags);
 | |
|                     }
 | |
| 
 | |
|                     vbuf = EnumProperties(pCO);
 | |
| 
 | |
|                     // Copy into buffer
 | |
|                     buf = (WCHAR *)realloc(buf, (wcslen(buf) + wcslen(vbuf) + 1) * sizeof(WCHAR));
 | |
|                     if (buf) 
 | |
|                     {
 | |
|                         wcscat(buf, vbuf);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         PrintErrorAndExit("Out of memory", 0, g_dwErrorFlags);
 | |
|                     }
 | |
| 
 | |
|                     // Add }
 | |
|                     MyString clMyBuff2;
 | |
| 
 | |
|                     for (x=0; x < g_dwIndent-1; x++)
 | |
|                     {
 | |
|                         clMyBuff2 += L"\t";
 | |
|                     }
 | |
|                     clMyBuff2 += L" }";
 | |
|                     clMyBuff2 += g_pwcsNewLine;
 | |
|                     vbuf = clMyBuff2.GetCloneString();
 | |
| 
 | |
|                     // Copy into buffer
 | |
|                     buf = (WCHAR *)realloc(buf, (wcslen(buf) + wcslen(vbuf) + 1) * sizeof(WCHAR));
 | |
|                     if (buf)
 | |
|                     {
 | |
|                         wcscat(buf, vbuf);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         PrintErrorAndExit("Out of memory", 0, g_dwErrorFlags);
 | |
|                     }
 | |
| 
 | |
|                     g_dwIndent--;
 | |
| 
 | |
|                     free(vbuf);
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 PrintErrorAndExit("Out of memory", 0, g_dwErrorFlags);
 | |
|             }
 | |
| 
 | |
|             g_dwIndent--;              // Decrease indention level
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         default:
 | |
|         {
 | |
|             buf = (WCHAR *)malloc(BLOCKSIZE);
 | |
|             if (buf)
 | |
|             {
 | |
|                 wcscpy(buf, L"<conversion error>");
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 PrintErrorAndExit("Out of memory", 0, g_dwErrorFlags);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return buf;
 | |
| 
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   ShowInstanceHeader
 | |
| // Purpose:    Prints the header at the top of each instance, unless we are
 | |
| //             printing instance mofs
 | |
| //*****************************************************************************
 | |
| void ShowInstanceHeader(LPCWSTR pwcsClassName)
 | |
| {
 | |
|     if ((!g_bInstanceMofs) && (!g_bShowInstance))
 | |
|     {
 | |
|         DoIndent(); // Indent
 | |
|         FWPRINTF(g_fOut, L"%wS%wS", pwcsClassName, g_pwcsNewLine); //Print class name
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   ResetGlobalFlags
 | |
| // Purpose:    Resets the global flags to their default values.  This is
 | |
| //             called in between command lines in a command file.
 | |
| //*****************************************************************************
 | |
| void ResetGlobalFlags()
 | |
| {
 | |
|     g_bShowSystem = FALSE;
 | |
|     g_bShowSystem1 = FALSE;
 | |
|     g_bShowInstance = FALSE;
 | |
|     g_bShowProperties = TRUE;
 | |
|     g_bRecurseClass = FALSE;
 | |
|     g_bRecurseNS = FALSE;
 | |
|     g_bCheckGet = FALSE;
 | |
|     g_bCheckAssoc = FALSE;
 | |
|     g_bDoQuery = FALSE;
 | |
|     g_bClassMofs = FALSE;
 | |
|     g_bInstanceMofs = FALSE;
 | |
| 
 | |
|     g_dwIndent = 0;              // Current indention level
 | |
|     g_lGFlags = 0;
 | |
| 
 | |
|     g_pwcsObjectPath = NULL;  // ObjectPath to show
 | |
|     g_pwcsQuery = NULL;      // Query (for /q commands)
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   ParseCommandLine
 | |
| // Purpose:    Reads the command line from a file and sends it to the parsing
 | |
| //             routine.
 | |
| //*****************************************************************************
 | |
| bool ParseCommandLine(int *numargs, wchar_t **argv)
 | |
| {
 | |
|     WCHAR wszLine[4096];
 | |
|     char szLine[4096];
 | |
|     int numchars;
 | |
|     WCHAR *p;
 | |
| 
 | |
|     // The parsing routine expects to find a program name as the first arg, so
 | |
|     // give it one
 | |
|     wcscpy(wszLine, L"xx ");
 | |
| 
 | |
|     // If this is a unicode command file, read a wcs
 | |
|     if (g_bUnicodeCmdFile)
 | |
|     {
 | |
|         if (!fgetws(wszLine + 3, sizeof(wszLine)/sizeof(WCHAR), g_fCmdFile))
 | |
|         {
 | |
|             return false;
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         // else convert to wcs
 | |
|         szLine[0] = '\0';
 | |
|         // If no more command lines
 | |
|         if (!fgets(szLine, sizeof(szLine), g_fCmdFile))
 | |
|         {
 | |
|             return false;
 | |
|         }
 | |
|         swprintf(wszLine + 3, L"%S", szLine);
 | |
|     }
 | |
| 
 | |
|     // Trim trailing cr, lf, space, and eof markers
 | |
|     p = &wszLine[wcslen(wszLine)-1];
 | |
|     while ((*p == L'\n') || (*p == L'\r') || (*p == L' ') || (*p == L'\x1a'))
 | |
|     {
 | |
|         *p = L'\0';
 | |
|         p = &wszLine[wcslen(wszLine)-1];
 | |
|     }
 | |
| 
 | |
|     // If we read a blank line
 | |
|     if (wcscmp(wszLine, L"xx") == 0)
 | |
|     {
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     /* first find out how much space is needed to store args */
 | |
|     wparse_cmdline(wszLine, NULL, NULL, numargs, &numchars);
 | |
| 
 | |
|     /* allocate space for argv[] vector and strings */
 | |
|     p = (WCHAR *)malloc(*numargs * sizeof(WCHAR *) + numchars * sizeof(WCHAR));
 | |
| 
 | |
|     if (!p)
 | |
|     {
 | |
|         PrintErrorAndExit("Out of memory", 0, g_dwErrorFlags);
 | |
|     }
 | |
| 
 | |
|     /* store args and argv ptrs in just allocated block */
 | |
|     wparse_cmdline(wszLine, (wchar_t **)p, (wchar_t *)(((char *)p) + *numargs * sizeof(wchar_t *)), numargs, &numchars);
 | |
| 
 | |
|     *argv = p;
 | |
|     (*numargs)--;
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| /***
 | |
| *static void parse_cmdline(cmdstart, argv, args, numargs, numchars)
 | |
| *
 | |
| *Purpose:
 | |
| *       Parses the command line and sets up the argv[] array.
 | |
| *       On entry, cmdstart should point to the command line,
 | |
| *       argv should point to memory for the argv array, args
 | |
| *       points to memory to place the text of the arguments.
 | |
| *       If these are NULL, then no storing (only coujting)
 | |
| *       is done.  On exit, *numargs has the number of
 | |
| *       arguments (plus one for a final NULL argument),
 | |
| *       and *numchars has the number of bytes used in the buffer
 | |
| *       pointed to by args.
 | |
| *
 | |
| *Entry:
 | |
| *       _TSCHAR *cmdstart - pointer to command line of the form
 | |
| *           <progname><nul><args><nul>
 | |
| *       _TSCHAR **argv - where to build argv array; NULL means don't
 | |
| *                       build array
 | |
| *       _TSCHAR *args - where to place argument text; NULL means don't
 | |
| *                       store text
 | |
| *
 | |
| *Exit:
 | |
| *       no return value
 | |
| *       int *numargs - returns number of argv entries created
 | |
| *       int *numchars - number of characters used in args buffer
 | |
| *
 | |
| *Exceptions:
 | |
| *
 | |
| *******************************************************************************/
 | |
| 
 | |
| #define DQUOTECHAR L'\"'
 | |
| #define NULCHAR    L'\0'
 | |
| #define SPACECHAR  L' '
 | |
| #define TABCHAR    L'\t'
 | |
| #define SLASHCHAR  L'\\'
 | |
| static void __cdecl wparse_cmdline (
 | |
|                                     WCHAR *cmdstart,
 | |
|                                     WCHAR **argv,
 | |
|                                     WCHAR *args,
 | |
|                                     int *numargs,
 | |
|                                     int *numchars
 | |
|                                     )
 | |
| {
 | |
|     WCHAR *p;
 | |
|     WCHAR c;
 | |
|     int inquote;                /* 1 = inside quotes */
 | |
|     int copychar;               /* 1 = copy char to *args */
 | |
|     unsigned numslash;                  /* num of backslashes seen */
 | |
| 
 | |
|     *numchars = 0;
 | |
|     *numargs = 1;       /* the program name at least */
 | |
| 
 | |
|     /* first scan the program name, copy it, and count the bytes */
 | |
|     p = cmdstart;
 | |
|     if (argv)
 | |
|         *argv++ = args;
 | |
| 
 | |
|         /* A quoted program name is handled here. The handling is much
 | |
|         simpler than for other arguments. Basically, whatever lies
 | |
|         between the leading double-quote and next one, or a terminal null
 | |
|         character is simply accepted. Fancier handling is not required
 | |
|         because the program name must be a legal NTFS/HPFS file name.
 | |
|         Note that the double-quote characters are not copied, nor do they
 | |
|     contribute to numchars. */
 | |
|     if ( *p == DQUOTECHAR )
 | |
|     {
 | |
|     /* scan from just past the first double-quote through the next
 | |
|         double-quote, or up to a null, whichever comes first */
 | |
|         while ( (*(++p) != DQUOTECHAR) && (*p != NULCHAR) )
 | |
|         {
 | |
| 
 | |
|             ++*numchars;
 | |
|             if ( args )
 | |
|                 *args++ = *p;
 | |
|         }
 | |
|         /* append the terminating null */
 | |
|         ++*numchars;
 | |
|         if ( args )
 | |
|             *args++ = NULCHAR;
 | |
| 
 | |
|         /* if we stopped on a double-quote (usual case), skip over it */
 | |
|         if ( *p == DQUOTECHAR )
 | |
|             p++;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         /* Not a quoted program name */
 | |
|         do
 | |
|         {
 | |
|             ++*numchars;
 | |
|             if (args)
 | |
|                 *args++ = *p;
 | |
| 
 | |
|             c = (WCHAR) *p++;
 | |
| 
 | |
|         } while ( c != SPACECHAR && c != NULCHAR && c != TABCHAR );
 | |
| 
 | |
|         if ( c == NULCHAR )
 | |
|         {
 | |
|             p--;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (args)
 | |
|                 *(args-1) = NULCHAR;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     inquote = 0;
 | |
| 
 | |
|     /* loop on each argument */
 | |
|     for(;;)
 | |
|     {
 | |
|         if ( *p )
 | |
|         {
 | |
|             while (*p == SPACECHAR || *p == TABCHAR)
 | |
|                 ++p;
 | |
|         }
 | |
| 
 | |
|         if (*p == NULCHAR)
 | |
|             break;              /* end of args */
 | |
| 
 | |
|         /* scan an argument */
 | |
|         if (argv)
 | |
|             *argv++ = args;     /* store ptr to arg */
 | |
|         ++*numargs;
 | |
| 
 | |
|         /* loop through scanning one argument */
 | |
|         for (;;)
 | |
|         {
 | |
|             copychar = 1;
 | |
|             /* Rules: 2N backslashes + " ==> N backslashes and begin/end quote
 | |
|             2N+1 backslashes + " ==> N backslashes + literal "
 | |
|             N backslashes ==> N backslashes */
 | |
|             numslash = 0;
 | |
|             while (*p == SLASHCHAR)
 | |
|             {
 | |
|                 /* count number of backslashes for use below */
 | |
|                 ++p;
 | |
|                 ++numslash;
 | |
|             }
 | |
|             if (*p == DQUOTECHAR)
 | |
|             {
 | |
|             /* if 2N backslashes before, start/end quote, otherwise
 | |
|                 copy literally */
 | |
|                 if (numslash % 2 == 0)
 | |
|                 {
 | |
|                     if (inquote)
 | |
|                     {
 | |
|                         if (p[1] == DQUOTECHAR)
 | |
|                             p++;    /* Double quote inside quoted string */
 | |
|                         else        /* skip first quote char and copy second */
 | |
|                             copychar = 0;
 | |
|                     } else
 | |
|                         copychar = 0;       /* don't copy quote */
 | |
| 
 | |
|                     inquote = !inquote;
 | |
|                 }
 | |
|                 numslash /= 2;          /* divide numslash by two */
 | |
|             }
 | |
| 
 | |
|             /* copy slashes */
 | |
|             while (numslash--)
 | |
|             {
 | |
|                 if (args)
 | |
|                     *args++ = SLASHCHAR;
 | |
|                 ++*numchars;
 | |
|             }
 | |
| 
 | |
|             /* if at end of arg, break loop */
 | |
|             if (*p == NULCHAR || (!inquote && (*p == SPACECHAR || *p == TABCHAR)))
 | |
|                 break;
 | |
| 
 | |
|             /* copy character into argument */
 | |
|             if (copychar)
 | |
|             {
 | |
|                 if (args)
 | |
|                     *args++ = *p;
 | |
|                 ++*numchars;
 | |
|             }
 | |
|             ++p;
 | |
|         }
 | |
| 
 | |
|         /* null-terminate the argument */
 | |
| 
 | |
|         if (args)
 | |
|             *args++ = NULCHAR;          /* terminate string */
 | |
|         ++*numchars;
 | |
|     }
 | |
| 
 | |
|     /* We put one last argument in -- a null ptr */
 | |
|     if (argv)
 | |
|         *argv++ = NULL;
 | |
|     ++*numargs;
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   CheckQualifiers
 | |
| // Purpose:    Checks to see if we are filtering on class qualifiers.  If
 | |
| //             so, checks to see if the specified qualifier/value is present.
 | |
| //*****************************************************************************
 | |
| BOOL CheckQualifiers(IWbemClassObject *pIWbemClassObject)
 | |
| {
 | |
|     // If we are not filtering on qualifiers
 | |
|     if (g_bstrQualifierName == NULL)
 | |
|     {
 | |
|         return TRUE;
 | |
|     }
 | |
| 
 | |
|     BOOL bRet = TRUE;
 | |
|     variant_t vValue;
 | |
| 
 | |
|     IWbemQualifierSet *pQualSet = NULL;
 | |
|     HRESULT hr = pIWbemClassObject->GetQualifierSet(&pQualSet);
 | |
| 
 | |
|     // This should always work
 | |
|     if (FAILED(hr))
 | |
|     {
 | |
|         PrintErrorAndExit("Failed to get class qualifier set", hr, g_dwErrorFlags); // exits program
 | |
|     }
 | |
| 
 | |
|     // However, this might reasonably fail
 | |
|     hr = pQualSet->Get(g_bstrQualifierName, 0L, &vValue, NULL);
 | |
|     if (SUCCEEDED(hr))
 | |
|     {
 | |
|         // Ok, the qualifier is there.  Did they request a specific value?
 | |
|         if (g_bstrQualifierValue == NULL)
 | |
|         {
 | |
|             bRet = TRUE;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             // Check to see if the value match
 | |
|             if (VariantChangeType(&vValue, &vValue, 0, VT_BSTR) == S_OK)
 | |
|                 bRet = _wcsicmp(V_BSTR(&vValue), g_bstrQualifierValue) == 0;
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         // We failed to Get the qualifier.  Was it because the thing just wasn't there?
 | |
|         if (hr == WBEM_E_NOT_FOUND)
 | |
|         {
 | |
|             bRet = FALSE;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             // Some other error
 | |
|             PrintErrorAndExit("Failed to Get class qualifier value", hr, g_dwErrorFlags); // exits program
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return bRet;
 | |
| 
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   CheckAssocEndPoints
 | |
| // Purpose:    Checks to see if the references pointed to by the reference
 | |
| //             properties of this class really exist.
 | |
| //*****************************************************************************
 | |
| void CheckAssocEndPoints(IWbemServices *pIWbemServices, IWbemClassObject *pIWbemClassObject)
 | |
| {
 | |
|     HRESULT hr;
 | |
| 
 | |
|     if (FAILED(hr = pIWbemClassObject->BeginEnumeration(WBEM_FLAG_REFS_ONLY)))
 | |
|     {
 | |
|         PrintErrorAndExit("Failed to get Refs Enumeration", hr, g_dwErrorFlags); // exits program
 | |
|     }
 | |
| 
 | |
|     BSTR bstrPropertyName = NULL;
 | |
|     variant_t vVal;
 | |
| 
 | |
|     while (SUCCEEDED(hr = pIWbemClassObject->Next(0, &bstrPropertyName, &vVal, NULL, NULL)) &&
 | |
|         (hr != WBEM_S_NO_MORE_DATA) )
 | |
|     {
 | |
|         if ( (V_VT(&vVal) == VT_BSTR) && (V_BSTR(&vVal) != NULL) )
 | |
|         {
 | |
|             if (FAILED(hr = pIWbemServices->GetObject(V_BSTR(&vVal), 0, NULL, NULL, NULL)))
 | |
|             {
 | |
|                 char szBuff[_MAX_PATH];
 | |
| 
 | |
|                 sprintf(szBuff, "Could not get endpoint for property %S", bstrPropertyName);
 | |
| 
 | |
|                 if (g_bWarningContinue)
 | |
|                 {
 | |
|                     PrintError(szBuff, hr, g_dwErrorFlags);
 | |
|                 }
 | |
|                 else if (g_bWarning)
 | |
|                 {
 | |
|                     PrintErrorAndAsk(szBuff, hr, g_dwErrorFlags);  // might exit program
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     PrintErrorAndExit(szBuff, hr, g_dwErrorFlags);  // will exit program
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         SysFreeString(bstrPropertyName);
 | |
|         vVal.Clear();
 | |
|     }
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Function:   CtrlHandler
 | |
| // Purpose:    Checks to see if the references pointed to by the reference
 | |
| //             properties of this class really exist.
 | |
| //*****************************************************************************
 | |
| BOOL CtrlHandler(DWORD fdwCtrlType)
 | |
| {
 | |
|     BOOL bRet = FALSE;
 | |
| 
 | |
|     switch (fdwCtrlType)
 | |
|     {
 | |
|         // Handle the CTRL+C signal.
 | |
| 
 | |
|         case CTRL_CLOSE_EVENT:
 | |
|         case CTRL_C_EVENT:
 | |
|         {
 | |
|             g_bExit = true;
 | |
|             bRet = TRUE;
 | |
|         }
 | |
| 
 | |
|         // Pass other signals to the next handler.
 | |
| 
 | |
|         case CTRL_BREAK_EVENT:
 | |
|         case CTRL_LOGOFF_EVENT:
 | |
|         case CTRL_SHUTDOWN_EVENT:
 | |
|         default:
 | |
|         {
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     return bRet;
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Class:      QuerySink
 | |
| // Purpose:    Generic class to be used as the sink to wbem's async functions
 | |
| //*****************************************************************************
 | |
| QuerySink::QuerySink()
 | |
| {
 | |
|     m_lRef = 1;
 | |
|     m_hResult = S_OK;
 | |
|     m_hDone = CreateEvent(NULL, TRUE, FALSE, NULL);
 | |
| }
 | |
| 
 | |
| QuerySink::~QuerySink()
 | |
| {
 | |
|     CloseHandle(m_hDone);
 | |
| }
 | |
| 
 | |
| ULONG QuerySink::AddRef()
 | |
| {
 | |
|     return InterlockedIncrement(&m_lRef);
 | |
| }
 | |
| 
 | |
| ULONG QuerySink::Release()
 | |
| {
 | |
|     LONG lRef = InterlockedDecrement(&m_lRef);
 | |
|     if(lRef == 0)
 | |
|     {
 | |
|         delete this;
 | |
|     }
 | |
|     return lRef;
 | |
| }
 | |
| 
 | |
| HRESULT QuerySink::QueryInterface(REFIID riid, void** ppv)
 | |
| {
 | |
|     if (riid == IID_IUnknown || riid == IID_IWbemObjectSink)
 | |
|     {
 | |
|         *ppv = (IWbemObjectSink *) this;
 | |
|         AddRef();
 | |
|         return WBEM_S_NO_ERROR;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         return E_NOINTERFACE;
 | |
|     }
 | |
| }
 | |
| 
 | |
| HRESULT QuerySink::SetStatus(
 | |
|             /* [in] */ LONG lFlags,
 | |
|             /* [in] */ HRESULT hResult,
 | |
|             /* [in] */ BSTR strParam,
 | |
|             /* [in] */ IWbemClassObject __RPC_FAR *pObjParam
 | |
|         )
 | |
| {
 | |
|     UNREFERENCED(pObjParam);
 | |
|     UNREFERENCED(strParam);
 | |
| 
 | |
|     if (WBEM_STATUS_COMPLETE == lFlags)
 | |
|     {
 | |
|         m_hResult = hResult;
 | |
|         SetEvent(m_hDone);
 | |
|     }
 | |
| 
 | |
|     return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Class:      InstanceQuerySink (derives from QuerySink)
 | |
| // Purpose:    processes instances sent back from ExecQueryAsync 
 | |
| //             and CreateInstanceEnumAsync
 | |
| //*****************************************************************************
 | |
| InstanceQuerySink::InstanceQuerySink(IWbemServices *pIWbemServices, LPCWSTR pwszClassName) : QuerySink()
 | |
| {
 | |
|     m_pIWbemServices = pIWbemServices;
 | |
|     m_pwszClassName = pwszClassName;
 | |
|     m_bFirst = true;
 | |
| }
 | |
| 
 | |
| InstanceQuerySink::~InstanceQuerySink()
 | |
| {
 | |
| }
 | |
| 
 | |
| HRESULT InstanceQuerySink::Indicate(long lObjCount, IWbemClassObject **pArray)
 | |
| {
 | |
|     for (long i = 0; i < lObjCount; i++)
 | |
|     {
 | |
|         IWbemClassObject *pObj = pArray[i];
 | |
| 
 | |
|         if (m_pwszClassName != NULL)
 | |
|         {
 | |
|             if (!m_bFirst)
 | |
|             {
 | |
|                 ShowInstanceHeader(m_pwszClassName);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 m_bFirst = false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         ShowInstance(m_pIWbemServices, pObj);
 | |
|         m_dwCount++;
 | |
|     }
 | |
| 
 | |
|     return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 | |
| //*****************************************************************************
 | |
| // Class:      ClassQuerySink (derives from QuerySink)
 | |
| // Purpose:    processes classes sent back from CreateClassEnum
 | |
| //*****************************************************************************
 | |
| ClassQuerySink::ClassQuerySink(IWbemServices *pIWbemServices) : QuerySink()
 | |
| {
 | |
|     m_pIWbemServices = pIWbemServices;
 | |
| }
 | |
| 
 | |
| ClassQuerySink::~ClassQuerySink()
 | |
| {
 | |
| }
 | |
| 
 | |
| HRESULT ClassQuerySink::Indicate(long lObjCount, IWbemClassObject **pArray)
 | |
| {
 | |
|     for (long i = 0; i < lObjCount; i++)
 | |
|     {
 | |
|         IWbemClassObject *pObj = pArray[i];
 | |
| 
 | |
|         ShowClass(m_pIWbemServices, pObj);
 | |
|     }
 | |
| 
 | |
|     return WBEM_S_NO_ERROR;
 | |
| }
 | |
| 
 |