home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1996 October / PCO_10.ISO / filesbbs / lw321.arj / TAP11.ZIP / tapserve.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  28.1 KB  |  1,028 lines

  1. //
  2. // TAPSERVER.C
  3. //
  4. // TAP
  5. // File Transfer Data Sharing
  6. // Server Code
  7. // Revision 1.10
  8. //
  9. // 12/28/94   First Created
  10. //
  11. #define INCL_WIN
  12. #define INCL_DOS
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <memory.h>
  17. #include <process.h>
  18. #include <os2.h>
  19. #include "tapserve.h"
  20. #include "tapres.h"
  21.  
  22. //
  23. // PTAPSERVERINFO InitializeServer_TAP(char szVersion[]);
  24. //
  25. // Initializes the TAP Server
  26. //
  27. // Parameters:
  28. // szVersion
  29. //   Server version string, max. 30 characters.
  30. //
  31. // Returns: Pointer to server instance data, or NULL
  32. // on failure.
  33. //
  34. PTAPSERVERINFO InitializeServer_TAP(char szVersion[])
  35. {
  36. PTAPSERVERINFO pTapServerInfo = NULL;
  37.  
  38.     // Create pTapServerInfo
  39.     pTapServerInfo = malloc(sizeof(TAPSERVERINFO));
  40.  
  41.     // Did we get back a valid pointer?
  42.     if (pTapServerInfo)
  43.     {
  44.         // Initialize pTapServerInfo
  45.         pTapServerInfo -> cb = sizeof(TAPSERVERINFO);
  46.         pTapServerInfo -> phWritePipe = NULL;
  47.         pTapServerInfo -> lNumPipes = 0;
  48.         pTapServerInfo -> lShutdown = FALSE;
  49.         pTapServerInfo -> lFileOpen = FALSE;
  50.  
  51.         // Create unowned mutual exclusion semaphore for
  52.         // controlling access to the TAP server
  53.         DosCreateMutexSem(NULL,
  54.                                 &(pTapServerInfo -> hServerMutex),
  55.                                 0L,
  56.                                 FALSE);
  57.  
  58.         // Initialize version string
  59.  
  60.         strncpy(pTapServerInfo -> szVersion,
  61.                     TAP_SERVER_VERSION,
  62.                     sizeof (pTapServerInfo->szVersion) - 1);
  63.                 // NUL terminate  (note that strncpy will not NUL terminate when max len is reached)
  64.         pTapServerInfo -> szVersion[sizeof (pTapServerInfo->szVersion) - 1] = '\0';
  65.  
  66.         // Initialize pTapServerInfo -> tiTapInfo (Pipe packet)
  67.  
  68.         pTapServerInfo -> tiTapInfo . szFileName [0] = 0;
  69.         pTapServerInfo -> tiTapInfo . lCurrentFileSize = TAP_SIZE_UNKNOWN;
  70.         pTapServerInfo -> tiTapInfo . lCompleteFileSize = TAP_SIZE_UNKNOWN;
  71.         pTapServerInfo -> tiTapInfo . ulFlags = 0;
  72.  
  73.         // Create pipe update semaphore in set mode
  74.         DosCreateEventSem(NULL,
  75.                                 &(pTapServerInfo -> hevUpdate),
  76.                                 0L,
  77.                                 FALSE);
  78.  
  79.         // Start server thread
  80.       #ifdef __BORLANDC__
  81.         pTapServerInfo -> tidTAPServer = (TID)
  82.             _beginthread(ServerThread_TAP, 8192, (void *) pTapServerInfo);
  83.       #else
  84.         pTapServerInfo -> tidTAPServer = (TID)
  85.             _beginthread(ServerThread_TAP, NULL, 8192, (void *) pTapServerInfo);
  86.       #endif
  87.     }
  88.  
  89.     szVersion = szVersion;
  90.  
  91.     return pTapServerInfo;
  92. }
  93.  
  94. //
  95. // int DeInitializeServer_TAP(PTAPSERVERINFO pTapServerInfo);
  96. //
  97. // DeInitializes the TAP Server
  98. //
  99. // Parameters:
  100. // pTapServerInfo
  101. //   Pointer to the TAP Server instance data.
  102. //
  103. // Returns: TRUE on success.
  104. //
  105. int DeInitializeServer_TAP(PTAPSERVERINFO pTapServerInfo)
  106. {
  107. int iRet = TRUE;
  108.  
  109.     // Request exclusive access to the server
  110.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  111.                                 (ULONG)SEM_INDEFINITE_WAIT);
  112.  
  113.     // Tell server thread to shutdown,
  114.     // it will take care of freeing memory
  115.     pTapServerInfo -> lShutdown = TRUE;
  116.     iRet = !DosPostEventSem(pTapServerInfo -> hevUpdate);
  117.  
  118.     // Release exclusive access to the server
  119.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  120.  
  121.     return iRet;
  122. }
  123.  
  124. //
  125. // int StartApplication_TAP(PTAPSERVERINFO pTapServerInfo,
  126. //                                        char *szAppPath,
  127. //                                        char *szAppParams,
  128. //                                        char *szAppTitle)
  129. //
  130. // Starts a TAP Application and sets up the TAP Server
  131. // to service the application.
  132. //
  133. // Parameters:
  134. // pTapServerInfo
  135. //   Pointer to the TAP Server instance data.
  136. // szAppPath
  137. //   Fully qualified application executable specification.
  138. // szAppParams
  139. //   Command line parameters sent to the application.
  140. // szAppTitle
  141. //   Default TAP Application title (for VIO titlebar).
  142. //
  143. // Returns: TRUE on success
  144. //
  145. int StartApplication_TAP(PTAPSERVERINFO pTapServerInfo,
  146.                                     char *szAppPath,
  147.                                     char *szAppParams,
  148.                                     char *szAppTitle)
  149. {
  150. int iRet = TRUE;
  151. char *szParameters;
  152. PROGDETAILS Details;
  153. PTIB ptib;
  154. PPIB ppib;
  155. char szPipeName[CCHMAXPATH];
  156.  
  157.     // Request exclusive access to the server
  158.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  159.                                 (ULONG)SEM_INDEFINITE_WAIT);
  160.  
  161.     // Allocate memory for a new pipe
  162.     pTapServerInfo -> lNumPipes ++;
  163.     if (pTapServerInfo -> phWritePipe)
  164.         pTapServerInfo -> phWritePipe = (HFILE *)
  165.                 realloc(pTapServerInfo -> phWritePipe,
  166.                                 (size_t)(pTapServerInfo -> lNumPipes * sizeof(HFILE)));
  167.     else
  168.         pTapServerInfo -> phWritePipe = (HFILE *)
  169.                 malloc((size_t)(pTapServerInfo -> lNumPipes * sizeof(HFILE)));
  170.  
  171.     // Query our environment
  172.     // so we can create a unique
  173.     // pipe name!
  174.     DosGetInfoBlocks(&ptib, &ppib);
  175.  
  176.     // Create pipe name
  177.     sprintf(szPipeName,
  178.                 "\\PIPE\\TapPipe%d_%d_%d",
  179.                 ppib -> pib_ulpid,
  180.                 ptib -> tib_ptib2 -> tib2_ultid,
  181.                 pTapServerInfo -> lNumPipes);
  182.  
  183.     // Create a new named pipe
  184.     DosCreateNPipe(szPipeName,
  185.                         &(pTapServerInfo -> phWritePipe[ pTapServerInfo -> lNumPipes - 1]),
  186.                         NP_NOWRITEBEHIND |
  187.                         NP_INHERIT |
  188.                         NP_ACCESS_DUPLEX,
  189.                         NP_NOWAIT |
  190.                         NP_TYPE_BYTE |
  191.                         1,
  192.                         1024,
  193.                         8192,
  194.                         0);
  195.  
  196.     // Allow a client to connect
  197.     DosConnectNPipe(pTapServerInfo -> phWritePipe [ pTapServerInfo -> lNumPipes - 1]);
  198.  
  199.     // Release exclusive access to the server
  200.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  201.  
  202.     // ***
  203.     // Setup for application launch
  204.     // ***
  205.  
  206.     // Query our environment
  207.     // to pass on to the shell
  208.     DosGetInfoBlocks(&ptib, &ppib);
  209.  
  210.     // Setup calling data structure
  211.     memset (&Details, 0, sizeof(PROGDETAILS));
  212.     Details.Length          = sizeof(PROGDETAILS);
  213.     Details.progt.progc     = PROG_DEFAULT;
  214.     Details.progt.fbVisible = SHE_VISIBLE;
  215.     Details.pszTitle        = szAppTitle;
  216.     Details.pszExecutable   = szAppPath;
  217.     Details.pszEnvironment  = ppib->pib_pchenv;
  218.     Details.swpInitial.fl   = SWP_ACTIVATE; /* window positioning */
  219.     Details.swpInitial.hwndInsertBehind = HWND_TOP;
  220.  
  221.     // Add our parameter to the end of the parameter list
  222.     szParameters = (char *) malloc(strlen(szAppParams) + 100);
  223.     sprintf(szParameters, "%s /TAP=%s", szAppParams, szPipeName);
  224.  
  225.     // Start application
  226.     if (!WinStartApp(NULLHANDLE,
  227.                     &Details,
  228.                     szParameters,
  229.                     NULL,
  230.                     SAF_STARTCHILDAPP))
  231.         iRet=FALSE;
  232.  
  233.     // Free up parameter list
  234.     free((void *) szParameters);
  235.  
  236.     // Wait for client to connect
  237.  
  238.     {  ULONG ulMaxRetries = 50;    // Wait no longer than 5 seconds! 
  239.         for (;;) {
  240.             AVAILDATA availData;
  241.             ULONG         ulDummy;
  242.             ULONG         ulState;
  243.             DosPeekNPipe (pTapServerInfo -> phWritePipe [ pTapServerInfo -> lNumPipes - 1],
  244.                            &ulDummy, 0, &ulDummy, &availData, &ulState);
  245.  
  246.             if (ulState == NP_CONNECTED)
  247.                 break;
  248.  
  249.             if (ulMaxRetries-- == 0)
  250.                 return (-1);
  251.  
  252.             DosSleep (100);
  253.             }
  254.         }
  255.  
  256.     // Request exclusive access to the server
  257.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  258.                                 (ULONG)SEM_INDEFINITE_WAIT);
  259.  
  260.     // Write server version 
  261.  
  262.     {    PTAPPACKET pTapPacket;
  263.         ULONG  ulBytesWritten;
  264.         USHORT usVersionLength = (USHORT)strlen (pTapServerInfo->szVersion);
  265.         USHORT usPacketLength = (USHORT)(sizeof (pTapPacket->versionPacket) + usVersionLength);
  266.         pTapPacket = malloc (usPacketLength);
  267.         pTapPacket->versionPacket.cb = usPacketLength;
  268.         pTapPacket->versionPacket.usFlags = TAP_VERSION;
  269.         pTapPacket->versionPacket.usVersionLength = usVersionLength;
  270.         strcpy (pTapPacket->versionPacket.szVersion, pTapServerInfo->szVersion);
  271.         DosWrite (pTapServerInfo -> phWritePipe [ pTapServerInfo -> lNumPipes - 1],
  272.                     pTapPacket, pTapPacket->versionPacket.cb, &ulBytesWritten);
  273.         free (pTapPacket);
  274.         }
  275.  
  276.     // If a file is currently open we need to send the new pipe a BOF !
  277.  
  278.     if (pTapServerInfo->lFileOpen) {
  279.         PTAPPACKET pTapPacket;
  280.         ULONG  ulBytesWritten;
  281.         USHORT usFileNameLength = (USHORT)strlen (pTapServerInfo->tiTapInfo.szFileName);
  282.         USHORT usPacketLength = (USHORT)(sizeof (pTapPacket->beginFilePacket) + usFileNameLength);
  283.         pTapPacket = malloc (usPacketLength);
  284.         pTapPacket->beginFilePacket.cb = usPacketLength;
  285.         pTapPacket->beginFilePacket.usFlags = TAP_BOF;
  286.         pTapPacket->beginFilePacket.lCurrentFileSize = pTapServerInfo->tiTapInfo.lCurrentFileSize;
  287.         pTapPacket->beginFilePacket.lCompleteFileSize = pTapServerInfo->tiTapInfo.lCompleteFileSize;
  288.         pTapPacket->beginFilePacket.usFileNameLength = usFileNameLength;
  289.         strcpy (pTapPacket->beginFilePacket.szFileName, pTapServerInfo->tiTapInfo.szFileName);
  290.         DosWrite (pTapServerInfo -> phWritePipe [ pTapServerInfo -> lNumPipes - 1],
  291.                     pTapPacket, pTapPacket->beginFilePacket.cb, &ulBytesWritten);
  292.         free (pTapPacket);
  293.         }
  294.  
  295.     // Release exclusive access to the server
  296.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  297.  
  298.     return iRet;
  299. }
  300.  
  301. //
  302. // int SelectApplication_TAP(PTAPSERVERINFO pTapServerInfo,
  303. //                                      HWND hWndParent,
  304. //                                      HWND hWndOwner,
  305. //                                      HMODULE hmod);
  306. //
  307. // Allows the user to select from a list of installed
  308. // TAP applications and launches that TAP application.
  309. //
  310. // In order for this function to work you must add the
  311. // resource file TAPSERVE.RC to your resources. To locate
  312. // these resources you must pass the module handle or
  313. // NULLHANDLE if the resources should be loaded from the
  314. // application's EXE.
  315. //
  316. // Alternatively you can launch TAP applications directly
  317. // by calling StartApplication_TAP.
  318. //
  319. // Parameters:
  320. // pTapServerInfo
  321. //   Pointer to the TAP Server instance data.
  322. // hWndParent
  323. //   Handle to the parent window of the dialog.
  324. // hWndOwner
  325. //   Handle to the owner window of the dialog.
  326. // hmod
  327. //   Handle to the module that contains the application's
  328. //   resources, or NULLHANDLE if resources come from the
  329. //   application's EXE.
  330. //
  331. //  Returns: TRUE on success.
  332. //
  333. int SelectApplication_TAP(PTAPSERVERINFO pTapServerInfo,
  334.                                   HWND hWndParent,
  335.                                   HWND hWndOwner,
  336.                                   HMODULE hmod)
  337. {
  338. int iRet = TRUE;
  339.     // Bring up the application selection dialog
  340.     if (WinDlgBox(hWndParent,
  341.                          hWndOwner,
  342.                          SelectApplicationDlgProc,
  343.                          hmod,
  344.                          DLG_SELECT_TAP,
  345.                          pTapServerInfo )
  346.             == DID_ERROR )
  347.         iRet = FALSE;
  348.  
  349.     return iRet;
  350. }
  351.  
  352. //
  353. // int GetApplications_TAP(char *szApplications, PULONG pulSize);
  354. //
  355. // Gets a list of registered TAP Applications and/or size
  356. // of the list of TAP Applications. The list of TAP applications
  357. // is returned as a buffer of null-terminated ASCII strings,
  358. // the final ASCII string double null-terminated.
  359. //
  360. // For Example: String1\0String2\0FinalString\0\0
  361. //
  362. // Parameters:
  363. // szApplications
  364. //   Pointer to a buffer where the application list will
  365. //   be stored. If this is NULL, only the application list
  366. //   size will be put in pulSize. (Output)
  367. // pulSize
  368. //   Size of the szApplications buffer in bytes. (Input)
  369. //   Size of the application list, in bytes. (Output)
  370. //
  371. // Returns: TRUE on success.
  372. //
  373. int GetApplications_TAP(char *szApplications, PULONG pulSize)
  374. {
  375. int iRet = TRUE;
  376.  
  377.     // If we have a pointer, get the data
  378.     if (szApplications)
  379.         if (!PrfQueryProfileString(HINI_SYSTEMPROFILE,
  380.                                                 TAP_INI_APPNAME,
  381.                                                 NULL,
  382.                                                 "\0\0",
  383.                                                 szApplications,
  384.                                                 *pulSize))
  385.                 iRet = FALSE;
  386.  
  387.     // And always return how much data we query in pulSize
  388.     if (!PrfQueryProfileSize(HINI_SYSTEMPROFILE,
  389.                                         TAP_INI_APPNAME,
  390.                                         NULL,
  391.                                         pulSize))
  392.         iRet = FALSE;
  393.  
  394.     return iRet;
  395. }
  396.  
  397. //
  398. // int GetApplicationInfo_TAP(char *szAppName,
  399. //                                        PTAPAPPENTRY pTapAppInfo);
  400. //
  401. // Given a TAP Application name (retrieved with
  402. // GetApplications_TAP) returns a structure containing
  403. // information about that TAP Application. For more
  404. // information, the structure is located in TAP.H.
  405. //
  406. // Parameters:
  407. // szAppName
  408. //   Name of the TAP Application.
  409. // pTapAppInfo
  410. //   Pointer to a TapAppInfo structure. (Output)
  411. //
  412. // Returns: TRUE on success.
  413. //
  414. int GetApplicationInfo_TAP(char *szAppName,
  415.                                     PTAPAPPENTRY pTapAppInfo)
  416. {
  417. int iRet = TRUE;
  418. ULONG DataLength;
  419.  
  420.     // Setup length of our data structure
  421.     DataLength = sizeof(TAPAPPENTRY);
  422.  
  423.     // Query application information
  424.     if (!PrfQueryProfileData(HINI_SYSTEMPROFILE,
  425.                                         TAP_INI_APPNAME,
  426.                                         szAppName,
  427.                                         pTapAppInfo,
  428.                                         &DataLength))
  429.         iRet = FALSE;
  430.  
  431.     return iRet;
  432. }
  433.  
  434. //
  435. // int SetFileName_TAP(PTAPSERVERINFO pTapServerInfo,
  436. //                                char *szFileName);
  437. //
  438. // Sets the name of the current TAP file.
  439. //
  440. // This filename must include path information (either
  441. // relative or fully qualified). That is, "TAP\TAPSAMP.EXE"
  442. // is an acceptable path. This function will automatically
  443. // fully qualify a relative path.
  444. //
  445. // Parameters:
  446. // pTapServerInfo
  447. //   Pointer to the TAP Server instance data.
  448. // szFileName
  449. //   Relative or fully qualified file specification.
  450. //
  451. // Returns: TRUE on success.
  452. //
  453. int SetFileName_TAP(PTAPSERVERINFO pTapServerInfo,
  454.                             char *szFileName)
  455. {
  456. int iRet = TRUE;
  457.  
  458.     // Request exclusive access to the server
  459.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  460.                                 (ULONG)SEM_INDEFINITE_WAIT);
  461.  
  462.     // Create a fully qualified file name and put
  463.     // it into the pipe packet
  464.     DosQueryPathInfo(szFileName,
  465.                           FIL_QUERYFULLNAME,
  466.                           pTapServerInfo -> tiTapInfo . szFileName,
  467.                           CCHMAXPATH);
  468.  
  469.     // Set flag indicating we started a new file
  470.     pTapServerInfo -> lFileOpen = TRUE;
  471.     pTapServerInfo -> tiTapInfo.ulFlags |= TAP_BOF;
  472.  
  473.     // Release exclusive access to the server
  474.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  475.  
  476.     return iRet;
  477. }
  478.  
  479. //
  480. // int SetCompleteSize_TAP(PTAPSERVERINFO pTapServerInfo,
  481. //                                    long lCompleteFileSize);
  482. //
  483. // Sets the complete size of the file. If this size is
  484. // not known it may be set to -1 (TAP_SIZE_UNKNOWN).
  485. //
  486. // Parameters:
  487. // pTapServerInfo
  488. //   Pointer to the TAP Server instance data.
  489. // lCompleteFileSize
  490. //   Size of the file when transfer is complete.
  491. //
  492. // Returns: TRUE on success.
  493. //
  494. int SetCompleteSize_TAP(PTAPSERVERINFO pTapServerInfo,
  495.                                 long lCompleteFileSize)
  496. {
  497. int iRet = TRUE;
  498.  
  499.     // Request exclusive access to the server
  500.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  501.                                 (ULONG)SEM_INDEFINITE_WAIT);
  502.  
  503.     // Set complete file size in pipe packet
  504.     pTapServerInfo -> tiTapInfo . lCompleteFileSize = lCompleteFileSize;
  505.  
  506.     // Release exclusive access to the server
  507.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  508.  
  509.     return iRet;
  510. }
  511.  
  512. //
  513. // int SetCurrentSize_TAP(PTAPSERVERINFO pTapServerInfo,
  514. //                                 long lCurrentFileSize);
  515. //
  516. // Sets the current size of the file. If thie size is
  517. // not known it may be set to -1 (TAP_SIZE_UNKNOWN).
  518. //
  519. // Parameters:
  520. // pTapServerInfo
  521. //   Pointer to the TAP Server instance data.
  522. // lCurrentFileSize
  523. //   Size of the file at the current time.
  524. //
  525. // Returns: TRUE on success.
  526. //
  527. int SetCurrentSize_TAP(PTAPSERVERINFO pTapServerInfo,
  528.                                 long lCurrentFileSize)
  529. {
  530. int iRet = TRUE;
  531.  
  532.     // Request exclusive access to the server
  533.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  534.                                 (ULONG)SEM_INDEFINITE_WAIT);
  535.  
  536.     // Set current file size in pipe packet
  537.     pTapServerInfo -> tiTapInfo . lCurrentFileSize = lCurrentFileSize;
  538.  
  539.     // Set flag indicating the file size changed
  540.     pTapServerInfo->tiTapInfo.ulFlags |= TAP_NEW_SIZE;
  541.  
  542.     // Send new file information down the pipe
  543.     DosPostEventSem(pTapServerInfo -> hevUpdate);
  544.  
  545.     // Release exclusive access to the server
  546.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  547.  
  548.     return iRet;
  549. }
  550.  
  551. //
  552. // int EmergencyClose_TAP(PTAPSERVERINFO pTapServerInfo)
  553. //
  554. // Calls for all TAP Applications to immediately
  555. // close the current file.
  556. //
  557. // This function might be called if the current file needs
  558. // to be erased, moved, copied, etc. Note that this file
  559. // close operation will not take affect as soon as this
  560. // function returns. A 1/4 second delay is recommended
  561. // following this call before attempting any other file
  562. // operations. Normally the operation will succeed, but
  563. // if it fails delay another 1/4 second and retry the
  564. // operation.
  565. //
  566. // NOTE: This does NOT close the current file on the
  567. // server side. You must do this yourself.
  568. //
  569. // Parameters:
  570. // pTapServerInfo
  571. //   Pointer to the TAP Server instance data.
  572. //
  573. // Returns: TRUE on success.
  574. //
  575. int EmergencyClose_TAP(PTAPSERVERINFO pTapServerInfo)
  576. {
  577. int iRet = TRUE;
  578.  
  579.     // Request exclusive access to the server
  580.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  581.                                 (ULONG)SEM_INDEFINITE_WAIT);
  582.  
  583.     // Set flag asking for an emergency close file
  584.     pTapServerInfo->tiTapInfo.ulFlags |= TAP_EMERGENCY_CLOSE;
  585.     pTapServerInfo -> lFileOpen = FALSE;
  586.  
  587.     // Send new file information down the pipe
  588.     DosPostEventSem(pTapServerInfo -> hevUpdate);
  589.  
  590.     // Release exclusive access to the server
  591.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  592.  
  593.     return iRet;
  594. }
  595.  
  596. //
  597. // int Cancel_TAP(PTAPSERVERINFO pTapServerInfo);
  598. //
  599. // Alerts the TAP Applications that the current
  600. // transfer batch has been cancelled.
  601. //
  602. // Parameters:
  603. // pTapServerInfo
  604. //   Pointer to the TAP Server instance data.
  605. //
  606. // Returns: TRUE on success.
  607. //
  608. int Cancel_TAP(PTAPSERVERINFO pTapServerInfo)
  609. {
  610. int iRet = TRUE;
  611.  
  612.     // Request exclusive access to the server
  613.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  614.                                 (ULONG)SEM_INDEFINITE_WAIT);
  615.  
  616.     // Set flag asking for a cancel transfer
  617.     pTapServerInfo->tiTapInfo.ulFlags |= TAP_CANCEL;
  618.     pTapServerInfo -> lFileOpen = FALSE;
  619.  
  620.     // Send new file information down the pipe
  621.     DosPostEventSem(pTapServerInfo -> hevUpdate);
  622.  
  623.     // Release exclusive access to the server
  624.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  625.  
  626.     return iRet;
  627. }
  628.  
  629. //
  630. // int EndOfFile_TAP(PTAPSERVERINFO pTapServerInfo);
  631. //
  632. // Alerts the TAP Applications that we have reached
  633. // the end of the current file.
  634. //
  635. // Parameters:
  636. // pTapServerInfo
  637. //   Pointer to the TAP Server instance data.
  638. //
  639. // Returns: TRUE on success.
  640. //
  641. int EndOfFile_TAP(PTAPSERVERINFO pTapServerInfo)
  642. {
  643. int iRet = TRUE;
  644.  
  645.     // Request exclusive access to the server
  646.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  647.                                 (ULONG)SEM_INDEFINITE_WAIT);
  648.  
  649.     // Set flag saying we've reached the end of this file
  650.     pTapServerInfo -> tiTapInfo.ulFlags |= TAP_EOF;
  651.     pTapServerInfo -> lFileOpen = FALSE;
  652.  
  653.     // Send new file information down the pipe
  654.     DosPostEventSem(pTapServerInfo -> hevUpdate);
  655.  
  656.     // Release exclusive access to the server
  657.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  658.  
  659.     return iRet;
  660. }
  661.  
  662. //
  663. // int EndOfBatch_TAP(PTAPSERVERINFO pTapServerInfo);
  664. //
  665. // Alerts the TAP Applications that we have reached
  666. // the end of the current file transfer batch.
  667. // That is, that the application should expect no more
  668. // files.
  669. //
  670. // Parameters:
  671. // pTapServerInfo
  672. //   Pointer to the TAP Server instance data.
  673. //
  674. // Returns: TRUE on success.
  675. //
  676. int EndOfBatch_TAP(PTAPSERVERINFO pTapServerInfo)
  677. {
  678. int iRet = TRUE;
  679.  
  680.     // Request exclusive access to the server
  681.     DosRequestMutexSem(pTapServerInfo -> hServerMutex,
  682.                                 (ULONG)SEM_INDEFINITE_WAIT);
  683.  
  684.     // Set flag saying we've reached the end of the batch
  685.     pTapServerInfo->tiTapInfo.ulFlags |= TAP_EOB;
  686.     pTapServerInfo -> lFileOpen = FALSE;
  687.  
  688.     // Send new file information down the pipe
  689.     DosPostEventSem(pTapServerInfo -> hevUpdate);
  690.  
  691.     // Release exclusive access to the server
  692.     DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  693.  
  694.     return iRet;
  695. }
  696.  
  697. //
  698. // void ServerThread_TAP(void *ServerInfo)
  699. //
  700. //              -= Internal only =-
  701. // -= Not to be called from outside this module =-
  702. //
  703. // Handles the dispatch of file information to
  704. // TAP Applications.
  705. //
  706. void ServerThread_TAP (void *ServerInfo) {
  707.     PTAPSERVERINFO pTapServerInfo = (PTAPSERVERINFO) ServerInfo;
  708.     ULONG PostCount;
  709.     ULONG BytesWritten;
  710.     long cnter;
  711.     PTAPPACKET pTapPacket;
  712.     USHORT usPacketLength;
  713.     
  714.  
  715.     for (;;)
  716.     {
  717.         // Wait until someone asks us to send a new pipe packet
  718.         DosWaitEventSem(pTapServerInfo -> hevUpdate, (ULONG)SEM_INDEFINITE_WAIT);
  719.  
  720.         // Request exclusive access to the server
  721.         DosRequestMutexSem(pTapServerInfo -> hServerMutex,    (ULONG)SEM_INDEFINITE_WAIT);
  722.  
  723.         // Note that TAP_VERSION is handled elsewhere; it is sent immediately when thread is created!
  724.  
  725.         if (pTapServerInfo->tiTapInfo.ulFlags & TAP_BOF) {
  726.             USHORT usFileNameLength = (USHORT)strlen (pTapServerInfo->tiTapInfo.szFileName);
  727.             usPacketLength = (USHORT)(sizeof (pTapPacket->beginFilePacket) + usFileNameLength);
  728.             pTapPacket = malloc (usPacketLength);
  729.             pTapPacket->beginFilePacket.lCurrentFileSize = pTapServerInfo->tiTapInfo.lCurrentFileSize;
  730.             pTapPacket->beginFilePacket.lCompleteFileSize = pTapServerInfo->tiTapInfo.lCompleteFileSize;
  731.             pTapPacket->beginFilePacket.usFileNameLength = usFileNameLength;
  732.             strcpy (pTapPacket->beginFilePacket.szFileName, pTapServerInfo->tiTapInfo.szFileName);
  733.             }
  734.         else if (pTapServerInfo->tiTapInfo.ulFlags & TAP_NEW_SIZE) {
  735.             usPacketLength = (USHORT)sizeof (pTapPacket->newSizePacket);
  736.             pTapPacket = malloc (usPacketLength);
  737.             pTapPacket->newSizePacket.lCurrentFileSize = pTapServerInfo->tiTapInfo.lCurrentFileSize;
  738.             pTapPacket->newSizePacket.lCompleteFileSize = pTapServerInfo->tiTapInfo.lCompleteFileSize;
  739.             }
  740.         else {
  741.             usPacketLength = sizeof (pTapPacket->flagPacket);
  742.             pTapPacket = malloc (usPacketLength);
  743.             }
  744.  
  745.         pTapPacket->flagPacket.cb = usPacketLength;
  746.         pTapPacket->flagPacket.usFlags = (USHORT)pTapServerInfo->tiTapInfo.ulFlags;
  747.  
  748.         // Send the packet down all pipes
  749.         for (cnter=0; cnter < pTapServerInfo->lNumPipes; cnter++) {
  750.             DosWrite (pTapServerInfo->phWritePipe[cnter], pTapPacket, pTapPacket->flagPacket.cb, &BytesWritten);
  751.             }
  752.  
  753.         free (pTapPacket);
  754.  
  755.         // Reset flags
  756.         pTapServerInfo -> tiTapInfo . ulFlags = 0L;
  757.  
  758.         // Reset update event semaphore
  759.         DosResetEventSem(pTapServerInfo -> hevUpdate, &PostCount);
  760.  
  761.         // Release exclusive access to the server
  762.         DosReleaseMutexSem(pTapServerInfo -> hServerMutex);
  763.  
  764.         // If this is a shutdown request break out
  765.         if (pTapServerInfo -> lShutdown)
  766.             break;
  767.     }
  768.  
  769.     // ***
  770.     // Shut down code
  771.     // ***
  772.  
  773.     // Close semaphores
  774.     DosCloseEventSem(pTapServerInfo -> hevUpdate);
  775.     DosCloseMutexSem(pTapServerInfo -> hServerMutex);
  776.  
  777.     // Close pipes
  778.     for(cnter=0; cnter < pTapServerInfo->lNumPipes; cnter++) {
  779.         DosClose(pTapServerInfo -> phWritePipe[cnter]);
  780.         }
  781.  
  782.     // Free memory
  783.     free((void *) pTapServerInfo -> phWritePipe);
  784.     free((void *) pTapServerInfo);
  785.  
  786.     // End this thread
  787.     _endthread();
  788. }
  789.  
  790. //
  791. // void LaunchApplicationThread_TAP(void *data);
  792. //
  793. // Thread to start the TAP application,
  794. // so we don't hog the message queue
  795. //
  796. void LaunchApplicationThread_TAP(void *data)
  797. {
  798. PLAUNCHINFO pLaunchInfo = (PLAUNCHINFO) data;
  799. HAB hab;
  800. HMQ hmq;
  801.  
  802.    // And to make things even more fun,
  803.    // StartApplication_TAP requires the
  804.    // presence of a message queue
  805.    hab=WinInitialize(0);
  806.    hmq=WinCreateMsgQueue(hab, 0);
  807.  
  808.     // Start TAP application
  809.    StartApplication_TAP(pLaunchInfo -> pTapServerInfo,
  810.                                 pLaunchInfo -> szProgram,
  811.                                 pLaunchInfo -> szParams,
  812.                                 pLaunchInfo -> szTitle);
  813.  
  814.    // We are responsible for freeing this structure
  815.    free(pLaunchInfo);
  816.  
  817.    // Free up PM resources
  818.    WinDestroyMsgQueue(hmq);
  819.    WinTerminate(hab);
  820.  
  821.    // End this thread
  822.    _endthread();
  823. }
  824.  
  825. //
  826. // MRESULT EXPENTRY SelectApplicationDlgProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  827. //
  828. //              -= Internal only =-
  829. // -= Not to be called from outside this module =-
  830. //
  831. MRESULT EXPENTRY SelectApplicationDlgProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  832. {
  833. MRESULT mResult;
  834.  
  835.     switch (msg)
  836.     {
  837.         case WM_INITDLG :
  838.         {
  839.         char *szApps;
  840.         ULONG ulSize;
  841.  
  842.             // ***
  843.             // Store PTAPSERVERINFO in the window words
  844.             // ***
  845.             WinSetWindowPtr(hWnd, QWL_USER, (PVOID) mp2);
  846.  
  847.             // ***
  848.             // Initialize listbox with TAP applications available
  849.             // ***
  850.  
  851.             // Get size of application list
  852.             if (GetApplications_TAP(NULL, &ulSize))
  853.             {
  854.                 // Allocate enough memory for list
  855.                 szApps = (char *) malloc(ulSize + 10);
  856.  
  857.                 if (GetApplications_TAP(szApps, &ulSize))
  858.                 {
  859.                 ULONG cnter;
  860.                 char szApp[256];
  861.                 int iAppLen;
  862.  
  863.                     // Traverse the array of strings
  864.                     for (cnter=0, iAppLen = 0; cnter<ulSize; cnter++)
  865.                             // Is there more to be added to the app name?
  866.                             if (szApps[cnter])
  867.                                 szApp[iAppLen++] = szApps[cnter];
  868.                             else
  869.                                 // No, have we seen two NULLs in a row?
  870.                                 if (!iAppLen)
  871.                                     // We've reached the end of the list
  872.                                     break;
  873.                                 else
  874.                                 {
  875.                                     // This is the end of an app name
  876.                                     szApp[iAppLen] = 0;
  877.                                     iAppLen = 0;
  878.  
  879.                                     // Insert this application into the
  880.                                     // list box
  881.                                     WinSendDlgItemMsg(hWnd,
  882.                                                             ID_APPLIST_TAP,
  883.                                                             LM_INSERTITEM,
  884.                                                             (MPARAM) LIT_SORTASCENDING,
  885.                                                             (MPARAM) szApp);
  886.                                 }
  887.                 }
  888.  
  889.                 // Free up application list
  890.                 free(szApps);
  891.             }
  892.  
  893.             mResult = (MRESULT) FALSE;
  894.             break;
  895.         }
  896.  
  897.         case WM_CONTROL :
  898.         {
  899.         USHORT id = SHORT1FROMMP(mp1);
  900.         USHORT usNotifyCode = SHORT2FROMMP(mp1);
  901.  
  902.             // Was an application selected in the list box?
  903.             if ((id == ID_APPLIST_TAP) &&
  904.                  (usNotifyCode == LN_SELECT))
  905.             {
  906.             TAPAPPENTRY TapAppEntry;
  907.             char szAppName[256];
  908.             SHORT sItemSelected;
  909.             IPT MLETextLen;
  910.  
  911.                 // Get selected application name
  912.                 sItemSelected = (SHORT)
  913.                     WinSendDlgItemMsg(hWnd,
  914.                                             ID_APPLIST_TAP,
  915.                                             LM_QUERYSELECTION,
  916.                                             (MPARAM) LIT_FIRST,
  917.                                             (MPARAM) 0);
  918.  
  919.                 WinSendDlgItemMsg(hWnd,
  920.                                         ID_APPLIST_TAP,
  921.                                         LM_QUERYITEMTEXT,
  922.                                         (MPARAM) MPFROM2SHORT(sItemSelected, 256),
  923.                                         (MPARAM) szAppName);
  924.  
  925.                 // Get the description of the application
  926.                 GetApplicationInfo_TAP(szAppName, &TapAppEntry);
  927.  
  928.                 // Put new application description into MLE
  929.                 MLETextLen = (IPT)
  930.                     WinSendDlgItemMsg(hWnd,
  931.                                             ID_APPDESC_TAP,
  932.                                             MLM_QUERYTEXTLENGTH,
  933.                                             (MPARAM) 0,
  934.                                             (MPARAM) 0);
  935.  
  936.                 WinSendDlgItemMsg(hWnd,
  937.                                         ID_APPDESC_TAP,
  938.                                         MLM_SETSEL,
  939.                                         (MPARAM) 0,
  940.                                         (MPARAM) MLETextLen);
  941.  
  942.                 WinSendDlgItemMsg(hWnd,
  943.                                         ID_APPDESC_TAP,
  944.                                         MLM_INSERT,
  945.                                         (MPARAM) TapAppEntry.szDescription,
  946.                                         (MPARAM) 0);
  947.  
  948.             }
  949.  
  950.             // Call default handler
  951.             mResult = WinDefDlgProc(hWnd, msg, mp1, mp2);
  952.             break;
  953.         }
  954.  
  955.         case WM_COMMAND :
  956.         {
  957.             // Should we launch an application?
  958.             if (SHORT1FROMMP(mp1) == DID_OK)
  959.             {
  960.             SHORT sItemSelected;
  961.             char szAppName[256];
  962.  
  963.                 // Get selected item number
  964.                 sItemSelected = (SHORT)
  965.                     WinSendDlgItemMsg(hWnd,
  966.                                             ID_APPLIST_TAP,
  967.                                             LM_QUERYSELECTION,
  968.                                             (MPARAM) LIT_FIRST,
  969.                                             (MPARAM) 0);
  970.  
  971.                 if (sItemSelected != LIT_NONE)
  972.                 {
  973.                 PTAPSERVERINFO pTapServerInfo;
  974.                 TAPAPPENTRY TapAppEntry;
  975.             PLAUNCHINFO pLaunchInfo;
  976.  
  977.                     // Get pTapServerInfo
  978.                     pTapServerInfo = (PTAPSERVERINFO) WinQueryWindowPtr(hWnd, QWL_USER);
  979.  
  980.                     // Get name of selected item
  981.                     WinSendDlgItemMsg(hWnd,
  982.                                             ID_APPLIST_TAP,
  983.                                             LM_QUERYITEMTEXT,
  984.                                             (MPARAM) MPFROM2SHORT(sItemSelected, 256),
  985.                                             (MPARAM) szAppName);
  986.  
  987.                     // Get application's information
  988.                     GetApplicationInfo_TAP(szAppName, &TapAppEntry);
  989.  
  990.                // Start a thread to launch the application,
  991.                // otherwise we will hog the message queue.
  992.                // The launch thread will terminate after the
  993.                // TAP application has started.
  994.                pLaunchInfo = malloc(sizeof(LAUNCHINFO));
  995.                pLaunchInfo -> cb = sizeof(LAUNCHINFO);
  996.                pLaunchInfo -> pTapServerInfo = pTapServerInfo;
  997.                strcpy(pLaunchInfo -> szProgram, TapAppEntry.szProgram);
  998.                strcpy(pLaunchInfo -> szParams, TapAppEntry.szParams);
  999.                strcpy(pLaunchInfo -> szTitle, "TAP Application");
  1000.  
  1001. #ifdef __BORLANDC__
  1002.                _beginthread(LaunchApplicationThread_TAP,
  1003.                             8192L,
  1004.                             pLaunchInfo);
  1005. #else
  1006.                _beginthread(LaunchApplicationThread_TAP,
  1007.                             NULL,
  1008.                             8192L,
  1009.                             pLaunchInfo);
  1010. #endif
  1011.                }
  1012.             }
  1013.  
  1014.             // Call default handler
  1015.             mResult = WinDefDlgProc(hWnd, msg, mp1, mp2);
  1016.             break;
  1017.         }
  1018.  
  1019.         default :
  1020.             // Call default handler
  1021.             mResult = WinDefDlgProc(hWnd, msg, mp1, mp2);
  1022.             break;
  1023.     }
  1024.  
  1025.     return mResult;
  1026. }
  1027.  
  1028.