Reactos
1/***
2*crtmbox.c - CRT MessageBoxA wrapper.
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Wrap MessageBoxA.
8*
9*******************************************************************************/
10
11#include <corecrt_internal.h>
12#include <corecrt_internal_traits.h>
13
14
15
16namespace
17{
18 template <typename Character>
19 struct message_box_arguments
20 {
21 Character const* _caption;
22 Character const* _text;
23 unsigned int _type;
24 int _result;
25 };
26}
27
28template <typename Character>
29static int __cdecl common_show_message_box(
30 Character const* const text,
31 Character const* const caption,
32 unsigned const type
33 ) throw()
34{
35 using traits = __crt_char_traits<Character>;
36
37 bool const debugger_attached = IsDebuggerPresent();
38 if (debugger_attached)
39 {
40 // Output the message to the attached debugger. This is useful when
41 // remotely debugging.
42 if (text)
43 {
44 traits::output_debug_string(text);
45 }
46
47 // We do not want to display a message box if a debugger
48 // is already attached, unless it's a desktop app.
49 // Instead, let the caller know that we want to
50 // directly break into the debugger:
51 bool const is_desktop_app = __acrt_get_windowing_model_policy() == windowing_model_policy_hwnd;
52 if (!is_desktop_app)
53 {
54 return IDRETRY; // Retry = Break into the debugger
55 }
56 }
57
58 bool const show_ui = __acrt_get_developer_information_policy() == developer_information_policy_ui;
59 if (!show_ui || !__acrt_can_show_message_box())
60 {
61 // If we can't get the message box pointers (perhaps because running on CoreSys),
62 // just abort, unless a debugger is attached--then break into the debugger instead.
63 // The message string was already output to the debugger above.
64 return debugger_attached ? IDRETRY : IDABORT;
65 }
66
67 // If the current process isn't attached to a visible window station (e.g.
68 // a non-interactive service), then we need to set the MB_SERVICE_NOTIFICATION
69 // flag, otherwise the message box will be invisible, stalling the program.
70 if (!__acrt_is_interactive())
71 {
72 return traits::message_box(nullptr, text, caption, type | MB_SERVICE_NOTIFICATION);
73 }
74
75 return traits::message_box(__acrt_get_parent_window(), text, caption, type);
76}
77
78extern "C" int __cdecl __acrt_show_narrow_message_box(
79 char const* const text,
80 char const* const caption,
81 unsigned const type
82 )
83{
84 return common_show_message_box(text, caption, type);
85}
86
87extern "C" int __cdecl __acrt_show_wide_message_box(
88 wchar_t const* const text,
89 wchar_t const* const caption,
90 unsigned const type
91 )
92{
93 return common_show_message_box(text, caption, type);
94}