#include #include #include #include #include #include #include #include #include "faxutil.h" #include "winfax.h" #include "resource.h" typedef struct _RECIPIENT { WCHAR Name[256]; WCHAR Address[256]; DWORD NameLen; DWORD AddressLen; DWORD MultiAddrCnt; } RECIPIENT, *PRECIPIENT; typedef struct _DOCUMENT { WCHAR Name[256]; LPSTR Text; DWORD TextSize; } DOCUMENT, *PDOCUMENT; LPWSTR FaxPrinterName; int x; int y; LPMAPILOGON pMAPILogon; LPMAPISENDMAIL pMAPISendMail; LPMAPILOGOFF pMAPILogoff; RECIPIENT Recipients[100]; DOCUMENT Documents[100]; HANDLE ExchangeEvent; BOOL UseExchange; DWORD DocCount; DWORD RecipCount; BOOL NoGuiMode = TRUE; DWORD Copies = 1; BOOL DontResetOnExit; #define LEFT_MARGIN 1 // ---| #define RIGHT_MARGIN 1 // | #define TOP_MARGIN 1 // |---> in inches #define BOTTOM_MARGIN 1 // ---| #define InchesToCM(_x) (((_x) * 254L + 50) / 100) #define CMToInches(_x) (((_x) * 100L + 127) / 254) int PopUpMsg( LPWSTR Format, ... ) { WCHAR buf[1024]; va_list arg_ptr; va_start( arg_ptr, Format ); _vsnwprintf( buf, sizeof(buf), Format, arg_ptr ); va_end(arg_ptr); return MessageBox( NULL, buf, L"Fax Stress Error", MB_SETFOREGROUND | MB_ICONEXCLAMATION | MB_OK ); } BOOL SetPrinterDataStr( HANDLE hPrinter, LPWSTR pRegKey, LPWSTR pValue, DWORD Length ) { if (SetPrinterData(hPrinter, pRegKey, REG_MULTI_SZ, (PBYTE) pValue, Length) != ERROR_SUCCESS) { DebugPrint((L"Couldn't save registry key %ws: %d\n", pRegKey, GetLastError())); return FALSE; } return TRUE; } BOOL SetPrinterDataDWord( HANDLE hPrinter, PWSTR pRegKey, DWORD value ) { if (SetPrinterData(hPrinter, pRegKey, REG_DWORD, (PBYTE) &value, sizeof(value)) != ERROR_SUCCESS) { DebugPrint((L"Couldn't save registry key %ws: %d\n", pRegKey, GetLastError())); return FALSE; } return TRUE; } LPWSTR GetPrinterDataStr( HANDLE hPrinter, LPWSTR pRegKey ) { DWORD type, cb; PVOID pBuffer = NULL; // // We should really pass NULL for pData parameter here. But to workaround // a bug in the spooler API GetPrinterData, we must pass in a valid pointer here. // if (GetPrinterData(hPrinter, pRegKey, &type, (PBYTE) &type, 0, &cb) == ERROR_MORE_DATA && (pBuffer = MemAlloc(cb)) && GetPrinterData(hPrinter, pRegKey, &type, pBuffer, cb, &cb) == ERROR_SUCCESS && (type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ)) { return pBuffer; } DebugPrint((L"Couldn't get printer data string %ws: %d\n", pRegKey, GetLastError())); MemFree(pBuffer); return NULL; } DWORD GetPrinterDataDWord( HANDLE hPrinter, PWSTR pRegKey, DWORD defaultValue ) { DWORD value, type, cb; if (GetPrinterData(hPrinter, pRegKey, &type, (PBYTE) &value, sizeof(value), &cb) == ERROR_SUCCESS) { return value; } return defaultValue; } void pprintf( HDC hDC, HFONT hFont, LPWSTR Format, ... ) { WCHAR buf[1024]; va_list arg_ptr; INT len; BOOL cr = FALSE; TEXTMETRIC tm; SIZE Size; INT Fit; va_start(arg_ptr, Format); _vsnwprintf( buf, sizeof(buf), Format, arg_ptr ); va_end(arg_ptr); len = wcslen(buf); if (buf[len-1] == TEXT('\n')) { len -= 1; buf[len] = 0; cr = TRUE; } SelectObject( hDC, hFont ); GetTextMetrics( hDC, &tm ); TextOut( hDC, x, y, buf, len ); if (cr) { y += tm.tmHeight; x = 0; } else { GetTextExtentExPoint( hDC, buf, len, len * tm.tmMaxCharWidth, &Fit, NULL, &Size ); x += Fit; } } LPSTR GetDefaultMessagingProfile( VOID ) { #define KeyPath L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles" #define Value L"DefaultProfile" HKEY hkey; WCHAR UserProfileStringW[64]; DWORD buf_sz = sizeof(UserProfileStringW); DWORD val_type; if( RegOpenKeyEx( HKEY_CURRENT_USER, KeyPath, 0, KEY_READ, &hkey ) == ERROR_SUCCESS ) { if ( RegQueryValueEx( hkey, Value, NULL, &val_type, (LPBYTE) UserProfileStringW, &buf_sz ) == ERROR_SUCCESS ) { if ( val_type == REG_SZ ) { RegCloseKey( hkey ); return UnicodeStringToAnsiString( UserProfileStringW ); } } RegCloseKey( hkey ); } return NULL; } BOOL PrintText( HDC hDC, LPSTR Text, DWORD TextSize ) { LPWSTR lpLine; LPWSTR pLineEOL; LPWSTR pNextLine; LPWSTR BodyText; DWORD Chars; HFONT hFont = NULL; HFONT hPrevFont = NULL; TEXTMETRIC tm; BOOL rVal = TRUE; INT nLinesPerPage; INT dyTop; // width of top border (pixels) INT dyBottom; // width of bottom border INT dxLeft; // width of left border INT dxRight; // width of right border INT yPrinWCHAR; // height of a character INT tabSize; // Size of a tab for print device in device units INT yCurpos = 0; INT xCurpos = 0; INT nPixelsLeft = 0; INT guess = 0; SIZE Size; // to see if text will fit in space left INT nPrintedLines = 0; BOOL fPageStarted = FALSE; INT iPageNum = 0; INT xPrintRes; // printer resolution in x direction INT yPrintRes; // printer resolution in y direction INT yPixInch; // pixels/inch INT xPixInch; // pixels/inch INT xPixUnit; // pixels/local measurement unit INT yPixUnit; // pixels/local measurement unit BOOL fEnglish; INT PrevBkMode = 0; BodyText = (LPWSTR) MemAlloc( (TextSize + 4) * sizeof(WCHAR) ); if (!BodyText) { return FALSE; } MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, Text, -1, BodyText, TextSize ); lpLine = BodyText; fEnglish = GetProfileInt( L"intl", L"iMeasure", 1 ); xPrintRes = GetDeviceCaps( hDC, HORZRES ); yPrintRes = GetDeviceCaps( hDC, VERTRES ); xPixInch = GetDeviceCaps( hDC, LOGPIXELSX ); yPixInch = GetDeviceCaps( hDC, LOGPIXELSY ); // // compute x and y pixels per local measurement unit // if (fEnglish) { xPixUnit= xPixInch; yPixUnit= yPixInch; } else { xPixUnit= CMToInches( xPixInch ); yPixUnit= CMToInches( yPixInch ); } SetMapMode( hDC, MM_TEXT ); hFont = GetStockObject( SYSTEM_FIXED_FONT ); hPrevFont = (HFONT) SelectObject( hDC, hFont ); SetBkMode( hDC, TRANSPARENT ); if (!GetTextMetrics( hDC, &tm )) { rVal = FALSE; goto exit; } yPrinWCHAR = tm.tmHeight + tm.tmExternalLeading; tabSize = tm.tmAveCharWidth * 8; // // compute margins in pixels // dxLeft = LEFT_MARGIN * xPixUnit; dxRight = RIGHT_MARGIN * xPixUnit; dyTop = TOP_MARGIN * yPixUnit; dyBottom = BOTTOM_MARGIN * yPixUnit; // // Number of lines on a page with margins // nLinesPerPage = ((yPrintRes - dyTop - dyBottom) / yPrinWCHAR); while (*lpLine) { if (*lpLine == '\r') { lpLine += 2; yCurpos += yPrinWCHAR; nPrintedLines++; xCurpos= 0; continue; } pLineEOL = lpLine; while (*pLineEOL && *pLineEOL != '\r') pLineEOL++; do { if ((nPrintedLines == 0) && (!fPageStarted)) { StartPage( hDC ); fPageStarted = TRUE; yCurpos = 0; xCurpos = 0; } if (*lpLine == '\t') { // // round up to the next tab stop // if the current position is on the tabstop, goto next one // xCurpos = ((xCurpos + tabSize) / tabSize ) * tabSize; lpLine++; } else { // // find end of line or tab // pNextLine = lpLine; while ((pNextLine != pLineEOL) && *pNextLine != '\t') pNextLine++; // // find out how many characters will fit on line // Chars = pNextLine - lpLine; nPixelsLeft = xPrintRes - dxRight - dxLeft - xCurpos; GetTextExtentExPoint( hDC, lpLine, Chars, nPixelsLeft, &guess, NULL, &Size ); if (guess) { // // at least one character fits - print // TextOut( hDC, dxLeft+xCurpos, yCurpos+dyTop, lpLine, guess ); xCurpos += Size.cx; // account for printing lpLine += guess; // printed characters } else { // // no characters fit what's left // no characters will fit in space left // if none ever will, just print one // character to keep progressing through // input file. // if (xCurpos == 0) { if( lpLine != pNextLine ) { // // print something if not null line // could use exttextout here to clip // TextOut( hDC, dxLeft+xCurpos, yCurpos+dyTop, lpLine, 1 ); lpLine++; } } else { // // perhaps the next line will get it // xCurpos = xPrintRes; // force to next line } } // // move printhead in y-direction // if ((xCurpos >= (xPrintRes - dxRight - dxLeft) ) || (lpLine == pLineEOL)) { yCurpos += yPrinWCHAR; nPrintedLines++; xCurpos = 0; } if (nPrintedLines >= nLinesPerPage) { EndPage( hDC ); fPageStarted = FALSE; nPrintedLines = 0; xCurpos = 0; yCurpos = 0; iPageNum++; } } } while( lpLine != pLineEOL ); if (*lpLine == '\r') { lpLine += 1; } if (*lpLine == '\n') { lpLine += 1; } } if (fPageStarted) { EndPage( hDC ); } exit: MemFree( BodyText ); if (hPrevFont) { SelectObject( hDC, hPrevFont ); DeleteObject( hFont ); } if (PrevBkMode) { SetBkMode( hDC, PrevBkMode ); } return rVal; } BOOL GetSettings( VOID ) { DWORD i; LPWSTR p; LPWSTR s; WCHAR MsgTypeString[64]; WCHAR RecipientName[128]; WCHAR RecipientNumber[128]; WCHAR DocKeys[4096]; DWORD RecipientCount; WCHAR Sections[4096]; // // get the doc type // GetPrivateProfileString( L"General", L"MessageType", L"Printer", MsgTypeString, sizeof(MsgTypeString), L".\\faxstres.ini" ); if (_wcsicmp( MsgTypeString, L"Exchange" ) == 0) { UseExchange = TRUE; } // // get the document names // DocCount = 0; GetPrivateProfileString( L"Documents", NULL, L"", DocKeys, sizeof(DocKeys), L".\\faxstres.ini" ); p = DocKeys; while (*p) { GetPrivateProfileString( L"Documents", p, L"", Documents[DocCount].Name, sizeof(Documents[DocCount].Name), L".\\faxstres.ini" ); DocCount += 1; p += (wcslen(p) + 1); } for (i=0; i 1) { Name = Recipients[i].Name; Addr = Recipients[i].Address; s = Buffer; len = 2; do { blen = ConcatStrings( s, Name, Addr ); s += blen; Name += wcslen(Name) + 1; Addr += wcslen(Addr) + 1; len += blen; } while( *Name ); len = len * sizeof(WCHAR); } else { ConcatStrings( Buffer, Recipients[i].Name, Recipients[i].Address ); len = (wcslen(Recipients[i].Name) + wcslen(Recipients[i].Address) + 3) * sizeof(WCHAR); } SetPrinterDataStr( hPrinter, SubKeyName, Buffer, len ); } } ClosePrinter( hPrinter ); } BOOL ExchangeStress( VOID ) { LPSTR UserProfile; MapiRecipDesc rgRecipDescStruct[30]; MapiMessage MessageStruct = {0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, 0, NULL}; MapiFileDesc MAPIFileDesc = {0, 0, 0, NULL, NULL, NULL}; HMODULE hMapiMod; DWORD rslt; LHANDLE hSession; DWORD RecipIdx; DWORD DocIdx; hMapiMod = LoadLibrary( L"mapi32.dll" ); pMAPILogon = (LPMAPILOGON) GetProcAddress( hMapiMod, "MAPILogon" ); pMAPISendMail = (LPMAPISENDMAIL) GetProcAddress( hMapiMod, "MAPISendMail" ); pMAPILogoff = (LPMAPILOGOFF) GetProcAddress( hMapiMod, "MAPILogoff" ); if (pMAPILogon == NULL || pMAPISendMail == NULL || pMAPILogoff == NULL) { PopUpMsg( L"cannot link to exchange" ); return FALSE; } UserProfile = GetDefaultMessagingProfile(); rslt = pMAPILogon( 0, UserProfile, NULL, MAPI_NEW_SESSION, 0, &hSession ); if (rslt != SUCCESS_SUCCESS) { PopUpMsg( L"cannot logon to exchange: [%d]", rslt ); return FALSE; } rgRecipDescStruct[0].ulReserved = 0; rgRecipDescStruct[0].ulRecipClass = MAPI_TO; rgRecipDescStruct[0].lpszName = NULL; rgRecipDescStruct[0].lpszAddress = NULL; rgRecipDescStruct[0].ulEIDSize = 0; rgRecipDescStruct[0].lpEntryID = NULL; MessageStruct.lpRecips = rgRecipDescStruct; MessageStruct.nRecipCount = 1; MessageStruct.lpszSubject = "Test Message"; MessageStruct.lpszNoteText = NULL; RecipIdx = 0; DocIdx = 0; while( Copies ) { rgRecipDescStruct[0].lpszName = UnicodeStringToAnsiString( Recipients[RecipIdx].Name ); MessageStruct.lpszNoteText = Documents[DocIdx].Text; rslt = pMAPISendMail( 0, 0, &MessageStruct, 0, 0 ); MemFree( rgRecipDescStruct[0].lpszName ); DocIdx += 1; if (DocIdx == DocCount) { DocIdx = 0; } RecipIdx += 1; if (RecipIdx == RecipCount) { RecipIdx = 0; } } ExchangeEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); PopUpMsg( L"**** when all documents have been queued to the printer then ^C this..." ); WaitForSingleObject( ExchangeEvent, INFINITE ); pMAPILogoff( hSession, 0, 0, 0 ); } BOOL PrintStress( VOID ) { LPWSTR MachineName = NULL; HANDLE hPrinter; HDC hDC; DOCINFO di; HPEN hPenWide; HFONT hFontBig; HFONT hFontNormal; SYSTEMTIME Time; DWORD DocIdx = 0; PRINTER_DEFAULTS PrinterDefaults; PrinterDefaults.pDatatype = NULL; PrinterDefaults.pDevMode = NULL; PrinterDefaults.DesiredAccess = PRINTER_ACCESS_USE; if (!OpenPrinter( FaxPrinterName, &hPrinter, &PrinterDefaults )) { DebugPrint(( L"OpenPrinter() failed, ec=%d", GetLastError() )); return FALSE; } hPenWide = CreatePen( PS_SOLID, 7, RGB(0,0,0) ); hFontBig = CreateFont( 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial" ); hFontNormal = CreateFont( 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial" ); while( Copies ) { hDC = CreateDC( L"WINSPOOL", FaxPrinterName, NULL, NULL ); if (!hDC) { return FALSE; } ZeroMemory( &di, sizeof( DOCINFO ) ); di.cbSize = sizeof( DOCINFO ); di.lpszDocName = L"Fax Stress Document"; StartDoc( hDC, &di ); if (DocCount) { PrintText( hDC, Documents[DocIdx].Text, Documents[DocIdx].TextSize ); DocIdx += 1; if (DocIdx == DocCount) { DocIdx = 0; } } else { StartPage( hDC ); x = 10; y = 50; pprintf( hDC, hFontBig, L"This is a TEST Fax!\n" ); GetLocalTime( &Time ); pprintf( hDC, hFontNormal, L"Document generated @ %02d:%02d:%02d.%03d\n", Time.wHour, Time.wMinute, Time.wSecond, Time.wMilliseconds ); EndPage( hDC ); } EndDoc( hDC ); DeleteDC( hDC ); Copies -= 1; } ClosePrinter( hPrinter ); return TRUE; } LRESULT StressWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch (message) { case WM_CREATE: return 0; case WM_COMMAND: switch (wParam) { case IDCANCEL: SendMessage( hwnd, WM_CLOSE, 0, 0 ); break; case IDOK: SendMessage( hwnd, WM_CLOSE, 0, 0 ); break; } return 0; case WM_DESTROY: PostQuitMessage( 0 ); return 0; default: break; } return DefWindowProc( hwnd, message, wParam, lParam ); } int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd ) { int argc; LPWSTR *argv; int i; MSG msg; HWND hwnd; WNDCLASS wndclass; HeapInitialize(NULL,NULL,NULL,0); // // process any command line arguments // argv = CommandLineToArgvW( lpCmdLine, &argc ); if (argv) { for (i=0; i