TweetFollow Us on Twitter

File Path
Volume Number:7
Issue Number:9
Column Tag:TechNotes

Related Info: File Manager File Mgr (PBxxx) Standard FIle

File Path Revisited

By Alexander Colwell, Redondo Beach, CA

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

File Path Revisited

Some of the MacTutor readers probably noticed. “Hey! Somebody has already written this article before! So, why is it here again?” Well the answer is yes, it has, but only half the story. The previous MacTutor articles in January 1986 “Programming for HFS Compatibility” by Mike Schuster and in July 1986 “Make a Path Name for HFS” by Tom Taylor discuss when given the volume reference number (vRefNum) obtained by the standard SFGetFile dialog then the file’s full file path can be derived.1 But what about when given a full file path and deriving the file’s vRefNum that would be identical number returned by the SFGetFile dialog?

There are cases when applications, DA’s, or other resource codes may want to know where the file is located between invocations. In April 1990, The Apple Technical Journal’s “d e v e l o p e “ in Macintosh Q&A section recommends saving the “DirID” number that references the directory.2 This scheme is desirable because it’s simple and easy to retrieve the file’s vRefNum by calling the PBOpenWD ROM routine that can be used either by the FSOpen or PBOpen ROM routines. Another advantage is that the user can change the directory name and the directory ID number will remain the same. There are cases when this scheme fails if the directory is backed up, deleted, and restored, then the directory ID number is likely to be changed. Therefore, the application must ask you for the location of the desired file by popping up the SFGetFile dialog again.

OK. So you bother the user again by reasking the location of the file. No big deal. But what about an application managing distributed databases of files where each user has mirror copy of the files and folders relationship on its hard disk? This could be a real pain to ask the user to find hundreds of files when they periodically receive database updates, and the directories are constantly changing. This was exactly the situation I encountered a few years ago during a Macintosh application development at my place of employment.

During the development cycle of that application, I poured over the MacTutor articles and Macintosh Technical Notes on how to do this seemingly simple procedure. To my disappointment, I could not find a method that somebody else might have hacked out! After a few weeks of off and on hacking, I finally figured out how to obtain the vRefNum based on the file path that is equivalent to the same vRefNum returned by the SFGetFile dialog.

The results are two procedures rewritten from Pascal to THINK C from my old Mac programming projects. The first procedure is “GetFilePath” (rehash from previous articles) to obtain the file path given by the vRefNum. The other inverse procedure is the “GetVolRefNbr” to obtain the vRefNum given by the file path.3

The key in the “GetVolRefNbr” procedure is the use of system working directory proc ID : ‘ERIK’. This small tidbit of information can be found in Macintosh Technical Note #77. In my case, I had to figure-out the hard way how this magic working directory proc ID ‘ERIK’ was used in the SFGetFile dialog. At the time, the technical note reference about ‘ERIK’ did not exist.

The conclusion is for those who need to save the file path and then later reconstruct the vRefNum for the FSOpen or PBOpen ROM routines other than using the “DirID” method, then these procedures are for you.

Bibliography

1 You can find additional references in Macintosh Technical Note #238.

2 Finder’s Desktop directory/folder hierarchy. Directories and folders are analogous.

3 I use these routines in the not quite popular shareware NotePad++ desk accessory to remember the last opened “NotePad++ File”.

