rdbntx Posted March 12, 2009 Posted March 12, 2009 I am trying to download microcode to an ATA hard disk using DeviceIoControl with IOCTL_ATA_PASS_THROUGH_DIRECT. When downloading microcode to ATA drive the entire microcode must be sent in one contiguous buffer which can be as large as 2MB, depending on the drive. DeviceIoControl() was returning a fail status with System Error 87 - Invalid Parameter. I set the transfer length to 0x9000 and I got a pass status. The microcode did not download but DeviceIoControl did not fail. I did an IOCTL_STORAGE_QUERY_PROPERTY and found out that the STORAGE_ADAPTER_DESRIPTOR MaximumTransferLength is set to 0x10000 (64k) and MaximumPhysicalPages is set to 0x10. I believe this is what is limiting the amount of data that I can send, but I have no idea how to change theses settings. The driver is atapi.sys and I can not find anything that points me to the location where these values can be changed.I have tried this using WinXP SP2 and W2K3 Server SP3 and get the same response.Below is my code ....BOOL StorageCommands::StorageQueryBusType(HANDLE hDevice, int * BusType, int * AdptrBus){ DWORD NumberOfBytesReturned; BOOL Status = 0; // set up Storage Property Query and Storage Adapter Descriptor Structures STORAGE_PROPERTY_QUERY StoragePropertyQuery; STORAGE_DEVICE_DESCRIPTOR StDescript = { 0 }; STORAGE_ADAPTER_DESCRIPTOR AdDescript = { 0 }; // get the Adapter bus type StoragePropertyQuery.PropertyId = StorageAdapterProperty; StoragePropertyQuery.QueryType = PropertyStandardQuery; // get Adapter Bus Status = DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &StoragePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), &AdDescript, sizeof(STORAGE_ADAPTER_DESCRIPTOR), &NumberOfBytesReturned, NULL ); if (Status) { // set Adapter BusType *AdptrBus=AdDescript.BusType; } // set up Storage Property Query and Storage Device Descriptor Structures StoragePropertyQuery.PropertyId = StorageDeviceProperty; Status = DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &StoragePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), &StDescript, sizeof(STORAGE_DEVICE_DESCRIPTOR), &NumberOfBytesReturned, NULL ); if (Status) { // set Device BusType *BusType=StDescript.BusType; } return (Status);}BOOL ATA_Commands::DownloadMicrocode(HANDLE hDevice, ATA_PASS_THROUGH_DIRECT *pATAData, unsigned char *buffer, DWORD datasize){ BOOL status = 0; DWORD sectors = datasize / 512; DWORD dsize = sizeof(ATA_PASS_THROUGH_DIRECT); DWORD bytescopied = 0; // clear contents of pATAData ZeroMemory(pATAData, dsize); // Fill in WRITE SECTORS query data pATAData->Length = (USHORT) dsize; pATAData->DataTransferLength = datasize; pATAData->AtaFlags = ATA_FLAGS_DATA_OUT; pATAData->TimeOutValue = 180; // Seconds pATAData->DataBuffer= (PVOID) buffer; pATAData->CurrentTaskFile[0] = 0x07; // FEATURES REG - save download code pATAData->CurrentTaskFile[1] = LOBYTE(LOWORD(sectors)); // SECTOR COUNT REG - LSB of sectors pATAData->CurrentTaskFile[2] = HIBYTE(LOWORD(sectors)); // LBA LOW REG - MSB of sectors pATAData->CurrentTaskFile[3] = 0x00; // LBA MID REG pATAData->CurrentTaskFile[4] = 0x00; // LBA HIGH REG pATAData->CurrentTaskFile[5] = 0x00; // DEVICE REG pATAData->CurrentTaskFile[6] = 0x92; // COMMAND REG status = DeviceIoControl( hDevice, IOCTL_ATA_PASS_THROUGH_DIRECT, pATAData, datasize, /* input buffer and size */ pATAData, datasize, /* output buffer and size */ &bytescopied, /* bytes copied to output buffer */ NULL); /* not overlapped */ if (status == 0) { printf("Error: %ld", GetLastError()); } return (status);}Thanks for any help in this.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now