1*169f7cd7SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*169f7cd7SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*169f7cd7SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*169f7cd7SAndrew Rist * distributed with this work for additional information
6*169f7cd7SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*169f7cd7SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*169f7cd7SAndrew Rist * "License"); you may not use this file except in compliance
9*169f7cd7SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*169f7cd7SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*169f7cd7SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*169f7cd7SAndrew Rist * software distributed under the License is distributed on an
15*169f7cd7SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*169f7cd7SAndrew Rist * KIND, either express or implied. See the License for the
17*169f7cd7SAndrew Rist * specific language governing permissions and limitations
18*169f7cd7SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*169f7cd7SAndrew Rist *************************************************************/
21*169f7cd7SAndrew Rist
22*169f7cd7SAndrew 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
main(int argc,char * argv[])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 /*--------------------------------------------------------------
94cdf0e10cSrcweir Find the MSO window if it is available and explictly 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 -------------------------------------------------------------*/
KillOffice()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 --------------------------------------------------------------*/
KillAppFromWindow(HWND hWnd,char * appName)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 --------------------------------------------------------------*/
CloseActiveDialogs()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 --------------------------------------------------------------*/
CloseOfficeDlgProc(HWND hwndChild,LPARAM)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 --------------------------------------------------------------*/
CountOfficeDlgProc(HWND hwndChild,LPARAM)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 -------------------------------------------------------------*/
printUsage()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 }