windows-nt/Source/XPSP1/NT/base/fs/utils/mode/common.cxx

346 lines
6.9 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}