开发可以自动运行程序的U盘
zhengv@gmail.com
一. 为什么要开发这样的U盘
可以自动运行程序的U盘插入电脑后U盘里面的程序会自动运行,这样的U盘可以作为软件厂商存储程序的载体,也可以作为U盘厂商扩展U盘功能的一种途径。举 几个例子:有加密功能的U盘可以把加密软件存放到U盘中,插入U盘后自动运行加密管理软件,极大方便了用户,厂商也不用另外提供软件;我甚至这么想过,把 温度芯片加入到U盘电路里面,U盘上的程序自动运行后,通过USB接口读出温度,显示给用户:)只要你多想,这样的U盘还可以做很多事情。
二. 开发思路
我们知道光驱插入光盘可以自动运行,所以我们可以让U盘的一个区模拟成光盘的形式。这样我们可以利用autorun.inf,让程序自动运行。
三. 开发步骤
1. 让U盘一个区显示成光盘
这个对于开发过U盘的人来说应该很简单,就是在操作系统发送SCSI设备的 INQUIRY 指令的时候,返回的INQUIRY里面指明设备类型,我们设置为CD设备。具体指令可以参考相关资料(spc3r23.pdf)。我开发的时候 INQUIRY返回数据的前几个字节如下:0x05,0x80,0x02,0x02仅供参考。
2. 响应操作系统对这光盘区的指令
成光盘后,操作系统可能会发送一些SCSI指令给这个光盘区。应该响应某些指令,有些并不需要响应。后面我会附录一个我弄过的一个U盘的BusHound监测文件,大家可以参考。最好买一个这样的U盘,然后用BusHound监测通讯过程。
3. 向光盘区写入文件
应该可以把光盘区弄成CDRW,这样直接写入就可以了,但这样需要了解很多协议。由于时间关系,我采用了简单的方法,把需要写入光盘的文件用ISO制作工 具弄成一个ISO镜像文件,编写一个小程序向这个光盘区写入ISO镜像文件。程序部分代码附在文档后面,仅供参考。写入的程序最终调用 DeviceIoControl函数。文件写入后,再重新拔插U盘就可以了。
四. 说明
这里只是简单说明了原理,如果是刚接触这个,还有很多东西要弄清楚,我是在别人一个普通U盘开发板的基础上添加这个功能的,最后弄通了,感觉很不容易,以前也没有弄过硬件的固件程序。希望对新手有帮助。有什么问题,可以邮件联系交流。
附录:
1. Write ISO程序部分代码:
UINT CWriteIsoFileDlg::ThreadWrite(LPVOID pParam)
{
CWriteIsoFileDlg * p = (CWriteIsoFileDlg*)pParam;
CSDsk sd;
CString str;
HANDLE fh,hFind;
WIN32_FIND_DATA FindFileData;
ULONGLONG fSize = 0;
CFileFind ff;
DWORD startAddr = 0;
DWORD nBytesRead = 0;
PBYTE buf = new BYTE[20480];
memset(buf,0,20480);
try
{
if(!ff.FindFile(p->filename))
{
str.Format("找不到文件 %s ",p->filename);
throw 1;
}
ff.FindNextFile();
fh = CreateFile(ff.GetFilePath(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(fh==INVALID_HANDLE_VALUE)
{
str.Format("打开文件 %s 失败",p->filename);
throw 1;
}
if(!sd.Open())
throw 0;
int index = sd.GetDevNum()-1;
if(!sd.ReadCapacity(index,0,fSize))
throw 0;
if(ff.GetLength()>fSize)
{
str = "光盘空间不足,不能写入。";
throw 1;
}
fSize = ff.GetLength();
if(!sd.GetFlashParam(index,0,1,buf))
throw 0;
buf[0]&=0xBF;
if(!sd.SetFlashParam(index,0,1,buf,false))
throw 0;
while(1)
{
if(ReadFile(fh,buf,20480,&nBytesRead,NULL))
{
if(nBytesRead!=0)
{
if(!sd.Write(index,0,startAddr,40,buf))
{
throw 0;
}
startAddr+=40;
memset(buf,0,20480);
}
else
break;
}
else
{
str = "读文件错误!";
throw 1;
}
}
//p->MessageBox("写入镜像文件成功!",NULL,MB_OK|MB_ICONINFORMATION);
sd.PlugDisk(index,0,true);
delete [] buf;
exit(0);
}
catch(int e)
{
if(e==0)
{
p->MessageBox(sd.err.GetErrMsg(),NULL,MB_OK|MB_ICONERROR);
}
else
p->MessageBox(str,NULL,MB_OK|MB_ICONERROR);
}
delete [] buf;
exit(-1);
return 1;
}
2. 可以自启动U盘的BusHound在windowsXp下的监测文件
Device Phase Data Description Cmd.Phase.Ofs(rep)
------ ----- ------------------------ ---------------- ------------------
20 CDB 12 00 00 00 24 00 INQUIRY 1.1.0
20 DI 05 80 02 02 19 81 10 28 .......( 1.2.0
32 31 53 54 43 20 20 20 21STC 1.2.8
53 45 43 55 52 45 20 43 SECURE C 1.2.16
44 20 41 52 45 41 20 20 D AREA 1.2.24
20 CDB 25 00 00 00 00 00 00 00 READ CAPACITY 2.1.0
00 00 2.1.8
20 SNS 70 00 06 00 00 00 00 0c medium changed 2.2.0
00 00 00 00 28 00 00 00 2.2.8
00 00 2.2.16
20 CDB 25 00 00 00 00 00 00 00 READ CAPACITY 3.1.0
00 00 3.1.8
20 DI 00 00 4f ff 00 00 02 00 ..O..... 3.2.0
20 CDB 5a 08 2a 00 00 00 00 00 MODE SENSE 4.1.0(2)
20 00 4.1.8
20 DI 00 06 00 00 00 00 00 00 ........ 4.2.0
20 CDB 12 00 00 00 24 00 INQUIRY 6.1.0
20 CDB 12 00 00 00 24 00 INQUIRY 7.1.0
20 DI 05 80 02 02 19 81 10 28 .......( 6.2.0
32 31 53 54 43 20 20 20 21STC 6.2.8
53 45 43 55 52 45 20 43 SECURE C 6.2.16
44 20 41 52 45 41 20 20 D AREA 6.2.24
20 DI 05 80 02 02 19 81 10 28 .......( 7.2.0
32 31 53 54 43 20 20 20 21STC 7.2.8
53 45 43 55 52 45 20 43 SECURE C 7.2.16
44 20 41 52 45 41 20 20 D AREA 7.2.24
20 CDB 00 00 00 00 00 00 TEST UNIT READY 8.1.0
20 SNS 70 00 02 00 00 00 00 0c no media 8.2.0
00 00 00 00 3a 00 00 00 8.2.8
00 00 8.2.16
20 CDB 00 00 00 00 00 00 TEST UNIT READY 9.1.0
20 SNS 70 00 06 00 00 00 00 0c medium changed 9.2.0
00 00 00 00 28 00 00 00 9.2.8
00 00 9.2.16
20 CDB 25 00 00 00 00 00 00 00 READ CAPACITY 10.1.0
00 00 10.1.8
20 DI 00 00 4f ff 00 00 02 00 ..O..... 10.2.0
20 CDB 43 00 00 00 00 00 00 00 READ TOC 11.1.0
0c 40 11.1.8
20 DI 00 12 01 01 00 14 01 00 ........ 11.2.0
00 00 02 00 .... 11.2.8
20 CDB 28 00 00 00 00 40 00 00 READ 12.1.0
04 00 12.1.8
20 DI 01 43 44 30 30 31 01 00 .CD001.. 12.2.0
00 00 00 00 00 00 00 00 ........ 12.2.8
00 00 00 00 00 00 00 00 ........ 12.2.16
00 00 00 00 00 00 00 00 ........ 12.2.24
20 CDB 28 00 00 00 00 44 00 00 READ 13.1.0
04 00 13.1.8
20 DI 02 43 44 30 30 31 01 00 .CD001.. 13.2.0
00 00 00 00 00 00 00 00 ........ 13.2.8
00 00 00 00 00 00 00 00 ........ 13.2.16
00 00 00 00 00 00 00 00 ........ 13.2.24
20 CDB 28 00 00 00 00 48 00 00 READ 14.1.0
04 00 14.1.8
20 DI ff 43 44 30 30 31 01 00 .CD001.. 14.2.0
00 00 00 00 00 00 00 00 ........ 14.2.8
00 00 00 00 00 00 00 00 ........ 14.2.16
00 00 00 00 00 00 00 00 ........ 14.2.24
20 CDB 28 00 00 00 00 4c 00 00 READ 15.1.0
04 00 15.1.8
20 DI 01 00 15 00 00 00 01 00 ........ 15.2.0
00 00 00 00 00 00 00 00 ........ 15.2.8
00 00 00 00 00 00 00 00 ........ 15.2.16
00 00 00 00 00 00 00 00 ........ 15.2.24
20 CDB 00 00 00 00 00 00 TEST UNIT READY 16.1.0
20 CDB 43 02 00 00 00 00 00 03 READ TOC 17.1.0
24 00 17.1.8
20 DI 00 12 01 01 00 14 01 00 ........ 17.2.0
00 00 02 00 00 00 00 00 ........ 17.2.8
00 00 00 00 00 00 03 24 .......$ 17.2.16
00 00 00 00 00 00 00 65 .......e 17.2.24
20 CDB 25 00 00 00 00 00 00 00 READ CAPACITY 18.1.0
00 00 18.1.8
20 DI 00 00 4f ff 00 00 02 00 ..O..... 18.2.0
20 CDB 28 00 00 00 00 00 00 00 READ 19.1.0
08 00 19.1.8
20 DI 00 00 00 00 00 00 00 00 ........ 19.2.0
00 00 00 00 00 00 00 00 ........ 19.2.8
00 00 00 00 00 00 00 00 ........ 19.2.16
00 00 00 00 00 00 00 00 ........ 19.2.24
20 CDB 00 00 00 00 00 00 TEST UNIT READY 20.1.0
20 CDB 25 00 00 00 00 00 00 00 READ CAPACITY 21.1.0
00 00 21.1.8
20 DI 00 00 4f ff 00 00 02 00 ..O..... 21.2.0
20 CDB 43 02 00 00 00 00 00 03 READ TOC 22.1.0
24 00 22.1.8
20 DI 00 12 01 01 00 14 01 00 ........ 22.2.0
00 00 02 00 00 00 00 00 ........ 22.2.8
00 00 00 00 00 00 03 24 .......$ 22.2.16
00 00 00 00 00 00 00 65 .......e 22.2.24
20 CDB 43 00 00 00 00 00 00 03 READ TOC 23.1.0
24 40 23.1.8
20 DI 00 12 01 01 00 14 01 00 ........ 23.2.0
00 00 02 00 00 00 00 00 ........ 23.2.8
00 00 00 00 00 00 03 24 .......$ 23.2.16
00 00 00 00 00 00 00 65 .......e 23.2.24
20 CDB 28 00 00 00 00 40 00 00 READ 24.1.0(2)
04 00 24.1.8
20 DI 01 43 44 30 30 31 01 00 .CD001.. 24.2.0
00 00 00 00 00 00 00 00 ........ 24.2.8
00 00 00 00 00 00 00 00 ........ 24.2.16
00 00 00 00 00 00 00 00 ........ 24.2.24
20 CDB 28 00 00 00 00 44 00 00 READ 26.1.0
04 00 26.1.8
20 DI 02 43 44 30 30 31 01 00 .CD001.. 26.2.0
00 00 00 00 00 00 00 00 ........ 26.2.8
00 00 00 00 00 00 00 00 ........ 26.2.16
00 00 00 00 00 00 00 00 ........ 26.2.24
20 CDB 28 00 00 00 00 58 00 00 READ 27.1.0
04 00 27.1.8
20 DI 22 00 16 00 00 00 00 00 "....... 27.2.0
00 16 00 08 00 00 00 00 ........ 27.2.8
08 00 6a 05 0a 0f 21 24 ..j...!$ 27.2.16
00 02 00 00 01 00 00 01 ........ 27.2.24
20 CDB 00 00 00 00 00 00 TEST UNIT READY 28.1.0(5)
20 CDB 28 00 00 00 00 50 00 00 READ 33.1.0
04 00 33.1.8
20 DI 02 00 16 00 00 00 01 00 ........ 33.2.0
00 00 00 00 00 00 00 00 ........ 33.2.8
00 00 00 00 00 00 00 00 ........ 33.2.16
00 00 00 00 00 00 00 00 ........ 33.2.24
20 CDB 00 00 00 00 00 00 TEST UNIT READY 34.1.0(2)
20 CDB 43 02 00 00 00 00 00 03 READ TOC 36.1.0
24 00 36.1.8
20 DI 00 12 01 01 00 14 01 00 ........ 36.2.0
00 00 02 00 00 00 00 00 ........ 36.2.8
00 00 00 00 00 00 03 24 .......$ 36.2.16
00 00 00 00 00 00 00 65 .......e 36.2.24
20 CDB 00 00 00 00 00 00 TEST UNIT READY 37.1.0
20 CDB 28 00 00 00 00 5c 00 00 READ 38.1.0
04 00 38.1.8
20 DI 5b 61 75 74 6f 72 75 6e [autorun 38.2.0
5d 0d 0a 4f 70 65 6e 3d ]..Open= 38.2.8
53 65 63 44 73 6b 2e 65 SecDsk.e 38.2.16
78 65 00 00 00 00 00 00 xe...... 38.2.24
20 CDB 00 00 00 00 00 00 TEST UNIT READY 39.1.0(19)
20 CDB 28 00 00 00 07 b4 00 00 READ 58.1.0
08 00 58.1.8
20 DI 4d 5a 90 00 03 00 00 00 MZ...... 58.2.0
04 00 00 00 ff ff 00 00 ........ 58.2.8
b8 00 00 00 00 00 00 00 ........ 58.2.16
40 00 00 00 00 00 00 00 @....... 58.2.24
20 CDB 28 00 00 00 07 bc 00 00 READ 59.1.0