home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / disk / Devs+Handler / proc / source / Proc-Handler.c < prev    next >
C/C++ Source or Header  |  1995-06-24  |  42KB  |  1,774 lines

  1. /****************************************************************************
  2.                                Proc-Handler
  3.                             (c) 1994 Jan Kautz
  4.  
  5.  
  6. You may use this Source-Code for anything you want, if you don't remove the
  7. copyright and if you mention my name.
  8.  
  9. ****************************************************************************/
  10.  
  11. #include <libraries/dos.h>
  12. #include <libraries/dosextens.h>
  13. #include <libraries/filehandler.h>
  14. #include <libraries/multiuser.h>
  15. #include <devices/serial.h>
  16. #include <devices/timer.h>
  17. #include <exec/memory.h>
  18. #include <proto/multiuser.h>
  19. #include <proto/exec.h>
  20. #include <proto/dos.h>
  21.  
  22.  
  23. /*
  24. so?: static and global Vars, ok ?
  25. */
  26.  
  27. /*************************** Debugging ****************************/
  28.  
  29. /*
  30. #define TEST_HANDLER
  31. */
  32.  
  33.  
  34. #ifdef TEST_HANDLER
  35. #define bug WriteString
  36. #define D(x) (x)
  37. #else
  38. #define D(x) ;
  39. #endif /* TEST_HANDLER */
  40.  
  41. /*************************** Other Things *************************/
  42.  
  43.  
  44. #define WORKBENCH
  45.  
  46.  
  47. /*************************** ProtoTypes ***************************/
  48.  
  49. VOID SendPacketToDOS( struct DosPacket * );
  50. VOID SetPacket( struct DosPacket *packet, ULONG res1, ULONG res2 );
  51. VOID GetName( char *bcpl_str, char *newstr );
  52. VOID ConvBSTRtoASTR( char *bstr, char *astr );
  53. VOID ConvASTRtoBSTR( char *str );
  54. char *ConvertStrToFileName( char * );
  55. VOID CopyBSTR( char *bstr1, char *bstr2 );
  56. void HandleDosMessage( struct DosPacket *, struct DeviceNode * );
  57. void InsertLock( struct MyFileLock * );
  58. void WriteString( char *str, ... );
  59. void FillFIB( struct FileInfoBlock *Fib, struct Proc *proc, struct Proc *nextproc );
  60. void InitPrivateList( void );
  61. struct Proc *DupProc( struct Proc *proc );
  62. struct Proc *FindParent( struct Proc *proc );
  63. struct Proc *FindByTypeOrName( struct Proc *father, char *name, long dirtype );
  64. struct Proc *FindEntry( struct MyFileLock *lck, char *name );
  65. struct Proc *FindEntry_Proc( struct Proc *lckpr, char *name );
  66. void FreeList( struct Proc *proc );
  67. struct Proc *MakeList( struct Proc *father );
  68. struct MyHandler *MakeFile( struct Proc * );
  69. void DeleteAFile( struct Proc *, struct DosPacket *mypkt );
  70.  
  71. void act_FindInput( struct DosPacket *mypkt );
  72. void act_End( struct DosPacket *mypkt );
  73. void act_Read( struct DosPacket *mypkt );
  74. void act_Seek( struct DosPacket *mypkt );
  75. void act_Parent( struct DosPacket *mypkt, struct DeviceNode *mynode );
  76. void act_Lock( struct DosPacket *mypkt, struct DeviceNode *mynode );
  77. void act_UnLock( struct DosPacket *mypkt );
  78. void act_DupLock( struct DosPacket *mypkt );
  79. void act_Examine( struct DosPacket *mypkt );
  80. void act_ExNext( struct DosPacket *mypkt );
  81. void act_Delete( struct DosPacket *mypkt );
  82. void act_Is_FileSystem( struct DosPacket *mypkt );
  83. void act_Die( struct DosPacket *mypkt, struct DeviceNode *mynode );
  84. void act_DiskInfo( struct DosPacket *mypkt, struct DeviceNode * );
  85. void act_Info( struct DosPacket *mypkt, struct DeviceNode * );
  86. void act_Default( struct DosPacket *mypkt );
  87.  
  88. /*************************** Defines *******************************/
  89.  
  90. #define AbsExecBase 4L
  91. #define DOS_FALSE  0L
  92. #define DOS_TRUE  -1L
  93. #define RES2      mypkt->dp_Res2
  94. #define toBCPL( a_ptr ) ( ( ULONG )( a_ptr ) >> 2 )
  95.  
  96. /**************** Constants and Definitions ************************/
  97.  
  98. struct MyFileLock
  99. {
  100.    BPTR mfl_Link;
  101.    struct Proc *mfl_Proc;            /* ist pointer auf Proc-Struktur */
  102.    LONG mfl_Access;
  103.    struct MsgPort *mfl_Task;
  104.    BPTR mfl_Volume;
  105.  
  106. /* own extensions */
  107.    struct Proc *mfl_ProcDir;        /* ProcDir: Pointer auf ersten in Liste */
  108. };
  109.  
  110. /* Reihenfolge muss identisch sein!!!! */
  111. enum { DIR_MAIN= 1, DIR_PROCESS, DIR_PORT, DIR_SCREEN, DIR_WINDOW,
  112.          DIR_DEVICE, DIR_LIBRARY, DIR_INTERRUPT, DIR_RESOURCE };
  113. enum { ENTRY_OF_MAIN = 129, ENTRY_OF_PROCESS, ENTRY_OF_PORT, ENTRY_OF_SCREEN, ENTRY_OF_WINDOW,
  114.          ENTRY_OF_DEVICE, ENTRY_OF_LIBRARY, ENTRY_OF_INTERRUPT, ENTRY_OF_RESOURCE };
  115.  
  116. struct Proc
  117. {
  118.     long proc_Type;        /* DIR_SCREEN, DIR_WINDOW, .., ENTRY_OF_SCREEN, .. */
  119.     char proc_Name[108];    /* if DIR_...: nothing, if ENTRY_OF_... name of
  120.                                     entry of proc_Type, used for read, lock, ... */
  121.     char proc_Comment[80];
  122.     void *proc_Next;        /* Next Entry */
  123.     void *proc_Data;        /* ptr to data in ENTRY_OF_... */
  124.     long proc_Flag;        /* no semantics defined for this! */
  125. };
  126.  
  127. struct MyHandler
  128. {
  129.     char *mh_Mem;                
  130.     LONG mh_Pos;
  131.     LONG mh_Len;
  132. };
  133.  
  134. struct PList
  135. {
  136.     struct PList *pl_Next;
  137.     char pl_Name[108];
  138.     long pl_Type;
  139. };
  140.  
  141. /**************** Global Variables *********************************/
  142.  
  143. struct ExecBase *SysBase;
  144. struct muBase *muBase;
  145. struct IntuitionBase *IntuitionBase;
  146. struct InfoData *IData;
  147. struct DeviceList *VNode;
  148. struct Process *ThisProc;
  149. struct MsgPort *ThisPort;
  150. struct DeviceNode *InfoNode;
  151. BPTR HeaderLock = 0;
  152. BPTR fh;
  153. char DevName[40];
  154.  
  155. struct Proc ProcMain =
  156. {
  157.     DIR_MAIN,
  158.     "PROC",
  159.     "\0",
  160.     0,
  161.     0
  162. };
  163.  
  164. struct PList *PListMain = 0;
  165.  
  166. /**************** Functions ****************************************/
  167.  
  168. /* MUST BE THE FIRST FUNCTION !!!! */
  169.  
  170. VOID __saveds ProcHandler( VOID ) 
  171. {
  172.     struct DosPacket *packet;
  173.     struct DeviceNode *mynode;
  174.     char convname[40];
  175.  
  176.     SysBase = *((struct ExecBase **) AbsExecBase); /* `open' exec.library */
  177.     DOSBase = (struct DosLibrary *)OpenLibrary( "dos.library", 0 );
  178.     IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 0 );
  179.     muBase = (struct muBase *)OpenLibrary("multiuser.library", 39);
  180.  
  181.  
  182.     if( !SysBase || !DOSBase || !IntuitionBase ) return;
  183.  
  184.     #ifdef TEST_HANDLER
  185.         /*    fh = Open( "raw:0/11/640/89/Handler-Window", MODE_NEWFILE );
  186.          does not work, but I don't know why! */
  187.  
  188.         fh = *((BPTR *) 0);
  189.         if( !fh ) return;        /* no window is open! */
  190.     #endif
  191.  
  192.     ThisProc = (struct Process *)FindTask( 0 );
  193.     ThisPort = &ThisProc->pr_MsgPort;
  194.  
  195.     packet = WaitPkt();
  196.     mynode = BADDR( packet->dp_Arg3 );
  197.  
  198.  
  199.     mynode->dn_Task = ThisPort;
  200.  
  201.     /* -> Wird auch auf der Workbench sichtbar :) */
  202. #ifdef WORKBENCH
  203.     mynode->dn_Type = DLT_VOLUME;
  204. #endif
  205.  
  206.  
  207.     CopyBSTR( BADDR( mynode->dn_Name ), convname );
  208.     ConvBSTRtoASTR( convname, DevName );
  209.  
  210.     /* now allocate some mem, etc... */
  211.  
  212.     InitPrivateList();
  213.  
  214.     D(bug( "Name of dev: %s\n ", DevName ) );
  215.  
  216.     SetPacket( packet, DOS_TRUE, packet->dp_Res2 );
  217.     SendPacketToDOS( packet );
  218.  
  219.     while( TRUE )
  220.     {
  221.        if (packet = WaitPkt())
  222.              HandleDosMessage( packet, mynode );
  223.     }
  224. }
  225.  
  226. void HandleDosMessage( struct DosPacket *mypkt, struct DeviceNode *mynode )
  227. {
  228.     D(bug( "%d: ", mypkt->dp_Type ) );
  229.  
  230.     switch( mypkt->dp_Type )
  231.     {
  232.         case ACTION_FINDINPUT:
  233.             act_FindInput( mypkt );
  234.             SendPacketToDOS( mypkt );
  235.             break;
  236.  
  237.         case ACTION_END:
  238.             act_End( mypkt );
  239.             SendPacketToDOS( mypkt );
  240.             break;
  241.  
  242.         case ACTION_READ:
  243.             act_Read( mypkt );
  244.             SendPacketToDOS( mypkt );
  245.             break;
  246.  
  247.         case ACTION_SEEK:
  248.             act_Seek( mypkt );
  249.             SendPacketToDOS( mypkt );
  250.             break;
  251.  
  252.         case ACTION_PARENT:
  253.             act_Parent( mypkt, mynode );
  254.             SendPacketToDOS( mypkt );
  255.             break;
  256.  
  257.         case ACTION_LOCATE_OBJECT:
  258.             act_Lock( mypkt, mynode );
  259.             SendPacketToDOS( mypkt );
  260.             break;
  261.  
  262.         case ACTION_FREE_LOCK:
  263.             act_UnLock( mypkt );
  264.             SendPacketToDOS( mypkt );
  265.             break;
  266.  
  267.         case ACTION_COPY_DIR:            /* = DupLock() */
  268.             act_DupLock( mypkt );
  269.             SendPacketToDOS( mypkt );
  270.             break;
  271.  
  272.         case ACTION_EXAMINE_OBJECT:
  273.             act_Examine( mypkt );
  274.             SendPacketToDOS( mypkt );
  275.             break;
  276.  
  277.         case ACTION_EXAMINE_NEXT:
  278.             act_ExNext( mypkt );
  279.             SendPacketToDOS( mypkt );
  280.             break;
  281.  
  282.         case ACTION_DELETE_OBJECT:
  283.             act_Delete( mypkt );
  284.             SendPacketToDOS( mypkt );
  285.             break;
  286.  
  287.       case ACTION_IS_FILESYSTEM:
  288.             act_Is_FileSystem( mypkt );
  289.             SendPacketToDOS( mypkt );
  290.             break;
  291.  
  292.       case ACTION_DIE:
  293.             act_Die( mypkt, mynode );
  294.             SendPacketToDOS( mypkt );
  295.             return;
  296.  
  297.         case ACTION_DISK_INFO:        /* wenn DLT_VOLUME an ist! */
  298.             act_Info( mypkt, mynode );
  299.             SendPacketToDOS( mypkt );
  300.             break;
  301.  
  302.       case ACTION_INFO:
  303.             act_Info( mypkt, mynode );
  304.             SendPacketToDOS( mypkt );
  305.             break;
  306.  
  307.  
  308.  
  309.       case ACTION_SET_PROTECT:        
  310.             act_Default( mypkt );
  311.             SendPacketToDOS( mypkt );
  312.             /*     braucht anscheinend die workbench! */
  313.             break;
  314.  
  315.         default:
  316.             act_Default( mypkt );
  317.             SendPacketToDOS( mypkt );
  318.             break;
  319.     }
  320. }
  321.  
  322.  
  323.  
  324.  
  325.  
  326. void act_FindInput( struct DosPacket *mypkt )
  327. {
  328.     char FName[120]; 
  329.     struct FileHandle *fhandle;
  330.     struct MyFileLock *lock;
  331.     struct Proc *proc;
  332.     char *name;
  333.  
  334.     fhandle = BADDR( mypkt->dp_Arg1 );
  335.     lock = BADDR( mypkt->dp_Arg2 );
  336.     name = BADDR( mypkt->dp_Arg3 );
  337.  
  338.     fhandle->fh_Port = (struct MsgPort *)DOS_FALSE;    /* error: or ThisPort ?? */
  339.     GetName( name, FName );     /* nach FName copieren */
  340.     D(bug( "FIND_INPUT: |%s|\n", FName ) );
  341.  
  342.     if( proc = FindEntry( lock, FName ) )
  343.     {
  344.         if( proc->proc_Type & 128 )    /* must be a file! */
  345.         {
  346.             fhandle->fh_Arg1 = (long)MakeFile( proc );
  347.             SetPacket( mypkt, DOS_TRUE, RES2 );
  348.         }
  349.         else
  350.         {
  351.             SetPacket( mypkt, DOS_FALSE, ERROR_OBJECT_WRONG_TYPE );
  352.         }
  353.  
  354.         FreeVec( proc );
  355.     }
  356.     else
  357.         SetPacket( mypkt, DOS_FALSE, ERROR_OBJECT_NOT_FOUND );
  358.  
  359.     D(bug( "  fh: $%x lck:$%x  arg1:$%x\n", fhandle, lock, fhandle->fh_Arg1 ) );
  360. }
  361.  
  362.  
  363. void act_End( struct DosPacket *mypkt )
  364. {
  365.     struct MyHandler *handle;
  366.  
  367.     handle = (struct MyHandler *)( mypkt->dp_Arg1 );
  368.  
  369.     D(bug( "END: $%x\n", handle ) );
  370.  
  371.     if( handle )
  372.     {
  373.         FreeVec( handle->mh_Mem );
  374.         FreeVec( handle );
  375.     }
  376.     else
  377.         SetPacket( mypkt, DOS_TRUE, RES2 );
  378.  
  379.     SetPacket( mypkt, DOS_TRUE, RES2 );
  380. }
  381.  
  382.  
  383. void act_Read( struct DosPacket *mypkt )
  384. {
  385.     struct MyHandler *handle;
  386.     ULONG length, ptr;
  387.  
  388.     handle = (struct MyHandler *)( mypkt->dp_Arg1 );
  389.     if( !handle )
  390.     {
  391.         SetPacket( mypkt, DOS_FALSE, ERROR_OBJECT_NOT_FOUND );
  392.         return;
  393.     }
  394.     ptr = mypkt->dp_Arg2;
  395.     length = mypkt->dp_Arg3;
  396.  
  397.     D(bug(  "READ: $%x len:%d ptr:$%x\n", handle, length, ptr ) );
  398.  
  399.     if( handle->mh_Pos < handle->mh_Len )    /* kann noch was gelesen werden! */
  400.     {
  401.         if( length > handle->mh_Len - handle->mh_Pos )
  402.             length = handle->mh_Len - handle->mh_Pos;
  403.  
  404.         D(bug( "  did %d bytes\n", length ) );
  405.         CopyMem( handle->mh_Mem + handle->mh_Pos, (APTR)ptr, length );
  406.         handle->mh_Pos += length;
  407.     }
  408.     else length = 0;
  409.  
  410.     SetPacket( mypkt, length, RES2 );
  411. }
  412.  
  413. void act_Seek( struct DosPacket *mypkt )
  414. {
  415.     struct MyHandler *handle;
  416.     long pos, mode, rel, oldpos;
  417.  
  418.     handle = (struct MyHandler *)( mypkt->dp_Arg1 );
  419.     if( !handle )
  420.     {
  421.         SetPacket( mypkt, DOS_FALSE, ERROR_OBJECT_NOT_FOUND );
  422.         return;
  423.     }
  424.     rel = mypkt->dp_Arg2;
  425.     mode = mypkt->dp_Arg3;
  426.     oldpos = handle->mh_Pos;
  427.  
  428.     D(bug(  "SEEK: $%x rel:%d mode:%d\n", handle, rel, mode ) );
  429.  
  430.     switch( mode )
  431.     {
  432.         case OFFSET_CURRENT:
  433.             pos = handle->mh_Pos;
  434.             break;
  435.  
  436.         case OFFSET_BEGINNING:
  437.             pos = 0;
  438.             break;
  439.  
  440.         case OFFSET_END:
  441.             pos = handle->mh_Len - 1;
  442.             break;
  443.     }
  444.  
  445.     pos += rel;
  446.  
  447.     if( pos < handle->mh_Len && pos >= 0 )
  448.     {
  449.         handle->mh_Pos = pos;
  450.         SetPacket( mypkt, oldpos, RES2 );
  451.     }
  452.     else SetPacket( mypkt, DOS_FALSE, ERROR_SEEK_ERROR );
  453. }
  454.  
  455. void act_Parent( struct DosPacket *mypkt, struct DeviceNode *mynode )
  456. {
  457.     struct MyFileLock *lock, *lck;
  458.     struct Proc *proc;
  459.  
  460.     lck = BADDR( mypkt->dp_Arg1 );
  461.     proc = (struct Proc *)lck->mfl_Proc;
  462.  
  463.     D(bug(  "PARENT: $%x, proc:$%x type:%d\n", lck, proc, proc->proc_Type ) );
  464.  
  465.     if( lck && proc->proc_Type != DIR_MAIN )
  466.     {
  467.         if( !( lock = AllocVec( sizeof( struct MyFileLock ), MEMF_CLEAR ) ) )
  468.         {
  469.             SetPacket( mypkt, DOS_FALSE, ERROR_NO_FREE_STORE );
  470.               return;
  471.           }
  472.           InsertLock( lock );
  473.  
  474.         lock->mfl_ProcDir = 0;
  475.         lock->mfl_Proc    = FindParent( proc );
  476.         lock->mfl_Access  = ACCESS_READ; 
  477.           lock->mfl_Task    = ThisPort;
  478.           lock->mfl_Volume  = toBCPL( mynode );
  479.  
  480.         D(bug(  "  newl: $%x\n", lock ) );
  481.  
  482.         SetPacket( mypkt, toBCPL( lock ), RES2 );
  483.     }
  484.     else
  485.     {
  486.         RES2 = 0;
  487.         SetPacket( mypkt, 0, RES2 );
  488.     }
  489. }
  490.  
  491.  
  492. void act_Lock( struct DosPacket *mypkt, struct DeviceNode *mynode )
  493. {
  494.     char FName[120]; 
  495.     struct MyFileLock *lock, *lck;
  496.     char debugstr[258];
  497.     char *name;
  498.     ULONG mode;
  499.     struct Proc *key;
  500.  
  501.  
  502.     lck = BADDR( mypkt->dp_Arg1 );    /* Dir, where to search */
  503.     name = BADDR( mypkt->dp_Arg2 );
  504.     mode = mypkt->dp_Arg3;
  505.     ConvBSTRtoASTR( name, debugstr );
  506.  
  507.     GetName( name, FName );
  508.  
  509.     D(bug( "LOCK: $%x |%s|->|%s|\n", lck, debugstr, FName ) );
  510.  
  511.     /* error:
  512.     if( mode & ACCESS_WRITE )
  513.     {
  514.         SetPacket( mypkt, DOS_FALSE, ERROR_WRITE_PROTECTED );
  515.         return;
  516.     }
  517.     */
  518.  
  519.     if( key = FindEntry( lck, FName ) )
  520.     {
  521.         if( !( lock = AllocVec( sizeof( struct MyFileLock ), MEMF_CLEAR ) ) )
  522.         {
  523.             SetPacket( mypkt, DOS_FALSE, ERROR_NO_FREE_STORE );
  524.             return;
  525.         }
  526.  
  527.         D(bug(  "   Found: $%x, name:|%s|, type:%d\n", lock,
  528.                     ((struct Proc *)key)->proc_Name, ((struct Proc *)key)->proc_Type ) );
  529.  
  530.           InsertLock( lock );
  531.  
  532.         lock->mfl_Proc  = key;
  533.         lock->mfl_Access = mode;        /* so?: must be ACCESS_READ */
  534.           lock->mfl_Task = ThisPort;
  535.           lock->mfl_Volume = toBCPL( mynode );
  536.           lock->mfl_ProcDir = (struct Proc *)0;
  537.         SetPacket( mypkt, toBCPL( lock ), RES2 );
  538.     }
  539.     else
  540.     {
  541.         D(bug( "  lck FALSE, object not found\n" ) );
  542.         SetPacket( mypkt, DOS_FALSE, ERROR_OBJECT_NOT_FOUND );
  543.     }
  544. }
  545.  
  546.  
  547. void act_UnLock( struct DosPacket *mypkt )
  548. {
  549.     struct MyFileLock *lock, *lck = (struct MyFileLock *)4;
  550.     struct Proc *proc;
  551.  
  552.     if( ( lock = BADDR( mypkt->dp_Arg1 ) ) )
  553.     {
  554.         D(bug( "FREE: l:$%x p:$%x pd:$%x\n", lock, lock->mfl_Proc, lock->mfl_ProcDir ) );
  555.         /*    Hier muss der von FindByTypeOrName() gefundene
  556.             Proc wieder gefreet werden    */
  557.  
  558.         proc = ((struct Proc *)lock->mfl_Proc);
  559.         D(bug( " freeing proc: $%x - t:%d\n", proc, proc->proc_Type ) );
  560.         FreeVec( proc );
  561.  
  562.  
  563.         /*    Hier muß, die proc-Liste aus lock->mfl_ProcDir
  564.             gefreet werden! */
  565.  
  566.         if( lock->mfl_ProcDir )
  567.         {
  568.             D(bug( "  procdir: $%x\n", lock->mfl_ProcDir ) );
  569.             FreeList( lock->mfl_ProcDir );
  570.         }
  571.  
  572.         Forbid();
  573.         if( (ULONG)BADDR( HeaderLock ) == (ULONG)lock )
  574.         {
  575.             HeaderLock = lock->mfl_Link;    /* DeleteLock ( Lock is Header ) */
  576.         }
  577.         else
  578.         {
  579.             lck = BADDR( HeaderLock );
  580.             while( (ULONG)BADDR( lck->mfl_Link ) != (ULONG)lock )
  581.             {
  582.                 lck = BADDR( lck->mfl_Link );
  583.                 if( !lck ) break;
  584.             }
  585.             if( lck )
  586.                 lck->mfl_Link = lock->mfl_Link; /* Neu verketten, lock auslassen */
  587.         }
  588.         FreeVec( lock );
  589.         Permit();
  590.  
  591.         if( !lck )
  592.             D(bug( "  lock:%x not found\n", lock ) );
  593.  
  594.         SetPacket( mypkt, DOS_TRUE, RES2 );
  595.     }
  596.     else
  597.         SetPacket( mypkt, DOS_FALSE, ERROR_INVALID_LOCK );
  598. }
  599.  
  600.  
  601. void act_DupLock( struct DosPacket *mypkt )
  602. {
  603.     struct MyFileLock *lock, *lck;
  604.     struct Proc *proc;
  605.  
  606.     if( ( lock = BADDR( mypkt->dp_Arg1 ) ) )
  607.     {
  608.         struct Proc *newproc;
  609.  
  610.         if( !( lck = AllocVec( sizeof( struct MyFileLock ), MEMF_CLEAR ) ) )
  611.         {
  612.             SetPacket( mypkt, DOS_FALSE, ERROR_NO_FREE_STORE );
  613.             return;
  614.         }
  615.         CopyMem( lock, lck, sizeof( struct MyFileLock ) );
  616.  
  617.         proc = ((struct Proc *)lock->mfl_Proc);
  618.         if( !( newproc = DupProc( proc ) ) )
  619.         {
  620.             SetPacket( mypkt, DOS_FALSE, ERROR_NO_FREE_STORE );
  621.             return;
  622.         }
  623.         lck->mfl_Proc = newproc;
  624.  
  625.         D(bug( "DUPLOCK: oldl:$%x pr:$%x\n    prdir:$%x newl:$%x newpr:$%x\n", lock, lock->mfl_Proc, lock->mfl_ProcDir, lck, newproc ) );
  626.  
  627.         if( lck->mfl_ProcDir )
  628.         {
  629.               lck->mfl_ProcDir = 0;   /* Pointer auf ersten in Liste */
  630.         }
  631.  
  632.           InsertLock( lck );
  633.         SetPacket( mypkt, toBCPL( lck ), RES2 );
  634.     }
  635.     else
  636.         SetPacket( mypkt, DOS_FALSE, ERROR_INVALID_LOCK );
  637. }
  638.  
  639.  
  640. void act_Examine( struct DosPacket *mypkt )
  641. {
  642.     struct MyFileLock *lock;
  643.     struct Proc *proc;
  644.     struct FileInfoBlock *Fib;
  645.  
  646.     lock = BADDR( mypkt->dp_Arg1 );
  647.     proc = (struct Proc *)lock->mfl_Proc;
  648.  
  649.     /* get FIB, fill with new things */
  650.     Fib = (struct FileInfoBlock *)BADDR( mypkt->dp_Arg2 );
  651.     FillFIB( Fib, proc, proc );
  652.  
  653.     D(bug( "EXAMINE: $%x |%s|\n", lock, Fib->fib_FileName ) );
  654.     ConvASTRtoBSTR( Fib->fib_FileName );    /* i hate BCPL */
  655.     ConvASTRtoBSTR( Fib->fib_Comment );
  656.  
  657.     if( !( proc->proc_Type & 128 ) )    /* DIR_xxx */
  658.     {
  659.         struct Proc *newproc;
  660.  
  661.         if( lock->mfl_ProcDir )                    /* schon mal examiniert! */
  662.             FreeList( lock->mfl_ProcDir );
  663.  
  664.         newproc = MakeList( proc );
  665.         Fib->fib_EntryType = (long)newproc;
  666.         lock->mfl_ProcDir = newproc;           /* Pointer auf ersten in Liste */
  667.  
  668.         D(bug( "  DIR_xxx -> Liste allokiert!\n" ) );
  669.  
  670.         if( !newproc )        /* falls irgendwas schiefgeht, bzw. NOT_IMPL. */
  671.         {
  672.             D(bug( "  Kein newproc!\n" ) );
  673.  
  674.             SetPacket( mypkt, DOS_FALSE, ERROR_NOT_IMPLEMENTED );
  675.             return;
  676.         }
  677.  
  678.         /*
  679.             Hier wurde jetzt eine Liste von Proc's (mit MakeList())
  680.             erzeugt, abhängig von proc_Type.
  681.             Diese Liste kann dann mit EX_NEXT durchgegangen
  682.             werden.
  683.             Dies hat den Vorteil, daß bei jedem neuen Dir-Read
  684.             die Daten neu gelesen werden! 
  685.             Außerdem wird diese neue proc-List in nach
  686.             lock->mfl_ProcDir geschrieben, um zum freen wieder
  687.             darauf zugreifen zu können!
  688.         */
  689.     }
  690.     else
  691.     {
  692.         ;
  693.         /* es wird ein File examiniert */
  694.         /* aber FillFIB() macht eigentlich schon alles! */
  695.         /* deshalb steht hier nichts! */
  696.     }
  697.  
  698.     SetPacket( mypkt, DOS_TRUE, RES2 );
  699. }
  700.  
  701.  
  702. void act_ExNext( struct DosPacket *mypkt )
  703. {
  704.     struct MyFileLock *lock;
  705.     struct Proc *proc, *procdir;
  706.     struct FileInfoBlock *Fib;
  707.  
  708.     lock = BADDR( mypkt->dp_Arg1 );
  709.     Fib = (struct FileInfoBlock *)BADDR( mypkt->dp_Arg2 );
  710.  
  711.     procdir = (struct Proc *)lock->mfl_Proc;
  712.     proc = (struct Proc *)Fib->fib_EntryType;
  713.  
  714.     if( procdir->proc_Type & 128 )        /* not a directory!!! */
  715.     {
  716.         SetPacket( mypkt, DOS_FALSE, ERROR_OBJECT_WRONG_TYPE );
  717.         return;        
  718.     }
  719.  
  720.     if( !proc )
  721.     {
  722.         D(bug(  "EX_NEXT: NO_MORE_ENTRIES\n" ) );
  723.         SetPacket( mypkt, DOS_FALSE, ERROR_NO_MORE_ENTRIES );
  724.         return;
  725.     }
  726.  
  727.     FillFIB( Fib, proc, proc->proc_Next );
  728.  
  729.     D(bug( "EX_NEXT: lock: $%x Fib:$%x |%s|, Proc:$%x Fl:%d\n", lock, Fib, Fib->fib_FileName, proc, proc->proc_Flag ) );
  730.  
  731.     ConvASTRtoBSTR( Fib->fib_FileName );
  732.     ConvASTRtoBSTR( Fib->fib_Comment );
  733.  
  734.     SetPacket( mypkt, DOS_TRUE, RES2 );
  735. }
  736.  
  737.  
  738. void act_Delete( struct DosPacket *mypkt )
  739. {
  740.     char FName[120]; 
  741.     struct MyFileLock *lock;
  742.     struct Proc *proc;
  743.     char *name;
  744.  
  745.     lock = BADDR( mypkt->dp_Arg1 );
  746.     name = BADDR( mypkt->dp_Arg2 );
  747.     GetName( name, FName );     /* nach FName copieren */
  748.     D(bug( "DELETE: lck:$%x |%s|\n", lock, FName ) );
  749.  
  750.     if( proc = FindEntry( lock, FName ) )
  751.     {
  752.         if( proc->proc_Type & 128 )    /* must be a file! */
  753.         {
  754.             SetPacket( mypkt, DOS_TRUE, RES2 );
  755.             DeleteAFile( proc, mypkt );
  756.         }
  757.         else
  758.         {
  759.             SetPacket( mypkt, DOS_FALSE, ERROR_OBJECT_WRONG_TYPE );
  760.         }
  761.  
  762.         FreeVec( proc );
  763.     }
  764.     else
  765.         SetPacket( mypkt, DOS_FALSE, ERROR_OBJECT_NOT_FOUND );
  766. }
  767.  
  768.  
  769. void act_Is_FileSystem( struct DosPacket *mypkt )
  770. {
  771.     D(bug( " \n" ) );
  772.     SetPacket( mypkt, DOS_TRUE, 0 );
  773. }
  774.  
  775. void act_Die( struct DosPacket *mypkt, struct DeviceNode *mynode )
  776. {
  777.     mynode->dn_Task = 0;
  778.     SetPacket( mypkt, DOS_TRUE, 0 );
  779. }
  780.  
  781. void act_Info( struct DosPacket *mypkt, struct DeviceNode *mynode )
  782. {
  783.     struct MyFileLock *lock;
  784.     struct InfoData *IData;
  785.  
  786.     lock = BADDR( mypkt->dp_Arg1 );
  787.     IData = BADDR( mypkt->dp_Arg2 );
  788.  
  789.     D(bug( "(D)INFO: $%x $%x\n", lock, IData ) );
  790.  
  791.     if( IData && lock )
  792.     {
  793.         IData->id_NumSoftErrors = 0;
  794.         IData->id_UnitNumber = 0;
  795.         IData->id_DiskState = ID_VALIDATED;
  796.         IData->id_NumBlocks = 4;
  797.         IData->id_NumBlocksUsed = 4;
  798.         IData->id_BytesPerBlock = 512;
  799.         IData->id_DiskType = ID_DOS_DISK;
  800.         IData->id_InUse = 0;
  801.         IData->id_VolumeNode = toBCPL( mynode );
  802.     }
  803.  
  804.     SetPacket( mypkt, DOS_TRUE, RES2 );
  805. }
  806.  
  807. void act_Default( struct DosPacket *mypkt )
  808. {
  809.     D(bug( " not known\n" ) );
  810.     SetPacket( mypkt, DOS_FALSE, ERROR_ACTION_NOT_KNOWN );
  811. }
  812.  
  813.  
  814.  
  815.  
  816. void InsertLock( struct MyFileLock *lock )
  817. {
  818.     Forbid();
  819.     lock->mfl_Link = HeaderLock;
  820.     HeaderLock = toBCPL( lock );    /* vorne einen Lock inserten */
  821.     Permit();
  822. }
  823.  
  824. void WriteString( char *str, ... )
  825. {
  826.     char strbuf[500];
  827.     va_list VarArgs;
  828.  
  829.     va_start( VarArgs, str );
  830.    vsprintf( strbuf, str, VarArgs );
  831.    va_end( VarArgs ); 
  832.  
  833.    Write( fh, strbuf, strlen( strbuf ) );
  834. }
  835.  
  836. void AppendData( char *ptr, char *str, ... )
  837. {
  838.     char strbuf[500];
  839.     va_list VarArgs;
  840.  
  841.     va_start( VarArgs, str );
  842.    vsprintf( strbuf, str, VarArgs );
  843.    va_end( VarArgs ); 
  844.  
  845.     strcat( ptr, strbuf );
  846. }
  847.  
  848. void FillFIB( struct FileInfoBlock *Fib, struct Proc *proc, struct Proc *nextproc )
  849. {
  850.     /* Fib muss nun abhänging von Daten-Typ und
  851.         von proc gefüllt werden! */
  852.  
  853.     strcpy( Fib->fib_FileName, proc->proc_Name );
  854.     strcpy( Fib->fib_Comment, proc->proc_Comment );
  855.  
  856.     if( proc->proc_Type & 128 )            /* file! */
  857.     {
  858.         Fib->fib_DirEntryType = -1;        /* means file */
  859.         Fib->fib_Size = 1000;
  860.         Fib->fib_NumBlocks = 2;
  861.     }
  862.     else                                            /* DIR_MAIN */
  863.     {
  864.         Fib->fib_DirEntryType = 1;            /* means dir */
  865.         Fib->fib_Size = 0;
  866.         Fib->fib_NumBlocks = 0;
  867.     }
  868.  
  869.     Fib->fib_DiskKey = 0;
  870.     Fib->fib_EntryType = (long)nextproc;    /* abuse it */
  871.     Fib->fib_Protection = FIBF_WRITE | FIBF_EXECUTE | FIBF_DELETE;    /* read only */
  872.     Fib->fib_Date.ds_Days = 0;
  873.     Fib->fib_Date.ds_Minute = 0;
  874.     Fib->fib_Date.ds_Tick = 0;
  875.  
  876.     /* hier noch die muehe machen bei ENTRY_OF_PROCESS richtig zu setzen! */
  877.  
  878.     if( proc->proc_Type == ENTRY_OF_PROCESS && muBase )
  879.     {
  880.         Fib->fib_OwnerUID = muGetTaskOwner( (struct Task *)proc->proc_Data ) >> 16;
  881.         Fib->fib_OwnerGID = muGetTaskOwner( (struct Task *)proc->proc_Data ) & 0xFFFF;
  882.     }
  883.     else
  884.     {
  885.         Fib->fib_OwnerUID = 0;
  886.         Fib->fib_OwnerGID = 0;
  887.     }
  888. }
  889.  
  890. char *NextMain( void **ptr, struct Proc *father, long *type, long *flag )
  891. {
  892.     struct PList **proc = (struct PList **)ptr;
  893.     static char name[108];
  894.  
  895.     if( *proc == 0 )
  896.     {
  897.         *proc = (struct PList *)PListMain;
  898.     }
  899.     else
  900.     {
  901.         if( !( *proc = (struct PList * )(*proc)->pl_Next ) )
  902.             return (char *)0;
  903.     }
  904.  
  905.     *type = (*proc)->pl_Type;                    /* type auch zurückgeben! */
  906.     strcpy( name, (*proc)->pl_Name );
  907.     return name;
  908. }
  909.  
  910. char *NextProcess( void **ptr, struct Proc *father, long *type, long *flag )
  911. {
  912.     struct Process **proc = (struct Process **)ptr;
  913.     static char buf[20], name[108];
  914.  
  915.     if( *proc == 0 )
  916.     {
  917.         *proc = (struct Process * )SysBase->TaskWait.lh_Head;
  918.     }
  919.     else
  920.     {
  921.         *proc = (struct Process * )(*proc)->pr_Task.tc_Node.ln_Succ;
  922.         if( !(*proc)->pr_Task.tc_Node.ln_Succ )
  923.         {
  924.             if( *flag == 0 )
  925.             {
  926.                 *flag = 1;
  927.                 *proc = (struct Process * )SysBase->TaskReady.lh_Head;
  928.  
  929.                 /* the line above doesn't work! */
  930.                 *proc = 0;
  931.                 return (char *)0;
  932.             }
  933.             else
  934.             {
  935.                 *proc = 0;
  936.                 return (char *)0;
  937.             }
  938.         }
  939.     }
  940.  
  941.     sprintf( buf, "%07x", *ptr );
  942.     strcpy( name, buf );     /* Adresse vorneweg! */
  943.     strcat( name, "_" );
  944.     strcat( name, (*proc)->pr_Task.tc_Node.ln_Name );
  945.  
  946.     *type = ENTRY_OF_PROCESS;
  947.     return name;
  948. }
  949.  
  950. char *NextExec( void **ptr, struct Proc *father, long *type, long *flag )    /* will work for all ExecLists! */
  951. {
  952.     struct Library **lib = (struct Library **)ptr;
  953.     static char name[20];
  954.  
  955.     if( *lib == 0 )
  956.     {
  957.         switch( father->proc_Type )
  958.         {
  959.             case DIR_LIBRARY:
  960.                 *lib = (struct Library * )SysBase->LibList.lh_Head;
  961.                 break;
  962.  
  963.             case DIR_INTERRUPT:
  964.                 *lib = (struct Library * )SysBase->IntrList.lh_Head;
  965.                 break;
  966.  
  967.             case DIR_PORT:
  968.                 *lib = (struct Library * )SysBase->PortList.lh_Head;
  969.                 break;
  970.  
  971.             case DIR_DEVICE:
  972.                 *lib = (struct Library * )SysBase->DeviceList.lh_Head;
  973.                 break;
  974.  
  975.             case DIR_RESOURCE:
  976.                 *lib = (struct Library * )SysBase->ResourceList.lh_Head;
  977.                 break;
  978.  
  979.             default:
  980.                 *lib = 0;
  981.                 break;
  982.         }
  983.     }
  984.     else
  985.     {
  986.         *lib = (struct Library * )(*lib)->lib_Node.ln_Succ;
  987.         if( !(*lib)->lib_Node.ln_Succ )
  988.         {
  989.             *lib = 0;
  990.             return (char *)0;
  991.         }
  992.     }
  993.  
  994.     *type = father->proc_Type | 128;        /* make an entry of ... */
  995.  
  996.     if( !(*lib)->lib_Node.ln_Name )
  997.     {
  998.         sprintf( name, "%07x", *ptr );
  999.         return name;
  1000.     }
  1001.     else
  1002.         return ConvertStrToFileName( (char *)(*lib)->lib_Node.ln_Name );
  1003. }
  1004.  
  1005. char *NextScreen( void **ptr, struct Proc *father, long *type, long *flag )
  1006. {
  1007.     struct Screen **scr = (struct Screen **)ptr;
  1008. /*    ULONG lckibase; */
  1009.  
  1010.     if( *scr == 0 )
  1011.     {
  1012. /*        if( lckibase = LockIBase( 0 ) ) { 
  1013.     the lock doesn't work :( */
  1014.  
  1015.             *scr = IntuitionBase->FirstScreen;
  1016.  
  1017. /*            UnlockIBase( lckibase ); } */
  1018.     }
  1019.     else
  1020.     {
  1021.         *scr = (*scr)->NextScreen;
  1022.     }
  1023.  
  1024.     if( !*scr ) return (char *)0;
  1025.  
  1026.     *type = DIR_WINDOW;
  1027.     return ConvertStrToFileName( (char *)(*scr)->Title );
  1028. }
  1029.  
  1030. char *NextWindow( void **ptr, struct Proc *father, long *type, long *flag )
  1031. {
  1032.     struct Screen *scr = (struct Screen *)father->proc_Data;
  1033.     struct Window **win = (struct Window **)ptr;
  1034.     static char buf[20], name[108];
  1035.  
  1036.     *type = ENTRY_OF_WINDOW;
  1037.  
  1038.     if( *flag == 0 )
  1039.     {
  1040.         *flag = 3;                            /* means 1:next be window & 2:is screeninfo */
  1041.         *win = scr->FirstWindow;        /* because it will be used to find the belonging screen */
  1042.  
  1043.         strcpy( name, "ScreenInfo" );
  1044.         return name;
  1045.     }
  1046.     else if( *flag == 3 )
  1047.     {
  1048.         *flag = 1;                            /* means this and next will be windows */
  1049.         *win = scr->FirstWindow;        /* Now show first window! */
  1050.     }
  1051.     else
  1052.     {
  1053.         *win = (*win)->NextWindow;
  1054.     }
  1055.  
  1056.     if( !*win ) return (char *)0;
  1057.  
  1058.     sprintf( buf, "%07x", *ptr );
  1059.     strcpy( name, buf );     /* Adresse vorneweg! */
  1060.     if( (*win)->Title )        /* nur wenn Titel da ist! */
  1061.     {
  1062.         /* error: hier string nach filenamen konvertieren!!! */
  1063.  
  1064.         sprintf( buf, "%.15s", ConvertStrToFileName( (*win)->Title ) );
  1065.         strcat( name, buf );
  1066.     }
  1067.  
  1068.     return (char *)name;
  1069. }
  1070.  
  1071. void FreeList( struct Proc *proc )
  1072. {
  1073.     struct Proc *dummy;
  1074.  
  1075.     while( proc )
  1076.     {
  1077.         dummy = proc->proc_Next;
  1078.         FreeVec( proc );
  1079.         proc = dummy;
  1080.     }
  1081. }
  1082.  
  1083. /* this is the Function GetNextFunctionByProc( struct Proc * )
  1084.     returning a function with void **,long as argument and returning
  1085.     a char * !!! */
  1086.  
  1087. char *( *GetNextFunctionByProc( struct Proc *father ) )( void **ptr, struct Proc *f, long *type, long *flag )
  1088. {
  1089.     switch( father->proc_Type )
  1090.     {
  1091.         case DIR_PROCESS:
  1092.             return NextProcess;
  1093.             
  1094.         case DIR_LIBRARY:
  1095.         case DIR_INTERRUPT:
  1096.         case DIR_DEVICE:
  1097.         case DIR_PORT:
  1098.         case DIR_RESOURCE:
  1099.             return NextExec;
  1100.  
  1101.         case DIR_MAIN:
  1102.             return NextMain;
  1103.  
  1104.         case DIR_SCREEN:
  1105.             return NextScreen;
  1106.  
  1107.         case DIR_WINDOW:
  1108.             return NextWindow;
  1109.  
  1110.         default:
  1111.             return 0;
  1112.     }
  1113. }
  1114.  
  1115.  
  1116. struct Proc *MakeProc( char *name, long type, void *ptr, long flag )
  1117. {
  1118.     struct Proc *proc = 0;
  1119.  
  1120.     if( !( proc = AllocVec( sizeof( struct Proc ), MEMF_CLEAR ) ) )
  1121.         return (struct Proc *)0;
  1122.  
  1123.     proc->proc_Type = type;
  1124.     proc->proc_Data = ptr;
  1125.     proc->proc_Flag = flag;
  1126.  
  1127.     strcpy( proc->proc_Name, name );
  1128.  
  1129.     /* so?: hier könnte bei Bedarf ein Kommentar gesetzt werden: 
  1130.         strcpy( proc->proc_Comment, "kommentar" );
  1131.    */
  1132.  
  1133.     return proc;
  1134. }
  1135.  
  1136. struct Proc *DupProc( struct Proc *proc )
  1137. {
  1138.     struct Proc *ret = 0;
  1139.  
  1140.     if( !proc ) proc = &ProcMain;        /* so?: should never be possible! */
  1141.  
  1142.     if( !( ret = AllocVec( sizeof( struct Proc ), MEMF_CLEAR ) ) )
  1143.         return (struct Proc *)0;
  1144.  
  1145.     CopyMem( proc, ret, sizeof( struct Proc ) );
  1146.  
  1147.     return ret;
  1148. }
  1149.  
  1150. struct Proc *MakeList( struct Proc *father )
  1151. {
  1152.     struct Proc *prochead = 0, *proc = 0;
  1153.     void *ptr = 0;
  1154.     char *name, *(*GetNextName)( void **, struct Proc *, long *, long * );
  1155.     long dtype, flag = 0;
  1156.  
  1157.     if( !(GetNextName = GetNextFunctionByProc( father )) )
  1158.         return (struct Proc *)0;
  1159.  
  1160.     while( name = (*GetNextName)( &ptr, father, &dtype, &flag ) )        /* in ptr wird Zeiger übergeben */
  1161.     {
  1162.         if( !( proc = MakeProc( name, dtype, ptr, flag ) ) ) break;
  1163.  
  1164.         if( !prochead )                    /* setzen */
  1165.         {
  1166.             prochead = proc;
  1167.         }
  1168.         else
  1169.         {
  1170.             proc->proc_Next = prochead;
  1171.             prochead = proc;
  1172.         }
  1173.     }
  1174.  
  1175.     return prochead;
  1176. }
  1177.  
  1178. struct Proc *FindParent( struct Proc *proc )
  1179. {
  1180.     long type = proc->proc_Type;
  1181.     struct Proc *dummy, *pr;
  1182.  
  1183.     if( type & 128 )    /* ENTRY_OF_... */
  1184.     {
  1185.         type = type & (~128);
  1186.  
  1187.         if( type == DIR_WINDOW )
  1188.         {
  1189.             dummy = FindByTypeOrName( &ProcMain, "\0", DIR_SCREEN );
  1190.             pr = FindByTypeOrName( dummy, ((struct Window *)proc->proc_Data )->WScreen->Title, 0 );
  1191.             FreeVec( dummy );
  1192.  
  1193.             D(bug( "Parent(ENTRY): type:%d - found:$%x t:%d\n ", type, pr, pr->proc_Type ) );    
  1194.             return pr;
  1195.         }
  1196.  
  1197.         return FindByTypeOrName( &ProcMain, "\0", type );
  1198.     }
  1199.     else
  1200.     {
  1201.         if( type == DIR_WINDOW )
  1202.         {
  1203.             pr = FindByTypeOrName( &ProcMain, "\0", DIR_SCREEN );
  1204.  
  1205.             D(bug( "Parent(DIR): type:%d - found:$%x t:%d\n ", type, pr, pr->proc_Type ) );    
  1206.             return pr;
  1207.         }
  1208.         return DupProc( &ProcMain );
  1209.     }
  1210. }
  1211.  
  1212. struct Proc *FindByTypeOrName( struct Proc *father, char *name, long subtype )
  1213. {
  1214.     struct Proc *proc = 0;
  1215.     void *ptr = 0;
  1216.     char *gotname, *(*GetNextName)( void **, struct Proc *, long *, long * );
  1217.     long dtype, flag = 0;
  1218.  
  1219.     if( *name == '/' )        /* so?: eleganter bitte!!! */
  1220.     {
  1221.         return FindParent( father );
  1222.         /* so:?    return DupProc( &ProcMain );
  1223.             frueher war's so, is wohl nix mehr, da verschachtelte dirs!
  1224.          */
  1225.     }
  1226.  
  1227.     if( !(GetNextName = GetNextFunctionByProc( father )) )
  1228.         return( struct Proc *)0;
  1229.  
  1230.     while( gotname = (*GetNextName)( &ptr, father, &dtype, &flag ) )
  1231.     {
  1232.         if( !*name )        /* Nicht by Name, sondern subtype */
  1233.         {
  1234.             if( dtype == subtype )
  1235.             {
  1236.                 proc = MakeProc( gotname, dtype, ptr, flag );
  1237.                 return proc;
  1238.             }
  1239.         }
  1240.         else
  1241.         {
  1242.             if( !stricmp( name, gotname ) )
  1243.             {
  1244.                 proc = MakeProc( name, dtype, ptr, flag );
  1245.                 return proc;
  1246.             }
  1247.         }
  1248.     }
  1249.  
  1250.     return (struct Proc *)0;
  1251. }
  1252.  
  1253. char *GetFullName( char *name )
  1254. {
  1255.     static char retname[108];
  1256.     long c = 0;
  1257.  
  1258.     for( c = 107; c >= 0; c-- ) retname[c] = 0;
  1259.     c = 0;
  1260.  
  1261.     while( *name == 0x01 ) name++;    /* HACK HACK: = schon abgearbeitet! */
  1262.  
  1263.     while( *name != '\0' )
  1264.     {
  1265.         retname[c++] = *name;
  1266.         *name++ = 0x01;            /* HACK: schon abgearbeitet! */
  1267.     }
  1268.     retname[c] = '\0';
  1269.  
  1270.     return retname;
  1271. }
  1272.  
  1273. char *GetPartName( char *name )
  1274. {
  1275.     static char retname[108];
  1276.     long c = 0;
  1277.  
  1278.     for( c = 107; c >= 0; c-- ) retname[c] = 0;
  1279.     c = 0;
  1280.  
  1281.     while( *name == 0x01 ) name++;    /* HACK HACK: = schon abgearbeitet! */
  1282.  
  1283.     if( *name == '/' )        /* so?: eins nach oben!!! */
  1284.     {
  1285.         retname[0] = '/';
  1286.         retname[1] = '\0';
  1287.         *name = 0x01;
  1288.  
  1289.         return retname;
  1290.     }
  1291.  
  1292.     while( *name != '\0' && *name != '/' )
  1293.     {
  1294.         retname[c++] = *name;
  1295.         *name++ = 0x01;            /* HACK: schon abgearbeitet! */
  1296.     }
  1297.  
  1298.     if( *name == '/' ) *name = 0x01;    /* nur bei /, sonst nicht!!! */
  1299.     retname[c] = '\0';
  1300.  
  1301.     return retname;
  1302. }
  1303.  
  1304. struct Proc *FindEntry( struct MyFileLock *lck, char *name )
  1305. {
  1306.     if( lck )
  1307.         return FindEntry_Proc( (struct Proc *)lck->mfl_Proc, name );
  1308.     else
  1309.         return FindEntry_Proc( (struct Proc *)0, name );
  1310. }
  1311.  
  1312. struct Proc *FindEntry_Proc( struct Proc *lckpr, char *name )
  1313. {
  1314.     struct Proc *proc = 0;
  1315.     struct Proc *retkey = 0;
  1316.     char partname[108];
  1317.  
  1318.     if( name && *name == '\0' ) name = 0;        /* einfacher abzufragen! */
  1319.  
  1320.     if( !lckpr )        /* nichts uebergeben -> DIR_MAIN suchen! */
  1321.     {
  1322.         if( !name || *name == '\0' )
  1323.         {
  1324.             retkey = DupProc( &ProcMain );    /* reproduce proc! */
  1325.             return retkey;
  1326.         }
  1327.     }
  1328.  
  1329.     if( lckpr && !name )        /* nochmals DIR selbst zurückgeben!!! */
  1330.     {
  1331.         retkey = DupProc( lckpr );        /* reproduce lckpr! */
  1332.         return retkey;
  1333.     }
  1334.  
  1335.         /* je nach proc_Type  */
  1336.  
  1337.         /* neuen proc allocieren für Objekt            */
  1338.         /* in proc_Type dann ENTRY_... schreiben!      */
  1339.         /* wird alles in FindByTypeOrName() erledigt! */
  1340.  
  1341.     if( !lckpr )    /* main-dir! */
  1342.     {
  1343.         lckpr = &ProcMain;
  1344.     }
  1345.  
  1346.     strcpy( partname, GetPartName( name ) );
  1347.     D(bug( "  FindEntry:part: |%s| of |%s|\n", partname, name ) );
  1348.     if( retkey = FindByTypeOrName( lckpr, partname, 0 ) )
  1349.     {
  1350.         strcpy( partname, GetFullName( name ) );
  1351.         if( *partname )    /* still sth. remaining */
  1352.         {
  1353.             D(bug( "  FindEntry:Remaining |%s|\n", partname ) );
  1354.             proc = retkey;
  1355.             retkey = FindEntry_Proc( proc, partname );
  1356.             FreeVec( proc );
  1357.         }
  1358.     }
  1359.  
  1360.     if( retkey )
  1361.     {
  1362.         D(bug( "  FindByTypeOrName(): $%x >%s<\n", retkey, retkey->proc_Name ) );;
  1363.     }
  1364.     else
  1365.     {
  1366.         D(bug( "  FindByTypeOrName(): nothing found\n" ) );;
  1367.     }
  1368.  
  1369.     return retkey;
  1370. }
  1371.  
  1372. struct MyHandler *MakeFile( struct Proc *proc )
  1373. {
  1374.     struct muUserInfo *uinfo;
  1375.     struct MyHandler *mh;
  1376.     struct Process *p;
  1377.     struct Library *l;
  1378.     struct Interrupt *i;
  1379.     struct MsgPort *mp;
  1380.     struct Screen *scr;
  1381.     struct Window *win;
  1382.     struct PList *pl;
  1383.     ULONG owner;
  1384.     char *ptr;
  1385.  
  1386.     if( !( ptr = AllocVec( 4096, MEMF_CLEAR ) ) )
  1387.         return (struct MyHandler *)0;
  1388.  
  1389.     if( !( mh = AllocVec( sizeof( struct MyHandler ), MEMF_CLEAR ) ) )
  1390.     {
  1391.         FreeVec( ptr );
  1392.         return (struct MyHandler *)0;
  1393.     }
  1394.  
  1395.     switch( proc->proc_Type )
  1396.     {
  1397.         case ENTRY_OF_PROCESS:
  1398.             p = (struct Process *)proc->proc_Data;
  1399.             AppendData( ptr, "%s: %s at $%x\n", p->pr_Task.tc_Node.ln_Type == NT_TASK ? "Task" : "Process", p->pr_Task.tc_Node.ln_Name, p );
  1400.             AppendData( ptr, "Prio: %d\n", p->pr_Task.tc_Node.ln_Pri );
  1401.             if( muBase )
  1402.             {
  1403.                 if( uinfo = muAllocUserInfo() )
  1404.                 {
  1405.                     owner = muGetTaskOwner( (struct Task *)p ) >> 16;
  1406.                     if( owner )
  1407.                     {
  1408.                         uinfo->uid = owner;
  1409.                         muGetUserInfo( uinfo, muKeyType_uid );
  1410.                         AppendData( ptr, "Owner: %s (%d)\n", uinfo->UserName, owner );
  1411.                     }
  1412.                     else
  1413.                         AppendData( ptr, "Owner: nobody\n" );
  1414.  
  1415.                     muFreeUserInfo(uinfo);
  1416.                 }
  1417.             }
  1418.             AppendData( ptr, "Stack    : $%x\n", p->pr_Task.tc_SPReg );
  1419.             AppendData( ptr, "Stacksize: $%x\n", (ULONG)p->pr_Task.tc_SPUpper - (ULONG)p->pr_Task.tc_SPLower );
  1420.             AppendData( ptr, "Signals : $%x\n", p->pr_Task.tc_SigWait );
  1421.             AppendData( ptr, "Received: $%x\n", p->pr_Task.tc_SigRecvd );
  1422.             if( p->pr_Task.tc_Node.ln_Type == NT_PROCESS )
  1423.             {
  1424.                 AppendData( ptr, "CurrentDir: $%x\n", BADDR( p->pr_CurrentDir ) );
  1425.                 AppendData( ptr, "CIS: $%x\n", BADDR( p->pr_CIS ) );
  1426.                 AppendData( ptr, "COS: $%x\n", BADDR( p->pr_COS ) );
  1427.                 AppendData( ptr, "ConsoleTask: $%x\n", p->pr_ConsoleTask );
  1428.                 AppendData( ptr, "FileSystemTask: $%x\n", p->pr_FileSystemTask );
  1429.                 AppendData( ptr, "Window: $%x\n", p->pr_WindowPtr );
  1430.             }
  1431.             break;
  1432.  
  1433.         case ENTRY_OF_LIBRARY:
  1434.         case ENTRY_OF_DEVICE:
  1435.         case ENTRY_OF_RESOURCE:
  1436.             l = (struct Library *)proc->proc_Data;
  1437.             AppendData( ptr, "%s: %s at $%x\n",
  1438.                 proc->proc_Type == ENTRY_OF_LIBRARY ? "Library" : 
  1439.                     (proc->proc_Type == ENTRY_OF_DEVICE ? "Device" : "Resource"),
  1440.                 l->lib_Node.ln_Name, l );
  1441.             AppendData( ptr, "Priori.: %d\n", l->lib_Node.ln_Pri );
  1442.             AppendData( ptr, "Version: %d.%d\n", l->lib_Version, l->lib_Revision );
  1443.             AppendData( ptr, "OpenCnt: %d\n", l->lib_OpenCnt );
  1444.             AppendData( ptr, "NegSize: %d\n", l->lib_NegSize );
  1445.             AppendData( ptr, "PosSize: %d\n", l->lib_PosSize );
  1446.             break;
  1447.  
  1448.         case ENTRY_OF_INTERRUPT:
  1449.             i = (struct Interrupt *)proc->proc_Data;
  1450.             AppendData( ptr, "Interrupt: %s at $%x\n", i->is_Node.ln_Name, i );
  1451.             break;
  1452.  
  1453.         case ENTRY_OF_PORT:
  1454.             {
  1455.                 char *mpflagstr[] = { "signal", "softint", "ignore", "action" };
  1456.  
  1457.                 mp = (struct MsgPort *)proc->proc_Data;
  1458.                 AppendData( ptr, "Port: %s at $%x\n\n", mp->mp_Node.ln_Name, mp );
  1459.  
  1460.                 AppendData( ptr, "Flags  : %s\n", mpflagstr[mp->mp_Flags] );
  1461.                 AppendData( ptr, "SigBit : %d\n", mp->mp_SigBit );
  1462.                 if( mp->mp_Flags == PA_SIGNAL    )
  1463.                     AppendData( ptr, "SigTask: %s at $%x\n", ((struct Task *)mp->mp_SigTask)->tc_Node.ln_Name, mp->mp_SigTask );
  1464.                 else if( mp->mp_Flags == PA_SOFTINT    )
  1465.                     AppendData( ptr, "SoftInt: $%x\n", mp->mp_SigTask );
  1466.             }
  1467.             break;
  1468.  
  1469.         case ENTRY_OF_SCREEN:
  1470.             scr = (struct Screen *)proc->proc_Data;
  1471.             AppendData( ptr, "You found a bug in Proc-Handler!!\nIt is not possible to get here :(\n" );
  1472.             AppendData( ptr, "Screen: \"%s\" at $%x\n", scr->Title, scr );
  1473.             break;
  1474.  
  1475.         case ENTRY_OF_WINDOW:
  1476.             win = (struct Window *)proc->proc_Data;
  1477.             if( proc->proc_Flag & 2 )    /* This here is the ScreenInfo-File in the DIR_WINDOW! */
  1478.             {
  1479.                 scr = win->WScreen;
  1480.                 AppendData( ptr, "Screen: \"%s\" at $%x\n\n", scr->Title ? (char *)scr->Title : (char *)"<no name>", scr );
  1481.  
  1482.                 AppendData( ptr, "Left : %3d  Top...: %3d\n", scr->LeftEdge, scr->TopEdge );
  1483.                 AppendData( ptr, "Width: %3d  Height: %3d\n\n", scr->Width, scr->Height );
  1484.  
  1485.                 AppendData( ptr, "WBorLeft : %3d  WBorTop...: %3d\n", scr->WBorLeft, scr->WBorTop );
  1486.                 AppendData( ptr, "WBorRight: %3d  WBorBottom: %3d\n\n", scr->WBorRight, scr->WBorBottom );
  1487.  
  1488.                 AppendData( ptr, "BarHeight: %3d  BarVBorder: %3d BarHBorder: %3d\n", scr->BarHeight, scr->BarVBorder, scr->BarHBorder );
  1489.                 AppendData( ptr, "MenuVBorder: %3d  MenuHBorder: %3d\n\n", scr->MenuVBorder, scr->MenuHBorder );
  1490.  
  1491.                 AppendData( ptr, "ViewPort: $%x\n", &scr->ViewPort );
  1492.                 AppendData( ptr, "          DWidth..: %3d  DHeight : %3d\n", scr->ViewPort.DWidth, scr->ViewPort.DHeight );
  1493.                 AppendData( ptr, "          DxOffset: %3d  DyOffset: %3d\n", scr->ViewPort.DxOffset, scr->ViewPort.DyOffset );
  1494.                 AppendData( ptr, "          Modes...: $%x\n\n", scr->ViewPort.Modes );
  1495.  
  1496.                 AppendData( ptr, "RastPort: $%x\n", &scr->RastPort );
  1497.                 AppendData( ptr, "          BitMap: $%x\n\n", scr->RastPort.BitMap );
  1498.  
  1499.                 AppendData( ptr, "Font : %s/%d\n", scr->Font->ta_Name, scr->Font->ta_YSize );
  1500.                 AppendData( ptr, "Flags: $%x\n", scr->Flags );
  1501.             }
  1502.             else
  1503.             {
  1504.                 AppendData( ptr, "Window: \"%s\"", win->Title ? (char *)win->Title : (char *)"<no name>" );
  1505.  
  1506.                 AppendData( ptr, " at $%x\n\n", win );
  1507.                 AppendData( ptr, "Left : %3d  Top...: %3d\n", win->LeftEdge, win->TopEdge );
  1508.                 AppendData( ptr, "Width: %3d  Height: %3d\n\n", win->Width, win->Height );
  1509.  
  1510.                 AppendData( ptr, "MinWidth: %3d  MinHeight: %3d\n", win->MinWidth, win->MinHeight );
  1511.                 AppendData( ptr, "MaxWidth: %3d  MaxHeight: %3d\n\n", win->MaxWidth, win->MaxHeight );
  1512.  
  1513.                 AppendData( ptr, "BorderLeft : %3d  BorderTop...: %3d\n", win->BorderLeft, win->BorderTop );
  1514.                 AppendData( ptr, "BorderRight: %3d  BorderBottom: %3d\n\n", win->BorderRight, win->BorderBottom );
  1515.  
  1516.                 AppendData( ptr, "DetailPen: %d  BlockPen: %d\n\n", win->DetailPen, win->BlockPen );
  1517.  
  1518.                 AppendData( ptr, "Flags : $%x\n", win->Flags );
  1519.                 AppendData( ptr, "IDCMP : $%x\n", win->IDCMPFlags );
  1520.             }
  1521.             break;
  1522.  
  1523.         case ENTRY_OF_MAIN:
  1524.             pl = (struct PList *)proc->proc_Data;
  1525.             if( !stricmp( pl->pl_Name, "Sysinfo" ) )
  1526.             {
  1527.                 static char *cpustr[] = { "68000", "68010", "68020", "68030", "68040" };
  1528.                 static char *fpustr[] = { "<none>", "68881", "68882", "68040" };
  1529.                 int cpuc = 0, fpuc = 0;
  1530.  
  1531.                 if( SysBase->AttnFlags & AFF_68010 ) cpuc = 1;
  1532.                 if( SysBase->AttnFlags & AFF_68020 ) cpuc = 2;
  1533.                 if( SysBase->AttnFlags & AFF_68030 ) cpuc = 3;
  1534.                 if( SysBase->AttnFlags & AFF_68040 ) cpuc = 4;
  1535.  
  1536.                 if( SysBase->AttnFlags & AFF_68881 ) fpuc = 1;
  1537.                 if( SysBase->AttnFlags & AFF_68882 ) fpuc = 2;
  1538.                 if( SysBase->AttnFlags & AFF_FPU40 ) fpuc = 3;
  1539.  
  1540.                 AppendData( ptr, "Sysinfo\n\n" );
  1541.                 AppendData( ptr, "Kickstart V%d.\n", SysBase->SoftVer );
  1542.                 AppendData( ptr, "CPU: %s  FPU: %s\n", cpustr[cpuc], fpustr[fpuc] );
  1543.                 AppendData( ptr, "Memory: ---\n" );
  1544.                 AppendData( ptr, "DMA Chip: ---\n" );
  1545.                 AppendData( ptr, "Graphic Chip: ---\n" );
  1546.             }
  1547.             else
  1548.                 AppendData( ptr, "Not supported yet!\n" );
  1549.             break;
  1550.  
  1551.         default:
  1552.             AppendData( ptr, "No data available!\n" );
  1553.             break;
  1554.     }
  1555.  
  1556.     mh->mh_Mem = ptr;
  1557.     mh->mh_Len = strlen( ptr );
  1558.     mh->mh_Pos = 0;
  1559.  
  1560.     return mh;
  1561. }
  1562.  
  1563. void DeleteAFile( struct Proc *proc, struct DosPacket *mypkt )
  1564. {
  1565.     switch( proc->proc_Type )
  1566.     {
  1567.         case ENTRY_OF_WINDOW:
  1568.             if( proc->proc_Data )
  1569.             {
  1570.                 if( proc->proc_Flag & 2 )
  1571.                 {
  1572.                     struct Screen *scr;
  1573.  
  1574.                     scr = ((struct Window *)proc->proc_Data)->WScreen;
  1575.                     if( scr->FirstWindow )
  1576.                     {
  1577.                         SetPacket( mypkt, DOS_FALSE, ERROR_DELETE_PROTECTED );
  1578.                     }
  1579.                     else
  1580.                     {
  1581.                         if( !CloseScreen( scr ) )        /* This is V36+ */
  1582.                         {
  1583.                             SetPacket( mypkt, DOS_FALSE, ERROR_DELETE_PROTECTED );
  1584.                         }
  1585.                     }
  1586.                 }
  1587.                 else     /* Window zumachen! */
  1588.                 {
  1589.                     struct MsgPort *port;
  1590.                     struct Window *win = (struct Window *)proc->proc_Data;
  1591.                     struct Requester *req;
  1592.  
  1593.                     ModifyIDCMP(win, NULL);
  1594.  
  1595.                     ClearDMRequest(win);
  1596.                     ClearMenuStrip(win);
  1597.                     ClearPointer(win);
  1598.  
  1599.                     while( req = win->FirstRequest )
  1600.                         EndRequest(req, win);
  1601.  
  1602.                     CloseWindow( win );
  1603.                 }
  1604.             }
  1605.             break;
  1606.  
  1607.         case ENTRY_OF_PROCESS:        /* do ONLY use, IF YOU KNOW WHAT YOU ARE DOING */
  1608.             if( proc->proc_Data )
  1609.             {
  1610.                 struct Task *t = (struct Task *)proc->proc_Data;
  1611.  
  1612.                 RemTask( t );
  1613.             }
  1614.             break;
  1615.  
  1616.         default:
  1617.             break;
  1618.     }
  1619. }
  1620.  
  1621. void AddEntryToPrivateList( long type, char *name )
  1622. {
  1623.     struct PList *pl = 0;
  1624.     
  1625.     pl = AllocVec( sizeof( struct PList ), MEMF_CLEAR );
  1626.     if( !pl ) return;
  1627.  
  1628.     strcpy( pl->pl_Name, name );
  1629.     pl->pl_Type = type;
  1630.     pl->pl_Next = PListMain;
  1631.  
  1632.     Forbid();
  1633.     PListMain = pl;
  1634.     Permit();
  1635. }
  1636.  
  1637. void InitPrivateList( void )
  1638. {
  1639.     strcpy( ProcMain.proc_Name, DevName );
  1640.  
  1641.     AddEntryToPrivateList( ENTRY_OF_MAIN, "Sysinfo" );    /* Last First */
  1642. /*    AddEntryToPrivateList( DIR_WINDOW, "Window" ); */
  1643. /* so?: die Windows sind nun Dirs in Screen :)    */
  1644.     AddEntryToPrivateList( DIR_SCREEN, "Screen" );
  1645.  
  1646.     AddEntryToPrivateList( DIR_RESOURCE, "Resource" );
  1647.     AddEntryToPrivateList( DIR_DEVICE, "Device" );
  1648.     AddEntryToPrivateList( DIR_LIBRARY, "Library" );
  1649.  
  1650.     AddEntryToPrivateList( DIR_PORT, "Port" );
  1651. /*    AddEntryToPrivateList( DIR_INTERRUPT, "Interrupt" ); */
  1652.     AddEntryToPrivateList( DIR_PROCESS, "Process" );
  1653. }
  1654.  
  1655. VOID SendPacketToDOS( struct DosPacket *packet )
  1656. {
  1657.     struct Message *mess;
  1658.     struct MsgPort *replyport;
  1659.     struct Process *myproc;
  1660.  
  1661.     replyport = packet->dp_Port;
  1662.     mess        = packet->dp_Link;
  1663.     myproc     = (struct Process *)FindTask( 0 );
  1664.  
  1665.     packet->dp_Port         = ThisPort;
  1666.     mess->mn_Node.ln_Name = ( char * )packet;
  1667.     mess->mn_Node.ln_Succ = NULL;
  1668.     mess->mn_Node.ln_Pred = NULL;
  1669.  
  1670.     PutMsg( replyport, mess );
  1671. }
  1672.  
  1673. VOID SetPacket( struct DosPacket *packet, ULONG res1, ULONG res2 )
  1674. {
  1675.     packet->dp_Res1 = res1;
  1676.     packet->dp_Res2 = res2;
  1677. }
  1678.  
  1679. VOID ConvASTRtoBSTR( char *str )
  1680. {
  1681.     LONG f;
  1682.     char *to = ( str + 1 );
  1683.  
  1684.     if( *str == (char)0 ) return;
  1685.  
  1686.     for( f = strlen( str ); f >= 0; f-- )
  1687.         to[ f ] = str[ f ];
  1688.     *str = strlen( str + 1 );
  1689. }
  1690.  
  1691. VOID ConvBSTRtoASTR( char *bstr, char *astr )
  1692. {
  1693.     UBYTE len;
  1694.  
  1695.     len = *bstr++;
  1696.  
  1697.     for( ; len && *bstr; len-- )
  1698.         *astr++ = *bstr++;
  1699.     *astr = '\0';
  1700. }
  1701.  
  1702. VOID CopyBSTR( char *bstr1, char *bstr2 )
  1703. {
  1704.     UBYTE len;
  1705.     len = *bstr1 + 1;
  1706.     for( ; len; len-- )
  1707.         *bstr2++ = *bstr1++;
  1708. }
  1709.  
  1710. char *ConvertStrToFileName( char *str )
  1711. {
  1712.     static char filename[100];
  1713.     int i = 0;
  1714.  
  1715.     while( i < 100 )
  1716.     {
  1717.         switch( str[i] )
  1718.         {
  1719.             case ' ':                    /* space to underscore */
  1720.                 filename[i] = '_';
  1721.                 break;
  1722.  
  1723.             case ':':
  1724.                 filename[i] = '.';
  1725.                 break;
  1726.  
  1727.             case '?':
  1728.                 filename[i] = '.';
  1729.                 break;
  1730.  
  1731.             case '#':
  1732.                 filename[i] = '.';
  1733.                 break;
  1734.  
  1735.             case '*':
  1736.                 filename[i] = '.';
  1737.                 break;
  1738.  
  1739.             default:
  1740.                 filename[i] = str[i];
  1741.                 break;
  1742.         }
  1743.  
  1744.         if( filename[i] == '\0' ) break;
  1745.  
  1746.         i++;
  1747.     }
  1748.  
  1749.     return filename;
  1750. }
  1751.  
  1752. VOID GetName( char *bcpl_str, char *newstr )
  1753. {
  1754.     UBYTE len1, len2;
  1755.     char *tester = bcpl_str + 1;
  1756.  
  1757.     len1 = len2 = *bcpl_str++;
  1758.  
  1759.     for(; len1 && *tester; len1-- )
  1760.     {
  1761.         if( *tester++ == ':' )
  1762.         {
  1763.             len2--;
  1764.             while( *bcpl_str++ != ':' ) len2--;
  1765.             break;
  1766.         }
  1767.     }
  1768.  
  1769.     for( ; len2 && *bcpl_str; len2-- )
  1770.         *newstr++ = *bcpl_str++;
  1771.  
  1772.     *newstr = '\0';
  1773. }
  1774.