Dezvoltați o bibliotecă dll pentru a interacționa cu driverul

Dacă vorbim rusă, înseamnă că: oricând programul poate încărca biblioteca dll. obțineți indicii la funcțiile și datele acestei biblioteci. Apoi, aplicația folosește într-un fel funcțiile bibliotecii și datele, iar atunci când nu mai sunt necesare, descărcarea bibliotecii.







Biblioteca DLL conține două tipuri de funcții: externe și interne. Funcțiile interne pot fi numite doar de dll-ul însuși, iar funcțiile externe pot fi de asemenea apelate de aplicația care a conectat biblioteca. În acest caz, se spune că biblioteca dll exporta funcții și date.

După cum sa menționat mai sus, în prezent, aplicația folosește schema Application -> Library dll -> Driver pentru a comunica cu driverul. Atunci când se utilizează o astfel de arhitectură, cererea de cerere pentru o operație I / O intră în biblioteca DLL, este pre-procesată acolo și transmisă driverului. Rezultatul returnat de driver în biblioteca DLL. De asemenea, procesate și transferate în aplicație. Avantajele acestei abordări sunt evidente:

  • Se produce un număr foarte mare de dispozitive periferice diferite și, în consecință, pentru fiecare dispozitiv este dezvoltat un driver. Programatorul va avea dificultăți în a înțelege toate detaliile driverului dispozitivului: formatul de date pentru citire / scriere, memorarea codurilor IOCTL incomprehensibile. Este mult mai bine să asigurăm o interfață clară a funcțiilor API pentru a lucra cu dispozitivul. Chiar mai bine, dacă o astfel de interfață este unificată pentru toate dispozitivele de acest tip. Sarcina bibliotecii dll. livrate împreună cu driverul - pentru a conecta interfețele standard furnizate programului de aplicație cu algoritmi specifici de driver.
  • dacă în viitor se va modifica algoritmul de interacțiune dintre aplicație și driver, utilizatorul va trebui să actualizeze DLL-ul doar pentru a lucra cu noul driver. Toate programele dezvoltate anterior vor rămâne aceleași.

Firește, această abordare are dezavantajele sale. În acest caz, datorită numărului mai mare de apeluri prin care trece cererea I / O, performanța sistemului scade.

În cazul nostru, trebuie să dezvoltăm o bibliotecă DLL care va furniza aplicației trei funcții: citirea memoriei, scrierea în memorie și obținerea cantității totale de memorie a dispozitivului. Bineînțeles, vom proiecta și o bibliotecă dll într-un mediu Visual C ++.

Porniți mediul VC ++ și creați un nou proiect numit XDSPInter. Pentru tipul de proiect, selectați Win32 Dynamic-Link Library. În continuare ca tip de proiect, selectați Un DLL simplu (DLL simplu). Mediul VC ++ va crea pentru dvs. un proiect gol cu ​​o singură funcție DllMain ().

Funcția DllMain () este apelată atunci când procesul este conectat și dezactivat de DLL. DllMain () are o valoare bool APIENTRY de retur (de fapt, se returnează bool tip de valoare) și trei parametri - MÂNER hModule, ul_reason_for_call DWORD, LPVOID lpReserved.

  • HANDLE hModule - descriptorul (mânerul) dll-ului nostru;
  • DWORD ul_reason_for_call - pictogramă care indică de ce a fost apelată funcția. Poate lua valori:
    • DLL_PROCESS_ATTACH sau DLL_THREAD_ATTACH - biblioteca este conectată la proces;
    • DLL_PROCESS_DETACH sau DLL_THREAD_DETACH - biblioteca este deconectată de la proces.
  • LPVOID lpReservată - rezervată.

Funcția DllMain () este singura funcție care trebuie să fie prezentă în bibliotecă. Restul funcțiilor și variabilelor sunt adăugate de programator în funcție de sarcina care trebuie rezolvată.

În cazul nostru, biblioteca dll va exporta următoarele funcții: bool IsDriverPresent (void). Funcția va determina dacă driverul necesar este prezent în sistem și încercați să vă conectați la acesta. Dacă aceasta reușește, funcția returnează adevărat, altfel este falsă.

Acum, ia în considerare textul fișierului original cpp al bibliotecii.

Astfel, biblioteca noastră exportă doar patru funcții pentru a lucra cu dispozitivul. Toți au o sintaxă simplă și sunt ușor de folosit. Utilizarea DLL-ului în cazul nostru permite programatorului să nu se gândească la apelurile sistem complexe necesare pentru a comunica cu șoferul, formatul datelor transferate la acesta și să se concentreze pe rezolvarea problemelor aplicației.

2.5 Conectarea DLL-ului la aplicație.

După scrierea driverului și a bibliotecii DLL pentru a lucra cu aceasta, este timpul să scrieți o aplicație de utilizator care funcționează cu dispozitivul. Acesta va interacționa cu driverul prin biblioteca dll. Firește, va fi scris și în mediul Visual C ++. În principiu, ar putea fi implementat într-un mediu Visual Basic, Delphi sau CVuilder, dar acest lucru va duce la anumite dificultăți, în special în utilizarea apelurilor de sistem și a structurilor de date. În această secțiune, spre deosebire de cele anterioare, nu luăm în considerare nicio aplicație specială, dar oferim recomandări generale pentru scrierea unui astfel de program.







Conectarea bibliotecii la aplicație nu necesită mult efort. Biblioteca este conectată utilizând apelul HMODULE LoadLibrary (char * LibraryName), unde LibraryName este șirul cu numele fișierului din biblioteca dll. Valoarea returnată este mânerul (descriptorul) bibliotecii. Dacă funcția a returnat NULL, a apărut o eroare la conectarea bibliotecii.

După conectarea bibliotecii, puteți importa funcții din aceasta. Funcția este importată utilizând un apel sistem

  • hModule - mânerul bibliotecii, returnat de LoadLibrary;
  • ProcName - un șir cu numele funcției importate.

Importăm patru funcții din bibliotecă, deci trebuie să definim tipurile lor: parametrii trecuți la funcție, valoarea returnată. Acest lucru se poate face cu directiva typedef:

Acum este timpul să creați indicatorii funcției:

Acum, ia în considerare funcția care conectează biblioteca dll la aplicație. Acesta va conecta biblioteca dll la aplicație și va încerca să stabilească comunicarea cu driverul. Funcția va reveni la adevăratul succes și la falsă la eșec. pentru că VC ++ este un mediu orientat pe obiecte, atunci această funcție va fi o metodă a uneia dintre clasele de aplicații (în cazul nostru, clasa de prezentare).

Este recomandabil să apelați metoda ConnectToDriver () din constructorul de clasă. Acolo este necesar să se implementeze și să se verifice dacă există un driver în sistem. Apoi, toate inițializarea necesară se va face chiar și atunci când aplicația va fi lansată.

O metodă care citește memoria dispozitivului ar putea arăta astfel:

În mod similar, metoda de scriere pe dispozitivul de memorie poate să arate ca:

Introduceți, de asemenea, o altă metodă care poate fi utilă. Se va șterge memoria dispozitivului.

Desigur, aplicația scrisă de noi și biblioteca dll sunt destul de imperfecte. De exemplu, dacă se descarcă mai multe aplicații, se vor produce erori. Apoi, aceștia vor accesa simultan același DLL și vor lucra împreună cu dispozitivul în același timp. Acest lucru poate provoca o mulțime de eșecuri. În cel mai bun caz, datele primite de fiecare dintre ele vor fi inadecvate. În cel mai rău caz - sistemul va atârna. Totuși, acest dezavantaj poate fi eliminat prin modificarea conducătorului auto în modul descris mai sus. De asemenea, în aplicația noastră lucrăm doar cu primii 1024 de octeți ai memoriei dispozitivului.

Desigur, valoarea comercială a unui astfel de sistem este zero. Dar poate fi un bun exemplu de învățare pentru învățarea programării driverelor WDM în Windows și DriverStudio.

2.6 Depanarea driverelor

