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.

285 lines
8.9 KiB

  1. /****************************************************************************/
  2. // icarpc.c
  3. //
  4. // winsta.dll RPC client code for interaction with termsrv.exe.
  5. //
  6. // Copyright (C) 1997-2000 Microsoft Corporation
  7. /****************************************************************************/
  8. #include <nt.h>
  9. #include <ntrtl.h>
  10. #include <nturtl.h>
  11. #include <ntddkbd.h>
  12. #include <ntddmou.h>
  13. #include <windows.h>
  14. #include <winbase.h>
  15. #include <winerror.h>
  16. #include <winsta.h>
  17. #include <icadd.h>
  18. #include "rpcwire.h"
  19. /****************************************************************************
  20. * ValidUserBuffer
  21. *
  22. * This function verifies that the caller if WinStationQueryInformation/
  23. * WinStationSetInformation has the correct structure size (i.e. client
  24. * application built with the same header files as winsta.dll).
  25. *
  26. * ENTRY:
  27. * BufferSize
  28. * The size of the bufferr.
  29. *
  30. * InfoClass
  31. * The WinStationQuery/Set information class.
  32. *
  33. * EXIT:
  34. * Retures TRUE if the buffer is valid, otherwise FALSE.
  35. ****************************************************************************/
  36. BOOLEAN ValidUserBuffer(ULONG BufferSize, WINSTATIONINFOCLASS InfoClass)
  37. {
  38. switch (InfoClass) {
  39. case WinStationLoadIndicator:
  40. return(BufferSize >= sizeof(WINSTATIONLOADINDICATORDATA));
  41. case WinStationCreateData:
  42. return(BufferSize == sizeof(WINSTATIONCREATEW));
  43. case WinStationConfiguration:
  44. return(BufferSize == sizeof(WINSTATIONCONFIGW));
  45. case WinStationPdParams:
  46. return(BufferSize == sizeof(PDPARAMSW));
  47. case WinStationWd:
  48. return(BufferSize == sizeof(WDCONFIGW));
  49. case WinStationPd:
  50. return(BufferSize == sizeof(PDCONFIGW));
  51. case WinStationPrinter:
  52. return(BufferSize == sizeof(WINSTATIONPRINTERW));
  53. case WinStationClient:
  54. return(BufferSize == sizeof(WINSTATIONCLIENTW));
  55. case WinStationModules:
  56. return(TRUE);
  57. case WinStationInformation:
  58. return(BufferSize == sizeof(WINSTATIONINFORMATIONW));
  59. case WinStationTrace:
  60. return(BufferSize == sizeof(ICA_TRACE));
  61. case WinStationBeep:
  62. return(BufferSize == sizeof(BEEPINPUT));
  63. case WinStationEncryptionOff:
  64. case WinStationEncryptionPerm:
  65. case WinStationNtSecurity:
  66. return(TRUE);
  67. case WinStationUserToken:
  68. return(BufferSize == sizeof(WINSTATIONUSERTOKEN));
  69. case WinStationVideoData:
  70. case WinStationInitialProgram:
  71. case WinStationCd:
  72. case WinStationSystemTrace:
  73. case WinStationVirtualData:
  74. return(TRUE); // Not Implemented - let server handle it
  75. case WinStationClientData:
  76. return(BufferSize >= sizeof(WINSTATIONCLIENTDATA));
  77. case WinStationLoadBalanceSessionTarget:
  78. return (BufferSize >= sizeof(ULONG));
  79. case WinStationShadowInfo:
  80. return(BufferSize == sizeof(WINSTATIONSHADOW));
  81. case WinStationDigProductId:
  82. return(BufferSize >= sizeof(WINSTATIONPRODID));
  83. case WinStationLockedState:
  84. return(BufferSize >= sizeof(BOOL));
  85. case WinStationRemoteAddress:
  86. return(BufferSize >= sizeof(WINSTATIONREMOTEADDRESS));
  87. case WinStationLastReconnectType:
  88. return(BufferSize >= sizeof(ULONG));
  89. case WinStationDisallowAutoReconnect:
  90. return(BufferSize >= sizeof(BOOLEAN));
  91. case WinStationMprNotifyInfo:
  92. return(BufferSize >= sizeof(ExtendedClientCredentials));
  93. default:
  94. return(FALSE);
  95. }
  96. }
  97. /****************************************************************************
  98. * CreateGenericWireBuf
  99. *
  100. * This function creates a generic wire buffer for structures which may
  101. * have new fields added to the end.
  102. *
  103. * ENTRY:
  104. *
  105. * DataSize (input)
  106. * The size of the structure.
  107. * pBuffer (output)
  108. * Pointer to the allocated buffer.
  109. * pBufSize (output)
  110. * Pointer to the wire buffer size.
  111. *
  112. * EXIT:
  113. * Returns ERROR_SUCCESS if successful. If successful, pBuffer
  114. * contains the generic wire buffer.
  115. ****************************************************************************/
  116. ULONG CreateGenericWireBuf(ULONG DataSize, PVOID *ppBuffer, PULONG pBufSize)
  117. {
  118. ULONG BufSize;
  119. PVARDATA_WIRE pVarData;
  120. BufSize = sizeof(VARDATA_WIRE) + DataSize;
  121. if ((pVarData = (PVARDATA_WIRE)LocalAlloc(0,BufSize)) == NULL)
  122. return(ERROR_NOT_ENOUGH_MEMORY);
  123. InitVarData(pVarData, DataSize, sizeof(VARDATA_WIRE));
  124. *ppBuffer = (PVOID) pVarData;
  125. *pBufSize = BufSize;
  126. return ERROR_SUCCESS;
  127. }
  128. /****************************************************************************
  129. * CheckUserBuffer
  130. *
  131. * This function determines if the buffer type should be converted to a
  132. * wire format. If so, a wire buffer is allocated.
  133. *
  134. * ENTRY:
  135. * InfoClass (input)
  136. * WinStationQuery/Set information class.
  137. *
  138. * UserBuf(input)
  139. * The client bufferr.
  140. *
  141. * UserBufLen (input)
  142. * The client buffer length.
  143. *
  144. * ppWireBuf(output)
  145. * Pointer to wirebuf pointer, updated with allocated wire buffer if
  146. * BufAllocated is TRUE.
  147. * pWireBufLen (output)
  148. * Pointer to the length of the wire buffer allocated, updated if
  149. * BufAllocated is TRUE.
  150. * pBufAllocated (output)
  151. * Pointer to flag indicating if a wire buffer was allocated.
  152. * EXIT:
  153. * Returns ERROR_SUCCESS if successful. If successful, BufAllocated
  154. * indicated whether a wire buffer was allocated.
  155. * on failure, an error code is returned.
  156. ****************************************************************************/
  157. ULONG CheckUserBuffer(
  158. WINSTATIONINFOCLASS InfoClass,
  159. PVOID UserBuf,
  160. ULONG UserBufLen,
  161. PVOID *ppWireBuf,
  162. PULONG pWireBufLen,
  163. BOOLEAN *pBufAllocated)
  164. {
  165. ULONG BufSize;
  166. ULONG Error;
  167. PPDCONFIGWIREW PdConfigWire;
  168. PPDCONFIGW PdConfig;
  169. PPDPARAMSWIREW PdParamsWire;
  170. PPDPARAMSW PdParam;
  171. PWINSTACONFIGWIREW WinStaConfigWire;
  172. PWINSTATIONCONFIGW WinStaConfig;
  173. PVOID WireBuf;
  174. if (!ValidUserBuffer(UserBufLen, InfoClass)) {
  175. return(ERROR_INSUFFICIENT_BUFFER);
  176. }
  177. switch (InfoClass) {
  178. case WinStationPd:
  179. BufSize = sizeof(PDCONFIGWIREW) + sizeof(PDCONFIG2W) + sizeof(PDPARAMSW);
  180. if ((WireBuf = (PCHAR)LocalAlloc(0,BufSize)) == NULL)
  181. return(ERROR_NOT_ENOUGH_MEMORY);
  182. PdConfigWire = (PPDCONFIGWIREW)WireBuf;
  183. InitVarData(&PdConfigWire->PdConfig2W,
  184. sizeof(PDCONFIG2W),
  185. sizeof(PDCONFIGWIREW));
  186. InitVarData(&PdConfigWire->PdParams.SdClassSpecific,
  187. sizeof(PDPARAMSW) - sizeof(SDCLASS),
  188. NextOffset(&PdConfigWire->PdConfig2W));
  189. break;
  190. case WinStationPdParams:
  191. BufSize = sizeof(PDPARAMSWIREW) + sizeof(PDPARAMSW);
  192. if ((WireBuf = (PCHAR)LocalAlloc(0,BufSize)) == NULL)
  193. return(ERROR_NOT_ENOUGH_MEMORY);
  194. PdParamsWire = (PPDPARAMSWIREW)WireBuf;
  195. InitVarData(&PdParamsWire->SdClassSpecific,
  196. sizeof(PDPARAMSW),
  197. sizeof(PDPARAMSWIREW));
  198. break;
  199. case WinStationConfiguration:
  200. BufSize = sizeof(WINSTACONFIGWIREW) + sizeof(USERCONFIGW);
  201. if ((WireBuf = (PCHAR)LocalAlloc(0,BufSize)) == NULL)
  202. return(ERROR_NOT_ENOUGH_MEMORY);
  203. WinStaConfigWire = (PWINSTACONFIGWIREW)WireBuf;
  204. InitVarData(&WinStaConfigWire->UserConfig,
  205. sizeof(USERCONFIGW),
  206. sizeof(WINSTACONFIGWIREW));
  207. InitVarData(&WinStaConfigWire->NewFields,
  208. 0,
  209. NextOffset(&WinStaConfigWire->UserConfig));
  210. break;
  211. case WinStationInformation:
  212. if ((Error = CreateGenericWireBuf(sizeof(WINSTATIONINFORMATIONW),
  213. &WireBuf,
  214. &BufSize)) != ERROR_SUCCESS)
  215. return(Error);
  216. break;
  217. case WinStationWd:
  218. if ((Error = CreateGenericWireBuf(sizeof(WDCONFIGW),
  219. &WireBuf,
  220. &BufSize)) != ERROR_SUCCESS)
  221. return(Error);
  222. break;
  223. case WinStationClient:
  224. if ((Error = CreateGenericWireBuf(sizeof(WINSTATIONCLIENTW),
  225. &WireBuf,
  226. &BufSize)) != ERROR_SUCCESS)
  227. return(Error);
  228. break;
  229. default:
  230. *ppWireBuf = NULL;
  231. *pBufAllocated = FALSE;
  232. return ERROR_SUCCESS;
  233. }
  234. *pWireBufLen = BufSize;
  235. *ppWireBuf = WireBuf;
  236. *pBufAllocated = TRUE;
  237. return ERROR_SUCCESS;
  238. }