Sunteți pe pagina 1din 19

Sistemul de fişiere NTFS

1. Introducere
Scop
Această lucrare explică pe scurt implementarea NTFS, sistemul de fişiere al
sistemului de operare Windows 2000, şi prezintă principalele funcţii ale API-ului
Win32 legate de gestiunea fişierelor.

Obiective
Lucrarea are următoarele obiective principale:
1. cunoaşterea sistemului de fişiere NTFS;
2. cunoaşterea tipurilor de fişiere şi a drepturilor de acces din NTFS;
3. cunoaşterea funcţiilor pentru lucrul cu fişiere în NTFS;
4. înţelegerea modului de creare a fişierelor ce conţin seturi multiple de date.

Prezentare generală
NTFS (NT File System) este un sistem de fişiere dezvoltat special pentru
Windows NT şi îmbunătăţit pentru Windows 2000. NTFS4 este folosit la
Windows NT, în timp ce sistemul de fişiere pentru Windows 2000 este NTFS5.
Windows XP Microsoft foloseşte o versiune uşor îmbunătăţită a NTFS5.

Facilităţile principale oferite de acest sistem de fişiere sunt următoarele:


• foloseşte adrese de disc de 64 de biţi şi poate suporta partiţii de până
la 264 bytes ;
• oferă posibilitatea folosirii caracterelor Unicode în numele de fişiere;
• permite folosirea numelor de fişiere de până la 255 de caractere,
inclusiv spaţii şi puncte;
• permite indexare generală a fişierelor;
• oferă posibilitatea managementului dinamic al sectoarelor ;

1
• datorită compatibilităţii POSIX, permite crearea hard-link-uri, face
distincţie între litere mari şi mici în cadrul numelor de fişiere şi
păstrează informaţii de timp referitoare la fişier;
• permite utilizarea fişierelor cu seturi multiple de date.

2. Structura de disc NTFS


La formatarea unei partiţii (volum) cu sistemul de fişiere NTFS se creează o
serie de fişiere sistem, dintre care cel mai important este fişierul Master File
Table (MFT), care conţine informaţii despre toate fişierele şi directoarele de pe
volumul NTFS.

Prima informaţie pe o partiţie NTFS este Sectorul de Boot, care este sectorul 0
al partiţiei şi conţine un program (cod) de pornire al sistemului. Alte informaţii
necesare programului de boot-are (de exemplu informaţii necesare accesării
volumului) pot fi înscrise în sectoarele de la 1 la 16, care sunt rezervate în acest
scop. Figura 1 ilustrează structura unui volum NTFS la terminarea formatării.

Primul fişier pe un volum NTFS este fişierul MFT. Pentru fiecare fişier de pe
un volum NTFS există cel puţin o intrare în MFT, inclusiv pentru MFT. Toate
informaţiile despre un fişier, incluzând numele, dimensiunea, informaţii de timp
referitoare la fişier, permisiuni şi datele efective, sunt păstrate în MFT sau în
spaţiul situat în exteriorul MFT-ului care descrie intrări în MFT. Atributele de
fişier sunt păstrate în MFT atunci când dimensiunea lor permite să fie
memorate în intrarea corespunzătoare din MFT, sau în zone auxiliare de pe
HDD, exterioare fişierului MFT şi asociate intrării din MFT a fişierului.

Sectorul FigureFişiere
Master File Table 1. Zona de fişiere
de boot sistem

Figura 1. Structura unui volum NTFS

2
Tabelul de mai jos conţine toate tipurile de atribute definite în prezent de
sistemul de fişiere NTFS. Aceste tipuri de atribute sunt folosite intern de către
NTFS, utilizatorul neavând acces direct la atribute şi neputând defini noi tipuri
de atribute. Această listă este extensibilă, în sensul că în viitor se vor putea
defini şi alte atribute de fişier.

Tabelul 1. Tipuri de atribute ale fişierelor în NTFS


Tipul
Descriere
atributului
Standard
Include informaţii cum ar fi informaţii de timp şi numărul de legături.
information
Attribute Lists Listează locaţiile tuturor înregistrărilor atributelor non-rezidente.
File Name Un atribut care se poate repeta atât pentru denumiri scurte, cât şi pentru
denumiri lungi de fişiere. Numele lung al fişierului poate fi de până la 255 de
caractere Unicode. Numele scurt este în format 8.3. Nume adiţionale sau hard
link-uri, necesitate de POSIX, pot fi incluse ca atribute de nume adiţionale ale
fişierului.
Security
Denumeşte proprietarul fişierului şi utilizatorii care îl pot accesa.
Descriptor
Data Conţine datele din fişier. NTFS permite atribute multiple de date pentru fiecare
fişier. În mod tipic fiecare fişier are un atribut de dată fără nume. Un fişier
poate de asemenea să aibă unul sau mai multe atribute de dată, fiecare cu o
sintaxă anume.
Object ID Un identificator unic în volum şi utilizat de facilitatea de regăsire a legăturilor
distribuite. Nu toate fişierele au identificatori de obiect.
Logged Tool Similar unui flux de date, dar operaţiile sunt înscrise în fişierul log al NTFS
Stream întocmai ca şi modificările de metadate. Folosit de EFS.
Reparse Point Folosit pentru puncte de montare de pe disc şi de asemenea şi de drivere de
filtrare ale IFS (Installable File System) pentru a marca anumite fişiere ca fiind
speciale pentru acel driver.
Index Root Folosit pentru a implementa directoare şi alţi indecşi.
Index
Folosit pentru a implementa directoare şi alţi indecşi.
Allocation
Bitmap Folosit pentru a implementa directoare şi alţi indecşi (pentru directoare f. mari)
Volume
Folosit doar de fişierul sistem $Volume. Conţine versiunea volumului.
Information
Volume Name Folosit doar de fişierul sistem $Volume. Conţine eticheta volumului.

Fişierele metadata sunt structurile de date folosite de NTFS pentru accesul şi


managementul fişierelor. Acest sistem de fişiere se bazează pe principiul „totul

3
este fişier”. Astfel, descriptorul de volum, informaţia de boot, înregistrări ale
sectoarelor defecte etc. sunt toate stocate în fişiere.
Fişierele care stochează informaţiile metadata ale NTFS sunt prezentate în
tabelul de mai jos:

Tabela 2. Intrările din MFT corespunzătoare fişierelor metadata ale NTFS


Numele Înregistrarea Descriere
fişierului MFT nr.
$MFT 0 MFT
$MFTmirr 1 Fişier plasat în mijlocul discului, copie a primelor 16 înregistrări
MFT.
$LogFile 2 Fişier de suport pentru jurnalizare.
$Volume 3 Informaţii de gestiune – eticheta volumului, versiunea sistemului
de fişiere etc.
$AttrDef 4 Lista atributelor standard de fişiere pe volum.
$. 5 Directorul rădăcină.
$Bitmap 6 Harta de biţi a spaţiului liber pe volum.
$Boot 7 Sectorul de boot (partiţie boot-abilă).
$BadClus 8 Lista blocurilor defecte.
$Secure 9 Descriptori de securitate pentru toate fişierele.
$Upcase Fişier – tabelul de conformitate între majuscule şi minuscule în
numele de fişiere de pe volum. Acest fişier este necesar pentru ca
numele de fişiere NTFS sunt memorate în Unicode care are
65.000 de caractere diferite şi nu este simplu să se caute
10 echivalentul de majusculă, respectiv minuscul.
$Quota 11 Fişier în care sunt înregistrate drepturile utilizatorilor asupra
spaţiului de disc (a început să funcţioneze doar de la NTFS5).

3. Tipuri de fişiere şi drepturi de acces în NTFS


În NTFS, putem identifica următoarele tipuri de fişiere:
• fişiere sistem: sunt fişierele descrise în tabelul de mai sus şi conţin
informaţii (metadata) ce sunt folosite numai de către sistemul de
operare.
• fişiere cu seturi multiple de date (Alternate Data Streams - ADS):
sunt fişiere care pe lângă setul de date principal (şi implicit), mai
conţin şi alte seturi distincte de date. Toate aceste seturi de date sunt
reprezentate prin atribute de tip Data. Modul de creare şi utilizare,

4
pentru un fişier, a seturilor de date auxiliare celui principal este
descris în capitolul 5.
• fişiere arhivate: NTFS poate arhiva şi dezarhiva fişierele „on-the-
fly”, adică în momentul efectuării operaţiilor de scriere şi, respectiv
citire a datelor din ele. Acest mecanism este invizibil aplicaţiilor ce
utilizează astfel de fişiere.
• fişiere criptate: EFS (Encrypted File System) oferă suport pentru a
stoca fişiere criptate pe un volum NTFS. Criptarea este transparentă
faţă de utilizatorii care au încriptat fişierul. Accesul celorlalţi
utilizatori nu este permis la aceste fişiere.
• fişiere „rare” (sparse files): sunt fişiere în care informaţia scrisă nu
se găseşte într-o singură zonă contiguă, ci zonele în care s-au scris
date alternează cu zone mari în care nu s-au scris („găuri”). NTFS
permite setarea unui atribut special al acestor fişiere, prin care se
indică sistemului de I/E să aloce spaţiu pe disc numai pentru zonele
efectiv scrise din fişier.
• fişiere de tip „hard-link”: sunt fişiere speciale introduse de NTFS5.
Aceste fişiere permit ca un fişier să poate fi accesat prin mai multe căi
fără ca datele efective să fie duplicate. Dacă ştergem un fişier la care
există şi o altă legătură, datele nu vor fi şterse de pe disc, până când nu
se şterg toate legăturile. Un fişier de tip hard-link poate fi creat folosind
funcţia CreateHardLink sau comanda "fsutil hardlink create" (în
Windows XP).

În ceea ce priveşte drepturile de acces, în NTFS ele sunt gestionate prin liste de
control al accesului (ACL). Aceste ACL-uri conţin informaţii care definesc
pentru fiecare utilizator sau grup de utilizatori drepturile pe care le au asupra
unui fişier. Drepturile de acces se numesc permisiuni.

NTFS-ul defineşte 6 astfel de permisiuni de bază, numite permisiuni speciale.


Următorul tabel enumeră aceste permisiuni şi explică ce efect are fiecare asupra
fişierelor, respectiv a directoarelor.

5
Tabelul 3. Permisiuni asupra fişierelor în NTFS
Permisiune Caracter Drepturi acordate pt. Drepturi acordate pentru
fişiere directoare
Read R Citire conţinut fişier Citire conţinut director
Write W Modificare conţinut Modificare conţinut director
fişier (creare fişiere sau subdirectoare)
Execute X Executare (rulare) Traversare structură
program subdirectoare
Delete D Stergere fişier Ştergere director
Change P Schimbare drepturi de Schimbare drepturi de acces pt.
Permissions acces pt. fişier director
Take Ownership O Schimbare proprietar Schimbare proprietar

Pentru a avea un control mai fin şi mai uşor asupra drepturilor de acces, s-au
introdus (începând cu Windows 2000) nişte grupuri de permisiuni, denumite
componente de permisiuni. Fiecare dintre ele grupează una sau mai multe
permisiuni speciale, după cum urmează:
• Traverse Folder / Execute File: X
• List Folder / Read Data: R
• Read Attributes: R + X
• Read Extended Attributes: R
• Create Files / Write Data: W
• Create Folders / Append Data: W
• Write Attributes: W
• Write Extended Attributes: W
• Delete Subfolders and Files: D
• Delete: D
• Read Permissions: R + W + X
• Change Permissions: P
• Take Ownership: O

Folosind interfaţa grafică pentru setarea drepturilor de acces, putem să ne


întâlnim şi cu alte grupuri de permisii.

6
4. Apeluri API pentru sistemul de fişiere NTFS
Toate resursele (fişiere, procese) pe sistemele de operare bazate pe Windows
NT sunt identificate de handler-e. Un handler este un token care permite
identificarea accesului unui program la o resursă. Este similar descriptorilor de
fişier din Unix. Astfel, atunci când este creat sau deschis un fişier, se returnează
un astfel de handler şi folosind acest handler fişierul poate fi accesat pentru
citire şi scriere.

Funcţia CreateFile
Funcţia este folosită pentru a crea un fişier sau pentru a deschide un fişier
existent. Sintaxa funcţiei este următoarea:

HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile);

Parametrii:
lpFileName – pointer către un string terminat cu 0 care specifică numele
fişierului care se creează sau se deschide
dwDesiredAccess – specifică tipul de acces la fişier. O aplicaţie poate
obţine acces de citire, acces de scriere, acces scriere/citire, sau acces
de interogare a dispozitivelor. Mai jos prezentăm cele mai
importante valori pentru acest parametru:
0 – acces de interogare a dispozitivelor fişierului.
GENERIC_READ – Dreptul de citire al fişierului. Datele se pot citi
din fişier şi pointerul de fişier poate fi deplasat.
Se combină cu GENERIC_WRITE pentru dreptul de scriere/citire.
GENERIC_WRITE – Dreptul de scriere a fişierului. Datele pot fi
scrise în fişier şi pointerul fişierului poate fi deplasat.
DELETE – Dreptul de a şterge fişierul.

7
READ_CONTROL – Dreptul de a citi informaţiile din descriptorul
de securitate al fişierului.
WRITE_OWNER – Dreptul de a schimba proprietarul în
descriptorul de securitate al fişierului.
SYNCHRONIZE – Dreptul de a folosi fişierul pentru sincronizare.
Acesta îi dă unui thread posibilitatea de a aştepta până când fişierul
este în starea marcată.
GENERIC_EXECUTE – Dreptul de execuţie.
GENERIC_ALL – Dreptul de citire, scriere şi execuţie.
dwShareMode – Specifică modul în care poate fi partajat fişierul între
mai mulţi utilizatori. Dacă dwShareMode este 0 şi CreateFile se
încheie cu succes, fişierul nu poate fi partajat şi nu poate fi deschis
din nou până când handlerul nu este închis. Pentru a partaja fişierul,
se poate folosi o combinaţie a următoarelor valori:
FILE_SHARE_DELETE – operaţiile de deschidere următoare
asupra fişierului vor reuşi numai dacă este solicitat accesul de
ştergere.
FILE_SHARE_READ – operaţiile de deschidere următoare asupra
fişierului vor reuşi numai dacă este solicitat accesul de citire.
FILE_SHARE_WRITE – operaţiile de deschidere următoare asupra
fişierului vor reuşi numai dacă este solicitat accesul de scriere.
lpSecurityAttributes – Pointer la o structură SECURITY_ATTRIBUTES
care determină dacă handlerul poate fi moştenit de procesele fiu.
Dacă atributul lpSecurityAttributes este NULL, atunci handlerul nu
poate fi moştenit.
dwCreationDisposition – Specifică acţiunea care se va efectua asupra
fişierelor care există şi ce acţiune să se efectueze dacă fişierul nu
există. Acest parametru trebuie să ia una dintre valorile următoare:
CREATE_NEW – Creează un fişier nou. Funcţia eşuează dacă
fişierul există deja.
CREATE_ALWAYS – Creează un fişier nou. Dacă fişierul există,
funcţia suprascrie fişierul, şterge atributele existente şi combină
atributele de fişier şi flag-urile specificate de dwFlagsAndAttributes
cu FILE_ATTRIBUTE_ARCHIVE.

