Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Drive Detection and Drive Information

Moderators: larsivi kris

Posted: 02/09/08 23:50:34

Im new to D and Tango, and just wrote my first project for it and I like it.

I have a larger project comming up and I was thinking of useing D. My primary problem is that I need detect disk changes and get information about the disk, ie volume name, serial, ect.. Basicly I need to detect removable media and need to beable to tell which disk is which.. I also wish to be windows\linux\bsd\osX? portable....

Any suggestion?

I'm currently messing with this code...

//Disk.d module Disk;

import tango.io.Stdout;

import tango.io.FileRoots?;

import tango.core.Thread;

auto running = true;

void main() {

auto listRunner = new Thread(&list);

listRunner.start();

while(running)

Thread.sleep(60);

}

void list() {

static uint driveMask;

while(running) {

foreach(drive; FileRoots?.list())

Stdout(drive).newline;

Thread.getThis.sleep(5);

}

}

Author Message

Posted: 02/10/08 01:50:19 -- Modified: 02/10/08 01:59:50 by
wyverex -- Modified 2 Times

This is what I got..

module Disk;

import tango.io.Stdout;
import tango.io.Console;
import tango.io.FileRoots;
import tango.core.Thread;

//main running varible
auto running = true;

void main()
{
	//listen for disk change
	auto listRunner = new Thread(&list);
	//listen for user input
	auto watchRunner = new Thread(&watch);
	
	//msg
	Stdout("Press any key to quit...").newline;
	
	//start listeners
	listRunner.start();
	watchRunner.start();
	
	//keep looping but dont eat up resources
	while(running)
		Thread.sleep(5);
	
	//msg
	Stdout("Exiting...").newline;
}


void list()
{
	char[][] known;	//disks we know we have
	char[][] roots;	//disks we found
	bool fnd;		//tmp 
	
	//while program running
	while(running)
	{
		//get Roots
		roots = FileRoots.list();
		
		//for each root find all not in known
		foreach(i; roots)
		{	
			//not found, yet
			fnd = false;
			//for all known
			foreach(j; known)
			{	//okay we know about this root
				if (i == j)	
				{	//mark it found
					fnd = true;
					//stop looping
					break;
				}
			}
			//hey was not found this is new!
			if(!fnd)
				Stdout(i)(" was inserted..").newline;
		}
		
		//now search all known to find removed disks
		foreach(i; known)
		{
			//not found, yet
			fnd = false;
			//for all current roots
			foreach(j; roots)
			{	//is same?
				if (i == j)	
				{	//okay found it, not removed
					fnd = true;
					break;
				}
			}
			//didn't find it, must be removed!
			if(!fnd)
				Stdout(i)(" was removed..").newline;
		}
				
		//update known
		known = roots;
		//sleep
		Thread.getThis.sleep(2);	
	}
}

void watch()
{
	char[] command;
	//get input, this blocks! (it better!)
	Cin.readln(command);
	
	//maybe should lock this, not that bad in this example
	// worse case, main loop drops out while threads still running
	// OS 'should' clean this up..
	running = false;
	Stdout("Shutting Down").newline;
}

Heres a sample run on windows (yes I have a lot of disks)

Press any key to quit...           
A:\ was inserted..                 
C:\ was inserted..                 
D:\ was inserted..                 
F:\ was inserted..                 
S:\ was inserted..                 
T:\ was inserted..                 
W:\ was inserted..                 
X:\ was inserted..                 
Y:\ was inserted..                 
E:\ was inserted..                 
E:\ was removed..                  
E:\ was inserted..                 
E:\ was removed..                  
                                   
Shutting Down                      
Exiting...                         

Ubuntu 7.04

Press any key to quit...
/ was inserted..
/proc was inserted..
/sys was inserted..
/var/run was inserted..
/var/lock was inserted..
/proc/bus/usb was inserted..
/dev was inserted..
/dev/shm was inserted..
/dev/pts was inserted..
/lib/modules/2.6.20-16-generic/volatile was inserted..
/home was inserted..
/proc/sys/fs/binfmt_misc was inserted..
/media/FLASH DRIVE was inserted..
/media/FLASH DRIVE was removed..
/media/FLASH DRIVE was inserted..

Shutting Down
Exiting...

What I need to know what kind of volume a disk is, name, and serial number of the disk. Or am I better of using API's?

Posted: 02/10/08 09:29:33

Hi wyverex!

I am not sure FileRoots is what you want for this task, and neither if there is a very portable way to do it. What you see for both Windows and Linux, is the mounted file systems. On Windows this is commonly a disk, but in a networked environment you may also list mounted network shares.

And as you see, on Linux there are a quite a few mounts that really are services used by the operating systems or various system applications. It would probably be useful in that respect to be able to filter out only non-system filesystems, possibly fstab should have been used instead of mtab.

However, the above doesn't really give you disks and info about them, for this you will probably have to use other methods. If a portable API can be presented on top of such information, then we may discuss the possible inclusion of it in Tango.