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 / testall / testall.cpp < prev    next >
C/C++ Source or Header  |  1996-10-15  |  36KB  |  1,165 lines

  1. // ====================================================================
  2. //
  3. //  File: testall.cpp
  4. //
  5. //  Copyright (C) 1994, 1995 by Microsoft Corporation.
  6. //
  7. //  Author:
  8. //      Jonathan Shuval     Microsoft Corp.
  9. //
  10. //
  11. //  This program illustrates the use of the SMS APIs to examine either
  12. //  a site container, a jobs container, or a package container. The
  13. //  only difference in code between them is the setting of filters.
  14. //
  15. //  The following APIs are used in this program:
  16. //
  17. //      SmsAPIVer
  18. //
  19. //      SmsDataSourceConnect
  20. //      SmsDataSourceDisconnect
  21. //
  22. //      SmsOpenContainer
  23. //      SmsSetFilter
  24. //      SmsPopulate
  25. //      SmsGetFolderCount
  26. //      SmsCloseContainer
  27. //
  28. //      SmsCreateFilter
  29. //      SmsGetToken
  30. //      SmsGetTokenCount
  31. //      SmsAddToken
  32. //      SmsCloseFilter
  33. //
  34. //      SmsGetFolderID
  35. //      SmsGetFolderType
  36. //      SmsGetNextFolder
  37. //      SmsGetScalarCount
  38. //      SmsGetNextScalar
  39. //      SmsCloseFolder
  40. //
  41. //  See the readme.txt file in this directory for more information.
  42. //
  43. // ====================================================================
  44.  
  45.  
  46.  
  47. // ====================================================================
  48. //  Includes.
  49. // ====================================================================
  50. #include <afx.h>
  51. #include <smsapi.h>             // Header for the APIs.
  52. #include <time.h>               // For converting time scalars into string.
  53.  
  54. // Include the GetStatusName function.
  55. // -------------------------------------
  56. #include "..\common\status.inc"
  57.  
  58.  
  59.  
  60. // ====================================================================
  61. //  Defines.
  62. // ====================================================================
  63. #define CCH_MAXINPUT 256
  64.  
  65.  
  66.  
  67. // ====================================================================
  68. //  Local prototypes.
  69. // ====================================================================
  70.  
  71. // Does the real work.
  72. // -------------------------------------------------------------
  73. void doTheWork( HANDLE hConnect );
  74.  
  75.  
  76. // Ask user if they want to see site, jobs or package container.
  77. // -------------------------------------------------------------
  78. DWORD getDumpOption();
  79.  
  80.  
  81. // Set filters according to what container we're looking at.
  82. // -------------------------------------------------------------
  83. BOOL setSiteFilters( HANDLE hConnect, HANDLE hContainer );
  84. BOOL setJobFilters( HANDLE hConnect, HANDLE hContainer );
  85. BOOL setPkgFilters( HANDLE hConnect, HANDLE hContainer );
  86.  
  87.  
  88. // Functions to display folders, scalars, and expressions.
  89. // -------------------------------------------------------------
  90. void DisplayFolder( HANDLE hFolder );
  91. void DisplayScalars( HANDLE hFolder );
  92. void DisplayExpression( HANDLE hFolder );
  93.  
  94.  
  95. // Prompt the user for input and return the reply.
  96. // -------------------------------------------------------------
  97. void InputString(const char* pszMessage, char* pszResult);
  98.  
  99.  
  100. // Connect to the SMS datasource.
  101. // -------------------------------------------------------------
  102. HANDLE ConnectToDatasource();
  103.  
  104.  
  105. // Display the help message.
  106. // -------------------------------------------------------------
  107. void DisplayHelp();
  108.  
  109.  
  110. // Display the greeting.
  111. // -------------------------------------------------------------
  112. void DisplayGreeting();
  113.  
  114.  
  115. // Check to see if there was a request for help
  116. // on the command line.
  117. // -------------------------------------------------------------
  118. BOOL DidRequestHelp(int argc, char** argv);
  119.  
  120.  
  121. // Display an error message with its SMS status value.
  122. // -------------------------------------------------------------
  123. void DisplaySmsError(const char* pszMessage, SMS_STATUS stat);
  124.  
  125.  
  126. // Get the string equivallent for an SMS status code.
  127. // -------------------------------------------------------------
  128. const char* GetStatusName(SMS_STATUS stat);
  129.  
  130.  
  131.  
  132. // ====================================================================
  133. //
  134. //  Macros for checking status
  135. //
  136. // ====================================================================
  137.         // Void return
  138. #define CHKSTAT(str) if (stat != SMS_OK) { \
  139.         DisplaySmsError(str, stat);         \
  140.         return; }
  141.  
  142.         // Bool return
  143. #define CHKSTAT_RTN(str) if (stat != SMS_OK) { \
  144.         DisplaySmsError(str, stat);             \
  145.         return(FALSE); }
  146.  
  147.  
  148.  
  149. // ====================================================================
  150. //
  151. //  The work starts here.
  152. //
  153. // ====================================================================
  154. void main(int argc, char** argv)
  155. {
  156.     // Check to see if this is a request to display the help
  157.     // screen.  If so, display it. Otherwise, display a greeting
  158.     // banner.
  159.     //=========================================================
  160.     if (DidRequestHelp(argc, argv)) {
  161.         DisplayHelp();
  162.         return;
  163.     }
  164.     else {
  165.         DisplayGreeting();
  166.     }
  167.  
  168.  
  169.  
  170.     HANDLE hConnect;
  171.  
  172.     // Get and display API version.
  173.     // ----------------------------
  174.     char *pszVersion;
  175.     SmsAPIVer( &pszVersion );
  176.     printf("%s\n", pszVersion );
  177.  
  178.  
  179.  
  180.     //===========================================
  181.     // Connect to the SMS datasource.
  182.     //===========================================
  183.     hConnect = ConnectToDatasource();
  184.     if (hConnect == NULL) {
  185.         return;
  186.     }
  187.  
  188.  
  189.     // This loop allows us to do the real work multiple times.
  190.     // =======================================================
  191.     BOOL bDone = FALSE;
  192.     char reply[10];
  193.  
  194.     while (!bDone) {
  195.  
  196.         doTheWork( hConnect );
  197.  
  198.         printf("Restart [y/n]? "); gets(reply);
  199.         bDone = (reply[0] != 'y' && reply[0] != 'Y');
  200.     }
  201.  
  202.  
  203.     // Disconnect from the datasource.
  204.     // ===============================
  205.     SmsDataSourceDisconnect( hConnect );
  206.  
  207.  
  208. }  /* main */
  209.  
  210.  
  211. // ====================================================================
  212. //
  213. //  This function does whatever work is required.
  214. //  In this case, it will:
  215. //      - open a container
  216. //      - set filters
  217. //      - populate the container
  218. //      - retrieve all folders from the container and store the handles
  219. //      - cause these folder to be displayed.
  220. //
  221. // ====================================================================
  222. void doTheWork( HANDLE hConnect )
  223. {
  224.     HANDLE hContainer;
  225.     SMS_STATUS stat;
  226.  
  227.     // Ask the user if he wants a site hierarchy, jobs, or package dump.
  228.     // =================================================================
  229.     DWORD cType = getDumpOption();
  230.     BOOL bRet;
  231.  
  232.     stat = SmsOpenContainer( cType, hConnect, &hContainer );
  233.     if (stat != SMS_OK) {
  234.         DisplaySmsError("SmsOpenContainer failed", stat);
  235.         return;
  236.     }
  237.  
  238.     switch (cType) {
  239.     case C_SITE:
  240.         bRet = setSiteFilters( hConnect, hContainer );
  241.         break;
  242.  
  243.     case C_JOB:
  244.         bRet = setJobFilters( hConnect, hContainer );
  245.         break;
  246.  
  247.     case C_PACKAGE:
  248.         bRet = setPkgFilters( hConnect, hContainer );
  249.         break;
  250.     }
  251.  
  252.     if (!bRet) {
  253.         printf("Failure in filters.\n");
  254.         SmsCloseContainer( hContainer );
  255.         return;
  256.     }
  257.  
  258.     // Select all objects matching filter.
  259.     // -----------------------------------
  260.     stat = SmsPopulate( hContainer, POP_SYNC, NULL );
  261.     if (stat != SMS_OK) {
  262.         DisplaySmsError("Bad return from SmsPopulate", stat);
  263.         SmsCloseContainer( hContainer );
  264.         return;
  265.     }
  266.  
  267.     DWORD numFolders;
  268.     SmsGetFolderCount( hContainer, F_ANY, &numFolders );
  269.     printf("\n======== Container has %d folders ==========================\n\n",
  270.                                 numFolders);
  271.  
  272.  
  273.     // For each object in the list enumerate its properties.
  274.     // What I'm going to do is open all folders in a loop and
  275.     // then close the container. The open container causes all
  276.     // objects to be left open until the container closes. This
  277.     // chews up memory big time.
  278.     // ------------------------------------------------------
  279.     CObArray topFolders;
  280.     HANDLE hFolder;
  281.  
  282.     // Open all top-level folders.
  283.     // ===========================
  284.     while (1) {
  285.         stat = SmsGetNextFolder( hContainer, F_ANY, &hFolder );
  286.         if (stat != SMS_OK) {
  287.             // Either error or no more objects in list.
  288.             break;
  289.         }
  290.  
  291.         // Store the folder's handle for later processing.
  292.         // -----------------------------------------------
  293.         topFolders.Add( (CObject *)hFolder );
  294.     }
  295.  
  296.     printf("*** Retrieved %d folders ***\n", topFolders.GetSize());
  297.     // Check why we exited the loop.
  298.     // -----------------------------
  299.     if (stat != SMS_NO_MORE_DATA) {
  300.         printf("Failed to retrieve folder: %d\n", stat);
  301.     }
  302.  
  303.     // Close the container.
  304.     // --------------------
  305.     SmsCloseContainer( hContainer );
  306.     printf("*** Container closed ***\n");
  307.  
  308.  
  309.     for (int iLoop = 0; iLoop < topFolders.GetSize(); iLoop++) {
  310.  
  311.         // Retrieve the handle.
  312.         // --------------------
  313.         hFolder = (HANDLE)topFolders[iLoop];
  314.  
  315.         printf("\n*** Top folder #%d\n", iLoop);
  316.  
  317.         // Display the folder.
  318.         // -------------------
  319.         DisplayFolder( hFolder );
  320.  
  321.         // The folder is closed inside DisplayFolder.
  322.     }
  323.  
  324.     printf("\n********* All done ***************\n");
  325.  
  326. }
  327.  
  328.  
  329. // ====================================================================
  330. //  We are passed in a handle to a folder. We retrieve the folder's
  331. //  information, displaying scalars if any.
  332. //  We then recursively examine sub-folders (after closing the
  333. //  current folder).
  334. // ====================================================================
  335. void DisplayFolder( HANDLE hFolder )
  336. {
  337.  
  338.     SMS_STATUS stat;
  339.     HANDLE hSubFolder;
  340.     DWORD fType;                   // type of folder we're dealing with.
  341.     char szfType[30];                   // type as a string.
  342.     DWORD totFolders;                   // Total number of sub-folders of
  343.                                         // all types.
  344.     char szFolderID[100];               // This folder's ID.
  345.     DWORD ctScalars;                    // How many scalars in this folder.
  346.  
  347.     printf("\n============================================================\n");
  348.  
  349.     // Get folder type and id.
  350.     // -----------------------
  351.     stat = SmsGetFolderID( hFolder, szFolderID );
  352.     CHKSTAT("SmsGetFolderID");
  353.  
  354.     stat = SmsGetFolderType( hFolder, &fType, szfType );
  355.     CHKSTAT("SmsGetFolderType");
  356.     printf("Folder ID \"%s\" is a %s\n\n", szFolderID, szfType);
  357.  
  358.     // How many scalars in this folder.
  359.     // --------------------------------------------------------
  360.     stat = SmsGetScalarCount( hFolder, &ctScalars );
  361.     CHKSTAT("SmsGetScalarCount");
  362.     printf("Contains %d scalars\n\n", ctScalars);
  363.     DisplayScalars( hFolder );
  364.  
  365.  
  366.     // If folder has an associated expression, display it.
  367.     // ---------------------------------------------------
  368.     DisplayExpression( hFolder );
  369.  
  370.     // Get count of all sub-folders (ie of all types).
  371.     // and allocate space for their handles.
  372.     // -----------------------------------------------
  373.     stat = SmsGetFolderCount( hFolder, F_ANY, &totFolders );
  374.     printf("Contains %d folders\n\n", totFolders);
  375.  
  376.     HANDLE *phFolders = (HANDLE *)malloc(totFolders * sizeof(HANDLE));
  377.  
  378.  
  379.     // This loop gets the sub-folder IDs and displays them.
  380.     // ====================================================
  381.     char szSubFolderID[100];
  382.     DWORD ctFolders;
  383.  
  384.     for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
  385.  
  386.         // Get a handle to a sub-folder.
  387.         // -----------------------------
  388.         stat = SmsGetNextFolder( hFolder, F_ANY, &hSubFolder );
  389.         CHKSTAT("SmsGetNextFolder");
  390.         phFolders[ctFolders] = hSubFolder;
  391.  
  392.         // Get and display the sub-folder's ID.
  393.         // ------------------------------------
  394.         stat = SmsGetFolderID( hSubFolder, szSubFolderID );
  395.         CHKSTAT("SmsGetFolderID");
  396.         printf("\tSub-folder: \"%s\"\n", szSubFolderID);
  397.     }
  398.  
  399.     // =======================================================
  400.     // We can now release the handle that was passed in to us.
  401.     // If we wait until the function returns then, because we
  402.     // recurse, we don't release it till the very end.
  403.     // =======================================================
  404.     SmsCloseFolder( hFolder );
  405.  
  406.     // This loop gets the sub-folders and displays them.
  407.     // =================================================
  408.     for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
  409.         DisplayFolder( phFolders[ctFolders] );
  410.     }
  411.  
  412.     // Free the folder handle array.
  413.     // -----------------------------
  414.     free( phFolders );
  415.  
  416. }  /* DisplayFolder */
  417.  
  418.  
  419.  
  420. // ====================================================================
  421. //
  422. //  Display all the scalars for the folder.
  423. //
  424. // Note: the buffer for string scalars has been deliberately set to a
  425. // value lower than the maximum. If we encounter a string scalar whose
  426. // value exceeds this amount then we will print the 'data truncated'
  427. // message.
  428. //
  429. // ====================================================================
  430. void DisplayScalars( HANDLE hFolder )
  431. {
  432.     SMS_STATUS stat = SMS_OK;
  433.     SCALAR scalar;
  434.     char szName[50];                        // Buffer for name.
  435.     char szValue[SMS_DATA_BUFF_SIZE+1];     // Buffer for string value.
  436.     BYTE byValue[SMS_DATA_BUFF_SIZE+1];     // Buffer for binary scalars.
  437.     scalar.pszName  = szName;
  438.     scalar.pszValue = szValue;
  439.     scalar.pValue   = byValue;
  440.  
  441.     char *pszTime;          // For time scalars.
  442.  
  443.  
  444.     while (1) {
  445.  
  446.         scalar.dwLen = sizeof(szValue)-1;       // must tell him the size
  447.  
  448.         stat = SmsGetNextScalar( hFolder, &scalar);
  449.         if (stat != SMS_OK && stat != SMS_MORE_DATA) {
  450.             break;
  451.         }
  452.  
  453.         if (stat == SMS_MORE_DATA) {
  454.             printf("Receive buffer too small, should be %d. Data truncated\n",
  455.                             scalar.dwLen);
  456.         }
  457.         // Check scalar type, display accordingly.
  458.         // ---------------------------------------
  459.         switch (scalar.scType) {
  460.         case SCALAR_STRING:
  461.             printf("\t%30s: %s\n", scalar.pszName, scalar.pszValue);
  462.             break;
  463.  
  464.         case SCALAR_INT:
  465.             printf("\t%30s: %ld\n", scalar.pszName, scalar.dwValue);
  466.             break;
  467.  
  468.         case SCALAR_TIME:
  469.             // If there is a string equivalence use it.
  470.             if (scalar.bStringEquivalence) {
  471.                 printf("\t%30s: %s\n", scalar.pszName, scalar.pszValue);
  472.             } else {
  473.                 pszTime = ctime( &scalar.tValue );
  474.                 printf("\t%30s: %s", scalar.pszName, pszTime);
  475.             }
  476.             break;
  477.  
  478.         case SCALAR_BINARY:
  479.             // Got binary data.
  480.             // Just tell the user how much data there is.
  481.             printf("\t%30s: Binary data - %d bytes of data\n",
  482.                         scalar.pszName, scalar.dwLen);
  483.             break;
  484.         }
  485.     }
  486.  
  487.     // Why did we exit (other than no more scalars)?
  488.     // ---------------------------------------------
  489.     if (stat != SMS_NO_MORE_DATA) {
  490.         DisplaySmsError("Bad return from Scalar access", stat);
  491.     }
  492.  
  493.     // Terminate with newline.
  494.     // -----------------------
  495.     printf("\n");
  496.  
  497. }
  498.  
  499.  
  500.  
  501. // ====================================================================
  502. //
  503. // DisplayExpression -- inv pkg has an expression, display it.
  504. //
  505. // ====================================================================
  506. void DisplayExpression( HANDLE hFolder )
  507. {
  508.     DWORD ctTokens;
  509.     SMS_STATUS stat;
  510.  
  511.     stat = SmsGetTokenCount( hFolder, &ctTokens );
  512.     if (stat != SMS_OK) {
  513.         printf("Folder has no expression\n\n");
  514.         return;
  515.     }
  516.  
  517.  
  518.     printf("Folder has expression with %d tokens\n\n", ctTokens);
  519.  
  520.     TOKEN Token;
  521.  
  522.     for (DWORD dwI = 0; dwI < ctTokens; dwI++) {
  523.         stat = SmsGetToken( hFolder, (INT)dwI, &Token );
  524.         if (stat != SMS_OK) {
  525.             DisplaySmsError("GetToken failed", stat);
  526.             break;
  527.         }
  528.         // print out token
  529.         CString sTokenType;
  530.  
  531.         switch (Token.tokenType) {
  532.         case TOKEN_USER:
  533.             sTokenType = "User token ";
  534.             break;
  535.  
  536.         case TOKEN_OR:
  537.             sTokenType = "OR token   ";
  538.             break;
  539.  
  540.         case TOKEN_AND:
  541.             sTokenType = "AND token  ";
  542.             break;
  543.  
  544.         case TOKEN_OPENPAREN:
  545.             sTokenType = "Open paren ";
  546.             break;
  547.  
  548.         case TOKEN_CLOSEPAREN:
  549.             sTokenType = "Close paren";
  550.             break;
  551.  
  552.         default:
  553.             sTokenType = "Invalid token type!";
  554.             break;
  555.         }
  556.  
  557.         printf("[%d: %s] %s\n", dwI,
  558.                 (const char *)sTokenType, Token.szTokenString );
  559.  
  560.     }
  561.  
  562.     // Terminate with newline.
  563.     // -----------------------
  564.     printf("\n");
  565.  
  566. }
  567.  
  568.  
  569.  
  570. // ********************************************************************
  571. //      Helper functions.
  572. // ********************************************************************
  573.  
  574.  
  575. // ====================================================================
  576. // Ask the user if they want to look at site, jobs, pkg hierarchy.
  577. // ====================================================================
  578. DWORD getDumpOption()
  579. {
  580.     DWORD cType;
  581.     char reply[10];
  582.     BOOL valid = FALSE;
  583.  
  584.     while (!valid) {
  585.         printf("Options: (S)ites (J)obs (P)ackages: ");
  586.         gets(reply);
  587.  
  588.         switch (reply[0]) {
  589.         case 'S': case 's':
  590.             cType = C_SITE;
  591.             valid = TRUE;
  592.             break;
  593.  
  594.         case 'J': case 'j':
  595.             cType = C_JOB;
  596.             valid = TRUE;
  597.             break;
  598.  
  599.         case 'P': case 'p':
  600.             cType = C_PACKAGE;
  601.             valid = TRUE;
  602.             break;
  603.  
  604.         default:
  605.             printf("Invalid - try again (S, J, P): ");
  606.             break;
  607.  
  608.         }
  609.     }
  610.  
  611.     return(cType);
  612. }
  613.  
  614.  
  615.  
  616.  
  617. // ====================================================================
  618. // This function sets the filters when we are looking at a site
  619. // container.
  620. //
  621. // This illustrates the use of the following filters: Site filter,
  622. // architecture filter, machine filter, group filter.
  623. //
  624. // The user is given the choice of using some of these filters or not.
  625. // ====================================================================
  626. BOOL setSiteFilters( HANDLE hConnect, HANDLE hContainer )
  627. {
  628.     SMS_STATUS stat;
  629.     char reply[5];
  630.     HANDLE hFilter;
  631.  
  632.     // =========================================================
  633.     // Site filter: RootSite or SiteByCode
  634.     // =========================================================
  635.     TOKEN SiteToken;
  636.     memset( &SiteToken, 0, sizeof(TOKEN) );
  637.     stat = SmsCreateFilter( SITE_FILTER, hConnect, &hFilter );
  638.     CHKSTAT_RTN("SmsCreateFilter");
  639.  
  640.     printf("Site filter. Rootsite or Site by code [R/S]? ");
  641.     gets(reply);
  642.     if (reply[0] == 'R' || reply[0] == 'r') {
  643.         strcpy( SiteToken.szName, "RootSite" );
  644.         stat = SmsAddToken( hFilter, OP_OR, &SiteToken, 0 );
  645.         CHKSTAT_RTN("SmsAddToken (site filter)");
  646.  
  647.     } else {
  648.         printf("Give 3 letter site code: ");
  649.         gets(reply);
  650.         strcpy( SiteToken.szName, "SiteByCode" );
  651.         strcpy( SiteToken.szValue, reply );
  652.         SiteToken.dwOp = QOP_STR_EQ;
  653.         stat = SmsAddToken( hFilter, OP_OR, &SiteToken, 0 );
  654.         CHKSTAT_RTN("SmsAddToken (site filter)");
  655.     }
  656.     stat = SmsSetFilter( hContainer, hFilter );
  657.     SmsCloseFilter( hFilter );
  658.     if (stat != SMS_OK) {
  659.         printf("SmsSetFilter failed: %d\n", stat);
  660.         return(FALSE);
  661.     }
  662.  
  663.  
  664.  
  665.     // =========================================================
  666.     // Architecture filter.
  667.     // Must set an architecture filter else we get no machines.
  668.     // Architecture = Personal Computer.
  669.     // =========================================================
  670.     TOKEN ArchToken;
  671.     memset( &ArchToken, 0, sizeof(TOKEN) );
  672.  
  673.     stat = SmsCreateFilter( ARCHITECTURE_FILTER, hConnect, &hFilter );
  674.     CHKSTAT_RTN("SmsCreateFilter");
  675.  
  676.     strcpy( ArchToken.szName, "Architecture" );
  677.     strcpy( ArchToken.szValue, "Personal Computer" );
  678.     ArchToken.dwOp = QOP_STR_EQ;
  679.  
  680.     stat = SmsAddToken( hFilter, OP_OR, &ArchToken, 0 );
  681.     CHKSTAT_RTN("SmsAddToken (architecture filter)");
  682.  
  683.     stat = SmsSetFilter( hContainer, hFilter );
  684.     SmsCloseFilter( hFilter );
  685.  
  686.     CHKSTAT_RTN("SmsSetFilter (architecture filter)");
  687.  
  688.  
  689.     // =========================================================
  690.     // Machine filter. This filter will result in only machines
  691.     // with a SystemRole of Server being included in the parent
  692.     // (domain) folder.
  693.     // =========================================================
  694.     printf("Filter SystemRole=Server [y/n]? ");
  695.     gets(reply);
  696.     if (reply[0] == 'y') {
  697.         TOKEN MachToken;
  698.         memset( &MachToken, 0, sizeof(TOKEN) );
  699.         strcpy( MachToken.szArchitecture, "Personal Computer" );
  700.         strcpy( MachToken.szGroupClass, "MICROSOFT|IDENTIFICATION|1.0" );
  701.         strcpy( MachToken.szAttributeName, "SystemRole" );
  702.         strcpy( MachToken.szValue, "Server" );
  703.         MachToken.dwOp = QOP_STR_EQ;
  704.  
  705.         stat = SmsCreateFilter( MACHINE_FILTER, hConnect, &hFilter );
  706.         CHKSTAT_RTN("SmsCreateFilter (machine filter)");
  707.  
  708.         stat = SmsAddToken( hFilter, OP_AND, &MachToken, 0 );
  709.         CHKSTAT_RTN("SmsAddToken (machine filter)");
  710.  
  711.         stat = SmsSetFilter( hContainer, hFilter );
  712.         SmsCloseFilter( hFilter );
  713.         CHKSTAT_RTN("SmsSetFilter (machine filter)");
  714.     }
  715.  
  716.  
  717.     // =========================================================
  718.     // Group filter.
  719.     //  Only one filter of a particular type can be applied to a
  720.     //  container. So we just record whether or not there is a
  721.     //  group filter to be set.
  722.     //  This group filter says that we only want the
  723.     //  identification group for a machine.
  724.     // =========================================================
  725.     BOOL bSetGroupFilter = FALSE;
  726.  
  727.     stat = SmsCreateFilter( GROUP_FILTER, hConnect, &hFilter );
  728.     CHKSTAT_RTN("SmsCreateFilter (group filter)");
  729.     TOKEN GroupToken;
  730.     memset( &GroupToken, 0, sizeof(TOKEN) );
  731.  
  732.     printf("Filter Group= MICROSOFT|IDENTIFICATION|1.0 [y/n]? ");
  733.     gets(reply);
  734.     if (reply[0] == 'y') {
  735.  
  736.         // Define a (perculating) filter: Group=Ident.
  737.         // -------------------------------------------------
  738.         strcpy( GroupToken.szName, "GroupClass" );
  739.         strcpy( GroupToken.szValue, "MICROSOFT|IDENTIFICATION|1.0" );
  740.         GroupToken.dwOp = QOP_STR_EQ;
  741.  
  742.         stat = SmsAddToken( hFilter, OP_OR, &GroupToken, 0 );
  743.         CHKSTAT_RTN("SmsAddToken (group filter - ID group)");
  744.         bSetGroupFilter = TRUE;
  745.     }
  746.  
  747.     // =========================================================
  748.     //  This one says that we only want the netcard
  749.     //  group for a machine.
  750.     // =========================================================
  751.     printf("Filter Group= MICROSOFT|NETCARD|1.0 [y/n]? ");
  752.     gets(reply);
  753.     if (reply[0] == 'y') {
  754.  
  755.         // Define a (perculating) filter: Group=Netcard.
  756.         // -------------------------------------------------
  757.         strcpy( GroupToken.szName, "GroupClass" );
  758.         strcpy( GroupToken.szValue, "MICROSOFT|NETCARD|1.0" );
  759.         GroupToken.dwOp = QOP_STR_EQ;
  760.  
  761.         stat = SmsAddToken( hFilter, OP_OR, &GroupToken, 0 );
  762.         CHKSTAT_RTN("SmsAddToken (group filter - Netcard group)");
  763.         bSetGroupFilter = TRUE;
  764.     }
  765.  
  766.     // Did user select a group filter? If so apply it to the container now.
  767.     // ====================================================================
  768.     if (bSetGroupFilter) {
  769.         stat = SmsSetFilter( hContainer, hFilter );
  770.         CHKSTAT_RTN("SmsSetFilter (group filter)");
  771.     }
  772.     SmsCloseFilter( hFilter );
  773.  
  774.     return(TRUE);
  775.  
  776. }  /* setSiteFilters */
  777.  
  778.  
  779.  
  780.  
  781. // ====================================================================
  782. // This function sets filters appropriate for a jobs container.
  783. // It illustrates the use of jobs filters.
  784. //
  785. // If no job filter is selected, then all jobs will be retrieved.
  786. // Currently, this will only test out the JobType tokens.
  787. // The user can select one or more of the following JobType tokens in
  788. // a job filter:
  789. //  look at workstation install jobs
  790. //  look at server share jobs
  791. //  look at remove package jobs
  792. //  look at system jobs (ie all the rest).
  793. //
  794. // NOTE: minimal error checking at the moment.
  795. //
  796. // ====================================================================
  797. BOOL setJobFilters( HANDLE hConnect, HANDLE hContainer )
  798. {
  799.  
  800.     SMS_STATUS stat = SMS_OK;
  801.     HANDLE hFilter;
  802.     BOOL done = FALSE;
  803.     char reply[10];
  804.     BOOL bRet = TRUE;
  805.     BOOL bTokenSelected = FALSE;    // Has token been added to filter?
  806.     const INT iIndex = -2;          // Token index in filter. -2 means add to end.
  807.  
  808.     printf("Select filters for jobs container.\n");
  809.     printf("Choices are: \n\tWorkstation install 'w'\n\tServer share 's'\n\tRemove package 'r'\n\tSystem 'y'\n");
  810.  
  811.     stat = SmsCreateFilter( JOB_FILTER, hConnect, &hFilter );
  812.     CHKSTAT_RTN("SmsCreateFilter (job filter)");
  813.  
  814.     TOKEN JobToken;
  815.     memset( &JobToken, 0, sizeof(TOKEN) );
  816.  
  817.     while (!done) {
  818.         printf("\nSelect one of [wsry] 'x' to complete: ");
  819.         gets(reply);
  820.  
  821.         switch (reply[0]) {
  822.         case 'W':
  823.         case 'w':
  824.             // Workstation install jobs
  825.             strcpy( JobToken.szName, "JobType" );
  826.             strcpy( JobToken.szValue, "Install" );
  827.             JobToken.dwOp = QOP_STR_EQ;
  828.             stat = SmsAddToken( hFilter, OP_OR, &JobToken, iIndex );
  829.             CHKSTAT_RTN("SmsAddToken (job filter)");
  830.             bTokenSelected = TRUE;
  831.             break;
  832.  
  833.         case 'S':
  834.         case 's':
  835.             // Server share jobs
  836.             strcpy( JobToken.szName, "JobType" );
  837.             strcpy( JobToken.szValue, "Server" );
  838.             JobToken.dwOp = QOP_STR_EQ;
  839.             stat = SmsAddToken( hFilter, OP_OR, &JobToken, iIndex );
  840.             CHKSTAT_RTN("SmsAddToken (job filter)");
  841.             bTokenSelected = TRUE;
  842.             break;
  843.  
  844.         case 'R':
  845.         case 'r':
  846.             // Remove package jobs
  847.             strcpy( JobToken.szName, "JobType" );
  848.             strcpy( JobToken.szValue, "Remove package" );
  849.             JobToken.dwOp = QOP_STR_EQ;
  850.             stat = SmsAddToken( hFilter, OP_OR, &JobToken, iIndex );
  851.             CHKSTAT_RTN("SmsAddToken (job filter)");
  852.             bTokenSelected = TRUE;
  853.             break;
  854.  
  855.         case 'Y':
  856.         case 'y':
  857.             // System jobs
  858.             strcpy( JobToken.szName, "JobType" );
  859.             strcpy( JobToken.szValue, "System" );
  860.             JobToken.dwOp = QOP_STR_EQ;
  861.             stat = SmsAddToken( hFilter, OP_OR, &JobToken, iIndex );
  862.             CHKSTAT_RTN("SmsAddToken (job filter)");
  863.             bTokenSelected = TRUE;
  864.             break;
  865.  
  866.         case 'X':
  867.         case 'x':
  868.             // finished
  869.             done = TRUE;
  870.             break;
  871.  
  872.         default:
  873.             // give message again
  874.             printf("Invalid response\n");
  875.             printf("Choices are: \n\tWorkstation install 'w'\n\tServer share 's'\n\tRemove package 'r'\n\tSystem 'y'\n");
  876.         }
  877.     }
  878.  
  879.  
  880.     // Only apply the filter if a token has been selected.
  881.     // ---------------------------------------------------
  882.     if (bTokenSelected) {
  883.         stat = SmsSetFilter( hContainer, hFilter );
  884.         CHKSTAT_RTN("SmsSetFilter (job filter)");
  885.     }
  886.     SmsCloseFilter( hFilter );
  887.  
  888.  
  889.     return(bRet);
  890. }
  891.  
  892.  
  893. // ====================================================================
  894. //
  895. // This function sets filters appropriate for a packages container.
  896. // It illustrates the use of packages filters.
  897. //
  898. // If no package filter is selected, then all packages will be retrieved.
  899. //
  900. // Package filter only uses the value field, values are:
  901. //  "Workstation", "Server", "Inventory"
  902. //
  903. // NOTE: minimal error checking at the moment.
  904. //
  905. // ====================================================================
  906. BOOL setPkgFilters( HANDLE hConnect, HANDLE hContainer )
  907. {
  908.  
  909.     SMS_STATUS stat = SMS_OK;
  910.     HANDLE hFilter;
  911.     BOOL done = FALSE;
  912.     char reply[10];
  913.     BOOL bRet = TRUE;
  914.     BOOL bTokenSelected = FALSE;    // Has token been added to filter?
  915.     const INT iIndex = -2;          // Token index in filter. -2 means add to end.
  916.  
  917.     printf("Select filters for packages container.\n");
  918.     printf("Choices are: \n\tWorkstation 'w'\n\tServer 's'\n\tInventory 'i'\n");
  919.  
  920.     stat = SmsCreateFilter( PACKAGE_FILTER, hConnect, &hFilter );
  921.     CHKSTAT_RTN("SmsCreateFilter (package filter)");
  922.  
  923.     TOKEN PkgToken;
  924.     memset( &PkgToken, 0, sizeof(TOKEN) );
  925.  
  926.     while (!done) {
  927.         printf("\nSelect one of [wsi] 'x' to complete: ");
  928.         gets(reply);
  929.  
  930.         switch (reply[0]) {
  931.         case 'W': case 'w':
  932.             // Workstation packages
  933.             strcpy( PkgToken.szName, "PackageType" );
  934.             strcpy( PkgToken.szValue, "Workstation" );
  935.             PkgToken.dwOp = QOP_STR_EQ;
  936.             stat = SmsAddToken( hFilter, OP_OR, &PkgToken, iIndex );
  937.             CHKSTAT_RTN("SmsAddToken (package filter)");
  938.             bTokenSelected = TRUE;
  939.             break;
  940.  
  941.         case 'S': case 's':
  942.             // Server share packages
  943.             strcpy( PkgToken.szName, "PackageType" );
  944.             strcpy( PkgToken.szValue, "Server" );
  945.             PkgToken.dwOp = QOP_STR_EQ;
  946.             stat = SmsAddToken( hFilter, OP_OR, &PkgToken, iIndex );
  947.             CHKSTAT_RTN("SmsAddToken (package filter)");
  948.             bTokenSelected = TRUE;
  949.             break;
  950.  
  951.         case 'I': case 'i':
  952.             // Inventory package.
  953.             strcpy( PkgToken.szName, "PackageType" );
  954.             strcpy( PkgToken.szValue, "Inventory" );
  955.             PkgToken.dwOp = QOP_STR_EQ;
  956.             stat = SmsAddToken( hFilter, OP_OR, &PkgToken, iIndex );
  957.             CHKSTAT_RTN("SmsAddToken (package filter)");
  958.             bTokenSelected = TRUE;
  959.             break;
  960.  
  961.         case 'X':
  962.         case 'x':
  963.             // finished
  964.             done = TRUE;
  965.             break;
  966.  
  967.         default:
  968.             // give message again
  969.             printf("Invalid response\n");
  970.             printf("Choices are: \n\tWorkstation 'w'\n\tServer 's'\n\tInventory 'i'\n");
  971.         }
  972.     }
  973.  
  974.  
  975.     // Only apply the filter if a token has been selected.
  976.     // ---------------------------------------------------
  977.     if (bTokenSelected) {
  978.         stat = SmsSetFilter( hContainer, hFilter );
  979.         CHKSTAT_RTN("SmsSetFilter (package filter)");
  980.     }
  981.  
  982.     SmsCloseFilter( hFilter );
  983.  
  984.  
  985.     return(bRet);
  986. }
  987.  
  988.  
  989.  
  990. // ====================================================================
  991. // InputString
  992. //
  993. // Prompt the user to input a string and return the string in the
  994. // specified buffer.
  995. //
  996. // Parameters:
  997. //      const char* pszMessage
  998. //          The user prompt to display.
  999. //
  1000. //      char* pszResult
  1001. //          Pointer to the buffer where the user's input will be returned.
  1002. //
  1003. // Returns;
  1004. //      The user's input is returned via the given buffer.
  1005. //
  1006. // ====================================================================
  1007. void InputString(const char* pszMessage, char* pszResult)
  1008. {
  1009.     printf("%s: ", pszMessage);
  1010.     gets(pszResult);
  1011. }
  1012.  
  1013.  
  1014.  
  1015.  
  1016. // ====================================================================
  1017. // ConnectToDatasource
  1018. //
  1019. // Get the datasource connection information from the user and use it
  1020. // to connect to the datasource.
  1021. //
  1022. // Parameters:  None.
  1023. //
  1024. // Returns:
  1025. //      The connection handle or NULL if the connection failed.
  1026. //
  1027. // ====================================================================
  1028. HANDLE ConnectToDatasource()
  1029. {
  1030.     // Get the information we need to connect to the
  1031.     // data source from the user.
  1032.     //==============================================
  1033.     char szServer[CCH_MAXINPUT];
  1034.     char szUser[CCH_MAXINPUT];
  1035.     char szPasswd[CCH_MAXINPUT];
  1036.     char szDatabase[CCH_MAXINPUT];
  1037.  
  1038.     printf("\n");
  1039.     printf("**************************\n");
  1040.     printf("* Connect to data source *\n");
  1041.     printf("**************************\n");
  1042.     InputString("SQL server name", szServer);
  1043.     InputString("SQL database name", szDatabase);
  1044.     InputString("User name for SQL server", szUser);
  1045.     InputString("Password for SQL server", szPasswd);
  1046.     printf("\n");
  1047.  
  1048.  
  1049.     // Connect to a data source. SQL in this case.
  1050.     // ===========================================
  1051.     DATASOURCE dsParams;
  1052.  
  1053.     dsParams.sqlParams.ds          = DB_SQL;
  1054.     dsParams.sqlParams.pszServer   = szServer;
  1055.     dsParams.sqlParams.pszUserName = szUser;
  1056.     dsParams.sqlParams.pszPasswd   = szPasswd;
  1057.     dsParams.sqlParams.pszDbName   = szDatabase;
  1058.     dsParams.sqlParams.pFunc       = NULL;         // No encryption.
  1059.     dsParams.sqlParams.pszKey      = "";
  1060.  
  1061.     HANDLE hConnect;
  1062.     SMS_STATUS stat;
  1063.     stat = SmsDataSourceConnect( &dsParams, &hConnect);
  1064.  
  1065.     if (stat != SMS_OK) {
  1066.         hConnect = NULL;
  1067.         DisplaySmsError("Connect to data source failed", stat);
  1068.     }
  1069.  
  1070.     return( hConnect );
  1071. }
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079. // ====================================================================
  1080. // DidRequestHelp
  1081. //
  1082. // Check the program's arguments to see if the user asked for
  1083. // the help screen to be displayed.
  1084. //
  1085. // Parameters:
  1086. //      int argc
  1087. //          The argc value from main(argc, argv)
  1088. //
  1089. //      char** argv
  1090. //          The argv value from main(argc, argv)
  1091. //
  1092. // Returns:
  1093. //      TRUE if command line parameters included a request
  1094. //      for help to be displayed.
  1095. //
  1096. // ====================================================================
  1097. BOOL DidRequestHelp( int argc, char **argv )
  1098. {
  1099.     if (argc == 2  && (strcmp(argv[1], "-help") == 0)) {
  1100.         return(TRUE);
  1101.     }
  1102.     else {
  1103.         return(FALSE);
  1104.     }
  1105. }
  1106.  
  1107.  
  1108. // ====================================================================
  1109. // DisplayHelp
  1110. //
  1111. // This function displays the samples help screen.
  1112. //
  1113. // Parameters:
  1114. //      None
  1115. //
  1116. // Returns:
  1117. //      Nothing.
  1118. //
  1119. // ====================================================================
  1120. void DisplayHelp()
  1121. {
  1122.     printf("\n\n");
  1123.     printf("********************************************************\n");
  1124.     printf("* testall.exe:                                         *\n");
  1125.     printf("*                                                      *\n");
  1126.     printf("* This is a sample program for the SMS SDK. It can be  *\n");
  1127.     printf("* used to view the contents of site, job, and package  *\n");
  1128.     printf("* folders in the SMS database.                         *\n");
  1129.     printf("*                                                      *\n");
  1130.     printf("* Syntax:                                              *\n");
  1131.     printf("*     testall.exe [-help]                              *\n");
  1132.     printf("*                                                      *\n");
  1133.     printf("* Switches:                                            *\n");
  1134.     printf("*     -help       Display this help screen.            *\n");
  1135.     printf("*                                                      *\n");
  1136.     printf("********************************************************\n");
  1137.     printf("\n");
  1138. }
  1139.  
  1140.  
  1141.  
  1142. // ====================================================================
  1143. // DisplayGreeting
  1144. //
  1145. // Display the initial greeting banner.
  1146. //
  1147. // Parameters:
  1148. //     None.
  1149. //
  1150. // Returns:
  1151. //     Nothing.
  1152. //
  1153. // ====================================================================
  1154. void DisplayGreeting()
  1155. {
  1156.     // For this sample, the greeting is identical to the help screen.
  1157.     //===============================================================
  1158.     DisplayHelp();
  1159. }
  1160.  
  1161.  
  1162.  
  1163. /* EOF: testall.cpp */
  1164.  
  1165.