|
|
/////////////////////////////////////////////////////////
//
// Copyright (c) 2001 Microsoft Corporation
//
// Module Name:
// tdiquery
//
// Abstract:
// This module contains code which deals with tdi queries
//
//////////////////////////////////////////////////////////
#include "sysvars.h"
//////////////////////////////////////////////////////////////
// private constants, types, and prototypes
//////////////////////////////////////////////////////////////
const PCHAR strFunc1 = "TSQueryInfo"; const PCHAR strFuncP1 = "TSQueryComplete";
//
// completion context
//
struct QUERY_CONTEXT { PIRP pUpperIrp; // irp from dll to complete
PMDL pLowerMdl; // mdl from lower irp
PUCHAR pucLowerBuffer; // data buffer from lower irp
}; typedef QUERY_CONTEXT *PQUERY_CONTEXT;
//
// completion function
//
TDI_STATUS TSQueryComplete( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context );
//////////////////////////////////////////////////////////////
// public functions
//////////////////////////////////////////////////////////////
// -----------------------------------------------------------------
//
// Function: TSQueryInfo
//
// Arguments: pGenericHeader -- handle of appropriate type
// pSendBuffer -- arguments from user dll
// pIrp -- completion information
//
// Returns: NTSTATUS (normally pending)
//
// Descript: This function queries the appropriate object for some information
//
// ----------------------------------------------------------------------------
NTSTATUS TSQueryInfo(PGENERIC_HEADER pGenericHeader, PSEND_BUFFER pSendBuffer, PIRP pUpperIrp) { ULONG ulQueryId = pSendBuffer->COMMAND_ARGS.ulQueryId;
//
// show debug, if it is turned on
//
if (ulDebugLevel & ulDebugShowCommand) { DebugPrint2("\nCommand = ulQUERYINFO\n" "FileObject = %p\n" "QueryId = 0x%08x\n", pGenericHeader, ulQueryId); }
//
// allocate all the necessary structures
//
PQUERY_CONTEXT pQueryContext = NULL; PUCHAR pucBuffer = NULL; PMDL pQueryMdl = NULL;
// first, our context
//
if ((TSAllocateMemory((PVOID *)&pQueryContext, sizeof(QUERY_CONTEXT), strFunc1, "QueryContext")) != STATUS_SUCCESS) { goto cleanup; } //
// next the data buffer (for the mdl)
//
if ((TSAllocateMemory((PVOID *)&pucBuffer, ulMAX_BUFFER_LENGTH, strFunc1, "pucBuffer")) != STATUS_SUCCESS) { goto cleanup; }
//
// then the actual mdl
//
pQueryMdl = TSAllocateBuffer(pucBuffer, ulMAX_BUFFER_LENGTH);
if (pQueryMdl) { pQueryContext->pUpperIrp = pUpperIrp; pQueryContext->pLowerMdl = pQueryMdl; pQueryContext->pucLowerBuffer = pucBuffer;
//
// finally, the irp itself
//
PIRP pLowerIrp = TSAllocateIrp(pGenericHeader->pDeviceObject, NULL);
if (pLowerIrp) { //
// if made it to here, everything is correctly allocated
// set up irp and call the tdi provider
//
#pragma warning(disable: CONSTANT_CONDITIONAL)
TdiBuildQueryInformation(pLowerIrp, pGenericHeader->pDeviceObject, pGenericHeader->pFileObject, TSQueryComplete, pQueryContext, ulQueryId, pQueryMdl);
#pragma warning(default: CONSTANT_CONDITIONAL)
//
// make the call to the tdi provider
//
pSendBuffer->pvLowerIrp = pLowerIrp; // so command can be cancelled
NTSTATUS lStatus = IoCallDriver(pGenericHeader->pDeviceObject, pLowerIrp);
if ((!NT_SUCCESS(lStatus)) && (ulDebugLevel & ulDebugShowCommand)) { DebugPrint2("%s: unexpected status for IoCallDriver [0x%08x]\n", strFunc1, lStatus); } return STATUS_PENDING; } }
//
// get to here if there was an error
//
cleanup: if (pQueryContext) { TSFreeMemory(pQueryContext); } if (pucBuffer) { TSFreeMemory(pucBuffer); } if (pQueryMdl) { TSFreeBuffer(pQueryMdl); }
return STATUS_INSUFFICIENT_RESOURCES; }
/////////////////////////////////////////////////////////////
// private functions
/////////////////////////////////////////////////////////////
// ---------------------------------------------------------
//
// Function: TSQueryComplete
//
// Arguments: pDeviceObject -- device object that called tdiquery
// pIrp -- IRP used in the call
// pContext -- context used for the call
//
// Returns: status of operation (STATUS_MORE_PROCESSING_REQUIRED)
//
// Descript: Gets the result of the query, stuffs results into
// receive buffer, completes the IRP from the dll, and
// cleans up the Irp and associated data from the query
//
// ---------------------------------------------------------
#pragma warning(disable: UNREFERENCED_PARAM)
TDI_STATUS TSQueryComplete(PDEVICE_OBJECT pDeviceObject, PIRP pLowerIrp, PVOID pvContext)
{ PQUERY_CONTEXT pQueryContext = (PQUERY_CONTEXT)pvContext; NTSTATUS lStatus = pLowerIrp->IoStatus.Status; ULONG_PTR ulCopyLength = pLowerIrp->IoStatus.Information; PRECEIVE_BUFFER pReceiveBuffer = TSGetReceiveBuffer(pQueryContext->pUpperIrp);
pReceiveBuffer->lStatus = lStatus;
if (NT_SUCCESS(lStatus)) { pReceiveBuffer->RESULTS.QueryRet.ulBufferLength = (ULONG)ulCopyLength; if (ulCopyLength) { RtlCopyMemory(pReceiveBuffer->RESULTS.QueryRet.pucDataBuffer, pQueryContext->pucLowerBuffer, ulCopyLength); } } else if (ulDebugLevel & ulDebugShowCommand) { DebugPrint2("%s: Completed with status 0x%08x\n", strFuncP1, lStatus); } TSCompleteIrp(pQueryContext->pUpperIrp);
//
// now cleanup
//
TSFreeBuffer(pQueryContext->pLowerMdl); TSFreeMemory(pQueryContext->pucLowerBuffer); TSFreeMemory(pQueryContext);
TSFreeIrp(pLowerIrp, NULL); return TDI_MORE_PROCESSING; }
#pragma warning(default: UNREFERENCED_PARAM)
///////////////////////////////////////////////////////////////////////////////
// end of file tdiquery.cpp
///////////////////////////////////////////////////////////////////////////////
|