%include "util.mac"
%include "icedump.inc"
%include "wiat.inc"
%include "options.inc"


global Parse_Option
global ON_TOGGLE_EXPERT_MODE.Emode
global OD_TOGGLE_EXPERT_MODE.Emode
global EmodeSub.IncDumpNum
global OT.OLastbutone
global OT.OBranch
global OT.OAll
global OT.OTraceSameProcess
global OT.OTraceChildProcess
global OT.OBreaknew
global OT.ONTsel

extern sdata
extern Parser.return
extern Parser.error
extern Parse_ScreenDump.EmodeFileName
extern Parse_ScreenDump.EmodeExtPtr
extern Parse_ScreenDump.modeMsg
extern Parse_Dump.EmodeFileName
extern Parse_Dump.EmodeExtPtr
extern Bhrama_Struc
extern rOptions


bits 32


;-------------------------------------------------------------------------------
; OPTION (Execute command for help)
;-------------------------------------------------------------------------------
segment _LTEXT
Parse_Option:				; OPTION parser for sub-sub commands
	call	[pSkipWhiteSpace]	; skip to subcommand
	jz	Option_HELP

	lodsb				; get subcommand
	and	al,0x5F			; upcase

	cmp	al,'P'
	jz	near O_PEDUMP

	cmp	al,'B'
	jz	near O_BHRAMA

	cmp	al,'N'
	jz	near O_SCREENDUMP

	cmp	al,'D'
	jz	near O_MEMDUMP

	cmp	al,'T'
	jz	near O_TRACE

Option_HELP:
	mov	ebp,[pPrintToCommandWindow]
	mov	esi, .TableHelp

.LoopDisplay:
	lodsd
	test	eax, eax
	jz	near Parser.return

	push	esi
	mov	esi, eax
	call	ebp
	pop	esi
	jmp	.LoopDisplay


segment _LDATA
.TableHelp:	dd	.helpON
	dd	.helpONf
	dd	.helpONd
	dd	.helpONv

	dd	.helpOD
	dd	.helpODf
	dd	.helpODd
	dd	.helpODv

	dd	.helpOB
	dd	.helpOBR
	dd	.helpOBS
	dd	.helpOBH
	dd	.helpOBI

	dd	.helpOP
	dd	.helpOPV
	dd	.helpOPP
	dd	.helpOPO
	dd	.helpOPB
	dd	.helpOPH
	dd	.helpOPI
	dd	.helpOPC
	dd	.helpOPK
	dd	.helpOPA
	dd	.helpOPR
	dd	.helpOPG
%if 0
	dd	.helpOPF	; hidden feature :)
	dd	.helpOPX
%endif
	dd	.helpOT
	dd	.helpOTL
	dd	.helpOTB
	dd	.helpOTA
	dd	.helpOTT
	dd	.helpOTP
	dd	.helpOTN
	dd	.helpOTE
	dd	0

.helpON:	db 'OPTION N              - toggle screendump expert mode on/off',0
.helpONf:	db 'OPTION N F <filename> - alter base filename',0
.helpONd:	db 'OPTION N D <number>   - alter current dump number',0
.helpONv:	db 'OPTION N V            - show current screendump options',0

.helpOD:	db 'OPTION D              - toggle memdump expert mode on/off',0
.helpODf:	db 'OPTION D F <filename> - alter base filename',0
.helpODd:	db 'OPTION D D <number>   - alter current dump number',0
.helpODv:	db 'OPTION D V            - show current memdump options',0
;.helpODl:	db 'OPTION D L <number>   - alter default dump length',0

.helpOB:	db 'OPTION B              - Print current state of BHRAMA options',0
.helpOBR:	db 'OPTION B rR           - Recompute PE Object size off/on',0
.helpOBS:	db 'OPTION B sS           - PE structure Reorganize off/on',0
.helpOBH:	db 'OPTION B hH           - Restore PE header off/on',0
.helpOBI:	db 'OPTION B 0..3         - Import mode [0..3]',0

.helpOP:	db 'OPTION P              - Print current state of PEDUMP options',0
.helpOPV:	db 'OPTION P vV           - Update PE Virtual Object size off/on',0
.helpOPP:	db 'OPTION P pP           - Update PE Physical Object size off/on',0
.helpOPO:	db 'OPTION P oO           - PE structure optimisation off/on',0
.helpOPB:	db 'OPTION P bB           - Automatic PE header rebuilding off/on',0
.helpOPI:	db 'OPTION P I0..4        - Import mode [0..4]',0
.helpOPH:	db 'OPTION P H0..7        - Reload PE header from disk [0..7]',0
.helpOPC:	db 'OPTION P cC           - Import caving attempt off/on',0
.helpOPK:	db 'OPTION P kK           - Compute ImageSize off/on',0
.helpOPA:	db 'OPTION P aA           - Use alternative scanner off/on',0
.helpOPR:	db 'OPTION P R0..2        - Code scanner mode [0..2]',0
.helpOPG:	db 'OPTION P gG           - Glue/Coagulate resources',0
.helpOPF:	db 'OPTION P fF           - Detect old relocations',0
.helpOPX:	db 'OPTION P xX           - Extra reduction of header',0

.helpOT:	db 'OPTION T              - Print current state of TRACE options',0
.helpOTL:	db 'OPTION T lL           - Print last but one address before break off/on',0
.helpOTB:	db 'OPTION T bB           - Print branch addresses off/on',0
.helpOTA:	db 'OPTION T aA           - Print all traced addresses off/on',0
.helpOTT:	db 'OPTION T pP           - Trace new threads in the same process off/on',0
.helpOTP:	db 'OPTION T cC           - Trace threads in child processes off/on',0
.helpOTN:	db 'OPTION T nN           - Break on new threads off/on',0
.helpOTE:	db 'OPTION T eE           - Emulate NT win32 selectors off/on',0


segment _LTEXT
O_TRACE:
	call	[pSkipWhiteSpace]	; skip to real params
	jz	.status

.next:
	lodsb
	cmp	al,0
	jnz	.l

.status:
	mov	esi,OT.msgLOGLASTBUTONE
	call	[pPrintToCommandWindow]

	mov	esi,OT.msgLOGBRANCH
	call	[pPrintToCommandWindow]

	mov	esi,OT.msgLOGALL
	call	[pPrintToCommandWindow]

	mov	esi,OT.msgTRACESAMEPROCESS
	call	[pPrintToCommandWindow]

	mov	esi,OT.msgTRACECHILDPROCESS
	call	[pPrintToCommandWindow]

	mov	esi,OT.msgBREAKNEW
	call	[pPrintToCommandWindow]

	mov	esi,OT.msgNTSEL
	call	[pPrintToCommandWindow]

	jmp	Parser.return

.l:
	cmp	al,'l'
	jnz	.L

	mov	byte [OT.OLastbutone],'D'
	jmp	short .next

.L:
	cmp	al,'L'
	jnz	.b

	mov	byte [OT.OLastbutone],'E'
	jmp	short .next

.b:
	cmp	al,'b'
	jnz	.B

	mov	byte [OT.OBranch],'D'
	jmp	.next

.B:
	cmp	al,'B'
	jnz	.a

	mov	byte [OT.OBranch],'E'
	jmp	.next

.a:
	cmp	al,'a'
	jnz	.A

	mov	byte [OT.OAll],'D'
	jmp	.next

.A:
	cmp	al,'A'
	jnz	.p

	mov	byte [OT.OAll],'E'
	jmp	.next

.p:
	cmp	al,'p'
	jnz	.P

	mov	byte [OT.OTraceSameProcess],'D'
	jmp	.next

.P:
	cmp	al,'P'
	jnz	.c

	mov	byte [OT.OTraceSameProcess],'E'
	jmp	.next

