308 lines
7.2 KiB
C++
308 lines
7.2 KiB
C++
|
#define _NTAPI_ULIB_
|
|||
|
|
|||
|
#include "ulib.hxx"
|
|||
|
#include "path.hxx"
|
|||
|
#include "wstring.hxx"
|
|||
|
#include "redir.hxx"
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// The string below represents the path used to determine whether or not
|
|||
|
// an LPT device is redirected to a COM device.
|
|||
|
// Due to performance, this path should always be defined in upper case.
|
|||
|
//
|
|||
|
|
|||
|
#define LPT_REDIRECTION_PATH (LPWSTR)L"\\??\\COM"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
REDIR::Redirect (
|
|||
|
IN PCPATH Device,
|
|||
|
IN PCPATH Destination
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Redirects a device. The device is redirected by creating a symbolic link
|
|||
|
to the destination device. If this is the first redirection of the device,
|
|||
|
the original symbolic link is saved in the registry under a volatile key
|
|||
|
so that it can be recovered latter on.
|
|||
|
|
|||
|
Note that redirection requires sufficient privileges to create symbolic
|
|||
|
links and to create entries in the registry under SAVE_ROOT.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Device - Supplies the device to be redirected.
|
|||
|
|
|||
|
Destination - Supplies the device to be redirected to
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if the device was successfully redirected.
|
|||
|
FALSE otherwise.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
BOOLEAN Redirected = FALSE;
|
|||
|
PCWSTRING DeviceName;
|
|||
|
PCWSTRING DestinationName;
|
|||
|
|
|||
|
|
|||
|
DebugPtrAssert( Device );
|
|||
|
DebugPtrAssert( Destination );
|
|||
|
|
|||
|
if( ( Device != NULL ) &&
|
|||
|
( Destination != NULL ) &&
|
|||
|
( ( DeviceName = Device->GetPathString() ) != NULL ) &&
|
|||
|
( ( DestinationName = Destination->GetPathString() ) != NULL )
|
|||
|
) {
|
|||
|
|
|||
|
Redirected = DefineDosDevice( 0,
|
|||
|
DeviceName->GetWSTR(),
|
|||
|
DestinationName->GetWSTR() ) ? TRUE : FALSE;
|
|||
|
|
|||
|
#if DBG
|
|||
|
if( !Redirected ) {
|
|||
|
DebugPrint( "MODE: DefineDosDevice() failed" );
|
|||
|
DebugPrintTrace(( "MODE: DefineDosDevice() failed, Device = %ls, Destination = %ls, Error = %d \n",
|
|||
|
DeviceName->GetWSTR(),
|
|||
|
DestinationName->GetWSTR(),
|
|||
|
GetLastError() ));
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
}
|
|||
|
return Redirected;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
REDIR::IsRedirected (
|
|||
|
OUT PREDIR_STATUS Status,
|
|||
|
IN PCPATH Device,
|
|||
|
IN PCPATH Destination
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Determines if a device is being redirected to a specific device.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Status - Supplies pointer to redirection status. Only set in
|
|||
|
if the return value of this method is FALSE
|
|||
|
|
|||
|
Device - Supplies the device about which we want to find out if
|
|||
|
it is redirected or not.
|
|||
|
|
|||
|
Destination - Supplies a pointer to a destination device.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if the device is redirected to the destination
|
|||
|
FALSE otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
BOOLEAN Redirected = FALSE;
|
|||
|
PCWSTRING DeviceName;
|
|||
|
PCWSTRING DestinationName;
|
|||
|
DSTRING DstRedir;
|
|||
|
FSTRING LptRedirectionPath;
|
|||
|
DSTRING TmpString;
|
|||
|
WCHAR buf[ 2*(MAX_PATH + 1) ];
|
|||
|
PWSTR pwstrTarget;
|
|||
|
|
|||
|
DebugPtrAssert( Device );
|
|||
|
|
|||
|
*Status = REDIR_STATUS_ERROR;
|
|||
|
|
|||
|
if (NULL == (DeviceName = Device->GetPathString())) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if (!QueryDosDevice(DeviceName->GetWSTR(),
|
|||
|
buf,
|
|||
|
sizeof(buf) / sizeof(WCHAR))) {
|
|||
|
|
|||
|
// The device probably doesn't exist
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
*Status = REDIR_STATUS_NONEXISTENT;
|
|||
|
|
|||
|
pwstrTarget = buf;
|
|||
|
|
|||
|
// Find out if the LPT device is redirected to the destination.
|
|||
|
|
|||
|
DstRedir.Initialize(pwstrTarget);
|
|||
|
|
|||
|
return INVALID_CHNUM != DstRedir.Strstr(Destination->GetPathString());
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
REDIR::IsRedirected (
|
|||
|
OUT PREDIR_STATUS Status,
|
|||
|
IN PCPATH Device
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Determines if a device is being redirected to any device.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Status - Supplies pointer to redirection status. Only set in
|
|||
|
if the return value of this method is FALSE
|
|||
|
|
|||
|
Device - Supplies the device about which we want to find out if
|
|||
|
it is redirected or not.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if redirected, FALSE otherwise.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
BOOLEAN Redirected = FALSE;
|
|||
|
PCWSTRING DeviceName;
|
|||
|
PCWSTRING DestinationName;
|
|||
|
DSTRING DstRedir;
|
|||
|
FSTRING LptRedirectionPath;
|
|||
|
DSTRING TmpString;
|
|||
|
WCHAR Buffer[ 2*(MAX_PATH + 1) ];
|
|||
|
PWSTR Pointer;
|
|||
|
PPATH Destination = NULL;
|
|||
|
|
|||
|
DebugPtrAssert( Device );
|
|||
|
|
|||
|
*Status = REDIR_STATUS_ERROR;
|
|||
|
|
|||
|
if( ( Device != NULL ) &&
|
|||
|
( ( DeviceName = Device->GetPathString() ) != NULL ) ) {
|
|||
|
|
|||
|
if( QueryDosDevice( DeviceName->GetWSTR(),
|
|||
|
Buffer,
|
|||
|
sizeof( Buffer ) / sizeof( WCHAR ) ) == 0 ) {
|
|||
|
//
|
|||
|
// The device probably doesn't exist
|
|||
|
//
|
|||
|
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// At this point we know that the device exists.
|
|||
|
// Assume that the device is not redirected.
|
|||
|
//
|
|||
|
|
|||
|
*Status = REDIR_STATUS_NONEXISTENT;
|
|||
|
|
|||
|
Pointer = Buffer;
|
|||
|
|
|||
|
LptRedirectionPath.Initialize( LPT_REDIRECTION_PATH );
|
|||
|
|
|||
|
//
|
|||
|
// Find out if the LPT device is redirected to a COM device
|
|||
|
//
|
|||
|
|
|||
|
while( ( *Pointer != ( WCHAR )'\0' ) &&
|
|||
|
DstRedir.Initialize( Pointer ) &&
|
|||
|
( DstRedir.Strupr() != NULL ) &&
|
|||
|
!Redirected ) {
|
|||
|
|
|||
|
if( DstRedir.Strstr( &LptRedirectionPath ) != INVALID_CHNUM ) {
|
|||
|
//
|
|||
|
// The LPT device is redirected to a COM device
|
|||
|
//
|
|||
|
if( Destination != NULL ) {
|
|||
|
if( ( ( DestinationName = Destination->GetPathString() ) != NULL ) &&
|
|||
|
( DstRedir.Strstr( DestinationName ) != INVALID_CHNUM ) ) {
|
|||
|
Redirected = TRUE;
|
|||
|
}
|
|||
|
} else {
|
|||
|
Redirected = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
Pointer += DstRedir.QueryChCount() + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return Redirected;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
REDIR::EndRedirection (
|
|||
|
IN PCPATH Device
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Ends the redirection of a device
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Device - Supplies the device
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
|
|||
|
TRUE if the device's redirection has ended.
|
|||
|
FALSE otherwise
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
BOOLEAN Done = FALSE;
|
|||
|
PCWSTRING DeviceName;
|
|||
|
REDIR_STATUS Status;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DebugPtrAssert( Device );
|
|||
|
|
|||
|
if( IsRedirected( &Status, Device ) ) {
|
|||
|
if( ( Device != NULL ) &&
|
|||
|
( ( DeviceName = Device->GetPathString() ) != NULL ) ) {
|
|||
|
|
|||
|
Done = DefineDosDevice( DDD_REMOVE_DEFINITION /* | DDD_RAW_TARGET_PATH */,
|
|||
|
DeviceName->GetWSTR(),
|
|||
|
NULL ) ? TRUE : FALSE;
|
|||
|
|
|||
|
#if DBG
|
|||
|
if( !Done ) {
|
|||
|
DebugPrint( "MODE: DefineDosDevice() failed" );
|
|||
|
DebugPrintTrace(( "MODE: DefineDosDevice() failed, Device = %ls, Destination = %ls, Error = %d \n",
|
|||
|
DeviceName->GetWSTR(),
|
|||
|
LPT_REDIRECTION_PATH,
|
|||
|
GetLastError() ));
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
return Done;
|
|||
|
}
|