/*****************************************************************************
Module : MSJTimeSrv.c
Notices: Written 1997 by Jeffrey Richter
Description: Minimal Service Template
*****************************************************************************/
#define STRICT
#define UNICODE
#include <Windows.h>
//////////////////////////////////////////////////////////////////////////////
#define dimof(A) (sizeof(A) / sizeof(A[0]))
//////////////////////////////////////////////////////////////////////////////
WCHAR g_szAppName[] = L"MSJ Time Service";
//////////////////////////////////////////////////////////////////////////////
HANDLE g_hIOCP = NULL;
// The completion port wakes for 1 of 2 reasons:
enum COMPKEY {
CK_SERVICECONTROL, // A service control code
CK_PIPE // A client connects to our pipe
};
//////////////////////////////////////////////////////////////////////////////
void WINAPI TimeServiceHandler(DWORD fdwControl) {
// The Handler thread is very simple and executes very quickly because
// it just passes the control code off to the ServiceMain thread.
PostQueuedCompletionStatus(g_hIOCP, fdwControl, CK_SERVICECONTROL, NULL);
}
//////////////////////////////////////////////////////////////////////////////
#define SERVICE_CONTROL_RUN 0x00000000
DWORD dwSrvCtrlToPend[256] = { // 255 is max user-defined code
/* 0: SERVICE_CONTROL_RUN */ SERVICE_START_PENDING,
/* 1: SERVICE_CONTROL_STOP */ SERVICE_STOP_PENDING,
/* 2: SERVICE_CONTROL_PAUSE */ SERVICE_PAUSE_PENDING,
/* 3: SERVICE_CONTROL_CONTINUE */ SERVICE_CONTINUE_PENDING,
/* 4: SERVICE_CONTROL_INTERROGATE */ 0,
/* 5: SERVICE_CONTROL_SHUTDOWN */ SERVICE_STOP_PENDING,
/* 6 - 255: User-defined codes */ 0
};
DWORD dwSrvPendToState[] = {
/* 0: Undefined */ 0,
/* 1: SERVICE_STOPPED */ 0,
/* 2: SERVICE_START_PENDING */ SERVICE_RUNNING,
/* 3: SERVICE_STOP_PENDING */ SERVICE_STOPPED,
/* 4: SERVICE_RUNNING */ 0,
/* 5: SERVICE_CONTINUE_PENDING */ SERVICE_RUNNING,
/* 6: SERVICE_PAUSE_PENDING */ SERVICE_PAUSED,
/* 7: SERVICE_PAUSED */ 0
};
//////////////////////////////////////////////////////////////////////////////
void WINAPI TimeServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
DWORD dwCompKey = CK_SERVICECONTROL;
DWORD fdwControl = SERVICE_CONTROL_RUN;
DWORD dwBytesTransferred;
SYSTEMTIME st;
HANDLE hpipe;
OVERLAPPED o, *po;
SERVICE_STATUS ss;
SERVICE_STATUS_HANDLE hSS; // Create the completion port and save its handle in a global
// variable so that the Handler function can access it.
g_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, CK_PIPE, 0); // Give SCM the address of this service's Handler
// NOTE: hSS does not have to be closed.
hSS = RegisterServiceCtrlHandler(g_szAppName, TimeServiceHandler); // Do what the service should do.
// Initialize the members that never change
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
do {
switch (dwCompKey) {
case CK_SERVICECONTROL:
// We got a new control code
ss.dwWin32ExitCode = NO_ERROR;
ss.dwServiceSpecificExitCode = 0;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0; if (fdwControl == SERVICE_CONTROL_INTERROGATE) {
SetServiceStatus(hSS, &ss);
break;
} // Determine which PENDING state to return
if (dwSrvCtrlToPend[fdwControl] != 0) {
ss.dwCurrentState = dwSrvCtrlToPend[fdwControl];
ss.dwCheckPoint = 0;
ss.dwWaitHint = 500; // half a second
SetServiceStatus(hSS, &ss);
} switch (fdwControl) {
case SERVICE_CONTROL_RUN:
case SERVICE_CONTROL_CONTINUE:
// While running, create a pipe that clients can connect to.
hpipe = CreateNamedPipe(L"\\\\.\\pipe\\MSJTime",
PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE, 1, sizeof(st), sizeof(st), 1000, NULL); // Associate the pipe with the completion port
CreateIoCompletionPort(hpipe, g_hIOCP, CK_PIPE, 0); // Pend an asynchronous connect against the pipe
ZeroMemory(&o, sizeof(o));
ConnectNamedPipe(hpipe, &o);
break; case SERVICE_CONTROL_PAUSE:
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
// When not running, close the pipe so clients can't connect
CloseHandle(hpipe);
break; case 128: // User-defined control (demonstration purposes)
MessageBox(NULL, L"Got control code 128", g_szAppName, MB_OK);
break;
} // Determine which complete state to return
if (dwSrvPendToState[ss.dwCurrentState] != 0) {
ss.dwCurrentState = dwSrvPendToState[ss.dwCurrentState];
ss.dwCheckPoint = ss.dwWaitHint = 0;
SetServiceStatus(hSS, &ss);
}
break; case CK_PIPE:
// We got a client request: Send our current time to the client
GetSystemTime(&st);
WriteFile(hpipe, &st, sizeof(st), &dwBytesTransferred, NULL);
FlushFileBuffers(hpipe);
DisconnectNamedPipe(hpipe); // Allow another client to connect
ZeroMemory(&o, sizeof(o));
ConnectNamedPipe(hpipe, &o);
} if (ss.dwCurrentState != SERVICE_STOPPED) {
// Sleep until a control code comes in or a client connects
GetQueuedCompletionStatus(g_hIOCP, &dwBytesTransferred,
&dwCompKey, &po, INFINITE);
fdwControl = dwBytesTransferred;
}
} while (ss.dwCurrentState != SERVICE_STOPPED); // Cleanup and stop this service
CloseHandle(g_hIOCP);
}
//////////////////////////////////////////////////////////////////////////////
void InstallService() {
TCHAR szModulePathname[_MAX_PATH];
SC_HANDLE hService; // Open the SCM on this machine.
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); // Get our full pathname
GetModuleFileName(NULL, szModulePathname, dimof(szModulePathname)); // Add this service to the SCM's database.
hService = CreateService(hSCM, g_szAppName, g_szAppName, 0,
SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE,
szModulePathname, NULL, NULL, NULL, NULL, NULL); // Close the service and the SCM
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
}
//////////////////////////////////////////////////////////////////////////////
void RemoveService() {
// Open the SCM on this machine.
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); // Open this service for DELETE access
SC_HANDLE hService = OpenService(hSCM, g_szAppName, DELETE); // Remove this service from the SCM's database.
DeleteService(hService); // Close the service and the SCM
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
}
//////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstExePrev,
LPSTR pszCmdLine, int nCmdShow) { int nArgc = __argc;
#ifdef UNICODE
LPCTSTR *ppArgv = (LPCTSTR*) CommandLineToArgvW(GetCommandLine(), &nArgc);
#else
LPCTSTR *ppArgv = (LPCTSTR*) __argv;
#endif BOOL fStartService = (nArgc < 2), fDebug = FALSE;
int i; for (i = 1; i < nArgc; i++) {
if ((ppArgv[i][0] == __TEXT('-')) || (ppArgv[i][0] == __TEXT('/'))) {
// Command line switch
if (lstrcmpi(&ppArgv[i][1], __TEXT("install")) == 0)
InstallService(); if (lstrcmpi(&ppArgv[i][1], __TEXT("remove")) == 0)
RemoveService(); if (lstrcmpi(&ppArgv[i][1], __TEXT("debug")) == 0)
fDebug = TRUE;
}
}
InstallService();#ifdef UNICODE
HeapFree(GetProcessHeap(), 0, (PVOID) ppArgv);
#endif if (fDebug) {
// Running as EXE not as service, just run the service for debugging
TimeServiceMain(0, NULL);
} if (fStartService) {
SERVICE_TABLE_ENTRY ServiceTable[] = {
{ g_szAppName, TimeServiceMain },
{ NULL, NULL } // End of list
};
StartServiceCtrlDispatcher(ServiceTable);
} return(0);
}
//////////////////////////////// End Of File /////////////////////////////////
Module : MSJTimeSrv.c
Notices: Written 1997 by Jeffrey Richter
Description: Minimal Service Template
*****************************************************************************/
#define STRICT
#define UNICODE
#include <Windows.h>
//////////////////////////////////////////////////////////////////////////////
#define dimof(A) (sizeof(A) / sizeof(A[0]))
//////////////////////////////////////////////////////////////////////////////
WCHAR g_szAppName[] = L"MSJ Time Service";
//////////////////////////////////////////////////////////////////////////////
HANDLE g_hIOCP = NULL;
// The completion port wakes for 1 of 2 reasons:
enum COMPKEY {
CK_SERVICECONTROL, // A service control code
CK_PIPE // A client connects to our pipe
};
//////////////////////////////////////////////////////////////////////////////
void WINAPI TimeServiceHandler(DWORD fdwControl) {
// The Handler thread is very simple and executes very quickly because
// it just passes the control code off to the ServiceMain thread.
PostQueuedCompletionStatus(g_hIOCP, fdwControl, CK_SERVICECONTROL, NULL);
}
//////////////////////////////////////////////////////////////////////////////
#define SERVICE_CONTROL_RUN 0x00000000
DWORD dwSrvCtrlToPend[256] = { // 255 is max user-defined code
/* 0: SERVICE_CONTROL_RUN */ SERVICE_START_PENDING,
/* 1: SERVICE_CONTROL_STOP */ SERVICE_STOP_PENDING,
/* 2: SERVICE_CONTROL_PAUSE */ SERVICE_PAUSE_PENDING,
/* 3: SERVICE_CONTROL_CONTINUE */ SERVICE_CONTINUE_PENDING,
/* 4: SERVICE_CONTROL_INTERROGATE */ 0,
/* 5: SERVICE_CONTROL_SHUTDOWN */ SERVICE_STOP_PENDING,
/* 6 - 255: User-defined codes */ 0
};
DWORD dwSrvPendToState[] = {
/* 0: Undefined */ 0,
/* 1: SERVICE_STOPPED */ 0,
/* 2: SERVICE_START_PENDING */ SERVICE_RUNNING,
/* 3: SERVICE_STOP_PENDING */ SERVICE_STOPPED,
/* 4: SERVICE_RUNNING */ 0,
/* 5: SERVICE_CONTINUE_PENDING */ SERVICE_RUNNING,
/* 6: SERVICE_PAUSE_PENDING */ SERVICE_PAUSED,
/* 7: SERVICE_PAUSED */ 0
};
//////////////////////////////////////////////////////////////////////////////
void WINAPI TimeServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
DWORD dwCompKey = CK_SERVICECONTROL;
DWORD fdwControl = SERVICE_CONTROL_RUN;
DWORD dwBytesTransferred;
SYSTEMTIME st;
HANDLE hpipe;
OVERLAPPED o, *po;
SERVICE_STATUS ss;
SERVICE_STATUS_HANDLE hSS; // Create the completion port and save its handle in a global
// variable so that the Handler function can access it.
g_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, CK_PIPE, 0); // Give SCM the address of this service's Handler
// NOTE: hSS does not have to be closed.
hSS = RegisterServiceCtrlHandler(g_szAppName, TimeServiceHandler); // Do what the service should do.
// Initialize the members that never change
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
do {
switch (dwCompKey) {
case CK_SERVICECONTROL:
// We got a new control code
ss.dwWin32ExitCode = NO_ERROR;
ss.dwServiceSpecificExitCode = 0;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0; if (fdwControl == SERVICE_CONTROL_INTERROGATE) {
SetServiceStatus(hSS, &ss);
break;
} // Determine which PENDING state to return
if (dwSrvCtrlToPend[fdwControl] != 0) {
ss.dwCurrentState = dwSrvCtrlToPend[fdwControl];
ss.dwCheckPoint = 0;
ss.dwWaitHint = 500; // half a second
SetServiceStatus(hSS, &ss);
} switch (fdwControl) {
case SERVICE_CONTROL_RUN:
case SERVICE_CONTROL_CONTINUE:
// While running, create a pipe that clients can connect to.
hpipe = CreateNamedPipe(L"\\\\.\\pipe\\MSJTime",
PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE, 1, sizeof(st), sizeof(st), 1000, NULL); // Associate the pipe with the completion port
CreateIoCompletionPort(hpipe, g_hIOCP, CK_PIPE, 0); // Pend an asynchronous connect against the pipe
ZeroMemory(&o, sizeof(o));
ConnectNamedPipe(hpipe, &o);
break; case SERVICE_CONTROL_PAUSE:
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
// When not running, close the pipe so clients can't connect
CloseHandle(hpipe);
break; case 128: // User-defined control (demonstration purposes)
MessageBox(NULL, L"Got control code 128", g_szAppName, MB_OK);
break;
} // Determine which complete state to return
if (dwSrvPendToState[ss.dwCurrentState] != 0) {
ss.dwCurrentState = dwSrvPendToState[ss.dwCurrentState];
ss.dwCheckPoint = ss.dwWaitHint = 0;
SetServiceStatus(hSS, &ss);
}
break; case CK_PIPE:
// We got a client request: Send our current time to the client
GetSystemTime(&st);
WriteFile(hpipe, &st, sizeof(st), &dwBytesTransferred, NULL);
FlushFileBuffers(hpipe);
DisconnectNamedPipe(hpipe); // Allow another client to connect
ZeroMemory(&o, sizeof(o));
ConnectNamedPipe(hpipe, &o);
} if (ss.dwCurrentState != SERVICE_STOPPED) {
// Sleep until a control code comes in or a client connects
GetQueuedCompletionStatus(g_hIOCP, &dwBytesTransferred,
&dwCompKey, &po, INFINITE);
fdwControl = dwBytesTransferred;
}
} while (ss.dwCurrentState != SERVICE_STOPPED); // Cleanup and stop this service
CloseHandle(g_hIOCP);
}
//////////////////////////////////////////////////////////////////////////////
void InstallService() {
TCHAR szModulePathname[_MAX_PATH];
SC_HANDLE hService; // Open the SCM on this machine.
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); // Get our full pathname
GetModuleFileName(NULL, szModulePathname, dimof(szModulePathname)); // Add this service to the SCM's database.
hService = CreateService(hSCM, g_szAppName, g_szAppName, 0,
SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE,
szModulePathname, NULL, NULL, NULL, NULL, NULL); // Close the service and the SCM
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
}
//////////////////////////////////////////////////////////////////////////////
void RemoveService() {
// Open the SCM on this machine.
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); // Open this service for DELETE access
SC_HANDLE hService = OpenService(hSCM, g_szAppName, DELETE); // Remove this service from the SCM's database.
DeleteService(hService); // Close the service and the SCM
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
}
//////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstExePrev,
LPSTR pszCmdLine, int nCmdShow) { int nArgc = __argc;
#ifdef UNICODE
LPCTSTR *ppArgv = (LPCTSTR*) CommandLineToArgvW(GetCommandLine(), &nArgc);
#else
LPCTSTR *ppArgv = (LPCTSTR*) __argv;
#endif BOOL fStartService = (nArgc < 2), fDebug = FALSE;
int i; for (i = 1; i < nArgc; i++) {
if ((ppArgv[i][0] == __TEXT('-')) || (ppArgv[i][0] == __TEXT('/'))) {
// Command line switch
if (lstrcmpi(&ppArgv[i][1], __TEXT("install")) == 0)
InstallService(); if (lstrcmpi(&ppArgv[i][1], __TEXT("remove")) == 0)
RemoveService(); if (lstrcmpi(&ppArgv[i][1], __TEXT("debug")) == 0)
fDebug = TRUE;
}
}
InstallService();#ifdef UNICODE
HeapFree(GetProcessHeap(), 0, (PVOID) ppArgv);
#endif if (fDebug) {
// Running as EXE not as service, just run the service for debugging
TimeServiceMain(0, NULL);
} if (fStartService) {
SERVICE_TABLE_ENTRY ServiceTable[] = {
{ g_szAppName, TimeServiceMain },
{ NULL, NULL } // End of list
};
StartServiceCtrlDispatcher(ServiceTable);
} return(0);
}
//////////////////////////////// End Of File /////////////////////////////////
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货