home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
useful
/
disk
/
misc
/
flat
/
flat-handler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-26
|
38KB
|
1,518 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1991 by Olaf Barthel
*
* Name .....: Flat-Handler.c
* Created ..: Saturday 11-May-91 17:55
* Revision .: 3
*
* Date Author Comment
* ========= ======== ====================
* 26-Jul-91 Olsen Added ACTION_COPY_DIR
* 11-Jul-91 Olsen Minor fixes.
* 11-May-91 Olsen Created this file!
*
* $Revision Header ********************************************************/
/* Standard FS error types. */
enum { ERR_WRITEPROTECT,ERR_NODISK,ERR_UNREADABLE,ERR_WRITEERROR };
/* This is a link node used both for locks and filehandles. */
struct FlatNode
{
struct FlatNode *fn_Succ; /* Vanilla node head. */
struct FlatNode *fn_Pred;
ULONG fn_UniqueID; /* A unique ID. */
LONG fn_Mode; /* Either shared or exclusive. */
struct DeviceNode *fn_DevInfo; /* Pointer to a device node,
* needed by ExNext and the like.
*/
ULONG fn_BlockSize; /* Size of a block (512 bytes are standard). */
ULONG fn_FirstBlock; /* The first accessible block. */
ULONG fn_NumBlocks; /* Maximum number of available blocks. */
LONG fn_Position; /* Current file position in bytes. */
struct FileLock fn_Lock; /* A dummy file lock. */
UBYTE fn_Name[40]; /* Name of this file. */
struct MsgPort *fn_DiskPort; /* Driver data. */
struct IOExtTD *fn_DiskRequest;
APTR fn_DiskBuffer;
BYTE fn_CheckCount; /* The disk state is checked
* every tenth r/w attempt,
* this byte keeps the count.
*/
};
/* This list keeps all the locks and filehandles. */
struct List FlatList;
/* Each open/lock call increments this counter to
* guarantee that each item receives a unique identifier.
*/
ULONG UniqueCounter = 0;
/* Shared library identifiers. */
struct ExecBase *SysBase = NULL;
struct DosLibrary *DOSBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
/* Prototypes for this module. */
LONG __saveds HandlerEntry(VOID);
LONG __regargs DoRead(struct FlatNode *FlatNode,LONG Size,UBYTE *Buffer,struct Process *Caller);
LONG __regargs DoWrite(struct FlatNode *FlatNode,LONG Size,UBYTE *Buffer,struct Process *Caller);
UBYTE * __regargs BaseName(UBYTE *String);
UBYTE __regargs Local2Upper(UBYTE c);
UBYTE __regargs StrCmp(UBYTE *a,UBYTE *b);
struct FlatNode * __regargs FindFlatNodeByID(ULONG UniqueID);
struct FlatNode * __regargs FindFlatNodeByName(UBYTE *Name);
VOID __regargs BtoCStr(UBYTE *Name,BSTR String,LONG MaxLength);
LONG __regargs ShowRequest(APTR WindowPtr,BYTE Type,UBYTE *Drive);
struct DeviceNode * __regargs FindDevice(struct DeviceNode *LastNode,struct FileSysStartupMsg **Startup,struct DosEnvec **DosEnvec,UBYTE *Name);
VOID __regargs DeleteNode(struct FlatNode *FlatNode);
struct FlatNode * __regargs CreateNode(LONG Type,UBYTE *Name);
VOID __regargs ReturnPacket(struct DosPacket *Packet,ULONG Res1,ULONG Res2,struct Process *HandlerProc);
struct DosPacket * __regargs WaitPacket(struct Process *HandlerProc);
/* HandlerEntry():
*
* Entry point for this module.
*/
LONG __saveds
HandlerEntry()
{
struct Process *HandlerProc;
struct FileHandle *FileHandle;
struct FileLock *FileLock;
LONG ReadBytes,WriteBytes,Bytes;
LONG NewPosition;
struct FileInfoBlock *FileInfo;
UBYTE *FileName;
UBYTE NameBuffer[257];
struct DosPacket *FlatPacket;
struct DeviceNode *FlatDevNode;
struct FlatNode *FlatNode;
/* Set up SysBase. */
SysBase = *(struct ExecBase **)4;
/* Know who we are. */
HandlerProc = (struct Process *)SysBase -> ThisTask;
/* Started from Shell (oops!)? */
if(!HandlerProc -> pr_CLI)
{
/* Wait for startup packet. */
FlatPacket = WaitPacket(HandlerProc);
/* Clear the list. */
NewList(&FlatList);
/* Pick up the pointer to our DeviceNode. */
FlatDevNode = (struct DeviceNode *)BADDR(FlatPacket -> dp_Arg3);
/* Install ourselves at the other hand. */
FlatDevNode -> dn_Task = &HandlerProc -> pr_MsgPort;
/* Open DOS; we are not making DOS calls but
* rather use the base to scan for block-
* mapped devices.
*/
if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
{
ReturnPacket(FlatPacket,DOSFALSE,FlatPacket -> dp_Res2,HandlerProc);
goto FallOff;
}
/* Open Intuition; we might want to put up
* auto-requesters.
*/
if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
{
ReturnPacket(FlatPacket,DOSFALSE,FlatPacket -> dp_Res2,HandlerProc);
goto FallOff;
}
/* Initialization finished, now return the
* startup packet.
*/
ReturnPacket(FlatPacket,DOSTRUE,FlatPacket -> dp_Res2,HandlerProc);
/* Go into loop waiting for data packets. */
FOREVER
{
/* Wait for packet. */
FlatPacket = WaitPacket(HandlerProc);
/* Examine the packet type. */
switch(FlatPacket -> dp_Type)
{
/* Obtain a filelock. */
case ACTION_LOCATE_OBJECT:
/* Convert the file name. */
BtoCStr(NameBuffer,FlatPacket -> dp_Arg2,256);
/* Are we to return a lock
* to a file or a lock to the
* root directory?
*/
if(FileName = BaseName(NameBuffer))
{
/* Look for a file of this name. */
if(FlatNode = FindFlatNodeByName(FileName))
{
/* See if the file is currently locked. */
if((FlatNode -> fn_Mode != FlatPacket -> dp_Arg3) || (FlatPacket -> dp_Arg3 == EXCLUSIVE_LOCK && FlatNode -> fn_Mode == EXCLUSIVE_LOCK))
{
ReturnPacket(FlatPacket,DOSFALSE,ERROR_OBJECT_IN_USE,HandlerProc);
break;
}
}
/* Create a new item and add it to the list. */
if(FlatNode = CreateNode(FlatPacket -> dp_Arg3,FileName))
{
AddTail(&FlatList,(struct Node *)FlatNode);
/* Initialize the default data so DOS will
* get along with us.
*/
FlatNode -> fn_Lock . fl_Access = FlatPacket -> dp_Arg3;
FlatNode -> fn_Lock . fl_Task = &HandlerProc -> pr_MsgPort;
FlatNode -> fn_Lock . fl_Volume = MKBADDR(FlatDevNode);
FlatNode -> fn_Lock . fl_Key = FlatNode -> fn_UniqueID;
FlatPacket -> dp_Res1 = MKBADDR(&FlatNode -> fn_Lock);
strcpy(FlatNode -> fn_Name,FileName);
ReturnPacket(FlatPacket,FlatPacket -> dp_Res1,FlatPacket -> dp_Res2,HandlerProc);
}
else
ReturnPacket(FlatPacket,DOSFALSE,ERROR_OBJECT_NOT_FOUND,HandlerProc);
}
else
{
if(FlatNode = CreateNode(FlatPacket -> dp_Arg3,NULL))
{
AddTail(&FlatList,(struct Node *)FlatNode);
FlatNode -> fn_Lock . fl_Access = FlatPacket -> dp_Arg3;
FlatNode -> fn_Lock . fl_Task = &HandlerProc -> pr_MsgPort;
FlatNode -> fn_Lock . fl_Volume = MKBADDR(FlatDevNode);
FlatNode -> fn_Lock . fl_Key = FlatNode -> fn_UniqueID;
FlatPacket -> dp_Res1 = MKBADDR(&FlatNode -> fn_Lock);
ReturnPacket(FlatPacket,FlatPacket -> dp_Res1,FlatPacket -> dp_Res2,HandlerProc);
}
else
ReturnPacket(FlatPacket,DOSFALSE,ERROR_OBJECT_NOT_FOUND,HandlerProc);
}
break;
/* Free a lock obtained above. */
case ACTION_FREE_LOCK:
/* Is the lock part of the list? */
if(FlatPacket -> dp_Arg1)
{
if(FlatNode = FindFlatNodeByID(((struct FileLock *)BADDR(FlatPacket -> dp_Arg1)) -> fl_Key))
{
Remove((struct Node *)FlatNode);
DeleteNode(FlatNode);
}
}
FlatPacket -> dp_Res1 = DOSTRUE;
ReturnPacket(FlatPacket,FlatPacket -> dp_Res1,FlatPacket -> dp_Res2,HandlerProc);
break;
/* Duplicate a shared lock. */
case ACTION_COPY_DIR:
/* Make sure a ZERO lock gives
* a more or less valid return
* code.
*/
FlatPacket -> dp_Res1 = 0;
FlatPacket -> dp_Res2 = 0;
/* Are we to duplicate a non-ZERO lock? */
if(FlatPacket -> dp_Arg1)
{
FileLock = (struct FileLock *)BADDR(FlatPacket -> dp_Arg1);
/* Try to find the corresponding list entry. */
if(FlatNode = FindFlatNodeByID(FileLock -> fl_Key))
{
/* Only shared locks may be duplicated. *