5514 lines
166 KiB
Python
Executable File
5514 lines
166 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
import inspect
|
|
import unittest
|
|
|
|
import re
|
|
|
|
from datetime import datetime
|
|
from difflib import unified_diff
|
|
from os import statvfs, uname, utime, environ, access, R_OK, W_OK
|
|
from os.path import exists, isdir, join
|
|
from pathlib import Path
|
|
from shutil import copy
|
|
from subprocess import call, CalledProcessError, run
|
|
from sys import argv, exit, modules
|
|
from time import mktime
|
|
|
|
from common_framework import (BaseTestCase, get_test_binaries, main, mkstring,
|
|
IPROMPT, KNOWNFAIL, UNSUPPORTED)
|
|
|
|
from func_cpu_trap_flag import cpu_trap_flag
|
|
from func_ds2_file_seek_tell import ds2_file_seek_tell
|
|
from func_ds2_file_seek_read import ds2_file_seek_read
|
|
from func_ds2_set_fattrs import ds2_set_fattrs
|
|
from func_ds3_file_access import ds3_file_access
|
|
from func_ds3_lock_concurrent import ds3_lock_concurrent
|
|
from func_ds3_lock_two_handles import ds3_lock_two_handles
|
|
from func_ds3_lock_readlckd import ds3_lock_readlckd
|
|
from func_ds3_lock_readonly import ds3_lock_readonly
|
|
from func_ds3_lock_twice import ds3_lock_twice
|
|
from func_ds3_lock_writable import ds3_lock_writable
|
|
from func_ds3_share_open_access import ds3_share_open_access
|
|
from func_ds3_share_open_twice import ds3_share_open_twice
|
|
from func_lfn_voln_info import lfn_voln_info
|
|
from func_lfs_disk_info import lfs_disk_info
|
|
from func_label_create import (label_create, label_create_on_lfns,
|
|
label_create_noduplicate, label_create_nonrootdir,
|
|
label_delete_wildcard, label_delete_recreate)
|
|
from func_lfs_file_info import lfs_file_info
|
|
from func_lfs_file_seek_tell import lfs_file_seek_tell
|
|
from func_libi86_testsuite import libi86_create_items
|
|
from func_memory_dpmi_dpmi10_ldt import memory_dpmi_dpmi10_ldt
|
|
from func_memory_dpmi_japheth import memory_dpmi_japheth
|
|
from func_memory_dpmi_leak_check import memory_dpmi_leak_check
|
|
from func_memory_dpmi_leak_check_dos import memory_dpmi_leak_check_dos
|
|
from func_memory_ems_borland import memory_ems_borland
|
|
from func_memory_hma import (memory_hma_freespace, memory_hma_alloc, memory_hma_a20,
|
|
memory_hma_alloc3, memory_hma_chain)
|
|
from func_memory_uma import memory_uma_strategy
|
|
from func_memory_xms import memory_xms
|
|
from func_mfs_findfile import mfs_findfile
|
|
from func_mfs_truename import mfs_truename
|
|
from func_network import network_pktdriver_mtcp
|
|
from func_pit_mode_2 import pit_mode_2
|
|
|
|
SYSTYPE_DRDOS_ENHANCED = "Enhanced DR-DOS"
|
|
SYSTYPE_DRDOS_ORIGINAL = "Original DR-DOS"
|
|
SYSTYPE_DRDOS_OLD = "Old DR-DOS"
|
|
SYSTYPE_PCDOS_NEW = "New PC-DOS"
|
|
SYSTYPE_PCDOS_OLD = "Old PC-DOS"
|
|
SYSTYPE_MSDOS_NEW = "New MS-DOS"
|
|
SYSTYPE_MSDOS_INTERMEDIATE = "Newer MS-DOS"
|
|
SYSTYPE_MSDOS_OLD = "Old MS-DOS"
|
|
SYSTYPE_MSDOS_NEC = "NEC MS-DOS"
|
|
SYSTYPE_FRDOS_OLD = "Old FreeDOS"
|
|
SYSTYPE_FRDOS_NEW = "FreeDOS"
|
|
SYSTYPE_FDPP = "FDPP"
|
|
|
|
PRGFIL_SFN = "PROGR~-I"
|
|
PRGFIL_LFN = "Program Files"
|
|
|
|
|
|
class OurTestCase(BaseTestCase):
|
|
|
|
attrs = ['cputest', 'dpmitest', 'hmatest', 'nettest', 'umatest', 'xmstest',
|
|
'labeltest']
|
|
pname = "test_dos"
|
|
|
|
# Tests using assembler
|
|
|
|
def _test_mfs_directory_common(self, nametype, operation):
|
|
if nametype == "LFN":
|
|
ename = "mfslfn"
|
|
testname = "test very long directory"
|
|
elif nametype == "SFN":
|
|
ename = "mfssfn"
|
|
testname = "testdir"
|
|
else:
|
|
self.fail("Incorrect argument")
|
|
|
|
testdir = self.mkworkdir('d')
|
|
|
|
cwdnum = "0x0"
|
|
|
|
if operation == "Create":
|
|
ename += "dc"
|
|
if nametype == "SFN":
|
|
intnum = "0x3900" # create
|
|
else:
|
|
intnum = "0x7139"
|
|
elif operation in ["Delete", "DeleteNotEmpty"]:
|
|
ename += "dd"
|
|
if nametype == "SFN":
|
|
intnum = "0x3a00" # delete
|
|
else:
|
|
intnum = "0x713a"
|
|
Path(testdir / testname).mkdir()
|
|
if operation == "DeleteNotEmpty":
|
|
self.mkfile("DirNotEm.pty", """hello\r\n""", join(testdir, testname))
|
|
elif operation == "Chdir":
|
|
ename += "dh"
|
|
if nametype == "SFN":
|
|
intnum = "0x3b00" # chdir
|
|
cwdnum = "0x4700" # getcwd
|
|
else:
|
|
intnum = "0x713b"
|
|
cwdnum = "0x7147"
|
|
Path(testdir / testname).mkdir()
|
|
else:
|
|
self.fail("Incorrect argument")
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, %s
|
|
mov dx, dname
|
|
int 21h
|
|
|
|
jnc prsucc
|
|
|
|
prfail:
|
|
mov dx, failmsg
|
|
jmp @1
|
|
prsucc:
|
|
mov dx, succmsg
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
mov ax, %s
|
|
cmp ax, 0x7147
|
|
je prcwd
|
|
cmp ax, 0x4700
|
|
je prcwd
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
prcwd:
|
|
; get cwd
|
|
mov dl, 0
|
|
mov si, curdir
|
|
int 21h
|
|
|
|
push ds
|
|
pop es
|
|
mov di, si
|
|
|
|
mov cx, 128
|
|
mov al, 0
|
|
cld
|
|
repne scasb
|
|
mov byte [di-1], ')'
|
|
mov byte [di], '$'
|
|
|
|
mov ah, 9
|
|
mov dx, pcurdir
|
|
int 21h
|
|
|
|
jmp exit
|
|
|
|
section .data
|
|
|
|
dname:
|
|
db "%s",0
|
|
|
|
succmsg:
|
|
db "Directory Operation Success",13,10,'$'
|
|
failmsg:
|
|
db "Directory Operation Failed",13,10,'$'
|
|
|
|
pcurdir:
|
|
db '('
|
|
curdir:
|
|
times 128 db '$'
|
|
|
|
""" % (intnum, cwdnum, testname))
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
# test to see if the directory intnum made it through to linux
|
|
if operation == "Create":
|
|
self.assertIn("Directory Operation Success", results)
|
|
self.assertTrue(isdir(join(testdir, testname)), "Directory not created")
|
|
elif operation == "Delete":
|
|
self.assertIn("Directory Operation Success", results)
|
|
self.assertFalse(isdir(join(testdir, testname)), "Directory not deleted")
|
|
elif operation == "DeleteNotEmpty":
|
|
self.assertIn("Directory Operation Failed", results)
|
|
self.assertTrue(isdir(join(testdir, testname)), "Directory incorrectly deleted")
|
|
elif operation == "Chdir":
|
|
self.assertIn("Directory Operation Success", results)
|
|
if nametype == "SFN":
|
|
self.assertIn("(" + testname.upper() + ")", results)
|
|
else:
|
|
self.assertIn("(" + testname + ")", results)
|
|
|
|
def test_mfs_sfn_directory_create(self):
|
|
"""MFS SFN directory create"""
|
|
self._test_mfs_directory_common("SFN", "Create")
|
|
|
|
def test_mfs_sfn_directory_delete(self):
|
|
"""MFS SFN directory delete"""
|
|
self._test_mfs_directory_common("SFN", "Delete")
|
|
|
|
def test_mfs_sfn_directory_delete_not_empty(self):
|
|
"""MFS SFN directory delete not empty"""
|
|
self._test_mfs_directory_common("SFN", "DeleteNotEmpty")
|
|
|
|
def test_mfs_sfn_directory_chdir(self):
|
|
"""MFS SFN directory change current"""
|
|
self._test_mfs_directory_common("SFN", "Chdir")
|
|
|
|
def test_mfs_lfn_directory_create(self):
|
|
"""MFS LFN directory create"""
|
|
self._test_mfs_directory_common("LFN", "Create")
|
|
|
|
def test_mfs_lfn_directory_delete(self):
|
|
"""MFS LFN directory delete"""
|
|
self._test_mfs_directory_common("LFN", "Delete")
|
|
|
|
def test_mfs_lfn_directory_delete_not_empty(self):
|
|
"""MFS LFN directory delete not empty"""
|
|
self._test_mfs_directory_common("LFN", "DeleteNotEmpty")
|
|
|
|
def test_mfs_lfn_directory_chdir(self):
|
|
"""MFS LFN directory change current"""
|
|
self._test_mfs_directory_common("LFN", "Chdir")
|
|
|
|
def _test_mfs_get_current_directory(self, nametype):
|
|
if nametype == "LFN":
|
|
ename = "mfslfngd"
|
|
testname = PRGFIL_LFN
|
|
elif nametype == "SFN":
|
|
ename = "mfssfngd"
|
|
testname = PRGFIL_SFN
|
|
else:
|
|
self.fail("Incorrect argument")
|
|
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if nametype == "SFN":
|
|
cwdnum = "0x4700" # getcwd
|
|
else:
|
|
cwdnum = "0x7147"
|
|
|
|
Path(testdir / PRGFIL_LFN).mkdir()
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
cd %s
|
|
c:\\%s
|
|
rem end
|
|
""" % (PRGFIL_SFN, ename), newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
; get cwd
|
|
mov ax, %s
|
|
mov dl, 0
|
|
mov si, curdir
|
|
int 21h
|
|
|
|
push ds
|
|
pop es
|
|
mov di, si
|
|
|
|
mov cx, 128
|
|
mov al, 0
|
|
cld
|
|
repne scasb
|
|
mov byte [di-1], ')'
|
|
mov byte [di], '$'
|
|
|
|
mov ah, 9
|
|
mov dx, pcurdir
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
pcurdir:
|
|
db '('
|
|
curdir:
|
|
times 128 db '$'
|
|
|
|
""" % cwdnum)
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
if nametype == "SFN":
|
|
self.assertIn("(" + testname.upper() + ")", results)
|
|
else:
|
|
self.assertIn("(" + testname + ")", results)
|
|
|
|
def test_mfs_sfn_get_current_directory(self):
|
|
"""MFS SFN get current directory"""
|
|
self._test_mfs_get_current_directory("SFN")
|
|
|
|
def test_mfs_lfn_get_current_directory(self):
|
|
"""MFS LFN get current directory"""
|
|
self._test_mfs_get_current_directory("LFN")
|
|
|
|
def _test_lfn_support(self, fstype, confsw):
|
|
ename = "lfnsuppt"
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if fstype == "MFS":
|
|
config = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
config = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % self.mkimage("12", cwd=testdir)
|
|
|
|
config += """$_lfn_support = (%s)\n""" % confsw
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
; Get current drive and store its letter in fspath
|
|
mov ax, 1900h
|
|
int 21h
|
|
add al, 'A'
|
|
mov byte [fspath], al
|
|
|
|
; Get Volume info
|
|
; Windows95 - LONG FILENAME - GET VOLUME INFORMATION
|
|
;
|
|
; Call:
|
|
; AX = 71A0h
|
|
; DS:DX -> ASCIZ root name (e.g. "C:\")
|
|
; ES:DI -> buffer for file system name
|
|
; CX = size of ES:DI buffer
|
|
;
|
|
; Return:
|
|
; CF clear if successful
|
|
; AX destroyed (0000h and 0200h seen)
|
|
; BX = file system flags (see ;01783)
|
|
; CX = maximum length of file name [usually 255]
|
|
; DX = maximum length of path [usually 260]
|
|
; ES:DI buffer filled (ASCIZ, e.g. "FAT","NTFS","CDFS")
|
|
;
|
|
; CF set on error
|
|
; AX = error code
|
|
; 7100h if function not supported
|
|
|
|
mov ax, 71a0h
|
|
mov dx, fspath ; ds:dx
|
|
mov di, fstype ; es:di
|
|
mov cx, fstypelen
|
|
stc
|
|
int 21h
|
|
|
|
jc chkfail
|
|
|
|
cmp byte [fstype], '$'
|
|
je prnofstype
|
|
|
|
prsuccess:
|
|
mov di, fstype
|
|
mov cx, fstypelen
|
|
mov al, 0
|
|
cld
|
|
repne scasb
|
|
mov byte [di-1], ')'
|
|
mov byte [di], 13
|
|
mov byte [di+1], 10
|
|
mov byte [di+2], '$'
|
|
mov dx, success
|
|
jmp exit
|
|
|
|
prnofstype:
|
|
mov dx, nofstype
|
|
jmp exit
|
|
|
|
prnotsupported:
|
|
mov dx, notsupported
|
|
jmp exit
|
|
|
|
prcarryset:
|
|
mov dx, carryset
|
|
jmp exit
|
|
|
|
chkfail:
|
|
cmp ax, 7100h
|
|
jne prcarryset
|
|
|
|
jmp prnotsupported
|
|
|
|
exit:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
carryset:
|
|
db "Carry Set",13,10,'$'
|
|
notsupported:
|
|
db "Not Supported(AX=0x7100)",13,10,'$'
|
|
nofstype:
|
|
db "Carry Not Set But No Filesystem Type",13,10,'$'
|
|
success:
|
|
db "Operation Success("
|
|
fstype:
|
|
times 32 db '$'
|
|
fstypelen equ $ - fstype
|
|
successend:
|
|
times 4 db 0
|
|
fspath:
|
|
db "?:\", 0
|
|
""")
|
|
|
|
results = self.runDosemu("testit.bat", config=config)
|
|
|
|
if fstype == "MFS":
|
|
if confsw == "on":
|
|
self.assertIn("Operation Success(%s)" % fstype, results)
|
|
else:
|
|
self.assertIn("Not Supported(AX=0x7100)", results)
|
|
else: # FAT
|
|
self.assertIn("Not Supported(AX=0x7100)", results)
|
|
|
|
def test_lfn_mfs_support_on(self):
|
|
"""LFN MFS Support On"""
|
|
self._test_lfn_support("MFS", "on")
|
|
|
|
def test_lfn_fat_support_on(self):
|
|
"""LFN FAT Support On"""
|
|
self._test_lfn_support("FAT", "on")
|
|
|
|
def test_lfn_mfs_support_off(self):
|
|
"""LFN MFS Support Off"""
|
|
self._test_lfn_support("MFS", "off")
|
|
|
|
def test_lfn_fat_support_off(self):
|
|
"""LFN FAT Support Off"""
|
|
self._test_lfn_support("FAT", "off")
|
|
|
|
def _test_fcb_read(self, fstype):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if fstype == "MFS":
|
|
ename = "mfsfcbrd"
|
|
fcbreadconfig = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
ename = "fatfcbrd"
|
|
fcbreadconfig = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % self.mkimage("12", cwd=testdir)
|
|
|
|
testdata = mkstring(32)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
echo %s > test.fil
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % (testdata, ename), newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 0f00h ; open file
|
|
mov dx, fcb
|
|
int 21h
|
|
cmp al, 0
|
|
jne prfailopen
|
|
|
|
mov ax, 1400h ; read from file
|
|
mov dx, fcb
|
|
int 21h
|
|
cmp al, 3 ; partial read
|
|
jne prfailread
|
|
|
|
jmp prsucc
|
|
|
|
prfailopen:
|
|
mov dx, failopen
|
|
jmp @1
|
|
|
|
prfailread:
|
|
mov ax, 1000h ; close file
|
|
mov dx, fcb
|
|
int 21h
|
|
mov dx, failread
|
|
jmp @1
|
|
|
|
prsucc:
|
|
mov dx, succstart
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
mov ax, 2f00h ; get DTA address in ES:BX
|
|
int 21h
|
|
|
|
mov byte [es:bx+%d], '$'; terminate
|
|
push es
|
|
pop ds
|
|
mov dx, bx
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
mov ax, 1000h ; close file
|
|
mov dx, fcb
|
|
int 21h
|
|
|
|
push cs
|
|
pop ds
|
|
mov dx, succend
|
|
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fcb:
|
|
db 0 ; 0 default drive
|
|
fn1:
|
|
db "% -8s" ; 8 bytes
|
|
fe1:
|
|
db "% -3s" ; 3 bytes
|
|
wk1:
|
|
times 24 db 0
|
|
|
|
succstart:
|
|
db "Operation Success($"
|
|
succend:
|
|
db ')',13,10,'$'
|
|
failopen:
|
|
db "Open Operation Failed",13,10,'$'
|
|
failread:
|
|
db "Read Operation Failed",13,10,'$'
|
|
|
|
""" % (len(testdata), "test", "fil"))
|
|
|
|
results = self.runDosemu("testit.bat", config=fcbreadconfig)
|
|
|
|
self.assertNotIn("Operation Failed", results)
|
|
self.assertIn("Operation Success(%s)" % testdata, results)
|
|
|
|
def test_fat_fcb_read(self):
|
|
"""FAT FCB file read simple"""
|
|
self._test_fcb_read("FAT")
|
|
|
|
def test_mfs_fcb_read(self):
|
|
"""MFS FCB file read simple"""
|
|
self._test_fcb_read("MFS")
|
|
|
|
def _test_fcb_read_alt_dta(self, fstype):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
ename = "fcbradta"
|
|
|
|
if fstype == "MFS":
|
|
config = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
config = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % self.mkimage("12", cwd=testdir)
|
|
|
|
testdata = mkstring(32)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
echo %s > test.fil
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % (testdata, ename), newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 1a00h ; set DTA
|
|
mov dx, altdta
|
|
int 21h
|
|
|
|
mov ax, 2f00h ; get DTA address in ES:BX
|
|
int 21h
|
|
mov ax, cs
|
|
mov dx, es
|
|
cmp dx, ax
|
|
jne prfaildtaset
|
|
cmp bx, altdta
|
|
jne prfaildtaset
|
|
|
|
mov ax, 0f00h ; open file
|
|
mov dx, fcb
|
|
int 21h
|
|
cmp al, 0
|
|
jne prfailopen
|
|
|
|
mov ax, 1400h ; read from file
|
|
mov dx, fcb
|
|
int 21h
|
|
cmp al, 3 ; partial read
|
|
jne prfailread
|
|
|
|
jmp prsucc
|
|
|
|
prfaildtaset:
|
|
mov dx, faildtaset
|
|
jmp @1
|
|
|
|
prfailopen:
|
|
mov dx, failopen
|
|
jmp @1
|
|
|
|
prfailread:
|
|
mov ax, 1000h ; close file
|
|
mov dx, fcb
|
|
int 21h
|
|
mov dx, failread
|
|
jmp @1
|
|
|
|
prsucc:
|
|
mov dx, succstart
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
mov ax, 2f00h ; get DTA address in ES:BX
|
|
int 21h
|
|
|
|
mov byte [es:bx+%d], '$'; terminate
|
|
push es
|
|
pop ds
|
|
mov dx, bx
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
mov ax, 1000h ; close file
|
|
mov dx, fcb
|
|
int 21h
|
|
|
|
push cs
|
|
pop ds
|
|
mov dx, succend
|
|
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fcb:
|
|
db 0 ; 0 default drive
|
|
fn1:
|
|
db "% -8s" ; 8 bytes
|
|
fe1:
|
|
db "% -3s" ; 3 bytes
|
|
wk1:
|
|
times 24 db 0
|
|
|
|
succstart:
|
|
db "Operation Success($"
|
|
succend:
|
|
db ')',13,10,'$'
|
|
faildtaset:
|
|
db "Set DTA Operation Failed",13,10,'$'
|
|
failopen:
|
|
db "Open Operation Failed",13,10,'$'
|
|
failread:
|
|
db "Read Operation Failed",13,10,'$'
|
|
|
|
altdta:
|
|
times 128 db 0
|
|
|
|
""" % (len(testdata), "test", "fil"))
|
|
|
|
results = self.runDosemu("testit.bat", config=config)
|
|
|
|
self.assertNotIn("Operation Failed", results)
|
|
self.assertIn("Operation Success(%s)" % testdata, results)
|
|
|
|
def test_fat_fcb_read_alt_dta(self):
|
|
"""FAT FCB file read alternate DTA"""
|
|
self._test_fcb_read_alt_dta("FAT")
|
|
|
|
def test_mfs_fcb_read_alt_dta(self):
|
|
"""MFS FCB file read alternate DTA"""
|
|
self._test_fcb_read_alt_dta("MFS")
|
|
|
|
def test_fat_label_create_simple(self):
|
|
"""FAT FCB label create simple"""
|
|
label_create(self, "FAT", None)
|
|
test_fat_label_create_simple.labeltest = True
|
|
|
|
def test_fat_label_create_bpb12(self):
|
|
"""FAT FCB label create BPB FAT12"""
|
|
label_create(self, "FAT", 'bpb12')
|
|
test_fat_label_create_bpb12.labeltest = True
|
|
|
|
def test_fat_label_create_bpb16(self):
|
|
"""FAT FCB label create BPB FAT16"""
|
|
label_create(self, "FAT", 'bpb16')
|
|
test_fat_label_create_bpb16.labeltest = True
|
|
|
|
def test_fat_label_create_bpb32(self):
|
|
"""FAT FCB label create BPB FAT32"""
|
|
label_create(self, "FAT", 'bpb32')
|
|
test_fat_label_create_bpb32.labeltest = True
|
|
|
|
def test_fat_label_create_prefile(self):
|
|
"""FAT FCB label create file beforehand"""
|
|
label_create(self, "FAT", 'prefile')
|
|
test_fat_label_create_prefile.labeltest = True
|
|
|
|
def test_fat_label_create_predir(self):
|
|
"""FAT FCB label create directory beforehand"""
|
|
label_create(self, "FAT", 'predir')
|
|
test_fat_label_create_predir.labeltest = True
|
|
|
|
def test_fat_label_create_postfile(self):
|
|
"""FAT FCB label create file afterwards"""
|
|
label_create(self, "FAT", 'postfile')
|
|
test_fat_label_create_postfile.labeltest = True
|
|
|
|
def test_fat_label_create_postdir(self):
|
|
"""FAT FCB label create directory afterwards"""
|
|
label_create(self, "FAT", 'postdir')
|
|
test_fat_label_create_postdir.labeltest = True
|
|
|
|
def test_fat_label_create_on_lfns(self):
|
|
"""FAT FCB label create on top of LFNs"""
|
|
label_create_on_lfns(self)
|
|
test_fat_label_create_on_lfns.labeltest = True
|
|
|
|
def test_fat_label_create_noduplicate(self):
|
|
"""FAT FCB label create no duplicate"""
|
|
label_create_noduplicate(self, "FAT")
|
|
test_fat_label_create_noduplicate.labeltest = True
|
|
|
|
def _test_fcb_write(self, fstype):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if fstype == "MFS":
|
|
ename = "mfsfcbwr"
|
|
fcbreadconfig = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
ename = "fatfcbwr"
|
|
fcbreadconfig = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % self.mkimage("12", cwd=testdir)
|
|
|
|
testdata = mkstring(32)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
DIR
|
|
type test.fil
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 1600h ; create file
|
|
mov dx, fcb
|
|
int 21h
|
|
cmp al, 0
|
|
jne prfailopen
|
|
|
|
mov si, data ; copy data to DTA
|
|
mov ax, 2f00h ; get DTA address in ES:BX
|
|
int 21h
|
|
mov di, bx
|
|
mov cx, datalen
|
|
cld
|
|
repnz movsb
|
|
|
|
mov ax, 1500h ; write to file
|
|
mov dx, fcb
|
|
mov word [flrs], datalen; only the significant part
|
|
int 21h
|
|
cmp al , 0
|
|
jne prfailwrite
|
|
|
|
mov dx, donewrite
|
|
jmp @2
|
|
|
|
prfailwrite:
|
|
mov dx, failwrite
|
|
jmp @2
|
|
|
|
prfailopen:
|
|
mov dx, failopen
|
|
jmp @1
|
|
|
|
@2:
|
|
mov ax, 1000h ; close file
|
|
push dx
|
|
mov dx, fcb
|
|
int 21h
|
|
pop dx
|
|
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
data:
|
|
db "Operation Success(%s)",13,10,'$'
|
|
datalen equ $ - data - 1
|
|
|
|
fcb:
|
|
db 0 ; 0 default drive
|
|
fn1:
|
|
db "% -8s" ; 8 bytes
|
|
fe1:
|
|
db "% -3s" ; 3 bytes
|
|
fcbn:
|
|
dw 0
|
|
flrs:
|
|
dw 0
|
|
ffsz:
|
|
dd 0
|
|
fdlw:
|
|
dw 0
|
|
ftlw:
|
|
dw 0
|
|
res8:
|
|
times 8 db 0
|
|
fcbr:
|
|
db 0
|
|
frrn:
|
|
dd 0
|
|
|
|
failopen:
|
|
db "Open Operation Failed",13,10,'$'
|
|
failwrite:
|
|
db "Write Operation Failed",13,10,'$'
|
|
donewrite:
|
|
db "Write Operation Done",13,10,'$'
|
|
|
|
""" % (testdata, "test", "fil"))
|
|
|
|
results = self.runDosemu("testit.bat", config=fcbreadconfig)
|
|
|
|
self.assertNotIn("Operation Failed", results)
|
|
self.assertIn("Operation Success(%s)" % testdata, results)
|
|
|
|
def test_fat_fcb_write(self):
|
|
"""FAT FCB file write simple"""
|
|
self._test_fcb_write("FAT")
|
|
|
|
def test_mfs_fcb_write(self):
|
|
"""MFS FCB file write simple"""
|
|
self._test_fcb_write("MFS")
|
|
|
|
def _test_fcb_rename_common(self, fstype, testname):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if testname == "simple":
|
|
ename = "mfsfcbr1"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
fn2 = "testb"
|
|
fe2 = "bal"
|
|
self.mkfile(fn1 + "." + fe1, """hello\r\n""", testdir)
|
|
elif testname == "source_missing":
|
|
ename = "mfsfcbr2"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
fn2 = "testb"
|
|
fe2 = "bal"
|
|
elif testname == "target_exists":
|
|
ename = "mfsfcbr3"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
fn2 = "testb"
|
|
fe2 = "bal"
|
|
self.mkfile(fn1 + "." + fe1, """hello\r\n""", testdir)
|
|
self.mkfile(fn2 + "." + fe2, """hello\r\n""", testdir)
|
|
elif testname == "wild_one":
|
|
ename = "mfsfcbr4"
|
|
fn1 = "*"
|
|
fe1 = "in"
|
|
fn2 = "*"
|
|
fe2 = "out"
|
|
for f in ["one.in", "two.in", "three.in", "four.in", "five.in",
|
|
"none.ctl"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_two":
|
|
ename = "mfsfcbr5"
|
|
fn1 = "a*"
|
|
fe1 = "*"
|
|
fn2 = "b*"
|
|
fe2 = "out"
|
|
for f in ["aone.in", "atwo.in", "athree.in", "afour.in",
|
|
"afive.in", "xnone.ctl"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_three":
|
|
# To rename "abc001.txt ... abc099.txt" to "abc601.txt....abc699.txt"
|
|
# REN abc0??.txt ???6*.*
|
|
ename = "mfsfcbr6"
|
|
fn1 = "abc0??"
|
|
fe1 = "*"
|
|
fn2 = "???6*"
|
|
fe2 = "*"
|
|
for f in ["abc001.txt", "abc002.txt", "abc003.txt", "abc004.txt",
|
|
"abc005.txt", "abc010.txt", "xbc007.txt"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_four":
|
|
# To rename abc001.htm to abc001.ht
|
|
# REN abc*.htm *.??
|
|
ename = "mfsfcbr7"
|
|
fn1 = "abc*"
|
|
fe1 = "htm"
|
|
fn2 = "*"
|
|
fe2 = "??"
|
|
for f in ["abc001.htm", "abc002.htm", "abc003.htm", "abc004.htm",
|
|
"abc005.htm", "abc010.htm", "xbc007.htm"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 1700h
|
|
mov dx, fcb
|
|
int 21h
|
|
|
|
cmp al, 0
|
|
je prsucc
|
|
|
|
prfail:
|
|
mov dx, failmsg
|
|
jmp @1
|
|
prsucc:
|
|
mov dx, succmsg
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fcb:
|
|
db 0 ; 0 default drive
|
|
fn1:
|
|
db "% -8s" ; 8 bytes
|
|
fe1:
|
|
db "% -3s" ; 3 bytes
|
|
wk1:
|
|
times 5 db 0
|
|
fn2:
|
|
db "% -8s" ; 8 bytes
|
|
fe2:
|
|
db "% -3s" ; 3 bytes
|
|
wk2:
|
|
times 16 db 0
|
|
|
|
succmsg:
|
|
db "Rename Operation Success",13,10,'$'
|
|
failmsg:
|
|
db "Rename Operation Failed",13,10,'$'
|
|
|
|
""" % (fn1, fe1, fn2, fe2))
|
|
|
|
def assertIsPresent(testdir, results, fstype, f, e, msg=None):
|
|
if fstype == "MFS":
|
|
self.assertTrue(exists(join(testdir, f + "." + e)), msg)
|
|
else:
|
|
self.assertRegex(results.upper(), r"%s( +|\.)%s" % (f.upper(), e.upper()))
|
|
|
|
if fstype == "MFS":
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name)
|
|
|
|
if testname == "simple":
|
|
self.assertIn("Rename Operation Success", results)
|
|
assertIsPresent(testdir, results, fstype, fn2, fe2, "File not renamed")
|
|
|
|
elif testname == "source_missing":
|
|
self.assertIn("Rename Operation Failed", results)
|
|
|
|
elif testname == "target_exists":
|
|
self.assertIn("Rename Operation Failed", results)
|
|
|
|
elif testname == "wild_one":
|
|
self.assertIn("Rename Operation Success", results)
|
|
assertIsPresent(testdir, results, fstype, "one", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "two", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "three", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "four", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "five", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "none", "ctl", "File incorrectly renamed")
|
|
|
|
elif testname == "wild_two":
|
|
self.assertIn("Rename Operation Success", results)
|
|
assertIsPresent(testdir, results, fstype, "bone", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "btwo", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "bthree", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "bfour", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "bfive", "out", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "xnone", "ctl", "File incorrectly renamed")
|
|
|
|
elif testname == "wild_three":
|
|
self.assertIn("Rename Operation Success", results)
|
|
assertIsPresent(testdir, results, fstype, "abc601", "txt", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc602", "txt", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc603", "txt", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc604", "txt", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc605", "txt", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc610", "txt", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "xbc007", "txt", "File incorrectly renamed")
|
|
|
|
elif testname == "wild_four":
|
|
self.assertIn("Rename Operation Success", results)
|
|
assertIsPresent(testdir, results, fstype, "abc001", "ht", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc002", "ht", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc003", "ht", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc004", "ht", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc005", "ht", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "abc010", "ht", "File not renamed")
|
|
assertIsPresent(testdir, results, fstype, "xbc007", "htm", "File incorrectly renamed")
|
|
|
|
def test_fat_fcb_rename_simple(self):
|
|
"""FAT FCB file rename simple"""
|
|
self._test_fcb_rename_common("FAT", "simple")
|
|
|
|
def test_mfs_fcb_rename_simple(self):
|
|
"""MFS FCB file rename simple"""
|
|
self._test_fcb_rename_common("MFS", "simple")
|
|
|
|
def test_fat_fcb_rename_source_missing(self):
|
|
"""FAT FCB file rename source missing"""
|
|
self._test_fcb_rename_common("FAT", "source_missing")
|
|
|
|
def test_mfs_fcb_rename_source_missing(self):
|
|
"""MFS FCB file rename source missing"""
|
|
self._test_fcb_rename_common("MFS", "source_missing")
|
|
|
|
def test_fat_fcb_rename_target_exists(self):
|
|
"""FAT FCB file rename target exists"""
|
|
self._test_fcb_rename_common("FAT", "target_exists")
|
|
|
|
def test_mfs_fcb_rename_target_exists(self):
|
|
"""MFS FCB file rename target exists"""
|
|
self._test_fcb_rename_common("MFS", "target_exists")
|
|
|
|
def test_fat_fcb_rename_wild_1(self):
|
|
"""FAT FCB file rename wildcard one"""
|
|
self._test_fcb_rename_common("FAT", "wild_one")
|
|
|
|
def test_mfs_fcb_rename_wild_1(self):
|
|
"""MFS FCB file rename wildcard one"""
|
|
self._test_fcb_rename_common("MFS", "wild_one")
|
|
|
|
def test_fat_fcb_rename_wild_2(self):
|
|
"""FAT FCB file rename wildcard two"""
|
|
self._test_fcb_rename_common("FAT", "wild_two")
|
|
|
|
def test_mfs_fcb_rename_wild_2(self):
|
|
"""MFS FCB file rename wildcard two"""
|
|
self._test_fcb_rename_common("MFS", "wild_two")
|
|
|
|
def test_fat_fcb_rename_wild_3(self):
|
|
"""FAT FCB file rename wildcard three"""
|
|
self._test_fcb_rename_common("FAT", "wild_three")
|
|
|
|
def test_mfs_fcb_rename_wild_3(self):
|
|
"""MFS FCB file rename wildcard three"""
|
|
self._test_fcb_rename_common("MFS", "wild_three")
|
|
|
|
def test_fat_fcb_rename_wild_4(self):
|
|
"""FAT FCB file rename wildcard four"""
|
|
self._test_fcb_rename_common("FAT", "wild_four")
|
|
|
|
def test_mfs_fcb_rename_wild_4(self):
|
|
"""MFS FCB file rename wildcard four"""
|
|
self._test_fcb_rename_common("MFS", "wild_four")
|
|
|
|
def _test_fcb_delete_common(self, fstype, testname):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if testname == "simple":
|
|
ename = "fcbdel1"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
self.mkfile(fn1 + "." + fe1, """hello\r\n""", testdir)
|
|
elif testname == "missing":
|
|
ename = "fcbdel2"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
elif testname == "wild_one":
|
|
ename = "fcbdel3"
|
|
fn1 = "*"
|
|
fe1 = "in"
|
|
for f in ["one.in", "two.in", "three.in", "four.in", "five.in",
|
|
"none.ctl"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_two":
|
|
ename = "fcbdel4"
|
|
fn1 = "a*"
|
|
fe1 = "*"
|
|
for f in ["aone.in", "atwo.in", "athree.in", "afour.in",
|
|
"afive.in", "xnone.ctl"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_three":
|
|
# To delete "abc001.txt ... abc099.txt"
|
|
ename = "fcbdel5"
|
|
fn1 = "abc0??"
|
|
fe1 = "*"
|
|
for f in ["abc001.txt", "abc002.txt", "abc003.txt", "abc004.txt",
|
|
"abc005.txt", "abc010.txt", "xbc007.txt"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 1300h
|
|
mov dx, fcb
|
|
int 21h
|
|
|
|
cmp al, 0
|
|
je prsucc
|
|
|
|
prfail:
|
|
mov dx, failmsg
|
|
jmp @1
|
|
prsucc:
|
|
mov dx, succmsg
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fcb:
|
|
db 0 ; 0 default drive
|
|
fn1:
|
|
db "% -8s" ; 8 bytes
|
|
fe1:
|
|
db "% -3s" ; 3 bytes
|
|
wk1:
|
|
times 25 db 0
|
|
|
|
succmsg:
|
|
db "Delete Operation Success",13,10,'$'
|
|
failmsg:
|
|
db "Delete Operation Failed",13,10,'$'
|
|
|
|
""" % (fn1, fe1))
|
|
|
|
def assertIsPresent(testdir, results, fstype, f, e, msg=None):
|
|
if fstype == "MFS":
|
|
self.assertTrue(exists(join(testdir, f + "." + e)), msg)
|
|
else:
|
|
self.assertRegex(results.upper(), r"%s( +|\.)%s" % (f.upper(), e.upper()))
|
|
|
|
def assertIsNotPresent(testdir, results, fstype, f, e, msg=None):
|
|
if fstype == "MFS":
|
|
self.assertFalse(exists(join(testdir, f + "." + e)), msg)
|
|
else:
|
|
self.assertNotRegex(results.upper(), r"%s( +|\.)%s" % (f.upper(), e.upper()))
|
|
|
|
if fstype == "MFS":
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name)
|
|
|
|
if testname == "simple":
|
|
self.assertIn("Delete Operation Success", results)
|
|
assertIsNotPresent(testdir, results, fstype, fn1, fe1, "File not deleted")
|
|
|
|
elif testname == "missing":
|
|
self.assertIn("Delete Operation Failed", results)
|
|
|
|
elif testname == "wild_one":
|
|
self.assertIn("Delete Operation Success", results)
|
|
assertIsNotPresent(testdir, results, fstype, "one", "in", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "two", "in", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "three", "in", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "four", "in", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "five", "in", "File not deleted")
|
|
assertIsPresent(testdir, results, fstype, "none", "ctl", "File incorrectly deleted")
|
|
|
|
elif testname == "wild_two":
|
|
self.assertIn("Delete Operation Success", results)
|
|
assertIsNotPresent(testdir, results, fstype, "aone", "in", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "atwo", "in", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "athree", "in", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "afour", "in", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "afive", "in", "File not deleted")
|
|
assertIsPresent(testdir, results, fstype, "xnone", "ctl", "File incorrectly deleted")
|
|
|
|
elif testname == "wild_three":
|
|
self.assertIn("Delete Operation Success", results)
|
|
assertIsNotPresent(testdir, results, fstype, "abc001", "txt", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "abc002", "txt", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "abc003", "txt", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "abc004", "txt", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "abc005", "txt", "File not deleted")
|
|
assertIsNotPresent(testdir, results, fstype, "abc010", "txt", "File not deleted")
|
|
assertIsPresent(testdir, results, fstype, "xbc007", "txt", "File incorrectly deleted")
|
|
|
|
def test_fat_fcb_delete_simple(self):
|
|
"""FAT FCB file delete simple"""
|
|
self._test_fcb_delete_common("FAT", "simple")
|
|
|
|
def test_mfs_fcb_delete_simple(self):
|
|
"""MFS FCB file delete simple"""
|
|
self._test_fcb_delete_common("MFS", "simple")
|
|
|
|
def test_fat_fcb_delete_missing(self):
|
|
"""FAT FCB file delete missing"""
|
|
self._test_fcb_delete_common("FAT", "missing")
|
|
|
|
def test_mfs_fcb_delete_missing(self):
|
|
"""MFS FCB file delete missing"""
|
|
self._test_fcb_delete_common("MFS", "missing")
|
|
|
|
def test_fat_fcb_delete_wild_1(self):
|
|
"""FAT FCB file delete wildcard one"""
|
|
self._test_fcb_delete_common("FAT", "wild_one")
|
|
|
|
def test_mfs_fcb_delete_wild_1(self):
|
|
"""MFS FCB file delete wildcard one"""
|
|
self._test_fcb_delete_common("MFS", "wild_one")
|
|
|
|
def test_fat_fcb_delete_wild_2(self):
|
|
"""FAT FCB file delete wildcard two"""
|
|
self._test_fcb_delete_common("FAT", "wild_two")
|
|
|
|
def test_mfs_fcb_delete_wild_2(self):
|
|
"""MFS FCB file delete wildcard two"""
|
|
self._test_fcb_delete_common("MFS", "wild_two")
|
|
|
|
def test_fat_fcb_delete_wild_3(self):
|
|
"""FAT FCB file delete wildcard three"""
|
|
self._test_fcb_delete_common("FAT", "wild_three")
|
|
|
|
def test_mfs_fcb_delete_wild_3(self):
|
|
"""MFS FCB file delete wildcard three"""
|
|
self._test_fcb_delete_common("MFS", "wild_three")
|
|
|
|
def _test_fcb_find_common(self, fstype, testname):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if testname == "simple":
|
|
ename = "fcbfind1"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
self.mkfile(fn1 + "." + fe1, """hello\r\n""", testdir)
|
|
elif testname == "missing":
|
|
ename = "fcbfind2"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
elif testname == "wild_one":
|
|
ename = "fcbfind3"
|
|
fn1 = "*"
|
|
fe1 = "in"
|
|
for f in ["one.in", "two.in", "three.in", "four.in", "five.in",
|
|
"none.ctl"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_two":
|
|
ename = "fcbfind4"
|
|
fn1 = "a*"
|
|
fe1 = "*"
|
|
for f in ["aone.in", "atwo.in", "athree.in", "afour.in",
|
|
"afive.in", "xnone.ctl"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_three":
|
|
# To find "abc001.txt ... abc099.txt"
|
|
ename = "fcbfind5"
|
|
fn1 = "abc0??"
|
|
fe1 = "*"
|
|
for f in ["abc001.txt", "abc002.txt", "abc003.txt", "abc004.txt",
|
|
"abc005.txt", "abc010.txt", "xbc007.txt"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
; Get DTA -> ES:BX
|
|
mov ax, 2f00h
|
|
int 21h
|
|
push es
|
|
push bx
|
|
pop long [pdta]
|
|
|
|
; FindFirst
|
|
findfirst:
|
|
mov ax, 1100h
|
|
mov dx, fcb
|
|
int 21h
|
|
|
|
cmp al, 0
|
|
je prsucc
|
|
|
|
prfail:
|
|
mov dx, failmsg
|
|
mov ah, 9
|
|
int 21h
|
|
jmp exit
|
|
|
|
prsucc:
|
|
mov dx, succmsg
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
prfilename:
|
|
push ds
|
|
lds si, [pdta]
|
|
inc si
|
|
|
|
push cs
|
|
pop es
|
|
mov di, prires
|
|
inc di
|
|
|
|
mov cx, 11
|
|
cld
|
|
repne movsb
|
|
|
|
pop ds
|
|
mov dx, prires
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
; FindNext
|
|
findnext:
|
|
mov ax, 1200h
|
|
mov dx, fcb
|
|
int 21h
|
|
|
|
cmp al, 0
|
|
je prfilename
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fcb:
|
|
db 0 ; 0 default drive
|
|
fn1:
|
|
db "% -8s" ; 8 bytes
|
|
fe1:
|
|
db "% -3s" ; 3 bytes
|
|
wk1:
|
|
times 25 db 0
|
|
|
|
pdta:
|
|
dd 0
|
|
|
|
prires:
|
|
db "("
|
|
fname:
|
|
times 8 db 20
|
|
fext:
|
|
times 3 db 20
|
|
db ')',13,10,'$'
|
|
|
|
succmsg:
|
|
db "Find Operation Success",13,10,'$'
|
|
failmsg:
|
|
db "Find Operation Failed",13,10,'$'
|
|
|
|
""" % (fn1, fe1))
|
|
|
|
if fstype == "MFS":
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name)
|
|
|
|
if testname == "simple":
|
|
self.assertIn("Find Operation Success", results)
|
|
self.assertIn("(TESTA BAT)", results)
|
|
|
|
elif testname == "missing":
|
|
self.assertIn("Find Operation Failed", results)
|
|
|
|
elif testname == "wild_one":
|
|
self.assertIn("Find Operation Success", results)
|
|
self.assertIn("(ONE IN )", results)
|
|
self.assertIn("(TWO IN )", results)
|
|
self.assertIn("(THREE IN )", results)
|
|
self.assertIn("(FOUR IN )", results)
|
|
self.assertIn("(FIVE IN )", results)
|
|
self.assertNotIn("(NONE CTL)", results)
|
|
|
|
elif testname == "wild_two":
|
|
self.assertIn("Find Operation Success", results)
|
|
self.assertIn("(AONE IN )", results)
|
|
self.assertIn("(ATWO IN )", results)
|
|
self.assertIn("(ATHREE IN )", results)
|
|
self.assertIn("(AFOUR IN )", results)
|
|
self.assertIn("(AFIVE IN )", results)
|
|
self.assertNotIn("(XNONE CTL)", results)
|
|
|
|
elif testname == "wild_three":
|
|
self.assertIn("Find Operation Success", results)
|
|
self.assertIn("(ABC001 TXT)", results)
|
|
self.assertIn("(ABC002 TXT)", results)
|
|
self.assertIn("(ABC003 TXT)", results)
|
|
self.assertIn("(ABC004 TXT)", results)
|
|
self.assertIn("(ABC005 TXT)", results)
|
|
self.assertIn("(ABC010 TXT)", results)
|
|
self.assertNotIn("(XBC007 TXT)", results)
|
|
|
|
def test_fat_fcb_find_simple(self):
|
|
"""FAT FCB file find simple"""
|
|
self._test_fcb_find_common("FAT", "simple")
|
|
|
|
def test_mfs_fcb_find_simple(self):
|
|
"""MFS FCB file find simple"""
|
|
self._test_fcb_find_common("MFS", "simple")
|
|
|
|
def test_fat_fcb_find_missing(self):
|
|
"""FAT FCB file find missing"""
|
|
self._test_fcb_find_common("FAT", "missing")
|
|
|
|
def test_mfs_fcb_find_missing(self):
|
|
"""MFS FCB file find missing"""
|
|
self._test_fcb_find_common("MFS", "missing")
|
|
|
|
def test_fat_fcb_find_wild_1(self):
|
|
"""FAT FCB file find wildcard one"""
|
|
self._test_fcb_find_common("FAT", "wild_one")
|
|
|
|
def test_mfs_fcb_find_wild_1(self):
|
|
"""MFS FCB file find wildcard one"""
|
|
self._test_fcb_find_common("MFS", "wild_one")
|
|
|
|
def test_fat_fcb_find_wild_2(self):
|
|
"""FAT FCB file find wildcard two"""
|
|
self._test_fcb_find_common("FAT", "wild_two")
|
|
|
|
def test_mfs_fcb_find_wild_2(self):
|
|
"""MFS FCB file find wildcard two"""
|
|
self._test_fcb_find_common("MFS", "wild_two")
|
|
|
|
def test_fat_fcb_find_wild_3(self):
|
|
"""FAT FCB file find wildcard three"""
|
|
self._test_fcb_find_common("FAT", "wild_three")
|
|
|
|
def test_mfs_fcb_find_wild_3(self):
|
|
"""MFS FCB file find wildcard three"""
|
|
self._test_fcb_find_common("MFS", "wild_three")
|
|
|
|
def _test_ds2_read_eof(self, fstype):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
ename = "ds2rdeof"
|
|
|
|
if fstype == "MFS":
|
|
config = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
config = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % self.mkimage("12", cwd=testdir)
|
|
|
|
testdata = mkstring(32)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
echo %s > test.fil
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % (testdata, ename), newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 3d00h ; open file readonly
|
|
mov dx, fname
|
|
int 21h
|
|
jc prfailopen
|
|
|
|
mov word [fhndl], ax
|
|
|
|
mov ax, 3f00h ; read from file, should be partial (35)
|
|
mov bx, word [fhndl]
|
|
mov cx, 64
|
|
mov dx, fdata
|
|
int 21h
|
|
jc prfailread
|
|
cmp ax, 35
|
|
jne prnumread
|
|
|
|
mov ax, 3f00h ; read from file again to get EOF
|
|
mov bx, word [fhndl]
|
|
mov cx, 64
|
|
mov dx, fdata
|
|
int 21h
|
|
jc prcarryset
|
|
cmp ax, 0
|
|
jne praxnotzero
|
|
|
|
jmp prsucc
|
|
|
|
prfailopen:
|
|
mov dx, failopen
|
|
jmp @1
|
|
|
|
prfailread:
|
|
mov dx, failread
|
|
jmp @2
|
|
|
|
prnumread:
|
|
mov dx, numread
|
|
jmp @2
|
|
|
|
praxnotzero:
|
|
mov dx, axnotzero
|
|
jmp @2
|
|
|
|
prcarryset:
|
|
mov dx, carryset
|
|
jmp @2
|
|
|
|
prsucc:
|
|
mov byte [fdata + 32], ')'
|
|
mov byte [fdata + 33], 13
|
|
mov byte [fdata + 34], 10
|
|
mov byte [fdata + 35], '$'
|
|
mov dx, success
|
|
jmp @2
|
|
|
|
@2:
|
|
mov ax, 3e00h ; close file
|
|
mov bx, word [fhndl]
|
|
int 21h
|
|
|
|
@1:
|
|
mov ah, 9 ; print string
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fname:
|
|
db "%s",0
|
|
|
|
fhndl:
|
|
dw 0
|
|
|
|
success:
|
|
db "Operation Success("
|
|
fdata:
|
|
times 64 db 0
|
|
failopen:
|
|
db "Open Operation Failed",13,10,'$'
|
|
failread:
|
|
db "Read Operation Failed",13,10,'$'
|
|
numread:
|
|
db "Partial Read Not 35 Chars",13,10,'$'
|
|
carryset:
|
|
db "Carry Set at EOF",13,10,'$'
|
|
axnotzero:
|
|
db "AX Not Zero at EOF",13,10,'$'
|
|
|
|
""" % "test.fil")
|
|
|
|
results = self.runDosemu("testit.bat", config=config)
|
|
|
|
self.assertNotIn("Operation Failed", results)
|
|
self.assertNotIn("Partial Read Not 35 Chars", results)
|
|
self.assertNotIn("Carry Set at EOF", results)
|
|
self.assertNotIn("AX Not Zero at EOF", results)
|
|
self.assertIn("Operation Success(%s)" % testdata, results)
|
|
|
|
def test_fat_ds2_read_eof(self):
|
|
"""FAT DOSv2 file read EOF"""
|
|
self._test_ds2_read_eof("FAT")
|
|
|
|
def test_mfs_ds2_read_eof(self):
|
|
"""MFS DOSv2 file read EOF"""
|
|
self._test_ds2_read_eof("MFS")
|
|
|
|
def _test_ds2_read_alt_dta(self, fstype):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
ename = "ds2radta"
|
|
|
|
if fstype == "MFS":
|
|
config = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
config = """\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % self.mkimage("12", cwd=testdir)
|
|
|
|
testdata = mkstring(32)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
echo %s > test.fil
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % (testdata, ename), newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 1a00h ; set DTA
|
|
mov dx, altdta
|
|
int 21h
|
|
|
|
mov ax, 2f00h ; get DTA address in ES:BX
|
|
int 21h
|
|
mov ax, cs
|
|
mov dx, es
|
|
cmp dx, ax
|
|
jne prfaildtaset
|
|
cmp bx, altdta
|
|
jne prfaildtaset
|
|
|
|
mov ax, 3d00h ; open file readonly
|
|
mov dx, fname
|
|
int 21h
|
|
jc prfailopen
|
|
|
|
mov word [fhndl], ax
|
|
|
|
mov ax, 3f00h ; read from file, should be partial (35)
|
|
mov bx, word [fhndl]
|
|
mov cx, 64
|
|
mov dx, fdata
|
|
int 21h
|
|
jc prfailread
|
|
cmp ax, 35
|
|
jne prnumread
|
|
|
|
jmp prsucc
|
|
|
|
prfaildtaset:
|
|
mov dx, faildtaset
|
|
jmp @1
|
|
|
|
prfailopen:
|
|
mov dx, failopen
|
|
jmp @1
|
|
|
|
prfailread:
|
|
mov dx, failread
|
|
jmp @2
|
|
|
|
prnumread:
|
|
mov dx, numread
|
|
jmp @2
|
|
|
|
prsucc:
|
|
mov byte [fdata + 32], ')'
|
|
mov byte [fdata + 33], 13
|
|
mov byte [fdata + 34], 10
|
|
mov byte [fdata + 35], '$'
|
|
mov dx, success
|
|
jmp @2
|
|
|
|
@2:
|
|
mov ax, 3e00h ; close file
|
|
mov bx, word [fhndl]
|
|
int 21h
|
|
|
|
@1:
|
|
mov ah, 9 ; print string
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fname:
|
|
db "%s",0
|
|
|
|
fhndl:
|
|
dw 0
|
|
|
|
success:
|
|
db "Operation Success("
|
|
fdata:
|
|
times 64 db 0
|
|
faildtaset:
|
|
db "Set DTA Operation Failed",13,10,'$'
|
|
failopen:
|
|
db "Open Operation Failed",13,10,'$'
|
|
failread:
|
|
db "Read Operation Failed",13,10,'$'
|
|
numread:
|
|
db "Partial Read Not 35 Chars",13,10,'$'
|
|
|
|
altdta:
|
|
times 128 db 0
|
|
|
|
""" % "test.fil")
|
|
|
|
results = self.runDosemu("testit.bat", config=config)
|
|
|
|
self.assertNotIn("Operation Failed", results)
|
|
self.assertNotIn("Partial Read Not 35 Chars", results)
|
|
self.assertIn("Operation Success(%s)" % testdata, results)
|
|
|
|
def test_fat_ds2_read_alt_dta(self):
|
|
"""FAT DOSv2 file read alternate DTA"""
|
|
self._test_ds2_read_alt_dta("FAT")
|
|
|
|
def test_mfs_ds2_read_alt_dta(self):
|
|
"""MFS DOSv2 file read alternate DTA"""
|
|
self._test_ds2_read_alt_dta("MFS")
|
|
|
|
def test_fat_ds2_file_seek_set_read(self):
|
|
"""FAT DOSv2 file seek set read"""
|
|
ds2_file_seek_read(self, "FAT", "SET")
|
|
|
|
def test_mfs_ds2_file_seek_set_read(self):
|
|
"""MFS DOSv2 file seek set read"""
|
|
ds2_file_seek_read(self, "MFS", "SET")
|
|
|
|
def test_fat_ds2_file_seek_cur_read(self):
|
|
"""FAT DOSv2 file seek current read"""
|
|
ds2_file_seek_read(self, "FAT", "CUR")
|
|
|
|
def test_mfs_ds2_file_seek_cur_read(self):
|
|
"""MFS DOSv2 file seek current read"""
|
|
ds2_file_seek_read(self, "MFS", "CUR")
|
|
|
|
def test_fat_ds2_file_seek_end_read(self):
|
|
"""FAT DOSv2 file seek end read"""
|
|
ds2_file_seek_read(self, "FAT", "END")
|
|
|
|
def test_mfs_ds2_file_seek_end_read(self):
|
|
"""MFS DOSv2 file seek end read"""
|
|
ds2_file_seek_read(self, "MFS", "END")
|
|
|
|
def test_fat_ds2_file_seek_tell_end_back(self):
|
|
"""FAT DOSv2 file seek tell end back"""
|
|
ds2_file_seek_tell(self, "FAT", "ENDBCKSML")
|
|
|
|
def test_mfs_ds2_file_seek_tell_end_back(self):
|
|
"""MFS DOSv2 file seek tell end back"""
|
|
ds2_file_seek_tell(self, "MFS", "ENDBCKSML")
|
|
|
|
def test_fat_ds2_file_seek_tell_end_back_large(self):
|
|
"""FAT DOSv2 file seek tell end back large"""
|
|
ds2_file_seek_tell(self, "FAT", "ENDBCKLRG")
|
|
|
|
def test_mfs_ds2_file_seek_tell_end_back_large(self):
|
|
"""MFS DOSv2 file seek tell end back large"""
|
|
ds2_file_seek_tell(self, "MFS", "ENDBCKLRG")
|
|
|
|
def test_fat_ds2_file_seek_tell_end_forward(self):
|
|
"""FAT DOSv2 file seek tell end forward"""
|
|
ds2_file_seek_tell(self, "FAT", "ENDFWDSML")
|
|
|
|
def test_mfs_ds2_file_seek_tell_end_forward(self):
|
|
"""MFS DOSv2 file seek tell end forward"""
|
|
ds2_file_seek_tell(self, "MFS", "ENDFWDSML")
|
|
|
|
def test_fat_ds2_file_seek_tell_end_forward_large(self):
|
|
"""FAT DOSv2 file seek tell end forward large"""
|
|
ds2_file_seek_tell(self, "FAT", "ENDFWDLRG")
|
|
|
|
def test_mfs_ds2_file_seek_tell_end_forward_large(self):
|
|
"""MFS DOSv2 file seek tell end forward large"""
|
|
ds2_file_seek_tell(self, "MFS", "ENDFWDLRG")
|
|
|
|
def _test_ds2_rename_common(self, fstype, testname):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
extrad = ""
|
|
|
|
if testname == "file":
|
|
ename = "mfsds2r1"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
fn2 = "testb"
|
|
fe2 = "bal"
|
|
self.mkfile(fn1 + "." + fe1, """hello\r\n""", testdir)
|
|
elif testname == "file_src_missing":
|
|
ename = "mfsds2r2"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
fn2 = "testb"
|
|
fe2 = "bal"
|
|
elif testname == "file_tgt_exists":
|
|
ename = "mfsds2r3"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
fn2 = "testb"
|
|
fe2 = "bal"
|
|
self.mkfile(fn1 + "." + fe1, """hello\r\n""", testdir)
|
|
self.mkfile(fn2 + "." + fe2, """hello\r\n""", testdir)
|
|
elif testname == "dir":
|
|
ename = "mfsds2r4"
|
|
fn1 = "testa"
|
|
fe1 = ""
|
|
fn2 = "testb"
|
|
fe2 = ""
|
|
extrad = "mkdir %s\n" % fn1
|
|
elif testname == "dir_src_missing":
|
|
ename = "mfsds2r5"
|
|
fn1 = "testa"
|
|
fe1 = ""
|
|
fn2 = "testb"
|
|
fe2 = ""
|
|
elif testname == "dir_tgt_exists":
|
|
ename = "mfsds2r6"
|
|
fn1 = "testa"
|
|
fe1 = ""
|
|
fn2 = "testb"
|
|
fe2 = ""
|
|
extrad = "mkdir %s\nmkdir %s\n" % (fn1, fn2)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
%s
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % (extrad, ename), newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
push cs
|
|
pop es
|
|
|
|
mov ax, 5600h
|
|
mov dx, src
|
|
mov di, dst
|
|
int 21h
|
|
jnc prsucc
|
|
|
|
prfail:
|
|
mov dx, failmsg
|
|
jmp @1
|
|
prsucc:
|
|
mov dx, succmsg
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
src:
|
|
db "%s",0 ; Full path
|
|
dst:
|
|
db "%s",0 ; Full path
|
|
|
|
succmsg:
|
|
db "Rename Operation Success",13,10,'$'
|
|
failmsg:
|
|
db "Rename Operation Failed",13,10,'$'
|
|
|
|
""" % (fn1 + "." + fe1, fn2 + "." + fe2))
|
|
|
|
def assertIsPresent(testdir, results, fstype, f, e, msg=None):
|
|
if fstype == "MFS":
|
|
self.assertTrue(exists(join(testdir, f + "." + e)), msg)
|
|
else:
|
|
self.assertRegex(results.upper(), r"%s( +|\.)%s" % (f.upper(), e.upper()), msg)
|
|
|
|
def assertIsPresentDir(testdir, results, fstype, f, msg=None):
|
|
if fstype == "MFS":
|
|
self.assertTrue(exists(join(testdir, f)), msg)
|
|
else:
|
|
# 2019-06-27 11:29 <DIR> DOSEMU
|
|
# DOSEMU <DIR> 06-27-19 5:33p
|
|
# TESTB <DIR> 8-17-20 2:03p
|
|
self.assertRegex(results.upper(),
|
|
r"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s<DIR>\s+%s"
|
|
r"|"
|
|
r"%s\s+<DIR>\s+\d{1,2}-\d{1,2}-\d{2}\s+\d+:\d+[AaPp]" % (f.upper(), f.upper()), msg)
|
|
|
|
if fstype == "MFS":
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name)
|
|
|
|
if testname == "file":
|
|
self.assertIn("Rename Operation Success", results)
|
|
assertIsPresent(testdir, results, fstype, fn2, fe2, "File not renamed")
|
|
|
|
elif testname == "file_src_missing":
|
|
self.assertIn("Rename Operation Failed", results)
|
|
|
|
elif testname == "file_tgt_exists":
|
|
self.assertIn("Rename Operation Failed", results)
|
|
|
|
elif testname == "dir":
|
|
self.assertIn("Rename Operation Success", results)
|
|
assertIsPresentDir(testdir, results, fstype, fn2, "Directory not renamed")
|
|
|
|
elif testname == "dir_src_missing":
|
|
self.assertIn("Rename Operation Failed", results)
|
|
|
|
elif testname == "dir_tgt_exists":
|
|
self.assertIn("Rename Operation Failed", results)
|
|
|
|
def test_fat_ds2_rename_file(self):
|
|
"""FAT DOSv2 rename file"""
|
|
self._test_ds2_rename_common("FAT", "file")
|
|
|
|
def test_mfs_ds2_rename_file(self):
|
|
"""MFS DOSv2 rename file"""
|
|
self._test_ds2_rename_common("MFS", "file")
|
|
|
|
def test_fat_ds2_rename_file_src_missing(self):
|
|
"""FAT DOSv2 rename file src missing"""
|
|
self._test_ds2_rename_common("FAT", "file_src_missing")
|
|
|
|
def test_mfs_ds2_rename_file_src_missing(self):
|
|
"""MFS DOSv2 rename file src missing"""
|
|
self._test_ds2_rename_common("MFS", "file_src_missing")
|
|
|
|
def test_fat_ds2_rename_file_tgt_exists(self):
|
|
"""FAT DOSv2 rename file tgt exists"""
|
|
self._test_ds2_rename_common("FAT", "file_tgt_exists")
|
|
|
|
def test_mfs_ds2_rename_file_tgt_exists(self):
|
|
"""MFS DOSv2 rename file tgt exists"""
|
|
self._test_ds2_rename_common("MFS", "file_tgt_exists")
|
|
|
|
def test_fat_ds2_rename_dir(self):
|
|
"""FAT DOSv2 rename dir"""
|
|
self._test_ds2_rename_common("FAT", "dir")
|
|
|
|
def test_mfs_ds2_rename_dir(self):
|
|
"""MFS DOSv2 rename dir"""
|
|
self._test_ds2_rename_common("MFS", "dir")
|
|
|
|
def test_fat_ds2_rename_dir_src_missing(self):
|
|
"""FAT DOSv2 rename dir src missing"""
|
|
self._test_ds2_rename_common("FAT", "dir_src_missing")
|
|
|
|
def test_mfs_ds2_rename_dir_src_missing(self):
|
|
"""MFS DOSv2 rename dir src missing"""
|
|
self._test_ds2_rename_common("MFS", "dir_src_missing")
|
|
|
|
def test_fat_ds2_rename_dir_tgt_exists(self):
|
|
"""FAT DOSv2 rename dir tgt exists"""
|
|
self._test_ds2_rename_common("FAT", "dir_tgt_exists")
|
|
|
|
def test_mfs_ds2_rename_dir_tgt_exists(self):
|
|
"""MFS DOSv2 rename dir tgt exists"""
|
|
self._test_ds2_rename_common("MFS", "dir_tgt_exists")
|
|
|
|
def _test_ds2_delete_common(self, fstype, testname):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if testname == "file":
|
|
ename = "mfsds2d1"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
self.mkfile(fn1 + "." + fe1, """hello\r\n""", dname=testdir)
|
|
elif testname == "file_missing":
|
|
ename = "mfsds2d2"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 4100h
|
|
mov dx, src
|
|
int 21h
|
|
jnc prsucc
|
|
|
|
prfail:
|
|
mov dx, failmsg
|
|
jmp @1
|
|
prsucc:
|
|
mov dx, succmsg
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
src:
|
|
db "%s",0 ; Full path
|
|
|
|
succmsg:
|
|
db "Delete Operation Success",13,10,'$'
|
|
failmsg:
|
|
db "Delete Operation Failed",13,10,'$'
|
|
|
|
""" % (fn1 + "." + fe1))
|
|
|
|
def assertIsNotPresent(testdir, results, fstype, f, e, msg=None):
|
|
if fstype == "MFS":
|
|
self.assertFalse(exists(join(testdir, f + "." + e)), msg)
|
|
else:
|
|
self.assertNotRegex(results.upper(), r"%s( +|\.)%s" % (f.upper(), e.upper()))
|
|
|
|
if fstype == "MFS":
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name)
|
|
|
|
if testname == "file":
|
|
self.assertIn("Delete Operation Success", results)
|
|
assertIsNotPresent(testdir, results, fstype, fn1, fe1, "File not deleted")
|
|
|
|
elif testname == "file_missing":
|
|
self.assertIn("Delete Operation Failed", results)
|
|
|
|
def test_fat_ds2_delete_file(self):
|
|
"""FAT DOSv2 delete file"""
|
|
self._test_ds2_delete_common("FAT", "file")
|
|
|
|
def test_mfs_ds2_delete_file(self):
|
|
"""MFS DOSv2 delete file"""
|
|
self._test_ds2_delete_common("MFS", "file")
|
|
|
|
def test_fat_ds2_delete_file_missing(self):
|
|
"""FAT DOSv2 delete file missing"""
|
|
self._test_ds2_delete_common("FAT", "file_missing")
|
|
|
|
def test_mfs_ds2_delete_file_missing(self):
|
|
"""MFS DOSv2 delete file missing"""
|
|
self._test_ds2_delete_common("MFS", "file_missing")
|
|
|
|
def _test_ds2_find_common(self, fstype, testname):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
if testname == "simple":
|
|
ename = "ds2find1"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
self.mkfile(fn1 + "." + fe1, """hello\r\n""", testdir)
|
|
elif testname == "missing":
|
|
ename = "ds2find2"
|
|
fn1 = "testa"
|
|
fe1 = "bat"
|
|
elif testname == "wild_one":
|
|
ename = "ds2find3"
|
|
fn1 = "*"
|
|
fe1 = "in"
|
|
for f in ["one.in", "two.in", "three.in", "four.in", "five.in",
|
|
"none.ctl"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_two":
|
|
ename = "ds2find4"
|
|
fn1 = "a*"
|
|
fe1 = "*"
|
|
for f in ["aone.in", "atwo.in", "athree.in", "afour.in",
|
|
"afive.in", "xnone.ctl"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
elif testname == "wild_three":
|
|
# To find "abc001.txt ... abc099.txt"
|
|
ename = "ds2find5"
|
|
fn1 = "abc0??"
|
|
fe1 = "*"
|
|
for f in ["abc001.txt", "abc002.txt", "abc003.txt", "abc004.txt",
|
|
"abc005.txt", "abc010.txt", "xbc007.txt"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
; Get DTA -> ES:BX
|
|
mov ax, 2f00h
|
|
int 21h
|
|
push es
|
|
push bx
|
|
pop long [pdta]
|
|
|
|
; FindFirst
|
|
findfirst:
|
|
mov ax, 4e00h
|
|
mov cx, 0
|
|
mov dx, fpatn
|
|
int 21h
|
|
jnc prsucc
|
|
|
|
prfail:
|
|
mov dx, failmsg
|
|
mov ah, 9
|
|
int 21h
|
|
jmp exit
|
|
|
|
prsucc:
|
|
mov dx, succmsg
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
prfilename:
|
|
push ds
|
|
lds ax, [pdta]
|
|
add ax, 1eh
|
|
mov si, ax
|
|
|
|
push cs
|
|
pop es
|
|
mov di, prires + 1
|
|
|
|
mov cx, 13
|
|
cld
|
|
|
|
@1:
|
|
cmp byte [ds:si], 0
|
|
je @2
|
|
|
|
movsb
|
|
loop @1
|
|
|
|
@2:
|
|
mov byte [es:di], ')'
|
|
mov byte [es:di + 1], 13
|
|
mov byte [es:di + 2], 10
|
|
mov byte [es:di + 3], '$'
|
|
|
|
pop ds
|
|
mov dx, prires
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
; FindNext
|
|
findnext:
|
|
mov ax, 4f00h
|
|
int 21h
|
|
jnc prfilename
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fpatn:
|
|
db "%s",0
|
|
|
|
pdta:
|
|
dd 0
|
|
|
|
prires:
|
|
db "("
|
|
times 32 db 0
|
|
|
|
succmsg:
|
|
db "Findfirst Operation Success",13,10,'$'
|
|
failmsg:
|
|
db "Findfirst Operation Failed",13,10,'$'
|
|
|
|
""" % (fn1 + "." + fe1))
|
|
|
|
if fstype == "MFS":
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name)
|
|
|
|
if testname == "simple":
|
|
self.assertIn("Findfirst Operation Success", results)
|
|
self.assertIn("(TESTA.BAT)", results)
|
|
|
|
elif testname == "missing":
|
|
self.assertIn("Findfirst Operation Failed", results)
|
|
|
|
elif testname == "wild_one":
|
|
self.assertIn("Findfirst Operation Success", results)
|
|
self.assertIn("(ONE.IN)", results)
|
|
self.assertIn("(TWO.IN)", results)
|
|
self.assertIn("(THREE.IN)", results)
|
|
self.assertIn("(FOUR.IN)", results)
|
|
self.assertIn("(FIVE.IN)", results)
|
|
self.assertNotIn("(NONE.CTL)", results)
|
|
|
|
elif testname == "wild_two":
|
|
self.assertIn("Findfirst Operation Success", results)
|
|
self.assertIn("(AONE.IN)", results)
|
|
self.assertIn("(ATWO.IN)", results)
|
|
self.assertIn("(ATHREE.IN)", results)
|
|
self.assertIn("(AFOUR.IN)", results)
|
|
self.assertIn("(AFIVE.IN)", results)
|
|
self.assertNotIn("(XNONE.CTL)", results)
|
|
|
|
elif testname == "wild_three":
|
|
self.assertIn("Findfirst Operation Success", results)
|
|
self.assertIn("(ABC001.TXT)", results)
|
|
self.assertIn("(ABC002.TXT)", results)
|
|
self.assertIn("(ABC003.TXT)", results)
|
|
self.assertIn("(ABC004.TXT)", results)
|
|
self.assertIn("(ABC005.TXT)", results)
|
|
self.assertIn("(ABC010.TXT)", results)
|
|
self.assertNotIn("(XBC007.TXT)", results)
|
|
|
|
def test_fat_ds2_find_simple(self):
|
|
"""FAT DOSv2 file find simple"""
|
|
self._test_ds2_find_common("FAT", "simple")
|
|
|
|
def test_mfs_ds2_find_simple(self):
|
|
"""MFS DOSv2 file find simple"""
|
|
self._test_ds2_find_common("MFS", "simple")
|
|
|
|
def test_fat_ds2_find_missing(self):
|
|
"""FAT DOSv2 file find missing"""
|
|
self._test_ds2_find_common("FAT", "missing")
|
|
|
|
def test_mfs_ds2_find_missing(self):
|
|
"""MFS DOSv2 file find missing"""
|
|
self._test_ds2_find_common("MFS", "missing")
|
|
|
|
def test_fat_ds2_find_wild_1(self):
|
|
"""FAT DOSv2 file find wildcard one"""
|
|
self._test_ds2_find_common("FAT", "wild_one")
|
|
|
|
def test_mfs_ds2_find_wild_1(self):
|
|
"""MFS DOSv2 file find wildcard one"""
|
|
self._test_ds2_find_common("MFS", "wild_one")
|
|
|
|
def test_fat_ds2_find_wild_2(self):
|
|
"""FAT DOSv2 file find wildcard two"""
|
|
self._test_ds2_find_common("FAT", "wild_two")
|
|
|
|
def test_mfs_ds2_find_wild_2(self):
|
|
"""MFS DOSv2 file find wildcard two"""
|
|
self._test_ds2_find_common("MFS", "wild_two")
|
|
|
|
def test_fat_ds2_find_wild_3(self):
|
|
"""FAT DOSv2 file find wildcard three"""
|
|
self._test_ds2_find_common("FAT", "wild_three")
|
|
|
|
def test_mfs_ds2_find_wild_3(self):
|
|
"""MFS DOSv2 file find wildcard three"""
|
|
self._test_ds2_find_common("MFS", "wild_three")
|
|
|
|
def _test_ds2_find_first(self, fstype, testname):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
ename = "ds2fndfi"
|
|
|
|
ATTR = "0x00"
|
|
|
|
if testname == "file_exists":
|
|
FSPEC = r"\fileexst.ext"
|
|
elif testname == "file_exists_as_dir":
|
|
FSPEC = r"\fileexst.ext\somefile.ext"
|
|
elif testname == "file_not_found":
|
|
FSPEC = r"\Notfname.ext"
|
|
elif testname == "no_more_files":
|
|
FSPEC = r"\????????.??x"
|
|
elif testname == "path_not_found_wc":
|
|
FSPEC = r"\NotDir\????????.???"
|
|
elif testname == "path_not_found_pl":
|
|
FSPEC = r"\NotDir\plainfil.txt"
|
|
elif testname == "path_exists_empty":
|
|
FSPEC = r"\DirExist"
|
|
elif testname == "path_exists_not_empty":
|
|
FSPEC = r"\DirExis2"
|
|
elif testname == "path_exists_file_not_dir":
|
|
FSPEC = r"\DirExis2\fileexst.ext"
|
|
ATTR = "0x10"
|
|
elif testname == "dir_exists_pl":
|
|
FSPEC = r"\DirExis2"
|
|
ATTR = "0x10"
|
|
elif testname == "dir_exists_wc":
|
|
FSPEC = r"\Di?Exis?"
|
|
ATTR = "0x10"
|
|
elif testname == "dir_not_exists_pl":
|
|
FSPEC = r"\dirNOTex"
|
|
ATTR = "0x10"
|
|
elif testname == "dir_not_exists_wc":
|
|
FSPEC = r"\dirNOTex\wi??card.???"
|
|
ATTR = "0x10"
|
|
elif testname == "dir_not_exists_fn":
|
|
FSPEC = r"\dirNOTex\somefile.ext"
|
|
ATTR = "0x10"
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
echo hello > fileexst.ext
|
|
mkdir DirExist
|
|
mkdir DirExis2
|
|
echo hello > DirExis2\\fileexst.ext
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov ax, 4e00h
|
|
mov cx, %s
|
|
mov dx, fspec
|
|
int 21h
|
|
|
|
jnc prsucc
|
|
|
|
cmp ax, 2
|
|
je fail02
|
|
|
|
cmp ax, 3
|
|
je fail03
|
|
|
|
cmp ax, 12h
|
|
je fail12
|
|
|
|
jmp genfail
|
|
|
|
fail02:
|
|
mov dx, filenotfound
|
|
jmp @1
|
|
|
|
fail03:
|
|
mov dx, pathnotfoundmsg
|
|
jmp @1
|
|
|
|
fail12:
|
|
mov dx, nomoremsg
|
|
jmp @1
|
|
|
|
genfail:
|
|
mov dx, genfailmsg
|
|
jmp @1
|
|
|
|
prsucc:
|
|
mov dx, succmsg
|
|
|
|
@1:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fspec:
|
|
db "%s",0 ; Full path
|
|
|
|
succmsg:
|
|
db "FindFirst Operation Success",13,10,'$'
|
|
filenotfound:
|
|
db "FindFirst Operation Returned FILE_NOT_FOUND(0x02)",13,10,'$'
|
|
pathnotfoundmsg:
|
|
db "FindFirst Operation Returned PATH_NOT_FOUND(0x03)",13,10,'$'
|
|
nomoremsg:
|
|
db "FindFirst Operation Returned NO_MORE_FILES(0x12)",13,10,'$'
|
|
genfailmsg:
|
|
db "FindFirst Operation Returned Unexpected Errorcode",13,10,'$'
|
|
|
|
""" % (ATTR, FSPEC))
|
|
|
|
if fstype == "MFS":
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name)
|
|
|
|
if testname == "file_exists":
|
|
self.assertIn("Operation Success", results)
|
|
elif testname == "file_exists_as_dir":
|
|
self.assertIn("Operation Returned PATH_NOT_FOUND(0x03)", results)
|
|
elif testname == "file_not_found": # Confirmed as not FILE_NOT_FOUND
|
|
self.assertIn("Operation Returned NO_MORE_FILES(0x12)", results)
|
|
elif testname == "no_more_files":
|
|
self.assertIn("Operation Returned NO_MORE_FILES(0x12)", results)
|
|
elif testname == "path_not_found_wc":
|
|
self.assertIn("Operation Returned PATH_NOT_FOUND(0x03)", results)
|
|
elif testname == "path_not_found_pl":
|
|
self.assertIn("Operation Returned PATH_NOT_FOUND(0x03)", results)
|
|
elif testname == "path_exists_empty":
|
|
self.assertIn("Operation Returned NO_MORE_FILES(0x12)", results)
|
|
elif testname == "path_exists_not_empty":
|
|
self.assertIn("Operation Returned NO_MORE_FILES(0x12)", results)
|
|
elif testname == "path_exists_file_not_dir":
|
|
self.assertIn("Operation Success", results)
|
|
elif testname == "dir_exists_pl":
|
|
self.assertIn("Operation Success", results)
|
|
elif testname == "dir_exists_wc":
|
|
self.assertIn("Operation Success", results)
|
|
elif testname == "dir_not_exists_pl":
|
|
self.assertIn("Operation Returned NO_MORE_FILES(0x12)", results)
|
|
elif testname == "dir_not_exists_wc":
|
|
self.assertIn("Operation Returned PATH_NOT_FOUND(0x03)", results)
|
|
elif testname == "dir_not_exists_fn":
|
|
self.assertIn("Operation Returned PATH_NOT_FOUND(0x03)", results)
|
|
|
|
def test_fat_ds2_findfirst_file_exists(self):
|
|
"""FAT DOSv2 findfirst file exists"""
|
|
self._test_ds2_find_first("FAT", "file_exists")
|
|
|
|
def test_mfs_ds2_findfirst_file_exists(self):
|
|
"""MFS DOSv2 findfirst file exists"""
|
|
self._test_ds2_find_first("MFS", "file_exists")
|
|
|
|
def test_fat_ds2_findfirst_file_exists_as_dir(self):
|
|
"""FAT DOSv2 findfirst file exists as dir"""
|
|
self._test_ds2_find_first("FAT", "file_exists_as_dir")
|
|
|
|
def test_mfs_ds2_findfirst_file_exists_as_dir(self):
|
|
"""MFS DOSv2 findfirst file exists as dir"""
|
|
self._test_ds2_find_first("MFS", "file_exists_as_dir")
|
|
|
|
def test_fat_ds2_findfirst_file_not_found(self):
|
|
"""FAT DOSv2 findfirst file not found"""
|
|
self._test_ds2_find_first("FAT", "file_not_found")
|
|
|
|
def test_mfs_ds2_findfirst_file_not_found(self):
|
|
"""MFS DOSv2 findfirst file not found"""
|
|
self._test_ds2_find_first("MFS", "file_not_found")
|
|
|
|
def test_fat_ds2_findfirst_no_more_files(self):
|
|
"""FAT DOSv2 findfirst no more files"""
|
|
self._test_ds2_find_first("FAT", "no_more_files")
|
|
|
|
def test_mfs_ds2_findfirst_no_more_files(self):
|
|
"""MFS DOSv2 findfirst no more files"""
|
|
self._test_ds2_find_first("MFS", "no_more_files")
|
|
|
|
def test_fat_ds2_findfirst_path_not_found_wc(self):
|
|
"""FAT DOSv2 findfirst path not found wildcard"""
|
|
self._test_ds2_find_first("FAT", "path_not_found_wc")
|
|
|
|
def test_mfs_ds2_findfirst_path_not_found_wc(self):
|
|
"""MFS DOSv2 findfirst path not found wildcard"""
|
|
self._test_ds2_find_first("MFS", "path_not_found_wc")
|
|
|
|
def test_fat_ds2_findfirst_path_not_found_pl(self):
|
|
"""FAT DOSv2 findfirst path not found plain"""
|
|
self._test_ds2_find_first("FAT", "path_not_found_pl")
|
|
|
|
def test_mfs_ds2_findfirst_path_not_found_pl(self):
|
|
"""MFS DOSv2 findfirst path not found plain"""
|
|
self._test_ds2_find_first("MFS", "path_not_found_pl")
|
|
|
|
def test_fat_ds2_findfirst_path_exists_empty(self):
|
|
"""FAT DOSv2 findfirst path exists empty"""
|
|
self._test_ds2_find_first("FAT", "path_exists_empty")
|
|
|
|
def test_mfs_ds2_findfirst_path_exists_empty(self):
|
|
"""MFS DOSv2 findfirst path exists empty"""
|
|
self._test_ds2_find_first("MFS", "path_exists_empty")
|
|
|
|
def test_fat_ds2_findfirst_path_exists_file_not_dir(self):
|
|
"""FAT DOSv2 findfirst path exists file not dir"""
|
|
self._test_ds2_find_first("FAT", "path_exists_file_not_dir")
|
|
|
|
def test_mfs_ds2_findfirst_path_exists_file_not_dir(self):
|
|
"""MFS DOSv2 findfirst path exists file not dir"""
|
|
self._test_ds2_find_first("MFS", "path_exists_file_not_dir")
|
|
|
|
def test_fat_ds2_findfirst_path_exists_not_empty(self):
|
|
"""FAT DOSv2 findfirst path exists not empty"""
|
|
self._test_ds2_find_first("FAT", "path_exists_not_empty")
|
|
|
|
def test_mfs_ds2_findfirst_path_exists_not_empty(self):
|
|
"""MFS DOSv2 findfirst path exists not empty"""
|
|
self._test_ds2_find_first("MFS", "path_exists_not_empty")
|
|
|
|
def test_fat_ds2_findfirst_dir_exists_pl(self):
|
|
"""FAT DOSv2 findfirst dir exists plain"""
|
|
self._test_ds2_find_first("FAT", "dir_exists_pl")
|
|
|
|
def test_mfs_ds2_findfirst_dir_exists_pl(self):
|
|
"""MFS DOSv2 findfirst dir exists plain"""
|
|
self._test_ds2_find_first("MFS", "dir_exists_pl")
|
|
|
|
def test_fat_ds2_findfirst_dir_exists_wc(self):
|
|
"""FAT DOSv2 findfirst dir exists wildcard"""
|
|
self._test_ds2_find_first("FAT", "dir_exists_wc")
|
|
|
|
def test_mfs_ds2_findfirst_dir_exists_wc(self):
|
|
"""MFS DOSv2 findfirst dir exists wildcard"""
|
|
self._test_ds2_find_first("MFS", "dir_exists_wc")
|
|
|
|
def test_fat_ds2_findfirst_dir_not_exists_pl(self):
|
|
"""FAT DOSv2 findfirst dir not exists plain"""
|
|
self._test_ds2_find_first("FAT", "dir_not_exists_pl")
|
|
|
|
def test_mfs_ds2_findfirst_dir_not_exists_pl(self):
|
|
"""MFS DOSv2 findfirst dir not exists plain"""
|
|
self._test_ds2_find_first("MFS", "dir_not_exists_pl")
|
|
|
|
def test_fat_ds2_findfirst_dir_not_exists_wc(self):
|
|
"""FAT DOSv2 findfirst dir not exists wildcard"""
|
|
self._test_ds2_find_first("FAT", "dir_not_exists_wc")
|
|
|
|
def test_mfs_ds2_findfirst_dir_not_exists_wc(self):
|
|
"""MFS DOSv2 findfirst dir not exists wildcard"""
|
|
self._test_ds2_find_first("MFS", "dir_not_exists_wc")
|
|
|
|
def test_fat_ds2_findfirst_dir_not_exists_fn(self):
|
|
"""FAT DOSv2 findfirst dir not exists filename"""
|
|
self._test_ds2_find_first("FAT", "dir_not_exists_fn")
|
|
|
|
def test_mfs_ds2_findfirst_dir_not_exists_fn(self):
|
|
"""MFS DOSv2 findfirst dir not exists filename"""
|
|
self._test_ds2_find_first("MFS", "dir_not_exists_fn")
|
|
|
|
def _test_ds2_find_mixed_wild_plain(self, fstype):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
ename = "ds2findm"
|
|
fsmpl = "xbc007.txt"
|
|
|
|
for f in ["abc001.txt", "abc002.txt", "abc003.txt", "abc004.txt",
|
|
"abc005.txt", "abc010.txt", "xbc007.txt"]:
|
|
self.mkfile(f, """hello\r\n""", testdir)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\%s
|
|
DIR
|
|
rem end
|
|
""" % ename, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
; Get DTA -> ES:BX
|
|
mov ax, 2f00h
|
|
int 21h
|
|
push es
|
|
push bx
|
|
pop long [pdta]
|
|
|
|
; First FindFirst
|
|
mov ax, 4e00h
|
|
mov cx, 0
|
|
mov dx, fwild
|
|
int 21h
|
|
|
|
; Set alternate DTA
|
|
mov ax, 1a00h
|
|
mov dx, altdta
|
|
int 21h
|
|
|
|
; Second FindFirst
|
|
mov ax, 4e00h
|
|
mov cx, 0
|
|
mov dx, fsmpl
|
|
int 21h
|
|
|
|
; Set default DTA
|
|
mov ax, 1a00h
|
|
lds dx, [pdta]
|
|
int 21h
|
|
|
|
; FindNext
|
|
mov ax, 4f00h
|
|
int 21h
|
|
jnc prsucc
|
|
|
|
prfail:
|
|
mov dx, failmsg
|
|
mov ah, 9
|
|
int 21h
|
|
jmp exit
|
|
|
|
prsucc:
|
|
push ds
|
|
lds ax, [pdta]
|
|
add ax, 1eh
|
|
mov si, ax
|
|
|
|
push cs
|
|
pop es
|
|
mov di, prires + 1
|
|
|
|
mov cx, 13
|
|
cld
|
|
|
|
@1:
|
|
cmp byte [ds:si], 0
|
|
je @2
|
|
|
|
movsb
|
|
loop @1
|
|
|
|
@2:
|
|
mov byte [es:di], ')'
|
|
mov byte [es:di + 1], 13
|
|
mov byte [es:di + 2], 10
|
|
mov byte [es:di + 3], '$'
|
|
|
|
pop ds
|
|
mov dx, succmsg
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
exit:
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
section .data
|
|
|
|
fwild:
|
|
db "a*.txt",0
|
|
fsmpl:
|
|
db "%s",0
|
|
|
|
altdta:
|
|
times 0x80 db 0
|
|
|
|
pdta:
|
|
dd 0
|
|
|
|
succmsg:
|
|
db "Findnext Operation Success"
|
|
prires:
|
|
db "("
|
|
times 32 db 0
|
|
|
|
failmsg:
|
|
db "Findnext Operation Failed",13,10,'$'
|
|
|
|
""" % fsmpl)
|
|
|
|
if fstype == "MFS":
|
|
config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name
|
|
|
|
results = self.runDosemu("testit.bat", config=config)
|
|
|
|
self.assertNotIn("Findnext Operation Failed", results)
|
|
self.assertRegex(results, r"Findnext Operation Success\(ABC...\.TXT\)")
|
|
|
|
def test_fat_ds2_find_mixed_wild_plain(self):
|
|
"""FAT DOSv2 findnext intermixed wild plain"""
|
|
self._test_ds2_find_mixed_wild_plain("FAT")
|
|
|
|
def test_mfs_ds2_find_mixed_wild_plain(self):
|
|
"""MFS DOSv2 findnext intermixed wild plain"""
|
|
self._test_ds2_find_mixed_wild_plain("MFS")
|
|
|
|
def test_create_new_psp(self):
|
|
"""Create New PSP"""
|
|
ename = "getnwpsp"
|
|
cmdline = "COMMAND TAIL TEST"
|
|
|
|
self.mkfile("testit.bat", """\
|
|
c:\\%s %s
|
|
rem end
|
|
""" % (ename, cmdline), newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkcom_with_nasm(ename, r"""
|
|
bits 16
|
|
cpu 386
|
|
|
|
org 100h
|
|
|
|
section .text
|
|
|
|
; designate target segment
|
|
push cs
|
|
pop ax
|
|
add ax, 0200h
|
|
mov es, ax
|
|
|
|
; create PSP in memory
|
|
mov dx, es
|
|
mov ax, 2600h
|
|
int 21h
|
|
|
|
; see if the exit field is set
|
|
cmp word [es:0000], 20cdh
|
|
jne extfail
|
|
|
|
; see if the parent PSP is zero
|
|
cmp word [es:0016h], 0
|
|
je pntzero
|
|
|
|
; see if the parent PSP points to a PSP
|
|
push es
|
|
push word [es:0016h]
|
|
pop es
|
|
cmp word [es:0000h], 20cdh
|
|
pop es
|
|
jne pntnpsp
|
|
|
|
; see if the 'INT 21,RETF' is there
|
|
cmp word [es:0050h], 21cdh
|
|
jne int21ms
|
|
cmp byte [es:0052h], 0cbh
|
|
jne int21ms
|
|
|
|
; see if the cmdtail is there
|
|
movzx cx, byte [es:0080h]
|
|
cmp cx, %d
|
|
jne cmdlngth
|
|
|
|
inc cx
|
|
mov si, cmdline
|
|
mov di, 81h
|
|
cld
|
|
repe cmpsb
|
|
jne cmdtail
|
|
|
|
success:
|
|
mov dx, successmsg
|
|
jmp exit
|
|
|
|
extfail:
|
|
mov dx, extfailmsg
|
|
jmp exit
|
|
|
|
pntzero:
|
|
mov dx, pntzeromsg
|
|
jmp exit
|
|
|
|
pntnpsp:
|
|
mov dx, pntnpspmsg
|
|
jmp exit
|
|
|
|
int21ms:
|
|
mov dx, int21msmsg
|
|
jmp exit
|
|
|
|
cmdlngth:
|
|
mov dx, cmdlngthmsg
|
|
jmp exit
|
|
|
|
cmdtail:
|
|
mov dx, cmdtailmsg
|
|
jmp exit
|
|
|
|
exit:
|
|
mov ah, 9
|
|
int 21h
|
|
|
|
mov ah, 4ch
|
|
int 21h
|
|
|
|
extfailmsg:
|
|
db "PSP exit field not set to CD20",13,10,'$'
|
|
|
|
pntzeromsg:
|
|
db "PSP parent is zero",13,10,'$'
|
|
|
|
pntnpspmsg:
|
|
db "PSP parent doesn't point to a PSP",13,10,'$'
|
|
|
|
int21msmsg:
|
|
db "PSP is missing INT21, RETF",13,10,'$'
|
|
|
|
cmdlngthmsg:
|
|
db "PSP has incorrect command length",13,10,'$'
|
|
|
|
cmdtailmsg:
|
|
db "PSP has incorrect command tail",13,10,'$'
|
|
|
|
successmsg:
|
|
db "PSP structure okay",13,10,'$'
|
|
|
|
; 05 20 54 45 53 54 0d
|
|
cmdline:
|
|
db " %s",13
|
|
|
|
""" % (1 + len(cmdline), cmdline))
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
self.assertIn("PSP structure okay", results)
|
|
|
|
# Tests using neither compiler nor assembler
|
|
|
|
def test_systype(self):
|
|
"""SysType"""
|
|
self.runDosemu("version.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_debug = "-D+d"
|
|
""")
|
|
|
|
# read the logfile
|
|
systypeline = "Not found in logfile"
|
|
with open(self.logfiles['log'][0], "r") as f:
|
|
for line in f:
|
|
if "system type is" in line:
|
|
systypeline = line
|
|
break
|
|
|
|
self.assertIn(self.systype, systypeline)
|
|
|
|
def test_command_com_keyword_exist(self):
|
|
"""Command.com keyword exist"""
|
|
self.mkfile("testit.bat", r"""
|
|
rem X: is a non-existent drive
|
|
if not exist X:\ANYTHING.EXE echo 00_True
|
|
if not exist X:\NUL echo 01_True
|
|
if not exist X:\FAKEDIR\NUL echo 02_True
|
|
|
|
rem D: is a FAT(local) drive
|
|
D:
|
|
cd \
|
|
mkdir ISDIR
|
|
echo hello > ISDIR\EXIST.TRU
|
|
if exist D:\NUL echo 03_True
|
|
if not exist D:\EXIST.NOT echo 04_True
|
|
if not exist D:\NODIR\NUL echo 05_True
|
|
if not exist D:\NODIR\ANYTHING.EXE echo 06_True
|
|
if exist D:\ISDIR\EXIST.TRU echo 07_True
|
|
if not exist D:\ISDIR\EXIST.NOT echo 08_True
|
|
|
|
rem C: is an MFS(network redirected) drive
|
|
C:
|
|
cd \
|
|
mkdir ISDIR
|
|
echo hello > ISDIR\EXIST.TRU
|
|
if exist C:\NUL echo 09_True
|
|
if not exist C:\EXIST.NOT echo 10_True
|
|
if not exist C:\NODIR\NUL echo 11_True
|
|
if not exist C:\NODIR\ANYTHING.EXE echo 12_True
|
|
if exist C:\ISDIR\EXIST.TRU echo 13_True
|
|
if not exist C:\ISDIR\EXIST.NOT echo 14_True
|
|
|
|
rem end
|
|
""", newline="\r\n")
|
|
|
|
testdir = self.mkworkdir('d')
|
|
name = self.mkimage("12", cwd=testdir)
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
""" % name)
|
|
|
|
for i in range(15):
|
|
with self.subTest("Subtest %02d" % i):
|
|
self.assertRegex(results, r"(?m)^%02d_True.*" % i)
|
|
|
|
def _test_memory_dpmi_ecm(self, name):
|
|
ename = "%s.com" % name
|
|
edir = self.topdir / "test" / "ecm" / "dpmitest"
|
|
|
|
call(["make", "--quiet", "-C", str(edir), ename])
|
|
copy(edir / ename, self.workdir)
|
|
|
|
self.mkfile("testit.bat", """\
|
|
c:\\%s
|
|
rem end
|
|
""" % name, newline="\r\n")
|
|
|
|
return self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
def test_memory_dpmi_ecm_alloc(self):
|
|
"""Memory DPMI (ECM) alloc"""
|
|
results = self._test_memory_dpmi_ecm("dpmialoc")
|
|
# About to Execute : dpmialoc.com
|
|
# Protected mode breakpoint at 0221h.
|
|
# 32-bit code segment breakpoint at 0233h.
|
|
# Return from child process at 0403h.
|
|
|
|
# Welcome in 32-bit protected mode.
|
|
# DPMI allocation at 02121000h.
|
|
# DPMI allocation entrypoint at 00EFh:00000000h.
|
|
# Real mode procedure called at 00EFh:00000044h.
|
|
# DPMI allocation exit at 00EFh:0000006Ch.
|
|
# Hello from DPMI memory section!
|
|
# Calling real mode procedure which called callback successful.
|
|
# Child process terminated okay, back in real mode.
|
|
|
|
self.assertRegex(results, r"Protected mode breakpoint at")
|
|
self.assertRegex(results, r"32-bit code segment breakpoint at")
|
|
self.assertRegex(results, r"Return from child process at")
|
|
self.assertRegex(results, r"Welcome in 32-bit protected mode")
|
|
self.assertRegex(results, r"Hello from DPMI memory section!")
|
|
self.assertRegex(results, r"Calling real mode procedure which called callback successful")
|
|
self.assertRegex(results, r"Child process terminated okay, back in real mode")
|
|
self.assertNotIn("fail", results)
|
|
test_memory_dpmi_ecm_alloc.dpmitest=True
|
|
|
|
def test_memory_dpmi_ecm_mini(self):
|
|
"""Memory DPMI (ECM) mini"""
|
|
results = self._test_memory_dpmi_ecm("dpmimini")
|
|
|
|
# About to Execute : dpmimini.com
|
|
# Protected mode breakpoint at 015Ah.
|
|
# 32-bit code segment breakpoint at 016Ch.
|
|
#
|
|
# Welcome in 32-bit protected mode.
|
|
|
|
self.assertRegex(results, r"Protected mode breakpoint at")
|
|
self.assertRegex(results, r"32-bit code segment breakpoint at")
|
|
self.assertRegex(results, r"Welcome in 32-bit protected mode")
|
|
self.assertNotIn("fail", results)
|
|
test_memory_dpmi_ecm_mini.dpmitest=True
|
|
|
|
def test_memory_dpmi_ecm_modeswitch(self):
|
|
"""Memory DPMI (ECM) Mode Switch"""
|
|
results = self._test_memory_dpmi_ecm("dpmims")
|
|
|
|
# About to Execute : dpmims.com
|
|
# Protected mode breakpoint at 015Eh.
|
|
#
|
|
# Welcome in protected mode.
|
|
# Mode-switched to real mode.
|
|
# In protected mode again.
|
|
|
|
self.assertRegex(results, r"Protected mode breakpoint at")
|
|
self.assertRegex(results, r"Welcome in protected mode")
|
|
self.assertRegex(results, r"Mode-switched to real mode")
|
|
self.assertRegex(results, r"In protected mode again")
|
|
self.assertNotIn("fail", results)
|
|
test_memory_dpmi_ecm_modeswitch.dpmitest=True
|
|
|
|
def test_memory_dpmi_ecm_psp(self):
|
|
"""Memory DPMI (ECM) psp"""
|
|
results = self._test_memory_dpmi_ecm("dpmipsp")
|
|
|
|
# About to Execute : dpmipsp.com
|
|
# Protected mode breakpoint at 0221h.
|
|
# 32-bit code segment breakpoint at 0233h.
|
|
# Real mode procedure called at 0275h.
|
|
# Return from child process at 02FCh.
|
|
#
|
|
# Welcome in 32-bit protected mode.
|
|
# Calling real mode procedure which called callback successful.
|
|
# Child process terminated okay, back in real mode.
|
|
|
|
self.assertRegex(results, r"Protected mode breakpoint at")
|
|
self.assertRegex(results, r"32-bit code segment breakpoint at")
|
|
self.assertRegex(results, r"Real mode procedure called at")
|
|
self.assertRegex(results, r"Return from child process at")
|
|
self.assertRegex(results, r"Welcome in 32-bit protected mode")
|
|
self.assertRegex(results, r"Calling real mode procedure which called callback successful")
|
|
self.assertRegex(results, r"Child process terminated okay, back in real mode")
|
|
self.assertNotIn("fail", results)
|
|
test_memory_dpmi_ecm_psp.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth(self):
|
|
"""Memory DPMI (Japheth) ''"""
|
|
memory_dpmi_japheth(self, '')
|
|
test_memory_dpmi_japheth.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth_c(self):
|
|
"""Memory DPMI (Japheth) '-c'"""
|
|
memory_dpmi_japheth(self, '-c')
|
|
test_memory_dpmi_japheth_c.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth_d(self):
|
|
"""Memory DPMI (Japheth) '-d'"""
|
|
memory_dpmi_japheth(self, '-d')
|
|
test_memory_dpmi_japheth_d.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth_e(self):
|
|
"""Memory DPMI (Japheth) '-e'"""
|
|
memory_dpmi_japheth(self, '-e')
|
|
test_memory_dpmi_japheth_e.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth_i(self):
|
|
"""Memory DPMI (Japheth) '-i'"""
|
|
memory_dpmi_japheth(self, '-i')
|
|
test_memory_dpmi_japheth_i.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth_m(self):
|
|
"""Memory DPMI (Japheth) '-m'"""
|
|
memory_dpmi_japheth(self, '-m')
|
|
test_memory_dpmi_japheth_m.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth_r(self):
|
|
"""Memory DPMI (Japheth) '-r'"""
|
|
memory_dpmi_japheth(self, '-r')
|
|
test_memory_dpmi_japheth_r.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth_t(self):
|
|
"""Memory DPMI (Japheth) '-t'"""
|
|
memory_dpmi_japheth(self, '-t')
|
|
test_memory_dpmi_japheth_t.dpmitest=True
|
|
|
|
def test_memory_dpmi_japheth_z(self):
|
|
"""Memory DPMI (Japheth) '-z'"""
|
|
memory_dpmi_japheth(self, '-z')
|
|
test_memory_dpmi_japheth_z.dpmitest=True
|
|
|
|
def test_memory_emm286_borland(self):
|
|
"""Memory EMM286 (Borland)"""
|
|
|
|
self.unTarOrSkip("TEST_EMM286.tar", [
|
|
("tasm32.exe", "61c2ddb2c193f49dd29c083579ec7f47566278a7"),
|
|
("emm286.exe", "d8388a574f024d500515e4f0575958cf52939f26"),
|
|
("32rtm.exe", "720c8bdcb0b3b2634e95c89c56c0cc1573272cd9"),
|
|
])
|
|
|
|
# Modify the config.sys
|
|
contents = (self.workdir / self.confsys).read_text()
|
|
contents = re.sub(r"device=(c:\\)?dosemu\\umb.sys", r"device=\1dosemu\\umb.sys /full", contents)
|
|
contents = re.sub(r"devicehigh=(c:\\)?dosemu\\ems.sys", r"devicehigh=c:\\emm286.exe 2048", contents)
|
|
self.mkfile(self.confsys, contents, newline="\r\n")
|
|
|
|
self.mkfile("testit.bat", """\
|
|
c:\\tasm32 /h
|
|
rem end
|
|
""", newline="\r\n")
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
# Look for last line of output to indicate successful load/run
|
|
# /zi,/zd,/zn Debug info: zi=full, zd=line numbers only, zn=none
|
|
self.assertRegex(results, r"/zi.*Debug info: zi=full")
|
|
|
|
def test_memory_ems_borland(self):
|
|
"""Memory EMS (Borland)"""
|
|
memory_ems_borland(self)
|
|
|
|
def test_memory_hma_a20(self):
|
|
"""Memory HMA a20 toggle"""
|
|
memory_hma_a20(self)
|
|
test_memory_hma_a20.hmatest = True
|
|
|
|
def test_memory_hma_alloc(self):
|
|
"""Memory HMA allocation"""
|
|
memory_hma_alloc(self)
|
|
test_memory_hma_alloc.hmatest = True
|
|
|
|
def test_memory_hma_alloc3(self):
|
|
"""Memory HMA alloc/resize/dealloc"""
|
|
memory_hma_alloc3(self)
|
|
test_memory_hma_alloc3.hmatest = True
|
|
|
|
def test_memory_hma_freespace(self):
|
|
"""Memory HMA freespace"""
|
|
memory_hma_freespace(self)
|
|
test_memory_hma_freespace.hmatest = True
|
|
|
|
def test_memory_hma_chain(self):
|
|
"""Memory HMA get chain"""
|
|
memory_hma_chain(self)
|
|
test_memory_hma_chain.hmatest = True
|
|
|
|
def test_memory_xms(self):
|
|
"""Memory XMS"""
|
|
memory_xms(self)
|
|
test_memory_xms.xmstest = True
|
|
|
|
def test_memory_dpmi10_ldt(self):
|
|
"""Memory DPMI-1.0 LDT"""
|
|
memory_dpmi_dpmi10_ldt(self)
|
|
test_memory_dpmi10_ldt.dpmitest = True
|
|
|
|
def test_memory_dpmi_leak_check_nofree(self):
|
|
"""Memory DPMI Leak Check No Free"""
|
|
memory_dpmi_leak_check(self, 'nofree')
|
|
test_memory_dpmi_leak_check_nofree.dpmitest = True
|
|
|
|
def test_memory_dpmi_leak_check_normal(self):
|
|
"""Memory DPMI Leak Check Normal"""
|
|
memory_dpmi_leak_check(self, 'normal')
|
|
test_memory_dpmi_leak_check_normal.dpmitest = True
|
|
|
|
def test_memory_dpmi_leak_check_dos_nofree(self):
|
|
"""Memory DPMI Leak Check DOS No Free"""
|
|
memory_dpmi_leak_check_dos(self, 'nofree')
|
|
test_memory_dpmi_leak_check_dos_nofree.dpmitest = True
|
|
|
|
def test_memory_dpmi_leak_check_dos_normal(self):
|
|
"""Memory DPMI Leak Check DOS Normal"""
|
|
memory_dpmi_leak_check_dos(self, 'normal')
|
|
test_memory_dpmi_leak_check_dos_normal.dpmitest = True
|
|
|
|
def test_memory_uma_strategy(self):
|
|
"""Memory UMA Strategy"""
|
|
memory_uma_strategy(self)
|
|
test_memory_uma_strategy.umatest = True
|
|
|
|
def test_floppy_img(self):
|
|
"""Floppy image file"""
|
|
# Note: image must have
|
|
# dosemu directory
|
|
# autoexec.bat
|
|
# version.bat
|
|
|
|
self.unTarImageOrSkip("boot-floppy.img")
|
|
|
|
results = self.runDosemu("version.bat", config="""\
|
|
$_hdimage = ""
|
|
$_floppy_a = "boot-floppy.img"
|
|
$_bootdrive = "a"
|
|
""")
|
|
|
|
self.assertIn(self.version, results)
|
|
|
|
def test_floppy_vfs(self):
|
|
"""Floppy vfs directory"""
|
|
self.mkfile(self.confsys, """\
|
|
DOS=UMB,HIGH
|
|
lastdrive=Z
|
|
files=40
|
|
stacks=0,0
|
|
buffers=10
|
|
device=a:\\dosemu\\emufs.sys
|
|
device=a:\\dosemu\\umb.sys
|
|
devicehigh=a:\\dosemu\\ems.sys
|
|
devicehigh=a:\\dosemu\\cdrom.sys
|
|
install=a:\\dosemu\\emufs.com
|
|
shell=command.com /e:1024 /k %s
|
|
""" % self.autoexec, newline="\r\n")
|
|
|
|
self.mkfile(self.autoexec, """\
|
|
prompt $P$G
|
|
path a:\\bin;a:\\gnu;a:\\dosemu
|
|
system -s DOSEMU_VERSION
|
|
@echo %s
|
|
""" % IPROMPT, newline="\r\n")
|
|
|
|
results = self.runDosemu("version.bat", config="""\
|
|
$_hdimage = ""
|
|
$_floppy_a = "dXXXXs/c:fiveinch_360"
|
|
$_bootdrive = "a"
|
|
""")
|
|
|
|
self.assertIn(self.version, results)
|
|
|
|
def test_three_drives_vfs(self):
|
|
"""Three vfs directories configured"""
|
|
# C exists as part of standard test
|
|
self.mkworkdir('d')
|
|
self.mkworkdir('e')
|
|
|
|
results = self.runDosemu("version.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 dXXXXs/e:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
self.assertIn(self.version, results) # Just to check we booted
|
|
|
|
def _test_fat_img_d_writable(self, fat):
|
|
self.mkfile("testit.bat", """\
|
|
D:
|
|
mkdir test
|
|
echo hello > hello.txt
|
|
DIR
|
|
rem end
|
|
""", newline="\r\n")
|
|
|
|
testdir = self.mkworkdir('d')
|
|
|
|
testfil = testdir / "there.txt"
|
|
testfil.write_text('there')
|
|
|
|
name = self.mkimage_vbr(fat, cwd=testdir)
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
""" % name)
|
|
|
|
# Std DOS format
|
|
# TEST <DIR>
|
|
# HELLO TXT 8
|
|
#
|
|
# ComCom32 format
|
|
# 2019-06-28 22:29 <DIR> TEST
|
|
# 2019-06-28 22:29 8 HELLO.TXT
|
|
self.assertRegex(results,
|
|
r"TEST[\t ]+<DIR>"
|
|
r"|"
|
|
r"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s<DIR>\s+TEST")
|
|
self.assertRegex(results,
|
|
r"HELLO[\t ]+TXT[\t ]+8"
|
|
r"|"
|
|
r"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s+8\s+HELLO.TXT")
|
|
self.assertRegex(results,
|
|
r"THERE[\t ]+TXT[\t ]+5"
|
|
r"|"
|
|
r"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s+5\s+THERE.TXT")
|
|
|
|
def test_fat12_img_d_writable(self):
|
|
"""FAT12 image file D writable"""
|
|
self._test_fat_img_d_writable("12")
|
|
|
|
def test_fat16_img_d_writable(self):
|
|
"""FAT16 image file D writable"""
|
|
self._test_fat_img_d_writable("16")
|
|
|
|
def test_fat16b_img_d_writable(self):
|
|
"""FAT16B image file D writable"""
|
|
self._test_fat_img_d_writable("16b")
|
|
|
|
def test_fat32_img_d_writable(self):
|
|
"""FAT32 image file D writable"""
|
|
self._test_fat_img_d_writable("32")
|
|
|
|
def test_mfs_lredir_auto_hdc(self):
|
|
"""MFS lredir auto C drive redirection"""
|
|
self.mkfile("testit.bat", "lredir\r\nrem end\r\n")
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
""")
|
|
|
|
# C:\>lredir
|
|
# Current Drive Redirections:
|
|
# C: = LINUX\FS\dosemu2.git\test-imagedir\dXXXXs\c\ attrib = READ/WRITE
|
|
|
|
self.assertRegex(results, r"C: = /.*")
|
|
|
|
def test_mfs_lredir_command(self):
|
|
"""MFS lredir command redirection"""
|
|
self.mkfile("testit.bat", """\
|
|
lredir X: /tmp
|
|
lredir
|
|
rem end
|
|
""", newline="\r\n")
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
$_lredir_paths = "/tmp"
|
|
""")
|
|
|
|
# A:\>lredir
|
|
# Current Drive Redirections:
|
|
# C: = LINUX\FS\dosemu2.git\test-imagedir\dXXXXs\c\ attrib = READ/WRITE
|
|
# X: = LINUX\FS\tmp\ attrib = READ/WRITE
|
|
|
|
self.assertRegex(results, r"X: = /tmp")
|
|
|
|
def test_mfs_lredir_command_no_perm(self):
|
|
"""MFS lredir command redirection permission fail"""
|
|
self.mkfile("testit.bat", """\
|
|
lredir X: /tmp
|
|
lredir
|
|
rem end
|
|
""", newline="\r\n")
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
# A:\>lredir
|
|
# Current Drive Redirections:
|
|
# C: = LINUX\FS\dosemu2.git\test-imagedir\dXXXXs\c\ attrib = READ/WRITE
|
|
# X: = LINUX\FS\tmp\ attrib = READ/WRITE
|
|
|
|
self.assertRegex(results, r"Error 5 \(access denied\) while redirecting drive X:")
|
|
|
|
# Tests using the DJGPP DOS compiler
|
|
|
|
def test_mfs_findfile_ufs_lfn(self):
|
|
"""MFS findfile UFS LFN"""
|
|
tests = (
|
|
# Type, Create, Find
|
|
("DIR", "Program Files", "Program Files"),
|
|
("FILE", "verylongfilename.txt", "verylongfilename.txt"),
|
|
("FILE", "verylongfilename2.txt", "verylongfilename2.txt"),
|
|
("FILE", "space embedded filename.txt", "space embedded filename.txt"),
|
|
("FILE", "MixedCaseFilename.ext", "MixedCaseFilename.ext"),
|
|
)
|
|
mfs_findfile(self, "UFS", "LFN", tests)
|
|
|
|
def test_mfs_findfile_ufs_sfn(self):
|
|
"""MFS findfile UFS SFN"""
|
|
tests = (
|
|
# Type, Create, Find
|
|
("DIR", "Program Files", "PROGR~-I"),
|
|
("FILE", "verylongfilename.txt", "VERYL~3G.TXT"),
|
|
("FILE", "verylongfilename2.txt", "VERYL~2N.TXT"),
|
|
("FILE", "space embedded filename.txt", "SPACE~L#.TXT"),
|
|
("FILE", "MixedCaseFilename.ext", "MIXED~G4.EXT"),
|
|
)
|
|
mfs_findfile(self, "UFS", "SFN", tests)
|
|
|
|
def test_mfs_findfile_vfat_linux_mounted_lfn(self):
|
|
"""MFS findfile VFAT Linux mounted LFN"""
|
|
tests = (
|
|
# Type, Create, Find
|
|
("DIR", "Program Files", "Program Files"),
|
|
("FILE", "verylongfilename.txt", "verylongfilename.txt"),
|
|
("FILE", "verylongfilename2.txt", "verylongfilename2.txt"),
|
|
("FILE", "space embedded filename.txt", "space embedded filename.txt"),
|
|
("FILE", "MixedCaseFilename.ext", "MixedCaseFilename.ext"),
|
|
)
|
|
mfs_findfile(self, "VFAT", "LFN", tests)
|
|
|
|
def test_mfs_findfile_vfat_linux_mounted_sfn(self):
|
|
"""MFS findfile VFAT Linux mounted SFN"""
|
|
tests = (
|
|
# Type, Create, Find
|
|
("DIR", "Program Files", "PROGRA~1"),
|
|
("FILE", "verylongfilename.txt", "VERYLO~1.TXT"),
|
|
("FILE", "verylongfilename2.txt", "VERYLO~2.TXT"),
|
|
("FILE", "space embedded filename.txt", "SPACEE~1.TXT"),
|
|
("FILE", "MixedCaseFilename.ext", "MIXEDC~1.EXT"),
|
|
)
|
|
mfs_findfile(self, "VFAT", "SFN", tests)
|
|
|
|
def test_mfs_truename_ufs_lfn(self):
|
|
"""MFS truename UFS LFN"""
|
|
names_to_create = (
|
|
("DIR", "Program Files"),
|
|
("DIR", "RealDir2"),
|
|
("DIR", "Sub"),
|
|
("DIR", "Sub/RealDir"),
|
|
("FILE", "Sub/Very Long realName"),
|
|
("FILE", "Sub/verylongRealname.txt"),
|
|
("FILE", "Sub/RealDir/Very Long realName"),
|
|
)
|
|
tests = ( # Note: CurDrv == D:, CurDir == \Sub
|
|
|
|
# These LFN 7160/0 tests are proven on Win98 and are seen
|
|
# to have the following rules:
|
|
# 1/ Any '..' are resolved.
|
|
# 2/ Any '.\' are stripped.
|
|
# 3/ If no drive specification, then default drive is prepended.
|
|
# 4/ If not absolute path, then current directory for drive
|
|
# is inserted between drive and relative path.
|
|
# 5/ All path components (except final) are upcased.
|
|
# 6/ Final path component case is preserved from the request.
|
|
# 7/ No path component has to exist on the filesystem or
|
|
# is checked against it and updated for case.
|
|
|
|
("LFN0", r"aux", r"D:/AUX"),
|
|
# D:\Sub exists as a directory
|
|
("LFN0", r"nonExist", r"D:\\SUB\\nonExist"),
|
|
("LFN0", r"\\nonExist", r"D:\\nonExist"),
|
|
("LFN0", r"\\Sub\\nonExist", r"D:\\SUB\\nonExist"),
|
|
("LFN0", r"c:nonExist", r"C:\\nonExist"),
|
|
("LFN0", r"c:\\nonExist", r"C:\\nonExist"),
|
|
("LFN0", r"c:\\RootC\\nonExist", r"C:\\ROOTC\\nonExist"),
|
|
# Both D:\RealDir2 and D:\\Sub\\RealDir exist as directories
|
|
("LFN0", r"d:realdir", r"D:\\SUB\\realdir"),
|
|
("LFN0", r"d:\\realdir2", r"D:\\realdir2"),
|
|
("LFN0", r"d:\\realdir2\\noNexist.TxT", r"D:\\REALDIR2\\noNexist.TxT"),
|
|
# D:\Sub exists as a directory
|
|
("LFN0", r"nonExist\\NewFile.txt", r"D:\\SUB\\NONEXIST\\NewFile.txt"),
|
|
("LFN0", r"d:nonExist\\NewFile.txt", r"D:\\SUB\\NONEXIST\\NewFile.txt"),
|
|
("LFN0", r"d:\\nonExist\\NewFile.txt", r"D:\\NONEXIST\\NewFile.txt"),
|
|
("LFN0", r"..\\Sub\\RealDir\\..\\NewFile.txt", r"D:\\SUB\\NewFile.txt"),
|
|
# D:\Program Files exists as a directory
|
|
("LFN0", r"D:\\progra~1", r"D:\\progra~1"),
|
|
("LFN0", r"D:\\PROGRA~1", r"D:\\PROGRA~1"),
|
|
("LFN0", r"D:\\program files", r"D:\\program files"),
|
|
("LFN0", r"D:\\PROGRAM FILES", r"D:\\PROGRAM FILES"),
|
|
("LFN0", r"D:\\Program Files", r"D:\\Program Files"),
|
|
("LFN0", r"D:\\Program Files\\NewFile.txt", r"D:\\PROGRAM FILES\\NewFile.txt"),
|
|
("LFN0", r"D:\\Program Files\\NewFile.txt", r"D:\\PROGRAM FILES\\NewFile.txt"),
|
|
("LFN0", r"D:\\Program Files\\NonExist\\NewFile.txt", r"D:\\PROGRAM FILES\\NONEXIST\\NewFile.txt"),
|
|
|
|
("LFN1", r"d:very long realname", r"D:\\SUB\\VERYL~CV"),
|
|
("LFN1", r"d:\\very long realname", r"ERROR: invalid component"),
|
|
("LFN1", r"d:\\Sub\\VERYLONGrEALNAME.TXT", r"D:\\SUB\\VERYL~6S.TXT"),
|
|
("LFN1", r"D:\\program files", r"D:\\PROGR~-I"),
|
|
("LFN1", r"D:\\PROGRAM FILES", r"D:\\PROGR~-I"),
|
|
("LFN1", r"D:\\Program Files", r"D:\\PROGR~-I"),
|
|
|
|
("LFN2", r"D:\\SUB\\VERYL~CV", r"D:\\Sub\\Very Long realName"),
|
|
("LFN2", r"D:\\SUB\\VERYL~6S.TXT", r"D:\\Sub\\verylongRealname.txt"),
|
|
("LFN2", r"D:\\progr~-i", r"D:\\Program Files"),
|
|
("LFN2", r"D:\\PROGR~-I", r"D:\\Program Files"),
|
|
)
|
|
mfs_truename(self, "UFS", names_to_create, tests)
|
|
|
|
def test_mfs_truename_ufs_sfn(self):
|
|
"""MFS truename UFS SFN"""
|
|
names_to_create = (
|
|
("DIR", "Sub"),
|
|
("DIR", "Sub/testname"),
|
|
("FILE", "shrtname.txt"),
|
|
)
|
|
tests = ( # Note: CurDrv == D:, CurDir == \SUB
|
|
("SFN", r"aux", r"D:/AUX"),
|
|
|
|
("SFN", r"fakename", r"D:\\SUB\\FAKENAME"), # Non existent
|
|
("SFN", r"\\fakename", r"D:\\FAKENAME"), # Non existent
|
|
("SFN", r"\\Sub\\fakename", r"D:\\SUB\\FAKENAME"), # Non existent
|
|
("SFN", r"c:fakename", r"C:\\FAKENAME"), # Non existent
|
|
("SFN", r"c:\\fakename", r"C:\\FAKENAME"), # Non existent
|
|
("SFN", r"c:\\Sub\\fakename", r"C:\\SUB\\FAKENAME"), # Non existent
|
|
|
|
("SFN", r"testname", r"D:\\SUB\\TESTNAME"),
|
|
("SFN", r"\\Sub\\testname", r"D:\\SUB\\TESTNAME"),
|
|
("SFN", r"d:testname", r"D:\\SUB\\TESTNAME"),
|
|
("SFN", r"d:\\Sub\\testname", r"D:\\SUB\\TESTNAME"),
|
|
|
|
("SFN", r"shrtname.txt", r"D:\\SUB\\SHRTNAME.TXT"), # Non existent
|
|
("SFN", r"\\shrtname.txt", r"D:\\SHRTNAME.TXT"),
|
|
("SFN", r"d:shrtname.txt", r"D:\\SUB\\SHRTNAME.TXT"), # Non existent
|
|
("SFN", r"d:\\shrtname.txt", r"D:\\SHRTNAME.TXT"),
|
|
)
|
|
mfs_truename(self, "UFS", names_to_create, tests)
|
|
|
|
def test_mfs_truename_vfat_linux_mounted_lfn(self):
|
|
"""MFS truename VFAT Linux mounted LFN"""
|
|
names_to_create = (
|
|
("DIR", "Program Files"),
|
|
("FILE", "lfnInRoot.tXt"),
|
|
("FILE", "Sub/verylongfilename.txt"),
|
|
("FILE", "Sub/verylongfilename2.txt"),
|
|
("FILE", "Sub/space embedded filename.txt"),
|
|
("FILE", "Sub/MixedCaseFilename.ext"),
|
|
("DIR", "Sub/test/1234567890987654321"),
|
|
("DIR", "Sub/abcdefgfedcba/1234567890987654321"),
|
|
("FILE", "Sub/1234567890987654321/abcdefgfedcba.txt"),
|
|
("FILE", "Sub/1234567890987654321/abcdefclash.txt"),
|
|
)
|
|
tests = (
|
|
# Since Truename 0x7160/0 does not interact with the filesystem,
|
|
# the tests on UFS should give coverage, but just do a few for
|
|
# belt and braces.
|
|
("LFN0", r"D:\\progra~1", r"D:\\progra~1"),
|
|
("LFN0", r"D:\\PROGRA~1", r"D:\\PROGRA~1"),
|
|
("LFN0", r"D:\\program files", r"D:\\program files"),
|
|
("LFN0", r"D:\\PROGRAM FILES", r"D:\\PROGRAM FILES"),
|
|
("LFN0", r"D:\\Program Files", r"D:\\Program Files"),
|
|
("LFN0", r"D:\\Program Files\\NewFile.txt", r"D:\\PROGRAM FILES\\NewFile.txt"),
|
|
("LFN0", r"D:\\Program Files\\NewFile.txt", r"D:\\PROGRAM FILES\\NewFile.txt"),
|
|
("LFN0", r"D:\\Program Files\\NonExist\\NewFile.txt", r"D:\\PROGRAM FILES\\NONEXIST\\NewFile.txt"),
|
|
|
|
("LFN1", r"X:\\lfnNotInRoot.tXt", r"ERROR: invalid component"), # Non existent
|
|
("LFN1", r"..\\lfnNotInRoot.tXt", r"ERROR: invalid component"), # Non existent
|
|
("LFN1", r"X:\\lfnInRoot.tXt", r"X:\\LFNINR~1.TXT"),
|
|
("LFN1", r"..\\lfnInRoot.tXt", r"X:\\LFNINR~1.TXT"),
|
|
("LFN1", r"..\\rootc\\..\\lfnInRoot.tXt", r"X:\\LFNINR~1.TXT"),
|
|
("LFN1", r"X:\\sub\\verylongfilename.txt", r"X:\\SUB\\VERYLO~1.TXT"),
|
|
("LFN1", r"X:\\sub\\verylongfilename2.txt", r"X:\\SUB\\VERYLO~2.TXT"),
|
|
("LFN1", r"X:\\sub\\space embedded filename.txt", r"X:\\SUB\\SPACEE~1.TXT"),
|
|
("LFN1", r"X:\\sub\\MixedCaseFilename.ext", r"X:\\SUB\\MIXEDC~1.EXT"),
|
|
("LFN1", r"X:\\sub\\test\\1234567890987654321", r"X:\\SUB\\TEST\\123456~1"),
|
|
("LFN1", r"X:\\sub\\abcdefgfedcba\\1234567890987654321", r"X:\\SUB\\ABCDEF~1\\123456~1"),
|
|
("LFN1", r"X:\\sub\\1234567890987654321\\abcdefgfedcba.txt", r"X:\\SUB\\123456~1\\ABCDEF~1.TXT"),
|
|
("LFN1", r"X:\\sub\\1234567890987654321\\abcdefclash.txt", r"X:\\SUB\\123456~1\\ABCDEF~2.TXT"),
|
|
("LFN1", r"1234567890987654321\\abcdefclash.txt", r"X:\\SUB\\123456~1\\ABCDEF~2.TXT"),
|
|
("LFN1", r".\\1234567890987654321\\abcdefclash.txt", r"X:\\SUB\\123456~1\\ABCDEF~2.TXT"),
|
|
("LFN1", r"..\\sub\\1234567890987654321\\abcdefclash.txt", r"X:\\SUB\\123456~1\\ABCDEF~2.TXT"),
|
|
("LFN1", r"X:\\program files", r"X:\\PROGRA~1"),
|
|
("LFN1", r"X:\\PROGRAM FILES", r"X:\\PROGRA~1"),
|
|
("LFN1", r"X:\\Program Files", r"X:\\PROGRA~1"),
|
|
|
|
("LFN2", r"X:\\LFNNOT~1.TXT", r"ERROR: invalid component"), # Non existent
|
|
("LFN2", r"X:\\LFNINR~1.TXT", r"X:\\lfnInRoot.tXt"),
|
|
("LFN2", r"X:\\sub\\VERYLO~1.TXT", r"X:\\Sub\\verylongfilename.txt"),
|
|
("LFN2", r"X:\\sub\\VERYLO~2.TXT", r"X:\\Sub\\verylongfilename2.txt"),
|
|
("LFN2", r"X:\\sub\\SPACEE~1.TXT", r"X:\\Sub\\space embedded filename.txt"),
|
|
("LFN2", r"X:\\sub\\MIXEDC~1.EXT", r"X:\\Sub\\MixedCaseFilename.ext"),
|
|
("LFN2", r"X:\\sub\\TEST\\123456~1", r"X:\\Sub\\test\\1234567890987654321"),
|
|
("LFN2", r"X:\\sub\\ABCDEF~1\\123456~1", r"X:\\Sub\\abcdefgfedcba\\1234567890987654321"),
|
|
("LFN2", r"X:\\sub\\123456~1\\ABCDEF~1.TXT", r"X:\\Sub\\1234567890987654321\\abcdefgfedcba.txt"),
|
|
("LFN2", r"X:\\sub\\123456~1\\ABCDEF~2.TXT", r"X:\\Sub\\1234567890987654321\\abcdefclash.txt"),
|
|
("LFN2", r"X:\\progra~1", r"X:\\Program Files"),
|
|
("LFN2", r"X:\\PROGRA~1", r"X:\\Program Files"),
|
|
("LFN2", r"X:\\PROGRA~1", r"X:\\Program Files"),
|
|
)
|
|
mfs_truename(self, "VFAT", names_to_create, tests)
|
|
|
|
def test_mfs_truename_vfat_linux_mounted_sfn(self):
|
|
"""MFS truename VFAT Linux mounted SFN"""
|
|
names_to_create = (
|
|
("DIR", "testname"),
|
|
("FILE", "Sub/shrtname.txt"),
|
|
("FILE", "Sub/verylongfilename.txt"),
|
|
("FILE", "Sub/verylongfilename2.txt"),
|
|
("FILE", "Sub/space embedded filename.txt"),
|
|
("FILE", "Sub/MixedCaseFilename.ext"),
|
|
("DIR", "Sub/test/1234567890987654321"),
|
|
("DIR", "Sub/abcdefgfedcba/1234567890987654321"),
|
|
("FILE", "Sub/654321fedcba/abcdef123456.txt"),
|
|
("FILE", "Sub/654321fedcba/abcdefclash.txt"),
|
|
)
|
|
tests = ( # Note: CurDrv == X:, CurDir == \SUB
|
|
("SFN", r"X:\\testname", r"X:\\TESTNAME"),
|
|
("SFN", r"..\\testname", r"X:\\TESTNAME"),
|
|
("SFN", r"testname", r"X:\\SUB\\TESTNAME"), # Non existent
|
|
("SFN", r"X:\\sub\\shrtname.txt", r"X:\\SUB\\SHRTNAME.TXT"),
|
|
("SFN", r"X:\\sub\\verylo~1.txt", r"X:\\SUB\\VERYLO~1.TXT"),
|
|
("SFN", r"X:\\sub\\verylo~2.txt", r"X:\\SUB\\VERYLO~2.TXT"),
|
|
("SFN", r"X:\\sub\\spacee~1.txt", r"X:\\SUB\\SPACEE~1.TXT"),
|
|
("SFN", r"X:\\sub\\mixedc~1.ext", r"X:\\SUB\\MIXEDC~1.EXT"),
|
|
("SFN", r"X:\\sub\\test\\123456~1", r"X:\\SUB\\TEST\\123456~1"),
|
|
("SFN", r"X:\\sub\\abcdef~1\\123456~1", r"X:\\SUB\\ABCDEF~1\\123456~1"),
|
|
("SFN", r"X:\\sub\\654321~1\\abcdef~1", r"X:\\SUB\\654321~1\\ABCDEF~1"),
|
|
("SFN", r"X:\\sub\\654321~1\\abcdef~2", r"X:\\SUB\\654321~1\\ABCDEF~2"),
|
|
)
|
|
mfs_truename(self, "VFAT", names_to_create, tests)
|
|
|
|
def _test_mfs_file_read(self, nametype):
|
|
if nametype == "LFN":
|
|
testname = "verylongname.txt"
|
|
disablelfn = ""
|
|
elif nametype == "SFN":
|
|
testname = "shrtname.txt"
|
|
disablelfn = "set LFN=n"
|
|
else:
|
|
self.fail("Incorrect argument")
|
|
|
|
testdata = mkstring(128)
|
|
testdir = self.mkworkdir('d')
|
|
|
|
self.mkfile("testit.bat", """\
|
|
%s
|
|
d:
|
|
c:\\mfsread %s %s
|
|
rem end
|
|
""" % (disablelfn, testname, testdata), newline="\r\n")
|
|
|
|
self.mkfile(testname, testdata, dname=testdir)
|
|
|
|
# compile sources
|
|
self.mkexe_with_djgpp("mfsread", r"""
|
|
#include <dir.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
int main(int argc, char *argv[]) {
|
|
char b[512];
|
|
int f, size;
|
|
|
|
if (argc < 1) {
|
|
printf("missing filename argument\n");
|
|
return 3;
|
|
}
|
|
|
|
f = open(argv[1], O_RDONLY | O_TEXT);
|
|
if (f < 0) {
|
|
printf("open failed\n");
|
|
return 2;
|
|
}
|
|
|
|
size = read(f, b, sizeof(b));
|
|
if (size < 0) {
|
|
printf("read failed\n");
|
|
return 1;
|
|
}
|
|
|
|
write(1, b, size);
|
|
close(f);
|
|
return 0;
|
|
}
|
|
""")
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
self.assertIn(testdata, results)
|
|
|
|
def test_mfs_lfn_file_read(self):
|
|
"""MFS LFN file read"""
|
|
self._test_mfs_file_read("LFN")
|
|
|
|
def test_mfs_sfn_file_read(self):
|
|
"""MFS SFN file read"""
|
|
self._test_mfs_file_read("SFN")
|
|
|
|
def _test_mfs_file_write(self, nametype, operation):
|
|
if nametype == "LFN":
|
|
ename = "mfslfn"
|
|
testname = "verylongname.txt"
|
|
disablelfn = ""
|
|
elif nametype == "SFN":
|
|
ename = "mfssfn"
|
|
testname = "shrtname.txt"
|
|
disablelfn = "set LFN=n"
|
|
else:
|
|
self.fail("Incorrect argument")
|
|
|
|
if operation == "create":
|
|
ename += "wc"
|
|
testprfx = ""
|
|
openflags = "O_WRONLY | O_CREAT | O_TEXT"
|
|
mode = ", 0222"
|
|
elif operation == "createreadonly":
|
|
ename += "wk"
|
|
testprfx = ""
|
|
openflags = "O_WRONLY | O_CREAT | O_TEXT"
|
|
mode = ", 0444"
|
|
elif operation == "truncate":
|
|
ename += "wt"
|
|
testprfx = "dummy data"
|
|
openflags = "O_WRONLY | O_CREAT | O_TRUNC | O_TEXT"
|
|
mode = ", 0222"
|
|
elif operation == "append":
|
|
ename += "wa"
|
|
testprfx = "Original Data"
|
|
openflags = "O_RDWR | O_APPEND | O_TEXT"
|
|
mode = ""
|
|
else:
|
|
self.fail("Incorrect argument")
|
|
|
|
testdata = mkstring(64) # need to be fairly short to pass as arg
|
|
testdir = self.mkworkdir('d')
|
|
|
|
self.mkfile("testit.bat", """\
|
|
%s
|
|
d:
|
|
c:\\%s %s %s
|
|
rem end
|
|
""" % (disablelfn, ename, testname, testdata), newline="\r\n")
|
|
|
|
if operation != "create" and operation != "createreadonly":
|
|
self.mkfile(testname, testprfx, dname=testdir)
|
|
|
|
# compile sources
|
|
self.mkexe_with_djgpp(ename, r"""
|
|
#include <dir.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
int main(int argc, char *argv[]) {
|
|
int f, size;
|
|
|
|
if (argc < 2) {
|
|
printf("missing filename argument\n");
|
|
return 4;
|
|
}
|
|
|
|
if (argc < 3) {
|
|
printf("missing data argument\n");
|
|
return 3;
|
|
}
|
|
|
|
f = open(argv[1], %s %s);
|
|
if (f < 0) {
|
|
printf("open failed\n");
|
|
return 2;
|
|
}
|
|
|
|
size = write(f, argv[2], strlen(argv[2]));
|
|
if (size < strlen(argv[2])) {
|
|
printf("write failed\n");
|
|
return 1;
|
|
}
|
|
|
|
close(f);
|
|
return 0;
|
|
}
|
|
""" % (openflags, mode))
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
self.assertNotIn("open failed", results)
|
|
|
|
try:
|
|
with open(join(testdir, testname), "r") as f:
|
|
filedata = f.read()
|
|
if operation == "truncate":
|
|
self.assertNotIn(testprfx, filedata)
|
|
elif operation == "append":
|
|
self.assertIn(testprfx + testdata, filedata)
|
|
self.assertIn(testdata, filedata)
|
|
except IOError:
|
|
self.fail("File not created/opened")
|
|
|
|
def test_mfs_lfn_file_create(self):
|
|
"""MFS LFN file create"""
|
|
self._test_mfs_file_write("LFN", "create")
|
|
|
|
def test_mfs_sfn_file_create(self):
|
|
"""MFS SFN file create"""
|
|
self._test_mfs_file_write("SFN", "create")
|
|
|
|
def test_mfs_lfn_file_create_readonly(self):
|
|
"""MFS LFN file create readonly"""
|
|
self._test_mfs_file_write("LFN", "createreadonly")
|
|
|
|
def test_mfs_sfn_file_create_readonly(self):
|
|
"""MFS SFN file create readonly"""
|
|
self._test_mfs_file_write("SFN", "createreadonly")
|
|
|
|
def test_mfs_lfn_file_truncate(self):
|
|
"""MFS LFN file truncate"""
|
|
self._test_mfs_file_write("LFN", "truncate")
|
|
|
|
def test_mfs_sfn_file_truncate(self):
|
|
"""MFS SFN file truncate"""
|
|
self._test_mfs_file_write("SFN", "truncate")
|
|
|
|
def test_mfs_lfn_file_append(self):
|
|
"""MFS LFN file append"""
|
|
self._test_mfs_file_write("LFN", "append")
|
|
|
|
def test_mfs_sfn_file_append(self):
|
|
"""MFS SFN file append"""
|
|
self._test_mfs_file_write("SFN", "append")
|
|
|
|
def test_lfn_volume_info_mfs(self):
|
|
"""LFN volume info on MFS"""
|
|
lfn_voln_info(self, "MFS")
|
|
|
|
def test_lfn_volume_info_fat16(self):
|
|
"""LFN volume info on FAT16"""
|
|
lfn_voln_info(self, "FAT16")
|
|
|
|
def test_lfn_volume_info_fat32(self):
|
|
"""LFN volume info on FAT32"""
|
|
lfn_voln_info(self, "FAT32")
|
|
|
|
def test_int21_disk_info(self):
|
|
"""INT21 disk info"""
|
|
|
|
path = "C:\\"
|
|
|
|
self.mkfile("testit.bat", """\
|
|
c:\\int21dif %s
|
|
rem end
|
|
""" % path, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkexe_with_djgpp("int21dif", r"""\
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
struct dinfo {
|
|
uint16_t spc;
|
|
uint16_t avail_clusters;
|
|
uint16_t bps;
|
|
uint16_t total_clusters;
|
|
};
|
|
|
|
#define MAXPATH 128
|
|
|
|
int main(int argc, char *argv[]) {
|
|
struct dinfo df;
|
|
uint8_t carry;
|
|
uint16_t ax, bx, cx, dx;
|
|
int len;
|
|
|
|
if (argc < 2) {
|
|
printf("path argument missing e.g. 'C:\\'\n");
|
|
return 3;
|
|
}
|
|
|
|
len = strlen(argv[1]) + 1;
|
|
if (len > MAXPATH) {
|
|
printf("path argument too long\n");
|
|
return 2;
|
|
}
|
|
|
|
if (argv[1][0] && argv[1][1] == ':') {
|
|
if (argv[1][0] == 'a' || argv[1][0] == 'A')
|
|
dx = 1;
|
|
else if (argv[1][0] == 'b' || argv[1][0] == 'B')
|
|
dx = 2;
|
|
else if (argv[1][0] == 'c' || argv[1][0] == 'C')
|
|
dx = 3;
|
|
else if (argv[1][0] == 'd' || argv[1][0] == 'D')
|
|
dx = 4;
|
|
else {
|
|
printf("Drive out of range\n");
|
|
return 2;
|
|
}
|
|
} else {
|
|
printf("Drive used is default\n");
|
|
dx = 0; // default drive
|
|
}
|
|
|
|
/*
|
|
AH = 36h
|
|
DL = drive number (00h = default, 01h = A:, etc)
|
|
|
|
Return:
|
|
AX = FFFFh if invalid drive
|
|
else
|
|
AX = sectors per cluster
|
|
BX = number of free clusters
|
|
CX = bytes per sector
|
|
DX = total clusters on drive
|
|
*/
|
|
|
|
asm volatile("stc\n"
|
|
"int $0x21\n"
|
|
: "=a"(ax), "=b"(bx), "=c"(cx), "=d"(dx)
|
|
: "a"(0x3600), "d"(dx)
|
|
: "cc", "memory");
|
|
|
|
if (ax == 0xffff) {
|
|
printf("Call failed, AX = 0x%04x\n", ax);
|
|
return 1;
|
|
}
|
|
|
|
printf("spc 0x%04x\n", ax);
|
|
printf("avail_clusters 0x%04x\n", bx);
|
|
printf("bps 0x%04x\n", cx);
|
|
printf("total_clusters 0x%04x\n", dx);
|
|
|
|
printf("avail_bytes(%llu)\n",
|
|
(unsigned long long)ax * (unsigned long long)cx * (unsigned long long)bx);
|
|
printf("total_bytes(%llu)\n",
|
|
(unsigned long long)ax * (unsigned long long)cx * (unsigned long long)dx);
|
|
return 0;
|
|
}
|
|
""")
|
|
|
|
results = self.runDosemu("testit.bat", config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
self.assertNotIn("Call failed", results)
|
|
|
|
fsinfo = statvfs(self.workdir)
|
|
lfs_total = fsinfo.f_blocks * fsinfo.f_bsize
|
|
lfs_avail = fsinfo.f_bavail * fsinfo.f_bsize
|
|
|
|
r1 = re.compile(r'total_bytes\((\d+)\)')
|
|
self.assertRegex(results, r1)
|
|
t = r1.search(results)
|
|
dfs_total = int(t.group(1))
|
|
|
|
r2 = re.compile(r'avail_bytes\((\d+)\)')
|
|
self.assertRegex(results, r2)
|
|
a = r2.search(results)
|
|
dfs_avail = int(a.group(1))
|
|
|
|
# see if we are within 5% of the values obtained from Linux
|
|
if lfs_total > 2147450880:
|
|
lfs_total = 2147450880
|
|
if lfs_avail > 2147450880:
|
|
lfs_avail = 2147450880
|
|
msg = "total dos %d, linux %d" % (dfs_total, lfs_total)
|
|
self.assertLessEqual(dfs_total, lfs_total * 1.05, msg)
|
|
self.assertGreaterEqual(dfs_total, lfs_total * 0.95, msg)
|
|
|
|
msg = "avail dos %d, linux %d" % (dfs_avail, lfs_avail)
|
|
self.assertLessEqual(dfs_avail, lfs_avail * 1.05, msg)
|
|
self.assertGreaterEqual(dfs_avail, lfs_avail * 0.95, msg)
|
|
|
|
def test_lfs_disk_info_fat32(self):
|
|
"""LFS disk info FAT32"""
|
|
lfs_disk_info(self, "FAT32")
|
|
|
|
def test_lfs_disk_info_mfs(self):
|
|
"""LFS disk info MFS"""
|
|
lfs_disk_info(self, "MFS")
|
|
|
|
def test_mfs_lfs_file_info_1MiB(self):
|
|
"""MFS LFS file info (1 MiB)"""
|
|
lfs_file_info(self, "MFS", "1MiB")
|
|
|
|
def test_mfs_lfs_file_info_6GiB(self):
|
|
"""MFS LFS file info (6 GiB)"""
|
|
lfs_file_info(self, "MFS", "6GiB")
|
|
|
|
def test_mfs_lfs_file_seek_tell_set(self):
|
|
"""MFS LFS file seek tell set"""
|
|
lfs_file_seek_tell(self, "MFS", "SET")
|
|
|
|
def test_mfs_lfs_file_seek_tell_cur(self):
|
|
"""MFS LFS file seek tell current"""
|
|
lfs_file_seek_tell(self, "MFS", "CUR")
|
|
|
|
def test_mfs_lfs_file_seek_tell_end(self):
|
|
"""MFS LFS file seek tell end"""
|
|
lfs_file_seek_tell(self, "MFS", "END")
|
|
|
|
def _test_ds2_get_ftime(self, fstype, tstype):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\getftime %s
|
|
rem end
|
|
""" % tstype, newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkexe_with_djgpp("getftime", r"""
|
|
|
|
#include <dos.h>
|
|
#include <dir.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
int gettest(const char *fname) {
|
|
|
|
int handle;
|
|
int ret;
|
|
unsigned int date, time;
|
|
unsigned int year, month, day, hour, minute, second;
|
|
|
|
ret = _dos_open(fname, O_RDONLY, &handle);
|
|
if (ret != 0) {
|
|
printf("FAIL: File '%s' not opened\n", fname);
|
|
return -1;
|
|
}
|
|
_dos_getftime(handle, &date, &time);
|
|
_dos_close(handle);
|
|
|
|
year = ((date >> 9) & 0x7f) + 1980;
|
|
month = (date >> 5) & 0x0f;
|
|
day = (date & 0x1f);
|
|
|
|
hour = (time >> 11) & 0x1f;
|
|
minute = (time >> 5) & 0x3f;
|
|
second = (time & 0x1f) * 2;
|
|
|
|
// 2018-08-13 10:10:51
|
|
printf("%s: %04u-%02u-%02u %02u:%02u:%02u\n",
|
|
fname, year, month, day, hour, minute, second);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
unsigned int val;
|
|
int ret;
|
|
char fname[13];
|
|
|
|
if (argc < 2) {
|
|
printf("FAIL: missing argument\n");
|
|
return -2;
|
|
}
|
|
|
|
if (strcmp(argv[1], "DATE") == 0) {
|
|
|
|
// Year
|
|
for (val = 1980; val <= 2099; val++) {
|
|
sprintf(fname, "%08u.YR", val);
|
|
if (gettest(fname) < 0)
|
|
return -1;
|
|
}
|
|
|
|
// Month
|
|
for (val = 1; val <= 12; val++) {
|
|
sprintf(fname, "%08u.MN", val);
|
|
if (gettest(fname) < 0)
|
|
return -1;
|
|
}
|
|
|
|
// Day
|
|
for (val = 1; val <= 31; val++) {
|
|
sprintf(fname, "%08u.DY", val);
|
|
if (gettest(fname) < 0)
|
|
return -1;
|
|
}
|
|
|
|
} else if (strcmp(argv[1], "TIME") == 0) {
|
|
|
|
// Hour
|
|
for (val = 0; val <= 23; val++) {
|
|
sprintf(fname, "%08u.HR", val);
|
|
if (gettest(fname) < 0)
|
|
return -1;
|
|
}
|
|
|
|
// Minute
|
|
for (val = 0; val <= 59; val++) {
|
|
sprintf(fname, "%08u.MI", val);
|
|
if (gettest(fname) < 0)
|
|
return -1;
|
|
}
|
|
|
|
// Seconds
|
|
for (val = 0; val <= 59; val += 2) {
|
|
sprintf(fname, "%08u.SC", val);
|
|
if (gettest(fname) < 0)
|
|
return -1;
|
|
}
|
|
|
|
} else {
|
|
printf("FAIL: argument not DATE or TIME\n");
|
|
return -2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
""")
|
|
|
|
def settime(fn, Y, M, D, h, m, s):
|
|
date = datetime(year=Y, month=M, day=D,
|
|
hour=h, minute=m, second=s)
|
|
modTime = mktime(date.timetuple())
|
|
utime(join(testdir, fname), (modTime, modTime))
|
|
|
|
YEARS = range(1980, 2099 + 1) if tstype == "DATE" else []
|
|
for i in YEARS:
|
|
fname = "%08d.YR" % i
|
|
self.mkfile(fname, "some content", dname=testdir)
|
|
settime(fname, i, 1, 1, 0, 0, 0)
|
|
|
|
MONTHS = range(1, 12 + 1) if tstype == "DATE" else []
|
|
for i in MONTHS:
|
|
fname = "%08d.MN" % i
|
|
self.mkfile(fname, "some content", dname=testdir)
|
|
settime(fname, 1980, i, 1, 0, 0, 0)
|
|
|
|
DAYS = range(1, 31 + 1) if tstype == "DATE" else []
|
|
for i in DAYS:
|
|
fname = "%08d.DY" % i
|
|
self.mkfile(fname, "some content", dname=testdir)
|
|
settime(fname, 1980, 1, i, 0, 0, 0)
|
|
|
|
HOURS = range(0, 23 + 1) if tstype == "TIME" else []
|
|
for i in HOURS:
|
|
fname = "%08d.HR" % i
|
|
self.mkfile(fname, "some content", dname=testdir)
|
|
settime(fname, 1980, 1, 1, i, 0, 0)
|
|
|
|
MINUTES = range(0, 59 + 1) if tstype == "TIME" else []
|
|
for i in MINUTES:
|
|
fname = "%08d.MI" % i
|
|
self.mkfile(fname, "some content", dname=testdir)
|
|
settime(fname, 1980, 1, 1, 0, i, 0)
|
|
|
|
SECONDS = range(0, 59 + 1, 2) if tstype == "TIME" else []
|
|
for i in SECONDS:
|
|
fname = "%08d.SC" % i
|
|
self.mkfile(fname, "some content", dname=testdir)
|
|
settime(fname, 1980, 1, 1, 0, 0, i)
|
|
|
|
if fstype == "MFS":
|
|
config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name
|
|
|
|
results = self.runDosemu("testit.bat", config=config)
|
|
|
|
for i in YEARS:
|
|
self.assertIn("%08d.YR: %04d-01-01 00:00:00" % (i, i), results)
|
|
for i in MONTHS:
|
|
self.assertIn("%08d.MN: 1980-%02d-01 00:00:00" % (i, i), results)
|
|
for i in DAYS:
|
|
self.assertIn("%08d.DY: 1980-01-%02d 00:00:00" % (i, i), results)
|
|
for i in HOURS:
|
|
self.assertIn("%08d.HR: 1980-01-01 %02d:00:00" % (i, i), results)
|
|
for i in MINUTES:
|
|
self.assertIn("%08d.MI: 1980-01-01 00:%02d:00" % (i, i), results)
|
|
for i in SECONDS:
|
|
self.assertIn("%08d.SC: 1980-01-01 00:00:%02d" % (i, i), results)
|
|
|
|
self.assertNotIn("FAIL:", results)
|
|
|
|
def test_mfs_ds2_get_ftime(self):
|
|
"""MFS DOSv2 get file time"""
|
|
self._test_ds2_get_ftime("MFS", "DATE")
|
|
self._test_ds2_get_ftime("MFS", "TIME")
|
|
|
|
def test_fat_ds2_get_ftime(self):
|
|
"""FAT DOSv2 get file time"""
|
|
# Note: we need to split this test as FAT cannot have enough files
|
|
# in the root directory, and mkimage can't store them in a
|
|
# subdirectory.
|
|
self._test_ds2_get_ftime("FAT", "DATE")
|
|
self._test_ds2_get_ftime("FAT", "TIME")
|
|
|
|
def _test_ds2_set_ftime(self, fstype):
|
|
testdir = self.mkworkdir('d')
|
|
|
|
self.mkfile("testit.bat", """\
|
|
d:
|
|
c:\\setftime
|
|
rem end
|
|
""", newline="\r\n")
|
|
|
|
# compile sources
|
|
self.mkexe_with_djgpp("setftime", r"""
|
|
/* Most of this was copied from DJGPP docs at
|
|
http://www.delorie.com/djgpp/doc/libc/libc_181.html */
|
|
|
|
#include <dos.h>
|
|
#include <dir.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
|
|
#define FNAME "FOO.DAT"
|
|
|
|
int settest(unsigned int year, unsigned int month, unsigned int day,
|
|
unsigned int hour, unsigned int minute, unsigned int second) {
|
|
|
|
int handle;
|
|
struct find_t f;
|
|
int ret;
|
|
unsigned int date, time;
|
|
unsigned int _year, _month, _day, _hour, _minute, _second;
|
|
|
|
_dos_creat(FNAME, _A_NORMAL, &handle);
|
|
date = ((year - 1980) << 9) | (month << 5) | day;
|
|
time = (hour << 11) | (minute << 5) | (second / 2);
|
|
_dos_setftime(handle, date, time);
|
|
_dos_close(handle);
|
|
|
|
ret = _dos_findfirst(FNAME, _A_NORMAL, &f);
|
|
if (ret != 0) {
|
|
printf("FAIL: File '%s' not found\n", FNAME);
|
|
return -1;
|
|
}
|
|
|
|
_year = ((f.wr_date >> 9) & 0x7f) + 1980;
|
|
_month = (f.wr_date >> 5) & 0x0f;
|
|
_day = (f.wr_date & 0x1f);
|
|
|
|
_hour = (f.wr_time >> 11) & 0x1f;
|
|
_minute = (f.wr_time >> 5) & 0x3f;
|
|
_second = (f.wr_time & 0x1f) * 2;
|
|
|
|
second &= ~1; // DOS has 2 second resolution so round down the target
|
|
|
|
if ((year != _year) || (month != _month) || (day != _day) ||
|
|
(hour != _hour) || (minute != _minute) || (second != _second)) {
|
|
printf("FAIL: mismatch year(%u -> %u), month(%u -> %u), day(%u -> %u)\n",
|
|
year, _year, month, _month, day, _day);
|
|
printf(" hour(%u -> %u), minute(%u -> %u), second(%u -> %u)\n",
|
|
hour, _hour, minute, _minute, second, _second);
|
|
return -2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(void) {
|
|
unsigned int val;
|
|
int ret;
|
|
|
|
// Year
|
|
for (val = 1980; val <= 2099; val++) {
|
|
if (settest(val, 1, 1, 0, 0, 0) < 0)
|
|
return -1;
|
|
}
|
|
printf("OKAY: years matched\n");
|
|
|
|
// Month
|
|
for (val = 1; val <= 12; val++) {
|
|
if (settest(1980, val, 1, 0, 0, 0) < 0)
|
|
return -1;
|
|
}
|
|
printf("OKAY: months matched\n");
|
|
|
|
// Day
|
|
for (val = 1; val <= 31; val++) {
|
|
if (settest(1980, 1, val, 0, 0, 0) < 0)
|
|
return -1;
|
|
}
|
|
printf("OKAY: days matched\n");
|
|
|
|
// Hour
|
|
for (val = 0; val <= 23; val++) {
|
|
if (settest(1980, 1, 1, val, 0, 0) < 0)
|
|
return -1;
|
|
}
|
|
printf("OKAY: hours matched\n");
|
|
|
|
// Minute
|
|
for (val = 0; val <= 59; val++) {
|
|
if (settest(1980, 1, 1, 0, val, 0) < 0)
|
|
return -1;
|
|
}
|
|
printf("OKAY: minutes matched\n");
|
|
|
|
// Seconds
|
|
for (val = 0; val <= 59; val++) {
|
|
if (settest(1980, 1, 1, 0, 0, val) < 0)
|
|
return -1;
|
|
}
|
|
printf("OKAY: seconds matched\n");
|
|
|
|
printf("PASS: Set values are retrieved and matched\n");
|
|
return 0;
|
|
}
|
|
""")
|
|
|
|
if fstype == "MFS":
|
|
config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 dXXXXs/d:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
"""
|
|
else: # FAT
|
|
name = self.mkimage("12", cwd=testdir)
|
|
config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
|
|
$_floppy_a = ""
|
|
""" % name
|
|
|
|
results = self.runDosemu("testit.bat", config=config)
|
|
|
|
self.assertNotIn("FAIL:", results)
|
|
|
|
def test_mfs_ds2_set_ftime(self):
|
|
"""MFS DOSv2 set file time"""
|
|
self._test_ds2_set_ftime("MFS")
|
|
|
|
def test_fat_ds2_set_ftime(self):
|
|
"""FAT DOSv2 set file time"""
|
|
self._test_ds2_set_ftime("FAT")
|
|
|
|
def test_mfs_ds2_set_fattrs(self):
|
|
"""MFS DOSv2 set file attrs"""
|
|
tests = ('RDONLY', 'HIDDEN', 'SYSTEM')
|
|
for t in tests:
|
|
with self.subTest(t=t):
|
|
ds2_set_fattrs(self, "MFS", t)
|
|
|
|
def test_fat_ds2_set_fattrs(self):
|
|
"""FAT DOSv2 set file attrs"""
|
|
tests = ('RDONLY', 'HIDDEN', 'SYSTEM')
|
|
for t in tests:
|
|
with self.subTest(t=t):
|
|
ds2_set_fattrs(self, "FAT", t)
|
|
|
|
def test_fat_ds3_file_access_read(self):
|
|
"""FAT DOSv3 file access read"""
|
|
ds3_file_access(self, "FAT", "READ")
|
|
|
|
def test_mfs_ds3_file_access_read(self):
|
|
"""MFS DOSv3 file access read"""
|
|
ds3_file_access(self, "MFS", "READ")
|
|
|
|
def test_fat_ds3_file_access_write(self):
|
|
"""FAT DOSv3 file access write"""
|
|
ds3_file_access(self, "FAT", "WRITE")
|
|
|
|
def test_mfs_ds3_file_access_write(self):
|
|
"""MFS DOSv3 file access write"""
|
|
ds3_file_access(self, "MFS", "WRITE")
|
|
|
|
def test_fat_ds3_file_access_read_device_readonly(self):
|
|
"""FAT DOSv3 file access read device readonly"""
|
|
ds3_file_access(self, "FATRO", "READ")
|
|
|
|
def test_mfs_ds3_file_access_read_device_readonly(self):
|
|
"""MFS DOSv3 file access read device readonly"""
|
|
ds3_file_access(self, "MFSRO", "READ")
|
|
|
|
def test_fat_ds3_file_access_write_device_readonly(self):
|
|
"""FAT DOSv3 file access write device readonly"""
|
|
ds3_file_access(self, "FATRO", "WRITE")
|
|
|
|
def test_mfs_ds3_file_access_write_device_readonly(self):
|
|
"""MFS DOSv3 file access write device readonly"""
|
|
ds3_file_access(self, "MFSRO", "WRITE")
|
|
|
|
# def test_mfs_ds3_lock_readonly(self):
|
|
# """MFS DOSv3 lock file readonly"""
|
|
# ds3_lock_readonly(self, "MFS")
|
|
|
|
def test_fat_ds3_lock_readonly(self):
|
|
"""FAT DOSv3 lock file readonly"""
|
|
ds3_lock_readonly(self, "FAT")
|
|
|
|
def test_mfs_ds3_lock_readlckd(self):
|
|
"""MFS DOSv3 lock file read locked"""
|
|
ds3_lock_readlckd(self, "MFS")
|
|
|
|
def test_fat_ds3_lock_readlckd(self):
|
|
"""FAT DOSv3 lock file read locked"""
|
|
ds3_lock_readlckd(self, "FAT")
|
|
|
|
def test_mfs_ds3_lock_concurrent(self):
|
|
"""MFS DOSv3 lock file lock concurrent limit"""
|
|
ds3_lock_concurrent(self, "MFS")
|
|
|
|
def test_fat_ds3_lock_concurrent(self):
|
|
"""FAT DOSv3 lock file lock concurrent limit"""
|
|
ds3_lock_concurrent(self, "FAT")
|
|
|
|
def test_mfs_ds3_lock_two_handles(self):
|
|
"""MFS DOSv3 lock file lock with two handles"""
|
|
ds3_lock_two_handles(self, "MFS")
|
|
|
|
def test_fat_ds3_lock_two_handles(self):
|
|
"""FAT DOSv3 lock file lock with two handles"""
|
|
ds3_lock_two_handles(self, "FAT")
|
|
|
|
def test_mfs_ds3_lock_twice(self):
|
|
"""MFS DOSv3 lock file twice"""
|
|
ds3_lock_twice(self, "MFS")
|
|
|
|
def test_fat_ds3_lock_twice(self):
|
|
"""FAT DOSv3 lock file twice"""
|
|
ds3_lock_twice(self, "FAT")
|
|
|
|
def test_mfs_ds3_lock_writable(self):
|
|
"""MFS DOSv3 lock file writable"""
|
|
ds3_lock_writable(self, "MFS")
|
|
|
|
def test_fat_ds3_lock_writable(self):
|
|
"""FAT DOSv3 lock file writable"""
|
|
ds3_lock_writable(self, "FAT")
|
|
|
|
def test_mfs_ds3_share_open_twice(self):
|
|
"""MFS DOSv3 share open twice"""
|
|
ds3_share_open_twice(self, "MFS")
|
|
|
|
def test_fat_ds3_share_open_twice(self):
|
|
"""FAT DOSv3 share open twice"""
|
|
ds3_share_open_twice(self, "FAT")
|
|
|
|
def test_mfs_ds3_share_open_delete_one_process_ds2(self):
|
|
"""MFS DOSv3 share open delete one process DOSv2"""
|
|
ds3_share_open_access(self, "ONE", "MFS", "DELPTH")
|
|
|
|
def test_fat_ds3_share_open_delete_one_process_ds2(self):
|
|
"""FAT DOSv3 share open delete one process DOSv2"""
|
|
ds3_share_open_access(self, "ONE", "FAT", "DELPTH")
|
|
|
|
def test_mfs_ds3_share_open_delete_one_process_fcb(self):
|
|
"""MFS DOSv3 share open delete one process FCB"""
|
|
ds3_share_open_access(self, "ONE", "MFS", "DELFCB")
|
|
|
|
def test_fat_ds3_share_open_delete_one_process_fcb(self):
|
|
"""FAT DOSv3 share open delete one process FCB"""
|
|
ds3_share_open_access(self, "ONE", "FAT", "DELFCB")
|
|
|
|
def test_mfs_ds3_share_open_rename_one_process_ds2(self):
|
|
"""MFS DOSv3 share open rename one process DOSv2"""
|
|
ds3_share_open_access(self, "ONE", "MFS", "RENPTH")
|
|
|
|
def test_fat_ds3_share_open_rename_one_process_ds2(self):
|
|
"""FAT DOSv3 share open rename one process DOSv2"""
|
|
ds3_share_open_access(self, "ONE", "FAT", "RENPTH")
|
|
|
|
def test_mfs_ds3_share_open_rename_one_process_fcb(self):
|
|
"""MFS DOSv3 share open rename one process FCB"""
|
|
ds3_share_open_access(self, "ONE", "MFS", "RENFCB")
|
|
|
|
def test_fat_ds3_share_open_rename_one_process_fcb(self):
|
|
"""FAT DOSv3 share open rename one process FCB"""
|
|
ds3_share_open_access(self, "ONE", "FAT", "RENFCB")
|
|
|
|
def test_mfs_ds3_share_open_setfattrs_one_process(self):
|
|
"""MFS DOSv3 share open set file attrs one process DOSv2"""
|
|
ds3_share_open_access(self, "ONE", "MFS", "SETATT")
|
|
|
|
def test_fat_ds3_share_open_setfattrs_one_process(self):
|
|
"""FAT DOSv3 share open set file attrs one process DOSv2"""
|
|
ds3_share_open_access(self, "ONE", "FAT", "SETATT")
|
|
|
|
def test_mfs_ds3_share_open_delete_two_process_ds2(self):
|
|
"""MFS DOSv3 share open delete two process DOSv2"""
|
|
ds3_share_open_access(self, "TWO", "MFS", "DELPTH")
|
|
|
|
def test_fat_ds3_share_open_delete_two_process_ds2(self):
|
|
"""FAT DOSv3 share open delete two process DOSv2"""
|
|
ds3_share_open_access(self, "TWO", "FAT", "DELPTH")
|
|
|
|
def test_mfs_ds3_share_open_delete_two_process_fcb(self):
|
|
"""MFS DOSv3 share open delete two process FCB"""
|
|
ds3_share_open_access(self, "TWO", "MFS", "DELFCB")
|
|
|
|
def test_fat_ds3_share_open_delete_two_process_fcb(self):
|
|
"""FAT DOSv3 share open delete two process FCB"""
|
|
ds3_share_open_access(self, "TWO", "FAT", "DELFCB")
|
|
|
|
def test_mfs_ds3_share_open_rename_two_process_ds2(self):
|
|
"""MFS DOSv3 share open rename two process DOSv2"""
|
|
ds3_share_open_access(self, "TWO", "MFS", "RENPTH")
|
|
|
|
def test_fat_ds3_share_open_rename_two_process_ds2(self):
|
|
"""FAT DOSv3 share open rename two process DOSv2"""
|
|
ds3_share_open_access(self, "TWO", "FAT", "RENPTH")
|
|
|
|
def test_mfs_ds3_share_open_rename_two_process_fcb(self):
|
|
"""MFS DOSv3 share open rename two process FCB"""
|
|
ds3_share_open_access(self, "TWO", "MFS", "RENFCB")
|
|
|
|
def test_fat_ds3_share_open_rename_two_process_fcb(self):
|
|
"""FAT DOSv3 share open rename two process FCB"""
|
|
ds3_share_open_access(self, "TWO", "FAT", "RENFCB")
|
|
|
|
def test_mfs_ds3_share_open_setfattrs_two_process(self):
|
|
"""MFS DOSv3 share open set file attrs two process DOSv2"""
|
|
ds3_share_open_access(self, "TWO", "MFS", "SETATT")
|
|
|
|
def test_fat_ds3_share_open_setfattrs_two_process(self):
|
|
"""FAT DOSv3 share open set file attrs two process DOSv2"""
|
|
ds3_share_open_access(self, "TWO", "FAT", "SETATT")
|
|
|
|
def test_network_pktdriver_mtcp_builtin(self):
|
|
"""Network pktdriver mTCP built-in"""
|
|
network_pktdriver_mtcp(self, 'builtin')
|
|
test_network_pktdriver_mtcp_builtin.nettest = True
|
|
|
|
def test_network_pktdriver_mtcp_ne2000(self):
|
|
"""Network pktdriver mTCP NE2000"""
|
|
network_pktdriver_mtcp(self, 'ne2000')
|
|
test_network_pktdriver_mtcp_ne2000.nettest = True
|
|
|
|
def _test_cpu(self, cpu_vm, cpu_vm_dpmi, cpu_emu):
|
|
if ('kvm' in cpu_vm or 'kvm' in cpu_vm_dpmi) and not access("/dev/kvm", W_OK|R_OK):
|
|
self.skipTest("requires KVM")
|
|
if cpu_vm == 'vm86' and uname()[4] != 'i686':
|
|
self.skipTest("native vm86() only on 32bit x86")
|
|
|
|
edir = self.topdir / "test" / "cpu"
|
|
|
|
# Native reference file is now checked in to git and will
|
|
# only need to be updated if the test source changes
|
|
reffile = edir / "reffile.log"
|
|
refoutput = []
|
|
with reffile.open("r") as f:
|
|
refoutput = f.readlines()
|
|
|
|
# DOS test binary is built as part of normal build process
|
|
copy(edir / "dosbin.exe", self.workdir / "dosbin.exe")
|
|
dosfile = self.workdir / "dosfile.log"
|
|
|
|
# output from DOS under test
|
|
self.mkfile("testit.bat", """\
|
|
dosbin --common-tests > %s
|
|
rem end
|
|
""" % dosfile.name, newline="\r\n")
|
|
|
|
self.runDosemu("testit.bat", timeout=20, config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
$_cpu_vm = "%s"
|
|
$_cpu_vm_dpmi = "%s"
|
|
$_cpuemu = (%i)
|
|
$_ignore_djgpp_null_derefs = (off)
|
|
"""%(cpu_vm, cpu_vm_dpmi, cpu_emu))
|
|
|
|
dosoutput = []
|
|
try:
|
|
with dosfile.open("r") as f:
|
|
dosoutput = f.readlines()
|
|
except FileNotFoundError:
|
|
pass
|
|
if not dosoutput:
|
|
self.fail("DOS output file not found")
|
|
|
|
# Compare DOS output to reference file
|
|
if dosoutput != refoutput:
|
|
diff = unified_diff(refoutput, dosoutput, fromfile=str(reffile), tofile=str(dosfile))
|
|
self.fail('differences detected\n' + ''.join(list(diff)))
|
|
|
|
def test_cpu_1_vm86native(self):
|
|
"""CPU native vm86 + native DPMI (i386 only)"""
|
|
self._test_cpu("vm86", "native", 0)
|
|
test_cpu_1_vm86native.cputest = True
|
|
|
|
def test_cpu_2_jitnative(self):
|
|
"""CPU JIT vm86 + native DPMI"""
|
|
self._test_cpu("emulated", "native", 0)
|
|
test_cpu_2_jitnative.cputest = True
|
|
|
|
def test_cpu_jitkvm(self):
|
|
"""CPU JIT vm86 + KVM DPMI"""
|
|
self._test_cpu("emulated", "kvm", 0)
|
|
test_cpu_jitkvm.cputest = True
|
|
|
|
def test_cpu_simnative(self):
|
|
"""CPU simulated vm86 + native DPMI"""
|
|
self._test_cpu("emulated", "native", 1)
|
|
test_cpu_simnative.cputest = True
|
|
|
|
def test_cpu_simkvm(self):
|
|
"""CPU simulated vm86 + KVM DPMI"""
|
|
self._test_cpu("emulated", "kvm", 1)
|
|
test_cpu_simkvm.cputest = True
|
|
|
|
def test_cpu_kvmnative(self):
|
|
"""CPU KVM vm86 + native DPMI"""
|
|
self._test_cpu("kvm", "native", 0)
|
|
test_cpu_kvmnative.cputest = True
|
|
|
|
def test_cpu_kvm(self):
|
|
"""CPU KVM vm86 + KVM DPMI"""
|
|
self._test_cpu("kvm", "kvm", 0)
|
|
test_cpu_kvm.cputest = True
|
|
|
|
def test_cpu_kvmjit(self):
|
|
"""CPU KVM vm86 + JIT DPMI"""
|
|
self._test_cpu("kvm", "emulated", 0)
|
|
test_cpu_kvmjit.cputest = True
|
|
|
|
def test_cpu_kvmsim(self):
|
|
"""CPU KVM vm86 + simulated DPMI"""
|
|
self._test_cpu("kvm", "emulated", 1)
|
|
test_cpu_kvmsim.cputest = True
|
|
|
|
def test_cpu_jit(self):
|
|
"""CPU JIT vm86 + JIT DPMI"""
|
|
self._test_cpu("emulated", "emulated", 0)
|
|
test_cpu_jit.cputest = True
|
|
|
|
def test_cpu_sim(self):
|
|
"""CPU simulated vm86 + simulated DPMI"""
|
|
self._test_cpu("emulated", "emulated", 1)
|
|
test_cpu_sim.cputest = True
|
|
|
|
def test_cpu_trap_flag_emulated(self):
|
|
"""CPU Trap Flag emulated"""
|
|
cpu_trap_flag(self, 'emulated')
|
|
test_cpu_trap_flag_emulated.cputest = True
|
|
|
|
def test_cpu_trap_flag_kvm(self):
|
|
"""CPU Trap Flag KVM"""
|
|
cpu_trap_flag(self, 'kvm')
|
|
test_cpu_trap_flag_kvm.cputest = True
|
|
|
|
def test_pcmos_build(self):
|
|
"""PC-MOS build script"""
|
|
if environ.get("SKIP_EXPENSIVE"):
|
|
self.skipTest("expensive test")
|
|
|
|
mosrepo = 'https://github.com/roelandjansen/pcmos386v501.git'
|
|
mosroot = self.imagedir / 'pcmos.git'
|
|
|
|
try:
|
|
run(["git", "clone", "-q", "--depth=1", mosrepo, str(mosroot)], check=True)
|
|
except CalledProcessError:
|
|
self.skipTest("repository unavailable")
|
|
|
|
outfiles = [mosroot / 'SOURCES/src/latest' / x for x in [
|
|
'$286n.sys', '$386.sys', '$all.sys', '$arnet.sys',
|
|
'$charge.sys', '$ems.sys', '$gizmo.sys', '$kbbe.sys',
|
|
'$kbcf.sys', '$kbdk.sys', '$kbfr.sys', '$kbgr.sys',
|
|
'$kbit.sys', '$kbla.sys', '$kbnl.sys', '$kbno.sys',
|
|
'$kbpo.sys', '$kbsf.sys', '$kbsg.sys', '$kbsp.sys',
|
|
'$kbsv.sys', '$kbuk.sys', 'minbrdpc.sys', 'mosdd7f.sys',
|
|
'$$mos.sys', '$mouse.sys', '$netbios.sys', '$pipe.sys',
|
|
'$ramdisk.sys', '$serial.sys', '$$shell.sys']]
|
|
|
|
for outfile in outfiles:
|
|
outfile.unlink(missing_ok=True)
|
|
|
|
# Run the equivalent of the MOSROOT/build.sh script from MOSROOT
|
|
# Note:
|
|
# We have to avoid runDosemu() as this test is non-interactive
|
|
args = ["-K", r".:SOURCES\src", "-E", "MAKEMOS.BAT", r"path=%D\bin;%O"]
|
|
results = self.runDosemuCmdline(args, cwd=str(mosroot), timeout=300, config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
self.assertNotIn('Timeout', results)
|
|
self.assertNotIn('NonZeroReturn', results)
|
|
|
|
missing = [str(x.relative_to(mosroot)) for x in outfiles if not x.exists()]
|
|
if len(missing):
|
|
msg = "Output file(s) missing %s\n" % str(missing)
|
|
raise self.failureException(msg)
|
|
|
|
def test_passing_environment_variable(self):
|
|
"""Passing Environment Variable to DOS"""
|
|
|
|
tstring1 = "0123456789aBcDeF"
|
|
|
|
self.mkfile("testit.bat", """\
|
|
@ECHO on
|
|
ECHO %TESTVAR1%
|
|
rem end
|
|
""", newline="\r\n")
|
|
|
|
args = ["TESTVAR1=" + tstring1, "-q", "-E", "testit.bat"]
|
|
results = self.runDosemuCmdline(args, config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
self.assertNotIn('Timeout', results)
|
|
self.assertNotIn('NonZeroReturn', results)
|
|
self.assertIn("rem end", results, msg="Test incomplete:\n")
|
|
self.assertIn(tstring1, results)
|
|
|
|
def test_passing_dos_errorlevel_back(self):
|
|
"""Passing DOS Errorlevel back"""
|
|
|
|
self.mkcom_with_ia16("justerro", r"""
|
|
int main(int argc, char *argv[])
|
|
{
|
|
return 53;
|
|
}
|
|
""")
|
|
|
|
results = self.runDosemuCmdline(["-q", "-E", "justerro.com"], config="""\
|
|
$_hdimage = "dXXXXs/c:hdtype1 +1"
|
|
$_floppy_a = ""
|
|
""")
|
|
|
|
self.assertNotIn('Timeout', results)
|
|
self.assertIn('NonZeroReturn:53', results)
|
|
|
|
def test_pit_mode_2(self):
|
|
"""PIT Mode 2"""
|
|
if environ.get("SKIP_EXPENSIVE"):
|
|
self.skipTest("expensive test")
|
|
if environ.get("SKIP_UNCERTAIN"):
|
|
self.skipTest("uncertain test")
|
|
|
|
pit_mode_2(self)
|
|
|
|
|
|
class DRDOS701TestCase(OurTestCase, unittest.TestCase):
|
|
# OpenDOS 7.01
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(DRDOS701TestCase, cls).setUpClass()
|
|
cls.version = "Caldera OpenDOS 7.01"
|
|
cls.prettyname = "DR-DOS-7.01"
|
|
cls.files = [
|
|
("ibmbio.com", "61211eb63329a67fdd9d336271f06e1bfdab2b6f"),
|
|
("ibmdos.com", "52e71c8e9d74100f138071acaecdef4a79b67d3c"),
|
|
("command.com", "4bc38f973b622509aedad8c6af0eca59a2d90fca"),
|
|
("share.exe", "10f2c0e2cabe98617faa017806c80476b3b6c1e1"),
|
|
]
|
|
cls.systype = SYSTYPE_DRDOS_ORIGINAL
|
|
cls.autoexec = "dautoemu.bat"
|
|
cls.confsys = "dconfig.sys"
|
|
cls.bootblocks = [
|
|
("boot-306-4-17.blk", "1151ab9a3429163ac3ddf55b88d81359cb6975e5"),
|
|
("boot-615-4-17.blk", "a18ee96e63e384b766bafc4ff936e4087c31bf59"),
|
|
("boot-900-15-17.blk", "2ea4ea747f6e62a8ea46f14f6c9af1ad6fd0126b"),
|
|
]
|
|
cls.images = [
|
|
("boot-floppy.img", "d38fb2dba30185ce510cf3366bd71a1cbc2635da"),
|
|
]
|
|
cls.actions = {
|
|
r"test_fat_ds3_share_open_setfattrs_(one|two)_process": KNOWNFAIL,
|
|
r"test_..._ds3_share_open_rename_one_process_fcb": KNOWNFAIL,
|
|
r"test_..._fcb_rename_simple": KNOWNFAIL,
|
|
r"test_..._fcb_rename_wild_\d": KNOWNFAIL,
|
|
"test_mfs_truename_ufs_sfn": KNOWNFAIL,
|
|
"test_mfs_truename_vfat_linux_mounted_sfn": KNOWNFAIL,
|
|
"test_fat32_img_d_writable": UNSUPPORTED,
|
|
"test_lfn_volume_info_fat16": KNOWNFAIL,
|
|
"test_lfn_volume_info_fat32": UNSUPPORTED,
|
|
"test_lfn_volume_info_mfs": KNOWNFAIL,
|
|
"test_lfs_disk_info_fat32": UNSUPPORTED,
|
|
"test_floppy_vfs": KNOWNFAIL,
|
|
"test_memory_hma_alloc3": UNSUPPORTED,
|
|
"test_memory_hma_chain": UNSUPPORTED,
|
|
"test_pcmos_build": KNOWNFAIL,
|
|
"test_passing_dos_errorlevel_back": KNOWNFAIL,
|
|
"test_fat_label_create_bpb12": KNOWNFAIL,
|
|
"test_fat_label_create_bpb16": KNOWNFAIL,
|
|
"test_fat_label_create_bpb32": UNSUPPORTED,
|
|
"test_fat_label_create_on_lfns": UNSUPPORTED,
|
|
}
|
|
|
|
cls.setUpClassPost()
|
|
|
|
def setUpDosAutoexec(self):
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / self.autoexec).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
self.mkfile(self.autoexec, contents, newline="\r\n")
|
|
|
|
def setUpDosConfig(self):
|
|
# Link back to std dosemu commands and scripts
|
|
p = self.workdir / "dosemu"
|
|
p.symlink_to(self.topdir / "commands" / "dosemu")
|
|
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / self.confsys).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
contents = re.sub(r"rem SWITCHES=/F", r"SWITCHES=/F", contents)
|
|
self.mkfile(self.confsys, contents, newline="\r\n")
|
|
|
|
def setUpDosVersion(self):
|
|
self.mkfile("version.bat", "ver\r\nrem end\r\n")
|
|
|
|
|
|
class FRDOS120TestCase(OurTestCase, unittest.TestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(FRDOS120TestCase, cls).setUpClass()
|
|
cls.version = "FreeDOS kernel 2042"
|
|
cls.prettyname = "FR-DOS-1.20"
|
|
cls.files = [
|
|
("kernel.sys", "0709f4e7146a8ad9b8acb33fe3fed0f6da9cc6e0"),
|
|
("command.com", "0733db7babadd73a1b98e8983c83b96eacef4e68"),
|
|
("share.com", "cadc29d49115cb3a250f90921cca345e7c427464"),
|
|
]
|
|
cls.systype = SYSTYPE_FRDOS_NEW
|
|
cls.autoexec = "fdautoem.bat"
|
|
cls.confsys = "fdconfig.sys"
|
|
cls.bootblocks = [
|
|
("boot-302-4-17.blk", "8b5cfda502e59b067d1e34e993486440cad1d4f7"),
|
|
("boot-603-4-17.blk", "5c89a0c9c20ba9d581d8bf6969fda88df8ab2d45"),
|
|
("boot-900-15-17.blk", "523f699a79edde098fceee398b15711fac56a807"),
|
|
]
|
|
cls.images = [
|
|
("boot-floppy.img", "c3faba3620c578b6e42a6ef26554cfc9d2ee3258"),
|
|
]
|
|
cls.actions = {
|
|
"test_fat_fcb_rename_target_exists": KNOWNFAIL,
|
|
"test_fat_fcb_rename_source_missing": KNOWNFAIL,
|
|
"test_fat_fcb_rename_wild_1": KNOWNFAIL,
|
|
"test_fat_fcb_rename_wild_2": KNOWNFAIL,
|
|
"test_fat_fcb_rename_wild_3": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_target_exists": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_source_missing": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_wild_1": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_wild_2": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_wild_3": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_wild_4": KNOWNFAIL,
|
|
"test_fat_fcb_find_wild_1": KNOWNFAIL,
|
|
"test_fat_fcb_find_wild_2": KNOWNFAIL,
|
|
"test_fat_fcb_find_wild_3": KNOWNFAIL,
|
|
"test_mfs_fcb_find_wild_1": KNOWNFAIL,
|
|
"test_mfs_fcb_find_wild_2": KNOWNFAIL,
|
|
"test_mfs_fcb_find_wild_3": KNOWNFAIL,
|
|
"test_mfs_lfs_file_info_1MiB": KNOWNFAIL,
|
|
"test_mfs_lfs_file_info_6GiB": KNOWNFAIL,
|
|
"test_mfs_lfs_file_seek_tell_set": KNOWNFAIL,
|
|
"test_mfs_lfs_file_seek_tell_cur": KNOWNFAIL,
|
|
"test_mfs_lfs_file_seek_tell_end": KNOWNFAIL,
|
|
"test_mfs_lredir_command": KNOWNFAIL,
|
|
"test_mfs_lredir_command_no_perm": KNOWNFAIL,
|
|
"test_fat_ds3_lock_writable": KNOWNFAIL,
|
|
"test_fat_ds3_lock_readlckd": KNOWNFAIL,
|
|
"test_fat_ds3_lock_two_handles": KNOWNFAIL,
|
|
"test_mfs_truename_vfat_linux_mounted_lfn": KNOWNFAIL,
|
|
"test_mfs_truename_vfat_linux_mounted_sfn": KNOWNFAIL,
|
|
"test_mfs_findfile_vfat_linux_mounted_lfn": KNOWNFAIL,
|
|
"test_mfs_findfile_vfat_linux_mounted_sfn": KNOWNFAIL,
|
|
"test_fat_ds3_share_open_twice": KNOWNFAIL,
|
|
r"test_fat_ds3_share_open_(delete|rename)_.*": KNOWNFAIL,
|
|
r"test_mfs_ds3_share_open_rename_(one|two)_process_fcb": KNOWNFAIL,
|
|
r"test_fat_ds3_share_open_setfattrs_(one|two)_process": KNOWNFAIL,
|
|
"test_create_new_psp": KNOWNFAIL,
|
|
"test_command_com_keyword_exist": KNOWNFAIL,
|
|
"test_memory_emm286_borland": KNOWNFAIL,
|
|
"test_memory_hma_alloc": KNOWNFAIL,
|
|
"test_memory_hma_alloc3": UNSUPPORTED,
|
|
"test_memory_hma_chain": UNSUPPORTED,
|
|
"test_memory_uma_strategy": KNOWNFAIL,
|
|
"test_pcmos_build": KNOWNFAIL,
|
|
r"test_libi86_item_\d+": KNOWNFAIL,
|
|
"test_passing_dos_errorlevel_back": KNOWNFAIL,
|
|
"test_fat_label_create_bpb12": KNOWNFAIL,
|
|
"test_fat_label_create_bpb16": KNOWNFAIL,
|
|
"test_fat_label_create_bpb32": KNOWNFAIL,
|
|
"test_fat_label_create_prefile": KNOWNFAIL,
|
|
"test_fat_label_create_predir": KNOWNFAIL,
|
|
}
|
|
|
|
cls.setUpClassPost()
|
|
|
|
def setUpDosAutoexec(self):
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / self.autoexec).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
self.mkfile(self.autoexec, contents, newline="\r\n")
|
|
|
|
def setUpDosConfig(self):
|
|
# Link back to std dosemu commands and scripts
|
|
p = self.workdir / "dosemu"
|
|
p.symlink_to(self.topdir / "commands" / "dosemu")
|
|
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / "c" / self.confsys).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
contents = re.sub(r"rem SWITCHES=/F", r"SWITCHES=/F", contents)
|
|
self.mkfile(self.confsys, contents, newline="\r\n")
|
|
|
|
|
|
class FRDOS130TestCase(OurTestCase, unittest.TestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(FRDOS130TestCase, cls).setUpClass()
|
|
cls.version = "FreeDOS kernel 2043"
|
|
cls.prettyname = "FR-DOS-1.30"
|
|
cls.files = [
|
|
("kernel.sys", "2bdf90c8bc8c0406cfa01349265bf782507af016"),
|
|
("command.com", "15abab3d3ee4a50449517131a13b2c5164610582"),
|
|
("share.com", "cadc29d49115cb3a250f90921cca345e7c427464"),
|
|
]
|
|
cls.systype = SYSTYPE_FRDOS_NEW
|
|
cls.autoexec = "fdautoem.bat"
|
|
cls.confsys = "fdconfig.sys"
|
|
cls.bootblocks = [
|
|
("boot-306-4-17.blk", "0092a320500d7a8359d40bddc48f592686745aed"),
|
|
("boot-615-4-17.blk", "2b757178c7ba97f8a439c83dc627d61c2d6b3cf6"),
|
|
("boot-900-15-17.blk", "8cd7adeff4a0265e8a8e20f7942672c677cbc891"),
|
|
]
|
|
cls.images = [
|
|
("boot-floppy.img", "7b68b4dc2de5891bb3700816d8e1a323e8d150bb"),
|
|
]
|
|
cls.actions = {
|
|
"test_command_com_keyword_exist": KNOWNFAIL,
|
|
"test_create_new_psp": KNOWNFAIL,
|
|
"test_fat_ds3_lock_readlckd": KNOWNFAIL,
|
|
"test_fat_ds3_lock_two_handles": KNOWNFAIL,
|
|
"test_fat_ds3_lock_writable": KNOWNFAIL,
|
|
r"test_fat_ds3_share_open_(delete|rename)_.*": KNOWNFAIL,
|
|
r"test_fat_ds3_share_open_setfattrs_(one|two)_process": KNOWNFAIL,
|
|
"test_fat_ds3_share_open_twice": KNOWNFAIL,
|
|
"test_fat_fcb_find_wild_1": KNOWNFAIL,
|
|
"test_fat_fcb_find_wild_2": KNOWNFAIL,
|
|
"test_fat_fcb_find_wild_3": KNOWNFAIL,
|
|
"test_fat_fcb_rename_wild_1": KNOWNFAIL,
|
|
"test_fat_fcb_rename_wild_2": KNOWNFAIL,
|
|
"test_fat_fcb_rename_wild_3": KNOWNFAIL,
|
|
"test_fat_fcb_rename_wild_4": KNOWNFAIL,
|
|
"test_fat_label_create_bpb12": KNOWNFAIL,
|
|
"test_fat_label_create_bpb16": KNOWNFAIL,
|
|
"test_fat_label_create_bpb32": KNOWNFAIL,
|
|
"test_fat_label_create_noduplicate": KNOWNFAIL,
|
|
"test_fat_label_create_predir": KNOWNFAIL,
|
|
"test_fat_label_create_prefile": KNOWNFAIL,
|
|
"test_memory_emm286_borland": KNOWNFAIL,
|
|
"test_memory_hma_alloc": KNOWNFAIL,
|
|
"test_memory_hma_alloc3": UNSUPPORTED,
|
|
"test_memory_hma_chain": UNSUPPORTED,
|
|
"test_memory_uma_strategy": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_wild_1": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_wild_2": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_wild_3": KNOWNFAIL,
|
|
"test_mfs_fcb_rename_wild_4": KNOWNFAIL,
|
|
"test_passing_dos_errorlevel_back": KNOWNFAIL,
|
|
}
|
|
|
|
cls.setUpClassPost()
|
|
|
|
def setUpDosAutoexec(self):
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / self.autoexec).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
self.mkfile(self.autoexec, contents, newline="\r\n")
|
|
|
|
def setUpDosConfig(self):
|
|
# Link back to std dosemu commands and scripts
|
|
p = self.workdir / "dosemu"
|
|
p.symlink_to(self.topdir / "commands" / "dosemu")
|
|
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / "c" / self.confsys).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
contents = re.sub(r"rem SWITCHES=/F", r"SWITCHES=/F", contents)
|
|
self.mkfile(self.confsys, contents, newline="\r\n")
|
|
|
|
|
|
class FRDOSGITTestCase(OurTestCase, unittest.TestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(FRDOSGITTestCase, cls).setUpClass()
|
|
cls.version = "DOS version 7.10"
|
|
cls.prettyname = "FR-DOS-GIT"
|
|
cls.tarfile = ""
|
|
cls.systype = SYSTYPE_FRDOS_NEW
|
|
cls.autoexec = "fdautoem.bat"
|
|
cls.confsys = "fdconfig.sys"
|
|
cls.bootblocks = [
|
|
]
|
|
cls.images = [
|
|
]
|
|
cls.actions = {
|
|
"test_fat_ds3_lock_concurrent": KNOWNFAIL,
|
|
"test_fat_ds3_lock_readlckd": KNOWNFAIL,
|
|
"test_fat_ds3_lock_two_handles": KNOWNFAIL,
|
|
"test_fat_ds3_lock_writable": KNOWNFAIL,
|
|
"test_fat_ds3_share_open_delete_one_process_ds2": KNOWNFAIL,
|
|
"test_fat_ds3_share_open_delete_one_process_fcb": KNOWNFAIL,
|
|
"test_fat_ds3_share_open_rename_one_process_ds2": KNOWNFAIL,
|
|
"test_fat_ds3_share_open_rename_one_process_fcb": KNOWNFAIL,
|
|
"test_fat_ds3_share_open_setfattrs_one_process": KNOWNFAIL,
|
|
"test_fat_ds3_share_open_twice": KNOWNFAIL,
|
|
"test_fat_label_create_bpb12": KNOWNFAIL,
|
|
"test_fat_label_create_bpb16": KNOWNFAIL,
|
|
"test_fat_label_create_bpb32": KNOWNFAIL,
|
|
"test_fat_label_create_noduplicate": KNOWNFAIL,
|
|
"test_fat_label_create_predir": KNOWNFAIL,
|
|
"test_fat_label_create_prefile": KNOWNFAIL,
|
|
"test_memory_emm286_borland": KNOWNFAIL,
|
|
"test_memory_hma_alloc3": UNSUPPORTED,
|
|
"test_memory_hma_chain": UNSUPPORTED,
|
|
"test_memory_uma_strategy": KNOWNFAIL,
|
|
"test_passing_dos_errorlevel_back": KNOWNFAIL,
|
|
}
|
|
|
|
cls.setUpClassPost()
|
|
|
|
# Check files under test exist, or skip the whole thing
|
|
cls.files_to_copy = [
|
|
Path(environ.get("FDOS_KERNEL_SYS", "../fdos/kernel.git/bin/kernel.sys")),
|
|
Path(environ.get("FDOS_COMMAND_COM", "../fdos/freecom.git/command.com")),
|
|
Path(environ.get("FDOS_SHARE_COM", "../fdos/share.git/src/share.com")),
|
|
]
|
|
for f in cls.files_to_copy:
|
|
if not f.is_file():
|
|
raise unittest.SkipTest("File '%s' not found" % f.name)
|
|
|
|
def setUp(self):
|
|
super(FRDOSGITTestCase, self).setUp()
|
|
for f in self.files_to_copy:
|
|
copy(f, self.workdir)
|
|
|
|
def setUpDosAutoexec(self):
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / self.autoexec).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
self.mkfile(self.autoexec, contents, newline="\r\n")
|
|
|
|
def setUpDosConfig(self):
|
|
# Link back to std dosemu commands and scripts
|
|
p = self.workdir / "dosemu"
|
|
p.symlink_to(self.topdir / "commands" / "dosemu")
|
|
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / "c" / self.confsys).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
contents = re.sub(r"rem SWITCHES=/F", r"SWITCHES=/F", contents)
|
|
self.mkfile(self.confsys, contents, newline="\r\n")
|
|
|
|
|
|
class MSDOS622TestCase(OurTestCase, unittest.TestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(MSDOS622TestCase, cls).setUpClass()
|
|
cls.version = "MS-DOS Version 6.22"
|
|
cls.prettyname = "MS-DOS-6.22"
|
|
cls.files = [
|
|
("io.sys", "d697961ca6edaf9a1aafe8b7eb949597506f7f95"),
|
|
("msdos.sys", "d6a5f54006e69c4407e56677cd77b82395acb60a"),
|
|
("command.com", "c2179d2abfa241edd388ab875cfabbac89fec44d"),
|
|
("share.exe", "9e7385cfa91a012638520e89b9884e4ce616d131"),
|
|
("dos/himem.sys", "fb41fbc1c4bdd8652d445055508bc8265bc64aea"),
|
|
]
|
|
cls.systype = SYSTYPE_MSDOS_INTERMEDIATE
|
|
cls.autoexec = "autoemu.bat"
|
|
cls.bootblocks = [
|
|
("boot-306-4-17.blk", "d40c24ef5f5f9fd6ef28c29240786c70477a0b06"),
|
|
("boot-615-4-17.blk", "7fc96777727072471dbaab6f817c8d13262260d2"),
|
|
("boot-900-15-17.blk", "2a0ca1b87b82013fd417542a5ac28e965fb13e7a"),
|
|
]
|
|
cls.images = [
|
|
("boot-floppy.img", "14b8310910bf19d6e375298f3b06da7ffdec9932"),
|
|
]
|
|
cls.actions = {
|
|
"test_fat32_img_d_writable": UNSUPPORTED,
|
|
"test_lfn_volume_info_fat16": KNOWNFAIL,
|
|
"test_lfn_volume_info_fat32": UNSUPPORTED,
|
|
"test_lfs_disk_info_fat32": UNSUPPORTED,
|
|
"test_memory_hma_alloc3": UNSUPPORTED,
|
|
"test_memory_hma_chain": UNSUPPORTED,
|
|
"test_passing_dos_errorlevel_back": KNOWNFAIL,
|
|
"test_fat_label_create_bpb32": UNSUPPORTED,
|
|
"test_fat_label_create_on_lfns": UNSUPPORTED,
|
|
}
|
|
|
|
cls.setUpClassPost()
|
|
|
|
def setUpDosAutoexec(self):
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / self.autoexec).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
self.mkfile(self.autoexec, contents, newline="\r\n")
|
|
|
|
def setUpDosConfig(self):
|
|
# Link back to std dosemu commands and scripts
|
|
p = self.workdir / "dosemu"
|
|
p.symlink_to(self.topdir / "commands" / "dosemu")
|
|
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / "c" / self.confsys).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
contents = re.sub(r"rem SWITCHES=/F", r"SWITCHES=/F", contents)
|
|
self.mkfile(self.confsys, contents, newline="\r\n")
|
|
|
|
def setUpDosVersion(self):
|
|
self.mkfile("version.bat", "ver\r\nrem end\r\n")
|
|
|
|
|
|
class MSDOS700TestCase(OurTestCase, unittest.TestCase):
|
|
# badged Win95 RTM at winworldpc.com
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(MSDOS700TestCase, cls).setUpClass()
|
|
cls.version = "Windows 95. [Version 4.00.950]"
|
|
cls.prettyname = "MS-DOS-7.00"
|
|
cls.files = [
|
|
("io.sys", "22924f93dd0f9ea6a4624ccdd1bbcdf5eb43a308"),
|
|
("msdos.sys", "f5d01c68d518f4b8b2482d3815af8bb88003831d"),
|
|
("command.com", "67696207c3963a0dc9afab8cf37dbdb966c1f663"),
|
|
]
|
|
cls.systype = SYSTYPE_MSDOS_NEW
|
|
cls.autoexec = "autoemu.bat"
|
|
cls.bootblocks = [
|
|
("boot-306-4-17.blk", "8c016e339ca6b8126fd2026ed3a7eeeb6cbb8903"),
|
|
("boot-615-4-17.blk", "b6fdddbfb37442a2762d5897de1aa7d7a694286a"),
|
|
("boot-900-15-17.blk", "8c1243481112f320f2a5f557f30db11174fe7e3d"),
|
|
]
|
|
cls.images = [
|
|
("boot-floppy.img", ""),
|
|
]
|
|
cls.actions = {
|
|
"test_fat32_img_d_writable": UNSUPPORTED,
|
|
"test_fat_label_create_bpb32": UNSUPPORTED,
|
|
"test_lfn_volume_info_fat16": KNOWNFAIL,
|
|
"test_lfn_volume_info_fat32": UNSUPPORTED,
|
|
"test_lfs_disk_info_fat32": UNSUPPORTED,
|
|
"test_lfs_disk_info_mfs": KNOWNFAIL,
|
|
}
|
|
|
|
cls.setUpClassPost()
|
|
|
|
def setUpDosAutoexec(self):
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / self.autoexec).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
self.mkfile(self.autoexec, contents, newline="\r\n")
|
|
|
|
def setUpDosConfig(self):
|
|
# Link back to std dosemu commands and scripts
|
|
p = self.workdir / "dosemu"
|
|
p.symlink_to(self.topdir / "commands" / "dosemu")
|
|
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / "c" / self.confsys).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
contents = re.sub(r"rem SWITCHES=/F", r"SWITCHES=/F", contents)
|
|
self.mkfile(self.confsys, contents, newline="\r\n")
|
|
|
|
def setUpDosVersion(self):
|
|
self.mkfile("version.bat", "ver\r\nrem end\r\n")
|
|
|
|
# Disable the logo here or we get blank screen
|
|
self.mkfile("msdos.sys", """
|
|
[Options]
|
|
BootGUI=0
|
|
Logo=0
|
|
""", newline="\r\n")
|
|
|
|
|
|
class MSDOS710TestCase(OurTestCase, unittest.TestCase):
|
|
# badged CDU (Chinese DOS Union) at winworldpc.com
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(MSDOS710TestCase, cls).setUpClass()
|
|
cls.version = "MS-DOS 7.1 [Version 7.10.1999]"
|
|
cls.prettyname = "MS-DOS-7.10"
|
|
cls.files = [
|
|
("io.sys", "8c586b1bf38fc2042f2383ca873283a466be2f44"),
|
|
("msdos.sys", "cd1e6103ce9cdebbc7a5611df13ff4fbd5e2159c"),
|
|
("command.com", "f6547d81e625a784633c059e536e90ee45532202"),
|
|
]
|
|
cls.systype = SYSTYPE_MSDOS_NEW
|
|
cls.autoexec = "autoemu.bat"
|
|
cls.bootblocks = [
|
|
("boot-306-4-17.blk", "0f520de6e2a33ef8fd336b2844957689fc1060e9"),
|
|
("boot-615-4-17.blk", "5e49a8ee7747191d87a2214cc0281736262687b9"),
|
|
("boot-900-15-17.blk", "2c29d06909c7d5ca46a3ca26ddde9287a11ef315"),
|
|
]
|
|
cls.images = [
|
|
("boot-floppy.img", ""),
|
|
]
|
|
|
|
cls.actions = {
|
|
}
|
|
|
|
cls.setUpClassPost()
|
|
|
|
def setUpDosAutoexec(self):
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / self.autoexec).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
self.mkfile(self.autoexec, contents, newline="\r\n")
|
|
|
|
def setUpDosConfig(self):
|
|
# Link back to std dosemu commands and scripts
|
|
p = self.workdir / "dosemu"
|
|
p.symlink_to(self.topdir / "commands" / "dosemu")
|
|
|
|
# Use the (almost) standard shipped config
|
|
contents = (self.topdir / "src" / "bindist" / "c" / self.confsys).read_text()
|
|
contents = re.sub(r"[Dd]:\\", r"c:\\", contents)
|
|
contents = re.sub(r"rem SWITCHES=/F", r"SWITCHES=/F", contents)
|
|
self.mkfile(self.confsys, contents, newline="\r\n")
|
|
|
|
def setUpDosVersion(self):
|
|
self.mkfile("version.bat", "ver\r\nrem end\r\n")
|
|
|
|
# Disable the logo here or we get blank screen
|
|
self.mkfile("msdos.sys", """
|
|
[Options]
|
|
BootGUI=0
|
|
Logo=0
|
|
""", newline="\r\n")
|
|
|
|
|
|
class PPDOSGITTestCase(OurTestCase, unittest.TestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(PPDOSGITTestCase, cls).setUpClass()
|
|
cls.version = "FDPP kernel"
|
|
cls.prettyname = "PP-DOS-GIT"
|
|
cls.actions = {
|
|
"test_floppy_img": UNSUPPORTED,
|
|
"test_floppy_vfs": UNSUPPORTED,
|
|
}
|
|
|
|
# Use the default files that FDPP installed
|
|
cls.tarfile = ""
|
|
|
|
cls.systype = SYSTYPE_FDPP
|
|
cls.autoexec = "fdppauto.bat"
|
|
cls.confsys = "fdppconf.sys"
|
|
|
|
cls.setUpClassPost()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
# Dynamically create libi86 tests
|
|
libi86_create_items(OurTestCase)
|
|
|
|
tests = [t[0] for t in
|
|
inspect.getmembers(OurTestCase, predicate=inspect.isfunction)
|
|
if t[0].startswith("test")]
|
|
|
|
xtests = [t[0] for t in
|
|
inspect.getmembers(OurTestCase, predicate=inspect.isfunction)
|
|
if t[0].startswith("xtest")]
|
|
|
|
cases = [c[0] for c in
|
|
inspect.getmembers(modules[__name__], predicate=inspect.isclass)
|
|
if issubclass(c[1], OurTestCase) and c[0] != "OurTestCase"]
|
|
|
|
attrs = sorted(OurTestCase.attrs)
|
|
|
|
def explode(n, attr=None):
|
|
if n in tests:
|
|
return [c + "." + n for c in cases]
|
|
if n in xtests:
|
|
return [c + "." + n for c in cases]
|
|
if n in cases:
|
|
if attr:
|
|
return [n + "." + t[0] for t in
|
|
inspect.getmembers(OurTestCase, predicate=inspect.isfunction)
|
|
if hasattr(t[1], attr)]
|
|
else:
|
|
return [n,]
|
|
p = n.split('.')
|
|
if p and p[0] in cases and (p[1] in tests or p[1] in xtests):
|
|
return [n,]
|
|
return []
|
|
|
|
if len(argv) > 1:
|
|
if argv[1] == "--help":
|
|
print(("Usage: %s [--help | --get-test-binaries | " +
|
|
"--list-attrs | --list-cases | --list-tests] | " +
|
|
"[--require-attr=STRING TestCase ...] | " +
|
|
"[TestCase[.testname] ...]") % argv[0])
|
|
exit(0)
|
|
elif argv[1] == "--get-test-binaries":
|
|
get_test_binaries()
|
|
exit(0)
|
|
elif argv[1] == "--list-attrs":
|
|
for a in attrs:
|
|
print(str(a))
|
|
exit(0)
|
|
elif argv[1] == "--list-cases":
|
|
for m in cases:
|
|
print(str(m))
|
|
exit(0)
|
|
elif argv[1] == "--list-tests":
|
|
for m in tests:
|
|
print(str(m))
|
|
exit(0)
|
|
else:
|
|
x = re.match(r"^--require-attr=(\S+).*$", argv[1])
|
|
if x:
|
|
attr = x.groups()[0]
|
|
del argv[1]
|
|
else:
|
|
attr = None
|
|
|
|
a = []
|
|
for b in [explode(x, attr=attr) for x in argv[1:]]:
|
|
a.extend(b)
|
|
|
|
if not len(a):
|
|
print("No tests found, was your testcase or testname incorrect? See --help")
|
|
exit(1)
|
|
argv = [argv[0],] + a
|
|
main(argv)
|
|
|
|
main()
|