/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ // // Various utils needed for the MAPI functions // Written by: Rich Pizzarro (rhp@netscape.com) // November 1997 // #include #include #include #include #include "xpapi.h" #include "trace.h" #include "mapiipc.h" #include "mapiutl.h" #include "resource.h" #define ONE_SEC 20 #define STARTUP "Start" #define STARTUP_TIME 20 #define EXIT "Exit" #define EXIT_TIME 10 // // Global variables // BOOL gLoggingEnabled = FALSE; DWORD GetPauseTime(LPSTR attrib) { DWORD val = 0; if (!GetConfigInfoNum(szMapiSection, attrib, &val, HKEY_LOCAL_MACHINE)) { if (lstrcmp(attrib, STARTUP) == 0) val = STARTUP_TIME; else if (lstrcmp(attrib, EXIT) == 0) val = EXIT_TIME; else val = STARTUP_TIME; } return val; } void FlushIt(void) { /* get the next message, if any */ MSG msg; BOOL ret; /* if we got one, process it */ while ((ret = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) == TRUE) { TranslateMessage(&msg); DispatchMessage(&msg); } } #ifdef WIN16 void Win16Sleep(DWORD sleepTime) { MSG msg; BOOL ret; DWORD startTick = GetTickCount(); while ( (GetTickCount() - startTick) < sleepTime ) { ret = (BOOL)PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); if (ret) { TranslateMessage(&msg); DispatchMessage(&msg); } else { Yield(); } } } #endif void SetLoggingEnabled(BOOL val) { gLoggingEnabled = val; } // Log File void LogString(LPCSTR pStr1) { // Off of the declaration line... LPCSTR pStr2 = NULL; BOOL useStr1 = TRUE; if (gLoggingEnabled) { char tempPath[_MAX_PATH] = ""; if (getenv("TEMP")) { lstrcpy((LPSTR) tempPath, getenv("TEMP")); // environmental variable } int len = lstrlen(tempPath); if ((len > 1) && tempPath[len - 1] != '\\') { lstrcat(tempPath, "\\"); } lstrcat(tempPath, szMapiLog); HFILE hFile = _lopen(tempPath, OF_WRITE); if (hFile == HFILE_ERROR) { hFile = _lcreat(tempPath, 0); } if (hFile != HFILE_ERROR) { _llseek(hFile, 0, SEEK_END); // seek to the end of the file LPCSTR pTemp = useStr1 ? pStr1 : pStr2; _lwrite(hFile, pTemp, lstrlen(pTemp)); _lclose(hFile); } } } void BuildMemName(LPSTR name, ULONG winSeed) { static DWORD id = 0; if (id == 0) { // Seed the random-number generator with current time so that // the numbers will be different every time we run. srand( (unsigned)time( NULL ) ); id = rand(); } wsprintf(name, "MAPI_IPC_SMEM-%d", (winSeed + id++)); TRACE("Shared Memory Name = [%s]\n", name); } DWORD ValidateFile(LPCSTR szFile) { struct _stat buf; int result; result = _stat( szFile, &buf ); if (result != 0) return(1); if (!(buf.st_mode & S_IREAD)) return(2); return(0); } // // return of zero is ok // 1 = MAPI_E_ATTACHMENT_NOT_FOUND // 2 = MAPI_E_ATTACHMENT_OPEN_FAILURE // DWORD SanityCheckAttachmentFiles(lpMapiMessage lpMessage) { ULONG i; DWORD rc; for (i=0; inFileCount; i++) { if ((rc = ValidateFile(lpMessage->lpFiles[i].lpszPathName)) != 0) { return(rc); } } return(0); } DWORD GetFileCount(LPSTR pFiles, LPSTR delimChar) { DWORD count = 1; if ((!pFiles) || (!*pFiles)) return(0); for (DWORD i=0; i= strlen(pFiles)) // Got to the end of string! return(FALSE); lstrcpy(fName, (LPSTR)pFiles + loc); // // Truncate at 2nd delimiter // for (DWORD i=0; i tag if ( (i+strlen(endTag)) < len) { if (strncmp(endTag, ptr, strlen(endTag)) == 0) { break; } } // If we are in HTML, check for a ">"... if (inHTML) { if (*ptr == '>') { inHTML = FALSE; } continue; } // Check for NEW HTML... if (*ptr == '<') { inHTML = TRUE; continue; } if (CheckForInlineHTML(ptr, len, &i, newBuf, &realLen)) continue; newBuf[realLen++] = *ptr; // Tack on a line feed if we hit a CR... if ( *ptr == 0x0D ) { newBuf[realLen++] = 0x0A; } } // terminate the buffer - reallocate and move on... newBuf[realLen++] = '\0'; newBuf = (LPSTR) realloc(newBuf, (size_t) realLen); // check if the realloc worked and if so, free old memory and // return...if not, just return the original buffer if (!newBuf) { return(noteText); } else { free(noteText); return(newBuf); } } // // RICHIE - this is a temporary fix for now to get rid of // html stuff within the text of a message - if there was a // valid noteText buffer coming into this call, we need to // free it on the way out. // LPSTR StripHTML(LPSTR noteText) { char *newBuf; LPSTR signTag = "This is a cryptographically signed message in MIME format."; LPSTR mimeTag = "This is a multi-part message in MIME format."; DWORD i; DWORD realLen = 0; DWORD totalCR = 0; // do sanity checking... if ((!noteText) || (!(*noteText))) return(noteText); // more sanity checking... DWORD len = strlen(noteText) + 1; if (len <= 0) return(noteText); // Get the number of CR's in this message and add room for // the LF's for (i=0; i= MAXTRY) return(1); goto TRYAGAIN; } return res; } #define kMaxTempFiles 10 #define kMaxListLength (10 * _MAX_PATH) void GetTempFiles(LPSTR pBuf, int lenBuf) { if (!GetConfigInfoStr(szMapiSection, szTempFiles, pBuf, lenBuf, HKEY_CURRENT_USER)) { *pBuf = 0; } } void WriteTempFiles(LPSTR pBuf) { SetConfigInfoStr(szMapiSection, szTempFiles, pBuf, HKEY_CURRENT_USER); /* HKEY_ROOT); - permission problem */ } void AddTempFile(LPCSTR pFileName) { char files[kMaxListLength]; GetTempFiles(files, sizeof(files)); if ((lstrlen(files) + lstrlen(pFileName) + 2) >= sizeof(files)) { return; } if (lstrlen(files) != 0) { lstrcat(files, ";"); } lstrcat(files, pFileName); WriteTempFiles(files); } void DeleteFirstTempFile(LPSTR pFiles) { if (!*pFiles) return; LPSTR pTemp = strchr(pFiles, ';'); if (pTemp) { *pTemp = 0; } _unlink(pFiles); if (pTemp) { memmove(pFiles, pTemp + 1, lstrlen(pTemp + 1) + 1); } else { *pFiles = 0; } } void RemoveAllTempFiles(void) { char files[kMaxListLength]; GetTempFiles(files, sizeof(files)); while (*files) { DeleteFirstTempFile(files); } WriteTempFiles(files); } void CheckAgeTempFiles(void) { char files[kMaxListLength]; GetTempFiles(files, sizeof(files)); int i = 0; LPSTR pTemp = files; while (TRUE) { pTemp = strchr(pTemp, ';'); if (!pTemp) break; ++pTemp; ++i; } if (i >= 4) { DeleteFirstTempFile(files); WriteTempFiles(files); } } // Need this to make sure that we can kill all temp files... // Enum all windows and check title for "Composition"... BOOL foundItRunning = FALSE; BOOL CALLBACK EnumWindowsProc(HWND hwnd, // handle to parent window LPARAM lParam) // application-defined value { UINT msg = RegisterWindowMessage(MAPI_CUSTOM_COMPOSE_MSG); // Need to do this to avoid SendMessage() causing recursion DWORD otherID; DWORD myID = GetCurrentProcessId(); (void) GetWindowThreadProcessId(hwnd, &otherID); if (myID == otherID) return TRUE; LONG rc = SendMessage(hwnd, msg, 0, 0); if (rc == MAPI_CUSTOM_RET_CODE) { foundItRunning = TRUE; return FALSE; } return TRUE; } BOOL CompositionWindowRunning(void) { foundItRunning = FALSE; if (Is_16_OR_32_BIT_CommunitorRunning() == 0) return FALSE; (void) EnumWindows(EnumWindowsProc, NULL); return (foundItRunning); } void CleanupMAPITempFiles(void) { if (!CompositionWindowRunning()) { RemoveAllTempFiles(); // if Communicator not running, clean up all the temp files } else { CheckAgeTempFiles(); } } #define EXITING -10 //multi-instance code return values #define RUNNING 10 const UINT NEAR msg_IPCStatus = RegisterWindowMessage("NetscapeIPCMsg"); const UINT NEAR msg_ExitStatus = RegisterWindowMessage("ExitingNetscape"); HWND GetTheValidWindow(void) { HWND hWnd = NULL; DWORD waitTime = GetPauseTime(STARTUP); DWORD timeCount = 0; while ( ((hWnd = FindWindow("aHiddenFrameClass", NULL)) != NULL) && (timeCount < ( (ONE_SEC * waitTime) / 2) ) ) { if (SendMessage(hWnd, msg_IPCStatus, 0, 0) == 19) { if (SendMessage(hWnd, msg_ExitStatus, 0, 0) == EXITING) return NULL; else { return hWnd; } } else { timeCount++; } FlushIt(); Sleep(50); } return NULL; } // // Find Communicator and return an HWND, if not, start Communicator, // then find an HWND // HWND GetCommunicatorIPCWindow(BOOL justBail) { HWND hWnd = NULL; DWORD timeCount = 0; hWnd = GetTheValidWindow(); if (hWnd != NULL) return hWnd; if (justBail) return NULL; char szPath[_MAX_PATH] = ""; DWORD nMAPIERROR; if ((nMAPIERROR = XP_GetInstallLocation(szPath, _MAX_PATH)) != SUCCESS_SUCCESS) return(NULL); TRACE("STARTING COMMUNICATOR\n"); if (!XP_CallProcess(szPath, " -MAPICLIENT")) { TRACE("FAILED TO COMMUNICATOR\n"); return(NULL); } DWORD waitTime = GetPauseTime(STARTUP); TRACE("WAIT FOR COMMUNICATOR TO START UP!\n"); TRACE("WAITING %d SECONDS FOR COMMUNICATOR\n", waitTime); while ( (Is_16_OR_32_BIT_CommunitorRunning() == 0) && (timeCount < (ONE_SEC * waitTime) ) ) { #ifdef WIN32 FlushIt(); Sleep(50); #else Win16Sleep(50); #endif timeCount++; } return(GetTheValidWindow()); }