source: trunk/src/win32k/test/win32ktst.c@ 3832

Last change on this file since 3832 was 3829, checked in by bird, 25 years ago

Early development.

File size: 20.6 KB
Line 
1/* $Id: win32ktst.c,v 1.1 2000-07-16 22:18:16 bird Exp $
2 *
3 * Win32k test module.
4 *
5 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define INCL_BASE
15#define INCL_OS2KRNL_ALL
16#define INCL_SSTODS
17
18#define SEL_FLATMASK 0x01fff0000
19#define SEL_FLAT_SHIFT 0x0d
20#define SEL_LDT_RPL3 0x07
21
22#define SelToFlat(sel, off) \
23 (PVOID)( (((unsigned)(sel) << SEL_FLAT_SHIFT) & SEL_FLAT_MASK) + (unsigned)(off))
24
25#define FlatToSel(flataddr) \
26 (PVOID)( ( (((unsigned)(flataddr) << 3) & 0xfff80000) | (SEL_LDT_RPL3 << 16) ) | ((unsigned)(flataddr) & 0xffff) )
27
28/*******************************************************************************
29* Internal Functions *
30*******************************************************************************/
31#include <os2.h>
32
33#include "malloc.h"
34
35#include <stdio.h>
36#include <string.h>
37#include <stdlib.h>
38
39#include "options.h"
40#include "dev1632.h"
41#include "dev32.h"
42#include "devcmd.h"
43#include "os2krnl.h"
44#include "ldrCalls.h"
45#include "test.h"
46#include "asmutils.h"
47#include "macros.h"
48#include "log.h"
49
50
51/** @design Win32k Ring-3 Testing
52 * I'll try to make it possible to test parts or all the win32k code in ring-3.
53 * To archive this the interface against the kernel has to be faked/emulated.
54 * More precisely:
55 * - DevHelps.
56 * - Worker routines for imported kernel functions. (calltab.asm jumps to them.)
57 * - 16-bit stack 1Kb.
58 * - Strategy calls.
59 * - Fake module loadings (= testcases).
60 * - ?
61 *
62 * Some of the initstuff has to be omitted, at least in the start. The first
63 * goal is to be able to test _ldrOpenPath and _ldrOpen.
64 *
65 *
66 * @subsection Device Helper Routines
67 *
68 * These I think we'll implemented by providing the kernel interface, a far 16:16
69 * pointer to a dh-router. Our router will in most cases thunk back to 32-bit
70 * code and implementet the required devhelp routines in pure C code.
71 *
72 * These are the needed routines:
73 * - DevHelp_VirtToLin - ok
74 * - DevHelp_VMAlloc - ok
75 * - DevHelp_VMFree - ok
76 * - DevHelp_GetDOSVar - ok
77 * - DevHelp_VMLock
78 * - DevHelp_VMUnLock ?
79 * - DevHelp_VMSetMem ?
80 * - DevHelp_Yield ?
81 *
82 *
83 * @subsection Worker routines for imported kernel functions
84 *
85 * Create worker routines for the imported kernel functions. Calltab will be
86 * set up to jump to them. This is done in d32init.c, in stead of using
87 * the importtab.
88 *
89 * Some of these workers will be parts of testcases. For example g_tkExecPgm
90 * and _LDRQAppType.
91 *
92 * Only the imported functions are implemented on demand. Initially these
93 * functions will be provided:
94 * - ldrOpen
95 * - ldrRead
96 * - ldrClose
97 * - ldrOpenPath
98 * - SftFileSize
99 *
100 *
101 * @subsection 16-bit stack
102 *
103 * To make this test real the stack has to be 16-bit and _very_ small (1KB).
104 * TKSSBase have to be implemented by the DevHelp_GetDOSVar DosTable2 stuff.
105 * The stack will be thunked to 16-bit by a thunking procedure called from
106 * main. This procedure thunks the stack (quite easy, we're in tiled memory!),
107 * set the value of TKSSBase, calls a C function which does all the rest of
108 * the testing. When taht function returns, the stack will be thunked back
109 * to 32-bit, TKSSBase will be zeroed, and the procedure returns to main.
110 *
111 *
112 * @subsection Straegy routine calls (not implemented)
113 *
114 * We'll call the strategy entry points with init request packets. The initiation
115 * will require a replacement for DosDevIOCtl (16-bit) which calls the
116 * $elf strategy routine. We'll also have to provide fakes for kernel probing,
117 * verifing and overloading in d32init.c.
118 *
119 *
120 * @subsection Order of events
121 *
122 * This is the order this testing environment currently works:
123 * 1) init devhelp subsystem
124 * 2) init workers
125 * 3) thunk stack
126 * 4) Fake 16-bit init. Set TKSSBase, FlatDS, FlatCS, DevHelp pointer....
127 * 5) Call R0Init32().
128 * (d32init.c is modified a bit to setup the calltab correctly.)
129 * 6) Start testing...
130 * 7) Testing finished - thunk stack back to 32-bit.
131 */
132
133
134/*******************************************************************************
135* Internal Functions *
136*******************************************************************************/
137void syntax(void);
138void workersinit(void);
139void initRPInit(RP32INIT *pRpInit, char *pszInitArgs);
140int tests(int iTest, int argc, char **argv);
141int TestCase1(void);
142int TestCase2(void);
143int TestCase3(void);
144int TestCase4(void);
145int TestCase5(void);
146int CompareOptions(struct options *pOpt);
147int TestCaseExeLoad1(void);
148
149
150/*******************************************************************************
151* Global Variables *
152*******************************************************************************/
153extern BOOL fInited; /* malloc.c */
154const char * pszInternalRevision = "\r\nInternal revision 14.040_W4";
155int cObjectsFake = 14;
156
157
158
159/**
160 * Main function. Arguments _currently_ unused.
161 */
162int main(int argc, char **argv)
163{
164 int iTest;
165 int rc;
166
167 /*
168 * Init devhelp subsystems.
169 */
170 dhinit();
171
172 /*
173 * Parse arguments.
174 * (printf don't work before dhinit is called...)
175 */
176 if (argc < 2 || (iTest = atoi(argv[1])) <= 0)
177 {
178 syntax();
179 printf("syntax error\n");
180 return -1;
181 }
182
183 /*
184 * Init workers if necessary.
185 */
186 workersinit();
187
188
189 /*
190 * Thunk Stack to 16-bits.
191 *
192 * IMPORTANT! From now on SSToDS have to be used when making pointers
193 * to stack objects.
194 */
195 ThunkStack32To16();
196
197 rc = tests(iTest, argc, argv);
198
199 /*
200 * Thunk Stack back to 32-bits.
201 */
202 ThunkStack16To32();
203
204
205 /*
206 * To avoid a sfree error message we'll set fInited (heap init flag) to false.
207 */
208 fInited = FALSE;
209 return rc;
210}
211
212
213/**
214 * Prints syntax information.
215 * @status partially implemented.
216 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
217 */
218void syntax(void)
219{
220 printf(
221 "Win32kTst.exe v%d.%d.%d - Ring 3 testing of win32k.sys\n"
222 "syntax: Win32kTst.exe <testcase number> [optional arguments]\n",
223 0,0,4
224 );
225}
226
227
228/**
229 * Initiate workers (imported kernel functions / vars)
230 * @status partially implemented.
231 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
232 */
233void workersinit(void)
234{
235 DosSetMem(&CODE16START, &CODE16END - &CODE16START, PAG_WRITE | PAG_READ);
236 DosSetMem(&CODE32START, &CODE32END - &CODE32START, PAG_WRITE | PAG_READ);
237}
238
239
240/**
241 * Initiates a init reqest packet.
242 * @param pRpInit Pointer to request packet to init.
243 * @param pszInitArgs Pointer to init arguments.
244 * @status completely implemented.
245 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
246 */
247void initRPInit(RP32INIT *pRpInit, char *pszInitArgs)
248{
249 /* $elf */
250 memset(pRpInit, 0, sizeof(RP32INIT));
251 pRpInit->rph.Len = sizeof(RP32INIT);
252 pRpInit->rph.Cmd = CMDInit;
253 pRpInit->DevHlpEP = getDHRouterFarPtr();
254 pRpInit->InitArgs = (PSZ)FlatToSel(pszInitArgs);
255}
256
257
258/**
259 * Testcase fan-out.
260 * @returns Testcase return value.
261 * -2 if testcase not found.
262 * @param iTest Testcase number.
263 * @param argc main argc
264 * @param argv main argv
265 * @status completely implemented.
266 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
267 */
268int tests(int iTest, int argc, char **argv)
269{
270 int rc;
271
272 printf("-------------------------------- Testcase %d:\n", iTest);
273 switch (iTest)
274 {
275 case 1: rc = TestCase1(); break;
276 case 2: rc = TestCase2(); break;
277 case 3: rc = TestCase3(); break;
278 case 4: rc = TestCase4(); break;
279 case 5: rc = TestCase5(); break;
280
281 default:
282 printf("testcase no. %d is not found\n", iTest);
283 rc = -2;
284 }
285 printf("result %d -----------------------------------\n", rc);
286
287 NOREF(argc);
288 NOREF(argv);
289 return rc;
290}
291
292
293
294/**
295 * Test case 1.
296 * Checks that default initiation works fine for Aurora SMP kernels.
297 *
298 * @sketch Create init packet with no arguments.
299 * Initiate elf$
300 * Create init packet with no arguments.
301 * Initiate win32k$
302 * @returns 0 on success.
303 * 1 on failure.
304 * @status completely implemented.
305 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
306 */
307int TestCase1(void)
308{
309 int rc = 1;
310 RP32INIT rpinit;
311
312 /* init fake variabels */
313 pszInternalRevision ="\r\nInternal revision 14.040_SMP";
314 cObjectsFake = 15;
315 _usFakeVerMajor = 20;
316 _usFakeVerMinor = 45;
317
318 /* $elf */
319 initRPInit(SSToDS(&rpinit), "-w3");
320 rc = InitElf(&rpinit); /* no SSToDS! */
321 printf("InitElf returned status=0x%04x\n", rpinit.rph.Status);
322 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
323 {
324 /* $win32k */
325 initRPInit(SSToDS(&rpinit), "-w3");
326 rc = InitWin32k(&rpinit); /* no SSToDS! */
327 printf("InitWin32k returned status=0x%04x\n", rpinit.rph.Status);
328 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
329 {
330 struct options opt = DEFAULT_OPTION_ASSIGMENTS;
331 opt.fKernel = KF_SMP;
332 opt.ulBuild = 14040;
333 opt.usVerMajor = 20;
334 opt.usVerMinor = 45;
335 opt.ulInfoLevel = 3;
336
337 rc = CompareOptions(SSToDS(&opt));
338 if (rc == NO_ERROR)
339 {
340 rc = TestCaseExeLoad1();
341 }
342 }
343 else
344 printf("!failed!\n");
345 }
346 else
347 printf("!failed!\n");
348
349 return rc;
350}
351
352
353/**
354 * Test case 2.
355 * Checks that default initiation works fine for Aurora UNI kernels.
356 *
357 * @sketch Create init packet with no arguments.
358 * Initiate elf$
359 * Create init packet with no arguments.
360 * Initiate win32k$
361 * @returns 0 on success.
362 * 1 on failure.
363 * @status completely implemented.
364 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
365 */
366int TestCase2(void)
367{
368 int rc = 1;
369 RP32INIT rpinit;
370
371 /* init fake variabels */
372 pszInternalRevision ="\r\nInternal revision 14.040_UNI";
373 cObjectsFake = 14;
374 _usFakeVerMajor = 20;
375 _usFakeVerMinor = 45;
376
377 /* $elf */
378 initRPInit(SSToDS(&rpinit), "");
379 rc = InitElf(&rpinit); /* no SSToDS! */
380 printf("InitElf returned status=0x%04x\n", rpinit.rph.Status);
381 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
382 {
383 /* $win32k */
384 initRPInit(SSToDS(&rpinit), "");
385 rc = InitWin32k(&rpinit); /* no SSToDS! */
386 printf("InitWin32k returned status=0x%04x\n", rpinit.rph.Status);
387 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
388 {
389 struct options opt = DEFAULT_OPTION_ASSIGMENTS;
390 opt.fKernel = KF_UNI;
391 opt.ulBuild = 14040;
392 opt.usVerMajor = 20;
393 opt.usVerMinor = 45;
394
395 rc = CompareOptions(SSToDS(&opt));
396 }
397 else
398 printf("!failed!\n");
399 }
400 else
401 printf("!failed!\n");
402
403 return rc;
404}
405
406
407/**
408 * Test case 3.
409 * Checks that default initiation works fine for Warp FP13 kernel.
410 *
411 * @sketch Create init packet with no arguments.
412 * Initiate elf$
413 * Create init packet with no arguments.
414 * Initiate win32k$
415 * @returns 0 on success.
416 * 1 on failure.
417 * @status completely implemented.
418 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
419 */
420int TestCase3(void)
421{
422 int rc = 1;
423 RP32INIT rpinit;
424
425 /* init fake variabels */
426 pszInternalRevision ="\r\nInternal revision 14.040_W4";
427 cObjectsFake = 14;
428 _usFakeVerMajor = 20;
429 _usFakeVerMinor = 45;
430
431 /* $elf */
432 initRPInit(SSToDS(&rpinit), "");
433 rc = InitElf(&rpinit); /* no SSToDS! */
434 printf("InitElf returned status=0x%04x\n", rpinit.rph.Status);
435 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
436 {
437 /* $win32k */
438 initRPInit(SSToDS(&rpinit), "");
439 rc = InitWin32k(&rpinit); /* no SSToDS! */
440 printf("InitWin32k returned status=0x%04x\n", rpinit.rph.Status);
441 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
442 {
443 struct options opt = DEFAULT_OPTION_ASSIGMENTS;
444 opt.fKernel = KF_UNI | KF_W4;
445 opt.ulBuild = 14040;
446 opt.usVerMajor = 20;
447 opt.usVerMinor = 45;
448
449 rc = CompareOptions(SSToDS(&opt));
450 }
451 else
452 printf("!failed!\n");
453 }
454 else
455 printf("!failed!\n");
456
457 return rc;
458}
459
460
461/**
462 * Test case 4.
463 * Checks that default initiation works fine for Aurora SMP kernels.
464 *
465 * @sketch Create init packet with no arguments.
466 * Initiate elf$
467 * Create init packet with no arguments.
468 * Initiate win32k$
469 * @returns 0 on success.
470 * 1 on failure.
471 * @status completely implemented.
472 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
473 */
474int TestCase4(void)
475{
476 int rc = 1;
477 RP32INIT rpinit;
478
479 /* init fake variabels */
480 pszInternalRevision ="\r\nInternal revision 9.036";
481 cObjectsFake = 14;
482 _usFakeVerMajor = 20;
483 _usFakeVerMinor = 40;
484
485 /* $elf */
486 initRPInit(SSToDS(&rpinit), "");
487 rc = InitElf(&rpinit); /* no SSToDS! */
488 printf("InitElf returned status=0x%04x\n", rpinit.rph.Status);
489 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
490 {
491 /* $win32k */
492 initRPInit(SSToDS(&rpinit), "");
493 rc = InitWin32k(&rpinit); /* no SSToDS! */
494 printf("InitWin32k returned status=0x%04x\n", rpinit.rph.Status);
495 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
496 {
497 struct options opt = DEFAULT_OPTION_ASSIGMENTS;
498 opt.fKernel = KF_UNI;
499 opt.ulBuild = 9036;
500 opt.usVerMajor = 20;
501 opt.usVerMinor = 40;
502
503 rc = CompareOptions(SSToDS(&opt));
504 }
505 else
506 printf("!failed!\n");
507 }
508 else
509 printf("!failed!\n");
510
511 return rc;
512}
513
514
515/**
516 * Test case 5.
517 * Checks that all parameters are read correctly (1) (Warp FP13 kernel).
518 *
519 * @sketch Create init packet with no arguments.
520 * Initiate elf$
521 * Create init packet with no arguments.
522 * Initiate win32k$
523 * @returns 0 on success.
524 * 1 on failure.
525 * @status completely implemented.
526 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
527 */
528int TestCase5(void)
529{
530 int rc = 1;
531 RP32INIT rpinit;
532 char * pszInitArgs = "-C1 -L:N -Verbose -Quiet -Elf:Yes -Pe:Mixed -Script:No -W4 -Heap:512000 -ResHeap:0256000 -HeapMax:4096000 -ResHeapMax:0x100000";
533
534 /* init fake variabels */
535 pszInternalRevision ="\r\nInternal revision 14.040_W4";
536 cObjectsFake = 14;
537 _usFakeVerMajor = 20;
538 _usFakeVerMinor = 45;
539
540 /* $elf */
541 initRPInit(SSToDS(&rpinit), pszInitArgs);
542 rc = InitElf(&rpinit); /* no SSToDS! */
543 printf("InitElf returned status=0x%04x\n", rpinit.rph.Status);
544 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
545 {
546 /* $win32k */
547 initRPInit(SSToDS(&rpinit), pszInitArgs);
548 rc = InitWin32k(&rpinit); /* no SSToDS! */
549 printf("InitWin32k returned status=0x%04x\n", rpinit.rph.Status);
550 if ((rpinit.rph.Status & (STDON | STERR)) == STDON)
551 {
552 struct options opt = DEFAULT_OPTION_ASSIGMENTS;
553 opt.fKernel = KF_UNI | KF_W4;
554 opt.ulBuild = 14040;
555 opt.usVerMajor = 20;
556 opt.usVerMinor = 45;
557 opt.cbSwpHeapInit = 512000;
558 opt.cbSwpHeapMax = 4096000;
559 opt.cbResHeapInit = 0256000;
560 opt.cbResHeapMax = 0x100000;
561 opt.fElf = TRUE;
562 opt.fUNIXScript = FALSE;
563 opt.fPE = FLAGS_PE_MIXED;
564 opt.fQuiet = TRUE;
565 opt.fLogging = FALSE;
566 opt.usCom = OUTPUT_COM1;
567 opt.ulInfoLevel = INFOLEVEL_INFOALL;
568
569 rc = CompareOptions(SSToDS(&opt));
570 }
571 else
572 printf("!failed!\n");
573 }
574 else
575 printf("!failed!\n");
576
577 return rc;
578}
579
580/**
581 * Compares the options with the option struct passed in.
582 * @returns 0 on success.
583 * number of mismatches on error.
584 * @param pOpt
585 * @status completely implemented.
586 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
587 */
588int CompareOptions(struct options *pOpt)
589{
590 int rc = 0;
591 /*
592 * Check that the option struct is correct.
593 */
594 if (options.fQuiet != pOpt->fQuiet)
595 printf("fQuiet = %d - should be %d\n", options.fQuiet, pOpt->fQuiet, rc++);
596 if (options.usCom != pOpt->usCom)
597 printf("usCom = %d - should be %d\n", options.usCom, pOpt->usCom, rc++);
598 if (options.fLogging != pOpt->fLogging)
599 printf("fLogging = %d - should be %d\n", options.fLogging, pOpt->fLogging, rc++);
600 if (options.fKernel != pOpt->fKernel)
601 printf("fKernel = %d - should be %d\n", options.fKernel, pOpt->fKernel, rc++);
602 if (options.ulBuild != pOpt->ulBuild)
603 printf("ulBuild = %d - should be %d\n", options.ulBuild, pOpt->ulBuild, rc++);
604 if (options.usVerMajor != pOpt->usVerMajor)
605 printf("usVerMajor = %d - should be %d\n", options.usVerMajor, pOpt->usVerMajor, rc++);
606 if (options.usVerMinor != pOpt->usVerMinor)
607 printf("usVerMinor = %d - should be %d\n", options.usVerMinor, pOpt->usVerMinor, rc++);
608 if (options.fPE != pOpt->fPE)
609 printf("fPE = %d - should be %d\n", options.fPE, pOpt->fPE, rc++);
610 if (options.ulInfoLevel != pOpt->ulInfoLevel)
611 printf("ulInfoLevel = %d - should be %d\n", options.ulInfoLevel, pOpt->ulInfoLevel, rc++);
612 if (options.fElf != pOpt->fElf)
613 printf("fElf = %d - should be %d\n", options.fElf, pOpt->fElf, rc++);
614 if (options.fUNIXScript != pOpt->fUNIXScript)
615 printf("fUNIXScript = %d - should be %d\n", options.fUNIXScript, pOpt->fUNIXScript, rc++);
616 if (options.fREXXScript != pOpt->fREXXScript)
617 printf("fREXXScript = %d - should be %d\n", options.fREXXScript, pOpt->fREXXScript, rc++);
618 if (options.fJava != pOpt->fJava)
619 printf("fJava = %d - should be %d\n", options.fJava, pOpt->fJava, rc++);
620 if (options.fNoLoader != pOpt->fNoLoader)
621 printf("fNoLoader = %d - should be %d\n", options.fNoLoader, pOpt->fNoLoader, rc++);
622 if (options.cbSwpHeapInit != pOpt->cbSwpHeapInit)
623 printf("cbSwpHeapInit = %d - should be %d\n", options.cbSwpHeapInit, pOpt->cbSwpHeapInit, rc++);
624 if (options.cbSwpHeapMax != pOpt->cbSwpHeapMax)
625 printf("cbSwpHeapMax = %d - should be %d\n", options.cbSwpHeapMax, pOpt->cbSwpHeapMax, rc++);
626 if (options.cbResHeapInit != pOpt->cbResHeapInit)
627 printf("cbResHeapInit = %d - should be %d\n", options.cbResHeapInit, pOpt->cbResHeapInit, rc++);
628 if (options.cbResHeapMax != pOpt->cbResHeapMax)
629 printf("cbResHeapMax = %d - should be %d\n", options.cbResHeapMax, pOpt->cbResHeapMax, rc++);
630
631 return rc;
632}
633
634
635
636
637/**
638 * Simulates a executable loading (no errors).
639 * This test requires a PE executable file named ExecLoad1.exe which
640 * imports the dll ExecLoad1d.dll.
641 *
642 * @returns 0 on success.
643 * > 0 on failure.
644 * @sketch
645 * @status
646 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
647 * @remark
648 */
649int TestCaseExeLoad1(void)
650{
651 APIRET rc;
652
653 /*
654 * Set global parameters... FIXME.
655 */
656
657 /*
658 * Do the real execution.
659 */
660 printf("--- TestcaseExeLoad1 - loading win32ktst.exe (LX image) ----\n");
661 rc = CalltkExecPgm(EXEC_LOAD, NULL, NULL, "win32ktst.exe");
662 if (rc == NO_ERROR)
663 {
664 printf("--- TestcaseExeLoad1 - loading libconv.exe (LX image) ----\n");
665 rc = CalltkExecPgm(EXEC_LOAD, NULL, NULL, "bin\\debug\\libconv.exe");
666 }
667
668 if (rc == NO_ERROR)
669 {
670 printf("--- TestcaseExeLoad1 - loading rexx\\tst.cmd (REXX script) ----\n");
671 rc = CalltkExecPgm(EXEC_LOAD, NULL, NULL, "rexx\\tst.cmd");
672 }
673
674 if (rc == NO_ERROR)
675 {
676 printf("--- TestcaseExeLoad1 - loading SOL.EXE (PE image) ----\n");
677 rc = CalltkExecPgm(EXEC_LOAD, NULL, NULL, "e:\\Win32Prog\\Sol\\Sol.exe");
678 }
679
680 /*
681 * The test is successful if rc == NO_ERROR (== 0).
682 */
683 return rc;
684}
Note: See TracBrowser for help on using the repository browser.