Copyright (c) Hyperion Entertainment and contributors.

AmigaDOS Packets

From AmigaOS Documentation Wiki
Jump to navigation Jump to search

Introduction

Packet passing handles all communication performed by AmigaDOS between processes. The function diagram below shows how packets fit in with the other components of the Amiga operating system.

   +--------------+
   | User Process +-----------------------+
   +-------+------+                       |
           |                              |
           |                              |
    Function Calls                        |
           |                              |
          \|/                             |
 +---------+--------+                     |
 | AmigaDOS Open(), |                     |
 |   Close(), etc.  |                     |
 +---------+--------+                     |
           |                              |
           |                              |
      +-Packets---+--------+     +-----Packets--------+
      |           |        |     |        |           |
     \|/         \|/      \|/   \|/      \|/         \|/
 +----+----+ +----+----+ +-+--+--+-+ +----+----+ +----+----+
 | FFS/OFS | | FFS/OFS | | FFS/OFS | |   CON:  | |   CON:  |
 |   DH0:  | |   DF0:  | |   DF1:  | | Window1 | | Window2 |
 | Handler | | Handler | | Handler | | Handler | | Handler |
 | Process | | Process | | Process | | Process | | Process |
 +----+----+ +-------+-+ +----+----+ +----+----+ +----+----+
      |              |        |           |           |
     \|/            \|/      \|/         \|/         \|/
 +----+--------+  +--+--------+----+ +----+-----------+----+
 |Hddisk.device|  |Trackdisk.device| |    Console.device   |
 +-------------+  +----------------+ +---------------------+

A StandardPacket (defined in <dos/dosextens.h>) is used to send packet commands to a process's MsgPort. The StandardPacket structure contains an Exec Message structure and an AmigaDOS DOSPacket structure:

    struct StandardPacket
    {   struct Message   sp_Msg;
        struct DOSPacket sp_Pkt;
    };

This structure must be longword-aligned, and initialized to link the Message and DOSPacket sections to each other:

    packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
    packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);

Packets must also be initialized with a ReplyPort which is created with AllocSysObject():

    if (replyport = (struct MsgPort *) IExec->AllocSysObjectTags(ASOT_PORT, TAG_END))
        packet->sp_Pkt.dp_Port = replyport;

The DOSPacket portion of the StandardPacket structure is used to pass the packet type and arguments, and to receive the results of the packet. The argument types, number of arguments, and results vary for different packet types and are documented with each packet description. A DOSPacket must be longword-aligned and has the following general structure:

Type Name Description
struct Message* dp_Link Pointer back to Exec message structure
struct Message* dp_Port Reply port for the packet. Must be filled in each send
int32 dp_Type Packet type
int32 dp_Res1 For file system calls this is the result that would have been returned by the function; eg. Write("W") returns actual length written.
int32 dp_Res2 For file system calls this is what would have been returned by IoErr()
int32 dp_Arg1 Argument 1 (depends on packet type)
int32 dp_Arg2 Argument 2 (depends on packet type)
int32 dp_Arg3 Argument 3 (depends on packet type)
int32 dp_Arg4 Argument 4 (depends on packet type)
int32 dp_Arg5 Argument 5 (depends on packet type)
int32 dp_Arg6 Argument 6 (depends on packet type)
int32 dp_Arg7 Argument 7 (depends on packet type)

The format of a specific packet depends on its type; but in all cases it contains a back-pointer to the Message structure, the MsgPort for the reply, and two result fields. When AmigaDOS sends a packet, the reply port is overwritten with the process ID of the sender so that the packet can be returned. Thus, when sending a packet to an AmigaDOS handler process, you must fill in the reply MsgPort each time; otherwise when the packet returns, AmigaDOS has overwritten the original port. AmigaDOS maintains all other fields except the result fields.

All AmigaDOS packets are sent to the message port created as part of a process; this message port is initialized so that arriving messages cause signal bit 8 to be set. An AmigaDOS process that is waiting for a message waits for signal 8 to be set. When the process wakes up because this event has occurred, GetMsg() takes the message from the message port and extracts the packet address. If the process is an AmigaDOS handler process, then the packet contains a value in the PktType field that indicates an action to be performed, such as reading some data. The argument fields contain specific information such as the size of the buffer where the characters go.

When the handler process has completed the work required to satisfy this request, the packet returns to the sender, using the same message structure. Both the message structure and the packet structure must be allocated by the client and not deallocated before the reply has been received. Normally AmigaDOS is called by the client to send the packet, such as when a call to Read() is made. However, there are cases where asynchronous I/O is required, and in this case the client may send packets to the handler process as required. The packet and message structures must be allocated, and the process ID field filled in with the message port where this packet must return. A call to PutMsg() then sends the message to the destination. Note that many packets may be sent out, returning to either the same or different message ports.

