|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1990 Microsoft Corporation
4:
5: Module Name:
6:
7: packet.c
8:
9: Abstract:
10:
11:
12: Author:
13:
14:
15: Environment:
16:
17: Kernel mode only.
18:
19: Notes:
20:
21:
22: Future:
23:
24:
25:
26: Revision History:
27:
28: --*/
29:
30: #include "stdarg.h"
31: #include "ntddk.h"
32: #include "ntiologc.h"
33: #include "ndis.h"
34:
35: #include "debug.h"
36: #include "packet.h"
37:
38:
39: UINT ProtocolSupportedOids[] = {
40: OID_GEN_SUPPORTED_LIST, // 0
41: OID_GEN_HARDWARE_STATUS, // 1
42: OID_GEN_MEDIA_SUPPORTED, // 2
43: OID_GEN_MEDIA_IN_USE, // 3
44: OID_GEN_MAXIMUM_LOOKAHEAD, // 4
45: OID_GEN_MAXIMUM_FRAME_SIZE, // 5
46: OID_GEN_MAXIMUM_TOTAL_SIZE, // 6
47: OID_GEN_LINK_SPEED, // 7
48: OID_GEN_TRANSMIT_BUFFER_SPACE, // 8
49: OID_GEN_RECEIVE_BUFFER_SPACE, // 9
50: OID_GEN_TRANSMIT_BLOCK_SIZE, //10
51: OID_GEN_RECEIVE_BLOCK_SIZE, //11
52: OID_GEN_VENDOR_ID, // 2
53: OID_GEN_DRIVER_VERSION, // 3
54: OID_GEN_CURRENT_PACKET_FILTER, // 4
55: OID_GEN_CURRENT_LOOKAHEAD, // 5
56: OID_802_3_PERMANENT_ADDRESS, // 6
57: OID_802_3_CURRENT_ADDRESS, // 7
58: OID_802_3_MULTICAST_LIST, // 8
59: OID_802_3_MAXIMUM_LIST_SIZE // 9
60: };
61:
62:
63:
64:
65:
66: NTSTATUS
67: DriverEntry(
68: IN PDRIVER_OBJECT DriverObject,
69: IN PUNICODE_STRING RegistryPath
70: );
71:
72:
73:
74: NTSTATUS
75: PacketReadRegistry(
76: IN PUNICODE_STRING MacDriverName,
77: IN PUNICODE_STRING PacketDriverName,
78: IN PUNICODE_STRING RegistryPath
79: );
80:
81:
82: NTSTATUS
83: PacketCreateSymbolicLink(
84: IN PUNICODE_STRING DeviceName,
85: IN BOOLEAN Create
86: );
87:
88:
89:
90: #if DBG
91: //
92: // Declare the global debug flag for this driver.
93: //
94:
95: ULONG PacketDebugFlag = PACKET_DEBUG_LOUD;
96:
97: #endif
98:
99: PDEVICE_EXTENSION GlobalDeviceExtension;
100:
101:
102:
103: NTSTATUS
104: DriverEntry(
105: IN PDRIVER_OBJECT DriverObject,
106: IN PUNICODE_STRING RegistryPath
107: )
108:
109: /*++
110:
111: Routine Description:
112:
113: This routine initializes the Packet (i8250) mouse port driver.
114:
115: Arguments:
116:
117: DriverObject - Pointer to driver object created by system.
118:
119: RegistryPath - Pointer to the Unicode name of the registry path
120: for this driver.
121:
122: Return Value:
123:
124: The function value is the final status from the initialization operation.
125:
126: --*/
127:
128: {
129:
130: NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
131:
132: UNICODE_STRING MacDriverName;
133: UNICODE_STRING UnicodeDeviceName;
134:
135: PDEVICE_OBJECT DeviceObject = NULL;
136: PDEVICE_EXTENSION DeviceExtension = NULL;
137:
138: NTSTATUS Status = STATUS_SUCCESS;
139: NTSTATUS ErrorCode = STATUS_SUCCESS;
140: NTSTATUS FailStatus;
141: ULONG i;
142: NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver");
143:
144: PNDIS_PACKET pPacket;
145:
146: IF_LOUD(DbgPrint("\n\nPacket: DriverEntry\n");)
147:
148: //
149: // Allocate Memory for the unicode used to jold the Macdriver name
150: //
151:
152: MacDriverName.MaximumLength = 128*sizeof(WCHAR);
153: MacDriverName.Length = 0;
154: MacDriverName.Buffer = ExAllocatePool(NonPagedPool,128*sizeof(WCHAR));
155:
156: if (MacDriverName.Buffer == NULL) {
157: return STATUS_INSUFFICIENT_RESOURCES;
158: }
159:
160: //
161: // Allocate memory for the packet driver device object name
162: //
163:
164: UnicodeDeviceName.MaximumLength = 128*sizeof(WCHAR);
165: UnicodeDeviceName.Length = 0;
166: UnicodeDeviceName.Buffer = ExAllocatePool(NonPagedPool,128*sizeof(WCHAR));
167:
168: if (UnicodeDeviceName.Buffer == NULL) {
169:
170: Status= STATUS_INSUFFICIENT_RESOURCES;
171: goto Fail010;
172: }
173:
174: //
175: // Get the name of the Packet driver and the name of the MAC driver
176: // to bind to from the registry
177: //
178:
179: Status=PacketReadRegistry(
180: &MacDriverName,
181: &UnicodeDeviceName,
182: RegistryPath
183: );
184:
185: if (Status != STATUS_SUCCESS) {
186:
187: goto Fail020;
188: }
189:
190:
191: IF_LOUD(DbgPrint("Packet: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);)
192:
193:
194: //
195: // Set up the device driver entry points.
196: //
197:
198: DriverObject->MajorFunction[IRP_MJ_CREATE] = PacketOpen;
199: DriverObject->MajorFunction[IRP_MJ_CLOSE] = PacketClose;
200: DriverObject->MajorFunction[IRP_MJ_READ] = PacketRead;
201: DriverObject->MajorFunction[IRP_MJ_WRITE] = PacketWrite;
202: DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PacketCleanup;
203: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PacketIoControl;
204: DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = PacketShutdown;
205:
206: DriverObject->DriverUnload = PacketUnload;
207:
208:
209: //
210: // Create the device object
211: //
212:
213: Status = IoCreateDevice(
214: DriverObject,
215: sizeof(DEVICE_EXTENSION),
216: &UnicodeDeviceName,
217: FILE_DEVICE_PROTOCOL,
218: 0,
219: TRUE,
220: &DeviceObject
221: );
222:
223: if (Status != STATUS_SUCCESS) {
224:
225: goto Fail020;
226: }
227:
228: DeviceObject->Flags |= DO_DIRECT_IO | DO_EXCLUSIVE;
229: DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
230: DeviceExtension->DeviceObject = DeviceObject;
231:
232: IoRegisterShutdownNotification(DeviceObject);
233:
234: //
235: // Create a symbolic link for the device object so that the
236: // WIN32 app can open the device
237: //
238:
239: Status=PacketCreateSymbolicLink(&UnicodeDeviceName,TRUE);
240:
241: if (Status != STATUS_SUCCESS) {
242: IF_LOUD(DbgPrint("Packet: Failed to create dos device name\n");)
243: goto Fail030;
244: }
245:
246: //
247: // Save the the name of the MAC driver to open in the Device Extension
248: //
249:
250: DeviceExtension->DeviceName=UnicodeDeviceName;
251: DeviceExtension->AdapterName=MacDriverName;
252:
253: ProtocolChar.MajorNdisVersion = 3;
254: ProtocolChar.MinorNdisVersion = 0;
255: ProtocolChar.Reserved = 0;
256: ProtocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete;
257: ProtocolChar.CloseAdapterCompleteHandler = PacketCloseAdapterComplete;
258: ProtocolChar.SendCompleteHandler = PacketSendComplete;
259: ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete;
260: ProtocolChar.ResetCompleteHandler = PacketResetComplete;
261: ProtocolChar.RequestCompleteHandler = PacketRequestComplete;
262: ProtocolChar.ReceiveHandler = PacketReceiveIndicate;
263: ProtocolChar.ReceiveCompleteHandler = PacketReceiveComplete;
264: ProtocolChar.StatusHandler = PacketStatus;
265: ProtocolChar.StatusCompleteHandler = PacketStatusComplete;
266: ProtocolChar.Name = ProtoName;
267:
268: NdisRegisterProtocol(
269: &Status,
270: &DeviceExtension->NdisProtocolHandle,
271: &ProtocolChar,
272: sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
273:
274: if (Status != NDIS_STATUS_SUCCESS) {
275: IF_LOUD(DbgPrint("Packet: Failed to register protocol with NDIS\n");)
276: goto Fail040;
277: }
278:
279:
280:
281: //
282: // General Purpose Spinlock
283: //
284: KeInitializeSpinLock(&DeviceExtension->DeviceSpinLock);
285:
286: InitializeListHead(&DeviceExtension->ResetIrpList);
287:
288: //
289: // Initialize free packet list, Used for send packets and
290: // transfer data packets
291: //
292: KeInitializeSpinLock(&DeviceExtension->FreePacketListSpinLock);
293: InitializeListHead(&DeviceExtension->FreePacketList);
294:
295: //
296: // Initialize list for holding pending read requests
297: //
298: KeInitializeSpinLock(&DeviceExtension->RcvQSpinLock);
299: InitializeListHead(&DeviceExtension->RcvList);
300:
301: KeInitializeSpinLock(&DeviceExtension->RequestSpinLock);
302: InitializeListHead(&DeviceExtension->RequestList);
303:
304:
305:
306: for (i=0;i<MAX_REQUESTS;i++) {
307: ExInterlockedInsertTailList(
308: &DeviceExtension->RequestList,
309: &DeviceExtension->Requests[i].ListElement,
310: &DeviceExtension->RequestSpinLock);
311:
312: }
313:
314: NdisAllocatePacketPool(
315: &Status,
316: &DeviceExtension->PacketPool,
317: TRANSMIT_PACKETS,
318: sizeof(PACKET_RESERVED));
319:
320: if (Status != NDIS_STATUS_SUCCESS) {
321: IF_LOUD(DbgPrint("Packet: Failed to allocate packet pool\n");)
322: goto Fail050;
323: }
324:
325: for (i=0;i<TRANSMIT_PACKETS;i++) {
326:
327: NdisAllocatePacket(
328: &Status,
329: &pPacket,
330: DeviceExtension->PacketPool);
331:
332: ExInterlockedInsertTailList(
333: &DeviceExtension->FreePacketList,
334: &RESERVED(pPacket)->ListElement,
335: &DeviceExtension->FreePacketListSpinLock);
336:
337: }
338:
339:
340:
341:
342: return STATUS_SUCCESS;
343:
344:
345:
346:
347: Fail050:
348: NdisDeregisterProtocol(
349: &FailStatus,
350: DeviceExtension->NdisProtocolHandle
351: );
352:
353:
354: Fail040:
355:
356: PacketCreateSymbolicLink(&DeviceExtension->AdapterName,FALSE);
357:
358: Fail030:
359: IoUnregisterShutdownNotification(DeviceObject);
360: IoDeleteDevice(DeviceObject);
361:
362: Fail020:
363: ExFreePool(UnicodeDeviceName.Buffer);
364:
365: Fail010:
366: ExFreePool(MacDriverName.Buffer);
367:
368: return(Status);
369:
370: }
371:
372:
373:
374: VOID
375: PacketUnload(
376: IN PDRIVER_OBJECT DriverObject
377: )
378:
379: {
380:
381: PDEVICE_OBJECT DeviceObject;
382: PDEVICE_EXTENSION DeviceExtension;
383:
384:
385: IF_LOUD(DbgPrint("Packet: Unload\n");)
386:
387: DeviceObject = DriverObject->DeviceObject;
388:
389: DeviceExtension = DeviceObject->DeviceExtension;
390:
391: PacketCreateSymbolicLink(&DeviceExtension->DeviceName,FALSE);
392:
393: ExFreePool(DeviceExtension->AdapterName.Buffer);
394:
395: ExFreePool(DeviceExtension->DeviceName.Buffer);
396:
397: IoUnregisterShutdownNotification(DeviceObject);
398:
399:
400: IoDeleteDevice(DeviceObject);
401:
402:
403: }
404:
405:
406:
407:
408: NTSTATUS
409: PacketIoControl(
410: IN PDEVICE_OBJECT DeviceObject,
411: IN PIRP Irp
412: )
413:
414: /*++
415:
416: Routine Description:
417:
418: This is the dispatch routine for create/open and close requests.
419: These requests complete successfully.
420:
421: Arguments:
422:
423: DeviceObject - Pointer to the device object.
424:
425: Irp - Pointer to the request packet.
426:
427: Return Value:
428:
429: Status is returned.
430:
431: --*/
432:
433: {
434:
435: PIO_STACK_LOCATION IrpSp;
436: PDEVICE_EXTENSION DeviceExtension;
437: PLIST_ENTRY RequestListEntry;
438: PINTERNAL_REQUEST pRequest;
439: UINT FunctionCode;
440:
441: NDIS_STATUS Status;
442:
443: IF_LOUD(DbgPrint("Packet: IoControl\n");)
444:
445: DeviceExtension = DeviceObject->DeviceExtension;
446:
447:
448: RequestListEntry=ExInterlockedRemoveHeadList(&DeviceExtension->RequestList,
449: &DeviceExtension->RequestSpinLock);
450:
451: if (RequestListEntry == NULL) {
452: Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
453: return STATUS_UNSUCCESSFUL;
454: }
455:
456:
457: pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
458: pRequest->Irp=Irp;
459:
460:
461: IoMarkIrpPending(Irp);
462: Irp->IoStatus.Status = STATUS_PENDING;
463: IrpSp = IoGetCurrentIrpStackLocation(Irp);
464:
465: FunctionCode=(IrpSp->Parameters.DeviceIoControl.IoControlCode >> 2) & 0x00ff;
466:
467: IF_LOUD(DbgPrint("Packet: Function code is %02x buff size=%08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
468:
469: if (FunctionCode == PACKET_RESET) {
470:
471: IF_LOUD(DbgPrint("Packet: IoControl - Reset request\n");)
472:
473: ExInterlockedInsertTailList(
474: &DeviceExtension->ResetIrpList,
475: &Irp->Tail.Overlay.ListEntry,
476: &DeviceExtension->DeviceSpinLock);
477:
478:
479: NdisReset(
480: &Status,
481: DeviceExtension->AdapterHandle
482: );
483:
484:
485: if (Status != NDIS_STATUS_PENDING) {
486:
487: IF_LOUD(DbgPrint("Packet: IoControl - ResetComplte being called\n");)
488:
489: PacketResetComplete(
490: DeviceExtension,
491: Status
492: );
493:
494:
495: }
496:
497: } else {
498:
499:
500: if (FunctionCode & 0x40) {
501:
502: pRequest->Request.RequestType=NdisRequestSetInformation;
503: pRequest->Request.DATA.SET_INFORMATION.Oid=ProtocolSupportedOids[FunctionCode & 0x3f];
504:
505: pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=Irp->AssociatedIrp.SystemBuffer;
506: pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=IrpSp->Parameters.DeviceIoControl.InputBufferLength;
507:
508:
509: } else {
510:
511: pRequest->Request.RequestType=NdisRequestQueryInformation;
512: pRequest->Request.DATA.QUERY_INFORMATION.Oid=ProtocolSupportedOids[FunctionCode & 0x3f];
513:
514: pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=Irp->AssociatedIrp.SystemBuffer;
515: pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=IrpSp->Parameters.DeviceIoControl.InputBufferLength;
516:
517: }
518:
519:
520:
521: NdisRequest(
522: &Status,
523: DeviceExtension->AdapterHandle,
524: &pRequest->Request);
525:
526: if (Status != NDIS_STATUS_PENDING) {
527:
528: IF_LOUD(DbgPrint("Packet: Calling RequestCompleteHandler\n");)
529:
530: PacketRequestComplete(
531: DeviceExtension,
532: &pRequest->Request,
533: Status
534: );
535:
536:
537: }
538:
539: }
540:
541: return(STATUS_PENDING);
542:
543: }
544:
545:
546:
547:
548:
549: VOID
550: PacketRequestComplete(
551: IN NDIS_HANDLE ProtocolBindingContext,
552: IN PNDIS_REQUEST NdisRequest,
553: IN NDIS_STATUS Status
554: )
555:
556: {
557: PIO_STACK_LOCATION IrpSp;
558: PDEVICE_EXTENSION DeviceExtension;
559: PIRP Irp;
560: PINTERNAL_REQUEST pRequest;
561: UINT FunctionCode;
562:
563: IF_LOUD(DbgPrint("Packet: RequestComplete\n");)
564:
565: DeviceExtension= (PDEVICE_EXTENSION)ProtocolBindingContext;
566:
567: pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
568: Irp=pRequest->Irp;
569:
570: IrpSp = IoGetCurrentIrpStackLocation(Irp);
571:
572: FunctionCode=(IrpSp->Parameters.DeviceIoControl.IoControlCode >> 2) & 0x00ff;
573:
574:
575: if (FunctionCode & 0x40) {
576:
577: Irp->IoStatus.Information=pRequest->Request.DATA.SET_INFORMATION.BytesRead;
578:
579: } else {
580:
581: Irp->IoStatus.Information=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;
582: }
583:
584:
585: ExInterlockedInsertTailList(
586: &DeviceExtension->RequestList,
587: &pRequest->ListElement,
588: &DeviceExtension->RequestSpinLock);
589:
590:
591: Irp->IoStatus.Status = Status;
592: IoCompleteRequest(Irp, IO_NO_INCREMENT);
593:
594: return;
595:
596:
597: }
598:
599:
600:
601:
602:
603:
604:
605:
606: VOID
607: PacketStatus(
608: IN NDIS_HANDLE ProtocolBindingContext,
609: IN NDIS_STATUS Status,
610: IN PVOID StatusBuffer,
611: IN UINT StatusBufferSize
612: )
613:
614: {
615:
616: IF_LOUD(DbgPrint("Packet: Status Indication\n");)
617:
618: return;
619:
620: }
621:
622:
623:
624: VOID
625: PacketStatusComplete(
626: IN NDIS_HANDLE ProtocolBindingContext
627: )
628:
629: {
630:
631: IF_LOUD(DbgPrint("Packet: StatusIndicationComplete\n");)
632:
633: return;
634:
635: }
636:
637:
638:
639:
640:
641: NTSTATUS
642: PacketReadRegistry(
643: IN PUNICODE_STRING MacDriverName,
644: IN PUNICODE_STRING PacketDriverName,
645: IN PUNICODE_STRING RegistryPath
646: )
647:
648: {
649:
650: NTSTATUS Status;
651:
652: RTL_QUERY_REGISTRY_TABLE ParamTable[4];
653:
654: PWSTR Bind = L"Bind";
655: PWSTR Export = L"Export";
656: PWSTR Parameters = L"Parameters";
657:
658: PWCHAR Path;
659:
660:
661: Path=ExAllocatePool(
662: PagedPool,
663: RegistryPath->Length+sizeof(WCHAR)
664: );
665:
666: if (Path == NULL) {
667: return STATUS_INSUFFICIENT_RESOURCES;
668: }
669:
670: RtlZeroMemory(
671: Path,
672: RegistryPath->Length+sizeof(WCHAR)
673: );
674:
675: RtlMoveMemory(
676: Path,
677: RegistryPath->Buffer,
678: RegistryPath->Length
679: );
680:
681: IF_LOUD(DbgPrint("Packet: Reg path is %ws\n",RegistryPath->Buffer);)
682:
683: RtlZeroMemory(
684: ParamTable,
685: sizeof(ParamTable)
686: );
687:
688:
689:
690: //
691: // change to the parmeters key
692: //
693:
694: ParamTable[0].QueryRoutine = NULL;
695: ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
696: ParamTable[0].Name = Parameters;
697:
698:
699:
700: //
701: // Get the name of the mac driver we should bind to
702: //
703:
704: ParamTable[1].QueryRoutine = NULL;
705: ParamTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED |
706: RTL_QUERY_REGISTRY_NOEXPAND |
707: RTL_QUERY_REGISTRY_DIRECT;
708:
709: ParamTable[1].Name = Bind;
710: ParamTable[1].EntryContext = (PVOID)MacDriverName;
711: ParamTable[1].DefaultType = REG_SZ;
712:
713: //
714: // Get the name that we should use for the driver object
715: //
716:
717: ParamTable[2].QueryRoutine = NULL;
718: ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED |
719: RTL_QUERY_REGISTRY_NOEXPAND |
720: RTL_QUERY_REGISTRY_DIRECT;
721:
722: ParamTable[2].Name = Export;
723: ParamTable[2].EntryContext = (PVOID)PacketDriverName;
724: ParamTable[2].DefaultType = REG_SZ;
725:
726:
727: Status=RtlQueryRegistryValues(
728: RTL_REGISTRY_ABSOLUTE,
729: Path,
730: ParamTable,
731: NULL,
732: NULL
733: );
734:
735:
736: ExFreePool(Path);
737:
738: return Status;
739:
740:
741:
742:
743: }
744:
745:
746: NTSTATUS
747: PacketCreateSymbolicLink(
748: IN PUNICODE_STRING DeviceName,
749: IN BOOLEAN Create
750: )
751:
752: {
753:
754:
755: UNICODE_STRING UnicodeDosDeviceName;
756: NTSTATUS Status;
757:
758: if (DeviceName->Length < sizeof(L"\\Device\\")) {
759:
760: return STATUS_UNSUCCESSFUL;
761: }
762:
763: RtlInitUnicodeString(&UnicodeDosDeviceName,NULL);
764:
765: UnicodeDosDeviceName.MaximumLength=DeviceName->Length+sizeof(L"\\DosDevices")+sizeof(UNICODE_NULL);
766:
767: UnicodeDosDeviceName.Buffer=ExAllocatePool(
768: NonPagedPool,
769: UnicodeDosDeviceName.MaximumLength
770: );
771:
772: if (UnicodeDosDeviceName.Buffer != NULL) {
773:
774: RtlZeroMemory(
775: UnicodeDosDeviceName.Buffer,
776: UnicodeDosDeviceName.MaximumLength
777: );
778:
779: RtlAppendUnicodeToString(
780: &UnicodeDosDeviceName,
781: L"\\DosDevices\\"
782: );
783:
784: RtlAppendUnicodeToString(
785: &UnicodeDosDeviceName,
786: (DeviceName->Buffer+(sizeof("\\Device")))
787: );
788:
789: IF_LOUD(DbgPrint("Packet: DosDeviceName is %ws\n",UnicodeDosDeviceName.Buffer);)
790:
791: if (Create) {
792:
793: Status=IoCreateSymbolicLink(&UnicodeDosDeviceName,DeviceName);
794:
795: } else {
796:
797: Status=IoDeleteSymbolicLink(&UnicodeDosDeviceName);
798: }
799:
800: ExFreePool(UnicodeDosDeviceName.Buffer);
801:
802: }
803:
804:
805: return Status;
806:
807: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.