Qbasicnews.com

QBasic => QB Discussion & Programming Help => Topic started by: Agamemnus on June 13, 2003, 09:32:14 AM



Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 13, 2003, 09:32:14 AM
Na_th_an, can you make a sub that opens a file with a long filename? Something as neat and cool as the thing you put in the FAQ? :)


Title: how to access long filename length in DOS? (na_th_an)
Post by: Neo on June 13, 2003, 09:38:11 AM
The following code is the full LFN module of KetOn. Check it out:

Code:
'    ==============
'Long FileName (Win32) Module
'By Neo Deus Ex Machina
'
'This Module is part of the KetOn library
'made by members of HAR-SoftWare
'
'This Module contains:
' 11 LFN routines
'
'Directory handling (5 routines)
DECLARE SUB KT.LFN.MakeDir(DirName AS STRING)
DECLARE SUB KT.LFN.RemoveDir(DirName AS STRING)
DECLARE SUB KT.LFN.ChangeDir(DirName AS STRING)
DECLARE FUNCTION KT.LFN.GetCurrDir$ ()
DECLARE SUB KT.LFN.RenameDir(DirName AS STRING, NewDirName AS STRING)

'File handling (5 routines)
DECLARE SUB KT.LFN.DeleteFile(FileName AS STRING)
DECLARE SUB KT.LFN.RenameFile(FileName AS STRING, NewFileName AS STRING)
DECLARE FUNCTION KT.LFN.GetFullPath$(FileName AS STRING)
DECLARE FUNCTION KT.LFN.GetShortPath$(FileName AS STRING)
DECLARE FUNCTION KT.LFN.ShortFileName$(LongFileName AS STRING)

'Drive function (1 routine)
DECLARE FUNCTION KT.LFN.GetFileSystem$(DriveLetter AS STRING)

DEFINT A-Z
'$DYNAMIC
'$INCLUDE: '..\..\QB.BI'
'$LIB: '..\..\QB.LIB'

'####################
' Directory Handling
'####################
SUB KT.LFN.MakeDir(DirName AS STRING)
        DIM Regs AS RegTypeX
        Regs.ax = &H7139
        DirNameZ$ = DirName + CHR$(0)
        Regs.ds = -1
        Regs.dx = SADD(DirNameZ$)
        INTERRUPTX &H21, Regs, Regs
END SUB

SUB KT.LFN.RemoveDir(DirName AS STRING)
DIM Regs AS RegTypeX
Regs.ax = &H713A
DirNameZ$ = DirName + CHR$(0)
Regs.ds = -1
Regs.dx = SADD(DirNameZ$)
INTERRUPTX &H21, Regs, Regs
END SUB

SUB KT.LFN.ChangeDir(DirName AS STRING)
DIM Regs AS RegTypeX
        Regs.ax = &H713B
        DirNameZ$ = DirName + CHR$(0)
        Regs.ds = -1
        Regs.dx = SADD(DirNameZ$)
        INTERRUPTX &H21, Regs, Regs
END SUB

FUNCTION KT.LFN.GetCurrDir$
        DIM Regs AS RegTypeX, CurrDir AS STRING * 256
        Regs.ax = &H7147
        Regs.dx = 0
        Regs.ds = -1
        Regs.si = VARPTR(CurrDir)
        INTERRUPTX &H21, Regs, Regs
        Null = INSTR(CurrDir, CHR$(0))
        IF Null <> 0 THEN KT.LFN.GetCurrDir$ = LEFT$(CurrDir, Null - 1) ELSE KT.LFN.GetCurrDir$ = CurrDir
END FUNCTION

SUB KT.LFN.RenameDir(DirName AS STRING, NewDirName AS STRING)
KT.LFN.RenameFile DirName, NewDirName
END SUB

'###############
' File Handling
'###############
SUB KT.LFN.DeleteFile(FileName AS STRING)
        DIM Regs AS RegTypeX
        Regs.ax = &H7141
        Regs.si = 0
        Regs.ds = -1
        FileNameZ$ = FileName + CHR$(0)
        Regs.dx = SADD(FileNameZ$)
        INTERRUPTX &H21, Regs, Regs
END SUB

SUB KT.LFN.RenameFile(FileName AS STRING, NewFileName AS STRING)
        DIM Regs AS RegTypeX
        Regs.ax = &H7156
        FileNameZ$ = FileName + CHR$(0)
        Regs.ds = -1
        Regs.dx = SADD(FileNameZ$)
        NewFileNameZ$ = NewFileName + CHR$(0)
        Regs.es = -1
        Regs.di = SADD(NewFileNameZ$)
        INTERRUPTX &H21, Regs, Regs
END SUB

FUNCTION KT.LFN.GetFullPath$(FileName AS STRING)
        DIM Regs AS RegTypeX, NameBuffer AS STRING * 261
        Regs.ax = &H7160
        Regs.cx = &H0000
        Regs.ds = -1
        FileNameZ$ = FileName + CHR$(0)
        Regs.si = SADD(FileNameZ$)
        Regs.es = -1
        Regs.di = VARPTR(NameBuffer)
        INTERRUPTX &H21, Regs, Regs
        PRINT nameBuffer; "ok"
        Null = INSTR(NameBuffer, CHR$(0))
        IF Null > 0 THEN KT.LFN.GetFullPath$ = LEFT$(NameBuffer, Null - 1) ELSE KT.LFN.GetFullPath$ = NameBuffer
