Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencreate.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS FAT file system driver 00003 * LICENSE: GNU GPLv3 as published by the Free Software Foundation 00004 * FILE: drivers/filesystems/fastfat/create.c 00005 * PURPOSE: Create routines 00006 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #define NDEBUG 00012 #include "fastfat.h" 00013 00014 /* FUNCTIONS *****************************************************************/ 00015 00016 IO_STATUS_BLOCK 00017 NTAPI 00018 FatiOpenRootDcb(IN PFAT_IRP_CONTEXT IrpContext, 00019 IN PFILE_OBJECT FileObject, 00020 IN PVCB Vcb, 00021 IN PACCESS_MASK DesiredAccess, 00022 IN USHORT ShareAccess, 00023 IN ULONG CreateDisposition) 00024 { 00025 IO_STATUS_BLOCK Iosb; 00026 PFCB Dcb; 00027 NTSTATUS Status; 00028 PCCB Ccb; 00029 00030 /* Reference our DCB */ 00031 Dcb = Vcb->RootDcb; 00032 00033 DPRINT("Opening root directory\n"); 00034 00035 /* Exclusively lock this DCB */ 00036 (VOID)FatAcquireExclusiveFcb(IrpContext, Dcb); 00037 00038 do 00039 { 00040 /* Validate parameters */ 00041 if (CreateDisposition != FILE_OPEN && 00042 CreateDisposition != FILE_OPEN_IF) 00043 { 00044 Iosb.Status = STATUS_ACCESS_DENIED; 00045 break; 00046 } 00047 00048 // TODO: Check file access 00049 00050 /* Is it a first time open? */ 00051 if (Dcb->OpenCount == 0) 00052 { 00053 /* Set share access */ 00054 IoSetShareAccess(*DesiredAccess, 00055 ShareAccess, 00056 FileObject, 00057 &Dcb->ShareAccess); 00058 } 00059 else 00060 { 00061 /* Check share access */ 00062 Status = IoCheckShareAccess(*DesiredAccess, 00063 ShareAccess, 00064 FileObject, 00065 &Dcb->ShareAccess, 00066 TRUE); 00067 } 00068 00069 /* Set file object pointers */ 00070 Ccb = FatCreateCcb(); 00071 FatSetFileObject(FileObject, UserDirectoryOpen, Dcb, Ccb); 00072 00073 /* Increment counters */ 00074 Dcb->OpenCount++; 00075 Dcb->UncleanCount++; 00076 Vcb->OpenFileCount++; 00077 if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; 00078 00079 /* Set success statuses */ 00080 Iosb.Status = STATUS_SUCCESS; 00081 Iosb.Information = FILE_OPENED; 00082 } while (FALSE); 00083 00084 /* Release the DCB lock */ 00085 FatReleaseFcb(IrpContext, Dcb); 00086 00087 return Iosb; 00088 } 00089 00090 FF_ERROR 00091 NTAPI 00092 FatiTryToOpen(IN PFILE_OBJECT FileObject, 00093 IN PVCB Vcb) 00094 { 00095 OEM_STRING AnsiName; 00096 CHAR AnsiNameBuf[512]; 00097 FF_ERROR Error; 00098 NTSTATUS Status; 00099 FF_FILE *FileHandle; 00100 00101 /* Convert the name to ANSI */ 00102 AnsiName.Buffer = AnsiNameBuf; 00103 AnsiName.Length = 0; 00104 AnsiName.MaximumLength = sizeof(AnsiNameBuf); 00105 RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); 00106 Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, &FileObject->FileName, FALSE); 00107 if (!NT_SUCCESS(Status)) 00108 { 00109 ASSERT(FALSE); 00110 } 00111 00112 /* Open the file with FullFAT */ 00113 FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, &Error); 00114 00115 /* Close the handle */ 00116 if (FileHandle) FF_Close(FileHandle); 00117 00118 /* Return status */ 00119 return Error; 00120 } 00121 00122 IO_STATUS_BLOCK 00123 NTAPI 00124 FatiOverwriteFile(PFAT_IRP_CONTEXT IrpContext, 00125 PFILE_OBJECT FileObject, 00126 PFCB Fcb, 00127 ULONG AllocationSize, 00128 PFILE_FULL_EA_INFORMATION EaBuffer, 00129 ULONG EaLength, 00130 UCHAR FileAttributes, 00131 ULONG CreateDisposition, 00132 BOOLEAN NoEaKnowledge) 00133 { 00134 IO_STATUS_BLOCK Iosb = {{0}}; 00135 PCCB Ccb; 00136 LARGE_INTEGER Zero; 00137 ULONG NotifyFilter; 00138 00139 Zero.QuadPart = 0; 00140 00141 /* Check Ea mismatch first */ 00142 if (NoEaKnowledge && EaLength > 0) 00143 { 00144 Iosb.Status = STATUS_ACCESS_DENIED; 00145 return Iosb; 00146 } 00147 00148 do 00149 { 00150 /* Check if it's not still mapped */ 00151 if (!MmCanFileBeTruncated(&Fcb->SectionObjectPointers, 00152 &Zero)) 00153 { 00154 /* Fail */ 00155 Iosb.Status = STATUS_USER_MAPPED_FILE; 00156 break; 00157 } 00158 00159 /* Set file object pointers */ 00160 Ccb = FatCreateCcb(); 00161 FatSetFileObject(FileObject, 00162 UserFileOpen, 00163 Fcb, 00164 Ccb); 00165 00166 FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; 00167 00168 /* Indicate that create is in progress */ 00169 Fcb->Vcb->State |= VCB_STATE_CREATE_IN_PROGRESS; 00170 00171 /* Purge the cache section */ 00172 CcPurgeCacheSection(&Fcb->SectionObjectPointers, NULL, 0, FALSE); 00173 00174 /* Add Eas */ 00175 if (EaLength > 0) 00176 { 00177 ASSERT(FALSE); 00178 } 00179 00180 /* Acquire the paging resource */ 00181 (VOID)ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE); 00182 00183 /* Initialize FCB header */ 00184 Fcb->Header.FileSize.QuadPart = 0; 00185 Fcb->Header.ValidDataLength.QuadPart = 0; 00186 00187 /* Let CC know about changed file size */ 00188 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); 00189 00190 // TODO: Actually truncate the file 00191 DPRINT1("TODO: Actually truncate file '%wZ' with a fullfat handle %x\n", &Fcb->FullFileName, Fcb->FatHandle); 00192 00193 /* Release the paging resource */ 00194 ExReleaseResourceLite(Fcb->Header.PagingIoResource); 00195 00196 /* Specify truncate on close */ 00197 Fcb->State |= FCB_STATE_TRUNCATE_ON_CLOSE; 00198 00199 // TODO: Delete previous EA if needed 00200 00201 /* Send notification about changes */ 00202 NotifyFilter = FILE_NOTIFY_CHANGE_LAST_WRITE | 00203 FILE_NOTIFY_CHANGE_ATTRIBUTES | 00204 FILE_NOTIFY_CHANGE_SIZE; 00205 00206 FsRtlNotifyFullReportChange(Fcb->Vcb->NotifySync, 00207 &Fcb->Vcb->NotifyList, 00208 (PSTRING)&Fcb->FullFileName, 00209 Fcb->FullFileName.Length - Fcb->FileNameLength, 00210 NULL, 00211 NULL, 00212 NotifyFilter, 00213 FILE_ACTION_MODIFIED, 00214 NULL); 00215 00216 /* Set success status */ 00217 Iosb.Status = STATUS_SUCCESS; 00218 00219 /* Set correct information code */ 00220 Iosb.Information = (CreateDisposition == FILE_SUPERSEDE) ? FILE_SUPERSEDED : FILE_OVERWRITTEN; 00221 } while (0); 00222 00223 /* Remove the create in progress flag */ 00224 ClearFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS); 00225 00226 return Iosb; 00227 } 00228 00229 IO_STATUS_BLOCK 00230 NTAPI 00231 FatiOpenExistingDir(IN PFAT_IRP_CONTEXT IrpContext, 00232 IN PFILE_OBJECT FileObject, 00233 IN PVCB Vcb, 00234 IN PFCB ParentDcb, 00235 IN PACCESS_MASK DesiredAccess, 00236 IN USHORT ShareAccess, 00237 IN ULONG AllocationSize, 00238 IN PFILE_FULL_EA_INFORMATION EaBuffer, 00239 IN ULONG EaLength, 00240 IN UCHAR FileAttributes, 00241 IN ULONG CreateDisposition, 00242 IN BOOLEAN DeleteOnClose) 00243 { 00244 IO_STATUS_BLOCK Iosb = {{0}}; 00245 OEM_STRING AnsiName; 00246 CHAR AnsiNameBuf[512]; 00247 PFCB Fcb; 00248 NTSTATUS Status; 00249 FF_FILE *FileHandle; 00250 00251 /* Only open is permitted */ 00252 if (CreateDisposition != FILE_OPEN && 00253 CreateDisposition != FILE_OPEN_IF) 00254 { 00255 Iosb.Status = STATUS_OBJECT_NAME_COLLISION; 00256 return Iosb; 00257 } 00258 00259 // TODO: Check dir access 00260 00261 /* Convert the name to ANSI */ 00262 AnsiName.Buffer = AnsiNameBuf; 00263 AnsiName.Length = 0; 00264 AnsiName.MaximumLength = sizeof(AnsiNameBuf); 00265 RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); 00266 Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, &FileObject->FileName, FALSE); 00267 if (!NT_SUCCESS(Status)) 00268 { 00269 ASSERT(FALSE); 00270 } 00271 00272 /* Open the dir with FullFAT */ 00273 FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_DIR, NULL); 00274 00275 if (!FileHandle) 00276 { 00277 Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND; // FIXME: A shortcut for now 00278 return Iosb; 00279 } 00280 00281 /* Create a new DCB for this directory */ 00282 Fcb = FatCreateDcb(IrpContext, Vcb, ParentDcb, FileHandle); 00283 00284 /* Set share access */ 00285 IoSetShareAccess(*DesiredAccess, ShareAccess, FileObject, &Fcb->ShareAccess); 00286 00287 /* Set context and section object pointers */ 00288 FatSetFileObject(FileObject, 00289 UserDirectoryOpen, 00290 Fcb, 00291 FatCreateCcb()); 00292 00293 /* Increase counters */ 00294 Fcb->UncleanCount++; 00295 Fcb->OpenCount++; 00296 Vcb->OpenFileCount++; 00297 if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; 00298 00299 Iosb.Status = STATUS_SUCCESS; 00300 Iosb.Information = FILE_OPENED; 00301 00302 DPRINT1("Successfully opened dir %s\n", AnsiNameBuf); 00303 00304 return Iosb; 00305 } 00306 00307 IO_STATUS_BLOCK 00308 NTAPI 00309 FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext, 00310 IN PFILE_OBJECT FileObject, 00311 IN PVCB Vcb, 00312 IN PFCB ParentDcb, 00313 IN PACCESS_MASK DesiredAccess, 00314 IN USHORT ShareAccess, 00315 IN ULONG AllocationSize, 00316 IN PFILE_FULL_EA_INFORMATION EaBuffer, 00317 IN ULONG EaLength, 00318 IN UCHAR FileAttributes, 00319 IN ULONG CreateDisposition, 00320 IN BOOLEAN IsPagingFile, 00321 IN BOOLEAN DeleteOnClose, 00322 IN BOOLEAN IsDosName) 00323 { 00324 IO_STATUS_BLOCK Iosb = {{0}}; 00325 OEM_STRING AnsiName; 00326 CHAR AnsiNameBuf[512]; 00327 PFCB Fcb; 00328 NTSTATUS Status; 00329 FF_FILE *FileHandle; 00330 FF_ERROR FfError; 00331 00332 /* Check for create file option and fail */ 00333 if (CreateDisposition == FILE_CREATE) 00334 { 00335 Iosb.Status = STATUS_OBJECT_NAME_COLLISION; 00336 return Iosb; 00337 } 00338 00339 // TODO: Check more params 00340 00341 /* Convert the name to ANSI */ 00342 AnsiName.Buffer = AnsiNameBuf; 00343 AnsiName.Length = 0; 00344 AnsiName.MaximumLength = sizeof(AnsiNameBuf); 00345 RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); 00346 Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, &FileObject->FileName, FALSE); 00347 if (!NT_SUCCESS(Status)) 00348 { 00349 ASSERT(FALSE); 00350 } 00351 00352 /* Open the file with FullFAT */ 00353 FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, &FfError); 00354 00355 if (!FileHandle) 00356 { 00357 DPRINT1("Failed to open file '%s', error %ld\n", AnsiName.Buffer, FfError); 00358 Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND; // FIXME: A shortcut for now 00359 return Iosb; 00360 } 00361 DPRINT1("Succeeded opening file '%s'\n", AnsiName.Buffer); 00362 00363 /* Create a new FCB for this file */ 00364 Fcb = FatCreateFcb(IrpContext, Vcb, ParentDcb, FileHandle); 00365 00366 // TODO: Check if overwrite is needed 00367 00368 // TODO: This is usual file open branch, without overwriting! 00369 /* Set context and section object pointers */ 00370 FatSetFileObject(FileObject, 00371 UserFileOpen, 00372 Fcb, 00373 FatCreateCcb()); 00374 FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; 00375 00376 Iosb.Status = STATUS_SUCCESS; 00377 Iosb.Information = FILE_OPENED; 00378 00379 00380 /* Increase counters */ 00381 Fcb->UncleanCount++; 00382 Fcb->OpenCount++; 00383 if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING)) Fcb->NonCachedUncleanCount++; 00384 if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; 00385 00386 return Iosb; 00387 } 00388 00389 IO_STATUS_BLOCK 00390 NTAPI 00391 FatiOpenVolume(IN PFAT_IRP_CONTEXT IrpContext, 00392 IN PFILE_OBJECT FileObject, 00393 IN PVCB Vcb, 00394 IN PACCESS_MASK DesiredAccess, 00395 IN USHORT ShareAccess, 00396 IN ULONG CreateDisposition) 00397 { 00398 PCCB Ccb; 00399 IO_STATUS_BLOCK Iosb = {{0}}; 00400 BOOLEAN VolumeFlushed = FALSE; 00401 00402 /* Check parameters */ 00403 if (CreateDisposition != FILE_OPEN && 00404 CreateDisposition != FILE_OPEN_IF) 00405 { 00406 /* Deny access */ 00407 Iosb.Status = STATUS_ACCESS_DENIED; 00408 } 00409 00410 /* Check if it's exclusive open */ 00411 if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) && 00412 !FlagOn(ShareAccess, FILE_SHARE_DELETE)) 00413 { 00414 // TODO: Check if exclusive read access requested 00415 // and opened handles count is not 0 00416 //if (!FlagOn(ShareAccess, FILE_SHARE_READ) 00417 00418 DPRINT1("Exclusive volume open\n"); 00419 00420 // TODO: Flush the volume 00421 VolumeFlushed = TRUE; 00422 } 00423 else if (FlagOn(*DesiredAccess, FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)) 00424 { 00425 DPRINT1("Shared open\n"); 00426 00427 // TODO: Flush the volume 00428 VolumeFlushed = TRUE; 00429 } 00430 00431 if (VolumeFlushed && 00432 !FlagOn(Vcb->State, VCB_STATE_MOUNTED_DIRTY) && 00433 FlagOn(Vcb->State, VCB_STATE_FLAG_DIRTY) && 00434 CcIsThereDirtyData(Vcb->Vpb)) 00435 { 00436 UNIMPLEMENTED; 00437 } 00438 00439 /* Set share access */ 00440 if (Vcb->DirectOpenCount > 0) 00441 { 00442 /* This volume has already been opened */ 00443 Iosb.Status = IoCheckShareAccess(*DesiredAccess, 00444 ShareAccess, 00445 FileObject, 00446 &Vcb->ShareAccess, 00447 TRUE); 00448 00449 if (!NT_SUCCESS(Iosb.Status)) 00450 { 00451 ASSERT(FALSE); 00452 } 00453 } 00454 else 00455 { 00456 /* This is the first time open */ 00457 IoSetShareAccess(*DesiredAccess, 00458 ShareAccess, 00459 FileObject, 00460 &Vcb->ShareAccess); 00461 } 00462 00463 /* Set file object pointers */ 00464 Ccb = FatCreateCcb(); 00465 FatSetFileObject(FileObject, UserVolumeOpen, Vcb, Ccb); 00466 FileObject->SectionObjectPointer = &Vcb->SectionObjectPointers; 00467 00468 /* Increase direct open count */ 00469 Vcb->DirectOpenCount++; 00470 Vcb->OpenFileCount++; 00471 if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++; 00472 00473 /* Set no buffering flag */ 00474 FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING; 00475 00476 // TODO: User's access check 00477 00478 Iosb.Status = STATUS_SUCCESS; 00479 Iosb.Information = FILE_OPENED; 00480 00481 return Iosb; 00482 } 00483 00484 NTSTATUS 00485 NTAPI 00486 FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, 00487 IN PIRP Irp) 00488 { 00489 /* Boolean options */ 00490 BOOLEAN CreateDirectory; 00491 BOOLEAN SequentialOnly; 00492 BOOLEAN NoIntermediateBuffering; 00493 BOOLEAN OpenDirectory; 00494 BOOLEAN IsPagingFile; 00495 BOOLEAN OpenTargetDirectory; 00496 BOOLEAN IsDirectoryFile; 00497 BOOLEAN NonDirectoryFile; 00498 BOOLEAN NoEaKnowledge; 00499 BOOLEAN DeleteOnClose; 00500 BOOLEAN TemporaryFile; 00501 ULONG CreateDisposition; 00502 00503 /* Control blocks */ 00504 PVCB Vcb, DecodedVcb, RelatedVcb; 00505 PFCB Fcb, NextFcb, RelatedDcb; 00506 PCCB Ccb, RelatedCcb; 00507 PFCB ParentDcb; 00508 00509 /* IRP data */ 00510 PFILE_OBJECT FileObject; 00511 PFILE_OBJECT RelatedFO; 00512 UNICODE_STRING FileName; 00513 ULONG AllocationSize; 00514 PFILE_FULL_EA_INFORMATION EaBuffer; 00515 PACCESS_MASK DesiredAccess; 00516 ULONG Options; 00517 UCHAR FileAttributes; 00518 USHORT ShareAccess; 00519 ULONG EaLength; 00520 00521 /* Misc */ 00522 NTSTATUS Status; 00523 IO_STATUS_BLOCK Iosb; 00524 PIO_STACK_LOCATION IrpSp; 00525 BOOLEAN EndBackslash = FALSE, OpenedAsDos, FirstRun = TRUE; 00526 UNICODE_STRING RemainingPart, FirstName, NextName, FileNameUpcased; 00527 OEM_STRING AnsiFirstName; 00528 FF_ERROR FfError; 00529 TYPE_OF_OPEN TypeOfOpen; 00530 BOOLEAN OplockPostIrp = FALSE; 00531 00532 Iosb.Status = STATUS_SUCCESS; 00533 00534 /* Get current IRP stack location */ 00535 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00536 00537 DPRINT("FatCommonCreate\n", 0 ); 00538 DPRINT("Irp = %08lx\n", Irp ); 00539 DPRINT("\t->Flags = %08lx\n", Irp->Flags ); 00540 DPRINT("\t->FileObject = %08lx\n", IrpSp->FileObject ); 00541 DPRINT("\t->RelatedFileObject = %08lx\n", IrpSp->FileObject->RelatedFileObject ); 00542 DPRINT("\t->FileName = %wZ\n", &IrpSp->FileObject->FileName ); 00543 DPRINT("\t->AllocationSize.LowPart = %08lx\n", Irp->Overlay.AllocationSize.LowPart ); 00544 DPRINT("\t->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart ); 00545 DPRINT("\t->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer ); 00546 DPRINT("\t->DesiredAccess = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); 00547 DPRINT("\t->Options = %08lx\n", IrpSp->Parameters.Create.Options ); 00548 DPRINT("\t->FileAttributes = %04x\n", IrpSp->Parameters.Create.FileAttributes ); 00549 DPRINT("\t->ShareAccess = %04x\n", IrpSp->Parameters.Create.ShareAccess ); 00550 DPRINT("\t->EaLength = %08lx\n", IrpSp->Parameters.Create.EaLength ); 00551 00552 /* Apply a special hack for Win32, idea taken from FASTFAT reference driver from WDK */ 00553 if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) && 00554 (IrpSp->FileObject->FileName.Buffer[1] == L'\\') && 00555 (IrpSp->FileObject->FileName.Buffer[0] == L'\\')) 00556 { 00557 /* Remove a leading slash */ 00558 IrpSp->FileObject->FileName.Length -= sizeof(WCHAR); 00559 RtlMoveMemory(&IrpSp->FileObject->FileName.Buffer[0], 00560 &IrpSp->FileObject->FileName.Buffer[1], 00561 IrpSp->FileObject->FileName.Length ); 00562 00563 /* Check again: if there are still two leading slashes, 00564 exit with an error */ 00565 if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) && 00566 (IrpSp->FileObject->FileName.Buffer[1] == L'\\') && 00567 (IrpSp->FileObject->FileName.Buffer[0] == L'\\')) 00568 { 00569 FatCompleteRequest( IrpContext, Irp, STATUS_OBJECT_NAME_INVALID ); 00570 00571 DPRINT1("FatiCreate: STATUS_OBJECT_NAME_INVALID\n"); 00572 return STATUS_OBJECT_NAME_INVALID; 00573 } 00574 } 00575 00576 /* Make sure we have SecurityContext */ 00577 ASSERT(IrpSp->Parameters.Create.SecurityContext != NULL); 00578 00579 /* Get necessary data out of IRP */ 00580 FileObject = IrpSp->FileObject; 00581 FileName = FileObject->FileName; 00582 RelatedFO = FileObject->RelatedFileObject; 00583 AllocationSize = Irp->Overlay.AllocationSize.LowPart; 00584 EaBuffer = Irp->AssociatedIrp.SystemBuffer; 00585 DesiredAccess = &IrpSp->Parameters.Create.SecurityContext->DesiredAccess; 00586 Options = IrpSp->Parameters.Create.Options; 00587 FileAttributes = (UCHAR)(IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL); 00588 ShareAccess = IrpSp->Parameters.Create.ShareAccess; 00589 EaLength = IrpSp->Parameters.Create.EaLength; 00590 00591 /* Set VPB to related object's VPB if it exists */ 00592 if (RelatedFO) 00593 FileObject->Vpb = RelatedFO->Vpb; 00594 00595 /* Reject open by id */ 00596 if (Options & FILE_OPEN_BY_FILE_ID) 00597 { 00598 FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_PARAMETER); 00599 return STATUS_INVALID_PARAMETER; 00600 } 00601 00602 /* Prepare file attributes mask */ 00603 FileAttributes &= (FILE_ATTRIBUTE_READONLY | 00604 FILE_ATTRIBUTE_HIDDEN | 00605 FILE_ATTRIBUTE_SYSTEM | 00606 FILE_ATTRIBUTE_ARCHIVE); 00607 00608 /* Get the volume control object */ 00609 Vcb = &((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->Vcb; 00610 00611 /* Get options */ 00612 IsDirectoryFile = BooleanFlagOn(Options, FILE_DIRECTORY_FILE); 00613 NonDirectoryFile = BooleanFlagOn(Options, FILE_NON_DIRECTORY_FILE); 00614 SequentialOnly = BooleanFlagOn(Options, FILE_SEQUENTIAL_ONLY); 00615 NoIntermediateBuffering = BooleanFlagOn(Options, FILE_NO_INTERMEDIATE_BUFFERING); 00616 NoEaKnowledge = BooleanFlagOn(Options, FILE_NO_EA_KNOWLEDGE); 00617 DeleteOnClose = BooleanFlagOn(Options, FILE_DELETE_ON_CLOSE); 00618 TemporaryFile = BooleanFlagOn(IrpSp->Parameters.Create.FileAttributes, 00619 FILE_ATTRIBUTE_TEMPORARY ); 00620 IsPagingFile = BooleanFlagOn(IrpSp->Flags, SL_OPEN_PAGING_FILE); 00621 OpenTargetDirectory = BooleanFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY); 00622 00623 /* Calculate create disposition */ 00624 CreateDisposition = (Options >> 24) & 0x000000ff; 00625 00626 /* Get Create/Open directory flags based on it */ 00627 CreateDirectory = (BOOLEAN)(IsDirectoryFile && 00628 ((CreateDisposition == FILE_CREATE) || 00629 (CreateDisposition == FILE_OPEN_IF))); 00630 00631 OpenDirectory = (BOOLEAN)(IsDirectoryFile && 00632 ((CreateDisposition == FILE_OPEN) || 00633 (CreateDisposition == FILE_OPEN_IF))); 00634 00635 /* Validate parameters: directory/nondirectory mismatch and 00636 AllocationSize being more than 4GB */ 00637 if ((IsDirectoryFile && NonDirectoryFile) || 00638 Irp->Overlay.AllocationSize.HighPart != 0) 00639 { 00640 FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_PARAMETER); 00641 00642 DPRINT1("FatiCreate: STATUS_INVALID_PARAMETER\n", 0); 00643 return STATUS_INVALID_PARAMETER; 00644 } 00645 00646 /* Acquire the VCB lock exclusively */ 00647 if (!FatAcquireExclusiveVcb(IrpContext, Vcb)) 00648 { 00649 // TODO: Postpone the IRP for later processing 00650 ASSERT(FALSE); 00651 return STATUS_NOT_IMPLEMENTED; 00652 } 00653 00654 // TODO: Verify the VCB 00655 00656 /* If VCB is locked, then no file openings are possible */ 00657 if (Vcb->State & VCB_STATE_FLAG_LOCKED) 00658 { 00659 DPRINT1("This volume is locked\n"); 00660 Status = STATUS_ACCESS_DENIED; 00661 00662 /* Set volume dismount status */ 00663 if (Vcb->Condition != VcbGood) 00664 Status = STATUS_VOLUME_DISMOUNTED; 00665 00666 /* Cleanup and return */ 00667 FatReleaseVcb(IrpContext, Vcb); 00668 FatCompleteRequest(IrpContext, Irp, Status); 00669 return Status; 00670 } 00671 00672 /* Check if the volume is write protected and disallow DELETE_ON_CLOSE */ 00673 if (DeleteOnClose & FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) 00674 { 00675 ASSERT(FALSE); 00676 return STATUS_NOT_IMPLEMENTED; 00677 } 00678 00679 // TODO: Make sure EAs aren't supported on FAT32 00680 00681 /* Check if it's a volume open request */ 00682 if (FileName.Length == 0) 00683 { 00684 /* Test related FO to be sure */ 00685 if (!RelatedFO || 00686 FatDecodeFileObject(RelatedFO, &DecodedVcb, &Fcb, &Ccb) == UserVolumeOpen) 00687 { 00688 /* Check parameters */ 00689 if (IsDirectoryFile || OpenTargetDirectory) 00690 { 00691 Status = IsDirectoryFile ? STATUS_NOT_A_DIRECTORY : STATUS_INVALID_PARAMETER; 00692 00693 /* Unlock VCB */ 00694 FatReleaseVcb(IrpContext, Vcb); 00695 00696 /* Complete the request and return */ 00697 FatCompleteRequest(IrpContext, Irp, Status); 00698 return Status; 00699 } 00700 00701 /* It is indeed a volume open request */ 00702 Iosb = FatiOpenVolume(IrpContext, 00703 FileObject, 00704 Vcb, 00705 DesiredAccess, 00706 ShareAccess, 00707 CreateDisposition); 00708 00709 /* Set resulting information */ 00710 Irp->IoStatus.Information = Iosb.Information; 00711 00712 /* Unlock VCB */ 00713 FatReleaseVcb(IrpContext, Vcb); 00714 00715 /* Complete the request and return */ 00716 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 00717 return Iosb.Status; 00718 } 00719 } 00720 00721 /* Check if this is a relative open */ 00722 if (RelatedFO) 00723 { 00724 /* Decode the file object */ 00725 TypeOfOpen = FatDecodeFileObject(RelatedFO, 00726 &RelatedVcb, 00727 &RelatedDcb, 00728 &RelatedCcb); 00729 00730 /* Check open type */ 00731 if (TypeOfOpen != UserFileOpen && 00732 TypeOfOpen != UserDirectoryOpen) 00733 { 00734 DPRINT1("Invalid file object!\n"); 00735 00736 Status = STATUS_OBJECT_PATH_NOT_FOUND; 00737 00738 /* Cleanup and return */ 00739 FatReleaseVcb(IrpContext, Vcb); 00740 FatCompleteRequest(IrpContext, Irp, Status); 00741 return Status; 00742 } 00743 00744 /* File path must be relative */ 00745 if (FileName.Length != 0 && 00746 FileName.Buffer[0] == L'\\') 00747 { 00748 Status = STATUS_OBJECT_NAME_INVALID; 00749 00750 /* The name is absolute, fail */ 00751 FatReleaseVcb(IrpContext, Vcb); 00752 FatCompleteRequest(IrpContext, Irp, Status); 00753 return Status; 00754 } 00755 00756 /* Make sure volume is the same */ 00757 ASSERT(RelatedVcb == Vcb); 00758 00759 /* Save VPB */ 00760 FileObject->Vpb = RelatedFO->Vpb; 00761 00762 /* Set parent DCB */ 00763 ParentDcb = RelatedDcb; 00764 00765 DPRINT("Opening file '%wZ' relatively to '%wZ'\n", &FileName, &ParentDcb->FullFileName); 00766 } 00767 else 00768 { 00769 /* Absolute open */ 00770 if ((FileName.Length == sizeof(WCHAR)) && 00771 (FileName.Buffer[0] == L'\\')) 00772 { 00773 /* Check if it's ok to open it */ 00774 if (NonDirectoryFile) 00775 { 00776 DPRINT1("Trying to open root dir as a file\n"); 00777 Status = STATUS_FILE_IS_A_DIRECTORY; 00778 00779 /* Cleanup and return */ 00780 FatReleaseVcb(IrpContext, Vcb); 00781 FatCompleteRequest(IrpContext, Irp, Status); 00782 return Status; 00783 } 00784 00785 /* Check for target directory on a root dir */ 00786 if (OpenTargetDirectory) 00787 { 00788 Status = STATUS_INVALID_PARAMETER; 00789 00790 /* Cleanup and return */ 00791 FatReleaseVcb(IrpContext, Vcb); 00792 FatCompleteRequest(IrpContext, Irp, Status); 00793 return Status; 00794 } 00795 00796 /* Check delete on close on a root dir */ 00797 if (DeleteOnClose) 00798 { 00799 Status = STATUS_CANNOT_DELETE; 00800 00801 /* Cleanup and return */ 00802 FatReleaseVcb(IrpContext, Vcb); 00803 FatCompleteRequest(IrpContext, Irp, Status); 00804 return Status; 00805 } 00806 00807 /* Call root directory open routine */ 00808 Iosb = FatiOpenRootDcb(IrpContext, 00809 FileObject, 00810 Vcb, 00811 DesiredAccess, 00812 ShareAccess, 00813 CreateDisposition); 00814 00815 Irp->IoStatus.Information = Iosb.Information; 00816 00817 /* Cleanup and return */ 00818 FatReleaseVcb(IrpContext, Vcb); 00819 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 00820 return Iosb.Status; 00821 } 00822 else 00823 { 00824 /* Not a root dir */ 00825 ParentDcb = Vcb->RootDcb; 00826 DPRINT("ParentDcb %p\n", ParentDcb); 00827 } 00828 } 00829 00830 /* Check for backslash at the end */ 00831 if (FileName.Length && 00832 FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] == L'\\') 00833 { 00834 /* Cut it out */ 00835 FileName.Length -= sizeof(WCHAR); 00836 00837 /* Remember we cut it */ 00838 EndBackslash = TRUE; 00839 } 00840 00841 /* Ensure the name is set */ 00842 if (!ParentDcb->FullFileName.Buffer) 00843 { 00844 /* Set it if it's missing */ 00845 FatSetFullFileNameInFcb(IrpContext, ParentDcb); 00846 } 00847 00848 /* Check max path length */ 00849 if (ParentDcb->FullFileName.Length + FileName.Length + sizeof(WCHAR) <= FileName.Length) 00850 { 00851 DPRINT1("Max length is way off\n"); 00852 Iosb.Status = STATUS_OBJECT_NAME_INVALID; 00853 ASSERT(FALSE); 00854 } 00855 00856 /* Loop through FCBs to find a good one */ 00857 while (TRUE) 00858 { 00859 Fcb = ParentDcb; 00860 00861 /* Dissect the name */ 00862 RemainingPart = FileName; 00863 while (RemainingPart.Length) 00864 { 00865 FsRtlDissectName(RemainingPart, &FirstName, &NextName); 00866 00867 /* Check for validity */ 00868 if ((NextName.Length && NextName.Buffer[0] == L'\\') || 00869 (NextName.Length > 255 * sizeof(WCHAR))) 00870 { 00871 /* The name is invalid */ 00872 DPRINT1("Invalid name found\n"); 00873 Iosb.Status = STATUS_OBJECT_NAME_INVALID; 00874 ASSERT(FALSE); 00875 } 00876 00877 /* Convert the name to ANSI */ 00878 AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length); 00879 AnsiFirstName.Length = 0; 00880 AnsiFirstName.MaximumLength = FirstName.Length; 00881 Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE); 00882 00883 if (!NT_SUCCESS(Status)) 00884 { 00885 DPRINT1("RtlUpcaseUnicodeStringToCountedOemString() failed with 0x%08x\n", Status); 00886 ASSERT(FALSE); 00887 NextFcb = NULL; 00888 AnsiFirstName.Length = 0; 00889 } 00890 else 00891 { 00892 /* Find the coresponding FCB */ 00893 NextFcb = FatFindFcb(IrpContext, 00894 &Fcb->Dcb.SplayLinksAnsi, 00895 (PSTRING)&AnsiFirstName, 00896 &OpenedAsDos); 00897 } 00898 00899 /* If nothing found - try with unicode */ 00900 if (!NextFcb && Fcb->Dcb.SplayLinksUnicode) 00901 { 00902 FileNameUpcased.Buffer = FsRtlAllocatePool(PagedPool, FirstName.Length); 00903 FileNameUpcased.Length = 0; 00904 FileNameUpcased.MaximumLength = FirstName.Length; 00905 00906 /* Downcase and then upcase to normalize it */ 00907 Status = RtlDowncaseUnicodeString(&FileNameUpcased, &FirstName, FALSE); 00908 Status = RtlUpcaseUnicodeString(&FileNameUpcased, &FileNameUpcased, FALSE); 00909 00910 /* Try to find FCB again using unicode name */ 00911 NextFcb = FatFindFcb(IrpContext, 00912 &Fcb->Dcb.SplayLinksUnicode, 00913 (PSTRING)&FileNameUpcased, 00914 &OpenedAsDos); 00915 } 00916 00917 /* Move to the next FCB */ 00918 if (NextFcb) 00919 { 00920 Fcb = NextFcb; 00921 RemainingPart = NextName; 00922 } 00923 00924 /* Break out of this loop if nothing can be found */ 00925 if (!NextFcb || 00926 NextName.Length == 0 || 00927 FatNodeType(NextFcb) == FAT_NTC_FCB) 00928 { 00929 break; 00930 } 00931 } 00932 00933 /* Ensure remaining name doesn't start from a backslash */ 00934 if (RemainingPart.Length && 00935 RemainingPart.Buffer[0] == L'\\') 00936 { 00937 /* Cut it */ 00938 RemainingPart.Buffer++; 00939 RemainingPart.Length -= sizeof(WCHAR); 00940 } 00941 00942 if (Fcb->Condition == FcbGood) 00943 { 00944 /* Good FCB, break out of the loop */ 00945 break; 00946 } 00947 else 00948 { 00949 ASSERT(FALSE); 00950 } 00951 } 00952 00953 /* Treat page file in a special way */ 00954 if (IsPagingFile) 00955 { 00956 UNIMPLEMENTED; 00957 // FIXME: System file too 00958 } 00959 00960 /* Make sure there is no pending delete on a higher-level FCB */ 00961 if (Fcb->State & FCB_STATE_DELETE_ON_CLOSE) 00962 { 00963 Iosb.Status = STATUS_DELETE_PENDING; 00964 00965 /* Cleanup and return */ 00966 FatReleaseVcb(IrpContext, Vcb); 00967 00968 /* Complete the request */ 00969 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 00970 00971 return Iosb.Status; 00972 } 00973 00974 /* We have a valid FCB now */ 00975 if (!RemainingPart.Length) 00976 { 00977 /* Check for target dir open */ 00978 if (OpenTargetDirectory) 00979 { 00980 DPRINT1("Opening target dir is missing\n"); 00981 ASSERT(FALSE); 00982 } 00983 00984 /* Check this FCB's type */ 00985 if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB || 00986 FatNodeType(Fcb) == FAT_NTC_DCB) 00987 { 00988 /* Open a directory */ 00989 if (NonDirectoryFile) 00990 { 00991 /* Forbidden */ 00992 Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; 00993 ASSERT(FALSE); 00994 return Iosb.Status; 00995 } 00996 00997 /* Open existing DCB */ 00998 Iosb = FatiOpenExistingDcb(IrpContext, 00999 FileObject, 01000 Vcb, 01001 Fcb, 01002 DesiredAccess, 01003 ShareAccess, 01004 CreateDisposition, 01005 NoEaKnowledge, 01006 DeleteOnClose); 01007 01008 /* Save information */ 01009 Irp->IoStatus.Information = Iosb.Information; 01010 01011 /* Unlock VCB */ 01012 FatReleaseVcb(IrpContext, Vcb); 01013 01014 /* Complete the request */ 01015 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 01016 01017 return Iosb.Status; 01018 } 01019 else if (FatNodeType(Fcb) == FAT_NTC_FCB) 01020 { 01021 /* Open a file */ 01022 if (OpenDirectory) 01023 { 01024 /* Forbidden */ 01025 Iosb.Status = STATUS_NOT_A_DIRECTORY; 01026 ASSERT(FALSE); 01027 return Iosb.Status; 01028 } 01029 01030 /* Check for trailing backslash */ 01031 if (EndBackslash) 01032 { 01033 /* Forbidden */ 01034 Iosb.Status = STATUS_OBJECT_NAME_INVALID; 01035 ASSERT(FALSE); 01036 return Iosb.Status; 01037 } 01038 01039 Iosb = FatiOpenExistingFcb(IrpContext, 01040 FileObject, 01041 Vcb, 01042 Fcb, 01043 DesiredAccess, 01044 ShareAccess, 01045 AllocationSize, 01046 EaBuffer, 01047 EaLength, 01048 FileAttributes, 01049 CreateDisposition, 01050 NoEaKnowledge, 01051 DeleteOnClose, 01052 OpenedAsDos, 01053 &OplockPostIrp); 01054 01055 /* Check if it's pending */ 01056 if (Iosb.Status != STATUS_PENDING) 01057 { 01058 /* In case of success set cache supported flag */ 01059 if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering) 01060 { 01061 SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED); 01062 } 01063 01064 /* Save information */ 01065 Irp->IoStatus.Information = Iosb.Information; 01066 01067 /* Unlock VCB */ 01068 FatReleaseVcb(IrpContext, Vcb); 01069 01070 /* Complete the request */ 01071 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 01072 01073 return Iosb.Status; 01074 } 01075 else 01076 { 01077 /* Queue this IRP */ 01078 UNIMPLEMENTED; 01079 ASSERT(FALSE); 01080 } 01081 } 01082 else 01083 { 01084 /* Unexpected FCB type */ 01085 KeBugCheckEx(FAT_FILE_SYSTEM, __LINE__, (ULONG_PTR)Fcb, 0, 0); 01086 } 01087 } 01088 01089 /* During parsing we encountered a part which has no attached FCB/DCB. 01090 Check that the parent is really DCB and not FCB */ 01091 if (FatNodeType(Fcb) != FAT_NTC_ROOT_DCB && 01092 FatNodeType(Fcb) != FAT_NTC_DCB) 01093 { 01094 DPRINT1("Weird FCB node type %x, expected DCB or root DCB\n", FatNodeType(Fcb)); 01095 ASSERT(FALSE); 01096 } 01097 01098 /* Create additional DCBs for all path items */ 01099 ParentDcb = Fcb; 01100 while (TRUE) 01101 { 01102 if (FirstRun) 01103 { 01104 RemainingPart = NextName; 01105 if (AnsiFirstName.Length) 01106 Status = STATUS_SUCCESS; 01107 else 01108 Status = STATUS_UNMAPPABLE_CHARACTER; 01109 01110 /* First run init is done */ 01111 FirstRun = FALSE; 01112 } 01113 else 01114 { 01115 FsRtlDissectName(RemainingPart, &FirstName, &RemainingPart); 01116 01117 /* Check for validity */ 01118 if ((RemainingPart.Length && RemainingPart.Buffer[0] == L'\\') || 01119 (NextName.Length > 255 * sizeof(WCHAR))) 01120 { 01121 /* The name is invalid */ 01122 DPRINT1("Invalid name found\n"); 01123 Iosb.Status = STATUS_OBJECT_NAME_INVALID; 01124 ASSERT(FALSE); 01125 } 01126 01127 /* Convert the name to ANSI */ 01128 AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length); 01129 AnsiFirstName.Length = 0; 01130 AnsiFirstName.MaximumLength = FirstName.Length; 01131 Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE); 01132 } 01133 01134 if (!NT_SUCCESS(Status)) 01135 { 01136 ASSERT(FALSE); 01137 } 01138 01139 DPRINT("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart); 01140 01141 /* Break if came to the end */ 01142 if (!RemainingPart.Length) break; 01143 01144 /* Create a DCB for this entry */ 01145 ParentDcb = FatCreateDcb(IrpContext, 01146 Vcb, 01147 ParentDcb, 01148 NULL); 01149 01150 /* Set its name */ 01151 FatSetFullNameInFcb(ParentDcb, &FirstName); 01152 } 01153 01154 /* Try to open it and get a result, saying if this is a dir or a file */ 01155 FfError = FatiTryToOpen(FileObject, Vcb); 01156 01157 /* Check if we need to open target directory */ 01158 if (OpenTargetDirectory) 01159 { 01160 // TODO: Open target directory 01161 UNIMPLEMENTED; 01162 } 01163 01164 /* Check, if path is a existing directory or file */ 01165 if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR || 01166 FfError == FF_ERR_FILE_ALREADY_OPEN || 01167 FfError == FF_ERR_NONE) 01168 { 01169 if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR) 01170 { 01171 if (NonDirectoryFile) 01172 { 01173 DPRINT1("Can't open dir as a file\n"); 01174 01175 /* Unlock VCB */ 01176 FatReleaseVcb(IrpContext, Vcb); 01177 01178 /* Complete the request */ 01179 Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; 01180 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 01181 return Iosb.Status; 01182 } 01183 01184 /* Open this directory */ 01185 Iosb = FatiOpenExistingDir(IrpContext, 01186 FileObject, 01187 Vcb, 01188 ParentDcb, 01189 DesiredAccess, 01190 ShareAccess, 01191 AllocationSize, 01192 EaBuffer, 01193 EaLength, 01194 FileAttributes, 01195 CreateDisposition, 01196 DeleteOnClose); 01197 01198 Irp->IoStatus.Information = Iosb.Information; 01199 01200 /* Unlock VCB */ 01201 FatReleaseVcb(IrpContext, Vcb); 01202 01203 /* Complete the request */ 01204 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 01205 01206 return Iosb.Status; 01207 } 01208 else 01209 { 01210 /* This is opening an existing file */ 01211 if (OpenDirectory) 01212 { 01213 /* But caller wanted a dir */ 01214 Status = STATUS_NOT_A_DIRECTORY; 01215 01216 /* Unlock VCB */ 01217 FatReleaseVcb(IrpContext, Vcb); 01218 01219 /* Complete the request */ 01220 FatCompleteRequest(IrpContext, Irp, Status); 01221 01222 return Status; 01223 } 01224 01225 /* If end backslash here, then it's definately not permitted, 01226 since we're opening files here */ 01227 if (EndBackslash) 01228 { 01229 /* Unlock VCB */ 01230 FatReleaseVcb(IrpContext, Vcb); 01231 01232 /* Complete the request */ 01233 Iosb.Status = STATUS_OBJECT_NAME_INVALID; 01234 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 01235 return Iosb.Status; 01236 } 01237 01238 /* Try to open the file */ 01239 Iosb = FatiOpenExistingFile(IrpContext, 01240 FileObject, 01241 Vcb, 01242 ParentDcb, 01243 DesiredAccess, 01244 ShareAccess, 01245 AllocationSize, 01246 EaBuffer, 01247 EaLength, 01248 FileAttributes, 01249 CreateDisposition, 01250 FALSE, 01251 DeleteOnClose, 01252 OpenedAsDos); 01253 01254 /* In case of success set cache supported flag */ 01255 if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering) 01256 { 01257 SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED); 01258 } 01259 01260 Irp->IoStatus.Information = Iosb.Information; 01261 01262 /* Unlock VCB */ 01263 FatReleaseVcb(IrpContext, Vcb); 01264 01265 /* Complete the request */ 01266 FatCompleteRequest(IrpContext, Irp, Iosb.Status); 01267 01268 return Iosb.Status; 01269 } 01270 } 01271 01272 /* We come here only in the case when a new file is created */ 01273 //ASSERT(FALSE); 01274 DPRINT1("TODO: Create a new file/directory, called '%wZ'\n", &IrpSp->FileObject->FileName); 01275 01276 Status = STATUS_NOT_IMPLEMENTED; 01277 01278 /* Unlock VCB */ 01279 FatReleaseVcb(IrpContext, Vcb); 01280 01281 /* Complete the request */ 01282 FatCompleteRequest(IrpContext, Irp, Status); 01283 01284 return Status; 01285 } 01286 01287 NTSTATUS 01288 NTAPI 01289 FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) 01290 { 01291 PFAT_IRP_CONTEXT IrpContext; 01292 NTSTATUS Status; 01293 01294 /* If it's called with our Disk FS device object - it's always open */ 01295 // TODO: Add check for CDROM FS device object 01296 if (DeviceObject == FatGlobalData.DiskDeviceObject) 01297 { 01298 /* Complete the request and return success */ 01299 Irp->IoStatus.Status = STATUS_SUCCESS; 01300 Irp->IoStatus.Information = FILE_OPENED; 01301 01302 IoCompleteRequest(Irp, IO_DISK_INCREMENT); 01303 01304 return STATUS_SUCCESS; 01305 } 01306 01307 /* Enter FsRtl critical region */ 01308 FsRtlEnterFileSystem(); 01309 01310 /* Build an irp context */ 01311 IrpContext = FatBuildIrpContext(Irp, TRUE); 01312 01313 /* Call internal function */ 01314 Status = FatiCreate(IrpContext, Irp); 01315 01316 /* Leave FsRtl critical region */ 01317 FsRtlExitFileSystem(); 01318 01319 return Status; 01320 } 01321 01322 /* EOF */ Generated on Fri May 25 2012 04:15:16 for ReactOS by
1.7.6.1
|