Support rastport clipping rectangle for layerless rastports
[tangerine.git] / rom / dos / getdeviceproc.c
blob1c71d63f9b6b0b2b3c79f577f8ac76f84dae226a
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: GetDeviceProc() - Find the filesystem for a path.
6 Lang: english
7 */
8 #include "dos_intern.h"
9 #include <proto/exec.h>
10 #include <proto/utility.h>
12 /*****************************************************************************
14 NAME */
15 #include <proto/dos.h>
17 AROS_LH2(struct DevProc *, GetDeviceProc,
19 /* SYNOPSIS */
20 AROS_LHA(STRPTR , name, D1),
21 AROS_LHA(struct DevProc *, dp, D2),
23 /* LOCATION */
24 struct DosLibrary *, DOSBase, 107, Dos)
26 /* FUNCTION
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
34 as NULL.
36 INPUTS
37 name - Name of the object to find.
38 dp - Previous result of GetDeviceProc() or NULL.
40 RESULT
41 A pointer to a DevProc structure containing the information
42 required to send a command to a filesystem.
44 NOTES
46 EXAMPLE
48 BUGS
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...
54 SEE ALSO
55 FreeDeviceProc()
57 INTERNALS
59 *****************************************************************************/
61 AROS_LIBFUNC_INIT
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? */
83 if( dp != NULL )
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
88 that case.
90 if( dp->dvp_DevNode )
91 if( dp->dvp_DevNode->dol_Type != DLT_DIRECTORY
92 || (dp->dvp_Flags & DVPF_ASSIGN) == 0 )
94 return NULL;
97 /* We'll start from there. */
99 /* Matches UnlockDosList at end of func */
100 LockDosList(LDF_ALL|LDF_READ);
102 dl = dp->dvp_DevNode;
104 else
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.
124 else
126 /* Copy the volume name */
127 s1 = name;
128 volname = NULL;
130 while(*s1)
132 if(*s1++ == ':')
134 volname = (STRPTR)AllocMem(s1-name, MEMF_ANY);
135 if( volname == NULL )
137 SetIoErr(ERROR_NO_FREE_STORE);
138 return NULL;
140 CopyMem(name, volname, s1 - name -1 );
141 volname[s1-name-1] = '\0';
142 break;
147 /* kprintf("Volume name: %p\n", volname);
148 if (volname)
149 kprintf("volname: %s\n", volname);
151 /* Allocate a DevProc */
152 dp = AllocMem(sizeof(struct DevProc), MEMF_ANY|MEMF_CLEAR);
153 if( dp == NULL )
155 FreeMem(volname, s1-name);
156 SetIoErr(ERROR_NO_FREE_STORE);
157 return NULL;
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);
166 if( dl == NULL )
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);
173 return NULL;
176 else
178 /* We have the lock in cur */
179 /* kprintf("lock in cur\n");
180 */ fh = BADDR(cur);
181 dp->dvp_Port = (struct MsgPort *)fh->fh_Device;
182 dp->dvp_Lock = cur;
183 dp->dvp_Flags = 0;
184 dp->dvp_DevNode = NULL;
185 UnLockDosList(LDF_ALL|LDF_READ);
186 SetIoErr(0);
187 return dp;
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);
198 if( lock )
200 AssignLock(volname, lock);
201 dl = LockDosList(LDF_ALL|LDF_READ);
202 dl = FindDosEntry(dl, volname, LDF_ALL);
203 if( dl == NULL )
205 UnLockDosList(LDF_ALL|LDF_READ);
206 FreeMem(volname, s1-name);
207 FreeMem(dp, sizeof(struct DevProc));
208 SetIoErr(ERROR_DEVICE_NOT_MOUNTED);
209 return NULL;
212 dp->dvp_Port = (struct MsgPort *)dl->dol_Device;
213 dp->dvp_Lock = lock;
214 dp->dvp_Flags = 0;
215 dp->dvp_DevNode = dl;
217 else
219 FreeMem(volname, s1-name);
220 FreeMem(dp, sizeof(struct DevProc));
221 return NULL;
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);
229 if( fh != NULL )
231 dp->dvp_Port = (struct MsgPort *)fh->fh_Device;
232 dp->dvp_Lock = lock;
233 dp->dvp_Flags = DVPF_UNLOCK;
234 dp->dvp_DevNode = dl;
236 else
238 UnLockDosList(LDF_ALL|LDF_READ);
239 FreeMem(dp, sizeof(struct DevProc));
240 FreeMem(volname, s1-name);
241 return NULL;
244 else
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
261 does exist
263 /* kprintf("First time multiple assign\n");
264 */ dp->dvp_Lock = dl->dol_misc.dol_assign.dol_List->al_Lock;
266 else
269 struct AssignList *al = dl->dol_misc.dol_assign.dol_List;
271 /* UBYTE buf[100];
273 kprintf("Do assign list\n");
274 */ /*
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);
281 */ al = al->al_Next;
284 if( al != NULL )
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);
293 */ }
294 else
296 /* We have reached the end of the list - just return NULL */
297 UnLockDosList(LDF_ALL|LDF_READ);
298 SetIoErr(ERROR_NO_MORE_ENTRIES);
300 if (volname)
301 FreeMem(volname, s1-name);
303 FreeMem(dp, sizeof(struct DevProc));
305 return NULL;
310 else
312 /* We have reached the end of the list - just return NULL */
313 UnLockDosList(LDF_ALL|LDF_READ);
314 SetIoErr(ERROR_NO_MORE_ENTRIES);
316 if (volname)
317 FreeMem(volname, s1-name);
320 FreeMem(dp, sizeof(struct DevProc));
322 return NULL;
325 } /* if (first iteration of assignlist) */
327 } /* if (DVPF_ASSIGN flag has been set */
328 else
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 */
336 else
338 dp->dvp_Lock = NULL;
339 dp->dvp_Flags = 0;
343 UnLockDosList(LDF_READ|LDF_ALL);
344 if( volname != NULL )
345 FreeMem(volname,s1-name);
346 SetIoErr(0);
347 return dp;
349 AROS_LIBFUNC_EXIT
350 } /* GetDeviceProc */