ed14d74edc86da7e0f48f3e4260f11606ff3179e
[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 /* FUNCTIONS ****************************************************************/
15
16 FSRTL_COMPARISON_RESULT
17 NTAPI
18 FatiCompareNames(PSTRING NameA,
19 PSTRING NameB)
20 {
21 ULONG MinimumLen, i;
22
23 /* Calc the minimum length */
24 MinimumLen = NameA->Length < NameB->Length ? NameA->Length :
25 NameB->Length;
26
27 /* Actually compare them */
28 i = (ULONG)RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinimumLen );
29
30 if (i < MinimumLen)
31 {
32 /* Compare prefixes */
33 if (NameA->Buffer[i] < NameB->Buffer[i])
34 return LessThan;
35 else
36 return GreaterThan;
37 }
38
39 /* Final comparison */
40 if (NameA->Length < NameB->Length)
41 return LessThan;
42 else if (NameA->Length > NameB->Length)
43 return GreaterThan;
44 else
45 return EqualTo;
46 }
47
48 PFCB
49 NTAPI
50 FatFindFcb(PFAT_IRP_CONTEXT IrpContext,
51 PRTL_SPLAY_LINKS *RootNode,
52 PSTRING AnsiName,
53 PBOOLEAN IsDosName)
54 {
55 PFCB_NAME_LINK Node;
56 FSRTL_COMPARISON_RESULT Comparison;
57 PRTL_SPLAY_LINKS Links;
58
59 Links = *RootNode;
60
61 while (Links)
62 {
63 Node = CONTAINING_RECORD(Links, FCB_NAME_LINK, Links);
64
65 /* Compare the prefix */
66 if (*(PUCHAR)Node->Name.Ansi.Buffer != *(PUCHAR)AnsiName->Buffer)
67 {
68 if (*(PUCHAR)Node->Name.Ansi.Buffer < *(PUCHAR)AnsiName->Buffer)
69 Comparison = LessThan;
70 else
71 Comparison = GreaterThan;
72 }
73 else
74 {
75 /* Perform real comparison */
76 Comparison = FatiCompareNames(&Node->Name.Ansi, AnsiName);
77 }
78
79 /* Do they match? */
80 if (Comparison == GreaterThan)
81 {
82 /* No, it's greater, go to the left child */
83 Links = RtlLeftChild(Links);
84 }
85 else if (Comparison == LessThan)
86 {
87 /* No, it's lesser, go to the right child */
88 Links = RtlRightChild(Links);
89 }
90 else
91 {
92 /* Exact match, balance the tree */
93 *RootNode = RtlSplay(Links);
94
95 /* Save type of the name, if needed */
96 if (IsDosName)
97 *IsDosName = Node->IsDosName;
98
99 /* Return the found fcb */
100 return Node->Fcb;
101 }
102 }
103
104 /* Nothing found */
105 return NULL;
106 }
107
108 PFCB
109 NTAPI
110 FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext,
111 IN PVCB Vcb,
112 IN PFCB ParentDcb)
113 {
114 PFCB Fcb;
115
116 /* Allocate it and zero it */
117 Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB);
118 RtlZeroMemory(Fcb, sizeof(FCB));
119
120 /* Set node types */
121 Fcb->Header.NodeTypeCode = FAT_NTC_FCB;
122 Fcb->Header.NodeByteSize = sizeof(FCB);
123 Fcb->Condition = FcbGood;
124
125 /* Initialize resources */
126 Fcb->Header.Resource = &Fcb->Resource;
127 ExInitializeResourceLite(Fcb->Header.Resource);
128
129 Fcb->Header.PagingIoResource = &Fcb->PagingIoResource;
130 ExInitializeResourceLite(Fcb->Header.PagingIoResource);
131
132 /* Initialize mutexes */
133 Fcb->Header.FastMutex = &Fcb->HeaderMutex;
134 ExInitializeFastMutex(&Fcb->HeaderMutex);
135 FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
136
137 /* Insert into parent's DCB list */
138 InsertTailList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks);
139
140 /* Set backlinks */
141 Fcb->ParentFcb = ParentDcb;
142 Fcb->Vcb = Vcb;
143
144 return Fcb;
145 }
146
147 PCCB
148 NTAPI
149 FatCreateCcb()
150 {
151 PCCB Ccb;
152
153 /* Allocate the CCB and zero it */
154 Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB);
155 RtlZeroMemory(Ccb, sizeof(CCB));
156
157 /* Set mandatory header */
158 Ccb->NodeTypeCode = FAT_NTC_FCB;
159 Ccb->NodeByteSize = sizeof(CCB);
160
161 return Ccb;
162 }
163
164 /* EOF */