[NDISUIO]
[reactos.git] / drivers / network / ndisuio / main.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS User I/O driver
4 * FILE: main.c
5 * PURPOSE: Driver entry point and protocol initialization
6 * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
7 */
8
9 #include "ndisuio.h"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 PDEVICE_OBJECT GlobalDeviceObject;
15 NDIS_HANDLE GlobalProtocolHandle;
16 KSPIN_LOCK GlobalAdapterListLock;
17 LIST_ENTRY GlobalAdapterList;
18 NDIS_HANDLE GlobalPacketPoolHandle;
19 NDIS_HANDLE GlobalBufferPoolHandle;
20
21 NDIS_STRING ProtocolName = RTL_CONSTANT_STRING(L"NDISUIO");
22
23 VOID NTAPI NduUnload(PDRIVER_OBJECT DriverObject)
24 {
25 DPRINT1("NDISUIO: Unloaded\n");
26 }
27
28 NTSTATUS
29 NTAPI
30 DriverEntry(PDRIVER_OBJECT DriverObject,
31 PUNICODE_STRING RegistryPath)
32 {
33 NDIS_STATUS Status;
34 NDIS_PROTOCOL_CHARACTERISTICS Chars;
35 UNICODE_STRING NtDeviceName = RTL_CONSTANT_STRING(NDISUIO_DEVICE_NAME_NT);
36 UNICODE_STRING DosDeviceName = RTL_CONSTANT_STRING(NDISUIO_DEVICE_NAME_DOS);
37
38 /* Setup dispatch functions */
39 DriverObject->MajorFunction[IRP_MJ_CREATE] = NduDispatchCreate;
40 DriverObject->MajorFunction[IRP_MJ_CLOSE] = NduDispatchClose;
41 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NduDispatchDeviceControl;
42 DriverObject->MajorFunction[IRP_MJ_READ] = NduDispatchRead;
43 DriverObject->MajorFunction[IRP_MJ_WRITE] = NduDispatchWrite;
44 DriverObject->DriverUnload = NduUnload;
45
46 /* Setup global state */
47 InitializeListHead(&GlobalAdapterList);
48 KeInitializeSpinLock(&GlobalAdapterListLock);
49
50 /* Create the NDISUIO device object */
51 Status = IoCreateDevice(DriverObject,
52 0,
53 &NtDeviceName,
54 FILE_DEVICE_SECURE_OPEN,
55 0,
56 FALSE,
57 &GlobalDeviceObject);
58 if (!NT_SUCCESS(Status))
59 {
60 DPRINT1("Failed to create device object with status 0x%x\n", Status);
61 return Status;
62 }
63
64 /* Create a symbolic link into the DOS devices namespace */
65 Status = IoCreateSymbolicLink(&DosDeviceName, &NtDeviceName);
66 if (!NT_SUCCESS(Status))
67 {
68 DPRINT1("Failed to create symbolic link with status 0x%x\n", Status);
69 IoDeleteDevice(GlobalDeviceObject);
70 return Status;
71 }
72
73 /* Create the buffer pool */
74 NdisAllocateBufferPool(&Status,
75 &GlobalBufferPoolHandle,
76 100);
77 if (Status != NDIS_STATUS_SUCCESS)
78 {
79 DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status);
80 IoDeleteSymbolicLink(&DosDeviceName);
81 IoDeleteDevice(GlobalDeviceObject);
82 return Status;
83 }
84
85 /* Create the packet pool */
86 NdisAllocatePacketPool(&Status,
87 &GlobalPacketPoolHandle,
88 50,
89 0);
90 if (Status != NDIS_STATUS_SUCCESS)
91 {
92 DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status);
93 NdisFreeBufferPool(GlobalBufferPoolHandle);
94 IoDeleteSymbolicLink(&DosDeviceName);
95 IoDeleteDevice(GlobalDeviceObject);
96 return Status;
97 }
98
99 /* Register the protocol with NDIS */
100 RtlZeroMemory(&Chars, sizeof(Chars));
101 Chars.MajorNdisVersion = NDIS_MAJOR_VERSION;
102 Chars.MinorNdisVersion = NDIS_MINOR_VERSION;
103 Chars.OpenAdapterCompleteHandler = NduOpenAdapterComplete;
104 Chars.CloseAdapterCompleteHandler = NduCloseAdapterComplete;
105 Chars.SendCompleteHandler = NduSendComplete;
106 Chars.TransferDataCompleteHandler = NduTransferDataComplete;
107 Chars.ResetCompleteHandler = NduResetComplete;
108 Chars.RequestCompleteHandler = NduRequestComplete;
109 Chars.ReceiveHandler = NduReceive;
110 Chars.ReceiveCompleteHandler = NduReceiveComplete;
111 Chars.StatusHandler = NduStatus;
112 Chars.StatusCompleteHandler = NduStatusComplete;
113 Chars.Name = ProtocolName;
114 Chars.BindAdapterHandler = NduBindAdapter;
115 Chars.UnbindAdapterHandler = NduUnbindAdapter;
116
117 NdisRegisterProtocol(&Status,
118 &GlobalProtocolHandle,
119 &Chars,
120 sizeof(Chars));
121 if (Status != NDIS_STATUS_SUCCESS)
122 {
123 DPRINT1("Failed to register protocol with status 0x%x\n", Status);
124 NdisFreePacketPool(GlobalPacketPoolHandle);
125 NdisFreeBufferPool(GlobalBufferPoolHandle);
126 IoDeleteSymbolicLink(&DosDeviceName);
127 IoDeleteDevice(GlobalDeviceObject);
128 return Status;
129 }
130
131 DPRINT1("NDISUIO: Loaded\n");
132
133 return STATUS_SUCCESS;
134 }