1  static char Version[] = "@(#) extsub.c 1.1 10/11/94 05:30:56";
  2  /****************************************************************
3  *                                                               *
  4  *  Module : extsub.c - User Written External Subroutines        *
  5  *                                                               *
  6  *  Description -This is a stub module for the support of up to  *
  7  *               10 external function calls via the LINK command *
  8  *                                                               *

  9  *  Functions : extsub()                                         *
 10  *  History :                                                    *
 11  *                                                               *
 12  *  Modified:    By:            Reason:                          *
 13  *  ---------    ---            -------                          *
 14  *  30-Apr-92    R. Williamson  Support for Unix  added.         *
 15  *  16-Aug-93    H. H-Wilkinson Support for MS-Windows added.    *
 16  *                                                               *
 17  ****************************************************************/
 18   
 19  #if (defined(__WINDOWS__) && defined(GUI))
 20  #define PROWIN    /* special code for invoking EXTSUB DLL */
 21  #define EXPORTED
 22  #else
 23   
 24  #  if defined(_WINDOWS)
 25  #  define WINDLL  /* special code for EXTSUB DLL */
 26  #  define EXPORTED __export
 27   
 28  #  else
 29  #  define EXPORTED
 30  #  endif /* _WINDOWS */
 31  #endif   /* __WINDOWS__ && GUI */
 32   
 33   
 34  #if defined(WINDLL)
 35  #  include <windows.h>
 36  #  include <string.h>
 37  #  include <malloc.h>
 38  #  include "multinst.h"
 39  #  include "extsub.h"
 40   
 41  #  define  MESSAGEBOX(s,f)  
     MessageBox(GetActiveWindow(),s, "ExtSub",MB_TASKMODAL | f)

 42  #  define  dim(x)           sizeof(x)/sizeof(x[0])

 43   
 44     HANDLE   DLLInstance;   /* DLL instance handle */
 45     PPROSUB  prosub=NULL;   /* ptr->callback table */
 46     char *   szPROIniFile;  /* name of PRO
IV's initialisation file */
 47   
 48     extern int sub0();
 49     extern int sub1();
 50     extern int sub2();
 51     extern int sub3();
 52     extern int sub4();
 53     extern int sub5();
 54     extern int sub6();
 55     extern int sub7();
 56     extern int sub8();
 57     extern int sub9();
 58   
 59  #  ifdef DEBUG
 60  #  include <stdarg.h>
 61     extern int WINAPI wvsprintf(LPSTR, LPCSTR, const void FAR *);
 62   
 63     void __cdecl DBMSG(LPCSTR lpszFmt, ...)
 64     {
 65        char  szDebugString[140];
 66   
 67        va_list arg_ptr;
 68        va_start(arg_ptr, lpszFmt);
 69   
 70        szDebugString[0] = '\0';
 71        wvsprintf(szDebugString, lpszFmt, arg_ptr); va_end(arg_ptr);
 72   
 73        OutputDebugString(szDebugString);
 74        //MESSAGEBOX(szDebugString, MB_ICONEXCLAMATION | MB_OK);
 75     }
 76  #  else
 77  #  define DBMSG(s)
 78  #  endif
 79   
 80     /* DLL startup routine */
 81     int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD cbHeapSize,
 82                            LPSTR lpszCmdLine)
 83     {
 84        /* unlock DLL data seg is MOVEABLE */
 85        if((cbInitialHeapSize = cbHeapSize) != 0)
 86           UnlockData (0);
 87   
 88        /* save instance handle */
 89        DLLInstance = hInstance;
 90        return (InitInstanceData(wDataSeg));
 91     }
 92   
 93     int EXPORTED init(char *inifile, PPROSUB p)
 94     {
 95        /* Get DS for this task instance
 96        ** if DS==0 then we are out of memory so return  
 97        */
 98        if( !LOADTASKDS(0) ) return -1;
 99   
100        prosub = p;
101        szPROIniFile = _strdup(inifile);
102        return 0;
103     }
104   
105     void EXPORTED term(void)
106     {
107        /* Get DS for this task instance
108        ** if DS==0 then we are out of memory so return  
109        */
110        if( !LOADTASKDS(0) ) return;
111   
112        if( szPROIniFile ) free(szPROIniFile);
113        UnregisterTask(0);
114     }
115  #endif /* WINDLL */
116   
117   
118  /***************************************************************/
193  #if !defined(AS400) && !defined(PROWIN)
194  #include <string.h>
195   
196  static char *subtbl[] = {
197                     "SUB0",
198                     "SUB1",
199                     "SUB2",
200                     "SUB3",
201                     "SUB4",
202                     "SUB5",
203                     "SUB6",
204                     "SUB7",
205                     "SUB8",
206                     "SUB9"
207                  };
208   
209  #define nsubs sizeof(subtbl)/sizeof(subtbl[0])
210   
211  /****************************************************************
212  *  strsrch()
213  *  simple linear search routine
214  *
215  ****************************************************************/
216   
217  static short strsrch(subname)
218  char *subname;
219  {
220      short index;
221   
222      for (index = 0;index < nsubs;index++)
223        {
224          if (!strcmp(subname,subtbl[index]))
225              return(index);
226        }
227   
228      /* subname is not in the table */
229      return -1;
230  }
231  #endif /* !AS400 && !PROWIN */
232   
233   
234  /****************************************************************
235  *                                                               *
236  *  extsub() is called                                           *
237  *  when the logic LINK command is executed. It searches the     *
238  *  subroutine name table (subtbl) for an entry matching the     *
239  *  user requested external subroutine name (argv[0]).           *
240  *  If a match is found it calls the routine based on the index  *
241  *  returned from the search routine. All external               *
242  *  functions are called with 10 arguments even if LINK was      *
243  *  called with less. This is a maximum imposed by the stub and  *
244  *  can be increased by the user if required                     *
245  *                                                               *
246  *                                                               *
247  ****************************************************************/
248   
249  int EXPORTED extsub(count,args)
250  short count;
251  void *args[];
252  {
253      short index;
254      int   retcode = 0;
255   
256  #if defined(PROWIN)
257      char  **args16, *p;
258      int   i, j, lib, suffix;
259   
260  #   include <string.h>
261  #   include <stdlib.h>
262  #   include <windows.h>
263  #   include "..\supv\dll16.h"
264   
265      suffix = 0; /* no module name prefix */
266      lib    = 0; /* default to 1st library */
267   
268      /* look for module name delimiter */
269      if((p = strchr(args[0], '.')))
270      {
271        /*
272        ** 'modulename.function' syntax used, so check
273        ** if specified module was loaded.
274        */
275        for(i=p-args[0], j=0; j < MAX_EXTSUBS && ExtSubs[j].hInst; j++)
276        {
277           if(strnicmp(args[0], ExtSubs[j].szPrefix, i) == 0)
278           {
279              lib = j;
280              suffix = i + 1;
281              break;
282           }
283        }
284      }
285   
286      args16 = (char **)malloc(sizeof(char *) * count);
287      if(!args16) return -1;
288   
289      /*
290      ** allocate 16-bit far pointer equivalents for 32-bit pointers
291      ** Note: if index 0 then ensure that we pass the actual function
292      **       name string and not the 'modulename.function' string.
293      */
294      for(index=0; index < count; index++)
295         args16[index] = (char *)AllocAlias16(
296            index ? args[index] : &((char *)args[0])[suffix]);
297   
298      /* invoke external functions despatcher */
299      retcode = ES_extsub(lib, count, args16);
300   
301      /* free allocated resources */
302      for(index=0; index < count; index++)
303         FreeAlias16((DWORD)args16[index]);   
304   
305      free(args16);
306   
307  #else /* !PROWIN */
308  #ifdef AS400
309      /* Use the __callpgm system routine.                        */
310      /* Program name (as specified by first parameter of LINK)   */
311      /* must be locatable in "*LIBL".                            */
312      /* Max number of parameters allowed is 20.                  */
313      /* Returns: 0 = OK                                          */
314      /*         -1 = program not found                           */
315      /*         -2 = too many parameters specified               */
316   
317      retcode = call_program(count, args);
318   
319  #else /* !AS400 */
320   
321  #if defined(WINDLL)
322   
323      /* Get DS for this task instance
324      ** if DS==0 then we are out of memory so return  
325      */
326      if( !LOADTASKDS(0) ) return 0;
327  #endif /* WINDLL */
328   
329      /* add/modify this switch statement to call your own routines with however */
330      /* many parameters they require */
331      /* args[0] is used to store the function name to call */
332      /* count gives the number of arguments being passed */
333   
334      /* first search the table for the given name*/
335   
336      if ((index = strsrch(args[0])) != -1)
337      {
338         switch (index)
339         {
340            case 0  :
341               retcode = sub0(args[1],args[2],args[3],args[4],args[5],args[6],
342                     args[7],args[8],args[9],args[10]);
343               break;
344   
345            case 1  :
346               retcode = sub1(args[1],args[2],args[3],args[4],args[5],args[6],
347                     args[7],args[8],args[9],args[10]);
348   
349               break;
350   
351            case 2  :
352               retcode = sub2(args[1],args[2],args[3],args[4],args[5],args[6],
353                              args[7],args[8],args[9],args[10]);
354   
355               break;
356   
357            case 3  :
358               retcode = sub3(args[1],args[2],args[3],args[4],args[5],args[6],
359                              args[7],args[8],args[9],args[10]);
360   
361               break;
362   
363            case 4  :
364               retcode = sub4(args[1],args[2],args[3],args[4],args[5],args[6],
365                              args[7],args[8],args[9],args[10]);
366   
367               break;
368   
369            case 5  :
370               retcode = sub5(args[1],args[2],args[3],args[4],args[5],args[6],
371                              args[7],args[8],args[9],args[10]);
372   
373               break;
374   
375            case 6  :
376               retcode = sub6(args[1],args[2],args[3],args[4],args[5],args[6],
377                              args[7],args[8],args[9],args[10]);
378   
379               break;
380   
381            case 7  :
382               retcode = sub7(args[1],args[2],args[3],args[4],args[5],args[6],
383                              args[7],args[8],args[9],args[10]);
384   
385               break;
386   
387            case 8  :
388               retcode = sub8(args[1],args[2],args[3],args[4],args[5],args[6],
389                              args[7],args[8],args[9],args[10]);
390   
391               break;
392   
393            case 9  :
394               retcode = sub9(args[1],args[2],args[3],args[4],args[5],args[6],
395                              args[7],args[8],args[9],args[10]);
396   
397               break;
398   
399            default :
400               break;
401         }
402      }
403      else /* couldn't find the name in the table */
404      {
405         retcode = -1;
406      }
407  #endif /* AS400 */
408  #endif /* PROWIN */
409      return(retcode);
410  }
411   

412      
#endif

Comment on this topic

Topic ID: 750018

Table of Contents

Index

Glossary

-Search-

Back