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.

241 lines
5.7 KiB

  1. // Copyright (c) 1998-1999 Microsoft Corporation
  2. /*************************************************************************
  3. *
  4. * TSDISCON.C
  5. *
  6. * This module is the TSDISCON utility code.
  7. *
  8. *
  9. *************************************************************************/
  10. #include <stdio.h>
  11. #include <windows.h>
  12. //#include <ntddkbd.h>
  13. //#include <ntddmou.h>
  14. #include <winstaw.h>
  15. #include <stdlib.h>
  16. #include <utilsub.h>
  17. #include <string.h>
  18. #include <malloc.h>
  19. #include <locale.h>
  20. #include "tsdiscon.h"
  21. #include "printfoa.h"
  22. WINSTATIONNAME WSName;
  23. USHORT help_flag = FALSE;
  24. USHORT v_flag = FALSE;
  25. HANDLE hServerName = SERVERNAME_CURRENT;
  26. WCHAR ServerName[MAX_IDS_LEN+1];
  27. TOKMAP ptm[] =
  28. {
  29. #define TERM_PARM 0
  30. {TOKEN_WS, TMFLAG_OPTIONAL, TMFORM_STRING,
  31. WINSTATIONNAME_LENGTH, WSName},
  32. {TOKEN_SERVER, TMFLAG_OPTIONAL, TMFORM_STRING,
  33. MAX_IDS_LEN, ServerName},
  34. {TOKEN_HELP, TMFLAG_OPTIONAL, TMFORM_BOOLEAN,
  35. sizeof(USHORT), &help_flag},
  36. {TOKEN_VERBOSE, TMFLAG_OPTIONAL, TMFORM_BOOLEAN,
  37. sizeof(USHORT), &v_flag},
  38. {0, 0, 0, 0, 0}
  39. };
  40. /*
  41. * Local function prototypes.
  42. */
  43. void Usage( BOOLEAN bError );
  44. /*************************************************************************
  45. *
  46. * main
  47. * Main function and entry point of the TSDISCON
  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. BOOLEAN bCurrent = FALSE;
  62. int rc, i;
  63. ULONG Error;
  64. WCHAR *CmdLine;
  65. WCHAR **argvW, *endptr;
  66. ULONG LogonId;
  67. setlocale(LC_ALL, ".OCP");
  68. /*
  69. * Massage the command line.
  70. */
  71. argvW = MassageCommandLine((DWORD)argc);
  72. if (argvW == NULL) {
  73. ErrorPrintf(IDS_ERROR_MALLOC);
  74. return(FAILURE);
  75. }
  76. /*
  77. * parse the cmd line without parsing the program name (argc-1, argv+1)
  78. */
  79. rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
  80. /*
  81. * Check for error from ParseCommandLine
  82. */
  83. if ( help_flag || (rc && !(rc & PARSE_FLAG_NO_PARMS)) ) {
  84. if ( !help_flag ) {
  85. Usage(TRUE);
  86. return(FAILURE);
  87. } else {
  88. Usage(FALSE);
  89. return(SUCCESS);
  90. }
  91. }
  92. //Check if we are running under Terminal Server
  93. if ((!IsTokenPresent(ptm, TOKEN_SERVER) ) && (!AreWeRunningTerminalServices()))
  94. {
  95. ErrorPrintf(IDS_ERROR_NOT_TS);
  96. return(FAILURE);
  97. }
  98. /*
  99. * Open the specified server
  100. */
  101. if( ServerName[0] ) {
  102. hServerName = WinStationOpenServer( ServerName );
  103. if( hServerName == NULL ) {
  104. StringErrorPrintf(IDS_ERROR_SERVER,ServerName);
  105. PutStdErr( GetLastError(), 0 );
  106. return(FAILURE);
  107. }
  108. }
  109. /*
  110. * Validate input string for WinStation or LogonId.
  111. */
  112. if ( !IsTokenPresent(ptm, TOKEN_WS) ) {
  113. /*
  114. * No string specified; use current WinStation / LogonId.
  115. */
  116. bCurrent = TRUE;
  117. LogonId = GetCurrentLogonId();
  118. if ( !WinStationNameFromLogonId(hServerName, LogonId, WSName) ) {
  119. ErrorPrintf(IDS_ERROR_CANT_GET_CURRENT_WINSTATION, GetLastError());
  120. PutStdErr( GetLastError(), 0 );
  121. return(FAILURE);
  122. }
  123. } else if ( !iswdigit(*WSName) ) {
  124. /*
  125. * Treat the string as a WinStation name.
  126. */
  127. if ( !LogonIdFromWinStationName(hServerName, WSName, &LogonId) ) {
  128. StringErrorPrintf(IDS_ERROR_WINSTATION_NOT_FOUND, WSName);
  129. return(FAILURE);
  130. }
  131. } else {
  132. /*
  133. * Treat the string as a LogonId.
  134. */
  135. LogonId = wcstoul(WSName, &endptr, 10);
  136. if ( *endptr ) {
  137. StringErrorPrintf(IDS_ERROR_INVALID_LOGONID, WSName);
  138. return(FAILURE);
  139. }
  140. if ( !WinStationNameFromLogonId(hServerName, LogonId, WSName) ) {
  141. ErrorPrintf(IDS_ERROR_LOGONID_NOT_FOUND, LogonId);
  142. return(FAILURE);
  143. }
  144. }
  145. /*
  146. * Perform the disconnect.
  147. */
  148. if ( v_flag )
  149. DwordStringMessage(IDS_WINSTATION_DISCONNECT, LogonId, WSName);
  150. if ( !WinStationDisconnect(hServerName, LogonId, TRUE) ) {
  151. if ( bCurrent )
  152. ErrorPrintf(IDS_ERROR_DISCONNECT_CURRENT,
  153. GetLastError());
  154. else
  155. ErrorPrintf(IDS_ERROR_DISCONNECT,
  156. LogonId, WSName, GetLastError());
  157. PutStdErr( GetLastError(), 0 );
  158. return(FAILURE);
  159. }
  160. return(SUCCESS);
  161. } /* main() */
  162. /*******************************************************************************
  163. *
  164. * Usage
  165. *
  166. * Output the usage message for this utility.
  167. *
  168. * ENTRY:
  169. * bError (input)
  170. * TRUE if the 'invalid parameter(s)' message should preceed the usage
  171. * message and the output go to stderr; FALSE for no such error
  172. * string and output goes to stdout.
  173. *
  174. * EXIT:
  175. *
  176. *
  177. ******************************************************************************/
  178. void
  179. Usage( BOOLEAN bError )
  180. {
  181. if ( bError ) {
  182. ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS);
  183. ErrorPrintf(IDS_USAGE_1);
  184. ErrorPrintf(IDS_USAGE_2);
  185. ErrorPrintf(IDS_USAGE_3);
  186. ErrorPrintf(IDS_USAGE_4);
  187. ErrorPrintf(IDS_USAGE_5);
  188. ErrorPrintf(IDS_USAGE_6);
  189. } else {
  190. Message(IDS_USAGE_1);
  191. Message(IDS_USAGE_2);
  192. Message(IDS_USAGE_3);
  193. Message(IDS_USAGE_4);
  194. Message(IDS_USAGE_5);
  195. Message(IDS_USAGE_6);
  196. }
  197. } /* Usage() */