Fix sublanguage IDs in .rc files:
[reactos.git] / reactos / drivers / net / npf / packet.c
1 /*
2 * Copyright (c) 1999, 2000
3 * Politecnico di Torino. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the Politecnico
13 * di Torino, and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22 #ifdef _MSC_VER
23 #include "stdarg.h"
24 #include "ntddk.h"
25 #include "ntiologc.h"
26 #include "ndis.h"
27 #else
28 #include <ddk/ntddk.h>
29 #include <ddk/ndis.h>
30 #endif
31
32 #include "ntddpack.h"
33
34 #include "debug.h"
35 #include "packet.h"
36 #include "win_bpf.h"
37 #include "win_bpf_filter_init.h"
38
39 #include "tme.h"
40
41 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
42
43 #if DBG
44 // Declare the global debug flag for this driver.
45 //ULONG PacketDebugFlag = PACKET_DEBUG_LOUD;
46 ULONG PacketDebugFlag = PACKET_DEBUG_LOUD + PACKET_DEBUG_VERY_LOUD + PACKET_DEBUG_INIT;
47
48 #endif
49
50 PDEVICE_EXTENSION GlobalDeviceExtension;
51
52 ////////////////////////////////////////////////////////////////////////////////
53 #define ROBERTS_PATCH
54 #ifdef ROBERTS_PATCH
55
56 #define NDIS_STRING_CONST(x) {sizeof(L##x)-2, sizeof(L##x), L##x}
57
58 //void __moddi3(void) {}
59 //void __divdi3(void) {}
60
61 #endif // ROBERTS_PATCH
62 ////////////////////////////////////////////////////////////////////////////////
63 //
64 // Global strings
65 //
66 NDIS_STRING NPF_Prefix = NDIS_STRING_CONST("NPF_");
67 NDIS_STRING devicePrefix = NDIS_STRING_CONST("\\Device\\");
68 NDIS_STRING symbolicLinkPrefix = NDIS_STRING_CONST("\\DosDevices\\");
69 NDIS_STRING tcpLinkageKeyName = NDIS_STRING_CONST("\\Registry\\Machine\\System"
70 L"\\CurrentControlSet\\Services\\Tcpip\\Linkage");
71 NDIS_STRING AdapterListKey = NDIS_STRING_CONST("\\Registry\\Machine\\System"
72 L"\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
73 NDIS_STRING bindValueName = NDIS_STRING_CONST("Bind");
74
75
76 /// Global variable that points to the names of the bound adapters
77 WCHAR* bindP = NULL;
78
79 extern struct time_conv G_Start_Time; // from openclos.c
80
81 extern NDIS_SPIN_LOCK Opened_Instances_Lock;
82
83 //
84 // Packet Driver's entry routine.
85 //
86 NTSTATUS
87 #ifdef __GNUC__
88 STDCALL
89 #endif
90 DriverEntry(
91 IN PDRIVER_OBJECT DriverObject,
92 IN PUNICODE_STRING RegistryPath
93 )
94 {
95
96 NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
97 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
98 NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver");
99 NDIS_HANDLE NdisProtocolHandle;
100 WCHAR* bindT;
101 PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP;
102 UNICODE_STRING macName;
103
104 // This driver at the moment works only on single processor machines
105 if(NdisSystemProcessorCount() != 1){
106 return STATUS_IMAGE_MP_UP_MISMATCH;
107 }
108
109 IF_LOUD(DbgPrint("Packet: DriverEntry\n");)
110
111 RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
112
113 #ifdef NDIS50
114 ProtocolChar.MajorNdisVersion = 5;
115 #else
116 ProtocolChar.MajorNdisVersion = 3;
117 #endif
118 ProtocolChar.MinorNdisVersion = 0;
119 ProtocolChar.Reserved = 0;
120 ProtocolChar.OpenAdapterCompleteHandler = NPF_OpenAdapterComplete;
121 ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete;
122 ProtocolChar.SendCompleteHandler = NPF_SendComplete;
123 ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete;
124 ProtocolChar.ResetCompleteHandler = NPF_ResetComplete;
125 ProtocolChar.RequestCompleteHandler = NPF_RequestComplete;
126 ProtocolChar.ReceiveHandler = NPF_tap;
127 ProtocolChar.ReceiveCompleteHandler = NPF_ReceiveComplete;
128 ProtocolChar.StatusHandler = NPF_Status;
129 ProtocolChar.StatusCompleteHandler = NPF_StatusComplete;
130 #ifdef NDIS50
131 ProtocolChar.BindAdapterHandler = NPF_BindAdapter;
132 ProtocolChar.UnbindAdapterHandler = NPF_UnbindAdapter;
133 ProtocolChar.PnPEventHandler = NPF_PowerChange;
134 ProtocolChar.ReceivePacketHandler = NULL;
135 #endif
136 ProtocolChar.Name = ProtoName;
137
138 NdisRegisterProtocol(
139 &Status,
140 &NdisProtocolHandle,
141 &ProtocolChar,
142 sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
143
144 if (Status != NDIS_STATUS_SUCCESS) {
145
146 IF_LOUD(DbgPrint("NPF: Failed to register protocol with NDIS\n");)
147
148 return Status;
149
150 }
151
152 NdisAllocateSpinLock(&Opened_Instances_Lock);
153
154 // Set up the device driver entry points.
155 DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)NPF_Open;
156 DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)NPF_Close;
157 DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)NPF_Read;
158 DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)NPF_Write;
159 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)NPF_IoControl;
160 DriverObject->DriverUnload = NPF_Unload;
161
162 /*
163 // Get the name of the Packet driver and the name of the NIC driver
164 // to bind to from the registry
165 Status=NPF_ReadRegistry(
166 &BindString,
167 &ExportString,
168 RegistryPath
169 );
170
171 if (Status != STATUS_SUCCESS) {
172
173 IF_LOUD(DbgPrint("Trying dynamic binding\n");)
174 */
175 bindP = getAdaptersList();
176
177 if (bindP == NULL) {
178 IF_LOUD(DbgPrint("Adapters not found in the registry, try to copy the bindings of TCP-IP.\n");)
179
180 tcpBindingsP = getTcpBindings();
181
182 if (tcpBindingsP == NULL){
183 IF_LOUD(DbgPrint("TCP-IP not found, quitting.\n");)
184 goto RegistryError;
185 }
186
187 bindP = (WCHAR*)tcpBindingsP;
188 bindT = (WCHAR*)(tcpBindingsP->Data);
189 } else {
190 bindT = bindP;
191 }
192
193 for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)) {
194 RtlInitUnicodeString(&macName, bindT);
195 createDevice(DriverObject, &macName, NdisProtocolHandle);
196 }
197
198 return STATUS_SUCCESS;
199 /*
200 }
201 BindStringSave = BindString;
202 ExportStringSave = ExportString;
203 //
204 // create a device object for each entry
205 //
206 while (*BindString!= UNICODE_NULL && *ExportString!= UNICODE_NULL) {
207 //
208 // Create a counted unicode string for both null terminated strings
209 //
210 RtlInitUnicodeString(
211 &MacDriverName,
212 BindString);
213 RtlInitUnicodeString(
214 &UnicodeDeviceName,
215 ExportString);
216 //
217 // Advance to the next string of the MULTI_SZ string
218 //
219 BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
220 ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
221 IF_LOUD(DbgPrint("NPF: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);)
222 //
223 // Create the device object
224 //
225 Status = IoCreateDevice(
226 DriverObject,
227 sizeof(DEVICE_EXTENSION),
228 &UnicodeDeviceName,
229 FILE_DEVICE_PROTOCOL,
230 0,
231 FALSE,
232 &DeviceObject);
233 if (Status != STATUS_SUCCESS) {
234 IF_LOUD(DbgPrint("NPF: IoCreateDevice() failed:\n");)
235 break;
236 }
237 DevicesCreated++;
238 DeviceObject->Flags |= DO_DIRECT_IO;
239 DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
240 DeviceExtension->DeviceObject = DeviceObject;
241 //
242 // Save the the name of the MAC driver to open in the Device Extension
243 //
244 DeviceExtension->AdapterName=MacDriverName;
245 if (DevicesCreated == 1) {
246 DeviceExtension->BindString = NULL;
247 DeviceExtension->ExportString = NULL;
248 }
249 DeviceExtension->NdisProtocolHandle=NdisProtocolHandle;
250 }
251 if (DevicesCreated > 0) {
252 //
253 // Managed to create at least one device.
254 //
255 IF_LOUD(DbgPrint("NPF: Managed to create at least one device.\n");)
256 return STATUS_SUCCESS;
257 }
258 ExFreePool(BindStringSave);
259 ExFreePool(ExportStringSave);
260 */
261
262 RegistryError:
263 IF_LOUD(DbgPrint("NPF: RegistryError: calling NdisDeregisterProtocol()\n");)
264 NdisDeregisterProtocol(
265 &Status,
266 NdisProtocolHandle
267 );
268
269 Status=STATUS_UNSUCCESSFUL;
270
271 return(Status);
272
273 }
274
275 //-------------------------------------------------------------------
276
277 PWCHAR getAdaptersList(void)
278 {
279 OBJECT_ATTRIBUTES objAttrs;
280 NTSTATUS status;
281 HANDLE keyHandle;
282 UINT BufPos=0;
283
284 #define NPF_TAG_DEVICENAME TAG('0', 'P', 'W', 'A')
285 PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, 4096, NPF_TAG_DEVICENAME);
286
287 if (DeviceNames == NULL) {
288 IF_LOUD(DbgPrint("Unable the allocate the buffer for the list of the network adapters\n");)
289 return NULL;
290 }
291
292 InitializeObjectAttributes(&objAttrs, &AdapterListKey,
293 OBJ_CASE_INSENSITIVE, NULL, NULL);
294 status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
295 if (!NT_SUCCESS(status)) {
296
297 //IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
298 IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, AdapterListKey.Buffer);)
299
300 } else { //OK
301 ULONG resultLength;
302 CHAR AdapInfo[1024];
303 UINT i=0;
304
305 IF_LOUD(DbgPrint("getAdaptersList: scanning the list of the adapters in the registry, DeviceNames=%x\n",DeviceNames);)
306
307 // Scan the list of the devices
308 while((status=ZwEnumerateKey(keyHandle,i,KeyBasicInformation,AdapInfo,sizeof(AdapInfo),&resultLength))==STATUS_SUCCESS) {
309 WCHAR ExportKeyName [512];
310 PWCHAR ExportKeyPrefix = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
311 UINT ExportKeyPrefixSize = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
312 PWCHAR LinkageKeyPrefix = L"\\Linkage";
313 UINT LinkageKeyPrefixSize = sizeof(L"\\Linkage");
314 NDIS_STRING FinalExportKey = NDIS_STRING_CONST("Export");
315 PKEY_BASIC_INFORMATION tInfo= (PKEY_BASIC_INFORMATION)AdapInfo;
316 UNICODE_STRING AdapterKeyName;
317 HANDLE ExportKeyHandle;
318 KEY_VALUE_PARTIAL_INFORMATION valueInfo;
319 ULONG resultLength;
320
321 RtlCopyMemory(ExportKeyName,
322 ExportKeyPrefix,
323 ExportKeyPrefixSize);
324
325 RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize,
326 tInfo->Name,
327 tInfo->NameLength+2);
328
329 RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize+tInfo->NameLength,
330 LinkageKeyPrefix,
331 LinkageKeyPrefixSize);
332
333 IF_LOUD(DbgPrint("Key name=%ws\n", ExportKeyName);)
334
335 RtlInitUnicodeString(&AdapterKeyName, ExportKeyName);
336
337 InitializeObjectAttributes(&objAttrs, &AdapterKeyName,
338 OBJ_CASE_INSENSITIVE, NULL, NULL);
339
340 status=ZwOpenKey(&ExportKeyHandle,KEY_READ,&objAttrs);
341
342 if (!NT_SUCCESS(status)) {
343 DbgPrint("OpenKey Failed, %d!\n",status);
344 i++;
345 continue;
346 }
347
348 status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
349 KeyValuePartialInformation, &valueInfo,
350 sizeof(valueInfo), &resultLength);
351
352 if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) {
353 IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
354 } else { // We know how big it needs to be.
355 ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
356 #define NPF_TAG_KEYVALUE TAG('1', 'P', 'W', 'A')
357 PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE);
358 if (valueInfoP != NULL) {
359 status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
360 KeyValuePartialInformation,
361 valueInfoP,
362 valueInfoLength, &resultLength);
363 if (!NT_SUCCESS(status)) {
364 IF_LOUD(DbgPrint("Status of %x querying key value\n", status);)
365 } else {
366 IF_LOUD(DbgPrint("Device %d = %ws\n", i, valueInfoP->Data);)
367 RtlCopyMemory((PCHAR)DeviceNames+BufPos,
368 valueInfoP->Data,
369 valueInfoP->DataLength);
370 BufPos+=valueInfoP->DataLength-2;
371 }
372
373 ExFreePool(valueInfoP);
374 } else {
375 IF_LOUD(DbgPrint("Error Allocating the buffer for the device name\n");)
376 }
377
378 }
379
380 // terminate the buffer
381 DeviceNames[BufPos/2]=0;
382 DeviceNames[BufPos/2+1]=0;
383
384 ZwClose (ExportKeyHandle);
385 i++;
386
387 }
388
389 ZwClose (keyHandle);
390
391 }
392 if(BufPos==0){
393 ExFreePool(DeviceNames);
394 return NULL;
395 }
396 return DeviceNames;
397 }
398
399 //-------------------------------------------------------------------
400
401 PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void)
402 {
403 PKEY_VALUE_PARTIAL_INFORMATION result = NULL;
404 OBJECT_ATTRIBUTES objAttrs;
405 NTSTATUS status;
406 HANDLE keyHandle;
407
408 InitializeObjectAttributes(&objAttrs, &tcpLinkageKeyName,
409 OBJ_CASE_INSENSITIVE, NULL, NULL);
410 status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
411 if (!NT_SUCCESS(status)) {
412 IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
413 } else {
414 ULONG resultLength;
415 KEY_VALUE_PARTIAL_INFORMATION valueInfo;
416
417 IF_LOUD(DbgPrint("\n\nOpened %ws\n", tcpLinkageKeyName.Buffer);)
418
419 status = ZwQueryValueKey(keyHandle, &bindValueName,
420 KeyValuePartialInformation, &valueInfo,
421 sizeof(valueInfo), &resultLength);
422 if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) {
423 IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
424 } else { // We know how big it needs to be.
425 ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
426 #define NPF_TAG_KEYVALUE2 TAG('2', 'P', 'W', 'A')
427 PKEY_VALUE_PARTIAL_INFORMATION valueInfoP =
428 (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE2);
429
430 if (valueInfoP != NULL) {
431 status = ZwQueryValueKey(keyHandle, &bindValueName,
432 KeyValuePartialInformation,
433 valueInfoP,
434 valueInfoLength, &resultLength);
435
436 if (!NT_SUCCESS(status)) {
437 IF_LOUD(DbgPrint("\n\nStatus of %x querying key value\n", status);)
438 }
439 else if (valueInfoLength != resultLength) {
440 IF_LOUD(DbgPrint("\n\nQuerying key value result len = %u "
441 "but previous len = %u\n",
442 resultLength, valueInfoLength);)
443 }
444 else if (valueInfoP->Type != REG_MULTI_SZ) {
445 IF_LOUD(DbgPrint("\n\nTcpip bind value not REG_MULTI_SZ but %u\n",
446 valueInfoP->Type);)
447 }
448 else { // It's OK
449 #if DBG
450 ULONG i;
451 WCHAR* dataP = (WCHAR*)(&valueInfoP->Data[0]);
452 IF_LOUD(DbgPrint("\n\nBind value:\n");)
453 for (i = 0; *dataP != UNICODE_NULL; i++) {
454 UNICODE_STRING macName;
455 RtlInitUnicodeString(&macName, dataP);
456 IF_LOUD(DbgPrint("\n\nMac %u = %ws\n", i, macName.Buffer);)
457 dataP +=
458 (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
459 }
460 #endif // DBG
461 result = valueInfoP;
462 }
463 }
464 }
465 ZwClose(keyHandle);
466 }
467 return result;
468 }
469
470 //-------------------------------------------------------------------
471
472 BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
473 IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle)
474 {
475 NTSTATUS status;
476 PDEVICE_OBJECT devObjP;
477 UNICODE_STRING deviceName;
478 UNICODE_STRING deviceSymLink;
479
480 IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer););
481 if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer,
482 devicePrefix.Length) < devicePrefix.Length) {
483 return FALSE;
484 }
485
486 deviceName.Length = 0;
487 deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL));
488 #define NPF_TAG_DEVICENAMEBUF TAG('3', 'P', 'W', 'A')
489 deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, NPF_TAG_DEVICENAMEBUF);
490
491 if (deviceName.Buffer == NULL)
492 return FALSE;
493
494 deviceSymLink.Length = 0;
495 deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length
496 + symbolicLinkPrefix.Length
497 + NPF_Prefix.Length
498 + sizeof(UNICODE_NULL));
499
500 #define NPF_TAG_SYMLINKBUF TAG('3', 'P', 'W', 'A')
501 deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, NPF_TAG_SYMLINKBUF);
502
503 if (deviceSymLink.Buffer == NULL)
504 {
505 ExFreePool(deviceName.Buffer);
506 return FALSE;
507 }
508
509 RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
510 RtlAppendUnicodeStringToString(&deviceName, &NPF_Prefix);
511 RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer +
512 devicePrefix.Length / sizeof(WCHAR));
513
514 RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
515 RtlAppendUnicodeStringToString(&deviceSymLink, &NPF_Prefix);
516 RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer +
517 devicePrefix.Length / sizeof(WCHAR));
518
519 IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);)
520
521 status = IoCreateDevice(adriverObjectP,
522 sizeof(PDEVICE_EXTENSION),
523 &deviceName,
524 FILE_DEVICE_TRANSPORT,
525 0,
526 FALSE,
527 &devObjP);
528
529 if (NT_SUCCESS(status)) {
530 PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;
531
532 IF_LOUD(DbgPrint("Device created successfully\n"););
533
534 devObjP->Flags |= DO_DIRECT_IO;
535 RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);
536 devExtP->NdisProtocolHandle=aProtoHandle;
537
538 IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer););
539
540 if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS) {
541 IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer););
542
543 ExFreePool(deviceName.Buffer);
544 ExFreePool(deviceSymLink.Buffer);
545
546 devExtP->ExportString = NULL;
547
548 return FALSE;
549 }
550
551 IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer););
552
553 devExtP->ExportString = deviceSymLink.Buffer;
554
555 ExFreePool(deviceName.Buffer);
556
557 return TRUE;
558 }
559
560 else
561 {
562 IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););
563
564 ExFreePool(deviceName.Buffer);
565 ExFreePool(deviceSymLink.Buffer);
566
567 return FALSE;
568 }
569 }
570
571 //-------------------------------------------------------------------
572
573 VOID STDCALL
574 NPF_Unload(IN PDRIVER_OBJECT DriverObject)
575 {
576 PDEVICE_OBJECT DeviceObject;
577 PDEVICE_OBJECT OldDeviceObject;
578 PDEVICE_EXTENSION DeviceExtension;
579
580 NDIS_HANDLE NdisProtocolHandle;
581 NDIS_STATUS Status;
582
583 NDIS_STRING SymLink;
584
585 IF_LOUD(DbgPrint("NPF: Unload\n"););
586
587 DeviceObject = DriverObject->DeviceObject;
588
589 while (DeviceObject != NULL) {
590 OldDeviceObject=DeviceObject;
591
592 DeviceObject=DeviceObject->NextDevice;
593
594 DeviceExtension = OldDeviceObject->DeviceExtension;
595
596 NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;
597
598 IF_LOUD(DbgPrint("Deleting Adapter %ws, Protocol Handle=%x, Device Obj=%x (%x)\n",
599 DeviceExtension->AdapterName.Buffer,
600 NdisProtocolHandle,
601 DeviceObject,
602 OldDeviceObject););
603
604 if (DeviceExtension->ExportString)
605 {
606 RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString);
607
608 IF_LOUD(DbgPrint("Deleting SymLink at %p\n", SymLink.Buffer););
609
610 IoDeleteSymbolicLink(&SymLink);
611 ExFreePool(DeviceExtension->ExportString);
612 }
613
614 IoDeleteDevice(OldDeviceObject);
615
616 NdisDeregisterProtocol(
617 &Status,
618 NdisProtocolHandle
619 );
620 }
621
622 // Free the adapters names
623 ExFreePool( bindP );
624 }
625
626 //-------------------------------------------------------------------
627
628 NTSTATUS STDCALL
629 NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
630 {
631 POPEN_INSTANCE Open;
632 PIO_STACK_LOCATION IrpSp;
633 PLIST_ENTRY RequestListEntry;
634 PINTERNAL_REQUEST pRequest;
635 ULONG FunctionCode;
636 NDIS_STATUS Status;
637 PUCHAR tpointer;
638 ULONG dim,timeout;
639 PUCHAR prog;
640 PPACKET_OID_DATA OidData;
641 ULONG mode;
642 PWSTR DumpNameBuff;
643 PUCHAR TmpBPFProgram;
644 INT WriteRes;
645 BOOLEAN SyncWrite = FALSE;
646 struct bpf_insn *initprogram;
647 ULONG insns;
648 ULONG cnt;
649 BOOLEAN IsExtendedFilter=FALSE;
650
651 IF_LOUD(DbgPrint("NPF: IoControl\n");)
652
653 IrpSp = IoGetCurrentIrpStackLocation(Irp);
654 FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
655 Open=IrpSp->FileObject->FsContext;
656
657 Irp->IoStatus.Status = STATUS_SUCCESS;
658
659 IF_LOUD(DbgPrint("NPF: Function code is %08lx buff size=%08lx %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);)
660
661
662 switch (FunctionCode){
663
664 case BIOCGSTATS: //function to get the capture stats
665
666 if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4*sizeof(INT)){
667 EXIT_FAILURE(0);
668 }
669
670 *(((PUINT)Irp->UserBuffer)+3) = Open->Accepted;
671 *(((PUINT)Irp->UserBuffer)) = Open->Received;
672 *(((PUINT)Irp->UserBuffer)+1) = Open->Dropped;
673 *(((PUINT)Irp->UserBuffer)+2) = 0; // Not yet supported
674
675 EXIT_SUCCESS(4*sizeof(INT));
676
677 break;
678
679 case BIOCGEVNAME: //function to get the name of the event associated with the current instance
680
681 if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength<26){
682 EXIT_FAILURE(0);
683 }
684
685 RtlCopyMemory(Irp->UserBuffer,(Open->ReadEventName.Buffer)+18,26);
686
687 EXIT_SUCCESS(26);
688
689 break;
690
691 case BIOCSENDPACKETSSYNC:
692
693 SyncWrite = TRUE;
694
695 case BIOCSENDPACKETSNOSYNC:
696
697 WriteRes = NPF_BufferedWrite(Irp,
698 (PCHAR)Irp->AssociatedIrp.SystemBuffer,
699 IrpSp->Parameters.DeviceIoControl.InputBufferLength,
700 SyncWrite);
701
702 if( WriteRes != -1)
703 {
704 EXIT_SUCCESS(WriteRes);
705 }
706
707 EXIT_FAILURE(WriteRes);
708
709 break;
710
711 case BIOCSETF:
712
713 // Free the previous buffer if it was present
714 if(Open->bpfprogram!=NULL){
715 TmpBPFProgram=Open->bpfprogram;
716 Open->bpfprogram = NULL;
717 ExFreePool(TmpBPFProgram);
718 }
719
720 if (Open->Filter!=NULL)
721 {
722 JIT_BPF_Filter *OldFilter=Open->Filter;
723 Open->Filter=NULL;
724 BPF_Destroy_JIT_Filter(OldFilter);
725 }
726
727 // Get the pointer to the new program
728 prog=(PUCHAR)Irp->AssociatedIrp.SystemBuffer;
729
730 if(prog==NULL){
731 IF_LOUD(DbgPrint("0001");)
732
733 EXIT_FAILURE(0);
734 }
735
736 insns=(IrpSp->Parameters.DeviceIoControl.InputBufferLength)/sizeof(struct bpf_insn);
737
738 //count the number of operative instructions
739 for (cnt=0;(cnt<insns) &&(((struct bpf_insn*)prog)[cnt].code!=BPF_SEPARATION); cnt++);
740
741 IF_LOUD(DbgPrint("Operative instructions=%u\n",cnt);)
742
743 if (((struct bpf_insn*)prog)[cnt].code==BPF_SEPARATION && (insns-cnt-1)!=0)
744 {
745 IF_LOUD(DbgPrint("Initialization instructions=%u\n",insns-cnt-1);)
746
747 IsExtendedFilter=TRUE;
748
749 initprogram=&((struct bpf_insn*)prog)[cnt+1];
750
751 if(bpf_filter_init(initprogram,&(Open->mem_ex),&(Open->tme), &G_Start_Time)!=INIT_OK)
752 {
753
754 IF_LOUD(DbgPrint("Error initializing NPF machine (bpf_filter_init)\n");)
755
756 EXIT_FAILURE(0);
757 }
758 }
759
760 //the NPF processor has been initialized, we have to validate the operative instructions
761 insns=cnt;
762
763 if(bpf_validate((struct bpf_insn*)prog,cnt,Open->mem_ex.size)==0)
764 {
765 IF_LOUD(DbgPrint("Error validating program");)
766 //FIXME: the machine has been initialized(?), but the operative code is wrong.
767 //we have to reset the machine!
768 //something like: reallocate the mem_ex, and reset the tme_core
769 EXIT_FAILURE(0);
770 }
771
772 // Allocate the memory to contain the new filter program
773 // We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers()
774 #define NPF_TAG_BPFPROG TAG('4', 'P', 'W', 'A')
775 TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), NPF_TAG_BPFPROG);
776 if (TmpBPFProgram==NULL){
777 IF_LOUD(DbgPrint("Error - No memory for filter");)
778 // no memory
779 EXIT_FAILURE(0);
780 }
781
782 //copy the program in the new buffer
783 RtlCopyMemory(TmpBPFProgram,prog,cnt*sizeof(struct bpf_insn));
784 Open->bpfprogram=TmpBPFProgram;
785
786 // Create the new JIT filter function
787 if(!IsExtendedFilter)
788 if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) == NULL) {
789 IF_LOUD(DbgPrint("Error jittering filter");)
790 EXIT_FAILURE(0);
791 }
792
793 //return
794 Open->Bhead = 0;
795 Open->Btail = 0;
796 Open->BLastByte = (UINT) -1;
797 Open->Received = 0;
798 Open->Dropped = 0;
799 Open->Accepted = 0;
800
801 EXIT_SUCCESS(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
802
803 break;
804
805 case BIOCSMODE: //set the capture mode
806
807 mode=*((PULONG)Irp->AssociatedIrp.SystemBuffer);
808
809 if(mode == MODE_CAPT){
810 Open->mode=MODE_CAPT;
811
812 EXIT_SUCCESS(0);
813 }
814 else if (mode==MODE_MON){
815 Open->mode=MODE_MON;
816
817 EXIT_SUCCESS(0);
818 }
819 else{
820 if(mode & MODE_STAT){
821 Open->mode = MODE_STAT;
822 Open->Nbytes.QuadPart=0;
823 Open->Npackets.QuadPart=0;
824
825 if(Open->TimeOut.QuadPart==0)Open->TimeOut.QuadPart=-10000000;
826
827 }
828
829 if(mode & MODE_DUMP){
830
831 Open->mode |= MODE_DUMP;
832 Open->MinToCopy=(Open->BufSize<2000000)?Open->BufSize/2:1000000;
833
834 }
835 EXIT_SUCCESS(0);
836 }
837
838 EXIT_FAILURE(0);
839
840 break;
841
842 case BIOCSETDUMPFILENAME:
843
844 if(Open->mode & MODE_DUMP)
845 {
846
847 // Close current dump file
848 if(Open->DumpFileHandle != NULL){
849 NPF_CloseDumpFile(Open);
850 Open->DumpFileHandle = NULL;
851 }
852
853 if(IrpSp->Parameters.DeviceIoControl.InputBufferLength == 0){
854 EXIT_FAILURE(0);
855 }
856
857 // Allocate the buffer that will contain the string
858 #define NPF_TAG_DUMPNAMEBUF TAG('5', 'P', 'W', 'A')
859 DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, NPF_TAG_DUMPNAMEBUF);
860 if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){
861 IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");)
862 EXIT_FAILURE(0);
863 }
864
865 // Copy the buffer
866 RtlCopyBytes((PVOID)DumpNameBuff,
867 Irp->AssociatedIrp.SystemBuffer,
868 IrpSp->Parameters.DeviceIoControl.InputBufferLength);
869
870 // Force a \0 at the end of the filename to avoid that malformed strings cause RtlInitUnicodeString to crash the system
871 ((SHORT*)DumpNameBuff)[IrpSp->Parameters.DeviceIoControl.InputBufferLength/2-1]=0;
872
873 // Create the unicode string
874 RtlInitUnicodeString(&Open->DumpFileName, DumpNameBuff);
875
876 IF_LOUD(DbgPrint("NPF: dump file name set to %ws, len=%d\n",
877 Open->DumpFileName.Buffer,
878 IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
879
880 // Try to create the file
881 if ( NT_SUCCESS( NPF_OpenDumpFile(Open,&Open->DumpFileName,FALSE)) &&
882 NT_SUCCESS( NPF_StartDump(Open))){
883
884 EXIT_SUCCESS(0);
885 }
886 }
887
888 EXIT_FAILURE(0);
889
890 break;
891
892 case BIOCSETDUMPLIMITS:
893
894 Open->MaxDumpBytes = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
895 Open->MaxDumpPacks = *((PULONG)Irp->AssociatedIrp.SystemBuffer + 1);
896
897 IF_LOUD(DbgPrint("NPF: Set dump limits to %u bytes, %u packs\n", Open->MaxDumpBytes, Open->MaxDumpPacks);)
898
899 EXIT_SUCCESS(0);
900
901 break;
902
903 case BIOCISDUMPENDED:
904 if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4){
905 EXIT_FAILURE(0);
906 }
907
908 *((UINT*)Irp->UserBuffer) = (Open->DumpLimitReached)?1:0;
909
910 EXIT_SUCCESS(4);
911
912 break;
913
914 case BIOCSETBUFFERSIZE:
915
916 // Get the number of bytes to allocate
917 dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
918
919 // Free the old buffer
920 tpointer = Open->Buffer;
921 if(tpointer != NULL){
922 Open->BufSize = 0;
923 Open->Buffer = NULL;
924 ExFreePool(tpointer);
925 }
926 // Allocate the new buffer
927 if(dim!=0){
928 #define NPF_TAG_TPOINTER TAG('6', 'P', 'W', 'A')
929 tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, NPF_TAG_TPOINTER);
930 if (tpointer==NULL) {
931 // no memory
932 Open->BufSize = 0;
933 Open->Buffer = NULL;
934 EXIT_FAILURE(0);
935 }
936 }
937 else
938 tpointer = NULL;
939
940 Open->Buffer = tpointer;
941 Open->Bhead = 0;
942 Open->Btail = 0;
943 Open->BLastByte = (UINT) -1;
944
945 Open->BufSize = (UINT)dim;
946 EXIT_SUCCESS(dim);
947
948 break;
949
950 case BIOCSRTIMEOUT: //set the timeout on the read calls
951
952 timeout = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
953 if((int)timeout==-1)
954 Open->TimeOut.QuadPart=(LONGLONG)IMMEDIATE;
955 else {
956 Open->TimeOut.QuadPart=(LONGLONG)timeout;
957 Open->TimeOut.QuadPart*=10000;
958 Open->TimeOut.QuadPart=-Open->TimeOut.QuadPart;
959 }
960
961 //IF_LOUD(DbgPrint("NPF: read timeout set to %d:%d\n",Open->TimeOut.HighPart,Open->TimeOut.LowPart);)
962 EXIT_SUCCESS(timeout);
963
964 break;
965
966 case BIOCSWRITEREP: //set the writes repetition number
967
968 Open->Nwrites = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
969
970 EXIT_SUCCESS(Open->Nwrites);
971
972 break;
973
974 case BIOCSMINTOCOPY: //set the minimum buffer's size to copy to the application
975
976 Open->MinToCopy = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
977
978 EXIT_SUCCESS(Open->MinToCopy);
979
980 break;
981
982 case IOCTL_PROTOCOL_RESET:
983
984 IF_LOUD(DbgPrint("NPF: IoControl - Reset request\n");)
985
986 IoMarkIrpPending(Irp);
987 Irp->IoStatus.Status = STATUS_SUCCESS;
988
989 ExInterlockedInsertTailList(&Open->ResetIrpList,&Irp->Tail.Overlay.ListEntry,&Open->RequestSpinLock);
990 NdisReset(&Status,Open->AdapterHandle);
991 if (Status != NDIS_STATUS_PENDING) {
992 IF_LOUD(DbgPrint("NPF: IoControl - ResetComplete being called\n");)
993 NPF_ResetComplete(Open,Status);
994 }
995
996 break;
997
998
999 case BIOCSETOID:
1000 case BIOCQUERYOID:
1001
1002 // Extract a request from the list of free ones
1003 RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock);
1004 if (RequestListEntry == NULL)
1005 {
1006 EXIT_FAILURE(0);
1007 }
1008
1009 pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
1010 pRequest->Irp=Irp;
1011 pRequest->Internal = FALSE;
1012
1013
1014 //
1015 // See if it is an Ndis request
1016 //
1017 OidData=Irp->AssociatedIrp.SystemBuffer;
1018
1019 if (((FunctionCode == BIOCSETOID) || (FunctionCode == BIOCQUERYOID))
1020 &&
1021 (IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength)
1022 &&
1023 (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA))
1024 &&
1025 (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) {
1026
1027 IF_LOUD(DbgPrint("NPF: IoControl: Request: Oid=%08lx, Length=%08lx\n",OidData->Oid,OidData->Length);)
1028
1029 //
1030 // The buffer is valid
1031 //
1032 if (FunctionCode == BIOCSETOID){
1033
1034 pRequest->Request.RequestType=NdisRequestSetInformation;
1035 pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid;
1036
1037 pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data;
1038 pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length;
1039 } else{
1040 pRequest->Request.RequestType=NdisRequestQueryInformation;
1041 pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid;
1042
1043 pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data;
1044 pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length;
1045
1046 }
1047
1048 NdisResetEvent(&Open->IOEvent);
1049 //
1050 // submit the request
1051 //
1052 NdisRequest(
1053 &Status,
1054 Open->AdapterHandle,
1055 &pRequest->Request
1056 );
1057
1058 } else {
1059 //
1060 // buffer too small
1061 //
1062 Status=NDIS_STATUS_FAILURE;
1063 pRequest->Request.DATA.SET_INFORMATION.BytesRead=0;
1064 pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0;
1065
1066 }
1067
1068 if (Status != NDIS_STATUS_PENDING) {
1069 IF_LOUD(DbgPrint("NPF: Calling RequestCompleteHandler\n");)
1070
1071 NPF_RequestComplete(Open, &pRequest->Request, Status);
1072 return Status;
1073
1074 }
1075
1076 NdisWaitEvent(&Open->IOEvent, 5000);
1077
1078 return(Open->IOStatus);
1079
1080 break;
1081
1082
1083 default:
1084
1085 EXIT_FAILURE(0);
1086 }
1087
1088 return Status;
1089 }
1090
1091 //-------------------------------------------------------------------
1092
1093 VOID STDCALL
1094 NPF_RequestComplete(
1095 IN NDIS_HANDLE ProtocolBindingContext,
1096 IN PNDIS_REQUEST NdisRequest,
1097 IN NDIS_STATUS Status
1098 )
1099
1100 {
1101 POPEN_INSTANCE Open;
1102 PIO_STACK_LOCATION IrpSp;
1103 PIRP Irp;
1104 PINTERNAL_REQUEST pRequest;
1105 UINT FunctionCode;
1106
1107 PPACKET_OID_DATA OidData;
1108
1109 IF_LOUD(DbgPrint("NPF: RequestComplete\n");)
1110
1111 Open= (POPEN_INSTANCE)ProtocolBindingContext;
1112
1113 pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
1114 Irp=pRequest->Irp;
1115
1116 if(pRequest->Internal == TRUE){
1117
1118 // Put the request in the list of the free ones
1119 ExInterlockedInsertTailList(&Open->RequestList, &pRequest->ListElement, &Open->RequestSpinLock);
1120
1121 if(Status != NDIS_STATUS_SUCCESS)
1122 Open->MaxFrameSize = 1514; // Assume Ethernet
1123
1124 // We always return success, because the adapter has been already opened
1125 Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;
1126 Irp->IoStatus.Information = 0;
1127 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1128 return;
1129 }
1130
1131 IrpSp = IoGetCurrentIrpStackLocation(Irp);
1132
1133 FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
1134
1135 OidData=Irp->AssociatedIrp.SystemBuffer;
1136
1137 if (FunctionCode == BIOCSETOID) {
1138
1139 OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead;
1140
1141 } else {
1142
1143 if (FunctionCode == BIOCQUERYOID) {
1144
1145 OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;
1146
1147 IF_LOUD(DbgPrint("RequestComplete: BytesWritten=%d\n",pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten);)
1148 }
1149
1150 }
1151
1152 Irp->IoStatus.Information=IrpSp->Parameters.DeviceIoControl.InputBufferLength;
1153
1154 IF_LOUD(DbgPrint("RequestComplete: BytesReturned=%d\n",IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
1155
1156 ExInterlockedInsertTailList(
1157 &Open->RequestList,
1158 &pRequest->ListElement,
1159 &Open->RequestSpinLock);
1160
1161 Irp->IoStatus.Status = Status;
1162
1163 Open->IOStatus = Status;
1164
1165 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1166
1167 // Unlock the caller
1168 NdisSetEvent(&Open->IOEvent);
1169
1170 return;
1171
1172
1173 }
1174
1175 //-------------------------------------------------------------------
1176
1177 VOID STDCALL
1178 NPF_Status(
1179 IN NDIS_HANDLE ProtocolBindingContext,
1180 IN NDIS_STATUS Status,
1181 IN PVOID StatusBuffer,
1182 IN UINT StatusBufferSize
1183 )
1184
1185 {
1186
1187 IF_LOUD(DbgPrint("NPF: Status Indication\n");)
1188
1189 return;
1190
1191 }
1192
1193 //-------------------------------------------------------------------
1194
1195 VOID STDCALL
1196 NPF_StatusComplete(
1197 IN NDIS_HANDLE ProtocolBindingContext
1198 )
1199
1200 {
1201
1202 IF_LOUD(DbgPrint("NPF: StatusIndicationComplete\n");)
1203
1204 return;
1205
1206 }
1207
1208 //-------------------------------------------------------------------
1209
1210 NTSTATUS
1211 NPF_ReadRegistry(
1212 IN PWSTR *MacDriverName,
1213 IN PWSTR *PacketDriverName,
1214 IN PUNICODE_STRING RegistryPath
1215 )
1216
1217 {
1218 NTSTATUS Status;
1219
1220 RTL_QUERY_REGISTRY_TABLE ParamTable[4];
1221
1222 PWSTR Bind = L"Bind";
1223 PWSTR Export = L"Export";
1224 PWSTR Linkage = L"Linkage";
1225
1226 PWCHAR Path;
1227
1228 #define NPF_TAG_PATH TAG('7', 'P', 'W', 'A')
1229 Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), NPF_TAG_PATH);
1230
1231 if (Path == NULL) {
1232 IF_LOUD(DbgPrint("\nPacketReadRegistry: returing STATUS_INSUFFICIENT_RESOURCES\n");)
1233 return STATUS_INSUFFICIENT_RESOURCES;
1234 }
1235
1236 RtlZeroMemory(
1237 Path,
1238 RegistryPath->Length+sizeof(WCHAR)
1239 );
1240
1241 RtlCopyMemory(
1242 Path,
1243 RegistryPath->Buffer,
1244 RegistryPath->Length
1245 );
1246
1247 IF_LOUD(DbgPrint("NPF: Reg path is %ws\n",RegistryPath->Buffer);)
1248
1249 RtlZeroMemory(
1250 ParamTable,
1251 sizeof(ParamTable)
1252 );
1253
1254
1255
1256 //
1257 // change to the linkage key
1258 //
1259 //ParamTable[0].QueryRoutine = NULL;
1260 ParamTable[0].QueryRoutine = NPF_QueryRegistryRoutine;
1261 ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
1262 ParamTable[0].Name = Linkage;
1263
1264
1265 //
1266 // Get the name of the mac driver we should bind to
1267 //
1268
1269 ParamTable[1].QueryRoutine = NPF_QueryRegistryRoutine;
1270 ParamTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED |
1271 RTL_QUERY_REGISTRY_NOEXPAND;
1272
1273 ParamTable[1].Name = Bind;
1274 ParamTable[1].EntryContext = (PVOID)MacDriverName;
1275 ParamTable[1].DefaultType = REG_MULTI_SZ;
1276
1277 //
1278 // Get the name that we should use for the driver object
1279 //
1280
1281 ParamTable[2].QueryRoutine = NPF_QueryRegistryRoutine;
1282 ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED |
1283 RTL_QUERY_REGISTRY_NOEXPAND;
1284
1285 ParamTable[2].Name = Export;
1286 ParamTable[2].EntryContext = (PVOID)PacketDriverName;
1287 ParamTable[2].DefaultType = REG_MULTI_SZ;
1288
1289
1290 Status=RtlQueryRegistryValues(
1291 RTL_REGISTRY_ABSOLUTE,
1292 Path,
1293 ParamTable,
1294 NULL,
1295 NULL
1296 );
1297
1298 if (Status != STATUS_SUCCESS) {
1299 // insert hard coded parameters here while registry on ROS is not working...
1300 IF_LOUD(DbgPrint("PacketReadRegistry() RtlQueryRegistryValues failed - returing fixed parameters\n");)
1301
1302 *MacDriverName = ExAllocatePool(PagedPool, 50 * sizeof(WCHAR));
1303 //memcpy(*MacDriverName, L"\\Device\\ne2000", 15 * sizeof(WCHAR));
1304 memcpy(*MacDriverName, L"\\Device\\ne2000", 15 * sizeof(WCHAR));
1305
1306 *PacketDriverName = ExAllocatePool(PagedPool, 50 * sizeof(WCHAR));
1307 memcpy(*PacketDriverName, L"\\Device\\NPF_ne2000", 19 * sizeof(WCHAR));
1308 Status = STATUS_SUCCESS;
1309
1310 }
1311
1312 ExFreePool(Path);
1313 return Status;
1314 }
1315
1316 //-------------------------------------------------------------------
1317
1318 NTSTATUS STDCALL
1319 NPF_QueryRegistryRoutine(
1320 IN PWSTR ValueName,
1321 IN ULONG ValueType,
1322 IN PVOID ValueData,
1323 IN ULONG ValueLength,
1324 IN PVOID Context,
1325 IN PVOID EntryContext
1326 )
1327
1328 {
1329
1330 PUCHAR Buffer;
1331
1332 IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");)
1333
1334 if (ValueType != REG_MULTI_SZ) {
1335
1336 return STATUS_OBJECT_NAME_NOT_FOUND;
1337
1338 }
1339
1340 #define NPF_TAG_REGBUF TAG('8', 'P', 'W', 'A')
1341 Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, NPF_TAG_REGBUF);
1342
1343 if (Buffer==NULL) {
1344
1345 return STATUS_INSUFFICIENT_RESOURCES;
1346
1347 }
1348
1349 RtlCopyMemory(
1350 Buffer,
1351 ValueData,
1352 ValueLength
1353 );
1354
1355 *((PUCHAR *)EntryContext)=Buffer;
1356
1357 return STATUS_SUCCESS;
1358
1359 }