645 lines
14 KiB
C
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;
|
|
|
|
}
|