617 lines
21 KiB
C
617 lines
21 KiB
C
//+-------------------------------------------------------------------------
|
||
//
|
||
// Microsoft Windows
|
||
//
|
||
// Copyright (C) Microsoft Corporation, 1999 - 1999
|
||
//
|
||
// File: ppa3x.c
|
||
//
|
||
//--------------------------------------------------------------------------
|
||
|
||
#include "pch.h"
|
||
|
||
|
||
VOID
|
||
ParCheckEnableLegacyZipFlag()
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initialize debugging variables from registry; set to default values
|
||
if anything fails.
|
||
|
||
Arguments:
|
||
|
||
RegistryPath - Root path in registry where we should look
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS Status;
|
||
RTL_QUERY_REGISTRY_TABLE paramTable[2];
|
||
ULONG defaultZipEnabled = 0;
|
||
PWSTR suffix = L"\\Parameters";
|
||
UNICODE_STRING path = {0,0,0};
|
||
ULONG length;
|
||
|
||
//
|
||
// set up table entries for call to RtlQueryRegistryValues
|
||
//
|
||
RtlZeroMemory( paramTable, sizeof(paramTable));
|
||
|
||
paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||
paramTable[0].Name = (PWSTR)L"ParEnableLegacyZip";
|
||
paramTable[0].EntryContext = &ParEnableLegacyZip;
|
||
paramTable[0].DefaultType = REG_DWORD;
|
||
paramTable[0].DefaultData = &defaultZipEnabled;
|
||
paramTable[0].DefaultLength = sizeof(ULONG);
|
||
|
||
//
|
||
// leave paramTable[2] as all zeros - this terminates the table
|
||
//
|
||
|
||
Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
|
||
RegistryPath.Buffer,
|
||
¶mTable[0],
|
||
NULL,
|
||
NULL);
|
||
|
||
ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - status from RtlQueryRegistryValues = %x\n", Status) );
|
||
|
||
if( !NT_SUCCESS( Status ) ) {
|
||
// registry read failed, use defaults
|
||
ParEnableLegacyZip = defaultZipEnabled;
|
||
return;
|
||
}
|
||
|
||
if( ParEnableLegacyZip ) {
|
||
// we found a non-zero value - enable PnP for old parallel port Zip
|
||
ParDump2(PARPNP1, ("ppa3x::ParCheckEnableLegacyZipFlag - FOUND - ParEnableLegacyZip Flag = %08x\n", ParEnableLegacyZip) );
|
||
return;
|
||
}
|
||
|
||
|
||
//
|
||
// We didn't find the registry flag, maybe it's under the Parameters subkey
|
||
//
|
||
|
||
|
||
// compute the size of the path including the "parameters" suffix
|
||
ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - RegPath length = %d\n", RegistryPath.Length) );
|
||
|
||
length = ( sizeof(WCHAR) * wcslen( suffix ) ) + sizeof(UNICODE_NULL);
|
||
ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - suffix length = %d\n", length) );
|
||
|
||
length += RegistryPath.Length;
|
||
ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - total dest length = %d\n", length) );
|
||
|
||
|
||
// build the path
|
||
path.Buffer = ExAllocatePool( PagedPool, length );
|
||
if( NULL == path.Buffer ) {
|
||
// out of pool, use defaults
|
||
ParEnableLegacyZip = defaultZipEnabled;
|
||
return;
|
||
}
|
||
|
||
RtlZeroMemory( path.Buffer, length );
|
||
path.MaximumLength = (USHORT)length;
|
||
RtlCopyUnicodeString( &path, &RegistryPath );
|
||
RtlAppendUnicodeToString( &path, suffix );
|
||
ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - path = <%wZ>\n", &path) );
|
||
|
||
|
||
// query at new location in registry
|
||
Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
|
||
path.Buffer,
|
||
¶mTable[0],
|
||
NULL,
|
||
NULL);
|
||
|
||
RtlFreeUnicodeString( &path );
|
||
|
||
ParDump2(PARPNP4, ("ppa3x::ParCheckEnableLegacyZipFlag - status from RtlQueryRegistryValues on SubKey = %x\n", Status) );
|
||
|
||
if( !NT_SUCCESS( Status ) ) {
|
||
// registry read failed, use defaults
|
||
ParEnableLegacyZip = defaultZipEnabled;
|
||
return;
|
||
}
|
||
|
||
ParDump2(PARPNP1, ("ppa3x::ParCheckEnableLegacyZipFlag - FOUND SubKey ParEnableLegacyZip Flag = %08x\n", ParEnableLegacyZip) );
|
||
|
||
}
|
||
|
||
BOOLEAN
|
||
ParLegacyZipCheckDevice(
|
||
PUCHAR Controller
|
||
)
|
||
{
|
||
WRITE_PORT_UCHAR( Controller+DCR_OFFSET, (UCHAR)(DCR_NOT_INIT | DCR_AUTOFEED) );
|
||
|
||
if ( (READ_PORT_UCHAR( Controller+DSR_OFFSET ) & DSR_NOT_FAULT) == DSR_NOT_FAULT ) {
|
||
|
||
WRITE_PORT_UCHAR( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT );
|
||
|
||
if ( (READ_PORT_UCHAR( Controller+DSR_OFFSET ) & DSR_NOT_FAULT) != DSR_NOT_FAULT ) {
|
||
// A device was found
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
// No device is there
|
||
return FALSE;
|
||
|
||
} // end PptLegacyZipCheckDevice()
|
||
|
||
PCHAR ParBuildLegacyZipDeviceId()
|
||
{
|
||
ULONG size = sizeof(PAR_LGZIP_PSEUDO_1284_ID_STRING) + sizeof(NULL);
|
||
PCHAR id = ExAllocatePool(PagedPool, size);
|
||
if( id ) {
|
||
RtlZeroMemory( id, size );
|
||
RtlCopyMemory( id, ParLegacyZipPseudoId, size - sizeof(NULL) );
|
||
return id;
|
||
} else {
|
||
return NULL;
|
||
}
|
||
}
|
||
PCHAR
|
||
Par3QueryLegacyZipDeviceId(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
OUT PCHAR CallerDeviceIdBuffer, OPTIONAL
|
||
IN ULONG CallerBufferSize,
|
||
OUT PULONG DeviceIdSize,
|
||
IN BOOLEAN bReturnRawString // TRUE == include the 2 size bytes in the returned string
|
||
// FALSE == discard the 2 size bytes
|
||
)
|
||
{
|
||
USHORT deviceIdSize;
|
||
PCHAR deviceIdBuffer;
|
||
|
||
UNREFERENCED_PARAMETER( Extension );
|
||
|
||
// initialize returned size in case we have an error
|
||
*DeviceIdSize = 0;
|
||
|
||
deviceIdBuffer = ParBuildLegacyZipDeviceId();
|
||
if( !deviceIdBuffer ) {
|
||
// error, likely out of resources
|
||
return NULL;
|
||
}
|
||
|
||
deviceIdSize = (USHORT) strlen(deviceIdBuffer);
|
||
*DeviceIdSize = deviceIdSize;
|
||
if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize) ) {
|
||
// caller supplied buffer is large enough, use it
|
||
RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
|
||
RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
|
||
ExFreePool( deviceIdBuffer );
|
||
return CallerDeviceIdBuffer;
|
||
} else {
|
||
// caller buffer too small, return pointer to our buffer
|
||
return deviceIdBuffer;
|
||
}
|
||
}
|
||
|
||
PDEVICE_OBJECT
|
||
ParCreateLegacyZipPdo(
|
||
IN PDEVICE_OBJECT LegacyPodo,
|
||
UCHAR Dot3Id
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Create PDO for legacy Zip Drive
|
||
|
||
LegacyPodo - points to the Legacy PODO for the port
|
||
|
||
Return Value:
|
||
|
||
PDEVICE_OBJECT - on success, points to the PDO we create
|
||
NULL - otherwise
|
||
|
||
--*/
|
||
{
|
||
PDEVICE_EXTENSION legacyExt = LegacyPodo->DeviceExtension;
|
||
PDRIVER_OBJECT driverObject = LegacyPodo->DriverObject;
|
||
PDEVICE_OBJECT fdo = legacyExt->ParClassFdo;
|
||
UNICODE_STRING className = {0,0,NULL};
|
||
NTSTATUS status;
|
||
PCHAR deviceIdString = NULL;
|
||
ULONG deviceIdLength = 0;
|
||
PDEVICE_OBJECT newDevObj = NULL;
|
||
PDEVICE_EXTENSION newDevExt;
|
||
ULONG idTry = 1;
|
||
ULONG maxIdTries = 3;
|
||
|
||
BOOLEAN useModifiedClassName = FALSE;
|
||
UNICODE_STRING modifiedClassName;
|
||
UNICODE_STRING suffix;
|
||
UNICODE_STRING dash;
|
||
WCHAR suffixBuffer[10];
|
||
ULONG number = 0;
|
||
ULONG maxNumber = 256;
|
||
ULONG newLength;
|
||
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Query for PnP device
|
||
//
|
||
while( (NULL == deviceIdString) && (idTry <= maxIdTries) ) {
|
||
if( Dot3Id == DOT3_LEGACY_ZIP_ID) {
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - calling ParBuildLegacyZipDeviceId()\n"));
|
||
deviceIdString = ParBuildLegacyZipDeviceId();
|
||
if(deviceIdString)
|
||
{
|
||
deviceIdLength = strlen( deviceIdString );
|
||
}
|
||
} else{
|
||
ASSERT(FALSE); // should never get here
|
||
deviceIdString = Par3QueryDeviceId(legacyExt, NULL, 0, &deviceIdLength, FALSE, FALSE);
|
||
}
|
||
|
||
if( NULL == deviceIdString ) {
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - no 1284 ID on try %d\n", idTry) );
|
||
KeStallExecutionProcessor(1);
|
||
++idTry;
|
||
} else {
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - devIdString=<%s> on try %d\n", deviceIdString, idTry) );
|
||
}
|
||
}
|
||
|
||
if( !deviceIdString ) {
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - no 1284 ID, bail out\n") );
|
||
return NULL;
|
||
}
|
||
|
||
|
||
//
|
||
// Found PnP Device, create a PDO to represent the device
|
||
// - create classname
|
||
// - create device object
|
||
// - initialize device object and extension
|
||
// - create symbolic link
|
||
// - register for PnP TargetDeviceChange notification
|
||
//
|
||
|
||
|
||
//
|
||
// Create a class name of the form \Device\ParallelN,
|
||
//
|
||
ParMakeDotClassNameFromBaseClassName(&legacyExt->ClassName, Dot3Id, &className);
|
||
if( !className.Buffer ) {
|
||
// unable to construct ClassName
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - unable to construct ClassName for device\n") );
|
||
ExFreePool(deviceIdString);
|
||
return NULL;
|
||
}
|
||
|
||
|
||
//
|
||
// create device object
|
||
//
|
||
status = ParCreateDevice(driverObject, sizeof(DEVICE_EXTENSION), &className,
|
||
FILE_DEVICE_PARALLEL_PORT, 0, TRUE, &newDevObj);
|
||
|
||
///
|
||
if( status == STATUS_OBJECT_NAME_COLLISION ) {
|
||
//
|
||
// old name is still in use, appending a suffix and try again
|
||
//
|
||
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - ParCreateDevice FAILED due to name Collision on <%wZ> - retry\n", &className));
|
||
|
||
useModifiedClassName = TRUE;
|
||
|
||
suffix.Length = 0;
|
||
suffix.MaximumLength = sizeof(suffixBuffer);
|
||
suffix.Buffer = suffixBuffer;
|
||
|
||
RtlInitUnicodeString( &dash, (PWSTR)L"-" );
|
||
|
||
newLength = className.MaximumLength + 5*sizeof(WCHAR); // L"-XXX" suffix
|
||
modifiedClassName.Length = 0;
|
||
modifiedClassName.MaximumLength = (USHORT)newLength;
|
||
modifiedClassName.Buffer = ExAllocatePool(PagedPool, newLength);
|
||
if( NULL == modifiedClassName.Buffer ) {
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - ParCreateDevice FAILED - no PagedPool avail\n"));
|
||
ExFreePool(deviceIdString);
|
||
RtlFreeUnicodeString( &className );
|
||
return NULL;
|
||
}
|
||
|
||
while( ( status == STATUS_OBJECT_NAME_COLLISION ) && ( number <= maxNumber ) ) {
|
||
|
||
status = RtlIntegerToUnicodeString(number, 10, &suffix);
|
||
if ( !NT_SUCCESS(status) ) {
|
||
ExFreePool(deviceIdString);
|
||
RtlFreeUnicodeString( &className );
|
||
RtlFreeUnicodeString( &modifiedClassName );
|
||
return NULL;
|
||
}
|
||
|
||
RtlCopyUnicodeString( &modifiedClassName, &className );
|
||
RtlAppendUnicodeStringToString( &modifiedClassName, &dash );
|
||
RtlAppendUnicodeStringToString( &modifiedClassName, &suffix );
|
||
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - trying ParCreateDevice with className <%wZ>\n", &modifiedClassName));
|
||
status = ParCreateDevice(driverObject, sizeof(DEVICE_EXTENSION), &modifiedClassName,
|
||
FILE_DEVICE_PARALLEL_PORT, 0, TRUE, &newDevObj);
|
||
if( NT_SUCCESS( status ) ) {
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - ParCreateDevice returned SUCCESS with className <%wZ>\n", &modifiedClassName));
|
||
} else {
|
||
++number;
|
||
}
|
||
}
|
||
}
|
||
///
|
||
|
||
if( useModifiedClassName ) {
|
||
// copy modifiedClassName to className
|
||
RtlFreeUnicodeString( &className );
|
||
className = modifiedClassName;
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - copy useModifiedClassName to className - className=<%wZ>\n", &className));
|
||
}
|
||
|
||
|
||
if( !NT_SUCCESS(status) ) {
|
||
// unable to create device object, bail out
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - unable to create device object "
|
||
"className=<%wZ>, bail out - status=%x\n", &className, status) );
|
||
ExFreePool(deviceIdString);
|
||
RtlFreeUnicodeString(&className);
|
||
ParLogError(fdo->DriverObject, NULL, PhysicalZero, PhysicalZero,
|
||
0, 0, 0, 9, STATUS_SUCCESS, PAR_INSUFFICIENT_RESOURCES);
|
||
return NULL;
|
||
} else {
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - device created <%wZ>\n", &className));
|
||
}
|
||
//
|
||
// device object created
|
||
//
|
||
newDevExt = newDevObj->DeviceExtension;
|
||
|
||
|
||
//
|
||
// initialize device object and extension
|
||
//
|
||
ParInitCommonDOPre(newDevObj, fdo, &className);
|
||
|
||
status = ParInitPdo(newDevObj, (PUCHAR)deviceIdString, deviceIdLength, LegacyPodo, Dot3Id);
|
||
if( !NT_SUCCESS( status ) ) {
|
||
// initialization failed, clean up and bail out
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - call to ParInitPdo failed, bail out\n") );
|
||
ParAcquireListMutexAndKillDeviceObject(fdo, newDevObj);
|
||
return NULL;
|
||
}
|
||
ParInitCommonDOPost(newDevObj);
|
||
|
||
//
|
||
// create symbolic link
|
||
//
|
||
if( newDevExt->SymbolicLinkName.Buffer ) {
|
||
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - ready to create symlink - SymbolicLinkName <%wZ>, ClassName <%wZ>\n",
|
||
&newDevExt->SymbolicLinkName, &newDevExt->ClassName) );
|
||
ParDump2(PARPNP1, (" - Length=%hd, MaximumLength=%hd\n", newDevExt->ClassName.Length, newDevExt->ClassName.MaximumLength) );
|
||
|
||
ASSERT(newDevExt->ClassName.Length < 100);
|
||
|
||
PAGED_CODE();
|
||
status = IoCreateUnprotectedSymbolicLink(&newDevExt->SymbolicLinkName, &newDevExt->ClassName);
|
||
|
||
if ( NT_SUCCESS(status) ) {
|
||
// note this in our extension for later cleanup
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - SymbolicLinkName -> ClassName = <%wZ> -> <%wZ>\n",
|
||
&newDevExt->SymbolicLinkName, &newDevExt->ClassName) );
|
||
newDevExt->CreatedSymbolicLink = TRUE;
|
||
|
||
// Write symbolic link map info to the registry.
|
||
status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
|
||
(PWSTR)L"PARALLEL PORTS",
|
||
newDevExt->ClassName.Buffer,
|
||
REG_SZ,
|
||
newDevExt->SymbolicLinkName.Buffer,
|
||
newDevExt->SymbolicLinkName.Length +
|
||
sizeof(WCHAR));
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
// unable to write map info to registry - continue anyway
|
||
ParLogError(newDevObj->DriverObject, newDevObj,
|
||
newDevExt->OriginalController, PhysicalZero,
|
||
0, 0, 0, 6, status, PAR_NO_DEVICE_MAP_CREATED);
|
||
}
|
||
|
||
} else {
|
||
|
||
// unable to create the symbolic link.
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - unable to create SymbolicLink - status = %x\n",status));
|
||
newDevExt->CreatedSymbolicLink = FALSE;
|
||
RtlFreeUnicodeString(&newDevExt->SymbolicLinkName);
|
||
ParLogError(newDevObj->DriverObject, newDevObj,
|
||
newDevExt->OriginalController, PhysicalZero,
|
||
0, 0, 0, 5, status, PAR_NO_SYMLINK_CREATED);
|
||
}
|
||
|
||
} else {
|
||
// extension does not contain a symbolic link name for us to use
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - extension does not contain a symbolic link for us to use\n"));
|
||
newDevExt->CreatedSymbolicLink = FALSE;
|
||
}
|
||
|
||
// End-Of-Chain PDO - register for PnP TargetDeviceChange notification
|
||
status = IoRegisterPlugPlayNotification(EventCategoryTargetDeviceChange,
|
||
0,
|
||
(PVOID)newDevExt->PortDeviceFileObject,
|
||
driverObject,
|
||
(PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) ParPnpNotifyTargetDeviceChange,
|
||
(PVOID)newDevObj,
|
||
&newDevExt->NotificationHandle);
|
||
|
||
if( !NT_SUCCESS(status) ) {
|
||
// PnP registration for TargetDeviceChange notification failed,
|
||
// clean up and bail out
|
||
ParDump2(PARPNP1, ("ppa3x::ParCreateLegacyZipPdo - PnP registration failed, killing PDO\n") );
|
||
ParAcquireListMutexAndKillDeviceObject(fdo, newDevObj);
|
||
return NULL;
|
||
}
|
||
|
||
return newDevObj;
|
||
}
|
||
|
||
PDEVICE_OBJECT
|
||
ParCreateAddLegacyZipPdo(
|
||
IN PDEVICE_OBJECT LegacyPodo
|
||
)
|
||
/*++
|
||
|
||
Create a new PDO for the legacy Zip and add the PDO to the list
|
||
of PDOs
|
||
|
||
--*/
|
||
{
|
||
PDEVICE_OBJECT newPdo = ParCreateLegacyZipPdo( LegacyPodo, DOT3_LEGACY_ZIP_ID );
|
||
|
||
if( newPdo ) {
|
||
ParAddDevObjToFdoList( newPdo );
|
||
}
|
||
|
||
return newPdo;
|
||
}
|
||
|
||
NTSTATUS
|
||
ParSelectLegacyZip( IN PDEVICE_OBJECT PortDeviceObject )
|
||
//
|
||
// Select Legacy Zip Drive
|
||
//
|
||
// Note: Caller must have already Acquired the Port prior to calling this function.
|
||
//
|
||
// Returns: STATUS_SUCCESS if drive selected, !STATUS_SUCCESS otherwise
|
||
//
|
||
{
|
||
PARALLEL_1284_COMMAND par1284Command;
|
||
NTSTATUS status;
|
||
|
||
ParDump2(PARLGZIP, ("rescan::ParSelectLegacyZip - Enter\n"));
|
||
|
||
par1284Command.ID = 0;
|
||
par1284Command.Port = 0;
|
||
par1284Command.CommandFlags = PAR_HAVE_PORT_KEEP_PORT | PAR_LEGACY_ZIP_DRIVE;
|
||
|
||
status = ParBuildSendInternalIoctl(IOCTL_INTERNAL_SELECT_DEVICE,
|
||
PortDeviceObject,
|
||
&par1284Command, sizeof(PARALLEL_1284_COMMAND),
|
||
NULL, 0, NULL);
|
||
|
||
ParDump2(PARLGZIP, ("rescan::ParSelectLegacyZip - returning status = %x\n", status));
|
||
return status;
|
||
}
|
||
|
||
NTSTATUS
|
||
ParDeselectLegacyZip( IN PDEVICE_OBJECT PortDeviceObject )
|
||
//
|
||
// Select Legacy Zip Drive
|
||
//
|
||
// Note: This function does not Release the port so the Caller still has
|
||
// the port after this function returns.
|
||
//
|
||
// Returns: STATUS_SUCCESS if drive deselected, !STATUS_SUCCESS otherwise
|
||
// (we don't expect this call to ever fail, but check just
|
||
// in case)
|
||
//
|
||
{
|
||
PARALLEL_1284_COMMAND par1284Command;
|
||
NTSTATUS status;
|
||
|
||
ParDump2(PARLGZIP, ("rescan::ParDeselectLegacyZip - Enter\n"));
|
||
|
||
par1284Command.ID = 0;
|
||
par1284Command.Port = 0;
|
||
par1284Command.CommandFlags = PAR_HAVE_PORT_KEEP_PORT | PAR_LEGACY_ZIP_DRIVE;
|
||
|
||
status = ParBuildSendInternalIoctl(IOCTL_INTERNAL_DESELECT_DEVICE,
|
||
PortDeviceObject,
|
||
&par1284Command, sizeof(PARALLEL_1284_COMMAND),
|
||
NULL, 0, NULL);
|
||
ParDump2(PARLGZIP, ("rescan::ParDeselectLegacyZip - returning status = %x\n", status));
|
||
return status;
|
||
}
|
||
|
||
BOOLEAN
|
||
ParZipPresent( PDEVICE_OBJECT LegacyPodo )
|
||
//
|
||
// Legacy Zip is present if we can SELECT it
|
||
//
|
||
{
|
||
BOOLEAN zipPresent = FALSE;
|
||
PDEVICE_EXTENSION legacyExt = LegacyPodo->DeviceExtension;
|
||
PDEVICE_OBJECT portDeviceObject = legacyExt->PortDeviceObject;
|
||
|
||
if( NT_SUCCESS( ParSelectLegacyZip( portDeviceObject ) ) ) {
|
||
ParDeselectLegacyZip( portDeviceObject );
|
||
zipPresent = TRUE;
|
||
}
|
||
|
||
return zipPresent;
|
||
}
|
||
|
||
VOID
|
||
ParRescanLegacyZip( IN PPAR_DEVOBJ_STRUCT CurrentNode )
|
||
//
|
||
// Rescan for change in Legacy Zip Drive, update PDO list if change detected
|
||
//
|
||
{
|
||
BOOLEAN hadZip;
|
||
BOOLEAN foundZip;
|
||
PDEVICE_OBJECT zipPdo;
|
||
|
||
ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - Enter\n"));
|
||
if( !ParEnableLegacyZip ) {
|
||
//
|
||
// legacy zip detection is disabled
|
||
//
|
||
ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - !ParEnableLegacyZip\n"));
|
||
|
||
//
|
||
// if we had a Legacy Zip then automatically mark it as hardware gone
|
||
//
|
||
zipPdo = CurrentNode->LegacyZipPdo;
|
||
if( zipPdo ) {
|
||
// we should never get here, but handle it if we do
|
||
ParMarkPdoHardwareGone( zipPdo->DeviceExtension );
|
||
}
|
||
return;
|
||
}
|
||
|
||
|
||
//
|
||
// Check for presence of Legacy Zip - update PDO list if we detect a change
|
||
//
|
||
hadZip = (NULL != CurrentNode->LegacyZipPdo);
|
||
foundZip = ParZipPresent( CurrentNode->LegacyPodo );
|
||
|
||
ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - hadZip=%s, foundZip=%s\n",
|
||
hadZip?"TRUE":"FALSE", foundZip?"TRUE":"FALSE"));
|
||
|
||
if( foundZip && !hadZip ) {
|
||
// we found a new Zip - create a PDO for it
|
||
ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - Found new Legacy Zip\n"));
|
||
ParCreateAddLegacyZipPdo( CurrentNode->LegacyPodo );
|
||
} else if( !foundZip && hadZip ) {
|
||
// our Zip went away - mark PDO as hardware gone
|
||
ParDump2(PARLGZIP, ("rescan::ParRescanLegacyZip - Had a Legacy Zip but now it's gone\n"));
|
||
zipPdo = CurrentNode->LegacyZipPdo;
|
||
ParMarkPdoHardwareGone( zipPdo->DeviceExtension );
|
||
}
|
||
|
||
return;
|
||
}
|