📄 request.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 + -