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 / tree / tree.cpp < prev    next >
C/C++ Source or Header  |  1996-10-15  |  25KB  |  832 lines

  1. // ====================================================================
  2. //
  3. //  File: tree.cpp
  4. //
  5. //  Copyright (c) 1994, 1995 Microsoft Corp.
  6. //
  7. //  Author:
  8. //      Jonathan Shuval     Microsoft Corp.
  9. //
  10. //
  11. //  This sample builds a tree of the container/folder hierarchy and
  12. //  displays it to the console.
  13. //
  14. //  The information that is displayed is as follows:
  15. //  For each container we display the container's type and tag followed
  16. //  by a list of filters (possibly empty). This lists filters that are
  17. //  acted upon directly at that level.
  18. //  Following the filter list is a folder list. This gives the folder's
  19. //  type and tag, its filter list, and then a list of scalars for the
  20. //  folder.
  21. //  The scalar display shows the scalar name, it's type, and its access
  22. //  mode.
  23. //
  24. //  See the readme.txt file in this directory for more information.
  25. //
  26. // ====================================================================
  27.  
  28.  
  29. // ====================================================================
  30. //
  31. //      Includes
  32. //
  33. // ====================================================================
  34. #include <afx.h>
  35. #include <smsapi.h>
  36.  
  37.  
  38. // ====================================================================
  39. //
  40. //      Defines.
  41. //
  42. // ====================================================================
  43. #define CCH_MAXSTRING 256
  44.  
  45.  
  46. // ====================================================================
  47. //
  48. //      Prototypes.
  49. //
  50. // ====================================================================
  51.  
  52. // Process a container.
  53. // -------------------------------------------------------------
  54. void doContainer( FOLDER_INFO *pContainer );
  55.  
  56.  
  57. // Process a folder.
  58. // -------------------------------------------------------------
  59. void doFolder( DWORD folderType, int indent, DWORD dwConType );
  60.  
  61.  
  62. // Adds a container to the container list.
  63. // -------------------------------------------------------------
  64. void AddContainer( DWORD dwConType );
  65.  
  66.  
  67. // Given a filter type display its properties.
  68. // -------------------------------------------------------------
  69. void doFilter( DWORD dwFilterType, int indent );
  70.  
  71.  
  72. // Locates filter of specified type from the global filter list.
  73. // -------------------------------------------------------------
  74. FILTER_INFO *FindFilter( DWORD filterType );
  75.  
  76.  
  77. // Mark folder as already enumerated within this container graph.
  78. // -------------------------------------------------------------
  79. void Enumerated( DWORD dwConType, DWORD folderType );
  80.  
  81.  
  82. // Call this to find out if this foldertype already been
  83. // enumerated within this container graph.
  84. // -------------------------------------------------------------
  85. BOOL IsEnumerated(DWORD dwConType, DWORD folderType);
  86.  
  87.  
  88. // Prompt the user for input and return the reply.
  89. // -------------------------------------------------------------
  90. void InputString( const char *pszMessage, char *pszResult );
  91.  
  92.  
  93. // Display the help message.
  94. // -------------------------------------------------------------
  95. void DisplayHelp();
  96.  
  97. // Display the greeting.
  98. // -------------------------------------------------------------
  99. void DisplayGreeting();
  100.  
  101.  
  102. // Check to see if there was a request for help
  103. // on the command line.
  104. // -------------------------------------------------------------
  105. BOOL DidRequestHelp( int argc, char **argv );
  106.  
  107.  
  108.  
  109.  
  110.  
  111. // ====================================================================
  112. //
  113. //      Globals.
  114. //
  115. // ====================================================================
  116. FOLDER_INFO **gpFolders = NULL;     // List of FOLDER_INFOs.
  117. DWORD gctFolders = 0;               // Count of them.
  118.  
  119.  
  120. FILTER_INFO *gpFilters = NULL;      // List of FILTER_INFOs.
  121. DWORD gctFilters = 0;               // Count of them.
  122.  
  123. //
  124. // This struct is used to hold information about what folders
  125. // have already been enumerated for a particular container.
  126. //
  127. typedef struct tagContainerEntry {
  128.     DWORD dwConType;                // Container's type.
  129.     CDWordArray aEnumFolders;       // Folders already enumerated.
  130. } ContainerEntry;
  131.  
  132.  
  133. CObArray ContainerList;             // List of containers (contains list
  134.                                     // of ContainerEntry structs.)
  135.  
  136.  
  137.  
  138.  
  139.  
  140. // ====================================================================
  141. //
  142. //      Start here.
  143. //
  144. // ====================================================================
  145. void main( int argc, char** argv )
  146. {
  147.     // Check to see if this is a request to display the help
  148.     // screen.  If so, display it. Otherwise, display a greeting
  149.     // banner.
  150.     //=========================================================
  151.     if (DidRequestHelp( argc, argv )) {
  152.         DisplayHelp();
  153.         return;
  154.     }
  155.     else {
  156.         DisplayGreeting();
  157.     }
  158.  
  159.  
  160.  
  161.     // Data.
  162.     // =====
  163.  
  164.     DWORD ctContainers;
  165.     FOLDER_INFO **pContainers = NULL;
  166.     FOLDER_INFO *pCont = NULL;
  167.  
  168.  
  169.  
  170.  
  171.     // Enumerate containers.
  172.     // =====================
  173.  
  174.         // Get number of containers.
  175.     SmsEnumContainers( NULL, &ctContainers );
  176.  
  177.         // Allocate memory and get the containers.
  178.     pContainers = new FOLDER_INFO *[ctContainers];
  179.     SmsEnumContainers( pContainers, &ctContainers );
  180.  
  181.  
  182.     // Enumerate all filters.
  183.     // ======================
  184.         // Get number of filters.
  185.     SmsEnumFilters(NULL, &gctFilters);
  186.  
  187.         // Allocate memory and get the filters.
  188.     gpFilters = new FILTER_INFO[gctFilters];
  189.     SmsEnumFilters( gpFilters, &gctFilters );
  190.  
  191.  
  192.     // Enumerate all folders.
  193.     // ======================
  194.         // Get number of folders.
  195.     SmsEnumFolders( NULL, &gctFolders );
  196.  
  197.         // Allocate memory and get the folders.
  198.     gpFolders = new FOLDER_INFO *[gctFolders];
  199.     SmsEnumFolders( gpFolders, &gctFolders );
  200.  
  201.  
  202.     // Loop through each container.
  203.     // ============================
  204.  
  205.     for (DWORD i = 0; i < ctContainers; i++) {
  206.  
  207.         // Process the container
  208.         doContainer( pContainers[i] );
  209.     }
  210.  
  211. }
  212.  
  213.  
  214.  
  215. // ====================================================================
  216. //
  217. //  doContainer -- process container.
  218. //
  219. //  This is called from main. We print out information for this
  220. //  container, and then process each folder within the container.
  221. //
  222. // ====================================================================
  223.  
  224. void doContainer( FOLDER_INFO *pContainer )
  225. {
  226.     DWORD dwI;
  227.  
  228.     // Add this container to our container list.
  229.     // =========================================
  230.     AddContainer( pContainer->dwTag );
  231.  
  232.     // We are now looking at the FOLDER_INFO for a container.
  233.     // We want to print out the count and list of filters,
  234.     // the folder type count, and then process each folder.
  235.     // ======================================================
  236.     printf("Container: %s [%d]\n", pContainer->pszTag, pContainer->dwTag);
  237.  
  238.     // Print out list of filters.
  239.     // =============================
  240.     printf("%d filter(s)\n", pContainer->ctFilters);
  241.     DWORD *pFilters = pContainer->pFilterTags;
  242.  
  243.     for (dwI = 0; dwI < pContainer->ctFilters; dwI++) {
  244.         doFilter( pFilters[dwI], 1 );
  245.     }
  246.  
  247.  
  248.     // Print out list of folders.
  249.     // ==========================
  250.     printf("%d folder-type(s)\n", pContainer->ctFolders);
  251.  
  252.     DWORD *pFolderIDs = pContainer->pFolderTags;
  253.     for (dwI = 0; dwI < pContainer->ctFolders; dwI++) {
  254.  
  255.         // Now cause the folder to print himself out.
  256.         // ------------------------------------------
  257.         doFolder( pFolderIDs[dwI], 1, pContainer->dwTag );
  258.     }
  259.  
  260.     // No scalars for container.
  261.     // =========================
  262.  
  263.     printf("\n\n");
  264. }
  265.  
  266.  
  267.  
  268. // ====================================================================
  269. //
  270. //  FindFilter -- locate filter of specified type from the list of
  271. //  filter descriptors returned by the API SmsEnumFilters.
  272. //
  273. //  Return a pointer to the FILTER_INFO for the filter.
  274. //
  275. //  Called from doFilter.
  276. //
  277. // ====================================================================
  278.  
  279. FILTER_INFO *FindFilter( DWORD filterType )
  280. {
  281.     FILTER_INFO *pFI;
  282.     for (DWORD dwI = 0; dwI < gctFilters; dwI++) {
  283.         pFI = &gpFilters[dwI];
  284.         if (pFI->filterType == filterType) {
  285.             return(pFI);
  286.         }
  287.     }
  288.  
  289.     return(NULL);
  290. }
  291.  
  292.  
  293. // ====================================================================
  294. //
  295. //  dumpScalar -- given a SCALAR_INFO, display the scalar.
  296. //
  297. //  We display the scalar's name, type, and access mode.
  298. //
  299. //  Params:
  300. //      SCALAR_INFO                 Scalar to display.
  301. //      indent                      indent level
  302. //
  303. //
  304. // ====================================================================
  305.  
  306. void dumpScalar( SCALAR_INFO *pSc, int indent )
  307. {
  308.     // Indentation.
  309.     // ============
  310.     char szIndent[100];
  311.     memset( szIndent, '\0', 100 );
  312.     for (int iLevel = 0; iLevel < indent; iLevel++) {
  313.         strcat( szIndent, "\t");
  314.     }
  315.  
  316.     char *pszType, *pszAccess;
  317.  
  318.     // Determine scalar type, display accordingly.
  319.     // ===========================================
  320.     switch (pSc->scType) {
  321.     case SCALAR_STRING:
  322.         pszType = "string";     break;
  323.  
  324.     case SCALAR_INT:
  325.         pszType = "integer";    break;
  326.  
  327.     case SCALAR_TIME:
  328.         pszType = "time";       break;
  329.  
  330.     case SCALAR_BINARY:
  331.         pszType = "binary";     break;
  332.     }
  333.  
  334.     // Determine access mode, display accordingly.
  335.     // ===========================================
  336.     switch (pSc->fAccess) {
  337.     case ACCESS_READ:
  338.         pszAccess = "read";     break;
  339.  
  340.     case ACCESS_CREATE:
  341.         pszAccess = "create";   break;
  342.  
  343.     case ACCESS_MODIFY:
  344.         pszAccess = "modify";   break;
  345.  
  346.     case ACCESS_DELETE:
  347.         pszAccess = "delete";   break;
  348.     }
  349.  
  350.  
  351.     printf("%s%s (%s, %s)\n", szIndent, pSc->szName, pszType, pszAccess);
  352.  
  353. }
  354.  
  355.  
  356.  
  357. // ====================================================================
  358. //
  359. //  doScalars -- display a folder's scalar.
  360. //
  361. //  Loop through the list of SCALAR structures that are embedded in the
  362. //  FOLDER_INFO, and display them.
  363. //
  364. //  The 'indent' parameter says how far to indent the resulting display
  365. //  string so it looks almost presentable.
  366. //
  367. //  Params:
  368. //      FOLDER_INFO *pFolder        The structure describing the folder
  369. //                                  under consideration.
  370. //      int indent                  Indent level.
  371. //
  372. //  Returns:
  373. //      Nothing.
  374. //
  375. // ====================================================================
  376.  
  377. void doScalars( FOLDER_INFO *pFolder, int indent )
  378. {
  379.     SCALAR_INFO *pScalar;
  380.  
  381.     for (DWORD dwI = 0; dwI < pFolder->ctScalars; dwI++) {
  382.         pScalar = &pFolder->pScalars[dwI];
  383.         dumpScalar( pScalar, indent );
  384.     }
  385. }
  386.  
  387.  
  388. // ====================================================================
  389. //
  390. //  doFolder -- Given a folder type print out this folder's information.
  391. //
  392. //  The folder has already been retrieved in SmsEnumFolders, we just
  393. //  access it from there.
  394. //
  395. //  Params:
  396. //      folderType                  Folder type we're interested in.
  397. //      dwConType                   Container's type.
  398. //
  399. //  Returns:
  400. //      Nothing.
  401. //
  402. // ====================================================================
  403.  
  404. void doFolder( DWORD folderType, int indent, DWORD dwConType )
  405. {
  406.  
  407.     FOLDER_INFO *pFolder;
  408.     DWORD dwI;
  409.     BOOL bFound = FALSE;
  410.  
  411.     // Indentation.
  412.     // ============
  413.     char szIndent[100];
  414.     memset( szIndent, '\0', 100 );
  415.     for (int iLevel = 0; iLevel < indent; iLevel++) {
  416.         strcat( szIndent, "\t");
  417.     }
  418.  
  419.  
  420.     // Loop through the retrieved folders looking for
  421.     // the one with a tag for folderType.
  422.     // ==============================================
  423.     for (dwI = 0; dwI < gctFolders; dwI++) {
  424.         pFolder = gpFolders[dwI];
  425.         if (pFolder->dwTag == folderType) {
  426.             bFound = TRUE;
  427.             break;
  428.         }
  429.     }
  430.  
  431.  
  432.     if (!bFound) {
  433.         printf("<<< Error: couldn't locate folder %d >>>\n", folderType);
  434.         return;
  435.     }
  436.  
  437.  
  438.     // Display folder type and tag and filter count.
  439.     // =============================================
  440.     printf("%s********** %s folder [%d] **********\n",
  441.         szIndent,    pFolder->pszTag, pFolder->dwTag);
  442.  
  443.     // Check to see if it's already been displayed.
  444.     // We only want to do this in the context of the current container.
  445.     // ----------------------------------------------------------------
  446.     if (IsEnumerated(dwConType, folderType)) {
  447.         printf("%sFolder already enumerated in this container\n", szIndent);
  448.         printf("%s********** End of %s folder **********\n\n",
  449.                     szIndent, pFolder->pszTag );
  450.         return;
  451.     }
  452.  
  453.     printf("%s%d filter(s)\n", szIndent, pFolder->ctFilters);
  454.  
  455.     // Print out list of filter types.
  456.     // ===============================
  457.     DWORD *pFilters = pFolder->pFilterTags;
  458.  
  459.     for (dwI = 0; dwI < pFolder->ctFilters; dwI++) {
  460.         doFilter( pFilters[dwI], indent );
  461.     }
  462.  
  463.     // Print out number of scalars, then display them.
  464.     // ===============================================
  465.     printf("%s%d scalars\n", szIndent, pFolder->ctScalars);
  466.     doScalars( pFolder, indent );
  467.  
  468.  
  469.     // Prepare to display sub-folders.
  470.     // ===============================
  471.     printf("%s%d folder-type(s)\n", szIndent, pFolder->ctFolders);
  472.  
  473.  
  474.     // Before processing sub-folder types mark this folder as already
  475.     // enumerated in this container. Prevents infinite recursion.
  476.     Enumerated(dwConType, folderType);
  477.  
  478.     // Print out list of folder types.
  479.     DWORD *pFolderIDs = pFolder->pFolderTags;
  480.     for (dwI = 0; dwI < pFolder->ctFolders; dwI++) {
  481.         // Now cause the folder to print himself out.
  482.         doFolder( pFolderIDs[dwI], indent+1, dwConType );
  483.  
  484.     }
  485.  
  486.     printf("%s********** End of %s folder **********\n\n",
  487.                 szIndent, pFolder->pszTag );
  488.  
  489. }
  490.  
  491.  
  492.  
  493. // ====================================================================
  494. //
  495. //  doFilter -- given a filter type display its properties.
  496. //
  497. //  Called from doContainer and doFolder.
  498. //
  499. // ====================================================================
  500.  
  501. void doFilter( DWORD dwFilterType, int indent )
  502. {
  503.  
  504.     FILTER_INFO *pFilter = FindFilter( dwFilterType );
  505.  
  506.     if (!pFilter) {
  507.         printf("<<< Error: couldn't locate filter %d >>>\n", dwFilterType);
  508.         return;
  509.     }
  510.  
  511.     // Indentation.
  512.     // ============
  513.     char szIndent[100];
  514.     memset( szIndent, '\0', 100 );
  515.     for (int iLevel = 0; iLevel < indent; iLevel++) {
  516.         strcat( szIndent, "\t");
  517.     }
  518.  
  519.     // Display filter type and tag.
  520.     // ============================
  521.     printf("%s%s (%d)\n", szIndent, pFilter->szTag, dwFilterType);
  522.  
  523.  
  524.     // Display filter properties.
  525.     // ==========================
  526.     char *ppszField[10];            // Store pointers here.
  527.     DWORD ctFields = 0;             // Number of pointers.
  528.  
  529.     char szBuff[256];               // Build up output string here.
  530.     sprintf(szBuff, "%s\t[", szIndent); // Additional level of indent.
  531.  
  532.     if (*(pFilter->szName)) {
  533.         ppszField[ctFields++] = "Token.szName = ";
  534.         ppszField[ctFields++] = pFilter->szName;
  535.     }
  536.  
  537.     if (*(pFilter->szValue)) {
  538.         ppszField[ctFields++] = "Token.szValue = ";
  539.         ppszField[ctFields++] = pFilter->szValue;
  540.     }
  541.  
  542.     if (*(pFilter->szOperator)) {
  543.         ppszField[ctFields++] = "Token.szOperator = ";
  544.         ppszField[ctFields++] = pFilter->szOperator;
  545.     }
  546.  
  547.     if (*(pFilter->szArchitecture)) {
  548.         ppszField[ctFields++] = "Token.szArchitecture = ";
  549.         ppszField[ctFields++] = pFilter->szArchitecture;
  550.     }
  551.  
  552.     if (*(pFilter->szGroupClass)) {
  553.         ppszField[ctFields++] = "Token.szGroupClass = ";
  554.         ppszField[ctFields++] = pFilter->szGroupClass;
  555.     }
  556.  
  557.     if (*(pFilter->szAttributeName)) {
  558.         ppszField[ctFields++] = "Token.szAttributeName = ";
  559.         ppszField[ctFields++] = pFilter->szAttributeName;
  560.     }
  561.  
  562.  
  563.     for (DWORD dwI = 0; dwI < ctFields; dwI += 2) {
  564.         printf("\t%s%s\"%s\"\n", szIndent, ppszField[dwI], ppszField[dwI+1]);
  565.     }
  566.  
  567.  
  568. }
  569.  
  570.  
  571.  
  572. // ====================================================================
  573. //
  574. //  AddContainer -- adds a container to the container list.
  575. //
  576. // This is only for detecting folders that have already been
  577. // enumerated. Nothing more.
  578. // Trouble is we duplicate!
  579. //
  580. // ====================================================================
  581.  
  582. void AddContainer( DWORD dwConType )
  583. {
  584.     ContainerEntry *pCEntry;
  585.     pCEntry = new ContainerEntry;
  586.     pCEntry->dwConType = dwConType;
  587.  
  588.     ContainerList.Add((CObject *)pCEntry );
  589. }
  590.  
  591.  
  592.  
  593. // ====================================================================
  594. //
  595. //  Enumerated -- Mark this folder as already enumerated within this
  596. //  container graph.
  597. //
  598. // ====================================================================
  599.  
  600. void Enumerated(DWORD dwConType, DWORD folderType)
  601. {
  602.     // Locate the container.
  603.     BOOL bFound = FALSE;
  604.     DWORD dwI;                  // loop index.
  605.     ContainerEntry *pCEntry;
  606.  
  607.     // We keep a global ContainerList (CObArray) which contains
  608.     // a list of container entries (above).
  609.  
  610.     // Locate container entry.
  611.     // =======================
  612.     for (dwI = 0; dwI < (DWORD)ContainerList.GetSize(); dwI++) {
  613.         pCEntry = (ContainerEntry *)ContainerList[dwI];
  614.         if (pCEntry->dwConType == dwConType) {
  615.             bFound = TRUE;
  616.             break;
  617.         }
  618.     }
  619.  
  620.     if (!bFound) {
  621.         printf("<<< Error: container tag %d not found in list >>>\n", dwConType);
  622.         return;
  623.     }
  624.  
  625.     // Add this folder to our list of enumerated folders.
  626.     // ==================================================
  627.     pCEntry->aEnumFolders.Add( folderType );
  628.  
  629. }
  630.  
  631.  
  632.  
  633. // ====================================================================
  634. //
  635. //  IsEnumerated -- Has this foldertype already been enumerated within
  636. //  this container graph?
  637. //
  638. // ====================================================================
  639.  
  640. BOOL IsEnumerated(DWORD dwConType, DWORD folderType)
  641. {
  642.     BOOL bFound = FALSE;
  643.     DWORD dwI;                  // loop index.
  644.     ContainerEntry *pCEntry;
  645.  
  646.     // We keep a global ContainerList (CObArray) which contains
  647.     // a list of container entries (above).
  648.  
  649.     // Locate container entry.
  650.     // =======================
  651.     for (dwI = 0; dwI < (DWORD)ContainerList.GetSize(); dwI++) {
  652.         pCEntry = (ContainerEntry *)ContainerList[dwI];
  653.         if (pCEntry->dwConType == dwConType) {
  654.             bFound = TRUE;
  655.             break;
  656.         }
  657.     }
  658.  
  659.     if (!bFound) {
  660.         printf("<<< Error: container tag %d not found in list >>>\n", dwConType);
  661.         return(FALSE);
  662.     }
  663.  
  664.     // Now look through the array of enumerated folders.
  665.     // =================================================
  666.     for (dwI = 0; dwI < (DWORD)pCEntry->aEnumFolders.GetSize(); dwI++) {
  667.         if (pCEntry->aEnumFolders[dwI] == folderType) {
  668.  
  669.             // Found it. Folder already enumerated.
  670.             // ------------------------------------
  671.             return(TRUE);
  672.         }
  673.     }
  674.  
  675.     // Folder hasn't been enumerated.
  676.     // ------------------------------
  677.     return(FALSE);
  678. }
  679.  
  680.  
  681.  
  682.  
  683.  
  684. // ====================================================================
  685. // InputString
  686. //
  687. // Prompt the user to input a string and return the string in the
  688. // specified buffer.
  689. //
  690. // Parameters:
  691. //      const char* pszMessage
  692. //          The user prompt to display.
  693. //
  694. //      char* pszResult
  695. //          Pointer to the buffer where the user's input will be returned.
  696. //
  697. // Returns;
  698. //      The user's input is returned via the given buffer.
  699. //
  700. // ====================================================================
  701. void InputString( const char *pszMessage, char *pszResult)
  702. {
  703.     printf("%s: ", pszMessage);
  704.     gets(pszResult);
  705. }
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714. // ====================================================================
  715. // DidRequestHelp
  716. //
  717. // Check the program's arguments to see if the user asked for
  718. // the help screen to be displayed.
  719. //
  720. // Parameters:
  721. //      int argc
  722. //          The argc value from main(argc, argv)
  723. //
  724. //      char** argv
  725. //          The argv value from main(argc, argv)
  726. //
  727. // Returns:
  728. //      TRUE if command line parameters included a request
  729. //      for help to be displayed.
  730. //
  731. // ====================================================================
  732. BOOL DidRequestHelp(int argc, char** argv)
  733. {
  734.     if (argc == 2  && (strcmp(argv[1], "-help") == 0)) {
  735.         return(TRUE);
  736.     }
  737.     else {
  738.         return(FALSE);
  739.     }
  740. }
  741.  
  742.  
  743. // ====================================================================
  744. // DisplayHelp
  745. //
  746. // This function displays the samples help screen.
  747. //
  748. // Parameters:
  749. //      None
  750. //
  751. // Returns:
  752. //      Nothing.
  753. //
  754. // ====================================================================
  755. void DisplayHelp()
  756. {
  757.     // Version information.
  758.     // ====================
  759.     char *pVer;
  760.     SmsAPIVer( &pVer );
  761.     printf("\n%s\n\n", pVer);
  762.  
  763.  
  764.     // Description.
  765.     // ============
  766.  
  767.     printf("********************************************************************\n");
  768.     printf("* tree.exe:                                                        *\n");
  769.     printf("*                                                                  *\n");
  770.     printf("* This is a sample program for the SMS SDK.  It shows how the      *\n");
  771.     printf("* container hierarchy can be displayed.                            *\n");
  772.     printf("*                                                                  *\n");
  773.     printf("* For each container in SMS, the following details are displayed:  *\n");
  774.     printf("*     the container's tag and type                                 *\n");
  775.     printf("*     any filters that are acted upon directly by the container    *\n");
  776.     printf("*                                                                  *\n");
  777.     printf("* Following this is a display of all folders within that container.*\n");
  778.     printf("*                                                                  *\n");
  779.     printf("* For folders the following is displayed:                          *\n");
  780.     printf("*     the folder's type and tag                                    *\n");
  781.     printf("*     any filters that are acted upon by the folder                *\n");
  782.     printf("*     a list of the folder's scalars                               *\n");
  783.     printf("* Note that folder enumeration is recursive, that is, some folders *\n");
  784.     printf("* contain sub-folders.                                             *\n");
  785.     printf("*                                                                  *\n");
  786.     printf("* For filters a list of the filter's attributes are displayed.     *\n");
  787.     printf("*                                                                  *\n");
  788.     printf("* Syntax:                                                          *\n");
  789.     printf("*     tree.exe [-help]                                             *\n");
  790.     printf("*                                                                  *\n");
  791.     printf("* Switches:                                                        *\n");
  792.     printf("*     -help       Display this help screen.                        *\n");
  793.     printf("*                                                                  *\n");
  794.     printf("********************************************************************\n");
  795.     printf("\n");
  796. }
  797.  
  798.  
  799.  
  800. // ====================================================================
  801. // DisplayGreeting
  802. //
  803. // Display the initial greeting banner.
  804. //
  805. // Parameters:
  806. //     None.
  807. //
  808. // Returns:
  809. //     Nothing.
  810. //
  811. // ====================================================================
  812. void DisplayGreeting()
  813. {
  814.     // For this sample, the greeting is identical to the help screen.
  815.     //===============================================================
  816.     DisplayHelp();
  817.  
  818.     // Pause so the description doesn't fly off the screen.
  819.     // ====================================================
  820.     char szReply[CCH_MAXSTRING];
  821.     InputString("Press ENTER to continue", szReply);
  822.     printf("\n");
  823. }
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830. /* EOF: tree.cpp */
  831.  
  832.