[ROSTESTS]
[reactos.git] / reactos / base / shell / explorer-new / explorer.c
1 /*
2 * ReactOS Explorer
3 *
4 * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <precomp.h>
22
23 HINSTANCE hExplorerInstance;
24 HMODULE hUser32;
25 HANDLE hProcessHeap;
26 HKEY hkExplorer = NULL;
27 DRAWCAPTEMP DrawCapTemp = NULL;
28
29 typedef struct _LANGCODEPAGE
30 {
31 WORD wLanguage;
32 WORD wCodePage;
33 } LANGCODEPAGE, *PLANGCODEPAGE;
34
35 /* undoc GUID */
36 DEFINE_GUID(CLSID_RebarBandSite, 0xECD4FC4D, 0x521C, 0x11D0, 0xB7, 0x92, 0x00, 0xA0, 0xC9, 0x03, 0x12, 0xE1);
37
38 LONG
39 SetWindowStyle(IN HWND hWnd,
40 IN LONG dwStyleMask,
41 IN LONG dwStyle)
42 {
43 LONG PrevStyle, Style;
44
45 ASSERT((~dwStyleMask & dwStyle) == 0);
46
47 PrevStyle = GetWindowLongPtr(hWnd,
48 GWL_STYLE);
49 if (PrevStyle != 0 &&
50 (PrevStyle & dwStyleMask) != dwStyle)
51 {
52 Style = PrevStyle & ~dwStyleMask;
53 Style |= dwStyle;
54
55 PrevStyle = SetWindowLongPtr(hWnd,
56 GWL_STYLE,
57 Style);
58 }
59
60 return PrevStyle;
61 }
62
63 LONG
64 SetWindowExStyle(IN HWND hWnd,
65 IN LONG dwStyleMask,
66 IN LONG dwStyle)
67 {
68 LONG PrevStyle, Style;
69
70 ASSERT((~dwStyleMask & dwStyle) == 0);
71
72 PrevStyle = GetWindowLongPtr(hWnd,
73 GWL_EXSTYLE);
74 if (PrevStyle != 0 &&
75 (PrevStyle & dwStyleMask) != dwStyle)
76 {
77 Style = PrevStyle & ~dwStyleMask;
78 Style |= dwStyle;
79
80 PrevStyle = SetWindowLongPtr(hWnd,
81 GWL_EXSTYLE,
82 Style);
83 }
84
85 return PrevStyle;
86 }
87
88 HMENU
89 LoadPopupMenu(IN HINSTANCE hInstance,
90 IN LPCTSTR lpMenuName)
91 {
92 HMENU hMenu, hSubMenu = NULL;
93
94 hMenu = LoadMenu(hInstance,
95 lpMenuName);
96
97 if (hMenu != NULL)
98 {
99 hSubMenu = GetSubMenu(hMenu,
100 0);
101 if (hSubMenu != NULL &&
102 !RemoveMenu(hMenu,
103 0,
104 MF_BYPOSITION))
105 {
106 hSubMenu = NULL;
107 }
108
109 DestroyMenu(hMenu);
110 }
111
112 return hSubMenu;
113 }
114
115 HMENU
116 FindSubMenu(IN HMENU hMenu,
117 IN UINT uItem,
118 IN BOOL fByPosition)
119 {
120 MENUITEMINFO mii;
121
122 mii.cbSize = sizeof(mii);
123 mii.fMask = MIIM_SUBMENU;
124
125 if (GetMenuItemInfo(hMenu,
126 uItem,
127 fByPosition,
128 &mii))
129 {
130 return mii.hSubMenu;
131 }
132
133 return NULL;
134 }
135
136 BOOL
137 GetCurrentLoggedOnUserName(OUT LPTSTR szBuffer,
138 IN DWORD dwBufferSize)
139 {
140 DWORD dwType;
141 DWORD dwSize;
142
143 /* Query the user name from the registry */
144 dwSize = (dwBufferSize * sizeof(TCHAR)) - 1;
145 if (RegQueryValueEx(hkExplorer,
146 TEXT("Logon User Name"),
147 0,
148 &dwType,
149 (LPBYTE)szBuffer,
150 &dwSize) == ERROR_SUCCESS &&
151 (dwSize / sizeof(TCHAR)) > 1 &&
152 szBuffer[0] != _T('\0'))
153 {
154 szBuffer[dwSize / sizeof(TCHAR)] = _T('\0');
155 return TRUE;
156 }
157
158 /* Fall back to GetUserName() */
159 dwSize = dwBufferSize;
160 if (!GetUserName(szBuffer,
161 &dwSize))
162 {
163 szBuffer[0] = _T('\0');
164 return FALSE;
165 }
166
167 return TRUE;
168 }
169
170 BOOL
171 FormatMenuString(IN HMENU hMenu,
172 IN UINT uPosition,
173 IN UINT uFlags,
174 ...)
175 {
176 va_list vl;
177 MENUITEMINFO mii;
178 TCHAR szBuf[128];
179 TCHAR szBufFmt[128];
180
181 /* Find the menu item and read the formatting string */
182 mii.cbSize = sizeof(mii);
183 mii.fMask = MIIM_STRING;
184 mii.dwTypeData = (LPTSTR)szBufFmt;
185 mii.cch = sizeof(szBufFmt) / sizeof(szBufFmt[0]);
186 if (GetMenuItemInfo(hMenu,
187 uPosition,
188 uFlags,
189 &mii))
190 {
191 /* Format the string */
192 va_start(vl, uFlags);
193 _vsntprintf(szBuf,
194 (sizeof(szBuf) / sizeof(szBuf[0])) - 1,
195 szBufFmt,
196 vl);
197 va_end(vl);
198 szBuf[(sizeof(szBuf) / sizeof(szBuf[0])) - 1] = _T('\0');
199
200 /* Update the menu item */
201 mii.dwTypeData = (LPTSTR)szBuf;
202 if (SetMenuItemInfo(hMenu,
203 uPosition,
204 uFlags,
205 &mii))
206 {
207 return TRUE;
208 }
209 }
210
211 return FALSE;
212 }
213
214 BOOL
215 GetExplorerRegValueSet(IN HKEY hKey,
216 IN LPCTSTR lpSubKey,
217 IN LPCTSTR lpValue)
218 {
219 TCHAR szBuffer[MAX_PATH];
220 HKEY hkSubKey;
221 DWORD dwType, dwSize;
222 BOOL Ret = FALSE;
223
224 _tcscpy(szBuffer,
225 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"));
226 _tcscat(szBuffer,
227 _T("\\"));
228 _tcscat(szBuffer,
229 lpSubKey);
230
231 dwSize = sizeof(szBuffer);
232 if (RegOpenKeyEx(hKey,
233 szBuffer,
234 0,
235 KEY_QUERY_VALUE,
236 &hkSubKey) == ERROR_SUCCESS)
237 {
238 ZeroMemory(szBuffer,
239 sizeof(szBuffer));
240
241 if (RegQueryValueEx(hkSubKey,
242 lpValue,
243 0,
244 &dwType,
245 (LPBYTE)szBuffer,
246 &dwSize) == ERROR_SUCCESS)
247 {
248 if (dwType == REG_DWORD && dwSize == sizeof(DWORD))
249 Ret = *((PDWORD)szBuffer) != 0;
250 else if (dwSize > 0)
251 Ret = *((PUCHAR)szBuffer) != 0;
252 }
253
254 RegCloseKey(hkSubKey);
255 }
256 return Ret;
257 }
258
259
260 static BOOL
261 SetShellReadyEvent(IN LPCTSTR lpEventName)
262 {
263 HANDLE hEvent;
264
265 hEvent = OpenEvent(EVENT_MODIFY_STATE,
266 FALSE,
267 lpEventName);
268 if (hEvent != NULL)
269 {
270 SetEvent(hEvent);
271
272 CloseHandle(hEvent);
273 return TRUE;
274 }
275
276 return FALSE;
277 }
278
279 BOOL
280 GetVersionInfoString(IN TCHAR *szFileName,
281 IN TCHAR *szVersionInfo,
282 OUT TCHAR *szBuffer,
283 IN UINT cbBufLen)
284 {
285 LPVOID lpData = NULL;
286 TCHAR szSubBlock[128];
287 TCHAR *lpszLocalBuf = NULL;
288 LANGID UserLangId;
289 PLANGCODEPAGE lpTranslate = NULL;
290 DWORD dwLen;
291 DWORD dwHandle;
292 UINT cbTranslate;
293 UINT cbLen;
294 BOOL bRet = FALSE;
295 unsigned int i;
296
297 dwLen = GetFileVersionInfoSize(szFileName,&dwHandle);
298
299 if (dwLen > 0)
300 {
301 lpData = HeapAlloc(hProcessHeap,0,dwLen);
302
303 if (lpData != NULL)
304 {
305 if (GetFileVersionInfo(szFileName,
306 0,
307 dwLen,
308 lpData) != 0)
309 {
310 UserLangId = GetUserDefaultLangID();
311
312 VerQueryValue(lpData,
313 TEXT("\\VarFileInfo\\Translation"),
314 (LPVOID *)&lpTranslate,
315 &cbTranslate);
316
317 for (i = 0;i < (cbTranslate / sizeof(LANGCODEPAGE));i++)
318 {
319 /* If the bottom eight bits of the language id's
320 match, use this version information (since this
321 means that the version information and the users
322 default language are the same). */
323 if ((lpTranslate[i].wLanguage & 0xFF) ==
324 (UserLangId & 0xFF))
325 {
326 wnsprintf(szSubBlock,
327 sizeof(szSubBlock) / sizeof(szSubBlock[0]),
328 TEXT("\\StringFileInfo\\%04X%04X\\%s"),
329 lpTranslate[i].wLanguage,
330 lpTranslate[i].wCodePage,szVersionInfo);
331
332 if (VerQueryValue(lpData,
333 szSubBlock,
334 (LPVOID *)&lpszLocalBuf,
335 &cbLen) != 0)
336 {
337 wcsncpy(szBuffer,lpszLocalBuf,cbBufLen);
338
339 bRet = TRUE;
340 break;
341 }
342 }
343 }
344 }
345 HeapFree(hProcessHeap,0,lpData);
346 lpData = NULL;
347 }
348 }
349
350 return bRet;
351 }
352
353 INT WINAPI
354 _tWinMain(IN HINSTANCE hInstance,
355 IN HINSTANCE hPrevInstance,
356 IN LPTSTR lpCmdLine,
357 IN INT nCmdShow)
358 {
359 ITrayWindow *Tray = NULL;
360 HANDLE hShellDesktop = NULL;
361 BOOL CreateShellDesktop = FALSE;
362
363 if (RegOpenKey(HKEY_CURRENT_USER,
364 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"),
365 &hkExplorer) != ERROR_SUCCESS)
366 {
367 TCHAR Message[256];
368 LoadString(hInstance, IDS_STARTUP_ERROR, Message, 256);
369 MessageBox(NULL, Message, NULL, MB_ICONERROR);
370 return 1;
371 }
372
373 hExplorerInstance = hInstance;
374 hProcessHeap = GetProcessHeap();
375
376 hUser32 = GetModuleHandle(TEXT("USER32.DLL"));
377 if (hUser32 != NULL)
378 {
379 DrawCapTemp = (DRAWCAPTEMP)GetProcAddress(hUser32,
380 PROC_NAME_DRAWCAPTIONTEMP);
381 }
382
383 InitCommonControls();
384 OleInitialize(NULL);
385
386 if (GetShellWindow() == NULL)
387 CreateShellDesktop = TRUE;
388
389 /* FIXME - initialize SSO Thread */
390
391 if (CreateShellDesktop)
392 {
393 if (RegisterTrayWindowClass() && RegisterTaskSwitchWndClass())
394 {
395 Tray = CreateTrayWindow();
396
397 if (Tray != NULL)
398 hShellDesktop = DesktopCreateWindow(Tray);
399 }
400
401 /* WinXP: Notify msgina to hide the welcome screen */
402 if (!SetShellReadyEvent(TEXT("msgina: ShellReadyEvent")))
403 SetShellReadyEvent(TEXT("Global\\msgina: ShellReadyEvent"));
404 }
405 else
406 {
407 /* A shell is already loaded. Parse the command line arguments
408 and unless we need to do something specific simply display
409 the desktop in a separate explorer window */
410 /* FIXME */
411 }
412
413 if (Tray != NULL)
414 TrayMessageLoop(Tray);
415
416 if (hShellDesktop != NULL)
417 DesktopDestroyShellWindow(hShellDesktop);
418
419 /* FIXME - shutdown SSO Thread */
420
421 OleUninitialize();
422
423 RegCloseKey(hkExplorer);
424 hkExplorer = NULL;
425
426 return 0;
427 }