DeviceIoControl Fails for SCSI_INQUIRY CDB with IOCTL_SCSI_PASS_THROUGH_DIRECT

Hi,
I am sending SCSI_INQUIRY from an application to
the port driver. This application works fine for the Non-Disk
devices but returns ERROR_INVALID_FUNCTION for the Disk
devices.
Does anyone has any idea about it?
I am sending the inquiry as follows:

int iRetVal , i;

unsigned int align = 8 ;

UCHAR ucDataBuf[MAX_RECV_DATA_SIZE] ;

SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER scsiCmd ;

ULONG length = 0, inLength = 0, errorCode = 0, returned = 0 ;

ZeroMemory(&scsiCmd,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));

memcpy(ucDataBuf ,m_scsiCmdBuffer.SRB_BufPointer,
m_scsiCmdBuffer.SRB_BufLen) ;

memcpy(scsiCmd.sptd.Cdb,m_scsiCmdBuffer.SRB_CDBByte,
TR_SCSI_CDB_SIZE );

scsiCmd.sptd.Length = sizeof(SCSI_PASS_THROUGH);

scsiCmd.sptd.PathId = gBus;

scsiCmd.sptd.TargetId = gTarget;

scsiCmd.sptd.CdbLength = m_scsiCmdBuffer.SRB_CDBLen;

scsiCmd.sptd.SenseInfoLength = m_scsiCmdBuffer.SRB_SenseLen ;

scsiCmd.sptd.DataIn = m_scsiCmdBuffer.SRB_Flags;

scsiCmd.sptd.DataTransferLength = m_scsiCmdBuffer.SRB_BufLen ;

scsiCmd.sptd.TimeOutValue = USCSI_TIMEOUT ;

scsiCmd.sptd.DataBuffer = ucDataBuf ;

scsiCmd.sptd.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf) ;

scsiCmd.sptd.Lun = gLun;

if (m_scsiCmdBuffer.SRB_BufLen <
sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER))

length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER) ;

else

length = m_scsiCmdBuffer.SRB_BufLen ;

if (length < 512 )

length= 512 ;

iRetVal = DeviceIoControl(m_Handle.Handle,

IOCTL_SCSI_PASS_THROUGH_DIRECT,

&scsiCmd,

length ,

&scsiCmd,

length,

&returned,

FALSE);

memcpy(m_scsiCmdBuffer.SRB_BufPointer,ucDataBuf,
m_scsiCmdBuffer.SRB_BufLen) ;

if(iRetVal == 0) {

LPVOID lpMsgBuf;

FormatMessage(

FORMAT_MESSAGE_ALLOCATE_BUFFER |

FORMAT_MESSAGE_FROM_SYSTEM |

FORMAT_MESSAGE_IGNORE_INSERTS,

NULL,

GetLastError(),

MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language

(LPTSTR) &lpMsgBuf,

0,

NULL

);

printf(“\nERROR : %s\n”, lpMsgBuf) ;

// Free the buffer.

LocalFree( lpMsgBuf );

fprintf(stderr,“\n SENSE ERROR:IOCTL Fail with iRetVal = %d
\n”, iRetVal) ;

sprintf(m_scsiCmdBuffer.SRB_SenseArea,“ERROR:IOCTL Fail with
iRetVal = %d”, iRetVal) ;

m_Status = iRetVal ;

m_errorCode = MY_IOCTL_FAIL ;

/*

Here m_retVal is undfined

*/

return MY_ERROR ;

}

return (MY_SUCCESS) ;

Try IOCTL_SCSI_GET_INQUIRY_DATA

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
----- Original Message -----
From: Rajendrakumar Rajguru
To: Windows System Software Devs Interest List
Cc: Windows File Systems Devs Interest List ; Kernel Debugging Interest List
Sent: Wednesday, June 08, 2005 10:48 AM
Subject: [ntdev] DeviceIoControl Fails for SCSI_INQUIRY CDB with IOCTL_SCSI_PASS_THROUGH_DIRECT

