📄 request.c
字号:
/*
* Copyright (c) 1999 - 2003
* NetGroup, Politecnico di Torino (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <basedef.h>
#include <vmm.h>
#include <ndis.h>
#include <vwin32.h>
#include "debug.h"
#include "packet.h"
#include <ntddpack.h>
#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG
/************************************************************
Function that allows to perform a query on a network driver
or to set the parameters of an adapter.
************************************************************/
DWORD
PacketRequest( POPEN_INSTANCE Open,
DWORD FunctionCode,
DWORD dwDDB,
DWORD hDevice,
PDIOCPARAMETERS pDiocParms )
{
PLIST_ENTRY RequestListEntry;
PINTERNAL_REQUEST pRequest;
PPACKET_RESERVED pReserved;
PPACKET_OID_DATA OidData;
NDIS_STATUS Status;
TRACE_ENTER( "Request Packet" );
/*extract a request from the list*/
NdisAcquireSpinLock( &Open->RequestSpinLock );
RequestListEntry = PacketRemoveHeadList(&Open->RequestList);
NdisReleaseSpinLock( &Open->RequestSpinLock );
if ( RequestListEntry == NULL )
{
IF_TRACE( "Request List Error" );
*(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
TRACE_LEAVE( "Request Packet" );
return NDIS_STATUS_FAILURE/*NDIS_STATUS_SUCCESS*/;
}
pReserved = CONTAINING_RECORD( RequestListEntry, PACKET_RESERVED, ListElement );
pRequest = CONTAINING_RECORD( pReserved, INTERNAL_REQUEST, Reserved );
OidData = (PPACKET_OID_DATA)(pDiocParms->lpvInBuffer);
if ( ( pDiocParms->cbInBuffer == pDiocParms->cbOutBuffer ) &&
( pDiocParms->cbInBuffer >= sizeof(PACKET_OID_DATA) - 1 + OidData->Length) )
{
pReserved->lpBuffer = (PVOID)PacketPageLock( pDiocParms->lpvInBuffer,
pDiocParms->cbInBuffer );
pReserved->lpcbBytesReturned= (PVOID)PacketPageLock( (PVOID)pDiocParms->lpcbBytesReturned,
sizeof(DWORD) );
pReserved->lpoOverlapped = (PVOID)PacketPageLock( (PVOID)pDiocParms->lpoOverlapped,
sizeof(OVERLAPPED) );
pReserved->cbBuffer = pDiocParms->cbInBuffer;
if ( FunctionCode == BIOCSETOID )
{
pRequest->Request.RequestType = NdisRequestSetInformation;
pRequest->Request.DATA.SET_INFORMATION.Oid = OidData->Oid;
pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = OidData->Length;
pRequest->Request.DATA.SET_INFORMATION.InformationBuffer = OidData->Data;
IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD )
{
IF_TRACE_MSG2( "Request Set: Oid=%08lx, Length=%08lx",
OidData->Oid,
OidData->Length );
}
}
else if ( FunctionCode == BIOCQUERYOID )
{
pRequest->Request.RequestType = NdisRequestQueryInformation;
pRequest->Request.DATA.QUERY_INFORMATION.Oid = OidData->Oid;
pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength= OidData->Length;
pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = OidData->Data;
IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD )
{
IF_TRACE_MSG3( "Request Query: Type:%d Oid=%08lx, Length=%08lx",
NdisRequestQueryInformation,
OidData->Oid,
OidData->Length );
}
}
else
{
pRequest->Request.RequestType = NdisRequestGeneric1;
pRequest->Request.DATA.QUERY_INFORMATION.Oid = OidData->Oid;
pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength= OidData->Length;
pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = OidData->Data;
IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD )
{
IF_TRACE_MSG3( "Request Statistic: Type:%d Oid=%08lx, Length=%08lx",
NdisRequestGeneric1,
OidData->Oid,
OidData->Length );
}
}
NdisRequest( &Status, Open->AdapterHandle, &pRequest->Request );
if ( Status != NDIS_STATUS_PENDING )
{
PacketRequestComplete( Open, &pRequest->Request, Status );
TRACE_LEAVE( "Request Packet" );
return /*NDIS_STATUS_FAILURE*/NDIS_STATUS_SUCCESS;
}
TRACE_LEAVE( "Request Packet" );
return (-1); /*Return ERROR_IO_PENDING and block the application*/
}
else
{
IF_TRACE_MSG4( "Request Buffer Error: In=%lx Out=%lx Size=%lx Length=%lx",
pDiocParms->cbInBuffer,
pDiocParms->cbOutBuffer,
sizeof( PACKET_OID_DATA ),
OidData->Length
);
*(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
}
TRACE_LEAVE( "Request Packet" );
return NDIS_STATUS_FAILURE/*NDIS_STATUS_SUCCESS*/;
}
/************************************************************
Function called by NDIS to complete asynchornously a
request
INPUT: ProtocolBindingContext - Structure describing the
current adapter
NdisRequest - Queue of NDIS internal requests
Status - Status of the operation reported by NDIS
************************************************************/
VOID NDIS_API
PacketRequestComplete( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status )
{
POPEN_INSTANCE Open;
PINTERNAL_REQUEST pRequest;
PPACKET_RESERVED pReserved;
OVERLAPPED* pOverlap;
PPACKET_OID_DATA oidData;
TRACE_ENTER( "RequestComplete" );
Open = (POPEN_INSTANCE)ProtocolBindingContext;
pRequest = CONTAINING_RECORD( NdisRequest, INTERNAL_REQUEST, Request );
pReserved = &pRequest->Reserved;
pOverlap = (OVERLAPPED *) pReserved->lpoOverlapped;
oidData = (PPACKET_OID_DATA)(pReserved->lpBuffer);
#if DEBUG
IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD )
{
ULONG i;
UCHAR* pcData = oidData->Data;
DbgPrint( "Packet: OID=%lx Status=%lx Buffer Length=%ld Buffer=%lx",
oidData->Oid, Status, oidData->Length, pcData );
for ( i=0; i<oidData->Length; i++, pcData++ )
{
if ( i%16 == 0 )
DbgPrint( "\r\nPacket: " );
DbgPrint( "%02x ", *pcData );
}
DbgPrint( "\r\n" );
IF_BREAK_SET;
}
#endif
if ( Status == NDIS_STATUS_SUCCESS )
{
/*if the operation was succesful*/
*(pReserved->lpcbBytesReturned) = oidData->Length + sizeof(PACKET_OID_DATA) - 1;
pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned);
}
else
{
/*if there is an error length contains the type of error*/
*(pReserved->lpcbBytesReturned) = 0;
pOverlap->O_InternalHigh = 0;
oidData->Length = Status;
}
/*wakes the suspended process */
VWIN32_DIOCCompletionRoutine( pOverlap->O_Internal );
PacketPageUnlock( pReserved->lpBuffer, pReserved->cbBuffer );
PacketPageUnlock( pReserved->lpcbBytesReturned, sizeof(DWORD) );
PacketPageUnlock( pReserved->lpoOverlapped, sizeof(OVERLAPPED) );
/*reinsert the request in the queue*/
NdisAcquireSpinLock( &Open->RequestSpinLock );
InsertTailList( &Open->RequestList, &pReserved->ListElement );
NdisReleaseSpinLock( &Open->RequestSpinLock );
TRACE_LEAVE( "RequestComplete" );
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -