Is there an easy way to find the storage card\'s path on a Windows Mobile device when there is a storage card and a bluetooth ftp connection?
I've found using the FindFirstFlashCard/FindNextFlashCard APIs to be more reliable than enumerating directories and checking the temporary flag (which will return bluetooth shared folders for example).
The following sample application demonstrates how to use them and the required P/Invoke statements.
using System;
using System.Runtime.InteropServices;
namespace RemovableStorageTest
{
class Program
{
static void Main(string[] args)
{
string removableDirectory = GetRemovableStorageDirectory();
if (removableDirectory != null)
{
Console.WriteLine(removableDirectory);
}
else
{
Console.WriteLine("No removable drive found");
}
}
public static string GetRemovableStorageDirectory()
{
string removableStorageDirectory = null;
WIN32_FIND_DATA findData = new WIN32_FIND_DATA();
IntPtr handle = IntPtr.Zero;
handle = FindFirstFlashCard(ref findData);
if (handle != INVALID_HANDLE_VALUE)
{
do
{
if (!string.IsNullOrEmpty(findData.cFileName))
{
removableStorageDirectory = findData.cFileName;
break;
}
}
while (FindNextFlashCard(handle, ref findData));
FindClose(handle);
}
return removableStorageDirectory;
}
public static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);
// The CharSet must match the CharSet of the corresponding PInvoke signature
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct WIN32_FIND_DATA
{
public int dwFileAttributes;
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public int nFileSizeHigh;
public int nFileSizeLow;
public int dwOID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
[StructLayout(LayoutKind.Sequential)]
public struct FILETIME
{
public int dwLowDateTime;
public int dwHighDateTime;
};
[DllImport("note_prj", EntryPoint = "FindFirstFlashCard")]
public extern static IntPtr FindFirstFlashCard(ref WIN32_FIND_DATA findData);
[DllImport("note_prj", EntryPoint = "FindNextFlashCard")]
[return: MarshalAs(UnmanagedType.Bool)]
public extern static bool FindNextFlashCard(IntPtr hFlashCard, ref WIN32_FIND_DATA findData);
[DllImport("coredll")]
public static extern bool FindClose(IntPtr hFindFile);
}
}
The mount point is usually "\Storage Card" but can be localized into other languages or modified by OEMs (some devices use "\SD Card" or other mount points, and some devices support mounting multiple storage media). The best way to enumerate the available cards is to use FindFirstFlashCard and FindNextFlashCard.
Both functions fill in a WIN32_FIND_DATA structure. The most important field is cFileName, which will contain the path to the card's mount point (e.g. "\Storage Card").
Note that the device's internal memory will also be enumerated by these functions. If you only care about external volumes, ignore the case where cFileName is an empty string ("").
Using these functions require you to #include <projects.h> and link with note_prj.lib. Both are included in the Windows Mobile SDKs for WM 2000 and later.