Cum se acceseaza un fisier in Windows
Una din sarcinile unui sistem de operare o reprezinta organizarea si gestiunea fisierelor. Atunci cand aplicatiile doresc sa acceseze continutul unui fisier ele nu manipuleaza direct structurile de pe disc pentru a accesa continutul fisierului, ci se bazeaza pe serviciile oferite de sistemul de operare.
Daca te-ai intrebat ce se intampla in interiorul Windows-ului atunci cand incerci sa deschizi un fisier, speram ca urmatoarele randuri sa-ti ofere raspunsul. Luam ca exemplu fisierul C:\test.doc. Cand o aplicatie incearca sa deschida un fisier, se apeleaza o functie dintr-o librarie sistem care ia ca unul din parametri calea C:\test.doc. Pentru a realiza operatia de deschidere functia apeleaza serviciul nativ NtCreateFile, dar nu inainte de a converti calea in format nativ prin prefixarea cu sirul \??\. Astfel, calea devine \??\C:\test.doc si este furnizata serviciului NtCreateFile().
In momentul in care serviciul nativ este apelat executia programului trece in modul kernel. Serviciul nativ apeleaza la componenta kernel a sistemului de operare responsabila cu managementul operatiilor de intrare/iesire, denumita I/O Manager. I/O Manager-ul se afla astfel in situatia in care trebuie sa acceseze un obiect identificat prin \??\C:\test.doc, despre care nu stie nimic mai mult; nu stie ca este vorba de un fisier, ci il priveste ca pe un obiect oarecare.
In general, sistemul de operare Windows este bazat pe obiecte, dar nu neaparat orientat-obiect (in sensul strict al notiunii). Majoritatea sistemului de operare este scris in C, cu cateva portiuni scrise in limbaj de asamblare. De obicei componentele kernel nu-si modifica direct structurile de date una alteia, ci apeleaza la interfete formale ce modifica obiecte, intr-o maniera similara cu filozofia orientata-obiect. Responsabila cu crearea, stergerea si managementul obiectelor este componenta kernel denumita Object Manager. Obiectele pot avea nume sau nu, Object Manager-ul gestionand spatiul de nume al tuturor obiectelor denumite.
Avand la dispozitie o cale catre un obiect, I/O Manager-ul apeleaza la Object Manager, singurul care poate localiza obiectul respectiv.
Accesarea fisierului
In cadrul sistemului de operare Windows obiectele sunt organizate ierarhic in directoare. Pentru a gasi obiectul, Object Manager-ul analizeaza fiecare componenta (delimitata de un backslash) din cale . Asa cum am spus mai inainte, urmand filozofia orientata-obiect, obiectele pot avea metode/rutine asociate cu ele. Un obiect poate avea asociata o rutina de analizare. Cautand un obiect prin analizarea caii, Object Manager-ul suspenda cautarea cand da peste un obiect care are asociata o astfel de rutina. Gasind un astfel de obiect, ii apeleaza rutina de analizare dandu-i ca parametru portiunea din cale ramasa neanalizata.
Folosim WinObj pentru a vizualiza continutul spatiului de nume gestionat de Object Manager. Revenind la exemplul nostru, la inceput se analizeaza obiectul cu numele ??. Object Manager-ul trateaza special acest obiect recunoscandu-l ca fiind directorul ce contine numele device-urilor MS-DOS. Acest obiect nu are atasata o rutina de analizare, dar fiind un director de obiecte vom continua cautand in interiorul sau componenta urmatoare, obiectul cu numele C:.
Asa cum vedem cu ajutorul lui WinObj, obiectul este gasit, dar se dovedeste a fi o legatura simbolica (un fel de scurtatura) catre un alt obiect. Avand atasata o rutina de analizare, aceasta este apelata si se inlocuieste C: cu calea catre obiectul indicat de legatura simbolica (\Device\HarddiskVolume2). Astfel, calea ramasa de analizat devine: \Device\HarddiskVolume2\test.doc.
Procedeul continua analog ajungand intr-un final la HarddiskVolume2 care este un obiect de tip device. Acest obiect reprezinta volumul (partitia) pe care se afla fisierul si este gestionat de driver-ul care recunoaste sistemul de fisiere (FAT, CDFS, NTFS etc.) prezent pe acel volum. Obiectele de tip device au asociata o rutina de analizare ce va fi apelata, rezultand in cazul nostru in trimiterea cererii de deschidere a fisierului catre driver-ul sistemului de fisiere. Sarcina de a analiza portiunea din cale ramasa (test.doc) ii revine astfel sistemului de fisiere care va incerca localizarea fisierului pe disc.
Presupunem in continuare ca sistemul de fisiere a localizat fisierul si a satisfacut cererea de deschidere cu succes. Localizarea a luat sfarsit, deci nu mai ramane decat sa se raporteze aplicatiei deschiderea cu succes a fisierului. Totusi, asa cum se va vedea mai jos, mai trebuie facut ceva pana la a face o aplicatie fericita.
Aplicatii fericite
Daca fiecare operatie asupra unui fisier (deschidere, creare, scriere, stergere etc.) s-ar face prin apelarea unei functii ce ia ca parametru calea catre fisier, atunci operatia de analizare efectuata de Object Manager ar avea loc la fiecare operatie asupra fisierului. Evident, acest lucru este costisitor si ar duce la degradarea semnificativa a performantei aplicatiilor.
Pentru a evita acest lucru Object Manager-ul creaza la deschiderea fisierului un obiect fara nume, de tip fisier (File Object), care va reprezenta instanta fisierului deschis. Dupa aceasta, toate operatiile asupra fisierului se vor realiza utilizand obiectul respectiv, pana in momentul in care instanta este inchisa. In momentul in care instanta fisierului este inchisa, obiectul este sters.
Cum se traduce acest lucru pentru aplicatie? Object Manager-ul va crea un handle pe care il primeste aplicatia. Acest handle va fi folosit de aplicatie pentru a putea efectua operatii asupra fisierului, deci pentru a putea utiliza obiectul de tip fisier. Prin urmare, in cadrul sistemului de operare un handle la un fisier se refera de fapt la un obiect (fara nume) de tip fisier.
Cand o aplicatie vrea sa citeasca dintr-un fisier deschis, ea paseaza handle-ul care reprezinta acel fisier unei functii dintr-o librarie sistem ce in final apeleaza serviciul nativ NtReadFile(). Fiind o operatie de citire, sarcina ii revine I/O Manager-ului, care trebuie sa-l intrebe mai intai pe Object Manager carui obiect ii corespunde handle-ul primit. Dupa ce a aflat obiectul, I/O Manager-ul coopereaza cu driver-ul sistemului de fisiere pentru a duce operatia de citire la bun sfarsit.
Speram (in cazul in care ati ajuns cu cititul pana aici) sa va fi format deja o idee despre ce inseamna pentru Windows deschiderea unui fisier. Intrebarile si comentariile sunt binevenite mai jos.


April 1st, 2006 - 19:10
Hello,
Sunt curios unde au loc verificarile de sharing. Sa zicem ca aplicatia 1 deschide fisierul c:\test.doc exclusiv. Aplicatia 2 doreste si ea sa dechida fisierul c:\test.doc, dar primeste eroarea “sharing violation”.
Intrebari:
1) O a doua [incercare de] deschidere referentiaza acelasi file object ? Cumva respectivul file object tine un bit mask ? [care in conditii extreme poate fi modificat]
2) Cine verifica daca un fisier a fost deja deschis, ca sa se referentieze acelasi file object ?
.. si ar mai fi altele.
Intrebarea o pun in contextul unui scanner AV, care trebuie sa scaneze orice fel de fisier. Si multi virusi isi deschid propriul fisier cu share exclusive
Thanx,
Warm regards,
Mike
April 1st, 2006 - 21:22
Verificarile de sharing au loc la deschidere in cadrul sistemului de fisiere.
1. Pentru o a doua incercare se creaza un nou file object. Fiecare handle catre un fisier corespunde unui file object. Fileobject-ul contine un bitmask unde se spune ce drepturi s-au obtinut pentru fisier, bitmask care se copiaza in handle si este verificat de exemplu in NtReadFile pentru a vedea daca poate citi sau nu.
2. Asa cum am spus la 1, nu se verifica daca un fisier a fost deja deschis, ci se foloseste corespondenta 1:1 dintre handle-ul catre un fisier si file object.
UPDATE: SE_BACKUP_PRIVILEGE despre care am amintit initial, nu poate trece peste sharing violation, ci doar peste atributele de securitate. Probabil ca intr-un viitor articol vom discuta in detaliu aceasta problema.
April 1st, 2006 - 19:55
Nevermind, am gasit
Thanx anyway,
Warm regards,
Mike
April 3rd, 2006 - 17:52
Salut,
Poti sa-mi dai un link catre detalii despre SeBackupPrivilege?
Eu gasisem alte solutii, unele destul de intrusive, altele mai elegante. Insa solutia cu SeBackupPrivilege mi se pare cea mai eleganta.
Am testat asa:
Procesul A a deschis fisierul bla.txt in felul urmator:
hFile = CreateFile (“bla.txt”, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Procesul B si-a dat privilegiul in mod corect si a incercat sa deschida acelasi fisier bla.txt :
hFile = CreateFile (“bla.txt”, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Dar primeste eroarea “sharing violation”.
Folosesc eu in mod gresit acest backup privilege? Din cate am gasit pe net este vorba de un API nou, de la XP in sus, care are legatura cu VSSAPI (Volume Shadow Service)…
Thanx in advance,
Mike
April 15th, 2006 - 22:05
Pe acelasi motiv, nu poti crea un folder numit “nul”
October 28th, 2006 - 17:40
Salut.
Referitor la fisierul “CON” intradevar se poate crea….
dar acum cum se poate sterge?:)…
October 28th, 2006 - 18:18
Il poti sterge folosind aceeasi tehnica pe care ai folosit-o si atunci cand l-ai creat
Ex:
rd \\?\c:\con
December 21st, 2009 - 19:34
cum fac ca xp-ul sa nu mai asocieze un fisier cu un anumit program. invers e simplu. ii dasu open with si gata. dar acel program va ramane mereu in lista daca optiune always… e bifata.
December 21st, 2009 - 19:39
Din meniul din My Computer de exemplu: Tools ->Folder Options -> File Types. Din lista alegi extensia care te intereseaza (mp3) de exemplu iar apoi de la advanced poti modifica toate actiunile (inclusiv sa le stergi).