404 lines
9.5 KiB
C++
404 lines
9.5 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1994 - 1996.
|
|
//
|
|
// File: main.cxx
|
|
//
|
|
// Contents: Entry point
|
|
//
|
|
// History: 10-31-96 Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#ifdef _CHICAGO_
|
|
#ifdef UNICODE
|
|
#undef UNICODE
|
|
#endif
|
|
#endif
|
|
|
|
#include <windows.h>
|
|
#include <mstask.h>
|
|
#include <msterr.h>
|
|
#include <stdio.h>
|
|
#include <tchar.h>
|
|
#include "tint.hxx"
|
|
|
|
|
|
//
|
|
// Forward references
|
|
//
|
|
|
|
HRESULT Init();
|
|
VOID Cleanup();
|
|
HRESULT StartSchedAgent();
|
|
HRESULT EndSchedAgent();
|
|
|
|
//
|
|
// Global variables
|
|
//
|
|
|
|
BOOL g_fSchedAgentRunning = FALSE;
|
|
SC_HANDLE g_hSCM, g_hSchedule;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: main
|
|
//
|
|
// Synopsis: Entry point for DRT.
|
|
//
|
|
// Arguments: See DisplayUsage().
|
|
//
|
|
// Returns: 1 on success, 0 on failure
|
|
//
|
|
// History: 10-31-96 (cribbed)
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
ULONG __cdecl main(int argc, char *argv[])
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = StartSchedAgent();
|
|
if (FAILED(hr))
|
|
{
|
|
printf("Failure to start the scheduling agent. hr = %x\n",hr);
|
|
EndSchedAgent();
|
|
return hr;
|
|
}
|
|
|
|
do
|
|
{
|
|
hr = Init();
|
|
if (hr == E_FAIL)
|
|
{
|
|
printf("Initialization Failed with %x\n",hr);
|
|
break;
|
|
};
|
|
TestISchedAgent();
|
|
TestITask();
|
|
TestITaskTrigger();
|
|
// wprintf(L"Pausing 3 seconds to allow service to catch up\n");
|
|
Sleep(3000);
|
|
TestIEnum();
|
|
} while (0);
|
|
|
|
// TestGRT();
|
|
Cleanup();
|
|
hr = EndSchedAgent();
|
|
if (FAILED(hr))
|
|
{
|
|
printf("Failure to stop the scheduling agent. hr = %x\n",hr);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Init
|
|
//
|
|
// Synopsis: Initialize OLE and globals.
|
|
//
|
|
// Returns: S_OK - initialization successful
|
|
// E_* - error logged
|
|
//
|
|
// Modifies: [g_pITask], [g_pISchedAgent]
|
|
//
|
|
// History: 10-31-96 cribbed
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT Init()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
hr = CoInitialize(NULL);
|
|
|
|
if(hr == E_FAIL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
|
|
hr = CoCreateInstance(
|
|
CLSID_CTask,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ITask,
|
|
(void **)&g_pITask);
|
|
|
|
hr = CoCreateInstance(
|
|
CLSID_CSchedulingAgent,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ITaskScheduler,
|
|
(void **)&g_pISchedAgent);
|
|
}
|
|
while (0);
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Cleanup
|
|
//
|
|
// Synopsis: Do shutdown processing.
|
|
//
|
|
// History: 10-31-96 created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
VOID Cleanup()
|
|
{
|
|
if (g_pITask)
|
|
{
|
|
g_pITask->Release();
|
|
g_pITask = NULL;
|
|
}
|
|
|
|
|
|
if (g_pISchedAgent)
|
|
{
|
|
g_pISchedAgent -> Release();
|
|
g_pISchedAgent = NULL;
|
|
}
|
|
|
|
if (g_pIUnknown)
|
|
{
|
|
g_pIUnknown -> Release();
|
|
g_pIUnknown = NULL;
|
|
}
|
|
|
|
if (g_pIEnumTasks)
|
|
{
|
|
g_pIEnumTasks->Release();
|
|
}
|
|
CoUninitialize();
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------
|
|
//
|
|
// Function: StartSchedAgent()
|
|
//
|
|
// Arguments/Returns: nothing
|
|
//
|
|
// Starts the service IF it is not running. Modifies global flag
|
|
// g_fSchedAgentRunning with initial service state.
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
|
|
HRESULT StartSchedAgent()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
#ifdef _CHICAGO_
|
|
// We are the inferior on Win9x - it has no system service
|
|
// daemon, no service control manager, no nothing. We have
|
|
// to make extra work for ourselves and fake it with a hidden window.
|
|
|
|
|
|
const char SCHED_CLASS[16] = "SAGEWINDOWCLASS";
|
|
const char SCHED_TITLE[24] = "SYSTEM AGENT COM WINDOW";
|
|
const char SCHED_SERVICE_APP_NAME[11] = "mstask.exe";
|
|
|
|
// is it running?
|
|
HWND hwnd = FindWindow(SCHED_CLASS, SCHED_TITLE);
|
|
|
|
if (hwnd != NULL)
|
|
{
|
|
// Already up
|
|
g_fSchedAgentRunning = TRUE;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = GetLastError();
|
|
g_fSchedAgentRunning = FALSE;
|
|
}
|
|
|
|
// Start me up...
|
|
STARTUPINFO sui;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
ZeroMemory(&sui, sizeof(sui));
|
|
sui.cb = sizeof(STARTUPINFO);
|
|
|
|
char szApp[MAX_PATH];
|
|
LPSTR pszPath;
|
|
|
|
DWORD dwRet = SearchPath(NULL,
|
|
SCHED_SERVICE_APP_NAME,
|
|
NULL, MAX_PATH, szApp, &pszPath);
|
|
if (dwRet == 0)
|
|
return GetLastError();
|
|
|
|
BOOL fRet = CreateProcess(szApp, NULL, NULL, NULL, FALSE,
|
|
CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
|
|
NULL, NULL, &sui, &pi);
|
|
if (fRet == FALSE)
|
|
return GetLastError();
|
|
|
|
CloseHandle(pi.hProcess);
|
|
CloseHandle(pi.hThread);
|
|
|
|
return S_OK;
|
|
|
|
#else
|
|
// It's NT! Do the smart thing and use a service control manager
|
|
|
|
LPTSTR lpszMachineName;
|
|
SERVICE_STATUS svcStatus;
|
|
|
|
lpszMachineName = new TCHAR[9999];
|
|
hr = GetEnvironmentVariable(_T("COMPUTERNAME"),lpszMachineName, 9999);
|
|
if (FAILED(hr))
|
|
{
|
|
printf("Failed to get machine name\n");
|
|
return hr;
|
|
}
|
|
|
|
g_hSCM = OpenSCManager(lpszMachineName, NULL,
|
|
SC_MANAGER_CONNECT | STANDARD_RIGHTS_REQUIRED |
|
|
GENERIC_READ | GENERIC_EXECUTE);
|
|
if (g_hSCM == NULL)
|
|
{
|
|
hr = (HRESULT)GetLastError();
|
|
printf("Service control manager handle not obtained. hr = %x\n",hr);
|
|
return hr;
|
|
}
|
|
|
|
delete lpszMachineName;
|
|
|
|
g_hSchedule = OpenService(g_hSCM, _T("Schedule"),
|
|
SERVICE_INTERROGATE | SERVICE_STOP | SERVICE_QUERY_STATUS |
|
|
SERVICE_START | STANDARD_RIGHTS_REQUIRED);
|
|
if (g_hSchedule == NULL)
|
|
{
|
|
hr = (HRESULT)GetLastError();
|
|
printf("Schedule Service handle not obtained. hr = %x\n",hr);
|
|
return hr;
|
|
}
|
|
|
|
if (QueryServiceStatus(g_hSchedule, &svcStatus) == 0)
|
|
{
|
|
hr = (HRESULT)GetLastError();
|
|
printf("Failed to get service status, hr = %x\n",hr);
|
|
return hr;
|
|
}
|
|
|
|
if (svcStatus.dwCurrentState == SERVICE_RUNNING)
|
|
{
|
|
g_fSchedAgentRunning = TRUE;
|
|
return S_OK;
|
|
}
|
|
else
|
|
g_fSchedAgentRunning = FALSE;
|
|
|
|
// Start the service
|
|
|
|
if (StartService(g_hSchedule, 0, NULL) == 0)
|
|
{
|
|
printf("Failed to start the service!\n");
|
|
hr = (HRESULT)GetLastError();
|
|
return hr;
|
|
}
|
|
|
|
// Got to wait for the service to fully start, though
|
|
// or things will fail.
|
|
int nCounter = 0;
|
|
while (svcStatus.dwCurrentState != SERVICE_RUNNING)
|
|
{
|
|
QueryServiceStatus(g_hSchedule, &svcStatus);
|
|
Sleep(250);
|
|
nCounter++;
|
|
if (nCounter > 80)
|
|
{
|
|
// It's been 20 seconds and we're still not
|
|
// running. Fail out.
|
|
printf("FAILURE - unable to start service after 20 seconds.");
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------
|
|
//
|
|
// Funtion: EndSchedAgent()
|
|
//
|
|
// No arguments, but depends on globals g_hSCM, g_hSchedule, and
|
|
// g_fSchedAgentRunning
|
|
//
|
|
//-----------------------------------------------------------------
|
|
HRESULT EndSchedAgent()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
#ifdef _CHICAGO_
|
|
// Memphis/Win9x. No support for an SCM, must use cheap window tricks
|
|
// to spoof around it.
|
|
|
|
const char SCHED_CLASS[16] = "SAGEWINDOWCLASS";
|
|
const char SCHED_TITLE[24] = "SYSTEM AGENT COM WINDOW";
|
|
|
|
if (! g_fSchedAgentRunning)
|
|
{
|
|
// Service was stopped, so we must stop it.
|
|
HWND hwnd = FindWindow(SCHED_CLASS, SCHED_TITLE);
|
|
|
|
if (hwnd)
|
|
{
|
|
// It is up and going. Nuke it.
|
|
SendMessage(hwnd, (WM_USER + 201), NULL, NULL);
|
|
}
|
|
}
|
|
|
|
#else
|
|
// NT. SCM is cool.
|
|
|
|
SERVICE_STATUS svcStatus;
|
|
|
|
if (! g_fSchedAgentRunning)
|
|
{
|
|
// Service was stopped.
|
|
if (ControlService(g_hSchedule, SERVICE_CONTROL_STOP,
|
|
&svcStatus) == 0)
|
|
{
|
|
hr = (HRESULT)GetLastError();
|
|
printf("Failed to stop the service - hr = %x\n",hr);
|
|
}
|
|
}
|
|
if (g_hSchedule)
|
|
{
|
|
if (CloseServiceHandle(g_hSchedule) == 0)
|
|
{
|
|
hr = (HRESULT)GetLastError();
|
|
printf("Failed to close service handle - hr = %x\n",hr);
|
|
}
|
|
}
|
|
|
|
if (g_hSCM)
|
|
{
|
|
if (CloseServiceHandle(g_hSCM) == 0)
|
|
{
|
|
hr = (HRESULT)GetLastError();
|
|
printf("Failed to close service controller handle - hr = %x\n",hr);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
return hr;
|
|
}
|