Something went wrong. Try again.
Reactos
Something went wrong. Try again.
C++
at master
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300/*++
Copyright (c) Microsoft Corporation
Module Name:
FxDmaTransactionAPI.cpp
Abstract:
Base for WDF DMA Transaction APIs
Environment:
Kernel mode only.
Notes:
Revision History:
--*/
#include "fxdmapch.hpp"
extern "C" {// #include "FxDmaTransactionAPI.tmh"}
//// Extern "C" the entire file//extern "C" {
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)WDFAPINTSTATUSNTAPIWDFEXPORT(WdfDmaTransactionCreate)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMAENABLER DmaEnabler, __in_opt WDF_OBJECT_ATTRIBUTES * Attributes, __out WDFDMATRANSACTION * DmaTransactionHandle ){ NTSTATUS status; FxDmaEnabler* pDmaEnabler; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaEnabler, FX_TYPE_DMA_ENABLER, (PVOID *) &pDmaEnabler, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, DmaTransactionHandle);
*DmaTransactionHandle = NULL;
status = FxValidateObjectAttributes(pFxDriverGlobals, Attributes, FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED ); if (!NT_SUCCESS(status)) { return status; }
switch (pDmaEnabler->GetProfile()) { case WdfDmaProfilePacket: case WdfDmaProfilePacket64: status = FxDmaPacketTransaction::_Create(pFxDriverGlobals, Attributes, pDmaEnabler, DmaTransactionHandle); break;
case WdfDmaProfileScatterGather: case WdfDmaProfileScatterGather64: case WdfDmaProfileScatterGatherDuplex: case WdfDmaProfileScatterGather64Duplex: status = FxDmaScatterGatherTransaction::_Create( pFxDriverGlobals, Attributes, pDmaEnabler, DmaTransactionHandle ); break;
case WdfDmaProfileSystem: case WdfDmaProfileSystemDuplex: status = FxDmaSystemTransaction::_Create(pFxDriverGlobals, Attributes, pDmaEnabler, DmaTransactionHandle); break;
default: NT_ASSERTMSG("Unknown profile for DMA enabler", FALSE); status = STATUS_UNSUCCESSFUL; break; }
return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)WDFAPINTSTATUSNTAPIWDFEXPORT(WdfDmaTransactionInitializeUsingRequest)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in WDFREQUEST Request, __in PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction, __in WDF_DMA_DIRECTION DmaDirection ){ NTSTATUS status; FxDmaTransactionBase* pDmaTrans; FxRequest* pReqObj; MDL* mdl = NULL; PIO_STACK_LOCATION stack; ULONG reqLength; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, EvtProgramDmaFunction);
if (DmaDirection != WdfDmaDirectionReadFromDevice && DmaDirection != WdfDmaDirectionWriteToDevice) { status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Initialization of WDFDMATRANSACTION 0x%p using WDFREQUEST %p, " "DmaDirection 0x%x is an invalid value, %!STATUS!", DmaTransaction, Request, DmaDirection, status); return status; }
FxObjectHandleGetPtr(pFxDriverGlobals, Request, FX_TYPE_REQUEST, (PVOID *) &pReqObj);
reqLength = 0;
stack = pReqObj->GetFxIrp()->GetCurrentIrpStackLocation();
// // Get the MDL and Length from the request. // switch (stack->MajorFunction) {
case IRP_MJ_READ:
if (DmaDirection != WdfDmaDirectionReadFromDevice) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Dma direction %!WDF_DMA_DIRECTION! of WDFTRANSACTION " "0x%p doesn't match with the WDFREQUEST 0x%p type " "%!WDF_REQUEST_TYPE! %!STATUS!", DmaDirection, DmaTransaction, Request, stack->MajorFunction, status);
return status; }
reqLength = stack->Parameters.Read.Length;
status = pReqObj->GetMdl(&mdl); break;
case IRP_MJ_WRITE:
if (DmaDirection != WdfDmaDirectionWriteToDevice) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Dma direction %!WDF_DMA_DIRECTION! of WDFTRANSACTION " "0x%p doesn't match with the WDFREQUEST 0x%p type " "%!WDF_REQUEST_TYPE! %!STATUS!", DmaDirection, DmaTransaction, Request, stack->MajorFunction, status);
return status; }
reqLength = stack->Parameters.Write.Length;
status = pReqObj->GetMdl(&mdl); break;
case IRP_MJ_DEVICE_CONTROL: case IRP_MJ_INTERNAL_DEVICE_CONTROL:
switch (METHOD_FROM_CTL_CODE(stack->Parameters.DeviceIoControl.IoControlCode)) { case METHOD_BUFFERED:
if (DmaDirection == WdfDmaDirectionWriteToDevice) { reqLength = stack->Parameters.DeviceIoControl.InputBufferLength; } else { reqLength = stack->Parameters.DeviceIoControl.OutputBufferLength; }
// // In this case both input buffer and output buffer map // to the same MDL and it's probed for read & write access. // So it's okay for DMA transfer in either direction. // status = pReqObj->GetMdl(&mdl); break;
case METHOD_IN_DIRECT: // // For this type, the output buffer is probed for read access. // So the direction of DMA transfer is WdfDmaDirectionWriteToDevice. // if (DmaDirection != WdfDmaDirectionWriteToDevice) {
status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Dma direction %!WDF_DMA_DIRECTION! of WDFTRANSACTION " "0x%p doesn't match with WDFREQUEST 0x%p ioctl type " "METHOD_IN_DIRECT %!STATUS!", DmaDirection, DmaTransaction, Request, status); return status; }
reqLength = stack->Parameters.DeviceIoControl.OutputBufferLength;
status = pReqObj->GetDeviceControlOutputMdl(&mdl);
break;
case METHOD_OUT_DIRECT: // // For this type, the output buffer is probed for write access. // So the direction of DMA transfer is WdfDmaDirectionReadFromDevice. // if (DmaDirection != WdfDmaDirectionReadFromDevice) {
status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Dma direction %!WDF_DMA_DIRECTION! of WDFTRANSACTION " "0x%p doesn't match with WDFREQUEST 0x%p ioctl type " "METHOD_OUT_DIRECT %!STATUS!", DmaDirection, DmaTransaction, Request, status);
return status; }
reqLength = stack->Parameters.DeviceIoControl.OutputBufferLength;
status = pReqObj->GetDeviceControlOutputMdl(&mdl);
break; default:
status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Invalid ioctl code in WDFREQUEST 0x%p %!STATUS!", Request, status);
FxVerifierDbgBreakPoint(pFxDriverGlobals); break;
}// End of switch(ioctType) break;
default: status = STATUS_INVALID_DEVICE_REQUEST; break;
}
if (!NT_SUCCESS(status)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Couldn't retrieve mdl from WDFREQUEST 0x%p for " "WDFTRANSACTION 0x%p %!STATUS!", Request, DmaTransaction, status); return status; }
if (reqLength == 0) { status = STATUS_INVALID_DEVICE_REQUEST; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Zero length request, %!STATUS!", status); return status; }
// // If the DMA enabler is packet based, make sure the virtual address and // the length of transfer are within bounds. Basically, we are checking // to see if the length of data to be transferred doesn't span multiple // MDLs, because packet based DMA doesn't support chained MDLs. // if (pDmaTrans->GetDmaEnabler()->SupportsChainedMdls() == FALSE) { ULONG length;
length = MmGetMdlByteCount(mdl);
if (reqLength > length) { status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "WDFREQUEST %p transfer length (%d) is out of bounds of MDL " "Byte count (%d), %!STATUS!", Request, reqLength, length, status);
return status; } }
// // Parms appear OK, so initialize this instance. // status = pDmaTrans->Initialize(EvtProgramDmaFunction, DmaDirection, mdl, 0, reqLength);
if (!NT_SUCCESS(status)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "WDFTANSACTION 0x%p initialization failed: " "%!STATUS!", DmaTransaction, status); return status; }
// // Set this Request in the new DmaTransaction. The request will // take a reference on this request when it starts executing. // pDmaTrans->SetRequest(pReqObj);
return STATUS_SUCCESS;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)WDFAPINTSTATUSNTAPIWDFEXPORT(WdfDmaTransactionInitializeUsingOffset)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction, __in WDF_DMA_DIRECTION DmaDirection, __in PMDL Mdl, __in size_t Offset, __in __drv_when(Length == 0, __drv_reportError(Length cannot be zero)) size_t Length ){ // // Stub this out by calling the regular initialize method. Eventually // the regular initialize method will call this instead. //
return WDFEXPORT(WdfDmaTransactionInitialize)( DriverGlobals, DmaTransaction, EvtProgramDmaFunction, DmaDirection, Mdl, (PVOID) (((ULONG_PTR) MmGetMdlVirtualAddress(Mdl)) + Offset), Length );}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)WDFAPINTSTATUSNTAPIWDFEXPORT(WdfDmaTransactionInitialize)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction, __in WDF_DMA_DIRECTION DmaDirection, __in PMDL Mdl,
//__drv_when(DmaDirection == WdfDmaDirectionReadFromDevice, __out_bcount(Length)) //__drv_when(DmaDirection == WdfDmaDirectionWriteToDevice, __in_bcount(Length)) __in PVOID VirtualAddress, __in __drv_when(Length == 0, __drv_reportError(Length cannot be zero)) size_t Length ){ NTSTATUS status; FxDmaTransactionBase * pDmaTrans; PUCHAR pVA; ULONG mdlLength; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, EvtProgramDmaFunction); FxPointerNotNull(pFxDriverGlobals, Mdl);
if (Length == 0) { status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Can't initialize WDFDMATRANSACTION 0x%p with " "zero length transfer", DmaTransaction); return status; }
if (DmaDirection != WdfDmaDirectionReadFromDevice && DmaDirection != WdfDmaDirectionWriteToDevice) { status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Initialization of WDFDMATRANSACTION 0x%p,DmaDirection 0x%x is an " "invalid value, %!STATUS!", DmaTransaction, DmaDirection, status); return status; }
// // Make sure the VirtualAddress is within the first MDL bounds. // pVA = (PUCHAR) MmGetMdlVirtualAddress(Mdl); mdlLength = MmGetMdlByteCount(Mdl);
if (VirtualAddress < pVA || VirtualAddress >= WDF_PTR_ADD_OFFSET(pVA, mdlLength)) { status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "VirtualAddress %p is not within the Mdl bounds, StartVA (%p) + " "ByteCount (0x%x), %!STATUS! ", VirtualAddress, pVA, mdlLength, status);
return status; }
// // Get the DmaEnabler // FxObjectHandleGetPtr(pFxDriverGlobals, DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
if (pDmaTrans->GetDmaEnabler()->SupportsChainedMdls() == FALSE) { // // Make sure the MDL is not a chained MDL by checking // to see if the virtual address and the length // are within bounds. // if (WDF_PTR_ADD_OFFSET(VirtualAddress, Length) > WDF_PTR_ADD_OFFSET(pVA, mdlLength)) { status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "VirtualAddress+Length (%p+%I64d) is out of bounds of MDL VA + MDL " "Byte count (max address is %p). " "Possibly a chained MDL, %!STATUS!", VirtualAddress, Length, WDF_PTR_ADD_OFFSET(pVA, mdlLength), status);
return status; } }
status = pDmaTrans->Initialize(EvtProgramDmaFunction, DmaDirection, Mdl, WDF_PTR_GET_OFFSET( MmGetMdlVirtualAddress(Mdl), VirtualAddress ), (ULONG) Length);
if (!NT_SUCCESS(status)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "WDFTANSACTION 0x%p initialization failed: " "%!STATUS!", DmaTransaction, status); }
return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)WDFAPINTSTATUSNTAPIWDFEXPORT(WdfDmaTransactionExecute)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in_opt WDFCONTEXT Context ){ FxDmaTransactionBase* pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
return pDmaTrans->Execute(Context);}
__success(TRUE)__drv_maxIRQL(DISPATCH_LEVEL)WDFAPINTSTATUSNTAPIWDFEXPORT(WdfDmaTransactionRelease)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaTransactionBase* pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
// // Release map registers allocated for this specific transaction, // but not map registers which were allocated through // AllocateResources. // pDmaTrans->ReleaseForReuse(FALSE); return STATUS_SUCCESS;}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIBOOLEANNTAPIWDFEXPORT(WdfDmaTransactionDmaCompleted)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __out NTSTATUS * pStatus ){ FxDmaTransactionBase * pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
FxPointerNotNull(pDmaTrans->GetDriverGlobals(), pStatus);
// // Indicate this DMA has been completed. // return pDmaTrans->DmaCompleted(0, pStatus, FxDmaCompletionTypeFull);}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIBOOLEANNTAPIWDFEXPORT(WdfDmaTransactionDmaCompletedWithLength)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in size_t TransferredLength, __out NTSTATUS * pStatus ){ FxDmaTransactionBase* pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
FxPointerNotNull(pDmaTrans->GetDriverGlobals(), pStatus);
// // Indicate this DMA transfer has been completed. // return pDmaTrans->DmaCompleted(TransferredLength, pStatus, FxDmaCompletionTypePartial);}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIBOOLEANNTAPIWDFEXPORT(WdfDmaTransactionDmaCompletedFinal)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in size_t FinalTransferredLength, __out NTSTATUS * pStatus ){ FxDmaTransactionBase* pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
FxPointerNotNull(pDmaTrans->GetDriverGlobals(), pStatus);
// // Indicate this DMA FinalLength has completed. // return pDmaTrans->DmaCompleted(FinalTransferredLength, pStatus, FxDmaCompletionTypeAbort);}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIsize_tNTAPIWDFEXPORT(WdfDmaTransactionGetBytesTransferred)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaTransactionBase* pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
return pDmaTrans->GetBytesTransferred();}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIVOIDNTAPIWDFEXPORT(WdfDmaTransactionSetMaximumLength)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in size_t MaximumLength ){ FxDmaTransactionBase* pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
pDmaTrans->SetMaximumFragmentLength(MaximumLength);}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIWDFREQUESTNTAPIWDFEXPORT(WdfDmaTransactionGetRequest)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaTransactionBase* pDmaTrans; FxRequest* pRequest;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
pRequest = pDmaTrans->GetRequest();
if (pRequest != NULL) { return pRequest->GetHandle(); } else { return NULL; }}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIsize_tNTAPIWDFEXPORT(WdfDmaTransactionGetCurrentDmaTransferLength)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaTransactionBase* pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
return pDmaTrans->GetCurrentFragmentLength();}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIWDFDEVICENTAPIWDFEXPORT(WdfDmaTransactionGetDevice)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaTransactionBase* pDmaTrans;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans);
return pDmaTrans->GetDmaEnabler()->GetDeviceHandle();}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIVOIDNTAPIWDFEXPORT(WdfDmaTransactionSetChannelConfigurationCallback)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in_opt PFN_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL ConfigureRoutine, __in_opt PVOID ConfigureContext ){ FxDmaTransactionBase* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
// // Verify that the transaction belongs to a system profile enabler. //
WDF_DMA_PROFILE profile = pDmaTrans->GetDmaEnabler()->GetProfile(); if ((profile != WdfDmaProfileSystem) && (profile != WdfDmaProfileSystemDuplex)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on non-system-profile " "WDFDMATRANSACTION (%p) (transaction profile " "is %!WDF_DMA_PROFILE!).", DmaTransaction, profile); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
// // Cast the transaction to the right sub-type now that we've verified the // profile. //
FxDmaSystemTransaction* systemTransaction = (FxDmaSystemTransaction*) pDmaTrans; systemTransaction->SetConfigureChannelCallback(ConfigureRoutine, ConfigureContext);}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIVOIDNTAPIWDFEXPORT(WdfDmaTransactionSetTransferCompleteCallback)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in_opt PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE DmaCompletionRoutine, __in_opt PVOID DmaCompletionContext ){ FxDmaTransactionBase* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
// // Verify that the transaction belongs to a system profile enabler. //
WDF_DMA_PROFILE profile = pDmaTrans->GetDmaEnabler()->GetProfile(); if ((profile != WdfDmaProfileSystem) && (profile != WdfDmaProfileSystemDuplex)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on non-system-profile " "WDFDMATRANSACTION (%p) (transaction profile " "is %!WDF_DMA_PROFILE!).", DmaTransaction, profile); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
// // Cast the transaction to the right sub-type now that we've verified the // profile. //
FxDmaSystemTransaction* systemTransaction = (FxDmaSystemTransaction*) pDmaTrans; systemTransaction->SetTransferCompleteCallback(DmaCompletionRoutine, DmaCompletionContext);
}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIVOIDNTAPIWDFEXPORT(WdfDmaTransactionSetDeviceAddressOffset)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in ULONG Offset ){ FxDmaTransactionBase* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
// // Verify that the transaction belongs to a system profile enabler. //
WDF_DMA_PROFILE profile = pDmaTrans->GetDmaEnabler()->GetProfile(); if ((profile != WdfDmaProfileSystem) && (profile != WdfDmaProfileSystemDuplex)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on non-system-profile " "WDFDMATRANSACTION (%p) (transaction profile " "is %!WDF_DMA_PROFILE!).", DmaTransaction, profile); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
// // Cast the transaction to the right sub-type now that we've verified the // profile. //
FxDmaSystemTransaction* systemTransaction = (FxDmaSystemTransaction*) pDmaTrans; systemTransaction->SetDeviceAddressOffset(Offset);}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIPVOIDNTAPIWDFEXPORT(WdfDmaTransactionWdmGetTransferContext)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaTransactionBase* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
if (pDmaTrans->GetDmaEnabler()->UsesDmaV3() == FALSE) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! for WDFDMATRANSACTION %p " "because the parent WDFDMAENABLER (%p) is not " "configured to use DMA version 3.", DmaTransaction, pDmaTrans->GetDmaEnabler()->GetHandle()); FxVerifierDbgBreakPoint(pFxDriverGlobals); return NULL; }
FxDmaTransactionState state = pDmaTrans->GetTransactionState();
if ((state == FxDmaTransactionStateInvalid) || (state == FxDmaTransactionStateCreated) || (state == FxDmaTransactionStateReleased) || (state == FxDmaTransactionStateDeleted)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on WDFDMATRANSACTION %p " "becuase it is uninitialized, reused, deleted " "(state is %!FxDmaTransactionState!).", DmaTransaction, state ); FxVerifierDbgBreakPoint(pFxDriverGlobals); return NULL; }
return pDmaTrans->GetTransferContext();}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIVOIDNTAPIWDFEXPORT(WdfDmaTransactionGetTransferInfo)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __out_opt ULONG* MapRegisterCount, __out_opt ULONG* ScatterGatherElementCount ){ FxDmaTransactionBase* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
pDmaTrans->GetTransferInfo(MapRegisterCount, ScatterGatherElementCount);}
//// Stubbed WDF 1.11 DMA DDIs start here.//
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIVOIDNTAPIWDFEXPORT(WdfDmaTransactionSetImmediateExecution)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in BOOLEAN UseImmediateExecution ){ FxDmaTransactionBase* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
if (pDmaTrans->GetDmaEnabler()->UsesDmaV3() == FALSE) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! for WDFDMATRANSACTION %p " "because the parent WDFDMAENABLER (%p) is not " "configured to use DMA version 3.", DmaTransaction, pDmaTrans->GetDmaEnabler()->GetHandle()); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
pDmaTrans->SetImmediateExecution(UseImmediateExecution);}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPINTSTATUSNTAPIWDFEXPORT(WdfDmaTransactionAllocateResources)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction, __in WDF_DMA_DIRECTION DmaDirection, __in ULONG RequiredMapRegisters, __in PFN_WDF_RESERVE_DMA EvtReserveDmaFunction, __in PVOID EvtReserveDmaContext ){ FxDmaPacketTransaction* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
// // Only valid if DMA V3 is enabled. //
if (pDmaTrans->GetDmaEnabler()->UsesDmaV3() == FALSE) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on WDFDMATRANSACTION %p " "because WDFDMAENABLER %p was not configured " "for DMA version 3 - %!STATUS!.", DmaTransaction, pDmaTrans->GetDmaEnabler()->GetHandle(), status); FxVerifierDbgBreakPoint(pFxDriverGlobals); return status; }
// // Only valid for packet or system profile transactions. // WDF_DMA_PROFILE profile = pDmaTrans->GetDmaEnabler()->GetProfile(); if ((profile != WdfDmaProfilePacket) && (profile != WdfDmaProfilePacket64) && (profile != WdfDmaProfileSystem) && (profile != WdfDmaProfileSystemDuplex)) {
status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on non packet or system " "profile WDFDMATRANSACTION (%p) (transaction " "profile is %!WDF_DMA_PROFILE!) - %!STATUS!.", DmaTransaction, profile, status); FxVerifierDbgBreakPoint(pFxDriverGlobals); return status; }
// // Validate the direction value. // if (DmaDirection != WdfDmaDirectionReadFromDevice && DmaDirection != WdfDmaDirectionWriteToDevice) { status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Allocation of DMA adapter for WDFDMATRANSACTION 0x%p, " "DmaDirection 0x%x is an invalid value, %!STATUS!", DmaTransaction, DmaDirection, status); FxVerifierDbgBreakPoint(pFxDriverGlobals); return status; }
FxPointerNotNull(pFxDriverGlobals, EvtReserveDmaFunction);
status = pDmaTrans->ReserveAdapter(RequiredMapRegisters, DmaDirection, EvtReserveDmaFunction, EvtReserveDmaContext);
return status;}__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIVOIDNTAPIWDFEXPORT(WdfDmaTransactionFreeResources)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaPacketTransaction* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
// // Only valid for packet or system profile transactions. // WDF_DMA_PROFILE profile = pDmaTrans->GetDmaEnabler()->GetProfile(); if ((profile != WdfDmaProfilePacket) && (profile != WdfDmaProfilePacket64) && (profile != WdfDmaProfileSystem) && (profile != WdfDmaProfileSystemDuplex)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on non packet or system " "profile WDFDMATRANSACTION (%p) (transaction " "profile is %!WDF_DMA_PROFILE!).", DmaTransaction, profile); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
// // Only valid if DMA V3 is enabled. //
if (pDmaTrans->GetDmaEnabler()->UsesDmaV3() == FALSE) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on WDFDMATRANSACTION %p " "because WDFDMAENABLER %p was not configured " "for DMA version 3", DmaTransaction, pDmaTrans->GetDmaEnabler()->GetHandle()); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
pDmaTrans->ReleaseAdapter();
return;}__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIBOOLEANNTAPIWDFEXPORT(WdfDmaTransactionCancel)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaTransactionBase* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
// // Only valid if the enabler uses DMA v3 //
if (pDmaTrans->GetDmaEnabler()->UsesDmaV3() == FALSE) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! WDFDMATRANSACTION (%p) " "because enabler is not using DMA version 3", DmaTransaction); FxVerifierDbgBreakPoint(pFxDriverGlobals); return FALSE; }
return pDmaTrans->CancelResourceAllocation();}
__drv_maxIRQL(DISPATCH_LEVEL)WDFAPIVOIDNTAPIWDFEXPORT(WdfDmaTransactionStopSystemTransfer)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDMATRANSACTION DmaTransaction ){ FxDmaTransactionBase* pDmaTrans; PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), DmaTransaction, FX_TYPE_DMA_TRANSACTION, (PVOID *) &pDmaTrans, &pFxDriverGlobals);
// // Verify that the transaction belongs to a system profile enabler. //
WDF_DMA_PROFILE profile = pDmaTrans->GetDmaEnabler()->GetProfile(); if ((profile != WdfDmaProfileSystem) && (profile != WdfDmaProfileSystemDuplex)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, "Cannot call %!FUNC! on non-system-profile " "WDFDMATRANSACTION (%p) (transaction profile " "is %!WDF_DMA_PROFILE!).", DmaTransaction, profile); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
// // Cast the transaction to the right sub-type now that we've verified the // profile. //
FxDmaSystemTransaction* systemTransaction = (FxDmaSystemTransaction*) pDmaTrans; systemTransaction->StopTransfer(); return;}
} // extern "C"