END FUNCTION

FUNCTION KT.LFN.GetShortPath$(FileName AS STRING)
        DIM Regs AS RegTypeX, NameBuffer AS STRING * 67
        Regs.ax = &H7160
        Regs.cx = 1
        FileNameZ$ = FileName + CHR$(0)
        Regs.ds = -1
        Regs.si = SADD(FileNameZ$)
        Regs.es = -1
        Regs.di = VARPTR(NameBuffer)
        INTERRUPTX &H21, Regs, Regs
        Null = INSTR(NameBuffer, CHR$(0))
        IF Null > 0 THEN KT.LFN.GetShortPath$ = LEFT$(NameBuffer, Null - 1) ELSE KT.LFN.GetShortPath$ = NameBuffer
END FUNCTION

FUNCTION KT.LFN.ShortFileName$(LongFileName AS STRING)
        DIM Regs AS RegTypeX, FBuffer AS STRING * 13
        Regs.ax = &H71A8
        LFNZ$ = LongFileName + CHR$(0)
        Regs.ds = -1
        Regs.si = SADD(LFNZ$)
Regs.es = -1
Regs.di = VARPTR(FBuffer)
        Regs.dx = &H0111
        INTERRUPTX &H21, Regs, Regs
        Null = INSTR(FBuffer, CHR$(0))
        IF Null <> 0 THEN KT.LFN.ShortFileName$ = LEFT$(FBuffer, Null - 1) ELSE KT.LFN.ShortFileName$ = FBuffer
END FUNCTION

'################
' Drive Function
'################
FUNCTION KT.LFN.GetFileSystem$(DriveLetter AS STRING)
DIM Regs AS RegTypeX, FS AS STRING * 32
        Regs.ax = &H71A0
        RootDirZ$ = DriveLetter + ":\" + CHR$(0)
        Regs.ds = -1
        Regs.dx = SADD(RootDirZ$)
        Regs.es = -1
        Regs.di = VARPTR(FS)
        Regs.cx = 32
        INTERRUPTX &H21, Regs, Regs
        Null = INSTR(FS, CHR$(0))
        IF Null > 0 THEN KT.LFN.GetFileSystem$ = LEFT$(FS, Null - 1) ELSE KT.LFN.GetFileSystem$ = FS
END FUNCTION


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 13, 2003, 09:46:13 AM
That wouldn't work. I don't want to convert to a short file name, I want to load a long file name into a record number...


Title: how to access long filename length in DOS? (na_th_an)
Post by: Neo on June 13, 2003, 10:22:02 AM
I don't know what you mean yet, but you can check at:

http://www.ctyme.com/rbrown.htm


Title: *faints*
Post by: Agamemnus on June 13, 2003, 11:04:57 AM
*comes to*

I'll just wait for nathan...


Title: how to access long filename length in DOS? (na_th_an)
Post by: Plasma on June 13, 2003, 12:53:30 PM
Quote
That wouldn't work. I don't want to convert to a short file name, I want to load a long file name into a record number...


Uh...you convert the long filename to a short filename, then you open the short filename. I don't know what you're whining about. It's the same file.


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 13, 2003, 12:58:25 PM
nope. it isn't.... always... there are more possible long names than short names...


Title: how to access long filename length in DOS? (na_th_an)
Post by: na_th_an on June 13, 2003, 12:59:56 PM
I think you need to read the long filename from DOS. If you...

Code:
SHELL "dir *.* /b >file.lst


You'll have all files in the directory (in long filenames) inside file.lst, which you can read.

What do you want to do *exactly*?

I have this neat piece of code from the ABC packets:

Code:
'===========================================================================
' Subject: WINDOW'S LONG FILENAMES           Date: 11-24-95 (00:00)
' Author:  Mark K. Kim                       Code: QB, QBasic, PDS
' Origin:  members.aol.com/vindaci/        Packet: DOS.ABC
'===========================================================================
'#iab.compatibility.version.1a
'LFN version 1.0 beta1 -- Long filename functions
'Copyright (c)1996 Mark K. Kim
'markkkim@aol.com
'http://members.aol.com/markkkim/
'http://members.aol.com/vinDaci/
'* Freely distributed.  May be used in other programs with proper notice of
'  credit.
'* This program is provided "as-is".
'* In QBASIC, no modification is necessary
'* In QuickBASIC, QuickBASIC PDS, or VisualBASIC for DOS, run with the
'  "/L" option, like so:
'
'    QB /L
'    QBX /L
'    VBDOS /L
'
'  Also, do not include the QB.BI, QBX.BI, or VBDOS.BI files. If you do,
'  modify them so that the line "DECLARE ABSOLUTE..." is gone.
'* In QuickBASIC PDS and VisualBASIC, change all the lines in the format
'  "VARSEG(any.string.variable$)" to "SSEG(any.string.variable$)".
'* CREDIT: Ralf Brown's interrupt list was used to get interrupt for the
'  function.  Microsoft DOS's Debug was used to convert Assembly code to
'  machine code.  Microsoft is a Registered Trademark of Microsoft Corp.
'* NOTE: Works only under operating systems that support Windows95 LFN
'  or LFN emulation programs.
'Read the header of each function to find out their usage. These functions
'are designed to work with most other routines as it does not interfere
'with any other routines.


'the following line exists for compatibility reasons:
DECLARE SUB absolute (var1%, var2%, var3%, var4%, var5%, var6%, var7%, var8%, var9%, offset%)

'#begin declaration
  'File attribute constants -- used to do file search
    CONST ATT.ALL = &HFF
    CONST ATT.SHARE = &H80
    CONST ATT.ARC = &H20
    CONST ATT.DIR = &H10
    CONST ATT.VOL = &H8
    CONST ATT.SYS = &H4
    CONST ATT.HID = &H2
    CONST ATT.RDO = &H1
    CONST ATT.NONE = &H0
  'Value set to error code if an error occurs
    Dim errval As Integer
  'Procedures
    DECLARE SUB lfn.mkdir (dirname$)           'make LFN directory
    DECLARE SUB lfn.rmdir (dirname$)           'remove LFN directory
    DECLARE SUB lfn.chdir (dirname$)           'change to a LFN directory
    DECLARE SUB lfn.del (filename$)            'delete a LFN file
    DECLARE SUB lfn.ren (oldname$, newname$)   'rename file
    DECLARE FUNCTION lfn.cwd$ (drive%)         'get current working directory
    DECLARE FUNCTION lfn.l2s$ (longname$)      'long name to short name
    DECLARE FUNCTION lfn.s2l$ (shortname$)     'short name to long name
    DECLARE FUNCTION lfn.findfirst$ (filespec$, findattrib%, mustattrib%)
    DECLARE FUNCTION lfn.findnext$ ()
    DECLARE SUB lfn.findclose ()
'#end declaration


'#start example program
  Cls

  longfilename$ = "long filename entry.tmp"
  longdirname$ = "long directory name entry"

  'make a LFN file by first opening a SFN file, then renaming it to LFN:
    'first create SFN
      Open "sfn.tmp" For Output As #1
      Print #1, "La la la! This is a SFN entry!"
      Close #1
    'rename SFN to LFN
      lfn.ren "sfn.tmp", longfilename$
      If errval Then Print "Error while renaming!" Else Print "LFN Created"

  'display all files in the current directory
    'file search -- allow any/all attributes and limit no attribute
      FileName$ = lfn.findfirst$("*.*", ATT.All, ATT.NONE)

    'display result
      If errval Then
          Print "Error during file search!"
      Else
          Print "File search result: "
        'display filename and continue search
          Do
            Print "  "; FileName$
            FileName$ = lfn.findnext$
          Loop Until errval
        'terminate search -- must be called
          lfn.findclose
      End If

  'delete previously created LFN file
    lfn.del longfilename$
    If errval Then Print "Error while deleting LFN!" Else Print "LFN deleted"

  'create LFN directory
    lfn.MkDir longdirname$
    If errval Then Print "Error while creating LFN directory!" Else Print "LFN directory created"

  'display LFN directory's SFN equivalent
    Print "LFN entry's SFN equivalent is: "; lfn.l2s(longdirname$)

  'change current directory to LFN
    'first display current directory
      Print "Current directory: "; lfn.cwd$(-1)
    'next change directory
      lfn.ChDir longdirname$
      If errval Then Print "Error changing directory" Else Print "Directory changed"
    'display directory
      Print "Directory after change: "; lfn.cwd$(-1)
    'change back
      lfn.ChDir ".."
      If errval Then Print "Error changing directory" Else Print "Back to original directory"

  'remove LFN directory
    lfn.RmDir longdirname$
    If errval Then Print "Error removing LFN directory" Else Print "LFN directory removed"

'lfn.chdir -- Change Directory
'INPUT:
'  dirname$ - Name of the directory to change to.
'SUCCESS:
'  * Working directory changed to specified directory.
'  * Global variable errval set to zero.
'FAIL:
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
SUB lfn.chdir (dirname$)
 
  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                       'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                          'MOV     BP,SP
  asm$ = asm$ + Chr$(&H1E)                                       'PUSH    DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)              'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)                          'MOV     DX,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)              'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                          'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H3B) + Chr$(&H71)             'MOV     AX,713B
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                          'INT     21
  asm$ = asm$ + Chr$(&H1F)                                       'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)              'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                           'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)              'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)               'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)               'ADC     AX,0000
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                           'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5D)                                       'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)              'RETF    0012

  lfn.dirname$ = dirname$ + Chr$(0)
  lfn.dirnameseg% = VARSEG(lfn.dirname$)
  lfn.dirnameoff% = SADD(lfn.dirname$)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, lfn.dirnameseg%, lfn.dirnameoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.dirnameseg%
  errorcode% = lfn.dirnameoff%

  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
  End If

End Sub

