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

📄 ndis.c

📁 ndiswrapper工具
💻 C
📖 第 1 页 / 共 5 页
字号:
	TRACEENTER3("%p, %p %u (%u)", wnd, buf, index, wnd->tx_dma_count);	if (wnd->use_sg_dma)		WARNING("buffer %p may have been unmapped already", buf);	if (index >= wnd->tx_dma_count) {		ERROR("invalid map register (%u >= %u)",		      index, wnd->tx_dma_count);		return;	}	DBGTRACE4("%lx, %d, %d", (unsigned long)wnd->tx_dma_addr[index],		  MmGetMdlByteCount(buf), index);	if (wnd->tx_dma_addr[index] == 0) {//		ERROR("map register not used (%lu)", index);		return;	}	PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, wnd->tx_dma_addr[index],			     MmGetMdlByteCount(buf), PCI_DMA_TODEVICE);	wnd->tx_dma_addr[index] = 0;}wstdcall void WIN_FUNC(NdisMAllocateSharedMemory,5)	(struct ndis_miniport_block *nmb, ULONG size,	 BOOLEAN cached, void **virt, NDIS_PHY_ADDRESS *phys){	dma_addr_t dma_addr;	struct wrap_device *wd = nmb->wnd->wd;	TRACEENTER3("size: %u, cached: %d", size, cached);	*virt = PCI_DMA_ALLOC_COHERENT(wd->pci.pdev, size, &dma_addr);	if (!*virt)		WARNING("couldn't allocate %d bytes of %scached DMA memory",			size, cached ? "" : "un-");	*phys = dma_addr;	TRACEEXIT3(return);}wstdcall void WIN_FUNC(NdisMFreeSharedMemory,5)	(struct ndis_miniport_block *nmb, ULONG size, BOOLEAN cached,	 void *virt, NDIS_PHY_ADDRESS addr){	struct wrap_device *wd = nmb->wnd->wd;	TRACEENTER3("");	PCI_DMA_FREE_COHERENT(wd->pci.pdev, size, virt, addr);	TRACEEXIT3(return);}wstdcall void alloc_shared_memory_async(void *arg1, void *arg2){	struct wrap_ndis_device *wnd;	struct alloc_shared_mem *alloc_shared_mem;	struct miniport_char *miniport;	void *virt;	NDIS_PHY_ADDRESS phys;	KIRQL irql;	wnd = arg1;	alloc_shared_mem = arg2;	miniport = &wnd->wd->driver->ndis_driver->miniport;	NdisMAllocateSharedMemory(wnd->nmb, alloc_shared_mem->size,				  alloc_shared_mem->cached, &virt, &phys);	irql = serialize_lock_irql(wnd);	LIN2WIN5(miniport->alloc_complete, wnd->nmb, virt,		 &phys, alloc_shared_mem->size, alloc_shared_mem->ctx);	serialize_unlock_irql(wnd, irql);	kfree(alloc_shared_mem);}WIN_FUNC_DECL(alloc_shared_memory_async,2)wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateSharedMemoryAsync,4)	(struct ndis_miniport_block *nmb, ULONG size, BOOLEAN cached,	 void *ctx){	struct wrap_ndis_device *wnd = nmb->wnd;	struct alloc_shared_mem *alloc_shared_mem;	TRACEENTER3("wnd: %p", wnd);	alloc_shared_mem = kmalloc(sizeof(*alloc_shared_mem), gfp_irql());	if (!alloc_shared_mem) {		WARNING("couldn't allocate memory");		return NDIS_STATUS_FAILURE;	}	alloc_shared_mem->size = size;	alloc_shared_mem->cached = cached;	alloc_shared_mem->ctx = ctx;	if (schedule_ntos_work_item(WIN_FUNC_PTR(alloc_shared_memory_async,2),				    wnd, alloc_shared_mem))		TRACEEXIT3(return NDIS_STATUS_FAILURE);	TRACEEXIT3(return NDIS_STATUS_PENDING);}/* Some drivers allocate NDIS_BUFFER (aka MDL) very often; instead of * allocating and freeing with kernel functions, we chain them into * ndis_buffer_pool. When an MDL is freed, it is added to the list of * free MDLs. When allocated, we first check if there is one in free * list and if so just return it; otherwise, we allocate a new one and * return that. This reduces memory fragmentation. Windows DDK says * that the driver itself shouldn't check what is returned in * pool_handle, presumably because buffer pools are not used in * XP. However, as long as driver follows rest of the semantics - that * it should indicate maximum number of MDLs used with num_descr and * pass the same pool_handle in other buffer functions, this should * work. Sadly, though, NdisFreeBuffer doesn't pass the pool_handle, * so we use 'process' field of MDL to store pool_handle. */wstdcall void WIN_FUNC(NdisAllocateBufferPool,3)	(NDIS_STATUS *status, struct ndis_buffer_pool **pool_handle,	 UINT num_descr){	struct ndis_buffer_pool *pool;	TRACEENTER1("buffers: %d", num_descr);	pool = kmalloc(sizeof(*pool), gfp_irql());	if (!pool) {		*status = NDIS_STATUS_RESOURCES;		TRACEEXIT3(return);	}	nt_spin_lock_init(&pool->lock);	pool->max_descr = num_descr;	pool->num_allocated_descr = 0;	pool->free_descr = NULL;	*pool_handle = pool;	*status = NDIS_STATUS_SUCCESS;	DBGTRACE1("pool: %p, num_descr: %d", pool, num_descr);	TRACEEXIT1(return);}wstdcall void WIN_FUNC(NdisAllocateBuffer,5)	(NDIS_STATUS *status, ndis_buffer **buffer,	 struct ndis_buffer_pool *pool, void *virt, UINT length){	ndis_buffer *descr;	TRACEENTER4("pool: %p, allocated: %d",		    pool, pool->num_allocated_descr);	if (!pool) {		*status = NDIS_STATUS_FAILURE;		TRACEEXIT4(return);	}	DBG_BLOCK(2) {		if (pool->num_allocated_descr > pool->max_descr)			WARNING("pool %p is full: %d(%d)", pool,				pool->num_allocated_descr, pool->max_descr);	}	descr = atomic_remove_list_head(pool->free_descr, oldhead->next);	if (descr) {		typeof(descr->flags) flags;		flags = descr->flags;		MmInitializeMdl(descr, virt, length);		if (flags & MDL_CACHE_ALLOCATED)			descr->flags = MDL_CACHE_ALLOCATED;		descr->flags |= MDL_SOURCE_IS_NONPAGED_POOL;	} else {		descr = allocate_init_mdl(virt, length);		if (!descr) {			WARNING("couldn't allocate buffer");			*status = NDIS_STATUS_FAILURE;			TRACEEXIT4(return);		}		DBGTRACE4("allocated buffer %p for %p, %d",			  descr, virt, length);		atomic_inc_var(pool->num_allocated_descr);		MmBuildMdlForNonPagedPool(descr);	}	descr->pool = pool;	*buffer = descr;	*status = NDIS_STATUS_SUCCESS;	DBGTRACE4("buffer: %p", descr);	TRACEEXIT4(return);}wstdcall void WIN_FUNC(NdisFreeBuffer,1)	(ndis_buffer *descr){	struct ndis_buffer_pool *pool;	TRACEENTER4("descr: %p", descr);	if (!descr || !descr->pool) {		ERROR("invalid buffer");		TRACEEXIT4(return);	}	pool = descr->pool;	if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_BUFFERS) {		/* NB NB NB: set mdl's 'pool' field to NULL before		 * calling free_mdl; otherwise free_mdl calls		 * NdisFreeBuffer causing deadlock (for spinlock) */		atomic_dec_var(pool->num_allocated_descr);		descr->pool = NULL;		free_mdl(descr);	} else		atomic_insert_list_head(pool->free_descr, descr->next, descr);	TRACEEXIT4(return);}wstdcall void WIN_FUNC(NdisFreeBufferPool,1)	(struct ndis_buffer_pool *pool){	ndis_buffer *cur, *next;	KIRQL irql;	DBGTRACE3("pool: %p", pool);	if (!pool) {		WARNING("invalid pool");		TRACEEXIT3(return);	}	irql = nt_spin_lock_irql(&pool->lock, DISPATCH_LEVEL);	cur = pool->free_descr;	while (cur) {		next = cur->next;		cur->pool = NULL;		free_mdl(cur);		cur = next;	}	nt_spin_unlock_irql(&pool->lock, irql);	kfree(pool);	pool = NULL;	TRACEEXIT3(return);}wstdcall void WIN_FUNC(NdisAdjustBufferLength,2)	(ndis_buffer *buffer, UINT length){	TRACEENTER4("%p, %d", buffer, length);	buffer->bytecount = length;}wstdcall void WIN_FUNC(NdisQueryBuffer,3)	(ndis_buffer *buffer, void **virt, UINT *length){	TRACEENTER4("buffer: %p", buffer);	if (virt)		*virt = MmGetSystemAddressForMdl(buffer);	*length = MmGetMdlByteCount(buffer);	DBGTRACE4("%u", *length);	TRACEEXIT4(return);}wstdcall void WIN_FUNC(NdisQueryBufferSafe,4)	(ndis_buffer *buffer, void **virt, UINT *length,	 enum mm_page_priority priority){	TRACEENTER4("%p, %p, %p, %d", buffer, virt, length, priority);	if (virt)		*virt = MmGetSystemAddressForMdlSafe(buffer, priority);	*length = MmGetMdlByteCount(buffer);	DBGTRACE4("%u", *length);}wstdcall void *WIN_FUNC(NdisBufferVirtualAddress,1)	(ndis_buffer *buffer){	TRACEENTER3("%p", buffer);	return MmGetSystemAddressForMdl(buffer);}wstdcall ULONG WIN_FUNC(NdisBufferLength,1)	(ndis_buffer *buffer){	TRACEENTER3("%p", buffer);	return MmGetMdlByteCount(buffer);}wstdcall void WIN_FUNC(NdisQueryBufferOffset,3)	(ndis_buffer *buffer, UINT *offset, UINT *length){	TRACEENTER3("%p", buffer);	*offset = MmGetMdlByteOffset(buffer);	*length = MmGetMdlByteCount(buffer);	DBGTRACE3("%d, %d", *offset, *length);}wstdcall void WIN_FUNC(NdisUnchainBufferAtBack,2)	(struct ndis_packet *packet, ndis_buffer **buffer){	ndis_buffer *b, *btail;	TRACEENTER3("%p", packet);	b = packet->private.buffer_head;	if (!b) {		/* no buffer in packet */		*buffer = NULL;		TRACEEXIT3(return);	}	btail = packet->private.buffer_tail;	*buffer = btail;	if (b == btail) {		/* one buffer in packet */		packet->private.buffer_head = NULL;		packet->private.buffer_tail = NULL;	} else {		while (b->next != btail)			b = b->next;		packet->private.buffer_tail = b;		b->next = NULL;	}	packet->private.valid_counts = FALSE;	TRACEEXIT3(return);}wstdcall void WIN_FUNC(NdisUnchainBufferAtFront,2)	(struct ndis_packet *packet, ndis_buffer **buffer){	TRACEENTER3("%p", packet);	if (packet->private.buffer_head == NULL) {		/* no buffer in packet */		*buffer = NULL;		TRACEEXIT3(return);	}	*buffer = packet->private.buffer_head;	if (packet->private.buffer_head == packet->private.buffer_tail) {		/* one buffer in packet */		packet->private.buffer_head = NULL;		packet->private.buffer_tail = NULL;	} else		packet->private.buffer_head = (*buffer)->next;	packet->private.valid_counts = FALSE;	TRACEEXIT3(return);}wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacketSafe,6)	(struct ndis_packet *packet, ndis_buffer **first_buffer,	 void **first_buffer_va, UINT *first_buffer_length,	 UINT *total_buffer_length, enum mm_page_priority priority){	ndis_buffer *b = packet->private.buffer_head;	TRACEENTER3("%p(%p)", packet, b);	*first_buffer = b;	if (b) {		*first_buffer_va = MmGetSystemAddressForMdlSafe(b, priority);		*first_buffer_length = *total_buffer_length =			MmGetMdlByteCount(b);		for (b = b->next; b; b = b->next)			*total_buffer_length += MmGetMdlByteCount(b);	} else {		*first_buffer_va = NULL;		*first_buffer_length = 0;		*total_buffer_length = 0;	}	DBGTRACE3("%p, %d, %d", *first_buffer_va, *first_buffer_length,		  *total_buffer_length);	TRACEEXIT3(return);}wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacket,6)	(struct ndis_packet *packet, ndis_buffer **first_buffer,	 void **first_buffer_va, UINT *first_buffer_length,	 UINT *total_buffer_length, enum mm_page_priority priority){	NdisGetFirstBufferFromPacketSafe(packet, first_buffer,					 first_buffer_va, first_buffer_length,					 total_buffer_length,					 NormalPagePriority);}wstdcall void WIN_FUNC(NdisAllocatePacketPoolEx,5)	(NDIS_STATUS *status, struct ndis_packet_pool **pool_handle,	 UINT num_descr, UINT overflowsize, UINT proto_rsvd_length){	struct ndis_packet_pool *pool;	TRACEENTER3("buffers: %d, length: %d", num_descr, proto_rsvd_length);	pool = kmalloc(sizeof(*pool), gfp_irql());	if (!pool) {		*status = NDIS_STATUS_RESOURCES;		TRACEEXIT3(return);	}	memset(pool, 0, sizeof(*pool));	nt_spin_lock_init(&pool->lock);	pool->max_descr = num_descr;	pool->num_allocated_descr = 0;	pool->num_used_descr = 0;	pool->free_descr = NULL;	pool->proto_rsvd_length = proto_rsvd_length;	*pool_handle = pool;	*status = NDIS_STATUS_SUCCESS;	DBGTRACE3("pool: %p", pool);	TRACEEXIT3(return);}wstdcall void WIN_FUNC(NdisAllocatePacketPool,4)	(NDIS_STATUS *status, struct ndis_packet_pool **pool_handle,	 UINT num_descr, UINT proto_rsvd_length){	NdisAllocatePacketPoolEx(status, pool_handle, num_descr, 0,				 proto_rsvd_length);	TRACEEXIT3(return);}wstdcall void WIN_FUNC(NdisFreePacketPool,1)	(struct ndis_packet_pool *pool){	struct ndis_packet *packet, *next;	KIRQL irql;	TRACEENTER3("pool: %p", pool);	if (!pool) {		WARNING("invalid pool");		TRACEEXIT3(return);	}	irql = nt_spin_lock_irql(&pool->lock, DISPATCH_LEVEL);	packet = pool->free_descr;	while (packet) {		next = (NDIS_PACKET_OOB_DATA(packet))->next;		kfree(packet);		packet = next;	}	pool->num_allocated_descr = 0;	pool->num_used_descr = 0;	pool->free_descr = NULL;	nt_spin_unlock_irql(&pool->lock, irql);	kfree(pool);	TRACEEXIT3(return);}wstdcall UINT WIN_FUNC(NdisPacketPoolUsage,1)	(struct ndis_packet_pool *pool){	TRACEEXIT4(return pool->num_used_descr);}wstdcall void WIN_FUNC(NdisAllocatePacket,3)	(NDIS_STATUS *status, struct ndis_packet **packet,	 struct ndis_packet_pool *pool){	struct ndis_packet *ndis_packet;	int packet_length;	TRACEENTER4("pool: %p", pool);	if (!pool) {		*status = NDIS_STATUS_RESOURCES;		TRACEEXIT4(return);	}	DBG_BLOCK(2) {		if (pool->num_used_descr >= pool->max_descr)			WARNING("pool %p is full: %d(%d)", pool,				pool->num_used_descr, pool->max_descr);	}	/* packet has space for 1 byte in protocol_reserved field */	packet_length = sizeof(*ndis_packet) - 1 + pool->proto_rsvd_length +		sizeof(struct ndis_packet_oob_data);	ndis_packet =		atomic_remove_list_head(pool->free_descr,					(NDIS_PACKET_OOB_DATA(oldhead))->next);	if (!ndis_packet) {		ndis_packet = kmalloc(packet_length, gfp_irql());		if (!ndis_packet) {			WARNING("couldn't allocate packet");			*status = NDIS_STATUS_RESOURCES;			return;		}		atomic_inc_var(pool->num_allocated_descr);	}	DBGTRACE3("packet: %p", ndis_packet);	atomic_inc_var(pool->num_used_descr);	memset(ndis_packet, 0, packet_length);	ndis_packet->private.oob_offset = packet_length -		sizeof(struct ndis_packet_oob_data);	ndis_packet->private.packet_flags = fPACKET_ALLOCATED_BY_NDIS;//		| NDIS_PROTOCOL_ID_TCP_IP;	ndis_packet->private.pool = pool;	*packet = ndis_packet;	*status = NDIS_STATUS_SUCCESS;	DBGTRACE4("packet: %p, pool: %p", ndis_packet, pool);	TRACEEXIT4(return);}wstdcall void WIN_FUNC(NdisDprAllocatePacket,3)	(NDIS_STATUS *status, struct ndis_packet **packet,	 struct ndis_packet_pool *pool)

⌨️ 快捷键说明

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