Skip DEFER'd assigns

This forum is for general developer support questions.
Post Reply
User avatar
mritter0
Posts: 214
Joined: Mon Aug 25, 2014 9:41 pm
Location: Bettendorf, IA, USA

Skip DEFER'd assigns

Post by mritter0 »

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
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 207
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: Skip DEFER'd assigns

Post by colinw »

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
mritter0
Posts: 214
Joined: Mon Aug 25, 2014 9:41 pm
Location: Bettendorf, IA, USA

Re: Skip DEFER'd assigns

Post by mritter0 »

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
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 207
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: Skip DEFER'd assigns

Post by colinw »

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.
Post Reply