How to get port number of SCSI Adapter

Hey,

I am trying to get port number of SCSI Adapter. Say if i have two PCI SCSI Adapters connected to my server and i am trying to query the controller(adapter) and get the port number with which its connected to .

I am using IOCTL_SCSI_GET_ADDRESS call from my application. To get a handle to the controller i am using Setupdi calls,but i am failing to get handle of the controller. What GUID should i use while calling “SetupDiGetClassDevs” , i used the class GUID of the SCSI Adapter “4D36E97B-E325-11CE-BFC1-08002BE10318”. am i giving the correct GUID.

I feel there is some problem with the GUID should i give class GUID or interface GUID? where do i get the interface GUID.

Regards,
Karthik.

Interface GUID.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Hey,
>
> I am trying to get port number of SCSI Adapter. Say if i have two PCI SCSI
Adapters connected to my server and i am trying to query the
controller(adapter) and get the port number with which its connected to .
>
> I am using IOCTL_SCSI_GET_ADDRESS call from my application. To get a handle
to the controller i am using Setupdi calls,but i am failing to get handle of
the controller. What GUID should i use while calling “SetupDiGetClassDevs” , i
used the class GUID of the SCSI Adapter “4D36E97B-E325-11CE-BFC1-08002BE10318”.
am i giving the correct GUID.
>
> I feel there is some problem with the GUID should i give class GUID or
interface GUID? where do i get the interface GUID.
>
> Regards,
> Karthik.
>

hey i tried with interface GUID of the SCSI adapter which is “0x4d36e97b, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18” but i am not able to succeed here.

Can some one help me with this request. I hope the interface GUID for the SCSI Adpater is “0x4d36e97b, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18”. How do i make sure that the GUID is correct.

xxxxx@yahoo.com wrote:

Can some one help me with this request. I hope the interface GUID for the SCSI Adpater is “0x4d36e97b, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18”. How do i make sure that the GUID is correct.

That’s the setup class GUID for SCSI adapters, not the device interface
GUID. Why don’t you post the code you are using to enumerate the list?

Also, your first message arrived at 3:40 AM in my time zone. You need
to wait a little more than 15 minutes before resubmitting your question.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Maxim S. Shatskih wrote:

Interface GUID.

No, the answer is “it depends”.

What GUID should i use while calling “SetupDiGetClassDevs” , i
used the class GUID of the SCSI Adapter “4D36E97B-E325-11CE-BFC1-08002BE10318”.
am i giving the correct GUID.

If you specify DIFCF_DEVICEINTERFACE, then you need to pass a device
interface GUID. If you don’t specify that, then you need to pass a
setup class GUID.

SetupDiGetClassDevs is one of the more messed up APIs in the SetupDi
kit, and it’s too bad, because it is so useful. If I had been designing
it, I would have had it accept TWO GUID parameters: a setup class GUID
and a device interface GUID. If you didn’t care about one or the other,
you’d leave it NULL. As it is, my head spins when I try to figure out
what combination of flags do what I want.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> SetupDiGetClassDevs is one of the more messed up APIs in the SetupDi

kit, and it’s too bad, because it is so useful.

This is because it has 2 purposes: a) enumerating a subtree of Device Manager
and b) enumerating active device interfaces. I would do 2 APIs for this, not a
single with a flag.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

hi,

here is the code snipet…

I am trying to get handle to the SCSI controller , send a IOCTL_GET_SCSI_ADDRESS to get the scsi port number of the controller.

SEtupdigetclassdevs() uses the setup class guid instead of interface GUID.

SetupDiGetDeviceInstanceId( ppd->DeviceInfoSet,
ppd->DeviceInfoData,
NULL,
0,
&NumBytes );

// Allocate Buffer used to get the Device ID
pDeviceId = malloc(NumBytes);

if( (NumBytes <= 0) || !pDeviceId )
{
status = FALSE;
__leave;
}

// Zero out DeviceId
memset(pDeviceId, 0, NumBytes);

// Call SetupDiGetDeviceInstanceId second to actually get the DeviceId.

status = SetupDiGetDeviceInstanceId( ppd->DeviceInfoSet,
ppd->DeviceInfoData,
pDeviceId,
NumBytes,
NULL );

