按扇区读取Windows Mobile的数据
http://dev.mmarket.com/cmdn/bbs/redirect.php?tid=114&goto=lastpost
% s0 D ~: s3 l; Y0 h# d
由 于移动设备的体系架构与桌面电脑类似,都是由CPU,内存,非易失性存储器组成,因此,对于文件系统管理等方面,将PC上的文件系统引入到移动设备是个非 常不错的选择。比如,Windows Mobile 5,(基于windows ce 5.0的内核),就采用了TFAT32的文件格式,相对于FAT32文件系统,TFAT32增强了安全性。中国移动开发者社区; m4 i) M1 F! k! M
7 U! q# ?7 m8 F+ /8 ?/ ^* p
微 软的API中提供了CreateFile函数,这个对于从事编程的人员来说应该是非常熟悉不过的了,CreateFile函数不仅能够操作文件,还能操作 各种IO设备,比如磁盘,COM口等。由于Windows Mobile 5将整个非易失性存储器(往往是FLASH,下面就将非易失性存储器粗略地当成FLASH,并以此称呼)划分成若干个逻辑分区,往往是3个,操作系统区, 数据备份区,用户区。因此就可以使用CreateFile函数对这些逻辑磁盘操作了。& I! g2 P3 n3 s1 W8 z/ |# H
开发者社区论坛: T X; ]6 d0 J6 g: O
首 先,可以用FindFirstStore和FindnextStore函数查找存储设备,这些函数需要用到storemgr.h和 storeapi.lib文件,这两个文件在Windows Mobile 5的SDK中都有,用上述函数能够得到存数设备的设备名,例如DSK:1等,这些将作为CreateFile的参数。我的设备插上SD卡后得到的设备名有 四个,分别是DSK1:到DSK4:,其中DSK1是系统所在分区,文件格式未知,DSK2为备份区,就是恢复出厂设置的时候所用到的区域,DSK3是用 户数据区,我们平常存放的短信啊,音乐文件啊都存放在这,也是用户唯一能使用的地方,DSK4就是SD卡。dev.mmarket.com* m2 S" ?! /& w& P
6 B4 p! @7 f- d! G
用 CreateFile打开设备后,不能用ReadFile去读取数据,具体原因不清楚,可能是文件系统驱动未提供支持吧。如何读取数据?用 DeviceIoControl函数,设置读的标志位DISK_IOCTL_READ,同时需要使用SG_REQ作为该函数的第三个参数,SG_REQ是 一个结构体,里面指明了需要读取的磁盘的起始sector和读取sector的数量,该结构体包含在Diskio.h中,不过Diskio.h文件 windows mobile 5.0的SDK没有,我是从PB5.0中的目录下拷贝过去的。" i( q0 T" l% j% J" [4 f
7 D" A$ F5 q2 @$ `6 T5 B) T) ? @
由 于调用FindFirstStore函数和FindNextStore函数能够获取磁盘的扇区数,所以只要根据获得的扇区数,就能完全读取Windows Mobile各个磁盘的数据。之后将其写入到U盘等设备中,那么打开U盘就像打开Windows Mobile设备一样了。不过其中发现了一个问题,读取用户区的数据之后,必须将头部的512*2的字节数据去掉,然后写入U盘才能打开U盘,不然会提示 U盘未格式化。不知道是什么原因,可能是TFAT和FAT之间的区别吧。
void enumStore()
{
STOREINFO stinfo = {0};
HANDLE hPart = INVALID_HANDLE_VALUE;
HANDLE hstore;
TCHAR szInfo[100] = _T("");
stinfo.cbSize = sizeof(STOREINFO);
hstore = FindFirstStore (&stinfo);
if(hstore!=INVALID_HANDLE_VALUE)
{
do {
RETAILMSG(1,(TEXT("Partion number:%ld /n"),stinfo.dwPartitionCount ));
Size2String(stinfo.snNumSectors * stinfo.dwBytesPerSector,szInfo,100);
RETAILMSG(1,(TEXT("enumPartion:%s szInfo=%s/n"),stinfo.szDeviceName,szInfo));
Size2String(stinfo.dwBytesPerSector, szInfo, 100);
RETAILMSG(1,(TEXT("enumPartion:%s dwBytesPerSector=%s/n"),stinfo.szDeviceName,szInfo));
enumPartion(stinfo.szDeviceName,"//Hard Disk2//");
} while(FindNextStore (hstore, &stinfo));
}
FindCloseStore (hstore);
}
LONGLONG enumPartion(LPCTSTR deviceName,CString szPartionName )
{
PARTINFO partInfo = {0};
STOREINFO stinfo = {0};
HANDLE hPart= INVALID_HANDLE_VALUE;
HANDLE hstore=INVALID_HANDLE_VALUE;
TCHAR szInfo[100] = _T("");
stinfo.cbSize = sizeof(STOREINFO);
partInfo.cbSize = sizeof(PARTINFO);
hstore = OpenStore (deviceName);
if(INVALID_HANDLE_VALUE!=hstore)
{
if(GetStoreInfo(hstore,&stinfo)==FALSE)
return 0;
hPart=FindFirstPartition(hstore, &partInfo);
if(hPart==INVALID_HANDLE_VALUE)
RETAILMSG(1,(TEXT("no find Partion info")));
if(hPart!=INVALID_HANDLE_VALUE)
{
do {
RETAILMSG(1,(TEXT("enumPartion:%s /n"),partInfo.szVolumeName));
if(szPartionName.Right(1).Compare(_T("//"))==0 )
szPartionName=szPartionName.Left(szPartionName.GetLength()-1);
if(szPartionName.Compare(partInfo.szVolumeName)==0)
{
CloseHandle(hstore);
FindClosePartition(hPart);
return partInfo.snNumSectors*stinfo.dwBytesPerSector;
}
} while(FindNextPartition(hPart, &partInfo));
}
}
CloseHandle(hstore);
FindClosePartition(hPart);
return 0L;
}
//