winlogon.c

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

C
998
字号
    {
      if (Msg.message == WM_HOTKEY)
        HandleHotKey(&Msg);
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
    }
  }

  UnregisterHotKeys();

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

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

  /* Unload user profile */
  UnloadUserProfile (WLSession->UserToken,
		     ProfileInfo.hProfile);

  CloseHandle (WLSession->UserToken);

  RtlDestroyEnvironment (lpEnvironment);

  return TRUE;
}
#endif

int STDCALL
WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nShowCmd)
{
#if SUPPORT_CONSOLESTART
//  WCHAR LoginName[255];
//  WCHAR Password[255];
#endif
#if 0
  LSA_STRING ProcessName, PackageName;
  HANDLE LsaHandle;
  LSA_OPERATIONAL_MODE Mode;
  ULONG AuthenticationPackage;
#endif

  hAppInstance = hInstance;

  if(!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
  {
    DPRINT1("WL: Could not register logon process\n");
    NtShutdownSystem(ShutdownNoReboot);
    ExitProcess(0);
    return 0;
  }

#if START_LSASS
  if (StartProcess(L"StartLsass"))
  {
    if (!StartLsass())
	{
	  DPRINT1("WL: Failed to start LSASS (0x%X)\n", GetLastError());
	}
  }
  else
  {
	  DPRINT1("WL: StartProcess() failed!\n");
  }
#endif

  if(!(WLSession = MsGinaInit()))
  {
    DPRINT1("WL: Failed to initialize msgina.dll\n");
    NtShutdownSystem(ShutdownNoReboot);
    ExitProcess(0);
    return 0;
  }

  WLSession->LogonStatus = LOGON_INITIALIZING;

  if(!WlxCreateWindowStationAndDesktops(WLSession))
  {
    NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
    ExitProcess(1);
    return 1;
  }

  /*
   * Switch to winlogon desktop
   */
  /* FIXME: Do start up in the application desktop for now. */
  SetThreadDesktop(WLSession->ApplicationDesktop);
  if(!SwitchDesktop(WLSession->ApplicationDesktop))
  {
    DPRINT1("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
  }

  InitServices();
  
  /* Check for pending setup */
  if (GetSetupType () != 0)
  {
    DPRINT("Winlogon: CheckForSetup() in setup mode\n");

    /* Run setup and reboot when done */
    RunSetup();

    NtShutdownSystem(ShutdownReboot);
    ExitProcess(0);
    return 0;
  }

#if SUPPORT_CONSOLESTART
  StartConsole = !StartIntoGUI();
#endif
  if(!InitializeSAS(WLSession))
  {
    DPRINT1("WL: Failed to initialize SAS\n");
    ExitProcess(2);
    return 2;
  }

#if 0
   /* real winlogon uses "Winlogon" */
   RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon");
   Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
   if (!NT_SUCCESS(Status))
   {
     switch(Status)
     {
       case STATUS_PORT_CONNECTION_REFUSED:
         /* FIXME - we don't have the 'SeTcbPrivilege' pivilege, so set it or call
                    LsaAddAccountRights() and try again */
         DPRINT1("WL: LsaRegisterLogonProcess() returned STATUS_PORT_CONNECTION_REFUSED\n");
         break;
       case STATUS_NAME_TOO_LONG:
         DPRINT1("WL: LsaRegisterLogonProcess() returned STATUS_NAME_TOO_LONG\n");
         break;
       default:
         DPRINT1("WL: Failed to connect to LSASS\n");
         break;
     }
     return(1);
   }

   RtlInitUnicodeString((PUNICODE_STRING)&PackageName, L"Kerberos");
   Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage);
   if (!NT_SUCCESS(Status))
   {
     LsaDeregisterLogonProcess(LsaHandle);
     DPRINT1("WL: Failed to lookup authentication package\n");
     return(1);
   }
#endif

   /* FIXME: Create a window class and associate a Winlogon
    *        window procedure with it.
    *        Register SAS with the window.
    *        Register for logoff notification
    */

   /* Main loop */
#if 0
   /* Display login prompt */
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
                LoginPrompt,
                strlen(LoginPrompt),  // wcslen(LoginPrompt),
                &Result,
                NULL);
   i = 0;
   do
     {
       ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
                   &LoginName[i],
                   1,
                   &Result,
                   NULL);
       i++;
     } while (LoginName[i - 1] != '\n');
   LoginName[i - 1] = 0;

   /* Display password prompt */
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
                PasswordPrompt,
                strlen(PasswordPrompt),  // wcslen(PasswordPrompt),
                &Result,
                NULL);
   i = 0;
   do
     {
       ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
                   &Password[i],
                   1,
                   &Result,
                   NULL);
       i++;
     } while (Password[i - 1] != '\n');
   Password[i - 1] =0;