'lfn.cwd$ -- Return current directory
'INPUT:
'  drive% - Number of the drive to get the current directory of.
'    0 = A:, 1 = B:, 2 = C:, etc. -1 if current drive.
'SUCCESS:
'  * Return current directory of the specified drive.
'  * Global variable errval set to zero.
'FAIL:
'  * Return "".
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
FUNCTION lfn.cwd$ (drive%)
 
  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                   'MOV     BP,SP
  asm$ = asm$ + Chr$(&H56)                                'PUSH    SI
  asm$ = asm$ + Chr$(&H1E)                                'PUSH    DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)       'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8A) + Chr$(&H17)                   'MOV     DL,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)       'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H37)                   'MOV     SI,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)       'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                   'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H47) + Chr$(&H71)      'MOV     AX,7147
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                   'INT     21
  asm$ = asm$ + Chr$(&H8C) + Chr$(&HDA)                   'MOV     DX,DS
  asm$ = asm$ + Chr$(&H1F)                                'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)       'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                    'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)       'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)        'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)        'ADC     AX,0000
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                    'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5E)                                'POP     SI
  asm$ = asm$ + Chr$(&H5D)                                'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)       'RETF    0012

  lfn.Drive% = Drive% + 1

  lfn.Path$ = Space$(1024)
  lfn.pathseg% = VARSEG(lfn.Path$)
  lfn.pathoff% = SADD(lfn.Path$)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, lfn.pathseg%, lfn.pathoff%, lfn.Drive%, SADD(asm$))
  DEF SEG

  'convert returned data
  IsError% = lfn.pathseg%
  errorcode% = lfn.pathoff%

  If IsError% Then
      errval = errorcode%
  Else
      errval = 0
    'return current directory
      Path$ = ""
      For i% = 1 To 1025
        ch$ = Mid$(lfn.Path$, i%, 1)
        If ch$ <> Chr$(0) Then
          Path$ = Path$ + ch$
        Else
          Exit For
        End If
      Next
      lfn.cwd$ = Path$
  End If

End Function

'lfn.del -- Delete a file
'INPUT:
'  filename$ - Name of the file to delete
'SUCCESS:
'  * File deleted
'  * Global variable errval set to zero.
'FAIL:
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
SUB lfn.del (filename$)

  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                       'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                          'MOV     BP,SP
  asm$ = asm$ + Chr$(&H56)                                       'PUSH SI
  asm$ = asm$ + Chr$(&H1E)                                       'PUSH    DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)              'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)                          'MOV     DX,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)              'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                          'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H41) + Chr$(&H71)             'MOV     AX,7141
  asm$ = asm$ + Chr$(&HB9) + Chr$(&H0) + Chr$(&H0)               'MOV     CX,0000
  asm$ = asm$ + Chr$(&HBE) + Chr$(&H1) + Chr$(&H0)               'MOV     SI,0001
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                          'INT     21
  asm$ = asm$ + Chr$(&H1F)                                       'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)              'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                           'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)              'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)               'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)               'ADC     AX,0000
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                           'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5E)                                       'POP     SI
  asm$ = asm$ + Chr$(&H5D)                                       'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)              'RETF    0012

  lfn.FileName$ = FileName$ + Chr$(0)
  lfn.filenameseg% = VARSEG(lfn.FileName$)
  lfn.filenameoff% = SADD(lfn.FileName$)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, lfn.filenameseg%, lfn.filenameoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.filenameseg%
  errorcode% = lfn.filenameoff%

  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
  End If

End Sub

'lfn.close -- Stop file search
'INPUT:
'  None
'SUCCESS:
'  * Global variable errval set to zero.
'FAIL:
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
SUB lfn.findclose

  SHARED lfn.filefindhandle%

  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                  'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                     'MOV     BP,SP
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)         'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H1F)                     'MOV     BX,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&HA1) + Chr$(&H71)        'MOV     AX,71A1
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                     'INT     21
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)         'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)          'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)          'ADC     AX,0000
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5D)                                  'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)         'RETF    0012

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, IsError%, errorcode%, lfn.filefindhandle%, SADD(asm$))
  DEF SEG

  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
  End If

End Sub

'lfn.findfirst$ -- Find file, initialization call
'INPUT:
'  filespec$ - File name type to look for. IE - "C:\*.*"
'  findattrib% - Files with these attributes are returned. Any files with
'    lesser attributes are also returned. Files with more than these
'    attributes are not returned. Used in conjunction with mustattrib%.
'    Use ATT.* constants provided in declaration.
'  mustattrib% - Files without these attributes are not returned. Used in
'    conjunction with findattrib%. Use ATT.* constants provided in
'    declaration.
'SUCCESS:
'  * Return name of the first file matching the createria.
'  * Global variable errval set to zero.
'FAIL:
'  * Return "".
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
FUNCTION lfn.findfirst$ (filespec$, findattrib%, mustattrib%)

  SHARED lfn.filefindhandle%
  SHARED lfn.finddata AS STRING * 320
  lfn.finddata = Space$(320)

  asm$ = asm$ + Chr$(&H55)                                  'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                     'MOV     BP,SP
  asm$ = asm$ + Chr$(&H57)                                  'PUSH    DI
  asm$ = asm$ + Chr$(&H6)                                   'PUSH    ES
  asm$ = asm$ + Chr$(&H56)                                  'PUSH    SI
  asm$ = asm$ + Chr$(&H1E)                                  'PUSH    DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)         'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H3F)                     'MOV     DI,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)         'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H7)                      'MOV     ES,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)                     'MOV     DX,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HE)         'MOV     BX,[BP+0E]
  asm$ = asm$ + Chr$(&H8A) + Chr$(&H2F)                     'MOV     CH,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H10)        'MOV     BX,[BP+10]
  asm$ = asm$ + Chr$(&H8A) + Chr$(&HF)                      'MOV     CL,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)         'MOV     BX,[BP+0C]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                     'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H4E) + Chr$(&H71)        'MOV     AX,714E
  asm$ = asm$ + Chr$(&HBE) + Chr$(&H1) + Chr$(&H0)          'MOV     SI,0001
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                     'INT     21
  asm$ = asm$ + Chr$(&H1F)                                  'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)          'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)          'ADC     AX,0000
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)         'MOV     BX,[BP+0C]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5E)                                  'POP     SI
  asm$ = asm$ + Chr$(&H7)                                   'POP     ES
  asm$ = asm$ + Chr$(&H5F)                                  'POP     DI
  asm$ = asm$ + Chr$(&H5D)                                  'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)         'RETF    0012

  lfn.filespec$ = filespec$ + Chr$(0)

  lfn.filespecseg% = VARSEG(lfn.filespec$)
  lfn.filespecoff% = SADD(lfn.filespec$)
  lfn.finddataseg% = VARSEG(lfn.finddata)
  lfn.finddataoff% = VarPtr(lfn.finddata)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, findattrib%, mustattrib%, lfn.filespecseg%, lfn.filespecoff%, lfn.finddataseg%, lfn.finddataoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.filespecseg%
  retcode% = lfn.filespecoff%

  If IsError% Then
    errval = retcode%
  Else
    errval = 0
    lfn.filefindhandle% = retcode%
    FileName$ = ""
    DEF SEG = VARSEG(lfn.finddata)
    For i% = 0 To 259
      ch$ = Chr$(PEEK(VarPtr(lfn.finddata) + &H2C + i%))
      If ch$ <> Chr$(0) Then
        FileName$ = FileName$ + ch$
      Else
        Exit For
      End If
    Next
    lfn.findfirst$ = FileName$
  End If

