|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
blddcb.c
Abstract:
This module implements Win32 comm api buildcommdcb
Author:
Anthony V. Ercolano (tonye) 10-March-1992
Actually this code was generously donated by ramonsa. It is basically the code used for the mode command.
Revision History:
--*/
#include <basedll.h>
typedef struct _PARSE_CONTEXT { PSTR CharIndex; PSTR AdvanceIndex; PSTR MatchBegin; PSTR MatchEnd; } PARSE_CONTEXT,*PPARSE_CONTEXT;
static BOOL BuildDcb ( LPCSTR L, LPDCB Dcb, LPCOMMTIMEOUTS To );
static BOOL Match( PPARSE_CONTEXT C, PSTR Pattern );
static VOID Advance( PPARSE_CONTEXT C );
static DWORD GetNumber( PPARSE_CONTEXT C );
static BOOL ConvertBaudRate ( DWORD BaudIn, PDWORD BaudRate );
static BOOL ConvertDataBits ( DWORD DataBitsIn, PBYTE DataBitsOut );
static BOOL ConvertStopBits ( DWORD StopBitsIn, PBYTE StopBits );
static BOOL ConvertParity ( CHAR ParityIn, PBYTE Parity );
static BOOL ConvertDtrControl ( PSTR IdxBegin, PSTR IdxEnd, PBYTE DtrControl );
static BOOL ConvertRtsControl ( PSTR IdxBegin, PSTR IdxEnd, PBYTE RtsControl );
static VOID IgnoreDeviceName( IN PPARSE_CONTEXT C );
static NTSTATUS DeviceNameCompare( IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext );
BOOL BuildCommDCBAndTimeoutsW( LPCWSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts )
/*++
Routine Description:
This function translates the definition string specified by the lpDef parameter into appropriate device-control block codes and places these codes into the block pointed to by the lpDCB parameter. It also sets the timeouts if specified.
Arguments:
lpDef - Points to a null terminated character string that specifies the device control information for the device.
lpDCB - Points to the DCB data structure that is to receive the translated string.. The structure defines the control settings for the serial communications device.
lpCommTimeouts - It "TO" included, it will set the timeouts.
Return Value:
The return value is TRUE if the function is successful or FALSE if an error occurs.
--*/
{
UNICODE_STRING Unicode; ANSI_STRING Ansi; NTSTATUS Status; BOOL AnsiBool;
RtlInitUnicodeString( &Unicode, lpDef );
Status = RtlUnicodeStringToAnsiString( &Ansi, &Unicode, TRUE );
if (!NT_SUCCESS(Status)) {
BaseSetLastNTError(Status); return FALSE;
}
AnsiBool = BuildCommDCBAndTimeoutsA( (LPCSTR)Ansi.Buffer, lpDCB, lpCommTimeouts );
RtlFreeAnsiString(&Ansi); return AnsiBool;
}
BOOL BuildCommDCBAndTimeoutsA( LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts )
/*++
Routine Description:
This function translates the definition string specified by the lpDef parameter into appropriate device-control block codes and places these codes into the block pointed to by the lpDCB parameter. It can also set the timeout value.
Arguments:
lpDef - Points to a null terminated character string that specifies the device control information for the device.
lpDCB - Points to the DCB data structure that is to receive the translated string.. The structure defines the control settings for the serial communications device.
lpCommTimeouts - If TO included in string then timeouts are also set.
Return Value:
The return value is TRUE if the function is successful or FALSE if an error occurs.
--*/
{
if (!BuildDcb( lpDef, lpDCB, lpCommTimeouts )) {
SetLastError(ERROR_INVALID_PARAMETER); return FALSE;
} else {
return TRUE;
}
}
BOOL BuildCommDCBW( LPCWSTR lpDef, LPDCB lpDCB )
/*++
Routine Description:
This function translates the definition string specified by the lpDef parameter into appropriate device-control block codes and places these codes into the block pointed to by the lpDCB parameter.
Arguments:
lpDef - Points to a null terminated character string that specifies the device control information for the device.
lpDCB - Points to the DCB data structure that is to receive the translated string.. The structure defines the control settings for the serial communications device.
Return Value:
The return value is TRUE if the function is successful or FALSE if an error occurs.
--*/
{
UNICODE_STRING Unicode; ANSI_STRING Ansi; NTSTATUS Status; BOOL AnsiBool;
RtlInitUnicodeString( &Unicode, lpDef );
Status = RtlUnicodeStringToAnsiString( &Ansi, &Unicode, TRUE );
if (!NT_SUCCESS(Status)) {
BaseSetLastNTError(Status); return FALSE;
}
AnsiBool = BuildCommDCBA( (LPCSTR)Ansi.Buffer, lpDCB );
RtlFreeAnsiString(&Ansi); return AnsiBool;
}
BOOL BuildCommDCBA( LPCSTR lpDef, LPDCB lpDCB )
/*++
Routine Description:
This function translates the definition string specified by the lpDef parameter into appropriate device-control block codes and places these codes into the block pointed to by the lpDCB parameter.
Arguments:
lpDef - Points to a null terminated character string that specifies the device control information for the device.
lpDCB - Points to the DCB data structure that is to receive the translated string.. The structure defines the control settings for the serial communications device.
Return Value:
The return value is TRUE if the function is successful or FALSE if an error occurs.
--*/
{
COMMTIMEOUTS JunkTimeouts;
if (!BuildDcb( lpDef, lpDCB, &JunkTimeouts )) {
SetLastError(ERROR_INVALID_PARAMETER); return FALSE;
} else {
return TRUE;
}
}
static BOOL BuildDcb ( LPCSTR L, LPDCB Dcb, LPCOMMTIMEOUTS To )
/*++
Routine Description:
Arguments:
L - A pointer to the string to convert to a DCB. Dcb - The dcb to fill in.
Return Value:
FALSE if the string has some error, TRUE otherwise.
--*/
{
BOOL SetBaud = FALSE; BOOL SetDataBits = FALSE; BOOL SetStopBits = FALSE; BOOL SetParity = FALSE; BOOL SetRetry = FALSE; BOOL SetTimeOut = FALSE; BOOL SetXon = FALSE; BOOL SetOdsr = FALSE; BOOL SetIdsr = FALSE; BOOL SetOcts = FALSE; BOOL SetDtrControl = FALSE; BOOL SetRtsControl = FALSE;
DWORD Baud; BYTE DataBits; BYTE StopBits; BYTE Parity; BOOL TimeOut; BOOL Xon; BOOL Odsr; BOOL Idsr; BOOL Octs; BYTE DtrControl; BYTE RtsControl; PARSE_CONTEXT C = {0};
C.CharIndex = C.AdvanceIndex = (PSTR)L;
//
// This following call will query all of the *current* serial
// provider names. If it finds that the argurment string
// contains the name (with an optional :) it will simply
// advance past it.
//
IgnoreDeviceName(&C);
if ( Match(&C, "#" ) ) {
//
// Old syntax, where parameter are positional and comma-delimited.
//
// We will use the following automata for parsing the input
// (eoi = end of input):
//
// eoi
// [Baud]------------->[End]
// | ^
// |, |eoi
// v |
// [a]-----------+
// | ^
// | @ |eoi
// +-->[Parity]-+
// | | ^
// | |, |
// |<----+ |
// | |
// |, |eoi
// | |
// v |
// [b]-----------+
// | ^
// | # |eoi
// +-->[Data]---+
// | | ^
// | |, |
// |<----+ |
// | |
// |, |eoi
// v |
// [c]-----------+
// | ^
// | # |eoi
// +-->[Stop]---+
//
//
// Assume xon=off
//
SetXon = TRUE; SetOdsr = TRUE; SetOcts = TRUE; SetDtrControl = TRUE; SetRtsControl = TRUE; Xon = FALSE; Odsr = FALSE; Octs = FALSE; DtrControl = DTR_CONTROL_ENABLE; RtsControl = RTS_CONTROL_ENABLE;
if (!ConvertBaudRate( GetNumber(&C), &Baud )) { return FALSE; } SetBaud = TRUE; Advance(&C);
//
// A:
//
if ( !Match(&C, "," ) ) { goto Eoi; } Advance(&C);
if ( !Match(&C, "," ) && Match(&C, "@" ) ) {
//
// Parity
//
if (!ConvertParity( *C.MatchBegin,&Parity )) { return FALSE; } SetParity = TRUE; Advance(&C); }
//
// B:
//
if ( !Match(&C, "," )) { goto Eoi; } Advance(&C);
if ( Match(&C, "#" )) {
//
// Data bits
//
if (!ConvertDataBits( GetNumber(&C),&DataBits )) { return FALSE; } SetDataBits = TRUE; Advance(&C); }
//
// C:
//
if ( !Match(&C, "," )) { goto Eoi; } Advance(&C);
if ( Match(&C, "1.5" ) ) { StopBits = ONE5STOPBITS; SetStopBits = TRUE; Advance(&C); } else if ( Match(&C, "#" ) ) { if (!ConvertStopBits( GetNumber(&C),&StopBits)) { return FALSE; } SetStopBits = TRUE; Advance(&C); }
if ( !Match(&C, "," )) { goto Eoi; }
Advance(&C);
if ( Match(&C, "x" ) ) {
//
// XON=ON
//
SetXon = TRUE; SetOdsr = TRUE; SetOcts = TRUE; SetDtrControl = TRUE; SetRtsControl = TRUE; Xon = TRUE; Odsr = FALSE; Octs = FALSE; DtrControl = DTR_CONTROL_ENABLE; RtsControl = RTS_CONTROL_ENABLE; Advance(&C);
} else if ( Match(&C, "p" ) ) {
//
// Permanent retry - Hardware handshaking
//
SetXon = TRUE; SetOdsr = TRUE; SetOcts = TRUE; SetDtrControl = TRUE; SetRtsControl = TRUE; Xon = FALSE; Odsr = TRUE; Octs = TRUE; DtrControl = DTR_CONTROL_HANDSHAKE; RtsControl = RTS_CONTROL_HANDSHAKE; Advance(&C);
} else {
//
// XON=OFF
//
SetXon = TRUE; SetOdsr = TRUE; SetOcts = TRUE; SetDtrControl = TRUE; SetRtsControl = TRUE; Xon = FALSE; Odsr = FALSE; Octs = FALSE; DtrControl = DTR_CONTROL_ENABLE; RtsControl = RTS_CONTROL_ENABLE; }
Eoi: if ( *C.CharIndex != '\0' ) {
//
// Error
//
return FALSE;
}
} else {
//
// New Form
//
while ( *C.CharIndex != '\0' ) {
if ( Match(&C, "BAUD=#" ) ) { //
// BAUD=
//
if ( !ConvertBaudRate(GetNumber(&C), &Baud ) ) { return FALSE; } SetBaud = TRUE; Advance(&C);
} else if ( Match(&C, "PARITY=@" ) ) { //
// PARITY=
//
if ( !ConvertParity( *C.MatchBegin, &Parity ) ) { return FALSE; } SetParity = TRUE; Advance(&C);
} else if ( Match(&C, "DATA=#" ) ) { //
// DATA=
//
if ( !ConvertDataBits(GetNumber(&C), &DataBits ) ) { return FALSE; } SetDataBits = TRUE; Advance(&C);
} else if ( Match(&C, "STOP=1.5" ) ) { //
// STOP=1.5
//
StopBits = ONE5STOPBITS; SetStopBits = TRUE; Advance(&C);
} else if ( Match(&C, "STOP=#" ) ) { //
// STOP=
//
if ( !ConvertStopBits(GetNumber(&C), &StopBits ) ) { return FALSE; } SetStopBits = TRUE; Advance(&C);
} else if ( Match(&C, "TO=ON" ) ) { //
// TO=ON
//
SetTimeOut = TRUE; TimeOut = TRUE; Advance(&C);
} else if ( Match(&C, "TO=OFF" ) ) { //
// TO=ON
//
SetTimeOut = TRUE; TimeOut = FALSE; Advance(&C);
} else if ( Match(&C, "XON=ON" ) ) { //
// XON=ON
//
SetXon = TRUE; Xon = TRUE; Advance(&C);
} else if ( Match(&C, "XON=OFF" ) ) { //
// XON=OFF
//
SetXon = TRUE; Xon = FALSE; Advance(&C);
} else if ( Match(&C, "ODSR=ON" ) ) { //
// ODSR=ON
//
SetOdsr = TRUE; Odsr = TRUE; Advance(&C);
} else if ( Match(&C, "ODSR=OFF" ) ) { //
// ODSR=OFF
//
SetOdsr = TRUE; Odsr = FALSE; Advance(&C);
} else if ( Match(&C, "IDSR=ON" ) ) { //
// IDSR=ON
//
SetIdsr = TRUE; Idsr = TRUE; Advance(&C);
} else if ( Match(&C, "IDSR=OFF" ) ) { //
// IDSR=OFF
//
SetIdsr = TRUE; Idsr = FALSE; Advance(&C);
} else if ( Match(&C, "OCTS=ON" ) ) { //
// OCS=ON
//
SetOcts = TRUE; Octs = TRUE; Advance(&C);
} else if ( Match(&C, "OCTS=OFF" ) ) { //
// OCS=OFF
//
SetOcts = TRUE; Octs = FALSE; Advance(&C);
} else if ( Match(&C, "DTR=*" ) ) { //
// DTR=
//
if ( !ConvertDtrControl(C.MatchBegin, C.MatchEnd, &DtrControl ) ) { return FALSE; } SetDtrControl = TRUE; Advance(&C);
} else if ( Match(&C, "RTS=*" ) ) { //
// RTS=
//
if ( !ConvertRtsControl(C.MatchBegin, C.MatchEnd, &RtsControl ) ) { return FALSE; } SetRtsControl = TRUE; Advance(&C);
} else {
return FALSE; } }
}
if ( SetBaud ) { Dcb->BaudRate = Baud; }
if ( SetDataBits ) { Dcb->ByteSize = DataBits; }
if ( SetStopBits ) { Dcb->StopBits = StopBits; } else if ( SetBaud && (Baud == 110) ) { Dcb->StopBits = TWOSTOPBITS; } else { Dcb->StopBits = ONESTOPBIT; }
if ( SetParity ) { Dcb->Parity = Parity; }
if ( SetXon ) { if ( Xon ) { Dcb->fInX = TRUE; Dcb->fOutX = TRUE; } else { Dcb->fInX = FALSE; Dcb->fOutX = FALSE; } }
if ( SetOcts ) {
if ( Octs ) { Dcb->fOutxCtsFlow = TRUE; } else { Dcb->fOutxCtsFlow = FALSE; } }
if ( SetOdsr ) { if ( Odsr ) { Dcb->fOutxDsrFlow = TRUE; } else { Dcb->fOutxDsrFlow = FALSE; } }
if ( SetIdsr ) { if ( Idsr ) { Dcb->fDsrSensitivity = TRUE; } else { Dcb->fDsrSensitivity = FALSE; } }
if ( SetDtrControl ) { Dcb->fDtrControl = DtrControl; }
if ( SetRtsControl ) { Dcb->fRtsControl = RtsControl; }
if ( SetTimeOut ) { if (TimeOut) { To->ReadIntervalTimeout = 0; To->ReadTotalTimeoutMultiplier = 0; To->ReadTotalTimeoutConstant = 0; To->WriteTotalTimeoutMultiplier = 0; To->WriteTotalTimeoutConstant = 60000; } else { To->ReadIntervalTimeout = 0; To->ReadTotalTimeoutMultiplier = 0; To->ReadTotalTimeoutConstant = 0; To->WriteTotalTimeoutMultiplier = 0; To->WriteTotalTimeoutConstant = 0; } }
return TRUE; }
static BOOL Match( PPARSE_CONTEXT C, PSTR Pattern )
/*++
Routine Description:
This function matches a pattern against whatever is in the command line at the current position.
Note that this does not advance our current position within the command line.
If the pattern has a magic character, then the variables C->MatchBegin and C->MatchEnd delimit the substring of the command line that matched that magic character.
Arguments:
C - The parse context. Pattern - Supplies pointer to the pattern to match
Return Value:
BOOLEAN - TRUE if the pattern matched, FALSE otherwise
Notes:
--*/
{
PSTR CmdIndex; // Index within command line
PSTR PatternIndex; // Index within pattern
CHAR PatternChar; // Character in pattern
CHAR CmdChar; // Character in command line;
CmdIndex = C->CharIndex; PatternIndex = Pattern;
while ( (PatternChar = *PatternIndex) != '\0' ) {
switch ( PatternChar ) {
case '#':
//
// Match a number
//
C->MatchBegin = CmdIndex; C->MatchEnd = C->MatchBegin;
//
// Get all consecutive digits
//
while ( ((CmdChar = *C->MatchEnd) != '\0') && isdigit( (char)CmdChar ) ) { C->MatchEnd++; } C->MatchEnd--;
if ( C->MatchBegin > C->MatchEnd ) { //
// No number
//
return FALSE; }
CmdIndex = C->MatchEnd + 1; PatternIndex++;
break;
case '@':
//
// Match one character
//
if ( *CmdIndex == '\0' ) { return FALSE; }
C->MatchBegin = C->MatchEnd = CmdIndex; CmdIndex++; PatternIndex++;
break;
case '*':
//
// Match everything up to next blank (or end of input)
//
C->MatchBegin = CmdIndex; C->MatchEnd = C->MatchBegin;
while ( ( (CmdChar = *C->MatchEnd ) != '\0' ) && ( CmdChar != ' ' ) ) {
C->MatchEnd++; } C->MatchEnd--;
CmdIndex = C->MatchEnd+1; PatternIndex++;
break;
case '[':
//
// Optional sequence
//
PatternIndex++;
PatternChar = *PatternIndex; CmdChar = *CmdIndex;
//
// If the first charcter in the input does not match the
// first character in the optional sequence, we just
// skip the optional sequence.
//
if ( ( CmdChar == '\0' ) || ( CmdChar == ' ') || ( toupper(CmdChar) != toupper(PatternChar) ) ) {
while ( PatternChar != ']' ) { PatternIndex++; PatternChar = *PatternIndex; } PatternIndex++;
} else {
//
// Since the first character in the sequence matched, now
// everything must match.
//
while ( PatternChar != ']' ) {
if ( toupper(PatternChar) != toupper(CmdChar) ) { return FALSE; } CmdIndex++; PatternIndex++; CmdChar = *CmdIndex; PatternChar = *PatternIndex; }
PatternIndex++; }
break;
default:
//
// Both characters must match
//
CmdChar = *CmdIndex;
if ( ( CmdChar == '\0' ) || ( toupper(CmdChar) != toupper(PatternChar) ) ) {
return FALSE;
}
CmdIndex++; PatternIndex++;
break;
} }
C->AdvanceIndex = CmdIndex;
return TRUE;
}
static VOID Advance( PPARSE_CONTEXT C )
/*++
Routine Description:
Advances our pointers to the beginning of the next lexeme
Arguments:
C - The parse context.
Return Value:
None
--*/
{
C->CharIndex = C->AdvanceIndex;
//
// Skip blank space
//
if ( *C->CharIndex == ' ' ) {
while ( *C->CharIndex == ' ' ) {
C->CharIndex++; }
} }
static DWORD GetNumber( PPARSE_CONTEXT C )
/*++
Routine Description:
Converts the substring delimited by C->MatchBegin and C->MatchEnd into a number.
Arguments:
C - The parse context
Return Value:
ULONG - The matched string converted to a number
--*/
{ DWORD Number; CHAR c; PSTR p = C->MatchEnd+1;
c = *p; // *p = '\0';
//intf( "Making number: %s\n", C->MatchBegin );
Number = atol( C->MatchBegin ); // *p = c;
return Number;
}
static BOOL ConvertBaudRate ( DWORD BaudIn, PDWORD BaudRate )
/*++
Routine Description:
Validates a baud rate given as an argument to the program, and converts it to something that the COMM_DEVICE understands.
Arguments:
BaudIn - Supplies the baud rate given by the user BaudRate - if returning TRUE then the baud rate to use.
Return Value:
If a valid baud rate then returns TRUE, otherwise FALSE.
--*/
{ switch ( BaudIn ) {
case 11: case 110: *BaudRate = 110; break;
case 15: case 150: *BaudRate = 150; break;
case 30: case 300: *BaudRate = 300; break;
case 60: case 600: *BaudRate = 600; break;
case 12: case 1200: *BaudRate = 1200; break;
case 24: case 2400: *BaudRate = 2400; break;
case 48: case 4800: *BaudRate = 4800; break;
case 96: case 9600: *BaudRate = 9600; break;
case 19: case 19200: *BaudRate = 19200; break;
default:
*BaudRate = BaudIn;
}
return TRUE; }
static BOOL ConvertDataBits ( DWORD DataBitsIn, PBYTE DataBitsOut )
/*++
Routine Description:
Validates the number of data bits given as an argument to the program, and converts it to something that the COMM_DEVICE understands.
Arguments:
DataBitsIn - Supplies the number given by the user DataBitsOut - if returning TRUE, then the number of data bits.
Return Value:
If a valid data bits then TRUE, otherwise FALSE.
--*/
{
if ( ( DataBitsIn != 5 ) && ( DataBitsIn != 6 ) && ( DataBitsIn != 7 ) && ( DataBitsIn != 8 ) ) {
return FALSE;
}
*DataBitsOut = (BYTE)DataBitsIn;
return TRUE;
}
static BOOL ConvertStopBits ( DWORD StopBitsIn, PBYTE StopBits )
/*++
Routine Description:
Validates a number of stop bits given as an argument to the program, and converts it to something that the COMM_DEVICE understands.
Arguments:
StopBitsIn - Supplies the number given by the user StopBits - If returning true then a valid stop bits setting.
Return Value:
If a valid stop bits setting then TRUE, otherwise false.
--*/
{
switch ( StopBitsIn ) {
case 1: *StopBits = ONESTOPBIT; break;
case 2: *StopBits = TWOSTOPBITS; break;
default: return FALSE;
}
return TRUE;
}
static BOOL ConvertParity ( CHAR ParityIn, PBYTE Parity )
/*++
Routine Description:
Validates a parity given as an argument to the program, and converts it to something that the COMM_DEVICE understands.
Arguments:
ParityIn - Supplies the baud rate given by the user Parity - The valid parity if return true.
Return Value:
If a valid parity setting then TRUE otherwise false.
--*/
{
//
// Set the correct parity value depending on the character.
//
switch ( tolower(ParityIn) ) {
case 'n': *Parity = NOPARITY; break;
case 'o': *Parity = ODDPARITY; break;
case 'e': *Parity = EVENPARITY; break;
case 'm': *Parity = MARKPARITY; break;
case 's': *Parity = SPACEPARITY; break;
default: return FALSE;
}
return TRUE; }
static BOOL ConvertDtrControl ( PSTR IdxBegin, PSTR IdxEnd, PBYTE DtrControl )
/*++
Routine Description:
Validates a DTR control value given as an argument to the program, and converts it to something that the COMM_DEVICE understands.
Arguments:
IdxBegin - Supplies Index of first character IdxEnd - Supplies Index of last character DtrControl - If returning true, the valid dtr setting.
Return Value:
DTR_CONTROL - The DTR control value
--*/
{
PSTR p;
p = IdxBegin; if ( (tolower(*p) == 'o' ) && p++ && (tolower(*p) == 'n' ) && (IdxEnd == p)) {
*DtrControl = DTR_CONTROL_ENABLE; return TRUE;
}
p = IdxBegin; if ( (tolower(*p) == 'o') && p++ && (tolower(*p) == 'f') && p++ && (tolower(*p) == 'f') && (IdxEnd == p ) ) {
*DtrControl = DTR_CONTROL_DISABLE; return TRUE; }
p = IdxBegin; if ( (tolower(*p) == 'h') && p++ && (tolower(*p++) == 's') && (IdxEnd == p ) ) {
*DtrControl = DTR_CONTROL_HANDSHAKE; return TRUE; }
return FALSE; }
static BOOL ConvertRtsControl ( PSTR IdxBegin, PSTR IdxEnd, PBYTE RtsControl )
/*++
Routine Description:
Validates a RTS control value given as an argument to the program, and converts it to something that the COMM_DEVICE understands.
Arguments:
IdxBegin - Supplies Index of first character IdxEnd - Supplies Index of last character RtsControl - If returning true, the valid rts setting.
Return Value:
RTS_CONTROL - The RTS control value
--*/
{
PSTR p; p = IdxBegin; if ( (tolower(*p) == 'o' ) && p++ && (tolower(*p) == 'n' ) && (IdxEnd == p)) {
*RtsControl = RTS_CONTROL_ENABLE; return TRUE;
}
p = IdxBegin; if ( (tolower(*p) == 'o') && p++ && (tolower(*p) == 'f') && p++ && (tolower(*p) == 'f') && (IdxEnd == p ) ) {
*RtsControl = RTS_CONTROL_DISABLE; return TRUE; }
p = IdxBegin; if ( (tolower(*p) == 'h') && p++ && (tolower(*p++) == 's') && (IdxEnd == p ) ) {
*RtsControl = RTS_CONTROL_HANDSHAKE; return TRUE; }
p = IdxBegin; if ( (tolower(*p) == 't') && p++ && (tolower(*p++) == 'g') && (IdxEnd == p ) ) {
*RtsControl = RTS_CONTROL_TOGGLE; return TRUE; }
return FALSE;
}
static NTSTATUS DeviceNameCompare( IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext )
{
PPARSE_CONTEXT C = EntryContext; UNICODE_STRING uniName; ANSI_STRING ansiName;
RtlInitUnicodeString( &uniName, ValueData );
if (!NT_SUCCESS(RtlUnicodeStringToAnsiString( &ansiName, &uniName, TRUE ))) {
//
// Oh well, couldn't form the name. Just get out.
//
return STATUS_SUCCESS;
}
//
// See if we got a name match.
//
if (Match(C,ansiName.Buffer)) {
//
// Ok, got a name match, advance past it.
//
Advance(C);
//
// See if they've got the optional : following the
// device name.
//
if (Match(C,":")) {
//
// Go past it.
//
Advance(C);
}
} RtlFreeAnsiString(&ansiName); return STATUS_SUCCESS;
}
static VOID IgnoreDeviceName( IN PPARSE_CONTEXT C )
{
RTL_QUERY_REGISTRY_TABLE qTable[2] = {0};
//
// Build the query table.
//
qTable[0].QueryRoutine = DeviceNameCompare; qTable[0].EntryContext = C;
RtlQueryRegistryValues( RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM", &qTable[0], NULL, NULL );
}
|