Skip DEFER'd assigns

This forum is for general developer support questions.

Skip DEFER'd assigns

Postby mritter0 » Fri May 12, 2017 12:40 am

In my project, Workbench Explorer, it scans for all the assigns. It was brought to my attention that it does not "skip over" DEFER'd assigns; it "activates" them during the scanning process.

I don't see any way around this. Is there some other way to scan for the assigns? I am using what the AutoDocs say to use:
Code: Select all
BOOL
GetAssigns(VOID)
{
   BOOL                     Success=TRUE;
   struct Node                  *node;
   struct List                  *ADOList;
   struct DevProc               *dp=NULL;

   if ((ADOList=IDOS->AllocDosObjectTags(DOS_VOLUMELIST,
      ADO_Type,                        LDF_ASSIGNS|LDF_READ,
      ADO_AddColon,                     TRUE,
   TAG_END)))
   {
      for(node=IExec->GetHead(ADOList); node; node=IExec->GetSucc(node))
      {
         if (!(AssignsNode=(struct AssignsNode *)SAK_CreateGenericListNode(sizeof(struct AssignsNode),(STRPTR)"")))
         {
            SAK_EasyRequest(Objects[OID_WINDOW],MainWindow,RequesterTitle,REQIMAGE_ERROR,0,SAK_LocaleString(MSG_COULD_NOT_CREATE_EXEC_LIST_NODE),SAK_LocaleString(MSG_CONTINUE));
            Success=FALSE;
            break;
         }
         SAK_AddGenericListNode(MasterAssignsList,(struct Node *)AssignsNode,GLIST_BOTTOM);

         IUtility->SNPrintf(AssignsNode->Name,128,"%s",node->ln_Name);
         IUtility->SNPrintf(AssignsNode->UserData,128,"[Ass]%s",AssignsNode->Name);
         AssignsNode->IsMultiAssign=FALSE;

         while ((dp=IDOS->GetDeviceProcFlags(node->ln_Name,dp,LDF_ASSIGNS)))
         {
            if (dp->dvp_Flags & DVPB_ASSIGNMENT)
            {
               AssignsNode->IsMultiAssign=TRUE;
            }
         }
      }

      if (dp)
      {
         IDOS->FreeDeviceProc(dp);
         dp=NULL;
      }

      IDOS->FreeDosObject(DOS_VOLUMELIST,ADOList);
   }

   return(Success);
}

The while() loop checks if it is a multi-assign, then gets populated later. I have commented that section out, same thing.
Workbench Explorer - A better way to browse drawers
User avatar
mritter0
 
Posts: 184
Joined: Mon Aug 25, 2014 10:41 pm
Location: Bettendorf, IA, USA

Re: Skip DEFER'd assigns

Postby colinw » Fri May 12, 2017 5:06 am

You have it nearly right.

Firstly, GetDeviceProc() is used to identify the device handler and "other" things like resolving assignments.
If you just want a list, don't call GetDeviceProc() or anything else that will call it, otherwise it will
resolve them, so there's your problem.

As you already have your list of assignments from the IDOS->AllocDosObjectTags(DOS_VOLUMELIST, ...) call,
that's likely all you need. You can already tell what their name is and what type they are, just by looking at
the ln_Name and ln_Type value of the returned nodes, they will be the same value as the dol_Name and dol_Type
of the DosList entries they represent, (as long as you don't add the colon character).

The three types of assignment nodes you can encounter are;
a) DLT_LOCK = Normal assignments, created by the IDOS->AssignLock() function.
b) DLT_LATE = Deferred assignments, created by the IDOS->AssignLate() function.
c) DLT_NONBINDING = Non binding assignments created by the IDOS->AssignPath() function.

DLT_LOCK use a permanent lock to the object they reference.
DLT_LATE use a name to the reference object, but once they are accessed, it is converted to DLT_LOCK type.
DLT_NONBINDING use a name to the reference object, it locks and unlocks the reference on every operation.

Under normal circumstances, you would want to have assignments resolved and multi-assignments automatically
searched when you try and Open() a file or load a library or something like that, however, that's exactly
what you don't want in your application, I assume, so it will require a bit more work.

There are currently only two types of assignments that can have multi-assignments bound to them,
and only one type (DLT_LOCK) if you are not a beta tester with a V54 version of the dos.library.

So firstly, change the AllocDosObject() call tag; "ADO_AddColon,TRUE" to FALSE instead.
Then, where your while() loop is, replace it with the following code;

Code: Select all
{
   uint32 flags = LDF_ASSIGNS|LDF_READ;
   struct DosList *dl = IDOS->LockDosList(flags);

   if(( dl = IDOS->FindDosEntry(dl,node->ln_Name,flags) ))
   {
      /*
      **  Standard old multi-assignments
      */
      if( dl->dol_MultiAssignList )
      {
          AssignsNode->IsMultiAssign=TRUE;
      }

      /*
      **  Add this for V54+ compatibility with the new V54 NONBINDING multiassigns.
      */
      if( dl->dol_NBMultiAssignList )
      {
          AssignsNode->IsMultiAssign=TRUE;
      }
   }
   IDOS->UnLockDosList(flags);
}

That should do it. If you want to know where they point, you will need to walk the respective chains.

PS:
I noticed in your code, you have a "struct AssignsNode", you should be carefull and change
that so it will not accidently conflict with a "struct AssignNode" found in dos/dosextens.h
I would recommend you add an underscore, ie; Assigns_Node, or something like that, it is never
a good idea to use the O.S style cases and naming convention in private application data types.

Also, your buffer sizes should never be hard-coded in calls like SNPrintf() and friends,
always use; sizeof(AssignsNode->Name) or sizeof(AssignsNode->UserData) if they are static
buffers within the structure, otherwise use a #define MYBUFSIZE 128 or something like that
everywhere, never use hard coded constants, it's a guaranteed buffer overrun if you change
something later and forget to change all instances throughout your code.
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
 
Posts: 156
Joined: Mon Aug 15, 2011 10:20 am
Location: Brisbane, QLD. Australia.

Re: Skip DEFER'd assigns

Postby mritter0 » Fri May 12, 2017 6:03 pm

That worked! Thank you!

Just for some clarification, should I be treating DLT_NONBINDING the same as DLT_LATE? Not show it in the list of assigns? And I will have to check for v54 of dos.library before checking for this, of course. Even though I am on v53.158 and it did not error.
Workbench Explorer - A better way to browse drawers
User avatar
mritter0
 
Posts: 184
Joined: Mon Aug 25, 2014 10:41 pm
Location: Bettendorf, IA, USA

Re: Skip DEFER'd assigns

Postby colinw » Sat May 13, 2017 2:50 am

Treat them the same, (except when walking the chain of course), no version tests required.
The new type of assigns uses a previously spare NULL field in the DosList structure,
it will only be non-NULL when the new multi-assign type is encountered.
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
 
Posts: 156
Joined: Mon Aug 15, 2011 10:20 am
Location: Brisbane, QLD. Australia.


Return to General Developer Support

Who is online

Users browsing this forum: No registered users and 1 guest