End Function

'lfn.findnext$ -- Find file, continuation call
'INPUT:
'  None. Same values used to call LFN.FINDFIRST$ are automatically used.
'SUCCESS:
'  * Return name of the next file matching the createria.
'  * Global variable errval set to zero.
'FAIL:
'  * Return "".
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully. This includes a case when there
'    is no more a file matching the createria.
FUNCTION lfn.findnext$
 
  SHARED lfn.filefindhandle%
  SHARED lfn.finddata AS STRING * 320

  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                  'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                     'MOV     BP,SP
  asm$ = asm$ + Chr$(&H56)                                  'PUSH    SI
  asm$ = asm$ + Chr$(&H6)                                   'PUSH    ES
  asm$ = asm$ + Chr$(&H57)                                  'PUSH    DI
  asm$ = asm$ + Chr$(&HBE) + Chr$(&H1) + Chr$(&H0)          'MOV     SI,0001
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)         'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H3F)                     'MOV     DI,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)         'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H7)                      'MOV     ES,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H1F)                     'MOV     BX,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H4F) + Chr$(&H71)        'MOV     AX,714F
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                     'INT     21
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)         'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)         'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)          'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)          'ADC     AX,0000
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5F)                                  'POP     DI
  asm$ = asm$ + Chr$(&H7)                                   'POP     ES
  asm$ = asm$ + Chr$(&H5E)                                  'POP     SI
  asm$ = asm$ + Chr$(&H5D)                                  'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)         'RETF    0012

  lfn.finddataseg% = VARSEG(lfn.finddata)
  lfn.finddataoff% = VarPtr(lfn.finddata)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, lfn.filefindhandle%, lfn.finddataseg%, lfn.finddataoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.finddataseg%
  errorcode% = lfn.finddataoff%

  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
    FileName$ = ""
    DEF SEG = VARSEG(lfn.finddata)
    For i% = 0 To 259
      ch$ = Chr$(PEEK(VarPtr(lfn.finddata) + &H2C + i%))
      If ch$ <> Chr$(0) Then
        FileName$ = FileName$ + ch$
      Else
        Exit For
      End If
    Next
    lfn.findnext$ = FileName$
  End If

End Function

'lfn.l2s$ -- Convert long filename to short filename
'INPUT:
'  longname$ - Long filename to convert to short filename.
'SUCCESS:
'  * Return short filename version of the long filename.
'  * Global variable errval set to zero.
'FAIL:
'  * Return "".
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
FUNCTION lfn.l2s$ (longname$)

  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                  'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                     'MOV     BP,SP
  asm$ = asm$ + Chr$(&H57)                                  'PUSH    DI
  asm$ = asm$ + Chr$(&H6)                                   'PUSH    ES
  asm$ = asm$ + Chr$(&H56)                                  'PUSH    SI
  asm$ = asm$ + Chr$(&H1E)                                  'PUSH    DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)         'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H3F)                     'MOV     DI,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)         'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H7)                      'MOV     ES,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H37)                     'MOV     SI,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)         'MOV     BX,[BP+0C]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                     'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H60) + Chr$(&H71)        'MOV     AX,7160
  asm$ = asm$ + Chr$(&HB9) + Chr$(&H1) + Chr$(&H0)          'MOV     CX,0001
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                     'INT     21
  asm$ = asm$ + Chr$(&H1F)                                  'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)          'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)          'ADC     AX,0000
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)         'MOV     BX,[BP+0C]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5E)                                  'POP     SI
  asm$ = asm$ + Chr$(&H7)                                   'POP     ES
  asm$ = asm$ + Chr$(&H5F)                                  'POP     DI
  asm$ = asm$ + Chr$(&H5D)                                  'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)         'RETF    0012

  lfn.longname$ = longname$ + Chr$(0)
  lfn.shortname$ = Space$(67)
 
  lfn.longnameseg% = VARSEG(lfn.longname$)
  lfn.longnameoff% = SADD(lfn.longname$)
  lfn.shortnameseg% = VARSEG(lfn.shortname$)
  lfn.shortnameoff% = SADD(lfn.shortname$)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, lfn.longnameseg%, lfn.longnameoff%, lfn.shortnameseg%, lfn.shortnameoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.longnameseg%
  errorcode% = lfn.longnameoff%
 
  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
    shortname$ = ""
    For i% = 1 To 67
      ch$ = Mid$(lfn.shortname$, i%, 1)
      If ch$ <> Chr$(0) Then
        shortname$ = shortname$ + ch$
      Else
        Exit For
      End If
    Next
    lfn.l2s$ = shortname$
  End If

