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.

263 lines
8.3 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. name.c
  5. Abstract:
  6. Local Address
  7. Author:
  8. Jiandong Ruan
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #include "name.tmh"
  13. //#pragma alloc_text(PAGE, SmbCreateClient)
  14. //#pragma alloc_text(PAGE, SmbCloseClient)
  15. #define TA_ADDRESS_HEADER_SIZE (FIELD_OFFSET(TA_ADDRESS,Address))
  16. VOID
  17. SmbDeleteClient(PSMB_CLIENT_ELEMENT ob)
  18. {
  19. KIRQL Irql;
  20. SMB_ACQUIRE_SPINLOCK(ob->Device, Irql);
  21. ASSERT(EntryIsInList(&ob->Device->PendingDeleteClientList, &ob->Linkage));
  22. RemoveEntryList(&ob->Linkage);
  23. SMB_RELEASE_SPINLOCK(ob->Device, Irql);
  24. ExFreePool(ob);
  25. SmbPrint(SMB_TRACE_CALL, ("SmbDeleteClient: free Client %p\n", ob));
  26. }
  27. NTSTATUS
  28. SmbCreateClient(
  29. IN PSMB_DEVICE Device,
  30. IN PIRP Irp,
  31. PFILE_FULL_EA_INFORMATION ea
  32. )
  33. {
  34. TRANSPORT_ADDRESS UNALIGNED *pTransportAddr;
  35. PTA_ADDRESS pAddress;
  36. PTDI_ADDRESS_NETBIOS pNetbiosAddr;
  37. PTDI_ADDRESS_NETBIOS_EX pNetbiosAddrEx;
  38. PTDI_ADDRESS_NETBIOS_UNICODE_EX pUnicodeEx;
  39. PSMB_CLIENT_ELEMENT ClientObject;
  40. PIO_STACK_LOCATION IrpSp;
  41. UNICODE_STRING ucName;
  42. int i;
  43. DWORD RemainingBufferLength;
  44. CHAR Name[NETBIOS_NAME_SIZE + 1];
  45. USHORT NameType;
  46. OEM_STRING OemString;
  47. KIRQL Irql;
  48. PAGED_CODE();
  49. SmbPrint(SMB_TRACE_CALL, ("Enter SmbCreateClient\n"));
  50. pTransportAddr = (PTRANSPORT_ADDRESS)(((PUCHAR)ea->EaName) + ea->EaNameLength + 1);
  51. RemainingBufferLength = ea->EaValueLength;
  52. if (RemainingBufferLength < sizeof(TA_NETBIOS_ADDRESS)) {
  53. return STATUS_INVALID_ADDRESS_COMPONENT;
  54. }
  55. RemainingBufferLength -= sizeof(pTransportAddr->TAAddressCount);
  56. pAddress = (PTA_ADDRESS)pTransportAddr->Address;
  57. for (i = 0; i < pTransportAddr->TAAddressCount; i++) {
  58. //
  59. // First, make sure we can safely access pAddress->AddressLength
  60. //
  61. if (RemainingBufferLength < TA_ADDRESS_HEADER_SIZE) {
  62. return STATUS_INVALID_ADDRESS_COMPONENT;
  63. }
  64. RemainingBufferLength -= TA_ADDRESS_HEADER_SIZE;
  65. if (RemainingBufferLength < pAddress->AddressLength) {
  66. return STATUS_INVALID_ADDRESS_COMPONENT;
  67. }
  68. if (TDI_ADDRESS_TYPE_NETBIOS == pAddress->AddressType) {
  69. if (pAddress->AddressLength < sizeof(TDI_ADDRESS_NETBIOS)) {
  70. return STATUS_INVALID_ADDRESS_COMPONENT;
  71. }
  72. pNetbiosAddr = (PTDI_ADDRESS_NETBIOS)pAddress->Address;
  73. RtlCopyMemory(Name, pNetbiosAddr->NetbiosName, NETBIOS_NAME_SIZE);
  74. NameType = pNetbiosAddr->NetbiosNameType;
  75. break;
  76. } else if (TDI_ADDRESS_TYPE_NETBIOS_EX == pAddress->AddressType) {
  77. if (pAddress->AddressLength < sizeof(TDI_ADDRESS_NETBIOS_EX)) {
  78. return STATUS_INVALID_ADDRESS_COMPONENT;
  79. }
  80. pNetbiosAddrEx = (PTDI_ADDRESS_NETBIOS_EX)pAddress->Address;
  81. RtlCopyMemory(Name, pNetbiosAddrEx->EndpointName, NETBIOS_NAME_SIZE);
  82. NameType = TDI_ADDRESS_NETBIOS_TYPE_QUICK_UNIQUE;
  83. break;
  84. } else if (TDI_ADDRESS_TYPE_NETBIOS_UNICODE_EX == pAddress->AddressType) {
  85. if (pAddress->AddressLength < sizeof(TDI_ADDRESS_NETBIOS_UNICODE_EX)) {
  86. return STATUS_INVALID_ADDRESS_COMPONENT;
  87. }
  88. pUnicodeEx = (PTDI_ADDRESS_NETBIOS_UNICODE_EX)pAddress->Address;
  89. OemString.Buffer = Name;
  90. OemString.Length = 0;
  91. OemString.MaximumLength = sizeof(Name);
  92. ucName = pUnicodeEx->EndpointName;
  93. RtlUpcaseUnicodeStringToOemString(&OemString, &ucName, FALSE);
  94. NameType = TDI_ADDRESS_NETBIOS_TYPE_QUICK_UNIQUE;
  95. break;
  96. }
  97. RemainingBufferLength -= pAddress->AddressLength;
  98. pAddress = (PTA_ADDRESS)(((PUCHAR)pAddress) + pAddress->AddressLength + TA_ADDRESS_HEADER_SIZE);
  99. }
  100. if (i >= pTransportAddr->TAAddressCount) {
  101. return STATUS_INVALID_ADDRESS_COMPONENT;
  102. }
  103. //
  104. // We have the name and name type
  105. //
  106. Name[NETBIOS_NAME_SIZE] = 0;
  107. ClientObject = ExAllocatePoolWithTag(NonPagedPool, sizeof(ClientObject[0]), CLIENT_OBJECT_POOL_TAG);
  108. if (NULL == ClientObject) {
  109. return STATUS_NO_MEMORY;
  110. }
  111. SmbInitializeObject((PSMB_OBJECT)ClientObject, TAG_CLIENT_OBJECT, (PSMB_OBJECT_CLEANUP)SmbDeleteClient);
  112. ClientObject->Device = Device;
  113. RtlCopyMemory(ClientObject->EndpointName, Name, NETBIOS_NAME_SIZE);
  114. KeInitializeSpinLock(&ClientObject->Lock);
  115. InitializeListHead(&ClientObject->ListenHead);
  116. InitializeListHead(&ClientObject->AssociatedConnection);
  117. InitializeListHead(&ClientObject->ActiveConnection);
  118. InitializeListHead(&ClientObject->PendingAcceptConnection);
  119. ClientObject->PendingAcceptNumber = 0;
  120. ClientObject->evConnect = NULL;
  121. ClientObject->ConEvContext = NULL;
  122. ClientObject->evDisconnect = NULL;
  123. ClientObject->DiscEvContext = NULL;
  124. ClientObject->evError = NULL;
  125. ClientObject->ErrorEvContext = NULL;
  126. ClientObject->evReceive = NULL;
  127. ClientObject->RcvEvContext = NULL;
  128. SMB_ACQUIRE_SPINLOCK(Device, Irql);
  129. if (RtlEqualMemory(Device->EndpointName, ClientObject->EndpointName, NETBIOS_NAME_SIZE)) {
  130. if (Device->SmbServer) {
  131. ExFreePool(ClientObject);
  132. SMB_RELEASE_SPINLOCK(Device, Irql);
  133. SmbPrint(SMB_TRACE_CALL, ("SmbCreateClient: Duplicate server\n"));
  134. return STATUS_ACCESS_DENIED;
  135. }
  136. SmbPrint(SMB_TRACE_CALL, ("SmbCreateClient: Server comes in\n"));
  137. Device->SmbServer = ClientObject;
  138. }
  139. InsertTailList(&Device->ClientList, &ClientObject->Linkage);
  140. SMB_RELEASE_SPINLOCK(Device, Irql);
  141. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  142. IrpSp->FileObject->FsContext = ClientObject;
  143. IrpSp->FileObject->FsContext2 = UlongToPtr(SMB_TDI_CLIENT);
  144. SmbPrint(SMB_TRACE_CALL, ("SmbCreateClient: new Client %p\n", ClientObject));
  145. return STATUS_SUCCESS;
  146. }
  147. NTSTATUS
  148. SmbCloseClient(
  149. IN PSMB_DEVICE Device,
  150. IN PIRP Irp
  151. )
  152. {
  153. PIO_STACK_LOCATION IrpSp;
  154. KIRQL Irql;
  155. PSMB_CLIENT_ELEMENT ClientObject;
  156. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  157. if (IrpSp->FileObject->FsContext2 != UlongToPtr(SMB_TDI_CLIENT)) {
  158. ASSERT(0);
  159. return STATUS_INVALID_PARAMETER;
  160. }
  161. SMB_ACQUIRE_SPINLOCK(&SmbCfg, Irql);
  162. IrpSp->FileObject->FsContext2 = UlongToPtr(SMB_TDI_INVALID);
  163. SMB_RELEASE_SPINLOCK(&SmbCfg, Irql);
  164. if (NULL == IrpSp->FileObject->FsContext) {
  165. ASSERT(0);
  166. return STATUS_INVALID_PARAMETER;
  167. }
  168. ClientObject = (PSMB_CLIENT_ELEMENT)IrpSp->FileObject->FsContext;
  169. SMB_ACQUIRE_SPINLOCK(Device, Irql);
  170. ASSERT(EntryIsInList(&Device->ClientList, &ClientObject->Linkage));
  171. if (RtlEqualMemory(Device->EndpointName, ClientObject->EndpointName, NETBIOS_NAME_SIZE)) {
  172. ASSERT(Device->SmbServer);
  173. Device->SmbServer = NULL;
  174. SmbPrint(SMB_TRACE_CALL, ("SmbCloseClient: Server leaves\n"));
  175. }
  176. RemoveEntryList(&ClientObject->Linkage);
  177. InsertTailList(&Device->PendingDeleteClientList, &ClientObject->Linkage);
  178. SMB_RELEASE_SPINLOCK(Device, Irql);
  179. SmbDereferenceClient(ClientObject, SMB_REF_CREATE);
  180. IrpSp->FileObject->FsContext = NULL;
  181. SmbPrint(SMB_TRACE_CALL, ("SmbCloseClient: close Client %p\n", ClientObject));
  182. return STATUS_SUCCESS;
  183. }
  184. PSMB_CLIENT_ELEMENT
  185. SmbVerifyAndReferenceClient(
  186. PFILE_OBJECT FileObject,
  187. SMB_REF_CONTEXT ctx
  188. )
  189. {
  190. PSMB_CLIENT_ELEMENT ClientObject;
  191. KIRQL Irql;
  192. SMB_ACQUIRE_SPINLOCK(&SmbCfg, Irql);
  193. if (FileObject->FsContext2 != UlongToPtr(SMB_TDI_CLIENT)) {
  194. ClientObject = NULL;
  195. } else {
  196. ClientObject = (PSMB_CLIENT_ELEMENT)FileObject->FsContext;
  197. SmbReferenceClient(ClientObject, ctx);
  198. }
  199. SMB_RELEASE_SPINLOCK(&SmbCfg, Irql);
  200. return ClientObject;
  201. }