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.

2950 lines
82 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. ntinit.c
  5. Abstract:
  6. NT specific routines for loading and configuring the TCP/UDP driver.
  7. Author:
  8. Mike Massa (mikemas) Aug 13, 1993
  9. Revision History:
  10. Who When What
  11. -------- -------- ----------------------------------------------
  12. mikemas 08-13-93 created
  13. Notes:
  14. --*/
  15. #include "precomp.h"
  16. #if !MILLEN
  17. #include <ipfilter.h>
  18. #include <ipsec.h>
  19. #endif // !MILLEN
  20. #include "tdint.h"
  21. #include "addr.h"
  22. #include "tcp.h"
  23. #include "tcb.h"
  24. #include "udp.h"
  25. #include "raw.h"
  26. #include "tcpconn.h"
  27. #include "mdlpool.h"
  28. #include "pplasl.h"
  29. #include "tcprcv.h"
  30. #include "tcpsend.h"
  31. #include "tlcommon.h"
  32. #include "tcpcfg.h"
  33. #include "secfltr.h"
  34. #if GPC
  35. #include <qos.h>
  36. #include <traffic.h>
  37. #include "gpcifc.h"
  38. #include "ntddtc.h"
  39. GPC_HANDLE hGpcClient[GPC_CF_MAX] = {0};
  40. ulong GpcCfCounts[GPC_CF_MAX] = {0};
  41. GPC_EXPORTED_CALLS GpcEntries;
  42. GPC_CLIENT_FUNC_LIST GpcHandlers;
  43. ulong GPCcfInfo = 0;
  44. ulong ServiceTypeOffset = FIELD_OFFSET(CF_INFO_QOS, ToSValue);
  45. GPC_STATUS GPCcfInfoAddNotifyIpsec(GPC_CLIENT_HANDLE ClCtxt,
  46. GPC_HANDLE GpcHandle,
  47. ULONG CfInfoSize,
  48. PVOID CfInfo,
  49. PGPC_CLIENT_HANDLE pClInfoCxt);
  50. GPC_STATUS GPCcfInfoRemoveNotifyIpsec(GPC_CLIENT_HANDLE ClCtxt,
  51. GPC_CLIENT_HANDLE ClInfoCxt);
  52. GPC_STATUS GPCcfInfoAddNotifyQoS(GPC_CLIENT_HANDLE ClCtxt,
  53. GPC_HANDLE GpcHandle,
  54. ULONG CfInfoSize,
  55. PVOID CfInfo,
  56. PGPC_CLIENT_HANDLE pClInfoCxt);
  57. GPC_STATUS GPCcfInfoRemoveNotifyQoS(GPC_CLIENT_HANDLE ClCtxt,
  58. GPC_CLIENT_HANDLE ClInfoCxt);
  59. #endif
  60. ReservedPortListEntry *PortRangeList = NULL;
  61. VOID
  62. GetReservedPortList(
  63. NDIS_HANDLE ConfigHandle
  64. );
  65. //
  66. // Global variables.
  67. //
  68. PDRIVER_OBJECT TCPDriverObject = NULL;
  69. PDEVICE_OBJECT TCPDeviceObject = NULL;
  70. PDEVICE_OBJECT UDPDeviceObject = NULL;
  71. PDEVICE_OBJECT RawIPDeviceObject = NULL;
  72. extern PDEVICE_OBJECT IPDeviceObject;
  73. TCPXSUM_ROUTINE tcpxsum_routine = tcpxsum;
  74. #if ACC
  75. PSECURITY_DESCRIPTOR TcpAdminSecurityDescriptor;
  76. extern uint AllowUserRawAccess;
  77. typedef ULONG SECURITY_INFORMATION;
  78. BOOLEAN
  79. IsRunningOnPersonal (
  80. VOID
  81. );
  82. #endif
  83. extern uint DisableLargeSendOffload;
  84. //
  85. //Place holder for Maximum duplicate acks we would like
  86. //to see before we do fast retransmit
  87. //
  88. extern uint MaxDupAcks;
  89. MM_SYSTEMSIZE systemSize;
  90. extern uint MaxHashTableSize;
  91. extern uint NumTcbTablePartitions;
  92. extern uint PerPartitionSize;
  93. extern uint LogPerPartitionSize;
  94. #define CACHE_LINE_SIZE 64
  95. #define CACHE_ALIGN_MASK (~(CACHE_LINE_SIZE-1))
  96. CTELock *pTWTCBTableLock;
  97. CTELock *pTCBTableLock;
  98. CTELock *pSynTCBTableLock;
  99. extern Queue *TWQueue;
  100. extern Queue *TWTCBTable;
  101. extern TCB **TCBTable;
  102. extern Queue *SYNTCBTable;
  103. extern PTIMER_WHEEL TimerWheel;
  104. PTIMER_WHEEL OrgTimerWheel;
  105. extern TCPConn **ConnTable;
  106. extern uint MaxConnBlocks;
  107. extern uint ConnPerBlock;
  108. extern uint GlobalMaxRcvWin;
  109. extern uint TcpHostOpts;
  110. extern uint TcpHostSendOpts;
  111. extern uint MaxRcvWin;
  112. HANDLE TCPRegistrationHandle;
  113. HANDLE UDPRegistrationHandle;
  114. HANDLE IPRegistrationHandle;
  115. //SynAttackProtect=0 no syn flood attack protection
  116. //SynAttackProtect !0 syn flood attack protection
  117. //SynAttackProtect !0 syn flood attack protection+forced(non-dynamic)
  118. // delayed connect acceptance
  119. uint SynAttackProtect; //syn-att protection checks
  120. // are made
  121. uint TCPPortsExhausted; //# of ports exhausted
  122. uint TCPMaxPortsExhausted; //Max # of ports that must be exhausted
  123. // for syn-att protection to kick in
  124. uint TCPMaxPortsExhaustedLW; //Low-watermark of # of ports exhausted
  125. //When reached, we revert to normal
  126. // count for syn-ack retries
  127. uint TCPMaxHalfOpen; //Max # of half-open connections allowed
  128. // before we dec. the syn-ack retries
  129. uint TCPMaxHalfOpenRetried; //Max # of half-open conn. that have
  130. // been retried at least 1 time
  131. uint TCPMaxHalfOpenRetriedLW; //Low-watermark of the above. When
  132. // go down to it, we revert to normal
  133. // # of retries for syn-acks
  134. uint TCPHalfOpen; //# of half-open connections
  135. uint TCPHalfOpenRetried; //# of half-open conn. that have been
  136. //retried at least once
  137. PDEVICE_OBJECT IPSECDeviceObject;
  138. PFILE_OBJECT IPSECFileObject;
  139. extern uint Time_Proc;
  140. extern HANDLE TcbPool;
  141. extern HANDLE TimewaitTcbPool;
  142. extern HANDLE SynTcbPool;
  143. extern void ArpUnload(PDRIVER_OBJECT);
  144. extern CTETimer TCBTimer[];
  145. extern BOOLEAN fTCBTimerStopping;
  146. extern CTEBlockStruc TcpipUnloadBlock;
  147. HANDLE AddressChangeHandle;
  148. extern ulong DefaultTOSValue;
  149. extern ulong DisableUserTOSSetting;
  150. extern uint MaxSendSegments;
  151. //
  152. // External function prototypes
  153. //
  154. int
  155. tlinit(
  156. void
  157. );
  158. NTSTATUS
  159. TCPDispatch(
  160. IN PDEVICE_OBJECT DeviceObject,
  161. IN PIRP Irp
  162. );
  163. NTSTATUS
  164. TCPDispatchInternalDeviceControl(
  165. IN PDEVICE_OBJECT DeviceObject,
  166. IN PIRP Irp
  167. );
  168. NTSTATUS
  169. IPDispatch(
  170. IN PDEVICE_OBJECT DeviceObject,
  171. IN PIRP Irp
  172. );
  173. NTSTATUS
  174. IPDriverEntry(
  175. IN PDRIVER_OBJECT DriverObject,
  176. IN PUNICODE_STRING RegistryPath
  177. );
  178. NTSTATUS
  179. IPPostDriverEntry(
  180. IN PDRIVER_OBJECT DriverObject,
  181. IN PUNICODE_STRING RegistryPath
  182. );
  183. NTSTATUS
  184. GetRegMultiSZValue(
  185. HANDLE KeyHandle,
  186. PWCHAR ValueName,
  187. PUNICODE_STRING ValueData
  188. );
  189. PWCHAR
  190. EnumRegMultiSz(
  191. IN PWCHAR MszString,
  192. IN ULONG MszStringLength,
  193. IN ULONG StringIndex
  194. );
  195. uint InitIsnGenerator();
  196. #if !MILLEN
  197. extern ulong g_cRandIsnStore;
  198. #endif // !MILLEN
  199. #if MILLEN
  200. extern VOID InitializeWDebDebug();
  201. #endif // MILLEN
  202. //
  203. // Local funcion prototypes
  204. //
  205. NTSTATUS
  206. DriverEntry(
  207. IN PDRIVER_OBJECT DriverObject,
  208. IN PUNICODE_STRING RegistryPath
  209. );
  210. void *
  211. TLRegisterProtocol(
  212. uchar Protocol,
  213. void *RcvHandler,
  214. void *XmitHandler,
  215. void *StatusHandler,
  216. void *RcvCmpltHandler,
  217. void *PnPHandler,
  218. void *ElistHandler
  219. );
  220. IP_STATUS
  221. TLGetIPInfo(
  222. IPInfo * Buffer,
  223. int Size
  224. );
  225. uchar
  226. TCPGetConfigInfo(
  227. void
  228. );
  229. NTSTATUS
  230. TCPInitializeParameter(
  231. HANDLE KeyHandle,
  232. PWCHAR ValueName,
  233. PULONG Value
  234. );
  235. #if !MILLEN
  236. NTSTATUS
  237. IpsecInitialize(
  238. void
  239. );
  240. NTSTATUS
  241. IpsecDeinitialize(
  242. void
  243. );
  244. #endif
  245. #if !MILLEN
  246. #ifdef i386
  247. NTSTATUS
  248. TCPSetChecksumRoutine(
  249. VOID
  250. );
  251. #endif
  252. #endif // !MILLEN
  253. uint
  254. EnumSecurityFilterValue(
  255. PNDIS_STRING FilterList,
  256. ulong Index,
  257. ulong * FilterValue
  258. );
  259. VOID
  260. TCPAcdBind();
  261. #ifdef ACC
  262. typedef ULONG SECURITY_INFORMATION;
  263. NTSTATUS
  264. TcpBuildDeviceAcl(
  265. OUT PACL * DeviceAcl
  266. );
  267. NTSTATUS
  268. TcpCreateAdminSecurityDescriptor(
  269. VOID
  270. );
  271. NTSTATUS
  272. AddNetConfigOpsAce(IN PACL Dacl,
  273. OUT PACL * DeviceAcl
  274. );
  275. NTSTATUS
  276. CreateDeviceDriverSecurityDescriptor(PVOID DeviceOrDriverObject
  277. );
  278. #endif // ACC
  279. #ifdef ALLOC_PRAGMA
  280. #pragma alloc_text(INIT, DriverEntry)
  281. #pragma alloc_text(INIT, TLRegisterProtocol)
  282. #pragma alloc_text(INIT, TLGetIPInfo)
  283. #pragma alloc_text(INIT, TCPGetConfigInfo)
  284. #pragma alloc_text(INIT, TCPInitializeParameter)
  285. #if !MILLEN
  286. #pragma alloc_text(INIT, IpsecInitialize)
  287. #endif
  288. #if !MILLEN
  289. #ifdef i386
  290. #pragma alloc_text(INIT, TCPSetChecksumRoutine)
  291. #endif
  292. #endif // !MILLEN
  293. #pragma alloc_text(PAGE, EnumSecurityFilterValue)
  294. #pragma alloc_text(INIT, TCPAcdBind)
  295. #ifdef ACC
  296. #pragma alloc_text(INIT, TcpBuildDeviceAcl)
  297. #pragma alloc_text(INIT, TcpCreateAdminSecurityDescriptor)
  298. #pragma alloc_text(INIT, AddNetConfigOpsAce)
  299. #pragma alloc_text(INIT, CreateDeviceDriverSecurityDescriptor)
  300. #endif // ACC
  301. #endif
  302. //
  303. // Function definitions
  304. //
  305. NTSTATUS
  306. DriverEntry(
  307. IN PDRIVER_OBJECT DriverObject,
  308. IN PUNICODE_STRING RegistryPath
  309. )
  310. /*++
  311. Routine Description:
  312. Initialization routine for the TCP/UDP driver.
  313. Arguments:
  314. DriverObject - Pointer to the TCP driver object created by the system.
  315. DeviceDescription - The name of TCP's node in the registry.
  316. Return Value:
  317. The final status from the initialization operation.
  318. --*/
  319. {
  320. NTSTATUS status;
  321. UNICODE_STRING deviceName;
  322. UNICODE_STRING SymbolicDeviceName;
  323. USHORT i;
  324. int initStatus;
  325. DEBUGMSGINIT();
  326. DEBUGMSG(DBG_TRACE && DBG_INIT,
  327. (DTEXT("+DriverEntry(%x, %x)\n"), DriverObject, RegistryPath));
  328. TdiInitialize();
  329. //
  330. // IP calls the security filter code, so initialize it first.
  331. //
  332. InitializeSecurityFilters();
  333. //
  334. // Initialize IP
  335. //
  336. status = IPDriverEntry(DriverObject, RegistryPath);
  337. if (!NT_SUCCESS(status)) {
  338. DEBUGMSG(DBG_ERROR && DBG_INIT,
  339. (DTEXT("TCPIP: IP Initialization failure %x\n"), status));
  340. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-DriverEntry [%x]\n"), status));
  341. return (status);
  342. }
  343. #if !MILLEN
  344. //
  345. // Initialize IPSEC
  346. //
  347. status = IpsecInitialize();
  348. if (!NT_SUCCESS(status)) {
  349. DEBUGMSG(DBG_ERROR && DBG_INIT,
  350. (DTEXT("TCPIP: IPSEC Initialization failure %x\n"), status));
  351. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-DriverEntry [%x]\n"), status));
  352. goto init_failed;
  353. }
  354. #endif
  355. //
  356. // Initialize TCP, UDP, and RawIP
  357. //
  358. TCPDriverObject = DriverObject;
  359. //
  360. // Create the device objects. IoCreateDevice zeroes the memory
  361. // occupied by the object.
  362. //
  363. RtlInitUnicodeString(&deviceName, DD_TCP_DEVICE_NAME);
  364. RtlInitUnicodeString(&SymbolicDeviceName, DD_TCP_SYMBOLIC_DEVICE_NAME);
  365. status = IoCreateDevice(
  366. DriverObject,
  367. 0,
  368. &deviceName,
  369. FILE_DEVICE_NETWORK,
  370. FILE_DEVICE_SECURE_OPEN,
  371. FALSE,
  372. &TCPDeviceObject
  373. );
  374. if (!NT_SUCCESS(status)) {
  375. CTELogEvent(
  376. DriverObject,
  377. EVENT_TCPIP_CREATE_DEVICE_FAILED,
  378. 1,
  379. 1,
  380. &deviceName.Buffer,
  381. 0,
  382. NULL
  383. );
  384. DEBUGMSG(DBG_ERROR && DBG_INIT,
  385. (DTEXT("DriverEntry: failure %x to create TCP device object %ws\n"),
  386. status, DD_TCP_DEVICE_NAME));
  387. goto init_failed;
  388. }
  389. status = IoCreateSymbolicLink(&SymbolicDeviceName, &deviceName);
  390. if (!NT_SUCCESS(status)) {
  391. CTELogEvent(
  392. DriverObject,
  393. EVENT_TCPIP_CREATE_DEVICE_FAILED,
  394. 1,
  395. 1,
  396. &deviceName.Buffer,
  397. 0,
  398. NULL
  399. );
  400. DEBUGMSG(DBG_ERROR && DBG_INIT,
  401. (DTEXT("DriverEntry: failure %x to create TCP symbolic device link %ws\n"),
  402. status, DD_TCP_SYMBOLIC_DEVICE_NAME));
  403. goto init_failed;
  404. }
  405. RtlInitUnicodeString(&deviceName, DD_UDP_DEVICE_NAME);
  406. status = IoCreateDevice(
  407. DriverObject,
  408. 0,
  409. &deviceName,
  410. FILE_DEVICE_NETWORK,
  411. FILE_DEVICE_SECURE_OPEN,
  412. FALSE,
  413. &UDPDeviceObject
  414. );
  415. if (!NT_SUCCESS(status)) {
  416. CTELogEvent(
  417. DriverObject,
  418. EVENT_TCPIP_CREATE_DEVICE_FAILED,
  419. 1,
  420. 1,
  421. &deviceName.Buffer,
  422. 0,
  423. NULL
  424. );
  425. TCPTRACE((
  426. "TCP: Failed to create UDP device object, status %lx\n",
  427. status
  428. ));
  429. goto init_failed;
  430. }
  431. RtlInitUnicodeString(&deviceName, DD_RAW_IP_DEVICE_NAME);
  432. status = IoCreateDevice(
  433. DriverObject,
  434. 0,
  435. &deviceName,
  436. FILE_DEVICE_NETWORK,
  437. FILE_DEVICE_SECURE_OPEN,
  438. FALSE,
  439. &RawIPDeviceObject
  440. );
  441. if (!NT_SUCCESS(status)) {
  442. CTELogEvent(
  443. DriverObject,
  444. EVENT_TCPIP_CREATE_DEVICE_FAILED,
  445. 1,
  446. 1,
  447. &deviceName.Buffer,
  448. 0,
  449. NULL
  450. );
  451. TCPTRACE((
  452. "TCP: Failed to create Raw IP device object, status %lx\n",
  453. status
  454. ));
  455. goto init_failed;
  456. }
  457. //
  458. // Initialize the driver object
  459. //
  460. DriverObject->DriverUnload = ArpUnload;
  461. DriverObject->FastIoDispatch = NULL;
  462. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  463. DriverObject->MajorFunction[i] = TCPDispatch;
  464. }
  465. //
  466. // We special case Internal Device Controls because they are the
  467. // hot path for kernel-mode clients.
  468. //
  469. DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
  470. TCPDispatchInternalDeviceControl;
  471. //
  472. // Intialize the device objects.
  473. //
  474. TCPDeviceObject->Flags |= DO_DIRECT_IO;
  475. UDPDeviceObject->Flags |= DO_DIRECT_IO;
  476. RawIPDeviceObject->Flags |= DO_DIRECT_IO;
  477. #ifdef ACC
  478. // Change the different devices and Objects to allow access to Network Configuration Operators
  479. if (!IsRunningOnPersonal()) {
  480. status = CreateDeviceDriverSecurityDescriptor(IPDeviceObject);
  481. if (!NT_SUCCESS(status)) {
  482. goto init_failed;
  483. }
  484. status = CreateDeviceDriverSecurityDescriptor(TCPDeviceObject);
  485. if (!NT_SUCCESS(status)) {
  486. goto init_failed;
  487. }
  488. status = CreateDeviceDriverSecurityDescriptor(IPSECDeviceObject);
  489. if (!NT_SUCCESS(status)) {
  490. goto init_failed;
  491. }
  492. }
  493. //
  494. // Create the security descriptor used for raw socket access checks.
  495. //
  496. status = TcpCreateAdminSecurityDescriptor();
  497. if (!NT_SUCCESS(status)) {
  498. goto init_failed;
  499. }
  500. #endif // ACC
  501. #if !MILLEN
  502. #ifdef i386
  503. //
  504. // Set the checksum routine pointer according to the processor available
  505. //
  506. TCPSetChecksumRoutine();
  507. #endif
  508. #endif // !MILLEN
  509. //
  510. // Finally, initialize the stack.
  511. //
  512. initStatus = tlinit();
  513. if (initStatus == TRUE) {
  514. //
  515. // Get the automatic connection driver
  516. // entry points.
  517. //
  518. TCPAcdBind();
  519. RtlInitUnicodeString(&deviceName, DD_TCP_DEVICE_NAME);
  520. (void)TdiRegisterDeviceObject(&deviceName, &TCPRegistrationHandle);
  521. RtlInitUnicodeString(&deviceName, DD_UDP_DEVICE_NAME);
  522. (void)TdiRegisterDeviceObject(&deviceName, &UDPRegistrationHandle);
  523. RtlInitUnicodeString(&deviceName, DD_RAW_IP_DEVICE_NAME);
  524. (void)TdiRegisterDeviceObject(&deviceName, &IPRegistrationHandle);
  525. // do the ndis register protocol now after all the intialization
  526. // is complete, o/w we get bindadapter even before we r fully
  527. // initialized.
  528. status = IPPostDriverEntry(DriverObject, RegistryPath);
  529. if (!NT_SUCCESS(status)) {
  530. DEBUGMSG(DBG_ERROR && DBG_INIT,
  531. (DTEXT("TCPIP: IP post-init failure %x\n"), status));
  532. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-DriverEntry [%x]\n"), status));
  533. return (status);
  534. }
  535. #if GPC
  536. status = GpcInitialize(&GpcEntries);
  537. if (!NT_SUCCESS(status)) {
  538. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"GpcInitialize Failed! Status: 0x%x\n", status));
  539. //return status;
  540. } else {
  541. //
  542. // Need to register as GPC client. Try it now.
  543. // we register clients for QOS and IPSEC
  544. //
  545. memset(&GpcHandlers, 0, sizeof(GPC_CLIENT_FUNC_LIST));
  546. GpcHandlers.ClAddCfInfoNotifyHandler = GPCcfInfoAddNotifyQoS;
  547. GpcHandlers.ClRemoveCfInfoNotifyHandler = GPCcfInfoRemoveNotifyQoS;
  548. status = GpcEntries.GpcRegisterClientHandler(
  549. GPC_CF_QOS, // classification family
  550. 0, // flags
  551. 1, // default max priority
  552. &GpcHandlers, // client notification vector - no notifications to TCPIP required
  553. 0, // client context, not needed
  554. &hGpcClient[GPC_CF_QOS]);
  555. if (!NT_SUCCESS(status)) {
  556. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"GPC registerclient QOS status %x hGpcClient %p\n",
  557. status, hGpcClient[GPC_CF_QOS]));
  558. hGpcClient[GPC_CF_QOS] = NULL;
  559. }
  560. GpcHandlers.ClAddCfInfoNotifyHandler = GPCcfInfoAddNotifyIpsec;
  561. GpcHandlers.ClRemoveCfInfoNotifyHandler = GPCcfInfoRemoveNotifyIpsec;
  562. status = GpcEntries.GpcRegisterClientHandler(
  563. GPC_CF_IPSEC, // classification family
  564. 0, // flags
  565. GPC_PRIORITY_IPSEC, // default max priority
  566. &GpcHandlers, // client notification vector - no notifications to TCPIP required
  567. 0, // client context, not needed
  568. &hGpcClient[GPC_CF_IPSEC]);
  569. if (!NT_SUCCESS(status)) {
  570. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"GPC registerclient IPSEC status %x hGpcClient %p\n",
  571. status, hGpcClient[GPC_CF_IPSEC]));
  572. hGpcClient[GPC_CF_IPSEC] = NULL;
  573. }
  574. }
  575. #endif
  576. if (InitIsnGenerator() == FALSE) {
  577. DEBUGMSG(DBG_ERROR && DBG_INIT,
  578. (DTEXT("InitIsnGenerator failure. TCP/IP failing to start.\n")));
  579. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-DriverEntry [%x]\n"), status));
  580. return (STATUS_UNSUCCESSFUL);
  581. }
  582. // Millennium TCPIP has debugger extensions built in!
  583. #if MILLEN
  584. InitializeWDebDebug();
  585. #endif // MILLEN
  586. #if TRACE_EVENT
  587. //
  588. // Register with WMI for Enable/Disable Notification
  589. // of Trace Logging
  590. //
  591. TCPCPHandlerRoutine = NULL;
  592. IoWMIRegistrationControl(
  593. TCPDeviceObject,
  594. WMIREG_ACTION_REGISTER |
  595. WMIREG_FLAG_TRACE_PROVIDER |
  596. WMIREG_NOTIFY_TDI_IO
  597. );
  598. #endif
  599. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-DriverEntry [SUCCESS]\n")));
  600. return (STATUS_SUCCESS);
  601. }
  602. DEBUGMSG(DBG_ERROR && DBG_INIT,
  603. (DTEXT("TCPIP: TCP initialization failed, IP still available.\n")));
  604. CTELogEvent(
  605. DriverObject,
  606. EVENT_TCPIP_TCP_INIT_FAILED,
  607. 1,
  608. 0,
  609. NULL,
  610. 0,
  611. NULL
  612. );
  613. status = STATUS_UNSUCCESSFUL;
  614. init_failed:
  615. DEBUGMSG(DBG_ERROR && DBG_INIT,
  616. (DTEXT("TCPIP DriverEntry initialization failure!\n")));
  617. //
  618. // IP has successfully started, but TCP & UDP failed. Set the
  619. // Dispatch routine to point to IP only, since the TCP and UDP
  620. // devices don't exist.
  621. //
  622. if (TCPDeviceObject != NULL) {
  623. IoDeleteDevice(TCPDeviceObject);
  624. }
  625. if (UDPDeviceObject != NULL) {
  626. IoDeleteDevice(UDPDeviceObject);
  627. }
  628. if (RawIPDeviceObject != NULL) {
  629. IoDeleteDevice(RawIPDeviceObject);
  630. }
  631. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  632. DriverObject->MajorFunction[i] = IPDispatch;
  633. }
  634. #if !MILLEN
  635. if (IPSECFileObject) {
  636. IpsecDeinitialize();
  637. }
  638. #endif
  639. return (status);
  640. }
  641. #if !MILLEN
  642. #ifdef i386
  643. NTSTATUS
  644. TCPSetChecksumRoutine(
  645. VOID
  646. )
  647. /*++
  648. Routine Description:
  649. This routine sets the checksum routine function pointer to the
  650. appropriate routine based on the processor features available
  651. Arguments:
  652. None
  653. Return Value:
  654. STATUS_SUCCESS - if successful
  655. --*/
  656. {
  657. SYSTEM_PROCESSOR_INFORMATION Info;
  658. ULONG Length;
  659. ULONG Features;
  660. ULONG Processors;
  661. ULONG i;
  662. NTSTATUS Status;
  663. BOOLEAN TcpipUsePrefetch;
  664. #if WINVER < 0x0500
  665. KAFFINITY OriginalAffinity;
  666. #endif /* WINVER */
  667. //
  668. // First check to see that I have at least Intel Pentium. This simplifies
  669. // the cpuid
  670. //
  671. Status = ZwQuerySystemInformation(SystemProcessorInformation,
  672. &Info,
  673. sizeof(Info),
  674. &Length);
  675. if (!NT_SUCCESS(Status)) {
  676. return (Status);
  677. }
  678. if (Info.ProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL ||
  679. Info.ProcessorLevel < 5) {
  680. Status = STATUS_INSUFFICIENT_RESOURCES;
  681. return (Status);
  682. }
  683. Status = STATUS_SUCCESS;
  684. TcpipUsePrefetch = TRUE;
  685. Processors = KeNumberProcessors;
  686. //
  687. // Affinity thread to boot processor
  688. //
  689. #if WINVER < 0x0500
  690. OriginalAffinity = KeSetAffinityThread(KeGetCurrentThread(), 1);
  691. #else /* WINVER >= 0x0500 */
  692. KeSetSystemAffinityThread(1);
  693. #endif /* WINVER */
  694. for (i = 0; i < Processors; i++) {
  695. if (i != 0) {
  696. #if WINVER < 0x0500
  697. KeSetAffinityThread(KeGetCurrentThread(), 1 << i);
  698. #else /* WINVER >= 0x0500 */
  699. KeSetSystemAffinityThread(1 << i);
  700. #endif /* WINVER */
  701. }
  702. _asm {
  703. push ebx
  704. mov eax, 1
  705. ;cpuid
  706. _emit 0fh
  707. _emit 0a2h
  708. mov Features, edx
  709. pop ebx
  710. }
  711. //
  712. // Check for Prefetch Present
  713. //
  714. if (!(Features & 0x02000000)) {
  715. //
  716. // All processors must have prefetch before we can use it.
  717. // We start with it enabled, if any processor does not have
  718. // it we clear it,
  719. TcpipUsePrefetch = FALSE;
  720. }
  721. }
  722. #if WINVER < 0x0500
  723. KeSetAffinityThread(KeGetCurrentThread(), OriginalAffinity);
  724. #else /* WINVER >= 0x0500 */
  725. KeRevertToUserAffinityThread();
  726. #endif /* WINVER */
  727. if (TcpipUsePrefetch == TRUE) {
  728. tcpxsum_routine = tcpxsum_xmmi;
  729. }
  730. return (Status);
  731. }
  732. #endif
  733. #endif // !MILLEN
  734. IP_STATUS
  735. TLGetIPInfo(
  736. IPInfo * Buffer,
  737. int Size
  738. )
  739. /*++
  740. Routine Description:
  741. Returns information necessary for TCP to call into IP.
  742. Arguments:
  743. Buffer - A pointer to the IP information structure.
  744. Size - The size of Buffer.
  745. Return Value:
  746. The IP status of the operation.
  747. --*/
  748. {
  749. return (IPGetInfo(Buffer, Size));
  750. }
  751. void *
  752. TLRegisterProtocol(
  753. uchar Protocol,
  754. void *RcvHandler,
  755. void *XmitHandler,
  756. void *StatusHandler,
  757. void *RcvCmpltHandler,
  758. void *PnPHandler,
  759. void *ElistHandler
  760. )
  761. /*++
  762. Routine Description:
  763. Calls the IP driver's protocol registration function.
  764. Arguments:
  765. Protocol - The protocol number to register.
  766. RcvHandler - Transport's packet receive handler.
  767. XmitHandler - Transport's packet transmit complete handler.
  768. StatusHandler - Transport's status update handler.
  769. RcvCmpltHandler - Transport's receive complete handler
  770. Return Value:
  771. A context value for the protocol to pass to IP when transmitting.
  772. --*/
  773. {
  774. return (IPRegisterProtocol(
  775. Protocol,
  776. RcvHandler,
  777. XmitHandler,
  778. StatusHandler,
  779. RcvCmpltHandler,
  780. PnPHandler,
  781. ElistHandler));
  782. }
  783. //
  784. // Interval in milliseconds between keepalive transmissions until a
  785. // response is received.
  786. //
  787. #define DEFAULT_KEEPALIVE_INTERVAL 1000
  788. //
  789. // time to first keepalive transmission. 2 hours == 7,200,000 milliseconds
  790. //
  791. #define DEFAULT_KEEPALIVE_TIME 7200000
  792. #define MIN_THRESHOLD_MAX_HO 1
  793. #define MIN_THRESHOLD_MAX_HO_RETRIED 80
  794. uchar
  795. TCPGetConfigInfo(
  796. void
  797. )
  798. /*++
  799. Routine Description:
  800. Initializes TCP global configuration parameters.
  801. Arguments:
  802. None.
  803. Return Value:
  804. Zero on failure, nonzero on success.
  805. --*/
  806. {
  807. HANDLE keyHandle;
  808. NTSTATUS status;
  809. OBJECT_ATTRIBUTES objectAttributes;
  810. UNICODE_STRING UKeyName;
  811. ULONG maxConnectRexmits = 0;
  812. ULONG maxConnectResponseRexmits = 0;
  813. ULONG maxDataRexmits = 0;
  814. ULONG pptpmaxDataRexmits = 0;
  815. ULONG useRFC1122UrgentPointer = 0;
  816. BOOLEAN AsSystem;
  817. ULONG tcp1323opts = 3; //turning off 1323 options by default
  818. ULONG SackOpts;
  819. ULONG i, j;
  820. DEBUGMSG(DBG_TRACE && DBG_INIT,
  821. (DTEXT("+TCPGetConfigInfo()\n")));
  822. //
  823. // Initialize to the defaults in case an error occurs somewhere.
  824. //
  825. KAInterval = DEFAULT_KEEPALIVE_INTERVAL;
  826. KeepAliveTime = DEFAULT_KEEPALIVE_TIME;
  827. PMTUDiscovery = TRUE;
  828. PMTUBHDetect = FALSE;
  829. DeadGWDetect = TRUE;
  830. DefaultRcvWin = 0; // Automagically pick a reasonable one.
  831. MaxConnections = DEFAULT_MAX_CONNECTIONS;
  832. maxConnectRexmits = MAX_CONNECT_REXMIT_CNT;
  833. maxConnectResponseRexmits = MAX_CONNECT_RESPONSE_REXMIT_CNT;
  834. pptpmaxDataRexmits = maxDataRexmits = MAX_REXMIT_CNT;
  835. BSDUrgent = TRUE;
  836. FinWait2TO = FIN_WAIT2_TO;
  837. NTWMaxConnectCount = NTW_MAX_CONNECT_COUNT;
  838. NTWMaxConnectTime = NTW_MAX_CONNECT_TIME;
  839. MaxUserPort = DEFAULT_MAX_USER_PORT;
  840. // Default number of duplicate acks
  841. MaxDupAcks = 2;
  842. SynAttackProtect = 0; //by default it is always off
  843. #if MILLEN
  844. TCPMaxPortsExhausted = 5;
  845. TCPMaxHalfOpen = 100;
  846. TCPMaxHalfOpenRetried = 80;
  847. #else // MILLEN
  848. if (!MmIsThisAnNtAsSystem()) {
  849. TCPMaxPortsExhausted = 5;
  850. TCPMaxHalfOpen = 100;
  851. TCPMaxHalfOpenRetried = 80;
  852. } else {
  853. TCPMaxPortsExhausted = 5;
  854. TCPMaxHalfOpen = 500;
  855. TCPMaxHalfOpenRetried = 400;
  856. }
  857. #endif // !MILLEN
  858. SecurityFilteringEnabled = FALSE;
  859. #ifdef ACC
  860. AllowUserRawAccess = FALSE;
  861. #endif
  862. //
  863. // Read the TCP optional (hidden) registry parameters.
  864. //
  865. #if !MILLEN
  866. RtlInitUnicodeString(
  867. &UKeyName,
  868. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
  869. );
  870. #else // !MILLEN
  871. RtlInitUnicodeString(
  872. &UKeyName,
  873. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\VxD\\MSTCP"
  874. );
  875. #endif // MILLEN
  876. DEBUGMSG(DBG_INFO && DBG_INIT,
  877. (DTEXT("TCPGetConfigInfo: Opening key %ws\n"), UKeyName.Buffer));
  878. memset(&objectAttributes, 0, sizeof(OBJECT_ATTRIBUTES));
  879. InitializeObjectAttributes(
  880. &objectAttributes,
  881. &UKeyName,
  882. OBJ_CASE_INSENSITIVE,
  883. NULL,
  884. NULL
  885. );
  886. status = ZwOpenKey(
  887. &keyHandle,
  888. KEY_READ,
  889. &objectAttributes
  890. );
  891. DEBUGMSG(!NT_SUCCESS(status) && DBG_ERROR,
  892. (DTEXT("TCPGetConfigInfo: failed to open TCP registry configuration: %ws\n"),
  893. UKeyName.Buffer));
  894. if (NT_SUCCESS(status)) {
  895. DEBUGMSG(DBG_INFO && DBG_INIT,
  896. (DTEXT("TCPGetConfigInfo: successfully opened registry to read.\n")));
  897. #if !MILLEN
  898. TCPInitializeParameter(
  899. keyHandle,
  900. L"IsnStoreSize",
  901. &g_cRandIsnStore
  902. );
  903. #endif // !MILLEN
  904. TCPInitializeParameter(
  905. keyHandle,
  906. L"KeepAliveInterval",
  907. &KAInterval
  908. );
  909. TCPInitializeParameter(
  910. keyHandle,
  911. L"KeepAliveTime",
  912. &KeepAliveTime
  913. );
  914. status = TCPInitializeParameter(
  915. keyHandle,
  916. L"EnablePMTUBHDetect",
  917. &PMTUBHDetect
  918. );
  919. #if MILLEN
  920. //
  921. // Backwards compatibility. If 'EnablePMTUBHDetect' value does not exist,
  922. // then attempt to read legacy 'PMTUBlackHoleDetect'.
  923. //
  924. if (!NT_SUCCESS(status)) {
  925. TCPInitializeParameter(
  926. keyHandle,
  927. L"PMTUBlackHoleDetect",
  928. &PMTUBHDetect
  929. );
  930. }
  931. #endif // MILLEN
  932. status = TCPInitializeParameter(
  933. keyHandle,
  934. L"TcpWindowSize",
  935. &DefaultRcvWin
  936. );
  937. #if MILLEN
  938. //
  939. // Backwards compatibility. If 'TcpWindowSize' value does not exist,
  940. // then attempt to read legacy 'DefaultRcvWindow'.
  941. //
  942. if (!NT_SUCCESS(status)) {
  943. TCPInitializeParameter(
  944. keyHandle,
  945. L"DefaultRcvWindow",
  946. &DefaultRcvWin
  947. );
  948. }
  949. #endif // MILLEN
  950. status = TCPInitializeParameter(
  951. keyHandle,
  952. L"TcpNumConnections",
  953. &MaxConnections
  954. );
  955. #if MILLEN
  956. //
  957. // Backwards compatibility. If 'TcpNumConnections' value does not exist,
  958. // then attempt to read legacy 'MaxConnections'.
  959. //
  960. if (!NT_SUCCESS(status)) {
  961. TCPInitializeParameter(
  962. keyHandle,
  963. L"MaxConnections",
  964. &MaxConnections
  965. );
  966. }
  967. #endif // MILLEN
  968. status = TCPInitializeParameter(
  969. keyHandle,
  970. L"TcpMaxConnectRetransmissions",
  971. &maxConnectRexmits
  972. );
  973. #if MILLEN
  974. //
  975. // Backwards compatibility. If 'TcpMaxConnectRetransmissions' value does not exist,
  976. // then attempt to read legacty 'MaxConnectRetries'.
  977. //
  978. if (!NT_SUCCESS(status)) {
  979. TCPInitializeParameter(
  980. keyHandle,
  981. L"MaxConnectRetries",
  982. &maxConnectRexmits
  983. );
  984. }
  985. #endif // MILLEN
  986. if (maxConnectRexmits > 255) {
  987. maxConnectRexmits = 255;
  988. }
  989. TCPInitializeParameter(
  990. keyHandle,
  991. L"TcpMaxConnectResponseRetransmissions",
  992. &maxConnectResponseRexmits
  993. );
  994. if (maxConnectResponseRexmits > 255) {
  995. maxConnectResponseRexmits = 255;
  996. }
  997. status = TCPInitializeParameter(
  998. keyHandle,
  999. L"TcpMaxDataRetransmissions",
  1000. &maxDataRexmits
  1001. );
  1002. #if MILLEN
  1003. //
  1004. // Backwards compatibility. If 'TcpMaxDataRetransmissions' value does not exist,
  1005. // then attempt to read legacy 'MaxDataRetries'.
  1006. //
  1007. if (!NT_SUCCESS(status)) {
  1008. TCPInitializeParameter(
  1009. keyHandle,
  1010. L"MaxDataRetries",
  1011. &maxDataRexmits
  1012. );
  1013. }
  1014. #endif // MILLEN
  1015. if (maxDataRexmits > 255) {
  1016. maxDataRexmits = 255;
  1017. }
  1018. // Limit the MaxDupAcks to 3
  1019. status = TCPInitializeParameter(
  1020. keyHandle,
  1021. L"TcpMaxDupAcks",
  1022. &MaxDupAcks
  1023. );
  1024. #if MILLEN
  1025. //
  1026. // Backwards compatibility. If 'TcpMaxDupAcks' value does not exist,
  1027. // then attempt to read legacy 'MaxDupAcks'.
  1028. //
  1029. if (!NT_SUCCESS(status)) {
  1030. TCPInitializeParameter(
  1031. keyHandle,
  1032. L"MaxDupAcks",
  1033. &MaxDupAcks
  1034. );
  1035. }
  1036. #endif // MILLEN
  1037. if (MaxDupAcks > 3) {
  1038. MaxDupAcks = 3;
  1039. }
  1040. if (MaxDupAcks == 0) {
  1041. MaxDupAcks = 1;
  1042. }
  1043. #if MILLEN
  1044. MaxConnBlocks = 16;
  1045. #else // MILLEN
  1046. systemSize = MmQuerySystemSize();
  1047. if (MmIsThisAnNtAsSystem()) {
  1048. if (systemSize == MmSmallSystem) {
  1049. MaxConnBlocks = 128;
  1050. } else if (systemSize == MmMediumSystem) {
  1051. MaxConnBlocks = 256;
  1052. } else {
  1053. #if defined(_WIN64)
  1054. MaxConnBlocks = 4096;
  1055. #else
  1056. MaxConnBlocks = 1024;
  1057. #endif
  1058. }
  1059. } else {
  1060. //for workstation, small system limit default number of connections to 4K.
  1061. // medium system 8k
  1062. // Large system 32k connections
  1063. if (systemSize == MmSmallSystem) {
  1064. MaxConnBlocks = 16;
  1065. } else if (systemSize == MmMediumSystem) {
  1066. MaxConnBlocks = 32;
  1067. } else {
  1068. MaxConnBlocks = 128;
  1069. }
  1070. }
  1071. #endif // !MILLEN
  1072. #if MILLEN
  1073. NumTcbTablePartitions = 1;
  1074. #else
  1075. NumTcbTablePartitions = (KeNumberProcessors * KeNumberProcessors);
  1076. #endif
  1077. TCPInitializeParameter(
  1078. keyHandle,
  1079. L"NumTcbTablePartitions",
  1080. &NumTcbTablePartitions
  1081. );
  1082. if (NumTcbTablePartitions > (MAXIMUM_PROCESSORS * MAXIMUM_PROCESSORS)) {
  1083. NumTcbTablePartitions = (MAXIMUM_PROCESSORS * MAXIMUM_PROCESSORS);
  1084. }
  1085. NumTcbTablePartitions = ComputeLargerOrEqualPowerOfTwo(NumTcbTablePartitions);
  1086. // Default to 128 TCBs per partition
  1087. MaxHashTableSize = 128 * NumTcbTablePartitions;
  1088. TCPInitializeParameter(
  1089. keyHandle,
  1090. L"MaxHashTableSize",
  1091. &MaxHashTableSize
  1092. );
  1093. if (MaxHashTableSize < 64) {
  1094. MaxHashTableSize = 64;
  1095. } else if (MaxHashTableSize > 0xffff) {
  1096. MaxHashTableSize = 0x10000;
  1097. }
  1098. MaxHashTableSize = ComputeLargerOrEqualPowerOfTwo(MaxHashTableSize);
  1099. if (MaxHashTableSize < NumTcbTablePartitions) {
  1100. MaxHashTableSize = NumTcbTablePartitions;
  1101. }
  1102. ASSERT(IsPowerOfTwo(MaxHashTableSize));
  1103. //since hash table size is power of 2 and cache line size
  1104. //is power of 2 and number of partion is even,
  1105. //entries per partions will be power of 2 and multiple of
  1106. //cache line size.
  1107. PerPartitionSize = MaxHashTableSize / NumTcbTablePartitions;
  1108. ASSERT(IsPowerOfTwo(PerPartitionSize));
  1109. LogPerPartitionSize =
  1110. ComputeShiftForLargerOrEqualPowerOfTwo(PerPartitionSize);
  1111. TWTCBTable = CTEAllocMemBoot(MaxHashTableSize * sizeof(*TWTCBTable));
  1112. if (TWTCBTable == NULL) {
  1113. ZwClose(keyHandle);
  1114. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate tw tcb table of size %x\n", MaxHashTableSize));
  1115. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1116. return (0);
  1117. }
  1118. for (i = 0; i < MaxHashTableSize; i++)
  1119. {
  1120. INITQ(&TWTCBTable[i]);
  1121. }
  1122. TCBTable = CTEAllocMemBoot(MaxHashTableSize * sizeof(*TCBTable));
  1123. if (TCBTable == NULL) {
  1124. ExFreePool(TWTCBTable);
  1125. ZwClose(keyHandle);
  1126. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate tcb table of size %x\n", MaxHashTableSize));
  1127. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1128. return (0);
  1129. }
  1130. NdisZeroMemory(TCBTable, MaxHashTableSize * sizeof(*TCBTable));
  1131. SYNTCBTable = CTEAllocMemBoot(MaxHashTableSize * sizeof(*SYNTCBTable));
  1132. if (SYNTCBTable == NULL) {
  1133. ExFreePool(TWTCBTable);
  1134. ExFreePool(TCBTable);
  1135. ZwClose(keyHandle);
  1136. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate syn tcb table of size %x\n", MaxHashTableSize));
  1137. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1138. return (0);
  1139. }
  1140. for (i = 0; i < MaxHashTableSize; i++)
  1141. {
  1142. INITQ(&SYNTCBTable[i]);
  1143. }
  1144. pSynTCBTableLock = CTEAllocMemBoot(NumTcbTablePartitions * sizeof(CTELock));
  1145. if (pSynTCBTableLock == NULL) {
  1146. ExFreePool(TCBTable);
  1147. ExFreePool(TWTCBTable);
  1148. ExFreePool(SYNTCBTable);
  1149. ZwClose(keyHandle);
  1150. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate twtcb lock table \n"));
  1151. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1152. return (0);
  1153. }
  1154. pTWTCBTableLock = CTEAllocMemBoot(NumTcbTablePartitions * sizeof(CTELock));
  1155. if (pTWTCBTableLock == NULL) {
  1156. ExFreePool(TCBTable);
  1157. ExFreePool(TWTCBTable);
  1158. ExFreePool(SYNTCBTable);
  1159. ExFreePool(pSynTCBTableLock);
  1160. ZwClose(keyHandle);
  1161. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate twtcb lock table \n"));
  1162. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1163. return (0);
  1164. }
  1165. pTCBTableLock = CTEAllocMemBoot(NumTcbTablePartitions * sizeof(CTELock));
  1166. if (pTCBTableLock == NULL) {
  1167. ExFreePool(TCBTable);
  1168. ExFreePool(TWTCBTable);
  1169. ExFreePool(pTWTCBTableLock);
  1170. ExFreePool(SYNTCBTable);
  1171. ExFreePool(pSynTCBTableLock);
  1172. ZwClose(keyHandle);
  1173. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate tcb lock table \n"));
  1174. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1175. return (0);
  1176. }
  1177. TWQueue = CTEAllocMemBoot(NumTcbTablePartitions * sizeof(Queue));
  1178. if (TWQueue == NULL) {
  1179. ExFreePool(TCBTable);
  1180. ExFreePool(TWTCBTable);
  1181. ExFreePool(pTWTCBTableLock);
  1182. ExFreePool(SYNTCBTable);
  1183. ExFreePool(pSynTCBTableLock);
  1184. ExFreePool(pTCBTableLock);
  1185. ZwClose(keyHandle);
  1186. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate Twqueue \n"));
  1187. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1188. return (0);
  1189. }
  1190. TimerWheel = CTEAllocMemBoot(NumTcbTablePartitions * sizeof(TIMER_WHEEL) + CACHE_LINE_SIZE);
  1191. if (TimerWheel == NULL) {
  1192. ExFreePool(TCBTable);
  1193. ExFreePool(TWTCBTable);
  1194. ExFreePool(pTWTCBTableLock);
  1195. ExFreePool(SYNTCBTable);
  1196. ExFreePool(pSynTCBTableLock);
  1197. ExFreePool(pTCBTableLock);
  1198. ExFreePool(TWQueue);
  1199. ZwClose(keyHandle);
  1200. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate Twqueue \n"));
  1201. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1202. return (0);
  1203. }
  1204. OrgTimerWheel = TimerWheel;
  1205. (ULONG_PTR) TimerWheel = ((ULONG_PTR) TimerWheel + CACHE_LINE_SIZE) & CACHE_ALIGN_MASK;
  1206. for (i = 0; i < NumTcbTablePartitions; i++) {
  1207. CTEInitLock(&pTCBTableLock[i]);
  1208. CTEInitLock(&pTWTCBTableLock[i]);
  1209. CTEInitLock(&pSynTCBTableLock[i]);
  1210. INITQ(&TWQueue[i])
  1211. // Init the timer wheel
  1212. CTEInitLock(&TimerWheel[i].tw_lock);
  1213. #ifdef TIMER_TEST
  1214. TimerWheel[i].tw_starttick = 0xfffff000;
  1215. #else
  1216. TimerWheel[i].tw_starttick = 0;
  1217. #endif
  1218. for(j = 0; j < TIMER_WHEEL_SIZE; j++) {
  1219. INITQ(&TimerWheel[i].tw_timerslot[j])
  1220. }
  1221. }
  1222. if (MaxConnections != DEFAULT_MAX_CONNECTIONS) {
  1223. //make it even
  1224. MaxConnBlocks = ((MaxConnections >> 1) << 1);
  1225. //allow minimum of 1k level 1 conn blocks.
  1226. //this gives minimum of 256K connections capability
  1227. if (MaxConnBlocks < 1024) {
  1228. MaxConnBlocks = 1024;
  1229. }
  1230. }
  1231. ConnTable = CTEAllocMemBoot(MaxConnBlocks * sizeof(TCPConnBlock *));
  1232. if (ConnTable == NULL) {
  1233. ExFreePool(OrgTimerWheel);
  1234. ExFreePool(TWQueue);
  1235. ExFreePool(TCBTable);
  1236. ExFreePool(TWTCBTable);
  1237. ExFreePool(pTWTCBTableLock);
  1238. ExFreePool(pTCBTableLock);
  1239. ExFreePool(SYNTCBTable);
  1240. ExFreePool(pSynTCBTableLock);
  1241. ZwClose(keyHandle);
  1242. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not allocate ConnTable \n"));
  1243. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [failure]\n")));
  1244. return (0);
  1245. }
  1246. status = TCPInitializeParameter(
  1247. keyHandle,
  1248. L"Tcp1323Opts",
  1249. &tcp1323opts
  1250. );
  1251. if (status == STATUS_SUCCESS) {
  1252. // Check if TS and/or WS options
  1253. // are enabled.
  1254. TcpHostOpts = TCP_FLAG_WS | TCP_FLAG_TS;
  1255. if (!(tcp1323opts & TCP_FLAG_TS)) {
  1256. TcpHostOpts &= ~TCP_FLAG_TS;
  1257. }
  1258. if (!(tcp1323opts & TCP_FLAG_WS)) {
  1259. TcpHostOpts &= ~TCP_FLAG_WS;
  1260. } else {
  1261. MaxRcvWin = 0x3fffffff;
  1262. }
  1263. TcpHostSendOpts = TcpHostOpts;
  1264. } else {
  1265. TcpHostSendOpts = 0;
  1266. }
  1267. TcpHostOpts |= TCP_FLAG_SACK;
  1268. status = TCPInitializeParameter(
  1269. keyHandle,
  1270. L"SackOpts",
  1271. &SackOpts
  1272. );
  1273. if (status == STATUS_SUCCESS) {
  1274. //Check if Sack option is enabled
  1275. //If so, set it in global options variable
  1276. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Sackopts %x\n", SackOpts));
  1277. if (!SackOpts) {
  1278. TcpHostOpts &= ~TCP_FLAG_SACK;
  1279. }
  1280. }
  1281. TCPInitializeParameter(
  1282. keyHandle,
  1283. L"GlobalMaxTcpWindowSize",
  1284. &GlobalMaxRcvWin
  1285. );
  1286. TCPInitializeParameter(
  1287. keyHandle,
  1288. L"SynAttackProtect",
  1289. (unsigned long *)&SynAttackProtect
  1290. );
  1291. if (SynAttackProtect) {
  1292. TCPInitializeParameter(
  1293. keyHandle,
  1294. L"TCPMaxPortsExhausted",
  1295. &TCPMaxPortsExhausted
  1296. );
  1297. TCPMaxPortsExhaustedLW = MAX((TCPMaxPortsExhausted >> 1) + (TCPMaxPortsExhausted >> 2), 1);
  1298. TCPInitializeParameter(
  1299. keyHandle,
  1300. L"TCPMaxHalfOpen",
  1301. &TCPMaxHalfOpen
  1302. );
  1303. if (TCPMaxHalfOpen < MIN_THRESHOLD_MAX_HO) {
  1304. TCPMaxHalfOpen = MIN_THRESHOLD_MAX_HO;
  1305. }
  1306. TCPInitializeParameter(
  1307. keyHandle,
  1308. L"TCPMaxHalfOpenRetried",
  1309. &TCPMaxHalfOpenRetried
  1310. );
  1311. if ((TCPMaxHalfOpenRetried > TCPMaxHalfOpen) ||
  1312. (TCPMaxHalfOpenRetried < MIN_THRESHOLD_MAX_HO_RETRIED)) {
  1313. TCPMaxHalfOpenRetried = MIN_THRESHOLD_MAX_HO_RETRIED;
  1314. }
  1315. TCPMaxHalfOpenRetriedLW = (TCPMaxHalfOpenRetried >> 1) +
  1316. (TCPMaxHalfOpenRetried >> 2);
  1317. }
  1318. //
  1319. // If we fail, then set to same value as maxDataRexmit so that the
  1320. // max(pptpmaxDataRexmit,maxDataRexmit) is a decent value
  1321. // Need this since TCPInitializeParameter no longer "initializes"
  1322. // to a default value
  1323. //
  1324. if (TCPInitializeParameter(keyHandle,
  1325. L"PPTPTcpMaxDataRetransmissions",
  1326. &pptpmaxDataRexmits) != STATUS_SUCCESS) {
  1327. pptpmaxDataRexmits = maxDataRexmits;
  1328. }
  1329. if (pptpmaxDataRexmits > 255) {
  1330. pptpmaxDataRexmits = 255;
  1331. }
  1332. status = TCPInitializeParameter(
  1333. keyHandle,
  1334. L"TcpUseRFC1122UrgentPointer",
  1335. &useRFC1122UrgentPointer
  1336. );
  1337. #if MILLEN
  1338. //
  1339. // Backwards compatibility. If TcpUseRFC1122UrgentPointer does not exist,
  1340. // then check for BSDUrgent. These values are logical opposites.
  1341. //
  1342. if (!NT_SUCCESS(status)) {
  1343. ULONG tmpBsdUrgent = TRUE;
  1344. status = TCPInitializeParameter(
  1345. keyHandle,
  1346. L"BSDUrgent",
  1347. &tmpBsdUrgent);
  1348. if (NT_SUCCESS(status)) {
  1349. useRFC1122UrgentPointer = !tmpBsdUrgent;
  1350. }
  1351. }
  1352. #endif
  1353. if (useRFC1122UrgentPointer) {
  1354. BSDUrgent = FALSE;
  1355. }
  1356. TCPInitializeParameter(
  1357. keyHandle,
  1358. L"TcpTimedWaitDelay",
  1359. &FinWait2TO
  1360. );
  1361. if (FinWait2TO > 300) {
  1362. FinWait2TO = 300;
  1363. }
  1364. FinWait2TO = MS_TO_TICKS(FinWait2TO * 1000);
  1365. NTWMaxConnectTime = MS_TO_TICKS(NTWMaxConnectTime * 1000);
  1366. TCPInitializeParameter(
  1367. keyHandle,
  1368. L"MaxUserPort",
  1369. &MaxUserPort
  1370. );
  1371. if (MaxUserPort < 5000) {
  1372. MaxUserPort = 5000;
  1373. }
  1374. if (MaxUserPort > 65534) {
  1375. MaxUserPort = 65534;
  1376. }
  1377. GetReservedPortList(keyHandle);
  1378. //Reserve ports if
  1379. //
  1380. // Read a few IP optional (hidden) registry parameters that TCP
  1381. // cares about.
  1382. //
  1383. status = TCPInitializeParameter(
  1384. keyHandle,
  1385. L"EnablePMTUDiscovery",
  1386. &PMTUDiscovery
  1387. );
  1388. #if MILLEN
  1389. //
  1390. // Backwards compatibility. If 'EnablePMTUDiscovery' value does not exist,
  1391. // then attempt to read legacy 'PMTUDiscovery'.
  1392. //
  1393. if (!NT_SUCCESS(status)) {
  1394. TCPInitializeParameter(
  1395. keyHandle,
  1396. L"PMTUDiscovery",
  1397. &PMTUDiscovery
  1398. );
  1399. }
  1400. #endif // MILLEN
  1401. TCPInitializeParameter(
  1402. keyHandle,
  1403. L"EnableDeadGWDetect",
  1404. &DeadGWDetect
  1405. );
  1406. TCPInitializeParameter(
  1407. keyHandle,
  1408. L"EnableSecurityFilters",
  1409. &SecurityFilteringEnabled
  1410. );
  1411. #ifdef ACC
  1412. TCPInitializeParameter(
  1413. keyHandle,
  1414. L"AllowUserRawAccess",
  1415. &AllowUserRawAccess
  1416. );
  1417. #endif // ACC
  1418. status = TCPInitializeParameter(
  1419. keyHandle,
  1420. L"DefaultTOSValue",
  1421. &DefaultTOSValue
  1422. );
  1423. #if MILLEN
  1424. //
  1425. // Backwards compatibility. Read 'DefaultTOS' if 'DefaultTOSValue' is
  1426. // not present.
  1427. //
  1428. if (!NT_SUCCESS(status)) {
  1429. TCPInitializeParameter(
  1430. keyHandle,
  1431. L"DefaultTOS",
  1432. &DefaultTOSValue
  1433. );
  1434. }
  1435. #endif // MILLEN
  1436. TCPInitializeParameter(
  1437. keyHandle,
  1438. L"DisableUserTOSSetting",
  1439. &DisableUserTOSSetting
  1440. );
  1441. TCPInitializeParameter(
  1442. keyHandle,
  1443. L"MaxSendSegments",
  1444. &MaxSendSegments
  1445. );
  1446. TCPInitializeParameter(
  1447. keyHandle,
  1448. L"DisableLargeSendOffload",
  1449. &DisableLargeSendOffload
  1450. );
  1451. ZwClose(keyHandle);
  1452. }
  1453. MaxConnectRexmitCount = maxConnectRexmits;
  1454. MaxConnectResponseRexmitCount = maxConnectResponseRexmits;
  1455. MaxConnectResponseRexmitCountTmp = MaxConnectResponseRexmitCount;
  1456. //
  1457. // Use the greater of the two, hence both values should be valid
  1458. //
  1459. MaxDataRexmitCount = (maxDataRexmits > pptpmaxDataRexmits ? maxDataRexmits : pptpmaxDataRexmits);
  1460. DEBUGMSG(DBG_TRACE && DBG_INIT, (DTEXT("-TCPGetConfigInfo [SUCCESS]\n")));
  1461. return (1);
  1462. }
  1463. #define WORK_BUFFER_SIZE 256
  1464. extern NTSTATUS
  1465. GetRegDWORDValue(
  1466. HANDLE KeyHandle,
  1467. PWCHAR ValueName,
  1468. PULONG ValueData
  1469. );
  1470. NTSTATUS
  1471. TCPInitializeParameter(
  1472. HANDLE KeyHandle,
  1473. PWCHAR ValueName,
  1474. PULONG Value
  1475. )
  1476. /*++
  1477. Routine Description:
  1478. Initializes a ULONG parameter from the registry or to a default
  1479. parameter if accessing the registry value fails.
  1480. Arguments:
  1481. KeyHandle - An open handle to the registry key for the parameter.
  1482. ValueName - The UNICODE name of the registry value to read.
  1483. Value - The ULONG into which to put the data.
  1484. DefaultValue - The default to assign if reading the registry fails.
  1485. Return Value:
  1486. None.
  1487. --*/
  1488. {
  1489. return (GetRegDWORDValue(KeyHandle, ValueName, Value));
  1490. }
  1491. VOID
  1492. GetReservedPortList(
  1493. NDIS_HANDLE ConfigHandle
  1494. )
  1495. {
  1496. UNICODE_STRING PortList;
  1497. PWCHAR nextRange;
  1498. TDI_STATUS status;
  1499. PortList.Buffer = CTEAllocMemBoot(WORK_BUFFER_SIZE * sizeof(WCHAR));
  1500. if (!PortList.Buffer) {
  1501. return;
  1502. }
  1503. PortList.Buffer[0] = UNICODE_NULL;
  1504. PortList.Length = 0;
  1505. PortList.MaximumLength = WORK_BUFFER_SIZE * sizeof(WCHAR);
  1506. PortRangeList = NULL;
  1507. if (PortList.Buffer) {
  1508. NdisZeroMemory(PortList.Buffer, WORK_BUFFER_SIZE * sizeof(WCHAR));
  1509. status = GetRegMultiSZValue(
  1510. ConfigHandle,
  1511. L"ReservedPorts",
  1512. &PortList
  1513. );
  1514. if (NT_SUCCESS(status)) {
  1515. for (nextRange = PortList.Buffer;
  1516. *nextRange != L'\0';
  1517. nextRange += wcslen(nextRange) + 1) {
  1518. PWCHAR tmps = nextRange;
  1519. USHORT upval = 0, loval = 0, tmpval = 0;
  1520. BOOLEAN error = FALSE;
  1521. ReservedPortListEntry *ListEntry;
  1522. while (*tmps != L'\0') {
  1523. if (*tmps == L'-') {
  1524. tmps++;
  1525. loval = tmpval;
  1526. tmpval = 0;
  1527. }
  1528. if (*tmps >= L'0' && *tmps <= L'9') {
  1529. tmpval = tmpval * 10 + (*tmps - L'0');
  1530. } else {
  1531. error = TRUE;
  1532. break;
  1533. }
  1534. tmps++;
  1535. }
  1536. upval = tmpval;
  1537. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"loval %d upval %d\n", loval, upval));
  1538. if (!error && (loval > 0) && (upval > 0) && (loval <= upval) &&
  1539. (upval <= MaxUserPort) && (loval <= MaxUserPort)) {
  1540. ListEntry = CTEAllocMemBoot(sizeof(ReservedPortListEntry));
  1541. if (ListEntry) {
  1542. //Insert this range.
  1543. //No need to take locks
  1544. //since we are at initialization.
  1545. ListEntry->UpperRange = upval;
  1546. ListEntry->LowerRange = loval;
  1547. ListEntry->next = PortRangeList;
  1548. PortRangeList = ListEntry;
  1549. }
  1550. }
  1551. }
  1552. }
  1553. CTEFreeMem(PortList.Buffer);
  1554. }
  1555. }
  1556. TDI_STATUS
  1557. GetSecurityFilterList(
  1558. NDIS_HANDLE ConfigHandle,
  1559. ulong Protocol,
  1560. PNDIS_STRING FilterList
  1561. )
  1562. {
  1563. PWCHAR parameterName;
  1564. TDI_STATUS status;
  1565. if (Protocol == PROTOCOL_TCP) {
  1566. parameterName = L"TcpAllowedPorts";
  1567. } else if (Protocol == PROTOCOL_UDP) {
  1568. parameterName = L"UdpAllowedPorts";
  1569. } else {
  1570. parameterName = L"RawIpAllowedProtocols";
  1571. }
  1572. status = GetRegMultiSZValue(
  1573. ConfigHandle,
  1574. parameterName,
  1575. FilterList
  1576. );
  1577. if (!NT_SUCCESS(status)) {
  1578. FilterList->Length = 0;
  1579. }
  1580. return (status);
  1581. }
  1582. uint
  1583. EnumSecurityFilterValue(
  1584. PNDIS_STRING FilterList,
  1585. ulong Index,
  1586. ulong * FilterValue
  1587. )
  1588. {
  1589. PWCHAR valueString;
  1590. UNICODE_STRING unicodeString;
  1591. NTSTATUS status;
  1592. PAGED_CODE();
  1593. valueString = EnumRegMultiSz(
  1594. FilterList->Buffer,
  1595. FilterList->Length,
  1596. Index
  1597. );
  1598. if ((valueString == NULL) || (valueString[0] == UNICODE_NULL)) {
  1599. return (FALSE);
  1600. }
  1601. RtlInitUnicodeString(&unicodeString, valueString);
  1602. status = RtlUnicodeStringToInteger(&unicodeString, 0, FilterValue);
  1603. if (!(NT_SUCCESS(status))) {
  1604. TCPTRACE(("TCP: Invalid filter value %ws\n", valueString));
  1605. return (FALSE);
  1606. }
  1607. return (TRUE);
  1608. }
  1609. VOID
  1610. TCPFreeupMemory()
  1611. /*++
  1612. Routine Description:
  1613. This routine frees up the memory at the TCP layer
  1614. Arguments:
  1615. NULL
  1616. Return Value:
  1617. None.
  1618. --*/
  1619. {
  1620. CTELockHandle Handle;
  1621. PNDIS_BUFFER curTCPHeader;
  1622. TCPConnReq *tcpConnReq;
  1623. TCPRcvReq *tcpRcvReq;
  1624. TCPSendReq *tcpSendReq;
  1625. PSINGLE_LIST_ENTRY BufferLink;
  1626. Queue *QueuePtr;
  1627. TCPReq *ReqPtr;
  1628. TCB *curTCB;
  1629. //
  1630. // Walk various lists and free assoc blocks
  1631. //
  1632. // DG header list
  1633. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Freeing DG headers....\n"));
  1634. MdpDestroyPool(DgHeaderPool);
  1635. if (AddrObjTable) {
  1636. CTEFreeMem(AddrObjTable);
  1637. }
  1638. PplDestroyPool(TcbPool);
  1639. PplDestroyPool(SynTcbPool);
  1640. #ifdef ACC
  1641. if (TcpAdminSecurityDescriptor) {
  1642. ExFreePool(TcpAdminSecurityDescriptor);
  1643. }
  1644. #endif
  1645. }
  1646. VOID
  1647. TCPUnload(
  1648. IN PDRIVER_OBJECT DriverObject
  1649. )
  1650. /*++
  1651. Routine Description:
  1652. This routine cleans up the TCP layer.
  1653. Arguments:
  1654. DriverObject - Pointer to driver object created by the system.
  1655. Return Value:
  1656. None. When the function returns, the driver is unloaded.
  1657. --*/
  1658. {
  1659. NTSTATUS status;
  1660. uint i;
  1661. #if !MILLEN
  1662. //
  1663. // Deinitialize IPSEC first
  1664. //
  1665. status = IpsecDeinitialize();
  1666. #endif
  1667. //
  1668. // Shut down all timers/events
  1669. //
  1670. CTEInitBlockStrucEx(&TcpipUnloadBlock);
  1671. fTCBTimerStopping = TRUE;
  1672. for (i = 0; i < Time_Proc; i++) {
  1673. if (!CTEStopTimer(&TCBTimer[i])) {
  1674. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Could not stop TCB timer - waiting on unload event\n"));
  1675. #if !MILLEN
  1676. if (KeReadStateEvent(&(TcpipUnloadBlock.cbs_event))) {
  1677. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Event is signaled...\n"));
  1678. }
  1679. #endif // !MILLEN
  1680. (VOID) CTEBlock(&TcpipUnloadBlock);
  1681. KeClearEvent(&TcpipUnloadBlock.cbs_event);
  1682. }
  1683. }
  1684. #if GPC
  1685. //
  1686. if (hGpcClient[GPC_CF_QOS]) {
  1687. status = GpcEntries.GpcDeregisterClientHandler(hGpcClient[GPC_CF_QOS]);
  1688. hGpcClient[GPC_CF_QOS] = NULL;
  1689. }
  1690. if (hGpcClient[GPC_CF_IPSEC]) {
  1691. status = GpcEntries.GpcDeregisterClientHandler(hGpcClient[GPC_CF_IPSEC]);
  1692. hGpcClient[GPC_CF_IPSEC] = NULL;
  1693. }
  1694. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"Deregistering GPC\n"));
  1695. status = GpcDeinitialize(&GpcEntries);
  1696. #endif
  1697. //
  1698. // Clean up all residual memory
  1699. //
  1700. TCPFreeupMemory();
  1701. //
  1702. // Deregister address notifn handler with TDI
  1703. //
  1704. (void)TdiDeregisterPnPHandlers(AddressChangeHandle);
  1705. //
  1706. // Deregister our devices with TDI
  1707. //
  1708. (void)TdiDeregisterDeviceObject(TCPRegistrationHandle);
  1709. (void)TdiDeregisterDeviceObject(UDPRegistrationHandle);
  1710. (void)TdiDeregisterDeviceObject(IPRegistrationHandle);
  1711. #if TRACE_EVENT
  1712. //
  1713. // Deregister with WMI
  1714. //
  1715. IoWMIRegistrationControl(TCPDeviceObject, WMIREG_ACTION_DEREGISTER);
  1716. #endif
  1717. //
  1718. // Delete devices
  1719. //
  1720. IoDeleteDevice(TCPDeviceObject);
  1721. IoDeleteDevice(UDPDeviceObject);
  1722. IoDeleteDevice(RawIPDeviceObject);
  1723. }
  1724. #if GPC
  1725. GPC_STATUS
  1726. GPCcfInfoAddNotifyIpsec(GPC_CLIENT_HANDLE ClCtxt,
  1727. GPC_HANDLE GpcHandle,
  1728. ULONG CfInfoSize,
  1729. PVOID CfInfo,
  1730. PGPC_CLIENT_HANDLE pClInfoCxt)
  1731. {
  1732. InterlockedIncrement(&GPCcfInfo);
  1733. IF_TCPDBG(TCP_DEBUG_GPC)
  1734. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"tcpip - Cfinfo Add notification %x\n", GPCcfInfo));
  1735. InterlockedIncrement(&GpcCfCounts[GPC_CF_IPSEC]);
  1736. IF_TCPDBG(TCP_DEBUG_GPC)
  1737. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"tcpip - Cfinfo Add notification IPSEC:%x\n", GpcCfCounts[GPC_CF_IPSEC]));
  1738. return (STATUS_SUCCESS);
  1739. }
  1740. GPC_STATUS
  1741. GPCcfInfoRemoveNotifyIpsec(GPC_CLIENT_HANDLE ClCtxt,
  1742. GPC_CLIENT_HANDLE ClInfoCxt)
  1743. {
  1744. InterlockedDecrement(&GPCcfInfo);
  1745. IF_TCPDBG(TCP_DEBUG_GPC)
  1746. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"tcpip - Cfinfo remove notification %x\n", GPCcfInfo));
  1747. InterlockedDecrement(&GpcCfCounts[GPC_CF_IPSEC]);
  1748. IF_TCPDBG(TCP_DEBUG_GPC)
  1749. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"tcpip - Cfinfo Add notification IPSEC: %x\n", GpcCfCounts[GPC_CF_IPSEC]));
  1750. return (STATUS_SUCCESS);
  1751. }
  1752. GPC_STATUS
  1753. GPCcfInfoAddNotifyQoS(GPC_CLIENT_HANDLE ClCtxt,
  1754. GPC_HANDLE GpcHandle,
  1755. ULONG CfInfoSize,
  1756. PVOID CfInfo,
  1757. PGPC_CLIENT_HANDLE pClInfoCxt)
  1758. {
  1759. InterlockedIncrement(&GPCcfInfo);
  1760. IF_TCPDBG(TCP_DEBUG_GPC)
  1761. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"tcpip - Cfinfo Add notification %x\n", GPCcfInfo));
  1762. InterlockedIncrement(&GpcCfCounts[GPC_CF_QOS]);
  1763. IF_TCPDBG(TCP_DEBUG_GPC)
  1764. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"tcpip - Cfinfo Add notification QOS: %x\n", GpcCfCounts[GPC_CF_QOS]));
  1765. return (STATUS_SUCCESS);
  1766. }
  1767. GPC_STATUS
  1768. GPCcfInfoRemoveNotifyQoS(GPC_CLIENT_HANDLE ClCtxt,
  1769. GPC_CLIENT_HANDLE ClInfoCxt)
  1770. {
  1771. InterlockedDecrement(&GPCcfInfo);
  1772. IF_TCPDBG(TCP_DEBUG_GPC)
  1773. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"tcpip - Cfinfo remove notification %x\n", GPCcfInfo));
  1774. InterlockedDecrement(&GpcCfCounts[GPC_CF_QOS]);
  1775. IF_TCPDBG(TCP_DEBUG_GPC)
  1776. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"tcpip - Cfinfo Add notification %x\n", GpcCfCounts[GPC_CF_QOS]));
  1777. return (STATUS_SUCCESS);
  1778. }
  1779. #endif
  1780. #if ACC
  1781. NTSTATUS
  1782. TcpBuildDeviceAcl(
  1783. OUT PACL * DeviceAcl
  1784. )
  1785. /*++
  1786. Routine Description:
  1787. (Lifted from AFD - AfdBuildDeviceAcl)
  1788. This routine builds an ACL which gives Administrators and LocalSystem
  1789. principals full access. All other principals have no access.
  1790. Arguments:
  1791. DeviceAcl - Output pointer to the new ACL.
  1792. Return Value:
  1793. STATUS_SUCCESS or an appropriate error code.
  1794. --*/
  1795. {
  1796. PGENERIC_MAPPING GenericMapping;
  1797. PSID AdminsSid;
  1798. PSID SystemSid;
  1799. PSID NetworkSid;
  1800. ULONG AclLength;
  1801. NTSTATUS Status;
  1802. ACCESS_MASK AccessMask = GENERIC_ALL;
  1803. PACL NewAcl;
  1804. //
  1805. // Enable access to all the globally defined SIDs
  1806. //
  1807. GenericMapping = IoGetFileObjectGenericMapping();
  1808. RtlMapGenericMask(&AccessMask, GenericMapping);
  1809. AdminsSid = SeExports->SeAliasAdminsSid;
  1810. SystemSid = SeExports->SeLocalSystemSid;
  1811. NetworkSid = SeExports->SeNetworkServiceSid;
  1812. AclLength = sizeof(ACL) +
  1813. 3 * sizeof(ACCESS_ALLOWED_ACE) +
  1814. RtlLengthSid(AdminsSid) +
  1815. RtlLengthSid(SystemSid) +
  1816. RtlLengthSid(NetworkSid) -
  1817. 3 * sizeof(ULONG);
  1818. NewAcl = CTEAllocMemBoot(AclLength);
  1819. if (NewAcl == NULL) {
  1820. return (STATUS_INSUFFICIENT_RESOURCES);
  1821. }
  1822. Status = RtlCreateAcl(NewAcl, AclLength, ACL_REVISION);
  1823. if (!NT_SUCCESS(Status)) {
  1824. CTEFreeMem(NewAcl);
  1825. return (Status);
  1826. }
  1827. Status = RtlAddAccessAllowedAce(
  1828. NewAcl,
  1829. ACL_REVISION2,
  1830. AccessMask,
  1831. AdminsSid
  1832. );
  1833. ASSERT(NT_SUCCESS(Status));
  1834. Status = RtlAddAccessAllowedAce(
  1835. NewAcl,
  1836. ACL_REVISION2,
  1837. AccessMask,
  1838. SystemSid
  1839. );
  1840. ASSERT(NT_SUCCESS(Status));
  1841. // Add acl for NetworkSid!
  1842. Status = RtlAddAccessAllowedAce(
  1843. NewAcl,
  1844. ACL_REVISION2,
  1845. AccessMask,
  1846. NetworkSid
  1847. );
  1848. ASSERT(NT_SUCCESS(Status));
  1849. *DeviceAcl = NewAcl;
  1850. return (STATUS_SUCCESS);
  1851. } // TcpBuildDeviceAcl
  1852. NTSTATUS
  1853. TcpCreateAdminSecurityDescriptor(
  1854. VOID
  1855. )
  1856. /*++
  1857. Routine Description:
  1858. (Lifted from AFD - AfdCreateAdminSecurityDescriptor)
  1859. This routine creates a security descriptor which gives access
  1860. only to Administrtors and LocalSystem. This descriptor is used
  1861. to access check raw endpoint opens and exclisive access to transport
  1862. addresses.
  1863. Arguments:
  1864. None.
  1865. Return Value:
  1866. STATUS_SUCCESS or an appropriate error code.
  1867. --*/
  1868. {
  1869. PACL rawAcl = NULL;
  1870. NTSTATUS status;
  1871. BOOLEAN memoryAllocated = FALSE;
  1872. PSECURITY_DESCRIPTOR tcpSecurityDescriptor;
  1873. ULONG tcpSecurityDescriptorLength;
  1874. CHAR buffer[SECURITY_DESCRIPTOR_MIN_LENGTH];
  1875. PSECURITY_DESCRIPTOR localSecurityDescriptor =
  1876. (PSECURITY_DESCRIPTOR) & buffer;
  1877. PSECURITY_DESCRIPTOR localTcpAdminSecurityDescriptor;
  1878. SECURITY_INFORMATION securityInformation = DACL_SECURITY_INFORMATION;
  1879. //
  1880. // Get a pointer to the security descriptor from the TCP device object.
  1881. //
  1882. status = ObGetObjectSecurity(
  1883. TCPDeviceObject,
  1884. &tcpSecurityDescriptor,
  1885. &memoryAllocated
  1886. );
  1887. if (!NT_SUCCESS(status)) {
  1888. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,
  1889. "TCP: Unable to get security descriptor, error: %x\n",
  1890. status
  1891. ));
  1892. ASSERT(memoryAllocated == FALSE);
  1893. return (status);
  1894. }
  1895. //
  1896. // Build a local security descriptor with an ACL giving only
  1897. // administrators and system access.
  1898. //
  1899. status = TcpBuildDeviceAcl(&rawAcl);
  1900. if (!NT_SUCCESS(status)) {
  1901. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"TCP: Unable to create Raw ACL, error: %x\n", status));
  1902. goto error_exit;
  1903. }
  1904. (VOID) RtlCreateSecurityDescriptor(
  1905. localSecurityDescriptor,
  1906. SECURITY_DESCRIPTOR_REVISION
  1907. );
  1908. (VOID) RtlSetDaclSecurityDescriptor(
  1909. localSecurityDescriptor,
  1910. TRUE,
  1911. rawAcl,
  1912. FALSE
  1913. );
  1914. //
  1915. // Make a copy of the TCP descriptor. This copy will be the raw descriptor.
  1916. //
  1917. tcpSecurityDescriptorLength = RtlLengthSecurityDescriptor(
  1918. tcpSecurityDescriptor
  1919. );
  1920. localTcpAdminSecurityDescriptor = ExAllocatePool(
  1921. PagedPool,
  1922. tcpSecurityDescriptorLength,
  1923. );
  1924. if (localTcpAdminSecurityDescriptor == NULL) {
  1925. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"TCP: couldn't allocate security descriptor\n"));
  1926. goto error_exit;
  1927. }
  1928. RtlMoveMemory(
  1929. localTcpAdminSecurityDescriptor,
  1930. tcpSecurityDescriptor,
  1931. tcpSecurityDescriptorLength
  1932. );
  1933. TcpAdminSecurityDescriptor = localTcpAdminSecurityDescriptor;
  1934. //
  1935. // Now apply the local descriptor to the raw descriptor.
  1936. //
  1937. status = SeSetSecurityDescriptorInfo(
  1938. NULL,
  1939. &securityInformation,
  1940. localSecurityDescriptor,
  1941. &TcpAdminSecurityDescriptor,
  1942. PagedPool,
  1943. IoGetFileObjectGenericMapping()
  1944. );
  1945. if (!NT_SUCCESS(status)) {
  1946. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"TCP: SeSetSecurity failed, %lx\n", status));
  1947. ASSERT(TcpAdminSecurityDescriptor == localTcpAdminSecurityDescriptor);
  1948. ExFreePool(TcpAdminSecurityDescriptor);
  1949. TcpAdminSecurityDescriptor = NULL;
  1950. goto error_exit;
  1951. }
  1952. if (TcpAdminSecurityDescriptor != localTcpAdminSecurityDescriptor) {
  1953. ExFreePool(localTcpAdminSecurityDescriptor);
  1954. }
  1955. status = STATUS_SUCCESS;
  1956. error_exit:
  1957. ObReleaseObjectSecurity(
  1958. tcpSecurityDescriptor,
  1959. memoryAllocated
  1960. );
  1961. if (rawAcl != NULL) {
  1962. CTEFreeMem(rawAcl);
  1963. }
  1964. return (status);
  1965. }
  1966. #endif // ACC
  1967. #if !MILLEN
  1968. NTSTATUS
  1969. IpsecInitialize(
  1970. void
  1971. )
  1972. /*++
  1973. Routine Description:
  1974. Initialize IPSEC.SYS.
  1975. Arguments:
  1976. None.
  1977. Return Value:
  1978. None.
  1979. --*/
  1980. {
  1981. UNICODE_STRING IPSECDeviceName;
  1982. IPSEC_SET_TCPIP_STATUS SetTcpipStatus;
  1983. PIRP Irp;
  1984. IO_STATUS_BLOCK StatusBlock;
  1985. KEVENT Event;
  1986. NTSTATUS status;
  1987. IPSECDeviceObject = NULL;
  1988. IPSECFileObject = NULL;
  1989. RtlInitUnicodeString(&IPSECDeviceName, DD_IPSEC_DEVICE_NAME);
  1990. //
  1991. // Keep a reference to the IPSec driver so it won't unload before us.
  1992. //
  1993. status = IoGetDeviceObjectPointer( &IPSECDeviceName,
  1994. FILE_ALL_ACCESS,
  1995. &IPSECFileObject,
  1996. &IPSECDeviceObject);
  1997. if (!NT_SUCCESS(status)) {
  1998. IPSECFileObject = NULL;
  1999. return (status);
  2000. }
  2001. SetTcpipStatus.TcpipStatus = TRUE;
  2002. SetTcpipStatus.TcpipFreeBuff = FreeIprBuff;
  2003. SetTcpipStatus.TcpipAllocBuff = IPAllocBuff;
  2004. SetTcpipStatus.TcpipGetInfo = IPGetInfo;
  2005. SetTcpipStatus.TcpipNdisRequest = IPProxyNdisRequest;
  2006. SetTcpipStatus.TcpipSetIPSecStatus = IPSetIPSecStatus;
  2007. SetTcpipStatus.TcpipSetIPSecPtr = SetIPSecPtr;
  2008. SetTcpipStatus.TcpipUnSetIPSecPtr = UnSetIPSecPtr;
  2009. SetTcpipStatus.TcpipUnSetIPSecSendPtr = UnSetIPSecSendPtr;
  2010. SetTcpipStatus.TcpipTCPXsum = tcpxsum;
  2011. KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
  2012. Irp = IoBuildDeviceIoControlRequest( IOCTL_IPSEC_SET_TCPIP_STATUS,
  2013. IPSECDeviceObject,
  2014. &SetTcpipStatus,
  2015. sizeof(IPSEC_SET_TCPIP_STATUS),
  2016. NULL,
  2017. 0,
  2018. FALSE,
  2019. &Event,
  2020. &StatusBlock);
  2021. if (Irp) {
  2022. status = IoCallDriver(IPSECDeviceObject, Irp);
  2023. if (status == STATUS_PENDING) {
  2024. KeWaitForSingleObject( &Event,
  2025. Executive,
  2026. KernelMode,
  2027. FALSE,
  2028. NULL);
  2029. status = StatusBlock.Status;
  2030. }
  2031. } else {
  2032. status = STATUS_INSUFFICIENT_RESOURCES;
  2033. }
  2034. return (status);
  2035. }
  2036. NTSTATUS
  2037. IpsecDeinitialize(
  2038. void
  2039. )
  2040. /*++
  2041. Routine Description:
  2042. Deinitialize IPSEC.SYS.
  2043. Arguments:
  2044. None.
  2045. Return Value:
  2046. None.
  2047. --*/
  2048. {
  2049. IPSEC_SET_TCPIP_STATUS SetTcpipStatus;
  2050. PIRP Irp;
  2051. IO_STATUS_BLOCK StatusBlock;
  2052. KEVENT Event;
  2053. NTSTATUS status;
  2054. if (!IPSECFileObject) {
  2055. return (STATUS_SUCCESS);
  2056. }
  2057. RtlZeroMemory(&SetTcpipStatus, sizeof(IPSEC_SET_TCPIP_STATUS));
  2058. KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
  2059. Irp = IoBuildDeviceIoControlRequest( IOCTL_IPSEC_SET_TCPIP_STATUS,
  2060. IPSECDeviceObject,
  2061. &SetTcpipStatus,
  2062. sizeof(IPSEC_SET_TCPIP_STATUS),
  2063. NULL,
  2064. 0,
  2065. FALSE,
  2066. &Event,
  2067. &StatusBlock);
  2068. if (Irp) {
  2069. status = IoCallDriver(IPSECDeviceObject, Irp);
  2070. if (status == STATUS_PENDING) {
  2071. KeWaitForSingleObject( &Event,
  2072. Executive,
  2073. KernelMode,
  2074. FALSE,
  2075. NULL);
  2076. status = StatusBlock.Status;
  2077. }
  2078. } else {
  2079. status = STATUS_INSUFFICIENT_RESOURCES;
  2080. }
  2081. ObDereferenceObject(IPSECFileObject);
  2082. IPSECFileObject = NULL;
  2083. return (status);
  2084. }
  2085. NTSTATUS
  2086. AddNetConfigOpsAce(IN PACL Dacl,
  2087. OUT PACL * DeviceAcl
  2088. )
  2089. /*++
  2090. Routine Description:
  2091. This routine builds an ACL which gives adds the Network Configuration Operators group
  2092. to the principals allowed to control the driver.
  2093. Arguments:
  2094. Dacl - Existing DACL.
  2095. DeviceAcl - Output pointer to the new ACL.
  2096. Return Value:
  2097. STATUS_SUCCESS or an appropriate error code.
  2098. --*/
  2099. {
  2100. PGENERIC_MAPPING GenericMapping;
  2101. PSID AdminsSid = NULL;
  2102. PSID SystemSid = NULL;
  2103. PSID NetworkSid = NULL;
  2104. PSID NetConfigOpsSid = NULL;
  2105. ULONG AclLength;
  2106. NTSTATUS Status;
  2107. ACCESS_MASK AccessMask = GENERIC_ALL;
  2108. PACL NewAcl = NULL;
  2109. ULONG SidSize;
  2110. SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
  2111. PISID ISid;
  2112. PACCESS_ALLOWED_ACE AceTemp;
  2113. int i;
  2114. //
  2115. // Enable access to all the globally defined SIDs
  2116. //
  2117. GenericMapping = IoGetFileObjectGenericMapping();
  2118. RtlMapGenericMask(&AccessMask, GenericMapping);
  2119. AdminsSid = SeExports->SeAliasAdminsSid;
  2120. SystemSid = SeExports->SeLocalSystemSid;
  2121. NetworkSid = SeExports->SeNetworkServiceSid;
  2122. SidSize = RtlLengthRequiredSid(3);
  2123. NetConfigOpsSid = (PSID)(CTEAllocMemBoot(SidSize));
  2124. if (NULL == NetConfigOpsSid) {
  2125. return STATUS_INSUFFICIENT_RESOURCES;
  2126. }
  2127. Status = RtlInitializeSid(NetConfigOpsSid, &sidAuth, 2);
  2128. if (Status != STATUS_SUCCESS) {
  2129. goto clean_up;
  2130. }
  2131. ISid = (PISID)(NetConfigOpsSid);
  2132. ISid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
  2133. ISid->SubAuthority[1] = DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS;
  2134. AclLength = Dacl->AclSize;
  2135. AclLength += sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - 2 * sizeof(ULONG);
  2136. AclLength += RtlLengthSid(NetConfigOpsSid);
  2137. NewAcl = CTEAllocMemBoot(AclLength);
  2138. if (NewAcl == NULL) {
  2139. Status = STATUS_INSUFFICIENT_RESOURCES;
  2140. goto clean_up;
  2141. }
  2142. Status = RtlCreateAcl(NewAcl, AclLength, ACL_REVISION2);
  2143. if (!NT_SUCCESS(Status)) {
  2144. goto clean_up;
  2145. }
  2146. for (i = 0; i < Dacl->AceCount; i++) {
  2147. Status = RtlGetAce(Dacl, i, &AceTemp);
  2148. if (NT_SUCCESS(Status)) {
  2149. Status = RtlAddAccessAllowedAce(NewAcl,
  2150. ACL_REVISION2,
  2151. AceTemp->Mask,
  2152. &AceTemp->SidStart);
  2153. }
  2154. if (!NT_SUCCESS(Status)) {
  2155. goto clean_up;
  2156. }
  2157. }
  2158. // Add Net Config Operators Ace
  2159. Status = RtlAddAccessAllowedAce(NewAcl,
  2160. ACL_REVISION2,
  2161. AccessMask,
  2162. NetConfigOpsSid);
  2163. if (!NT_SUCCESS(Status)) {
  2164. goto clean_up;
  2165. }
  2166. *DeviceAcl = NewAcl;
  2167. clean_up:
  2168. if (NetConfigOpsSid) {
  2169. CTEFreeMem(NetConfigOpsSid);
  2170. }
  2171. if (!NT_SUCCESS(Status) && NewAcl) {
  2172. CTEFreeMem(NewAcl);
  2173. }
  2174. return (Status);
  2175. }
  2176. NTSTATUS
  2177. CreateDeviceDriverSecurityDescriptor(PVOID DeviceOrDriverObject)
  2178. /*++
  2179. Routine Description:
  2180. Creates the SD responsible for giving access to different users.
  2181. Arguments:
  2182. DeviceOrDriverObject - Object to which to assign the Access Rights.
  2183. Return Value:
  2184. STATUS_SUCCESS or an appropriate error code.
  2185. --*/
  2186. {
  2187. NTSTATUS status;
  2188. BOOLEAN memoryAllocated = FALSE;
  2189. PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  2190. ULONG SecurityDescriptorLength;
  2191. CHAR buffer[SECURITY_DESCRIPTOR_MIN_LENGTH];
  2192. PSECURITY_DESCRIPTOR localSecurityDescriptor =
  2193. (PSECURITY_DESCRIPTOR) & buffer;
  2194. SECURITY_INFORMATION securityInformation = DACL_SECURITY_INFORMATION;
  2195. PACL Dacl = NULL;
  2196. BOOLEAN HasDacl = FALSE;
  2197. BOOLEAN DaclDefaulted = FALSE;
  2198. PACL NewAcl = NULL;
  2199. INT i;
  2200. //
  2201. // Get a pointer to the security descriptor from the driver/device object.
  2202. //
  2203. status = ObGetObjectSecurity(
  2204. DeviceOrDriverObject,
  2205. &SecurityDescriptor,
  2206. &memoryAllocated
  2207. );
  2208. if (!NT_SUCCESS(status)) {
  2209. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,
  2210. "TCP: Unable to get security descriptor, error: %x\n",
  2211. status
  2212. ));
  2213. ASSERT(memoryAllocated == FALSE);
  2214. return (status);
  2215. }
  2216. status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, &HasDacl, &Dacl, &DaclDefaulted);
  2217. if (NT_SUCCESS(status) && HasDacl)
  2218. {
  2219. status = AddNetConfigOpsAce(Dacl, &NewAcl);
  2220. if (NT_SUCCESS(status)) {
  2221. PSECURITY_DESCRIPTOR SecDesc = NULL;
  2222. ULONG SecDescSize = 0;
  2223. PACL AbsDacl = NULL;
  2224. ULONG DaclSize = 0;
  2225. PACL AbsSacl = NULL;
  2226. ULONG ulSacl = 0;
  2227. PSID Owner = NULL;
  2228. ULONG OwnerSize = 0;
  2229. PSID PrimaryGroup = NULL;
  2230. ULONG PrimaryGroupSize = 0;
  2231. BOOLEAN OwnerDefault = FALSE;
  2232. BOOLEAN GroupDefault = FALSE;
  2233. BOOLEAN HasSacl = FALSE;
  2234. BOOLEAN SaclDefaulted = FALSE;
  2235. SECURITY_INFORMATION secInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
  2236. SecDescSize = sizeof(SecDesc) + NewAcl->AclSize;
  2237. SecDesc = CTEAllocMemBoot(SecDescSize);
  2238. if (SecDesc) {
  2239. DaclSize = NewAcl->AclSize;
  2240. AbsDacl = CTEAllocMemBoot(DaclSize);
  2241. if (AbsDacl) {
  2242. status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, &Owner, &OwnerDefault);
  2243. if (NT_SUCCESS(status)) {
  2244. OwnerSize = RtlLengthSid(Owner);
  2245. status = RtlGetGroupSecurityDescriptor(SecurityDescriptor, &PrimaryGroup, &GroupDefault);
  2246. if (NT_SUCCESS(status)) {
  2247. PrimaryGroupSize = RtlLengthSid(PrimaryGroup);
  2248. status = RtlGetSaclSecurityDescriptor(SecurityDescriptor, &HasSacl, &AbsSacl, &SaclDefaulted);
  2249. if (NT_SUCCESS(status)) {
  2250. if (HasSacl) {
  2251. ulSacl = AbsSacl->AclSize;
  2252. secInfo |= SACL_SECURITY_INFORMATION;
  2253. }
  2254. status = RtlSelfRelativeToAbsoluteSD(SecurityDescriptor, SecDesc, &SecDescSize, AbsDacl,
  2255. &DaclSize, AbsSacl, &ulSacl, Owner, &OwnerSize, PrimaryGroup, &PrimaryGroupSize);
  2256. if (NT_SUCCESS(status)) {
  2257. status = RtlSetDaclSecurityDescriptor(SecDesc, TRUE, NewAcl, FALSE);
  2258. if (NT_SUCCESS(status)) {
  2259. status = ObSetSecurityObjectByPointer(DeviceOrDriverObject, secInfo, SecDesc);
  2260. }
  2261. }
  2262. }
  2263. }
  2264. } else {
  2265. status = STATUS_INSUFFICIENT_RESOURCES;
  2266. }
  2267. } else {
  2268. status = STATUS_INSUFFICIENT_RESOURCES;
  2269. }
  2270. if (SecDesc) {
  2271. // Since this is a Self-Relative security descriptor, freeing it also frees
  2272. // Owner and PrimaryGroup.
  2273. CTEFreeMem(SecDesc);
  2274. }
  2275. if (AbsDacl) {
  2276. CTEFreeMem(AbsDacl);
  2277. }
  2278. }
  2279. if (NewAcl) {
  2280. CTEFreeMem(NewAcl);
  2281. }
  2282. }
  2283. } else {
  2284. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_INFO_LEVEL,"TCP: No Dacl: %x\n", status));
  2285. }
  2286. ObReleaseObjectSecurity(
  2287. SecurityDescriptor,
  2288. memoryAllocated
  2289. );
  2290. return (status);
  2291. }
  2292. //
  2293. // Function: IsRunningOnPersonal
  2294. //
  2295. // Purpose: Determines whether running on Whistler Personal
  2296. //
  2297. // Returns: Returns true if running on Personal - FALSE otherwise
  2298. BOOLEAN
  2299. IsRunningOnPersonal(
  2300. VOID
  2301. )
  2302. {
  2303. OSVERSIONINFOEXW OsVer = {0};
  2304. ULONGLONG ConditionMask = 0;
  2305. BOOLEAN IsPersonal = TRUE;
  2306. OsVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  2307. OsVer.wSuiteMask = VER_SUITE_PERSONAL;
  2308. OsVer.wProductType = VER_NT_WORKSTATION;
  2309. VER_SET_CONDITION(ConditionMask, VER_PRODUCT_TYPE, VER_EQUAL);
  2310. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_AND);
  2311. if (RtlVerifyVersionInfo(&OsVer, VER_PRODUCT_TYPE | VER_SUITENAME,
  2312. ConditionMask) == STATUS_REVISION_MISMATCH) {
  2313. IsPersonal = FALSE;
  2314. }
  2315. return IsPersonal;
  2316. }
  2317. #endif