Skip to content

Commit

Permalink
Consolidate OID request code
Browse files Browse the repository at this point in the history
  • Loading branch information
bonsaiviking committed Aug 10, 2022
1 parent 406c4f7 commit d6644c0
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 99 deletions.
34 changes: 0 additions & 34 deletions packetWin7/npf/npf/Openclos.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,40 +121,6 @@ extern PDEVICE_OBJECT pNpcapDeviceObject;
extern SINGLE_LIST_ENTRY g_arrFiltMod; //Adapter filter module list head, each list item is a group head.
extern NDIS_SPIN_LOCK g_FilterArrayLock; //The lock for adapter filter module list.

/*!
\brief Utility routine that forms and sends an NDIS_OID_REQUEST to the miniport adapter.
\param FilterModuleContext Pointer to the filter context structure.
\param RequestType NdisRequest[Set|Query|method]Information.
\param Oid The object being set/queried.
\param InformationBuffer Data for the request.
\param InformationBufferLength Length of the above.
\param OutputBufferLength Valid only for method request.
\param MethodId Valid only for method request.
\param pBytesProcessed Place to return bytes read/written.
\return Status of the set/query request.
Utility routine that forms and sends an NDIS_OID_REQUEST to the miniport,
waits for it to complete, and returns status to the caller.
NOTE: this assumes that the calling routine ensures validity
of the filter handle until this returns.
*/
_IRQL_requires_(PASSIVE_LEVEL)
NDIS_STATUS
NPF_DoInternalRequest(
_At_(pFiltMod->AdapterBindingStatus, _In_range_(FilterPausing, FilterRestarting))
_In_ PNPCAP_FILTER_MODULE pFiltMod,
_In_ NDIS_REQUEST_TYPE RequestType,
_In_ NDIS_OID Oid,
_When_(RequestType == NdisRequestQueryInformation, _Out_writes_bytes_to_(InformationBufferLength, *pBytesProcessed))
_When_(RequestType == NdisRequestSetInformation, _In_reads_bytes_(InformationBufferLength))
_When_(RequestType == NdisRequestMethod, _Inout_updates_bytes_to_(InformationBufferLength, *pBytesProcessed))
PVOID InformationBuffer,
_In_ ULONG InformationBufferLength,
_In_opt_ ULONG OutputBufferLength,
_In_ ULONG MethodId,
_Out_ PULONG pBytesProcessed
);

/*!
\brief Add the open context to the group open array of a filter module.
\param pOpen Pointer to open context structure.
Expand Down
74 changes: 9 additions & 65 deletions packetWin7/npf/npf/Packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1509,7 +1509,6 @@ static NTSTATUS funcBIOC_OID(_In_ POPEN_INSTANCE pOpen,
_In_ BOOLEAN bSetOid,
_Out_ PULONG_PTR Info)
{
PINTERNAL_REQUEST pRequest = NULL;
PVOID OidBuffer = NULL;
LOCK_STATE_EX lockState;
ULONG ulTmp = 0;
Expand Down Expand Up @@ -1755,21 +1754,6 @@ static NTSTATUS funcBIOC_OID(_In_ POPEN_INSTANCE pOpen,

// The buffer is valid

// Extract a request from the list of free ones
pRequest = (PINTERNAL_REQUEST) ExAllocateFromLookasideListEx(&pOpen->DeviceExtension->InternalRequestPool);
if (pRequest == NULL)
{
INFO_DBG("pRequest=NULL\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
goto OID_REQUEST_DONE;
}
// This also zeroes the NDIS_OID_REQUEST structure.
RtlZeroMemory(pRequest, sizeof(INTERNAL_REQUEST));

pRequest->Request.Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
pRequest->Request.Header.Revision = NPCAP_REVISION_NDIS_OID_REQUEST;
pRequest->Request.Header.Size = NPCAP_SIZEOF_NDIS_OID_REQUEST;

/* NDIS_OID_REQUEST.InformationBuffer must be non-paged */
// TODO: Test whether this copy needs to happen. Buffered I/O ought to
// mean AssociatedIrp.SystemBuffer is non-paged already and is not
Expand All @@ -1783,70 +1767,36 @@ static NTSTATUS funcBIOC_OID(_In_ POPEN_INSTANCE pOpen,
}
RtlCopyMemory(OidBuffer, OidData->Data, OidData->Length);

if (bSetOid)
{
pRequest->Request.RequestType = NdisRequestSetInformation;
pRequest->Request.DATA.SET_INFORMATION.Oid = OidData->Oid;
Status = NPF_DoInternalRequest(pOpen->pFiltMod,
bSetOid ? NdisRequestSetInformation : NdisRequestQueryInformation,
OidData->Oid,
OidBuffer,
OidData->Length,
0, 0,
&ulTmp);

pRequest->Request.DATA.SET_INFORMATION.InformationBuffer = OidBuffer;
pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = OidData->Length;
}
else
{
pRequest->Request.RequestType = NdisRequestQueryInformation;
pRequest->Request.DATA.QUERY_INFORMATION.Oid = OidData->Oid;

pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = OidBuffer;
pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength = OidData->Length;
}

