This program sucessfully stores the filename from the command line
into SOURCE_FILE. But when I incorporated it into shred2.asm (next) it doesn't
work. Thanks.

; test.asm Com file
; store command line
;
model tiny
code

org 100h

BEGIN:
jmp parse

file db 'filename' ; marker right before where
SOURCE_FILE db 128 dup (0);filename is stored
TARGET_PATH db 128 dup (0)

VALID_IN db 'abcdefghijklmnopqrstuvwxyz,;=',9
VALID_OUT db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
VALID_NUM equ $ - VALID_OUT + 1

NO_PARMS db 10,10,13,'Nothing on command line. ',10,13,13,'$'

OK db 'File found.$'

parse: ; Parse command line

mov si,80h ; PSP parameter byte count pointer
mov cl, ; Move byte count to CL
xor ch,ch ; Zero CH
jcxz NO_PARMS_PASSED; If CX is zero, no parameters
mov dx,cx ; Save byte count in dx
inc si ; Point to parameter area
mov di,si ; Copy SI to DI for cleanup routine
cld ; Set direction flag to forward

CLEAN_PARMS: ; Change valid delimiters to blanks, lower to
; upper case

lodsb ; Load each character to AL
push di ; Save DI on stack
mov di,offset VALID_IN; Point to table of valid inputs
push cx ; Save CX on stack
mov cx,VALID_NUM ; Set CX to number of inputs

; to look for
repne scasb ; See if any are in AL
jcxz CLEAN_END ; If not, change nothing
mov bx,VALID_NUM; Set up BX to point to valid output
sub bx,cx ; This will leave BX one off
mov al,VALID_OUT ; Load the valid output to AL

CLEAN_END:

pop cx ; Restore CX
pop di ; Restore DI
stosb ; Store modified AL back to PSP
loop CLEAN_PARMS ; Loop until CX is zero

mov cx,dx ; Restore number of bytes in PSP to CX
mov dx,2 ; Set DX to look for up to 2 parameters
mov bx,offset SOURCE_FILE; Set BX to address of 1st
; parameter
mov al,' ' ; Set up to scan for first non-blank
mov di,81h ; Set DI to PC-DOS parameter pointer

FIND_PARMS ; Start looking for parameters

repe scasb ; Scan while blanks
mov si,di ; Set SI to second non-blank byte
dec si ; Adjust it to first non-blank byte
inc cx ; Adjust CX to compensate
jcxz PARMS_LOADED ; If CX is zero, no parameters left
mov di,bx ; Set DI to parameter hold area
mov ax,cx ; Store CX to first byte of hold area
stosb ; DI is adjusted to second byte here
STORE:
lodsb ; Load each byte to AL
cmp al,' ' ; Is it a blank?
jz END_STORE ; Yes, end of this parameter

stosb ; No, store the byte to hold area

END_STORE:

loopnz STORE ; Keep looking
sub ,cx ; Store number of bytes in each
jcxz PARMS_LOADED ; If CX is zero, no more parameters
dec byte ptr ; parameter to first byte of hold area
mov di,si ; Set up to scan for next non-blank
dec di ; Adjust DI to point to the blank
inc cx ; Adjust CX to compensate
dec dx ; Decrement DX counter
cmp dx,0 ; Is DX zero?
jz PARMS_LOADED ; Yes, all expected parameters loaded
add bx,128 ; No, point to next part of hold
area
jmp FIND_PARMS ; Go back and look for more

PARMS_LOADED: ; All parameters are loaded
jmp short finish

NO_PARMS_PASSED: ; Exit with an error if there

lea dx, NO_PARMS ; are no parameters passed

ERROR_EXIT: ; Print Error Message and Exit

mov ah,9 ; Display error header
int 21h
mov ax,4c01h
int 21h
finish:
mov ah,9
lea dx,OK
int 21h
mov ax,4c00h
int 21h
end begin

; SHRED2.ASM Ver 1e 8/24/03 Andy Kennedy 1996 - 2003
;
; Works through Win 98
; Supports Long Filenames
;
; Overwrite a file with random bytes,
; truncates it to zero bytes,
; set file time and date to 12:59:58 pm 1/1/80,
; renames it and then deletes it.
; Single files only. (For Safety)
;
; Use full path when not in current directory Ex. a:\test
;
; Works across drives, handles periods in the path names 1a 10/8/96
; 1b 5/2002
; ***** FILE is NOT recoverable !!!! **** 1c 9/02
; 1d 3/29/03
; 1e 8/24/03
model small
stack 200h

data? ; can contain ONLY un-initialized data

random db 64000 dup(?)

data

handle dw ?
file_size dd ?
name_size dw ?

prompt db 13,10,13,10,9,'File Shredder Ver. 1e',13,10
db 13,10,'This file will NOT be recoverable !!',13,10
db 13,10,'File name to SHRED --> $'

not_there db 13,10,13,10,'File not present.',13,10,'$'
emsg2 db 13,10,13,10,'Error moving file pointer.',13,10,'$'
emsg3 db 13,10,13,10,'Error writing to file.',13,10,'$'

NO_PARMS db 13,10,13,10,'Nothing on command line.',13,10,13,10,'$'
VALID_IN db 'abcdefghijklmnopqrstuvwxyz,;=',9
VALID_OUT db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
VALID_NUM equ $ - VALID_OUT + 1

done_msg db 13,10,13,10,'File has been shredded.',13,10,'$'
prescence db 'Andrew Kennedy 2003'

n db 'file'
file_name db 128 dup(?) ; DOS maximum path length
storage db 150 dup(?)
eraser_name db '????????.',0

code

start:
mov ah,15 ; clear the screen
int 10h
mov ah,0
int 10h


mov ax,@data
mov ds,ax
mov es,ax ; need for LFN functions

parse: ; Parse command line

mov si,80h ; PSP parameter byte count pointer
mov cl, ; Move byte count to CL
xor ch,ch ; Zero CH
jcxz NO_PARMS_PASSED ; If CX is zero, there are no parameters
mov dx,cx ; Save byte count in dx
inc si ; Point to parameter area
mov di,si ; Copy SI to DI for cleanup routine
cld ; Set direction flag to forward

CLEAN_PARMS: ; Change valid delimiters to blanks, lower to upper case

lodsb ; Load each character to AL
push di ; Save DI on stack
mov di,offset VALID_IN ; Point to table of valid inputs
push cx ; Save CX on stack
mov cx,VALID_NUM ; Set CX to number of inputs to look
for
repne scasb ; See if any are in AL
jcxz CLEAN_END ; If not, change nothing
mov bx,VALID_NUM ; Set up BX to point to valid output
sub bx,cx ; This will leave BX one off
mov al,VALID_OUT ; Load the valid output to AL

CLEAN_END:

pop cx ; Restore CX
pop di ; Restore DI
stosb ; Store modified AL back to PSP
loop CLEAN_PARMS ; Loop until CX is zero

mov cx,dx ; Restore number of bytes in PSP to
CX
mov dx,2 ; Set DX to look for up to 2 parameters
mov bx,offset file_name ; Set BX to address of 1st parameter
mov al,' ' ; Set up to scan for first non-blank
mov di,81h ; Set DI to PC-DOS parameter pointer

FIND_PARMS: ; Start looking for parameters, load to program storage

repe scasb ; Scan while blanks
mov si,di ; Set SI to second non-blank byte
dec si ; Adjust it to first non-blank byte
inc cx ; Adjust CX to compensate
jcxz PARMS_LOADED ; If CX is zero, no parameters left
mov di,bx ; Set DI to parameter hold area
mov ax,cx ; Store CX to first byte of hold area
stosb ; DI is adjusted to second byte here
STORE:
lodsb ; Load each byte to AL
cmp al,' ' ; Is it a blank?
jz END_STORE ; Yes, end of this parameter

stosb ; No, store the byte to hold area

END_STORE:

loopnz STORE ; Keep looking
sub ,cx ; Store number of bytes in each
jcxz PARMS_LOADED ; If CX is zero, no more parameters
dec byte ptr ; parameter to first byte of hold area
mov di,si ; Set up to scan for next non-blank
dec di ; Adjust DI to point to the blank
inc cx ; Adjust CX to compensate
dec dx ; Decrement DX counter
cmp dx,0 ; Is DX zero?
jz PARMS_LOADED ; Yes, all expected parameters loaded
add bx,128 ; No, point to next part of hold
area
jmp FIND_PARMS ; Go back and look for more

