source: trunk/src/win32k/ldr/mytkExecPgm.asm

Last change on this file was 5247, checked in by bird, 25 years ago

Calltable fixes. Handle event. New 14062e kernels.

File size: 17.6 KB
RevLine 
[5247]1; $Id: mytkExecPgm.asm,v 1.13 2001-02-23 02:57:55 bird Exp $
[2824]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;
[4164]12; Defined Constants And Macros
13;
14CCHFILENAME EQU 261 ; The size of the filename buffer
15CCHARGUMENTS EQU 1536 ; The size of the argument buffer
16CCHMAXPATH EQU CCHFILENAME - 1 ; Max path length
17
18;
[2824]19; Include files
20;
21 include devsegdf.inc
22
[4164]23
[2824]24;
[4164]25; Imported Functions and variables.
[2824]26;
[4347]27 extrn g_tkExecPgm:PROC
[2824]28
[2838]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
[4347]34 extrn f_FuStrLenZ:PROC
[2838]35
36 ; Stringlength
37 ; input: bx:di
38 ; uses: nearly all (save bp)
39 ; return: cx size - CF clear
40 ; ax error- CF set
[4347]41 extrn f_FuStrLen:PROC
[2838]42
43 ;memcpy
44 ;input: bx:si pointer to source
45 ; es:di pointer to target
46 ; cx count of bytes to copy
[2848]47 ;uses: nearly all (save bp), es, ds
[2838]48 ;return: success CF clear
49 ; failure CF set
[4347]50 extrn f_FuBuff:PROC
[2838]51
[4164]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
[2824]84;
85; Exported symbols
86;
[4347]87 public myg_tkExecPgm
[4164]88 public tkExecPgmCopyEnv
[2824]89
[4164]90 public fTkExecPgm
91 public achTkExecPgmFilename
92 public achTkExecPgmArguments
[2824]93
94
[4164]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!)
105DATA16 SEGMENT
106fTkExecPgm db 0 ; 0 - achTkExecPgmFilename and achTkExecPgmArguments is INVALID
107 ; 1 - achTkExecPgmFilename and achTkExecPgmArguments is VALID.
108achTkExecPgmFilename db CCHFILENAME dup (0) ; The filename passed in to tkExecPgm if (fTkExec is TRUE)
109achTkExecPgmArguments db CCHARGUMENTS dup (0) ; The arguments passed in to tkExecPgm if (fTkExec is TRUE)
110fpachTkExecPgmEnv dd 0 ; Far pointer to environment passed in to tkExecPgm.
111 ; Valid at isLdrStateExecPgm time.
112 ; NOTE! User data, don't touch it directly!
113DATA16 ENDS
114
115
[2824]116CODE32 SEGMENT
117;;
[4164]118; New implementation.
[2824]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
[2871]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.
[4164]128; @status completely implemented.
[2824]129; @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
130;
131;
[4347]132myg_tkExecPgm PROC FAR
[4164]133cchFilename = -4h
134cchArgs = -08h
135usExecFlag = -0ch
136SegFilename = -10h
137OffFilename = -12h
138SegEnv = -14h
139OffEnv = -16h
140SegArg = -18h
141OffArg = -1ah
[2848]142
[2824]143 ASSUME CS:CODE32, DS:NOTHING, SS:NOTHING
144 push ebp
145 mov ebp, esp
[4164]146 lea esp, [ebp + OffArg]
[2824]147
[4164]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
[2824]160
[4164]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 ;
[2827]168
[4164]169 ; Validate filename pointer
[2838]170 ;
[4164]171 cmp bx, 4 ; pointer to filename
172 jb tkepgm_backout
173
174 ; Validate filename length
[2838]175 ;
[4164]176 mov di, dx ; bx:di is now filename address
[2838]177 push cs ; Problem calling far into the calltab segement.
[5247]178 call f_FuStrLen ; NB/TODO/FIXME: this is a 16-bit call...
[4164]179 jc tkepgm_backout ; If the FuStrLen call failed we bail out!
[2824]180
181 ; if filename length is more that CCHMAXPATH then we don't do anything!.
[4164]182 cmp cx, CCHMAXPATH
183 jae tkepgm_backout ; length >= CCHMAXPATH
184 mov [ebp + cchFilename], cx
[2824]185
186 ;
187 ; args length
[2827]188 ; Note: the arguments are a series of ASCIIZs ended by an empty string (ie. '\0').
[2824]189 ;
[4164]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
[2824]194
[4164]195 mov di, [ebp + OffArg] ; bx:di -> arguments
[2838]196 push cs ; Problem calling far into the calltab segement.
[5247]197 call f_FuStrLenZ ; NB/TODO/FIXME: this is a 16-bit call...
[4164]198 jc tkepgm_backout
[2838]199
[4164]200tkepgm1:
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.
[2824]204 ; 3 = two '\0's and a space after added argument.
[4164]205 cmp cx, CCHARGUMENTS ; argument Buffersize.
206 jae tkepgm_backout ; jmp if argument + file + additional arguments >= buffer size
[2824]207
[4164]208
[2824]209 ;
[4164]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.
[2824]218 ;
[4164]219 mov ax, seg FLAT:DATA32
220 mov ds, ax
221 mov es, ax
222 ASSUME DS:FLAT, ES:FLAT
[2824]223
[4164]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
[2824]235 ;
[4164]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.)
[2824]239 ;
240
[4164]241
[2824]242 ;
[4164]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.
[2824]248 ;
[4164]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
[2824]257
[4164]258
[2824]259 ;
[4164]260 ; Copy filename to achBuffer.
[2824]261 ;
[4164]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
[2838]270 push cs ; Problem calling far into the calltab segement.
[5247]271 call f_FuBuff ; NB/TODO/FIXME: this is a 16-bit call...
[4164]272 jc tkepgm_backout2 ; In case of error back (quite unlikely).
[2824]273
[2827]274
[2824]275 ;
[4164]276 ; Copy Args to achTkExecPgmArguments
[2824]277 ;
[4164]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.
[5247]292 call f_FuBuff ; NB/TODO/FIXME: this is a 16-bit call...
[4164]293 jc tkepgm_backout2 ; In case of error back (quite unlikely).
[2824]294
[4164]295
[2824]296 ;
[4347]297 ; Setup new input parameters (call g_tkExecPgm)
[2824]298 ;
[4164]299 ; ds:dx is to become &achTkExecPgmFilename[0]
300 ; di:si is to become &achTkExecPgmArguments[0]
[2824]301 ;
[4164]302tkepgm_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
[2824]311
312
313 ;
[4347]314 ; Call g_tkExecPgm
[2824]315 ;
[4164]316tkepgm_callbehind:
[2838]317 push cs ; Problem calling far into the calltab segement.
[5247]318 call g_tkExecPgm
[4164]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
[2824]327
[4164]328
[2824]329 ;
[4164]330 ; Clear loader semaphore?
331 ; and clear loader state, current exe module and tkExecPgm global data flag.
[2824]332 ;
[4164]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).
[5247]339 call _KSEMQueryMutex@8
[4164]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
[2824]349
350 ;
[4164]351 ; Restore ds and es (probably unecessary but...) and Return
[2824]352 ;
[4164]353tkepgm_callbehindret:
354 push dword ptr [ebp + SegFilename]
[2824]355 pop ds
[4164]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
[2824]362 leave
363 retf
364
[4164]365
366;
367; This is a backout were tkExecPgm probably will backout and we're
368; allready behind the loader semaphore.
369;
370tkepgm_backout2:
[2824]371 ;
[4164]372 ; Set Flat context and invalidate buffer.
[2824]373 ;
[4164]374 mov ax, seg FLAT:DATA32
375 mov ds, ax
376 ASSUME ds:FLAT
377 mov fTkExecPgm, 0 ; Marks global data invalid.
[2824]378
[4164]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
[2824]392
[4164]393
394;
395; This is a backout were tkExecPgm too is exspected to back out.
396;
397tkepgm_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
[4347]411myg_tkExecPgm_CalltkExecPgm:
[4164]412 push cs ; Problem calling far into the calltab segement.
[5247]413 call g_tkExecPgm
[2824]414 leave
415 retf
[4347]416myg_tkExecPgm ENDP
[2824]417
[2827]418
419
[4164]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
436tkExecPgmCopyEnv PROC NEAR
437cchEnv = -04h
438 ASSUME ds:FLAT, es:FLAT, ss:NOTHING
[2848]439 push ebp
440 mov ebp, esp
[4164]441 lea esp, [ebp + cchEnv]
[2848]442
[4164]443 push ebx
444 mov ebx, eax ; ebx now holds the buffer pointer.
[2848]445
446 ;
[4164]447 ; Call tkExecPgmEnvLength to get length and check that pointer is valid.
[2848]448 ;
[4164]449 push edx
450 call tkExecPgmEnvLength
451 pop ecx ; ecx now holds the buffer length.
[2848]452
[4164]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.
[2848]457
[4164]458tkepce_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
[2848]463
[4164]464tkepce_ok2:
465 mov [ebp + cchEnv], eax ; Save environment length.
[2848]466
467
468 ;
[4164]469 ; Thunk the environment 16-bit far pointer to 32-bit.
[2848]470 ;
[4164]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
[2848]478
[4164]479tkepce_ok3:
[2848]480 ;
[4164]481 ; Copy the environment data.
[2848]482 ;
[4164]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.
[5247]487 call _TKFuBuff@16
[2848]488
[4164]489tkepce_ret:
490 pop ebx
491 leave
492 ret
493tkExecPgmCopyEnv 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
506tkExecPgmEnvLength PROC NEAR
507 ASSUME ds:FLAT, es:FLAT, ss:NOTHING
508 push ebp
509 mov ebp, esp
510
[2848]511 ;
[4164]512 ; Push register which needs to be presered.
[2848]513 ;
[4164]514 push es
515 push ds
516 push esi
517 push edi
518 push ebx
[2848]519
[4164]520
[2848]521 ;
[4164]522 ; Check that the data is valid.
[2848]523 ;
[4164]524 cmp ulLDRState, 1 ; LDRSTATE_TKEXECPGM
525 jnz tkepel_err_ret
[2848]526
527
528 ;
[4164]529 ; Check if the environment pointer is NULL.
[2848]530 ;
[4164]531 mov ebx, fpachTkExecPgmEnv
532 ror ebx, 16
533 cmp bx, 4
534 jb tkepel_err_ret
[2848]535
[4164]536
537tkepel1:
[2848]538 ;
[4164]539 ; Get the environment length
[2848]540 ;
[4164]541 mov edi, ebx
542 ror edi, 16 ; bx:di -> [fpachTkExecPgmEnv]
543 xor ecx, ecx
[2848]544 push cs ; Problem calling far into the calltab segement.
[5247]545 call f_FuStrLenZ ; NB/TODO/FIXME: this is a 16-bit call...
[4164]546 jc tkepel_err_ret
547 movzx eax, cx
548 jmp tkepel_ret
[2848]549
550
[4164]551; Failure
552tkepel_err_ret:
553 xor eax, eax
554
555
556; Return
557tkepel_ret:
558 pop ebx ; restore registers
559 pop edi
560 pop esi
[2848]561 pop ds
562 pop es
563 leave
[4164]564 ret
565tkExecPgmEnvLength ENDP
[2848]566
567
568
569
[4164]570
[2824]571CODE32 ENDS
[2848]572
573
[2824]574END
575
Note: See TracBrowser for help on using the repository browser.