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>
27 #include "include/logging.h"
29 #include "include/NetVscApi.h"
30 #include "RndisFilter.h"
36 typedef struct _RNDIS_FILTER_DRIVER_OBJECT {
37 // The original driver
38 NETVSC_DRIVER_OBJECT InnerDriver;
40 } RNDIS_FILTER_DRIVER_OBJECT;
43 RNDIS_DEV_UNINITIALIZED = 0,
44 RNDIS_DEV_INITIALIZING,
45 RNDIS_DEV_INITIALIZED,
46 RNDIS_DEV_DATAINITIALIZED,
49 typedef struct _RNDIS_DEVICE {
50 NETVSC_DEVICE *NetDevice;
52 RNDIS_DEVICE_STATE State;
57 LIST_ENTRY RequestList;
59 unsigned char HwMacAddr[HW_MACADDR_LEN];
63 typedef struct _RNDIS_REQUEST {
67 // FIXME: We assumed a fixed size response here. If we do ever need to handle a bigger response,
68 // we can either define a max response message or add a response buffer variable above this field
69 RNDIS_MESSAGE ResponseMessage;
71 // Simplify allocation by having a netvsc packet inline
74 // FIXME: We assumed a fixed size request here.
75 RNDIS_MESSAGE RequestMessage;
79 typedef struct _RNDIS_FILTER_PACKET {
80 void *CompletionContext;
81 PFN_ON_SENDRECVCOMPLETION OnCompletion;
83 RNDIS_MESSAGE Message;
84 } RNDIS_FILTER_PACKET;
90 RndisFilterSendRequest(
92 RNDIS_REQUEST *Request
96 RndisFilterReceiveResponse(
98 RNDIS_MESSAGE *Response
102 RndisFilterReceiveIndicateStatus(
103 RNDIS_DEVICE *Device,
104 RNDIS_MESSAGE *Response
108 RndisFilterReceiveData(
109 RNDIS_DEVICE *Device,
110 RNDIS_MESSAGE *Message,
111 NETVSC_PACKET *Packet
115 RndisFilterOnReceive(
116 DEVICE_OBJECT *Device,
117 NETVSC_PACKET *Packet
121 RndisFilterQueryDevice(
122 RNDIS_DEVICE *Device,
129 RndisFilterQueryDeviceMac(
134 RndisFilterQueryDeviceLinkStatus(
139 RndisFilterSetPacketFilter(
140 RNDIS_DEVICE *Device,
145 RndisFilterInitDevice(
150 RndisFilterOpenDevice(
155 RndisFilterCloseDevice(
160 RndisFilterOnDeviceAdd(
161 DEVICE_OBJECT *Device,
166 RndisFilterOnDeviceRemove(
167 DEVICE_OBJECT *Device
171 RndisFilterOnCleanup(
172 DRIVER_OBJECT *Driver
177 DEVICE_OBJECT *Device
182 DEVICE_OBJECT *Device
187 DEVICE_OBJECT *Device,
188 NETVSC_PACKET *Packet
192 RndisFilterOnSendCompletion(
197 RndisFilterOnSendRequestCompletion(
206 RNDIS_FILTER_DRIVER_OBJECT gRndisFilter;
208 static inline RNDIS_DEVICE* GetRndisDevice(void)
210 RNDIS_DEVICE *device;
212 device = MemAllocZeroed(sizeof(RNDIS_DEVICE));
218 device->RequestLock = SpinlockCreate();
219 if (!device->RequestLock)
225 INITIALIZE_LIST_HEAD(&device->RequestList);
227 device->State = RNDIS_DEV_UNINITIALIZED;
232 static inline void PutRndisDevice(RNDIS_DEVICE *Device)
234 SpinlockClose(Device->RequestLock);
238 static inline RNDIS_REQUEST* GetRndisRequest(RNDIS_DEVICE *Device, u32 MessageType, u32 MessageLength)
240 RNDIS_REQUEST *request;
241 RNDIS_MESSAGE *rndisMessage;
242 RNDIS_SET_REQUEST *set;
244 request = MemAllocZeroed(sizeof(RNDIS_REQUEST));
250 request->WaitEvent = WaitEventCreate();
251 if (!request->WaitEvent)
257 rndisMessage = &request->RequestMessage;
258 rndisMessage->NdisMessageType = MessageType;
259 rndisMessage->MessageLength = MessageLength;
261 // Set the request id. This field is always after the rndis header for request/response packet types so
262 // we just used the SetRequest as a template
263 set = &rndisMessage->Message.SetRequest;
264 set->RequestId = InterlockedIncrement((int*)&Device->NewRequestId);
266 // Add to the request list
267 SpinlockAcquire(Device->RequestLock);
268 INSERT_TAIL_LIST(&Device->RequestList, &request->ListEntry);
269 SpinlockRelease(Device->RequestLock);
274 static inline void PutRndisRequest(RNDIS_DEVICE *Device, RNDIS_REQUEST *Request)
276 SpinlockAcquire(Device->RequestLock);
277 REMOVE_ENTRY_LIST(&Request->ListEntry);
278 SpinlockRelease(Device->RequestLock);
280 WaitEventClose(Request->WaitEvent);
284 static inline void DumpRndisMessage(RNDIS_MESSAGE *RndisMessage)
286 switch (RndisMessage->NdisMessageType)
288 case REMOTE_NDIS_PACKET_MSG:
289 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",
290 RndisMessage->MessageLength,
291 RndisMessage->Message.Packet.DataOffset,
292 RndisMessage->Message.Packet.DataLength,
293 RndisMessage->Message.Packet.NumOOBDataElements,
294 RndisMessage->Message.Packet.OOBDataOffset,
295 RndisMessage->Message.Packet.OOBDataLength,
296 RndisMessage->Message.Packet.PerPacketInfoOffset,
297 RndisMessage->Message.Packet.PerPacketInfoLength);
300 case REMOTE_NDIS_INITIALIZE_CMPLT:
301 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)",
302 RndisMessage->MessageLength,
303 RndisMessage->Message.InitializeComplete.RequestId,
304 RndisMessage->Message.InitializeComplete.Status,
305 RndisMessage->Message.InitializeComplete.MajorVersion,
306 RndisMessage->Message.InitializeComplete.MinorVersion,
307 RndisMessage->Message.InitializeComplete.DeviceFlags,
308 RndisMessage->Message.InitializeComplete.MaxTransferSize,
309 RndisMessage->Message.InitializeComplete.MaxPacketsPerMessage,
310 RndisMessage->Message.InitializeComplete.PacketAlignmentFactor);
313 case REMOTE_NDIS_QUERY_CMPLT:
314 DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT (len %u, id 0x%x, status 0x%x, buf len %u, buf offset %u)",
315 RndisMessage->MessageLength,
316 RndisMessage->Message.QueryComplete.RequestId,
317 RndisMessage->Message.QueryComplete.Status,
318 RndisMessage->Message.QueryComplete.InformationBufferLength,
319 RndisMessage->Message.QueryComplete.InformationBufferOffset);
322 case REMOTE_NDIS_SET_CMPLT:
323 DPRINT_DBG(NETVSC, "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)",
324 RndisMessage->MessageLength,
325 RndisMessage->Message.SetComplete.RequestId,
326 RndisMessage->Message.SetComplete.Status);
329 case REMOTE_NDIS_INDICATE_STATUS_MSG:
330 DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG (len %u, status 0x%x, buf len %u, buf offset %u)",
331 RndisMessage->MessageLength,
332 RndisMessage->Message.IndicateStatus.Status,
333 RndisMessage->Message.IndicateStatus.StatusBufferLength,
334 RndisMessage->Message.IndicateStatus.StatusBufferOffset);
338 DPRINT_DBG(NETVSC, "0x%x (len %u)",
339 RndisMessage->NdisMessageType,
340 RndisMessage->MessageLength);
346 RndisFilterSendRequest(
347 RNDIS_DEVICE *Device,
348 RNDIS_REQUEST *Request
352 NETVSC_PACKET *packet;
354 DPRINT_ENTER(NETVSC);
356 // Setup the packet to send it
357 packet = &Request->Packet;
359 packet->IsDataPacket = FALSE;
360 packet->TotalDataBufferLength = Request->RequestMessage.MessageLength;
361 packet->PageBufferCount = 1;
363 packet->PageBuffers[0].Pfn = GetPhysicalAddress(&Request->RequestMessage) >> PAGE_SHIFT;
364 packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength;
365 packet->PageBuffers[0].Offset = (unsigned long)&Request->RequestMessage & (PAGE_SIZE -1);
367 packet->Completion.Send.SendCompletionContext = Request;//packet;
368 packet->Completion.Send.OnSendCompletion = RndisFilterOnSendRequestCompletion;
369 packet->Completion.Send.SendCompletionTid = (unsigned long)Device;
371 ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet);
378 RndisFilterReceiveResponse(
379 RNDIS_DEVICE *Device,
380 RNDIS_MESSAGE *Response
385 RNDIS_REQUEST *request=NULL;
388 DPRINT_ENTER(NETVSC);
390 SpinlockAcquire(Device->RequestLock);
391 ITERATE_LIST_ENTRIES(anchor, curr, &Device->RequestList)
393 request = CONTAINING_RECORD(curr, RNDIS_REQUEST, ListEntry);
395 // All request/response message contains RequestId as the 1st field
396 if (request->RequestMessage.Message.InitializeRequest.RequestId == Response->Message.InitializeComplete.RequestId)
398 DPRINT_DBG(NETVSC, "found rndis request for this response (id 0x%x req type 0x%x res type 0x%x)",
399 request->RequestMessage.Message.InitializeRequest.RequestId, request->RequestMessage.NdisMessageType, Response->NdisMessageType);
405 SpinlockRelease(Device->RequestLock);
409 if (Response->MessageLength <= sizeof(RNDIS_MESSAGE))
411 memcpy(&request->ResponseMessage, Response, Response->MessageLength);
415 DPRINT_ERR(NETVSC, "rndis response buffer overflow detected (size %u max %u)", Response->MessageLength, sizeof(RNDIS_FILTER_PACKET));
417 if (Response->NdisMessageType == REMOTE_NDIS_RESET_CMPLT) // does not have a request id field
419 request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW;
423 request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW;
427 WaitEventSet(request->WaitEvent);
431 DPRINT_ERR(NETVSC, "no rndis request found for this response (id 0x%x res type 0x%x)",
432 Response->Message.InitializeComplete.RequestId, Response->NdisMessageType);
439 RndisFilterReceiveIndicateStatus(
440 RNDIS_DEVICE *Device,
441 RNDIS_MESSAGE *Response
444 RNDIS_INDICATE_STATUS *indicate = &Response->Message.IndicateStatus;
446 if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT)
448 gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1);
450 else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT)
452 gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0);
461 RndisFilterReceiveData(
462 RNDIS_DEVICE *Device,
463 RNDIS_MESSAGE *Message,
464 NETVSC_PACKET *Packet
467 RNDIS_PACKET *rndisPacket;
470 DPRINT_ENTER(NETVSC);
472 // empty ethernet frame ??
473 ASSERT(Packet->PageBuffers[0].Length > RNDIS_MESSAGE_SIZE(RNDIS_PACKET));
475 rndisPacket = &Message->Message.Packet;
477 // FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
478 // netvsc packet (ie TotalDataBufferLength != MessageLength)
480 // Remove the rndis header and pass it back up the stack
481 dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset;
483 Packet->TotalDataBufferLength -= dataOffset;
484 Packet->PageBuffers[0].Offset += dataOffset;
485 Packet->PageBuffers[0].Length -= dataOffset;
487 Packet->IsDataPacket = TRUE;
489 gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device, Packet);
495 RndisFilterOnReceive(
496 DEVICE_OBJECT *Device,
497 NETVSC_PACKET *Packet
500 NETVSC_DEVICE *netDevice = (NETVSC_DEVICE*)Device->Extension;
501 RNDIS_DEVICE *rndisDevice;
502 RNDIS_MESSAGE rndisMessage;
503 RNDIS_MESSAGE *rndisHeader;
505 DPRINT_ENTER(NETVSC);
508 //Make sure the rndis device state is initialized
509 if (!netDevice->Extension)
511 DPRINT_ERR(NETVSC, "got rndis message but no rndis device...dropping this message!");
516 rndisDevice = (RNDIS_DEVICE*)netDevice->Extension;
517 if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED)
519 DPRINT_ERR(NETVSC, "got rndis message but rndis device uninitialized...dropping this message!");
524 rndisHeader = (RNDIS_MESSAGE*)PageMapVirtualAddress(Packet->PageBuffers[0].Pfn);
526 rndisHeader = (void*)((unsigned long)rndisHeader + Packet->PageBuffers[0].Offset);
528 // Make sure we got a valid rndis message
529 // FIXME: There seems to be a bug in set completion msg where its MessageLength is 16 bytes but
530 // the ByteCount field in the xfer page range shows 52 bytes
532 if ( Packet->TotalDataBufferLength != rndisHeader->MessageLength )
534 PageUnmapVirtualAddress((void*)(unsigned long)rndisHeader - Packet->PageBuffers[0].Offset);
536 DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u bytes got %u)...dropping this message!",
537 rndisHeader->MessageLength, Packet->TotalDataBufferLength);
543 if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) && (rndisHeader->MessageLength > sizeof(RNDIS_MESSAGE)))
545 DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow detected (got %u, max %u)...marking it an error!",
546 rndisHeader->MessageLength, sizeof(RNDIS_MESSAGE));
549 memcpy(&rndisMessage, rndisHeader, (rndisHeader->MessageLength > sizeof(RNDIS_MESSAGE))?sizeof(RNDIS_MESSAGE):rndisHeader->MessageLength);
551 PageUnmapVirtualAddress((void*)(unsigned long)rndisHeader - Packet->PageBuffers[0].Offset);
553 DumpRndisMessage(&rndisMessage);
555 switch (rndisMessage.NdisMessageType)
558 case REMOTE_NDIS_PACKET_MSG:
559 RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet);
563 case REMOTE_NDIS_INITIALIZE_CMPLT:
564 case REMOTE_NDIS_QUERY_CMPLT:
565 case REMOTE_NDIS_SET_CMPLT:
566 //case REMOTE_NDIS_RESET_CMPLT:
567 //case REMOTE_NDIS_KEEPALIVE_CMPLT:
568 RndisFilterReceiveResponse(rndisDevice, &rndisMessage);
572 case REMOTE_NDIS_INDICATE_STATUS_MSG:
573 RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage);
576 DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", rndisMessage.NdisMessageType, rndisMessage.MessageLength);
586 RndisFilterQueryDevice(
587 RNDIS_DEVICE *Device,
593 RNDIS_REQUEST *request;
594 u32 inresultSize = *ResultSize;
595 RNDIS_QUERY_REQUEST *query;
596 RNDIS_QUERY_COMPLETE *queryComplete;
599 DPRINT_ENTER(NETVSC);
604 request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG, RNDIS_MESSAGE_SIZE(RNDIS_QUERY_REQUEST));
611 // Setup the rndis query
612 query = &request->RequestMessage.Message.QueryRequest;
614 query->InformationBufferOffset = sizeof(RNDIS_QUERY_REQUEST);
615 query->InformationBufferLength = 0;
616 query->DeviceVcHandle = 0;
618 ret = RndisFilterSendRequest(Device, request);
624 WaitEventWait(request->WaitEvent);
626 // Copy the response back
627 queryComplete = &request->ResponseMessage.Message.QueryComplete;
629 if (queryComplete->InformationBufferLength > inresultSize)
636 (void*)((unsigned long)queryComplete + queryComplete->InformationBufferOffset),
637 queryComplete->InformationBufferLength);
639 *ResultSize = queryComplete->InformationBufferLength;
644 PutRndisRequest(Device, request);
652 RndisFilterQueryDeviceMac(
656 u32 size=HW_MACADDR_LEN;
658 return RndisFilterQueryDevice(Device,
659 RNDIS_OID_802_3_PERMANENT_ADDRESS,
665 RndisFilterQueryDeviceLinkStatus(
669 u32 size=sizeof(u32);
671 return RndisFilterQueryDevice(Device,
672 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
678 RndisFilterSetPacketFilter(
679 RNDIS_DEVICE *Device,
683 RNDIS_REQUEST *request;
684 RNDIS_SET_REQUEST *set;
685 RNDIS_SET_COMPLETE *setComplete;
689 DPRINT_ENTER(NETVSC);
691 ASSERT(RNDIS_MESSAGE_SIZE(RNDIS_SET_REQUEST) + sizeof(u32) <= sizeof(RNDIS_MESSAGE));
693 request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(RNDIS_SET_REQUEST) + sizeof(u32));
700 // Setup the rndis set
701 set = &request->RequestMessage.Message.SetRequest;
702 set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
703 set->InformationBufferLength = sizeof(u32);
704 set->InformationBufferOffset = sizeof(RNDIS_SET_REQUEST);
706 memcpy((void*)(unsigned long)set + sizeof(RNDIS_SET_REQUEST), &NewFilter, sizeof(u32));
708 ret = RndisFilterSendRequest(Device, request);
714 ret = WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/);
718 DPRINT_ERR(NETVSC, "timeout before we got a set response...");
719 // We cant deallocate the request since we may still receive a send completion for it.
728 setComplete = &request->ResponseMessage.Message.SetComplete;
729 status = setComplete->Status;
735 PutRndisRequest(Device, request);
745 NETVSC_DRIVER_OBJECT *Driver
748 DPRINT_ENTER(NETVSC);
750 DPRINT_DBG(NETVSC, "sizeof(RNDIS_FILTER_PACKET) == %d", sizeof(RNDIS_FILTER_PACKET));
752 Driver->RequestExtSize = sizeof(RNDIS_FILTER_PACKET);
753 Driver->AdditionalRequestPageBufferCount = 1; // For rndis header
755 //Driver->Context = rndisDriver;
757 memset(&gRndisFilter, 0, sizeof(RNDIS_FILTER_DRIVER_OBJECT));
759 /*rndisDriver->Driver = Driver;
761 ASSERT(Driver->OnLinkStatusChanged);
762 rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/
764 // Save the original dispatch handlers before we override it
765 gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd;
766 gRndisFilter.InnerDriver.Base.OnDeviceRemove = Driver->Base.OnDeviceRemove;
767 gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup;
769 ASSERT(Driver->OnSend);
770 ASSERT(Driver->OnReceiveCallback);
771 gRndisFilter.InnerDriver.OnSend = Driver->OnSend;
772 gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback;
773 gRndisFilter.InnerDriver.OnLinkStatusChanged = Driver->OnLinkStatusChanged;
776 Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd;
777 Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
778 Driver->Base.OnCleanup = RndisFilterOnCleanup;
779 Driver->OnSend = RndisFilterOnSend;
780 Driver->OnOpen = RndisFilterOnOpen;
781 Driver->OnClose = RndisFilterOnClose;
782 //Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus;
783 Driver->OnReceiveCallback = RndisFilterOnReceive;
791 RndisFilterInitDevice(
795 RNDIS_REQUEST *request;
796 RNDIS_INITIALIZE_REQUEST *init;
797 RNDIS_INITIALIZE_COMPLETE *initComplete;
801 DPRINT_ENTER(NETVSC);
803 request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG, RNDIS_MESSAGE_SIZE(RNDIS_INITIALIZE_REQUEST));
810 // Setup the rndis set
811 init = &request->RequestMessage.Message.InitializeRequest;
812 init->MajorVersion = RNDIS_MAJOR_VERSION;
813 init->MinorVersion = RNDIS_MINOR_VERSION;
814 init->MaxTransferSize = 2048; // FIXME: Use 1536 - rounded ethernet frame size
816 Device->State = RNDIS_DEV_INITIALIZING;
818 ret = RndisFilterSendRequest(Device, request);
821 Device->State = RNDIS_DEV_UNINITIALIZED;
825 WaitEventWait(request->WaitEvent);
827 initComplete = &request->ResponseMessage.Message.InitializeComplete;
828 status = initComplete->Status;
829 if (status == RNDIS_STATUS_SUCCESS)
831 Device->State = RNDIS_DEV_INITIALIZED;
836 Device->State = RNDIS_DEV_UNINITIALIZED;
843 PutRndisRequest(Device, request);
851 RndisFilterHaltDevice(
855 RNDIS_REQUEST *request;
856 RNDIS_HALT_REQUEST *halt;
858 DPRINT_ENTER(NETVSC);
860 // Attempt to do a rndis device halt
861 request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG, RNDIS_MESSAGE_SIZE(RNDIS_HALT_REQUEST));
867 // Setup the rndis set
868 halt = &request->RequestMessage.Message.HaltRequest;
869 halt->RequestId = InterlockedIncrement((int*)&Device->NewRequestId);
871 // Ignore return since this msg is optional.
872 RndisFilterSendRequest(Device, request);
874 Device->State = RNDIS_DEV_UNINITIALIZED;
879 PutRndisRequest(Device, request);
887 RndisFilterOpenDevice(
893 DPRINT_ENTER(NETVSC);
895 if (Device->State != RNDIS_DEV_INITIALIZED)
898 ret = RndisFilterSetPacketFilter(Device, NDIS_PACKET_TYPE_BROADCAST|NDIS_PACKET_TYPE_DIRECTED);
901 Device->State = RNDIS_DEV_DATAINITIALIZED;
909 RndisFilterCloseDevice(
915 DPRINT_ENTER(NETVSC);
917 if (Device->State != RNDIS_DEV_DATAINITIALIZED)
920 ret = RndisFilterSetPacketFilter(Device, 0);
923 Device->State = RNDIS_DEV_INITIALIZED;
933 RndisFilterOnDeviceAdd(
934 DEVICE_OBJECT *Device,
939 NETVSC_DEVICE *netDevice;
940 RNDIS_DEVICE *rndisDevice;
941 NETVSC_DEVICE_INFO *deviceInfo = (NETVSC_DEVICE_INFO*)AdditionalInfo;
943 DPRINT_ENTER(NETVSC);
945 //rndisDevice = MemAlloc(sizeof(RNDIS_DEVICE));
946 rndisDevice = GetRndisDevice();
953 DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
955 // Let the inner driver handle this first to create the netvsc channel
956 // NOTE! Once the channel is created, we may get a receive callback
957 // (RndisFilterOnReceive()) before this call is completed
958 ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo);
961 PutRndisDevice(rndisDevice);
967 // Initialize the rndis device
969 netDevice = (NETVSC_DEVICE*)Device->Extension;
971 ASSERT(netDevice->Device);
973 netDevice->Extension = rndisDevice;
974 rndisDevice->NetDevice = netDevice;
976 // Send the rndis initialization message
977 ret = RndisFilterInitDevice(rndisDevice);
980 // TODO: If rndis init failed, we will need to shut down the channel
983 // Get the mac address
984 ret = RndisFilterQueryDeviceMac(rndisDevice);
987 // TODO: shutdown rndis device and the channel
990 DPRINT_INFO(NETVSC, "Device 0x%p mac addr %02x%02x%02x%02x%02x%02x",
992 rndisDevice->HwMacAddr[0],
993 rndisDevice->HwMacAddr[1],
994 rndisDevice->HwMacAddr[2],
995 rndisDevice->HwMacAddr[3],
996 rndisDevice->HwMacAddr[4],
997 rndisDevice->HwMacAddr[5]);
999 memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, HW_MACADDR_LEN);
1001 RndisFilterQueryDeviceLinkStatus(rndisDevice);
1003 deviceInfo->LinkState = rndisDevice->LinkStatus;
1004 DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, ((deviceInfo->LinkState)?("down"):("up")));
1006 DPRINT_EXIT(NETVSC);
1013 RndisFilterOnDeviceRemove(
1014 DEVICE_OBJECT *Device
1017 NETVSC_DEVICE *netDevice = (NETVSC_DEVICE*)Device->Extension;
1018 RNDIS_DEVICE *rndisDevice = (RNDIS_DEVICE*)netDevice->Extension;
1020 DPRINT_ENTER(NETVSC);
1022 // Halt and release the rndis device
1023 RndisFilterHaltDevice(rndisDevice);
1025 PutRndisDevice(rndisDevice);
1026 netDevice->Extension = NULL;
1028 // Pass control to inner driver to remove the device
1029 gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device);
1031 DPRINT_EXIT(NETVSC);
1038 RndisFilterOnCleanup(
1039 DRIVER_OBJECT *Driver
1042 DPRINT_ENTER(NETVSC);
1044 DPRINT_EXIT(NETVSC);
1049 DEVICE_OBJECT *Device
1053 NETVSC_DEVICE *netDevice = (NETVSC_DEVICE*)Device->Extension;
1055 DPRINT_ENTER(NETVSC);
1058 ret = RndisFilterOpenDevice((RNDIS_DEVICE*)netDevice->Extension);
1060 DPRINT_EXIT(NETVSC);
1067 DEVICE_OBJECT *Device
1071 NETVSC_DEVICE *netDevice = (NETVSC_DEVICE*)Device->Extension;
1073 DPRINT_ENTER(NETVSC);
1076 ret = RndisFilterCloseDevice((RNDIS_DEVICE*)netDevice->Extension);
1078 DPRINT_EXIT(NETVSC);
1086 DEVICE_OBJECT *Device,
1087 NETVSC_PACKET *Packet
1091 RNDIS_FILTER_PACKET *filterPacket;
1092 RNDIS_MESSAGE *rndisMessage;
1093 RNDIS_PACKET *rndisPacket;
1094 u32 rndisMessageSize;
1096 DPRINT_ENTER(NETVSC);
1098 // Add the rndis header
1099 filterPacket = (RNDIS_FILTER_PACKET*)Packet->Extension;
1100 ASSERT(filterPacket);
1102 memset(filterPacket, 0, sizeof(RNDIS_FILTER_PACKET));
1104 rndisMessage = &filterPacket->Message;
1105 rndisMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_PACKET);
1107 rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG;
1108 rndisMessage->MessageLength = Packet->TotalDataBufferLength + rndisMessageSize;
1110 rndisPacket = &rndisMessage->Message.Packet;
1111 rndisPacket->DataOffset = sizeof(RNDIS_PACKET);
1112 rndisPacket->DataLength = Packet->TotalDataBufferLength;
1114 Packet->IsDataPacket = TRUE;
1115 Packet->PageBuffers[0].Pfn = GetPhysicalAddress(rndisMessage) >> PAGE_SHIFT;
1116 Packet->PageBuffers[0].Offset = (unsigned long)rndisMessage & (PAGE_SIZE-1);
1117 Packet->PageBuffers[0].Length = rndisMessageSize;
1119 // Save the packet send completion and context
1120 filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion;
1121 filterPacket->CompletionContext = Packet->Completion.Send.SendCompletionContext;
1124 Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion;
1125 Packet->Completion.Send.SendCompletionContext = filterPacket;
1127 ret = gRndisFilter.InnerDriver.OnSend(Device, Packet);
1130 // Reset the completion to originals to allow retries from above
1131 Packet->Completion.Send.OnSendCompletion = filterPacket->OnCompletion;
1132 Packet->Completion.Send.SendCompletionContext = filterPacket->CompletionContext;
1135 DPRINT_EXIT(NETVSC);
1141 RndisFilterOnSendCompletion(
1144 RNDIS_FILTER_PACKET *filterPacket = (RNDIS_FILTER_PACKET *)Context;
1146 DPRINT_ENTER(NETVSC);
1148 // Pass it back to the original handler
1149 filterPacket->OnCompletion(filterPacket->CompletionContext);
1151 DPRINT_EXIT(NETVSC);
1156 RndisFilterOnSendRequestCompletion(
1160 DPRINT_ENTER(NETVSC);
1163 DPRINT_EXIT(NETVSC);