⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndis.c

📁 改文件可以安装无线网卡在linux下的驱动,大家可以在网站上查找一下用法
💻 C
📖 第 1 页 / 共 5 页
字号:
	TRACEENTER1("%s", "");	ansi.buf = "mac_address";	ansi.buflen = strlen(ansi.buf);	ansi.len = ansi.buflen;	*len = 0;	*status = NDIS_STATUS_FAILURE;	if (RtlAnsiStringToUnicodeString(&key, &ansi, 1) !=	    NDIS_STATUS_SUCCESS)		TRACEEXIT1(return);	NdisReadConfiguration(status, &setting, handle, &key,			      NDIS_CONFIG_PARAM_STRING);	RtlFreeUnicodeString(&key);	if (*status == NDIS_STATUS_SUCCESS) {		int int_mac[ETH_ALEN];		ret = RtlUnicodeStringToAnsiString(&ansi,						   &setting->data.ustring, 1);		if (ret != NDIS_STATUS_SUCCESS)			TRACEEXIT1(return);		ret = sscanf(ansi.buf, MACSTR, MACINTADR(int_mac));		RtlFreeAnsiString(&ansi);		if (ret == ETH_ALEN) {			int i;			for (i = 0; i < ETH_ALEN; i++)				handle->mac[i] = int_mac[i];			printk(KERN_INFO "%s: %s ethernet device " MACSTR "\n",			       handle->net_dev->name, DRIVER_NAME,			       MAC2STR(handle->mac));			*len = ETH_ALEN;			*addr = handle->mac;			*status = NDIS_STATUS_SUCCESS;		}	}	TRACEEXIT1(return);}STDCALL void WRAP_EXPORT(NdisMRegisterAdapterShutdownHandler)	(struct ndis_handle *handle, void *ctx, void *func){	TRACEENTER1("sp:%p", get_sp());	handle->driver->miniport_char.adapter_shutdown = func;	handle->shutdown_ctx = ctx;}STDCALL void WRAP_EXPORT(NdisMDeregisterAdapterShutdownHandler)	(struct ndis_handle *handle){	TRACEENTER1("sp:%p", get_sp());	handle->driver->miniport_char.adapter_shutdown = NULL;	handle->shutdown_ctx = NULL;}/* bottom half of the irq handler */static void ndis_irq_bh(void *data){	struct ndis_irq *ndis_irq = (struct ndis_irq *)data;	struct ndis_handle *handle = ndis_irq->handle;	struct miniport_char *miniport = &handle->driver->miniport_char;	KIRQL irql;	if (ndis_irq->enabled) {		irql = raise_irql(DISPATCH_LEVEL);		LIN2WIN1(miniport->handle_interrupt, handle->adapter_ctx);		if (miniport->enable_interrupts)			LIN2WIN1(miniport->enable_interrupts,				 handle->adapter_ctx);		lower_irql(irql);	}}/* Top half of the irq handler */static irqreturn_t ndis_irq_th(int irq, void *data, struct pt_regs *pt_regs){	int recognized = 0;	int handled = 0;	struct ndis_irq *ndis_irq = (struct ndis_irq *)data;	struct ndis_handle *handle;	struct miniport_char *miniport;	unsigned long flags;	if (!ndis_irq || !ndis_irq->handle)		return IRQ_NONE;	handle = ndis_irq->handle;	miniport = &handle->driver->miniport_char;	/* this spinlock should be shared with NdisMSynchronizeWithInterrupt	 */	kspin_lock_irqsave(&ndis_irq->lock, flags);	if (ndis_irq->req_isr)		LIN2WIN3(miniport->isr, &recognized, &handled,			 handle->adapter_ctx);	else { //if (miniport->disable_interrupts)		LIN2WIN1(miniport->disable_interrupts, handle->adapter_ctx);		/* it is not shared interrupt, so handler must be called */		recognized = handled = 1;	}	kspin_unlock_irqrestore(&ndis_irq->lock, flags);	if (recognized && handled)		schedule_work(&handle->irq_work);	if (recognized)		return IRQ_HANDLED;	return IRQ_NONE;}STDCALL NDIS_STATUS WRAP_EXPORT(NdisMRegisterInterrupt)	(struct ndis_irq *ndis_irq, struct ndis_handle *handle,	 UINT vector, UINT level, BOOLEAN req_isr,	 BOOLEAN shared, enum kinterrupt_mode mode){	TRACEENTER1("%p, vector:%d, level:%d, req_isr:%d, shared:%d, "		    "mode:%d sp:%p", ndis_irq, vector, level, req_isr,		    shared, mode, get_sp());	ndis_irq->irq.irq = vector;	ndis_irq->handle = handle;	ndis_irq->req_isr = req_isr;	if (shared && !req_isr)		WARNING("%s", "shared but dynamic interrupt!");	ndis_irq->shared = shared;	kspin_lock_init(&ndis_irq->lock);	INIT_WORK(&handle->irq_work, &ndis_irq_bh, ndis_irq);	if (request_irq(vector, ndis_irq_th, shared? SA_SHIRQ : 0,			"ndiswrapper", ndis_irq)) {		printk(KERN_WARNING "%s: request for irq %d failed\n",		       DRIVER_NAME, vector);		TRACEEXIT1(return NDIS_STATUS_RESOURCES);	}	ndis_irq->enabled = 1;	printk(KERN_INFO "%s: using irq %d\n", DRIVER_NAME, vector);	TRACEEXIT1(return NDIS_STATUS_SUCCESS);}STDCALL void WRAP_EXPORT(NdisMDeregisterInterrupt)	(struct ndis_irq *ndis_irq){	struct ndis_handle *handle;	TRACEENTER1("%p", ndis_irq);	if (!ndis_irq)		TRACEEXIT1(return);	handle = ndis_irq->handle;	if (!handle)		TRACEEXIT1(return);	ndis_irq->enabled = 0;	/* flush irq_bh workqueue; calling it before enabled=0 will	 * crash since some drivers (Centrino at least) don't expect	 * irq hander to be called anymore */	/* cancel_delayed_work is probably better, but 2.4 kernels	 * don't have equivalent function	 */#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,6,0)	flush_scheduled_work();#else	set_current_state(TASK_INTERRUPTIBLE);	schedule_timeout(HZ/10);#endif	free_irq(ndis_irq->irq.irq, ndis_irq);	ndis_irq->handle = NULL;	handle->ndis_irq = NULL;	TRACEEXIT1(return);}STDCALL BOOLEAN WRAP_EXPORT(NdisMSynchronizeWithInterrupt)	(struct ndis_irq *ndis_irq, void *func, void *ctx){	unsigned char ret;	unsigned char (*sync_func)(void *ctx) STDCALL;	unsigned long flags;	TRACEENTER5("%p %p %p\n", ndis_irq, func, ctx);	if (func == NULL || ctx == NULL)		TRACEEXIT5(return 0);	sync_func = func;	kspin_lock_irqsave(&ndis_irq->lock, flags);	ret = LIN2WIN1(sync_func, ctx);	kspin_unlock_irqrestore(&ndis_irq->lock, flags);	DBGTRACE5("sync_func returns %u", ret);	TRACEEXIT5(return ret);}/* called via function pointer */STDCALL voidNdisMIndicateStatus(struct ndis_handle *handle,		    NDIS_STATUS status, void *buf, UINT len){	TRACEENTER2("%08x", status);	if (status == NDIS_STATUS_MEDIA_DISCONNECT) {		handle->link_status = 0;		handle->send_ok = 0;		set_bit(LINK_STATUS_CHANGED, &handle->wrapper_work);	}	if (status == NDIS_STATUS_MEDIA_CONNECT) {		handle->link_status = 1;		handle->send_ok = 1;		set_bit(LINK_STATUS_CHANGED, &handle->wrapper_work);	}	if (status == NDIS_STATUS_MEDIA_SPECIFIC_INDICATION && buf) {		struct ndis_status_indication *status = buf;		struct ndis_auth_req *auth_req;		struct ndis_radio_status_indication *radio_status;		switch (status->status_type) {		case Ndis802_11StatusType_Authentication:			buf = (char *)buf + sizeof(*status);			len -= sizeof(*status);			while (len > 0) {				auth_req = (struct ndis_auth_req *)buf;				DBGTRACE1(MACSTR, MAC2STR(auth_req->bssid));				if (auth_req->flags & 0x01)					DBGTRACE2("%s", "reqauth");				if (auth_req->flags & 0x02)					DBGTRACE2("%s", "keyupdate");				if (auth_req->flags & 0x06)					DBGTRACE2("%s", "pairwise_error");				if (auth_req->flags & 0x0E)					DBGTRACE2("%s", "group_error");				len -= auth_req->length;				buf = (char *)buf + auth_req->length;			}			break;		case Ndis802_11StatusType_MediaStreamMode:			break;		case Ndis802_11StatusType_PMKID_CandidateList:			break;		case Ndis802_11StatusType_RadioState:			radio_status = buf;			if (radio_status->radio_state ==			    Ndis802_11RadioStatusOn)				INFO("radio is turned on");			else if (radio_status->radio_state ==				 Ndis802_11RadioStatusHardwareOff)				INFO("radio is turned off by hardware");			else if (radio_status->radio_state ==				 Ndis802_11RadioStatusSoftwareOff)				INFO("radio is turned off by software");			break;		}	}	TRACEEXIT1(return);}/* called via function pointer */STDCALL void NdisMIndicateStatusComplete(struct ndis_handle *handle){	TRACEENTER3("%s", "");	schedule_work(&handle->wrapper_worker);}/* called via function pointer */STDCALL voidNdisMIndicateReceivePacket(struct ndis_handle *handle,			   struct ndis_packet **packets, UINT nr_packets){	ndis_buffer *buffer;	struct ndis_packet *packet;	struct sk_buff *skb;	int i;	struct ndis_work_entry *ndis_work_entry;	KIRQL irql;	TRACEENTER3("%s", "");	for (i = 0; i < nr_packets; i++) {		packet = packets[i];		if (!packet) {			WARNING("%s", "Skipping empty packet on receive");			continue;		}		buffer = packet->private.buffer_head;		skb = dev_alloc_skb(MmGetMdlByteCount(buffer));		if (skb) {			skb->dev = handle->net_dev;			eth_copy_and_sum(skb, MmGetMdlVirtualAddress(buffer),					 MmGetMdlByteCount(buffer), 0);			skb_put(skb, MmGetMdlByteCount(buffer));			skb->protocol = eth_type_trans(skb, handle->net_dev);			handle->stats.rx_bytes += MmGetMdlByteCount(buffer);			handle->stats.rx_packets++;			netif_rx(skb);		} else			handle->stats.rx_dropped++;		/* serialized drivers check the status upon return		 * from this function */		if (test_bit(ATTR_SERIALIZED, &handle->attributes)) {			packet->oob_data.status = NDIS_STATUS_SUCCESS;			continue;		}		/* if a deserialized driver sets		 * NDIS_STATUS_RESOURCES, then it reclaims the packet		 * upon return from this function: it doesn't matter		 * what value we set in the status */		if (packet->oob_data.status == NDIS_STATUS_RESOURCES) {			packet->oob_data.status = NDIS_STATUS_SUCCESS;			DBGTRACE3("low on resources");			continue;		}		if (packet->oob_data.status != NDIS_STATUS_SUCCESS)			WARNING("invalid packet status %08X",				packet->oob_data.status);		/* deserialized driver doesn't check the status upon		 * return from this function; we need to call		 * MiniportReturnPacket later for this packet. Calling		 * MiniportReturnPacket from here is not correct - the		 * driver doesn't expect it (at least Centrino driver		 * crashes) */		packet->oob_data.status = NDIS_STATUS_PENDING;		ndis_work_entry = kmalloc(sizeof(*ndis_work_entry),					  GFP_ATOMIC);		if (!ndis_work_entry) {			ERROR("couldn't allocate memory");			continue;		}		ndis_work_entry->type = NDIS_RETURN_PACKET_WORK_ITEM;		ndis_work_entry->handle = handle;		ndis_work_entry->entry.return_packet = packet;		irql = kspin_lock_irql(&ndis_work_list_lock, DISPATCH_LEVEL);		list_add_tail(&ndis_work_entry->list, &ndis_work_list);		kspin_unlock_irql(&ndis_work_list_lock, irql);	}	schedule_work(&ndis_work);	TRACEEXIT3(return);}STDCALL void WRAP_EXPORT(NdisMCoIndicateReceivePacket)	(struct ndis_handle *handle, struct ndis_packet **packets,	 UINT nr_packets){	TRACEENTER3("handle = %p", handle);	NdisMIndicateReceivePacket(handle, packets, nr_packets);	TRACEEXIT3(return);}/* called via function pointer */STDCALL voidNdisMSendComplete(struct ndis_handle *handle,		  struct ndis_packet *packet, NDIS_STATUS status){	TRACEENTER3("%08x", status);	sendpacket_done(handle, packet);	/* In case a serialized driver has requested a pause by returning	 * NDIS_STATUS_RESOURCES we need to give the send-code a kick again.	 */	handle->send_ok = 1;	schedule_work(&handle->xmit_work);	TRACEEXIT3(return);}STDCALL void WRAP_EXPORT(NdisMCoSendComplete)	(NDIS_STATUS status, struct ndis_handle *handle,	 struct ndis_packet *packet){	TRACEENTER3("%08x", status);	NdisMSendComplete(handle, packet, status);	TRACEEXIT3(return);}/* called via function pointer */STDCALL voidNdisMSendResourcesAvailable(struct ndis_handle *handle){	TRACEENTER3("%s", "");	/* sending packets immediately seem to result in NDIS_STATUS_FAILURE,	   so wait for a while before sending the packet again */	mdelay(5);	handle->send_ok = 1;	schedule_work(&handle->xmit_work);	TRACEEXIT3(return);}/* called via function pointer (by NdisMEthIndicateReceive macro) */STDCALL voidEthRxIndicateHandler(void *adapter_ctx, void *rx_ctx, char *header1,		     char *header, UINT header_size, void *look_ahead,		     UINT look_ahead_size, UINT packet_size){	struct sk_buff *skb = NULL;	struct ndis_handle *handle = ctx_to_handle(rx_ctx);	unsigned int skb_size = 0;	KIRQL irql;	TRACEENTER3("adapter_ctx = %p, rx_ctx = %p, buf = %p, size = %d, "		    "buf = %p, size = %d, packet = %d",		    adapter_ctx, rx_ctx, header, header_size, look_ahead,		    look_ahead_size, packet_size);	DBGTRACE3("handle = %p", handle);	if (!handle)		TRACEEXIT3(return);	if (look_ahead_size < packet_size) {		struct ndis_packet *packet;		struct miniport_char *miniport;		unsigned int res, bytes_txed;		packet = allocate_ndis_packet();		if (!packet) {			handle->stats.rx_dropped++;			TRACEEXIT3(return);		}		packet->private.pool = NULL;		miniport = &handle->driver->miniport_char;		irql = raise_irql(DISPATCH_LEVEL);		res = LIN2WIN6(miniport->tx_data, packet, &bytes_txed,			       adapter_ctx, rx_ctx, look_ahead_size,			       packet_size);		lower_irql(irql);		if (res == NDIS_STATUS_SUCCESS) {			ndis_buffer *buffer;			skb = dev_alloc_skb(header_size+look_ahead_size+					    bytes_txed);			if (skb) {				memcpy(skb->data, header, header_size);				memcpy(skb->data+header_size, look_ahead,				       look_ahead_size);				buffer = packet->private.buffer_head;				memcpy(skb->data+header_size+look_ahead_size,				       MmGetMdlVirtualAddress(buffer),				       bytes_txed);				skb_size = header_size+look_ahead_size+					bytes_txed;				free_ndis_packet(packet);			}		} else if (res == NDIS_STATUS_PENDING) {			/* driver will call td_complete */			packet->look_ahead = kmalloc(look_ahead_size,						     GFP_ATOMIC);			if (!packet->look_ahead) {				free_ndis_packet(packet);				handle->stats.rx_dropped++;				TRACEEXIT3(return);			}			memcpy(&packet->header, header,			       sizeof(packet->header));			memcpy(packet->look_ahead, look_ahead,			       look_ahead_size);			packet->look_ahead_size = look_ahead_size;		} else {			free_ndis_packet(packet);			handle->stats.rx_dropped++;			TRACEEXIT3(return);		}	} else {		skb_size = header_size+packet_size;		skb = dev_alloc_skb(skb_size);		if (skb) {			memcpy(skb->data, header, header_size);			memcpy(skb->data+header_size, look_ahead, packet_size);		}	}	if (skb && skb_size > 0) {		skb->dev = handle->net_dev;		skb_put(skb, skb_size);		skb->protocol = eth_type_trans(skb, handle->net_dev);		handle->stats.rx_bytes += skb_size;		handle->stats.rx_packets++;		netif_rx(skb);	} else		handle->stats.rx_dropped++;	TRACEEXIT3(return);}/* called via function pointer */STDCALL voidNdisMTransferDataComplete(struct ndis_handle *handle,			  struct ndis_packet *packet,			  NDIS_STATUS status, UINT bytes_txed){	struct sk_buff *skb;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -