home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pc3270sa.zip / listfile / listdde.c < prev    next >
Text File  |  2002-02-28  |  37KB  |  791 lines

  1. //******************************************************************************
  2. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  3. //
  4. //  PROGRAM: listdde.c
  5. //
  6. //  PURPOSE: DDE interface functions for ListFile DDE application
  7. //
  8. //  FUNCTIONS:
  9. //
  10. //  ListDDEInitiate       - Handle INITIATE for primary DDE conversation
  11. //  ListDDEAck            - Handle ACK for primary DDE conversation
  12. //  ListDDEPoke           - Handle POKE for primary DDE conversation
  13. //  ListDDERequest        - Handle REQUEST for primary DDE conversation
  14. //  ListDDETerminate      - Handle TERMINATE for primary DDE conversation
  15. //
  16. //  StartFileConversation - Initiate secondary DDE conversation
  17. //
  18. //  FileDDEAck            - Handle ACK for secondary DDE conversation
  19. //  FileDDEData           - Handle DATA for secondary DDE conversation
  20. //  FileDDETerminate      - Handle TERMINATE for secondary DDE conversation
  21. //
  22. //  lstrncpy              - String copy with long pointers
  23. //  ParsePS               - Parse session presentation space ( PS )
  24. //
  25. //  Copyright (c) 1990, 1996 IBM Corporation. All rights reserved.
  26. //
  27. //******************************************************************************
  28.  
  29. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  30. //
  31. //  In the LISTFILE application two DDE conversations take place. The
  32. //  primary conversation is initiated by the PC/3270 receive dialog function
  33. //  acting as a DDE clint. The LISTFILE application completes the conversation
  34. //  link by acknowledging the he initiate. from the PC/3270 receive dialog.
  35. //  After LISTFILE has received the file mask to use with the CMS LISTFILE
  36. //  via a DDE_POKE message, from the client, and received a request for the
  37. //  the list of files from the client via a DDE_REQUEST message it opens
  38. //  a hidden window to conduct the secondary conversation. The hidden
  39. //  window, acting as a client, sends a DDE_INITIATE message to the PC/3270
  40. //  session to start the secondary conversation. Once the secondary
  41. //  conversation is acknowledged by the PC/3270 session the secondary
  42. //  conversation will send the session the CMS LISTFILE command, and begin
  43. //  reading the presentation space to retrieve the cms file names returned
  44. //  by the CMS listfile command.
  45. //
  46. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT */
  47.  
  48. #include <windows.h>                // required for all Windows applications
  49. #include <string.h>                 // C string functions
  50. #include <stdio.h>                  // C functions
  51. #include <stdlib.h>                 // C functions
  52.  
  53. #include "dde_c.h"                  // required for PCOM DDE Appls
  54. #include "listfile.h"               // specific to this program
  55. #include "listdata.h"               // Global Data
  56.  
  57. //******************************************************************************
  58. //
  59. // Local Function Prototypes
  60. //
  61. //******************************************************************************
  62.  
  63. BOOL  StartFileConversation (void);             //Starts 2nd conversation
  64. LPSTR lstrncpy              (LPSTR,LPSTR,WORD); //copy n chars
  65. WORD  ParsePS               (LPSTR,WORD,WORD);  //parse presentation space
  66.  
  67. //******************************************************************************
  68. //
  69. // Local Data
  70. //
  71. //******************************************************************************
  72.  
  73. uchar  z3270List[17];
  74. uchar  zGetList[17];
  75. uchar  zFileMask[17];
  76. uchar  zListFile[17];
  77. uchar  zIBM3270[11];
  78. uchar  zSESSION[9];
  79. uchar  zKEYS[6];
  80. uchar  zPS[4];
  81.  
  82. //******************************************************************************
  83. //
  84. //  FUNCTION: InitDDE()
  85. //
  86. //  PURPOSE:
  87. //
  88. //  Initialize various DDE atoms, and any other required DDE initializations.
  89. //
  90. //******************************************************************************
  91.  
  92. BOOL InitDDE( void )
  93. {
  94.   LoadString(hGlobalInst, LS_16STR_FORMAT, zFmtBuffer, sizeof(zFmtBuffer));
  95.   LoadString(hGlobalInst, LS_DDE_TOKENS,   zMsgBuffer, sizeof(zMsgBuffer));
  96.  
  97.   sscanf(zMsgBuffer,                           // Input String
  98.          zFmtBuffer,                           // sscanf format to use
  99.          z3270List,                            // Server Name
  100.          zListFile,                            // Server Topic
  101.          zFileMask,                            // Poke Data Item  file mask
  102.          zGetList,                             // Request Item for list of files
  103.          zIBM3270,                             // Session Server Name
  104.          zSESSION,                             // Session Topic
  105.          zKEYS,                                // Session Data Items
  106.          zPS);                                 // "
  107.                                                //
  108.   lstrcat(z3270List, zCmdLineSessionID );      // Append Session ID
  109.   lstrcat(zSESSION, zCmdLineSessionID );       // Append Session ID
  110.  
  111.   return(TRUE);
  112. }
  113.  
  114. //******************************************************************************
  115. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  116. //
  117. //  FUNCTION: ListDDEInitiate(HWND , unsigned , WORD , LONG )
  118. //
  119. //  PURPOSE:
  120. //
  121. //  Accepts the DDE_INITIATE message from the PC/3270 receive dialog, and
  122. //  acknowledges the conversation if it can be supported.
  123. //
  124. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  125. //******************************************************************************
  126.  
  127. void ListDDEInitiate(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  128. {
  129.   ATOM aApplication  = LOWORD( lParam );
  130.   ATOM aTopic        = HIWORD( lParam );
  131.  
  132.   ATOM a3270List     = GlobalAddAtom( z3270List );  // Temp Test Atoms
  133.   ATOM aListFile     = GlobalAddAtom( zListFile );  //
  134.  
  135.   if( aApplication == a3270List )
  136.   {
  137.     if( aTopic == aListFile || aTopic == 0 )
  138.     {
  139.       hRcvDlgClient = (HWND)wParam;               // Save away handle
  140.       bFirstScreen  = TRUE;                       // Init first screen flag
  141.       a3270List     = GlobalAddAtom( z3270List ); // Add Atoms
  142.       aListFile     = GlobalAddAtom( zListFile ); //
  143.       if(!SendMessage(hRcvDlgClient, WM_DDE_ACK, (WPARAM)hWnd, MAKELONG(aApplication, aTopic)))
  144.       {
  145.         GlobalDeleteAtom( aApplication ); // Error, delete client's ATOMS
  146.         GlobalDeleteAtom( aTopic       ); // Error, delete client's ATOMS
  147.       }
  148.     }
  149.   }
  150.  
  151.   GlobalDeleteAtom( a3270List );        // Delete Test Atoms
  152.   GlobalDeleteAtom( aListFile );
  153. }
  154.  
  155. //******************************************************************************
  156. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  157. //
  158. //  FUNCTION: ListDDEPoke(HWND , unsigned , WORD , LONG)
  159. //
  160. //  PURPOSE:
  161. //
  162. //  Processes and acknowledges a DDE_POKE message containing a host file name
  163. //  mask to be used with the CMS LISTFILE commaned sent to the VM session.
  164. //
  165. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  166. //******************************************************************************
  167.  
  168. void FAR ListDDEPoke(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  169. {
  170.   HWND      hWndClient = (HWND)wParam;               //
  171.   HANDLE    hFileMask;                               //
  172.   ATOM      aItem, aFileMask;                        //
  173.   WORD      uAck       = DDE_NACK;                   // Initial ACK Value
  174.   BOOL      bTerminate = FALSE;                      // Terminate Flag
  175.   LPDDE_GETLIST lpGetList;                           //
  176.   UINT          uiLo, uiHi;                          //
  177.                                                      //
  178.   aFileMask  = GlobalAddAtom( zFileMask );           // Test Atom
  179.   UnpackDDElParam(WM_DDE_POKE, lParam, (PUINT)&uiLo, (PUINT)&uiHi);
  180.   hFileMask = (HANDLE)uiLo;
  181.   aItem     = (ATOM)uiHi;
  182.  
  183.   if( aItem == aFileMask && hFileMask != NULL)       //
  184.   {                                                  //
  185.     if( (lpGetList = (LPDDE_GETLIST) GlobalLock(hFileMask)) != NULL )                           //
  186.     {                                                //
  187.       uAck = DDE_ACK;                                // ACK
  188.       lstrcpy(zHostFileMask, lpGetList->DDEgetlist.Data); // Save mask for REQUEST
  189.       if(lpGetList->DDEpoke.fRelease)                // Release the memory
  190.       {                                              //
  191.         GlobalUnlock(hFileMask);                     //
  192.         GlobalFree(hFileMask);                       //
  193.       }                                              //
  194.       else                                           //
  195.       {                                              //
  196.         GlobalUnlock(hFileMask);                     //
  197.       }                                              //
  198.     }                                                //
  199.     else                                             //
  200.     {                                                //
  201.       bTerminate = TRUE;                             // Error, terminate conv
  202.     }                                                //
  203.   }                                                  //
  204.   else                                               //
  205.   {                                                  //
  206.     bTerminate = TRUE;                               // Error, terminate conv
  207.   }                                                  //
  208.                                                      //
  209.   if( !PostMessage(hWndClient, WM_DDE_ACK, (WPARAM)hWnd, PackDDElParam(WM_DDE_ACK, uAck, aItem)) )
  210.   {                                                  //
  211.     GlobalDeleteAtom( aItem );                       //
  212.     bTerminate = TRUE;                               //
  213.   }                                                  //
  214.                                                      //
  215.   if( bTerminate )                                   // Terminate Conversation?
  216.   {                                                  // Yes
  217.     Terminate( CONVERSATIONS );                      //
  218.   }                                                  //
  219.                                                      //
  220.   GlobalDeleteAtom( aFileMask );                     //
  221.   FreeDDElParam(WM_DDE_POKE, lParam);
  222. }
  223.  
  224. //******************************************************************************
  225. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  226. //
  227. //  FUNCTION: ListDDERequest(HWND , unsigned , WORD , LONG )
  228. //
  229. //  PURPOSE:
  230. //
  231. //  Processes and acknowledges a DDE_REQUEST message containing the request
  232. //  for the file list.
  233. //
  234. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  235. //******************************************************************************
  236.  
  237. void FAR ListDDERequest(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  238. {
  239.   WORD   wFormat    = LOWORD(lParam);               //
  240.   WORD   wStatus    = DDE_NACK;                     //
  241.   ATOM   aItem      = HIWORD(lParam);               //
  242.   BOOL   bTerminate = FALSE;                        // Terminate Flag
  243.                                                     //
  244.   ATOM   aGetList  = GlobalAddAtom( zGetList );     // Test Atom
  245.                                                     //
  246.   if( wFormat == CF_DSPTEXT && aItem == aGetList )  //
  247.   {                                                 //
  248.     if( !StartFileConversation() )                  // Start 2nd conversation
  249.     {                                               // Error
  250.       bTerminate = TRUE;                            // Terminate
  251.     }                                               //
  252.   }                                                 //
  253.   else                                              // Request Error!
  254.   {                                                 // NACK it and
  255.     bTerminate = TRUE;                              // Terminate
  256.   }                                                 //
  257.                                                     //
  258.   if( bTerminate )                                  // Terminate Conversation?
  259.   {                                                 // Yes
  260.     Terminate( CONVERSATIONS );                     //
  261.   }                                                 //
  262.                                                     //
  263.   GlobalDeleteAtom( aGetList );                     // Delete Test Atom
  264. }
  265.  
  266. //******************************************************************************
  267. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  268. //
  269. //  FUNCTION: ListDDETerminate(HWND , unsigned , WORD , LONG )
  270. //
  271. //  PURPOSE:
  272. //
  273. //  Processes a DDE_TERMINATE message from the client and send the client
  274. //  a DDE_TERMINATE message to complete the DDE termination process.
  275. //
  276. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  277. //******************************************************************************
  278.  
  279. void FAR ListDDETerminate(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  280. {
  281.   Terminate( CONVERSATIONS );            // Terminate DDE Conversations
  282. }
  283.  
  284. //##############################################################################
  285.  
  286. //******************************************************************************
  287. //
  288. //  FUNCTION:  StartFileConversation(void)
  289. //
  290. //  PURPOSE:
  291. //
  292. //  This function is called from ListDDERequeest where ListFile receives the
  293. //  request for the file list. The secondary DDE convseration is initiated
  294. //  in this function.
  295. //
  296. //******************************************************************************
  297.  
  298. BOOL StartFileConversation( void )             //
  299. {                                              //
  300.   BOOL         bRC = FALSE;                    // Error until proven otherwise
  301.   ATOM         aIBM3270,aSESSION,aKEYS;        //
  302.   LPXCOMMANDS  lpData;                         //
  303.                                                //
  304.   uCurFileDDEMsg = 0;                          // current file dde message
  305.                                                //
  306.   aIBM3270 = GlobalAddAtom( zIBM3270 );        // Create Temp atoms for
  307.   aSESSION = GlobalAddAtom( zSESSION );        // DDE traffic
  308.   aKEYS    = GlobalAddAtom( zKEYS    );        // DDE traffic
  309.                                                //
  310.   uCurFileDDEMsg = WM_DDE_INITIATE;            //
  311.                                                //
  312.   aIBM3270 = GlobalAddAtom( zIBM3270 );        // Create atoms for
  313.   aSESSION = GlobalAddAtom( zSESSION );        // DDE traffic
  314.                                                //
  315.   if( !SendMessage( (HWND)-1, uCurFileDDEMsg, (WPARAM)hWndHidden, MAKELONG(aIBM3270, aSESSION)) )
  316.   {                                            //
  317.     GlobalDeleteAtom( aIBM3270  );             // Error, delete atoms
  318.     GlobalDeleteAtom( aSESSION  );             //
  319.   }                                            //
  320.                                                //
  321.   if( hSessionServer == NULL )                 // did we get a DDE link up
  322.   {                                            // No, better handle error
  323.      bRC = FALSE;                              //
  324.   }                                            //
  325.   else                                         // yes,poke the LISTFILE
  326.   {
  327.      if( (hData = GlobalAlloc(DDE_GLOBAL,(DWORD) sizeof(XCOMMANDS))) != NULL )
  328.      {
  329.        if( (lpData = (LPXCOMMANDS) GlobalLock(hData)) != NULL ) //
  330.        {
  331.           LoadString(hGlobalInst, LS_LISTFILE_COMMAND, zFmtBuffer, sizeof(zFmtBuffer));
  332.  
  333.           wsprintf( lpData->zXCommands,      // Target Buffer
  334.                     (LPSTR) zFmtBuffer,      // Format "LISTFILE %s ..."
  335.                     '\"',                    // DQUOTE
  336.                     (LPSTR) zHostFileMask,   // File Mask
  337.                     '\"' );                  // DQUOTE
  338.                                              //
  339.           GlobalUnlock(hData);               // Unlock the buffer
  340.                                              //
  341.           uCurFileDDEMsg = WM_DDE_EXECUTE;   //
  342.                                              //
  343.           if( !PostMessage(hSessionServer, uCurFileDDEMsg, (WPARAM)hWndHidden, (LPARAM)hData) )
  344.           {                                  //
  345.             GlobalFree( hData );             // Error, Free the data
  346.           }                                  //
  347.           else                               //
  348.           {                                  //
  349.              bRC = TRUE;                     // Initial Success!
  350.           }                                  //
  351.        }                                     //
  352.        else                                  // Lock failed
  353.        {                                     //
  354.           GlobalFree( hData );               //
  355.        }                                     //
  356.      }                                       //
  357.      else                                    // Alloc Failed
  358.      {                                       //
  359.      }                                       //
  360.   }                                          //
  361.                                              //
  362.   GlobalDeleteAtom( aIBM3270 );              // Delete Temporary Atoms
  363.   GlobalDeleteAtom( aSESSION );              //
  364.   GlobalDeleteAtom( aKEYS    );              //
  365.                                              //
  366.   return( bRC );                             // Return the RC
  367. }
  368.  
  369. //******************************************************************************
  370. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  371. //
  372. //  FUNCTION: FileDDEAck(HWND , unsigned , WORD , LONG )
  373. //
  374. //  PURPOSE:
  375. //
  376. //  Process DDE_ACK messages from the PC/3270 session, and if needed,
  377. //  request the presentation space from the session by sending a DDE_REQUEST
  378. //  message.
  379. //
  380. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  381. //******************************************************************************
  382.  
  383. void FAR FileDDEAck(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  384. {
  385.   ATOM   aPS;
  386.   HGLOBAL hCommands;
  387.   WORD    wStatus;
  388.   UINT    uiLo, uiHi;
  389.  
  390.   if (uCurFileDDEMsg == WM_DDE_INITIATE)
  391.   {                                              // Are we trying to Init DDE?
  392.      hSessionServer = (HWND)wParam;              // yes, save handle.
  393.      GlobalDeleteAtom(LOWORD(lParam));           // Delete INITIATE atoms
  394.      GlobalDeleteAtom(HIWORD(lParam));           //
  395.      uNumberOfFiles = 0;                         //
  396.   }                                              //
  397.   else if(uCurFileDDEMsg == WM_DDE_EXECUTE)      // from listfile cmd or clear
  398.   {                                              //
  399.      UnpackDDElParam(WM_DDE_ACK, lParam, (PUINT)&uiLo, (PUINT)&uiHi);
  400.      wStatus   = (WORD)uiLo;
  401.      hCommands = (HGLOBAL)uiHi;
  402.      FreeDDElParam(WM_DDE_ACK, lParam);
  403.  
  404.      if( (wStatus        & DDE_ACK) != DDE_ACK ) // NACK ?
  405.      {                                           //
  406.        GlobalFree(hCommands);                    // free hCommands
  407.        Terminate( CONVERSATIONS );               // Terminate conversation
  408.      }                                           //
  409.      else                                        // ACK
  410.      {                                           //
  411.        aPS = GlobalAddAtom((LPSTR) zPS);         // Add PS atom
  412.        uCurFileDDEMsg = WM_DDE_REQUEST;          // Request PS
  413.        if( !PostMessage(hSessionServer, uCurFileDDEMsg, (WPARAM)hWnd, MAKELONG(CF_TEXT, aPS)) )
  414.        {                                         //
  415.          GlobalDeleteAtom( aPS );                // Error, Delete Atom
  416.          Terminate( CONVERSATIONS );             // Terminate conversation
  417.        }                                         //
  418.      }                                           //
  419.   }                                              //
  420.   else if(uCurFileDDEMsg == WM_DDE_REQUEST)      //
  421.   {                                              // if we get this it is a NACK
  422.     Terminate( CONVERSATIONS );                  // Terminate conversation
  423.   }                                              //
  424. }                                                //
  425.  
  426. //******************************************************************************
  427. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  428. //
  429. //  FUNCTION: FileDDEData(HWND , unsigned , WORD , LONG )
  430. //
  431. //  PURPOSE:
  432. //
  433. //  This function processes DDE_DATA messages from the session and parses
  434. //  the file names from the presentation space buffer returned with the
  435. //  message.
  436. //
  437. //
  438. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  439. //******************************************************************************
  440.  
  441. void FAR FileDDEData(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  442. {
  443.   HANDLE        hPS;                             // Handle to PS
  444.   ATOM          aItem;                           // Atom for PS
  445.  
  446.   ATOM          aPS, aGetList;
  447.   unsigned char zRows[5], zCols[5];
  448.   WORD          uRows, uCols, uBytesInFileList;
  449.   lpDDE_PS_CF_TEXT  lpPS;
  450.   LPXCOMMANDS       lpData;
  451.   LPDDE_LISTFILES   lpList;
  452.   UINT              uiLo, uiHi;
  453.  
  454.   UnpackDDElParam(WM_DDE_DATA, lParam, (PUINT)&uiLo, (PUINT)&uiHi);
  455.   hPS       = (HANDLE)uiLo;
  456.   aItem     = (ATOM)uiHi;
  457.  
  458.   if( hPS != NULL )
  459.   {
  460.     if((lpPS = (lpDDE_PS_CF_TEXT) GlobalLock(hPS)) != NULL)
  461.     {
  462.       lstrncpy(zRows,lpPS->DDEps.PSROWS,4);
  463.       lstrncpy(zCols,lpPS->DDEps.PSCOLS,4);
  464.       zRows[4] = '\0';
  465.       zCols[4] = '\0';
  466.       uRows = atoi(zRows);
  467.       uCols = atoi(zCols);
  468.       switch( ParsePS(lpPS->DDEps.PS, uRows, uCols) )
  469.       {
  470.         case PSDATA_MORE:
  471.           if( (hData = GlobalAlloc(DDE_GLOBAL, (DWORD)sizeof(XCOMMANDS))) != NULL )
  472.           {
  473.             if( (lpData = (LPXCOMMANDS) GlobalLock(hData)) != NULL )
  474.             {
  475.               LoadString(hGlobalInst,                   // Instance
  476.                          LS_CLEARSCREEN_COMMAND,        // String ID
  477.                          lpData->zXCommands,            // Target Buffer
  478.                          sizeof(lpData->zXCommands));   // Size of target
  479.                                                         //
  480.               GlobalUnlock(hData);                      // Unlock the buffer
  481.                                                         //
  482.               uCurFileDDEMsg = WM_DDE_EXECUTE;          //
  483.                                                         //
  484.               if( !PostMessage(hSessionServer, uCurFileDDEMsg, (WPARAM)hWnd, (LPARAM)hData) )
  485.               {                                         //
  486.                 GlobalFree( hData );                    // Error, Free the data
  487.               }                                         //
  488.             }                                           //
  489.             else                                        // Lock failure
  490.             {                                           //
  491.               GlobalFree(hData);                        //
  492.             }                                           //
  493.           }                                             //
  494.           else                                          // Alloc failure
  495.           {                                             //
  496.           }                                             //
  497.           break;                                        //
  498.  
  499.         case PSDATA_REREAD:                      // Do not clear, reread PS
  500.           aPS = GlobalAddAtom((LPSTR) zPS);      // Add PS atom
  501.           uCurFileDDEMsg = WM_DDE_REQUEST;       // Request ps
  502.           if( !PostMessage(hSessionServer, uCurFileDDEMsg, (WPARAM)hWnd, MAKELONG(CF_TEXT, aPS)) )
  503.           {                                      // Error,
  504.             GlobalDeleteAtom( aPS );             // Delete PS atom
  505.           }                                      //
  506.           break;                                 //
  507.                                                  //
  508.         case PSDATA_END:                         // Post DATA to Receive
  509.           uBytesInFileList = uNumberOfFiles * SIZEOFFILENAME;
  510.           if( (hData = GlobalAlloc(DDE_GLOBAL, (DWORD)sizeof(DDE_LISTFILES)+uBytesInFileList+2)) != NULL )
  511.           {
  512.             if( (lpList = (LPDDE_LISTFILES) GlobalLock(hData)) != NULL )
  513.             {
  514.                lpList->DDEdata.fRelease       = TRUE;
  515.                lpList->DDEdata.cfFormat       = CF_DSPTEXT;
  516.                lpList->DDElistfiles.iItemsInList   = uNumberOfFiles;
  517.                lpList->DDElistfiles.uFilenameWidth = SIZEOFFILENAME;
  518.  
  519.                memcpy(lpList->DDElistfiles.Data, zListFileNames, uBytesInFileList);
  520.  
  521.                lpList->DDElistfiles.Data[uBytesInFileList]   = NULL_CHAR;
  522.                lpList->DDElistfiles.Data[uBytesInFileList+1] = NULL_CHAR;
  523.  
  524.                GlobalUnlock(hData);
  525.  
  526.                aGetList = GlobalAddAtom((LPSTR) zGetList); //DDE atom
  527.  
  528.                if( !PostMessage(hRcvDlgClient, WM_DDE_DATA, (WPARAM)hGlobalWnd,
  529.                                 PackDDElParam(WM_DDE_DATA, (UINT)hData, aGetList)));
  530.                {
  531.                  GlobalDeleteAtom( aGetList ); // Error, delete atom
  532.                }
  533.  
  534.                // ** Do the terminate server logic
  535.  
  536.                PostMessage(hSessionServer, WM_DDE_TERMINATE, (WPARAM)hWnd, 0L);
  537.                hSessionServer = NULL;                       // reset handle
  538.             }                                           //
  539.             else                                        // BAD LOCK
  540.             {                                           //
  541.                GlobalFree(hData);                       //
  542.                Terminate( CONVERSATIONS );              // Terminate Conver
  543.             }                                           //
  544.           }                                             //
  545.           else                                          // BAD ALLOC
  546.           {                                             //
  547.             Terminate( CONVERSATIONS );                 // Terminate Conver
  548.           }                                             //
  549.           break;                                        //
  550.                                                         //
  551.         default:                                        // PSDATA_ERROR
  552.           //error case                                  //
  553.           //do the terminate logic                      //
  554.           break;                                        //
  555.       }                                                 //
  556.                                                         //
  557.       if(lpPS->DDEdata.fAckReq)                         // ACK required?
  558.       {                                                 //
  559.         if( !PostMessage(hSessionServer, WM_DDE_ACK, (WPARAM)hWnd, PackDDElParam(WM_DDE_ACK, DDE_ACK, aItem)))
  560.         {                                               //
  561.           GlobalDeleteAtom(aItem);                      //
  562.         }                                               //
  563.       }                                                 //
  564.                                                         //
  565.       if(lpPS->DDEdata.fRelease)                        // Release required?
  566.       {                                                 //
  567.         GlobalUnlock(hPS);                              //
  568.         GlobalFree(hPS);                                //
  569.       }                                                 //
  570.       else                                              //
  571.       {                                                 //
  572.         GlobalUnlock(hPS);                              //
  573.       }                                                 //
  574.     }                                                   //
  575.     else                                                // BAD LOCK
  576.     {                                                   //
  577.       GlobalFree(hPS);                                  // Free the handle
  578.       Terminate( CONVERSATIONS );                       // Terminate Conver
  579.     }                                                   //
  580.   }                                                     //
  581.   else                                                  // Bad Handle
  582.   {                                                     //
  583.   }
  584.   FreeDDElParam(WM_DDE_DATA, lParam);
  585. }
  586.  
  587. //******************************************************************************
  588. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  589. //
  590. //  FUNCTION: FileDDETerminate(HWND , unsigned , WORD , LONG )
  591. //
  592. //  PURPOSE:
  593. //
  594. //  Processes a DDE_TERMINATE message from the session and sends the session
  595. //  a DDE_TERMINATE message to complete the DDE termination process.
  596. //
  597. //**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT**BOX-COMMENT
  598. //******************************************************************************
  599.  
  600. void FAR FileDDETerminate(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  601. {
  602.   Terminate( CONVERSATION_SESSION );              // Terminate Conversations
  603. }
  604.  
  605. //******************************************************************************
  606. //
  607. //  FUNCTION: lstrncpy( LPSTR , LPSTR , WORD )
  608. //
  609. //  PURPOSE:
  610. //
  611. //  Long pointer strncpy function.
  612. //
  613. //
  614. //******************************************************************************
  615.  
  616. LPSTR lstrncpy( LPSTR lpzString1, LPSTR lpzString2, WORD uLength )
  617. {
  618.   int i;
  619.   LPSTR p = lpzString1;
  620.   uchar ch;
  621.  
  622.   for( i = 0; i < uLength; i++)
  623.   {
  624.     ch = *(lpzString2++);
  625.     *(lpzString1++) = ch;
  626.     if( ch == NULL_CHAR )
  627.     {
  628.       return( p );                  /* String was less than uLength in Length */
  629.     }
  630.   }
  631.  
  632.   *(lpzString1) = NULL_CHAR;        /* copied up to uLength, add Null on End */
  633.  
  634.   return( p );
  635. }
  636.  
  637. //******************************************************************************
  638. //
  639. //  FUNCTION: ParsePS(LPSTR , WORD , WORD )
  640. //
  641. //  PURPOSE:
  642. //
  643. //  COMMENTS:
  644. //
  645. //  Each line of a CF_TEXT PS ends in 0x0D 0x0A so the lines are
  646. //  actually uCols+2 characters long.
  647. //
  648. //  RETURNS:
  649. //
  650. //    PSDATA_ERROR  0
  651. //    PSDATA_END    1
  652. //    PSDATA_MORE   2
  653. //    PSDATA_REREAD 3
  654. //
  655. //******************************************************************************
  656.  
  657. WORD ParsePS(LPSTR lpPS, WORD uRows, WORD uCols)
  658. {                                                      //
  659.   WORD uRetCode = PSDATA_MORE;                         //
  660.   WORD uOffset  = 0;                                   //
  661.   WORD uLine    = 0;                                   //
  662.   WORD uLineStart;                                     //
  663.   BOOL bReady   = FALSE;                               //
  664.                                                        //
  665.   if( bFirstScreen )                                   // First Screen
  666.   {                                                    // Yes, IGNORE first line
  667.     uLineStart = 1;                                    //
  668.     bFirstScreen = FALSE;                              // reset flag
  669.   }                                                    //
  670.   else                                                 // Otherwise
  671.   {                                                    //
  672.     uLineStart = 0;                                    // Start with first
  673.   }                                                    // line
  674.                                                        //
  675.   for(uLine = uLineStart; uLine < uRows; uLine++)      // check each line of the PS
  676.   {                                                    // to see if it contains a
  677.     uOffset = uLine * (uCols + 2);                     // filename or Ready
  678.                                                        //
  679.     lstrncpy(zMsgBuffer,lpPS+uOffset,uCols);           //
  680.     zMsgBuffer[uCols] = '\0';                          // copy & make into str
  681.                                                        //
  682.     if( (*(lpPS+uOffset+8)  == SPACE_CHAR) &&          // If there are spaces
  683.         (*(lpPS+uOffset+9)  != SPACE_CHAR) &&          // at cols 8, 17, & 20
  684.         (*(lpPS+uOffset+17) == SPACE_CHAR) &&          // non spaces at cols 0,
  685.         (*(lpPS+uOffset+18) != SPACE_CHAR) &&          // 9, & 18 then the line
  686.         (uNumberOfFiles < MAXFILENAMES) )              // is a file name.
  687.     {                                                  //
  688.       lstrncpy(&zListFileNames[uNumberOfFiles][0],     // add found name to
  689.               lpPS+uOffset,SIZEOFFILENAME);            // names array
  690.       zListFileNames[uNumberOfFiles][SIZEOFFILENAME-1] //
  691.         = NULL_CHAR;                                   //
  692.       uNumberOfFiles++;                                //
  693.     }                                                  //
  694.                                                        //
  695.     strupr(zMsgBuffer);                                // Upcase it ...
  696.                                                        //
  697.     if(strstr(zMsgBuffer,zReady) != NULL)              // Check if CMS READY is
  698.     {                                                  // present indicating end
  699.       bReady = TRUE;                                   // of data.
  700.      }                                                 //
  701.   }
  702.  
  703.   //--------------------------------------------------------
  704.   //check lower right status message and respond accordingly
  705.  
  706.   lstrncpy(zMsgBuffer,lpPS+((uRows-1) * (uCols + 2)),uCols);
  707.                                                    //
  708.   zMsgBuffer[uCols] = NULL_CHAR;                   // Copy line & make a string
  709.                                                    //
  710.   strupr(zMsgBuffer);                              // Upcase it ...
  711.                                                    //
  712.   if(strstr(zMsgBuffer, zMore) != NULL)            //
  713.   {                                                // here we should send a
  714.      uRetCode = PSDATA_MORE;                       // clear and read the next
  715.   }                                                // screen of names
  716.   else if(strstr(zMsgBuffer,zRunning) != NULL)     //
  717.   {                                                //
  718.     if(bReady)                                     // running + ready tells us
  719.     {                                              // we are done
  720.       uRetCode = PSDATA_END;                       //
  721.     }                                              //
  722.     else                                           // this case means cms is
  723.     {                                              // not done writing file
  724.       uRetCode = PSDATA_REREAD;                    // names to the screen,
  725.     }                                              // so we should just
  726.   }                                                // reread the screen
  727.   else                                             //
  728.   {                                                //
  729.     uRetCode = PSDATA_ERROR;                       // shouldn't happen
  730.   }                                                //
  731.                                                    //
  732.    return(uRetCode);                               // return status
  733. }
  734.  
  735. //******************************************************************************
  736. //
  737. //  FUNCTION: Terminate( WORD uTerminateType )
  738. //
  739. //  PURPOSE:
  740. //
  741. //  When an error is encountered in processing the listfile request, this
  742. //  function will be called to terminate the dde conversations, or the
  743. //  entire application.
  744. //
  745. //  COMMENTS:
  746. //
  747. //  1. Values that can be passed to this function:
  748. //
  749. //     APPLICATION   - Terminates conversations, and application
  750. //
  751. //     CONVERSATIONS - Terminates conversations, but leaves the
  752. //                     application enabled for other requests.
  753. //
  754. //  RETURNS: void
  755. //
  756. //******************************************************************************
  757.  
  758. void Terminate( WORD uTerminateType )
  759. {
  760.   switch( uTerminateType )
  761.   {
  762.     case APPLICATION:
  763.     default:
  764.       DestroyWindow(hWndHidden);  // Destroy hidden window
  765.       DestroyWindow(hGlobalWnd);  // Destroy visible window
  766.  
  767.       //*** Drops through
  768.  
  769.     case CONVERSATIONS:
  770.       if( hRcvDlgClient != NULL )
  771.       {
  772.         PostMessage(hRcvDlgClient, WM_DDE_TERMINATE, (WPARAM)hGlobalWnd, 0L );
  773.         hRcvDlgClient = NULL;
  774.       }
  775.       if( hSessionServer != NULL )
  776.       {
  777.         PostMessage(hSessionServer, WM_DDE_TERMINATE, (WPARAM)hWndHidden, 0L );
  778.         hSessionServer = NULL;
  779.       }
  780.       break;
  781.  
  782.     case CONVERSATION_SESSION:
  783.       if( hSessionServer != NULL )
  784.       {
  785.         PostMessage(hSessionServer, WM_DDE_TERMINATE, (WPARAM)hWndHidden, 0L );
  786.         hSessionServer = NULL;
  787.       }
  788.       break;
  789.   }
  790. }
  791.