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

📄 request.c

📁 NDIS 实现pppoe例子
💻 C
字号:
/*
    MikroTik PPPoE - MikroTik PPP over Ethernet client for Windows
    Copyright (C),  2001  MikroTikls

    The contents of this program are subject to the Mozilla Public License 
    Version 1.1; you may not use this program except in compliance with the 
    License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ 

    
    http://www.mikrotik.com
    mt@mt.lv
*/


#include "request.h"
#include "debug.h"

void ProtoSetRequest(PADAPTER a, NDIS_OID oid, PVOID data, UINT len, ADAPTER_REQ_HANDLER h,
					 PDATABUF_DESCR p) {
	LOCK_STATE ls;
	PADAPT_REQ req;
	PVOID buf;
	NDIS_STATUS status;

	FENTER("ProtoSetRequest");

	// allocate memory for request
	if (NdisAllocateMemory(&req, sizeof(*req), 0, MaxAddress) != NDIS_STATUS_SUCCESS) {
		DbgPrint("out of memory for request structure\n");
		(*h)(a, NDIS_STATUS_FAILURE, NULL, 0, 0, NULL);

		FLEAVE("ProtoSetRequest");
		return;
	}

	if (NdisAllocateMemory(&buf, len, 0, MaxAddress) != NDIS_STATUS_SUCCESS) {
		DbgPrint("out of memory for data buffer\n");
		(*h)(a, NDIS_STATUS_FAILURE, NULL, 0, 0, NULL);

		NdisFreeMemory(req, sizeof(*req), 0);
		FLEAVE("ProtoSetRequest");
		return;
	}

	NdisZeroMemory(req, sizeof(*req));
	NdisMoveMemory(buf, data, len);

	req->req.RequestType = NdisRequestSetInformation;
  	req->req.DATA.SET_INFORMATION.Oid = oid;
  	req->req.DATA.SET_INFORMATION.InformationBuffer = buf;
  	req->req.DATA.SET_INFORMATION.InformationBufferLength = len;
	req->handler = h;
	if (p) NdisMoveMemory(&req->params, p, sizeof(*p));

	NdisAcquireReadWriteLock(&a->protoReqLock, TRUE, &ls);
	req->next = a->protoReqs;
	a->protoReqs = req;
	NdisReleaseReadWriteLock(&a->protoReqLock, &ls);

  	NdisRequest(&status, a->protoBindingHandle, &req->req);

	if (status != NDIS_STATUS_PENDING) {
		// issue artificial complete event
		ProtoHandleRequestReply(a, &req->req, status);
	}

	FLEAVE("ProtoSetRequest");
}

void ProtoQueryRequest(PADAPTER a, NDIS_OID oid, UINT len, ADAPTER_REQ_HANDLER h,
					   PDATABUF_DESCR p) {
	LOCK_STATE ls;
	PADAPT_REQ req;
	PVOID buf;
	NDIS_STATUS status;

	FENTER("ProtoQueryRequest");

	// allocate memory for request
	if (NdisAllocateMemory(&req, sizeof(*req), 0, MaxAddress) != NDIS_STATUS_SUCCESS) {
		DbgPrint("out of memory for request structure\n");
		(*h)(a, NDIS_STATUS_FAILURE, NULL, 0, 0, NULL);

		FLEAVE("ProtoQueryRequest");
		return;
	}

	if (NdisAllocateMemory(&buf, len, 0, MaxAddress) != NDIS_STATUS_SUCCESS) {
		DbgPrint("out of memory for data buffer\n");
		(*h)(a, NDIS_STATUS_FAILURE, NULL, 0, 0, NULL);

		NdisFreeMemory(req, sizeof(*req), 0);
		FLEAVE("ProtoQueryRequest");
		return;
	}

	NdisZeroMemory(req, sizeof(*req));
	NdisZeroMemory(buf, len);

	req->req.RequestType = NdisRequestQueryInformation;
  	req->req.DATA.QUERY_INFORMATION.Oid = oid;
  	req->req.DATA.QUERY_INFORMATION.InformationBuffer = buf;
  	req->req.DATA.QUERY_INFORMATION.InformationBufferLength = len;
	req->handler = h;
	if (p) NdisMoveMemory(&req->params, p, sizeof(*p));

	NdisAcquireReadWriteLock(&a->protoReqLock, TRUE, &ls);
	req->next = a->protoReqs;
	a->protoReqs = req;
	NdisReleaseReadWriteLock(&a->protoReqLock, &ls);

  	NdisRequest(&status, a->protoBindingHandle, &req->req);

	if (status != NDIS_STATUS_PENDING) {
		// issue artificial complete event
		ProtoHandleRequestReply(a, &req->req, status);
	}

	FLEAVE("ProtoQueryRequest");
}

