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 #include <browseui_undoc.h> 23 24 HINSTANCE hExplorerInstance; 25 HANDLE hProcessHeap; 26 HKEY hkExplorer = NULL; 27 BOOL bExplorerIsShell = FALSE; 28 29 class CExplorerModule : public CComModule 30 { 31 public: 32 }; 33 34 BEGIN_OBJECT_MAP(ObjectMap) 35 END_OBJECT_MAP() 36 37 CExplorerModule gModule; 38 CAtlWinModule gWinModule; 39 40 static VOID InitializeAtlModule(HINSTANCE hInstance, BOOL bInitialize) 41 { 42 if (bInitialize) 43 { 44 gModule.Init(ObjectMap, hInstance, NULL); 45 } 46 else 47 { 48 gModule.Term(); 49 } 50 } 51 52 #if !WIN7_DEBUG_MODE 53 static BOOL 54 SetShellReadyEvent(IN LPCWSTR lpEventName) 55 { 56 HANDLE hEvent; 57 58 hEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, lpEventName); 59 if (hEvent != NULL) 60 { 61 SetEvent(hEvent); 62 63 CloseHandle(hEvent); 64 return TRUE; 65 } 66 67 return FALSE; 68 } 69 70 static VOID 71 HideMinimizedWindows(IN BOOL bHide) 72 { 73 MINIMIZEDMETRICS mm; 74 75 mm.cbSize = sizeof(mm); 76 if (!SystemParametersInfoW(SPI_GETMINIMIZEDMETRICS, sizeof(mm), &mm, 0)) 77 { 78 ERR("SystemParametersInfoW failed with %lu\n", GetLastError()); 79 return; 80 } 81 if (bHide) 82 mm.iArrange |= ARW_HIDE; 83 else 84 mm.iArrange &= ~ARW_HIDE; 85 if (!SystemParametersInfoW(SPI_SETMINIMIZEDMETRICS, sizeof(mm), &mm, 0)) 86 ERR("SystemParametersInfoW failed with %lu\n", GetLastError()); 87 } 88 #endif 89 90 static BOOL 91 IsExplorerSystemShell() 92 { 93 BOOL bIsSystemShell = TRUE; // Assume we are the system shell by default. 94 WCHAR szPath[MAX_PATH]; 95 96 if (!GetModuleFileNameW(NULL, szPath, _countof(szPath))) 97 return FALSE; 98 99 LPWSTR szExplorer = PathFindFileNameW(szPath); 100 101 HKEY hKeyWinlogon; 102 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 103 L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 104 0, KEY_READ, &hKeyWinlogon) == ERROR_SUCCESS) 105 { 106 LSTATUS Status; 107 DWORD dwType; 108 WCHAR szShell[MAX_PATH]; 109 DWORD cbShell = sizeof(szShell); 110 111 // TODO: Add support for paths longer than MAX_PATH 112 Status = RegQueryValueExW(hKeyWinlogon, L"Shell", 0, &dwType, (LPBYTE)szShell, &cbShell); 113 if (Status == ERROR_SUCCESS) 114 { 115 if ((dwType != REG_SZ && dwType != REG_EXPAND_SZ) || !StrStrIW(szShell, szExplorer)) 116 bIsSystemShell = FALSE; 117 } 118 119 RegCloseKey(hKeyWinlogon); 120 } 121 122 return bIsSystemShell; 123 } 124 125 #if !WIN7_COMPAT_MODE 126 static INT 127 StartWithCommandLine(IN HINSTANCE hInstance) 128 { 129 BOOL b = FALSE; 130 EXPLORER_CMDLINE_PARSE_RESULTS parseResults = { 0 }; 131 132 if (SHExplorerParseCmdLine(&parseResults)) 133 b = SHCreateFromDesktop(&parseResults); 134 135 if (parseResults.strPath) 136 SHFree(parseResults.strPath); 137 138 if (parseResults.pidlPath) 139 ILFree(parseResults.pidlPath); 140 141 if (parseResults.pidlRoot) 142 ILFree(parseResults.pidlRoot); 143 144 return b; 145 } 146 #endif 147 148 static INT 149 StartWithDesktop(IN HINSTANCE hInstance) 150 { 151 InitializeAtlModule(hInstance, TRUE); 152 153 if (RegOpenKeyW(HKEY_CURRENT_USER, 154 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", 155 &hkExplorer) != ERROR_SUCCESS) 156 { 157 WCHAR Message[256]; 158 LoadStringW(hInstance, IDS_STARTUP_ERROR, Message, _countof(Message)); 159 MessageBox(NULL, Message, NULL, MB_ICONERROR); 160 return 1; 161 } 162 163 hExplorerInstance = hInstance; 164 hProcessHeap = GetProcessHeap(); 165 166 g_TaskbarSettings.Load(); 167 168 InitCommonControls(); 169 OleInitialize(NULL); 170 171 #if !WIN7_COMPAT_MODE 172 /* Initialize shell dde support */ 173 _ShellDDEInit(TRUE); 174 #endif 175 176 /* Initialize shell icons */ 177 FileIconInit(TRUE); 178 179 /* Initialize CLSID_ShellWindows class */ 180 _WinList_Init(); 181 182 CComPtr<ITrayWindow> Tray; 183 CreateTrayWindow(&Tray); 184 185 #if !WIN7_DEBUG_MODE 186 /* This not only hides the minimized window captions in the bottom 187 left screen corner, but is also needed in order to receive 188 HSHELL_* notification messages (which are required for taskbar 189 buttons to work right) */ 190 HideMinimizedWindows(TRUE); 191 192 ProcessRunOnceItems(); // Must be executed before the desktop is created 193 194 HANDLE hShellDesktop = NULL; 195 if (Tray != NULL) 196 hShellDesktop = DesktopCreateWindow(Tray); 197 198 /* WinXP: Notify msgina to hide the welcome screen */ 199 if (!SetShellReadyEvent(L"msgina: ShellReadyEvent")) 200 SetShellReadyEvent(L"Global\\msgina: ShellReadyEvent"); 201 202 if (DoStartStartupItems(Tray)) 203 { 204 ProcessStartupItems(); 205 DoFinishStartupItems(); 206 } 207 ReleaseStartupMutex(); // For ProcessRunOnceItems 208 #endif 209 210 if (Tray != NULL) 211 { 212 TrayMessageLoop(Tray); 213 #if !WIN7_DEBUG_MODE 214 HideMinimizedWindows(FALSE); 215 #endif 216 } 217 218 #if !WIN7_DEBUG_MODE 219 if (hShellDesktop != NULL) 220 DesktopDestroyShellWindow(hShellDesktop); 221 #endif 222 223 OleUninitialize(); 224 225 RegCloseKey(hkExplorer); 226 hkExplorer = NULL; 227 228 InitializeAtlModule(hInstance, FALSE); 229 230 return 0; 231 } 232 233 INT WINAPI 234 _tWinMain(IN HINSTANCE hInstance, 235 IN HINSTANCE hPrevInstance, 236 IN LPTSTR lpCmdLine, 237 IN INT nCmdShow) 238 { 239 /* 240 * Set our shutdown parameters: we want to shutdown the very last, 241 * but before any TaskMgr instance (which has a shutdown level of 1). 242 */ 243 SetProcessShutdownParameters(2, 0); 244 245 InitRSHELL(); 246 247 TRACE("Explorer starting... Command line: %S\n", lpCmdLine); 248 249 #if !WIN7_COMPAT_MODE 250 bExplorerIsShell = (GetShellWindow() == NULL) && IsExplorerSystemShell(); 251 252 if (!bExplorerIsShell) 253 { 254 return StartWithCommandLine(hInstance); 255 } 256 #else 257 bExplorerIsShell = IsExplorerSystemShell(); 258 #endif 259 260 return StartWithDesktop(hInstance); 261 } 262