if( !status )
{
__leave;
}
else
{
DEBUGPRINT((0, " pDeviceId Value:%s\n",pDeviceId));
}

// Once we have the DeviceID, we can get the device information set

hDevInfo = SetupDiGetClassDevs( &GUID_DEVINTERFACE_SCSIADAPTER,
pDeviceId,
NULL,
DIGCF_ALLCLASSES | DIGCF_PRESENT);

if( INVALID_HANDLE_VALUE == hDevInfo )
{
DEBUGPRINT((0, " SetupDiGetClassDevs Fails\n"));
status = FALSE;
__leave;
}

memset(&DeviceInterfaceData, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

// Given the Device Information Set, enumerate the Device interfaces, should only be one.

status = SetupDiEnumDeviceInterfaces( hDevInfo,
NULL,
&GUID_DEVINTERFACE_SCSIADAPTER, 0,
&DeviceInterfaceData );
if( !status )
{
DEBUGPRINT((0, " SetupDiEnumDeviceInterfaces Fails:%d\n",GetLastError()));
__leave;
}

// Call SetupDiGetDeviceInterfaceDetail first to determine the size of the Buffer. (Expected to Return FALSE)

SetupDiGetDeviceInterfaceDetail( hDevInfo,
&DeviceInterfaceData,
NULL,
0,
&NumBytes,
NULL );

// Allocate struct for Interface Detail Data

pDeviceInterfaceDetailData = malloc( NumBytes );

if( !pDeviceInterfaceDetailData )
{
DEBUGPRINT((0, " Memory allocation for pDeviceInterfaceDetailData Fails …\n"));
status = FALSE;
__leave;
}

// Clear out struct, and set cb.size to the correct value

memset(pDeviceInterfaceDetailData, 0, NumBytes);
pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

// Next call this to get the device path we need to pass to CreateFile

status = SetupDiGetDeviceInterfaceDetail( hDevInfo,
&DeviceInterfaceData,
pDeviceInterfaceDetailData,
NumBytes,
NULL,
NULL );

if(!status)
{
DEBUGPRINT((0, " Memory allocation for pDeviceInterfaceDetailData Fails Again…\n"));
__leave;
}

DEBUGPRINT((0, " CreateFile(Handle to ):%s\n",pDeviceInterfaceDetailData->DevicePath));

// Now get the Handle.

hDevice = CreateFile( pDeviceInterfaceDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );

if ( (hDevice == NULL) || (hDevice == INVALID_HANDLE_VALUE) )
{
DEBUGPRINT((0, " GetDeviceHandle - Unable to obtain handle.\n"));
status = FALSE;
}

status = IOCTL_ReadDevice( hDevice,
IOCTL_SCSI_GET_ADDRESS,
(PULONG) pScsiAddress,
sizeof(SCSI_ADDRESS),
&NumBytes );
if (!status)
{
DEBUGPRINT((0, " Not able to Get SCSI ADDRESS…\n"));
dwErrorCode = GetLastError();
DEBUGPRINT((0, " GetSCSIAddress(GetLastError) : %d\n",dwErrorCode));
}
dwIndexNumber = pScsiAddress->PortNumber;
DEBUGPRINT((0, " GetSCSIAddress(IndexNumber) : %d\n",dwIndexNumber));

IOCTL_SCSI_GET_ADDRESS only works for targets on the bus not the adapter device. I actually gave up trying to get handles to the adapter itself using the setupapi as it was not generically useful across platforms. Instead I enumerate across the \.\ScsiN namespace. I assume that the N in ScsiN correlates to the Port value in a SCSI_ADDRESS. Note that this assumption is broken for some third party adapters that do not use ScsiPort, but it is generally good enough.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-290374-
xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Friday, June 15, 2007 2:53 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] How to get port number of SCSI Adapter

hi,

here is the code snipet…

I am trying to get handle to the SCSI controller , send a
IOCTL_GET_SCSI_ADDRESS to get the scsi port number of the controller.

SEtupdigetclassdevs() uses the setup class guid instead of interface
GUID.

SetupDiGetDeviceInstanceId( ppd->DeviceInfoSet,
ppd->DeviceInfoData,
NULL,
0,
&NumBytes );