End Function

'lfn.mkdir -- Create/Make Directory
'INPUT:
'  dirname$ - Name of the directory to create.
'SUCCESS:
'  * New directory created
'  * Global variable errval set to zero.
'FAIL:
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
SUB lfn.mkdir (dirname$)

  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                       'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                          'MOV     BP,SP
  asm$ = asm$ + Chr$(&H1E)                                       'PUSH    DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)              'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)                          'MOV     DX,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)              'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                          'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H39) + Chr$(&H71)             'MOV     AX,7139
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                          'INT     21
  asm$ = asm$ + Chr$(&H1F)                                       'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)              'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                           'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)              'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)               'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)               'ADC     AX,0000
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                           'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5D)                                       'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)              'RETF    0012

  lfn.dirname$ = dirname$ + Chr$(0)
  lfn.dirnameseg% = VARSEG(lfn.dirname$)
  lfn.dirnameoff% = SADD(lfn.dirname$)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, lfn.dirnameseg%, lfn.dirnameoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.dirnameseg%
  errorcode% = lfn.dirnameoff%

  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
  End If

End Sub

'lfn.ren -- Rename file/directory
'INPUT:
'  oldname$ - Name of the file/directory to change.
'  newname$ - Name of the new file/directory name.
'SUCCESS:
'  * Specified file/directory name changed to the specified name.
'  * Global variable errval set to zero.
'FAIL:
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
SUB lfn.ren (oldname$, newname$)

  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                  'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                     'MOV     BP,SP
  asm$ = asm$ + Chr$(&H57)                                  'PUSH    DI
  asm$ = asm$ + Chr$(&H6)                                   'PUSH    ES
  asm$ = asm$ + Chr$(&H1E)                                  'PUSH    DS
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H56) + Chr$(&H71)        'MOV     AX,7156
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)         'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H3F)                     'MOV     DI,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)         'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H7)                      'MOV     ES,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)                     'MOV     DX,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)         'MOV     BX,[BP+0C]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                     'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                     'INT     21
  asm$ = asm$ + Chr$(&H1F)                                  'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)         'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)          'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)          'ADC     AX,0000
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)         'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H7)                                   'POP     ES
  asm$ = asm$ + Chr$(&H5F)                                  'POP     DI
  asm$ = asm$ + Chr$(&H5D)                                  'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)         'RETF    0012

  lfn.oldname$ = oldname$ + Chr$(0)
  lfn.newname$ = newname$ + Chr$(0)

  lfn.oldnameseg% = VARSEG(lfn.oldname$)
  lfn.oldnameoff% = SADD(lfn.oldname$)
  lfn.newnameseg% = VARSEG(lfn.newname$)
  lfn.newnameoff% = SADD(lfn.newname$)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, lfn.oldnameseg%, lfn.oldnameoff%, lfn.newnameseg%, lfn.newnameoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.newnameseg%
  errorcode% = lfn.newnameoff%

  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
  End If

End Sub

'lfn.rmdir -- Remove Directory
'INPUT:
'  dirname$ - Name of the directory to remove.
'SUCCESS:
'  * Specified directory removed.
'  * Global variable errval set to zero.
'FAIL:
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
SUB lfn.rmdir (dirname$)
  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                       'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                          'MOV     BP,SP
  asm$ = asm$ + Chr$(&H1E)                                       'PUSH    DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)              'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H17)                          'MOV     DX,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)              'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                          'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H3A) + Chr$(&H71)             'MOV     AX,713A
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                          'INT     21
  asm$ = asm$ + Chr$(&H1F)                                       'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)              'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                           'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)              'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)               'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)               'ADC     AX,0000
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                           'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5D)                                       'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)              'RETF    0012

  lfn.dirname$ = dirname$ + Chr$(0)
  lfn.dirnameseg% = VARSEG(lfn.dirname$)
  lfn.dirnameoff% = SADD(lfn.dirname$)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, dummy%, lfn.dirnameseg%, lfn.dirnameoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.dirnameseg%
  errorcode% = lfn.dirnameoff%

  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
  End If

End Sub

'lfn.s2l$ -- Convert short filename to long filename
'INPUT:
'  shortname$ - Short filename to convert to long filename.
'SUCCESS:
'  * Return long filename version of the short filename.
'  * Global variable errval set to zero.
'FAIL:
'  * Return "".
'  * Global variable errval set to &h7100 if function is not supported.
'    (probably does not support LFN)
'  * Global variable errval set to non-zero if an error occurs and the task
'    could not be completed successfully.
FUNCTION lfn.s2l$ (shortname$)

  asm$ = ""
  asm$ = asm$ + Chr$(&H55)                                  'PUSH    BP
  asm$ = asm$ + Chr$(&H89) + Chr$(&HE5)                     'MOV     BP,SP
  asm$ = asm$ + Chr$(&H57)                                  'PUSH    DI
  asm$ = asm$ + Chr$(&H6)                                   'PUSH    ES
  asm$ = asm$ + Chr$(&H56)                                  'PUSH    SI
  asm$ = asm$ + Chr$(&H1E)                                  'PUSH    DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H6)         'MOV     BX,[BP+06]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H3F)                     'MOV     DI,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&H8)         'MOV     BX,[BP+08]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H7)                      'MOV     ES,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H37)                     'MOV     SI,[BX]
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)         'MOV     BX,[BP+0C]
  asm$ = asm$ + Chr$(&H8E) + Chr$(&H1F)                     'MOV     DS,[BX]
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H60) + Chr$(&H71)        'MOV     AX,7160
  asm$ = asm$ + Chr$(&HB9) + Chr$(&H2) + Chr$(&H0)          'MOV     CX,0002
  asm$ = asm$ + Chr$(&HCD) + Chr$(&H21)                     'INT     21
  asm$ = asm$ + Chr$(&H1F)                                  'POP     DS
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HA)         'MOV     BX,[BP+0A]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&HB8) + Chr$(&H0) + Chr$(&H0)          'MOV     AX,0000
  asm$ = asm$ + Chr$(&H15) + Chr$(&H0) + Chr$(&H0)          'ADC     AX,0000
  asm$ = asm$ + Chr$(&H8B) + Chr$(&H5E) + Chr$(&HC)         'MOV     BX,[BP+0C]
  asm$ = asm$ + Chr$(&H89) + Chr$(&H7)                      'MOV     [BX],AX
  asm$ = asm$ + Chr$(&H5E)                                  'POP     SI
  asm$ = asm$ + Chr$(&H7)                                   'POP     ES
  asm$ = asm$ + Chr$(&H5F)                                  'POP     DI
  asm$ = asm$ + Chr$(&H5D)                                  'POP     BP
  asm$ = asm$ + Chr$(&HCA) + Chr$(&H12) + Chr$(&H0)         'RETF    0012

  lfn.shortname$ = shortname$ + Chr$(0)
  lfn.longname$ = Space$(261)
 
  lfn.shortnameseg% = VARSEG(lfn.shortname$)
  lfn.shortnameoff% = SADD(lfn.shortname$)
  lfn.longnameseg% = VARSEG(lfn.longname$)
  lfn.longnameoff% = SADD(lfn.longname$)

  DEF SEG = VARSEG(asm$)
  Call absolute(dummy%, dummy%, dummy%, dummy%, dummy%, lfn.shortnameseg%, lfn.shortnameoff%, lfn.longnameseg%, lfn.longnameoff%, SADD(asm$))
  DEF SEG

  IsError% = lfn.shortnameseg%
  errorcode% = lfn.shortnameoff%

  If IsError% Then
    errval = errorcode%
  Else
    errval = 0
    longname$ = ""
    For i% = 1 To 261
      ch$ = Mid$(lfn.longname$, i%, 1)
      If ch$ <> Chr$(0) Then
        longname$ = longname$ + ch$
      Else
        Exit For
      End If
    Next
    lfn.s2l$ = longname$
  End If

End Function


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 13, 2003, 01:03:26 PM
SUB open.file(long.file.name$, n%, method%)

opens that file in record n% with the method method%... like you know OUTPUT INPUT RANDOM APPEND etc....

EDIT
I guess converting to short filename isn't terrible, but I just don't like it.


Title: how to access long filename length in DOS? (na_th_an)
Post by: na_th_an on June 13, 2003, 01:32:31 PM
You can use the FUNCTION lfn.l2s$ (longname$) in the code I gave you inside your open.file function. That way, using longfilenames or not will be transparent to the user and your problem will be fixed. You _have_ to do this 'cause OPEN only takes 8.3 filenames.


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 13, 2003, 01:45:48 PM
Ok... I'll use neo's though.. it's shorter....

EDIT: Neo, what is RegTypeX? You don't define it.


Title: REGTYPEX...
Post by: Glenn on June 13, 2003, 02:02:36 PM
is a user-defined variable type set up in QB.BI.  Calls to INTERRUPTX require it (or its equivalent).  I'm wondering what his

'$LIB: '..\..\QB.LIB'

does.


Title: Due to the sheer number of requests flooding this forum,
Post by: Agamemnus on June 13, 2003, 04:22:40 PM
I will now show y'all how I did it without qb.bi...

Observe.

Code:

'$DYNAMIC
DIM SHARED option.list$(1 TO 1), option.list2$(1 TO 1), option.amount as integer

load.file.list "C:\qbasic\"

SUB load.file.list (dir$)
CHDIR dir$
SHELL "dir *.txt /b /ON >list.dir"
SHELL "dir *.txt /l /ON >list2.dir"

f% = FREEFILE
option.amount% = 0
OPEN "list.dir" FOR INPUT AS #f%
DO
LINE INPUT #f%, file$
options$ = options$ + file$ + "|"
option.amount% = option.amount% + 1

