dcsimg
 

ASPI Tape Snoop

Wednesday May 8th 2002 by Till Toenshoff

This Project provides a primitive wrapper class for accessing a SCSI tape via ASPI, "CASPIDriver".

-->

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.

DWORD CASPIDriver::WaitReady (LPVOID SRBPtr)
{
  MSG msg;
  while (WaitForSingleObject(m_hDoneEvent,0) != WAIT_OBJECT_0)
  {
    while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
    {
      if (!AfxGetApp()->PumpMessage())
      {
        ::PostQuitMessage (IDOK); 
         break; 
      }
    };
  };
  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;
  HGLOBAL hMem;
  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
  aspi.Init(NULL);

  //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];
  aspi.m_DeviceList.RemoveAll();
  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\"",
                pDev->m_cAdapter,
                pDev->m_cID,
                pDev->m_cLUN,
                pDev->m_strType,
                pDev->m_strName);
    m_ListBox.AddString (str);
    aspi.m_DeviceList.GetNext(pos);
  }

  //deinit interface
  aspi.Destroy();

  //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.

Downloads

Download demo application - 20 Kb
Download source code of the demo application - 55 Kb
Home
Mobile Site | Full Site
Copyright 2018 © QuinStreet Inc. All Rights Reserved