📄 usbdisk_ctrl.cpp
字号:
/*
*********************************************************************************************************
* UsbDisk_Ctrl.cpp
*
*
* File : UsbDisk_Ctrl.cpp
* By : Michael Wei
*********************************************************************************************************
*/
#include "stdafx.h"
#include "SDUsbMassStorage.h"
#include "GUIDs.h"
/////////////////////////////////////////////////////////////////////////////
//CBWDATA FORMATLASTBLOCK={00, 00, 00, 0x7c, 0xE0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
CBWDATA FORMATLASTBLOCK={00, 00, 00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
CBWDATA DISK0BLOCK={00, 00, 00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
DWORD INQUIRY_BUFFER_LENGTH = 0x800;
DWORD RESERVESECTORS = 0x200;//默认的保留0x80个扇区(对于2K/Page的情况)。对于512B/Page的情况,该值设置为512。
const UCHAR INITKEY[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// GetDeviceViaInterface: Open a handle via a device interface
HANDLE GetDeviceViaInterface( GUID* pGuid, DWORD instance)
{
// Get handle to relevant device information set
HDEVINFO info = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if(info==INVALID_HANDLE_VALUE)
{
printf("No HDEVINFO available for this GUID\n");
return NULL;
}
// Get interface data for the requested instance
SP_INTERFACE_DEVICE_DATA ifdata;
ifdata.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
ULONG nGuessCount = MAXLONG;
for (ULONG iDevIndex=0; iDevIndex<nGuessCount; iDevIndex++)
if(!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, iDevIndex, &ifdata))
{
int n = GetLastError();
if (n == ERROR_NO_MORE_ITEMS)
{
printf("No SP_INTERFACE_DEVICE_DATA available for this GUID instance\n");
SetupDiDestroyDeviceInfoList(info);
return NULL;
}
}
else
break;
/*
if(!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, instance, &ifdata))
{
int n = GetLastError();
printf("No SP_INTERFACE_DEVICE_DATA available for this GUID instance\n");
SetupDiDestroyDeviceInfoList(info);
return NULL;
}
*/
// Get size of symbolic link name
DWORD ReqLen;
SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL);
PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
if( ifDetail==NULL)
{
SetupDiDestroyDeviceInfoList(info);
return NULL;
}
// Get symbolic link name
ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if( !SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL))
{
SetupDiDestroyDeviceInfoList(info);
delete ifDetail;
return NULL;
}
printf("Symbolic link is %s\n",ifDetail->DevicePath);
// Open file
HANDLE rv = CreateFile( ifDetail->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( rv==INVALID_HANDLE_VALUE) rv = NULL;
delete ifDetail;
SetupDiDestroyDeviceInfoList(info);
return rv;
}
HANDLE GetDeviceViaInterface( GUID* pGuid, DWORD instance,char *psyslinkname)
{
// Get handle to relevant device information set
HDEVINFO info = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if(info==INVALID_HANDLE_VALUE)
{
printf("No HDEVINFO available for this GUID\n");
return NULL;
}
// Get interface data for the requested instance
SP_INTERFACE_DEVICE_DATA ifdata;
ifdata.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
/*
ULONG nGuessCount = MAXLONG;
for (ULONG iDevIndex=0; iDevIndex<nGuessCount; iDevIndex++)
if(!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, iDevIndex, &ifdata))
{
int n = GetLastError();
if (n == ERROR_NO_MORE_ITEMS)
{
printf("No SP_INTERFACE_DEVICE_DATA available for this GUID instance\n");
SetupDiDestroyDeviceInfoList(info);
return NULL;
}
}
else
break;
*/
if(!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, instance, &ifdata))
{
int n = GetLastError();
printf("No SP_INTERFACE_DEVICE_DATA available for this GUID instance\n");
SetupDiDestroyDeviceInfoList(info);
return NULL;
}
// Get size of symbolic link name
DWORD ReqLen;
SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL);
PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
//ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
if( ifDetail==NULL)
{
SetupDiDestroyDeviceInfoList(info);
return NULL;
}
// Get symbolic link name
ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if( !SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL))
{
SetupDiDestroyDeviceInfoList(info);
delete ifDetail;
return NULL;
}
printf("Symbolic link is %s\n",ifDetail->DevicePath);
// Open file
HANDLE rv = CreateFile( ifDetail->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( rv==INVALID_HANDLE_VALUE) rv = NULL;
strcpy(psyslinkname,ifDetail->DevicePath);
delete ifDetail;
SetupDiDestroyDeviceInfoList(info);
return rv;
}
/////////////////////////////////////////////////////////////////////////////
BOOL MassStorageIO(
LPSTR lpDeviceName,
DWORD dwIoControlCode,
LPVOID lpCDBBuffer,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped,
DWORD nTimeout
)
{
BOOL bResult;
HANDLE hDevice;
int i=0;
hDevice = CreateFile( lpDeviceName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
NULL,
NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{ return false; }
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
DWORD dwBufferBytes = nOutBufferSize;
sptdwb.sptd.Length= sizeof(SCSI_PASS_THROUGH_DIRECT);
sptdwb.sptd.PathId= 0;
sptdwb.sptd.TargetId= 1;
sptdwb.sptd.Lun= 0;
sptdwb.sptd.SenseInfoLength= 24;
sptdwb.sptd.TimeOutValue= 2;
switch (dwIoControlCode)
{
case UFI_READCAPACITY://读取DISK1的容量
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= 0xf1;//UFI_READCAPACITY;
break;
}
case SD_WRITEENABLE:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= UFI_READCAPACITY;
sptdwb.sptd.Cdb[15]= 0xFB;
break;
}
case SD_BACKUP:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= 0xdd;//derek 2007.06.27
// sptdwb.sptd.Cdb[15]= 0xF7;
break;
}
case SD_GUDISK:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= UFI_READCAPACITY;
sptdwb.sptd.Cdb[15]= 0xF9;
break;
}
case UFI_READCAPACITY_TOTAL://读取flash总容量,除去DISK0(光盘)分区
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= 0xf2;//UFI_READCAPACITY;
//sptdwb.sptd.Cdb[15]= 0xFF;
break;
}
case UFI_READ10:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= UFI_READ10;
for(i=0; i<15; i++)
sptdwb.sptd.Cdb[i+1] = *((UCHAR*)lpCDBBuffer+i);
break;
}
case UFI_WRITE10:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_OUT;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= UFI_WRITE10;
for(i=0; i<15; i++)
sptdwb.sptd.Cdb[i+1] = *((UCHAR*)lpCDBBuffer+i);//装载CBW
break;
}
case SD_INPUTPASSWORD:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= 0xaa;//UFI_READCAPACITY;//derek 2007.06.15
sptdwb.sptd.Cdb[7]= *(UCHAR*)lpCDBBuffer;
sptdwb.sptd.Cdb[8]= *((UCHAR*)lpCDBBuffer+1);
sptdwb.sptd.Cdb[9]= *((UCHAR*)lpCDBBuffer+2);
sptdwb.sptd.Cdb[10]= *((UCHAR*)lpCDBBuffer+3);
sptdwb.sptd.Cdb[11]= *((UCHAR*)lpCDBBuffer+4);
sptdwb.sptd.Cdb[12]= *((UCHAR*)lpCDBBuffer+5);
sptdwb.sptd.Cdb[13]= *((UCHAR*)lpCDBBuffer+6);
sptdwb.sptd.Cdb[14]= *((UCHAR*)lpCDBBuffer+7);
//sptdwb.sptd.Cdb[15]= 0xFE;
break;
}
case SD_LOGOUT:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= 0xbb;//UFI_READCAPACITY;//derek 200706.15
//sptdwb.sptd.Cdb[15]= 0xF8;
break;
}
case 0xff:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= 0xff;//UFI_READCAPACITY;//derek 200706.15
//sptdwb.sptd.Cdb[15]= 0xF8;
break;
}
case SD_MODIFYPASSWORD:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= 0xcc;//UFI_READCAPACITY;//derek 2007.06.15
sptdwb.sptd.Cdb[7]= *(UCHAR*)lpCDBBuffer;
sptdwb.sptd.Cdb[8]= *((UCHAR*)lpCDBBuffer+1);
sptdwb.sptd.Cdb[9]= *((UCHAR*)lpCDBBuffer+2);
sptdwb.sptd.Cdb[10]= *((UCHAR*)lpCDBBuffer+3);
sptdwb.sptd.Cdb[11]= *((UCHAR*)lpCDBBuffer+4);
sptdwb.sptd.Cdb[12]= *((UCHAR*)lpCDBBuffer+5);
sptdwb.sptd.Cdb[13]= *((UCHAR*)lpCDBBuffer+6);
sptdwb.sptd.Cdb[14]= *((UCHAR*)lpCDBBuffer+7);
//sptdwb.sptd.Cdb[15]= 0xFD;
break;
}
case SD_DISCONNECT:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= UFI_READCAPACITY;
sptdwb.sptd.Cdb[15]= 0xF8;
break;
}
case SD_GETKEY:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
//sptdwb.sptd.TimeOutValue= 2;
sptdwb.sptd.DataBuffer= lpOutBuffer;
sptdwb.sptd.SenseInfoOffset= offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0]= 0xf3;//UFI_READCAPACITY;
/* sptdwb.sptd.Cdb[7]= *(UCHAR*)lpCDBBuffer;
sptdwb.sptd.Cdb[8]= *((UCHAR*)lpCDBBuffer+1);
sptdwb.sptd.Cdb[9]= *((UCHAR*)lpCDBBuffer+2);
sptdwb.sptd.Cdb[10]= *((UCHAR*)lpCDBBuffer+3);
sptdwb.sptd.Cdb[11]= *((UCHAR*)lpCDBBuffer+4);
sptdwb.sptd.Cdb[12]= *((UCHAR*)lpCDBBuffer+5);
sptdwb.sptd.Cdb[13]= *((UCHAR*)lpCDBBuffer+6);
sptdwb.sptd.Cdb[14]= *((UCHAR*)lpCDBBuffer+7);
sptdwb.sptd.Cdb[15]= 0xF7;*/
break;
}
case SD_GET_DESKEY:
{
sptdwb.sptd.CdbLength= CDB10GENERIC_LENGTH+6;
sptdwb.sptd.DataIn= SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength= nOutBufferSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -