Организация удаленного доступа к распределенным базам данных. Содержание Введение 3 Основные подходы к проектированию распределенных баз данных 5
Скачать 0.97 Mb.
|
Приложение 2Приложение 3Исходные тексты коммуникационного сервиса ServiceMain.c Файл ServiceMain.c - Модуль инициализации и управления сервером. /*************************************************************/ /* Main unit for Communication Service */ /* Copyright (c) 1997 by Malkov O.V. */ /* JSC "Svyazinform" RM */ /*************************************************************/ #include #include "DoService.h" #include "CommonConfig.h" /* Globals */ SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE ServiceStatusHandle; /* Function Prototypes */ void WINAPI ServiceStart (DWORD argc, LPTSTR *argv); VOID WINAPI ServiceCtrlHandler (IN DWORD opcode); 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 #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 #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 #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 #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 #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 #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 { } |