Packet Types

Packets sent to a file system or handler can be divided into several basic categories:

Basic Input/Output
These actions deal with transferring data to and from objects controlled by the handler.
File/Directory Manipulation/Information
These actions are used to gain access to and manipulate the high level structures of the file system.
Volume Manipulation/Information
These actions allow access to the specific volume controlled by the file system.
Handler Maintenance and Control
These allow control over the handler/file system itself, independent of the actual volume or structure underneath.
Handler Internal
These actions are never sent to the handler directly. Instead they are generally responses to IO requests made by the handler.
Obsolete Packets
These packets are no longer valid for use by handlers/file systems.
Deprecated Packets
These packets are superceded by new ones with updated functionality and file systems/handlers should avoid implementing these packets at all and let dos.library emulate the old and limited functionality.
Console Only Packets
These packets are specific to console handlers.
File Systems can ignore these packets.

Each packet type documented in this section is listed with its action name, its corresponding number, any AmigaDOS routines that use this packet, and the list of parameters that the packet uses. The C variable types for the packet parameters are one of the following types:

Type Description
BPTR This is BCPL pointer (an address which is right shifted by 2). This means that the object must be aligned on a 32 bit address.
BSTR This is a BCPL pointer to a string where the first byte indicates the number of characters in the string. This length byte is unsigned but because it is stored in only 8 bits, the strings are limited to 255 characters in length before V52 of dos.library.

As of V52+ dos.library, "extended BSTR" (XBSTR) strings can be sent to handlers and file systems from dos.library for extensibility reasons, while still maintaining legacy backward compatibility. These extended BSTR strings are in the same format as a legacy BSTR string but are guaranteed to have a null-terminator byte added to the end, and the length byte of these will be correct only up to 255 characters, past that length, the length byte will always read 255 (0xFF) and is there just for limited legacy compatibility. These extended BSTR strings are always documented and identified by having an additional dospacket identifier parameter supplied, consult the individual DOS packet documentation for details.

See also ACTION_INHIBIT_DOS_LONGPATH_HANDLING for details on this DOS packet and how to formally control the use of XBSTR strings.

BOOLEAN A 32-bit boolean value which is either ZERO or NON-ZERO. For implementation purposes, non-zero boolean values should be -1 this is also defined as DOSTRUE. However for compatibility reasons, performing equality comparisons with any value other than zero is absolutely forbidden, only 0 or FALSE may be used in a value comparison test.

See the dos.doc file introduction paragraph for more details on this issue.

RESULT1 A 32 bit primary result code as defined for the function.
RESULT2 A 32 bit error code as defined in the dos/errors.h include file. Handlers should not return error codes besides those defined. For some functions a secondary result can also be returned here upon success.

Summary of Defined Packet Numbers

Summary of defined packet numbers, as of DOS library version 53.71

This is a listing of all the DOS packets defined by Commodore and other relevant authorities since.

Unless otherwise noted, packets 2050-2999 and 8500-8999 are reserved for use by third party developers (see chart below).

All remaining packets are reserved for future OS expansion.

Decimal Hex Action #define Status
0 0x0000 ACTION_NIL or ACTION_STARTUP
1 <Reserved for operating system>
2 0x0002 ACTION_GET_BLOCK Obsolete
3 <Reserved for operating system>
4 0x0004 ACTION_SET_MAP Obsolete
5 0x0005 ACTION_DIE Deprecated
6 0x0006 ACTION_EVENT Obsolete
7 0x0007 ACTION_CURRENT_VOLUME Obsolete
8 0x0008 ACTION_LOCATE_OBJECT
9 0x0009 ACTION_RENAME_DISK
10-14 <Reserved for operating system>
15 0x000F ACTION_FREE_LOCK
16 0x0010 ACTION_DELETE_OBJECT
17 0x0011 ACTION_RENAME_OBJECT
18 0x0012 ACTION_MORE_CACHE Deprecated
19 0x0013 ACTION_COPY_DIR or ACTION_COPY_LOCK
20 0x0014 ACTION_WAIT_CHAR
21 0x0015 ACTION_SET_PROTECT
22 0x0016 ACTION_CREATE_DIR
23 0x0017 ACTION_EXAMINE_OBJECT Deprecated
24 0x0018 ACTION_EXAMINE_NEXT Deprecated
25 0x0019 ACTION_DISK_INFO
26 0x001A ACTION_INFO
27 0x001B ACTION_FLUSH
28 0x001C ACTION_SET_COMMENT
29 0x001D ACTION_PARENT
30 0x001E ACTION_TIMER Internal
31 0x001F ACTION_INHIBIT
32 0x0020 ACTION_DISK_TYPE Obsolete
33 0x0021 ACTION_DISK_CHANGE Obsolete
34 0x0022 ACTION_SET_DATE
35-39 <Reserved for operating system>
40 0x0028 ACTION_SAME_LOCK
41-52 <Reserved for operating system>
53 0x0035 ACTION_SAME_FH
54-81 <Reserved for operating system>
82 0x0052 ACTION_READ
83-86 <Reserved for operating system>
87 0x0057 ACTION_WRITE
88-993 <Reserved for operating system>
994 0x03E2 ACTION_SCREEN_MODE or ACTION_SINGLE_CHARACTER_MODE
995 0x03E3 ACTION_CHANGE_SIGNAL
996-1000 <Reserved for operating system>
1001 0x03E9 ACTION_READ_RETURN Internal
1002 0x03EA ACTION_WRITE_RETURN Internal
1003 0x03EB ACTION_INT_WRITE_RETURN Internal
1004 0x03EC ACTION_FINDUPDATE (MODE_READWRITE)
1005 0x03ED ACTION_FINDINPUT (MODE_OLDFILE)
1006 0x03EE ACTION_FINDOUTPUT (MODE_NEWFILE)
1007 0x03EF ACTION_END
1008 0x03F0 ACTION_SEEK Deprecated
1009 0x03F1 ACTION_ICONIFY Internal
1010-1019 <Reserved for operating system>
1020 0x03FC ACTION_FORMAT
1021 0x03FD ACTION_MAKE_LINK
1022 0x03FE ACTION_SET_FILE_SIZE Deprecated
1023 0x03FF ACTION_WRITE_PROTECT
1024 0x0400 ACTION_READ_LINK
1025 <Reserved for operating system>
1026 0x0402 ACTION_FH_FROM_LOCK
1027 0x0403 ACTION_IS_FILESYSTEM
1028 0x0404 ACTION_CHANGE_MODE
1029 <Reserved for operating system>
1030 0x0406 ACTION_COPY_DIR_FH
1031 0x0407 ACTION_PARENT_FH
1032 <Reserved for operating system>
1033 0x0409 ACTION_EXAMINE_ALL Deprecated
1034 0x040A ACTION_EXAMINE_FH Deprecated
1035 0x040B ACTION_EXAMINE_ALL_END Deprecated
1036 0x040C ACTION_SET_OWNER Deprecated
1037 0x040D ACTION_SET_OWNER_INFO
1038 <Reserved for operating system>
1039 0x040F ACTION_NEWMEMFILE Internal
1040 0x0410 ACTION_NEWMEMLOCK Internal
1041-1997 <Reserved for operating system>
1998 0x07CE ACTION_WAIT_FOR_DATA
1999 0x07CF ACTION_SET_BLOCKING_MODE
2000-2007 <Reserved for operating system>
2008 0x07D8 ACTION_LOCK_RECORD Optional
2009 0x07D9 ACTION_FREE_RECORD Optional
2010-2049 <Reserved for operating system>
2050-2999 <Reserved for 3rd Party Handlers>
3000 0x0BB8 ACTION_SHUTDOWN
3001 0x0BB9 ACTION_COLLECT
3002-3004 <Reserved for operating system>
3005 0x0BBD ACTION_FILESYSTEM_ATTR
3006 0x0BBE ACTION_OBTAIN_CON_INFO
3007 0x0BBF ACTION_RELEASE_CON_INFO
3008-3029 <Reserved for operating system>
3030 0x0BD6 ACTION_EXAMINEDATA
3031 0x0BD7 ACTION_EXAMINEDATA_FH
3032-3039 <Reserved for operating system>
3040 0x0BE0 ACTION_EXAMINEDATA_DIR
3041-4096 <Reserved for operating system>
4097 0x1001 ACTION_ADD_NOTIFY Optional
4098 0x1002 ACTION_REMOVE_NOTIFY Optional
4099-4199 <Reserved for operating system>
4200 0x1068 ACTION_SERIALIZE_DISK
4201 0x1069 ACTION_GET_DISK_FSSM
4202 0x106A ACTION_FREE_DISK_FSSM
4203-5322 <Reserved for operating system>
5323 0x14CB ACTION_INHIBIT_DOS_LONGPATH_HANDLING
5324-8000 <Reserved for operating system>
8001 0x1F41 ACTION_CHANGE_FILE_POSITION64
8002 0x1F42 ACTION_GET_FILE_POSITION64
8003 0x1F43 ACTION_CHANGE_FILE_SIZE64
8004 0x1F44 ACTION_GET_FILE_SIZE64
8005-8499 <Reserved for operating system 64 bit functions>
8500-8999 <Reserved for use by 3rd Party Handlers for 64 bit functions>
9000-... <Reserved for operating system>