PARMS_LOADED: ; All parameters are loaded
jmp short change
int 3
NO_PARMS_PASSED: ; Exit with an error if there

lea dx, NO_PARMS ; are no parameters passed
jmp ERROR_EXIT

; Change any read-only attribute

change:
lea dx,file_name + 2
mov ax,4301h
mov cx,00000000b ; remove read-only attribute
int 21h

;INT 21 - Windows95 - LONG FILENAME - CREATE OR OPEN FILE
; AX = 716Ch
; BX = access mode and sharing flags (see #01782,also AX=6C00h);
; CX = attributes
; DX = action (see #01781)
; DS:SI -> ASCIZ filename

mov ax,716Ch ; create file
xor cx,cx ; file attributes

; file access modes (bits)
; 000 read-only
; 001 write-only
; 010 read-write
; 100 read-only, do not modify file's last-access time

mov bx,2 ; access mode (R/W)
mov dx,2 ; open file
lea si,file_name + 2 ; sets the file name
int 21h
mov ,ax ; Save file handle
jnc short get_size ; No errors, go on
no_file:
mov dx,offset not_there; Get error message
jmp error ; and go display/exit
get_size:
mov ax,4202h ; Set file pointer
mov bx, ; for this file
xor cx,cx ; relative to end of file
xor dx,dx ; offset 0 bytes
int 21h
jnc save_size
err2:
mov dx,offset emsg2 ; Get error message
jmp error ; and go display/exit

save_size:
mov word ptr ,ax ; Save low word of
file size
mov word ptr ,dx ; Save high word

mov ax,4200h ; Move file pointer
mov bx, ; for this file
xor cx,cx ; relative to beginning of file
xor dx,dx ; offset 0 bytes
int 21h
jc err2 ; Errors: go handle

next_bunch:
mov cx,64000 ; Assume 64,000 bytes or more
left
; to do

sub word ptr ,cx ; Is there ? - subtract
it
sbb word ptr ,0 ; from saved file size

jae wipe ; There were 64,000 bytes or

; more left

mov cx,word ptr ; Get number of bytes left
add cx,64000 ; back CX (undo subtraction)

wipe:
mov ah,40h ; Write file
mov bx, ; Handle
mov dx,offset random ; Write the random bytes
int 21h
jnc check_size ; No errors, go on

err3:
mov dx,offset emsg3 ; Get appropriate error message
jmp error ; and go display/exit

check_size:
cmp ax,cx
jnz err3
cmp ax,64000 ; Full 64,000 bytes written,
je next_bunch ; yes, go check for more

mov bx, ; close file
mov ah,3eh
int 21h

; Truncate file to zero bytes

mov ah,3ch ; truncate file to zero bytes
mov cx,0
mov dx,offset file_name + 2
int 21h

mov bx, ; close file
mov ah,3eh
int 21h

; Store the path

scan:
lea si,
xor cx,cx
mov di,si
mov cx,

mov al,'\'
add di,cx
std ; scan from right to left
dec di
repne scasb
jnz short no_path ; No slash is present
add cx,1 ;

no_path:
mov di,offset storage
cld ; change directions and scan
rep movsb ; from left to right
mov al,00
stosb ; make path ASCIZ

; Add on eraser_name to end of storage

add_eraser:

mov cx,
mov si,cx
lea di,storage
mov al,00 ; stops at the byte after the "00"
repnz scasb
dec di ; backup one

xor cx,cx
mov si,offset eraser_name
mov cx,9 ; # of characters
rep movsb

; Rename and delete file (LFN)

rename:
mov dx,offset file_name + 2 ; old file name
mov di,offset storage
mov ax,7156h ; LFN support
int 21h

; Change file date and time

mov ax,716Ch ; open file
xor cx,cx ; file attributes

; file access modes (bits) FOR BX Register
; 000 read-only
; 001 write-only
; 010 read-write
; 100 read-only, do not modify file's last-access time
; set bit 14 - commit file after every write operation

mov bx,100000000000010b ; access mode (R/W) and commit
; file after every write

; Bitfields for Windows 95 long-name open action: DX Register
; Bit(s) Description (Table 01781)
; 0 open file (fail if file does not exist)
; 1 truncate file if it already exists (fail if file does not exist)
; 4 create new file if file does not already exist (fail if exists)
; Note: the only valid combinations of multiple flags are bits 4&0 and 4&1

mov dx,1 ; open file
lea si,storage ; sets the file name
int 21h
mov bx,ax ; save file handle
push bx

mov ax,5701h ; change file date
; BITS 5-10 are minutes, 11-15 are hours
mov cx,677dh ; 12:59:58 pm 110011101111101b
;
; BITS 0-4 are day, 5-8 are month, 9-15 (year -
1980)
mov dx,021h ; 1/1/80 0000000000100001b
int 21h

pop bx

;INT 21 U - DOS 4.0+ - COMMIT FILE
; AH = 6Ah
; BX = file handle

mov ah,6ah
int 21h
int 3

mov ah,3eh ; close file
int 21h

; INT 21 - Windows95 - LONG FILENAME - DELETE FILE
; AX = 7141h
; DS:DX -> ASCIZ long name of file to delete


mov dx,offset storage ; delete file
mov ax,7141h
xor si,si
int 21h

xor ax,ax ; Zero out file_name
mov di,offset storage + 2
mov cx,150
repnz stosb


finito:
mov ah,9
mov dx,offset done_msg
int 21h
mov ax,4c00h ; Set errorlevel to 0
int 21h

error:
mov ah,9
int 21h
mov ax,4c01h ; Set errorlevel to 1
int 21h

ERROR_EXIT: ; Print Error Message and Exit

lea dx, NO_PARMS ; are no parameters passed
mov ah,9 ; Display error header
int 21h
mov ax,4c01h
int 21h


end start
Posted on 2003-09-05 08:29:26 by skywalker
You are accessing the command line with the wrong segment. Use the initial value of DS.
Posted on 2003-09-05 16:16:47 by Sephiroth3
You are accessing the command line with the wrong segment. Use the initial value of DS.

What exactly do you mean.

model small
stack 200h

data? ; can contain ONLY un-initialized data

random db 64000 dup(?)

data

handle dw ?
file_size dd ?
name_size dw ?

prompt db 13,10,13,10,9,'File Shredder Ver. 1e',13,10
db 13,10,'This file will NOT be recoverable !!',13,10
db 13,10,'File name to SHRED --> $'

not_there db 13,10,13,10,'File not present.',13,10,'$'
emsg2 db 13,10,13,10,'Error moving file pointer.',13,10,'$'
emsg3 db 13,10,13,10,'Error writing to file.',13,10,'$'

NO_PARMS db 13,10,13,10,'Nothing on command line.',13,10,13,10,'$'
VALID_IN db 'abcdefghijklmnopqrstuvwxyz,;=',9
VALID_OUT db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
VALID_NUM equ $ - VALID_OUT + 1

done_msg db 13,10,13,10,'File has been shredded.',13,10,'$'
prescence db 'Andrew Kennedy 2003'

n db 'file'
file_name db 128 dup(?) ; DOS maximum path length
storage db 150 dup(?)
eraser_name db '????????.',0

code

start:
mov ah,15 ; clear the screen
int 10h
mov ah,0
int 10h


mov ax,@data
mov ds,ax
mov es,ax ; need for LFN functions
Posted on 2003-09-05 19:26:03 by skywalker

You are accessing the command line with the wrong segment. Use the initial value of DS.

What exactly do you mean.

model small
; ......
code

start:
mov ah,15 ; clear the screen
int 10h
mov ah,0
int 10h

mov ax,@data
mov ds,ax
mov es,ax ; need for LFN functions
When a DOS EXE starts up, DS and ES point to the PSP to give you access to the command line arguments just like in a COM file. Here you change both DS and ES to your new data segment before you get a chance to access your command arguments.
Posted on 2003-09-05 20:17:20 by tenkey