1169f7cd7SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3169f7cd7SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4169f7cd7SAndrew Rist * or more contributor license agreements. See the NOTICE file 5169f7cd7SAndrew Rist * distributed with this work for additional information 6169f7cd7SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7169f7cd7SAndrew Rist * to you under the Apache License, Version 2.0 (the 8169f7cd7SAndrew Rist * "License"); you may not use this file except in compliance 9169f7cd7SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11169f7cd7SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13169f7cd7SAndrew Rist * Unless required by applicable law or agreed to in writing, 14169f7cd7SAndrew Rist * software distributed under the License is distributed on an 15169f7cd7SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16169f7cd7SAndrew Rist * KIND, either express or implied. See the License for the 17169f7cd7SAndrew Rist * specific language governing permissions and limitations 18169f7cd7SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20169f7cd7SAndrew Rist *************************************************************/ 21169f7cd7SAndrew Rist 22169f7cd7SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir /* 25cdf0e10cSrcweir * Description: Put MSO in a state where it can be closed using 26cdf0e10cSrcweir * automation or kill it completely 27cdf0e10cSrcweir */ 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include "stdafx.h" 30cdf0e10cSrcweir #include <stdio.h> 31cdf0e10cSrcweir 32cdf0e10cSrcweir 33cdf0e10cSrcweir void KillOffice(); 34cdf0e10cSrcweir BOOL KillAppFromWindow(HWND hWnd, char *appName); 35cdf0e10cSrcweir BOOL CloseActiveDialogs(); 36cdf0e10cSrcweir void printUsage(); 37cdf0e10cSrcweir 38cdf0e10cSrcweir //Callbacks used in closing 39cdf0e10cSrcweir BOOL CALLBACK CloseOfficeDlgProc(HWND hwndChild, LPARAM lParam); 40cdf0e10cSrcweir BOOL CALLBACK CountOfficeDlgProc(HWND hwndChild, LPARAM lParam); 41cdf0e10cSrcweir 42cdf0e10cSrcweir //Global counters for number of windows found 43cdf0e10cSrcweir int gWDDlgCount = 0; 44cdf0e10cSrcweir int gXLDlgCount = 0; 45cdf0e10cSrcweir int gPPDlgCount = 0; 46cdf0e10cSrcweir 47cdf0e10cSrcweir //Dialog window class names for excel, powerpoint and word 48cdf0e10cSrcweir //These are "Best guess" dialog names 49cdf0e10cSrcweir const char *pWordDlg2k = "bosa_sdm_Microsoft Word 9.0"; 50cdf0e10cSrcweir const char *pWordDlg2k3 = "bosa_sdm_Microsoft Office Word"; 51cdf0e10cSrcweir const char *pXLDlg2k = "bosa_sdm_XL9"; 52cdf0e10cSrcweir const char *pPPDlg2k = "#32770"; 53cdf0e10cSrcweir const char *pXLDlg2k3 = "bosa_sdm_XL9"; 54cdf0e10cSrcweir const char *pPPDlg2k3 = "#32770"; 55cdf0e10cSrcweir const char *pGenMSODlg = "bosa_sdm_Mso96"; 56cdf0e10cSrcweir //consider adding - bosa_sdm_Mso96 57cdf0e10cSrcweir 58cdf0e10cSrcweir //Command Line Argument constants 59cdf0e10cSrcweir const char *ARG_HELP = "--help"; 60cdf0e10cSrcweir const char *ARG_KILL = "--kill"; 61cdf0e10cSrcweir const char *ARG_CLOSE = "--close"; 62cdf0e10cSrcweir 63cdf0e10cSrcweir //Window class names for MSO apps - if we need to look at other office instances 64cdf0e10cSrcweir //then this list would need to be expanded 65cdf0e10cSrcweir #define NUM_WINDOWCLASSNAMES 4 66cdf0e10cSrcweir char *wndClassName[NUM_WINDOWCLASSNAMES] = {"OpusApp", "XLMAIN", "PP9FrameClass", "PP10FrameClass"}; 67cdf0e10cSrcweir 68cdf0e10cSrcweir int main(int argc, char* argv[]) 69cdf0e10cSrcweir { 70cdf0e10cSrcweir if (argc < 2) { 71cdf0e10cSrcweir printUsage(); 72cdf0e10cSrcweir return 0; 73cdf0e10cSrcweir } 74cdf0e10cSrcweir 75cdf0e10cSrcweir if (strcmpi(argv[1], ARG_HELP) == 0) { 76cdf0e10cSrcweir printUsage(); 77cdf0e10cSrcweir return 0; 78cdf0e10cSrcweir } 79cdf0e10cSrcweir 80cdf0e10cSrcweir if (strcmpi(argv[1], ARG_KILL) == 0) { 81cdf0e10cSrcweir KillOffice(); 82cdf0e10cSrcweir return 0; 83cdf0e10cSrcweir } 84cdf0e10cSrcweir 85cdf0e10cSrcweir if (strcmpi(argv[1], ARG_CLOSE) == 0) { 86cdf0e10cSrcweir CloseActiveDialogs(); 87cdf0e10cSrcweir return 0; 88cdf0e10cSrcweir } 89cdf0e10cSrcweir 90cdf0e10cSrcweir return 0; 91cdf0e10cSrcweir } 92cdf0e10cSrcweir 93cdf0e10cSrcweir /*-------------------------------------------------------------- 94*a893be29SPedro Giffuni Find the MSO window if it is available and explicitly kill it 95cdf0e10cSrcweir MSO apps in this case are Excel, Word and PP 96cdf0e10cSrcweir Use FindWindow Win32 API to detect if they are available 97cdf0e10cSrcweir 98cdf0e10cSrcweir -------------------------------------------------------------*/ 99cdf0e10cSrcweir void KillOffice() { 100cdf0e10cSrcweir HWND hWnd; 101cdf0e10cSrcweir 102cdf0e10cSrcweir for (int i=0;i<NUM_WINDOWCLASSNAMES;i++) { 103cdf0e10cSrcweir int j = 0; 104cdf0e10cSrcweir while (((hWnd = FindWindow(wndClassName[i], NULL )) != NULL) && (j < 10)) { 105cdf0e10cSrcweir KillAppFromWindow(hWnd, wndClassName[i]); 106cdf0e10cSrcweir j++; 107cdf0e10cSrcweir } 108cdf0e10cSrcweir } 109cdf0e10cSrcweir } 110cdf0e10cSrcweir 111cdf0e10cSrcweir /*-------------------------------------------------------------- 112cdf0e10cSrcweir Using window handle, get process handle and try to kill the 113cdf0e10cSrcweir app. This may not be successful if you do not have enough 114cdf0e10cSrcweir privileges to kill the app. 115cdf0e10cSrcweir 116cdf0e10cSrcweir --------------------------------------------------------------*/ 117cdf0e10cSrcweir BOOL KillAppFromWindow( 118cdf0e10cSrcweir HWND hWnd, 119cdf0e10cSrcweir char * 120cdf0e10cSrcweir #ifdef _DEBUG 121cdf0e10cSrcweir appName 122cdf0e10cSrcweir #endif 123cdf0e10cSrcweir ) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir BOOL bRet = TRUE; 126cdf0e10cSrcweir 127cdf0e10cSrcweir if(hWnd == NULL) { 128cdf0e10cSrcweir //The app doesn't appear to be running 129cdf0e10cSrcweir #ifdef _DEBUG 130cdf0e10cSrcweir printf("App %s: window not found.\n,", appName); 131cdf0e10cSrcweir #endif 132cdf0e10cSrcweir bRet = FALSE; 133cdf0e10cSrcweir } else { 134cdf0e10cSrcweir DWORD pid; // Variable to hold the process ID. 135cdf0e10cSrcweir DWORD dThread; // Variable to hold (unused) thread ID. 136cdf0e10cSrcweir dThread = GetWindowThreadProcessId(hWnd, &pid); 137cdf0e10cSrcweir HANDLE hProcess; // Handle to existing process 138cdf0e10cSrcweir 139cdf0e10cSrcweir hProcess = OpenProcess(SYNCHRONIZE | PROCESS_ALL_ACCESS, TRUE, pid); 140cdf0e10cSrcweir if (hProcess == NULL) { 141cdf0e10cSrcweir #ifdef _DEBUG 142cdf0e10cSrcweir printf("App %s : Failed to get process handle",appName); 143cdf0e10cSrcweir #endif 144cdf0e10cSrcweir bRet = FALSE; 145cdf0e10cSrcweir } else { 146cdf0e10cSrcweir if (!TerminateProcess(hProcess, 0)) { 147cdf0e10cSrcweir LPTSTR lpMsgBuf; 148cdf0e10cSrcweir FormatMessage( 149cdf0e10cSrcweir FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 150cdf0e10cSrcweir NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 151cdf0e10cSrcweir (LPTSTR) &lpMsgBuf, 0, NULL ); 152cdf0e10cSrcweir printf("%s\n", lpMsgBuf); 153cdf0e10cSrcweir LocalFree( lpMsgBuf ); 154cdf0e10cSrcweir bRet = FALSE; 155cdf0e10cSrcweir } 156cdf0e10cSrcweir #ifdef _DEBUG 157cdf0e10cSrcweir else { 158cdf0e10cSrcweir printf("Kill %s appears to be successful.\n", appName); 159cdf0e10cSrcweir } 160cdf0e10cSrcweir #endif 161cdf0e10cSrcweir } 162cdf0e10cSrcweir } 163cdf0e10cSrcweir return bRet; 164cdf0e10cSrcweir } 165cdf0e10cSrcweir 166cdf0e10cSrcweir /*-------------------------------------------------------------- 167cdf0e10cSrcweir Close the dialogs if possible based on their window class 168cdf0e10cSrcweir Use the EnumChildWindows win32 api for this 169cdf0e10cSrcweir --------------------------------------------------------------*/ 170cdf0e10cSrcweir BOOL CloseActiveDialogs() { 171cdf0e10cSrcweir char buff[1024]; 172cdf0e10cSrcweir 173cdf0e10cSrcweir gWDDlgCount = 0; 174cdf0e10cSrcweir gXLDlgCount = 0; 175cdf0e10cSrcweir gPPDlgCount = 0; 176cdf0e10cSrcweir 177cdf0e10cSrcweir EnumChildWindows(GetDesktopWindow(), CloseOfficeDlgProc, (LPARAM) 0); 178cdf0e10cSrcweir sprintf(buff, "Word: %d\tExcel: %d\tPP: %d", gWDDlgCount, gXLDlgCount, gPPDlgCount); 179cdf0e10cSrcweir return TRUE; 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir /*-------------------------------------------------------------- 183cdf0e10cSrcweir Callback for EnumChildWindows that sends close message to 184cdf0e10cSrcweir any dialogs that match window class of MSO dialogs 185cdf0e10cSrcweir 186cdf0e10cSrcweir --------------------------------------------------------------*/ 187cdf0e10cSrcweir BOOL CALLBACK CloseOfficeDlgProc(HWND hwndChild, LPARAM) 188cdf0e10cSrcweir { 189cdf0e10cSrcweir //bosa_sdm_Microsoft Word 9.0 190cdf0e10cSrcweir //bosa_sdm_XL9 191cdf0e10cSrcweir //#32770 (Dialog) 192cdf0e10cSrcweir 193cdf0e10cSrcweir char szBuff[4096]; 194cdf0e10cSrcweir if (GetClassName(hwndChild, szBuff, 4096) == 0) { 195cdf0e10cSrcweir 196cdf0e10cSrcweir } else { 197cdf0e10cSrcweir if ((strcmpi(szBuff, pWordDlg2k) == 0) || (strcmpi(szBuff, pWordDlg2k3) == 0)) { 198cdf0e10cSrcweir gWDDlgCount++; 199cdf0e10cSrcweir SendMessage(hwndChild, WM_CLOSE, 0, 0); 200cdf0e10cSrcweir } 201cdf0e10cSrcweir if (strcmpi(szBuff, pXLDlg2k) == 0) { 202cdf0e10cSrcweir gXLDlgCount++; 203cdf0e10cSrcweir SendMessage(hwndChild, WM_CLOSE, 0, 0); 204cdf0e10cSrcweir } 205cdf0e10cSrcweir if (strcmpi(szBuff, pPPDlg2k) == 0) { 206cdf0e10cSrcweir gPPDlgCount++; 207cdf0e10cSrcweir SendMessage(hwndChild, WM_CLOSE, 0, 0); 208cdf0e10cSrcweir } 209cdf0e10cSrcweir if (strcmpi(szBuff, pGenMSODlg) == 0) { 210cdf0e10cSrcweir SendMessage(hwndChild, WM_CLOSE, 0, 0); 211cdf0e10cSrcweir } 212cdf0e10cSrcweir } 213cdf0e10cSrcweir 214cdf0e10cSrcweir return TRUE; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir 218cdf0e10cSrcweir /*-------------------------------------------------------------- 219cdf0e10cSrcweir Callback for EnumChildWindows that counts numnnber of 220cdf0e10cSrcweir dialogs that match window class of MSO dialogs 221cdf0e10cSrcweir 222cdf0e10cSrcweir --------------------------------------------------------------*/ 223cdf0e10cSrcweir BOOL CALLBACK CountOfficeDlgProc(HWND hwndChild, LPARAM) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir char szBuff[4096]; 226cdf0e10cSrcweir if (GetClassName(hwndChild, szBuff, 4096) == 0) { 227cdf0e10cSrcweir 228cdf0e10cSrcweir } else { 229cdf0e10cSrcweir if ((strcmpi(szBuff, pWordDlg2k) == 0) || (strcmpi(szBuff, pWordDlg2k3) == 0)) { 230cdf0e10cSrcweir gWDDlgCount++; 231cdf0e10cSrcweir } 232cdf0e10cSrcweir if (strcmpi(szBuff, pXLDlg2k) == 0) { 233cdf0e10cSrcweir gXLDlgCount++; 234cdf0e10cSrcweir } 235cdf0e10cSrcweir if (strcmpi(szBuff, pPPDlg2k) == 0) { 236cdf0e10cSrcweir gPPDlgCount++; 237cdf0e10cSrcweir } 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir return TRUE; 241cdf0e10cSrcweir } 242cdf0e10cSrcweir 243cdf0e10cSrcweir /*-------------------------------------------------------------- 244cdf0e10cSrcweir Simple usage message... 245cdf0e10cSrcweir 246cdf0e10cSrcweir -------------------------------------------------------------*/ 247cdf0e10cSrcweir void printUsage() { 248cdf0e10cSrcweir printf("Recovery Assistant Utility - try and put MSO apps in a recoverable state\n"); 249cdf0e10cSrcweir printf("Copyright Sun Microsystems 2008\n"); 250cdf0e10cSrcweir printf("Options:\n"); 251cdf0e10cSrcweir printf(" --help : This message\n"); 252cdf0e10cSrcweir printf(" --close: Attempt to close any open dialogs owned by \n"); 253cdf0e10cSrcweir printf(" MSO apps so Application.Quit() can succeed\n"); 254cdf0e10cSrcweir printf(" --kill : Kill any open MSO apps. Use with caution and only as a last resort\n\n"); 255cdf0e10cSrcweir }