.c:
	cmp	al,'c'
	jnz	.C

	mov	byte [OT.OTraceChildProcess],'D'
	jmp	.next

.C:
	cmp	al,'C'
	jnz	.n

	mov	byte [OT.OTraceChildProcess],'E'
	jmp	.next

.n:
	cmp	al,'n'
	jnz	.N

	mov	byte [OT.OBreaknew],'D'
	jmp	.next

.N:
	cmp	al,'N'
	jnz	.e

	mov	byte [OT.OBreaknew],'E'
	jmp	.next

.e:
	cmp	al,'e'
	jnz	.E

	mov	byte [OT.ONTsel],'D'
	jmp	.next

.E:
	cmp	al,'E'
	jnz	near .next

	mov	byte [OT.ONTsel],'E'
	jmp	.next


segment _LDATA
OT:
.msgLOGLASTBUTONE:	db 'Print last but one address (Enabled/Disabled): '
.OLastbutone:		db 'E',0
.msgLOGBRANCH:		db 'Print branch addresses (Enabled/Disabled): '
.OBranch:		db 'D',0
.msgLOGALL:		db 'Print all traced addresses (Enabled/Disabled): '
.OAll:			db 'D',0
.msgTRACESAMEPROCESS:	db 'Trace new threads in the process (Enabled/Disabled): '
.OTraceSameProcess:	db 'E',0
.msgTRACECHILDPROCESS:	db 'Trace threads in child processes (Enabled/Disabled): '
.OTraceChildProcess:	db 'D',0
.msgBREAKNEW:		db 'Break on new threads (Enabled/Disabled): '
.OBreaknew:		db 'D',0
.msgNTSEL:		db 'Emulate NT win32 selectors (Enabled/Disabled): '
.ONTsel:		db 'D',0


segment _LTEXT
O_PEDUMP:
	call	[pSkipWhiteSpace]	; skip to real params
	jz	.status

.next:
	lodsb
	cmp	al,0
	jnz	near .v

.status:
	mov	esi,OP.msgVSIZE
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgPSIZE
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgPESHRINK
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgBUILD
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgCAVE
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgRELOAD
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgCOMPUTE
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgIAT
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgIMPORT
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgRANGE
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgRSRC
	call	[pPrintToCommandWindow]

%if 0
; hidden feature :)
	mov	esi,OP.msgReloc
	call	[pPrintToCommandWindow]

	mov	esi,OP.msgReduce
	call	[pPrintToCommandWindow]
%endif

	jmp	Parser.return

.v:
	cmp	al,'v'
	jnz	.V

	and	byte [rOptions+RebuildOptions.UpdateVSize], 0xFE
	mov	byte [OP.OVSizemode],'D'
	jmp	.next

.V:
	cmp	al,'V'
	jnz	.p

	or	byte [rOptions+RebuildOptions.UpdateVSize], 1
	mov	byte [OP.OVSizemode],'E'
	jmp	.next

.p:
	cmp	al,'p'
	jnz	.P

	and	byte [rOptions+RebuildOptions.UpdatePSize], 0xFE
	mov	byte [OP.OPSizemode],'D'
	jmp	.next

.P:
	cmp	al,'P'
	jnz	.o

	or	byte [rOptions+RebuildOptions.UpdatePSize], 1
	mov	byte [OP.OPSizemode],'E'
	jmp	.next

.o:
	cmp	al,'o'
	jnz	.O

	and	byte [rOptions+RebuildOptions.ShrinkPE], 0xFE
	mov	byte [OP.OShrinkmode],'D'
	jmp	.next

.O:
	cmp	al,'O'
	jnz	.c

	or	byte [rOptions+RebuildOptions.ShrinkPE], 1
	mov	byte [OP.OShrinkmode],'E'
	jmp	.next

.c:
	cmp	al,'c'
	jnz	.C

	and	byte [rOptions+RebuildOptions.CaveImport], 0xFE
	mov	byte [OP.OCavemode],'D'
	jmp	.next

