2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GNU GPLv3 as published by the Free Software Foundation
4 * FILE: drivers/filesystems/fastfat/dir.c
5 * PURPOSE: Directory Control
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES *****************************************************************/
14 /* FUNCTIONS *****************************************************************/
18 FatDirectoryControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
20 DPRINT1("FatDirectoryControl()\n");
21 return STATUS_NOT_IMPLEMENTED
;
26 FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext
,
31 /* Make sure it's not already created */
32 ASSERT(!Vcb
->RootDcb
);
34 /* Allocate the DCB */
35 Dcb
= FsRtlAllocatePoolWithTag(NonPagedPool
,
40 RtlZeroMemory(Dcb
, sizeof(FCB
));
42 /* Assign it to the VCB */
46 Dcb
->Header
.NodeTypeCode
= FAT_NTC_ROOT_DCB
;
47 Dcb
->Header
.NodeByteSize
= sizeof(FCB
);
49 /* FCB is in a good condition */
50 Dcb
->Condition
= FcbGood
;
52 /* Initialize FCB's resource */
53 Dcb
->Header
.Resource
= &Dcb
->Resource
;
54 ExInitializeResourceLite(&Dcb
->Resource
);
56 /* Initialize Paging Io resource*/
57 Dcb
->Header
.PagingIoResource
= &Dcb
->PagingIoResource
;
58 ExInitializeResourceLite(&Dcb
->PagingIoResource
);
60 /* Initialize a list of parent DCBs*/
61 InitializeListHead(&Dcb
->ParentDcbLinks
);
66 /* Initialize parent's DCB list */
67 InitializeListHead(&Dcb
->Dcb
.ParentDcbList
);
69 /* Initialize the full file name */
70 Dcb
->FullFileName
.Buffer
= L
"\\";
71 Dcb
->FullFileName
.Length
= 1 * sizeof(WCHAR
);
72 Dcb
->FullFileName
.MaximumLength
= 2 * sizeof(WCHAR
);
74 Dcb
->ShortName
.Name
.Ansi
.Buffer
= "\\";
75 Dcb
->ShortName
.Name
.Ansi
.Length
= 1;
76 Dcb
->ShortName
.Name
.Ansi
.MaximumLength
= 2 * sizeof(CHAR
);
78 /* Fill dirent attribute byte copy */
79 Dcb
->DirentFatFlags
= FILE_ATTRIBUTE_DIRECTORY
;
81 /* Initialize advanced FCB header fields */
82 ExInitializeFastMutex(&Dcb
->HeaderMutex
);
83 FsRtlSetupAdvancedHeader(&Dcb
->Header
, &Dcb
->HeaderMutex
);
85 /* Set up first cluster field depending on FAT type */
86 if (TRUE
/*FatIsFat32(Vcb)*/)
88 /* First cluster is really the first cluster of this volume */
89 Dcb
->FirstClusterOfFile
= Vcb
->Bpb
.RootDirFirstCluster
;
91 /* Calculate size of FAT32 root dir */
92 Dcb
->Header
.AllocationSize
.LowPart
= 0xFFFFFFFF;
93 //FatLookupFileAllocationSize(IrpContext, Dcb);
94 DPRINT1("Calculation of a size of a root dir is missing!\n");
96 Dcb
->Header
.FileSize
.QuadPart
= Dcb
->Header
.AllocationSize
.QuadPart
;
105 FatRootDirectoryLbo(&Vcb
->Bpb
),
106 FatRootDirectorySize(&Vcb
->Bpb
));
108 /* Set a real size of the root directory */
109 Dcb
->Header
.FileSize
.QuadPart
= FatRootDirectorySize(&Vcb
->Bpb
);
110 Dcb
->Header
.AllocationSize
.QuadPart
= Dcb
->Header
.FileSize
.QuadPart
;
118 FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext
,
121 IN FF_FILE
*FileHandle
)
125 /* Allocate it and zero it */
126 Fcb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(FCB
), TAG_FCB
);
127 RtlZeroMemory(Fcb
, sizeof(FCB
));
130 Fcb
->Header
.NodeTypeCode
= FAT_NTC_DCB
;
131 Fcb
->Header
.NodeByteSize
= sizeof(FCB
);
132 Fcb
->Condition
= FcbGood
;
134 /* Initialize resources */
135 Fcb
->Header
.Resource
= &Fcb
->Resource
;
136 ExInitializeResourceLite(Fcb
->Header
.Resource
);
138 Fcb
->Header
.PagingIoResource
= &Fcb
->PagingIoResource
;
139 ExInitializeResourceLite(Fcb
->Header
.PagingIoResource
);
141 /* Initialize mutexes */
142 Fcb
->Header
.FastMutex
= &Fcb
->HeaderMutex
;
143 ExInitializeFastMutex(&Fcb
->HeaderMutex
);
144 FsRtlSetupAdvancedHeader(&Fcb
->Header
, &Fcb
->HeaderMutex
);
146 /* Insert into parent's DCB list */
147 InsertHeadList(&ParentDcb
->Dcb
.ParentDcbList
, &Fcb
->ParentDcbLinks
);
150 Fcb
->ParentFcb
= ParentDcb
;
153 /* Initialize parent dcb list */
154 InitializeListHead(&Fcb
->Dcb
.ParentDcbList
);
156 /* Set FullFAT handle */
157 Fcb
->FatHandle
= FileHandle
;
162 FatSetFcbNames(IrpContext
, Fcb
);
164 /* Ensure the full name is set */
165 FatSetFullFileNameInFcb(IrpContext
, Fcb
);
173 FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext
,
174 IN PFILE_OBJECT FileObject
,
177 IN PACCESS_MASK DesiredAccess
,
178 IN USHORT ShareAccess
,
179 IN ULONG CreateDisposition
,
180 IN BOOLEAN NoEaKnowledge
,
181 IN BOOLEAN DeleteOnClose
)
183 IO_STATUS_BLOCK Iosb
= {{0}};
186 /* Exclusively lock this FCB */
187 FatAcquireExclusiveFcb(IrpContext
, Dcb
);
189 /* Check if it's a delete-on-close of a root DCB */
190 if (FatNodeType(Dcb
) == FAT_NTC_ROOT_DCB
&& DeleteOnClose
)
192 Iosb
.Status
= STATUS_CANNOT_DELETE
;
194 /* Release the lock and return */
195 FatReleaseFcb(IrpContext
, Dcb
);
199 /*if (NoEaKnowledge && NodeType(Dcb) != FAT_NTC_ROOT_DCB &&
205 /* Check the create disposition and desired access */
206 if ((CreateDisposition
!= FILE_OPEN
) &&
207 (CreateDisposition
!= FILE_OPEN_IF
))
209 Iosb
.Status
= STATUS_OBJECT_NAME_COLLISION
;
211 /* Release the lock and return */
212 FatReleaseFcb(IrpContext
, Dcb
);
217 if (!FatCheckFileAccess(IrpContext
,
221 Iosb
.Status
= STATUS_ACCESS_DENIED
;
226 /* If it's already opened - check share access */
227 if (Dcb
->OpenCount
> 0)
229 Iosb
.Status
= IoCheckShareAccess(*DesiredAccess
,
235 if (!NT_SUCCESS(Iosb
.Status
))
237 /* Release the lock and return */
238 FatReleaseFcb(IrpContext
, Dcb
);
244 IoSetShareAccess(*DesiredAccess
,
250 /* Set the file object */
251 Ccb
= FatCreateCcb();
252 FatSetFileObject(FileObject
,
257 /* Increase counters */
260 Vcb
->OpenFileCount
++;
261 if (IsFileObjectReadOnly(FileObject
)) Vcb
->ReadOnlyCount
++;
263 /* Set delete on close */
265 SetFlag(Ccb
->Flags
, CCB_DELETE_ON_CLOSE
);
267 /* Clear delay close flag */
268 ClearFlag(Dcb
->State
, FCB_STATE_DELAY_CLOSE
);
271 Iosb
.Status
= STATUS_SUCCESS
;
272 Iosb
.Information
= FILE_OPENED
;
274 /* Release the lock */
275 FatReleaseFcb(IrpContext
, Dcb
);