diff options
Diffstat (limited to 'migrationanalysis/src/msokill/msokill.cpp')
-rw-r--r-- | migrationanalysis/src/msokill/msokill.cpp | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/migrationanalysis/src/msokill/msokill.cpp b/migrationanalysis/src/msokill/msokill.cpp new file mode 100644 index 000000000000..2125b3f773c7 --- /dev/null +++ b/migrationanalysis/src/msokill/msokill.cpp @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/* + * Description: Put MSO in a state where it can be closed using + * automation or kill it completely + */ + +#include "stdafx.h" +#include <stdio.h> + + +void KillOffice(); +BOOL KillAppFromWindow(HWND hWnd, char *appName); +BOOL CloseActiveDialogs(); +void printUsage(); + +//Callbacks used in closing +BOOL CALLBACK CloseOfficeDlgProc(HWND hwndChild, LPARAM lParam); +BOOL CALLBACK CountOfficeDlgProc(HWND hwndChild, LPARAM lParam); + +//Global counters for number of windows found +int gWDDlgCount = 0; +int gXLDlgCount = 0; +int gPPDlgCount = 0; + +//Dialog window class names for excel, powerpoint and word +//These are "Best guess" dialog names +const char *pWordDlg2k = "bosa_sdm_Microsoft Word 9.0"; +const char *pWordDlg2k3 = "bosa_sdm_Microsoft Office Word"; +const char *pXLDlg2k = "bosa_sdm_XL9"; +const char *pPPDlg2k = "#32770"; +const char *pXLDlg2k3 = "bosa_sdm_XL9"; +const char *pPPDlg2k3 = "#32770"; +const char *pGenMSODlg = "bosa_sdm_Mso96"; +//consider adding - bosa_sdm_Mso96 + +//Command Line Argument constants +const char *ARG_HELP = "--help"; +const char *ARG_KILL = "--kill"; +const char *ARG_CLOSE = "--close"; + +//Window class names for MSO apps - if we need to look at other office instances +//then this list would need to be expanded +#define NUM_WINDOWCLASSNAMES 4 +char *wndClassName[NUM_WINDOWCLASSNAMES] = {"OpusApp", "XLMAIN", "PP9FrameClass", "PP10FrameClass"}; + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + printUsage(); + return 0; + } + + if (strcmpi(argv[1], ARG_HELP) == 0) { + printUsage(); + return 0; + } + + if (strcmpi(argv[1], ARG_KILL) == 0) { + KillOffice(); + return 0; + } + + if (strcmpi(argv[1], ARG_CLOSE) == 0) { + CloseActiveDialogs(); + return 0; + } + + return 0; +} + +/*-------------------------------------------------------------- + Find the MSO window if it is available and explictly kill it + MSO apps in this case are Excel, Word and PP + Use FindWindow Win32 API to detect if they are available + + -------------------------------------------------------------*/ +void KillOffice() { + HWND hWnd; + + for (int i=0;i<NUM_WINDOWCLASSNAMES;i++) { + int j = 0; + while (((hWnd = FindWindow(wndClassName[i], NULL )) != NULL) && (j < 10)) { + KillAppFromWindow(hWnd, wndClassName[i]); + j++; + } + } +} + +/*-------------------------------------------------------------- + Using window handle, get process handle and try to kill the + app. This may not be successful if you do not have enough + privileges to kill the app. + + --------------------------------------------------------------*/ +BOOL KillAppFromWindow( + HWND hWnd, + char * +#ifdef _DEBUG + appName +#endif +) +{ + BOOL bRet = TRUE; + + if(hWnd == NULL) { + //The app doesn't appear to be running +#ifdef _DEBUG + printf("App %s: window not found.\n,", appName); +#endif + bRet = FALSE; + } else { + DWORD pid; // Variable to hold the process ID. + DWORD dThread; // Variable to hold (unused) thread ID. + dThread = GetWindowThreadProcessId(hWnd, &pid); + HANDLE hProcess; // Handle to existing process + + hProcess = OpenProcess(SYNCHRONIZE | PROCESS_ALL_ACCESS, TRUE, pid); + if (hProcess == NULL) { +#ifdef _DEBUG + printf("App %s : Failed to get process handle",appName); +#endif + bRet = FALSE; + } else { + if (!TerminateProcess(hProcess, 0)) { + LPTSTR lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, 0, NULL ); + printf("%s\n", lpMsgBuf); + LocalFree( lpMsgBuf ); + bRet = FALSE; + } +#ifdef _DEBUG + else { + printf("Kill %s appears to be successful.\n", appName); + } +#endif + } + } + return bRet; +} + +/*-------------------------------------------------------------- + Close the dialogs if possible based on their window class + Use the EnumChildWindows win32 api for this + --------------------------------------------------------------*/ +BOOL CloseActiveDialogs() { + char buff[1024]; + + gWDDlgCount = 0; + gXLDlgCount = 0; + gPPDlgCount = 0; + + EnumChildWindows(GetDesktopWindow(), CloseOfficeDlgProc, (LPARAM) 0); + sprintf(buff, "Word: %d\tExcel: %d\tPP: %d", gWDDlgCount, gXLDlgCount, gPPDlgCount); + return TRUE; +} + +/*-------------------------------------------------------------- + Callback for EnumChildWindows that sends close message to + any dialogs that match window class of MSO dialogs + + --------------------------------------------------------------*/ +BOOL CALLBACK CloseOfficeDlgProc(HWND hwndChild, LPARAM) +{ + //bosa_sdm_Microsoft Word 9.0 + //bosa_sdm_XL9 + //#32770 (Dialog) + + char szBuff[4096]; + if (GetClassName(hwndChild, szBuff, 4096) == 0) { + + } else { + if ((strcmpi(szBuff, pWordDlg2k) == 0) || (strcmpi(szBuff, pWordDlg2k3) == 0)) { + gWDDlgCount++; + SendMessage(hwndChild, WM_CLOSE, 0, 0); + } + if (strcmpi(szBuff, pXLDlg2k) == 0) { + gXLDlgCount++; + SendMessage(hwndChild, WM_CLOSE, 0, 0); + } + if (strcmpi(szBuff, pPPDlg2k) == 0) { + gPPDlgCount++; + SendMessage(hwndChild, WM_CLOSE, 0, 0); + } + if (strcmpi(szBuff, pGenMSODlg) == 0) { + SendMessage(hwndChild, WM_CLOSE, 0, 0); + } + } + + return TRUE; +} + + +/*-------------------------------------------------------------- + Callback for EnumChildWindows that counts numnnber of + dialogs that match window class of MSO dialogs + + --------------------------------------------------------------*/ +BOOL CALLBACK CountOfficeDlgProc(HWND hwndChild, LPARAM) +{ + char szBuff[4096]; + if (GetClassName(hwndChild, szBuff, 4096) == 0) { + + } else { + if ((strcmpi(szBuff, pWordDlg2k) == 0) || (strcmpi(szBuff, pWordDlg2k3) == 0)) { + gWDDlgCount++; + } + if (strcmpi(szBuff, pXLDlg2k) == 0) { + gXLDlgCount++; + } + if (strcmpi(szBuff, pPPDlg2k) == 0) { + gPPDlgCount++; + } + } + + return TRUE; +} + +/*-------------------------------------------------------------- + Simple usage message... + + -------------------------------------------------------------*/ +void printUsage() { + printf("Recovery Assistant Utility - try and put MSO apps in a recoverable state\n"); + printf("Copyright Sun Microsystems 2008\n"); + printf("Options:\n"); + printf(" --help : This message\n"); + printf(" --close: Attempt to close any open dialogs owned by \n"); + printf(" MSO apps so Application.Quit() can succeed\n"); + printf(" --kill : Kill any open MSO apps. Use with caution and only as a last resort\n\n"); +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |