home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / sna / appc / sendrecv.c < prev    next >
Encoding:
Text File  |  1997-04-09  |  40.7 KB  |  1,260 lines

  1. /* sendrecv.c */
  2. /* (C) COPYRIGHT DATA CONNECTION LIMITED 1993 */
  3.  
  4. /*****************************************************************************/
  5. /* Change History                                                            */
  6. /*                                                                           */
  7. /*       04/05/93 NGR Created.                                               */
  8. /* TPED  26/05/93 SW  RECVTP must issue TP_ENDED after each conversation     */
  9. /* PERF  24/06/93 SW  Don't regenerate data for each SEND verb               */
  10. /* FILE  02/07/93 NGR Don't attempt to close NULL file handle                */
  11. /* PATH  10/08/93 NGR Gord's changes to get config from current directory    */
  12. /*****************************************************************************/
  13.  
  14. /*****************************************************************************/
  15. /*                                                                           */
  16. /* ROUTINE : SENDRECV                                                        */
  17. /*                                                                           */
  18. /* FUNCTION: This file contains the main routines for a simple bulk data     */
  19. /*           sending and receiving TPs SENDTP and RECVTP                     */
  20. /*                                                                           */
  21. /* INPUTS  : SENDTP.CFG (file) (documented below)                            */
  22. /*           RECVTP.CFG (file) (documented below)                            */
  23. /*                                                                           */
  24. /* OUTPUTS : SENDTP.OUT                                                      */
  25. /*           RECVTP.OUT                                                      */
  26. /*                                                                           */
  27. /*****************************************************************************/
  28.  
  29. /*****************************************************************************/
  30. /* Operation:                                                                */
  31. /*                                                                           */
  32. /* SENDTP                                                                    */
  33. /* DOS and OS/2. Simple command line TP which simply allocates, does the     */
  34. /* specified number of send_data and then deallocates. Done via a while loop */
  35. /* which makes calls to IssueNextVerb.                                       */
  36. /*                                                                           */
  37. /* RECVTP                                                                    */
  38. /* As SENDTP, but it receive_allocates, then receive_and_waits until it gets */
  39. /* deallocated. Repeat this NumConversation times.                           */
  40. /*                                                                           */
  41. /* NT and Win16. Simple windows apps which use the async verbs and control   */
  42. /* operation via the window proc of a minimised window. This proc makes      */
  43. /* calls to IssueNextVerb on receipt of an async_complete message            */
  44. /*                                                                           */
  45. /* IssueNextVerb uses the opcode of the verb which just completed to         */
  46. /* decide what to issue next, and calls the appropriate do_ routine to fill  */
  47. /* in the vcb, it then calls the appropriate APPC entry point.               */
  48. /*                                                                           */
  49. /* Send TP will initially issue a SEND_CONVERSATION verb in order to send    */
  50. /* the number of conversations to be done to the Recv TP which expect this   */
  51. /* to be sent to it.                                                         */
  52. /*                                                                           */
  53. /* The applications will terminate if they encounter an error and do not     */
  54. /* produce diagnostic output so the APPC API trace is the best place to look */
  55. /*****************************************************************************/
  56.  
  57. /*****************************************************************************/
  58. /* Configuration files:                                                      */
  59. /*                                                                           */
  60. /* Configuration file is C:\SENDTP.CFG or RECVTP.CFG which contains          */
  61. /* the following, one per line in any order. If not present then the given   */
  62. /* default is assumed.                                                       */
  63. /*                                                                           */
  64. /* ResultFile = <Name of file for results, default C:\(SEND/RECV)TP.OUT>     */
  65. /* LocalTPName = <Name to be used for TP started, default SENDTP/RECVTP>     */
  66. /*                                                                           */
  67. /* The following only apply to SENDTP                                        */
  68. /*                                                                           */
  69. /* NumConversations = <Number of conversations to be done, default = 1>      */
  70. /* LocalLUAlias = <Alias for local LU (!), default SENDLU>                   */
  71. /* RemoteLUAlias = <Alias for remote LU (!!), default RECVLU>                */
  72. /* ModeName = <!?! default #INTER>                                           */
  73. /* RemoteTPName = <name of the TP, default RECVTP>                           */
  74. /* NumSends = <number of SEND_DATA verbs per conversation, default = 2>      */
  75. /* ConfirmEvery = <number of SEND_DATA verbs between CONFIRMs, default = 1>  */
  76. /* SendSize = <number of bytes per SEND_DATA, default = 1024>                */
  77. /* SendConversation = <use the SEND_CONVERSATION verb, default = no>         */
  78. /*                                                                           */
  79. /* Note that if SendConversation is used then NumSends is irrelevant, the TP */
  80. /* will simply do NumConversations SEND_CONVERSATION verbs                   */
  81. /* If NumConversations is zero, then the TPs will do an infinite number of   */
  82. /* conversations.                                                            */
  83. /* If NumSends is zero, then SENDTP will never DEALLOCATE the first          */
  84. /* conversation.                                                             */
  85. /* If ConfirmEvery is zero, then SENDTP will not issue CONFIRM verbs.        */
  86. /*****************************************************************************/
  87. #if (defined(WINDOWS)||defined(WIN32))
  88. #include <windows.h>
  89. HINSTANCE hInst;
  90. #endif
  91.  
  92. #include <stdio.h>
  93. #include <stdlib.h>
  94. #include <string.h>
  95. #include <winappc.h>
  96. #include <wincsv.h>
  97. #include "sendrecv.h"
  98.  
  99. #if defined(DOS5) || defined(DOS)
  100. #define SYNC
  101. #endif
  102.  
  103. #ifdef WINDOWS
  104. #define memset(x,y,z) _fmemset(x,y,z)
  105. #define memchr(x,y,z) _fmemchr(x,y,z)
  106. #define strupr(x) _fstrupr(x)
  107. #define strcmpi(x,y) _fstricmp(x,y)
  108. #define strncpy(x,y,z) _fstrncpy(x,y,z)
  109. #endif
  110.  
  111. #ifdef SYNC
  112. /*****************************************************************************/
  113. /* main - reads initialisation info and creates threads                      */
  114. /*        DOS & OS\2 version                                                 */
  115. /*****************************************************************************/
  116. void main( int argc, char FAR * argv[])
  117. {
  118.  
  119. #if defined(WIN32) || defined(WINDOWS)
  120.   WAPPCDATA APPCData;
  121.   WNDCLASS class;
  122.   #define WinAPPCVERSION  0x0001
  123.  
  124.   /**************************************************************************/
  125.   /* Startup WinAPPC                                                        */
  126.   /**************************************************************************/
  127.   if (WinAPPCStartup(WinAPPCVERSION,&APPCData))
  128.   {
  129.      return (FALSE);
  130.   }
  131. #endif
  132.  
  133.   printf("\n\n\n\n\n\n\n");
  134. #ifdef SENDTP
  135.   printf("SENDTP - APPC Bulk data send program to be used with RECVTP\n");
  136. #else
  137.   printf("RECVTP - APPC Bulk data recv program to be used with SENDTP\n");
  138. #endif
  139.   printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n\n");
  140.  
  141.  
  142.   InitialiseMain();
  143.   ReadConfig();
  144.  
  145.   while (!TPDead)
  146.   {
  147.      IssueNextVerb();
  148.   }
  149. #ifdef SENDTP
  150.   OutputResults();
  151. #endif
  152.  
  153. #if defined(WIN32) || defined(WINDOWS)
  154.   WinAPPCCleanup();
  155. #endif
  156.  
  157.   printf("Finished");
  158.  
  159. }
  160. #else
  161. /*****************************************************************************/
  162. /* WinMain - reads initialisation info and controls message loop             */
  163. /*           NT and Win16 version                                            */
  164. /*****************************************************************************/
  165. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  166.                    LPSTR lpCmdLine, int nCmdShow)
  167. {
  168.  
  169.   MSG msg;
  170.  
  171.   hInst = hInstance;
  172.  
  173.   InitialiseMain();
  174.  
  175.   if (!InitialiseWinMain(hInstance))
  176.   {
  177.      return (FALSE);
  178.   }
  179.  
  180.   ReadConfig();
  181.  
  182.   while(GetMessage(&msg,NULL,0,0))
  183.   {
  184.      TranslateMessage(&msg);
  185.      DispatchMessage(&msg);
  186.   }
  187.  
  188.   return msg.wParam;         /* save exit parameter for return               */
  189.  
  190. }
  191.  
  192. /*****************************************************************************/
  193. /* InitialiseWinMain - does the windows bits of initialisation               */
  194. /*****************************************************************************/
  195. BOOL InitialiseWinMain(HINSTANCE hInstance)
  196. {
  197.    WAPPCDATA APPCData;
  198.    WNDCLASS class;
  199.    #define WinAPPCVERSION  0x0001
  200.  
  201.    /**************************************************************************/
  202.    /* Startup WinAPPC                                                        */
  203.    /**************************************************************************/
  204.    if (WinAPPCStartup(WinAPPCVERSION,&APPCData))
  205.    {
  206.       return (FALSE);
  207.    }
  208.  
  209.    if ( (ASYNC_COMPLETE =
  210.          RegisterWindowMessage(WIN_APPC_ASYNC_COMPLETE_MESSAGE)) == 0 )
  211.    {
  212.       return (0);
  213.    }
  214.  
  215.    async_corr=0;
  216.  
  217.    /**************************************************************************/
  218.    /* Register Window Class for our icon                                     */
  219.    /**************************************************************************/
  220.  
  221.    class.style = 0;
  222.    class.lpfnWndProc   = (WNDPROC)TPWndProc;
  223.    class.cbClsExtra    = (DWORD)0;
  224.    class.cbWndExtra    = (DWORD)0;
  225.    class.hInstance     = hInstance;
  226.    class.hIcon         = LoadIcon(hInstance,"MainIcon");
  227.    class.hCursor       = LoadCursor(NULL, IDC_ARROW);
  228.    class.hbrBackground = GetStockObject(WHITE_BRUSH);
  229.    class.lpszMenuName  = (LPSTR) NULL;
  230.    class.lpszClassName = (LPSTR) "SENDRECV\0";
  231.  
  232.    if (!RegisterClass(&class))
  233.    {
  234.      return (FALSE);
  235.    }
  236.  
  237.    /**************************************************************************/
  238.    /* Create the window                                                      */
  239.    /**************************************************************************/
  240. #ifdef SENDTP
  241.    sprintf(title,"APPC Send TP\0");
  242. #else
  243.    sprintf(title,"APPC Receive TP\0");
  244. #endif
  245.  
  246.    if ((hWndMain = CreateWindow("SENDRECV\0",      /* window class           */
  247.        title,                                      /* window name            */
  248.        WS_MINIMIZE|WS_OVERLAPPEDWINDOW,            /* window style           */
  249.        0,                                          /* x position             */
  250.        0,                                          /* y position             */
  251.        10,                                         /* width                  */
  252.        10,                                         /* height                 */
  253.        NULL,                                       /* parent handle          */
  254.        NULL,                                       /* menu or child ID       */
  255.        hInstance,                                  /* instance               */
  256.        NULL))                                      /* additional info        */
  257.        == NULL)
  258.    {
  259.       return (FALSE);
  260.    }
  261.  
  262.    ShowWindow(hWndMain, SW_MINIMIZE);
  263.  
  264.    return(TRUE);
  265.  
  266. }
  267.  
  268. /*****************************************************************************/
  269. /* Window proc for the iconised window                                       */
  270. /*****************************************************************************/
  271. LONG FAR PASCAL TPWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
  272. {
  273.    if (message == ASYNC_COMPLETE)
  274.    {
  275.       if (wParam != (WPARAM) async_corr)
  276.       {
  277.          /*****************************************************************/
  278.          /* This is not the correlator we were expecting, so we must die. */
  279.          /*****************************************************************/
  280.          TPDead = TRUE;
  281. #ifdef WIN32
  282.          DebugBreak();
  283. #endif
  284.       }
  285.       else
  286.       {
  287. #ifdef SENDTP
  288.          IssueNextVerb();
  289. #else
  290.          if (!GotNumConv)
  291.          {
  292.             /*****************************************************************/
  293.             /* We are still in the process of getting the number of convs to */
  294.             /* be done, so do the next stage of this. Note if all is not OK  */
  295.             /* then we just die.                                             */
  296.             /*****************************************************************/
  297.             Get_Run_Details();
  298.             if (TPDead)
  299.             {
  300.                PostMessage(hWndMain, WM_CLOSE, 0, 0);
  301.             }
  302.          }
  303.          else
  304.          {
  305.             IssueNextVerb();
  306.          }
  307. #endif
  308.       }
  309.    }
  310.    else
  311.    {
  312.       switch (message)
  313.       {
  314.          case WM_CREATE:
  315.             /*****************************************************************/
  316.             /* Post a message to ourselves to kick off the first verb        */
  317.             /*****************************************************************/
  318.             vcb.hdr.opcode = 0x0000;
  319.             async_corr = 0;
  320.             PostMessage(hWnd, ASYNC_COMPLETE, (WPARAM)async_corr,
  321.                                                  (LPARAM)(char FAR *)(vcbptr));
  322.             break;
  323.  
  324.          case WM_QUERYOPEN:
  325.             /*****************************************************************/
  326.             /* Prevent the window being opened                               */
  327.             /*****************************************************************/
  328.             break;
  329.  
  330.          case WM_CLOSE:
  331.             TPDead = TRUE;
  332.             WinAPPCCleanup();
  333. #ifdef SENDTP
  334.             OutputResults();
  335. #endif
  336.             return DefWindowProc(hWnd, message, wParam, lParam);
  337.             break;
  338.  
  339.          case WM_DESTROY:
  340.             if( DataPtr != NULL )
  341.             {
  342. #ifdef WINDOWS
  343.                 GlobalUnlock(LOWORD(GlobalHandle(SELECTOROF(DataPtr))));
  344.                 GlobalFree(LOWORD(GlobalHandle(SELECTOROF(DataPtr))));
  345. #else
  346.  #ifdef WIN32
  347.                  free(DataPtr);
  348.  #else
  349.                  DosFreeSeg(selector);
  350.  #endif
  351. #endif
  352.             }
  353.             PostQuitMessage(0);
  354.             break;
  355.  
  356.          default:
  357.             return DefWindowProc(hWnd, message, wParam, lParam);
  358.             break;
  359.       }
  360.    }
  361.    return 0l;
  362. }
  363.  
  364. #endif
  365.  
  366. /*****************************************************************************/
  367. /* InitialiseMain - blanks out variables.                                    */
  368. /*****************************************************************************/
  369. void InitialiseMain()
  370. {
  371.    NumConversations=0;
  372.    FirstConv=TRUE;
  373.    memset(LocalTPName,0,64);
  374.    ConvCount=0;
  375.    Convid=0;
  376.    SendSize=0;
  377.    memset(TPid,0,8);
  378.    TPDead=FALSE;
  379.    vcbptr=(char *)&vcb;
  380.    cnvtptr=(char *)&cnvt;
  381.  
  382. #ifdef SENDTP
  383.    NumSends=0;
  384.    SendConversation=0;
  385.    ConfirmEvery=0;
  386.    SendCount=0;
  387.    ConfirmCount=0;
  388.    datach='A';
  389.  
  390.    memset(LocalLUAlias,0,8);
  391.    memset(RemoteLUAlias,0,8);
  392.    memset(ModeName,0,8);
  393.    memset(RemoteTPName,0,64);
  394. #else
  395.    GotNumConv = FALSE;
  396.    GetStage = 0;
  397. #endif
  398.  
  399.  
  400. }
  401.  
  402. /*****************************************************************************/
  403. /* IssueNextVerb - looks at the verb which has just completed and does the   */
  404. /*                 next one                                                  */
  405. /*****************************************************************************/
  406. void IssueNextVerb()
  407. {
  408.    if (vcb.hdr.opcode != 0x0000)
  409.    {
  410.       ProcessReturns();
  411.    }
  412.    if (!TPDead)
  413.    {
  414.       switch (vcb.hdr.opcode)
  415.       {
  416.          case 0x0000:
  417. #ifdef SENDTP
  418.             Build_TP_STARTED();
  419.  
  420.             /**************************************************************/
  421.             /*PERF* Don't re-generate data each time we issue a send!     */
  422.             /**************************************************************/
  423.             GenerateData();
  424.  
  425. #else
  426.             Build_RECEIVE_ALLOCATE();
  427. #endif
  428.             break;
  429.  
  430. #ifdef SENDTP
  431.          case AP_TP_STARTED:
  432.             if (ConvCount == 0)
  433.             {
  434.                Send_Run_Details();
  435.             }
  436.             if (!TPDead)
  437.             {
  438.                NewConversation();
  439.                if (SendConversation)
  440.                {
  441.                   Build_MC_SEND_CONVERSATION();
  442.                }
  443.                else
  444.                {
  445.                   Build_MC_ALLOCATE();
  446.                }
  447.             }
  448.             break;
  449.  
  450.          case AP_M_ALLOCATE:
  451.             Build_MC_SEND_DATA();
  452.             break;
  453.  
  454.          case AP_M_SEND_DATA:
  455.             SendCount++;
  456.             ConfirmCount++;
  457.             if ((NumSends != 0) && (SendCount == NumSends))
  458.             {
  459.                Build_MC_DEALLOCATE();
  460.             }
  461.             else if ((ConfirmEvery != 0) && (ConfirmCount == ConfirmEvery))
  462.             {
  463.                Build_MC_CONFIRM();
  464.             }
  465.             else
  466.             {
  467.                Build_MC_SEND_DATA();
  468.             }
  469.             break;
  470.  
  471.          case AP_M_SEND_CONVERSATION:
  472.             if ((NumConversations != 0) && (ConvCount == NumConversations))
  473.             {
  474.                NewConversation();
  475.                Build_TP_ENDED();
  476.             }
  477.             else
  478.             {
  479.                NewConversation();
  480.                Build_MC_SEND_CONVERSATION();
  481.             }
  482.             break;
  483.  
  484.          case AP_M_CONFIRM:
  485.             ConfirmCount=0;
  486.             Build_MC_SEND_DATA();
  487.             break;
  488.  
  489.          case AP_M_DEALLOCATE:
  490.             if ((NumConversations !=0) && (ConvCount == NumConversations))
  491.             {
  492.                NewConversation();
  493.                Build_TP_ENDED();
  494.             }
  495.             else
  496.             {
  497.                NewConversation();
  498.                Build_MC_ALLOCATE();
  499.             }
  500.             break;
  501.  
  502.          case AP_TP_ENDED:
  503.             /**************************************************************/
  504.             /*TPED* Quit out and die if SENDTP                            */
  505.             /**************************************************************/
  506.             TPDead = TRUE;
  507.             break;
  508. #else
  509.          case AP_RECEIVE_ALLOCATE:
  510.             NewConversation();
  511.             Build_MC_RECEIVE_AND_WAIT();
  512.             break;
  513.  
  514.          case AP_M_RECEIVE_AND_WAIT:
  515.             if ((vcb.rcvwait.primary_rc == AP_DEALLOC_NORMAL))
  516.             {
  517.                /*************************************************************/
  518.                /*TPED* Issue TP_ENDED every time conversation deallocated   */
  519.                /*************************************************************/
  520.                Build_TP_ENDED();
  521.             }
  522.             else if ((vcb.rcvwait.what_rcvd == AP_CONFIRM_WHAT_RECEIVED) ||
  523.                      (vcb.rcvwait.what_rcvd == AP_DATA_COMPLETE_CONFIRM))
  524.             {
  525.                Build_MC_CONFIRMED();
  526.                Deallocated = FALSE;
  527.             }
  528.             else if ((vcb.rcvwait.what_rcvd == AP_CONFIRM_DEALLOCATE) ||
  529.                      (vcb.rcvwait.what_rcvd == AP_DATA_COMPLETE_CONFIRM_DEALL))
  530.             {
  531.                Build_MC_CONFIRMED();
  532.                Deallocated = TRUE;
  533.             }
  534.             else
  535.             {
  536.                Build_MC_RECEIVE_AND_WAIT();
  537.             }
  538.             break;
  539.  
  540.          case AP_M_CONFIRMED:
  541.             if (Deallocated)
  542.             {
  543.                /*************************************************************/
  544.                /*TPED* Issue TP_ENDED every time conversation deallocated   */
  545.                /*************************************************************/
  546.                Build_TP_ENDED();
  547.             }
  548.             else
  549.             {
  550.                Build_MC_RECEIVE_AND_WAIT();
  551.             }
  552.             break;
  553.  
  554.          case AP_TP_ENDED:
  555.             /**************************************************************/
  556.             /*TPED* If not completed all conversations,  issue RCV_ALLOC  */
  557.             /**************************************************************/
  558.             if ((NumConversations != 0) && (ConvCount < NumConversations))
  559.             {
  560.                Build_RECEIVE_ALLOCATE();
  561.             }
  562.             else
  563.             {
  564.                TPDead = TRUE;
  565.             }
  566.             break;
  567. #endif
  568.  
  569.          default:
  570.             /*****************************************************************/
  571.             /* What is this verb then ??                                     */
  572.             /*****************************************************************/
  573.             TPDead = TRUE;
  574. #ifdef WIN32
  575.             DebugBreak();
  576. #endif
  577.             break;
  578.  
  579.       } /* Op-code switch */
  580.  
  581.    } /* TPDead after previous verb */
  582.  
  583.    /**************************************************************************/
  584.    /* Now go ahead and issue the verb, if we're not dead.                    */
  585.    /**************************************************************************/
  586.    if (!TPDead)
  587.    {
  588. #ifdef SYNC
  589.       APPC((long)(vcbptr));
  590. #else
  591.       async_corr=WinAsyncAPPC(hWndMain, (long)(char FAR *)(vcbptr));
  592. #endif
  593.    }
  594. #ifndef SYNC
  595.    else
  596.    {
  597.       PostMessage(hWndMain, WM_CLOSE, 0, 0);
  598.    }
  599. #endif
  600. } /* Issue next verb */
  601.  
  602. #ifdef SENDTP
  603. void Build_TP_STARTED()
  604. {
  605.    CLEARVCB
  606.  
  607.    vcb.tpstart.opcode = AP_TP_STARTED;
  608.    memcpy(&(vcb.tpstart.lu_alias), LocalLUAlias, 8);
  609.    memcpy(&(vcb.tpstart.tp_name), LocalTPName, 64);
  610.  
  611. }
  612.  
  613. void Build_MC_ALLOCATE()
  614. {
  615.    CLEARVCB
  616.  
  617.    vcb.allocate.opcode = AP_M_ALLOCATE;
  618.    vcb.allocate.opext = AP_MAPPED_CONVERSATION;
  619.    memcpy(&(vcb.allocate.tp_id),TPid, 8);
  620.    vcb.allocate.sync_level = AP_CONFIRM_SYNC_LEVEL;
  621.    vcb.allocate.rtn_ctl = AP_WHEN_SESSION_ALLOCATED;
  622.    memcpy(&(vcb.allocate.plu_alias), RemoteLUAlias, 8);
  623.    memcpy(&(vcb.allocate.mode_name), ModeName, 8);
  624.    memcpy(&(vcb.allocate.tp_name), RemoteTPName, 64);
  625.    vcb.allocate.security = AP_NONE;
  626.  
  627. }
  628.  
  629. void Build_MC_DEALLOCATE()
  630. {
  631.    CLEARVCB
  632.  
  633.    vcb.deallocate.opcode = AP_M_DEALLOCATE;
  634.    vcb.deallocate.opext = AP_MAPPED_CONVERSATION;
  635.    memcpy(&(vcb.deallocate.tp_id), TPid, 8);
  636.    vcb.deallocate.conv_id = Convid;
  637.    if (ConfirmEvery == 0)
  638.    {
  639.       vcb.deallocate.dealloc_type = AP_FLUSH;
  640.    }
  641.    else
  642.    {
  643.       vcb.deallocate.dealloc_type = AP_SYNC_LEVEL;
  644.    }
  645.  
  646. }
  647.  
  648. void Build_MC_SEND_DATA()
  649. {
  650.    CLEARVCB
  651.  
  652.    //  PERF - GenerateData();
  653.  
  654.    vcb.snddata.opcode = AP_M_SEND_DATA;
  655.    vcb.snddata.opext = AP_MAPPED_CONVERSATION;
  656.    memcpy(&(vcb.snddata.tp_id), TPid, 8);
  657.    vcb.snddata.conv_id = Convid;
  658.    vcb.snddata.dlen = SendSize;
  659.    vcb.snddata.dptr = DataPtr;
  660.    vcb.snddata.type = AP_NONE;
  661. }
  662.  
  663. void Build_MC_SEND_CONVERSATION()
  664. {
  665.    CLEARVCB
  666.  
  667.    // PERF - GenerateData();
  668.  
  669.    vcb.sndconv.opcode = AP_M_SEND_CONVERSATION;
  670.    vcb.sndconv.opext = AP_MAPPED_CONVERSATION;
  671.    memcpy(&(vcb.sndconv.tp_id), TPid, 8);
  672.    vcb.sndconv.rtn_ctl = AP_WHEN_SESSION_ALLOCATED;
  673.    memcpy(&(vcb.sndconv.plu_alias), RemoteLUAlias, 8);
  674.    memcpy(&(vcb.sndconv.mode_name), ModeName, 8);
  675.    memcpy(&(vcb.sndconv.tp_name), RemoteTPName, 64);
  676.    vcb.sndconv.security = AP_NONE;
  677.    vcb.sndconv.dlen = SendSize;
  678.    vcb.sndconv.dptr = DataPtr;
  679. }
  680.  
  681. void Build_MC_CONFIRM()
  682. {
  683.    CLEARVCB
  684.  
  685.    vcb.confirm.opcode = AP_M_CONFIRM;
  686.    vcb.confirm.opext = AP_MAPPED_CONVERSATION;
  687.    memcpy(&(vcb.confirm.tp_id), TPid, 8);
  688.    vcb.confirm.conv_id = Convid;
  689. }
  690. #else
  691.  
  692. void Build_RECEIVE_ALLOCATE()
  693. {
  694.    CLEARVCB
  695.  
  696.    vcb.rcvalloc.opcode = AP_RECEIVE_ALLOCATE;
  697.    memcpy(&(vcb.rcvalloc.tp_name), LocalTPName, 64);
  698. }
  699.  
  700. void Build_MC_RECEIVE_AND_WAIT()
  701. {
  702.    CLEARVCB
  703.  
  704.    vcb.rcvwait.opcode = AP_M_RECEIVE_AND_WAIT;
  705.    vcb.rcvwait.opext = AP_MAPPED_CONVERSATION;
  706.    memcpy(&(vcb.rcvwait.tp_id),TPid,8);
  707.    vcb.rcvwait.conv_id = Convid;
  708.    vcb.rcvwait.rtn_status = AP_YES;
  709.    vcb.rcvwait.max_len = 0xFFFF;
  710.    vcb.rcvwait.dptr = DataPtr;
  711. }
  712.  
  713. void Build_MC_CONFIRMED()
  714. {
  715.    CLEARVCB
  716.  
  717.    vcb.confirmed.opcode = AP_M_CONFIRMED;
  718.    vcb.confirmed.opext = AP_MAPPED_CONVERSATION;
  719.    memcpy(&(vcb.confirmed.tp_id),TPid,8);
  720.    vcb.confirmed.conv_id = Convid;
  721. }
  722. #endif
  723.  
  724. void Build_TP_ENDED()
  725. {
  726.    CLEARVCB
  727.  
  728.    vcb.tpend.opcode = AP_TP_ENDED;
  729.    memcpy(&(vcb.tpend.tp_id), TPid, 8);
  730.    vcb.tpend.type = AP_SOFT;
  731. }
  732.  
  733. #ifdef SENDTP
  734. void Send_Run_Details()
  735. {
  736.    /**************************************************************************/
  737.    /* Issues a Send_Conversation verb to send the number of conversations to */
  738.    /* be done to the other side.                                             */
  739.    /**************************************************************************/
  740.    CLEARVCB
  741.  
  742.    vcb.sndconv.opcode = AP_M_SEND_CONVERSATION;
  743.    vcb.sndconv.opext = AP_MAPPED_CONVERSATION;
  744.    memcpy(&(vcb.sndconv.tp_id), TPid, 8);
  745.    vcb.sndconv.rtn_ctl = AP_WHEN_SESSION_ALLOCATED;
  746.    memcpy(&(vcb.sndconv.plu_alias), RemoteLUAlias, 8);
  747.    memcpy(&(vcb.sndconv.mode_name), ModeName, 8);
  748.    memcpy(&(vcb.sndconv.tp_name), RemoteTPName, 64);
  749.    vcb.sndconv.security = AP_NONE;
  750.    vcb.sndconv.dlen = sizeof(unsigned short);
  751.    vcb.sndconv.dptr = DataPtr;
  752. #ifdef WIN32
  753.    *((unsigned short UNALIGNED *) DataPtr) = NumConversations;
  754. #else
  755.    *((unsigned short far *)DataPtr) = NumConversations;
  756. #endif
  757.  
  758.    APPC((long)(vcbptr));
  759.    if (vcb.sndconv.primary_rc != AP_OK)
  760.    {
  761.       TPDead = TRUE;
  762.    }
  763. }
  764. #else
  765. void Get_Run_Details()
  766. {
  767.    /**************************************************************************/
  768.    /* Issues a Receive_Allocate and Receive_and_wait verb to get the number  */
  769.    /* of conversations to be done.                                           */
  770.    /* Returns true if this was successful, false otherwise.                  */
  771.    /**************************************************************************/
  772.    switch (GetStage)
  773.    {
  774.       case 0:
  775.  
  776.          CLEARVCB
  777.          vcb.rcvalloc.opcode = AP_RECEIVE_ALLOCATE;
  778.          memcpy(&(vcb.rcvalloc.tp_name), LocalTPName, 64);
  779.          async_corr=WinAsyncAPPC(hWndMain, (long)(char FAR *)(vcbptr));
  780.          GetStage = 1;
  781.          break;
  782.  
  783.       case 1:
  784.  
  785.          if (vcb.rcvalloc.primary_rc != AP_OK)
  786.          {
  787.             TPDead = TRUE;
  788.          }
  789.          else
  790.          {
  791.             memcpy(TPid,&(vcb.rcvalloc.tp_id),8);
  792.             Convid = vcb.rcvalloc.conv_id;
  793.             CLEARVCB
  794.             vcb.rcvwait.opcode = AP_M_RECEIVE_AND_WAIT;
  795.             vcb.rcvwait.opext = AP_MAPPED_CONVERSATION;
  796.             memcpy(&(vcb.rcvwait.tp_id),TPid,8);
  797.             vcb.rcvwait.conv_id = Convid;
  798.             vcb.rcvwait.rtn_status = AP_YES;
  799.             vcb.rcvwait.max_len = sizeof(unsigned short);
  800.             vcb.rcvwait.dptr = DataPtr;
  801.             async_corr=WinAsyncAPPC(hWndMain, (long)(char FAR *)(vcbptr));
  802.             GetStage = 2;
  803.          }
  804.          break;
  805.  
  806.       case 2:
  807.  
  808.          if (vcb.rcvwait.primary_rc != AP_DEALLOC_NORMAL)
  809.          {
  810.             TPDead = TRUE;
  811.          }
  812.          else
  813.          {
  814. #ifdef WIN32
  815.             NumConversations = *((unsigned short UNALIGNED *)DataPtr);
  816. #else
  817.             NumConversations = *((unsigned short far *)DataPtr);
  818. #endif
  819.             CLEARVCB
  820.             vcb.tpend.opcode = AP_TP_ENDED;
  821.             memcpy(&(vcb.tpend.tp_id), TPid, 8);
  822.             vcb.tpend.type = AP_SOFT;
  823.             async_corr=WinAsyncAPPC(hWndMain, (long)(char FAR *)(vcbptr));
  824.             GetStage = 3;
  825.          }
  826.          break;
  827.  
  828.       case 3:
  829.  
  830.          if (vcb.tpend.primary_rc != AP_OK)
  831.          {
  832.             TPDead = TRUE;
  833.          }
  834.          else
  835.          {
  836.             GotNumConv = TRUE;
  837.             vcb.hdr.opcode = 0x0000;
  838.             async_corr = 0;
  839.             PostMessage(hWndMain, ASYNC_COMPLETE, (WPARAM)async_corr,
  840.                                                  (LPARAM)(char FAR *)(vcbptr));
  841.          }
  842.          break;
  843.    }
  844. }
  845. #endif
  846.  
  847.  
  848. /*****************************************************************************/
  849. /* ProcessReturns - Checks return codes from the last verb to complete and   */
  850. /*                  saves off any useful information. If the return code is  */
  851. /*                  bad then we just die.                                    */
  852. /*****************************************************************************/
  853. void ProcessReturns()
  854. {
  855.    if ( (  vcb.hdr.primary_rc != AP_OK) &&
  856.        !( (vcb.hdr.opcode == AP_M_RECEIVE_AND_WAIT)&&
  857.           (vcb.hdr.primary_rc == AP_DEALLOC_NORMAL)  )  )
  858.    {
  859.       TPDead = TRUE;
  860.    }
  861.    else
  862.    {
  863.       switch (vcb.hdr.opcode)
  864.       {
  865.          case AP_TP_ENDED:
  866.             break;
  867. #ifdef SENDTP
  868.          case AP_TP_STARTED:
  869.             memcpy(TPid,&(vcb.tpstart.tp_id),8);
  870.             break;
  871.  
  872.          case AP_M_SEND_CONVERSATION:
  873.             break;
  874.  
  875.          case AP_M_ALLOCATE:
  876.             Convid = vcb.allocate.conv_id;
  877.             break;
  878.  
  879.          case AP_M_SEND_DATA:
  880.             break;
  881.  
  882.          case AP_M_DEALLOCATE:
  883.             Convid = 0;
  884.             break;
  885.  
  886.          case AP_M_CONFIRM:
  887.             break;
  888. #else
  889.          case AP_RECEIVE_ALLOCATE:
  890.             memcpy(TPid,&(vcb.rcvalloc.tp_id),8);
  891.             Convid = vcb.rcvalloc.conv_id;
  892.             break;
  893.  
  894.          case AP_M_RECEIVE_AND_WAIT:
  895.             break;
  896.  
  897.          case AP_M_CONFIRMED:
  898.             break;
  899. #endif
  900.          default:
  901.             TPDead = TRUE;
  902. #ifdef WIN32
  903.             DebugBreak();
  904. #endif
  905.             break;
  906.       }
  907.    }
  908. }
  909.  
  910. /*****************************************************************************/
  911. /* ReadConfig - Reads config info from SENDTP.CFG also allocates buffer for  */
  912. /*              sending                                                      */
  913. /*****************************************************************************/
  914. void ReadConfig()
  915. {
  916. #ifdef SENDTP
  917.    char buffer[200];
  918. #endif
  919. #ifdef DOS5
  920.    unsigned short selector;
  921. #endif
  922.  
  923.    SendSize = 0xFFFF;
  924.  
  925.    if (!ReadString("LocalTPName",LocalTPName,64))
  926.    {
  927. #ifdef SENDTP
  928.       strncpy(LocalTPName,"SENDTP",6);
  929. #else
  930.       strncpy(LocalTPName,"RECVTP",6);
  931. #endif
  932.    }
  933.    PadString(LocalTPName,64);
  934.    CONV_A_TO_E(LocalTPName,64);
  935.  
  936. #ifdef SENDTP
  937.    if (!ReadString("ResultFile",FileName,60))
  938.    {
  939.       strcpy(FileName,"C:\\SENDTP.OUT");
  940.    }
  941.    NumConversations=1;
  942.    if (ReadString("NumConversations",buffer,200))
  943.    {
  944.       NumConversations=atoi(buffer);
  945.    }
  946.    if (!ReadString("LocalLUAlias",LocalLUAlias,8))
  947.    {
  948.       strncpy(LocalLUAlias,"SENDLU",8);
  949.    }
  950.    PadString(LocalLUAlias,8);
  951.    if (!ReadString("RemoteLUAlias",RemoteLUAlias,8))
  952.    {
  953.       strncpy(RemoteLUAlias,"RECVLU",8);
  954.    }
  955.    PadString(RemoteLUAlias,8);
  956.    if (!ReadString("ModeName",ModeName,8))
  957.    {
  958.       strncpy(ModeName,"#INTER",8);
  959.    }
  960.    PadString(ModeName,8);
  961.    CONV_A_TO_E(ModeName,8);
  962.    if (!ReadString("RemoteTPName",RemoteTPName,64))
  963.    {
  964.       strncpy(RemoteTPName,"RECVTP",6);
  965.    }
  966.    PadString(RemoteTPName,64);
  967.    CONV_A_TO_E(RemoteTPName,64);
  968.    NumSends=2;
  969.    if (ReadString("NumSends",buffer,200))
  970.    {
  971.       NumSends=atoi(buffer);
  972.    }
  973.    ConfirmEvery=1;
  974.    if (ReadString("ConfirmEvery",buffer,200))
  975.    {
  976.       ConfirmEvery=atoi(buffer);
  977.    }
  978.    SendSize=1024;
  979.    if (ReadString("SendSize",buffer,200))
  980.    {
  981.       SendSize=atoi(buffer);
  982.    }
  983.    SendConversation=FALSE;
  984.    if (ReadString("SendConversation",buffer,200))
  985.    {
  986.       SendConversation = (*(strupr(buffer)) == 'Y');
  987.    }
  988. #endif
  989. #ifdef DOS5
  990.    DosAllocSeg(SendSize,&selector,1);
  991.    DataPtr = MAKEP(selector,0);
  992. #else
  993.  #ifdef WIN32
  994.    DataPtr = malloc(SendSize);
  995.  #else
  996.    DataPtr = (char far *)GlobalLock(GlobalAlloc(GPTR,SendSize));
  997.  #endif
  998. #endif
  999.    ResultBuf = (NumConversations == 0) ?
  1000.                NULL : malloc(NumConversations * sizeof(RESULT));
  1001.    ResultPtr = ResultBuf;
  1002. }
  1003.  
  1004. /*****************************************************************************/
  1005. /* CONV_A_TO_E - ASCII to EBCDIC conversion routine.                         */
  1006. /*****************************************************************************/
  1007. void CONV_A_TO_E(char FAR * string,int length)
  1008. {
  1009.    memset(cnvtptr,0,sizeof(cnvt));
  1010.  
  1011.    cnvt.opcode       = SV_CONVERT;
  1012.    cnvt.direction    = SV_ASCII_TO_EBCDIC;
  1013.    cnvt.char_set     = SV_AE;
  1014.  
  1015.    cnvt.len          = length;
  1016.    cnvt.source       = string;
  1017.    cnvt.target       = string;
  1018.  
  1019.    ACSSVC_C((long)(char far *) (cnvtptr));      /* Call ACSSVC - go convert! */
  1020. }
  1021.  
  1022. /*****************************************************************************/
  1023. /* CONV_E_TO_A - EBCDIC to ASCII conversion routine.                         */
  1024. /*****************************************************************************/
  1025. void CONV_E_TO_A(char FAR * string,int length)
  1026. {
  1027.    memset(cnvtptr,0,sizeof(cnvt));
  1028.  
  1029.    cnvt.opcode       = SV_CONVERT;
  1030.    cnvt.direction    = SV_EBCDIC_TO_ASCII;
  1031.    cnvt.char_set     = SV_AE;
  1032.    cnvt.len          = length;
  1033.    cnvt.source       = string;
  1034.    cnvt.target       = string;
  1035.  
  1036.    ACSSVC_C((long)(char FAR *) (cnvtptr));      /* Call ACSSVC - go convert! */
  1037. }
  1038.  
  1039.  
  1040.  
  1041. /*****************************************************************************/
  1042. /* NewConversation - Reset and record timers for this conversation.          */
  1043. /*****************************************************************************/
  1044. void NewConversation()
  1045. {
  1046.    RESULT NewTime;
  1047.  
  1048. #ifdef SENDTP
  1049.    SendCount = 0;
  1050.    ConfirmCount =0;
  1051. #endif
  1052.  
  1053.    if (FirstConv)
  1054.    {
  1055.       FirstConv = FALSE;
  1056.       ConvStarted = GetTickCount();
  1057.    }
  1058.    else if (ResultPtr != NULL)
  1059.    {
  1060.       *ResultPtr++ = ((NewTime = GetTickCount()) - ConvStarted);
  1061.       ConvStarted = NewTime;
  1062.    }
  1063.    ConvCount++;
  1064.    OUTPUTNUMBER
  1065. }
  1066.  
  1067. #ifdef SENDTP
  1068. /*****************************************************************************/
  1069. /* GenerateData    - Fill in data buffer                                     */
  1070. /*****************************************************************************/
  1071. void GenerateData()
  1072. {
  1073.    int i;
  1074.    int div;
  1075.    int rem;
  1076.    char FAR * dptr;
  1077.  
  1078.    dptr = DataPtr;
  1079.    div = SendSize / 5;
  1080.    rem = SendSize % 5;
  1081.  
  1082.    for (; div--;)
  1083.    {
  1084.       for (i=4; i--; *dptr++ = datach);
  1085.       *dptr++ = '.';
  1086.    }
  1087.    for (; rem--; *dptr++ = datach);
  1088.  
  1089.    datach = (datach=='Z' ? 'A' : datach + 1);
  1090. }
  1091.  
  1092. /*****************************************************************************/
  1093. /* OutputResults - dump the times of conversations to file                   */
  1094. /*****************************************************************************/
  1095. void OutputResults()
  1096. {
  1097.   FILE *h = NULL;
  1098.   RESULT FAR * ptr = NULL;
  1099.   unsigned short i = 0;
  1100.   RESULT TotalTime=0;
  1101.  
  1102.   h = fopen(FileName,"w");
  1103.   if (h != NULL)
  1104.   {
  1105.     fprintf(h,"SENDTP Results\n--------------\n\n");
  1106.     CONV_E_TO_A(LocalTPName,64);
  1107.     fprintf(h,"Local TP Name           = %.64s\n",LocalTPName);
  1108.     CONV_E_TO_A(RemoteTPName,64);
  1109.     fprintf(h,"Remote TP Name          = %.64s\n",RemoteTPName);
  1110.     fprintf(h,"Local LU Alias          = %.8s\n",LocalLUAlias);
  1111.     fprintf(h,"Remote LU Alias         = %.8s\n",RemoteLUAlias);
  1112.     CONV_E_TO_A(ModeName,8);
  1113.     fprintf(h,"ModeName                = %.8s\n",ModeName);
  1114.     fprintf(h,"Number of conversations = %d\n",NumConversations);
  1115.     if (!SendConversation)
  1116.     {
  1117.        fprintf(h,"Sends per conversation  = %d\n",NumSends);
  1118.        fprintf(h,"Sends between confirms  = %d\n",ConfirmEvery);
  1119.     }
  1120.     fprintf(h,"Bytes per send          = %d\n",SendSize);
  1121.     fprintf(h,"Use SEND_CONVERSATION   = %s\n",(SendConversation ? "Yes":"No"));
  1122.     fprintf(h,"\n");
  1123.  
  1124.     ptr = ResultBuf;
  1125.     while (ptr < ResultPtr)
  1126.     {
  1127.         TotalTime += *ptr;
  1128.       fprintf(h,"Conversation number %d, time = %.3f seconds\n",i++,
  1129.                                                 (((float) *ptr++) / 1000.0 ));
  1130.       
  1131.     }
  1132.     fprintf( h,"Total Time in Conversation = %.3f seconds\n",(((float)TotalTime)/1000.0) );
  1133.     fclose(h);                                                        /*FILE*/
  1134.   }
  1135. }
  1136.  
  1137. #endif
  1138.  
  1139. /*****************************************************************************/
  1140. /* ReadString - Get a line of text from the config file.                     */
  1141. /*****************************************************************************/
  1142. int ReadString(char FAR * lpValueName,char FAR * lpData, int maxlen)
  1143. {
  1144.    char       buffer[200];
  1145.    char      *p = NULL;
  1146.    FILE      *h = NULL;
  1147.    BOOL       match = FALSE;
  1148.    BOOL       eof   = FALSE;
  1149.    int        rc = 0;
  1150.    int        ch = 0;
  1151.    int        i = 0;
  1152.    BOOL       gotdata = FALSE;
  1153.    char       separators[] = " =\t\n";
  1154.  
  1155. #if (defined(WINDOWS)||defined(WIN32))                                 /*PATH*/
  1156.                                                                        /*PATH*/
  1157.     GetModuleFileName( hInst, buffer, sizeof(buffer) );                /*PATH*/
  1158.     lstrcpy( buffer+lstrlen(buffer) - 4, ".CFG" );                     /*PATH*/
  1159.     h = fopen( buffer, "r" );                                          /*PATH*/
  1160.     buffer[0] = '\0';                                                  /*PATH*/
  1161.                                                                        /*PATH*/
  1162. #else                                                                  /*PATH*/
  1163. #ifdef SENDTP
  1164.    h = fopen("C:\\sendtp.cfg", "r");
  1165. #else
  1166.    h = fopen("C:\\recvtp.cfg", "r");
  1167. #endif
  1168. #endif                                                                 /*PATH*/
  1169.  
  1170.    lpValueName=strupr(lpValueName);
  1171.  
  1172.    if (h != NULL)
  1173.    {
  1174.       while ((!match) && (!eof))
  1175.       {
  1176.          /********************************************************************/
  1177.          /* Use fgetc to read a line of text from the file.                  */
  1178.          /********************************************************************/
  1179.          for (i=0; (i<sizeof(buffer))     &&
  1180.                    ((ch=getc(h)) != EOF)  &&
  1181.                    ((char)ch != '\n');
  1182.                                       i++)
  1183.          {
  1184.             buffer[i] = (char)ch;
  1185.          }
  1186.          if ((char)ch == '\n')
  1187.          {
  1188.             buffer[i++] = (char)ch;
  1189.          }
  1190.          if (ch == EOF)
  1191.          {
  1192.             eof = TRUE;
  1193.          }
  1194.          else
  1195.          {
  1196.             /*****************************************************************/
  1197.             /* Compare the 1st token in the line read with the requested     */
  1198.             /* param.                                                        */
  1199.             /*****************************************************************/
  1200.             if (!strcmpi(strupr(strtok(buffer, separators)), lpValueName))
  1201.             {
  1202.                match = TRUE;
  1203.                /**************************************************************/
  1204.                /* Get a pointer to the 2nd token (the value we want)         */
  1205.                /**************************************************************/
  1206.                p = strtok(NULL, separators);
  1207.  
  1208.                /**************************************************************/
  1209.                /* Copy the data IF there is some.                            */
  1210.                /**************************************************************/
  1211.                if (p != NULL)
  1212.                {
  1213.                   /***********************************************************/
  1214.                   /* Force a NULL after the 2nn token                        */
  1215.                   /***********************************************************/
  1216.                   strtok(NULL, separators);
  1217.  
  1218.                   /***********************************************************/
  1219.                   /* Copy the data                                           */
  1220.                   /***********************************************************/
  1221.                   strncpy(lpData, p, maxlen);
  1222.                   gotdata = TRUE;
  1223.                }
  1224.                else
  1225.                {
  1226.                   gotdata = FALSE;
  1227.                }
  1228.             }
  1229.          }
  1230.       }
  1231.  
  1232.       if (gotdata)
  1233.       {
  1234.          rc = 1;
  1235.       }
  1236.  
  1237.       fclose(h);
  1238.  
  1239.    }
  1240.  
  1241. return(rc);
  1242. }
  1243.  
  1244. /*****************************************************************************/
  1245. /* PadString - Remove terminating NULL  and pad on the right with spaces     */
  1246. /*****************************************************************************/
  1247. void PadString(char FAR * string,int length)
  1248. {
  1249.    char FAR * p;
  1250.    if ((p=memchr(string,'\0',length)) != NULL)
  1251.    {
  1252.       while (p < string+length)
  1253.       {
  1254.          *p++=' ';
  1255.       }
  1256.    }
  1257. }
  1258.  
  1259. 
  1260.