2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filesystems/fastfat/create.c
5 * PURPOSE: Create routines
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES *****************************************************************/
14 /* FUNCTIONS *****************************************************************/
18 FatiOpenRootDcb(IN PFAT_IRP_CONTEXT IrpContext
,
19 IN PFILE_OBJECT FileObject
,
21 IN PACCESS_MASK DesiredAccess
,
22 IN USHORT ShareAccess
,
23 IN ULONG CreateDisposition
)
27 DPRINT1("Opening root directory\n");
29 Iosb
.Status
= STATUS_NOT_IMPLEMENTED
;
36 FatiCreate(IN PFAT_IRP_CONTEXT IrpContext
,
40 BOOLEAN CreateDirectory
;
41 BOOLEAN SequentialOnly
;
42 BOOLEAN NoIntermediateBuffering
;
43 BOOLEAN OpenDirectory
;
45 BOOLEAN OpenTargetDirectory
;
46 BOOLEAN DirectoryFile
;
47 BOOLEAN NonDirectoryFile
;
48 BOOLEAN NoEaKnowledge
;
49 BOOLEAN DeleteOnClose
;
50 BOOLEAN TemporaryFile
;
51 ULONG CreateDisposition
;
60 PFILE_OBJECT FileObject
;
61 PFILE_OBJECT RelatedFO
;
62 UNICODE_STRING FileName
;
64 PFILE_FULL_EA_INFORMATION EaBuffer
;
65 PACCESS_MASK DesiredAccess
;
74 PIO_STACK_LOCATION IrpSp
;
76 /* Get current IRP stack location */
77 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
79 DPRINT1("FatCommonCreate\n", 0 );
80 DPRINT1("Irp = %08lx\n", Irp
);
81 DPRINT1("\t->Flags = %08lx\n", Irp
->Flags
);
82 DPRINT1("\t->FileObject = %08lx\n", IrpSp
->FileObject
);
83 DPRINT1("\t->RelatedFileObject = %08lx\n", IrpSp
->FileObject
->RelatedFileObject
);
84 DPRINT1("\t->FileName = %wZ\n", &IrpSp
->FileObject
->FileName
);
85 DPRINT1("\t->AllocationSize.LowPart = %08lx\n", Irp
->Overlay
.AllocationSize
.LowPart
);
86 DPRINT1("\t->AllocationSize.HighPart = %08lx\n", Irp
->Overlay
.AllocationSize
.HighPart
);
87 DPRINT1("\t->SystemBuffer = %08lx\n", Irp
->AssociatedIrp
.SystemBuffer
);
88 DPRINT1("\t->DesiredAccess = %08lx\n", IrpSp
->Parameters
.Create
.SecurityContext
->DesiredAccess
);
89 DPRINT1("\t->Options = %08lx\n", IrpSp
->Parameters
.Create
.Options
);
90 DPRINT1("\t->FileAttributes = %04x\n", IrpSp
->Parameters
.Create
.FileAttributes
);
91 DPRINT1("\t->ShareAccess = %04x\n", IrpSp
->Parameters
.Create
.ShareAccess
);
92 DPRINT1("\t->EaLength = %08lx\n", IrpSp
->Parameters
.Create
.EaLength
);
94 /* Apply a special hack for Win32, idea taken from FASTFAT reference driver from WDK */
95 if ((IrpSp
->FileObject
->FileName
.Length
> sizeof(WCHAR
)) &&
96 (IrpSp
->FileObject
->FileName
.Buffer
[1] == L
'\\') &&
97 (IrpSp
->FileObject
->FileName
.Buffer
[0] == L
'\\'))
99 /* Remove a leading slash */
100 IrpSp
->FileObject
->FileName
.Length
-= sizeof(WCHAR
);
101 RtlMoveMemory(&IrpSp
->FileObject
->FileName
.Buffer
[0],
102 &IrpSp
->FileObject
->FileName
.Buffer
[1],
103 IrpSp
->FileObject
->FileName
.Length
);
105 /* Check again: if there are still two leading slashes,
106 exit with an error */
107 if ((IrpSp
->FileObject
->FileName
.Length
> sizeof(WCHAR
)) &&
108 (IrpSp
->FileObject
->FileName
.Buffer
[1] == L
'\\') &&
109 (IrpSp
->FileObject
->FileName
.Buffer
[0] == L
'\\'))
111 FatCompleteRequest( IrpContext
, Irp
, STATUS_OBJECT_NAME_INVALID
);
113 DPRINT1("FatiCreate: STATUS_OBJECT_NAME_INVALID\n");
114 return STATUS_OBJECT_NAME_INVALID
;
118 /* Make sure we have SecurityContext */
119 ASSERT(IrpSp
->Parameters
.Create
.SecurityContext
!= NULL
);
121 /* Get necessary data out of IRP */
122 FileObject
= IrpSp
->FileObject
;
123 FileName
= FileObject
->FileName
;
124 RelatedFO
= FileObject
->RelatedFileObject
;
125 AllocationSize
= Irp
->Overlay
.AllocationSize
.LowPart
;
126 EaBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
127 DesiredAccess
= &IrpSp
->Parameters
.Create
.SecurityContext
->DesiredAccess
;
128 Options
= IrpSp
->Parameters
.Create
.Options
;
129 FileAttributes
= (UCHAR
)(IrpSp
->Parameters
.Create
.FileAttributes
& ~FILE_ATTRIBUTE_NORMAL
);
130 ShareAccess
= IrpSp
->Parameters
.Create
.ShareAccess
;
131 EaLength
= IrpSp
->Parameters
.Create
.EaLength
;
133 /* Set VPB to related object's VPB if it exists */
135 FileObject
->Vpb
= RelatedFO
->Vpb
;
137 /* Prepare file attributes mask */
138 FileAttributes
&= (FILE_ATTRIBUTE_READONLY
|
139 FILE_ATTRIBUTE_HIDDEN
|
140 FILE_ATTRIBUTE_SYSTEM
|
141 FILE_ATTRIBUTE_ARCHIVE
);
143 /* Get the volume control object */
144 Vcb
= &((PVOLUME_DEVICE_OBJECT
)IrpSp
->DeviceObject
)->Vcb
;
147 DirectoryFile
= BooleanFlagOn(Options
, FILE_DIRECTORY_FILE
);
148 NonDirectoryFile
= BooleanFlagOn(Options
, FILE_NON_DIRECTORY_FILE
);
149 SequentialOnly
= BooleanFlagOn(Options
, FILE_SEQUENTIAL_ONLY
);
150 NoIntermediateBuffering
= BooleanFlagOn(Options
, FILE_NO_INTERMEDIATE_BUFFERING
);
151 NoEaKnowledge
= BooleanFlagOn(Options
, FILE_NO_EA_KNOWLEDGE
);
152 DeleteOnClose
= BooleanFlagOn(Options
, FILE_DELETE_ON_CLOSE
);
153 TemporaryFile
= BooleanFlagOn(IrpSp
->Parameters
.Create
.FileAttributes
,
154 FILE_ATTRIBUTE_TEMPORARY
);
155 IsPagingFile
= BooleanFlagOn(IrpSp
->Flags
, SL_OPEN_PAGING_FILE
);
156 OpenTargetDirectory
= BooleanFlagOn(IrpSp
->Flags
, SL_OPEN_TARGET_DIRECTORY
);
158 /* Calculate create disposition */
159 CreateDisposition
= (Options
>> 24) & 0x000000ff;
161 /* Get Create/Open directory flags based on it */
162 CreateDirectory
= (BOOLEAN
)(DirectoryFile
&&
163 ((CreateDisposition
== FILE_CREATE
) ||
164 (CreateDisposition
== FILE_OPEN_IF
)));
166 OpenDirectory
= (BOOLEAN
)(DirectoryFile
&&
167 ((CreateDisposition
== FILE_OPEN
) ||
168 (CreateDisposition
== FILE_OPEN_IF
)));
170 /* Validate parameters: directory/nondirectory mismatch and
171 AllocationSize being more than 4GB */
172 if ((DirectoryFile
&& NonDirectoryFile
) ||
173 Irp
->Overlay
.AllocationSize
.HighPart
!= 0)
175 FatCompleteRequest(IrpContext
, Irp
, STATUS_INVALID_PARAMETER
);
177 DPRINT1("FatiCreate: STATUS_INVALID_PARAMETER\n", 0);
178 return STATUS_INVALID_PARAMETER
;
181 /* Acquire the VCB lock exclusively */
182 if (!FatAcquireExclusiveVcb(IrpContext
, Vcb
))
184 // TODO: Postpone the IRP for later processing
186 return STATUS_NOT_IMPLEMENTED
;
189 // TODO: Verify the VCB
191 /* If VCB is locked, then no file openings are possible */
192 if (Vcb
->State
& VCB_STATE_FLAG_LOCKED
)
194 DPRINT1("This volume is locked\n");
195 Status
= STATUS_ACCESS_DENIED
;
197 /* Cleanup and return */
198 FatReleaseVcb(IrpContext
, Vcb
);
202 // TODO: Check if the volume is write protected and disallow DELETE_ON_CLOSE
204 // TODO: Make sure EAs aren't supported on FAT32
206 /* Check if it's a volume open request */
207 if (FileName
.Length
== 0)
209 /* Test related FO to be sure */
211 FatDecodeFileObject(RelatedFO
, &DecodedVcb
, &Fcb
, &Ccb
) == UserVolumeOpen
)
213 /* It is indeed a volume open request */
214 DPRINT1("Volume open request, not implemented now!\n");
219 /* Check if this is a relative open */
222 // RelatedFO will be a parent directory
228 if ((FileName
.Length
== sizeof(WCHAR
)) &&
229 (FileName
.Buffer
[0] == L
'\\'))
231 /* Check if it's ok to open it */
232 if (NonDirectoryFile
)
234 DPRINT1("Trying to open root dir as a file\n");
236 /* Cleanup and return */
237 FatReleaseVcb(IrpContext
, Vcb
);
238 return STATUS_FILE_IS_A_DIRECTORY
;
241 /* Check delete on close on a root dir */
244 /* Cleanup and return */
245 FatReleaseVcb(IrpContext
, Vcb
);
246 return STATUS_CANNOT_DELETE
;
249 /* Call root directory open routine */
250 Iosb
= FatiOpenRootDcb(IrpContext
,
257 Irp
->IoStatus
.Information
= Iosb
.Information
;
259 /* Cleanup and return */
260 FatReleaseVcb(IrpContext
, Vcb
);
266 ParentDcb
= Vcb
->RootDcb
;
267 DPRINT1("ParentDcb %p\n", ParentDcb
);
271 //return Iosb.Status;
272 return STATUS_SUCCESS
;
277 FatCreate(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
279 PFAT_IRP_CONTEXT IrpContext
;
281 //PVOLUME_DEVICE_OBJECT VolumeDO = (PVOLUME_DEVICE_OBJECT)DeviceObject;
283 DPRINT1("FatCreate()\n");
285 /* If it's called with our Disk FS device object - it's always open */
286 // TODO: Add check for CDROM FS device object
287 if (DeviceObject
== FatGlobalData
.DiskDeviceObject
)
289 /* Complete the request and return success */
290 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
291 Irp
->IoStatus
.Information
= FILE_OPENED
;
293 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
295 return STATUS_SUCCESS
;
298 /* Enter FsRtl critical region */
299 FsRtlEnterFileSystem();
301 /* Build an irp context */
302 IrpContext
= FatBuildIrpContext(Irp
, TRUE
);
304 /* Call internal function */
305 Status
= FatiCreate(IrpContext
, Irp
);
307 /* Leave FsRtl critical region */
308 FsRtlExitFileSystem();