[fastfat_new]
[reactos.git] / reactos / drivers / filesystems / fastfat_new / fcb.c
1 /*
2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filesystems/fastfat/fcb.c
5 * PURPOSE: FCB manipulation routines.
6 * PROGRAMMERS: Aleksey Bragin <aleksey@reactos.org>
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #define NDEBUG
12 #include "fastfat.h"
13
14 #define TAG_FILENAME 'fBnF'
15
16 /* FUNCTIONS ****************************************************************/
17
18 FSRTL_COMPARISON_RESULT
19 NTAPI
20 FatiCompareNames(PSTRING NameA,
21 PSTRING NameB)
22 {
23 ULONG MinimumLen, i;
24
25 /* Calc the minimum length */
26 MinimumLen = NameA->Length < NameB->Length ? NameA->Length :
27 NameB->Length;
28
29 /* Actually compare them */
30 i = (ULONG)RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinimumLen );
31
32 if (i < MinimumLen)
33 {
34 /* Compare prefixes */
35 if (NameA->Buffer[i] < NameB->Buffer[i])
36 return LessThan;
37 else
38 return GreaterThan;
39 }
40
41 /* Final comparison */
42 if (NameA->Length < NameB->Length)
43 return LessThan;
44 else if (NameA->Length > NameB->Length)
45 return GreaterThan;
46 else
47 return EqualTo;
48 }
49
50 PFCB
51 NTAPI
52 FatFindFcb(PFAT_IRP_CONTEXT IrpContext,
53 PRTL_SPLAY_LINKS *RootNode,
54 PSTRING AnsiName,
55 PBOOLEAN IsDosName)
56 {
57 PFCB_NAME_LINK Node;
58 FSRTL_COMPARISON_RESULT Comparison;
59 PRTL_SPLAY_LINKS Links;
60
61 Links = *RootNode;
62
63 while (Links)
64 {
65 Node = CONTAINING_RECORD(Links, FCB_NAME_LINK, Links);
66
67 /* Compare the prefix */
68 if (*(PUCHAR)Node->Name.Ansi.Buffer != *(PUCHAR)AnsiName->Buffer)
69 {
70 if (*(PUCHAR)Node->Name.Ansi.Buffer < *(PUCHAR)AnsiName->Buffer)
71 Comparison = LessThan;
72 else
73 Comparison = GreaterThan;
74 }
75 else
76 {
77 /* Perform real comparison */
78 Comparison = FatiCompareNames(&Node->Name.Ansi, AnsiName);
79 }
80
81 /* Do they match? */
82 if (Comparison == GreaterThan)
83 {
84 /* No, it's greater, go to the left child */
85 Links = RtlLeftChild(Links);
86 }
87 else if (Comparison == LessThan)
88 {
89 /* No, it's lesser, go to the right child */
90 Links = RtlRightChild(Links);
91 }
92 else
93 {
94 /* Exact match, balance the tree */
95 *RootNode = RtlSplay(Links);
96
97 /* Save type of the name, if needed */
98 if (IsDosName)
99 *IsDosName = Node->IsDosName;
100
101 /* Return the found fcb */
102 return Node->Fcb;
103 }
104 }
105
106 /* Nothing found */
107 return NULL;
108 }
109
110 PFCB
111 NTAPI
112 FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext,
113 IN PVCB Vcb,
114 IN PFCB ParentDcb,
115 IN FF_FILE *FileHandle)
116 {
117 PFCB Fcb;
118
119 /* Allocate it and zero it */
120 Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB);
121 RtlZeroMemory(Fcb, sizeof(FCB));
122
123 /* Set node types */
124 Fcb->Header.NodeTypeCode = FAT_NTC_FCB;
125 Fcb->Header.NodeByteSize = sizeof(FCB);
126 Fcb->Condition = FcbGood;
127
128 /* Initialize resources */
129 Fcb->Header.Resource = &Fcb->Resource;
130 ExInitializeResourceLite(Fcb->Header.Resource);
131
132 Fcb->Header.PagingIoResource = &Fcb->PagingIoResource;
133 ExInitializeResourceLite(Fcb->Header.PagingIoResource);
134
135 /* Initialize mutexes */
136 Fcb->Header.FastMutex = &Fcb->HeaderMutex;
137 ExInitializeFastMutex(&Fcb->HeaderMutex);
138 FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
139
140 /* Insert into parent's DCB list */
141 InsertTailList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks);
142
143 /* Set backlinks */
144 Fcb->ParentFcb = ParentDcb;
145 Fcb->Vcb = Vcb;
146
147 /* Set file handle and sizes */
148 Fcb->Header.FileSize.LowPart = FileHandle->Filesize;
149 Fcb->Header.ValidDataLength.LowPart = FileHandle->Filesize;
150 Fcb->FatHandle = FileHandle;
151
152 return Fcb;
153 }
154
155 PCCB
156 NTAPI
157 FatCreateCcb()
158 {
159 PCCB Ccb;
160
161 /* Allocate the CCB and zero it */
162 Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB);
163 RtlZeroMemory(Ccb, sizeof(CCB));
164
165 /* Set mandatory header */
166 Ccb->NodeTypeCode = FAT_NTC_FCB;
167 Ccb->NodeByteSize = sizeof(CCB);
168
169 return Ccb;
170 }
171
172 VOID
173 NTAPI
174 FatSetFullNameInFcb(PFCB Fcb,
175 PUNICODE_STRING Name)
176 {
177 PUNICODE_STRING ParentName;
178
179 /* Make sure this FCB's name wasn't already set */
180 ASSERT(Fcb->FullFileName.Buffer == NULL);
181
182 /* First of all, check exact case name */
183 if (Fcb->ExactCaseLongName.Buffer)
184 {
185 ASSERT(Fcb->ExactCaseLongName.Length != 0);
186
187 /* Use exact case name */
188 Name = &Fcb->ExactCaseLongName;
189 }
190
191 /* Treat root dir different */
192 if (FatNodeType(Fcb->ParentFcb) == FAT_NTC_ROOT_DCB)
193 {
194 /* Set lengths */
195 Fcb->FullFileName.MaximumLength = sizeof(WCHAR) + Name->Length;
196 Fcb->FullFileName.Length = Fcb->FullFileName.MaximumLength;
197
198 /* Allocate a buffer */
199 Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag(PagedPool,
200 Fcb->FullFileName.Length,
201 TAG_FILENAME);
202
203 /* Prefix with a backslash */
204 Fcb->FullFileName.Buffer[0] = L'\\';
205
206 /* Copy the name here */
207 RtlCopyMemory(&Fcb->FullFileName.Buffer[1],
208 &Name->Buffer[0],
209 Name->Length );
210 }
211 else
212 {
213 ParentName = &Fcb->ParentFcb->FullFileName;
214
215 /* Check if parent's name is set */
216 if (!ParentName->Buffer)
217 return;
218
219 /* Set lengths */
220 Fcb->FullFileName.MaximumLength =
221 ParentName->Length + sizeof(WCHAR) + Name->Length;
222 Fcb->FullFileName.Length = Fcb->FullFileName.MaximumLength;
223
224 /* Allocate a buffer */
225 Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag(PagedPool,
226 Fcb->FullFileName.Length,
227 TAG_FILENAME );
228
229 /* Copy parent's name here */
230 RtlCopyMemory(&Fcb->FullFileName.Buffer[0],
231 &ParentName->Buffer[0],
232 ParentName->Length );
233
234 /* Add a backslash */
235 Fcb->FullFileName.Buffer[ParentName->Length / sizeof(WCHAR)] = L'\\';
236
237 /* Copy given name here */
238 RtlCopyMemory(&Fcb->FullFileName.Buffer[(ParentName->Length / sizeof(WCHAR)) + 1],
239 &Name->Buffer[0],
240 Name->Length );
241 }
242 }
243
244 /* EOF */