Leaked source code of windows server 2003
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.
|
|
/*++
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;
}
|