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

# User Rev Content
1 asvitkine 1.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     }