Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809/*++
Copyright (c) Microsoft Corporation
Module Name:
FxRequestApi.cpp
Abstract:
This module implements FxRequest object
Author:
Environment:
Both kernel and user mode
Revision History:
--*/#include "coreprivshared.hpp"
// Tracing supportextern "C" {// #include "FxRequestApi.tmh"
//// Verifiers//// Do not supply Argument namesFX_DECLARE_VF_FUNCTION_P1(NTSTATUS,VerifyRequestComplete, _In_ FxRequest* );
// Do not supply Argument namesFX_DECLARE_VF_FUNCTION_P1(NTSTATUS,VerifyWdfRequestIsCanceled, _In_ FxRequest* );
//Do not supply argument namesFX_DECLARE_VF_FUNCTION_P1(NTSTATUS,VerifyWdfRequestForwardToIoQueue, _In_ FxRequest* );
//Do not supply argument namesFX_DECLARE_VF_FUNCTION_P1(NTSTATUS,VerifyWdfRequestForwardToParentDeviceIoQueue, _In_ FxRequest* );
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestCreate)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES RequestAttributes, __in_opt WDFIOTARGET Target, __out WDFREQUEST* Request )
/*++
Routine Description: Creates a WDFREQUEST handle that is suitable to be submitted to the provided target
Arguments: RequestAttributes - Attributes associated with the request. If NULL, the size of the user context associated with the request will be the default size specified in WdfDriverCreate.
Target - Target for which the request will be sent to. If NULL, then WdfRequestChangeTarget must be called before the request is formatted or sent to any target
Request - Pointer which will receive the newly created request
Return Value: NT_SUCCESS if successful, otherwise appropriate error code
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest* pRequest; FxIoTarget* pTarget; NTSTATUS status;
pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
if (Target != NULL) { FxObjectHandleGetPtrAndGlobals(pFxDriverGlobals, Target, FX_TYPE_IO_TARGET, (PVOID*)&pTarget, &pFxDriverGlobals); } else { pTarget = NULL;
// // For class extension support, get globals from parent object. // if (RequestAttributes != NULL && RequestAttributes->ParentObject != NULL) {
FxObjectHandleGetGlobals( pFxDriverGlobals, RequestAttributes->ParentObject, &pFxDriverGlobals); } }
FxPointerNotNull(pFxDriverGlobals, Request); *Request = NULL;
status = FxRequest::_Create(pFxDriverGlobals, RequestAttributes, NULL, pTarget, FxRequestOwnsIrp, FxRequestConstructorCallerIsDriver, &pRequest);
if (NT_SUCCESS(status)) { *Request = pRequest->GetHandle();
#if FX_VERBOSE_TRACE DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Created WDFREQUEST %p, %!STATUS!", *Request, status);#endif // FX_VERBOSE_TRACE }
return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestCreateFromIrp)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES RequestAttributes, __in MdIrp Irp, __in BOOLEAN RequestFreesIrp, __out WDFREQUEST* Request )
/*++
Routine Description: Creates a request handle that uses an external IRP instead of an internally allocated irp.
Arguments: RequestAttributes - Attributes associated with the request. If NULL, the size of the user context associated with the request will be the default size specified in WdfDriverCreate.
Irp - The IRP to use
RequestFreesIrp - If TRUE, when the request handle is destroyed, it will free the IRP with IoFreeIrp. If FALSE, it is the responsibility of the calller to free the IRP
Request - Pointer which will receive the newly created request
Return Value: NT_SUCCESS or appropriate error code
--*/
{ FxRequest* pRequest; NTSTATUS status; PFX_DRIVER_GLOBALS pFxDriverGlobals;
pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
// // For class extension support, get globals from parent object. // if (RequestAttributes != NULL && RequestAttributes->ParentObject != NULL) {
FxObjectHandleGetGlobals( pFxDriverGlobals, RequestAttributes->ParentObject, &pFxDriverGlobals); }
FxPointerNotNull(pFxDriverGlobals, Irp); FxPointerNotNull(pFxDriverGlobals, Request);
*Request = NULL;
status = FxRequest::_Create(pFxDriverGlobals, RequestAttributes, Irp, NULL, RequestFreesIrp ? FxRequestOwnsIrp : FxRequestDoesNotOwnIrp, FxRequestConstructorCallerIsDriver, &pRequest);
if (NT_SUCCESS(status)) { *Request = pRequest->GetHandle();
#if FX_VERBOSE_TRACE DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Irp %p RequestFreesIrp %d WDFREQUEST %p created", Irp, RequestFreesIrp, *Request);#endif // FX_VERBOSE_TRACE }
return status;}
#define WDF_REQUEST_REUSE_VALID_FLAGS_V1_9 \ (WDF_REQUEST_REUSE_SET_NEW_IRP)
#define WDF_REQUEST_REUSE_VALID_FLAGS \ (WDF_REQUEST_REUSE_SET_NEW_IRP | WDF_REQUEST_REUSE_MUST_COMPLETE)
__drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestReuse)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in PWDF_REQUEST_REUSE_PARAMS ReuseParams )/*++
Routine Description: Clears out the internal state of the irp, which includes, but is not limited to: a) Any internal allocations for the previously formatted request b) The completion routine and its context c) The request's intended i/o target d) All of the internal IRP's stack locations
Arguments: Request - The request to be reused.
ReuseParams - Parameters controlling the reuse of the request, see comments for each field in the structure for usage
Return Value: NT_SUCCESS or appropriate error code
--*/ { PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest *pRequest; ULONG validFlags;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, ReuseParams);
if (ReuseParams->Size != sizeof(WDF_REQUEST_REUSE_PARAMS)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "ReuseParams Size %d, expected %d %!STATUS!", ReuseParams->Size, sizeof(WDF_REQUEST_REUSE_PARAMS), STATUS_INVALID_PARAMETER); return STATUS_INVALID_PARAMETER; }
if (pFxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,11)) { validFlags = WDF_REQUEST_REUSE_VALID_FLAGS; } else { validFlags = WDF_REQUEST_REUSE_VALID_FLAGS_V1_9; }
if (ReuseParams->Flags & ~validFlags) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "ReuseParams Flags 0x%x, valid mask 0x%x, %!STATUS!", ReuseParams->Flags, (ULONG) ~validFlags, STATUS_INVALID_PARAMETER); return STATUS_INVALID_PARAMETER; }
return pRequest->Reuse(ReuseParams);}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestChangeTarget)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in WDFIOTARGET IoTarget ){ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest* pRequest; FxIoTarget* pTarget;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxObjectHandleGetPtr(pFxDriverGlobals, IoTarget, FX_TYPE_IO_TARGET, (PVOID*)&pTarget);
return pRequest->ValidateTarget(pTarget);}
_Must_inspect_result_NTSTATUSFX_VF_FUNCTION(VerifyRequestComplete) ( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest* pRequest ){ NTSTATUS status; KIRQL irql;
PAGED_CODE_LOCKED();
pRequest->Lock(&irql);
status = pRequest->VerifyRequestIsDriverOwned(FxDriverGlobals); if (NT_SUCCESS(status)) { status = pRequest->VerifyRequestCanBeCompleted(FxDriverGlobals); }
pRequest->Unlock(irql); return status;}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDWDFAPINTAPIWDFEXPORT(WdfRequestComplete)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in NTSTATUS RequestStatus )
/*++
Routine Description:
Complete the request with supplied status.
Any default reference counts implied by handle are invalid after completion.
Arguments:
Request - Handle to the Request object
RequestStatus - Wdm Status to complete the request with
Returns:
None
--*/{ NTSTATUS status; FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest);#if FX_VERBOSE_TRACE // // Use object's globals, not the caller's // DoTraceLevelMessage(pRequest->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Completing WDFREQUEST 0x%p, %!STATUS!", Request, RequestStatus);#endif status = VerifyRequestComplete(pRequest->GetDriverGlobals(), pRequest ); if (!NT_SUCCESS(status)) { return; }
pRequest->Complete(RequestStatus);}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDWDFAPINTAPIWDFEXPORT(WdfRequestCompleteWithPriorityBoost)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in NTSTATUS RequestStatus, __in CCHAR PriorityBoost )
/*++
Routine Description:
Complete the request with supplied status.
Any default reference counts implied by handle are invalid after completion.
Arguments:
Request - Handle to the Request object
RequestStatus - Wdm Status to complete the request with
PriorityBoost - A system-defined constant value by which to increment the run-time priority of the original thread that requested the operation.
Returns:
None
--*/
{ NTSTATUS status; FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest);
#if FX_VERBOSE_TRACE // // Use the object's globals, not the caller's // DoTraceLevelMessage(pRequest->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Completing WDFREQUEST 0x%p, %!STATUS!", Request, RequestStatus);#endif status = VerifyRequestComplete(pRequest->GetDriverGlobals(), pRequest); if (!NT_SUCCESS(status)) { return; }
pRequest->CompleteWithPriority(RequestStatus, PriorityBoost);}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDWDFAPINTAPIWDFEXPORT(WdfRequestCompleteWithInformation)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in NTSTATUS RequestStatus, __in ULONG_PTR Information )
/*++
Routine Description:
Complete the request with supplied status and information.
Any default reference counts implied by handle are invalid after completion.
Arguments:
Request - Handle to the Request object
RequestStatus - Wdm Status to complete the request with
Information - Information to complete request with
Returns:
None
--*/
{ FxRequest *pRequest; NTSTATUS status;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest);
#if FX_VERBOSE_TRACE // // Use the object's globals, not the caller's // DoTraceLevelMessage(pRequest->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Completing WDFREQUEST 0x%p, %!STATUS!", Request, RequestStatus);#endif status = VerifyRequestComplete(pRequest->GetDriverGlobals(), pRequest); if (!NT_SUCCESS(status)) { return; }
pRequest->CompleteWithInformation(RequestStatus, Information);}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDWDFAPINTAPIWDFEXPORT(WdfRequestSetInformation)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in ULONG_PTR Information )
/*++
Routine Description:
Set the transfer information for the request.
This sets the NT Irp->Status.Information field.
Arguments:
Request - Handle to the Request object
Information - Value to be set
Returns:
None
--*/
{ FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest);
#if FX_VERBOSE_TRACE // // Use the object's globals, not the caller's // DoTraceLevelMessage(pRequest->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p, Information 0x%p", Request, (VOID*)Information);#endif // FX_VERBOSE_TRACE
pRequest->SetInformation(Information);}
__drv_maxIRQL(DISPATCH_LEVEL)ULONG_PTRWDFAPINTAPIWDFEXPORT(WdfRequestGetInformation)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description:
Get the transfer information for the reuqest.
Arguments:
Request - Handle to the Request object
Returns:
Returns Irp->IoStatus.Information value.
--*/
{ FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest);
return pRequest->GetInformation();}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestRetrieveInputMemory)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __out WDFMEMORY *Memory )/*++
Routine Description:
Return the WDFMEMORY buffer associated with the request.
The memory buffer is valid in any thread/process context, and may be accessed at IRQL > PASSIVE_LEVEL.
The memory buffer is automatically released when the request is completed.
The memory buffers access permissions are validated according to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may only be accessed according to the access semantics of the request.
The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL, or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are configured for the device object.
The Memory buffer is as follows for each buffering mode:
DO_BUFFERED_IO:
Irp->AssociatedIrp.SystemBuffer
DO_DIRECT_IO:
MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
NEITHER flag set:
NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order to access the request in the calling threads address space before it is placed into any I/O Queues.
The buffer is only valid until the request is completed.
Arguments:
Request - Handle to the Request object
Memory - Pointer location to return WDFMEMORY handle
Returns:
NTSTATUS
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; IFxMemory* pMemory; PVOID pBuffer; size_t length;
pMemory = NULL;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Memory);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
// // This call is not valid on Read request. // if (pRequest->GetFxIrp()->GetMajorFunction() == IRP_MJ_READ) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on the Read request, you should call" " WdfRequestRetrieveOutputMemory to get the Memory for WDFREQUEST " "0x%p, %!STATUS!", Request, status);
return status; }
status = pRequest->GetMemoryObject(&pMemory, &pBuffer, &length); if (NT_SUCCESS(status)) { *Memory = pMemory->GetHandle(); }
return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestRetrieveOutputMemory)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __out WDFMEMORY *Memory )
/*++
Routine Description:
Return the WDFMEMORY buffer associated with the request.
The memory buffer is valid in any thread/process context, and may be accessed at IRQL > PASSIVE_LEVEL.
The memory buffer is automatically released when the request is completed.
The memory buffers access permissions are validated according to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may only be accessed according to the access semantics of the request.
The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL, or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are configured for the device object.
The Memory buffer is as follows for each buffering mode:
DO_BUFFERED_IO:
Irp->AssociatedIrp.SystemBuffer
DO_DIRECT_IO:
MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
NEITHER flag set:
NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order to access the request in the calling threads address space before it is placed into any I/O Queues.
The buffer is only valid until the request is completed.
Arguments:
Request - Handle to the Request object
Memory - Pointer location to return WDFMEMORY handle
Returns:
NTSTATUS
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; IFxMemory* pMemory; PVOID pBuffer; size_t length; UCHAR majorFunction;
pMemory = NULL;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Memory);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
// // This call is not valid on Write request. // majorFunction = pRequest->GetFxIrp()->GetMajorFunction();
if (majorFunction == IRP_MJ_WRITE) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on the Write request, you should call" " WdfRequestRetrieveInputMemory to get the Memory for WDFREQUEST " "0x%p, %!STATUS!", Request, status);
return status; }
if( (majorFunction == IRP_MJ_DEVICE_CONTROL) || (majorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) ) { status = pRequest->GetDeviceControlOutputMemoryObject(&pMemory, &pBuffer, &length); } else { status = pRequest->GetMemoryObject(&pMemory, &pBuffer, &length); }
if (NT_SUCCESS(status)) { *Memory = pMemory->GetHandle(); }
return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestRetrieveInputBuffer)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in size_t RequiredLength, __deref_out_bcount(*Length) PVOID* Buffer, __out_opt size_t* Length )/*++
Routine Description:
Return the memory buffer associated with the request along with its maximum length.
The memory buffer is valid in any thread/process context, and may be accessed at IRQL > PASSIVE_LEVEL.
The memory buffer is automatically released when the request is completed.
The memory buffers access permissions are validated according to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may only be accessed according to the access semantics of the request.
The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL, or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are configured for the device object.
The Memory buffer is as follows for each buffering mode:
DO_BUFFERED_IO:
Irp->AssociatedIrp.SystemBuffer
DO_DIRECT_IO:
MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
NEITHER flag set:
NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order to access the request in the calling threads address space before it is placed into any I/O Queues.
The buffer is only valid until the request is completed.
Arguments:
Request - Handle to the Request object
RequiredLength - This is the minimum size expected by the caller
Buffer - Pointer location to return buffer ptr
Length - actual size of the buffer. This is >= to RequiredLength
Returns:
NTSTATUS
--*/{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; IFxMemory* pMemory; PVOID pBuffer; size_t length;
pMemory = NULL;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
// // Validate the pointers and set its content to NULL // FxPointerNotNull(pFxDriverGlobals, Buffer); *Buffer = NULL;
if (Length != NULL) { *Length = 0; }
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif //FX_VERBOSE_TRACE
// // This call is not valid on Read request. // if (pRequest->GetFxIrp()->GetMajorFunction() == IRP_MJ_READ) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on the read request, you should call" " WdfRequestRetrieveOutputBuffer to get the buffer for WDFREQUEST " "0x%p, %!STATUS!", Request, status);
return status; }
status = pRequest->GetMemoryObject(&pMemory, &pBuffer, &length);
if (NT_SUCCESS(status)) { if (length < RequiredLength) { status = STATUS_BUFFER_TOO_SMALL;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "WDFREQUEST 0x%p buffer size %I64d is less than RequiredLength " "%I64d, %!STATUS!", Request, length, RequiredLength, status);
return status; }
*Buffer = pBuffer;
if (Length != NULL) { *Length = length; } }
return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestRetrieveOutputBuffer)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in size_t RequiredLength, __deref_out_bcount(*Length) PVOID* Buffer, __out_opt size_t* Length )/*++
Routine Description:
Return the memory buffer associated with the request along with its maximum length.
The memory buffer is valid in any thread/process context, and may be accessed at IRQL > PASSIVE_LEVEL.
The memory buffer is automatically released when the request is completed.
The memory buffers access permissions are validated according to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may only be accessed according to the access semantics of the request.
The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL, or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are configured for the device object.
The Memory buffer is as follows for each buffering mode:
DO_BUFFERED_IO:
Irp->AssociatedIrp.SystemBuffer
DO_DIRECT_IO:
MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
NEITHER flag set:
NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order to access the request in the calling threads address space before it is placed into any I/O Queues.
The buffer is only valid until the request is completed.
Arguments:
Request - Handle to the Request object
RequiredLength - This is the minimum size expected by the caller
Buffer - Pointer location to return buffer ptr
Length - actual size of the buffer. This is >= to RequiredLength
Returns:
NTSTATUS
--*/{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; IFxMemory* pMemory; PVOID pBuffer; size_t length; UCHAR majorFunction;
pMemory = NULL;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
// // Validate the pointers and set its content to NULL // FxPointerNotNull(pFxDriverGlobals, Buffer); *Buffer = NULL;
if (Length != NULL) { *Length = 0; }
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif //FX_VERBOSE_TRACE
// // This call is not valid on Write request. // majorFunction = pRequest->GetFxIrp()->GetMajorFunction();
if (majorFunction == IRP_MJ_WRITE) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on write request, you should call" " WdfRequestRetrieveInputBuffer to get the buffer for WDFREQUEST " "0x%p, %!STATUS!", Request, status);
return status; }
if (majorFunction == IRP_MJ_DEVICE_CONTROL || majorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { status = pRequest->GetDeviceControlOutputMemoryObject( &pMemory, &pBuffer, &length); } else { status = pRequest->GetMemoryObject(&pMemory, &pBuffer, &length); }
if (NT_SUCCESS(status)) { if (length < RequiredLength) { status = STATUS_BUFFER_TOO_SMALL;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "WDFREQUEST 0x%p buffer size %I64d is less than RequiredLength " "%I64d, %!STATUS!", Request, length, RequiredLength, status);
return status; }
*Buffer = pBuffer;
if (Length != NULL) { *Length = length; } }
return status;}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestRetrieveUnsafeUserInputBuffer)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in size_t RequiredLength, __deref_out_bcount_opt(*Length) PVOID* InputBuffer, __out_opt size_t* Length )/*++
Routine Description:
Returns input buffer of a method-neither request. This function can be called only in the context of EvtDeviceIoInProcessContextCallback at PASSIVE_LEVEL.
This call is valid on public IOCTL and Write request.
The returned buffer is valid only in the caller's process context. This call should be typically used in a toplevel or monolithic driver to guarantee the caller's context.
The Memory buffer is as follows for each type of request:
For IOCTL, it will return irpStack->Parameters.DeviceIoControl.Type3InputBuffer
For Write, it will return Irp->UserBuffer.
For read and internal-device control and other type of request, this call will return an error.
Arguments:
Request - Handle to the Request object
RequiredLength - minimum length of the buffer expected by the caller. If it's not this call will return an error.
InputBuffer - Pointer location to return buffer ptr
Length - actual size of the buffer. This is >= to RequiredLength
Returns:
NTSTATUS
--*/{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; UCHAR majorFunction; FxDevice* pDevice;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
FxPointerNotNull(pFxDriverGlobals, InputBuffer); *InputBuffer = NULL;
if (Length != NULL) { *Length = 0; }
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); if (!NT_SUCCESS(status)) { return status; }
// // Make sure this function is called in the context of in-process callback // if (pFxDriverGlobals->FxVerifierOn) { KIRQL irql;
pRequest->Lock(&irql);
status = pRequest->VerifyRequestIsInCallerContext(pFxDriverGlobals);
pRequest->Unlock(irql);
if (!NT_SUCCESS(status)) { return status; } }
FxIrp* irp = pRequest->GetFxIrp();
pDevice = FxDevice::GetFxDevice(irp->GetDeviceObject());
// // This call is not valid on Read request. // majorFunction = irp->GetMajorFunction();
if (majorFunction == IRP_MJ_READ) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on read request, you should call" " WdfRequestRetrieveUnsafeUserOutputBuffer to get the buffer for " "WDFREQUEST 0x%p, %!STATUS!", Request, status);
return status; }
if (majorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on internal-ioctl request, you should call" " safer WdfRequestRetrieveInputBuffer to get the buffer for " "WDFREQUEST 0x%p, %!STATUS!", Request, status);
return status; }
if (majorFunction == IRP_MJ_DEVICE_CONTROL && irp->GetParameterIoctlCodeBufferMethod() == METHOD_NEITHER) {
if (irp->GetParameterIoctlInputBufferLength() < RequiredLength) { status = STATUS_BUFFER_TOO_SMALL;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "WDFREQUEST %p buffer size %d is less than RequiredLength %I64d," " %!STATUS!", Request, irp->GetParameterIoctlInputBufferLength(), RequiredLength, status);
return status; }
*InputBuffer = irp->GetParameterIoctlType3InputBuffer(); if (Length != NULL) { *Length = irp->GetParameterIoctlInputBufferLength(); }
return STATUS_SUCCESS;
} else if (majorFunction == IRP_MJ_WRITE && pDevice->GetIoType() == WdfDeviceIoNeither) {
if (irp->GetParameterWriteLength() < RequiredLength) { status = STATUS_BUFFER_TOO_SMALL;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "WDFREQUEST 0x%p buffer size %d is less than RequiredLength " "%I64d, %!STATUS!", Request, irp->GetParameterWriteLength(), RequiredLength, status);
return status; }
*InputBuffer = pRequest->GetFxIrp()->GetUserBuffer(); if (Length != NULL) { *Length = irp->GetParameterWriteLength(); }
return STATUS_SUCCESS;
} else { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "Error: This call is valid only on method-neither " "ioctl and write WDFREQUEST %p, %!STATUS!", Request, status); FxVerifierDbgBreakPoint(pFxDriverGlobals);
return status; }
// NOTREACHED}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestRetrieveUnsafeUserOutputBuffer)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in size_t RequiredLength, __deref_out_bcount_opt(*Length) PVOID* OutputBuffer, __out_opt size_t* Length )/*++
Routine Description:
Returns output buffer of a method-neither request. This function can be called only in the context of EvtDeviceIoInProcessContextCallback at PASSIVE_LEVEL.
This call is valid on public IOCTL and Read request.
The returned buffer is valid only in the caller's process context. This call should be typically used in a toplevel or monolithic driver to guarantee the caller's context.
The Memory buffer is as follows for each type of request:
For IOCTL, it will return Irp->UserBuffer
For Read, it will return Irp->UserBuffer.
For Write and internal-device control and other type of request, this call will return an error.
Arguments:
Request - Handle to the Request object
RequiredLength - minimum length of the buffer expected by the caller. If it's not this call will return an error.
OutputBuffer - Pointer location to return buffer ptr
Length - actual size of the buffer. This is >= to RequiredLength
Returns:
NTSTATUS
--*/{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; UCHAR majorFunction; FxDevice* pDevice;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, OutputBuffer); *OutputBuffer = NULL;
if (Length != NULL) { *Length = 0; }
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); if (!NT_SUCCESS(status)) { return status; }
// // Make sure this function is called in the context of in-process callback // if (pFxDriverGlobals->FxVerifierOn) { KIRQL irql;
pRequest->Lock(&irql);
status = pRequest->VerifyRequestIsInCallerContext(pFxDriverGlobals);
pRequest->Unlock(irql);
if (!NT_SUCCESS(status)) { return status; } }
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", pRequest);#endif // FX_VERBOSE_TRACE
FxIrp* irp = pRequest->GetFxIrp(); pDevice = FxDevice::GetFxDevice(irp->GetDeviceObject());
// // This call is not valid on Write request. // majorFunction = irp->GetMajorFunction();
if (majorFunction == IRP_MJ_WRITE) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on Write request, you should call" " WdfRequestRetrieveUnsafeUserInputBuffer to get the buffer for " "WDFREQUEST 0x%p, %!STATUS!", Request, status);
return status;
}
if (majorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on an internal IOCTL request, you should call" " safer WdfRequestRetrieveOutputBuffer to get the buffer for " "WDFREQUEST 0x%p, %!STATUS!", Request, status);
return status; }
if (majorFunction == IRP_MJ_DEVICE_CONTROL && irp->GetParameterIoctlCodeBufferMethod() == METHOD_NEITHER) {
if (irp->GetParameterIoctlOutputBufferLength() < RequiredLength) { status = STATUS_BUFFER_TOO_SMALL;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "WDFREQUEST 0x%p buffer size %d is less than RequiredLength " "%I64d, %!STATUS!", Request, irp->GetParameterIoctlOutputBufferLength(), RequiredLength, status);
return status; }
*OutputBuffer = pRequest->GetFxIrp()->GetUserBuffer();
if (Length != NULL) { *Length = irp->GetParameterIoctlOutputBufferLength(); }
return STATUS_SUCCESS;
} else if (majorFunction == IRP_MJ_READ && pDevice->GetIoType() == WdfDeviceIoNeither) {
if (irp->GetParameterReadLength() < RequiredLength) { status = STATUS_BUFFER_TOO_SMALL;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "WDFREQUEST 0x%p buffer size %d is less than RequiredLength " "%I64d, %!STATUS!", Request, irp->GetParameterReadLength(), RequiredLength, status);
return status; }
*OutputBuffer = pRequest->GetFxIrp()->GetUserBuffer(); if (Length != NULL) { *Length = irp->GetParameterReadLength(); }
return STATUS_SUCCESS;
} else { status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "Error: This call is valid only on method-neither ioctl and read " "WDFREQUEST 0x%p, %!STATUS!", Request, status);
return status; }
// NOTREACHED}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestRetrieveInputWdmMdl)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __deref_out PMDL *Mdl )
/*++
Routine Description:
Return the MDL associated with the request.
The MDL is automatically released when the request is completed.
The MDL's access permissions are validated according to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may only be accessed according to the access semantics of the request.
The MDL is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL, or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are configured for the device object.
The MDL is as follows for each buffering mode:
DO_BUFFERED_IO:
MmBuildMdlForNonPagedPool(IoAllocateMdl(Irp->AssociatedIrp.SystemBuffer, ... ))
DO_DIRECT_IO:
Irp->MdlAddress
NEITHER flag set:
NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order to access the request in the calling threads address space before it is placed into any I/O Queues.
The MDL is only valid until the request is completed.
Arguments:
Request - Handle to the Request object
Mdl - Pointer location to return MDL ptr
Returns:
NTSTATUS
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Mdl); *Mdl = NULL;
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
// // This call is not valid on Read request. // if (pRequest->GetFxIrp()->GetMajorFunction() == IRP_MJ_READ) { DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on the Read request, you should call" " WdfRequestRetrieveOutputMdl to get the Mdl for WFDREQUEST 0x%p, " " %!STATUS!", Request, STATUS_INVALID_DEVICE_REQUEST);
return STATUS_INVALID_DEVICE_REQUEST; }
status = pRequest->GetMdl(Mdl);
return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestRetrieveOutputWdmMdl)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __deref_out PMDL *Mdl )
/*++
Routine Description:
Return the MDL associated with the request.
The MDL is automatically released when the request is completed.
The MDL's access permissions are validated according to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may only be accessed according to the access semantics of the request.
The MDL is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL, or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are configured for the device object.
The MDL is as follows for each buffering mode:
DO_BUFFERED_IO:
MmBuildMdlForNonPagedPool(IoAllocateMdl(Irp->AssociatedIrp.SystemBuffer, ... ))
DO_DIRECT_IO:
Irp->MdlAddress
NEITHER flag set:
NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order to access the request in the calling threads address space before it is placed into any I/O Queues.
The MDL is only valid until the request is completed.
Arguments:
Request - Handle to the Request object
Mdl - Pointer location to return MDL ptr
Returns:
NTSTATUS
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; UCHAR majorFunction;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Mdl); *Mdl = NULL;
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
// // This call is not valid on Write request. // majorFunction = pRequest->GetFxIrp()->GetMajorFunction(); if (majorFunction == IRP_MJ_WRITE) { DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "This call is not valid on the Write request, you should call" " WdfRequestRetrieveInputMemory to get the Memory for WDFREQUEST 0x%p, " "%!STATUS!",Request, STATUS_INVALID_DEVICE_REQUEST);
return STATUS_INVALID_DEVICE_REQUEST; }
if( (majorFunction == IRP_MJ_DEVICE_CONTROL) || (majorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) ) { status = pRequest->GetDeviceControlOutputMdl(Mdl); } else { status = pRequest->GetMdl(Mdl); }
return status;}
voidCheckUnionAssumptions( VOID )/*++
Routine Description: Make sure our assumptions about using the passed in parameters as locals does not exceed the space allocated on the stack for the passed in variables, otherwise we could corrupt the stack.
*DO NOT REMOVE* this function even though no code calls it. Because it uses WDFCASSERT, if our assumptions were false, it would not compile.
Arguments: None.
Return Value: None
--*/{ // ActionUnion check WDFCASSERT(sizeof(ULONG) <= sizeof(PWDF_DRIVER_GLOBALS)); // RequestUnion check WDFCASSERT(sizeof(FxRequest*) <= sizeof(WDFREQUEST)); // TargetUnion check WDFCASSERT(sizeof(FxIoTarget*) <= sizeof(WDFIOTARGET));}
#define GLOBALS_ACTION(globals) ((ULONG)(ULONG_PTR)(globals))#define PGLOBALS_ACTION(globals) ((PULONG)(PULONG_PTR)(globals))
#define GLOBALS_DEVICE(globals) ((FxDevice*)(ULONG_PTR)(globals))#define PGLOBALS_DEVICE(globals) ((FxDevice**)(PULONG_PTR)(globals))
#define WDFREQUEST_FXREQUEST(handle) ((FxRequest*)(handle))#define WDFIOTARGET_FXIOTARGET(handle) ((FxIoTarget*)(handle))
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)BOOLEANNTAPIWDFEXPORT(WdfRequestSend)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in WDFIOTARGET Target, __in_opt PWDF_REQUEST_SEND_OPTIONS Options )/*++
Routine Description: Sends a previously created and formatted request to the target device object. The target device object will typically be the device object that this device is attached to. The submission can also be controlled by a set of options.
Arguments: Request - The request to be submitted
Target - The target of the request
Options - Optional options applied to the sending of the request
In the aggressive attempt to conserve stack space, the passed in parameters are unionized with the locals this function would need. On an optimized build, the compiler may already do this, but we want to be extra aggressive and ensure that this type of stack reuse is done.
Return Value: TRUE if the request was sent to the target, FALSE otherwise.
To retrieve the status of the request, call WdfRequestGetStatus. WdfRequestGetStatus should only be called if WdfRequestSend returns FALSE or if the caller specified that the request be synchronous in WDF_REQUEST_SEND_OPTIONS. Otherwise, the request is asynchronous and the status will be returned in the request's completion routine.
--*/{ // // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*) &Request);
// // Request stack memory now holds an FxRequest pointer. // Request as a handle is no longer valid! // if (!NT_SUCCESS(FxValidateRequestOptions( WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(), Options, WDFREQUEST_FXREQUEST(Request)))) {
WDFREQUEST_FXREQUEST(Request)->SetStatus(STATUS_INVALID_PARAMETER);
FxVerifierDbgBreakPoint(WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals()); return FALSE; }
FxObjectHandleGetPtr(WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(), Target, FX_TYPE_IO_TARGET, (PVOID*) &Target);
// // Target stack memory now hold an FxIoTarget pointer. // Target as a handle is no longer valid! // if (Options != NULL && (Options->Flags & (WDF_REQUEST_SEND_OPTION_SYNCHRONOUS | WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET)) != 0x0) {
if (Options->Flags & WDF_REQUEST_SEND_OPTION_SYNCHRONOUS) { // // This sets impersonation flags for UMDF. Noop for KMDF. // WDFREQUEST_FXREQUEST(Request)->SetImpersonationFlags(Options->Flags);
*PGLOBALS_ACTION(&DriverGlobals) = SubmitSyncCallCompletion; (void) WDFIOTARGET_FXIOTARGET(Target)->SubmitSync( WDFREQUEST_FXREQUEST(Request), Options, PGLOBALS_ACTION(&DriverGlobals) ); } else if (Options->Flags & WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET) { if (WDFREQUEST_FXREQUEST(Request)->IsAllocatedFromIo() == FALSE) { DoTraceLevelMessage( WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "WDFREQUEST %p must be a WDFQUEUE presented request", WDFREQUEST_FXREQUEST(Request)->GetHandle());
WDFREQUEST_FXREQUEST(Request)->SetStatus( STATUS_INVALID_DEVICE_STATE );
*PGLOBALS_ACTION(&DriverGlobals) = 0; } else if (WDFREQUEST_FXREQUEST(Request)->HasContext()) { // // Cannot send-and-forget a request with formatted IO context. // DoTraceLevelMessage( WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Cannot send-and-forget WDFREQUEST 0x%p with formatted IO" " context, %!STATUS!", WDFREQUEST_FXREQUEST(Request)->GetHandle(), STATUS_INVALID_DEVICE_REQUEST );
WDFREQUEST_FXREQUEST(Request)->SetStatus( STATUS_INVALID_DEVICE_REQUEST );
*PGLOBALS_ACTION(&DriverGlobals) = 0;
FxVerifierDbgBreakPoint( WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals()); } else { // // We split processing into pre and post processing to reduce // stack usage (by not making the call to IoCallDriver in a // deep function. //
// // This will skip the current stack location // WDFREQUEST_FXREQUEST(Request)->PreProcessSendAndForget();
// // This sets impersonation flags for UMDF. Noop for KMDF. // WDFREQUEST_FXREQUEST(Request)->SetImpersonationFlags(Options->Flags);
MdIrp submitIrp = WDFREQUEST_FXREQUEST(Request)->GetSubmitIrp();
WDFIOTARGET_FXIOTARGET(Target)->Send(submitIrp);
// // This will free the request memory and pop the queue // WDFREQUEST_FXREQUEST(Request)->PostProcessSendAndForget(); return TRUE; } } } else if (WDFREQUEST_FXREQUEST(Request)->IsCompletionRoutineSet() == FALSE && WDFREQUEST_FXREQUEST(Request)->IsAllocatedFromIo()) { // // Cannot send an asynchronous queue presented request without a // completion routine. // DoTraceLevelMessage( WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "WDFREQUEST %p is a WDFQUEUE presented request with no" " completion routine, %!STATUS!", WDFREQUEST_FXREQUEST(Request)->GetHandle(), STATUS_INVALID_DEVICE_REQUEST );
WDFREQUEST_FXREQUEST(Request)->SetStatus( STATUS_INVALID_DEVICE_REQUEST );
*PGLOBALS_ACTION(&DriverGlobals) = 0;
FxVerifierDbgBreakPoint( WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals()); } else {#if FX_VERBOSE_TRACE DoTraceLevelMessage( WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, "Enter: WDFIOTARGET %p, WDFREQUEST %p", WDFIOTARGET_FXIOTARGET(Target)->GetObjectHandle(), WDFREQUEST_FXREQUEST(Request));#endif // FX_VERBOSE_TRACE
// // This sets impersonation flags for UMDF. Noop for KMDF. // if (Options != NULL) { WDFREQUEST_FXREQUEST(Request)->SetImpersonationFlags(Options->Flags); }
// // Submit will return whether the request should be sent *right now*. // If SubmitSend is clear, then SubmitQueued must be checked. If set, // then the request was queued, otherwise, the request has failed. // // NOTE: by calling FxIoTarget::Submit instead of acquiring the lock // in this call frame, we don't have expend stack space for the KIRQL // storage // *PGLOBALS_ACTION(&DriverGlobals) = WDFIOTARGET_FXIOTARGET(Target)->Submit( WDFREQUEST_FXREQUEST(Request), Options, (Options != NULL) ? Options->Flags : 0 );
// DriverGlobals stack memory now hold a ULONG action value. // DriverGlobals as a pointer is no longer valid!
#if FX_VERBOSE_TRACE DoTraceLevelMessage( WDFIOTARGET_FXIOTARGET(Target)->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, "action 0x%x", GLOBALS_ACTION(DriverGlobals));#endif // FX_VERBOSE_TRACE
if (GLOBALS_ACTION(DriverGlobals) & SubmitSend) {
*PGLOBALS_ACTION(&DriverGlobals) |= SubmitSent;
ASSERT((GLOBALS_ACTION(DriverGlobals) & SubmitQueued) == 0);
#if FX_VERBOSE_TRACE DoTraceLevelMessage( WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, "Sending FxRequest %p (WDFREQUEST %p), Irp %p", WDFREQUEST_FXREQUEST(Request), WDFREQUEST_FXREQUEST(Request)->GetHandle(), WDFREQUEST_FXREQUEST(Request)->GetSubmitIrp());#endif // FX_VERBOSE_TRACE
MdIrp submitIrp = WDFREQUEST_FXREQUEST(Request)->GetSubmitIrp();
WDFIOTARGET_FXIOTARGET(Target)->Send(submitIrp); } else if (GLOBALS_ACTION(DriverGlobals) & SubmitQueued) { // // To the caller, we saw and sent the request (and all the cancel // semantics of a sent request still work). // *(PGLOBALS_ACTION(&DriverGlobals)) |= SubmitSent; } }
return (GLOBALS_ACTION(DriverGlobals) & SubmitSent) ? TRUE : FALSE;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestGetStatus)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request ){ FxRequest* pRequest;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest);
return pRequest->GetStatus();}
__drv_maxIRQL(DISPATCH_LEVEL)BOOLEANWDFAPINTAPIWDFEXPORT(WdfRequestCancelSentRequest)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description: Cancels a previously submitted request.
Arguments: Request - The previously submitted request
Return Value: TRUE if the cancel was *attempted*. The caller must still synchronize with the request's completion routine since TRUE just means the owner of the request was successfully asked to cancel the request.
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest *pRequest; BOOLEAN result;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST %p to be cancelled", Request);
result = pRequest->Cancel();
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Exit: WDFREQUEST %p, result %d", Request, result);#endif // FX_VERBOSE_TRACE
return result;}
_Must_inspect_result___drv_maxIRQL(APC_LEVEL)BOOLEANNTAPIWDFEXPORT(WdfRequestIsFrom32BitProcess)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )/*++
Routine Description: Indicates to the caller if the I/O request originated in a 32 bit process or not. On 32 bit systems, this function always returns TRUE.
Arguments: Request - The request being queried
Return Value: TRUE if the request came from a 32 bit process, FALSE otherwise.
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest* pRequest; BOOLEAN result;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*) &pRequest, &pFxDriverGlobals);
result = pRequest->GetFxIrp()->Is32bitProcess();
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST %p is from 32 bit process = %d", Request, result);#endif // FX_VERBOSE_TRACE
return result;}
__drv_maxIRQL(DISPATCH_LEVEL)
VOIDNTAPIWDFEXPORT(WdfRequestFormatRequestUsingCurrentType)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )/*++
Routine Description: Copies the current Irp stack location to the next one. This is the equivalent of IoCopyCurrentIrpStackLocationToNext.
Arguments: Request - The request that will be formatted.
Return Value: None
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest *pRequest; FxIrp* irp;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST %p", Request);#endif // FX_VERBOSE_TRACE
irp = pRequest->GetSubmitFxIrp();
if (irp->GetIrp() == NULL) { FxVerifierBugCheck(pFxDriverGlobals, WDF_REQUEST_FATAL_ERROR, WDF_REQUEST_FATAL_ERROR_NULL_IRP, (ULONG_PTR) Request); return; // not reached }
// // 1 is the minimum for CurrentLocation. Since the next stack location is // CurrentLocation-1, the CurrentLocation must be at least 2. // if (irp->HasStack(2) == FALSE) { FxVerifierBugCheck(pFxDriverGlobals, WDF_REQUEST_FATAL_ERROR, WDF_REQUEST_FATAL_ERROR_NO_MORE_STACK_LOCATIONS, (ULONG_PTR) irp->GetIrp()); return; // not reached }
pRequest->m_NextStackLocationFormatted = TRUE; irp->CopyCurrentIrpStackLocationToNext();
pRequest->VerifierSetFormatted();}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDWDFAPINTAPIWDFEXPORT(WdfRequestWdmFormatUsingStackLocation)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in PIO_STACK_LOCATION Stack )
/*++
Routine Description: Sets the next IRP stack location to the one provided by the caller. The Context and CompletionRoutine values will be ignored. If the caller wants to set a completion routine, WdfRequestSetCompletionRoutine should be used instead.
Arguments: Request - The request to be formatted
Stack - A pointer to an IO_STACK_LOCATION structure that contains driver-supplied information
Return Value: None.
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest *pRequest; FxIrp* pIrp;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Stack);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST %p", Request);#endif // FX_VERBOSE_TRACE
pIrp = pRequest->GetSubmitFxIrp();
if (pIrp == NULL) { FxVerifierBugCheck(pFxDriverGlobals, WDF_REQUEST_FATAL_ERROR, WDF_REQUEST_FATAL_ERROR_NULL_IRP, (ULONG_PTR) Request); return; // not reached }
// // 1 is the minimum for CurrentLocation. Since the next stack location is // CurrentLocation-1, the CurrentLocation must be at least 2. // if (pIrp->GetCurrentIrpStackLocationIndex() < 2) { FxVerifierBugCheck(pFxDriverGlobals, WDF_REQUEST_FATAL_ERROR, WDF_REQUEST_FATAL_ERROR_NO_MORE_STACK_LOCATIONS, (ULONG_PTR) pIrp); return; // not reached }
pRequest->m_NextStackLocationFormatted = TRUE; pIrp->CopyToNextIrpStackLocation(Stack);
pRequest->VerifierSetFormatted();}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDWDFAPINTAPIWDFEXPORT(WdfRequestSetCompletionRoutine)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine, __in_opt WDFCONTEXT CompletionContext ){ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST %p, Routine %p, Context %p", Request, CompletionRoutine, CompletionContext);#endif // FX_VERBOSE_TRACE
pRequest->SetCompletionRoutine(CompletionRoutine, CompletionContext);
return;}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDWDFAPINTAPIWDFEXPORT(WdfRequestGetParameters)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __out PWDF_REQUEST_PARAMETERS Parameters ){ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Parameters);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: Request %p, Parameters %p", Request, Parameters);#endif // FX_VERBOSE_TRACE
if (Parameters->Size != sizeof(WDF_REQUEST_PARAMETERS)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "Params size %d incorrect, expected %d", Parameters->Size, sizeof(WDF_REQUEST_PARAMETERS));
FxVerifierDbgBreakPoint(pFxDriverGlobals);
return; }
(VOID) pRequest->GetParameters(Parameters);
return;}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDWDFAPINTAPIWDFEXPORT(WdfRequestGetCompletionParams)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __out PWDF_REQUEST_COMPLETION_PARAMS Params ){ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST %p, Params %p", Request, Params);#endif // FX_VERBOSE_TRACE
FxPointerNotNull(pFxDriverGlobals, Params);
if (Params->Size != sizeof(WDF_REQUEST_COMPLETION_PARAMS)) { DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "Params Size 0x%x, expected 0x%x", Params->Size, sizeof(WDF_REQUEST_COMPLETION_PARAMS)); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
pRequest->CopyCompletionParams(Params);
return;
}
__drv_maxIRQL(DISPATCH_LEVEL)MdIrpWDFAPINTAPIWDFEXPORT(WdfRequestWdmGetIrp)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description:
This routine returns the WDM IRP associated with the given request.
The WDM IRP is invalid once WdfRequestComplete is called, regardless of any reference counts on the WDFREQUEST object.
Arguments:
Request - Handle to the Request object
Returns:
PIRP
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; MdIrp irp;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
status = pRequest->GetIrp(&irp);
if (!NT_SUCCESS(status)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "WDFREQUEST is already completed 0x%p, %!STATUS!", Request, status); FxVerifierDbgBreakPoint(pFxDriverGlobals); return NULL; }
return irp;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestAllocateTimer)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )/*++
Routine Description: Preallocates a timer to be associated with the passed in request object. By preallocating the timer, WdfSendRequest cannot fail with insufficient resources when attempting to allocate a timer when a timeout constraint has been passed in.
If the request already has a timer allocated for it, then the function will succeed.
Arguments: Request - the request to allocate a timer for
Return Value: NT_SUCCESS upon success, STATUS_INSUFFICIENT_RESOURCES upon failure
--*/
{ FxRequest* pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest);
return pRequest->CreateTimer();}
__drv_maxIRQL(DISPATCH_LEVEL)WDFFILEOBJECTWDFAPINTAPIWDFEXPORT(WdfRequestGetFileObject)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description:
This routine returns the WDFFILEOBJECT associated with the given request.
Arguments:
Request - Handle to the Request object
Returns:
WDFFILEOBJECT handle.
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; FxFileObject* pFO;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*) &pRequest, &pFxDriverGlobals);
pFO = NULL;
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
if (pRequest->GetDriverGlobals()->IsVerificationEnabled( 1,9, OkForDownLevel)) { KIRQL irql;
pRequest->Lock(&irql); status = pRequest->VerifyRequestIsDriverOwned(pFxDriverGlobals); pRequest->Unlock(irql); if (!NT_SUCCESS(status)) { return NULL; } }
status = pRequest->GetFileObject(&pFO); if (!NT_SUCCESS(status)) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "GetFileobject failed with %!STATUS!", status); return NULL; } else if (NULL == pFO) { // // Success and NULL file object: driver during init told us that it // knows how to handle NULL file objects. // return NULL; }
return pFO->GetHandle();}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestProbeAndLockUserBufferForRead)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in_bcount(Length) PVOID Buffer, __in size_t Length, __out WDFMEMORY* MemoryObject )
/*++
Routine Description:
This routine probes and locks the specified user mode address into an MDL, and associates it with the WDFREQUEST object.
The MDL, and its associated system buffer is represented by a WDFMEMORY object.
The WDFMEMORY object and the MDL is automatically released when the WDFREQUEST is completed by WdfRequestComplete.
Arguments:
Request - Handle to the Request object
Buffer - Buffer to probe and lock into an MDL
Length - Length of buffer
MemoryObject - Location to return WDFMEMORY handle
Returns:
NTSTATUS
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; FxRequestMemory* pMemory;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Buffer); FxPointerNotNull(pFxDriverGlobals, MemoryObject); *MemoryObject = NULL;
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); if (!NT_SUCCESS(status)) { return status; }
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
if (pRequest->GetDriverGlobals()->IsVerificationEnabled( 1,9, OkForDownLevel)) { KIRQL irql;
pRequest->Lock(&irql); status = pRequest->VerifyRequestIsDriverOwned(pFxDriverGlobals); pRequest->Unlock(irql); if (!NT_SUCCESS(status)) { return status; } }
status = pRequest->ProbeAndLockForRead(Buffer, (ULONG) Length, &pMemory);
if (!NT_SUCCESS(status)) { DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "ProbeAndLockForRead failed with %!STATUS!", status); return status; }
*MemoryObject = (WDFMEMORY) pMemory->GetObjectHandle();
return status;}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSWDFAPINTAPIWDFEXPORT(WdfRequestProbeAndLockUserBufferForWrite)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in_bcount(Length) PVOID Buffer, __in size_t Length, __out WDFMEMORY* MemoryObject )
/*++
Routine Description:
This routine probes and locks the specified user mode address into an MDL, and associates it with the WDFREQUEST object.
The MDL, and its associated system buffer is represented by a WDFMEMORY object.
The WDFMEMORY object and the MDL is automatically released when the WDFREQUEST is completed by WdfRequestComplete.
Arguments:
Request - Handle to the Request object
Buffer - Buffer to probe and lock into an MDL
Length - Length of buffer
MemoryObject - Location to return WDFMEMORY handle
Returns:
NTSTATUS
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxRequest *pRequest; FxRequestMemory* pMemory;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Buffer); FxPointerNotNull(pFxDriverGlobals, MemoryObject);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); if (!NT_SUCCESS(status)) { return status; }
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
if (pRequest->GetDriverGlobals()->IsVerificationEnabled( 1,9, OkForDownLevel)) { KIRQL irql;
pRequest->Lock(&irql); status = pRequest->VerifyRequestIsDriverOwned(pFxDriverGlobals); pRequest->Unlock(irql); if (!NT_SUCCESS(status)) { return status; } }
status = pRequest->ProbeAndLockForWrite(Buffer, (ULONG) Length, &pMemory); if (!NT_SUCCESS(status)) { DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "ProbeAndLockForWrite failed with %!STATUS!", status); return status; }
*MemoryObject = (WDFMEMORY)pMemory->GetObjectHandle();
return status;}
__drv_maxIRQL(DISPATCH_LEVEL)KPROCESSOR_MODEWDFAPINTAPIWDFEXPORT(WdfRequestGetRequestorMode)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description:
Returns the RequestorMode information from the IRP.
Arguments:
Request - Handle to the Request object
Returns:
KPROCESSOR_MODE is CCHAR
--*/
{ FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest);
return pRequest->GetRequestorMode();}
__drv_maxIRQL(DISPATCH_LEVEL)WDFQUEUEWDFAPINTAPIWDFEXPORT(WdfRequestGetIoQueue)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description:
Returns the queue handle that currently owns the request.
Arguments:
Request - Handle to the Request object
Returns:
WDFQUEUE
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest *pRequest;
// // Validate the request handle, and get the FxRequest* // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
if (pRequest->GetCurrentQueue() == NULL) { // // For a driver-created request, the queue can be NULL. It is not // necessarily an error to call WdfRequestGetIoQueue on a driver- // created request, because the caller may not really know whether or // not the request is driver-created. // // For example, it is possible for a class extension to create a request // and pass it to the client driver, in which case the client driver // wouldn't really know whether or not it was driver-created. Or a // client driver is might be using a helper library for some of its // tasks and it might pass in a request object to the helper library. In // this case, the helper library wouldn't really know whether or not the // request was driver-created. Therefore, the log message below is at // verbose level and not at error or warning level. // DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "WDFREQUEST %p doesn't belong to any queue", Request); return NULL; }
if (pRequest->GetFxIrp()->GetMajorFunction() == IRP_MJ_CREATE) { // // If the queue for Create is the framework internal queue // return NULL. // FxPkgGeneral* devicePkgGeneral = pRequest->GetDevice()->m_PkgGeneral;
if (devicePkgGeneral->GetDeafultInternalCreateQueue() == pRequest->GetCurrentQueue()) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, "Getting queue handle for Create request is " "not allowed for WDFREQUEST 0x%p", pRequest); FxVerifierDbgBreakPoint(pFxDriverGlobals); return NULL; } }
return (WDFQUEUE) pRequest->GetCurrentQueue()->GetObjectHandle();}
_Must_inspect_result_NTSTATUSFX_VF_FUNCTION(VerifyWdfRequestForwardToIoQueue) ( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest* request ){ NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE_LOCKED();
// // * Is request I/O allocated but without a queue? This should not happen. // * Is WDF driver v1.9 or below trying to use this feature? We don't allow it. // if (request->IsAllocatedDriver() == FALSE || FxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,11) == FALSE) { status = STATUS_INVALID_DEVICE_REQUEST; DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "WDFREQUEST %p doesn't belong to any queue, %!STATUS!", request->GetHandle(), status); FxVerifierDbgBreakPoint(FxDriverGlobals); return status; }
// // Make sure current IRP stack location is valid. See helper routine for error msgs. // status = request->VerifyRequestCanBeCompleted(FxDriverGlobals); return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestForwardToIoQueue)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in WDFQUEUE DestinationQueue )
/*++
Routine Description:
Forward a request presented on one queue to another driver managed queue.
A request may only be forwarded from a queues dispatch routine.
If the request is successfully forwarded to the DestinationQueue, it is no longer owned by the driver, but by the DestinationQueue.
Both the source queue and destination queue should be part of the same device.
The driver gets ownership of the request when it receives it from the DestinationQueue through EvtIo callback, or WdfIoQueueRetrieveNextRequest.
Arguments:
Request - Request object to forward.
DestinationQueue - Queue that is to receive the request.
Returns:
STATUS_SUCCESS - Request was forwarded to Queue and driver no longer owns it.
!STATUS_SUCCESS - Request was not forwarded to the Queue, and the driver still owns the request and is responsible for either completing it, or eventually successfully forwarding it to a Queue.--*/
{ PFX_DRIVER_GLOBALS fxDriverGlobals; PFX_DRIVER_GLOBALS cxDriverGlobals; FxRequest* request; FxIoQueue* queue; NTSTATUS status;
cxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
// // Validate destination queue handle // FxObjectHandleGetPtrAndGlobals(cxDriverGlobals, DestinationQueue, FX_TYPE_QUEUE, (PVOID*)&queue, &fxDriverGlobals);
// // Validate request object handle // FxObjectHandleGetPtr(fxDriverGlobals, Request, FX_TYPE_REQUEST, (PVOID*)&request);
// // If present, let the queue do the heavy lifting. // if (request->GetCurrentQueue() != NULL) { status = request->GetCurrentQueue()->ForwardRequest(queue, request); goto Done; }
// // Basic verification. // status = VerifyWdfRequestForwardToIoQueue(fxDriverGlobals, request); if (!NT_SUCCESS(status)) { goto Done; }
// // OK, queue this request. // status = queue->QueueDriverCreatedRequest(request, FALSE);
Done: return status;}
_Must_inspect_result_NTSTATUSFX_VF_FUNCTION(VerifyWdfRequestForwardToParentDeviceIoQueue) ( _In_ PFX_DRIVER_GLOBALS fxDriverGlobals, _In_ FxRequest* request ){ NTSTATUS status; FxIrp* irp;
PAGED_CODE_LOCKED();
// // * Is request I/O allocated but without a queue? This should not happen. // * Is WDF driver v1.9 or below trying to use this feature? We don't allow it. // if (request->IsAllocatedDriver() == FALSE || fxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,11) == FALSE) { status = STATUS_INVALID_DEVICE_REQUEST; DoTraceLevelMessage(fxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "WDFREQUEST %p doesn't belong to any queue, %!STATUS!", request->GetHandle(), status); FxVerifierDbgBreakPoint(fxDriverGlobals); goto Done; }
// // Make sure current IRP stack location is valid. // status = request->VerifyRequestCanBeCompleted(fxDriverGlobals); if (!NT_SUCCESS(status)) { goto Done; }
// // Make sure IRP has space for at least another stack location. // irp = request->GetFxIrp();
ASSERT(irp->GetIrp() != NULL);
if (irp->GetCurrentIrpStackLocationIndex() <= 1) { status = STATUS_INVALID_DEVICE_REQUEST; DoTraceLevelMessage(fxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "IRP %p of WDFREQUEST %p doesn't enough stack " "locations, %!STATUS!", irp, request->GetHandle(), status); FxVerifierDbgBreakPoint(fxDriverGlobals); goto Done; }
Done: return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestForwardToParentDeviceIoQueue)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in WDFQUEUE ParentDeviceQueue, __in PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions )
/*++
Routine Description:
Forward a request presented on one queue to parent Device queue.
A request may only be forwarded from a queues dispatch routine.
If the request is successfully forwarded to the ParentDeviceQueue, it is no longer owned by the driver, but by the ParentDeviceQueue.
The driver gets ownership of the request when it receives it from the DestinationQueue through EvtIo callback, or WdfIoQueueRetrieveNextRequest.
Arguments:
Request - Request object to forward.
ParentDeviceQueue - Queue that is to receive the request.
ForwardOptions - A pointer to a caller-allocated WDF_REQUEST_FORWARD_OPTIONS structure
Returns:
STATUS_SUCCESS - Request was forwarded to Queue and driver no longer owns it.
!STATUS_SUCCESS - Request was not forwarded to the Queue, and the driver still owns the request and is responsible for either completing it, or eventually successfully forwarding it to a Queue.--*/
{ PFX_DRIVER_GLOBALS fxDriverGlobals; NTSTATUS status; FxRequest* request; FxIoQueue* queue;
// // Validate destination queue handle // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), ParentDeviceQueue, FX_TYPE_QUEUE, (PVOID*)&queue, &fxDriverGlobals);
// // Validate request object handle // FxObjectHandleGetPtr(fxDriverGlobals, Request, FX_TYPE_REQUEST, (PVOID*)&request); FxPointerNotNull(fxDriverGlobals, ForwardOptions);
if (ForwardOptions->Size != sizeof(WDF_REQUEST_FORWARD_OPTIONS)) { // // Size is wrong, bale out // status = STATUS_INFO_LENGTH_MISMATCH; DoTraceLevelMessage(fxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, "ForwardOptions %p Size incorrect, expected %d, " "got %d, %!STATUS!", ForwardOptions, sizeof(WDF_REQUEST_FORWARD_OPTIONS), ForwardOptions->Size, status);
goto Done; }
if ((ForwardOptions->Flags & ~WDF_REQUEST_FORWARD_OPTION_SEND_AND_FORGET) != 0) { // // Invalid flag // status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage(fxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, "ForwardOptions %p Flags 0x%x invalid, " "valid mask is 0x%x, %!STATUS!", ForwardOptions, ForwardOptions->Flags, WDF_REQUEST_FORWARD_OPTION_SEND_AND_FORGET, status);
goto Done; }
// // If present, let the queue do the heavy lifting. // if (request->GetCurrentQueue() != NULL) { status = request->GetCurrentQueue()->ForwardRequestToParent( queue, request, ForwardOptions); goto Done; }
// // Basic verification. // status = VerifyWdfRequestForwardToParentDeviceIoQueue(fxDriverGlobals, request); if (!NT_SUCCESS(status)) { goto Done; }
// // OK, queue this request. // status = queue->QueueDriverCreatedRequest(request, TRUE);
Done: return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestRequeue)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description:
Requeue the request - only allowed if the queue is a manual queue.
Arguments:
Request - Request to requeue
Returns:
NTSTATUS
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest* pRequest;
// // Validate request object handle // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
// // GetCurrentQueue may return NULL if the request is driver created request // or the if the call is made in the context of InProcessContextCallback. // if (pRequest->GetCurrentQueue() == NULL) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "WDFREQUEST %p doesn't belong to any queue %!STATUS!", Request, STATUS_INVALID_DEVICE_REQUEST); FxVerifierDbgBreakPoint(pFxDriverGlobals); return STATUS_INVALID_DEVICE_REQUEST; }
return pRequest->GetCurrentQueue()->Requeue(pRequest);}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDNTAPIWDFEXPORT(WdfRequestMarkCancelable)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in PFN_WDF_REQUEST_CANCEL EvtRequestCancel )
/*++
Routine Description:
Mark the specified request as cancelable
Arguments:
Request - Request to mark as cancelable.
EvtRequestCancel - cancel routine to be invoked when the request is cancelled.
Returns:
None
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest* pRequest; NTSTATUS status;
// // Validate request object handle // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, EvtRequestCancel);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
if (pRequest->GetCurrentQueue() == NULL) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "WDFREQUEST %p doesn't belong to any queue", Request); FxVerifierDbgBreakPoint(pFxDriverGlobals); return; }
status = pRequest->GetCurrentQueue()->RequestCancelable(pRequest, TRUE, EvtRequestCancel, FALSE); UNREFERENCED_PARAMETER(status); //for fre build ASSERT(status == STATUS_SUCCESS);
}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestMarkCancelableEx)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in PFN_WDF_REQUEST_CANCEL EvtRequestCancel )
/*++
Routine Description:
Mark the specified request as cancelable. Do not call the specified cancel routine if IRP is already cancelled but instead return STATUS_CANCELLED. Caller is responsible for completing the request with STATUS_CANCELLED.
Arguments:
Request - Request to mark as cancelable.
EvtRequestCancel - cancel routine to be invoked when the request is cancelled.
Returns:
STATUS_SUCCESS - The request has been marked cancelable. STATUS_CANCELLED - The IRP is already cancelled. NTSTATUS - Other values are possible when verifier is enabled.
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest* pRequest; NTSTATUS status;
// // Validate request object handle // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, EvtRequestCancel);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
if (pRequest->GetCurrentQueue() == NULL) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "WDFREQUEST %p doesn't belong to any queue %!STATUS!", Request, STATUS_INVALID_DEVICE_REQUEST); FxVerifierDbgBreakPoint(pFxDriverGlobals); return STATUS_INVALID_DEVICE_REQUEST; }
status = pRequest->GetCurrentQueue()->RequestCancelable(pRequest, TRUE, EvtRequestCancel, TRUE);
ASSERT(status == STATUS_SUCCESS || status == STATUS_CANCELLED); return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfRequestUnmarkCancelable)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description:
Unmark the specified request as cancelable
Arguments:
Request - Request to unmark as cancelable.
Returns:
NTSTATUS
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest* pRequest;
// // Validate request object handle // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
if (pRequest->GetCurrentQueue() == NULL) { DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "WDFREQUEST %p doesn't belong to any queue %!STATUS!", Request, STATUS_INVALID_DEVICE_REQUEST); FxVerifierDbgBreakPoint(pFxDriverGlobals); return STATUS_INVALID_DEVICE_REQUEST; }
return pRequest->GetCurrentQueue()->RequestCancelable(pRequest, FALSE, NULL, FALSE);}
_Must_inspect_result_NTSTATUSFX_VF_FUNCTION(VerifyWdfRequestIsCanceled)( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest* pRequest ){ NTSTATUS status; KIRQL irql;
PAGED_CODE_LOCKED();
pRequest->Lock(&irql);
status = pRequest->VerifyRequestIsDriverOwned(FxDriverGlobals); if (NT_SUCCESS(status)) { status = pRequest->VerifyRequestIsNotCancelable(FxDriverGlobals); }
pRequest->Unlock(irql); return status;}
_Must_inspect_result___drv_maxIRQL(DISPATCH_LEVEL)BOOLEANNTAPIWDFEXPORT(WdfRequestIsCanceled)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )
/*++
Routine Description:
Check to see if the request is cancelled by the I/O manager. This call is valid only on a driver owned non-cancelable request.
Arguments:
Request - Request being checked.
Returns:
BOOLEAN
--*/
{ PFX_DRIVER_GLOBALS pFxDriverGlobals; FxRequest* pRequest; NTSTATUS status;
// // Validate request object handle // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals); status = VerifyWdfRequestIsCanceled(pRequest->GetDriverGlobals(), pRequest); if (!NT_SUCCESS(status)) { return FALSE; }
return pRequest->IsCancelled();}
__drv_maxIRQL(DISPATCH_LEVEL)VOIDNTAPIWDFEXPORT(WdfRequestStopAcknowledge)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request, __in BOOLEAN Requeue )
/*++
Routine Description:
The driver calls this to acknowledge that it is no longer attempting to perform I/O on the request which was provided in the EvtIoStop event callback notification.
The device driver must arrange to no longer touch any hardware resources before making this call.
Arguments:
Request - Request being stopped
Requeue - True if the request is to be placed back on the front of the queue, and re-delivered to the device driver on resume.
Returns:
None
--*/
{ FxRequest* pRequest; PFX_DRIVER_GLOBALS pFxDriverGlobals;
// // Validate request object handle // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
#if FX_VERBOSE_TRACE DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST, "Enter: WDFREQUEST 0x%p", Request);#endif // FX_VERBOSE_TRACE
pRequest->StopAcknowledge(Requeue);}
__drv_maxIRQL(DISPATCH_LEVEL)BOOLEANNTAPIWDFEXPORT(WdfRequestIsReserved)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFREQUEST Request )/*++
Routine Description: This is used to determine if a Request is a reserved request. Reserved Requests are used for forward progress.
Arguments:
Request - Request being checked
Returns:
BOOLEAN
--*/
{ FxRequest* pRequest; PFX_DRIVER_GLOBALS pFxDriverGlobals;
// // Validate request object handle // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST, (PVOID*)&pRequest, &pFxDriverGlobals);
return pRequest->IsReserved();}
} // extern "C" the whole file