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.

306 lines
7.7 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*************************************************************************
  3. *
  4. * RWINSTA.C
  5. * This module is the RESET WINSTA utility code.
  6. *
  7. *
  8. *************************************************************************/
  9. #include <stdio.h>
  10. #include <windows.h>
  11. //#include <ntddkbd.h>
  12. //#include <ntddmou.h>
  13. #include <winstaw.h>
  14. #include <stdlib.h>
  15. #include <utilsub.h>
  16. #include <string.h>
  17. #include <malloc.h>
  18. #include <locale.h>
  19. #include "rwinsta.h"
  20. #include <printfoa.h>
  21. WINSTATIONNAME WSName;
  22. USHORT help_flag = FALSE;
  23. USHORT v_flag = FALSE;
  24. HANDLE hServerName = SERVERNAME_CURRENT;
  25. WCHAR ServerName[MAX_IDS_LEN+1];
  26. TOKMAP ptm[] =
  27. {
  28. #define TERM_PARM 0
  29. {TOKEN_WS, TMFLAG_REQUIRED, TMFORM_S_STRING,
  30. WINSTATIONNAME_LENGTH, WSName},
  31. {TOKEN_SERVER, TMFLAG_OPTIONAL, TMFORM_STRING,
  32. MAX_IDS_LEN, ServerName},
  33. {TOKEN_HELP, TMFLAG_OPTIONAL, TMFORM_BOOLEAN,
  34. sizeof(USHORT), &help_flag},
  35. {TOKEN_VERBOSE, TMFLAG_OPTIONAL, TMFORM_BOOLEAN,
  36. sizeof(USHORT), &v_flag},
  37. {0, 0, 0, 0, 0}
  38. };
  39. /*
  40. * Local function prototypes.
  41. */
  42. void Usage( BOOLEAN bError );
  43. BOOL ProceedWithLogoff(HANDLE hServerName,ULONG LogonId,PWINSTATIONNAME pWSName);
  44. /*************************************************************************
  45. *
  46. * main
  47. * Main function and entry point of the RESET WINSTA
  48. * utility.
  49. *
  50. * ENTRY:
  51. * argc - count of the command line arguments.
  52. * argv - vector of strings containing the command line arguments.
  53. *
  54. * EXIT
  55. * Nothing.
  56. *
  57. *************************************************************************/
  58. int __cdecl
  59. main(INT argc, CHAR **argv)
  60. {
  61. int rc, i;
  62. ULONG Error;
  63. WCHAR **argvW, *endptr;
  64. ULONG LogonId;
  65. setlocale(LC_ALL, ".OCP");
  66. /*
  67. * Massage the command line.
  68. */
  69. argvW = MassageCommandLine((DWORD)argc);
  70. if (argvW == NULL) {
  71. ErrorPrintf(IDS_ERROR_MALLOC);
  72. return(FAILURE);
  73. }
  74. /*
  75. * parse the cmd line without parsing the program name (argc-1, argv+1)
  76. */
  77. rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
  78. /*
  79. * Check for error from ParseCommandLine
  80. */
  81. if ( help_flag || rc ) {
  82. if ( !help_flag ) {
  83. Usage(TRUE);
  84. return(FAILURE);
  85. } else {
  86. Usage(FALSE);
  87. return(SUCCESS);
  88. }
  89. }
  90. // If no remote server was specified, then check if we are running under Terminal Server
  91. if ((!IsTokenPresent(ptm, TOKEN_SERVER) ) && (!AreWeRunningTerminalServices()))
  92. {
  93. ErrorPrintf(IDS_ERROR_NOT_TS);
  94. return(FAILURE);
  95. }
  96. /*
  97. * Open the specified server
  98. */
  99. if( ServerName[0] ) {
  100. hServerName = WinStationOpenServer( ServerName );
  101. if( hServerName == NULL ) {
  102. StringErrorPrintf(IDS_ERROR_SERVER,ServerName);
  103. PutStdErr( GetLastError(), 0 );
  104. return(FAILURE);
  105. }
  106. }
  107. /*
  108. * Validate, reset, and output status.
  109. */
  110. if ( !iswdigit(*WSName) ) {
  111. /*
  112. * Treat the entered string as a WinStation name.
  113. */
  114. if ( !LogonIdFromWinStationName(hServerName, WSName, &LogonId) ) {
  115. StringErrorPrintf(IDS_ERROR_WINSTATION_NOT_FOUND, WSName);
  116. return(FAILURE);
  117. }
  118. if(!ProceedWithLogoff(hServerName,LogonId,WSName))
  119. return (SUCCESS);
  120. if ( v_flag )
  121. StringMessage(IDS_RESET_WINSTATION, WSName);
  122. if ( !WinStationReset(hServerName, LogonId, TRUE) ) {
  123. Error = GetLastError();
  124. StringDwordErrorPrintf(IDS_ERROR_WINSTATION_RESET_FAILED, WSName, Error);
  125. PutStdErr( Error, 0 );
  126. return(FAILURE);
  127. }
  128. if ( v_flag )
  129. StringMessage(IDS_RESET_WINSTATION_DONE, WSName);
  130. } else {
  131. /*
  132. * Treated the entered string as a LogonId.
  133. */
  134. LogonId = wcstoul(WSName, &endptr, 10);
  135. if ( *endptr ) {
  136. StringErrorPrintf(IDS_ERROR_INVALID_LOGONID, WSName);
  137. return(FAILURE);
  138. }
  139. if ( !WinStationNameFromLogonId(hServerName, LogonId, WSName) ) {
  140. ErrorPrintf(IDS_ERROR_LOGONID_NOT_FOUND, LogonId);
  141. return(FAILURE);
  142. }
  143. if(!ProceedWithLogoff(hServerName,LogonId,WSName))
  144. return (SUCCESS);
  145. if ( v_flag )
  146. Message(IDS_RESET_LOGONID, LogonId);
  147. if ( !WinStationReset(hServerName, LogonId, TRUE) ) {
  148. Error = GetLastError();
  149. ErrorPrintf(IDS_ERROR_LOGONID_RESET_FAILED, LogonId, Error);
  150. PutStdErr( GetLastError(), 0 );
  151. return(FAILURE);
  152. }
  153. if ( v_flag )
  154. Message(IDS_RESET_LOGONID_DONE, LogonId);
  155. }
  156. return(SUCCESS);
  157. } /* main() */
  158. /*******************************************************************************
  159. *
  160. * ProcessWithLogoff
  161. *
  162. * If LogonId does not have a corresponding UserName then a warning
  163. * message is displayed.
  164. *
  165. * ENTRY:
  166. * hServerName : Handle to server
  167. * LogonId : ID as shown in qwinsta
  168. * pWSName : Session Name
  169. *
  170. * EXIT:
  171. * TRUE : User wants to logoff
  172. * FALSE: User does not want to proceed with logoff
  173. *
  174. *
  175. ******************************************************************************/
  176. BOOL ProceedWithLogoff(HANDLE hServerName,ULONG LogonId,PWINSTATIONNAME pWSName)
  177. {
  178. #ifdef UNICODE
  179. #define GetStdInChar getwchar
  180. wint_t ch;
  181. #else
  182. #define GetStdInChar getchar
  183. int ch;
  184. #endif
  185. WINSTATIONINFORMATION WinInfo;
  186. ULONG ReturnLength;
  187. int rc;
  188. // No-session Name, No-Problem
  189. if(lstrlen(pWSName) == 0) return (TRUE);
  190. memset(&WinInfo,0,sizeof(WINSTATIONINFORMATION));
  191. rc = WinStationQueryInformation( hServerName,
  192. LogonId,
  193. WinStationInformation,
  194. (PVOID)&WinInfo,
  195. sizeof(WINSTATIONINFORMATION),
  196. &ReturnLength);
  197. // Try to show message only if necessary
  198. if( rc && (sizeof(WINSTATIONINFORMATION) == ReturnLength) ) {
  199. if(lstrlen(WinInfo.UserName) == 0) {
  200. ErrorPrintf(IDS_WARNING_LOGOFF);
  201. rc = GetStdInChar();
  202. if(rc == L'n') return(FALSE);
  203. }
  204. }
  205. // Failed on call - assume nothing and prompt with message
  206. else{
  207. ErrorPrintf(IDS_WARNING_LOGOFF_QUESTIONABLE);
  208. rc = GetStdInChar();
  209. if(rc == L'n') return(FALSE);
  210. }
  211. return (TRUE);
  212. }
  213. /*******************************************************************************
  214. *
  215. * Usage
  216. *
  217. * Output the usage message for this utility.
  218. *
  219. * ENTRY:
  220. * bError (input)
  221. * TRUE if the 'invalid parameter(s)' message should preceed the usage
  222. * message and the output go to stderr; FALSE for no such error
  223. * string and output goes to stdout.
  224. *
  225. * EXIT:
  226. *
  227. *
  228. ******************************************************************************/
  229. void
  230. Usage( BOOLEAN bError )
  231. {
  232. if ( bError ) {
  233. ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS);
  234. ErrorPrintf(IDS_USAGE_1);
  235. ErrorPrintf(IDS_USAGE_2);
  236. ErrorPrintf(IDS_USAGE_3);
  237. ErrorPrintf(IDS_USAGE_4);
  238. ErrorPrintf(IDS_USAGE_5);
  239. ErrorPrintf(IDS_USAGE_6);
  240. ErrorPrintf(IDS_USAGE_7);
  241. ErrorPrintf(IDS_USAGE_8);
  242. ErrorPrintf(IDS_USAGE_9);
  243. } else {
  244. Message(IDS_USAGE_1);
  245. Message(IDS_USAGE_2);
  246. Message(IDS_USAGE_3);
  247. Message(IDS_USAGE_4);
  248. Message(IDS_USAGE_5);
  249. Message(IDS_USAGE_6);
  250. Message(IDS_USAGE_7);
  251. Message(IDS_USAGE_8);
  252. Message(IDS_USAGE_9);
  253. }
  254. } /* Usage() */