Leaked source code of windows server 2003
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.

402 lines
10 KiB

  1. /*******************************************************************************
  2. * server.c
  3. *
  4. * Published Terminal Server APIs
  5. *
  6. * - server routines
  7. *
  8. * Copyright 1998, Citrix Systems Inc.
  9. * Copyright (C) 1997-1999 Microsoft Corp.
  10. /******************************************************************************/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <ntddkbd.h>
  15. #include <ntddmou.h>
  16. #include <windows.h>
  17. #include <winbase.h>
  18. #include <winerror.h>
  19. #if(WINVER >= 0x0500)
  20. #include <ntstatus.h>
  21. #include <winsta.h>
  22. #else
  23. #include <citrix\cxstatus.h>
  24. #include <citrix\winsta.h>
  25. #endif
  26. #include <utildll.h>
  27. #include <stdio.h>
  28. #include <stdarg.h>
  29. #include <wtsapi32.h>
  30. /*=============================================================================
  31. == External procedures defined
  32. =============================================================================*/
  33. BOOL WINAPI WTSEnumerateServersW( LPWSTR, DWORD, DWORD, PWTS_SERVER_INFOW *, DWORD * );
  34. BOOL WINAPI WTSEnumerateServersA( LPSTR, DWORD, DWORD, PWTS_SERVER_INFOA *, DWORD * );
  35. HANDLE WINAPI WTSOpenServerW( LPWSTR );
  36. HANDLE WINAPI WTSOpenServerA( LPSTR );
  37. VOID WINAPI WTSCloseServer( HANDLE );
  38. /*=============================================================================
  39. == Procedures used
  40. =============================================================================*/
  41. VOID UnicodeToAnsi( CHAR *, ULONG, WCHAR * );
  42. VOID AnsiToUnicode( WCHAR *, ULONG, CHAR * );
  43. /****************************************************************************
  44. *
  45. * WTSEnumerateServersW (UNICODE)
  46. *
  47. * Returns a list of Terminal servers within the specified NT domain
  48. *
  49. * ENTRY:
  50. * pDomainName (input)
  51. * Pointer to NT domain name (or NULL for current domain)
  52. * Reserved (input)
  53. * Must be zero
  54. * Version (input)
  55. * Version of the enumeration request (must be 1)
  56. * ppServerInfo (output)
  57. * Points to the address of a variable to receive the enumeration results,
  58. * which are returned as an array of WTS_SERVER_INFO structures. The
  59. * buffer is allocated within this API and is disposed of using
  60. * WTSFreeMemory.
  61. * pCount (output)
  62. * Points to the address of a variable to receive the number of
  63. * WTS_SERVER_INFO structures returned
  64. *
  65. * EXIT:
  66. *
  67. * TRUE -- The enumerate operation succeeded.
  68. *
  69. * FALSE -- The operation failed. Extended error status is available
  70. * using GetLastError.
  71. *
  72. ****************************************************************************/
  73. BOOL
  74. WINAPI
  75. WTSEnumerateServersW(
  76. IN LPWSTR pDomainName,
  77. IN DWORD Reserved,
  78. IN DWORD Version,
  79. OUT PWTS_SERVER_INFOW * ppServerInfo,
  80. OUT DWORD * pCount
  81. )
  82. {
  83. LPWSTR pServerList;
  84. LPWSTR pData;
  85. PBYTE pNameData;
  86. ULONG Length;
  87. ULONG NameCount; // number of names
  88. ULONG NameLength; // number of bytes of name data
  89. PWTS_SERVER_INFOW pServerW;
  90. /*
  91. * Validate parameters
  92. */
  93. if ( Reserved != 0 || Version != 1 ) {
  94. SetLastError( ERROR_INVALID_PARAMETER );
  95. goto badparam;
  96. }
  97. if ( !ppServerInfo || !pCount) {
  98. SetLastError( ERROR_INVALID_USER_BUFFER);
  99. goto badparam;
  100. }
  101. /*
  102. * Enumerate servers and check for an error
  103. */
  104. pServerList = EnumerateMultiUserServers( pDomainName );
  105. if ( pServerList == NULL ) {
  106. SetLastError(ERROR_INVALID_DOMAINNAME);
  107. goto badenum;
  108. }
  109. /*
  110. * Count the number of Terminal servers
  111. */
  112. NameCount = 0;
  113. NameLength = 0;
  114. pData = pServerList;
  115. while ( *pData ) {
  116. Length = (wcslen(pData) + 1) * sizeof(WCHAR); // number of bytes
  117. NameCount++;
  118. NameLength += Length;
  119. (PBYTE)pData += Length;
  120. }
  121. /*
  122. * Allocate user buffer
  123. */
  124. pServerW = LocalAlloc( LPTR, (NameCount * sizeof(WTS_SERVER_INFOW)) + NameLength );
  125. if ( pServerW == NULL )
  126. goto badalloc;
  127. /*
  128. * Update user parameters
  129. */
  130. *ppServerInfo = pServerW;
  131. *pCount = NameCount;
  132. /*
  133. * Copy data to new buffer
  134. */
  135. pData = pServerList;
  136. pNameData = (PBYTE)pServerW + (NameCount * sizeof(WTS_SERVER_INFOW));
  137. while ( *pData ) {
  138. Length = (wcslen(pData) + 1) * sizeof(WCHAR); // number of bytes
  139. memcpy( pNameData, pData, Length );
  140. pServerW->pServerName = (LPWSTR) pNameData;
  141. pServerW++;
  142. pNameData += Length;
  143. (PBYTE)pData += Length;
  144. }
  145. /*
  146. * Free original server list buffer
  147. */
  148. LocalFree( pServerList );
  149. return( TRUE );
  150. /*=============================================================================
  151. == Error return
  152. =============================================================================*/
  153. badalloc:
  154. badenum:
  155. badparam:
  156. if (ppServerInfo) *ppServerInfo = NULL;
  157. if (pCount) *pCount = 0;
  158. return( FALSE );
  159. }
  160. /****************************************************************************
  161. *
  162. * WTSEnumerateServersA (ANSI stub)
  163. *
  164. * Returns a list of Terminal servers within the specified NT domain
  165. *
  166. * ENTRY:
  167. *
  168. * see WTSEnumerateServersW
  169. *
  170. * EXIT:
  171. *
  172. * TRUE -- The enumerate operation succeeded.
  173. *
  174. * FALSE -- The operation failed. Extended error status is available
  175. * using GetLastError.
  176. *
  177. ****************************************************************************/
  178. BOOL
  179. WINAPI
  180. WTSEnumerateServersA(
  181. IN LPSTR pDomainName,
  182. IN DWORD Reserved,
  183. IN DWORD Version,
  184. OUT PWTS_SERVER_INFOA * ppServerInfo,
  185. OUT DWORD * pCount
  186. )
  187. {
  188. LPWSTR pDomainNameW = NULL;
  189. ULONG DomainNameWLength;
  190. PWTS_SERVER_INFOW pServerW;
  191. PWTS_SERVER_INFOA pServerA;
  192. PBYTE pNameData;
  193. ULONG Length;
  194. ULONG NameLength; // number of bytes of name data
  195. ULONG NameCount;
  196. ULONG i;
  197. if ( !ppServerInfo || !pCount) {
  198. SetLastError( ERROR_INVALID_USER_BUFFER);
  199. return FALSE;
  200. }
  201. /*
  202. * Convert ansi domain name to unicode
  203. */
  204. if ( pDomainName ) {
  205. DomainNameWLength = (strlen(pDomainName) + 1) * sizeof(WCHAR);
  206. if ( (pDomainNameW = LocalAlloc( LPTR, DomainNameWLength )) == NULL )
  207. goto badalloc1;
  208. AnsiToUnicode( pDomainNameW, DomainNameWLength, pDomainName );
  209. }
  210. /*
  211. * Enumerate servers (UNICODE)
  212. */
  213. if ( !WTSEnumerateServersW( pDomainNameW,
  214. Reserved,
  215. Version,
  216. &pServerW,
  217. &NameCount ) ) {
  218. goto badenum;
  219. }
  220. /*
  221. * Calculate the length of the name data
  222. */
  223. for ( i=0, NameLength=0; i < NameCount; i++ ) {
  224. NameLength += (wcslen(pServerW[i].pServerName) + 1);
  225. }
  226. /*
  227. * Allocate user buffer
  228. */
  229. pServerA = LocalAlloc( LPTR, (NameCount * sizeof(WTS_SERVER_INFOA)) + NameLength );
  230. if ( pServerA == NULL )
  231. goto badalloc2;
  232. /*
  233. * Convert unicode server list to ansi
  234. */
  235. pNameData = (PBYTE)pServerA + (NameCount * sizeof(WTS_SERVER_INFOA));
  236. for ( i=0; i < NameCount; i++ ) {
  237. Length = wcslen(pServerW[i].pServerName) + 1;
  238. pServerA[i].pServerName = pNameData;
  239. UnicodeToAnsi( pNameData, NameLength, pServerW[i].pServerName );
  240. NameLength -= Length;
  241. pNameData += Length;
  242. }
  243. /*
  244. * Free unicode server list buffer
  245. */
  246. LocalFree( pServerW );
  247. /*
  248. * Free domain name buffer
  249. */
  250. if ( pDomainNameW )
  251. LocalFree( pDomainNameW );
  252. /*
  253. * Update user parameters
  254. */
  255. *ppServerInfo = pServerA;
  256. *pCount = NameCount;
  257. return( TRUE );
  258. /*=============================================================================
  259. == Error return
  260. =============================================================================*/
  261. badalloc2:
  262. LocalFree( pServerW );
  263. badenum:
  264. if ( pDomainNameW )
  265. LocalFree( pDomainNameW );
  266. badalloc1:
  267. *ppServerInfo = NULL;
  268. *pCount = 0;
  269. return( FALSE );
  270. }
  271. /****************************************************************************
  272. *
  273. * WTSOpenServerW (UNICODE)
  274. *
  275. * Opens a handle to the specified server
  276. *
  277. * NOTE: WTS_SERVER_CURRENT can be used as a handle to the current server
  278. *
  279. * ENTRY:
  280. * pServerName (input)
  281. * Pointer to Terminal server name
  282. *
  283. * EXIT:
  284. *
  285. * Handle to specified server (NULL on error)
  286. *
  287. *
  288. ****************************************************************************/
  289. HANDLE
  290. WINAPI
  291. WTSOpenServerW(
  292. IN LPWSTR pServerName
  293. )
  294. {
  295. return( WinStationOpenServerW( pServerName ) );
  296. }
  297. /****************************************************************************
  298. *
  299. * WTSOpenServerA (ANSI)
  300. *
  301. * Opens a handle to the specified server
  302. *
  303. * NOTE: WTS_SERVER_CURRENT can be used as a handle to the current server
  304. *
  305. * ENTRY:
  306. * pServerName (input)
  307. * Pointer to Terminal server name
  308. *
  309. * EXIT:
  310. *
  311. * Handle to specified server
  312. *
  313. *
  314. ****************************************************************************/
  315. HANDLE
  316. WINAPI
  317. WTSOpenServerA(
  318. IN LPSTR pServerName
  319. )
  320. {
  321. return( WinStationOpenServerA( pServerName ) );
  322. }
  323. /****************************************************************************
  324. *
  325. * WTSCloseServer
  326. *
  327. * Close server handle
  328. *
  329. * ENTRY:
  330. * hServer (input)
  331. * handle to server
  332. *
  333. * EXIT:
  334. * nothing
  335. *
  336. ****************************************************************************/
  337. VOID
  338. WINAPI
  339. WTSCloseServer(
  340. IN HANDLE hServer
  341. )
  342. {
  343. (void) WinStationCloseServer( hServer );
  344. }