请问CF卡读取问题

twins222 2009-12-09 02:22:20
请问谁知道用EVC怎么来读取多个CF卡的序列号,我现在能读取出一个CF卡的序列号,但是如果有多个CF卡的时候怎么办呢?
而且我还要读出CF卡的个数,谢谢大家。下面是我读取CF卡的程序
#include "stdafx.h"
//my code
#include <windows.h>
#include <winioctl.h>

#define IOCTL_DISK_BASE FILE_DEVICE_DISK
#define IOCTL_DISK_GET_STORAGEID CTL_CODE(IOCTL_DISK_BASE, 0x709, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _STORAGE_IDENTIFICATION {

DWORD dwSize;
DWORD dwFlags;
DWORD dwManufactureIDOffset;
DWORD dwSerialNumOffset;

} STORAGE_IDENTIFICATION, *PSTORAGE_IDENTIFICATION;


#define MANUFACTUREID_INVALID 0x01
#define SERIALNUM_INVALID 0x02

//end of my code

int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
HANDLE hDisk = CreateFile(_T("DSK1:"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (!hDisk) return -1;

PSTORAGE_IDENTIFICATION pStoreInfo = (PSTORAGE_IDENTIFICATION) new BYTE[100];
if (!pStoreInfo) {
CloseHandle(hDisk);
return -2;
}

DWORD dwBytesRet;

if (!DeviceIoControl(hDisk, IOCTL_DISK_GET_STORAGEID, NULL, 0, pStoreInfo, 100, &dwBytesRet, NULL)) { //3000 changed to 46
DWORD err = GetLastError();
delete [] pStoreInfo;
CloseHandle(hDisk);
return -3;
}

TCHAR tStr[200];
if (dwBytesRet)
{
unsigned char *SerialNo=(((BYTE *)pStoreInfo)+pStoreInfo->dwSerialNumOffset);
int i =0;
while (SerialNo[i]!=0 && i < (int)(dwBytesRet-pStoreInfo->dwSerialNumOffset))
{
tStr[i] = (TCHAR)SerialNo[i];
i++;
}
tStr[i] = 0;
}

delete [] pStoreInfo;
CloseHandle(hDisk);

MessageBox(NULL, tStr, _T("HDD Serial No"), MB_OK);


return 0;
}
...全文
448 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
guopeixin 2009-12-17
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 motta021 的回复:]
我指的是这样,ManufacturerID:03011C02B3;serialnum:011C02B3
感觉就是manufacturerID 比serialnum多前面两个字符而已。