LOOP UNTIL EOF(f%)
CLOSE #f%
KILL "list.dir"
REDIM option.list$(1 TO option.amount%)
REDIM option.list2$(1 TO option.amount%)
f% = FREEFILE
OPEN "list2.dir" FOR INPUT AS #f%
FOR i% = 1 TO 5
LINE INPUT #1, temp$
NEXT i%
FOR i% = 1 TO option.amount%
LINE INPUT #1, temp$
space.exists% = INSTR(1, temp$, " ")
temp1$ = MID$(temp$, 1, space.exists% - 1)
space.exists% = INSTR(10, temp$, " ")
temp2$ = MID$(temp$, 10, space.exists% - 10)
option.list2$(i%) = temp1$ + "." + temp2$
NEXT i%
CLOSE
KILL "list2.dir"
FOR i% = 1 TO option.amount%
filename.break% = INSTR(options$, "|")
option.list$(i%) = MID$(options$, 1, filename.break% - 1)
options$ = MID$(options$, filename.break% + 1)
NEXT i%
END SUB


Title: I just realized that....
Post by: Agamemnus on June 13, 2003, 06:56:15 PM
I realized that I STILL need a way to convert from long to short without having to go through the entire file list to do so. I want efficiency, not exponential running time..

But I DON'T want qb.bi, especially not with UGL as well....


Title: how to access long filename length in DOS? (na_th_an)
Post by: na_th_an on June 13, 2003, 07:03:55 PM
I've been researching and the only way is using interrupts (the code I supplied). Why don't you wanna use QB.QLB?


Title: Because I don't think that UGL is....
Post by: Agamemnus on June 13, 2003, 07:20:55 PM
compatible with other libs.

Anyways, I am a real n00b on the issue, but maybe they can be mixed? If so I don't know how..

(and I don't want to use the huge qb lib thing)


Title: how to access long filename length in DOS? (na_th_an)
Post by: Plasma on June 13, 2003, 08:29:19 PM
UGL doesn't even "know" what other libs you are using. As far as combining libs, use multilib (http://qb45.tonez-online.com/qbasic/pn/modules.php?op=modload&name=Downloads&file=index&req=getit&lid=1243) if you're scared of the command line.


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 14, 2003, 12:12:54 AM
Thanks to plasma for help.... he made me what i needed.


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 14, 2003, 08:15:44 PM
Ok, Neo, I got your file conversion function working, but it adds "__" at the end. Bug!?


Title: how to access long filename length in DOS? (na_th_an)
Post by: Blitz on June 15, 2003, 12:14:43 PM
nathan, that code will crash in pds and vbdos becuase of far strings. You'll need to use sseg()


Title: how to access long filename length in DOS? (na_th_an)
Post by: na_th_an on June 15, 2003, 01:44:41 PM
Ok. Nice to know. But it is already commented in the code:

Quote
Code:
'* In QuickBASIC PDS and VisualBASIC, change all the lines in the format
'  "VARSEG(any.string.variable$)" to "SSEG(any.string.variable$)".


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 15, 2003, 01:49:06 PM
I can't do it in qb45, either. I get divide by zero error when trying to copy.


Title: how to access long filename length in DOS? (na_th_an)
Post by: [Unknown] on June 15, 2003, 04:47:57 PM
Search on Google for "LFN quickbasic" and you'll doubtless find a dozen libraries.... but...

http://unknown.network32.net/qb/lfn2.zip

Written in Assembly, with source.  It's been a while since I looked at it, but I know it at least *worked*.  All it has is short->long and long->short.  Includes QLB, OBJ, ASM, and BAS test file.

-[Unknown]


Title: yeah,
Post by: Agamemnus on June 15, 2003, 04:52:52 PM
i actually found the same thing in my old files:

http://www.geocities.com/pisforpi/lfn.zip

But now I am confuzzled on how to combine lfn lib and ugl lib with multilib, since I suck.


Title: Did you leave some "." out of there?...
Post by: Glenn on June 15, 2003, 05:09:12 PM
If you have LFN.LIB and UGL.LIB, and you want to combine them into one library, named for example, LFNUGL.LIB:

LIB LFNUGL +LFN.LIB +UGL.LIB;

To make LFNUGL.QLB:

LINK /Q LFNUGL.LIB, LFNUGL,, BQLB45;

or before you make LFNUGL.LIB, via

LINK /Q LFN.LIB UGL.LIB, LFNUGL,, BQLB45;


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 15, 2003, 05:56:24 PM
the qlb won't link due to too many segments.

Blitz said how to compile UGL here, maybe that is what some smarter dude could use to figure it out? :)

http://forum.qbasicnews.com/viewtopic.php?t=2906&highlight=compile+ugl


Title: You *may* be able to use the /SE:800 option...
Post by: Glenn on June 15, 2003, 07:05:57 PM
with the /Q option.  I don't know.  I've never tried it.  (But I can't see offhand why it shouldn't be allowed.)


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 15, 2003, 07:35:01 PM
works :)


Title: how to access long filename length in DOS? (na_th_an)
Post by: Blitz on June 15, 2003, 09:27:52 PM
hey ag, the ugl builder allows you to add 14 of your own objs/libs. I just uploaded it. Get the latest build.


Title: how to access long filename length in DOS? (na_th_an)
Post by: Agamemnus on June 15, 2003, 09:36:11 PM
i might do this later, but you're too late, blitz. I already did what I needed. :(