char *GetFilePathName(vRefNum)
 short vRefNum;              /* File's vol/dir ref    */
 {
  WDParam      wDir;         /* Working directory     */
  HVolumeParam wVol;         /* Working HFS param blk */
  DirInfo      wCInfo;       /* Working cat info blk  */
  long         wDirID;       /* Working dir number    */
  Str255       wName;        /* Working directory name*/
  char         *wPtr;        /* Working string pointer*/
  long         wLength;      /* Working string length */
  char         *pathFileName;/* Working file path name*/

  wDir.ioNamePtr = 0L;       /* Init working directory*/
  wDir.ioVRefNum = vRefNum;
  wDir.ioWDIndex = 0;
  wDir.ioWDProcID = 0;
  wDir.ioWDVRefNum = vRefNum;

  PBGetWDInfo(&wDir,FALSE);  /* Get the directory ref */
  
  vRefNum = wDir.ioWDVRefNum;/* Save working vol ref #*/
  wDirID = wDir.ioWDDirID;   /* Save working dir ref #*/

  wVol.ioNamePtr = (StringPtr)&wName;/* Init vol block*/
  wVol.ioVRefNum = vRefNum;
  wVol.ioVolIndex = 0;
    
  wLength = 0L;              /* Set path length to zip*/
  pathFileName = NewPtr(0L); /* Set null file's path  */
  
  if (!PBHGetVInfo(&wVol,FALSE) &&/* Got vol info?    */
   pathFileName) {           /* Got file path pointer?*/
   if (wVol.ioVSigWord == 0x4244) {/* Check if it HFS */
    wCInfo.ioNamePtr = (StringPtr)&wName;/* Init it   */
    wCInfo.ioVRefNum = vRefNum;
    wCInfo.ioFDirIndex = -1;
    wCInfo.ioDrParID = wDirID;
    wCInfo.ioDrDirID = wDirID;

    while (wCInfo.ioDrParID != 1){/* Do full path     */
     wCInfo.ioDrDirID = wCInfo.ioDrParID;/*Move up dir*/

     if (PBGetCatInfo(&wCInfo,FALSE))/* Get dir info  */
      break;                 /* Break-out if failed!! */

     wLength += wName[0] + 1L;/* Set string length    */
     wPtr = NewPtr(wLength + 1L);/* Alloc new str     */

     if (!wPtr) {            /* Didn't get str ptr?   */
      if (pathFileName)      /* Check if got memory   */
       DisposPtr(pathFileName);/* Release it          */
      pathFileName = 0L;     /* Invalidate str pointer*/
      break;                 /* Break-out if failed!! */
     }
                             /* Shuffle file path down*/
     BlockMove(pathFileName,wPtr + wName[0] + 1,
               wLength - (long)(wName[0]));
     DisposPtr(pathFileName);/* Release old one       */
     *(wPtr + wName[0]) = ':';/* Add dir delimeter    */
     BlockMove(&wName[1],pathFileName = wPtr, (long)(wName[0]));
    }
   }
   else {                    /* Oops, get vol info    */
    wLength = wName[0] + 1L; /* Set string length     */
    wPtr = NewPtr(wLength + 1L);/* Alloc new string   */

    if (wPtr) {              /* Got string pointer?   */
     *(wPtr + wName[0]) = ':';/* Tack on dir delimeter*/
     BlockMove(&wName[1],pathFileName = wPtr,
               (long)(wName[0]));
    }

   }
   if (pathFileName)         /* Check if got da string*/
    pathFileName[wLength] = 0;/* Set end-of-string    */
  }
  return(pathFileName);      /* Return file path name */
 }
 
