|
|
//+---------------------------------------------------------------------------
//
// 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; }
|