Add ProgramData to the env var whitelist for running scripts
[cygwin-setup.git] / msg.cc
blob8e344ff87afa8df671c27616c6f0b02dde047c90
1 /*
2 * Copyright (c) 2000, Red Hat, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
12 * Written by DJ Delorie <dj@cygnus.com>
16 /* The purpose of this file is to centralize all the message
17 functions. */
19 #include "msg.h"
21 #include "LogFile.h"
22 #include "win32.h"
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include "dialog.h"
27 #include "state.h"
28 #include "String++.h"
29 #include "resource.h"
31 static int
32 unattended_result(int mb_type)
34 // Return some default values.
35 switch (mb_type & MB_TYPEMASK)
37 case MB_OK:
38 case MB_OKCANCEL:
39 return IDOK;
40 break;
41 case MB_YESNO:
42 case MB_YESNOCANCEL:
43 return IDYES;
44 break;
45 case MB_ABORTRETRYIGNORE:
46 return IDIGNORE;
47 break;
48 case MB_RETRYCANCEL:
49 return IDCANCEL;
50 break;
51 default:
52 Log (LOG_PLAIN) << "unattended_mode failed for " << (mb_type & MB_TYPEMASK) << endLog;
53 return 0;
57 int
58 mbox (HWND owner, const char *buf, const char *name, int type)
60 // 'name' is not the mbox caption, just some text written to the log
61 Log (LOG_PLAIN) << "mbox " << name << ": " << buf << endLog;
62 if (unattended_mode)
64 Log (LOG_PLAIN) << "unattended_mode is set at mbox: returning default value" << endLog;
65 return unattended_result(type);
68 char caption[32];
69 LoadString (hinstance, IDS_MBOX_CAPTION, caption, sizeof (caption));
71 return MessageBox (owner, buf, caption, type);
74 static int
75 mbox (HWND owner, const char *name, int type, int id, va_list args)
77 char buf[1000], fmt[1000];
79 if (LoadString (hinstance, id, fmt, sizeof (fmt)) <= 0)
80 ExitProcess (0);
82 vsnprintf (buf, 1000, fmt, args);
83 return mbox(owner, buf, name, type);
86 void
87 note (HWND owner, int id, ...)
89 va_list args;
90 va_start (args, id);
91 mbox (owner, "note", 0, id, args);
94 void
95 fatal (HWND owner, int id, ...)
97 va_list args;
98 va_start (args, id);
99 mbox (owner, "fatal", 0, id, args);
100 Logger ().exit (1);
104 yesno (HWND owner, int id, ...)
106 va_list args;
107 va_start (args, id);
108 return mbox (owner, "yesno", MB_YESNO, id, args);
111 static HHOOK hMsgBoxHook;
113 LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) {
114 HWND hWnd;
115 switch (nCode) {
116 case HCBT_ACTIVATE:
117 hWnd = (HWND)wParam;
118 if (GetDlgItem(hWnd, IDCANCEL) != NULL)
120 // XXX: ideally we'd discover the text used for 'Continue' buttons in
121 // MessageBoxes, rather than having our own translation.
122 std::wstring cont = LoadStringW(IDS_CONTINUE);
123 SetDlgItemTextW(hWnd, IDCANCEL, cont.c_str());
125 UnhookWindowsHookEx(hMsgBoxHook);
127 return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam);
130 // registry key to store "don't show this again" state, made unique by including a GUID
131 static const char *regkey = "Cygwin-Setup-d975d7b8-8c44-44a1-915a-7cf44b79cd88";
134 mbox(HWND owner, unsigned int format_id, int mb_type, ...)
136 std::wstring fmt = LoadStringWEx(format_id, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
137 if (fmt.empty())
138 fmt = L"Internal error: format string resource not found";
140 va_list args;
141 va_start(args, mb_type);
142 std::wstring buf = vformat(fmt, args);
143 va_end(args);
145 // write unlocalized to log as UTF8
146 Log (LOG_PLAIN) << "mbox " << ": " << wstring_to_string(buf) << endLog;
148 if (unattended_mode)
149 return unattended_result(mb_type);
151 fmt = LoadStringW(format_id);
152 if (fmt.empty())
153 fmt = L"Internal error: format string resource not found";
155 va_start(args, mb_type);
156 buf = vformat(fmt, args);
157 va_end(args);
159 bool retry_continue = (mb_type & MB_TYPEMASK) == MB_RETRYCONTINUE;
160 if (retry_continue) {
161 mb_type &= ~MB_TYPEMASK;
162 mb_type |= MB_RETRYCANCEL;
163 // Install a window hook, so we can intercept the message-box creation, and
164 // customize it (replacing the text on the 'cancel' button with 'continue')
165 // Only install for THIS thread!!!
166 hMsgBoxHook = SetWindowsHookEx(WH_CBT, CBTProc, NULL, GetCurrentThreadId());
169 typedef int (WINAPI *PFNSHMESSAGEBOXCHECKW)(HWND, LPCWSTR, LPCWSTR, UINT, int, LPCWSTR);
170 static PFNSHMESSAGEBOXCHECKW pfnSHMessageBoxCheckW = 0;
171 static bool doOnce = FALSE;
173 if (!doOnce)
175 doOnce = TRUE;
176 pfnSHMessageBoxCheckW = (PFNSHMESSAGEBOXCHECKW)GetProcAddress(GetModuleHandle("shlwapi.dll"), "SHMessageBoxCheckW");
179 std::wstring caption = LoadStringW(IDS_MBOX_CAPTION);
180 int retval;
181 if (pfnSHMessageBoxCheckW && (mb_type & MB_DSA_CHECKBOX))
183 mb_type &= ~MB_DSA_CHECKBOX;
184 std::wstring regkey_msg = format(L"%s-%d", regkey, format_id);
185 retval = pfnSHMessageBoxCheckW(owner, buf.c_str(), caption.c_str(), mb_type,
186 unattended_result(mb_type), regkey_msg.c_str());
188 else
189 retval = MessageBoxW(owner, buf.c_str(), caption.c_str(), mb_type);
191 // When the the retry_continue customization is active, adjust the return
192 // value for less confusing results
193 if (retry_continue && retval == IDCANCEL)
194 retval = IDCONTINUE;
196 return retval;