Windows recognizes a few different types of storage: Fixed, CD/DVD, Removable, Network, and Ram Disk. Let’s take a look at what each of those mean:
– Fixed: A hard drive (HDD, SSD, or hybrid) drive that is physically attached to the motherboard. It is a permanent storage on the computer. Most of the time your operating system is installed on a fixed drive.
– CD/DVD: Removable storage where data is read from and stored on a CD/DVD drive.
– Removable: an SD card, USB stick, or otherwise easily removable hard drive.
– Network: a drive that is located on a different computer and is shared via ethernet.
– RAM Disk: a drive that is located on a memory stick that is volatile.
While programming in Legato, there are a few different functions that allow us to interact with drive volumes so that we can get information about the drives themselves. These functions are as follows:
– GetVolumeType : Gets an integer defined in the Legato and Windows SDK that refers to the type of volume that is passed to the function. We talked about the different types that can be returned in the previous paragraph.
– GetVolumeSerialNumber: Gets the serial number of the volume.
– GetVolumeLabel: Gets the label of the volume. This is equivalent to the name for a mapped network drive.
– GetVolumeSize: Gets the total size as a qword (unsigned 64-bit number).
– GetVolumeFreeSpace: Gets the free space of a volume as a qword (unsigned 64-bit number).
– DoesVolumeSupportHidden: Returns a boolean reflecting if the volume supports hidden files and folders.
– DoesVolumeSupportRecycling: Returns a boolean reflecting if the volume supports sending files to the recycle bin when deleted. If false, any files deleted are instantly deleted rather than being sent to the recycling bin.
– DoesVolumeSupportWriting: Returns a boolean reflecting if the volume is able to be written to. Most of the time this should be true except for in the case of CDs that are not blank and in a CD-RW drive or other removable media that have physical locks.
All of these functions are “read only”, as in they return information about the drive rather writing to it. I’ve created a short script that shows off all of these functions. It runs through all of the current drives on your computer and gives you a readout of all of the available information about the drives. The readout should be similar to the following:
Drive Name Serial Type Volume Size Free Space Hidden Recycle Writing
----- ----------------------- --------- --------- ------------------ ------------------ ------ ------- -------
[C] (untitled) CC03-9F5A Fixed 262,967,128,064 93,477,847,040 True True True
[D] Development 260D-7C5C Fixed 261,618,659,328 250,750,894,080 True True True
[E] HRM_CCSA_X64FRE_EN-US_DV5 F091-03F7 CD/DVD 3,581,853,696 0 True False False
[F] (untitled) D0F7-89D2 Removable 16,091,439,104 2,933,473,280 True False True
[L] Library B025-489F Network 2,000,243,650,560 616,431,173,632 True False True
[P] joshua.kwiatkowski B025-489F Network 2,000,243,650,560 616,431,173,632 True False True
[Q] QA B025-489F Network 2,000,243,650,560 616,431,173,632 True False True
[R] Development B025-489F Network 2,000,243,650,560 616,431,173,632 True False True
[S] Support B025-489F Network 2,000,243,650,560 616,431,173,632 True False True
[T] Transfer B025-489F Network 2,000,243,650,560 616,431,173,632 True False True
You can see the two local volumes on my computer, which are actually two partitions on the same drive. I’ve then plugged in a USB and a CD into my computer, and then you can see the network drives that are mapped for me. Some quick things to note: Recycle is true for the two local drives, but false for network and removable drives so anything that gets deleted from these volumes is just instantly gone. The other interesting fact is that the only volume that is not able to be written to is the CD, which can be a common occurrence depending on the media in the drive.
Let’s take a look at the script:
//
// Demonstrate Drive Volume Functions
// ----------------------------------
//
// Rev 05/25/2018
//
// (c) Novaworks, LLC
//
string v_drive, v_name, v_serial; // Volume Information
string v_size, v_free, v_type; // Volume Information
string v_hidden, v_recycle, v_writing; // Volume Information
qword size, free; // 64-Bit Size Values
int type; // Drive Type
string s1; // General
int dl; // Drive Letter
int rc; // Return Code
AddMessage("Drive Name Serial Type Volume Size Free Space Hidden Recycle Writing");
AddMessage("----- ----------------------- --------- --------- ------------------ ------------------ ------ ------- -------");
dl = 'A';
// Loop through drive letters
while (dl <= 'Z') {
s1 = FormatString("%c:\\", dl);
type = GetVolumeType(s1);
if (IsError(type)) { // Invalid type, does not exist
dl++;
continue;
}
v_serial = GetVolumeSerialNumber(s1);
if (v_serial == "") { // Device not ready
dl++;
continue;
}
v_type = "(unknown)"; // English volume type
switch (type) {
case DRIVE_REMOVABLE:
v_type = "Removable";
break;
case DRIVE_FIXED:
v_type = "Fixed";
break;
case DRIVE_REMOTE:
v_type = "Network";
break;
case DRIVE_CDROM:
v_type = "CD/DVD";
break;
case DRIVE_RAMDISK:
v_type = "Ram Disk";
break;
}
v_drive = FormatString("[%c]", dl); // Volume label
v_name = GetVolumeLabel(s1);
if (v_name == "") {
v_name = "(untitled)";
}
size = GetVolumeSize(s1); // Sizes, formatted
v_size = FormatString("%a", size);
free = GetVolumeFreeSpace(s1);
v_free = FormatString("%a", free);
v_hidden = "False";
if (DoesVolumeSupportHidden(s1)) {
v_hidden = "True";
}
v_recycle = "False";
if (DoesVolumeSupportRecycling(s1)) {
v_recycle = "True";
}
v_writing = "False";
if (DoesVolumeSupportWriting(s1)) {
v_writing = "True";
}
// Add to log, move on
AddMessage("%3s %-25s %-12s %-10s %20s %20s %-6s %-7s %-7s", v_drive, v_name, v_serial, v_type, v_size, v_free, v_hidden, v_recycle, v_writing);
dl++;
}
This is a fairly simple script, but let’s examine what we’re doing in greater detail. First we create a bunch of variables where we’re going to store all of the information that we’re retrieving. Then we create our header in the message log. Since this is just a quick and dirty script, we’re not doing anything fancy with the output, just putting it in the default Legato message log.
string v_drive, v_name, v_serial; // Volume Information
string v_size, v_free, v_type; // Volume Information
string v_hidden, v_recycle, v_writing; // Volume Information
qword size, free; // 64-Bit Size Values
int type; // Drive Type
string s1; // General
int dl; // Drive Letter
int rc; // Return Code
AddMessage("Drive Name Serial Type Volume Size Free Space Hidden Recycle Writing");
AddMessage("----- ----------------------- --------- --------- ------------------ ------------------ ------ ------- -------");
Afterwards, we set our drive letter (dl) to ‘A’. We can do this because chars and ints are interchangeable. In this case we’re setting dl to 65, the ASCII table equivalent of ‘A’. We start a loop checking from ‘A’ to ‘Z’. In each iteration of the loop, we transform our int dl into a string, and then check to see if we can get the drive type of that volume with the GetVolumeType function. If there is an error returned, it means that the drive does not exist and we should just continue our loop with the next letter. Next, we can retrieve the serial number with the GetVolumeSerialNumber function. If there is no serial number with the volume, again we should simply continue our loop.
dl = 'A';
// Loop through drive letters
while (dl <= 'Z') {
s1 = FormatString("%c:\\", dl);
type = GetVolumeType(s1);
if (IsError(type)) { // Invalid type, does not exist
dl++;
continue;
}
v_serial = GetVolumeSerialNumber(s1);
if (v_serial == "") { // Device not ready
dl++;
continue;
}
Next we take a switch statement to the drive type in order to get a string for reporting. This is done so that we can print an understandable English term to the log. The cases here are definitions corresponding to integer codes in Legato and the Windows SDK.
v_type = "(unknown)"; // English volume type
switch (type) {
case DRIVE_REMOVABLE:
v_type = "Removable";
break;
case DRIVE_FIXED:
v_type = "Fixed";
break;
case DRIVE_REMOTE:
v_type = "Network";
break;
case DRIVE_CDROM:
v_type = "CD/DVD";
break;
case DRIVE_RAMDISK:
v_type = "Ram Disk";
break;
}
After that, we can perform a few more statements and put the output into strings, including getting the volume’s size with the GetVolumeSize function and getting its free space with the GetFreeSpace function. We can also check the drives’s label with the GetVolumeLabel function. If there is no label for a volume, we put in a string to show that the label is untitled. This looks better than just printing out a blank space for the name.
v_drive = FormatString("[%c]", dl); // Volume label
v_name = GetVolumeLabel(s1);
if (v_name == "") {
v_name = "(untitled)";
}
size = GetVolumeSize(s1); // Sizes, formatted
v_size = FormatString("%a", size);
free = GetVolumeFreeSpace(s1);
v_free = FormatString("%a", free);
The following code translates boolean return values into meaningful text. The DoesVolumeSupportHidden, DoesVolumeSupportRecycling, and DoesVolumeSupportWriting functions all return boolean values. We need strings of “True” or “False”, so we set the string to “False” by default, and if any of these function return as TRUE, we change the string value to “True”.
v_hidden = "False";
if (DoesVolumeSupportHidden(s1)) {
v_hidden = "True";
}
v_recycle = "False";
if (DoesVolumeSupportRecycling(s1)) {
v_recycle = "True";
}
v_writing = "False";
if (DoesVolumeSupportWriting(s1)) {
v_writing = "True";
}
Finally we print the information out and increment our counter. Once the loop breaks, we’re done with the script.
// Add to log, move on
AddMessage("%3s %-25s %-12s %-10s %20s %20s %-6s %-7s %-7s", v_drive, v_name, v_serial, v_type, v_size, v_free, v_hidden, v_recycle, v_writing);
dl++;
}
And there is our script that prints out all of the information available on the drive volumes on your machine. Having all of this information available allows us to better understand where we can save files or what happens when we ask files to be deleted. This allows us to create smarter interfaces when it comes to interacting with a user’s machine. So keep on creating your Grumpy Cat memes and know that your creations will be saved thanks to storage devices attached to your computer.
Joshua Kwiatkowski is a developer at Novaworks, primarily working on Novaworks’ cloud-based solution, GoFiler Online. He is a graduate of the Rochester Institute of Technology with a Bachelor of Science degree in Game Design and Development. He has been with the company since 2013. |
Additional Resources
Novaworks’ Legato Resources
Legato Script Developers LinkedIn Group
Primer: An Introduction to Legato