home *** CD-ROM | disk | FTP | other *** search
- // ====================================================================
- //
- // File: attribut.cpp
- //
- // Copyright (C) 1994, 1995 Microsoft Corp.
- //
- // Author:
- // Jonathan Shuval Microsoft Corp.
- //
- // This program illustrates possible uses of the following SMS APIs:
- //
- // SmsAPIVer
- //
- // SmsDataSourceConnect
- // SmsDataSourceDisconnect
- //
- // SmsOpenContainer
- // SmsSetFilter
- // SmsPopulate
- // SmsGetFolderCount
- // SmsCloseContainer
- // SmsGetNextFolder
- //
- // SmsCreateFilter
- // SmsAddToken
- // SmsCloseFilter
- //
- // SmsGetFolderType
- // SmsGetFolderID
- // SmsCloseFolder
- // SmsGetScalarCount
- // SmsGetNextScalar
- //
- //
- // See the readme.txt file in this directory for a decription of this
- // sample.
- //
- // ====================================================================
- //
-
-
- // ====================================================================
- //
- // Includes.
- //
- // ====================================================================
- #include <afx.h>
- #include <smsapi.h> // Header for the APIs.
- #include <time.h> // For converting time scalars into strings.
-
- // Include the GetStatusName function.
- // -------------------------------------
- #include "..\common\status.inc"
-
-
- // ====================================================================
- //
- // Defines.
- //
- // ====================================================================
- #define CCH_MAXINPUT 256 // Length for some string buffers.
-
-
- // ====================================================================
- //
- // Globals.
- //
- // ====================================================================
- HANDLE ghConnect; // Connection handle.
-
-
- // ====================================================================
- //
- // Local prototypes.
- //
- // ====================================================================
-
-
- // Set filters.
- // -------------------------------------------------------------
- BOOL setFilters( HANDLE hContainer );
-
-
- // Displays folders (recursively).
- // -------------------------------------------------------------
- void DisplayFolder( DWORD ctFolder, HANDLE hFolder );
-
-
- // Retrieves, decodes, and displays a folder's scalars.
- // -------------------------------------------------------------
- void DisplayScalars( HANDLE hFolder );
-
-
- // Prompt the user for input and return the reply.
- // -------------------------------------------------------------
- void InputString( const char *pszMessage, char *pszResult );
-
-
- // Connect to the SMS datasource.
- // -------------------------------------------------------------
- HANDLE ConnectToDatasource();
-
-
- // Display the help message.
- // -------------------------------------------------------------
- void DisplayHelp();
-
-
- // Display the greeting.
- // -------------------------------------------------------------
- void DisplayGreeting();
-
-
- // Check if there was a request for help on the command line.
- // -------------------------------------------------------------
- BOOL DidRequestHelp( int argc, char **argv );
-
-
- // Display an error message with its SMS status value.
- // -------------------------------------------------------------
- void DisplaySmsError( const char *pszMessage, SMS_STATUS stat );
-
-
- // Get the string equivalence for an SMS status code.
- // -------------------------------------------------------------
- const char *GetStatusName( SMS_STATUS stat );
-
-
-
-
-
-
- // ====================================================================
- // The work starts here.
- // ====================================================================
- void main( int argc, char **argv )
- {
-
- // Check to see if this is a request to display the help
- // screen. If so, display it. Otherwise, display a greeting
- // banner.
- // =========================================================
- if (DidRequestHelp(argc, argv)) {
- DisplayHelp();
- return;
- }
- else {
- DisplayGreeting();
- }
-
-
- SMS_STATUS stat; // Return from the APIs.
- HANDLE hContainer; // Handle to a container.
-
-
- // Get and display the SMS API version.
- // ------------------------------------
- char *pszVersion; // Receives pointer to the version string.
- SmsAPIVer( &pszVersion ); // Get version
- printf("Using %s\n", pszVersion); // and print it.
-
-
- //===========================================
- // Connect to the SMS datasource.
- //===========================================
- ghConnect = ConnectToDatasource();
- if (ghConnect == NULL) {
- return;
- }
-
-
- // Open the site container.
- // ========================
- stat = SmsOpenContainer( C_SITE, ghConnect, &hContainer );
- if (stat != SMS_OK) {
- DisplaySmsError("SmsOpenContainer failed", stat);
- SmsDataSourceDisconnect( ghConnect );
- return;
- }
-
- // Construct and apply filters.
- // ============================
- BOOL bRet = setFilters( hContainer );
- if (!bRet) {
- // Error message already displayed, but give a general one as well.
- printf("Problem with setting filters.\n");
- SmsDataSourceDisconnect( ghConnect );
- return;
- }
-
- // Select all folders matching our filters.
- // ========================================
- stat = SmsPopulate( hContainer, POP_SYNC, NULL );
- if (stat != SMS_OK) {
- DisplaySmsError("Bad return from SmsPopulate", stat);
- SmsCloseContainer( hContainer );
- SmsDataSourceDisconnect( ghConnect );
- return;
- }
-
- printf("======== Enumerating site hierarchy =============\n");
-
- // For each folder in the list enumerate its properties.
- // What we do is open all folders in a loop and then
- // close the container. The open container causes ALL
- // folders to be left open until the container closes.
- // -----------------------------------------------------
- CObArray topFolders;
- HANDLE hFolder;
-
- // Open all top-level folders.
- // ===========================
- while ((stat = SmsGetNextFolder( hContainer, F_ANY, &hFolder )) == SMS_OK) {
-
- // Store the folder's handle for later processing.
- // -----------------------------------------------
- topFolders.Add( (CObject *)hFolder );
- }
-
- printf("*** Retrieved %d folders ***\n", topFolders.GetSize());
-
- // Check why we exited the loop.
- // -----------------------------
- if (stat != SMS_NO_MORE_DATA) {
- DisplaySmsError("Failed to retrieve folder", stat);
- }
-
- // Close the container.
- // --------------------
- SmsCloseContainer( hContainer );
-
-
- // Now (recursively) process each top-level folder.
- // ================================================
- for (int iLoop = 0; iLoop < topFolders.GetSize(); iLoop++) {
-
- // Retrieve the handle.
- // --------------------
- hFolder = (HANDLE)topFolders[iLoop];
-
- printf("*** Top folder #%d\n", iLoop);
-
- // Display the folder.
- // -------------------
- DisplayFolder( iLoop, hFolder );
-
- // Note: the folder is closed inside DisplayFolder.
- }
-
- printf("********* All done ***************\n");
-
- stat = SmsDataSourceDisconnect( ghConnect );
-
-
- } /* main */
-
-
-
-
- // ====================================================================
- //
- // DisplayFolder
- //
- // Display the folder's details and scalars, then recursively process
- // any sub-folders.
- //
- // Parameters:
- // DWORD ctFolder
- // The number of sub-folders at this level of the container/folder
- // hierarchy.
- //
- // HANDLE hFolder
- // The handle of the folder to display.
- //
- // Returns: Nothing.
- //
- // ====================================================================
-
- // Simple macro for checking status.
- #define CHKSTAT(str) if (stat != SMS_OK && stat != SMS_MORE_DATA) { \
- printf(str); printf(": %d\n", stat); \
- return; }
-
- void DisplayFolder( DWORD ctFolder, HANDLE hFolder )
- {
-
- SMS_STATUS stat;
- HANDLE hSubFolder;
- DWORD fType; // type of folder we're dealing with.
- char szfType[30]; // type as a string.
- DWORD totFolders; // Total number of sub-folders of
- // all types.
- char szFolderID[100]; // This folder's ID.
- DWORD ctScalars; // How many scalars in this folder.
-
-
- // Get object type and id.
- // -----------------------
- stat = SmsGetFolderID( hFolder, szFolderID );
- CHKSTAT("SmsGetFolderID");
-
- stat = SmsGetFolderType( hFolder, &fType, szfType );
- CHKSTAT("SmsGetFolderType");
-
- printf("===================================================\n");
- printf("[%d] Folder %s is a %s\n", ctFolder, szFolderID, szfType);
-
- // How many scalars and folders in this folder.
- // --------------------------------------------------------
- stat = SmsGetScalarCount( hFolder, &ctScalars );
- stat = SmsGetFolderCount( hFolder, F_ANY, &totFolders );
- printf("\tContains %d scalars and %d folders\n", ctScalars, totFolders);
- DisplayScalars( hFolder );
-
-
- // Allocate space for sub-folder handles.
- // --------------------------------------
- CObArray subFolders;
- subFolders.SetSize( totFolders );
-
-
- // This loop gets the sub-folder IDs and displays them.
- // ====================================================
- char szSubFolderID[100];
- DWORD ctFolders;
-
- for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
-
- // Get a handle to a sub-folder.
- // -----------------------------
- stat = SmsGetNextFolder( hFolder, F_ANY, &hSubFolder );
- CHKSTAT("SmsGetNextFolder");
- subFolders.SetAt( ctFolders, (CObject *)hSubFolder );
-
- // Get and display the sub-folder's ID.
- // ------------------------------------
- stat = SmsGetFolderID( hSubFolder, (char *)szSubFolderID );
- CHKSTAT("SmsGetFolderID");
- printf("Sub-folder #%d: %s\n", ctFolders, szSubFolderID);
- }
-
- // =======================================================
- // We can now release the handle that was passed in to us.
- // If we wait until the function returns then, because we
- // recurse, we don't release it till the very end.
- // =======================================================
- SmsCloseFolder( hFolder );
-
-
- // This loop gets the sub-folders and displays them.
- // =================================================
- for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
- hSubFolder = (HANDLE)subFolders[ctFolders];
- DisplayFolder( ctFolders, hSubFolder );
- }
-
- // Free the folder handle array.
- // -----------------------------
- subFolders.RemoveAll();
-
- } /* DisplayFolder */
-
-
-
- // ====================================================================
- //
- // DisplayScalars
- //
- // Display all the scalars for the folder.
- //
- // Parameters:
- // HANDLE hFolder
- // This is the folder handle. Display this folder's scalars.
- //
- // Returns: Nothing.
- //
- // ====================================================================
-
- #define MY_BUFF_SIZE 100 // Buff size for strings and binaries.
- // NOTE: this is deliberately set lower than the maximum (SMS_DATA_BUFF_SIZE).
- // By doing this we can exercise the code for checking if the buffer is too
- // small for the data (see 'Check for buffer being too small' below).
-
- void DisplayScalars( HANDLE hFolder )
- {
- SMS_STATUS stat = SMS_OK;
- SCALAR scalar;
- char szName[50]; // buffer for name
- char szValue[MY_BUFF_SIZE]; // buffer for value
- BYTE byValue[MY_BUFF_SIZE]; // Buffer for binary scalars.
- scalar.pszName = szName;
- scalar.pszValue = szValue;
- scalar.pValue = byValue;
-
- char *pszTime; // For time scalars.
- CTime tTime; // ditto
- CString sTime; // ditto
-
-
- while (1) {
-
- scalar.dwLen = MY_BUFF_SIZE-1; // must tell him the size
-
- stat = SmsGetNextScalar( hFolder, &scalar);
- if (stat != SMS_OK && stat != SMS_MORE_DATA) {
- break;
- }
-
- // Check for buffer being too small.
- // ---------------------------------
- if (stat == SMS_MORE_DATA) {
- printf("Receive buffer too small, should be %d. Data truncated\n",
- scalar.dwLen);
- // NOTE: at this point we could retrieve the scalar by name
- // after allocating a larger buffer.
- }
-
-
- // Check scalar type, display accordingly.
- // ---------------------------------------
- switch (scalar.scType) {
- case SCALAR_STRING:
- printf("\t%25s (string): %s\n", scalar.pszName, scalar.pszValue);
- break;
-
- case SCALAR_INT:
- printf("\t%25s (Integer): %ld\n", scalar.pszName, scalar.dwValue);
- break;
-
- case SCALAR_TIME:
- // Check if we have a string equivalence. If so use it.
- if (scalar.bStringEquivalence) {
- pszTime = scalar.pszValue;
-
- } else {
- // Use time functions to make a string out of it.
- // NOTE: we really need to get rid of trailing newline.
- tTime = scalar.tValue;
- sTime = tTime.Format( "%m/%d/%y %I:%M %p" );
- pszTime = (char *)(const char *)sTime;
- }
- printf("\t%25s (time): %s", scalar.pszName, pszTime);
- break;
-
- case SCALAR_BINARY:
- // In this sample we won't display the binary data.
- // Just tell the user its size.
- printf("\t%25s (Binary - this is its size): %ld\n", scalar.pszName, scalar.dwLen);
- break;
- }
- }
-
- // Why did we exit (other than no more scalars)?
- // ---------------------------------------------
- if (stat != SMS_NO_MORE_DATA) {
- DisplaySmsError("Bad return from Scalar access: %d\n", stat);
- }
-
- // Terminate with newline.
- // -----------------------
- printf("\n");
-
- }
-
-
- // ********************************************************************
- // Helper functions.
- // ********************************************************************
-
-
- // ====================================================================
- //
- // setFilters
- //
- // Create a new filter and apply it to the specified container.
- //
- // Parameters:
- // HANDLE hContainer
- // This is the handle of the container to which the filter
- // will be applied to.
- //
- // Returns:
- // BOOL
- // TRUE if no errors occcured, otherwise FALSE.
- //
- // ====================================================================
-
-
- #define CHECK(str) if (stat != SMS_OK) { \
- DisplaySmsError(str, stat); \
- return(FALSE); \
- }
-
-
- BOOL setFilters( HANDLE hContainer )
- {
-
- printf("This test will set the following filters:\n");
- printf(" Site filter: RootSite\n");
- printf("Architecture filter: Personal Computer\n");
- printf(" Attribute filter: (MS|ID|1.0) Name\n");
- printf(" : (MS|ID|1.0) SMSLocation\n");
- printf(" : (MS|ID|1.0) NetCardID\n");
-
- SMS_STATUS stat;
- HANDLE hFilter;
- TOKEN Token;
-
- // Define a filter: root site.
- // ----------------------------------
- memset( &Token, 0, sizeof(TOKEN) ); // Clear it.
- stat = SmsCreateFilter( SITE_FILTER, ghConnect, &hFilter );
- strcpy( Token.szName, "RootSite" );
- stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
- CHECK("SmsAddToken (site)");
-
- stat = SmsSetFilter( hContainer, hFilter );
- SmsCloseFilter( hFilter );
- CHECK("SmsSetFilter (site)");
-
-
-
- // =========================================================
- // Must set an architecture filter else we get no machines.
- // =========================================================
- memset( &Token, 0, sizeof(TOKEN) ); // Clear it.
- stat = SmsCreateFilter( ARCHITECTURE_FILTER, ghConnect, &hFilter );
- strcpy( Token.szName, "Architecture" );
- strcpy( Token.szValue, "Personal Computer" );
- Token.dwOp = QOP_STR_EQ;
- stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
- CHECK("SmsAddToken (architecture)");
- stat = SmsSetFilter( hContainer, hFilter );
- SmsCloseFilter( hFilter );
- CHECK("SmsSetFilter (architecture)");
-
-
- // =========================================================
- // Attribute filter (MICROSOFT|IDENTIFICATION|1.0)
- // Three tokens:
- // Name
- // SMSLocation
- // NetCardID
- // =========================================================
- memset( &Token, 0, sizeof(TOKEN) ); // Clear it.
- stat = SmsCreateFilter( ATTRIBUTE_FILTER, ghConnect, &hFilter );
-
- strcpy( Token.szArchitecture, "Personal Computer" );
- strcpy( Token.szGroupClass, "MICROSOFT|IDENTIFICATION|1.0" );
- strcpy( Token.szAttributeName, "Name" );
- stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
- CHECK("SmsAddToken (attribute:name)");
-
- strcpy( Token.szAttributeName, "SMSLocation" );
- stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
- CHECK("SmsAddToken (attribute:Location)");
-
- strcpy( Token.szAttributeName, "NetCardID" );
- stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
- CHECK("SmsAddToken (attribute:NetCardID)");
-
- stat = SmsSetFilter( hContainer, hFilter );
- SmsCloseFilter( hFilter );
- CHECK("SmsSetFilter (attribute)");
-
-
- return( TRUE );
-
- } /* setFilters */
-
-
-
-
- // ====================================================================
- //
- // InputString
- //
- // Prompt the user to input a string and return the string in the
- // specified buffer.
- //
- // Parameters:
- // const char *pszMessage
- // The user prompt to display.
- //
- // char *pszResult
- // Pointer to the buffer where the user's input will be returned.
- //
- // Returns;
- // The user's input is returned via the given buffer.
- //
- // ====================================================================
- void InputString( const char *pszMessage, char *pszResult )
- {
- printf("%s: ", pszMessage);
- gets(pszResult);
- }
-
-
-
-
- // ====================================================================
- //
- // ConnectToDatasource
- //
- // Get the datasource connection information from the user and use it
- // to connect to the datasource.
- //
- // Parameters: None.
- //
- // Returns:
- // The connection handle or NULL if the connection failed.
- //
- // ====================================================================
- HANDLE ConnectToDatasource()
- {
- // Get the information we need to connect to the
- // data source from the user.
- //==============================================
- char szServer[CCH_MAXINPUT];
- char szUser[CCH_MAXINPUT];
- char szPasswd[CCH_MAXINPUT];
- char szDatabase[CCH_MAXINPUT];
-
- printf("\n");
- printf("**************************\n");
- printf("* Connect to data source *\n");
- printf("**************************\n");
- InputString("SQL server name", szServer);
- InputString("SQL database name", szDatabase);
- InputString("User name for SQL server", szUser);
- InputString("Password for SQL server", szPasswd);
- printf("\n");
-
-
- // Connect to a data source. SQL in this case.
- // ===========================================
- DATASOURCE dsParams;
-
- dsParams.sqlParams.ds = DB_SQL;
- dsParams.sqlParams.pszServer = szServer;
- dsParams.sqlParams.pszUserName = szUser;
- dsParams.sqlParams.pszPasswd = szPasswd;
- dsParams.sqlParams.pszDbName = szDatabase;
- dsParams.sqlParams.pFunc = NULL; // No encryption.
- dsParams.sqlParams.pszKey = "";
-
- HANDLE hConnect;
- SMS_STATUS stat;
- stat = SmsDataSourceConnect( &dsParams, &hConnect);
-
- if (stat != SMS_OK) {
- hConnect = NULL;
- DisplaySmsError("Connect to data source failed", stat);
- }
-
- return( hConnect );
- }
-
-
-
-
-
- // ====================================================================
- //
- // DidRequestHelp
- //
- // Check the program's arguments to see if the user asked for
- // the help screen to be displayed.
- //
- // Parameters:
- // int argc
- // The argc value from main(argc, argv)
- //
- // char **argv
- // The argv value from main(argc, argv)
- //
- // Returns:
- // TRUE if command line parameters included a request
- // for help to be displayed.
- //
- // ====================================================================
- BOOL DidRequestHelp( int argc, char **argv )
- {
- if (argc == 2 && (strcmp(argv[1], "-help") == 0)) {
- return( TRUE );
- }
- else {
- return( FALSE );
- }
-
- }
-
-
-
-
- // ====================================================================
- //
- // DisplayHelp
- //
- // This function displays the samples help screen.
- //
- // Parameters:
- // None
- //
- // Returns:
- // Nothing.
- //
- // ====================================================================
- void DisplayHelp()
- {
- printf("\n\n");
- printf("***********************************************************\n");
- printf("* attribut.exe: *\n");
- printf("* *\n");
- printf("* SMS API Example: Test attribute filters. *\n");
- printf("* *\n");
- printf("* This sample illustrates the use of the Attribute filter *\n");
- printf("* that is applied to a site container in order to *\n");
- printf("* enumerate specified properties of a machine *\n");
- printf("* (architecture Personal Computer). *\n");
- printf("* *\n");
- printf("* Applying an attribute filter in order to enumerate *\n");
- printf("* machines is considerably faster than setting group *\n");
- printf("* filters and then retrieving specified machine group *\n");
- printf("* scalars (machine properties). *\n");
- printf("* *\n");
- printf("* Syntax: *\n");
- printf("* attribut.exe [-help] *\n");
- printf("* *\n");
- printf("* Switches: *\n");
- printf("* -help Display this help message. *\n");
- printf("* *\n");
- printf("***********************************************************\n");
- printf("\n");
- }
-
-
-
- // ====================================================================
- //
- // DisplayGreeting
- //
- // Display the initial greeting banner.
- //
- // Parameters:
- // None.
- //
- // Returns:
- // Nothing.
- //
- // ====================================================================
- void DisplayGreeting()
- {
- // For this sample, the greeting is identical to the help screen.
- //===============================================================
- DisplayHelp();
- }
-
-
-
- /* EOF: attribut.cpp */
-
-