Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676/* * ReactOS kernel * Copyright (C) 2005 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *//* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: base/services/umpnpmgr/rpcserver.c * PURPOSE: RPC server * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org) * Hervé Poussineau (hpoussin@reactos.org) * Colin Finck (colin@reactos.org) */
/* INCLUDES *****************************************************************/
#include "precomp.h"
#define NDEBUG#include <debug.h>
/* GLOBALS ******************************************************************/
static WCHAR szRootDeviceInstanceID[] = L"HTREE\\ROOT\\0";LUID LoadDriverPrivilege = {SE_LOAD_DRIVER_PRIVILEGE, 0};
LIST_ENTRY NotificationListHead;RTL_RESOURCE NotificationListLock;
/* FUNCTIONS *****************************************************************/
DWORD WINAPIRpcServerThread(LPVOID lpParameter){ RPC_STATUS Status; BOOLEAN RegisteredProtSeq = FALSE;
UNREFERENCED_PARAMETER(lpParameter);
DPRINT("RpcServerThread() called\n");
InitializeListHead(&NotificationListHead); RtlInitializeResource(&NotificationListLock);
#if 0 /* 2k/XP/2k3-compatible protocol sequence/endpoint */ Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\ntsvcs", NULL); // Security descriptor if (Status == RPC_S_OK) RegisteredProtSeq = TRUE; else DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);#endif
/* Vista/7-compatible protocol sequence/endpoint */ Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\plugplay", NULL); // Security descriptor if (Status == RPC_S_OK) RegisteredProtSeq = TRUE; else DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
/* Make sure there's a usable endpoint */ if (RegisteredProtSeq == FALSE) return 0;
Status = RpcServerRegisterIf(pnp_v1_0_s_ifspec, NULL, NULL); if (Status != RPC_S_OK) { DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status); return 0; }
Status = RpcServerListen(1, 20, FALSE); if (Status != RPC_S_OK) { DPRINT1("RpcServerListen() failed (Status %lx)\n", Status); return 0; }
/* ROS HACK (this should never happen...) */ DPRINT1("*** Other devices won't be installed correctly. If something\n"); DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
DPRINT("RpcServerThread() done\n");
return 0;}
void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len){ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);}
void __RPC_USER midl_user_free(void __RPC_FAR * ptr){ HeapFree(GetProcessHeap(), 0, ptr);}
static CONFIGRET WINAPINtStatusToCrError(NTSTATUS Status){ switch (Status) { case STATUS_NOT_IMPLEMENTED: return CR_CALL_NOT_IMPLEMENTED;
case STATUS_INVALID_PARAMETER: return CR_INVALID_DATA;
case STATUS_NO_SUCH_DEVICE: return CR_NO_SUCH_DEVINST;
case STATUS_ACCESS_DENIED: return CR_ACCESS_DENIED;
case STATUS_BUFFER_TOO_SMALL: return CR_BUFFER_SMALL;
case STATUS_OBJECT_NAME_NOT_FOUND: return CR_NO_SUCH_VALUE;
default: return CR_FAILURE; }}
static VOIDSplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID, OUT LPWSTR pszEnumerator, OUT LPWSTR pszDevice, OUT LPWSTR pszInstance){ WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN]; LPWSTR lpEnumerator = NULL; LPWSTR lpDevice = NULL; LPWSTR lpInstance = NULL; LPWSTR ptr;
wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID);
*pszEnumerator = 0; *pszDevice = 0; *pszInstance = 0;
lpEnumerator = szLocalDeviceInstanceID;
ptr = wcschr(lpEnumerator, L'\\'); if (ptr != NULL) { *ptr = 0; lpDevice = ++ptr;
ptr = wcschr(lpDevice, L'\\'); if (ptr != NULL) { *ptr = 0; lpInstance = ++ptr; } }
if (lpEnumerator != NULL) wcscpy(pszEnumerator, lpEnumerator);
if (lpDevice != NULL) wcscpy(pszDevice, lpDevice);
if (lpInstance != NULL) wcscpy(pszInstance, lpInstance);}
staticCONFIGRETClearDeviceStatus( _In_ LPWSTR pszDeviceID, _In_ DWORD ulStatus, _In_ DWORD ulProblem){ PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
DPRINT1("ClearDeviceStatus(%S 0x%lx 0x%lx)\n", pszDeviceID, ulStatus, ulProblem);
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID); PlugPlayData.Operation = PNP_CLEAR_DEVICE_STATUS; PlugPlayData.DeviceStatus = ulStatus; PlugPlayData.DeviceProblem = ulProblem;
Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_STATUS_DATA)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status);
return ret;}
staticCONFIGRETGetDeviceStatus( _In_ LPWSTR pszDeviceID, _Out_ DWORD *pulStatus, _Out_ DWORD *pulProblem){ PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
DPRINT("GetDeviceStatus(%S %p %p)\n", pszDeviceID, pulStatus, pulProblem);
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID); PlugPlayData.Operation = PNP_GET_DEVICE_STATUS;
Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_STATUS_DATA)); if (NT_SUCCESS(Status)) { *pulStatus = PlugPlayData.DeviceStatus; *pulProblem = PlugPlayData.DeviceProblem; } else { ret = NtStatusToCrError(Status); }
return ret;}
staticCONFIGRETSetDeviceStatus( _In_ LPWSTR pszDeviceID, _In_ DWORD ulStatus, _In_ DWORD ulProblem){ PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
DPRINT1("SetDeviceStatus(%S 0x%lx 0x%lx)\n", pszDeviceID, ulStatus, ulProblem);
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID); PlugPlayData.Operation = PNP_SET_DEVICE_STATUS; PlugPlayData.DeviceStatus = ulStatus; PlugPlayData.DeviceProblem = ulProblem;
Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_STATUS_DATA)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status);
return ret;}
staticCONFIGRETDisableDeviceInstance( _In_ LPWSTR pszDeviceInstance, _Inout_opt_ PPNP_VETO_TYPE pVetoType, _Inout_opt_ LPWSTR pszVetoName, _In_ DWORD ulNameLength){ PLUGPLAY_CONTROL_QUERY_REMOVE_DATA QueryRemoveData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
DPRINT1("DisableDeviceInstance(%S %p %p %lu)\n", pszDeviceInstance, pVetoType, pszVetoName, ulNameLength);
RtlInitUnicodeString(&QueryRemoveData.DeviceInstance, pszDeviceInstance);
QueryRemoveData.Flags = 0; QueryRemoveData.VetoType = 0; QueryRemoveData.VetoName = pszVetoName; QueryRemoveData.NameLength = ulNameLength;
Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice, &QueryRemoveData, sizeof(PLUGPLAY_CONTROL_QUERY_REMOVE_DATA)); if (Status == STATUS_NO_SUCH_DEVICE) { ret = CR_INVALID_DEVNODE; } else if (Status == STATUS_PLUGPLAY_QUERY_VETOED) { if (pVetoType != NULL) *pVetoType = QueryRemoveData.VetoType;
ret = CR_REMOVE_VETOED; } else if (!NT_SUCCESS(Status)) { ret = NtStatusToCrError(Status); }
return ret;}
staticBOOLIsValidDeviceInstanceID( _In_ PWSTR pszDeviceInstanceID){ INT nPartLength[3] = {0, 0, 0}; INT nLength = 0, nParts = 0; PWCHAR p;
DPRINT("IsValidDeviceInstanceID(%S)\n", pszDeviceInstanceID);
if (pszDeviceInstanceID == NULL) { DPRINT("Device instance ID is NULL!\n"); return FALSE; }
p = pszDeviceInstanceID; while (*p != UNICODE_NULL) { if (*p == L'\\') { nParts++; if (nParts >= 3) { DPRINT("Too many separators: %d\n", nParts); return FALSE; } } else { nPartLength[nParts]++; }
nLength++; if (nLength >= MAX_DEVICE_ID_LEN) { DPRINT("Too long: %d\n", nLength); return FALSE; }
p++; }
if (nParts != 2) { DPRINT("Invalid number of separtors: %d\n", nParts); return FALSE; }
if ((nPartLength[0] == 0) || (nPartLength[1] == 0) || (nPartLength[2] == 0)) { DPRINT("Invalid part lengths: %d %d %d\n", nPartLength[0], nPartLength[1], nPartLength[2]); return FALSE; }
DPRINT("Valid device instance ID!\n");
return TRUE;}
staticBOOLIsRootDeviceInstanceID( _In_ PWSTR pszDeviceInstanceID){ if (_wcsicmp(pszDeviceInstanceID, szRootDeviceInstanceID) == 0) return TRUE;
return FALSE;}
staticBOOLIsPresentDeviceInstanceID( _In_ LPWSTR pszDeviceInstanceID){ DWORD ulStatus, ulProblem;
return (GetDeviceStatus(pszDeviceInstanceID, &ulStatus, &ulProblem) == CR_SUCCESS);}
staticCONFIGRETOpenConfigurationKey( _In_ LPCWSTR pszDeviceID, _In_ DWORD ulLogConfType, _Out_ PHKEY phKey){ WCHAR szKeyName[MAX_PATH]; PCWSTR pszSubKeyName; HKEY hInstanceKey; DWORD dwError;
/* Build the full device instance key name */ wcscpy(szKeyName, L"System\\CurrentControlSet\\Enum\\"); wcscat(szKeyName, pszDeviceID);
/* Open the device instance key */ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY, &hInstanceKey); if (dwError != ERROR_SUCCESS) return CR_INVALID_DEVINST;
switch (ulLogConfType) { case BOOT_LOG_CONF: case BASIC_LOG_CONF: pszSubKeyName = L"LogConf"; break;
case ALLOC_LOG_CONF: case FILTERED_LOG_CONF: pszSubKeyName = L"Control"; break;
default: DPRINT1("Unsupported configuration type!\n"); return CR_FAILURE; }
/* Create or open the LogConf key */ dwError = RegCreateKeyExW(hInstanceKey, pszSubKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, phKey, NULL);
/* Close the device instance key */ RegCloseKey(hInstanceKey);
if (dwError != ERROR_SUCCESS) return CR_REGISTRY_ERROR;
return CR_SUCCESS;}
staticCONFIGRETGetConfigurationData( _In_ HKEY hKey, _In_ ULONG ulLogConfType, _Out_ PULONG pulRegDataType, _Out_ PULONG pulDataSize, _Out_ LPBYTE *ppBuffer, _In_ ULONG ulValueNameBufferSize, _Out_opt_ LPWSTR pszValueNameBuffer){ LPCWSTR pszValueName;
switch (ulLogConfType) { case BOOT_LOG_CONF: pszValueName = L"BootConfig"; *pulRegDataType = REG_RESOURCE_LIST; break;
case ALLOC_LOG_CONF: pszValueName = L"AllocConfig"; *pulRegDataType = REG_RESOURCE_LIST; break;
case FORCED_LOG_CONF: pszValueName = L"ForcedConfig"; *pulRegDataType = REG_RESOURCE_LIST; break;
case FILTERED_LOG_CONF: pszValueName = L"FilteredConfigVector"; *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST; break;
case BASIC_LOG_CONF: pszValueName = L"BasicConfigVector"; *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST; break;
case OVERRIDE_LOG_CONF: pszValueName = L"OverrideConfigVector"; *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST; break;
default: DPRINT1("Unsupported configuration type!\n"); return CR_FAILURE; }
/* Return the selected configuration value name */ if ((ulValueNameBufferSize > 0) && (pszValueNameBuffer != NULL) && (wcslen(pszValueName) + 1 <= ulValueNameBufferSize)) wcscpy(pszValueNameBuffer, pszValueName);
/* Get the configuration data size */ if (RegQueryValueExW(hKey, pszValueName, NULL, NULL, NULL, pulDataSize) != ERROR_SUCCESS) { return CR_INVALID_LOG_CONF; }
/* Allocate the buffer */ *ppBuffer = HeapAlloc(GetProcessHeap(), 0, *pulDataSize); if (*ppBuffer == NULL) { return CR_OUT_OF_MEMORY; }
/* Retrieve the configuration data */ if (RegQueryValueExW(hKey, pszValueName, NULL, NULL, (LPBYTE)*ppBuffer, pulDataSize) != ERROR_SUCCESS) { return CR_INVALID_LOG_CONF; }
return CR_SUCCESS;}
staticPCM_FULL_RESOURCE_DESCRIPTORNextResourceDescriptor( _In_ PCM_FULL_RESOURCE_DESCRIPTOR pDescriptor){ PBYTE pNext = NULL; ULONG ulLastIndex = 0;
if (pDescriptor == NULL) return NULL;
/* Skip the full resource descriptor */ pNext = (LPBYTE)pDescriptor + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
/* Skip the partial resource descriptors */ pNext += (pDescriptor->PartialResourceList.Count - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
/* Skip the device specific data, if present */ if (pDescriptor->PartialResourceList.Count > 0) { ulLastIndex = pDescriptor->PartialResourceList.Count - 1;
if (pDescriptor->PartialResourceList.PartialDescriptors[ulLastIndex].Type == CmResourceTypeDeviceSpecific) { pNext += pDescriptor->PartialResourceList.PartialDescriptors[ulLastIndex]. u.DeviceSpecificData.DataSize; } }
return (PCM_FULL_RESOURCE_DESCRIPTOR)pNext;}
staticPIO_RESOURCE_LISTNextResourceRequirement( _In_ PIO_RESOURCE_LIST pResourceList){ LPBYTE pNext = NULL;
if (pResourceList == NULL) return NULL;
/* Skip the resource list */ pNext = (LPBYTE)pResourceList + sizeof(IO_RESOURCE_LIST);
/* Skip the resource descriptors */ pNext += (pResourceList->Count - 1) * sizeof(IO_RESOURCE_DESCRIPTOR);
return (PIO_RESOURCE_LIST)pNext;}
staticBOOLIsCallerInteractive( _In_ handle_t hBinding){ SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; HANDLE hToken; PSID pInteractiveSid = NULL; BOOL bInteractive = FALSE; RPC_STATUS RpcStatus;
DPRINT("IsCallerInteractive(%p)\n", hBinding);
/* Allocate an interactive user sid */ if (!AllocateAndInitializeSid(&NtAuthority, 1, SECURITY_INTERACTIVE_RID, 0, 0, 0, 0, 0, 0, 0, &pInteractiveSid)) { DPRINT1("AllocateAndInitializeSid failed\n"); return FALSE; }
/* Impersonate the client */ RpcStatus = RpcImpersonateClient(hBinding); if (RpcStatus != RPC_S_OK) { DPRINT1("RpcImpersonateClient failed (Status 0x%08lx)\n", RpcStatus); goto done; }
/* Open the thread token and check for interactive user membership */ if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)) { CheckTokenMembership(hToken, pInteractiveSid, &bInteractive); CloseHandle(hToken); }
/* Revert the impersonation */ RpcRevertToSelf();
done: if (pInteractiveSid) FreeSid(pInteractiveSid);
return bInteractive;}
VOID__RPC_USERPNP_NOTIFY_HANDLE_rundown( PNP_NOTIFY_HANDLE pHandle){ DPRINT1("PNP_NOTIFY_HANDLE_rundown(%p)\n", pHandle);}
/* PUBLIC FUNCTIONS **********************************************************/
/* Function 0 */DWORDWINAPIPNP_Disconnect( handle_t hBinding){ UNREFERENCED_PARAMETER(hBinding); return CR_SUCCESS;}
/* Function 1 */DWORDWINAPIPNP_Connect( handle_t hBinding){ UNREFERENCED_PARAMETER(hBinding); return CR_SUCCESS;}
/* Function 2 */DWORDWINAPIPNP_GetVersion( handle_t hBinding, WORD *pVersion){ UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetVersion(%p %p)\n", hBinding, pVersion);
*pVersion = CONFIGMG_VERSION;
return CR_SUCCESS;}
/* Function 3 */DWORDWINAPIPNP_GetGlobalState( handle_t hBinding, DWORD *pulState, DWORD ulFlags){ UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetGlobalState(%p %p 0x%08lx)\n", hBinding, pulState, ulFlags);
if (ulFlags != 0) return CR_INVALID_FLAG;
*pulState = CM_GLOBAL_STATE_CAN_DO_UI | CM_GLOBAL_STATE_SERVICES_AVAILABLE;
if (g_ShuttingDown) *pulState |= CM_GLOBAL_STATE_SHUTTING_DOWN;
return CR_SUCCESS;}
/* Function 4 */DWORDWINAPIPNP_InitDetection( handle_t hBinding){ UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_InitDetection(%p)\n", hBinding);
return CR_SUCCESS;}
/* Function 5 */DWORDWINAPIPNP_ReportLogOn( handle_t hBinding, BOOL Admin, DWORD ProcessId){ DWORD ReturnValue = CR_FAILURE; HANDLE hProcess = NULL;
UNREFERENCED_PARAMETER(Admin);
DPRINT("PNP_ReportLogOn(%p %u, %u)\n", hBinding, Admin, ProcessId);
/* Fail, if the caller is not an interactive user */ if ((g_IsLiveMedium == FALSE) && (IsCallerInteractive(hBinding) == FALSE)) goto cleanup;
/* Get the users token */ hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcessId);
if (!hProcess) { DPRINT1("OpenProcess failed with error %u\n", GetLastError()); goto cleanup; }
if (hUserToken) { CloseHandle(hUserToken); hUserToken = NULL; }
if (!OpenProcessToken(hProcess, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY, &hUserToken)) { DPRINT1("OpenProcessToken failed with error %u\n", GetLastError()); goto cleanup; }
/* Trigger the installer thread */ if (hInstallEvent) SetEvent(hInstallEvent);
ReturnValue = CR_SUCCESS;
cleanup: if (hProcess) CloseHandle(hProcess);
return ReturnValue;}
/* Function 6 */DWORDWINAPIPNP_ValidateDeviceInstance( handle_t hBinding, LPWSTR pDeviceID, DWORD ulFlags){ CONFIGRET ret = CR_SUCCESS; HKEY hDeviceKey = NULL;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_ValidateDeviceInstance(%p %S 0x%08lx)\n", hBinding, pDeviceID, ulFlags);
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
if (RegOpenKeyExW(hEnumKey, pDeviceID, 0, KEY_READ, &hDeviceKey)) { DPRINT("Could not open the Device Key!\n"); ret = CR_NO_SUCH_DEVNODE; goto Done; }
/* FIXME: add more tests */
Done: if (hDeviceKey != NULL) RegCloseKey(hDeviceKey);
DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret);
return ret;}
/* Function 7 */DWORDWINAPIPNP_GetRootDeviceInstance( handle_t hBinding, LPWSTR pDeviceID, PNP_RPC_STRING_LEN ulLength){ CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetRootDeviceInstance(%p %S %lu)\n", hBinding, pDeviceID, ulLength);
if (!pDeviceID) { ret = CR_INVALID_POINTER; goto Done; }
if (ulLength < lstrlenW(szRootDeviceInstanceID) + 1) { ret = CR_BUFFER_SMALL; goto Done; }
lstrcpyW(pDeviceID, szRootDeviceInstanceID);
Done: DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret);
return ret;}
/* Function 8 */DWORDWINAPIPNP_GetRelatedDeviceInstance( handle_t hBinding, DWORD ulRelationship, LPWSTR pDeviceID, LPWSTR pRelatedDeviceId, PNP_RPC_STRING_LEN *pulLength, DWORD ulFlags){ PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_GetRelatedDeviceInstance(%p %lu %S %p %p 0x%lx)\n", hBinding, ulRelationship, pDeviceID, pRelatedDeviceId, pulLength, ulFlags);
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
if (ulRelationship == PNP_GET_PARENT_DEVICE_INSTANCE) { /* The root device does not have a parent */ if (IsRootDeviceInstanceID(pDeviceID)) return CR_NO_SUCH_DEVINST;
/* Return the root device for non existing devices */ if (!IsPresentDeviceInstanceID(pDeviceID)) { if ((wcslen(szRootDeviceInstanceID) + 1) > *pulLength) { *pulLength = wcslen(szRootDeviceInstanceID) + 1; return CR_BUFFER_SMALL; }
wcscpy(pRelatedDeviceId, szRootDeviceInstanceID); *pulLength = wcslen(szRootDeviceInstanceID) + 1; return CR_SUCCESS; } } else if (ulRelationship == PNP_GET_SIBLING_DEVICE_INSTANCE) { /* The root device does not have siblings */ if (IsRootDeviceInstanceID(pDeviceID)) return CR_NO_SUCH_DEVINST; }
RtlInitUnicodeString(&PlugPlayData.TargetDeviceInstance, pDeviceID);
PlugPlayData.Relation = ulRelationship;
PlugPlayData.RelatedDeviceInstanceLength = *pulLength; PlugPlayData.RelatedDeviceInstance = pRelatedDeviceId;
Status = NtPlugPlayControl(PlugPlayControlGetRelatedDevice, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA)); if (!NT_SUCCESS(Status)) { ret = NtStatusToCrError(Status); }
DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret); if (ret == CR_SUCCESS) { DPRINT("RelatedDevice: %wZ\n", &PlugPlayData.RelatedDeviceInstance); }
return ret;}
/* Function 9 */DWORDWINAPIPNP_EnumerateSubKeys( handle_t hBinding, DWORD ulBranch, DWORD ulIndex, LPWSTR Buffer, PNP_RPC_STRING_LEN ulLength, PNP_RPC_STRING_LEN *pulRequiredLen, DWORD ulFlags){ CONFIGRET ret = CR_SUCCESS; HKEY hKey; DWORD dwError;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_EnumerateSubKeys(%p %lu %lu %p %lu %p 0x%08lx)\n", hBinding, ulBranch, ulIndex, Buffer, ulLength, pulRequiredLen, ulFlags);
switch (ulBranch) { case PNP_ENUMERATOR_SUBKEYS: hKey = hEnumKey; break;
case PNP_CLASS_SUBKEYS: hKey = hClassKey; break;
default: return CR_FAILURE; }
*pulRequiredLen = ulLength; dwError = RegEnumKeyExW(hKey, ulIndex, Buffer, pulRequiredLen, NULL, NULL, NULL, NULL); if (dwError != ERROR_SUCCESS) { ret = (dwError == ERROR_NO_MORE_ITEMS) ? CR_NO_SUCH_VALUE : CR_FAILURE; } else { (*pulRequiredLen)++; }
DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
return ret;}
staticCONFIGRETGetRelationsInstanceList( _In_ PWSTR pszDevice, _In_ DWORD ulFlags, _Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength){ PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData; NTSTATUS Status; CONFIGRET ret = CR_SUCCESS;
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDevice);
if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS) { PlugPlayData.Relations = 3; } else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS) { PlugPlayData.Relations = 2; } else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS) { PlugPlayData.Relations = 1; } else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS) { PlugPlayData.Relations = 0; }
PlugPlayData.BufferSize = *pulLength * sizeof(WCHAR); PlugPlayData.Buffer = pszBuffer;
Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA)); if (NT_SUCCESS(Status)) { *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR); } else { ret = NtStatusToCrError(Status); }
return ret;}
staticCONFIGRETGetServiceInstanceList( _In_ PWSTR pszService, _Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength){ WCHAR szPathBuffer[512]; WCHAR szName[16]; HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL; DWORD dwValues, dwSize, dwIndex, dwUsedLength, dwPathLength; DWORD dwError; PWSTR pPtr; CONFIGRET ret = CR_SUCCESS;
/* Open the device key */ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services", 0, KEY_READ, &hServicesKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the services key (Error %lu)\n", dwError); return CR_REGISTRY_ERROR; }
dwError = RegOpenKeyExW(hServicesKey, pszService, 0, KEY_READ, &hServiceKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the service key (Error %lu)\n", dwError); ret = CR_REGISTRY_ERROR; goto Done; }
dwError = RegOpenKeyExW(hServiceKey, L"Enum", 0, KEY_READ, &hEnumKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the service enum key (Error %lu)\n", dwError); ret = CR_REGISTRY_ERROR; goto Done; }
/* Retrieve the number of device instances */ dwSize = sizeof(DWORD); dwError = RegQueryValueExW(hEnumKey, L"Count", NULL, NULL, (LPBYTE)&dwValues, &dwSize); if (dwError != ERROR_SUCCESS) { DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError); dwValues = 1; }
DPRINT("dwValues %lu\n", dwValues);
dwUsedLength = 0; pPtr = pszBuffer;
for (dwIndex = 0; dwIndex < dwValues; dwIndex++) { wsprintf(szName, L"%lu", dwIndex);
dwSize = sizeof(szPathBuffer); dwError = RegQueryValueExW(hEnumKey, szName, NULL, NULL, (LPBYTE)szPathBuffer, &dwSize); if (dwError != ERROR_SUCCESS) break;
DPRINT("Path: %S\n", szPathBuffer);
dwPathLength = wcslen(szPathBuffer) + 1; if (dwUsedLength + dwPathLength + 1 > *pulLength) { ret = CR_BUFFER_SMALL; break; }
wcscpy(pPtr, szPathBuffer); dwUsedLength += dwPathLength; pPtr += dwPathLength;
*pPtr = UNICODE_NULL; }
Done: if (hEnumKey != NULL) RegCloseKey(hEnumKey);
if (hServiceKey != NULL) RegCloseKey(hServiceKey);
if (hServicesKey != NULL) RegCloseKey(hServicesKey);
if (ret == CR_SUCCESS) *pulLength = dwUsedLength + 1; else *pulLength = 0;
return ret;}
staticCONFIGRETGetDeviceInstanceList( _In_ PWSTR pszDevice, _Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength){ WCHAR szInstanceBuffer[MAX_DEVICE_ID_LEN]; WCHAR szPathBuffer[512]; HKEY hDeviceKey; DWORD dwInstanceLength, dwPathLength, dwUsedLength; DWORD dwIndex, dwError; PWSTR pPtr; CONFIGRET ret = CR_SUCCESS;
/* Open the device key */ dwError = RegOpenKeyExW(hEnumKey, pszDevice, 0, KEY_ENUMERATE_SUB_KEYS, &hDeviceKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the device key (Error %lu)\n", dwError); return CR_REGISTRY_ERROR; }
dwUsedLength = 0; pPtr = pszBuffer;
for (dwIndex = 0; ; dwIndex++) { dwInstanceLength = MAX_DEVICE_ID_LEN; dwError = RegEnumKeyExW(hDeviceKey, dwIndex, szInstanceBuffer, &dwInstanceLength, NULL, NULL, NULL, NULL); if (dwError != ERROR_SUCCESS) break;
wsprintf(szPathBuffer, L"%s\\%s", pszDevice, szInstanceBuffer); DPRINT("Path: %S\n", szPathBuffer);
dwPathLength = wcslen(szPathBuffer) + 1; if (dwUsedLength + dwPathLength + 1 > *pulLength) { ret = CR_BUFFER_SMALL; break; }
wcscpy(pPtr, szPathBuffer); dwUsedLength += dwPathLength; pPtr += dwPathLength;
*pPtr = UNICODE_NULL; }
RegCloseKey(hDeviceKey);
if (ret == CR_SUCCESS) *pulLength = dwUsedLength + 1; else *pulLength = 0;
return ret;}
CONFIGRETGetEnumeratorInstanceList( _In_ PWSTR pszEnumerator, _Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength){ WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN]; WCHAR szPathBuffer[512]; HKEY hEnumeratorKey; PWSTR pPtr; DWORD dwIndex, dwDeviceLength, dwUsedLength, dwRemainingLength, dwPathLength; DWORD dwError; CONFIGRET ret = CR_SUCCESS;
/* Open the enumerator key */ dwError = RegOpenKeyExW(hEnumKey, pszEnumerator, 0, KEY_ENUMERATE_SUB_KEYS, &hEnumeratorKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError); return CR_REGISTRY_ERROR; }
dwUsedLength = 0; dwRemainingLength = *pulLength; pPtr = pszBuffer;
for (dwIndex = 0; ; dwIndex++) { dwDeviceLength = MAX_DEVICE_ID_LEN; dwError = RegEnumKeyExW(hEnumeratorKey, dwIndex, szDeviceBuffer, &dwDeviceLength, NULL, NULL, NULL, NULL); if (dwError != ERROR_SUCCESS) break;
wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer); DPRINT("Path: %S\n", szPathBuffer);
dwPathLength = dwRemainingLength; ret = GetDeviceInstanceList(szPathBuffer, pPtr, &dwPathLength); if (ret != CR_SUCCESS) break;
dwUsedLength += dwPathLength - 1; dwRemainingLength -= dwPathLength - 1; pPtr += dwPathLength - 1; }
RegCloseKey(hEnumeratorKey);
if (ret == CR_SUCCESS) *pulLength = dwUsedLength + 1; else *pulLength = 0;
return ret;}
staticCONFIGRETGetAllInstanceList( _Inout_ PWSTR pszBuffer, _Inout_ PDWORD pulLength){ WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN]; PWSTR pPtr; DWORD dwIndex, dwEnumeratorLength, dwUsedLength, dwRemainingLength, dwPathLength; DWORD dwError; CONFIGRET ret = CR_SUCCESS;
dwUsedLength = 0; dwRemainingLength = *pulLength; pPtr = pszBuffer;
for (dwIndex = 0; ; dwIndex++) { dwEnumeratorLength = MAX_DEVICE_ID_LEN; dwError = RegEnumKeyExW(hEnumKey, dwIndex, szEnumeratorBuffer, &dwEnumeratorLength, NULL, NULL, NULL, NULL); if (dwError != ERROR_SUCCESS) break;
dwPathLength = dwRemainingLength; ret = GetEnumeratorInstanceList(szEnumeratorBuffer, pPtr, &dwPathLength); if (ret != CR_SUCCESS) break;
dwUsedLength += dwPathLength - 1; dwRemainingLength -= dwPathLength - 1; pPtr += dwPathLength - 1; }
if (ret == CR_SUCCESS) *pulLength = dwUsedLength + 1; else *pulLength = 0;
return ret;}
/* Function 10 */DWORDWINAPIPNP_GetDeviceList( handle_t hBinding, LPWSTR pszFilter, LPWSTR Buffer, PNP_RPC_STRING_LEN *pulLength, DWORD ulFlags){ WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; WCHAR szDevice[MAX_DEVICE_ID_LEN]; WCHAR szInstance[MAX_DEVICE_ID_LEN]; CONFIGRET ret = CR_SUCCESS;
DPRINT("PNP_GetDeviceList(%p %S %p %p 0x%08lx)\n", hBinding, pszFilter, Buffer, pulLength, ulFlags);
if (ulFlags & ~CM_GETIDLIST_FILTER_BITS) return CR_INVALID_FLAG;
if (pulLength == NULL) return CR_INVALID_POINTER;
if ((ulFlags != CM_GETIDLIST_FILTER_NONE) && (pszFilter == NULL)) return CR_INVALID_POINTER;
if (ulFlags & (CM_GETIDLIST_FILTER_BUSRELATIONS | CM_GETIDLIST_FILTER_POWERRELATIONS | CM_GETIDLIST_FILTER_REMOVALRELATIONS | CM_GETIDLIST_FILTER_EJECTRELATIONS)) { ret = GetRelationsInstanceList(pszFilter, ulFlags, Buffer, pulLength); } else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE) { ret = GetServiceInstanceList(pszFilter, Buffer, pulLength); } else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR) { SplitDeviceInstanceID(pszFilter, szEnumerator, szDevice, szInstance);
if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL) { ret = GetDeviceInstanceList(pszFilter, Buffer, pulLength); } else { ret = GetEnumeratorInstanceList(pszFilter, Buffer, pulLength); } } else /* CM_GETIDLIST_FILTER_NONE */ { ret = GetAllInstanceList(Buffer, pulLength); }
return ret;}
staticCONFIGRETGetRelationsInstanceListSize( _In_ PWSTR pszDevice, _In_ DWORD ulFlags, _Inout_ PDWORD pulLength){ PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData; NTSTATUS Status; CONFIGRET ret = CR_SUCCESS;
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDevice);
if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS) { PlugPlayData.Relations = 3; } else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS) { PlugPlayData.Relations = 2; } else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS) { PlugPlayData.Relations = 1; } else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS) { PlugPlayData.Relations = 0; }
PlugPlayData.BufferSize = 0; PlugPlayData.Buffer = NULL;
Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA)); if (NT_SUCCESS(Status)) { *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR); } else { ret = NtStatusToCrError(Status); }
return ret;}
staticCONFIGRETGetServiceInstanceListSize( _In_ PWSTR pszService, _Out_ PDWORD pulLength){ HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL; DWORD dwValues, dwMaxValueLength, dwSize; DWORD dwError; CONFIGRET ret = CR_SUCCESS;
/* Open the device key */ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services", 0, KEY_READ, &hServicesKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the services key (Error %lu)\n", dwError); return CR_REGISTRY_ERROR; }
dwError = RegOpenKeyExW(hServicesKey, pszService, 0, KEY_READ, &hServiceKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the service key (Error %lu)\n", dwError); ret = CR_REGISTRY_ERROR; goto Done; }
dwError = RegOpenKeyExW(hServiceKey, L"Enum", 0, KEY_READ, &hEnumKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the service enum key (Error %lu)\n", dwError); ret = CR_REGISTRY_ERROR; goto Done; }
/* Retrieve the number of device instances */ dwSize = sizeof(DWORD); dwError = RegQueryValueExW(hEnumKey, L"Count", NULL, NULL, (LPBYTE)&dwValues, &dwSize); if (dwError != ERROR_SUCCESS) { DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError); dwValues = 1; }
/* Retrieve the maximum instance name length */ dwError = RegQueryInfoKeyW(hEnumKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwMaxValueLength, NULL, NULL); if (dwError != ERROR_SUCCESS) { DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError); dwMaxValueLength = MAX_DEVICE_ID_LEN; }
DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues, dwMaxValueLength / sizeof(WCHAR));
/* Return the largest possible buffer size */ *pulLength = dwValues * dwMaxValueLength / sizeof(WCHAR) + 2;
Done: if (hEnumKey != NULL) RegCloseKey(hEnumKey);
if (hServiceKey != NULL) RegCloseKey(hServiceKey);
if (hServicesKey != NULL) RegCloseKey(hServicesKey);
return ret;}
staticCONFIGRETGetDeviceInstanceListSize( _In_ LPCWSTR pszDevice, _Out_ PULONG pulLength){ HKEY hDeviceKey; DWORD dwSubKeys, dwMaxSubKeyLength; DWORD dwError;
/* Open the device key */ dwError = RegOpenKeyExW(hEnumKey, pszDevice, 0, KEY_READ, &hDeviceKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the device key (Error %lu)\n", dwError); return CR_REGISTRY_ERROR; }
/* Retrieve the number of device instances and the maximum name length */ dwError = RegQueryInfoKeyW(hDeviceKey, NULL, NULL, NULL, &dwSubKeys, &dwMaxSubKeyLength, NULL, NULL, NULL, NULL, NULL, NULL); if (dwError != ERROR_SUCCESS) { DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError); dwSubKeys = 0; dwMaxSubKeyLength = 0; }
/* Close the device key */ RegCloseKey(hDeviceKey);
/* Return the largest possible buffer size */ *pulLength = dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1);
return CR_SUCCESS;}
staticCONFIGRETGetEnumeratorInstanceListSize( _In_ LPCWSTR pszEnumerator, _Out_ PULONG pulLength){ WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN]; WCHAR szPathBuffer[512]; HKEY hEnumeratorKey; DWORD dwIndex, dwDeviceLength, dwBufferLength; DWORD dwError; CONFIGRET ret = CR_SUCCESS;
*pulLength = 0;
/* Open the enumerator key */ dwError = RegOpenKeyExW(hEnumKey, pszEnumerator, 0, KEY_ENUMERATE_SUB_KEYS, &hEnumeratorKey); if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError); return CR_REGISTRY_ERROR; }
for (dwIndex = 0; ; dwIndex++) { dwDeviceLength = MAX_DEVICE_ID_LEN; dwError = RegEnumKeyExW(hEnumeratorKey, dwIndex, szDeviceBuffer, &dwDeviceLength, NULL, NULL, NULL, NULL); if (dwError != ERROR_SUCCESS) break;
wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer); DPRINT("Path: %S\n", szPathBuffer);
ret = GetDeviceInstanceListSize(szPathBuffer, &dwBufferLength); if (ret != CR_SUCCESS) { *pulLength = 0; break; }
*pulLength += dwBufferLength; }
/* Close the enumerator key */ RegCloseKey(hEnumeratorKey);
return ret;}
staticCONFIGRETGetAllInstanceListSize( _Out_ PULONG pulLength){ WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN]; DWORD dwIndex, dwEnumeratorLength, dwBufferLength; DWORD dwError; CONFIGRET ret = CR_SUCCESS;
for (dwIndex = 0; ; dwIndex++) { dwEnumeratorLength = MAX_DEVICE_ID_LEN; dwError = RegEnumKeyExW(hEnumKey, dwIndex, szEnumeratorBuffer, &dwEnumeratorLength, NULL, NULL, NULL, NULL); if (dwError != ERROR_SUCCESS) break;
/* Get the size of all device instances for the enumerator */ ret = GetEnumeratorInstanceListSize(szEnumeratorBuffer, &dwBufferLength); if (ret != CR_SUCCESS) break;
*pulLength += dwBufferLength; }
return ret;}
/* Function 11 */DWORDWINAPIPNP_GetDeviceListSize( handle_t hBinding, LPWSTR pszFilter, PNP_RPC_BUFFER_SIZE *pulLength, DWORD ulFlags){ WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; WCHAR szDevice[MAX_DEVICE_ID_LEN]; WCHAR szInstance[MAX_DEVICE_ID_LEN]; CONFIGRET ret = CR_SUCCESS;
DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%08lx)\n", hBinding, pszFilter, pulLength, ulFlags);
if (ulFlags & ~CM_GETIDLIST_FILTER_BITS) return CR_INVALID_FLAG;
if (pulLength == NULL) return CR_INVALID_POINTER;
if ((ulFlags != CM_GETIDLIST_FILTER_NONE) && (pszFilter == NULL)) return CR_INVALID_POINTER;
*pulLength = 0;
if (ulFlags & (CM_GETIDLIST_FILTER_BUSRELATIONS | CM_GETIDLIST_FILTER_POWERRELATIONS | CM_GETIDLIST_FILTER_REMOVALRELATIONS | CM_GETIDLIST_FILTER_EJECTRELATIONS)) { ret = GetRelationsInstanceListSize(pszFilter, ulFlags, pulLength); } else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE) { ret = GetServiceInstanceListSize(pszFilter, pulLength); } else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR) { SplitDeviceInstanceID(pszFilter, szEnumerator, szDevice, szInstance);
if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL) { ret = GetDeviceInstanceListSize(pszFilter, pulLength); } else { ret = GetEnumeratorInstanceListSize(pszFilter, pulLength); } } else /* CM_GETIDLIST_FILTER_NONE */ { ret = GetAllInstanceListSize(pulLength); }
/* Add one character for the terminating double UNICODE_NULL */ if (ret == CR_SUCCESS) (*pulLength) += 1;
return ret;}
/* Function 12 */DWORDWINAPIPNP_GetDepth( handle_t hBinding, LPWSTR pszDeviceID, DWORD *pulDepth, DWORD ulFlags){ PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_GetDepth(%p %S %p 0x%08lx)\n", hBinding, pszDeviceID, pulDepth, ulFlags);
if (!IsValidDeviceInstanceID(pszDeviceID)) return CR_INVALID_DEVINST;
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID);
Status = NtPlugPlayControl(PlugPlayControlGetDeviceDepth, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_DEPTH_DATA)); if (NT_SUCCESS(Status)) { *pulDepth = PlugPlayData.Depth; } else { ret = NtStatusToCrError(Status); }
DPRINT("PNP_GetDepth() done (returns %lx)\n", ret);
return ret;}
/* Function 13 */DWORDWINAPIPNP_GetDeviceRegProp( handle_t hBinding, LPWSTR pDeviceID, DWORD ulProperty, DWORD *pulRegDataType, BYTE *Buffer, PNP_PROP_SIZE *pulTransferLen, PNP_PROP_SIZE *pulLength, DWORD ulFlags){ PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData; CONFIGRET ret = CR_SUCCESS; LPWSTR lpValueName = NULL; HKEY hKey = NULL; LONG lError; NTSTATUS Status;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetDeviceRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n", hBinding, pDeviceID, ulProperty, pulRegDataType, Buffer, pulTransferLen, pulLength, ulFlags);
if (pulTransferLen == NULL || pulLength == NULL) { ret = CR_INVALID_POINTER; goto done; }
if (ulFlags != 0) { ret = CR_INVALID_FLAG; goto done; }
/* Check pDeviceID */ if (!IsValidDeviceInstanceID(pDeviceID)) { ret = CR_INVALID_DEVINST; goto done; }
if (*pulLength < *pulTransferLen) *pulLength = *pulTransferLen;
*pulTransferLen = 0;
switch (ulProperty) { case CM_DRP_DEVICEDESC: lpValueName = L"DeviceDesc"; break;
case CM_DRP_HARDWAREID: lpValueName = L"HardwareID"; break;
case CM_DRP_COMPATIBLEIDS: lpValueName = L"CompatibleIDs"; break;
case CM_DRP_SERVICE: lpValueName = L"Service"; break;
case CM_DRP_CLASS: lpValueName = L"Class"; break;
case CM_DRP_CLASSGUID: lpValueName = L"ClassGUID"; break;
case CM_DRP_DRIVER: lpValueName = L"Driver"; break;
case CM_DRP_CONFIGFLAGS: lpValueName = L"ConfigFlags"; break;
case CM_DRP_MFG: lpValueName = L"Mfg"; break;
case CM_DRP_FRIENDLYNAME: lpValueName = L"FriendlyName"; break;
case CM_DRP_LOCATION_INFORMATION: lpValueName = L"LocationInformation"; break;
case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME: PlugPlayData.Property = PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME; *pulRegDataType = REG_SZ; break;
case CM_DRP_CAPABILITIES: lpValueName = L"Capabilities"; break;
case CM_DRP_UI_NUMBER: PlugPlayData.Property = PNP_PROPERTY_UI_NUMBER; break;
case CM_DRP_UPPERFILTERS: lpValueName = L"UpperFilters"; break;
case CM_DRP_LOWERFILTERS: lpValueName = L"LowerFilters"; break;
case CM_DRP_BUSTYPEGUID: PlugPlayData.Property = PNP_PROPERTY_BUSTYPEGUID; *pulRegDataType = REG_BINARY; break;
case CM_DRP_LEGACYBUSTYPE: PlugPlayData.Property = PNP_PROPERTY_LEGACYBUSTYPE; *pulRegDataType = REG_DWORD; break;
case CM_DRP_BUSNUMBER: PlugPlayData.Property = PNP_PROPERTY_BUSNUMBER; *pulRegDataType = REG_DWORD; break;
case CM_DRP_ENUMERATOR_NAME: PlugPlayData.Property = PNP_PROPERTY_ENUMERATOR_NAME; *pulRegDataType = REG_SZ; break;
case CM_DRP_SECURITY: lpValueName = L"Security"; break;
case CM_DRP_DEVTYPE: lpValueName = L"DeviceType"; break;
case CM_DRP_EXCLUSIVE: lpValueName = L"Exclusive"; break;
case CM_DRP_CHARACTERISTICS: lpValueName = L"DeviceCharacteristics"; break;
case CM_DRP_ADDRESS: PlugPlayData.Property = PNP_PROPERTY_ADDRESS; *pulRegDataType = REG_DWORD; break;
case CM_DRP_UI_NUMBER_DESC_FORMAT: lpValueName = L"UINumberDescFormat"; break;
case CM_DRP_DEVICE_POWER_DATA: PlugPlayData.Property = PNP_PROPERTY_POWER_DATA; *pulRegDataType = REG_BINARY; break;
case CM_DRP_REMOVAL_POLICY: PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY; *pulRegDataType = REG_DWORD; break;
case CM_DRP_REMOVAL_POLICY_HW_DEFAULT: PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT; *pulRegDataType = REG_DWORD; break;
case CM_DRP_REMOVAL_POLICY_OVERRIDE: lpValueName = L"RemovalPolicy"; *pulRegDataType = REG_DWORD; break;
case CM_DRP_INSTALL_STATE: PlugPlayData.Property = PNP_PROPERTY_INSTALL_STATE; *pulRegDataType = REG_DWORD; break;
#if (WINVER >= _WIN32_WINNT_WS03) case CM_DRP_LOCATION_PATHS: PlugPlayData.Property = PNP_PROPERTY_LOCATION_PATHS; *pulRegDataType = REG_MULTI_SZ; break;#endif
#if (WINVER >= _WIN32_WINNT_WIN7) case CM_DRP_BASE_CONTAINERID: PlugPlayData.Property = PNP_PROPERTY_CONTAINERID; *pulRegDataType = REG_SZ; break;#endif
default: ret = CR_INVALID_PROPERTY; goto done; }
DPRINT("Value name: %S\n", lpValueName);
if (lpValueName) { /* Retrieve information from the Registry */ lError = RegOpenKeyExW(hEnumKey, pDeviceID, 0, KEY_QUERY_VALUE, &hKey); if (lError != ERROR_SUCCESS) { hKey = NULL; *pulLength = 0; ret = CR_INVALID_DEVNODE; goto done; }
lError = RegQueryValueExW(hKey, lpValueName, NULL, pulRegDataType, Buffer, pulLength); if (lError != ERROR_SUCCESS) { if (lError == ERROR_MORE_DATA) { ret = CR_BUFFER_SMALL; } else { *pulLength = 0; ret = CR_NO_SUCH_VALUE; } } } else { /* Retrieve information from the Device Node */ RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pDeviceID); PlugPlayData.Buffer = Buffer; PlugPlayData.BufferSize = *pulLength;
Status = NtPlugPlayControl(PlugPlayControlProperty, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA)); if (NT_SUCCESS(Status)) { *pulLength = PlugPlayData.BufferSize; } else { ret = NtStatusToCrError(Status); } }
done: if (pulTransferLen) *pulTransferLen = (ret == CR_SUCCESS) ? *pulLength : 0;
if (hKey != NULL) RegCloseKey(hKey);
DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret);
return ret;}
/* Function 14 */DWORDWINAPIPNP_SetDeviceRegProp( handle_t hBinding, LPWSTR pDeviceId, DWORD ulProperty, DWORD ulDataType, BYTE *Buffer, PNP_PROP_SIZE ulLength, DWORD ulFlags){ CONFIGRET ret = CR_SUCCESS; LPWSTR lpValueName = NULL; HKEY hKey = 0;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_SetDeviceRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n", hBinding, pDeviceId, ulProperty, ulDataType, Buffer, ulLength, ulFlags);
if (!IsValidDeviceInstanceID(pDeviceId)) return CR_INVALID_DEVINST;
switch (ulProperty) { case CM_DRP_DEVICEDESC: lpValueName = L"DeviceDesc"; break;
case CM_DRP_HARDWAREID: lpValueName = L"HardwareID"; break;
case CM_DRP_COMPATIBLEIDS: lpValueName = L"CompatibleIDs"; break;
case CM_DRP_SERVICE: lpValueName = L"Service"; break;
case CM_DRP_CLASS: lpValueName = L"Class"; break;
case CM_DRP_CLASSGUID: lpValueName = L"ClassGUID"; break;
case CM_DRP_DRIVER: lpValueName = L"Driver"; break;
case CM_DRP_CONFIGFLAGS: lpValueName = L"ConfigFlags"; break;
case CM_DRP_MFG: lpValueName = L"Mfg"; break;
case CM_DRP_FRIENDLYNAME: lpValueName = L"FriendlyName"; break;
case CM_DRP_LOCATION_INFORMATION: lpValueName = L"LocationInformation"; break;
case CM_DRP_UPPERFILTERS: lpValueName = L"UpperFilters"; break;
case CM_DRP_LOWERFILTERS: lpValueName = L"LowerFilters"; break;
case CM_DRP_SECURITY: lpValueName = L"Security"; break;
case CM_DRP_DEVTYPE: lpValueName = L"DeviceType"; break;
case CM_DRP_EXCLUSIVE: lpValueName = L"Exclusive"; break;
case CM_DRP_CHARACTERISTICS: lpValueName = L"DeviceCharacteristics"; break;
case CM_DRP_UI_NUMBER_DESC_FORMAT: lpValueName = L"UINumberDescFormat"; break;
case CM_DRP_REMOVAL_POLICY_OVERRIDE: lpValueName = L"RemovalPolicy"; break;
default: return CR_INVALID_PROPERTY; }
DPRINT("Value name: %S\n", lpValueName);
if (RegOpenKeyExW(hEnumKey, pDeviceId, 0, KEY_SET_VALUE, &hKey)) return CR_INVALID_DEVNODE;
if (ulLength == 0) { if (RegDeleteValueW(hKey, lpValueName)) ret = CR_REGISTRY_ERROR; } else { if (RegSetValueExW(hKey, lpValueName, 0, ulDataType, Buffer, ulLength)) ret = CR_REGISTRY_ERROR; }
RegCloseKey(hKey);
DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret);
return ret;}
/* Function 15 */DWORDWINAPIPNP_GetClassInstance( handle_t hBinding, LPWSTR pDeviceId, LPWSTR pszClassInstance, PNP_RPC_STRING_LEN ulLength){ WCHAR szClassGuid[40]; WCHAR szClassInstance[5]; HKEY hDeviceClassKey = NULL; HKEY hClassInstanceKey; ULONG ulTransferLength, ulDataLength; DWORD dwDataType, dwDisposition, i; DWORD dwError; CONFIGRET ret = CR_SUCCESS;
DPRINT("PNP_GetClassInstance(%p %S %p %lu)\n", hBinding, pDeviceId, pszClassInstance, ulLength);
if (!IsValidDeviceInstanceID(pDeviceId)) return CR_INVALID_DEVINST;
ulTransferLength = ulLength; ret = PNP_GetDeviceRegProp(hBinding, pDeviceId, CM_DRP_DRIVER, &dwDataType, (BYTE *)pszClassInstance, &ulTransferLength, &ulLength, 0); if (ret == CR_SUCCESS) return ret;
ulTransferLength = sizeof(szClassGuid); ulDataLength = sizeof(szClassGuid); ret = PNP_GetDeviceRegProp(hBinding, pDeviceId, CM_DRP_CLASSGUID, &dwDataType, (BYTE *)szClassGuid, &ulTransferLength, &ulDataLength, 0); if (ret != CR_SUCCESS) { DPRINT1("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret); goto done; }
dwError = RegOpenKeyExW(hClassKey, szClassGuid, 0, KEY_READ, &hDeviceClassKey); if (dwError != ERROR_SUCCESS) { DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError); ret = CR_FAILURE; goto done; }
for (i = 0; i < 10000; i++) { wsprintf(szClassInstance, L"%04lu", i);
dwError = RegCreateKeyExW(hDeviceClassKey, szClassInstance, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hClassInstanceKey, &dwDisposition); if (dwError == ERROR_SUCCESS) { RegCloseKey(hClassInstanceKey);
if (dwDisposition == REG_CREATED_NEW_KEY) { wsprintf(pszClassInstance, L"%s\\%s", szClassGuid, szClassInstance);
ulDataLength = (wcslen(pszClassInstance) + 1) * sizeof(WCHAR); ret = PNP_SetDeviceRegProp(hBinding, pDeviceId, CM_DRP_DRIVER, REG_SZ, (BYTE *)pszClassInstance, ulDataLength, 0); if (ret != CR_SUCCESS) { DPRINT1("PNP_SetDeviceRegProp() failed (Error %lu)\n", ret); RegDeleteKeyW(hDeviceClassKey, szClassInstance); }
break; } } }
done: if (hDeviceClassKey != NULL) RegCloseKey(hDeviceClassKey);
return ret;}
/* Function 16 */DWORDWINAPIPNP_CreateKey( handle_t hBinding, LPWSTR pszSubKey, DWORD samDesired, DWORD ulFlags){ HKEY hDeviceKey = NULL, hParametersKey = NULL; DWORD dwError; CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(samDesired);
DPRINT("PNP_CreateKey(%p %S 0x%lx 0x%08lx)\n", hBinding, pszSubKey, samDesired, ulFlags);
if (ulFlags != 0) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pszSubKey)) return CR_INVALID_DEVINST;
dwError = RegOpenKeyExW(hEnumKey, pszSubKey, 0, KEY_WRITE, &hDeviceKey); if (dwError != ERROR_SUCCESS) { ret = CR_INVALID_DEVNODE; goto done; }
dwError = RegCreateKeyExW(hDeviceKey, L"Device Parameters", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hParametersKey, NULL); if (dwError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
/* FIXME: Set key security */
done: if (hParametersKey != NULL) RegCloseKey(hParametersKey);
if (hDeviceKey != NULL) RegCloseKey(hDeviceKey);
return ret;}
/* Function 17 */DWORDWINAPIPNP_DeleteRegistryKey( handle_t hBinding, LPWSTR pszDeviceID, LPWSTR pszParentKey, LPWSTR pszChildKey, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 18 */DWORDWINAPIPNP_GetClassCount( handle_t hBinding, DWORD *pulClassCount, DWORD ulFlags){ HKEY hKey; DWORD dwError;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_GetClassCount(%p %p 0x%08lx)\n", hBinding, pulClassCount, ulFlags);
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, REGSTR_PATH_CLASS, 0, KEY_QUERY_VALUE, &hKey); if (dwError != ERROR_SUCCESS) return CR_INVALID_DATA;
dwError = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, pulClassCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL); RegCloseKey(hKey); if (dwError != ERROR_SUCCESS) return CR_INVALID_DATA;
return CR_SUCCESS;}
/* Function 19 */DWORDWINAPIPNP_GetClassName( handle_t hBinding, LPWSTR pszClassGuid, LPWSTR Buffer, PNP_RPC_STRING_LEN *pulLength, DWORD ulFlags){ WCHAR szKeyName[MAX_PATH]; CONFIGRET ret = CR_SUCCESS; HKEY hKey; DWORD dwSize;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_GetClassName(%p %S %p %p 0x%08lx)\n", hBinding, pszClassGuid, Buffer, pulLength, ulFlags);
lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class\\"); if (lstrlenW(pszClassGuid) + 1 < sizeof(szKeyName)/sizeof(WCHAR)-(lstrlenW(szKeyName) * sizeof(WCHAR))) lstrcatW(szKeyName, pszClassGuid); else return CR_INVALID_DATA;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey)) return CR_REGISTRY_ERROR;
dwSize = *pulLength * sizeof(WCHAR); if (RegQueryValueExW(hKey, L"Class", NULL, NULL, (LPBYTE)Buffer, &dwSize)) { *pulLength = 0; ret = CR_REGISTRY_ERROR; } else { *pulLength = dwSize / sizeof(WCHAR); }
RegCloseKey(hKey);
DPRINT("PNP_GetClassName() done (returns %lx)\n", ret);
return ret;}
/* Function 20 */DWORDWINAPIPNP_DeleteClassKey( handle_t hBinding, LPWSTR pszClassGuid, DWORD ulFlags){ CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_DeleteClassKey(%p %S 0x%08lx)\n", hBinding, pszClassGuid, ulFlags);
if (ulFlags & CM_DELETE_CLASS_SUBKEYS) { if (SHDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS) ret = CR_REGISTRY_ERROR; } else { if (RegDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS) ret = CR_REGISTRY_ERROR; }
DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret);
return ret;}
/* Function 21 */DWORDWINAPIPNP_GetInterfaceDeviceAlias( handle_t hBinding, LPWSTR pszInterfaceDevice, GUID *AliasInterfaceGuid, LPWSTR pszAliasInterfaceDevice, PNP_RPC_STRING_LEN *pulLength, PNP_RPC_STRING_LEN *pulTransferLen, DWORD ulFlags){ NTSTATUS Status; PLUGPLAY_CONTROL_INTERFACE_ALIAS_DATA PlugPlayData; DWORD ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetInterfaceDeviceAlias(%p %S %p %p %p %p 0x%08lx)\n", hBinding, pszInterfaceDevice, AliasInterfaceGuid, pszAliasInterfaceDevice, pulLength, pulTransferLen, ulFlags);
if ((AliasInterfaceGuid == NULL) || (pulLength == NULL)) return CR_INVALID_POINTER;
if (ulFlags != 0) return CR_INVALID_FLAG;
RtlInitUnicodeString(&PlugPlayData.SymbolicLinkName, pszInterfaceDevice); PlugPlayData.AliasInterfaceClassGuid = AliasInterfaceGuid; PlugPlayData.AliasSymbolicLinkName = pszAliasInterfaceDevice; PlugPlayData.AliasSymbolicLinkNameLength = *pulTransferLen;
Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceAlias, &PlugPlayData, sizeof(PLUGPLAY_CONTROL_INTERFACE_ALIAS_DATA)); if (NT_SUCCESS(Status)) { *pulLength = PlugPlayData.AliasSymbolicLinkNameLength; *pulTransferLen = *pulLength + 1; } else { *pulLength = 0; *pulTransferLen = 0; ret = NtStatusToCrError(Status); }
DPRINT("PNP_GetInterfaceDeviceAlias() done (returns %lx)\n", ret); return ret;}
/* Function 22 */DWORDWINAPIPNP_GetInterfaceDeviceList( handle_t hBinding, GUID *InterfaceGuid, LPWSTR pszDeviceID, BYTE *Buffer, PNP_RPC_BUFFER_SIZE *pulLength, DWORD ulFlags){ NTSTATUS Status; PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData; DWORD ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetInterfaceDeviceList(%p %p %S %p %p 0x%08lx)\n", hBinding, InterfaceGuid, pszDeviceID, Buffer, pulLength, ulFlags);
if (!IsValidDeviceInstanceID(pszDeviceID)) return CR_INVALID_DEVINST;
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID);
PlugPlayData.Flags = ulFlags; PlugPlayData.FilterGuid = InterfaceGuid; PlugPlayData.Buffer = Buffer; PlugPlayData.BufferSize = *pulLength;
Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA)); if (NT_SUCCESS(Status)) { *pulLength = PlugPlayData.BufferSize; } else { ret = NtStatusToCrError(Status); }
DPRINT("PNP_GetInterfaceDeviceList() done (returns %lx)\n", ret); return ret;}
/* Function 23 */DWORDWINAPIPNP_GetInterfaceDeviceListSize( handle_t hBinding, PNP_RPC_BUFFER_SIZE *pulLen, GUID *InterfaceGuid, LPWSTR pszDeviceID, DWORD ulFlags){ NTSTATUS Status; PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData; DWORD ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetInterfaceDeviceListSize(%p %p %p %S 0x%08lx)\n", hBinding, pulLen, InterfaceGuid, pszDeviceID, ulFlags);
if (!IsValidDeviceInstanceID(pszDeviceID)) return CR_INVALID_DEVINST;
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID);
PlugPlayData.FilterGuid = InterfaceGuid; PlugPlayData.Buffer = NULL; PlugPlayData.BufferSize = 0; PlugPlayData.Flags = ulFlags;
Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList, (PVOID)&PlugPlayData, sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA)); if (NT_SUCCESS(Status)) { *pulLen = PlugPlayData.BufferSize; } else { ret = NtStatusToCrError(Status); }
DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret); return ret;}
/* Function 24 */DWORDWINAPIPNP_RegisterDeviceClassAssociation( handle_t hBinding, LPWSTR pszDeviceID, GUID *InterfaceGuid, LPWSTR pszReference, LPWSTR pszSymLink, PNP_RPC_STRING_LEN *pulLength, PNP_RPC_STRING_LEN *pulTransferLen, DWORD ulFlags){ PLUGPLAY_CONTROL_CLASS_ASSOCIATION_DATA PlugPlayData; NTSTATUS Status; CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT1("PNP_RegisterDeviceClassAssociation(%p %S %p %S %S %p %p 0x%08lx)\n", hBinding, pszDeviceID, InterfaceGuid, pszReference, pszSymLink, pulLength, pulTransferLen, ulFlags);
if ((InterfaceGuid == NULL) || (pszSymLink == NULL) || (pulLength == NULL) || (pulTransferLen == NULL)) return CR_INVALID_POINTER;
if (ulFlags != 0) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pszDeviceID)) return CR_INVALID_DEVINST;
RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID); PlugPlayData.InterfaceGuid = InterfaceGuid; RtlInitUnicodeString(&PlugPlayData.Reference, pszReference); PlugPlayData.Register = TRUE; PlugPlayData.SymbolicLinkName = pszSymLink; PlugPlayData.SymbolicLinkNameLength = *pulLength;
Status = NtPlugPlayControl(PlugPlayControlDeviceClassAssociation, &PlugPlayData, sizeof(PLUGPLAY_CONTROL_CLASS_ASSOCIATION_DATA)); if (NT_SUCCESS(Status)) { *pulLength = PlugPlayData.SymbolicLinkNameLength; *pulTransferLen = *pulLength; } else { *pulLength = 0; ret = NtStatusToCrError(Status); }
return ret;}
/* Function 25 */DWORDWINAPIPNP_UnregisterDeviceClassAssociation( handle_t hBinding, LPWSTR pszInterfaceDevice, DWORD ulFlags){ PLUGPLAY_CONTROL_CLASS_ASSOCIATION_DATA PlugPlayData; NTSTATUS Status; CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT1("PNP_UnregisterDeviceClassAssociation(%p %S 0x%08lx)\n", hBinding, pszInterfaceDevice, ulFlags);
if (pszInterfaceDevice == NULL) return CR_INVALID_POINTER;
if (ulFlags != 0) return CR_INVALID_FLAG;
ZeroMemory(&PlugPlayData, sizeof(PlugPlayData)); PlugPlayData.Register = FALSE; PlugPlayData.SymbolicLinkName = pszInterfaceDevice; PlugPlayData.SymbolicLinkNameLength = wcslen(pszInterfaceDevice) + 1;
Status = NtPlugPlayControl(PlugPlayControlDeviceClassAssociation, &PlugPlayData, sizeof(PLUGPLAY_CONTROL_CLASS_ASSOCIATION_DATA)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status);
return ret;}
/* Function 26 */DWORDWINAPIPNP_GetClassRegProp( handle_t hBinding, LPWSTR pszClassGuid, DWORD ulProperty, DWORD *pulRegDataType, BYTE *Buffer, PNP_RPC_STRING_LEN *pulTransferLen, PNP_RPC_STRING_LEN *pulLength, DWORD ulFlags){ CONFIGRET ret = CR_SUCCESS; LPWSTR lpValueName = NULL; HKEY hInstKey = NULL; HKEY hPropKey = NULL; LONG lError;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetClassRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n", hBinding, pszClassGuid, ulProperty, pulRegDataType, Buffer, pulTransferLen, pulLength, ulFlags);
if (pulTransferLen == NULL || pulLength == NULL) { ret = CR_INVALID_POINTER; goto done; }
if (ulFlags != 0) { ret = CR_INVALID_FLAG; goto done; }
if (*pulLength < *pulTransferLen) *pulLength = *pulTransferLen;
*pulTransferLen = 0;
switch (ulProperty) { case CM_CRP_SECURITY: lpValueName = L"Security"; break;
case CM_CRP_DEVTYPE: lpValueName = L"DeviceType"; break;
case CM_CRP_EXCLUSIVE: lpValueName = L"Exclusive"; break;
case CM_CRP_CHARACTERISTICS: lpValueName = L"DeviceCharacteristics"; break;
default: ret = CR_INVALID_PROPERTY; goto done; }
DPRINT("Value name: %S\n", lpValueName);
lError = RegOpenKeyExW(hClassKey, pszClassGuid, 0, KEY_READ, &hInstKey); if (lError != ERROR_SUCCESS) { *pulLength = 0; ret = CR_NO_SUCH_REGISTRY_KEY; goto done; }
lError = RegOpenKeyExW(hInstKey, L"Properties", 0, KEY_READ, &hPropKey); if (lError != ERROR_SUCCESS) { *pulLength = 0; ret = CR_NO_SUCH_REGISTRY_KEY; goto done; }
lError = RegQueryValueExW(hPropKey, lpValueName, NULL, pulRegDataType, Buffer, pulLength); if (lError != ERROR_SUCCESS) { if (lError == ERROR_MORE_DATA) { ret = CR_BUFFER_SMALL; } else { *pulLength = 0; ret = CR_NO_SUCH_VALUE; } }
done: if (ret == CR_SUCCESS) *pulTransferLen = *pulLength;
if (hPropKey != NULL) RegCloseKey(hPropKey);
if (hInstKey != NULL) RegCloseKey(hInstKey);
DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret);
return ret;}
/* Function 27 */DWORDWINAPIPNP_SetClassRegProp( handle_t hBinding, LPWSTR pszClassGuid, DWORD ulProperty, DWORD ulDataType, BYTE *Buffer, PNP_PROP_SIZE ulLength, DWORD ulFlags){ CONFIGRET ret = CR_SUCCESS; LPWSTR lpValueName = NULL; HKEY hInstKey = 0; HKEY hPropKey = 0; LONG lError;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_SetClassRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n", hBinding, pszClassGuid, ulProperty, ulDataType, Buffer, ulLength, ulFlags);
if (ulFlags != 0) return CR_INVALID_FLAG;
switch (ulProperty) { case CM_CRP_SECURITY: lpValueName = L"Security"; break;
case CM_CRP_DEVTYPE: lpValueName = L"DeviceType"; break;
case CM_CRP_EXCLUSIVE: lpValueName = L"Exclusive"; break;
case CM_CRP_CHARACTERISTICS: lpValueName = L"DeviceCharacteristics"; break;
default: return CR_INVALID_PROPERTY; }
lError = RegOpenKeyExW(hClassKey, pszClassGuid, 0, KEY_WRITE, &hInstKey); if (lError != ERROR_SUCCESS) { ret = CR_NO_SUCH_REGISTRY_KEY; goto done; }
/* FIXME: Set security descriptor */ lError = RegCreateKeyExW(hInstKey, L"Properties", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hPropKey, NULL); if (lError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
if (ulLength == 0) { if (RegDeleteValueW(hPropKey, lpValueName)) ret = CR_REGISTRY_ERROR; } else { if (RegSetValueExW(hPropKey, lpValueName, 0, ulDataType, Buffer, ulLength)) ret = CR_REGISTRY_ERROR; }
done: if (hPropKey != NULL) RegCloseKey(hPropKey);
if (hInstKey != NULL) RegCloseKey(hInstKey);
return ret;}
staticCONFIGRETCreateDeviceInstance( _In_ LPWSTR pszDeviceID, _In_ BOOL bPhantomDevice){ WCHAR szEnumerator[MAX_DEVICE_ID_LEN]; WCHAR szDevice[MAX_DEVICE_ID_LEN]; WCHAR szInstance[MAX_DEVICE_ID_LEN]; HKEY hKeyEnumerator; HKEY hKeyDevice; HKEY hKeyInstance; HKEY hKeyControl; LONG lError;
/* Split the instance ID */ SplitDeviceInstanceID(pszDeviceID, szEnumerator, szDevice, szInstance);
/* Open or create the enumerator key */ lError = RegCreateKeyExW(hEnumKey, szEnumerator, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyEnumerator, NULL); if (lError != ERROR_SUCCESS) { return CR_REGISTRY_ERROR; }
/* Open or create the device key */ lError = RegCreateKeyExW(hKeyEnumerator, szDevice, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyDevice, NULL);
/* Close the enumerator key */ RegCloseKey(hKeyEnumerator);
if (lError != ERROR_SUCCESS) { return CR_REGISTRY_ERROR; }
/* Try to open the instance key and fail if it exists */ lError = RegOpenKeyExW(hKeyDevice, szInstance, 0, KEY_SET_VALUE, &hKeyInstance); if (lError == ERROR_SUCCESS) { DPRINT1("Instance %S already exists!\n", szInstance); RegCloseKey(hKeyInstance); RegCloseKey(hKeyDevice); return CR_ALREADY_SUCH_DEVINST; }
/* Create a new instance key */ lError = RegCreateKeyExW(hKeyDevice, szInstance, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyInstance, NULL);
/* Close the device key */ RegCloseKey(hKeyDevice);
if (lError != ERROR_SUCCESS) { return CR_REGISTRY_ERROR; }
if (bPhantomDevice) { DWORD dwPhantomValue = 1; RegSetValueExW(hKeyInstance, L"Phantom", 0, REG_DWORD, (PBYTE)&dwPhantomValue, sizeof(dwPhantomValue)); }
/* Create the 'Control' sub key */ lError = RegCreateKeyExW(hKeyInstance, L"Control", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyControl, NULL); if (lError == ERROR_SUCCESS) { RegCloseKey(hKeyControl); }
RegCloseKey(hKeyInstance);
return (lError == ERROR_SUCCESS) ? CR_SUCCESS : CR_REGISTRY_ERROR;}
staticCONFIGRETGenerateDeviceID( _Inout_ LPWSTR pszDeviceID, _In_ PNP_RPC_STRING_LEN ulLength){ WCHAR szGeneratedInstance[MAX_DEVICE_ID_LEN]; HKEY hKey; DWORD dwInstanceNumber; DWORD dwError = ERROR_SUCCESS; CONFIGRET ret = CR_SUCCESS;
/* Fail, if the device name contains backslashes */ if (wcschr(pszDeviceID, L'\\') != NULL) return CR_INVALID_DEVICE_ID;
/* Generated ID is: Root\<Device ID>\<Instance number> */ dwInstanceNumber = 0; while (dwError == ERROR_SUCCESS) { if (dwInstanceNumber >= 10000) return CR_FAILURE;
swprintf(szGeneratedInstance, L"Root\\%ls\\%04lu", pszDeviceID, dwInstanceNumber);
/* Try to open the enum key of the device instance */ dwError = RegOpenKeyEx(hEnumKey, szGeneratedInstance, 0, KEY_QUERY_VALUE, &hKey); if (dwError == ERROR_SUCCESS) { RegCloseKey(hKey); dwInstanceNumber++; } }
/* pszDeviceID is an out parameter too for generated IDs */ if (wcslen(szGeneratedInstance) > ulLength) { ret = CR_BUFFER_SMALL; } else { wcscpy(pszDeviceID, szGeneratedInstance); }
return ret;}
/* Function 28 */DWORDWINAPIPNP_CreateDevInst( handle_t hBinding, LPWSTR pszDeviceID, LPWSTR pszParentDeviceID, PNP_RPC_STRING_LEN ulLength, DWORD ulFlags){ PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData; HKEY hKey = NULL; DWORD dwSize, dwPhantom; NTSTATUS Status; CONFIGRET ret = CR_SUCCESS;
DPRINT("PNP_CreateDevInst(%p %S %S %lu 0x%08lx)\n", hBinding, pszParentDeviceID, pszDeviceID, ulLength, ulFlags);
if (ulFlags & ~CM_CREATE_DEVNODE_BITS) return CR_INVALID_FLAG;
if (pszDeviceID == NULL || pszParentDeviceID == NULL) return CR_INVALID_POINTER;
/* Fail, if the parent device is not the root device */ if (!IsRootDeviceInstanceID(pszParentDeviceID)) return CR_INVALID_DEVINST;
if (ulFlags & CM_CREATE_DEVNODE_GENERATE_ID) { ret = GenerateDeviceID(pszDeviceID, ulLength); if (ret != CR_SUCCESS) return ret; }
/* Try to open the device instance key */ RegOpenKeyEx(hEnumKey, pszDeviceID, 0, KEY_READ | KEY_WRITE, &hKey);
if (ulFlags & CM_CREATE_DEVNODE_PHANTOM) { /* Fail, if the device already exists */ if (hKey != NULL) { ret = CR_ALREADY_SUCH_DEVINST; goto done; }
/* Create the phantom device instance */ ret = CreateDeviceInstance(pszDeviceID, TRUE); } else { /* Fail, if the device exists and is present */ if ((hKey != NULL) && (IsPresentDeviceInstanceID(pszDeviceID))) { ret = CR_ALREADY_SUCH_DEVINST; goto done; }
/* If it does not already exist ... */ if (hKey == NULL) { /* Create the device instance */ ret = CreateDeviceInstance(pszDeviceID, FALSE);
/* Open the device instance key */ RegOpenKeyEx(hEnumKey, pszDeviceID, 0, KEY_READ | KEY_WRITE, &hKey); }
/* Create a device node for the device */ RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceID); Status = NtPlugPlayControl(PlugPlayControlInitializeDevice, &ControlData, sizeof(ControlData)); if (!NT_SUCCESS(Status)) { ret = CR_FAILURE; goto done; }
/* If the device is a phantom device, turn it into a normal device */ if (hKey != NULL) { dwPhantom = 0; dwSize = sizeof(DWORD); RegQueryValueEx(hKey, L"Phantom", NULL, NULL, (PBYTE)&dwPhantom, &dwSize);
if (dwPhantom != 0) RegDeleteValue(hKey, L"Phantom"); } }
done: if (hKey) RegCloseKey(hKey);
DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret);
return ret;}
static CONFIGRETSetupDeviceInstance( _In_ LPWSTR pszDeviceInstance, _In_ DWORD ulMinorAction){ PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData; HKEY hDeviceKey = NULL; DWORD dwDisableCount, dwSize; DWORD ulStatus, ulProblem; DWORD dwError; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
DPRINT1("SetupDeviceInstance(%S 0x%08lx)\n", pszDeviceInstance, ulMinorAction);
if (IsRootDeviceInstanceID(pszDeviceInstance)) return CR_INVALID_DEVINST;
if (ulMinorAction & ~CM_SETUP_BITS) return CR_INVALID_FLAG;
if ((ulMinorAction == CM_SETUP_DOWNLOAD) || (ulMinorAction == CM_SETUP_WRITE_LOG_CONFS)) return CR_SUCCESS;
dwError = RegOpenKeyExW(hEnumKey, pszDeviceInstance, 0, KEY_READ, &hDeviceKey); if (dwError != ERROR_SUCCESS) return CR_INVALID_DEVNODE;
dwSize = sizeof(dwDisableCount); dwError = RegQueryValueExW(hDeviceKey, L"DisableCount", NULL, NULL, (LPBYTE)&dwDisableCount, &dwSize); if ((dwError == ERROR_SUCCESS) && (dwDisableCount > 0)) { goto done; }
GetDeviceStatus(pszDeviceInstance, &ulStatus, &ulProblem);
if (ulStatus & DN_STARTED) { goto done; }
if (ulStatus & DN_HAS_PROBLEM) { ret = ClearDeviceStatus(pszDeviceInstance, DN_HAS_PROBLEM, ulProblem); }
if (ret != CR_SUCCESS) goto done;
/* Start the device */ RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceInstance); Status = NtPlugPlayControl(PlugPlayControlStartDevice, &ControlData, sizeof(PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status);
done: if (hDeviceKey != NULL) RegCloseKey(hDeviceKey);
return ret;}
static CONFIGRETEnableDeviceInstance( _In_ LPWSTR pszDeviceInstance){ PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
DPRINT("Enable device instance %S\n", pszDeviceInstance);
RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceInstance); Status = NtPlugPlayControl(PlugPlayControlStartDevice, &ControlData, sizeof(ControlData)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status);
return ret;}
static CONFIGRETReenumerateDeviceInstance( _In_ LPWSTR pszDeviceInstance, _In_ ULONG ulMinorAction){ PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status;
DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n", pszDeviceInstance, ulMinorAction);
if (ulMinorAction & ~CM_REENUMERATE_BITS) return CR_INVALID_FLAG;
if (ulMinorAction & CM_REENUMERATE_RETRY_INSTALLATION) { DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n"); }
RtlInitUnicodeString(&EnumerateDeviceData.DeviceInstance, pszDeviceInstance); EnumerateDeviceData.Flags = 0;
Status = NtPlugPlayControl(PlugPlayControlEnumerateDevice, &EnumerateDeviceData, sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status);
return ret;}
/* Function 29 */DWORDWINAPIPNP_DeviceInstanceAction( handle_t hBinding, DWORD ulMajorAction, DWORD ulMinorAction, LPWSTR pszDeviceInstance1, LPWSTR pszDeviceInstance2){ CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_DeviceInstanceAction(%p %lu 0x%08lx %S %S)\n", hBinding, ulMajorAction, ulMinorAction, pszDeviceInstance1, pszDeviceInstance2);
switch (ulMajorAction) { case PNP_DEVINST_SETUP: ret = SetupDeviceInstance(pszDeviceInstance1, ulMinorAction); break;
case PNP_DEVINST_ENABLE: ret = EnableDeviceInstance(pszDeviceInstance1); break;
case PNP_DEVINST_REENUMERATE: ret = ReenumerateDeviceInstance(pszDeviceInstance1, ulMinorAction); break;
default: DPRINT1("Unknown device action %lu: not implemented\n", ulMajorAction); ret = CR_CALL_NOT_IMPLEMENTED; }
DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret);
return ret;}
/* Function 30 */DWORDWINAPIPNP_GetDeviceStatus( handle_t hBinding, LPWSTR pDeviceID, DWORD *pulStatus, DWORD *pulProblem, DWORD ulFlags){ DWORD ulDataType, ulTransferLength, ulLength; DWORD ulCapabilities, ulConfigFlags; CONFIGRET ret;
UNREFERENCED_PARAMETER(hBinding); UNREFERENCED_PARAMETER(ulFlags);
DPRINT("PNP_GetDeviceStatus(%p %S %p %p 0x%08lx)\n", hBinding, pDeviceID, pulStatus, pulProblem, ulFlags);
if (ulFlags != 0) return CR_INVALID_FLAG;
if ((pulStatus == NULL) || (pulProblem == NULL)) return CR_INVALID_POINTER;
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
ret = GetDeviceStatus(pDeviceID, pulStatus, pulProblem); if (ret != CR_SUCCESS) return ret;
/* Check for DN_REMOVABLE */ ulTransferLength = sizeof(ulCapabilities); ulLength = sizeof(ulCapabilities); ret = PNP_GetDeviceRegProp(NULL, pDeviceID, CM_DRP_CAPABILITIES, &ulDataType, (PBYTE)&ulCapabilities, &ulTransferLength, &ulLength, 0); if (ret != CR_SUCCESS) ulCapabilities = 0;
if (ulCapabilities & CM_DEVCAP_REMOVABLE) *pulStatus |= DN_REMOVABLE;
/* Check for DN_MANUAL */ ulTransferLength = sizeof(ulConfigFlags); ulLength = sizeof(ulConfigFlags); ret = PNP_GetDeviceRegProp(NULL, pDeviceID, CM_DRP_CONFIGFLAGS, &ulDataType, (PBYTE)&ulConfigFlags, &ulTransferLength, &ulLength, 0); if (ret != CR_SUCCESS) ulConfigFlags = 0;
if (ulConfigFlags & CONFIGFLAG_MANUAL_INSTALL) *pulStatus |= DN_MANUAL;
/* Check for failed install */ if (((*pulStatus & DN_HAS_PROBLEM) == 0) && (ulConfigFlags & CONFIGFLAG_FAILEDINSTALL)) { *pulStatus |= DN_HAS_PROBLEM; *pulProblem = CM_PROB_FAILED_INSTALL; }
return CR_SUCCESS;}
/* Function 31 */DWORDWINAPIPNP_SetDeviceProblem( handle_t hBinding, LPWSTR pDeviceID, DWORD ulProblem, DWORD ulFlags){ ULONG ulOldStatus, ulOldProblem; CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT1("PNP_SetDeviceProblem(%p %S %lu 0x%08lx)\n", hBinding, pDeviceID, ulProblem, ulFlags);
if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
ret = GetDeviceStatus(pDeviceID, &ulOldStatus, &ulOldProblem); if (ret != CR_SUCCESS) return ret;
if (((ulFlags & CM_SET_DEVNODE_PROBLEM_OVERRIDE) == 0) && (ulOldProblem != 0) && (ulOldProblem != ulProblem)) { return CR_FAILURE; }
if (ulProblem == 0) { ret = ClearDeviceStatus(pDeviceID, DN_HAS_PROBLEM, ulOldProblem); } else { ret = SetDeviceStatus(pDeviceID, DN_HAS_PROBLEM, ulProblem); }
return ret;}
/* Function 32 */DWORDWINAPIPNP_DisableDevInst( handle_t hBinding, LPWSTR pDeviceID, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, DWORD ulNameLength, DWORD ulFlags){ UNREFERENCED_PARAMETER(hBinding);
DPRINT1("PNP_DisableDevInst(%p %S %p %p %lu 0x%08lx)\n", hBinding, pDeviceID, pVetoType, pszVetoName, ulNameLength, ulFlags);
if (ulFlags & ~CM_DISABLE_BITS) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pDeviceID) || IsRootDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
return DisableDeviceInstance(pDeviceID, pVetoType, pszVetoName, ulNameLength);}
/* Function 33 */DWORDWINAPIPNP_UninstallDevInst( handle_t hBinding, LPWSTR pDeviceID, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
static BOOLCheckForDeviceId(LPWSTR lpDeviceIdList, LPWSTR lpDeviceId){ LPWSTR lpPtr; DWORD dwLength;
lpPtr = lpDeviceIdList; while (*lpPtr != 0) { dwLength = wcslen(lpPtr); if (0 == _wcsicmp(lpPtr, lpDeviceId)) return TRUE;
lpPtr += (dwLength + 1); }
return FALSE;}
static VOIDAppendDeviceId(LPWSTR lpDeviceIdList, LPDWORD lpDeviceIdListSize, LPWSTR lpDeviceId){ DWORD dwLen; DWORD dwPos;
dwLen = wcslen(lpDeviceId); dwPos = (*lpDeviceIdListSize / sizeof(WCHAR)) - 1;
wcscpy(&lpDeviceIdList[dwPos], lpDeviceId);
dwPos += (dwLen + 1);
lpDeviceIdList[dwPos] = 0;
*lpDeviceIdListSize = dwPos * sizeof(WCHAR);}
/* Function 34 */DWORDWINAPIPNP_AddID( handle_t hBinding, LPWSTR pszDeviceID, LPWSTR pszID, DWORD ulFlags){ CONFIGRET ret = CR_SUCCESS; HKEY hDeviceKey; LPWSTR pszSubKey; DWORD dwDeviceIdListSize; DWORD dwNewDeviceIdSize; WCHAR * pszDeviceIdList = NULL;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_AddID(%p %S %S 0x%08lx)\n", hBinding, pszDeviceID, pszID, ulFlags);
if (RegOpenKeyExW(hEnumKey, pszDeviceID, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hDeviceKey) != ERROR_SUCCESS) { DPRINT("Failed to open the device key!\n"); return CR_INVALID_DEVNODE; }
pszSubKey = (ulFlags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID";
if (RegQueryValueExW(hDeviceKey, pszSubKey, NULL, NULL, NULL, &dwDeviceIdListSize) != ERROR_SUCCESS) { DPRINT("Failed to query the desired ID string!\n"); ret = CR_REGISTRY_ERROR; goto Done; }
dwNewDeviceIdSize = lstrlenW(pszDeviceID); if (!dwNewDeviceIdSize) { ret = CR_INVALID_POINTER; goto Done; }
dwDeviceIdListSize += (dwNewDeviceIdSize + 2) * sizeof(WCHAR);
pszDeviceIdList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeviceIdListSize); if (!pszDeviceIdList) { DPRINT("Failed to allocate memory for the desired ID string!\n"); ret = CR_OUT_OF_MEMORY; goto Done; }
if (RegQueryValueExW(hDeviceKey, pszSubKey, NULL, NULL, (LPBYTE)pszDeviceIdList, &dwDeviceIdListSize) != ERROR_SUCCESS) { DPRINT("Failed to query the desired ID string!\n"); ret = CR_REGISTRY_ERROR; goto Done; }
/* Check whether the device ID is already in use */ if (CheckForDeviceId(pszDeviceIdList, pszDeviceID)) { DPRINT("Device ID was found in the ID string!\n"); ret = CR_SUCCESS; goto Done; }
/* Append the Device ID */ AppendDeviceId(pszDeviceIdList, &dwDeviceIdListSize, pszID);
if (RegSetValueExW(hDeviceKey, pszSubKey, 0, REG_MULTI_SZ, (LPBYTE)pszDeviceIdList, dwDeviceIdListSize) != ERROR_SUCCESS) { DPRINT("Failed to set the desired ID string!\n"); ret = CR_REGISTRY_ERROR; }
Done: RegCloseKey(hDeviceKey); if (pszDeviceIdList) HeapFree(GetProcessHeap(), 0, pszDeviceIdList);
DPRINT("PNP_AddID() done (returns %lx)\n", ret);
return ret;}
/* Function 35 */DWORDWINAPIPNP_RegisterDriver( handle_t hBinding, LPWSTR pszDeviceID, DWORD ulFlags){ DPRINT("PNP_RegisterDriver(%p %S 0x%lx)\n", hBinding, pszDeviceID, ulFlags);
if (ulFlags & ~CM_REGISTER_DEVICE_DRIVER_BITS) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pszDeviceID)) return CR_INVALID_DEVINST;
SetDeviceStatus(pszDeviceID, 0, 0);
return CR_SUCCESS;}
/* Function 36 */DWORDWINAPIPNP_QueryRemove( handle_t hBinding, LPWSTR pszDeviceID, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, DWORD ulNameLength, DWORD ulFlags){ PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData; NTSTATUS Status; DWORD ret = CR_SUCCESS;
DPRINT1("PNP_QueryRemove(%p %S %p %p %lu 0x%lx)\n", hBinding, pszDeviceID, pVetoType, pszVetoName, ulNameLength, ulFlags);
if (ulFlags & ~CM_REMOVE_BITS) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pszDeviceID) || IsRootDeviceInstanceID(pszDeviceID)) return CR_INVALID_DEVINST;
if (pVetoType != NULL) *pVetoType = PNP_VetoTypeUnknown;
if (pszVetoName != NULL && ulNameLength > 0) *pszVetoName = UNICODE_NULL;
RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData)); RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID); PlugPlayData.VetoName = pszVetoName; PlugPlayData.NameLength = ulNameLength;// PlugPlayData.Flags =
Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice, &PlugPlayData, sizeof(PlugPlayData)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status);
return ret;}
/* Function 37 */DWORDWINAPIPNP_RequestDeviceEject( handle_t hBinding, LPWSTR pszDeviceID, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, DWORD ulNameLength, DWORD ulFlags){ PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData; NTSTATUS Status; DWORD ret = CR_SUCCESS;
DPRINT1("PNP_RequestDeviceEject(%p %S %p %p %lu 0x%lx)\n", hBinding, pszDeviceID, pVetoType, pszVetoName, ulNameLength, ulFlags);
if (ulFlags != 0) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pszDeviceID)) return CR_INVALID_DEVINST;
if (pVetoType != NULL) *pVetoType = PNP_VetoTypeUnknown;
if (pszVetoName != NULL && ulNameLength > 0) *pszVetoName = UNICODE_NULL;
RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData)); RtlInitUnicodeString(&PlugPlayData.DeviceInstance, pszDeviceID); PlugPlayData.VetoName = pszVetoName; PlugPlayData.NameLength = ulNameLength;// PlugPlayData.Flags =
Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice, &PlugPlayData, sizeof(PlugPlayData)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status);
return ret;}
/* Function 38 */CONFIGRETWINAPIPNP_IsDockStationPresent( handle_t hBinding, BOOL *Present){ HKEY hKey; DWORD dwType; DWORD dwValue; DWORD dwSize; CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT1("PNP_IsDockStationPresent(%p %p)\n", hBinding, Present);
*Present = FALSE;
if (RegOpenKeyExW(HKEY_CURRENT_CONFIG, L"CurrentDockInfo", 0, KEY_READ, &hKey) != ERROR_SUCCESS) return CR_REGISTRY_ERROR;
dwSize = sizeof(DWORD); if (RegQueryValueExW(hKey, L"DockingState", NULL, &dwType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS) ret = CR_REGISTRY_ERROR;
RegCloseKey(hKey);
if (ret == CR_SUCCESS) { if (dwType != REG_DWORD || dwSize != sizeof(DWORD)) { ret = CR_REGISTRY_ERROR; } else if (dwValue != 0) { *Present = TRUE; } }
DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret);
return ret;}
/* Function 39 */DWORDWINAPIPNP_RequestEjectPC( handle_t hBinding){ WCHAR szDockDeviceInstance[MAX_DEVICE_ID_LEN]; PLUGPLAY_CONTROL_RETRIEVE_DOCK_DATA DockData; NTSTATUS Status;
DPRINT("PNP_RequestEjectPC(%p)\n", hBinding);
/* Retrieve the dock device */ DockData.DeviceInstanceLength = ARRAYSIZE(szDockDeviceInstance); DockData.DeviceInstance = szDockDeviceInstance;
Status = NtPlugPlayControl(PlugPlayControlRetrieveDock, &DockData, sizeof(DockData)); if (!NT_SUCCESS(Status)) return NtStatusToCrError(Status);
/* Eject the dock device */ return PNP_RequestDeviceEject(hBinding, szDockDeviceInstance, NULL, NULL, 0, 0);}
/* Function 40 */DWORDWINAPIPNP_HwProfFlags( handle_t hBinding, DWORD ulAction, LPWSTR pDeviceID, DWORD ulConfig, DWORD *pulValue, PPNP_VETO_TYPE pVetoType, LPWSTR pszVetoName, DWORD ulNameLength, DWORD ulFlags){ CONFIGRET ret = CR_SUCCESS; WCHAR szKeyName[MAX_PATH]; HKEY hKey; HKEY hDeviceKey; DWORD dwSize;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_HwProfFlags() called\n");
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
if (ulConfig == 0) { wcscpy(szKeyName, L"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum"); } else { swprintf(szKeyName, L"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum", ulConfig); }
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) return CR_REGISTRY_ERROR;
if (ulAction == PNP_GET_HWPROFFLAGS) { if (RegOpenKeyExW(hKey, pDeviceID, 0, KEY_QUERY_VALUE, &hDeviceKey) != ERROR_SUCCESS) { *pulValue = 0; } else { dwSize = sizeof(DWORD); if (RegQueryValueExW(hDeviceKey, L"CSConfigFlags", NULL, NULL, (LPBYTE)pulValue, &dwSize) != ERROR_SUCCESS) { *pulValue = 0; }
RegCloseKey(hDeviceKey); } } else if (ulAction == PNP_SET_HWPROFFLAGS) { /* FIXME: not implemented yet */ ret = CR_CALL_NOT_IMPLEMENTED; }
RegCloseKey(hKey);
return ret;}
/* Function 41 */DWORDWINAPIPNP_GetHwProfInfo( handle_t hBinding, DWORD ulIndex, HWPROFILEINFO *pHWProfileInfo, DWORD ulProfileInfoSize, DWORD ulFlags){ WCHAR szProfileName[5]; HKEY hKeyConfig = NULL; HKEY hKeyProfiles = NULL; HKEY hKeyProfile = NULL; DWORD dwDisposition; DWORD dwSize; LONG lError; CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetHwProfInfo() called\n");
if (ulProfileInfoSize == 0) { ret = CR_INVALID_DATA; goto done; }
if (ulFlags != 0) { ret = CR_INVALID_FLAG; goto done; }
/* Initialize the profile information */ pHWProfileInfo->HWPI_ulHWProfile = 0; pHWProfileInfo->HWPI_szFriendlyName[0] = 0; pHWProfileInfo->HWPI_dwFlags = 0;
/* Open the 'IDConfigDB' key */ lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\IDConfigDB", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, &hKeyConfig, &dwDisposition); if (lError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
/* Open the 'Hardware Profiles' subkey */ lError = RegCreateKeyExW(hKeyConfig, L"Hardware Profiles", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, NULL, &hKeyProfiles, &dwDisposition); if (lError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
if (ulIndex == (ULONG)-1) { dwSize = sizeof(ULONG); lError = RegQueryValueExW(hKeyConfig, L"CurrentConfig", NULL, NULL, (LPBYTE)&pHWProfileInfo->HWPI_ulHWProfile, &dwSize); if (lError != ERROR_SUCCESS) { pHWProfileInfo->HWPI_ulHWProfile = 0; ret = CR_REGISTRY_ERROR; goto done; } } else { /* FIXME: not implemented yet */ ret = CR_CALL_NOT_IMPLEMENTED; goto done; }
swprintf(szProfileName, L"%04lu", pHWProfileInfo->HWPI_ulHWProfile);
lError = RegOpenKeyExW(hKeyProfiles, szProfileName, 0, KEY_QUERY_VALUE, &hKeyProfile); if (lError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
dwSize = sizeof(pHWProfileInfo->HWPI_szFriendlyName); lError = RegQueryValueExW(hKeyProfile, L"FriendlyName", NULL, NULL, (LPBYTE)&pHWProfileInfo->HWPI_szFriendlyName, &dwSize); if (lError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
done: if (hKeyProfile != NULL) RegCloseKey(hKeyProfile);
if (hKeyProfiles != NULL) RegCloseKey(hKeyProfiles);
if (hKeyConfig != NULL) RegCloseKey(hKeyConfig);
return ret;}
/* Function 42 */DWORDWINAPIPNP_AddEmptyLogConf( handle_t hBinding, LPWSTR pDeviceID, DWORD ulPriority, DWORD *pulLogConfTag, DWORD ulFlags){ HKEY hConfigKey = NULL; DWORD RegDataType = 0; ULONG ulDataSize = 0, ulNewSize = 0; PBYTE pDataBuffer = NULL; WCHAR szValueNameBuffer[LOGCONF_NAME_BUFFER_SIZE]; CONFIGRET ret = CR_SUCCESS;
DPRINT("PNP_AddEmptyLogConf(%p %S %lu %p 0x%08lx)\n", hBinding, pDeviceID, ulPriority, pulLogConfTag, ulFlags);
if (pulLogConfTag == NULL) return CR_INVALID_POINTER;
*pulLogConfTag = 0;
if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT)) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pDeviceID) || IsRootDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVNODE;
ret = OpenConfigurationKey(pDeviceID, ulFlags & LOG_CONF_BITS, &hConfigKey); if (ret != CR_SUCCESS) { DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); ret = CR_NO_MORE_LOG_CONF; goto done; }
ret = GetConfigurationData(hConfigKey, ulFlags & LOG_CONF_BITS, &RegDataType, &ulDataSize, &pDataBuffer, LOGCONF_NAME_BUFFER_SIZE, szValueNameBuffer);
if (ret != CR_SUCCESS || ulDataSize == 0) { ret = CR_SUCCESS;
if (RegDataType == REG_RESOURCE_LIST) { PCM_RESOURCE_LIST pResourceList = NULL; PCM_FULL_RESOURCE_DESCRIPTOR pResource = NULL;
/* Allocate a buffer for the new configuration */ ulDataSize = sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); pDataBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulDataSize); if (pDataBuffer == NULL) { ret = CR_OUT_OF_MEMORY; goto done; }
pResourceList = (PCM_RESOURCE_LIST)pDataBuffer; pResourceList->Count = 1;
pResource = (PCM_FULL_RESOURCE_DESCRIPTOR)&pResourceList->List[0]; pResource->InterfaceType = InterfaceTypeUndefined; pResource->BusNumber = 0; pResource->PartialResourceList.Version = 1; pResource->PartialResourceList.Revision = 1; pResource->PartialResourceList.Count = 0; } else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) { PIO_RESOURCE_REQUIREMENTS_LIST pRequirementsList = NULL; PIO_RESOURCE_LIST pResourceList = NULL;
ulDataSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST); pDataBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulDataSize); if (pDataBuffer == NULL) { ret = CR_OUT_OF_MEMORY; goto done; }
pRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST)pDataBuffer; pRequirementsList->ListSize = ulDataSize; pRequirementsList->InterfaceType = InterfaceTypeUndefined; pRequirementsList->BusNumber = 0; pRequirementsList->SlotNumber = 0; pRequirementsList->AlternativeLists = 1;
pResourceList = (PIO_RESOURCE_LIST)&pRequirementsList->List[0]; pResourceList->Version = 1; pResourceList->Revision = 1; pResourceList->Count = 1;
pResourceList->Descriptors[0].Option = IO_RESOURCE_PREFERRED; pResourceList->Descriptors[0].Type = CmResourceTypeConfigData; pResourceList->Descriptors[0].u.ConfigData.Priority = ulPriority; } else { ret = CR_FAILURE; goto done; } } else { if (RegDataType == REG_RESOURCE_LIST) { PCM_RESOURCE_LIST pResourceList = NULL; PCM_FULL_RESOURCE_DESCRIPTOR pResource = NULL; ULONG ulIndex;
/* Reallocate a larger buffer in order to add the new configuration */ ulNewSize = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); pDataBuffer = HeapReAlloc(GetProcessHeap(), 0, pDataBuffer, ulDataSize + ulNewSize); if (pDataBuffer == NULL) { ret = CR_OUT_OF_MEMORY; goto done; }
pResourceList = (PCM_RESOURCE_LIST)pDataBuffer;
/* Get a pointer to the new (uninitialized) resource descriptor */ pResource = (PCM_FULL_RESOURCE_DESCRIPTOR)&pResourceList->List[0]; for (ulIndex = 0; ulIndex < pResourceList->Count; ulIndex++) pResource = NextResourceDescriptor(pResource);
/* Initialize the new resource descriptor */ pResourceList->Count++; pResource->InterfaceType= InterfaceTypeUndefined; pResource->BusNumber = 0; pResource->PartialResourceList.Version = 1; pResource->PartialResourceList.Revision = 1; pResource->PartialResourceList.Count = 0;
*pulLogConfTag = ulIndex; } else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) { PIO_RESOURCE_REQUIREMENTS_LIST pRequirementsList = NULL; PIO_RESOURCE_LIST pResourceList = NULL; ULONG ulIndex;
/* Reallocate a larger buffer in order to add the new configuration */ ulNewSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST); pDataBuffer = HeapReAlloc(GetProcessHeap(), 0, pDataBuffer, ulDataSize + ulNewSize); if (pDataBuffer == NULL) { ret = CR_OUT_OF_MEMORY; goto done; }
pRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST)pDataBuffer; pResourceList = (PIO_RESOURCE_LIST)&pRequirementsList->List[0]; for (ulIndex = 0; ulIndex < pRequirementsList->AlternativeLists - 1; ulIndex++) pResourceList = NextResourceRequirement(pResourceList);
pRequirementsList->ListSize = ulDataSize + ulNewSize; pRequirementsList->AlternativeLists++;
pResourceList->Version = 1; pResourceList->Revision = 1; pResourceList->Count = 1;
pResourceList->Descriptors[0].Option = IO_RESOURCE_PREFERRED; pResourceList->Descriptors[0].Type = CmResourceTypeConfigData; pResourceList->Descriptors[0].u.ConfigData.Priority = ulPriority;
*pulLogConfTag = ulIndex; } else { ret = CR_FAILURE; goto done; } }
/* Store the configuration */ if (RegSetValueEx(hConfigKey, szValueNameBuffer, 0, RegDataType, pDataBuffer, ulDataSize + ulNewSize) != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
done: if (pDataBuffer != NULL) HeapFree(GetProcessHeap(), 0, pDataBuffer);
if (hConfigKey != NULL) RegCloseKey(hConfigKey);
DPRINT("PNP_AddEmptyLogConf() returns %lu\n", ret);
return ret;}
/* Function 43 */DWORDWINAPIPNP_FreeLogConf( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfType, DWORD ulLogConfTag, DWORD ulFlags){ HKEY hConfigKey = NULL; DWORD RegDataType = 0; ULONG ulDataSize = 0; LPBYTE pDataBuffer = NULL; WCHAR szValueNameBuffer[LOGCONF_NAME_BUFFER_SIZE]; CONFIGRET ret = CR_SUCCESS;
DPRINT("PNP_FreeLogConf(%p %S %lu %lu 0x%08lx)\n", hBinding, pDeviceID, ulLogConfType, ulLogConfTag, ulFlags);
if (ulFlags != 0) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVNODE;
ret = OpenConfigurationKey(pDeviceID, ulLogConfType, &hConfigKey); if (ret != CR_SUCCESS) { DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); ret = CR_NO_MORE_LOG_CONF; goto done; }
ret = GetConfigurationData(hConfigKey, ulLogConfType, &RegDataType, &ulDataSize, &pDataBuffer, LOGCONF_NAME_BUFFER_SIZE, szValueNameBuffer); if (ret != CR_SUCCESS) { ret = CR_INVALID_LOG_CONF; goto done; }
if (RegDataType == REG_RESOURCE_LIST) { PCM_RESOURCE_LIST pResourceList = (PCM_RESOURCE_LIST)pDataBuffer;
if (pResourceList->Count <= 1) { /* Delete the key if there is only one or no configuration in the key */ DPRINT("Delete value %S\n", szValueNameBuffer); RegDeleteValue(hConfigKey, szValueNameBuffer); } else { PCM_FULL_RESOURCE_DESCRIPTOR pResource = NULL, pNextResource = NULL; ULONG ulIndex, ulMoveSize; DWORD dwError;
/* Fail if we try to delete an entry outside of our resource list */ if (ulLogConfTag >= pResourceList->Count) { ret = CR_INVALID_LOG_CONF; goto done; }
/* Get a pointer to the resource descriptor to be deleted */ pResource = (PCM_FULL_RESOURCE_DESCRIPTOR)&pResourceList->List[0]; for (ulIndex = 0; ulIndex < ulLogConfTag; ulIndex++) pResource = NextResourceDescriptor(pResource);
/* Delete the resource descriptor */ if (ulLogConfTag == pResourceList->Count - 1) { /* Delete the last resource descriptor */ ulDataSize = (ULONG)((ULONG_PTR)pResource - (ULONG_PTR)pResourceList); } else { pNextResource = NextResourceDescriptor(pResource);
ulMoveSize = ulDataSize - (DWORD)((ULONG_PTR)pNextResource - (ULONG_PTR)pResourceList); MoveMemory(pResource, pNextResource, ulMoveSize);
ulDataSize -= (DWORD)((ULONG_PTR)pNextResource - (ULONG_PTR)pResource); }
pResourceList->Count--;
/* Store the new configuration */ dwError = RegSetValueEx(hConfigKey, szValueNameBuffer, 0, RegDataType, pDataBuffer, ulDataSize); if (dwError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; } } } else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) { if (((PIO_RESOURCE_REQUIREMENTS_LIST)pDataBuffer)->AlternativeLists <= 1) { /* Delete the key if there is only one or no configuration in the key */ DPRINT("Delete value %S\n", szValueNameBuffer); RegDeleteValue(hConfigKey, szValueNameBuffer); } else { /* FIXME */ } } else { ret = CR_FAILURE; goto done; }
done: if (pDataBuffer != NULL) HeapFree(GetProcessHeap(), 0, pDataBuffer);
if (hConfigKey != NULL) RegCloseKey(hConfigKey);
DPRINT("PNP_FreeLogConf() returns %lu\n", ret);
return ret;}
/* Function 44 */DWORDWINAPIPNP_GetFirstLogConf( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfType, DWORD *pulLogConfTag, DWORD ulFlags){ HKEY hConfigKey = NULL; DWORD RegDataType = 0; ULONG ulDataSize = 0; LPBYTE lpData = NULL; CONFIGRET ret = CR_SUCCESS;
DPRINT("PNP_GetFirstLogConf(%p %S %lu %p 0x%08lx)\n", hBinding, pDeviceID, ulLogConfType, pulLogConfTag, ulFlags);
if (pulLogConfTag == NULL) return CR_INVALID_POINTER;
*pulLogConfTag = (DWORD)0;
if (ulFlags & ~LOG_CONF_BITS) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
ret = OpenConfigurationKey(pDeviceID, ulLogConfType, &hConfigKey); if (ret != CR_SUCCESS) { DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); ret = CR_NO_MORE_LOG_CONF; goto done; }
ret = GetConfigurationData(hConfigKey, ulLogConfType, &RegDataType, &ulDataSize, &lpData, 0, NULL); if (ret != CR_SUCCESS) { DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret); ret = CR_NO_MORE_LOG_CONF; goto done; }
DPRINT1("Data size %lu\n", ulDataSize); if (ulDataSize == 0 || lpData == NULL) { DPRINT1("No config data available!\n"); ret = CR_NO_MORE_LOG_CONF; goto done; }
/* Get the first tag */ if (RegDataType == REG_RESOURCE_LIST) { DPRINT("REG_RESOURCE_LIST->Count %lu\n", ((PCM_RESOURCE_LIST)lpData)->Count);
/* Fail, if we do not have any resource */ if (((PCM_RESOURCE_LIST)lpData)->Count == 0) { DPRINT1("No resource descriptors!\n"); ret = CR_NO_MORE_LOG_CONF; goto done; } } else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) { DPRINT("REG_RESOURCE_REQUIREMENTS_LIST->AlternativeLists %lu\n", ((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists);
/* Fail, if we do not have any requirements */ if (((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists == 0) { ret = CR_NO_MORE_LOG_CONF; goto done; } }
done: if (lpData != NULL) HeapFree(GetProcessHeap(), 0, lpData);
if (hConfigKey != NULL) RegCloseKey(hConfigKey);
DPRINT("PNP_GetFirstLogConf() returns %lu\n", ret);
return ret;}
/* Function 45 */DWORDWINAPIPNP_GetNextLogConf( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfType, DWORD ulCurrentTag, DWORD *pulNextTag, DWORD ulFlags){ HKEY hConfigKey = NULL; DWORD RegDataType = 0; ULONG ulDataSize = 0; LPBYTE lpData = NULL; CONFIGRET ret = CR_SUCCESS;
DPRINT("PNP_GetNextLogConf(%p %S %lu %lu %p 0x%08lx)\n", hBinding, pDeviceID, ulLogConfType, ulCurrentTag, pulNextTag, ulFlags);
if (pulNextTag == NULL) return CR_INVALID_POINTER;
*pulNextTag = (DWORD)0;
if (ulFlags != 0) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
ret = OpenConfigurationKey(pDeviceID, ulLogConfType, &hConfigKey); if (ret != CR_SUCCESS) { DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); ret = CR_NO_MORE_LOG_CONF; goto done; }
ret = GetConfigurationData(hConfigKey, ulLogConfType, &RegDataType, &ulDataSize, &lpData, 0, NULL); if (ret != CR_SUCCESS) { DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret); ret = CR_NO_MORE_LOG_CONF; goto done; }
DPRINT("Data size %lu\n", ulDataSize);
if (ulDataSize == 0 || lpData == NULL) { DPRINT1("No config data available!\n"); ret = CR_NO_MORE_LOG_CONF; goto done; }
/* Check if the next entry is available */ if (RegDataType == REG_RESOURCE_LIST) { DPRINT("REG_RESOURCE_LIST->Count %lu\n", ((PCM_RESOURCE_LIST)lpData)->Count);
/* Fail, if we are beyond the end of the list */ if (ulCurrentTag >= ((PCM_RESOURCE_LIST)lpData)->Count) { ret = CR_INVALID_LOG_CONF; goto done; }
/* Indicate that we reached the end of the list */ if (ulCurrentTag == ((PCM_RESOURCE_LIST)lpData)->Count - 1) { ret = CR_NO_MORE_LOG_CONF; goto done; } } else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) { DPRINT("REG_RESOURCE_REQUIREMENTS_LIST->AlternativeLists %lu\n", ((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists);
/* Fail, if we are beyond the end of the list */ if (ulCurrentTag >= ((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists) { ret = CR_INVALID_LOG_CONF; goto done; }
/* Indicate that we reached the end of the list */ if (ulCurrentTag == ((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists - 1) { ret = CR_NO_MORE_LOG_CONF; goto done; } }
/* Return the next tag value */ *pulNextTag = ulCurrentTag + 1;
done: if (lpData != NULL) HeapFree(GetProcessHeap(), 0, lpData);
if (hConfigKey != NULL) RegCloseKey(hConfigKey);
DPRINT("PNP_GetNextLogConf() returns %lu\n", ret);
return ret;}
/* Function 46 */DWORDWINAPIPNP_GetLogConfPriority( handle_t hBinding, LPWSTR pDeviceID, DWORD ulType, DWORD ulTag, DWORD *pPriority, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 47 */DWORDWINAPIPNP_AddResDes( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID ResourceID, DWORD *pulResourceTag, BYTE *ResourceData, PNP_RPC_BUFFER_SIZE ResourceLen, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 48 */DWORDWINAPIPNP_FreeResDes( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID ResourceID, DWORD ulResourceTag, DWORD *pulPreviousResType, DWORD *pulPreviousResTag, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 49 */DWORDWINAPIPNP_GetNextResDes( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID ResourceID, DWORD ulResourceTag, DWORD *pulNextResType, DWORD *pulNextResTag, DWORD ulFlags){ HKEY hConfigKey = NULL; DWORD RegDataType = 0; ULONG ulDataSize = 0; LPBYTE lpData = NULL; CONFIGRET ret = CR_SUCCESS;
DPRINT1("PNP_GetNextResDes(%p %S 0x%lx %lu %lu %ul %p %p 0x%08lx)\n", hBinding, pDeviceID, ulLogConfTag, ulLogConfType, ResourceID, ulResourceTag, pulNextResType, pulNextResTag, ulFlags);
if (pulNextResType == NULL) return CR_INVALID_POINTER;
*pulNextResType = 0;
if (ulFlags != 0) return CR_INVALID_FLAG;
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
ret = OpenConfigurationKey(pDeviceID, ulLogConfType, &hConfigKey); if (ret != CR_SUCCESS) { DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); ret = CR_NO_MORE_LOG_CONF; goto done; }
ret = GetConfigurationData(hConfigKey, ulLogConfType, &RegDataType, &ulDataSize, &lpData, 0, NULL); if (ret != CR_SUCCESS) { DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret); ret = CR_NO_MORE_LOG_CONF; goto done; }
DPRINT1("Data size %lu\n", ulDataSize);
if (ulDataSize == 0 || lpData == NULL) { DPRINT1("No config data available!\n"); ret = CR_NO_MORE_LOG_CONF; goto done; }
/* Get the next resource descriptor */ if (RegDataType == REG_RESOURCE_LIST) { DPRINT1("FIXME: REG_RESOURCE_LIST\n"); /* FIXME */ ret = CR_NO_MORE_LOG_CONF; goto done; } else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) { DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n"); /* FIXME */ ret = CR_NO_MORE_LOG_CONF; goto done; }
done: if (lpData != NULL) HeapFree(GetProcessHeap(), 0, lpData);
if (hConfigKey != NULL) RegCloseKey(hConfigKey);
DPRINT1("PNP_GetNextResDes() returns %lu\n", ret);
return ret;}
/* Function 50 */DWORDWINAPIPNP_GetResDesData( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID ResourceID, DWORD ulResourceTag, BYTE *Buffer, PNP_RPC_BUFFER_SIZE BufferLen, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 51 */DWORDWINAPIPNP_GetResDesDataSize( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID ResourceID, DWORD ulResourceTag, DWORD *pulSize, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 52 */DWORDWINAPIPNP_ModifyResDes( handle_t hBinding, LPWSTR pDeviceID, DWORD ulLogConfTag, DWORD ulLogConfType, RESOURCEID CurrentResourceID, RESOURCEID NewResourceID, DWORD ulResourceTag, BYTE *ResourceData, PNP_RPC_BUFFER_SIZE ResourceLen, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 53 */DWORDWINAPIPNP_DetectResourceConflict( handle_t hBinding, LPWSTR pDeviceID, RESOURCEID ResourceID, BYTE *ResourceData, PNP_RPC_BUFFER_SIZE ResourceLen, BOOL *pbConflictDetected, DWORD ulFlags){ DPRINT("PNP_DetectResourceConflict()\n");
if (pbConflictDetected != NULL) *pbConflictDetected = FALSE;
return CR_CALL_NOT_IMPLEMENTED;}
/* Function 54 */DWORDWINAPIPNP_QueryResConfList( handle_t hBinding, LPWSTR pDeviceID, RESOURCEID ResourceID, BYTE *ResourceData, PNP_RPC_BUFFER_SIZE ResourceLen, BYTE *Buffer, PNP_RPC_BUFFER_SIZE BufferLen, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 55 */DWORDWINAPIPNP_SetHwProf( handle_t hBinding, DWORD ulHardwareProfile, DWORD ulFlags){ return CR_CALL_NOT_IMPLEMENTED;}
/* Function 56 */DWORDWINAPIPNP_QueryArbitratorFreeData( handle_t hBinding, BYTE *pData, DWORD DataLen, LPWSTR pDeviceID, RESOURCEID ResourceID, DWORD ulFlags){ return CR_CALL_NOT_IMPLEMENTED;}
/* Function 57 */DWORDWINAPIPNP_QueryArbitratorFreeSize( handle_t hBinding, DWORD *pulSize, LPWSTR pDeviceID, RESOURCEID ResourceID, DWORD ulFlags){ if (pulSize != NULL) *pulSize = 0;
return CR_CALL_NOT_IMPLEMENTED;}
/* Function 58 */CONFIGRETWINAPIPNP_RunDetection( handle_t hBinding, DWORD ulFlags){ return CR_CALL_NOT_IMPLEMENTED;}
/* Function 59 */DWORDWINAPIPNP_RegisterNotification( handle_t hBinding, DWORD_PTR hRecipient, LPWSTR pszName, BYTE *pNotificationFilter, DWORD ulNotificationFilterSize, DWORD ulFlags, PNP_NOTIFY_HANDLE *pNotifyHandle, DWORD ulProcessId, DWORD *pulUnknown9){ PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface; PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle; PNOTIFY_ENTRY pNotifyData = NULL; DWORD ret = CR_SUCCESS;
DPRINT1("PNP_RegisterNotification(%p %p '%S' %p %lu 0x%lx %p %lx %p)\n", hBinding, hRecipient, pszName, pNotificationFilter, ulNotificationFilterSize, ulFlags, pNotifyHandle, ulProcessId, pulUnknown9);
if (pNotifyHandle == NULL) return CR_INVALID_POINTER;
*pNotifyHandle = NULL;
if (pNotificationFilter == NULL || pulUnknown9 == NULL) return CR_INVALID_POINTER;
if (ulFlags & ~0x7) return CR_INVALID_FLAG;
if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HDR)) || (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR))) return CR_INVALID_DATA;
if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { DPRINT1("DBT_DEVTYP_DEVICEINTERFACE\n"); pBroadcastDeviceInterface = (PDEV_BROADCAST_DEVICEINTERFACE_W)pNotificationFilter;
if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)) || (pBroadcastDeviceInterface->dbcc_size < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W))) return CR_INVALID_DATA;
pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_ENTRY)); if (pNotifyData == NULL) { ret = CR_OUT_OF_MEMORY; goto done; }
pNotifyData->dwType = CLASS_NOTIFICATION;
if (pszName != NULL) { pNotifyData->pszName = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(pszName) + 1) * sizeof(WCHAR)); if (pNotifyData->pszName == NULL) { ret = CR_OUT_OF_MEMORY; goto done; }
wcscpy(pNotifyData->pszName, pszName); }
if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE) { pNotifyData->hRecipient = hRecipient; } else { DPRINT("Validate service: %S\n", pszName); if (I_ScValidatePnpService(NULL, pszName, (SERVICE_STATUS_HANDLE *)&pNotifyData->hRecipient) != ERROR_SUCCESS) { DPRINT1("I_ScValidatePnpService failed!\n"); ret = CR_INVALID_DATA; goto done; }
DPRINT("Service status handle: %p\n", pNotifyData->hRecipient); }
pNotifyData->ulFlags = ulFlags;
if ((ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) == 0) { CopyMemory(&pNotifyData->ClassGuid, &pBroadcastDeviceInterface->dbcc_classguid, sizeof(GUID)); }
/* Add the entry to the notification list */ RtlAcquireResourceExclusive(&NotificationListLock, TRUE); InsertTailList(&NotificationListHead, &pNotifyData->ListEntry); RtlReleaseResource(&NotificationListLock);
DPRINT("pNotifyData: %p\n", pNotifyData); *pNotifyHandle = (PNP_NOTIFY_HANDLE)pNotifyData; } else if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_HANDLE) { DPRINT1("DBT_DEVTYP_HANDLE\n"); pBroadcastDeviceHandle = (PDEV_BROADCAST_HANDLE)pNotificationFilter;
if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HANDLE)) || (pBroadcastDeviceHandle->dbch_size < sizeof(DEV_BROADCAST_HANDLE))) { ret = CR_INVALID_DATA; goto done; }
if (ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) { ret = CR_INVALID_FLAG; goto done; }
/* FIXME */ } else { DPRINT1("Invalid device type %lu\n", ((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype); ret = CR_INVALID_DATA; }
done: if (ret != CR_SUCCESS) { if (pNotifyData) { if (pNotifyData->pszName) RtlFreeHeap(GetProcessHeap(), 0, pNotifyData->pszName);
RtlFreeHeap(GetProcessHeap(), 0, pNotifyData); } }
return ret;}
/* Function 60 */DWORDWINAPIPNP_UnregisterNotification( handle_t hBinding, PNP_NOTIFY_HANDLE *pNotifyHandle){ PNOTIFY_ENTRY pEntry;
DPRINT1("PNP_UnregisterNotification(%p %p)\n", hBinding, pNotifyHandle);
pEntry = (PNOTIFY_ENTRY)*pNotifyHandle; if (pEntry == NULL) return CR_INVALID_DATA;
RtlAcquireResourceExclusive(&NotificationListLock, TRUE); RemoveEntryList(&pEntry->ListEntry); RtlReleaseResource(&NotificationListLock);
if (pEntry->pszName) RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry->pszName); RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry); *pNotifyHandle = NULL;
return CR_SUCCESS;}
/* Function 61 */DWORDWINAPIPNP_GetCustomDevProp( handle_t hBinding, LPWSTR pDeviceID, LPWSTR CustomPropName, DWORD *pulRegDataType, BYTE *Buffer, PNP_RPC_STRING_LEN *pulTransferLen, PNP_RPC_STRING_LEN *pulLength, DWORD ulFlags){ HKEY hDeviceKey = NULL; HKEY hParamKey = NULL; LONG lError; CONFIGRET ret = CR_SUCCESS;
UNREFERENCED_PARAMETER(hBinding);
DPRINT("PNP_GetCustomDevProp() called\n");
if (pulTransferLen == NULL || pulLength == NULL) { ret = CR_INVALID_POINTER; goto done; }
if (ulFlags & ~CM_CUSTOMDEVPROP_BITS) { ret = CR_INVALID_FLAG; goto done; }
if (!IsValidDeviceInstanceID(pDeviceID)) return CR_INVALID_DEVINST;
if (*pulLength < *pulTransferLen) *pulLength = *pulTransferLen;
*pulTransferLen = 0;
lError = RegOpenKeyExW(hEnumKey, pDeviceID, 0, KEY_READ, &hDeviceKey); if (lError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
lError = RegOpenKeyExW(hDeviceKey, L"Device Parameters", 0, KEY_READ, &hParamKey); if (lError != ERROR_SUCCESS) { ret = CR_REGISTRY_ERROR; goto done; }
lError = RegQueryValueExW(hParamKey, CustomPropName, NULL, pulRegDataType, Buffer, pulLength); if (lError != ERROR_SUCCESS) { if (lError == ERROR_MORE_DATA) { ret = CR_BUFFER_SMALL; } else { *pulLength = 0; ret = CR_NO_SUCH_VALUE; } }
done: if (ret == CR_SUCCESS) *pulTransferLen = *pulLength;
if (hParamKey != NULL) RegCloseKey(hParamKey);
if (hDeviceKey != NULL) RegCloseKey(hDeviceKey);
DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret);
return ret;}
/* Function 62 */DWORDWINAPIPNP_GetVersionInternal( handle_t hBinding, WORD *pwVersion){ UNREFERENCED_PARAMETER(hBinding);
*pwVersion = WINVER; return CR_SUCCESS;}
/* Function 63 */DWORDWINAPIPNP_GetBlockedDriverInfo( handle_t hBinding, BYTE *Buffer, PNP_RPC_BUFFER_SIZE *pulTransferLen, PNP_RPC_BUFFER_SIZE *pulLength, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 64 */DWORDWINAPIPNP_GetServerSideDeviceInstallFlags( handle_t hBinding, DWORD *pulSSDIFlags, DWORD ulFlags){ UNREFERENCED_PARAMETER(hBinding);
DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n", hBinding, pulSSDIFlags, ulFlags);
if (pulSSDIFlags == NULL) return CR_INVALID_POINTER;
if (ulFlags != 0) return CR_INVALID_FLAG;
/* FIXME */ *pulSSDIFlags = 0;
return CR_SUCCESS;}
/* Function 65 */DWORDWINAPIPNP_GetObjectPropKeys( handle_t hBinding, LPWSTR ObjectName, DWORD ObjectType, LPWSTR PropertyCultureName, PNP_PROP_COUNT *PropertyCount, PNP_PROP_COUNT *TransferLen, DEVPROPKEY *PropertyKeys, DWORD Flags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 66 */DWORDWINAPIPNP_GetObjectProp( handle_t hBinding, LPWSTR ObjectName, DWORD ObjectType, LPWSTR PropertyCultureName, const DEVPROPKEY *PropertyKey, DEVPROPTYPE *PropertyType, PNP_PROP_SIZE *PropertySize, PNP_PROP_SIZE *TransferLen, BYTE *PropertyBuffer, DWORD Flags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 67 */DWORDWINAPIPNP_SetObjectProp( handle_t hBinding, LPWSTR ObjectName, DWORD ObjectType, LPWSTR PropertyCultureName, const DEVPROPKEY *PropertyKey, DEVPROPTYPE PropertyType, PNP_PROP_SIZE PropertySize, BYTE *PropertyBuffer, DWORD Flags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 68 */DWORDWINAPIPNP_InstallDevInst( handle_t hBinding){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 69 */DWORDWINAPIPNP_ApplyPowerSettings( handle_t hBinding){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 70 */DWORDWINAPIPNP_DriverStoreAddDriverPackage( handle_t hBinding){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 71 */DWORDWINAPIPNP_DriverStoreDeleteDriverPackage( handle_t hBinding){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 72 */DWORDWINAPIPNP_RegisterServiceNotification( handle_t hBinding){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 73 */DWORDWINAPIPNP_SetActiveService( handle_t hBinding, LPWSTR pszFilter, DWORD ulFlags){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}
/* Function 74 */DWORDWINAPIPNP_DeleteServiceDevices( handle_t hBinding){ UNIMPLEMENTED; return CR_CALL_NOT_IMPLEMENTED;}