최종완료보고 버전

This commit is contained in:
CodeTempla
2026-05-20 03:08:08 +09:00
commit 10d255ed51
548 changed files with 435582 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
// DebugAssist.h: interface for the DebugAssist class.
//
//////////////////////////////////////////////////////////////////////
#if defined(_WIN32) && !defined(_DEBUG)
#ifndef DEBUGASSIST_H__
#define DEBUGASSIST_H__
#pragma once
#include <DbgHelp.h> // in Platform SDK
//#include <c:\Program Files\Microsoft SDKs\Windows\v5.0\Include\DbgHelp.h>
//or #include <c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\DbgHelp.h>
//or #include <c:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include\DbgHelp.h>
//or #include <c:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\Include\DbgHelp.h>
#include <tchar.h>
TCHAR g_szDbgModulePathName[2048] = {0,};
TCHAR g_szDumpPathName[2048] = {0,};
LONG TopExceptionFilter(LPEXCEPTION_POINTERS pException)
{
HMODULE hDll = LoadLibrary(g_szDbgModulePathName);
if (hDll == NULL)
{
OutputDebugString(TEXT("tps, ERROR, Can't found DbgHelp.dll file.\n"));
return EXCEPTION_EXECUTE_HANDLER;
}
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = pException;
exceptionInfo.ClientPointers = NULL;
BOOL (WINAPI * fnWriteDump)(HANDLE, DWORD, ...);
fnWriteDump = (BOOL (WINAPI *)(HANDLE, DWORD, ...))GetProcAddress(hDll, "MiniDumpWriteDump");
if (fnWriteDump == NULL)
{
OutputDebugString(TEXT("tps, ERROR, Can't found MiniDumpWriteDump interface.\n"));
return EXCEPTION_EXECUTE_HANDLER;
}
HANDLE hFile = CreateFile(g_szDumpPathName, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
fnWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile,
MiniDumpNormal, &exceptionInfo, NULL, NULL);
FreeLibrary(hDll);
CloseHandle(hFile);
return EXCEPTION_EXECUTE_HANDLER;
}
void InitialDumpWriting(LPCTSTR pszDir = NULL, LPCTSTR pszPrefix = NULL)
{
TCHAR szPostFix[32];
SYSTEMTIME systemTime;
GetLocalTime(&systemTime);
_stprintf(szPostFix, TEXT("_%.4d%.2d%.2d%.2d%.2d%.2d.dmp"), systemTime.wYear,
systemTime.wMonth, systemTime.wDay, systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
if (pszDir && pszPrefix)
{
// pszDir ex) "C:\\Temp\\"
_tcscpy(g_szDbgModulePathName, pszDir);
_tcscat(g_szDbgModulePathName, TEXT("dbghelp.dll"));
_tcscpy(g_szDumpPathName, pszDir);
_tcscat(g_szDumpPathName, pszPrefix);
_tcscat(g_szDumpPathName, szPostFix);
}
else
{
char szModuleFileName[2048];
GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName));
char szDrive[_MAX_DRIVE], szDir[1024], szFileName[1024], szExt[1024];
_splitpath_s(szModuleFileName, szDrive, _MAX_DRIVE, szDir, 1024, szFileName, 1024, szExt, 1024);
if (pszDir)
{
_tcscpy(g_szDbgModulePathName, pszDir);
_tcscpy(g_szDumpPathName, pszDir);
}
else
{
_tcscpy(g_szDbgModulePathName, szDrive);
_tcscat(g_szDbgModulePathName, szDir);
_tcscpy(g_szDumpPathName, g_szDbgModulePathName);
}
_tcscat(g_szDbgModulePathName, TEXT("dbghelp.dll"));
if (pszPrefix)
{
_tcscat(g_szDumpPathName, pszPrefix);
_tcscat(g_szDumpPathName, szPostFix);
}
else
{
_tcscat(g_szDumpPathName, szFileName);
_tcscat(g_szDumpPathName, szPostFix);
}
}
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)TopExceptionFilter);
}
#endif // DEBUGASSIST_H__
#endif // defined(_WIN32) && !defined(_DEBUG)
+645
View File
@@ -0,0 +1,645 @@
/*---------------------------------------------------------------------------
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (C) 1993 - 2000. Microsoft Corporation. All rights reserved.
MODULE: service.c
PURPOSE: Implements functions required by all Windows NT services
FUNCTIONS:
main(int argc, char **argv);
service_ctrl(DWORD dwCtrlCode);
service_main(DWORD dwArgc, LPTSTR *lpszArgv);
CmdInstallService();
CmdRemoveService();
CmdDebugService(int argc, char **argv);
ControlHandler ( DWORD dwCtrlType );
GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
---------------------------------------------------------------------------*/
#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <tchar.h>
#include "WinService.h"
#pragma warning(disable:4996)
// internal variables
SERVICE_STATUS g_ssStatus; // current status of the service
SERVICE_STATUS_HANDLE g_sshStatusHandle;
DWORD g_dwWinServiceErr = 0;
TCHAR g_szWinServiceErr[256];
BOOL g_bDebugExecuted = FALSE;
// internal function prototypes
VOID WINAPI service_ctrl(DWORD dwCtrlCode);
VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
VOID CmdInstallService();
VOID CmdRemoveService();
VOID CmdDebugService(int argc, char **argv);
BOOL WINAPI ControlHandler(DWORD dwCtrlType);
LPTSTR GetLastErrorText(LPTSTR lpszBuf, DWORD dwSize);
//
// FUNCTION: main
//
// PURPOSE: entrypoint for service
//
// PARAMETERS:
// argc - number of command line arguments
// argv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// main() either performs the command line task, or
// call StartServiceCtrlDispatcher to register the
// main service thread. When the this call returns,
// the service has stopped, so exit.
//
#if 0 // original code
void __cdecl main(int argc, char **argv)
#else
void WinServiceMain(int argc, char **argv)
#endif
{
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ TEXT((char *)g_szServiceName), (LPSERVICE_MAIN_FUNCTION)service_main}, { NULL, NULL}
};
if ((argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')))
{
if (_stricmp("install", argv[1] + 1) == 0)
{
CmdInstallService();
}
else if (_stricmp("remove", argv[1] + 1) == 0)
{
CmdRemoveService();
}
else if (_stricmp("debug", argv[1] + 1) == 0)
{
g_bDebugExecuted = TRUE;
CmdDebugService(argc, argv);
}
else
{
goto dispatch;
}
exit(0);
}
//else
//{
// g_bDebugExecuted = TRUE;
// CmdDebugService(argc, argv);
//}
// if it doesn't match any of the above parameters
// the service control manager may be starting the service
// so we must call StartServiceCtrlDispatcher
dispatch:
const char * pszAppName = strrchr(argv[0], '\\');
if (pszAppName)
{
pszAppName++;
}
else
{
pszAppName = strrchr(argv[0], '/');
if (pszAppName)
pszAppName++;
else
pszAppName = argv[0];
}
// this is just to be friendly
printf("%s -install to install the service\n", pszAppName);
printf("%s -remove to remove the service\n", pszAppName);
//printf("%s -debug <params> to run as a console app for debugging\n", pszAppName);
printf("\nStartServiceCtrlDispatcher being called.\n");
printf("This may take several seconds. Please wait.\n");
#if 1 // original code
if (!StartServiceCtrlDispatcher(dispatchTable))
AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
#endif
}
//
// FUNCTION: service_main
//
// PURPOSE: To perform actual initialization of the service
//
// PARAMETERS:
// dwArgc - number of command line arguments
// lpszArgv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This routine performs the service initialization and then calls
// the user defined ServiceStart() routine to perform majority
// of the work.
//
void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
// register our service control handler:
//
g_sshStatusHandle = RegisterServiceCtrlHandler(TEXT(g_szServiceName), service_ctrl);
if (!g_sshStatusHandle)
goto cleanup;
// SERVICE_STATUS members that don't change in example
//
g_ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ssStatus.dwServiceSpecificExitCode = 0;
// report the status to the service control manager.
//
if (!ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
goto cleanup;
ServiceStart(dwArgc, lpszArgv, FALSE);
cleanup:
// try to report the stopped status to the service control manager.
//
if (g_sshStatusHandle)
ReportStatusToSCMgr(SERVICE_STOPPED, g_dwWinServiceErr, 0);
return;
}
//
// FUNCTION: service_ctrl
//
// PURPOSE: This function is called by the SCM whenever
// ControlService() is called on this service.
//
// PARAMETERS:
// dwCtrlCode - type of control requested
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
VOID WINAPI service_ctrl(DWORD dwCtrlCode)
{
// Handle the requested control code.
//
switch (dwCtrlCode)
{
// Stop the service.
//
// SERVICE_STOP_PENDING should be reported before
// setting the Stop Event - hServerStopEvent - in
// ServiceStop(). This avoids a race condition
// which may result in a 1053 - The Service did not respond...
// error.
case SERVICE_CONTROL_STOP:
ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
ServiceStop();
return;
// Update the service status.
//
case SERVICE_CONTROL_INTERROGATE:
break;
// invalid control code
//
default:
break;
}
ReportStatusToSCMgr(g_ssStatus.dwCurrentState, NO_ERROR, 0);
}
//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
// COMMENTS:
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
BOOL fResult = TRUE;
if (!g_bDebugExecuted) // when debugging we don't report to the SCM
{
if (dwCurrentState == SERVICE_START_PENDING)
g_ssStatus.dwControlsAccepted = 0;
else
g_ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ssStatus.dwCurrentState = dwCurrentState;
g_ssStatus.dwWin32ExitCode = dwWin32ExitCode;
g_ssStatus.dwWaitHint = dwWaitHint;
if ((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED))
g_ssStatus.dwCheckPoint = 0;
else
g_ssStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the service control manager.
//
if (!(fResult = SetServiceStatus(g_sshStatusHandle, &g_ssStatus)))
{
AddToMessageLog(TEXT("SetServiceStatus"));
}
}
return fResult;
}
//
// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
//
// PURPOSE: Allows any thread to log an error message
//
// PARAMETERS:
// lpszMsg - text for message
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
VOID AddToMessageLog(LPTSTR lpszMsg)
{
//TCHAR szMsg [(sizeof(SZSERVICENAME) / sizeof(TCHAR)) + 100 ];
TCHAR * pszMsg = (TCHAR *)malloc(((strlen(g_szServiceName) / sizeof(TCHAR)) + 100) * sizeof(TCHAR));
HANDLE hEventSource;
LPTSTR lpszStrings[2];
if (!g_bDebugExecuted)
{
g_dwWinServiceErr = GetLastError();
// Use event logging to log the error.
//
hEventSource = RegisterEventSource(NULL, TEXT(g_szServiceName));
_stprintf(pszMsg, TEXT("%s error: %d"), TEXT(g_szServiceName), g_dwWinServiceErr);
lpszStrings[0] = pszMsg;
lpszStrings[1] = lpszMsg;
if (hEventSource != NULL)
{
ReportEvent(hEventSource, // handle of event source
EVENTLOG_ERROR_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // strings in lpszStrings
0, // no bytes of raw data
(LPCTSTR *)lpszStrings, // array of error strings
NULL); // no raw data
DeregisterEventSource(hEventSource);
}
}
free(pszMsg);
}
///////////////////////////////////////////////////////////////////
//
// The following code handles service installation and removal
//
//
// FUNCTION: CmdInstallService()
//
// PURPOSE: Installs the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
void CmdInstallService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
TCHAR szPath[2048];
if (GetModuleFileName(NULL, szPath, 2048) == 0)
{
_tprintf(TEXT("Unable to install %s - %s\n"), TEXT(g_szServiceDisplayName), GetLastErrorText(g_szWinServiceErr, 256));
return;
}
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE // access required
);
if (schSCManager)
{
schService = CreateService(
schSCManager, // SCManager database
TEXT(g_szServiceName), // name of service
TEXT(g_szServiceDisplayName), // name to display
SERVICE_QUERY_STATUS | SERVICE_CHANGE_CONFIG | SERVICE_START, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
//SERVICE_DEMAND_START, // start type
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL, // error control type
szPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
TEXT(g_szDependencies), // dependencies
NULL, // LocalSystem account
NULL); // no password
if (g_szServiceDesc && g_szServiceDesc[0] != TEXT('\0'))
{
SERVICE_DESCRIPTION serviceDesc;
serviceDesc.lpDescription = (LPSTR)g_szServiceDesc;
if (ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &serviceDesc) == 0)
_tprintf(TEXT("ChangeServiceConfig2 failed - %s\n"), GetLastErrorText(g_szWinServiceErr, 256));
}
SC_ACTION scAction[1];
scAction[0].Type = SC_ACTION_RESTART;
scAction[0].Delay = 10000;
SERVICE_FAILURE_ACTIONS serviceFailAction;
serviceFailAction.lpsaActions = (SC_ACTION *)scAction;
serviceFailAction.cActions = 1;
serviceFailAction.dwResetPeriod = 600;
serviceFailAction.lpRebootMsg = TEXT("");
serviceFailAction.lpCommand = TEXT("");
if (ChangeServiceConfig2(schService, SERVICE_CONFIG_FAILURE_ACTIONS, &serviceFailAction) == 0)
_tprintf(TEXT("ChangeServiceConfig2 failed 2 - %s\n"), GetLastErrorText(g_szWinServiceErr, 256));
if (schService)
{
_tprintf(TEXT("%s installed.\n"), TEXT(g_szServiceDisplayName));
CloseServiceHandle(schService);
}
else
{
_tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(g_szWinServiceErr, 256));
}
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(g_szWinServiceErr, 256));
}
//
// FUNCTION: CmdRemoveService()
//
// PURPOSE: Stops and removes the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
void CmdRemoveService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_CONNECT // access required
);
if (schSCManager)
{
schService = OpenService(schSCManager, TEXT(g_szServiceName), DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS);
if (schService)
{
// try to stop the service
if (ControlService(schService, SERVICE_CONTROL_STOP, &g_ssStatus))
{
_tprintf(TEXT("Stopping %s."), TEXT(g_szServiceDisplayName));
Sleep(1000);
while (QueryServiceStatus(schService, &g_ssStatus))
{
if (g_ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
_tprintf(TEXT("."));
Sleep(1000);
}
else
break;
}
if (g_ssStatus.dwCurrentState == SERVICE_STOPPED)
_tprintf(TEXT("\n%s stopped.\n"), TEXT(g_szServiceDisplayName));
else
_tprintf(TEXT("\n%s failed to stop.\n"), TEXT(g_szServiceDisplayName));
}
// now remove the service
if (DeleteService(schService))
_tprintf(TEXT("%s removed.\n"), TEXT(g_szServiceDisplayName));
else
_tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(g_szWinServiceErr, 256));
CloseServiceHandle(schService);
}
else
_tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(g_szWinServiceErr, 256));
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(g_szWinServiceErr, 256));
}
///////////////////////////////////////////////////////////////////
//
// The following code is for running the service as a console app
//
//
// FUNCTION: CmdDebugService(int argc, char ** argv)
//
// PURPOSE: Runs the service as a console application
//
// PARAMETERS:
// argc - number of command line arguments
// argv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
void CmdDebugService(int argc, char ** argv)
{
DWORD dwArgc;
LPTSTR *lpszArgv;
#ifdef UNICODE
lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc));
if (NULL == lpszArgv)
{
// CommandLineToArvW failed!!
_tprintf(TEXT("CmdDebugService CommandLineToArgvW returned NULL\n"));
return;
}
#else
dwArgc = (DWORD) argc;
lpszArgv = argv;
#endif
_tprintf(TEXT("Debugging %s.\n"), TEXT(g_szServiceDisplayName));
SetConsoleCtrlHandler(ControlHandler, TRUE);
ServiceStart(dwArgc, lpszArgv, TRUE);
#ifdef UNICODE
// Must free memory allocated for arguments
GlobalFree(lpszArgv);
#endif // UNICODE
}
//
// FUNCTION: ControlHandler ( DWORD dwCtrlType )
//
// PURPOSE: Handled console control events
//
// PARAMETERS:
// dwCtrlType - type of control event
//
// RETURN VALUE:
// True - handled
// False - unhandled
//
// COMMENTS:
//
BOOL WINAPI ControlHandler(DWORD dwCtrlType)
{
switch (dwCtrlType)
{
case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate
case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
_tprintf(TEXT("Stopping %s.\n"), TEXT(g_szServiceDisplayName));
ServiceStop();
return TRUE;
break;
}
return FALSE;
}
//
// FUNCTION: GetLastErrorText
//
// PURPOSE: copies error message text to string
//
// PARAMETERS:
// lpszBuf - destination buffer
// dwSize - size of buffer
//
// RETURN VALUE:
// destination buffer
//
// COMMENTS:
//
LPTSTR GetLastErrorText(LPTSTR lpszBuf, DWORD dwSize)
{
DWORD dwRet;
LPTSTR lpszTemp = NULL;
dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&lpszTemp,
0,
NULL);
// supplied buffer is not long enough
if (!dwRet || ((long)dwSize < (long)dwRet + 14))
lpszBuf[0] = TEXT('\0');
else
{
lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
_stprintf(lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError());
}
if (lpszTemp)
LocalFree((HLOCAL) lpszTemp);
return lpszBuf;
}
#endif _WIN32
+120
View File
@@ -0,0 +1,120 @@
/*---------------------------------------------------------------------------
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (C) 1993 - 2000. Microsoft Corporation. All rights reserved.
MODULE: service.h
Comments: The use of this header file and the accompanying service.c
file simplifies the process of writting a service. You as a developer
simply need to follow the TODO's outlined in this header file, and
implement the ServiceStart() and ServiceStop() functions.
There is no need to modify the code in service.c. Just add service.c
to your project and link with the following libraries...
libcmt.lib kernel32.lib advapi.lib shell32.lib
This code also supports unicode. Be sure to compile both service.c and
and code #include "service.h" with the same Unicode setting.
Upon completion, your code will have the following command line interface
<service exe> -? to display this list
<service exe> -install to install the service
<service exe> -remove to remove the service
<service exe> -debug <params> to run as a console app for debugging
Note: This code also implements Ctrl+C and Ctrl+Break handlers
when using the debug option. These console events cause
your ServiceStop routine to be called
Also, this code only handles the OWN_SERVICE service type
running in the LOCAL_SYSTEM security context.
To control your service ( start, stop, etc ) you may use the
Services control panel applet or the NET.EXE program.
To aid in writing/debugging service, the
SDK contains a utility (MSTOOLS\BIN\SC.EXE) that
can be used to control, configure, or obtain service status.
SC displays complete status for any service/driver
in the service database, and allows any of the configuration
parameters to be easily changed at the command line.
For more information on SC.EXE, type SC at the command line.
------------------------------------------------------------------------------*/
#ifdef _WIN32
#ifndef WIN_SERVICE__H_
#define WIN_SERVICE__H_
extern const char * g_szServiceName; // internal name of the service
extern const char * g_szServiceDisplayName; // displayed name of the service
extern const char * g_szDependencies; // list of service dependencies - "dep1\0dep2\0\0"
extern const char * g_szServiceDesc;
//////////////////////////////////////////////////////////////////////////////
//// todo: ServiceStart()must be defined by in your code.
//// The service should use ReportStatusToSCMgr to indicate
//// progress. This routine must also be used by StartService()
//// to report to the SCM when the service is running.
////
//// If a ServiceStop procedure is going to take longer than
//// 3 seconds to execute, it should spawn a thread to
//// execute the stop code, and return. Otherwise, the
//// ServiceControlManager will believe that the service has
//// stopped responding
////
VOID ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv, BOOL bConsoleMode);
VOID ServiceStop();
//////////////////////////////////////////////////////////////////////////////
//// The following are procedures which
//// may be useful to call within the above procedures,
//// but require no implementation by the user.
//// They are implemented in service.c
//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
//
// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
//
// PURPOSE: Allows any thread to log an error message
//
// PARAMETERS:
// lpszMsg - text for message
//
// RETURN VALUE:
// none
//
void AddToMessageLog(LPTSTR lpszMsg);
void WinServiceMain(int argc, char **argv);
#endif // WIN_SERVICE__H_
#endif _WIN32