msgina.c
来自「一个类似windows」· C语言 代码 · 共 563 行
C
563 行
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: msgina.c 21429 2006-03-31 17:47:52Z tretiakov $
*
* PROJECT: ReactOS msgina.dll
* FILE: lib/msgina/msgina.c
* PURPOSE: ReactOS Logon GINA DLL
* PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* UPDATE HISTORY:
* 24-11-2003 Created
*/
#include <windows.h>
#include <winwlx.h>
#include "msgina.h"
#include "resource.h"
#include <wine/debug.h>
extern HINSTANCE hDllInstance;
typedef struct _DISPLAYSTATUSMSG
{
PGINA_CONTEXT Context;
HDESK hDesktop;
DWORD dwOptions;
PWSTR pTitle;
PWSTR pMessage;
HANDLE StartupEvent;
} DISPLAYSTATUSMSG, *PDISPLAYSTATUSMSG;
INT_PTR CALLBACK
LoggedOnDlgProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDYES:
case IDNO:
{
EndDialog(hwndDlg, LOWORD(wParam));
break;
}
}
return FALSE;
}
case WM_INITDIALOG:
{
SetFocus(GetDlgItem(hwndDlg, IDNO));
break;
}
case WM_CLOSE:
{
EndDialog(hwndDlg, IDNO);
return TRUE;
}
}
return FALSE;
}
/*
* @implemented
*/
BOOL WINAPI
WlxNegotiate(
DWORD dwWinlogonVersion,
PDWORD pdwDllVersion)
{
if(!pdwDllVersion || (dwWinlogonVersion < GINA_VERSION))
return FALSE;
*pdwDllVersion = GINA_VERSION;
return TRUE;
}
/*
* @implemented
*/
BOOL WINAPI
WlxInitialize(
LPWSTR lpWinsta,
HANDLE hWlx,
PVOID pvReserved,
PVOID pWinlogonFunctions,
PVOID *pWlxContext)
{
PGINA_CONTEXT pgContext;
pgContext = (PGINA_CONTEXT)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(GINA_CONTEXT));
if(!pgContext)
return FALSE;
/* return the context to winlogon */
*pWlxContext = (PVOID)pgContext;
pgContext->hDllInstance = hDllInstance;
/* save pointer to dispatch table */
pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION)pWinlogonFunctions;
/* save the winlogon handle used to call the dispatch functions */
pgContext->hWlx = hWlx;
/* save window station */
pgContext->station = lpWinsta;
/* clear status window handle */
pgContext->hStatusWindow = 0;
/* notify winlogon that we will use the default SAS */
pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx);
return TRUE;
}
/*
* @implemented
*/
BOOL WINAPI
WlxStartApplication(
PVOID pWlxContext,
PWSTR pszDesktopName,
PVOID pEnvironment,
PWSTR pszCmdLine)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL Ret;
si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpTitle = pszCmdLine;
si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L;
si.dwFlags = 0;
si.wShowWindow = SW_SHOW;
si.lpReserved2 = NULL;
si.cbReserved2 = 0;
si.lpDesktop = pszDesktopName;
Ret = CreateProcessAsUser(pgContext->UserToken,
NULL,
pszCmdLine,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
pEnvironment,
NULL,
&si,
&pi);
VirtualFree(pEnvironment, 0, MEM_RELEASE);
return Ret;
}
/*
* @implemented
*/
BOOL WINAPI
WlxActivateUserShell(
PVOID pWlxContext,
PWSTR pszDesktopName,
PWSTR pszMprLogonScript,
PVOID pEnvironment)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HKEY hKey;
DWORD BufSize, ValueType;
WCHAR pszUserInitApp[MAX_PATH];
WCHAR pszExpUserInitApp[MAX_PATH];
BOOL Ret;
/* get the path of userinit */
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\Winlogon",
0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
{ERR("GINA: Failed: 1\n");
VirtualFree(pEnvironment, 0, MEM_RELEASE);
return FALSE;
}
BufSize = MAX_PATH * sizeof(WCHAR);
if((RegQueryValueEx(hKey, L"Userinit", NULL, &ValueType, (LPBYTE)pszUserInitApp,
&BufSize) != ERROR_SUCCESS) ||
!((ValueType == REG_SZ) || (ValueType == REG_EXPAND_SZ)))
{ERR("GINA: Failed: 2\n");
RegCloseKey(hKey);
VirtualFree(pEnvironment, 0, MEM_RELEASE);
return FALSE;
}
RegCloseKey(hKey);
/* start userinit */
/* FIXME - allow to start more applications that are comma-separated */
si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpTitle = L"userinit";
si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0;
si.dwFlags = 0;
si.wShowWindow = SW_SHOW;
si.lpReserved2 = NULL;
si.cbReserved2 = 0;
si.lpDesktop = pszDesktopName;
ExpandEnvironmentStrings(pszUserInitApp, pszExpUserInitApp, MAX_PATH);
Ret = CreateProcessAsUser(pgContext->UserToken,
pszExpUserInitApp,
NULL,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
pEnvironment,
NULL,
&si,
&pi);
if(!Ret) ERR("GINA: Failed: 3\n");
VirtualFree(pEnvironment, 0, MEM_RELEASE);
return Ret;
}
/*
* @implemented
*/
int WINAPI
WlxLoggedOnSAS(
PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
int SasAction = WLX_SAS_ACTION_NONE;
switch(dwSasType)
{
case WLX_SAS_TYPE_CTRL_ALT_DEL:
{
int Result;
/* display "Are you sure you want to log off?" dialog */
Result = pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx,
pgContext->hDllInstance,
(LPTSTR)IDD_LOGOFF_DLG,
NULL,
LoggedOnDlgProc,
(LPARAM)pgContext);
if(Result == IDOK)
{
SasAction = WLX_SAS_ACTION_LOCK_WKSTA;
}
break;
}
case WLX_SAS_TYPE_SC_INSERT:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n");
break;
}
case WLX_SAS_TYPE_SC_REMOVE:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n");
break;
}
case WLX_SAS_TYPE_TIMEOUT:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_TIMEOUT not supported!\n");
break;
}
default:
{
WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType);
break;
}
}
return SasAction;
}
BOOL
CALLBACK
StatusMessageWindowProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam;
if(!msg)
return FALSE;
msg->Context->hStatusWindow = hwndDlg;
if(msg->pTitle)
SetWindowText(hwndDlg, msg->pTitle);
SetDlgItemText(hwndDlg, IDC_STATUSLABEL, msg->pMessage);
if(!msg->Context->SignaledStatusWindowCreated)
{
msg->Context->SignaledStatusWindowCreated = TRUE;
SetEvent(msg->StartupEvent);
}
break;
}
}
return FALSE;
}
DWORD WINAPI
StartupWindowThread(LPVOID lpParam)
{
HDESK OldDesk;
PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam;
OldDesk = GetThreadDesktop(GetCurrentThreadId());
if(!SetThreadDesktop(msg->hDesktop))
{
HeapFree(GetProcessHeap(), 0, lpParam);
return FALSE;
}
DialogBoxParam(hDllInstance,
MAKEINTRESOURCE(IDD_STATUSWINDOW),
0,
StatusMessageWindowProc,
(LPARAM)lpParam);
SetThreadDesktop(OldDesk);
msg->Context->hStatusWindow = 0;
msg->Context->SignaledStatusWindowCreated = FALSE;
HeapFree(GetProcessHeap(), 0, lpParam);
return TRUE;
}
/*
* @implemented
*/
BOOL WINAPI
WlxDisplayStatusMessage(
PVOID pWlxContext,
HDESK hDesktop,
DWORD dwOptions,
PWSTR pTitle,
PWSTR pMessage)
{
PDISPLAYSTATUSMSG msg;
HANDLE Thread;
DWORD ThreadId;
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
if(!pgContext->hStatusWindow)
{
msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG));
if(!msg)
return FALSE;
msg->Context = pgContext;
msg->dwOptions = dwOptions;
msg->pTitle = pTitle;
msg->pMessage = pMessage;
msg->hDesktop = hDesktop;
msg->StartupEvent = CreateEvent(NULL,
TRUE,
FALSE,
NULL);
if(!msg->StartupEvent)
return FALSE;
Thread = CreateThread(NULL,
0,
StartupWindowThread,
(PVOID)msg,
0,
&ThreadId);
if(Thread)
{
CloseHandle(Thread);
WaitForSingleObject(msg->StartupEvent, INFINITE);
CloseHandle(msg->StartupEvent);
return TRUE;
}
return FALSE;
}
if(pTitle)
SetWindowText(pgContext->hStatusWindow, pTitle);
SetDlgItemText(pgContext->hStatusWindow, IDC_STATUSLABEL, pMessage);
return TRUE;
}
/*
* @implemented
*/
BOOL WINAPI
WlxRemoveStatusMessage(
PVOID pWlxContext)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
if(pgContext->hStatusWindow)
{
EndDialog(pgContext->hStatusWindow, 0);
pgContext->hStatusWindow = 0;
}
return TRUE;
}
/*
* @implemented
*/
VOID WINAPI
WlxDisplaySASNotice(
PVOID pWlxContext)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
}
static PWSTR
DuplicationString(PWSTR Str)
{
DWORD cb;
PWSTR NewStr;
cb = (wcslen(Str) + 1) * sizeof(WCHAR);
if((NewStr = LocalAlloc(LMEM_FIXED, cb)))
{
memcpy(NewStr, Str, cb);
}
return NewStr;
}
/*
* @unimplemented
*/
int WINAPI
WlxLoggedOutSAS(
PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
PVOID *pProfile)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
TOKEN_STATISTICS Stats;
DWORD cbStats;
if(!phToken)
{
WARN("msgina: phToken == NULL!\n");
return WLX_SAS_ACTION_NONE;
}
if(!LogonUser(L"Administrator", NULL, L"Secrect",
LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */
LOGON32_PROVIDER_DEFAULT,
phToken))
{
WARN("msgina: Logonuser() failed\n");
return WLX_SAS_ACTION_NONE;
}
if(!(*phToken))
{
WARN("msgina: *phToken == NULL!\n");
return WLX_SAS_ACTION_NONE;
}
pgContext->UserToken =*phToken;
*pdwOptions = 0;
*pProfile =NULL;
if(!GetTokenInformation(*phToken,
TokenStatistics,
(PVOID)&Stats,
sizeof(TOKEN_STATISTICS),
&cbStats))
{
WARN("msgina: Couldn't get Autentication id from user token!\n");
return WLX_SAS_ACTION_NONE;
}
*pAuthenticationId = Stats.AuthenticationId;
pNprNotifyInfo->pszUserName = DuplicationString(L"Administrator");
pNprNotifyInfo->pszDomain = NULL;
pNprNotifyInfo->pszPassword = DuplicationString(L"Secret");
pNprNotifyInfo->pszOldPassword = NULL;
return WLX_SAS_ACTION_LOGON;
}
BOOL STDCALL
DllMain(
HINSTANCE hinstDLL,
DWORD dwReason,
LPVOID lpvReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
/* fall through */
case DLL_THREAD_ATTACH:
hDllInstance = hinstDLL;
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?