|
|
/*************************************************************************
* * shadow.c * * Shadow utility * * Copyright 1994, Citrix Systems Inc. * * Copyright (c) 1998 - 1999 Microsoft Corporation * * $Author: tyl $ Mike Discavage * * $Log: N:\nt\private\utils\citrix\shadow\VCS\shadow.c $ * * Rev 1.20 May 04 1998 17:37:40 tyl * bug 2019 - oem to ansi * * Rev 1.19 Jun 26 1997 18:25:40 billm * move to WF40 tree * * Rev 1.18 23 Jun 1997 15:39:22 butchd * update * * Rev 1.17 15 Feb 1997 15:57:34 miked * update * * Rev 1.16 07 Feb 1997 15:56:54 bradp * update * * Rev 1.15 13 Nov 1996 17:14:40 miked * update * * Rev 1.14 30 Sep 1996 08:34:28 butchd * update * * Rev 1.13 11 Sep 1996 09:21:44 bradp * update * * *************************************************************************/
#define NT
/*
* Includes */ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <windows.h>
#include <winnlsp.h>
// #include <ntddkbd.h>
// #include <ntddmou.h>
#include <winsta.h>
#include <utilsub.h>
#include <kbd.h> // for KBDCTRL KLB 07-15-95
#include "shadow.h"
#include "printfoa.h"
// max length of the locale string
#define MAX_LOCALE_STRING 64
/*
* Global variables */ USHORT help_flag = FALSE; USHORT v_flag = FALSE; WINSTATIONNAME WSName; ULONG LogonId; ULONG Timeout; // timeout in seconds
HANDLE hServerName = SERVERNAME_CURRENT; WCHAR ServerName[MAX_NAME+1];
TOKMAP ptm[] = { {TOKEN_WS, TMFLAG_REQUIRED, TMFORM_STRING, WINSTATIONNAME_LENGTH, WSName },
{TOKEN_SERVER, TMFLAG_OPTIONAL, TMFORM_STRING, MAX_NAME, ServerName },
{TOKEN_TIMEOUT, TMFLAG_OPTIONAL, TMFORM_ULONG, sizeof(ULONG), &Timeout },
{TOKEN_VERBOSE, TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &v_flag },
{TOKEN_HELP, TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &help_flag },
{0, 0, 0, 0, 0} };
/*
* Private function prototypes. */ void Usage(BOOLEAN bError);
/*******************************************************************************
* * main * ******************************************************************************/
int __cdecl main( INT argc, CHAR **argv ) { WCHAR *CmdLine; WCHAR **argvW, *endptr; ULONG rc; int i; BOOLEAN Result; WCHAR wszString[MAX_LOCALE_STRING + 1];
setlocale(LC_ALL, ".OCP"); // We don't want LC_CTYPE set the same as the others or else we will see
// garbage output in the localized version, so we need to explicitly
// set it to correct console output code page
_snwprintf(wszString, sizeof(wszString)/sizeof(WCHAR), L".%d", GetConsoleOutputCP()); wszString[sizeof(wszString)/sizeof(WCHAR) - 1] = L'\0'; _wsetlocale(LC_CTYPE, wszString);
SetThreadUILanguage(0);
/*
* Massage the command line. */
argvW = MassageCommandLine((DWORD)argc); if (argvW == NULL) { ErrorPrintf(IDS_ERROR_MALLOC); return(FAILURE); }
/*
* parse the cmd line without parsing the program name (argc-1, argv+1) */ rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
/*
* Check for error from ParseCommandLine */ if ( help_flag || rc ) {
if ( !help_flag ) { Usage(TRUE); return(FAILURE);
} else { Usage(FALSE); return(SUCCESS); } }
//Check if we are running under Terminal Server
if(!AreWeRunningTerminalServices()) { ErrorPrintf(IDS_ERROR_NOT_TS); return(FAILURE); }
/*
* Open the specified server */ if( ServerName[0] ) { hServerName = WinStationOpenServer( ServerName ); if( hServerName == NULL ) { StringErrorPrintf(IDS_ERROR_SERVER,ServerName); PutStdErr( GetLastError(), 0 ); return(FAILURE); } }
/*
* Validate the shadowee. */ if ( !iswdigit(*WSName) ) {
/*
* Treat the entered string as a WinStation name. * */
if ( !LogonIdFromWinStationName(hServerName, WSName, &LogonId) ) { StringErrorPrintf(IDS_ERROR_WINSTATION_NOT_FOUND, WSName); return(FAILURE); }
Message(IDS_SHADOWING_WARNING); if ( v_flag ) StringMessage(IDS_SHADOWING_WINSTATION, WSName);
} else {
/*
* Treated the entered string as a LogonId. */ LogonId = wcstoul(WSName, &endptr, 10); if ( *endptr ) { StringErrorPrintf(IDS_ERROR_INVALID_LOGONID, WSName); return(FAILURE); } if ( !WinStationNameFromLogonId(hServerName, LogonId, WSName) ) { ErrorPrintf(IDS_ERROR_LOGONID_NOT_FOUND, LogonId); return(FAILURE); }
Message(IDS_SHADOWING_WARNING); if ( v_flag ) Message(IDS_SHADOWING_LOGONID, LogonId); }
// Let the warning be displayed
Sleep(500);
/*
* Start shadowing. */ if ( IsTokenPresent(ptm, TOKEN_TIMEOUT) ) { Result = WinStationShadow( SERVERNAME_CURRENT, ServerName, LogonId, (BYTE)Timeout, (WORD)-1); } else { Result = WinStationShadow( SERVERNAME_CURRENT, ServerName, LogonId, VK_MULTIPLY, KBDCTRL ); // ctrl-*
}
/*
* Return success or failure. */ if ( !Result ) {
ErrorPrintf(IDS_ERROR_SHADOW_FAILURE, GetLastError()); PutStdErr( GetLastError(), 0 ); return(FAILURE);
} else {
if ( v_flag ) Message(IDS_SHADOWING_DONE);
return(SUCCESS); }
} /* main() */
/*******************************************************************************
* * Usage * * Output the usage message for this utility. * * ENTRY: * bError (input) * TRUE if the 'invalid parameter(s)' message should preceed the usage * message and the output go to stderr; FALSE for no such error * string and output goes to stdout. * * EXIT: * * ******************************************************************************/
void Usage( BOOLEAN bError ) { if ( bError ) {
ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS); ErrorPrintf(IDS_USAGE_1); ErrorPrintf(IDS_USAGE_2); ErrorPrintf(IDS_USAGE_3); ErrorPrintf(IDS_USAGE_4); ErrorPrintf(IDS_USAGE_5); ErrorPrintf(IDS_USAGE_6); ErrorPrintf(IDS_USAGE_7); ErrorPrintf(IDS_USAGE_8); ErrorPrintf(IDS_USAGE_9);
} else {
Message(IDS_USAGE_1); Message(IDS_USAGE_2); Message(IDS_USAGE_3); Message(IDS_USAGE_4); Message(IDS_USAGE_5); Message(IDS_USAGE_6); Message(IDS_USAGE_7); Message(IDS_USAGE_8); Message(IDS_USAGE_9); }
} /* Usage() */
|