// Allocate Buffer used to get the Device ID
pDeviceId = malloc(NumBytes);

if( (NumBytes <= 0) || !pDeviceId )
{
status = FALSE;
__leave;
}

// Zero out DeviceId
memset(pDeviceId, 0, NumBytes);

// Call SetupDiGetDeviceInstanceId second to actually get the
DeviceId.

status = SetupDiGetDeviceInstanceId( ppd->DeviceInfoSet,
ppd->DeviceInfoData,
pDeviceId,
NumBytes,
NULL );

if( !status )
{
__leave;
}
else
{
DEBUGPRINT((0, " pDeviceId Value:%s\n",pDeviceId));
}

// Once we have the DeviceID, we can get the device information set

hDevInfo = SetupDiGetClassDevs( &GUID_DEVINTERFACE_SCSIADAPTER,
pDeviceId,
NULL,
DIGCF_ALLCLASSES | DIGCF_PRESENT);

if( INVALID_HANDLE_VALUE == hDevInfo )
{
DEBUGPRINT((0, " SetupDiGetClassDevs Fails\n"));
status = FALSE;
__leave;
}

memset(&DeviceInterfaceData, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

// Given the Device Information Set, enumerate the Device interfaces,
should only be one.

status = SetupDiEnumDeviceInterfaces( hDevInfo,
NULL,

&GUID_DEVINTERFACE_SCSIADAPTER,

0,
&DeviceInterfaceData );
if( !status )
{
DEBUGPRINT((0, " SetupDiEnumDeviceInterfaces
Fails:%d\n",GetLastError()));
__leave;
}

// Call SetupDiGetDeviceInterfaceDetail first to determine the size of
the Buffer. (Expected to Return FALSE)

SetupDiGetDeviceInterfaceDetail( hDevInfo,
&DeviceInterfaceData,
NULL,
0,
&NumBytes,
NULL );

// Allocate struct for Interface Detail Data

pDeviceInterfaceDetailData = malloc( NumBytes );

if( !pDeviceInterfaceDetailData )
{
DEBUGPRINT((0, " Memory allocation for
pDeviceInterfaceDetailData Fails …\n"));
status = FALSE;
__leave;
}

// Clear out struct, and set cb.size to the correct value

memset(pDeviceInterfaceDetailData, 0, NumBytes);
pDeviceInterfaceDetailData->cbSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

// Next call this to get the device path we need to pass to CreateFile

status = SetupDiGetDeviceInterfaceDetail( hDevInfo,
&DeviceInterfaceData,
pDeviceInterfaceDetailData,
NumBytes,
NULL,
NULL );

if(!status)
{
DEBUGPRINT((0, " Memory allocation for
pDeviceInterfaceDetailData Fails Again…\n"));
__leave;
}

DEBUGPRINT((0, " CreateFile(Handle to
):%s\n",pDeviceInterfaceDetailData->DevicePath));

// Now get the Handle.

hDevice = CreateFile( pDeviceInterfaceDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );

if ( (hDevice == NULL) || (hDevice == INVALID_HANDLE_VALUE) )
{
DEBUGPRINT((0, " GetDeviceHandle - Unable to obtain handle.\n"));
status = FALSE;
}

status = IOCTL_ReadDevice( hDevice,
IOCTL_SCSI_GET_ADDRESS,
(PULONG) pScsiAddress,
sizeof(SCSI_ADDRESS),
&NumBytes );
if (!status)
{
DEBUGPRINT((0, " Not able to Get SCSI ADDRESS…\n"));
dwErrorCode = GetLastError();
DEBUGPRINT((0, " GetSCSIAddress(GetLastError) :
%d\n",dwErrorCode));
}
dwIndexNumber = pScsiAddress->PortNumber;
DEBUGPRINT((0, " GetSCSIAddress(IndexNumber) : %d\n",dwIndexNumber));


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Would IoGetDeviceInterfaces be useful for this?
Using StoragePortClassGuid, that will return a buffer with the SCSI interfaces.
You can then use IoGetDeviceObjectPointer to get a pointer to each one.

Maybe I’m misunderstanding the question…