TITLE SELFWRIT NAME SELFWRIT .386 .387 ; Part of the FWKTL(TM) Text_program Launcher kit, version 1.00. ; (C)Copyright Frederick W. Kantor 1996. All rights reserved. ; this program can store up to 32 bytes from its command tail in an ; internal array, and then overwrite its program file with that new ; material, or can display what it has currently in that array ; Usage: FWKTL SELFWRIT.COM to display current array contents ; FWKTL SELFWRIT.COM string to load/w to revise contents PSETUP EQU 01 ; = 1 include address for SHOW utility USE32 ; for A386 flat, protected_mode, 32_bit code. ; structure for initial data: P_ STRUC P_LOADEDAT DD ? ; start of this memory block P_PWHENCE DD ? ; points to ASCIIZ string re where program was found P_PCOMTAIL DD ? ; points to ASCIIZ command tail P_GETFN DD ? ; address for indirect call to FWKTL GETFN function: P_GETFNLIST DD ? ; address for indirect call to FWKTL GETFNLIST P_HDOSCALLS DD ? ; handle for DOSCALLS module as loaded by FWKTL, #IF PSETUP EQ 1 P_SHOW DD ? ; address for FWKTL SHOW function; P_USWORDCAPS DD ? ; address for FWKTL capitalization function; #ENDIF ; PSETUP EQ 1 P_WROTE DD ? ; used with the DOS32WRITE API P_HNL DD ? ; file handle P_WRITE DD ? P_CLOSE DD ? P_OPEN DD ? P_ ENDS CODESTART: ; used as a reference point RET ; 4_byte header identification string DB 'FWK' ; DD PSETUP ; style DD TYPE P_ ; amount of free memory requested after code JMP >L0 ; execution entry point. STORAGE: OSTORAGE EQU $-CODESTART DB 020H DUP 00 LSTORAGE EQU $-STORAGE DB 00 FNLIST: ; list of procedures (DOSCALLS ordinals). OFNLIST EQU $-CODESTART ; offset used for finding FNLIST in memory. ; these decimal number WORDs are in the same order ; as their corresponding DD targets in P_ STRUC ; decimal ordinals DW 282 ; DOS32WRITE (DOSCALLS.282) DW 257 ; DOS32CLOSE (DOSCALLS.257) DW 273 ; DOS32OPEN (DOSCALLS.273) NFNLIST EQU ($-FNLIST)/2 ; number of items in FNLIST L0: ; target for JMP from entry point PUSH EBX ; save EBX value MOV EBP,ESP ; save ESP value in EBP REP MOVSD ; load EBX:P_ STRUC MOV ESI,[EBX].P_LOADEDAT ; calculate position of start of FNLIST ADD ESI,OFNLIST ; procedure list LEA EDI,[EBX].P_WRITE ; point EDI at address array MOV EAX,02 ; FNLIST list contains 2_byte ordinals MOV ECX,NFNLIST ; number of items in list MOV EDX,[EBX].P_HDOSCALLS ; use handle for DOSCALLS module, CALL [EBX].P_GETFNLIST ; get addresses for procedures in list MOV ESI,[EBX].P_PCOMTAIL ; search command tail for /W MOV EDI,ESI MOV ECX,0200H XOR EAX,EAX ; find terminal 00 REPNE SCASB ; MOV ECX,EDI DEC EDI ; MOV AL,'/' SUB ECX,ESI STD REPNE SCASB CLD JNE >L2 ; if no '/', then jmp to SHOW INC EDI MOV B[EDI],00 ; terminate ASCIIZ string PUSH ESI MOV ESI,EDI INC ESI CALL [EBX].P_USWORDCAPS ; capitalize CMP B[ESI],'W' POP ESI JNE >L2 ; if not /W, then skip to use SHOW MOV ECX,EDI SUB ECX,ESI MOV EDI,LSTORAGE CMP ECX,EDI JNA >L0 MOV ECX,EDI L0: MOV EDI,[EBX].P_LOADEDAT ; point to STORAGE ADD EDI,OSTORAGE ; PUSHAD ; save values MOV ECX,LSTORAGE ; clear STORAGE XOR EAX,EAX ; REP STOSB ; POPAD ; restore values REP MOVSB ; copy into STORAGE PUSHD 0 ; for opening an existing file PUSHD 042H ; bits 6-4 = 100 = 4h OPEN_SHARE_DENYNONE ; bits 2-0 = 010 = 2h OPEN_ACCESS_READWRITE PUSHD 1H ; OPEN_ACTION_OPEN_IF_EXISTS PUSHD 7H ; FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY PUSHD 0 ; for opening an existing file LEA EAX,[EBX].P_WROTE ; pDWORD for report PUSHD EAX LEA EAX,[EBX].P_HNL ; where to save file handle PUSHD EAX PUSHD [EBX].P_PWHENCE ; ASCIIZ d:\path\filename.ext CALL [EBX].P_OPEN ; open TEST EAX,EAX ; test JNZ BADEXIT ; leave if bad MOV EBX,[EBP] ; overwrite program file LEA EAX,[EBX].P_WROTE ; pDWORD for amount written PUSHD EAX ; PUSHD CODE_END-CODESTART ; amount to write PUSHD [EBX].P_LOADEDAT ; push address of beginning of program PUSHD [EBX].P_HNL ; use file handle CALL [EBX].P_WRITE ; indirect call to DOS32WRITE to write message MOV EBX,[EBP] ; PUSHD [EBX].P_HNL ; close file handle CALL [EBX].P_CLOSE ; JMP SHORT EXIT L2: MOV ESI,[EBX].P_LOADEDAT ; display existing ASCIIZ string ADD ESI,OSTORAGE CALL [EBX].P_SHOW EXIT: XOR EAX,EAX ; set exit errorlevel = 0 BADEXIT: MOV ESP,EBP ; clear STACK POP EBX ; RET ; return to FWKTL ;--------------------------- CODE_END EQU $