home *** CD-ROM | disk | FTP | other *** search
- /************************************************************
- * MultiUser - MultiUser Task/File Support System *
- * --------------------------------------------------------- *
- * Segment Management *
- * --------------------------------------------------------- *
- * © Copyright 1993-1994 Geert Uytterhoeven *
- * All Rights Reserved. *
- ************************************************************/
-
-
- #include <exec/execbase.h>
- #include <exec/alerts.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/utility.h>
-
- #include "Memory.h"
- #include "Segment.h"
- #include "Misc.h"
- #include "Config.h"
- #include "Locale.h"
- #include "LibHeader.h"
- #include "Task.h"
-
-
- /*
- * Static Routines
- */
-
- static struct muSegNode *AddSegNode(BPTR seglist, ULONG owner);
- static void RemSegNode(struct muSegNode *snode);
- static struct muSegNode *FindSegNode(BPTR SegList);
- static struct muExtOwner *GetSegOwner(BPTR seglist);
-
-
- /*
- * Allocate and Add a Segment Node
- *
- * Make sure you have access to the list (via ObtainSemaphore(Shared))!!
- */
-
- static struct muSegNode *AddSegNode(BPTR seglist, ULONG owner)
- {
- struct muSegNode *snode;
-
- if (snode = MAlloc(sizeof(struct muSegNode))) {
- snode->SegList = seglist;
- snode->Owner.uid = (owner & muMASK_UID)>>16;
- snode->Owner.gid = owner & muMASK_GID;
- AddHead((struct List *)&muBase->SegOwnerList, (struct Node *)&snode->Node);
- }
- return(snode);
- }
-
-
- /*
- * Remove and Deallocate a Segment Node
- *
- * Make sure you have access to the list (via ObtainSemaphore(Shared))!!
- */
-
- static void __inline RemSegNode(struct muSegNode *snode)
- {
- Remove((struct Node *)&snode->Node);
- Free(snode, sizeof(struct muSegNode));
- }
-
-
- /*
- * Find the Segment Node for a given SegList
- *
- * Make sure you have access to the list (via ObtainSemaphore(Shared))!!
- */
-
- static struct muSegNode *FindSegNode(BPTR seglist)
- {
- struct MinNode *node;
- struct muSegNode *snode;
-
- for (node = muBase->SegOwnerList.mlh_Head;
- node->mln_Succ && ((snode = (struct muSegNode *)node)->SegList != seglist);
- node = node->mln_Succ);
- if (!node->mln_Succ)
- snode = NULL;
- return(snode);
- }
-
-
- /*
- * Get the owner of a Segment
- *
- * Make sure you have access to the list (via ObtainSemaphore(Shared))!!
- */
-
- static struct muExtOwner *GetSegOwner(BPTR seglist)
- {
- struct muExtOwner *owner = NULL;
- struct muSegNode *snode;
-
- ObtainSemaphoreShared(&muBase->SegOwnerSem);
- if (snode = FindSegNode(seglist))
- owner = &snode->Owner;
- ReleaseSemaphore(&muBase->SegOwnerSem);
- return(owner);
- }
-
-
- /*
- * Init Segment List
- */
-
- void InitSegList(void)
- {
- ObtainSemaphore(&muBase->SegOwnerSem);
- NewList((struct List *)&muBase->SegOwnerList);
- ReleaseSemaphore(&muBase->SegOwnerSem);
- }
-
-
- /*
- * Replacement for the dos.library LoadSeg() function
- */
-
- BPTR __asm __saveds NEWLoadSeg(register __d1 STRPTR name, register __a6 struct DosLibrary *dosbase)
- {
- BPTR fl;
- struct FileInfoBlock *fib;
- ULONG owner = muOWNER_NOBODY;
- BPTR seglist;
-
- if (name && (fl = Lock(name, ACCESS_READ))) {
- if (CheckmuFSVolume(((struct FileLock *)BADDR(fl))->fl_Task) &&
- (fib = AllocDosObject(DOS_FIB, NULL))) {
- if (Examine(fl, fib) && (fib->fib_Protection & muFIBF_SET_UID))
- owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
- FreeDosObject(DOS_FIB, fib);
- }
- UnLock(fl);
- }
- seglist = muBase->OLDLoadSeg(name, dosbase);
- if (owner & muMASK_UID) {
- ObtainSemaphore(&muBase->SegOwnerSem);
- AddSegNode(seglist, owner);
- ReleaseSemaphore(&muBase->SegOwnerSem);
- }
- return(seglist);
- }
-
-
- /*
- * Replacement for the dos.library NewLoadSeg() function
- */
-
- BPTR __asm __saveds NEWNewLoadSeg(register __d1 STRPTR name, register __d2 struct TagItem *tags,
- register __a6 struct DosLibrary *dosbase)
- {
- BPTR fl;
- struct FileInfoBlock *fib;
- ULONG owner = muOWNER_NOBODY;
- BPTR seglist;
-
- if (name && (fl = Lock(name, ACCESS_READ))) {
- if (CheckmuFSVolume(((struct FileLock *)BADDR(fl))->fl_Task) &&
- (fib = AllocDosObject(DOS_FIB, NULL))) {
- if (Examine(fl, fib) && (fib->fib_Protection & muFIBF_SET_UID))
- owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
- FreeDosObject(DOS_FIB, fib);
- }
- UnLock(fl);
- }
- seglist = muBase->OLDNewLoadSeg(name, tags, dosbase);
- if (owner & muMASK_UID) {
- ObtainSemaphore(&muBase->SegOwnerSem);
- AddSegNode(seglist, owner);
- ReleaseSemaphore(&muBase->SegOwnerSem);
- }
- return(seglist);
- }
-
-
- /*
- * Replacement for the dos.library UnLoadSeg() function
- */
-
- BOOL __asm __saveds NEWUnLoadSeg(register __d1 BPTR seglist, register __a6 struct DosLibrary *dosbase)
- {
- struct muSegNode *snode;
-
- ObtainSemaphoreShared(&muBase->SegOwnerSem);
- if (snode = FindSegNode(seglist))
- RemSegNode(snode);
- ReleaseSemaphore(&muBase->SegOwnerSem);
- return(muBase->OLDUnLoadSeg(seglist, dosbase));
- }
-
-
- /*
- * Replacement for the dos.library InternalLoadSeg() function
- */
-
- BPTR __asm __saveds NEWInternalLoadSeg(register __d0 BPTR fh, register __a0 BPTR table,
- register __a1 LONG *functionarray, register __a2 LONG *stack,
- register __a6 struct DosLibrary *dosbase)
- {
- struct FileInfoBlock *fib;
- ULONG owner = muOWNER_NOBODY;
- BPTR seglist;
-
- if (fh && CheckmuFSVolume(((struct FileHandle *)BADDR(fh))->fh_Type) &&
- (fib = AllocDosObject(DOS_FIB, NULL))) {
- if (ExamineFH(fh, fib) && (fib->fib_Protection & muFIBF_SET_UID))
- owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
- FreeDosObject(DOS_FIB, fib);
- }
- seglist = muBase->OLDInternalLoadSeg(fh, table, functionarray, stack, dosbase);
- if (owner & muMASK_UID) {
- ObtainSemaphore(&muBase->SegOwnerSem);
- AddSegNode(seglist, owner);
- ReleaseSemaphore(&muBase->SegOwnerSem);
- }
- return(seglist);
- }
-
-
- /*
- * Replacement for the dos.library InternalUnLoadSeg() function
- */
-
- BOOL __asm __saveds NEWInternalUnLoadSeg(register __d1 BPTR seglist, register __a1 void (*freefunc)(),
- register __a6 struct DosLibrary *dosbase)
- {
- struct muSegNode *snode;
-
- ObtainSemaphoreShared(&muBase->SegOwnerSem);
- if (snode = FindSegNode(seglist))
- RemSegNode(snode);
- ReleaseSemaphore(&muBase->SegOwnerSem);
-
- return(muBase->OLDInternalUnLoadSeg(seglist, freefunc, dosbase));
- }
-
-
- /*
- * Replacement for the dos.library CreateProc() function
- */
-
- struct Process __asm __saveds *NEWCreateProc(register __d1 STRPTR name, register __d2 LONG pri,
- register __d3 BPTR seglist, register __d4 LONG stacksize,
- register __a6 struct DosLibrary *dosbase)
- {
- struct muExtOwner *owner;
- struct Process *proc;
-
- if (owner = GetSegOwner(seglist))
- PushTask(SysBase->ThisTask, owner);
- proc = muBase->OLDCreateProc(name, pri, seglist, stacksize, dosbase);
- if (owner)
- PopTask(SysBase->ThisTask);
- return(proc);
- }
-
-
- /*
- * Replacement for the dos.library CreateNewProc() function
- */
-
- struct Process __asm __saveds *NEWCreateNewProc(register __d1 struct TagItem *tags,
- register __a6 struct DosLibrary *dosbase)
- {
- struct muExtOwner *owner = NULL;
- struct Process *proc;
- BPTR seglist;
-
- if (tags && (seglist = (BPTR)GetTagData(NP_Seglist, NULL, tags)) && (owner = GetSegOwner(seglist)))
- PushTask(SysBase->ThisTask, owner);
- proc = muBase->OLDCreateNewProc(tags, dosbase);
- if (owner)
- PopTask(SysBase->ThisTask);
- return(proc);
- }
-
-
- /*
- * Replacement for the dos.library RunCommand() function
- */
-
- LONG __asm __saveds NEWRunCommand(register __d1 BPTR seglist, register __d2 ULONG stacksize,
- register __d3 STRPTR argptr, register __d4 ULONG argsize,
- register __a6 struct DosLibrary *dosbase)
- {
- struct muExtOwner *owner;
- LONG rc;
-
- if (owner = GetSegOwner(seglist))
- PushTask(SysBase->ThisTask, owner);
- rc = muBase->OLDRunCommand(seglist, stacksize, argptr, argsize, dosbase);
- if (owner)
- PopTask(SysBase->ThisTask);
- return(rc);
- }
-