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.

318 lines
8.3 KiB

  1. #include "precomp.h"
  2. #include "fsdiag.h"
  3. DEBUG_FILEZONE(ZONE_T120_MCSNC);
  4. /*
  5. * userchnl.cpp
  6. *
  7. * Copyright (c) 1993 - 1995 by DataBeam Corporation, Lexington, KY
  8. *
  9. * Abstract:
  10. * This is the implementation file for the UserChannel class. It contains
  11. * the code that distinguishes this class from that of its parent, Channel.
  12. *
  13. * The main difference between this class and that of its parent is how
  14. * the join and data requests are handled. There is also a new instance
  15. * variable that keeps track of what attachment leads to the user being
  16. * represented by this class. Merge requests are also generated as is
  17. * appropriate for a user channel
  18. *
  19. * The data primitives are overridden, allowing this object to decide
  20. * not to send data upward, if it is known that the user lies in the
  21. * sub-tree of this provider.
  22. *
  23. * Private Instance Variables:
  24. * m_pUserAttachment
  25. * This is a pointer to the attachment that leads to the user being
  26. * represented by this object.
  27. *
  28. * Private Member Functions:
  29. * None.
  30. *
  31. * Caveats:
  32. * None.
  33. *
  34. * Author:
  35. * James P. Galvin, Jr.
  36. */
  37. /*
  38. * External Interfaces
  39. */
  40. #include "userchnl.h"
  41. /*
  42. * UserChannel ()
  43. *
  44. * Public
  45. *
  46. * Functional Description:
  47. * This is the primary constructor for UserChannel objects. It creates
  48. * an object with all instance variable initialized, but with no
  49. * attachments (i.e. the user is not joined to the channel automatically).
  50. *
  51. * Note that most instance variable initialization is done by invoking the
  52. * equivalent constructor in the base class.
  53. *
  54. * Upon successful completion, an attach user confirm is automtically
  55. * issued to the new user.
  56. */
  57. UserChannel::UserChannel (
  58. ChannelID channel_id,
  59. CAttachment *user_attachment,
  60. PDomain local_provider,
  61. PConnection top_provider,
  62. CChannelList2 *channel_list,
  63. CAttachmentList *attachment_list)
  64. :
  65. Channel(channel_id, local_provider, top_provider, channel_list, attachment_list),
  66. m_pUserAttachment(user_attachment)
  67. {
  68. /*
  69. * Issue an attach user confirm to the new user.
  70. */
  71. m_pUserAttachment->AttachUserConfirm(RESULT_SUCCESSFUL, channel_id);
  72. }
  73. /*
  74. * UserChannel ()
  75. *
  76. * Public
  77. *
  78. * Functional Description:
  79. * This is a secondary constructor that is only used during merge
  80. * operations. The intent of this constructor is to create an equivalent
  81. * object without issuing any of the confirms.
  82. *
  83. * Note that the additional constructor allows for the creator to specify
  84. * that the user is to be already joined to the channel upon creation.
  85. * The value of user_attachment and attachment should either be the same
  86. * or attachment should be NULL.
  87. */
  88. UserChannel::UserChannel (
  89. ChannelID channel_id,
  90. CAttachment *user_attachment,
  91. PDomain local_provider,
  92. PConnection top_provider,
  93. CChannelList2 *channel_list,
  94. CAttachmentList *attachment_list,
  95. PConnection pConn)
  96. :
  97. Channel(channel_id, local_provider, top_provider, channel_list, attachment_list, pConn),
  98. m_pUserAttachment(user_attachment)
  99. {
  100. }
  101. /*
  102. * ~UserChannel ()
  103. *
  104. * Public
  105. *
  106. * Functional Description:
  107. * This destructor does nothing more than clear the joined attachment list.
  108. * This is important because it prevents the base class destructor from
  109. * trying to issue channel leave indications to the user if the user is
  110. * locally attached.
  111. */
  112. UserChannel::~UserChannel ()
  113. {
  114. }
  115. /*
  116. * Channel_Type GetChannelType ()
  117. *
  118. * Public
  119. *
  120. * Functional Description:
  121. * Objects of this class are always user channels, so simply return
  122. * USER_CHANNEL.
  123. */
  124. Channel_Type UserChannel::GetChannelType ()
  125. {
  126. return (USER_CHANNEL);
  127. }
  128. /*
  129. * BOOL IsValid ()
  130. *
  131. * Public
  132. *
  133. * Functional Description:
  134. * User ID channels are always valid, so return TRUE.
  135. */
  136. BOOL UserChannel::IsValid ()
  137. {
  138. return (TRUE);
  139. }
  140. /*
  141. * CAttachment *GetAttachment ()
  142. *
  143. * Public
  144. *
  145. * Functional Description:
  146. * Return the pointer to the attachment leading to the user.
  147. */
  148. CAttachment *UserChannel::GetAttachment(void)
  149. {
  150. return m_pUserAttachment;
  151. }
  152. /*
  153. * Void IssueMergeRequest ()
  154. *
  155. * Public
  156. *
  157. * Functional Description:
  158. * This member function is used to cause the Channel object to issue a
  159. * merge request to the pending top provier.
  160. */
  161. Void UserChannel::IssueMergeRequest ()
  162. {
  163. ChannelAttributes channel_attributes;
  164. CChannelAttributesList merge_channel_list;
  165. CChannelIDList purge_channel_list;
  166. if (m_pConnToTopProvider != NULL)
  167. {
  168. /*
  169. * Fill in the fields of the channel attributes structure so that it
  170. * accurately describes this channel. Then put the structure into the
  171. * merge channel list.
  172. */
  173. channel_attributes.channel_type = USER_CHANNEL;
  174. if (m_JoinedAttachmentList.IsEmpty() == FALSE)
  175. channel_attributes.u.user_channel_attributes.joined = TRUE;
  176. else
  177. channel_attributes.u.user_channel_attributes.joined = FALSE;
  178. channel_attributes.u.user_channel_attributes.user_id = Channel_ID;
  179. merge_channel_list.Append(&channel_attributes);
  180. /*
  181. * Send the merge request to the indicated provider.
  182. */
  183. m_pConnToTopProvider->MergeChannelsRequest(&merge_channel_list, &purge_channel_list);
  184. }
  185. }
  186. /*
  187. * Void ChannelJoinRequest ()
  188. *
  189. * Public
  190. *
  191. * Functional Description:
  192. * This function overrides the base class implementation. The main
  193. * difference is that this implementation only allows a user to join
  194. * their own channel. No one else is allowed to join it.
  195. *
  196. * Also, since it is possible to have a user channel object with no one
  197. * joined to it, this request will be forwarded upward to the Top
  198. * Provider from here (unless this is the Top Provider).
  199. */
  200. Void UserChannel::ChannelJoinRequest (
  201. CAttachment *pOrigAtt,
  202. UserID uidInitiator,
  203. ChannelID channel_id)
  204. {
  205. /*
  206. * See if the requesting user ID is the same as that of the user this
  207. * UserChannel object represents.
  208. */
  209. if (uidInitiator == Channel_ID)
  210. {
  211. /*
  212. * See if the user is already joined to the channel.
  213. */
  214. if (m_JoinedAttachmentList.Find(pOrigAtt) == FALSE)
  215. {
  216. /*
  217. * The user is not joined to the channel. If this is the Top
  218. * Provider, then the request can be processed here.
  219. */
  220. if (IsTopProvider())
  221. {
  222. /*
  223. * Add the user to its own channel, and issue a successful
  224. * channel join confirm to the user.
  225. */
  226. TRACE_OUT (("UserChannel::ChannelJoinRequest: "
  227. "user joining own user ID channel = %04X",
  228. uidInitiator));
  229. m_JoinedAttachmentList.Append(pOrigAtt);
  230. pOrigAtt->ChannelJoinConfirm(RESULT_SUCCESSFUL, uidInitiator, channel_id, Channel_ID);
  231. }
  232. else
  233. {
  234. /*
  235. * This is not the Top Provider. Forward the join request
  236. * upward to the Top Provider.
  237. */
  238. TRACE_OUT (("UserChannel::ChannelJoinRequest: "
  239. "forwarding join request to Top Provider"));
  240. m_pConnToTopProvider->ChannelJoinRequest(uidInitiator, Channel_ID);
  241. }
  242. }
  243. else
  244. {
  245. /*
  246. * The user is already joined to their channel. Go ahead and
  247. * issue a successful channel join confirm.
  248. */
  249. WARNING_OUT (("UserChannel::ChannelJoinRequest: "
  250. "user already joined to own user channel"));
  251. pOrigAtt->ChannelJoinConfirm(RESULT_SUCCESSFUL, uidInitiator, channel_id, Channel_ID);
  252. }
  253. }
  254. else
  255. {
  256. /*
  257. * Someone is trying to join someone elses channel. This is not
  258. * valid. Reject the request without further processing.
  259. */
  260. WARNING_OUT (("UserChannel::ChannelJoinRequest: "
  261. "rejecting attempt to join someone elses user channel"));
  262. pOrigAtt->ChannelJoinConfirm(RESULT_OTHER_USER_ID, uidInitiator, channel_id, 0);
  263. }
  264. }
  265. /*
  266. * Void SendDataRequest ()
  267. *
  268. * Public
  269. *
  270. * Functional Description:
  271. * This function is used to send data through the channel. Note that data
  272. * is NEVER sent upward, since the user (who is the only one who can be
  273. * joined to this channel) is in the sub-tree of this provider. This helps
  274. * to optimize network traffic.
  275. */
  276. Void UserChannel::SendDataRequest (
  277. CAttachment *pOrigAtt,
  278. UINT type,
  279. PDataPacket data_packet)
  280. {
  281. CAttachment *pAtt;
  282. ASSERT (Channel_ID == data_packet->GetChannelID());
  283. /*
  284. * Iterate through the attachment list, sending the data to all
  285. * the attachments (except for one from whence the data came).
  286. */
  287. m_JoinedAttachmentList.Reset();
  288. while (NULL != (pAtt = m_JoinedAttachmentList.Iterate()))
  289. {
  290. if (pAtt != pOrigAtt)
  291. {
  292. pAtt->SendDataIndication(type, data_packet);
  293. }
  294. }
  295. }