📄 aspidriver.cpp
字号:
//AspiDriver.cpp : implementation file
//(c) 1999-2002, Till Toenshoff <me@mmsguru.de>
//this code is FREE for any use
#include "stdafx.h"
#include <afxwin.h> // for MSGF_DDEMGR
#include "AspiDriver.h"
extern char *gszAppName;
HANDLE CASPIDriver::m_hDoneEvent=NULL;
/*\
*<------------ CASPIDriver ------------>
@m default constructor
*--> I N <-- @p
* BOOL bPosting - use ASPI posting
*/
CASPIDriver::CASPIDriver(BOOL bPosting)
{
m_bUsePosting=bPosting;
m_nAdapters=0;
m_nPosition=0L;
}
/*\
*<------------ ~CASPIDriver ------------>
@m destructor
*/
CASPIDriver::~CASPIDriver()
{
}
/*\
*<------------ Init ------------>
@m initialize this interface
*--> I N <-- @p
* HWND hWnd - handle of our application window (or NULL)
*<-- OUT --> @r
* BOOL - TRUE=ok
*/
BOOL CASPIDriver::Init (HWND hWnd)
{
DWORD ASPIStatus;
// TODO: Add your control notification handler code here
ASPIStatus = GetASPI32SupportInfo();
switch (HIBYTE(LOWORD(ASPIStatus)))
{
case SS_COMP: // ASPI for Windows is resident.
m_nAdapters = (LOWORD(LOBYTE(ASPIStatus)));
TRACE ("ASPIsnoop: ASPI driver found installed !\n");
break;
default:
MessageBox(hWnd,"ASPI for Windows not available!",gszAppName,MB_ICONSTOP);
return FALSE;
}
m_DeviceList.RemoveAll();
m_hDoneEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
return TRUE;
}
/*\
*<------------ Destroy ------------>
@m close interface
*/
void CASPIDriver::Destroy (void)
{
TRACE ("ASPIsnoop: ASPI interface unloaded !\n");
CloseHandle(m_hDoneEvent);
}
/*\
*<------------ WaitReady ------------>
@m wait for command to complete
*--> I N <-- @p
* LPVOID SRBPtr -
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
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;
}
};
//PUT YOUR IDLE-CALLS HERE !
};
DisplaySense ((SRB_MyExecSCSICmd *)SRBPtr);
return GetError ((SRB_MyExecSCSICmd *)SRBPtr);
}
/*\
*<------------ PostProc ------------>
@m ASPI callback function
*--> I N <-- @p
* LPVOID DoneSRB - pointer to scsi request block
*/
void CASPIDriver::PostProc(LPVOID DoneSRB)
{
TRACE ("ASPIsnoop: callback running\n");
SetEvent(m_hDoneEvent);
}
/*\
*<------------ RunCommand ------------>
@m run a ASPI request
*--> I N <-- @p
* LPVOID p - pointer to scsi request block
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
DWORD CASPIDriver::RunCommand (LPVOID p)
{
SRB_MyExecSCSICmd *pSRB=(SRB_MyExecSCSICmd *)p;
if (m_bUsePosting)
{
pSRB->SRB_Flags|=SRB_POSTING;
pSRB->SRB_PostProc=(void (*)(void *))PostProc;
}
else
{
pSRB->SRB_Flags|=SRB_EVENT_NOTIFY;
pSRB->SRB_PostProc=m_hDoneEvent;
}
SendASPI32Command(pSRB); //send it..
return WaitReady(p);
}
// If the user is exiting the program, wait
// until all pending ASPI requests are
void CASPIDriver::ShutDown (void)
{
}
/*\
*<------------ HaInquiry ------------>
@m check for installed host adapters
*--> I N <-- @p
* BYTE adapter_id - adapter id
* SRB_HAInquiry *inq - pointer to prepared request data (see CASPIsnoopDlg::OnSnoop as a sample)
*/
void CASPIDriver::HaInquiry (BYTE adapter_id,SRB_HAInquiry *inq)
{
if (adapter_id >= m_nAdapters) //finished ?
return;
TRACE ("ASPIsnoop: host adapter inquiry ...");
inq->SRB_Cmd = SC_HA_INQUIRY;
inq->SRB_HaId = adapter_id; //ASPI host adapter number
inq->SRB_Flags = SRB_DIR_IN; //ASPI request flags
SendASPI32Command(inq); //send it..
}
/*\
*<------------ DeviceType ------------>
@m get installed device type
*--> I N <-- @p
* BYTE adapter_id - host adapter
* BYTE device_id - device id
* BYTE lun - lun id
* CString &name - returned name of such device
*<-- OUT --> @r
* BYTE - SCSI device type (DTYPE_xxx - see AspiDriver.h)
*/
BYTE CASPIDriver::DeviceType (BYTE adapter_id,BYTE device_id,BYTE lun,CString &name)
{
HGLOBAL hmem;
PSRB_GDEVBlock dev;
BYTE type;
DWORD ret;
hmem=GlobalAlloc (GHND,sizeof(SRB_GDEVBlock));
dev=(PSRB_GDEVBlock)GlobalLock(hmem);
dev->SRB_Cmd = SC_GET_DEV_TYPE;
dev->SRB_HaId = adapter_id;
dev->SRB_Target = device_id;
dev->SRB_Lun = lun;
TRACE ("ASPIsnoop: get device type ... ");
if ((ret=SendASPI32Command(dev)) != 0x0001)
return (BYTE)-1;
type=dev->SRB_DeviceType;
GlobalFree (hmem);
switch (type)
{
case DTYPE_DASD: name="HDD"; break;
case DTYPE_SEQD: name="TAPE"; break;
case DTYPE_PRNT: name="PRINTER"; break;
case DTYPE_PROC: name="PROCESSOR"; break;
case DTYPE_WORM: name="WORM"; break;
case DTYPE_CROM: name="CDROM"; break;
case DTYPE_SCAN: name="SCANNER"; break;
case DTYPE_OPTI: name="OPTICAL"; break;
case DTYPE_JUKE: name="JUKEBOX"; break;
case DTYPE_COMM: name="COMMDEV"; break;
case DTYPE_RESL: name="reserved"; break;
case DTYPE_RESH: name="reserved"; break;
default:
name="unknown";
}
return dev->SRB_DeviceType;
}
/*\
*<------------ InstalledAdapters ------------>
@m get number of adapters
*<-- OUT --> @r
* WORD - number of installed scsi adapters
*/
WORD CASPIDriver::InstalledAdapters (void)
{
return m_nAdapters;
}
/*\
*<------------ Reset ------------>
@m reset the bus device
*--> I N <-- @p
* BYTE adapter_id - host adapter id
* BYTE device_id - device id
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
DWORD CASPIDriver::Reset (BYTE adapter_id,BYTE device_id)
{
//finished ?
SRB_BusDeviceReset reset;
ZeroMemory (&reset,sizeof(SRB_BusDeviceReset));
TRACE ("ASPIsnoop: resetting %d %d %d\n",adapter_id,device_id,0);
reset.SRB_Cmd = SC_RESET_DEV;
//reset.SRB_HaId = 0;
//reset.SRB_Target = 7;
//reset.SRB_Flags = SRB_POSTING;
reset.SRB_HaId = 0;
reset.SRB_Target = 7;
reset.SRB_Lun = 0;
//reset.SRB_PostProc = (void (*)(void *))PostProc;
return RunCommand(&reset); //send it..
}
/*\
*<------------ Scan ------------>
@m scan for scsi device
*--> I N <-- @p
* BYTE adapter_id - host adapter id
* BYTE device_id - device id
* LPVOID buffer - pointer to 32 byte buffer (see CASPIsnoopDlg::OnSnoop)
* BYTE size -
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
DWORD CASPIDriver::Scan (BYTE adapter_id,BYTE device_id,LPVOID buffer,BYTE size)
{
SRB_MyExecSCSICmd exec;
ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
TRACE ("ASPIsnoop: scanning ... ");
// Now we construct the SCSI Inquiry SRB and send it to ASPI!
exec.SRB_Cmd = SC_EXEC_SCSI_CMD;
exec.SRB_HaId = adapter_id;
exec.SRB_Flags = SRB_DIR_IN;
exec.SRB_Target = device_id;
exec.SRB_BufPointer = (unsigned char *)buffer;
exec.SRB_BufLen = size;
exec.SRB_SenseLen = SENSE_LEN;
exec.SRB_CDBLen = 6;
exec.ccb.inq.cmd = SCSI_INQUIRY;
exec.ccb.inq.len = size;
return RunCommand(&exec); //send it..
}
/*\
*<------------ LoadUnload ------------>
@m eject or load a media
*--> I N <-- @p
* BYTE adapter_id - host adapter id
* BYTE device_id - device id
* BYTE lun - lun id
* BYTE bLoad - TRUE=load,FALSE=eject
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
DWORD CASPIDriver::LoadUnload (BYTE adapter_id,BYTE device_id,BYTE lun,BYTE bLoad)
{
SRB_MyExecSCSICmd exec;
ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
TRACE ("ASPIsnoop: ejecting ... ");
// Now we construct the SCSI SRB and send it to ASPI!
exec.SRB_Cmd = SC_EXEC_SCSI_CMD;
exec.SRB_HaId = adapter_id;
exec.SRB_Flags = SRB_DIR_OUT;
exec.SRB_Target = device_id;
exec.SRB_Lun = lun;
exec.SRB_SenseLen = SENSE_LEN;
exec.SRB_CDBLen = 6;
exec.ccb.ld.cmd = SCSI_LOAD_UN;
exec.ccb.ld.immediate = 0;
exec.ccb.ld.lun = lun;
exec.ccb.ld.load = bLoad;
exec.ccb.ld.retention = 0;
exec.ccb.ld.eot = 0;
return RunCommand(&exec); //send it..
}
/*\
*<------------ Rezero ------------>
@m seek to zero
*--> I N <-- @p
* BYTE adapter_id - host adapter id
* BYTE device_id - device id
* BYTE lun - lun id
* BYTE immediate - TRUE=return immediate (handle with care)
*<-- OUT --> @r
* DWORD - ASPIERROR_xxx defined in AspiDriver.h
*/
DWORD CASPIDriver::Rezero (BYTE adapter_id,BYTE device_id,BYTE lun,BYTE immediate)
{
SRB_MyExecSCSICmd exec;
ZeroMemory (&exec,sizeof(SRB_MyExecSCSICmd));
TRACE ("ASPIsnoop: rezero tape ... ");
// Now we construct the SCSI SRB and send it to ASPI!
exec.SRB_Cmd = SC_EXEC_SCSI_CMD;
exec.SRB_HaId = adapter_id;
exec.SRB_Flags = SRB_DIR_OUT;
exec.SRB_Target = device_id;
exec.SRB_Lun = lun;
exec.SRB_SenseLen = SENSE_LEN;
exec.SRB_CDBLen = 6;
exec.ccb.c6.cmd = SCSI_REZERO;
exec.ccb.c6.lun = lun;
exec.ccb.c6.flag0 = immediate;
m_nPosition=0L;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -