346 lines
6.9 KiB
C++
346 lines
6.9 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1990 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
Common
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Takes care of request which are common to all devices.
|
|||
|
|
|||
|
Also contains any function which is common to two or more devices.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ramon Juan San Andres (ramonsa) 26-Jun-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#define _NTAPI_ULIB_
|
|||
|
|
|||
|
#include "mode.hxx"
|
|||
|
#include "common.hxx"
|
|||
|
#include "com.hxx"
|
|||
|
#include "array.hxx"
|
|||
|
#include "arrayit.hxx"
|
|||
|
#include "stream.hxx"
|
|||
|
#include "system.hxx"
|
|||
|
#include "redir.hxx"
|
|||
|
#include "registry.hxx"
|
|||
|
#include "regvalue.hxx"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
CommonHandler(
|
|||
|
IN PREQUEST_HEADER Request
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Calls all the device handlers with the supplied request.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Request - Supplies pointer to request
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
ULONG Device; // Current device
|
|||
|
REDIR_STATUS Status;
|
|||
|
PPATH DevicePath;
|
|||
|
REGISTRY Registry;
|
|||
|
DSTRING ParentName;
|
|||
|
DSTRING KeyName;
|
|||
|
ARRAY ValueArray;
|
|||
|
PARRAY_ITERATOR Iterator;
|
|||
|
ULONG ErrorCode;
|
|||
|
PCBYTE Data;
|
|||
|
DSTRING PortName;
|
|||
|
DSTRING QualifiedName;
|
|||
|
PREGISTRY_VALUE_ENTRY Value;
|
|||
|
|
|||
|
|
|||
|
DebugPtrAssert( Request );
|
|||
|
DebugAssert( Request->DeviceType == DEVICE_TYPE_ALL );
|
|||
|
|
|||
|
//
|
|||
|
// If this is not a null request, then we pass this request to all
|
|||
|
// device handlers. Note that this means that a device handler must
|
|||
|
// NOT modify the request, otherwise the next device handler would
|
|||
|
// get a corrupted request.
|
|||
|
//
|
|||
|
if ( Request->RequestType != REQUEST_TYPE_NULL ) {
|
|||
|
|
|||
|
//
|
|||
|
// LPT devices
|
|||
|
//
|
|||
|
for ( Device = 1; Device <= LAST_LPT; Device++ ) {
|
|||
|
|
|||
|
if ( IsAValidLptDevice( DEVICE_TYPE_LPT, Device, &DevicePath ) ||
|
|||
|
REDIR::IsRedirected( &Status, DevicePath )
|
|||
|
) {
|
|||
|
|
|||
|
Request->DeviceType = DEVICE_TYPE_LPT;
|
|||
|
Request->DeviceNumber = Device;
|
|||
|
|
|||
|
//
|
|||
|
// Have it serviced
|
|||
|
//
|
|||
|
DeviceHandler[ DEVICE_TYPE_LPT ]( Request );
|
|||
|
DELETE( DevicePath );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// COM devices
|
|||
|
//
|
|||
|
if ( ParentName.Initialize( "" ) &&
|
|||
|
KeyName.Initialize( COMM_KEY_NAME ) &&
|
|||
|
ValueArray.Initialize() &&
|
|||
|
Registry.Initialize() &&
|
|||
|
Registry.QueryValues(
|
|||
|
PREDEFINED_KEY_LOCAL_MACHINE,
|
|||
|
&ParentName,
|
|||
|
&KeyName,
|
|||
|
&ValueArray,
|
|||
|
&ErrorCode
|
|||
|
) ) {
|
|||
|
|
|||
|
if ( Iterator = (PARRAY_ITERATOR)ValueArray.QueryIterator() ) {
|
|||
|
|
|||
|
while ( Value = (PREGISTRY_VALUE_ENTRY)(Iterator->GetNext() ) ) {
|
|||
|
|
|||
|
if ( Value->GetData( &Data ) ) {
|
|||
|
|
|||
|
if ( PortName.Initialize( (PWSTR)Data ) &&
|
|||
|
QualifiedName.Initialize( L"\\\\.\\" ) &&
|
|||
|
QualifiedName.Strcat( &PortName ) ) {
|
|||
|
|
|||
|
if ( SYSTEM::QueryFileType( &QualifiedName ) == CharFile ) {
|
|||
|
|
|||
|
Request->DeviceType = DEVICE_TYPE_COM;
|
|||
|
Request->DeviceName = &PortName;
|
|||
|
|
|||
|
DeviceHandler[ DEVICE_TYPE_COM ]( Request );
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DELETE( Iterator );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// CON device
|
|||
|
//
|
|||
|
Request->DeviceType = DEVICE_TYPE_CON;
|
|||
|
Request->DeviceNumber = 1;
|
|||
|
DeviceHandler[ DEVICE_TYPE_CON ]( Request );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
IsAValidDevice (
|
|||
|
IN DEVICE_TTYPE DeviceType,
|
|||
|
IN ULONG DeviceNumber,
|
|||
|
OUT PPATH *DevicePathPointer
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Determines if a certain device exists and optionally creates a path
|
|||
|
for the device.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DeviceType - Supplies the type of device
|
|||
|
DeviceNumber - Supplies the device number
|
|||
|
DeviceName - Supplies a pointer to a pointer to the path for
|
|||
|
the device.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if the device exists,
|
|||
|
FALSE otherwise.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DSTRING DeviceName;
|
|||
|
DSTRING QualifiedDeviceName;
|
|||
|
DSTRING Number;
|
|||
|
CHNUM Index;
|
|||
|
FILE_TYPE DriveType;
|
|||
|
PPATH DevicePath;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Determine what device we're working with.
|
|||
|
//
|
|||
|
switch ( DeviceType ) {
|
|||
|
|
|||
|
case DEVICE_TYPE_COM:
|
|||
|
DeviceName.Initialize("COM#");
|
|||
|
break;
|
|||
|
|
|||
|
case DEVICE_TYPE_LPT:
|
|||
|
DeviceName.Initialize("LPT#");
|
|||
|
break;
|
|||
|
|
|||
|
case DEVICE_TYPE_CON:
|
|||
|
DeviceName.Initialize("CON");
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
DebugAssert( FALSE );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// All devices (except the console) have a device number
|
|||
|
//
|
|||
|
if ( DeviceType != DEVICE_TYPE_CON ) {
|
|||
|
|
|||
|
//
|
|||
|
// Get the device number in string form
|
|||
|
//
|
|||
|
Number.Initialize( DeviceNumber );
|
|||
|
|
|||
|
//
|
|||
|
// Now substitute the matchnumber character with the number
|
|||
|
//
|
|||
|
Index = DeviceName.Strchr( '#' );
|
|||
|
DebugAssert( Index != INVALID_CHNUM );
|
|||
|
|
|||
|
DeviceName.Replace( Index, 1, &Number );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We have the device name, gets its type.
|
|||
|
//
|
|||
|
QualifiedDeviceName.Initialize( "\\\\.\\" );
|
|||
|
QualifiedDeviceName.Strcat( &DeviceName );
|
|||
|
|
|||
|
DriveType = SYSTEM::QueryFileType( &QualifiedDeviceName );
|
|||
|
|
|||
|
//
|
|||
|
// If the caller wants a path, make it.
|
|||
|
//
|
|||
|
if ( DevicePathPointer ) {
|
|||
|
|
|||
|
DevicePath = NEW PATH;
|
|||
|
DebugPtrAssert( DevicePath );
|
|||
|
|
|||
|
if ( DevicePath ) {
|
|||
|
|
|||
|
DevicePath->Initialize( &DeviceName );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
*DevicePathPointer = DevicePath;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Now return whether the device is valid or not
|
|||
|
//
|
|||
|
return DriveType == CharFile;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
WriteStatusHeader (
|
|||
|
IN PCPATH DevicePath
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Write the header for a status block.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DevicePath - Supplies the device path
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if header written
|
|||
|
FALSE otherwise.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
PWSTRING Header;
|
|||
|
CHNUM Index;
|
|||
|
|
|||
|
Header = QueryMessageString( MODE_MESSAGE_STATUS );
|
|||
|
|
|||
|
if ( !Header ) {
|
|||
|
|
|||
|
DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Replace the match-all character in the header with the device
|
|||
|
// path.
|
|||
|
//
|
|||
|
Index = Header->Strchr( '*' );
|
|||
|
DebugAssert( Index != INVALID_CHNUM );
|
|||
|
|
|||
|
Header->Replace( Index, 1, DevicePath->GetPathString() );
|
|||
|
|
|||
|
//
|
|||
|
// Display the header
|
|||
|
//
|
|||
|
Get_Standard_Output_Stream()->WriteChar( '\r' );
|
|||
|
Get_Standard_Output_Stream()->WriteChar( '\n' );
|
|||
|
Get_Standard_Output_Stream()->WriteString( Header );
|
|||
|
Get_Standard_Output_Stream()->WriteChar( '\r' );
|
|||
|
Get_Standard_Output_Stream()->WriteChar( '\n' );
|
|||
|
|
|||
|
//
|
|||
|
// Underline it
|
|||
|
//
|
|||
|
for (Index = 0; Index < Header->QueryChCount(); Index++) {
|
|||
|
Header->SetChAt( '-', Index );
|
|||
|
}
|
|||
|
Get_Standard_Output_Stream()->WriteString( Header );
|
|||
|
Get_Standard_Output_Stream()->WriteChar( '\r' );
|
|||
|
Get_Standard_Output_Stream()->WriteChar( '\n' );
|
|||
|
|
|||
|
DELETE( Header );
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|