Seadmedraiver

Seadmedraiver (inglise keeles "driver" – juht, antud kontekstis juhtprogramm) ehk ohjur on informaatikas arvutiprogramm, mis võimaldab teistel kõrgtasemeprogrammidel riistvarakomponenti kasutada.
Arvutis on iga riistvarakomponendi jaoks seadmedraiver (edaspidi lühemalt draiver), ilma milleta ei suudaks riistvara töötada. Tavaliselt toimub andmevahetus draiveri ja arvutikomponendi vahel läbi arvutisiini või mõne teise ühenduskanali, mille külge riistvarakomponent on ühendatud. Kui kasutajaprogramm tahab komponendilt midagi, siis ta annab draiverile vastava käsu ja draiver edastab selle komponendile spetsiifilise riistvarakäsuna. Kui komponent tahab programmile andmeid saata, siis käib see samuti läbi draiveri. Seadmedraiver töötab seega tõlgina riistvaraseadme ning rakenduste või operatsioonisüsteemi vahel.
Draiveri paigaldamine ja uuendamine.
Enamasti saab draiveri koos seadmega kaasa CD või mõne teise andmekandja peal. Algselt on riistvaral ainult üldine draiver, kuid sellel ei ole piisavalt informatsiooni, et arvuti saaks riistvara õigesti kasutada.
Kui riistvara ei tööta korralikult, siis on tavaliselt seadmedraiveris tekkinud mingi rike. Draiverit on võimalik uuesti installida. Selleks tuleb minna vastava seadmemudeli kodulehele ning sealt otsida sellele sobiv draiver. Samuti on olemas ka mitmeid programme, mis uuendavad draivereid automaatselt, kui on olemas uuem versioon.
Füüsiline struktuur.
Seadmedraiveri füüsiline struktuur koosneb tuumast ehk kernelist, sisend/väljundihaldurist ning kasutajarežiimidest.
Tüüpide loend:
Kasutajarežiimis ühendub rakendus API-ga, mis ühendub Ntdll'iga. Seejärel liigub rakenduse päring kernelisse 
läbi sisend/väljundhalduri. Sisend/väljundhaldur kasutab NtReadFile’i, et päring läbi töötada, ning saadab
selle IoCallDraiverisse, mis omakorda saadab informatsiooni õigesse draiverisse. Pärast seda otsustab draiver, 
mida selle päringuga teha. See saadab selle riistvara porti, teise draiverisse või tegeleb sellega hiljem.
Kasutajarežiimi draiverid.
Need draiverid tagavad näiteks liidese Win32 rakenduse ja kernelirežiimi draiverite või teiste operatsioonisüsteemi komponenti vahel. Windows Vistas on kõik printeri draiverid kasutajarežiimis. Kasutades kasutajarežiimi draiveri raamistikku, on võimalik luua kasutajarežiimi draivereid, mis põhinevad protokollil või jadasiinil. Selle režiimi eeliseks on madalam latentsus, paranenud stabiilsus, sest halvasti kirjutatud seadmedraiver ei ole võimeline süsteemi kokkujooksutama..
Kernelirežiimi draiverid.
Need draiverid töötavad kernelirežiimis operatsioonisüsteemi komponentidena, mis haldavad sisend/väljundit, isehäälestamist, mälu, protsesse ja lõimi, turvalisust jne. Kernelirežiimi draiverid on enamasti jaotatud kihtideks. Kõik kernelirežiimi draiverid on varustatud süsteemi määratud tavaliste draiverirutiinidega.
Osa kernelirežiimi draivereid on Windowsi Draiveri Mudeli (WDM) draiverid, mis kuuletuvad WDM-ile. Mõned draiverid on kernelirežiimi draiveri raamistiku (KMDF) draiverid. Ülejäänud draiverid põhinevad NDIS-i või teistel draiverimudelitel, mis on spetsiifilised seadme klassile.
Kujundus.
Seadmedraiverid jaotatakse arhitektuurilise projekteerimise ning arendamise viisi järgi kaheks mudeliks, mis täiendavad teineteist andmete kapseldamise, süsteemi tõhususe ning tarkvara muutuste haldamise osas.
Mitmeastmeline seadmedraiver.
See jagab draiveri koodi kolme gruppi, nii et äriloogika on eraldatud alamtaseme riistvara spetsiifilisest koodist ning süsteemi tase tagab vajaliku ühenduse vahepeal. Kui riistvara muutub, siis tuleks koodi muuta ainult alamtasemes ning vastupidi, kui andmepäringud muutuvad, siis tuleks muuta ainult rakendusekoodi. Süsteemi taseme kood tagab ligipääsufunktsioonid alamtaseme koodidele, et need saaksid suhelda rakendusetaseme koodidega. Rakendusetaseme kood ei saa otse alamtaseme koodiga suhelda.
Sõpruse tsoon.
See on üpriski sarnane mitmeastmelise seadmedraiveri arhitektuuriga, kuid see on efektiivsem, sest siin on süsteemi- ja alamtaseme andmetele ligipääs tunduvalt kiirem. Selleks tuleb tasakaalustada andme kapseldamise vastasmõjud ja süsteemi jõudlus. Selle saab, kui kasutada ‘sõbra’ funktsiooni C++’s, mis annab ühele klassile ligipääsu teise klassi privaatsetele andmetele, kui teine klass on esimese oma ‘sõbraks’ määranud. Sellepärast on vähem lisafunktsiooni kutseid ning see hoiab klassi andmed saladuses kõigi ees, kes ei ole määratud tema ‘sõbraks’.
Arendus.
Seadmedraiveri kirjutamine nõuab põhjalikke teadmisi sellest, kuidas riistvara ja tarkvara omavahel talitlevad mingis operatsioonisüsteemis. Draiverid töötavad kõrgete käskudega keskkonnas ning võivad tekitada tõsist kahju, kui midagi läheb valesti. Enamikku kasutajataseme tarkvaraprogramme saab peatada, ilma et need mõjutaksid ülejäänud süsteemi drastiliselt. Peamiselt kirjutavad seadmedraivereid tarkvarainsenerid, kes töötavad riistvarafirmades, sest nemad tunnevad oma riistvara paremini kui keegi väljastpoolt firmat. Riistvara tootja huvides oli parim, kui kasutaja saab kasutada nende toodet kõige efektiivsemal viisil.
Microsoft Driver Foundation.
Microsoft lõi Windows Driver Foundatoni, et kergendada draiverite arendamist ning parandada nende kvaliteeti, ilma et see vähendaks jõudlust. WDF-ga kaasneb mudel, millel on infrastruktuur nii kerneli kui ka kasutajarežiimi draiveritele. See mudel on paindlik, pikendatav, skaleeritav, võimaldab lisanduvaid arenguid, vähendab õppeaega ning lubab draiveri kirjutajal keskenduda operatsioonisüsteemi asemel seadme riistvarale.
WDF-i draiverimudel.
Draiverimudel määrab objektorienteeritud keskkonna, milles draiveri kood saab hakkama tarkvarale spetsiifiliste funktsioonidega ning Microsofti raamistik ütleb draiverile, et see vastaks sündmustele, mis mõjutavad selle draiveri operatsioone. Sellisel kujundusel on mitu tähtsat eelist oma eelkäija Windows Driver Modeli (WDM) ees. Esiteks saab Microsoft muuta operatsioonisüsteemi sisest andmestruktuuri ilma draiveri ühildamatusega. Peale selle on draiverid väiksemad, kiiremad arenema ja vigu kõrvaldama tänu raamistikule, mis rakendab üldisi draiveri tunnuseid ja tavalist käitumist. Draiveri arendajad ja riistvara edasimüüjad on paremini isoleeritud lisanduvatest uuendustest igas uues operatsioonisüsteemi versioonis. Iga raamistik saab jälgida draiveri hetkeseisu, operatsioonisüsteemi ning seadet, seega eemaldades palju keerulist loogikat, mida on draiverites vaja.
WDFi objektimudel.
Objektid töötavad ehituskividena draiveris. Draiver muudab neid objekte täpselt määratletud liideste kaudu. Objektidel endal on täpselt defineeritud elutsükkel. Mingi hulk sündmusi võib mõjutada igat objektiliiki. Raamistik määrab tavalise käitumise iga sündmuse puhul. Toetamaks seadmele spetsiifilist käitumist, on draiveril tagasihelistamise rutiin, mis tühistab vaikeoleku.
Objektidel on meetodid, sündmused ja atribuudid. Meetodid teostavad tegevusi objektidel. Sündmused on tingimused, millel draiver võib tegutseda. WDF identifitseerib võimalikud sündmused igale objektile ning määrab enamikule vaiketegevuse. Draiver sisaldab koodi, mis on suuteline ainult neid sündmusi täitma, millele on vaiketegevused sobivad. Kui sündmus toimub, siis WDF kutsub välja seotud tagasihelistamise. Atribuudid kirjeldavad objektide tunnuseid. Iga atribuut on seostatud meetodiga, mis saavad ning kui vajalik, siis ka määravad omandile väärtuse.
Kernelirežiimi objektid.
"Kernel-Mode Driver Foundationi" (KMDF) objektid on struktuurid, mis on läbipaistmatud draiverile. Draiverid viitavad objekti juhtumeid pidemetega. Lugemiseks, kirjutamiseks või tegevuse teostamiseks objektil peab draiver kutsuma meetodi objektile ning pideme edasi andma. KMDF eristab umbes 20 tüüpi objekte. KMDF-i objektid on unikaalsed raamistikule. Neid ei halda Windowsi objektihaldur ning sellepärast ei saa neid mõjutada kasutades süsteemi ObXxx funktsioone. Ainult raamistik ning WDF draiverid saavad luua ja neid muuta.
KMDFi sündmused ei ole seotud kerneli dispetšeri sündmustega, mida Windows kasutab sünkroonimismehhanismina. Draiver ei saa luua, muuta või oodata WDF sündmuse järel. Selle asemel draiver registreerib tagasihelistamise sündmusele ja WDF kutsub draiverit, kui sündmus leiab aset.
Kasutajarežiimi objektid.
"User-Mode Driver Foundationi" (UMDF) objektid põhinevad komponent objekt mudelil. UMDF kasutab väikest komponent objekt mudeli alamhulka iga päringuliidese ja viidete lugemise tunnuseid. Kasutajarežiimi draiverites rakendavad nii draiver kui ka raamistik komponent objekt mudeli stiilis liideseid. Pidemeid ei ole vaja, sest liidesed on abstraktsed ning selletõttu identifitseerivad objekti.
UMDB eristab vähem objekte kui KMDF, sest kasutajarežiimi draiveritel ei ole otsest ligipääsu riistvarale ning sellepärast ei teosta otsest mälu ligipääsu ega tootel katkestusi.
Rakendused.
Draivereid kasutatakse mitmes valdkonnas: 
Virtuaalsed seadmedraiverid.
Virtuaalsed seadmedraiverid esindavad uut seadmedraiverite varianti. Neid kasutatakse, et emuleerida mingit riistvara seadet, enamasti virtualiseerimiskeskkonnas. Näiteks kui DOS-programmi kasutatakse Windowsi arvutis või kui külalisoperatsioonisüsteemi kasutatakse Xen hostis. Selle asemel, et võimaldada külalisoperatsioonisüsteemil suhelda riistvaraga, virtuaalsed seadmedraiverid võtavad vastas rolli ja emuleerivad mingit riistvara seadet, nii et külalisoperatsioonisüsteem ja selle virtuaalses masinas töötavatel draiveritel oleks illusioon, et neil on ligipääs reaalsele riistvarale. Külalisoperatsioonisüsteemi katsed riistvarale ligipääsemiseks on ümbersuunatud virtuaalsesse seadmedraiverisse hosti operatsioonisüsteemi funktsiooni kutsetena.
Virtuaalsed seadmed võivad töötada ka mitte virtuaalses keskkonnas. Näiteks virtuaalset võrguadapterit kasutatakse virtuaalses privaatvõrgus, samal ajal kui virtuaalset ketta seadet kasutatakse iSCSI-ga. Parim virtuaalse seadmedraiveri näide on Daemon Tools.