Source code of Windows XP (NT5)
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.

301 lines
6.7 KiB

  1. /*************************************************************************
  2. *
  3. * shadow.c
  4. *
  5. * Shadow utility
  6. *
  7. * Copyright 1994, Citrix Systems Inc.
  8. *
  9. * Copyright (c) 1998 - 1999 Microsoft Corporation
  10. *
  11. * $Author: tyl $ Mike Discavage
  12. *
  13. * $Log: N:\nt\private\utils\citrix\shadow\VCS\shadow.c $
  14. *
  15. * Rev 1.20 May 04 1998 17:37:40 tyl
  16. * bug 2019 - oem to ansi
  17. *
  18. * Rev 1.19 Jun 26 1997 18:25:40 billm
  19. * move to WF40 tree
  20. *
  21. * Rev 1.18 23 Jun 1997 15:39:22 butchd
  22. * update
  23. *
  24. * Rev 1.17 15 Feb 1997 15:57:34 miked
  25. * update
  26. *
  27. * Rev 1.16 07 Feb 1997 15:56:54 bradp
  28. * update
  29. *
  30. * Rev 1.15 13 Nov 1996 17:14:40 miked
  31. * update
  32. *
  33. * Rev 1.14 30 Sep 1996 08:34:28 butchd
  34. * update
  35. *
  36. * Rev 1.13 11 Sep 1996 09:21:44 bradp
  37. * update
  38. *
  39. *
  40. *************************************************************************/
  41. #define NT
  42. /*
  43. * Includes
  44. */
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <locale.h>
  49. #include <windows.h>
  50. // #include <ntddkbd.h>
  51. // #include <ntddmou.h>
  52. #include <winsta.h>
  53. #include <utilsub.h>
  54. #include <kbd.h> // for KBDCTRL KLB 07-15-95
  55. #include "shadow.h"
  56. #include "printfoa.h"
  57. /*
  58. * Global variables
  59. */
  60. USHORT help_flag = FALSE;
  61. USHORT v_flag = FALSE;
  62. WINSTATIONNAME WSName;
  63. ULONG LogonId;
  64. ULONG Timeout; // timeout in seconds
  65. HANDLE hServerName = SERVERNAME_CURRENT;
  66. WCHAR ServerName[MAX_NAME+1];
  67. TOKMAP ptm[] = {
  68. {TOKEN_WS, TMFLAG_REQUIRED, TMFORM_STRING,
  69. WINSTATIONNAME_LENGTH, WSName },
  70. {TOKEN_SERVER, TMFLAG_OPTIONAL, TMFORM_STRING,
  71. MAX_NAME, ServerName },
  72. {TOKEN_TIMEOUT, TMFLAG_OPTIONAL, TMFORM_ULONG,
  73. sizeof(ULONG), &Timeout },
  74. {TOKEN_VERBOSE, TMFLAG_OPTIONAL, TMFORM_BOOLEAN,
  75. sizeof(USHORT), &v_flag },
  76. {TOKEN_HELP, TMFLAG_OPTIONAL, TMFORM_BOOLEAN,
  77. sizeof(USHORT), &help_flag },
  78. {0, 0, 0, 0, 0}
  79. };
  80. /*
  81. * Private function prototypes.
  82. */
  83. void Usage(BOOLEAN bError);
  84. /*******************************************************************************
  85. *
  86. * main
  87. *
  88. ******************************************************************************/
  89. int __cdecl
  90. main( INT argc, CHAR **argv )
  91. {
  92. WCHAR *CmdLine;
  93. WCHAR **argvW, *endptr;
  94. ULONG rc;
  95. int i;
  96. BOOLEAN Result;
  97. setlocale(LC_ALL, ".OCP");
  98. /*
  99. * Massage the command line.
  100. */
  101. argvW = MassageCommandLine((DWORD)argc);
  102. if (argvW == NULL) {
  103. ErrorPrintf(IDS_ERROR_MALLOC);
  104. return(FAILURE);
  105. }
  106. /*
  107. * parse the cmd line without parsing the program name (argc-1, argv+1)
  108. */
  109. rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
  110. /*
  111. * Check for error from ParseCommandLine
  112. */
  113. if ( help_flag || rc ) {
  114. if ( !help_flag ) {
  115. Usage(TRUE);
  116. return(FAILURE);
  117. } else {
  118. Usage(FALSE);
  119. return(SUCCESS);
  120. }
  121. }
  122. //Check if we are running under Terminal Server
  123. if(!AreWeRunningTerminalServices())
  124. {
  125. ErrorPrintf(IDS_ERROR_NOT_TS);
  126. return(FAILURE);
  127. }
  128. /*
  129. * Open the specified server
  130. */
  131. if( ServerName[0] ) {
  132. hServerName = WinStationOpenServer( ServerName );
  133. if( hServerName == NULL ) {
  134. StringErrorPrintf(IDS_ERROR_SERVER,ServerName);
  135. PutStdErr( GetLastError(), 0 );
  136. return(FAILURE);
  137. }
  138. }
  139. /*
  140. * Validate the shadowee.
  141. */
  142. if ( !iswdigit(*WSName) ) {
  143. /*
  144. * Treat the entered string as a WinStation name.
  145. *
  146. */
  147. if ( !LogonIdFromWinStationName(hServerName, WSName, &LogonId) ) {
  148. StringErrorPrintf(IDS_ERROR_WINSTATION_NOT_FOUND, WSName);
  149. return(FAILURE);
  150. }
  151. Message(IDS_SHADOWING_WARNING);
  152. if ( v_flag )
  153. StringMessage(IDS_SHADOWING_WINSTATION, WSName);
  154. } else {
  155. /*
  156. * Treated the entered string as a LogonId.
  157. */
  158. LogonId = wcstoul(WSName, &endptr, 10);
  159. if ( *endptr ) {
  160. StringErrorPrintf(IDS_ERROR_INVALID_LOGONID, WSName);
  161. return(FAILURE);
  162. }
  163. if ( !WinStationNameFromLogonId(hServerName, LogonId, WSName) ) {
  164. ErrorPrintf(IDS_ERROR_LOGONID_NOT_FOUND, LogonId);
  165. return(FAILURE);
  166. }
  167. Message(IDS_SHADOWING_WARNING);
  168. if ( v_flag )
  169. Message(IDS_SHADOWING_LOGONID, LogonId);
  170. }
  171. // Let the warning be displayed
  172. Sleep(500);
  173. /*
  174. * Start shadowing.
  175. */
  176. if ( IsTokenPresent(ptm, TOKEN_TIMEOUT) ) {
  177. Result = WinStationShadow( SERVERNAME_CURRENT,
  178. ServerName,
  179. LogonId,
  180. (BYTE)Timeout,
  181. (WORD)-1);
  182. } else {
  183. Result = WinStationShadow( SERVERNAME_CURRENT,
  184. ServerName,
  185. LogonId,
  186. VK_MULTIPLY,
  187. KBDCTRL ); // ctrl-*
  188. }
  189. /*
  190. * Return success or failure.
  191. */
  192. if ( !Result ) {
  193. ErrorPrintf(IDS_ERROR_SHADOW_FAILURE, GetLastError());
  194. PutStdErr( GetLastError(), 0 );
  195. return(FAILURE);
  196. } else {
  197. if ( v_flag )
  198. Message(IDS_SHADOWING_DONE);
  199. return(SUCCESS);
  200. }
  201. } /* main() */
  202. /*******************************************************************************
  203. *
  204. * Usage
  205. *
  206. * Output the usage message for this utility.
  207. *
  208. * ENTRY:
  209. * bError (input)
  210. * TRUE if the 'invalid parameter(s)' message should preceed the usage
  211. * message and the output go to stderr; FALSE for no such error
  212. * string and output goes to stdout.
  213. *
  214. * EXIT:
  215. *
  216. *
  217. ******************************************************************************/
  218. void
  219. Usage( BOOLEAN bError )
  220. {
  221. if ( bError ) {
  222. ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS);
  223. ErrorPrintf(IDS_USAGE_1);
  224. ErrorPrintf(IDS_USAGE_2);
  225. ErrorPrintf(IDS_USAGE_3);
  226. ErrorPrintf(IDS_USAGE_4);
  227. ErrorPrintf(IDS_USAGE_5);
  228. ErrorPrintf(IDS_USAGE_6);
  229. ErrorPrintf(IDS_USAGE_7);
  230. ErrorPrintf(IDS_USAGE_8);
  231. ErrorPrintf(IDS_USAGE_9);
  232. } else {
  233. Message(IDS_USAGE_1);
  234. Message(IDS_USAGE_2);
  235. Message(IDS_USAGE_3);
  236. Message(IDS_USAGE_4);
  237. Message(IDS_USAGE_5);
  238. Message(IDS_USAGE_6);
  239. Message(IDS_USAGE_7);
  240. Message(IDS_USAGE_8);
  241. Message(IDS_USAGE_9);
  242. }
  243. } /* Usage() */