home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sysmgmt / sms / smsapi / attribut / attribut.cpp next >
C/C++ Source or Header  |  1996-10-15  |  24KB  |  763 lines

  1. // ====================================================================
  2. //
  3. //  File: attribut.cpp
  4. //
  5. //  Copyright (C) 1994, 1995 Microsoft Corp.
  6. //
  7. //  Author:
  8. //      Jonathan Shuval     Microsoft Corp.
  9. //
  10. //  This program illustrates possible uses of the following SMS APIs:
  11. //
  12. //      SmsAPIVer
  13. //
  14. //      SmsDataSourceConnect
  15. //      SmsDataSourceDisconnect
  16. //
  17. //      SmsOpenContainer
  18. //      SmsSetFilter
  19. //      SmsPopulate
  20. //      SmsGetFolderCount
  21. //      SmsCloseContainer
  22. //      SmsGetNextFolder
  23. //
  24. //      SmsCreateFilter
  25. //      SmsAddToken
  26. //      SmsCloseFilter
  27. //
  28. //      SmsGetFolderType
  29. //      SmsGetFolderID
  30. //      SmsCloseFolder
  31. //      SmsGetScalarCount
  32. //      SmsGetNextScalar
  33. //
  34. //
  35. //  See the readme.txt file in this directory for a decription of this
  36. //  sample.
  37. //
  38. // ====================================================================
  39. //
  40.  
  41.  
  42. // ====================================================================
  43. //
  44. //  Includes.
  45. //
  46. // ====================================================================
  47. #include <afx.h>
  48. #include <smsapi.h>             // Header for the APIs.
  49. #include <time.h>               // For converting time scalars into strings.
  50.  
  51. // Include the GetStatusName function.
  52. // -------------------------------------
  53. #include "..\common\status.inc"
  54.  
  55.  
  56. // ====================================================================
  57. //
  58. //  Defines.
  59. //
  60. // ====================================================================
  61. #define CCH_MAXINPUT 256        // Length for some string buffers.
  62.  
  63.  
  64. // ====================================================================
  65. //
  66. //  Globals.
  67. //
  68. // ====================================================================
  69. HANDLE ghConnect;               // Connection handle.
  70.  
  71.  
  72. // ====================================================================
  73. //
  74. //  Local prototypes.
  75. //
  76. // ====================================================================
  77.  
  78.  
  79. // Set filters.
  80. // -------------------------------------------------------------
  81. BOOL setFilters( HANDLE hContainer );
  82.  
  83.  
  84. // Displays folders (recursively).
  85. // -------------------------------------------------------------
  86. void DisplayFolder( DWORD ctFolder, HANDLE hFolder );
  87.  
  88.  
  89. // Retrieves, decodes, and displays a folder's scalars.
  90. // -------------------------------------------------------------
  91. void DisplayScalars( HANDLE hFolder );
  92.  
  93.  
  94. // Prompt the user for input and return the reply.
  95. // -------------------------------------------------------------
  96. void InputString( const char *pszMessage, char *pszResult );
  97.  
  98.  
  99. // Connect to the SMS datasource.
  100. // -------------------------------------------------------------
  101. HANDLE ConnectToDatasource();
  102.  
  103.  
  104. // Display the help message.
  105. // -------------------------------------------------------------
  106. void DisplayHelp();
  107.  
  108.  
  109. // Display the greeting.
  110. // -------------------------------------------------------------
  111. void DisplayGreeting();
  112.  
  113.  
  114. // Check if there was a request for help on the command line.
  115. // -------------------------------------------------------------
  116. BOOL DidRequestHelp( int argc, char **argv );
  117.  
  118.  
  119. // Display an error message with its SMS status value.
  120. // -------------------------------------------------------------
  121. void DisplaySmsError( const char *pszMessage, SMS_STATUS stat );
  122.  
  123.  
  124. // Get the string equivalence for an SMS status code.
  125. // -------------------------------------------------------------
  126. const char *GetStatusName( SMS_STATUS stat );
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133. // ====================================================================
  134. //  The work starts here.
  135. // ====================================================================
  136. void main( int argc, char **argv )
  137. {
  138.  
  139.     // Check to see if this is a request to display the help
  140.     // screen. If so, display it. Otherwise, display a greeting
  141.     // banner.
  142.     // =========================================================
  143.     if (DidRequestHelp(argc, argv)) {
  144.         DisplayHelp();
  145.         return;
  146.     }
  147.     else {
  148.         DisplayGreeting();
  149.     }
  150.  
  151.  
  152.     SMS_STATUS stat;                    // Return from the APIs.
  153.     HANDLE hContainer;                  // Handle to a container.
  154.  
  155.  
  156.     // Get and display the SMS API version.
  157.     // ------------------------------------
  158.     char *pszVersion;                   // Receives pointer to the version string.
  159.     SmsAPIVer( &pszVersion );           // Get version
  160.     printf("Using %s\n", pszVersion);   // and print it.
  161.  
  162.  
  163.     //===========================================
  164.     // Connect to the SMS datasource.
  165.     //===========================================
  166.     ghConnect = ConnectToDatasource();
  167.     if (ghConnect == NULL) {
  168.         return;
  169.     }
  170.  
  171.  
  172.     // Open the site container.
  173.     // ========================
  174.     stat = SmsOpenContainer( C_SITE, ghConnect, &hContainer );
  175.     if (stat != SMS_OK) {
  176.         DisplaySmsError("SmsOpenContainer failed", stat);
  177.         SmsDataSourceDisconnect( ghConnect );
  178.         return;
  179.     }
  180.  
  181.     // Construct and apply filters.
  182.     // ============================
  183.     BOOL bRet = setFilters( hContainer );
  184.     if (!bRet) {
  185.         // Error message already displayed, but give a general one as well.
  186.         printf("Problem with setting filters.\n");
  187.         SmsDataSourceDisconnect( ghConnect );
  188.         return;
  189.     }
  190.  
  191.     // Select all folders matching our filters.
  192.     // ========================================
  193.     stat = SmsPopulate( hContainer, POP_SYNC, NULL );
  194.     if (stat != SMS_OK) {
  195.         DisplaySmsError("Bad return from SmsPopulate", stat);
  196.         SmsCloseContainer( hContainer );
  197.         SmsDataSourceDisconnect( ghConnect );
  198.         return;
  199.     }
  200.  
  201.     printf("========   Enumerating site hierarchy   =============\n");
  202.  
  203.     // For each folder in the list enumerate its properties.
  204.     // What we do is open all folders in a loop and  then
  205.     // close the container. The open container causes ALL
  206.     // folders to be left open until the container closes.
  207.     // -----------------------------------------------------
  208.     CObArray topFolders;
  209.     HANDLE hFolder;
  210.  
  211.     // Open all top-level folders.
  212.     // ===========================
  213.     while ((stat = SmsGetNextFolder( hContainer, F_ANY, &hFolder )) == SMS_OK) {
  214.  
  215.         // Store the folder's handle for later processing.
  216.         // -----------------------------------------------
  217.         topFolders.Add( (CObject *)hFolder );
  218.     }
  219.  
  220.     printf("*** Retrieved %d folders ***\n", topFolders.GetSize());
  221.  
  222.     // Check why we exited the loop.
  223.     // -----------------------------
  224.     if (stat != SMS_NO_MORE_DATA) {
  225.         DisplaySmsError("Failed to retrieve folder", stat);
  226.     }
  227.  
  228.     // Close the container.
  229.     // --------------------
  230.     SmsCloseContainer( hContainer );
  231.  
  232.  
  233.     // Now (recursively) process each top-level folder.
  234.     // ================================================
  235.     for (int iLoop = 0; iLoop < topFolders.GetSize(); iLoop++) {
  236.  
  237.         // Retrieve the handle.
  238.         // --------------------
  239.         hFolder = (HANDLE)topFolders[iLoop];
  240.  
  241.         printf("*** Top folder #%d\n", iLoop);
  242.  
  243.         // Display the folder.
  244.         // -------------------
  245.         DisplayFolder( iLoop, hFolder );
  246.  
  247.         // Note: the folder is closed inside DisplayFolder.
  248.     }
  249.  
  250.     printf("********* All done ***************\n");
  251.  
  252.     stat = SmsDataSourceDisconnect( ghConnect );
  253.  
  254.  
  255. }  /* main */
  256.  
  257.  
  258.  
  259.  
  260. // ====================================================================
  261. //
  262. //  DisplayFolder
  263. //
  264. //  Display the folder's details and scalars, then recursively process
  265. //  any sub-folders.
  266. //
  267. //  Parameters:
  268. //      DWORD ctFolder
  269. //          The number of sub-folders at this level of the container/folder
  270. //          hierarchy.
  271. //
  272. //      HANDLE hFolder
  273. //          The handle of the folder to display.
  274. //
  275. //  Returns: Nothing.
  276. //
  277. // ====================================================================
  278.  
  279. // Simple macro for checking status.
  280. #define CHKSTAT(str) if (stat != SMS_OK && stat != SMS_MORE_DATA) { \
  281.         printf(str); printf(": %d\n", stat); \
  282.         return; }
  283.  
  284. void DisplayFolder( DWORD ctFolder, HANDLE hFolder )
  285. {
  286.  
  287.     SMS_STATUS stat;
  288.     HANDLE hSubFolder;
  289.     DWORD fType;                        // type of folder we're dealing with.
  290.     char szfType[30];                   // type as a string.
  291.     DWORD totFolders;                   // Total number of sub-folders of
  292.                                         // all types.
  293.     char szFolderID[100];               // This folder's ID.
  294.     DWORD ctScalars;                    // How many scalars in this folder.
  295.  
  296.  
  297.     // Get object type and id.
  298.     // -----------------------
  299.     stat = SmsGetFolderID( hFolder, szFolderID );
  300.     CHKSTAT("SmsGetFolderID");
  301.  
  302.     stat = SmsGetFolderType( hFolder, &fType, szfType );
  303.     CHKSTAT("SmsGetFolderType");
  304.  
  305.     printf("===================================================\n");
  306.     printf("[%d] Folder %s is a %s\n", ctFolder, szFolderID, szfType);
  307.  
  308.     // How many scalars and folders in this folder.
  309.     // --------------------------------------------------------
  310.     stat = SmsGetScalarCount( hFolder, &ctScalars );
  311.     stat = SmsGetFolderCount( hFolder, F_ANY, &totFolders );
  312.     printf("\tContains %d scalars and %d folders\n", ctScalars, totFolders);
  313.     DisplayScalars( hFolder );
  314.  
  315.  
  316.     // Allocate space for sub-folder handles.
  317.     // --------------------------------------
  318.     CObArray subFolders;
  319.     subFolders.SetSize( totFolders );
  320.  
  321.  
  322.     // This loop gets the sub-folder IDs and displays them.
  323.     // ====================================================
  324.     char szSubFolderID[100];
  325.     DWORD ctFolders;
  326.  
  327.     for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
  328.  
  329.         // Get a handle to a sub-folder.
  330.         // -----------------------------
  331.         stat = SmsGetNextFolder( hFolder, F_ANY, &hSubFolder );
  332.         CHKSTAT("SmsGetNextFolder");
  333.         subFolders.SetAt( ctFolders, (CObject *)hSubFolder );
  334.  
  335.         // Get and display the sub-folder's ID.
  336.         // ------------------------------------
  337.         stat = SmsGetFolderID( hSubFolder, (char *)szSubFolderID );
  338.         CHKSTAT("SmsGetFolderID");
  339.         printf("Sub-folder #%d: %s\n", ctFolders, szSubFolderID);
  340.     }
  341.  
  342.     // =======================================================
  343.     // We can now release the handle that was passed in to us.
  344.     // If we wait until the function returns then, because we
  345.     // recurse, we don't release it till the very end.
  346.     // =======================================================
  347.     SmsCloseFolder( hFolder );
  348.  
  349.  
  350.     // This loop gets the sub-folders and displays them.
  351.     // =================================================
  352.     for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
  353.         hSubFolder = (HANDLE)subFolders[ctFolders];
  354.         DisplayFolder( ctFolders, hSubFolder );
  355.     }
  356.  
  357.     // Free the folder handle array.
  358.     // -----------------------------
  359.     subFolders.RemoveAll();
  360.  
  361. }  /* DisplayFolder */
  362.  
  363.  
  364.  
  365. // ====================================================================
  366. //
  367. //  DisplayScalars
  368. //
  369. //  Display all the scalars for the folder.
  370. //
  371. //  Parameters:
  372. //      HANDLE hFolder
  373. //          This is the folder handle. Display this folder's scalars.
  374. //
  375. //  Returns:  Nothing.
  376. //
  377. // ====================================================================
  378.  
  379. #define MY_BUFF_SIZE 100            // Buff size for strings and binaries.
  380. // NOTE: this is deliberately set lower than the maximum (SMS_DATA_BUFF_SIZE).
  381. // By doing this we can exercise the code for checking if the buffer is too
  382. // small for the data (see 'Check for buffer being too small' below).
  383.  
  384. void DisplayScalars( HANDLE hFolder )
  385. {
  386.     SMS_STATUS stat = SMS_OK;
  387.     SCALAR scalar;
  388.     char szName[50];                // buffer for name
  389.     char szValue[MY_BUFF_SIZE];     // buffer for value
  390.     BYTE byValue[MY_BUFF_SIZE];     // Buffer for binary scalars.
  391.     scalar.pszName  = szName;
  392.     scalar.pszValue = szValue;
  393.     scalar.pValue   = byValue;
  394.  
  395.     char *pszTime;                  // For time scalars.
  396.     CTime tTime;                    //  ditto
  397.     CString sTime;                  //  ditto
  398.  
  399.  
  400.     while (1) {
  401.  
  402.         scalar.dwLen = MY_BUFF_SIZE-1;       // must tell him the size
  403.  
  404.         stat = SmsGetNextScalar( hFolder, &scalar);
  405.         if (stat != SMS_OK && stat != SMS_MORE_DATA) {
  406.             break;
  407.         }
  408.  
  409.         // Check for buffer being too small.
  410.         // ---------------------------------
  411.         if (stat == SMS_MORE_DATA) {
  412.             printf("Receive buffer too small, should be %d. Data truncated\n",
  413.                             scalar.dwLen);
  414.             // NOTE: at this point we could retrieve the scalar by name
  415.             // after allocating a larger buffer.
  416.         }
  417.  
  418.  
  419.         // Check scalar type, display accordingly.
  420.         // ---------------------------------------
  421.         switch (scalar.scType) {
  422.         case SCALAR_STRING:
  423.             printf("\t%25s (string): %s\n", scalar.pszName, scalar.pszValue);
  424.             break;
  425.  
  426.         case SCALAR_INT:
  427.             printf("\t%25s (Integer): %ld\n", scalar.pszName, scalar.dwValue);
  428.             break;
  429.  
  430.         case SCALAR_TIME:
  431.             // Check if we have a string equivalence. If so use it.
  432.             if (scalar.bStringEquivalence) {
  433.                 pszTime = scalar.pszValue;
  434.  
  435.             } else {
  436.                 // Use time functions to make a string out of it.
  437.                 // NOTE: we really need to get rid of trailing newline.
  438.                 tTime = scalar.tValue;
  439.                 sTime = tTime.Format( "%m/%d/%y %I:%M %p" );
  440.                 pszTime = (char *)(const char *)sTime;
  441.             }
  442.             printf("\t%25s (time): %s", scalar.pszName, pszTime);
  443.             break;
  444.  
  445.         case SCALAR_BINARY:
  446.             // In this sample we won't display the binary data.
  447.             // Just tell the user its size.
  448.             printf("\t%25s (Binary - this is its size): %ld\n", scalar.pszName, scalar.dwLen);
  449.             break;
  450.         }
  451.     }
  452.  
  453.     // Why did we exit (other than no more scalars)?
  454.     // ---------------------------------------------
  455.     if (stat != SMS_NO_MORE_DATA) {
  456.         DisplaySmsError("Bad return from Scalar access: %d\n", stat);
  457.     }
  458.  
  459.     // Terminate with newline.
  460.     // -----------------------
  461.     printf("\n");
  462.  
  463. }
  464.  
  465.  
  466. // ********************************************************************
  467. //      Helper functions.
  468. // ********************************************************************
  469.  
  470.  
  471. // ====================================================================
  472. //
  473. // setFilters
  474. //
  475. // Create a new filter and apply it to the specified container.
  476. //
  477. // Parameters:
  478. //      HANDLE hContainer
  479. //          This is the handle of the container to which the filter
  480. //          will be applied to.
  481. //
  482. // Returns:
  483. //      BOOL
  484. //          TRUE if no errors occcured, otherwise FALSE.
  485. //
  486. // ====================================================================
  487.  
  488.  
  489. #define CHECK(str) if (stat != SMS_OK) {       \
  490.         DisplaySmsError(str, stat);            \
  491.         return(FALSE);                         \
  492.     }
  493.  
  494.  
  495. BOOL setFilters( HANDLE hContainer )
  496. {
  497.  
  498.     printf("This test will set the following filters:\n");
  499.     printf("        Site filter: RootSite\n");
  500.     printf("Architecture filter: Personal Computer\n");
  501.     printf("   Attribute filter: (MS|ID|1.0) Name\n");
  502.     printf("                   : (MS|ID|1.0) SMSLocation\n");
  503.     printf("                   : (MS|ID|1.0) NetCardID\n");
  504.  
  505.     SMS_STATUS stat;
  506.     HANDLE hFilter;
  507.     TOKEN Token;
  508.  
  509.     // Define a filter: root site.
  510.     // ----------------------------------
  511.     memset( &Token, 0, sizeof(TOKEN) );             // Clear it.
  512.     stat = SmsCreateFilter( SITE_FILTER, ghConnect, &hFilter );
  513.     strcpy( Token.szName, "RootSite" );
  514.     stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
  515.     CHECK("SmsAddToken (site)");
  516.  
  517.     stat = SmsSetFilter( hContainer, hFilter );
  518.     SmsCloseFilter( hFilter );
  519.     CHECK("SmsSetFilter (site)");
  520.  
  521.  
  522.  
  523.     // =========================================================
  524.     // Must set an architecture filter else we get no machines.
  525.     // =========================================================
  526.     memset( &Token, 0, sizeof(TOKEN) );             // Clear it.
  527.     stat = SmsCreateFilter( ARCHITECTURE_FILTER, ghConnect, &hFilter );
  528.     strcpy( Token.szName, "Architecture" );
  529.     strcpy( Token.szValue, "Personal Computer" );
  530.     Token.dwOp = QOP_STR_EQ;
  531.     stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
  532.     CHECK("SmsAddToken (architecture)");
  533.     stat = SmsSetFilter( hContainer, hFilter );
  534.     SmsCloseFilter( hFilter );
  535.     CHECK("SmsSetFilter (architecture)");
  536.  
  537.  
  538.     // =========================================================
  539.     // Attribute filter (MICROSOFT|IDENTIFICATION|1.0)
  540.     // Three tokens:
  541.     //  Name
  542.     //  SMSLocation
  543.     //  NetCardID
  544.     // =========================================================
  545.     memset( &Token, 0, sizeof(TOKEN) );             // Clear it.
  546.     stat = SmsCreateFilter( ATTRIBUTE_FILTER, ghConnect, &hFilter );
  547.  
  548.     strcpy( Token.szArchitecture, "Personal Computer" );
  549.     strcpy( Token.szGroupClass, "MICROSOFT|IDENTIFICATION|1.0" );
  550.     strcpy( Token.szAttributeName, "Name" );
  551.     stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
  552.     CHECK("SmsAddToken (attribute:name)");
  553.  
  554.     strcpy( Token.szAttributeName, "SMSLocation" );
  555.     stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
  556.     CHECK("SmsAddToken (attribute:Location)");
  557.  
  558.     strcpy( Token.szAttributeName, "NetCardID" );
  559.     stat = SmsAddToken( hFilter, OP_OR, &Token, -2 );
  560.     CHECK("SmsAddToken (attribute:NetCardID)");
  561.  
  562.     stat = SmsSetFilter( hContainer, hFilter );
  563.     SmsCloseFilter( hFilter );
  564.     CHECK("SmsSetFilter (attribute)");
  565.  
  566.  
  567.     return( TRUE );
  568.  
  569. }  /* setFilters */
  570.  
  571.  
  572.  
  573.  
  574. // ====================================================================
  575. //
  576. // InputString
  577. //
  578. // Prompt the user to input a string and return the string in the
  579. // specified buffer.
  580. //
  581. // Parameters:
  582. //      const char *pszMessage
  583. //          The user prompt to display.
  584. //
  585. //      char *pszResult
  586. //          Pointer to the buffer where the user's input will be returned.
  587. //
  588. // Returns;
  589. //      The user's input is returned via the given buffer.
  590. //
  591. // ====================================================================
  592. void InputString( const char *pszMessage, char *pszResult )
  593. {
  594.     printf("%s: ", pszMessage);
  595.     gets(pszResult);
  596. }
  597.  
  598.  
  599.  
  600.  
  601. // ====================================================================
  602. //
  603. // ConnectToDatasource
  604. //
  605. // Get the datasource connection information from the user and use it
  606. // to connect to the datasource.
  607. //
  608. // Parameters:  None.
  609. //
  610. // Returns:
  611. //      The connection handle or NULL if the connection failed.
  612. //
  613. // ====================================================================
  614. HANDLE ConnectToDatasource()
  615. {
  616.     // Get the information we need to connect to the
  617.     // data source from the user.
  618.     //==============================================
  619.     char szServer[CCH_MAXINPUT];
  620.     char szUser[CCH_MAXINPUT];
  621.     char szPasswd[CCH_MAXINPUT];
  622.     char szDatabase[CCH_MAXINPUT];
  623.  
  624.     printf("\n");
  625.     printf("**************************\n");
  626.     printf("* Connect to data source *\n");
  627.     printf("**************************\n");
  628.     InputString("SQL server name", szServer);
  629.     InputString("SQL database name", szDatabase);
  630.     InputString("User name for SQL server", szUser);
  631.     InputString("Password for SQL server", szPasswd);
  632.     printf("\n");
  633.  
  634.  
  635.     // Connect to a data source. SQL in this case.
  636.     // ===========================================
  637.     DATASOURCE dsParams;
  638.  
  639.     dsParams.sqlParams.ds          = DB_SQL;
  640.     dsParams.sqlParams.pszServer   = szServer;
  641.     dsParams.sqlParams.pszUserName = szUser;
  642.     dsParams.sqlParams.pszPasswd   = szPasswd;
  643.     dsParams.sqlParams.pszDbName   = szDatabase;
  644.     dsParams.sqlParams.pFunc       = NULL;         // No encryption.
  645.     dsParams.sqlParams.pszKey      = "";
  646.  
  647.     HANDLE hConnect;
  648.     SMS_STATUS stat;
  649.     stat = SmsDataSourceConnect( &dsParams, &hConnect);
  650.  
  651.     if (stat != SMS_OK) {
  652.         hConnect = NULL;
  653.         DisplaySmsError("Connect to data source failed", stat);
  654.     }
  655.  
  656.     return( hConnect );
  657. }
  658.  
  659.  
  660.  
  661.  
  662.  
  663. // ====================================================================
  664. //
  665. // DidRequestHelp
  666. //
  667. // Check the program's arguments to see if the user asked for
  668. // the help screen to be displayed.
  669. //
  670. // Parameters:
  671. //      int argc
  672. //          The argc value from main(argc, argv)
  673. //
  674. //      char **argv
  675. //          The argv value from main(argc, argv)
  676. //
  677. // Returns:
  678. //      TRUE if command line parameters included a request
  679. //      for help to be displayed.
  680. //
  681. // ====================================================================
  682. BOOL DidRequestHelp( int argc, char **argv )
  683. {
  684.     if (argc == 2  && (strcmp(argv[1], "-help") == 0)) {
  685.         return( TRUE );
  686.     }
  687.     else {
  688.         return( FALSE );
  689.     }
  690.  
  691. }
  692.  
  693.  
  694.  
  695.  
  696. // ====================================================================
  697. //
  698. // DisplayHelp
  699. //
  700. // This function displays the samples help screen.
  701. //
  702. // Parameters:
  703. //      None
  704. //
  705. // Returns:
  706. //      Nothing.
  707. //
  708. // ====================================================================
  709. void DisplayHelp()
  710. {
  711.     printf("\n\n");
  712.     printf("***********************************************************\n");
  713.     printf("* attribut.exe:                                           *\n");
  714.     printf("*                                                         *\n");
  715.     printf("* SMS API Example: Test attribute filters.                *\n");
  716.     printf("*                                                         *\n");
  717.     printf("* This sample illustrates the use of the Attribute filter *\n");
  718.     printf("* that is applied to a site container in order to         *\n");
  719.     printf("* enumerate specified properties of a machine             *\n");
  720.     printf("* (architecture Personal Computer).                       *\n");
  721.     printf("*                                                         *\n");
  722.     printf("* Applying an attribute filter in order to enumerate      *\n");
  723.     printf("* machines is considerably faster than setting group      *\n");
  724.     printf("* filters and then retrieving specified machine group     *\n");
  725.     printf("* scalars (machine properties).                           *\n");
  726.     printf("*                                                         *\n");
  727.     printf("* Syntax:                                                 *\n");
  728.     printf("*     attribut.exe [-help]                                *\n");
  729.     printf("*                                                         *\n");
  730.     printf("* Switches:                                               *\n");
  731.     printf("*     -help       Display this help message.              *\n");
  732.     printf("*                                                         *\n");
  733.     printf("***********************************************************\n");
  734.     printf("\n");
  735. }
  736.  
  737.  
  738.  
  739. // ====================================================================
  740. //
  741. // DisplayGreeting
  742. //
  743. // Display the initial greeting banner.
  744. //
  745. // Parameters:
  746. //     None.
  747. //
  748. // Returns:
  749. //     Nothing.
  750. //
  751. // ====================================================================
  752. void DisplayGreeting()
  753. {
  754.     // For this sample, the greeting is identical to the help screen.
  755.     //===============================================================
  756.     DisplayHelp();
  757. }
  758.  
  759.  
  760.  
  761. /* EOF: attribut.cpp */
  762.  
  763.