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