Solved

Associate drive letter with ASPI's [Adapter-Target-Lun] in W95/98

Posted on 1998-07-17
11
462 Views
Last Modified: 2013-12-03
I am writing an application that controls my CD-writer via Adaptec's ASPI Layer.
Each device is identified by a Adapter-Target-LUN combination.
Now, I'm looking for a way to associate a drive letter with its ASPI addressing
e.g. suppose I have a writer which is accessible as drive D: ,
I would like to know which Adapter-Target-LUN combination is associated with D:

I've successfully managed to do this in Win NT (see code below).
But unfortunately Windows 95/98 does not allow using CreateFile to open a disc device,
and therefore I cannot use DeviceIOControl to obtain the needed information.

Since I need to get it both working in 95/98 and NT I still need a solution for W95/98.

Any Ideas ?

Thanks,
-----
// obtain drive letter's ADAPTER-TARGET-LUN in WIN NT
for (char c='A';c<='Z';c++) {
  sprintf (DeviceName,"\\\\.\\%c:",c);
  // GENERIC_READ replaced by 0 : query device attributes without accessing device
  FileHandle=CreateFile(DeviceName,0,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  if (FileHandle==NULL) {
    printf ("\n%s : Unable to get filehandle",DeviceName,DeviceName);
  } else {
    if(DeviceIoControl(FileHandle,IOCTL_SCSI_GET_ADDRESS,NULL,0,&DeviceAddress,sizeof(SCSI_ADDRESS),(LPDWORD)&ByteCount,FALSE)) {
      printf ("\n%s : Adapter=%d",DeviceName,DeviceAddress.PortNumber);
      printf ("-Target=%d",DeviceAddress.TargetId);
      printf ("-LUN=%d",DeviceAddress.Lun);
    } else {
      printf ("\n%s-failed",DeviceName);
    }
  }
}
0
Comment
Question by:skris
11 Comments
 
LVL 7

Expert Comment

by:psdavis
Comment Utility
I haven't done ASPI in quite a while.  When I was working on it, this was a subsection of my code.  I hope it can help somewhat.

It didn't use the DeviceIoControl nor the CreateFile for handling the data, but rather the libraries supplied by Adaptec.

BYTE SCSI_InitASPI( void )
{
   OutputDebugString( "Initializing ASPI!\n" );

   DWORD dwASPIStatus = GetASPI32SupportInfo( );
   BYTE  byNumAdapters = 0;

   switch( HIBYTE( LOWORD( dwASPIStatus )))
   {
   case SS_COMP:
      byNumAdapters = LOBYTE( LOWORD( dwASPIStatus ));
      break;

   default:
      OutputDebugString( "ASPI not initialized!\n" );
      break;
      }

   return byNumAdapters;
   }

void SCSI_CloseASPI( void )
{
   return;
   }


//***************************************************************************
// Function:      Scan_For_Target
//
// Description:   If polling is enabled, this function is called whenever
//                Windows is idle.  If a SCSI Inquiry command is still in
//                progress, this routine will return control back to the
//                caller to free up the CPU.  If posting is enabled, this
//                function is called when the SCSI Inquiry command has
//                completed.
//
// Returns:  Nothing
//***************************************************************************

BYTE SCSI_ScanTarget( BYTE byAdapterID, char *lpszScan_String, BYTE byLastTarget )
{
   DWORD dwEventStatus     = 0;
   DWORD dwASPIStatus      = 0;

   HANDLE ASPICompletionEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

   if( ASPICompletionEvent == NULL )
      return FALSE;

   static SRB_ExecSCSICmd ExecSRB;
 
   BYTE   nCounter;

   for( byAdapterID = 0; byAdapterID <= 1; byAdapterID ++ )
   {
      for( nCounter = byLastTarget; nCounter < 7; nCounter ++ )                
      {
         ExecSRB.SRB_Cmd         = SC_EXEC_SCSI_CMD;
         ExecSRB.SRB_HaId        = byAdapterID;
         ExecSRB.SRB_Flags       = SRB_DIR_IN | SRB_EVENT_NOTIFY;        // SRB_DIR_SCSI
         ExecSRB.SRB_Target      = nCounter;
         ExecSRB.SRB_BufPointer  = gm_szResponse_Buffer;
         ExecSRB.SRB_BufLen      = 32;
         ExecSRB.SRB_SenseLen    = SENSE_LEN;
         ExecSRB.SRB_CDBLen      = 6;
         ExecSRB.SRB_PostProc    = (PFNPOST) ASPICompletionEvent;
         ExecSRB.CDBByte[0]      = SCSI_INQUIRY;
         ExecSRB.CDBByte[1]      = 0x00;
         ExecSRB.CDBByte[2]      = 0x00;
         ExecSRB.CDBByte[3]      = 0x00;
         ExecSRB.CDBByte[4]      = 0x40;
         ExecSRB.CDBByte[5]      = 0x00;

         dwASPIStatus = SendASPI32Command( &ExecSRB );

         if( ExecSRB.SRB_Status == SS_PENDING )
            dwEventStatus = WaitForSingleObject( ASPICompletionEvent, 500 );

         if( dwEventStatus == WAIT_OBJECT_0 )
            ResetEvent( ASPICompletionEvent );
     
         if( ExecSRB.SRB_Status == SS_INVALID_HA )
            break;
           
         if( ExecSRB.SRB_Status == SS_NO_DEVICE )
            continue;

         }
      }

   return 0xFF;
   }

BOOL SCSI_ResetDefaults( BYTE byAdapterID, BYTE byTarget )
{
   DWORD dwEventStatus;
   DWORD dwASPIStatus;

   HANDLE ASPICompletionEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

   if( ASPICompletionEvent == NULL )
      return FALSE;

   static SRB_ExecSCSICmd ExecSRB;  
   
   gm_szResponse_Buffer[ 0 ] = 0x80;
   gm_szResponse_Buffer[ 1 ] = 0x00;
   gm_szResponse_Buffer[ 2 ] = 0x00;
   gm_szResponse_Buffer[ 3 ] = 0x00;
   gm_szResponse_Buffer[ 4 ] = 0x00;
   gm_szResponse_Buffer[ 5 ] = 0x00;
   
   ExecSRB.SRB_Cmd         = SC_EXEC_SCSI_CMD;
   ExecSRB.SRB_HaId        = byAdapterID;
   ExecSRB.SRB_Flags       = SRB_DIR_OUT | SRB_EVENT_NOTIFY;
   ExecSRB.SRB_Target      = byTarget;
   ExecSRB.SRB_BufPointer  = gm_szResponse_Buffer;
   ExecSRB.SRB_BufLen      = 40;
   ExecSRB.SRB_SenseLen    = SENSE_LEN;
   ExecSRB.SRB_CDBLen      = 6;
   ExecSRB.SRB_PostProc    = (PFNPOST) ASPICompletionEvent;
   ExecSRB.CDBByte[0]      = SCSI_SEND;
   ExecSRB.CDBByte[1]      = 0x00;
   ExecSRB.CDBByte[2]      = 0x00;
   ExecSRB.CDBByte[3]      = 0x00;
   ExecSRB.CDBByte[4]      = 0x01;
   ExecSRB.CDBByte[5]      = 0x00;

   dwASPIStatus = SendASPI32Command( &ExecSRB );

   if( ExecSRB.SRB_Status == SS_PENDING )
      dwEventStatus = WaitForSingleObject( ASPICompletionEvent, 500 );

   if( dwEventStatus == WAIT_OBJECT_0 )
      ResetEvent( ASPICompletionEvent );

   if( dwEventStatus == WAIT_TIMEOUT )
      return FALSE;
   
   return TRUE;
   }

Phillip
0
 

Author Comment

by:skris
Comment Utility
Thanks for your input PSDAVIS. But I'm pretty much using the same code that you used for handling all ASPI stuff. But the Adaptec libraries do not offer that bit of extra functionality I need. These libraries allow you to do anything you want with the drive, but they do not allow you make an association between ASPI's ADAPTER-TARGET-LUN and the drive letter that the OS has assigned.
DeviceIoControl or CreateFile aren't necessary for working with the device. I just used them to determine the drive letter association.

Thanks,
0
 
LVL 1

Expert Comment

by:aa571
Comment Utility
Win95/98 don't have the functionality you want.  The only
way to do it is to enum your way through the registry through
the scsi devices (both scsi and atapi devices show up here)
and manually make the association between the target/lun/
drive identity string/drive letter from the registry with
the adapter/target/lun/drive identity string that you get
with the aspi calls.
0
 

Author Comment

by:skris
Comment Utility
I've found the info you referred to in HKEY_LOCAL_MACHINE\ENUM\SCSI
But I still have some considerations :
* Currently I have several (3) identical CD-Writers connected. Based on the information from the registry [Target-LUN-Drive Identity string] I cannot make a 100% reliable match with that same info obtained from the ASPI, since the target number is identical (LUN is always zero, devices with same target are both on a different adapter). The only info left to make a match is the identity string, but this one is identical since I'm dealing with identical devices. So, I will still need the adapter number...
* Furthermore, I've noticed also something that might complicate things. In this registry tree I still found the reference to a CD-writer which currently isn't connected anymore. It seems that devices aren't automatically erased whenever they are removed. So, I'll probably also need a way to determine which device in SCSI\ is still connected...

Thanks,

0
 
LVL 6

Expert Comment

by:snoegler
Comment Utility
The registry key "HKEY_LOCAL_MACHINE\Enum\SCSI" contains as you said the installed
drivers - which may be more than installed devices ...
When using 'regedit' you will find there is a key "HKEY_DYN_DATA" containing a subkey
"Config Manager\Enum".
To find the INSTALLED devices, you have to ::RegEnumKey() over these subkeys, open each,
and then query the value "HardWareKey" which will give you a path to
HKEY_LOCAL_MACHINE\Enum\<queried value>. These paths you get on this way contain
ONLY the real installed devices. Maybe HKEY_DYN_DATA is not defined in the language you
use so here is the HKEY to it:  (( HKEY ) 0x80000006 )

0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:skris
Comment Utility
Excellent Info snoegler, this solves the problem of knowing which devices are actually installed.
My main problem however remains ; Associating, in a 100% reliable manner, the info from HKEY_LOCAL_MACHINE\ENUM\SCSI with the ASPI (as described in my comment from July 25 1998).
I'll be reopening this question so that the 200 points are available to other experts...
Thanks,
0
 
LVL 1

Expert Comment

by:aa571
Comment Utility
You are getting as close as you can to an answer for 95.
Under the HKLM\enum\scsi\yourdrive, you can also get the
SCSILUN and SCSITargetID entries along with the drive letter
and the drive identity strings.  ASPI will get you the
drive identity strings and the LUN/ID values.  You can compare
the two sets of info to take a best guess because you can't
get the adapter number from the registry.  Unless you have
two identical drives with the same SCSI IDs on two different
adapters you should be able to get the drive letter of the
drives. Of course don't get me started on machines that have
an empty CurrentDriveLetterAssignment entry in the registry...
0
 

Author Comment

by:skris
Comment Utility
> Unless you have two identical drives with the same SCSI IDs on > two different adapters you should be able to get the drive
> letter of the drives.
The chances that somebody has 2 devices with the same ID on two different adapters are very likley to occur. Perhaps not with SCSI, but most certainly when you're dealing with ATAPI devices since the number of devices per adapter is limited to two.
And since I'm currently writing code only for ATAPI devices I need something reliable.

> You are getting as close as you can to an answer for 95.
Don't think so, take a look at Adaptec's writer software (or probably any other writer software). This software absolutely has no problem with assigning the drive letters to the correct writer. So, I can only conclude that there is a 100% reliable solution somewhere out there that works properly on W95.




0
 
LVL 1

Accepted Solution

by:
aa571 earned 200 total points
Comment Utility
Here is the final word on the subject I got directly from
my contact at Adaptec. You were right there is an answer as
long as you are running a very recent version of the aspi
drivers and you have the very recent version of the sdk. The
function they talk about is not part of the aspi that comes
standard as part of win95/98 and thus you have to get the
more recent version of aspi from Adaptec.



--------
"No private calls are being made.  You are seeing the results of the documented TranslateASPI32Address call.  The call takes a DEVNODE pointer and translates it to an HA/ID/LN triple.  The
"HKEY_DYN_DATA\Config Manager\Enum" key has named subkeys which
represent all the devices on the system.  The name of each subkey is the DWORD value in hex which can be passed to ASPI to see if it has a corresponding HA/ID/LN triple.  Those keys also have a "HardWareKey" value which points into HKEY_LOCAL_MACHINE at the devices you're currently playing with.  When you match up, you have your translation."


0
 

Author Comment

by:skris
Comment Utility
Great stuff, aa571.
With the latest info you provided it was really easy to write some code that took care of my problem.

Thanks, you're getting an A !


0
 
LVL 1

Expert Comment

by:curtis_george1
Comment Utility
I know this is an old question but I am not sure how else to contact you.  It seems that you have a good understanding of writing to an atapi cdr.  I posted under C++ and MFC in regards to a question similiar to yours.  I was wondering if you could help me out.  Any help would be greatly appreciated.  The link for the question is at http://www.experts-exchange.com/Programming/Programming_Languages/MFC/Q_20659958.html.
the subject is atapi/cdr.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now