8
OPEN_EXISTING – Deschide un fişier. Funcţia eşuează dacă
fişierul nu există.
OPEN_ALWAYS – Deschide fişierul, dacă acesta există. Dacă
fişierul nu există, funcţia creează fişierul ca şi cum
dwCreationDisposition ar fi CREATE_NEW.
TRUNCATE_EXISTING – Deschide fişierul. Odată deschis,
fişierul este trunchiat astfel încât dimensiunea lui să fie de 0 octeţi.
Procesul apelant trebuie să deschidă fişierul cel puţin cu accesul
GENERIC_WRITE.Funcţia eşuează dacă fişierul nu există.
dwFlagsAndAttributes – Specifică atributele fişierului şi flag-urile
pentru fişier. Un fişier poate avea următoarele atribute: archive,
encrypted, hidden, normal, not content indexed, offline, read-only,
system, temporary; şi următoarele flag-uri: write through,
overlapped, no buffering, random access, sequential scan, delete on
close, backup semantics, POSIX semantics, open reparse point,
open no recall.
hTemplateFile – Specifică un handler cu acces GENERIC_READ la un
fişier template. Fişierul template furnizează atributele de fişier
pentru fişierul ce se creează.

Dacă funcţia are succes, valoarea returnată este un handler prin care se
accesează în continuare fişierul specificat. Dacă funcţia eşuează, valoarea
returnată este INVALID_HANDLE_VALUE. Pentru a obţine informaţii
extinse de eroare, apelaţi GetLastError.

Funcţia DeleteFile
Funcţia sterge un fişier existent şi are următoarea sintaxă:
BOOL DeleteFile(
LPCTSTR lpFileName); // numele fişierului

Returnează o valoare nenulă în caz de succes, 0 altfel.

9
Funcţia CloseHandle
Funcţia închide un handler deschis de fişier.

BOOL CloseHandle(
HANDLE hObject); //handler catre obiect

Returnează o valoare nenulă în caz de succes, 0 altfel.

Funcţia ReadFile
Funcţia ReadFile citeşte date dintr-un fişier, începând de la poziţia indicată de
către pointerul fişierului. După ce operaţia de citire a fost finalizată, pointerul
de fişier este ajustat cu numărul de bytes citiţi efectiv, mai puţin în cazul în care
handler-ul de fişier este creat cu atributul suprapus. Dacă handler-ul de fişier
este creat pentru intrare-ieşire suprapusă (I/O), aplicaţia trebuie să ajusteze
poziţia pointerului de fişier după operaţia de citire.

BOOL ReadFile(
HANDLE hFile, // handler către fişier
LPVOID lpBuffer, // buffer de date
DWORD nNumberOfBytesToRead, // nr de bytes de citit
LPDWORD lpNumberOfBytesRead, // nr de bytes cititi
LPOVERLAPPED lpOverlapped); // buffer suprapus

Parametrii:
hFile – Handler către fişierul de citit. Handler-ul de fişier trebuie să fi
fost creat cu accesul GENERIC_READ la fişier.
lpBuffer – Pointer la bufferul care primeşte datele citite din fişier.
nNumberOfBytesToRead – Specifică numărul de octeţi care trebuie citit
din fişier.
lpNumberOfBytesToRead – Pointer la variabila care primeşte numărul
de octeţi citiţi.
lpOverlapped – Pointer la o structură OVERLAPPED. Această structură
este solicitată dacă hFile a fost creat cu
FILE_FLAG_OVERLAPPED.

10
Funcţia returnează dacă numărul de octeţi a fost citit sau dacă a apărut o eroare.
Dacă funcţia reuşeşte, valoarea returnată este nenulă.

Funcţia WriteFile
Această funcţie scrie date într-un fişier şi este destinată atât pentru operaţii
sincrone cât şi pentru operaţii asincrone. Funcţia începe să scrie datele în fişier
la poziţia indicată de pointerul de fişier. După ce operaţia de scriere a fost
terminată, pointerul de fişier este ajustat cu numărul de octeţi scrişi efectiv, cu
excepţia cazului în care fişierul este deschis cu FILE_FLAG_OVERLAPPED.

BOOL WriteFile(
HANDLE hFile, // handler la fişier
LPCVOID lpBuffer, // buffer de date
DWORD nNumberOfBytesToWrite, // nr de bytes de scris
LPDWORD lpNumberOfBytesWritten, // nr de bytes scrişi
LPOVERLAPPED lpOverlapped); // buffer suprapus

Semnificaţiile parametrilor sunt similare cu cele ale parametrilor funcţiei


ReadFile.

Dacă funcţia se termină cu succes, valoarea returnată va fi nenulă. Dacă funcţia


eşuează, valoarea returnată este 0.

Funcţia SetFilePointer
Funcţia SetFilePointer deplasează pointerul unui fişier deschis.

DWORD SetFilePointer(
HANDLE hFile,
LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh,
DWORD dwMoveMethod);

Parametrii:
hFile – Handler la fişierul al cărui pointer se va deplasa. Handlerul de
fişier trebuie să fi fost creat cu unul din următoarele două tipuri de
acces la fişier GENERIC_READ sau GENERIC_WRITE.

11
lDistanceToMove – Cei 32 cei mai puţin semnificativi biţi al valorii în
semn care specifică numărul de bytes cu care se va deplasa pointerul
fişierului. lpDistanceToMoveHigh – Pointer la cei 32 de biţi cei mai
semnificativi al distanţei exprimată în semn pe 64 de biţi. Dacă nu e
nevoie de cei 32 de biţi cei mai semnificativi, acest pointer trebuie
setat la NULL.
dwMoveMethod – Punctul iniţial de unde se va deplasa pointerul. Acest
parametru poate avea una din următoarele valori:
FILE_BEGIN – Punctul iniţial este 0 la începutul fişierului.
FILE_CURRENT – Punctul iniţial este valoarea curentă a
pointerului fişierului.
FILE_END – Punctul iniţial este poziţia EOF curentă a fişierului.

Dacă funcţia SetFilePointer se termină cu success şi lpDistanceToMoveHigh


este NULL, valoarea returnată este dublu-cuvântul DWORD cel mai puţin
semnificativ al noului pointer la fişier. Dacă lpDistanceToMoveHigh nu este
NULL, atunci funcţia returnează dublu-cuvântul DWORD cel mai puţin
semnificativ al noului pointer la fişier şi pune dublu-cuvântul DWORD cel mai
semnificativ al noului pointer la fişier în valoarea LONG la care pointează acel
parametru. Dacă funcţia eşuează şi lpDistanceToMoveHigh este NULL atunci
valoarea returnată este INVALID_SET_FILE_POINTER.

Funcţia GetFileAttributes
Această funcţie restabileşte un set de atribute de stil FAT pentru un fişier sau un
director specificat.

DWORD GetFileAttributes(
LPCTSTR lpFileName); // numele fişierului sau al
directorului

Dacă funcţia se termină cu succes, valoarea returnată va conţine atributele


fişierului sau directorului specificat. Atributele pot consta din una sau mai
multe valori prezentate la 2.2.1. completate cu directoare sau fişiere împrăştiate.

12
Funcţia LockFile
Funcţia LockFile închide o regiune dintr-un fişier deschis pentru a asigura
excludere mutuală. Închiderea unei regiuni sub lacăt previne situaţia în care alte
procese ar putea să acceseze acea regiune.

Sintaxa funcţiei LockFile este prezentată mai jos.

BOOL LockFile(
HANDLE hFile,
DWORD dwFileOffsetLow,
DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh);

Parametrii:
hFile – Handler la fişierul al cărei regiune se va bloca. Numele fişierului trebuie
să fi fost creat cu unul din următoarele tipuri de acces la fişier:
GENERIC_READ sau GENERIC_WRITE (sau ambele).
dwFileOffsetLow – Specifică cuvântul cel mai puţin semnificativ al offset-ului
de octeţi în fişier acolo unde va începe lacătul.
dwFileOffsetHigh – Specifică cuvântul cel mai semnificativ al offset-ului de
octeţi în fişier acolo unde va începe lacătul.
nNumberOfBytesToLockLow – Specifică cuvântul cel mai puţin semnificativ al
lungimii numărului de octeţi care vor fi blocaţi.
nNumberOfBytesToLockHigh – Specifică cuvântul cel mai semnificativ al
lungimii numărului de octeţi care vor fi blocaţi.

Dacă funcţia se termină cu succes, valoarea returnată este nenulă, altfel 0.

