LEFT | RIGHT |
1 /** | 1 /** |
2 * \file close_application.cpp | 2 * \file close_application.cpp |
3 */ | 3 */ |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "session.h" | 7 #include "session.h" |
8 #include "property.h" | 8 #include "property.h" |
9 #include "database.h" | 9 #include "database.h" |
10 #include "process.h" | 10 #include "process.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 ProcessCloser browserCloser ; | 23 ProcessCloser browserCloser ; |
24 | 24 |
25 ProcessCloser engineCloser ; | 25 ProcessCloser engineCloser ; |
26 | 26 |
27 public: | 27 public: |
28 InternetExplorerCloser() | 28 InternetExplorerCloser() |
29 : snapshot(), browserCloser( snapshot, browserNames ), engineCloser( snapsho
t, engineNames ) | 29 : snapshot(), browserCloser( snapshot, browserNames ), engineCloser( snapsho
t, engineNames ) |
30 {} | 30 {} |
31 | 31 |
32 void refresh() | 32 void Refresh() |
33 { | 33 { |
34 snapshot.refresh() ; | 34 snapshot.Refresh() ; |
35 browserCloser.refresh() ; | 35 browserCloser.Refresh() ; |
36 engineCloser.refresh() ; | 36 engineCloser.Refresh() ; |
37 } | 37 } |
38 | 38 |
39 bool IsRunning() | 39 bool IsRunning() |
40 { | 40 { |
41 return browserCloser.IsRunning() || engineCloser.IsRunning() ; | 41 return browserCloser.IsRunning() || engineCloser.IsRunning() ; |
42 } | 42 } |
43 | 43 |
44 bool shutDown() | 44 bool ShutDown() |
45 { | 45 { |
46 if ( browserCloser.IsRunning() && ! browserCloser.shutDown() ) | 46 if ( browserCloser.IsRunning() && ! browserCloser.ShutDown() ) |
47 { | 47 { |
48 // Assert IE is still running | 48 // Assert IE is still running |
49 // This is after we've tried to shut it down, so we fail | 49 // This is after we've tried to shut it down, so we fail |
50 return false ; | 50 return false ; |
51 } | 51 } |
52 if ( engineCloser.IsRunning() && ! engineCloser.shutDown() ) | 52 if ( engineCloser.IsRunning() && ! engineCloser.ShutDown() ) |
53 { | 53 { |
54 // Assert the engine is still running | 54 // Assert the engine is still running |
55 // This is after IE has shut down itself and after we've tried to shut dow
n the engine. Whatever. | 55 // This is after IE has shut down itself and after we've tried to shut dow
n the engine. Whatever. |
56 return false ; | 56 return false ; |
57 } | 57 } |
58 return true ; | 58 return true ; |
59 } | 59 } |
60 } ; | 60 } ; |
61 | 61 |
62 | 62 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 // Instantiation of ProcessCloser takes a snapshot. | 128 // Instantiation of ProcessCloser takes a snapshot. |
129 InternetExplorerCloser iec ; | 129 InternetExplorerCloser iec ; |
130 | 130 |
131 /* | 131 /* |
132 * We take the short path through this function if neither IE nor engine is
not running at the outset. | 132 * We take the short path through this function if neither IE nor engine is
not running at the outset. |
133 */ | 133 */ |
134 if ( ! iec.IsRunning() ) | 134 if ( ! iec.IsRunning() ) |
135 { | 135 { |
136 browserRunning = L"0" ; // The browser is not running. | 136 browserRunning = L"0" ; // The browser is not running. |
137 browserClosed = L"0" ; // We didn't close the browser (and we could
n't have). | 137 browserClosed = L"0" ; // We didn't close the browser (and we could
n't have). |
138 session.log( "IE not running. No issue with reboot policy." ) ; | 138 session.Log( "IE not running. No issue with reboot policy." ) ; |
139 return ERROR_SUCCESS ; | 139 return ERROR_SUCCESS ; |
140 } | 140 } |
141 | 141 |
142 /* | 142 /* |
143 * As a (potentially) user-driven function, a state machine manages control
flow. | 143 * As a (potentially) user-driven function, a state machine manages control
flow. |
144 * The states are organized around the policy stances. | 144 * The states are organized around the policy stances. |
145 */ | 145 */ |
146 enum PolicyState { | 146 enum PolicyState { |
147 // Non-terminal states | 147 // Non-terminal states |
148 notKnown, // We don't know the user's stance at all | 148 notKnown, // We don't know the user's stance at all |
(...skipping 15 matching lines...) Expand all Loading... |
164 */ | 164 */ |
165 std::wstring avoidReboot = Property( session, L"AVOIDREBOOT" ) ; | 165 std::wstring avoidReboot = Property( session, L"AVOIDREBOOT" ) ; |
166 std::transform( avoidReboot.begin(), avoidReboot.end(), avoidReboot.begin(),
::towupper ) ; | 166 std::transform( avoidReboot.begin(), avoidReboot.end(), avoidReboot.begin(),
::towupper ) ; |
167 if ( avoidReboot == L"" ) | 167 if ( avoidReboot == L"" ) |
168 { | 168 { |
169 state = notKnown ; | 169 state = notKnown ; |
170 } | 170 } |
171 else if ( avoidReboot == L"NO" ) | 171 else if ( avoidReboot == L"NO" ) |
172 { | 172 { |
173 state = allow ; | 173 state = allow ; |
174 session.log( "Reboot allowed on command line." ) ; | 174 session.Log( "Reboot allowed on command line." ) ; |
175 } | 175 } |
176 else if ( avoidReboot == L"PASSIVE" ) | 176 else if ( avoidReboot == L"PASSIVE" ) |
177 { | 177 { |
178 state = passive ; | 178 state = passive ; |
179 session.log( "Reboot avoided on command line." ) ; | 179 session.Log( "Reboot avoided on command line." ) ; |
180 } | 180 } |
181 else if ( avoidReboot == L"ACTIVE" ) | 181 else if ( avoidReboot == L"ACTIVE" ) |
182 { | 182 { |
183 state = active ; | 183 state = active ; |
184 } | 184 } |
185 else if ( avoidReboot == L"AUTOMATIC" ) | 185 else if ( avoidReboot == L"AUTOMATIC" ) |
186 { | 186 { |
187 state = automatic ; | 187 state = automatic ; |
188 } | 188 } |
189 else | 189 else |
(...skipping 26 matching lines...) Expand all Loading... |
216 // Assert installer is running without user interaction. | 216 // Assert installer is running without user interaction. |
217 interactive = false ; | 217 interactive = false ; |
218 if ( state == notKnown ) | 218 if ( state == notKnown ) |
219 { | 219 { |
220 // Assert AVOIDREBOOT was not specified | 220 // Assert AVOIDREBOOT was not specified |
221 /* | 221 /* |
222 * This is where we specify default behavior for non-interactive operati
on. | 222 * This is where we specify default behavior for non-interactive operati
on. |
223 * The choice of "allow" makes it act like other installers, which is to
make no effort to avoid a reboot after installation. | 223 * The choice of "allow" makes it act like other installers, which is to
make no effort to avoid a reboot after installation. |
224 */ | 224 */ |
225 state = allow ; | 225 state = allow ; |
226 » session.log( "Reboot allowed by default in non-interactive session." ) ; | 226 » session.Log( "Reboot allowed by default in non-interactive session." ) ; |
227 } | 227 } |
228 else if ( state == active ) | 228 else if ( state == active ) |
229 { | 229 { |
230 throw std::runtime_error( "AVOIDREBOOT=ACTIVE in non-interative session
is not consistent" ) ; | 230 throw std::runtime_error( "AVOIDREBOOT=ACTIVE in non-interative session
is not consistent" ) ; |
231 } | 231 } |
232 // Assert state is one of { allow, passive, automatic } | 232 // Assert state is one of { allow, passive, automatic } |
233 } | 233 } |
234 else | 234 else |
235 { | 235 { |
236 throw std::runtime_error( "unrecognized value for UILevel" ) ; | 236 throw std::runtime_error( "unrecognized value for UILevel" ) ; |
(...skipping 22 matching lines...) Expand all Loading... |
259 /* | 259 /* |
260 * Precondition: interactive session | 260 * Precondition: interactive session |
261 * | 261 * |
262 * Ask the user "Would you like to close IE and avoid reboot?" | 262 * Ask the user "Would you like to close IE and avoid reboot?" |
263 * Yes -> Close IE somehow. Goto partKnown. | 263 * Yes -> Close IE somehow. Goto partKnown. |
264 * No -> Install with reboot. Goto allow. | 264 * No -> Install with reboot. Goto allow. |
265 * Cancel -> terminate installation. Goto abort. | 265 * Cancel -> terminate installation. Goto abort. |
266 */ | 266 */ |
267 { | 267 { |
268 int x = session.WriteMessage(IMB( | 268 int x = session.WriteMessage(IMB( |
269 messageText.text(L"dialog_unknown"), | 269 messageText.Text(L"dialog_unknown"), |
270 IMB::Box::warning, IMB::ButtonSet::yesNoCancel, IMB::DefaultButton::
three | 270 IMB::Box::warning, IMB::ButtonSet::yesNoCancel, IMB::DefaultButton::
three |
271 )) ; | 271 )) ; |
272 switch ( x ) | 272 switch ( x ) |
273 { | 273 { |
274 case IDYES: | 274 case IDYES: |
275 state = partKnown ; | 275 state = partKnown ; |
276 break ; | 276 break ; |
277 case IDNO: | 277 case IDNO: |
278 state = allow ; | 278 state = allow ; |
279 » session.log( "User chose to allow reboot" ) ; | 279 » session.Log( "User chose to allow reboot" ) ; |
280 break ; | 280 break ; |
281 case IDCANCEL: | 281 case IDCANCEL: |
282 state = abort ; | 282 state = abort ; |
283 » session.log( "User cancelled installation" ) ; | 283 » session.Log( "User cancelled installation" ) ; |
284 break ; | 284 break ; |
285 default: | 285 default: |
286 throw UnexpectedReturnValueFromMessageBox() ; | 286 throw UnexpectedReturnValueFromMessageBox() ; |
287 } | 287 } |
288 } | 288 } |
289 break ; | 289 break ; |
290 | 290 |
291 case partKnown: | 291 case partKnown: |
292 /* | 292 /* |
293 * Precondition: interactive session | 293 * Precondition: interactive session |
294 * | 294 * |
295 * Ask the user "Would you like the installer to close IE for you?" | 295 * Ask the user "Would you like the installer to close IE for you?" |
296 * Yes -> Goto automatic | 296 * Yes -> Goto automatic |
297 * No -> Goto active | 297 * No -> Goto active |
298 * Cancel -> Goto notKnown | 298 * Cancel -> Goto notKnown |
299 */ | 299 */ |
300 { | 300 { |
301 int x = session.WriteMessage(IMB( | 301 int x = session.WriteMessage(IMB( |
302 messageText.text(L"dialog_part_known"), | 302 messageText.Text(L"dialog_part_known"), |
303 IMB::Box::warning, IMB::ButtonSet::yesNoCancel, IMB::DefaultButton::
three | 303 IMB::Box::warning, IMB::ButtonSet::yesNoCancel, IMB::DefaultButton::
three |
304 )) ; | 304 )) ; |
305 switch ( x ) | 305 switch ( x ) |
306 { | 306 { |
307 case IDYES: | 307 case IDYES: |
308 state = automatic ; | 308 state = automatic ; |
309 break ; | 309 break ; |
310 case IDNO: | 310 case IDNO: |
311 state = active ; | 311 state = active ; |
312 break ; | 312 break ; |
(...skipping 11 matching lines...) Expand all Loading... |
324 * Precondition: interactive session | 324 * Precondition: interactive session |
325 * | 325 * |
326 * IE is no longer running -> Goto success | 326 * IE is no longer running -> Goto success |
327 * IE is still running -> | 327 * IE is still running -> |
328 * Ask the user to close IE manually | 328 * Ask the user to close IE manually |
329 * OK -> re-enter this state | 329 * OK -> re-enter this state |
330 * Cancel -> Goto notKnown | 330 * Cancel -> Goto notKnown |
331 */ | 331 */ |
332 { | 332 { |
333 int x = session.WriteMessage(IMB( | 333 int x = session.WriteMessage(IMB( |
334 messageText.text(L"dialog_active_retry"), | 334 messageText.Text(L"dialog_active_retry"), |
335 IMB::Box::warning, IMB::ButtonSet::okCancel, IMB::DefaultButton::one | 335 IMB::Box::warning, IMB::ButtonSet::okCancel, IMB::DefaultButton::one |
336 )) ; | 336 )) ; |
337 switch ( x ) | 337 switch ( x ) |
338 { | 338 { |
339 case IDOK: | 339 case IDOK: |
340 /* | 340 /* |
341 * Refresh our knowledge of whether IE is running. | 341 * Refresh our knowledge of whether IE is running. |
342 * If it is, we display the dialog again. The state doesn't change,
so we just iterate again. | 342 * If it is, we display the dialog again. The state doesn't change,
so we just iterate again. |
343 * If it's not, then the user has closed IE and we're done. | 343 * If it's not, then the user has closed IE and we're done. |
344 */ | 344 */ |
345 » iec.refresh() ; | 345 » iec.Refresh() ; |
346 if ( ! iec.IsRunning() ) | 346 if ( ! iec.IsRunning() ) |
347 { | 347 { |
348 state = success ; | 348 state = success ; |
349 » session.log( "User shut down IE manually." ) ; | 349 » session.Log( "User shut down IE manually." ) ; |
350 } | 350 } |
351 break ; | 351 break ; |
352 case IDCANCEL: | 352 case IDCANCEL: |
353 state = notKnown ; | 353 state = notKnown ; |
354 break ; | 354 break ; |
355 default: | 355 default: |
356 throw UnexpectedReturnValueFromMessageBox() ; | 356 throw UnexpectedReturnValueFromMessageBox() ; |
357 } | 357 } |
358 } | 358 } |
359 break ; | 359 break ; |
360 | 360 |
361 case automatic: | 361 case automatic: |
362 /* | 362 /* |
363 * Close all known IE instances. | 363 * Close all known IE instances. |
364 * Unlike other cases, this state starts with an action and not a user q
uery. | 364 * Unlike other cases, this state starts with an action and not a user q
uery. |
365 * We first shut down IE, or at least attempt to. | 365 * We first shut down IE, or at least attempt to. |
366 * | 366 * |
367 * Succeeded -> Goto success | 367 * Succeeded -> Goto success |
368 * Failed && interactive -> | 368 * Failed && interactive -> |
369 * Ask user if they would like to try again | 369 * Ask user if they would like to try again |
370 * Retry -> re-enter this state | 370 * Retry -> re-enter this state |
371 * Cancel -> Goto notKnown | 371 * Cancel -> Goto notKnown |
372 * Failed && not interactive -> Goto abort | 372 * Failed && not interactive -> Goto abort |
373 */ | 373 */ |
374 { | 374 { |
375 » bool ieWasClosed = iec.shutDown() ; | 375 » bool ieWasClosed = iec.ShutDown() ; |
376 if ( iec.IsRunning() ) | 376 if ( iec.IsRunning() ) |
377 { | 377 { |
378 » session.log( "Attempt to shut down IE automatically failed." ) ; | 378 » session.Log( "Attempt to shut down IE automatically failed." ) ; |
379 if ( interactive ) | 379 if ( interactive ) |
380 { | 380 { |
381 // Assert Interactive session and IE did not shut down. | 381 // Assert Interactive session and IE did not shut down. |
382 int x = session.WriteMessage(IMB( | 382 int x = session.WriteMessage(IMB( |
383 messageText.text(L"dialog_automatic_retry"), | 383 messageText.Text(L"dialog_automatic_retry"), |
384 IMB::Box::warning, IMB::ButtonSet::retryCancel, IMB::DefaultButt
on::one | 384 IMB::Box::warning, IMB::ButtonSet::retryCancel, IMB::DefaultButt
on::one |
385 )) ; | 385 )) ; |
386 switch ( x ) | 386 switch ( x ) |
387 { | 387 { |
388 case IDRETRY: | 388 case IDRETRY: |
389 // Don't change the state. Iterate again. | 389 // Don't change the state. Iterate again. |
390 break ; | 390 break ; |
391 case IDCANCEL: | 391 case IDCANCEL: |
392 state = notKnown ; | 392 state = notKnown ; |
393 break ; | 393 break ; |
394 default: | 394 default: |
395 throw UnexpectedReturnValueFromMessageBox() ; | 395 throw UnexpectedReturnValueFromMessageBox() ; |
396 } | 396 } |
397 } | 397 } |
398 else | 398 else |
399 { | 399 { |
400 // Assert Non-interactive session and IE did not shut down. | 400 // Assert Non-interactive session and IE did not shut down. |
401 state = abort ; | 401 state = abort ; |
402 » session.log( "Failed to shut down IE automatically." ) ; | 402 » session.Log( "Failed to shut down IE automatically." ) ; |
403 } | 403 } |
404 } | 404 } |
405 else | 405 else |
406 { | 406 { |
407 » // Assert IE is not running, so shutDown() succeeded. | 407 » // Assert IE is not running, so ShutDown() succeeded. |
408 state = success ; | 408 state = success ; |
409 » session.log( "Automatically shut down IE." ) ; | 409 » session.Log( "Automatically shut down IE." ) ; |
410 } | 410 } |
411 } | 411 } |
412 break; | 412 break; |
413 } | 413 } |
414 } | 414 } |
415 /* | 415 /* |
416 * State machine: Actions for terminal states. | 416 * State machine: Actions for terminal states. |
417 */ | 417 */ |
418 switch ( state ) | 418 switch ( state ) |
419 { | 419 { |
(...skipping 21 matching lines...) Expand all Loading... |
441 return ERROR_INSTALL_FAILURE ; | 441 return ERROR_INSTALL_FAILURE ; |
442 } | 442 } |
443 catch( ... ) | 443 catch( ... ) |
444 { | 444 { |
445 session.LogNoexcept( "terminated by unknown exception" ) ; | 445 session.LogNoexcept( "terminated by unknown exception" ) ; |
446 return ERROR_INSTALL_FAILURE ; | 446 return ERROR_INSTALL_FAILURE ; |
447 } | 447 } |
448 // Should be unreachable. | 448 // Should be unreachable. |
449 return ERROR_INSTALL_FAILURE ; | 449 return ERROR_INSTALL_FAILURE ; |
450 } | 450 } |
LEFT | RIGHT |