winlogon.c

来自「一个类似windows」· C语言 代码 · 共 998 行 · 第 1/2 页

C
998
字号
/* $Id: winlogon.c 21392 2006-03-25 21:04:40Z fireball $
 *
 * COPYRIGHT:       See COPYING in the top level directory
 * PROJECT:         ReactOS kernel
 * FILE:            services/winlogon/winlogon.c
 * PURPOSE:         Logon
 * PROGRAMMER:      David Welch (welch@cwcom.net)
 * UPDATE HISTORY:
 *                  Created 22/05/98
 */

/* INCLUDES *****************************************************************/
#include "winlogon.h"

#define NDEBUG
#include <debug.h>

#define SUPPORT_CONSOLESTART 1
#define START_LSASS          1

/* GLOBALS ******************************************************************/

BOOL
LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion);
PWLSESSION
MsGinaInit(void);
void
SessionLoop(PWLSESSION Session);
BOOL
InitServices(void);
BOOL
WlxCreateWindowStationAndDesktops(PWLSESSION Session);

HINSTANCE hAppInstance;
PWLSESSION WLSession = NULL;

#if SUPPORT_CONSOLESTART
BOOL StartConsole = TRUE;
#endif

/* FUNCTIONS *****************************************************************/

static void
PrintString (WCHAR* fmt,...)
{
   WCHAR buffer[512];
   va_list ap;

   va_start(ap, fmt);
   wsprintf(buffer, fmt, ap);
   va_end(ap);

   OutputDebugString(buffer);
}


INT_PTR CALLBACK
ShutdownComputerProc (HWND hwndDlg,
		      UINT uMsg,
		      WPARAM wParam,
		      LPARAM lParam)
{
  switch(uMsg)
  {
    case WM_COMMAND:
    {
      switch(LOWORD(wParam))
      {
        case IDC_BTNSHTDOWNCOMPUTER:
          EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER);
          break;
      }
      break;
    }
    case WM_INITDIALOG:
    {
      RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
      SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER));
      break;
    }
  }
  return FALSE;
}

static BOOLEAN
StartServices (VOID)
{
   HANDLE ServicesInitEvent;
   BOOLEAN Result;
   STARTUPINFO StartupInfo;
   PROCESS_INFORMATION ProcessInformation;
   DWORD Count;
   WCHAR ServiceString[] = L"services.exe";

   /* Start the service control manager (services.exe) */

   StartupInfo.cb = sizeof(StartupInfo);
   StartupInfo.lpReserved = NULL;
   StartupInfo.lpDesktop = NULL;
   StartupInfo.lpTitle = NULL;
   StartupInfo.dwFlags = 0;
   StartupInfo.cbReserved2 = 0;
   StartupInfo.lpReserved2 = 0;

#if 0
   PrintString(L"WL: Creating new process - \"services.exe\".\n");
#endif

   Result = CreateProcess(NULL,
                          ServiceString,
                          NULL,
                          NULL,
                          FALSE,
                          DETACHED_PROCESS,
                          NULL,
                          NULL,
                          &StartupInfo,
                          &ProcessInformation);
   if (!Result)
     {
        PrintString(L"WL: Failed to execute services\n");
        return FALSE;
     }

   /* wait for event creation (by SCM) for max. 20 seconds */
   for (Count = 0; Count < 20; Count++)
     {
        Sleep(1000);

        DPRINT("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
        ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
                                      FALSE,
                                      L"SvcctrlStartEvent_A3725DX");
        if (ServicesInitEvent != NULL)
          {
             break;
          }
     }

   if (ServicesInitEvent == NULL)
     {
        DPRINT1("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
        return FALSE;
     }

   /* wait for event signalization */
   DPRINT("WL: Waiting forever on event handle: %x\n", ServicesInitEvent);
   WaitForSingleObject(ServicesInitEvent, INFINITE);
   DPRINT("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
   CloseHandle(ServicesInitEvent);
   DPRINT("WL: StartServices() Done.\n");

   return TRUE;
}

#if START_LSASS
static BOOLEAN
StartLsass (VOID)
{
   HANDLE LsassInitEvent;
   BOOLEAN Result;
   STARTUPINFO StartupInfo;
   PROCESS_INFORMATION ProcessInformation;
   WCHAR ServiceString[] = L"lsass.exe";

   LsassInitEvent = CreateEvent(NULL,
                                TRUE,
                                FALSE,
                                L"\\SECURITY_SERVICES_STARTED");

   if (LsassInitEvent == NULL)
     {
        DPRINT1("WL: Failed to create lsass notification event\n");
        return(FALSE);
     }

   /* Start the local security authority subsystem (lsass.exe) */

   StartupInfo.cb = sizeof(StartupInfo);
   StartupInfo.lpReserved = NULL;
   StartupInfo.lpDesktop = NULL;
   StartupInfo.lpTitle = NULL;
   StartupInfo.dwFlags = 0;
   StartupInfo.cbReserved2 = 0;
   StartupInfo.lpReserved2 = 0;

   Result = CreateProcess(NULL,
                          ServiceString,
                          NULL,
                          NULL,
                          FALSE,
                          DETACHED_PROCESS,
                          NULL,
                          NULL,
                          &StartupInfo,
                          &ProcessInformation);
   if (!Result)
     {
        DPRINT1("WL: Failed to execute lsass\n");
        return(FALSE);
     }

   WaitForSingleObject(LsassInitEvent, INFINITE);
   CloseHandle(LsassInitEvent);

   return(TRUE);
}
#endif


static BOOLEAN
OpenRegistryKey (HKEY *WinLogonKey)
{
   return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                                        L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
                                        0,
                                        KEY_QUERY_VALUE,
                                        WinLogonKey);
}


static BOOLEAN StartProcess(PWCHAR ValueName)
{
   BOOL StartIt;
   HKEY WinLogonKey;
   DWORD Type;
   DWORD Size;
   DWORD StartValue;

   StartIt = TRUE;
   if (OpenRegistryKey(&WinLogonKey))
     {
	Size = sizeof(DWORD);
	if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
                                             ValueName,
	                                     NULL,
	                                     &Type,
	                                     (LPBYTE) &StartValue,
                                             &Size))
	   {
	   if (REG_DWORD == Type)
	     {
		StartIt = (0 != StartValue);
	     }
	   }
	RegCloseKey(WinLogonKey);
     }

   return StartIt;
}

