charisma sectional sofa | charismatic service lord's supper | sven bodem | amored cars | muster fahrzeugschein | joe girardi rookie card | charisse baker missouri | sven board bbs | mustek h140 software download | joe gomillion husband | george hardy tuskegee | amoresse labs nail products | avian certifications | george harrison jaya mp3 | bluetongue essay | cnn mead robyn | sven baldermann | bluetongue in us | ernie banks glove | mustek mdc5000 5mp | amorim glass bottles | mustelus californicus | mustek dv 3000 | charissa thompson nude | bluetooth adapter microsoft gps 360 | avia propeller | mustek v520 dvd player | sven bolz | joe gazzola | george harron knives | mustek scanmagic 600 cp | sven bogdanski | avian conures goffin nutrition parrot | joe gnadt | sven benjamin appen | amorette nelson bryant | cnn michael ware | george harrison plagarism suit | ernie banks childhood | charisse christin | cnn moore gupta video | joe gillis mortgage first horizon | mustela frenata pics | aviad cohen mp3 | george halstein attorney | mustek dvd recorder r100a | avia sos belgium | ernie ball custom gauge | aviacsa promocion | george harrison apple scruffs | avia ht guide calibration disc | joe grady courthouse | sven bielfeldt | charisme developpement | charissa b martin | amorea | ernia al disco | charismatic llamas | joe giglio transportation | charisma window curtains | joe gazza and long island | ernie ball male male connector | ernie ball axis trans orange | joe goldberg tavernier fl | amore thornwood ny | mustek dv 5300se | amore today's bridal | george halas award speech | mustek pl510 | amored angel wallpaper | cnn miniseries god's warriors | cnn las vegas debate questions | charissa hammer | charissa chapman | joe gibbs truck suv s | bluetoooth | sven board5 | charisma queen duvet | avian adventures chiquita | bluetick houds for sale | joe giannetti new castle | joe gibbs racecar shop | charissa thompson gallery | joe gibbs supercross team | ernie ball axis orange | joe geilo | amores la quinta ca | george harvey boyes | charismatic legitimation | bluetongue review | charisma und amt | ernie banks sports magazine cover | george harrison ridgefield ct 06877 | ernie ball albert lee | amoretti pipes | avialable truck company | ernie and the kingsmen quartet | sven bils | sven birkerts biography | charismatic versus transformational leadership | amorebieta echano | cnn holloway natalie news update | mustelus canis | charismatic renewal services book store | bluetiful world | george harrison whatis life | bluetick coonhound pics | george harrison gone troppo | george harrison stab humour | charissa carter | aviaiton | aviaco airline | cnn mccafferty | amores pizza westerville ohio | charismatic episcopal church cec forum | charisse baker st louis | sven bomers | mustek pagescan software | charismatic cows and beefcake bulls | cnn halmark cattle | amores de mercado poptv | amore stripe tee | sven bbs ro | amores perros famous lones | george harrison lethal | bluetooch headset | avia tel aviv | sven alexius | ernie aguirre in tucson az | george harris karen zent | amore wigs | bluetooht heart rate monitor | cnn pie charts tuesday | avia tv adjuster | cnn headline news robin mead | aviall melb | avia pbx | george harrison merchandice | cnn nems | sven b shau | mustek mdc 5000 manual | cnn libia | erni enclosures | mustek relacement battery pack | sven bbs forum | mustek pvr-h140 manual | amores diamantes | george halas lebanese | george harrison alleluia | amori pronounced | george hawes 1848 | joe gibson daewoo | joe gough depot | charisma red oak | charisse rose website | mustelid photos | cnn imigration | george hamilton's actor height | cnn heroes polaris | george harrison b wyoming genealogy | cnn kenya airways crash | amoretti cookies | avia tyler us television | ernie ball melody man | mustek nv7 | avian brooder | sven bentlage | bluetights network superman returns | cnn nwes | sven bardua | sven andler | aviac sa | mustek powermust office 650 | joe gerdom | amores at waters edge | charisma srl | ernie banks stats | cnn news reporter naked | bluetick kennels | sven bergener | sven blaesing | charisse ellsworth | bluetick coonhound pups | amored paintball gloves | avian emporium cages | avia mary janes | bluetoon | sven birkets | sven bebber | joe gornall | amoret spenser | cnn news chupacabra | amores perros animal cruelty | george harrison soft-hearted hana lyrics | joe gornick | cnn headline news bill cosby | ernie balls electric guitar | charisma period clothing | charissa carroll | ernie ball petrucci | bluetoot camera | amore wig | sven biederer | amoreiras shopping center | sven balmain football soccer | cnn hamburger recall november 2007 | ernie barnes paintings wallpaper | mustela restructuring gel | joe giacalone | avian and exotic raleigh | amores perros soundtrack ismael serrano | joe gomez ncsu | charismatic and pentecostal churches | george hambleton new jersey | bluetooh blackberry | cnn newx | amoretti biscuits | joe giannone | avian bone infection | mustek vista scanner a3 driver | cnn heidi collins bio | joe geever | aviaion | aviall inc texas | ernie ball stingray bass guitar | amore's newark delaware | joe gawler | mustek dv-9300 9.0 | mustek powermust 600 plus troubleshooting | ernie barnes a life restored | bluetick in kansas | sven ahlf | charisma pdf alessandra | mustek ocr language | george harenberg | charissa ford | sven bichler | ernie ball axis super sport | avia juda | sven andreae | aviamo 50 | amores brown de mercado michel | cnn nfc championship game video | mustela nigripes | sven breckner | charisma radeon 7500 | bluetooth 2d barcode scanner | george hale fencer | ernie banks batting average | george harrison mystical one tabs | cnn lary king | cnn market news stock 0a | musteline baby | mustek mdc500 memory card | charissa schmidt | joe goff gator | charisma saint cloud mn | avia suede mesh sneakers | amores como el nuestro lyrics | joe giacomin | joe gerardi manager | cnn on air personalities | mustek pvra1 reviews | george harrison gretsch guitar | amores by barbars boyd | charisse abellana | joe gillion | ernie ball guitat dealers | ernie ball 2146 | amore un ladroncello | amore's srping texas | sven bbs gate | charissa rhodes | avia ry mino | mustek mp73 divx | aviacom | mustek scanexpress a3 usb driver | amored sea starfish | george harrison hitting intruder | george hartwells peugeot | ernie ball classic pure nickel | charismatic at stud in japan | charisse cobbs | amores battle moon pie | joe glim | ernie ball volume pedal repair | amoretti edmund spencer | cnn news airborne medication | bluetooth access point kensington forum | amoretti 34 | joe gordon waterstones | amores by barbars boyd summarry | charisma patel toronto | aviador dro vortex | ernie andrewws girl talk | avian ca clara santa veterinary | joe golen | cnn nancy grace rene rockwell | amores perros soundtrack lyrics | sven barnim | bluetoooth printers | george harrison speach | musteline | avian bone cancer holistic | bluetooth adapter acer aspire 9410 | bluetoooth drivers | amores by barbara boyd summarry | cnn hungary policemen dance | mustek dv5200 | muster every ounce of confidence | aviaire gripe | mustek dv4000 digital video camera | bluetooth 2.0 with multilink | sven behring | charissa escort | ernie ball flatwound | joe goerge and nj | joe gibbs silverado accessories | avia trail running shoes | charismatic churches in pickens country | bluetick hound forum | joe giacona | bluetick beagle puppies | george halley velvet dress | george hardman usn | ernie ball sub bass | sven barner | avian botulism taxonomy | ernie ball guitar picks | avia proofreading | mustek dv5500 digital camcorder | avian adventures dome kit | joe goebel illustration | sven birkenbach | bluetick coonhound temperament | charismac discribe version 4 | mustek dv5300se | ernie 4152 | ernie ball music man review | ernie ball string cleaner | bluetongue laboratories | sven biggen | charisma tours in egypt | aviacsa consorci airlines | mustek scanner driver vi 10 | amori home spas | bluetick pups for sale | ernie ball bullet | sven blumberg | avia sports wave | george hart sarasota florida o7 | charissa payer | joe goodman investment manager | charismatic theosophic prayer | bluetick coon dogs | charismatic leadership is value neutral | mustek mini3 driver | ernie ball music man evh | amores como el lyric nuestro | cnn lou dobbs senator kyl | ernie anderson ghoulardi | mustek ni-mh battery pack | charismatic churches in staten island | sven alius | erni kipper | charismatic catholic congregations | mustek pvr a1 media centre | bluetongue virus genome | ernice a stovall jr | charismatic church spokane | bluetick dog treeing | bluetooth access nokia 6126 | charisma runs lumpy | cnn omni tower meeting robin | bluetooth adapters for harley-davidson motorcycles | bluetick coon hounds | charismatic churches ottawa ontario | joe gilman piano | sven beckedahl | ernie ball limited edition | avian deluxe floor lighting spectrum | bluetooth 2.0 bcm2045 driver | george harrison family auckland | sven bollow | mustek driver ep a3 | avian biotech florida | bluetooth adaptor classification | avia running shoes disount | charismatic church thunder bay canada | sven beister | charismatic renewal services indiana | charismatic leader versus transformational leader | mustek gsmart d30 | amorim imobiliaria portugal | amores gondolas | charisma salon wichita ks | charismatic prophet church listing tulsa | ernie accorsi biography | amore te veta | joe goldblatt | cnn kanye mike myers west | mustek dv-9300 | charismatic episcopal church maine | joe gillium of the steelers | ernie ball wearing apparel | george halus | mustek mp 72 region hack | charisma shetty | george harris refugio poth | joe glass motorcycle dillon montana | cnn neus | sven benjamin von appen | ernie ball stingray serial | amores no correspondidos | george hamawy | george hales radiate himalaya | sven bodmann | sven bentien | charisma salon wichita kansas | cnn magma flow in hawaii | george harris lehi city council | joe gerkin | george halloran perry court | george hawi | amorexia behavior cultures | sven beisiegel | cnn money giorgio armani | ernia iatale cure | bluetongue deer | avia theater calibration software | bluetooth 2.0 edr telephone headset | george hayes dearing georgia | bluetooth 355c | charisma spas jet operations | cnn irac | bluetick coon | sven bbs gateway futaba | bluetini recipes | mustelus squalus | cnn latest news missing maddy | avian excretory systems | george harker macomb il | sven alexander hantz | sven aloe | joe giocondi | george harry braxton seay | charismatic renewal carlisle | amorfilial password | sven beissel | charissa brennan | bluetiful day | cnn journalist in drug rehab | ernie ball finger picks | amoretta cookie recipe | charismatic churches pinellas county | amoretti by edmund spenser | amoretta coffee | amorelli giovanni | amores by barbas boyd summary | ernia hiatal | joe genthe | cnn newsource | amoretto stone | cnn john mcgrady | ernie aragon | joe giordano newark de | mustek mdc | erni winter | cnn michael baisden | joe giesick | charismatic catholic church maryland | mustek gsmart d35 manual pdf | mustek mp70b manual | cnn lisa riblet | aviaid | george hatchard | cnn newws | cnn newsroom for esl | ernie and rosemary caldwell | charisse marie mendoza | joe graedon's the peoples pharmacy | cnn marlene nancy grace | sven alts | cnn las vegas debate transcript | avia real estate | george halas it's not work | amorgos houses sale | mustek dv 5500 battery charger | bluetiful | amores perfeitos | charismatic churches malyasia | joe gibbs motocross team | george hampton carey ridgefield ct | ernie ball super slinky bass | bluetooth adapter motorola v600 | bluetooth 770 user guide | george handel almira | mustekasetti | amore tomato co | bluetooth 20 compliant wireless headset | mustek mdc4000 | george harte infiniti | mustela allergic reactions | charismatic prayer groups washington pa | ernie ball dealers | erni painter | ernie althaus | charissa l chambers | cnn headline news music filler | ernie ball pedal 6166 | avia prox reader | ernie and rubber ducky | amoretto | ernie adamson | joe giella original page | mustek dv2032 reviews | ernie banks cubs t shirt | bluetongue vaccine sale | sven baumhauer | ernie ball compact volume pedal | bluetick coonhound pennsylvania | joe giliberti | bluetooth accessories for 6310i | sven bbs iboard3 | joe gibbs racing auctions | aviabor | joe gibbs hof nascar labonte | charisma property sioux falls sd | mustela belgique | george hayden mundelein | ernie ball replacement potentiometer | ernie ball linux | avian adoption memphis tn | bluetooth 8125 gprs tether | cnn legal adviser toomy | amores extranos laura pausini | mustek pf-a700b wireless | bluetick coonhound info | sven birkerts | george hager kerrville texas | joe gersch winner | bluetick coonhound picture | bluetick coon hounds for sale | cnn koontz | cnn news bigfoot | ernie ashby south carolina | mustek dv3032 | charisma supima | charismatic ecumenical renewal | bluetick hound big game | ernie anderson voice | george harry sweigert | sven borghoff | muster funeral home mclean | mustek pvr-h140 review | bluetick photos | sven ballhause | amores mil pitbull | ernie ball straps | george harrison rickenbacker | charisma svu | amorim cork composites | bluetick hound diet | sven berson | avian fecal discriptions | charisma sciences ann arbor | joe gottbrath louisville | cnn news room cohen | amores perros scripty | sven breuel | muster coaches calhoun ky | avia home theater disc | charisma towel sale | avian eye lesion | muster field farm | ernie ball regular slinkys | avian circo virus | sven baumgart | bluetooth accessable isp | mustek gsmart mini 3 driver | amores culos | mustek scanexpress 1248ub | amoretta buttercream cake | george harrison bangla desh | amore-pacific | mustek pl207 service manual | mustek cardsmart | charisma steven barnes review | ernie ball 6165 | joe goodwin nature's way landscaping | mustek dv3500 digital camera | mustek pvr h140 review | ernie and the kingsmen songs | joe gassel | aviadores y sus enfermedades | charismatic chaos by john macarthur | avia scooter | charismatic prayer symbols | joe gordon hunting fishing inore | avian 1 02m

Introducing The Windows Driver Foundation


Introduzione

In questo tutorial farò un'introduzione al WDF (Windows Driver Foundation), dato che di tutorial in giro se ne trovano pochissimi (e in italiano nessuno) eppoi ormai avevo promesso un tutorial alla giulia. Introduzione perché il WDF al momento è ancora in beta testing e uscirà con Longhorn (anche se come dopo spiegherò si può già codare driver WDF se si entra nel programma beta di microsoft). Nonostante ciò sarà comunque disponibile anche per Win2k, WinXP e Win2k3. Ora, siccome questo non è un tutorial sull'architettura di windows o su come codare driver in generale, mi aspetto che chi legga 'sto tutorial sappia cosa significhino le parole IRP, IRQL, PnP, Power Managment, WDM, ecc. Insomma se non sapete nulla del coding in Kernel Mode su windows è inutile (o quasi) che leggiate. La maggior parte delle informazioni le ho prese da microsoft.com (ve n'è qualcuna anche su osronline.com, ma poche), personalmente mi sono anche visto le sessioni WinHec riprese a Seattle ce ne sono circa una 10 di un'ora ciascuna (sono veramente interessantissime).

Ora come tutti sappiamo il corrente modello per i device driver è il WDM, ci consente di fare Function Drivers, Minidrivers, Filter Drivers ecc. per ogni utilizzo. Nonostante sia un modello molto potente il WDM è soggetto anche a delle "limitazioni", ve le elenco in breve perché chi coda WDM le conosce benissimo, diciamo che le metto solo per fare il punto della situazione per chi invece non è così ferrato:

- Non sono proprio facili da codare i WDM, chi ha avuto a che fare con PnP, Power Management ecc lo sa.

- Le attuali DDI (Device Driver Interfaces) sono state progettate molto tempo fa e il fatto che rendano disponibili ai drivers strutture interne del sistema operativo, ha fatto in modo che il loro aggiornamento sia molto difficile e spesso impossibile per motivi di retrocompatibilità. Questo è forse uno degli argomenti di cui si sente più parlare nei newsgroup o nei forum sul driver-coding, spesso programmatori incitano altri programmatori a non basare il propri driver su strutture che potrebbero cambiare da versione a versione di Windows. La verità è che spesso le strutture proibitive servono per fare cose banalissime, il primo esempio che mi viene in mente è il modo in cui si ottiene l'image name di un processo in kernel mode, cosa che in user mode come tutti sappiamo è facilissima grazie alle api nel kernel32 e alle psapi. Be' a ring 0 le cose sono un po' diverse, solo per fare ciò è necessario accedere alla PEB nella struttura EPROCESS e poi basarsi su grandezze fisse per ottenere la stringa. Eccovi un esempio di codice che scrissi diverso tempo fa:

PWCHAR GetCurrentProcessName(PWCHAR Name)   
{
   PEPROCESS CurProc;      
   BYTE *Ptr;
   ULONG_PTR Offset, Offset2 = 0;
   
   RtlFillMemory(Name, ((MAX_PATH + 1) * sizeof (WCHAR)), 0);

   CurProc = PsGetCurrentProcess();     
       
   // 0x1B0 : position of _PEB in _EPROCESS structure
         
   Ptr = (PBYTE) CurProc + 0x1B0;                  
           
   RtlCopyMemory(&Offset, Ptr, sizeof (ULONG_PTR));
       
   Ptr = (PBYTE)(Offset + 0x10);                 
    
   // 0x10 : position of ProcessParameters in _PEB structure
    
   RtlCopyMemory(&Offset, Ptr, sizeof (ULONG_PTR));
    
   // 0x3C : position of ImagePath in ProcessParameters

   Ptr = (PBYTE)(Offset + 0x3C);                 
     
   RtlCopyMemory(&Offset2, Ptr, sizeof (WORD));

   RtlCopyMemory(Name, (PBYTE)(Offset + Offset2), MAX_PATH * sizeof(WCHAR));
   
   // DbgPrint("ImagePath:[%ws]\n", Name);
   
   return Name;
}

Il problema di questo codice è che, come ben capite, potrebbe non poter più fungere su una nuova versione di windows, anzi codare in questa maniera è pericoloso perché può facilmente portare a belle BSOD. Insomma è chiaro perché soprattutto questa caratteristica delle presenti DDI ne ha spesso limitato l'estensione o comunque la modifica.

- Vi sono troppi Miniport Models. I miniport sono drivers WDM che a causa del relativamente poco lavoro che devono fare si interfacciano con un altro driver che svolge gran parte del lavoro al posto loro. Ci sono troppi modelli sui cui un miniport si può basare per fare una determinata cosa. Ogni modello può essere del tutto diverso dall'altro e quindi anche il miniport driver cambierà totalmente a seconda del modello su cui si basa (sarebbe anche solo da considerarsi la documentazione necessaria per ogni modello). Inoltre i modelli devono esser aggiornati ogni qualvolta sia richiesto e dubito che ciò venga fatto. Come se non bastasse la microsoft ci ricorda che sviluppare per device multifunzione usando un solo modello è quasi impossibile, sicuramente sarà necessario sviluppare un bus driver (WDM) e due miniports.

- Gli attuali driver girano praticamente tutti in kernel mode. Non sarebbe bello se il driver della nostra webcam usb nel caso crashasse non portasse giù insieme a sé tutto l'os? Voglio dire come ben sapete un semplice errore in kernel mode ci assicura una bella Blue Screen Of Death... Questo secondo me è uno dei punti più essenziali del discorso WDF, infatti non sono così tanti i programmatori di driver e alcuni tra questi non sanno veramente programmare driver, ma cosa vi aspettate, anche le normali applicazioni crashano, non ditemi che non vi è mai crashato nulla, certo i driver in genere contengono meno codice delle applicazioni normali e vengono "in genere" anche testati parecchio prima di rilasciarli proprio perché errori di coding possono costare una sessione importante ad un utente che quasi sicuramente si lamenterà, ma non tutte le aziende son così serie da assumere professionisti di razza e state pur certi che alcuni dei driver, che avete sul pc, sono codati alla cazzo di cane. Il WDF fa sì che alcuni driver che non devono fare cose particolarmente critiche, possano girare in user mode. Ma di questo parleremo dopo.

Bene adesso che abbiamo fatto il punto della situazione resta la domanda? Cosa è il WDF? È un modello di driver molto diverso da quelli attuali, che permette forse meno controllo/potere, ma è più facile da codare e può (non necessariamente) girare in user mode. Vabbe' questa è una spiegazione alla buona, in verità c'è molto di più da dire. Vediamo le principali caratteristiche di questo modello:

- Gli IRP non vengono più passati direttamente al driver. Al loro posto vengono usate routine di callback quali: Create / Close / Ioctl / Read / Write / Start / Stop.

- Un driver nello stack non può essere posto al di sopra di un altro driver (cosa molto comune come molti sapranno negli attuali driver). Il driver deve compiere le operazioni I/O quando la callback adibita viene richiamata. E questo si può dire sarà un bel problema se qualche programmatore aveva pensato di fare rootkit col WDF. Vabbe' pace tanto il WDF non è comunque indicato per altri motivi che dopo vedremo.

- Le allocazioni in memoria saranno semplificate, tutte le allocazioni saranno non-paged pool. Così da non doversi preoccupare dell'IRQL nel caso stessimo usando un paged-pool. Questo è un genere di errore molto comune fra i newbies, che si meravigliano di ricevere una BSOD quando non sono a passive level.

- Le richieste I/O saranno bufferate (o meglio buffered) e non ci sarà più bisogno di gestire le memory descriptor lists (MDL per gli amici).

- Si potranno generare interfacce semplici per comunicare col driver da applicazioni user mode.

- Tutte le chiamate del driver sono serializzate (ehm serialized), ovvero vengono passate una alla volta, cosicché non vi sia il rischio che più thread si sovrappongano chiamando qualcosa (evviva niente lavori con locks vari). Resta comunque anche la possibilità di sincronizzare a mano.

- Ci saranno funzioni che aiuteranno a modificare il PCI Configuration Space. Nei WDM è necessario mandare l'irp IRP_MN_QUERY_INTERFACE per far ritornare dei pointer per modificare il config space oppure usare HalGetBusData()/HalGetBusDataByOffset. Inoltre funzioni di questo genere verrano messe a disposizione anche per bus USB e IEEE 1394.

- Sono supportati solo i Power State: D0 e D3. Nei WDM gestire il Power State è abbastanza un casino. Non pochi sono i driver che non sanno riprendersi da uno standby, infatti un errore in quel settore è abbastanza frequente. Un comune Power Management per una periferica usb può costare dai 40 kb in su di codice. Anzi è possibile trovare in giro driver che non fanno andare il sistema in standby perché il coder non sapeva come scrivere la ripresa dallo sleeping.

- I driver saranno muniti di due callback, Start and Stop, per gestire il PnP. Ma del PnP (come anche del Power Management) ne parliamo più approfonditamente in avanti, dato che probabilmente la sua gestione è una delle caratteristiche più affascinanti del WDF.

- Le DDI del WDF saranno in grado di gestire eventi asincroni come interrupt e dati in arrivo su bus protocollati, cosicché anche quel lavoro non lo si deve fare a mano.

Queste alcune delle caratteristiche principali. Per non parlare del fatto che probabilmente sarà possibile codare anche in C# dei driver WDF. Come è a tutti noto, il 99% dei nostri drivers (WDM, nativi NT4 ecc) son codati in C, pochi in C++. Coll'introduzione del WDF sarà sicuramente più comune il C++, ma credo, da quanto ho potuto capire, che la microsoft non si vuol assolutamente lasciar sfuggire la fetta di programmatori C# (con tutto il rispetto per questo linguaggio nel quale anche io programmo). In effetti in diversi ambiti ho visto proliferare un uso pesante di questo nuovo linguaggio, e non mi stupirei se la microsoft vuol fare anche questo passo, che, come ben si capisce, non è da poco. Bisogna dire anche un'altra cosa, nelle comunità di driver c'è spesso un forte senso di rifiuto nei confronti del WDF, vi sono molti puristi che vedono il WDF come un'immane tragedia (un saluto a Xoanon): fondamentalmente la paura sta nell'astrattezza che il WDF porta nel coding di driver (senza nemmeno accennare al coding in C#). Ma d'altronde la tecnologia si sta spostando in una direzione ben precisa, è inevitabile. Chiusa la parentesi. Ad ogni modo il WDF al momento in cui scrivo è ancora un modello sotto sviluppo, anzi facendo parte della programma beta (facilmente reperibile sul sito microsoft) è possibile scrivere qualche driver e far sapere alla MS cosa si vorrebbe fosse introdotto/cambiato nel modello. A quanto pare la MS è sinceramente interessata al feedback dei programmatori di driver, vista anche la sua comunicazione con le community e le richieste fatte durante le sessioni dei winhec. Comunque quel che avete letto finora è stato solo un assaggio giusto per prender gusto a quello che gli americani chiamano double-di-ef. Partiamo dai fondamenti, ovvero il framework.
 

WDF Framework

In pratica il WDF è composto da due framework, uno user mode e uno kernel mode. La sessione winhec 2004 di introduzione ha illustrato brevemente le caratteristiche dei due framework. Entrambi supportano PnP, Power Management, I/O asincrono basato sui pacchetti e filtri. Anche il processo di installazione dei driver resta uguale a quello dei WDM e si applica sia ai kernel mode driver sia a quelli user mode, non fa differenza. Per i driver kernel mode però non vi sarà il riavvio in caso di crash, cosa che invece è prevista per quelli user mode. Infine il linguaggio inizialmente previsto per codare in kernel mode sarà il C (poi anche il C++) e in user mode C++ e C# (e il managed code consente la software isolation che garantirà una grande capacità di evitare crash e di recupero).

Ecco quella che dovrebbe essere la struttura del framework user mode:



Dove il Driver Manager è il processo wdfmgr.exe e il suo compito è di caricare il driver che sarebbe l'Host Driver Process. In pratica i vari componenti dialogano tra loro tramite il Redirector che è un componente che gira in kernel mode. Vedendo un po' più nei particolari:



Come vedete il driver ha accesso alle api win32. Però come disse il pakistano durante la sessione winhec, non sarà possibile chiamare api che riguardano le gui, cioè è un servizio non ci potete fare finestrelle anche se lavorate in user mode. Le potenziali applicazioni per il framework user mode sono lettori multimediali portatili, scanner, foto e videocamere, periferiche connesse tramite rete, tutte le periferiche basate su bus protocollati (tipo USB, IEEE 1394, IP) con eccezione di quelle che si occupano di input, visualizzazione, storage o rete. Una delle parti più importanti del WDF sono i tools di debugging e di verifica (statica e dinamica), nonostante ciò ho deciso di non trattarli in questo tutorial, poiché richiederebbe troppo e poi voglio parlare della programmazione non del debug. Probabilmente scriverò un tutorial in futuro su questo argomento. Il modo più comune di interfacciarsi al driver resta l'io control che però presenta diverse limitazioni in fatto di sicurezza, intanto non è type safe e per questo motivo non sarà possibile usarlo in managed code applications. Cosa comunque che sarà facilmente raggirabile. Come abbiamo visto nello schema del framework soprastante, vi sono, all'interno dell'Host Driver Process i WDF Objecets... Ma cosa sono?


WDF Object Model

Il WDF si basa su oggetti, vediamo le direttive che la MS ha seguito per la progettazione:

- Fornire alle DDI un fondamento concettuale (oggetti non semplici liste di funzioni C).
- Definire un set di comportamenti comune a tutti gli oggetti.
- Fornire un modello col quale sia facile scalare da implementazioni semplici a implementazioni complesse (tipo passare da una implementazione miniport per fare tutt'altra cosa).
- Isolare il driver da dettagli di implementazione interna (come si era già detto prima).
- Fare in modo che sia possibile far girare due versioni diverse di implementazioni (ovvero il framework è un file sys che gira indipendemente dal ntoskrnl.exe e quindi anche due versioni diverse del framework possono girare contemporaneamente).
- Fare in modo che in futuro sia possibile un supporto per altri linguaggi.
- Usare concetti di oggetti familiari a programmatori WDM.

a loro volta gli oggetti:

- Rappresentano driver, device, queue ecc.
- Hanno prorietà, metodi e eventi (gli eventi sono callback (serializzate) nel nostro driver).
- Possono aver Context Memory (tipo device extension per WDM).
- Hanno reference counts.
- Sono organizzati gerarchicamente, con parentela padre/figlio.
- Vi si fa riferimento tramite handle, non puntatori (sempre a proposito di astrazione).

Come già detto più volte vi è la serializzazione automatica degli eventi, ma anche il cleanup è possibile da parte del framework. Se per esempio un oggetto viene chiuso (ovvero il suo reference count passa a 0) tutti i suoi figli (tramite la relazione gerarchica) vengon chiusi dal framework. Inoltre è possibile associare qualsiasi oggetto al device object in modo da avere il cleanup automatico durante l'unload (ma si può associare anche a qualsiasi altro oggetto, non per forza il device object). Il driver interagisce col framework e viceversa tramite le DDI in questi termini: il driver crea gli oggetti che gli servono, definisce routine di callback per gli eventi degli oggetti e può associare Context Memory a qualsiasi dei suoi oggetti, il framework, da parte sua, gestisce i reference count degli oggetti (anche se volendo è possibile aggiungere / rimuovere reference manualmente, se per esempio si vuol essere sicuri che un certo oggetto non venga distrutto), gestisce le parentele e chiama le routine di callback del driver nel caso si verifichi un evento. La Context Memory, come già detto, può essere associata (e quindi allocata) a qualsiasi tipo di oggetto e provvede la possibilità di associare all'oggetto informazioni specifiche. Si accede a tale memoria tramite un puntatore, il quale è possibile ottenere tramite l'handle dell'oggetto. Più di una Context Memory può essere associata a un oggetto se differisce nel tipo. Ovviamente se l'oggetto viene distrutto la sua (o sue) Conext Memory viene automaticamente deallocata.

Le convenzioni per il C DDI Set sono fondamentalmente:

- Tutti i riferimenti a oggetti sono effettuati tramite handle.
- L'handle è il primo parametro passato a qualsiasi funzione DDI del WDF.
- Ogni DDI è classificata come una proprietà, un metodo o un evento, a seconda della semantica e del valore di ritorno.
- Le callback all'interno del nostro diver sono eventi (e questo spero sia chiaro ormai).
- La naming convention è Wdf<ObjectType><Operation>, esempi:
   - WdfObjectDelete(WDFOBJECT Object)
   - WdfRequestComplete(WDFREQUEST Request, NTSTATUS Status)
   - WdfDevicePowerReference(WDFDEVICE Device, BOOLEAN WaitForD0)

Andiamo avanti.
 

Proprietà, Metodi ed Eventi

Le proprietà sono quel che nei WDM è il diretto accesso ai campi dell'oggetto. Tipo se abbiamo una struttura e settiamo un parametro Struct.Param = Param in questa maniera si è effettuato un accesso diretto (hardcoded), proprio quel che spesso complica la vita ai programmatori MS nel caso di patch o fix. Invece col WDF arrivano le proprietà a cui si accede con metodi Get/Set (nei quali non possono verificarsi errori). La chiamata Get ritorna con l'informazione richiesta e la Set ritorna void (dato che comunque non possono verificarsi errori). Ecco un esempio di naming convention per due metodi Get/Set:

ValueName WdfObjectGetValueName(WDFOBJECT Object)
VOID WdfObjectSetValueName(WDFOBJECT Object)

In generale la naming convention dei metodi è WDFSTATUS WdfObjectMethod(WDFOBJECT Object, …), giusto per ribadire. E sui metodi non c'è altro da aggiungere.

Gli eventi possono avvertire il nostro driver per una richiesta, un cambiamento del power state del sistema, un interrupt ecc. Le callback sono definite dal nostro driver e vengono chiamate se si verifica un evento, inoltre sono definite di default dal WDF se il nostro driver non si preoccupa di definire delle proprie. La suddetta serializzazione automatica degli eventi non è sempre obbligatoria, per alcuni oggetti è possibile gestirla manualmente (vedremo fra due secondi). La naming convention usata nei driver per gli eventi è: EvtObjectEventName. Gli eventi che hanno a che fare con la lifetime o, per dirla più chiaramente, la distruzione dell'oggetto sono EvtObjectDestroy e EvtObjectCleanup. Il primo evento corrisponde IRP_MJ_CLOSE, è chiamato quando il reference count va a 0, la Context Memory dell'oggetto viene liberata. Il secondo, invece, è simile a IRP_MJ_CLEANUP e può essere usato per prevenire reference counts circolari (Circular Reference Counts). Questi si verificano quando un oggetto figlio fa riferimento al padre e il padre a sua volta fa riferimento (anche indirettamente) al figlio. Questo può portare a memory leaks, quindi nell'evento di cleanup il driver deve eliminare questi reference count circolari, rimuovendo, per esempio, i propri reference (intendo dire se ha fatto uso di WdfObjectReference per aggiungere un reference manualmente). In ogni caso il framework non distrugge l'oggetto finché il reference count non scende a 0.


Serializzazione

La serialization, come precedentemente detto, riguarda gli eventi, ovvero le callback. È opzionale e comunque anche se utilizzata non riguarda l'oggetto la cui (o le cui) callback è serializzata, l'oggetto continua a rispondere normalmente. La serializzazione manuale si effettua tramite WdfObjectAcquireLock e  WdfObjectReleaseUnlock. Il driver può specificare a quale IRQL le callback vengono chiamate. È possibile specificare dispatch level (utile per la sincronizzazione diretta con dpc o timer) o passive level (nel caso di quest'ultimo il framework rinvia automaticamente a un workitem che ci richiama a passive se necessario, ovvero se qualcuno ci chiama a un altro IRQL). Si può volere o no la serializzazione, e se sì è possibile usare la struttura di configurazione per specificare i suddetti parametri:

typedef enum _WDF_SERIALIZATION_SCOPE {
    WdfSerializationNonSpecified = 0x00,
    WdfSerializationScopeObject,
    WdfSerializationScopeDevice
} WDF_SERIALIZATION_SCOPE;

typedef enum _WDF_EXECUTION_LEVEL {
    WdfExecutionLevelNonSpecified = 0x00,
    WdfExecutionLevelPassive,
    WdfExecutionLevelDispatch
} WDF_EXECUTION_LEVEL;

typedef struct _WDF_CALLBACK_CONSTRAINTS {
    ULONG                    Size;
    WDF_SERIALIZATION_SCOPE  SerializationScope;
    WDF_EXECUTION_LEVEL      ExecutionLevel;
    BOOLEAN                  SaveFloatingPointState;
} WDF_CALLBACK_CONSTRAINTS, *PWDF_CALLBACK_CONSTAINTS;

Gli accessi nelle callback degli eventi alla Context Memory sono serializzati automaticamente (se si accede esternamente la serializzazione è necessaria farla manualmente (almeno se si teme una sovrapposizione) tramite WdfObjectAcquireLock e WdfObjectReleaseLock). Però se associamo i nostri dati alla Context Memory di un dato oggetto e accediamo a questi solo nelle callback è chiaro che nessuna serializzazione dovremmo farla manualmente, il framework se ne occuperà al nostro posto: cosa abbastanza comoda direi.


Core WDF Objects

Vi sono oggetti che vedrete molto spesso nei sorgenti WDF perché di grande utilità, questi oggetti sono per esempio WDFDPC, WDFWORKITEM, WDFTIMER ecc. Ma ci sono oggetti che vedrete ancora più spesso, per non dire sempre, nei sorgenti WDF perché facenti parte del core del modello. La microsoft ne elenca quattro: WDFDRIVER, WDFDEVICE, WDFQUEUE e WDFREQUEST.

WDFDRIVER è l'oggetto creato da WdfDriverCreate, in pratica corrisponde all'inizializzazione del framework, dato che prima di questa chiamata (da fare nella driver entry) non possiamo usare nessun'altra DDI. Questo oggetto fornisce due eventi. Il primo, EvtDriverDeviceAdd, viene chiamato quando un device viene assegnato al nostro driver (un PnP device, s'intende). Il secondo, EvtDriverUnload, è opzionale, nel senso che, anche se si registra EvtDriverDeviceAdd, questo evento è solo richiesto se ci sono dati esterni al framework da liberare  (il framework fa il cleanup dei propri dati) o altre cose da fare. Ecco un esempio di come si crea un oggetto WDFDRIVER:

NTSTATUS DriverEntry(IN PDRIVER_OBJECT  DriverObject,
           IN PUNICODE_STRING RegistryPath)
{
    WDF_DRIVER_CONFIG config;
    WDFDRIVER driver;
    NTSTATUS status;

    //
    // inizializza la struttura config
    //

    WDF_DRIVER_CONFIG_INIT(&config, EvtDriverDeviceAdd);

    //
    // chiama come prima cosa WdfDriverCreate
    //

    status = WdfDriverCreate(DriverObject, RegistryPath, NULL, &config, &driver);

    return status;
}

Adesso, come anche nel WDM c'è il device object, nel WDF abbiamo il WDFDEVICE, tramite cui si effettuano la maggior parte delle operazioni. In poche parole tutto l'IO gira lì. Corrisponde a una singola istanza di un device che il nostro driver supporta. Il device object lo si crea nella EvtDriverDeviceAdd.

NTSTATUS DeviceCreate(WDFDEVICE_INIT Device)
{
    WDFSTATUS status;
    WDFDEVICE  device;
    WDF_FDO_EVENT_CALLBACKS fdoCallbacks;

    //
    // specifica che il device obj è un fdo
    // e ne specifica le callback,
    // dei pdo e fdo parleremo in seguito
    // per ora basta dire il dev obj può
    // essere configurato come uno dei due
    //

    WDF_FDO_EVENT_CALLBACKS_INIT(&fdoCallbacks);

    fdoCallbacks.EvtDeviceStart           = EvtDeviceStart;
    fdoCallbacks.EvtDeviceRemove     = EvtDeviceRemove;

    WdfFdoInitSetEventCallbacks(DeviceInit, &fdoCallbacks);

    // crea WDFDEVICE

    status = WdfDeviceCreate(DeviceInit, &attributes, &device);

    return status;
}

Se, dopo aver creato il WDFDEVICE decidiamo di creare qualche altro oggetto che ci serve tipo queue, dpc ecc e lo associamo al device, non ritorniamo con uno status success, il framework si occupa di distruggere il device e tutti i suoi figli.

WDFREQUEST è quello che nel WDM chiamiamo irp. Sarebbero richieste di IO, le proprietà dell'oggetto corrispondono ai campi del irp.

WDFQUEUE si associa al device object e se ne possono associare di più allo stesso. La WDFQUEUE rappresenta una specifica coda di richieste IO. Si può richiedere in che modo le richieste siano mandate al driver: serialmente (ovvero una alla volta), parallelamente (le richieste vengono mandate quando arrivano) e manualmente (il driver si preoccupa manualmente di processare le richieste).


Conclusione

Be' per questa volta direi che può bastare, in questo articolo ho fornito un po' di fondamenti, nel prossimo mi vorrei occupare di PnP e Power Management (e anche altre cose), anche se temo non basterà un articolo solo per discutere gli argomenti restanti, quindi probabilmente suddividerò il lavoro in più parti (anche se ancora non ho un piano ben preciso). Oltretutto c'è da dire che questi articoli sicuramente andranno rivisti in molti punti all'uscita vera e propria del WDF e non so nemmeno se continuerò a scriverli in italiano.

Alla Prossima!

Daniel Pistelli