| 1 | ; $Id: ldstub.asm 214 2003-05-21 22:34:46Z zap $ | 
|---|
| 2 | ; | 
|---|
| 3 | ; Micro stub for <app> -> <app>.exe forwarding | 
|---|
| 4 | ; | 
|---|
| 5 | ; Build Instructions: | 
|---|
| 6 | ;   Stantard version: | 
|---|
| 7 | ;       alp ldstub.asm | 
|---|
| 8 | ;       ilink /pmtype:vio /ALIGN:1 /OUT:ldstub.bin ldstub.obj ldstub.def os2386.lib | 
|---|
| 9 | ; | 
|---|
| 10 | ;   Microversion: | 
|---|
| 11 | ;       alp -D:MICRO=1 ldstub.asm | 
|---|
| 12 | ;       ilink /pmtype:vio /ALIGN:1 /OUT:ldstub.bin ldstub.obj ldstub.def os2386.lib | 
|---|
| 13 | ; | 
|---|
| 14 | ; OVERLAY may be defined for execv()/spawnv(OVERLAY,..) is to be emulated. | 
|---|
| 15 | ; | 
|---|
| 16 | ; InnoTek Systemberatung GmbH Confidential | 
|---|
| 17 | ; | 
|---|
| 18 | ; Copyright (c) 2003 InnoTek Systemberatung GmbH | 
|---|
| 19 | ; Author: knut st. osmundsen <bird@anduin.net> | 
|---|
| 20 | ; | 
|---|
| 21 | ; All Rights Reserved | 
|---|
| 22 | ; | 
|---|
| 23 | ; | 
|---|
| 24 |  | 
|---|
| 25 | .486 | 
|---|
| 26 |  | 
|---|
| 27 | ;******************************************************************************* | 
|---|
| 28 | ;* Structures and Typedefs                                                     * | 
|---|
| 29 | ;******************************************************************************* | 
|---|
| 30 | RESULTCODES     STRUC | 
|---|
| 31 | resc_codeTerminate      DD      ? | 
|---|
| 32 | resc_codeResult DD      ? | 
|---|
| 33 | RESULTCODES     ENDS | 
|---|
| 34 |  | 
|---|
| 35 | extrn DosExecPgm:near | 
|---|
| 36 | extrn DosQueryModuleName:near | 
|---|
| 37 |  | 
|---|
| 38 |  | 
|---|
| 39 | DATA32 segment use32 para public 'DATA' | 
|---|
| 40 | DATA32 ends | 
|---|
| 41 |  | 
|---|
| 42 | BSS32   segment use32 para public 'BSS' | 
|---|
| 43 | ; buffer for modifying the executable name | 
|---|
| 44 | achNewExeName   db 260 dup(?) | 
|---|
| 45 | padding         db   8 dup(?)           ; safety precaution. | 
|---|
| 46 |  | 
|---|
| 47 | ; DosExecPgm result buffer. | 
|---|
| 48 | res             RESULTCODES <?,?> | 
|---|
| 49 | BSS32   ends | 
|---|
| 50 |  | 
|---|
| 51 | STACK32 segment use32 para stack 'STACK' | 
|---|
| 52 | dd  1800h dup(?)                    ; size doesn't matter as DosExecPgm uses thunk stack in any case. :/ | 
|---|
| 53 | STACK32 ends | 
|---|
| 54 |  | 
|---|
| 55 | ifndef MICRO | 
|---|
| 56 | DGROUP group DATA32, BSS32, STACK32 | 
|---|
| 57 | else | 
|---|
| 58 | DGROUP group CODE32, DATA32, BSS32, STACK32 | 
|---|
| 59 | endif | 
|---|
| 60 |  | 
|---|
| 61 |  | 
|---|
| 62 | ifndef MICRO | 
|---|
| 63 | CODE32 segment use32 para public 'CODE' | 
|---|
| 64 | else | 
|---|
| 65 | CODE32 segment use32 para public 'DATA' | 
|---|
| 66 | endif | 
|---|
| 67 |  | 
|---|
| 68 | ; Program startup registers are defined as follows. | 
|---|
| 69 | ;    EIP = Starting program entry address. | 
|---|
| 70 | ;    ESP = Top of stack address. | 
|---|
| 71 | ;    CS = Code selector for base of linear address space. | 
|---|
| 72 | ;    DS = ES = SS = Data selector for base of linear address space. | 
|---|
| 73 | ;    FS = Data selector of base of Thread Information Block (TIB). | 
|---|
| 74 | ;    GS = 0. | 
|---|
| 75 | ;    EAX = EBX = 0. | 
|---|
| 76 | ;    ECX = EDX = 0. | 
|---|
| 77 | ;    ESI = EDI = 0. | 
|---|
| 78 | ;    EBP = 0. | 
|---|
| 79 | ;    [ESP+0] = Return address to routine which calls DosExit(1,EAX). | 
|---|
| 80 | ;    [ESP+4] = Module handle for program module. | 
|---|
| 81 | ;    [ESP+8] = Reserved. | 
|---|
| 82 | ;    [ESP+12] = Environment data object address. | 
|---|
| 83 | ;    [ESP+16] = Command line linear address in environment data object. | 
|---|
| 84 | ; | 
|---|
| 85 | ; @remark   I don't care about cleaning up arguments as the leave does so. | 
|---|
| 86 | ; | 
|---|
| 87 | start: | 
|---|
| 88 | ASSUME ss:FLAT, ds:FLAT, es:FLAT, fs:nothing, gs:nothing | 
|---|
| 89 | push    ebp | 
|---|
| 90 | mov     ebp, esp | 
|---|
| 91 |  | 
|---|
| 92 | ; | 
|---|
| 93 | ; Get the executable name. | 
|---|
| 94 | ; | 
|---|
| 95 | ; ULONG DosQueryModuleName(HMODULE hmod, ULONG ulNameLength, PCHAR pNameBuf); | 
|---|
| 96 | ; | 
|---|
| 97 | push    offset FLAT:achNewExeName   ; pNameBuf | 
|---|
| 98 | push    size achNewExeName          ; ulNameLength | 
|---|
| 99 | push    dword ptr [ebp+8]           ; hmod | 
|---|
| 100 | call    DosQueryModuleName | 
|---|
| 101 | or      eax, eax | 
|---|
| 102 | jz      modname_ok | 
|---|
| 103 |  | 
|---|
| 104 | ; this ain't supposed to happen | 
|---|
| 105 | mov     edx, [ebp+4] | 
|---|
| 106 | int     3 | 
|---|
| 107 |  | 
|---|
| 108 | modname_ok: | 
|---|
| 109 | ; | 
|---|
| 110 | ; Append .EXE to the module name. | 
|---|
| 111 | ; | 
|---|
| 112 | xor     ecx, ecx | 
|---|
| 113 | dec     ecx | 
|---|
| 114 | mov     edi, offset FLAT:achNewExeName | 
|---|
| 115 | repne scasb | 
|---|
| 116 | mov     dword ptr [edi-1], 'EXE.' | 
|---|
| 117 | mov     dword ptr [edi+3], 0 | 
|---|
| 118 |  | 
|---|
| 119 | ; | 
|---|
| 120 | ; Try execute the .EXE appended module name. | 
|---|
| 121 | ; | 
|---|
| 122 | ; APIRET APIENTRY DosExecPgm(PCHAR pObjname, | 
|---|
| 123 | ;                            LONG cbObjname, | 
|---|
| 124 | ;                            ULONG execFlag, | 
|---|
| 125 | ;                            PCSZ  pArg, | 
|---|
| 126 | ;                            PCSZ  pEnv, | 
|---|
| 127 | ;                            PRESULTCODES pRes, | 
|---|
| 128 | ;                            PCSZ  pName); | 
|---|
| 129 | ; | 
|---|
| 130 | xor     ecx, ecx | 
|---|
| 131 | push    offset FLAT:achNewExeName   ; pName | 
|---|
| 132 | push    offset FLAT:res             ; pRes | 
|---|
| 133 | push    dword ptr [ebp + 10h]       ; pEnv | 
|---|
| 134 | push    dword ptr [ebp + 14h]       ; pArg | 
|---|
| 135 | ifdef OVERLAY | 
|---|
| 136 | push    1                           ; execFlag = EXEC_ASYNC | 
|---|
| 137 | else | 
|---|
| 138 | push    ecx                         ; execFlag = EXEC_SYNC = 0 | 
|---|
| 139 | endif | 
|---|
| 140 | push    ecx                         ; cbObjname | 
|---|
| 141 | push    ecx                         ; pObjname | 
|---|
| 142 | call    DosExecPgm | 
|---|
| 143 | or      eax, eax | 
|---|
| 144 | jz      exec_success | 
|---|
| 145 |  | 
|---|
| 146 | exec_failed: | 
|---|
| 147 | mov     eax, 07fh | 
|---|
| 148 | jmp     done | 
|---|
| 149 |  | 
|---|
| 150 | exec_success: | 
|---|
| 151 | ifndef OVERLAY | 
|---|
| 152 | ; | 
|---|
| 153 | ; Retrieve the result code. | 
|---|
| 154 | ; | 
|---|
| 155 | mov     eax, res.resc_codeResult | 
|---|
| 156 | mov     edx, res.resc_codeTerminate | 
|---|
| 157 | or      edx, edx | 
|---|
| 158 | jz      done | 
|---|
| 159 |  | 
|---|
| 160 | ; | 
|---|
| 161 | ; Something bad happend and the result code is 0. | 
|---|
| 162 | ; We shouldn't return 0 when we trap, crash or is killed. | 
|---|
| 163 | ; | 
|---|
| 164 | mov     eax, 0ffh | 
|---|
| 165 | endif | 
|---|
| 166 |  | 
|---|
| 167 |  | 
|---|
| 168 | done: | 
|---|
| 169 | leave | 
|---|
| 170 | ret | 
|---|
| 171 | CODE32 ends | 
|---|
| 172 |  | 
|---|
| 173 | end start | 
|---|
| 174 |  | 
|---|