Added AROS port of all shell applications:
[cake.git] / rom / dos / openfromlock.c
blob2260b56b52de977bca97b6334fef1776c23d717d
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Open a file from a lock
6 Lang: english
7 */
8 #include <proto/exec.h>
9 #include <dos/dosextens.h>
10 #include <dos/filesystem.h>
11 #include "dos_intern.h"
13 #define DEBUG 0
14 #include <aros/debug.h>
16 #ifndef SFS_SPECIFIC_MESSAGE
17 #define SFS_SPECIFIC_MESSAGE 0xff00
18 #endif
20 static BPTR SFSOpenFromLock(BPTR lock, struct DosLibrary *DOSBase);
22 /*****************************************************************************
24 NAME */
25 #include <proto/dos.h>
27 AROS_LH1(BPTR, OpenFromLock,
29 /* SYNOPSIS */
30 AROS_LHA(BPTR, lock, D1),
32 /* LOCATION */
33 struct DosLibrary *, DOSBase, 63, Dos)
35 /* FUNCTION
36 Convert a lock into a filehandle. If all went well the lock
37 will be gone. In case of an error it must still be freed.
39 INPUTS
40 lock - Lock to convert.
42 RESULT
43 New filehandle or 0 in case of an error. IoErr() will give
44 additional information in that case.
46 NOTES
48 EXAMPLE
50 BUGS
52 SEE ALSO
54 INTERNALS
55 Since locks and filehandles in AROS are identical this function
56 is just the (useless) identity operator and thus can never fail.
57 It's there for compatibility with Amiga OS.
59 As of 04/17/08:
60 - the above note is not true anymore
61 - the AROS packet implementation and the various DOS packets conversion
62 layers can't handle packet type ACTION_FH_FROM_LOCK which does not
63 exist in AROS as a consequence of the above note
64 - we can continue to hack this way until death
65 - the current OpenFromLock implementation is hacked to handle SFS
66 - by the way, C:Touch does not work on SFS (AROS packets handling bug)
68 *****************************************************************************/
70 AROS_LIBFUNC_INIT
72 BPTR file = NULL, test_lock, old_dir;
73 ULONG mode;
75 if (lock == NULL)
77 SetIoErr(ERROR_INVALID_LOCK);
78 return NULL;
81 /* Try SFS hack first */
82 file = SFSOpenFromLock(lock, DOSBase);
84 /* If SFS hack failed, try more general method that should work for both
85 * device-based and packet-based handlers */
86 if (file == NULL)
88 /* Get lock's mode */
89 test_lock = DupLock(lock);
90 if (test_lock != (BPTR)NULL)
92 mode = SHARED_LOCK;
93 UnLock(test_lock);
95 else
96 mode = EXCLUSIVE_LOCK;
98 /* If necessary, switch to a SHARED_LOCK temporarily so we can open
99 the file */
100 if (mode == EXCLUSIVE_LOCK)
101 ChangeMode(CHANGE_LOCK, lock, SHARED_LOCK);
103 /* Open file and dispose of no longer needed lock */
104 old_dir = CurrentDir(lock);
105 file = Open("", MODE_OLDFILE);
106 CurrentDir(old_dir);
107 if (file != (BPTR)NULL)
108 UnLock(lock);
110 /* Restore old mode */
111 if (mode == EXCLUSIVE_LOCK)
113 if (file != (BPTR)NULL)
114 ChangeMode(CHANGE_FH, file, mode);
115 else
116 ChangeMode(CHANGE_LOCK, lock, mode);
120 return file;
122 AROS_LIBFUNC_EXIT
123 } /* OpenFromLock */
125 static BPTR SFSOpenFromLock(BPTR lock, struct DosLibrary *DOSBase)
127 struct MsgPort *mp;
128 struct IOFileSys iofs;
129 struct DosPacket pkt = {0};
130 struct FileHandle *fh;
131 BPTR file = NULL;
133 struct ASFSHandle
135 void *handle;
136 ULONG flags;
137 struct ASFSDeviceInfo *device;
140 struct ASFSHandle *asfshandle;
142 fh = (struct FileHandle *)BADDR(lock);
144 if (fh->fh_Unit)
146 asfshandle = (struct ASFSHandle *)fh->fh_Unit;
148 mp = CreateMsgPort();
149 if (!mp)
151 SetIoErr(ERROR_NO_FREE_STORE);
152 return NULL;
155 InitIOFS(&iofs, SFS_SPECIFIC_MESSAGE, DOSBase);
157 iofs.IOFS.io_Device = fh->fh_Device;
158 iofs.IOFS.io_Unit = fh->fh_Unit;
160 fh = (struct FileHandle *)AllocDosObject(DOS_FILEHANDLE, NULL);
161 if (!fh)
163 DeleteMsgPort(mp);
164 SetIoErr(ERROR_NO_FREE_STORE);
165 return NULL;
168 fh->fh_Pos = fh->fh_End = (UBYTE *)-1;
170 pkt.dp_Type = ACTION_FH_FROM_LOCK;
171 pkt.dp_Arg1 = (SIPTR)MKBADDR(fh);
172 pkt.dp_Arg2 = (SIPTR)asfshandle->handle;
174 iofs.io_PacketEmulation = &pkt;
176 DosDoIO((struct IORequest *)&iofs);
178 D(bug("OpenFromLock dp_Res1=%d IoErr=%d\n",
179 pkt.dp_Res1, iofs.io_DosError));
180 switch (iofs.io_DosError)
182 case ERROR_ACTION_NOT_KNOWN:
183 case ERROR_NOT_IMPLEMENTED:
184 FreeDosObject(DOS_FILEHANDLE, fh);
185 file = NULL;
186 break;
187 default:
188 if (pkt.dp_Res1)
190 fh->fh_Device = iofs.IOFS.io_Device;
191 fh->fh_Unit = iofs.IOFS.io_Unit;
192 file = MKBADDR(fh);
194 else
196 SetIoErr(iofs.io_DosError);
197 FreeDosObject(DOS_FILEHANDLE, fh);
198 file = NULL;
202 DeleteMsgPort(mp);
205 return file;