Funcţia UnlockFile
Funcţia deblochează o regiune într-un fişier deschis. Sintaxa acestei funcţii este
similară cu cea a funcţiei LockFile.

13
Funcţia CreateDirectory
Această funcţie creează un nou director. Dacă sistemul de fişiere existent
suportă opţiuni de securitate pentru directoare şi fişiere, funcţia va aplica un
descriptor de securitate specificat pentru noul director.

BOOL CreateDirectory(
LPCTSTR lpPathName, // nume director
LPSECURITY_ATTRIBUTES lpSecurityAttributes);

Dacă funcţia se termină cu succes, valoarea returnată este nenulă, altfel 0.

Funcţia RemoveDirectory
Funcţia RemoveDirectory şterge un director gol deja existent.

BOOL RemoveDirectory(
LPCTSTR lpPathName); // numele directorului

Dacă funcţia se termină cu succes, valoarea returnată este nenulă, altfel 0.

Funcţia FindFirstFile
Această funcţie caută un director pentru un fişier al cărui nume corespunde
numelui de fişier specificat. Funcţia FindFirstFile examinează atât numele
subdirectoarelor cât şi numele de fişiere.

HANDLE FindFirstFile(
LPCTSTR lpFileName, // numele fişierului
LPWIN32_FIND_DATA lpFindFileData); // buffer de date,
care stochează informaţiile despre fişierul găsit

Dacă funcţia se termină cu succes , valoarea returnată este un handler de căutare


folosit într-un apel ulterior la FindNextFile sau FindClose. Dacă funcţia
eşuează, valoarea returnată este INVALID_HANDLE_VALUE.

14
Funcţia FindNextFile
Această funcţie continuă o căutare de fişier de la un apel anterior al funcţiei
FindFirstFile .

BOOL FindNextFile(
HANDLE hFindFile, // handle r căutare
LPWIN32_FIND_DATA lpFindFileData); // buffer de date

Dacă funcţia se termină cu succes, valoarea returnată este nenulă, altfel 0.

Funcţia MoveFile
Mută un fişier sau director existent, inclusiv copii acestuia.

BOOL MoveFile(
LPCTSTR lpExistingFileName, // numele fişierului
LPCTSTR lpNewFileName); // noul nume al fişierului

Dacă funcţia se termină cu succes, valoarea returnată este nenulă, altfel 0.

Funcţia SetCurrentDirectory
Funcţia schimbă directorul curent pentru procesul curent.

BOOL SetCurrentDirectory(
LPCTSTR lpPathName); // numele noului director

Dacă funcţia se termină cu succes, valoarea returnată este nenulă, altfel 0.

5. Fişiere cu seturi multiple de date

După cum am mai menţionat, sistemul NTFS permite ca unui fişier să fie
asociate mai multe atribute de date, deci mai multe fluxuri de date. Fiecare
fişier are asociat un flux de date principal, fără nume. Dacă este necesar, se mai
pot asocia fişierului fluxuri alternative cu nume. Această facilitate permite ca

15
unele date din fişier să fie accesate ca o unitate separată. De exemplu, o
aplicaţie grafică poate să stocheze iconul (thumbnail) pentru o imagine bitmap
într-un flux separat în interiorul fişierului NTFS care conţine imaginea.
Fluxurile alternative au dimensiuni separate de fişierul principal, dar au aceleaşi
permisiuni.

Un flux alternativ poate fi creat foarte uşor din linia de comandă. Pentru a crea
fluxul principal, putem scrie:

echo “Flux principal in fisier” > Data

Astfel, am creat fişierul cu numele Data. Să-i adăugăm un flux alternativ cu


numele ADS:

echo “Flux alternativ” > Data:ADS

Se poate observa că fluxul adăugat nu apare între fişierele listate din director şi
nici nu măreşte dimensiunea fişierului principal. Pentru a citi conţinutul
fluxului principal şi al celui alternativ, executăm comenzile:

more < Data


more < Data:ADS

Pentru a deschide un flux alternativ în Notepad, numele fluxului trebuie să aibă


