2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: GetDeviceProc() - Find the filesystem for a path.
8 #include "dos_intern.h"
9 #include <proto/exec.h>
10 #include <proto/utility.h>
12 /*****************************************************************************
15 #include <proto/dos.h>
17 AROS_LH2(struct DevProc
*, GetDeviceProc
,
20 AROS_LHA(STRPTR
, name
, D1
),
21 AROS_LHA(struct DevProc
*, dp
, D2
),
24 struct DosLibrary
*, DOSBase
, 107, Dos
)
27 GetDeviceProc() will search for the filesystem handler which
28 you should send a command to for a specific path.
30 By calling GetDeviceProc() multiple times, the caller will
31 be able to handle multi-assign paths.
33 The first call to GetDeviceProc() should have the |dp| parameter
37 name - Name of the object to find.
38 dp - Previous result of GetDeviceProc() or NULL.
41 A pointer to a DevProc structure containing the information
42 required to send a command to a filesystem.
49 Currently doesn't return dvp_DevNode for locks which are
50 relative to "PROGDIR:", ":", or the current directory.
52 I'm working on it though...
59 *****************************************************************************/
62 AROS_LIBBASE_EXT_DECL(struct DosLibrary
*,DOSBase
)
64 struct Process
*pr
= (struct Process
*)FindTask(NULL
);
65 struct DosList
*dl
= NULL
;
66 struct FileHandle
*fh
;
67 STRPTR volname
= NULL
, s1
= NULL
;
68 BPTR cur
= NULL
, lock
= (BPTR
)0;
71 Note: We can free the DevProc structure anywhere an error occurs
72 because for all cases except DLT_DIRECTORY types, we will have
73 not returned a DevProc before, therefore the caller will have
74 nothing to call FreeDeviceProc() on.
76 There are no errors of this type for DLT_DIRECTORY, so we can
77 just handle this as needed. However if there was an error, we
78 would simply check the dp->dvp_Flags & DVPF_ASSIGN to see if
79 we had returned the structure to the caller.
82 /* Have we already got a DevProc? */
86 Yes, if this is not a multi-assign directory, then there
87 is no reason for us to bother again. Just return NULL in
91 if( dp
->dvp_DevNode
->dol_Type
!= DLT_DIRECTORY
92 || (dp
->dvp_Flags
& DVPF_ASSIGN
) == 0 )
97 /* We'll start from there. */
99 /* Matches UnlockDosList at end of func */
100 LockDosList(LDF_ALL
|LDF_READ
);
102 dl
= dp
->dvp_DevNode
;
107 We have to find the starting dl structure
108 What is the volume part of the filesystem?
110 cur
= pr
->pr_CurrentDir
;
112 if(!Strnicmp(name
, "PROGDIR:", 8))
114 /* The path refers to PROGDIR: */
115 cur
= pr
->pr_HomeDir
;
117 else if( *name
== ':' )
120 Relative to the current volume (ie current directory)
121 We simply need to remove this case from the below.
126 /* Copy the volume name */
134 volname
= (STRPTR
)AllocMem(s1
-name
, MEMF_ANY
);
135 if( volname
== NULL
)
137 SetIoErr(ERROR_NO_FREE_STORE
);
140 CopyMem(name
, volname
, s1
- name
-1 );
141 volname
[s1
-name
-1] = '\0';
147 /* kprintf("Volume name: %p\n", volname);
149 kprintf("volname: %s\n", volname);
151 /* Allocate a DevProc */
152 dp
= AllocMem(sizeof(struct DevProc
), MEMF_ANY
|MEMF_CLEAR
);
155 FreeMem(volname
, s1
-name
);
156 SetIoErr(ERROR_NO_FREE_STORE
);
160 /* We now go through the DOS device list */
161 dl
= LockDosList(LDF_ALL
|LDF_READ
);
162 if( volname
!= NULL
)
164 /* Find logical Device */
165 dl
= FindDosEntry(dl
, volname
, LDF_ALL
);
168 /* kprintf("Found logical device\n");
169 */ UnLockDosList(LDF_ALL
|LDF_READ
);
170 FreeMem(volname
, s1
-name
);
171 FreeMem(dp
, sizeof(struct DevProc
));
172 SetIoErr(ERROR_DEVICE_NOT_MOUNTED
);
178 /* We have the lock in cur */
179 /* kprintf("lock in cur\n");
181 dp
->dvp_Port
= (struct MsgPort
*)fh
->fh_Device
;
184 dp
->dvp_DevNode
= NULL
;
185 UnLockDosList(LDF_ALL
|LDF_READ
);
189 } /* we didn't have a DevProc passed into us */
191 /* We now look at the type of the DosList entry */
192 if( dl
->dol_Type
== DLT_LATE
)
194 /* kprintf("Late assign\n");
195 */ UnLockDosList(LDF_ALL
|LDF_READ
);
197 lock
= Lock(dl
->dol_misc
.dol_assign
.dol_AssignName
, SHARED_LOCK
);
200 AssignLock(volname
, lock
);
201 dl
= LockDosList(LDF_ALL
|LDF_READ
);
202 dl
= FindDosEntry(dl
, volname
, LDF_ALL
);
205 UnLockDosList(LDF_ALL
|LDF_READ
);
206 FreeMem(volname
, s1
-name
);
207 FreeMem(dp
, sizeof(struct DevProc
));
208 SetIoErr(ERROR_DEVICE_NOT_MOUNTED
);
212 dp
->dvp_Port
= (struct MsgPort
*)dl
->dol_Device
;
215 dp
->dvp_DevNode
= dl
;
219 FreeMem(volname
, s1
-name
);
220 FreeMem(dp
, sizeof(struct DevProc
));
223 } /* late binding assign */
224 else if(dl
->dol_Type
== DLT_NONBINDING
)
226 /* kprintf("nonbinding assign\n");
227 */ lock
= Lock(dl
->dol_misc
.dol_assign
.dol_AssignName
, SHARED_LOCK
);
228 fh
= (struct FileHandle
*)BADDR(lock
);
231 dp
->dvp_Port
= (struct MsgPort
*)fh
->fh_Device
;
233 dp
->dvp_Flags
= DVPF_UNLOCK
;
234 dp
->dvp_DevNode
= dl
;
238 UnLockDosList(LDF_ALL
|LDF_READ
);
239 FreeMem(dp
, sizeof(struct DevProc
));
240 FreeMem(volname
, s1
-name
);
246 /* kprintf("generic case\n");
247 */ /* Generic case, a volume, a device, or a multi-assign */
248 dp
->dvp_Port
= (struct MsgPort
*)dl
->dol_Device
;
249 dp
->dvp_DevNode
= dl
;
250 if( dl
->dol_Type
== DLT_DIRECTORY
)
252 /* If called before, this will be set */
253 if( dp
->dvp_Flags
== DVPF_ASSIGN
)
255 /* kprintf("DBPF_ASSIGN flag found\n");
256 */ /* First iteration of list ? */
257 if (dp
->dvp_Lock
== dl
->dol_Lock
)
259 /* If so, set to first item in assignlist.
260 (The set DVPF_ASSIGN flag tells that a assignlist
263 /* kprintf("First time multiple assign\n");
264 */ dp
->dvp_Lock
= dl
->dol_misc
.dol_assign
.dol_List
->al_Lock
;
269 struct AssignList
*al
= dl
->dol_misc
.dol_assign
.dol_List
;
273 kprintf("Do assign list\n");
275 Go through until we have found the last one returned.
277 while( al
&& (al
->al_Lock
!= dp
->dvp_Lock
) )
279 /* NameFromLock(al->al_Lock, buf, 100);
280 kprintf("gdp: trying assigndir %s\n", buf);
286 /* kprintf("al != NULL\n");
287 */ if( al
->al_Next
!= NULL
)
289 dp
->dvp_Lock
= al
->al_Next
->al_Lock
;
291 /* NameFromLock(dp->dvp_Lock, buf, 100);
292 kprintf("gdp: returning assigndir %s\n", buf);
296 /* We have reached the end of the list - just return NULL */
297 UnLockDosList(LDF_ALL
|LDF_READ
);
298 SetIoErr(ERROR_NO_MORE_ENTRIES
);
301 FreeMem(volname
, s1
-name
);
303 FreeMem(dp
, sizeof(struct DevProc
));
312 /* We have reached the end of the list - just return NULL */
313 UnLockDosList(LDF_ALL
|LDF_READ
);
314 SetIoErr(ERROR_NO_MORE_ENTRIES
);
317 FreeMem(volname
, s1
-name
);
320 FreeMem(dp
, sizeof(struct DevProc
));
325 } /* if (first iteration of assignlist) */
327 } /* if (DVPF_ASSIGN flag has been set */
329 dp
->dvp_Lock
= dl
->dol_Lock
;
331 /* Only set this again if we have some locks to look at */
332 if( dl
->dol_misc
.dol_assign
.dol_List
!= NULL
)
333 dp
->dvp_Flags
= DVPF_ASSIGN
;
335 } /* DLT_DIRECTORY */
343 UnLockDosList(LDF_READ
|LDF_ALL
);
344 if( volname
!= NULL
)
345 FreeMem(volname
,s1
-name
);
350 } /* GetDeviceProc */