Смекни!
smekni.com

Организация удаленного доступа к распределенным базам данных (стр. 18 из 19)

END ^

^

CREATE PROCEDURE TalksExamineOwner (APhoneNmb CHAR(7), ADate DATE)

RETURNS (APhone INTEGER)

AS

DECLARE VARIABLE AStreet INTEGER;

DECLARE VARIABLE NOwner INTEGER;

DECLARE VARIABLE APhoneCode INTEGER;

BEGIN

SELECT PKey FROM Phones WHERE (PhoneNmb = :APhoneNmb) AND (:ADate BETWEEN BegDate AND EndDate)

INTO :APhone;

IF (:APhone IS NULL) THEN

BEGIN

SELECT NullOwner FROM SysSettings INTO :NOwner;

SELECT Street FROM PhonesOwners

WHERE (PKey = :NOwner) AND (:ADate BETWEEN PhonesOwners.BegDate AND PhonesOwners.EndDate)

INTO :AStreet;

IF (:AStreet IS NOT NULL) THEN

BEGIN

EXECUTE PROCEDURE PrGenPhonesKeys RETURNING_VALUES :APhone;

INSERT INTO PhonesKeys (Code)

VALUES (:APhone);

INSERT INTO Phones(Owner, PKey, PhoneNmb, Street, InstallDate, RemoveDate, BegDate, EndDate)

VALUES (:NOwner, :APhone, :APhoneNmb, :AStreet, :ADate, "12.12.2222", :ADate, "12.12.2222");

END

END

END ^

CREATE PROCEDURE TalksGetTax

AS

BEGIN

EXIT;

END ^

CREATE PROCEDURE TalksGetPay (APhone INTEGER, ADay DATE, ACallTime INTEGER, AHowLong INTEGER)

RETURNS (APay FLOAT, ACalculated SMALLINT, IsLgot SMALLINT)

AS

DECLARE VARIABLE ATax FLOAT;

DECLARE VARIABLE AProcNach FLOAT;

DECLARE VARIABLE ATalksUsl INTEGER;

DECLARE VARIABLE AOwner INTEGER;

DECLARE VARIABLE ANalog FLOAT;

BEGIN

ACalculated = 0;

SELECT TimeTalksUsl FROM SysSettings INTO :ATalksUsl;

IF (:ATalksUsl IS NULL) THEN EXIT;

SELECT Owner FROM Phones WHERE (PKey = :APhone) AND (:ADay BETWEEN BegDate AND EndDate)

INTO :AOwner;

IF (:AOwner IS NULL) THEN EXIT;

EXECUTE PROCEDURE UslGetOwnerTax(:AOwner, :ATalksUsl, :ADay)

RETURNING_VALUES :ATax, :AProcNach, :ANalog;

IF (:ATax IS NULL) THEN EXIT;

APay = ATax*AHowLong*AProcNach/3000;

ACalculated = 1;

END ^

CREATE PROCEDURE TalksCallBilling (APhone INTEGER, ACallDate DATE, ACallTime INTEGER, AHowLong INTEGER)

RETURNS (ATalksPayCode INTEGER, ACalculated SMALLINT)

AS

DECLARE VARIABLE APay FLOAT;

DECLARE VARIABLE PayCode INTEGER;

DECLARE VARIABLE IsLgot SMALLINT;

DECLARE VARIABLE TTime INTEGER;

DECLARE VARIABLE LTime INTEGER;

BEGIN

EXECUTE PROCEDURE TalksGetPay(APhone, ACallDate, ACallTime, AHowLong)

RETURNING_VALUES :APay, :ACalculated, :IsLgot;

SELECT Code FROM TalksPay WHERE (Phone = :APhone) AND (CallDate = :ACallDate)

INTO PayCode;

IF (:ACalculated = 0) THEN EXIT;

IF (:IsLgot = 0) THEN BEGIN

TTime = AHowLong;

LTime = 0;

END

ELSE BEGIN

LTime = AHowLong;

TTime = 0;

END

IF (:PayCode IS NULL) THEN BEGIN

EXECUTE PROCEDURE PrGenTalksPay RETURNING_VALUES :PayCode;

INSERT INTO TalksPay (Code, Phone, CallDate, TotalSum, TotalFullTime, TotalLgotTime)

VALUES (:PayCode, :APhone, :ACallDate, :APay, :TTime, :LTime);

END

ELSE BEGIN

UPDATE TalksPay

SET TotalSum = TotalSum+:APay,

TotalFullTime = TotalFullTime+:TTime,

TotalLgotTime = TotalLgotTime+:LTime

WHERE Code = :PayCode;

END

END ^

CREATE PROCEDURE UslGetOwnerTax(AOwner INTEGER, AUsl INTEGER, ADate DATE)

RETURNS (ATax FLOAT,

AProcNach FLOAT,

ANalog FLOAT)

AS

DECLARE VARIABLE ACategory INTEGER;

BEGIN

SELECT Category FROM PhonesOwners

WHERE (PKey = :AOwner) AND (:ADate BETWEEN BegDate AND EndDate)

INTO :ACategory;

SELECT Tax, NachCoeff, Nalog FROM UslLgots

WHERE (Usl = :AUsl) AND (:ADate BETWEEN BegDate AND EndDate)

INTO :ATax, :AProcNach, :ANalog;

EXIT;

END

Приложение 2

Приложение 3

Исходные тексты коммуникационного сервиса

ServiceMain.c

Файл ServiceMain.c - Модуль инициализации и управления сервером.

/*************************************************************/

/* Main unit for Communication Service */

/* Copyright (c) 1997 by Malkov O.V. */

/* JSC "Svyazinform" RM */

/*************************************************************/

#include <windows.h>

#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 <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 = "&bsol;pipe&bsol;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 "..&bsol;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, "&bsol;"Svyazinform&bsol;" Communicatin Service Initialized");

return(0);

}

void ServerDoPause()

{

SuspendThread(&ShedulingThread);

SuspendThread(&ClientHandlingThread);

LogEvent(EVENTLOG_INFORMATION_TYPE, "&bsol;"Svyazinform&bsol;" Communicatin Service Paused");

}

void ServerDoContinue()

{

ResumeThread(&ShedulingThread);

ResumeThread(&ClientHandlingThread);

LogEvent(EVENTLOG_INFORMATION_TYPE, "&bsol;"Svyazinform&bsol;" 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, "&bsol;"Svyazinform&bsol;" 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

};