Организация удаленного доступа к распределенным базам данных
DWORD ServiceInitialization(DWORD argc, LPTSTR *argv,
DWORD *specificError);
VOID _CRTAPI1 main(int argc, char **argv)
{
int i;
SERVICE_TABLE_ENTRY DispatchTable[] = {
{ TEXT("SiTime"), ServiceStart },
{ NULL, NULL }
};
/* Allow the user to override settings with command line switches */
for ( i = 1; i < argc; i++) {
if ((*argv[i] == '-') || (*argv[i] == '/')) {
switch (tolower(*(argv[i]+1))) {
case 'p': // protocol sequence
pszProtocolSequence = argv[++i];
break;
case 'e': // endpoint
pszEndpoint = argv[++i];
break;
default: ;
}
}
}
if (!StartServiceCtrlDispatcher( DispatchTable)) {
/* Error Handling */
}
}
void WINAPI ServiceStart(DWORD argc, LPTSTR *argv)
{
DWORD status;
DWORD specificError;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatusHandle = RegisterServiceCtrlHandler(
TEXT("SiTime"),
ServiceCtrlHandler);
if (ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) {
/* Error Handling */
return;
}
// Initialization code goes here.
status = ServiceInitialization(argc,argv, &specificError);
// Handle error condition
if (status != NO_ERROR) {
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwWin32ExitCode = status;
ServiceStatus.dwServiceSpecificExitCode = specificError;
SetServiceStatus (ServiceStatusHandle, &ServiceStatus);
return;
}
// Initialization complete - report running status
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus)) {
status = GetLastError();
}
// This is where the service does its work. //
ServerProcess();
return;
}
/* stub initialization function */
DWORD ServiceInitialization(DWORD argc, LPTSTR *argv,
DWORD *specificError)
{
*specificError = ServerInit();
if (*specificError) return *specificError;
return(0);
}
void WINAPI ServiceCtrlHandler ( IN DWORD Opcode)
{
DWORD status;
switch(Opcode) {
case SERVICE_CONTROL_PAUSE:
/* Do whatever it takes to pause here. */
ServerDoPause();
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
/* Do whatever it takes to continue here.*/
ServerDoContinue();
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
/* Do whatever it takes to stop here. */
ServerDoStop();
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
status = GetLastError();
}
return;
case SERVICE_CONTROL_INTERROGATE:
/* fall through to send current status */
break;
default:
/* Error handling */
break;
}
/* Send current status.*/
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus)) {
status = GetLastError();
}
return;
}
CommonConfig.c
Файл CommonConfig.c - Управление конфигурацией
#include <windows.h>
#include "CommonConfig.h"
#include "EventLog.h"
#define REGVALUENAME_LENGTH 255
DWORD ConfigWatchingThread;
HANDLE hConfigMutex = NULL;
HANDLE hTaskMutex = NULL;
unsigned char * pszProtocolSequence = "ncacn_np";
unsigned char * pszSecurity = NULL;
unsigned char * pszEndpoint = "\pipe\CommServ";
unsigned int cMinCalls = 1;
unsigned int cMaxCalls = 20;
unsigned int fDontWait = FALSE;
struct TASKENTRY TaskTable[TASK_COUNT];
int EntryCount = 0;
DWORD TaskThreads[TASK_COUNT];
int TaskCount = 0;
void UpdateVariables()
{
HKEY hKey;
DWORD dwIndex = 0;
DWORD VNameLength = REGVALUENAME_LENGTH;
char VName[REGVALUENAME_LENGTH];
DWORD dwLength = sizeof(struct TASKENTRY);
int i;
__try {
WaitForSingleObject(hConfigMutex, INFINITE);
// Инициализация таблицы задач
for (i = 0; i < TASK_COUNT; i++) {
TaskTable[i].Active = FALSE;
TaskTable[i].ExecTime = 0;
ZeroMemory(&TaskTable[i].DllName, sizeof(TaskTable[i].DllName));
TaskTable[i].TermProc = NULL;
TaskTable[i].TaskThread = 0;
}
// Загрузка таблицы задач из реестра
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGISTRY_TASKS_PATH,
0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) {
dwIndex = 0;
EntryCount = 0;
while (RegEnumValue(hKey,
dwIndex,
(char *)&VName,
&VNameLength,
NULL,
NULL,
(LPVOID)&TaskTable[dwIndex],
&dwLength) == ERROR_SUCCESS) {
if (dwLength != sizeof(struct TASKENTRY)) {
LogEvent(EVENTLOG_ERROR_TYPE, "Invalid Task Parameter");
break;
}
EntryCount+=1;
dwIndex+=1;
}
RegCloseKey(hKey);
} else LogEvent(EVENTLOG_ERROR_TYPE, "Error Loading Configuration");
}
__finally {
ReleaseMutex(hConfigMutex);
}
}
DoService.c
#include <windows.h>
#include "DoService.h"
#include "..Comm.h"
#include "CommonConfig.h"
#include "ClientHandler.h"
#include "EventLog.h"
#include "ShedulerServ.h"
void ServerProcess() {
hConfigMutex = CreateMutex(NULL, FALSE, NULL);
hTaskMutex = CreateMutex(NULL, FALSE, NULL);
CreateThread(NULL, 0, ShedulingProc, NULL, 0, &ShedulingThread);
CreateThread(NULL, 0, RPCClientHandling, NULL, 0, &ClientHandlingThread);
}
DWORD ServerInit() {
RPC_STATUS status;
status = RpcServerUseProtseqEp(
pszProtocolSequence,
cMaxCalls,
pszEndpoint,
pszSecurity); // Security descriptor
if (status != NO_ERROR) {
return(1);
}
status = RpcServerRegisterIf(
CommService_ServerIfHandle, // !!!
NULL, // MgrTypeUuid
NULL); // MgrEpv; null means use default
if (status != NO_ERROR) {
return(2);
}
LogEvent(EVENTLOG_INFORMATION_TYPE, ""Svyazinform" Communicatin Service Initialized");
return(0);
}
void ServerDoPause()
{
SuspendThread(&ShedulingThread);
SuspendThread(&ClientHandlingThread);
LogEvent(EVENTLOG_INFORMATION_TYPE, ""Svyazinform" Communicatin Service Paused");
}
void ServerDoContinue()
{
ResumeThread(&ShedulingThread);
ResumeThread(&ClientHandlingThread);
LogEvent(EVENTLOG_INFORMATION_TYPE, ""Svyazinform" Communicatin Service Resumed");
}
void ServerDoStop() {
RPC_STATUS status;
status = RpcMgmtStopServerListening(NULL);
if (status != NO_ERROR) {
// Error handling
}
status = RpcServerUnregisterIf(NULL, NULL, FALSE);
if (status != NO_ERROR) {
// Error handling
}
TerminateTasks();
WaitForSingleObject(&ClientHandlingThread, 5000);
CloseHandle(&ClientHandlingThread);
InterlockedIncrement(&TerminateSheduling);
WaitForSingleObject(&ShedulingThread, 5000);
CloseHandle(&ShedulingThread);
WaitForSingleObject(hConfigMutex, 3000);
ReleaseMutex(hConfigMutex);
CloseHandle(hConfigMutex);
WaitForSingleObject(hTaskMutex, 3000);
ReleaseMutex(hTaskMutex);
CloseHandle(hTaskMutex);
LogEvent(EVENTLOG_INFORMATION_TYPE, ""Svyazinform" Communicatin Service Stopped");
}
/**************************************************************/
/* MIDL allocate and free */
/**************************************************************/
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return(malloc(len));
}
void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}
ClientHandler.c
/**********************************************************/
/* Этот модуль обрабатывает подключения клиентов */
/**********************************************************/
#include <windows.h>
#include "ClientHandler.h"
#include "CommonConfig.h"
#include "../Comm.h"
DWORD ClientHandlingThread;
DWORD WINAPI RPCClientHandling(LPVOID ThreadParm)
{
RPC_STATUS status;
status = RpcServerListen(
cMinCalls,
cMaxCalls,
fDontWait);
if (status != NO_ERROR) {
return 1;
}
return 0;
}
void RefreshIniProps()
{
MessageBeep(1);
return;
}
EventLog.c
#include <windows.h>
#include "EventLog.h"
void LogEvent(WORD EventType, LPSTR EventMsg)
{
HANDLE h;
h = RegisterEventSource(NULL, /* uses local computer */
"CommServ"); /* source name */
if (h != NULL)
{
ReportEvent(h, /* event log handle */
EventType, /* event type */
0, /* category zero */
0x1003, /* event identifier */
NULL, /* no user security identifier */
1, /* one substitution string */
0, /* no data */
&EventMsg, /* address of string array */
NULL); /* address of data */
DeregisterEventSource(h);
}
return;
}
Comm_s.c
/* this ALWAYS GENERATED file contains the RPC server stubs */
/* File created by MIDL compiler version 3.00.15 */
/* at Tue Jun 03 11:35:46 1997
*/
/* Compiler settings for comm.idl:
Os, W1, Zp8, env=Win32, ms_ext, c_ext, oldnames
error checks: none
*/
//@@MIDL_FILE_HEADING( )
#include <string.h>
#include "comm.h"
#define TYPE_FORMAT_STRING_SIZE 1
#define PROC_FORMAT_STRING_SIZE 3
typedef struct _MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} MIDL_TYPE_FORMAT_STRING;
typedef struct _MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} MIDL_PROC_FORMAT_STRING;
extern const MIDL_TYPE_FORMAT_STRING __MIDLTypeFormatString;
extern const MIDL_PROC_FORMAT_STRING __MIDLProcFormatString;
/* Standard interface: CommService, ver. 1.0,
GUID={0x4a25d2e0,0x6703,0x11d0,{0x89,0x27,0x00,0xa0,0x24,0x13,0x85,0x0e}} */
extern RPC_DISPATCH_TABLE CommService_DispatchTable;
static const RPC_SERVER_INTERFACE CommService___RpcServerInterface =
{
sizeof(RPC_SERVER_INTERFACE),
{{0x4a25d2e0,0x6703,0x11d0,{0x89,0x27,0x00,0xa0,0x24,0x13,0x85,0x0e}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
&CommService_DispatchTable,
0,
0,
0,
0,
0
};
RPC_IF_HANDLE CommService_ServerIfHandle = (RPC_IF_HANDLE)& CommService___RpcServerInterface;
extern const MIDL_STUB_DESC CommService_StubDesc;
void __RPC_STUB
CommService_RefreshIniProps(
PRPC_MESSAGE _pRpcMessage )
{
MIDL_STUB_MESSAGE _StubMsg;
RPC_STATUS _Status;
((void)(_Status));
NdrServerInitializeNew(
_pRpcMessage,
&_StubMsg,
&CommService_StubDesc);
RpcTryFinally
{
RefreshIniProps();
}
RpcFinally
{
}
RpcEndFinally
_pRpcMessage->BufferLength =
(unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer);
}
static const MIDL_STUB_DESC CommService_StubDesc =
{
(void __RPC_FAR *)& CommService___RpcServerInterface,
MIDL_user_allocate,
MIDL_user_free,
0,
0,
0,
0,
0,
__MIDLTypeFormatString.Format,
0, /* -error bounds_check flag */
0x10001, /* Ndr library version */
0,
0x300000f, /* MIDL Version 3.0.15 */
0,
0,
0, /* Reserved1 */
0, /* Reserved2 */
0, /* Reserved3 */
0, /* Reserved4 */
0 /* Reserved5 */
};
static RPC_DISPATCH_FUNCTION CommService_table[] =
{
CommService_RefreshIniProps,
0
};
RPC_DISPATCH_TABLE CommService_DispatchTable =
{
1,
CommService_table
};
#if !defined(__RPC_WIN32__)
#error Invalid build platform for this stub.
#endif
static const MIDL_PROC_FORMAT_STRING __MIDLProcFormatString =
{
0,
{
0x5b, /* FC_END */
0x5c, /* FC_PAD */
0x0
}
};
static const MIDL_TYPE_FORMAT_STRING __MIDLTypeFormatString =
{
0,
{
0x0
}
};
ShedulerServ.c
/**********************************************************//* Task Sheduler
/**********************************************************/
#include <windows.h>
#include "ShedulerServ.h"
#include "CommonConfig.h"
#include "EventLog.h"
#define SLEEP_INTERVAL 5000
#define ACTIVATE_INTERVAL 60000
BOOL TerminateSheduling = FALSE;
DWORD ShedulingThread;
DWORD WINAPI TaskProc(LPVOID ThreadParm);
void AnalyseTaskTable();
DWORD GetTimeInMins();
DWORD WINAPI ShedulingProc(LPVOID ThreadParm)
{
long i = 0;
while (!TerminateSheduling) {
if ((i += SLEEP_INTERVAL) >= ACTIVATE_INTERVAL) {
i = 0;
if (TaskCount == 0) UpdateVariables();
AnalyseTaskTable();
}
Sleep(SLEEP_INTERVAL);
}
return 0;
}
DWORD WINAPI TaskProc(LPVOID ThreadParm)
{
HINSTANCE hLib;
FARPROC hProc;
InterlockedIncrement(&TaskCount);
WaitForSingleObject(hConfigMutex, INFINITE);
MessageBeep(1);
if (hLib = LoadLibrary((char *)&((struct TASKENTRY*)ThreadParm)->DllName)) {
if (((struct TASKENTRY*)ThreadParm)->TermProc = GetProcAddress(hLib, (LPCSTR)TaskProcName))
{
((struct TASKENTRY*)ThreadParm)->Active = TRUE;
ReleaseMutex(hConfigMutex);
if (hProc = GetProcAddress(hLib, (LPCSTR)TaskProcName)) {
hProc();
__try {
WaitForSingleObject(hConfigMutex, INFINITE);
((struct TASKENTRY*)ThreadParm)->Active = FALSE;
CloseHandle((HANDLE)((struct TASKENTRY*)ThreadParm)->TaskThread);
}
__finally {
ReleaseMutex(hConfigMutex);
}
} else LogEvent(EVENTLOG_ERROR_TYPE, "Error Getting Procedure Address");
} else LogEvent(EVENTLOG_ERROR_TYPE, "Error Getting TermProc Address");
} else {
ReleaseMutex(hConfigMutex);
LogEvent(EVENTLOG_ERROR_TYPE, "Error Loading Library");
}
InterlockedDecrement(&TaskCount);
return 0;
}
void AnalyseTaskTable()
{
DWORD CurrTime;
int i;
CurrTime = GetTimeInMins();
__try {
WaitForSingleObject(hConfigMutex, INFINITE);
for (i = 0; i < EntryCount; i++) {
if ((TaskTable[i].ExecTime == CurrTime) &&
(!TaskTable[i].Active)) {
CreateThread(NULL, 0, TaskProc, &TaskTable[i], 0, &TaskTable[i].TaskThread);
}
}
}
__finally {
ReleaseMutex(hConfigMutex);
}
}
DWORD GetTimeInMins()
{
SYSTEMTIME SysTime;
GetLocalTime(&SysTime);
return SysTime.wHour*60+SysTime.wMinute;
}
void TerminateTasks()
{
int i;
DWORD TaskIndex = 0;
HANDLE Handles[TASK_COUNT];
for (i = 0; i < EntryCount; i++) {
if (TaskTable[i].Active) {
TaskTable[i].TermProc();
Handles[TaskIndex++] = (HANDLE)TaskTable[i].TaskThread;
}
}
WaitForMultipleObjects(TaskIndex, Handles, TRUE, INFINITE);
}
Comm.h
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 3.00.15 */
/* at Tue Jun 03 11:35:46 1997
*/
/* Compiler settings for comm.idl:
Os, W1, Zp8, env=Win32, ms_ext, c_ext, oldnames
error checks: none
*/
//@@MIDL_FILE_HEADING( )
#include "rpc.h"
#include "rpcndr.h"
#ifndef __comm_h__
#define __comm_h__
#ifdef __cplusplus
extern "C"{
#endif
/* Forward Declarations */
void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t);
void __RPC_USER MIDL_user_free( void __RPC_FAR * );
#ifndef __CommService_INTERFACE_DEFINED__
#define __CommService_INTERFACE_DEFINED__
/****************************************
* Generated header for interface: CommService
* at Tue Jun 03 11:35:46 1997
* using MIDL 3.00.15
****************************************/
/* [implicit_handle][version][uuid] */
void RefreshIniProps( void);
extern handle_t CommServ_IfHandle;
extern RPC_IF_HANDLE CommService_ClientIfHandle;
extern RPC_IF_HANDLE CommService_ServerIfHandle;
#endif /* __CommService_INTERFACE_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif
DoService.h
/**************************************************************/
/* DoService Module - implementation of initialisation other
/* tasks */
/* */
/* Copuright (c) 1997 by Malkov O.V. */
/* JSC "Svyazinform" RM */
/**************************************************************/
#ifndef __DOSERVICE
#define __DESERVICE
void ServerProcess();
DWORD ServerInit();
void ServerDoPause();
void ServerDoStop();
void ServerDoContinue();
#endif
CommonConfig.h
/**************** Server Engine Header File *******************/
#ifndef __COMMON_CONFIG
#define __COMMON_CONFIG
#define TASK_COUNT 10
#include "../RegistryConfig.h"
extern DWORD ConfigWatchingThread;
extern HANDLE hConfigMutex;
extern HANDLE hTaskMutex;
extern unsigned char *pszProtocolSequence;
extern unsigned char *pszSecurity;
extern unsigned char *pszEndpoint;
extern unsigned int cMinCalls;
extern unsigned int cMaxCalls;
extern unsigned int fDontWait;
extern struct TASKENTRY TaskTable[TASK_COUNT];
extern int EntryCount;
extern DWORD TaskThreads[TASK_COUNT];
extern int TaskCount;
DWORD WINAPI CommonConfigWatcher(LPVOID ThreadParm);
void UpdateVariables();
#endif
EventLog.h
#ifndef __EVENT_LOG
#define __EVENT_LOG
void LogEvent(WORD EventType, LPSTR EventMsg);
#endif
ClientHandler.h
#ifndef __CLIENT_HANDLER
#define __CLIENT_HANDLER
extern DWORD ClientHandlingThread;
DWORD WINAPI RPCClientHandling(LPVOID ThreadParm);
void RefreshIniProps();
#endif
ShedulerServ.h
#ifndef __SHEDULING_SERVICE
#define __SHEDULING_SERVICE
#define TaskProcName "TaskProc"
extern BOOL TerminateSheduling;
extern DWORD ShedulingThread;
DWORD WINAPI ShedulingProc(LPVOID ThreadParm);
void TerminateTasks();
#endif
RegistryConfig.h
#ifndef __REGISTRY_CONFIG
#define __REGISTRY_CONFIG
#define REGISTRY_TASKS_PATH "SOFTWARE\Svyazinform\CommService\Tasks"
struct TASKENTRY
{
DWORD ExecTime;
char DllName[256];
FARPROC TermProc;
DWORD TaskThread;
BOOL Active;
};
#endif
Comm.idl
/* IDL File */
[ uuid (4a25d2e0-6703-11d0-8927-00a02413850e),
version(1.0)
]
interface CommService
{
void RefreshIniProps();
}
Comm.acf
/* acf file for TimeInclude Service (RPC) */
[ implicit_handle(handle_t CommServ_IfHandle)
]interface CommService
{
}
Приложение 4Исходные тексты программы установки коммуникационного сервиса
#include <windows.h>
#include <stdio.h>
void RegEventSource();
VOID _CRTAPI1 main(void)
{
LPCTSTR lpszBinaryPathName =
TEXT("c:\ibserver\bin\CommServ.exe");
SC_HANDLE schSCManager;
SC_HANDLE schService;
/* Open a handle to the SC Manager database. */
schSCManager = OpenSCManager(
NULL, /* local machine */
NULL, /* ServicesActive database */
SC_MANAGER_ALL_ACCESS); /* full access rights */
if (schSCManager == NULL) {
printf("nError opening Service Manager.n");
return;
}
schService = CreateService(
schSCManager, /* SCManager database */
TEXT("CommServ"), /* name of service */
TEXT("JSC "SvjazInform" Communication Service"), /* service name to display */
SERVICE_ALL_ACCESS, /* desired access */
SERVICE_WIN32_OWN_PROCESS, /* service type */
SERVICE_DEMAND_START, /* start type */
SERVICE_ERROR_NORMAL, /* error control type */
lpszBinaryPathName, /* service's binary */
NULL, /* no load ordering group */
NULL, /* no tag identifier */
NULL, /* no dependencies */
NULL, /* LocalSystem account */
NULL); /* no password */
if (schService == NULL) {
printf("nFailed to create service!n");
}
else
printf("CreateService SUCCESSn");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
RegEventSource();
}
void RegEventSource()
{
HKEY hk;
DWORD dwData;
UCHAR szBuf[80];
if (RegCreateKey(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Services
\EventLog\Application\CommServ", &hk)) {
printf("could not create registry key");
return;
}
/* Set the Event ID message-file name. */
strcpy(szBuf, "c:\ibserver\bin\CommServ.exe");
/* Add the Event ID message-file name to the subkey. */
if (RegSetValueEx(hk, /* subkey handle */
"EventMessageFile", /* value name */
0, /* must be zero */
REG_EXPAND_SZ, /* value type */
(LPBYTE) szBuf, /* address of value data */
strlen(szBuf) + 1)) /* length of value data*/
{
printf("could not set event message file");
return;
}
/* Set the supported types flags. */
dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
EVENTLOG_INFORMATION_TYPE;
if (RegSetValueEx(hk, /* subkey handle */
"TypesSupported", /* value name */
0, /* must be zero */
REG_DWORD, /* value type */
(LPBYTE) &dwData, /* address of value data*/
sizeof(DWORD))) /* length of value data */
{
printf("could not set supported types");
return;
}
RegCloseKey(hk);
}
Приложение 5Исходные тексты программы удаления коммуникационного сервиса
#include <windows.h>
#include <stdio.h>
void CleanRegistry();
VOID _CRTAPI1 main(void)
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
/* Open a handle to the SC Manager database. */
schSCManager = OpenSCManager(
NULL, /* local machine */
NULL, /* ServicesActive database */
SC_MANAGER_ALL_ACCESS); /* full access rights */
if (schSCManager == NULL) {
printf("nError opening Service Manager.n");
return;
}
schService = OpenService(
schSCManager, /* SCManager database */
TEXT("CommServ"), /* name of service */
DELETE); /* only need DELETE access */
if (! DeleteService(schService) )
printf("nFailed to Delete service!n");
else
printf("DeleteService SUCCESSn");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
void CleanRegistry()
{
if (RegDeleteKey(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Services
\EventLog\Application\CommServ"))
{
printf("nError Cleaning Registry");
} else {
printf("nCleaning Registry SUCCESS");
}
return;
}
Приложение 6
Структуры баз данных