ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/b2ether/driver/b2ether.c
Revision: 1.1
Committed: 2012-04-21T16:23:07Z (12 years, 7 months ago) by asvitkine
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
Import b2ether driver sources from a 2001 source archive of BasiliskII.

File Contents

# Content
1 /*
2 * b2ether driver -- derived from DDK packet driver sample
3 *
4 * Basilisk II (C) 1997-1999 Christian Bauer
5 *
6 * Windows platform specific code copyright (C) Lauri Pesonen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24 #include "stdarg.h"
25 #include "ntddk.h"
26 #include "ntiologc.h"
27 #include "ndis.h"
28 #include "ntddpack.h"
29 #include "b2ether.h"
30
31 #undef DBG
32 #define DBG 0
33 #include "debug.h"
34
35 NTSTATUS
36 DriverEntry(
37 IN PDRIVER_OBJECT DriverObject,
38 IN PUNICODE_STRING RegistryPath
39 );
40
41
42 NTSTATUS
43 PacketReadRegistry(
44 IN PWSTR *MacDriverName,
45 IN PWSTR *PacketDriverName,
46 IN PUNICODE_STRING RegistryPath
47 );
48
49
50 NTSTATUS
51 PacketCreateSymbolicLink(
52 IN PUNICODE_STRING DeviceName,
53 IN BOOLEAN Create
54 );
55
56 NTSTATUS
57 PacketQueryRegistryRoutine(
58 IN PWSTR ValueName,
59 IN ULONG ValueType,
60 IN PVOID ValueData,
61 IN ULONG ValueLength,
62 IN PVOID Context,
63 IN PVOID EntryContext
64 );
65
66
67 #if DBG
68 ULONG PacketDebugFlag = PACKET_DEBUG_LOUD;
69 #endif
70
71
72 PDEVICE_EXTENSION GlobalDeviceExtension;
73
74
75 NTSTATUS DriverEntry(
76 IN PDRIVER_OBJECT DriverObject,
77 IN PUNICODE_STRING RegistryPath
78 )
79 {
80 NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
81
82 UNICODE_STRING MacDriverName;
83 UNICODE_STRING UnicodeDeviceName;
84
85 PDEVICE_OBJECT DeviceObject = NULL;
86 PDEVICE_EXTENSION DeviceExtension = NULL;
87
88 NTSTATUS Status = STATUS_SUCCESS;
89 NTSTATUS ErrorCode = STATUS_SUCCESS;
90 NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver");
91
92 ULONG DevicesCreated=0;
93
94 PWSTR BindString;
95 PWSTR ExportString;
96
97 PWSTR BindStringSave;
98 PWSTR ExportStringSave;
99
100 NDIS_HANDLE NdisProtocolHandle;
101
102 IF_LOUD(DbgPrint("\n\nPacket: DriverEntry\n");)
103
104 RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
105
106 ProtocolChar.MajorNdisVersion = 3;
107 ProtocolChar.MinorNdisVersion = 0;
108 ProtocolChar.Reserved = 0;
109 ProtocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete;
110 ProtocolChar.CloseAdapterCompleteHandler = PacketCloseAdapterComplete;
111 ProtocolChar.SendCompleteHandler = PacketSendComplete;
112 ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete;
113 ProtocolChar.ResetCompleteHandler = PacketResetComplete;
114 ProtocolChar.RequestCompleteHandler = PacketRequestComplete;
115 ProtocolChar.ReceiveHandler = PacketReceiveIndicate;
116 ProtocolChar.ReceiveCompleteHandler = PacketReceiveComplete;
117 ProtocolChar.StatusHandler = PacketStatus;
118 ProtocolChar.StatusCompleteHandler = PacketStatusComplete;
119 ProtocolChar.Name = ProtoName;
120
121 NdisRegisterProtocol(
122 &Status,
123 &NdisProtocolHandle,
124 &ProtocolChar,
125 sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
126
127 if (Status != NDIS_STATUS_SUCCESS) {
128 IF_LOUD(DbgPrint("Packet: Failed to register protocol with NDIS\n");)
129 return Status;
130 }
131
132 //
133 // Set up the device driver entry points.
134 //
135
136 DriverObject->MajorFunction[IRP_MJ_CREATE] = PacketOpen;
137 DriverObject->MajorFunction[IRP_MJ_CLOSE] = PacketClose;
138 DriverObject->MajorFunction[IRP_MJ_READ] = PacketRead;
139 DriverObject->MajorFunction[IRP_MJ_WRITE] = PacketWrite;
140 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PacketCleanup;
141 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PacketIoControl;
142
143 DriverObject->DriverUnload = PacketUnload;
144
145
146 //
147 // Get the name of the Packet driver and the name of the MAC driver
148 // to bind to from the registry
149 //
150
151 Status=PacketReadRegistry(
152 &BindString,
153 &ExportString,
154 RegistryPath
155 );
156
157 if (Status != STATUS_SUCCESS) {
158 IF_LOUD(DbgPrint("Perf: Failed to read registry\n");)
159 goto RegistryError;
160 }
161
162 BindStringSave = BindString;
163 ExportStringSave = ExportString;
164
165 // create a device object for each entry
166 while (*BindString!= UNICODE_NULL && *ExportString!= UNICODE_NULL) {
167
168 // Create a counted unicode string for both null terminated strings
169 RtlInitUnicodeString(
170 &MacDriverName,
171 BindString
172 );
173
174 RtlInitUnicodeString(
175 &UnicodeDeviceName,
176 ExportString
177 );
178
179 // Advance to the next string of the MULTI_SZ string
180 BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
181
182 ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
183
184 IF_LOUD(DbgPrint("Packet: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);)
185
186 // Create the device object
187 Status = IoCreateDevice(
188 DriverObject,
189 sizeof(DEVICE_EXTENSION),
190 &UnicodeDeviceName,
191 FILE_DEVICE_PROTOCOL,
192 0,
193 FALSE,
194 &DeviceObject
195 );
196
197 if (Status != STATUS_SUCCESS) {
198 IF_LOUD(DbgPrint("Perf: IoCreateDevice() failed:\n");)
199 break;
200 }
201
202 DevicesCreated++;
203
204 DeviceObject->Flags |= DO_DIRECT_IO;
205 DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
206 DeviceExtension->DeviceObject = DeviceObject;
207
208 // Save the the name of the MAC driver to open in the Device Extension
209 DeviceExtension->AdapterName=MacDriverName;
210
211 if (DevicesCreated == 1) {
212 DeviceExtension->BindString = BindStringSave;
213 DeviceExtension->ExportString = ExportStringSave;
214 }
215
216 DeviceExtension->NdisProtocolHandle=NdisProtocolHandle;
217 }
218
219 if (DevicesCreated > 0) {
220 return STATUS_SUCCESS;
221 }
222
223 ExFreePool(BindStringSave);
224 ExFreePool(ExportStringSave);
225
226 RegistryError:
227
228 NdisDeregisterProtocol(
229 &Status,
230 NdisProtocolHandle
231 );
232
233 Status=STATUS_UNSUCCESSFUL;
234
235 return(Status);
236 }
237
238
239 VOID PacketUnload( IN PDRIVER_OBJECT DriverObject )
240 {
241 PDEVICE_OBJECT DeviceObject;
242 PDEVICE_OBJECT OldDeviceObject;
243 PDEVICE_EXTENSION DeviceExtension;
244
245 NDIS_HANDLE NdisProtocolHandle;
246 NDIS_STATUS Status;
247
248 IF_LOUD(DbgPrint("Packet: Unload\n");)
249
250 DeviceObject = DriverObject->DeviceObject;
251
252 while (DeviceObject != NULL) {
253 DeviceExtension = DeviceObject->DeviceExtension;
254 NdisProtocolHandle = DeviceExtension->NdisProtocolHandle;
255 if (DeviceExtension->BindString != NULL) {
256 ExFreePool(DeviceExtension->BindString);
257 }
258 if (DeviceExtension->ExportString != NULL) {
259 ExFreePool(DeviceExtension->ExportString);
260 }
261 OldDeviceObject=DeviceObject;
262 DeviceObject=DeviceObject->NextDevice;
263 IoDeleteDevice(OldDeviceObject);
264 }
265
266 NdisDeregisterProtocol( &Status, NdisProtocolHandle );
267 }
268
269
270 NTSTATUS PacketIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
271 {
272 POPEN_INSTANCE Open;
273 PIO_STACK_LOCATION IrpSp;
274 PLIST_ENTRY RequestListEntry;
275 PINTERNAL_REQUEST pRequest;
276 ULONG FunctionCode;
277 NDIS_STATUS Status;
278
279 IF_LOUD(DbgPrint("Packet: IoControl\n");)
280
281 IrpSp = IoGetCurrentIrpStackLocation(Irp);
282
283 FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
284
285 Open=IrpSp->FileObject->FsContext;
286
287 RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock);
288 if (RequestListEntry == NULL) {
289 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
290 Irp->IoStatus.Information = 0;
291 IoCompleteRequest(Irp, IO_NO_INCREMENT);
292 return STATUS_UNSUCCESSFUL;
293 }
294
295 pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
296 pRequest->Irp=Irp;
297
298 IoMarkIrpPending(Irp);
299 Irp->IoStatus.Status = STATUS_PENDING;
300
301 IF_LOUD(DbgPrint("Packet: Function code is %08lx buff size=%08lx %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);)
302
303 if (FunctionCode == IOCTL_PROTOCOL_RESET) {
304 IF_LOUD(DbgPrint("Packet: IoControl - Reset request\n");)
305 ExInterlockedInsertTailList(
306 &Open->ResetIrpList,
307 &Irp->Tail.Overlay.ListEntry,
308 &Open->RequestSpinLock);
309 NdisReset( &Status, Open->AdapterHandle );
310
311 if (Status != NDIS_STATUS_PENDING) {
312 IF_LOUD(DbgPrint("Packet: IoControl - ResetComplte being called\n");)
313 PacketResetComplete( Open, Status );
314 }
315
316 } else {
317 // See if it is an Ndis request
318 PPACKET_OID_DATA OidData=Irp->AssociatedIrp.SystemBuffer;
319
320 if (((FunctionCode == IOCTL_PROTOCOL_SET_OID) || (FunctionCode == IOCTL_PROTOCOL_QUERY_OID))
321 &&
322 (IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength)
323 &&
324 (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA))
325 &&
326 (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) {
327
328 IF_LOUD(DbgPrint("Packet: IoControl: Request: Oid=%08lx, Length=%08lx\n",OidData->Oid,OidData->Length);)
329
330 if (FunctionCode == IOCTL_PROTOCOL_SET_OID) {
331 pRequest->Request.RequestType=NdisRequestSetInformation;
332 pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid;
333 pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data;
334 pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length;
335 } else {
336 pRequest->Request.RequestType=NdisRequestQueryInformation;
337 pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid;
338 pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data;
339 pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length;
340 }
341 NdisRequest(
342 &Status,
343 Open->AdapterHandle,
344 &pRequest->Request
345 );
346 } else { // buffer too small
347 Status=NDIS_STATUS_FAILURE;
348 pRequest->Request.DATA.SET_INFORMATION.BytesRead=0;
349 pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0;
350 }
351
352 if (Status != NDIS_STATUS_PENDING) {
353 IF_LOUD(DbgPrint("Packet: Calling RequestCompleteHandler\n");)
354 PacketRequestComplete(
355 Open,
356 &pRequest->Request,
357 Status
358 );
359 }
360 }
361 return(STATUS_PENDING);
362 }
363
364
365 VOID PacketRequestComplete(
366 IN NDIS_HANDLE ProtocolBindingContext,
367 IN PNDIS_REQUEST NdisRequest,
368 IN NDIS_STATUS Status
369 )
370 {
371 POPEN_INSTANCE Open;
372 PIO_STACK_LOCATION IrpSp;
373 PIRP Irp;
374 PINTERNAL_REQUEST pRequest;
375 UINT FunctionCode;
376
377 PPACKET_OID_DATA OidData;
378
379 IF_LOUD(DbgPrint("Packet: RequestComplete\n");)
380
381 Open= (POPEN_INSTANCE)ProtocolBindingContext;
382
383 pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
384 Irp=pRequest->Irp;
385
386 IrpSp = IoGetCurrentIrpStackLocation(Irp);
387
388 FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
389
390 OidData=Irp->AssociatedIrp.SystemBuffer;
391
392 if (FunctionCode == IOCTL_PROTOCOL_SET_OID) {
393 OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead;
394 } else {
395 if (FunctionCode == IOCTL_PROTOCOL_QUERY_OID) {
396 OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;
397 }
398 }
399
400 Irp->IoStatus.Information=IrpSp->Parameters.DeviceIoControl.InputBufferLength;
401
402 ExInterlockedInsertTailList(
403 &Open->RequestList,
404 &pRequest->ListElement,
405 &Open->RequestSpinLock);
406
407 Irp->IoStatus.Status = Status;
408 IoCompleteRequest(Irp, IO_NO_INCREMENT);
409 }
410
411
412 VOID PacketStatus(
413 IN NDIS_HANDLE ProtocolBindingContext,
414 IN NDIS_STATUS Status,
415 IN PVOID StatusBuffer,
416 IN UINT StatusBufferSize
417 )
418 {
419 IF_LOUD(DbgPrint("Packet: Status Indication\n");)
420 }
421
422
423 VOID PacketStatusComplete( IN NDIS_HANDLE ProtocolBindingContext )
424 {
425 IF_LOUD(DbgPrint("Packet: StatusIndicationComplete\n");)
426 }
427
428
429 #if 0
430 NTSTATUS PacketCreateSymbolicLink(
431 IN PUNICODE_STRING DeviceName,
432 IN BOOLEAN Create
433 )
434 {
435 UNICODE_STRING UnicodeDosDeviceName;
436 NTSTATUS Status;
437
438 if (DeviceName->Length < sizeof(L"\\Device\\")) {
439 return STATUS_UNSUCCESSFUL;
440 }
441
442 RtlInitUnicodeString(&UnicodeDosDeviceName,NULL);
443 UnicodeDosDeviceName.MaximumLength=DeviceName->Length+sizeof(L"\\DosDevices")+sizeof(UNICODE_NULL);
444 UnicodeDosDeviceName.Buffer=ExAllocatePool(
445 NonPagedPool,
446 UnicodeDosDeviceName.MaximumLength
447 );
448 if (UnicodeDosDeviceName.Buffer != NULL) {
449 RtlZeroMemory( UnicodeDosDeviceName.Buffer, UnicodeDosDeviceName.MaximumLength );
450 RtlAppendUnicodeToString( &UnicodeDosDeviceName, L"\\DosDevices\\" );
451 RtlAppendUnicodeToString( &UnicodeDosDeviceName, (DeviceName->Buffer+(sizeof("\\Device"))) );
452 IF_LOUD(DbgPrint("Packet: DosDeviceName is %ws\n",UnicodeDosDeviceName.Buffer);)
453 if (Create) {
454 Status=IoCreateSymbolicLink(&UnicodeDosDeviceName,DeviceName);
455 } else {
456 Status=IoDeleteSymbolicLink(&UnicodeDosDeviceName);
457 }
458 ExFreePool(UnicodeDosDeviceName.Buffer);
459 }
460 return Status;
461 }
462 #endif
463
464
465 NTSTATUS PacketReadRegistry(
466 IN PWSTR *MacDriverName,
467 IN PWSTR *PacketDriverName,
468 IN PUNICODE_STRING RegistryPath
469 )
470 {
471 NTSTATUS Status;
472 RTL_QUERY_REGISTRY_TABLE ParamTable[5];
473 PWSTR Bind = L"Bind"; // LAURI: \Device\W30NT1
474 PWSTR Export = L"Export"; // \Device\appletalk\W30NT1\0\0
475 PWSTR Parameters = L"Parameters";
476 PWSTR Linkage = L"Linkage";
477 PWCHAR Path;
478
479 Path=ExAllocatePool( PagedPool, RegistryPath->Length+sizeof(WCHAR) );
480
481 if (!Path) return STATUS_INSUFFICIENT_RESOURCES;
482
483 RtlZeroMemory( Path, RegistryPath->Length+sizeof(WCHAR) );
484 RtlCopyMemory( Path, RegistryPath->Buffer, RegistryPath->Length );
485
486 IF_LOUD(DbgPrint("Packet: Reg path is %ws\n",RegistryPath->Buffer);)
487
488 RtlZeroMemory( ParamTable, sizeof(ParamTable) );
489
490 // change to the parmeters key
491 ParamTable[0].QueryRoutine = NULL;
492 ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
493 ParamTable[0].Name = Parameters;
494
495 // change to the linkage key
496 ParamTable[1].QueryRoutine = NULL;
497 ParamTable[1].Flags = RTL_QUERY_REGISTRY_SUBKEY;
498 ParamTable[1].Name = Linkage;
499
500 // Get the name of the mac driver we should bind to
501 ParamTable[2].QueryRoutine = PacketQueryRegistryRoutine;
502 ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
503
504 ParamTable[2].Name = Bind;
505 ParamTable[2].EntryContext = (PVOID)MacDriverName;
506 ParamTable[2].DefaultType = REG_MULTI_SZ;
507
508 // Get the name that we should use for the driver object
509 ParamTable[3].QueryRoutine = PacketQueryRegistryRoutine;
510 ParamTable[3].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
511
512 ParamTable[3].Name = Export;
513 ParamTable[3].EntryContext = (PVOID)PacketDriverName;
514 ParamTable[3].DefaultType = REG_MULTI_SZ;
515
516 Status=RtlQueryRegistryValues(
517 RTL_REGISTRY_ABSOLUTE,
518 Path,
519 ParamTable,
520 NULL,
521 NULL
522 );
523
524 ExFreePool(Path);
525
526 return Status;
527 }
528
529
530 NTSTATUS PacketQueryRegistryRoutine(
531 IN PWSTR ValueName,
532 IN ULONG ValueType,
533 IN PVOID ValueData,
534 IN ULONG ValueLength,
535 IN PVOID Context,
536 IN PVOID EntryContext
537 )
538
539 {
540 PUCHAR Buffer;
541
542 IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");)
543
544 if (ValueType != REG_MULTI_SZ) {
545 return STATUS_OBJECT_NAME_NOT_FOUND;
546 }
547
548 Buffer=ExAllocatePool(NonPagedPool,ValueLength);
549 if(!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
550
551 RtlCopyMemory( Buffer, ValueData, ValueLength );
552
553 *((PUCHAR *)EntryContext)=Buffer;
554
555 return STATUS_SUCCESS;
556 }