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