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、我的程序代码遇到的问题怎么解决,有没有更好的方式?
备注:希望得到非人工智能的回答方式回复