Hi,
I am sending SCSI_INQUIRY from an application to
the port driver. This application works fine for the Non-Disk
devices but returns ERROR_INVALID_FUNCTION for the Disk
devices.
Does anyone has any idea about it?
I am sending the inquiry as follows:

int iRetVal , i;

unsigned int align = 8 ;

UCHAR ucDataBuf[MAX_RECV_DATA_SIZE] ;

SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER scsiCmd ;

ULONG length = 0, inLength = 0, errorCode = 0, returned = 0 ;

ZeroMemory(&scsiCmd,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));

memcpy(ucDataBuf ,m_scsiCmdBuffer.SRB_BufPointer, m_scsiCmdBuffer.SRB_BufLen) ;

memcpy(scsiCmd.sptd.Cdb,m_scsiCmdBuffer.SRB_CDBByte, TR_SCSI_CDB_SIZE );

scsiCmd.sptd.Length = sizeof(SCSI_PASS_THROUGH);

scsiCmd.sptd.PathId = gBus;

scsiCmd.sptd.TargetId = gTarget;

scsiCmd.sptd.CdbLength = m_scsiCmdBuffer.SRB_CDBLen;

scsiCmd.sptd.SenseInfoLength = m_scsiCmdBuffer.SRB_SenseLen ;

scsiCmd.sptd.DataIn = m_scsiCmdBuffer.SRB_Flags;

scsiCmd.sptd.DataTransferLength = m_scsiCmdBuffer.SRB_BufLen ;

scsiCmd.sptd.TimeOutValue = USCSI_TIMEOUT ;

scsiCmd.sptd.DataBuffer = ucDataBuf ;

scsiCmd.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf) ;

scsiCmd.sptd.Lun = gLun;

if (m_scsiCmdBuffer.SRB_BufLen < sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER))

length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER) ;

else

length = m_scsiCmdBuffer.SRB_BufLen ;

if (length < 512 )

length= 512 ;

iRetVal = DeviceIoControl(m_Handle.Handle,

IOCTL_SCSI_PASS_THROUGH_DIRECT,

&scsiCmd,

length ,

&scsiCmd,

length,

&returned,

FALSE);

memcpy(m_scsiCmdBuffer.SRB_BufPointer,ucDataBuf, m_scsiCmdBuffer.SRB_BufLen) ;

if(iRetVal == 0) {

LPVOID lpMsgBuf;

FormatMessage(

FORMAT_MESSAGE_ALLOCATE_BUFFER |

FORMAT_MESSAGE_FROM_SYSTEM |

FORMAT_MESSAGE_IGNORE_INSERTS,

NULL,

GetLastError(),

MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language

(LPTSTR) &lpMsgBuf,

0,

NULL

);

printf(“\nERROR : %s\n”, lpMsgBuf) ;

// Free the buffer.

LocalFree( lpMsgBuf );

fprintf(stderr,“\n SENSE ERROR:IOCTL Fail with iRetVal = %d \n”, iRetVal) ;

sprintf(m_scsiCmdBuffer.SRB_SenseArea,“ERROR:IOCTL Fail with iRetVal = %d”, iRetVal) ;

m_Status = iRetVal ;

m_errorCode = MY_IOCTL_FAIL ;

/*

Here m_retVal is undfined

*/

return MY_ERROR ;

}

return (MY_SUCCESS) ;


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hi Maxim,

I did try IOCTL_SCSI_GET_INQUIRY_DATA but it is working fine on
Windows2000 . But on Windows2003 the IOCTL_SCSI_GET_INQUIRY_DATA itself
is failing.

My code is something like this…

void do_scsi_inc()
{

DWORD accessMode = 0, shareMode =
FILE_SHARE_READ | FILE_SHARE_WRITE, dwBytesReturned;
HANDLE fileHandle = NULL;
ULONG errorCode;
char DeviceName[256];
char matchedDevice[256];
int iPhysicalDriveCount = 0;
SCSI_ADDRESS psa;
BOOL bResult;
int driveNum = 0;

fprintf(stderr,“\n Device Name = %s\n”, szDeviceName) ;
for (iPhysicalDriveCount = 0; iPhysicalDriveCount < 255;
iPhysicalDriveCount++)
{
sprintf (DeviceName, “\\.\PhysicalDrive%d”,
iPhysicalDriveCount);

shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; // default
accessMode = GENERIC_WRITE | GENERIC_READ; // default

m_Handle.Handle = CreateFile ((LPCTSTR) DeviceName,
accessMode,
shareMode, NULL, OPEN_EXISTING, 0, NULL);

if (m_Handle.Handle == INVALID_HANDLE_VALUE)
{
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
(LPTSTR) & lpMsgBuf, 0, NULL);

// Free the buffer.
LocalFree (lpMsgBuf);
continue;
}
PSCSI_ADAPTER_BUS_INFO AdapterInfo;

AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)
malloc(SCSI_INFO_BUFFER_SIZE) ;
if ( AdapterInfo == NULL)
{
fprintf(stderr,“\n Can not allocate Memory for
AdapterInfo\n”) ;
}
else
{
// Get the SCSI inquiry data for all devices for the given
SCSI bus
bResult = DeviceIoControl(
m_Handle.Handle,
IOCTL_SCSI_GET_INQUIRY_DATA,
NULL,
0,
AdapterInfo,
SCSI_INFO_BUFFER_SIZE,
&dwBytesReturned,
NULL );

if ( !bResult ) {
fprintf(stderr,“Error in IOCTL_SCSI_GET_INQUIRY_DATA\n”
);
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
(LPTSTR) & lpMsgBuf, 0, NULL);

// Free the buffer.
LocalFree (lpMsgBuf);

free( AdapterInfo );
}
else {
fprintf(stderr," IOCTL_SCSI_GET_INQUIRY_DATA done") ;
PSCSI_BUS_DATA BusData;
PSCSI_INQUIRY_DATA InquiryData;
BOOL Claimed;

for ( int Bus = 0; Bus < AdapterInfo->NumberOfBuses;
Bus++ ) {
BusData = &AdapterInfo->BusData[Bus];
InquiryData = (PSCSI_INQUIRY_DATA) ( (PUCHAR)
AdapterInfo + BusData->InquiryDataOffset );
for ( int Luns = 0; Luns <
BusData->NumberOfLogicalUnits; Luns++ ) {
fprintf(stderr,“\n Inq Data = %d \n”,
InquiryData->InquiryDataLength) ;
for (int tp = 0 ; tp <
InquiryData->InquiryDataLength ; tp++)
fprintf(stderr,
“%c”,InquiryData->InquiryData[tp] ) ;
Claimed = InquiryData->DeviceClaimed;
fprintf(stderr," %3d %d %d
%d %s ",
BusData->InitiatorBusId,
InquiryData->PathId, InquiryData->TargetId,
InquiryData->Lun, Claimed? “Yes” : "No "
);
InquiryData = (PSCSI_INQUIRY_DATA) ( (PUCHAR)
AdapterInfo + InquiryData->NextInquiryDataOffset );
} // for Luns
} // for Bus

}
}
CloseHandle(m_Handle.Handle) ;
}
return 1;
}

It can require administrator access.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
----- Original Message -----
From: Rajendrakumar Rajguru
To: Windows System Software Devs Interest List
Sent: Wednesday, June 08, 2005 1:09 PM
Subject: RE: [ntdev] DeviceIoControl Fails for SCSI_INQUIRY CDB with IOCTL_SCSI_PASS_THROUGH_DIRECT

Hi Maxim,

I did try IOCTL_SCSI_GET_INQUIRY_DATA but it is working fine on Windows2000 . But on Windows2003 the IOCTL_SCSI_GET_INQUIRY_DATA itself is failing.

My code is something like this…

void do_scsi_inc()
{

DWORD accessMode = 0, shareMode =
FILE_SHARE_READ | FILE_SHARE_WRITE, dwBytesReturned;
HANDLE fileHandle = NULL;
ULONG errorCode;
char DeviceName[256];
char matchedDevice[256];
int iPhysicalDriveCount = 0;
SCSI_ADDRESS psa;
BOOL bResult;
int driveNum = 0;

fprintf(stderr,“\n Device Name = %s\n”, szDeviceName) ;
for (iPhysicalDriveCount = 0; iPhysicalDriveCount < 255;
iPhysicalDriveCount++)
{
sprintf (DeviceName, “\\.\PhysicalDrive%d”, iPhysicalDriveCount);

shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; // default
accessMode = GENERIC_WRITE | GENERIC_READ; // default

m_Handle.Handle = CreateFile ((LPCTSTR) DeviceName,
accessMode,
shareMode, NULL, OPEN_EXISTING, 0, NULL);

if (m_Handle.Handle == INVALID_HANDLE_VALUE)
{
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) & lpMsgBuf, 0, NULL);

// Free the buffer.
LocalFree (lpMsgBuf);
continue;
}
PSCSI_ADAPTER_BUS_INFO AdapterInfo;

AdapterInfo = (PSCSI_ADAPTER_BUS_INFO) malloc(SCSI_INFO_BUFFER_SIZE) ;
if ( AdapterInfo == NULL)
{
fprintf(stderr,“\n Can not allocate Memory for AdapterInfo\n”) ;
}
else
{
// Get the SCSI inquiry data for all devices for the given SCSI bus
bResult = DeviceIoControl(
m_Handle.Handle,
IOCTL_SCSI_GET_INQUIRY_DATA,
NULL,
0,
AdapterInfo,
SCSI_INFO_BUFFER_SIZE,
&dwBytesReturned,
NULL );

if ( !bResult ) {
fprintf(stderr,“Error in IOCTL_SCSI_GET_INQUIRY_DATA\n” );
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) & lpMsgBuf, 0, NULL);

// Free the buffer.
LocalFree (lpMsgBuf);

free( AdapterInfo );
}
else {
fprintf(stderr," IOCTL_SCSI_GET_INQUIRY_DATA done") ;
PSCSI_BUS_DATA BusData;
PSCSI_INQUIRY_DATA InquiryData;
BOOL Claimed;

for ( int Bus = 0; Bus < AdapterInfo->NumberOfBuses; Bus++ ) {
BusData = &AdapterInfo->BusData[Bus];
InquiryData = (PSCSI_INQUIRY_DATA) ( (PUCHAR) AdapterInfo + BusData->InquiryDataOffset );
for ( int Luns = 0; Luns < BusData->NumberOfLogicalUnits; Luns++ ) {
fprintf(stderr,“\n Inq Data = %d \n”, InquiryData->InquiryDataLength) ;
for (int tp = 0 ; tp < InquiryData->InquiryDataLength ; tp++)
fprintf(stderr, “%c”,InquiryData->InquiryData[tp] ) ;
Claimed = InquiryData->DeviceClaimed;
fprintf(stderr," %3d %d %d %d %s ",
BusData->InitiatorBusId, InquiryData->PathId, InquiryData->TargetId,
InquiryData->Lun, Claimed? “Yes” : "No " );
InquiryData = (PSCSI_INQUIRY_DATA) ( (PUCHAR) AdapterInfo + InquiryData->NextInquiryDataOffset );
} // for Luns
} // for Bus

}
}
CloseHandle(m_Handle.Handle) ;
}
return 1;
}


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

try IOCTL_STORAGE_QUERY_PROPERTY for the device descriptor. This will
have the ID information in it, the device type, etc…

I think (don’t remember anymore) it might even have the raw inquiry
response reported by the device at the tail end of the structure.

-p


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Rajendrakumar
Rajguru
Sent: Wednesday, June 08, 2005 2:10 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] DeviceIoControl Fails for SCSI_INQUIRY CDB
with IOCTL_SCSI_PASS_THROUGH_DIRECT

Hi Maxim,

