windows-nt/Source/XPSP1/NT/net/config/netman/eapol/service/ellogon.c
2020-09-26 16:20:57 +08:00

645 lines
14 KiB
C

/*++
Copyright (c) 2000, Microsoft Corporation
Module Name:
Abstract:
Revision History:
timmoore, sachins, May 19 2000, Created
--*/
#include "pcheapol.h"
#pragma hdrstop
LONG_PTR FAR PASCAL
WndProc(
HWND hWnd,
unsigned message,
WPARAM wParam,
LPARAM lParam
);
#define TASK_BAR_CREATED L"TaskbarCreated"
TCHAR EAPOLClassName[] = TEXT("EAPOLClass");
UINT g_TaskbarCreated;
HWND g_hWnd = 0;
HINSTANCE g_hInstance;
HANDLE g_UserToken;
HWINSTA hWinStaUser = 0;
HWINSTA hSaveWinSta = 0;
HDESK hDeskUser = 0;
HDESK hSaveDesk = 0;
//
// WindowInit
//
// Description:
//
// Function called create the taskbar used to detect user logon/logoff
//
// Arguments:
//
// Return values:
// NO_ERROR - success
// NON-zero - error
//
DWORD
WindowInit ()
{
WNDCLASS Wc;
DWORD dwRetCode = NO_ERROR;
TRACE0 (ANY, "Came into WindowInit ========================\n");
do
{
if ((g_TaskbarCreated = RegisterWindowMessage(TASK_BAR_CREATED))
== 0)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: RegisterWindowMessage failed with error %ld\n",
dwRetCode);
break;
}
TRACE1 (ANY, "WindowInit: TaskbarCreated id = %ld",
g_TaskbarCreated);
// save current desktop and window station
// so that it can be restored when we shutdown
if ((hSaveWinSta = GetProcessWindowStation()) == NULL)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: GetProcessWindowStation failed with error %ld\n",
dwRetCode);
break;
}
if ((hSaveDesk = GetThreadDesktop(GetCurrentThreadId())) == NULL)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: GetThreadDesktop failed with error %ld\n",
dwRetCode);
break;
}
// Open the current user's window station and desktop
if ((hWinStaUser = OpenWindowStation(L"WinSta0", FALSE, MAXIMUM_ALLOWED)) == NULL)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: OpenWindowStation failed with error %ld\n",
dwRetCode);
break;
}
if (!SetProcessWindowStation(hWinStaUser))
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: SetProcessWindowStation failed with error %ld\n",
dwRetCode);
break;
}
else
{
TRACE0 (ANY, "WindowInit: SetProcessWindowStation succeeded\n");
}
if ((hDeskUser = OpenDesktop(L"Default", 0 , FALSE, MAXIMUM_ALLOWED))
== NULL)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: OpenDesktop failed with error %ld\n",
dwRetCode);
break;
}
if (!SetThreadDesktop(hDeskUser))
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: SetThreadDesktop failed with error %ld\n",
dwRetCode);
break;
}
else
{
TRACE0 (ANY, "WindowInit: SetThreadDesktop succeeded\n");
}
//
// Register the class for the window
//
Wc.style = CS_NOCLOSE;
Wc.cbClsExtra = 0;
Wc.cbWndExtra = 0;
Wc.hInstance = g_hInstance;
Wc.hIcon = NULL;
Wc.hCursor = NULL;
Wc.hbrBackground = NULL;
Wc.lpszMenuName = NULL;
Wc.lpfnWndProc = WndProc;
Wc.lpszClassName = EAPOLClassName;
if (!RegisterClass(&Wc))
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: RegisterClass failed with error %ld\n",
dwRetCode);
if (dwRetCode == ERROR_CLASS_ALREADY_EXISTS)
{
dwRetCode = NO_ERROR;
}
else
{
break;
}
}
// Create the window that will receive the taskbar menu messages.
// The window has to be created after opening the user's desktop
if ((g_hWnd = CreateWindow(
EAPOLClassName,
L"EAPOLWindow",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
g_hInstance,
NULL)) == NULL)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: CreateWindow failed with error %ld\n",
dwRetCode);
break;
}
// We don't care about the return value, since we just want it to
// be hidden and it will always succeed
ShowWindow(g_hWnd, SW_HIDE);
if (!UpdateWindow(g_hWnd))
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowInit: UpdateWindow failed with error %ld\n",
dwRetCode);
break;
}
TRACE0 (ANY, "WindowInit: CreateWindow succeeded\n");
} while (FALSE);
return dwRetCode;
}
//
// WindowShut
//
// Description:
//
// Function called to delete the task bar created to detect user logon/logoff
//
// Arguments:
//
// Return values:
// NO_ERROR - success
// NON-zero - error
//
DWORD
WindowShut ()
{
DWORD dwRetCode = NO_ERROR;
do
{
if (g_hWnd)
{
if (!DestroyWindow (g_hWnd))
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowShut: DestroyWindow failed with error %ld\n",
dwRetCode);
// log
}
}
if (g_hInstance)
{
if (!UnregisterClass (
EAPOLClassName,
g_hInstance))
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowShut: UnregisterClass failed with error %ld\n",
dwRetCode);
// log
}
g_hInstance = NULL;
}
if (hDeskUser)
{
if (CloseDesktop(hDeskUser) == 0)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowShut: CloseDesktop-hDeskUser failed with error %ld\n",
dwRetCode);
// log
}
hDeskUser = 0;
}
if (hWinStaUser)
{
if (CloseWindowStation(hWinStaUser) == 0)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowShut: CloseWindowStation-hWinStaUser failed with error %ld\n",
dwRetCode);
// log
}
hWinStaUser = 0;
}
if (hSaveDesk)
{
if (!SetThreadDesktop(hSaveDesk))
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowShut: SetThreadDesktop failed with error %ld\n",
dwRetCode);
// log
}
if (hSaveWinSta)
{
if (SetProcessWindowStation(hSaveWinSta) == 0)
{
TRACE1 (ANY, "WindowShut: SetProcessWindowStation failed with error %ld\n",
dwRetCode);
dwRetCode = GetLastError ();
// log
}
}
if (CloseDesktop(hSaveDesk) == 0)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowShut: CloseDesktop-hSaveDesk failed with error %ld\n",
dwRetCode);
// log
}
hSaveDesk = 0;
if (hSaveWinSta)
{
if (CloseWindowStation(hSaveWinSta) == 0)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "WindowShut: CloseWindowStation-hSaveWinSta failed with error %ld\n",
dwRetCode);
// log
}
hSaveWinSta = 0;
}
}
} while (FALSE);
return dwRetCode;
}
//
// UserLogon
//
// Description:
//
// Function called to do processing when user logs on
//
// Arguments:
//
// Return values:
// NO_ERROR - success
// NON-zero - error
//
DWORD
UserLogon ()
{
DWORD dwRetCode = NO_ERROR;
TRACE0 (ANY, "Came into UserLogon ===================\n");
do
{
ElUserLogonCallback (
NULL,
TRUE
);
TRACE0 (ANY, "UserLogon: ElUserLogonCallback completed");
} while (FALSE);
return dwRetCode;
}
//
// UserLogoff
//
// Description:
//
// Function called to do processing when user logs off
//
// Arguments:
//
// Return values:
// NO_ERROR - success
// NON-zero - error
//
DWORD
UserLogoff ()
{
DWORD dwRetCode = NO_ERROR;
TRACE0 (ANY, "Came into UserLogoff ===================\n");
do
{
ElUserLogoffCallback (
NULL,
TRUE
);
TRACE0 (ANY, "UserLogoff: ElUserLogoffCallback completed");
} while (FALSE);
return dwRetCode;
}
//
// ElWaitOnEvent
//
// Description:
//
// Function called to wait on taskbar event changes
//
// Arguments:
//
// Return values:
// NO_ERROR - success
// NON-zero - error
//
DWORD
ElWaitOnEvent ()
{
MSG Msg;
HANDLE hEvents[1];
BOOL fExitThread = FALSE;
DWORD dwStatus = NO_ERROR;
DWORD dwRetCode = NO_ERROR;
// Check if 802.1X service has stopped
// Exit if so
if (( dwStatus = WaitForSingleObject (
g_hEventTerminateEAPOL,
0)) == WAIT_FAILED)
{
dwRetCode = GetLastError ();
if ( g_dwTraceId != INVALID_TRACEID )
{
TRACE1 (INIT, "ElWaitOnEvent: WaitForSingleObject failed with error %ld, Terminating cleanup",
dwRetCode);
}
// log
return dwRetCode;
}
if (dwStatus == WAIT_OBJECT_0)
{
if ( g_dwTraceId != INVALID_TRACEID )
{
dwRetCode = NO_ERROR;
TRACE0 (INIT, "ElWaitOnEvent: g_hEventTerminateEAPOL already signaled, returning");
}
return dwRetCode;
}
if (!g_dwMachineAuthEnabled)
{
if ((dwRetCode = UserLogon()) != NO_ERROR)
{
TRACE1 (ANY, "ElWaitOnEvent: UserLogon failed with error %ld",
dwRetCode);
return dwRetCode;
}
}
do
{
do
{
hEvents[0] = g_hEventTerminateEAPOL;
dwStatus = MsgWaitForMultipleObjects(
1,
hEvents,
FALSE,
INFINITE,
QS_ALLINPUT | QS_ALLEVENTS | QS_ALLPOSTMESSAGE);
if (dwStatus == WAIT_FAILED)
{
dwRetCode = GetLastError ();
TRACE1 (ANY, "ElWaitOnEvent: MsgWaitForMultipleObjects failed with error %ld",
dwRetCode);
// log
break;
}
switch (dwStatus)
{
case WAIT_OBJECT_0:
// Service exit detected
fExitThread = TRUE;
TRACE0 (ANY, "ElWaitOnEvent: Service exit detected");
break;
default:
while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
if (Msg.message == WM_QUIT)
{
break;
}
TRACE3 (ANY, "ElWaitonEvent: Mesg %ld, wparam %lx, lparam %lx",
(DWORD)Msg.message, Msg.wParam, Msg.lParam);
if (!IsDialogMessage(g_hWnd, &Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
break;
}
} while (dwStatus != WAIT_OBJECT_0);
if ((dwRetCode != NO_ERROR) || (fExitThread))
{
TRACE0 (ANY, "ElWaitOnEvent: Exit wait loop");
break;
}
} while (TRUE);
return dwRetCode;
}
//
// WndProc
//
// Description:
//
// Function called to process taskbar events
//
// Arguments:
//
// Return values:
//
LONG_PTR FAR PASCAL
WndProc (
IN HWND hWnd,
IN unsigned message,
IN WPARAM wParam,
IN LPARAM lParam
)
{
DWORD dwRetCode = NO_ERROR;
TRACE1 (ANY, "WndProc: Came into WndProc %ld", (DWORD)message );
switch (message)
{
case WM_ENDSESSION:
TRACE2 (ANY, "WndProc: Endsession (logoff) %x %x\n",
wParam, lParam);
if(wParam)
{
// Only user session logoff
if (lParam & ENDSESSION_LOGOFF)
{
if ((dwRetCode = UserLogoff()) != NO_ERROR)
{
TRACE1 (ANY, "WndProc: UserLogoff failed with error %ld",
dwRetCode);
}
}
}
break;
default:
if (message == g_TaskbarCreated)
{
TRACE0 (ANY, "WndProc: Taskbar created (Logon)\n");
if ((dwRetCode = UserLogon()) != NO_ERROR)
{
TRACE1 (ANY, "WndProc: UserLogon failed with error %ld",
dwRetCode);
}
}
}
return (DefWindowProc(hWnd, message, wParam, lParam));
}
//
// ElUserLogonDetection
//
// Description:
//
// Function called to initialize module detecting user logon/logoff
//
// Arguments:
// pvContext - Unused
//
// Return values:
//
VOID
ElUserLogonDetection (
PVOID pvContext
)
{
DWORD dwRetCode = NO_ERROR;
do
{
if ((dwRetCode = WindowInit()) != NO_ERROR)
{
break;
}
if ((dwRetCode = ElWaitOnEvent()) != NO_ERROR)
{
// no action
}
} while (FALSE);
dwRetCode = WindowShut();
if (dwRetCode != NO_ERROR)
{
TRACE1 (ANY, "ElUserLogonDetection: Error in processing = %ld",
dwRetCode);
// log
}
return;
}