.C:
	cmp	al,'C'
	jnz	.b

	or	byte [rOptions+RebuildOptions.CaveImport], 1
	mov	byte [OP.OCavemode],'E'
	jmp	.next

.b:
	cmp	al,'b'
	jnz	.B

	and	byte [rOptions+RebuildOptions.BuildSection], 0xFE
	mov	byte [OP.OBuildmode],'D'
	jmp	.next

.B:
	cmp	al,'B'
	jnz	.k

	or	byte [rOptions+RebuildOptions.BuildSection], 1
	mov	byte [OP.OBuildmode],'E'
	jmp	.next
.k:
	cmp	al,'k'
	jnz	.K

	and	byte [rOptions+RebuildOptions.ComputeImage], 0xFE
	mov	byte [OP.OCompute],'D'
	jmp	.next

.K:
	cmp	al,'K'
	jnz	.a

	or	byte [rOptions+RebuildOptions.ComputeImage], 1
	mov	byte [OP.OCompute],'E'
	jmp	.next
.a:
	cmp	al,'a'
	jnz	.A

	and	byte [rOptions+RebuildOptions.OldScanner], 0xFE
	mov	byte [OP.OIAT],'D'
	jmp	.next
.A:
	cmp	al,'A'
	jnz	.g

	or	byte [rOptions+RebuildOptions.OldScanner], 1
	mov	byte [OP.OIAT],'E'
	jmp	.next
.g:
	cmp	al,'g'
	jnz	.G

	and	byte [rOptions+RebuildOptions.RestoreRsrc], 0xFE
	mov	byte [OP.ORSRC],'D'
	jmp	.next
.G:
	cmp	al,'G'
	jnz	.f

	or	byte [rOptions+RebuildOptions.RestoreRsrc], 1
	mov	byte [OP.ORSRC],'E'
	jmp	.next
.f:
	cmp	al,'f'
	jnz	.F

	and	byte [rOptions+RebuildOptions.RestoreReloc], 0xFE
	mov	byte [OP.OReloc],'D'
	jmp	.next
.F:
	cmp	al,'F'
	jnz	.x

	or	byte [rOptions+RebuildOptions.RestoreReloc], 1
	mov	byte [OP.OReloc],'E'
	jmp	.next
.x:
	cmp	al,'x'
	jnz	.X

	and	byte [rOptions+RebuildOptions.ReduceHeader], 0xFE
	mov	byte [OP.OReduce],'D'
	jmp	.next
.X:
	cmp	al,'X'
	jnz	.R

	or	byte [rOptions+RebuildOptions.ReduceHeader], 1
	mov	byte [OP.OReduce],'E'
	jmp	.next
.R:
	cmp	al,'r'
	jz	@F

	cmp	al,'R'
	jnz	.I

@@
	mov	al,[esi]
	cmp	al,'0'
	jb	near .next

	cmp	al,'2'
	ja	near .next

	inc	esi
	mov	[OP.ORangeCode], al
	sub	al, '0'
	mov	[rOptions+RebuildOptions.CodeMode], al
	jmp	.next
.I:
	cmp	al,'i'
	jz	@F

	cmp	al,'I'
	jnz	.H

@@
	mov	al,[esi]
	cmp	al,'0'
	jb	near .next

	cmp	al,'4'
	ja	near .next

	inc	esi
	mov	[OP.OImportmode], al
	sub	al, '0'
	mov	[rOptions+RebuildOptions.ImportMode], al
	jmp	.next

.H:
	cmp	al, 'h'
	jz	@F

	cmp	al, 'H'
	jnz	near .next

@@
	mov	al,[esi]
	cmp	al,'0'
	jb	near .next

	cmp	al,'7'
	ja	near .next

	inc	esi
	mov	[OP.OReloadmode], al
	sub	al, '0'
	mov	[rOptions+RebuildOptions.ReloadHeader], al
	jmp	.next


