View Single Post
Old 20 July 2021, 02:39   #5
Warty
Registered User
 
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 301
Here's the final code if anyone is looking for same thing in the future.

The flow is simple:
- Folder_PopulateVolumeList() iterates through DOSBase->dl_Root->rn_Info
- For each item it finds that is a volume, it is going to create a "file" object in my code, and then try to do 2 things:
- 1) find out what the device name (DH0:, DF0:, etc.) is. It calls General_FindMatchingDeviceName() to do this (see below)
- 2) it tries to classify the object as a floppy, RAM disk, Hard Drive, or CD-ROM. The logic should be pretty obvious. If you were going to be very complete, you'd want to add handling for other devices.
- General_FindMatchingDeviceName() takes a task, and then scans through the DOS list again, this time looking for items of type Device. For each of those, it compares to the task, and when they match, then that's the device info for the passed volume (task).


Code:
// populate the folder's List by iterating through the DOS List objects and treating each as a folder/file
boolean Folder_PopulateVolumeList(WB2KFolderObject* the_folder)
{
	// tricky stuff based on code from https://forum.amiga.org/index.php?topic=73225.0

	// reset panel's file count, as we will be starting over from zero
	the_folder->file_count_ = 0;

	// get the DOS list and iterate through it
	struct DosInfo*		the_dos_info = (struct DosInfo*)BADDR(DOSBase->dl_Root->rn_Info);
	struct DeviceList*	the_device_list;
	struct DeviceList*	this_volume = NULL;
	
	Forbid();

	for(the_device_list = (struct DeviceList *)BADDR(the_dos_info->di_DevInfo) ;
		the_device_list != NULL ;
		the_device_list = (struct DeviceList *)BADDR(the_device_list->dl_Next))
	{
		if(the_device_list->dl_Type == DLT_VOLUME)
		{
			// NOTE: the_device_list->dl_Name is a BSTR!
			unsigned char	path_buffer[FILE_MAX_PATHNAME_SIZE];
			unsigned char*	the_path_buffer = path_buffer;
			unsigned char*	this_name = (char*)BADDR(the_device_list->dl_Name);
			unsigned char*	volume_name = this_name + 1;
			unsigned char*	the_device_name;
			unsigned char*	the_driver_name;
		
			General_Strlcpy(the_path_buffer, volume_name, FILE_MAX_PATHNAME_SIZE);
			General_Strlcat(the_path_buffer, ":", FILE_MAX_PATHNAME_SIZE);

			// we have volume name, need to get a device name that matches up to the volume name, and also get the device type
			if (General_FindMatchingDeviceName(the_dos_info, the_device_list->, &the_device_name, &the_driver_name) == false)
			{
				LOG_ERR(("Folder_PopulateVolumeList %d: Could not find a device name for volume '%s'", __LINE__, the_path_buffer));
				return false;
			}
			
			//DEBUG_OUT(("Folder_PopulateVolumeList %d: device name '%s', driver name '%s'", __LINE__, the_device_name, the_driver_name));
			
			// now we can make a file object, we'll sort out device type and device name shortly
			WB2KFileObject* this_file = File_New(volume_name, the_path_buffer, the_device_name, true, the_folder->icon_rport_, 0, the_device_list->dl_VolumeDate);

			if (this_file == NULL)
			{
				LOG_ERR(("Folder_PopulateVolumeList %d: Could not allocate memory for file object for '%s'", __LINE__, volume_name));
				goto error;
			}
			
			// finally, set the file type
			// RAMdisk vs all others: RAMdisk will not have a device process; Amiga RAM Disks are always named "Ram Disk", regardless of language
			if (Strnicmp((STRPTR)this_file->file_name_, (STRPTR)RAM_DISK_NAME, FILE_MAX_FILENAME_SIZE) == 0)
			{
				this_file->file_type_ = global_app->file_type_db_->disk_ram_filetype_;
			}
			else
			{
				File_DetermineDriveType(this_file, the_driver_name);
			}
						
			// Add this file to the list of files
			WB2KList* the_new_item = List_NewItem((void*)this_file);
			List_AddItem(the_folder->list_, the_new_item);
			the_folder->file_count_++;
		}
	}
	
	Permit();

	//DEBUG
	//DEBUG_OUT(("Folder_PopulateVolumeList %d: file list:", __LINE__));
	//List_Print(the_folder->list_, &File_Print);
	
	return true;

error:
	return false;
}

Code:
// iterates through device list, looking for devices who dvi_Task matches the passed device list task. if found, sets the device name and driver name
boolean General_FindMatchingDeviceName(struct DosInfo* the_dos_info, struct MsgPort* the_device_list_task, unsigned char** the_device_name, unsigned char** the_driver_name)
{
	struct DevInfo*		dvi;
	boolean				found_device = false;

	for (dvi = (struct DevInfo *)BADDR(the_dos_info->di_DevInfo) ;
		dvi != NULL ;
		dvi = (struct DevInfo *)BADDR(dvi->dvi_Next))
	{
		if (dvi->dvi_Type == DLT_DEVICE && dvi->dvi_Task == the_device_list_task)
		{
			UBYTE*	name = BADDR(dvi->dvi_Name);
			int		name_len = name[0];
			struct FileSysStartupMsg*	fssm;
			
			fssm = BADDR(dvi->dvi_Startup);

			if (TypeOfMem(fssm) && (APTR)fssm > (APTR)1000)
			{
				UBYTE*		driver_name = BADDR(fssm->fssm_Device);
				int			driver_name_len = driver_name[0];
				
				driver_name++;
				*the_driver_name = General_StrlcpyWithAlloc(driver_name, driver_name_len + 1);
				//DEBUG_OUT(("General_FindMatchingDeviceName %d: found device driver name '%s'", __LINE__, *the_driver_name));
			}
							
			name++;
			*the_device_name = General_StrlcpyWithAlloc(name, name_len + 1);
			//DEBUG_OUT(("General_FindMatchingDeviceName %d: found device name '%s'", __LINE__, *the_device_name));
			
			found_device = true;
			break;
		}
	}

	return (found_device);
}
Warty is offline  
 
Page generated in 0.07749 seconds with 11 queries