2 * packet.handler - Proxy filesystem for DOS packet handlers
4 * Copyright © 2007 The AROS Development Team
6 * This program is free software; you can redistribute it and/or modify it
7 * under the same terms as AROS itself.
14 #if defined(DEBUG) && DEBUG != 0
15 #define fsa_str(cmd) ( \
16 cmd == FSA_OPEN ? "FSA_OPEN" : \
17 cmd == FSA_CLOSE ? "FSA_CLOSE" : \
18 cmd == FSA_READ ? "FSA_READ" : \
19 cmd == FSA_WRITE ? "FSA_WRITE" : \
20 cmd == FSA_SEEK ? "FSA_SEEK" : \
21 cmd == FSA_SET_FILE_SIZE ? "FSA_SET_FILE_SIZE" : \
22 cmd == FSA_WAIT_CHAR ? "FSA_WAIT_CHAR" : \
23 cmd == FSA_FILE_MODE ? "FSA_FILE_MODE" : \
24 cmd == FSA_IS_INTERACTIVE ? "FSA_IS_INTERACTIVE" : \
25 cmd == FSA_SAME_LOCK ? "FSA_SAME_LOCK" : \
26 cmd == FSA_EXAMINE ? "FSA_EXAMINE" : \
27 cmd == FSA_EXAMINE_NEXT ? "FSA_EXAMINE_NEXT" : \
28 cmd == FSA_EXAMINE_ALL ? "FSA_EXAMINE_ALL" : \
29 cmd == FSA_EXAMINE_ALL_END ? "FSA_EXAMINE_ALL_END" : \
30 cmd == FSA_OPEN_FILE ? "FSA_OPEN_FILE" : \
31 cmd == FSA_CREATE_DIR ? "FSA_CREATE_DIR" : \
32 cmd == FSA_CREATE_HARDLINK ? "FSA_CREATE_HARDLINK" : \
33 cmd == FSA_CREATE_SOFTLINK ? "FSA_CREATE_SOFTLINK" : \
34 cmd == FSA_RENAME ? "FSA_RENAME" : \
35 cmd == FSA_READ_SOFTLINK ? "FSA_READ_SOFTLINK" : \
36 cmd == FSA_DELETE_OBJECT ? "FSA_DELETE_OBJECT" : \
37 cmd == FSA_SET_COMMENT ? "FSA_SET_COMMENT" : \
38 cmd == FSA_SET_PROTECT ? "FSA_SET_PROTECT" : \
39 cmd == FSA_SET_OWNER ? "FSA_SET_OWNER" : \
40 cmd == FSA_SET_DATE ? "FSA_SET_DATE" : \
41 cmd == FSA_IS_FILESYSTEM ? "FSA_IS_FILESYSTEM" : \
42 cmd == FSA_MORE_CACHE ? "FSA_MORE_CACHE" : \
43 cmd == FSA_FORMAT ? "FSA_FORMAT" : \
44 cmd == FSA_MOUNT_MODE ? "FSA_MOUNT_MODE" : \
45 cmd == FSA_INHIBIT ? "FSA_INHIBIT" : \
46 cmd == FSA_ADD_NOTIFY ? "FSA_ADD_NOTIFY" : \
47 cmd == FSA_REMOVE_NOTIFY ? "FSA_REMOVE_NOTIFY" : \
48 cmd == FSA_DISK_INFO ? "FSA_DISK_INFO" : \
49 cmd == FSA_CHANGE_SIGNAL ? "FSA_CHANGE_SIGNAL" : \
50 cmd == FSA_LOCK_RECORD ? "FSA_LOCK_RECORD" : \
51 cmd == FSA_UNLOCK_RECORD ? "FSA_UNLOCK_RECORD" : \
52 cmd == FSA_PARENT_DIR ? "FSA_PARENT_DIR" : \
53 cmd == FSA_PARENT_DIR_POST ? "FSA_PARENT_DIR_POST" : \
54 cmd == FSA_CONSOLE_MODE ? "FSA_CONSOLE_MODE" : \
55 cmd == FSA_RELABEL ? "FSA_RELABEL" : \
58 #define act_str(cmd) ( \
59 cmd == ACTION_NIL ? "ACTION_NIL" : \
60 cmd == ACTION_STARTUP ? "ACTION_STARTUP" : \
61 cmd == ACTION_GET_BLOCK ? "ACTION_GET_BLOCK" : \
62 cmd == ACTION_SET_MAP ? "ACTION_SET_MAP" : \
63 cmd == ACTION_DIE ? "ACTION_DIE" : \
64 cmd == ACTION_EVENT ? "ACTION_EVENT" : \
65 cmd == ACTION_CURRENT_VOLUME ? "ACTION_CURRENT_VOLUME" : \
66 cmd == ACTION_LOCATE_OBJECT ? "ACTION_LOCATE_OBJECT" : \
67 cmd == ACTION_RENAME_DISK ? "ACTION_RENAME_DISK" : \
68 cmd == ACTION_FREE_LOCK ? "ACTION_FREE_LOCK" : \
69 cmd == ACTION_DELETE_OBJECT ? "ACTION_DELETE_OBJECT" : \
70 cmd == ACTION_RENAME_OBJECT ? "ACTION_RENAME_OBJECT" : \
71 cmd == ACTION_MORE_CACHE ? "ACTION_MORE_CACHE" : \
72 cmd == ACTION_COPY_DIR ? "ACTION_COPY_DIR" : \
73 cmd == ACTION_WAIT_CHAR ? "ACTION_WAIT_CHAR" : \
74 cmd == ACTION_SET_PROTECT ? "ACTION_SET_PROTECT" : \
75 cmd == ACTION_CREATE_DIR ? "ACTION_CREATE_DIR" : \
76 cmd == ACTION_EXAMINE_OBJECT ? "ACTION_EXAMINE_OBJECT" : \
77 cmd == ACTION_EXAMINE_NEXT ? "ACTION_EXAMINE_NEXT" : \
78 cmd == ACTION_DISK_INFO ? "ACTION_DISK_INFO" : \
79 cmd == ACTION_INFO ? "ACTION_INFO" : \
80 cmd == ACTION_FLUSH ? "ACTION_FLUSH" : \
81 cmd == ACTION_SET_COMMENT ? "ACTION_SET_COMMENT" : \
82 cmd == ACTION_PARENT ? "ACTION_PARENT" : \
83 cmd == ACTION_TIMER ? "ACTION_TIMER" : \
84 cmd == ACTION_INHIBIT ? "ACTION_INHIBIT" : \
85 cmd == ACTION_DISK_TYPE ? "ACTION_DISK_TYPE" : \
86 cmd == ACTION_DISK_CHANGE ? "ACTION_DISK_CHANGE" : \
87 cmd == ACTION_SET_DATE ? "ACTION_SET_DATE" : \
88 cmd == ACTION_SAME_LOCK ? "ACTION_SAME_LOCK" : \
89 cmd == ACTION_WRITE ? "ACTION_WRITE" : \
90 cmd == ACTION_READ ? "ACTION_READ" : \
91 cmd == ACTION_SCREEN_MODE ? "ACTION_SCREEN_MODE" : \
92 cmd == ACTION_CHANGE_SIGNAL ? "ACTION_CHANGE_SIGNAL" : \
93 cmd == ACTION_READ_RETURN ? "ACTION_READ_RETURN" : \
94 cmd == ACTION_WRITE_RETURN ? "ACTION_WRITE_RETURN" : \
95 cmd == ACTION_FINDUPDATE ? "ACTION_FINDUPDATE" : \
96 cmd == ACTION_FINDINPUT ? "ACTION_FINDINPUT" : \
97 cmd == ACTION_FINDOUTPUT ? "ACTION_FINDOUTPUT" : \
98 cmd == ACTION_END ? "ACTION_END" : \
99 cmd == ACTION_SEEK ? "ACTION_SEEK" : \
100 cmd == ACTION_FORMAT ? "ACTION_FORMAT" : \
101 cmd == ACTION_MAKE_LINK ? "ACTION_MAKE_LINK" : \
102 cmd == ACTION_SET_FILE_SIZE ? "ACTION_SET_FILE_SIZE" : \
103 cmd == ACTION_WRITE_PROTECT ? "ACTION_WRITE_PROTECT" : \
104 cmd == ACTION_READ_LINK ? "ACTION_READ_LINK" : \
105 cmd == ACTION_FH_FROM_LOCK ? "ACTION_FH_FROM_LOCK" : \
106 cmd == ACTION_IS_FILESYSTEM ? "ACTION_IS_FILESYSTEM" : \
107 cmd == ACTION_CHANGE_MODE ? "ACTION_CHANGE_MODE" : \
108 cmd == ACTION_COPY_DIR_FH ? "ACTION_COPY_DIR_FH" : \
109 cmd == ACTION_PARENT_FH ? "ACTION_PARENT_FH" : \
110 cmd == ACTION_EXAMINE_ALL ? "ACTION_EXAMINE_ALL" : \
111 cmd == ACTION_EXAMINE_FH ? "ACTION_EXAMINE_FH" : \
112 cmd == ACTION_EXAMINE_ALL_END ? "ACTION_EXAMINE_ALL_END" : \
113 cmd == ACTION_SET_OWNER ? "ACTION_SET_OWNER" : \
114 cmd == ACTION_LOCK_RECORD ? "ACTION_LOCK_RECORD" : \
115 cmd == ACTION_FREE_RECORD ? "ACTION_FREE_RECORD" : \
116 cmd == ACTION_ADD_NOTIFY ? "ACTION_ADD_NOTIFY" : \
117 cmd == ACTION_REMOVE_NOTIFY ? "ACTION_REMOVE_NOTIFY" : \
118 cmd == ACTION_SERIALIZE_DISK ? "ACTION_SERIALIZE_DISK" : \
122 static BSTR
mkbstr(APTR pool
, STRPTR str
) {
126 len
= strlen(str
) & 0xff;
128 buf
= AllocPooled(pool
, len
+ 1);
129 CopyMem(str
, &(buf
[1]), len
);
132 return (BSTR
) MKBADDR(buf
);
135 static STRPTR
mkcstr(APTR pool
, BSTR bstr
) {
136 UBYTE
*str
= BADDR(bstr
);
140 buf
= AllocPooled(pool
, len
+ 1);
141 CopyMem(&(str
[1]), buf
, len
);
147 static struct ph_packet
*packet_alloc(void) {
149 struct ph_packet
*pkt
;
151 pool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
, 1024, 256);
153 SetIoErr(ERROR_NO_FREE_STORE
);
157 pkt
= AllocPooled(pool
, sizeof(struct ph_packet
));
159 pkt
->dp
.dp_Link
= (struct Message
*) pkt
;
160 pkt
->msg
.mn_Node
.ln_Name
= (char *) &(pkt
->dp
);
167 void packet_handle_request(struct IOFileSys
*iofs
, struct PacketBase
*PacketBase
) {
168 struct ph_handle
*handle
= (struct ph_handle
*) iofs
->IOFS
.io_Unit
;
169 struct ph_packet
*pkt
;
170 struct DosPacket
*dp
;
172 D(bug("[packet] got io request %d (%s)\n", iofs
->IOFS
.io_Command
, fsa_str(iofs
->IOFS
.io_Command
)));
174 /* get our data back */
175 handle
= (struct ph_handle
*) iofs
->IOFS
.io_Unit
;
177 /* make a fresh new packet */
178 pkt
= packet_alloc();
181 /* hook the iofs up to the packet so we can find it on return
182 * dp_Arg7 should be unused; DoPkt() doesn't touch it */
183 dp
->dp_Arg7
= (IPTR
) iofs
;
185 /* our reply port will cause packet_reply() to be called when they reply */
186 dp
->dp_Port
= &(handle
->mount
->reply_port
);
188 /* convert the command */
189 switch (iofs
->IOFS
.io_Command
) {
192 D(bug("[packet] OPEN: lock 0x%08x (%s) name '%s' type %s\n",
194 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
195 iofs
->io_Union
.io_OPEN
.io_Filename
,
196 (iofs
->io_Union
.io_OPEN
.io_FileMode
& FMF_LOCK
) ? "EXCLUSIVE" : "SHARED"));
199 * NameFromLock() can call FSA_OPEN with a handle to a file rather
200 * than a directory. That seems like a bug, but it doesn't affect
201 * existing handlers because they naively concat the lock name and
202 * the file name, then look backwards through the full name
203 * looking for '/' and going up the tree based on that.
204 * FATFileSystem instead checks a flag inside the lock structure
205 * to see if the lock is a directory, and fails outright if its
208 * Here we intercept this special case and explicitly request the
209 * current/parent directory. Unfortunately ACTION_PARENT can't
210 * take an lock parameter - it always returns a shared lock. Thats
211 * sufficient for this case but is technically incorrect. The
212 * real solution is for something other than FSA_OPEN to be used
215 if (iofs
->io_Union
.io_OPEN
.io_Filename
[0] == '/' &&
216 iofs
->io_Union
.io_OPEN
.io_Filename
[1] == '\0') {
218 /* if they asked for the parent of the root, give it to them */
219 if (handle
== &(handle
->mount
->root_handle
)) {
220 iofs
->IOFS
.io_Unit
= (struct Unit
*) &(handle
->mount
->root_handle
);
224 dp
->dp_Type
= ACTION_PARENT
;
225 dp
->dp_Arg1
= (IPTR
) (handle
->is_lock
? handle
->actual
: NULL
);
229 dp
->dp_Type
= ACTION_LOCATE_OBJECT
;
230 dp
->dp_Arg1
= (IPTR
) (handle
->is_lock
? handle
->actual
: NULL
);
231 dp
->dp_Arg2
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_OPEN
.io_Filename
);
232 dp
->dp_Arg3
= (iofs
->io_Union
.io_OPEN
.io_FileMode
& FMF_LOCK
) ? EXCLUSIVE_LOCK
: SHARED_LOCK
;
237 case FSA_OPEN_FILE
: {
238 ULONG mode
= iofs
->io_Union
.io_OPEN_FILE
.io_FileMode
;
239 struct FileHandle
*fh
;
241 D(bug("[packet] OPEN_FILE: lock 0x%08x (%s) name '%s' mode 0x%x prot 0x%x\n",
243 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
244 iofs
->io_Union
.io_OPEN_FILE
.io_Filename
,
246 iofs
->io_Union
.io_OPEN_FILE
.io_Protection
));
248 /* convert modes to the proper packet type */
249 if (mode
== FMF_MODE_OLDFILE
|| mode
== FMF_READ
)
250 dp
->dp_Type
= ACTION_FINDINPUT
;
251 else if (mode
== FMF_MODE_READWRITE
)
252 dp
->dp_Type
= ACTION_FINDUPDATE
;
253 else if (mode
== FMF_MODE_NEWFILE
)
254 dp
->dp_Type
= ACTION_FINDOUTPUT
;
256 /* XXX do we need to handle other combinations? */
257 iofs
->io_DosError
= ERROR_BAD_NUMBER
;
261 /* make a new filehandle */
262 fh
= (struct FileHandle
*) AllocMem(sizeof(struct FileHandle
), MEMF_PUBLIC
| MEMF_CLEAR
);
264 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
268 /* dos.lib buffer stuff, must be initialised this way */
269 fh
->fh_Pos
= fh
->fh_End
= (UBYTE
*) -1;
271 dp
->dp_Arg1
= (IPTR
) MKBADDR(fh
);
272 dp
->dp_Arg2
= (IPTR
) (handle
->is_lock
? handle
->actual
: NULL
);
273 dp
->dp_Arg3
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_OPEN
.io_Filename
);
279 D(bug("[packet] CLOSE: lock 0x%08x (%s)\n",
281 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle")));
283 /* if this is the root handle, then we previously intercepted a
284 * call and returned it (eg FSA_OPEN/ACTION_PARENT), so we don't
285 * want the handler to do anything */
286 if (handle
== &(handle
->mount
->root_handle
)) {
287 iofs
->IOFS
.io_Unit
= NULL
;
291 dp
->dp_Type
= (handle
->is_lock
) ? ACTION_FREE_LOCK
: ACTION_END
;
292 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
296 D(bug("[packet] READ: handle 0x%08x buf 0x%08x len %ld\n",
298 iofs
->io_Union
.io_READ
.io_Buffer
,
299 iofs
->io_Union
.io_READ
.io_Length
));
301 dp
->dp_Type
= ACTION_READ
;
302 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
303 dp
->dp_Arg2
= (IPTR
) iofs
->io_Union
.io_READ
.io_Buffer
;
304 dp
->dp_Arg3
= (IPTR
) iofs
->io_Union
.io_READ
.io_Length
;
306 /* DOSFALSE == 0, so we can't distinguish between a zero-length
307 * read an actual error. So, we reset the length here. If the
308 * returned packet is DOSFALSE, but no error, this will make sure
309 * DOS gets the right length back */
310 iofs
->io_Union
.io_READ
.io_Length
= 0;
314 D(bug("[packet] WRITE: handle 0x%08x buf 0x%08x len %ld\n",
316 iofs
->io_Union
.io_WRITE
.io_Buffer
,
317 iofs
->io_Union
.io_WRITE
.io_Length
));
319 dp
->dp_Type
= ACTION_WRITE
;
320 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
321 dp
->dp_Arg2
= (IPTR
) iofs
->io_Union
.io_WRITE
.io_Buffer
;
322 dp
->dp_Arg3
= (IPTR
) iofs
->io_Union
.io_WRITE
.io_Length
;
324 iofs
->io_Union
.io_WRITE
.io_Length
= 0;
328 #if defined(DEBUG) && DEBUG != 0
330 ULONG mode
= iofs
->io_Union
.io_SEEK
.io_SeekMode
;
332 bug("[packet] SEEK: handle 0x%08x offset %ld mode %ld (%s)\n",
334 (LONG
) iofs
->io_Union
.io_SEEK
.io_Offset
,
336 mode
== OFFSET_BEGINNING
? "OFFSET_BEGINNING" :
337 mode
== OFFSET_CURRENT
? "OFFSET_CURRENT" :
338 mode
== OFFSET_END
? "OFFSET_END" :
343 dp
->dp_Type
= ACTION_SEEK
;
344 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
345 dp
->dp_Arg2
= (IPTR
) iofs
->io_Union
.io_SEEK
.io_Offset
;
346 dp
->dp_Arg3
= (IPTR
) iofs
->io_Union
.io_SEEK
.io_SeekMode
;
349 case FSA_SET_FILE_SIZE
:
350 #if defined(DEBUG) && DEBUG != 0
352 ULONG mode
= iofs
->io_Union
.io_SET_FILE_SIZE
.io_SeekMode
;
354 bug("[packet] SET_FILE_SIZE: handle 0x%08x offset %ld mode %ld (%s)\n",
356 (LONG
) iofs
->io_Union
.io_SET_FILE_SIZE
.io_Offset
,
358 mode
== OFFSET_BEGINNING
? "OFFSET_BEGINNING" :
359 mode
== OFFSET_CURRENT
? "OFFSET_CURRENT" :
360 mode
== OFFSET_END
? "OFFSET_END" :
365 dp
->dp_Type
= ACTION_SET_FILE_SIZE
;
366 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
367 dp
->dp_Arg2
= (IPTR
) iofs
->io_Union
.io_SET_FILE_SIZE
.io_Offset
;
368 dp
->dp_Arg3
= (IPTR
) iofs
->io_Union
.io_SET_FILE_SIZE
.io_SeekMode
;
371 case FSA_FILE_MODE
: /* XXX untested */
372 D(bug("[packet] FILE_MODE: lock 0x%08x (%s) mode 0x%x\b\n",
374 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
375 iofs
->io_Union
.io_FILE_MODE
.io_FileMode
));
377 dp
->dp_Type
= ACTION_CHANGE_MODE
;
379 if (handle
->is_lock
) {
380 dp
->dp_Arg1
= CHANGE_LOCK
;
381 dp
->dp_Arg3
= (IPTR
) iofs
->io_Union
.io_FILE_MODE
.io_FileMode
;
384 dp
->dp_Arg1
= CHANGE_FH
;
385 dp
->dp_Arg3
= iofs
->io_Union
.io_FILE_MODE
.io_FileMode
& FMF_LOCK
? EXCLUSIVE_LOCK
: SHARED_LOCK
;
390 case FSA_IS_INTERACTIVE
:
391 /* XXX is there some other way to query this? how does (eg) aos
392 * console handler do it? */
393 iofs
->io_Union
.io_IS_INTERACTIVE
.io_IsInteractive
= FALSE
;
394 iofs
->io_DosError
= 0;
397 case FSA_SAME_LOCK
: {
398 struct ph_handle
*h1
, *h2
;
399 h1
= (struct ph_handle
*) iofs
->io_Union
.io_SAME_LOCK
.io_Lock
[0];
400 h2
= (struct ph_handle
*) iofs
->io_Union
.io_SAME_LOCK
.io_Lock
[1];
402 D(bug("[packet] SAME_LOCK: lock1 0x%08x (%s) lock2 0x%08x (%s)\n",
404 h1
== &(h1
->mount
->root_handle
) ? "root" : (h1
->is_lock
? "lock" : "handle"),
406 h2
== &(h2
->mount
->root_handle
) ? "root" : (h2
->is_lock
? "lock" : "handle")));
408 dp
->dp_Type
= ACTION_SAME_LOCK
;
409 dp
->dp_Arg1
= (IPTR
) h1
->actual
;
410 dp
->dp_Arg2
= (IPTR
) h2
->actual
;
415 struct FileInfoBlock
*fib
;
417 D(bug("[packet] EXAMINE: lock 0x%08x (%s)\n",
419 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle")));
421 fib
= (struct FileInfoBlock
*) AllocMem(sizeof(struct FileInfoBlock
), MEMF_PUBLIC
| MEMF_CLEAR
);
423 dp
->dp_Type
= (handle
->is_lock
) ? ACTION_EXAMINE_OBJECT
: ACTION_EXAMINE_FH
;
424 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
425 dp
->dp_Arg2
= (IPTR
) MKBADDR(fib
);
429 case FSA_EXAMINE_NEXT
:
430 D(bug("[packet] EXAMINE_NEXT: lock 0x%08x (%s) fib 0x%08x\n",
432 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
433 iofs
->io_Union
.io_EXAMINE_NEXT
.io_fib
));
435 dp
->dp_Type
= ACTION_EXAMINE_NEXT
;
436 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
437 dp
->dp_Arg2
= (IPTR
) MKBADDR(iofs
->io_Union
.io_EXAMINE_NEXT
.io_fib
);
441 D(bug("[packet] CREATE_DIR: lock 0x%08x (%s) name '%s'\n",
443 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
444 iofs
->io_Union
.io_CREATE_DIR
.io_Filename
));
446 dp
->dp_Type
= ACTION_CREATE_DIR
;
447 dp
->dp_Arg1
= (IPTR
) (handle
->is_lock
? handle
->actual
: NULL
);
448 dp
->dp_Arg2
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_CREATE_DIR
.io_Filename
);
451 case FSA_IS_FILESYSTEM
:
452 dp
->dp_Type
= ACTION_IS_FILESYSTEM
;
456 dp
->dp_Type
= ACTION_DISK_INFO
;
457 dp
->dp_Arg1
= (IPTR
) MKBADDR(iofs
->io_Union
.io_INFO
.io_Info
);
460 case FSA_CREATE_HARDLINK
: /* XXX untested */
461 D(bug("[packet] CREATE_HARDLINK: lock 0x%08x (%s) name '%s' target '%s'\n",
463 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
464 iofs
->io_Union
.io_CREATE_HARDLINK
.io_Filename
,
465 iofs
->io_Union
.io_CREATE_HARDLINK
.io_OldFile
));
467 dp
->dp_Type
= ACTION_MAKE_LINK
;
468 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
469 dp
->dp_Arg2
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_CREATE_HARDLINK
.io_Filename
);
470 dp
->dp_Arg3
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_CREATE_HARDLINK
.io_OldFile
);
471 dp
->dp_Arg4
= LINK_HARD
;
474 case FSA_CREATE_SOFTLINK
: /* XXX untested */
475 D(bug("[packet] CREATE_SOFTLINK: lock 0x%08x (%s) name '%s' target '%s'\n",
477 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
478 iofs
->io_Union
.io_CREATE_SOFTLINK
.io_Filename
,
479 iofs
->io_Union
.io_CREATE_SOFTLINK
.io_Reference
));
481 dp
->dp_Type
= ACTION_MAKE_LINK
;
482 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
483 dp
->dp_Arg2
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_CREATE_SOFTLINK
.io_Filename
);
484 dp
->dp_Arg3
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_CREATE_SOFTLINK
.io_Reference
);
485 dp
->dp_Arg4
= LINK_SOFT
;
489 D(bug("[packet] RENAME: lock 0x%08x (%s) name '%s' target '%s'\n",
491 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
492 iofs
->io_Union
.io_RENAME
.io_Filename
,
493 iofs
->io_Union
.io_RENAME
.io_NewName
));
495 /* XXX the two paths from FSA_RENAME are copied directly from the
496 * arguments to rename with no changes, so they may contain volume
497 * specifiers, path seperators, etc. both can be calculated
498 * relative to the handle. here we just pass them through to the
499 * handler as-is, but I'm not sure if thats right. fat.handler at
500 * least will do the right thing. this probably needs to be
501 * revisited if another packet-based handler is ported */
503 dp
->dp_Type
= ACTION_RENAME_OBJECT
;
504 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
505 dp
->dp_Arg2
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_RENAME
.io_Filename
);
506 dp
->dp_Arg3
= (IPTR
) handle
->actual
;
507 dp
->dp_Arg4
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_RENAME
.io_NewName
);
510 case FSA_READ_SOFTLINK
: /* XXX untested */
511 D(bug("[packet] READ_SOFTLINK: lock 0x%08x (%s)\n",
513 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle")));
515 dp
->dp_Type
= ACTION_READ_LINK
;
516 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
517 dp
->dp_Arg2
= 0; /* XXX we don't have this (path that caused ERROR_IS_SOFT_LINK) */
518 dp
->dp_Arg3
= (IPTR
) iofs
->io_Union
.io_READ_SOFTLINK
.io_Buffer
;
519 dp
->dp_Arg4
= (IPTR
) iofs
->io_Union
.io_READ_SOFTLINK
.io_Size
;
522 case FSA_DELETE_OBJECT
:
523 D(bug("[packet] DELETE: lock 0x%08x (%s) name '%s'\n",
525 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
526 iofs
->io_Union
.io_DELETE_OBJECT
.io_Filename
));
528 dp
->dp_Type
= ACTION_DELETE_OBJECT
;
529 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
530 dp
->dp_Arg2
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_DELETE_OBJECT
.io_Filename
);
533 case FSA_SET_COMMENT
: /* XXX untested */
534 D(bug("[packet] SET_COMMENT: lock 0x%08x (%s) name '%s' comment '%s'\n",
536 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
537 iofs
->io_Union
.io_SET_COMMENT
.io_Filename
,
538 iofs
->io_Union
.io_SET_COMMENT
.io_Comment
));
540 dp
->dp_Type
= ACTION_SET_COMMENT
;
542 dp
->dp_Arg2
= (IPTR
) handle
->actual
;
543 dp
->dp_Arg3
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_SET_COMMENT
.io_Filename
);
544 dp
->dp_Arg4
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_SET_COMMENT
.io_Comment
);
547 case FSA_SET_PROTECT
:
548 D(bug("[packet] SET_PROTECT: lock 0x%08x (%s) name '%s' attrs 0x%x\n",
550 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
551 iofs
->io_Union
.io_SET_PROTECT
.io_Filename
,
552 iofs
->io_Union
.io_SET_PROTECT
.io_Protection
));
554 dp
->dp_Type
= ACTION_SET_PROTECT
;
556 dp
->dp_Arg2
= (IPTR
) handle
->actual
;
557 dp
->dp_Arg3
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_SET_PROTECT
.io_Filename
);
558 dp
->dp_Arg4
= (IPTR
) iofs
->io_Union
.io_SET_PROTECT
.io_Protection
;
561 case FSA_SET_OWNER
: /* XXX untested */
562 D(bug("[packet] SET_OWNER: lock 0x%08x (%s) name '%s' uid 0x%x gid 0x%x\n",
564 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
565 iofs
->io_Union
.io_SET_OWNER
.io_Filename
,
566 iofs
->io_Union
.io_SET_OWNER
.io_UID
,
567 iofs
->io_Union
.io_SET_OWNER
.io_GID
));
569 dp
->dp_Type
= ACTION_SET_OWNER
;
571 dp
->dp_Arg2
= (IPTR
) handle
->actual
;
572 dp
->dp_Arg3
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_SET_OWNER
.io_Filename
);
573 dp
->dp_Arg4
= (IPTR
) iofs
->io_Union
.io_SET_OWNER
.io_GID
<< 16 |
574 iofs
->io_Union
.io_SET_OWNER
.io_UID
;
577 case FSA_SET_DATE
: /* XXX untested */
578 #if defined(DEBUG) && DEBUG != 0
581 char datestr
[LEN_DATSTRING
];
583 dt
.dat_Stamp
= iofs
->io_Union
.io_SET_DATE
.io_Date
;
584 dt
.dat_Format
= FORMAT_DOS
;
586 dt
.dat_StrDay
= NULL
;
587 dt
.dat_StrDate
= datestr
;
588 dt
.dat_StrTime
= NULL
;
591 bug("[packet] SET_DATE: lock 0x%08x (%s) name '%s' date '%s'\n",
593 handle
== &(handle
->mount
->root_handle
) ? "root" : (handle
->is_lock
? "lock" : "handle"),
594 iofs
->io_Union
.io_SET_DATE
.io_Filename
,
599 dp
->dp_Type
= ACTION_SET_DATE
;
601 dp
->dp_Arg2
= (IPTR
) handle
->actual
;
602 dp
->dp_Arg3
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_SET_DATE
.io_Filename
);
603 dp
->dp_Arg4
= (IPTR
) &iofs
->io_Union
.io_SET_DATE
.io_Date
;
606 case FSA_MORE_CACHE
: /* XXX untested */
607 D(bug("[packet] MORE_CACHE: buffers '0x%x'\n", iofs
->io_Union
.io_MORE_CACHE
.io_NumBuffers
));
609 dp
->dp_Type
= ACTION_MORE_CACHE
;
610 dp
->dp_Arg1
= (IPTR
) iofs
->io_Union
.io_MORE_CACHE
.io_NumBuffers
;
613 case FSA_FORMAT
: /* XXX untested */
614 D(bug("[packet] FSA_FORMAT: name '%s' type 0x%x\n",
615 iofs
->io_Union
.io_FORMAT
.io_VolumeName
,
616 iofs
->io_Union
.io_FORMAT
.io_DosType
));
618 dp
->dp_Type
= ACTION_FORMAT
;
619 dp
->dp_Arg1
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_FORMAT
.io_VolumeName
);
620 dp
->dp_Arg2
= (IPTR
) iofs
->io_Union
.io_FORMAT
.io_DosType
;
623 case FSA_INHIBIT
: /* XXX untested */
624 D(bug("[packet] FSA_INHIBIT: %sinhibit\n", iofs
->io_Union
.io_INHIBIT
.io_Inhibit
== 0 ? "un" : ""));
626 dp
->dp_Type
= ACTION_INHIBIT
;
627 dp
->dp_Arg1
= (IPTR
) iofs
->io_Union
.io_INHIBIT
.io_Inhibit
;
631 D(bug("[packet] FSA_RELABEL: name '%s'\n", iofs
->io_Union
.io_RELABEL
.io_NewName
));
633 dp
->dp_Type
= ACTION_RENAME_DISK
;
634 dp
->dp_Arg1
= (IPTR
) mkbstr(pkt
->pool
, iofs
->io_Union
.io_RELABEL
.io_NewName
);
637 case FSA_LOCK_RECORD
: /* XXX untested */
638 #if defined(DEBUG) && DEBUG != 0
640 ULONG mode
= iofs
->io_Union
.io_RECORD
.io_RecordMode
;
642 bug("[packet] FSA_LOCK_RECORD: handle 0x%08x offset %ld size %ld mode %d (%s) timeout %d\n",
644 (LONG
) iofs
->io_Union
.io_RECORD
.io_Offset
,
645 iofs
->io_Union
.io_RECORD
.io_Size
,
647 mode
== REC_EXCLUSIVE
? "REC_EXCLUSIVE" :
648 mode
== REC_EXCLUSIVE_IMMED
? "REC_EXCLUSIVE_IMMED" :
649 mode
== REC_SHARED
? "REC_SHARED" :
650 mode
== REC_SHARED_IMMED
? "REC_SHARED_IMMED" :
652 iofs
->io_Union
.io_RECORD
.io_Timeout
);
656 dp
->dp_Type
= ACTION_LOCK_RECORD
;
657 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
658 dp
->dp_Arg2
= (IPTR
) iofs
->io_Union
.io_RECORD
.io_Offset
;
659 dp
->dp_Arg3
= (IPTR
) iofs
->io_Union
.io_RECORD
.io_Size
;
660 dp
->dp_Arg4
= (IPTR
) iofs
->io_Union
.io_RECORD
.io_RecordMode
;
661 dp
->dp_Arg5
= (IPTR
) iofs
->io_Union
.io_RECORD
.io_Timeout
;
664 case FSA_UNLOCK_RECORD
: /* XXX untested */
665 D(bug("[packet] FSA_UNLOCK_RECORD: handle 0x%08x offset %ld size %ld\n",
667 (LONG
) iofs
->io_Union
.io_RECORD
.io_Offset
,
668 iofs
->io_Union
.io_RECORD
.io_Size
));
670 dp
->dp_Type
= ACTION_FREE_RECORD
;
671 dp
->dp_Arg1
= (IPTR
) handle
->actual
;
672 dp
->dp_Arg2
= (IPTR
) iofs
->io_Union
.io_RECORD
.io_Offset
;
673 dp
->dp_Arg3
= (IPTR
) iofs
->io_Union
.io_RECORD
.io_Size
;
677 D(bug("[packet] FSA_ADD_NOTIFY: nr 0x%08x name '%s'\n",
678 iofs
->io_Union
.io_NOTIFY
.io_NotificationRequest
,
679 iofs
->io_Union
.io_NOTIFY
.io_NotificationRequest
->nr_FullName
));
681 dp
->dp_Type
= ACTION_ADD_NOTIFY
;
682 dp
->dp_Arg1
= iofs
->io_Union
.io_NOTIFY
.io_NotificationRequest
;
685 case FSA_REMOVE_NOTIFY
:
686 D(bug("[packet] FSA_REMOVE_NOTIFY: nr 0x%08x name '%s'\n",
687 iofs
->io_Union
.io_NOTIFY
.io_NotificationRequest
,
688 iofs
->io_Union
.io_NOTIFY
.io_NotificationRequest
->nr_FullName
));
690 dp
->dp_Type
= ACTION_REMOVE_NOTIFY
;
691 dp
->dp_Arg1
= iofs
->io_Union
.io_NOTIFY
.io_NotificationRequest
;
695 case FSA_EXAMINE_ALL
:
696 case FSA_EXAMINE_ALL_END
:
698 case FSA_CHANGE_SIGNAL
:
700 case FSA_PARENT_DIR_POST
:
701 case FSA_CONSOLE_MODE
:
702 D(bug("[packet] command not implemented\n"));
703 iofs
->io_DosError
= ERROR_NOT_IMPLEMENTED
;
707 D(bug("[packet] unknown command\n"));
708 iofs
->io_DosError
= ERROR_ACTION_NOT_KNOWN
;
712 D(bug("[packet] converted to %s packet\n", act_str(dp
->dp_Type
)));
714 /* WaitIO() will look into this */
715 iofs
->IOFS
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
717 /* since these all go to the packet handler process, they can't be done now */
718 iofs
->IOFS
.io_Flags
&= ~IOF_QUICK
;
720 /* send the packet */
721 PutMsg(&(handle
->mount
->process
->pr_MsgPort
), dp
->dp_Link
);
725 /* jump here to reply to the packet now, handling IOF_QUICK appropriately */
727 D(bug("[packet] replying directly with error %d\n", iofs
->io_DosError
));
729 /* kill the packet */
730 DeletePool(pkt
->pool
);
732 /* if they can handle quick replies, just bail out */
733 if (iofs
->IOFS
.io_Flags
& IOF_QUICK
)
736 /* otherwise tell them properly */
737 ReplyMsg((APTR
) iofs
);
740 AROS_UFH3(void, packet_reply
,
741 AROS_UFHA(struct ph_mount
*, mount
, A1
),
742 AROS_UFHA(APTR
, dummy
, A5
),
743 AROS_UFHA(struct ExecBase
*, SysBase
, A6
)) {
747 struct DosPacket
*dp
;
748 struct ph_packet
*pkt
;
749 struct IOFileSys
*iofs
;
750 struct ph_handle
*handle
;
752 /* retrieve the message and fish the packet out */
753 dp
= (struct DosPacket
*) GetMsg(&(mount
->reply_port
))->mn_Node
.ln_Name
;
754 pkt
= (struct ph_packet
*) dp
->dp_Link
;
756 D(bug("[packet] got reply packet %d (%s)\n", dp
->dp_Type
, act_str(dp
->dp_Type
)));
758 /* get the iofs back */
759 iofs
= (struct IOFileSys
*) dp
->dp_Arg7
;
761 /* dos error code comes back in Res2 */
762 if (dp
->dp_Res1
== DOSFALSE
) {
763 iofs
->io_DosError
= dp
->dp_Res2
;
765 /* do any cleanup from the request (eg freeing memory) */
766 switch (dp
->dp_Type
) {
767 case ACTION_FINDINPUT
:
768 case ACTION_FINDOUTPUT
:
769 case ACTION_FINDUPDATE
:
770 FreeMem((APTR
) BADDR(dp
->dp_Arg1
), sizeof(struct FileHandle
));
773 case ACTION_SAME_LOCK
:
774 /* DOSFALSE & no error means the locks are different */
775 if (iofs
->io_DosError
== 0)
776 iofs
->io_Union
.io_SAME_LOCK
.io_Same
= LOCK_DIFFERENT
;
780 /* no error means they tried to go up past the root. The
781 * packet system allows this, IOFS does not */
782 if (iofs
->io_DosError
== 0)
783 iofs
->io_DosError
= ERROR_OBJECT_NOT_FOUND
;
787 /* kill the packet */
788 DeletePool(pkt
->pool
);
790 D(bug("[packet] returning error %ld\n", iofs
->io_DosError
));
793 ReplyMsg((APTR
) iofs
);
799 iofs
->io_DosError
= 0;
801 /* populate the iofs with the results. note that for packets that only
802 * return success/failure we have nothing to do, so they're not listed here */
803 switch (dp
->dp_Type
) {
805 case ACTION_LOCATE_OBJECT
:
807 handle
= (struct ph_handle
*) AllocMem(sizeof(struct ph_handle
), MEMF_PUBLIC
| MEMF_CLEAR
);
808 if (handle
== NULL
) {
809 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
813 /* we'll need the lock they gave us for future operations */
814 handle
->actual
= (void *) dp
->dp_Res1
;
815 handle
->is_lock
= TRUE
;
816 handle
->mount
= mount
;
818 iofs
->IOFS
.io_Unit
= (struct Unit
*) handle
;
822 case ACTION_FINDINPUT
:
823 case ACTION_FINDOUTPUT
:
824 case ACTION_FINDUPDATE
: {
825 struct FileHandle
*fh
= (struct FileHandle
*) BADDR(dp
->dp_Arg1
);
827 handle
= (struct ph_handle
*) AllocMem(sizeof(struct ph_handle
), MEMF_PUBLIC
| MEMF_CLEAR
);
828 if (handle
== NULL
) {
829 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
830 FreeMem((APTR
) fh
, sizeof(struct FileHandle
));
834 /* handlers return "internal data" (typically a lock, though we
835 * can't assume that) in fh_Arg1. we need to keep it for later
836 * filehandle operations. the filehandle itself is expendable -
837 * the calls that need this data (eg ACTION_READ/WRITE/SEEK) take
838 * it directly in dp_Arg1 */
839 handle
->actual
= (void *) fh
->fh_Arg1
;
840 handle
->is_lock
= FALSE
;
841 handle
->mount
= mount
;
843 iofs
->IOFS
.io_Unit
= (struct Unit
*) handle
;
845 FreeMem((APTR
) fh
, sizeof(struct FileHandle
));
850 case ACTION_FREE_LOCK
:
852 /* free up our data */
853 handle
= (struct ph_handle
*) iofs
->IOFS
.io_Unit
;
854 FreeMem((APTR
) handle
, sizeof(struct ph_handle
));
855 iofs
->IOFS
.io_Unit
= NULL
;
859 iofs
->io_Union
.io_READ
.io_Length
= dp
->dp_Res1
;
863 iofs
->io_Union
.io_WRITE
.io_Length
= dp
->dp_Res1
;
867 iofs
->io_Union
.io_SEEK
.io_Offset
= dp
->dp_Res1
;
870 case ACTION_SAME_LOCK
:
871 iofs
->io_Union
.io_SAME_LOCK
.io_Same
= LOCK_SAME
;
874 case ACTION_EXAMINE_OBJECT
:
875 case ACTION_EXAMINE_FH
: {
876 struct FileInfoBlock
*fib
= (struct FileInfoBlock
*) BADDR(dp
->dp_Arg2
);
877 struct ExAllData
*ead
= iofs
->io_Union
.io_EXAMINE
.io_ead
;
878 ULONG size
= iofs
->io_Union
.io_EXAMINE
.io_Size
;
879 ULONG mode
= iofs
->io_Union
.io_EXAMINE
.io_Mode
;
880 ULONG comment_len
= 0, filename_len
= 0;
882 iofs
->io_DirPos
= fib
->fib_DiskKey
;
884 /* make sure we have enough room for everything that came back */
885 if (size
< sizeof(struct ExAllData
) +
886 (mode
>= ED_COMMENT
? (comment_len
= strlen(fib
->fib_Comment
)) : 0) +
887 (mode
>= ED_NAME
? (filename_len
= strlen(fib
->fib_FileName
)) : 0)) {
888 iofs
->io_DosError
= ERROR_BUFFER_OVERFLOW
;
889 FreeMem(fib
, sizeof(struct FileInfoBlock
));
893 /* copy stuff from the fib to the ead */
896 ead
->ed_OwnerUID
= fib
->fib_OwnerUID
;
897 ead
->ed_OwnerGID
= fib
->fib_OwnerGID
;
900 /* store the comment in the spare space after the ead and
902 ead
->ed_Comment
= (UBYTE
*) ead
+ sizeof(struct ExAllData
) + filename_len
+ 1;
903 strcpy(ead
->ed_Comment
, fib
->fib_Comment
);
906 ead
->ed_Days
= fib
->fib_Date
.ds_Days
;
907 ead
->ed_Mins
= fib
->fib_Date
.ds_Minute
;
908 ead
->ed_Ticks
= fib
->fib_Date
.ds_Tick
;
911 ead
->ed_Prot
= fib
->fib_Protection
;
914 ead
->ed_Size
= fib
->fib_Size
;
917 ead
->ed_Type
= fib
->fib_EntryType
;
920 /* store the name in the spare space after the ead */
921 ead
->ed_Name
= (UBYTE
*) ead
+ sizeof(struct ExAllData
);
922 strcpy(ead
->ed_Name
, fib
->fib_FileName
);
929 iofs
->io_DosError
= ERROR_BAD_NUMBER
;
933 FreeMem(fib
, sizeof(struct FileInfoBlock
));
938 case ACTION_IS_FILESYSTEM
:
939 iofs
->io_Union
.io_IS_FILESYSTEM
.io_IsFilesystem
= TRUE
;
942 case ACTION_CREATE_DIR
:
943 handle
= (struct ph_handle
*) AllocMem(sizeof(struct ph_handle
), MEMF_PUBLIC
| MEMF_CLEAR
);
944 if (handle
== NULL
) {
945 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
949 /* we'll need the lock they gave us for future operations */
950 handle
->actual
= (void *) dp
->dp_Res1
;
951 handle
->is_lock
= TRUE
;
952 handle
->mount
= mount
;
954 iofs
->IOFS
.io_Unit
= (struct Unit
*) handle
;
958 case ACTION_READ_LINK
:
959 iofs
->io_Union
.io_READ_SOFTLINK
.io_Size
= dp
->dp_Res1
;
962 case ACTION_MORE_CACHE
:
963 iofs
->io_Union
.io_MORE_CACHE
.io_NumBuffers
= dp
->dp_Res1
;
966 /* done with the packet */
967 DeletePool(pkt
->pool
);
970 ReplyMsg((APTR
) iofs
);