[SHELL32] Fix Control_RunDLLW (#5400)
[reactos.git] / drivers / network / tcpip / tcpip / main.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/main.c
5 * PURPOSE: Driver entry point
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11 #include "precomp.h"
12
13 #include <ntifs.h>
14 #include <ndk/rtlfuncs.h>
15 #include <ndk/obfuncs.h>
16
17 #include <dispatch.h>
18 #include <fileobjs.h>
19
20 PDEVICE_OBJECT TCPDeviceObject = NULL;
21 PDEVICE_OBJECT UDPDeviceObject = NULL;
22 PDEVICE_OBJECT IPDeviceObject = NULL;
23 PDEVICE_OBJECT RawIPDeviceObject = NULL;
24 NDIS_HANDLE GlobalPacketPool = NULL;
25 NDIS_HANDLE GlobalBufferPool = NULL;
26 KSPIN_LOCK EntityListLock;
27 TDIEntityInfo *EntityList = NULL;
28 ULONG EntityCount = 0;
29 ULONG EntityMax = 0;
30 UDP_STATISTICS UDPStats;
31
32 /* Network timers */
33 KTIMER IPTimer;
34 KDPC IPTimeoutDpc;
35
36 VOID TiWriteErrorLog(
37 PDRIVER_OBJECT DriverContext,
38 NTSTATUS ErrorCode,
39 ULONG UniqueErrorValue,
40 NTSTATUS FinalStatus,
41 PWSTR String,
42 ULONG DumpDataCount,
43 PULONG DumpData)
44 /*
45 * FUNCTION: Writes an error log entry
46 * ARGUMENTS:
47 * DriverContext = Pointer to the driver or device object
48 * ErrorCode = An error code to put in the log entry
49 * UniqueErrorValue = UniqueErrorValue in the error log packet
50 * FinalStatus = FinalStatus in the error log packet
51 * String = If not NULL, a pointer to a string to put in log
52 * entry
53 * DumpDataCount = Number of ULONGs of dump data
54 * DumpData = Pointer to dump data for the log entry
55 */
56 {
57 PIO_ERROR_LOG_PACKET LogEntry;
58 UCHAR EntrySize;
59 ULONG StringSize;
60 PUCHAR pString;
61 static WCHAR DriverName[] = L"TCP/IP";
62
63 EntrySize = sizeof(IO_ERROR_LOG_PACKET) +
64 (DumpDataCount * sizeof(ULONG)) + sizeof(DriverName);
65
66 if (String) {
67 StringSize = (wcslen(String) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
68 EntrySize += (UCHAR)StringSize;
69 }
70
71 /* Fail if the required error log entry is too large */
72 if (EntrySize > ERROR_LOG_MAXIMUM_SIZE)
73 return;
74
75 LogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(DriverContext, EntrySize);
76 if (!LogEntry)
77 return;
78
79 LogEntry->MajorFunctionCode = -1;
80 LogEntry->RetryCount = -1;
81 LogEntry->DumpDataSize = (USHORT)(DumpDataCount * sizeof(ULONG));
82 LogEntry->NumberOfStrings = (String == NULL) ? 1 : 2;
83 LogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET) + (DumpDataCount * sizeof(ULONG));
84 LogEntry->EventCategory = 0;
85 LogEntry->ErrorCode = ErrorCode;
86 LogEntry->UniqueErrorValue = UniqueErrorValue;
87 LogEntry->FinalStatus = FinalStatus;
88 LogEntry->SequenceNumber = -1;
89 LogEntry->IoControlCode = 0;
90
91 if (DumpDataCount)
92 RtlCopyMemory(LogEntry->DumpData, DumpData, DumpDataCount * sizeof(ULONG));
93
94 pString = ((PUCHAR)LogEntry) + LogEntry->StringOffset;
95 RtlCopyMemory(pString, DriverName, sizeof(DriverName));
96 pString += sizeof(DriverName);
97
98 if (String)
99 RtlCopyMemory(pString, String, StringSize);
100
101 IoWriteErrorLogEntry(LogEntry);
102 }
103
104 /*
105 * FUNCTION: Creates a file object
106 * ARGUMENTS:
107 * DeviceObject = Pointer to a device object for this driver
108 * Irp = Pointer to a I/O request packet
109 * RETURNS:
110 * Status of the operation
111 */
112
113 NTSTATUS TiCreateFileObject(
114 PDEVICE_OBJECT DeviceObject,
115 PIRP Irp)
116 {
117 PFILE_FULL_EA_INFORMATION EaInfo;
118 PTRANSPORT_CONTEXT Context;
119 PIO_STACK_LOCATION IrpSp;
120 PTA_IP_ADDRESS Address;
121 TDI_REQUEST Request;
122 PVOID ClientContext;
123 NTSTATUS Status;
124 ULONG Protocol;
125 BOOLEAN Shared;
126
127 TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
128
129 EaInfo = Irp->AssociatedIrp.SystemBuffer;
130
131 /* Parameter check */
132 /* No EA information means that we're opening for SET/QUERY_INFORMATION
133 * style calls. */
134
135 /* Allocate resources here. We release them again if something failed */
136 Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSPORT_CONTEXT),
137 TRANS_CONTEXT_TAG);
138 if (!Context)
139 {
140 TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
141 return STATUS_INSUFFICIENT_RESOURCES;
142 }
143
144 Context->CancelIrps = FALSE;
145
146 IrpSp = IoGetCurrentIrpStackLocation(Irp);
147 IrpSp->FileObject->FsContext = Context;
148 Request.RequestContext = Irp;
149
150 /* Branch to the right handler */
151 if (EaInfo &&
152 (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) &&
153 (RtlCompareMemory(&EaInfo->EaName, TdiTransportAddress,
154 TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH))
155 {
156 /* This is a request to open an address */
157
158
159 /* XXX This should probably be done in IoCreateFile() */
160 /* Parameter checks */
161
162 Address = (PTA_IP_ADDRESS)(EaInfo->EaName + EaInfo->EaNameLength + 1); //0-term
163
164 if ((EaInfo->EaValueLength < sizeof(TA_IP_ADDRESS)) ||
165 (Address->TAAddressCount != 1) ||
166 (Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
167 (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP))
168 {
169 TI_DbgPrint(MIN_TRACE, ("Parameters are invalid:\n"));
170 TI_DbgPrint(MIN_TRACE, ("AddressCount: %d\n", Address->TAAddressCount));
171 if( Address->TAAddressCount == 1 )
172 {
173 TI_DbgPrint(MIN_TRACE, ("AddressLength: %u\n",
174 Address->Address[0].AddressLength));
175 TI_DbgPrint(MIN_TRACE, ("AddressType: %u\n",
176 Address->Address[0].AddressType));
177 }
178
179 ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
180 return STATUS_INVALID_PARAMETER;
181 }
182
183 /* Open address file object */
184
185 /* Protocol depends on device object so find the protocol */
186 if (DeviceObject == TCPDeviceObject)
187 Protocol = IPPROTO_TCP;
188 else if (DeviceObject == UDPDeviceObject)
189 Protocol = IPPROTO_UDP;
190 else if (DeviceObject == IPDeviceObject)
191 Protocol = IPPROTO_RAW;
192 else if (DeviceObject == RawIPDeviceObject)
193 {
194 Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol);
195 if (!NT_SUCCESS(Status))
196 {
197 TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n"));
198 ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
199 return STATUS_INVALID_PARAMETER;
200 }
201 }
202 else
203 {
204 TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject));
205 ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
206 return STATUS_INVALID_PARAMETER;
207 }
208
209 Shared = (IrpSp->Parameters.Create.ShareAccess != 0);
210
211 Status = FileOpenAddress(&Request, Address, Protocol, Shared, NULL);
212 if (NT_SUCCESS(Status))
213 {
214 IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
215 Context->Handle.AddressHandle = Request.Handle.AddressHandle;
216 }
217
218 }
219 else if (EaInfo &&
220 (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) &&
221 (RtlCompareMemory
222 (&EaInfo->EaName, TdiConnectionContext,
223 TDI_CONNECTION_CONTEXT_LENGTH) ==
224 TDI_CONNECTION_CONTEXT_LENGTH))
225 {
226 /* This is a request to open a connection endpoint */
227
228 /* Parameter checks */
229
230 if (EaInfo->EaValueLength < sizeof(PVOID))
231 {
232 TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
233 ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
234 return STATUS_INVALID_PARAMETER;
235 }
236
237 /* Can only do connection oriented communication using TCP */
238
239 if (DeviceObject != TCPDeviceObject)
240 {
241 TI_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
242 ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
243 return STATUS_INVALID_PARAMETER;
244 }
245
246 ClientContext = *((PVOID*)(EaInfo->EaName + EaInfo->EaNameLength));
247
248 /* Open connection endpoint file object */
249
250 Status = FileOpenConnection(&Request, ClientContext);
251 if (NT_SUCCESS(Status))
252 {
253 IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONNECTION_FILE;
254 Context->Handle.ConnectionContext = Request.Handle.ConnectionContext;
255 }
256 }
257 else
258 {
259 /* This is a request to open a control connection */
260 Status = FileOpenControlChannel(&Request);
261 if (NT_SUCCESS(Status))
262 {
263 IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONTROL_CHANNEL_FILE;
264 Context->Handle.ControlChannel = Request.Handle.ControlChannel;
265 }
266 }
267
268 if (!NT_SUCCESS(Status))
269 ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
270
271 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
272
273 Irp->IoStatus.Status = Status;
274 return Status;
275 }
276
277
278 /*
279 * FUNCTION: Releases resources used by a file object
280 * ARGUMENTS:
281 * DeviceObject = Pointer to a device object for this driver
282 * Irp = Pointer to a I/O request packet
283 * RETURNS:
284 * Status of the operation
285 * NOTES:
286 * This function does not pend
287 */
288 NTSTATUS TiCloseFileObject(
289 PDEVICE_OBJECT DeviceObject,
290 PIRP Irp)
291 {
292 PIO_STACK_LOCATION IrpSp;
293 PTRANSPORT_CONTEXT Context;
294 TDI_REQUEST Request;
295 NTSTATUS Status;
296
297 IrpSp = IoGetCurrentIrpStackLocation(Irp);
298 Context = IrpSp->FileObject->FsContext;
299 if (!Context)
300 {
301 TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
302 return STATUS_INVALID_PARAMETER;
303 }
304
305 switch ((ULONG_PTR)IrpSp->FileObject->FsContext2)
306 {
307 case TDI_TRANSPORT_ADDRESS_FILE:
308 Request.Handle.AddressHandle = Context->Handle.AddressHandle;
309 Status = FileCloseAddress(&Request);
310 break;
311
312 case TDI_CONNECTION_FILE:
313 Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
314 Status = FileCloseConnection(&Request);
315 break;
316
317 case TDI_CONTROL_CHANNEL_FILE:
318 Request.Handle.ControlChannel = Context->Handle.ControlChannel;
319 Status = FileCloseControlChannel(&Request);
320 break;
321
322 default:
323 Status = STATUS_INVALID_PARAMETER;
324 break;
325 }
326
327 if (NT_SUCCESS(Status))
328 ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
329
330 Irp->IoStatus.Status = Status;
331
332 return Irp->IoStatus.Status;
333 }
334
335
336 NTSTATUS NTAPI
337 TiDispatchOpenClose(
338 IN PDEVICE_OBJECT DeviceObject,
339 IN PIRP Irp)
340 /*
341 * FUNCTION: Main dispath routine
342 * ARGUMENTS:
343 * DeviceObject = Pointer to a device object for this driver
344 * Irp = Pointer to a I/O request packet
345 * RETURNS:
346 * Status of the operation
347 */
348 {
349 PIO_STACK_LOCATION IrpSp;
350 NTSTATUS Status;
351
352 // DbgPrint("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp);
353
354 IrpSp = IoGetCurrentIrpStackLocation(Irp);
355
356 switch (IrpSp->MajorFunction) {
357 /* Open an address file, connection endpoint, or control connection */
358 case IRP_MJ_CREATE:
359 Status = TiCreateFileObject(DeviceObject, Irp);
360 break;
361
362 /* Close an address file, connection endpoint, or control connection */
363 case IRP_MJ_CLOSE:
364 Status = TiCloseFileObject(DeviceObject, Irp);
365 break;
366
367 default:
368 Status = STATUS_INVALID_DEVICE_REQUEST;
369 }
370
371 //DbgPrint("Leaving. Status is (0x%X)\n", Status);
372
373 return IRPFinish( Irp, Status );
374 }
375
376
377 NTSTATUS NTAPI
378 TiDispatchInternal(
379 PDEVICE_OBJECT DeviceObject,
380 PIRP Irp)
381 /*
382 * FUNCTION: Internal IOCTL dispatch routine
383 * ARGUMENTS:
384 * DeviceObject = Pointer to a device object for this driver
385 * Irp = Pointer to a I/O request packet
386 * RETURNS:
387 * Status of the operation
388 */
389 {
390 NTSTATUS Status;
391 BOOLEAN Complete = TRUE;
392 PIO_STACK_LOCATION IrpSp;
393
394 IrpSp = IoGetCurrentIrpStackLocation(Irp);
395
396 TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatchInternal] Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
397 DeviceObject, Irp, IrpSp->MinorFunction));
398
399 Irp->IoStatus.Status = STATUS_SUCCESS;
400 Irp->IoStatus.Information = 0;
401
402 switch (IrpSp->MinorFunction) {
403 case TDI_RECEIVE:
404 Status = DispTdiReceive(Irp);
405 Complete = FALSE;
406 break;
407
408 case TDI_RECEIVE_DATAGRAM:
409 Status = DispTdiReceiveDatagram(Irp);
410 Complete = FALSE;
411 break;
412
413 case TDI_SEND:
414 Status = DispTdiSend(Irp);
415 Complete = FALSE; /* Completed in DispTdiSend */
416 break;
417
418 case TDI_SEND_DATAGRAM:
419 Status = DispTdiSendDatagram(Irp);
420 Complete = FALSE;
421 break;
422
423 case TDI_ACCEPT:
424 Status = DispTdiAccept(Irp);
425 break;
426
427 case TDI_LISTEN:
428 Status = DispTdiListen(Irp);
429 Complete = FALSE;
430 break;
431
432 case TDI_CONNECT:
433 Status = DispTdiConnect(Irp);
434 Complete = FALSE; /* Completed by the TCP event handler */
435 break;
436
437 case TDI_DISCONNECT:
438 Status = DispTdiDisconnect(Irp);
439 Complete = FALSE;
440 break;
441
442 case TDI_ASSOCIATE_ADDRESS:
443 Status = DispTdiAssociateAddress(Irp);
444 break;
445
446 case TDI_DISASSOCIATE_ADDRESS:
447 Status = DispTdiDisassociateAddress(Irp);
448 break;
449
450 case TDI_QUERY_INFORMATION:
451 Status = DispTdiQueryInformation(DeviceObject, Irp);
452 break;
453
454 case TDI_SET_INFORMATION:
455 Status = DispTdiSetInformation(Irp);
456 break;
457
458 case TDI_SET_EVENT_HANDLER:
459 Status = DispTdiSetEventHandler(Irp);
460 break;
461
462 case TDI_ACTION:
463 Status = STATUS_SUCCESS;
464 break;
465
466 /* An unsupported IOCTL code was submitted */
467 default:
468 Status = STATUS_INVALID_DEVICE_REQUEST;
469 }
470
471 TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatchInternal] Leaving. Status = (0x%X).\n", Status));
472
473 if( Complete )
474 IRPFinish( Irp, Status );
475
476 return Status;
477 }
478
479
480 /**
481 * @brief Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
482 *
483 * @param[in] DeviceObject
484 * Pointer to a device object for this driver
485 * @param[in] Irp
486 * Pointer to a I/O request packet
487 *
488 * @return
489 * Status of the operation
490 */
491 NTSTATUS NTAPI
492 TiDispatch(
493 PDEVICE_OBJECT DeviceObject,
494 PIRP Irp)
495 {
496 NTSTATUS Status;
497 PIO_STACK_LOCATION IrpSp;
498
499 IrpSp = IoGetCurrentIrpStackLocation(Irp);
500
501 TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp));
502
503 Irp->IoStatus.Information = 0;
504
505 #if 0
506 Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
507 if (NT_SUCCESS(Status))
508 {
509 TiDispatchInternal(DeviceObject, Irp);
510 Status = STATUS_PENDING;
511 }
512 else
513 {
514 #else
515 if (TRUE) {
516 #endif
517 /* See if this request is TCP/IP specific */
518 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
519 {
520 case IOCTL_TCP_QUERY_INFORMATION_EX:
521 TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
522 Status = DispTdiQueryInformationEx(Irp, IrpSp);
523 break;
524
525 case IOCTL_TCP_SET_INFORMATION_EX:
526 TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
527 Status = DispTdiSetInformationEx(Irp, IrpSp);
528 break;
529
530 case IOCTL_SET_IP_ADDRESS:
531 TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
532 Status = DispTdiSetIPAddress(Irp, IrpSp);
533 break;
534
535 case IOCTL_DELETE_IP_ADDRESS:
536 TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
537 Status = DispTdiDeleteIPAddress(Irp, IrpSp);
538 break;
539
540 case IOCTL_QUERY_IP_HW_ADDRESS:
541 TI_DbgPrint(MIN_TRACE, ("QUERY_IP_HW_ADDRESS\n"));
542 Status = DispTdiQueryIpHwAddress(DeviceObject, Irp, IrpSp);
543 break;
544
545 case IOCTL_ICMP_ECHO_REQUEST:
546 TI_DbgPrint(MIN_TRACE, ("ICMP_ECHO_REQUEST\n"));
547 Status = DispEchoRequest(DeviceObject, Irp, IrpSp);
548 break;
549
550 default:
551 TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
552 IrpSp->Parameters.DeviceIoControl.IoControlCode));
553 Status = STATUS_NOT_IMPLEMENTED;
554 break;
555 }
556 }
557
558 TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status));
559
560 return IRPFinish(Irp, Status);
561 }
562
563 static
564 NTSTATUS TiCreateSecurityDescriptor(
565 _Out_ PSECURITY_DESCRIPTOR *SecurityDescriptor)
566 {
567 NTSTATUS Status;
568 SECURITY_DESCRIPTOR AbsSD;
569 ULONG DaclSize, RelSDSize = 0;
570 PSECURITY_DESCRIPTOR RelSD = NULL;
571 PACL Dacl = NULL;
572
573 /* Setup a SD */
574 Status = RtlCreateSecurityDescriptor(&AbsSD,
575 SECURITY_DESCRIPTOR_REVISION);
576 if (!NT_SUCCESS(Status))
577 {
578 TI_DbgPrint(MIN_TRACE, ("Failed to create the absolute SD (0x%X)\n", Status));
579 goto Quit;
580 }
581
582 /* Setup a DACL */
583 DaclSize = sizeof(ACL) +
584 sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeExports->SeLocalSystemSid) +
585 sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeExports->SeAliasAdminsSid) +
586 sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeExports->SeNetworkServiceSid);
587 Dacl = ExAllocatePoolWithTag(PagedPool,
588 DaclSize,
589 DEVICE_OBJ_SECURITY_TAG);
590 if (Dacl == NULL)
591 {
592 TI_DbgPrint(MIN_TRACE, ("Failed to allocate buffer heap for a DACL\n"));
593 Status = STATUS_INSUFFICIENT_RESOURCES;
594 goto Quit;
595 }
596
597 Status = RtlCreateAcl(Dacl,
598 DaclSize,
599 ACL_REVISION);
600 if (!NT_SUCCESS(Status))
601 {
602 TI_DbgPrint(MIN_TRACE, ("Failed to create a DACL (0x%X)\n", Status));
603 goto Quit;
604 }
605
606 /* Setup access */
607 Status = RtlAddAccessAllowedAce(Dacl,
608 ACL_REVISION,
609 GENERIC_ALL,
610 SeExports->SeLocalSystemSid);
611 if (!NT_SUCCESS(Status))
612 {
613 TI_DbgPrint(MIN_TRACE, ("Failed to add access allowed ACE for System SID (0x%X)\n", Status));
614 goto Quit;
615 }
616
617 Status = RtlAddAccessAllowedAce(Dacl,
618 ACL_REVISION,
619 GENERIC_ALL,
620 SeExports->SeAliasAdminsSid);
621 if (!NT_SUCCESS(Status))
622 {
623 TI_DbgPrint(MIN_TRACE, ("Failed to add access allowed ACE for Admins SID (0x%X)\n", Status));
624 goto Quit;
625 }
626
627 Status = RtlAddAccessAllowedAce(Dacl,
628 ACL_REVISION,
629 GENERIC_ALL,
630 SeExports->SeNetworkServiceSid);
631 if (!NT_SUCCESS(Status))
632 {
633 TI_DbgPrint(MIN_TRACE, ("Failed to add access allowed ACE for Network Service SID (0x%X)\n", Status));
634 goto Quit;
635 }
636
637 /* Assign security data to SD */
638 Status = RtlSetDaclSecurityDescriptor(&AbsSD,
639 TRUE,
640 Dacl,
641 FALSE);
642 if (!NT_SUCCESS(Status))
643 {
644 TI_DbgPrint(MIN_TRACE, ("Failed to set DACL to security descriptor (0x%X)\n", Status));
645 goto Quit;
646 }
647
648 Status = RtlSetGroupSecurityDescriptor(&AbsSD,
649 SeExports->SeLocalSystemSid,
650 FALSE);
651 if (!NT_SUCCESS(Status))
652 {
653 TI_DbgPrint(MIN_TRACE, ("Failed to set group to security descriptor (0x%X)\n", Status));
654 goto Quit;
655 }
656
657 Status = RtlSetOwnerSecurityDescriptor(&AbsSD,
658 SeExports->SeAliasAdminsSid,
659 FALSE);
660 if (!NT_SUCCESS(Status))
661 {
662 TI_DbgPrint(MIN_TRACE, ("Failed to set owner to security descriptor (0x%X)\n", Status));
663 goto Quit;
664 }
665
666 /* Get the required buffer size for the self-relative SD */
667 Status = RtlAbsoluteToSelfRelativeSD(&AbsSD,
668 NULL,
669 &RelSDSize);
670 if (Status != STATUS_BUFFER_TOO_SMALL)
671 {
672 TI_DbgPrint(MIN_TRACE, ("Expected STATUS_BUFFER_TOO_SMALL but got something else (0x%X)\n", Status));
673 goto Quit;
674 }
675
676 RelSD = ExAllocatePoolWithTag(PagedPool,
677 RelSDSize,
678 DEVICE_OBJ_SECURITY_TAG);
679 if (RelSD == NULL)
680 {
681 TI_DbgPrint(MIN_TRACE, ("Failed to allocate buffer heap for relative SD\n"));
682 Status = STATUS_INSUFFICIENT_RESOURCES;
683 goto Quit;
684 }
685
686 /* Convert it now */
687 Status = RtlAbsoluteToSelfRelativeSD(&AbsSD,
688 RelSD,
689 &RelSDSize);
690 if (!NT_SUCCESS(Status))
691 {
692 TI_DbgPrint(MIN_TRACE, ("Failed to convert absolute SD into a relative SD (0x%X)\n", Status));
693 goto Quit;
694 }
695
696 /* Give the buffer to caller */
697 *SecurityDescriptor = RelSD;
698
699 Quit:
700 if (!NT_SUCCESS(Status))
701 {
702 if (RelSD != NULL)
703 {
704 ExFreePoolWithTag(RelSD, DEVICE_OBJ_SECURITY_TAG);
705 }
706 }
707
708 if (Dacl != NULL)
709 {
710 ExFreePoolWithTag(Dacl, DEVICE_OBJ_SECURITY_TAG);
711 }
712
713 return Status;
714 }
715
716 static
717 NTSTATUS TiSetupTcpDeviceSD(
718 _In_ PDEVICE_OBJECT DeviceObject)
719 {
720 NTSTATUS Status;
721 PSECURITY_DESCRIPTOR Sd;
722 SECURITY_INFORMATION Info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
723
724 /* Obtain a security descriptor */
725 Status = TiCreateSecurityDescriptor(&Sd);
726 if (!NT_SUCCESS(Status))
727 {
728 TI_DbgPrint(MIN_TRACE, ("Failed to create a security descriptor for the device object\n"));
729 return Status;
730 }
731
732 /* Whack the new descriptor into the TCP device object */
733 Status = ObSetSecurityObjectByPointer(DeviceObject,
734 Info,
735 Sd);
736 if (!NT_SUCCESS(Status))
737 {
738 TI_DbgPrint(MIN_TRACE, ("Failed to set new security information to the device object\n"));
739 }
740
741 ExFreePoolWithTag(Sd, DEVICE_OBJ_SECURITY_TAG);
742 return Status;
743 }
744
745 static
746 NTSTATUS TiSecurityStartup(
747 VOID)
748 {
749 NTSTATUS Status;
750
751 /* Set security data for the TCP and IP device objects */
752 Status = TiSetupTcpDeviceSD(TCPDeviceObject);
753 if (!NT_SUCCESS(Status))
754 {
755 TI_DbgPrint(MIN_TRACE, ("Failed to set security data for TCP device object\n"));
756 return Status;
757 }
758
759 Status = TiSetupTcpDeviceSD(IPDeviceObject);
760 if (!NT_SUCCESS(Status))
761 {
762 TI_DbgPrint(MIN_TRACE, ("Failed to set security data for IP device object\n"));
763 return Status;
764 }
765
766 return STATUS_SUCCESS;
767 }
768
769
770 VOID NTAPI TiUnload(
771 PDRIVER_OBJECT DriverObject)
772 /*
773 * FUNCTION: Unloads the driver
774 * ARGUMENTS:
775 * DriverObject = Pointer to driver object created by the system
776 */
777 {
778 #if DBG
779 KIRQL OldIrql;
780
781 TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
782 if (!IsListEmpty(&AddressFileListHead)) {
783 TI_DbgPrint(MIN_TRACE, ("[TCPIP, TiUnload] Called. Open address file objects exists.\n"));
784 }
785 TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
786 #endif
787 /* Cancel timer */
788 KeCancelTimer(&IPTimer);
789
790 /* Unregister loopback adapter */
791 LoopUnregisterAdapter(NULL);
792
793 /* Unregister protocol with NDIS */
794 LANUnregisterProtocol();
795
796 /* Shutdown transport level protocol subsystems */
797 TCPShutdown();
798 UDPShutdown();
799 RawIPShutdown();
800 ICMPShutdown();
801
802 /* Shutdown network level protocol subsystem */
803 IPShutdown();
804
805 /* Free NDIS buffer descriptors */
806 if (GlobalBufferPool)
807 NdisFreeBufferPool(GlobalBufferPool);
808
809 /* Free NDIS packet descriptors */
810 if (GlobalPacketPool)
811 NdisFreePacketPool(GlobalPacketPool);
812
813 /* Release all device objects */
814
815 if (TCPDeviceObject)
816 IoDeleteDevice(TCPDeviceObject);
817
818 if (UDPDeviceObject)
819 IoDeleteDevice(UDPDeviceObject);
820
821 if (RawIPDeviceObject)
822 IoDeleteDevice(RawIPDeviceObject);
823
824 if (IPDeviceObject) {
825 ChewShutdown();
826 IoDeleteDevice(IPDeviceObject);
827 }
828
829 if (EntityList)
830 ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG);
831
832 TI_DbgPrint(MAX_TRACE, ("[TCPIP, TiUnload] Leaving.\n"));
833 }
834
835 NTSTATUS NTAPI
836 DriverEntry(
837 PDRIVER_OBJECT DriverObject,
838 PUNICODE_STRING RegistryPath)
839 /*
840 * FUNCTION: Main driver entry point
841 * ARGUMENTS:
842 * DriverObject = Pointer to a driver object for this driver
843 * RegistryPath = Registry node for configuration parameters
844 * RETURNS:
845 * Status of driver initialization
846 */
847 {
848 NTSTATUS Status;
849 UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
850 UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
851 UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
852 UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
853 UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
854 NDIS_STATUS NdisStatus;
855 LARGE_INTEGER DueTime;
856
857 TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Called\n"));
858
859 /* TdiInitialize() ? */
860
861 /* FIXME: Create symbolic links in Win32 namespace */
862
863 /* Initialize our periodic timer and its associated DPC object. When the
864 timer expires, the IPTimeout deferred procedure call (DPC) is queued */
865 KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
866 KeInitializeTimer(&IPTimer);
867
868 /* Create IP device object */
869 Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
870 FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
871 if (!NT_SUCCESS(Status)) {
872 TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
873 TiUnload(DriverObject);
874 return Status;
875 }
876
877 ChewInit( IPDeviceObject );
878
879 /* Create RawIP device object */
880 Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
881 FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
882 if (!NT_SUCCESS(Status)) {
883 TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
884 TiUnload(DriverObject);
885 return Status;
886 }
887
888 /* Create UDP device object */
889 Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
890 FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
891 if (!NT_SUCCESS(Status)) {
892 TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
893 TiUnload(DriverObject);
894 return Status;
895 }
896
897 /* Create TCP device object */
898 Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
899 FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
900 if (!NT_SUCCESS(Status)) {
901 TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
902 TiUnload(DriverObject);
903 return Status;
904 }
905
906 /* Setup network layer and transport layer entities */
907 KeInitializeSpinLock(&EntityListLock);
908 EntityList = ExAllocatePoolWithTag(NonPagedPool,
909 sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
910 TDI_ENTITY_TAG );
911 if (!EntityList) {
912 TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
913 TiUnload(DriverObject);
914 return STATUS_INSUFFICIENT_RESOURCES;
915 }
916
917 EntityCount = 0;
918 EntityMax = MAX_TDI_ENTITIES;
919
920 /* Allocate NDIS packet descriptors */
921 NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
922 if (NdisStatus != NDIS_STATUS_SUCCESS) {
923 TiUnload(DriverObject);
924 return STATUS_INSUFFICIENT_RESOURCES;
925 }
926
927 /* Allocate NDIS buffer descriptors */
928 NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
929 if (NdisStatus != NDIS_STATUS_SUCCESS) {
930 TiUnload(DriverObject);
931 return STATUS_INSUFFICIENT_RESOURCES;
932 }
933
934 /* Initialize address file list and protecting spin lock */
935 InitializeListHead(&AddressFileListHead);
936 KeInitializeSpinLock(&AddressFileListLock);
937
938 /* Initialize connection endpoint list and protecting spin lock */
939 InitializeListHead(&ConnectionEndpointListHead);
940 KeInitializeSpinLock(&ConnectionEndpointListLock);
941
942 /* Initialize interface list and protecting spin lock */
943 InitializeListHead(&InterfaceListHead);
944 KeInitializeSpinLock(&InterfaceListLock);
945
946 /* Initialize network level protocol subsystem */
947 IPStartup(RegistryPath);
948
949 /* Initialize transport level protocol subsystems */
950 Status = RawIPStartup();
951 if( !NT_SUCCESS(Status) ) {
952 TiUnload(DriverObject);
953 return Status;
954 }
955
956 Status = UDPStartup();
957 if( !NT_SUCCESS(Status) ) {
958 TiUnload(DriverObject);
959 return Status;
960 }
961
962 Status = TCPStartup();
963 if( !NT_SUCCESS(Status) ) {
964 TiUnload(DriverObject);
965 return Status;
966 }
967
968 Status = ICMPStartup();
969 if( !NT_SUCCESS(Status) ) {
970 TiUnload(DriverObject);
971 return Status;
972 }
973
974 /* Initialize security */
975 Status = TiSecurityStartup();
976 if (!NT_SUCCESS(Status))
977 {
978 TiUnload(DriverObject);
979 return Status;
980 }
981
982 /* Use direct I/O */
983 IPDeviceObject->Flags |= DO_DIRECT_IO;
984 RawIPDeviceObject->Flags |= DO_DIRECT_IO;
985 UDPDeviceObject->Flags |= DO_DIRECT_IO;
986 TCPDeviceObject->Flags |= DO_DIRECT_IO;
987
988 /* Initialize the driver object with this driver's entry points */
989 DriverObject->MajorFunction[IRP_MJ_CREATE] = TiDispatchOpenClose;
990 DriverObject->MajorFunction[IRP_MJ_CLOSE] = TiDispatchOpenClose;
991 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
992 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;
993
994 DriverObject->DriverUnload = TiUnload;
995
996 /* Open loopback adapter */
997 Status = LoopRegisterAdapter(NULL, NULL);
998 if (!NT_SUCCESS(Status)) {
999 TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
1000 TiUnload(DriverObject);
1001 return Status;
1002 }
1003
1004 /* Register protocol with NDIS */
1005 /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
1006 Status = LANRegisterProtocol(&strNdisDeviceName);
1007 if (!NT_SUCCESS(Status)) {
1008 TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
1009 TiWriteErrorLog(
1010 DriverObject,
1011 EVENT_TRANSPORT_REGISTER_FAILED,
1012 TI_ERROR_DRIVERENTRY,
1013 Status,
1014 NULL,
1015 0,
1016 NULL);
1017 TiUnload(DriverObject);
1018 return Status;
1019 }
1020
1021 /* Start the periodic timer with an initial and periodic
1022 relative expiration time of IP_TIMEOUT milliseconds */
1023 DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
1024 KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);
1025
1026 TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));
1027
1028
1029 return STATUS_SUCCESS;
1030 }
1031
1032 VOID NTAPI
1033 IPAddInterface(
1034 ULONG Unknown0,
1035 ULONG Unknown1,
1036 ULONG Unknown2,
1037 ULONG Unknown3,
1038 ULONG Unknown4)
1039 {
1040 UNIMPLEMENTED;
1041 }
1042
1043
1044 VOID NTAPI
1045 IPDelInterface(
1046 ULONG Unknown0)
1047 {
1048 UNIMPLEMENTED;
1049 }
1050
1051
1052 VOID NTAPI
1053 LookupRoute(
1054 ULONG Unknown0,
1055 ULONG Unknown1)
1056 {
1057 UNIMPLEMENTED;
1058 }
1059
1060 /* EOF */