home *** CD-ROM | disk | FTP | other *** search
- /* fs.c */
-
- #include "chunks.h"
- #include "debug.h"
- #include "swis.h"
-
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
-
- /*********************************************************************************/
- /* */
- /* Support routines */
- /* */
- /*********************************************************************************/
-
- static const char *xFiles_Leaf(const char *pName)
- {
- const char *lastDot;
-
- if (lastDot = strrchr(pName, '.'), lastDot)
- return lastDot + 1;
-
- return pName;
- }
-
- static xFiles_fileInfo *xFiles_FindOpenFile(xFiles_info *pInfo, unsigned cnkNum)
- {
- xFiles_fileInfo *pFile;
-
- for (pFile = (xFiles_fileInfo *) pInfo->openList.head; pFile; pFile = (xFiles_fileInfo *) pFile->li.next)
- {
- if (pFile->cnkNum == cnkNum)
- return pFile;
- }
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_FindObject(xFiles_info *pInfo, const char *fileName,
- xFiles_dirHash *pDirHash, xFiles_dirEntry *pDirEnt,
- unsigned *pParent)
- {
- _kernel_oserror *err;
- unsigned hashOffset;
-
- if (err = xFiles_parsePath(pInfo, fileName, pParent, &hashOffset, NULL, pDirHash, pDirEnt, FALSE), err)
- return err;
-
- if (hashOffset == 0) return &xFiles_NotFound;
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_FindDir(xFiles_info *pInfo, const char *fileName,
- xFiles_dirHash *pDirHash, xFiles_dirEntry *pDirEnt)
- {
- _kernel_oserror *err;
-
- if (err = xFiles_FindObject(pInfo, fileName, pDirHash, pDirEnt, NULL), err)
- return err;
-
- if ((pDirEnt->attr & xFiles_isDir) == 0)
- return &xFiles_NotADir;
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_Rename(xFiles_info *pInfo, const char *from, const char *to)
- {
- _kernel_oserror *err;
-
- unsigned toDir, toHashOffset;
- unsigned fromDir, fromHashOffset, fromEntryOffset;
- xFiles_dirEntry fromDirEnt;
- xFiles_dirHash fromDirHash;
-
- /*TRACE("Rename %s %s\n", from, to);*/
-
- if (err = xFiles_parsePath(pInfo, to, &toDir, &toHashOffset, NULL, NULL, NULL, TRUE), err)
- return err;
-
- if (err = xFiles_parsePath(pInfo, from, &fromDir, &fromHashOffset, &fromEntryOffset, &fromDirHash, &fromDirEnt, FALSE), err)
- return err;
-
- /* Create the new entry */
-
- if (err = xFiles_createDirEntry(pInfo, toDir, &fromDirHash, &fromDirEnt, xFiles_Leaf(to)), err)
- return err;
-
- /* If they are in the same directory the offsets might not be valid anymore, so
- * do another scan of the directory to get the latest info.
- */
-
- if (err = xFiles_dirLookup(pInfo, fromDir, xFiles_Leaf(from),
- &fromHashOffset, &fromEntryOffset, NULL, NULL), err)
- return err;
-
- if (err = xFiles_deleteDirEntry(pInfo, fromDir, fromHashOffset), err)
- return err;
-
- return NULL;
- }
-
-
- static _kernel_oserror *xFiles_ReadDirEntries(xFiles_info *pInfo, const char *dirName, void *buffer,
- int *pCount, int *pNext, int bufSize, BOOL infoToo)
- {
- _kernel_oserror *err;
- xFiles_dirHeader dirHdr;
- xFiles_dirHash dirHash;
- xFiles_dirEntry dirEnt;
- unsigned dirObject;
- unsigned hashPos;
- int nFiles;
- char *bufPtr, *bufLimit;
- int spaceNeeded;
- BOOL fakeName;
-
- struct fileInfo
- {
- unsigned load, exec, size, attr, type;
- } *pFileInfo;
-
- if (err = xFiles_FindDir(pInfo, dirName, &dirHash, &dirEnt), err)
- return err;
-
- dirObject = dirHash.node;
-
- if (err = xFiles_getDirHeader(pInfo, dirObject, &dirHdr), err)
- return err;
-
- nFiles = *pCount;
- *pCount = 0;
- bufPtr = (char *) buffer;
- bufLimit = bufPtr + bufSize;
-
- while (nFiles > 0 && *pNext < dirHdr.used)
- {
- hashPos = sizeof(xFiles_dirHeader) + sizeof(xFiles_dirHash) * (*pNext);
- fakeName = FALSE;
-
- if (err = xFiles_readChunk(pInfo, &dirHash, dirObject, hashPos, sizeof(dirHash)), err)
- return err;
-
- if (err = xFiles_readChunk(pInfo, &dirEnt, dirObject, dirHash.entryPos, sizeof(dirEnt)), err)
- return err;
-
- if (dirEnt.nameLen > 256 || dirEnt.nameLen == 0)
- {
- TRACE("Fixing broken name (length = %08x)\n", dirEnt.nameLen);
-
- fakeName = TRUE;
- dirEnt.nameLen = 12;
- }
-
- if (infoToo)
- spaceNeeded = 20 + (dirEnt.nameLen + 4) & ~3;
- else
- spaceNeeded = dirEnt.nameLen + 1;
-
- if (bufPtr + spaceNeeded > bufLimit)
- break;
-
- if (infoToo)
- {
- pFileInfo = (struct fileInfo *) bufPtr;
-
- if (fakeName)
- {
- xFiles_chunk cnk;
-
- if (err = xFiles_getChunkInfo(pInfo, dirHash.node, &cnk), err)
- return err;
-
- dirEnt.load =
- dirEnt.exec = 0xFFFFFFFF;
- dirEnt.size = cnk.size;
- dirEnt.attr = xFiles_meRead | xFiles_meWrite;
- }
-
- pFileInfo->load = dirEnt.load;
- pFileInfo->exec = dirEnt.exec;
- pFileInfo->size = dirEnt.size;
- pFileInfo->attr = dirEnt.attr & 0xFF;
- pFileInfo->type = (dirEnt.attr & xFiles_isDir) ? 2 : 1;
- bufPtr = (char *) (pFileInfo + 1);
- }
-
- if (fakeName)
- {
- memcpy(bufPtr, dirHash.nameStart, 4);
- sprintf(bufPtr + 4, "%08d", dirHash.node);
- }
- else
- {
- if (err = xFiles_readChunk(pInfo, bufPtr, dirObject,
- dirHash.entryPos + sizeof(dirEnt), dirEnt.nameLen + 1), err)
- return err;
- }
-
- bufPtr += dirEnt.nameLen + 1;
-
- if (infoToo)
- {
- while (((int) bufPtr & 3) != 0)
- *bufPtr++ = 0;
- }
-
- (*pCount)++;
- (*pNext)++;
- nFiles--;
- }
-
- if (*pNext >= dirHdr.used)
- *pNext = -1;
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_FileInfo(xFiles_info *pInfo, _kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- xFiles_dirEntry dirEnt;
- unsigned hashOffset;
-
- if (err = xFiles_parsePath(pInfo, (const char *) regs->r[1], NULL, &hashOffset, NULL, NULL, &dirEnt, FALSE), err)
- return err;
-
- if (hashOffset == 0)
- regs->r[0] = 0;
- else
- {
- regs->r[0] = (dirEnt.attr & xFiles_isDir) ? 2 : 1;
- regs->r[2] = dirEnt.load;
- regs->r[3] = dirEnt.exec;
- regs->r[4] = dirEnt.size;
- regs->r[5] = dirEnt.attr & 0xFF;
- }
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_UpdateInfo(xFiles_info *pInfo, _kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- xFiles_dirEntry dirEnt;
- unsigned hashOffset;
- unsigned entryOffset;
- unsigned parent;
-
- const char *objName = (const char *) regs->r[1];
-
- if (*objName == '\0') /* don't even bother trying with the root */
- return NULL;
-
- if (err = xFiles_parsePath(pInfo, objName, &parent, &hashOffset, &entryOffset, NULL, &dirEnt, FALSE), err)
- return err;
-
- if (hashOffset == 0)
- return NULL;
-
- dirEnt.load = regs->r[2];
- dirEnt.exec = regs->r[3];
- dirEnt.attr = (dirEnt.attr & 0xFFFFFF00) | (regs->r[5] & 0xFF);
-
- if (err = xFiles_writeChunk(pInfo, &dirEnt, parent, entryOffset, sizeof(dirEnt)), err)
- return err;
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_NewImage(_kernel_swi_regs *regs)
- {
- xFiles_info *pInfo;
- _kernel_oserror *err;
-
- if (pInfo = malloc(sizeof(xFiles_info)), !pInfo)
- return &xFiles_NoMemory;
-
- xFiles_InitItem(&pInfo->li);
- xFiles_InitList(&pInfo->openList);
-
- pInfo->fileHandle = regs->r[1];
-
- /* Should this perhaps take some notice of the sage advice which appears
- * on page 4-46 of the PRM?
- */
-
- if (err = xFiles_OpenImage(pInfo), err)
- return err;
-
- regs->r[1] = (int) pInfo;
- return NULL;
- }
-
- static _kernel_oserror *xFiles_Delete(xFiles_info *pInfo, const char *objName)
- {
- _kernel_oserror *err;
- xFiles_fileInfo *pFile;
- xFiles_dirHash dirHash;
- xFiles_dirEntry dirEnt;
- unsigned hashOffset;
- unsigned entryOffset;
- unsigned parent;
-
- /*TRACE("Delete %s\n", objName);*/
-
- if (*objName == '\0') /* don't even bother trying with the root */
- return NULL;
-
- if (err = xFiles_parsePath(pInfo, objName, &parent, &hashOffset, &entryOffset, &dirHash, &dirEnt, FALSE), err)
- return err;
-
- /* Don't delete an open file */
-
- if (pFile = xFiles_FindOpenFile(pInfo, dirHash.node), pFile)
- return &xFiles_IsOpen;
-
- if (hashOffset == 0)
- return NULL;
-
- if (dirEnt.attr & xFiles_locked)
- return &xFiles_Locked;
-
- if (dirEnt.attr & xFiles_isDir)
- {
- xFiles_dirHeader dirHdr;
-
- if (err = xFiles_getDirHeader(pInfo, dirHash.node, &dirHdr), err)
- return err;
-
- if (dirHdr.used != 0)
- return NULL; /* &xFiles_DirNotEmpty; */
- }
-
- if (err = xFiles_deleteDirEntry(pInfo, parent, hashOffset), err)
- return err;
-
- if (err = xFiles_freeChunk(pInfo, dirHash.node), err)
- return err;
-
- return NULL;
-
- }
-
- static _kernel_oserror *xFiles_ObjectExists(xFiles_info *pInfo, const char *pName, BOOL *pExists)
- {
- _kernel_oserror *err;
- unsigned hashOffset;
-
- if (err = xFiles_parsePath(pInfo, pName, NULL, &hashOffset, NULL, NULL, NULL, FALSE), err)
- return err;
-
- if (pExists) *pExists = (hashOffset != 0);
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_CDir(xFiles_info *pInfo, _kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- xFiles_dirEntry dirEnt, newDir;
- xFiles_dirHash dirHash, newHash;
- const char *dirName = (const char *) regs->r[1];
- unsigned hashOffset;
- BOOL exists;
-
- /*TRACE("CDir %s\n", dirName);*/
-
- if (err = xFiles_ObjectExists(pInfo, dirName, &exists), err)
- return err;
-
- if (exists)
- return NULL;
-
- if (err = xFiles_parsePath(pInfo, dirName, NULL, &hashOffset, NULL, &dirHash, &dirEnt, TRUE), err)
- return err;
-
- if (hashOffset == 0)
- return &xFiles_NotFound;
-
- if (err = xFiles_cDir(pInfo, dirHash.node, &newHash.node), err)
- return err;
-
- newDir.load = regs->r[2];
- newDir.exec = regs->r[3];
- newDir.size = 0;
- newDir.attr = xFiles_meRead | xFiles_meWrite | xFiles_isDir;
-
- if (err = xFiles_createDirEntry(pInfo, dirHash.node, &newHash, &newDir, xFiles_Leaf(dirName)), err)
- return err;
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_Create(xFiles_info *pInfo, _kernel_swi_regs *regs, unsigned *pCnk)
- {
- _kernel_oserror *err;
- const char *fileName = (const char *) regs->r[1];
- xFiles_dirEntry dirEnt, newFile;
- xFiles_dirHash dirHash, newHash;
- unsigned hashOffset, entryOffset, parent;
-
- /*TRACE("Create %s\n", fileName);*/
-
- #if 0
- if (err = xFiles_Delete(pInfo, fileName), err)
- return err;
- #else
- if (err = xFiles_parsePath(pInfo, fileName, &parent, &hashOffset, &entryOffset, &dirHash, &dirEnt, FALSE), err)
- return err;
-
- if (hashOffset != 0) /* File already exists */
- {
- if (err = xFiles_setChunkSize(pInfo, dirHash.node, regs->r[5] - regs->r[4]), err)
- return err;
-
- dirEnt.load = regs->r[2];
- dirEnt.exec = regs->r[3];
- dirEnt.size = regs->r[5] - regs->r[4];
-
- if (err = xFiles_writeChunk(pInfo, &dirEnt, parent, entryOffset, sizeof(dirEnt)), err)
- return err;
-
- if (pCnk) *pCnk = dirHash.node;
- return NULL;
- }
- #endif
-
- if (err = xFiles_parsePath(pInfo, fileName, NULL, &hashOffset, NULL, &dirHash, &dirEnt, TRUE), err)
- return err;
-
- if (hashOffset == 0)
- return &xFiles_NotFound;
-
- if (err = xFiles_newChunk(pInfo, &newHash.node), err)
- return err;
-
- if (err = xFiles_setChunkSize(pInfo, newHash.node, regs->r[5] - regs->r[4]), err)
- return err;
-
- newFile.load = regs->r[2];
- newFile.exec = regs->r[3];
- newFile.size = regs->r[5] - regs->r[4];
- newFile.attr = xFiles_meRead | xFiles_meWrite;
-
- if (err = xFiles_createDirEntry(pInfo, dirHash.node, &newHash, &newFile, xFiles_Leaf(fileName)), err)
- return err;
-
- if (pCnk) *pCnk = newHash.node;
-
- return NULL;
- }
-
- static _kernel_oserror *xFiles_Save(xFiles_info *pInfo, _kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- unsigned newChunk;
-
- if (err = xFiles_Create(pInfo, regs, &newChunk), err)
- return err;
-
- return xFiles_writeChunk(pInfo, (void *) regs->r[4], newChunk, 0, regs->r[5] - regs->r[4]);
- }
-
- static _kernel_oserror *xFiles_FindFile(xFiles_info *pInfo, const char *fileName,
- xFiles_dirHash *pDirHash, xFiles_dirEntry *pDirEnt,
- unsigned *pParent)
- {
- _kernel_oserror *err;
-
- if (err = xFiles_FindObject(pInfo, fileName, pDirHash, pDirEnt, pParent), err)
- return err;
-
- if ((pDirEnt->attr & xFiles_isDir) != 0)
- return &xFiles_NotAFile;
-
- return NULL;
- }
-
- /* Locate an open file's directory information by looking it up
- * in it's parent directory.
- */
-
- static _kernel_oserror *xFiles_LocateOpenFile(xFiles_info *pInfo, xFiles_fileInfo *pFileInfo,
- unsigned *pEntryOffset, xFiles_dirEntry *pDirEnt)
- {
- _kernel_oserror *err;
- unsigned hashOffset;
- xFiles_dirHash dirHash;
-
- /* Might want to change this to return the hash too? */
-
- if (err = xFiles_dirLookupByNode(pInfo, pFileInfo->parentDir, pFileInfo->cnkNum,
- &hashOffset, pEntryOffset, &dirHash), err)
- return err;
-
- if (hashOffset == 0)
- return &xFiles_LostTrack;
-
- if (pDirEnt)
- {
- if (err = xFiles_readChunk(pInfo, (void *) pDirEnt, pFileInfo->parentDir,
- dirHash.entryPos, sizeof(xFiles_dirEntry)), err)
- return err;
- }
-
- return NULL;
- }
-
- /*********************************************************************************/
- /* */
- /* Filing system functionality (at last) */
- /* */
- /*********************************************************************************/
-
- _kernel_oserror *xFiles_Open(_kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- const char *fileName = (const char *) regs->r[1];
- xFiles_info *pInfo = (xFiles_info *) regs->r[6];
- xFiles_fileInfo *pFileInfo;
- xFiles_dirEntry dirEnt;
- xFiles_dirHash dirHash;
-
- if (pFileInfo = malloc(sizeof(xFiles_fileInfo)), !pFileInfo)
- return &xFiles_NoMemory;
-
- xFiles_InitItem(&pFileInfo->li);
-
- pFileInfo->fileSwitchHandle = regs->r[3];
- pFileInfo->pOwner = pInfo;
-
- /*TRACE("Open(%s)\n", leafName);*/
-
- if (err = xFiles_FindFile(pInfo, fileName, &dirHash, &dirEnt, &pFileInfo->parentDir), err)
- goto failed;
-
- pFileInfo->cnkNum = dirHash.node;
- pFileInfo->fileSize = dirEnt.size;
-
- regs->r[0] = dirEnt.attr << 30;
- regs->r[1] = (int) pFileInfo;
- regs->r[2] = pInfo->fileHeader.allocationUnit;
- regs->r[3] = dirEnt.size;
- regs->r[4] = (dirEnt.size + 1023) & ~1023;
-
- if (err = xFiles_Commit(pInfo), err)
- return err;
-
- /* Link it in to it's owner */
-
- xFiles_AddAtHead(&pInfo->openList, &pFileInfo->li);
-
- return NULL;
-
- failed:
- free(pFileInfo);
- regs->r[1] = 0;
- return err;
- }
-
- _kernel_oserror *xFiles_GetBytes(_kernel_swi_regs *regs)
- {
- xFiles_fileInfo *pFileInfo = (xFiles_fileInfo *) regs->r[1];
- xFiles_info *pInfo = pFileInfo->pOwner;
- unsigned pos = regs->r[4];
- unsigned size = regs->r[3];
-
- if (pos + size > pFileInfo->fileSize)
- size = pFileInfo->fileSize - pos;
-
- /*TRACE("GetBytes() %08x, %08x, %08x\n", regs->r[2], regs->r[3], regs->r[4]);*/
-
- return xFiles_readChunk(pInfo, (void *) regs->r[2], pFileInfo->cnkNum, pos, size);
- }
-
- _kernel_oserror *xFiles_PutBytes(_kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- xFiles_fileInfo *pFileInfo = (xFiles_fileInfo *) regs->r[1];
- xFiles_info *pInfo = pFileInfo->pOwner;
- unsigned pos = regs->r[4];
- unsigned size = regs->r[3];
-
- /*TRACE("PutBytes() %08x, %08x, %08x\n", regs->r[2], regs->r[3], regs->r[4]);
- TRACE("pFileInfo->cnkNum = %08x\n", pFileInfo->cnkNum);*/
-
- if (err = xFiles_writeChunk(pInfo, (void *) regs->r[2], pFileInfo->cnkNum, pos, size), err)
- return err;
-
- return xFiles_Commit(pInfo);
- }
-
- _kernel_oserror *xFiles_Args(_kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- unsigned entryOffset;
- xFiles_fileInfo *pFileInfo = (xFiles_fileInfo *) regs->r[1];
- xFiles_info *pInfo = pFileInfo->pOwner;
- xFiles_dirEntry dirEnt;
- BOOL update = FALSE;
-
- if (err = xFiles_LocateOpenFile(pInfo, pFileInfo, &entryOffset, &dirEnt), err)
- return err;
-
- switch (regs->r[0])
- {
- case 7: /* ensure file size */
- /*TRACE("Ensure file is >= %08x (currently %08x)\n", regs->r[2], dirEnt.size);*/
- if (regs->r[2] <= dirEnt.size)
- break;
-
- case 3: /* write file extent */
- if (err = xFiles_setChunkSize(pInfo, pFileInfo->cnkNum, regs->r[2]), err)
- return err;
- dirEnt.size = regs->r[2];
- pFileInfo->fileSize = regs->r[2];
- update = TRUE;
- break;
-
- case 4:
- regs->r[2] = dirEnt.size;
- break;
-
- case 9:
- regs->r[2] = dirEnt.load;
- regs->r[3] = dirEnt.exec;
- break;
-
- case 6:
- case 8: /* write zeros */
- case 10:
- break;
-
- default:
- TRACE("Args(%d) called\n", regs->r[0]);
- return &xFiles_NotImplemented;
- }
-
- if (update)
- {
- if (err = xFiles_writeChunk(pInfo, &dirEnt, pFileInfo->parentDir,
- entryOffset, sizeof(dirEnt)), err)
- return err;
- }
-
- return xFiles_Commit(pInfo);
- }
-
- _kernel_oserror *xFiles_Close(_kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- unsigned entryOffset;
- xFiles_fileInfo *pFileInfo = (xFiles_fileInfo *) regs->r[1];
- xFiles_info *pInfo = pFileInfo->pOwner;
- xFiles_dirEntry dirEnt;
-
- /*TRACE("Close()\n");*/
-
- if (err = xFiles_LocateOpenFile(pInfo, pFileInfo, &entryOffset, &dirEnt), err)
- return err;
-
- if (regs->r[2] != 0) dirEnt.load = regs->r[2];
- if (regs->r[3] != 0) dirEnt.exec = regs->r[3];
-
- if (regs->r[2] != 0 || regs->r[3] != 0)
- {
- if (err = xFiles_writeChunk(pInfo, &dirEnt, pFileInfo->parentDir,
- entryOffset, sizeof(dirEnt)), err)
- return err;
- }
-
- if (err = xFiles_Commit(pInfo), err)
- return err;
-
- /* Can't error now, so unlink it and get rid of it */
-
- xFiles_Remove(&pInfo->openList, &pFileInfo->li);
- free(pFileInfo);
-
- return NULL;
- }
-
- _kernel_oserror *xFiles_File(_kernel_swi_regs *regs)
- {
- _kernel_oserror *err;
- xFiles_info *pInfo = (xFiles_info *) regs->r[6];
-
- switch (regs->r[0])
- {
- case 0:
- if (err = xFiles_Save(pInfo, regs), err) return err;
- break;
-
- case 1:
- if (err = xFiles_UpdateInfo(pInfo, regs), err) return err;
- break;
-
- case 5:
- if (err = xFiles_FileInfo(pInfo, regs), err) return err;
- break;
-
- case 6:
- if (err = xFiles_Delete(pInfo, (const char *) regs->r[1]), err) return err;
- break;
-
- case 7:
- if (err = xFiles_Create(pInfo, regs, NULL), err) return err;
- break;
-
- case 8:
- if (err = xFiles_CDir(pInfo, regs), err) return err;
- break;
-
- default:
- TRACE("File(%d) called\n", regs->r[0]);
- return &xFiles_NotImplemented;
- }
-
- return xFiles_Commit(pInfo);
- }
-
- _kernel_oserror *xFiles_Func(_kernel_swi_regs *regs)
- {
- xFiles_info *pInfo = (xFiles_info *) regs->r[6];
- _kernel_oserror *err;
-
- /*TRACE("Func(%d) called\n", regs->r[0]);*/
-
- switch (regs->r[0])
- {
- case 8: /* rename object */
- if (err = xFiles_Rename(pInfo, (const char *) regs->r[1], (const char *) regs->r[2]), err)
- return err;
- regs->r[1] = 0;
- return xFiles_Commit(pInfo);
-
- case 14: /* read directory entries */
- case 15:
- return xFiles_ReadDirEntries(pInfo, (const char *) regs->r[1],
- (void *) regs->r[2], ®s->r[3], ®s->r[4], regs->r[5],
- regs->r[0] == 15);
-
- case 21: /* new image notification */
- return xFiles_NewImage(regs);
-
- case 22:
- return xFiles_CloseImage((xFiles_info *) regs->r[1]);
-
- case 27: /* return boot option */
- regs->r[2] = 0;
- return NULL;
-
- default:
- TRACE("Func(%d) called\n", regs->r[0]);
- return &xFiles_NotImplemented;
- }
-
- return NULL;
- }
-
-