3 * Copyright (c) 2009, Microsoft Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
26 #include <linux/kernel.h>
28 #include "include/logging.h"
30 #include "include/NetVscApi.h"
31 #include "RndisFilter.h"
37 typedef struct _RNDIS_FILTER_DRIVER_OBJECT {
38 // The original driver
39 NETVSC_DRIVER_OBJECT InnerDriver;
41 } RNDIS_FILTER_DRIVER_OBJECT;
44 RNDIS_DEV_UNINITIALIZED = 0,
45 RNDIS_DEV_INITIALIZING,
46 RNDIS_DEV_INITIALIZED,
47 RNDIS_DEV_DATAINITIALIZED,
50 typedef struct _RNDIS_DEVICE {
51 NETVSC_DEVICE *NetDevice;
53 RNDIS_DEVICE_STATE State;
58 LIST_ENTRY RequestList;
60 unsigned char HwMacAddr[HW_MACADDR_LEN];
64 typedef struct _RNDIS_REQUEST {
68 // FIXME: We assumed a fixed size response here. If we do ever need to handle a bigger response,
69 // we can either define a max response message or add a response buffer variable above this field
70 RNDIS_MESSAGE ResponseMessage;
72 // Simplify allocation by having a netvsc packet inline
75 // FIXME: We assumed a fixed size request here.
76 RNDIS_MESSAGE RequestMessage;
80 typedef struct _RNDIS_FILTER_PACKET {
81 void *CompletionContext;
82 PFN_ON_SENDRECVCOMPLETION OnCompletion;
84 RNDIS_MESSAGE Message;
85 } RNDIS_FILTER_PACKET;
91 RndisFilterSendRequest(
93 RNDIS_REQUEST *Request
97 RndisFilterReceiveResponse(
99 RNDIS_MESSAGE *Response
103 RndisFilterReceiveIndicateStatus(
104 RNDIS_DEVICE *Device,
105 RNDIS_MESSAGE *Response
109 RndisFilterReceiveData(
110 RNDIS_DEVICE *Device,
111 RNDIS_MESSAGE *Message,
112 NETVSC_PACKET *Packet
116 RndisFilterOnReceive(
117 DEVICE_OBJECT *Device,
118 NETVSC_PACKET *Packet
122 RndisFilterQueryDevice(
123 RNDIS_DEVICE *Device,
130 RndisFilterQueryDeviceMac(
135 RndisFilterQueryDeviceLinkStatus(
140 RndisFilterSetPacketFilter(
141 RNDIS_DEVICE *Device,
146 RndisFilterInitDevice(
151 RndisFilterOpenDevice(
156 RndisFilterCloseDevice(
161 RndisFilterOnDeviceAdd(
162 DEVICE_OBJECT *Device,
167 RndisFilterOnDeviceRemove(
168 DEVICE_OBJECT *Device
172 RndisFilterOnCleanup(
173 DRIVER_OBJECT *Driver
178 DEVICE_OBJECT *Device
183 DEVICE_OBJECT *Device
188 DEVICE_OBJECT *Device,
189 NETVSC_PACKET *Packet
193 RndisFilterOnSendCompletion(
198 RndisFilterOnSendRequestCompletion(
207 RNDIS_FILTER_DRIVER_OBJECT gRndisFilter;
209 static inline RNDIS_DEVICE* GetRndisDevice(void)
211 RNDIS_DEVICE *device;
213 device = MemAllocZeroed(sizeof(RNDIS_DEVICE));
219 device->RequestLock = SpinlockCreate();
220 if (!device->RequestLock)
226 INITIALIZE_LIST_HEAD(&device->RequestList);
228 device->State = RNDIS_DEV_UNINITIALIZED;
233 static inline void PutRndisDevice(RNDIS_DEVICE *Device)
235 SpinlockClose(Device->RequestLock);
239 static inline RNDIS_REQUEST* GetRndisRequest(RNDIS_DEVICE *Device, u32 MessageType, u32 MessageLength)
241 RNDIS_REQUEST *request;
242 RNDIS_MESSAGE *rndisMessage;
243 RNDIS_SET_REQUEST *set;
245 request = MemAllocZeroed(sizeof(RNDIS_REQUEST));
251 request->WaitEvent = WaitEventCreate();
252 if (!request->WaitEvent)
258 rndisMessage = &request->RequestMessage;
259 rndisMessage->NdisMessageType = MessageType;
260 rndisMessage->MessageLength = MessageLength;
262 // Set the request id. This field is always after the rndis header for request/response packet types so
263 // we just used the SetRequest as a template
264 set = &rndisMessage->Message.SetRequest;
265 set->RequestId = InterlockedIncrement((int*)&Device->NewRequestId);
267 // Add to the request list
268 SpinlockAcquire(Device->RequestLock);
269 INSERT_TAIL_LIST(&Device->RequestList, &request->ListEntry);
270 SpinlockRelease(Device->RequestLock);
275 static inline void PutRndisRequest(RNDIS_DEVICE *Device, RNDIS_REQUEST *Request)
277 SpinlockAcquire(Device->RequestLock);
278 REMOVE_ENTRY_LIST(&Request->ListEntry);
279 SpinlockRelease(Device->RequestLock);
281 WaitEventClose(Request->WaitEvent);
285 static inline void DumpRndisMessage(RNDIS_MESSAGE *RndisMessage)
287 switch (RndisMessage->NdisMessageType)
289 case REMOTE_NDIS_PACKET_MSG:
290 DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, data offset %u data len %u, # oob %u, oob offset %u, oob len %u, pkt offset %u, pkt len %u",
291 RndisMessage->MessageLength,
292 RndisMessage->Message.Packet.DataOffset,
293 RndisMessage->Message.Packet.DataLength,
294 RndisMessage->Message.Packet.NumOOBDataElements,
295 RndisMessage->Message.Packet.OOBDataOffset,
296 RndisMessage->Message.Packet.OOBDataLength,
297 RndisMessage->Message.Packet.PerPacketInfoOffset,
298 RndisMessage->Message.Packet.PerPacketInfoLength);
301 case REMOTE_NDIS_INITIALIZE_CMPLT:
302 DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT (len %u, id 0x%x, status 0x%x, major %d, minor %d, device flags %d, max xfer size 0x%x, max pkts %u, pkt aligned %u)",
303 RndisMessage->MessageLength,
304 RndisMessage->Message.InitializeComplete.RequestId,
305 RndisMessage->Message.InitializeComplete.Status,
306 RndisMessage->Message.InitializeComplete.MajorVersion,
307 RndisMessage->Message.InitializeComplete.MinorVersion,
308 RndisMessage->Message.InitializeComplete.DeviceFlags,
309 RndisMessage->Message.InitializeComplete.MaxTransferSize,
310 RndisMessage->Message.InitializeComplete.MaxPacketsPerMessage,
311 RndisMessage->Message.InitializeComplete.PacketAlignmentFactor);
314 case REMOTE_NDIS_QUERY_CMPLT:
315 DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT (len %u, id 0x%x, status 0x%x, buf len %u, buf offset %u)",
316 RndisMessage->MessageLength,
317 RndisMessage->Message.QueryComplete.RequestId,
318 RndisMessage->Message.QueryComplete.Status,
319 RndisMessage->Message.QueryComplete.InformationBufferLength,
320 RndisMessage->Message.QueryComplete.InformationBufferOffset);
323 case REMOTE_NDIS_SET_CMPLT:
324 DPRINT_DBG(NETVSC, "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)",
325 RndisMessage->MessageLength,
326 RndisMessage->Message.SetComplete.RequestId,
327 RndisMessage->Message.SetComplete.Status);
330 case REMOTE_NDIS_INDICATE_STATUS_MSG:
331 DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG (len %u, status 0x%x, buf len %u, buf offset %u)",
332 RndisMessage->MessageLength,
333 RndisMessage->Message.IndicateStatus.Status,
334 RndisMessage->Message.IndicateStatus.StatusBufferLength,
335 RndisMessage->Message.IndicateStatus.StatusBufferOffset);
339 DPRINT_DBG(NETVSC, "0x%x (len %u)",
340 RndisMessage->NdisMessageType,
341 RndisMessage->MessageLength);
347 RndisFilterSendRequest(
348 RNDIS_DEVICE *Device,
349 RNDIS_REQUEST *Request
353 NETVSC_PACKET *packet;
355 DPRINT_ENTER(NETVSC);
357 // Setup the packet to send it
358 packet = &Request->Packet;
360 packet->IsDataPacket = false;
361 packet->TotalDataBufferLength = Request->RequestMessage.MessageLength;
362 packet->PageBufferCount = 1;
364 packet->PageBuffers[0].Pfn = GetPhysicalAddress(&Request->RequestMessage) >> PAGE_SHIFT;
365 packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength;
366 packet->PageBuffers[0].Offset = (unsigned long)&Request->RequestMessage & (PAGE_SIZE -1);
368 packet->Completion.Send.SendCompletionContext = Request;//packet;
369 packet->Completion.Send.OnSendCompletion = RndisFilterOnSendRequestCompletion;
370 packet->Completion.Send.SendCompletionTid = (unsigned long)Device;
372 ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet);
379 RndisFilterReceiveResponse(
380 RNDIS_DEVICE *Device,
381 RNDIS_MESSAGE *Response
386 RNDIS_REQUEST *request=NULL;
389 DPRINT_ENTER(NETVSC);
391 SpinlockAcquire(Device->RequestLock);
392 ITERATE_LIST_ENTRIES(anchor, curr, &Device->RequestList)
394 request = CONTAINING_RECORD(curr, RNDIS_REQUEST, ListEntry);
396 // All request/response message contains RequestId as the 1st field
397 if (request->RequestMessage.Message.InitializeRequest.RequestId == Response->Message.InitializeComplete.RequestId)
399 DPRINT_DBG(NETVSC, "found rndis request for this response (id 0x%x req type 0x%x res type 0x%x)",
400 request->RequestMessage.Message.InitializeRequest.RequestId, request->RequestMessage.NdisMessageType, Response->NdisMessageType);
406 SpinlockRelease(Device->RequestLock);
410 if (Response->MessageLength <= sizeof(RNDIS_MESSAGE))
412 memcpy(&request->ResponseMessage, Response, Response->MessageLength);
416 DPRINT_ERR(NETVSC, "rndis response buffer overflow detected (size %u max %u)", Response->MessageLength, sizeof(RNDIS_FILTER_PACKET));
418 if (Response->NdisMessageType == REMOTE_NDIS_RESET_CMPLT) // does not have a request id field
420 request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW;
424 request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW;
428 WaitEventSet(request->WaitEvent);
432 DPRINT_ERR(NETVSC, "no rndis request found for this response (id 0x%x res type 0x%x)",
433 Response->Message.InitializeComplete.RequestId, Response->NdisMessageType);
440 RndisFilterReceiveIndicateStatus(
441 RNDIS_DEVICE *Device,
442 RNDIS_MESSAGE *Response
445 RNDIS_INDICATE_STATUS *indicate = &Response->Message.IndicateStatus;
447 if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT)
449 gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1);
451 else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT)
453 gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0);
462 RndisFilterReceiveData(
463 RNDIS_DEVICE *Device,
464 RNDIS_MESSAGE *Message,
465 NETVSC_PACKET *Packet
468 RNDIS_PACKET *rndisPacket;
471 DPRINT_ENTER(NETVSC);
473 // empty ethernet frame ??
474 ASSERT(Packet->PageBuffers[0].Length > RNDIS_MESSAGE_SIZE(RNDIS_PACKET));
476 rndisPacket = &Message->Message.Packet;
478 // FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
479 // netvsc packet (ie TotalDataBufferLength != MessageLength)
481 // Remove the rndis header and pass it back up the stack
482 dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset;
484 Packet->TotalDataBufferLength -= dataOffset;
485 Packet->PageBuffers[0].Offset += dataOffset;
486 Packet->PageBuffers[0].Length -= dataOffset;
488 Packet->IsDataPacket = true;
490 gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device, Packet);
496 RndisFilterOnReceive(
497 DEVICE_OBJECT *Device,
498 NETVSC_PACKET *Packet
501 NETVSC_DEVICE *netDevice = (NETVSC_DEVICE*)Device->Extension;
502 RNDIS_DEVICE *rndisDevice;
503 RNDIS_MESSAGE rndisMessage;
504 RNDIS_MESSAGE *rndisHeader;
506 DPRINT_ENTER(NETVSC);
509 //Make sure the rndis device state is initialized
510 if (!netDevice->Extension)
512 DPRINT_ERR(NETVSC, "got rndis message but no rndis device...dropping this message!");
517 rndisDevice = (RNDIS_DEVICE*)netDevice->Extension;
518 if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED)
520 DPRINT_ERR(NETVSC, "got rndis message but rndis device uninitialized...dropping this message!");
525 rndisHeader = (RNDIS_MESSAGE*)PageMapVirtualAddress(Packet->PageBuffers[0].Pfn);
527 rndisHeader = (void*)((unsigned long)rndisHeader + Packet->PageBuffers[0].Offset);
529 // Make sure we got a valid rndis message
530 // FIXME: There seems to be a bug in set completion msg where its MessageLength is 16 bytes but
531 // the ByteCount field in the xfer page range shows 52 bytes
533 if ( Packet->TotalDataBufferLength != rndisHeader->MessageLength )
535 PageUnmapVirtualAddress((void*)(unsigned long)rndisHeader - Packet->PageBuffers[0].Offset);
537 DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u bytes got %u)...dropping this message!",
538 rndisHeader->MessageLength, Packet->TotalDataBufferLength);
544 if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) && (rndisHeader->MessageLength > sizeof(RNDIS_MESSAGE)))
546 DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow detected (got %u, max %u)...marking it an error!",
547 rndisHeader->MessageLength, sizeof(RNDIS_MESSAGE));
550 memcpy(&rndisMessage, rndisHeader, (rndisHeader->MessageLength > sizeof(RNDIS_MESSAGE))?sizeof(RNDIS_MESSAGE):rndisHeader->MessageLength);
552 PageUnmapVirtualAddress((void*)(unsigned long)rndisHeader - Packet->PageBuffers[0].Offset);
554 DumpRndisMessage(&rndisMessage);
556 switch (rndisMessage.NdisMessageType)
559 case REMOTE_NDIS_PACKET_MSG:
560 RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet);
564 case REMOTE_NDIS_INITIALIZE_CMPLT:
565 case REMOTE_NDIS_QUERY_CMPLT:
566 case REMOTE_NDIS_SET_CMPLT:
567 //case REMOTE_NDIS_RESET_CMPLT:
568 //case REMOTE_NDIS_KEEPALIVE_CMPLT:
569 RndisFilterReceiveResponse(rndisDevice, &rndisMessage);
573 case REMOTE_NDIS_INDICATE_STATUS_MSG:
574 RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage);
577 DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", rndisMessage.NdisMessageType, rndisMessage.MessageLength);
587 RndisFilterQueryDevice(
588 RNDIS_DEVICE *Device,
594 RNDIS_REQUEST *request;
595 u32 inresultSize = *ResultSize;
596 RNDIS_QUERY_REQUEST *query;
597 RNDIS_QUERY_COMPLETE *queryComplete;
600 DPRINT_ENTER(NETVSC);
605 request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG, RNDIS_MESSAGE_SIZE(RNDIS_QUERY_REQUEST));
612 // Setup the rndis query
613 query = &request->RequestMessage.Message.QueryRequest;
615 query->InformationBufferOffset = sizeof(RNDIS_QUERY_REQUEST);
616 query->InformationBufferLength = 0;
617 query->DeviceVcHandle = 0;
619 ret = RndisFilterSendRequest(Device, request);
625 WaitEventWait(request->WaitEvent);
627 // Copy the response back
628 queryComplete = &request->ResponseMessage.Message.QueryComplete;
630 if (queryComplete->InformationBufferLength > inresultSize)
637 (void*)((unsigned long)queryComplete + queryComplete->InformationBufferOffset),
638 queryComplete->InformationBufferLength);
640 *ResultSize = queryComplete->InformationBufferLength;
645 PutRndisRequest(Device, request);
653 RndisFilterQueryDeviceMac(
657 u32 size=HW_MACADDR_LEN;
659 return RndisFilterQueryDevice(Device,
660 RNDIS_OID_802_3_PERMANENT_ADDRESS,
666 RndisFilterQueryDeviceLinkStatus(
670 u32 size=sizeof(u32);
672 return RndisFilterQueryDevice(Device,
673 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
679 RndisFilterSetPacketFilter(
680 RNDIS_DEVICE *Device,
684 RNDIS_REQUEST *request;
685 RNDIS_SET_REQUEST *set;
686 RNDIS_SET_COMPLETE *setComplete;
690 DPRINT_ENTER(NETVSC);
692 ASSERT(RNDIS_MESSAGE_SIZE(RNDIS_SET_REQUEST) + sizeof(u32) <= sizeof(RNDIS_MESSAGE));
694 request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(RNDIS_SET_REQUEST) + sizeof(u32));
701 // Setup the rndis set
702 set = &request->RequestMessage.Message.SetRequest;
703 set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
704 set->InformationBufferLength = sizeof(u32);
705 set->InformationBufferOffset = sizeof(RNDIS_SET_REQUEST);
707 memcpy((void*)(unsigned long)set + sizeof(RNDIS_SET_REQUEST), &NewFilter, sizeof(u32));
709 ret = RndisFilterSendRequest(Device, request);
715 ret = WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/);
719 DPRINT_ERR(NETVSC, "timeout before we got a set response...");
720 // We cant deallocate the request since we may still receive a send completion for it.
729 setComplete = &request->ResponseMessage.Message.SetComplete;
730 status = setComplete->Status;
736 PutRndisRequest(Device, request);
746 NETVSC_DRIVER_OBJECT *Driver
749 DPRINT_ENTER(NETVSC);
751 DPRINT_DBG(NETVSC, "sizeof(RNDIS_FILTER_PACKET) == %d", sizeof(RNDIS_FILTER_PACKET));
753 Driver->RequestExtSize = sizeof(RNDIS_FILTER_PACKET);
754 Driver->AdditionalRequestPageBufferCount = 1; // For rndis header
756 //Driver->Context = rndisDriver;
758 memset(&gRndisFilter, 0, sizeof(RNDIS_FILTER_DRIVER_OBJECT));
760 /*rndisDriver->Driver = Driver;
762 ASSERT(Driver->OnLinkStatusChanged);
763 rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/
765 // Save the original dispatch handlers before we override it
766 gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd;
767 gRndisFilter.InnerDriver.Base.OnDeviceRemove = Driver->Base.OnDeviceRemove;
768 gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup;
770 ASSERT(Driver->OnSend);
771 ASSERT(Driver->OnReceiveCallback);
772 gRndisFilter.InnerDriver.OnSend = Driver->OnSend;
773 gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback;
774 gRndisFilter.InnerDriver.OnLinkStatusChanged = Driver->OnLinkStatusChanged;
777 Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd;
778 Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
779 Driver->Base.OnCleanup = RndisFilterOnCleanup;
780 Driver->OnSend = RndisFilterOnSend;
781 Driver->OnOpen = RndisFilterOnOpen;
782 Driver->OnClose = RndisFilterOnClose;
783 //Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus;
784 Driver->OnReceiveCallback = RndisFilterOnReceive;
792 RndisFilterInitDevice(
796 RNDIS_REQUEST *request;
797 RNDIS_INITIALIZE_REQUEST *init;
798 RNDIS_INITIALIZE_COMPLETE *initComplete;
802 DPRINT_ENTER(NETVSC);
804 request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG, RNDIS_MESSAGE_SIZE(RNDIS_INITIALIZE_REQUEST));
811 // Setup the rndis set
812 init = &request->RequestMessage.Message.InitializeRequest;
813 init->MajorVersion = RNDIS_MAJOR_VERSION;
814 init->MinorVersion = RNDIS_MINOR_VERSION;
815 init->MaxTransferSize = 2048; // FIXME: Use 1536 - rounded ethernet frame size
817 Device->State = RNDIS_DEV_INITIALIZING;
819 ret = RndisFilterSendRequest(Device, request);
822 Device->State = RNDIS_DEV_UNINITIALIZED;
826 WaitEventWait(request->WaitEvent);
828 initComplete = &request->ResponseMessage.Message.InitializeComplete;
829 status = initComplete->Status;
830 if (status == RNDIS_STATUS_SUCCESS)
832 Device->State = RNDIS_DEV_INITIALIZED;
837 Device->State = RNDIS_DEV_UNINITIALIZED;
844 PutRndisRequest(Device, request);
852 RndisFilterHaltDevice(
856 RNDIS_REQUEST *request;
857 RNDIS_HALT_REQUEST *halt;
859 DPRINT_ENTER(NETVSC);
861 // Attempt to do a rndis device halt
862 request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG, RNDIS_MESSAGE_SIZE(RNDIS_HALT_REQUEST));
868 // Setup the rndis set
869 halt = &request->RequestMessage.Message.HaltRequest;
870 halt->RequestId = InterlockedIncrement((int*)&Device->NewRequestId);
872 // Ignore return since this msg is optional.
873 RndisFilterSendRequest(Device, request);
875 Device->State = RNDIS_DEV_UNINITIALIZED;
880 PutRndisRequest(Device, request);
888 RndisFilterOpenDevice(
894 DPRINT_ENTER(NETVSC);
896 if (Device->State != RNDIS_DEV_INITIALIZED)
899 ret = RndisFilterSetPacketFilter(Device, NDIS_PACKET_TYPE_BROADCAST|NDIS_PACKET_TYPE_DIRECTED);
902 Device->State = RNDIS_DEV_DATAINITIALIZED;
910 RndisFilterCloseDevice(
916 DPRINT_ENTER(NETVSC);
918 if (Device->State != RNDIS_DEV_DATAINITIALIZED)
921 ret = RndisFilterSetPacketFilter(Device, 0);
924 Device->State = RNDIS_DEV_INITIALIZED;
934 RndisFilterOnDeviceAdd(
935 DEVICE_OBJECT *Device,
940 NETVSC_DEVICE *netDevice;
941 RNDIS_DEVICE *rndisDevice;
942 NETVSC_DEVICE_INFO *deviceInfo = (NETVSC_DEVICE_INFO*)AdditionalInfo;
944 DPRINT_ENTER(NETVSC);
946 //rndisDevice = MemAlloc(sizeof(RNDIS_DEVICE));
947 rndisDevice = GetRndisDevice();
954 DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
956 // Let the inner driver handle this first to create the netvsc channel
957 // NOTE! Once the channel is created, we may get a receive callback
958 // (RndisFilterOnReceive()) before this call is completed
959 ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo);
962 PutRndisDevice(rndisDevice);
968 // Initialize the rndis device
970 netDevice = (NETVSC_DEVICE*)Device->Extension;
972 ASSERT(netDevice->Device);
974 netDevice->Extension = rndisDevice;
975 rndisDevice->NetDevice = netDevice;
977 // Send the rndis initialization message
978 ret = RndisFilterInitDevice(rndisDevice);
981 // TODO: If rndis init failed, we will need to shut down the channel
984 // Get the mac address
985 ret = RndisFilterQueryDeviceMac(rndisDevice);
988 // TODO: shutdown rndis device and the channel
991 DPRINT_INFO(NETVSC, "Device 0x%p mac addr %02x%02x%02x%02x%02x%02x",
993 rndisDevice->HwMacAddr[0],
994 rndisDevice->HwMacAddr[1],
995 rndisDevice->HwMacAddr[2],
996 rndisDevice->HwMacAddr[3],
997 rndisDevice->HwMacAddr[4],
998 rndisDevice->HwMacAddr[5]);
1000 memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, HW_MACADDR_LEN);
1002 RndisFilterQueryDeviceLinkStatus(rndisDevice);
1004 deviceInfo->LinkState = rndisDevice->LinkStatus;
1005 DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, ((deviceInfo->LinkState)?("down"):("up")));
1007 DPRINT_EXIT(NETVSC);
1014 RndisFilterOnDeviceRemove(
1015 DEVICE_OBJECT *Device
1018 NETVSC_DEVICE *netDevice = (NETVSC_DEVICE*)Device->Extension;
1019 RNDIS_DEVICE *rndisDevice = (RNDIS_DEVICE*)netDevice->Extension;
1021 DPRINT_ENTER(NETVSC);
1023 // Halt and release the rndis device
1024 RndisFilterHaltDevice(rndisDevice);
1026 PutRndisDevice(rndisDevice);
1027 netDevice->Extension = NULL;
1029 // Pass control to inner driver to remove the device
1030 gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device);
1032 DPRINT_EXIT(NETVSC);
1039 RndisFilterOnCleanup(
1040 DRIVER_OBJECT *Driver
1043 DPRINT_ENTER(NETVSC);
1045 DPRINT_EXIT(NETVSC);
1050 DEVICE_OBJECT *Device
1054 NETVSC_DEVICE *netDevice = (NETVSC_DEVICE*)Device->Extension;
1056 DPRINT_ENTER(NETVSC);
1059 ret = RndisFilterOpenDevice((RNDIS_DEVICE*)netDevice->Extension);
1061 DPRINT_EXIT(NETVSC);
1068 DEVICE_OBJECT *Device
1072 NETVSC_DEVICE *netDevice = (NETVSC_DEVICE*)Device->Extension;
1074 DPRINT_ENTER(NETVSC);
1077 ret = RndisFilterCloseDevice((RNDIS_DEVICE*)netDevice->Extension);
1079 DPRINT_EXIT(NETVSC);
1087 DEVICE_OBJECT *Device,
1088 NETVSC_PACKET *Packet
1092 RNDIS_FILTER_PACKET *filterPacket;
1093 RNDIS_MESSAGE *rndisMessage;
1094 RNDIS_PACKET *rndisPacket;
1095 u32 rndisMessageSize;
1097 DPRINT_ENTER(NETVSC);
1099 // Add the rndis header
1100 filterPacket = (RNDIS_FILTER_PACKET*)Packet->Extension;
1101 ASSERT(filterPacket);
1103 memset(filterPacket, 0, sizeof(RNDIS_FILTER_PACKET));
1105 rndisMessage = &filterPacket->Message;
1106 rndisMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_PACKET);
1108 rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG;
1109 rndisMessage->MessageLength = Packet->TotalDataBufferLength + rndisMessageSize;
1111 rndisPacket = &rndisMessage->Message.Packet;
1112 rndisPacket->DataOffset = sizeof(RNDIS_PACKET);
1113 rndisPacket->DataLength = Packet->TotalDataBufferLength;
1115 Packet->IsDataPacket = true;
1116 Packet->PageBuffers[0].Pfn = GetPhysicalAddress(rndisMessage) >> PAGE_SHIFT;
1117 Packet->PageBuffers[0].Offset = (unsigned long)rndisMessage & (PAGE_SIZE-1);
1118 Packet->PageBuffers[0].Length = rndisMessageSize;
1120 // Save the packet send completion and context
1121 filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion;
1122 filterPacket->CompletionContext = Packet->Completion.Send.SendCompletionContext;
1125 Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion;
1126 Packet->Completion.Send.SendCompletionContext = filterPacket;
1128 ret = gRndisFilter.InnerDriver.OnSend(Device, Packet);
1131 // Reset the completion to originals to allow retries from above
1132 Packet->Completion.Send.OnSendCompletion = filterPacket->OnCompletion;
1133 Packet->Completion.Send.SendCompletionContext = filterPacket->CompletionContext;
1136 DPRINT_EXIT(NETVSC);
1142 RndisFilterOnSendCompletion(
1145 RNDIS_FILTER_PACKET *filterPacket = (RNDIS_FILTER_PACKET *)Context;
1147 DPRINT_ENTER(NETVSC);
1149 // Pass it back to the original handler
1150 filterPacket->OnCompletion(filterPacket->CompletionContext);
1152 DPRINT_EXIT(NETVSC);
1157 RndisFilterOnSendRequestCompletion(
1161 DPRINT_ENTER(NETVSC);
1164 DPRINT_EXIT(NETVSC);