	title	AUTOSTUB Version 1.2

;Copyright (C) 1992 Steve Flynn, C-Scape Computing

;This program is hereby donated to the Public Domain providing the line
;above copyright notice is left in tact.

;You may use this hack for any purpose that you wish, but I do not warrant
;it to be suitable for ANY purpose at all. Use at your own risk. If it
;blows up in your face, I am not responsible and I dont want to know.

;This is a replacement for WINSTUB.EXE which will auto load WINDOWS if the
;program using this stub is executed from the DOS command line.

;The string searching is crude, but its fast and effective (like TYLENOL).
;Anyway, most of the code if thrown away when WIN.COM is loaded. Only
;enough is kept to throw away the rest of the program, load WIN.COM
;and return to DOS after WIN.COM.

;I use the Borland C++ compiler and therefore TASM and TLINK.
;To assemble the program -
;	TASM AUTOSTUB
;	TLINK AUTOSTUB
;Thats all!

;For Microsoft assembler it should be -
;	MASM AUTOSTUB;
;	LINK AUTOSTUB;
;But I have not tried it!

;To use AUTOSTUB in your windows executables modify your .DEF files as follows
;Change the line
;	STUB	'WINSTUB.EXE'
;To
;	STUB	'AUTOSTUB.EXE'
;Or add this line if there is no STUB definition (which is often the case with
;the Borland products since the TLINK.EXE program knows how to add a WINSTUB
;all by itself).

;Fixes:
;	V1.2	Fixed problem when WINDIR= was last entry in environment
;	V1.1	Fixed problem of incorrect path when WINDIR= was not found
;		in the environment


msdos	equ	21h			;MS-DOS function request interrupt
envseg	equ	2ch			;PSP offset of environent segment
b	equ	byte ptr		;I HATE byte ptr
w	equ	word ptr		;and word ptr

code	segment
	assume	cs:code, ds:code, es:code, ss:code

path	db	'\WINDOWS', 120 dup (0)	;path to WIN.COM
cmdline	db	128 dup (0)		;command line to pass
param	dw	0			;pass same environment to WIN.COM
	dw	offset	cmdline
seg1	dw	0
	dw	5ch
seg2	dw	0
	dw	6ch
seg3	dw	0

loadwin:mov	bx, offset start	;last byte to keep
	mov	cl,4
	shr	bx,cl			;convert to paragraphs
	add	bx,17			;allow for PSP, and round to next para
	mov	es,bp			;get PSP segment
	mov	ah,4Ah			;dealloc
	int	msdos
	push	ds
	pop	es			;find data again
	lea	bx,param		;es:bx = parameter block
	lea	dx,path			;ds:dx = path to WIN.COM
	mov	ax,4B00h		;spawn WIN.COM
	int	msdos
	mov	ah,4ch			;terminate process
	int	msdos			;return code in AL

start:	push	cs
	pop	ds			;find the data
	mov	bp,es			;save PSP segment
	mov	seg1,cs			;save segment in parameter block
	mov	seg2,cs
	mov	seg3,cs

;Search environment for "WINDIR="
	mov	ax,es:[envseg]		;get segment of environment
	mov	ds,ax			;find environment
	push	cs
	pop	es			;find data
	mov	si,-1h			;set di just before environment
dir1:	inc	si			;point to next environment variable
	cmp	b [si],'W'		;test for start of WINDIR
	je	dir3			;found what looks like start
dir2:	cmp	w [si],0		;at end of environment yet
	jz	envend			;yes
	cmp	b [si],0		;end of variable statement
	jz	dir1			;found next variable
	inc	si			;try next character
	jmp	dir2			;keep looking
dir3:	cmp	[si+1],4E49h		;test for "IN"
	jne	dir2			;no match
	cmp	[si+3],4944h		;test for "DI"
	jne	dir2			;no match
	cmp	[si+5],3D52h		;test for "R="
	jne	dir2			;no match
	add	si,7			;found it, point to dir name
	lea	di,path			;where to copy it
dir4:	lodsb				;get character
	or	al,al			;is it end of directory name
	jz	dir5			;keep looking for end of environment
	stosb				;save character
	jmp	dir4			;copy whole name
dir5:	dec	si			;in case WINDIR= is at end of environment
	jmp	dir2

;By the time we are here -
;	si points to the end of the environment
;	di points to the end of the directory name for WIN.COM
;Now add "\WIN.COM" to directory name and get program name for
;WIN.COM to load, plus any command line arguments.
envend:	cmp	di,offset path		;was a path found
	jnz	env1			;yes
	add	di,8			;no, so point to end of default path
env1:	mov	w es:[di],575Ch		;add "\W"
	mov	w es:[di+2],4E49h	;add "IN"
	mov	w es:[di+4],432Eh	;add ".C"
	mov	w es:[di+6],4D4Fh	;add "OM"
	add	si,4			;point si to program name
	lea	di,cmdline		;command line to pass
	inc	di			;allow for command line size byte
env2:	lodsb				;get character
	or	al,al			;is it end of program name
	jz	prgend			;yes
	stosb				;save character
	inc	b es:[cmdline]		;count this character
	jmp	env2			;copy whole name
;Path to WIN.COM is now setup all that needs to be done is to
;delimit the command line, then throw away this crud and run WINDOWS.
prgend:	push	es
	pop	ds			;find data
	mov	w [di],0A0Dh		;add carriage return linefeed
	inc	b [cmdline]		;count delimiter
	inc	b [cmdline]
	jmp	loadwin			;now load WINDOWS

code	ends
	end	start
