When you open a file using the File folio OpenDiskFile() function, the item that is returned serves as a handle to the file. The Item is of type Device. This enables communication to the filesystem that controls this file using the standard Portfolio I/O model.
When you send a command to a file device, the file system responsible for the file wakes up and executes the command. Therefore, the file device is only a pseudo-device, serving as a gateway to the underlying filesystem.
The File folio provides many high-level functions to control file systems. For example, you can create files using the CreateFile() function, or you can delete files using the DeleteFile() function. These File folio functions are merely wrappers for file system commands. The functions internally create file devices and send commands to the device to perform work.
This section explains the various commands you can send to a file device. It is often much easier to use the higher-level File folio functions to interact with the file system. However, there are some operations that can only be performed by interfacing to the file device directly.
FILECMD_FSSTAT command.
Once the command returns successfully, you can look at the fields in the fsStat structure for the status information. The
IOInfo ioInfo;
FileSystemStat fsStat;
memset(&ioInfo,0,sizeof(ioInfo));
ioInfo.ioi_Command = FILECMD_FSSTAT;
ioInfo.ioi_Recv.iob_Buffer = &fsStat;
ioInfo.ioi_Recv.iob_Len = sizeof(FileSystemStat);
fst_BitMap field of the FileSystemStat structure indicates which fields in the rest of the structure are valid and can be examined. Different file systems cannot always provide all the information in a FileSystemStat structure. For example, if the FSSTAT_SIZE bit is set in fst_BitMap, it means the fst_Size field of the FileSystemStat structure is valid.
The fields in the FileSystemStat structure are:
CMD_STATUS command.
Once the command completes successfully, you can look at the fields in the fStat structure for the status information. Fields of interest are:
IOInfo ioInfo;
FileStatus fStat;
memset(&ioInfo,0,sizeof(ioInfo));
ioInfo.ioi_Command = CMD_STATUS;
ioInfo.ioi_Recv.iob_Buffer = &fStat;
ioInfo.ioi_Recv.iob_Len = sizeof(FileStatus);
CreateFile() function. You supply the path name of the file to create, and the function does the necessary work to create a new file entry on the filesystem.
To delete an existing file, use the File folio's DeleteFile() function. You supply it the path name of the file to delete, and the function does the necessary work to remove the file's entry from the filesystem.
FILECMD_ALLOCBLOCKS command.
The
IOInfo ioInfo;
memset(&ioInfo,0,sizeof(ioInfo));
ioInfo.ioi_Command = FILECMD_ALLOCBLOCKS;
ioInfo.ioi_Offset = numBlocks;
numBlocks variable contains the number of blocks by which to extend the file. If this value is negative, the size of the file is reduced by the specified number of blocks.
CMD_WRITE command to write data to a file. All write operations must be performed in full blocks. The size of the blocks can be obtained by sending a CMD_STATUS command to the file device. The write operation must also be aligned on a block boundary within the file.
The
IOInfo ioInfo;
memset(&ioInfo,0,sizeof(ioInfo));
ioInfo.ioi_Command = CMD_WRITE;
ioInfo.ioi_Offset = blockOffset;
ioInfo.ioi_Send.iob_Buffer = dataAddress;
ioInfo.ioi_Send.iob_Len = numBytes;
blockOffset field indicates the offset in blocks from the beginning of the file where the data is to be written. The dataAddress value points to the data that is to be written. Finally, the numBytes value indicates the number of bytes to write out. This value must be an even multiple of the block size for the file.
FILECMD_SETEOF command. This command tells the filesystem how many useful bytes of data are in the file. Because you can only transfer data in terms of blocks, sending this command tells the filesystem how many bytes of the last written block are useful bytes.
IOInfo ioInfo;
memset(&ioInfo,0,sizeof(ioInfo));
ioInfo.ioi_Command = FILECMD_SETEOF;
ioInfo.ioi_Offset = numBytesInFile;
The
IOInfo ioInfo;
memset(&ioInfo,0,sizeof(ioInfo));
ioInfo.ioi_Command = CMD_READ;
ioInfo.ioi_Offset = blockOffset;
ioInfo.ioi_Recv.iob_Buffer = dataAddress;
ioInfo.ioi_Recv.iob_Len = numBytes;
blockOffset value indicates the offset in blocks from the beginning of the file from which data is read. dataAddress indicates an address in memory where the data will be copied once read from the filesystem. Finally, numBytes contains the number of bytes to read. This number must be an even multiple of the block size of the file.
OpenDiskFile() function opens a directories. You can then use the FILECMD_READDIR command to scan the directory and obtain information about files in the directory.
The
IOInfo ioInfo;
DirectoryEntry dirEntry;
memset(&ioInfo,0,sizeof(ioInfo));
ioInfo.ioi_Command = FILECMD_READDIR;
ioInfo.ioi_Offset = fileNum;
ioInfo.ioi_Recv.iob_Buffer = &dirEntry;
ioInfo.ioi_Recv.iob_Len = sizeof(DirectoryEntry);
fileNum value indicates the number of the file within the directory to read. You start with file 0, and keep going until the I/O cannot be completed because there are no more files. The dirEntry structure will be filled out with information about the specified file.
FILECMD_GETPATH command determines the exact path to an open file.
Once the command completes successfully, the path variable contains a complete unambiguous path to reach the file. You can then use this path to issue another
IOInfo ioInfo;
char path[FILESYSTEM_MAX_PATH_LEN];
memset(&ioInfo,0,sizeof(ioInfo));
ioInfo.ioi_Command = FILECMD_GETPATH;
ioInfo.ioi_Recv.iob_Buffer = path;
ioInfo.ioi_Recv.iob_Len = sizeof(path);
OpenDiskFile() command or a DeleteFile() command.