Detailed DOS Packet Documentation

See the dos.dospackets.doc autodoc for all the detailed information regarding each DOS packet.

Using Packets Directly

AmigaDOS contains many features that can only be accessed by sending a packet directly to a process. For example, the ACTION_DISK_INFO packet may be used to find the Intuition window pointer of a CON: or RAW: window. This is useful for redirecting system requesters so that they appear where the user can see them (see "Redirecting System Requesters" above). The Window pointer will be returned in the ID_VolumeNode field, and a pointer to the console's I/O request will be returned in the ID_InUse field. Note that auxiliary consoles (AUX:) can return a NULL Window pointer, and also may have no ConUnit (io_Unit) associated with their I/O request block. Be careful to check for these possibilities when you use this packet. If your application runs in a CLI window, a user may be running you in an auxiliary (AUX:) CLI.

Another example is the ACTION_SCREENMODE_MODE packet which can be sent to the handler process of a CON: window to put the console into raw or cooked mode.

By default, CON: provides mapped keyboard input which is filtered, buffered, and automatically echoed. Many of the special key escape sequences (such as those generated by the function, cursor, and help keys) are filtered out; all strokes are buffered and held back from the reader until the user hits the RETURN key; and the nonfiltered keypresses (such as alphanumeric keys and backspace) are automatically echoed to the CON: window. This "cooked" mode is perfect for general line input from a user because it provides automatic line editing features (same as in the Shell command line).

Sometimes, however, an application needs to get individual keys immediately from a CON: window, or control its own echoing, or receive the escape strings that the keymap generates for special keys such as the Help key or cursor keys.

In this case, an ACTION_SCREEN_MODE packet with the argument DOSTRUE (-1) may be sent to the MsgPort of a CON: window to put the CON: into "raw" mode. In raw mode, a CON: behaves much like a RAW: window. Keyboard console input is not automatically filtered, buffered, or echoed. When reading a CON: which has been set to "raw" mode, each keypress can be read immediately as the ASCII value or string to which the key is mapped by the keymap.

For some applications, it may be convenient to toggle a CON: window between cooked and raw modes, to use cooked mode for use line input, and raw mode when keypresses should cause immediate actions.

ACTION_SCREEN_MODE with the argument DOSFALSE (0L) will place a CON: window in cooked mode. Note that the ACTION_SCREEN_MODE packet may also be used on auxiliary (AUX:) consoles.

The handler MsgPort of most named AmigaDOS devices (like DF0:) can be found with the DeviceProc() function. Note that DeviceProc() cannot be used to find a CON: or RAW: handler because there may be many handlers for each of these. The handler MsgPort (ProcessID) of a CON: or RAW: window is in its FileHandle structure (fh_Type). The MsgPort of a CLI process's "*" window is process->pr_ConsoleTask.

Here's how to find the MsgPort of a handler process (in all cases make sure that port is non-NULL before using it):

Finding the MsgPort of a unique named handler process such as "DF0:":

    port = (struct MsgPort *) IDOS->DeviceProc("DF1:");

Finding the MsgPort of the handler process for an open file:

    fh = IDOS->Open("CON:0/40/640/140/Test", MODE_NEWFILE);
    if ((fh) && (fh->Type))
    {   /* if Open() succeeded and fh_Type is non-NULL */
        port = (struct MsgPort *)
               (((struct FileHandle *) (fh << 2))->fh_Type);
    }

Finding the MsgPort of your process's console handler:

    struct Task* task = IExec->FindTask(NULL);
    if (task->tc_Node.ln_Type == NT_PROCESS)
    {   /* port may be NULL - check before using! */
        port = ((struct Process *) task)->pr_ConsoleTask;
    }

Packets are sent by initializing a longword-aligned StandardPacket structure and sending the packet to the MsgPort of a handler process.

The dos.library provides simple functions for sending and replying to packets:

SendPkt() asynchronously send your initialized packet
WaitPkt() wait for asynchronous packet to complete
ReplyPkt() reply a packet which has been sent to you
DoPkt() creates and sends a packet, and waits for completion