#endif

#if SUPPORT_CONSOLESTART
 if(StartConsole)
 {
//   if (! DoLogonUser(LoginName, Password))
   if (! DoLogonUser(L"Administrator", L"Secret"))
     {
     }

   NtShutdownSystem(ShutdownNoReboot);
   ExitProcess(0);
 }
 else
 {
#endif

   RegisterHotKeys();

   SessionLoop(WLSession);

   UnregisterHotKeys();

   /* FIXME - Flush disks and registry, ... */

   if(WLSession->LogonStatus == LOGON_SHUTDOWN)
   {
     /* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */
     switch(DialogBox(hInstance, MAKEINTRESOURCE(IDD_SHUTDOWNCOMPUTER), 0, ShutdownComputerProc))
     {
       case IDC_BTNSHTDOWNCOMPUTER:
         NtShutdownSystem(ShutdownReboot);
         break;
       default:
         NtShutdownSystem(ShutdownNoReboot);
         break;
     }
     ExitProcess(0);
   }
   else
   {
     DPRINT1("WL: LogonStatus != LOGON_SHUTDOWN!!!\n");
     ExitProcess(0);
   }
#if SUPPORT_CONSOLESTART
 }
#endif

   return 0;
}

BOOL
DisplayStatusMessage(PWLSESSION Session, HDESK hDesktop, DWORD dwOptions, PWSTR pTitle, PWSTR pMessage)
{
  if(Session->SuppressStatus)
  {
    return TRUE;
  }

  #if SUPPORT_CONSOLESTART
  if(StartConsole)
  {
    if(pMessage)
    {
      DPRINT1("WL-Status: %ws\n", pMessage);
    }
    return TRUE;
  }
  #endif

  return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, dwOptions, pTitle, pMessage);
}

BOOL
InitServices(void)
{
  WCHAR StatusMsg[256];

  LoadString(hAppInstance, IDS_REACTOSISSTARTINGUP, StatusMsg, 256 * sizeof(WCHAR));
  DisplayStatusMessage(WLSession, WLSession->ApplicationDesktop, 0, NULL, StatusMsg);

  /* start system processes (services.exe & lsass.exe) */
  if(StartProcess(L"StartServices"))
  {
	if(!StartServices())
    {
      DPRINT1("WL: Failed to start Services (0x%X)\n", GetLastError());
    }
  }
  else
  {
	  DPRINT1("WL: StartProcess() failed!\n");
  }

  return TRUE;
}

DWORD
DoLogin(PWLSESSION Session)
{
  DWORD WlxAction, Options;
  WLX_MPR_NOTIFY_INFO MprNotifyInfo;
  PWLX_PROFILE_V2_0 Profile;
  PSID LogonSid = NULL;
  HANDLE Token;

  /* FIXME - Create a Logon Sid
  if(!(LogonSid = CreateUserLogonSid(NULL)))
  {
    return WLX_SAS_ACTION_NONE;
  }
  */

  Options = 0;
  WlxAction = Session->MsGina.Functions.WlxLoggedOutSAS(Session->MsGina.Context,
                                                        Session->SASAction,
                                                        &Session->LogonId,
                                                        LogonSid,
                                                        &Options,
                                                        &Token,
                                                        &MprNotifyInfo,
                                                        (PVOID*)&Profile);

  return WlxAction;
}

