update dev300-m58
[ooovba.git] / migrationanalysis / src / msokill / msokill.cpp
blob9d58a6a4a6886ee7f792c9360e3369968f8d644e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: msokill.cpp,v $
11 * This file is part of OpenOffice.org.
13 * OpenOffice.org is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License version 3
15 * only, as published by the Free Software Foundation.
17 * OpenOffice.org is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License version 3 for more details
21 * (a copy is included in the LICENSE file that accompanied this code).
23 * You should have received a copy of the GNU Lesser General Public License
24 * version 3 along with OpenOffice.org. If not, see
25 * <http://www.openoffice.org/license.html>
26 * for a copy of the LGPLv3 License.
28 ************************************************************************/
31 * Description: Put MSO in a state where it can be closed using
32 * automation or kill it completely
35 #include "stdafx.h"
36 #include <stdio.h>
39 void KillOffice();
40 BOOL KillAppFromWindow(HWND hWnd, char *appName);
41 BOOL CloseActiveDialogs();
42 void printUsage();
44 //Callbacks used in closing
45 BOOL CALLBACK CloseOfficeDlgProc(HWND hwndChild, LPARAM lParam);
46 BOOL CALLBACK CountOfficeDlgProc(HWND hwndChild, LPARAM lParam);
48 //Global counters for number of windows found
49 int gWDDlgCount = 0;
50 int gXLDlgCount = 0;
51 int gPPDlgCount = 0;
53 //Dialog window class names for excel, powerpoint and word
54 //These are "Best guess" dialog names
55 const char *pWordDlg2k = "bosa_sdm_Microsoft Word 9.0";
56 const char *pWordDlg2k3 = "bosa_sdm_Microsoft Office Word";
57 const char *pXLDlg2k = "bosa_sdm_XL9";
58 const char *pPPDlg2k = "#32770";
59 const char *pXLDlg2k3 = "bosa_sdm_XL9";
60 const char *pPPDlg2k3 = "#32770";
61 const char *pGenMSODlg = "bosa_sdm_Mso96";
62 //consider adding - bosa_sdm_Mso96
64 //Command Line Argument constants
65 const char *ARG_HELP = "--help";
66 const char *ARG_KILL = "--kill";
67 const char *ARG_CLOSE = "--close";
69 //Window class names for MSO apps - if we need to look at other office instances
70 //then this list would need to be expanded
71 #define NUM_WINDOWCLASSNAMES 4
72 char *wndClassName[NUM_WINDOWCLASSNAMES] = {"OpusApp", "XLMAIN", "PP9FrameClass", "PP10FrameClass"};
74 int main(int argc, char* argv[])
76 if (argc < 2) {
77 printUsage();
78 return 0;
81 if (strcmpi(argv[1], ARG_HELP) == 0) {
82 printUsage();
83 return 0;
86 if (strcmpi(argv[1], ARG_KILL) == 0) {
87 KillOffice();
88 return 0;
91 if (strcmpi(argv[1], ARG_CLOSE) == 0) {
92 CloseActiveDialogs();
93 return 0;
96 return 0;
99 /*--------------------------------------------------------------
100 Find the MSO window if it is available and explictly kill it
101 MSO apps in this case are Excel, Word and PP
102 Use FindWindow Win32 API to detect if they are available
104 -------------------------------------------------------------*/
105 void KillOffice() {
106 HWND hWnd;
108 for (int i=0;i<NUM_WINDOWCLASSNAMES;i++) {
109 int j = 0;
110 while (((hWnd = FindWindow(wndClassName[i], NULL )) != NULL) && (j < 10)) {
111 KillAppFromWindow(hWnd, wndClassName[i]);
112 j++;
117 /*--------------------------------------------------------------
118 Using window handle, get process handle and try to kill the
119 app. This may not be successful if you do not have enough
120 privileges to kill the app.
122 --------------------------------------------------------------*/
123 BOOL KillAppFromWindow(
124 HWND hWnd,
125 char *
126 #ifdef _DEBUG
127 appName
128 #endif
131 BOOL bRet = TRUE;
133 if(hWnd == NULL) {
134 //The app doesn't appear to be running
135 #ifdef _DEBUG
136 printf("App %s: window not found.\n,", appName);
137 #endif
138 bRet = FALSE;
139 } else {
140 DWORD pid; // Variable to hold the process ID.
141 DWORD dThread; // Variable to hold (unused) thread ID.
142 dThread = GetWindowThreadProcessId(hWnd, &pid);
143 HANDLE hProcess; // Handle to existing process
145 hProcess = OpenProcess(SYNCHRONIZE | PROCESS_ALL_ACCESS, TRUE, pid);
146 if (hProcess == NULL) {
147 #ifdef _DEBUG
148 printf("App %s : Failed to get process handle",appName);
149 #endif
150 bRet = FALSE;
151 } else {
152 if (!TerminateProcess(hProcess, 0)) {
153 LPTSTR lpMsgBuf;
154 FormatMessage(
155 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
156 NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
157 (LPTSTR) &lpMsgBuf, 0, NULL );
158 printf("%s\n", lpMsgBuf);
159 LocalFree( lpMsgBuf );
160 bRet = FALSE;
162 #ifdef _DEBUG
163 else {
164 printf("Kill %s appears to be successful.\n", appName);
166 #endif
169 return bRet;
172 /*--------------------------------------------------------------
173 Close the dialogs if possible based on their window class
174 Use the EnumChildWindows win32 api for this
175 --------------------------------------------------------------*/
176 BOOL CloseActiveDialogs() {
177 char buff[1024];
179 gWDDlgCount = 0;
180 gXLDlgCount = 0;
181 gPPDlgCount = 0;
183 EnumChildWindows(GetDesktopWindow(), CloseOfficeDlgProc, (LPARAM) 0);
184 sprintf(buff, "Word: %d\tExcel: %d\tPP: %d", gWDDlgCount, gXLDlgCount, gPPDlgCount);
185 return TRUE;
188 /*--------------------------------------------------------------
189 Callback for EnumChildWindows that sends close message to
190 any dialogs that match window class of MSO dialogs
192 --------------------------------------------------------------*/
193 BOOL CALLBACK CloseOfficeDlgProc(HWND hwndChild, LPARAM)
195 //bosa_sdm_Microsoft Word 9.0
196 //bosa_sdm_XL9
197 //#32770 (Dialog)
199 char szBuff[4096];
200 if (GetClassName(hwndChild, szBuff, 4096) == 0) {
202 } else {
203 if ((strcmpi(szBuff, pWordDlg2k) == 0) || (strcmpi(szBuff, pWordDlg2k3) == 0)) {
204 gWDDlgCount++;
205 SendMessage(hwndChild, WM_CLOSE, 0, 0);
207 if (strcmpi(szBuff, pXLDlg2k) == 0) {
208 gXLDlgCount++;
209 SendMessage(hwndChild, WM_CLOSE, 0, 0);
211 if (strcmpi(szBuff, pPPDlg2k) == 0) {
212 gPPDlgCount++;
213 SendMessage(hwndChild, WM_CLOSE, 0, 0);
215 if (strcmpi(szBuff, pGenMSODlg) == 0) {
216 SendMessage(hwndChild, WM_CLOSE, 0, 0);
220 return TRUE;
224 /*--------------------------------------------------------------
225 Callback for EnumChildWindows that counts numnnber of
226 dialogs that match window class of MSO dialogs
228 --------------------------------------------------------------*/
229 BOOL CALLBACK CountOfficeDlgProc(HWND hwndChild, LPARAM)
231 char szBuff[4096];
232 if (GetClassName(hwndChild, szBuff, 4096) == 0) {
234 } else {
235 if ((strcmpi(szBuff, pWordDlg2k) == 0) || (strcmpi(szBuff, pWordDlg2k3) == 0)) {
236 gWDDlgCount++;
238 if (strcmpi(szBuff, pXLDlg2k) == 0) {
239 gXLDlgCount++;
241 if (strcmpi(szBuff, pPPDlg2k) == 0) {
242 gPPDlgCount++;
246 return TRUE;
249 /*--------------------------------------------------------------
250 Simple usage message...
252 -------------------------------------------------------------*/
253 void printUsage() {
254 printf("Recovery Assistant Utility - try and put MSO apps in a recoverable state\n");
255 printf("Copyright Sun Microsystems 2008\n");
256 printf("Options:\n");
257 printf(" --help : This message\n");
258 printf(" --close: Attempt to close any open dialogs owned by \n");
259 printf(" MSO apps so Application.Quit() can succeed\n");
260 printf(" --kill : Kill any open MSO apps. Use with caution and only as a last resort\n\n");