segment _LDATA
OP:
.msgVSIZE:		db 'Virtual size update (Enabled/Disabled): '
.OVSizemode:		db 'E',0
.msgPSIZE:		db 'Physical size update (Enabled/Disabled): '
.OPSizemode:		db 'E',0
.msgCAVE:		db 'Import caving attempt (Enabled/Disabled): '
.OCavemode:		db 'D',0
.msgBUILD:		db 'PE header auto-rebuilding (Enabled/Disabled): '
.OBuildmode:		db 'E',0
.msgRELOAD:		db 'PE header reload mode : '
.OReloadmode:		db '0',0
.msgPESHRINK:		db 'PE Structure Optimization (Enabled/Disabled): '
.OShrinkmode:		db 'E',0
.msgCOMPUTE:		db 'Compute ImageSize (Enabled/Disabled): '
.OCompute:		db 'D',0
.msgIAT:		db 'Alternative Scanner (Enabled/Disabled): '
.OIAT:			db 'E',0
.msgRSRC:		db 'Glue/Coagulate resource (Enabled/Disabled): '
.ORSRC:			db 'D',0
.msgReloc:		db 'Detect old relocation table (Enabled/Disabled): '
.OReloc:		db 'D',0
.msgReduce:		db 'Extra header reduction (Enabled/Disabled): '
.OReduce:		db 'D',0
.msgIMPORT:		db 'Actual Import mode : '
.OImportmode:		db '3',0
.msgRANGE:		db 'Actual Code mode : '
.ORangeCode:		db '1',0


segment _LTEXT
O_BHRAMA:
	call	[pSkipWhiteSpace]	; skip to real params
	jz	.status

.next:
	lodsb				; get subcommand
	cmp	al,0
	jnz	.r

.status:
	mov	esi,OB.msgOBJECTSIZE
	call	[pPrintToCommandWindow]

	mov	esi,OB.msgPESHRINK
	call	[pPrintToCommandWindow]

	mov	esi,OB.msgHEADER
	call	[pPrintToCommandWindow]

	mov	esi,OB.msgIMPORT
	call	[pPrintToCommandWindow]

	jmp	Parser.return

.r:
	cmp	al,'r'
	jnz	.R

	and	byte [Bhrama_Struc+BhramaComStruc.OptL3+1], 0xFE
	mov	byte [OB.OSizemode],'D'
	jmp	short .next

.R:
	cmp	al,'R'
	jnz	.s

	or	byte [Bhrama_Struc+BhramaComStruc.OptL3+1], 1
	mov	byte [OB.OSizemode],'E'
	jmp	short .next

.s:
	cmp	al,'s'
	jnz	.S

	and	byte [Bhrama_Struc+BhramaComStruc.OptL3], 0xFE
	mov	byte [OB.OShrinkmode],'D'
	jmp	short .next

.S:
	cmp	al,'S'
	jnz	.h

	or	byte [Bhrama_Struc+BhramaComStruc.OptL3], 1
	mov	byte [OB.OShrinkmode],'E'
	jmp	.next

.h:
	cmp	al,'h'
	jnz	.H

	and	byte [Bhrama_Struc+BhramaComStruc.OptL4+2], 0xFE
	mov	byte [OB.OHeadermode],'D'
	jmp	.next

.H:
	cmp	al,'H'
	jnz	.03

	or	byte [Bhrama_Struc+BhramaComStruc.OptL4+2], 1
	mov	byte [OB.OHeadermode],'E'
	jmp	.next

.03:
	cmp	al,'0'
	jb	near .next

	cmp	al,'3'
	ja	near .next

	mov	[OB.OImportmode],al
	sub	al,'0'
	mov	[Bhrama_Struc+BhramaComStruc.OptL4+1],al
	jmp	.next