o extensie, de exemplu: Data:ADS2.txt. El se poate edita cu comanda
"notepad Data:ADS2.txt".

Fluxurile alternative pot conţine şi date binare, adică fişiere executabile. Ele se
pot executa cu comanda: "start .\Data:fis.exe".

Sistemul Windows foloseşte fluxuri alternative atunci când specificăm date


suplimentare pentru un fişier prin Properties->Summary. Fluxurile oferă o
posibilitate bună viruşilor de a se ascunde, pentru că ele nu se văd în lista de
fişiere, şi nu modifică dimensiunea şi ştampila de timp al fişierului principal.
Windows nu oferă programe care pot detecta fluxurile alternative.

16
6. Exemple

1. Copierea unui fişier folosind funcţiile API ale Windows 2000

#include <windows.h>
#include <stdio.h>
#define BUF_SIZE 10

void main() {
HANDLE inhandle, outhandle;
char buffer[BUF_SIZE];
int count;
DWORD ocnt;
/* Deschide fi•ierele de intrare •i de ie•ire */
inhandle = CreateFile(“data”, GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);
outhandle = CreateFile(“newf”, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
/* Copieaz• fi•ierul */
do {
s = ReadFile(inhandle, buffer, BUF_SIZE, &count, NULL);
if (s && count > 0) WriteFile(outhandle, buffer, count,
&ocnt, NULL);
} while (s>0 && count>0);

/* Închide fi•ierele */
CloseHandle(inhandle);
CloseHandle(outhandle);
}

2. Să se găsească toate fişiere .txt din directorul curent şi să se seteze atributele


lor la read-only.

#include <windows.h>
#include <stdio.h>

WIN32_FIND_DATA FileData;
HANDLE hSearch;
DWORD dwAttrs;

17
BOOL fFinished = FALSE;

void main() {

// Caută fişiere .TXT în directorul current


hSearch = FindFirstFile("*.txt", &FileData);
if (hSearch == INVALID_HANDLE_VALUE)
{
printf("No .TXT files found.");
return;
}

// Pentru fiecare fişier schimbă atributul în read-only dacă


// nu este deja read-only
while (!fFinished)
{
dwAttrs = GetFileAttributes(FileData.cFileName);
if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))
{
SetFileAttributes(FileData.cFileName,
dwAttrs | FILE_ATTRIBUTE_READONLY);
}

if (!FindNextFile(hSearch, &FileData))
{
if (GetLastError() == ERROR_NO_MORE_FILES)
{
printf("No more .TXT files. Search completed.");
fFinished = TRUE;
}
else
{
printf("Couldn't find next file.");
return;
}
}
}

// Închide handle-ul de căutare


FindClose(hSearch);
}

18
7. Probleme propuse
1. Cum se poate afla dimensiunea unui fişier folosind funcţia SetFilePointer ?
2. Folosind funcţiile API prezentate scrieţi un program C care să afişeze în
ordine inversă liniile unui fişier.
3. Să se scrie un program care citeşte şi tipăreşte caracterele 0, 20, 40 ,... dintr-
un fişier creat anterior.
4. Să se scrie un program care lansat în background de N ori scrie într-un fişier
ID procesului curent. Nici unul dintre programe nu poate să-şi continue
execuţia până ce toate procesele nu şi-au scris ID-ul propriu în fişier. În
final fiecare proces afişează ID procesului următor.
5. Să se scrie un program care să permită scrierea unor şiruri de caractere din
intrarea standard într-un fişier, începând cu o anumita poziţie. Apelul
programului se face sub forma: rw poz fis.
6. Să se scrie un program care listează toate fişierele dintr-un director dat.
7. Să se scrie un program care elimină tot al cincilea octet dintr-un fişier.
Observaţie: nu se va folosi un fişier temporar.
8. Să se scrie un program care demonstrează modul de utilizare al fişierelor de
tip hard link.
9. Să se creeze un fişier text la care să se asocieze un flux alternativ de date
care să conţină programul solitaire (sol.exe).

19

S-ar putea să vă placă și