Созданная версия сообщения Майкла Фукаракиса (так как у меня нет «репутации», чтобы добавить комментарий к этому сообщению):
#include <stdio.h>
#include <string.h>
void print(unsigned char *byte_array, int byte_array_size)
{
int i = 0;
printf("0x");
for(; i < byte_array_size; i++)
{
printf("%02x", byte_array[i]);
}
printf("\n");
}
int convert(const char *hex_str, unsigned char *byte_array, int byte_array_max)
{
int hex_str_len = strlen(hex_str);
int i = 0, j = 0;
// The output array size is half the hex_str length (rounded up)
int byte_array_size = (hex_str_len+1)/2;
if (byte_array_size > byte_array_max)
{
// Too big for the output array
return -1;
}
if (hex_str_len % 2 == 1)
{
// hex_str is an odd length, so assume an implicit "0" prefix
if (sscanf(&(hex_str[0]), "%1hhx", &(byte_array[0])) != 1)
{
return -1;
}
i = j = 1;
}
for (; i < hex_str_len; i+=2, j++)
{
if (sscanf(&(hex_str[i]), "%2hhx", &(byte_array[j])) != 1)
{
return -1;
}
}
return byte_array_size;
}
void main()
{
char *examples[] = { "", "5", "D", "5D", "5Df", "deadbeef10203040b00b1e50", "02invalid55" };
unsigned char byte_array[128];
int i = 0;
for (; i < sizeof(examples)/sizeof(char *); i++)
{
int size = convert(examples[i], byte_array, 128);
if (size < 0)
{
printf("Failed to convert '%s'\n", examples[i]);
}
else if (size == 0)
{
printf("Nothing to convert for '%s'\n", examples[i]);
}
else
{
print(byte_array, size);
}
}
}
Следует иметь в виду, что "\Storage Карта" английский ориентированный. Устройство, сделанное для другого региона, может иметь другое имя. Название пути карты памяти на моем устройстве меняется, как я использую устройство.
Некоторое время назад в формах MSDN я ответил на несколько вопросов о том, как обнаружить карты памяти в файловой системе и как каждый получает способность карты памяти. Я записал, что следующее могло быть ответом на те вопросы и думало, что будет полезно совместно использовать. Карты памяти обнаруживаются в файловой системе как временные каталоги. Эта программа исследует объекты в корне устройства и любых папок, которые имеют временный атрибут, считаются положительным совпадением
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);
}
}
}
}
Точка монтирования обычно является "\Storage Картой", но может быть локализована на другие языки или изменена OEMs (некоторое использование устройств "\SD Карта" или другие точки монтирования и некоторая поддержка устройств, монтирующая несколько носителей). Лучший способ перечислить доступные карты состоит в том, чтобы использовать FindFirstFlashCard и FindNextFlashCard.
Обе функции заполняют структуру WIN32_FIND_DATA. Самое важное поле является cFileName, который будет содержать путь к точке монтирования карты (например, "\Storage Карта").
Обратите внимание, что внутренняя память устройства будет также перечислена этими функциями. Если Вы только заботитесь о внешних объемах, игнорируете регистр, где cFileName является пустой строкой ("").
Используя эти функции требуют Вас к #include <projects.h> и ссылке с note_prj.lib. Оба включены в Windows Mobile SDKs на 2000 WM и позже.
Я нашел, что использование API FindFirstFlashCard/FindNextFlashCard более надежно, чем перечисление каталогов и проверка временного флага (который возвратит совместно используемые папки Bluetooth, например).
Следующий пример приложения демонстрирует, как использовать их и необходимые операторы P/Invoke.
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);
}
}
На Windows CE 5 (который является основой для Windows Mobile 6) карты памяти смонтированы в корневой файловой системе как "Карта памяти \", "устройство хранения данных Card2 \", и т.д.
Чтобы узнать, смонтировалось ли это, называют GetFileAttributes (или удаленная версия CeGetFileAttributes, которому я верю), передающий в полном пути (" \Storage Карта \"). Если это возвращает INVALID_FILE_ATTRIBUTES затем, это не смонтировано, иначе проверьте, чтобы удостовериться, что это - каталог прежде, чем возвратить true.
Есть чистый C # способ сделать это без собственных вызовов.
Взято из здесь .
//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;
}
Не могу добавить комментарий к TreeUK и ктак-дискуссии ниже :
Это не гарантированно найдет Карта памяти - многие устройства монтируются встроенная вспышка таким же образом, и это тоже появится в этом списке. – такк 8 мая в 18:23
Это имело хорошо сработало для меня на HTC и Psion. устройства. Какие устройства вы знаете это не сработает? Стоило бы выявление другого признака вы можете сделать скидку на встроенную вспышку с памятью. - TreeUK 9 мая в 22:29
Чтобы дать представление о Motorola MC75 (раньше это была SymboL), я использовал эту часть (нативного) кода :
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);
Вывод отладки :
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]
"Приложение" и "Диск кэша" являются внутренними флэш-накопителями. Карта памяти" - это съемная карта SD. Все они помечены как флэш-накопители (какие они есть), но только "Storage Card" (Карта памяти) является съемной.