| 1 | /* $Id: kDevTest.c,v 1.1 2002-09-30 23:53:52 bird Exp $
|
|---|
| 2 | *
|
|---|
| 3 | * Main Program for Ring-3 Device Testing.
|
|---|
| 4 | *
|
|---|
| 5 | * Copyright (c) 2000-2002 knut st. osmundsen <bird@anduin.net>
|
|---|
| 6 | *
|
|---|
| 7 | *
|
|---|
| 8 | * This file is part of kKrnlLib.
|
|---|
| 9 | *
|
|---|
| 10 | * kKrnlLib is free software; you can redistribute it and/or modify
|
|---|
| 11 | * it under the terms of the GNU General Public License as published by
|
|---|
| 12 | * the Free Software Foundation; either version 2 of the License, or
|
|---|
| 13 | * (at your option) any later version.
|
|---|
| 14 | *
|
|---|
| 15 | * kKrnlLib is distributed in the hope that it will be useful,
|
|---|
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 18 | * GNU General Public License for more details.
|
|---|
| 19 | *
|
|---|
| 20 | * You should have received a copy of the GNU General Public License
|
|---|
| 21 | * along with kKrnlLib; if not, write to the Free Software
|
|---|
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|---|
| 23 | *
|
|---|
| 24 | */
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 | /** @design Win32k Ring-3 Testing
|
|---|
| 28 | * I'll try to make it possible to test parts or all the win32k code in ring-3.
|
|---|
| 29 | * To archive this the interface against the kernel has to be faked/emulated.
|
|---|
| 30 | * More precisely:
|
|---|
| 31 | * - DevHelps.
|
|---|
| 32 | * - Worker routines for imported kernel functions. (calltab.asm jumps to them.)
|
|---|
| 33 | * - 16-bit stack 1Kb.
|
|---|
| 34 | * - Strategy calls.
|
|---|
| 35 | * - Fake module loadings (= testcases).
|
|---|
| 36 | * - ?
|
|---|
| 37 | *
|
|---|
| 38 | * Some of the initstuff has to be omitted, at least in the start. The first
|
|---|
| 39 | * goal is to be able to test _ldrOpenPath and _ldrOpen.
|
|---|
| 40 | *
|
|---|
| 41 | *
|
|---|
| 42 | * @subsection Device Helper Routines
|
|---|
| 43 | *
|
|---|
| 44 | * These I think we'll implemented by providing the kernel interface, a far 16:16
|
|---|
| 45 | * pointer to a dh-router. Our router will in most cases thunk back to 32-bit
|
|---|
| 46 | * code and implementet the required devhelp routines in pure C code.
|
|---|
| 47 | *
|
|---|
| 48 | * These are the needed routines:
|
|---|
| 49 | * - DevHelp_VirtToLin - ok
|
|---|
| 50 | * - DevHelp_VMAlloc - ok
|
|---|
| 51 | * - DevHelp_VMFree - ok
|
|---|
| 52 | * - DevHelp_GetDOSVar - ok
|
|---|
| 53 | * - DevHelp_VMLock
|
|---|
| 54 | * - DevHelp_VMUnLock ?
|
|---|
| 55 | * - DevHelp_VMSetMem ?
|
|---|
| 56 | * - DevHelp_Yield ?
|
|---|
| 57 | *
|
|---|
| 58 | *
|
|---|
| 59 | * @subsection Worker routines for imported kernel functions
|
|---|
| 60 | *
|
|---|
| 61 | * Create worker routines for the imported kernel functions. Calltab will be
|
|---|
| 62 | * set up to jump to them. This is done in d32init.c, in stead of using
|
|---|
| 63 | * the importtab.
|
|---|
| 64 | *
|
|---|
| 65 | * Some of these workers will be parts of testcases. For example g_tkExecPgm
|
|---|
| 66 | * and _LDRQAppType.
|
|---|
| 67 | *
|
|---|
| 68 | * Only the imported functions are implemented on demand. Initially these
|
|---|
| 69 | * functions will be provided:
|
|---|
| 70 | * - ldrOpen
|
|---|
| 71 | * - ldrRead
|
|---|
| 72 | * - ldrClose
|
|---|
| 73 | * - ldrOpenPath
|
|---|
| 74 | * - SftFileSize
|
|---|
| 75 | *
|
|---|
| 76 | *
|
|---|
| 77 | * @subsection 16-bit stack
|
|---|
| 78 | *
|
|---|
| 79 | * To make this test real the stack has to be 16-bit and _very_ small (1KB).
|
|---|
| 80 | * TKSSBase have to be implemented by the DevHelp_GetDOSVar DosTable2 stuff.
|
|---|
| 81 | * The stack will be thunked to 16-bit by a thunking procedure called from
|
|---|
| 82 | * main. This procedure thunks the stack (quite easy, we're in tiled memory!),
|
|---|
| 83 | * set the value of TKSSBase, calls a C function which does all the rest of
|
|---|
| 84 | * the testing. When taht function returns, the stack will be thunked back
|
|---|
| 85 | * to 32-bit, TKSSBase will be zeroed, and the procedure returns to main.
|
|---|
| 86 | *
|
|---|
| 87 | *
|
|---|
| 88 | * @subsection Straegy routine calls (not implemented)
|
|---|
| 89 | *
|
|---|
| 90 | * We'll call the strategy entry points with init request packets. The initiation
|
|---|
| 91 | * will require a replacement for DosDevIOCtl (16-bit) which calls the
|
|---|
| 92 | * $elf strategy routine. We'll also have to provide fakes for kernel probing,
|
|---|
| 93 | * verifing and overloading in d32init.c.
|
|---|
| 94 | *
|
|---|
| 95 | *
|
|---|
| 96 | * @subsection Order of events
|
|---|
| 97 | *
|
|---|
| 98 | * This is the order this testing environment currently works:
|
|---|
| 99 | * 1) init devhelp subsystem
|
|---|
| 100 | * 2) init workers
|
|---|
| 101 | * 3) thunk stack
|
|---|
| 102 | * 4) Fake 16-bit init. Set TKSSBase, FlatDS, FlatCS, DevHelp pointer....
|
|---|
| 103 | * 5) Call R0Init32().
|
|---|
| 104 | * (d32init.c is modified a bit to setup the calltab correctly.)
|
|---|
| 105 | * 6) Start testing...
|
|---|
| 106 | * 7) Testing finished - thunk stack back to 32-bit.
|
|---|
| 107 | */
|
|---|
| 108 |
|
|---|
| 109 |
|
|---|
| 110 |
|
|---|
| 111 | /*******************************************************************************
|
|---|
| 112 | * Defined Constants And Macros *
|
|---|
| 113 | *******************************************************************************/
|
|---|
| 114 |
|
|---|
| 115 |
|
|---|
| 116 | /*******************************************************************************
|
|---|
| 117 | * Header Files *
|
|---|
| 118 | *******************************************************************************/
|
|---|
| 119 | #define INCL_BASE
|
|---|
| 120 | #include <os2.h>
|
|---|
| 121 |
|
|---|
| 122 | #include <stdio.h>
|
|---|
| 123 | #include <string.h>
|
|---|
| 124 | #include <stdlib.h>
|
|---|
| 125 |
|
|---|
| 126 | #include "kDevTest.h"
|
|---|
| 127 |
|
|---|
| 128 |
|
|---|
| 129 | /*******************************************************************************
|
|---|
| 130 | * Internal Functions *
|
|---|
| 131 | *******************************************************************************/
|
|---|
| 132 | BOOL init(void);
|
|---|
| 133 | BOOL LoadAndInitDriver(const char *pszDriver, const char *pszArgs, BOOL fBaseDev);
|
|---|
| 134 |
|
|---|
| 135 |
|
|---|
| 136 |
|
|---|
| 137 |
|
|---|
| 138 |
|
|---|
| 139 | /**
|
|---|
| 140 | * Initiates all 'subsystems'
|
|---|
| 141 | * @returns Success indicator.
|
|---|
| 142 | */
|
|---|
| 143 | BOOL init(void)
|
|---|
| 144 | {
|
|---|
| 145 | kdtDHInit();
|
|---|
| 146 | return TRUE;
|
|---|
| 147 | }
|
|---|
| 148 |
|
|---|
| 149 |
|
|---|
| 150 | /**
|
|---|
| 151 | * Loads and initiates an device driver.
|
|---|
| 152 | * @returns Success indicator.
|
|---|
| 153 | * @param pszDriver Name of the driver module file.
|
|---|
| 154 | * @param pszArgs Arguments to pass along.
|
|---|
| 155 | * @param fBaseDev Set this if base device.
|
|---|
| 156 | */
|
|---|
| 157 | BOOL LoadAndInitDriver(const char *pszDriver, const char *pszArgs, BOOL fBaseDev)
|
|---|
| 158 | {
|
|---|
| 159 | PMODINFO pModInfo;
|
|---|
| 160 |
|
|---|
| 161 | /*
|
|---|
| 162 | * Load it.
|
|---|
| 163 | */
|
|---|
| 164 | pModInfo = kdtLoadDriver(pszDriver);
|
|---|
| 165 | if (pModInfo)
|
|---|
| 166 | {
|
|---|
| 167 | if (kdtLoadValidateDriver(pModInfo))
|
|---|
| 168 | {
|
|---|
| 169 | ULONG rc;
|
|---|
| 170 |
|
|---|
| 171 | if (kdtInitDriver(pModInfo, pszArgs, fBaseDev))
|
|---|
| 172 | {
|
|---|
| 173 | return TRUE;
|
|---|
| 174 | }
|
|---|
| 175 | else
|
|---|
| 176 | printf("kDevTest: Init failed with rc=%d\n", rc);
|
|---|
| 177 | }
|
|---|
| 178 | else
|
|---|
| 179 | printf("kDevTest: Invalid driver module %s.\n", pszDriver);
|
|---|
| 180 | free(pModInfo);
|
|---|
| 181 | }
|
|---|
| 182 | else
|
|---|
| 183 | printf("kDevTest: failed to load %s.\n", pszDriver);
|
|---|
| 184 |
|
|---|
| 185 | return FALSE;
|
|---|
| 186 | }
|
|---|
| 187 |
|
|---|
| 188 |
|
|---|
| 189 | /**
|
|---|
| 190 | * Prints syntax information.
|
|---|
| 191 | */
|
|---|
| 192 | void syntax(void)
|
|---|
| 193 | {
|
|---|
| 194 | printf(
|
|---|
| 195 | "kDevTest v0.0.0 - Ring 3 Device Testing!\n"
|
|---|
| 196 | "\n"
|
|---|
| 197 | "syntax: kDevTest.exe [options] <module> [args]\n"
|
|---|
| 198 | "\n"
|
|---|
| 199 | "options:\n"
|
|---|
| 200 | " -b basedevice. default is normal device.\n"
|
|---|
| 201 | "\n"
|
|---|
| 202 | " module Full name of the device module to test.\n"
|
|---|
| 203 | " args Arguments to present to the device driver.\n");
|
|---|
| 204 | }
|
|---|
| 205 |
|
|---|
| 206 |
|
|---|
| 207 | /**
|
|---|
| 208 | * Main function. Arguments _currently_ unused.
|
|---|
| 209 | */
|
|---|
| 210 | int main(int argc, char **argv)
|
|---|
| 211 | {
|
|---|
| 212 | int rc;
|
|---|
| 213 | int argi;
|
|---|
| 214 | BOOL fOptions = TRUE;
|
|---|
| 215 |
|
|---|
| 216 | /* parsed arguments */
|
|---|
| 217 | static char szDriver[CCHMAXPATH];
|
|---|
| 218 | static char szArguments[4096];
|
|---|
| 219 | BOOL fBaseDev = FALSE;
|
|---|
| 220 |
|
|---|
| 221 |
|
|---|
| 222 | /*
|
|---|
| 223 | * Parse input.
|
|---|
| 224 | */
|
|---|
| 225 | for (szDriver[0] = '\0', argi = 1; argi < argc; argi++)
|
|---|
| 226 | {
|
|---|
| 227 | if (!szDriver[0] && (argv[argi][0] == '-' || argv[argi][0] == '/'))
|
|---|
| 228 | {
|
|---|
| 229 | switch (argv[argi][1])
|
|---|
| 230 | {
|
|---|
| 231 | case 'b':
|
|---|
| 232 | case 'B':
|
|---|
| 233 | fBaseDev = TRUE;
|
|---|
| 234 | break;
|
|---|
| 235 |
|
|---|
| 236 | default:
|
|---|
| 237 | printf("kDevTest: syntax error! invalid argument %s\n", argv[argi]);
|
|---|
| 238 | case '?':
|
|---|
| 239 | case '-':
|
|---|
| 240 | case 'h':
|
|---|
| 241 | case 'H':
|
|---|
| 242 | syntax();
|
|---|
| 243 | return 12;
|
|---|
| 244 | }
|
|---|
| 245 | }
|
|---|
| 246 | else if (!szDriver[0])
|
|---|
| 247 | strcpy(szDriver, argv[argi]);
|
|---|
| 248 | else
|
|---|
| 249 | { /* TODO: quoting etc */
|
|---|
| 250 | strcat(strcat(szArguments, " "), argv[argi]);
|
|---|
| 251 | }
|
|---|
| 252 | }
|
|---|
| 253 |
|
|---|
| 254 | if (!szDriver[0])
|
|---|
| 255 | {
|
|---|
| 256 | printf("kDevTest: syntax error! missing driver name.\n");
|
|---|
| 257 | syntax();
|
|---|
| 258 | return 12;
|
|---|
| 259 | }
|
|---|
| 260 |
|
|---|
| 261 |
|
|---|
| 262 | /*
|
|---|
| 263 | * Load and init the driver
|
|---|
| 264 | */
|
|---|
| 265 | if (LoadAndInitDriver(&szDriver[0], &szArguments[0], fBaseDev))
|
|---|
| 266 | {
|
|---|
| 267 | rc = 0;
|
|---|
| 268 | }
|
|---|
| 269 | else
|
|---|
| 270 | {
|
|---|
| 271 | rc = 8;
|
|---|
| 272 | printf("kDevTest: LoadAndInitDriver failed\n");
|
|---|
| 273 | }
|
|---|
| 274 |
|
|---|
| 275 | return rc;
|
|---|
| 276 | }
|
|---|
| 277 |
|
|---|