![]() extsub.c |
![]() Virtual Machine |
![]() |
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 PROIV'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
Topic ID: 750018