Virtual Developer Workshop: Containerized Development with Docker


Environment : VC 7, Windows 9x/NT/2000/XP (ASPI Drivers must be installed!)

This project provides a primitive wrapper class for accessing a SCSI tape via ASPI: CASPIDriver. CASPIDriver is used by the sample application entitled TapeSnoop, a very simple but effective tool for experimenting with SCSI (DAT) tapes.

To use the tool, you may need to configure it. Just execute it and click Configure. Please enter the SCSI device id etc. of the tape device you want to use.

Some of the TapeSnoop functionalities seem to have problems with NT/2000/XP; that is a known ASPI problem with those operating systems. Namely, the bus device reset ("Reset") does not seem to be supported using ASPI with NT (2000, XP). Unfortunately, ASPI is not officially supported by Adaptec/Microsoft on those platforms. In fact, it now seems to be a little outdated; instead, it uses ASPI for direct hardware access. To access SCSI devices, one now can use the IOCTL-Interface (SPTI). After I get a little more experience with that method, I will certainly post another demo application/article.

The code itself really isn't too good -- sorry about that. I did it some time ago with some big project in mind. This was just the test platform for creating basic libraries for a multimedia storage system. Maybe someday I will post that stuff too...

If you plan to use this code to build a big application, I would strongly suggest that you use a threaded version. As described below, TapeSnoop uses a non-threaded method of waiting for SCSI requests to complete.

CASPIDriver implements both ASPI posting and event notification. TapeSnoop runs in event notify mode. So, when a regular SCSI command is done with its execution, the ASPI driver sets an event signal. My "WaitReady" method just keeps on testing for that flag. If it's set, "WaitReady" returns.

The worst part of this code is my CASPIDriver::WaitReady method.

  MSG msg;
  while (WaitForSingleObject(m_hDoneEvent,0) != WAIT_OBJECT_0)
    while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
      if (!AfxGetApp()->PumpMessage())
        ::PostQuitMessage (IDOK); 
  DisplaySense ((SRB_MyExecSCSICmd *)SRBPtr);
  return GetError ((SRB_MyExecSCSICmd *)SRBPtr);

Waiting for things like that from directly within the application message loop is, IMHO, always a bad idea, but it works fine for simple applications like TapeSnoop.

To use CASPIDriver in your own project, just instantiate that class and call ASPIDriver::Init (see CASPIsnoopDlg::OnInitDialog). When your application no longer needs this interface, call CASPIDriver::Destroy (CASPIsnoopDlg::OnDestroy).

If all you need is a SCSI bus snoop, something like this will work fine:

void CDlgSample::OnSnoop() 
  CString str;
  SRB_HAInquiry *inq;
  BYTE d,t,l;
  char type;
  CString name;
  char *buffer;
  DWORD code;
  CString      str;
  POSITION     pos;
  CASPIDevice *pDev;
  CASPIDriver aspi;	

  //init interface

  //get number of installed adapters
  hMem=GlobalAlloc (GHND,sizeof(SRB_HAInquiry));
  inq=(SRB_HAInquiry *)GlobalLock(hMem);
  m_pASPI->HaInquiry (0,inq);
  GlobalFree (hMem);

  //get devices connected
  buffer=new char[32];
  for (t=0x00;t <: aspi.InstalledAdapters();t++)
    for (d=0x00;d <= 0x0F;d++)
      if ((code=aspi.Scan  (t,d,buffer,32)) == ASPIERR_OK)
        for (l=0x00;l <= 0x7F;l++)
          if ((type=aspi.DeviceType (t,d,l,name)) != -1)
            aspi.m_DeviceList.AddDevice (t,d,l,type,name,&buffer[8]);

  //dump device list
  for (pos=aspi.m_DeviceList.GetHeadPosition();pos != NULL;)
    pDev=(CASPIDevice *)aspi.m_DeviceList.GetAt (pos);
    str.Format ("HOST#%d ID#%d LUN#%d %s: \"%s\"",
    m_ListBox.AddString (str);

  //deinit interface

  //update screen data
  UpdateData (FALSE);

All code and the application should work on all Windows versions (9x, NT, XP) and with all SCSI adapters. I did try it on with Sony SDT9000 and most things seem to work just fine. But nevertheless, there are differences between DAT tape drives that may prevent some things from working. If you encounter any problems, look at "4mmdat.c". "4mmdat.c" is part of the Microsoft NT DDK and samples a version of 4mmdat.sys -- the NT DAT driver. If that doesn't help, just tell me; maybe I can give you a hint.

I finally would like to give credit to "The Tape Guy." That guy really knows everything about tape drives and he gave me some help on SCSI DAT tape compression. See his page at www.tapeguy.com.


Download demo application - 20 Kb
Download source code of the demo application - 55 Kb


  • Help

    Posted by Legacy on 04/08/2003 07:00am

    Originally posted by: PKP

    I tried to run the application but it is giving the following problem :
    wnaspi32.lib not found.
    Please Help me out

  • In WinMe and Win98 support SCSI_PASS_THOUGHT ???

    Posted by Legacy on 10/17/2002 07:00am

    Originally posted by: Funny

    In WinME usb device which use USB Native Driver can use SCSI PASS THOUGHT to read/write data ?

  • How to Hanlde Stacker Programatically

    Posted by Legacy on 10/08/2002 07:00am

    Originally posted by: Dash

    Hi Mr. Till

    I need your kind help on a problem.
    How can i hanlde stacker Programmatically to load and unload tape cartridges into tape drive??
    I have a stacker mounted on FUJITSU tape drive.
    i am using ASPI command!
    please help me to know how and what command i need to send to stacker, so that to load and unload tape cartridges from this stacker into FUJITSU tape drive??

    best regards,


  • Read Problem with FUJITSU

    Posted by Legacy on 09/25/2002 07:00am

    Originally posted by: Dash

    Hi Mr. Till,
    Thanks for your previous response.
    But this time I have yet another query and hope to get good help from you.
    In fact I am reading and writing to two Tape drives.
    One is '3480 from FUJITSU' and other is 'Exabyte'.

    I tried both types of APIs, like ASPI and ReadFile of SPTI(Scsi Pass Through Interface).
    But problem is that, when I use SendASPI32Command() of ASPI command, it is working for reading and writing on both types of above mentioned Tapes .

    But when I use ReadFile(..) API, it lets me to read from Exabyte tape successfully, but it is not successful on FUJITSU tape.
    All other functionality like moving forward, Reverse, Seek blocks and eject tapes etc are working fine using SPTI APIs , like SetTapePosition(..) API,
    But only problem is that, same ReadFile(..) which is working fine for Exabyte Tapes, is not working well with FUJITSU tapes.

    Please help me to know if there is any thing I am missing or what parameter is required to adjust for this type of working.
    Like GetTapeParamaters(..) API is used to get tape and cartridge info.

    Secondly please tell me what is the programmatically preferred way to interact with Tapes according to your suggestion? ASPI or SPTI?

    You mentioned in your tape article that one can also use IOCTL-Interface (SPTI) to interact with Tapes!
    I will be really very much thankful of your courtesy if you please help me to provide some sort of demo application, which use IOCTL-Interface (SPTI) similar to the TapeSnoop?

    best regards

    Dashing Hawk

  • Help on Tape Drive actual read write ??

    Posted by Legacy on 09/23/2002 07:00am

    Originally posted by: Dashing Hawk

    Dear Sir,
    I hope u will be enjoying best of your health.

    Referred to your article and code on CodeGuru.
    it was really very much helpful in a project of mine.
    But i need your kindful help and remarkable expertiese in tape drive field.
    my quuestion is that;

    How can i determine that how many bytes i have actually read or write to tape drive using ASPI (SRB) command, like SendASPI32Command ?

    like, if we use ReadFile(...) API and give it parameters;
    1: Buff as buffer to read
    2: number of bytes to read

    it returns us a paramater as third parameter, which mentions how much bytes we have actually read or write!

    Is there any parameter like that in ASPI, or any other way to do this??????

    I will be really thankful of your kind help.
    waiting for your courteous response !

    Best regards


  • Help ! How can I read physical sector in win98 and find disk Map ?

    Posted by Legacy on 07/25/2002 07:00am

    Originally posted by: Funny

    Can I read disk physical sector in Win98?
    How can I find logical disk and physical disk mapping ?

  • May I ask you a question?

    Posted by Legacy on 06/21/2002 07:00am

    Originally posted by: Elle Lang

    With ASPI for Win32, you can get the HA/Target/LUN, but can you get the drive letter such as "H:"?

  • DAT Audio-Tape

    Posted by Legacy on 05/15/2002 07:00am

    Originally posted by: Karl Dahmer


    just a question. Is there anyone, who has succesfully copied
    audio-tracks from 'Audio'-DAT tape to the computer ? It seems, that this is not possible with normal Computer-DAT drives.

    best regards


  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date