1,222
社区成员




#include <iostream>
#include <string>
#include <Windows.h>
#include <nvme.h>
using namespace std;
int main()
{
// 打开设备
string devicePath = "\\\\.\\PhysicalDrive0";
HANDLE deviceHandle = CreateFileA(devicePath.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
printf("deviceHandle = %d", deviceHandle);
if (deviceHandle == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
cout << "\r\nFailed to open device. Error code: \r\n" << error << endl;
system("pause");
return 0;
}
if (deviceHandle == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
cout << "\r\nFailed to open device. Error code: \r\n" << error;
system("pause");
return 0;
}
// 构造协议命令
const int bufferLength = 4096*2;
char* inputbuffer = new char[bufferLength];
char* outputbuffer = new char[bufferLength];
//char outputbuffer[bufferLength];
ZeroMemory(inputbuffer, bufferLength);
ZeroMemory(outputbuffer, bufferLength);
PSTORAGE_PROTOCOL_COMMAND protocolCommand = (PSTORAGE_PROTOCOL_COMMAND)inputbuffer;
protocolCommand->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
protocolCommand->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
protocolCommand->ProtocolType = ProtocolTypeNvme;
protocolCommand->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
protocolCommand->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
protocolCommand->ErrorInfoLength = sizeof(NVME_ERROR_INFO_LOG);
protocolCommand->DataFromDeviceTransferLength = 4096;
protocolCommand->TimeOutValue = 10;
protocolCommand->ErrorInfoOffset = FIELD_OFFSET(STORAGE_PROTOCOL_COMMAND, Command) + STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
protocolCommand->DataFromDeviceBufferOffset = protocolCommand->ErrorInfoOffset + protocolCommand->ErrorInfoLength;
protocolCommand->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;
//NVME_COMMAND_User *command = (PNVME_COMMAND)protocolCommand->Command;
//NVME_COMMAND_User *command = new NVME_COMMAND_User();
PNVME_COMMAND command = (PNVME_COMMAND)protocolCommand->Command;
command->CDW0.OPC = 0x06; // 自定义操作码
command->u.GENERAL.CDW10 = 0x1; // 填充数据
command->u.GENERAL.CDW11 = 0x0;
//command->u.GENERAL.CDW12 = 0x00000000;
//command->u.GENERAL.CDW13 = 0x00000000;
command->u.GENERAL.CDW14 = 0x0;
// 发送命令
DWORD returnedLength = 0;
BOOL result = DeviceIoControl(deviceHandle,
IOCTL_STORAGE_PROTOCOL_COMMAND,
inputbuffer, bufferLength,
inputbuffer, bufferLength,
&returnedLength, nullptr);
cout << "\r\n protocolCommand->ReturnStatus: " << protocolCommand->ReturnStatus<<"\n";
cout << "\r\nresult: " << result<<"\n";
cout << "\rreturnedLength: " << returnedLength<<"\n";
if (!result) {
DWORD error = GetLastError();
cout << "\r\nFailed to send protocol command. Error code: \r\n" << error;
CloseHandle(deviceHandle);
system("pause");
return 0;
}
else
{
cout << "\r\nSuccess to DeviceIoControl.\r\n" << endl;
}
// 打印 outputbuffer 中的数据
cout << "\r\nOutput Buffer: \n";
for (DWORD i = protocolCommand->ErrorInfoOffset + protocolCommand->ErrorInfoLength; i < returnedLength; ++i) {
printf("%02X ", (unsigned char)inputbuffer[i]);
if ((i + 1) % 32 == 0) {
printf("\n"); // 每16个字节换行
//break;
}
}
// 关闭设备句柄
CloseHandle(deviceHandle);
system("pause");
return 0;
}
问题描述:
我打算开发一款上位机程序,通过windows API 的nvme部分下发nvne指令给nvme 盘片,发现有很多问题,,我无法确定这种操作是否可行。(我的代码参考微软nvme部分示例)
报错内容:
deviceHandle = 180
protocolCommand->ReturnStatus: 0
result: 0
returnedLength: 0
Failed to send protocol command. Error code:
317请按任意键继续. . .
我的初步解决思路是参数配置不对,需要继续修改参数
操作环境是:Windows
软件是visual studio 2022
我的Nvme盘片,支持的协议是M2.0
问题:
1、我想问一下,这个开发可行性怎么样,理论上可以实现不,实际上可以实现不,怎么实现?
2、开发是否需要再开发一款windows pcie驱动,从而配套开发,开发代码怎么写?
3、在visual studio直接调用windows API的话,理论上可以实现不,实际上可以实现不,怎么实现?
4、我的程序代码遇到的问题怎么解决,有没有更好的方式?
备注:希望得到非人工智能的回答方式回复