Changeset 4164 for trunk/src/win32k/ldr
- Timestamp:
- Sep 2, 2000, 11:08:23 PM (25 years ago)
- Location:
- trunk/src/win32k/ldr
- Files:
-
- 1 added
- 5 deleted
- 10 edited
-
ModuleBase.cpp (modified) (6 diffs)
-
calltab.asm (modified) (4 diffs)
-
ldr.cpp (modified) (9 diffs)
-
myLDRLoadExe.cpp (deleted)
-
myLDRQAppType.cpp (modified) (4 diffs)
-
myldrClose.cpp (modified) (5 diffs)
-
myldrCreateMte.cpp (deleted)
-
myldrEnum32bitRelRecs.cpp (modified) (3 diffs)
-
myldrGetMte.cpp (deleted)
-
myldrGetResource.cpp (deleted)
-
myldrOpen.cpp (modified) (8 diffs)
-
myldrOpenNewExe.cpp (deleted)
-
myldrOpenPath.cpp (modified) (4 diffs)
-
myldrRead.cpp (modified) (4 diffs)
-
mytkExecPgm.asm (modified) (8 diffs)
-
mytkStartProcess.asm (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/win32k/ldr/ModuleBase.cpp
r2926 r4164 1 /* $Id: ModuleBase.cpp,v 1. 3 2000-02-27 02:17:06 bird Exp $1 /* $Id: ModuleBase.cpp,v 1.4 2000-09-02 21:08:06 bird Exp $ 2 2 * 3 3 * ModuleBase - Implementetation. … … 12 12 * Defined Constants And Macros * 13 13 *******************************************************************************/ 14 #define INCL_DOSERRORS /* DOS Error codes. */14 #define INCL_DOSERRORS /* DOS Error codes. */ 15 15 #ifdef RING0 16 #define INCL_NOAPI /* RING0: No apis. */16 #define INCL_NOAPI /* RING0: No apis. */ 17 17 #else /*RING3*/ 18 #define INCL_DOSFILEMGR /* RING3: DOS File api. */18 #define INCL_DOSFILEMGR /* RING3: DOS File api. */ 19 19 #endif 20 20 … … 23 23 * Header Files * 24 24 *******************************************************************************/ 25 #include <os2.h> /* OS/2 header file. */ 26 27 #include "malloc.h" /* win32k malloc. Not C library! */ 28 29 #include <string.h> /* C library string.h. */ 30 #include <stdarg.h> /* C library stdarg.h. */ 31 32 #include "vprintf.h" /* win32k printf and vprintf. Not C library! */ 33 #include "dev32.h" /* 32-Bit part of the device driver. (SSToDS) */ 34 #include "OS2Krnl.h" /* kernel structs. (SFN) */ 35 #include "modulebase.h" /* ModuleBase class definitions, ++. */ 25 #include <os2.h> /* OS/2 header file. */ 26 27 #include "devSegDf.h" /* Win32k segment definitions. */ 28 #include "malloc.h" /* Win32k malloc. Not C library! */ 29 30 #include <string.h> /* C library string.h. */ 31 #include <stdarg.h> /* C library stdarg.h. */ 32 33 #include "vprintf.h" /* win32k printf and vprintf. Not C library! */ 34 #include "dev32.h" /* 32-Bit part of the device driver. (SSToDS) */ 35 #include "OS2Krnl.h" /* kernel structs. (SFN) */ 36 #include "ldrCalls.h" /* ldrOpenPath and ldrlv_t. */ 37 #include "modulebase.h" /* ModuleBase class definitions, ++. */ 36 38 37 39 … … 159 161 } 160 162 163 164 /** 165 * openPath - opens file eventually searching loader specific paths. 166 * 167 * This base implementation simply calls ldrOpenPath. 168 * This method is only called for DLLs. DosLoadModule and Imports. 169 * 170 * @returns OS2 return code. 171 * pLdrLv->lv_sfn is set to filename handle. 172 * @param pachFilename Pointer to filename. Not zero terminated! 173 * @param cchFilename Filename length. 174 * @param pLdrLv Loader local variables? (Struct from KERNEL.SDF) 175 * @param pful Pointer to flags which are passed on to ldrOpen. 176 * @sketch 177 * This is roughly what the original ldrOpenPath does: 178 * if !CLASS_GLOBAL or miniifs then 179 * ldrOpen(pachModName) 180 * else 181 * loop until no more libpath elements 182 * get next libpath element and add it to the modname. 183 * try open the modname 184 * if successfull then break the loop. 185 * endloop 186 * endif 187 */ 188 ULONG ModuleBase::openPath(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *pLdrLv, PULONG pful) /* (ldrOpenPath) */ 189 { 190 #ifdef RING0 191 printf("ModuleBase::openPath:\n"); 192 return ldrOpenPath(pachFilename, cchFilename, pLdrLv, pful); 193 #else 194 NOREF(pachFilename); 195 NOREF(cchFilename); 196 NOREF(pLdrLv); 197 NOREF(pful); 198 return ERROR_NOT_SUPPORTED; 199 #endif 200 } 161 201 162 202 … … 232 272 233 273 /** 274 * Gets the fullpath filename. 275 * @returns Const ("Readonly") pointer to the filename. 276 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 277 */ 278 PCSZ ModuleBase::getFilename() 279 { 280 return pszFilename; 281 } 282 283 284 /** 285 * Gets the modulename. 286 * @returns Const ("Readonly") pointer to the module name. 287 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 288 * @remark Modulename is filename without path and extention. 289 */ 290 PCSZ ModuleBase::getModuleName() 291 { 292 return pszModuleName; 293 } 294 295 296 /** 234 297 * Output function for Modules. 235 298 * @param pszFormat Pointer to format string. … … 273 336 rc = DosRead(hFile, pvBuffer, cbToRead, &cbRead); 274 337 else 275 printErr(("DosSetFilePtr(hfile, %#8x(%d),..) failed with rc = %d. ",338 printErr(("DosSetFilePtr(hfile, %#8x(%d),..) failed with rc = %d.\n", 276 339 ulOffset, ulOffset, rc)); 277 340 -
trunk/src/win32k/ldr/calltab.asm
r3411 r4164 1 ; $Id: calltab.asm,v 1.12 2000-04-17 01:56:49 bird Exp $ 2 ; 3 ; callTab - Call back again table - table with entry for each function which is overrided. 4 ; It holds the part of the prolog which was replaced by a jmp instruction. 5 ; 6 ; Copyright (c) 1998-1999 knut st. osmundsen 1 ; $Id: calltab.asm,v 1.13 2000-09-02 21:08:06 bird Exp $ 2 ; 3 ; callTab - Call back again table - table with entry for each function or 4 ; variable which is overrided. 5 ; It holds the part of the prolog which was replaced by the jmp 6 ; instruction (overridden functions). 7 ; 8 ; Copyright (c) 1998-2000 knut st. osmundsen 7 9 ; 8 10 ; Project Odin Software License can be found in LICENSE.TXT … … 35 37 public _VMGetOwner@8 36 38 public _g_tkExecPgm 39 public _tkStartProcess 37 40 public _f_FuStrLenZ 38 41 public _f_FuBuff 39 42 43 public _VMObjHandleInfo@12 44 public _ldrASMpMTEFromHandle@4 45 public _ldrOpenPath@16 46 public _LDRClearSem@0 47 public _ldrFindModule@16 48 public _KSEMRequestMutex@8 49 public _KSEMReleaseMutex@4 50 public _KSEMQueryMutex@8 51 public _KSEMInit@12 52 53 public pLDRSem 54 public LDRSem_offObject 55 public _fpLDRSem 56 public LDRSem_sel 57 58 public pLDRLibPath 59 public LDRLibPath_offObject 60 public _fpLDRLibPath 61 public LDRLibPath_sel 62 63 public _TKSuBuff@16 64 public _TKFuBuff@16 65 public _TKFuBufLen@20 66 public _ldrValidateMteHandle@4 67 68 public ppTCBCur 69 public pTCBCur_offObject 70 public _fppTCBCur 71 public pTCBCur_sel 72 73 public ppPTDACur 74 public pPTDACur_offObject 75 public _fppPTDACur 76 public pPTDACur_sel 77 78 public pptda_start 79 public ptda_start_offObject 80 public _fpptda_start 81 public ptda_start_sel 82 83 public pptda_environ 84 public ptda_environ_offObject 85 public _fpptda_environ 86 public ptda_environ_sel 87 88 public pptda_ptdasem 89 public ptda_ptdasem_offObject 90 public _fpptda_ptdasem 91 public ptda_ptdasem_sel 92 93 public pptda_module 94 public ptda_module_offObject 95 public _fpptda_module 96 public ptda_module_sel 97 98 public pptda_pBeginLIBPATH 99 public ptda_pBeginLIBPATH_offObject 100 public _fpptda_pBeginLIBPATH 101 public pptda_pBeginLIBPATH_sel 102 103 public pldrpFileNameBuf 104 public pldrpFileNameBuf_offObject 105 public _fpldrpFileNameBuf 106 public pldrpFileNameBuf_sel 107 108 public SecPathFromSFN 109 40 110 41 111 ; … … 47 117 48 118 CALLTAB segment 49 assume cs:CALLTAB, ds:flat, ss:nothing 119 ;assume cs:CALLTAB, ds:flat, ss:nothing 120 assume ds:flat, ss:nothing 50 121 ; 51 122 ; callTab is an array of evt. function prologs with a jump to the real function. … … 56 127 ; 57 128 callTab: 129 130 ; 0 58 131 _ldrRead@24 PROC NEAR 59 132 db MAXSIZE_PROLOG dup(0cch) 60 133 _ldrRead@24 ENDP 61 134 135 ; 1 62 136 _ldrOpen@12 PROC NEAR 63 137 db MAXSIZE_PROLOG dup(0cch) 64 138 _ldrOpen@12 ENDP 65 139 140 ; 2 66 141 _ldrClose@4 PROC NEAR 67 142 db MAXSIZE_PROLOG dup(0cch) 68 143 _ldrClose@4 ENDP 69 144 145 ; 3 70 146 _LDRQAppType@8 PROC NEAR 71 147 db MAXSIZE_PROLOG dup(0cch) 72 148 _LDRQAppType@8 ENDP 73 149 150 ; 4 74 151 _ldrEnum32bitRelRecs@24 PROC NEAR 75 152 db MAXSIZE_PROLOG dup(0cch) 76 153 _ldrEnum32bitRelRecs@24 ENDP 77 154 78 155 ; 5 79 156 _IOSftOpen@20 PROC NEAR 80 157 db MAXSIZE_PROLOG dup(0cch) 81 158 _IOSftOpen@20 ENDP 82 159 160 ; 6 83 161 _IOSftClose@4 PROC NEAR 84 162 db MAXSIZE_PROLOG dup(0cch) 85 163 _IOSftClose@4 ENDP 86 164 165 ; 7 87 166 _IOSftTransPath@4 PROC NEAR 88 167 db MAXSIZE_PROLOG dup(0cch) 89 168 _IOSftTransPath@4 ENDP 90 169 170 ; 8 91 171 _IOSftReadAt@20 PROC NEAR 92 172 db MAXSIZE_PROLOG dup(0cch) 93 173 _IOSftReadAt@20 ENDP 94 174 175 ; 9 95 176 _IOSftWriteAt@20 PROC NEAR 96 177 db MAXSIZE_PROLOG dup(0cch) 97 178 _IOSftWriteAt@20 ENDP 98 179 180 ; 10 99 181 _SftFileSize@8 PROC NEAR 100 182 db MAXSIZE_PROLOG dup(0cch) 101 183 _SftFileSize@8 ENDP 102 184 103 185 ; 11 104 186 _VMAllocMem@36 PROC NEAR 105 187 db MAXSIZE_PROLOG dup(0cch) 106 188 _VMAllocMem@36 ENDP 107 189 190 ; 12 108 191 _VMGetOwner@8 PROC NEAR 109 192 db MAXSIZE_PROLOG dup(0cch) 110 193 _VMGetOwner@8 ENDP 111 194 195 ; 13 112 196 _g_tkExecPgm PROC NEAR 113 197 db MAXSIZE_PROLOG dup(0cch) 114 198 _g_tkExecPgm ENDP 115 199 116 200 ; 14 201 _tkStartProcess PROC NEAR 202 db MAXSIZE_PROLOG dup(0cch) 203 _tkStartProcess ENDP 204 205 ; 15 117 206 _f_FuStrLenZ PROC FAR 118 207 db MAXSIZE_PROLOG dup(0cch) 119 208 _f_FuStrLenZ ENDP 120 209 210 ; 16 121 211 _f_FuStrLen PROC FAR 122 212 db MAXSIZE_PROLOG dup(0cch) 123 213 _f_FuStrLen ENDP 124 214 215 ; 17 125 216 _f_FuBuff PROC FAR 126 217 db MAXSIZE_PROLOG dup(0cch) 127 218 _f_FuBuff ENDP 128 219 220 ; 18 129 221 _VMObjHandleInfo@12 PROC NEAR 130 222 db MAXSIZE_PROLOG dup(0cch) 131 223 _VMObjHandleInfo@12 ENDP 132 224 225 ; 19 226 _ldrASMpMTEFromHandle@4 PROC NEAR 227 db MAXSIZE_PROLOG dup(0cch) 228 _ldrASMpMTEFromHandle@4 ENDP 229 230 ; 20 231 _ldrOpenPath@16 PROC NEAR 232 db MAXSIZE_PROLOG dup(0cch) 233 _ldrOpenPath@16 ENDP 234 235 ; 21 236 _LDRClearSem@0 PROC NEAR 237 db MAXSIZE_PROLOG dup(0cch) 238 _LDRClearSem@0 ENDP 239 240 ; 22 241 _ldrFindModule@16 PROC NEAR 242 db MAXSIZE_PROLOG dup(0cch) 243 _ldrFindModule@16 ENDP 244 245 ; 23 246 _KSEMRequestMutex@8 PROC NEAR 247 db MAXSIZE_PROLOG dup(0cch) 248 _KSEMRequestMutex@8 ENDP 249 250 ; 24 251 _KSEMReleaseMutex@4 PROC NEAR 252 db MAXSIZE_PROLOG dup(0cch) 253 _KSEMReleaseMutex@4 ENDP 254 255 ; 25 256 _KSEMQueryMutex@8 PROC NEAR 257 db MAXSIZE_PROLOG dup(0cch) 258 _KSEMQueryMutex@8 ENDP 259 260 ; 26 261 _KSEMInit@12 PROC NEAR 262 db MAXSIZE_PROLOG dup(0cch) 263 _KSEMInit@12 ENDP 264 265 ; 27 266 pLDRSem dd 0 267 LDRSem_offObject dd 0 268 _fpLDRSem dd 0 269 LDRSem_sel dw 0 270 db (MAXSIZE_PROLOG - 14) dup(0cch) 271 272 273 ; 28 274 pLDRLibPath dd 0 275 LDRLibPath_offObject dd 0 276 _fpLDRLibPath dd 0 277 LDRLibPath_sel dw 0 278 db (MAXSIZE_PROLOG - 14) dup(0cch) 279 280 ; 29 281 _TKSuBuff@16 PROC NEAR 282 db MAXSIZE_PROLOG dup(0cch) 283 _TKSuBuff@16 ENDP 284 285 ; 30 286 _TKFuBuff@16 PROC NEAR 287 db MAXSIZE_PROLOG dup(0cch) 288 _TKFuBuff@16 ENDP 289 290 ; 31 291 _TKFuBufLen@20 PROC NEAR 292 db MAXSIZE_PROLOG dup(0cch) 293 _TKFuBufLen@20 ENDP 294 295 ; 32 296 _ldrValidateMteHandle@4 PROC NEAR 297 db MAXSIZE_PROLOG dup(0cch) 298 _ldrValidateMteHandle@4 ENDP 299 300 ; 33 301 ppTCBCur dd 0 302 pTCBCur_offObject dd 0 303 _fppTCBCur dd 0 304 pTCBCur_sel dw 0 305 db (MAXSIZE_PROLOG - 14) dup(0cch) 306 307 ; 34 308 ppPTDACur dd 0 309 pPTDACur_offObject dd 0 310 _fppPTDACur dd 0 311 pPTDACur_sel dw 0 312 db (MAXSIZE_PROLOG - 14) dup(0cch) 313 314 ; 35 315 pptda_start dd 0 316 ptda_start_offObject dd 0 317 _fpptda_start dd 0 318 ptda_start_sel dw 0 319 db (MAXSIZE_PROLOG - 14) dup(0cch) 320 321 ; 36 322 pptda_environ dd 0 323 ptda_environ_offObject dd 0 324 _fpptda_environ dd 0 325 ptda_environ_sel dw 0 326 db (MAXSIZE_PROLOG - 14) dup(0cch) 327 328 ; 37 329 pptda_ptdasem dd 0 330 ptda_ptdasem_offObject dd 0 331 _fpptda_ptdasem dd 0 332 ptda_ptdasem_sel dw 0 333 db (MAXSIZE_PROLOG - 14) dup(0cch) 334 335 ; 38 336 pptda_module dd 0 337 ptda_module_offObject dd 0 338 _fpptda_module dd 0 339 ptda_module_sel dw 0 340 db (MAXSIZE_PROLOG - 14) dup(0cch) 341 342 ; 39 343 pptda_pBeginLIBPATH dd 0 344 ptda_pBeginLIBPATH_offObject dd 0 345 _fpptda_pBeginLIBPATH dd 0 346 pptda_pBeginLIBPATH_sel dw 0 347 db (MAXSIZE_PROLOG - 14) dup(0cch) 348 349 ; 40 350 pldrpFileNameBuf dd 0 351 pldrpFileNameBuf_offObject dd 0 352 _fpldrpFileNameBuf dd 0 353 pldrpFileNameBuf_sel dw 0 354 db (MAXSIZE_PROLOG - 14) dup(0cch) 355 356 ; 41 357 SecPathFromSFN PROC NEAR 358 db MAXSIZE_PROLOG dup(0cch) 359 SecPathFromSFN ENDP 360 361 133 362 CALLTAB ENDS 134 363 -
trunk/src/win32k/ldr/ldr.cpp
r2501 r4164 1 /* $Id: ldr.cpp,v 1. 7 2000-01-22 18:21:01bird Exp $1 /* $Id: ldr.cpp,v 1.8 2000-09-02 21:08:06 bird Exp $ 2 2 * 3 3 * ldr.cpp - Loader helpers. … … 14 14 #define INCL_DOSERRORS 15 15 #define INCL_NOPMAPI 16 16 #define INCL_OS2KRNL_SEM 17 #define INCL_OS2KRNL_PTDA 17 18 18 19 /******************************************************************************* … … 21 22 #include <os2.h> 22 23 24 #include "devSegDf.h" 23 25 #include "malloc.h" 24 26 #include "new.h" … … 26 28 #include <stdlib.h> 27 29 #include <stddef.h> 30 #include <string.h> 28 31 29 32 #include "log.h" 33 #include "avl.h" 30 34 #include <peexe.h> 31 35 #include <exe386.h> 32 36 #include "OS2Krnl.h" 37 #include "ldr.h" 38 #include "ldrCalls.h" 33 39 #include "ModuleBase.h" 34 40 #include "pe2lx.h" 35 #include "avl.h"36 #include "ldr.h"37 41 #include "options.h" 38 42 … … 41 45 * Global Variables * 42 46 *******************************************************************************/ 43 PAVLNODECORE pSFNRoot = NULL; 44 PAVLNODECORE pMTERoot = NULL; 45 47 static PAVLNODECORE pSFNRoot = NULL; 48 static PAVLNODECORE pMTERoot = NULL; 49 50 51 /* 52 * Loader State. (See ldr.h for more info.) 53 */ 54 ULONG ulLdrState = LDRSTATE_UNKNOWN; 55 56 57 /* 58 * Pointer to the executable module being loaded. 59 * This pointer is set by ldrOpen and cleared by tkExecPgm. 60 * It's hence only valid at tkExecPgm time. (isLdrStateExecPgm() == TRUE). 61 */ 62 PMODULE pExeModule = NULL; 63 64 65 /* 66 * Filehandle bitmap. 67 */ 46 68 unsigned char achHandleStates[MAX_FILE_HANDLES/8]; 69 70 47 71 48 72 … … 64 88 * Gets a module by the MTE. 65 89 * @returns Pointer to module node. If not found NULL. 66 * @param pMTE Pointer a nModule Table Entry.90 * @param pMTE Pointer a Module Table Entry. 67 91 * @sketch Try find it in the MTE tree. 68 92 * IF not found THEN … … 124 148 125 149 /** 150 * Gets a module by the hMTE. 151 * @returns Pointer to module node. If not found NULL. 152 * @param hMTE Handle to a Module Table Entry. 153 * @sketch Convert hMte to an pMTE (pointer to MTE). 154 * Call getModuleByMTE with MTE pointer. 155 * @status completely implemented. 156 * @author knut st. osmundsen 157 */ 158 PMODULE getModuleByhMTE(HMTE hMTE) 159 { 160 PMTE pMTE; 161 162 pMTE = ldrValidateMteHandle(hMTE); 163 if (pMTE != NULL) 164 return getModuleByMTE(pMTE); 165 166 return NULL; 167 } 168 169 170 /** 126 171 * Get a module by filename. 127 172 * @returns Pointer to module node. If not found NULL. … … 236 281 delete pMod->Data.pPe2Lx; 237 282 break; 238 283 /* 239 284 case MOD_TYPE_ELF2LX: 240 case MOD_TYPE_SCRIPT: 241 case MOD_TYPE_PE: 285 break; 286 */ 287 #ifdef DEBUG 242 288 default: 243 289 kprintf(("removeModule: Unknown type, %#x\n", pMod->fFlags & MOD_TYPE_MASK)); 290 #endif 244 291 } 245 292 … … 248 295 249 296 return NO_ERROR; 297 } 298 299 300 /** 301 * Gets the path of the executable being executed. 302 * @returns Pointer to pszPath on success. Path has _NOT_ a trailing slash. 303 * NULL pointer on error. 304 * @param pszPath Pointer to path buffer. Expects CCHMAXPATH length. 305 * @param fExecChild Use hMTE of the PTDAExecChild if present. 306 * @sketch 307 * @status completely implemented. 308 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 309 * @remark The path from the pExeModule might not be fully qualified. 310 */ 311 PSZ ldrGetExePath(PSZ pszPath, BOOL fExecChild) 312 { 313 PCSZ pszFilename; 314 PCSZ psz; 315 316 #if 0 /* getFilename not implemented */ 317 if (pExeModule != NULL) 318 /* 319 * We have the executable object pointer. Let's use it! 320 */ 321 pszFilename = pExeModule->Data.pModule->getFilename(); 322 else 323 #endif 324 { 325 /* 326 * Get the hMTE for the executable using the pPTDAExecChild 327 * Then get the pMTE, and access the smte_path to get a pointer to the executable path. 328 */ 329 PPTDA pPTDACur; /* Pointer to the current (system context) PTDA */ 330 PPTDA pPTDA; /* PTDA in question. */ 331 HMTE hMTE = NULLHANDLE; /* Modulehandle of the executable module. */ 332 PMTE pMTE; /* Pointer to ModuleTableEntry of the executable module. */ 333 334 /* 335 * Get the current PTDA. (Fail if this call failes.) 336 * IF pPTDAExecChild isn't NULL THEN get hMTE for that. 337 * IF no pPTDAExecChild THEN get hMte for the current PTDA. 338 */ 339 pPTDACur = ptdaGetCur(); 340 if (pPTDACur != NULL) 341 { 342 pPTDA = ptdaGet_pPTDAExecChild(pPTDACur); 343 if (pPTDA != NULL && fExecChild) 344 hMTE = ptdaGet_ptda_module(pPTDA); 345 if (hMTE == NULLHANDLE) 346 hMTE = ptdaGet_ptda_module(pPTDACur); 347 } 348 else 349 { /* Not called at task time? No current task! */ 350 kprintf(("ldrGetExePath: Failed to get current PTDA.\n")); 351 return NULL; 352 } 353 354 /* fail if hMTE is NULLHANDLE ie. not found / invalid */ 355 if (hMTE == NULLHANDLE) 356 { 357 kprintf(("ldrGetExePath: Failed to get hMTE from the PTDAs.\n")); 358 return NULL; 359 } 360 361 /* get the pMTE for this hMTE */ 362 pMTE = ldrASMpMTEFromHandle(hMTE); 363 if (pMTE == NULL) 364 { 365 kprintf(("ldrGetExePath: ldrASMpMTEFromHandle failed for hMTE=0x%04.\n", hMTE)); 366 return NULL; 367 } 368 if (pMTE->mte_swapmte == NULL) /* paranoia */ 369 { 370 kprintf(("ldrGetExePath: mte_swapmte is NULL.\n")); 371 return NULL; 372 } 373 374 /* take the filename from the swappable MTE */ 375 pszFilename = pMTE->mte_swapmte->smte_path; 376 if (pszFilename == NULL) 377 { 378 kprintf(("ldrGetExePath: smte_path is NULL.\n")); 379 return NULL; 380 } 381 } 382 383 /* paranoia... */ 384 if (*pszFilename == '\0') 385 { 386 kprintf(("ldrGetExePath: pszFilename is empty!\n")); 387 return NULL; 388 } 389 390 /* 391 * Skip back over the filename. (stops pointing at the slash or ':') 392 */ 393 psz = pszFilename + strlen(pszFilename)-1; 394 while (psz >= pszFilename && *psz != '\\' && *psz != '/' && *psz != ':') 395 psz--; 396 397 /* 398 * If no path the fail. 399 */ 400 if (psz <= pszFilename) 401 { 402 kprintf(("ldrGetExePath: Exepath is empty.\n")); 403 return NULL; 404 } 405 406 /* 407 * Copy path and return. 408 */ 409 memcpy(pszPath, pszFilename, psz - pszFilename); 410 pszPath[psz - pszFilename] = '\0'; 411 return pszPath; 250 412 } 251 413 -
trunk/src/win32k/ldr/myLDRQAppType.cpp
r2501 r4164 1 /* $Id: myLDRQAppType.cpp,v 1. 3 2000-01-22 18:21:02bird Exp $1 /* $Id: myLDRQAppType.cpp,v 1.4 2000-09-02 21:08:07 bird Exp $ 2 2 * 3 3 * _myLDRQAppType - _LDRQAppType overload. … … 15 15 #define INCL_NOPMAPI 16 16 17 #define INCL_OS2KRNL_PTDA 18 #define INCL_OS2KRNL_SEM 19 17 20 /******************************************************************************* 18 21 * Header Files * … … 20 23 #include <os2.h> 21 24 25 #include "devSegDf.h" /* Win32k segment definitions. */ 22 26 #include "OS2Krnl.h" 27 #include "avl.h" 28 #include "ldr.h" 23 29 #include "ldrCalls.h" 24 30 #include "log.h" 25 31 26 BOOL fQAppType = FALSE;27 32 28 33 /** 29 * LDRQAppType - Loader Query Application Type. 30 * We set a flag while we're executing this function. Just to speed up processing. 31 * If a PE file is queried, a dummy LX header is presented. 34 * LDRQAppType - Loader Query Application Type - DosQueryAppType worker. 35 * 36 * We overrides this be able to determin if a convertion is only for a 37 * LDRQAppType call. 38 * 39 * isLdrStateQAppType() returns TRUE when this procedure is on the stack. 40 * 32 41 * @returns return code. 33 42 * @param p1 … … 38 47 APIRET rc; 39 48 40 kprintf(("_LDRQAppType: entry\n")); 41 fQAppType = 1; 49 kprintf(("myLDRQAppType: entry\n")); 50 rc = KSEMRequestMutex(ptda_ptda_ptdasem(ptdaGetCur()), KSEM_INDEFINITE_WAIT); 51 if (rc != NO_ERROR) 52 { 53 kprintf(("myLDRQAppType: failed to get intra-process semaphore.\n")); 54 return rc; 55 } 56 rc = LDRRequestSem(); 57 if (rc != NO_ERROR) 58 { 59 kprintf(("myLDRQAppType: failed to get loader semaphore.\n")); 60 return rc; 61 } 62 63 ASSERT_LdrStateUnknown("myLDRQAppType") 64 setLdrStateQAppType(); 42 65 43 66 rc = LDRQAppType(p1, p2); 44 67 45 fQAppType = 0; 46 kprintf(("_LDRQAppType: exit\n")); 68 ASSERT_LdrStateQAppType("myLDRQAppType") 69 setLdrStateUnknown(); 70 71 LDRClearSem(); 72 KSEMReleaseMutex(ptda_ptda_ptdasem(ptdaGetCur())); 73 kprintf(("myLDRQAppType: exit\n")); 47 74 48 75 return rc; -
trunk/src/win32k/ldr/myldrClose.cpp
r2501 r4164 1 /* $Id: myldrClose.cpp,v 1. 5 2000-01-22 18:21:02bird Exp $1 /* $Id: myldrClose.cpp,v 1.6 2000-09-02 21:08:07 bird Exp $ 2 2 * 3 3 * myldrClose - ldrClose … … 23 23 #include <stdlib.h> 24 24 25 #include "devSegDf.h" /* Win32k segment definitions. */ 25 26 #include "log.h" 27 #include "avl.h" 26 28 #include <peexe.h> 27 29 #include <exe386.h> 28 30 #include "OS2Krnl.h" 29 #include "avl.h"30 #include "ModuleBase.h"31 31 #include "ldr.h" 32 32 #include "ldrCalls.h" 33 #include "ModuleBase.h" 34 #include "Pe2Lx.h" 33 35 34 36 … … 42 44 { 43 45 /* closes handle */ 44 kprintf((" ldrClose: hFile = %.4x\n", hFile));46 kprintf(("myldrClose: hFile = %.4x\n", hFile)); 45 47 if (GetState(hFile) == HSTATE_OUR) 46 48 { … … 52 54 pMod->Data.pModule->dumpVirtualLxFile(); 53 55 else 54 kprintf((" ldrClose: getModuleBySFN failed!!!"));56 kprintf(("myldrClose: getModuleBySFN failed!!!")); 55 57 #endif 56 58 57 59 rc = removeModule(hFile); 58 60 if (rc != NO_ERROR) 59 kprintf((" ldrClose: removeModule retured rc=%d\n", rc));61 kprintf(("myldrClose: removeModule retured rc=%d\n", rc)); 60 62 61 63 #pragma info(notrd) … … 63 65 #pragma info(restore) 64 66 } 67 /* 68 * Invalidate the odin32path if kernel32 is closed. 69 * (Might possible not be needed as Pe2Lx does invalides 70 * the odin32path on object destruction.) 71 */ 72 else if (Pe2Lx::getKernel32SFN() == hFile) 73 Pe2Lx::invalidateOdin32Path(); 65 74 75 /* 76 * Finally call the real close function. 77 */ 66 78 return ldrClose(hFile); 67 79 } -
trunk/src/win32k/ldr/myldrEnum32bitRelRecs.cpp
r2537 r4164 1 /* $Id: myldrEnum32bitRelRecs.cpp,v 1. 2 2000-01-27 23:43:07bird Exp $1 /* $Id: myldrEnum32bitRelRecs.cpp,v 1.3 2000-09-02 21:08:08 bird Exp $ 2 2 * 3 3 * myldrEnum32bitRelRecs - ldrEnum32bitRelRecs … … 24 24 #include <stdlib.h> 25 25 26 #include "devSegDf.h" /* Win32k segment definitions. */ 27 #include "avl.h" 26 28 #include "log.h" 27 29 #include <peexe.h> 28 30 #include <exe386.h> 29 31 #include "OS2Krnl.h" 30 #include "avl.h"31 #include "ModuleBase.h"32 32 #include "ldr.h" 33 33 #include "ldrCalls.h" 34 #include "ModuleBase.h" 34 35 35 36 … … 63 64 APIRET rc; 64 65 #if 1 65 kprintf((" ldrEnum32BitRelRecs: pMTE=0x%08x iObject=0x%02x iPageTable=0x%03x pvPage=0x%08x\n"66 kprintf(("myldrEnum32BitRelRecs: pMTE=0x%08x iObject=0x%02x iPageTable=0x%03x pvPage=0x%08x\n" 66 67 " ulPageAddress=0x%08x pvPTDA=0x%08x\n", 67 68 pMTE, iObject, iPageTable, pvPage, ulPageAddress, pvPTDA -
trunk/src/win32k/ldr/myldrOpen.cpp
r2838 r4164 1 /* $Id: myldrOpen.cpp,v 1.1 0 2000-02-21 09:24:01bird Exp $1 /* $Id: myldrOpen.cpp,v 1.11 2000-09-02 21:08:09 bird Exp $ 2 2 * 3 3 * myldrOpen - ldrOpen. 4 4 * 5 * Copyright (c) 1998- 1999knut st. osmundsen5 * Copyright (c) 1998-2000 knut st. osmundsen 6 6 * 7 7 * Project Odin Software License can be found in LICENSE.TXT … … 17 17 18 18 #define INCL_OS2KRNL_IO 19 #define INCL_OS2KRNL_TCB 20 #define INCL_OS2KRNL_SEM 21 #define INCL_OS2KRNL_SEC 19 22 20 23 /******************************************************************************* … … 23 26 #include <os2.h> 24 27 28 #include "devSegDf.h" /* Win32k segment definitions. */ 25 29 #include "rmalloc.h" 26 30 #include "malloc.h" … … 28 32 #include <stdlib.h> 29 33 #include <string.h> 34 #include <stdarg.h> 30 35 31 36 #include "log.h" 37 #include "avl.h" 38 #include "options.h" 32 39 #include <peexe.h> 33 40 #include <exe386.h> 41 #include "elf.h" 34 42 #include "OS2Krnl.h" 35 43 #include "dev32.h" 44 #include "ldr.h" 45 #include "ldrCalls.h" 36 46 #include "ModuleBase.h" 37 47 #include "pe2lx.h" 38 #include "elf.h"39 #include "avl.h"40 #include "ldr.h"41 #include "ldrCalls.h"42 #include "options.h"43 48 #include "myExecPgm.h" 44 45 /******************************************************************************* 46 * Global Variables * 47 *******************************************************************************/ 48 extern BOOL fQAppType; /* From LDRQAppType */ 49 #include "env.h" 50 #include "vprintf.h" /* Make 100% sure we have va_start. */ 51 52 49 53 50 54 /******************************************************************************* 51 55 * Internal Functions * 52 56 *******************************************************************************/ 53 static unsigned getArgsLength(const char *pachArgs); 57 /* static */ APIRET AddArgsToFront(int cArgs, ...); 58 /* static */ APIRET SetExecName(const char *pszExeName); 59 /* static */ APIRET OpenPATH(PSFN phFile, char *pszFilename, PULONG pfl); 54 60 55 61 … … 59 65 * @param phFile Pointer to file handler. Holds filehandle on output. 60 66 * @param pszFilename Pointer to filename. 61 * @parma p aram3 Probablysome flags.67 * @parma pfl Pointer to some flags. 62 68 */ 63 ULONG LDRCALL myldrOpen(PSFN phFile, char *pszFilename, ULONG param3)69 ULONG LDRCALL myldrOpen(PSFN phFile, PSZ pszFilename, PULONG pfl) 64 70 { 65 ULONG rc; 66 67 /* 68 * Try open the file (thats why this function is called anyway) 71 static int cNesting = 0; /* This is an variable which hold the nesting */ 72 /* level of this function. This is useful */ 73 /* when we call it recurcively. */ 74 /* The maximum nesting level is currently 3. */ 75 /* When the maximum depth has been reached */ 76 /* we'll not intercept loading any longer! */ 77 ULONG rc; /* Return value. */ 78 79 /** @sketch 80 * Try open the file (that's why this function is called anyway) 69 81 */ 70 rc = ldrOpen(phFile, pszFilename, param3); 71 72 /* log sucesses */ 82 rc = ldrOpen(phFile, pszFilename, pfl); 73 83 if (rc == NO_ERROR) 74 kprintf(("ldrOpen: phFile=%#.4x, flags=%#.8x, pszFn=%s\n", *phFile, param3, pszFilename)); 75 76 /* 84 kprintf(("myldrOpen-%d: phFile=%#.4x, flags=%#.8x, pszFn=%s\n", cNesting, *phFile, pfl, pszFilename)); 85 86 87 /** @sketch 77 88 * Are we to intercept the loading? 78 * - Only if open were succesful and one of the loaders are enabled. 89 * - If open were successful. 90 * - And Not too deep nesting. 91 * - And that this isn't an unsupported load. 92 * - And one of the loaders are enabled. 79 93 */ 80 if (rc == NO_ERROR && (options.fElf || options.fPE != FLAGS_PE_NOT || options.fScript)) 81 { 82 char *pszBuffer = (char*)rmalloc(640); /* Read buffer. */ 83 PIMAGE_DOS_HEADER pMzHdr = (PIMAGE_DOS_HEADER)pszBuffer; /* Pointer to the buffer as it were a dosheader. */ 84 PIMAGE_NT_HEADERS pNtHdrs = (PIMAGE_NT_HEADERS)pszBuffer; /* Pointer to the buffer as if it were an NT header. */ 85 char *pach = pszBuffer; /* Finally an pointer to the buffer as if it were chars.. (which it is!) */ 86 PEXECPGMBUFFER pBuffer; /* Pointer to a buffer containing the programname and arguments. */ 87 /* For scripts and PE.EXE this has to be changed to have correct */ 88 /* parameters sendt in to the program. */ 89 unsigned cchRead = sizeof(IMAGE_DOS_HEADER); /* Amount of the buffer which contains valid data. */ 90 unsigned cbFile; /* Filesize (0xffffffff if call to SftFileSize failed - should _never_ happen though) */ 91 92 /* 93 * Verify that rmalloc completed successfully. 94 */ 95 if (pszBuffer == NULL) 94 if (rc == NO_ERROR 95 && cNesting < 3 96 && !isLdrStateLoadingUnsupported() 97 && isAnyLoaderEnabled() 98 ) 99 { 100 union _u_ReadBufferPointers /* Read buffer pointer(s). */ 96 101 { 97 kprintf(("ldrOpen: rmalloc(1024) failed\n")); 98 return NO_ERROR; 102 char *pach; /* Pointer to the buffer as char. */ 103 unsigned long *pul; /* Pointer to the buffer as unsigned long. */ 104 PIMAGE_DOS_HEADER pMzHdr; /* Use the buffer as a dosheader. */ 105 PIMAGE_NT_HEADERS pNtHdrs; /* Use the buffer as a NT header. */ 106 } u1; 107 unsigned cbFile; /* Filesize (0xffffffff if call to SftFileSize failed - should _never_ happen though) */ 108 unsigned cbRead; /* Amount of the buffer which contains valid data. */ 109 char * psz; /* Multipurpose string pointer no.1. */ 110 char * psz2; /* Multipurpose string pointer no.2. */ 111 char * psz3; /* Multipurpose string pointer no.3. */ 112 113 /** @sketch 114 * Allocate read buffer from resident heap. 115 * IF this fails THEN we'll simply return NO_ERROR. 116 */ 117 u1.pach = (char*)rmalloc(640); 118 if (u1.pach == NULL) 119 { 120 kprintf(("myldrOpen-%d: rmalloc(640) failed\n", cNesting)); 121 goto ret; 99 122 } 100 123 101 /* 102 * Try get the filesize 124 125 /** @sketch 126 * Increment nesting level. 127 */ 128 cNesting++; 129 130 131 /** @sketch 132 * Get the filesize. On failure filesize is set to ~0. 103 133 */ 104 134 rc = SftFileSize(*phFile, (PULONG)SSToDS(&cbFile)); 105 135 if (rc != NO_ERROR) 106 136 { 107 kprintf((" ldrOpen: SftFileSize failed with rc=%d\n", rc));137 kprintf(("myldrOpen-%d: SftFileSize failed with rc=%d\n", cNesting, rc)); 108 138 cbFile = (unsigned)~0; 109 139 } 110 140 111 /* 112 * See if this is an recognizable module format. 113 * This costs up to two disk reads! 114 */ 115 rc = ldrRead(*phFile, 0UL, pMzHdr, 0UL, cchRead, NULL); 116 if (rc == NO_ERROR) 141 142 /** @sketch 143 * Read the size of a DOS (ie. MZ) header. 144 * IF successful and more stuff in file THEN 145 * See if this is an recognizable module binary format: 146 */ 147 cbRead = min(sizeof(IMAGE_DOS_HEADER), cbFile); 148 rc = ldrRead(*phFile, 0UL, u1.pMzHdr, 0UL, cbRead, NULL); 149 if (rc == NO_ERROR && cbRead < cbFile) 117 150 { 118 /* 119 * PE header? 120 * - If DOS Magic is found AND a valid e_lfanew (offset of NE/LX/LE/PE header) is found 121 * - OR if PE siganture is found. 151 /** @sketch 152 * If LX header just give up at once. 122 153 */ 123 if ((pMzHdr->e_magic == IMAGE_DOS_SIGNATURE && 124 pMzHdr->e_lfanew > sizeof(IMAGE_DOS_HEADER) && pMzHdr->e_lfanew < 0x04000000UL) /* Larger than 64 bytes and less that 64MB. */ 125 || *(PULONG)pach == IMAGE_NT_SIGNATURE) 126 { /* 127 * MZ or PE header found 154 if (u1.pMzHdr->e_magic == E32MAGIC) 155 goto cleanup; 156 157 /** @sketch 158 * IF PE or MZ header THEN 159 */ 160 if (u1.pMzHdr->e_magic == IMAGE_DOS_SIGNATURE 161 || u1.pNtHdrs->Signature == IMAGE_NT_SIGNATURE) 162 { 163 ULONG offPe; /* Offset to PE header. */ 164 165 /** @sketch 166 * --- 167 * We now known that this is file has a MZ or a PE header. If it's 168 * a MZ header, we might end up with no "New" header or the "New" 169 * header might turn out to be a NE, LE, or LX header. I any of 170 * these non PE headers occur OS/2 will take care of it, we'll do nothing. 171 * --- 172 * IF PE loading is disable or MZ header and e_lfanew is invalid THEN 173 * return (successfully) to the caller. 174 * ENDIF 175 * (Find the offset of the PE header while testing (offPe).) 128 176 */ 129 130 /* if PE loading is diable return to the caller */131 if ( options.fPE == FLAGS_PE_NOT)177 if (isPELoaderDisabled()) 178 goto cleanup; 179 if (u1.pMzHdr->e_magic == IMAGE_DOS_SIGNATURE) 132 180 { 133 rfree(pszBuffer); 134 return NO_ERROR; 181 offPe = u1.pMzHdr->e_lfanew; 182 if (offPe < sizeof(IMAGE_DOS_HEADER) || offPe > 0x04000000UL) 183 goto cleanup; 135 184 } 136 137 /* 138 * Read the PE header if it isn't what we allready have! 185 else 186 offPe = 0; 187 188 189 /** @sketch 190 * Read the PE header. 191 * If the read failes or not PE signature, there isn't anything for us to do. 139 192 */ 140 cchRead = sizeof(IMAGE_NT_HEADERS); 141 if (*(PULONG)pach != IMAGE_NT_SIGNATURE) 142 rc = ldrRead(*phFile, pMzHdr->e_lfanew, pach, 0UL, cchRead, NULL); 143 else 144 rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL); 145 146 /* 147 * If successfully read, and a PE signature is present the continue and try load it! 148 * Else don't do anything, simply return NO_ERROR to the caller. (probably NE or LX exec) 193 rc = ldrRead(*phFile, offPe, u1.pach, 0UL, sizeof(IMAGE_NT_HEADERS), NULL); 194 if (rc != NO_ERROR || u1.pNtHdrs->Signature != IMAGE_NT_SIGNATURE) 195 goto cleanup_noerror; 196 197 198 /** @sketch 199 * PE signature found! 149 200 */ 150 if (rc == NO_ERROR && *(PULONG)pach == IMAGE_NT_SIGNATURE) 151 { /* 152 * PE signature found. 153 */ 154 kprintf(("ldrOpen: PE executable...\n")); 155 156 /* 157 * PE2LX? 158 * - When PE2LX flag is set 159 * - OR when the MIXED flag is set and the image is with the first 64MB of memory. 160 */ 161 if (options.fPE == FLAGS_PE_PE2LX 162 || (options.fPE == FLAGS_PE_MIXED 163 && !((pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL == 0UL) 164 && pNtHdrs->OptionalHeader.ImageBase >= 0x04000000UL /* 64MB */ 165 ) 201 kprintf(("myldrOpen-%d: PE executable...\n", cNesting)); 202 203 204 /** @sketch 205 * Use Pe2Lx? 206 * - When Pe2Lx flag is set 207 * - When the MIXED flag is set and the image isn't an executable 208 * above the first 64MB private limit without relocations 209 */ 210 if (isPe2LxLoaderEnabled() 211 || (isMixedPeLoaderEnabled() 212 && ((u1.pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL) 213 || !(u1.pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) 214 || u1.pNtHdrs->OptionalHeader.ImageBase < 0x04000000UL /* 64MB */ 166 215 ) 167 216 ) 168 { /* 169 * Pe2Lx (Ring0 of course) 170 * - Create a Pe2Lx class, 171 * - initiate it 172 * - Add the module to the module tree so we may find it later... 173 * - Set the handle state to 'our'. 174 */ 175 Pe2Lx * pPe2Lx = new Pe2Lx(*phFile); 176 if (pPe2Lx != NULL) 217 ) 218 { /** @sketch 219 * Pe2Lx (Ring0 of course) 220 * - Create a Pe2Lx class, 221 * - initiate it 222 * - Add the module to the module tree so we may find it later... 223 * - Set the (file)handle state to 'our'. 224 * - Set pExeModule to module pointer and loaderstate to our exe. 225 */ 226 Pe2Lx * pPe2Lx = new Pe2Lx(*phFile); 227 if (pPe2Lx != NULL) 228 { 229 rc = pPe2Lx->init(pszFilename); 230 if (rc == NO_ERROR) 177 231 { 178 rc = pPe2Lx->init(pszFilename); 232 kprintf(("myldrOpen-%d: Successfully init of Pe2Lx object.\n", cNesting)); 233 rc = addModule(*phFile, NULL, MOD_TYPE_PE2LX, pPe2Lx); 179 234 if (rc == NO_ERROR) 180 235 { 181 kprintf(("ldrOpen: Successfully init of Pe2Lx object.\n")); 182 rc = addModule(*phFile, NULL, MOD_TYPE_PE2LX, pPe2Lx); 183 if (rc == NO_ERROR) 184 #pragma info(notrd) 185 SetState(*phFile, HSTATE_OUR); 186 #pragma info(restore) 187 else 188 kprintf(("ldrOpen: Failed to add the module. rc=%d\n")); 236 #pragma info(notrd) 237 SetState(*phFile, HSTATE_OUR); 238 #pragma info(restore) 239 if (pPe2Lx->isExe()) 240 { 241 setLdrStateLoadingOurEXE(); 242 pExeModule = getModuleBySFN(*phFile); 243 #ifdef DEBUG 244 if (pExeModule == NULL) 245 kprintf(("myldrOpen-%d: getModuleBySFN failed when setting pExeModule! FATAL!\n", cNesting)); 246 #endif 247 } 189 248 } 190 249 else 191 kprintf(("ldrOpen: Failed to init Pe2Lx object. rc=%d\n")); 192 if (rc != NO_ERROR) 193 delete pPe2Lx; 250 kprintf(("myldrOpen-%d: Failed to add the module. rc=%d\n", cNesting)); 194 251 } 195 252 else 196 kprintf(("ldrOpen: Failed to allocate Pe2Lx object.\n")); 253 kprintf(("myldrOpen-%d: Failed to init Pe2Lx object. rc=%d\n", cNesting)); 254 if (rc != NO_ERROR) 255 delete pPe2Lx; 197 256 } 198 257 else 199 258 { 200 /* 201 * Starting of PE.EXE enable? 259 kprintf(("myldrOpen-%d: Failed to allocate Pe2Lx object.\n", cNesting)); 260 rc = ERROR_NOT_ENOUGH_MEMORY; 261 } 262 263 goto cleanup; 264 } 265 266 267 /** @sketch 268 * Using PE.EXE to start EXE? 269 * - When the file is an EXE file and PE.EXE is enabled. 270 */ 271 if ((u1.pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL) == 0UL 272 && (options.fPE == FLAGS_PE_PE || options.fPE == FLAGS_PE_MIXED) 273 && (isLdrStateExecPgm() || isLdrStateQAppType()) 274 ) 275 { 276 /** @sketch 277 * PE.EXE: 278 * Find pe.exe - look in current directory and thru the PATH. 279 * Note! We use the read buffer (u1.p*) as a storage for the 280 * pe.exe filename and path. 281 */ 282 kprintf(("myldrOpen-%d: pe.exe - opening\n", cNesting)); 283 ldrClose(*phFile); 284 strcpy(u1.pach, "PE.EXE"); 285 rc = ldrOpen(phFile, u1.pach, pfl); /* This isn't recusive! */ 286 if (rc != NO_ERROR) 287 rc = OpenPATH(phFile, u1.pach, pfl); 288 if (rc == NO_ERROR) 289 { 290 /** @sketch 291 * If we're in tkExecPgm state we'll have to shuffle the parameters 292 * and executable filename tkExecPgm were called with. 293 * If not tkExecPgm we can't do anything about parameters (and there is 294 * probably nothing to do either). 202 295 */ 203 if (options.fPE == FLAGS_PE_PE || options.fPE == FLAGS_PE_MIXED) 204 { /* 205 * pe.exe - need the path! 206 */ 207 kprintf(("ldrOpen: pe.exe - opening\n")); 208 ldrClose(*phFile); 209 rc = ldrOpen(phFile, "pe.exe", param3); /* path....! problems! */ 210 kprintf(("ldrOpen: pe.exe - open returned with rc = %d\n", rc)); 211 rfree(pszBuffer); 212 return rc; 296 kprintf(("myldrOpen-%d: pe.exe - %s\n", cNesting, u1.pach)); 297 if (isLdrStateExecPgm() && fTkExecPgm) 298 { 299 rc = AddArgsToFront(2, ldrpFileNameBuf, achTkExecPgmFilename); 300 if (rc == NO_ERROR) 301 { 302 rc = SetExecName(ldrpFileNameBuf); 303 if (rc != NO_ERROR) 304 kprintf(("myldrOpen-%d: pe.exe - failed to set pe.exe as execname. rc=%d\n", cNesting)); 305 } 306 else 307 kprintf(("myldrOpen-%d: pe.exe - failed to add programname as argument. rc=%d\n", cNesting, rc)); 308 goto cleanup_noerror; 213 309 } 214 310 } 311 else 312 kprintf(("myldrOpen-%d: pe.exe - couldn't find/open pe.exe\n", cNesting)); 215 313 } 216 rfree(pszBuffer); 217 return NO_ERROR; 314 goto cleanup; 218 315 } 219 else 316 /** @sketch End of PE Loading. */ 317 318 319 /** @sketch 320 * ELF image? 321 */ 322 if (*u1.pul == ELFMAGICLSB) 220 323 { 324 if (isELFDisabled()) 325 goto cleanup_noerror; 326 221 327 /* 222 * ELF image?328 * ELF signature found. 223 329 */ 224 if (pach[0] == ELFMAG0 && pach[1] == ELFMAG1 && pach[2] == ELFMAG2 && pach[3] == ELFMAG3) 330 kprintf(("myldrOpen-%d: ELF image! - not implemented yet!\n", cNesting)); 331 332 /* 333 * Do nothing more yet. NEED AN ELF LOADER!!! 334 */ 335 goto cleanup; 336 } 337 338 339 /** @sketch 340 * Java image? 341 */ 342 if (*u1.pul == 0xBEBAFECAUL) //CAh FEh BAh BEh 343 { 344 char *pszName = NULL; 345 int cchName; 346 347 if (isJAVADisabled()) 348 goto cleanup_noerror; 349 350 /** @sketch 351 * Java signature found. 352 * Copy the name to a temporary buffer. (only if necessary) 353 * Remove the extention (.class) and insert a space between the name and the path. 354 * (This is the needed processing of the class filename to make it a classpath 355 * entry (path) and a class name (filename).) 356 * Try find the java executor in current dir or PATH: java.exe 357 */ 358 kprintf(("myldrOpen-%d: Jave image!\n", cNesting)); 359 360 if (isLdrStateExecPgm() && fTkExecPgm) 225 361 { 226 /* 227 * ELF signature found. 362 /* Ooops we had to get the file name from the MFT. ldrpFileNameBuf is allways uppercased... */ 363 /* MFT seems to hold uppercased filenames! ARG! But (by pure luck?) achTkExecPgmArguments is 364 * not uppercased (yet). Nothing could be simpler! 228 365 */ 229 kprintf(("ldrOpen: ELF executable! - not implemented yet!\n")); 230 231 /* 232 * Do nothing more yet. NEED AN ELF LOADER!!! 366 #if 1 367 psz3 = achTkExecPgmArguments; 368 #elif 0 369 psz3 = SecPathFromSFN(*phFile); 370 if (psz3 == NULL) 371 psz3 = ldrpFileNameBuf; 372 #else 373 psz3 = ldrpFileNameBuf; 374 #endif 375 cchName = strlen(psz3); 376 pszName = (char*)rmalloc(cchName + 2); 377 if (pszName == NULL) 378 { 379 rc = ERROR_NOT_ENOUGH_MEMORY; 380 goto cleanup; 381 } 382 memcpy(pszName, psz3, cchName+1); 383 384 psz = pszName + strlen(pszName) - 1; 385 while (psz > pszName && *psz != '.' && *psz != '\\' && *psz != '/') 386 psz--; 387 if (*psz == '.') 388 { 389 cchName = psz - pszName; 390 *psz-- = '\0'; 391 while (psz > pszName && *psz != '\\' && *psz != '/') 392 psz--; 393 394 /* check for root and evt. make room for an extra slash. */ 395 if (psz - pszName == 2) 396 { 397 memmove(psz + 1, psz, cchName - 1); 398 *psz++ = '\\'; 399 } 400 } 401 /* check if no path */ 402 if (psz == pszName) 403 memmove(pszName + 1, pszName, cchName + 1); 404 *psz = ' '; 405 } 406 407 ldrClose(*phFile); 408 rc = ldrOpen(phFile, ".\\JAVA.EXE", pfl); 409 if (rc != NO_ERROR) 410 rc = OpenPATH(phFile, "JAVA.EXE", pfl); 411 if (rc == NO_ERROR) 412 { 413 kprintf(("myldrOpen-%d: java - %s\n", cNesting, ldrpFileNameBuf)); 414 415 /** @sketch 416 * To be able to execute any given class name we'll have to pass in the 417 * directory as -classpath. But -classpath seems to override the default 418 * and environmental CLASSPATHs. So, we'll have to pass in the value of 419 * the CLASSPATH env.var. or generate the default class path (what ever that is). 420 * 233 421 */ 234 rfree(pszBuffer); 235 return NO_ERROR; 422 if (isLdrStateExecPgm() && fTkExecPgm) 423 { 424 psz = u1.pach; 425 426 /* 427 * Get classpath and add it as a parameter 428 */ 429 strcpy(u1.pach, "-classpath "); 430 psz = u1.pach + strlen(u1.pach); 431 432 psz3 = (char*)ScanEnv(GetEnv(TRUE), "CLASSPATH"); 433 if (psz3 != NULL) 434 { /* environment variable set */ 435 if (strlen(psz3) > 640 - 11 - 1 - cchName) //check for overflow 436 { // TODO? should reallocate... 437 memcpy(psz, psz3, 640 - 11 - 1 - cchName); 438 psz[640 - 11 - 1 - cchName] = '\0'; 439 } 440 else 441 strcpy(psz, psz3); 442 psz += strlen(psz); 443 } 444 else 445 { 446 /* Make default classpath by taking the java.exe path + '..\lib\classes.zip' */ 447 strcpy(psz, ldrpFileNameBuf); 448 psz3 = psz + strlen(psz) - 1; 449 while (psz3 > psz && *psz3 != '\\' && *psz3 != '/') 450 psz3--; 451 strcpy(++psz3, "..\\lib\\classes.zip"); 452 psz = psz3 + strlen(psz3); 453 } 454 455 /* 456 * Add the class directory (as the last classpath entry) and the class name. 457 * (Note. I may happen that there is no directory, but that don't matter 458 * a space is allways preceding the class name.) 459 */ 460 *psz++ = ';'; 461 strcpy(psz, pszName); 462 if (pszName != NULL) 463 rfree(pszName); 464 465 /* 466 * Setup JAVA.EXE as executable with the parameters we've build. 467 */ 468 rc = AddArgsToFront(2, ldrpFileNameBuf, u1.pach); 469 kprintf(("myldrOpen-%d: java - Exe: %s Args: %s\n", cNesting, ldrpFileNameBuf, u1.pach)); 470 if (rc == NO_ERROR) 471 { 472 rc = SetExecName(ldrpFileNameBuf); 473 if (rc != NO_ERROR) 474 kprintf(("myldrOpen-%d: java - failed to set java.exe as execname. rc=%d\n", cNesting, rc)); 475 } 476 else 477 kprintf(("myldrOpen-%d: java - failed to setup the parameters. rc=%d\n", cNesting, rc)); 478 479 goto cleanup_noerror; 480 } 236 481 } 482 else 483 kprintf(("myldrOpen-%d: java - couldn't find/open java.exe\n", cNesting)); 484 485 486 /** @sketch 487 * End of Java loading. (return) 488 */ 489 if (pszName != NULL) 490 rfree(pszName); 491 goto cleanup; 237 492 } 493 238 494 } 495 else 496 { 497 /** @sketch 498 * ELSE - the reading size of a DOS header failed or file is smaller than the dos header. 499 * IF read failed or filesize is less than 4 bytes THEN 500 * return no_error to the caller. 501 * ENDIF 502 */ 503 #ifdef DEBUG 504 if (rc != NO_ERROR) 505 { 506 kprintf(("myldrOpen-%d: ldrRead failed cbRead=%d, cbFile=%d, rc=%d\n", cNesting, cbRead, cbFile, rc)); 507 goto cleanup_noerror; 508 } 509 if (cbRead < 4) 510 { 511 kprintf(("myldrOpen-%d: File too small! cbFile=%d\n", cNesting, cbFile)); 512 goto cleanup_noerror; 513 } 514 #else 515 if (rc != NO_ERROR || cbRead < 4) //just forget files less than 4 bytes! 516 goto cleanup_noerror; 517 #endif 518 } 519 /** @sketch ENDIF (dos header read) */ 520 521 239 522 240 523 /* 241 * Only unreconized files and readerrorpasses this point!524 * Only unreconized files passes this point! 242 525 * 243 526 * * Fileformats with lower priority should reside here. * … … 245 528 */ 246 529 247 /* 248 * If the initial readoperation failed try to read a smaller amount, in case it is a small script... 249 * 4 bytes is a small amount isn't it? 250 */ 251 if (rc != NO_ERROR) 530 /** @sketch 531 * UNIX styled script? 532 * - Starts with a hash (#) 533 * - And we're loading an EXE 534 * - And we're either in QAppType or ExecPgm state. 535 * - And that a bang (!) is the first char after the hash (ignoring blanks). 536 */ 537 if (*u1.pach == '#' 538 && isLdrStateLoadingEXE() 539 && (isLdrStateQAppType() || isLdrStateExecPgm()) 540 ) 252 541 { 253 kprintf(("ldrOpen: first ldrread failed with rc=%d. tries to read 4 byte.\n", rc)); 254 cchRead = 4; 255 if ((rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL)) != NO_ERROR) 256 kprintf(("ldrOpen: second ldrread failed with rc=%d.\n ", rc)); 257 } 258 259 /* 260 * Now we'll try again, UNIX styled script? 261 */ 262 if (rc == NO_ERROR && *pach == '#' && pach[1] == '!') 263 { 542 if (isUNIXScriptDisabled()) 543 goto cleanup_noerror; 264 544 /* 265 * UNIX styled script? 266 * FIXME! Must be more than 64 bytes long? 267 * No options! 268 * Firstline < 64 bytes! 545 * Look for a bang (!). Tabs and spaces are skipped, anything else result in error. 269 546 */ 270 kprintf(("ldrOpen: unix script?\n"));271 cchRead = min(cbFile, 256);272 rc = ldrRead(*phFile, 0UL, pach, 0UL, cchRead, NULL);273 if ( rc == NO_ERROR)547 psz = u1.pach + 1; 548 while ((*psz == ' ' || *psz == '\t') && psz - u1.pach < cbRead) 549 psz++; 550 if (*psz == '!') 274 551 { 275 char *pszStart = pach+2; 276 kprintf(("ldrOpen: script debug 1\n")); 277 278 /* Make sure we don't read to much... */ 279 pszBuffer[cchRead] = '\0'; 280 281 /* 282 * Skip blanks 552 /** @sketch Found UNIX styled script! */ 553 554 /** @sketch 555 * Read more of the script if necessary. (max is 256 chars (- Linux max is 127)) 556 * Terminate the string read from the file to make sure with stop somewhere! 283 557 */ 284 pszStart = pszBuffer + 2; /* skips the "#!" stuff. */ 285 while (*pszStart != '\0' && (*pszStart == ' ' || *pszStart == '\t')) 286 pszStart++; 287 kprintf(("ldrOpen: script debug 2\n")); 288 289 /* anything left on the line? */ 290 if (*pszStart != '\0' && *pszStart != '\r' && *pszStart != '\n') 558 if (cbRead < cbFile /*&& cbRead != 256*/) 291 559 { 292 char * pszEnd; /* Pointer to the end of the string(s) when the next step is finished. */ 293 unsigned cchToAdd = 1; /* Chars to add */ 294 BOOL fFirst = TRUE; /* Set if a '\0' has not been set yet. 295 * If this is clear, there are one or more parameters after the interpreter name. */ 296 297 /* 298 * find linesize and make parameters ready for copying 560 cbRead = min(256, cbFile); 561 rc = ldrRead(*phFile, 0UL, u1.pach, 0UL, cbRead, NULL); 562 } 563 u1.pach[cbRead] = '\0'; 564 565 if (rc == NO_ERROR) 566 { 567 /** @sketch 568 * Parse out filename and optional arguments (if any). 569 * The result of the parsing is that: 570 * psz will point at the executable name. 571 * psz2 will point at the arguments. 572 * Both strings are trimmed. 299 573 */ 300 pszEnd = pszStart; 301 kprintf(("ldrOpen: script debug 3\n")); 302 while (*pszEnd != '\0' && *pszEnd != '\r' && *pszEnd != '\n') 574 psz++; /* psz points to the bang, skip it. */ 575 while (*psz == ' ' || *psz == '\t') /* skip blanks after bang */ 576 psz++; 577 if (*psz == '\r' || *psz == '\n' || *psz == '\0') /* End-of-line? */ 303 578 { 304 if (fFirst && (*pszEnd == ' ' || *pszEnd == '\t')) 579 kprintf(("myldrOpen-%d: script no executable name.\n", cNesting)); 580 goto cleanup_noerror; /* other error code? */ 581 } 582 psz2 = psz + 1; /* Not end-of-line, so add 1 before searching for args. */ 583 while (*psz2 != '\0' && *psz2 != '\n' && *psz2 != '\r' /* skip executable name. */ 584 && *psz2 != ' ' && *psz2 != '\t') 585 psz2++; 586 while (*psz2 == ' ' || *psz2 == '\t') /* skip blanks after executable - pad them with '\0'! */ 587 *psz2++ = '\0'; 588 589 psz3 = psz2; 590 while (*psz3 != '\n' && *psz3 != '\r' && *psz3 != '\0') /* find end of parameters and terminate the string. */ 591 psz3++; 592 *psz3 = '\0'; 593 while (psz3 >= psz2 && (*psz3 == '\0' || *psz3 == ' ' || *psz3 == '\t')) /* trim args */ 594 *psz3-- = '\0'; 595 596 597 /** @sketch 598 * IF tkExecPgm THEN 599 * Correct parameters - ie. add exec name (as argv[0]), 600 * arguments (psz2) as argv[1+], old exec name, and finally 601 * the existing parameters (current argv[1+]). 602 * Set the executable name. 603 * ENDIF 604 * Open the new executable file recursively. (psz) 605 */ 606 if (isLdrStateExecPgm()) 607 { 608 if (*psz2) 609 rc = AddArgsToFront(3, psz, psz2, achTkExecPgmFilename); 610 else 611 rc = AddArgsToFront(2, psz, achTkExecPgmFilename); 612 if (rc != NO_ERROR) 305 613 { 306 *pszEnd = '\0'; 307 fFirst = FALSE; 308 if (pszEnd[1] == '\0' || pszEnd[1] == '\r' || pszEnd[1] == '\n') 309 fFirst = TRUE; 614 kprintf(("myldrOpen-%d: AddArgsToFront failed with rc=%d\n", cNesting)); 615 goto cleanup_noerror; 310 616 } 311 312 /* next */ 313 pszEnd++; 314 cchToAdd++; 617 rc = SetExecName(psz); 618 if (rc != NO_ERROR) 619 kprintf(("myldrOpen-%d: SetExecName failed with rc=%d\n", cNesting)); 315 620 } 316 *pszEnd = '\0'; 317 kprintf(("ldrOpen: script debug 4\n")); 318 319 /* 320 * If ldrQueryApp type we don't have any ExecPgm buffer we need to mess with. 321 * We'll simply try open the the interpreter. 322 */ 323 if (fQAppType) 621 ldrClose(*phFile); 622 rc = myldrOpen(phFile, psz, pfl); 623 if (rc != NO_ERROR) 324 624 { 325 rc = ldrClose(*phFile); 326 rc = ldrOpen(phFile, pszStart, param3); /* FIXME, recusion! check that name not equal! Use flags to prevent race? */ 327 } 328 else 329 { 330 /* 331 * Find the ExecPgm buffer. 332 */ 333 pBuffer = QueryBufferPointerFromFilename(pszFilename); 334 kprintf(("ldrOpen: script debug 5\n")); 335 if (pBuffer != NULL) 625 psz2 = psz + strlen(psz); 626 if (psz + 4 >= psz2 || strcmp(psz2 - 4, ".EXE") != 0) 336 627 { 337 unsigned cchArguments = getArgsLength(pBuffer->achArgs); /* minus the first argument. */ 338 unsigned cchScriptnameDelta = strlen(pBuffer->szFilename) - strlen(pBuffer->achArgs); /* scriptname size difference. */ 339 340 kprintf(("ldrOpen: script debug 6\n")); 341 342 /* 343 * Is there enough space in the struct? 344 */ 345 if (cchArguments + cchToAdd + cchScriptnameDelta < sizeof(pBuffer->achArgs)) 346 { 347 kprintf(("ldrOpen: script debug 7\n")); 348 /* 349 * Open the interpreter. 350 */ 351 rc = ldrClose(*phFile); 352 rc = ldrOpen(phFile, pszStart, param3); /* FIXME, recusion! check that name not equal! Use flags to prevent race? */ 353 if (rc == NO_ERROR) 354 { 355 kprintf(("ldrOpen: script debug 8\n")); 356 /* Make space for the addition arguments. */ 357 #ifdef DEBUG 358 char *psz = &pBuffer->achArgs[0]; 359 int i = 0; 360 while (*psz != '\0') 361 { 362 kprintf(("Arg %d: %s\n", i++, psz)); 363 psz += 1 + strlen(psz); 364 } 365 #endif 366 memmove(&pBuffer->achArgs[cchToAdd + cchScriptnameDelta], 367 &pBuffer->achArgs[0], cchArguments); 368 369 /* 370 * Copy the arguments. 371 */ 372 kprintf(("ldrOpen: script debug 8\n")); 373 memcpy(&pBuffer->achArgs[0], pszStart, cchToAdd); /* Interpreter with arguments */ 374 if (!fFirst) 375 pBuffer->achArgs[cchToAdd - 1] = ' '; 376 strcpy(&pBuffer->achArgs[cchToAdd], pszFilename); /* Scriptname */ 377 kprintf(("ldrOpen: script debug a\n")); 378 379 #ifdef DEBUG 380 psz = &pBuffer->achArgs[0]; 381 i = 0; 382 while (*psz != '\0') 383 { 384 kprintf(("Arg %d: %s\n", i++, psz)); 385 psz += 1 + strlen(psz); 386 } 387 #endif 388 } 389 else 390 kprintf(("ldrOpen: failed to open interpreter (%s), rc=%d\n", pszStart, rc)); 391 } 392 else 393 { 394 kprintf(("ldrOpen: Argument buffer too small, %d\n", cchArguments + cchToAdd)); 395 rc = ERROR_BAD_EXE_FORMAT; 396 } 628 strcpy(psz2, ".EXE"); 629 rc = myldrOpen(phFile, psz, pfl); 630 *psz2 = '\0'; 397 631 } 398 632 else 633 psz2 = NULL; 634 635 //should we search the PATH??? For a starting, we'll do it. 636 if (rc != NO_ERROR 637 && (rc = OpenPATH(phFile, psz, pfl)) != NO_ERROR 638 && psz2 != NULL) 399 639 { 400 kprintf(("ldrOpen: QueryBufferPointerFromFilename failed.\n"));401 rc = ERROR_BAD_EXE_FORMAT; /*?*/640 *psz2 = '.'; 641 rc = OpenPATH(phFile, psz, pfl); 402 642 } 403 643 } … … 405 645 else 406 646 { 407 kprintf((" ldrOpen: no interpereter on the first line.\n"));408 rc = ERROR_BAD_EXE_FORMAT; /*?*/647 kprintf(("myldrOpen-%d: script - failed to read more of the script!, rc=%d cbRead=%d cbFile=%d.\n", 648 cNesting, rc, cbRead, cbFile)); 409 649 } 650 651 goto cleanup; 410 652 } 411 653 else 412 654 { 413 kprintf((" ldrOpen: read of min(cbFile, 256) = %d failed, rc = %d\n", cchRead, rc));655 kprintf(("myldrOpen-%d: script - hash found but no bang (!).\n", cNesting)); 414 656 } 415 } /* else inn other formats here. */ 416 rfree(pszBuffer); 417 } 657 } /**@sketch ENDIF - UNIX styled script. */ 658 659 660 661 /** @sketch 662 * REXX script? 663 * - Starts with a REXX start comment ('/','*') 664 * - And we're loading an EXE 665 * - And we're either in QAppType or ExecPgm state. 666 * - Extention: 667 * .RX and .REX are known to be pure REXX scripts. 668 * While .CMD has to invoked used the commandline OS2_SHELL or COMSPEC variable. 669 */ 670 psz2 = pszFilename + strlen(pszFilename) - 1; 671 while (psz2 > pszFilename && *psz2 != '.') 672 psz2--; 673 if (*psz2 == '.' 674 && *u1.pach == '/' && u1.pach[1] == '*' 675 && isLdrStateLoadingEXE() 676 && (isLdrStateQAppType() || isLdrStateExecPgm()) 677 && (stricmp(psz2, ".RX") == 0 || stricmp(psz2, ".REX") == 0) 678 ) 679 { 680 if (isREXXScriptDisabled()) 681 goto cleanup_noerror; 682 683 /** @sketch 684 * Found REXX styled script! 685 * Find the REXX interpreter. We'll use kRx.exe to execute the REXX scripts. 686 * (This interpreter could be embedded as a child of ModuleBase as it turned out 687 * to be quite small about 700 bytes.) 688 */ 689 kprintf(("myldrOpen-%d: Found REXX script\n", cNesting)); 690 ldrClose(*phFile); 691 psz = "KRX.EXE"; 692 rc = ldrOpen(phFile, psz, pfl); 693 if (rc != NO_ERROR) 694 rc = OpenPATH(phFile, psz, pfl); 695 696 /** @sketch 697 * IF tkExecPgm THEN 698 * Correct parameters - ie. add exec name (as argv[0]), old exec name, 699 * and finally the existing parameters (current argv[1+]). 700 * Set the executable name. 701 * ENDIF 702 */ 703 if (rc == NO_ERROR && isLdrStateExecPgm()) 704 { 705 rc = AddArgsToFront(2, ldrpFileNameBuf, achTkExecPgmFilename); 706 if (rc != NO_ERROR) 707 { 708 kprintf(("myldrOpen-%d: AddArgsToFront failed with rc=%d\n", cNesting)); 709 goto cleanup_noerror; 710 } 711 rc = SetExecName(ldrpFileNameBuf); 712 if (rc != NO_ERROR) 713 kprintf(("myldrOpen-%d: SetExecName failed with rc=%d\n", cNesting)); 714 715 goto cleanup_noerror; 716 } 717 goto cleanup; 718 } /**@sketch ENDIF - REXX styled script. */ 719 720 721 /* 722 * Cleanup with rc set to NO_ERROR. 723 */ 724 cleanup_noerror: 725 rc = NO_ERROR; 726 727 /* 728 * Cleanup without having rc set to NO_ERROR. 729 * Decrement the nesting count. 730 */ 731 cleanup: 732 rfree(u1.pach); 733 cNesting--; 734 } 735 #ifdef DEBUG 736 else if (cNesting >= 3) 737 kprintf(("myldrOpen-%d: cNesting = %d, which is too deep!\n", cNesting, cNesting)); 738 #endif 739 740 ret: 741 /** @sketch 742 * Return rc. 743 */ 418 744 return rc; 419 745 } … … 421 747 422 748 /** 423 * Get the lenght of the arguments. 424 * @returns Lenght in char, includes the two '\0's. 425 * @param pachArgs Pointer to the ASCIIZs which makes up the arguments. 426 * @status completely implemented. 749 * Adds new arguments to the front of the startup arguments for the program about to be 750 * executed. 751 * 752 * @returns OS/2 return code. 753 * @param cArgs Count of arguments to add. At least 1!!! 754 * @param ... Pointers to the arguments to add. 755 * The first argument have to be the executable name. This have to the 756 * the only argument in the first string. 757 * The other arguements are space separated, so you could add a bunch 758 * of arguments in a single string! 759 * The last argument should be the old first parameter if this is to be 760 * preserved. The old first parameter is overwritten since it's 761 * normally the executable name. 762 * 763 * @status completly implemented. 427 764 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 765 * @remark Implementation note: 766 * The arguments convention is as follows: 767 * First argument, which should be the executable name, is terminated with a '\0'. 768 * It starts at offset 0 into the argument buffer, of course. 769 * All other arguemnts are separated by a space and follows the immediately after the 770 * first argument. 771 * The arguments are terminated by a double nulltermination: '\0\0'. 428 772 */ 429 static unsigned getArgsLength(const char *pachArgs)773 APIRET AddArgsToFront(int cArgs, ...) 430 774 { 431 unsigned cch = 1; 432 const char *psz = pachArgs; 433 775 va_list vaarg; /* Variable length argument list. */ 776 int cchOldArgs; /* Length of the old arguments (including the first argument). */ 777 /* cchOldArgs = 1 means no arguments. It don't include the very last '\0' */ 778 /* (remember argumets are terminated with two '\0's). */ 779 int iSecondArg; /* Index of the second argument. (Used to skip the first argument.) */ 780 /* Used first on the original arguments and them when adding the first */ 781 /* new argument. */ 782 int cchNewArgs; /* Length of the new arguments to be inserted. */ 783 int i; /* Loop variable. Current function argument. */ 784 char * psz; /* General string pointer. */ 785 786 787 /** @sketch 788 * Assert that we're in the right state. 789 * Calc the length of the existing parameters. 790 * Calc the length of the new arguments to determin. 791 * Assert that the new arguments have length > 0. 792 */ 793 #ifdef DEBUG 794 if (!isLdrStateExecPgm()) 795 { 796 kprintf(("AddArgsToFront: not in tkExecPgm state.\n")); 797 return ERROR_INVALID_PARAMETER; 798 } 799 #endif 800 if (!fTkExecPgm) 801 { 802 kprintf(("AddArgsToFront: called when not in tkExecPgm data is invalid!\n")); 803 return ERROR_INVALID_PARAMETER; 804 } 805 806 iSecondArg = strlen(&achTkExecPgmArguments[0]) + 1; 807 psz = &achTkExecPgmArguments[iSecondArg]; 434 808 while (*psz != '\0') 435 { 436 register unsigned cch2 = strlen(psz); 437 cch += cch2; 438 psz += cch2 + 1; 439 } 440 441 return cch; 809 psz += strlen(psz) + 1; 810 cchOldArgs = psz - &achTkExecPgmArguments[iSecondArg]; 811 812 va_start(vaarg, cArgs); 813 for (cchNewArgs = i = 0; i < cArgs; i++) 814 cchNewArgs += strlen(va_arg(vaarg, char *)) + 1; /* 1 is for space or '\0'. */ 815 va_end(vaarg); 816 #ifdef DEBUG 817 if (cchNewArgs == 0) 818 { 819 kprintf(("AddArgsToFront: the size of the arguments to add is zero!\n")); 820 return ERROR_INVALID_PARAMETER; 821 } 822 #endif 823 824 825 /** @sketch 826 * Check if we have enough room for the new arguments. Fail if not enough. 827 * Move the existing arguments to make room for the new ones. 828 * !IMPORTANT! The first existing arguments (executable name) is skipped !IMPORTANT! 829 * !IMPORTANT! in this move as this have to be re-added in this call! !IMPORTANT! 830 */ 831 if (cchOldArgs + cchNewArgs + 1 > CCHARGUMENTS) 832 { 833 kprintf(("AddArgsToFront: argument buffer is too small to hold the arguments to add, cchOldArgs=%d, cchNewArgs=%d\n", 834 cchOldArgs, cchNewArgs)); 835 return ERROR_BAD_ARGUMENTS; 836 } 837 838 if (cchOldArgs > 0) 839 { 840 memmove(&achTkExecPgmArguments[cchNewArgs], &achTkExecPgmArguments[iSecondArg], 841 cchOldArgs + 1); 842 } 843 else 844 achTkExecPgmArguments[cchNewArgs] = '\0'; 845 846 847 /** @sketch 848 * Copy new arguments. 849 * Since the first argument is special case we'll do it separately. (Uses '\0' as separator.) 850 * We assume that the entire first argument passed into this function should be the first argument! 851 * (This don't have to be true for the other arguments since these are space separated. You could 852 * pass in more than argument in a single string.) 853 * Loop thru the rest of the new arguments and add them with space as separator. 854 */ 855 va_start(vaarg, cArgs); 856 psz = va_arg(vaarg, char *); 857 memcpy(&achTkExecPgmArguments[0], psz, (i = strlen(psz) + 1)); 858 psz = &achTkExecPgmArguments[i]; 859 860 for (i = 1; i < cArgs; i++) 861 { 862 if (i > 1) *psz++ = ' '; //Add space if not second argument. 863 strcpy(psz, va_arg(vaarg, char *)); 864 psz += strlen(psz); 865 } 866 va_end(vaarg); 867 if (cchOldArgs > 0) *psz++ = ' '; //Add space if old arguments 868 869 #ifdef DEBUG /* assertion */ 870 if (psz != &achTkExecPgmArguments[cchNewArgs]) 871 { 872 kprintf(("AddArgsToFront: !Assertion failed! psz didn't end up where it should! (psz -> %d should be %d)\n", 873 psz - &achTkExecPgmArguments[0], cchNewArgs)); 874 if (cchOldArgs <= 1) 875 psz[0] = psz[1] = '\0'; 876 } 877 #endif 878 879 return NO_ERROR; 442 880 } 881 882 883 /** 884 * Sets the executable name of the module. 885 * This function is normally invoked after a different executable than the one requested was 886 * opened. It does _NOT_ set the new executable name as the first argument, since it is more 887 * convenient to this while calling AddArgsToFront to add other arguments. 888 * 889 * @returns OS/2 return code. 890 * @param pszExecName Pointer to new executable name. 891 * @status completly implemented. 892 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 893 * @remark . 894 */ 895 APIRET SetExecName(const char *pszExecName) 896 { 897 #ifdef DEBUG 898 int cch; 899 cch = strlen(pszExecName); 900 if (cch > CCHMAXPATH) 901 { 902 kprintf(("ChangeExecName: filename is too long! cch=%d. name=%s\n", cch, pszExecName)); 903 return ERROR_FILENAME_EXCED_RANGE; 904 } 905 if (!isLdrStateExecPgm()) 906 { 907 kprintf(("ChangeExecName: called when not in tkExecPgm state!!! FATAL ERROR!\n")); 908 return ERROR_INVALID_PARAMETER; 909 } 910 #endif 911 if (!fTkExecPgm) 912 { 913 kprintf(("ChangeExecName: called when not in tkExecPgm data is invalid!!! FATAL ERROR!\n")); 914 return ERROR_INVALID_PARAMETER; 915 } 916 917 strcpy(achTkExecPgmFilename, pszExecName); 918 919 return 0; 920 } 921 922 923 /** 924 * Opens a file using the PATH environment variable of the current process. 925 * @returns OS2 return code. 926 * @param phFile Pointer to filehandle. The filehandle is set to the SFN for the opened 927 * file on successful return. 928 * The filehandle is 0 on failure. 929 * @param pszFilename Pointer to filename buffer. This will hold the filename on input. 930 * On successful return it holds the filepath found. 931 * On failiure it's undefined. 932 * @param pfl Some flags set by ldrOpen. 933 * @sketch stub 934 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 935 * @remark 936 */ 937 APIRET OpenPATH(PSFN phFile, char *pszFilename, PULONG pfl) 938 { 939 APIRET rc; 940 USHORT TCBFailErr_save; 941 int cchFile; /* Filename length + 1. */ 942 const char *pszFile; /* Pointer to filename portion. */ 943 const char *pszPath = ScanEnv(GetEnv(FALSE), "PATH"); /* Current Process environment? */ 944 945 /**@sketch 946 * No PATH environment. 947 */ 948 if (pszPath == NULL) 949 return ERROR_FILE_NOT_FOUND; 950 951 /**@sketch 952 * Skip any paths in the filename. 953 */ 954 pszFile = pszFilename + (cchFile = strlen(pszFilename)); 955 while (pszFile >= pszFilename && *pszFile != '\\' && *pszFile != '/') 956 pszFile--; 957 cchFile -= pszFile - pszFilename; 958 pszFile++; 959 960 /**@sketch 961 * We'll have to save the TCBFailErr since we don't want to cause 962 * Hard Errors while searching invalid paths, etc. (ldrOpenPath does this!) 963 */ 964 TCBFailErr_save = tcbGetTCBFailErr(tcbGetCur()); 965 966 /**@ sketch 967 * Loop thru the PATH trying to open the specified file in each 968 * directory. 969 */ 970 while (*pszPath != '\0') 971 { 972 const char * pszNext; 973 int cchPath; 974 char chEnd; 975 register char ch; 976 977 /* 978 * Find end of this path. 979 */ 980 while (*pszPath == ' ') pszPath++; //skip leading spaces. 981 if (*pszPath == '"') 982 { 983 chEnd = '"'; 984 pszPath++; 985 } 986 else 987 chEnd = ';'; 988 pszNext = pszPath; 989 while ((ch = *pszNext) != chEnd && ch != '\0') 990 pszNext++; 991 992 cchPath = pszNext - pszPath; 993 if (chEnd == '"') 994 { 995 /* Skip anything between the " and the ; or string end. */ 996 while ((ch = *pszNext) != ';' && ch != '\0') 997 pszNext++; 998 } 999 else 1000 { 1001 /* Trim the string. */ 1002 while (cchPath > 0 && pszPath[cchPath-1] == ' ') //?? 1003 cchPath--; 1004 } 1005 1006 /* 1007 * No length? No Path! Or path'\'filename too long? => Next 1008 */ 1009 if (cchPath > 0 && cchPath + cchFile + 1 < CCHMAXPATH) 1010 { 1011 static char achFilename[CCHMAXPATH]; 1012 /* 1013 * Build filename 1014 */ 1015 memcpy(achFilename, pszPath, cchPath); 1016 if ((ch = achFilename[cchPath - 1]) == '\\' || ch == '/') 1017 cchPath--; 1018 else 1019 achFilename[cchPath] = '\\'; 1020 memcpy(&achFilename[cchPath + 1], pszFile, cchFile); /* cchFile = length + 1; hence we copy the terminator too. */ 1021 1022 /* 1023 * Try open the file. 1024 */ 1025 rc = myldrOpen(phFile, achFilename, pfl); 1026 switch (rc) 1027 { 1028 case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_ACCESS_DENIED: case ERROR_INVALID_ACCESS: 1029 case ERROR_INVALID_DRIVE: case ERROR_NOT_DOS_DISK: case ERROR_REM_NOT_LIST: case ERROR_BAD_NETPATH: 1030 case ERROR_NETWORK_BUSY: case ERROR_DEV_NOT_EXIST: case ERROR_TOO_MANY_CMDS: case ERROR_ADAP_HDW_ERR: 1031 case ERROR_UNEXP_NET_ERR: case ERROR_BAD_REM_ADAP: case ERROR_NETNAME_DELETED: case ERROR_BAD_DEV_TYPE: 1032 case ERROR_NETWORK_ACCESS_DENIED: case ERROR_BAD_NET_NAME: case ERROR_TOO_MANY_SESS: case ERROR_REQ_NOT_ACCEP: 1033 case ERROR_INVALID_PASSWORD: case ERROR_OPEN_FAILED: case ERROR_INVALID_NAME: case ERROR_FILENAME_EXCED_RANGE: 1034 case ERROR_VC_DISCONNECTED: 1035 break; 1036 1037 case NO_ERROR: 1038 strcpy(pszFilename, achFilename); 1039 default: 1040 tcbSetTCBFailErr(tcbGetCur(), TCBFailErr_save); 1041 return rc; 1042 } 1043 } 1044 #ifdef DEBUG 1045 else if (cchPath > 0) kprintf(("OpenPATH: Path component is too long\n")); 1046 #endif 1047 1048 /* 1049 * Next 1050 */ 1051 if (*pszNext == '\0') 1052 break; 1053 pszPath = pszNext + 1; 1054 } 1055 1056 1057 /* 1058 * File is not found. 1059 */ 1060 *phFile = 0; 1061 tcbSetTCBFailErr(tcbGetCur(), TCBFailErr_save); 1062 return ERROR_FILE_NOT_FOUND; 1063 } -
trunk/src/win32k/ldr/myldrOpenPath.cpp
r3829 r4164 1 /* $Id: myldrOpenPath.cpp,v 1. 1 2000-07-16 22:21:16bird Exp $1 /* $Id: myldrOpenPath.cpp,v 1.2 2000-09-02 21:08:10 bird Exp $ 2 2 * 3 3 * myldrOpenPath - ldrOpenPath used to open executables we'll override … … 16 16 #define INCL_NOPMAPI 17 17 #define INCL_OS2KRNL_TCB 18 #define INCL_OS2KRNL_PTDA 18 19 19 20 /******************************************************************************* … … 25 26 #include <stdlib.h> 26 27 28 #include "devSegDf.h" /* Win32k segment definitions. */ 27 29 #include "log.h" 28 30 #include "dev32.h" … … 134 136 else 135 137 { 136 struct InfoSegLDT *pInfoSeg; 137 pInfoSeg = (struct InfoSegLDT *)D32Hlp_GetDOSVar(DHGETDOSV_SYSINFOSEG, 0); 138 if (pInfoSeg == NULL) 138 PPTDA pPTDA = ptdaGetCur(); 139 if (pPTDA) 139 140 { 140 pExe = getModuleByhMTE(p InfoSeg->LIS_DI); /* LIS_DI is the same as hmod in LINFOSEG from bsedos16.h. */141 pExe = getModuleByhMTE(ptdaGet_ptda_module(pPTDA)); 141 142 #ifdef DEBUG /* While testing! */ 142 kprintf(("myldrOpenPath: getModuleByhMTE returned 0x% x08 for hmod=0x%04\n",143 pExe, p InfoSeg->LIS_DI));143 kprintf(("myldrOpenPath: getModuleByhMTE returned 0x%08x for hmod=0x%04x\n", 144 pExe, ptdaGet_ptda_module(pPTDA))); 144 145 #endif 145 146 } 146 #ifdef DEBUG /* While testing! */147 else148 dprintf(("myldrOpenPath: D32Hlp_GetDOSVar(DHGETDOSV_SYSINFOSEG) failed.\n"));149 #endif150 147 } 151 148 -
trunk/src/win32k/ldr/myldrRead.cpp
r2501 r4164 1 /* $Id: myldrRead.cpp,v 1. 6 2000-01-22 18:21:02bird Exp $1 /* $Id: myldrRead.cpp,v 1.7 2000-09-02 21:08:10 bird Exp $ 2 2 * 3 3 * myldrRead - ldrRead. 4 4 * 5 * Copyright (c) 1998- 1999 knut st. osmundsen5 * Copyright (c) 1998-2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no) 6 6 * 7 7 * Project Odin Software License can be found in LICENSE.TXT … … 23 23 #include <stdlib.h> 24 24 25 #include "devSegDf.h" /* Win32k segment definitions. */ 25 26 #include "log.h" 27 #include "avl.h" 26 28 #include "dev32.h" 27 29 #include <peexe.h> 28 30 #include <exe386.h> 29 31 #include "OS2Krnl.h" 32 #include "ldrCalls.h" 33 #include "ldr.h" 30 34 #include "ModuleBase.h" 31 35 #include "pe2lx.h" 32 #include "avl.h"33 #include "ldrCalls.h"34 #include "ldr.h"35 36 36 37 38 /** 39 * Overloads ldrRead. 40 * @returns OS/2 return code. 41 * @param hFile Filehandle to read from. 42 * @param pvBuffer Buffer to read into. 43 * @param fpBuffer This is not flags as I first though, but probably a far 16-bit pointer 44 * to the buffer. 45 * @param cbToRead Count of bytes to read. 46 * @param pMTE 47 * @sketch IF it's our module THEN 48 * Get module pointer. (complain if this failes and backout to ldrRead.) 49 * Currently - verify that it's a Pe2Lx module. (complain and fail if not.) 50 * Invoke the read method of the module do the requested read operation. 51 * Save pMTE if present and not save allready. 52 * ENDIF 53 * - backout or not our module - 54 * forward request to the original ldrRead. 55 * @status Completely implemented. 56 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 57 */ 37 58 ULONG LDRCALL myldrRead( 38 SFNhFile,39 ULONGulOffset,40 PVOID pBuffer,41 ULONG ulFlags,42 ULONG ulBytesToRead,43 PMTEpMTE44 )59 SFN hFile, 60 ULONG ulOffset, 61 PVOID pvBuffer, 62 ULONG fpBuffer, 63 ULONG cbToRead, 64 PMTE pMTE 65 ) 45 66 { 46 67 ULONG rc; … … 50 71 { 51 72 PMODULE pMod; 52 kprintf(("ldrRead+: hF=%+04x off=%+08x pB=%+08x fl=%+08x cb=%+04x pMTE=%+08x\n",hFile,ulOffset,pBuffer,ulFlags,ulBytesToRead,pMTE)); 73 kprintf(("myldrRead: hF=%+04x off=%+08x pB=%+08x fp=%+08x cb=%+04x pMTE=%+08x\n", 74 hFile, ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE)); 53 75 54 76 pMod = getModuleBySFN(hFile); … … 59 81 pMod->pMTE = pMTE; 60 82 61 /* debug */62 if (ulFlags != 0)63 kprintf(("ldrRead: Warning ulFlags = 0x%x (!= 0)\n", ulFlags));64 65 83 if ((pMod->fFlags & MOD_TYPE_MASK) == MOD_TYPE_PE2LX) 66 rc = pMod->Data.pModule->read(ulOffset, p Buffer, ulBytesToRead, ulFlags, pMTE);84 rc = pMod->Data.pModule->read(ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE); 67 85 else 68 86 { 69 kprintf((" ldrRead: Invalid module type, %#x\n", pMod->fFlags & MOD_TYPE_MASK));87 kprintf(("myldrRead: Invalid module type, %#x\n", pMod->fFlags & MOD_TYPE_MASK)); 70 88 rc = ERROR_READ_FAULT; 71 89 } 72 return rc;73 90 } 74 91 else 75 kprintf(("ldrRead: DON'T PANIC! - but I can't get Node ptr! - This is really an IPE!\n")); 92 { 93 kprintf(("myldrRead: DON'T PANIC! - but I can't get Node ptr! - This is really an IPE!\n")); 94 rc = ERROR_READ_FAULT; 95 } 76 96 } 77 78 rc = ldrRead(hFile, ulOffset, pBuffer, ulFlags, ulBytesToRead, pMTE); 79 97 else 98 { 99 rc = ldrRead(hFile, ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE); 100 } 80 101 #if 0 81 kprintf((" ldrRead: hF=%+04x off=%+08x pB=%+08x fl=%+08x cb=%+04x pMTE=%+08x rc=%d\n",82 hFile, ulOffset,pBuffer,ulFlags,ulBytesToRead,pMTE,rc));102 kprintf(("myldrRead: hF=%+04x off=%+08x pB=%+08x fp=%+08x cb=%+04x pMTE=%+08x rc=%d\n", 103 hFile, ulOffset, pvBuffer, fpBuffer, cbToRead, pMTE, rc)); 83 104 #endif 84 105 -
trunk/src/win32k/ldr/mytkExecPgm.asm
r2872 r4164 1 ; $Id: mytkExecPgm.asm,v 1.1 0 2000-02-23 16:53:04bird Exp $1 ; $Id: mytkExecPgm.asm,v 1.11 2000-09-02 21:08:10 bird Exp $ 2 2 ; 3 3 ; mytkExecPgm - tkExecPgm overload … … 10 10 11 11 ; 12 ; Defined Constants And Macros 13 ; 14 CCHFILENAME EQU 261 ; The size of the filename buffer 15 CCHARGUMENTS EQU 1536 ; The size of the argument buffer 16 CCHMAXPATH EQU CCHFILENAME - 1 ; Max path length 17 18 ; 12 19 ; Include files 13 20 ; 14 21 include devsegdf.inc 15 22 16 ; 17 ; Imported Functions 23 24 ; 25 ; Imported Functions and variables. 18 26 ; 19 27 extrn _g_tkExecPgm:PROC 20 extrn AcquireBuffer:PROC21 extrn ReleaseBuffer:PROC22 extrn QueryBufferSegmentOffset:PROC23 28 24 29 ; Scans strings until empy-string is reached. … … 45 50 extrn _f_FuBuff:PROC 46 51 52 53 ; 32-bit memcpy. (see OS2KTK.h) 54 extrn _TKFuBuff@16:PROC 55 56 ; 57 ; LDR semaphore 58 ; 59 extrn pLdrSem:DWORD 60 extrn _LDRClearSem@0:PROC 61 extrn _KSEMRequestMutex@8:PROC 62 extrn _KSEMQueryMutex@8:PROC 63 64 ; 65 ; Loader State 66 ; 67 extrn ulLDRState:DWORD 68 69 ; 70 ; Pointer to current executable module. 71 ; 72 extrn pExeModule:DWORD 73 74 ; 75 ; DevHlp32 76 ; 77 extrn D32Hlp_VirtToLin:PROC 78 79 ; 80 ; TKSSBase (32-bit) 81 ; 82 extrn pulTKSSBase32:DWORD 83 47 84 ; 48 85 ; Exported symbols 49 86 ; 50 87 public mytkExecPgm 51 88 public tkExecPgmCopyEnv 89 90 public fTkExecPgm 91 public achTkExecPgmFilename 92 public achTkExecPgmArguments 93 94 95 96 ; 97 ; Global data 98 ; 99 100 ; Filename and arguments buffers + environment pointer 101 ; from the tkExecPgm call. 102 ; 103 ; This data is only valid at isLdrStateExecPgm time 104 ; (and you'll have to be behind the loader semaphore of course!) 105 DATA16 SEGMENT 106 fTkExecPgm db 0 ; 0 - achTkExecPgmFilename and achTkExecPgmArguments is INVALID 107 ; 1 - achTkExecPgmFilename and achTkExecPgmArguments is VALID. 108 achTkExecPgmFilename db CCHFILENAME dup (0) ; The filename passed in to tkExecPgm if (fTkExec is TRUE) 109 achTkExecPgmArguments db CCHARGUMENTS dup (0) ; The arguments passed in to tkExecPgm if (fTkExec is TRUE) 110 fpachTkExecPgmEnv dd 0 ; Far pointer to environment passed in to tkExecPgm. 111 ; Valid at isLdrStateExecPgm time. 112 ; NOTE! User data, don't touch it directly! 113 DATA16 ENDS 52 114 53 115 54 116 CODE32 SEGMENT 55 56 117 ;; 57 ; 118 ; New implementation. 58 119 ; @returns same as tkExecPgm: eax, edx and carry flag 59 120 ; @param ax Exec flag … … 65 126 ; may modify later if this is a UNIX shellscript or 66 127 ; a PE-file started by pe.exe. 67 ; @status 128 ; @status completely implemented. 68 129 ; @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 69 ; @remark 70 ; 71 ; The buffer we are using is a C struct as follows. 72 ; struct Buffer 73 ; { 74 ; char szFilename[261]; /* offset 0 */ 75 ; char achArg[1536-261]; /* offset 261 */ 76 ; }; 130 ; 77 131 ; 78 132 mytkExecPgm PROC FAR 79 pBuffer = dword ptr -04h 80 SegBuffer = -08h 81 OffBuffer = -0Ch 82 cchFilename = dword ptr -10h 83 cchArgs = dword ptr -14h 84 ;usExecFlag = -18h 85 ;SegFilename = -1ch 86 ;OffFilename = -1eh 87 ;SegEnv = -20h 88 ;OffEnv = -22h 89 ;SegArg = -24h 90 ;OffArg = -26h 91 92 ASSUME CS:CODE32, DS:NOTHING, SS:NOTHING 93 ; int 3 94 push ebp 95 mov ebp, esp 96 lea esp, [ebp + cchArgs] 97 98 push eax 99 push ecx 100 push ds 101 push es 102 push edi 103 104 ; parameter validations 105 mov ax, ds ; pointer to filename 106 cmp ax, 4 107 jb mytkExecPgm_CalltkExecPgm_X1 108 109 ; 110 ; filename length 111 ; 112 mov ax, ds 113 mov es, ax 114 pushad 115 push es 116 push ds 117 mov bx, ds 118 mov di, dx ; es:di is now filename address (ds:dx). 119 push cs ; Problem calling far into the calltab segement. 120 call near ptr FLAT:_f_FuStrLen 121 movzx ecx, cx 122 mov [ebp+cchFilename], ecx 123 pop ds 124 pop es 125 popad 126 jc mytkExecPgm_CalltkExecPgm_X1; If the FuStrLen call failed we bail out! 127 128 ; 129 ; if filename length is more that CCHMAXPATH then we don't do anything!. 130 ; 131 cmp [ebp+cchFilename], 260 132 jae mytkExecPgm_CalltkExecPgm_X1; length >= 260 133 134 ; 135 ; args length 136 ; Note: the arguments are a series of ASCIIZs ended by an empty string (ie. '\0'). 137 ; 138 pop edi 139 push edi 140 xor ecx, ecx 141 cmp di, 4 ; The argument might me a invalid pointer... 142 jb mytkExecPgm_CalltkExecPgm_1 143 144 pushad 145 push es 146 push ds 147 mov bx, di ; 148 mov di, si ; bx:di -> arguments 149 push cs ; Problem calling far into the calltab segement. 150 call near ptr FLAT:_f_FuStrLenZ 151 movzx ecx, cx 152 mov [ebp+cchArgs], ecx 153 pop ds 154 pop es 155 popad 156 jc mytkExecPgm_CalltkExecPgm_X1 157 158 mytkExecPgm_CalltkExecPgm_1: 159 mov ecx, [ebp+cchArgs] 160 add ecx, [ebp+cchFilename] ; filename 161 add ecx, 3 + 260 ; 260 = new argument from a scrip file or something. 162 ; 3 = two '\0's and a space after added argument. 163 cmp ecx, 1536 ; 1536 = Buffersize. FIXME! Define this!!! 164 jae mytkExecPgm_CalltkExecPgm_X1; jmp if argument + file + new file > buffer size 165 166 ; 167 ; Aquire a buffer 168 ; 169 call AcquireBuffer 170 or eax, eax 171 jz mytkExecPgm_CalltkExecPgm_X1; Failed to get buffer. 172 mov [ebp+pBuffer], eax 173 174 ; 175 ; Get Segment and offset for the buffer 176 ; 177 call QueryBufferSegmentOffset 178 mov cx, es 179 mov [ebp+OffBuffer], ax 180 mov [ebp+SegBuffer], es 181 test eax, 000570000h 182 jnz mytkExecPgm_CalltkExecPgm_X2 183 184 ; 185 ; Copy filename to pBuffer. 186 ; 187 pushad 188 push es 189 push ds 190 mov di, ax ; es:di pBuffer 191 mov si, dx 192 mov bx, ds ; bx:si Filename pointer (input ds:dx) 193 mov ecx, [ebp+cchFilename] 194 push cs ; Problem calling far into the calltab segement. 195 call near ptr FLAT:_f_FuBuff 196 pop ds 197 pop es 198 popad 199 jc mytkExecPgm_CalltkExecPgm_X2 200 201 ; 202 ; Copy Args to pBuffer + 261 203 ; 204 ; stack: edi, es, ds, ecx, eax 205 pop edi 206 push edi 207 add eax, 261 ; we'll use eax in the branch 208 cmp di, 4 209 jb mytkExecPgm_CalltkExecPgm_2 210 pushad 211 push es 212 push ds 213 mov ecx, [ebp+cchArgs] 214 mov bx, di ; ds:si -> arguments 215 mov di, ax ; es:di -> buffer + 261 216 push cs ; Problem calling far into the calltab segement. 217 call near ptr FLAT:_f_FuBuff 218 pop ds 219 pop es 220 popad 221 jc mytkExecPgm_CalltkExecPgm_X2 222 jmp mytkExecPgm_CalltkExecPgm_3 223 224 mytkExecPgm_CalltkExecPgm_2: 225 mov word ptr es:[eax], 0 ; Terminate the empty string! 226 227 ; 228 ; Restore variables pushed on the stack 229 ; 230 ; stack: edi, es, ds, ecx, eax 231 mytkExecPgm_CalltkExecPgm_3: 232 pop edi 233 pop es 234 pop ds 235 pop ecx 236 pop eax 237 238 ; 239 ; Set new input parameters (call _g_tkExecPgm) 240 ; 241 ; ds:dx is to become SegBuffer:OffBuffer 242 ; di:si is to become SegBuffer:OffBuffer+261 243 ; 244 ; The some of the old values are stored on the stack (for the time being) 245 push ds 246 push edi 247 push esi 248 249 mov di, [ebp+SegBuffer] 250 mov ds, di 251 mov si, [ebp+OffBuffer] 252 mov dx, si ; ds:dx SegBuffer:OffBuffer 253 add si, 261 ; di:si SegBuffer:OffBuffer+261 254 255 ; 256 ; Call _g_tkExecPgm 257 ; 258 push cs ; Problem calling far into the calltab segement. 259 call near ptr FLAT:_g_tkExecPgm 260 pushfd 261 262 ; 263 ; Release buffer 264 ; 265 push eax 266 mov eax, [ebp + pBuffer] 267 call ReleaseBuffer 268 mov [ebp + pBuffer], 0 269 pop eax 270 271 ; 272 ; Return 273 ; 274 popfd 275 pop esi 276 pop edi 277 pop ds 278 leave 279 retf 280 281 mytkExecPgm_CalltkExecPgm_X2: 282 ; 283 ; Release buffer 284 ; 285 mov eax, [ebp + pBuffer] 286 call ReleaseBuffer 287 mov [ebp + pBuffer], 0 288 289 mytkExecPgm_CalltkExecPgm_X1: 290 pop edi 291 pop es 292 pop ds 293 pop ecx 294 pop eax 295 296 mytkExecPgm_CalltkExecPgm: 297 push cs 298 call near ptr FLAT:_g_tkExecPgm 299 leave 300 retf 301 mytkExecPgm ENDP 302 303 304 305 CODE32 ENDS 306 307 if 0 ; alternate implementation. 308 mytkExecPgm PROC FAR 309 pBuffer = dword ptr -04h 310 SegBuffer = -08h 311 OffBuffer = -0Ch 312 cchFilename = -10h 313 cchArgs = -14h 314 usExecFlag = -18h 315 SegFilename = -1ch 316 OffFilename = -1eh 317 SegEnv = -20h 318 OffEnv = -22h 319 SegArg = -24h 320 OffArg = -26h 133 cchFilename = -4h 134 cchArgs = -08h 135 usExecFlag = -0ch 136 SegFilename = -10h 137 OffFilename = -12h 138 SegEnv = -14h 139 OffEnv = -16h 140 SegArg = -18h 141 OffArg = -1ah 321 142 322 143 ASSUME CS:CODE32, DS:NOTHING, SS:NOTHING … … 325 146 lea esp, [ebp + OffArg] 326 147 327 ; save input parameters 148 ; 149 ; Save input parameters 150 ; 328 151 mov [ebp + usExecFlag], ax 329 152 mov ax, es … … 332 155 mov [ebp + SegArg], di 333 156 mov [ebp + OffArg], si 334 mov ax, ds335 mov [ebp + SegFilename], ax157 mov bx, ds 158 mov [ebp + SegFilename], bx 336 159 mov [ebp + OffFilename], dx 337 160 338 ; parameter validations 339 cmp ax, 4 ; pointer to filename 340 jb mytkExecPgm_CalltkExecPgm_X1 341 342 ; 343 ; filename length 344 ; 345 mov bx, ax 161 ; 162 ; Parameter validations - if any of these fail we'll just pass on to 163 ; the real tkExecPgm without setting up any buffers stuff. 164 ; 1) validate the file pointer. 165 ; 2) validate the file name length < 260 166 ; 3) validate that the arguments aren't larger than the buffer. 167 ; 168 169 ; Validate filename pointer 170 ; 171 cmp bx, 4 ; pointer to filename 172 jb tkepgm_backout 173 174 ; Validate filename length 175 ; 346 176 mov di, dx ; bx:di is now filename address 347 177 push cs ; Problem calling far into the calltab segement. 348 178 call near ptr FLAT:_f_FuStrLen 349 jc mytkExecPgm_CalltkExecPgm_X1; If the FuStrLen call failed we bail out! 350 351 ; 179 jc tkepgm_backout ; If the FuStrLen call failed we bail out! 180 352 181 ; if filename length is more that CCHMAXPATH then we don't do anything!. 353 ; 354 cmp cx, 260 355 jae mytkExecPgm_CalltkExecPgm_X1; length >= 260 356 mov [ebp+cchFilename], cx 182 cmp cx, CCHMAXPATH 183 jae tkepgm_backout ; length >= CCHMAXPATH 184 mov [ebp + cchFilename], cx 357 185 358 186 ; … … 360 188 ; Note: the arguments are a series of ASCIIZs ended by an empty string (ie. '\0'). 361 189 ; 362 mov bx, [ebp+SegArg] 190 xor cx, cx ; Set length to zero. 191 mov bx, [ebp + SegArg] 363 192 cmp bx, 4 ; The argument might me an NULL pointer 364 xor cx, cx 365 jb mytkExecPgm_CalltkExecPgm_1 366 367 mov di, [ebp+OffArg] ; bx:di -> arguments 193 jb tkepgm1 194 195 mov di, [ebp + OffArg] ; bx:di -> arguments 368 196 push cs ; Problem calling far into the calltab segement. 369 197 call near ptr FLAT:_f_FuStrLenZ 370 mov [ebp+cchArgs], cx371 jc mytkExecPgm_CalltkExecPgm_X1 372 373 mytkExecPgm_CalltkExecPgm_1: 374 add cx, [ebp +cchFilename]; filename length375 add cx, 3 + 260 ; 260 = new argument from a scripfile or something.198 jc tkepgm_backout 199 200 tkepgm1: 201 mov [ebp + cchArgs], cx 202 add cx, [ebp + cchFilename] ; filename length 203 add cx, 3 + 260 ; 260 = additional arguments from a script file or something. 376 204 ; 3 = two '\0's and a space after added argument. 377 cmp ecx, 1536 ; 1536 = Buffersize. FIXME! Define this!!! 378 jae mytkExecPgm_CalltkExecPgm_X1; jmp if argument + file + new file > buffer size 379 380 ; 381 ; Aquire a buffer 382 ; 383 call AcquireBuffer 384 mov [ebp+pBuffer], eax 385 or eax, eax 386 jz mytkExecPgm_CalltkExecPgm_X1; Failed to get buffer. 387 388 ; 389 ; Get Segment and offset for the buffer 390 ; 391 call QueryBufferSegmentOffset 392 mov cx, es 393 mov [ebp+OffBuffer], ax 394 mov [ebp+SegBuffer], es 395 test eax, 000570000h 396 jnz mytkExecPgm_CalltkExecPgm_X2 397 398 ; 399 ; Copy filename to pBuffer. 400 ; 401 mov di, ax ; es:di pBuffer 402 mov si, dx 403 mov bx, ds ; bx:si Filename pointer (input ds:dx) 404 mov cx, [ebp+cchFilename] ; cx = length of area to copy 205 cmp cx, CCHARGUMENTS ; argument Buffersize. 206 jae tkepgm_backout ; jmp if argument + file + additional arguments >= buffer size 207 208 209 ; 210 ; Aquire the OS/2 loader semaphore 211 ; Since parameters looks good, we're ready for getting the loader semaphore. 212 ; We use the loader semaphore to serialize access to the win32k.sys loader 213 ; subsystem. 214 ; Before we can get the loader semaphore, we'll need to set ds and es to 215 ; flat R0 context. 216 ; The loader semaphore is later requested by the original tkExecPgm so 217 ; this shouldn't break anything. 218 ; 219 mov ax, seg FLAT:DATA32 220 mov ds, ax 221 mov es, ax 222 ASSUME DS:FLAT, ES:FLAT 223 224 mov eax, pLdrSem ; Get pointer to the loader semaphore. 225 or eax, eax ; Check if null. (paranoia) 226 jz tkepgm_backout ; Fail if null. 227 228 push 0ffffffffh ; Wait indefinitely. 229 push eax ; Push LdrSem address (which is the handle). 230 call near ptr FLAT:_KSEMRequestMutex@8 231 or eax, eax ; Check if failed. 232 jnz tkepgm_backout ; Backout on failure. 233 234 235 ; 236 ; From here on we won't backout to the tkepgm_backout lable but 237 ; the tkepgm_backout2 lable. (This will restore the parameters 238 ; and jump in at the call to tkExecPgm behind the Loader Sem.) 239 ; 240 241 242 ; 243 ; Set global data: 244 ; Zeros pointer to exemodule to NULL (a bit paranoia). 245 ; Mark global data valid. 246 ; Store Environment pointer. 247 ; Set loader state. 248 ; 249 mov pExeModule, 0 ; Sets the exemodule pointer to NULL. 250 mov fTkExecPgm, 1 ; Optimistic, mark the global data valid. 251 mov eax, [ebp + OffEnv] ; Environment FAR pointer. 252 mov fpachTkExecPgmEnv, eax ; Store the Environment pointer. This will 253 ; later permit us to get the passed in 254 ; environment in for ex. ldrOpenPath. 255 mov ulLDRState, 1 ; Set the loader state to LDRSTATE_TKEXECPGM! 256 ASSUME DS:NOTHING, ES:NOTHING 257 258 259 ; 260 ; Copy filename to achBuffer. 261 ; 262 mov di, seg achTkExecPgmFilename 263 mov es, di 264 mov edi, offset achTkExecPgmFilename 265 ; es:(e)di -> &achTkExecPgmFilename[0] 266 mov si, [ebp + OffFilename] 267 mov bx, [ebp + SegFilename] ; bx:si Filename pointer (input ds:dx) 268 ASSUME DS:NOTHING 269 mov cx, [ebp + cchFilename] ; cx = length of area to copy 405 270 push cs ; Problem calling far into the calltab segement. 406 271 call near ptr FLAT:_f_FuBuff 407 jc mytkExecPgm_CalltkExecPgm_X2 408 409 ; 410 ; Copy Args to pBuffer + 261 411 ; 412 mov si, [ebp+SegArg] 413 cmp si, 4 414 jb mytkExecPgm_CalltkExecPgm_2 415 mov ds, si 416 mov si, [ebp+OffArg] ; ds:si -> arguments 417 mov di, [ebp+SegBuffer] 272 jc tkepgm_backout2 ; In case of error back (quite unlikely). 273 274 275 ; 276 ; Copy Args to achTkExecPgmArguments 277 ; 278 mov di, seg achTkExecPgmArguments 418 279 mov es, di 419 mov di, [ebp+OffBuffer] 420 add di, 261 ; es:di -> buffer + 261 421 mov cx, [ebp+cchArgs] ; cx = length of area to copy 280 mov edi, offset achTkExecPgmArguments 281 ; es:(e)di -> &achTkExecPgmArguments[0] 282 mov word ptr es:[edi], 0 ; Terminate the argument string in case 283 ; there aren't any arguments.('\0\0') 284 ; (We're just about to find that out.) 285 mov bx, [ebp + SegArg] 286 cmp bx, 4 ; Is the argument pointer a null-pointer? 287 jb tkepgm_setup_parms ; Skip copy if null pointer. 288 ; Argument string is '\0\0'. 289 mov si, [ebp + OffArg] ; bx:si -> arguments 290 mov cx, [ebp + cchArgs] ; cx = length of area to copy 422 291 push cs ; Problem calling far into the calltab segement. 423 292 call near ptr FLAT:_f_FuBuff 424 jc mytkExecPgm_CalltkExecPgm_X2 425 jmp mytkExecPgm_CalltkExecPgm_3 426 427 mytkExecPgm_CalltkExecPgm_2: 428 mov word ptr es:[eax], 0 ; Terminate the empty string! 429 430 ; 431 ; Set new input parameters (call _g_tkExecPgm) 432 ; 433 ; ds:dx is to become SegBuffer:OffBuffer 434 ; di:si is to become SegBuffer:OffBuffer+261 435 ; 436 mytkExecPgm_CalltkExecPgm_3: 437 mov di, [ebp+SegBuffer] 438 mov ds, di 439 mov si, [ebp+OffBuffer] 440 mov dx, si ; ds:dx SegBuffer:OffBuffer 441 add si, 261 ; di:si SegBuffer:OffBuffer+261 442 mov bx, [ebp+SegEnv] 293 jc tkepgm_backout2 ; In case of error back (quite unlikely). 294 295 296 ; 297 ; Setup new input parameters (call _g_tkExecPgm) 298 ; 299 ; ds:dx is to become &achTkExecPgmFilename[0] 300 ; di:si is to become &achTkExecPgmArguments[0] 301 ; 302 tkepgm_setup_parms: 303 mov ax, [ebp + usExecFlag] 304 mov di, seg achTkExecPgmArguments 305 mov esi, offset achTkExecPgmArguments ; di:si &achTkExecPgmArguments[0] 306 mov ds, di ; Assumes same segment (which of course is true). 307 mov edx, offset achTkExecPgmFilename ; ds:dx &achTkExecPgmFilename[0] 308 mov bx, [ebp + SegEnv] 443 309 mov es, bx 444 mov bx, [ebp+SegEnv] 310 mov bx, [ebp + OffEnv] ; es:bx Environment 311 445 312 446 313 ; 447 314 ; Call _g_tkExecPgm 448 315 ; 316 tkepgm_callbehind: 449 317 push cs ; Problem calling far into the calltab segement. 450 318 call near ptr FLAT:_g_tkExecPgm 451 pushfd 452 453 ; 454 ; Release buffer 455 ; 456 push eax 457 mov eax, [ebp + pBuffer] 458 call ReleaseBuffer 459 mov [ebp + pBuffer], 0 460 pop eax 461 462 ; 463 ; Return 464 ; 465 push [ebp + SegFilename] 319 pushfd ; preserve flags 320 push eax ; preserve result. 321 push ecx ; preserve ecx just in case 322 push edx ; preserve edx just in case 323 mov ax, seg FLAT:DATA32 324 mov ds, ax 325 mov es, ax 326 ASSUME ds:FLAT, es:FLAT ; both ds and es are now FLAT 327 328 329 ; 330 ; Clear loader semaphore? 331 ; and clear loader state, current exe module and tkExecPgm global data flag. 332 ; 333 push 0 ; Usage count variable. 334 mov eax, pulTKSSBase32 ; Get TKSSBase 335 mov eax, [eax] 336 add eax, esp ; Added TKSSBase to the usage count pointer 337 push eax ; Push address of usage count pointer. 338 push pLdrSem ; Push pointer to loader semaphore ( = handle). 339 call near ptr FLAT:_KSEMQueryMutex@8 340 or eax, eax ; Check return code. (1 = our / free; 0 = not our but take) 341 pop eax ; Pops usage count. 342 je tkepgm_callbehindret ; jmp if not taken by us (rc=FALSE). 343 or eax, eax ; Check usage count. 344 jz tkepgm_callbehindret ; jmp if 0 (=free). 345 mov ulLDRState, 0 ; Clears loaderstate. (LDRSTATE_UNKNOWN) 346 mov pExeModule, 0 ; Sets the exemodule pointer to NULL. 347 mov fTkExecPgm, 0 ; Marks global data invalid. 348 call near ptr FLAT:_LDRClearSem@0 349 350 ; 351 ; Restore ds and es (probably unecessary but...) and Return 352 ; 353 tkepgm_callbehindret: 354 push dword ptr [ebp + SegFilename] 466 355 pop ds 467 push [ebp + SegEnv]356 push dword ptr [ebp + SegEnv] 468 357 pop es 469 popfd 358 pop edx ; restore edx 359 pop ecx ; restore ecx 360 pop eax ; restore result. 361 popfd ; restore flags 470 362 leave 471 363 retf 472 364 473 mytkExecPgm_CalltkExecPgm_X2: 474 ; 475 ; Release buffer 476 ; 477 mov eax, [ebp + pBuffer] 478 call ReleaseBuffer 479 mov [ebp + pBuffer], 0 480 481 mytkExecPgm_CalltkExecPgm_X1: 482 pop ds 365 366 ; 367 ; This is a backout were tkExecPgm probably will backout and we're 368 ; allready behind the loader semaphore. 369 ; 370 tkepgm_backout2: 371 ; 372 ; Set Flat context and invalidate buffer. 373 ; 374 mov ax, seg FLAT:DATA32 375 mov ds, ax 376 ASSUME ds:FLAT 377 mov fTkExecPgm, 0 ; Marks global data invalid. 378 379 ; 380 ; Restore parameters. and call the original tkExecPgm 381 ; 382 mov ax, [ebp + usExecFlag] 383 mov dx, [ebp + SegFilename] 384 mov ds, dx 385 mov dx, [ebp + OffFilename] 386 mov bx, [ebp + SegEnv] 387 mov es, bx 388 mov bx, [ebp + OffEnv] 389 mov di, [ebp + SegArg] 390 mov si, [ebp + OffArg] 391 jmp tkepgm_callbehind 392 393 394 ; 395 ; This is a backout were tkExecPgm too is exspected to back out. 396 ; 397 tkepgm_backout: 398 ; 399 ; Restore parameters. and call the original tkExecPgm 400 ; 401 mov ax, [ebp + usExecFlag] 402 mov dx, [ebp + SegFilename] 403 mov ds, dx 404 mov dx, [ebp + OffFilename] 405 mov bx, [ebp + SegEnv] 406 mov es, bx 407 mov bx, [ebp + OffEnv] 408 mov di, [ebp + SegArg] 409 mov si, [ebp + OffArg] 483 410 484 411 mytkExecPgm_CalltkExecPgm: 485 push cs 412 push cs ; Problem calling far into the calltab segement. 486 413 call near ptr FLAT:_g_tkExecPgm 487 414 leave … … 489 416 mytkExecPgm ENDP 490 417 418 419 420 ;; 421 ; Function which copies the environment data passed into tkExecPgm 422 ; to a given buffer. 423 ; @cproto ULONG _Optlink tkExecPgmCopyEnv(char *pachBuffer, unsigned cchBuffer); 424 ; @returns OS/2 return code - NO_ERROR on success. 425 ; 0 on error or no data. 426 ; @param pachBuffer Pointer to buffer which the environment data is 427 ; to be copied to. 428 ; (eax) 429 ; @param cchBuffer Size of the buffer. 430 ; (edx) 431 ; @uses eax, edx, ecx 432 ; @sketch 433 ; @status 434 ; @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 435 ; @remark 436 tkExecPgmCopyEnv PROC NEAR 437 cchEnv = -04h 438 ASSUME ds:FLAT, es:FLAT, ss:NOTHING 439 push ebp 440 mov ebp, esp 441 lea esp, [ebp + cchEnv] 442 443 push ebx 444 mov ebx, eax ; ebx now holds the buffer pointer. 445 446 ; 447 ; Call tkExecPgmEnvLength to get length and check that pointer is valid. 448 ; 449 push edx 450 call tkExecPgmEnvLength 451 pop ecx ; ecx now holds the buffer length. 452 453 cmp eax, 0 454 ja tkepce_ok1 455 mov eax, 232 ; ERROR_NO_DATA 456 jmp tkepce_ret ; Fail if no data or any other error. 457 458 tkepce_ok1: 459 cmp eax, ecx ; (ecx is the buffer size.) 460 jbe tkepce_ok2 ; Fail if buffer too small. 461 mov eax, 111 ; ERROR_BUFFER_OVERFLOW 462 jmp tkepce_ret 463 464 tkepce_ok2: 465 mov [ebp + cchEnv], eax ; Save environment length. 466 467 468 ; 469 ; Thunk the environment 16-bit far pointer to 32-bit. 470 ; 471 mov eax, fpachTkExecPgmEnv 472 call D32Hlp_VirtToLin 473 or eax, eax ; check if thunking were successful. 474 jnz tkepce_ok3 ; Jump if success. 475 mov eax, edx ; A special feature for D32Hlp_VirtToLin is that edx 476 ; have the error code in case on failure. 477 jmp tkepce_ret 478 479 tkepce_ok3: 480 ; 481 ; Copy the environment data. 482 ; 483 push 3 ; Fatal if error. 484 push dword ptr [ebp + cchEnv] ; Number of bytes to copy 485 push eax ; Source buffer pointer. (user) 486 push ebx ; Target buffer pointer. 487 call near ptr FLAT:_TKFuBuff@16 488 489 tkepce_ret: 490 pop ebx 491 leave 492 ret 493 tkExecPgmCopyEnv ENDP 494 495 496 497 ;; 498 ; This function gets the length of the tkExecPgm environment data. 499 ; @cproto ULONG _Optlink tkExecPgmEnvLength(void); 500 ; @returns Environment data length in bytes. 501 ; @uses eax, edx, ecx 502 ; @sketch 503 ; @status 504 ; @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 505 ; @remark 506 tkExecPgmEnvLength PROC NEAR 507 ASSUME ds:FLAT, es:FLAT, ss:NOTHING 508 push ebp 509 mov ebp, esp 510 511 ; 512 ; Push register which needs to be presered. 513 ; 514 push es 515 push ds 516 push esi 517 push edi 518 push ebx 519 520 521 ; 522 ; Check that the data is valid. 523 ; 524 cmp ulLDRState, 1 ; LDRSTATE_TKEXECPGM 525 jnz tkepel_err_ret 526 527 528 ; 529 ; Check if the environment pointer is NULL. 530 ; 531 mov ebx, fpachTkExecPgmEnv 532 ror ebx, 16 533 cmp bx, 4 534 jb tkepel_err_ret 535 536 537 tkepel1: 538 ; 539 ; Get the environment length 540 ; 541 mov edi, ebx 542 ror edi, 16 ; bx:di -> [fpachTkExecPgmEnv] 543 xor ecx, ecx 544 push cs ; Problem calling far into the calltab segement. 545 call near ptr FLAT:_f_FuStrLenZ 546 jc tkepel_err_ret 547 movzx eax, cx 548 jmp tkepel_ret 549 550 551 ; Failure 552 tkepel_err_ret: 553 xor eax, eax 554 555 556 ; Return 557 tkepel_ret: 558 pop ebx ; restore registers 559 pop edi 560 pop esi 561 pop ds 562 pop es 563 leave 564 ret 565 tkExecPgmEnvLength ENDP 566 567 568 569 570 491 571 CODE32 ENDS 492 endif493 572 494 573
Note:
See TracChangeset
for help on using the changeset viewer.
