Finding the storage card path on WM6

后端 未结 8 658
我在风中等你
我在风中等你 2021-01-03 00:33

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?

相关标签:
8条回答
  • Can't add a comment on the TreeUK and ctacke discusion below :

    This isn't guaranteed to find a Storage Card - many devices mount built-in flash in teh same way, and it would show up in this list as well. – ctacke May 8 at 18:23
    This has worked well for me on HTC and Psion devices. What devices are you aware this doesn't work on? Would be worth seeing if there's another attribute you can discount the build in flash memory with. – TreeUK May 9 at 22:29

    To give a idea on a Motorola MC75 (used to be SymboL), i used this piece (of native) code :

        WIN32_FIND_DATA cardinfo;
    HANDLE  card = FindFirstFlashCard(&cardinfo);
    if (card != INVALID_HANDLE_VALUE)
    {
        TCHAR existFile[MAX_PATH];
    
        wprintf(_T("found : %s\n"), cardinfo.cFileName);
    
        while(FindNextFlashCard(card, &cardinfo))
        {
            wprintf(_T("found : %s\n"), cardinfo.cFileName);
        }
    }
    FindClose(card);
    

    Debug output :

    cardinfo.dwFileAttributes   0x00000110  unsigned long int
    cardinfo.cFileName          "Application"   wchar_t[260]
    
    cardinfo.dwFileAttributes   0x00000110  unsigned long int
    cardinfo.cFileName          "Cache Disk"    wchar_t[260]
    
    cardinfo.dwFileAttributes   0x00000110  unsigned long int
    cardinfo.cFileName          "Storage Card"  wchar_t[260]
    

    The "Application" and "Cache disk" are internal Flash drives. The "Storage Card" a removable SD Card. All are marked as a FlashDrive (which they are), but only "Storage Card" is removable.

    0 讨论(0)
  • 2021-01-03 01:05

    There's a pure C# way to do this without native calls.

    Taken from here.

    //codesnippet:06EE3DE0-D469-44DD-A15F-D8AF629E4E03
    public string GetStorageCardFolder()
    {
       string storageCardFolder = string.Empty;
       foreach (string directory in Directory.GetDirectories("\\"))
       {
           DirectoryInfo dirInfo = new DirectoryInfo(directory);
    
           //Storage cards have temporary attributes do a bitwise check.
            //http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=612136&SiteID=1
            if ((dirInfo.Attributes & FileAttributes.Temporary) == FileAttributes.Temporary)
                storageCardFolder = directory;
        }
    
        return storageCardFolder;
    }
    
    0 讨论(0)
  • 2021-01-03 01:11

    On Windows CE 5 (which is the base for Windows Mobile 6) the storage cards get mounted at the root file system as "Storage Card\", "Storage Card2\", etc.

    To find out if it's mounted call GetFileAttributes (or the remote version CeGetFileAttributes I believe) passing in the full path ("\Storage Card\"). If it returns INVALID_FILE_ATTRIBUTES then it's not mounted, otherwise check to make sure it's a directory before returning true.

    0 讨论(0)
  • 2021-01-03 01:12

    Keep in mind that "\Storage Card" is english oriented. A device made for a different region may have a different name. The name of the storage card path on my device varies with how I am using the device.

    Some time ago in the MSDN forms I responded to a few questions on how to detect the storage cards in the file system and how does one get the storage card's capacity. I wrote the following could are a response to those questions and thought it would be helpful to share. Storage cards show up in the file system as temporary directories. This program examines the objects in the root of the device and any folders that have temp attribute are considered to be a positive match

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    
    namespace StorageCardInfo
    {
        class Program
        {
            const ulong Megabyte = 1048576;
            const ulong Gigabyte = 1073741824;
    
            [DllImport("CoreDLL")]
            static extern int GetDiskFreeSpaceEx(
            string DirectoryName,
            out ulong lpFreeBytesAvailableToCaller,
            out ulong lpTotalNumberOfBytes,
            out ulong lpTotalNumberOfFreeBytes 
        );
    
        static void Main(string[] args)
        {
            DirectoryInfo root = new DirectoryInfo("\\");
            DirectoryInfo[] directoryList = root.GetDirectories();
            ulong FreeBytesAvailable;
            ulong TotalCapacity;
            ulong TotalFreeBytes;
    
            for (int i = 0; i < directoryList.Length; ++i)
            {
                if ((directoryList.Attributes & FileAttributes.Temporary) != 0)
                {
                    GetDiskFreeSpaceEx(directoryList.FullName, out FreeBytesAvailable, out TotalCapacity, out TotalFreeBytes);
                    Console.Out.WriteLine("Storage card name: {0}", directoryList.FullName);
                    Console.Out.WriteLine("Available Bytes : {0}", FreeBytesAvailable);
                    Console.Out.WriteLine("Total Capacity : {0}", TotalCapacity);
                    Console.Out.WriteLine("Total Free Bytes : {0}", TotalFreeBytes);
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-03 01:13

    I post here the code that I use to get the mount dirs of the storage cards. The part where I get the flash cards paths is copied from Sibly's post with a few changes.

    The main difference is in that I search through the mount dirs of all the flash cards and I keep the one(s) that match the default storage card name that I read from windows' registry.

    It solves the problem that one has on motorola's smart devices where there are multiple flash cards and only one sd card reader whose mount dir's name can change from the default by the numeric suffix (ie. in english WM systems: 'Storage Card' , 'Storage Card2' and so on). I tested it on some motorola models (MC75, MC75A, MC90, MC65) with WM 6.5 english.

    This solution should work well with different windows mobile's languages but I don't know if it can deal with those that change the default name of the storage cards. It all depends whether the device's manufacturer updates the windows registry with the new default name.

    It would be great if you can test it on different WMs or devices. Feedback is welcome.

       //
       // the storage card is a flash drive mounted as a directory in the root folder 
       // of the smart device
       //
       // on english windows mobile systems the storage card is mounted in the directory "/Storage Card", 
       // if that directory already exists then it's mounted in "/Storage Card2" and so on
       //
       // the regional name of the mount base dir of the storage card can be found in
       // the registry at [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\Folder]
       //  
       // in order to find the path of the storage card we look for the flash drive that starts 
       // with the base name
       //
    
       public class StorageCard
       {
          private StorageCard()
          {
          }
    
          public static List<string> GetMountDirs()
          {
             string key = @"HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory";
             string storageCardBaseName = Registry.GetValue(key, "Folder", "Storage Card") as String;
             List<string> storageCards = new List<string>();
             foreach (string flashCard in GetFlashCardMountDirs())
             {
                string path = flashCard.Trim();
                if (path.StartsWith(storageCardBaseName))
                {
                   storageCards.Add(path);
                }
             }
             return storageCards;
          }
    
          private static List<string> GetFlashCardMountDirs()
          {
             List<string> storages = new List<string>();
    
             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))
                   {
                      storages.Add(findData.cFileName);
                      storages.Add(findData.cAlternateFileName);
                   }
                }
                while (FindNextFlashCard(handle, ref findData));
                FindClose(handle);
             }
    
             return storages;
          }
    
          private static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);    
    
          [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
          private 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)]
          private struct FILETIME
          {
             public int dwLowDateTime;
             public int dwHighDateTime;
          };
    
          [DllImport("note_prj", EntryPoint = "FindFirstFlashCard")]
          private extern static IntPtr FindFirstFlashCard(ref WIN32_FIND_DATA findData);
    
          [DllImport("note_prj", EntryPoint = "FindNextFlashCard")]
          [return: MarshalAs(UnmanagedType.Bool)]
          private extern static bool FindNextFlashCard(IntPtr hFlashCard, ref WIN32_FIND_DATA findData);
    
          [DllImport("coredll")]
          private static extern bool FindClose(IntPtr hFindFile);
       }
    
    0 讨论(0)
  • 2021-01-03 01:14

    I have combined a number of the solutions above, particularly qwlice's code, to find SD cards on a range of devices. This solution finds SD cards only (so excludes all of the internal "storage cards" that some devices have) without using native dll calls.

    The code searches the HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\ key for keys containing "SD" as the name varies slightly on some devices, finds the default mount dir and then looks for temp directories that start with this. This means that it will find \StorageCard2, \StorageCard3, etc.

    I have been using this on a range of Intermec and Motorola/Symbol devices and haven't had any problems. Here is the code below:

    public class StorageCardFinder
    {
        public static List<string> GetMountDirs()
        {
            //get default sd card folder name
            string key = @"HKEY_LOCAL_MACHINE\System\StorageManager\Profiles";
            RegistryKey profiles = Registry.LocalMachine.OpenSubKey(@"System\StorageManager\Profiles");
            string sdprofilename = profiles.GetSubKeyNames().FirstOrDefault(k => k.Contains("SD"));
            if (sdprofilename == null)
                return new List<string>();
    
            key += "\\" + sdprofilename;
            string storageCardBaseName = Registry.GetValue(key, "Folder", "Storage Card") as String;
            if (storageCardBaseName == null)
                return new List<string>();
    
            //find storage card
            List<string> cardDirectories = GetFlashCardMountDirs();
    
            List<string> storageCards = new List<string>();
            foreach (string flashCard in GetFlashCardMountDirs())
            {
                string path = flashCard.Trim();
                if (path.StartsWith(storageCardBaseName))
                {
                    storageCards.Add("\\" + path);
                }
            }
            return storageCards;
        }
    
        private static List<string> GetFlashCardMountDirs()
        {
            DirectoryInfo root = new DirectoryInfo("\\");
            return root.GetDirectories().Where(d => (d.Attributes & FileAttributes.Temporary) != 0)
                                        .Select(d => d.Name).ToList();
        }
    }
    
    0 讨论(0)
提交回复
热议问题