segment _LDATA
OB:
.msgOBJECTSIZE:		db 'PE Object size recomputation (Enabled/Disabled): '
.OSizemode:		db 'E',0
.msgPESHRINK:		db 'PE Structure Optimization (Enabled/Disabled): '
.OShrinkmode:		db 'E',0
.msgHEADER:		db 'PE Header restoration (Enabled/Disabled): '
.OHeadermode:		db 'D',0
.msgIMPORT:		db 'Actual Import mode : '
.OImportmode:		db '3',0


segment _LTEXT
O_SCREENDUMP:
	call	[pSkipWhiteSpace]	; skip to real params
	jz	ON_TOGGLE_EXPERT_MODE

	lodsb				; get subcommand
	and	al,0x5F			; upcase

	cmp	al,'D'
	jz	ON_SET_DUMP_NUMBER

	cmp	al,'F'
	jz	ON_SET_DUMP_BASEFILENAME

	cmp	al,'V'
	jz	ON_VIEW_SCREENDUMP_OPTIONS

	jmp	Option_HELP

ON_TOGGLE_EXPERT_MODE:
	xor	byte [ON_TOGGLE_EXPERT_MODE.Emode],1

	mov	esi,.msgEXPERT_MODE
	call	[pPrintToCommandWindow]

	jmp	Parser.return


segment _LDATA
.msgEXPERT_MODE:db 'Screendump expert mode (Enabled/Disabled): '
.Emode:		db 'D',0


segment _LTEXT
ON_SET_DUMP_NUMBER:
	call	[pSkipWhiteSpace]	;skip to real params
	jz	near Option_HELP

	mov	edi,Parse_ScreenDump.EmodeFileName
	add	edi,[Parse_ScreenDump.EmodeExtPtr]
	call	EmodeSub.SetDumpNum

	jmp	Parser.return


ON_SET_DUMP_BASEFILENAME:
	call	[pSkipWhiteSpace]	; skip to real params
	jz	near Option_HELP

	mov	edi,Parse_ScreenDump.EmodeFileName
	mov	ebx,Parse_ScreenDump.EmodeExtPtr	; num ptr
	call	EmodeSub.SetBaseFileName

	jmp	near Parser.return


ON_VIEW_SCREENDUMP_OPTIONS:
	mov	esi,ON_TOGGLE_EXPERT_MODE.msgEXPERT_MODE
	mov	ebp,[pPrintToCommandWindow]
	call	ebp

	mov	esi,Parse_ScreenDump.EmodeFileName
	call	ebp

	mov	esi,Parse_ScreenDump.modeMsg
	call	ebp

	jmp	Parser.error


O_MEMDUMP:
	call	[pSkipWhiteSpace]	; skip to real params
	jz	OD_TOGGLE_EXPERT_MODE

	lodsb				; get subcommand
	and	al,0x5F			; upcase

	cmp	al,'D'
	jz	near OD_SET_DUMP_NUMBER

	cmp	al,'F'
	jz	near OD_SET_DUMP_BASEFILENAME

	cmp	al,'V'
	jz	near OD_VIEW_DUMP_OPTIONS

	jmp	Option_HELP


OD_TOGGLE_EXPERT_MODE:
	xor	byte [OD_TOGGLE_EXPERT_MODE.Emode],1

	mov	esi,.msgEXPERT_MODE
	call	[pPrintToCommandWindow]

	jmp	near Parser.return


segment _LDATA
.msgEXPERT_MODE:db 'Memdump expert mode (Enabled/Disabled): '
.Emode:		db 'D',0


segment _LTEXT
OD_SET_DUMP_NUMBER:
	call	[pSkipWhiteSpace]	;skip to real params
	jz	near Option_HELP

	mov	edi,Parse_Dump.EmodeFileName
	add	edi,[Parse_Dump.EmodeExtPtr]
	call	EmodeSub.SetDumpNum

	jmp	Parser.return


