Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1380 lines
32 KiB

/*++
Module Name:
ctape.h
Abstract:
Rescan.c has the support functions for ctape.c
to get all the tape device info. (scsi and non scsi).
This also does the actual scsi bus rescan.
Author:
Dieter Achtelstetter (A-DACH) 8/4/1994
NOTE:
--*/
extern "C" {
#include <nt.h>
#include <ntddscsi.h>
#include <ntdddisk.h>
#include <ntddcdrm.h>
#include <ntrtl.h>
#include <nturtl.h>
}
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <WINREG.H>
#include <CTYPE.H>
#include <WCHAR.H>
#include <ntddpcm.h>
#include "resource.h"
#include "..\..\pcmcia\pcminfo\getconf.h"
#include "index.h"
#include "setup.h"
#include "device.h"
#include "rescan.h"
#include "detect.h"
#include "uni.h"
#include "debug.h"
#include "adapreg.h"
#include "qic117.h"
//#define GetTapeInfoDEBUG
#ifdef GetTapeInfoDEBUG
int
main(
int argc,
char ** argv,
char ** argp)
{
struct DeviceInfoT TapeDeviceInfo[20]; //Struct to hold ol the info on all the tape devices.
DWORD TapeDeviceCount;
BOOL Ret;
//---- Rescan bus and then get all the device info.
Ret = GetAllTapeDeviceInfo(TRUE,TapeDeviceInfo,&TapeDeviceCount);
if(Ret != TRUE)
{
printf("Error Getting Tape info stuff\n");
}
return(0);
}
#endif
VOID
GenerateDeviceDisplayName(
PDEVICEINFO DeviceInfo);
VOID
GetScsiTapeDeviceMap(
UCHAR PortNumber,
UCHAR BUS,
UCHAR DeviceID,
UCHAR DeviceLUN,
UCHAR * DeviceName,
DWORD BuffLen);
VOID
SaveDeviceInfo(
PSCSI_INQUIRY_DATA InquiryData,
PINQUIRYDATA DetailedInquiryData,
PDEVICEINFO DeviceInfo);
HANDLE
OpenScsiPort(
BYTE Port);
DWORD
ExtractDeviceInfo(
PSCSI_ADAPTER_BUS_INFO AdapterInfo,
BYTE ScsiPortNumber,
int ScsiBusIndex,
PDEVICEINFO_LIST DeviceInfo,
UCHAR * DeviceCount,
BYTE DeviceTypes);
BOOL
GetScsiPortInfo(
BYTE Port,
BOOL Rescan,
PSCSI_ADAPTER_BUS_INFO AdapterInfoBuffer,
DWORD AdapterInfoBufferSize);
VOID InitAdapter(
PSCSI_ADAPTER_REGC AdapterReg,
PSCSI_HOST_ADAPTER Adapter,
int ScsiPortNumber);
VOID
SetDeviceType(
PDEVICEINFO DeviceInfo,
PSCSI_INQUIRY_DATA InquiryData);
VOID
GetAdapterResources(
PSCSI_HOST_ADAPTER Adapter);
VOID
GetAdapterFrindlyName(
PSCSI_HOST_ADAPTER AdapterInfo,
PSCSI_ADAPTER_REGC AdapterReg,
POPTIONLISTC OptionList);
VOID
AddQic117DetectDevice(
PDEVICEINFO_LIST TapeDeviceList);
//*********************************************************************
//* FUNCTION:GetScsiMiniPortDriverName
//*
//* PURPOSE:
//*
//*
//* RETURNS:
//*
//*********************************************************************
void
GetScsiMiniPortDriverName(
int PortNumber,
PCHAR DriverNameBuffer,
DWORD DriverNameBufferSize)
{
CHAR RegKeyString[MaxRegKeySize];
HKEY HK;
int Ret;
DWORD Type;
SCSI_ADAPTER_REGC ScsiAdapterReg;
ScsiAdapterReg.OpenAdapterRegKey(PortNumber);
ScsiAdapterReg.GetAdapterRegDriverName(
DriverNameBuffer,
DriverNameBufferSize);
#if 0
//
//---- Create Reg key string to open
//
_snprintf(RegKeyString,MaxRegKeySize,SCSI_PORT_STRING, PortNumber);
//
//----- Open the Scsi port key
//
Ret = RegOpenKeyA(HKEY_LOCAL_MACHINE,RegKeyString,&HK);
if(Ret != ERROR_SUCCESS)
return;
//
//--- Get the driver name
//
Ret = RegQueryValueExA(HK,DRIVER_STRING,
NULL,&Type,(BYTE*)DriverNameBuffer,&DriverNameBufferSize);
if(Ret != ERROR_SUCCESS)
{
RegCloseKey(HK);
return;
}
#endif
DebugPrintf(("-- GetScsiMiniPortDriverName (NEW) :%s\n",DriverNameBuffer));
//RegCloseKey(HK);
}
//*********************************************************************
//* FUNCTION:GetAllTapeDeviceInfo
//*
//* PURPOSE: Gets the info on all tape devices and stores is in PAR2.
//* If PAR1 == TRUE it will Rescan for any TAPE devices
//* and then do the same.
//* RETURNS:
//*
//*********************************************************************
BOOL
GetAllTapeDeviceInfo(
BOOL Rescan,
PDEVICEINFO_LIST TapeDeviceList,
POPTIONLISTC OptionList)
{
BOOL ScsiStatus,NonScsiStatus;
TapeDeviceList->SetReboot(FALSE);
//
//--- Clear the current list
//
TapeDeviceList->Clear();
//
//----- Get all the scsi tape devices.
//
ScsiStatus = GetAllScsiTapeDeviceInfo(Rescan,
TapeDeviceList,OptionList);
//
//---- Get nono scsi devices
//
NonScsiStatus = GetAllNonScsiTapeDeviceInfo(Rescan,
Rescan,TapeDeviceList,OptionList);
return(NonScsiStatus && ScsiStatus);
}
//*********************************************************************
//* FUNCTION:DetectQIC117
//* RETURNS:
//*********************************************************************
BOOL
DetectQIC117(
VOID)
{
OPTIONC Option;
DWORD Ret;
BOOL Remove=TRUE;
BOOL Disabled;
Option.SetDriverName("qic117");
//
//---- We can only detect the qic117 device
//---- by starting the driver.
//
if(!Option.IsDisabled() )
{
Ret = Option.StartDriver();
if(Ret == ERROR_SERVICE_DISABLED)
{
//
//--- The service key is still intacked but the
//--- driver was disbaled using the SetupDi* APIS.
//
Option.DelService();
Disabled=TRUE;
}
else
Disabled=FALSE;
}
else
Disabled=TRUE;
if( Disabled )
{
//
//---- The service is not installed but the driver is
//---- in the drivers directory. Lets start the driver
//---- to see if the device is pressent.
//
DWORD Ret;
//
//---- Atempt to create the service
//
Ret = Option.CreateService();
//
//---- If the servie already existed
//---- make shure it is set to start
//
if(Ret == ERROR_SERVICE_EXISTS)
{
if(!Option.SetStartUpType(SERVICE_SYSTEM_START))
return(FALSE);
Ret = NO_ERROR;
Remove = TRUE;
}
//
//---- Start the driver
//
if(Ret == NO_ERROR)
{
BOOL Found=FALSE;
Ret = Option.StartDriver();
if(Ret != ERROR_BAD_UNIT
&& Ret != ERROR_MR_MID_NOT_FOUND)
{
//
//--- There is a qic117 device
//
Found = TRUE;
}
//
//--- We only enabled the service so that
//--- we can detect the device. The user still
//--- has to install the driver threw the inf
//--- so I will disable the service again.
//
if(Remove)
Option.SetStartUpType(SERVICE_DISABLED);
return(Found);
}
}
return(FALSE);
}
//*********************************************************************
//* FUNCTION:AddQic117DetectDevice
//*
//* PURPOSE: Gets the info on all non scsi tape devices and stores is in PAR2.
//* If PAR1 == TRUE it will Rescan for any TAPE devices and then do the same.
//* RETURNS:
//*
//*********************************************************************
VOID
AddQic117DetectDevice(
PDEVICEINFO_LIST TapeDeviceList)
{
PTAPEDEVC TapeDevice;
PDEVICEINFO TapeDeviceInfo;
//
//--- Add a new tape device to the list
//
TapeDevice = TapeDeviceList->Append();
TapeDeviceInfo = &TapeDevice->DeviceInfo;
strcpy((PCHAR)TapeDeviceInfo->DeviceDisplayName,"Floppy Tape Device");
TapeDeviceInfo->Option.SetDriverName("QIC117");
TapeDeviceInfo->Option.SetOption("QIC117");
strcpy((PCHAR)TapeDeviceInfo->VendorId,"QIC117");
strcpy((PCHAR)TapeDeviceInfo->ProductId,"QIC117");
TapeDeviceInfo->DeviceClaimed = FALSE;
TapeDeviceInfo->SubType = SUB_TYPE_FLOPPY;
TapeDeviceInfo->DeviceType = TYPE_TAPE;
TapeDevice->InitType();
//TapeDeviceList->SetReboot(TRUE);
}
//*********************************************************************
//* FUNCTION:GetAllNonScsiTapeDeviceInfo
//*
//* PURPOSE: Gets the info on all non scsi tape devices and stores is in PAR2.
//* If PAR1 == TRUE it will Rescan for any TAPE devices and then do the same.
//* RETURNS:
//*
//*********************************************************************
BOOL
GetAllNonScsiTapeDeviceInfo(
BOOL RatleDevice,
BOOL Rescan,
PDEVICEINFO_LIST TapeDeviceList,
POPTIONLISTC OptionList)
{
int Ret;
//int i = 0;
//int TapeDeviceIndex = -1;
DWORD Device=0;
PTAPEDEVC TapeDevice;
PDEVICEINFO TapeDeviceInfo;
BYTE Buff2[MaxRegKeySize];
QIC117 TapeInfo;
if(Rescan)
{
if(DetectQIC117())
{
//
//--- A qic117 device was found in the detection
//--- process lets add it to the device list.
//
AddQic117DetectDevice(TapeDeviceList);
return(TRUE);
}
}
for(Device = 0; Device < MAX_DEVICE_COUNT;Device++)
{
//
//--- Open the tape info for the Non scsi tape device of number Device
//
if( !TapeInfo.Open(Device,Rescan))
{
//
//--- Device doesn't exist
//
continue;
}
//
//--- Add a new tape device to the list
//
TapeDevice = TapeDeviceList->Append();
TapeDeviceInfo = &TapeDevice->DeviceInfo;
//
//--- Get the registry info for this device
//
TapeInfo.GetRegTapeInfo(TapeDeviceInfo);
if(RatleDevice)
{
//
//---- I get the device name in the registry. But qic117 tape devices will
//---- actualy have the drivers name in the registry till someone did something to the
//---- tape device.
//---- So if it still has the driver name in the registry i will
//---- get the tape status. This does the trick.
//----
//
if(!_strnicmp((PCHAR)TapeDeviceInfo->DeviceDisplayName,
"QIC-40/QIC-80",sizeof("QIC-40/QIC-80")-1) ||
!_strnicmp((PCHAR)TapeDeviceInfo->DeviceDisplayName,
"Floppy tape drive",sizeof("Floppy tape drive")-1)
)
{
Ret = DoRatleDevice((PCHAR)TapeDeviceInfo->DeviceName,Device);
if(Ret == TRUE);
{
//
//---- We actualy rattled somthing
//---- So we need to get the identifier again.
//
TapeInfo.GetRegDeviceIdentifier(
(PCHAR) TapeDeviceInfo->DeviceDisplayName,
DEVICE_DISPLAY_NAME_LEN);
}
}
}
//
//--- Set device type . If the driver name is QIC117 it is a floppy tape
//--- else I do not know
//
if(!_stricmp(TapeDeviceInfo->Option.GetDriverName(),QIC117S))
TapeDeviceInfo->SubType = SUB_TYPE_FLOPPY;
else
TapeDeviceInfo->SubType = SUB_TYPE_OTHER;
TapeDeviceInfo->DeviceType = TYPE_TAPE;
//
//---- If we got this info threw the detection process
//---- We still need to officialy installe the driver for this device.
//---- If we say this device is not claimed this will happen.
//
TapeDeviceInfo->DeviceClaimed = TRUE;
TapeDevice->InitType();
DebugPrintf(("-- GetAllNonScsiTapeDeviceInfo\n"));
DebugPrintf(("-- .DeviceDisplayName=%s\n",
(char*)TapeDeviceInfo->DeviceDisplayName));
DebugPrintf(("-- .DeviceName=%s\n",
(char*)TapeDeviceInfo->DeviceName));
DebugPrintf(("-- .DeviceDriverName=%s\n",
TapeDeviceInfo->Option.GetDriverName()));
TapeInfo.Close();
}
return(TRUE);
}
//*********************************************************************
//* FUNCTION:DoRatleDevice
//*
//* PURPOSE: Since the qic117 driver dosn't but the actual device Indenifier in the
//* registry till the tape device has been tuched i need to do this myself.
//* I do this by getting the tape status.
//*
//* RETURNS: TRUE if it actualy did somthing FALSE if it did not.
//*
//*********************************************************************
BOOL
DoRatleDevice(
PCHAR DeviceName,
DWORD Device)
{
HANDLE hTape;
CHAR TapeString[100];
//
//----Open the tape in DeviceName.
//
_snprintf(TapeString,100,"\\\\.\\%s",DeviceName);
hTape = CreateFileA(TapeString,GENERIC_READ,0,0,OPEN_EXISTING,0,NULL);
if(hTape == INVALID_HANDLE_VALUE)
{
//
//--- Couldn't open tape device.
//---- Probaply somthing else has it open
//
return(FALSE);
}
//
//---- Ratle the tape.
//
GetTapeStatus(hTape);
CloseHandle(hTape);
return(TRUE);
}
//*********************************************************************
//* FUNCTION:OpenScsiPort
//*
//* RETURNS:
//*
//*********************************************************************
HANDLE
OpenScsiPort(
BYTE Port)
{
CHAR ScsiPortString[20];
//
//---- Init ScsiPortString to first scsiport
//
_snprintf(ScsiPortString,20,"\\\\.\\Scsi%d:",Port);
//
//---- Open the scsi port
//
return( CreateFileA( ScsiPortString,GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0) );
}
//*********************************************************************
//* FUNCTION:GetAllScsiTapeDeviceInfo
//*
//* PURPOSE: Gets the info on all scsi tape devices and stores is
//* in PAR2. If PAR1 == TRUE it will Rescan for any TAPE
//* devices and then do the same.
//* RETURNS:
//*
//*********************************************************************
BOOL
GetAllScsiTapeDeviceInfo(
BOOL Rescan,
PDEVICEINFO_LIST TapeDeviceList,
POPTIONLISTC OptionList)
{
BYTE ScsiPortNumber = 0;
UCHAR Count;
//
//---- Will hold all the info for all the devices on one port
//
PSCSI_ADAPTER_BUS_INFO AdapterInfoBuffer;
//
//---- Index into DeviceInfo
//
int ScsiBusIndex;
int DeviceIndex = 0;
//
//---- Allocate memory for bus data
//
AdapterInfoBuffer = (PSCSI_ADAPTER_BUS_INFO) malloc(0x400);
if(AdapterInfoBuffer == NULL)
{
return(FALSE);
}
//
//---- Loop they all the scsiports if we faile to open one
//---- we are done and will get out of this loop
//
while (TRUE)
{
if( !GetScsiPortInfo(ScsiPortNumber,Rescan,
AdapterInfoBuffer,0x400) )
break;
//
//---- Loop threw all the bus's on the current adapter.
//
for (ScsiBusIndex=0; ScsiBusIndex < AdapterInfoBuffer->NumberOfBuses; ScsiBusIndex++)
{
DeviceIndex += ExtractDeviceInfo(
AdapterInfoBuffer,
ScsiPortNumber,
ScsiBusIndex,
TapeDeviceList,
&Count,
SEQUENTIAL_ACCESS_DEVICE);
}
ScsiPortNumber++;
}
//
//----- We are done
//
free(AdapterInfoBuffer);
return(TRUE);
}
//*********************************************************************
//* FUNCTION:GetAllScsiTapeDeviceInfo
//*
//* PURPOSE: Gets the info on all scsi tape devices and stores is
//* in PAR2. If PAR1 == TRUE it will Rescan for any TAPE
//* devices and then do the same.
//* RETURNS:
//*
//*********************************************************************
BOOL
GetAllScsiInfo(
BOOL Rescan,
PSCSI_HOST_ADAPTER_LIST AdapterList,
POPTIONLISTC OptionList)
{
PSCSI_HOST_ADAPTER AdapterInfo;
PSCSIDEVC Adapter;
BYTE ScsiPortNumber = 0;
UCHAR Count;
SCSI_ADAPTER_REGC AdapterReg;
//
//---- Will hold all the info for all the devices on one port
//
PSCSI_ADAPTER_BUS_INFO AdapterInfoBuffer;
//
//---- Index into DeviceInfo
//
int ScsiBusIndex;
int DeviceIndex = 0;
//
//---- Allocate memory for bus data
//
AdapterInfoBuffer = (PSCSI_ADAPTER_BUS_INFO) malloc(0x400);
if(AdapterInfoBuffer == NULL)
{
return(FALSE);
}
//
//--- Make shure we start with an empty list
//
AdapterList->Clear();
//
//---- Loop they all the scsiports if we faile to open one
//---- we are done and will get out of this loop
//
while (GetScsiPortInfo(ScsiPortNumber,Rescan,
AdapterInfoBuffer,0x400))
{
//
//---- We have a new SCSI adapter
//
//
//--- Open the registry info for this adapter
//
AdapterReg.OpenAdapterRegKey(ScsiPortNumber);
//
//---- Add a new adapter structure to the list
//
Adapter = AdapterList->Append();
AdapterInfo = &Adapter->AdapterInfo;
//
//--- Init the basic adapter info
//
InitAdapter(
&AdapterReg,
AdapterInfo,
ScsiPortNumber);
//
//---- Get the adapters frindly name
//
GetAdapterFrindlyName(
AdapterInfo,
&AdapterReg,
OptionList);
DeviceIndex = 0;
//
//---- Loop threw all the bus's on the current adapter.
//
for (ScsiBusIndex=0; ScsiBusIndex < AdapterInfoBuffer->NumberOfBuses; ScsiBusIndex++)
{
DeviceIndex += ExtractDeviceInfo(
AdapterInfoBuffer,
ScsiPortNumber,
ScsiBusIndex,
&AdapterInfo->Devices,
&Count,
ALL_DEVICES);
AdapterInfo->BusCount++;
}
ScsiPortNumber++;
}
//
//----- We are done
//
free(AdapterInfoBuffer);
return(TRUE);
}
//*********************************************************************
//* FUNCTION:GetAdapterFrindlyName
//*
//*********************************************************************
VOID
GetAdapterFrindlyName(
PSCSI_HOST_ADAPTER AdapterInfo,
PSCSI_ADAPTER_REGC AdapterReg,
POPTIONLISTC OptionList)
{
if(! *AdapterInfo->Option.GetOptionName() )
{
//
//--- We do not have the devices frindly name
//--- so we need to get it from the inf.
//
if(OptionList->FindOptionOnOption(&AdapterInfo->Option))
{
//
//--- We got a frindly name for this device
//--- out of OptionList so lets save it in the registry.
//--- This is done so if someone removes the
//--- driver for this adapter but didn't reboot
//--- I still have a frindly name for it.
//
AdapterReg->SetAdapterRegFrindlyName(
AdapterInfo->Option.GetOptionName());
AdapterReg->SetAdapterRegMfgName(
AdapterInfo->Option.GetMfgName());
}
else
{
//
//----- Error. We have a scsi port but where unable to
//----- find its frindly name in any INF of CLASS
//----- SCSIAdapter. If we have a driver name we will use it
//----- if not we will use IDS_UnknowSCSIAdapter
//
if( *AdapterInfo->Option.GetDriverName() )
{
AdapterInfo->Option.SetOptionName(
AdapterInfo->Option.GetDriverName());
}
else
{
AdapterInfo->Option.SetOptionName(
Astr(GetString(IDS_UnknowSCSIAdapter)));
}
}
}
}
//*********************************************************************
//* FUNCTION:GetAllScsiTapeDeviceInfo
//*
//* PURPOSE: Gets the info on all scsi tape devices and stores is
//* in PAR2. If PAR1 == TRUE it will Rescan for any TAPE
//* devices and then do the same.
//* RETURNS:
//*
//*********************************************************************
VOID InitAdapter(
PSCSI_ADAPTER_REGC AdapterReg,
PSCSI_HOST_ADAPTER AdapterInfo,
int ScsiPortNumber)
{
AdapterInfo->BusCount = 0;
AdapterInfo->Port = ScsiPortNumber;
//
//--- Init both DriverName and Option with driver name
//--- from the scsiport registry info
//
AdapterReg->GetAdapterRegDriverName(
AdapterInfo->Option.GetDriverName(),
MAX_OPTION_LENGTH);
AdapterInfo->Option.SetOption(AdapterInfo->Option.GetDriverName());
//
//--- See if we saved the frindly name already
//
AdapterReg->GetAdapterRegFrindlyName(
AdapterInfo->Option.GetOptionName(),
MAX_OPTION_DISPLAY_STRING_LENGTH);
AdapterReg->GetAdapterRegMfgName(
AdapterInfo->Option.GetMfgName(),
MAX_OPTION_DISPLAY_STRING_LENGTH);
//
//---- Crate the ScsiPort# string
//
swprintf(AdapterInfo->DeviceName,L"ScsiPort%i",ScsiPortNumber);
//
//--- Get the resources for this adapter
//
GetAdapterResources(AdapterInfo);
}
//*********************************************************************
//* FUNCTION:GetAdapterResources
//*
//* PURPOSE:
//* RETURNS:
//*********************************************************************
VOID
GetAdapterResources(
PSCSI_HOST_ADAPTER AdapterInfo)
{
CHAR RegKeyString[MaxRegKeySize];
HKEY HKInitiator;
LONG Ret;
DWORD ValueType;
BYTE ResourceListBuff[512];
DWORD ResourceListBuffSize = 512;
//
//---- Open adapter key
//
_snprintf(RegKeyString,MaxRegKeySize,
SCSI_INITIATOR_RESOURCE_STRING, (char*)AdapterInfo->Option.GetDriverName());
Ret = RegOpenKeyA(HKEY_LOCAL_MACHINE,RegKeyString,&HKInitiator);
if(Ret != ERROR_SUCCESS)
return;
//
//---- Get resources for this adapter from the resourcemap in
//---- the registry.
//
_snwprintf((WCHAR*)RegKeyString,MaxRegKeySize,
L"\\Device\\%s.Raw",AdapterInfo->DeviceName);
Ret = RegQueryValueEx(HKInitiator,
(WCHAR*)RegKeyString,
0,
&ValueType,
ResourceListBuff,
&ResourceListBuffSize);
if(Ret != ERROR_SUCCESS)
return;
//
//---- Extract the resource info
//
ExtractResourceFromResourceList(
&AdapterInfo->Configuration,
(VOID*) ResourceListBuff,
FirstResourceOnly,
NULL);
}
//*********************************************************************
//* FUNCTION:OpenScsiPort
//*
//* RETURNS:
//*
//*********************************************************************
BOOL
GetScsiPortInfo(
BYTE Port,
BOOL Rescan,
PSCSI_ADAPTER_BUS_INFO AdapterInfoBuffer,
DWORD AdapterInfoBufferSize)
{
HANDLE ScsiPortHandle;
DWORD BytesTransferred;
//
//---- Open Scsi Port
//
ScsiPortHandle = OpenScsiPort( Port);
if( ScsiPortHandle == INVALID_HANDLE_VALUE )
return(FALSE);
//
//---- Rescan Current Scsi Port if Rescan == TRUE
//
if(Rescan)
{
if( !DeviceIoControl( ScsiPortHandle,
IOCTL_SCSI_RESCAN_BUS,NULL,0,NULL,0,&BytesTransferred,NULL ) )
{
CloseHandle(ScsiPortHandle);
return(FALSE);
}
}
//
//---- Get all the bus data.
//
memset(AdapterInfoBuffer,0,0x400);
if (!DeviceIoControl( ScsiPortHandle,
IOCTL_SCSI_GET_INQUIRY_DATA,NULL,0,AdapterInfoBuffer,
AdapterInfoBufferSize,&BytesTransferred,NULL))
{
CloseHandle( ScsiPortHandle);
return(FALSE);
}
CloseHandle(ScsiPortHandle);
return(TRUE);
}
//*********************************************************************
//* FUNCTION:GetAllScsiTapeDeviceInfo
//*
//* PURPOSE: Gets the info on all scsi tape devices and stores is
//* in PAR2. If PAR1 == TRUE it will Rescan for any TAPE
//* devices and then do the same.
//* RETURNS:
//*
//*********************************************************************
DWORD
ExtractDeviceInfo(
PSCSI_ADAPTER_BUS_INFO AdapterInfo,
BYTE ScsiPortNumber,
int ScsiBusIndex,
PDEVICEINFO_LIST TapeDeviceList,
UCHAR * DeviceCount,
BYTE DeviceTypes)
{
PSCSI_BUS_DATA BusData;
PSCSI_INQUIRY_DATA InquiryData;
PINQUIRYDATA DetailedInquiryData;
int ScsiDeviceIndex;
int DeviceIndex = -1;
PDEVICEINFO CurDeviceInfo;
PTAPEDEVC TapeDevice;
//
//---- Pointer to current Addapter info.
//
BusData = &AdapterInfo->BusData[ScsiBusIndex];
InquiryData = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo + BusData->InquiryDataOffset);
for (ScsiDeviceIndex=0; ScsiDeviceIndex < BusData->NumberOfLogicalUnits; ScsiDeviceIndex++)
{
//
// Determine the perpherial type.
//
//
//---- We are looking for a specific type or we want them all
//
if( (((PINQUIRYDATA)InquiryData->InquiryData)->DeviceType == DeviceTypes) ||
DeviceTypes == ALL_DEVICES)
{
DeviceIndex++;
TapeDevice = TapeDeviceList->Append();
CurDeviceInfo = &TapeDevice->DeviceInfo;
SetDeviceType(CurDeviceInfo ,InquiryData);
//
//---- Set pointer to product info
//
DetailedInquiryData = ((PINQUIRYDATA)InquiryData->InquiryData);
DetailedInquiryData->VendorSpecific[0] = 0;
CurDeviceInfo->PortNumber = ScsiPortNumber;
CurDeviceInfo->InitiatorID = BusData->InitiatorBusId;
CurDeviceInfo->BUS = ScsiBusIndex;
GetScsiMiniPortDriverName(ScsiPortNumber,
(char*)CurDeviceInfo->InitiatorNameString,60);
SaveDeviceInfo(
InquiryData,DetailedInquiryData,CurDeviceInfo);
//
//--- If this is a tape device
//--- do the tape device specific stuff.
//--- Like map the device name to a driver .
//
if(DeviceTypes == SEQUENTIAL_ACCESS_DEVICE)
{
GetScsiTapeDeviceMap(
ScsiPortNumber,
ScsiBusIndex,
InquiryData->TargetId,
InquiryData->Lun,
CurDeviceInfo->DeviceName,
60);
//FindOptionThatWouldClaimeDevice(CurDeviceInfo);
}
TapeDevice->InitType();
}
InquiryData = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo + InquiryData->NextInquiryDataOffset);
}
return(*DeviceCount);
}
//*********************************************************************
//* FUNCTION:SaveDeviceInfo
//*
//*********************************************************************
VOID
SetDeviceType(
PDEVICEINFO DeviceInfo,
PSCSI_INQUIRY_DATA InquiryData)
{
//
//---- Translate devcie types.
//
DebugPrintf(("-- SetDeviceType: %i\n",
((PINQUIRYDATA)InquiryData->InquiryData)->DeviceType));
switch( ((PINQUIRYDATA)InquiryData->InquiryData)->DeviceType )
{
case DIRECT_ACCESS_DEVICE:
case OPTICAL_DEVICE:
if( ((PINQUIRYDATA)InquiryData->InquiryData)->RemovableMedia )
DeviceInfo->DeviceType = TYPE_RM_DISK;
else
DeviceInfo->DeviceType = TYPE_DISK;
break;
case SEQUENTIAL_ACCESS_DEVICE:
DeviceInfo->DeviceType = TYPE_TAPE;
break;
case PRINTER_DEVICE:
DeviceInfo->DeviceType = TYPE_PRINTER;
break;
case PROCESSOR_DEVICE:
DeviceInfo->DeviceType = TYPE_SCANNER;
break;
case WRITE_ONCE_READ_MULTIPLE_DEVICE:
DeviceInfo->DeviceType = TYPE_WORM;
break;
case READ_ONLY_DIRECT_ACCESS_DEVICE:
DeviceInfo->DeviceType = TYPE_CD_ROM;
break;
case SCANNER_DEVICE:
DeviceInfo->DeviceType = TYPE_SCANNER;
break;
//case OPTICAL_DEVICE:
// DeviceInfo->DeviceType = TYPE_OPTICAL;
// break;
case MEDIUM_CHANGER:
DeviceInfo->DeviceType = TYPE_JUKEBOX;
break;
case COMMUNICATION_DEVICE:
DeviceInfo->DeviceType = TYPE_JUKEBOX;
break;
default:
DeviceInfo->DeviceType = TYPE_NON;
break;
}
//
//
//
}
//*********************************************************************
//* FUNCTION:SaveDeviceInfo
//*
//*********************************************************************
VOID
SaveDeviceInfo(
PSCSI_INQUIRY_DATA InquiryData,
PINQUIRYDATA DetailedInquiryData,
PDEVICEINFO DeviceInfo)
{
DeviceInfo->ID = InquiryData->TargetId;
DeviceInfo->LUN = InquiryData->Lun;
strncpy((char*)DeviceInfo->VendorId,(char*)DetailedInquiryData->VendorId,
sizeof( (((INQUIRYDATA * )0)->VendorId)) );
strncpy((char*)DeviceInfo->ProductId,(char*)DetailedInquiryData->ProductId,
sizeof( (((INQUIRYDATA * )0)->ProductId)) );
strncpy((char*)DeviceInfo->ProductRevisionLevel,(char*)DetailedInquiryData->ProductRevisionLevel,
sizeof( (((INQUIRYDATA * )0)->ProductRevisionLevel)) );
DeviceInfo->DeviceClaimed = InquiryData->DeviceClaimed;
DeviceInfo->SubType = SUB_TYPE_SCSI;
//
//--- No idea on option list index at this time
//
//DeviceInfo->OptionIndex = UNKNOW_OPTIONLIST_INDEX;
GenerateDeviceDisplayName(DeviceInfo);
DebugPrintf(("-- SaveDeviceInfo\n"));
DebugPrintf(("-- DeviceInfo->ID=%i\n",DeviceInfo->ID));
DebugPrintf(("-- DeviceInfo->LUN=%i\n",DeviceInfo->LUN));
DebugPrintf(("-- DeviceInfo->VendorId=%s\n",DeviceInfo->VendorId));
DebugPrintf(("-- DeviceInfo->ProductId=%s\n",DeviceInfo->ProductId));
DebugPrintf(("-- DeviceInfo->ProductRevisionLevel=%s\n",DeviceInfo->ProductRevisionLevel));
DebugPrintf(("-- DeviceInfo->DeviceClaimed=%i\n",DeviceInfo->DeviceClaimed));
DebugPrintf(("-- DeviceInfo->DeviceInfo->SubType=%i\n",DeviceInfo->SubType));
}
//*********************************************************************
//* FUNCTION:GenerateDeviceDisplayName
//*
//* PURPOSE: Creates a DeviceName that the user will see from
//* VendorId + ProductId
//* RETURNS:
//*
//*********************************************************************
VOID
GenerateDeviceDisplayName(
PDEVICEINFO DeviceInfo)
{
UCHAR * p;
int i;
//
//--- Make a copy of VendorId and ProductId.
//--- Since I do not want to change the original for detection.
//
memcpy((char*)DeviceInfo->DisplayVendorId,(char*)DeviceInfo->VendorId,VENDER_ID_LEN);
memcpy((char*)DeviceInfo->DisplayProductId,(char*)DeviceInfo->ProductId,PRODUCT_ID_LEN);
DeviceInfo->DisplayVendorId[VENDER_ID_LEN] = '\0';
DeviceInfo->DisplayProductId[PRODUCT_ID_LEN] = '\0';
//
//--- Remove trailing non printible chars and spaces
//
p = DeviceInfo->DisplayVendorId + VENDER_ID_LEN-1;
while( (p > DeviceInfo->DisplayVendorId) && ( !isprint(*p) ||(*p == ' ')) )
{
*p = '\0';
p--;
}
p = DeviceInfo->DisplayProductId + PRODUCT_ID_LEN-1;
while( (p > DeviceInfo->DisplayProductId) && ( !isprint(*p) || (*p == ' ')) )
{
*p = '\0';
p--;
}
//
//---- Create DeviceDisplayName
//
strcpy((char*)DeviceInfo->DeviceDisplayName,(char*)DeviceInfo->DisplayVendorId);
strcat((char*)DeviceInfo->DeviceDisplayName," ");
strcat((char*)DeviceInfo->DeviceDisplayName,(char*)DeviceInfo->DisplayProductId);
}
//*********************************************************************
//* FUNCTION:GetScsiTapeDeviceMap
//*
//* PURPOSE: Get the tape# identifer from the registry for this
//* tape device.
//* RETURNS:
//*
//*********************************************************************
VOID
GetScsiTapeDeviceMap(
UCHAR PortNumber,
UCHAR BUS,
UCHAR DeviceID,
UCHAR DeviceLUN,
UCHAR * DeviceName,
DWORD BuffLen)
{
CHAR RegKeyString[MaxRegKeySize];
HKEY HK;
int Ret;
DWORD Type;
DWORD Len = BuffLen;
//
//---- Create Reg key string to open
//
_snprintf(RegKeyString,MaxRegKeySize,SCSI_DEVICE_NAME_STRING,
PortNumber,
BUS,
DeviceID,
DeviceLUN);
//
//--- Open key
//
Ret = RegOpenKeyA(HKEY_LOCAL_MACHINE,RegKeyString,&HK);
if(Ret != ERROR_SUCCESS)
{
//
//--- Key didn't open
//
strcpy((char*)DeviceName,Astr(GetString(IDS_NotAvailible)) );
return;
}
//
//--- Get value data for TAPE_DEVICE_STRING. This is
//--- the tape% string
//
Ret = RegQueryValueExA( HK, TAPE_DEVICE_STRING,
NULL, &Type,(LPBYTE) DeviceName, &Len);
if(Ret != ERROR_SUCCESS)
{
//
//--- Value Name not found
//
strcpy((char*)DeviceName,Astr(GetString(IDS_NotAvailible)) );
return;
}
return;
}