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.

784 lines
24 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. ioctl.c
  5. Abstract:
  6. I/O Control of SMB6 device
  7. Author:
  8. Jiandong Ruan
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #include "nb30.h"
  13. #include "ioctl.tmh"
  14. #pragma alloc_text(PAGE, SmbCreateControl)
  15. NTSTATUS
  16. SmbCreateControl(
  17. PSMB_DEVICE Device,
  18. PIRP Irp
  19. )
  20. {
  21. PIO_STACK_LOCATION IrpSp;
  22. PAGED_CODE();
  23. SmbPrint(SMB_TRACE_CALL, ("Enter SmbCreateControl\n"));
  24. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  25. IrpSp->FileObject->FsContext = NULL;
  26. IrpSp->FileObject->FsContext2 = UlongToPtr(SMB_TDI_CONTROL);
  27. return STATUS_SUCCESS;
  28. }
  29. NTSTATUS
  30. SmbCloseControl(
  31. PSMB_DEVICE Device,
  32. PIRP Irp
  33. )
  34. #pragma alloc_text(PAGE, SmbCloseControl)
  35. {
  36. PIO_STACK_LOCATION IrpSp;
  37. PAGED_CODE();
  38. SmbPrint(SMB_TRACE_CALL, ("Enter SmbCloseControl\n"));
  39. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  40. ASSERT (IrpSp->FileObject->FsContext2 == UlongToPtr(SMB_TDI_CONTROL));
  41. return STATUS_SUCCESS;
  42. }
  43. NTSTATUS
  44. SmbQueryProviderCompletion(
  45. IN PDEVICE_OBJECT DeviceObject,
  46. IN PIRP Irp,
  47. IN PVOID Context
  48. )
  49. /*++
  50. Routine Description:
  51. This routine handles the completion event when the Query Provider
  52. Information completes. This routine must decrement the MaxDgramSize
  53. and max send size by the respective NBT header sizes.
  54. Arguments:
  55. Return Value:
  56. The final status from the operation (success or an exception).
  57. --*/
  58. {
  59. PTDI_PROVIDER_INFO Provider;
  60. if (!NT_SUCCESS(Irp->IoStatus.Status)) {
  61. ASSERT(0);
  62. return STATUS_SUCCESS;
  63. }
  64. Provider = (PTDI_PROVIDER_INFO)MmGetMdlVirtualAddress(Irp->MdlAddress);
  65. Provider->ServiceFlags = TDI_SERVICE_MESSAGE_MODE |
  66. TDI_SERVICE_CONNECTION_MODE |
  67. TDI_SERVICE_CONNECTIONLESS_MODE |
  68. TDI_SERVICE_ERROR_FREE_DELIVERY |
  69. TDI_SERVICE_BROADCAST_SUPPORTED |
  70. TDI_SERVICE_MULTICAST_SUPPORTED |
  71. TDI_SERVICE_DELAYED_ACCEPTANCE |
  72. TDI_SERVICE_ROUTE_DIRECTED |
  73. TDI_SERVICE_FORCE_ACCESS_CHECK;
  74. Provider->MinimumLookaheadData = 128;
  75. //
  76. // Adjust maximum session packet size
  77. //
  78. if (Provider->MaxSendSize > SMB_SESSION_HEADER_SIZE) {
  79. if (Provider->MaxSendSize > (0x1ffff + SMB_SESSION_HEADER_SIZE)) {
  80. Provider->MaxSendSize = 0x1ffff;
  81. } else {
  82. Provider->MaxSendSize -= SMB_SESSION_HEADER_SIZE;
  83. }
  84. } else {
  85. Provider->MaxSendSize = 0;
  86. }
  87. //
  88. // SMB device doesn't support datagram
  89. //
  90. Provider->MaxDatagramSize = 0;
  91. SmbPrint(SMB_TRACE_CALL, ("SmbQueryProviderCompletion: Complete IRP %p\n", Irp));
  92. return STATUS_SUCCESS;
  93. }
  94. NTSTATUS
  95. SmbQueryTcpProviderInfo(
  96. PFILE_OBJECT ControlFileObject,
  97. PIRP Irp,
  98. PTDI_PROVIDER_INFO TcpProvider
  99. )
  100. {
  101. PMDL Mdl, SavedMdl;
  102. NTSTATUS status;
  103. TcpProvider->MaxSendSize = SMB_MAX_SESSION_PACKET;
  104. if (NULL == ControlFileObject) {
  105. return STATUS_INVALID_PARAMETER;
  106. }
  107. Mdl = IoAllocateMdl(TcpProvider, sizeof(TDI_PROVIDER_INFO), FALSE, FALSE, NULL);
  108. if (NULL == Mdl) {
  109. return STATUS_INSUFFICIENT_RESOURCES;
  110. }
  111. MmBuildMdlForNonPagedPool(Mdl);
  112. SavedMdl = Irp->MdlAddress;
  113. TdiBuildQueryInformation(
  114. Irp,
  115. IoGetRelatedDeviceObject(ControlFileObject),
  116. ControlFileObject,
  117. NULL,
  118. NULL,
  119. TDI_QUERY_PROVIDER_INFO,
  120. Mdl
  121. );
  122. status = SubmitSynchTdiRequest (ControlFileObject, Irp);
  123. Irp->MdlAddress = SavedMdl;
  124. if (status == STATUS_SUCCESS) {
  125. if (TcpProvider->MaxSendSize > SMB_SESSION_HEADER_SIZE) {
  126. if (TcpProvider->MaxSendSize > (0x1ffff + SMB_SESSION_HEADER_SIZE)) {
  127. TcpProvider->MaxSendSize = 0x1ffff;
  128. } else {
  129. TcpProvider->MaxSendSize -= SMB_SESSION_HEADER_SIZE;
  130. }
  131. } else {
  132. TcpProvider->MaxSendSize = 0;
  133. }
  134. SmbPrint(SMB_TRACE_TCP, ("SmbQueryTcpProviderInfo returns MaxSendSize = %d bytes\n",
  135. TcpProvider->MaxSendSize));
  136. SmbTrace(SMB_TRACE_TCP, ("returns MaxSendSize = %d bytes", TcpProvider->MaxSendSize));
  137. } else {
  138. SmbPrint(SMB_TRACE_TCP, ("SmbQueryTcpProviderInfo returns status = 0x%08lx\n", status));
  139. SmbTrace(SMB_TRACE_TCP, ("returns %!status!", status));
  140. }
  141. IoFreeMdl(Mdl);
  142. return status;
  143. }
  144. NTSTATUS
  145. SmbQueryProviderInfo(
  146. PSMB_DEVICE Device,
  147. PIRP Irp
  148. )
  149. {
  150. NTSTATUS status = STATUS_SUCCESS;
  151. PTDI_PROVIDER_INFO TcpProvider = NULL, Provider = NULL;
  152. DWORD BytesCopied = 0;
  153. if (NULL == Irp->MdlAddress) {
  154. status = STATUS_INVALID_PARAMETER;
  155. goto cleanup;
  156. }
  157. TcpProvider = (PTDI_PROVIDER_INFO)ExAllocatePoolWithTag(
  158. NonPagedPool, sizeof(TDI_PROVIDER_INFO), '6BMS');
  159. Provider = (PTDI_PROVIDER_INFO)ExAllocatePoolWithTag(
  160. NonPagedPool, sizeof(TDI_PROVIDER_INFO), '6BMS');
  161. if (NULL == TcpProvider || NULL == Provider) {
  162. status = STATUS_INSUFFICIENT_RESOURCES;
  163. goto cleanup;
  164. }
  165. status = STATUS_UNSUCCESSFUL;
  166. RtlZeroMemory(Provider, sizeof(TDI_PROVIDER_INFO));
  167. //
  168. // Set SMB-specific information
  169. //
  170. Provider->Version = 0x0200;
  171. Provider->MaxSendSize = SMB_MAX_SESSION_PACKET;
  172. Provider->MaxConnectionUserData = 0;
  173. Provider->MaxDatagramSize = 0;
  174. Provider->ServiceFlags = TDI_SERVICE_MESSAGE_MODE |
  175. TDI_SERVICE_CONNECTION_MODE |
  176. TDI_SERVICE_CONNECTIONLESS_MODE |
  177. TDI_SERVICE_ERROR_FREE_DELIVERY |
  178. TDI_SERVICE_BROADCAST_SUPPORTED |
  179. TDI_SERVICE_MULTICAST_SUPPORTED |
  180. TDI_SERVICE_DELAYED_ACCEPTANCE |
  181. TDI_SERVICE_ROUTE_DIRECTED |
  182. TDI_SERVICE_FORCE_ACCESS_CHECK;
  183. Provider->MinimumLookaheadData = 128;
  184. Provider->MaximumLookaheadData = SMB_MAX_SESSION_PACKET;
  185. //
  186. // Query TCP4 info
  187. //
  188. if (SmbCfg.Tcp4Available) {
  189. status = SmbQueryTcpProviderInfo(Device->Tcp4.TCPControlFileObject, Irp, TcpProvider);
  190. if (status == STATUS_SUCCESS) {
  191. if (Provider->MaxSendSize > TcpProvider->MaxSendSize) {
  192. Provider->MaxSendSize = TcpProvider->MaxSendSize;
  193. }
  194. }
  195. }
  196. //
  197. // Query TCP6 info
  198. //
  199. if (SmbCfg.Tcp6Available) {
  200. status = SmbQueryTcpProviderInfo(Device->Tcp6.TCPControlFileObject, Irp, TcpProvider);
  201. if (status == STATUS_SUCCESS) {
  202. if (Provider->MaxSendSize > TcpProvider->MaxSendSize) {
  203. Provider->MaxSendSize = TcpProvider->MaxSendSize;
  204. }
  205. }
  206. }
  207. BytesCopied = 0;
  208. status = TdiCopyBufferToMdl (Provider, 0, sizeof(TDI_PROVIDER_INFO),
  209. Irp->MdlAddress, 0, &BytesCopied);
  210. cleanup:
  211. if (NULL != TcpProvider) {
  212. ExFreePool(TcpProvider);
  213. TcpProvider = NULL;
  214. }
  215. if (NULL != Provider) {
  216. ExFreePool(Provider);
  217. Provider = NULL;
  218. }
  219. Irp->IoStatus.Status = status;
  220. Irp->IoStatus.Information = (status != STATUS_SUCCESS)? 0: BytesCopied;
  221. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  222. return status;
  223. }
  224. NTSTATUS
  225. SmbQueryAdapterStatus(
  226. PSMB_DEVICE Device,
  227. PIRP Irp
  228. )
  229. /*++
  230. Routine Description:
  231. Return the local adapter status
  232. Arguments:
  233. Return Value:
  234. NTSTATUS.
  235. Note: this routine should complete the IRP because
  236. the caller doesn't complete it.
  237. Smb device is netbiosless. We don't need to return
  238. name cache as we do in legacy NetBT devices.
  239. --*/
  240. {
  241. NTSTATUS status = STATUS_SUCCESS;
  242. DWORD Size = 0, BytesCopied = 0;
  243. ADAPTER_STATUS as = { 0 };
  244. if (NULL == Irp->MdlAddress) {
  245. status = STATUS_INVALID_PARAMETER;
  246. goto cleanup;
  247. }
  248. Size = MmGetMdlByteCount (Irp->MdlAddress);
  249. if (Size < sizeof(ADAPTER_STATUS)) {
  250. status = STATUS_BUFFER_TOO_SMALL;
  251. goto cleanup;
  252. }
  253. RtlZeroMemory(&as, sizeof(ADAPTER_STATUS));
  254. as.rev_major = 0x03;
  255. as.adapter_type = 0xFE; // pretend it is an ethernet adapter
  256. as.name_count = 0; // Smb device won't return the name cache
  257. as.max_cfg_sess = (USHORT)0xffff;
  258. as.max_sess = (USHORT)0xffff;
  259. as.free_ncbs = (USHORT)0xffff;
  260. as.max_cfg_ncbs = (USHORT)0xffff;
  261. as.max_ncbs = (USHORT)0xffff;
  262. as.max_dgram_size = 0; // Smb device doesn't support datagram
  263. as.max_sess_pkt_size = 0xffff;
  264. BytesCopied = 0;
  265. status = TdiCopyBufferToMdl (&as, 0, sizeof(ADAPTER_STATUS),
  266. Irp->MdlAddress, 0, &BytesCopied);
  267. cleanup:
  268. Irp->IoStatus.Status = status;
  269. Irp->IoStatus.Information = (status != STATUS_SUCCESS)? 0: BytesCopied;
  270. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  271. return status;
  272. }
  273. NTSTATUS
  274. SmbQueryPeerInfo(
  275. PSMB_CONNECT ConnectObject,
  276. PNBT_ADDRESS_PAIR_INFO AddressPair,
  277. DWORD Size,
  278. DWORD *BytesCopied
  279. )
  280. {
  281. KIRQL Irql = 0;
  282. NBT_ADDRESS_PAIR_INFO ap = { 0 };
  283. DWORD RequiredSize = 0;
  284. *BytesCopied = 0;
  285. RtlZeroMemory(&ap, sizeof(ap));
  286. ap.ActivityCount = 1;
  287. ap.AddressPair.TAAddressCount = 2;
  288. SMB_ACQUIRE_SPINLOCK(ConnectObject, Irql);
  289. if (NULL == ConnectObject->TcpContext) {
  290. SMB_RELEASE_SPINLOCK(ConnectObject, Irql);
  291. return STATUS_CONNECTION_DISCONNECTED;
  292. }
  293. //
  294. // Fill IP address
  295. //
  296. if (SMB_AF_INET == ConnectObject->RemoteIpAddress.sin_family) {
  297. ap.AddressPair.AddressIP.AddressLength = TDI_ADDRESS_LENGTH_IP;
  298. ap.AddressPair.AddressIP.AddressType = TDI_ADDRESS_TYPE_IP;
  299. ap.AddressPair.AddressIP.Address.in_addr = ConnectObject->RemoteIpAddress.ip4.sin4_addr;
  300. RequiredSize = sizeof(ap) +
  301. sizeof(ap.AddressPair.AddressIP.Address) -
  302. sizeof(ap.AddressPair.AddressIP.AddressIp6);
  303. } else {
  304. ap.AddressPair.AddressIP.AddressLength = TDI_ADDRESS_LENGTH_IP6;
  305. ap.AddressPair.AddressIP.AddressType = TDI_ADDRESS_TYPE_IP6;
  306. RtlCopyMemory(
  307. ap.AddressPair.AddressIP.AddressIp6.sin6_addr,
  308. ConnectObject->RemoteIpAddress.ip6.sin6_addr,
  309. sizeof(ap.AddressPair.AddressIP.AddressIp6.sin6_addr)
  310. );
  311. ap.AddressPair.AddressIP.AddressIp6.sin6_scope_id = ConnectObject->RemoteIpAddress.ip6.sin6_scope_id;
  312. RequiredSize = sizeof(ap);
  313. }
  314. //
  315. // Fill Netbios address
  316. //
  317. ap.AddressPair.AddressNetBIOS.AddressType = TDI_ADDRESS_TYPE_NETBIOS;
  318. ap.AddressPair.AddressNetBIOS.AddressLength = TDI_ADDRESS_LENGTH_NETBIOS;
  319. ap.AddressPair.AddressNetBIOS.Address.NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
  320. RtlCopyMemory(
  321. ap.AddressPair.AddressNetBIOS.Address.NetbiosName,
  322. ConnectObject->RemoteName,
  323. NETBIOS_NAME_SIZE
  324. );
  325. SMB_RELEASE_SPINLOCK(ConnectObject, Irql);
  326. if (Size > sizeof(ap)) {
  327. Size = sizeof(ap);
  328. }
  329. RtlCopyMemory(AddressPair, &ap, Size);
  330. *BytesCopied = Size;
  331. //
  332. // note: STATUS_BUFFER_OVERFLOW can pass NT_SUCCESS(status)
  333. //
  334. return (Size < RequiredSize)? STATUS_BUFFER_OVERFLOW: STATUS_SUCCESS;
  335. }
  336. NTSTATUS
  337. SmbQueryAddressInfo(
  338. PSMB_DEVICE Device,
  339. PIRP Irp
  340. )
  341. {
  342. PSMB_CONNECT ConnectObject = NULL;
  343. PIO_STACK_LOCATION IrpSp = NULL;
  344. NTSTATUS status = STATUS_SUCCESS;
  345. DWORD BytesCopied = 0;
  346. if (NULL == Irp->MdlAddress) {
  347. status = STATUS_INVALID_PARAMETER;
  348. goto cleanup;
  349. }
  350. SmbPrint(SMB_TRACE_CALL, ("Client needs changes to use IP6 address %d of %s\n",
  351. __LINE__, __FILE__));
  352. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  353. ConnectObject = SmbVerifyAndReferenceConnect(IrpSp->FileObject, SMB_REF_TDI);
  354. if (NULL == ConnectObject) {
  355. ASSERT(0);
  356. status = STATUS_NOT_SUPPORTED;
  357. goto cleanup;
  358. }
  359. status = SmbQueryPeerInfo(ConnectObject,
  360. (PNBT_ADDRESS_PAIR_INFO)MmGetMdlVirtualAddress(Irp->MdlAddress),
  361. MmGetMdlByteCount (Irp->MdlAddress),
  362. &BytesCopied
  363. );
  364. SmbDereferenceConnect(ConnectObject, SMB_REF_TDI);
  365. cleanup:
  366. Irp->IoStatus.Status = status;
  367. Irp->IoStatus.Information = (status != STATUS_SUCCESS)? 0: BytesCopied;
  368. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  369. return status;
  370. }
  371. NTSTATUS
  372. SmbQueryConnectionInfo(
  373. PSMB_DEVICE Device,
  374. PIRP Irp
  375. )
  376. {
  377. NTSTATUS status = STATUS_SUCCESS;
  378. PIO_STACK_LOCATION IrpSp = NULL;
  379. PSMB_CONNECT ConnectObject = NULL;
  380. PDEVICE_OBJECT DeviceObject = NULL;
  381. PFILE_OBJECT TcpConnObject = NULL;
  382. KIRQL Irql = 0;
  383. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  384. ConnectObject = SmbVerifyAndReferenceConnect(IrpSp->FileObject, SMB_REF_TDI);
  385. if (NULL == ConnectObject) {
  386. status = STATUS_INVALID_PARAMETER;
  387. goto cleanup;
  388. }
  389. SMB_ACQUIRE_SPINLOCK(ConnectObject, Irql);
  390. if (NULL == ConnectObject->TcpContext) {
  391. TcpConnObject = NULL;
  392. DeviceObject = NULL;
  393. } else {
  394. TcpConnObject = ConnectObject->TcpContext->Connect.ConnectObject;
  395. ASSERT(TcpConnObject != NULL);
  396. ObReferenceObject(TcpConnObject);
  397. DeviceObject = IoGetRelatedDeviceObject(TcpConnObject);
  398. }
  399. SMB_RELEASE_SPINLOCK(ConnectObject, Irql);
  400. if (NULL == TcpConnObject) {
  401. SmbDereferenceConnect(ConnectObject, SMB_REF_TDI);
  402. status = STATUS_INVALID_PARAMETER;
  403. goto cleanup;
  404. }
  405. TdiBuildQueryInformation(
  406. Irp,
  407. DeviceObject,
  408. TcpConnObject,
  409. NULL, NULL,
  410. TDI_QUERY_CONNECTION_INFO,
  411. Irp->MdlAddress
  412. );
  413. status = IoCallDriver(DeviceObject, Irp);
  414. SmbDereferenceConnect(ConnectObject, SMB_REF_TDI);
  415. ObDereferenceObject(TcpConnObject);
  416. SmbPrint(SMB_TRACE_CALL, ("TCP returns 0x%08lx for TDI_QUERY_CONNECTION_INFO "
  417. "%d of %s\n", status, __LINE__, __FILE__));
  418. return status;
  419. cleanup:
  420. Irp->IoStatus.Status = status;
  421. Irp->IoStatus.Information = 0;
  422. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  423. return status;
  424. }
  425. NTSTATUS
  426. SmbQueryInformation(
  427. PSMB_DEVICE Device,
  428. PIRP Irp,
  429. BOOL *bComplete
  430. )
  431. {
  432. PTDI_REQUEST_KERNEL_QUERY_INFORMATION Query = NULL;
  433. PIO_STACK_LOCATION IrpSp = NULL;
  434. NTSTATUS status = STATUS_NOT_SUPPORTED;
  435. *bComplete = TRUE;
  436. SmbPrint(SMB_TRACE_CALL, ("Entering SmbQueryInformation IRP %p\n", Irp));
  437. SmbTrace(SMB_TRACE_CALL, ("Entering SmbQueryInformation"));
  438. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  439. Query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)(&IrpSp->Parameters);
  440. switch(Query->QueryType) {
  441. case TDI_QUERY_BROADCAST_ADDRESS:
  442. //
  443. // Smb device doesn't support broadcast
  444. //
  445. status = STATUS_INVALID_DEVICE_REQUEST;
  446. ASSERT(0);
  447. break;
  448. case TDI_QUERY_PROVIDER_INFO:
  449. *bComplete = FALSE;
  450. return SmbQueryProviderInfo(Device, Irp);
  451. case TDI_QUERY_ADAPTER_STATUS:
  452. if (Query->RequestConnectionInformation &&
  453. Query->RequestConnectionInformation->RemoteAddress) {
  454. //
  455. // Smb device doesn't support quering remote machine status
  456. //
  457. status = STATUS_NOT_SUPPORTED;
  458. break;
  459. }
  460. *bComplete = FALSE;
  461. return SmbQueryAdapterStatus(Device, Irp);
  462. case TDI_QUERY_CONNECTION_INFO:
  463. *bComplete = FALSE;
  464. return SmbQueryConnectionInfo(Device, Irp);
  465. case TDI_QUERY_FIND_NAME:
  466. status = STATUS_INVALID_DEVICE_REQUEST;
  467. break;
  468. case TDI_QUERY_ADDRESS_INFO:
  469. *bComplete = FALSE;
  470. return SmbQueryAddressInfo(Device, Irp);
  471. case TDI_QUERY_SESSION_STATUS:
  472. default:
  473. status = STATUS_INVALID_DEVICE_REQUEST;
  474. break;
  475. }
  476. SmbPrint(SMB_TRACE_CALL, ("SmbQueryInformatoin: unsupported query type 0x%08lx\n",
  477. Query->QueryType));
  478. return STATUS_NOT_SUPPORTED;
  479. }
  480. NTSTATUS
  481. SmbSetEventHandler(
  482. PSMB_DEVICE Device,
  483. PIRP Irp
  484. )
  485. {
  486. PIO_STACK_LOCATION IrpSp;
  487. NTSTATUS status;
  488. KIRQL Irql;
  489. PSMB_CLIENT_ELEMENT ClientObject;
  490. PTDI_REQUEST_KERNEL_SET_EVENT TdiEvent;
  491. PAGED_CODE();
  492. SmbPrint(SMB_TRACE_CALL, ("Entering SmbSetEventHandler\n"));
  493. SmbTrace(SMB_TRACE_CALL, ("Entering SmbSetEventHandler"));
  494. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  495. ClientObject = SmbVerifyAndReferenceClient(IrpSp->FileObject, SMB_REF_TDI);
  496. if (NULL == ClientObject) {
  497. ASSERT(0);
  498. return STATUS_INVALID_PARAMETER;
  499. }
  500. TdiEvent = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
  501. status = STATUS_SUCCESS;
  502. SMB_ACQUIRE_SPINLOCK(ClientObject, Irql);
  503. switch(TdiEvent->EventType) {
  504. case TDI_EVENT_CONNECT:
  505. ClientObject->evConnect = TdiEvent->EventHandler;
  506. ClientObject->ConEvContext = TdiEvent->EventContext;
  507. SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiConnectHandler\n"));
  508. SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiConnectHandler"));
  509. break;
  510. case TDI_EVENT_DISCONNECT:
  511. ClientObject->evDisconnect = TdiEvent->EventHandler;
  512. ClientObject->DiscEvContext = TdiEvent->EventContext;
  513. SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiDisconnectHandler\n"));
  514. SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiDisconnectHandler"));
  515. break;
  516. case TDI_EVENT_RECEIVE:
  517. ClientObject->evReceive = TdiEvent->EventHandler;
  518. ClientObject->RcvEvContext = TdiEvent->EventContext;
  519. SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveHandler\n"));
  520. SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveHandler"));
  521. break;
  522. case TDI_EVENT_ERROR:
  523. ClientObject->evError = TdiEvent->EventHandler;
  524. ClientObject->ErrorEvContext = TdiEvent->EventContext;
  525. SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiErrorHandler\n"));
  526. SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiErrorHandler"));
  527. break;
  528. case TDI_EVENT_RECEIVE_DATAGRAM:
  529. SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveDatagram (unsupported)\n"));
  530. SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveDatagram (unsupported)"));
  531. break;
  532. case TDI_EVENT_RECEIVE_EXPEDITED:
  533. SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveExpedited (unsupported)\n"));
  534. SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveExpedited (unsupported)"));
  535. break;
  536. case TDI_EVENT_SEND_POSSIBLE:
  537. SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiSendPossible (unsupported)\n"));
  538. SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiSendPossible (unsupported)"));
  539. break;
  540. default:
  541. //status = STATUS_NOT_SUPPORTED;
  542. SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set unsupported TDI event handler %lx\n",
  543. TdiEvent->EventType));
  544. SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set upsupported TDI event handler %lx",
  545. TdiEvent->EventType));
  546. ASSERT (0);
  547. }
  548. SMB_RELEASE_SPINLOCK(ClientObject, Irql);
  549. ASSERT(status != STATUS_PENDING);
  550. SmbDereferenceClient(ClientObject, SMB_REF_TDI);
  551. return status;
  552. }
  553. NTSTATUS
  554. SmbSetInformation(
  555. PSMB_DEVICE Device,
  556. PIRP Irp
  557. )
  558. {
  559. PAGED_CODE();
  560. SmbPrint(SMB_TRACE_CALL, ("Entering SmbSetInformation\n"));
  561. SmbTrace(SMB_TRACE_CALL, ("Entering SmbSetInformation"));
  562. ASSERT(0);
  563. return STATUS_NOT_SUPPORTED;
  564. }
  565. NTSTATUS
  566. SmbClientSetTcpInfo(
  567. PSMB_DEVICE Device,
  568. PIRP Irp
  569. )
  570. {
  571. PIO_STACK_LOCATION IrpSp;
  572. PVOID InfoBuffer;
  573. ULONG InfoBufferLength;
  574. PSMB_CONNECT ConnectObject;
  575. PFILE_OBJECT TcpConnObject;
  576. KIRQL Irql;
  577. NTSTATUS status;
  578. if (Irp->RequestorMode != KernelMode) {
  579. return STATUS_ACCESS_DENIED;
  580. }
  581. // BREAK_WHEN_TAKE();
  582. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  583. InfoBuffer = Irp->AssociatedIrp.SystemBuffer;
  584. InfoBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  585. ConnectObject = SmbVerifyAndReferenceConnect(IrpSp->FileObject, SMB_REF_TDI);
  586. if (NULL == ConnectObject) {
  587. return STATUS_INVALID_PARAMETER;
  588. }
  589. SMB_ACQUIRE_SPINLOCK(ConnectObject, Irql);
  590. if (NULL == ConnectObject->TcpContext) {
  591. TcpConnObject = NULL;
  592. } else {
  593. TcpConnObject = ConnectObject->TcpContext->Connect.ConnectObject;
  594. ASSERT(TcpConnObject != NULL);
  595. ObReferenceObject(TcpConnObject);
  596. }
  597. SMB_RELEASE_SPINLOCK(ConnectObject, Irql);
  598. SmbDereferenceConnect(ConnectObject, SMB_REF_TDI);
  599. if (NULL == TcpConnObject) {
  600. return STATUS_INVALID_PARAMETER;
  601. }
  602. status = SmbSendIoctl(
  603. TcpConnObject,
  604. IOCTL_TCP_SET_INFORMATION_EX,
  605. InfoBuffer,
  606. InfoBufferLength,
  607. NULL,
  608. NULL
  609. );
  610. if (!NT_SUCCESS(status)) {
  611. SmbPrint(SMB_TRACE_TCP, ("SmbClientSetTcpInfo: SetTcpInfo FAILed <0x%x> InfoBuffer=%p Length=%d\n",
  612. status, InfoBuffer, InfoBufferLength));
  613. SmbTrace(SMB_TRACE_TCP, ("FAILed %!status! InfoBuffer=%p Length=%d",
  614. status, InfoBuffer, InfoBufferLength));
  615. }
  616. ObDereferenceObject(TcpConnObject);
  617. return status;
  618. }
  619. NTSTATUS
  620. IoctlSetIPv6Protection(
  621. PSMB_DEVICE pDeviceObject,
  622. PIRP pIrp,
  623. PIO_STACK_LOCATION pIrpSp
  624. )
  625. {
  626. NTSTATUS ntStatus = STATUS_SUCCESS;
  627. DWORD dwInputBufferLength = 0;
  628. PNBSMB_IPV6_PROTECTION_PARAM pInput = NULL;
  629. ULONG uOldIPv6Protection = 0;
  630. dwInputBufferLength = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
  631. pInput = pIrp->AssociatedIrp.SystemBuffer;
  632. if (dwInputBufferLength < sizeof(NBSMB_IPV6_PROTECTION_PARAM) || NULL == pInput) {
  633. ntStatus = STATUS_INVALID_PARAMETER;
  634. goto error;
  635. }
  636. SmbTrace(SMB_TRACE_IOCTL, ("uIPv6Protection: input %d", pInput->uIPv6ProtectionLevel));
  637. if (SmbCfg.uIPv6Protection != pInput->uIPv6ProtectionLevel) {
  638. uOldIPv6Protection = SmbCfg.uIPv6Protection;
  639. SmbCfg.uIPv6Protection = pInput->uIPv6ProtectionLevel;
  640. ntStatus = SmbSetInboundIPv6Protection(pDeviceObject);
  641. SmbTrace(SMB_TRACE_IOCTL, ("Change IPv6 Protection for inbound return %!status!", ntStatus));
  642. if (ntStatus != STATUS_SUCCESS) {
  643. NTSTATUS LocalStatus = STATUS_SUCCESS;
  644. SmbCfg.uIPv6Protection = uOldIPv6Protection;
  645. LocalStatus = SmbSetInboundIPv6Protection(pDeviceObject);
  646. SmbTrace(SMB_TRACE_IOCTL, ("Restore to the old settings on failure. Restore status %!status!",
  647. LocalStatus));
  648. }
  649. }
  650. if (ntStatus == STATUS_SUCCESS) {
  651. SmbCfg.bIPv6EnableOutboundGlobal = pInput->bIPv6EnableOutboundGlobal;
  652. }
  653. error:
  654. SmbTrace(SMB_TRACE_IOCTL, ("%!status!", ntStatus));
  655. return ntStatus;
  656. }