msxml3: Clean formatting chars before passing to base64 decoder.
[wine] / programs / winecfg / main.c
1 /*
2  * WineCfg main entry point
3  *
4  * Copyright 2002 Jaco Greeff
5  * Copyright 2003 Dimitrie O. Paun
6  * Copyright 2003 Mike Hearn
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  *
22  */
23
24 #define WIN32_LEAN_AND_MEAN
25
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
28
29 #include <windows.h>
30 #include <commctrl.h>
31 #include <objbase.h>
32 #include <wine/debug.h>
33
34 #include "resource.h"
35 #include "winecfg.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
38
39 static INT CALLBACK
40 PropSheetCallback (HWND hWnd, UINT uMsg, LPARAM lParam)
41 {
42     switch (uMsg)
43     {
44         /*
45          * hWnd = NULL, lParam == dialog resource
46          */
47     case PSCB_PRECREATE:
48         break;
49
50     case PSCB_INITIALIZED:
51         /* Set the window icon */
52         SendMessageW( hWnd, WM_SETICON, ICON_BIG,
53                       (LPARAM)LoadIconW( (HINSTANCE)GetWindowLongPtrW(hWnd, GWLP_HINSTANCE),
54                                          MAKEINTRESOURCEW(IDI_WINECFG) ));
55         break;
56
57     default:
58         break;
59     }
60     return 0;
61 }
62
63 #define NUM_PROPERTY_PAGES 7
64
65 static INT_PTR
66 doPropertySheet (HINSTANCE hInstance, HWND hOwner)
67 {
68     PROPSHEETPAGEW psp[NUM_PROPERTY_PAGES];
69     PROPSHEETHEADERW psh;
70     int pg = 0; /* start with page 0 */
71
72     /*
73      * Fill out the (Applications) PROPSHEETPAGE data structure 
74      * for the property sheet
75      */
76     psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
77     psp[pg].dwFlags = PSP_USETITLE;
78     psp[pg].hInstance = hInstance;
79     psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_APPCFG);
80     psp[pg].u2.pszIcon = NULL;
81     psp[pg].pfnDlgProc = AppDlgProc;
82     psp[pg].pszTitle = load_string (IDS_TAB_APPLICATIONS);
83     psp[pg].lParam = 0;
84     pg++;
85
86     /*
87      * Fill out the (Libraries) PROPSHEETPAGE data structure 
88      * for the property sheet
89      */
90     psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
91     psp[pg].dwFlags = PSP_USETITLE;
92     psp[pg].hInstance = hInstance;
93     psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_DLLCFG);
94     psp[pg].u2.pszIcon = NULL;
95     psp[pg].pfnDlgProc = LibrariesDlgProc;
96     psp[pg].pszTitle = load_string (IDS_TAB_DLLS);
97     psp[pg].lParam = 0;
98     pg++;
99     
100     /*
101      * Fill out the (X11Drv) PROPSHEETPAGE data structure 
102      * for the property sheet
103      */
104     psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
105     psp[pg].dwFlags = PSP_USETITLE;
106     psp[pg].hInstance = hInstance;
107     psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_GRAPHCFG);
108     psp[pg].u2.pszIcon = NULL;
109     psp[pg].pfnDlgProc = GraphDlgProc;
110     psp[pg].pszTitle =  load_string (IDS_TAB_GRAPHICS);
111     psp[pg].lParam = 0;
112     pg++;
113
114     psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
115     psp[pg].dwFlags = PSP_USETITLE;
116     psp[pg].hInstance = hInstance;
117     psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_DESKTOP_INTEGRATION);
118     psp[pg].u2.pszIcon = NULL;
119     psp[pg].pfnDlgProc = ThemeDlgProc;
120     psp[pg].pszTitle =  load_string (IDS_TAB_DESKTOP_INTEGRATION);
121     psp[pg].lParam = 0;
122     pg++;
123
124     psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
125     psp[pg].dwFlags = PSP_USETITLE;
126     psp[pg].hInstance = hInstance;
127     psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_DRIVECFG);
128     psp[pg].u2.pszIcon = NULL;
129     psp[pg].pfnDlgProc = DriveDlgProc;
130     psp[pg].pszTitle =  load_string (IDS_TAB_DRIVES);
131     psp[pg].lParam = 0;
132     pg++;
133
134     psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
135     psp[pg].dwFlags = PSP_USETITLE;
136     psp[pg].hInstance = hInstance;
137     psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_AUDIOCFG);
138     psp[pg].u2.pszIcon = NULL;
139     psp[pg].pfnDlgProc = AudioDlgProc;
140     psp[pg].pszTitle =  load_string (IDS_TAB_AUDIO);
141     psp[pg].lParam = 0;
142     pg++;
143
144     /*
145      * Fill out the (General) PROPSHEETPAGE data structure 
146      * for the property sheet
147      */
148     psp[pg].dwSize = sizeof (PROPSHEETPAGEW);
149     psp[pg].dwFlags = PSP_USETITLE;
150     psp[pg].hInstance = hInstance;
151     psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_ABOUTCFG);
152     psp[pg].u2.pszIcon = NULL;
153     psp[pg].pfnDlgProc = AboutDlgProc;
154     psp[pg].pszTitle =  load_string (IDS_TAB_ABOUT);
155     psp[pg].lParam = 0;
156     pg++;
157
158     /*
159      * Fill out the PROPSHEETHEADER
160      */
161     psh.dwSize = sizeof (PROPSHEETHEADERW);
162     psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USEICONID | PSH_USECALLBACK;
163     psh.hwndParent = hOwner;
164     psh.hInstance = hInstance;
165     psh.u.pszIcon = MAKEINTRESOURCEW (IDI_WINECFG);
166     psh.pszCaption =  load_string (IDS_WINECFG_TITLE);
167     psh.nPages = NUM_PROPERTY_PAGES;
168     psh.u3.ppsp = psp;
169     psh.pfnCallback = PropSheetCallback;
170     psh.u2.nStartPage = 0;
171
172     /*
173      * Display the modal property sheet
174      */
175     return PropertySheetW (&psh);
176 }
177
178 /******************************************************************************
179  * Name       : ProcessCmdLine
180  * Description: Checks command line parameters for 'autodetect drives' option
181  * Parameters : lpCmdLine - the command line
182  * Returns    : TRUE - if '/D' was found. Drive autodetection was carried out.
183  *              FALSE - no '/D' option found in command line
184  * Notes      : This is a very simple implementation, which only works 
185  *              correctly if the one and only cmd line option is '/D' or
186  *              no option at all. Has to be reworked, if more options are to
187  *              be supported.
188  */
189 static BOOL
190 ProcessCmdLine(LPSTR lpCmdLine)
191 {
192     if ((lpCmdLine[0] == '/' || lpCmdLine[0] == '-') && 
193         (lpCmdLine[1] == 'D' || lpCmdLine[1] == 'd')) 
194     {
195         gui_mode = FALSE;
196         if (autodetect_drives()) {
197             apply_drive_changes();
198         }
199         return TRUE;
200     }
201
202     return FALSE;
203 }
204
205 /*****************************************************************************
206  * Name       : WinMain
207  * Description: Main windows entry point
208  * Parameters : hInstance
209  *              hPrev
210  *              szCmdLine
211  *              nShow
212  * Returns    : Program exit code
213  */
214 int WINAPI
215 WinMain (HINSTANCE hInstance, HINSTANCE hPrev, LPSTR szCmdLine, int nShow)
216 {
217     BOOL is_wow64;
218
219     if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64)
220     {
221         STARTUPINFOW si;
222         PROCESS_INFORMATION pi;
223         WCHAR filename[MAX_PATH];
224         void *redir;
225         DWORD exit_code;
226
227         memset( &si, 0, sizeof(si) );
228         si.cb = sizeof(si);
229         GetModuleFileNameW( 0, filename, MAX_PATH );
230
231         Wow64DisableWow64FsRedirection( &redir );
232         if (CreateProcessW( filename, GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
233         {
234             WINE_TRACE( "restarting %s\n", wine_dbgstr_w(filename) );
235             WaitForSingleObject( pi.hProcess, INFINITE );
236             GetExitCodeProcess( pi.hProcess, &exit_code );
237             ExitProcess( exit_code );
238         }
239         else WINE_ERR( "failed to restart 64-bit %s, err %d\n", wine_dbgstr_w(filename), GetLastError() );
240         Wow64RevertWow64FsRedirection( redir );
241     }
242
243     if (ProcessCmdLine(szCmdLine)) {
244         return 0;
245     }
246
247     if (initialize(hInstance) != 0) {
248         WINE_ERR("initialization failed, aborting\n");
249         ExitProcess(1);
250     }
251     
252     /*
253      * The next 9 lines should be all that is needed
254      * for the Wine Configuration property sheet
255      */
256     InitCommonControls ();
257     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
258     if (doPropertySheet (hInstance, NULL) > 0) {
259         WINE_TRACE("OK\n");
260     } else {
261         WINE_TRACE("Cancel\n");
262     }
263     CoUninitialize(); 
264     ExitProcess (0);
265
266     return 0;
267 }