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

📄 wrapndis.c

📁 ndiswrapper工具
💻 C
📖 第 1 页 / 共 4 页
字号:
			i++;		}		res = miniport_set_info(wnd, OID_802_3_MULTICAST_LIST,					buf, i * ETH_ALEN);		if (res == NDIS_STATUS_SUCCESS && i > 0)			packet_filter |= NDIS_PACKET_TYPE_MULTICAST;		else			packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;		kfree(buf);	}	DBGTRACE2("0x%08x", packet_filter);	res = set_packet_filter(wnd, packet_filter);	if (res)		DBGTRACE1("couldn't set packet filter (%08X)", res);	TRACEEXIT2(return);}static void link_status_handler(struct wrap_ndis_device *wnd){	struct ndis_assoc_info *ndis_assoc_info;	union iwreq_data wrqu;	NDIS_STATUS res;	const int assoc_size = sizeof(*ndis_assoc_info) + IW_CUSTOM_MAX + 32;#if WIRELESS_EXT <= 17	unsigned char *wpa_assoc_info, *ies;	unsigned char *p;	int i;#endif	TRACEENTER2("link: %d", netif_carrier_ok(wnd->net_dev));	if (wnd->physical_medium != NdisPhysicalMediumWirelessLan)		TRACEEXIT2(return);#ifndef CONFIG_NET_RADIO	TRACEEXIT2(return);#endif	if (!netif_carrier_ok(wnd->net_dev)) {		memset(&wrqu, 0, sizeof(wrqu));		wrqu.ap_addr.sa_family = ARPHRD_ETHER;		wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL);		TRACEEXIT2(return);	}	ndis_assoc_info = kmalloc(assoc_size, GFP_KERNEL);	if (!ndis_assoc_info) {		ERROR("couldn't allocate memory");		TRACEEXIT2(return);	}	memset(ndis_assoc_info, 0, assoc_size);	res = miniport_query_info(wnd, OID_802_11_ASSOCIATION_INFORMATION,				  ndis_assoc_info, assoc_size);	if (res) {		DBGTRACE2("query assoc_info failed (%08X)", res);		kfree(ndis_assoc_info);		TRACEEXIT2(return);	}#if WIRELESS_EXT > 17	memset(&wrqu, 0, sizeof(wrqu));	wrqu.data.length = ndis_assoc_info->req_ie_length;	wireless_send_event(wnd->net_dev, IWEVASSOCREQIE, &wrqu,			    ((char *)ndis_assoc_info) +			    ndis_assoc_info->offset_req_ies);	wrqu.data.length = ndis_assoc_info->resp_ie_length;	wireless_send_event(wnd->net_dev, IWEVASSOCRESPIE, &wrqu,			    ((char *)ndis_assoc_info) +			    ndis_assoc_info->offset_resp_ies);#else	/* we need 28 extra bytes for the format strings */	if ((ndis_assoc_info->req_ie_length +	     ndis_assoc_info->resp_ie_length + 28) > IW_CUSTOM_MAX) {		WARNING("information element is too long! (%u,%u),"			"association information dropped",			ndis_assoc_info->req_ie_length,			ndis_assoc_info->resp_ie_length);		kfree(ndis_assoc_info);		TRACEEXIT2(return);	}	wpa_assoc_info = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);	if (!wpa_assoc_info) {		ERROR("couldn't allocate memory");		kfree(ndis_assoc_info);		TRACEEXIT2(return);	}	p = wpa_assoc_info;	p += sprintf(p, "ASSOCINFO(ReqIEs=");	ies = ((char *)ndis_assoc_info) + ndis_assoc_info->offset_req_ies;	for (i = 0; i < ndis_assoc_info->req_ie_length; i++)		p += sprintf(p, "%02x", ies[i]);	p += sprintf(p, " RespIEs=");	ies = ((char *)ndis_assoc_info) + ndis_assoc_info->offset_resp_ies;	for (i = 0; i < ndis_assoc_info->resp_ie_length; i++)		p += sprintf(p, "%02x", ies[i]);	p += sprintf(p, ")");	memset(&wrqu, 0, sizeof(wrqu));	wrqu.data.length = p - wpa_assoc_info;	wireless_send_event(wnd->net_dev, IWEVCUSTOM, &wrqu, wpa_assoc_info);	kfree(wpa_assoc_info);#endif	kfree(ndis_assoc_info);	get_ap_address(wnd, (char *)&wrqu.ap_addr.sa_data);	wrqu.ap_addr.sa_family = ARPHRD_ETHER;	wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL);	DBGTRACE2(MACSTRSEP, MAC2STR(wrqu.ap_addr.sa_data));	TRACEEXIT2(return);}static void stats_timer_proc(unsigned long data){	struct wrap_ndis_device *wnd = (struct wrap_ndis_device *)data;	TRACEENTER2("");	if (wnd->stats_interval <= 0)		TRACEEXIT2(return);	set_bit(COLLECT_STATS, &wnd->wrap_ndis_pending_work);	schedule_wrap_work(&wnd->wrap_ndis_work);	wnd->stats_timer.expires += wnd->stats_interval;	add_timer(&wnd->stats_timer);}static void add_stats_timer(struct wrap_ndis_device *wnd){	if (wnd->physical_medium != NdisPhysicalMediumWirelessLan)		return;	if (wnd->stats_interval < 0)		wnd->stats_interval *= -1;	wnd->stats_timer.data = (unsigned long)wnd;	wnd->stats_timer.function = stats_timer_proc;	wnd->stats_timer.expires = jiffies + wnd->stats_interval;	add_timer(&wnd->stats_timer);}static void del_stats_timer(struct wrap_ndis_device *wnd){	TRACEENTER2("");	wnd->stats_interval *= -1;	del_timer_sync(&wnd->stats_timer);	TRACEEXIT2(return);}static void hangcheck_proc(unsigned long data){	struct wrap_ndis_device *wnd = (struct wrap_ndis_device *)data;	BOOLEAN reset;	struct miniport_char *miniport;	TRACEENTER2("");	if (wnd->hangcheck_interval <= 0)		TRACEEXIT2(return);	miniport = &wnd->wd->driver->ndis_driver->miniport;	if_serialize_lock(wnd);	reset = LIN2WIN1(miniport->hangcheck, wnd->nmb->adapter_ctx);	if_serialize_unlock(wnd);	if (reset) {		set_bit(MINIPORT_RESET, &wnd->wrap_ndis_pending_work);		schedule_wrap_work(&wnd->wrap_ndis_work);	}	wnd->hangcheck_timer.expires += wnd->hangcheck_interval;	add_timer(&wnd->hangcheck_timer);	TRACEEXIT3(return);}void hangcheck_add(struct wrap_ndis_device *wnd){	if (!wnd->wd->driver->ndis_driver->miniport.hangcheck ||	    hangcheck_interval < 0)		return;	if (hangcheck_interval > 0)		wnd->hangcheck_interval = hangcheck_interval * HZ;	if (wnd->hangcheck_interval < 0)		wnd->hangcheck_interval *= -1;	wnd->hangcheck_timer.data = (unsigned long)wnd;	wnd->hangcheck_timer.function = hangcheck_proc;	wnd->hangcheck_timer.expires = jiffies + wnd->hangcheck_interval;	add_timer(&wnd->hangcheck_timer);	return;}void hangcheck_del(struct wrap_ndis_device *wnd){	TRACEENTER2("");	if (wnd->hangcheck_interval > 0)		wnd->hangcheck_interval *= -1;	del_timer_sync(&wnd->hangcheck_timer);	TRACEEXIT2(return);}/* worker procedure to take care of setting/checking various states */static void wrap_ndis_worker(void *param){	struct wrap_ndis_device *wnd = (struct wrap_ndis_device *)param;	DBGTRACE2("%lu", wnd->wrap_ndis_pending_work);	if (test_bit(SHUTDOWN, &wnd->wrap_ndis_pending_work))		TRACEEXIT3(return);	if (test_and_clear_bit(SET_MULTICAST_LIST, &wnd->wrap_ndis_pending_work))		set_multicast_list(wnd);	if (test_and_clear_bit(COLLECT_STATS, &wnd->wrap_ndis_pending_work))		update_wireless_stats(wnd);	if (test_and_clear_bit(LINK_STATUS_CHANGED,			       &wnd->wrap_ndis_pending_work))		link_status_handler(wnd);	if (test_and_clear_bit(MINIPORT_RESET, &wnd->wrap_ndis_pending_work))		miniport_reset(wnd);	TRACEEXIT3(return);}NDIS_STATUS ndis_reinit(struct wrap_ndis_device *wnd){	NDIS_STATUS status;	wnd->pm_capa = FALSE;	status = miniport_set_power_state(wnd, NdisDeviceStateD3);	if (status != NDIS_STATUS_SUCCESS) {		ERROR("halting device %s failed: %08X", wnd->net_dev->name,		      status);		return status;	}	status = miniport_set_power_state(wnd, NdisDeviceStateD0);	if (status != NDIS_STATUS_SUCCESS)		ERROR("starting device %s failed: %08X", wnd->net_dev->name,		      status);	return status;}void get_encryption_capa(struct wrap_ndis_device *wnd){	int i, mode;	NDIS_STATUS res;	struct ndis_assoc_info ndis_assoc_info;	struct ndis_add_key ndis_key;	struct ndis_capability *c;	char *buf;	const int buf_len = 512;	TRACEENTER1("%p", wnd);	/* check if WEP is supported */	if (set_encr_mode(wnd, Ndis802_11Encryption1Enabled) == 0 &&	    get_encr_mode(wnd) == Ndis802_11Encryption1KeyAbsent)		set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr);	/* check if WPA is supported */	if (set_auth_mode(wnd, Ndis802_11AuthModeWPA) == 0 &&	    get_auth_mode(wnd) == Ndis802_11AuthModeWPA)		set_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth);	else		TRACEEXIT1(return);	if (set_auth_mode(wnd, Ndis802_11AuthModeWPAPSK) == 0 &&	    get_auth_mode(wnd) == Ndis802_11AuthModeWPAPSK)		set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth);	/* check for highest encryption */	mode = 0;	if (set_encr_mode(wnd, Ndis802_11Encryption3Enabled) == 0 &&	    (i = get_encr_mode(wnd)) > 0 &&	    (i == Ndis802_11Encryption3KeyAbsent ||	     i == Ndis802_11Encryption3Enabled))		mode = Ndis802_11Encryption3Enabled;	else if (set_encr_mode(wnd, Ndis802_11Encryption2Enabled) == 0 &&		 (i = get_encr_mode(wnd)) > 0 &&		 (i == Ndis802_11Encryption2KeyAbsent ||		  i == Ndis802_11Encryption2Enabled))		mode = Ndis802_11Encryption2Enabled;	else if (set_encr_mode(wnd, Ndis802_11Encryption1Enabled) == 0 &&		 (i = get_encr_mode(wnd)) > 0 &&		 (i == Ndis802_11Encryption1KeyAbsent ||		  i == Ndis802_11Encryption1Enabled))		mode = Ndis802_11Encryption1Enabled;	DBGTRACE1("mode: %d", mode);	if (mode == 0)		TRACEEXIT1(return);	set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr);	if (mode == Ndis802_11Encryption1Enabled)		TRACEEXIT1(return);	ndis_key.length = 32;	ndis_key.index = 0xC0000001;	ndis_key.struct_size = sizeof(ndis_key);	res = miniport_set_info(wnd, OID_802_11_ADD_KEY, &ndis_key,				ndis_key.struct_size);	DBGTRACE2("%08X, %lu", res, (unsigned long)sizeof(ndis_key));	if (res && res != NDIS_STATUS_INVALID_DATA)		TRACEEXIT1(return);	res = miniport_query_info(wnd, OID_802_11_ASSOCIATION_INFORMATION,				  &ndis_assoc_info, sizeof(ndis_assoc_info));	DBGTRACE1("%08X", res);	if (res == NDIS_STATUS_NOT_SUPPORTED)		TRACEEXIT1(return);	set_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr);	if (mode == Ndis802_11Encryption3Enabled)		set_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr);	/* not all drivers support OID_802_11_CAPABILITY, so we don't	 * know for sure if driver support WPA or WPAPSK; assume	 * WPA */	set_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth);	/* check for wpa2 */	buf = kmalloc(buf_len, GFP_KERNEL);	if (!buf) {		ERROR("couldn't allocate memory");		TRACEEXIT1(return);	}	memset(buf, 0, buf_len);	c = (struct ndis_capability *)buf;	res = miniport_query_info(wnd, OID_802_11_CAPABILITY, buf, buf_len);	if (!(res == NDIS_STATUS_SUCCESS && c->version == 2)) {		kfree(buf);		TRACEEXIT1(return);	}	wnd->num_pmkids = c->num_PMKIDs;	for (i = 0; i < c->num_auth_encr_pair; i++) {		struct ndis_auth_encr_pair *ae;		ae = &c->auth_encr_pair[i];		if ((char *)(ae + 1) > buf + buf_len)			break;		switch (ae->auth_mode) {		case Ndis802_11AuthModeOpen:		case Ndis802_11AuthModeShared:		case Ndis802_11AuthModeWPA:		case Ndis802_11AuthModeWPAPSK:		case Ndis802_11AuthModeWPANone:		case Ndis802_11AuthModeWPA2:		case Ndis802_11AuthModeWPA2PSK:			set_bit(ae->auth_mode, &wnd->capa.auth);			break;		default:			WARNING("unknown auth_mode: %d", ae->auth_mode);			break;		}		switch (ae->encr_mode) {		case Ndis802_11EncryptionDisabled:		case Ndis802_11Encryption1Enabled:		case Ndis802_11Encryption2Enabled:		case Ndis802_11Encryption3Enabled:			set_bit(ae->encr_mode, &wnd->capa.encr);			break;		default:			WARNING("unknown encr_mode: %d", ae->encr_mode);			break;		}	}	kfree(buf);	TRACEEXIT1(return);}wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo,					    struct irp *irp){	struct wrap_ndis_device *wnd;	DBGTRACE3("fdo: %p", fdo);	/* for now, we don't have anything intresting here, so pass it	 * down to bus driver */	wnd = fdo->reserved;	return IoPassIrpDown(wnd->nmb->pdo, irp);}WIN_FUNC_DECL(NdisDispatchDeviceControl,2)wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp){	struct io_stack_location *irp_sl;	struct wrap_ndis_device *wnd;	enum ndis_power_state state;	NTSTATUS status;	NDIS_STATUS ndis_status;	irp_sl = IoGetCurrentIrpStackLocation(irp);	wnd = fdo->reserved;	IOTRACE("fdo: %p, fn: %d:%d, wnd: %p", fdo, irp_sl->major_fn,		irp_sl->minor_fn, wnd);	if ((irp_sl->params.power.type == SystemPowerState &&	     irp_sl->params.power.state.system_state > PowerSystemWorking) ||	    (irp_sl->params.power.type == DevicePowerState &&	     irp_sl->params.power.state.device_state > PowerDeviceD0))		state = NdisDeviceStateD3;	else		state = NdisDeviceStateD0;	switch (irp_sl->minor_fn) {	case IRP_MN_SET_POWER:		if (state == NdisDeviceStateD0) {			status = IoSyncForwardIrp(wnd->nmb->pdo, irp);			if (status != STATUS_SUCCESS)				break;			ndis_status = miniport_set_power_state(wnd, state);			if (ndis_status != NDIS_STATUS_SUCCESS)				WARNING("couldn't set power to %d: %08X",					state, ndis_status);			DBGTRACE2("%s: device resumed", wnd->net_dev->name);			irp->io_status.status = status = STATUS_SUCCESS;			IoCompleteRequest(irp, IO_NO_INCREMENT);			break;		} else {			ndis_status = miniport_set_power_state(wnd, state);			/* TODO: handle error case */			if (ndis_status != NDIS_STATUS_SUCCESS)				WARNING("setting power to %d failed: %08X",					state, ndis_status);			status = IoAsyncForwardIrp(wnd->nmb->pdo, irp);		}		break;	case IRP_MN_QUERY_POWER:		if (wnd->pm_capa) {			ndis_status =				miniport_query_info(wnd, OID_PNP_QUERY_POWER,						    &state, sizeof(state));			DBGTRACE2("%d, %08X", state, ndis_status);			/* this OID must always succeed */			if (ndis_status != NDIS_STATUS_SUCCESS)				DBGTRACE1("query power returns %08X",					  ndis_status);			irp->io_status.status = STATUS_SUCCESS;		} else			irp->io_status.status = STATUS_SUCCESS;		status = IoPassIrpDown(wnd->nmb->pdo, irp);		break;	case IRP_MN_WAIT_WAKE:	case IRP_MN_POWER_SEQUENCE:		/* TODO: implement WAIT_WAKE */		status = IoPassIrpDown(wnd->nmb->pdo, irp);		break;	default:		status = IoPassIrpDown(wnd->nmb->pdo, irp);		break;	}	IOEXIT(return status);}WIN_FUNC_DECL(NdisDispatchPower,2)wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp){	struct io_stack_location *irp_sl;	struct wrap_ndis_device *wnd;	struct device_object *pdo;	NTSTATUS status;	IOTRACE("fdo: %p, irp: %p", fdo, irp);	irp_sl = IoGetCurrentIrpStackLocation(irp);	wnd = fdo->reserved;	pdo = wnd->nmb->pdo;	switch (irp_sl->minor_fn) {	case IRP_MN_START_DEVICE:		status = IoSyncForwardIrp(pdo, irp);		if (status != STATUS_SUCCESS)			break;		if (ndis_start_device(wnd) == NDIS_STATUS_SUCCESS)			status = STATUS_SUCCESS;		else			status = STATUS_FAILURE;		irp->io_status.status = status;		IoCompleteRequest(irp, IO_NO_INCREMENT);		break;	case IRP_MN_QUERY_STOP_DEVICE:		/* TODO: implement in NDIS */		status = IoPassIrpDown(wnd->nmb->pdo, irp);		break;	case IRP_MN_STOP_DEVICE:		miniport_halt(wnd);		irp->io_status.status = STATUS_SUCCESS;		status = IoAsyncForwardIrp(pdo, irp);		break;	case IRP_MN_REMOVE_DEVICE:		DBGTRACE1("%s", wnd->net_dev->name);		miniport_pnp_event(wnd, NdisDevicePnPEventSurpriseRemoved);		if (ndis_remove_device(wnd)) {

⌨️ 快捷键说明

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