home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PP0803.ZIP / QFN.ASM next >
Assembly Source File  |  1989-02-14  |  9KB  |  218 lines

  1. ;----------------------------------------------------------------------
  2. ; QFN.ASM -- Qualify File Name, OS/2 Version
  3. ; Copyright (c) 1989 Ziff Communications Co.
  4. ; PC Magazine * Ray Duncan * Feb 14, 1989
  5. ;
  6. ; Call with:    DS:SI = filename address, AX = length
  7. ;
  8. ; Returns:      Carry = clear if filename OK
  9. ;               DS:SI = qualified filename, AX = length
  10. ;               or
  11. ;               Carry = set if bad filename
  12. ;
  13. ; Registers other than DS:SI and AX are preserved.
  14. ;----------------------------------------------------------------------
  15.         .286
  16.  
  17.         extrn   DosChDir:far    ; OS/2 API functions
  18.         extrn   DosQCurDisk:far
  19.         extrn   DosQCurDir:far
  20.         extrn   DosSelectDisk:far
  21.  
  22. DGROUP  group   _DATA
  23. _DATA   segment word public 'DATA'
  24.  
  25. cdrive  dw      0               ; current drive
  26. cpath   db      '\',64 dup (0)  ; current directory
  27. cpsiz   dw      $-cpath-1
  28. drvmap  dd      ?               ; valid drive bitmap
  29. ndrive  dw      0               ; new drive
  30.  
  31. tbuff   db      64 dup (0)      ; target directory
  32.  
  33. qbuff   db      'X:\'           ; qualified pathname
  34.         db      64 dup (0)
  35. qbsiz   dw      $-qbuff-3
  36.  
  37. fname   dw      ?               ; filename address
  38. flen    dw      ?               ; filename length
  39.  
  40. _DATA   ends
  41. ;----------------------------------------------------------------------
  42. _TEXT   segment word public 'CODE'
  43.         assume  cs:_TEXT,ds:DGROUP
  44.  
  45.         public  qfn             ; make visible to Linker
  46.  
  47. qfn     proc    near            ; qualify file name
  48.  
  49.         push    bx              ; save registers
  50.         push    cx
  51.         push    dx
  52.         push    di
  53.         push    es
  54.  
  55.         mov     flen,ax         ; save length and
  56.         mov     fname,si        ; address of filename
  57.  
  58.         mov     ax,ds           ; make DGROUP addressable
  59.         mov     es,ax           ; with ES register
  60. ; save current drive...
  61.         push    ds              ; receives drive ID
  62.         push    offset DGROUP:cdrive
  63.         push    ds              ; receives valid drive bitmap
  64.         push    offset DGROUP:drvmap
  65.         call    DosQCurDisk     ; transfer to OS/2
  66. ; save current directory...
  67.         push    0               ; drive ID = current
  68.         push    ds              ; receives directory path
  69.         push    offset DGROUP:cpath+1
  70.         push    ds              ; contains buffer length
  71.         push    offset DGROUP:cpsiz
  72.         call    DosQCurDir      ; transfer to OS/2
  73. ; did caller specify drive?
  74.         mov     di,fname        ; get address of name
  75.         mov     cx,flen         ; get length of name
  76.  
  77.         cmp     cx,2            ; if drive, length must be >= 2 chars.
  78.         jl      qfn2            ; too short, no drive
  79.  
  80.         cmp     byte ptr [di+1],':'  ; check for drive delimiter
  81.         jne     qfn2            ; no delimiter, jump
  82.  
  83.         mov     al,[di]         ; get ASCII drive code
  84.         or      al,20h          ; fold to lower case
  85.         sub     al,'a'-1        ; convert it to binary
  86.         xor     ah,ah
  87. ; now select new drive
  88.         push    ax              ; binary drive ID
  89.         call    DosSelectDisk   ; transfer to OS/2
  90.         or      ax,ax           ; was drive valid?
  91.         jz      qfn1            ; jump, drive was OK
  92.         jmp     qfn8            ; exit, drive not valid
  93.  
  94. qfn1:   add     di,2            ; bump pointer past drive
  95.         sub     cx,2            ; and decrement length
  96. qfn2:                           ; get current directory again for new drive...
  97.         push    0               ; drive ID = current
  98.         push    ds              ; receives directory path
  99.         push    offset DGROUP:cpath+1
  100.         push    ds              ; contains buffer length
  101.         push    offset DGROUP:cpsiz
  102.         call    DosQCurDir      ; transfer to OS/2
  103. ; scan off path if any...
  104.         push    di              ; save start of path
  105.         mov     al,'\'          ; path delimiter
  106. qfn3:   mov     fname,di        ; save path pointer
  107.         mov     flen,cx         ; save path length
  108.         jcxz    qfn4            ; jump if none left
  109.         repne scasb             ; any '\' left in path?
  110.         je      qfn3            ; loop if '\' found
  111. qfn4:   pop     si              ; recover starting address of path portion
  112. ; copy path to local buffer and make it ASCIIZ...
  113.         mov     di,offset DGROUP:tbuff
  114.         mov     cx,fname        ; calculate path length
  115.         sub     cx,si
  116.         jz      qfn6            ; jump, no path at all
  117.         cmp     cx,1            ; root directory?
  118.         je      qfn5            ; jump if root
  119.         dec     cx              ; else discard last '\'
  120. qfn5:   rep movsb               ; transfer path and
  121.         xor     al,al           ; append null byte
  122.         stosb
  123. ; select target directory...
  124.         push    ds              ; directory path address
  125.         push    offset DGROUP:tbuff
  126.         push    0               ; DWORD reserved
  127.         push    0
  128.         call    DosChDir        ; transfer to OS/2
  129.         or      ax,ax           ; directory valid?
  130.         jnz     qfn8            ; jump, no such directory
  131. ; build up full pathname...get current drive
  132. qfn6:
  133.         push    ds              ; receives drive ID
  134.         push    offset DGROUP:ndrive
  135.         push    ds              ; receives valid drive bitmap
  136.         push    offset DGROUP:drvmap
  137.         call    DosQCurDisk     ; transfer to OS/2
  138.         mov     ax,ndrive       ; convert binary drive code
  139.         add     ax,'a'-1        ; to ASCII drive identifier
  140.         mov     qbuff,al
  141. ; get current directory
  142.         push    0               ; drive ID = current
  143.         push    ds              ; receives directory path
  144.         push    offset DGROUP:qbuff+3
  145.         push    ds              ; contains buffer length
  146.         push    offset DGROUP:qbsiz
  147.         call    DosQCurDir      ; transfer to OS/2
  148.         or      ax,ax           ; operation successful?
  149.         jnz     qfn8            ; no, return error
  150. ; point to path component
  151.         mov     di,offset DGROUP:qbuff+3
  152.         cmp     byte ptr [di],0 ; is current directory the root directory?
  153.         je      qfn7            ; yes, jump
  154.  
  155.         xor     al,al           ; scan for null byte at
  156.         mov     cx,-1           ; end of path name
  157.         repne scasb             ; and append backslash
  158.         mov     byte ptr [di-1],'\'
  159. qfn7:                           ; now append filename
  160.                                 ; to drive and path...
  161.         mov     si,fname        ; filename address
  162.         cmp     byte ptr [si],'.'
  163.         je      qfn8            ; exit if directory alias
  164.         mov     cx,flen         ; filename length
  165.         rep movsb               ; copy it
  166.         mov     si,offset DGROUP:qbuff ; set DS:SI = address
  167.         mov     ax,di           ; and AX = length of
  168.         sub     ax,si           ; fully qualified filename
  169.         call    makelc          ; fold filename to lower case to make it pretty
  170.         clc                     ; set Carry = false to indicate success and
  171.         jmp     qfn9            ; go to common exit point
  172. qfn8:                           ; come here if any error detected...
  173.         stc                     ; set Carry = true to indicate error
  174. qfn9:   pushf                   ; save Carry flag
  175.         push    ax              ; save final length
  176.                                 ; restore original directory
  177.         push    ds              ; address of directory path
  178.         push    offset DGROUP:cpath
  179.         push    0               ; DWORD reserved
  180.         push    0
  181.         call    DosChDir        ; transfer to OS/2
  182.                                 ; restore original drive
  183.         push    cdrive          ; binary drive ID
  184.         call    DosSelectDisk
  185.  
  186.         pop     ax              ; restore length
  187.         popf                    ; and Carry flag
  188.  
  189.         pop     es              ; restore other affected
  190.         pop     di              ; registers
  191.         pop     dx
  192.         pop     cx
  193.         pop     bx
  194.         ret                     ; back to caller
  195.  
  196. qfn     endp
  197. ;----------------------------------------------------------------------
  198. makelc  proc    near ; string -> lower case, DS:SI = address, AX = length
  199.  
  200.         push    bx              ; save BX contents
  201.         xor     bx,bx           ; BX will be pointer
  202. mlc1:                           ; change A-Z to a-z
  203.         cmp     byte ptr [bx+si],'A'
  204.         jb      mlc2
  205.         cmp     byte ptr [bx+si],'Z'
  206.         ja      mlc2
  207.         or      byte ptr [bx+si],20h
  208. mlc2:   inc     bx              ; advance through string
  209.         cmp     bx,ax           ; done with string yet?
  210.         jne     mlc1            ; no, check next char.
  211.         pop     bx              ; restore BX and
  212.         ret                     ; return to caller
  213.  
  214. makelc  endp
  215.  
  216. _TEXT   ends
  217.         end
  218.