diff --git a/builds/mac_os_x/CS/CS.pbproj/project.pbxproj b/builds/mac_os_x/CS/CS.pbproj/project.pbxproj index f376d22574..b0e6d75d93 100644 --- a/builds/mac_os_x/CS/CS.pbproj/project.pbxproj +++ b/builds/mac_os_x/CS/CS.pbproj/project.pbxproj @@ -738,7 +738,6 @@ F616C4490200B0CF01EF0ADE, F616C4670200B0CF01EF0ADE, F616C4920200B0CF01EF0ADE, - F616C5230200B0CF01EF0ADE, F616C53A0200B0CF01EF0ADE, F616C55E0200B0CF01EF0ADE, F616C6FC0200B0D001EF0ADE, @@ -3143,85 +3142,6 @@ path = undef.h; refType = 4; }; - F616C5230200B0CF01EF0ADE = { - children = ( - F616C5240200B0CF01EF0ADE, - F616C5250200B0CF01EF0ADE, - F616C5260200B0CF01EF0ADE, - F616C5270200B0CF01EF0ADE, - F616C5280200B0CF01EF0ADE, - F616C5290200B0CF01EF0ADE, - F616C52A0200B0CF01EF0ADE, - F616C52B0200B0CF01EF0ADE, - F616C52C0200B0CF01EF0ADE, - F616C52D0200B0CF01EF0ADE, - F616C52E0200B0CF01EF0ADE, - F616C52F0200B0CF01EF0ADE, - ); - isa = PBXGroup; - path = ipserver; - refType = 4; - }; - F616C5240200B0CF01EF0ADE = { - isa = PBXFileReference; - path = alli.cpp; - refType = 4; - }; - F616C5250200B0CF01EF0ADE = { - isa = PBXFileReference; - path = alli_proto.h; - refType = 4; - }; - F616C5260200B0CF01EF0ADE = { - isa = PBXFileReference; - path = blk.h; - refType = 4; - }; - F616C5270200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ipapi_proto.h; - refType = 4; - }; - F616C5280200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ipc.h; - refType = 4; - }; - F616C5290200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ipcevent.cpp; - refType = 4; - }; - F616C52A0200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ipcli_proto.h; - refType = 4; - }; - F616C52B0200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ipclient.cpp; - refType = 4; - }; - F616C52C0200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ipevt_proto.h; - refType = 4; - }; - F616C52D0200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ips.h; - refType = 4; - }; - F616C52E0200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ipserver.cpp; - refType = 4; - }; - F616C52F0200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ipsrv_proto.h; - refType = 4; - }; F616C53A0200B0CF01EF0ADE = { children = ( F616C53C0200B0CF01EF0ADE, @@ -6710,26 +6630,6 @@ path = interface.cpp; refType = 4; }; - F616C8810200B0D001EF0ADE = { - isa = PBXFileReference; - path = ipc.cpp; - refType = 4; - }; - F616C8820200B0D001EF0ADE = { - isa = PBXFileReference; - path = ipc.h; - refType = 4; - }; - F616C8830200B0D001EF0ADE = { - isa = PBXFileReference; - path = ipc_proto.h; - refType = 4; - }; - F616C8840200B0D001EF0ADE = { - isa = PBXFileReference; - path = ipc_server.cpp; - refType = 4; - }; F616C8850200B0D001EF0ADE = { isa = PBXFileReference; path = isc_tcpent.mar; diff --git a/builds/posix/prefix.mingw b/builds/posix/prefix.mingw index 9e59cae87c..ed518cc62b 100644 --- a/builds/posix/prefix.mingw +++ b/builds/posix/prefix.mingw @@ -19,10 +19,6 @@ # 2003-Sep-27 BRS Removed IPSERVER after XNET is included # -# To build with ipserver use the following two lines instead the uncommented ones -# PROD_FLAGS=-O2 -march=i586 -mcpu=i686 -DMINGW -mno-cygwin -mthreads -Wall -Wno-unused-variable -Wno-unknown-pragmas -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DMAXPATHLEN=255 -DWIN32_LEAN_AND_MEAN -MMD -# DEV_FLAGS=-ggdb -march=i586 -mcpu=i686 -DMINGW -mno-cygwin -mthreads -Wall -Wno-unused-variable -Wno-unknown-pragmas -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DMAXPATHLEN=255 -DDEBUG_GDS_ALLOC -DWIN32_LEAN_AND_MEAN -MMD - # -Wno-unused-variable is used due to unused gpre generated variables PROD_FLAGS=-O2 -march=i586 -mcpu=i686 -DMINGW -mno-cygwin -mthreads -Wall -Wshadow -Wundef -pedantic -Wno-long-long -Wno-unused-variable -Wno-unknown-pragmas -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD DEV_FLAGS=-ggdb -march=i586 -mcpu=i686 -DMINGW -mno-cygwin -mthreads -Wall -Wshadow -Wundef -pedantic -Wno-long-long -Wno-unused-variable -Wno-unknown-pragmas -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD @@ -42,8 +38,6 @@ LIB_GUI:= -mwindows -lcomctl32 -lgdi32 EMBED_UTIL_TARGETS:=gstat gsec nbackup fb_lock_print CLIENT_UTIL_TARGETS:=gstat gsec ibguard instsvc instreg nbackup fb_lock_print -# To build with ipserver uncomment the following line -# WIN_IPSERVER_Files:=ipserver.cpp alli.cpp Physical_IO_Module=os/win32/winnt.cpp diff --git a/builds/win32/msvc6/fbclient_static.dsp b/builds/win32/msvc6/fbclient_static.dsp index 7adaa099f3..203cd58d62 100644 --- a/builds/win32/msvc6/fbclient_static.dsp +++ b/builds/win32/msvc6/fbclient_static.dsp @@ -216,22 +216,6 @@ SOURCE=..\..\..\src\remote\xdr.cpp SOURCE=..\..\..\src\remote\xnet.cpp # End Source File # End Group -# Begin Group "IPSERVER files" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\src\ipserver\alli.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipcevent.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipclient.cpp -# End Source File -# End Group # Begin Group "DSQL files" # PROP Default_Filter "" diff --git a/builds/win32/msvc6/ipserver.dsp b/builds/win32/msvc6/ipserver.dsp deleted file mode 100644 index 68d1c8ab85..0000000000 --- a/builds/win32/msvc6/ipserver.dsp +++ /dev/null @@ -1,141 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ipserver" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=ipserver - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ipserver.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ipserver.mak" CFG="ipserver - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ipserver - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE "ipserver - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ipserver - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "" -# PROP BASE Intermediate_Dir "" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\..\..\temp\debug\ipserver" -# PROP Intermediate_Dir "..\..\..\temp\debug\ipserver" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /GR /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /GR /ZI /Od /I "../../../src/include" /I "../../../src/include/gen" /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /D "_X86_" /D "DEV_BUILD" /D "SUPERSERVER" /FD /GZ /c -# ADD BASE RSC /l 0x41d /d "_DEBUG" -# ADD RSC /l 0x41d /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ELSEIF "$(CFG)" == "ipserver - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "" -# PROP BASE Intermediate_Dir "" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\..\..\temp\release\ipserver" -# PROP Intermediate_Dir "..\..\..\temp\release\ipserver" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /GX /GR /Ot /Oi /Op /Oy /Ob2 /I "../../../src/include" /I "../../../src/include/gen" /D "NDEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /D "_X86_" /FD /GZ /c -# SUBTRACT BASE CPP /YX -# ADD CPP /nologo /MD /W3 /GX /GR /Ot /Og /Oi /Op /Oy /Ob1 /I "../../../src/include" /I "../../../src/include/gen" /D "NDEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /D "_X86_" /D "SUPERSERVER" /FD /EHc- /c -# ADD BASE RSC /l 0x41d /d "_DEBUG" -# ADD RSC /l 0x41d /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ENDIF - -# Begin Target - -# Name "ipserver - Win32 Debug" -# Name "ipserver - Win32 Release" -# Begin Group "IPSERVER files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\..\src\ipserver\alli.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipcevent.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipclient.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipserver.cpp -# End Source File -# End Group -# Begin Group "Header files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\..\src\ipserver\alli_proto.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\blk.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipapi_proto.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipc.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipcli_proto.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipevt_proto.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ips.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\ipserver\ipsrv_proto.h -# End Source File -# End Group -# End Target -# End Project diff --git a/src/ipserver/alli.cpp b/src/ipserver/alli.cpp deleted file mode 100644 index d0396e5dad..0000000000 --- a/src/ipserver/alli.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * PROGRAM: Interprocess server interface - * MODULE: alli.cpp - * DESCRIPTION: Internal block allocator - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -#include "firebird.h" -#include - -#include "../ipserver/ipc.h" - -#define BLKDEF(type, root, tail) {sizeof (struct root), tail}, -static struct -{ - SSHORT typ_root_length; - SSHORT typ_tail_length; -} PIPE_block_sizes[] = { - {0, 0}, - -#include "../ipserver/blk.h" - {0, 0} -}; - -#include "../jrd/gds_proto.h" -#include "../ipserver/alli_proto.h" - - -//____________________________________________________________ -// -// Allocate a block. -// -void* ALLI_alloc(ULONG size) -{ - return gds__alloc(size); -} - - -//____________________________________________________________ -// -// Allocate a block from a given pool and initialize the block. -// This is the primary block allocation routine. -// -BLK ALLI_block(UCHAR type, int count) -{ -/* - -if (type <= (SCHAR) type_MIN || type >= (SCHAR) type_MAX) - abort(); - -*/ - -// Compute block length - - const USHORT tail = PIPE_block_sizes[type].typ_tail_length; - USHORT size = PIPE_block_sizes[type].typ_root_length + count * tail; - - BLK block = (BLK) ALLI_alloc((SLONG) size); - - if (block) - { - block->blk_type = type; - block->blk_length = size; - - size -= sizeof(struct blk); - if (size) - { - memset((SCHAR *) block + sizeof(struct blk), 0, size); - } - } - - return block; -} - - -//____________________________________________________________ -// -// Free a block. -// -void ALLI_free(void* block) -{ - gds__free(block); -} - - -//____________________________________________________________ -// -// Release a structured block. -// -void ALLI_release(BLK block) -{ - ALLI_free(block); -} diff --git a/src/ipserver/alli_proto.h b/src/ipserver/alli_proto.h deleted file mode 100644 index 0470be0581..0000000000 --- a/src/ipserver/alli_proto.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * PROGRAM: Interprocess Interface Allocator - * MODULE: alli_proto.h - * DESCRIPTION: Prototype Header file for alli.cpp - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -#ifndef ALLI_PROTO_H -#define ALLI_PROTO_H - -void* ALLI_alloc(ULONG); -BLK ALLI_block(UCHAR, int); -void ALLI_free(void*); -void ALLI_release(BLK); - -#endif /* ALLI_PROTO_H */ - diff --git a/src/ipserver/blk.h b/src/ipserver/blk.h deleted file mode 100644 index bc735db661..0000000000 --- a/src/ipserver/blk.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * PROGRAM: Interprocess server interface - * MODULE: blk.h - * DESCRIPTION: Block type definitions - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -BLKDEF(type_idb, idb, 0) - BLKDEF(type_irq, irq, 0) - BLKDEF(type_itr, itr, 0) - BLKDEF(type_ibl, ibl, 1) - BLKDEF(type_ivnt, ivnt, 0) - BLKDEF(type_ipserver_isr, ipserver_isr, 0) - BLKDEF(type_icc, icc, 0) diff --git a/src/ipserver/ipapi_proto.h b/src/ipserver/ipapi_proto.h deleted file mode 100644 index 5a32466492..0000000000 --- a/src/ipserver/ipapi_proto.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * PROGRAM: JRD Access Method - * MODULE: ipapi_proto.h - * DESCRIPTION: Prototype header file for ipclient.cpp api calls - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - - -#ifndef IPAPI_PROTO_H -#define IPAPI_PROTO_H - -#ifdef __cplusplus -extern "C" { -#endif - -ISC_STATUS IPI_attach_database(ISC_STATUS*, USHORT, const SCHAR*, - struct idb**, USHORT, const SCHAR*, - const SCHAR*); -ISC_STATUS IPI_blob_info(ISC_STATUS*, struct ibl**, USHORT, - const UCHAR*, USHORT, UCHAR*); -ISC_STATUS IPI_cancel_blob(ISC_STATUS *, struct ibl **); -ISC_STATUS IPI_cancel_events(ISC_STATUS *, struct idb **, SLONG *); -ISC_STATUS IPI_close_blob(ISC_STATUS *, struct ibl **); -ISC_STATUS IPI_commit_transaction(ISC_STATUS *, struct itr **); -ISC_STATUS IPI_commit_retaining(ISC_STATUS *, struct itr **); -ISC_STATUS IPI_compile_request(ISC_STATUS*, struct idb**, - struct irq**, - USHORT, const UCHAR*); -ISC_STATUS IPI_create_blob(ISC_STATUS *, struct idb **, - struct itr **, struct ibl **, - struct bid *); -ISC_STATUS IPI_create_blob2(ISC_STATUS*, struct idb**, - struct itr**, struct ibl**, - struct bid*, USHORT, const UCHAR*); -ISC_STATUS IPI_create_database(ISC_STATUS*, USHORT, const SCHAR*, - struct idb**, USHORT, const SCHAR*, - SSHORT, const SCHAR*); -ISC_STATUS IPI_database_info(ISC_STATUS*, struct idb**, USHORT, - const UCHAR*, USHORT, UCHAR*); -ISC_STATUS IPI_ddl(ISC_STATUS*, struct idb**, struct itr**, - USHORT, const UCHAR*); -ISC_STATUS IPI_detach_database(ISC_STATUS *, struct idb **); -ISC_STATUS IPI_drop_database(ISC_STATUS *, struct idb **); -ISC_STATUS IPI_get_segment(ISC_STATUS *, struct ibl **, USHORT *, - USHORT, UCHAR *); -ISC_STATUS IPI_get_slice(ISC_STATUS*, struct idb**, struct itr**, - struct bid*, USHORT, const UCHAR*, USHORT, - const UCHAR*, SLONG, UCHAR*, SLONG*); -ISC_STATUS IPI_open_blob(ISC_STATUS*, struct idb**, struct itr**, - struct ibl**, struct bid*); -ISC_STATUS IPI_open_blob2(ISC_STATUS*, struct idb**, - struct itr**, struct ibl**, - struct bid*, USHORT, const UCHAR*); -ISC_STATUS IPI_prepare_transaction(ISC_STATUS *, struct itr **, - USHORT, UCHAR *); -ISC_STATUS IPI_put_segment(ISC_STATUS*, struct ibl**, USHORT, - const UCHAR*); -ISC_STATUS IPI_put_slice(ISC_STATUS*, struct idb**, struct itr**, - struct bid*, USHORT, const UCHAR*, USHORT, - const UCHAR*, SLONG, UCHAR*); -ISC_STATUS IPI_que_events(ISC_STATUS*, struct idb**, SLONG*, - USHORT, const UCHAR*, - FPTR_EVENT_CALLBACK, void*); -ISC_STATUS IPI_receive(ISC_STATUS *, struct irq **, SSHORT, USHORT, - UCHAR *, SSHORT -#ifdef SCROLLABLE_CURSORS - , USHORT, ULONG -#endif - ); -ISC_STATUS IPI_reconnect_transaction(ISC_STATUS*, struct idb**, - struct itr**, USHORT, - const UCHAR*); -ISC_STATUS IPI_release_request(ISC_STATUS *, struct irq **); -ISC_STATUS IPI_request_info(ISC_STATUS*, struct irq**, USHORT, - USHORT, const UCHAR*, USHORT, UCHAR*); -ISC_STATUS IPI_rollback_transaction(ISC_STATUS *, struct itr **); -ISC_STATUS IPI_rollback_retaining(ISC_STATUS *, struct itr **); -ISC_STATUS IPI_seek_blob(ISC_STATUS *, struct ibl **, SSHORT, SLONG, - SLONG *); -ISC_STATUS IPI_send(ISC_STATUS *, struct irq **, SSHORT, USHORT, - UCHAR *, SSHORT); -ISC_STATUS IPI_service_attach(ISC_STATUS*, USHORT, const TEXT*, - struct idb**, USHORT, const SCHAR*); -ISC_STATUS IPI_service_detach(ISC_STATUS *, struct idb **); -ISC_STATUS IPI_service_query(ISC_STATUS*, struct idb**, ULONG*, - USHORT, const SCHAR*, - USHORT, const SCHAR*, - USHORT, SCHAR*); -ISC_STATUS IPI_service_start(ISC_STATUS*, struct idb**, ULONG*, - USHORT, const SCHAR*); -ISC_STATUS IPI_start_request(ISC_STATUS *, struct irq **, - struct itr **, SSHORT); -ISC_STATUS IPI_start_and_send(ISC_STATUS *, struct irq **, - struct itr **, SSHORT, USHORT, - UCHAR *, SSHORT); -ISC_STATUS IPI_start_multiple(ISC_STATUS *, struct itr **, SSHORT, - int **); -ISC_STATUS IPI_start_transaction(ISC_STATUS *, struct itr **, - SSHORT, ...); -ISC_STATUS IPI_transaction_info(ISC_STATUS*, struct itr**, USHORT, - const UCHAR*, USHORT, UCHAR*); -ISC_STATUS IPI_transact_request(ISC_STATUS*, struct idb**, - struct itr**, USHORT, const UCHAR*, - USHORT, UCHAR*, USHORT, - UCHAR*); -ISC_STATUS IPI_unwind_request(ISC_STATUS *, struct irq **, SSHORT); - -/* DSQL entrypoints */ - -ISC_STATUS IPI_allocate_statement(ISC_STATUS *, struct idb **, - struct ipserver_isr **); -ISC_STATUS IPI_execute(ISC_STATUS *, struct itr **, - struct ipserver_isr **, USHORT, UCHAR *, - USHORT, USHORT, UCHAR *); -ISC_STATUS IPI_execute2(ISC_STATUS *, struct itr **, - struct ipserver_isr **, USHORT, UCHAR *, - USHORT, USHORT, UCHAR *, USHORT, - UCHAR *, USHORT, USHORT, UCHAR *); -ISC_STATUS IPI_execute_immediate(ISC_STATUS*, struct idb**, - struct itr**, USHORT, const UCHAR*, - USHORT, USHORT, const UCHAR*, - USHORT, USHORT, UCHAR*); -ISC_STATUS IPI_execute_immediate2(ISC_STATUS*, struct idb**, - struct itr**, USHORT, - const UCHAR*, USHORT, USHORT, - const UCHAR*, USHORT, USHORT, - UCHAR*, USHORT, UCHAR*, - USHORT, USHORT, UCHAR*); -ISC_STATUS IPI_fetch(ISC_STATUS*, struct ipserver_isr**, USHORT, - const UCHAR*, USHORT, USHORT, UCHAR*); -ISC_STATUS IPI_free_statement(ISC_STATUS *, struct ipserver_isr **, - USHORT); -ISC_STATUS IPI_insert(ISC_STATUS *, struct ipserver_isr **, USHORT, - UCHAR *, USHORT, USHORT, UCHAR *); -ISC_STATUS IPI_prepare(ISC_STATUS *, struct itr **, - struct ipserver_isr **, USHORT, UCHAR *, - USHORT, USHORT, UCHAR *, USHORT, - UCHAR *); -ISC_STATUS IPI_set_cursor_name(ISC_STATUS*, struct ipserver_isr**, - const UCHAR*, USHORT); -ISC_STATUS IPI_sql_info(ISC_STATUS*, struct ipserver_isr**, - USHORT, const UCHAR*, USHORT, UCHAR*); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif // IPAPI_PROTO_H - diff --git a/src/ipserver/ipc.h b/src/ipserver/ipc.h deleted file mode 100644 index 9fd99fdc48..0000000000 --- a/src/ipserver/ipc.h +++ /dev/null @@ -1,669 +0,0 @@ -/* - * PROGRAM: Interprocess Interface definitions - * MODULE: ipc.h - * DESCRIPTION: Common descriptions - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -#ifndef IPSERVER_IPC_H -#define IPSERVER_IPC_H - -#include -#include "../jrd/common.h" -#include "../jrd/thd.h" - -#define ALLOC(type) ALLI_block (type, 0) -#define ALLOCV(type, count) ALLI_block (type, count) - -#ifdef BUFSIZ -const USHORT BLOB_LENGTH = BUFSIZ - 20; -#else -const USHORT BLOB_LENGTH = 1024 - 20; -#endif - -typedef enum { - op_attach, /* Attach database */ - op_create, /* Create database */ - op_detach, /* Detach database */ - - op_compile, /* Request based operations */ - op_start, - op_start_and_send, - op_send, - op_receive, - op_unwind, - op_release, - - op_transaction, /* Transaction operations */ - op_commit, - op_rollback, - op_reconnect, - - op_create_blob, /* Blob operations */ - op_open_blob, - op_get_segment, - op_put_segment, - op_cancel_blob, - op_close_blob, - - op_info_database, /* Information services */ - op_info_request, - op_info_transaction, - op_info_blob, - - op_prepare2, - op_commit_retaining, - op_rollback_retaining, - op_open_blob2, - op_create_blob2, - op_ddl, - op_que_events, - op_cancel_events, - op_put_slice, - op_get_slice, - op_seek_blob, - - op_allocate_stmt, /* DSQL operations */ - op_execute, - op_exec_immediate, - op_fetch, - op_free_stmt, - op_prepare_stmt, - op_set_cursor, - op_info_sql, /* Last opcode in V3.3 */ - - op_insert, - op_execute2, - op_exec_immediate2, - - op_service_attach, - op_service_detach, - op_service_info, - op_service_start, - - op_transact_request, - op_drop_database, - - op_ping, - op_disconnect, - op_max, - op_gateway_sync = 127 -} P_OP; - -/* mapped file parameters */ - -#define IPS_MAPPED_PER_CLI(p) ((ULONG)(p) * 1024L) -#define IPS_MAPPED_FOR_CLI(p,x) ((ULONG)(x) * IPS_MAPPED_PER_CLI(p)) -#define IPS_MAPPED_SIZE(p,c) ((ULONG)(c) * IPS_MAPPED_PER_CLI(p)) -#define IPS_USEFUL_SPACE(p) (IPS_MAPPED_PER_CLI(p) - sizeof( ips_comm_area)) - -const USHORT IPS_DEF_NUM_CLI = 10; /* default clients per mapped file */ -// const USHORT IPS_DEF_NUM_MAPS = 10; /* default maps available */ -const USHORT IPS_DEF_PAGES_PER_CLI = 8; /* default 1k pages space per client */ - -const USHORT IPS_MIN_NUM_CLI = 1; /* min clients per mapped file */ -// const USHORT IPS_MIN_NUM_MAPS = 1; /* min maps available */ -const USHORT IPS_MIN_PAGES_PER_CLI = 1; /* min 1k pages space per client */ - -const USHORT IPS_MAX_NUM_CLI = 64; /* max clients per mapped file */ -// const USHORT IPS_MAX_NUM_MAPS = 64; /* max maps available */ -const USHORT IPS_MAX_PAGES_PER_CLI = 16; /* max 1k pages space per client */ - -#define IPS_PACK_PARAMS(x,p,m,u) (((ULONG)(x) << 24) + ((ULONG)(p) << 16) + ((m) << 8) + (u) + IP_BIAS) -#define IPS_UNPACK_MAX_USERS(n) (((ULONG)(n - IP_BIAS) >> 24) & 0xFF) -#define IPS_UNPACK_PAGES(n) (((ULONG)(n - IP_BIAS) >> 16) & 0xFF) -#define IPS_UNPACK_MAPNUM(n) (((ULONG)(n - IP_BIAS) >> 8) & 0xFF) -#define IPS_UNPACK_USERNUM(n) ((n - IP_BIAS) & 0xFF) - -typedef struct bid { - ULONG bid_relation_id; /* Relation id (or null) */ - ULONG bid_number; /* Record number */ -} *BID; - -/* Block types */ - -struct blk; - -#ifndef INCLUDE_FB_BLK -#include "../include/old_fb_blk.h" -#endif - -/* Block types */ - -typedef struct cnct { - int *cnct_read_pipe; /* this is really a FILE pointer */ - int *cnct_write_pipe; /* this is really a FILE pointer */ -} *CNCT; - -/* mapped file structure */ - -typedef struct ipm { - struct ipm *ipm_next; /* pointer to next one */ - USHORT ipm_count; /* slots in use */ - USHORT ipm_number; /* mapped area number */ - HANDLE ipm_handle; /* handle of mapped memory */ - USHORT ipm_flags; /* flag word */ - LPVOID ipm_address; /* address of mapped memory */ - UCHAR ipm_ids[IPS_MAX_NUM_CLI]; - /* ids */ -} *IPM; - -/* mapped structure flags */ -const USHORT IPMF_SERVER_SHUTDOWN = 1; /* server has shut down */ - -/* thread connection control block */ - -typedef struct icc -{ - blk icc_header; - struct icc* icc_next; /* pointer to next thread */ - struct idb* icc_databases; /* linked list of attachments */ - struct ipm* icc_ipm; /* pointer back to ipm */ - SSHORT icc_file; /* this thread's mapped file number */ - SSHORT icc_slot; /* this thread's slot number */ - DWORD icc_thread_handle; /* thread's handle */ - HANDLE icc_file_handle; /* mapped file's handle */ - HANDLE icc_client_sem; /* client's semaphore handle */ - HANDLE icc_server_sem; /* server's semaphore handle */ - HANDLE icc_server_proc; /* server's process handle */ - HANDLE icc_client_proc; /* client's process handle */ - DWORD icc_server_id; /* server's process id */ - DWORD icc_client_id; /* client's process id */ - SSHORT icc_flags; /* status bits */ - HANDLE icc_waits[2]; /* wait for these handles */ - UCHAR* icc_mapped_addr; /* where the thread's mapped to */ -} *ICC; - -/* icc structure flags */ -const USHORT ICCF_SHUTDOWN = 1; /* shutdown in progress */ -const USHORT ICCF_SERVER_SHUTDOWN = 2; /* server has shut down */ -const USHORT ICCF_UNMAP_CLIENT = 4; /* client maps must be shut down */ - -/* database block */ - -typedef struct idb -{ - blk idb_header; - struct icc* idb_thread; /* back pointer to thread */ - FB_API_HANDLE idb_handle; /* database handle */ - struct itr* idb_transactions; /* linked list of transactions */ - struct irq* idb_requests; /* compiled requests */ - struct ipserver_isr* idb_sql_requests; /* SQL requests */ - struct ivnt* idb_events; /* events */ - struct idb* idb_next; /* pointer to next db */ - int* idb_status_vector; /* pointer to status vector */ - USHORT idb_flags; /* flags (see below) */ - SCHAR* idb_setjmp; -} *IDB; - -const USHORT IDBF_DATABASE_ATTACHMENT = 1; -const USHORT IDBF_SERVICE_ATTACHMENT = 2; -const USHORT IDBF_SERVER_SHUTDOWN = 4; - -/* transaction block */ - -typedef struct itr -{ - blk itr_header; - struct idb* itr_idb; - struct itr* itr_next; - struct ibl* itr_blobs; - FB_API_HANDLE itr_handle; - USHORT itr_flags; -} *ITR; - -const USHORT ITR_limbo = 1; - -/* blob control block */ - -typedef struct ibl -{ - blk ibl_header; - struct idb* ibl_idb; - struct itr* ibl_itr; - struct ibl* ibl_next; - FB_API_HANDLE ibl_handle; - SLONG ibl_offset; /* Apparent (to user) offset in blob */ - USHORT ibl_flags; - UCHAR* ibl_ptr; - USHORT ibl_length; - USHORT ibl_fragment_length; - USHORT ibl_buffer_length; - UCHAR ibl_buffer[1]; -} *IBL; - -//const USHORT IBL_eof = 1; -//const USHORT IBL_segment = 2; -//const USHORT IBL_eof_pending = 4; -const USHORT IBL_create = 8; - -/* request block */ - -typedef struct irq { - blk irq_header; - struct idb *irq_idb; - struct tra *irq_itr; - struct irq *irq_next; - struct irq **irq_user_handle; - FB_API_HANDLE irq_handle; -} *IRQ; - -/* event structure */ - -typedef struct ivnt { - blk ivnt_header; - struct ivnt *ivnt_next; - struct idb *ivnt_idb; - FPTR_EVENT_CALLBACK ivnt_ast; - void* ivnt_arg; - HWND ivnt_window; - SLONG ivnt_id; - SLONG ivnt_handle; -} *IVNT; - -/* remote SQL request */ - -typedef struct ipserver_isr { - blk isr_header; - struct ipserver_isr *isr_next; - struct idb *isr_idb; - struct itr *isr_itr; - FB_API_HANDLE isr_handle; - USHORT isr_rec_count; - USHORT isr_max_recs; - USHORT isr_eof_flag; - USHORT isr_batch_flag; - ISC_STATUS_ARRAY isr_status; - UCHAR *isr_cursor; - UCHAR *isr_packed; -} *IPSERVER_ISR; - -#define BLKDEF(type, root, tail) type, -enum blk_t { - type_MIN = 0, -#include "../ipserver/blk.h" - type_MAX -}; -#undef BLKDEF - -/* - This structure is used to move stuff between the ipc buffer(s) - and the client's and server's memory. - - Three buffers are tracked - a client buffer, a server buffer and - a buffer within the communications data structure. For the client - and server buffers, the address within that task plus the max size - and current size are maintained. there is a flag indicating whether - the buffer is used for input, output, both or neither. For the - comm buffer, a relative offset from the start of the comm area, - the current area mapped in the comm area and its allocated size - in the comm area are maintained. - - When the client needs to pass stuff to the server, space will be - allocated in the comm area for all client buffers. If there is - insufficient space, the comm buffer will be filled by the client - and emptied by the server as often as necessary to pass everything. - the same process is carried out when the server responds for any - data passed back to the client. - - There can be up to five of these in use for a call to the server. - The flag words are used to indicate what, if anything, to copy for - each of the five transfer blocks. -*/ - -typedef struct { - ULONG ips_cl_size; /* client buffer size */ - ULONG ips_sv_size; /* server buffer size */ - ULONG ips_sv_alloced; /* server buffer size allocated */ - ULONG ips_cl_copied; /* client buffer copied so far */ - ULONG ips_sv_copied; /* server buffer copied so far */ - ULONG ips_com_offset; /* offset to comm buffer */ - ULONG ips_com_size; /* size of comm buffer */ - ULONG ips_com_curr; /* current mapped offset of comm buffer */ - ULONG ips_flags; /* flags */ - UCHAR *ips_cl_addr; /* address of client buffer */ - const UCHAR* ips_sv_addr; /* address of server buffer */ - UCHAR *ips_sv_buffer; /* allocated local buffer */ -} ips_string; - -const ULONG IPS_INPUT_BUFFER = 1; /* used for input from client */ -const ULONG IPS_OUTPUT_BUFFER = 2; /* used for output to client */ - - -/* - strucure used for attachments - - attach database - - attach service - - create database - - and for info calls - - blob info - - database info - - query service info - - request info - - sql request info - - transaction info - - and for simple controls of various objects - - cancel blob - - cancel events - - close blob - - commit transaction - - commit transaction (retaining) - - detach database - - detach service - - drop database - - dsql free statement - - prepare transaction - - release request - - rollback transaction - - unwind request -*/ - -typedef struct { - UCHAR *ips_handle; /* handle of object */ - ULONG ips_parameter; /* a parameter, used if needed */ -} ips_object; - -const USHORT IPS_ATTACH_NAME = 0; /* use controller 0 for db name */ -const USHORT IPS_ATTACH_DPB = 1; /* use controller 1 for dpb */ -const USHORT IPS_ATTACH_EXPANDED= 2; /* use controller 2 for exp name */ - -const USHORT IPS_CREATE_NAME = 0; /* use controller 0 for db name */ -const USHORT IPS_CREATE_DPB = 1; /* use controller 1 for dpb */ -const USHORT IPS_CREATE_EXPANDED= 2; /* use controller 2 for exp name */ - -const USHORT IPS_ATTACH_SVC_NAME= 0; /* use controller 0 for service name */ -const USHORT IPS_ATTACH_SVC_SPB = 1; /* use controller 1 for spb */ -const USHORT IPS_START_SVC_SPB = 2; /* use controller 2 for start spb */ - -const USHORT IPS_CLOSE_BLOB_REM = 0; /* use controller 0 for remainders */ - -const USHORT IPS_INFO_ITEMS = 0; /* use controller 0 for items */ -const USHORT IPS_INFO_DATA = 1; /* use controller 1 for data */ - -const USHORT IPS_QUERY_RECV_ITEMS = 2;/* use controller 2 for recv items */ - -const USHORT IPS_PREPARE_TRANS = 0; /* use controller 0 for string */ - - -/* structure used to compile requests */ - -typedef struct { - UCHAR *ips_db_handle; /* database handle */ - UCHAR *ips_rq_handle; /* returned request handle */ -} ips_compile_req; - -const USHORT IPS_COMPILE_REQ = 0; /* use controller 0 for blr */ - - -/* structure used by create/open blob (and create/open blob2) */ - -typedef struct { - UCHAR *ips_db_handle; /* database handle */ - UCHAR *ips_tr_handle; /* transaction handle */ - UCHAR *ips_bl_handle; /* returned blob handle */ - ULONG ips_rel_id; /* returned relation ID */ - ULONG ips_bid_number; /* returned blob ID number */ -} ips_blob; - -const USHORT IPS_BLOB_BPB = 0; /* use contorller 0 for bpb */ - - -/* structure used for DDL operations */ - -typedef struct { - UCHAR *ips_db_handle; /* database handle */ - UCHAR *ips_tr_handle; /* transaction handle */ -} ips_ddl; - -const USHORT IPS_DDL_DDL = 0; /* use controller 0 for ddl */ - - -/* - structure used for most DSQL operations - - allocate - - execute - - execute2 - - execute immediate - - execute immediate2 - - fetch - - insert - - prepare - - set cursor -*/ - -typedef struct { - UCHAR *ips_db_handle; /* database handle */ - UCHAR *ips_tr_handle; /* transaction handle (in/out) */ - UCHAR *ips_st_handle; /* statement handle */ - ULONG ips_parameter; /* sql dialect/fetch status/set cursor */ - USHORT ips_msg_type; /* message type */ - USHORT ips_msg_out; /* output message type */ - USHORT ips_rec_count; /* packed records count */ -} ips_dsql; - -const USHORT IPS_DSQL_EXEC_BLR = 0; /* use controller 0 for blr */ -const USHORT IPS_DSQL_EXEC_MSG = 1; /* use controller 1 for message */ - -const USHORT IPS_DSQL_EXEC2_BLR_IN = IPS_DSQL_EXEC_BLR; -const USHORT IPS_DSQL_EXEC2_MSG_IN = IPS_DSQL_EXEC_MSG; -const USHORT IPS_DSQL_EXEC2_BLR_OUT = 2; /* use controller 2 for output blr */ -const USHORT IPS_DSQL_EXEC2_MSG_OUT = 3; /* use controller 3 for output msg */ - -const USHORT IPS_DSQL_EXEC_IMMED_SQL = 0; /* use controller 0 for sql */ -const USHORT IPS_DSQL_EXEC_IMMED_BLR = 1; /* use controller 1 for blr */ -const USHORT IPS_DSQL_EXEC_IMMED_MSG = 2; /* use controller 2 for message */ - -const USHORT IPS_DSQL_EXEC_IMMED2_SQL = IPS_DSQL_EXEC_IMMED_SQL; -const USHORT IPS_DSQL_EXEC_IMMED2_BLR_IN = IPS_DSQL_EXEC_IMMED_BLR; -const USHORT IPS_DSQL_EXEC_IMMED2_MSG_IN = IPS_DSQL_EXEC_IMMED_MSG; -const USHORT IPS_DSQL_EXEC_IMMED2_BLR_OUT = 3; /* use controller 3 for output blr */ -const USHORT IPS_DSQL_EXEC_IMMED2_MSG_OUT = 4; /* use controller 4 for output msg */ - -const USHORT IPS_DSQL_FETCH_BLR = 0; /* use controller 0 for blr */ -const USHORT IPS_DSQL_FETCH_MSG = 1; /* use controller 1 for message */ - -const USHORT IPS_DSQL_INSERT_BLR = 0; /* use controller 0 for blr */ -const USHORT IPS_DSQL_INSERT_MSG = 1; /* use controller 1 for message */ - -const USHORT IPS_DSQL_PREP_STRING = 0; /* use controller 0 for string */ -const USHORT IPS_DSQL_PREP_ITEMS = 1; /* use controller 1 for items */ -const USHORT IPS_DSQL_PREP_BUFFER = 2; /* use controller 2 for buffer */ - -const USHORT IPS_DSQL_SET_CURSOR = 0; /* use controller 0 for name */ - - -/* structure used to get/put blob segments */ - -typedef struct { - UCHAR *ips_bl_handle; /* blob handle */ - USHORT ips_length; /* returned actual length */ -} ips_segment; - -const USHORT IPS_BLOB_SEGMENT = 0; /* use controller 0 for segment */ - - -/* structure used to get/put array slices */ - -typedef struct { - UCHAR *ips_db_handle; /* database handle */ - UCHAR *ips_tr_handle; /* transaction handle */ - ULONG ips_rel_id; /* array rel id */ - ULONG ips_number; /* array number */ - ULONG ips_length; /* returned actual length */ -} ips_slice; - -const USHORT IPS_SLICE_SDL = 0; /* use controller 0 for sdl */ -const USHORT IPS_SLICE_PARAM = 1; /* use controller 1 for parameters */ -const USHORT IPS_SLICE_BUFFER = 2; /* use controller 2 for slice */ - - -/* structure for queueing events */ - -typedef struct { - UCHAR *ips_db_handle; /* database handle */ - ULONG ips_event_id; /* returned event id */ - HWND ips_event_hwnd; /* window handle to return to */ - FPTR_EVENT_CALLBACK ips_ast; /* ast address */ - UCHAR* ips_arg; /* ast arg */ -} ips_que_events; - -const USHORT IPS_QUEUE_EVENT = 0; /* use controller 0 for event */ - - -/* structure for send/receive message */ - -typedef struct { - UCHAR *ips_tr_handle; /* transaction handle */ - UCHAR *ips_rq_handle; /* request handle */ - USHORT ips_msg_type; /* message type */ - USHORT ips_req_level; /* request level */ -#ifdef SCROLLABLE_CURSORS - USHORT ips_direction; /* direction */ - ULONG ips_offset; /* offset */ -#endif -} ips_request; - -const USHORT IPS_SEND_MESSAGE = 0; /* use controller 0 for message */ -const USHORT IPS_RECEIVE_MESSAGE = 0; /* use controller 0 for message */ - - -/* structure used to reconnect transaction */ - -typedef struct { - UCHAR *ips_db_handle; /* transaction handle */ - UCHAR *ips_tr_handle; /* transaction handle */ -} ips_reconnect; - -const USHORT IPS_RECONNECT_ID = 0; /* use controller 0 for id */ - - -/* structure used to seek into a blob */ - -typedef struct { - UCHAR *ips_bl_handle; /* blob handle */ - ULONG ips_offset; /* offset into blob */ - ULONG ips_result; /* returned result */ - USHORT ips_mode; /* seek mode */ -} ips_seek_blob; - - -/* structure used to start transactions */ - -typedef struct { - UCHAR *ips_tr_handle; /* returned transaction handle */ - USHORT ips_db_count; /* number of db's in transaction */ -} ips_start_trans; - - -/* structure used for transact request */ - -typedef struct { - UCHAR *ips_db_handle; /* database handle */ - UCHAR *ips_tr_handle; /* transaction handle (in/out) */ -} ips_transact_request; - -const USHORT IPS_TRANS_REQ_BLR = 0; /* use controller 0 for blr */ -const USHORT IPS_TRANS_REQ_IN_MSG = 1; /* use controller 1 for input msg */ -const USHORT IPS_TRANS_REQ_OUT_MSG = 2; /* use controller 2 for output msg */ - - -/* - This structure is mapped to the start of the allocated - communications area between the client and server. -*/ - -const USHORT MAX_IPS_STRINGS = 5; - -typedef struct { - ULONG ips_server_protocol; /* server's protocol level */ - ULONG ips_client_protocol; /* client's protocol level */ - ISC_STATUS_ARRAY ips_status; /* status vector */ - ips_string ips_buffers[MAX_IPS_STRINGS]; - /* array of buffer controllers */ - USHORT ips_ops_count; /* operations performed */ - USHORT ips_sequence; /* transfer sequence number */ - USHORT ips_operation; /* operation being performed */ - HANDLE ips_server_proc; /* server's process handle */ - HANDLE ips_client_proc; /* client's process handle */ - DWORD ips_server_id; /* server's process id */ - DWORD ips_client_id; /* client's process id */ - union { - ips_object ips_op_object; - ips_compile_req ips_op_compile; - ips_blob ips_op_blob; - ips_ddl ips_op_ddl; - ips_dsql ips_op_dsql; - ips_segment ips_op_segment; - ips_slice ips_op_slice; - ips_que_events ips_op_que_evnt; - ips_request ips_op_request; - ips_reconnect ips_op_recon_trans; - ips_seek_blob ips_op_sk_blob; - ips_start_trans ips_op_strt_trans; - ips_transact_request ips_op_trans_req; - } ips_operations; - ULONG ips_data[1]; /* start of data area */ -} ips_comm_area, *IPS; - -/* size of mapped memory for a given client */ - -//#define CLIENT_SERVER_AREA_SIZE 8192 - -/* size available for packing stuff in the mapped area */ - -//#define CLIENT_SERVER_AVAIL (CLIENT_SERVER_AREA_SIZE - sizeof(ips_comm_area)) - -/* Windows names used to identify various named objects */ - -static const char* IPI_MAPPED_FILE_NAME = "%sMappedArea%d"; -static const char* IPI_CLIENT_SEM_NAME = "%sClientSem%d_%d"; -static const char* IPI_SERVER_SEM_NAME = "%sServerSem%d_%d"; -static const char* IPI_EVENT_NAME = "%sEvent%d"; -static const char* IPI_EVENT_CLASS = "%sEventClass"; -static const char* IPI_EVENT_THREAD = "%sEventThread%d_%d"; - -/* local event queue structure */ - -typedef struct eventq { - struct eventq *evq_next; /* next event */ - SLONG evq_id; /* event ID */ - USHORT evq_length; /* event length */ - UCHAR evq_string[1]; /* event string */ -} *EVENTQ; - -/* interprocess database thread structure */ - -class tidb : public ThreadData -{ -public: - struct rdb *tidb_database; - ISC_STATUS *tidb_status_vector; - UCHAR *tidb_setjmp; -}; - -typedef tidb* TIDB; - - -/* bias for connect messages */ - -const ULONG IP_BIAS = 3333; - -#endif /* IPSERVER_IPC_H */ diff --git a/src/ipserver/ipcevent.cpp b/src/ipserver/ipcevent.cpp deleted file mode 100644 index a3a9e62159..0000000000 --- a/src/ipserver/ipcevent.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * PROGRAM: Interprocess Client - * MODULE: ipcevent.cpp - * DESCRIPTION: Interprocess interface event window initializer - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -#include "firebird.h" -#include - -#include "../ipserver/ipcli_proto.h" -#include "../ipserver/ipevt_proto.h" -#include "../ipserver/ips.h" - -// instance handle - -extern HINSTANCE hIBDLLInstance; - -// callback for event handling - -LRESULT CALLBACK IBEventWindowFunc(HWND, UINT, WPARAM, LPARAM); - - - -int IPC_window_init( - char *class_name, - char *task_name, HWND * event_window, HANDLE event_sem) -{ -/************************************** - * - * I P C _ w i n d o w _ i n i t - * - ************************************** - * - * Functional description - * Initialize the window used to process events. - * - **************************************/ - HWND hWnd; - WNDCLASS wcl; - DWORD result; - MSG msg; - - - wcl.hInstance = hIBDLLInstance; - wcl.lpszClassName = class_name; - wcl.lpfnWndProc = IBEventWindowFunc; - wcl.style = 0; - - wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wcl.hCursor = LoadCursor(NULL, IDC_ARROW); - wcl.lpszMenuName = NULL; - - wcl.cbClsExtra = 0; - wcl.cbWndExtra = 0; - - wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); - - if (!RegisterClass(&wcl)) { - result = GetLastError(); - return 0; - } - - hWnd = CreateWindow(class_name, - task_name, - WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | - WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, - hIBDLLInstance, NULL); - - ShowWindow(hWnd, SW_HIDE); - UpdateWindow(hWnd); - - // return handle and signal with semaphore - - *event_window = hWnd; - ReleaseSemaphore(event_sem, 1L, NULL); - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return msg.wParam; -} - - -LRESULT CALLBACK IBEventWindowFunc(HWND hWnd, - UINT message, WPARAM wParam, LPARAM lParam) -{ - COPYDATASTRUCT *cpdata; - - - switch (message) { - case WM_CLOSE: - DestroyWindow(hWnd); - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - case WM_COPYDATA: - cpdata = (COPYDATASTRUCT *) lParam; - IPC_process_event(cpdata->dwData, cpdata->cbData, cpdata->lpData); - break; - - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; -} diff --git a/src/ipserver/ipcli_proto.h b/src/ipserver/ipcli_proto.h deleted file mode 100644 index 79174d040c..0000000000 --- a/src/ipserver/ipcli_proto.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * PROGRAM: JRD Access Method - * MODULE: ipcli_proto.h - * DESCRIPTION: Prototype header file for ipclient.cpp - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - - -#ifndef IPCLI_PROTO_H -#define IPCLI_PROTO_H - -#ifdef __cplusplus -extern "C" { -#endif - -void IPC_process_event(DWORD, DWORD, LPVOID); -void IPC_release_all(void); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* IPCLI_PROTO_H */ - diff --git a/src/ipserver/ipclient.cpp b/src/ipserver/ipclient.cpp deleted file mode 100644 index f850fc289a..0000000000 --- a/src/ipserver/ipclient.cpp +++ /dev/null @@ -1,4728 +0,0 @@ -/* - * PROGRAM: Interprocess Client - * MODULE: ipclient.cpp - * DESCRIPTION: Interprocess interface - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - * - * 2002.10.29 Sean Leyne - Removed obsolete "Netware" port - * - */ - -#include "firebird.h" -#include -#include -#include "../jrd/common.h" -#include -#include -#include -#include -#include - -#include "../ipserver/ipc.h" -#include "gen/iberror.h" -#include "../jrd/license.h" -#include "../jrd/inf_pub.h" -#include "../jrd/gds_proto.h" -#include "../jrd/isc_proto.h" -#include "../jrd/db_alias.h" -#include "../ipserver/alli_proto.h" -#include "../ipserver/ipcli_proto.h" -#include "../ipserver/ipevt_proto.h" -#include "../ipserver/ipapi_proto.h" -#include "../ipserver/ips.h" -#include "../jrd/thd.h" -#include "../jrd/isc_proto.h" -#include "../jrd/isc_f_proto.h" -#include "../jrd/sch_proto.h" -#include "../jrd/thread_proto.h" -#include "../remote/os/win32/window.h" -#include "../common/config/config.h" - -#define statistics stat - -typedef void (*PTR) (); - -static ISC_STATUS check_response(ICC, ISC_STATUS *); -static void clear_statement_cache(IPSERVER_ISR); -static void clear_transaction_statements(ITR); -static THREAD_ENTRY_DECLARE event_packer(THREAD_ENTRY_PARAM); -static THREAD_ENTRY_DECLARE event_thread(THREAD_ENTRY_PARAM); -static void extract_status(ICC, ISC_STATUS *); -static ISC_STATUS handle_error(ISC_STATUS *, ISC_STATUS); -static SSHORT init(ISC_STATUS *, ICC *); -static ITR make_transaction(ISC_STATUS *, IDB, FB_API_HANDLE); -static SSHORT name_length(const TEXT*); -static bool pack_strings(ICC); -static void release_blob(IBL); -static void release_database(IDB); -static void release_event(IVNT); -static void release_request(IRQ); -static void release_sql_request(IPSERVER_ISR); -static void release_transaction(ITR); -static bool send_and_wait(ICC); -static void server_shutdown(void); -static THREAD_ENTRY_DECLARE server_watcher(THREAD_ENTRY_PARAM); -static bool unpack_strings(ICC); - - -#define RETURN_ERROR(e) { THD_mutex_unlock( &mapsect);\ - if ( icc != NULL) {\ - if ( icc->icc_flags & ICCF_UNMAP_CLIENT)\ - {\ - server_shutdown();\ - icc->icc_flags &= ~ICCF_UNMAP_CLIENT;\ - }\ - }\ - return e; } - -#define RETURN_SUCCESS RETURN_ERROR( FB_SUCCESS) - -#define CHECK_HANDLE(blk, type, error)\ - if ( !blk || ((BLK)blk)->blk_type != (SCHAR) type) \ - return handle_error( user_status, error) - -#define CHECK_HANDLE_REL(blk, type, error)\ - if ( !blk || ((BLK)blk)->blk_type != (SCHAR) type) \ - {\ - RETURN_ERROR( handle_error( user_status, error));\ - } - -#define NULL_CHECK(ptr, code) if (*ptr)\ - return handle_error( user_status, code) - -#define NOT_NULL(ptr) if (!ptr)\ - {\ - RETURN_ERROR( handle_error( user_status, isc_virmemexh));\ - } - -#define GET_OBJECT(obj) icc = (ICC)obj;\ - if ( icc->icc_thread_handle != GetCurrentThreadId() &&\ - event_icc)\ - icc = event_icc;\ - if ( icc->icc_flags & ICCF_SERVER_SHUTDOWN)\ - {\ - user_status[0] = isc_arg_gds;\ - user_status[1] = isc_lost_db_connection;\ - user_status[2] = isc_arg_end;\ - return user_status[1];\ - }\ - THD_mutex_lock( &mapsect);\ - comm = (ips_comm_area*)icc->icc_mapped_addr;\ - for ( commi = 0; commi < MAX_IPS_STRINGS; commi++)\ - comm->ips_buffers[commi].ips_flags = 0; - -// some macros to set up the strings - -#define IPS_CLIENT(c,p,n,a,s,f) { c->ips_buffers[n].ips_cl_size = s;\ - c->ips_buffers[n].ips_cl_addr = (UCHAR*)a;\ - c->ips_buffers[n].ips_cl_copied = 0;\ - c->ips_buffers[n].ips_flags = f;\ - p = &c->ips_buffers[n];} - -#define IPS_C_IN(c,p,n,a,s) IPS_CLIENT(c,p,n,a,s,IPS_INPUT_BUFFER) -#define IPS_C_OUT(c,p,n,a,s) IPS_CLIENT(c,p,n,a,s,IPS_OUTPUT_BUFFER) -#define IPS_C_IN_OUT(c,p,n,a,s) IPS_CLIENT(c,p,n,a,s,IPS_INPUT_BUFFER+IPS_OUTPUT_BUFFER) - -static TEXT error_text[1024]; -static ICC client_threads = NULL; -static IPM client_maps = NULL; -static MUTX_T clisect; -static MUTX_T evtsect; -static MUTX_T mapsect; -static LONG interlock = -1; -static bool initialized = false; -static SLONG eventID = 0; -static HANDLE event_semaphore = 0; -static HWND event_window = 0; -static ICC event_icc = NULL; -static HANDLE event_packer_handle = 0; -static HANDLE event_thread_handle = 0; -static EVENTQ event_head = NULL, event_tail = NULL; -static USHORT exit_flag = 0; -static USHORT pages_per_user = IPS_DEF_PAGES_PER_CLI; -static USHORT users_per_map = IPS_DEF_NUM_CLI; -static HANDLE server_watcher_handle = 0; -static HANDLE server_process_handle = 0; - - -#define GDS_ATTACH_DATABASE IPI_attach_database -#define GDS_BLOB_INFO IPI_blob_info -#define GDS_CANCEL_BLOB IPI_cancel_blob -#define GDS_CANCEL_EVENTS IPI_cancel_events -#define GDS_CLOSE_BLOB IPI_close_blob -#define GDS_COMMIT IPI_commit_transaction -#define GDS_COMMIT_RETAINING IPI_commit_retaining -#define GDS_COMPILE IPI_compile_request -#define GDS_CREATE_BLOB IPI_create_blob -#define GDS_CREATE_BLOB2 IPI_create_blob2 -#define GDS_CREATE_DATABASE IPI_create_database -#define GDS_DATABASE_INFO IPI_database_info -#define GDS_DDL IPI_ddl -#define GDS_DETACH IPI_detach_database -#define GDS_DROP_DATABASE IPI_drop_database -#define GDS_GET_SEGMENT IPI_get_segment -#define GDS_GET_SLICE IPI_get_slice -#define GDS_OPEN_BLOB IPI_open_blob -#define GDS_OPEN_BLOB2 IPI_open_blob2 -#define GDS_PREPARE IPI_prepare_transaction -#define GDS_PUT_SEGMENT IPI_put_segment -#define GDS_PUT_SLICE IPI_put_slice -#define GDS_QUE_EVENTS IPI_que_events -#define GDS_RECEIVE IPI_receive -#define GDS_RECONNECT IPI_reconnect_transaction -#define GDS_RELEASE_REQUEST IPI_release_request -#define GDS_REQUEST_INFO IPI_request_info -#define GDS_ROLLBACK IPI_rollback_transaction -#define GDS_ROLLBACK_RETAINING IPI_rollback_retaining -#define GDS_SEEK_BLOB IPI_seek_blob -#define GDS_SEND IPI_send -#define GDS_SERVICE_ATTACH IPI_service_attach -#define GDS_SERVICE_DETACH IPI_service_detach -#define GDS_SERVICE_QUERY IPI_service_query -#define GDS_SERVICE_START IPI_service_start -#define GDS_START IPI_start_request -#define GDS_START_AND_SEND IPI_start_and_send -#define GDS_START_MULTIPLE IPI_start_multiple -#define GDS_START_TRANSACTION IPI_start_transaction -#define GDS_TRANSACTION_INFO IPI_transaction_info -#define GDS_TRANSACT_REQUEST IPI_transact_request -#define GDS_UNWIND IPI_unwind_request - -#define GDS_DSQL_ALLOCATE IPI_allocate_statement -#define GDS_DSQL_EXECUTE IPI_execute -#define GDS_DSQL_EXECUTE2 IPI_execute2 -#define GDS_DSQL_EXECUTE_IMMED IPI_execute_immediate -#define GDS_DSQL_EXECUTE_IMMED2 IPI_execute_immediate2 -#define GDS_DSQL_FETCH IPI_fetch -#define GDS_DSQL_FREE IPI_free_statement -#define GDS_DSQL_INSERT IPI_insert -#define GDS_DSQL_PREPARE IPI_prepare -#define GDS_DSQL_SET_CURSOR IPI_set_cursor_name -#define GDS_DSQL_SQL_INFO IPI_sql_info - - -ISC_STATUS GDS_ATTACH_DATABASE( - ISC_STATUS* user_status, - USHORT file_length, - const SCHAR* file_name, - IDB* handle, - USHORT dpb_length, - const SCHAR* dpb, - const SCHAR* expanded_filename) -{ -/************************************** - * - * g d s _ a t t a c h _ d a t a b a s e - * - ************************************** - * - * Functional description - * Attach to an existing database via the interprocess - * interface to the local server. - * - **************************************/ - IDB idb; - ICC icc; - SSHORT l; - ips_object *ips; - ips_string *ips_name; - ips_string *ips_dpb; - ips_string *ips_expanded; - ips_comm_area *comm; - USHORT commi; - - - /* make sure handle is valid (should be null coming in) */ - - NULL_CHECK(handle, isc_bad_db_handle); - if (!(l = file_length)) - l = strlen(file_name); - - // remote names should not go through here - - if (ISC_check_if_remote(expanded_filename, true)) { - user_status[0] = isc_arg_gds; - user_status[1] = isc_unavailable; - user_status[2] = isc_arg_end; - return user_status[1]; - } - - // call init to initiate connection - - if (!init(user_status, &icc)) - return user_status[1]; - - // set up communications area - - THD_mutex_lock(&mapsect); - comm = (ips_comm_area *) icc->icc_mapped_addr; - for (commi = 0; commi < MAX_IPS_STRINGS; commi++) - comm->ips_buffers[commi].ips_flags = 0; - comm->ips_operation = op_attach; - ips = &comm->ips_operations.ips_op_object; - Firebird::PathName temp; - if (ResolveDatabaseAlias(file_name, temp)) { - IPS_C_IN(comm, ips_name, IPS_ATTACH_NAME, file_name, l); - } - else { - IPS_C_IN(comm, ips_name, IPS_ATTACH_NAME, - expanded_filename, strlen(expanded_filename)); - } - IPS_C_IN(comm, ips_dpb, IPS_ATTACH_DPB, dpb, dpb_length); - IPS_C_IN(comm, ips_expanded, IPS_ATTACH_EXPANDED, - expanded_filename, strlen(expanded_filename)); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // allocate a database structure and link it to thread - - idb = (IDB) ALLOC(type_idb); - *handle = idb; - NOT_NULL(idb); - idb->idb_flags = IDBF_DATABASE_ATTACHMENT; - idb->idb_next = icc->icc_databases; - idb->idb_thread = icc; - icc->icc_databases = idb; - idb->idb_handle = (FB_API_HANDLE) (ips->ips_handle); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_BLOB_INFO(ISC_STATUS* user_status, - IBL* blob, - USHORT item_length, - const UCHAR* items, - USHORT buffer_length, UCHAR* buffer) -{ -/************************************** - * - * g d s _ b l o b _ i n f o - * - ************************************** - * - * Functional description - * Provide information on blob object. - * - **************************************/ - IDB idb; - ips_object *ips; - ips_string *ips_items; - ips_string *ips_data; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - CHECK_HANDLE((*blob), type_ibl, isc_bad_segstr_handle); - idb = (*blob)->ibl_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // set up communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_info_blob; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) ((*blob)->ibl_handle); - IPS_C_IN(comm, ips_items, IPS_INFO_ITEMS, items, item_length); - IPS_C_OUT(comm, ips_data, IPS_INFO_DATA, buffer, buffer_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_CANCEL_BLOB(ISC_STATUS * user_status, IBL * blob_handle) -{ -/************************************** - * - * g d s _ c a n c e l _ b l o b - * - ************************************** - * - * Functional description - * Abort a partially completed blob. - * - **************************************/ - IDB idb; - IBL blob; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - blob = *blob_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - idb = blob->ibl_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // if blob handle is null, we're done - - blob = *blob_handle; - if (!blob) { - *user_status++ = isc_arg_gds; - *user_status++ = FB_SUCCESS; - *user_status = isc_arg_end; - return FB_SUCCESS; - } - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_cancel_blob; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (blob->ibl_handle); - - // free object - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - release_blob(blob); - *blob_handle = NULL; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_CANCEL_EVENTS(ISC_STATUS * user_status, IDB * handle, SLONG * id) -{ -/************************************** - * - * g d s _ c a n c e l _ e v e n t s - * - ************************************** - * - * Functional description - * Try to cancel an event. - * - **************************************/ - IDB idb; - IVNT event; - ISC_STATUS result; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handle - - idb = *handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_cancel_events; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (idb->idb_handle); - ips->ips_parameter = (ULONG) (*id); - - // send request and get response - - result = check_response(icc, user_status); - - // find and neutralize event - - for (event = idb->idb_events; event; event = event->ivnt_next) - if (event->ivnt_handle == *id) - break; - if (event) - event->ivnt_id = 0; - - // send response - - if (result) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_CLOSE_BLOB(ISC_STATUS * user_status, IBL * blob_handle) -{ -/************************************** - * - * g d s _ c l o s e _ b l o b - * - ************************************** - * - * Functional description - * Abort a partially completed blob. - * - **************************************/ - IDB idb; - IBL blob; - ips_object *ips; - ips_string *ips_seg; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - blob = *blob_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - idb = blob->ibl_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_close_blob; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (blob->ibl_handle); - - // send any unsent portion of the blob - - if ((blob->ibl_flags & IBL_create) && blob->ibl_ptr != blob->ibl_buffer) { - IPS_C_IN(comm, ips_seg, IPS_CLOSE_BLOB_REM, blob->ibl_buffer, - (blob->ibl_ptr - blob->ibl_buffer)); - } - - // send request, release blob object and resources - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - release_blob(blob); - *blob_handle = NULL; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_COMMIT(ISC_STATUS * user_status, ITR * itr_handle) -{ -/************************************** - * - * g d s _ c o m m i t - * - ************************************** - * - * Functional description - * Commit a transaction. - * - **************************************/ - IDB idb; - ITR transaction; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - idb = (*itr_handle)->itr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_commit; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (transaction->itr_handle); - - // send request, release object and resources - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - clear_transaction_statements(transaction); - release_transaction(transaction); - *itr_handle = NULL; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_COMMIT_RETAINING(ISC_STATUS * user_status, ITR * itr_handle) -{ -/************************************** - * - * g d s _ c o m m i t _ r e t a i n i n g - * - ************************************** - * - * Functional description - * Prepare a transaction for commit. First phase of a two - * phase commit. - * - **************************************/ - IDB idb; - ITR transaction; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - idb = (*itr_handle)->itr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_commit_retaining; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (transaction->itr_handle); - - // send request - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_COMPILE(ISC_STATUS* user_status, - IDB* db_handle, - IRQ* req_handle, USHORT blr_length, const UCHAR* blr) -{ -/************************************** - * - * g d s _ c o m p i l e - * - ************************************** - * - * Functional description - * - **************************************/ - IDB idb; - IRQ request; - ips_compile_req *ips; - ips_string *ips_blr; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - NULL_CHECK(req_handle, isc_bad_req_handle); - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_compile; - ips = &comm->ips_operations.ips_op_compile; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - IPS_C_IN(comm, ips_blr, IPS_COMPILE_REQ, blr, blr_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // allocate request block - - request = (IRQ) ALLOC(type_irq); - *req_handle = request; - NOT_NULL(request); - request->irq_handle = (FB_API_HANDLE) ips->ips_rq_handle; - request->irq_idb = idb; - request->irq_next = idb->idb_requests; - idb->idb_requests = request; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_CREATE_BLOB(ISC_STATUS * user_status, - IDB * db_handle, - ITR * itr_handle, IBL * blob_handle, BID blob_id) -{ -/************************************** - * - * g d s _ c r e a t e _ b l o b - * - ************************************** - * - * Functional description - * Create a brand new blob. - * - **************************************/ - IDB idb; - ITR transaction; - IBL blob; - ips_blob *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - NULL_CHECK(blob_handle, isc_bad_segstr_handle); - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_create_blob; - ips = &comm->ips_operations.ips_op_blob; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // allocate and fill blob object - - blob = (IBL) ALLOCV(type_ibl, BLOB_LENGTH); - *blob_handle = blob; - NOT_NULL(blob); - blob->ibl_handle = (FB_API_HANDLE) ips->ips_bl_handle; - blob->ibl_buffer_length = BLOB_LENGTH; - blob->ibl_idb = idb; - blob->ibl_itr = transaction; - blob->ibl_ptr = blob->ibl_buffer; - blob->ibl_flags |= IBL_create; - blob->ibl_next = transaction->itr_blobs; - transaction->itr_blobs = blob; - blob_id->bid_relation_id = ips->ips_rel_id; - blob_id->bid_number = ips->ips_bid_number; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_CREATE_BLOB2(ISC_STATUS* user_status, - IDB* db_handle, - ITR* itr_handle, - IBL* blob_handle, - BID blob_id, USHORT bpb_length, const UCHAR* bpb) -{ -/************************************** - * - * g d s _ c r e a t e _ b l o b 2 - * - ************************************** - * - * Functional description - * Create a brand new blob. - * - **************************************/ - IDB idb; - ITR transaction; - IBL blob; - ips_blob *ips; - ips_string *ips_bpb; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - NULL_CHECK(blob_handle, isc_bad_segstr_handle); - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_create_blob2; - ips = &comm->ips_operations.ips_op_blob; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - IPS_C_IN(comm, ips_bpb, IPS_BLOB_BPB, bpb, bpb_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // allocate and fill blob object - - blob = (IBL) ALLOCV(type_ibl, BLOB_LENGTH); - *blob_handle = blob; - NOT_NULL(blob); - blob->ibl_handle = (FB_API_HANDLE) ips->ips_bl_handle; - blob->ibl_buffer_length = BLOB_LENGTH; - blob->ibl_idb = idb; - blob->ibl_itr = transaction; - blob->ibl_ptr = blob->ibl_buffer; - blob->ibl_flags |= IBL_create; - blob->ibl_next = transaction->itr_blobs; - transaction->itr_blobs = blob; - blob_id->bid_relation_id = ips->ips_rel_id; - blob_id->bid_number = ips->ips_bid_number; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, - USHORT file_length, - const SCHAR* file_name, - IDB* handle, - USHORT dpb_length, - const SCHAR* dpb, - SSHORT db_type, - const SCHAR* expanded_filename) -{ -/************************************** - * - * g d s _ c r e a t e _ d a t a b a s e - * - ************************************** - * - * Functional description - * Create a database. - * - **************************************/ - IDB idb; - ICC icc; - USHORT l; - ips_object *ips; - ips_string *ips_name; - ips_string *ips_dpb; - ips_string *ips_expanded; - ips_comm_area *comm; - USHORT commi; - - - // handle must be null coming in - - NULL_CHECK(handle, isc_bad_db_handle); - if (!(l = file_length)) - l = strlen(file_name); - - // remote names should not go through here - - if (ISC_check_if_remote(expanded_filename, true)) { - user_status[0] = isc_arg_gds; - user_status[1] = isc_unavailable; - user_status[2] = isc_arg_end; - return user_status[1]; - } - - // initiate a connection - - if (!init(user_status, &icc)) - return user_status[1]; - - // point to communications area - - GET_OBJECT(icc); - comm->ips_operation = op_create; - ips = &comm->ips_operations.ips_op_object; - Firebird::PathName temp; - if (ResolveDatabaseAlias(file_name, temp)) { - IPS_C_IN(comm, ips_name, IPS_CREATE_NAME, file_name, l); - } - else { - IPS_C_IN(comm, ips_name, IPS_CREATE_NAME, - expanded_filename, strlen(expanded_filename)); - } - IPS_C_IN(comm, ips_dpb, IPS_CREATE_DPB, dpb, dpb_length); - IPS_C_IN(comm, ips_expanded, IPS_CREATE_EXPANDED, - expanded_filename, strlen(expanded_filename)); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // allocate a database structure and link it to thread - - idb = (IDB) ALLOC(type_idb); - *handle = idb; - NOT_NULL(idb); - idb->idb_flags = IDBF_DATABASE_ATTACHMENT; - idb->idb_next = icc->icc_databases; - idb->idb_thread = icc; - icc->icc_databases = idb; - idb->idb_handle = (FB_API_HANDLE) (ips->ips_handle); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DATABASE_INFO(ISC_STATUS* user_status, - IDB* handle, - USHORT item_length, - const UCHAR* items, - USHORT buffer_length, UCHAR* buffer) -{ -/************************************** - * - * g d s _ d a t a b a s e _ i n f o - * - ************************************** - * - * Functional description - * Provide information on database object. - * - **************************************/ - IDB idb; - ips_object *ips; - ips_string *ips_items; - ips_string *ips_data; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handle - - idb = *handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_info_database; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (idb->idb_handle); - IPS_C_IN(comm, ips_items, IPS_INFO_ITEMS, items, item_length); - IPS_C_OUT(comm, ips_data, IPS_INFO_DATA, buffer, buffer_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DDL(ISC_STATUS* user_status, - IDB* db_handle, - ITR* itr_handle, USHORT length, const UCHAR* msg) -{ -/************************************** - * - * g d s _ d d l - * - ************************************** - * - * Functional description - * Pump thru a DDL call. - * - **************************************/ - ITR transaction; - IDB idb; - ips_ddl *ips; - ips_string *ips_ddl_string; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_ddl; - ips = &comm->ips_operations.ips_op_ddl; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - IPS_C_IN(comm, ips_ddl_string, IPS_DDL_DDL, msg, length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DETACH(ISC_STATUS * user_status, IDB * handle) -{ -/************************************** - * - * g d s _ d e t a c h - * - ************************************** - * - * Functional description - * Close down a database. - * - **************************************/ - ICC icc; - IDB idb; - IRQ irq; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - - - // verify handle - - idb = *handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - icc = idb->idb_thread; - THD_mutex_lock(&mapsect); - if (icc->icc_flags & ICCF_SERVER_SHUTDOWN) { - - // if server was shut down, set up vector - - user_status[0] = isc_arg_gds; - user_status[1] = FB_SUCCESS; - user_status[2] = isc_arg_end; - } - else { - comm = (ips_comm_area *) icc->icc_mapped_addr; - for (commi = 0; commi < MAX_IPS_STRINGS; commi++) - comm->ips_buffers[commi].ips_flags = 0; - comm->ips_operation = op_detach; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (idb->idb_handle); - - // send request and release object - - if (check_response(icc, user_status)) - if (user_status[1] != isc_lost_db_connection) - RETURN_ERROR(user_status[1]); - } - - /* release any event, request, sql request or transaction objects for this - database, and then free the data structure (events are protected by - a critical region to make sure there's no event trigger in progress) */ - - THD_mutex_lock(&clisect); - while (idb->idb_events) - release_event(idb->idb_events); - THD_mutex_unlock(&clisect); - while (irq = idb->idb_requests) { - if (irq->irq_user_handle) - *(irq->irq_user_handle) = NULL; - release_request(irq); - } - while (idb->idb_sql_requests) - release_sql_request(idb->idb_sql_requests); - while (idb->idb_transactions) - release_transaction(idb->idb_transactions); - release_database(idb); - *handle = NULL; - /* - icc is already freed as a part of idb and the - necessary cleanup thro server_shutdown has occured. - */ - icc = NULL; - if (user_status[1]) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DROP_DATABASE(ISC_STATUS * user_status, IDB * handle) -{ -/************************************** - * - * i s c _ d r o p _ d a t a b a s e - * - ************************************** - * - * Functional description - * Close down and purge a database. - * - **************************************/ - IDB idb; - IRQ irq; - ISC_STATUS code; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handle - - idb = *handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_drop_database; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (idb->idb_handle); - - // send request and release handle - - code = check_response(icc, user_status); - if (code && (code != isc_drdb_completed_with_errs)) - RETURN_ERROR(user_status[1]); - - /* release any event, request, sql request or transaction objects for this - database, and then free the data structure (events are protected by - a critical region to make sure there's no event trigger in progress) */ - - THD_mutex_lock(&clisect); - while (idb->idb_events) - release_event(idb->idb_events); - THD_mutex_unlock(&clisect); - while (irq = idb->idb_requests) { - if (irq->irq_user_handle) - *(irq->irq_user_handle) = NULL; - release_request(irq); - } - while (idb->idb_sql_requests) - release_sql_request(idb->idb_sql_requests); - while (idb->idb_transactions) - release_transaction(idb->idb_transactions); - release_database(idb); - *handle = NULL; - if (code) - RETURN_ERROR(code); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_ALLOCATE(ISC_STATUS * user_status, - IDB * db_handle, IPSERVER_ISR * stmt_handle) -{ -/************************************** - * - * d s q l _ a l l o c a t e _ s t a t e m e n t - * - ************************************** - * - * Functional description - * Allocate a statement handle. - * - **************************************/ - IDB idb; - IPSERVER_ISR statement; - ips_dsql *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - NULL_CHECK(stmt_handle, isc_bad_req_handle); - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_allocate_stmt; - ips = &comm->ips_operations.ips_op_dsql; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // allocate and fill SQL request block - - statement = (IPSERVER_ISR) ALLOC(type_ipserver_isr); - *stmt_handle = statement; - NOT_NULL(statement); - statement->isr_handle = (FB_API_HANDLE) ips->ips_st_handle; - statement->isr_idb = idb; - statement->isr_next = idb->idb_sql_requests; - statement->isr_batch_flag = 0; - statement->isr_rec_count = 0; - statement->isr_max_recs = 0; - statement->isr_eof_flag = FALSE; - statement->isr_packed = NULL; - idb->idb_sql_requests = statement; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_EXECUTE(ISC_STATUS * user_status, - ITR * itr_handle, - IPSERVER_ISR * stmt_handle, - USHORT blr_length, - UCHAR * blr, - USHORT msg_type, USHORT msg_length, UCHAR * msg) -{ -/************************************** - * - * d s q l _ e x e c u t e - * - ************************************** - * - * Functional description - * Execute a dynamic SQL statement. - * - **************************************/ - IDB idb; - ITR transaction; - IPSERVER_ISR statement; - FB_API_HANDLE handle; - ips_dsql *ips; - ips_string *ips_blr; - ips_string *ips_msg; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - if (transaction = *itr_handle) - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - statement = *stmt_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_req_handle); - idb = statement->isr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_execute; - ips = &comm->ips_operations.ips_op_dsql; - if (transaction) - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - else - ips->ips_tr_handle = NULL; - ips->ips_st_handle = (UCHAR *) (statement->isr_handle); - ips->ips_msg_type = msg_type; - IPS_C_IN(comm, ips_blr, IPS_DSQL_EXEC_BLR, blr, blr_length); - IPS_C_IN(comm, ips_msg, IPS_DSQL_EXEC_MSG, msg, msg_length); - - // send request and wait for response - - check_response(icc, user_status); - - // take care of transactions - - handle = (FB_API_HANDLE) ips->ips_tr_handle; - if (transaction && !handle) { - release_transaction(transaction); - *itr_handle = NULL; - } - else if (!transaction && handle) - *itr_handle = make_transaction(user_status, idb, handle); - if (user_status[1]) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_EXECUTE2(ISC_STATUS * user_status, - ITR * itr_handle, - IPSERVER_ISR * stmt_handle, - USHORT in_blr_length, - UCHAR * in_blr, - USHORT in_msg_type, - USHORT in_msg_length, - UCHAR * in_msg, - USHORT out_blr_length, - UCHAR * out_blr, - USHORT out_msg_type, - USHORT out_msg_length, UCHAR * out_msg) -{ -/************************************** - * - * d s q l _ e x e c u t e 2 - * - ************************************** - * - * Functional description - * Execute a dynamic SQL statement. - * - **************************************/ - IDB idb; - ITR transaction; - IPSERVER_ISR statement; - FB_API_HANDLE handle; - ips_dsql *ips; - ips_string *ips_blr_in; - ips_string *ips_blr_out; - ips_string *ips_msg_in; - ips_string *ips_msg_out; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - if (transaction = *itr_handle) - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - statement = *stmt_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_req_handle); - idb = statement->isr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_execute2; - ips = &comm->ips_operations.ips_op_dsql; - if (transaction) - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - else - ips->ips_tr_handle = NULL; - ips->ips_st_handle = (UCHAR *) (statement->isr_handle); - ips->ips_msg_type = in_msg_type; - ips->ips_msg_out = out_msg_type; - IPS_C_IN(comm, ips_blr_in, IPS_DSQL_EXEC2_BLR_IN, in_blr, in_blr_length); - IPS_C_IN(comm, ips_blr_out, IPS_DSQL_EXEC2_BLR_OUT, out_blr, - out_blr_length); - IPS_C_IN(comm, ips_msg_in, IPS_DSQL_EXEC2_MSG_IN, in_msg, in_msg_length); - IPS_C_OUT(comm, ips_msg_out, IPS_DSQL_EXEC2_MSG_OUT, out_msg, - out_msg_length); - - // send request and wait for response - - check_response(icc, user_status); - - // take care of transactions - - handle = (FB_API_HANDLE) ips->ips_tr_handle; - if (transaction && !handle) { - release_transaction(transaction); - *itr_handle = NULL; - } - else if (!transaction && handle) - *itr_handle = make_transaction(user_status, idb, handle); - statement->isr_itr = *itr_handle; - if (user_status[1]) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_EXECUTE_IMMED(ISC_STATUS* user_status, - IDB* db_handle, - ITR* itr_handle, - USHORT length, - const UCHAR* string, - USHORT dialect, - USHORT blr_length, - const UCHAR* blr, - USHORT msg_type, USHORT msg_length, UCHAR* msg) -{ -/************************************** - * - * d s q l _ e x e c u t e _ i m m e d i a t e - * - ************************************** - * - * Functional description - * Prepare and execute a statement. - * - **************************************/ - IDB idb; - ITR transaction; - FB_API_HANDLE handle; - ips_dsql *ips; - ips_string *ips_blr; - ips_string *ips_msg; - ips_string *ips_sql; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - if (transaction = *itr_handle) - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - if (!length) - length = strlen(reinterpret_cast(string)); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_exec_immediate; - ips = &comm->ips_operations.ips_op_dsql; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - if (transaction) - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - else - ips->ips_tr_handle = NULL; - ips->ips_msg_type = msg_type; - ips->ips_parameter = dialect; - IPS_C_IN(comm, ips_blr, IPS_DSQL_EXEC_IMMED_BLR, blr, blr_length); - IPS_C_IN(comm, ips_msg, IPS_DSQL_EXEC_IMMED_MSG, msg, msg_length); - IPS_C_IN(comm, ips_sql, IPS_DSQL_EXEC_IMMED_SQL, string, length); - - // send request and get response - - check_response(icc, user_status); - - // take care of transacion handles - - handle = (FB_API_HANDLE) ips->ips_tr_handle; - if (transaction && !handle) { - release_transaction(transaction); - *itr_handle = NULL; - } - else if (!transaction && handle) - *itr_handle = make_transaction(user_status, idb, handle); - if (user_status[1]) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_EXECUTE_IMMED2(ISC_STATUS* user_status, - IDB* db_handle, - ITR* itr_handle, - USHORT length, - const UCHAR* string, - USHORT dialect, - USHORT in_blr_length, - const UCHAR* in_blr, - USHORT in_msg_type, - USHORT in_msg_length, - UCHAR* in_msg, - USHORT out_blr_length, - UCHAR* out_blr, - USHORT out_msg_type, - USHORT out_msg_length, UCHAR* out_msg) -{ -/************************************** - * - * d s q l _ e x e c u t e _ i m m e d i a t e 2 - * - ************************************** - * - * Functional description - * Prepare and execute a statement. - * - **************************************/ - IDB idb; - ITR transaction; - FB_API_HANDLE handle; - ips_dsql *ips; - ips_string *ips_blr_in; - ips_string *ips_msg_in; - ips_string *ips_blr_out; - ips_string *ips_msg_out; - ips_string *ips_sql; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - if (transaction = *itr_handle) - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - if (!length) - length = strlen(reinterpret_cast(string)); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_exec_immediate2; - ips = &comm->ips_operations.ips_op_dsql; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - if (transaction) - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - else - ips->ips_tr_handle = NULL; - ips->ips_msg_type = in_msg_type; - ips->ips_msg_out = out_msg_type; - ips->ips_parameter = dialect; - IPS_C_IN(comm, ips_sql, IPS_DSQL_EXEC_IMMED2_SQL, string, length); - IPS_C_IN(comm, ips_blr_in, IPS_DSQL_EXEC_IMMED2_BLR_IN, in_blr, - in_blr_length); - IPS_C_IN(comm, ips_msg_in, IPS_DSQL_EXEC_IMMED2_MSG_IN, in_msg, - in_msg_length); - IPS_C_IN(comm, ips_blr_out, IPS_DSQL_EXEC_IMMED2_BLR_OUT, out_blr, - out_blr_length); - IPS_C_OUT(comm, ips_msg_out, IPS_DSQL_EXEC_IMMED2_MSG_OUT, out_msg, - out_msg_length); - - // send request and get answer - - check_response(icc, user_status); - - // handle transactions - - handle = (FB_API_HANDLE) ips->ips_tr_handle; - if (transaction && !handle) { - release_transaction(transaction); - *itr_handle = NULL; - } - else if (!transaction && handle) - *itr_handle = make_transaction(user_status, idb, handle); - if (user_status[1]) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_FETCH(ISC_STATUS* user_status, - IPSERVER_ISR* stmt_handle, - USHORT blr_length, - const UCHAR* blr, - USHORT msg_type, USHORT msg_length, UCHAR* msg) -{ -/************************************** - * - * d s q l _ f e t c h - * - ************************************** - * - * Functional description - * Fetch next record from a dynamic SQL cursor. - * - **************************************/ - IDB idb; - IPSERVER_ISR statement; - USHORT packed_length; - UCHAR *packed_buffer; - USHORT i; - ips_dsql *ips; - ips_string *ips_blr; - ips_string *ips_msg; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - statement = *stmt_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_req_handle); - idb = statement->isr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - icc = idb->idb_thread; - - // check for connection lost - - if (icc->icc_flags & ICCF_SERVER_SHUTDOWN) { - user_status[0] = isc_arg_gds; - user_status[1] = isc_lost_db_connection; - user_status[2] = isc_arg_end; - return user_status[1]; - } - - // calculate how many records to pack - - THD_mutex_lock(&mapsect); - if (!statement->isr_max_recs) { - statement->isr_max_recs = - (USHORT) (IPS_USEFUL_SPACE(pages_per_user) / msg_length); - if (!statement->isr_max_recs || !statement->isr_batch_flag) - statement->isr_max_recs = 1; - else { - statement->isr_packed = - (UCHAR *) ALLI_alloc(msg_length * statement->isr_max_recs); - NOT_NULL(statement->isr_packed); - statement->isr_rec_count = 0; - statement->isr_cursor = statement->isr_packed; - } - } - - // if there are any packed records, return the next one - - user_status[0] = isc_arg_gds; - user_status[1] = FB_SUCCESS; - user_status[2] = isc_arg_end; - if (statement->isr_max_recs > 1) { - if (statement->isr_rec_count) { - memcpy(msg, statement->isr_cursor, msg_length); - statement->isr_rec_count--; - statement->isr_cursor += msg_length; - RETURN_SUCCESS; - } - else if (statement->isr_eof_flag) { - statement->isr_eof_flag = FALSE; - RETURN_ERROR(100); - } - else if (statement->isr_status[1]) { - for (i = 0; i < ISC_STATUS_LENGTH && statement->isr_status[i]; - i++) { - user_status[i] = statement->isr_status[i]; - statement->isr_status[i] = 0; - } - - RETURN_ERROR(user_status[1]); - } - } - THD_mutex_unlock(&mapsect); - - // either there's no packing, or there's no more packed records - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_fetch; - ips = &comm->ips_operations.ips_op_dsql; - ips->ips_st_handle = (UCHAR *) (statement->isr_handle); - ips->ips_msg_type = msg_type; - packed_length = msg_length * statement->isr_max_recs; - if (statement->isr_max_recs == 1) - packed_buffer = msg; - else - packed_buffer = statement->isr_packed; - IPS_C_IN(comm, ips_blr, IPS_DSQL_FETCH_BLR, blr, blr_length); - IPS_C_OUT(comm, ips_msg, IPS_DSQL_FETCH_MSG, packed_buffer, - packed_length); - ips->ips_rec_count = statement->isr_max_recs; - - // send request and get response - - check_response(icc, user_status); - - // for packed records, extract the first - - statement->isr_rec_count = ips->ips_rec_count; - if (statement->isr_max_recs > 1 && statement->isr_rec_count) { - - // get first record and save status vector - - statement->isr_cursor = statement->isr_packed; - memcpy(msg, statement->isr_cursor, msg_length); - statement->isr_cursor += msg_length; - for (i = 0; i < ISC_STATUS_LENGTH; i++) - statement->isr_status[i] = user_status[i]; - if (ips->ips_parameter == 100) - statement->isr_eof_flag = TRUE; - else - statement->isr_eof_flag = FALSE; - ips->ips_parameter = 0; - - // if there are more records, fake good return - - if (statement->isr_rec_count) { - user_status[0] = isc_arg_gds; - user_status[1] = FB_SUCCESS; - user_status[2] = isc_arg_end; - } - statement->isr_rec_count--; - } - if (ips->ips_parameter == 100) - RETURN_ERROR(100); - if (user_status[1]) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_FREE(ISC_STATUS * user_status, - IPSERVER_ISR * stmt_handle, USHORT option) -{ -/************************************** - * - * d s q l _ f r e e _ s t a t e m e n t - * - ************************************** - * - * Functional description - * Release request for a Dynamic SQL statement - * - **************************************/ - IDB idb; - IPSERVER_ISR statement; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - statement = *stmt_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_req_handle); - idb = statement->isr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_free_stmt; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (statement->isr_handle); - ips->ips_parameter = (ULONG) option; - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // free statement resources - - statement->isr_handle = (FB_API_HANDLE) ips->ips_handle; - if (!statement->isr_handle) { - release_sql_request(statement); - *stmt_handle = NULL; - } - else { - statement->isr_itr = NULL; - clear_statement_cache(statement); - } - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_INSERT(ISC_STATUS * user_status, - IPSERVER_ISR * stmt_handle, - USHORT blr_length, - UCHAR * blr, - USHORT msg_type, USHORT msg_length, UCHAR * msg) -{ -/************************************** - * - * d s q l _ i n s e r t - * - ************************************** - * - * Functional description - * Insert next record into a dynamic SQL cursor. - * - **************************************/ - IDB idb; - IPSERVER_ISR statement; - ips_dsql *ips; - ips_string *ips_blr; - ips_string *ips_msg; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - statement = *stmt_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_req_handle); - idb = statement->isr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_insert; - ips = &comm->ips_operations.ips_op_dsql; - ips->ips_st_handle = (UCHAR *) (statement->isr_handle); - ips->ips_msg_type = msg_type; - IPS_C_IN(comm, ips_blr, IPS_DSQL_INSERT_BLR, blr, blr_length); - IPS_C_IN(comm, ips_msg, IPS_DSQL_INSERT_MSG, msg, msg_length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_PREPARE(ISC_STATUS * user_status, - ITR * itr_handle, - IPSERVER_ISR * stmt_handle, - USHORT length, - UCHAR * string, - USHORT dialect, - USHORT item_length, - UCHAR * items, USHORT buffer_length, UCHAR * buffer) -{ -/************************************** - * - * d s q l _ p r e p a r e - * - ************************************** - * - * Functional description - * Prepare a dynamic SQL statement for execution. - * - **************************************/ - IDB idb; - ITR transaction; - IPSERVER_ISR statement; - ips_dsql *ips; - ips_string *ips_prep_string; - ips_string *ips_prep_items; - ips_string *ips_prep_buffer; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - statement = *stmt_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_req_handle); - idb = statement->isr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - if (transaction = *itr_handle) - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - if (!length) - length = strlen(reinterpret_cast < char *>(string)); - if (statement->isr_packed) - ALLI_free((UCHAR *) statement->isr_packed); - statement->isr_max_recs = 0; - statement->isr_eof_flag = FALSE; - statement->isr_packed = NULL; - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_prepare_stmt; - ips = &comm->ips_operations.ips_op_dsql; - if (transaction) - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - else - ips->ips_tr_handle = NULL; - ips->ips_st_handle = (UCHAR *) (statement->isr_handle); - ips->ips_parameter = dialect; - IPS_C_IN(comm, ips_prep_string, IPS_DSQL_PREP_STRING, string, length); - IPS_C_IN(comm, ips_prep_items, IPS_DSQL_PREP_ITEMS, items, item_length); - IPS_C_OUT(comm, ips_prep_buffer, IPS_DSQL_PREP_BUFFER, buffer, - buffer_length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - statement->isr_batch_flag = (USHORT) ips->ips_parameter; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_SET_CURSOR(ISC_STATUS* user_status, - IPSERVER_ISR* stmt_handle, - const UCHAR* cursor, USHORT type) -{ -/***************************************** - * - * d s q l _ s e t _ c u r s o r - * - ***************************************** - * - * Functional Description - * Set a cursor name for a dynamic request. - * - *****************************************/ - IDB idb; - IPSERVER_ISR statement; - USHORT cursor_length; - ips_dsql *ips; - ips_string *ips_name; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - statement = *stmt_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_req_handle); - idb = statement->isr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - cursor_length = name_length(reinterpret_cast(cursor)) + 1; - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_set_cursor; - ips = &comm->ips_operations.ips_op_dsql; - ips->ips_st_handle = (UCHAR *) (statement->isr_handle); - ips->ips_parameter = type; - IPS_C_IN(comm, ips_name, IPS_DSQL_SET_CURSOR, cursor, cursor_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_DSQL_SQL_INFO(ISC_STATUS* user_status, - IPSERVER_ISR* stmt_handle, - USHORT item_length, - const UCHAR* items, - USHORT buffer_length, UCHAR* buffer) -{ -/************************************** - * - * d s q l _ s q l _ i n f o - * - ************************************** - * - * Functional description - * Provide information on sql object. - * - **************************************/ - IDB idb; - IPSERVER_ISR statement; - ips_object *ips; - ips_string *ips_items; - ips_string *ips_data; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - statement = *stmt_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_req_handle); - idb = statement->isr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_info_sql; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (statement->isr_handle); - IPS_C_IN(comm, ips_items, IPS_INFO_ITEMS, items, item_length); - IPS_C_OUT(comm, ips_data, IPS_INFO_DATA, buffer, buffer_length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_GET_SEGMENT(ISC_STATUS * user_status, - IBL * blob_handle, - USHORT * length, - USHORT buffer_length, UCHAR * buffer) -{ -/************************************** - * - * g d s _ g e t _ s e g m e n t - * - ************************************** - * - * Functional description - * Get a segment from an open blob. - * - **************************************/ - IDB idb; - IBL blob; - ips_segment *ips; - ips_string *ips_seg; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - blob = *blob_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - idb = blob->ibl_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_get_segment; - ips = &comm->ips_operations.ips_op_segment; - ips->ips_bl_handle = (UCHAR *) (blob->ibl_handle); - IPS_C_OUT(comm, ips_seg, IPS_BLOB_SEGMENT, buffer, buffer_length); - - // send request and get response - - *length = 0; - if (check_response(icc, user_status)) - if (user_status[1] != isc_segment) - RETURN_ERROR(user_status[1]); - *length = ips->ips_length; - RETURN_ERROR(user_status[1]); -} - - -ISC_STATUS GDS_GET_SLICE(ISC_STATUS* user_status, - IDB* db_handle, - ITR* tra_handle, - BID array_id, - USHORT sdl_length, - const UCHAR* sdl, - USHORT param_length, - const UCHAR* param, - SLONG slice_length, - UCHAR* slice, SLONG* return_length) -{ -/************************************** - * - * g d s _ g e t _ s l i c e - * - ************************************** - * - * Functional description - * Snatch a slice of an array. - * - **************************************/ - IDB idb; - ITR transaction; - ULONG length; - ips_slice *ips; - ips_string *ips_sdl; - ips_string *ips_parms; - ips_string *ips_data; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = *tra_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_get_slice; - ips = &comm->ips_operations.ips_op_slice; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - ips->ips_rel_id = array_id->bid_relation_id; - ips->ips_number = array_id->bid_number; - IPS_C_IN(comm, ips_sdl, IPS_SLICE_SDL, sdl, sdl_length); - IPS_C_IN(comm, ips_parms, IPS_SLICE_PARAM, param, param_length); - IPS_C_OUT(comm, ips_data, IPS_SLICE_BUFFER, slice, slice_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // return data - - length = ips->ips_length; - if (return_length) - *return_length = length; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_OPEN_BLOB(ISC_STATUS* user_status, - IDB* db_handle, - ITR* itr_handle, IBL* blob_handle, BID blob_id) -{ -/************************************** - * - * g d s _ o p e n _ b l o b - * - ************************************** - * - * Functional description - * Open an existing blob. - * - **************************************/ - IDB idb; - ITR transaction; - IBL blob; - ips_blob *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - NULL_CHECK(blob_handle, isc_bad_segstr_handle); - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_open_blob; - ips = &comm->ips_operations.ips_op_blob; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - ips->ips_rel_id = blob_id->bid_relation_id; - ips->ips_bid_number = blob_id->bid_number; - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // create and fill a blob structure with results - - blob = (IBL) ALLOCV(type_ibl, BLOB_LENGTH); - *blob_handle = blob; - NOT_NULL(blob); - blob->ibl_handle = (FB_API_HANDLE) ips->ips_bl_handle; - blob->ibl_buffer_length = BLOB_LENGTH; - blob->ibl_idb = idb; - blob->ibl_itr = transaction; - blob->ibl_ptr = blob->ibl_buffer; - blob->ibl_next = transaction->itr_blobs; - transaction->itr_blobs = blob; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_OPEN_BLOB2(ISC_STATUS* user_status, - IDB* db_handle, - ITR* itr_handle, - IBL* blob_handle, - BID blob_id, USHORT bpb_length, const UCHAR* bpb) -{ -/************************************** - * - * g d s _ o p e n _ b l o b 2 - * - ************************************** - * - * Functional description - * Open an existing blob. - * - **************************************/ - IDB idb; - ITR transaction; - IBL blob; - ips_blob *ips; - ips_string *ips_bpb; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - NULL_CHECK(blob_handle, isc_bad_segstr_handle); - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_open_blob2; - ips = &comm->ips_operations.ips_op_blob; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - ips->ips_rel_id = blob_id->bid_relation_id; - ips->ips_bid_number = blob_id->bid_number; - IPS_C_IN(comm, ips_bpb, IPS_BLOB_BPB, bpb, bpb_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // create and fill blob structure - - blob = (IBL) ALLOCV(type_ibl, BLOB_LENGTH); - *blob_handle = blob; - NOT_NULL(blob); - blob->ibl_handle = (FB_API_HANDLE) ips->ips_bl_handle; - blob->ibl_buffer_length = BLOB_LENGTH; - blob->ibl_idb = idb; - blob->ibl_itr = transaction; - blob->ibl_ptr = blob->ibl_buffer; - blob->ibl_next = transaction->itr_blobs; - transaction->itr_blobs = blob; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_PREPARE(ISC_STATUS * user_status, - ITR * itr_handle, - USHORT buffer_length, UCHAR * buffer) -{ -/************************************** - * - * g d s _ p r e p a r e - * - ************************************** - * - * Functional description - * Prepare a transaction for commit. First phase of a two - * phase commit. - * - **************************************/ - IDB idb; - ITR transaction; - ips_object *ips; - ips_string *ips_prep_str; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - idb = (*itr_handle)->itr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_prepare2; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (transaction->itr_handle); - IPS_C_IN(comm, ips_prep_str, IPS_PREPARE_TRANS, buffer, buffer_length); - - // send request and wait for and return response - - RETURN_ERROR(check_response(icc, user_status)); -} - - -ISC_STATUS GDS_PUT_SEGMENT(ISC_STATUS* user_status, - IBL* blob_handle, - USHORT buffer_length, const UCHAR* buffer) -{ -/************************************** - * - * g d s _ p u t _ s e g m e n t - * - ************************************** - * - * Functional description - * Send a segment of data to an open blob. - * - **************************************/ - IDB idb; - IBL blob; - ips_segment *ips; - ips_string *ips_seg; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - blob = *blob_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - idb = blob->ibl_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_put_segment; - ips = &comm->ips_operations.ips_op_segment; - ips->ips_bl_handle = (UCHAR *) (blob->ibl_handle); - IPS_C_IN(comm, ips_seg, IPS_BLOB_SEGMENT, buffer, buffer_length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_PUT_SLICE(ISC_STATUS* user_status, - IDB* db_handle, - ITR* tra_handle, - BID array_id, - USHORT sdl_length, - const UCHAR* sdl, - USHORT param_length, - const UCHAR* param, - SLONG slice_length, UCHAR* slice) -{ -/************************************** - * - * g d s _ p u t _ s l i c e - * - ************************************** - * - * Functional description - * Insert a slice of an array. - * - **************************************/ - IDB idb; - ITR transaction; - ips_slice *ips; - ips_string *ips_sdl; - ips_string *ips_parms; - ips_string *ips_data; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = *tra_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_put_slice; - ips = &comm->ips_operations.ips_op_slice; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - ips->ips_rel_id = array_id->bid_relation_id; - ips->ips_number = array_id->bid_number; - IPS_C_IN(comm, ips_sdl, IPS_SLICE_SDL, sdl, sdl_length); - IPS_C_IN(comm, ips_parms, IPS_SLICE_PARAM, param, param_length); - IPS_C_IN(comm, ips_data, IPS_SLICE_BUFFER, slice, slice_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // return resulting ids - - array_id->bid_relation_id = ips->ips_rel_id; - array_id->bid_number = ips->ips_number; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_QUE_EVENTS(ISC_STATUS* user_status, - IDB* handle, - SLONG* id, - USHORT length, - const UCHAR* events, - FPTR_EVENT_CALLBACK ast, void* arg) -{ -/************************************** - * - * g d s _ q u e _ e v e n t s - * - ************************************** - * - * Functional description - * Que request for event notification. - * - **************************************/ - IDB idb; - USHORT evsem; - TEXT name_buffer[128]; - IVNT event; - ips_que_events *ips; - ips_string *ips_event; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - idb = *handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_que_events; - ips = &comm->ips_operations.ips_op_que_evnt; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_ast = ast; - ips->ips_arg = (UCHAR *) arg; - IPS_C_IN(comm, ips_event, IPS_QUEUE_EVENT, events, length); - - // allocate an event block - - THD_mutex_lock(&clisect); - if (!event_semaphore) { - - /* start the event threads, if necessary, by creating the - event semaphore, starting the event packer, waiting until - it's done on the event semaphore, and then starting the - event thread itself */ - - // create an event semaphore, but make sure it's a new one - - for (evsem = 0; evsem < 1000; evsem++) { - sprintf(name_buffer, IPI_EVENT_THREAD, Config::getIpcName(), evsem); - event_semaphore = - CreateSemaphore(ISC_get_security_desc(), 0L, 10000L, - name_buffer); - if (event_semaphore && GetLastError() != ERROR_ALREADY_EXISTS) - break; - event_semaphore = 0; - } - if (event_semaphore) { - gds__thread_start(event_packer, idb->idb_thread, THREAD_high, 0, - &event_packer_handle); - if (!event_packer_handle) - gds__log("unable to start event packer thread %ld", - (long) GetLastError()); - else { - WaitForSingleObject(event_semaphore, INFINITE); - gds__thread_start(event_thread, NULL, THREAD_high, 0, - &event_thread_handle); - if (!event_thread_handle) - gds__log("unable to start event processing thread %ld", - (long) GetLastError()); - } - } - else - gds__log("Unable to create event semaphore"); - } - for (event = idb->idb_events; event; event = event->ivnt_next) - if (!event->ivnt_id) - break; - if (!event) { - event = (IVNT) ALLOC(type_ivnt); - if (!event) { - THD_mutex_unlock(&clisect); - NOT_NULL(event); - } - event->ivnt_handle = 0; - event->ivnt_idb = idb; - event->ivnt_next = idb->idb_events; - idb->idb_events = event; - } - eventID++; - event->ivnt_id = eventID; - event->ivnt_ast = ast; - event->ivnt_arg = arg; - THD_mutex_unlock(&clisect); - - // send request and get response - - ips->ips_event_hwnd = event_window; - ips->ips_event_id = eventID; - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - *id = ips->ips_event_id; - event->ivnt_handle = ips->ips_event_id; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_RECEIVE(ISC_STATUS * user_status, - IRQ * req_handle, - SSHORT msg_type, - USHORT msg_length, - UCHAR * msg, SSHORT level -#ifdef SCROLLABLE_CURSORS - , USHORT direction, ULONG offset -#endif - ) -{ -/************************************** - * - * g d s _ r e c e i v e 2 - * - ************************************** - * - * Functional description - * Get a record from the host program. - * - **************************************/ - IRQ request; - IDB idb; - ips_request *ips; - ips_string *ips_message; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - request = *req_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - idb = request->irq_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_receive; - ips = &comm->ips_operations.ips_op_request; - ips->ips_rq_handle = (UCHAR *) (request->irq_handle); - ips->ips_msg_type = msg_type; - ips->ips_req_level = level; -#ifdef SCROLLABLE_CURSORS - ips->ips_direction = direction; - ips->ips_offset = offset; -#endif - IPS_C_OUT(comm, ips_message, IPS_RECEIVE_MESSAGE, msg, msg_length); - - // send request and get answer - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_RECONNECT(ISC_STATUS* user_status, - IDB* db_handle, - ITR* itr_handle, USHORT length, const UCHAR* id) -{ -/************************************** - * - * g d s _ r e c o n n e c t - * - ************************************** - * - * Functional description - * Connect to a transaction in limbo. - * - **************************************/ - IDB idb; - ISC_STATUS l; - ips_reconnect *ips; - ips_string *ips_id; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - NULL_CHECK(itr_handle, isc_bad_trans_handle); - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - l = length; - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_reconnect; - ips = &comm->ips_operations.ips_op_recon_trans; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - IPS_C_IN(comm, ips_id, IPS_RECONNECT_ID, id, l); - - // send message and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - *itr_handle = - make_transaction(user_status, idb, (FB_API_HANDLE) ips->ips_tr_handle); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_RELEASE_REQUEST(ISC_STATUS * user_status, IRQ * req_handle) -{ -/************************************** - * - * g d s _ r e l e a s e _ r e q u e s t - * - ************************************** - * - * Functional description - * Release a request. - * - **************************************/ - IDB idb; - IRQ request; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - request = *req_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - idb = request->irq_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_release; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (request->irq_handle); - - // make request and free handle - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // release request resources - - release_request(request); - *req_handle = NULL; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_REQUEST_INFO(ISC_STATUS* user_status, - IRQ* request, - USHORT level, - USHORT item_length, - const UCHAR* items, - USHORT buffer_length, UCHAR* buffer) -{ -/************************************** - * - * g d s _ r e q u e s t _ i n f o - * - ************************************** - * - * Functional description - * Provide information on request object. - * - **************************************/ - IDB idb; - ips_object *ips; - ips_string *ips_items; - ips_string *ips_data; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - CHECK_HANDLE((*request), type_irq, isc_bad_req_handle); - idb = (*request)->irq_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_info_request; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) ((*request)->irq_handle); - ips->ips_parameter = level; - IPS_C_IN(comm, ips_items, IPS_INFO_ITEMS, items, item_length); - IPS_C_OUT(comm, ips_data, IPS_INFO_DATA, buffer, buffer_length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_ROLLBACK_RETAINING(ISC_STATUS * user_status, ITR * itr_handle) -{ -/************************************** - * - * i s c _ r o l l b a c k _ r e t a i n i n g - * - ************************************** - * - * Functional description - * - * Abort the transaction but keep the environment valid - * - **************************************/ - IDB idb; - ITR transaction; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - idb = (*itr_handle)->itr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_rollback_retaining; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (transaction->itr_handle); - - // send request - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_ROLLBACK(ISC_STATUS * user_status, ITR * itr_handle) -{ -/************************************** - * - * g d s _ r o l l b a c k - * - ************************************** - * - * Functional description - * Abort a transaction. - * - **************************************/ - IDB idb; - ITR transaction; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - idb = (*itr_handle)->itr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_rollback; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (transaction->itr_handle); - - // send request and free handle - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // release transaction resources - - clear_transaction_statements(transaction); - release_transaction(transaction); - *itr_handle = NULL; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_SEEK_BLOB(ISC_STATUS * user_status, - IBL * blob_handle, - SSHORT mode, - SLONG offset, SLONG * result) -{ -/************************************** - * - * g d s _ s e e k _ b l o b - * - ************************************** - * - * Functional description - * Try to seek a blob. - * - **************************************/ - IDB idb; - IBL blob; - ips_seek_blob *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - blob = *blob_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - idb = blob->ibl_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_seek_blob; - ips = &comm->ips_operations.ips_op_sk_blob; - ips->ips_bl_handle = (UCHAR *) (blob->ibl_handle); - ips->ips_offset = offset; - ips->ips_mode = mode; - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - *result = ips->ips_result; - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_SEND(ISC_STATUS * user_status, - IRQ * req_handle, - SSHORT msg_type, - USHORT msg_length, - UCHAR * msg, SSHORT level) -{ -/************************************** - * - * g d s _ s e n d - * - ************************************** - * - * Functional description - * Get a record from the host program. - * - **************************************/ - IRQ request; - IDB idb; - ips_request *ips; - ips_string *ips_message; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - request = *req_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - idb = request->irq_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_send; - ips = &comm->ips_operations.ips_op_request; - ips->ips_rq_handle = (UCHAR *) (request->irq_handle); - ips->ips_msg_type = msg_type; - ips->ips_req_level = level; - IPS_C_IN(comm, ips_message, IPS_SEND_MESSAGE, msg, msg_length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - -ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status, - USHORT service_length, - const TEXT* service_name, - IDB* handle, USHORT spb_length, const SCHAR* spb) -{ -/************************************** - * - * g d s _ s e r v i c e _ a t t a c h - * - ************************************** - * - * Functional description - * Connect to an Interbase service via the - * interprocess interface to a local server. - * - **************************************/ - IDB idb; - ICC icc; - SSHORT l; - ips_object *ips; - ips_string *ips_name; - ips_string *ips_spb; - ips_comm_area *comm; - USHORT commi; - - - // handle should be null coming in - - NULL_CHECK(handle, isc_bad_svc_handle); - if (!(l = service_length)) - l = strlen(service_name); - - // initiate connection - - if (!init(user_status, &icc)) - return user_status[1]; - - // set up communications area - - THD_mutex_lock(&mapsect); - comm = (ips_comm_area *) icc->icc_mapped_addr; - for (commi = 0; commi < MAX_IPS_STRINGS; commi++) - comm->ips_buffers[commi].ips_flags = 0; - comm->ips_operation = op_service_attach; - ips = &comm->ips_operations.ips_op_object; - IPS_C_IN(comm, ips_name, IPS_ATTACH_SVC_NAME, service_name, l); - IPS_C_IN(comm, ips_spb, IPS_ATTACH_SVC_SPB, spb, spb_length); - - // send request and wait for response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - - // allocate a database structure and link it to thread - - idb = (IDB) ALLOC(type_idb); - *handle = idb; - NOT_NULL(idb); - idb->idb_flags = IDBF_SERVICE_ATTACHMENT; - idb->idb_next = icc->icc_databases; - idb->idb_thread = icc; - icc->icc_databases = idb; - idb->idb_handle = (FB_API_HANDLE) (ips->ips_handle); - RETURN_SUCCESS; -} - -ISC_STATUS GDS_SERVICE_DETACH(ISC_STATUS * user_status, IDB * handle) -{ -/************************************** - * - * g d s _ s e r v i c e _ d e t a c h - * - ************************************** - * - * Functional description - * Close down a service. - * - **************************************/ - ICC icc; - IDB idb; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - - - // verify handle - - idb = *handle; - CHECK_HANDLE(idb, type_idb, isc_bad_svc_handle); - - // point to communications area - - icc = idb->idb_thread; - THD_mutex_lock(&mapsect); - if (icc->icc_flags & ICCF_SERVER_SHUTDOWN) { - - // if server was shut down, set up vector - - user_status[0] = isc_arg_gds; - user_status[1] = FB_SUCCESS; - user_status[2] = isc_arg_end; - } - else { - comm = (ips_comm_area *) icc->icc_mapped_addr; - for (commi = 0; commi < MAX_IPS_STRINGS; commi++) - comm->ips_buffers[commi].ips_flags = 0; - comm->ips_operation = op_service_detach; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (idb->idb_handle); - - // send request and release handle - - if (check_response(icc, user_status)) - if (user_status[1] != isc_lost_db_connection) - return user_status[1]; - } - - // free up resources - - release_database(idb); - *handle = NULL; - if (user_status[1]) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - -ISC_STATUS GDS_SERVICE_QUERY(ISC_STATUS* user_status, - IDB* service, - ULONG* reserved, - USHORT send_item_length, - const SCHAR* send_items, - USHORT recv_item_length, - const SCHAR* recv_items, - USHORT buffer_length, SCHAR* buffer) -{ -/************************************** - * - * g d s _ s e r v i c e _ q u e r y - * - ************************************** - * - * Functional description - * Provide information on service object. - * - **************************************/ - IDB idb; - ips_object *ips; - ips_string *ips_snd_items; - ips_string *ips_rcv_items; - ips_string *ips_data; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handle - - idb = *service; - CHECK_HANDLE(idb, type_idb, isc_bad_svc_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_service_info; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (idb->idb_handle); - IPS_C_IN(comm, ips_snd_items, IPS_INFO_ITEMS, send_items, - send_item_length); - IPS_C_IN(comm, ips_rcv_items, IPS_QUERY_RECV_ITEMS, recv_items, - recv_item_length); - IPS_C_OUT(comm, ips_data, IPS_INFO_DATA, buffer, buffer_length); - - // send request and get answer - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - -ISC_STATUS GDS_SERVICE_START(ISC_STATUS* user_status, - IDB* service, - ULONG* reserved, USHORT spb_length, const SCHAR* spb) -{ - /************************************** - * - * g d s _ s e r v i c e _ s t a r t - * - ************************************** - * - * Functional description - * Start an InterBase service - * - **************************************/ - IDB idb; - ips_object *ips; - ips_string *ips_spb; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handle - idb = *service; - CHECK_HANDLE(idb, type_idb, isc_bad_svc_handle); - - // point to communications area - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_service_start; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (idb->idb_handle); - IPS_C_IN(comm, ips_spb, IPS_START_SVC_SPB, spb, spb_length); - - // send request and get answer - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_START(ISC_STATUS * user_status, - IRQ * req_handle, - ITR * itr_handle, SSHORT level) -{ -/************************************** - * - * g d s _ s t a r t - * - ************************************** - * - * Functional description - * Get a record from the host program. - * - **************************************/ - IRQ request; - ITR transaction; - IDB idb; - ips_request *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - request = *req_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - idb = request->irq_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_start; - ips = &comm->ips_operations.ips_op_request; - ips->ips_rq_handle = (UCHAR *) (request->irq_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - ips->ips_req_level = level; - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_START_AND_SEND(ISC_STATUS * user_status, - IRQ * req_handle, - ITR * itr_handle, - SSHORT msg_type, - USHORT msg_length, - UCHAR * msg, SSHORT level) -{ -/************************************** - * - * g d s _ s t a r t _ a n d _ s e n d - * - ************************************** - * - * Functional description - * Get a record from the host program. - * - **************************************/ - IRQ request; - ITR transaction; - IDB idb; - ips_request *ips; - ips_string *ips_message; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - request = *req_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - transaction = *itr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - idb = request->irq_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_start_and_send; - ips = &comm->ips_operations.ips_op_request; - ips->ips_rq_handle = (UCHAR *) (request->irq_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - ips->ips_msg_type = msg_type; - ips->ips_req_level = level; - IPS_C_IN(comm, ips_message, IPS_SEND_MESSAGE, msg, msg_length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_START_MULTIPLE(ISC_STATUS * user_status, - ITR * itr_handle, - SSHORT count, int **vector) -{ -/************************************** - * - * g d s _ s t a r t _ m u l t i p l e - * - ************************************** - * - * Functional description - * Start a transaction. - * - **************************************/ - int **args; - IDB idb; - USHORT i, j; - TEXT *p; - ULONG l, *lp; - ips_start_trans *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - USHORT commi; - ICC icc; - - - // verify handle - - NULL_CHECK(itr_handle, isc_bad_trans_handle); - - // point to communications area - - args = vector; - idb = (IDB) * (*args++); - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - GET_OBJECT(idb->idb_thread); - comm_ptr = (TEXT *) comm->ips_data; - comm->ips_operation = op_transaction; - ips = &comm->ips_operations.ips_op_strt_trans; - ips->ips_db_count = count; - - /* fill in handles, verifying along the way (note that this is the - ONLY case where normal buffering is not done, so we'd better - never have enough databases to exceed 8k worth of space */ - - for (i = 0; i < count; i++) { - - // first idb pointer already acquired above - - if (i) { - idb = (IDB) * (*args++); - CHECK_HANDLE_REL(idb, type_idb, isc_bad_db_handle); - } - lp = (ULONG *) comm_ptr; - *lp++ = (ULONG) (idb->idb_handle); - l = (ULONG) * args++; - *lp++ = l; - comm_ptr = (TEXT *) lp; - p = (TEXT *) * args++; - for (j = 0; j < l; j++) - *comm_ptr++ = *p++; - - // align on ULONG - - l = l % sizeof(ULONG); - if (l) - comm_ptr += sizeof(ULONG) - l; - } - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - *itr_handle = - make_transaction(user_status, idb, (FB_API_HANDLE) ips->ips_tr_handle); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_START_TRANSACTION(ISC_STATUS * user_status, - ITR * itr_handle, SSHORT count, ...) -{ -/************************************** - * - * g d s _ s t a r t _ t r a n s a c t i o n - * - ************************************** - * - * Functional description - * Start a transaction. - * - **************************************/ - va_list args; - IDB idb; - USHORT i, j; - UCHAR *p; - ULONG l, *lp; - ips_start_trans *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - USHORT commi; - ICC icc; - - - // verify handle - - NULL_CHECK(itr_handle, isc_bad_trans_handle); - - // point to communications area - - va_start(args, count); - idb = *(va_arg(args, IDB *)); - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - GET_OBJECT(idb->idb_thread); - comm_ptr = (TEXT *) comm->ips_data; - comm->ips_operation = op_transaction; - ips = &comm->ips_operations.ips_op_strt_trans; - ips->ips_db_count = count; - - /* fill in handles, verifying along the way (note that this is the - ONLY case where normal buffering is not done, so we'd better - never have enough databases to exceed 8k worth of space */ - - for (i = 0; i < count; i++) { - - // the first pointer has already been gotten above - - if (i) { - idb = *(va_arg(args, IDB *)); - CHECK_HANDLE_REL(idb, type_idb, isc_bad_db_handle); - } - lp = (ULONG *) comm_ptr; - *lp++ = (ULONG) (idb->idb_handle); - l = (ULONG) va_arg(args, int); - *lp++ = l; - comm_ptr = (TEXT *) lp; - p = va_arg(args, UCHAR *); - for (j = 0; j < l; j++) - *comm_ptr++ = *p++; - - // align on ULONG - - l = l % sizeof(ULONG); - if (l) - comm_ptr += sizeof(ULONG) - l; - } - va_end(args); // Note CHECK_HANDLE_REL may return above! - - // send message and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - *itr_handle = - make_transaction(user_status, idb, (FB_API_HANDLE) ips->ips_tr_handle); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_TRANSACTION_INFO(ISC_STATUS* user_status, - ITR* transaction, - USHORT item_length, - const UCHAR* items, - USHORT buffer_length, UCHAR* buffer) -{ -/************************************** - * - * g d s _ t r a n s a c t i o n _ i n f o - * - ************************************** - * - * Functional description - * Provide information on transaction object. - * - **************************************/ - IDB idb; - ips_object *ips; - ips_string *ips_items; - ips_string *ips_data; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - CHECK_HANDLE((*transaction), type_itr, isc_bad_trans_handle); - idb = (*transaction)->itr_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_info_transaction; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) ((*transaction)->itr_handle); - IPS_C_IN(comm, ips_items, IPS_INFO_ITEMS, items, item_length); - IPS_C_OUT(comm, ips_data, IPS_INFO_DATA, buffer, buffer_length); - - // send request and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_TRANSACT_REQUEST(ISC_STATUS* user_status, - IDB* db_handle, - ITR* tra_handle, - USHORT blr_length, - const UCHAR* blr, - USHORT in_msg_length, - UCHAR* in_msg, - USHORT out_msg_length, UCHAR* out_msg) -{ -/************************************** - * - * i s c _ t r a n s a c t _ r e q u e s t - * - ************************************** - * - * Functional description - * - **************************************/ - IDB idb; - ITR transaction; - ips_transact_request *ips; - ips_string *ips_blr; - ips_string *ips_in_msg; - ips_string *ips_out_msg; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - idb = *db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = *tra_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_transact_request; - ips = &comm->ips_operations.ips_op_trans_req; - ips->ips_db_handle = (UCHAR *) (idb->idb_handle); - ips->ips_tr_handle = (UCHAR *) (transaction->itr_handle); - IPS_C_IN(comm, ips_blr, IPS_TRANS_REQ_BLR, blr, blr_length); - IPS_C_IN(comm, ips_in_msg, IPS_TRANS_REQ_IN_MSG, in_msg, in_msg_length); - IPS_C_OUT(comm, ips_out_msg, IPS_TRANS_REQ_OUT_MSG, out_msg, - out_msg_length); - - // send message and get response - - if (check_response(icc, user_status)) - RETURN_ERROR(user_status[1]); - RETURN_SUCCESS; -} - - -ISC_STATUS GDS_UNWIND(ISC_STATUS * user_status, - IRQ * req_handle, SSHORT level) -{ -/************************************** - * - * g d s _ u n w i n d - * - ************************************** - * - * Functional description - * Unwind a running request. - * - **************************************/ - IDB idb; - IRQ request; - ips_object *ips; - ips_comm_area *comm; - USHORT commi; - ICC icc; - - - // verify handles - - request = *req_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - idb = request->irq_idb; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // point to communications area - - GET_OBJECT(idb->idb_thread); - comm->ips_operation = op_unwind; - ips = &comm->ips_operations.ips_op_object; - ips->ips_handle = (UCHAR *) (request->irq_handle); - ips->ips_parameter = (ULONG) level; - - // send request and return response - - RETURN_ERROR(check_response(icc, user_status)); -} - - -static ISC_STATUS check_response( ICC icc, ISC_STATUS * user_status) -{ -/************************************** - * - * c h e c k _ r e s p o n s e - * - ************************************** - * - * Functional description - * Check response to a remote call. - * - * Pack any and all input buffers and send the - * request to the server. This gets done as - * often as needed to get all the client's - * input buffers across. - * - * After all the client buffers get across, this - * function waits for the server to complete the - * operation. This entails getting any and all - * client output buffers from the server. Again, - * the unpacking gets done as often as necessary. - * - * Data movement is done in order of buffer usage - * for any of the buffers that need copying. As - * much as possible is crammed into the remaining - * buffer space in the comminucations area for each - * copy stage. - * - **************************************/ -#ifdef DEBUG_IP_TRACE - ips_comm_area *comm; - - - comm = (ips_comm_area *) icc->icc_mapped_addr; - gds__log("ipclient sends %d at %8lX %8lX", comm->ips_operation, icc, - comm); -#endif - - if (!(icc->icc_flags & ICCF_SERVER_SHUTDOWN)) { - if (pack_strings(icc)) { - if (send_and_wait(icc)) { - extract_status(icc, user_status); - if (unpack_strings(icc)) - return user_status[1]; - } - } - } - - // communications failure - database is now unavailable - - icc->icc_flags |= ICCF_SERVER_SHUTDOWN; -#ifdef DEBUG_IP_TRACE - gds__log("ipclient comm failure %lX", (long) icc); -#endif - user_status[0] = isc_arg_gds; - user_status[1] = isc_lost_db_connection; - user_status[2] = isc_arg_end; - return user_status[1]; -} - - -static void clear_statement_cache( IPSERVER_ISR statement) -{ -/************************************** - * - * c l e a r _ s t a t e m e n t _ c a c h e - * - ************************************** - * - * Functional description - * Clean out any unfetched cached records for a statement. - * - **************************************/ - USHORT i; - - - if (statement->isr_packed) - ALLI_free((UCHAR *) statement->isr_packed); - statement->isr_rec_count = 0; - statement->isr_max_recs = 0; - statement->isr_eof_flag = FALSE; - statement->isr_packed = NULL; - for (i = 0; i < ISC_STATUS_LENGTH; i++) - statement->isr_status[i] = 0; -} - - -static void clear_transaction_statements( ITR transaction) -{ -/************************************** - * - * c l e a r _ t r a n s a c t i o n _ s t a t e m e n t s - * - ************************************** - * - * Functional description - * Clean out cached records for any statements - * for this transaction. - * - **************************************/ - IPSERVER_ISR statement; - IDB database; - - - database = transaction->itr_idb; - for (statement = database->idb_sql_requests; statement; - statement = statement->isr_next) - { - if (statement->isr_itr == transaction) - clear_statement_cache(statement); - } -} - - -static THREAD_ENTRY_DECLARE event_packer(THREAD_ENTRY_PARAM arg) -{ -/************************************** - * - * e v e n t _ p a c k e r - * - ************************************** - * - * Functional description - * This thread just packs events on the - * client's queue for event_thread, so - * the server isn't kept waiting - * - **************************************/ - ICC icc = (ICC)(arg); - TEXT name_buffer[128], class_buffer[32]; - - - // init the window, which never really returns - - sprintf(name_buffer, IPI_EVENT_NAME, Config::getIpcName(), icc->icc_file, icc->icc_slot); - sprintf(class_buffer, IPI_EVENT_CLASS, Config::getIpcName()); - IPC_window_init((char *) class_buffer, (char *) name_buffer, - &event_window, event_semaphore); - CloseHandle(event_packer_handle); - event_packer_handle = 0; - return 0; -} - - -static THREAD_ENTRY_DECLARE event_thread(THREAD_ENTRY_PARAM) -{ -/************************************** - * - * e v e n t _ t h r e a d - * - ************************************** - * - * Functional description - * This thread gets events of an event queue and - * posts them. Events are put on the queue by - * the event handler hidden windows. - * - **************************************/ - ICC icc; - IDB idb; - IVNT ivnt; - IVNT event; - EVENTQ queued; - ISC_STATUS_ARRAY status; - - - // loop to wait for events - - for (;;) { - WaitForSingleObject(event_semaphore, INFINITE); - if (exit_flag) - break; - - // init our icc - - if (!event_icc) - if (!init(status, &event_icc)) - return 0; - - // find next queued event - - THD_mutex_lock(&evtsect); - if (event_head) { - queued = event_head; - event_head = queued->evq_next; - - // if queue is empty, clear tail - - if (!event_head) - event_tail = NULL; - THD_mutex_unlock(&evtsect); - - // find event in icc/idb/events chain - - event = NULL; - THD_mutex_lock(&clisect); - for (icc = client_threads; icc && !event; icc = icc->icc_next) - for (idb = icc->icc_databases; idb && !event; - idb = idb->idb_next) for (ivnt = idb->idb_events; ivnt; - ivnt = ivnt->ivnt_next) - if (ivnt->ivnt_id == queued->evq_id) { - event = ivnt; - break; - } - if (event) { - if (event->ivnt_ast) { - (*event->ivnt_ast) (event->ivnt_arg, - queued->evq_length, - queued->evq_string); - event->ivnt_id = 0; - } - } - THD_mutex_unlock(&clisect); - ALLI_free((UCHAR *) queued); - } - else - THD_mutex_unlock(&evtsect); - } - CloseHandle(event_thread_handle); - event_thread_handle = 0; - return 0; -} - - -static void extract_status( ICC icc, ISC_STATUS * user_status) -{ -/************************************** - * - * e x t r a c t _ s t a t u s - * - ************************************** - * - * Functional description - * Extract and convert the status vector - * and pack it into the comm area. - * - **************************************/ - USHORT i, length; - TEXT *text; - ISC_STATUS *v, code, *server_status; - ips_comm_area *comm; - ULONG *comm_ptr; - TEXT *p; - - - comm = (ips_comm_area *) icc->icc_mapped_addr; - - // extract the status information - - text = error_text; - server_status = reinterpret_cast < ISC_STATUS * >(comm->ips_status); - comm_ptr = comm->ips_data; - v = user_status; - - // if there's no error or warning, skip the rest - - if (!server_status[1] && !server_status[2]) { - *v++ = *server_status++; - *v++ = *server_status++; - } - else { - while (code = *server_status++) { - switch (*v++ = code) { - case isc_arg_interpreted: - case isc_arg_string: - - /* get a string from the comm area, aligning the - pointer accordingly */ - - *v++ = (ISC_STATUS) text; - length = (USHORT) * comm_ptr++; - p = (TEXT *) comm_ptr; - comm_ptr = comm_ptr + - (length + (sizeof(ULONG) - 1)) / sizeof(ULONG); - for (i = 0; i < length; i++) - *text++ = *p++; - *text++ = (TEXT) 0; - continue; - - case isc_arg_gds: - case isc_arg_warning: - case isc_arg_number: - case isc_arg_vms: - case isc_arg_unix: - case isc_arg_win32: - *v++ = *server_status++; - continue; - - case isc_arg_end: - case isc_arg_cstring: - default: - return; - } - } - } - *v = isc_arg_end; -} - - -static ISC_STATUS handle_error( ISC_STATUS * user_status, ISC_STATUS code) -{ -/************************************** - * - * h a n d l e _ e r r o r - * - ************************************** - * - * Functional description - * An invalid handle has been passed in. If there is a user status - * vector, make it reflect the error. If not, emulate the routine - * "error" and abort. - * - **************************************/ - - *user_status++ = isc_arg_gds; - *user_status++ = code; - *user_status = isc_arg_end; - return code; -} - - -static SSHORT init( ISC_STATUS * user_status, ICC * picc) -{ -/************************************** - * - * i n i t - * - ************************************** - * - * Functional description - * Initialize for database access. First call from both CREATE and - * OPEN. - * - **************************************/ - ICC icc; - IPM ipm; - ULONG number=0; - USHORT mapped_area, mapped_position; - TEXT name_buffer[128]; - DWORD current_thread_id; - DWORD last_error; - HANDLE file_handle; - LPVOID mapped_address; - DWORD client_pid; - ips_comm_area *comm; - - // first, make sure that the critical region is initialized - - while (!initialized) - { - if (!InterlockedIncrement(&interlock)) - { - // increment "succeeded", initialize - - initialized = true; - gds__register_cleanup(reinterpret_cast(IPC_release_all), - NULL); - } - else - { - // some other thread is initializing now - - InterlockedDecrement(&interlock); - } - } - - // set up for unavailable server - - user_status[0] = isc_arg_gds; - user_status[1] = isc_unavailable; - user_status[2] = isc_arg_end; - - // see if this thread has been connected yet, and if not, do so - - THD_mutex_lock(&clisect); - current_thread_id = GetCurrentThreadId(); - for (icc = client_threads; icc; icc = icc->icc_next) - { - if (icc->icc_thread_handle == current_thread_id && - !(icc->icc_flags & ICCF_SERVER_SHUTDOWN)) - { - break; - } - } - - if (!icc) - { - - /* send a message to the server to get the next available - attachment, a 32 bit value with a mapped memory file - ID in the high order and an allocated area in that - mapped file in the low order */ - - client_pid = GetCurrentProcessId(); - HWND hWndServer = FindWindow(szClassName, APP_NAME); - if (hWndServer) - { - number = (ULONG) SendMessage(hWndServer, - IPI_CONNECT_MESSAGE, 0, - (LPARAM) client_pid); - } - if (!number || number == (ULONG) - 1) - { - THD_mutex_unlock(&clisect); - return 0; - } - pages_per_user = (USHORT) IPS_UNPACK_PAGES(number); - users_per_map = (USHORT) IPS_UNPACK_MAX_USERS(number); - mapped_area = (USHORT) IPS_UNPACK_MAPNUM(number); - mapped_position = (USHORT) IPS_UNPACK_USERNUM(number); - - // see if area is already mapped for this client - - for (ipm = client_maps; ipm; ipm = ipm->ipm_next) - { - if (ipm->ipm_number == mapped_area && - !(ipm->ipm_flags & IPMF_SERVER_SHUTDOWN)) - { - break; - } - } - - if (!ipm) - { - // add new mapping - - sprintf(name_buffer, IPI_MAPPED_FILE_NAME, Config::getIpcName(), mapped_area); - file_handle = OpenFileMapping(FILE_MAP_WRITE, FALSE, name_buffer); - if (!file_handle) { - THD_mutex_unlock(&clisect); - return 0; - } - mapped_address = - MapViewOfFile(file_handle, FILE_MAP_WRITE, 0L, 0L, - IPS_MAPPED_SIZE(users_per_map, pages_per_user)); - if (!mapped_address) - { - last_error = GetLastError(); - CloseHandle(file_handle); - THD_mutex_unlock(&clisect); - return 0; - } - ipm = (IPM) ALLI_alloc(sizeof(struct ipm)); - if (!ipm) - { - UnmapViewOfFile(mapped_address); - CloseHandle(file_handle); - THD_mutex_unlock(&clisect); - return 0; - } - ipm->ipm_next = client_maps; - client_maps = ipm; - ipm->ipm_count = 0; - ipm->ipm_number = mapped_area; - ipm->ipm_handle = file_handle; - ipm->ipm_address = mapped_address; - ipm->ipm_flags = 0; - } - - // there's no thread structure, so make one - - icc = (ICC) ALLOC(type_icc); - if (!icc) - { - UnmapViewOfFile(mapped_address); - CloseHandle(file_handle); - THD_mutex_unlock(&clisect); - return 0; - } - icc->icc_thread_handle = current_thread_id; - icc->icc_file_handle = ipm->ipm_handle; - icc->icc_mapped_addr = (UCHAR *) ipm->ipm_address + - IPS_MAPPED_FOR_CLI(pages_per_user, mapped_position); - icc->icc_file = mapped_area; - icc->icc_slot = mapped_position; - icc->icc_ipm = ipm; - icc->icc_flags = 0; -#ifdef DEBUG_IP_TRACE - gds__log("ipclient icc %8lX, comm %8lX, number %lX", - icc, comm, number); -#endif - comm = (ips_comm_area *) icc->icc_mapped_addr; - - // only speak if server has correct protocol - - if (comm->ips_server_protocol != 1L || comm->ips_server_proc == 0) - { - UnmapViewOfFile(mapped_address); - CloseHandle(file_handle); - THD_mutex_unlock(&clisect); - return 0; - } - comm->ips_client_protocol = 1L; - icc->icc_server_id = comm->ips_server_id; - /* - * comm-ips_server_proc is set by ipserver.c when the client first - * initiates the conversation with the server. - * - */ - icc->icc_server_proc = comm->ips_server_proc; - ipm->ipm_count++; - - // get handles of semaphores - - sprintf(name_buffer, IPI_CLIENT_SEM_NAME, Config::getIpcName(), - mapped_area, mapped_position); - icc->icc_client_sem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, - name_buffer); - sprintf(name_buffer, IPI_SERVER_SEM_NAME, Config::getIpcName(), - mapped_area, mapped_position); - icc->icc_server_sem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, - name_buffer); - - // initialize wait for multiple objects array - - icc->icc_waits[0] = icc->icc_client_sem; - icc->icc_waits[1] = icc->icc_server_proc; - - // if we're not watching the server yet, do so now - - if (!server_watcher_handle) - { - server_process_handle = icc->icc_server_proc; - gds__thread_start(server_watcher, - NULL, - THREAD_high, - 0, - &server_watcher_handle); - } - - // link to icc chain - - icc->icc_next = client_threads; - client_threads = icc; - } - THD_mutex_unlock(&clisect); - if (picc) { - *picc = icc; - } - return 1; -} - - -static ITR make_transaction( ISC_STATUS * user_status, IDB idb, FB_API_HANDLE handle) -{ -/************************************** - * - * m a k e _ t r a n s a c t i o n - * - ************************************** - * - * Functional description - * Create a local transaction handle. - * - **************************************/ - ITR transaction; - - transaction = (ITR) ALLOC(type_itr); - if (!transaction) { - user_status[0] = isc_arg_gds; - user_status[1] = isc_virmemexh; - user_status[2] = isc_arg_end; - return NULL; - } - transaction->itr_idb = idb; - transaction->itr_handle = handle; - transaction->itr_next = idb->idb_transactions; - idb->idb_transactions = transaction; - return transaction; -} - - -// Another function to count the legnth up to the first space. -static SSHORT name_length(const TEXT* name) -{ -/***************************************** - * - * n a m e _ l e n g t h - * - ***************************************** - * - * Functional Description - * Compute length of user-supplied( blank-padded) or - * NULL-terminated buffer - * - *****************************************/ - const TEXT* p = name; - while (*p && *p != ' ') - ++p; - return (p - name); -} - - -static bool pack_strings( ICC icc) -{ -/************************************** - * - * p a c k _ s t r i n g s - * - ************************************** - * - * Functional description - * Pack the input buffers into the comm area. - * Note that this may require multiple send/receive - * operations to get all the buffers across. - * - **************************************/ - USHORT i; - ips_comm_area *comm; - ips_string *string; - TEXT *acursor, *ccursor, *abase; - ULONG to_copy, size_left; - - - comm = (ips_comm_area *) icc->icc_mapped_addr; - - /* for each buffer, pack it into the comm area and send it, - waiting until the server is done to pack the next buffer - full */ - - size_left = (ULONG) (IPS_USEFUL_SPACE(pages_per_user)); - acursor = (TEXT *) comm->ips_data; - abase = acursor; - for (i = 0; i < MAX_IPS_STRINGS; i++) { - string = &comm->ips_buffers[i]; - - // see if this buffer needs sending - - if (string->ips_flags & IPS_INPUT_BUFFER && string->ips_cl_size) { - - string->ips_cl_copied = 0; - ccursor = reinterpret_cast < char *>(string->ips_cl_addr); - - // keep packing it in - - while (string->ips_cl_copied < string->ips_cl_size) { - - // put in the whole thing, or whatever will fit - - to_copy = string->ips_cl_size - string->ips_cl_copied; - if (size_left <= to_copy) - to_copy = size_left; - string->ips_com_offset = acursor - abase; - string->ips_com_size = to_copy; - memcpy(acursor, ccursor, (USHORT) to_copy); - acursor += to_copy; - ccursor += to_copy; - size_left -= to_copy; - string->ips_cl_copied += to_copy; - - // if all the space has been used up, send it and wait - - if (!size_left && string->ips_cl_copied < string->ips_cl_size) { - if (!send_and_wait(icc)) - return false; - size_left = (ULONG) (IPS_USEFUL_SPACE(pages_per_user)); - acursor = (TEXT *) comm->ips_data; - } - } - } - } - return true; -} - - -static void release_blob( IBL blob) -{ -/************************************** - * - * r e l e a s e _ b l o b - * - ************************************** - * - * Functional description - * Release a blob block and friends. - * - **************************************/ - ITR transaction; - IBL *p; - - - transaction = blob->ibl_itr; - for (p = &transaction->itr_blobs; *p; p = &(*p)->ibl_next) - if (*p == blob) { - *p = blob->ibl_next; - break; - } - ALLI_release((BLK) blob); -} - - -static void release_database( IDB idb) -{ -/************************************** - * - * r e l e a s e _ d a t a b a s e - * - ************************************** - * - * Functional description - * Take a database structure out of - * the thread's chain and close down - * the thread's comm if it's the last - * structure on the chain. - * - **************************************/ - ICC icc; - ICC picc; - IPM ipm; - IPM pipm; - IDB pidb; - ips_comm_area *comm; - - - // find the structure in the thread's chain and remove it - - THD_mutex_lock(&clisect); - icc = idb->idb_thread; - if (icc->icc_databases == idb) - icc->icc_databases = idb->idb_next; - else { - for (pidb = icc->icc_databases; pidb->idb_next; pidb = pidb->idb_next) - if (pidb->idb_next == idb) { - pidb->idb_next = idb->idb_next; - break; - } - } - ALLI_release((BLK) idb); - - // close down if chain is now empty - - if (!icc->icc_databases) { - - // point to communications area - - ipm = icc->icc_ipm; - if (!(icc->icc_flags & ICCF_SERVER_SHUTDOWN)) { - comm = (ips_comm_area *) icc->icc_mapped_addr; - comm->ips_operation = op_disconnect; - ReleaseSemaphore(icc->icc_server_sem, 1L, NULL); - } - - // free up semaphores - - if (icc->icc_client_sem) - CloseHandle(icc->icc_client_sem); - if (icc->icc_server_sem) - CloseHandle(icc->icc_server_sem); - if (icc->icc_server_proc) - CloseHandle(icc->icc_server_proc); - - // find icc in chain and release - - if (client_threads == icc) - client_threads = icc->icc_next; - else { - for (picc = client_threads; picc->icc_next; picc = picc->icc_next) - if (picc->icc_next == icc) { - picc->icc_next = icc->icc_next; - break; - } - } - ALLI_release((BLK) icc); - - // if this was the last area for this map, unmap it - - ipm->ipm_count--; - if (!ipm->ipm_count) { - if (!(ipm->ipm_flags & IPMF_SERVER_SHUTDOWN)) { - UnmapViewOfFile(ipm->ipm_address); - CloseHandle(ipm->ipm_handle); - } - - // find in chain and release - - if (client_maps == ipm) - client_maps = ipm->ipm_next; - else { - for (pipm = client_maps; pipm->ipm_next; pipm = pipm->ipm_next) - if (pipm->ipm_next == ipm) { - pipm->ipm_next = ipm->ipm_next; - break; - } - } - ALLI_free((UCHAR *) ipm); - } - } - THD_mutex_unlock(&clisect); -} - - -static void release_event( IVNT event) -{ -/************************************** - * - * r e l e a s e _ e v e n t - * - ************************************** - * - * Functional description - * Release a event block and friends. - * - **************************************/ - IDB idb; - IVNT *p; - - - idb = event->ivnt_idb; - for (p = &idb->idb_events; *p; p = &(*p)->ivnt_next) - if (*p == event) { - *p = event->ivnt_next; - break; - } - ALLI_release((BLK) event); -} - - -static void release_request( IRQ request) -{ -/************************************** - * - * r e l e a s e _ r e q u e s t - * - ************************************** - * - * Functional description - * Release a request block and friends. - * - **************************************/ - IDB idb; - IRQ *p; - - - idb = request->irq_idb; - for (p = &idb->idb_requests; *p; p = &(*p)->irq_next) - if (*p == request) { - *p = request->irq_next; - break; - } - ALLI_release((BLK) request); -} - - -static void release_transaction( ITR transaction) -{ -/************************************** - * - * r e l e a s e _ t r a n s a c t i o n - * - ************************************** - * - * Functional description - * Release a transaction block and friends. - * - **************************************/ - IDB idb; - ITR *p; - - - idb = transaction->itr_idb; - for (p = &idb->idb_transactions; *p; p = &(*p)->itr_next) - if (*p == transaction) { - *p = transaction->itr_next; - break; - } - ALLI_release((BLK) transaction); -} - - -static void release_sql_request( IPSERVER_ISR stmt) -{ -/************************************** - * - * r e l e a s e _ s q l _ r e q u e s t - * - ************************************** - * - * Functional description - * Release an SQL request block. - * - **************************************/ - IDB idb; - IPSERVER_ISR *p; - - - idb = stmt->isr_idb; - for (p = &idb->idb_sql_requests; *p; p = &(*p)->isr_next) - if (*p == stmt) { - *p = stmt->isr_next; - break; - } - if (stmt->isr_packed) - ALLI_free((UCHAR *) stmt->isr_packed); - ALLI_release((BLK) stmt); -} - - -static bool send_and_wait( ICC icc) -{ -/************************************** - * - * s e n d _ a n d _ w a i t - * - ************************************** - * - * Functional description - * This function starts the server by releasing - * its semaphore, and then waits for the server's - * response by waiting on the client's semaphore. - * - **************************************/ - DWORD result; - -// dead server means no point in sending - - if (icc->icc_flags & ICCF_SERVER_SHUTDOWN) - return false; - -/* first, signal the server that the communications - area in mapped memory is filed and ready */ - - if (!ReleaseSemaphore(icc->icc_server_sem, 1L, NULL)) - return false; - -// next, wait for the server to signal us back or die - - THREAD_EXIT(); - result = - WaitForMultipleObjects((DWORD) 2, icc->icc_waits, FALSE, INFINITE); - THREAD_ENTER(); - - if (result != WAIT_OBJECT_0) { - icc->icc_flags |= ICCF_UNMAP_CLIENT; - return false; - } - - return true; -} - - -static void server_shutdown(void) -{ -/************************************** - * - * s e r v e r _ s h u t d o w n - * - ************************************** - * - * Functional description - * Server shutdown detected, so mark - * everything and release handles. - * - **************************************/ - ICC icc; - IPM ipm; - IDB idb; - - - // for each icc structure, shut it and its database - - for (icc = client_threads; icc; icc = icc->icc_next) { - icc->icc_flags |= ICCF_SERVER_SHUTDOWN; - - // free up semaphores - - if (icc->icc_client_sem) - CloseHandle(icc->icc_client_sem); - if (icc->icc_server_sem) - CloseHandle(icc->icc_server_sem); - if (icc->icc_server_proc) - CloseHandle(icc->icc_server_proc); - icc->icc_client_sem = 0; - icc->icc_server_sem = 0; - icc->icc_server_proc = 0; - - // mark databases - - for (idb = icc->icc_databases; idb; idb = idb->idb_next) - idb->idb_flags |= IDBF_SERVER_SHUTDOWN; - } - - // unmap all mapped files - - for (ipm = client_maps; ipm; ipm = ipm->ipm_next) { - ipm->ipm_flags |= IPMF_SERVER_SHUTDOWN; - UnmapViewOfFile(ipm->ipm_address); - CloseHandle(ipm->ipm_handle); - ipm->ipm_handle = 0; - } -} - - -static THREAD_ENTRY_DECLARE server_watcher(THREAD_ENTRY_PARAM) -{ -/************************************** - * - * s e r v e r _ w a t c h e r - * - ************************************** - * - * Functional description - * This thread just waits for the server - * process. If that process goes away, - * this gets triggered and unmaps any - * currently mapped maps. - * - **************************************/ - DWORD result; - - - for (;;) { - if (exit_flag) - break; - result = WaitForSingleObject(server_process_handle, INFINITE); - if (result == WAIT_OBJECT_0) { - - // unmap and close all maps - - THD_mutex_lock(&mapsect); - server_shutdown(); - THD_mutex_unlock(&mapsect); - server_process_handle = 0; - CloseHandle(server_watcher_handle); - server_watcher_handle = 0; - break; - } - } - return 0; -} - - -static bool unpack_strings( ICC icc) -{ -/************************************** - * - * u n p a c k _ s t r i n g s - * - ************************************** - * - * Functional description - * Unpack all buffers from comm area to user's - * address space. Note that this may require - * multiple send/receive operations to get all - * the data across. - * - **************************************/ - USHORT i; - ips_comm_area *comm; - ips_string *string; - TEXT *acursor, *ccursor; - ULONG to_copy; - - - comm = (ips_comm_area *) icc->icc_mapped_addr; - for (i = 0; i < MAX_IPS_STRINGS; i++) { - string = &comm->ips_buffers[i]; - - // see if this buffer needs extraction - - if (string->ips_flags & IPS_OUTPUT_BUFFER && string->ips_cl_size) { - string->ips_cl_copied = 0; - ccursor = reinterpret_cast < char *>(string->ips_cl_addr); - - // start extraction - - while (string->ips_cl_copied < string->ips_cl_size) { - - // extract all or whatever's available - - to_copy = string->ips_cl_size - string->ips_cl_copied; - if (string->ips_com_size <= to_copy) - to_copy = string->ips_com_size; - acursor = (TEXT *) comm->ips_data + string->ips_com_offset; - memcpy(ccursor, acursor, (USHORT) to_copy); - ccursor += to_copy; - string->ips_cl_copied += to_copy; - - // if there is more to copy, wait for it - - if (string->ips_cl_copied < string->ips_cl_size) - if (!send_and_wait(icc)) - return false; - } - } - } - return true; -} - - -void IPC_process_event( - DWORD eventID, DWORD event_length, LPVOID event_string) -{ -/************************************** - * - * I P C _ p r o c e s s _ e v e n t s - * - ************************************** - * - * Functional description - * Process an event. This looks the event up by - * its id and executes the ast with the argument - * and the event string. - * - **************************************/ - EVENTQ queued; - - - // allocate a queued event structure, fill it and link it - - THD_mutex_lock(&evtsect); - queued = (EVENTQ) ALLI_alloc(sizeof(struct eventq) + event_length); - if (queued) { - memcpy(queued->evq_string, event_string, event_length); - queued->evq_length = (USHORT) event_length; - queued->evq_id = eventID; - queued->evq_next = NULL; - if (!event_head) { - event_head = queued; - event_tail = queued; - } - else { - event_tail->evq_next = queued; - event_tail = queued; - } - } - THD_mutex_unlock(&evtsect); - ReleaseSemaphore(event_semaphore, 1L, NULL); -} - - -void IPC_release_all(void) -{ -/************************************** - * - * I P C _ r e l e a s e _ a l l - * - ************************************** - * - * Functional description - * Release all connections and dependant stuff. - * - **************************************/ - ICC icc, nicc; - IPM ipm, nipm; - IDB idb, nidb; - ITR itr, nitr; - IBL ibl, nibl; - IRQ irq, nirq; - IPSERVER_ISR isr, nisr; - IVNT ivnt, nivnt; - EVENTQ event, nevent; - ips_comm_area *comm; - - - // get stuff to release and clear list heads - - exit_flag++; - if (exit_flag > 1) - return; - icc = client_threads; - nicc = icc; - client_threads = NULL; - ipm = client_maps; - client_maps = NULL; - - // cause event threads to shut down - - if (event_window) { - PostMessage(event_window, WM_CLOSE, 0, 0); - event_window = 0; - } - if (event_semaphore) { - ReleaseSemaphore(event_semaphore, 1L, NULL); - CloseHandle(event_semaphore); - event_semaphore = 0; - } - if (event_packer_handle) { - TerminateThread(event_packer_handle, 0); - CloseHandle(event_packer_handle); - event_packer_handle = 0; - } - if (event_thread_handle) { - TerminateThread(event_thread_handle, 0); - CloseHandle(event_thread_handle); - event_thread_handle = 0; - } - if (server_watcher_handle) { - TerminateThread(server_watcher_handle, 0); - CloseHandle(server_watcher_handle); - server_watcher_handle = 0; - } - - // release queued event structures - - event = event_head; - event_head = NULL; - event_tail = NULL; - for (; event; event = nevent) { - nevent = event->evq_next; - ALLI_free((UCHAR *) event); - } - - // disconnect each thread - - for (; icc; icc = icc->icc_next) { - if (!(icc->icc_flags & ICCF_SERVER_SHUTDOWN)) { - comm = (ips_comm_area *) icc->icc_mapped_addr; - comm->ips_operation = op_disconnect; - ReleaseSemaphore(icc->icc_server_sem, 1L, NULL); - } - } - icc = nicc; - - // for each icc structure, release its database and close it down - - for (; icc; icc = nicc) { - nicc = icc->icc_next; - - // free up semaphores - - if (icc->icc_client_sem) - CloseHandle(icc->icc_client_sem); - if (icc->icc_server_sem) - CloseHandle(icc->icc_server_sem); - if (icc->icc_server_proc) - CloseHandle(icc->icc_server_proc); - - // free up dependant data structures - - for (idb = icc->icc_databases; idb; idb = nidb) { - nidb = idb->idb_next; - for (ivnt = idb->idb_events; ivnt; ivnt = nivnt) { - nivnt = ivnt->ivnt_next; - ALLI_release((BLK) ivnt); - } - for (irq = idb->idb_requests; irq; irq = nirq) { - nirq = irq->irq_next; - ALLI_release((BLK) irq); - } - for (isr = idb->idb_sql_requests; isr; isr = nisr) { - nisr = isr->isr_next; - if (isr->isr_packed) - ALLI_free((UCHAR *) isr->isr_packed); - ALLI_release((BLK) isr); - } - for (itr = idb->idb_transactions; itr; itr = nitr) { - nitr = itr->itr_next; - for (ibl = itr->itr_blobs; ibl; ibl = nibl) { - nibl = ibl->ibl_next; - ALLI_release((BLK) ibl); - } - ALLI_release((BLK) itr); - } - ALLI_release((BLK) idb); - } - ALLI_release((BLK) icc); - } - - // unmap all mapped files - - for (; ipm; ipm = nipm) { - nipm = ipm->ipm_next; - if (!(ipm->ipm_flags & IPMF_SERVER_SHUTDOWN)) { - UnmapViewOfFile(ipm->ipm_address); - CloseHandle(ipm->ipm_handle); - } - ALLI_free((UCHAR *) ipm); - } - if (initialized) { - initialized = false; - } -} - - diff --git a/src/ipserver/ipevt_proto.h b/src/ipserver/ipevt_proto.h deleted file mode 100644 index 8e49acb5f7..0000000000 --- a/src/ipserver/ipevt_proto.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * PROGRAM: JRD Access Method - * MODULE: ipevt_proto.h - * DESCRIPTION: Prototype header file for ipcevent.cpp - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - - -#ifndef IPEVT_PROTO_H -#define IPEVT_PROTO_H - -int IPC_window_init(char*, char*, HWND*, HANDLE); - -#endif /* IPEVT_PROTO_H */ - diff --git a/src/ipserver/ips.h b/src/ipserver/ips.h deleted file mode 100644 index 6a92ddc900..0000000000 --- a/src/ipserver/ips.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * PROGRAM: Interprocess Interface definitions - * MODULE: ips.h - * DESCRIPTION: Common descriptions - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -#ifndef IPSERVER_IPS_H -#define IPSERVER_IPS_H - -#define IPI_CONNECT_MESSAGE WM_USER + 1 - -#endif /* IPSERVER_IPS_H */ - diff --git a/src/ipserver/ipserver.cpp b/src/ipserver/ipserver.cpp deleted file mode 100644 index 5500a49d34..0000000000 --- a/src/ipserver/ipserver.cpp +++ /dev/null @@ -1,4115 +0,0 @@ -/* - * PROGRAM: Interprocess Interface server - * MODULE: ipserver.cpp - * DESCRIPTION: interprocess interface server - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -#include "firebird.h" -#include -#include -#include -#include - -#include "../ipserver/ipc.h" -#include "../jrd/license.h" -#include "../jrd/ibase.h" -#include "../jrd/gds_proto.h" -#include "../ipserver/alli_proto.h" -#include "../jrd/thd.h" -#include "../ipserver/ipsrv_proto.h" -#include "../ipserver/ips.h" -#include "../jrd/isc_proto.h" -#include "../jrd/sch_proto.h" -#include "../jrd/why_proto.h" -#include "../common/config/config.h" -#include "../jrd/gdsassert.h" - -static void allocate_statement(ICC); -static void attach_database(ICC, P_OP); -static void cancel_events(ICC); -static USHORT check_statement_type(IPSERVER_ISR); -static void compile(ICC); -static void ddl(ICC); -static void drop_database(ICC); -static void end_blob(ICC, P_OP); -static void end_database(ICC); -static void end_request(ICC); -static void end_statement(ICC); -static void end_transaction(ICC, P_OP); -static void event_ast(void*, USHORT, const UCHAR*); -static void execute_immediate(ICC, P_OP); -static void execute_statement(ICC, P_OP); -static void fetch(ICC); -static UCHAR *get_buffer(IPS, USHORT, USHORT); -static void get_segment(ICC); -static void get_slice(ICC); -static void info(ICC, P_OP); -static void insert(ICC); -static void ipi_end_thread(ICC); -static void ipi_server(ICC); -static IPM make_map(USHORT); -static ITR make_transaction(IDB, FB_API_HANDLE); -static void open_blob(ICC, P_OP); -static void prepare_statement(ICC); -static void put_segment(ICC); -static void put_slice(ICC); -static void que_events(ICC); -static void receive_msg(ICC); -static void reconnect(ICC); -static void release_blob(IBL); -static void release_event(IVNT); -static void release_request(IRQ); -static void release_sql_request(IPSERVER_ISR); -static void release_transaction(ITR); -static void seek_blob(ICC); -static bool send_and_wait(ICC); -static void send_msg(ICC); -static void send_no_wait(ICC); -static void send_response(ICC, ISC_STATUS *); -static void set_cursor(ICC); -static void service_attach(ICC); -static void service_end(ICC); -static void service_start(ICC); -static void shutdown_attachments(ICC); -static void start(ICC); -static void start_and_send(ICC); -static void start_transaction(ICC); -static void transact_request(ICC); -static bool transfer_buffers(ICC, ips_comm_area *); -static void unwind(ICC); -static bool wait_no_send(ICC); - -static HWND IPSVR_window = NULL; -static const UCHAR sql_info[] = { isc_info_sql_batch_fetch }; - -/* Macro to check a given handle for validity. While generally - * we can depend on the client-side remote library to do this - * for us, there were bugs due to not checking on our side. - * Also, since these handles are passed though to - * the why-value routines and checked there, strictly speaking - * we only have to check ones that we dereference before - * passing along. For safety's side, we check them all. - */ - -/* h = handle to check - * t = type of handle to expect - * c = error code to return - */ -#define CHECK_HANDLE(h,t,c) if ( !(h) || (((BLK) (h))->blk_type !=( t))) \ - { \ - status_vector[0] = isc_arg_gds;\ - status_vector[1] = (c);\ - status_vector[2] = isc_arg_end;\ - send_response( icc, status_vector); \ - return; \ - } - -#define NOT_NULL(p,s) if ( !(p) && (s)) \ - { \ - status_vector[0] = isc_arg_gds;\ - status_vector[1] = isc_virmemexh;\ - status_vector[2] = isc_arg_end;\ - send_response( icc, status_vector); \ - return; \ - } - -#define GET_COMM_OBJECT { comm = (ips_comm_area*)icc->icc_mapped_addr;\ - comm_ptr = (TEXT*)comm->ips_data;} - -#define IPS_SERVER(c,n,a,s) { c->ips_buffers[n].ips_sv_size = s;\ - c->ips_buffers[n].ips_sv_addr = a;\ - c->ips_buffers[n].ips_sv_copied = 0;} - - - -#define GDS_ATTACH_DATABASE isc_attach_database -#define GDS_BLOB_INFO isc_blob_info -#define GDS_CANCEL_BLOB isc_cancel_blob -#define GDS_CANCEL_EVENTS isc_cancel_events -#define GDS_CLOSE_BLOB isc_close_blob -#define GDS_COMMIT isc_commit_transaction -#define GDS_COMMIT_RETAINING isc_commit_retaining -#define GDS_COMPILE isc_compile_request -#define GDS_CREATE_BLOB isc_create_blob -#define GDS_CREATE_BLOB2 isc_create_blob2 -#define GDS_CREATE_DATABASE isc_create_database -#define GDS_DATABASE_INFO isc_database_info -#define GDS_DDL isc_ddl -#define GDS_DETACH isc_detach_database -#define GDS_DROP_DATABASE isc_drop_database -#define GDS_GET_SEGMENT isc_get_segment -#define GDS_GET_SLICE isc_get_slice -#define GDS_OPEN_BLOB isc_open_blob -#define GDS_OPEN_BLOB2 isc_open_blob2 -#define GDS_PREPARE isc_prepare_transaction -#define GDS_PREPARE2 isc_prepare_transaction2 -#define GDS_PUT_SEGMENT isc_put_segment -#define GDS_PUT_SLICE isc_put_slice -#define GDS_QUE_EVENTS isc_que_events -#define GDS_RECONNECT isc_reconnect_transaction - -#ifdef SCROLLABLE_CURSORS -#define GDS_RECEIVE isc_receive2 -#else -#define GDS_RECEIVE isc_receive -#endif - -#define GDS_RELEASE_REQUEST isc_release_request -#define GDS_REQUEST_INFO isc_request_info -#define GDS_ROLLBACK isc_rollback_transaction -#define GDS_ROLLBACK_RETAINING isc_rollback_retaining -#define GDS_SEEK_BLOB isc_seek_blob -#define GDS_SEND isc_send -#define GDS_SERVICE_ATTACH isc_service_attach -#define GDS_SERVICE_DETACH isc_service_detach -#define GDS_SERVICE_QUERY isc_service_query -#define GDS_SERVICE_START isc_service_start -#define GDS_START_AND_SEND isc_start_and_send -#define GDS_START isc_start_request -#define GDS_START_MULTIPLE isc_start_multiple -#define GDS_START_TRANSACTION isc_start_transaction -#define GDS_TRANSACT_REQUEST isc_transact_request -#define GDS_TRANSACTION_INFO isc_transaction_info -#define GDS_UNWIND isc_unwind_request - -#define GDS_DSQL_ALLOCATE isc_dsql_allocate_statement -#define GDS_DSQL_EXECUTE isc_dsql_execute2_m -#define GDS_DSQL_EXECUTE_IMMED isc_dsql_exec_immed3_m -#define GDS_DSQL_FETCH isc_dsql_fetch_m -#define GDS_DSQL_FREE isc_dsql_free_statement -#define GDS_DSQL_INSERT isc_dsql_insert_m -#define GDS_DSQL_PREPARE isc_dsql_prepare_m -#define GDS_DSQL_SET_CURSOR isc_dsql_set_cursor_name -#define GDS_DSQL_SQL_INFO isc_dsql_sql_info - -// -// TMN: -// -// Static data ahead. -// -// But the multithread-wizard said: -// - Let there be light. Move static data into specific instances. -// Let these instances be one per thread, and there will be rejoicing -// among your followers again... Currently we don't use thread-specific -// data here, but putting it in a struct is a step. -// -struct ipserver_private_data_t -{ - IPM first_ipm; - IPM ipms; - MUTX_T ipics; - USHORT pages_per_user; - USHORT users_per_map; - // TMN: num_maps was never used, why I patched it with comments. - // If anyone can shed some light as to why this was added in the - // first place it would be appreciated. -// USHORT num_maps; -}; - -static ipserver_private_data_t ipserver_private_data = -{ - 0, // first_ipm - 0, // ipms - { 0 }, // ipics - DON'T REMOVE THE BRACES! - IPS_DEF_PAGES_PER_CLI, // pages_per_user - IPS_DEF_NUM_CLI // users_per_map -}; - - -#ifdef DEBUG_IP_TRACE -static const char* op_strings[] = -{ - "op_attach", - "op_create", - "op_detach", - "op_compile", - "op_start", - "op_start_and_send", - "op_send", - "op_receive", - "op_unwind", - "op_release", - "op_transaction", - "op_commit", - "op_rollback", - "op_reconnect", - "op_create_blob", - "op_open_blob", - "op_get_segment", - "op_put_segment", - "op_cancel_blob", - "op_close_blob", - "op_info_database", - "op_info_request", - "op_info_transaction", - "op_info_blob", - "op_prepare2", - "op_commit_retaining", - "op_rollback_retaining", - "op_open_blob2", - "op_create_blob2", - "op_ddl", - "op_que_events", - "op_cancel_events", - "op_put_slice", - "op_get_slice", - "op_seek_blob", - "op_allocate_stmt", - "op_execute", - "op_exec_immediate", - "op_fetch", - "op_free_stmt", - "op_prepare_stmt", - "op_set_cursor", - "op_info_sql", - "op_insert", - "op_execute2", - "op_exec_immediate2", - "op_service_attach", - "op_service_detach", - "op_service_info", - "op_service_start", - "op_transact_request", - "op_drop_database", - "op_ping", - "op_disconnect" -}; -#endif - - -#if defined(SUPERSERVER) && defined(WIN_NT) -extern "C" { - static void atexit_close_handles() - { - IPM pFirstIpm = ipserver_private_data.first_ipm; - for (IPM pIpm = pFirstIpm; pIpm; pIpm = pIpm->ipm_next) - { - if (pIpm->ipm_address) { - UnmapViewOfFile(pIpm->ipm_address); - pIpm->ipm_address = 0; - } - if (pIpm->ipm_handle) { - CloseHandle(pIpm->ipm_handle); - pIpm->ipm_handle = 0; - } - } - } -} -#endif // SUPERSERVER && WIN_NT - - -USHORT IPS_init(HWND hwnd, - USHORT usrs_pr_mp, - USHORT pgs_pr_usr, - USHORT mx_mps) -{ -/************************************** - * - * I P S _ i n i t - * - ************************************** - * - * Functional description - * Create a critical section structure and init - * the mapped file stuff. Returns 1 if successful - * and 0 otherwise. - * - **************************************/ - - // init the limits - - if (usrs_pr_mp && - usrs_pr_mp >= IPS_MIN_NUM_CLI && - usrs_pr_mp <= IPS_MAX_NUM_CLI) - { - ipserver_private_data.users_per_map = usrs_pr_mp; - } - if (pgs_pr_usr && - pgs_pr_usr >= IPS_MIN_PAGES_PER_CLI && - pgs_pr_usr <= IPS_MAX_PAGES_PER_CLI) - { - ipserver_private_data.pages_per_user = pgs_pr_usr; - } - -// TMN: Disabled code. See definition of the struct above for comments. -// if (mx_mps && mx_mps >= IPS_MIN_NUM_MAPS && mx_mps <= IPS_MAX_NUM_MAPS) { -// ipserver_private_data.num_maps = mx_mps; -// } - - // init mapped chain and critical regions - - ipserver_private_data.ipms = NULL; - THD_mutex_init(&ipserver_private_data.ipics); - IPSVR_window = hwnd; - - /* create the first map (failure means it's already there */ - - IPM ipm = make_map(0); - - if (ipm && (ipm != (IPM) - 1)) - { - fb_assert(!ipserver_private_data.first_ipm); - ipserver_private_data.first_ipm = ipm; -#if defined(SUPERSERVER) && defined(WIN_NT) - // TMN: 2003-03-11: Close the handles at server shutdown - // Possibly this is also needed for CS, but since I can't test that - // I decided to only do it for SS. - atexit(&atexit_close_handles); -#endif - return (USHORT) 1; - } - - return (USHORT)(ULONG) ipm; -} - - -ULONG IPS_start_thread(ULONG client_pid) -{ -/************************************** - * - * I P S _ s t a r t _ t h r e a d - * - ************************************** - * - * Functional description - * Start an interprocess thread. This allocates - * the next available chunk of the mapped file and - * tells the client where it is. - * - **************************************/ - ICC icc; - USHORT mapped_area, mapped_position; - TEXT name_buffer[128]; - IPM ipm; - USHORT i, j; - UCHAR *p; - HANDLE server_proc; - ips_comm_area *comm; - - - // go through list of maps - - THD_mutex_lock(&ipserver_private_data.ipics); - j = 0; - for (ipm = ipserver_private_data.ipms; ipm; ipm = ipm->ipm_next) - { - // find an available unused comm area - - for (i = 0; i < ipserver_private_data.users_per_map; i++) - { - if (!ipm->ipm_ids[i]) - { - break; - } - } - if (i < ipserver_private_data.users_per_map) - { - ipm->ipm_count++; - ipm->ipm_ids[i]++; - j = ipm->ipm_number; - break; - } - j++; - } - - /* if the mapped file structure has not yet been initialized, - make one now */ - - if (!ipm) - { - - // allocate new map file and first slot - - ipm = make_map(j); - - // check for errors in creation of mapped file - - if (!ipm || ipm == (IPM) - 1) - { - THD_mutex_unlock(&ipserver_private_data.ipics); - return (ULONG) - 1; - } - i = 0; - ipm->ipm_ids[0]++; - ipm->ipm_count++; - } - mapped_area = j; - mapped_position = i; - - // allocate a communications control structure and fill it in - - icc = (ICC) ALLOC(type_icc); - if (!icc) - { - THD_mutex_unlock(&ipserver_private_data.ipics); - return (ULONG) - 1; - } - p = (UCHAR *) ipm->ipm_address; - p += IPS_MAPPED_FOR_CLI(ipserver_private_data.pages_per_user, mapped_position); - memset(p, (char) 0, IPS_MAPPED_PER_CLI(ipserver_private_data.pages_per_user)); - icc->icc_mapped_addr = reinterpret_cast(p); - icc->icc_ipm = ipm; - icc->icc_slot = mapped_position; - icc->icc_flags = 0; - icc->icc_client_id = (DWORD) client_pid; - icc->icc_client_proc = - OpenProcess(PROCESS_ALL_ACCESS, TRUE, icc->icc_client_id); - comm = (ips_comm_area *) icc->icc_mapped_addr; - comm->ips_client_id = icc->icc_client_id; - comm->ips_client_proc = icc->icc_client_proc; - comm->ips_server_id = GetCurrentProcessId(); - - // make sure client knows what this server speaks - - comm->ips_server_protocol = 1L; - comm->ips_client_protocol = 0L; - - // Duplicate the server process handle for client synchronization - if (!DuplicateHandle(GetCurrentProcess(), - GetCurrentProcess(), - GetCurrentProcess(), - &server_proc, PROCESS_ALL_ACCESS, FALSE, 0)) - { - CHAR szBuf[80]; - DWORD dw = GetLastError(); - - sprintf(szBuf, "%s:%s failed: GetLastError returned %lu\n", - "ipserver.c", "DuplicateHandle(server_proc)", dw); - gds__log(szBuf); - } - if (!DuplicateHandle(server_proc, - server_proc, - comm->ips_client_proc, - &comm->ips_server_proc, SYNCHRONIZE, FALSE, 0)) - { - CHAR szBuf[80]; - DWORD dw = GetLastError(); - - sprintf(szBuf, "%s:%s failed: GetLastError returned %lu\n", - "ipserver.c", "DuplicateHandle(ips_server_proc)", dw); - gds__log(szBuf); - comm->ips_server_proc = 0; - } - - CloseHandle(server_proc); - - // create the semaphores and put the handles into the icc - - sprintf(name_buffer, IPI_CLIENT_SEM_NAME, Config::getIpcName(), - mapped_area, mapped_position); - icc->icc_client_sem = - CreateSemaphore(ISC_get_security_desc(), 0L, 1L, name_buffer); - sprintf(name_buffer, IPI_SERVER_SEM_NAME, Config::getIpcName(), - mapped_area, mapped_position); - icc->icc_server_sem = - CreateSemaphore(ISC_get_security_desc(), 0L, 1L, name_buffer); - - // make sure semaphores are "empty" - - while (WaitForSingleObject(icc->icc_client_sem, (DWORD) 1) == - WAIT_OBJECT_0); - while (WaitForSingleObject(icc->icc_server_sem, (DWORD) 1) == - WAIT_OBJECT_0); - - // initialize wait for multiple objects array - - icc->icc_waits[0] = icc->icc_server_sem; - icc->icc_waits[1] = icc->icc_client_proc; - - // finally, start the thread for this client - - gds__thread_start(ipi_server, icc, THREAD_medium, 0, 0); - - // return combined mapped area and number - -#ifdef DEBUG_IP_TRACE - gds__log("ipserver icc %8lX, comm %8lX", icc, comm); -#endif - - THD_mutex_unlock(&ipserver_private_data.ipics); - return IPS_PACK_PARAMS(ipserver_private_data.users_per_map, ipserver_private_data.pages_per_user, mapped_area, - mapped_position); -} - - -static void ipi_end_thread( ICC icc) -{ -/************************************** - * - * i p i _ e n d _ t h r e a d - * - ************************************** - * - * Functional description - * End a thread's existence, close its handles, - * free its slot and whatnot. - * - **************************************/ - - // free up this thread's slot - - IPM ipm = icc->icc_ipm; - THD_mutex_lock(&ipserver_private_data.ipics); - ipm->ipm_ids[icc->icc_slot] = 0; - ipm->ipm_count--; - - /* if last slot was emptied, unmap and free structure, except - for the first map, which is always retained */ - - if (!ipm->ipm_count && ipm != ipserver_private_data.first_ipm) - { - if (ipm->ipm_address) { - UnmapViewOfFile(ipm->ipm_address); - ipm->ipm_address = 0; - } - if (ipm->ipm_handle) { - CloseHandle(ipm->ipm_handle); - ipm->ipm_handle = 0; - } - - if (ipserver_private_data.ipms == ipm) { - ipserver_private_data.ipms = ipm->ipm_next; - } - else { - for (IPM pipm = ipserver_private_data.ipms; - pipm->ipm_next; - pipm = pipm->ipm_next) - { - if (pipm->ipm_next == ipm) - { - pipm->ipm_next = ipm->ipm_next; - break; - } - } - } - ALLI_free((UCHAR *) ipm); - } - - // close handles for semaphores - - CloseHandle(icc->icc_client_sem); - CloseHandle(icc->icc_server_sem); - CloseHandle(icc->icc_client_proc); - ALLI_release((BLK) icc); - THD_mutex_unlock(&ipserver_private_data.ipics); -} - - -static void ipi_server( ICC icc) -{ -/************************************** - * - * i p i _ s e r v e r - * - ************************************** - * - * Functional description - * Main entrypoint of server. - * - **************************************/ - ips_comm_area *comm; - TEXT *comm_ptr; - - // start this thread - - gds__thread_enable(-1); - - // error handler - - try { - - // request processing loop - - while (!(icc->icc_flags & ICCF_SHUTDOWN)) - { - if (!wait_no_send(icc)) - break; - GET_COMM_OBJECT; - comm->ips_ops_count++; -#ifdef DEBUG_IP_TRACE - { - char line[200]; - sprintf(line, "%8lX %8lX %8lX %d ipserver %s", - (long) GetCurrentThreadId(), (long) icc, - comm, comm->ips_operation, op_strings[comm->ips_operation]); - gds__log(line); - } -#endif - switch (comm->ips_operation) - { - case op_attach: - case op_create: - attach_database(icc, static_cast(comm->ips_operation)); - break; - - case op_cancel_events: - cancel_events(icc); - break; - - case op_compile: - compile(icc); - break; - - case op_ddl: - ddl(icc); - break; - - case op_receive: - receive_msg(icc); - break; - - case op_seek_blob: - seek_blob(icc); - break; - - case op_send: - send_msg(icc); - break; - - case op_start: - start(icc); - break; - - case op_start_and_send: - start_and_send(icc); - break; - - case op_transact_request: - transact_request(icc); - break; - - case op_transaction: - start_transaction(icc); - break; - - case op_rollback: - case op_commit: - case op_commit_retaining: - case op_rollback_retaining: - case op_prepare2: - end_transaction(icc, static_cast < P_OP > (comm->ips_operation)); - break; - - case op_detach: - end_database(icc); - break; - - case op_drop_database: - drop_database(icc); - break; - - case op_create_blob: - case op_open_blob: - case op_create_blob2: - case op_open_blob2: - open_blob(icc, static_cast < P_OP > (comm->ips_operation)); - break; - - case op_put_segment: - put_segment(icc); - break; - - case op_get_segment: - get_segment(icc); - break; - - case op_cancel_blob: - case op_close_blob: - end_blob(icc, static_cast < P_OP > (comm->ips_operation)); - break; - - case op_release: - end_request(icc); - break; - - case op_que_events: - que_events(icc); - break; - - case op_unwind: - unwind(icc); - break; - - case op_reconnect: - reconnect(icc); - break; - - case op_info_blob: - case op_info_request: - case op_info_database: - case op_info_transaction: - case op_info_sql: - case op_service_info: - info(icc, static_cast < P_OP > (comm->ips_operation)); - break; - - case op_get_slice: - get_slice(icc); - break; - - case op_put_slice: - put_slice(icc); - break; - - case op_allocate_stmt: - allocate_statement(icc); - break; - - case op_execute: - case op_execute2: - execute_statement(icc, - static_cast < P_OP > (comm->ips_operation)); - break; - - case op_exec_immediate: - case op_exec_immediate2: - execute_immediate(icc, - static_cast < P_OP > (comm->ips_operation)); - break; - - case op_fetch: - fetch(icc); - break; - - case op_free_stmt: - end_statement(icc); - break; - - case op_insert: - insert(icc); - break; - - case op_prepare_stmt: - prepare_statement(icc); - break; - - case op_set_cursor: - set_cursor(icc); - break; - - case op_service_attach: - service_attach(icc); - break; - - case op_service_detach: - service_end(icc); - break; - - case op_service_start: - service_start(icc); - break; - - case op_disconnect: - icc->icc_flags |= ICCF_SHUTDOWN; - break; - - default: - gds__log("Interprocess Server op code %d unknown\n", - (int *)(ULONG) comm->ips_operation); - icc->icc_flags |= ICCF_SHUTDOWN; - break; - } - } - - // left loop, so shut down - - shutdown_attachments(icc); - ipi_end_thread(icc); - - } // try - catch (const std::exception&) { - gds__log("ipi_server: error during startup, shutting down"); - } -} - - -static void allocate_statement( ICC icc) -{ -/************************************** - * - * a l l o c a t e _ s t a t e m e n t - * - ************************************** - * - * Functional description - * Allocate a statement handle. - * - **************************************/ - IDB idb; - IPSERVER_ISR statement; - FB_API_HANDLE handle; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - ips_dsql *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_dsql; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - handle = NULL; - - // allocate the statement and create a structure - - result = GDS_DSQL_ALLOCATE(status_vector, &idb->idb_handle, &handle); - if (!result) - { - statement = (IPSERVER_ISR) ALLOC(type_ipserver_isr); - ips->ips_st_handle = (UCHAR *) statement; - NOT_NULL(statement, TRUE); - statement->isr_handle = handle; - statement->isr_idb = idb; - statement->isr_next = idb->idb_sql_requests; - statement->isr_batch_flag = 0; - statement->isr_max_recs = 0; - statement->isr_packed = NULL; - idb->idb_sql_requests = statement; - } - else { - ips->ips_st_handle = NULL; - } - send_response(icc, status_vector); -} - - -static void attach_database( ICC icc, P_OP operation) -{ -/************************************** - * - * a t t a c h _ d a t a b a s e - * - ************************************** - * - * Functional description - * Process an attach or create packet. - * - **************************************/ - USHORT dpb_length, expanded_length; - UCHAR file_buf[256], *dpb, dpb_buf[256]; - UCHAR *expanded, expanded_buf[256]; - FB_API_HANDLE handle; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - IDB idb; - ips_object *ips; - ips_string *ips_name; - ips_string *ips_dpb; - ips_string *ips_expanded; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - - // figure out file name buffer - - ips_name = &comm->ips_buffers[IPS_ATTACH_NAME]; - const USHORT file_length = (USHORT) ips_name->ips_cl_size; - const UCHAR* file_name; - if (file_length <= sizeof(file_buf)) - file_name = file_buf; - else - file_name = get_buffer(comm, file_length, IPS_ATTACH_NAME); - NOT_NULL(file_name, TRUE); - IPS_SERVER(comm, IPS_ATTACH_NAME, file_name, file_length); - - // figure out dpb buffer - - ips_dpb = &comm->ips_buffers[IPS_ATTACH_DPB]; - dpb_length = (USHORT) ips_dpb->ips_cl_size; - if (dpb_length <= sizeof(dpb_buf)) - dpb = dpb_buf; - else - dpb = get_buffer(comm, dpb_length, IPS_ATTACH_DPB); - NOT_NULL(dpb, dpb_length); - IPS_SERVER(comm, IPS_ATTACH_DPB, dpb, dpb_length); - - // figure out expanded file name buffer - - ips_expanded = &comm->ips_buffers[IPS_ATTACH_EXPANDED]; - expanded_length = (USHORT) ips_expanded->ips_cl_size; - if (expanded_length <= sizeof(expanded_buf)) - expanded = expanded_buf; - else - expanded = get_buffer(comm, expanded_length, IPS_ATTACH_EXPANDED); - NOT_NULL(expanded, expanded_length); - IPS_SERVER(comm, IPS_ATTACH_EXPANDED, expanded, expanded_length); - if (!transfer_buffers(icc, comm)) - return; - - // get handle - - handle = NULL; - if (operation == op_attach) - result = GDS_ATTACH_DATABASE(status_vector, file_length, - reinterpret_cast(file_name), - &handle, dpb_length, - reinterpret_cast(dpb)); - else - result = GDS_CREATE_DATABASE(status_vector, file_length, - reinterpret_cast(file_name), - &handle, dpb_length, - reinterpret_cast(dpb), 0); - - // allocate structure and return handle - - if (!result) - { - idb = (IDB) ALLOC(type_idb); - ips->ips_handle = (UCHAR *) idb; - NOT_NULL(idb, TRUE); - idb->idb_flags = IDBF_DATABASE_ATTACHMENT; - idb->idb_handle = handle; - idb->idb_next = icc->icc_databases; - icc->icc_databases = idb; - } - else - ips->ips_handle = NULL; - send_response(icc, status_vector); -} - - -static void cancel_events( ICC icc) -{ -/************************************** - * - * c a n c e l _ e v e n t s - * - ************************************** - * - * Functional description - * Cancel an outstanding event call. - * - **************************************/ - ISC_STATUS_ARRAY status_vector; - IDB idb; - IVNT event; - SLONG id; - ips_object *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - idb = (IDB) ips->ips_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - id = ips->ips_parameter; - - // perform operation, return response and remove event - - GDS_CANCEL_EVENTS(status_vector, &idb->idb_handle, &id); - for (event = idb->idb_events; event; event = event->ivnt_next) - { - if (event->ivnt_ast && event->ivnt_id == id) - { - event->ivnt_ast = NULL; - event->ivnt_id = 0; - break; - } - } - send_response(icc, status_vector); -} - - -static USHORT check_statement_type( IPSERVER_ISR statement) -{ -/************************************** - * - * c h e c k _ s t a t e m e n t _ t y p e - * - ************************************** - * - * Functional description - * Return the type of SQL statement. - * - **************************************/ - UCHAR buffer[16], *info; - USHORT l, type; - ISC_STATUS_ARRAY local_status; - ISC_STATUS result; - USHORT ret; - bool done; - - - // init to no batch allowed - - ret = 0; - done = false; - result = GDS_DSQL_SQL_INFO(local_status, - &statement->isr_handle, - sizeof(sql_info), - reinterpret_cast(sql_info), - sizeof(buffer), - reinterpret_cast(buffer)); - if (!result) - { - // check the buffer for a batch fetch flag - - for (info = buffer; (*info != isc_info_end) && !done;) - { - l = (USHORT)isc_vax_integer(reinterpret_cast(info + 1), - 2); - type = (USHORT)isc_vax_integer(reinterpret_cast(info + 3), - l); - switch (*info) - { - case isc_info_sql_batch_fetch: - ret = type; - done = true; - break; - - case isc_info_error: - case isc_info_truncated: - done = true; - break; - } - info += 3 + l; - } - } - return ret; -} - - -static void compile( ICC icc) -{ -/************************************** - * - * c o m p i l e - * - ************************************** - * - * Functional description - * Compile a request. - * - **************************************/ - IDB idb; - IRQ request; - USHORT blr_length; - UCHAR *blr; - FB_API_HANDLE handle; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - ips_compile_req *ips; - ips_string *ips_blr; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_compile; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // set up blr buffer - - ips_blr = &comm->ips_buffers[IPS_COMPILE_REQ]; - blr_length = (USHORT) ips_blr->ips_cl_size; - blr = get_buffer(comm, blr_length, IPS_COMPILE_REQ); - NOT_NULL(blr, blr_length); - IPS_SERVER(comm, IPS_COMPILE_REQ, blr, blr_length); - if (!transfer_buffers(icc, comm)) - return; - - // compile and get handle - - handle = NULL; - result = GDS_COMPILE(status_vector, &idb->idb_handle, &handle, - blr_length, reinterpret_cast(blr)); - - // create data structure and return handle - - if (!result) - { - request = (IRQ) ALLOC(type_irq); - ips->ips_rq_handle = (UCHAR *) request; - NOT_NULL(request, TRUE); - request->irq_handle = handle; - request->irq_idb = idb; - request->irq_next = idb->idb_requests; - idb->idb_requests = request; - } - else - ips->ips_rq_handle = NULL; - send_response(icc, status_vector); -} - - -static void ddl( ICC icc) -{ -/************************************** - * - * d d l - * - ************************************** - * - * Functional description - * Pass thru a DDL call. - * - **************************************/ - ISC_STATUS_ARRAY status_vector; - ITR transaction; - IDB idb; - UCHAR *buffer; - USHORT length; - ips_ddl *ips; - ips_string *ips_ddl_string; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_ddl; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = (ITR) ips->ips_tr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // set up ddl buffer - - ips_ddl_string = &comm->ips_buffers[IPS_DDL_DDL]; - length = (USHORT) ips_ddl_string->ips_cl_size; - buffer = get_buffer(comm, length, IPS_DDL_DDL); - NOT_NULL(buffer, length); - IPS_SERVER(comm, IPS_DDL_DDL, buffer, length); - if (!transfer_buffers(icc, comm)) - return; - - // perform operation and return response - - GDS_DDL(status_vector, &idb->idb_handle, &transaction->itr_handle, - length, reinterpret_cast(buffer)); - send_response(icc, status_vector); -} - - -static void drop_database( ICC icc) -{ -/************************************** - * - * d r o p _ d a t a b a s e - * - ************************************** - * - * Functional description - * End a request. - * - **************************************/ - IDB idb, *ptr; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS code; - ips_object *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - idb = (IDB) ips->ips_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // drop database, release resources and send response - - code = GDS_DROP_DATABASE(status_vector, &idb->idb_handle); - send_response(icc, status_vector); - if (!code || (code == isc_drdb_completed_with_errs)) - { - while (idb->idb_events) - release_event(idb->idb_events); - while (idb->idb_requests) - release_request(idb->idb_requests); - while (idb->idb_sql_requests) - release_sql_request(idb->idb_sql_requests); - while (idb->idb_transactions) - release_transaction(idb->idb_transactions); - for (ptr = &icc->icc_databases; *ptr; ptr = &(*ptr)->idb_next) - { - if (*ptr == idb) - { - *ptr = idb->idb_next; - break; - } - } - ALLI_release((BLK) idb); - } -} - - -static void end_blob( ICC icc, P_OP operation) -{ -/************************************** - * - * e n d _ b l o b - * - ************************************** - * - * Functional description - * End a blob. - * - **************************************/ - IBL blob; - ISC_STATUS_ARRAY status_vector; - UCHAR *buffer; - USHORT length; - ips_object *ips; - ips_string *ips_seg; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - blob = (IBL) ips->ips_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - - // set up buffer for last segment, if any - - ips_seg = &comm->ips_buffers[IPS_CLOSE_BLOB_REM]; - length = (USHORT) ips_seg->ips_cl_size; - if (length) - { - buffer = get_buffer(comm, length, IPS_CLOSE_BLOB_REM); - NOT_NULL(buffer, length); - IPS_SERVER(comm, IPS_CLOSE_BLOB_REM, buffer, length); - if (!transfer_buffers(icc, comm)) - return; - } - - // perform operation, send response and free resources - ISC_STATUS result; - if (operation == op_close_blob) - result = GDS_CLOSE_BLOB(status_vector, &blob->ibl_handle); - else - result = GDS_CANCEL_BLOB(status_vector, &blob->ibl_handle); - send_response(icc, status_vector); - if (!result) - release_blob(blob); -} - - -static void end_database( ICC icc) -{ -/************************************** - * - * e n d _ d a t a b a s e - * - ************************************** - * - * Functional description - * End a request. - * - **************************************/ - IDB idb, *ptr; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - ips_object *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - idb = (IDB) ips->ips_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // detach database, send response and free resources - - result = GDS_DETACH(status_vector, &idb->idb_handle); - send_response(icc, status_vector); - if (!result) - { - while (idb->idb_events) - release_event(idb->idb_events); - while (idb->idb_requests) - release_request(idb->idb_requests); - while (idb->idb_sql_requests) - release_sql_request(idb->idb_sql_requests); - while (idb->idb_transactions) - release_transaction(idb->idb_transactions); - for (ptr = &icc->icc_databases; *ptr; ptr = &(*ptr)->idb_next) - { - if (*ptr == idb) - { - *ptr = idb->idb_next; - break; - } - } - ALLI_release((BLK) idb); - } -} - - -static void end_request( ICC icc) -{ -/************************************** - * - * e n d _ r e q u e s t - * - ************************************** - * - * Functional description - * End a request. - * - **************************************/ - IRQ request; - ISC_STATUS_ARRAY status_vector; - ips_object *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - request = (IRQ) ips->ips_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - - // process call, respond and free resources - - GDS_RELEASE_REQUEST(status_vector, &request->irq_handle); - send_response(icc, status_vector); - release_request(request); -} - - -static void end_statement( ICC icc) -{ -/************************************** - * - * e n d _ s t a t e m e n t - * - ************************************** - * - * Functional description - * Free a dynamic statement. - * - **************************************/ - IPSERVER_ISR statement; - USHORT option; - ISC_STATUS_ARRAY status_vector; - ips_object *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - -// set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - statement = (IPSERVER_ISR) ips->ips_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_stmt_handle); - option = (USHORT) ips->ips_parameter; - -// free statement, return response and free resources - - GDS_DSQL_FREE(status_vector, &statement->isr_handle, option); - - if (statement->isr_handle) - { - ips->ips_handle = (UCHAR *) statement; - send_response(icc, status_vector); - } - else - { - ips->ips_handle = NULL; - send_response(icc, status_vector); - release_sql_request(statement); - } -} - - -static void end_transaction( ICC icc, P_OP operation) -{ -/************************************** - * - * e n d _ t r a n s a c t i o n - * - ************************************** - * - * Functional description - * End a transaction. - * - **************************************/ - ITR transaction; - USHORT msg_length; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - ips_object *ips; - ips_string *ips_prep; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - transaction = (ITR) ips->ips_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // set up buffer for prepare2 - - const UCHAR* msg = 0; - if (operation == op_prepare2) - { - ips_prep = &comm->ips_buffers[IPS_PREPARE_TRANS]; - msg_length = (USHORT) ips_prep->ips_cl_size; - msg = get_buffer(comm, msg_length, IPS_PREPARE_TRANS); - NOT_NULL(msg, msg_length); - IPS_SERVER(comm, IPS_PREPARE_TRANS, msg, msg_length); - if (!transfer_buffers(icc, comm)) - return; - } - - // perform operation as required - - switch (operation) - { - case op_commit: - result = GDS_COMMIT(status_vector, &transaction->itr_handle); - if (!result) - release_transaction(transaction); - break; - - case op_rollback: - result = GDS_ROLLBACK(status_vector, &transaction->itr_handle); - if (!result) - release_transaction(transaction); - break; - - case op_commit_retaining: - result = GDS_COMMIT_RETAINING(status_vector, &transaction->itr_handle); - break; - - case op_rollback_retaining: - result = GDS_ROLLBACK_RETAINING(status_vector, &transaction->itr_handle); - break; - - case op_prepare2: - result = GDS_PREPARE2(status_vector, &transaction->itr_handle, - msg_length, msg); - if (!result) - transaction->itr_flags |= ITR_limbo; - break; - } - send_response(icc, status_vector); -} - - -static void event_ast(void* event_void, USHORT length, const UCHAR* data) -{ -/************************************** - * - * e v e n t _ a s t - * - ************************************** - * - * Functional description - * Send off event stuff. - * - **************************************/ - COPYDATASTRUCT cpdata; - ULONG result; - ivnt* event = static_cast(event_void); - - if (!event->ivnt_ast) - return; - cpdata.dwData = (DWORD) event->ivnt_id; - cpdata.cbData = (DWORD) length; - cpdata.lpData = (LPVOID) data; - result = - SendMessage(event->ivnt_window, WM_COPYDATA, (WPARAM) IPSVR_window, - (LPARAM) & cpdata); - event->ivnt_ast = NULL; -} - - -static void execute_immediate( ICC icc, P_OP operation) -{ -/************************************** - * - * e x e c u t e _ i m m e d i a t e - * - ************************************** - * - * Functional description - * Prepare and execute a statement. - * - **************************************/ - IDB idb; - ITR transaction; - FB_API_HANDLE handle; - USHORT length, dialect, in_blr_length, in_msg_type, in_msg_length, - out_blr_length, out_msg_type, out_msg_length, parser_version; - UCHAR *in_msg, *out_blr, *out_msg; - ISC_STATUS_ARRAY status_vector; - ips_dsql *ips; - ips_string *ips_blr; - ips_string *ips_msg; - ips_string *ips_sql; - ips_string *ips_blr_out; - ips_string *ips_msg_out; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_dsql; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = (ITR) ips->ips_tr_handle; - if (transaction) - { - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - handle = transaction->itr_handle; - } - else - handle = NULL; - in_msg_type = ips->ips_msg_type; - dialect = (USHORT) ips->ips_parameter; - - // set up sql - - ips_sql = &comm->ips_buffers[IPS_DSQL_EXEC_IMMED_SQL]; - length = (USHORT) ips_sql->ips_cl_size; - const UCHAR* string = get_buffer(comm, length, IPS_DSQL_EXEC_IMMED_SQL); - NOT_NULL(string, length); - IPS_SERVER(comm, IPS_DSQL_EXEC_IMMED_SQL, string, length); - - // set up blr - - ips_blr = &comm->ips_buffers[IPS_DSQL_EXEC_IMMED_BLR]; - in_blr_length = (USHORT) ips_blr->ips_cl_size; - const UCHAR* in_blr = get_buffer(comm, in_blr_length, IPS_DSQL_EXEC_IMMED_BLR); - NOT_NULL(in_blr, in_blr_length); - IPS_SERVER(comm, IPS_DSQL_EXEC_IMMED_BLR, in_blr, in_blr_length); - - // set up message - - ips_msg = &comm->ips_buffers[IPS_DSQL_EXEC_IMMED_MSG]; - in_msg_length = (USHORT) ips_msg->ips_cl_size; - in_msg = get_buffer(comm, in_msg_length, IPS_DSQL_EXEC_IMMED_MSG); - NOT_NULL(in_msg, in_msg_length); - IPS_SERVER(comm, IPS_DSQL_EXEC_IMMED_MSG, in_msg, in_msg_length); - - // set up output message and blr if necessary - - if (operation == op_exec_immediate2) - { - out_msg_type = ips->ips_msg_out; - ips_blr_out = &comm->ips_buffers[IPS_DSQL_EXEC_IMMED2_BLR_OUT]; - out_blr_length = (USHORT) ips_blr_out->ips_cl_size; - out_blr = - get_buffer(comm, out_blr_length, IPS_DSQL_EXEC_IMMED2_BLR_OUT); - NOT_NULL(out_blr, out_blr_length); - IPS_SERVER(comm, IPS_DSQL_EXEC_IMMED2_BLR_OUT, out_blr, - out_blr_length); - ips_msg_out = &comm->ips_buffers[IPS_DSQL_EXEC_IMMED2_MSG_OUT]; - out_msg_length = (USHORT) ips_msg_out->ips_cl_size; - out_msg = - get_buffer(comm, out_msg_length, IPS_DSQL_EXEC_IMMED2_MSG_OUT); - NOT_NULL(out_msg, out_msg_length); - IPS_SERVER(comm, IPS_DSQL_EXEC_IMMED2_MSG_OUT, out_msg, - out_msg_length); - } - else - { - out_blr_length = out_msg_type = out_msg_length = 0; - out_blr = out_msg = NULL; - } - if (!transfer_buffers(icc, comm)) - return; - - // NT Local access: Client and server are always the same version - /* Since the API to GDS_DSQL_EXECUTE_IMMED is public and can not be changed, there needs to - * be a way to send the parser version to DSQL so that the parser can compare the keyword - * version to the parser version. To accomplish this, the parser version is combined with - * the client dialect and sent across that way. In dsql8_execute_immediate, the parser version - * and client dialect are separated and passed on to their final desintations. The information - * is combined as follows: - * Dialect * 10 + parser_version - * - * and is extracted in dsql8_execute_immediate as follows: - * parser_version = ((dialect *10)+parser_version)%10 - * client_dialect = ((dialect *10)+parser_version)/10 - * - * For example, parser_version = 1 and client dialect = 1 - * - * combined = (1 * 10) + 1 == 11 - * - * parser = (combined) %10 == 1 - * dialect = (combined) / 19 == 1 - */ - - parser_version = 2; - - // execute the statement, respond and clean up - - GDS_DSQL_EXECUTE_IMMED(status_vector, - &idb->idb_handle, - &handle, - length, - reinterpret_cast(string), - (USHORT) ((dialect * 10) + parser_version), - in_blr_length, - reinterpret_cast(in_blr), - in_msg_type, - in_msg_length, - reinterpret_cast < char *>(in_msg), - out_blr_length, - reinterpret_cast < char *>(out_blr), - out_msg_type, - out_msg_length, - reinterpret_cast < char *>(out_msg)); - if (transaction && !handle) - { - release_transaction(transaction); - transaction = NULL; - } - else if (!transaction && handle) - { - transaction = make_transaction(idb, handle); - NOT_NULL(transaction, TRUE); - } - ips->ips_tr_handle = (UCHAR *) transaction; - send_response(icc, status_vector); -} - - -static void execute_statement( ICC icc, P_OP operation) -{ -/************************************** - * - * e x e c u t e _ s t a t e m e n t - * - ************************************** - * - * Functional description - * Execute a non-SELECT dynamic SQL statement. - * - **************************************/ - ITR transaction; - IPSERVER_ISR statement; - FB_API_HANDLE handle; - USHORT in_blr_length, in_msg_type, in_msg_length, - out_blr_length, out_msg_type, out_msg_length; - UCHAR *in_blr, *in_msg, *out_blr, *out_msg; - ISC_STATUS_ARRAY status_vector; - ips_dsql *ips; - ips_string *ips_blr; - ips_string *ips_msg; - ips_string *ips_blr_out; - ips_string *ips_msg_out; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_dsql; - transaction = (ITR) ips->ips_tr_handle; - if (transaction) - { - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - handle = transaction->itr_handle; - } - else - handle = NULL; - statement = (IPSERVER_ISR) ips->ips_st_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_stmt_handle); - in_msg_type = ips->ips_msg_type; - - // set up blr - - ips_blr = &comm->ips_buffers[IPS_DSQL_EXEC_BLR]; - in_blr_length = (USHORT) ips_blr->ips_cl_size; - in_blr = get_buffer(comm, in_blr_length, IPS_DSQL_EXEC_BLR); - NOT_NULL(in_blr, in_blr_length); - IPS_SERVER(comm, IPS_DSQL_EXEC_BLR, in_blr, in_blr_length); - - // set up message - - ips_msg = &comm->ips_buffers[IPS_DSQL_EXEC_MSG]; - in_msg_length = (USHORT) ips_msg->ips_cl_size; - in_msg = get_buffer(comm, in_msg_length, IPS_DSQL_EXEC_MSG); - NOT_NULL(in_msg, in_msg_length); - IPS_SERVER(comm, IPS_DSQL_EXEC_MSG, in_msg, in_msg_length); - - // set up output message and blr if necessary - - if (operation == op_execute2) - { - out_msg_type = ips->ips_msg_out; - ips_blr_out = &comm->ips_buffers[IPS_DSQL_EXEC2_BLR_OUT]; - out_blr_length = (USHORT) ips_blr_out->ips_cl_size; - out_blr = get_buffer(comm, out_blr_length, IPS_DSQL_EXEC2_BLR_OUT); - NOT_NULL(out_blr, out_blr_length); - IPS_SERVER(comm, IPS_DSQL_EXEC2_BLR_OUT, out_blr, out_blr_length); - ips_msg_out = &comm->ips_buffers[IPS_DSQL_EXEC2_MSG_OUT]; - out_msg_length = (USHORT) ips_msg_out->ips_cl_size; - out_msg = get_buffer(comm, out_msg_length, IPS_DSQL_EXEC2_MSG_OUT); - NOT_NULL(out_msg, out_msg_length); - IPS_SERVER(comm, IPS_DSQL_EXEC2_MSG_OUT, out_msg, out_msg_length); - } - else - { - out_blr_length = out_msg_type = out_msg_length = 0; - out_blr = out_msg = NULL; - } - if (!transfer_buffers(icc, comm)) - return; - - // execute, get results and clean up - - GDS_DSQL_EXECUTE(status_vector, - &handle, - &statement->isr_handle, - in_blr_length, - reinterpret_cast < char *>(in_blr), - in_msg_type, - in_msg_length, - reinterpret_cast < char *>(in_msg), - out_blr_length, - reinterpret_cast < char *>(out_blr), - out_msg_type, - out_msg_length, reinterpret_cast < char *>(out_msg)); - if (transaction && !handle) - { - release_transaction(transaction); - transaction = NULL; - } - else if (!transaction && handle) - { - transaction = make_transaction(statement->isr_idb, handle); - NOT_NULL(transaction, TRUE); - } - ips->ips_tr_handle = (UCHAR *) transaction; - send_response(icc, status_vector); -} - - -static void fetch( ICC icc) -{ -/************************************** - * - * f e t c h - * - ************************************** - * - * Functional description - * Fetch next record from a dynamic SQL cursor. - * - **************************************/ - IPSERVER_ISR statement; - USHORT records, total_length, blr_length, msg_type, msg_length; - ISC_STATUS s; - ISC_STATUS_ARRAY status_vector; - ips_dsql *ips; - ips_string *ips_blr; - ips_string *ips_msg; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_dsql; - statement = (IPSERVER_ISR) ips->ips_st_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_stmt_handle); - msg_type = ips->ips_msg_type; - - // set up blr - - ips_blr = &comm->ips_buffers[IPS_DSQL_FETCH_BLR]; - blr_length = (USHORT) ips_blr->ips_cl_size; - const UCHAR* blr = get_buffer(comm, blr_length, IPS_DSQL_FETCH_BLR); - NOT_NULL(blr, blr_length); - IPS_SERVER(comm, IPS_DSQL_FETCH_BLR, blr, blr_length); - - // set up message - - ips_msg = &comm->ips_buffers[IPS_DSQL_FETCH_MSG]; - total_length = (USHORT) ips_msg->ips_cl_size; - msg_length = total_length / ips->ips_rec_count; - UCHAR* msg = get_buffer(comm, total_length, IPS_DSQL_FETCH_MSG); - NOT_NULL(msg, msg_length); - IPS_SERVER(comm, IPS_DSQL_FETCH_MSG, msg, total_length); - if (!transfer_buffers(icc, comm)) - return; - - // pack in records, keeping final result of operation for eof - - for (records = 0; records < ips->ips_rec_count; records++) - { - s = GDS_DSQL_FETCH(status_vector, - &statement->isr_handle, - blr_length, - reinterpret_cast(blr), - msg_type, - msg_length, reinterpret_cast(msg)); - - // point to next packed record - - msg += msg_length; - if (s) - break; - } - ips->ips_rec_count = records; - ips->ips_parameter = s; - send_response(icc, status_vector); -} - - -static UCHAR *get_buffer( IPS comm, USHORT length, USHORT n) -{ -/************************************** - * - * g e t _ b u f f e r - * - ************************************** - * - * Functional description - * Get a buffer "big enough". - * - **************************************/ - - if (comm->ips_buffers[n].ips_sv_alloced < length) - { - if (comm->ips_buffers[n].ips_sv_buffer) - gds__free(comm->ips_buffers[n].ips_sv_buffer); - comm->ips_buffers[n].ips_sv_alloced = length; - comm->ips_buffers[n].ips_sv_buffer = (UCHAR*)gds__alloc((SLONG) length); - } - - // Make sure that the buffer returned is empty - if (comm->ips_buffers[n].ips_sv_buffer) - memset(comm->ips_buffers[n].ips_sv_buffer, 0, - comm->ips_buffers[n].ips_sv_alloced); - - return comm->ips_buffers[n].ips_sv_buffer; -} - - -static void get_segment( ICC icc) -{ -/************************************** - * - * g e t _ s e g m e n t - * - ************************************** - * - * Functional description - * Get a single blob segment. - * - **************************************/ - IBL blob; - USHORT buffer_length, length; - UCHAR *buffer; - ISC_STATUS_ARRAY status_vector; - ips_segment *ips; - ips_string *ips_seg; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_segment; - blob = (IBL) ips->ips_bl_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - - // set up segment buffer - - ips_seg = &comm->ips_buffers[IPS_BLOB_SEGMENT]; - buffer_length = (USHORT) ips_seg->ips_cl_size; - buffer = get_buffer(comm, buffer_length, IPS_BLOB_SEGMENT); - NOT_NULL(buffer, buffer_length); - IPS_SERVER(comm, IPS_BLOB_SEGMENT, buffer, buffer_length); - - /* get the segment data - return it regardless of result - * as that is what the client side expects - * isc_segment can be returned in the status vector, - * but that the data is still valid. - */ - - length = 0; - GDS_GET_SEGMENT(status_vector, &blob->ibl_handle, &length, buffer_length, - reinterpret_cast < char *>(buffer)); - if (!transfer_buffers(icc, comm)) - return; - ips->ips_length = length; - send_response(icc, status_vector); -} - - -static void get_slice( ICC icc) -{ -/************************************** - * - * g e t _ s l i c e - * - ************************************** - * - * Functional description - * Get slice of array; - * - **************************************/ - IDB idb; - ITR transaction; - ISC_STATUS_ARRAY status_vector; - SSHORT sdl_length, param_length; - ULONG slice_length, return_length, *params, parameters[32]; - UCHAR *sdl, sdl_buf[256], *slice; - struct bid array_id; - ips_slice *ips; - ips_string *ips_sdl; - ips_string *ips_parms; - ips_string *ips_data; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_slice; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = (ITR) ips->ips_tr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - array_id.bid_relation_id = ips->ips_rel_id; - array_id.bid_number = ips->ips_number; - - // set up sdl - - ips_sdl = &comm->ips_buffers[IPS_SLICE_SDL]; - sdl_length = (SSHORT) ips_sdl->ips_cl_size; - if (sdl_length <= (SLONG) sizeof(sdl_buf)) - sdl = sdl_buf; - else - sdl = get_buffer(comm, sdl_length, IPS_SLICE_SDL); - NOT_NULL(sdl, sdl_length); - IPS_SERVER(comm, IPS_SLICE_SDL, sdl, sdl_length); - - // set up parameters - - ips_parms = &comm->ips_buffers[IPS_SLICE_PARAM]; - param_length = (SSHORT) ips_parms->ips_cl_size; - if (param_length <= (SLONG) sizeof(parameters)) - params = parameters; - else - params = (ULONG *) get_buffer(comm, param_length, IPS_SLICE_PARAM); - NOT_NULL(params, param_length); - IPS_SERVER(comm, IPS_SLICE_PARAM, (UCHAR *) params, param_length); - - // set up slice data buffer - - ips_data = &comm->ips_buffers[IPS_SLICE_BUFFER]; - slice_length = ips_data->ips_cl_size; - if (slice_length) - { - slice = (UCHAR*)gds__alloc(slice_length); - NOT_NULL(slice, TRUE); - memset(slice, 0, slice_length); - } - else - slice = NULL; - IPS_SERVER(comm, IPS_SLICE_BUFFER, slice, slice_length); - if (!transfer_buffers(icc, comm)) - { - if (slice) - { - gds__free(slice); - } - return; - } - - // get and return slice - - GDS_GET_SLICE(status_vector, &idb->idb_handle, &transaction->itr_handle, - (ISC_QUAD*) &array_id, sdl_length, - reinterpret_cast(sdl), param_length, - reinterpret_cast(params), slice_length, - slice, reinterpret_cast(&return_length)); - ips->ips_length = return_length; - send_response(icc, status_vector); - if (slice) - { - gds__free(slice); - } -} - - -static void info( ICC icc, P_OP operation) -{ -/************************************** - * - * i n f o - * - ************************************** - * - * Functional description - * Issue information. - * - **************************************/ - FB_API_HANDLE handle; - ISC_STATUS_ARRAY status_vector; - USHORT item_length, recv_item_length, buffer_length, incarnation; - UCHAR items_buf[128], recv_items_buf[128]; - IDB idb; - ITR transaction; - IBL blob; - IRQ request; - IPSERVER_ISR statement; - ips_object *ips; - ips_string *ips_items; - ips_string *ips_data; - ips_string *ips_rcv_items; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - comm->ips_operation = op_info_blob; - ips = &comm->ips_operations.ips_op_object; - handle = (FB_API_HANDLE)ips->ips_handle; - if (operation == op_info_request) - incarnation = (USHORT) ips->ips_parameter; - - // set up items buffer - - ips_items = &comm->ips_buffers[IPS_INFO_ITEMS]; - item_length = (USHORT) ips_items->ips_cl_size; - UCHAR* items; - if (item_length <= sizeof(items_buf)) - items = items_buf; - else - items = get_buffer(comm, item_length, IPS_INFO_ITEMS); - NOT_NULL(items, item_length); - IPS_SERVER(comm, IPS_INFO_ITEMS, items, item_length); - - // set up data buffer - - ips_data = &comm->ips_buffers[IPS_INFO_DATA]; - buffer_length = (USHORT) ips_data->ips_cl_size; - UCHAR* buffer = get_buffer(comm, buffer_length, IPS_INFO_DATA); - NOT_NULL(buffer, buffer_length); - IPS_SERVER(comm, IPS_INFO_DATA, buffer, buffer_length); - - // set up receive items buffer if necessary - - UCHAR* recv_items = 0; - if (operation == op_service_info) - { - ips_rcv_items = &comm->ips_buffers[IPS_QUERY_RECV_ITEMS]; - recv_item_length = (USHORT) ips_rcv_items->ips_cl_size; - if (recv_item_length <= sizeof(recv_items_buf)) - recv_items = recv_items_buf; - else - recv_items = - get_buffer(comm, recv_item_length, IPS_QUERY_RECV_ITEMS); - NOT_NULL(recv_items, recv_item_length); - IPS_SERVER(comm, IPS_QUERY_RECV_ITEMS, recv_items, recv_item_length); - } - if (!transfer_buffers(icc, comm)) - return; - - // perform operation - - switch (operation) - { - case op_info_database: - idb = (IDB) handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - GDS_DATABASE_INFO(status_vector, &idb->idb_handle, - item_length, reinterpret_cast(items), - buffer_length, reinterpret_cast < char *>(buffer)); - break; - - case op_info_blob: - blob = (IBL) handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - GDS_BLOB_INFO(status_vector, &blob->ibl_handle, item_length, - reinterpret_cast(items), buffer_length, - reinterpret_cast < char *>(buffer)); - break; - - case op_info_request: - request = (IRQ) handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - GDS_REQUEST_INFO(status_vector, &request->irq_handle, incarnation, - item_length, reinterpret_cast(items), - buffer_length, reinterpret_cast < char *>(buffer)); - break; - - case op_info_transaction: - transaction = (ITR) handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - GDS_TRANSACTION_INFO(status_vector, &transaction->itr_handle, - item_length, reinterpret_cast(items), - buffer_length, reinterpret_cast < char *>(buffer)); - break; - - case op_service_info: - idb = (IDB) handle; - CHECK_HANDLE(idb, type_idb, isc_bad_svc_handle); - GDS_SERVICE_QUERY(status_vector, &idb->idb_handle, 0, // reserved - item_length, - reinterpret_cast(items), - recv_item_length, - reinterpret_cast(recv_items), - buffer_length, reinterpret_cast < char *>(buffer)); - break; - - case op_info_sql: - statement = (IPSERVER_ISR) handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_stmt_handle); - GDS_DSQL_SQL_INFO(status_vector, - &statement->isr_handle, - item_length, - reinterpret_cast(items), - buffer_length, reinterpret_cast < char *>(buffer)); - break; - } - - // return results - - send_response(icc, status_vector); -} - - -static void insert( ICC icc) -{ -/************************************** - * - * i n s e r t - * - ************************************** - * - * Functional description - * Insert next record into a dynamic SQL cursor. - * - **************************************/ - IPSERVER_ISR statement; - USHORT blr_length, msg_type, msg_length; - UCHAR *blr, *msg; - ISC_STATUS_ARRAY status_vector; - ips_dsql *ips; - ips_string *ips_blr; - ips_string *ips_msg; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_dsql; - statement = (IPSERVER_ISR) ips->ips_st_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_stmt_handle); - msg_type = ips->ips_msg_type; - - // set up blr - - ips_blr = &comm->ips_buffers[IPS_DSQL_INSERT_BLR]; - blr_length = (USHORT) ips_blr->ips_cl_size; - blr = get_buffer(comm, blr_length, IPS_DSQL_INSERT_BLR); - NOT_NULL(blr, blr_length); - IPS_SERVER(comm, IPS_DSQL_INSERT_BLR, blr, blr_length); - - // set up message - - ips_msg = &comm->ips_buffers[IPS_DSQL_INSERT_MSG]; - msg_length = (USHORT) ips_msg->ips_cl_size; - msg = get_buffer(comm, msg_length, IPS_DSQL_INSERT_MSG); - NOT_NULL(msg, msg_length); - IPS_SERVER(comm, IPS_DSQL_INSERT_MSG, msg, msg_length); - if (!transfer_buffers(icc, comm)) - return; - - // insert the record and return - - GDS_DSQL_INSERT(status_vector, - &statement->isr_handle, - blr_length, - reinterpret_cast(blr), - msg_type, msg_length, reinterpret_cast(msg)); - send_response(icc, status_vector); -} - - -static IPM make_map(USHORT map_number) -{ -/************************************** - * - * m a k e _ m a p - * - ************************************** - * - * Functional description - * Create a mapped file. This - * returns - - * 0 - mapped file already exists - * -1 - mapping or creation error - * other - pointer to new structure - * - **************************************/ - - HANDLE map_handle; - LPVOID map_address; - // Here we better be 100% SURE this won't overflow! - TEXT name_buffer[128]; - - // create the mapped file name and try to open it - - sprintf(name_buffer, IPI_MAPPED_FILE_NAME, Config::getIpcName(), map_number); - map_handle = CreateFileMapping((HANDLE) 0xFFFFFFFF, - ISC_get_security_desc(), - PAGE_READWRITE, - 0L, - IPS_MAPPED_SIZE(ipserver_private_data.users_per_map, - ipserver_private_data.pages_per_user), - name_buffer); - if (map_handle && GetLastError() == ERROR_ALREADY_EXISTS) { - return NULL; - } - if (!map_handle) { - return (IPM) -1; - } - map_address = MapViewOfFile(map_handle, FILE_MAP_WRITE, 0L, 0L, - IPS_MAPPED_SIZE(ipserver_private_data.users_per_map, - ipserver_private_data.pages_per_user)); - if (!map_address) { - CloseHandle(map_handle); - return (IPM) -1; - } - - // allocate a structure and initialize it - - IPM ipm = (IPM) ALLI_alloc(sizeof(struct ipm)); - if (!ipm) { - UnmapViewOfFile(map_address); - CloseHandle(map_handle); - return (IPM) -1; - } - ipm->ipm_handle = map_handle; - ipm->ipm_address = map_address; - ipm->ipm_number = map_number; - ipm->ipm_count = 0; - for (USHORT i = 0; i < ipserver_private_data.users_per_map; i++) { - ipm->ipm_ids[i] = 0; - } - ipm->ipm_next = ipserver_private_data.ipms; - ipserver_private_data.ipms = ipm; - return ipm; -} - - -static ITR make_transaction( IDB idb, FB_API_HANDLE handle) -{ -/************************************** - * - * m a k e _ t r a n s a c t i o n - * - ************************************** - * - * Functional description - * Create a local transaction handle. - * - **************************************/ - ITR transaction; - - - transaction = (ITR) ALLOC(type_itr); - if (transaction) - { - transaction->itr_idb = idb; - transaction->itr_handle = handle; - transaction->itr_next = idb->idb_transactions; - idb->idb_transactions = transaction; - } - return transaction; -} - - -static void open_blob( ICC icc, P_OP op) -{ -/************************************** - * - * o p e n _ b l o b - * - ************************************** - * - * Functional description - * Open or create a new blob. - * - **************************************/ - IDB idb; - IBL blob; - ITR transaction; - FB_API_HANDLE handle; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - USHORT bpb_length; - UCHAR *bpb, bpb_buf[128]; - struct bid blob_id; - ips_blob *ips; - ips_string *ips_bpb; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_blob; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = (ITR) ips->ips_tr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - handle = NULL; - bpb_length = 0; - - // set up bpb if needed - - if (op == op_open_blob2 || op == op_create_blob2) - { - ips_bpb = &comm->ips_buffers[IPS_BLOB_BPB]; - bpb_length = (USHORT) ips_bpb->ips_cl_size; - if (bpb_length <= sizeof(bpb_buf)) - bpb = bpb_buf; - else - bpb = get_buffer(comm, bpb_length, IPS_BLOB_BPB); - NOT_NULL(bpb, bpb_length); - IPS_SERVER(comm, IPS_BLOB_BPB, bpb, bpb_length); - } - if (!transfer_buffers(icc, comm)) - return; - - // perform operation and return handle - - switch (op) - { - case op_open_blob: - blob_id.bid_relation_id = ips->ips_rel_id; - blob_id.bid_number = ips->ips_bid_number; - result = GDS_OPEN_BLOB(status_vector, &idb->idb_handle, - &transaction->itr_handle, &handle, - (ISC_QUAD*) & blob_id); - break; - - case op_create_blob: - result = GDS_CREATE_BLOB(status_vector, &idb->idb_handle, - &transaction->itr_handle, - &handle, (ISC_QUAD*) & blob_id); - ips->ips_rel_id = blob_id.bid_relation_id; - ips->ips_bid_number = blob_id.bid_number; - break; - - case op_open_blob2: - blob_id.bid_relation_id = ips->ips_rel_id; - blob_id.bid_number = ips->ips_bid_number; - result = GDS_OPEN_BLOB2(status_vector, &idb->idb_handle, - &transaction->itr_handle, &handle, - (ISC_QUAD*) & blob_id, - bpb_length, - bpb); - break; - - case op_create_blob2: - result = GDS_CREATE_BLOB2(status_vector, &idb->idb_handle, - &transaction->itr_handle, &handle, - (ISC_QUAD*) & blob_id, bpb_length, - reinterpret_cast(bpb)); - ips->ips_rel_id = blob_id.bid_relation_id; - ips->ips_bid_number = blob_id.bid_number; - break; - } - if (!result) - { - blob = (IBL) ALLOC(type_ibl); - ips->ips_bl_handle = (UCHAR *) blob; - NOT_NULL(blob, TRUE); - blob->ibl_handle = handle; - blob->ibl_idb = idb; - blob->ibl_itr = transaction; - blob->ibl_next = transaction->itr_blobs; - transaction->itr_blobs = blob; - } - else - ips->ips_bl_handle = NULL; - send_response(icc, status_vector); -} - - -static void prepare_statement( ICC icc) -{ -/************************************** - * - * p r e p a r e _ s t a t e m e n t - * - ************************************** - * - * Functional description - * Prepare a dynamic SQL statement for execution. - * - **************************************/ - ITR transaction; - IPSERVER_ISR statement; - USHORT length, item_length, buffer_length, dialect, parser_version; - UCHAR *string, *items, items_buf[128], *buffer; - ISC_STATUS_ARRAY status_vector; - FB_API_HANDLE handle; - ips_dsql *ips; - ips_string *ips_prep_string; - ips_string *ips_prep_items; - ips_string *ips_prep_buffer; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_dsql; - transaction = (ITR) ips->ips_tr_handle; - if (transaction) - { - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - handle = transaction->itr_handle; - } - else - handle = NULL; - statement = (IPSERVER_ISR) ips->ips_st_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_stmt_handle); - dialect = (USHORT) ips->ips_parameter; - - // set up string - - ips_prep_string = &comm->ips_buffers[IPS_DSQL_PREP_STRING]; - length = (USHORT) ips_prep_string->ips_cl_size; - string = get_buffer(comm, length, IPS_DSQL_PREP_STRING); - NOT_NULL(string, length); - IPS_SERVER(comm, IPS_DSQL_PREP_STRING, string, length); - - // set up items - - ips_prep_items = &comm->ips_buffers[IPS_DSQL_PREP_ITEMS]; - item_length = (USHORT) ips_prep_items->ips_cl_size; - if (item_length <= sizeof(items_buf)) - items = items_buf; - else - items = get_buffer(comm, item_length, IPS_DSQL_PREP_ITEMS); - NOT_NULL(items, item_length); - IPS_SERVER(comm, IPS_DSQL_PREP_ITEMS, items, item_length); - - // set up buffer - - ips_prep_buffer = &comm->ips_buffers[IPS_DSQL_PREP_BUFFER]; - buffer_length = (USHORT) ips_prep_buffer->ips_cl_size; - buffer = get_buffer(comm, buffer_length, IPS_DSQL_PREP_BUFFER); - NOT_NULL(buffer, buffer_length); - IPS_SERVER(comm, IPS_DSQL_PREP_BUFFER, buffer, buffer_length); - if (!transfer_buffers(icc, comm)) - return; - - // NT Local access: Client and server are always the same version - /* Since the API to GDS_DSQL_PREPARE is public and can not be changed, there needs to - * be a way to send the parser version to DSQL so that the parser can compare the keyword - * version to the parser version. To accomplish this, the parser version is combined with - * the client dialect and sent across that way. In dsql8_prepare_statement, the parser version - * and client dialect are separated and passed on to their final desintations. The information - * is combined as follows: - * Dialect * 10 + parser_version - * - * and is extracted in dsql8_prepare_statement as follows: - * parser_version = ((dialect *10)+parser_version)%10 - * client_dialect = ((dialect *10)+parser_version)/10 - * - * For example, parser_version = 1 and client dialect = 1 - * - * combined = (1 * 10) + 1 == 11 - * - * parser = (combined) %10 == 1 - * dialect = (combined) / 19 == 1 - */ - - parser_version = 2; - - // prepare statement and return data - - GDS_DSQL_PREPARE(status_vector, - &handle, - &statement->isr_handle, - length, - reinterpret_cast(string), - (USHORT) ((dialect * 10) + parser_version), - item_length, - reinterpret_cast(items), - buffer_length, reinterpret_cast(buffer)); - statement->isr_batch_flag = check_statement_type(statement); - ips->ips_parameter = statement->isr_batch_flag; - send_response(icc, status_vector); -} - - -static void put_segment( ICC icc) -{ -/************************************** - * - * p u t _ s e g m e n t - * - ************************************** - * - * Functional description - * Write a single blob segment. - * - **************************************/ - IBL blob; - USHORT buffer_length; - UCHAR *buffer; - ISC_STATUS_ARRAY status_vector; - ips_segment *ips; - ips_string *ips_seg; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_segment; - blob = (IBL) ips->ips_bl_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - - // set up segment buffer - - ips_seg = &comm->ips_buffers[IPS_BLOB_SEGMENT]; - buffer_length = (USHORT) ips_seg->ips_cl_size; - buffer = get_buffer(comm, buffer_length, IPS_BLOB_SEGMENT); - NOT_NULL(buffer, buffer_length); - IPS_SERVER(comm, IPS_BLOB_SEGMENT, buffer, buffer_length); - if (!transfer_buffers(icc, comm)) - return; - - // put the segment into the database - - GDS_PUT_SEGMENT(status_vector, &blob->ibl_handle, buffer_length, - reinterpret_cast(buffer)); - send_response(icc, status_vector); -} - - -static void put_slice( ICC icc) -{ -/************************************** - * - * p u t _ s l i c e - * - ************************************** - * - * Functional description - * Put slice of array; - * - **************************************/ - IDB idb; - ITR transaction; - ISC_STATUS_ARRAY status_vector; - USHORT sdl_length, param_length; - ULONG slice_length, *params, parameters[32]; - UCHAR *sdl, sdl_buf[256], *slice; - struct bid array_id; - ips_slice *ips; - ips_string *ips_sdl; - ips_string *ips_parms; - ips_string *ips_data; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_slice; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = (ITR) ips->ips_tr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - array_id.bid_relation_id = ips->ips_rel_id; - array_id.bid_number = ips->ips_number; - - // set up sdl - - ips_sdl = &comm->ips_buffers[IPS_SLICE_SDL]; - sdl_length = (USHORT) ips_sdl->ips_cl_size; - if (sdl_length <= sizeof(sdl_buf)) - sdl = sdl_buf; - else - sdl = get_buffer(comm, sdl_length, IPS_SLICE_SDL); - NOT_NULL(sdl, sdl_length); - IPS_SERVER(comm, IPS_SLICE_SDL, sdl, sdl_length); - - // set up parameters - - ips_parms = &comm->ips_buffers[IPS_SLICE_PARAM]; - param_length = (USHORT) ips_parms->ips_cl_size; - if (param_length <= sizeof(parameters)) - params = parameters; - else - params = (ULONG *) get_buffer(comm, param_length, IPS_SLICE_PARAM); - NOT_NULL(params, param_length); - IPS_SERVER(comm, IPS_SLICE_PARAM, (UCHAR *) params, param_length); - - // set up slice data buffer - - ips_data = &comm->ips_buffers[IPS_SLICE_BUFFER]; - slice_length = ips_data->ips_cl_size; - if (slice_length) - { - slice = (UCHAR*)gds__alloc(slice_length); - NOT_NULL(slice, TRUE); - memset(slice, 0, slice_length); - } - else - slice = NULL; - IPS_SERVER(comm, IPS_SLICE_BUFFER, slice, slice_length); - if (!transfer_buffers(icc, comm)) - { - if (slice) - { - gds__free(slice); - } - return; - } - - // put the slice into the database - - GDS_PUT_SLICE(status_vector, &idb->idb_handle, &transaction->itr_handle, - (ISC_QUAD*) & array_id, sdl_length, - reinterpret_cast(sdl), param_length, - reinterpret_cast(params), slice_length, slice); - ips->ips_rel_id = array_id.bid_relation_id; - ips->ips_number = array_id.bid_number; - send_response(icc, status_vector); - if (slice) - { - gds__free(slice); - } -} - - -static void que_events( ICC icc) -{ -/************************************** - * - * q u e _ e v e n t s - * - ************************************** - * - * Functional description - * Que events for asynchronous notification. - * - **************************************/ - IDB idb; - USHORT length; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - IVNT event; - ips_que_events *ips; - ips_string *ips_event; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_que_evnt; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // set up event string - - ips_event = &comm->ips_buffers[IPS_QUEUE_EVENT]; - length = (USHORT) ips_event->ips_cl_size; - UCHAR* events = get_buffer(comm, length, IPS_QUEUE_EVENT); - NOT_NULL(events, length); - IPS_SERVER(comm, IPS_QUEUE_EVENT, events, length); - - // find or allocate event block - - for (event = idb->idb_events; event; event = event->ivnt_next) - if (!event->ivnt_ast) - break; - if (!event) - { - event = (IVNT) ALLOC(type_ivnt); - NOT_NULL(event, TRUE); - event->ivnt_next = idb->idb_events; - event->ivnt_idb = idb; - idb->idb_events = event; - } - - // Get data, etc - - event->ivnt_window = ips->ips_event_hwnd; - event->ivnt_id = ips->ips_event_id; - event->ivnt_ast = ips->ips_ast; - event->ivnt_arg = (void *) ips->ips_arg; - if (!transfer_buffers(icc, comm)) - return; - - // queue the event and return id - - result = GDS_QUE_EVENTS(status_vector, &idb->idb_handle, &event->ivnt_handle, - length, reinterpret_cast(events), - event_ast, - event); - if (!result) - ips->ips_event_id = event->ivnt_handle; - else - event->ivnt_ast = NULL; - send_response(icc, status_vector); -} - - -static void receive_msg( ICC icc) -{ -/************************************** - * - * r e c e i v e _ m s g - * - ************************************** - * - * Functional description - * Receive a message. - * - **************************************/ - ISC_STATUS_ARRAY status_vector; - IRQ request; - USHORT length, number, level; -#ifdef SCROLLABLE_CURSORS - USHORT direction; - ULONG offset; -#endif - UCHAR *buffer; - ips_request *ips; - ips_string *ips_message; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_request; - request = (IRQ) ips->ips_rq_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - - // set up message - - ips_message = &comm->ips_buffers[IPS_RECEIVE_MESSAGE]; - length = (USHORT) ips_message->ips_cl_size; - buffer = get_buffer(comm, length, IPS_RECEIVE_MESSAGE); - NOT_NULL(buffer, length); - IPS_SERVER(comm, IPS_RECEIVE_MESSAGE, buffer, length); - number = ips->ips_msg_type; - level = ips->ips_req_level; -#ifdef SCROLLABLE_CURSORS - direction = ips->ips_direction; - offset = ips->ips_offset; -#endif - - // receive message and send response - - GDS_RECEIVE(status_vector, &request->irq_handle, - number, length, buffer, level -#ifdef SCROLLABLE_CURSORS - , direction, offset -#endif - ); - - send_response(icc, status_vector); -} - - -static void reconnect( ICC icc) -{ -/************************************** - * - * r e c o n n e c t - * - ************************************** - * - * Functional description - * Reconnect to a transaction in limbo. - * - **************************************/ - IDB idb; - ITR transaction; - USHORT length; - UCHAR *buffer; - FB_API_HANDLE handle; - ISC_STATUS_ARRAY status_vector; - ips_reconnect *ips; - ips_string *ips_recon; - ips_comm_area *comm; - TEXT *comm_ptr; - -// set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_recon_trans; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - -// set up string - - ips_recon = &comm->ips_buffers[IPS_RECONNECT_ID]; - length = (USHORT) ips_recon->ips_cl_size; - buffer = get_buffer(comm, length, IPS_RECONNECT_ID); - NOT_NULL(buffer, length); - IPS_SERVER(comm, IPS_RECONNECT_ID, buffer, length); - handle = NULL; - if (!transfer_buffers(icc, comm)) - return; - -// reconnect transaction and return id - - if (!GDS_RECONNECT(status_vector, &idb->idb_handle, &handle, - length, reinterpret_cast < char *>(buffer))) - { - if (transaction = make_transaction(idb, handle)) - { - ips->ips_tr_handle = (UCHAR *) transaction; - transaction->itr_flags |= ITR_limbo; - } - else - { - gds__handle_cleanup(status_vector, - (FB_API_HANDLE*) &handle); - NOT_NULL(transaction, TRUE); - } - } - - send_response(icc, status_vector); -} - - -static void release_blob( IBL blob) -{ -/************************************** - * - * r e l e a s e _ b l o b - * - ************************************** - * - * Functional description - * Release a blob block and friends. - * - **************************************/ - IDB idb; - ITR transaction; - IBL *p; - - - idb = blob->ibl_idb; - transaction = blob->ibl_itr; - - for (p = &transaction->itr_blobs; *p; p = &(*p)->ibl_next) - { - if (*p == blob) - { - *p = blob->ibl_next; - break; - } - } - ALLI_release((BLK) blob); -} - - -static void release_event( IVNT event) -{ -/************************************** - * - * r e l e a s e _ e v e n t s - * - ************************************** - * - * Functional description - * Release a event block and friends. - * - **************************************/ - IDB idb; - IVNT *p; - - - idb = event->ivnt_idb; - for (p = &idb->idb_events; *p; p = &(*p)->ivnt_next) - { - if (*p == event) - { - *p = event->ivnt_next; - break; - } - } - ALLI_release((BLK) event); -} - - -static void release_request( IRQ request) -{ -/************************************** - * - * r e l e a s e _ r e q u e s t - * - ************************************** - * - * Functional description - * Release a request block and friends. - * - **************************************/ - IDB idb; - IRQ *p; - - - idb = request->irq_idb; - for (p = &idb->idb_requests; *p; p = &(*p)->irq_next) - if (*p == request) - { - *p = request->irq_next; - break; - } - ALLI_release((BLK) request); -} - - -static void release_sql_request( IPSERVER_ISR stmt) -{ -/************************************** - * - * r e l e a s e _ s q l _ r e q u e s t - * - ************************************** - * - * Functional description - * Release an SQL request block. - * - **************************************/ - IDB idb; - IPSERVER_ISR *p; - - - idb = stmt->isr_idb; - for (p = &idb->idb_sql_requests; *p; p = &(*p)->isr_next) - if (*p == stmt) - { - *p = stmt->isr_next; - break; - } - ALLI_release((BLK) stmt); -} - - -static void release_transaction( ITR transaction) -{ -/************************************** - * - * r e l e a s e _ t r a n s a c t i o n - * - ************************************** - * - * Functional description - * Release a transaction block and friends. - * - **************************************/ - IDB idb; - ITR *p; - - - idb = transaction->itr_idb; - while (transaction->itr_blobs) - release_blob(transaction->itr_blobs); - for (p = &idb->idb_transactions; *p; p = &(*p)->itr_next) - if (*p == transaction) - { - *p = transaction->itr_next; - break; - } - ALLI_release((BLK) transaction); -} - - -static void seek_blob( ICC icc) -{ -/************************************** - * - * s e e k _ b l o b - * - ************************************** - * - * Functional description - * Perform a blob seek. - * - **************************************/ - IBL blob; - SSHORT mode; - SLONG offset, result; - ISC_STATUS_ARRAY status_vector; - ips_seek_blob *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_sk_blob; - blob = (IBL) ips->ips_bl_handle; - CHECK_HANDLE(blob, type_ibl, isc_bad_segstr_handle); - offset = ips->ips_offset; - mode = ips->ips_mode; - - // seek blob and return result - - GDS_SEEK_BLOB(status_vector, &blob->ibl_handle, mode, offset, &result); - ips->ips_result = result; - send_response(icc, status_vector); -} - - -static bool send_and_wait( ICC icc) -{ -/************************************** - * - * s e n d _ a n d _ w a i t - * - ************************************** - * - * Functional description - * This function responds to the client by releasing - * the client's semaphore, and then waits for more - * work by waiting on the server's semaphore. - * - **************************************/ - DWORD result; - - - // already in shutdown mode - - if (icc->icc_flags & ICCF_SHUTDOWN) - return false; - - /* first, signal the client that the communications - area in mapped memory is filed and ready */ - - if (!ReleaseSemaphore(icc->icc_client_sem, 1L, NULL)) - { - icc->icc_flags |= ICCF_SHUTDOWN; -#ifdef DEBUG_IP_TRACE - gds__log("ipserver send of send and wait failed %lX %ld", - (long) icc, (long) GetLastError()); -#endif - return false; - } - - // next, wait for the client to signal us back - - result = - WaitForMultipleObjects((DWORD) 2, icc->icc_waits, FALSE, INFINITE); - if (result != WAIT_OBJECT_0) - { - icc->icc_flags |= ICCF_SHUTDOWN; -#ifdef DEBUG_IP_TRACE - gds__log("ipserver wait of send and wait failed %lX %ld", - (long) icc, (long) GetLastError()); -#endif - return false; - } - else - return true; -} - - -static void send_msg( ICC icc) -{ -/************************************** - * - * s e n d _ m s g - * - ************************************** - * - * Functional description - * - **************************************/ - ISC_STATUS_ARRAY status_vector; - IRQ request; - USHORT length, number, level; - ips_request *ips; - ips_string *ips_message; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_request; - request = (IRQ) ips->ips_rq_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - - // set up message - - ips_message = &comm->ips_buffers[IPS_SEND_MESSAGE]; - length = (USHORT) ips_message->ips_cl_size; - const UCHAR* buffer = get_buffer(comm, length, IPS_SEND_MESSAGE); - NOT_NULL(buffer, length); - IPS_SERVER(comm, IPS_SEND_MESSAGE, buffer, length); - number = ips->ips_msg_type; - level = ips->ips_req_level; - if (!transfer_buffers(icc, comm)) - return; - - // send message - - GDS_SEND(status_vector, &request->irq_handle, number, length, buffer, - level); - send_response(icc, status_vector); -} - - -static void send_no_wait( ICC icc) -{ -/************************************** - * - * s e n d _ n o _ w a i t - * - ************************************** - * - * Functional description - * This function sends the client the server's - * last filled in communications area, indicating - * that the server is done. No wait is done here. - * - **************************************/ - - - // already in shutdown mode - - if (icc->icc_flags & ICCF_SHUTDOWN) - return; - - /* signal the client that the communications - area in mapped memory is filed and ready */ - - if (!ReleaseSemaphore(icc->icc_client_sem, 1L, NULL)) - { -#ifdef DEBUG_IP_TRACE - gds__log("ipserver send no wait failed %lX %ld", - (long) icc, (long) GetLastError()); -#endif - icc->icc_flags |= ICCF_SHUTDOWN; - } -} - - -static void send_response( ICC icc, ISC_STATUS* status_vector) -{ -/************************************** - * - * s e n d _ r e s p o n s e - * - ************************************** - * - * Functional description - * Send a response packet. - * - **************************************/ - ISC_STATUS *comm_status; - USHORT i, length; - ULONG to_copy, size_left; - TEXT* abase; - ips_comm_area *comm; - TEXT *comm_ptr; - ips_string *string; - ULONG l, *lp; - - - // first, initialize the status vector in the comm area - - comm = (ips_comm_area *) icc->icc_mapped_addr; - comm_ptr = (TEXT *) comm->ips_data; - comm_status = reinterpret_cast < ISC_STATUS * >(comm->ips_status); - abase = comm_ptr; - - // if there's no error or warning, just put in a clean status vector - - if (!status_vector[1] && !status_vector[2]) - { - *comm_status++ = *status_vector++; - *comm_status++ = *status_vector++; - } - else - { - /* transfer the status vector, putting strings in the comm area's - data area */ - TEXT buffer[1024]; - - while (*status_vector) - { - const TEXT* p; - switch (*status_vector) - { - case isc_arg_interpreted: - case isc_arg_string: - - /* for strings, put the length, followed by the - string in the comm data area */ - - *comm_status++ = *status_vector++; - p = (TEXT *) * status_vector++; - if (p) - length = strlen(p); - else - length = 0; - lp = (ULONG *) comm_ptr; - *lp = length; - comm_ptr += sizeof(ULONG); - for (i = 0; i < length; i++) - *comm_ptr++ = *p++; - l = length % sizeof(ULONG); - if (l) - comm_ptr += (sizeof(ULONG) - l); - break; - - case isc_arg_cstring: - *comm_status++ = isc_arg_string; - status_vector++; - length = (USHORT) * status_vector++; - lp = (ULONG *) comm_ptr; - *lp = length; - comm_ptr += sizeof(ULONG); - p = (TEXT *) * status_vector++; - for (i = 0; i < length; i++) - *comm_ptr++ = *p++; - l = length % sizeof(ULONG); - if (l) - comm_ptr += (sizeof(ULONG) - l); - break; - - case isc_arg_warning: - case isc_arg_number: - case isc_arg_gds: - *comm_status++ = *status_vector++; - *comm_status++ = *status_vector++; - break; - - default: - { // scope - const ISC_STATUS* svp = status_vector; - length = (USHORT) fb_interpret(buffer, sizeof(buffer), &svp); - status_vector = const_cast(svp); - } // scope - if (!length) - { - *status_vector = 0; - break; - } - *comm_status++ = isc_arg_interpreted; - lp = (ULONG *) comm_ptr; - *lp = length; - comm_ptr += sizeof(ULONG); - for (i = 0; i < length; i++) - *comm_ptr++ = buffer[i]; - l = length % sizeof(ULONG); - if (l) - comm_ptr += (sizeof(ULONG) - l); - break; - } - } - } - *comm_status++ = isc_arg_end; - - // point to the current first available byte and figure space available - - TEXT* acursor = comm_ptr; - size_left = (ULONG) (IPS_USEFUL_SPACE(ipserver_private_data.pages_per_user)) - - (abase - reinterpret_cast < TEXT * >(comm->ips_data)); - for (i = 0; i < MAX_IPS_STRINGS; i++) - { - string = &comm->ips_buffers[i]; - - // see if this buffer needs sending - - if ((string->ips_flags & IPS_OUTPUT_BUFFER) && string->ips_sv_size) - { - string->ips_sv_copied = 0; - const UCHAR* scursor = string->ips_sv_addr; - - // keep packing it in - - while (string->ips_sv_copied < string->ips_sv_size) - { - - // put in the whole thing, or whatever will fit - - to_copy = string->ips_sv_size - string->ips_sv_copied; - if (size_left <= to_copy) - to_copy = size_left; - string->ips_com_offset = acursor - abase; - string->ips_com_size = to_copy; - memcpy(acursor, scursor, (USHORT) to_copy); - acursor += to_copy; - scursor += to_copy; - size_left -= to_copy; - string->ips_sv_copied += to_copy; - - // if all the space has been used up, send it and wait - - if (!size_left && string->ips_sv_copied < string->ips_sv_size) - { - comm->ips_sequence++; - if (!send_and_wait(icc)) - return; - size_left = (ULONG) (IPS_USEFUL_SPACE(ipserver_private_data.pages_per_user)); - acursor = reinterpret_cast < char *>(comm->ips_data); - } - } - } - } - - // sending the last buffer, all done - - comm->ips_sequence++; - send_no_wait(icc); -} - - -static void service_attach( ICC icc) -{ -/************************************** - * - * s e r v i c e _ a t t a c h - * - ************************************** - * - * Functional description - * Connect to an Interbase service. - * - **************************************/ - USHORT service_length, spb_length; - UCHAR service_name[256], *spb, spb_buf[256]; - FB_API_HANDLE handle; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - IDB idb; - ips_object *ips; - ips_string *ips_name; - ips_string *ips_spb; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - - // figure out service name buffer - - ips_name = &comm->ips_buffers[IPS_ATTACH_SVC_NAME]; - service_length = (USHORT) ips_name->ips_cl_size; - IPS_SERVER(comm, IPS_ATTACH_SVC_NAME, service_name, service_length); - - // figure out spb buffer - - ips_spb = &comm->ips_buffers[IPS_ATTACH_SVC_SPB]; - spb_length = (USHORT) ips_spb->ips_cl_size; - if (spb_length <= sizeof(spb_buf)) - spb = spb_buf; - else - spb = get_buffer(comm, spb_length, IPS_ATTACH_SVC_SPB); - NOT_NULL(spb, spb_length); - IPS_SERVER(comm, IPS_ATTACH_SVC_SPB, spb, spb_length); - if (!transfer_buffers(icc, comm)) - return; - - // get handle - - handle = NULL; - result = GDS_SERVICE_ATTACH(status_vector, - service_length, - reinterpret_cast(service_name), - &handle, - spb_length, reinterpret_cast(spb)); - - // allocate structure and return handle - - if (!result) - { - idb = (IDB) ALLOC(type_idb); - ips->ips_handle = (UCHAR *) idb; - NOT_NULL(idb, TRUE); - idb->idb_flags = IDBF_SERVICE_ATTACHMENT; - idb->idb_handle = handle; - idb->idb_next = icc->icc_databases; - icc->icc_databases = idb; - } - else - ips->ips_handle = NULL; - send_response(icc, status_vector); -} - - -static void service_end( ICC icc) -{ -/************************************** - * - * s e r v i c e _ e n d - * - ************************************** - * - * Functional description - * Close down a service. - * - **************************************/ - IDB idb, *ptr; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - ips_object *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - idb = (IDB) ips->ips_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - - // detach request, return response and free resources - - result = GDS_SERVICE_DETACH(status_vector, &idb->idb_handle); - send_response(icc, status_vector); - if (!result) - { - for (ptr = &icc->icc_databases; *ptr; ptr = &(*ptr)->idb_next) - if (*ptr == idb) - { - *ptr = idb->idb_next; - break; - } - ALLI_release((BLK) idb); - } -} - - -static void service_start( ICC icc) -{ -/************************************** - * - * s e r v i c e _ s t a r t - * - ************************************** - * - * Functional description - * Start a service. - * - **************************************/ - IDB idb; - ISC_STATUS_ARRAY status_vector; - ISC_STATUS result; - ips_object *ips; - ips_comm_area *comm; - ips_string *ips_spb; - TEXT *comm_ptr; - USHORT spb_length; - UCHAR *spb, spb_buf[256]; - HANDLE handle; - ULONG *reserved = 0; - -// set up communications area - GET_COMM_OBJECT; - comm->ips_operation = op_service_start; - ips = &comm->ips_operations.ips_op_object; - handle = (HANDLE) ips->ips_handle; - -// figure out spb buffer - ips_spb = &comm->ips_buffers[IPS_START_SVC_SPB]; - spb_length = (USHORT) ips_spb->ips_cl_size; - if (spb_length <= sizeof(spb_buf)) - spb = spb_buf; - else - spb = get_buffer(comm, spb_length, IPS_START_SVC_SPB); - NOT_NULL(spb, spb_length); - - IPS_SERVER(comm, IPS_START_SVC_SPB, spb, spb_length); - - if (!transfer_buffers(icc, comm)) - return; - - idb = (IDB) handle; - CHECK_HANDLE(idb, type_idb, isc_bad_svc_handle); - result = GDS_SERVICE_START(status_vector, - &idb->idb_handle, - reinterpret_cast(reserved), - spb_length, reinterpret_cast(spb)); - - send_response(icc, status_vector); -} - - -static void set_cursor( ICC icc) -{ -/************************************** - * - * s e t _ c u r s o r - * - ************************************** - * - * Functional description - * Set a cursor name for a dynamic request. - * - **************************************/ - IPSERVER_ISR statement; - USHORT length, type; - UCHAR *cursor; - ISC_STATUS_ARRAY status_vector; - ips_dsql *ips; - ips_string *ips_name; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_dsql; - statement = (IPSERVER_ISR) ips->ips_st_handle; - CHECK_HANDLE(statement, type_ipserver_isr, isc_bad_stmt_handle); - type = (USHORT) ips->ips_parameter; - - // set up cursor name - - ips_name = &comm->ips_buffers[IPS_DSQL_SET_CURSOR]; - length = (USHORT) ips_name->ips_cl_size; - cursor = get_buffer(comm, length, IPS_DSQL_SET_CURSOR); - NOT_NULL(cursor, length); - IPS_SERVER(comm, IPS_DSQL_SET_CURSOR, cursor, length); - if (!transfer_buffers(icc, comm)) - return; - - // set cursor name - - GDS_DSQL_SET_CURSOR(status_vector, - &statement->isr_handle, - reinterpret_cast(cursor), type); - send_response(icc, status_vector); -} - - -static void shutdown_attachments( ICC icc) -{ -/************************************** - * - * s h u t d o w n _ a t t a c h m e n t s - * - ************************************** - * - * Functional description - * About to exit, detach any remaining database - * and service attachments. - * - **************************************/ - IDB idb, nextidb; - ISC_STATUS_ARRAY status_vector; - ips_comm_area *comm; - USHORT i; - - for (idb = icc->icc_databases; idb; idb = nextidb) - { - // save next pointer here because the structure's getting freed - - nextidb = idb->idb_next; - if (idb->idb_flags | IDBF_DATABASE_ATTACHMENT) - { - while (idb->idb_transactions) - { - if (!(idb->idb_transactions->itr_flags & ITR_limbo)) - GDS_ROLLBACK(status_vector, &idb->idb_transactions->itr_handle); - else - gds__handle_cleanup(status_vector, - (FB_API_HANDLE*) &idb->idb_transactions->itr_handle); - - release_transaction(idb->idb_transactions); - } - - GDS_DETACH(status_vector, &idb->idb_handle); - while (idb->idb_events) - release_event(idb->idb_events); - - while (idb->idb_requests) - release_request(idb->idb_requests); - - while (idb->idb_sql_requests) - release_sql_request(idb->idb_sql_requests); - } - else - { - GDS_SERVICE_DETACH(status_vector, &idb->idb_handle); - } - - ALLI_release((BLK) idb); - } - -// free any allocated server buffers - - comm = (ips_comm_area *) icc->icc_mapped_addr; - for (i = 0; i < MAX_IPS_STRINGS; i++) - if (comm->ips_buffers[i].ips_sv_buffer) - gds__free(comm->ips_buffers[i].ips_sv_buffer); -} - - -static void start( ICC icc) -{ -/************************************** - * - * s t a r t - * - ************************************** - * - * Functional description - * - **************************************/ - ISC_STATUS_ARRAY status_vector; - IRQ request; - ITR transaction; - USHORT level; - ips_request *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_request; - request = (IRQ) ips->ips_rq_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - transaction = (ITR) ips->ips_tr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - level = ips->ips_req_level; - - // start the request - - GDS_START(status_vector, &request->irq_handle, &transaction->itr_handle, - level); - send_response(icc, status_vector); -} - - -static void start_and_send( ICC icc) -{ -/************************************** - * - * s t a r t _ a n d _ s e n d - * - ************************************** - * - * Functional description - * - **************************************/ - ISC_STATUS_ARRAY status_vector; - IRQ request; - ITR transaction; - USHORT length, number, level; - ips_request *ips; - ips_string *ips_message; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_request; - request = (IRQ) ips->ips_rq_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - transaction = (ITR) ips->ips_tr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - number = ips->ips_msg_type; - level = ips->ips_req_level; - - // set up message - - ips_message = &comm->ips_buffers[IPS_SEND_MESSAGE]; - length = (USHORT) ips_message->ips_cl_size; - const UCHAR* buffer = get_buffer(comm, length, IPS_SEND_MESSAGE); - NOT_NULL(buffer, length); - IPS_SERVER(comm, IPS_SEND_MESSAGE, buffer, length); - number = ips->ips_msg_type; - level = ips->ips_req_level; - if (!transfer_buffers(icc, comm)) - return; - - // start the request - - GDS_START_AND_SEND(status_vector, &request->irq_handle, - &transaction->itr_handle, number, length, buffer, level); - send_response(icc, status_vector); -} - - -static void start_transaction( ICC icc) -{ -/************************************** - * - * s t a r t _ t r a n s a c t i o n - * - ************************************** - * - * Functional description - * Start a transaction. - * - **************************************/ - IDB idb; - ITR transaction; - USHORT count, c; - UCHAR *buffer; - FB_API_HANDLE handle; - ULONG **v, *vector[3 * 16]; - ISC_STATUS_ARRAY status_vector; - ips_start_trans *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - ULONG length, l, *lp; - - - // set up communications area - - GET_COMM_OBJECT; - lp = (ULONG *) comm_ptr; - ips = &comm->ips_operations.ips_op_strt_trans; - v = vector; - count = ips->ips_db_count; - buffer = get_buffer(comm, 1024, 0); - NOT_NULL(buffer, TRUE); - - // set up all the handles - - for (c = 0; c < count; c++) - { - idb = (IDB) * lp++; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - *v++ = reinterpret_cast < ULONG * >(&idb->idb_handle); - length = *lp++; - *v++ = reinterpret_cast < ULONG * >(length); - *v++ = reinterpret_cast < ULONG * >(buffer); - comm_ptr = (TEXT *) lp; - for (l = 0; l < length; l++) - *buffer++ = *comm_ptr++; - lp = lp + ((length + (sizeof(ULONG) - 1)) / sizeof(ULONG)); - } - handle = NULL; - - // start the transaction and return the handle - - GDS_START_MULTIPLE(status_vector, &handle, count, (UCHAR *) vector); - transaction = make_transaction(idb, handle); - ips->ips_tr_handle = (UCHAR *) transaction; - NOT_NULL(transaction, TRUE); - send_response(icc, status_vector); -} - - -static void transact_request( ICC icc) -{ -/************************************** - * - * t r a n s a c t _ r e q u e s t - * - ************************************** - * - * Functional description - * - **************************************/ - IDB idb; - ITR transaction; - USHORT blr_length, in_msg_length, out_msg_length; - UCHAR *blr, *in_buffer, *out_buffer; - ISC_STATUS_ARRAY status_vector; - ips_transact_request *ips; - ips_string *ips_blr; - ips_string *ips_in_msg; - ips_string *ips_out_msg; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_trans_req; - idb = (IDB) ips->ips_db_handle; - CHECK_HANDLE(idb, type_idb, isc_bad_db_handle); - transaction = (ITR) ips->ips_tr_handle; - CHECK_HANDLE(transaction, type_itr, isc_bad_trans_handle); - - // set up blr - - ips_blr = &comm->ips_buffers[IPS_TRANS_REQ_BLR]; - blr_length = (USHORT) ips_blr->ips_cl_size; - blr = get_buffer(comm, blr_length, IPS_TRANS_REQ_BLR); - NOT_NULL(blr, blr_length); - IPS_SERVER(comm, IPS_TRANS_REQ_BLR, blr, blr_length); - - // set up input message - - ips_in_msg = &comm->ips_buffers[IPS_TRANS_REQ_IN_MSG]; - in_msg_length = (USHORT) ips_in_msg->ips_cl_size; - in_buffer = get_buffer(comm, in_msg_length, IPS_TRANS_REQ_IN_MSG); - NOT_NULL(in_buffer, in_msg_length); - IPS_SERVER(comm, IPS_TRANS_REQ_IN_MSG, in_buffer, in_msg_length); - - // set up blr - - ips_out_msg = &comm->ips_buffers[IPS_TRANS_REQ_OUT_MSG]; - out_msg_length = (USHORT) ips_out_msg->ips_cl_size; - out_buffer = get_buffer(comm, out_msg_length, IPS_TRANS_REQ_OUT_MSG); - NOT_NULL(out_buffer, out_msg_length); - IPS_SERVER(comm, IPS_TRANS_REQ_OUT_MSG, out_buffer, out_msg_length); - if (!transfer_buffers(icc, comm)) - return; - - // transact request and return output - - GDS_TRANSACT_REQUEST(status_vector, - &idb->idb_handle, - &transaction->itr_handle, - blr_length, - reinterpret_cast(blr), - in_msg_length, - reinterpret_cast(in_buffer), - out_msg_length, - reinterpret_cast(out_buffer)); - send_response(icc, status_vector); -} - - -static bool transfer_buffers( ICC icc, ips_comm_area * comm) -{ -/************************************** - * - * t r a n s f e r _ b u f f e r s - * - ************************************** - * - * Functional description - * - **************************************/ - ULONG to_copy; - USHORT i; - ips_string *string; - - - /* for each buffer, see if the client is sending stuff, and if so, - put the data in the server's buffers */ - - for (i = 0; i < MAX_IPS_STRINGS; i++) - { - string = &comm->ips_buffers[i]; - - // see if this buffer needs extraction - - if ((string->ips_flags & IPS_INPUT_BUFFER) && string->ips_sv_size) - { - string->ips_sv_copied = 0; - UCHAR* scursor = const_cast(string->ips_sv_addr); - - // start extraction - - while (string->ips_sv_copied < string->ips_sv_size) - { - - // extract all or whatever's available - - to_copy = string->ips_sv_size - string->ips_sv_copied; - if (string->ips_com_size <= to_copy) - to_copy = string->ips_com_size; - const TEXT* acursor = (TEXT*) comm->ips_data + string->ips_com_offset; - memcpy(scursor, acursor, (USHORT) to_copy); - scursor += to_copy; - string->ips_sv_copied += to_copy; - - // if there is more to copy, wait for it - - if (string->ips_sv_copied < string->ips_sv_size) - { - comm->ips_sequence++; - if (!send_and_wait(icc)) - return false; - } - } - } - } - return true; -} - - -static void unwind( ICC icc) -{ -/************************************** - * - * u n w i n d - * - ************************************** - * - * Functional description - * Unwind a request. - * - **************************************/ - IRQ request; - USHORT level; - ISC_STATUS_ARRAY status_vector; - ips_object *ips; - ips_comm_area *comm; - TEXT *comm_ptr; - - - // set up communications area - - GET_COMM_OBJECT; - ips = &comm->ips_operations.ips_op_object; - request = (IRQ) ips->ips_handle; - CHECK_HANDLE(request, type_irq, isc_bad_req_handle); - level = (USHORT) ips->ips_parameter; - - // unwind the request - - GDS_UNWIND(status_vector, &request->irq_handle, level); - send_response(icc, status_vector); -} - - -static bool wait_no_send( ICC icc) -{ -/************************************** - * - * w a i t _ n o _ s e n d - * - ************************************** - * - * Functional description - * This function waits for the client's next - * request by waiting on the server's semaphore. - * - **************************************/ - DWORD result1; - DWORD result2; - DWORD error1; - DWORD error2; - bool ret; - - - // already in shutdown mode - - if (icc->icc_flags & ICCF_SHUTDOWN) - return false; - - // wait for the server to signal us back - - ret = true; - while (ret) - { - - // wait for semaphore for a minute - - result1 = WaitForSingleObject(icc->icc_waits[0], 10000L); - error1 = GetLastError(); - - // check for success - - if (result1 == WAIT_OBJECT_0) - break; - - // a non-timeout result is an error - - if (result1 != WAIT_TIMEOUT) - { -#ifdef DEBUG_IP_TRACE - gds__log("ipserver wait no send failed %lX %ld %ld", - (long) icc, result1, error1); - gds__log("ipserver ids %lX %lX", - icc->icc_waits[0], icc->icc_waits[1]); -#endif - ret = false; - break; - } - - // see if the client is still alive - - result2 = WaitForSingleObject(icc->icc_waits[1], 1L); - error2 = GetLastError(); - - // if process is gone, or there's some error, bag it - - if (result2 != WAIT_TIMEOUT) - { -#ifdef DEBUG_IP_TRACE - gds__log("ip server wait no send failed again %lX %ld %ld", - (long) icc, result2, error2); -#endif - ret = false; - break; - } - } - if (!ret) - icc->icc_flags |= ICCF_SHUTDOWN; - return ret; -} - diff --git a/src/ipserver/ipsrv_proto.h b/src/ipserver/ipsrv_proto.h deleted file mode 100644 index 2c1f3b2a98..0000000000 --- a/src/ipserver/ipsrv_proto.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * PROGRAM: Interprocess server - * MODULE: ips_proto.h - * DESCRIPTION: Prototpe header file for ipserver.cpp - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -#ifndef IPSRV_PROTO_H -#define IPSRV_PROTO_H - -USHORT IPS_init(HWND, USHORT, USHORT, USHORT); -ULONG IPS_start_thread(ULONG); - -#endif /* IPSRV_PROTO_H */ -