⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbdisk_ctrl.cpp

📁 上位机磁盘mass storage传输应用
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
*									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 + -