Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

255 lines
9.2 KiB

/***************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name:
Parport.sys - Parallel port (IEEE 1284, IEEE 1284.3) driver.
File Name:
driverEntry.c
Abstract:
DriverEntry routine - driver initialization
Environment:
Kernel mode only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Copyright (c) 2000 Microsoft Corporation. All Rights Reserved.
Revision History:
2000-07-25 - Doug Fritz
- code cleanup, add comments, add copyright
Author(s):
Doug Fritz
****************************************************************************/
#include "pch.h"
/************************************************************************/
/* DriverEntry */
/************************************************************************/
//
// Routine Description:
//
// This is the DriverEntry routine -- the first function called
// after the driver has been loaded into memory.
//
// Arguments:
//
// DriverObject - points to the DRIVER_OBJECT for this driver
// RegPath - the service registry key for this driver
//
// Return Value:
//
// STATUS_SUCCESS - on success
// STATUS_NO_MEMORY - if unable to allocate pool
//
// Notes:
//
// Log:
//
/************************************************************************/
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegPath
)
{
//
// Save a copy of *RegPath in driver global RegistryPath for future reference.
//
// UNICODE_NULL terminate the path so that we can safely use RegistryPath.Buffer
// as a PWSTR.
//
{
USHORT size = RegPath->Length + sizeof(WCHAR);
RegistryPath.Buffer = ExAllocatePool( (PagedPool | POOL_COLD_ALLOCATION), size );
if( NULL == RegistryPath.Buffer ) {
return STATUS_NO_MEMORY;
}
RegistryPath.Length = 0;
RegistryPath.MaximumLength = size;
RtlCopyUnicodeString( &RegistryPath, RegPath );
RegistryPath.Buffer[ size/sizeof(WCHAR) - 1 ] = UNICODE_NULL;
}
//
// Initialize Driver Globals
//
// Non-zero means don't raise IRQL from PASSIVE_LEVEL to DISPATCH_LEVEL
// when doing CENTRONICS mode (SPP) writes.
SppNoRaiseIrql = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"SppNoRaiseIrql", &SppNoRaiseIrql );
// Non-zero means override CENTRONICS as the default Forward mode and/or NIBBLE as
// the default Reverse mode. Valid modes are those defined in ntddpar.h as
// parameters for IOCTL_IEEE1284_NEGOTIATE.
// *** Warning: invalid settings and/or setting/device incompatibilities can render
// the port unusable until the settings are corrected
DefaultModes = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DefaultModes", &DefaultModes );
// Set tracing level for driver DbgPrint messages. Trace values defined in debug.h.
// Zero means no trace output.
Trace = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"Trace", &Trace );
// Request DbgBreakPoint on driver events. Event values defined in debug.h.
// Zero means no breakpoints requested.
Break = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"Break", &Break );
// Mask OFF debug spew for specific devices. See debug.h for flag definitions
// 0 means allow debug spew for that device
// ~0 means mask OFF all (show NO) debug spew for that device type
DbgMaskFdo = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DbgMaskFdo", &DbgMaskFdo );
DbgMaskRawPort = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DbgMaskRawPort", &DbgMaskRawPort );
DbgMaskDaisyChain0 = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DbgMaskDaisyChain0", &DbgMaskDaisyChain0 );
DbgMaskDaisyChain1 = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DbgMaskDaisyChain1", &DbgMaskDaisyChain1 );
DbgMaskEndOfChain = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DbgMaskEndOfChain", &DbgMaskEndOfChain );
DbgMaskLegacyZip = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DbgMaskLegacyZip", &DbgMaskLegacyZip );
DbgMaskNoDevice = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DbgMaskNoDevice", &DbgMaskNoDevice );
#if 1 == DBG_SHOW_BYTES
DbgShowBytes = 1;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"DbgShowBytes", &DbgShowBytes );
#endif
//
// Allow asserts? non-zero means allow assertions
//
AllowAsserts = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"AllowAsserts", &AllowAsserts );
// Non-zero means enable detection of Iomega Legacy Zip-100 drives that use
// an Iomega proprietary Select/Deselect mechanism rather than the Select/Deselect
// mechanism defined by IEEE 1284.3. (These drives pre-date IEEE 1284.3)
// *** Note: if zero, this registry setting is checked again during every PnP QDR/BusRelations
// query to see if the user has enabled detection via the Ports property page "Enable
// legacy Plug and Play detection" checkbox.
ParEnableLegacyZip = 0;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"ParEnableLegacyZip", &ParEnableLegacyZip );
// Default timeout when trying to acquire exclusive access to the (shared) port
{
const ULONG halfSecond = 500; // in milliseconds
const ULONG fiveSeconds = 5000;
ULONG requestedTimeout = halfSecond;
PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"AcquirePortTimeout", &requestedTimeout );
if( requestedTimeout < halfSecond ) {
requestedTimeout = halfSecond;
} else if( requestedTimeout > fiveSeconds ) {
requestedTimeout = fiveSeconds;
}
PPT_SET_RELATIVE_TIMEOUT_IN_MILLISECONDS( AcquirePortTimeout, requestedTimeout );
}
{
//
// register for callbacks so that we can detect switch between
// AC and battery power and tone done "polling for printers"
// when machine switches to battery power.
//
OBJECT_ATTRIBUTES objAttributes;
UNICODE_STRING callbackName;
NTSTATUS localStatus;
RtlInitUnicodeString(&callbackName, L"\\Callback\\PowerState");
InitializeObjectAttributes(&objAttributes,
&callbackName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
localStatus = ExCreateCallback(&PowerStateCallbackObject,
&objAttributes,
FALSE,
TRUE);
if( STATUS_SUCCESS == localStatus ) {
PowerStateCallbackRegistration = ExRegisterCallback(PowerStateCallbackObject,
PowerStateCallback,
NULL);
}
}
//
// Set dispatch table entries for IRP_MJ_* functions that we handle
//
DriverObject->MajorFunction[ IRP_MJ_CREATE ] = PptDispatchCreateOpen;
DriverObject->MajorFunction[ IRP_MJ_CLOSE ] = PptDispatchClose;
DriverObject->MajorFunction[ IRP_MJ_CLEANUP ] = PptDispatchCleanup;
DriverObject->MajorFunction[ IRP_MJ_READ ] = PptDispatchRead;
DriverObject->MajorFunction[ IRP_MJ_WRITE ] = PptDispatchWrite;
DriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL ] = PptDispatchDeviceControl;
DriverObject->MajorFunction[ IRP_MJ_INTERNAL_DEVICE_CONTROL ] = PptDispatchInternalDeviceControl;
DriverObject->MajorFunction[ IRP_MJ_QUERY_INFORMATION ] = PptDispatchQueryInformation;
DriverObject->MajorFunction[ IRP_MJ_SET_INFORMATION ] = PptDispatchSetInformation;
DriverObject->MajorFunction[ IRP_MJ_PNP ] = PptDispatchPnp;
DriverObject->MajorFunction[ IRP_MJ_POWER ] = PptDispatchPower;
DriverObject->MajorFunction[ IRP_MJ_SYSTEM_CONTROL ] = PptDispatchSystemControl;
DriverObject->DriverExtension->AddDevice = P5AddDevice;
DriverObject->DriverUnload = PptUnload;
//
// Break on user request
// (typically via registry setting ...\Services\Parport\Parameters : Break : REG_DWORD : 0x1)
//
// This is a useful breakpoint in order to manually set appropriate breakpoints elsewhere in the driver.
//
PptBreakOnRequest( PPT_BREAK_ON_DRIVER_ENTRY, ("PPT_BREAK_ON_DRIVER_ENTRY - BreakPoint requested") );
DD(NULL,DDT,"Parport DriverEntry - SUCCESS\n");
return STATUS_SUCCESS;
}