short GetFilePathVolRef(pathFileName)
 char *pathFileName;         /* File's path string    */
 {
  short        i;            /* Working index         */
  char         c;            /* Working input char    */
  short        vRefNum;      /* Working vol/dir ref   */
  WDParam      wDir;         /* Working directory     */
  HVolumeParam wVol;         /* Working HFS param blk */
  DirInfo      wCInfo;       /* Working cat info block*/
  long         wDirID;       /* Working directory ID  */
  Str255       wVolName;     /* Working volume name   */
  Str255       wName;        /* Working string name   */
  char         *wPtr;        /* Working string pointer*/
  short        wLength;      /* Working string length */
  
  vRefNum = 0;               /* Invalid vol/dir ref # */
  
  wVol.ioVRefNum = 0;        /* Init working vol ID # */
  wCInfo.ioDrDirID = 2;      /* Init top-most dir     */
  
  i = 0;                     /* Init working index    */
  wLength = 0;               /* Init string length    */
  
  c = pathFileName[i];       /* Set 1st input char    */
  
  while(c) {                 /* Do til get vol/dir ref*/
   if (c == ':') {           /* Check if got dir specs*/
    wName[0] = wLength - 1;  /* Set "Pascal" str len  */
    wLength = 0;             /* Reset string length   */

    if (!wVol.ioVRefNum) {   /* Check if need vol ref */
     wVol.ioNamePtr = (StringPtr)(&wVolName);

     for(wVol.ioVolIndex = 1; !PBHGetVInfo(&wVol,FALSE);
      wVol.ioVolIndex++) {
      if (EqualString(wName,wVolName,FALSE,FALSE))
       break;
      }

     vRefNum = wVol.ioVRefNum;/* Save vol ID          */
     if (wVol.ioVSigWord != 0x4244)/* MFS ?           */
      return(vRefNum);       /* Let's get out early!  */
    }
    else {                   /* Nope, get dir ref     */
     wCInfo.ioNamePtr = (StringPtr)(&wName);
     wCInfo.ioVRefNum = wVol.ioVRefNum;
     wCInfo.ioFDirIndex = 0;
     wCInfo.ioDrParID = wCInfo.ioDrDirID;

     if (PBGetCatInfo(&wCInfo,FALSE))/* Check dir ?   */
      return(0);             /* Nope, break-out!!!    */
    }
   }                         /* Add to directory specs*/
   c = wName[++wLength] = pathFileName[i++];
  }
  wDir.ioNamePtr = 0L;       /* Init dir data block   */
  wDir.ioVRefNum = wVol.ioVRefNum;
  wDir.ioWDProcID = 'ERIK';  /* Magic 'SFGetFile' ID #*/
  wDir.ioWDDirID = wCInfo.ioDrDirID;
  
  if (!PBOpenWD(&wDir,FALSE))/* Check if opened dir   */
   vRefNum = wDir.ioVRefNum; /* Return vol/dir ref #  */

  return(vRefNum);           /* Return vol/dir ref #  */
 }
 

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Whitethorn Games combines two completely...
If you have ever gone fishing then you know that it is a lesson in patience, sitting around waiting for a bite that may never come. Well, that's because you have been doing it wrong, since as Whitehorn Games now demonstrates in new release Skate... | Read more »
Call of Duty Warzone is a Waiting Simula...
It's always fun when a splashy multiplayer game comes to mobile because they are few and far between, so I was excited to see the notification about Call of Duty: Warzone Mobile (finally) launching last week and wanted to try it out. As someone who... | Read more »
Albion Online introduces some massive ne...
Sandbox Interactive has announced an upcoming update to its flagship MMORPG Albion Online, containing massive updates to its existing guild Vs guild systems. Someone clearly rewatched the Helms Deep battle in Lord of the Rings and spent the next... | Read more »
Chucklefish announces launch date of the...
Chucklefish, the indie London-based team we probably all know from developing Terraria or their stint publishing Stardew Valley, has revealed the mobile release date for roguelike deck-builder Wildfrost. Developed by Gaziter and Deadpan Games, the... | Read more »
Netmarble opens pre-registration for act...
It has been close to three years since Netmarble announced they would be adapting the smash series Solo Leveling into a video game, and at last, they have announced the opening of pre-orders for Solo Leveling: Arise. [Read more] | Read more »
PUBG Mobile celebrates sixth anniversary...
For the past six years, PUBG Mobile has been one of the most popular shooters you can play in the palm of your hand, and Krafton is celebrating this milestone and many years of ups by teaming up with hit music man JVKE to create a special song for... | Read more »
ASTRA: Knights of Veda refuse to pump th...
In perhaps the most recent example of being incredibly eager, ASTRA: Knights of Veda has dropped its second collaboration with South Korean boyband Seventeen, named so as it consists of exactly thirteen members and a video collaboration with Lee... | Read more »
Collect all your cats and caterpillars a...
If you are growing tired of trying to build a town with your phone by using it as a tiny, ineffectual shover then fear no longer, as Independent Arts Software has announced the upcoming release of Construction Simulator 4, from the critically... | Read more »
Backbone complete its lineup of 2nd Gene...
With all the ports of big AAA games that have been coming to mobile, it is becoming more convenient than ever to own a good controller, and to help with this Backbone has announced the completion of their 2nd generation product lineup with their... | Read more »
Zenless Zone Zero opens entries for its...
miHoYo, aka HoYoverse, has become such a big name in mobile gaming that it's hard to believe that arguably their flagship title, Genshin Impact, is only three and a half years old. Now, they continue the road to the next title in their world, with... | Read more »

