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

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

Calltable fixes. Handle event. New 14062e kernels.

File size: 17.6 KB
Line 
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;
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;
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!)
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
116CODE32 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;
132myg_tkExecPgm PROC FAR
133cchFilename = -4h
134cchArgs = -08h
135usExecFlag = -0ch
136SegFilename = -10h
137OffFilename = -12h
138SegEnv = -14h
139OffEnv = -16h
140SegArg = -18h
141OffArg = -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
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.
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 ;
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
311
312
313 ;
314 ; Call g_tkExecPgm
315 ;
316tkepgm_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 ;
353tkepgm_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;
370tkepgm_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;
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
411myg_tkExecPgm_CalltkExecPgm:
412 push cs ; Problem calling far into the calltab segement.
413 call g_tkExecPgm
414 leave
415 retf
416myg_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
436tkExecPgmCopyEnv PROC NEAR
437cchEnv = -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
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
463
464tkepce_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
479tkepce_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
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
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
537tkepel1:
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
552tkepel_err_ret:
553 xor eax, eax
554
555
556; Return
557tkepel_ret:
558 pop ebx ; restore registers
559 pop edi
560 pop esi
561 pop ds
562 pop es
563 leave
564 ret
565tkExecPgmEnvLength ENDP
566
567
568
569
570
571CODE32 ENDS
572
573
574END
575
Note: See TracBrowser for help on using the repository browser.