[comp.sys.mac.programmer] Getting a complete pathname

marty@june.cs.washington.edu (Marty Sirkin) (02/21/89)

I am currently using (in LSP 2.0) SFGetFile to select an input file (with a 
custom dialog box and dialogHook procedure).  It works just great.  My
problem is that when a file is selected, the reply record returns a file
name and directory ref number.  I really need the pathname, not the number
as I need to use the staandard pascal reset/rewrite...

I have looked through IM 2 and 4, but cannot seem to find what I need.  It
should not be too tough, as the LSP routine "getoldfile" does return the
whole path name.  Any ideas?  I appreciate the help.

					Marty Sirkin

bob@accuvax.nwu.edu (Bob Hablutzel) (02/21/89)

> I am currently using (in LSP 2.0) SFGetFile to select an input file (with a 
> custom dialog box and dialogHook procedure).  It works just great.  My
> problem is that when a file is selected, the reply record returns a file
> name and directory ref number.  I really need the pathname, not the number
> as I need to use the staandard pascal reset/rewrite...

> I have looked through IM 2 and 4, but cannot seem to find what I need.  It
> should not be too tough, as the LSP routine "getoldfile" does return the
> whole path name.  Any ideas?  I appreciate the help.

What you have to do is start at the vRefNum regurturned, and walk backwards
up the directory chain using GetCatInfo. This will return both the name of
the directory, and the DirID of the parent of the directory. 

The following code will do just that, but it's in assembler. With sufficient
demand, I'll translate it into Pascal. Feel free to use this as you like.
This is MPW assembler, 2.0.2, using the truly great program structure macros.

	Title	'Get full folder name'
;_______________________________________________________________________________
;
; Module	GetFolderName
;
; Description	GetFolderName gets the folder name from the vRefNum
;
; Written by	Bob Hablutzel, Wildwood Software
;
; Modified by
;_______________________________________________________________________________


	Procedure	GetFolderName(		\
			vRefNum:W,		\	; In, volume reference
			name:L			)	; Out, string pointer
								
	Var	ioParamBlock:b[ioHFQElSiz]
	Var	TempString:B[256]
		
	Begin	Save=SaveRegs

; Break the vRefNum into a directory ID and a vRefNum

	clr.l	D1
	lea	ioParamBlock(FP),A0
	clr.l	ioCompletion(A0)
	lea	tempString(FP),A1
	move.l	A1,ioFileName(A0)
	move.w	vRefNum(FP),ioVRefNum(A0)
	clr.w	ioWDIndex(A0)
	clr.l	ioWDProcID(A0)
	clr.w	ioWDVRefNum(A0)
	_GetWDInfo
			
; The string is assumed to be 255 characters long. Get a pointer to the end of 
; the string. A3 points the current position in the string, and A4 points to
; the byte count for the string.
					
	move.l	Name(FP),A4
	lea	256(A4),A3
	move.b	#':',-(A3)
	move.b	#1,(A4)
									
; Initialize the ioParamBlock for the get name request.

	move.l	ioWDDirId(A0),ioDrDirID(A0)
	clr.l	ioCompletion(A0)
	lea	tempString(FP),A1
	move.l	A1,ioFileName(A0)
	move.w	#-1,ioFDirIndex(A0)
	move.w	vRefNum(FP),ioVRefNum(A0)
							
; Get the next folder name
									
Loop:
	clr.b	tempString(FP)
	lea	ioParamBlock(FP),A0
	_GetCatInfo
	bmi	Exit

; See if the string will fit. If not, make the current first character a '' and
; return the string. Note - the '' is the ellipse character '...' on the Mac
	
	addq.b	#1,D0
	add.b	tempString(FP),D0
	bvc	CopyString
			
	move.b	#'',(A3)
	bra	ReturnString

; The string will fit, so copy it in

CopyString:
	clr.l	D0
	move.b	TempString(FP),D0
	sub.l	D0,A3
	
	move.l	A3,A1
	lea	tempString+1(FP),A0
	_BlockMove
	move.b	tempString(FP),D0
	add.b	D0,(A4)
	
; If we are done, 
	
	cmp.l	#1,ioParamBlock+ioDrParID(FP)
	beq	ReturnString
			
; Add the ':' seperator

	move.b	#':',-(A3)
	addq.b	#1,(A4)

; Get ready for the next _GetCatInfo

	move.l	ioParamBlock+ioDrParID(FP),ioParamBlock+ioDrDirID(FP)
	bra	Loop
	
; Return the string

ReturnString:

	clr.l	D0
	move.b	(A4),D0
	move.l	A3,A0
	lea	1(A4),A1
	_BlockMove
				
; and exit
				
Exit:	Return
	Endp
					
	End



Bob Hablutzel	Wildwood Software	BOB@NUACC.ACNS.NWU.EDU

alan@Apple.COM (Alan Mimms) (02/22/89)

In article <7326@june.cs.washington.edu> marty@june.cs.washington.edu (Marty Sirkin) writes:
>name and directory ref number.  I really need the pathname, not the number
>as I need to use the staandard pascal reset/rewrite...

You can create a textual pathname given a directory ref num easily.
The idea is to climb up via the parent directory ID from the directory
you've been given, prepending the name of each directory as you go to
the results of the previous iterations.

Just use the PBGetCatInfo trap with ioFDirIndex set to -1 and ioDrDirID
set to zero.  After each trap, set the ioDrDirID to the ioDrParID
returned by the just-completed call.  The ioNamePtr should point to a
buffer, in which the portion of the pathname pertaining to the current
folder is returned.  You can catenate these together
(first-in-last-out) to build a complete pathname.  Stop the iteration
when you get a dirID of 2, which is the root directory (always).

Hope this helps.
-- 
Alan Mimms			My opinions are generally
Communications Products Group	pretty worthless, but
Apple Computer			they *are* my own...
...it's so simple that only a child can do it!  -- Tom Lehrer, "New Math"

CXT105@PSUVM.BITNET (Christopher Tate) (02/22/89)

In article <7326@june.cs.washington.edu>, marty@june.cs.washington.edu (Marty Sirkin) says:

>I am currently using (in LSP 2.0) SFGetFile to select an input file (with a
>custom dialog box and dialogHook procedure).  It works just great.  My
>problem is that when a file is selected, the reply record returns a file
>name and directory ref number.  I really need the pathname, not the number
>as I need to use the staandard pascal reset/rewrite...

What I usually do is call SFGetFile (or SFPutFile, for that matter), then
use SetVol to make that directory the current volume.  Then, writes using the
reset and rewrite default to the correct folder.  If you really need to, you
can use GetVol beforehand to preserve the previous default directory.

-------
Christopher Tate                  |  I hate writing, and I hate statistics,
cxt105@psuvm.psu.edu              |  but most of all I hate writing about
...!psuvax1!psuvm.bitnet!cxt105   |  statistics.  I'd rather go to the
cxt105@psuvm.bitnet               |  dentist; at least there you get to spit.