/*
static BOOL RestartShell(void)
{
  HKEY WinLogonKey;
  DWORD Type, Size, Value;

  if(OpenRegistryKey(&WinLogonKey))
  {
    Size = sizeof(DWORD);
    if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
                                        L"AutoRestartShell",
                                        NULL,
                                        &Type,
                                        (LPBYTE)&Value,
                                        &Size))
    {
      if(Type == REG_DWORD)
      {
        RegCloseKey(WinLogonKey);
        return (Value != 0);
      }
    }
    RegCloseKey(WinLogonKey);
  }
  return FALSE;
}
*/

VOID STDCALL
RegisterHotKeys(VOID)
{
  RegisterHotKey(NULL, 0, MOD_ALT | MOD_CONTROL, VK_DELETE);
}

VOID STDCALL
UnregisterHotKeys(VOID)
{
  UnregisterHotKey(NULL, 0);
}

VOID STDCALL
HandleHotKey(MSG *Msg)
{
  DPRINT1("HOTKEY: Got hot key (%d)\n", Msg->wParam);

  /* CTRL-ALT-DEL */
  if (Msg->wParam == 0)
  {
    STARTUPINFO StartupInfo;
    PROCESS_INFORMATION ProcessInformation;

    StartupInfo.cb = sizeof(StartupInfo);
    StartupInfo.lpReserved = NULL;
    StartupInfo.lpDesktop = NULL;
    StartupInfo.lpTitle = NULL;
    StartupInfo.dwFlags = 0;
    StartupInfo.cbReserved2 = 0;
    StartupInfo.lpReserved2 = 0;

    CreateProcessW(
      L"taskmgr.exe",
      NULL,
      NULL,
      NULL,
      FALSE,
      CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
      NULL,
      NULL,
      &StartupInfo,
      &ProcessInformation);

    CloseHandle (ProcessInformation.hProcess);
    CloseHandle (ProcessInformation.hThread);
  }
}

#if SUPPORT_CONSOLESTART
static BOOL StartIntoGUI(VOID)
{
  HKEY WinLogonKey;
  DWORD Type, Size, Value;

  if(OpenRegistryKey(&WinLogonKey))
  {
    Size = sizeof(DWORD);
    if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
                                        L"StartGUI",
                                        NULL,
                                        &Type,
                                        (LPBYTE)&Value,
                                        &Size))
    {
      if(Type == REG_DWORD)
      {
        RegCloseKey(WinLogonKey);
        return (Value != 0);
      }
    }
    RegCloseKey(WinLogonKey);
  }
  return FALSE;
}