void
SessionLoop(PWLSESSION Session)
{
  //WCHAR StatusMsg[256];
 // HANDLE hShutdownEvent;
  DWORD WlxAction;
  MSG Msg;

  WlxAction = WLX_SAS_ACTION_NONE;
  Session->LogonStatus = LOGON_NONE;
  while(WlxAction == WLX_SAS_ACTION_NONE)
  {
    RemoveStatusMessage(Session);
    if(Session->LogonStatus == LOGON_NONE)
    {
      Session->LogonStatus = LOGON_SHOWINGLOGON;
      /* we're ready to display a logon window,
         don't timeout dialogboxes here */
      WlxSetTimeout(Session->MsGina.Context, 0);
      Session->SuppressStatus = TRUE;
      /* tell msgina to show a window telling the user one can logon */
      #if SUPPORT_CONSOLESTART
      if(!StartConsole)
      #endif
      DisplaySASNotice(Session);
      Session->SuppressStatus = FALSE;

      if(Session->SASAction == WLX_SAS_ACTION_LOGOFF)
      {
        /* the system wants to log off here */
        Session->LogonStatus = LOGON_SHUTDOWN;
        break;
      }
    }

    WlxAction = DoLogin(Session);
    if(WlxAction == WLX_SAS_ACTION_LOGOFF)
    {
      /* the user doesn't want to login, instead pressed cancel
         we should display the window again so one can logon again */
      /* FIXME - disconnect any connections in case we did a remote logon */
      DPRINT1("WL: DoLogin failed\n");
      WlxAction = WLX_SAS_ACTION_NONE;
    }
    if(WlxAction == WLX_SAS_ACTION_NONE)
    {
      if(Session->SASAction == WLX_SAS_ACTION_LOGOFF)
      {
        /* system is about to shut down, leave the main loop */
        Session->LogonStatus = LOGON_SHUTDOWN;
        break;
      }
      Session->LogonStatus = LOGON_NONE;
      continue;
    }

    /* FIXME - don't leave the loop when suspending the computer */
    if(WLX_SUSPENDING(WlxAction))
    {
      Session->LogonStatus = LOGON_NONE;
      WlxAction = WLX_SAS_ACTION_NONE;
      /* don't leave the loop */
      continue;
    }

    if(WLX_SHUTTINGDOWN(WlxAction))
    {
      Session->LogonStatus = LOGON_SHUTDOWN;
      /* leave the loop here */
      break;
    }

    /* Message loop for the SAS window */
    while(GetMessage(&Msg, 0, 0, 0))
    {
      if (Msg.message == WM_HOTKEY)
        HandleHotKey(&Msg);
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
    }
  }
   /*
   LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR));
   MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
                                                  ApplicationDesktop,
                                                  0,
                                                  NULL,
                                                  StatusMsg);


   Sleep(150);

   LoadString(hAppInstance, IDS_APPLYINGCOMPUTERSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
   MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
                                                  ApplicationDesktop,
                                                  0,
                                                  NULL,
                                                  StatusMsg);


   Sleep(150);

   MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
   MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
   MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);


    Sleep(250);

   LoadString(hAppInstance, IDS_LOADINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
   MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
                                                  ApplicationDesktop,
                                                  0,
                                                  NULL,
                                                  StatusMsg);

   Sleep(150);

   LoadString(hAppInstance, IDS_APPLYINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
   MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
                                                  ApplicationDesktop,
                                                  0,
                                                  NULL,
                                                  StatusMsg);


   Sleep(150);

   MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
   MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);

   if(!MsGinaInst->Functions->WlxActivateUserShell(MsGinaInst->Context,
                                                   L"WinSta0\\Default",
                                                   NULL,
                                                   NULL))
   {
     LoadString(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, 256 * sizeof(WCHAR));
     MessageBox(0, StatusMsg, NULL, MB_ICONERROR);
     SetEvent(hShutdownEvent);
   }


   WaitForSingleObject(hShutdownEvent, INFINITE);
   CloseHandle(hShutdownEvent);

   LoadString(hAppInstance, IDS_SAVEYOURSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
   MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
                                                  ApplicationDesktop,
                                                  0,
                                                  NULL,
                                                  StatusMsg);


   Sleep(150);

   MsGinaInst->Functions->WlxShutdown(MsGinaInst->Context, WLX_SAS_ACTION_SHUTDOWN);

   LoadString(hAppInstance, IDS_REACTOSISSHUTTINGDOWN, StatusMsg, 256 * sizeof(WCHAR));
   MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
                                                  ApplicationDesktop,
                                                  0,
                                                  NULL,
                                                  StatusMsg);


   Sleep(250);

   MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
   MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
   */
}

⌨️ 快捷键说明

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