diff options
Diffstat (limited to 'private/mvdm/fax/wowfaxui/wfhelper.c')
-rw-r--r-- | private/mvdm/fax/wowfaxui/wfhelper.c | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/private/mvdm/fax/wowfaxui/wfhelper.c b/private/mvdm/fax/wowfaxui/wfhelper.c new file mode 100644 index 000000000..69a3833c4 --- /dev/null +++ b/private/mvdm/fax/wowfaxui/wfhelper.c @@ -0,0 +1,467 @@ +//************************************************************************ +// Generic Win 3.1 fax printer driver support. Helper functions which are +// called in WOWFAXUI.C +// +// History: +// 14-mar-95 reedb Created. Many of the functions were moved from +// FAXCOMM.C, since they're no longer called +// from WOWFAX.DLL. +// 16-aug-95 reedb Move to kernel mode. Debug output and validate +// functions moved from FAXCOMM.C. +// +//************************************************************************ + +#include "wowfaxui.h" + +extern LPCRITICAL_SECTION lpCriticalSection; +extern HINSTANCE ghInst; + +#if DBG + +INT iFaxLogLevel = 20; +INT iReqFaxLogLevel = 0; + +typedef PVOID HANDLE; + + +//************************************************************************ +// faxlogprintf - Two different implementations. One for client side +// debugging the other for server side. +// +//************************************************************************ + + +// For Debug logging. +#define MAX_DISPLAY_LINE 256 // 128 characters. + +TCHAR szFaxLogFile[] = L"C:\\FAXLOG.LOG"; +HANDLE hfFaxLog = NULL; + +// Defines for iFaxLogMode +#define NO_LOGGING 0 +#define LOG_TO_FILE 1 +#define OPEN_LOG_FILE 2 +#define CLOSE_LOG_FILE 3 + +INT iFaxLogMode = NO_LOGGING; + +VOID faxlogprintf(LPTSTR pszFmt, ...) +{ + DWORD lpBytesWritten; + int len; + TCHAR szText[1024]; + va_list arglist; + + va_start(arglist, pszFmt); + len = wvsprintf(szText, pszFmt, arglist); + + if (iFaxLogMode > LOG_TO_FILE) { + if (iFaxLogMode == OPEN_LOG_FILE) { + if((hfFaxLog = CreateFile(szFaxLogFile, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL)) != INVALID_HANDLE_VALUE) { + iFaxLogMode = LOG_TO_FILE; + } + else { + hfFaxLog = NULL; + iFaxLogMode = NO_LOGGING; + OutputDebugString(L"Couldn't open fax log file!\n"); + } + } + else { + FlushFileBuffers(hfFaxLog); + CloseHandle(hfFaxLog); + hfFaxLog = NULL; + iFaxLogMode = NO_LOGGING; + } + } + + if (iFaxLogLevel >= iReqFaxLogLevel) { + if (iFaxLogMode) { + WriteFile(hfFaxLog, szText, len, &lpBytesWritten, NULL); + } + else { + OutputDebugString(szText); + } + } +} + + +VOID LogWowFaxInfo(LPWOWFAXINFO lpWowFaxInfo) +{ + faxlogprintf(L"\tlpWowFaxInfo (lpMap): %X\n", lpWowFaxInfo); + faxlogprintf(L"\t\thwnd: %X\n", lpWowFaxInfo->hwnd); + faxlogprintf(L"\t\ttid: %X\n", lpWowFaxInfo->tid); + faxlogprintf(L"\t\tproc16: %X\n", lpWowFaxInfo->proc16); + faxlogprintf(L"\t\tlpinfo16: %X\n", lpWowFaxInfo->lpinfo16); + faxlogprintf(L"\t\tmsg: %X\n", lpWowFaxInfo->msg); + faxlogprintf(L"\t\thdc: %X\n", lpWowFaxInfo->hdc); + faxlogprintf(L"\t\twCmd: %X\n", lpWowFaxInfo->wCmd); + faxlogprintf(L"\t\tcData: %X\n", lpWowFaxInfo->cData); + faxlogprintf(L"\t\thwndui: %X\n", lpWowFaxInfo->hwndui); + faxlogprintf(L"\t\tretvalue: %X\n", lpWowFaxInfo->retvalue); + faxlogprintf(L"\t\tstatus: %X\n", lpWowFaxInfo->status); + if (lpWowFaxInfo->lpDevice) { + faxlogprintf(L"\t\tlpDevice: %s\n", lpWowFaxInfo->lpDevice); + } + else { + faxlogprintf(L"\t\tlpDevice: %X\n", lpWowFaxInfo->lpDevice); + } + if (lpWowFaxInfo->lpDriverName) { + faxlogprintf(L"\t\tlpDriverName: %s\n", lpWowFaxInfo->lpDriverName); + } + else { + faxlogprintf(L"\t\tlpDriverName: %X\n", lpWowFaxInfo->lpDriverName); + } + if (lpWowFaxInfo->lpPortName) { + faxlogprintf(L"\t\tlpPortName: %s\n", lpWowFaxInfo->lpPortName); + } + else { + faxlogprintf(L"\t\tlpPortName: %X\n", lpWowFaxInfo->lpPortName); + } + faxlogprintf(L"\t\tlpIn: %X\n", lpWowFaxInfo->lpIn); + faxlogprintf(L"\t\tlpOut: %X\n", lpWowFaxInfo->lpOut); + if (lpWowFaxInfo->szDeviceName) { + faxlogprintf(L"\t\tszDeviceName: %s\n", lpWowFaxInfo->szDeviceName); + } + else { + faxlogprintf(L"\t\tszDeviceName: %X\n", lpWowFaxInfo->szDeviceName); + } + faxlogprintf(L"\t\tbmPixPerByte: %X\n", lpWowFaxInfo->bmPixPerByte); + faxlogprintf(L"\t\tbmWidthBytes: %X\n", lpWowFaxInfo->bmWidthBytes); + faxlogprintf(L"\t\tbmHeight: %X\n", lpWowFaxInfo->bmHeight); + faxlogprintf(L"\t\tlpbits: %X\n", lpWowFaxInfo->lpbits); +} + +VOID LogFaxDev(LPTSTR pszTitle, LPFAXDEV lpFaxDev) +{ + DWORD dwTmp; + CHAR cTmp0, cTmp1, cTmp2, cTmp3; + + faxlogprintf(L"WOWFAXUI!%s: %X\n", pszTitle, lpFaxDev); + dwTmp = lpFaxDev->id; + cTmp3 = (CHAR) dwTmp & 0xFF; + cTmp2 = (CHAR) (dwTmp >> 8) & 0xFF; + cTmp1 = (CHAR) (dwTmp >> 16) & 0xFF; + cTmp0 = (CHAR) (dwTmp >> 24) & 0xFF; + faxlogprintf(L"\tid: %c%c%c%c\n", cTmp3, cTmp2, cTmp1, cTmp0); + faxlogprintf(L"\tlpNext: %X\n", lpFaxDev->lpNext); + faxlogprintf(L"\tlpClient: %X\n", lpFaxDev->lpClient); + faxlogprintf(L"\thdev: %X\n", lpFaxDev->hdev); + faxlogprintf(L"\tidMap: %X\n", lpFaxDev->idMap); + faxlogprintf(L"\tcbMapLow: %X\n", lpFaxDev->cbMapLow); + faxlogprintf(L"\thMap: %X\n", lpFaxDev->hMap); + faxlogprintf(L"\tszMap: %s\n", lpFaxDev->szMap); + if (lpFaxDev->lpMap) { + LogWowFaxInfo(lpFaxDev->lpMap); + } + else { + faxlogprintf(L"\tlpMap: %X\n", lpFaxDev->lpMap); + } + faxlogprintf(L"\toffbits: %X\n", lpFaxDev->offbits); + faxlogprintf(L"\thbm: %X\n", lpFaxDev->hbm); + faxlogprintf(L"\tcPixPerByte: %X\n", lpFaxDev->cPixPerByte); + faxlogprintf(L"\tbmFormat: %X\n", lpFaxDev->bmFormat); + faxlogprintf(L"\tbmWidthBytes: %X\n", lpFaxDev->bmWidthBytes); + faxlogprintf(L"\thbmSurf: %X\n", lpFaxDev->hbmSurf); + faxlogprintf(L"\thwnd: %X\n", lpFaxDev->hwnd); + faxlogprintf(L"\ttid: %X\n", lpFaxDev->tid); + faxlogprintf(L"\tlpinfo16: %X\n", lpFaxDev->lpinfo16); + faxlogprintf(L"\thDriver: %X\n", lpFaxDev->hDriver); + faxlogprintf(L"\tStart of gdiinfo: %X\n", (DWORD)&(lpFaxDev->gdiinfo)); + faxlogprintf(L"\tStart of devinfo: %X\n", (DWORD)&(lpFaxDev->devinfo)); + faxlogprintf(L"\tpdevmode: %X\n", lpFaxDev->pdevmode); +} +#endif + +//************************************************************************ +// ValidateFaxDev - Validates the FAXDEV structure by checking the DWORD +// signature, which is a known fixed value. +// +//************************************************************************ + +BOOL ValidateFaxDev(LPFAXDEV lpFaxDev) +{ + if (lpFaxDev) { + if (lpFaxDev->id == FAXDEV_ID) { + return TRUE; + } + LOGDEBUG(0, (L"ValidateFaxDev failed, bad id, lpFaxDev: %X\n", lpFaxDev)); + } + else { + LOGDEBUG(0, (L"ValidateFaxDev failed, lpFaxDev: NULL\n")); + } + return FALSE; +} + +//*************************************************************************** +// WFLocalAlloc - Debug version of LocalAlloc. +//*************************************************************************** + +LPVOID WFLocalAlloc(DWORD dwBytes, LPWSTR lpszWhoCalled) +{ + LPVOID lpTmp; + + lpTmp = LocalAlloc(LPTR, dwBytes); + + if (lpTmp == NULL){ + LOGDEBUG(0, (L"WOWFAXUI!%s, failed on memory allocation of %d bytes\n", lpszWhoCalled, dwBytes)); + } + return(lpTmp); +} + +//*************************************************************************** +// FindWowFaxWindow - Put up a message box if you can't. +//*************************************************************************** +HWND FindWowFaxWindow(void) +{ + HWND hwnd; + PROCESS_INFORMATION ProcessInformation; + STARTUPINFO StartupInfo; + DWORD WaitStatus; + TCHAR szMsg[WOWFAX_MAX_USER_MSG_LEN]; + TCHAR szTitle[WOWFAX_MAX_USER_MSG_LEN]; + WCHAR szWowExec[] = L"WOWEXEC"; + + if ((hwnd = FindWindow(WOWFAX_CLASS, NULL)) == NULL) { + // You can't find the WowFaxWindow, try to start WOW. + RtlZeroMemory((PVOID)&StartupInfo, (DWORD)sizeof(StartupInfo)); + StartupInfo.cb = sizeof(StartupInfo); + StartupInfo.dwFlags = STARTF_USESHOWWINDOW; + StartupInfo.wShowWindow = SW_NORMAL; + + if (CreateProcess(NULL, + szWowExec, + NULL, // security + NULL, // security + FALSE, // inherit handles + CREATE_NEW_CONSOLE | CREATE_DEFAULT_ERROR_MODE, + NULL, // environment strings + NULL, // current directory + &StartupInfo, + &ProcessInformation)) { + + WaitForInputIdle(ProcessInformation.hProcess, 10*1000); + + if ((hwnd = FindWindow(WOWFAX_CLASS, NULL)) != NULL) { + return(hwnd); + } + } + + // WOW failed to start. Let user know. + if (LoadString(ghInst, WOWFAX_NAME_STR, szTitle, WOWFAX_MAX_USER_MSG_LEN)) { + if (LoadString(ghInst, WOWFAX_NOWOW_STR, szMsg, WOWFAX_MAX_USER_MSG_LEN)) { + MessageBox(hwnd, szMsg, szTitle, MB_OK); + } + } + } + return(hwnd); +} + +//************************************************************************ +// DupTokenW - Helper for Get16BitDriverInfoFromRegistry. Allocate and +// copy a token, wide format. Allocates storage for duplicate. +// wcsdup is not present in the run-times we link to. +//************************************************************************ + +LPTSTR DupTokenW(LPTSTR lpTok) +{ + LPTSTR lpRetVal = NULL; + + if (lpTok != NULL) { + lpRetVal = WFLOCALALLOC((wcslen(lpTok) + 1) * sizeof(TCHAR), L"DupTokenW"); + if (lpRetVal) { + wcscpy(lpRetVal, lpTok); + } + } + return(lpRetVal); +} + +//************************************************************************ +// Get16BitDriverInfoFromRegistry - Get the 16-bit driver info (name, port) +// from the registry where it is written by the 16-bit fax driver +// install program using an intercepted WriteProfileString. Storage is +// allocated for the returned info, and must be freed by the caller +// using Free16BitDriverInfo. See also Set16BitDriverInfoToRegistry +// in WOW32FAX.C +//************************************************************************ + +LPREGFAXDRVINFO16 Get16BitDriverInfoFromRegistry(PWSTR pDeviceName) +{ + TCHAR szRetBuf[256]; + HKEY hKey = 0; + DWORD dwType, cbBufSize = 256; + LPTSTR lpTok; + + LPREGFAXDRVINFO16 lpRetVal = WFLOCALALLOC(sizeof(REGFAXDRVINFO16), L"Get16BitDriverInfoFromRegistry"); + + if ((pDeviceName != NULL) && (lpRetVal != NULL)) { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WOW\\WowFax\\devices", + 0, KEY_READ, &hKey ) == ERROR_SUCCESS) { + + if (RegQueryValueEx(hKey, pDeviceName, 0, &dwType, (LPBYTE)szRetBuf, &cbBufSize) == ERROR_SUCCESS) { + RegCloseKey(hKey); + + // Make wcstok multi-thread safe, it stores state. + EnterCriticalSection(lpCriticalSection); + lpTok = wcstok(szRetBuf, L","); + LeaveCriticalSection(lpCriticalSection); + + if ((lpRetVal->lpDriverName = DupTokenW(lpTok)) != NULL) { + EnterCriticalSection(lpCriticalSection); + lpTok = wcstok(NULL, L","); + LeaveCriticalSection(lpCriticalSection); + lpRetVal->lpPortName = DupTokenW(lpTok); + LOGDEBUG(1, (L"WOWFAXUI!Get16BitDriverInfoFromRegistry, Name: %s, Driver: %s, Port: %s\n", pDeviceName, lpRetVal->lpDriverName, lpRetVal->lpPortName)); + return(lpRetVal); + } + } + RegCloseKey(hKey); + } + } + + if (pDeviceName) { + LOGDEBUG(0, (L"WOWFAXUI!Get16BitDriverInfoFromRegistry, failed Name: %s\n", pDeviceName)); + } + else { + LOGDEBUG(0, (L"WOWFAXUI!Get16BitDriverInfoFromRegistry, failed Name: NULL\n")); + } + + Free16BitDriverInfo(lpRetVal); + return(NULL); +} + +//************************************************************************ +// Free16BitDriverInfo - Free the 16-bit driver info allocated by +// Get16BitDriverInfoFromRegistry. +//************************************************************************ + +VOID Free16BitDriverInfo(LPREGFAXDRVINFO16 lpRegFaxDrvInfo16) +{ + if (lpRegFaxDrvInfo16) { + if (lpRegFaxDrvInfo16->lpDriverName) { + LocalFree(lpRegFaxDrvInfo16->lpDriverName); + } + if (lpRegFaxDrvInfo16->lpPortName) { + LocalFree(lpRegFaxDrvInfo16->lpPortName); + } + LocalFree(lpRegFaxDrvInfo16); + return; + } +} + +//*************************************************************************** +// InterProcCommHandler - Handles inter-process communication between +// WOWFAXUI-WOW32 and WOWFAX-WOW32. +//*************************************************************************** + +BOOL InterProcCommHandler(LPFAXDEV lpdev, UINT iAction) +{ + LPWOWFAXINFO lpT = lpdev->lpMap; + HANDLE hMap = 0; + WNDPROC wndproc; + MSG msg; + + switch (iAction) + { + case DRVFAX_SETMAPDATA: + if (lpdev->lpMap) { + // init map struct + lpdev->lpMap->status = FALSE; + lpdev->lpMap->retvalue = (DWORD)-1; + lpdev->hwnd = FindWowFaxWindow(); + lpdev->lpMap->hwnd = lpdev->hwnd; + lpdev->lpMap->msg = 0; + lpdev->lpMap->hdc = (WPARAM)lpdev->idMap; + (DWORD)lpdev->lpMap->lpinfo16 = lpdev->lpinfo16; + } + break; + + case DRVFAX_SENDTOWOW: + if (lpdev->lpMap->hwnd) { + SendMessage(lpdev->lpMap->hwnd, lpdev->lpMap->msg, (WPARAM)lpdev->idMap, 0); + } + else { + LOGDEBUG(0, (L"WOWFAXUI!InterProcCommHandler, No hwnd to send to.\n")); + } + break; + + case DRVFAX_CALLWOW: + if (lpdev->lpMap->hwnd) { + wndproc = (WNDPROC) GetWindowLongA(lpdev->lpMap->hwnd, GWL_WNDPROC); + CallWindowProc(wndproc, lpdev->lpMap->hwnd, lpdev->lpMap->msg, (WPARAM)lpdev->idMap, 0); + } + else { + LOGDEBUG(0, (L"WOWFAXUI!InterProcCommHandler, No hwnd to call to.\n")); + } + break; + + case DRVFAX_SENDNOTIFYWOW: + if (lpdev->lpMap->hwnd) { + SendNotifyMessage(lpdev->lpMap->hwnd, lpdev->lpMap->msg, (WPARAM)lpdev->idMap, 0); + + // To simulate app-modal dialog, pass message's to this threads + // windows to DefWndProc, until 16-bit fax driver UI is dismissed. + while (!lpdev->lpMap->status) { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message != WM_PAINT) { + DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam); + } + else { + DispatchMessage(&msg); + } + } + } + } + break; + + case DRVFAX_CREATEMAP: + case DRVFAX_DESTROYMAP: + if (lpdev->lpMap) { + + // destroys the current map - for both iActions + UnmapViewOfFile(lpdev->lpMap); + CloseHandle(lpdev->hMap); + lpdev->lpMap = 0; + lpdev->hMap = 0; + lpT = 0; + } + + if (iAction == DRVFAX_CREATEMAP) { + // GetFaxDataMapName is WOWFAX_INC_COMMON_CODE in wowfax.h. + GetFaxDataMapName((DWORD)lpdev->idMap, lpdev->szMap); + hMap = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, + 0, lpdev->cbMapLow, lpdev->szMap); + if (hMap) { + if (GetLastError() == ERROR_ALREADY_EXISTS) { + CloseHandle(hMap); + } + else { + lpT = (LPWOWFAXINFO)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); + if (lpT) { + lpdev->hMap = hMap; + lpdev->lpMap = lpT; + } + else { + LOGDEBUG(0, (L"WOWFAXUI!InterProcCommHandler, MapViewOfFile failed, LastError = %ld\n", GetLastError())); + CloseHandle(hMap); + } + } + } + else { + LOGDEBUG(0, (L"WOWFAXUI!InterProcCommHandler, CreateFileMapping failed, LastError = %ld\n", GetLastError())); + } + } + break; + + } //switch + + return((BOOL)lpT); +} + + |