From: Steve Wart <swart@prodigy.bc.ca>
Subject: Toolbox access with MCL (relatively long)
Summary: File Manager Problems
Organization: PTC Vancouver
X-Useragent: Nuntius v1.0
Date: Wed, 22 Jul 1992 22:06:33 GMT



I've been trying to access the low-level file manager calls, with mixed
results.  For example, I wrote functions to remedy what I saw as
inconsistencies
in the documentation in the MCL 2.0b1 reference manual.  First, there
doesn't
seem to be any built-in way to get the name of a volume, given that you
have
a valid volume number (compare (volume-number) on p. 290 to (drive-name)
and
(drive-number) on p. 292).  Second, there doesn't seem to be a way to
find out
which volumes are actually mounted when using the function calls on p.
290-291.
I'd appreciate any comments on the following functions that I came up
with:

(defun volume-name (vol)
  ;;
  ;;  This function will return the volume name of the volume specified
by the
  ;;  volume name or vrefnum passed as the argument specified by the
parameter,
  ;;  vol.
  ;;
  (with-returned-pstrs ((volume-name-str
  						 (cond ((typep vol 'pathname) (mac-namestring vol))
          					   ((typep vol 'fixnum) "")
          					   (t (error "Argument ~S is not of the required type."
vol)))))
    (let ((pb (make-record :HParamBlockRec
                           :ioNamePtr volume-name-str
                           :ioVRefNum (volume-number vol)
                           :ioVolIndex 0)))
      (unwind-protect
        (cond ((eql (#_PBHGetVinfoSync pb) #$noErr)
               (make-pathname :directory
                                (%get-string (rref pb
(HParamBlockRec.ioNamePtr)))))
              (t (error "No such volume.")))
        (dispose-record pb :HParamBlockRec)))))

(defun scan-volumes ()
  ;;
  ;;  This function will return a list of mounted Macintosh volumes.
  ;;  Each element of the list will contain the following information:
  ;;     (first element) => volume name
  ;;     (second element) => volume reference number
  ;;     (third element) => drive number
  ;;
  (with-returned-pstrs ((volume-name ""))
    (loop with pb  = (make-record :HParamBlockRec
                                  :ioNamePtr volume-name
                                  :ioVRefNum 0
                                  :ioVolIndex 1)
          while (eql (#_PBHGetVInfoSync pb) #$noErr)
          collect (list
                   (make-pathname :directory
                                  (%get-string (rref pb
(HParamBlockRec.ioNamePtr))))
                   (rref pb (HParamBlockRec.ioVRefNum))
                   (rref pb (HParamBlockRec.ioVDrvInfo)))
          do (rset pb :HParamBlockRec.ioVolIndex
                   (+ (rref pb (HParamBlockRec.ioVolIndex)) 1))
          finally
          (dispose-record pb :HParamBlockRec))))

My question is this:  will the release version of MCL provide higher
level access
to the toolbox than through deftrap?  This seems to be a slow way to get
things
done, and while it is much easier in Lisp than in C, allocating and
deallocating
records goes against my concept of "high level."  In particular, I've
been trying
to access some of the fields of the volume parameter block without
success.  When
I pass ioVCrDate and ioVModDate to the following function, I get "Fri,
Jan 1, 1904"
for every volume block I examine (in fact, it returns this value no
matter what you
pass as the argument for the parameter, seconds):

(defun secs2date (seconds)
  ;;
  ;;  Return a string representing the date of the argument, as specified
  ;;  by the parameter, seconds.
  ;;
  (let* ((dr (make-record :LongDateRec))
         (s (#_NewPtr 4))
         (ignore-result (%put-long s seconds))			;ignore-result causes a 
compiler
         (ignore-result (#_LongSecs2Date s dr))			;warning...should this
be a progn?
         (day-of-week (rref dr (LongDateRec.DayOfWeek)))
         (day (rref dr (LongDateRec.day)))
         (month (rref dr (LongDateRec.month)))
         (year (rref dr (LongDateRec.year))))
    (dispose-record dr :LongDateRec)
    (#_DisposPtr s)
    (format nil "~[Sun~;Mon~;Tue~;Wed~;Thu~;Fri~;Sat~], ~
                
~[Jan~;Feb~;Mar~;Apr~;May~;Jun~;Jul~;Aug~;Sep~;Oct~;Nov~;Dec~] ~D, ~D"
            (- day-of-week 1) (- month 1) day year)))
			
Some high-level date and time functions would be very nice (classes?
what are classes?)

I guess the other problems I'm having are more or less related to Mac 
programming in general than with MCL.  If anyone can point me to some 
tech notes or provide solutions to the following questions, I'd 
appreciate it, however:

1> Is there an acceptable way to find out if a disk is ejectable?  i.e. 
I'd like a function (ejectablep vol) that will tell me if I can pop out a 
disk.  I've seen some sample code that scans the drive queue for the 
drive number corresponding to vol, but doesn't that violate Apple's 
programming guidelines?

2> How do you find the icon associated with a particular volume?

Sorry this posting is so long.  I hope my problems are interesting enough 
to provide me with some expert advice.

Thanks,

Steve Wart
swart@prodigy.bc.ca
PTC Vancouver
(604) 687-4636