I did try IOCTL_SCSI_GET_INQUIRY_DATA but it is working fine on
Windows2000 . But on Windows2003 the IOCTL_SCSI_GET_INQUIRY_DATA itself
is failing.

My code is something like this…

void do_scsi_inc()
{

DWORD accessMode = 0, shareMode =
FILE_SHARE_READ | FILE_SHARE_WRITE, dwBytesReturned;
HANDLE fileHandle = NULL;
ULONG errorCode;
char DeviceName[256];
char matchedDevice[256];
int iPhysicalDriveCount = 0;
SCSI_ADDRESS psa;
BOOL bResult;
int driveNum = 0;

fprintf(stderr,“\n Device Name = %s\n”, szDeviceName) ;
for (iPhysicalDriveCount = 0; iPhysicalDriveCount < 255;
iPhysicalDriveCount++)
{
sprintf (DeviceName, “\\.\PhysicalDrive%d”,
iPhysicalDriveCount);

shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; //
default
accessMode = GENERIC_WRITE | GENERIC_READ; // default

m_Handle.Handle = CreateFile ((LPCTSTR) DeviceName,
accessMode,
shareMode, NULL, OPEN_EXISTING, 0, NULL);

if (m_Handle.Handle == INVALID_HANDLE_VALUE)
{
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
(LPTSTR) & lpMsgBuf, 0, NULL);

// Free the buffer.
LocalFree (lpMsgBuf);
continue;
}
PSCSI_ADAPTER_BUS_INFO AdapterInfo;

AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)
malloc(SCSI_INFO_BUFFER_SIZE) ;
if ( AdapterInfo == NULL)
{
fprintf(stderr,“\n Can not allocate Memory for
AdapterInfo\n”) ;
}
else
{
// Get the SCSI inquiry data for all devices for the
given SCSI bus
bResult = DeviceIoControl(
m_Handle.Handle,
IOCTL_SCSI_GET_INQUIRY_DATA,
NULL,
0,
AdapterInfo,
SCSI_INFO_BUFFER_SIZE,
&dwBytesReturned,
NULL );

if ( !bResult ) {
fprintf(stderr,“Error in
IOCTL_SCSI_GET_INQUIRY_DATA\n” );
LPVOID lpMsgBuf;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
(LPTSTR) & lpMsgBuf, 0, NULL);

// Free the buffer.
LocalFree (lpMsgBuf);

free( AdapterInfo );
}
else {
fprintf(stderr," IOCTL_SCSI_GET_INQUIRY_DATA
done") ;
PSCSI_BUS_DATA BusData;
PSCSI_INQUIRY_DATA InquiryData;
BOOL Claimed;

for ( int Bus = 0; Bus <
AdapterInfo->NumberOfBuses; Bus++ ) {
BusData = &AdapterInfo->BusData[Bus];
InquiryData = (PSCSI_INQUIRY_DATA) (
(PUCHAR) AdapterInfo + BusData->InquiryDataOffset );
for ( int Luns = 0; Luns <
BusData->NumberOfLogicalUnits; Luns++ ) {
fprintf(stderr,“\n Inq Data = %d \n”,
InquiryData->InquiryDataLength) ;
for (int tp = 0 ; tp <
InquiryData->InquiryDataLength ; tp++)
fprintf(stderr,
“%c”,InquiryData->InquiryData[tp] ) ;
Claimed = InquiryData->DeviceClaimed;
fprintf(stderr," %3d %d
%d %d %s ",
BusData->InitiatorBusId,
InquiryData->PathId, InquiryData->TargetId,
InquiryData->Lun, Claimed? “Yes”
: "No " );
InquiryData = (PSCSI_INQUIRY_DATA) (
(PUCHAR) AdapterInfo + InquiryData->NextInquiryDataOffset );
} // for Luns
} // for Bus

}
}
CloseHandle(m_Handle.Handle) ;
}
return 1;
}


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag
argument: ‘’
To unsubscribe send a blank email to
xxxxx@lists.osr.com