📄 ndis.c
字号:
ENTER2("nmb: %p", nmb); ret = RtlUnicodeStringToAnsiString(&ansi, key, TRUE); if (ret != STATUS_SUCCESS || ansi.buf == NULL) { *param = NULL; *status = NDIS_STATUS_FAILURE; RtlFreeAnsiString(&ansi); EXIT2(return); } TRACE2("%d, %s", type, ansi.buf); if (read_setting(&nmb->wnd->wd->settings, ansi.buf, ansi.length, param, type) == 0 || read_setting(&nmb->wnd->wd->driver->settings, ansi.buf, ansi.length, param, type) == 0) *status = NDIS_STATUS_SUCCESS; else { TRACE2("setting %s not found (type:%d)", ansi.buf, type); *status = NDIS_STATUS_FAILURE; } RtlFreeAnsiString(&ansi); EXIT2(return);}wstdcall void WIN_FUNC(NdisWriteConfiguration,4) (NDIS_STATUS *status, struct ndis_mp_block *nmb, struct unicode_string *key, struct ndis_configuration_parameter *param){ struct ansi_string ansi; char *keyname; struct wrap_device_setting *setting; ENTER2("nmb: %p", nmb); if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE)) { *status = NDIS_STATUS_FAILURE; EXIT2(return); } keyname = ansi.buf; TRACE2("%s", keyname); if (down_interruptible(&loader_mutex)) WARNING("couldn't obtain loader_mutex"); nt_list_for_each_entry(setting, &nmb->wnd->wd->settings, list) { if (strnicmp(keyname, setting->name, ansi.length) == 0) { up(&loader_mutex); if (ndis_decode_setting(setting, param)) *status = NDIS_STATUS_FAILURE; else *status = NDIS_STATUS_SUCCESS; RtlFreeAnsiString(&ansi); EXIT2(return); } } up(&loader_mutex); setting = kzalloc(sizeof(*setting), GFP_KERNEL); if (setting) { if (ansi.length == ansi.max_length) ansi.length--; memcpy(setting->name, keyname, ansi.length); setting->name[ansi.length] = 0; if (ndis_decode_setting(setting, param)) *status = NDIS_STATUS_FAILURE; else { *status = NDIS_STATUS_SUCCESS; if (down_interruptible(&loader_mutex)) WARNING("couldn't obtain loader_mutex"); InsertTailList(&nmb->wnd->wd->settings, &setting->list); up(&loader_mutex); } } else *status = NDIS_STATUS_RESOURCES; RtlFreeAnsiString(&ansi); EXIT2(return);}wstdcall void WIN_FUNC(NdisReadNetworkAddress,4) (NDIS_STATUS *status, void **addr, UINT *len, struct ndis_mp_block *nmb){ struct wrap_ndis_device *wnd = nmb->wnd; struct ndis_configuration_parameter *param; struct unicode_string key; struct ansi_string ansi; typeof(wnd->mac) mac; int i, ret; ENTER2("%p", nmb); RtlInitAnsiString(&ansi, "NetworkAddress"); *status = NDIS_STATUS_FAILURE; if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) EXIT1(return); NdisReadConfiguration(&ret, ¶m, nmb, &key, NdisParameterString); RtlFreeUnicodeString(&key); if (ret != NDIS_STATUS_SUCCESS) EXIT1(return); ret = RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string, TRUE); if (ret != STATUS_SUCCESS) EXIT1(return); i = 0; if (ansi.length >= 2 * sizeof(mac)) { for (i = 0; i < sizeof(mac); i++) { char c[3]; int x; c[0] = ansi.buf[i*2]; c[1] = ansi.buf[i*2+1]; c[2] = 0; ret = sscanf(c, "%x", &x); if (ret != 1) break; mac[i] = x; } } TRACE2("%s, %d, " MACSTR, ansi.buf, i, MAC2STR(mac)); RtlFreeAnsiString(&ansi); if (i == sizeof(mac)) { memcpy(wnd->mac, mac, sizeof(wnd->mac)); *len = sizeof(mac); *addr = wnd->mac; *status = NDIS_STATUS_SUCCESS; } EXIT1(return);}wstdcall void WIN_FUNC(NdisInitializeString,2) (struct unicode_string *dest, UCHAR *src){ struct ansi_string ansi; ENTER2(""); if (src == NULL) { dest->length = dest->max_length = 0; dest->buf = NULL; } else { RtlInitAnsiString(&ansi, src); /* the string is freed with NdisFreeMemory */ RtlAnsiStringToUnicodeString(dest, &ansi, TRUE); } EXIT2(return);}wstdcall void WIN_FUNC(NdisInitAnsiString,2) (struct ansi_string *dst, CHAR *src){ RtlInitAnsiString(dst, src); EXIT2(return);}wstdcall void WIN_FUNC(NdisInitUnicodeString,2) (struct unicode_string *dest, const wchar_t *src){ RtlInitUnicodeString(dest, src); return;}wstdcall NDIS_STATUS WIN_FUNC(NdisAnsiStringToUnicodeString,2) (struct unicode_string *dst, struct ansi_string *src){ ENTER2(""); if (dst == NULL || src == NULL) EXIT2(return NDIS_STATUS_FAILURE); if (RtlAnsiStringToUnicodeString(dst, src, FALSE) == STATUS_SUCCESS) return NDIS_STATUS_SUCCESS; else return NDIS_STATUS_FAILURE;}wstdcall NDIS_STATUS WIN_FUNC(NdisUnicodeStringToAnsiString,2) (struct ansi_string *dst, struct unicode_string *src){ ENTER2(""); if (dst == NULL || src == NULL) EXIT2(return NDIS_STATUS_FAILURE); if (RtlUnicodeStringToAnsiString(dst, src, FALSE) == STATUS_SUCCESS) return NDIS_STATUS_SUCCESS; else return NDIS_STATUS_FAILURE;}wstdcall NTSTATUS WIN_FUNC(NdisUpcaseUnicodeString,2) (struct unicode_string *dst, struct unicode_string *src){ EXIT2(return RtlUpcaseUnicodeString(dst, src, FALSE));}wstdcall void WIN_FUNC(NdisMSetAttributesEx,5) (struct ndis_mp_block *nmb, void *mp_ctx, UINT hangcheck_interval, UINT attributes, ULONG adaptertype){ struct wrap_ndis_device *wnd; ENTER1("%p, %p, %d, %08x, %d", nmb, mp_ctx, hangcheck_interval, attributes, adaptertype); wnd = nmb->wnd; nmb->mp_ctx = mp_ctx; wnd->attributes = attributes; if ((attributes & NDIS_ATTRIBUTE_BUS_MASTER) && wrap_is_pci_bus(wnd->wd->dev_bus)) pci_set_master(wnd->wd->pci.pdev); if (hangcheck_interval > 0) wnd->hangcheck_interval = 2 * hangcheck_interval * HZ; else wnd->hangcheck_interval = 2 * HZ; EXIT1(return);}wstdcall ULONG WIN_FUNC(NdisReadPciSlotInformation,5) (struct ndis_mp_block *nmb, ULONG slot, ULONG offset, char *buf, ULONG len){ struct wrap_device *wd = nmb->wnd->wd; ULONG i; for (i = 0; i < len; i++) if (pci_read_config_byte(wd->pci.pdev, offset + i, &buf[i]) != PCIBIOS_SUCCESSFUL) break; DBG_BLOCK(2) { if (i != len) WARNING("%u, %u", i, len); } return i;}wstdcall ULONG WIN_FUNC(NdisImmediateReadPciSlotInformation,5) (struct ndis_mp_block *nmb, ULONG slot, ULONG offset, char *buf, ULONG len){ return NdisReadPciSlotInformation(nmb, slot, offset, buf, len);}wstdcall ULONG WIN_FUNC(NdisWritePciSlotInformation,5) (struct ndis_mp_block *nmb, ULONG slot, ULONG offset, char *buf, ULONG len){ struct wrap_device *wd = nmb->wnd->wd; ULONG i; for (i = 0; i < len; i++) if (pci_write_config_byte(wd->pci.pdev, offset + i, buf[i]) != PCIBIOS_SUCCESSFUL) break; DBG_BLOCK(2) { if (i != len) WARNING("%u, %u", i, len); } return i;}wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterIoPortRange,4) (void **virt, struct ndis_mp_block *nmb, UINT start, UINT len){ ENTER3("%08x %08x", start, len); *virt = (void *)(ULONG_PTR)start; return NDIS_STATUS_SUCCESS;}wstdcall void WIN_FUNC(NdisMDeregisterIoPortRange,4) (struct ndis_mp_block *nmb, UINT start, UINT len, void* virt){ ENTER1("%08x %08x", start, len);}wstdcall void WIN_FUNC(NdisReadPortUchar,3) (struct ndis_mp_block *nmb, ULONG port, char *data){ *data = inb(port);}wstdcall void WIN_FUNC(NdisImmediateReadPortUchar,3) (struct ndis_mp_block *nmb, ULONG port, char *data){ *data = inb(port);}wstdcall void WIN_FUNC(NdisWritePortUchar,3) (struct ndis_mp_block *nmb, ULONG port, char data){ outb(data, port);}wstdcall void WIN_FUNC(NdisImmediateWritePortUchar,3) (struct ndis_mp_block *nmb, ULONG port, char data){ outb(data, port);}wstdcall void WIN_FUNC(NdisMQueryAdapterResources,4) (NDIS_STATUS *status, struct ndis_mp_block *nmb, NDIS_RESOURCE_LIST *resource_list, UINT *size){ struct wrap_ndis_device *wnd = nmb->wnd; NDIS_RESOURCE_LIST *list; UINT resource_length; list = &wnd->wd->resource_list->list->partial_resource_list; resource_length = sizeof(struct cm_partial_resource_list) + sizeof(struct cm_partial_resource_descriptor) * (list->count - 1); TRACE2("%p, %p,%d (%d), %p %d %d", wnd, resource_list, *size, resource_length, &list->partial_descriptors[list->count-1], list->partial_descriptors[list->count-1].u.interrupt.level, list->partial_descriptors[list->count-1].u.interrupt.vector); if (*size < sizeof(*list)) { *size = resource_length; *status = NDIS_STATUS_BUFFER_TOO_SHORT; } else { ULONG count; if (*size >= resource_length) { *size = resource_length; count = list->count; } else { UINT n = sizeof(*list); count = 1; while (count++ < list->count && n < *size) n += sizeof(list->partial_descriptors); *size = n; } memcpy(resource_list, list, *size); resource_list->count = count; *status = NDIS_STATUS_SUCCESS; } EXIT2(return);}wstdcall NDIS_STATUS WIN_FUNC(NdisMPciAssignResources,3) (struct ndis_mp_block *nmb, ULONG slot_number, NDIS_RESOURCE_LIST **resources){ struct wrap_ndis_device *wnd = nmb->wnd; ENTER2("%p, %p", wnd, wnd->wd->resource_list); *resources = &wnd->wd->resource_list->list->partial_resource_list; EXIT2(return NDIS_STATUS_SUCCESS);}wstdcall NDIS_STATUS WIN_FUNC(NdisMMapIoSpace,4) (void **virt, struct ndis_mp_block *nmb, NDIS_PHY_ADDRESS phy_addr, UINT len){ struct wrap_ndis_device *wnd = nmb->wnd; ENTER2("%Lx, %d", phy_addr, len); *virt = MmMapIoSpace(phy_addr, len, MmCached); if (*virt == NULL) { ERROR("ioremap failed"); EXIT2(return NDIS_STATUS_FAILURE); } wnd->mem_start = phy_addr; wnd->mem_end = phy_addr + len; TRACE2("%p", *virt); EXIT2(return NDIS_STATUS_SUCCESS);}wstdcall void WIN_FUNC(NdisMUnmapIoSpace,3) (struct ndis_mp_block *nmb, void *virt, UINT len){ ENTER2("%p, %d", virt, len); MmUnmapIoSpace(virt, len); EXIT2(return);}wstdcall void WIN_FUNC(NdisAllocateSpinLock,1) (struct ndis_spinlock *lock){ TRACE4("lock %p, %p", lock, &lock->klock); KeInitializeSpinLock(&lock->klock); lock->irql = PASSIVE_LEVEL; EXIT4(return);}wstdcall void WIN_FUNC(NdisFreeSpinLock,1) (struct ndis_spinlock *lock){ TRACE4("lock %p, %p", lock, &lock->klock); EXIT4(return);}wstdcall void WIN_FUNC(NdisAcquireSpinLock,1) (struct ndis_spinlock *lock){ ENTER6("lock %p, %p", lock, &lock->klock);// assert_irql(_irql_ <= DISPATCH_LEVEL); lock->irql = nt_spin_lock_irql(&lock->klock, DISPATCH_LEVEL); EXIT6(return);}wstdcall void WIN_FUNC(NdisReleaseSpinLock,1) (struct ndis_spinlock *lock){ ENTER6("lock %p, %p", lock, &lock->klock);// assert_irql(_irql_ == DISPATCH_LEVEL); nt_spin_unlock_irql(&lock->klock, lock->irql); EXIT6(return);}wstdcall void WIN_FUNC(NdisDprAcquireSpinLock,1) (struct ndis_spinlock *lock){ ENTER6("lock %p", &lock->klock);// assert_irql(_irql_ == DISPATCH_LEVEL); nt_spin_lock(&lock->klock); EXIT6(return);}wstdcall void WIN_FUNC(NdisDprReleaseSpinLock,1) (struct ndis_spinlock *lock){ ENTER6("lock %p", &lock->klock);// assert_irql(_irql_ == DISPATCH_LEVEL); nt_spin_unlock(&lock->klock); EXIT6(return);}wstdcall void WIN_FUNC(NdisInitializeReadWriteLock,1) (struct ndis_rw_lock *rw_lock){ ENTER3("%p", rw_lock); memset(rw_lock, 0, sizeof(*rw_lock)); KeInitializeSpinLock(&rw_lock->klock); EXIT3(return);}/* read/write locks are implemented in a rather simplisitic way - we * should probably use Linux's rw_lock implementation */wstdcall void WIN_FUNC(NdisAcquireReadWriteLock,3) (struct ndis_rw_lock *rw_lock, BOOLEAN write, struct lock_state *lock_state){ if (write) { while (1) { if (cmpxchg(&rw_lock->count, 0, -1) == 0) return; while (rw_lock->count) cpu_relax(); } return; } while (1) { typeof(rw_lock->count) count; while ((count = rw_lock->count) < 0) cpu_relax(); if (cmpxchg(&rw_lock->count, count, count + 1) == count) return; }}wstdcall void WIN_FUNC(NdisReleaseReadWriteLock,2) (struct ndis_rw_lock *rw_lock, struct lock_state *lock_state){ if (rw_lock->count > 0) pre_atomic_add(rw_lock->count, -1); else if (rw_lock->count == -1) rw_lock->count = 0; else WARNING("invalid state: %d", rw_lock->count);}wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateMapRegisters,5) (struct ndis_mp_block *nmb, UINT dmachan, NDIS_DMA_SIZE dmasize, ULONG basemap, ULONG max_buf_size){ struct wrap_ndis_device *wnd = nmb->wnd; ENTER2("%p, %d %d %d %d", wnd, dmachan, dmasize, basemap, max_buf_size); if (wnd->dma_map_count > 0) { WARNING("%s: map registers already allocated: %u", wnd->net_dev->name, wnd->dma_map_count); EXIT2(return NDIS_STATUS_RESOURCES);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -