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;
|
|||
|
}
|