Changeset 2827 for trunk/src/win32k/ldr/myldrOpen.cpp
- Timestamp:
- Feb 19, 2000, 9:40:31 AM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/win32k/ldr/myldrOpen.cpp
r2501 r2827 1 /* $Id: myldrOpen.cpp,v 1. 6 2000-01-22 18:21:02bird Exp $1 /* $Id: myldrOpen.cpp,v 1.7 2000-02-19 08:40:30 bird Exp $ 2 2 * 3 3 * myldrOpen - ldrOpen. … … 16 16 #define INCL_NOPMAPI 17 17 18 #define INCL_OS2KRNL_IO 19 18 20 /******************************************************************************* 19 21 * Header Files * … … 21 23 #include <os2.h> 22 24 25 #include "rmalloc.h" 23 26 #include "malloc.h" 24 27 #include <memory.h> 25 28 #include <stdlib.h> 29 #include <string.h> 26 30 27 31 #include "log.h" … … 29 33 #include <exe386.h> 30 34 #include "OS2Krnl.h" 35 #include "dev32.h" 31 36 #include "ModuleBase.h" 32 37 #include "pe2lx.h" … … 36 41 #include "ldrCalls.h" 37 42 #include "options.h" 43 #include "myExecPgm.h" 44 45 46 /******************************************************************************* 47 * Internal Functions * 48 *******************************************************************************/ 49 static unsigned getArgsLength(const char *pachArgs); 38 50 39 51 … … 49 61 ULONG rc; 50 62 63 /* 64 * Try open the file (thats why this function is called anyway) 65 */ 51 66 rc = ldrOpen(phFile, pszFilename, param3); 52 67 68 /* log sucesses */ 53 69 if (rc == NO_ERROR) 54 70 kprintf(("ldrOpen: phFile=%#.4x, flags=%#.8x, pszFn=%s\n", *phFile, param3, pszFilename)); 55 71 72 /* 73 * Are we to intercept the loading? 74 * - Only if open were succesful and one of the loaders are enabled. 75 */ 56 76 if (rc == NO_ERROR && (options.fElf || options.fPE != FLAGS_PE_NOT || options.fScript)) 57 77 { 58 static char achBuffer[sizeof(IMAGE_DOS_HEADER)]; 59 PIMAGE_DOS_HEADER pMzHdr = (PIMAGE_DOS_HEADER)&achBuffer[0]; 60 PIMAGE_NT_HEADERS pNtHdrs = (PIMAGE_NT_HEADERS)&achBuffer[0]; /* oops. Last accessible field is OptionalHeader.FileAlignment */ 61 char *pach = &achBuffer[0]; 62 63 /** 78 char *pszBuffer = (char*)rmalloc(640); /* Read buffer. */ 79 PIMAGE_DOS_HEADER pMzHdr = (PIMAGE_DOS_HEADER)pszBuffer; /* Pointer to the buffer as it were a dosheader. */ 80 PIMAGE_NT_HEADERS pNtHdrs = (PIMAGE_NT_HEADERS)pszBuffer; /* Pointer to the buffer as if it were an NT header. */ 81 char *pach = pszBuffer; /* Finally an pointer to the buffer as if it were chars.. (which it is!) */ 82 PEXECPGMBUFFER pBuffer; /* Pointer to a buffer containing the programname and arguments. */ 83 /* For scripts and PE.EXE this has to be changed to have correct */ 84 /* parameters sendt in to the program. */ 85 unsigned cchRead = sizeof(IMAGE_DOS_HEADER); /* Amount of the buffer which contains valid data. */ 86 unsigned cbFile; /* Filesize (0xffffffff if call to SftFileSize failed - should _never_ happen though) */ 87 88 /* 89 * Verify that rmalloc completed successfully. 90 */ 91 if (pszBuffer == NULL) 92 { 93 kprintf(("ldrOpen: rmalloc(1024) failed\n")); 94 return NO_ERROR; 95 } 96 97 /* 98 * Try get the filesize 99 */ 100 /* 101 rc = SftFileSize(*phFile, (PULONG)SSToDS(&cbFile)); 102 if (rc != NO_ERROR) 103 { 104 kprintf(("ldrOpen: SftFileSize failed with rc=%d\n", rc)); 105 */ 106 cbFile = (unsigned)~0; 107 /* 108 } */ 109 110 /* 64 111 * See if this is an recognizable module format. 65 112 * This costs up to two disk reads! 66 113 */ 67 rc = ldrRead(*phFile, 0UL, pMzHdr, 0UL, sizeof(IMAGE_DOS_HEADER), NULL);114 rc = ldrRead(*phFile, 0UL, pMzHdr, 0UL, cchRead, NULL); 68 115 if (rc == NO_ERROR) 69 116 { 117 /* 118 * PE header? 119 * - If DOS Magic is found AND a valid e_lfanew (offset of NE/LX/LE/PE header) is found 120 * - OR if PE siganture is found. 121 */ 70 122 if ((pMzHdr->e_magic == IMAGE_DOS_SIGNATURE && 71 123 pMzHdr->e_lfanew > sizeof(IMAGE_DOS_HEADER) && pMzHdr->e_lfanew < 0x04000000UL) /* Larger than 64 bytes and less that 64MB. */ 72 124 || *(PULONG)pach == IMAGE_NT_SIGNATURE) 73 { /* MZ or PE header found */ 125 { /* 126 * MZ or PE header found 127 */ 128 129 /* if PE loading is diable return to the caller */ 74 130 if (options.fPE == FLAGS_PE_NOT) 131 { 132 free(pszBuffer); 75 133 return NO_ERROR; 76 134 } 135 136 /* 137 * Read the PE header if it isn't what we allready have! 138 */ 139 cchRead = sizeof(IMAGE_NT_HEADERS); 77 140 if (*(PULONG)pach != IMAGE_NT_SIGNATURE) 78 rc = ldrRead(*phFile, pMzHdr->e_lfanew, pach, 0UL, sizeof(achBuffer), NULL); 79 141 rc = ldrRead(*phFile, pMzHdr->e_lfanew, pach, 0UL, cchRead, NULL); 142 else 143 rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL); 144 145 /* 146 * If successfully read, and a PE signature is present the continue and try load it! 147 * Else don't do anything, simply return NO_ERROR to the caller. (probably NE or LX exec) 148 */ 80 149 if (rc == NO_ERROR && *(PULONG)pach == IMAGE_NT_SIGNATURE) 81 { /* PE signature found */ 150 { /* 151 * PE signature found. 152 */ 82 153 kprintf(("ldrOpen: PE executable...\n")); 154 155 /* 156 * PE2LX? 157 * - When PE2LX flag is set 158 * - OR when the MIXED flag is set and the image is with the first 64MB of memory. 159 */ 83 160 if (options.fPE == FLAGS_PE_PE2LX 84 161 || (options.fPE == FLAGS_PE_MIXED … … 88 165 ) 89 166 ) 90 { /* pe2lx */ 167 { /* 168 * Pe2Lx (Ring0 of course) 169 * - Create a Pe2Lx class, 170 * - initiate it 171 * - Add the module to the module tree so we may find it later... 172 * - Set the handle state to 'our'. 173 */ 91 174 Pe2Lx * pPe2Lx = new Pe2Lx(*phFile); 92 175 if (pPe2Lx != NULL) … … 113 196 } 114 197 else 198 { 199 /* 200 * Starting of PE.EXE enable? 201 */ 115 202 if (options.fPE == FLAGS_PE_PE || options.fPE == FLAGS_PE_MIXED) 116 { /* pe.exe */ 203 { /* 204 * pe.exe - need the path! 205 */ 117 206 kprintf(("ldrOpen: pe.exe - opening\n")); 118 207 ldrClose(*phFile); 119 208 rc = ldrOpen(phFile, "pe.exe", param3); /* path....! problems! */ 120 209 kprintf(("ldrOpen: pe.exe - open returned with rc = %d\n", rc)); 210 free(pszBuffer); 121 211 return rc; 122 212 } 213 } 123 214 } 124 rc = NO_ERROR; 215 free(pszBuffer); 216 return NO_ERROR; 125 217 } 126 218 else 127 219 { 220 /* 221 * ELF image? 222 */ 128 223 if (pach[0] == ELFMAG0 && pach[1] == ELFMAG1 && pach[2] == ELFMAG2 && pach[3] == ELFMAG3) 129 224 { 130 /* ELF signature found */ 225 /* 226 * ELF signature found. 227 */ 131 228 kprintf(("ldrOpen: ELF executable! - not implemented yet!\n")); 229 230 /* 231 * Do nothing more yet. NEED AN ELF LOADER!!! 232 */ 233 free(pszBuffer); 234 return NO_ERROR; 132 235 } 133 else 134 if (*pach == '#' && pach[1] == '!') 236 } 237 238 /* 239 * Only unreconized files and readerror passes this point! 240 * 241 * * Fileformats with lower priority should reside here. * 242 * 243 */ 244 245 /* 246 * If the initial readoperation failed try to read a smaller amount, in case it is a small script... 247 * 4 bytes is a small amount isn't it? 248 */ 249 if (rc != NO_ERROR) 250 { 251 kprintf(("ldrOpen: first ldrread failed with rc=%d. tries to read 4 byte.\n", rc)); 252 cchRead = 4; 253 if ((rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL)) != NO_ERROR) 254 kprintf(("ldrOpen: second ldrread failed with rc=%d.\n ", rc)); 255 } 256 257 /* 258 * Now we'll try again, UNIX styled script? 259 */ 260 if (rc == NO_ERROR && *pach == '#' && pach[1] == '!') 261 { 262 /* 263 * UNIX styled script? 264 * FIXME! Must be more than 64 bytes long? 265 * No options! 266 * Firstline < 64 bytes! 267 */ 268 kprintf(("ldrOpen: unix script?\n")); 269 270 cchRead = min(cbFile, 256); 271 rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL); 272 if (rc != NO_ERROR) 273 { 274 char *pszStart = pach+2; 275 276 /* Make sure we don't read to much... */ 277 pszBuffer[cchRead] = '\0'; 278 279 /* 280 * Skip blanks 281 */ 282 pszStart = pszBuffer + 2; /* skips the "#!" stuff. */ 283 while (*pszStart != '\0' && (*pszStart == ' ' || *pszStart == '\t')) 284 pszStart++; 285 286 /* anything left on the line? */ 287 if (*pszStart != '\0' && *pszStart != '\r' && *pszStart != '\n') 135 288 { 136 /* unix styled script...? Must be more than 64 bytes long? No options. firstline < 64 bytes. */ 137 char *pszStart = pach+2; 138 char *pszEnd; 139 kprintf(("ldrOpen: unix script?\n")); 140 141 achBuffer[sizeof(achBuffer)-1] = '\0'; /* just to make sure we don't read to much... */ 142 143 /* skip blanks */ 144 while (*pszStart != '\0' && (*pszStart == ' ' || *pszStart == '\t')) 145 pszStart++; 146 if (*pszStart != '\0' && *pszStart != '\r' && *pszStart != '\n') 147 { /* find end-of-word */ 148 pszEnd = pszStart + 1; 149 while (*pszEnd != '\0' && *pszEnd != '\n' && *pszEnd != '\r' 150 && *pszEnd != '\t' && *pszEnd != ' ') 151 pszEnd++; 152 if (*pszEnd != '\0') 289 char * pszEnd; /* Pointer to the end of the string(s) when the next step is finished. */ 290 //char * pszFirstArg; /* Pointer to the first argument, the one after the interpreter name. */ 291 unsigned cchToAdd = 1; /* Chars to add */ 292 int f = TRUE; /* flag which tells me if I have just closed the last argument. */ 293 /* 294 * find linesize and make parameters ready for copying 295 */ 296 pszEnd = pszStart; 297 //pszFirstArg = NULL; 298 while (*pszEnd != '\0' && *pszEnd != '\r' && *pszEnd != '\n') 299 { 300 if (f) 153 301 { 154 *pszEnd = '\0'; 155 kprintf(("ldrOpen: unix script - opening %s\n", pszStart)); 156 ldrClose(*phFile); 157 rc = ldrOpen(phFile, pszStart, param3); 158 kprintf(("ldrOpen: unix script - open returned with rc = %d\n", rc)); 302 f = FALSE; 303 //if (pszFirstArg != NULL) pszFirstArg = pszEnd + 1; 304 } 305 else if (!f && (*pszEnd == ' ' || *pszEnd == '\t')) 306 { 307 *pszEnd = '\0'; 308 f = TRUE; 309 } 310 311 /* next */ 312 pszEnd++; 313 cchToAdd++; 314 } 315 *pszEnd = '\0'; 316 317 /* 318 * Find the ExecPgm buffer. 319 */ 320 pBuffer = QueryBufferPointerFromFilename(pszFilename); 321 if (pBuffer != NULL) 322 { 323 unsigned cchArguments = getArgsLength(pBuffer->achArgs); 324 kprintf(("ldrOpen: debug1\n")); 325 326 /* 327 * Is there enough space in the struct? 328 */ 329 if (cchArguments + cchToAdd < sizeof(pBuffer->achArgs)) 330 { 331 kprintf(("ldrOpen: debug2\n")); 332 /* 333 * Open the interpreter. 334 */ 335 rc = ldrClose(*phFile); 336 rc = ldrOpen(phFile, pszStart, param3); /* FIXME, recusion! check that name not equal! Use flags to prevent race? */ 337 if (rc == NO_ERROR) 338 { 339 kprintf(("ldrOpen: debug3\n")); 340 /* Make space for the addition arguments. */ 341 memmove(&pBuffer->achArgs[cchToAdd], &pBuffer->achArgs[0], cchArguments); 342 memcpy(&pBuffer->achArgs[0], pszBuffer, cchToAdd); 343 kprintf(("ldrOpen: debug4\n")); 344 } 345 else 346 kprintf(("ldrOpen: failed to open interpreter (%s), rc=%d\n", pszStart, rc)); 347 } 348 else 349 { 350 kprintf(("ldrOpen: Argument buffer too small, %d\n", cchArguments + cchToAdd)); 351 rc = ERROR_BAD_EXE_FORMAT; 159 352 } 160 353 } 161 354 else 162 kprintf(("ldrOpen: unix script - unexpected end of line/file. (line: %.10s\n", pach)); 355 { 356 kprintf(("ldrOpen: QueryBufferPointerFromFilename failed.\n")); 357 rc = ERROR_BAD_EXE_FORMAT; /*?*/ 358 } 163 359 } 164 } 360 else 361 { 362 kprintf(("ldrOpen: no interpereter on the first line.\n")); 363 rc = ERROR_BAD_EXE_FORMAT; /*?*/ 364 } 365 } 366 else 367 { 368 kprintf(("ldrOpen: read of min(cbFile, 256) = %d failed, rc = %d\n", cchRead, rc)); 369 } 370 } /* else inn other formats here. */ 165 371 } 166 372 else … … 169 375 rc = NO_ERROR; 170 376 } 377 free(pszBuffer); 171 378 } 172 379 return rc; 173 380 } 381 382 383 /** 384 * Get the lenght of the arguments. 385 * @returns Lenght in char, includes the two '\0's. 386 * @param pachArgs Pointer to the ASCIIZs which makes up the arguments. 387 * @status completely implemented. 388 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 389 */ 390 static unsigned getArgsLength(const char *pachArgs) 391 { 392 unsigned cch = 1; 393 const char *psz = pachArgs; 394 395 while (*psz != '\0') 396 { 397 register unsigned cch2 = strlen(psz); 398 cch += cch2; 399 psz += cch2 + 1; 400 } 401 402 return cch; 403 }
Note:
See TracChangeset
for help on using the changeset viewer.