2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
5 Desc: Open a file from a lock
8 #include <proto/exec.h>
9 #include <dos/dosextens.h>
10 #include <dos/filesystem.h>
11 #include "dos_intern.h"
14 #include <aros/debug.h>
16 #ifndef SFS_SPECIFIC_MESSAGE
17 #define SFS_SPECIFIC_MESSAGE 0xff00
20 static BPTR
SFSOpenFromLock(BPTR lock
, struct DosLibrary
*DOSBase
);
22 /*****************************************************************************
25 #include <proto/dos.h>
27 AROS_LH1(BPTR
, OpenFromLock
,
30 AROS_LHA(BPTR
, lock
, D1
),
33 struct DosLibrary
*, DOSBase
, 63, Dos
)
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.
40 lock - Lock to convert.
43 New filehandle or 0 in case of an error. IoErr() will give
44 additional information in that case.
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.
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 *****************************************************************************/
72 BPTR file
= NULL
, test_lock
, old_dir
;
77 SetIoErr(ERROR_INVALID_LOCK
);
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 */
89 test_lock
= DupLock(lock
);
90 if (test_lock
!= (BPTR
)NULL
)
96 mode
= EXCLUSIVE_LOCK
;
98 /* If necessary, switch to a SHARED_LOCK temporarily so we can open
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
);
107 if (file
!= (BPTR
)NULL
)
110 /* Restore old mode */
111 if (mode
== EXCLUSIVE_LOCK
)
113 if (file
!= (BPTR
)NULL
)
114 ChangeMode(CHANGE_FH
, file
, mode
);
116 ChangeMode(CHANGE_LOCK
, lock
, mode
);
125 static BPTR
SFSOpenFromLock(BPTR lock
, struct DosLibrary
*DOSBase
)
128 struct IOFileSys iofs
;
129 struct DosPacket pkt
= {0};
130 struct FileHandle
*fh
;
137 struct ASFSDeviceInfo
*device
;
140 struct ASFSHandle
*asfshandle
;
142 fh
= (struct FileHandle
*)BADDR(lock
);
146 asfshandle
= (struct ASFSHandle
*)fh
->fh_Unit
;
148 mp
= CreateMsgPort();
151 SetIoErr(ERROR_NO_FREE_STORE
);
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
);
164 SetIoErr(ERROR_NO_FREE_STORE
);
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
);
190 fh
->fh_Device
= iofs
.IOFS
.io_Device
;
191 fh
->fh_Unit
= iofs
.IOFS
.io_Unit
;
196 SetIoErr(iofs
.io_DosError
);
197 FreeDosObject(DOS_FILEHANDLE
, fh
);