Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1073 lines
25 KiB

  1. #include <windows.h>
  2. #include <commctrl.h>
  3. #include <winspool.h>
  4. #include <shellapi.h>
  5. #include <shlapip.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <mapi.h>
  9. #include "faxutil.h"
  10. #include "winfax.h"
  11. #include "resource.h"
  12. typedef struct _RECIPIENT {
  13. WCHAR Name[256];
  14. WCHAR Address[256];
  15. DWORD NameLen;
  16. DWORD AddressLen;
  17. DWORD MultiAddrCnt;
  18. } RECIPIENT, *PRECIPIENT;
  19. typedef struct _DOCUMENT {
  20. WCHAR Name[256];
  21. LPSTR Text;
  22. DWORD TextSize;
  23. } DOCUMENT, *PDOCUMENT;
  24. LPWSTR FaxPrinterName;
  25. int x;
  26. int y;
  27. LPMAPILOGON pMAPILogon;
  28. LPMAPISENDMAIL pMAPISendMail;
  29. LPMAPILOGOFF pMAPILogoff;
  30. RECIPIENT Recipients[100];
  31. DOCUMENT Documents[100];
  32. HANDLE ExchangeEvent;
  33. BOOL UseExchange;
  34. DWORD DocCount;
  35. DWORD RecipCount;
  36. BOOL NoGuiMode = TRUE;
  37. DWORD Copies = 1;
  38. BOOL DontResetOnExit;
  39. #define LEFT_MARGIN 1 // ---|
  40. #define RIGHT_MARGIN 1 // |
  41. #define TOP_MARGIN 1 // |---> in inches
  42. #define BOTTOM_MARGIN 1 // ---|
  43. #define InchesToCM(_x) (((_x) * 254L + 50) / 100)
  44. #define CMToInches(_x) (((_x) * 100L + 127) / 254)
  45. int
  46. PopUpMsg(
  47. LPWSTR Format,
  48. ...
  49. )
  50. {
  51. WCHAR buf[1024];
  52. va_list arg_ptr;
  53. va_start( arg_ptr, Format );
  54. _vsnwprintf( buf, sizeof(buf), Format, arg_ptr );
  55. va_end(arg_ptr);
  56. return MessageBox(
  57. NULL,
  58. buf,
  59. L"Fax Stress Error",
  60. MB_SETFOREGROUND | MB_ICONEXCLAMATION | MB_OK
  61. );
  62. }
  63. BOOL
  64. SetPrinterDataStr(
  65. HANDLE hPrinter,
  66. LPWSTR pRegKey,
  67. LPWSTR pValue,
  68. DWORD Length
  69. )
  70. {
  71. if (SetPrinterData(hPrinter,
  72. pRegKey,
  73. REG_MULTI_SZ,
  74. (PBYTE) pValue,
  75. Length) != ERROR_SUCCESS)
  76. {
  77. DebugPrint((L"Couldn't save registry key %ws: %d\n", pRegKey, GetLastError()));
  78. return FALSE;
  79. }
  80. return TRUE;
  81. }
  82. BOOL
  83. SetPrinterDataDWord(
  84. HANDLE hPrinter,
  85. PWSTR pRegKey,
  86. DWORD value
  87. )
  88. {
  89. if (SetPrinterData(hPrinter,
  90. pRegKey,
  91. REG_DWORD,
  92. (PBYTE) &value,
  93. sizeof(value)) != ERROR_SUCCESS)
  94. {
  95. DebugPrint((L"Couldn't save registry key %ws: %d\n", pRegKey, GetLastError()));
  96. return FALSE;
  97. }
  98. return TRUE;
  99. }
  100. LPWSTR
  101. GetPrinterDataStr(
  102. HANDLE hPrinter,
  103. LPWSTR pRegKey
  104. )
  105. {
  106. DWORD type, cb;
  107. PVOID pBuffer = NULL;
  108. //
  109. // We should really pass NULL for pData parameter here. But to workaround
  110. // a bug in the spooler API GetPrinterData, we must pass in a valid pointer here.
  111. //
  112. if (GetPrinterData(hPrinter, pRegKey, &type, (PBYTE) &type, 0, &cb) == ERROR_MORE_DATA &&
  113. (pBuffer = MemAlloc(cb)) &&
  114. GetPrinterData(hPrinter, pRegKey, &type, pBuffer, cb, &cb) == ERROR_SUCCESS &&
  115. (type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ))
  116. {
  117. return pBuffer;
  118. }
  119. DebugPrint((L"Couldn't get printer data string %ws: %d\n", pRegKey, GetLastError()));
  120. MemFree(pBuffer);
  121. return NULL;
  122. }
  123. DWORD
  124. GetPrinterDataDWord(
  125. HANDLE hPrinter,
  126. PWSTR pRegKey,
  127. DWORD defaultValue
  128. )
  129. {
  130. DWORD value, type, cb;
  131. if (GetPrinterData(hPrinter,
  132. pRegKey,
  133. &type,
  134. (PBYTE) &value,
  135. sizeof(value),
  136. &cb) == ERROR_SUCCESS)
  137. {
  138. return value;
  139. }
  140. return defaultValue;
  141. }
  142. void
  143. pprintf(
  144. HDC hDC,
  145. HFONT hFont,
  146. LPWSTR Format,
  147. ...
  148. )
  149. {
  150. WCHAR buf[1024];
  151. va_list arg_ptr;
  152. INT len;
  153. BOOL cr = FALSE;
  154. TEXTMETRIC tm;
  155. SIZE Size;
  156. INT Fit;
  157. va_start(arg_ptr, Format);
  158. _vsnwprintf( buf, sizeof(buf), Format, arg_ptr );
  159. va_end(arg_ptr);
  160. len = wcslen(buf);
  161. if (buf[len-1] == TEXT('\n')) {
  162. len -= 1;
  163. buf[len] = 0;
  164. cr = TRUE;
  165. }
  166. SelectObject( hDC, hFont );
  167. GetTextMetrics( hDC, &tm );
  168. TextOut( hDC, x, y, buf, len );
  169. if (cr) {
  170. y += tm.tmHeight;
  171. x = 0;
  172. } else {
  173. GetTextExtentExPoint(
  174. hDC,
  175. buf,
  176. len,
  177. len * tm.tmMaxCharWidth,
  178. &Fit,
  179. NULL,
  180. &Size
  181. );
  182. x += Fit;
  183. }
  184. }
  185. LPSTR
  186. GetDefaultMessagingProfile(
  187. VOID
  188. )
  189. {
  190. #define KeyPath L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles"
  191. #define Value L"DefaultProfile"
  192. HKEY hkey;
  193. WCHAR UserProfileStringW[64];
  194. DWORD buf_sz = sizeof(UserProfileStringW);
  195. DWORD val_type;
  196. if( RegOpenKeyEx( HKEY_CURRENT_USER, KeyPath, 0, KEY_READ, &hkey ) == ERROR_SUCCESS )
  197. {
  198. if ( RegQueryValueEx( hkey, Value, NULL, &val_type, (LPBYTE) UserProfileStringW, &buf_sz ) == ERROR_SUCCESS )
  199. {
  200. if ( val_type == REG_SZ )
  201. {
  202. RegCloseKey( hkey );
  203. return UnicodeStringToAnsiString( UserProfileStringW );
  204. }
  205. }
  206. RegCloseKey( hkey );
  207. }
  208. return NULL;
  209. }
  210. BOOL
  211. PrintText(
  212. HDC hDC,
  213. LPSTR Text,
  214. DWORD TextSize
  215. )
  216. {
  217. LPWSTR lpLine;
  218. LPWSTR pLineEOL;
  219. LPWSTR pNextLine;
  220. LPWSTR BodyText;
  221. DWORD Chars;
  222. HFONT hFont = NULL;
  223. HFONT hPrevFont = NULL;
  224. TEXTMETRIC tm;
  225. BOOL rVal = TRUE;
  226. INT nLinesPerPage;
  227. INT dyTop; // width of top border (pixels)
  228. INT dyBottom; // width of bottom border
  229. INT dxLeft; // width of left border
  230. INT dxRight; // width of right border
  231. INT yPrinWCHAR; // height of a character
  232. INT tabSize; // Size of a tab for print device in device units
  233. INT yCurpos = 0;
  234. INT xCurpos = 0;
  235. INT nPixelsLeft = 0;
  236. INT guess = 0;
  237. SIZE Size; // to see if text will fit in space left
  238. INT nPrintedLines = 0;
  239. BOOL fPageStarted = FALSE;
  240. INT iPageNum = 0;
  241. INT xPrintRes; // printer resolution in x direction
  242. INT yPrintRes; // printer resolution in y direction
  243. INT yPixInch; // pixels/inch
  244. INT xPixInch; // pixels/inch
  245. INT xPixUnit; // pixels/local measurement unit
  246. INT yPixUnit; // pixels/local measurement unit
  247. BOOL fEnglish;
  248. INT PrevBkMode = 0;
  249. BodyText = (LPWSTR) MemAlloc( (TextSize + 4) * sizeof(WCHAR) );
  250. if (!BodyText) {
  251. return FALSE;
  252. }
  253. MultiByteToWideChar(
  254. CP_ACP,
  255. MB_PRECOMPOSED,
  256. Text,
  257. -1,
  258. BodyText,
  259. TextSize
  260. );
  261. lpLine = BodyText;
  262. fEnglish = GetProfileInt( L"intl", L"iMeasure", 1 );
  263. xPrintRes = GetDeviceCaps( hDC, HORZRES );
  264. yPrintRes = GetDeviceCaps( hDC, VERTRES );
  265. xPixInch = GetDeviceCaps( hDC, LOGPIXELSX );
  266. yPixInch = GetDeviceCaps( hDC, LOGPIXELSY );
  267. //
  268. // compute x and y pixels per local measurement unit
  269. //
  270. if (fEnglish) {
  271. xPixUnit= xPixInch;
  272. yPixUnit= yPixInch;
  273. } else {
  274. xPixUnit= CMToInches( xPixInch );
  275. yPixUnit= CMToInches( yPixInch );
  276. }
  277. SetMapMode( hDC, MM_TEXT );
  278. hFont = GetStockObject( SYSTEM_FIXED_FONT );
  279. hPrevFont = (HFONT) SelectObject( hDC, hFont );
  280. SetBkMode( hDC, TRANSPARENT );
  281. if (!GetTextMetrics( hDC, &tm )) {
  282. rVal = FALSE;
  283. goto exit;
  284. }
  285. yPrinWCHAR = tm.tmHeight + tm.tmExternalLeading;
  286. tabSize = tm.tmAveCharWidth * 8;
  287. //
  288. // compute margins in pixels
  289. //
  290. dxLeft = LEFT_MARGIN * xPixUnit;
  291. dxRight = RIGHT_MARGIN * xPixUnit;
  292. dyTop = TOP_MARGIN * yPixUnit;
  293. dyBottom = BOTTOM_MARGIN * yPixUnit;
  294. //
  295. // Number of lines on a page with margins
  296. //
  297. nLinesPerPage = ((yPrintRes - dyTop - dyBottom) / yPrinWCHAR);
  298. while (*lpLine) {
  299. if (*lpLine == '\r') {
  300. lpLine += 2;
  301. yCurpos += yPrinWCHAR;
  302. nPrintedLines++;
  303. xCurpos= 0;
  304. continue;
  305. }
  306. pLineEOL = lpLine;
  307. while (*pLineEOL && *pLineEOL != '\r') pLineEOL++;
  308. do {
  309. if ((nPrintedLines == 0) && (!fPageStarted)) {
  310. StartPage( hDC );
  311. fPageStarted = TRUE;
  312. yCurpos = 0;
  313. xCurpos = 0;
  314. }
  315. if (*lpLine == '\t') {
  316. //
  317. // round up to the next tab stop
  318. // if the current position is on the tabstop, goto next one
  319. //
  320. xCurpos = ((xCurpos + tabSize) / tabSize ) * tabSize;
  321. lpLine++;
  322. } else {
  323. //
  324. // find end of line or tab
  325. //
  326. pNextLine = lpLine;
  327. while ((pNextLine != pLineEOL) && *pNextLine != '\t') pNextLine++;
  328. //
  329. // find out how many characters will fit on line
  330. //
  331. Chars = pNextLine - lpLine;
  332. nPixelsLeft = xPrintRes - dxRight - dxLeft - xCurpos;
  333. GetTextExtentExPoint( hDC, lpLine, Chars, nPixelsLeft, &guess, NULL, &Size );
  334. if (guess) {
  335. //
  336. // at least one character fits - print
  337. //
  338. TextOut( hDC, dxLeft+xCurpos, yCurpos+dyTop, lpLine, guess );
  339. xCurpos += Size.cx; // account for printing
  340. lpLine += guess; // printed characters
  341. } else {
  342. //
  343. // no characters fit what's left
  344. // no characters will fit in space left
  345. // if none ever will, just print one
  346. // character to keep progressing through
  347. // input file.
  348. //
  349. if (xCurpos == 0) {
  350. if( lpLine != pNextLine ) {
  351. //
  352. // print something if not null line
  353. // could use exttextout here to clip
  354. //
  355. TextOut( hDC, dxLeft+xCurpos, yCurpos+dyTop, lpLine, 1 );
  356. lpLine++;
  357. }
  358. } else {
  359. //
  360. // perhaps the next line will get it
  361. //
  362. xCurpos = xPrintRes; // force to next line
  363. }
  364. }
  365. //
  366. // move printhead in y-direction
  367. //
  368. if ((xCurpos >= (xPrintRes - dxRight - dxLeft) ) || (lpLine == pLineEOL)) {
  369. yCurpos += yPrinWCHAR;
  370. nPrintedLines++;
  371. xCurpos = 0;
  372. }
  373. if (nPrintedLines >= nLinesPerPage) {
  374. EndPage( hDC );
  375. fPageStarted = FALSE;
  376. nPrintedLines = 0;
  377. xCurpos = 0;
  378. yCurpos = 0;
  379. iPageNum++;
  380. }
  381. }
  382. } while( lpLine != pLineEOL );
  383. if (*lpLine == '\r') {
  384. lpLine += 1;
  385. }
  386. if (*lpLine == '\n') {
  387. lpLine += 1;
  388. }
  389. }
  390. if (fPageStarted) {
  391. EndPage( hDC );
  392. }
  393. exit:
  394. MemFree( BodyText );
  395. if (hPrevFont) {
  396. SelectObject( hDC, hPrevFont );
  397. DeleteObject( hFont );
  398. }
  399. if (PrevBkMode) {
  400. SetBkMode( hDC, PrevBkMode );
  401. }
  402. return rVal;
  403. }
  404. BOOL
  405. GetSettings(
  406. VOID
  407. )
  408. {
  409. DWORD i;
  410. LPWSTR p;
  411. LPWSTR s;
  412. WCHAR MsgTypeString[64];
  413. WCHAR RecipientName[128];
  414. WCHAR RecipientNumber[128];
  415. WCHAR DocKeys[4096];
  416. DWORD RecipientCount;
  417. WCHAR Sections[4096];
  418. //
  419. // get the doc type
  420. //
  421. GetPrivateProfileString(
  422. L"General",
  423. L"MessageType",
  424. L"Printer",
  425. MsgTypeString,
  426. sizeof(MsgTypeString),
  427. L".\\faxstres.ini"
  428. );
  429. if (_wcsicmp( MsgTypeString, L"Exchange" ) == 0) {
  430. UseExchange = TRUE;
  431. }
  432. //
  433. // get the document names
  434. //
  435. DocCount = 0;
  436. GetPrivateProfileString(
  437. L"Documents",
  438. NULL,
  439. L"",
  440. DocKeys,
  441. sizeof(DocKeys),
  442. L".\\faxstres.ini"
  443. );
  444. p = DocKeys;
  445. while (*p) {
  446. GetPrivateProfileString(
  447. L"Documents",
  448. p,
  449. L"",
  450. Documents[DocCount].Name,
  451. sizeof(Documents[DocCount].Name),
  452. L".\\faxstres.ini"
  453. );
  454. DocCount += 1;
  455. p += (wcslen(p) + 1);
  456. }
  457. for (i=0; i<DocCount; i++) {
  458. HANDLE hFile = CreateFile(
  459. Documents[i].Name,
  460. GENERIC_READ,
  461. FILE_SHARE_READ,
  462. NULL,
  463. OPEN_EXISTING,
  464. 0,
  465. NULL
  466. );
  467. if (hFile != INVALID_HANDLE_VALUE) {
  468. DWORD sz = GetFileSize( hFile, NULL );
  469. Documents[i].Text = MemAlloc( sz + 4 );
  470. if (Documents[i].Text) {
  471. ReadFile( hFile, Documents[i].Text, sz, &sz, NULL );
  472. Documents[i].TextSize = sz;
  473. }
  474. CloseHandle( hFile );
  475. }
  476. }
  477. RecipientCount = 0;
  478. //
  479. // get all of the section names
  480. //
  481. GetPrivateProfileString(
  482. NULL,
  483. NULL,
  484. L"",
  485. Sections,
  486. sizeof(Sections),
  487. L".\\faxstres.ini"
  488. );
  489. //
  490. // count the number of sections
  491. //
  492. p = Sections;
  493. while (*p) {
  494. if (wcscmp( p, L"Documents" ) != 0) {
  495. RecipientCount += 1;
  496. }
  497. p += (wcslen(p) + 1);
  498. }
  499. //
  500. // read the recipient info for each receipient
  501. //
  502. p = Sections;
  503. i = 0;
  504. RecipCount = 0;
  505. while (*p) {
  506. if ((wcscmp( p, L"Documents" ) == 0) ||
  507. (wcscmp( p, L"General" ) == 0)) {
  508. p += (wcslen(p) + 1);
  509. continue;
  510. }
  511. ZeroMemory( RecipientName, sizeof(RecipientName) );
  512. GetPrivateProfileString(
  513. p,
  514. L"Name",
  515. L"",
  516. RecipientName,
  517. sizeof(RecipientName),
  518. L".\\faxstres.ini"
  519. );
  520. GetPrivateProfileString(
  521. p,
  522. L"Number",
  523. L"",
  524. RecipientNumber,
  525. sizeof(RecipientNumber),
  526. L".\\faxstres.ini"
  527. );
  528. wcscpy( Recipients[RecipCount].Name, RecipientName );
  529. wcscpy( Recipients[RecipCount].Address, RecipientNumber );
  530. Recipients[RecipCount].NameLen = wcslen( Recipients[RecipCount].Name );
  531. s = wcschr( Recipients[RecipCount].Name, L',' );
  532. Recipients[RecipCount].MultiAddrCnt = 1;
  533. while( s ) {
  534. *s = UNICODE_NULL;
  535. s = wcschr( s+1, L',' );
  536. Recipients[RecipCount].MultiAddrCnt += 1;
  537. }
  538. Recipients[RecipCount].AddressLen = wcslen( Recipients[RecipCount].Address );
  539. s = wcschr( Recipients[RecipCount].Address, L',' );
  540. while( s ) {
  541. *s = UNICODE_NULL;
  542. s = wcschr( s+1, L',' );
  543. }
  544. RecipCount += 1;
  545. i += 1;
  546. p += (wcslen(p) + 1);
  547. }
  548. return TRUE;
  549. }
  550. DWORD
  551. ConcatStrings(
  552. LPWSTR DestStr,
  553. LPWSTR Str1,
  554. LPWSTR Str2
  555. )
  556. {
  557. DWORD len = 0;
  558. wcscpy( DestStr, Str1 );
  559. len += wcslen(DestStr) + 1;
  560. DestStr += wcslen(DestStr) + 1;
  561. wcscpy( DestStr, Str2 );
  562. len += wcslen(DestStr) + 1;
  563. DestStr += wcslen(DestStr) + 1;
  564. return len;
  565. }
  566. BOOL
  567. SetFakeRecipientInfo(
  568. VOID
  569. )
  570. {
  571. HANDLE hPrinter;
  572. PRINTER_DEFAULTS PrinterDefaults;
  573. WCHAR SubKeyName[256];
  574. WCHAR Buffer[256];
  575. DWORD i;
  576. DWORD len;
  577. DWORD blen;
  578. LPWSTR s;
  579. LPWSTR Name,Addr;
  580. PrinterDefaults.pDatatype = NULL;
  581. PrinterDefaults.pDevMode = NULL;
  582. PrinterDefaults.DesiredAccess = PRINTER_ACCESS_USE;
  583. if (!OpenPrinter( FaxPrinterName, &hPrinter, &PrinterDefaults )) {
  584. DebugPrint(( L"OpenPrinter#1() failed, ec=%d", GetLastError() ));
  585. return FALSE;
  586. }
  587. if (GetPrinterDataDWord( hPrinter, L"FakeRecipientCount", 0 )) {
  588. DontResetOnExit = TRUE;
  589. ClosePrinter( hPrinter );
  590. return TRUE;
  591. }
  592. ClosePrinter( hPrinter );
  593. PrinterDefaults.DesiredAccess = PRINTER_ALL_ACCESS;
  594. if (!OpenPrinter( FaxPrinterName, &hPrinter, &PrinterDefaults )) {
  595. DebugPrint(( L"OpenPrinter#2() failed, ec=%d", GetLastError() ));
  596. return FALSE;
  597. }
  598. SetPrinterDataDWord( hPrinter, L"FakeRecipientCount", UseExchange ? 0 : RecipCount );
  599. if (!UseExchange) {
  600. for (i=0; i<RecipCount; i++) {
  601. ZeroMemory( Buffer, sizeof(Buffer) );
  602. swprintf( SubKeyName, L"FakeRecipient%d", i );
  603. if (Recipients[i].MultiAddrCnt > 1) {
  604. Name = Recipients[i].Name;
  605. Addr = Recipients[i].Address;
  606. s = Buffer;
  607. len = 2;
  608. do {
  609. blen = ConcatStrings( s, Name, Addr );
  610. s += blen;
  611. Name += wcslen(Name) + 1;
  612. Addr += wcslen(Addr) + 1;
  613. len += blen;
  614. } while( *Name );
  615. len = len * sizeof(WCHAR);
  616. } else {
  617. ConcatStrings( Buffer, Recipients[i].Name, Recipients[i].Address );
  618. len = (wcslen(Recipients[i].Name) + wcslen(Recipients[i].Address) + 3) * sizeof(WCHAR);
  619. }
  620. SetPrinterDataStr( hPrinter, SubKeyName, Buffer, len );
  621. }
  622. }
  623. ClosePrinter( hPrinter );
  624. }
  625. BOOL
  626. ExchangeStress(
  627. VOID
  628. )
  629. {
  630. LPSTR UserProfile;
  631. MapiRecipDesc rgRecipDescStruct[30];
  632. MapiMessage MessageStruct = {0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, 0, NULL};
  633. MapiFileDesc MAPIFileDesc = {0, 0, 0, NULL, NULL, NULL};
  634. HMODULE hMapiMod;
  635. DWORD rslt;
  636. LHANDLE hSession;
  637. DWORD RecipIdx;
  638. DWORD DocIdx;
  639. hMapiMod = LoadLibrary( L"mapi32.dll" );
  640. pMAPILogon = (LPMAPILOGON) GetProcAddress( hMapiMod, "MAPILogon" );
  641. pMAPISendMail = (LPMAPISENDMAIL) GetProcAddress( hMapiMod, "MAPISendMail" );
  642. pMAPILogoff = (LPMAPILOGOFF) GetProcAddress( hMapiMod, "MAPILogoff" );
  643. if (pMAPILogon == NULL || pMAPISendMail == NULL || pMAPILogoff == NULL) {
  644. PopUpMsg( L"cannot link to exchange" );
  645. return FALSE;
  646. }
  647. UserProfile = GetDefaultMessagingProfile();
  648. rslt = pMAPILogon( 0, UserProfile, NULL, MAPI_NEW_SESSION, 0, &hSession );
  649. if (rslt != SUCCESS_SUCCESS) {
  650. PopUpMsg( L"cannot logon to exchange: [%d]", rslt );
  651. return FALSE;
  652. }
  653. rgRecipDescStruct[0].ulReserved = 0;
  654. rgRecipDescStruct[0].ulRecipClass = MAPI_TO;
  655. rgRecipDescStruct[0].lpszName = NULL;
  656. rgRecipDescStruct[0].lpszAddress = NULL;
  657. rgRecipDescStruct[0].ulEIDSize = 0;
  658. rgRecipDescStruct[0].lpEntryID = NULL;
  659. MessageStruct.lpRecips = rgRecipDescStruct;
  660. MessageStruct.nRecipCount = 1;
  661. MessageStruct.lpszSubject = "Test Message";
  662. MessageStruct.lpszNoteText = NULL;
  663. RecipIdx = 0;
  664. DocIdx = 0;
  665. while( Copies ) {
  666. rgRecipDescStruct[0].lpszName = UnicodeStringToAnsiString( Recipients[RecipIdx].Name );
  667. MessageStruct.lpszNoteText = Documents[DocIdx].Text;
  668. rslt = pMAPISendMail( 0, 0, &MessageStruct, 0, 0 );
  669. MemFree( rgRecipDescStruct[0].lpszName );
  670. DocIdx += 1;
  671. if (DocIdx == DocCount) {
  672. DocIdx = 0;
  673. }
  674. RecipIdx += 1;
  675. if (RecipIdx == RecipCount) {
  676. RecipIdx = 0;
  677. }
  678. }
  679. ExchangeEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  680. PopUpMsg( L"**** when all documents have been queued to the printer then ^C this..." );
  681. WaitForSingleObject( ExchangeEvent, INFINITE );
  682. pMAPILogoff( hSession, 0, 0, 0 );
  683. }
  684. BOOL
  685. PrintStress(
  686. VOID
  687. )
  688. {
  689. LPWSTR MachineName = NULL;
  690. HANDLE hPrinter;
  691. HDC hDC;
  692. DOCINFO di;
  693. HPEN hPenWide;
  694. HFONT hFontBig;
  695. HFONT hFontNormal;
  696. SYSTEMTIME Time;
  697. DWORD DocIdx = 0;
  698. PRINTER_DEFAULTS PrinterDefaults;
  699. PrinterDefaults.pDatatype = NULL;
  700. PrinterDefaults.pDevMode = NULL;
  701. PrinterDefaults.DesiredAccess = PRINTER_ACCESS_USE;
  702. if (!OpenPrinter( FaxPrinterName, &hPrinter, &PrinterDefaults )) {
  703. DebugPrint(( L"OpenPrinter() failed, ec=%d", GetLastError() ));
  704. return FALSE;
  705. }
  706. hPenWide = CreatePen( PS_SOLID, 7, RGB(0,0,0) );
  707. hFontBig = CreateFont( 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial" );
  708. hFontNormal = CreateFont( 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial" );
  709. while( Copies ) {
  710. hDC = CreateDC( L"WINSPOOL", FaxPrinterName, NULL, NULL );
  711. if (!hDC) {
  712. return FALSE;
  713. }
  714. ZeroMemory( &di, sizeof( DOCINFO ) );
  715. di.cbSize = sizeof( DOCINFO );
  716. di.lpszDocName = L"Fax Stress Document";
  717. StartDoc( hDC, &di );
  718. if (DocCount) {
  719. PrintText( hDC, Documents[DocIdx].Text, Documents[DocIdx].TextSize );
  720. DocIdx += 1;
  721. if (DocIdx == DocCount) {
  722. DocIdx = 0;
  723. }
  724. } else {
  725. StartPage( hDC );
  726. x = 10;
  727. y = 50;
  728. pprintf( hDC, hFontBig, L"This is a TEST Fax!\n" );
  729. GetLocalTime( &Time );
  730. pprintf( hDC, hFontNormal, L"Document generated @ %02d:%02d:%02d.%03d\n",
  731. Time.wHour,
  732. Time.wMinute,
  733. Time.wSecond,
  734. Time.wMilliseconds
  735. );
  736. EndPage( hDC );
  737. }
  738. EndDoc( hDC );
  739. DeleteDC( hDC );
  740. Copies -= 1;
  741. }
  742. ClosePrinter( hPrinter );
  743. return TRUE;
  744. }
  745. LRESULT
  746. StressWndProc(
  747. HWND hwnd,
  748. UINT message,
  749. WPARAM wParam,
  750. LPARAM lParam
  751. )
  752. {
  753. switch (message) {
  754. case WM_CREATE:
  755. return 0;
  756. case WM_COMMAND:
  757. switch (wParam) {
  758. case IDCANCEL:
  759. SendMessage( hwnd, WM_CLOSE, 0, 0 );
  760. break;
  761. case IDOK:
  762. SendMessage( hwnd, WM_CLOSE, 0, 0 );
  763. break;
  764. }
  765. return 0;
  766. case WM_DESTROY:
  767. PostQuitMessage( 0 );
  768. return 0;
  769. default:
  770. break;
  771. }
  772. return DefWindowProc( hwnd, message, wParam, lParam );
  773. }
  774. int
  775. WINAPI
  776. wWinMain(
  777. HINSTANCE hInstance,
  778. HINSTANCE hPrevInstance,
  779. LPWSTR lpCmdLine,
  780. int nShowCmd
  781. )
  782. {
  783. int argc;
  784. LPWSTR *argv;
  785. int i;
  786. MSG msg;
  787. HWND hwnd;
  788. WNDCLASS wndclass;
  789. HeapInitialize(NULL,NULL,NULL,0);
  790. //
  791. // process any command line arguments
  792. //
  793. argv = CommandLineToArgvW( lpCmdLine, &argc );
  794. if (argv) {
  795. for (i=0; i<argc; i++) {
  796. if ((argv[i][0] == L'/') || (argv[i][0] == L'-')) {
  797. switch (towlower(argv[i][1])) {
  798. case 'q':
  799. NoGuiMode = TRUE;
  800. break;
  801. case 'c':
  802. i += 1;
  803. Copies = _wtoi( argv[i] );
  804. break;
  805. case 'p':
  806. i += 1;
  807. FaxPrinterName = argv[i];
  808. break;
  809. default:
  810. break;
  811. }
  812. }
  813. }
  814. } else {
  815. argc = 0;
  816. }
  817. GetSettings();
  818. if (RecipCount == 0) {
  819. PopUpMsg( L"you must supply at least 1 recipient" );
  820. return FALSE;
  821. }
  822. if (UseExchange && DocCount == 0) {
  823. PopUpMsg( L"you must supply at least 1 document when using exchange stress" );
  824. return FALSE;
  825. }
  826. if ((!UseExchange) && (!FaxPrinterName)) {
  827. PopUpMsg( L"you must supply at fax printer name" );
  828. return FALSE;
  829. }
  830. if (!UseExchange) {
  831. SetFakeRecipientInfo();
  832. }
  833. if (NoGuiMode) {
  834. if (UseExchange) {
  835. ExchangeStress();
  836. } else {
  837. PrintStress();
  838. }
  839. if ((!UseExchange) && (!DontResetOnExit)) {
  840. RecipCount = 0;
  841. SetFakeRecipientInfo();
  842. }
  843. return 0;
  844. }
  845. InitCommonControls();
  846. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  847. wndclass.lpfnWndProc = StressWndProc;
  848. wndclass.cbClsExtra = 0;
  849. wndclass.cbWndExtra = DLGWINDOWEXTRA;
  850. wndclass.hInstance = hInstance;
  851. wndclass.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(APPICON) );
  852. wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
  853. wndclass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE);
  854. wndclass.lpszMenuName = NULL;
  855. wndclass.lpszClassName = L"FaxStress";
  856. RegisterClass( &wndclass );
  857. hwnd = CreateDialog(
  858. hInstance,
  859. MAKEINTRESOURCE(IDD_STRESS),
  860. 0,
  861. StressWndProc
  862. );
  863. ShowWindow( hwnd, SW_SHOWNORMAL );
  864. while (GetMessage (&msg, NULL, 0, 0)) {
  865. if (!IsDialogMessage( hwnd, &msg )) {
  866. TranslateMessage (&msg) ;
  867. DispatchMessage (&msg) ;
  868. }
  869. }
  870. return 0;
  871. }