==== FS_FILEIO ====
**Purpose**
Perform multiple lock, unlock, seek, read, and write I/O.   
**Calling Sequence**
int far pascal FS_FILEIO (psffsi, psffsd, pCmdList, cbCmdList, poError,
                          IOflag)
struct sffsi far * psffsi;
struct sffsd far * psffsd;
char far * pCmdList;
unsigned short cbCmdList;
unsigned short far * poError;
unsigned short IOflag;
**Where**
//psffsi// is a pointer to the file-system-independent portion of an open file instance.   
//psffsd// is a pointer to the file-system-dependent portion of an open file instance.   
//pCmdList// is a pointer to a command list that contains entries indicating what commands will be performed.   
Each individual operation (//CmdLock//, //CmdUnlock//, //CmdSeek//, //CmdIO//) is performed as atomic operations until all are complete or until one fails. //CmdLock// executes a multiple range lock as an atomic operation. //CmdUnlock// executes a multiple range unlock as an atomic operation. Unlike //CmdLock//, //CmdUnlock// cannot fail as long as the parameters to it are correct, and the calling application had done a Lock earlier, so it can be viewed as atomic.   
The validity of the user address is not verified (see //FSH_PROBEBUF//).   
For //CmdLock//, the command format is:   
struct CmdLock {
    unsigned short Cmd = 0;   /* 0 for lock operations         */
    unsigned short LockCnt;   /* number of locks that follow   */
    unsigned long  TimeOut;   /* ms time-out for lock success  */
}
which is followed by a series of records of the following format:   
struct Lock {
    unsigned short Share = 0;   /* 0 for exclusive, 1 for read-only  */
    long           Start;       /* start of lock region              */
    long           Length;      /* length of lock region             */
}
If a lock within a //CmdLock// causes a time-out, none of the other locks within the scope of //CmdLock// are in force, because the lock operation is viewed as atomic.   
//CmdLock//. //TimeOut// is the count in milliseconds, until the requesting process is to resume execution if the requested locks are not available. If //CmdLock//. //TimeOut// == 0, there will be no wait. If //CmdLock//. //TimeOut// < 0xFFFFFFFF it is the number of milliseconds to wait until the requested locks become available. If //CmdLock//. //TimeOut// == 0xFFFFFFFF then the thread will wait indefinitely until the requested locks become available.   
Lock.Share defines the type of access other processes may have to the file-range being locked. If its value == 0, other processes have No-Access to the locked range. If its value == 1, other process have Read-Only access to the locked range.   
For //CmdUnlock//, the command format is:   
struct CmdUnlock {
    unsigned short Cmd = 1;     /* 1 for unlock operations        */
    unsigned short UnlockCnt;   /* Number of unlocks that follow  */
}
which is followed by a series of records of the following format:   
struct UnLock {
    long Start;                 /* start of locked region         */
    long Length;                /* length of locked region        */
}
For //CmdSeek//, the command format is:   
struct CmdSeek {
    unsigned short Cmd = 2;   /* 2 for seek operation         */
    unsigned short Method;    /* 0 for absolute               */
                              /* 1 for relative to current    */
                              /* 2 for relative to EOF        */
    long           Position;  /* file seek position or delta  */
    long           Actual;    /* actual position seeked to    */
}
For //CmdIO//, the command format is:   
struct CmdIO {
    unsigned short Cmd;        /* 3 for read, 4 for write      */
    void far * Buffer;         /* pointer to the data buffer   */
    unsigned short BufferLen;  /* number of bytes requested    */
    unsigned short Actual;     /* number of bytes transferred  */
}
//cbCmdList// is the length in bytes of the command list.   
//poError// is the offset within the command list of the command that caused the error.   
This field has a value only when an error occurs.   
The validity of the user address has not been verified (see //FSH_PROBEBUF//).   
^//IOflag// ^indicates information about the operation on the handle.   ^
|//IOflag// == 0x0010 |indicates write-through. |
|//IOflag// == 0x0020 |indicates no-cache. |
**Remarks**
This function provides a simple mechanism for combining the file I/O operations into a single request and providing improved performance, particularly in a networking environment.   
File systems that do not have the //FileIO// bit in their attribute field do not see this call: The command list is parsed by the IFS router. The FSD sees only //FS_CHGFILEPTR//, //FS_READ//, //FS_WRITE// calls.   
File systems that have the //FileIO// bit in their attribute field see this call in its entirety. The atomicity guarantee applies only to the commands themselves and not to the list as a whole.   
Of the information passed in //IOflag//, the write-through bit is a mandatory bit in that any data written to the block device must be put out on the medium before the device driver returns. The no-cache bit, on the other hand, is an advisory bit that says whether the data being transferred is worth caching or not.