- Timestamp:
- Jan 18, 2012, 11:33:39 AM (14 years ago)
- Location:
- trunk/src/peldr
- Files:
-
- 3 added
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/peldr/Makefile.kmk
r21924 r21942 8 8 PROGRAMS += pe 9 9 pe_TEMPLATE = OdinApp 10 pe_SOURCES = pe.cpp pe.def 10 pe_SOURCES = pe.c pe.def helpers.c $(pe_0_OUTDIR)/crt0.obj 11 pe_LDFLAGS = -nostdlib -llibos2 11 12 12 13 PROGRAMS += pec 13 14 pec_TEMPLATE = OdinApp 14 15 pec_DEFS = COMMAND_LINE_VERSION 15 pec_SOURCES = pe.cpp pec.def 16 pec_SOURCES = pe.c pec.def helpers.c $(pe_0_OUTDIR)/crt0.obj 17 pec_LDFLAGS = -nostdlib -llibos2 18 19 $$(pe_0_OUTDIR)/crt0.obj: crt0.s 20 $(QUIET)gcc -c -x assembler-with-cpp crt0.s -o $@.o 21 $(QUIET)emxomf -m__text $@.o -o $@ 16 22 17 23 include $(FILE_KBUILD_SUB_FOOTER) -
trunk/src/peldr/pe.c
r21940 r21942 3 3 * 4 4 * Copyright 1998-2001 Sander van Leeuwen (sandervl@xs4all.nl) 5 * Copyright 2012 Dmitriy Kuminov 5 6 * 6 7 * Command line options: … … 10 11 * 11 12 * Project Odin Software License can be found in LICENSE.TXT 12 *13 13 */ 14 14 15 #define INCL_DOSFILEMGR /* File Manager values */ 15 16 #define INCL_DOSERRORS /* DOS Error values */ … … 21 22 #include <os2.h> 22 23 #include <bseord.h> 23 #include <stdio.h>24 #include <string.h>25 #include <stdlib.h>26 #include <string.h>27 #include <assert.h>28 24 #include <win32type.h> 29 25 #include <misc.h> … … 33 29 #include "pe.h" 34 30 31 #include "helpers.h" 32 35 33 char INFO_BANNER[] = "Usage: PE winexe commandline"; 36 34 char szErrorTitle[] = "Odin"; 37 35 char szLoadErrorMsg[] = "Can't load executable %s"; 38 char szFileNotFound[] = "File not found .";36 char szFileNotFound[] = "File not found: %s"; 39 37 char szFileErrorMsg[] = "File IO error"; 40 38 char szPEErrorMsg[] = "Not a valid win32 exe. (perhaps 16 bits windows)"; … … 44 42 char szInteralErrorMsg1[]= "Internal Error"; 45 43 char szNoKernel32Msg[] = "Can't load/find kernel32.dll (rc=%d, module %s)"; 46 char szDosInfoBlocks[] = "DosInfoBlocks failed!";47 44 char szErrorExports[] = "Unable to process exports of %s"; 48 45 char szErrorMemory[] = "Memory allocation failure while loading %s"; 49 46 char szErrorImports[] = "Failure to load \"%s\" due to bad or missing %s"; 50 47 51 char szErrDosStartSession[] = "Failed to start win16 session(rc=%d)";48 char szErrDosStartSession[] = "Failed to start win16 (%s) for %s (rc=%d)"; 52 49 53 50 char fullpath[CCHMAXPATH]; … … 80 77 BOOL AllocateExeMem(char *filename, BOOL *fNEExe); 81 78 82 //****************************************************************************** 83 //****************************************************************************** 84 int main(int argc, char *argv[]) 79 #ifdef DEBUG 80 void print(const char *fmt, ...) 85 81 { 82 static char buf[1024]; 83 char *s, *e; 84 ULONG dummy; 85 int len; 86 va_list args; 87 va_start(args, fmt); 88 len = vsnprintf(buf, sizeof(buf), fmt, args); 89 va_end(args); 90 s = buf; 91 while (*s) 92 { 93 e = (char *)str_find_char(s, '\n'); 94 DosWrite((HFILE)1, s, e - s, &dummy); 95 if (*e == '\n') 96 { 97 DosWrite((HFILE)1, "\n\r", 2, &dummy); 98 e++; 99 } 100 s = e; 101 } 102 } 103 #define DBG(a) do { print a; } while (0) 104 #else 105 #define DBG(a) do {} while (0) 106 #endif 107 108 //****************************************************************************** 109 //****************************************************************************** 110 int simple_main() 111 { 112 DBG(("PE: BEGIN (DEBUG mode)\n")); 113 86 114 HAB hab = 0; /* PM anchor block handle */ 87 115 HMQ hmq = 0; /* Message queue handle */ 88 116 char exeName[CCHMAXPATH]; 89 char fullpath[CCHMAXPATH ];117 char fullpath[CCHMAXPATH * 2]; 90 118 char errorMod[CCHMAXPATH]; 119 char szErrorMsg[512]; 91 120 char *pszErrorMsg = NULL; 92 121 APIRET rc; … … 94 123 PTIB ptib; 95 124 PPIB ppib; 96 char *cmdline, *win32cmdline, *peoptions, *newcmdline; 97 BOOL fQuote = FALSE, fVioConsole, fIsNEExe, fEndOfCmdLine = FALSE; 98 int nrTries = 1; 99 125 char *cmdline, *win32cmdline, *peoptions; 126 BOOL fVioConsole, fIsNEExe; 127 128 char *pszTemp, *pszTemp2; 129 130 DosGetInfoBlocks(&ptib, &ppib); 131 132 #ifdef COMMAND_LINE_VERSION 100 133 if(DosGetInfoBlocks(&ptib, &ppib) == 0) 101 134 { 102 char *pszTemp; 103 104 fullpath[0] = 0; 105 DosQueryModuleName(ppib->pib_hmte, sizeof(fullpath), fullpath); 106 107 strupr(fullpath); 108 #ifdef COMMAND_LINE_VERSION 109 pszTemp = strstr(fullpath, "PEC.EXE"); 110 #else 111 pszTemp = strstr(fullpath, "PE.EXE"); 135 //switch process type to PM so the command line app can create PM 136 //windows 137 ppib->pib_ultype = 3; 138 } 112 139 #endif 113 if(pszTemp == NULL) { 114 pszErrorMsg = szInteralErrorMsg1; 115 goto failerror; 116 } 117 pszTemp--; //to go trailing backslash 140 141 fullpath[0] = 0; 142 DosQueryModuleName(ppib->pib_hmte, sizeof(fullpath), fullpath); 143 144 pszTemp = fullpath + strlen(fullpath) - 1; 145 while (pszTemp >= fullpath && (*pszTemp != '\\' && *pszTemp != '/')) 146 --pszTemp; 147 if (pszTemp >= fullpath) 148 { 118 149 *pszTemp = 0; 119 150 strcat(fullpath, ";%BeginLIBPATH%"); 120 151 DosSetExtLIBPATH(fullpath, BEGIN_LIBPATH); 121 } 122 123 if(argc >= 2) { 124 if(DosGetInfoBlocks(&ptib, &ppib) == 0) { 125 tryagain: 126 cmdline = ppib->pib_pchcmd; 127 cmdline += strlen(cmdline)+1; //skip pe.exe 128 peoptions = strstr(cmdline, "/OPT:["); 129 if(peoptions) { 130 newcmdline = strchr(peoptions, ']'); 131 if(newcmdline) { 132 cmdline = newcmdline+1; 133 } 134 #ifdef DEBUG 135 else _interrupt(3); //should not happen! 136 #endif 152 DBG(("PE: Added '%s' to BEGINLIBPATH\n", fullpath)); 153 } 154 155 cmdline = ppib->pib_pchcmd; 156 if (cmdline) 157 { 158 cmdline += strlen(cmdline) + 1; // skip executable name 159 if (!*cmdline) 160 cmdline = NULL; 161 } 162 163 if (cmdline) 164 { 165 DBG(("PE: Full command line: '%s'\n", cmdline)); 166 167 pszTemp = (char *)str_skip_char(cmdline, ' '); 168 169 // get PE options 170 if (str_starts_with(pszTemp, "/OPT:[")) 171 { 172 const char *end = str_find_char(pszTemp , ']'); 173 if (*end) 174 pszTemp = (char *)str_skip_char(end + 1, ' '); 175 else 176 peoptions = NULL; 177 } 178 179 // get Win32 executable name 180 int delim = ' '; 181 if (*pszTemp == '"') 182 { 183 pszTemp++; 184 delim = '"'; 185 } 186 pszTemp2 = exeName; 187 while (*pszTemp && *pszTemp != delim && 188 (pszTemp2 - exeName) < CCHMAXPATH - 1) 189 { 190 *pszTemp2++ = *pszTemp++; 191 } 192 *pszTemp2 = '\0'; 193 if (delim == '"') 194 pszTemp++; 195 pszTemp = (char *)str_skip_char(pszTemp, ' '); 196 197 // get Win32 command line 198 win32cmdline = pszTemp; 199 200 // add the .EXE extension if missing 201 int i = strlen(exeName); 202 if (i < 4 || !((exeName[i-1] == 'E' || exeName[i-1] == 'e') && 203 (exeName[i-2] == 'X' || exeName[i-2] == 'x') && 204 (exeName[i-3] == 'E' || exeName[i-3] == 'e') && 205 exeName[i-4] == '.')) 206 { 207 if (i + 4 < CCHMAXPATH) 208 strcat(exeName, ".exe"); 209 } 210 211 // try to locate the executable 212 pszTemp = exeName + strlen(exeName) - 1; 213 while (pszTemp >= exeName && (*pszTemp != '\\' && *pszTemp != '/')) 214 --pszTemp; 215 if (pszTemp < exeName) 216 { 217 // no path information, perform a search 218 219 char newExeName[CCHMAXPATH]; 220 221 if(DosSearchPath( SEARCH_CUR_DIRECTORY | SEARCH_ENVIRONMENT | SEARCH_IGNORENETERRS 222 , "WINDOWSPATH" /* environment value */ 223 , exeName /* Name of file to look for */ 224 , newExeName /* Result of the search */ 225 , sizeof(newExeName) /* Length of search buffer */ 226 ) == NO_ERROR) 227 { 228 strcpy(exeName, newExeName); 137 229 } 138 while(*cmdline == ' ') cmdline++; //skip leading space 139 if(*cmdline == '"') { 140 cmdline++; 141 fQuote = TRUE; 142 } 143 win32cmdline = cmdline; 144 145 strncpy(exeName, cmdline, sizeof(exeName)-1); 146 exeName[sizeof(exeName)-1] = 0; 147 char *p = exeName; 148 if(fQuote) { 149 while(*p != '"' && *p != 0) p++; 150 } 151 else { 152 for(int i=0;i<nrTries;i++) { 153 while(*p != ' ' && *p != 0) p++; 154 if(*p == 0) break; 155 if(i != nrTries-1) { 156 while(*p == ' ' && *p != 0) p++; 157 } 158 } 159 if(nrTries > 1 && *p == 0) { 160 fEndOfCmdLine = TRUE; 161 } 162 } 163 *p = 0; 164 strupr(exeName); 165 cmdline = strstr(exeName, ".EXE"); 166 if(cmdline) { 167 cmdline[4] = 0; 168 win32cmdline += ((ULONG)cmdline - (ULONG)exeName) + 4; 169 } 170 else { 171 win32cmdline += strlen(exeName); 172 if(strstr(exeName, ".") == NULL) { 173 strcat(exeName, ".EXE"); 174 } 175 } 176 if(fQuote) win32cmdline++; 177 while(*win32cmdline == ' ') win32cmdline++; //skip spaces 178 179 cmdline = exeName + strlen(exeName) - 1; 180 while(*cmdline == ' ') cmdline--; 181 cmdline[1] = 0; 182 183 char drive[_MAX_DRIVE]; 184 char dir[_MAX_DIR]; 185 char fname[_MAX_FNAME]; 186 char ext[_MAX_EXT]; 187 char exeShortName[_MAX_FNAME+_MAX_EXT]; 188 _splitpath(exeName, drive, dir, fname, ext); 189 190 strcpy(fullpath, drive); 191 strcat(fullpath, dir); 192 193 strcpy(exeShortName, fname); 194 strcat(exeShortName, ext); 195 196 if ( strlen(fullpath) == 0 ) 197 { 198 char newExeName[CCHMAXPATH]; 199 200 if(DosSearchPath( SEARCH_CUR_DIRECTORY | SEARCH_ENVIRONMENT | SEARCH_IGNORENETERRS 201 , "WINDOWSPATH" /* environment value */ 202 , exeShortName /* Name of file to look for */ 203 , newExeName /* Result of the search */ 204 , sizeof(newExeName) /* Length of search buffer */ 205 ) == NO_ERROR) 206 { 207 strcpy(exeName, newExeName); 208 } 209 } 210 211 FILESTATUS3 fstat3; 212 if(DosQueryPathInfo(exeName, FIL_STANDARD, (PVOID)&fstat3, sizeof(fstat3))) 213 { 214 nrTries++; 215 if(fEndOfCmdLine) { 216 pszErrorMsg = szFileNotFound; 217 goto failerror; 218 } 219 220 if(*win32cmdline != NULL && !fQuote) { 221 goto tryagain; 222 } 223 } 224 } 225 else {//should never happen! 226 pszErrorMsg = szDosInfoBlocks; 230 } 231 232 DBG(("PE: Win32 EXE: '%s'\n", exeName)); 233 DBG(("PE: Win32 command line: '%s'\n", win32cmdline)); 234 235 FILESTATUS3 fstat3; 236 if (DosQueryPathInfo(exeName, FIL_STANDARD, (PVOID)&fstat3, sizeof(fstat3)) != NO_ERROR) 237 { 238 snprintf(szErrorMsg, sizeof(szErrorMsg), szFileNotFound, exeName); 239 pszErrorMsg = szErrorMsg; 227 240 goto failerror; 228 241 } 242 229 243 AllocateExeMem(exeName, &fIsNEExe); 230 if(fIsNEExe) { 244 245 if (fIsNEExe) 246 { 231 247 STARTDATA sdata = {0}; 232 248 ULONG idSession; … … 242 258 sdata.SessionType = SSF_TYPE_WINDOWEDVDM; 243 259 rc = DosStartSession(&sdata, &idSession, &pid); 244 if(rc) { 245 sprintf(fullpath, szErrDosStartSession, rc); 246 pszErrorMsg = fullpath; 260 if (rc) 261 { 262 snprintf(szErrorMsg, sizeof(szErrorMsg), szErrDosStartSession, sdata.PgmName, exeName, rc); 263 pszErrorMsg = szErrorMsg; 247 264 goto failerror; 248 265 } … … 250 267 } 251 268 } 252 253 #ifdef COMMAND_LINE_VERSION254 if(DosGetInfoBlocks(&ptib, &ppib) == 0) {255 //switch process type to PM so the command line app can create PM256 //windows257 ppib->pib_ultype = 3;258 }259 #endif260 269 261 270 rc = DosLoadModule(exeName, sizeof(exeName), "PMWIN", &hmodPMWin); … … 271 280 hmq = MyWinCreateMsgQueue(hab, 0); 272 281 273 if (argc < 2) {274 MyWinMessageBox(HWND_DESKTOP, NULL , INFO_BANNER, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);282 if (!cmdline) { 283 MyWinMessageBox(HWND_DESKTOP, NULLHANDLE, INFO_BANNER, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 275 284 goto fail; 276 285 } … … 279 288 rc = DosLoadModule(errorMod, sizeof(errorMod), "KERNEL32", &hmodKernel32); 280 289 if(rc) { 281 s printf(fullpath, szNoKernel32Msg, rc, errorMod);282 MyWinMessageBox(HWND_DESKTOP, NULL , fullpath, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);290 snprintf(fullpath, CCHMAXPATH, szNoKernel32Msg, rc, errorMod); 291 MyWinMessageBox(HWND_DESKTOP, NULLHANDLE, fullpath, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 283 292 goto fail; 284 293 } … … 294 303 if(rc != LDRERROR_SUCCESS) 295 304 { 296 char szErrorMsg[512];297 298 305 switch(rc) { 299 306 case LDRERROR_INVALID_MODULE: 300 s printf(szErrorMsg, szLoadErrorMsg, exeName);307 snprintf(szErrorMsg, sizeof(szErrorMsg), szLoadErrorMsg, exeName); 301 308 break; 302 309 case LDRERROR_INVALID_CPU: 303 s printf(pszErrorMsg, szCPUErrorMsg, exeName);310 snprintf(szErrorMsg, sizeof(szErrorMsg), szCPUErrorMsg, exeName); 304 311 break; 305 312 case LDRERROR_FILE_SYSTEM: 306 s printf(szErrorMsg, szExeErrorMsg, exeName);313 snprintf(szErrorMsg, sizeof(szErrorMsg), szExeErrorMsg, exeName); 307 314 break; 308 315 case LDRERROR_MEMORY: 309 s printf(szErrorMsg, szErrorMemory, exeName);316 snprintf(szErrorMsg, sizeof(szErrorMsg), szErrorMemory, exeName); 310 317 break; 311 318 case LDRERROR_EXPORTS: 312 s printf(szErrorMsg, szErrorExports, exeName);319 snprintf(szErrorMsg, sizeof(szErrorMsg), szErrorExports, exeName); 313 320 break; 314 321 case LDRERROR_IMPORTS: 315 s printf(szErrorMsg, szErrorImports, exeName, errorMod);322 snprintf(szErrorMsg, sizeof(szErrorMsg), szErrorImports, exeName, errorMod); 316 323 break; 317 324 case LDRERROR_INVALID_SECTION: 318 325 default: 319 s printf(szErrorMsg, szInteralErrorMsg, exeName);326 snprintf(szErrorMsg, sizeof(szErrorMsg), szInteralErrorMsg, exeName); 320 327 break; 321 328 } … … 330 337 DosFreeModule(hmodPMWin); 331 338 DosFreeModule(hmodKernel32); 339 340 DBG(("PE: END (returning 0)\n")); 332 341 return 0; 333 342 … … 338 347 if(hmodPMWin) DosFreeModule(hmodPMWin); 339 348 if(hmodKernel32) DosFreeModule(hmodKernel32); 349 350 DBG(("PE: END (returning 1)\n")); 340 351 return(1); 341 352 … … 353 364 hmq = MyWinCreateMsgQueue(hab, 0); 354 365 355 MyWinMessageBox(HWND_DESKTOP, NULL , pszErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);366 MyWinMessageBox(HWND_DESKTOP, NULLHANDLE, pszErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 356 367 } 357 368 if(hmq) MyWinDestroyMsgQueue( hmq ); /* Tidy up... */ 358 369 if(hab) MyWinTerminate( hab ); /* Terminate the application */ 359 370 if(hmodPMWin) DosFreeModule(hmodPMWin); 371 372 DBG(("PE: END (returning 1)\n")); 360 373 return 1; 361 374 } … … 368 381 { 369 382 HFILE dllfile = 0; 370 char szFileName[CCHMAXPATH], *tmp; 371 char szResult[CCHMAXPATH]; 383 char *tmp; 372 384 ULONG action, ulRead, signature; 373 385 APIRET rc; … … 376 388 IMAGE_FILE_HEADER fh; 377 389 ULONG address = 0; 378 ULONG *memallocs;379 390 ULONG alloccnt = 0; 380 391 ULONG diff, i, baseAddress; … … 382 393 BOOL ret = FALSE; 383 394 395 //Reserve enough space to store 4096 pointers to 1MB memory chunks 396 static ULONG memallocs[4096]; 397 384 398 *fNEExe = FALSE; 385 strcpy(szFileName, filename); 386 387 rc = DosOpen(szFileName, &dllfile, &action, 0, FILE_READONLY, OPEN_ACTION_OPEN_IF_EXISTS|OPEN_ACTION_FAIL_IF_NEW, OPEN_SHARE_DENYNONE|OPEN_ACCESS_READONLY, NULL); 388 if(rc != 0) { 389 if(!strstr(szFileName, ".EXE")) { 390 strcat(szFileName,".EXE"); 391 } 392 } 393 else DosClose(dllfile); 394 395 rc = DosOpen(szFileName, &dllfile, &action, 0, FILE_READONLY, OPEN_ACTION_OPEN_IF_EXISTS|OPEN_ACTION_FAIL_IF_NEW, OPEN_SHARE_DENYNONE|OPEN_ACCESS_READONLY, NULL); 399 400 rc = DosOpen(filename, &dllfile, &action, 0, FILE_READONLY, OPEN_ACTION_OPEN_IF_EXISTS|OPEN_ACTION_FAIL_IF_NEW, OPEN_SHARE_DENYNONE|OPEN_ACCESS_READONLY, NULL); 396 401 if(rc) { 397 if(DosSearchPath(SEARCH_IGNORENETERRS|SEARCH_ENVIRONMENT, "PATH", 398 szFileName, szResult, sizeof(szResult)) != 0) { 399 goto end; //oops 400 } 401 rc = DosOpen(szResult, &dllfile, &action, 0, FILE_READONLY, OPEN_ACTION_OPEN_IF_EXISTS|OPEN_ACTION_FAIL_IF_NEW, OPEN_SHARE_DENYNONE|OPEN_ACCESS_READONLY, NULL); 402 if(rc) { 403 goto end; //oops 404 } 402 goto end; //oops 405 403 } 406 404 … … 432 430 fConsoleApp = (oh.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI); 433 431 432 DBG(("PE: AllocateExeMem: oh.Subsystem: %d\n", oh.Subsystem)); 433 DBG(("PE: AllocateExeMem: oh.ImageBase: 0x%08X\n", oh.ImageBase)); 434 434 435 // check for high memory support 435 436 rc = DosQuerySysInfo(QSV_VIRTUALADDRESSLIMIT, QSV_VIRTUALADDRESSLIMIT, &ulSysinfo, sizeof(ulSysinfo)); … … 439 440 } 440 441 441 //Reserve enough space to store 4096 pointers to 1MB memory chunks 442 memallocs = (ULONG *)alloca(4096*sizeof(ULONG *)); 443 if(memallocs == NULL) { 444 goto end; //oops 445 } 442 DBG(("PE: AllocateExeMem: VIRTUALADDRESSLIMIT: %d (rc %d)\n", ulSysinfo, rc)); 446 443 447 444 if(oh.ImageBase < 512*1024*1024) { … … 483 480 DosFreeMem((PVOID)memallocs[i]); 484 481 } 482 DBG(("PE: AllocateExeMem: reservedMemory: 0x%08X\n", reservedMemory)); 485 483 ret = TRUE; 486 484 end: 487 485 if(dllfile) DosClose(dllfile); 486 DBG(("PE: AllocateExeMem: returning %d\n", ret)); 488 487 return ret; 489 488 }
Note:
See TracChangeset
for help on using the changeset viewer.