NdisInitializeEvent(&pRequest->InternalRequestCompletedEvent);
NdisResetEvent(&pRequest->InternalRequestCompletedEvent);

if (*((PVOID *) pRequest->Request.SourceReserved) != NULL)
{
*((PVOID *) pRequest->Request.SourceReserved) = NULL;
}

//
// submit the request
//
pRequest->Request.RequestId = (PVOID) NPF_REQUEST_ID;
pRequest->Request.RequestHandle = pOpen->pFiltMod->AdapterHandle;
// ASSERT(pOpen->pFiltMod->AdapterHandle != NULL);

Status = NdisFOidRequest(pOpen->pFiltMod->AdapterHandle, &pRequest->Request);

if (Status == NDIS_STATUS_PENDING)
{
NdisWaitEvent(&pRequest->InternalRequestCompletedEvent, 0);
Status = pRequest->RequestStatus;
}

//
// Complete the request
//
if (bSetOid)
{
OidData->Length = pRequest->Request.DATA.SET_INFORMATION.BytesRead;
OidData->Length = ulTmp;
INFO_DBG("BIOCSETOID completed, BytesRead = %u\n", OidData->Length);
*Info = FIELD_OFFSET(PACKET_OID_DATA, Data);
}
else
{
ulTmp = pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;

// check for the stupid bug of the Nortel driver ipsecw2k.sys v. 4.10.0.0 that doesn't set the BytesWritten correctly
// The driver is the one shipped with Nortel client Contivity VPN Client V04_65.18, and the MD5 for the buggy (unsigned) driver
// is 3c2ff8886976214959db7d7ffaefe724 *ipsecw2k.sys (there are multiple copies of this binary with the same exact version info!)
//
// The (certified) driver shipped with Nortel client Contivity VPN Client V04_65.320 doesn't seem affected by the bug.
//
//if (pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten > pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength)
if (ulTmp > OidData->Length)
{
INFO_DBG("Bogus return from NdisRequest (query): Bytes Written (%u) > InfoBufferLength (%u)!!\n",
pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten, pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength);
ulTmp, OidData->Length);
ulTmp = OidData->Length; // truncate
Status = NDIS_STATUS_INVALID_DATA;
}
Expand Down Expand Up @@ -1885,12 +1835,6 @@ static NTSTATUS funcBIOC_OID(_In_ POPEN_INSTANCE pOpen,
ExFreePoolWithTag(OidBuffer, NPF_USER_OID_TAG);
}

if (pRequest)
{
ExFreeToLookasideListEx(&pOpen->DeviceExtension->InternalRequestPool, pRequest);
pRequest = NULL;
}

NPF_StopUsingOpenInstance(pOpen, OpenAttached, NPF_IRQL_UNKNOWN);
return Status;
}
Expand Down
34 changes: 34 additions & 0 deletions packetWin7/npf/npf/Packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,40 @@ typedef __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) struct _PACKET_RESERVED
IoCompleteRequest(Irp, IO_NO_INCREMENT);\
return STATUS_UNSUCCESSFUL;\

/*!
\brief Utility routine that forms and sends an NDIS_OID_REQUEST to the miniport adapter.
\param FilterModuleContext Pointer to the filter context structure.
\param RequestType NdisRequest[Set|Query|method]Information.
\param Oid The object being set/queried.
\param InformationBuffer Data for the request.
\param InformationBufferLength Length of the above.
\param OutputBufferLength Valid only for method request.
\param MethodId Valid only for method request.
\param pBytesProcessed Place to return bytes read/written.
\return Status of the set/query request.
Utility routine that forms and sends an NDIS_OID_REQUEST to the miniport,
waits for it to complete, and returns status to the caller.
NOTE: this assumes that the calling routine ensures validity
of the filter handle until this returns.
*/
_IRQL_requires_(PASSIVE_LEVEL)
NDIS_STATUS
NPF_DoInternalRequest(
_At_(pFiltMod->AdapterBindingStatus, _In_range_(FilterPausing, FilterRestarting))
_In_ PNPCAP_FILTER_MODULE pFiltMod,
_In_ NDIS_REQUEST_TYPE RequestType,
_In_ NDIS_OID Oid,
_When_(RequestType == NdisRequestQueryInformation, _Out_writes_bytes_to_(InformationBufferLength, *pBytesProcessed))
_When_(RequestType == NdisRequestSetInformation, _In_reads_bytes_(InformationBufferLength))
_When_(RequestType == NdisRequestMethod, _Inout_updates_bytes_to_(InformationBufferLength, *pBytesProcessed))
PVOID InformationBuffer,
_In_ ULONG InformationBufferLength,
_In_opt_ ULONG OutputBufferLength,
_In_ ULONG MethodId,
_Out_ PULONG pBytesProcessed
);

/**
* @}
*/
Expand Down

0 comments on commit d6644c0

Please sign in to comment.