Hello,
I am having a spot of bother implementing the read disc structure command. I have already got the scsi inquiry command returning drive info. The error comes from transferring data from the returned buffer into a char to print.
I've tried printf("vendor id: %i\n", recvStruct.disk_category); which doesn't work either. It just prints "0"
Error:
invalid application of sizeof to a bit-field
invalid conversion from uchar to const char*
initializing argument 2 of char* strncpy(char*, const char*, size)
Code:
//Function to access disc structure
void discStructure(HANDLE device)
{
readStructureCDB readStruct = {0}; //Creates CDB structure
SCSI_recvStructure recvStruct = {0}; //receive data
DWORD returnedBuf; //Bytes received through DeviceIoControl
unsigned char cmdLen[sizeof(SCSI_PASS_THROUGH_DIRECT) + 96] = {0};
SCSI_PASS_THROUGH_DIRECT * discStructureSCSIptd = (SCSI_PASS_THROUGH_DIRECT *) cmdLen;
typedef enum {
DVD = 0x00,
Bluray = 0x01
/* reserved */
} media_Type;
//Set disc struct CDB here
readStruct.opCode = SCSIOP_discStructure;
readStruct.allocationLength = sizeof(recvStruct);
//readStruct.mediaType = media_Type;
//printf("%d", readStruct.opCode);
memcpy(discStructureSCSIptd->Cdb, &readStruct, sizeof(readStruct));
discStructureSCSIptd->DataBuffer = &recvStruct;
discStructureSCSIptd->DataTransferLength = sizeof(recvStruct);
discStructureSCSIptd->DataIn = SCSI_IOCTL_DATA_IN;
discStructureSCSIptd->CdbLength = sizeof(readStruct);
discStructureSCSIptd->Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
discStructureSCSIptd->SenseInfoLength = sizeof(cmdLen) - sizeof(SCSI_PASS_THROUGH_DIRECT);
discStructureSCSIptd->SenseInfoOffset = sizeof(SCSI_PASS_THROUGH_DIRECT);
discStructureSCSIptd->TimeOutValue = 6000;
BOOL bRet = DeviceIoControl(device,
IOCTL_SCSI_PASS_THROUGH_DIRECT,
(LPVOID)&cmdLen,
sizeof(cmdLen),
(LPVOID)&cmdLen,
sizeof(cmdLen),
&returnedBuf,
NULL);
DWORD error = GetLastError();
if (error != ERROR_SUCCESS)
{
printf("carry_cdb(): last error = %08X\n", error);
}
if (bRet) {
char readStructExtract[100];
int i = 0;
/*Prints info from drive*/
//strncpy(readStructExtract, recvStruct.disk_category, i = sizeof(recvStruct.disk_category));
// readStructExtract[i] = 0;
printf("disc category: %u\n", recvStruct.disk_category);
printf("disc category: %u\n", recvStruct.part_version);
printf("disc category: %u\n", recvStruct.disc_size);
printf("disc category: %u\n", recvStruct.max_rate);
printf("disc category: %u\n", recvStruct.reserved0);
strncpy(readStructExtract, recvStruct.disk_category, i = sizeof(recvStruct.disk_category));
readStructExtract[i] = 0;
printf("vendor id: %s\n", readStructExtract);
}
return ;
}
Code:
#include <windows.h>
#ifndef IOCTL_SCSI_PASS_THROUGH_DIRECT
#define IOCTL_SCSI_PASS_THROUGH_DIRECT 0x4D014
#define SCSI_IOCTL_DATA_OUT 0
#define SCSI_IOCTL_DATA_IN 1
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
//Check pointers - shouldnt be here
typedef struct _SCSI_PASS_THROUGH_DIRECT{
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
void * DataBuffer;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
} SCSI_PASS_THROUGH_DIRECT;
#endif //Termintes endif
typedef struct _SCSI_INQUIRY_STD_DATA{
UCHAR preipheral_device_type : 5;
UCHAR peripheral_qualifier: 3;
UCHAR rsvrd : 7;
UCHAR rmb: 1;
UCHAR version;
UCHAR RESPONSE_DATA_FORMAT; // 7 = AERC, 6 = Obsolete, 5 = NormACA, 4 = HiSup 3-0 = Response data format.
// If ANSI Version = 0, this is ATAPI and bits 7-4 = ATAPI version.
UCHAR ADDITIONAL_LENGTH; // Number of additional bytes available in inquiry data
UCHAR SCCSReserved; // SCC-2 device flag and reserved fields
UCHAR flags1; // First byte of support flags
UCHAR flags2; // Second byte of support flags (Byte 7)
char vendor_id[8];
char product_id[16];
char product_revision_level[4];
} SCSI_INQUIRY_STD_DATA;
/*typedef struct SCSI_INQUIRY_STRCT_DATA{
}SCSI_INQUIRY_STRCT_DATA;*/
#ifndef _SCSI_DVD_STRUCTURES_H
#define _SCSI_DVD_STRUCTURES_H
typedef struct _SCSI_recvStructure{
/* from MMC specs */
UCHAR disk_category :4;
UCHAR part_version :4;
UCHAR disc_size :4;
UCHAR max_rate :4;
UCHAR reserved0 :1;
UCHAR layers_num :2;
UCHAR track :1;
UCHAR layer_type :4;
UCHAR linear_density :4;
UCHAR track_density :4;
UCHAR zero_1;
UCHAR user_data_start [3];
UCHAR zero_2;
UCHAR user_data_end [3];
UCHAR zero_3;
UCHAR user_data_end_layer0 [3];
UCHAR reserved1 :7;
UCHAR burst_cutting_area :1;
UCHAR media_specific [2031];
}SCSI_recvStructure;
#endif
#ifndef SCSIOP_INQUIRY
#define SCSIOP_INQUIRY 0x12
//*Reference region code - chech data types - UCHAR etc...
typedef struct _inquiryCDB{
UCHAR OperationCode6; //* 0x12 - SCSIOP_INQUIRY
UCHAR Reserved1 : 5;
UCHAR LogicalUnitNumber : 3;
UCHAR PageCode;
UCHAR IReserved;
UCHAR AllocationLength;
UCHAR Control;
} inquiryCDB;
#endif
#define SCSIOP_discStructure 0xAD
typedef struct _readStructureCDB{
UCHAR opCode; //0xAD SCSIOP_discStructure
UCHAR mediaType :4;
UCHAR reserved0 :4;
UCHAR address [4]; //[4]
UCHAR layerNo;
UCHAR format;
UCHAR allocationLength ; //[2]
UCHAR reserved1 :6;
UCHAR agid :2; //check these etc
UCHAR ctl;
}readStructureCDB;
I don't think I've set the return structure up correctly. Its called SCSI_DVD_STRUCTURES_H. The guide I'm working from says set the data types to UCHAR. I've tried char and it doesn't change anything. I need to pass values to a char so they can be used to perform various other tasks.
Code:
#define _SCSI_DVD_STRUCTURES_H
typedef struct _SCSI_recvStructure{
/* from MMC specs */
UCHAR disk_category :4;
UCHAR part_version :4;
UCHAR disc_size :4;
UCHAR max_rate :4;
UCHAR reserved0 :1;
UCHAR layers_num :2;
UCHAR track :1;
UCHAR layer_type :4;
UCHAR linear_density :4;
UCHAR track_density :4;
UCHAR zero_1;
UCHAR user_data_start [3];
UCHAR zero_2;
UCHAR user_data_end [3];
UCHAR zero_3;
UCHAR user_data_end_layer0 [3];
UCHAR reserved1 :7;
UCHAR burst_cutting_area :1;
UCHAR media_specific [2031];
}SCSI_recvStructure;
#endif
Thanks for any help in advance.