| 1 | ; $Id: mytkExecPgm.asm,v 1.13 2001-02-23 02:57:55 bird Exp $ | 
|---|
| 2 | ; | 
|---|
| 3 | ; mytkExecPgm - tkExecPgm overload | 
|---|
| 4 | ; | 
|---|
| 5 | ; Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no) | 
|---|
| 6 | ; | 
|---|
| 7 | ; Project Odin Software License can be found in LICENSE.TXT | 
|---|
| 8 | ; | 
|---|
| 9 | .386p | 
|---|
| 10 |  | 
|---|
| 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 | ; | 
|---|
| 19 | ;   Include files | 
|---|
| 20 | ; | 
|---|
| 21 | include devsegdf.inc | 
|---|
| 22 |  | 
|---|
| 23 |  | 
|---|
| 24 | ; | 
|---|
| 25 | ;   Imported Functions and variables. | 
|---|
| 26 | ; | 
|---|
| 27 | extrn  g_tkExecPgm:PROC | 
|---|
| 28 |  | 
|---|
| 29 | ; Scans strings until empy-string is reached. | 
|---|
| 30 | ; input:  bx:di | 
|---|
| 31 | ; uses:   nearly all (save bp) | 
|---|
| 32 | ; return: cx size - CF clear | 
|---|
| 33 | ;         ax error- CF set | 
|---|
| 34 | extrn  f_FuStrLenZ:PROC | 
|---|
| 35 |  | 
|---|
| 36 | ; Stringlength | 
|---|
| 37 | ; input:  bx:di | 
|---|
| 38 | ; uses:   nearly all (save bp) | 
|---|
| 39 | ; return: cx size - CF clear | 
|---|
| 40 | ;         ax error- CF set | 
|---|
| 41 | extrn  f_FuStrLen:PROC | 
|---|
| 42 |  | 
|---|
| 43 | ;memcpy | 
|---|
| 44 | ;input:  bx:si pointer to source | 
|---|
| 45 | ;        es:di pointer to target | 
|---|
| 46 | ;        cx    count of bytes to copy | 
|---|
| 47 | ;uses:   nearly all (save bp), es, ds | 
|---|
| 48 | ;return: success CF clear | 
|---|
| 49 | ;        failure CF set | 
|---|
| 50 | extrn  f_FuBuff:PROC | 
|---|
| 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 |  | 
|---|
| 84 | ; | 
|---|
| 85 | ;   Exported symbols | 
|---|
| 86 | ; | 
|---|
| 87 | public myg_tkExecPgm | 
|---|
| 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 | 
|---|
| 114 |  | 
|---|
| 115 |  | 
|---|
| 116 | CODE32 SEGMENT | 
|---|
| 117 | ;; | 
|---|
| 118 | ; New implementation. | 
|---|
| 119 | ; @returns   same as tkExecPgm: eax, edx and carry flag | 
|---|
| 120 | ; @param     ax     Exec flag | 
|---|
| 121 | ;            ds:dx  Filename address. (String) | 
|---|
| 122 | ;            es:bx  Environment address. (String) | 
|---|
| 123 | ;            di:si  Argument address. (String) | 
|---|
| 124 | ; @uses      all - bp | 
|---|
| 125 | ; @sketch    Copy the filename and arguments into a buffer we | 
|---|
| 126 | ;            may modify later if this is a UNIX shellscript or | 
|---|
| 127 | ;            a PE-file started by pe.exe. | 
|---|
| 128 | ; @status    completely implemented. | 
|---|
| 129 | ; @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no) | 
|---|
| 130 | ; | 
|---|
| 131 | ; | 
|---|
| 132 | myg_tkExecPgm PROC FAR | 
|---|
| 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 | 
|---|
| 142 |  | 
|---|
| 143 | ASSUME CS:CODE32, DS:NOTHING, SS:NOTHING | 
|---|
| 144 | push    ebp | 
|---|
| 145 | mov     ebp, esp | 
|---|
| 146 | lea     esp, [ebp + OffArg] | 
|---|
| 147 |  | 
|---|
| 148 | ; | 
|---|
| 149 | ; Save input parameters | 
|---|
| 150 | ; | 
|---|
| 151 | mov     [ebp + usExecFlag], ax | 
|---|
| 152 | mov     ax, es | 
|---|
| 153 | mov     [ebp + SegEnv], ax | 
|---|
| 154 | mov     [ebp + OffEnv], bx | 
|---|
| 155 | mov     [ebp + SegArg], di | 
|---|
| 156 | mov     [ebp + OffArg], si | 
|---|
| 157 | mov     bx, ds | 
|---|
| 158 | mov     [ebp + SegFilename], bx | 
|---|
| 159 | mov     [ebp + OffFilename], dx | 
|---|
| 160 |  | 
|---|
| 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 | ; | 
|---|
| 176 | mov     di, dx                      ; bx:di is now filename address | 
|---|
| 177 | push    cs                          ; Problem calling far into the calltab segement. | 
|---|
| 178 | call    f_FuStrLen                  ; NB/TODO/FIXME: this is a 16-bit call... | 
|---|
| 179 | jc      tkepgm_backout              ; If the FuStrLen call failed we bail out! | 
|---|
| 180 |  | 
|---|
| 181 | ; if filename length is more that CCHMAXPATH then we don't do anything!. | 
|---|
| 182 | cmp     cx, CCHMAXPATH | 
|---|
| 183 | jae     tkepgm_backout              ; length >= CCHMAXPATH | 
|---|
| 184 | mov     [ebp + cchFilename], cx | 
|---|
| 185 |  | 
|---|
| 186 | ; | 
|---|
| 187 | ; args length | 
|---|
| 188 | ; Note: the arguments are a series of ASCIIZs ended by an empty string (ie. '\0'). | 
|---|
| 189 | ; | 
|---|
| 190 | xor     cx, cx                      ; Set length to zero. | 
|---|
| 191 | mov     bx, [ebp + SegArg] | 
|---|
| 192 | cmp     bx, 4                       ; The argument might me an NULL pointer | 
|---|
| 193 | jb      tkepgm1 | 
|---|
| 194 |  | 
|---|
| 195 | mov     di, [ebp + OffArg]          ; bx:di -> arguments | 
|---|
| 196 | push    cs                          ; Problem calling far into the calltab segement. | 
|---|
| 197 | call    f_FuStrLenZ                 ; NB/TODO/FIXME: this is a 16-bit call... | 
|---|
| 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. | 
|---|
| 204 | ;    3 = two '\0's and a space after added argument. | 
|---|
| 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 | 
|---|
| 270 | push    cs                          ; Problem calling far into the calltab segement. | 
|---|
| 271 | call    f_FuBuff                    ; NB/TODO/FIXME: this is a 16-bit call... | 
|---|
| 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 | 
|---|
| 279 | mov     es, di | 
|---|
| 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 | 
|---|
| 291 | push    cs                          ; Problem calling far into the calltab segement. | 
|---|
| 292 | call    f_FuBuff                    ; NB/TODO/FIXME: this is a 16-bit call... | 
|---|
| 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] | 
|---|
| 309 | mov     es, bx | 
|---|
| 310 | mov     bx, [ebp + OffEnv]                ; es:bx  Environment | 
|---|
| 311 |  | 
|---|
| 312 |  | 
|---|
| 313 | ; | 
|---|
| 314 | ; Call g_tkExecPgm | 
|---|
| 315 | ; | 
|---|
| 316 | tkepgm_callbehind: | 
|---|
| 317 | push    cs                          ; Problem calling far into the calltab segement. | 
|---|
| 318 | call    g_tkExecPgm | 
|---|
| 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    _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] | 
|---|
| 355 | pop     ds | 
|---|
| 356 | push    dword ptr [ebp + SegEnv] | 
|---|
| 357 | pop     es | 
|---|
| 358 | pop     edx                         ; restore edx | 
|---|
| 359 | pop     ecx                         ; restore ecx | 
|---|
| 360 | pop     eax                         ; restore result. | 
|---|
| 361 | popfd                               ; restore flags | 
|---|
| 362 | leave | 
|---|
| 363 | retf | 
|---|
| 364 |  | 
|---|
| 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] | 
|---|
| 410 |  | 
|---|
| 411 | myg_tkExecPgm_CalltkExecPgm: | 
|---|
| 412 | push    cs                          ; Problem calling far into the calltab segement. | 
|---|
| 413 | call    g_tkExecPgm | 
|---|
| 414 | leave | 
|---|
| 415 | retf | 
|---|
| 416 | myg_tkExecPgm ENDP | 
|---|
| 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    _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    f_FuStrLenZ                 ; NB/TODO/FIXME: this is a 16-bit call... | 
|---|
| 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 |  | 
|---|
| 571 | CODE32 ENDS | 
|---|
| 572 |  | 
|---|
| 573 |  | 
|---|
| 574 | END | 
|---|
| 575 |  | 
|---|