ReactOS 0.4.16-dev-297-gc569aee
create.cpp File Reference
#include "udffs.h"
Include dependency graph for create.cpp:

Go to the source code of this file.

Macros

#define IsFileObjectReadOnly(FO)   (!((FO)->WriteAccess | (FO)->DeleteAccess))
 
#define UDF_BUG_CHECK_ID   UDF_FILE_CREATE
 
#define MEM_USABS_TAG   "US_Abs"
 
#define MEM_USLOC_TAG   "US_Loc"
 
#define MEM_USOBJ_TAG   "US_Obj"
 
#define UDF_LOG_CREATE_DISPOSITION
 
#define OpenForBackup   (RequestedOptions & FILE_OPEN_FOR_BACKUP_INTENT)
 
#define DirectoryOnlyRequested   (RequestedOptions & FILE_DIRECTORY_FILE)
 
#define FileOnlyRequested   (RequestedOptions & FILE_NON_DIRECTORY_FILE)
 
#define NoBufferingSpecified   (RequestedOptions & FILE_NO_INTERMEDIATE_BUFFERING)
 
#define SequentialIoRequested   (RequestedOptions & FILE_SEQUENTIAL_ONLY ? TRUE : FALSE)
 
#define NoExtAttrKnowledge   /*(RequestedOptions & FILE_NO_EA_KNOWLEDGE) ?*/ TRUE /*: FALSE*/
 
#define OpenByFileId   (RequestedOptions & FILE_OPEN_BY_FILE_ID)
 

Functions

NTSTATUS NTAPI UDFCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
VOID __fastcall UDFReleaseResFromCreate (IN PERESOURCE *PagingIoRes, IN PERESOURCE *Res1, IN PERESOURCE *Res2)
 
VOID __fastcall UDFAcquireParent (IN PUDF_FILE_INFO RelatedFileInfo, IN PERESOURCE *Res1, IN PERESOURCE *Res2)
 
NTSTATUS UDFCommonCreate (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS UDFFirstOpenFile (IN PVCB Vcb, IN PFILE_OBJECT PtrNewFileObject, OUT PtrUDFFCB *PtrNewFcb, IN PUDF_FILE_INFO RelatedFileInfo, IN PUDF_FILE_INFO NewFileInfo, IN PUNICODE_STRING LocalPath, IN PUNICODE_STRING CurName)
 
NTSTATUS UDFOpenFile (PVCB Vcb, PFILE_OBJECT PtrNewFileObject, PtrUDFFCB PtrNewFcb)
 
NTSTATUS UDFInitializeFCB (IN PtrUDFFCB PtrNewFcb, IN PVCB Vcb, IN PtrUDFObjectName PtrObjectName, IN ULONG Flags, IN PFILE_OBJECT FileObject)
 

Macro Definition Documentation

◆ DirectoryOnlyRequested

#define DirectoryOnlyRequested   (RequestedOptions & FILE_DIRECTORY_FILE)

◆ FileOnlyRequested

#define FileOnlyRequested   (RequestedOptions & FILE_NON_DIRECTORY_FILE)

◆ IsFileObjectReadOnly

#define IsFileObjectReadOnly (   FO)    (!((FO)->WriteAccess | (FO)->DeleteAccess))

Definition at line 19 of file create.cpp.

◆ MEM_USABS_TAG

#define MEM_USABS_TAG   "US_Abs"

Definition at line 24 of file create.cpp.

◆ MEM_USLOC_TAG

#define MEM_USLOC_TAG   "US_Loc"

Definition at line 25 of file create.cpp.

◆ MEM_USOBJ_TAG

#define MEM_USOBJ_TAG   "US_Obj"

Definition at line 26 of file create.cpp.

◆ NoBufferingSpecified

#define NoBufferingSpecified   (RequestedOptions & FILE_NO_INTERMEDIATE_BUFFERING)

◆ NoExtAttrKnowledge

#define NoExtAttrKnowledge   /*(RequestedOptions & FILE_NO_EA_KNOWLEDGE) ?*/ TRUE /*: FALSE*/

◆ OpenByFileId

#define OpenByFileId   (RequestedOptions & FILE_OPEN_BY_FILE_ID)

◆ OpenForBackup

#define OpenForBackup   (RequestedOptions & FILE_OPEN_FOR_BACKUP_INTENT)

◆ SequentialIoRequested

#define SequentialIoRequested   (RequestedOptions & FILE_SEQUENTIAL_ONLY ? TRUE : FALSE)

◆ UDF_BUG_CHECK_ID

#define UDF_BUG_CHECK_ID   UDF_FILE_CREATE

Definition at line 22 of file create.cpp.

◆ UDF_LOG_CREATE_DISPOSITION

#define UDF_LOG_CREATE_DISPOSITION

Definition at line 28 of file create.cpp.

Function Documentation

◆ UDFAcquireParent()

VOID __fastcall UDFAcquireParent ( IN PUDF_FILE_INFO  RelatedFileInfo,
IN PERESOURCE Res1,
IN PERESOURCE Res2 
)

Definition at line 146 of file create.cpp.

151{
152 if(RelatedFileInfo->Fcb &&
153 RelatedFileInfo->Fcb->ParentFcb) {
154
155 UDF_CHECK_PAGING_IO_RESOURCE(RelatedFileInfo->Fcb->ParentFcb->NTRequiredFCB);
156 UDFAcquireResourceExclusive((*Res2) = &(RelatedFileInfo->Fcb->ParentFcb->NTRequiredFCB->MainResource),TRUE);
157 }
158
159 UDF_CHECK_PAGING_IO_RESOURCE(RelatedFileInfo->Fcb->NTRequiredFCB);
160 UDFAcquireResourceExclusive((*Res1) = &(RelatedFileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
161
162 UDFInterlockedIncrement((PLONG)&(RelatedFileInfo->Fcb->ReferenceCount));
163 UDFInterlockedIncrement((PLONG)&(RelatedFileInfo->Dloc->CommonFcb->CommonRefCount));
164 UDFReferenceFile__(RelatedFileInfo);
165 ASSERT_REF(RelatedFileInfo->Fcb->ReferenceCount >= RelatedFileInfo->RefCount);
166} // end UDFAcquireParent()
#define TRUE
Definition: types.h:120
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
int32_t * PLONG
Definition: typedefs.h:58
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:260

Referenced by UDFCommonCreate().

◆ UDFCommonCreate()

NTSTATUS UDFCommonCreate ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 186 of file create.cpp.

190{
193 PIO_SECURITY_CONTEXT PtrSecurityContext = NULL;
194 PFILE_OBJECT PtrNewFileObject = NULL;
195 PFILE_OBJECT PtrRelatedFileObject = NULL;
196 LONGLONG AllocationSize; // if we create a new file
197 PFILE_FULL_EA_INFORMATION PtrExtAttrBuffer = NULL;
198 ULONG RequestedOptions;
199 ULONG RequestedDisposition;
201 USHORT TmpFileAttributes;
203 ULONG ExtAttrLength = 0;
206
208 _SEH2_VOLATILE BOOLEAN AcquiredVcb = FALSE;
209 BOOLEAN OpenExisting = FALSE;
210 PERESOURCE Res1 = NULL;
211 PERESOURCE Res2 = NULL;
212 PERESOURCE PagingIoRes = NULL;
213
214// BOOLEAN DirectoryOnlyRequested;
215// BOOLEAN FileOnlyRequested;
216// BOOLEAN NoBufferingSpecified;
217 BOOLEAN WriteThroughRequested;
218 BOOLEAN DeleteOnCloseSpecified;
219// BOOLEAN NoExtAttrKnowledge;
220// BOOLEAN CreateTreeConnection = FALSE;
221// BOOLEAN OpenByFileId;
222
223 // Are we dealing with a page file?
224 BOOLEAN PageFileManipulation;
225 // Is this open for a target directory (used in rename operations)?
226 BOOLEAN OpenTargetDirectory;
227 // Should we ignore case when attempting to locate the object?
229
230 PtrUDFCCB PtrRelatedCCB = NULL, PtrNewCcb = NULL;
231 PtrUDFFCB PtrRelatedFCB = NULL, PtrNewFcb = NULL;
233
234 ULONG ReturnedInformation = 0;
235
236 UNICODE_STRING TargetObjectName;
237 UNICODE_STRING RelatedObjectName;
238
239 UNICODE_STRING AbsolutePathName; // '\aaa\cdf\fff\rrrr.tre:s'
240 UNICODE_STRING LocalPath; // '\aaa\cdf'
241 UNICODE_STRING CurName; // 'cdf'
242 UNICODE_STRING TailName; // 'fff\rrrr.tre:s'
243 UNICODE_STRING LastGoodName; // it depends...
244 UNICODE_STRING LastGoodTail; // it depends...
246
247 PUDF_FILE_INFO RelatedFileInfo;
248 PUDF_FILE_INFO OldRelatedFileInfo = NULL;
249 PUDF_FILE_INFO NewFileInfo = NULL;
250 PUDF_FILE_INFO LastGoodFileInfo = NULL;
251 PWCHAR TmpBuffer;
252 ULONG TreeLength = 0;
253// ULONG i = 0;
254
255 BOOLEAN StreamOpen = FALSE;
256 BOOLEAN StreamExists = FALSE;
257 BOOLEAN RestoreVCBOpenCounter = FALSE;
258 BOOLEAN RestoreShareAccess = FALSE;
259 PWCHAR TailNameBuffer = NULL;
260 ULONG SNameIndex = 0;
261
262 TmPrint(("UDFCommonCreate:\n"));
263
264 ASSERT(PtrIrpContext);
265 ASSERT(Irp);
266
267 _SEH2_TRY {
268
269 AbsolutePathName.Buffer =
270 LocalPath.Buffer = NULL;
271 // If we were called with our file system device object instead of a
272 // volume device object, just complete this request with STATUS_SUCCESS.
273 if (!(PtrIrpContext->TargetDeviceObject->DeviceExtension)) {
274
275 ReturnedInformation = FILE_OPENED;
277 }
278
279 AbsolutePathName.Length = AbsolutePathName.MaximumLength =
280 LocalPath.Length = LocalPath.MaximumLength = 0;
281 // First, get a pointer to the current I/O stack location
283 ASSERT(IrpSp);
284
285 // If the caller cannot block, post the request to be handled
286 // asynchronously
287 if (!(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK)) {
288 // We must defer processing of this request since we could
289 // block anytime while performing the create/open ...
290 ASSERT(FALSE);
291 RC = UDFPostRequest(PtrIrpContext, Irp);
292 try_return(RC);
293 }
294
295 // Now, we can obtain the parameters specified by the user.
296 // Note that the file object is the new object created by the
297 // I/O Manager in anticipation that this create/open request
298 // will succeed.
299 PtrNewFileObject = IrpSp->FileObject;
300 TargetObjectName = PtrNewFileObject->FileName;
301 PtrRelatedFileObject = PtrNewFileObject->RelatedFileObject;
302
303 // If a related file object is present, get the pointers
304 // to the CCB and the FCB for the related file object
305 if (PtrRelatedFileObject) {
306 PtrRelatedCCB = (PtrUDFCCB)(PtrRelatedFileObject->FsContext2);
307 ASSERT(PtrRelatedCCB);
309 // each CCB in turn points to a FCB
310 PtrRelatedFCB = PtrRelatedCCB->Fcb;
311 ASSERT(PtrRelatedFCB);
313 ||(PtrRelatedFCB->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB));
314 RelatedObjectName = PtrRelatedFileObject->FileName;
315 if (!(RelatedObjectName.Length) || (RelatedObjectName.Buffer[0] != L'\\')) {
316 if(PtrRelatedFCB->FCBName)
317 RelatedObjectName = PtrRelatedFCB->FCBName->ObjectName;
318 }
319 }
320
321 // Allocation size is only used if a new file is created
322 // or a file is superseded.
323 AllocationSize = Irp->Overlay.AllocationSize.QuadPart;
324
325 // Get a ptr to the supplied security context
326 PtrSecurityContext = IrpSp->Parameters.Create.SecurityContext;
327 AccessState = PtrSecurityContext->AccessState;
328
329 // The desired access can be obtained from the SecurityContext
330 DesiredAccess = PtrSecurityContext->DesiredAccess;
331
332 // Two values are supplied in the Create.Options field:
333 // (a) the actual user supplied options
334 // (b) the create disposition
335 RequestedOptions = (IrpSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS);
336
337 // The file disposition is packed with the user options ...
338 // Disposition includes FILE_SUPERSEDE, FILE_OPEN_IF, etc.
339 RequestedDisposition = (IrpSp->Parameters.Create.Options >> 24);// & 0xFF;
340
341//#ifdef UDF_LOG_CREATE_DISPOSITION
342 switch(RequestedDisposition) {
343 case FILE_SUPERSEDE:
344 AdPrint((" Dispos: FILE_SUPERSEDE\n"));
345 break;
346 case FILE_OPEN:
347 AdPrint((" Dispos: FILE_OPEN\n"));
348 break;
349 case FILE_CREATE:
350 AdPrint((" Dispos: FILE_CREATE\n"));
351 break;
352 case FILE_OPEN_IF:
353 AdPrint((" Dispos: FILE_OPEN_IF\n"));
354 break;
355 case FILE_OVERWRITE:
356 AdPrint((" Dispos: FILE_OVERWRITE\n"));
357 break;
359 AdPrint((" Dispos: FILE_OVERWRITE_IF\n"));
360 break;
361 default:
362 AdPrint((" Dispos: *** Unknown ***\n"));
363 break;
364 }
365//#endif // UDF_LOG_CREATE_DISPOSITION
366
368 ShareAccess = IrpSp->Parameters.Create.ShareAccess;
369
370 // If the FSD does not support EA manipulation, we might return
371 // invalid parameter if the following are supplied.
372 // EA arguments are only used if a new file is created or a file is
373 // superseded
374
375 // But some applications _require_ EA support
376 // (Notepad... rather strange, isn't it ?)
377
378 // So, for such stupid ones
379 // !!! We shall ignore these parameters !!!
380
381// PtrExtAttrBuffer = (struct _FILE_FULL_EA_INFORMATION *) Irp->AssociatedIrp.SystemBuffer;
382// ExtAttrLength = IrpSp->Parameters.Create.EaLength;
383
384 // Get the options supplied by the user
385
386#define OpenForBackup (RequestedOptions & FILE_OPEN_FOR_BACKUP_INTENT)
387 // User specifies that returned object MUST be a directory.
388 // Lack of presence of this flag does not mean it *cannot* be a
389 // directory *unless* FileOnlyRequested is set (see below)
390
391 // Presence of the flag however, does require that the returned object be
392 // a directory (container) object.
393#define DirectoryOnlyRequested (RequestedOptions & FILE_DIRECTORY_FILE)
394
395 // User specifies that returned object MUST NOT be a directory.
396 // Lack of presence of this flag does not mean it *cannot* be a
397 // file *unless* DirectoryOnlyRequested is set (see above).
398
399 // Presence of the flag however does require that the returned object be
400 // a simple file (non-container) object.
401#define FileOnlyRequested (RequestedOptions & FILE_NON_DIRECTORY_FILE)
402
403 // We cannot cache the file if the following flag is set.
404 // However, things do get a little bit interesting if caching
405 // has been already initiated due to a previous open ...
406 // (maintaining consistency then becomes a little bit more
407 // of a headache - see read/write file descriptions)
408#define NoBufferingSpecified (RequestedOptions & FILE_NO_INTERMEDIATE_BUFFERING)
409
410 // Write-through simply means that the FSD must *not* return from
411 // a user write request until the data has been flushed to secondary
412 // storage (either to disks directly connected to the node or across
413 // the network in the case of a redirector)
414 WriteThroughRequested = (RequestedOptions & FILE_WRITE_THROUGH) ? TRUE : FALSE;
415
416#define SequentialIoRequested (RequestedOptions & FILE_SEQUENTIAL_ONLY ? TRUE : FALSE)
417
418 // Not all of the native file system implementations support
419 // the delete-on-close option. All this means is that after the
420 // last close on the FCB has been performed, the FSD should
421 // delete the file. It simply saves the caller from issuing a
422 // separate delete request. Also, some FSD implementations might choose
423 // to implement a Windows NT idiosyncratic behavior wherein we
424 // could create such "delete-on-close" marked files under directories
425 // marked for deletion. Ordinarily, a FSD will not allow us to create
426 // a new file under a directory that has been marked for deletion.
427 DeleteOnCloseSpecified = (IrpSp->Parameters.Create.Options & FILE_DELETE_ON_CLOSE) ? TRUE : FALSE;
428
429 if(DeleteOnCloseSpecified) {
430 AdPrint((" DeleteOnClose\n"));
431 }
432
433#define NoExtAttrKnowledge /*(RequestedOptions & FILE_NO_EA_KNOWLEDGE) ?*/ TRUE /*: FALSE*/
434
435 // The following flag is only used by the LAN Manager redirector
436 // to initiate a "new mapping" to a remote share. Typically,
437 // a FSD will not see this flag (especially disk based FSD's)
438 // CreateTreeConnection = (RequestedOptions & FILE_CREATE_TREE_CONNECTION) ? TRUE : FALSE;
439
440 // The NTFS file system for exmaple supports the OpenByFileId option.
441 // The FSD may also be able to associate a unique numerical ID with
442 // an on-disk object. The caller would get this ID in a "query file
443 // information" call.
444
445 // Later, the caller might decide to reopen the object, this time
446 // though it may supply the FSD with the file identifier instead of
447 // a file/path name.
448#define OpenByFileId (RequestedOptions & FILE_OPEN_BY_FILE_ID)
449
450 // Are we dealing with a page file?
451 PageFileManipulation = (IrpSp->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE;
452
453 // The open target directory flag is used as part of the sequence of
454 // operations performed by the I/O Manager is response to a file/dir
455 // rename operation. See the explanation in the book for details.
456 OpenTargetDirectory = (IrpSp->Flags & SL_OPEN_TARGET_DIRECTORY) ? TRUE : FALSE;
457
458 // If the FSD supports case-sensitive file name checks, we may
459 // choose to honor the following flag ...
461
462 // Ensure that the operation has been directed to a valid VCB ...
463 Vcb = (PVCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
464 ASSERT(Vcb);
465 ASSERT(Vcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
466// Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
467
468 WriteThroughRequested = WriteThroughRequested ||
469 (Vcb->CompatFlags & UDF_VCB_IC_FORCE_WRITE_THROUGH);
470
471 // Do some preliminary checks to make sure the operation is supported.
472 // We fail in the following cases immediately.
473 // - Open a paging file.
474 // - Open a file with Eas.
475 if(PageFileManipulation) {
476 ReturnedInformation = 0;
477 AdPrint(("Can't create a page file\n"));
479 }
480 if(ExtAttrLength) {
481 ReturnedInformation = 0;
482 AdPrint(("Can't create file with EAs\n"));
484 }
485
487
488 if (Vcb->SoftEjectReq) {
489 AdPrint((" Eject requested\n"));
490 ReturnedInformation = FILE_DOES_NOT_EXIST;
492 }
493
494 // If the volume has been locked, fail the request
495 if ((Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) &&
496 (Vcb->VolumeLockPID != GetCurrentPID())) {
497 AdPrint((" Volume is locked\n"));
499 try_return(RC);
500 }
501 // We need EXCLUSIVE access to Vcb to avoid parallel calls to UDFVerifyVcb()
502 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
503 AcquiredVcb = TRUE;
504
505 // Disk based file systems might decide to verify the logical volume
506 // (if required and only if removable media are supported) at this time
507 RC = UDFVerifyVcb(PtrIrpContext,Vcb);
508 if(!NT_SUCCESS(RC))
509 try_return(RC);
510
511 UDFConvertExclusiveToSharedLite(&(Vcb->VCBResource));
512
514
515 // We fail in the following cases for Read-Only volumes
516 // - Open a target directory.
517 // - Create a file.
518 if(
519 (
520 ((Vcb->origIntegrityType == INTEGRITY_TYPE_OPEN) &&
521 (Vcb->CompatFlags & UDF_VCB_IC_DIRTY_RO))
522#ifndef UDF_READ_ONLY_BUILD
523 || (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)
524#endif //UDF_READ_ONLY_BUILD
525 ) &&
526 (DeleteOnCloseSpecified ||
527 OpenTargetDirectory ||
528 (RequestedDisposition == FILE_CREATE) ||
529 (RequestedDisposition == FILE_OVERWRITE) ||
530 (RequestedDisposition == FILE_OVERWRITE_IF) ||
531 (RequestedDisposition == FILE_SUPERSEDE) ||
532 AllocationSize) ) {
533 ReturnedInformation = 0;
534 AdPrint((" Write protected or dirty\n"));
536 }
537
538/* if(DesiredAccess & (FILE_READ_EA | FILE_WRITE_EA)) {
539 ReturnedInformation = 0;
540 AdPrint((" EAs not supported\n"));
541 try_return(RC = STATUS_ACCESS_DENIED);
542 }*/
543
544 // ****************
545 // If a Volume open is requested, satisfy it now
546 // ****************
547 if (!(PtrNewFileObject->FileName.Length) && (!PtrRelatedFileObject ||
548 (PtrRelatedFCB->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB))) {
549
550 BOOLEAN UndoLock = FALSE;
551
552 AdPrint((" Opening Volume\n"));
553 // If the supplied file name is NULL *and* either there exists
554 // no related file object *or* if a related file object was supplied
555 // but it too refers to a previously opened instance of a logical
556 // volume, this open must be for a logical volume.
557
558 // Note: the FSD might decide to do "special" things (whatever they
559 // might be) in response to an open request for the logical volume.
560
561 // Logical volume open requests are done primarily to get/set volume
562 // information, lock the volume, dismount the volume (using the IOCTL
563 // FSCTL_DISMOUNT_VOLUME) etc.
564
565 // If a volume open is requested, perform checks to ensure that
566 // invalid options have not also been specified ...
567 if ((OpenTargetDirectory) || (PtrExtAttrBuffer)) {
569 }
570
572 // a volume is not a directory
574 }
575
576#ifndef UDF_READ_ONLY_BUILD
577 if (DeleteOnCloseSpecified) {
578 // delete volume.... hmm
580 }
581
582 if ((RequestedDisposition != FILE_OPEN) && (RequestedDisposition != FILE_OPEN_IF)) {
583 // cannot create a new volume, I'm afraid ...
584 ReturnedInformation = FILE_DOES_NOT_EXIST;
586 }
587#endif //UDF_READ_ONLY_BUILD
588
589 UDFPrint((" ShareAccess %x, DesiredAccess %x\n", ShareAccess, DesiredAccess));
590/*
591 if(!(ShareAccess & (FILE_SHARE_WRITE | FILE_SHARE_DELETE)) &&
592 !(DesiredAccess & (FILE_GENERIC_WRITE & ~SYNCHRONIZE)) &&
593 (ShareAccess & FILE_SHARE_READ) ) {
594*/
597 UDFPrint((" R/O volume open\n"));
598 } else {
599
600 UDFPrint((" R/W volume open\n"));
601 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) {
602 UDFPrint((" media-ro\n"));
604 }
605 }
606
610 // do nothing
611 } else {
612
615 // As soon as OpenVolume flushes the volume
616 // we should complete all pending requests (Close)
617
618 UDFPrint((" set UDF_IRP_CONTEXT_FLUSH2_REQUIRED\n"));
620
621/*
622 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
623 UDFReleaseResource(&(Vcb->VCBResource));
624 AcquiredVcb = FALSE;
625
626 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
627 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
628 }
629#ifdef UDF_DELAYED_CLOSE
630 UDFCloseAllDelayed(Vcb);
631#endif //UDF_DELAYED_CLOSE
632
633 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
634 AcquiredVcb = TRUE;
635 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
636*/
637 }
638 }
639
640 // If the user does not want to share write or delete then we will try
641 // and take out a lock on the volume.
643 // Do a quick check here for handles on exclusive open.
644 if ((Vcb->VCBHandleCount) &&
646 // Sharing violation
647 UDFPrint((" !FILE_SHARE_READ + open handles (%d)\n", Vcb->VCBHandleCount));
649 }
651
652 UDFPrint((" perform flush\n"));
653 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_FLUSH2_REQUIRED;
654
655 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
656 UDFReleaseResource(&(Vcb->VCBResource));
657 AcquiredVcb = FALSE;
658
659 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
660 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
661 }
662#ifdef UDF_DELAYED_CLOSE
664#endif //UDF_DELAYED_CLOSE
665
666 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
667 AcquiredVcb = TRUE;
668 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
669
671
673 ((Vcb->VCBOpenCount - UDF_RESIDUAL_REFERENCE) != (Vcb->VCBOpenCountRO))) {
674 UDFPrint((" FILE_SHARE_READ + R/W handles: %d(%d) -> STATUS_SHARING_VIOLATION ?\n",
675 Vcb->VCBOpenCount - UDF_RESIDUAL_REFERENCE,
676 Vcb->VCBOpenCountRO));
677 /* we shall not check it here, let System do it in IoCheckShareAccess() */
678 //try_return(RC = STATUS_SHARING_VIOLATION);
679 }
680 }
681 // Lock the volume
683 UDFPrint((" set Lock\n"));
684 Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_LOCKED;
685 Vcb->VolumeLockFileObject = PtrNewFileObject;
686 UndoLock = TRUE;
687 } else
689 UDFPrint((" set UDF_IRP_CONTEXT_FLUSH_REQUIRED\n"));
691 }
692 }
693
694 PtrNewFcb = (PtrUDFFCB)Vcb;
695 ASSERT(!(PtrNewFcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE));
696
697 RC = UDFOpenFile(Vcb, PtrNewFileObject, PtrNewFcb);
698 if (!NT_SUCCESS(RC))
699 goto op_vol_accs_dnd;
700
701 PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
702 if(PtrNewCcb) PtrNewCcb->CCBFlags |= UDF_CCB_VOLUME_OPEN;
703 // Check _Security_
704 RC = UDFCheckAccessRights(NULL, AccessState, Vcb->RootDirFCB, PtrNewCcb, DesiredAccess, ShareAccess);
705 if (!NT_SUCCESS(RC)) {
706 AdPrint((" Access violation (Volume)\n"));
707 goto op_vol_accs_dnd;
708 }
709 // Check _ShareAccess_
710 RC = UDFCheckAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
711 if(!NT_SUCCESS(RC)) {
712 AdPrint((" Sharing violation (Volume)\n"));
713op_vol_accs_dnd:
714 if(UndoLock) {
715 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_LOCKED;
716 Vcb->VolumeLockFileObject = NULL;
717 }
718 try_return(RC);
719 }
720
721// NoBufferingSpecified = TRUE; See #define above
722 RequestedOptions |= FILE_NO_INTERMEDIATE_BUFFERING;
723
724 ReturnedInformation = FILE_OPENED;
725 UDFNotifyVolumeEvent(PtrNewFileObject, FSRTL_VOLUME_LOCK);
726 try_return(RC);
727 }
728
729 if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
731 ReturnedInformation = 0;
732 AdPrint((" Can't open anything on blank volume ;)\n"));
734 }
735
737 ReturnedInformation = 0;
738 AdPrint((" Illegal share access\n"));
740 }
741 // we could mount blank R/RW media in order to allow
742 // user-mode applications to get access with Write privileges
744
745 // we should check appropriate privilege if OpenForBackup requested
746 if(OpenForBackup) {
749 }
750 }
751
752 // The FSD might wish to implement the open-by-id option. The "id"
753 // is some unique numerical representation of the on-disk object.
754 // The caller then therefore give us this file id and the FSD
755 // should be completely capable of "opening" the object (it must
756 // exist since the caller received an id for the object from the
757 // FSD in a "query file" call ...
758
759 // If the file has been deleted in the meantime, we'll return
760 // "not found"
761
762 // ****************
763 // Open by FileID
764 // ****************
765 if (OpenByFileId) {
766 // perform the open ...
767 PUNICODE_STRING TmpPath;
768 LONGLONG Id;
769
770 UDFPrint((" open by File ID\n"));
771 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
772 ReturnedInformation = 0;
773 AdPrint((" Can't open by FileID on blank volume ;)\n"));
775 }
776
777 if (TargetObjectName.Length != sizeof(FILE_ID)) {
778 AdPrint((" Invalid file ID\n"));
780 }
781 Id = *((FILE_ID*)(TargetObjectName.Buffer));
782 AdPrint((" Opening by ID %8.8x%8.8x\n", (ULONG)(Id>>32), (ULONG)Id));
783 if ((RequestedDisposition != FILE_OPEN) &&
784 (RequestedDisposition != FILE_OPEN_IF)) {
785 AdPrint((" Illegal disposition for ID open\n"));
787 }
788
789 RC = UDFGetOpenParamsByFileId(Vcb, Id, &TmpPath, &IgnoreCase);
790 if(!NT_SUCCESS(RC)) {
791 AdPrint((" ID open failed\n"));
792 try_return(RC);
793 }
794 // simulate absolute path open
795/* if(!NT_SUCCESS(RC = MyInitUnicodeString(&TargetObjectName, L"")) ||
796 !NT_SUCCESS(RC = MyAppendUnicodeStringToStringTag(&TargetObjectName, TmpPath, MEM_USABS_TAG))) {*/
797 if(!NT_SUCCESS(RC = MyCloneUnicodeString(&TargetObjectName, TmpPath))) {
798 AdPrint((" Init String failed\n"));
799 try_return(RC);
800 }
801 //ASSERT(TargetObjectName.Buffer);
802 AbsolutePathName = TargetObjectName;
803 PtrRelatedFileObject = NULL;
804 } else
805 // ****************
806 // Relative open
807 // ****************
808 // Now determine the starting point from which to begin the parsing
809 if (PtrRelatedFileObject) {
810 // We have a user supplied related file object.
811 // This implies a "relative" open i.e. relative to the directory
812 // represented by the related file object ...
813
814 UDFPrint((" PtrRelatedFileObject %x, FCB %x\n", PtrRelatedFileObject, PtrRelatedFCB));
815 // Note: The only purpose FSD implementations ever have for
816 // the related file object is to determine whether this
817 // is a relative open or not. At all other times (including
818 // during I/O operations), this field is meaningless from
819 // the FSD's perspective.
820 if (!(PtrRelatedFCB->FCBFlags & UDF_FCB_DIRECTORY)) {
821 // we must have a directory as the "related" object
823 AdPrint((" Related object must be a directory\n"));
824 AdPrint((" Flags %x\n", PtrRelatedFCB->FCBFlags));
825 _SEH2_TRY {
826 AdPrint((" ObjName %x, ", PtrRelatedFCB->FCBName->ObjectName));
827 AdPrint((" Name %S\n", PtrRelatedFCB->FCBName->ObjectName.Buffer));
829 AdPrint((" exception when printing name\n"));
830 } _SEH2_END;
831 try_return(RC);
832 }
833
834 // So we have a directory, ensure that the name begins with
835 // a "\" i.e. begins at the root and does *not* begin with a "\\"
836 // NOTE: This is just an example of the kind of path-name string
837 // validation that a FSD must do. Although the remainder of
838 // the code may not include such checks, any commercial
839 // FSD *must* include such checking (no one else, including
840 // the I/O Manager will perform checks on the FSD's behalf)
841 if (!(RelatedObjectName.Length) || (RelatedObjectName.Buffer[0] != L'\\')) {
842 AdPrint((" Wrong pathname (1)\n"));
844 try_return(RC);
845 }
846 // similarly, if the target file name starts with a "\", it
847 // is wrong since the target file name can no longer be absolute
848 ASSERT(TargetObjectName.Buffer || !TargetObjectName.Length);
849 if (TargetObjectName.Length && (TargetObjectName.Buffer[0] == L'\\')) {
850 AdPrint((" Wrong pathname (2)\n"));
852 try_return(RC);
853 }
854 // Create an absolute path-name. We could potentially use
855 // the absolute path-name if we cache previously opened
856 // file/directory object names.
857/* if(!NT_SUCCESS(RC = MyInitUnicodeString(&AbsolutePathName, L"")) ||
858 !NT_SUCCESS(RC MyAppendUnicodeStringToStringTag(&AbsolutePathName, &RelatedObjectName, MEM_USABS_TAG)))*/
859 if(!NT_SUCCESS(RC = MyCloneUnicodeString(&AbsolutePathName, &RelatedObjectName)))
860 try_return(RC);
861 if(RelatedObjectName.Length &&
862 (RelatedObjectName.Buffer[ (RelatedObjectName.Length/sizeof(WCHAR)) - 1 ] != L'\\')) {
863 RC = MyAppendUnicodeToString(&AbsolutePathName, L"\\");
864 if(!NT_SUCCESS(RC)) try_return(RC);
865 }
866 if(!AbsolutePathName.Length ||
867 (AbsolutePathName.Buffer[ (AbsolutePathName.Length/sizeof(WCHAR)) - 1 ] != L'\\')) {
868 ASSERT(TargetObjectName.Buffer);
869 if(TargetObjectName.Length && TargetObjectName.Buffer[0] != L'\\') {
870 RC = MyAppendUnicodeToString(&AbsolutePathName, L"\\");
871 if(!NT_SUCCESS(RC)) try_return(RC);
872 }
873 }
874 //ASSERT(TargetObjectName.Buffer);
875 RC = MyAppendUnicodeStringToStringTag(&AbsolutePathName, &TargetObjectName, MEM_USABS_TAG);
876 if(!NT_SUCCESS(RC))
877 try_return(RC);
878
879 } else {
880 // ****************
881 // Absolute open
882 // ****************
883 // The suplied path-name must be an absolute path-name i.e.
884 // starting at the root of the file system tree
885 UDFPrint((" Absolute open\n"));
886 ASSERT(TargetObjectName.Buffer);
887 if (!TargetObjectName.Length || TargetObjectName.Buffer[0] != L'\\') {
888 AdPrint((" Wrong target name (1)\n"));
890 }
891/* if(!NT_SUCCESS(RC = MyInitUnicodeString(&AbsolutePathName, L"")) ||
892 !NT_SUCCESS(RC = MyAppendUnicodeStringToStringTag(&AbsolutePathName, &TargetObjectName, MEM_USABS_TAG)))*/
893 ASSERT(TargetObjectName.Buffer);
894 if(!NT_SUCCESS(RC = MyCloneUnicodeString(&AbsolutePathName, &TargetObjectName)))
895 try_return(RC);
896 }
897 // Win 32 protection :)
898 if ((AbsolutePathName.Length >= sizeof(WCHAR)*2) &&
899 (AbsolutePathName.Buffer[1] == L'\\') &&
900 (AbsolutePathName.Buffer[0] == L'\\')) {
901
902 // If there are still two beginning backslashes, the name is bogus.
903 if ((AbsolutePathName.Length > 2*sizeof(WCHAR)) &&
904 (AbsolutePathName.Buffer[2] == L'\\')) {
905 AdPrint((" Wrong target name (2)\n"));
907 }
908 // Slide the name down in the buffer.
909 RtlMoveMemory( AbsolutePathName.Buffer,
910 AbsolutePathName.Buffer + 1,
911 AbsolutePathName.Length ); // .Length includes
912 // NULL-terminator
913 AbsolutePathName.Length -= sizeof(WCHAR);
914 }
915 if ( (AbsolutePathName.Length > sizeof(WCHAR) ) &&
916 (AbsolutePathName.Buffer[ (AbsolutePathName.Length/sizeof(WCHAR)) - 1 ] == L'\\') ) {
917
918 AbsolutePathName.Length -= sizeof(WCHAR);
919 }
920 // TERMINATOR (2) ;)
921 AbsolutePathName.Buffer[AbsolutePathName.Length/sizeof(WCHAR)] = 0;
922
923 // Sometimes W2000 decides to duplicate handle of
924 // already opened File/Dir. In this case it sends us
925 // RelatedFileObject & specifies zero-filled RelativePath
926 if(!TargetObjectName.Length) {
927 TargetObjectName = AbsolutePathName;
928 OpenExisting = TRUE;
929 }
930 //ASSERT(TargetObjectName.Buffer);
931
932 // ****************
933 // First, check if the caller simply wishes to open the Root
934 // of the file system tree.
935 // ****************
936 if (AbsolutePathName.Length == sizeof(WCHAR)) {
937 AdPrint((" Opening RootDir\n"));
938 // this is an open of the root directory, ensure that the caller
939 // has not requested a file only
940 if (FileOnlyRequested || (RequestedDisposition == FILE_SUPERSEDE) ||
941 (RequestedDisposition == FILE_OVERWRITE) ||
942 (RequestedDisposition == FILE_OVERWRITE_IF)) {
943 AdPrint((" Can't overwrite RootDir\n"));
945 try_return(RC);
946 }
947
948#if 0
949 CollectStatistics(Vcb, MetaDataReads);
950#endif
951
952 if (DeleteOnCloseSpecified) {
953 // delete RootDir.... rather strange idea... I dislike it
954 AdPrint((" Can't delete RootDir\n"));
956 }
957
958 PtrNewFcb = Vcb->RootDirFCB;
959 RC = UDFOpenFile(Vcb, PtrNewFileObject, PtrNewFcb);
960 if(!NT_SUCCESS(RC)) try_return(RC);
961// DbgPrint("UDF: Open/Create RootDir : ReferenceCount %x\n",PtrNewFcb->ReferenceCount);
962 UDFReferenceFile__(PtrNewFcb->FileInfo);
963 PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
964 TreeLength = 1;
965
966 RC = UDFCheckAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
967 if(!NT_SUCCESS(RC)) {
968 AdPrint((" Access/Sharing violation (RootDir)\n"));
969 try_return(RC);
970 }
971
972 ReturnedInformation = FILE_OPENED;
973
974 try_return(RC);
975 } // end of OpenRootDir
976
977 _SEH2_TRY {
978 AdPrint((" Opening file %ws %8.8x\n",AbsolutePathName.Buffer, PtrNewFileObject));
980 AdPrint((" Exception when printing FN\n"));
981 } _SEH2_END;
982 // ****************
983 // Check if we have DuplicateHandle (or Reopen) request
984 // ****************
985 if(OpenExisting) {
986
987// BrutePoint();
988 // We don't handle OpenTargetDirectory in this case
989 if(OpenTargetDirectory)
991
992 // Init environment to simulate normal open procedure behavior
993/* if(!NT_SUCCESS(RC = MyInitUnicodeString(&LocalPath, L"")) ||
994 !NT_SUCCESS(RC = MyAppendUnicodeStringToStringTag(&LocalPath, &TargetObjectName, MEM_USLOC_TAG)))*/
995 ASSERT(TargetObjectName.Buffer);
996 if(!NT_SUCCESS(RC = MyCloneUnicodeString(&LocalPath, &TargetObjectName)))
997 try_return(RC);
998
999 ASSERT(PtrRelatedFCB);
1000 RelatedFileInfo = PtrRelatedFCB->FileInfo;
1001
1002 RC = STATUS_SUCCESS;
1003 NewFileInfo =
1004 LastGoodFileInfo = RelatedFileInfo;
1005
1006 RelatedFileInfo =
1007 OldRelatedFileInfo = RelatedFileInfo->ParentFile;
1008 PtrRelatedFCB = PtrRelatedFCB->ParentFcb;
1009 // prevent releasing parent structures
1010 UDFAcquireParent(RelatedFileInfo, &Res1, &Res2);
1011 TreeLength++;
1012
1013 if(Res1) UDFReleaseResource(Res1);
1014 if(Res2) UDFReleaseResource(Res2);
1015
1016 UDF_CHECK_PAGING_IO_RESOURCE(RelatedFileInfo->Fcb->NTRequiredFCB);
1017 UDFAcquireResourceExclusive(Res2 = &(RelatedFileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1018 PtrNewFcb = NewFileInfo->Fcb;
1019
1020 UDF_CHECK_PAGING_IO_RESOURCE(PtrNewFcb->NTRequiredFCB);
1021 UDFAcquireResourceExclusive(Res1 = &(PtrNewFcb->NTRequiredFCB->MainResource),TRUE);
1022 UDFReferenceFile__(NewFileInfo);
1023 TreeLength++;
1024
1025 goto AlreadyOpened;
1026 }
1027
1028 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
1029 ReturnedInformation = 0;
1030 AdPrint((" Can't open File on blank volume ;)\n"));
1031 ReturnedInformation = FILE_DOES_NOT_EXIST;
1033 }
1034
1035 //AdPrint((" Opening file %ws %8.8x\n",AbsolutePathName.Buffer, PtrNewFileObject));
1036
1037 if(AbsolutePathName.Length > UDF_X_PATH_LEN*sizeof(WCHAR)) {
1039 }
1040
1041 // validate path specified
1042 // (sometimes we can see here very strange characters ;)
1043 if(!UDFIsNameValid(&AbsolutePathName, &StreamOpen, &SNameIndex)) {
1044 AdPrint((" Absolute path is not valid\n"));
1046 }
1047 if(StreamOpen && !UDFStreamsSupported(Vcb)) {
1048 ReturnedInformation = FILE_DOES_NOT_EXIST;
1050 }
1051
1052 RC = MyInitUnicodeString(&LocalPath, L"");
1053 if(!NT_SUCCESS(RC))
1054 try_return(RC);
1055 if (PtrRelatedFileObject) {
1056 // Our "start directory" is the one identified
1057 // by the related file object
1058 RelatedFileInfo = PtrRelatedFCB->FileInfo;
1059 if(RelatedFileInfo != Vcb->RootDirFCB->FileInfo) {
1060 RC = MyAppendUnicodeStringToStringTag(&LocalPath, &(PtrRelatedFCB->FCBName->ObjectName), MEM_USLOC_TAG);
1061 if(!NT_SUCCESS(RC))
1062 try_return(RC);
1063 }
1064 if(TargetObjectName.Buffer != AbsolutePathName.Buffer) {
1065 ASSERT(TargetObjectName.Buffer);
1066 if(!NT_SUCCESS(RC = MyCloneUnicodeString(&TailName, &TargetObjectName))) {
1067 AdPrint((" Init String 'TargetObjectName' failed\n"));
1068 try_return(RC);
1069 }
1070 TailNameBuffer = TailName.Buffer;
1071 } else {
1072 TailName = AbsolutePathName;
1073 }
1074 } else {
1075 // Start at the root of the file system
1076 RelatedFileInfo = Vcb->RootDirFCB->FileInfo;
1077 TailName = AbsolutePathName;
1078 }
1079
1080 if(StreamOpen) {
1081 StreamName = AbsolutePathName;
1082 StreamName.Buffer += SNameIndex;
1083 StreamName.Length -= (USHORT)SNameIndex*sizeof(WCHAR);
1084 // if StreamOpen specified & stream name starts with NULL character
1085 // we should create Stream Dir at first
1086 TailName.Length -= (AbsolutePathName.Length - (USHORT)SNameIndex*sizeof(WCHAR));
1087 AbsolutePathName.Length = (USHORT)SNameIndex*sizeof(WCHAR);
1088 }
1089 CurName.MaximumLength = TailName.MaximumLength;
1090
1091 RC = STATUS_SUCCESS;
1092 LastGoodName.Length = 0;
1093 LastGoodFileInfo = RelatedFileInfo;
1094 // reference RelatedObject to prevent releasing parent structures
1095 UDFAcquireParent(RelatedFileInfo, &Res1, &Res2);
1096 TreeLength++;
1097
1098 // go into a loop parsing the supplied name
1099
1100 // Note that we may have to "open" intermediate directory objects
1101 // while traversing the path. We should __try to reuse existing code
1102 // whenever possible therefore we should consider using a common
1103 // open routine regardless of whether the open is on behalf of the
1104 // caller or an intermediate (internal) open performed by the driver.
1105
1106 // ****************
1107 // now we'll parse path to desired file
1108 // ****************
1109
1110 while (TRUE) {
1111
1112 // remember last 'good' ('good' means NO ERRORS before) path tail
1113 if(NT_SUCCESS(RC)) {
1114 LastGoodTail = TailName;
1115 while(LastGoodTail.Buffer[0] == L'\\') {
1116 LastGoodTail.Buffer++;
1117 LastGoodTail.Length -= sizeof(WCHAR);
1118 }
1119 }
1120 // get next path part...
1121 TmpBuffer = TailName.Buffer;
1122 TailName.Buffer = UDFDissectName(TailName.Buffer,&(CurName.Length) );
1123 TailName.Length -= (USHORT)((ULONG_PTR)(TailName.Buffer) - (ULONG_PTR)TmpBuffer);
1124 CurName.Buffer = TailName.Buffer - CurName.Length;
1125 CurName.Length *= sizeof(WCHAR);
1126 CurName.MaximumLength = CurName.Length + sizeof(WCHAR);
1127 // check if we have already opened the component before last one
1128 // in this case OpenTargetDir request will be served in a special
1129 // way...
1130 if(OpenTargetDirectory && NT_SUCCESS(RC) && !TailName.Length) {
1131 // check if we should open SDir..
1132 if(!StreamOpen ||
1133 (TailName.Buffer[0]!=L':')) {
1134 // no, we should not. Continue with OpenTargetDir
1135 break;
1136 }
1137 }
1138
1139 if( CurName.Length &&
1140 (NT_SUCCESS(RC) || !StreamOpen)) {
1141 // ...wow! non-zero! try to open!
1142 if(!NT_SUCCESS(RC)) {
1143 AdPrint((" Error opening path component\n"));
1144 // we haven't reached last name part... hm..
1145 // probably, the path specified is invalid..
1146 // or we had a hard error... What else can we do ?
1147 // Only say ..CK OFF !!!!
1150 ReturnedInformation = FILE_DOES_NOT_EXIST;
1151 try_return(RC);
1152 }
1153
1154 ASSERT_REF(RelatedFileInfo->Fcb->ReferenceCount >= RelatedFileInfo->RefCount);
1155
1156 if(RelatedFileInfo && (TreeLength>1)) {
1157 // it was an internal Open operation. Thus, assume
1158 // RelatedFileInfo's Fcb to be valid
1159 RelatedFileInfo->Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
1160 RelatedFileInfo->Fcb->FCBFlags |= UDF_FCB_VALID;
1161 }
1162 // check path fragment size
1163 if(CurName.Length > UDF_X_NAME_LEN * sizeof(WCHAR)) {
1164 AdPrint((" Path component is too long\n"));
1166 }
1167 // ...and now release previously acquired objects,
1168 if(Res1) UDFReleaseResource(Res1);
1169 if(Res2) {
1170 UDFReleaseResource(Res2);
1171 Res2 = NULL;
1172 }
1173 // acquire new _parent_ directory & try to open what
1174 // we want.
1175
1176 UDF_CHECK_PAGING_IO_RESOURCE(RelatedFileInfo->Fcb->NTRequiredFCB);
1177 UDFAcquireResourceExclusive(Res1 = &(RelatedFileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1178
1179 // check traverse rights
1180 RC = UDFCheckAccessRights(NULL, NULL, RelatedFileInfo->Fcb, PtrRelatedCCB, FILE_TRAVERSE, 0);
1181 if(!NT_SUCCESS(RC)) {
1182 NewFileInfo = NULL;
1183 AdPrint((" Traverse check failed\n"));
1184 goto Skip_open_attempt;
1185 }
1186 // check if we should open normal File/Dir or SDir
1187 if(CurName.Buffer[0] != ':') {
1188 // standard open, nothing interesting....
1189 RC = UDFOpenFile__(Vcb,
1190 IgnoreCase,TRUE,&CurName,
1191 RelatedFileInfo,&NewFileInfo,NULL);
1192 if(RC == STATUS_FILE_DELETED) {
1193 // file has gone, but system still remembers it...
1194 NewFileInfo = NULL;
1195 AdPrint((" File deleted\n"));
1197#ifdef UDF_DBG
1198 } else
1199 if(RC == STATUS_NOT_A_DIRECTORY) {
1200 AdPrint((" Not a directory\n"));
1201#endif // UDF_DBG
1202 } else
1203 if(RC == STATUS_SHARING_PAUSED) {
1204 AdPrint((" Dloc is being initialized\n"));
1205 BrutePoint();
1207 }
1208 } else {
1209 // And here we should open Stream Dir (if any, of cource)
1210 RC = UDFOpenStreamDir__(Vcb, RelatedFileInfo, &NewFileInfo);
1211 if(NT_SUCCESS(RC)) {
1212SuccessOpen_SDir:
1213 // this indicates that we needn't Stream Dir creation
1214 StreamExists = TRUE;
1215 StreamName.Buffer++;
1216 StreamName.Length-=sizeof(WCHAR);
1217 // update TailName
1218 TailName = StreamName;
1219 } else
1220 if(RC == STATUS_NOT_FOUND) {
1221#ifndef UDF_READ_ONLY_BUILD
1222 // Stream Dir doesn't exist, but caller wants it to be
1223 // created. Lets try to help him...
1224 if((RequestedDisposition == FILE_CREATE) ||
1225 (RequestedDisposition == FILE_OPEN_IF) ||
1226 (RequestedDisposition == FILE_OVERWRITE_IF) ||
1227 OpenTargetDirectory ) {
1228 RC = UDFCreateStreamDir__(Vcb, RelatedFileInfo, &NewFileInfo);
1229 if(NT_SUCCESS(RC))
1230 goto SuccessOpen_SDir;
1231 }
1232#endif //UDF_READ_ONLY_BUILD
1233 }
1234/* } else {
1235 AdPrint((" File deleted (2)\n"));
1236 RC = STATUS_ACCESS_DENIED;*/
1237 }
1238#if 0
1239 CollectStatistics(Vcb, MetaDataReads);
1240#endif
1241
1242Skip_open_attempt:
1243
1244 // check if we have successfully opened path component
1245 if(NT_SUCCESS(RC)) {
1246 // Yesss !!!
1247 if (!(PtrNewFcb = NewFileInfo->Fcb)) {
1248 // It is a first open operation
1249 // Allocate new FCB
1250 // Here we set FileObject pointer to NULL to avoid
1251 // new CCB allocation
1252 RC = UDFFirstOpenFile(Vcb,
1253 NULL, &PtrNewFcb, RelatedFileInfo, NewFileInfo,
1254 &LocalPath, &CurName);
1255
1256 if(!NT_SUCCESS(RC)) {
1257 BrutePoint();
1258 AdPrint((" Can't perform FirstOpen\n"));
1259 UDFCloseFile__(Vcb, NewFileInfo);
1260 if(PtrNewFcb) UDFCleanUpFCB(PtrNewFcb);
1261 PtrNewFcb = NULL;
1262 NewFileInfo->Fcb = NULL;
1263 if(UDFCleanUpFile__(Vcb, NewFileInfo)) {
1264 MyFreePool__(NewFileInfo);
1265 NewFileInfo = NULL;
1266 }
1267 try_return(RC);
1268 }
1269 } else {
1270 // It is not a first open operation
1271 // Validate Fcb. It is possible to get
1272 // not completly initialized Fcb here.
1273 if(!(PtrNewFcb->FCBFlags & UDF_FCB_VALID)) {
1274 BrutePoint();
1275 AdPrint((" Fcb not valid\n"));
1276 UDFCloseFile__(Vcb, NewFileInfo);
1277 PtrNewFcb = NULL;
1278 if(UDFCleanUpFile__(Vcb, NewFileInfo)) {
1279 MyFreePool__(NewFileInfo);
1280 NewFileInfo = NULL;
1281 }
1283 }
1284 }
1285 // Acquire newly opened File...
1286 Res2 = Res1;
1287 UDF_CHECK_PAGING_IO_RESOURCE(NewFileInfo->Fcb->NTRequiredFCB);
1288 UDFAcquireResourceExclusive(Res1 = &(NewFileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1289 // ...and reference it
1290 UDFInterlockedIncrement((PLONG)&(PtrNewFcb->ReferenceCount));
1291 UDFInterlockedIncrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1292
1293 ASSERT_REF(PtrNewFcb->ReferenceCount >= NewFileInfo->RefCount);
1294 // update unwind information
1295 LastGoodFileInfo = NewFileInfo;
1296 LastGoodName = CurName;
1297 TreeLength++;
1298 // update current path
1299 if(!StreamOpen ||
1300 ((CurName.Buffer[0] != L':') &&
1301 (!LocalPath.Length || (LocalPath.Buffer[LocalPath.Length/sizeof(WCHAR)-1] != L':'))) ) {
1302 // we should not insert '\' before or after ':'
1303 ASSERT(!LocalPath.Length ||
1304 (LocalPath.Buffer[LocalPath.Length/2-1] != L'\\'));
1305 RC = MyAppendUnicodeToString(&LocalPath, L"\\");
1306 if(!NT_SUCCESS(RC)) try_return(RC);
1307 }
1308 RC = MyAppendUnicodeStringToStringTag(&LocalPath, &CurName, MEM_USLOC_TAG);
1309 if(!NT_SUCCESS(RC))
1310 try_return(RC);
1311// DbgPrint("UDF: Open/Create File %ws : ReferenceCount %x\n",CurName.Buffer,PtrNewFcb->ReferenceCount);
1312 } else {
1313 AdPrint((" Can't open file\n"));
1314 // We have failed durring last Open attempt
1315 // Roll back to last good state
1317 // Cleanup FileInfo if any
1318 if(NewFileInfo) {
1319 PtrNewFcb = NewFileInfo->Fcb;
1320 // acquire appropriate resource if possible
1321 if(PtrNewFcb &&
1322 PtrNewFcb->NTRequiredFCB) {
1323 NtReqFcb = PtrNewFcb->NTRequiredFCB;
1324 Res2 = Res1;
1326 UDFAcquireResourceExclusive(Res1 = &(NtReqFcb->MainResource),TRUE);
1327 }
1328 // cleanup pointer to Fcb in FileInfo to allow
1329 // UDF_INFO package release FileInfo if there are
1330 // no more references
1331 if(PtrNewFcb &&
1332 !PtrNewFcb->ReferenceCount &&
1333 !PtrNewFcb->OpenHandleCount) {
1334 NewFileInfo->Fcb = NULL;
1335 }
1336 // cleanup pointer to CommonFcb in Dloc to allow
1337 // UDF_INFO package release Dloc if there are
1338 // no more references
1339 if(NewFileInfo->Dloc &&
1340 !NewFileInfo->Dloc->LinkRefCount &&
1341 (!PtrNewFcb || !PtrNewFcb->ReferenceCount)) {
1342 NewFileInfo->Dloc->CommonFcb = NULL;
1343 }
1344 // try to release FileInfo
1345 if(UDFCleanUpFile__(Vcb, NewFileInfo)) {
1346 ASSERT(!PtrNewFcb);
1347 if(PtrNewFcb) {
1348 BrutePoint();
1349 UDFCleanUpFCB(PtrNewFcb);
1350 }
1351 MyFreePool__(NewFileInfo);
1352 } else {
1353 // if we can't release FileInfo
1354 // restore pointers to Fcb & CommonFcb in
1355 // FileInfo & Dloc
1356 NewFileInfo->Fcb = PtrNewFcb;
1357 if(NtReqFcb)
1358 NewFileInfo->Dloc->CommonFcb = NtReqFcb;
1359 }
1360 // forget about last FileInfo & Fcb,
1361 // further unwind staff needs only last good
1362 // structures
1363 PtrNewFcb = NULL;
1364 NewFileInfo = NULL;
1365 }
1366 }
1367
1368 // should return error if 'delete in progress'
1369 if(LastGoodFileInfo->Fcb->FCBFlags & (UDF_FCB_DELETE_ON_CLOSE |
1372 AdPrint((" Return DeletePending (no err)\n"));
1374 }
1375 // update last good state information...
1376 OldRelatedFileInfo = RelatedFileInfo;
1377 RelatedFileInfo = NewFileInfo;
1378 // ...and go to the next open cycle
1379 } else {
1380 // ************
1381 if(StreamOpen && (RC == STATUS_NOT_FOUND))
1382 // handle SDir return code
1385 // good path, but no such file.... Amen
1386 // break open loop and continue with Create
1387 break;
1388 }
1389 if (!NT_SUCCESS(RC)) {
1390 // Hard error or damaged data structures ...
1391#ifdef UDF_DBG
1392 if((RC != STATUS_OBJECT_PATH_NOT_FOUND) &&
1393 (RC != STATUS_ACCESS_DENIED) &&
1394 (RC != STATUS_NOT_A_DIRECTORY)) {
1395 AdPrint((" Hard error or damaged data structures\n"));
1396 }
1397#endif // UDF_DBG
1398 // ... and exit with error
1399 try_return(RC);
1400 }
1401 // discard changes for last successfully opened file
1402 UDFInterlockedDecrement((PLONG)&(PtrNewFcb->ReferenceCount));
1403 UDFInterlockedDecrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1404 RC = STATUS_SUCCESS;
1405 ASSERT(!OpenTargetDirectory);
1406 // break open loop and continue with Open
1407 // (Create will be skipped)
1408 break;
1409 }
1410 } // end of while(TRUE)
1411
1412 // ****************
1413 // If "open target directory" was specified
1414 // ****************
1415 if(OpenTargetDirectory) {
1416
1417 if(!UDFIsADirectory(LastGoodFileInfo)) {
1418 AdPrint((" Not a directory (2)\n"));
1420 }
1421 if(!NT_SUCCESS(RC) ||
1422 TailName.Length) {
1423 AdPrint((" Target name should not contain (back)slashes\n"));
1424 NewFileInfo = NULL;
1426 }
1427
1428 NewFileInfo = LastGoodFileInfo;
1429 RtlCopyUnicodeString(&(PtrNewFileObject->FileName), &CurName);
1430
1431 // now we have to check if last component exists...
1433 &CurName, RelatedFileInfo))) {
1434 // file exists, set this information in the Information field
1435 ReturnedInformation = FILE_EXISTS;
1436 AdPrint((" Open Target: FILE_EXISTS\n"));
1437 } else
1439#ifdef UDF_DBG
1440 // check name. If there are '\\'s in TailName, some
1441 // directories in path specified do not exist
1442 for(TmpBuffer = LastGoodTail.Buffer; *TmpBuffer; TmpBuffer++) {
1443 if((*TmpBuffer) == L'\\') {
1444 ASSERT(FALSE);
1445 AdPrint((" Target name should not contain (back)slashes\n"));
1447 }
1448 }
1449#endif // UDF_DBG
1450 // Tell the I/O Manager that file does not exit
1451 ReturnedInformation = FILE_DOES_NOT_EXIST;
1452 AdPrint((" Open Target: FILE_DOES_NOT_EXIST\n"));
1453 RC = STATUS_SUCCESS; // is already set here
1454 } else {
1455 AdPrint((" Open Target: unexpected error\n"));
1456 NewFileInfo = NULL;
1457 ReturnedInformation = FILE_DOES_NOT_EXIST;
1459 }
1460
1461// RC = STATUS_SUCCESS; // is already set here
1462
1463 // Update the file object FsContext and FsContext2 fields
1464 // to reflect the fact that the parent directory of the
1465 // target has been opened
1466 PtrNewFcb = NewFileInfo->Fcb;
1467 UDFInterlockedDecrement((PLONG)&(PtrNewFcb->ReferenceCount));
1468 UDFInterlockedDecrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1469 RC = UDFOpenFile(Vcb, PtrNewFileObject, PtrNewFcb);
1470 ASSERT_REF(PtrNewFcb->ReferenceCount >= NewFileInfo->RefCount);
1471 if (!NT_SUCCESS(RC)) {
1472 AdPrint((" Can't perform OpenFile operation for target\n"));
1473 try_return(RC);
1474 }
1475 PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
1476
1477 ASSERT(Res1);
1478 RC = UDFCheckAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
1479 if(!NT_SUCCESS(RC)) {
1480 AdPrint((" Access/Share access check failed (Open Target)\n"));
1481 }
1482
1483 try_return(RC);
1484 }
1485
1486 // ****************
1487 // should we CREATE a new file ?
1488 // ****************
1489 if (!NT_SUCCESS(RC)) {
1490 if (RC == STATUS_OBJECT_NAME_NOT_FOUND ||
1492 if( ((RequestedDisposition == FILE_OPEN) ||
1493 (RequestedDisposition == FILE_OVERWRITE)) /*&&
1494 (!StreamOpen || !StreamExists)*/ ){
1495 ReturnedInformation = FILE_DOES_NOT_EXIST;
1496 AdPrint((" File doesn't exist\n"));
1497 try_return(RC);
1498 }
1499 } else {
1500 // Any other operation return STATUS_ACCESS_DENIED.
1501 AdPrint((" Can't create due to unexpected error\n"));
1502 try_return(RC);
1503 }
1504 // Object was not found, create if requested
1505 if ((RequestedDisposition != FILE_CREATE) && (RequestedDisposition != FILE_OPEN_IF) &&
1506 (RequestedDisposition != FILE_OVERWRITE_IF) && (RequestedDisposition != FILE_SUPERSEDE)) {
1507 AdPrint((" File doesn't exist (2)\n"));
1508 ReturnedInformation = FILE_DOES_NOT_EXIST;
1509 try_return(RC);
1510 }
1511 // Check Volume ReadOnly attr
1512#ifndef UDF_READ_ONLY_BUILD
1513 if((Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)) {
1514#endif //UDF_READ_ONLY_BUILD
1515 ReturnedInformation = 0;
1516 AdPrint((" Write protected\n"));
1518#ifndef UDF_READ_ONLY_BUILD
1519 }
1520 // Check r/o + delete on close
1521 if(DeleteOnCloseSpecified &&
1523 AdPrint((" Can't create r/o file marked for deletion\n"));
1525 }
1526
1527 // Create a new file/directory here ...
1528 if(StreamOpen)
1529 StreamName.Buffer[StreamName.Length/sizeof(WCHAR)] = 0;
1530 for(TmpBuffer = LastGoodTail.Buffer; *TmpBuffer; TmpBuffer++) {
1531 if((*TmpBuffer) == L'\\') {
1532 AdPrint((" Target name should not contain (back)slashes\n"));
1534 }
1535 }
1537 ((IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_TEMPORARY) ||
1538 StreamOpen || FALSE)) {
1539 AdPrint((" Creation of _temporary_ directory not permited\n"));
1541 }
1542 // check access rights
1543 ASSERT(Res1);
1544 RC = UDFCheckAccessRights(NULL, NULL, OldRelatedFileInfo->Fcb, PtrRelatedCCB, DirectoryOnlyRequested ? FILE_ADD_SUBDIRECTORY : FILE_ADD_FILE, 0);
1545 if(!NT_SUCCESS(RC)) {
1546 AdPrint((" Creation of File/Dir not permitted\n"));
1547 try_return(RC);
1548 }
1549 // Note that a FCB structure will be allocated at this time
1550 // and so will a CCB structure. Assume that these are called
1551 // PtrNewFcb and PtrNewCcb respectively.
1552 // Further, note that since the file is being created, no other
1553 // thread can have the file stream open at this time.
1554 RelatedFileInfo = OldRelatedFileInfo;
1555
1556 RC = UDFCreateFile__(Vcb, IgnoreCase, &LastGoodTail, 0, 0,
1557 Vcb->UseExtendedFE || (StreamOpen && !StreamExists),
1558 (RequestedDisposition == FILE_CREATE), RelatedFileInfo, &NewFileInfo);
1559 if(!NT_SUCCESS(RC)) {
1560 AdPrint((" Creation error\n"));
1561Creation_Err_1:
1562 if(NewFileInfo) {
1563 PtrNewFcb = NewFileInfo->Fcb;
1564 ASSERT(!PtrNewFcb);
1565 if(PtrNewFcb &&
1566 !PtrNewFcb->ReferenceCount &&
1567 !PtrNewFcb->OpenHandleCount) {
1568 NewFileInfo->Fcb = NULL;
1569 }
1570 if(NewFileInfo->Dloc &&
1571 !NewFileInfo->Dloc->LinkRefCount) {
1572 NewFileInfo->Dloc->CommonFcb = NULL;
1573 }
1574 if(UDFCleanUpFile__(Vcb, NewFileInfo)) {
1575 if(PtrNewFcb) {
1576 BrutePoint();
1577 UDFCleanUpFCB(PtrNewFcb);
1578 }
1579 MyFreePool__(NewFileInfo);
1580 PtrNewFcb = PtrNewFcb;
1581 } else {
1582 NewFileInfo->Fcb = PtrNewFcb;
1583 }
1584 PtrNewFcb = NULL;
1585 }
1586 try_return(RC);
1587 }
1588 // Update parent object
1589 if((Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_WRITE) &&
1590 PtrRelatedFCB &&
1591 PtrRelatedFileObject &&
1592 (PtrRelatedFCB->FileInfo == NewFileInfo->ParentFile)) {
1593 PtrRelatedFileObject->Flags |= (FO_FILE_MODIFIED | FO_FILE_SIZE_CHANGED);
1594 }
1595#if 0
1596 CollectStatistics(Vcb, MetaDataWrites);
1597#endif
1598
1600 // user wants the directory to be created
1601 RC = UDFRecordDirectory__(Vcb, NewFileInfo);
1602 if(!NT_SUCCESS(RC)) {
1603 AdPrint((" Can't transform to directory\n"));
1604Undo_Create_1:
1605 if((RC != STATUS_FILE_IS_A_DIRECTORY) &&
1606 (RC != STATUS_NOT_A_DIRECTORY) &&
1607 (RC != STATUS_ACCESS_DENIED)) {
1608 UDFFlushFile__(Vcb, NewFileInfo);
1609 UDFUnlinkFile__(Vcb, NewFileInfo, TRUE);
1610 }
1611 UDFCloseFile__(Vcb, NewFileInfo);
1612 BrutePoint();
1613 goto Creation_Err_1;
1614 }
1615#if 0
1616 CollectStatistics(Vcb, MetaDataWrites);
1617#endif
1618 } else if(AllocationSize) {
1619 // set initial file size
1620/* if(!NT_SUCCESS(RC = UDFResizeFile__(Vcb, NewFileInfo, AllocationSize))) {
1621 AdPrint((" Can't set initial file size\n"));
1622 goto Undo_Create_1;
1623 }
1624 CollectStatistics(Vcb, MetaDataWrites);*/
1625 }
1626
1627 if(StreamOpen && !StreamExists) {
1628
1629 // PHASE 0
1630
1631 // Open the newly created object (file)
1632 if (!(PtrNewFcb = NewFileInfo->Fcb)) {
1633 // It is a first open operation
1634 // Allocate new FCB
1635 // Here we set FileObject pointer to NULL to avoid
1636 // new CCB allocation
1637 RC = UDFFirstOpenFile(Vcb,
1638 NULL, &PtrNewFcb, RelatedFileInfo, NewFileInfo,
1639 &LocalPath, &LastGoodTail);
1640 if(!NT_SUCCESS(RC)) {
1641 AdPrint((" Can't perform FirstOpenFile operation for file to contain stream\n"));
1642 BrutePoint();
1643 UDFCleanUpFCB(NewFileInfo->Fcb);
1644 NewFileInfo->Fcb = NULL;
1645 goto Creation_Err_1;
1646 }
1647 } else {
1648 BrutePoint();
1649 }
1650
1651 // Update unwind information
1652 TreeLength++;
1653 LastGoodFileInfo = NewFileInfo;
1654 // update FCB tree
1655 RC = MyAppendUnicodeToString(&LocalPath, L"\\");
1656 if(!NT_SUCCESS(RC)) try_return(RC);
1657 RC = MyAppendUnicodeStringToStringTag(&LocalPath, &LastGoodTail, MEM_USLOC_TAG);
1658 if(!NT_SUCCESS(RC))
1659 goto Creation_Err_1;
1660 UDFInterlockedIncrement((PLONG)&(PtrNewFcb->ReferenceCount));
1661 UDFInterlockedIncrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1662 ASSERT_REF(PtrNewFcb->ReferenceCount >= NewFileInfo->RefCount);
1663 PtrNewFcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
1664 PtrNewFcb->FCBFlags |= UDF_FCB_VALID;
1665
1666 UDFNotifyFullReportChange( Vcb, NewFileInfo,
1669
1670 // PHASE 1
1671
1672 // we need to create Stream Dir
1673 RelatedFileInfo = NewFileInfo;
1674 RC = UDFCreateStreamDir__(Vcb, RelatedFileInfo, &NewFileInfo);
1675 if(!NT_SUCCESS(RC)) {
1676 AdPrint((" Can't create SDir\n"));
1677 BrutePoint();
1678 goto Creation_Err_1;
1679 }
1680#if 0
1681 CollectStatistics(Vcb, MetaDataWrites);
1682#endif
1683
1684 // normalize stream name
1685 StreamName.Buffer++;
1686 StreamName.Length-=sizeof(WCHAR);
1687 // Open the newly created object
1688 if (!(PtrNewFcb = NewFileInfo->Fcb)) {
1689 // It is a first open operation
1690 // Allocate new FCB
1691 // Here we set FileObject pointer to NULL to avoid
1692 // new CCB allocation
1693 RC = UDFFirstOpenFile(Vcb,
1694 NULL, &PtrNewFcb, RelatedFileInfo, NewFileInfo,
1695 &LocalPath, &(UDFGlobalData.UnicodeStrSDir));
1696 } else {
1697 BrutePoint();
1698 }
1699 if(!NT_SUCCESS(RC)) {
1700 AdPrint((" Can't perform OpenFile operation for SDir\n"));
1701 BrutePoint();
1702 goto Creation_Err_1;
1703 }
1704
1705 // Update unwind information
1706 TreeLength++;
1707 LastGoodFileInfo = NewFileInfo;
1708 // update FCB tree
1709 RC = MyAppendUnicodeStringToStringTag(&LocalPath, &(UDFGlobalData.UnicodeStrSDir), MEM_USLOC_TAG);
1710 if(!NT_SUCCESS(RC)) {
1711 AdPrint((" Can't append UNC str\n"));
1712 BrutePoint();
1713 goto Creation_Err_1;
1714 }
1715 UDFInterlockedIncrement((PLONG)&(PtrNewFcb->ReferenceCount));
1716 UDFInterlockedIncrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1717 ASSERT_REF(PtrNewFcb->ReferenceCount >= NewFileInfo->RefCount);
1718 PtrNewFcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
1719 PtrNewFcb->FCBFlags |= UDF_FCB_VALID;
1720
1721 // PHASE 2
1722
1723 // create stream
1724 RelatedFileInfo = NewFileInfo;
1726 Vcb->UseExtendedFE, (RequestedDisposition == FILE_CREATE),
1727 RelatedFileInfo, &NewFileInfo);
1728 if(!NT_SUCCESS(RC)) {
1729 AdPrint((" Can't create Stream\n"));
1730 BrutePoint();
1731 goto Creation_Err_1;
1732 }
1733#if 0
1734 CollectStatistics(Vcb, MetaDataWrites);
1735#endif
1736
1737 // Update unwind information
1738 LastGoodTail = StreamName;
1739 }
1740 // NT wants ARCHIVE bit to be set on Files
1743 // Open the newly created object
1744 if (!(PtrNewFcb = NewFileInfo->Fcb)) {
1745 // It is a first open operation
1746#ifndef IFS_40
1747 // Set attributes for the file ...
1749 NewFileInfo->Dloc->FileEntry, FileAttributes);
1750#endif //IFS_40
1751 // Allocate new FCB
1752 // Here we set FileObject pointer to NULL to avoid
1753 // new CCB allocation
1754 RC = UDFFirstOpenFile(Vcb,
1755 PtrNewFileObject, &PtrNewFcb, RelatedFileInfo, NewFileInfo,
1756 &LocalPath, &LastGoodTail);
1757 } else {
1758 BrutePoint();
1759 }
1760
1761 if(!NT_SUCCESS(RC)) {
1762 AdPrint((" Can't perform OpenFile operation for file or stream\n"));
1763 BrutePoint();
1764 goto Undo_Create_1;
1765 }
1766
1767 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.FileSize.QuadPart =
1768 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.ValidDataLength.QuadPart = 0;
1769 if(AllocationSize) {
1770 // inform NT about size changes
1771 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart = AllocationSize;
1772 MmPrint((" CcIsFileCached()\n"));
1773 if(CcIsFileCached(PtrNewFileObject)) {
1774 MmPrint((" CcSetFileSizes()\n"));
1775 BrutePoint();
1776 CcSetFileSizes(PtrNewFileObject, (PCC_FILE_SIZES)&(PtrNewFcb->NTRequiredFCB->CommonFCBHeader.AllocationSize));
1777 PtrNewFcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
1778 }
1779 }
1780
1781 // Update unwind information
1782 TreeLength++;
1783 LastGoodFileInfo = NewFileInfo;
1784
1785 // Set the Share Access for the file stream.
1786 // The FCBShareAccess field will be set by the I/O Manager.
1787 PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
1788 RC = UDFSetAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
1789
1790 if(!NT_SUCCESS(RC)) {
1791 AdPrint((" Can't set Access Rights on Create\n"));
1792 BrutePoint();
1793 UDFFlushFile__(Vcb, NewFileInfo);
1794 UDFUnlinkFile__(Vcb, NewFileInfo, TRUE);
1795 try_return(RC);
1796 }
1797
1798#ifdef IFS_40
1799 // Set attributes for the file ...
1801 NewFileInfo->Dloc->FileEntry, FileAttributes);
1802 // It is rather strange for me, but NT requires us to allow
1803 // Create operation for r/o + WriteAccess, but denies all
1804 // the rest operations in this case. Thus, we should update
1805 // r/o flag in Fcb _after_ Access check :-/
1807 PtrNewFcb->FCBFlags |= UDF_FCB_READ_ONLY;
1808#endif //IFS_40
1809 // We call the notify package to report that the
1810 // we have added a stream.
1811 if(UDFIsAStream(NewFileInfo)) {
1812 UDFNotifyFullReportChange( Vcb, NewFileInfo,
1815 } else {
1816 UDFNotifyFullReportChange( Vcb, NewFileInfo,
1819 }
1820/*#ifdef UDF_DBG
1821 {
1822 ULONG i;
1823 PDIR_INDEX_HDR hDirIndex = NewFileInfo->ParentFile->Dloc->DirIndex;
1824
1825 for(i=0;DirIndex[i].FName.Buffer;i++) {
1826 AdPrint(("%ws\n", DirIndex[i].FName.Buffer));
1827 }
1828 }
1829#endif*/
1830 ReturnedInformation = FILE_CREATED;
1831
1832 try_return(RC);
1833#endif //UDF_READ_ONLY_BUILD
1834
1835 }
1836
1837AlreadyOpened:
1838
1839 // ****************
1840 // we have always STATUS_SUCCESS here
1841 // ****************
1842
1843 ASSERT(NewFileInfo != OldRelatedFileInfo);
1844 // A new CCB will be allocated.
1845 // Assume that this structure named PtrNewCcb
1846 RC = UDFOpenFile(Vcb, PtrNewFileObject, PtrNewFcb);
1847 if (!NT_SUCCESS(RC)) try_return(RC);
1848 PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
1849
1850 if(RequestedDisposition == FILE_CREATE) {
1851 ReturnedInformation = FILE_EXISTS;
1852 AdPrint((" Object name collision\n"));
1854 }
1855
1856 NtReqFcb = PtrNewFcb->NTRequiredFCB;
1857 NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(PtrNewFcb);
1858
1859 // Check if caller wanted a directory only and target object
1860 // is not a directory, or caller wanted a file only and target
1861 // object is not a file ...
1862 if((PtrNewFcb->FCBFlags & UDF_FCB_DIRECTORY) && ((RequestedDisposition == FILE_SUPERSEDE) ||
1863 (RequestedDisposition == FILE_OVERWRITE) || (RequestedDisposition == FILE_OVERWRITE_IF) ||
1865 if(FileOnlyRequested) {
1866 AdPrint((" Can't open directory as a plain file\n"));
1867 } else {
1868 AdPrint((" Can't supersede directory\n"));
1869 }
1871 try_return(RC);
1872 }
1873
1874 if(DirectoryOnlyRequested && !(PtrNewFcb->FCBFlags & UDF_FCB_DIRECTORY)) {
1875 AdPrint((" This is not a directory\n"));
1877 try_return(RC);
1878 }
1879
1880 if(DeleteOnCloseSpecified && (PtrNewFcb->FCBFlags & UDF_FCB_READ_ONLY)) {
1881 AdPrint((" Can't delete Read-Only file\n"));
1883 try_return(RC);
1884 }
1885 // Check share access and fail if the share conflicts with an existing
1886 // open.
1887 ASSERT(Res1 != NULL);
1888 ASSERT(Res2 != NULL);
1889 RC = UDFCheckAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
1890 if(!NT_SUCCESS(RC)) {
1891 AdPrint((" Access/Share access check failed\n"));
1892 try_return(RC);
1893 }
1894
1895 RestoreShareAccess = TRUE;
1896
1897 if(FileOnlyRequested) {
1898 // If the user wants 'write access' access to the file make sure there
1899 // is not a process mapping this file as an image. Any attempt to
1900 // delete the file will be stopped in fileinfo.cpp
1901 //
1902 // If the user wants to delete on close, we must check at this
1903 // point though.
1904 if( (DesiredAccess & FILE_WRITE_DATA) || DeleteOnCloseSpecified ) {
1905 MmPrint((" MmFlushImageSection();\n"));
1906 NtReqFcb->AcqFlushCount++;
1907 if(!MmFlushImageSection( &(NtReqFcb->SectionObject),
1908 MmFlushForWrite )) {
1909
1910 NtReqFcb->AcqFlushCount--;
1911 RC = DeleteOnCloseSpecified ? STATUS_CANNOT_DELETE :
1913 AdPrint((" File is mapped or deletion in progress\n"));
1914 try_return (RC);
1915 }
1916 NtReqFcb->AcqFlushCount--;
1917 }
1919 /* (PtrNewFileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) &&*/
1920 !(PtrNewFcb->CachedOpenHandleCount) &&
1921 (NtReqFcb->SectionObject.DataSectionObject) ) {
1922 // If this is a non-cached open, and there are no open cached
1923 // handles, but there is still a data section, attempt a flush
1924 // and purge operation to avoid cache coherency overhead later.
1925 // We ignore any I/O errors from the flush.
1926 MmPrint((" CcFlushCache()\n"));
1927 CcFlushCache( &(NtReqFcb->SectionObject), NULL, 0, NULL );
1928 MmPrint((" CcPurgeCacheSection()\n"));
1929 CcPurgeCacheSection( &(NtReqFcb->SectionObject), NULL, 0, FALSE );
1930 }
1931 }
1932
1933 if(DeleteOnCloseSpecified && UDFIsADirectory(NewFileInfo) && !UDFIsDirEmpty__(NewFileInfo)) {
1934 AdPrint((" Directory in not empry\n"));
1936 }
1937
1938 // Get attributes for the file ...
1939 TmpFileAttributes =
1941 NewFileInfo->Dloc->FileEntry);
1942
1943 if(DeleteOnCloseSpecified &&
1944 (TmpFileAttributes & FILE_ATTRIBUTE_READONLY)) {
1945 ASSERT(Res1 != NULL);
1946 ASSERT(Res2 != NULL);
1947 RC = UDFCheckAccessRights(NULL, NULL, OldRelatedFileInfo->Fcb, PtrRelatedCCB, FILE_DELETE_CHILD, 0);
1948 if(!NT_SUCCESS(RC)) {
1949 AdPrint((" Read-only. DeleteOnClose attempt failed\n"));
1951 }
1952 }
1953
1954 // If a supersede or overwrite was requested, do so now ...
1955 if((RequestedDisposition == FILE_SUPERSEDE) ||
1956 (RequestedDisposition == FILE_OVERWRITE) ||
1957 (RequestedDisposition == FILE_OVERWRITE_IF)) {
1958 // Attempt the operation here ...
1959
1960#ifndef UDF_READ_ONLY_BUILD
1961 ASSERT(!UDFIsADirectory(NewFileInfo));
1962
1963 if(RequestedDisposition == FILE_SUPERSEDE) {
1964 BOOLEAN RestoreRO = FALSE;
1965
1966 ASSERT(Res1 != NULL);
1967 ASSERT(Res2 != NULL);
1968 // NT wants us to allow Supersede on RO files
1969 if(PtrNewFcb->FCBFlags & UDF_FCB_READ_ONLY) {
1970 // Imagine, that file is not RO and check other permissions
1971 RestoreRO = TRUE;
1972 PtrNewFcb->FCBFlags &= ~UDF_FCB_READ_ONLY;
1973 }
1974 RC = UDFCheckAccessRights(NULL, NULL, PtrNewFcb, PtrNewCcb, DELETE, 0);
1975 if(RestoreRO) {
1976 // Restore RO state if changed
1977 PtrNewFcb->FCBFlags |= UDF_FCB_READ_ONLY;
1978 }
1979 if(!NT_SUCCESS(RC)) {
1980 AdPrint((" Can't supersede. DELETE permission required\n"));
1981 try_return (RC);
1982 }
1983 } else {
1984 ASSERT(Res1 != NULL);
1985 ASSERT(Res2 != NULL);
1986 RC = UDFCheckAccessRights(NULL, NULL, PtrNewFcb, PtrNewCcb,
1988 if(!NT_SUCCESS(RC)) {
1989 AdPrint((" Can't overwrite. Permission denied\n"));
1990 try_return (RC);
1991 }
1992 }
1993 // Existing & requested System and Hidden bits must match
1994 if( (TmpFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) &
1996 AdPrint((" The Hidden and/or System bits do not match\n"));
1998 }
1999
2000 // Before we actually truncate, check to see if the purge
2001 // is going to fail.
2002 MmPrint((" MmCanFileBeTruncated()\n"));
2003 if (!MmCanFileBeTruncated( &NtReqFcb->SectionObject,
2004 &(UDFGlobalData.UDFLargeZero) )) {
2005 AdPrint((" Can't truncate. File is mapped\n"));
2007 }
2008
2009 ASSERT(Res1 != NULL);
2010 ASSERT(Res2 != NULL);
2011
2012#if 0
2013 CollectStatistics(Vcb, MetaDataWrites);
2014#endif
2015 // Synchronize with PagingIo
2016 UDFAcquireResourceExclusive(PagingIoRes = &(NtReqFcb->PagingIoResource),TRUE);
2017 // Set file sizes
2018 if(!NT_SUCCESS(RC = UDFResizeFile__(Vcb, NewFileInfo, 0))) {
2019 AdPrint((" Error during resize operation\n"));
2020 try_return(RC);
2021 }
2022/* if(AllocationSize) {
2023 if(!NT_SUCCESS(RC = UDFResizeFile__(Vcb, NewFileInfo, AllocationSize))) {
2024 AdPrint((" Error during resize operation (2)\n"));
2025 try_return(RC);
2026 }
2027 }*/
2028 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart = UDFSysGetAllocSize(Vcb, AllocationSize);
2029 NtReqFcb->CommonFCBHeader.FileSize.QuadPart =
2030 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = 0 /*AllocationSize*/;
2031 PtrNewFcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
2032 MmPrint((" CcSetFileSizes()\n"));
2033 CcSetFileSizes(PtrNewFileObject, (PCC_FILE_SIZES)&(NtReqFcb->CommonFCBHeader.AllocationSize));
2034 NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
2035 // Release PagingIoResource
2036 UDFReleaseResource(PagingIoRes);
2037 PagingIoRes = NULL;
2038
2039 if(NT_SUCCESS(RC)) {
2041 if (RequestedDisposition == FILE_SUPERSEDE) {
2042 // Set attributes for the file ...
2044 NewFileInfo->Dloc->FileEntry, FileAttributes);
2045 ReturnedInformation = FILE_SUPERSEDED;
2046 } else {
2047 // Get attributes for the file ...
2048 FileAttributes |= TmpFileAttributes;
2049 // Set attributes for the file ...
2051 NewFileInfo->Dloc->FileEntry, FileAttributes);
2052 ReturnedInformation = FILE_OVERWRITTEN;
2053 }
2054 }
2055 // notify changes
2056 UDFNotifyFullReportChange( Vcb, NewFileInfo,
2059
2060 // Update parent object
2061 if((Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_WRITE) &&
2062 PtrRelatedFCB &&
2063 PtrRelatedFileObject &&
2064 (PtrRelatedFCB->FileInfo == NewFileInfo->ParentFile)) {
2065 PtrRelatedFileObject->Flags |= (FO_FILE_MODIFIED | FO_FILE_SIZE_CHANGED);
2066 }
2067#else //UDF_READ_ONLY_BUILD
2069#endif //UDF_READ_ONLY_BUILD
2070 } else {
2071 ReturnedInformation = FILE_OPENED;
2072 }
2073
2074 // Update parent object
2075 if((Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_READ) &&
2076 PtrRelatedFCB &&
2077 PtrRelatedFileObject &&
2078 (PtrRelatedFCB->FileInfo == NewFileInfo->ParentFile)) {
2079 PtrRelatedFileObject->Flags |= FO_FILE_FAST_IO_READ;
2080 }
2081
2082try_exit: NOTHING;
2083
2084 } _SEH2_FINALLY {
2085 // Complete the request unless we are here as part of unwinding
2086 // when an exception condition was encountered, OR
2087 // if the request has been deferred (i.e. posted for later handling)
2088
2089 if(RestoreVCBOpenCounter) {
2090 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
2091 RestoreVCBOpenCounter = FALSE;
2092 }
2093
2094 if (RC != STATUS_PENDING) {
2095 // If any intermediate (directory) open operations were performed,
2096 // implement the corresponding close (do *not* however close
2097 // the target we have opened on behalf of the caller ...).
2098
2099#if 0
2100 if(NT_SUCCESS(RC)) {
2101 CollectStatistics2(Vcb, SuccessfulCreates);
2102 } else {
2103 CollectStatistics2(Vcb, FailedCreates);
2104 }
2105#endif
2106
2107 if (NT_SUCCESS(RC) && PtrNewFcb) {
2108 // Update the file object such that:
2109 // (a) the FsContext field points to the NTRequiredFCB field
2110 // in the FCB
2111 // (b) the FsContext2 field points to the CCB created as a
2112 // result of the open operation
2113
2114 // If write-through was requested, then mark the file object
2115 // appropriately
2116
2117 // directories are not cached
2118 // so we should prevent flush attepmts on cleanup
2119 if(!(PtrNewFcb->FCBFlags & UDF_FCB_DIRECTORY)) {
2120#ifndef UDF_READ_ONLY_BUILD
2121 if(WriteThroughRequested) {
2122 PtrNewFileObject->Flags |= FO_WRITE_THROUGH;
2123 PtrNewFcb->FCBFlags |= UDF_FCB_WRITE_THROUGH;
2124 MmPrint((" FO_WRITE_THROUGH\n"));
2125 }
2126#endif //UDF_READ_ONLY_BUILD
2128 !(Vcb->CompatFlags & UDF_VCB_IC_IGNORE_SEQUENTIAL_IO)) {
2129 PtrNewFileObject->Flags |= FO_SEQUENTIAL_ONLY;
2130 MmPrint((" FO_SEQUENTIAL_ONLY\n"));
2131#ifndef UDF_READ_ONLY_BUILD
2132 if(Vcb->TargetDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
2133 PtrNewFileObject->Flags &= ~FO_WRITE_THROUGH;
2134 PtrNewFcb->FCBFlags &= ~UDF_FCB_WRITE_THROUGH;
2135 MmPrint((" FILE_REMOVABLE_MEDIA + FO_SEQUENTIAL_ONLY => ~FO_WRITE_THROUGH\n"));
2136 }
2137#endif //UDF_READ_ONLY_BUILD
2138 if(PtrNewFcb->FileInfo) {
2140 }
2141 }
2143 PtrNewFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
2144 MmPrint((" FO_NO_INTERMEDIATE_BUFFERING\n"));
2145 } else {
2146 PtrNewFileObject->Flags |= FO_CACHE_SUPPORTED;
2147 MmPrint((" FO_CACHE_SUPPORTED\n"));
2148 }
2149 }
2150
2151 if((DesiredAccess & FILE_EXECUTE) /*&&
2152 !(PtrNewFcb->FCBFlags & UDF_FCB_DIRECTORY)*/) {
2153 MmPrint((" FO_FILE_FAST_IO_READ\n"));
2154 PtrNewFileObject->Flags |= FO_FILE_FAST_IO_READ;
2155 }
2156 // All right. Now we can safely increment OpenHandleCount
2157 UDFInterlockedIncrement((PLONG)&(Vcb->VCBHandleCount));
2158 UDFInterlockedIncrement((PLONG)&(PtrNewFcb->OpenHandleCount));
2159
2160 if(PtrNewFileObject->Flags & FO_CACHE_SUPPORTED)
2161 UDFInterlockedIncrement((PLONG)&(PtrNewFcb->CachedOpenHandleCount));
2162 // Store some flags in CCB
2163 if(PtrNewCcb) {
2164 PtrNewCcb->TreeLength = TreeLength;
2165 // delete on close
2166#ifndef UDF_READ_ONLY_BUILD
2167 if(DeleteOnCloseSpecified) {
2168 ASSERT(!(PtrNewFcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
2169 PtrNewCcb->CCBFlags |= UDF_CCB_DELETE_ON_CLOSE;
2170 }
2171#endif //UDF_READ_ONLY_BUILD
2172 // case sensetivity
2173 if(!IgnoreCase) {
2174 // remember this for possible Rename/Move operation
2175 PtrNewCcb->CCBFlags |= UDF_CCB_CASE_SENSETIVE;
2176 PtrNewFileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
2177 }
2178 if(IsFileObjectReadOnly(PtrNewFileObject)) {
2179 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCountRO));
2180 PtrNewCcb->CCBFlags |= UDF_CCB_READ_ONLY;
2181 }
2182 } else {
2183 BrutePoint();
2184 }
2185 // it was a stream...
2186 if(StreamOpen)
2187 PtrNewFileObject->Flags |= FO_STREAM_FILE;
2188// PtrNewCcb->CCBFlags |= UDF_CCB_VALID;
2189 // increment the number of outstanding open operations on this
2190 // logical volume (i.e. volume cannot be dismounted)
2191 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
2192 PtrNewFcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
2193 PtrNewFcb->FCBFlags |= UDF_FCB_VALID;
2194#ifdef UDF_DBG
2195 // We have no FileInfo for Volume
2196 if(PtrNewFcb->FileInfo) {
2197 ASSERT_REF(PtrNewFcb->ReferenceCount >= PtrNewFcb->FileInfo->RefCount);
2198 }
2199#endif // UDF_DBG
2200 AdPrint((" FCB %x, CCB %x, FO %x, Flags %x\n", PtrNewFcb, PtrNewCcb, PtrNewFileObject, PtrNewFcb->FCBFlags));
2201
2202 UDFReleaseResFromCreate(&PagingIoRes, &Res1, &Res2);
2203
2204 } else if(!NT_SUCCESS(RC)) {
2205 // Perform failure related post-processing now
2206 if(RestoreShareAccess && NtReqFcb && PtrNewFileObject) {
2207 IoRemoveShareAccess(PtrNewFileObject, &(NtReqFcb->FCBShareAccess));
2208 }
2209 UDFCleanUpCCB(PtrNewCcb);
2210 if(PtrNewFileObject) {
2211 PtrNewFileObject->FsContext2 = NULL;
2212 }
2213 // We have successfully opened LastGoodFileInfo,
2214 // so mark it as VALID to avoid future troubles...
2215 if(LastGoodFileInfo && LastGoodFileInfo->Fcb) {
2216 LastGoodFileInfo->Fcb->FCBFlags |= UDF_FCB_VALID;
2217 if(LastGoodFileInfo->Fcb->NTRequiredFCB) {
2218 LastGoodFileInfo->Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
2219 }
2220 }
2221 // Release resources...
2222 UDFReleaseResFromCreate(&PagingIoRes, &Res1, &Res2);
2223 ASSERT(AcquiredVcb);
2224 // close the chain
2225 UDFCloseFileInfoChain(Vcb, LastGoodFileInfo, TreeLength, TRUE);
2226 // cleanup FCBs (if any)
2227 if( Vcb && (PtrNewFcb != Vcb->RootDirFCB) &&
2228 LastGoodFileInfo ) {
2229 UDFCleanUpFcbChain(Vcb, LastGoodFileInfo, TreeLength, TRUE);
2230 } else {
2231 ASSERT(!LastGoodFileInfo);
2232 }
2233 } else {
2234 UDFReleaseResFromCreate(&PagingIoRes, &Res1, &Res2);
2235 }
2236 // As long as this unwinding is not being performed as a result of
2237 // an exception condition, complete the IRP ...
2239 Irp->IoStatus.Status = RC;
2240 Irp->IoStatus.Information = ReturnedInformation;
2241
2242 // complete the IRP
2244 // Free up the Irp Context
2245 UDFReleaseIrpContext(PtrIrpContext);
2246 }
2247 } else {
2248 UDFReleaseResFromCreate(&PagingIoRes, &Res1, &Res2);
2249 }
2250
2251 if(AcquiredVcb) {
2252 UDFReleaseResource(&(Vcb->VCBResource));
2253 }
2254 // free allocated tmp buffers (if any)
2255 if(AbsolutePathName.Buffer)
2256 MyFreePool__(AbsolutePathName.Buffer);
2257 if(LocalPath.Buffer)
2258 MyFreePool__(LocalPath.Buffer);
2259 if(TailNameBuffer)
2260 MyFreePool__(TailNameBuffer);
2261 } _SEH2_END;
2262
2263 return(RC);
2264} // end UDFCommonCreate()
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
DWORD Id
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
unsigned char BOOLEAN
VOID UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry, IN ULONG NTAttr)
ULONG UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry)
NTSTATUS MyCloneUnicodeString(IN PUNICODE_STRING Str1, IN PUNICODE_STRING Str2)
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
#define CcIsFileCached(FO)
#define try_return(S)
Definition: cdprocs.h:2179
struct _VCB * PVCB
Definition: fatstruc.h:557
NTSTATUS UDFCloseFileInfoChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: cleanup.cpp:696
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define IgnoreCase
Definition: cdprocs.h:461
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define FILE_SHARE_READ
Definition: compat.h:136
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK _In_ USHORT ShareAccess
Definition: create.c:4147
VOID __fastcall UDFReleaseResFromCreate(IN PERESOURCE *PagingIoRes, IN PERESOURCE *Res1, IN PERESOURCE *Res2)
Definition: create.cpp:122
#define OpenByFileId
#define IsFileObjectReadOnly(FO)
Definition: create.cpp:19
#define MEM_USABS_TAG
Definition: create.cpp:24
#define FileOnlyRequested
VOID __fastcall UDFAcquireParent(IN PUDF_FILE_INFO RelatedFileInfo, IN PERESOURCE *Res1, IN PERESOURCE *Res2)
Definition: create.cpp:146
#define NoBufferingSpecified
#define OpenForBackup
#define SequentialIoRequested
#define MEM_USLOC_TAG
Definition: create.cpp:25
#define DirectoryOnlyRequested
NTSTATUS UDFOpenFile(PVCB Vcb, PFILE_OBJECT PtrNewFileObject, PtrUDFFCB PtrNewFcb)
Definition: create.cpp:2437
NTSTATUS UDFFirstOpenFile(IN PVCB Vcb, IN PFILE_OBJECT PtrNewFileObject, OUT PtrUDFFCB *PtrNewFcb, IN PUDF_FILE_INFO RelatedFileInfo, IN PUDF_FILE_INFO NewFileInfo, IN PUNICODE_STRING LocalPath, IN PUNICODE_STRING CurName)
Definition: create.cpp:2281
VOID __fastcall UDFCleanUpFCB(PtrUDFFCB Fcb)
Definition: misc.cpp:908
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
VOID __fastcall UDFCleanUpCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:805
#define INTEGRITY_TYPE_OPEN
Definition: ecma_167.h:357
#define UDFNotifyVolumeEvent(FileObject, EventCode)
Definition: env_spec.h:114
#define CollectStatistics(VCB, Field)
Definition: env_spec.h:120
__inline VOID UDFNotifyFullReportChange(PVCB V, PUDF_FILE_INFO FI, ULONG E, ULONG A)
Definition: env_spec.h:99
#define GetCurrentPID()
Definition: env_spec.h:152
#define CollectStatistics2(VCB, Field)
Definition: env_spec.h:128
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
NTSTATUS MyInitUnicodeString(IN PUNICODE_STRING Str1, IN PCWSTR Str2)
#define UDFConvertExclusiveToSharedLite(Resource)
Definition: env_spec_w32.h:665
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
#define TmPrint(_x_)
Definition: env_spec_w32.h:290
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define BrutePoint()
Definition: env_spec_w32.h:504
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
#define NtReqFcb
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:323
NTSTATUS UDFGetOpenParamsByFileId(IN PVCB Vcb, IN LONGLONG Id, OUT PUNICODE_STRING *FName, OUT BOOLEAN *CaseSens)
Definition: fileinfo.cpp:2472
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1236
VOID UDFFlushTryBreak(IN PVCB Vcb)
Definition: flush.cpp:625
ULONG UDFFlushLogicalVolume(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PVCB Vcb, IN ULONG FlushFlags)
Definition: flush.cpp:506
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING StreamName
Definition: fsrtlfuncs.h:741
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define NOTHING
Definition: input_list.c:10
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN __fastcall UDFIsNameValid(IN PUNICODE_STRING SearchPattern, OUT BOOLEAN *StreamOpen, OUT ULONG *SNameIndex)
Definition: namesup.cpp:92
PWCHAR __fastcall UDFDissectName(IN PWCHAR Buffer, OUT PUSHORT Length)
Definition: namesup.cpp:19
#define UserMode
Definition: asm.h:35
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_DOES_NOT_EXIST
Definition: nt_native.h:773
#define FILE_ATTRIBUTE_VALID_FLAGS
Definition: nt_native.h:714
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_DELETE_CHILD
Definition: nt_native.h:645
#define FILE_CREATED
Definition: nt_native.h:770
#define FILE_OVERWRITTEN
Definition: nt_native.h:771
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_SUPERSEDED
Definition: nt_native.h:768
#define FILE_EXISTS
Definition: nt_native.h:772
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
#define FILE_OPENED
Definition: nt_native.h:769
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define FILE_WRITE_EA
Definition: nt_native.h:640
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
#define FSRTL_VOLUME_LOCK
Definition: ntifs_ex.h:441
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3478
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:711
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
#define STATUS_EAS_NOT_SUPPORTED
Definition: ntstatus.h:315
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define Vcb
Definition: cdprocs.h:1415
NTSTATUS UDFVerifyVcb(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb)
Definition: verfysup.cpp:37
NTSTATUS UDFSetAccessRights(PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: secursup.cpp:1049
NTSTATUS UDFCheckAccessRights(PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: secursup.cpp:927
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:166
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_VOLATILE
Definition: pseh2_64.h:169
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
Definition: section.c:4260
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4361
PSE_EXPORTS SeExports
Definition: semgr.c:21
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define UDF_FCB_VALID
Definition: struct.h:300
#define UDF_FCB_READ_ONLY
Definition: struct.h:312
struct _UDFFileControlBlock * PtrUDFFCB
#define UDF_IRP_CONTEXT_FLUSH2_REQUIRED
Definition: struct.h:393
#define UDF_IRP_CONTEXT_FLUSH_REQUIRED
Definition: struct.h:392
#define UDF_CCB_READ_ONLY
Definition: struct.h:170
#define UDF_NTREQ_FCB_VALID
Definition: struct.h:237
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
#define UDF_FCB_DELETED
Definition: struct.h:314
#define UDF_CCB_VOLUME_OPEN
Definition: struct.h:166
#define UDF_NODE_TYPE_CCB
Definition: struct.h:59
#define UDF_FCB_POSTED_RENAME
Definition: struct.h:317
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_CCB_CASE_SENSETIVE
Definition: struct.h:159
#define UDF_FCB_ROOT_DIRECTORY
Definition: struct.h:304
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDF_NTREQ_FCB_MODIFIED
Definition: struct.h:236
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDF_FCB_DELETE_ON_CLOSE
Definition: struct.h:309
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define UDF_FCB_WRITE_THROUGH
Definition: struct.h:305
#define UDF_CCB_DELETE_ON_CLOSE
Definition: struct.h:162
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PACCESS_STATE AccessState
Definition: iotypes.h:2867
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2868
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1579 Parameters
struct _IO_STACK_LOCATION::@3978::@3979 Create
LUID SeBackupPrivilege
Definition: setypes.h:1210
UDFIdentifier NodeIdentifier
Definition: struct.h:109
struct _UDFFileControlBlock * Fcb
Definition: struct.h:111
PVOID AutoFormatCount
Definition: udf_common.h:629
UNICODE_STRING UnicodeStrSDir
Definition: udf_common.h:617
PtrUDFObjectName FCBName
Definition: struct.h:286
struct _UDFFileControlBlock * ParentFcb
Definition: struct.h:289
UDFIdentifier NodeIdentifier
Definition: struct.h:252
PUDF_FILE_INFO FileInfo
Definition: struct.h:257
uint32 NodeType
Definition: struct.h:75
uint32 IrpContextFlags
Definition: struct.h:364
PDEVICE_OBJECT TargetDeviceObject
Definition: struct.h:374
UNICODE_STRING ObjectName
Definition: struct.h:94
struct _UDFNTRequiredFCB * CommonFcb
Definition: udf_rel.h:255
uint32 LinkRefCount
Definition: udf_rel.h:306
PUDF_DATALOC_INFO Dloc
Definition: udf_rel.h:367
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
uint32 RefCount
Definition: udf_rel.h:399
struct _UDF_FILE_INFO * ParentFile
Definition: udf_rel.h:381
uint_di Index
Definition: udf_rel.h:392
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cdstruc.h:498
int64_t LONGLONG
Definition: typedefs.h:68
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define UDF_VCB_IC_DIRTY_RO
Definition: udf_common.h:516
#define UDF_VCB_IC_IGNORE_SEQUENTIAL_IO
Definition: udf_common.h:506
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_VCB_FLAGS_VOLUME_LOCKED
Definition: udf_common.h:460
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY
Definition: udf_common.h:481
#define UDF_VCB_IC_UPDATE_DIR_READ
Definition: udf_common.h:498
#define UDF_VCB_IC_UPDATE_DIR_WRITE
Definition: udf_common.h:497
#define UDF_VCB_IC_SHOW_BLANK_CD
Definition: udf_common.h:520
#define UDF_VCB_IC_FORCE_WRITE_THROUGH
Definition: udf_common.h:504
OSSTATUS UDFRecordDirectory__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO DirInfo)
Definition: udf_info.cpp:3384
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
OSSTATUS UDFUnlinkFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN FreeSpace)
Definition: udf_info.cpp:1766
OSSTATUS UDFOpenStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4965
OSSTATUS UDFResizeFile__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo, IN int64 NewLength)
Definition: udf_info.cpp:3468
OSSTATUS UDFCreateFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN PUNICODE_STRING _fn, IN uint32 ExtAttrSz, IN uint32 ImpUseLen, IN BOOLEAN Extended, IN BOOLEAN CreateNew, IN OUT PUDF_FILE_INFO DirInfo, OUT PUDF_FILE_INFO *_FileInfo)
Definition: udf_info.cpp:2577
OSSTATUS UDFCreateStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4888
OSSTATUS UDFOpenFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN BOOLEAN NotDeleted, IN PUNICODE_STRING fn, IN PUDF_FILE_INFO DirInfo, OUT PUDF_FILE_INFO *_FileInfo, IN uint_di *IndexToOpen)
Definition: udf_info.cpp:2004
#define UDFStreamsSupported(Vcb)
Definition: udf_info.h:1037
#define UDFIsDirEmpty__(fi)
Definition: udf_info.h:1070
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
__inline OSSTATUS UDFFindFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN PUNICODE_STRING Name, IN PUDF_FILE_INFO DirInfo)
Definition: udf_info.h:114
#define UDFIsADirectory(FileInfo)
Definition: udf_info.h:792
#define UDFSetFileAllocMode__(fi, mode)
Definition: udf_info.h:1073
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
#define EXTENT_FLAG_ALLOC_SEQUENTIAL
Definition: udf_rel.h:77
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_SHARING_PAUSED
Definition: udferr_usr.h:165
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define UdfIllegalFcbAccess(Vcb, DesiredAccess)
Definition: udffs.h:201
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDF_X_PATH_LEN
Definition: udffs.h:33
#define UDFPrint(Args)
Definition: udffs.h:223
#define UDF_X_NAME_LEN
Definition: udffs.h:32
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1817
#define FO_SEQUENTIAL_ONLY
Definition: iotypes.h:1780
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_ACTION_MODIFIED
#define FO_OPENED_CASE_SENSITIVE
Definition: iotypes.h:1793
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1795
#define FILE_NOTIFY_CHANGE_STREAM_NAME
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define FILE_NOTIFY_CHANGE_FILE_NAME
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1789
#define FO_STREAM_FILE
Definition: iotypes.h:1783
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778
#define FO_CACHE_SUPPORTED
Definition: iotypes.h:1781
#define FILE_ACTION_ADDED_STREAM
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1818
#define FILE_ACTION_ADDED
#define FILE_NOTIFY_CHANGE_DIR_NAME
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1820
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by UDFCommonDispatch(), and UDFCreate().

◆ UDFCreate()

NTSTATUS NTAPI UDFCreate ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 48 of file create.cpp.

51{
53 PtrUDFIrpContext PtrIrpContext;
54 BOOLEAN AreWeTopLevel = FALSE;
55
56 TmPrint(("UDFCreate:\n"));
57
60 ASSERT(Irp);
61
62 // sometimes, we may be called here with the device object representing
63 // the file system (instead of the device object created for a logical
64 // volume. In this case, there is not much we wish to do (this create
65 // typically will happen 'cause some process has to open the FSD device
66 // object so as to be able to send an IOCTL to the FSD)
67
68 // All of the logical volume device objects we create have a device
69 // extension whereas the device object representing the FSD has no
70 // device extension. This seems like a good enough method to identify
71 // between the two device objects ...
72 if (UDFIsFSDevObj(DeviceObject)) {
73 // this is an open of the FSD itself
74 Irp->IoStatus.Status = RC;
75 Irp->IoStatus.Information = FILE_OPENED;
76
79 return(RC);
80 }
81
82 // set the top level context
83 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
84
85 _SEH2_TRY {
86
87 // get an IRP context structure and issue the request
88 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
89 if(PtrIrpContext) {
90 RC = UDFCommonCreate(PtrIrpContext, Irp);
91 } else {
93 Irp->IoStatus.Status = RC;
94 Irp->IoStatus.Information = 0;
95 // complete the IRP
97 }
98
100
101 RC = UDFExceptionHandler(PtrIrpContext, Irp);
102
104 } _SEH2_END;
105
106 if (AreWeTopLevel) {
108 }
109
110 AdPrint(("UDFCreate: %x\n", RC));
111
113
114 return(RC);
115
116} // end UDFCreate()
NTSTATUS UDFCommonCreate(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: create.cpp:186
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by UDFInitializeFunctionPointers().

◆ UDFFirstOpenFile()

NTSTATUS UDFFirstOpenFile ( IN PVCB  Vcb,
IN PFILE_OBJECT  PtrNewFileObject,
OUT PtrUDFFCB PtrNewFcb,
IN PUDF_FILE_INFO  RelatedFileInfo,
IN PUDF_FILE_INFO  NewFileInfo,
IN PUNICODE_STRING  LocalPath,
IN PUNICODE_STRING  CurName 
)

Definition at line 2281 of file create.cpp.

2290{
2291// DIR_INDEX NewFileIndex;
2292 PtrUDFObjectName NewFCBName;
2294 NTSTATUS RC;
2296 PDIR_INDEX_HDR hDirIndex;
2297 PDIR_INDEX_ITEM DirIndex;
2298
2299 AdPrint(("UDFFirstOpenFile\n"));
2300
2301 if(!((*PtrNewFcb) = UDFAllocateFCB())) {
2302 AdPrint(("Can't allocate FCB\n"));
2304 }
2305
2306 // Allocate and set new FCB unique name (equal to absolute path name)
2307 if(!(NewFCBName = UDFAllocateObjectName())) return STATUS_INSUFFICIENT_RESOURCES;
2308
2309 if(RelatedFileInfo && RelatedFileInfo->Fcb &&
2310 !(RelatedFileInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY)) {
2311 RC = MyCloneUnicodeString(&(NewFCBName->ObjectName), &(RelatedFileInfo->Fcb->FCBName->ObjectName));
2312 } else {
2313 RC = MyInitUnicodeString(&(NewFCBName->ObjectName), L"");
2314 }
2315 if(!NT_SUCCESS(RC))
2317 if( (CurName->Buffer[0] != L':') &&
2318 (!LocalPath->Length ||
2319 ((LocalPath->Buffer[LocalPath->Length/sizeof(WCHAR)-1] != L':') /*&&
2320 (LocalPath->Buffer[LocalPath->Length/sizeof(WCHAR)-1] != L'\\')*/) )) {
2321 RC = MyAppendUnicodeToString(&(NewFCBName->ObjectName), L"\\");
2322 if(!NT_SUCCESS(RC)) {
2323 UDFReleaseObjectName(NewFCBName);
2325 }
2326 }
2327
2328 // Make link between Fcb and FileInfo
2329 (*PtrNewFcb)->FileInfo = NewFileInfo;
2330 NewFileInfo->Fcb = (*PtrNewFcb);
2331 (*PtrNewFcb)->ParentFcb = RelatedFileInfo->Fcb;
2332
2333 if(!((*PtrNewFcb)->NTRequiredFCB = NewFileInfo->Dloc->CommonFcb)) {
2334 (*PtrNewFcb)->NTRequiredFCB = (PtrUDFNTRequiredFCB)MyAllocatePool__(NonPagedPool, UDFQuadAlign(sizeof(UDFNTRequiredFCB)));
2335 if(!((*PtrNewFcb)->NTRequiredFCB)) {
2336 UDFReleaseObjectName(NewFCBName);
2338 }
2339
2340 UDFPrint(("UDFAllocateNtReqFCB: %x\n", (*PtrNewFcb)->NTRequiredFCB));
2341 RtlZeroMemory((*PtrNewFcb)->NTRequiredFCB, UDFQuadAlign(sizeof(UDFNTRequiredFCB)));
2342 (*PtrNewFcb)->FileInfo->Dloc->CommonFcb = (*PtrNewFcb)->NTRequiredFCB;
2343 Linked = FALSE;
2344 } else {
2345 if(!(NewFileInfo->Dloc->CommonFcb->NtReqFCBFlags & UDF_NTREQ_FCB_VALID)) {
2346 (*PtrNewFcb)->NTRequiredFCB = NULL;
2347 BrutePoint();
2348 UDFReleaseObjectName(NewFCBName);
2349 return STATUS_ACCESS_DENIED;
2350 }
2351 }
2352
2353 NtReqFcb = (*PtrNewFcb)->NTRequiredFCB;
2354 // Set times
2355 if(!Linked) {
2356 UDFGetFileXTime((*PtrNewFcb)->FileInfo,
2357 &(NtReqFcb->CreationTime.QuadPart),
2358 &(NtReqFcb->LastAccessTime.QuadPart),
2359 &(NtReqFcb->ChangeTime.QuadPart),
2360 &(NtReqFcb->LastWriteTime.QuadPart) );
2361
2362 // Set the allocation size for the object is specified
2363 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart =
2364 UDFSysGetAllocSize(Vcb, NewFileInfo->Dloc->DataLoc.Length);
2365// NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart = UDFGetFileAllocationSize(Vcb, NewFileInfo);
2366 NtReqFcb->CommonFCBHeader.FileSize.QuadPart =
2367 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = NewFileInfo->Dloc->DataLoc.Length;
2368 }
2369 // begin transaction
2370 UDFAcquireResourceExclusive(&(Vcb->FcbListResource), TRUE);
2371
2372 RC = UDFInitializeFCB(*PtrNewFcb, Vcb, NewFCBName,
2373 UDFIsADirectory(NewFileInfo) ? UDF_FCB_DIRECTORY : 0, PtrNewFileObject);
2374 if(!NT_SUCCESS(RC)) {
2375 if(!Linked) {
2376 MyFreePool__((*PtrNewFcb)->NTRequiredFCB);
2377 (*PtrNewFcb)->NTRequiredFCB = NULL;
2378 }
2379 UDFReleaseResource(&(Vcb->FcbListResource));
2380 return RC;
2381 }
2382 // set Read-only attribute
2383 if(!UDFIsAStreamDir(NewFileInfo)) {
2384 hDirIndex = UDFGetDirIndexByFileInfo(NewFileInfo);
2385#ifdef UDF_DBG
2386 if(!hDirIndex) {
2387 BrutePoint();
2388 } else {
2389#endif // UDF_DBG
2390 if(UDFAttributesToNT(DirIndex = UDFDirIndex(hDirIndex, NewFileInfo->Index),NULL) & FILE_ATTRIBUTE_READONLY) {
2391 (*PtrNewFcb)->FCBFlags |= UDF_FCB_READ_ONLY;
2392 }
2393 MyAppendUnicodeStringToStringTag(&(NewFCBName->ObjectName), &(DirIndex->FName), MEM_USOBJ_TAG);
2394#ifdef UDF_DBG
2395 }
2396#endif // UDF_DBG
2397 } else if (RelatedFileInfo->ParentFile) {
2398 hDirIndex = UDFGetDirIndexByFileInfo(RelatedFileInfo);
2399 if(UDFAttributesToNT(DirIndex = UDFDirIndex(hDirIndex, RelatedFileInfo->Index),NULL) & FILE_ATTRIBUTE_READONLY) {
2400 (*PtrNewFcb)->FCBFlags |= UDF_FCB_READ_ONLY;
2401 }
2402 RC = MyAppendUnicodeStringToStringTag(&(NewFCBName->ObjectName), CurName, MEM_USOBJ_TAG);
2403// } else {
2404// BrutePoint();
2405 }
2406 // do not allocate CCB if it is internal Create/Open
2407 if(NT_SUCCESS(RC)) {
2408 if(PtrNewFileObject) {
2409 RC = UDFOpenFile(Vcb, PtrNewFileObject, *PtrNewFcb);
2410 } else {
2411 RC = STATUS_SUCCESS;
2412 }
2413 }
2414 UDFReleaseResource(&(Vcb->FcbListResource));
2415 // end transaction
2416
2417// if(!NT_SUCCESS(RC)) return RC;
2418
2419 return RC;
2420} // end UDFFirstOpenFile()
VOID UDFGetFileXTime(IN PUDF_FILE_INFO FileInfo, OUT LONGLONG *CrtTime, OUT LONGLONG *AccTime, OUT LONGLONG *AttrTime, OUT LONGLONG *ChgTime)
static const WCHAR Linked[]
Definition: interface.c:30
#define MEM_USOBJ_TAG
Definition: create.cpp:26
NTSTATUS UDFInitializeFCB(IN PtrUDFFCB PtrNewFcb, IN PVCB Vcb, IN PtrUDFObjectName PtrObjectName, IN ULONG Flags, IN PFILE_OBJECT FileObject)
Definition: create.cpp:2517
VOID __fastcall UDFReleaseObjectName(PtrUDFObjectName PtrObjectName)
Definition: misc.cpp:670
PtrUDFObjectName UDFAllocateObjectName(VOID)
Definition: misc.cpp:611
PtrUDFFCB UDFAllocateFCB(VOID)
Definition: misc.cpp:854
#define NonPagedPool
Definition: env_spec_w32.h:307
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
struct _UDFNTRequiredFCB * PtrUDFNTRequiredFCB
UNICODE_STRING FName
Definition: udf_rel.h:173
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define UDFQuadAlign(Value)
Definition: udffs.h:194

Referenced by UDFCommonCreate().

◆ UDFInitializeFCB()

NTSTATUS UDFInitializeFCB ( IN PtrUDFFCB  PtrNewFcb,
IN PVCB  Vcb,
IN PtrUDFObjectName  PtrObjectName,
IN ULONG  Flags,
IN PFILE_OBJECT  FileObject 
)

Definition at line 2517 of file create.cpp.

2523{
2524 AdPrint(("UDFInitializeFCB\n"));
2527
2528 if(!PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource) {
2529 // record signature
2530 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeTypeCode = UDF_NODE_TYPE_NT_REQ_FCB;
2531 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeByteSize = sizeof(UDFNTRequiredFCB);
2532 // Initialize the ERESOURCE objects
2533 if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->NTRequiredFCB->MainResource)))) {
2534 AdPrint((" Can't init resource\n"));
2535 return status;
2536 }
2537 if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->NTRequiredFCB->PagingIoResource)))) {
2538 AdPrint((" Can't init resource (2)\n"));
2539 UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->MainResource));
2540 return status;
2541 }
2542 // Fill NT required Fcb part
2543 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource = &(PtrNewFcb->NTRequiredFCB->MainResource);
2544 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource = &(PtrNewFcb->NTRequiredFCB->PagingIoResource);
2545 // Itialize byte-range locks support structure
2546 FsRtlInitializeFileLock(&(PtrNewFcb->NTRequiredFCB->FileLock),NULL,NULL);
2547 // Init reference counter
2548 PtrNewFcb->NTRequiredFCB->CommonRefCount = 0;
2549 Linked = FALSE;
2550 } else {
2551 ASSERT(PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeTypeCode == UDF_NODE_TYPE_NT_REQ_FCB);
2552 }
2553 if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->CcbListResource)))) {
2554 AdPrint((" Can't init resource (3)\n"));
2555 BrutePoint();
2556 if(!Linked) {
2557 UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->PagingIoResource));
2558 UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->MainResource));
2559 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource =
2560 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource = NULL;
2561 FsRtlUninitializeFileLock(&(PtrNewFcb->NTRequiredFCB->FileLock));
2562 }
2563 return status;
2564 }
2565
2566 // caller MUST ensure that VCB has been acquired exclusively
2567 InsertTailList(&(Vcb->NextFCB), &(PtrNewFcb->NextFCB));
2568
2569 // initialize the various list heads
2570 InitializeListHead(&(PtrNewFcb->NextCCB));
2571
2572 PtrNewFcb->ReferenceCount = 0;
2573 PtrNewFcb->OpenHandleCount = 0;
2574
2575 PtrNewFcb->FCBFlags = Flags | UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE;
2576
2577 PtrNewFcb->FCBName = PtrObjectName;
2578
2579 PtrNewFcb->Vcb = Vcb;
2580
2581 return STATUS_SUCCESS;
2582} // end UDFInitializeFCB()
#define InsertTailList(ListHead, Entry)
#define UDFDeleteResource(Resource)
Definition: env_spec_w32.h:663
#define UDFInitializeResourceLite(Resource)
Definition: env_spec_w32.h:667
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1262
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
#define UDF_NODE_TYPE_NT_REQ_FCB
Definition: struct.h:57
#define UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE
Definition: struct.h:316
struct _UDFNTRequiredFCB UDFNTRequiredFCB
Definition: ps.c:97
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by UDFBlankMount(), UDFCompleteMount(), and UDFFirstOpenFile().

