home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / sdk / mapi / win16 / dev / sendapp / sendmail.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-11  |  35.3 KB  |  1,278 lines

  1. /*
  2.  -  S E N D M A I L . C P P
  3.  -  Copyright (C) 1995 Microsoft Corporation
  4.  -
  5.  *  Purpose:
  6.  *      Main source module for SendApp.  This is an MFC application.
  7.  *
  8.  */
  9.  
  10.  
  11.  
  12. #ifndef _WIN95
  13.     #define CTL3D
  14. #endif
  15.  
  16. #define SMALL_ATTACHMENT_SIZE     32000
  17. #define LARGE_ATTACHMENT_SIZE   1000000
  18. #define HUGE_ATTACHMENT_SIZE    2600000
  19.  
  20.  
  21.  
  22. #ifdef WIN32
  23. #ifdef _WIN95
  24. #define _INC_OLE
  25. #endif
  26. #define INC_OLE2
  27. #define INC_RPC
  28. #endif
  29.  
  30. #include <afxwin.h>     
  31. #include <windowsx.h>
  32. #include <string.h>
  33.  
  34. #ifdef WIN16
  35. #include <compobj.h>
  36. #endif
  37.  
  38. #ifdef WIN32
  39. #include <objbase.h>
  40. #include <objerror.h>
  41. #ifdef _WIN95
  42. #include <ole2.h>
  43. #endif
  44. #endif
  45.  
  46.  
  47.  
  48. #ifdef WIN16
  49.     #include <direct.h>
  50. #endif
  51. #include "strtbl.h"
  52. #include <mapidefs.h>
  53. #include <commdlg.h>
  54. #include <mapi.h>
  55. #include <mapiwin.h>
  56. #include <time.h>
  57. #include "pvalloc.h"
  58. #ifndef _WIN95
  59.     #include <ctl3d.h>
  60. #endif
  61. #include "smplmapi.h"
  62. #include "resource.h"
  63. #include "sendmail.h"
  64.  
  65.  
  66. /*
  67.  -
  68.  -  Global data
  69.  -
  70.  */
  71.  
  72. CTheApp                 theApp;
  73. LHANDLE                 lhSession   = NULL;
  74. HWND                    hWnd;
  75. HINSTANCE               hLib        = NULL;
  76. BOOL                    fLoggedOn   = FALSE;
  77. static HCURSOR          hWaitCur;
  78. BOOL                    fKillThread = FALSE;
  79. static lpMapiRecipDesc  lpRecips    = NULL;
  80. ULONG                   cRecips     = 0;
  81. BOOL                    fCustomAttachment = FALSE;
  82. OPENFILENAME            ofn;
  83. char *                  szMax = "Maximum number of characters";
  84. char                    szFileName[256] = "";
  85.  
  86. LPFNMAPILOGON           lpfnMAPILogon = NULL;
  87. LPFNMAPILOGOFF          lpfnMAPILogoff = NULL;
  88. LPFNMAPISENDMAIL        lpfnMAPISendMail = NULL;
  89. LPFNMAPISENDDOCUMENTS   lpfnMAPISendDocuments = NULL;
  90. LPFNMAPIFINDNEXT        lpfnMAPIFindNext = NULL;
  91. LPFNMAPIREADMAIL        lpfnMAPIReadMail = NULL;
  92. LPFNMAPISAVEMAIL        lpfnMAPISaveMail = NULL;
  93. LPFNMAPIDELETEMAIL      lpfnMAPIDeleteMail = NULL;
  94. LPFNMAPIFREEBUFFER      lpfnMAPIFreeBuffer = NULL;
  95. LPFNMAPIADDRESS         lpfnMAPIAddress = NULL;
  96. LPFNMAPIDETAILS         lpfnMAPIDetails = NULL;
  97. LPFNMAPIRESOLVENAME     lpfnMAPIResolveName = NULL;
  98.  
  99.  
  100. /*
  101.  -
  102.  -  Main message loop
  103.  -
  104.  */
  105.  
  106. BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd )
  107.     ON_COMMAND( IDM_EXIT,   OnExit )
  108.     ON_WM_CLOSE()
  109.     ON_COMMAND( IDM_SEND,   OnSend )
  110.     ON_COMMAND( IDM_ABOUT,  OnAbout )
  111.     ON_WM_DESTROY()
  112. END_MESSAGE_MAP()
  113.  
  114.  
  115. /*
  116.  -
  117.  -  CMainWindow Methods.
  118.  -
  119.  */
  120.  
  121. /*
  122.  -  InitInstance
  123.  -
  124.  *  Purpose:
  125.  *      When any CTheApp object is created, this member function is
  126.  *      automatically  called.  The main window of the application
  127.  *      is created and shown here.
  128.  *
  129.  *  Parameters:
  130.  *      None
  131.  *
  132.  *  Returns:
  133.  *      TRUE if the initialization is successful.
  134.  *
  135.  */
  136.  
  137. BOOL CTheApp::InitInstance()
  138. {
  139.     TRACE( "SendMail\n" );
  140.     m_pMainWnd = new CMainWindow();
  141.  
  142.     m_pMainWnd->ShowWindow( m_nCmdShow );
  143.     m_pMainWnd->UpdateWindow();
  144.  
  145.     CoInitialize(NULL); // Init the 'new' operator for OLE 2.0 compatibility
  146.  
  147. #ifdef CTL3D
  148.     Ctl3dRegister( AfxGetInstanceHandle() );   // Register Ctl3D controls
  149.     Ctl3dAutoSubclass( AfxGetInstanceHandle());
  150. #endif
  151.  
  152.     return InitMapiDll();
  153. }
  154.  
  155.  
  156. /*
  157.  -  CMainWindow::
  158.  -  CMainWindow
  159.  -
  160.  *  Purpose:
  161.  *      Create the window with the appropriate style, size, menu, etc.
  162.  *
  163.  *  Parameters:
  164.  *      None
  165.  *
  166.  *
  167.  */
  168.  
  169. CMainWindow::CMainWindow()
  170. {
  171.     CRect rect;
  172.     int nL, nT, nR, nB = 100;
  173.  
  174.     LoadAccelTable( "MainAccelTable" );
  175.  
  176.     nL = GetPrivateProfileInt("Location", "Left", 5, "SendMail.ini");
  177.     nT = GetPrivateProfileInt("Location", "Top", 5, "SendMail.ini");
  178.     nR = GetPrivateProfileInt("Location", "Right", 300, "SendMail.ini");
  179.     nB = GetPrivateProfileInt("Location", "Bottom", 75, "SendMail.ini");
  180.  
  181.     rect.SetRect(nL, nT, nR, nB);
  182.     Create( NULL, "MAPI",
  183.         WS_OVERLAPPEDWINDOW, rect, NULL, MAKEINTRESOURCE(AFX_IDI_STD_FRAME) );
  184.  
  185.     hWnd = m_hWnd;
  186.  
  187. #ifdef CTL3D
  188.     Ctl3dColorChange();
  189. #else
  190.     CMainWindow::OnSysColorChange();
  191. #endif
  192.  
  193. }
  194.  
  195.  
  196.  
  197. /*
  198.  -  ExitInstance
  199.  -
  200.  *  Purpose:
  201.  *
  202.  *  Parameters:
  203.  *      None
  204.  *
  205.  *  Returns:
  206.  *      TRUE if the Exit is successful.
  207.  *
  208.  */
  209.  
  210. int CTheApp::ExitInstance()
  211. {
  212.  
  213. #ifdef CTL3D
  214.     Ctl3dUnregister(AfxGetInstanceHandle());
  215. #endif
  216.     return CWinApp::ExitInstance();
  217. }
  218.  
  219.  
  220. /*
  221.  -  CMainWindow::
  222.  -  OnExit
  223.  -
  224.  *  Purpose:
  225.  *      Asks the application to Close itself.
  226.  *
  227.  */
  228.  
  229. void CMainWindow::OnExit()
  230. {
  231.     SendMessage( WM_CLOSE );
  232. }
  233.  
  234.  
  235. /*
  236.  -
  237.  -  CMainWindow::
  238.  -  OnClose
  239.  -
  240.  -  Purpose:
  241.  -      Gets the windows coordinates, and deletes all temporary files.
  242.  -
  243.  -  Parameters:
  244.  -      None
  245.  -
  246.  -  Returns:
  247.  -      Void
  248.  -
  249.  */
  250.  
  251. void CMainWindow::OnClose()
  252. {
  253.     ULONG           ulResult;
  254.     CRect           lpRect;
  255.     char            szBuf[256];
  256.     char            szTempPath[256];
  257.     WIN32_FIND_DATA pfd;
  258.     HANDLE          hFind;
  259.  
  260.     GetTempPath(256,szTempPath);
  261. #ifdef WIN32
  262.     SetCurrentDirectory(szTempPath);
  263. #else
  264.     _chdir(szTempPath);
  265. #endif
  266.  
  267.     lstrcat(szTempPath,"*.XXX");
  268.     while((hFind = FindFirstFile(szTempPath, &pfd)) != (HANDLE)INVALID_HANDLE_VALUE)
  269.     {
  270.         (void)DeleteFile(pfd.cFileName);
  271.         FindClose(hFind);
  272.     }
  273.  
  274.     GetWindowRect( lpRect );
  275.     wsprintf((LPSTR) szBuf, (LPSTR) "%d", lpRect.left);
  276.     WritePrivateProfileString("Location", "Left", (LPSTR) szBuf, "SendMail.ini");
  277.  
  278.     wsprintf((LPSTR) szBuf, (LPSTR) "%d", lpRect.top);
  279.     WritePrivateProfileString("Location", "Top", (LPSTR) szBuf, "SendMail.ini");
  280.  
  281.     wsprintf((LPSTR) szBuf, (LPSTR) "%d", lpRect.right);
  282.     WritePrivateProfileString("Location", "Right", (LPSTR) szBuf, "SendMail.ini");
  283.  
  284.     wsprintf((LPSTR) szBuf, (LPSTR) "%d", lpRect.bottom);
  285.     WritePrivateProfileString("Location", "Bottom", (LPSTR) szBuf, "SendMail.ini");
  286.  
  287.     if(MAPIFreeBuffer( lpRecips ))
  288.         MessageBox( "Recipients not freed", "Stress Mailer", MB_OK );
  289.  
  290.     if(lhSession)
  291.     {
  292.         ulResult = MAPILogoff( lhSession, (ULONG)(void *)m_hWnd, MAPI_LOGOFF_UI, 0 );
  293.         lhSession = 0;
  294.     }
  295.  
  296.     if(hLib)
  297.         FreeLibrary(hLib);
  298.  
  299.     CoUninitialize();
  300.     DeinitSimpleMAPI ();
  301.     DestroyWindow();
  302. }
  303.  
  304.  
  305. /*
  306.  -  CMainWindow::
  307.  -  PostNcDestroy
  308.  *
  309.  *  Purpose:
  310.  *      In order to avoid an access violation when ending this application
  311.  *      it it necessary to catch the WM_DESTROY window message.
  312.  *
  313.  *      Cleanup of the main window will occur in the OnClose function, with
  314.  *      the DestroyWindow() call.
  315.  *
  316.  *      ExitInstance() will perform the remaining cleanup.
  317.  *
  318.  */
  319.  
  320. void CMainWindow::PostNcDestroy()
  321. {
  322.     //don't delete this
  323. }
  324.  
  325.  
  326. /*
  327.  -
  328.  -  CMainWindow::
  329.  -  OnAbout
  330.  -
  331.  -  Purpose:
  332.  -      A CModalDialog object for the About dialog.
  333.  -
  334.  -  Parameters:
  335.  -      None
  336.  -
  337.  -  Returns:
  338.  -      Void
  339.  -
  340.  */
  341.  
  342. void CMainWindow::OnAbout()
  343. {
  344.     CModalDialog about( "AboutBox", this );
  345.     about.DoModal();
  346. }
  347.  
  348.  
  349. /*
  350.  -
  351.  -  CMainWindow::
  352.  -  OnSend
  353.  -
  354.  -  Purpose:
  355.  -      Brings up the Profile Logon dialog.
  356.  -      Sets the logged on flag to true.
  357.  -      Calls the SendMail dialog
  358.  -
  359.  -  Parameters:
  360.  -      None
  361.  -
  362.  -  Returns:
  363.  -      Void
  364.  -
  365.  */
  366.  
  367. void CMainWindow::OnSend()
  368. {
  369.     ULONG       ulResult;
  370.     char        szBuf[128];
  371.  
  372.     if( !fLoggedOn )
  373.     {
  374.         if( (ulResult = MAPILogon( (ULONG)(void *) hWnd, NULL, NULL, MAPI_LOGON_UI | MAPI_NEW_SESSION,
  375.                    0, &lhSession )) != SUCCESS_SUCCESS )
  376.         {
  377.             if( ulResult )
  378.             {
  379.                 wsprintf( szBuf, "%s %lu", "Error: MAPILogon", ulResult );
  380.                 MessageBox( szBuf, "Stress Mailer", MB_OK );
  381.                 return;
  382.             }
  383.         }
  384.     }
  385.  
  386.     fLoggedOn = TRUE;
  387.  
  388.     CSendMailDialog sendmail( this );
  389.     sendmail.DoModal();
  390.  
  391.     return;
  392. }
  393.  
  394.  
  395. /*
  396.  -
  397.  -  CSendMailDialog message loop
  398.  -
  399.  */
  400.  
  401. BEGIN_MESSAGE_MAP( CSendMailDialog, CModalDialog )
  402.     ON_COMMAND( IDOK,        OnOK )
  403.     ON_COMMAND( IDC_ADDRESS, OnAddress )
  404.     ON_COMMAND( IDCANCEL,    OnCancel )
  405.     ON_COMMAND( IDC_STOP,    OnStop )
  406.     ON_COMMAND( IDC_FILE,    OnFile )
  407. END_MESSAGE_MAP()
  408.  
  409.  
  410. /*
  411.  -
  412.  -  CSendMailDialog::
  413.  -  OnInitDialog
  414.  -
  415.  -  Purpose:
  416.  -      Sets some initial dialog settings
  417.  -      Zeros and Nulls the recipient lists
  418.  -
  419.  -  Parameters:
  420.  -      None
  421.  -
  422.  -  Returns:
  423.  -      Void
  424.  -
  425.  */
  426.  
  427. BOOL CSendMailDialog::OnInitDialog()
  428. {
  429.     static char     *rgszSubject[6] = {
  430.                                         "Message from SendMail",
  431.                                         "NULL",
  432.                                         "Empty String (nothing)",
  433.                                         "A single character - A",
  434.                                         "Maximum number of characters",
  435.                                         "Alternate (minimum messages: 5)"
  436.                                         };
  437.  
  438.     static char     *rgszMessageType[] = {
  439.                                             "IPM",
  440.                                             "IPX",
  441.                                             "IPC",
  442.                                             "MCI",
  443.                                             "NULL",
  444.                                             "Empty String (nothing)",
  445.                                             "A single characters - A",
  446.                                             "Maximum number of characters",
  447.                                             "Alternate (minimum messages: 7)"
  448.                                             };
  449.  
  450.     static char     *rgszMessageText[] = {
  451.                                             "Body text",
  452.                                             "NULL",
  453.                                             "Empty String (nothing)",
  454.                                             "A single character - A",
  455.                                             "Maximum number of characters",
  456.                                             "Alternate (minimum messages: 5)"
  457.                                             };
  458.  
  459.     if( !CDialog::OnInitDialog() )
  460.         return (FALSE);
  461.  
  462.     hWaitCur = LoadCursor( NULL, IDC_WAIT );
  463.  
  464.     SetDlgItemInt( IDC_MESSAGES, 5, FALSE );
  465.     SetDlgItemInt( IDC_SECONDS, 0, FALSE );
  466.     CheckRadioButton( IDC_NOATTACHMENT, IDC_LSATTACHMENT, IDC_NOATTACHMENT );
  467.  
  468.     /* Listbox for Subject */
  469.     for( int i=0; i<(sizeof(rgszSubject)/sizeof(char *)); ++i )
  470.         SendDlgItemMessage(IDC_SUBJECT, CB_ADDSTRING, 0, ((LPARAM)(LPSTR)rgszSubject[i]));
  471.     SendDlgItemMessage(IDC_SUBJECT, CB_SETCURSEL, 0, 0L);
  472.  
  473.     /* Listbox for Message Type */
  474.     for( i=0; i<(sizeof(rgszMessageType)/sizeof(char *)); ++i )
  475.         SendDlgItemMessage(IDC_MESSAGETYPE, CB_ADDSTRING, 0, ((LPARAM)(LPSTR)rgszMessageType[i]));
  476.     SendDlgItemMessage(IDC_MESSAGETYPE, CB_SETCURSEL, 0, 0L);
  477.  
  478.     /* Listbox for Message Text */
  479.     for( i=0; i<(sizeof(rgszMessageText)/sizeof(char *)); ++i )
  480.         SendDlgItemMessage(IDC_MESSAGETEXT, CB_ADDSTRING, 0, ((LPARAM)(LPSTR)rgszMessageText[i]));
  481.     SendDlgItemMessage(IDC_MESSAGETEXT, CB_SETCURSEL, 0, 0L);
  482.  
  483.     SendDlgItemMessage(IDC_STATUS, LB_SETHORIZONTALEXTENT,
  484.                        (WPARAM)2000, 0);
  485.  
  486.     lpRecips = NULL;
  487.     cRecips = 0;
  488.  
  489.     return (TRUE);
  490. }
  491.  
  492.  
  493. /*
  494.  -
  495.  -  CSendMailDialog::
  496.  -  OnStop
  497.  -
  498.  -  Purpose:
  499.  -      Kills the thread that is doing the sending.
  500.  -
  501.  -  Parameters:
  502.  -      None
  503.  -
  504.  -  Returns:
  505.  -      Void
  506.  -
  507.  */
  508.  
  509. void CSendMailDialog::OnStop()
  510. {
  511.     fKillThread = TRUE;
  512. }
  513.  
  514.  
  515. /*
  516.  -
  517.  -  CSendMailDialog::
  518.  -  OnFile
  519.  -
  520.  -  Purpose:
  521.  -      Bring up command dialog to select a specific attachment for the
  522.  -      sendnote.
  523.  -
  524.  -  Parameters:
  525.  -      None
  526.  -
  527.  -  Returns:
  528.  -      void
  529.  -
  530.  */
  531.  
  532. void CSendMailDialog::OnFile()
  533. {
  534.     static char szFileTitle[16];
  535.     static char szDirName[256] = "";
  536.     static char * szFilter = "All Files (*.*)\0""*.*\0""\0";
  537.  
  538.     if (!szDirName[0])
  539.         GetSystemDirectory ((LPSTR) szDirName, 255);
  540.     else
  541.         lstrcpy (szFileName, szFileTitle);
  542.  
  543.     ofn.lStructSize = sizeof (OPENFILENAME);
  544.     ofn.hwndOwner = 0;
  545.     ofn.hInstance = 0;
  546.     ofn.lpstrFilter = (LPSTR) szFilter;
  547.     ofn.lpstrCustomFilter = NULL;
  548.     ofn.nMaxCustFilter = 0L;
  549.     ofn.nFilterIndex = 1L;
  550.     ofn.lpstrFile = szFileName;
  551.     ofn.nMaxFile = 256;
  552.     ofn.lpstrFileTitle = szFileTitle;
  553.     ofn.nMaxFileTitle = 16;
  554.     ofn.lpstrInitialDir = szDirName;
  555.     ofn.lpstrTitle = "Attach";
  556.     ofn.nFileOffset = 0;
  557.     ofn.nFileExtension = 0;
  558.     ofn.lpstrDefExt = NULL;
  559.     ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  560.  
  561.     if(GetOpenFileName (&ofn))
  562.         fCustomAttachment = TRUE;
  563. }
  564.  
  565.  
  566. /*
  567.  -
  568.  -  CSendMailDialog::
  569.  -  OnOK
  570.  -
  571.  -  Purpose:
  572.  -      Gets the number of messages, subject, timing delay, and
  573.  -          recipients from the SendMail dialog
  574.  -      Creates a Simple MAPI message data structure
  575.  -      Calls MAPISendMail x times
  576.  -      Logs the start, status, and end of the test
  577.  -
  578.  -  Parameters:
  579.  -      None
  580.  -
  581.  -  Returns:
  582.  -      Void
  583.  -
  584.  */
  585.  
  586. void CSendMailDialog::OnOK()
  587. {
  588.     ULONG           ulAttach = 0;
  589.     HCURSOR         hOldCur;
  590.     LPTHREADDATA    lptd;
  591.     ULONG           ulItem = 0;
  592.     BOOL            fMultipleAttachments = FALSE;
  593.     int             i = 0;
  594.     ULONG           len = 0;
  595.     ULONG           idx = 0;
  596.     LONG            cb = 0;
  597.     OFSTRUCT        lpOpenBuff1;
  598.     OFSTRUCT        lpOpenBuff2;
  599.     HFILE           hFile1;
  600.     HFILE           hFile2;
  601.     char *          pszFileName1;
  602.     char *          pszFileName2;
  603.     WIN32_FIND_DATA pfd;
  604.     HANDLE          hFind;
  605.     char            szTempPath[256];
  606.  
  607. #ifdef WIN32
  608.     HANDLE          hThrd;
  609. #else
  610.     CHiddenDialog   *pHiddenDialog = NULL;
  611. #endif
  612.  
  613.     hOldCur = SetCursor(hWaitCur);
  614.     GetTempPath(256,szTempPath);
  615.  
  616. #ifdef WIN32
  617.     SetCurrentDirectory(szTempPath);
  618. #else
  619.     _chdir(szTempPath);
  620. #endif
  621.  
  622.     if( lpRecips == NULL )
  623.     {
  624.         MessageBox( "No recipients have been selected", "Stress Mailer", MB_OK );
  625.         return;
  626.     }
  627.  
  628.     lptd = (LPTHREADDATA)PvAlloc(sizeof(THREADDATA));
  629.  
  630.     if(!lptd)
  631.     {
  632.         MessageBox("Error: PvAlloc failed to allocate lptd.", "Stress Mailer", MB_OK );
  633.         goto free;
  634.     }
  635.  
  636.     lptd->fSubjectAlt = FALSE;
  637.     lptd->fMessageTypeAlt = FALSE;
  638.     lptd->fNoteTextAlt = FALSE;
  639.  
  640.     //  Number of messages
  641.     lptd->cMessages = GetDlgItemInt( IDC_MESSAGES, NULL, FALSE );
  642.  
  643.     //  Time delay between messages
  644.     lptd->nSeconds = GetDlgItemInt( IDC_SECONDS, NULL, FALSE );
  645.  
  646.     //  Determine whether or not to mail everybody at 1 time
  647.     lptd->fSendToAll = IsDlgButtonChecked( IDC_GROUPSEND );
  648.     lptd->lpRecips = lpRecips;
  649.     lptd->cRecips  = cRecips;
  650.  
  651.     lptd->lpmsg = (MapiMessage FAR *)PvAlloc(sizeof(MapiMessage));
  652.  
  653.     if(!lptd->lpmsg)
  654.     {
  655.         MessageBox("Error: PvAlloc failed to allocate lpmsg.", "Stress Mailer", MB_OK );
  656.         goto free;
  657.     }
  658.  
  659.     memset( lptd->lpmsg, 0, sizeof( MapiMessage ) );
  660.  
  661.     lptd->hWnd = m_hWnd;
  662.  
  663.     //  Get subject
  664.     //  The list box strings describe the subject, they do not give the literal
  665.     //  contents for the subject
  666.     ulItem = SendDlgItemMessage( IDC_SUBJECT, CB_GETCURSEL, 0, 0L );
  667.     switch( ulItem )
  668.     {
  669.         case 0 : lptd->lpmsg->lpszSubject = (LPSTR) PvAlloc(sizeof("Message from SendMail")+10);
  670.                  lstrcpy(lptd->lpmsg->lpszSubject, "Message from SendMail");
  671.                  break;
  672.  
  673.         case 1 : PvFree(lptd->lpmsg->lpszSubject);
  674.                  lptd->lpmsg->lpszSubject = NULL;
  675.                  break;
  676.  
  677.         case 2 : lstrcpy(lptd->lpmsg->lpszSubject, "");
  678.                  break;
  679.  
  680.         case 3 : lptd->lpmsg->lpszSubject = (LPSTR) PvAlloc(sizeof("A"));
  681.                  lstrcpy(lptd->lpmsg->lpszSubject, "A");
  682.                  break;
  683.  
  684.         case 4 : lptd->lpmsg->lpszSubject = (LPSTR)PvAlloc(256);
  685.                  lstrcpy(lptd->lpmsg->lpszSubject,szMax);
  686.                  _fmemset(lptd->lpmsg->lpszSubject+strlen(szMax), 99, 256-strlen(szMax));
  687.                  lptd->lpmsg->lpszSubject[255] = '\0';
  688.                  break;
  689.  
  690.         case 5 : //Will cycle through all subjects in rgszSubject
  691.                  lptd->fSubjectAlt = TRUE;
  692.                  lptd->lpmsg->lpszSubject = (LPSTR)PvAlloc(256);
  693.                  break;
  694.  
  695.         default : lptd->lpmsg->lpszSubject = (LPSTR)PvAlloc(255);
  696.                   GetDlgItemText( IDC_SUBJECT, lptd->lpmsg->lpszSubject, 255 );
  697.     }
  698.  
  699.     //  Get message type
  700.     ulItem = SendDlgItemMessage( IDC_MESSAGETYPE, CB_GETCURSEL, 0, 0L );
  701.     switch( ulItem )
  702.     {
  703.         case 0 : lptd->lpmsg->lpszMessageType = (LPSTR) PvAlloc(4);
  704.                  lstrcpy(lptd->lpmsg->lpszMessageType, "IPM");
  705.                  break;
  706.  
  707.         case 1 : lptd->lpmsg->lpszMessageType = (LPSTR) PvAlloc(4);
  708.                  lstrcpy(lptd->lpmsg->lpszMessageType, "IPX");
  709.                  break;
  710.  
  711.         case 2 : lptd->lpmsg->lpszMessageType = (LPSTR) PvAlloc(4);
  712.                  lstrcpy(lptd->lpmsg->lpszMessageType, "IPC");
  713.                  break;
  714.  
  715.         case 3 : lptd->lpmsg->lpszMessageType = (LPSTR) PvAlloc(4);
  716.                  lstrcpy(lptd->lpmsg->lpszMessageType, "MCI");
  717.                  break;
  718.  
  719.         case 4 : PvFree(lptd->lpmsg->lpszMessageType);
  720.                  lptd->lpmsg->lpszMessageType = NULL;
  721.                  break;
  722.  
  723.         case 5 : lstrcpy(lptd->lpmsg->lpszMessageType, "");
  724.                  break;
  725.  
  726.         case 6 : lptd->lpmsg->lpszMessageType = (LPSTR)PvAlloc(256);
  727.                  lstrcpy(lptd->lpmsg->lpszMessageType,szMax);
  728.                  _fmemset(lptd->lpmsg->lpszMessageType+strlen(szMax), 99, 256-strlen(szMax));
  729.                  lptd->lpmsg->lpszMessageType[255] = '\0';
  730.                  break;
  731.  
  732.         case 7 : //Will cycle through all message types in rgszMessageType
  733.                  lptd->fMessageTypeAlt = TRUE;
  734.                  lptd->lpmsg->lpszMessageType = (LPSTR)PvAlloc(256);
  735.                  break;
  736.  
  737.         default : lptd->lpmsg->lpszMessageType = (LPSTR)PvAlloc(255);
  738.                   GetDlgItemText( IDC_MESSAGETYPE, lptd->lpmsg->lpszMessageType, 255 );
  739.     }
  740.  
  741.     //  Get message text
  742.     ulItem = SendDlgItemMessage( IDC_MESSAGETEXT, CB_GETCURSEL, 0, 0L );
  743.     switch( ulItem )
  744.     {
  745.         case 0 : lptd->lpmsg->lpszNoteText = (LPSTR) PvAlloc(sizeof("Body text"));
  746.                  lstrcpy(lptd->lpmsg->lpszNoteText, "Body text");
  747.                  break;
  748.  
  749.         case 1 : PvFree(lptd->lpmsg->lpszNoteText);
  750.                  lptd->lpmsg->lpszNoteText = NULL;
  751.                  break;
  752.  
  753.         case 2 : lstrcpy(lptd->lpmsg->lpszNoteText, "");
  754.                  break;
  755.  
  756.         case 3 : lstrcpy(lptd->lpmsg->lpszNoteText, "A");
  757.                  break;
  758.  
  759.         case 4 : lptd->lpmsg->lpszNoteText = (LPSTR)PvAlloc(65000);
  760.                  lstrcpy(lptd->lpmsg->lpszNoteText,szMax);
  761.                  _fmemset(lptd->lpmsg->lpszNoteText+strlen(szMax), 99, size_t(65000-strlen(szMax)));
  762.                  lptd->lpmsg->lpszNoteText[64999] = '\0';
  763.                  break;
  764.  
  765.         case 5 : //Will cycle through all message texts in rgszMessageText
  766.                  lptd->fNoteTextAlt = TRUE;
  767.                  lptd->lpmsg->lpszNoteText = (LPSTR)PvAlloc(65000);
  768.                  break;
  769.  
  770.         default : lptd->lpmsg->lpszNoteText = (LPSTR)PvAlloc(255);
  771.                   GetDlgItemText( IDC_MESSAGETEXT, lptd->lpmsg->lpszNoteText, 255 );
  772.     }
  773.  
  774.     //  Check to see if multiple attachments are requested
  775.     fMultipleAttachments = IsDlgButtonChecked( IDC_MULTIPLE );
  776.  
  777.     //  Find out what type of attachment is requested
  778.     ulAttach = GetCheckedRadioButton( IDC_NOATTACHMENT, IDC_LSATTACHMENT );
  779.  
  780.     //  Count the number of attachments
  781.     lptd->lpmsg->nFileCount = 0;
  782.     if( (ulAttach != IDC_NOATTACHMENT) || fCustomAttachment )
  783.     {
  784.         if( (ulAttach == IDC_SATTACHMENT) ||
  785.             (ulAttach == IDC_LATTACHMENT) ||
  786.             (ulAttach == IDC_HATTACHMENT) )
  787.             ++lptd->lpmsg->nFileCount;
  788.  
  789.         if( ulAttach == IDC_LSATTACHMENT )
  790.             lptd->lpmsg->nFileCount = 2;
  791.  
  792.         if( fMultipleAttachments )
  793.             lptd->lpmsg->nFileCount *= 5;
  794.  
  795.         if( fCustomAttachment )
  796.             ++lptd->lpmsg->nFileCount;
  797.  
  798.         lptd->lpmsg->lpFiles = (MapiFileDesc FAR *)PvAlloc(lptd->lpmsg->nFileCount*sizeof(MapiFileDesc));
  799.         if(!lptd->lpmsg->lpFiles)
  800.         {
  801.             MessageBox("Error: PvAlloc failed to allocate lpFiles", "Stress Mailer", MB_OK );
  802.             return;
  803.         }
  804.  
  805.         if( fCustomAttachment && (lptd->lpmsg->nFileCount == 1) )
  806.             goto Custom;
  807.  
  808.         //  Create attachments
  809.         pszFileName1 = (LPSTR)PvAlloc(256);
  810.         lstrcpy(pszFileName1, "file1.XXX");
  811.         if( (hFile1 = OpenFile(pszFileName1, &lpOpenBuff1, OF_CREATE | OF_READWRITE)) == HFILE_ERROR )
  812.         {
  813.             MessageBox("Error: Could not create data file", "Stress Mailer", MB_OK );
  814.             goto free;
  815.         }
  816.  
  817.         switch( ulAttach )
  818.         {
  819.             case IDC_SATTACHMENT : FillFile( SMALL_ATTACHMENT_SIZE, hFile1 );
  820.                                    rename(pszFileName1, "SMALL.XXX");
  821.                                    lstrcpy(pszFileName1, "SMALL.XXX");
  822.                                    break;
  823.  
  824.             case IDC_LATTACHMENT : FillFile( LARGE_ATTACHMENT_SIZE, hFile1 );
  825.                                    rename(pszFileName1, "LARGE.XXX");
  826.                                    lstrcpy(pszFileName1, "LARGE.XXX");
  827.                                    break;
  828.  
  829.             case IDC_HATTACHMENT : FillFile( HUGE_ATTACHMENT_SIZE, hFile1 );
  830.                                    rename(pszFileName1, "HUGE.XXX");
  831.                                    lstrcpy(pszFileName1, "HUGE.XXX");
  832.                                    break;
  833.  
  834.             case IDC_LSATTACHMENT : pszFileName2 = (LPSTR)PvAlloc(256);
  835.                                     lstrcpy(pszFileName2, "file2.XXX");
  836.                                     if( (hFile2 = OpenFile(pszFileName2, &lpOpenBuff2, OF_CREATE | OF_READWRITE )) == HFILE_ERROR )
  837.                                     {
  838.                                         MessageBox("Error: Could not create data file", "Stress Mailer", MB_OK );
  839.                                         goto free;
  840.                                     }
  841.                                     FillFile( SMALL_ATTACHMENT_SIZE, hFile1 );
  842.                                     rename(pszFileName1, "SMALL.XXX");
  843.                                     lstrcpy( pszFileName1, "SMALL.XXX");
  844.                                     FillFile( LARGE_ATTACHMENT_SIZE, hFile2 );
  845.                                     rename(pszFileName2, "LARGE.XXX");
  846.                                     lstrcpy( pszFileName2, "LARGE.XXX");
  847.                                     break;
  848.         }  // Case
  849.  
  850.         if( fCustomAttachment )
  851.             idx = lptd->lpmsg->nFileCount-1;
  852.         else
  853.             idx = lptd->lpmsg->nFileCount;
  854.  
  855.         for( i=0; i<idx; ++i )
  856.         {
  857.             lptd->lpmsg->lpFiles[i].ulReserved = 0;
  858.             lptd->lpmsg->lpFiles[i].flFlags = 0;
  859.             lptd->lpmsg->lpFiles[i].nPosition = (ULONG) -1;
  860.             if( (ulAttach==IDC_LSATTACHMENT) && (i%2==0) )
  861.             {
  862.                 lptd->lpmsg->lpFiles[i].lpszPathName = pszFileName2;
  863.                 lptd->lpmsg->lpFiles[i].lpszFileName = pszFileName2;
  864.             }
  865.             else
  866.             {
  867.                 lptd->lpmsg->lpFiles[i].lpszPathName = pszFileName1;
  868.                 lptd->lpmsg->lpFiles[i].lpszFileName = pszFileName1;
  869.             }
  870.             lptd->lpmsg->lpFiles[i].lpFileType = NULL;
  871.         }
  872.  
  873.     Custom:
  874.         if( fCustomAttachment )
  875.         {
  876.             lptd->lpmsg->lpFiles[i].lpszPathName = (LPSTR)PvAlloc(256);
  877.             lptd->lpmsg->lpFiles[i].ulReserved = 0;
  878.             lptd->lpmsg->lpFiles[i].flFlags = 0;
  879.             lptd->lpmsg->lpFiles[i].nPosition = (ULONG) -1;
  880.             memcpy(lptd->lpmsg->lpFiles[i].lpszPathName, ofn.lpstrFile, 256);
  881.             lptd->lpmsg->lpFiles[i].lpszFileName = lptd->lpmsg->lpFiles[i].lpszPathName;
  882.             lptd->lpmsg->lpFiles[i].lpFileType = NULL;
  883.         }
  884.     }
  885.  
  886.     /* (LPTHREAD_START_ROUTINE) */
  887. #ifdef WIN32
  888.     hThrd = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)DoSend, lptd,
  889.                 0, &lptd->dwThreadId );
  890.     if( hThrd )
  891. #else
  892.     pHiddenDialog = new CHiddenDialog(lptd);
  893.     if(pHiddenDialog)
  894. #endif
  895.  
  896.     {
  897.         GetDlgItem(IDOK)->EnableWindow( FALSE );
  898.         GetDlgItem(IDC_ADDRESS)->EnableWindow( FALSE );
  899.         return;
  900.     }
  901.     else
  902.         MessageBox( "Cannot create thread", "Stress Mailer", MB_OK );
  903.  
  904. free:
  905.         PvFree( lptd->lpmsg->lpszNoteText );
  906.         PvFree( lptd->lpmsg->lpszMessageType );
  907.         PvFree( lptd->lpmsg->lpszSubject );
  908.         PvFree( lptd->lpmsg->lpFiles );
  909.         PvFree( lptd->lpmsg );
  910.         PvFree( lptd );
  911.  
  912.         while((hFind = FindFirstFile(szTempPath, &pfd)) != (HANDLE)INVALID_HANDLE_VALUE)
  913.         {
  914.             (void)DeleteFile(pfd.cFileName);
  915.             FindClose(hFind);
  916.         }
  917.  
  918. #ifdef WIN16
  919.         delete pHiddenDialog;
  920. #endif
  921.  
  922.         PvFree(pszFileName1);
  923.         PvFree(pszFileName2);
  924. }
  925.  
  926.  
  927. /*
  928.  -
  929.  -  CSendMailDialog::
  930.  -  OnAddress
  931.  -
  932.  -  Purpose:
  933.  -      Call MAPIAddress to allow the user to select the recipients.
  934.  -      Creates a buffer that contains all recipients to be displayed
  935.  -          in the SendMail dialog.
  936.  -
  937.  -  Parameters:
  938.  -      None
  939.  -
  940.  -  Returns:
  941.  -      Void
  942.  -
  943.  */
  944.  
  945. void CSendMailDialog::OnAddress()
  946. {
  947.     char            szDisplayName[255];
  948.     ULONG           ulResult;
  949.     static ULONG    ulTestNumber;
  950.     HCURSOR         hOldCur;
  951.     char            szBuf[128];
  952.  
  953.     hOldCur = SetCursor(hWaitCur);
  954.  
  955.     lpNewRecips = NULL;
  956.     cNewRecips = 0;
  957.  
  958.     ulResult = MAPIAddress( lhSession, (ULONG)(void *) this->m_hWnd, "Address Book", 1,
  959.         "&To:", cRecips, lpRecips, 0, 0, &cNewRecips, &lpNewRecips);
  960.  
  961.     if( ulResult )
  962.     {
  963.         if( ulResult != MAPI_E_USER_ABORT )
  964.         {
  965.             wsprintf( szBuf, "%s %lu", "Error: MAPIAddress", ulResult );
  966.             MessageBox( szBuf, "Stress Mailer", MB_OK );
  967.             return;
  968.         }
  969.     }
  970.     else
  971.         if( cNewRecips )
  972.         {
  973.             MAPIFreeBuffer( lpRecips );
  974.             lpRecips = lpNewRecips;
  975.             cRecips = cNewRecips;
  976.             lpNewRecips =  NULL;
  977.             cNewRecips = 0;
  978.         }
  979.         else
  980.         {
  981.             this->SetDlgItemText( IDC_RECIPIENTS, '\0' );
  982.             return;
  983.         }
  984.  
  985.     szDisplayName[0] = '\0';
  986.  
  987.     for( int idx=0; idx<cRecips; idx++ )
  988.     {
  989.         if( lpRecips[idx].ulRecipClass == MAPI_TO )
  990.         {
  991.             if(strlen(szDisplayName+strlen(lpRecips[idx].lpszName)+2)>255)
  992.                 break;
  993.             lstrcat( szDisplayName, lpRecips[idx].lpszName );
  994.             lstrcat( szDisplayName, "; " );
  995.         }
  996.     }
  997.  
  998.     if( *szDisplayName )
  999.     {
  1000.         szDisplayName[lstrlen(szDisplayName)-2] = '\0';
  1001.         this->SetDlgItemText( IDC_RECIPIENTS, szDisplayName );
  1002.     }
  1003.  
  1004.     return;
  1005. }
  1006.  
  1007.  
  1008. /*
  1009.  -
  1010.  -  CSendMailDialog::
  1011.  -  OnCancel
  1012.  -
  1013.  -  Purpose:
  1014.  -      Frees the recipient structure, and zeros and NULLs it out
  1015.  -
  1016.  -  Parameters:
  1017.  -      None
  1018.  -
  1019.  -  Returns:
  1020.  -      Void
  1021.  -
  1022.  */
  1023.  
  1024. void CSendMailDialog::OnCancel()
  1025. {
  1026.     MAPIFreeBuffer( lpRecips );
  1027.     lpRecips = NULL;
  1028.     cRecips = 0;
  1029.  
  1030.     EndDialog(IDOK);
  1031. }
  1032.  
  1033.  
  1034. #ifdef WIN16
  1035. //  The HiddenDialog is used in 16bit to simulate multiple threads.
  1036. /*
  1037.  -
  1038.  -  CHiddenDialog::
  1039.  -  OnInitDialog
  1040.  -
  1041.  -  Purpose:
  1042.  -
  1043.  -  Parameters:
  1044.  -      None
  1045.  -
  1046.  -  Returns:
  1047.  -      Void
  1048.  -
  1049.  */
  1050.  
  1051. BOOL CHiddenDialog::OnInitDialog()
  1052. {
  1053.     DoSend(lptd2);
  1054.     EndDialog(TRUE);
  1055.     return TRUE;
  1056. }
  1057.  
  1058.  
  1059. /*
  1060.  -  CHiddenDialog
  1061.  -  OnCancel
  1062.  -
  1063.  *  Purpose:
  1064.  *      Cancels the CHiddenDialog dialog
  1065.  *
  1066.  */
  1067.  
  1068. void CHiddenDialog::OnCancel()
  1069. {
  1070.     delete this;
  1071. }
  1072. #endif
  1073.  
  1074.  
  1075. /*
  1076.  -  DoSend
  1077.  -
  1078.  *  Purpose:
  1079.  *      Sends the message and updates the status listbox
  1080.  *
  1081.  */
  1082.  
  1083. long DoSend( LPTHREADDATA lptd )
  1084. {
  1085.     int             iMessage, jRecipient, idx;
  1086.     ULONG           cSend = 0;
  1087.     ULONG           ulResult;
  1088.     int             cRun = 0;
  1089.     int             cFailed = 0;
  1090.     char            szBufS[256];
  1091.     char            szResult[256];
  1092.     char            szBuffer[256];
  1093.     char            szSubject[256];
  1094.     LPSTR           lpszTemp1, lpszTemp2, lpszTemp3;
  1095.     int             nCount = 0;
  1096.  
  1097.     SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_RESETCONTENT, 0, 0 );
  1098.  
  1099.     if( lptd->fSendToAll )
  1100.     {
  1101.         lptd->lpmsg->nRecipCount = lptd->cRecips;
  1102.         cSend = 1;
  1103.     }
  1104.     else
  1105.     {
  1106.         lptd->lpmsg->nRecipCount = 1;
  1107.         cSend = lptd->cRecips;
  1108.     }
  1109.  
  1110.     lstrcpy(szBuffer, "Tests beginning...");
  1111.     SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_ADDSTRING, 0, (LPARAM)szBuffer );
  1112.  
  1113.     lstrcpy(szSubject, lptd->lpmsg->lpszSubject);
  1114.     for( jRecipient=1; jRecipient <= lptd->cMessages; ++jRecipient )
  1115.     {
  1116.         idx = jRecipient-1;
  1117.         // Set up subject field if alternating was selected
  1118.         if( lptd->fSubjectAlt )
  1119.         {
  1120.             switch( idx%5 )
  1121.             {
  1122.                 case 0: lstrcpy(lptd->lpmsg->lpszSubject, "Message from SendMail");
  1123.                         break;
  1124.                 case 1: lpszTemp1 = lptd->lpmsg->lpszSubject;
  1125.                         lptd->lpmsg->lpszSubject = NULL;
  1126.                         break;
  1127.                 case 2: lptd->lpmsg->lpszSubject = lpszTemp1;
  1128.                         lstrcpy(lptd->lpmsg->lpszSubject, "");
  1129.                         break;
  1130.                 case 3: lstrcpy(lptd->lpmsg->lpszSubject, "A");
  1131.                         break;
  1132.                 case 4: lstrcpy(lptd->lpmsg->lpszSubject,szMax);
  1133.                         _fmemset(lptd->lpmsg->lpszSubject+strlen(szMax), 99, 256-strlen(szMax));
  1134.                         lptd->lpmsg->lpszSubject[255] = '\0';
  1135.                         break;
  1136.             } //switch
  1137.         } //if
  1138.         else
  1139.             wsprintf(lptd->lpmsg->lpszSubject,"%s - %d", szSubject, jRecipient);
  1140.  
  1141.         // Set up message type field if alternating was selected
  1142.         if( lptd->fMessageTypeAlt )
  1143.         {
  1144.             switch( jRecipient%7 )
  1145.             {
  1146.                 case 0: lstrcpy(lptd->lpmsg->lpszMessageType, "IPM");
  1147.                         break;
  1148.                 case 1: lstrcpy(lptd->lpmsg->lpszMessageType, "IPX");
  1149.                         break;
  1150.                 case 2: lstrcpy(lptd->lpmsg->lpszMessageType, "IPC");
  1151.                         break;
  1152.                 case 3: lstrcpy(lptd->lpmsg->lpszMessageType, "MCI");
  1153.                         break;
  1154.                 case 4: lpszTemp2 = lptd->lpmsg->lpszMessageType;
  1155.                         lptd->lpmsg->lpszMessageType = NULL;
  1156.                         break;
  1157.                 case 5: lptd->lpmsg->lpszMessageType = lpszTemp2;
  1158.                         lstrcpy(lptd->lpmsg->lpszMessageType, "");
  1159.                         break;
  1160.                 case 6: lstrcpy(lptd->lpmsg->lpszMessageType,szMax);
  1161.                         _fmemset(lptd->lpmsg->lpszMessageType+strlen(szMax), 99, 256-strlen(szMax));
  1162.                         lptd->lpmsg->lpszMessageType[255] = '\0';
  1163.                         break;
  1164.             } //switch
  1165.         } //if
  1166.  
  1167.         // Set up note text field if alternating was selected
  1168.         if( lptd->fNoteTextAlt )
  1169.         {
  1170.             switch( jRecipient%5 )
  1171.             {
  1172.                 case 0: lstrcpy(lptd->lpmsg->lpszNoteText, "Body text");
  1173.                         break;
  1174.                 case 1: lpszTemp3 = lptd->lpmsg->lpszNoteText;
  1175.                         lptd->lpmsg->lpszNoteText = NULL;
  1176.                         break;
  1177.                 case 2: lptd->lpmsg->lpszNoteText = lpszTemp3;
  1178.                         lstrcpy(lptd->lpmsg->lpszNoteText, "");
  1179.                         break;
  1180.                 case 3: lstrcpy(lptd->lpmsg->lpszNoteText, "A");
  1181.                         break;
  1182.                 case 4: lstrcpy(lptd->lpmsg->lpszNoteText,szMax);
  1183.                         _fmemset(lptd->lpmsg->lpszNoteText+strlen(szMax), 99, size_t(65000-strlen(szMax)));
  1184.                         lptd->lpmsg->lpszNoteText[64999] = '\0';
  1185.                         break;
  1186.             } //switch
  1187.         } //if
  1188.  
  1189.         for( iMessage=1; iMessage<=cSend; ++iMessage )
  1190.         {
  1191.             lptd->lpmsg->lpRecips = &lptd->lpRecips[iMessage-1];
  1192.             ulResult = MAPISendMail( lhSession, (ULONG)(void *) lptd->hWnd, lptd->lpmsg, 0, 0);
  1193.             wsprintf( szBufS, "Message: %d of %d, Recipient %d of %d ", jRecipient, lptd->cMessages, iMessage, cSend );
  1194.             SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_ADDSTRING, 0, (LPARAM) szBufS );
  1195.             nCount = (WORD) SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_GETCOUNT, 0, (LPARAM) 0L);
  1196.             SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_SETCURSEL, nCount-1, (LPARAM) 0L );
  1197.             if( ulResult )
  1198.             {
  1199.                 //  This builds a string from the ulResult
  1200.                 if(!GetString( "MAPIErrors", ulResult, szResult ))
  1201.                 {
  1202.                     lstrcpy(  szResult, "??" );
  1203.                     wsprintf( szBuffer, " %04X", ulResult );
  1204.                     lstrcat(  szResult, szBuffer );
  1205.                 }
  1206.  
  1207.                 wsprintf( szBufS, "ERROR: MAPISendMail returned: %s", szResult );
  1208.                 SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_ADDSTRING, 0, (LPARAM) szBufS );
  1209.                 ++cFailed;
  1210.             }
  1211.             if( fKillThread )
  1212.             {
  1213.                 lstrcpy(szBuffer,"User canceled test.");
  1214.                 SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_ADDSTRING, 0, (LPARAM)szBuffer );
  1215.                 goto KillThread;
  1216.             }
  1217.             //  Sleep requires an interval in milliseconds
  1218.             Sleep( lptd->nSeconds * 1000);
  1219.             if( fKillThread )
  1220.             {
  1221.                 lstrcpy(szBuffer,"User canceled test.");
  1222.                 SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_ADDSTRING, 0, (LPARAM)szBuffer );
  1223.                 goto KillThread;
  1224.             }
  1225.         }
  1226.     }
  1227.  
  1228.     jRecipient--;
  1229.     iMessage--;
  1230.  
  1231. KillThread:
  1232.     cRun = jRecipient*iMessage;
  1233.     wsprintf( szBufS, "Test(s) completed, Succeeded: %d  Failed: %d ", cRun-cFailed, cFailed );
  1234.     SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_ADDSTRING, 0, (LPARAM) szBufS );
  1235.     nCount = (WORD) SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_GETCOUNT, 0, (LPARAM) 0L);
  1236.     SendDlgItemMessage( lptd->hWnd, IDC_STATUS, LB_SETCURSEL, nCount-1, (LPARAM) 0L );
  1237.  
  1238.     EnableWindow( GetDlgItem(lptd->hWnd, IDOK), TRUE );
  1239.     EnableWindow( GetDlgItem(lptd->hWnd, IDC_ADDRESS), TRUE );
  1240.  
  1241.     PvFree( lptd->lpmsg->lpszNoteText );
  1242.     PvFree( lptd->lpmsg->lpszMessageType );
  1243.     PvFree( lptd->lpmsg->lpszSubject );
  1244.     for(iMessage=0; iMessage<lptd->lpmsg->nFileCount; ++iMessage)
  1245.         PvFree(lptd->lpmsg->lpFiles[iMessage].lpszPathName);
  1246.     PvFree( lptd->lpmsg->lpFiles );
  1247.  
  1248.  
  1249.     PvFree( lptd->lpmsg );
  1250.     PvFree( lptd );
  1251.  
  1252.     fKillThread = FALSE;
  1253.  
  1254. #ifdef WIN32
  1255.     ExitThread( 0 );
  1256. #endif
  1257.  
  1258.     return(0L);
  1259. }
  1260.  
  1261.  
  1262. void FillFile( ULONG ulsize, HFILE hFile )
  1263. {
  1264.     ULONG       i = 0;
  1265.     char        szBuffer[100];
  1266.     int         j = 33;
  1267.  
  1268.     for(i=0; i<ulsize; i+=100)
  1269.     {
  1270.         if(j == 256)
  1271.             j = 33;
  1272.         _fmemset(szBuffer, j, 100);
  1273.         _lwrite(hFile, szBuffer, 100);
  1274.         ++j;
  1275.     }
  1276.     _lclose(hFile);
  1277. }
  1278.