Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//+----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: schedlog.c
//
// Contents: Task Scheduler StartShell notification
//
// Classes: None.
//
// Functions:
// SchedStartShell - queue the work to the WinLogon thread pool.
// DoSchedStartShell - notify Sched service that a user logged on.
//
// History: 07-Mar-01 JBenton Created
//
//-----------------------------------------------------------------------------
//
// Note: We don't build/publish a lib here as suggested in wlnotify.cxx.
// Rather we include the source file here because there is only a single
// simple function.
//
// Note: We are using the StartShell event because the Scheduler service
// expects the user's explorer session to be running.
//
#include <windows.h>
#include <winwlx.h>
#define SCHED_SERVICE_NAME TEXT("Schedule")
//
// The following LOGON and LOGOFF defines must be kept in sync with
// the definition in %sdxroot%\admin\services\sched\inc\common.hxx
//
#define SERVICE_CONTROL_USER_LOGON 128
#define SERVICE_CONTROL_USER_LOGOFF 133
DWORD WINAPI SchedStartShell(LPVOID lpvParam); DWORD WINAPI DoSchedStartShell(LPVOID lpvParam);
DWORD WINAPI SchedEventLogOff(LPVOID lpvParam) //
//
// Routine Description:
//
// Send a logoff notification to the Task Scheduler service
// via a user defined Service Control.
//
// Arguments:
//
// lpvParam - Winlogon notification info (unused as of yet)
//
// Return Value:
//
// Extended error status from Service control functions.
//
{ DWORD status = ERROR_SUCCESS; SC_HANDLE hSC = NULL; SC_HANDLE hSvc = NULL; BOOL bSucceeded = FALSE; SERVICE_STATUS ServiceStatus;
hSC = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSC == NULL) { return GetLastError(); }
hSvc = OpenService(hSC, SCHED_SERVICE_NAME, SERVICE_USER_DEFINED_CONTROL); if (hSvc == NULL) { CloseServiceHandle(hSC); return GetLastError(); }
bSucceeded = ControlService(hSvc, SERVICE_CONTROL_USER_LOGOFF, &ServiceStatus); if( !bSucceeded ) { status = GetLastError(); }
CloseServiceHandle(hSvc); CloseServiceHandle(hSC);
return status; }
DWORD WINAPI SchedStartShell(LPVOID lpvParam)
{ DWORD dwSessionId = 0;
//
// Don't send logon notification to Terminal Server sessions.
//
if (ProcessIdToSessionId(GetCurrentProcessId(), &dwSessionId) && (dwSessionId == 0)) { //
// Queue the work to the thread pool since we may
// be looping on the notification.
//
QueueUserWorkItem(DoSchedStartShell, lpvParam, WT_EXECUTELONGFUNCTION); }
return GetLastError(); }
DWORD WINAPI DoSchedStartShell(LPVOID lpvParam) //
//
// Routine Description:
//
// Send a logon notification to the Task Scheduler service
// via a user defined Service Control.
//
// Arguments:
//
// lpvParam - Winlogon notification info (unused as of yet)
//
// Return Value:
//
// Extended error status from Service control functions.
//
{ DWORD status = ERROR_SUCCESS; PWLX_NOTIFICATION_INFO pTempInfo = (PWLX_NOTIFICATION_INFO) lpvParam;
SC_HANDLE hSC = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSC == NULL) { return GetLastError(); }
SC_HANDLE hSvc = OpenService(hSC, SCHED_SERVICE_NAME, SERVICE_USER_DEFINED_CONTROL); if (hSvc == NULL) { CloseServiceHandle(hSC); return GetLastError(); }
BOOL fSucceeded; const int NOTIFY_RETRIES = 20; const DWORD NOTIFY_SLEEP = 4000;
//
// Use a retry loop to notify the service. This is done
// because, if the user logs in quickly, the service may not
// be started when the shell runs this instance.
//
for (int i = 1; ; i++) { SERVICE_STATUS Status; fSucceeded = ControlService(hSvc, SERVICE_CONTROL_USER_LOGON, &Status); if (fSucceeded) { break; }
if (i >= NOTIFY_RETRIES) { status = GetLastError(); break; }
Sleep(NOTIFY_SLEEP); }
CloseServiceHandle(hSvc); CloseServiceHandle(hSC);
return status; }
|