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.

325 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. brdmmstr.c
  5. Abstract:
  6. This module contains the routines to manage a domain master browser server
  7. Author:
  8. Rita Wong (ritaw) 20-Feb-1991
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //-------------------------------------------------------------------//
  14. // //
  15. // Local structure definitions //
  16. // //
  17. //-------------------------------------------------------------------//
  18. //-------------------------------------------------------------------//
  19. // //
  20. // Local function prototypes //
  21. // //
  22. //-------------------------------------------------------------------//
  23. VOID
  24. GetMasterAnnouncementCompletion (
  25. IN PVOID Ctx
  26. );
  27. typedef struct _BROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT {
  28. PDOMAIN_INFO DomainInfo;
  29. HANDLE EventHandle;
  30. NET_API_STATUS NetStatus;
  31. } BROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT, *PBROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT;
  32. NET_API_STATUS
  33. PostGetMasterAnnouncement (
  34. PNETWORK Network
  35. )
  36. /*++
  37. Routine Description:
  38. Ensure the GetMasterAnnouncement request is posted for a particular network.
  39. Arguments:
  40. None.
  41. Return Value:
  42. Status - The status of the operation.
  43. --*/
  44. {
  45. NET_API_STATUS NetStatus = NERR_Success;
  46. #ifdef ENABLE_PSEUDO_BROWSER
  47. if ( BrInfo.PseudoServerLevel == BROWSER_PSEUDO ) {
  48. // No master announcement handling for a phase out server
  49. return NERR_Success;
  50. }
  51. #endif
  52. if (!LOCK_NETWORK(Network)) {
  53. return NERR_InternalError;
  54. }
  55. if ( (Network->Flags & NETWORK_PDC) != 0 &&
  56. (Network->Flags & NETWORK_WANNISH) != 0 ) {
  57. if (!(Network->Flags & NETWORK_GET_MASTER_ANNOUNCE_POSTED)) {
  58. BrPrint(( BR_MASTER,
  59. "%ws: %ws: Doing PostGetMasterAnnouncement\n",
  60. Network->DomainInfo->DomUnicodeDomainName,
  61. Network->NetworkName.Buffer));
  62. NetStatus = BrIssueAsyncBrowserIoControl(Network,
  63. IOCTL_LMDR_WAIT_FOR_MASTER_ANNOUNCE,
  64. GetMasterAnnouncementCompletion,
  65. NULL
  66. );
  67. if ( NetStatus == NERR_Success ) {
  68. Network->Flags |= NETWORK_GET_MASTER_ANNOUNCE_POSTED;
  69. }
  70. } else {
  71. BrPrint(( BR_MASTER,
  72. "%ws: %ws: PostGetMasterAnnouncement already posted.\n",
  73. Network->DomainInfo->DomUnicodeDomainName,
  74. Network->NetworkName.Buffer));
  75. }
  76. }
  77. UNLOCK_NETWORK(Network);
  78. return NetStatus;
  79. }
  80. VOID
  81. GetMasterAnnouncementCompletion (
  82. IN PVOID Ctx
  83. )
  84. /*++
  85. Routine Description:
  86. This function is the completion routine for a master announcement. It is
  87. called whenever a master announcement is received for a particular network.
  88. Arguments:
  89. Ctx - Context block for request.
  90. Return Value:
  91. None.
  92. --*/
  93. {
  94. PVOID ServerList = NULL;
  95. ULONG EntriesRead;
  96. ULONG TotalEntries;
  97. NET_API_STATUS Status = NERR_Success;
  98. PBROWSERASYNCCONTEXT Context = Ctx;
  99. PLMDR_REQUEST_PACKET MasterAnnouncement = Context->RequestPacket;
  100. PNETWORK Network = Context->Network;
  101. LPTSTR RemoteMasterName = NULL;
  102. BOOLEAN NetLocked = FALSE;
  103. BOOLEAN NetReferenced = FALSE;
  104. try {
  105. //
  106. // Ensure the network wasn't deleted from under us.
  107. //
  108. if ( BrReferenceNetwork( Network ) == NULL ) {
  109. try_return(NOTHING);
  110. }
  111. NetReferenced = TRUE;
  112. if (!LOCK_NETWORK(Network)){
  113. try_return(NOTHING);
  114. }
  115. NetLocked = TRUE;
  116. Network->Flags &= ~NETWORK_GET_MASTER_ANNOUNCE_POSTED;
  117. //
  118. // The request failed for some reason - just return immediately.
  119. //
  120. if (!NT_SUCCESS(Context->IoStatusBlock.Status)) {
  121. try_return(NOTHING);
  122. }
  123. Status = PostGetMasterAnnouncement(Network);
  124. if (Status != NERR_Success) {
  125. BrPrint(( BR_CRITICAL,
  126. "%ws: %ws: Unable to re-issue GetMasterAnnouncement request: %lx\n",
  127. Network->DomainInfo->DomUnicodeDomainName,
  128. Network->NetworkName.Buffer,
  129. Status));
  130. try_return(NOTHING);
  131. }
  132. RemoteMasterName = MIDL_user_allocate(MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength+3*sizeof(TCHAR));
  133. if (RemoteMasterName == NULL) {
  134. try_return(NOTHING);
  135. }
  136. RemoteMasterName[0] = TEXT('\\');
  137. RemoteMasterName[1] = TEXT('\\');
  138. STRNCPY(&RemoteMasterName[2],
  139. MasterAnnouncement->Parameters.WaitForMasterAnnouncement.Name,
  140. MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength/sizeof(TCHAR));
  141. RemoteMasterName[(MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength/sizeof(TCHAR))+2] = UNICODE_NULL;
  142. BrPrint(( BR_MASTER,
  143. "%ws: %ws: GetMasterAnnouncement: Got a master browser announcement from %ws\n",
  144. Network->DomainInfo->DomUnicodeDomainName,
  145. Network->NetworkName.Buffer,
  146. RemoteMasterName));
  147. UNLOCK_NETWORK(Network);
  148. NetLocked = FALSE;
  149. //
  150. // Remote the api and pull the browse list from the remote server.
  151. //
  152. Status = RxNetServerEnum(RemoteMasterName,
  153. Network->NetworkName.Buffer,
  154. 101,
  155. (LPBYTE *)&ServerList,
  156. 0xffffffff,
  157. &EntriesRead,
  158. &TotalEntries,
  159. SV_TYPE_LOCAL_LIST_ONLY,
  160. NULL,
  161. NULL
  162. );
  163. if ((Status == NERR_Success) || (Status == ERROR_MORE_DATA)) {
  164. if (!LOCK_NETWORK(Network)) {
  165. try_return(NOTHING);
  166. }
  167. NetLocked = TRUE;
  168. Status = MergeServerList(&Network->BrowseTable,
  169. 101,
  170. ServerList,
  171. EntriesRead,
  172. TotalEntries
  173. );
  174. UNLOCK_NETWORK(Network);
  175. NetLocked = FALSE;
  176. (void) NetApiBufferFree( ServerList );
  177. ServerList = NULL;
  178. } else {
  179. BrPrint(( BR_MASTER,
  180. "%ws: %ws: GetMasterAnnouncement: Cannot get server list from %ws (%ld)\n",
  181. Network->DomainInfo->DomUnicodeDomainName,
  182. Network->NetworkName.Buffer,
  183. RemoteMasterName,
  184. Status ));
  185. }
  186. //
  187. // Remote the api and pull the browse list from the remote server.
  188. //
  189. Status = RxNetServerEnum(RemoteMasterName,
  190. Network->NetworkName.Buffer,
  191. 101,
  192. (LPBYTE *)&ServerList,
  193. 0xffffffff,
  194. &EntriesRead,
  195. &TotalEntries,
  196. SV_TYPE_LOCAL_LIST_ONLY | SV_TYPE_DOMAIN_ENUM,
  197. NULL,
  198. NULL
  199. );
  200. if ((Status == NERR_Success) || (Status == ERROR_MORE_DATA)) {
  201. if (!LOCK_NETWORK(Network)) {
  202. try_return(NOTHING);
  203. }
  204. NetLocked = TRUE;
  205. Status = MergeServerList(&Network->DomainList,
  206. 101,
  207. ServerList,
  208. EntriesRead,
  209. TotalEntries
  210. );
  211. } else {
  212. BrPrint(( BR_MASTER,
  213. "%ws: %ws: GetMasterAnnouncement: Cannot get domain list from %ws (%ld)\n",
  214. Network->DomainInfo->DomUnicodeDomainName,
  215. Network->NetworkName.Buffer,
  216. RemoteMasterName,
  217. Status ));
  218. }
  219. try_exit:NOTHING;
  220. } finally {
  221. if (NetLocked) {
  222. UNLOCK_NETWORK(Network);
  223. }
  224. if ( NetReferenced ) {
  225. BrDereferenceNetwork( Network );
  226. }
  227. if (RemoteMasterName != NULL) {
  228. MIDL_user_free(RemoteMasterName);
  229. }
  230. MIDL_user_free(Context);
  231. if ( ServerList != NULL ) {
  232. (void) NetApiBufferFree( ServerList );
  233. }
  234. }
  235. return;
  236. }