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.

399 lines
13 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name :
  4. session.h
  5. Abstract:
  6. Session object is created to handle redirection for this session
  7. Revision History:
  8. --*/
  9. #pragma once
  10. typedef enum enmSessionStatus { // cs
  11. csDisconnected, // Not yet connected, or disconnected
  12. csPendingClientConfirm, // ServerAnnounce sent, waiting for ClientConfirm
  13. csPendingClientReconfirm, // Insisted on ClientId, waiting for second ClientConfirm
  14. csConnected, // All connected, ready for devices or I/O
  15. csExpired // This client is gone
  16. } SessionState;
  17. class DrDevice;
  18. typedef struct tagWriteContext
  19. {
  20. IO_STATUS_BLOCK IoStatusBlock;
  21. SmartPtr<DrSession> Session;
  22. PVOID BufferToFree;
  23. PVOID AdditionalContext;
  24. ISessionPacketSender *PacketSender;
  25. DrWriteCallback WriteCallback;
  26. } DrWriteContext;
  27. //
  28. // Server capability set
  29. //
  30. typedef struct tagRDPDR_SERVER_COMBINED_CAPABILITYSET
  31. {
  32. RDPDR_CAPABILITY_SET_HEADER Header;
  33. #define RDPDR_NUM_SERVER_CAPABILITIES 5
  34. RDPDR_GENERAL_CAPABILITY GeneralCap;
  35. #define RDPDR_SERVER_IO_CODES 0xFFFF
  36. RDPDR_PRINT_CAPABILITY PrintCap;
  37. RDPDR_PORT_CAPABILITY PortCap;
  38. RDPDR_FS_CAPABILITY FileSysCap;
  39. RDPDR_SMARTCARD_CAPABILITY SmartCardCap;
  40. } RDPDR_SERVER_COMBINED_CAPABILITYSET, *PRDPDR_SERVER_COMBINED_CAPABILITYSET;
  41. //
  42. // Server default capability set sent to client
  43. //
  44. const RDPDR_SERVER_COMBINED_CAPABILITYSET SERVER_CAPABILITY_SET_DEFAULT = {
  45. // Capability Set Header
  46. {
  47. {
  48. RDPDR_CTYP_CORE,
  49. DR_CORE_SERVER_CAPABILITY
  50. },
  51. RDPDR_NUM_SERVER_CAPABILITIES,
  52. 0
  53. },
  54. // General Capability
  55. {
  56. RDPDR_GENERAL_CAPABILITY_TYPE,
  57. sizeof(RDPDR_GENERAL_CAPABILITY),
  58. RDPDR_GENERAL_CAPABILITY_VERSION_01,
  59. RDPDR_OS_TYPE_WINNT, // the OS type
  60. 0, // don't care about the version
  61. RDPDR_MAJOR_VERSION,
  62. RDPDR_MINOR_VERSION,
  63. RDPDR_SERVER_IO_CODES,
  64. 0,
  65. RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU,
  66. 0,
  67. 0
  68. },
  69. // Printing Capability
  70. {
  71. RDPDR_PRINT_CAPABILITY_TYPE,
  72. sizeof(RDPDR_PRINT_CAPABILITY),
  73. RDPDR_PRINT_CAPABILITY_VERSION_01
  74. },
  75. // Port Capability
  76. {
  77. RDPDR_PORT_CAPABILITY_TYPE,
  78. sizeof(RDPDR_PORT_CAPABILITY),
  79. RDPDR_PORT_CAPABILITY_VERSION_01
  80. },
  81. // FileSystem Capability
  82. {
  83. RDPDR_FS_CAPABILITY_TYPE,
  84. sizeof(RDPDR_FS_CAPABILITY),
  85. RDPDR_FS_CAPABILITY_VERSION_01
  86. },
  87. // SmartCard Capability
  88. {
  89. RDPDR_SMARTCARD_CAPABILITY_TYPE,
  90. sizeof(RDPDR_SMARTCARD_CAPABILITY),
  91. RDPDR_SMARTCARD_CAPABILITY_VERSION_01
  92. }
  93. };
  94. //
  95. // Default client capability set sent from client
  96. //
  97. const RDPDR_SERVER_COMBINED_CAPABILITYSET CLIENT_CAPABILITY_SET_DEFAULT = {
  98. // Capability Set Header
  99. {
  100. {
  101. RDPDR_CTYP_CORE,
  102. DR_CORE_CLIENT_CAPABILITY
  103. },
  104. RDPDR_NUM_SERVER_CAPABILITIES,
  105. 0
  106. },
  107. // General Capability
  108. {
  109. RDPDR_GENERAL_CAPABILITY_TYPE,
  110. sizeof(RDPDR_GENERAL_CAPABILITY),
  111. 0,
  112. 0, // Need to specify the OS type
  113. 0, // Need to specify the OS version
  114. 0,
  115. 0,
  116. 0,
  117. 0,
  118. 0,
  119. 0,
  120. 0
  121. },
  122. // Printing Capability
  123. {
  124. RDPDR_PRINT_CAPABILITY_TYPE,
  125. sizeof(RDPDR_PRINT_CAPABILITY),
  126. 0
  127. },
  128. // Port Capability
  129. {
  130. RDPDR_PORT_CAPABILITY_TYPE,
  131. sizeof(RDPDR_PORT_CAPABILITY),
  132. 0
  133. },
  134. // FileSystem Capability
  135. {
  136. RDPDR_FS_CAPABILITY_TYPE,
  137. sizeof(RDPDR_FS_CAPABILITY),
  138. 0
  139. },
  140. // SmartCard Capability
  141. {
  142. RDPDR_SMARTCARD_CAPABILITY_TYPE,
  143. sizeof(RDPDR_SMARTCARD_CAPABILITY),
  144. 0
  145. }
  146. };
  147. //
  148. // The session is not like other RefCount objects, in that releasing the last
  149. // reference both deletes the object and removes it from the SessionMgr. As
  150. // a result, we need a special RefCount implementation that accomodates the
  151. // SessionMgr lock as well as the deletion of the object in an atomic operation
  152. //
  153. class DrSession : public TopObj, public ISessionPacketReceiver, public ISessionPacketSender
  154. {
  155. private:
  156. LONG _crefs;
  157. SmartPtr<VirtualChannel> _Channel;
  158. DoubleList _PacketReceivers;
  159. KernelResource _ConnectNotificationLock;
  160. KernelResource _ConnectRDPDYNNotificationLock; // Need granular locking on notifying
  161. // RDPDYN so we don't deadlock.
  162. KernelResource _ChannelLock;
  163. ULONG _AutoClientDrives : 1; // Automatically map client drives
  164. ULONG _AutoClientLpts : 1; // Automatically install client printers
  165. ULONG _ForceClientLptDef : 1; // Set default printer to client default
  166. ULONG _DisableCpm : 1; // Disable Print mapping completely
  167. ULONG _DisableCdm : 1; // Disable Drive mapping
  168. ULONG _DisableCcm : 1; // Disable COM mapping
  169. ULONG _DisableLPT : 1; // Disable LPT port
  170. ULONG _DisableClip : 1; // Automatically redirect clipboard
  171. ULONG _DisableExe : 1; // I have no idea
  172. ULONG _DisableCam : 1; // Disable Audio mapping
  173. SessionState _SessionState;
  174. LONG _ConnectCount;
  175. PBYTE _ChannelBuffer;
  176. ULONG _ChannelBufferSize;
  177. KernelEvent _ChannelDeletionEvent;
  178. IO_STATUS_BLOCK _ReadStatus;
  179. ULONG _ClientId; // Id for this client (identifies SrvCall)
  180. DrExchangeManager _ExchangeManager;
  181. ULONG _PartialPacketData;
  182. WCHAR _ClientName[RDPDR_MAX_COMPUTER_NAME_LENGTH];
  183. WCHAR _ClientDisplayName[RDPDR_MAX_CLIENT_DISPLAY_NAME];
  184. DrDeviceManager _DeviceManager;
  185. ULONG _SessionId;
  186. RDPDR_VERSION _ClientVersion;
  187. RDPDR_SERVER_COMBINED_CAPABILITYSET _CliCapabilitySet;
  188. RDPDR_SERVER_COMBINED_CAPABILITYSET _SrvCapabilitySet;
  189. BOOL _Initialized;
  190. #if DBG
  191. LONG _BufCount;
  192. #define DEBUG_REF_BUF() /*ASSERT (InterlockedIncrement(&_BufCount) == 1)*/
  193. #define DEBUG_DEREF_BUF() /*ASSERT (InterlockedDecrement(&_BufCount) == 0)*/
  194. #else
  195. #define DEBUG_REF_BUF()
  196. #define DEBUG_DEREF_BUF()
  197. #endif
  198. VOID SetSessionState(SessionState inSessionState)
  199. {
  200. _SessionState = inSessionState;
  201. }
  202. #if DBG
  203. BOOL PacketReceiverExists(ISessionPacketReceiver *PacketReceiver);
  204. #endif // DBG
  205. BOOL FindChannelFromConnectIn(PULONG ChannelId,
  206. PCHANNEL_CONNECT_IN ConnectIn);
  207. VOID DeleteChannel(BOOL Wait);
  208. VOID SetChannel(SmartPtr<VirtualChannel> &Channel);
  209. VOID RemoveDevices();
  210. VOID CancelClientIO();
  211. VOID ChannelIoFailed();
  212. NTSTATUS ReallocateChannelBuffer(ULONG ulNewBufferSize,
  213. ULONG ulSaveBytes);
  214. //
  215. // Generic Sending and Receiving data
  216. //
  217. NTSTATUS PrivateSendToClient(PVOID Buffer, ULONG Length,
  218. ISessionPacketSender *PacketSender, DrWriteCallback WriteCallback,
  219. BOOL bWorkerItem, BOOL LowPrioWrite = FALSE,
  220. PVOID AdditionalContext = NULL);
  221. static NTSTATUS SendCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
  222. IN PIRP Irp, IN PVOID Context);
  223. static NTSTATUS ReadCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
  224. IN PIRP Irp, IN PVOID Context);
  225. VOID SendCompletion(DrWriteContext *WriteContext,
  226. PIO_STATUS_BLOCK IoStatusBlock);
  227. VOID ReadCompletion(PIO_STATUS_BLOCK IoStatusBlock);
  228. VOID ReadPacket();
  229. virtual NTSTATUS SendCompleted(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock);
  230. //
  231. // Packet sending
  232. //
  233. NTSTATUS ServerAnnounceWrite();
  234. VOID SendClientConfirm();
  235. VOID SendClientCapability();
  236. VOID SendDeviceReply(ULONG DeviceId, NTSTATUS Result);
  237. //
  238. // Packets received
  239. //
  240. NTSTATUS OnClientIdConfirm(PRDPDR_HEADER RdpdrHeader, ULONG cbPacket,
  241. BOOL *DoDefaultRead);
  242. NTSTATUS InitClientCapability(PRDPDR_CAPABILITY_HEADER pCapHdr, ULONG *pPacketLen, BOOL *pCapSupported);
  243. NTSTATUS OnClientCapability(PRDPDR_HEADER RdpdrHeader, ULONG cbPacket,
  244. BOOL *DoDefaultRead);
  245. NTSTATUS OnClientName(PRDPDR_HEADER RdpdrHeader, ULONG cbPacket,
  246. BOOL *DoDefaultRead);
  247. NTSTATUS OnClientDisplayName(PRDPDR_HEADER RdpdrHeader, ULONG cbPacket,
  248. BOOL *DoDefaultRead);
  249. public:
  250. #if DBG
  251. LONG _ApcCount;
  252. LONG _ApcChannelRef;
  253. #endif
  254. DrSession();
  255. virtual ~DrSession();
  256. //
  257. // Lock/Unlock connect notification.
  258. //
  259. void LockConnectStateChange() {
  260. _ConnectNotificationLock.AcquireResourceExclusive();
  261. }
  262. void UnlockConnectStateChange() {
  263. _ConnectNotificationLock.ReleaseResource();
  264. }
  265. void LockRDPDYNConnectStateChange() {
  266. _ConnectRDPDYNNotificationLock.AcquireResourceExclusive();
  267. }
  268. void UnlockRDPDYNConnectStateChange() {
  269. _ConnectRDPDYNNotificationLock.ReleaseResource();
  270. }
  271. //
  272. // Session specific refcounting as discussed above
  273. //
  274. void AddRef(void)
  275. {
  276. ULONG crefs = InterlockedIncrement(&_crefs);
  277. }
  278. void Release(void);
  279. PBYTE GetBuffer() { return _ChannelBuffer; }
  280. BOOL IsConnected() { return _SessionState == csConnected; }
  281. PWCHAR GetClientName() { return &_ClientName[0]; }
  282. PWCHAR GetClientDisplayName() {
  283. if (_ClientDisplayName[0] != L'\0') {
  284. return &_ClientDisplayName[0];
  285. }
  286. else {
  287. return &_ClientName[0];
  288. }
  289. }
  290. ULONG GetSessionId() { return _SessionId; }
  291. void SetSessionId(ULONG SessionId) { _SessionId = SessionId; }
  292. ULONG GetState() { return _SessionState; }
  293. ULONG GetClientId() { return _ClientId; }
  294. RDPDR_VERSION &GetClientVersion() { return _ClientVersion; }
  295. RDPDR_SERVER_COMBINED_CAPABILITYSET &GetClientCapabilitySet()
  296. { return _CliCapabilitySet; }
  297. BOOL AutomapDrives() { return _AutoClientDrives != 0; }
  298. BOOL AutoInstallPrinters() { return _AutoClientLpts != 0; }
  299. BOOL SetDefaultPrinter() { return _ForceClientLptDef != 0; }
  300. BOOL DisablePrinterMapping() { return _DisableCpm != 0; }
  301. BOOL DisableDriveMapping() { return _DisableCdm != 0; }
  302. BOOL DisableComPortMapping() { return _DisableCcm != 0; }
  303. BOOL DisableLptPortMapping() { return _DisableLPT != 0; }
  304. BOOL DisableClipboardMapping() { return _DisableClip != 0; }
  305. BOOL DisableExe() { return _DisableExe != 0; }
  306. BOOL DisableAudioMapping() { return _DisableCam != 0; }
  307. DrExchangeManager &GetExchangeManager() { return _ExchangeManager; }
  308. virtual BOOL RecognizePacket(PRDPDR_HEADER RdpdrHeader);
  309. virtual NTSTATUS HandlePacket(PRDPDR_HEADER RdpdrHeader, ULONG Length,
  310. BOOL *DoDefaultRead);
  311. BOOL ReadMore(ULONG cbSaveData, ULONG cbWantData = 0);
  312. BOOL Initialize();
  313. NTSTATUS RegisterPacketReceiver(ISessionPacketReceiver *PacketReceiver);
  314. VOID RemovePacketReceiver(ISessionPacketReceiver *PacketReceiver);
  315. NTSTATUS SendToClient(PVOID Buffer, ULONG Length,
  316. ISessionPacketSender *PacketSender, BOOL bWorkerItem,
  317. BOOL LowPrioSend = FALSE, PVOID AdditionalContext = NULL);
  318. NTSTATUS SendToClient(PVOID Buffer, ULONG Length,
  319. DrWriteCallback WriteCallback, BOOL bWorkerItem,
  320. BOOL LowPrioSend = FALSE, PVOID AdditionalContext = NULL);
  321. BOOL GetChannel(SmartPtr<VirtualChannel> &Channel);
  322. BOOL Connect(PCHANNEL_CONNECT_IN ConnectIn,
  323. PCHANNEL_CONNECT_OUT ConnectOut);
  324. VOID Disconnect(PCHANNEL_DISCONNECT_IN DisconnectIn,
  325. PCHANNEL_DISCONNECT_OUT DisconnectOut);
  326. BOOL FindDeviceById(ULONG DeviceId, SmartPtr<DrDevice> &DeviceFound,
  327. BOOL fMustBeValid = FALSE)
  328. {
  329. return _DeviceManager.FindDeviceById(DeviceId, DeviceFound, fMustBeValid);
  330. }
  331. BOOL FindDeviceByDosName(UCHAR* DeviceDosName, SmartPtr<DrDevice> &DeviceFound,
  332. BOOL fMustBeValid = FALSE)
  333. {
  334. return _DeviceManager.FindDeviceByDosName(DeviceDosName, DeviceFound, fMustBeValid);
  335. }
  336. DrDeviceManager &GetDevMgr() {
  337. return _DeviceManager;
  338. }
  339. #if DBG
  340. VOID DumpUserConfigSettings();
  341. #endif // DBG
  342. };