ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

userinit.c
Go to the documentation of this file.
00001 /*
00002  *  ReactOS applications
00003  *  Copyright (C) 2001, 2002 ReactOS Team
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License along
00016  *  with this program; if not, write to the Free Software Foundation, Inc.,
00017  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00018  */
00019 /*
00020  * COPYRIGHT:   See COPYING in the top level directory
00021  * PROJECT:     ReactOS Userinit Logon Application
00022  * FILE:        subsys/system/userinit/userinit.c
00023  * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
00024  *              Hervé Poussineau (hpoussin@reactos.org)
00025  */
00026 #include <windows.h>
00027 #include <cfgmgr32.h>
00028 #include <regstr.h>
00029 #include <shlobj.h>
00030 #include <shlwapi.h>
00031 #include <undocuser.h>
00032 #include "resource.h"
00033 #include <wine/debug.h>
00034 
00035 WINE_DEFAULT_DEBUG_CHANNEL(userinit);
00036 
00037 #define CMP_MAGIC  0x01234567
00038 
00039 /* GLOBALS ******************************************************************/
00040 
00041 /* FUNCTIONS ****************************************************************/
00042 
00043 static LONG
00044 ReadRegSzKey(
00045     IN HKEY hKey,
00046     IN LPCWSTR pszKey,
00047     OUT LPWSTR* pValue)
00048 {
00049     LONG rc;
00050     DWORD dwType;
00051     DWORD cbData = 0;
00052     LPWSTR Value;
00053 
00054     TRACE("(%p, %s, %p)\n", hKey, debugstr_w(pszKey), pValue);
00055 
00056     rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData);
00057     if (rc != ERROR_SUCCESS)
00058     {
00059         WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc);
00060         return rc;
00061     }
00062     if (dwType != REG_SZ)
00063     {
00064         WARN("Wrong registry data type (%u vs %u)\n", dwType, REG_SZ);
00065         return ERROR_FILE_NOT_FOUND;
00066     }
00067     Value = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
00068     if (!Value)
00069     {
00070         WARN("No memory\n");
00071         return ERROR_NOT_ENOUGH_MEMORY;
00072     }
00073     rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
00074     if (rc != ERROR_SUCCESS)
00075     {
00076         WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc);
00077         HeapFree(GetProcessHeap(), 0, Value);
00078         return rc;
00079     }
00080     /* NULL-terminate the string */
00081     Value[cbData / sizeof(WCHAR)] = '\0';
00082 
00083     *pValue = Value;
00084     return ERROR_SUCCESS;
00085 }
00086 
00087 static
00088 BOOL IsConsoleShell(VOID)
00089 {
00090     HKEY ControlKey = NULL;
00091     LPWSTR SystemStartOptions = NULL;
00092     LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
00093     LONG rc;
00094     BOOL ret = FALSE;
00095 
00096     TRACE("()\n");
00097 
00098     rc = RegOpenKeyEx(
00099         HKEY_LOCAL_MACHINE,
00100         REGSTR_PATH_CURRENT_CONTROL_SET,
00101         0,
00102         KEY_QUERY_VALUE,
00103         &ControlKey);
00104     if (rc != ERROR_SUCCESS)
00105     {
00106         WARN("RegOpenKeyEx() failed with error %lu\n", rc);
00107         goto cleanup;
00108     }
00109 
00110     rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
00111     if (rc != ERROR_SUCCESS)
00112     {
00113         WARN("ReadRegSzKey() failed with error %lu\n", rc);
00114         goto cleanup;
00115     }
00116 
00117     /* Check for CONSOLE in SystemStartOptions */
00118     CurrentOption = SystemStartOptions;
00119     while (CurrentOption)
00120     {
00121         NextOption = wcschr(CurrentOption, L' ');
00122         if (NextOption)
00123             *NextOption = L'\0';
00124         if (_wcsicmp(CurrentOption, L"CONSOLE") == 0)
00125         {
00126             TRACE("Found 'CONSOLE' boot option\n");
00127             ret = TRUE;
00128             goto cleanup;
00129         }
00130         CurrentOption = NextOption ? NextOption + 1 : NULL;
00131     }
00132 
00133 cleanup:
00134     if (ControlKey != NULL)
00135         RegCloseKey(ControlKey);
00136     HeapFree(GetProcessHeap(), 0, SystemStartOptions);
00137     TRACE("IsConsoleShell() returning %d\n", ret);
00138     return ret;
00139 }
00140 
00141 static
00142 BOOL GetShell(
00143     OUT WCHAR *CommandLine, /* must be at least MAX_PATH long */
00144     IN HKEY hRootKey)
00145 {
00146     HKEY hKey;
00147     DWORD Type, Size;
00148     WCHAR Shell[MAX_PATH];
00149     BOOL Ret = FALSE;
00150     BOOL ConsoleShell = IsConsoleShell();
00151     LONG rc;
00152 
00153     TRACE("(%p, %p)\n", CommandLine, hRootKey);
00154 
00155     rc = RegOpenKeyExW(hRootKey, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
00156                        0, KEY_QUERY_VALUE, &hKey);
00157     if (rc == ERROR_SUCCESS)
00158     {
00159         Size = MAX_PATH * sizeof(WCHAR);
00160         rc = RegQueryValueExW(hKey,
00161                               ConsoleShell ? L"ConsoleShell" : L"Shell",
00162                               NULL,
00163                               &Type,
00164                               (LPBYTE)Shell,
00165                               &Size);
00166         if (rc == ERROR_SUCCESS)
00167         {
00168             if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
00169             {
00170                 TRACE("Found command line %s\n", debugstr_w(Shell));
00171                 wcscpy(CommandLine, Shell);
00172                 Ret = TRUE;
00173             }
00174             else
00175                 WARN("Wrong type %lu (expected %u or %u)\n", Type, REG_SZ, REG_EXPAND_SZ);
00176         }
00177         else
00178             WARN("RegQueryValueEx() failed with error %lu\n", rc);
00179         RegCloseKey(hKey);
00180     }
00181     else
00182         WARN("RegOpenKeyEx() failed with error %lu\n", rc);
00183 
00184     return Ret;
00185 }
00186 
00187 static VOID
00188 StartAutoApplications(
00189     IN INT clsid)
00190 {
00191     WCHAR szPath[MAX_PATH] = {0};
00192     HRESULT hResult;
00193     HANDLE hFind;
00194     WIN32_FIND_DATAW findData;
00195     SHELLEXECUTEINFOW ExecInfo;
00196     size_t len;
00197 
00198     TRACE("(%d)\n", clsid);
00199 
00200     hResult = SHGetFolderPathW(NULL, clsid, NULL, SHGFP_TYPE_CURRENT, szPath);
00201     len = wcslen(szPath);
00202     if (!SUCCEEDED(hResult) || len == 0)
00203     {
00204         WARN("SHGetFolderPath() failed with error %lu\n", GetLastError());
00205         return;
00206     }
00207 
00208     wcscat(szPath, L"\\*");
00209     hFind = FindFirstFileW(szPath, &findData);
00210     if (hFind == INVALID_HANDLE_VALUE)
00211     {
00212         WARN("FindFirstFile(%s) failed with error %lu\n", debugstr_w(szPath), GetLastError());
00213         return;
00214     }
00215 
00216     do
00217     {
00218         if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (findData.nFileSizeHigh || findData.nFileSizeLow))
00219         {
00220             memset(&ExecInfo, 0x0, sizeof(SHELLEXECUTEINFOW));
00221             ExecInfo.cbSize = sizeof(ExecInfo);
00222             wcscpy(&szPath[len+1], findData.cFileName);
00223             ExecInfo.lpVerb = L"open";
00224             ExecInfo.lpFile = szPath;
00225             ExecInfo.lpDirectory = NULL;
00226             TRACE("Executing %s in directory %s\n",
00227                 debugstr_w(findData.cFileName), debugstr_w(szPath));
00228             ShellExecuteExW(&ExecInfo);
00229         }
00230     } while (FindNextFileW(hFind, &findData));
00231     FindClose(hFind);
00232 }
00233 
00234 static BOOL
00235 TryToStartShell(
00236     IN LPCWSTR Shell)
00237 {
00238     STARTUPINFO si;
00239     PROCESS_INFORMATION pi;
00240     WCHAR ExpandedShell[MAX_PATH];
00241 
00242     TRACE("(%s)\n", debugstr_w(Shell));
00243 
00244     ZeroMemory(&si, sizeof(STARTUPINFO));
00245     si.cb = sizeof(STARTUPINFO);
00246     ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
00247 
00248     ExpandEnvironmentStrings(Shell, ExpandedShell, MAX_PATH);
00249 
00250     if (!CreateProcess(NULL,
00251                       ExpandedShell,
00252                       NULL,
00253                       NULL,
00254                       FALSE,
00255                       NORMAL_PRIORITY_CLASS,
00256                       NULL,
00257                       NULL,
00258                       &si,
00259                       &pi))
00260     {
00261         WARN("CreateProcess() failed with error %lu\n", GetLastError());
00262         return FALSE;
00263     }
00264 
00265     StartAutoApplications(CSIDL_STARTUP);
00266     StartAutoApplications(CSIDL_COMMON_STARTUP);
00267     CloseHandle(pi.hProcess);
00268     CloseHandle(pi.hThread);
00269     return TRUE;
00270 }
00271 
00272 static
00273 VOID StartShell(VOID)
00274 {
00275     WCHAR Shell[MAX_PATH];
00276     TCHAR szMsg[RC_STRING_MAX_SIZE];
00277     DWORD Type, Size;
00278     DWORD Value = 0;
00279     LONG rc;
00280     HKEY hKey;
00281 
00282     TRACE("()\n");
00283 
00284     /* Safe Mode shell run */
00285     rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00286                        L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option",
00287                        0, KEY_QUERY_VALUE, &hKey);
00288     if(rc == ERROR_SUCCESS)
00289     {
00290         Size = sizeof(Value);
00291         rc = RegQueryValueExW(hKey, L"UseAlternateShell", NULL,
00292                               &Type, (LPBYTE)&Value, &Size);
00293         if(rc == ERROR_SUCCESS)
00294         {
00295             RegCloseKey(hKey);
00296             if(Type == REG_DWORD)
00297             {
00298                 if(Value)
00299                 {
00300                     /* Safe Mode Alternate Shell required */
00301                     rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
00302                                        L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot",
00303                                        0, KEY_READ, &hKey);
00304                     if(rc == ERROR_SUCCESS)
00305                     {
00306                         Size = MAX_PATH * sizeof(WCHAR);
00307                         rc = RegQueryValueExW(hKey, L"AlternateShell", NULL,
00308                                               &Type, (LPBYTE)Shell, &Size);
00309                         if(rc == ERROR_SUCCESS)
00310                         {
00311                             RegCloseKey(hKey);
00312                             if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
00313                             {
00314                                 TRACE("Key located - %s\n", debugstr_w(Shell));
00315                                 /* Try to run alternate shell */
00316                                 if (TryToStartShell(Shell))
00317                                 {
00318                                     TRACE("Alternate shell started (Safe Mode)\n");
00319                                     return;
00320                                 }
00321                             }
00322                             else
00323                             {
00324                                 WARN("Wrong type %lu (expected %u or %u)\n",
00325                                      Type, REG_SZ, REG_EXPAND_SZ);
00326                             }
00327                         }
00328                         else
00329                         {
00330                             WARN("Alternate shell in Safe Mode required but not specified.");
00331                         }
00332                     }
00333                 }
00334             }
00335             else
00336             {
00337                 WARN("Wrong type %lu (expected %u)\n", Type, REG_DWORD);
00338             }
00339         }
00340     }
00341     /* Try to run shell in user key */
00342     if (GetShell(Shell, HKEY_CURRENT_USER) && TryToStartShell(Shell))
00343     {
00344         TRACE("Started shell from HKEY_CURRENT_USER\n");
00345         return;
00346     }
00347 
00348     /* Try to run shell in local machine key */
00349     if (GetShell(Shell, HKEY_LOCAL_MACHINE) && TryToStartShell(Shell))
00350     {
00351         TRACE("Started shell from HKEY_LOCAL_MACHINE\n");
00352         return;
00353     }
00354 
00355     /* Try default shell */
00356     if (IsConsoleShell())
00357     {
00358         if (GetSystemDirectory(Shell, MAX_PATH - 8))
00359             wcscat(Shell, L"\\cmd.exe");
00360         else
00361             wcscpy(Shell, L"cmd.exe");
00362     }
00363     else
00364     {
00365         if (GetWindowsDirectory(Shell, MAX_PATH - 13))
00366             wcscat(Shell, L"\\explorer.exe");
00367         else
00368             wcscpy(Shell, L"explorer.exe");
00369     }
00370     if (!TryToStartShell(Shell))
00371     {
00372         WARN("Failed to start default shell %s\n", debugstr_w(Shell));
00373         LoadString( GetModuleHandle(NULL), STRING_USERINIT_FAIL, szMsg, sizeof(szMsg) / sizeof(szMsg[0]));
00374         MessageBox(0, szMsg, NULL, 0);
00375     }
00376 }
00377 
00378 const WCHAR g_RegColorNames[][32] = {
00379     L"Scrollbar",             /* 00 = COLOR_SCROLLBAR */
00380     L"Background",            /* 01 = COLOR_DESKTOP */
00381     L"ActiveTitle",           /* 02 = COLOR_ACTIVECAPTION  */
00382     L"InactiveTitle",         /* 03 = COLOR_INACTIVECAPTION */
00383     L"Menu",                  /* 04 = COLOR_MENU */
00384     L"Window",                /* 05 = COLOR_WINDOW */
00385     L"WindowFrame",           /* 06 = COLOR_WINDOWFRAME */
00386     L"MenuText",              /* 07 = COLOR_MENUTEXT */
00387     L"WindowText",            /* 08 = COLOR_WINDOWTEXT */
00388     L"TitleText",             /* 09 = COLOR_CAPTIONTEXT */
00389     L"ActiveBorder",          /* 10 = COLOR_ACTIVEBORDER */
00390     L"InactiveBorder",        /* 11 = COLOR_INACTIVEBORDER */
00391     L"AppWorkSpace",          /* 12 = COLOR_APPWORKSPACE */
00392     L"Hilight",               /* 13 = COLOR_HIGHLIGHT */
00393     L"HilightText",           /* 14 = COLOR_HIGHLIGHTTEXT */
00394     L"ButtonFace",            /* 15 = COLOR_BTNFACE */
00395     L"ButtonShadow",          /* 16 = COLOR_BTNSHADOW */
00396     L"GrayText",              /* 17 = COLOR_GRAYTEXT */
00397     L"ButtonText",            /* 18 = COLOR_BTNTEXT */
00398     L"InactiveTitleText",     /* 19 = COLOR_INACTIVECAPTIONTEXT */
00399     L"ButtonHilight",         /* 20 = COLOR_BTNHIGHLIGHT */
00400     L"ButtonDkShadow",        /* 21 = COLOR_3DDKSHADOW */
00401     L"ButtonLight",           /* 22 = COLOR_3DLIGHT */
00402     L"InfoText",              /* 23 = COLOR_INFOTEXT */
00403     L"InfoWindow",            /* 24 = COLOR_INFOBK */
00404     L"ButtonAlternateFace",   /* 25 = COLOR_ALTERNATEBTNFACE */
00405     L"HotTrackingColor",      /* 26 = COLOR_HOTLIGHT */
00406     L"GradientActiveTitle",   /* 27 = COLOR_GRADIENTACTIVECAPTION */
00407     L"GradientInactiveTitle", /* 28 = COLOR_GRADIENTINACTIVECAPTION */
00408     L"MenuHilight",           /* 29 = COLOR_MENUHILIGHT */
00409     L"MenuBar"                /* 30 = COLOR_MENUBAR */
00410 };
00411 #define NUM_SYSCOLORS (sizeof(g_RegColorNames) / sizeof(g_RegColorNames[0]))
00412 
00413 static
00414 COLORREF StrToColorref(
00415     IN LPWSTR lpszCol)
00416 {
00417     BYTE rgb[3];
00418 
00419     TRACE("(%s)\n", debugstr_w(lpszCol));
00420 
00421     rgb[0] = StrToIntW(lpszCol);
00422     lpszCol = StrChrW(lpszCol, L' ') + 1;
00423     rgb[1] = StrToIntW(lpszCol);
00424     lpszCol = StrChrW(lpszCol, L' ') + 1;
00425     rgb[2] = StrToIntW(lpszCol);
00426     return RGB(rgb[0], rgb[1], rgb[2]);
00427 }
00428 
00429 static
00430 VOID SetUserSysColors(VOID)
00431 {
00432     HKEY hKey;
00433     INT i;
00434     WCHAR szColor[20];
00435     DWORD Type, Size;
00436     COLORREF crColor;
00437     LONG rc;
00438 
00439     TRACE("()\n");
00440 
00441     rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_COLORS,
00442                       0, KEY_QUERY_VALUE, &hKey);
00443     if (rc != ERROR_SUCCESS)
00444     {
00445         WARN("RegOpenKeyEx() failed with error %lu\n", rc);
00446         return;
00447     }
00448     for(i = 0; i < NUM_SYSCOLORS; i++)
00449     {
00450         Size = sizeof(szColor);
00451         rc = RegQueryValueEx(hKey, g_RegColorNames[i], NULL, &Type,
00452                              (LPBYTE)szColor, &Size);
00453         if (rc == ERROR_SUCCESS && Type == REG_SZ)
00454         {
00455             crColor = StrToColorref(szColor);
00456             SetSysColors(1, &i, &crColor);
00457         }
00458         else
00459             WARN("RegQueryValueEx(%s) failed with error %lu\n",
00460                 debugstr_w(g_RegColorNames[i]), rc);
00461     }
00462     RegCloseKey(hKey);
00463 }
00464 
00465 static
00466 VOID SetUserWallpaper(VOID)
00467 {
00468     HKEY hKey;
00469     DWORD Type, Size;
00470     WCHAR szWallpaper[MAX_PATH + 1];
00471     LONG rc;
00472 
00473     TRACE("()\n");
00474 
00475     rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP,
00476                       0, KEY_QUERY_VALUE, &hKey);
00477     if (rc == ERROR_SUCCESS)
00478     {
00479         Size = sizeof(szWallpaper);
00480         rc = RegQueryValueEx(hKey,
00481                              L"Wallpaper",
00482                              NULL,
00483                              &Type,
00484                              (LPBYTE)szWallpaper,
00485                              &Size);
00486         if (rc == ERROR_SUCCESS && Type == REG_SZ)
00487         {
00488             ExpandEnvironmentStrings(szWallpaper, szWallpaper, MAX_PATH);
00489             TRACE("Using wallpaper %s\n", debugstr_w(szWallpaper));
00490 
00491             /* Load and change the wallpaper */
00492             SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_SENDCHANGE);
00493         }
00494         else
00495         {
00496             /* remove the wallpaper */
00497             TRACE("No wallpaper set in registry (error %lu)\n", rc);
00498             SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE);
00499         }
00500         RegCloseKey(hKey);
00501     }
00502     else
00503         WARN("RegOpenKeyEx() failed with error %lu\n", rc);
00504 }
00505 
00506 static
00507 VOID SetUserSettings(VOID)
00508 {
00509     TRACE("()\n");
00510 
00511     UpdatePerUserSystemParameters(1, TRUE);
00512     SetUserSysColors();
00513     SetUserWallpaper();
00514 }
00515 
00516 typedef DWORD (WINAPI *PCMP_REPORT_LOGON)(DWORD, DWORD);
00517 
00518 static VOID
00519 NotifyLogon(VOID)
00520 {
00521     HINSTANCE hModule;
00522     PCMP_REPORT_LOGON CMP_Report_LogOn;
00523 
00524     TRACE("()\n");
00525 
00526     hModule = LoadLibrary(L"setupapi.dll");
00527     if (hModule)
00528     {
00529         CMP_Report_LogOn = (PCMP_REPORT_LOGON)GetProcAddress(hModule, "CMP_Report_LogOn");
00530         if (CMP_Report_LogOn)
00531             CMP_Report_LogOn(CMP_MAGIC, GetCurrentProcessId());
00532         else
00533             WARN("GetProcAddress() failed\n");
00534 
00535         FreeLibrary(hModule);
00536     }
00537     else
00538         WARN("LoadLibrary() failed with error %lu\n", GetLastError());
00539 }
00540 
00541 #ifdef _MSC_VER
00542 #pragma warning(disable : 4100)
00543 #endif /* _MSC_VER */
00544 
00545 int WINAPI
00546 wWinMain(IN HINSTANCE hInst,
00547          IN HINSTANCE hPrevInstance,
00548          IN LPWSTR lpszCmdLine,
00549          IN int nCmdShow)
00550 {
00551     SetUserSettings();
00552     StartShell();
00553     NotifyLogon();
00554     return 0;
00555 }
00556 
00557 /* EOF */

Generated on Sun May 27 2012 04:18:53 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.