◆ UDFOpenFile()

NTSTATUS UDFOpenFile ( PVCB  Vcb,
PFILE_OBJECT  PtrNewFileObject,
PtrUDFFCB  PtrNewFcb 
)

Definition at line 2437 of file create.cpp.

2442{
2444 PtrUDFCCB Ccb = NULL;
2446
2447 AdPrint(("UDFOpenFile\n"));
2449 ||(PtrNewFcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB));
2450
2451 _SEH2_TRY {
2452
2453#if 0
2454 CollectStatistics2(Vcb, CreateHits);
2455#endif
2456 // create a new CCB structure
2457 if (!(Ccb = UDFAllocateCCB())) {
2458 AdPrint(("Can't allocate CCB\n"));
2459 PtrNewFileObject->FsContext2 = NULL;
2460 //
2464 try_return(RC);
2465 }
2466 // initialize the CCB
2467 Ccb->Fcb = PtrNewFcb;
2468 // initialize the CCB to point to the file object
2469 Ccb->FileObject = PtrNewFileObject;
2470
2471 // initialize the file object appropriately
2472 PtrNewFileObject->FsContext2 = (PVOID)(Ccb);
2473 PtrNewFileObject->Vpb = Vcb->Vpb;
2474 PtrNewFileObject->FsContext = (PVOID)(NtReqFcb = PtrNewFcb->NTRequiredFCB);
2475 PtrNewFileObject->SectionObjectPointer = &(NtReqFcb->SectionObject);
2476#ifdef DBG
2477// NtReqFcb ->FileObject = PtrNewFileObject;
2478#endif //DBG
2479
2480#ifdef UDF_DELAYED_CLOSE
2481 PtrNewFcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
2482#endif //UDF_DELAYED_CLOSE
2483
2485 // insert CCB into linked list of open file object to Fcb or
2486 // to Vcb and do other intialization
2487 InsertTailList(&(PtrNewFcb->NextCCB), &(Ccb->NextCCB));
2490 UDFReleaseResource(&(PtrNewFcb->CcbListResource));
2491
2492try_exit: NOTHING;
2493 } _SEH2_FINALLY {
2494 NOTHING;
2495 } _SEH2_END;
2496
2497 return(RC);
2498} // end UDFOpenFile()
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
PtrUDFCCB UDFAllocateCCB(VOID)
Definition: misc.cpp:707
struct _FCB::@729::@732 Fcb
PFILE_OBJECT FileObject
Definition: ntfs.h:520
ERESOURCE CcbListResource
Definition: struct.h:287
PtrUDFNTRequiredFCB NTRequiredFCB
Definition: struct.h:255
uint32 ReferenceCount
Definition: struct.h:281
LIST_ENTRY NextCCB
Definition: struct.h:268
ULONG CommonRefCount
Definition: struct.h:218
void * PVOID
Definition: typedefs.h:50

Referenced by UDFCommonCreate(), and UDFFirstOpenFile().

◆ UDFReleaseResFromCreate()

VOID __fastcall UDFReleaseResFromCreate ( IN PERESOURCE PagingIoRes,
IN PERESOURCE Res1,
IN PERESOURCE Res2 
)

Definition at line 122 of file create.cpp.

127{
128 if(*PagingIoRes) {
129 UDFReleaseResource(*PagingIoRes);
130 (*PagingIoRes) = NULL;
131 }
132 if(*Res1) {
133 UDFReleaseResource(*Res1);
134 (*Res1) = NULL;
135 }
136 if(*Res2) {
137 UDFReleaseResource(*Res2);
138 (*Res2) = NULL;
139 }
140} // end UDFReleaseResFromCreate()

Referenced by UDFCommonCreate().