Detecting Storage of Modern Smartphones
I got my Nexus 4 few weeks ago. It has no micro-SD card slot, but this is not a rant about the lack of storage scalability. When you plug modern smartphones into a Windows machine, you’ll get a Portable Device label. What does it mean? It’s technically not a Removable Device.

Display of drives and devices connected to the computer
Please do note that this is not only a case for modern smartphones. Same applies for different devices such as portable media players (MP3 players, etc.)
The problem with this is, the device is not treated as a drive, so codes like this won’t show information about such devices.
foreach (DriveInfo dinfo in DriveInfo.GetDrives())
{
Console.WriteLine(dinfo.RootDirectory);
}
Based on the above image, this code will only output:
C:\ D:\ E:\ F:\ G:\ H:\
It would be so much pain if I will be writing an automated process application that does something with the smartphone’s storage. But there must be a way, right?
If you are using VS, this will help you, open up your reference manager, and add these COM references.

Portable Device API
But there’s another problem. This will only detect one device. Luckily we can edit the assembly, but first set Embed Interop Assembly on both interops to False

Embed Interop Assemblies
Now, go to your project’s folder, and navigate to
. Make sure the assemblies are inside that folder. Copy the full path, and open up Developer Command Prompt for VSXXXX where XXXX is your VS version.

Developer Command Prompt
Change the working directory to the path you copied earlier, and using ildasm, disassemble Interop.PortableDeviceApiLib.dll.
ildasm Interop.PortableDeviceApiLib.dll /out:papi.il
The MSIL Disassembler is a companion tool to the MSIL Assembler (Ilasm.exe). Ildasm.exe takes a portable executable (PE) file that contains Microsoft intermediate language (MSIL) code and creates a text file suitable as input to Ilasm.exe.
We’ve just disassembled Interop.PortableDeviceApiLib.dll, and now you can edit it with your favorite text editor. This is the line we’re looking for:
GetDevices([in][out] string& marshal( lpwstr)
We need to change every occurrence of that to:
GetDevices([in][out] string[] marshal(lpwstr[])
Short Explanation: We just changed the first parameter’s data type from a string reference, to an array of strings. This way, we can retrieve many devices.
Lastly, re-assemble the interop:
ilasm papi.il /dll /output="<obj Path>\Interop.PortableDeviceApiLib.dll"
For the code:
uint devNum = 1;
PortableDeviceManagerClass devM = new PortableDeviceManagerClass();
devM.GetDevices(null, ref devNum);
if (devNum > 0)
{
string[] dId = new string[devNum];
devM.GetDevices(dId, ref devNum);
for (int dx = 0; dx < devNum; dx++)
{
Console.WriteLine("Device " + dx + 1 + " : " + dId[dx]);
}
}
It will output lines like:
Device 1 : \\?\usb#vid_18d1&pid_4ee2&mi_00#6&68a019c&1&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}
You can then use \\?\usb#vid_18d1&pid_4ee2&mi_00#6&68a019c&1&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}, copy it and paste it on explorer’s address bar. Works like charm!


