MGRP.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:20k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // ====================================================================
  2. //
  3. //  File: mgrp.cpp
  4. //
  5. //  Copyright (C) 1996 by Microsoft Corporation.
  6. //
  7. //  Author:
  8. //      Jonathan Shuval     Microsoft Corp.
  9. //
  10. //
  11. //  This sample shows how to create a machine group and insert machines
  12. //  into it.
  13. //
  14. // ====================================================================
  15. // ====================================================================
  16. //  Includes.
  17. // ====================================================================
  18. #include <afx.h>
  19. #include <smsapi.h>             // Header for the APIs.
  20. #include <time.h>               // For converting time scalars into string.
  21. // Include the GetStatusName function.
  22. // -------------------------------------
  23. #include "..commonstatus.inc"
  24. // ====================================================================
  25. //  Defines.
  26. // ====================================================================
  27. #define CCH_MAXINPUT 256
  28. // ====================================================================
  29. //  Local prototypes.
  30. // ====================================================================
  31. // Does the real work.
  32. // -------------------------------------------------------------
  33. void doTheWork( HANDLE hConnect );
  34. // Set filters according to what container we're looking at.
  35. // -------------------------------------------------------------
  36. BOOL setMachFilters( HANDLE hConnect, HANDLE hContainer );
  37. // Functions to display folders, scalars, and expressions.
  38. // -------------------------------------------------------------
  39. void DisplayFolder( HANDLE hFolder );
  40. void DisplayScalars( HANDLE hFolder );
  41. // Prompt the user for input and return the reply.
  42. // -------------------------------------------------------------
  43. void InputString(const char* pszMessage, char* pszResult);
  44. // Connect to the SMS datasource.
  45. // -------------------------------------------------------------
  46. HANDLE ConnectToDatasource();
  47. // Display an error message with its SMS status value.
  48. // -------------------------------------------------------------
  49. void DisplaySmsError(const char* pszMessage, SMS_STATUS stat);
  50. // Get the string equivallent for an SMS status code.
  51. // -------------------------------------------------------------
  52. const char *GetStatusName(SMS_STATUS stat);
  53. // Set a string scalar.
  54. // -------------------------------------------------------------
  55. SMS_STATUS SetScalarString( HANDLE hFolder, char *pszName, char *pszValue);
  56. // ====================================================================
  57. //
  58. //  Macros for checking status
  59. //
  60. // ====================================================================
  61.         // Void return
  62. #define CHKSTAT(str) if (stat != SMS_OK) { 
  63.         DisplaySmsError(str, stat);         
  64.         return; }
  65.         // Bool return
  66. #define CHKSTAT_RTN(str) if (stat != SMS_OK) { 
  67.         DisplaySmsError(str, stat);             
  68.         return(FALSE); }
  69. // ====================================================================
  70. //
  71. //  The work starts here.
  72. //
  73. // ====================================================================
  74. void main()
  75. {
  76.     HANDLE hConnect;
  77.     // Get and display API version.
  78.     // ----------------------------
  79.     char *pszVersion;
  80.     SmsAPIVer( &pszVersion );
  81.     printf("%sn", pszVersion );
  82.     //===========================================
  83.     // Connect to the SMS datasource.
  84.     //===========================================
  85.     hConnect = ConnectToDatasource();
  86.     if (hConnect == NULL) {
  87.         return;
  88.     }
  89.     // This loop allows us to do the real work multiple times.
  90.     // =======================================================
  91.     BOOL bDone = FALSE;
  92.     char reply[10];
  93.     while (!bDone) {
  94.         doTheWork( hConnect );
  95.         printf("Restart [y/n]? "); gets(reply);
  96.         bDone = (reply[0] != 'y' && reply[0] != 'Y');
  97.     }
  98.     // Disconnect from the datasource.
  99.     // ===============================
  100.     SmsDataSourceDisconnect( hConnect );
  101. }  /* main */
  102. // ====================================================================
  103. //
  104. //  This function does whatever work is required.
  105. //  In this case, it will:
  106. //      - open a machine group container
  107. //      - create a machine group folder
  108. //      - open a machine container
  109. //      - select machine folders from mach container that I want
  110. //          to copy to the mgrp folder
  111. //      - loop copying these machine folders to the mgrp folder
  112. //      - link and commit the mgrp folder
  113. //      - close everything
  114. //
  115. // ====================================================================
  116. void doTheWork( HANDLE hConnect )
  117. {
  118.     HANDLE hMGrpContainer;
  119.     HANDLE hMachContainer;
  120.     SMS_STATUS stat;
  121.     // Open the containers
  122.     // ===================
  123.     stat = SmsOpenContainer( C_MACHINEGROUP, hConnect, &hMGrpContainer );
  124.     if (stat != SMS_OK) {
  125.         DisplaySmsError("SmsOpenContainer (mach grp) failed", stat);
  126.         return;
  127.     }
  128.     stat = SmsOpenContainer( C_MACHINE, hConnect, &hMachContainer );
  129.     if (stat != SMS_OK) {
  130.         DisplaySmsError("SmsOpenContainer (mach) failed", stat);
  131.         SmsCloseContainer( hMGrpContainer );
  132.         return;
  133.     }
  134.     // Create machine group folder
  135.     // ===========================
  136.     HANDLE hMGrpFolder;
  137.     stat = SmsCreateFolder( hMGrpContainer, F_MACHINEGROUP, "", &hMGrpFolder );
  138.     if (stat != SMS_OK) {
  139.         char szError[256];
  140.         sprintf(szError, "SmsCreateFolder failed to create MachineGroup folder");
  141.         DisplaySmsError(szError, stat);
  142.         SmsCloseContainer( hMGrpContainer );
  143.         SmsCloseContainer( hMachContainer );
  144.         return;
  145.     }
  146.     // Select machine folders that we want tp put in to the mgrp folder.
  147.     // Just get all the PC machines from the mach container for now.
  148.     // Set filter for arch PC only machines.
  149.     // =================================================================
  150.     setMachFilters( hConnect, hMachContainer );
  151.     stat = SmsPopulate( hMachContainer, POP_SYNC, NULL );
  152.     if (stat != SMS_OK) {
  153.         DisplaySmsError("Bad return from SmsPopulate", stat);
  154.         // Close everything and return.
  155.         SmsCloseContainer( hMGrpContainer );
  156.         SmsCloseContainer( hMachContainer );
  157.         SmsCloseFolder( hMGrpFolder );
  158.         return;
  159.     }
  160.     // Loop getting a handle to each machine folder and
  161.     // inserting it into the new mgroup folder.
  162.     // ================================================
  163.     DWORD ctFolders;
  164.     SmsGetFolderCount( hMachContainer, F_ANY, &ctFolders );
  165.     printf("n======== Mach Container has %d foldersn", ctFolders);
  166.     HANDLE hFolder;
  167.     char szFolderID[100];               // This folder's ID.
  168.     BOOL bValid = TRUE;
  169.     for (DWORD dwLoop = 0; dwLoop < ctFolders; dwLoop++) {
  170.         SmsGetNextFolder( hMachContainer, F_ANY, &hFolder );
  171.         // Display message saying what we've got
  172.         // -------------------------------------
  173.         stat = SmsGetFolderID( hFolder, szFolderID );
  174.         printf("[%d] Got folder: %s, about to insert in new foldern",
  175.                 dwLoop+1, szFolderID);
  176.         // Insert the machine folder into the machine group folder.
  177.         // This can't do a straight swap of parents since we want to keep
  178.         // the machine folder's relationship to his current parent.
  179.         // What this API does therefore is to make a *copy* of the folder
  180.         // and link this copy into the mach group folder (ie the mach group
  181.         // folder becomes the new folder's parent).
  182.         // This means that this API returns a handle to the newly-created
  183.         // folder.
  184.         // ================================================================
  185.         HANDLE hNewFolder;
  186.         stat = SmsDupFolder( hMGrpFolder, hFolder, &hNewFolder );
  187.         if (stat != SMS_OK) {
  188.             printf("Failure duplicating folder %s: %dn", szFolderID, stat);
  189.             bValid = FALSE;
  190.             break;
  191.         }
  192.         // Now we need to link and commit the new machine folder to
  193.         // the machine group folder.
  194.         // ========================================================
  195.         stat = SmsLinkFolder( hNewFolder );
  196.         if (stat != SMS_OK) {
  197.             printf("Failure linking folder %s: %dn", szFolderID, stat);
  198.             goto CLOSE;
  199.         }
  200.         stat = SmsCommitFolder( hNewFolder );
  201.         if (stat != SMS_OK && stat != SMS_PARENT_NEEDS_COMMIT) {
  202.             printf("Failure comitting folder %s: %dn", szFolderID, stat);
  203.             goto CLOSE;
  204.         }
  205.         SmsCloseFolder( hFolder );
  206.         SmsCloseFolder( hNewFolder );
  207.     }
  208.     // Set scalars for the mach group folder.
  209.     // ======================================
  210.     char szBuff[99];
  211.     InputString("Give me a unique name for the mach gp", szBuff);
  212.     SetScalarString( hMGrpFolder, "Name", szBuff );
  213.     SetScalarString( hMGrpFolder, "Comment", "some comment" );
  214.     // Link mach grp folder into parent and commit it.
  215.     // ===============================================
  216.     stat = SmsLinkFolder( hMGrpFolder );
  217.     if (stat != SMS_OK) {
  218.         DisplaySmsError("SmsLinkFolder failed on the mach Group folder", stat);
  219.         goto CLOSE;
  220.     }
  221.     // Write it back to data source.
  222.     // =============================
  223.     stat = SmsCommitFolder( hMGrpFolder );
  224.     if (stat != SMS_OK) {
  225.         DisplaySmsError("SmsCommitFolder failed on the mach Group folder", stat);
  226.         goto CLOSE;
  227.     }
  228.     // If we got here then all seems to be ok.
  229.     // Display the mach group folder
  230.     // =======================================
  231.     DisplayFolder( hMGrpFolder );
  232.     // Close everything - we're done.
  233.     // ==============================
  234. CLOSE:
  235.     SmsCloseContainer( hMGrpContainer );
  236.     SmsCloseContainer( hMachContainer );
  237.     SmsCloseFolder( hMGrpFolder );
  238.     printf("n********* All done ***************n");
  239. }
  240. // ====================================================================
  241. //  We are passed in a handle to a folder. We retrieve the folder's
  242. //  information, displaying scalars if any.
  243. //  We then recursively examine sub-folders (after closing the
  244. //  current folder).
  245. // ====================================================================
  246. void DisplayFolder( HANDLE hFolder )
  247. {
  248.     SMS_STATUS stat;
  249.     HANDLE hSubFolder;
  250.     DWORD fType;                   // type of folder we're dealing with.
  251.     char szfType[30];                   // type as a string.
  252.     DWORD totFolders;                   // Total number of sub-folders of
  253.                                         // all types.
  254.     char szFolderID[100];               // This folder's ID.
  255.     DWORD ctScalars;                    // How many scalars in this folder.
  256.     printf("n============================================================n");
  257.     // Get folder type and id.
  258.     // -----------------------
  259.     stat = SmsGetFolderID( hFolder, szFolderID );
  260.     if (stat != SMS_OK) {
  261.         if (stat == SMS_NEW_FOLDER) {
  262.             strcpy(szFolderID, "**New folder**");
  263.         } else {
  264.             CHKSTAT("SmsGetFolderID");
  265.         }
  266.     }
  267.     stat = SmsGetFolderType( hFolder, &fType, szfType );
  268.     CHKSTAT("SmsGetFolderType");
  269.     printf("Folder ID "%s" is a %snn", szFolderID, szfType);
  270.     // How many scalars in this folder.
  271.     // --------------------------------------------------------
  272.     stat = SmsGetScalarCount( hFolder, &ctScalars );
  273.     CHKSTAT("SmsGetScalarCount");
  274.     printf("Contains %d scalarsnn", ctScalars);
  275.     DisplayScalars( hFolder );
  276.     // Get count of all sub-folders (ie of all types).
  277.     // and allocate space for their handles.
  278.     // -----------------------------------------------
  279.     stat = SmsGetFolderCount( hFolder, F_ANY, &totFolders );
  280.     printf("Contains %d foldersnn", totFolders);
  281.     char szSubFolderID[100];
  282.     DWORD ctFolders;
  283.     HANDLE *phFolders;
  284.     phFolders = (HANDLE *)malloc(totFolders * sizeof(HANDLE));
  285.     // This loop gets the sub-folder IDs and displays them.
  286.     // ====================================================
  287.     for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
  288.         // Get a handle to a sub-folder.
  289.         // -----------------------------
  290.         stat = SmsGetNextFolder( hFolder, F_ANY, &hSubFolder );
  291.         CHKSTAT("SmsGetNextFolder");
  292.         phFolders[ctFolders] = hSubFolder;
  293.         // Get and display the sub-folder's ID.
  294.         // ------------------------------------
  295.         stat = SmsGetFolderID( hSubFolder, szSubFolderID );
  296.         CHKSTAT("SmsGetFolderID");
  297.         printf("tSub-folder: "%s"n", szSubFolderID);
  298.     }
  299.     // =======================================================
  300.     // We can now release the handle that was passed in to us.
  301.     // If we wait until the function returns then, because we
  302.     // recurse, we don't release it till the very end.
  303.     // =======================================================
  304.     SmsCloseFolder( hFolder );
  305.     // This loop gets the sub-folders and displays them.
  306.     // =================================================
  307.     for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
  308.         DisplayFolder( phFolders[ctFolders] );
  309.     }
  310.     // Free the folder handle array.
  311.     // -----------------------------
  312.     free( phFolders );
  313. }  /* DisplayFolder */
  314. // ====================================================================
  315. //
  316. //  Display all the scalars for the folder.
  317. //
  318. // Note: the buffer for string scalars has been deliberately set to a
  319. // value lower than the maximum. If we encounter a string scalar whose
  320. // value exceeds this amount then we will print the 'data truncated'
  321. // message.
  322. //
  323. // ====================================================================
  324. void DisplayScalars( HANDLE hFolder )
  325. {
  326.     SMS_STATUS stat = SMS_OK;
  327.     SCALAR scalar;
  328.     char szName[50];                        // Buffer for name.
  329.     char szValue[SMS_DATA_BUFF_SIZE+1];     // Buffer for string value.
  330.     BYTE byValue[SMS_DATA_BUFF_SIZE+1];     // Buffer for binary scalars.
  331.     scalar.pszName  = szName;
  332.     scalar.pszValue = szValue;
  333.     scalar.pValue   = byValue;
  334.     char *pszTime;          // For time scalars.
  335.     while (1) {
  336.         scalar.dwLen = sizeof(szValue)-1;       // must tell him the size
  337.         stat = SmsGetNextScalar( hFolder, &scalar);
  338.         if (stat != SMS_OK && stat != SMS_MORE_DATA) {
  339.             break;
  340.         }
  341.         if (stat == SMS_MORE_DATA) {
  342.             printf("Receive buffer too small, should be %d. Data truncatedn",
  343.                             scalar.dwLen);
  344.         }
  345.         // Check scalar type, display accordingly.
  346.         // ---------------------------------------
  347.         switch (scalar.scType) {
  348.         case SCALAR_STRING:
  349.             printf("t%30s: %sn", scalar.pszName, scalar.pszValue);
  350.             break;
  351.         case SCALAR_INT:
  352.             printf("t%30s: %ldn", scalar.pszName, scalar.dwValue);
  353.             break;
  354.         case SCALAR_TIME:
  355.             // If there is a string equivalence use it.
  356.             if (scalar.bStringEquivalence) {
  357.                 printf("t%30s: %sn", scalar.pszName, scalar.pszValue);
  358.             } else {
  359.                 pszTime = ctime( &scalar.tValue );
  360.                 printf("t%30s: %s", scalar.pszName, pszTime);
  361.             }
  362.             break;
  363.         case SCALAR_BINARY:
  364.             // Got binary data.
  365.             // Just tell the user how much data there is.
  366.             printf("t%30s: Binary data - %d bytes of datan",
  367.                         scalar.pszName, scalar.dwLen);
  368.             break;
  369.         }
  370.     }
  371.     // Why did we exit (other than no more scalars)?
  372.     // ---------------------------------------------
  373.     if (stat != SMS_NO_MORE_DATA) {
  374.         DisplaySmsError("Bad return from Scalar access", stat);
  375.     }
  376.     // Terminate with newline.
  377.     // -----------------------
  378.     printf("n");
  379. }
  380. // ********************************************************************
  381. //      Helper functions.
  382. // ********************************************************************
  383. // ====================================================================
  384. // This function sets the filters when we are looking at a Machine
  385. // container.
  386. //
  387. // Want only PC archs, so we set an architecture filter.
  388. //
  389. // ====================================================================
  390. BOOL setMachFilters( HANDLE hConnect, HANDLE hContainer )
  391. {
  392.     HANDLE hFilter;
  393.     // =========================================================
  394.     // Architecture filter.
  395.     // Architecture = Personal Computer.
  396.     // =========================================================
  397.     SmsCreateFilter( ARCHITECTURE_FILTER, hConnect, &hFilter );
  398.     TOKEN ArchToken;
  399.     memset( &ArchToken, 0, sizeof(TOKEN) );
  400.     strcpy( ArchToken.szName, "Architecture" );
  401.     strcpy( ArchToken.szValue, "Personal Computer" );
  402.     ArchToken.dwOp = QOP_STR_EQ;
  403.     SmsAddToken( hFilter, OP_OR, &ArchToken, 0 );
  404.     SmsSetFilter( hContainer, hFilter );
  405.     SmsCloseFilter( hFilter );
  406.     SmsCloseFilter( hFilter );
  407.     return(TRUE);
  408. }  /* setMachFilters */
  409. // ====================================================================
  410. // InputString
  411. //
  412. // Prompt the user to input a string and return the string in the
  413. // specified buffer.
  414. //
  415. // Parameters:
  416. //      const char* pszMessage
  417. //          The user prompt to display.
  418. //
  419. //      char* pszResult
  420. //          Pointer to the buffer where the user's input will be returned.
  421. //
  422. // Returns;
  423. //      The user's input is returned via the given buffer.
  424. //
  425. // ====================================================================
  426. void InputString(const char* pszMessage, char* pszResult)
  427. {
  428.     printf("%s: ", pszMessage);
  429.     gets(pszResult);
  430. }
  431. // ====================================================================
  432. // ConnectToDatasource
  433. //
  434. // Get the datasource connection information from the user and use it
  435. // to connect to the datasource.
  436. //
  437. // Parameters:  None.
  438. //
  439. // Returns:
  440. //      The connection handle or NULL if the connection failed.
  441. //
  442. // ====================================================================
  443. HANDLE ConnectToDatasource()
  444. {
  445.     // Get the information we need to connect to the
  446.     // data source from the user.
  447.     //==============================================
  448.     char szServer[CCH_MAXINPUT];
  449.     char szUser[CCH_MAXINPUT];
  450.     char szPasswd[CCH_MAXINPUT];
  451.     char szDatabase[CCH_MAXINPUT];
  452.     printf("n");
  453.     printf("**************************n");
  454.     printf("* Connect to data source *n");
  455.     printf("**************************n");
  456.     InputString("SQL server name", szServer);
  457.     InputString("SQL database name", szDatabase);
  458.     InputString("User name for SQL server", szUser);
  459.     InputString("Password for SQL server", szPasswd);
  460.     printf("n");
  461.     // Connect to a data source. SQL in this case.
  462.     // ===========================================
  463.     DATASOURCE dsParams;
  464.     dsParams.sqlParams.ds          = DB_SQL;
  465.     dsParams.sqlParams.pszServer   = szServer;
  466.     dsParams.sqlParams.pszUserName = szUser;
  467.     dsParams.sqlParams.pszPasswd   = szPasswd;
  468.     dsParams.sqlParams.pszDbName   = szDatabase;
  469.     dsParams.sqlParams.pFunc       = NULL;         // No encryption.
  470.     dsParams.sqlParams.pszKey      = "";
  471.     HANDLE hConnect;
  472.     SMS_STATUS stat;
  473.     stat = SmsDataSourceConnect( &dsParams, &hConnect);
  474.     if (stat != SMS_OK) {
  475.         hConnect = NULL;
  476.         DisplaySmsError("Connect to data source failed", stat);
  477.     }
  478.     return( hConnect );
  479. }
  480. SMS_STATUS SetScalarString(HANDLE hFolder, char* pszName, char* pszValue)
  481. {
  482.     SCALAR sc;
  483.     sc.pszName = pszName;
  484.     sc.scType = SCALAR_STRING;
  485.     sc.pszValue = pszValue;
  486.     SMS_STATUS stat;
  487.     stat = SmsSetScalar(hFolder, &sc);
  488.     return( stat );
  489. }
  490. /* EOF: mgrp.cpp */