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.

247 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. bowbackp.c
  5. Abstract:
  6. This module implements all of the backup browser related routines for the
  7. NT browser
  8. Author:
  9. Larry Osterman (LarryO) 21-Jun-1990
  10. Revision History:
  11. 21-Jun-1990 LarryO
  12. Created
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #define INCLUDE_SMB_TRANSACTION
  17. typedef struct _BECOME_BACKUP_CONTEXT {
  18. WORK_QUEUE_ITEM WorkHeader;
  19. PTRANSPORT_NAME TransportName;
  20. PBECOME_BACKUP_1 BecomeBackupRequest;
  21. ULONG BytesAvailable;
  22. } BECOME_BACKUP_CONTEXT, *PBECOME_BACKUP_CONTEXT;
  23. VOID
  24. BowserBecomeBackupWorker(
  25. IN PVOID WorkItem
  26. );
  27. #ifdef ALLOC_PRAGMA
  28. #pragma alloc_text(PAGE, BowserBecomeBackupWorker)
  29. #endif
  30. DATAGRAM_HANDLER(
  31. BowserHandleBecomeBackup
  32. )
  33. /*++
  34. Routine Description:
  35. Indicate that a machine should become a backup browser server.
  36. This routine is called on receipt of a BecomeBackup frame.
  37. Arguments:
  38. IN PTRANSPORT Transport - The transport for the net we're on.
  39. IN PUCHAR MasterName - The name of the new master browser server.
  40. Return Value
  41. None.
  42. --*/
  43. {
  44. // PTA_NETBIOS_ADDRESS Address = SourceAddress;
  45. return BowserPostDatagramToWorkerThread(
  46. TransportName,
  47. Buffer,
  48. BytesAvailable,
  49. BytesTaken,
  50. SourceAddress,
  51. SourceAddressLength,
  52. SourceName,
  53. SourceNameLength,
  54. BowserBecomeBackupWorker,
  55. NonPagedPool,
  56. DelayedWorkQueue,
  57. ReceiveFlags,
  58. FALSE // No response will be sent
  59. );
  60. }
  61. VOID
  62. BowserBecomeBackupWorker(
  63. IN PVOID WorkItem
  64. )
  65. {
  66. PPOST_DATAGRAM_CONTEXT Context = WorkItem;
  67. PIRP Irp = NULL;
  68. PTRANSPORT Transport = Context->TransportName->Transport;
  69. UNICODE_STRING UPromoteeName;
  70. OEM_STRING APromoteeName;
  71. PPAGED_TRANSPORT PagedTransport = Transport->PagedTransport;
  72. PBECOME_BACKUP_1 BecomeBackupRequest = Context->Buffer;
  73. PAGED_CODE();
  74. UPromoteeName.Buffer = NULL;
  75. LOCK_TRANSPORT(Transport);
  76. try {
  77. NTSTATUS Status;
  78. //
  79. // If this packet was smaller than a minimal packet,
  80. // ignore the packet.
  81. //
  82. if (Context->BytesAvailable <= FIELD_OFFSET(BECOME_BACKUP_1, BrowserToPromote)) {
  83. try_return(NOTHING);
  84. }
  85. //
  86. // If the packet doesn't have a zero terminated BrowserToPromote,
  87. // ignore the packet.
  88. //
  89. if ( !IsZeroTerminated(
  90. BecomeBackupRequest->BrowserToPromote,
  91. Context->BytesAvailable - FIELD_OFFSET(BECOME_BACKUP_1, BrowserToPromote) ) ) {
  92. try_return(NOTHING);
  93. }
  94. RtlInitAnsiString(&APromoteeName, BecomeBackupRequest->BrowserToPromote);
  95. Status = RtlOemStringToUnicodeString(&UPromoteeName, &APromoteeName, TRUE);
  96. if (!NT_SUCCESS(Status)) {
  97. BowserLogIllegalName( Status, APromoteeName.Buffer, APromoteeName.Length );
  98. try_return(NOTHING);
  99. }
  100. if (RtlEqualUnicodeString(&UPromoteeName, &Transport->DomainInfo->DomUnicodeComputerName, TRUE)) {
  101. if (PagedTransport->Role == Master) {
  102. BowserWriteErrorLogEntry(EVENT_BOWSER_PROMOTED_WHILE_ALREADY_MASTER,
  103. STATUS_UNSUCCESSFUL,
  104. NULL,
  105. 0,
  106. 0);
  107. try_return(NOTHING);
  108. }
  109. //
  110. // Ignore become backup requests on point-to-point (RAS) links and
  111. // transports which are actually duplicates of others.
  112. //
  113. if (PagedTransport->DisabledTransport) {
  114. try_return(NOTHING);
  115. }
  116. //
  117. // Complete any the first become backup request outstanding against this
  118. // workstation.
  119. //
  120. Irp = BowserDequeueQueuedIrp(&Transport->BecomeBackupQueue);
  121. if (Irp != NULL) {
  122. Irp->IoStatus.Information = 0;
  123. BowserCompleteRequest(Irp, STATUS_SUCCESS);
  124. }
  125. }
  126. try_exit:NOTHING;
  127. } finally {
  128. UNLOCK_TRANSPORT(Transport);
  129. BowserDereferenceTransportName(Context->TransportName);
  130. BowserDereferenceTransport(Transport);
  131. if (UPromoteeName.Buffer != NULL) {
  132. RtlFreeUnicodeString(&UPromoteeName);
  133. }
  134. InterlockedDecrement( &BowserPostedDatagramCount );
  135. FREE_POOL(Context);
  136. }
  137. }
  138. VOID
  139. BowserResetStateForTransport(
  140. IN PTRANSPORT Transport,
  141. IN UCHAR NewState
  142. )
  143. {
  144. PIRP Irp = NULL;
  145. PIO_STACK_LOCATION IrpSp;
  146. NTSTATUS Status;
  147. //
  148. // Complete a reset state IRP outstanding on this transport.
  149. //
  150. Irp = BowserDequeueQueuedIrp(&Transport->ChangeRoleQueue);
  151. if (Irp != NULL) {
  152. PLMDR_REQUEST_PACKET RequestPacket = Irp->AssociatedIrp.SystemBuffer;
  153. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  154. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LMDR_REQUEST_PACKET)) {
  155. Status = STATUS_INSUFFICIENT_RESOURCES;
  156. } else {
  157. RequestPacket->Parameters.ChangeRole.RoleModification = NewState;
  158. Irp->IoStatus.Information = sizeof(LMDR_REQUEST_PACKET);
  159. Status = STATUS_SUCCESS;
  160. }
  161. BowserCompleteRequest(Irp, Status);
  162. }
  163. }
  164. DATAGRAM_HANDLER(
  165. BowserResetState
  166. )
  167. {
  168. PTRANSPORT Transport = TransportName->Transport;
  169. UCHAR NewState = (UCHAR)((PRESET_STATE_1)(Buffer))->Options;
  170. if (!BowserRefuseReset) {
  171. BowserResetStateForTransport(Transport, NewState);
  172. }
  173. return STATUS_SUCCESS;
  174. }