OD_SET_DUMP_BASEFILENAME:
	call	[pSkipWhiteSpace]	; skip to real params
	jz	near Option_HELP

	mov	edi,Parse_Dump.EmodeFileName
	mov	ebx,Parse_Dump.EmodeExtPtr	; num ptr
	call	EmodeSub.SetBaseFileName

	jmp	Parser.return


OD_VIEW_DUMP_OPTIONS:
	mov	ebp,[pPrintToCommandWindow]

	mov	esi,OD_TOGGLE_EXPERT_MODE.msgEXPERT_MODE
	call	ebp

	mov	esi,Parse_Dump.EmodeFileName
	call	ebp

	jmp	Parser.error


; Expert/Auto Mode subroutines

EmodeSub:
.SetDumpNum:	; EDI = number space in filename, ESI = param
	push	esi
	mov	ecx,OPT_EMODE_NUMLEN
	mov	edx,ecx

.sdn_loop1:
	lodsb			; validate the param
	cmp	al,'0'
	jb	.sdn_store0

	cmp	al,'9'
	ja	.sdn_store0

	loop	.sdn_loop1

.sdn_store0:
	pop	esi
	sub	edx,ecx		; how many positions are actually valid
	or	ecx,ecx
	jz	.sdn_storeN

	mov	al,'0'
	rep	stosb		; 0-prepend if the number is smaller than 3-pos

.sdn_storeN:
	mov	ecx,edx
	jecxz	.sdn_end	; do we have ANY valid numbers ? =)

	rep	movsb

.sdn_end:
	dec	edi		; need to dec once due to the auto-inc on dump
	dec	byte [edi]
	retn


.SetBaseFileName:	; ESI = params, EDI = filename buf, EBX = num ptr
	push	edi
	xor	ecx,ecx		; get length

.sbf_loop1:
	lodsb
	cmp	al,'*'
	jne	.sbf_notstar

.sbf_star:
	or	ebx,ebx		; check if numptr already stored
	jz	.sbf_noovfl

	mov	[ebx],ecx	; set number ptr
	xor	ebx,ebx		; ptr set, flag it
	push	eax
	push	ecx
	mov	ecx,OPT_EMODE_NUMLEN - 1
	mov	al,'0'		; store init dump number, ie '000'
	rep	stosb
	dec	eax
	stosb
	pop	ecx
	pop	eax
	jmp	.sbf_noovfl

.sbf_notstar:
	inc	ecx
	cmp	ecx,byte OPT_EMODE_FILENAMELEN
	jbe	.sbf_noovfl

	xor	eax,eax		; filename length limit reached
	jmp	.sbf_star	; store the number ptr and init

.sbf_noovfl:
	or	al,al
	jz	.sbf_zero

	cmp	al,'*'
	jz	.sbf_loop1

	stosb
	jmp	.sbf_loop1

.sbf_zero:
	or	ebx,ebx		; if there was no * in the filename
	jnz	.sbf_star	; append dump number
	stosb			; store 0-term

;	cmp	ecx,byte OPT_EMODE_FILENAMELEN
;	jbe	.sbf_nameok

;	mov	esi,.helpOFE	; error - filename too long
;	call	[pPrintToCommandWindow]

.sbf_nameok:
	pop	esi
	call	[pPrintToCommandWindow]
	retn


;segment _LDATA
;.helpOFE:	db 'Filename is too long and was trimmed. Edit source and recompile for larger filename buffer.',0


segment _LTEXT
.IncDumpNum:	; EDI = dump number ptr
	mov	ecx,OPT_EMODE_NUMLEN
	add	edi,ecx
	dec	edi		; now we got a ptr to the last digit
	mov	esi,edi
	std			; and going in reverse
	mov	ah,1

.idn_loop1:
	lodsb
	add	al,ah
	mov	ah,1		; have to set ah=0
	dec	ah		; and clear AF
	aaa
	or	al,0x30
	stosb
	loop	.idn_loop1
	cld			; the rest of the code assumes DF=0 =)
	retn