static PWCHAR
GetUserInit (WCHAR *CommandLine)
{
   HKEY WinLogonKey;
   BOOL GotCommandLine;
   DWORD Type;
   DWORD Size;
   WCHAR Shell[_MAX_PATH];

   GotCommandLine = FALSE;
   if (OpenRegistryKey(&WinLogonKey))
     {
	Size = MAX_PATH;
	if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
                                         L"UserInit",
	                                     NULL,
	                                     &Type,
	                                     (LPBYTE) Shell,
                                         &Size))
	   {
	   if (REG_EXPAND_SZ == Type)
	     {
		ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH);
		GotCommandLine = TRUE;
	     }
	   else if (REG_SZ == Type)
	     {
		wcscpy(CommandLine, Shell);
		GotCommandLine = TRUE;
	     }
	   }
	RegCloseKey(WinLogonKey);
     }

   if (! GotCommandLine)
     {
	GetSystemDirectory(CommandLine, MAX_PATH - 15);
	wcscat(CommandLine, L"\\userinit.exe");
     }

   return CommandLine;
}


static BOOL
DoLogonUser (PWCHAR Name,
	     PWCHAR Password)
{
  PROCESS_INFORMATION ProcessInformation;
  STARTUPINFO StartupInfo;
  WCHAR CommandLine[MAX_PATH];
  WCHAR CurrentDirectory[MAX_PATH];
  PROFILEINFOW ProfileInfo;
  BOOL Result;
  LPVOID lpEnvironment = NULL;
  MSG Msg;

  Result = LogonUserW (Name,
		       NULL,
		       Password,
		       LOGON32_LOGON_INTERACTIVE,
		       LOGON32_PROVIDER_DEFAULT,
		       &WLSession->UserToken);
  if (!Result)
    {
      DPRINT1 ("WL: LogonUserW() failed\n");
      RtlDestroyEnvironment (lpEnvironment);
      return FALSE;
    }

  /* Load the user profile */
  ProfileInfo.dwSize = sizeof(PROFILEINFOW);
  ProfileInfo.dwFlags = 0;
  ProfileInfo.lpUserName = Name;
  ProfileInfo.lpProfilePath = NULL;
  ProfileInfo.lpDefaultPath = NULL;
  ProfileInfo.lpServerName = NULL;
  ProfileInfo.lpPolicyPath = NULL;
  ProfileInfo.hProfile = NULL;

  if (!LoadUserProfileW (WLSession->UserToken,
			 &ProfileInfo))
    {
      DPRINT1 ("WL: LoadUserProfileW() failed\n");
      CloseHandle (WLSession->UserToken);
      RtlDestroyEnvironment (lpEnvironment);
      return FALSE;
    }

  if (!CreateEnvironmentBlock (&lpEnvironment,
			       WLSession->UserToken,
			       TRUE))
    {
      DPRINT1("WL: CreateEnvironmentBlock() failed\n");
      return FALSE;
    }

  if (ImpersonateLoggedOnUser(WLSession->UserToken))
    {
      UpdatePerUserSystemParameters(0, TRUE);
      RevertToSelf();
    }

  GetWindowsDirectoryW (CurrentDirectory, MAX_PATH);

  StartupInfo.cb = sizeof(StartupInfo);
  StartupInfo.lpReserved = NULL;
  StartupInfo.lpDesktop = NULL;
  StartupInfo.lpTitle = NULL;
  StartupInfo.dwFlags = 0;
  StartupInfo.cbReserved2 = 0;
  StartupInfo.lpReserved2 = 0;

  Result = CreateProcessAsUserW (WLSession->UserToken,
				 NULL,
				 GetUserInit (CommandLine),
				 NULL,
				 NULL,
				 FALSE,
				 CREATE_UNICODE_ENVIRONMENT,
				 lpEnvironment,
				 CurrentDirectory,
				 &StartupInfo,
				 &ProcessInformation);
  if (!Result)
    {
      DPRINT1("WL: Failed to execute user shell %s\n", CommandLine);
      if (ImpersonateLoggedOnUser(WLSession->UserToken))
        {
          UpdatePerUserSystemParameters(0, FALSE);
          RevertToSelf();
        }
      UnloadUserProfile (WLSession->UserToken,
			 ProfileInfo.hProfile);
      CloseHandle (WLSession->UserToken);
      DestroyEnvironmentBlock (lpEnvironment);
      return FALSE;
    }

  RegisterHotKeys();

  while (WaitForSingleObject (ProcessInformation.hProcess, 100) != WAIT_OBJECT_0)
  {
    if (PeekMessage(&Msg, 0, 0, 0, PM_REMOVE))

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?