home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PPOS2.ZIP / QFN.ASM < prev    next >
Assembly Source File  |  1988-10-19  |  10KB  |  266 lines

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