MGRP.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:20k
源码类别:
Windows编程
开发平台:
Visual C++
- // ====================================================================
- //
- // File: mgrp.cpp
- //
- // Copyright (C) 1996 by Microsoft Corporation.
- //
- // Author:
- // Jonathan Shuval Microsoft Corp.
- //
- //
- // This sample shows how to create a machine group and insert machines
- // into it.
- //
- // ====================================================================
- // ====================================================================
- // Includes.
- // ====================================================================
- #include <afx.h>
- #include <smsapi.h> // Header for the APIs.
- #include <time.h> // For converting time scalars into string.
- // Include the GetStatusName function.
- // -------------------------------------
- #include "..commonstatus.inc"
- // ====================================================================
- // Defines.
- // ====================================================================
- #define CCH_MAXINPUT 256
- // ====================================================================
- // Local prototypes.
- // ====================================================================
- // Does the real work.
- // -------------------------------------------------------------
- void doTheWork( HANDLE hConnect );
- // Set filters according to what container we're looking at.
- // -------------------------------------------------------------
- BOOL setMachFilters( HANDLE hConnect, HANDLE hContainer );
- // Functions to display folders, scalars, and expressions.
- // -------------------------------------------------------------
- void DisplayFolder( HANDLE hFolder );
- void DisplayScalars( HANDLE hFolder );
- // Prompt the user for input and return the reply.
- // -------------------------------------------------------------
- void InputString(const char* pszMessage, char* pszResult);
- // Connect to the SMS datasource.
- // -------------------------------------------------------------
- HANDLE ConnectToDatasource();
- // Display an error message with its SMS status value.
- // -------------------------------------------------------------
- void DisplaySmsError(const char* pszMessage, SMS_STATUS stat);
- // Get the string equivallent for an SMS status code.
- // -------------------------------------------------------------
- const char *GetStatusName(SMS_STATUS stat);
- // Set a string scalar.
- // -------------------------------------------------------------
- SMS_STATUS SetScalarString( HANDLE hFolder, char *pszName, char *pszValue);
- // ====================================================================
- //
- // Macros for checking status
- //
- // ====================================================================
- // Void return
- #define CHKSTAT(str) if (stat != SMS_OK) {
- DisplaySmsError(str, stat);
- return; }
- // Bool return
- #define CHKSTAT_RTN(str) if (stat != SMS_OK) {
- DisplaySmsError(str, stat);
- return(FALSE); }
- // ====================================================================
- //
- // The work starts here.
- //
- // ====================================================================
- void main()
- {
- HANDLE hConnect;
- // Get and display API version.
- // ----------------------------
- char *pszVersion;
- SmsAPIVer( &pszVersion );
- printf("%sn", pszVersion );
- //===========================================
- // Connect to the SMS datasource.
- //===========================================
- hConnect = ConnectToDatasource();
- if (hConnect == NULL) {
- return;
- }
- // This loop allows us to do the real work multiple times.
- // =======================================================
- BOOL bDone = FALSE;
- char reply[10];
- while (!bDone) {
- doTheWork( hConnect );
- printf("Restart [y/n]? "); gets(reply);
- bDone = (reply[0] != 'y' && reply[0] != 'Y');
- }
- // Disconnect from the datasource.
- // ===============================
- SmsDataSourceDisconnect( hConnect );
- } /* main */
- // ====================================================================
- //
- // This function does whatever work is required.
- // In this case, it will:
- // - open a machine group container
- // - create a machine group folder
- // - open a machine container
- // - select machine folders from mach container that I want
- // to copy to the mgrp folder
- // - loop copying these machine folders to the mgrp folder
- // - link and commit the mgrp folder
- // - close everything
- //
- // ====================================================================
- void doTheWork( HANDLE hConnect )
- {
- HANDLE hMGrpContainer;
- HANDLE hMachContainer;
- SMS_STATUS stat;
- // Open the containers
- // ===================
- stat = SmsOpenContainer( C_MACHINEGROUP, hConnect, &hMGrpContainer );
- if (stat != SMS_OK) {
- DisplaySmsError("SmsOpenContainer (mach grp) failed", stat);
- return;
- }
- stat = SmsOpenContainer( C_MACHINE, hConnect, &hMachContainer );
- if (stat != SMS_OK) {
- DisplaySmsError("SmsOpenContainer (mach) failed", stat);
- SmsCloseContainer( hMGrpContainer );
- return;
- }
- // Create machine group folder
- // ===========================
- HANDLE hMGrpFolder;
- stat = SmsCreateFolder( hMGrpContainer, F_MACHINEGROUP, "", &hMGrpFolder );
- if (stat != SMS_OK) {
- char szError[256];
- sprintf(szError, "SmsCreateFolder failed to create MachineGroup folder");
- DisplaySmsError(szError, stat);
- SmsCloseContainer( hMGrpContainer );
- SmsCloseContainer( hMachContainer );
- return;
- }
- // Select machine folders that we want tp put in to the mgrp folder.
- // Just get all the PC machines from the mach container for now.
- // Set filter for arch PC only machines.
- // =================================================================
- setMachFilters( hConnect, hMachContainer );
- stat = SmsPopulate( hMachContainer, POP_SYNC, NULL );
- if (stat != SMS_OK) {
- DisplaySmsError("Bad return from SmsPopulate", stat);
- // Close everything and return.
- SmsCloseContainer( hMGrpContainer );
- SmsCloseContainer( hMachContainer );
- SmsCloseFolder( hMGrpFolder );
- return;
- }
- // Loop getting a handle to each machine folder and
- // inserting it into the new mgroup folder.
- // ================================================
- DWORD ctFolders;
- SmsGetFolderCount( hMachContainer, F_ANY, &ctFolders );
- printf("n======== Mach Container has %d foldersn", ctFolders);
- HANDLE hFolder;
- char szFolderID[100]; // This folder's ID.
- BOOL bValid = TRUE;
- for (DWORD dwLoop = 0; dwLoop < ctFolders; dwLoop++) {
- SmsGetNextFolder( hMachContainer, F_ANY, &hFolder );
- // Display message saying what we've got
- // -------------------------------------
- stat = SmsGetFolderID( hFolder, szFolderID );
- printf("[%d] Got folder: %s, about to insert in new foldern",
- dwLoop+1, szFolderID);
- // Insert the machine folder into the machine group folder.
- // This can't do a straight swap of parents since we want to keep
- // the machine folder's relationship to his current parent.
- // What this API does therefore is to make a *copy* of the folder
- // and link this copy into the mach group folder (ie the mach group
- // folder becomes the new folder's parent).
- // This means that this API returns a handle to the newly-created
- // folder.
- // ================================================================
- HANDLE hNewFolder;
- stat = SmsDupFolder( hMGrpFolder, hFolder, &hNewFolder );
- if (stat != SMS_OK) {
- printf("Failure duplicating folder %s: %dn", szFolderID, stat);
- bValid = FALSE;
- break;
- }
- // Now we need to link and commit the new machine folder to
- // the machine group folder.
- // ========================================================
- stat = SmsLinkFolder( hNewFolder );
- if (stat != SMS_OK) {
- printf("Failure linking folder %s: %dn", szFolderID, stat);
- goto CLOSE;
- }
- stat = SmsCommitFolder( hNewFolder );
- if (stat != SMS_OK && stat != SMS_PARENT_NEEDS_COMMIT) {
- printf("Failure comitting folder %s: %dn", szFolderID, stat);
- goto CLOSE;
- }
- SmsCloseFolder( hFolder );
- SmsCloseFolder( hNewFolder );
- }
- // Set scalars for the mach group folder.
- // ======================================
- char szBuff[99];
- InputString("Give me a unique name for the mach gp", szBuff);
- SetScalarString( hMGrpFolder, "Name", szBuff );
- SetScalarString( hMGrpFolder, "Comment", "some comment" );
- // Link mach grp folder into parent and commit it.
- // ===============================================
- stat = SmsLinkFolder( hMGrpFolder );
- if (stat != SMS_OK) {
- DisplaySmsError("SmsLinkFolder failed on the mach Group folder", stat);
- goto CLOSE;
- }
- // Write it back to data source.
- // =============================
- stat = SmsCommitFolder( hMGrpFolder );
- if (stat != SMS_OK) {
- DisplaySmsError("SmsCommitFolder failed on the mach Group folder", stat);
- goto CLOSE;
- }
- // If we got here then all seems to be ok.
- // Display the mach group folder
- // =======================================
- DisplayFolder( hMGrpFolder );
- // Close everything - we're done.
- // ==============================
- CLOSE:
- SmsCloseContainer( hMGrpContainer );
- SmsCloseContainer( hMachContainer );
- SmsCloseFolder( hMGrpFolder );
- printf("n********* All done ***************n");
- }
- // ====================================================================
- // We are passed in a handle to a folder. We retrieve the folder's
- // information, displaying scalars if any.
- // We then recursively examine sub-folders (after closing the
- // current folder).
- // ====================================================================
- void DisplayFolder( HANDLE hFolder )
- {
- SMS_STATUS stat;
- HANDLE hSubFolder;
- DWORD fType; // type of folder we're dealing with.
- char szfType[30]; // type as a string.
- DWORD totFolders; // Total number of sub-folders of
- // all types.
- char szFolderID[100]; // This folder's ID.
- DWORD ctScalars; // How many scalars in this folder.
- printf("n============================================================n");
- // Get folder type and id.
- // -----------------------
- stat = SmsGetFolderID( hFolder, szFolderID );
- if (stat != SMS_OK) {
- if (stat == SMS_NEW_FOLDER) {
- strcpy(szFolderID, "**New folder**");
- } else {
- CHKSTAT("SmsGetFolderID");
- }
- }
- stat = SmsGetFolderType( hFolder, &fType, szfType );
- CHKSTAT("SmsGetFolderType");
- printf("Folder ID "%s" is a %snn", szFolderID, szfType);
- // How many scalars in this folder.
- // --------------------------------------------------------
- stat = SmsGetScalarCount( hFolder, &ctScalars );
- CHKSTAT("SmsGetScalarCount");
- printf("Contains %d scalarsnn", ctScalars);
- DisplayScalars( hFolder );
- // Get count of all sub-folders (ie of all types).
- // and allocate space for their handles.
- // -----------------------------------------------
- stat = SmsGetFolderCount( hFolder, F_ANY, &totFolders );
- printf("Contains %d foldersnn", totFolders);
- char szSubFolderID[100];
- DWORD ctFolders;
- HANDLE *phFolders;
- phFolders = (HANDLE *)malloc(totFolders * sizeof(HANDLE));
- // This loop gets the sub-folder IDs and displays them.
- // ====================================================
- for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
- // Get a handle to a sub-folder.
- // -----------------------------
- stat = SmsGetNextFolder( hFolder, F_ANY, &hSubFolder );
- CHKSTAT("SmsGetNextFolder");
- phFolders[ctFolders] = hSubFolder;
- // Get and display the sub-folder's ID.
- // ------------------------------------
- stat = SmsGetFolderID( hSubFolder, szSubFolderID );
- CHKSTAT("SmsGetFolderID");
- printf("tSub-folder: "%s"n", szSubFolderID);
- }
- // =======================================================
- // We can now release the handle that was passed in to us.
- // If we wait until the function returns then, because we
- // recurse, we don't release it till the very end.
- // =======================================================
- SmsCloseFolder( hFolder );
- // This loop gets the sub-folders and displays them.
- // =================================================
- for (ctFolders = 0; ctFolders < totFolders; ctFolders++) {
- DisplayFolder( phFolders[ctFolders] );
- }
- // Free the folder handle array.
- // -----------------------------
- free( phFolders );
- } /* DisplayFolder */
- // ====================================================================
- //
- // Display all the scalars for the folder.
- //
- // Note: the buffer for string scalars has been deliberately set to a
- // value lower than the maximum. If we encounter a string scalar whose
- // value exceeds this amount then we will print the 'data truncated'
- // message.
- //
- // ====================================================================
- void DisplayScalars( HANDLE hFolder )
- {
- SMS_STATUS stat = SMS_OK;
- SCALAR scalar;
- char szName[50]; // Buffer for name.
- char szValue[SMS_DATA_BUFF_SIZE+1]; // Buffer for string value.
- BYTE byValue[SMS_DATA_BUFF_SIZE+1]; // Buffer for binary scalars.
- scalar.pszName = szName;
- scalar.pszValue = szValue;
- scalar.pValue = byValue;
- char *pszTime; // For time scalars.
- while (1) {
- scalar.dwLen = sizeof(szValue)-1; // must tell him the size
- stat = SmsGetNextScalar( hFolder, &scalar);
- if (stat != SMS_OK && stat != SMS_MORE_DATA) {
- break;
- }
- if (stat == SMS_MORE_DATA) {
- printf("Receive buffer too small, should be %d. Data truncatedn",
- scalar.dwLen);
- }
- // Check scalar type, display accordingly.
- // ---------------------------------------
- switch (scalar.scType) {
- case SCALAR_STRING:
- printf("t%30s: %sn", scalar.pszName, scalar.pszValue);
- break;
- case SCALAR_INT:
- printf("t%30s: %ldn", scalar.pszName, scalar.dwValue);
- break;
- case SCALAR_TIME:
- // If there is a string equivalence use it.
- if (scalar.bStringEquivalence) {
- printf("t%30s: %sn", scalar.pszName, scalar.pszValue);
- } else {
- pszTime = ctime( &scalar.tValue );
- printf("t%30s: %s", scalar.pszName, pszTime);
- }
- break;
- case SCALAR_BINARY:
- // Got binary data.
- // Just tell the user how much data there is.
- printf("t%30s: Binary data - %d bytes of datan",
- scalar.pszName, scalar.dwLen);
- break;
- }
- }
- // Why did we exit (other than no more scalars)?
- // ---------------------------------------------
- if (stat != SMS_NO_MORE_DATA) {
- DisplaySmsError("Bad return from Scalar access", stat);
- }
- // Terminate with newline.
- // -----------------------
- printf("n");
- }
- // ********************************************************************
- // Helper functions.
- // ********************************************************************
- // ====================================================================
- // This function sets the filters when we are looking at a Machine
- // container.
- //
- // Want only PC archs, so we set an architecture filter.
- //
- // ====================================================================
- BOOL setMachFilters( HANDLE hConnect, HANDLE hContainer )
- {
- HANDLE hFilter;
- // =========================================================
- // Architecture filter.
- // Architecture = Personal Computer.
- // =========================================================
- SmsCreateFilter( ARCHITECTURE_FILTER, hConnect, &hFilter );
- TOKEN ArchToken;
- memset( &ArchToken, 0, sizeof(TOKEN) );
- strcpy( ArchToken.szName, "Architecture" );
- strcpy( ArchToken.szValue, "Personal Computer" );
- ArchToken.dwOp = QOP_STR_EQ;
- SmsAddToken( hFilter, OP_OR, &ArchToken, 0 );
- SmsSetFilter( hContainer, hFilter );
- SmsCloseFilter( hFilter );
- SmsCloseFilter( hFilter );
- return(TRUE);
- } /* setMachFilters */
- // ====================================================================
- // InputString
- //
- // Prompt the user to input a string and return the string in the
- // specified buffer.
- //
- // Parameters:
- // const char* pszMessage
- // The user prompt to display.
- //
- // char* pszResult
- // Pointer to the buffer where the user's input will be returned.
- //
- // Returns;
- // The user's input is returned via the given buffer.
- //
- // ====================================================================
- void InputString(const char* pszMessage, char* pszResult)
- {
- printf("%s: ", pszMessage);
- gets(pszResult);
- }
- // ====================================================================
- // ConnectToDatasource
- //
- // Get the datasource connection information from the user and use it
- // to connect to the datasource.
- //
- // Parameters: None.
- //
- // Returns:
- // The connection handle or NULL if the connection failed.
- //
- // ====================================================================
- HANDLE ConnectToDatasource()
- {
- // Get the information we need to connect to the
- // data source from the user.
- //==============================================
- char szServer[CCH_MAXINPUT];
- char szUser[CCH_MAXINPUT];
- char szPasswd[CCH_MAXINPUT];
- char szDatabase[CCH_MAXINPUT];
- printf("n");
- printf("**************************n");
- printf("* Connect to data source *n");
- printf("**************************n");
- InputString("SQL server name", szServer);
- InputString("SQL database name", szDatabase);
- InputString("User name for SQL server", szUser);
- InputString("Password for SQL server", szPasswd);
- printf("n");
- // Connect to a data source. SQL in this case.
- // ===========================================
- DATASOURCE dsParams;
- dsParams.sqlParams.ds = DB_SQL;
- dsParams.sqlParams.pszServer = szServer;
- dsParams.sqlParams.pszUserName = szUser;
- dsParams.sqlParams.pszPasswd = szPasswd;
- dsParams.sqlParams.pszDbName = szDatabase;
- dsParams.sqlParams.pFunc = NULL; // No encryption.
- dsParams.sqlParams.pszKey = "";
- HANDLE hConnect;
- SMS_STATUS stat;
- stat = SmsDataSourceConnect( &dsParams, &hConnect);
- if (stat != SMS_OK) {
- hConnect = NULL;
- DisplaySmsError("Connect to data source failed", stat);
- }
- return( hConnect );
- }
- SMS_STATUS SetScalarString(HANDLE hFolder, char* pszName, char* pszValue)
- {
- SCALAR sc;
- sc.pszName = pszName;
- sc.scType = SCALAR_STRING;
- sc.pszValue = pszValue;
- SMS_STATUS stat;
- stat = SmsSetScalar(hFolder, &sc);
- return( stat );
- }
- /* EOF: mgrp.cpp */