if((pStoreInfo->dwFlags & MANUFACTUREID_INVALID) != MANUFACTUREID_INVALID)
{
if (pStoreInfo->dwManufactureIDOffset!=0)
{
int j=0; 
pbyManuID  =(((BYTE *)pStoreInfo)+pStoreInfo->dwManufactureIDOffset); 
while(pbyManuID[j]!=0 && j <(int)(dwBytesRet-pStoreInfo->dwManufactureIDOffset)) 

j++; 

pbyManuID[j] = '\0'; 


strManufactureID  =  (char*)pbyManuID;

[/Quote]
你是说这个呀,那多了两个有什么问题么?
motta021 2009-12-17
  • 打赏
  • 举报
回复
我指的是这样,ManufacturerID:03011C02B3;serialnum:011C02B3
感觉就是manufacturerID 比serialnum多前面两个字符而已。

if((pStoreInfo->dwFlags & MANUFACTUREID_INVALID) != MANUFACTUREID_INVALID)
{
if (pStoreInfo->dwManufactureIDOffset!=0)
{
int j=0;
pbyManuID =(((BYTE *)pStoreInfo)+pStoreInfo->dwManufactureIDOffset);
while(pbyManuID[j]!=0 && j <(int)(dwBytesRet-pStoreInfo->dwManufactureIDOffset))
{
j++;
}
pbyManuID[j] = '\0';


strManufactureID = (char*)pbyManuID;
motta021 2009-12-17
  • 打赏
  • 举报
回复
ManufacturerID:03011C02B3;serialnum:011C02B3,看起来大部分是一样的,感觉怪怪的,要不你试试
guopeixin 2009-12-16
  • 打赏
  • 举报
回复
to:出厂的标示少俩字符
出场的标志是如何获取的?
motta021 2009-12-16
  • 打赏
  • 举报
回复
这样得到的结果还是一样的 (比出厂的标示少俩字符)?肯定是重合造成取的字符部分相同了,这两个标示可能出现这种现象吗?我想生产SD卡的时候,序列号也是采用随机数算法搞的吧。纳闷,望大侠指点,谢谢。
BOOL GetSDCardSerialNumber(CString strCardName,CString &strManufactureID, CString &strSerialNum)
{
BOOL bRet = FALSE;
HANDLE hdisk = NULL;
BYTE *pbySerialNo = NULL;
BYTE *pbyManuID = NULL;
DWORD dwBytesRet = 0;
PSTORAGE_IDENTIFICATION pStoreInfo = NULL;

hdisk=CreateFile(strCardName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if (hdisk != NULL && hdisk != INVALID_HANDLE_VALUE)
{
pStoreInfo = (STORAGE_IDENTIFICATION *)new BYTE[3000];
bRet = DeviceIoControl(hdisk,IOCTL_DISK_GET_STORAGEID,NULL,0,pStoreInfo,3000,&dwBytesRet,NULL);
DWORD dwErr = GetLastError();
CString strTemp;
if( (FALSE == bRet) || (ERROR_INSUFFICIENT_BUFFER == dwErr))
{
strTemp.Format(TEXT("Err1, %d "),dwErr);
AfxMessageBox(strTemp);
delete []pStoreInfo;
CloseHandle(hdisk);
return FALSE;
}

if((pStoreInfo->dwFlags & SERIALNUM_INVALID) != SERIALNUM_INVALID)
{
if (pStoreInfo->dwSerialNumOffset!=0)
{
int i=0;
pbySerialNo=(((BYTE *)pStoreInfo)+pStoreInfo->dwSerialNumOffset);
while (pbySerialNo[i]!=0 && i<(int)(dwBytesRet-pStoreInfo->dwSerialNumOffset))
{
i++;
}
pbySerialNo[i] = '\0';

}
}

if((pStoreInfo->dwFlags & MANUFACTUREID_INVALID) != MANUFACTUREID_INVALID)
{
if (pStoreInfo->dwManufactureIDOffset!=0)
{
int j=0;
pbyManuID =(((BYTE *)pStoreInfo)+pStoreInfo->dwManufactureIDOffset);
while(pbyManuID[j]!=0 && j<(int)(dwBytesRet-pStoreInfo->dwManufactureIDOffset))
{
j++;
}
pbyManuID[j] = '\0';

}
}

strManufactureID = (char*)pbyManuID;
strSerialNum = (char*)pbySerialNo;

delete []pStoreInfo;
CloseHandle(hdisk);
return TRUE;
}
else
{
AfxMessageBox(L"Crete file failed");
return FALSE;
}
return FALSE;
}
motta021 2009-12-15
  • 打赏
  • 举报
回复
借用楼主这块宝地,想请问下,你获取到了序列号,有没有获取过MANUFACTURERID?结构体typedef struct _STORAGE_IDENTIFICATION {
DWORD dwSize;
DWORD dwFlags;
DWORD dwManufactureIDOffset;
DWORD dwSerialNumOffset;
} STORAGE_IDENTIFICATION, *PSTORAGE_IDENTIFICATION;

这里面有个dwFlags,
dwFlags
Provides information about the manufacturer identifier and serial number. Flag Description
MANUFACTURERID_INVALID The identifier for the manufacturer is not valid.
SERIALNUM_INVALID The serial number is not valid.
这里是不是表示有的卡只有一种ID,有的卡两个都有呢?如果两个都有的话,那他的偏移量会不会有重合的现象, 我得到的是这样的 MANUFACTURERID:02AE1A378E, SERIALNUM: AE1A378E,换了几个卡感觉序列号始终是比出厂标示少俩字符,一看就知道偏移量造成两个标示有重合。

是不是我做错了,要怎么搞?


以下是获取函数

void CSystemInfoDlg::dumpStorageId(CString szDisk,CString &strmanu, CString &strcardid)
{
HANDLE hDsk=NULL;
hDsk = ::CreateFile(szDisk, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

byte buf[sizeof(STORAGE_IDENTIFICATION)+256];
STORAGE_IDENTIFICATION *si= (STORAGE_IDENTIFICATION *)buf;
si->dwSize=sizeof(STORAGE_IDENTIFICATION)+256;
DWORD nReturned;
if (!DeviceIoControl(hDsk, IOCTL_DISK_GET_STORAGEID, NULL, 0,buf, sizeof(STORAGE_IDENTIFICATION)+256, &nReturned, NULL))
{
return ;
}
TCHAR bufxx[100],bufyy[100];
wsprintf(bufxx,L"%hs", &buf[si->dwManufactureIDOffset]);
wsprintf(bufyy,L"%hs", &buf[si->dwSerialNumOffset]);

strmanu =bufxx;
strcardid =bufyy;
}
guopeixin 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 guopeixin 的回复:]
引用 10 楼 motta021 的回复:
借用楼主这块宝地,想请问下,你获取到了序列号,有没有获取过MANUFACTURERID?结构体typedef struct _STORAGE_IDENTIFICATION {
  DWORD dwSize;
  DWORD dwFlags;
  DWORD dwManufactureIDOffset;
  DWORD dwSerialNumOffset;
} STORAGE_IDENTIFICATION, *PSTORAGE_IDENTIFICATION;

这里面有个dwFlags,
dwFlags
Provides information about the manufacturer identifier and serial number. Flag Description
MANUFACTURERID_INVALID The identifier for the manufacturer is not valid.
SERIALNUM_INVALID The serial number is not valid.
这里是不是表示有的卡只有一种ID,有的卡两个都有呢?如果两个都有的话,那他的偏移量会不会有重合的现象, 我得到的是这样的 MANUFACTURERID:02AE1A378E, SERIALNUM: AE1A378E,换了几个卡感觉序列号始终是比出厂标示少俩字符,一看就知道偏移量造成两个标示有重合。

是不是我做错了,要怎么搞?


以下是获取函数

void CSystemInfoDlg::dumpStorageId(CString szDisk,CString &strmanu, CString &strcardid)
{
HANDLE hDsk=NULL;
hDsk = ::CreateFile(szDisk, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

byte buf[sizeof(STORAGE_IDENTIFICATION)+256];
STORAGE_IDENTIFICATION *si= (STORAGE_IDENTIFICATION *)buf;
si->dwSize=sizeof(STORAGE_IDENTIFICATION)+256;
DWORD nReturned;
if (!DeviceIoControl(hDsk, IOCTL_DISK_GET_STORAGEID, NULL, 0,buf, sizeof(STORAGE_IDENTIFICATION)+256, &nReturned, NULL))
{
return ;
}
TCHAR bufxx[100],bufyy[100];
wsprintf(bufxx,L"%hs", &buf[si->dwManufactureIDOffset]);
wsprintf(bufyy,L"%hs", &buf[si->dwSerialNumOffset]);

    strmanu =bufxx;
strcardid =bufyy;
}

1. 有没有获取过MANUFACTURERID
你的lz获取的不都是一样的么?都是通过调用IOCTL_DISK_GET_STORAGEID从cid转换出来的一组数据
2. 里是不是表示有的卡只有一种ID,有的卡两个都有呢
按照1.0和2.0协议的规定,每种卡两个id号都有,具体是否给应用程序和存储管理器使用,取决于driver的client层的设计,一般情况下两者都给;
2. 换了几个卡感觉序列号始终是比出厂标示少俩字符,一看就知道偏移量造成两个标示有重合
不知道你的标志是如何获取的?
[/Quote]
2. 由于IOCTL_DISK_GET_STORAGEID并非只针对sd卡,所以有的块设备可以只提供MANUFACTURERID或者rial id
guopeixin 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 motta021 的回复:]
借用楼主这块宝地,想请问下,你获取到了序列号,有没有获取过MANUFACTURERID?结构体typedef struct _STORAGE_IDENTIFICATION {
  DWORD dwSize;
  DWORD dwFlags;
  DWORD dwManufactureIDOffset;
  DWORD dwSerialNumOffset;
} STORAGE_IDENTIFICATION, *PSTORAGE_IDENTIFICATION;

这里面有个dwFlags,
dwFlags
Provides information about the manufacturer identifier and serial number. Flag Description
MANUFACTURERID_INVALID The identifier for the manufacturer is not valid.
SERIALNUM_INVALID The serial number is not valid.
这里是不是表示有的卡只有一种ID,有的卡两个都有呢?如果两个都有的话,那他的偏移量会不会有重合的现象, 我得到的是这样的 MANUFACTURERID:02AE1A378E, SERIALNUM: AE1A378E,换了几个卡感觉序列号始终是比出厂标示少俩字符,一看就知道偏移量造成两个标示有重合。

是不是我做错了,要怎么搞?


以下是获取函数

void CSystemInfoDlg::dumpStorageId(CString szDisk,CString &strmanu, CString &strcardid)
{
HANDLE hDsk=NULL;
hDsk = ::CreateFile(szDisk, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

byte buf[sizeof(STORAGE_IDENTIFICATION)+256];
STORAGE_IDENTIFICATION *si= (STORAGE_IDENTIFICATION *)buf;
si->dwSize=sizeof(STORAGE_IDENTIFICATION)+256;
DWORD nReturned;
if (!DeviceIoControl(hDsk, IOCTL_DISK_GET_STORAGEID, NULL, 0,buf, sizeof(STORAGE_IDENTIFICATION)+256, &nReturned, NULL))
{
return ;
}
TCHAR bufxx[100],bufyy[100];
wsprintf(bufxx,L"%hs", &buf[si->dwManufactureIDOffset]);
wsprintf(bufyy,L"%hs", &buf[si->dwSerialNumOffset]);

    strmanu =bufxx;
strcardid =bufyy;
}
[/Quote]
1. 有没有获取过MANUFACTURERID
你的lz获取的不都是一样的么?都是通过调用IOCTL_DISK_GET_STORAGEID从cid转换出来的一组数据
2. 里是不是表示有的卡只有一种ID,有的卡两个都有呢
按照1.0和2.0协议的规定,每种卡两个id号都有,具体是否给应用程序和存储管理器使用,取决于driver的client层的设计,一般情况下两者都给;
2. 换了几个卡感觉序列号始终是比出厂标示少俩字符,一看就知道偏移量造成两个标示有重合
不知道你的标志是如何获取的?
twins222 2009-12-11
  • 打赏
  • 举报
回复
其他人没有回答一下的吗?
twins222 2009-12-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 guopeixin 的回复:]

两种方法:
方法1: 查看注册表下driver\active\**下的键值,找到对应你驱动的device  name
方法2: 利用api遍历所有由device.exe/dll加载的驱动的设备名
[/Quote]
1.我在注册表HKEY_LOCAL_MACJINE//Drivers//Active//05下面看到了 名字为Name 数据为DSK1:这个是不是我读取的CF卡的内容啊?
2.如果再有其他CF卡,这个名字还会如何显示呢?所有的都像上面那样吗?
3.在注册表的这个位置没有驱动的名字啊 我也不知道如何去遍历啊?这个遍历的函数是GDUI来获得设备路径,然后用DeviceIOControl函数来做吗?
guopeixin 2009-12-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 twins222 的回复:]
引用 5 楼 guopeixin 的回复:

两种方法:
方法1: 查看注册表下driver\active\**下的键值,找到对应你驱动的device  name
方法2: 利用api遍历所有由device.exe/dll加载的驱动的设备名

1.我在注册表HKEY_LOCAL_MACJINE//Drivers//Active//05下面看到了 名字为Name 数据为DSK1:这个是不是我读取的CF卡的内容啊?
2.如果再有其他CF卡,这个名字还会如何显示呢?所有的都像上面那样吗?
3.在注册表的这个位置没有驱动的名字啊 我也不知道如何去遍历啊?这个遍历的函数是GDUI来获得设备路径,然后用DeviceIOControl函数来做吗?
[/Quote]
1. 仅仅看到name是DSK1:,还不能确定这个是cf卡,你可以看看Active//05下面的dll是不是你sd卡的host驱动,如果是,你就对了
2. 如果还没有其它卡,按照存储管理的规则,会以此朝下增长,即dsk1:-->dsk2-->...;
3. 便利的方法是findfirstdevice吧,就是存储管理的api,你先找一下,找不到下周上班我给你找
liuysheng 2009-12-11
  • 打赏
  • 举报
回复
可能借助于IOControl来调用客户端驱动的SMC_IOControl,从中可以获取卡的信息。。。
DSK是你要获取的名字。。。一般还有一个"FriendlyName",
http://topic.csdn.net/u/20070726/16/928dde7c-6e66-466b-b995-2bc0bd6829e8.html
DeviceIoControl中的参数 IOCTL_SD_SN比较关键。。。
guopeixin 2009-12-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 twins222 的回复:]
引用 2 楼 guopeixin 的回复:
多个cf卡在存储管理上加载的时候,device name是不一样的,你可以确定device name后,挨个createfile,然后以相同iocontrol的方式进行读取

那请问如何确定device name呢?
[/Quote]
两种方法:
方法1: 查看注册表下driver\active\**下的键值,找到对应你驱动的device name
方法2: 利用api遍历所有由device.exe/dll加载的驱动的设备名
twins222 2009-12-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 guopeixin 的回复:]
多个cf卡在存储管理上加载的时候,device name是不一样的,你可以确定device name后,挨个createfile,然后以相同iocontrol的方式进行读取
[/Quote]
那请问如何确定device name呢?
kyzf 2009-12-10
  • 打赏
  • 举报
回复
MARK下,学习下。
guopeixin 2009-12-09
  • 打赏
  • 举报
回复
多个cf卡在存储管理上加载的时候,device name是不一样的,你可以确定device name后,挨个createfile,然后以相同iocontrol的方式进行读取
twins222 2009-12-09
  • 打赏
  • 举报
回复
怎么没有人回答呢?顶一下呵呵

19,500

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