home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / useful / disk / misc / flat / flat-handler.c < prev    next >
C/C++ Source or Header  |  1991-07-26  |  38KB  |  1,518 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1991 by Olaf Barthel
  4.  *
  5.  *    Name .....:    Flat-Handler.c
  6.  *    Created ..:    Saturday 11-May-91 17:55
  7.  *    Revision .:    3
  8.  *
  9.  *    Date        Author        Comment
  10.  *    =========    ========    ====================
  11.  *    26-Jul-91    Olsen        Added ACTION_COPY_DIR
  12.  *    11-Jul-91    Olsen        Minor fixes.
  13.  *    11-May-91    Olsen        Created this file!
  14.  *
  15.  * $Revision Header ********************************************************/
  16.  
  17.     /* Standard FS error types. */
  18.  
  19. enum    { ERR_WRITEPROTECT,ERR_NODISK,ERR_UNREADABLE,ERR_WRITEERROR };
  20.  
  21.     /* This is a link node used both for locks and filehandles. */
  22.  
  23. struct FlatNode
  24. {
  25.     struct FlatNode        *fn_Succ;    /* Vanilla node head. */
  26.     struct FlatNode        *fn_Pred;
  27.  
  28.     ULONG             fn_UniqueID;    /* A unique ID. */
  29.  
  30.     LONG             fn_Mode;    /* Either shared or exclusive. */
  31.  
  32.     struct DeviceNode    *fn_DevInfo;    /* Pointer to a device node,
  33.                          * needed by ExNext and the like.
  34.                          */
  35.     ULONG             fn_BlockSize;    /* Size of a block (512 bytes are standard). */
  36.     ULONG             fn_FirstBlock;    /* The first accessible block. */
  37.     ULONG             fn_NumBlocks;    /* Maximum number of available blocks. */
  38.  
  39.     LONG             fn_Position;    /* Current file position in bytes. */
  40.     struct FileLock         fn_Lock;    /* A dummy file lock. */
  41.  
  42.     UBYTE             fn_Name[40];    /* Name of this file. */
  43.  
  44.     struct MsgPort        *fn_DiskPort;    /* Driver data. */
  45.     struct IOExtTD        *fn_DiskRequest;
  46.     APTR             fn_DiskBuffer;
  47.  
  48.     BYTE             fn_CheckCount;    /* The disk state is checked
  49.                          * every tenth r/w attempt,
  50.                          * this byte keeps the count.
  51.                          */
  52. };
  53.  
  54.     /* This list keeps all the locks and filehandles. */
  55.  
  56. struct List             FlatList;
  57.  
  58.     /* Each open/lock call increments this counter to
  59.      * guarantee that each item receives a unique identifier.
  60.      */
  61.  
  62. ULONG                 UniqueCounter = 0;
  63.  
  64.     /* Shared library identifiers. */
  65.  
  66. struct ExecBase            *SysBase = NULL;
  67. struct DosLibrary        *DOSBase = NULL;
  68. struct IntuitionBase        *IntuitionBase = NULL;
  69.  
  70.     /* Prototypes for this module. */
  71.  
  72. LONG __saveds            HandlerEntry(VOID);
  73.  
  74. LONG __regargs            DoRead(struct FlatNode *FlatNode,LONG Size,UBYTE *Buffer,struct Process *Caller);
  75. LONG __regargs            DoWrite(struct FlatNode *FlatNode,LONG Size,UBYTE *Buffer,struct Process *Caller);
  76.  
  77. UBYTE * __regargs        BaseName(UBYTE *String);
  78.  
  79. UBYTE __regargs            Local2Upper(UBYTE c);
  80. UBYTE __regargs            StrCmp(UBYTE *a,UBYTE *b);
  81.  
  82. struct FlatNode * __regargs    FindFlatNodeByID(ULONG UniqueID);
  83. struct FlatNode * __regargs    FindFlatNodeByName(UBYTE *Name);
  84.  
  85. VOID __regargs            BtoCStr(UBYTE *Name,BSTR String,LONG MaxLength);
  86.  
  87. LONG __regargs            ShowRequest(APTR WindowPtr,BYTE Type,UBYTE *Drive);
  88.  
  89. struct DeviceNode * __regargs    FindDevice(struct DeviceNode *LastNode,struct FileSysStartupMsg    **Startup,struct DosEnvec **DosEnvec,UBYTE *Name);
  90.  
  91. VOID __regargs            DeleteNode(struct FlatNode *FlatNode);
  92. struct FlatNode * __regargs    CreateNode(LONG Type,UBYTE *Name);
  93.  
  94. VOID __regargs            ReturnPacket(struct DosPacket *Packet,ULONG Res1,ULONG Res2,struct Process *HandlerProc);
  95. struct DosPacket * __regargs    WaitPacket(struct Process *HandlerProc);
  96.  
  97.     /* HandlerEntry():
  98.      *
  99.      *    Entry point for this module.
  100.      */
  101.  
  102. LONG __saveds
  103. HandlerEntry()
  104. {
  105.     struct Process            *HandlerProc;
  106.  
  107.     struct FileHandle        *FileHandle;
  108.     struct FileLock            *FileLock;
  109.  
  110.     LONG                 ReadBytes,WriteBytes,Bytes;
  111.     LONG                 NewPosition;
  112.     struct FileInfoBlock        *FileInfo;
  113.     UBYTE                *FileName;
  114.     UBYTE                 NameBuffer[257];
  115.  
  116.     struct DosPacket        *FlatPacket;
  117.     struct DeviceNode        *FlatDevNode;
  118.  
  119.     struct FlatNode            *FlatNode;
  120.  
  121.         /* Set up SysBase. */
  122.  
  123.     SysBase = *(struct ExecBase **)4;
  124.  
  125.         /* Know who we are. */
  126.  
  127.     HandlerProc = (struct Process *)SysBase -> ThisTask;
  128.  
  129.         /* Started from Shell (oops!)? */
  130.  
  131.     if(!HandlerProc -> pr_CLI)
  132.     {
  133.             /* Wait for startup packet. */
  134.  
  135.         FlatPacket = WaitPacket(HandlerProc);
  136.  
  137.             /* Clear the list. */
  138.  
  139.         NewList(&FlatList);
  140.  
  141.             /* Pick up the pointer to our DeviceNode. */
  142.  
  143.         FlatDevNode = (struct DeviceNode *)BADDR(FlatPacket -> dp_Arg3);
  144.  
  145.             /* Install ourselves at the other hand. */
  146.  
  147.         FlatDevNode -> dn_Task = &HandlerProc -> pr_MsgPort;
  148.  
  149.             /* Open DOS; we are not making DOS calls but
  150.              * rather use the base to scan for block-
  151.              * mapped devices.
  152.              */
  153.  
  154.         if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
  155.         {
  156.             ReturnPacket(FlatPacket,DOSFALSE,FlatPacket -> dp_Res2,HandlerProc);
  157.             goto FallOff;
  158.         }
  159.  
  160.             /* Open Intuition; we might want to put up
  161.              * auto-requesters.
  162.              */
  163.  
  164.         if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
  165.         {
  166.             ReturnPacket(FlatPacket,DOSFALSE,FlatPacket -> dp_Res2,HandlerProc);
  167.             goto FallOff;
  168.         }
  169.  
  170.             /* Initialization finished, now return the
  171.              * startup packet.
  172.              */
  173.  
  174.         ReturnPacket(FlatPacket,DOSTRUE,FlatPacket -> dp_Res2,HandlerProc);
  175.  
  176.             /* Go into loop waiting for data packets. */
  177.  
  178.         FOREVER
  179.         {
  180.                 /* Wait for packet. */
  181.  
  182.             FlatPacket = WaitPacket(HandlerProc);
  183.  
  184.                 /* Examine the packet type. */
  185.  
  186.             switch(FlatPacket -> dp_Type)
  187.             {
  188.                     /* Obtain a filelock. */
  189.  
  190.                 case ACTION_LOCATE_OBJECT:
  191.  
  192.                         /* Convert the file name. */
  193.  
  194.                     BtoCStr(NameBuffer,FlatPacket -> dp_Arg2,256);
  195.  
  196.                         /* Are we to return a lock
  197.                          * to a file or a lock to the
  198.                          * root directory?
  199.                          */
  200.  
  201.                     if(FileName = BaseName(NameBuffer))
  202.                     {
  203.                             /* Look for a file of this name. */
  204.  
  205.                         if(FlatNode = FindFlatNodeByName(FileName))
  206.                         {
  207.                                 /* See if the file is currently locked. */
  208.  
  209.                             if((FlatNode -> fn_Mode != FlatPacket -> dp_Arg3) || (FlatPacket -> dp_Arg3 == EXCLUSIVE_LOCK && FlatNode -> fn_Mode == EXCLUSIVE_LOCK))
  210.                             {
  211.                                 ReturnPacket(FlatPacket,DOSFALSE,ERROR_OBJECT_IN_USE,HandlerProc);
  212.                                 break;
  213.                             }
  214.                         }
  215.  
  216.                             /* Create a new item and add it to the list. */
  217.  
  218.                         if(FlatNode = CreateNode(FlatPacket -> dp_Arg3,FileName))
  219.                         {
  220.                             AddTail(&FlatList,(struct Node *)FlatNode);
  221.  
  222.                                 /* Initialize the default data so DOS will
  223.                                  * get along with us.
  224.                                  */
  225.  
  226.                             FlatNode -> fn_Lock . fl_Access    = FlatPacket -> dp_Arg3;
  227.                             FlatNode -> fn_Lock . fl_Task    = &HandlerProc -> pr_MsgPort;
  228.                             FlatNode -> fn_Lock . fl_Volume    = MKBADDR(FlatDevNode);
  229.                             FlatNode -> fn_Lock . fl_Key    = FlatNode -> fn_UniqueID;
  230.  
  231.                             FlatPacket -> dp_Res1 = MKBADDR(&FlatNode -> fn_Lock);
  232.  
  233.                             strcpy(FlatNode -> fn_Name,FileName);
  234.  
  235.                             ReturnPacket(FlatPacket,FlatPacket -> dp_Res1,FlatPacket -> dp_Res2,HandlerProc);
  236.                         }
  237.                         else
  238.                             ReturnPacket(FlatPacket,DOSFALSE,ERROR_OBJECT_NOT_FOUND,HandlerProc);
  239.                     }
  240.                     else
  241.                     {
  242.                         if(FlatNode = CreateNode(FlatPacket -> dp_Arg3,NULL))
  243.                         {
  244.                             AddTail(&FlatList,(struct Node *)FlatNode);
  245.  
  246.                             FlatNode -> fn_Lock . fl_Access    = FlatPacket -> dp_Arg3;
  247.                             FlatNode -> fn_Lock . fl_Task    = &HandlerProc -> pr_MsgPort;
  248.                             FlatNode -> fn_Lock . fl_Volume    = MKBADDR(FlatDevNode);
  249.                             FlatNode -> fn_Lock . fl_Key    = FlatNode -> fn_UniqueID;
  250.  
  251.                             FlatPacket -> dp_Res1 = MKBADDR(&FlatNode -> fn_Lock);
  252.  
  253.                             ReturnPacket(FlatPacket,FlatPacket -> dp_Res1,FlatPacket -> dp_Res2,HandlerProc);
  254.                         }
  255.                         else
  256.                             ReturnPacket(FlatPacket,DOSFALSE,ERROR_OBJECT_NOT_FOUND,HandlerProc);
  257.                     }
  258.  
  259.                     break;
  260.  
  261.                     /* Free a lock obtained above. */
  262.  
  263.                 case ACTION_FREE_LOCK:
  264.  
  265.                         /* Is the lock part of the list? */
  266.  
  267.                     if(FlatPacket -> dp_Arg1)
  268.                     {
  269.                         if(FlatNode = FindFlatNodeByID(((struct FileLock *)BADDR(FlatPacket -> dp_Arg1)) -> fl_Key))
  270.                         {
  271.                             Remove((struct Node *)FlatNode);
  272.  
  273.                             DeleteNode(FlatNode);
  274.                         }
  275.                     }
  276.  
  277.                     FlatPacket -> dp_Res1 = DOSTRUE;
  278.  
  279.                     ReturnPacket(FlatPacket,FlatPacket -> dp_Res1,FlatPacket -> dp_Res2,HandlerProc);
  280.  
  281.                     break;
  282.  
  283.                     /* Duplicate a shared lock. */
  284.  
  285.                 case ACTION_COPY_DIR:
  286.  
  287.                         /* Make sure a ZERO lock gives
  288.                          * a more or less valid return
  289.                          * code.
  290.                          */
  291.  
  292.                     FlatPacket -> dp_Res1 = 0;
  293.                     FlatPacket -> dp_Res2 = 0;
  294.  
  295.                         /* Are we to duplicate a non-ZERO lock? */
  296.  
  297.                     if(FlatPacket -> dp_Arg1)
  298.                     {
  299.                         FileLock = (struct FileLock *)BADDR(FlatPacket -> dp_Arg1);
  300.  
  301.                             /* Try to find the corresponding list entry. */
  302.  
  303.                         if(FlatNode = FindFlatNodeByID(FileLock -> fl_Key))
  304.                         {
  305.                                 /* Only shared locks may be duplicated. *