Price Scanner via MacPrices.net

B&H has Apple’s 13-inch M2 MacBook Airs o...
B&H Photo has 13″ MacBook Airs with M2 CPUs and 256GB of storage in stock and on sale for up to $150 off Apple’s new MSRP, starting at only $849. Free 1-2 day delivery is available to most US... Read more
M2 Mac minis on sale for $100-$200 off MSRP,...
B&H Photo has Apple’s M2-powered Mac minis back in stock and on sale today for $100-$200 off MSRP. Free 1-2 day shipping is available for most US addresses: – Mac mini M2/256GB SSD: $499, save $... Read more
Mac Studios with M2 Max and M2 Ultra CPUs on...
B&H Photo has standard-configuration Mac Studios with Apple’s M2 Max & Ultra CPUs in stock today and on Easter sale for $200 off MSRP. Their prices are the lowest available for these models... Read more
Deal Alert! B&H Photo has Apple’s 14-inch...
B&H Photo has new Gray and Black 14″ M3, M3 Pro, and M3 Max MacBook Pros on sale for $200-$300 off MSRP, starting at only $1399. B&H offers free 1-2 day delivery to most US addresses: – 14″ 8... Read more
Department Of Justice Sets Sights On Apple In...
NEWS – The ball has finally dropped on the big Apple. The ball (metaphorically speaking) — an antitrust lawsuit filed in the U.S. on March 21 by the Department of Justice (DOJ) — came down following... Read more
New 13-inch M3 MacBook Air on sale for $999,...
Amazon has Apple’s new 13″ M3 MacBook Air on sale for $100 off MSRP for the first time, now just $999 shipped. Shipping is free: – 13″ MacBook Air (8GB RAM/256GB SSD/Space Gray): $999 $100 off MSRP... Read more
Amazon has Apple’s 9th-generation WiFi iPads...
Amazon has Apple’s 9th generation 10.2″ WiFi iPads on sale for $80-$100 off MSRP, starting only $249. Their prices are the lowest available for new iPads anywhere: – 10″ 64GB WiFi iPad (Space Gray or... Read more
Discounted 14-inch M3 MacBook Pros with 16GB...
Apple retailer Expercom has 14″ MacBook Pros with M3 CPUs and 16GB of standard memory discounted by up to $120 off Apple’s MSRP: – 14″ M3 MacBook Pro (16GB RAM/256GB SSD): $1691.06 $108 off MSRP – 14... Read more
Clearance 15-inch M2 MacBook Airs on sale for...
B&H Photo has Apple’s 15″ MacBook Airs with M2 CPUs (8GB RAM/256GB SSD) in stock today and on clearance sale for $999 in all four colors. Free 1-2 delivery is available to most US addresses.... Read more
Clearance 13-inch M1 MacBook Airs drop to onl...
B&H has Apple’s base 13″ M1 MacBook Air (Space Gray, Silver, & Gold) in stock and on clearance sale today for $300 off MSRP, only $699. Free 1-2 day shipping is available to most addresses in... Read more

Jobs Board

Medical Assistant - Surgical Oncology- *Apple...
Medical Assistant - Surgical Oncology- Apple Hill Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Read more
Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Business Analyst | *Apple* Pay - Banco Popu...
Business Analyst | Apple PayApply now " Apply now + Apply Now + Start applying with LinkedIn Start + Please wait Date:Mar 19, 2024 Location: San Juan-Cupey, PR Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.