static void ProtoSyncQueryReply(PADAPTER a, NDIS_STATUS s, PVOID data, UINT len, UINT alen,
						   PDATABUF_DESCR p) {
	FENTER("ProtoSyncQueryReply");

	if (s == NDIS_STATUS_SUCCESS) {
		if (a->protoSyncReqLen != len) DbgPrint("syncReqLen != len\n");
		NdisMoveMemory(a->protoSyncReqData, data, a->protoSyncReqLen);
	}

	a->protoSyncReqAlen = alen;
	a->protoSyncReqStatus = s;
	a->protoSyncReqComplete = 1;

	FLEAVE("ProtoSyncQueryReply");
}

static void ProtoSyncSetReply(PADAPTER a, NDIS_STATUS s, PVOID data, UINT len, UINT alen,
						 PDATABUF_DESCR p) {
	FENTER("ProtoSyncSetReply");

	a->protoSyncReqAlen = alen;
	a->protoSyncReqStatus = s;
	a->protoSyncReqComplete = 1;

	FLEAVE("ProtoSyncSetReply");
}

NDIS_STATUS ProtoQueryRequestSync(PADAPTER a, NDIS_OID oid, PVOID data, UINT len, PUINT alen) {
	NDIS_STATUS s;
	LOCK_STATE ls;

	FENTER("ProtoQueryRequestSync");

	NdisAcquireReadWriteLock(&a->protoSyncReqLock, TRUE, &ls);

	a->protoSyncReqComplete = 0;
	a->protoSyncReqData = data;
	a->protoSyncReqLen = len;
	ProtoQueryRequest(a, oid, len, ProtoSyncQueryReply, NULL);

	// stupid, but safest - busy wait for complete event
	while (a->protoSyncReqComplete == 0);

	if (alen) *alen = a->protoSyncReqAlen;
	s = a->protoSyncReqStatus;

	NdisReleaseReadWriteLock(&a->protoSyncReqLock, &ls);

	FLEAVE("ProtoQueryRequestSync");

	return s;
}

NDIS_STATUS ProtoSetRequestSync(PADAPTER a, NDIS_OID oid, PVOID data, UINT len, PUINT alen) {
	NDIS_STATUS s;
	LOCK_STATE ls;

	FENTER("ProtoSetRequestSync");

	NdisAcquireReadWriteLock(&a->protoSyncReqLock, TRUE, &ls);

	a->protoSyncReqComplete = 0;
	ProtoSetRequest(a, oid, data, len, ProtoSyncSetReply, NULL);

	// stupid, but safest - busy wait for complete event
	while (a->protoSyncReqComplete == 0);

	if (alen) *alen = a->protoSyncReqAlen;
	s = a->protoSyncReqStatus;

	NdisReleaseReadWriteLock(&a->protoSyncReqLock, &ls);

	FLEAVE("ProtoSetRequestSync");

	return s;
}

void ProtoHandleRequestReply(PADAPTER a, PNDIS_REQUEST req, NDIS_STATUS s) {
	PADAPT_REQ r = NULL;
	LOCK_STATE ls;

	FENTER("ProtoHandleRequestReply");

	NdisAcquireReadWriteLock(&a->protoReqLock, TRUE, &ls);

	if (a->protoReqs != NULL) {
		PADAPT_REQ *rp;
		for (rp = &a->protoReqs; *rp; rp = &((*rp)->next)) if (req == &((*rp)->req)) break;
		if (*rp != NULL) {
			DbgPrint("found request, unlinking\n");
			// unlink this bastard
			r = *rp;
			*rp = r->next;
		}
		else DbgPrint("WOW, reply for unknown request\n");
	}
	else DbgPrint("WOW, reply, when no requests...\n");

	NdisReleaseReadWriteLock(&a->protoReqLock, &ls);

	if (r) {
		// call handler callback and free memory
		if (req->RequestType == NdisRequestQueryInformation) {
			(r->handler)(a, s, req->DATA.QUERY_INFORMATION.InformationBuffer,
				         req->DATA.QUERY_INFORMATION.BytesWritten,
						 req->DATA.QUERY_INFORMATION.BytesNeeded,
						 &r->params);
			NdisFreeMemory(req->DATA.QUERY_INFORMATION.InformationBuffer,
						   req->DATA.QUERY_INFORMATION.InformationBufferLength, 0);
		}
		else {
			(r->handler)(a, s, req->DATA.SET_INFORMATION.InformationBuffer,
				         req->DATA.SET_INFORMATION.BytesRead,
						 req->DATA.SET_INFORMATION.BytesNeeded,
						 &r->params);
			NdisFreeMemory(req->DATA.SET_INFORMATION.InformationBuffer,
						   req->DATA.SET_INFORMATION.InformationBufferLength, 0);
		}
		NdisFreeMemory(r, sizeof(*r), 0);
	}

	FLEAVE("ProtoHandleRequestReply");
}

⌨️ 快捷键说明

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