Discuția despre drivere ar fi incompletă, dacă nu menționați driverele de depanare. pentru că driverele funcționează în inelul zero al protecției procesorului, cu toate consecințele care rezultă, debuggerii obișnuiți ai aplicațiilor utilizatorilor nu sunt potriviți pentru depanarea driverelor.

Dacă, de exemplu, pentru a dezvolta un driver pentru sistemul de operare Linux. atunci situația poate fi puțin mai proastă: în acest sistem de operare nu există, în general, posibilitatea de a depana driverul, cu excepția folosirii programului debugger gdb. Dar în acest caz este necesar să recompilam nucleul sistemului într-un mod special și să dansăm mai multe dansuri similare cu o tamburină. Prin urmare, depanarea adesea reduce la apelul funcțiilor de imprimare, care sunt împrăștiate în întregul nucleu al sistemului într-un număr mare.

Odată instalat în Win98, SoftIce scrie următoarea linie în Autoexec.bat: c: \ Progra

Ie SoftIce se încarcă după încărcarea DOS și încarcă Windows în sine. Când rulează Windows SoftIce este activat numai cu o excepție de sistem sau la punctul de întrerupere specificat de programator în driver. De asemenea, puteți apela SoftIce apăsând pe Ctrl + D. O fereastră de depanare apare pe ecran.

În timp ce fereastra SoftIce este activă, toată activitatea OS se blochează; chiar acum este posibilă depanarea fără probleme a șoferului.

Fereastra SoftIce este împărțită în mai multe ferestre. De obicei în centru puteți vedea fereastra de cod, deasupra acesteia - fereastra de registre a procesorului și, în partea de jos, fereastra de mesaje. Puteți să vă mutați în fereastră utilizând tastele săgeată sau pe mouse.

În partea de jos a ferestrei SoftIce este linia de comandă. SoftIce nu are o interfață grafică și toate comenzile de depanare sunt introduse pe linia de comandă. SoftIce are un sistem de ajutor destul de bun. Lista de comenzi este dată de comanda de ajutor. Poate că cea mai importantă comandă este comanda de ieșire din SoftIce. Pentru aceasta, apăsați F5 sau dați comanda X (registrul nu contează).

După ce am studiat cu atenție fereastra mesajului, vom vedea o varietate de mesaje și mesaje de sistem pe care conducătorul auto le transmite prin obiectul tras. Astfel, puteți vedea toate informațiile importante pe care șoferul dorește să le spună. Dacă dorim ca șoferul să nu afișeze mesaje sau să emită alte mesaje, trebuie să editați textul driverului adăugând altele noi sau ștergând mesajele de urmărire existente. După aceasta, trebuie să recompilați driverul și să îl reporniți.

Punctul universal de întrerupere este utilizarea unei întreruperi INT 3. Ca și în cazul MS-DOS. în Windows INT 3 este de asemenea o întrerupere a depanării. Pentru a face acest lucru, în textul driverului, unde trebuie să instalați breakpoint, trebuie să introduceți următorul cod:

Acest lucru provoacă un apel de întrerupere INT 3.

Dar, în mod implicit, SoftIce nu răspunde la INT 3. Pentru ca debuggerul să activeze pe această întrerupere, este necesar să apelezi SoftIce și să dai comanda:

Acum, când INT 3 este chemat, <всплывание> acest cod în depanator. Pentru a dezactiva modul de depanare INT 3, eliberați comanda SET I3HERE OFF.

După șoferul nostru <всплыл> în SoftIce, putem controla executarea programului folosind următoarele comenzi:

Dacă driverul a fost compilat într-o configurație de depanare, textul șoferului scrise în C ++ va fi vizibil pe ecran.

Acestea sunt comenzile de bază. Se aplică la depanarea driverelor de dispozitive în SoftIce. În general, acest program de depanare are o multitudine de funcționalități, iar descrierea completă este trimisă împreună cu programul și durează aproximativ două sute de pagini. Sper că acest ghid a fost interesant pentru dvs. Dacă nu chiar interesant - atunci, sper că ai învățat ceva nou pentru tine.







Articole similare

Trimiteți-le prietenilor: