ReactOS  0.4.15-dev-1184-g23e04ae
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 UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
#define TRUE
Definition: types.h:120
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262
signed int * PLONG
Definition: retypes.h:5

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 
207  PVCB Vcb = NULL;
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...
245  UNICODE_STRING StreamName; // ':s'
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);
308  ASSERT(PtrRelatedCCB->NodeIdentifier.NodeType == UDF_NODE_TYPE_CCB);
309  // each CCB in turn points to a FCB
310  PtrRelatedFCB = PtrRelatedCCB->Fcb;
311  ASSERT(PtrRelatedFCB);
312  ASSERT((PtrRelatedFCB->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB)
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;
358  case FILE_OVERWRITE_IF:
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 
613  if(!(ShareAccess & FILE_SHARE_READ) ||
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  }
650  if(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_FLUSH2_REQUIRED) {
651 
652  UDFPrint((" perform flush\n"));
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 
672  if((ShareAccess & FILE_SHARE_READ) &&
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
682  if(!(ShareAccess & FILE_SHARE_READ)) {
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"));
713 op_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"));
1196  RC = STATUS_ACCESS_DENIED;
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)) {
1212 SuccessOpen_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 
1242 Skip_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 |
1370  UDF_FCB_DELETED |
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
1384  if(RC == STATUS_OBJECT_NAME_NOT_FOUND) {
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
1438  if(RC == STATUS_OBJECT_NAME_NOT_FOUND) {
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  }
1536  if( DirectoryOnlyRequested &&
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"));
1561 Creation_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"));
1604 Undo_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;
1725  RC = UDFCreateFile__(Vcb, IgnoreCase, &StreamName, 0, 0,
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 ...
1748  UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo),NewFileInfo->Index),
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 ...
1800  UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo),NewFileInfo->Index),
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 
1837 AlreadyOpened:
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) ||
1864  FileOnlyRequested)) {
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"));
1882  RC = STATUS_CANNOT_DELETE;
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  }
1918  if( NoBufferingSpecified &&
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 =
1940  (USHORT)UDFAttributesToNT(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo), NewFileInfo->Index),
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 ...
2043  UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo), NewFileInfo->Index),
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 ...
2050  UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo), NewFileInfo->Index),
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 
2082 try_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
2127  if(SequentialIoRequested &&
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  }
2142  if(NoBufferingSpecified) {
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 ...
2238  if (!_SEH2_AbnormalTermination()) {
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()
#define IsFileObjectReadOnly(FO)
Definition: create.cpp:19
#define UDF_VCB_IC_SHOW_BLANK_CD
Definition: udf_common.h:520
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define STATUS_EAS_NOT_SUPPORTED
Definition: ntstatus.h:315
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY
Definition: udf_common.h:481
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
BOOLEAN NTAPI MmCanFileBeTruncated(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN PLARGE_INTEGER NewFileSize)
Definition: section.c:4728
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define FILE_WRITE_EA
Definition: nt_native.h:640
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define FILE_EXISTS
Definition: nt_native.h:772
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
NTSTATUS UDFGetOpenParamsByFileId(IN PVCB Vcb, IN LONGLONG Id, OUT PUNICODE_STRING *FName, OUT BOOLEAN *CaseSens)
Definition: fileinfo.cpp:2472
#define UDFPrint(Args)
Definition: udffs.h:225
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1800
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_CCB_READ_ONLY
Definition: struct.h:170
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define NoBufferingSpecified
#define FILE_OVERWRITTEN
Definition: nt_native.h:771
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400
UNICODE_STRING ObjectName
Definition: struct.h:94
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
__inline OSSTATUS UDFFindFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN PUNICODE_STRING Name, IN PUDF_FILE_INFO DirInfo)
Definition: udf_info.h:114
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1797
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UDF_FCB_POSTED_RENAME
Definition: struct.h:317
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define FILE_ATTRIBUTE_VALID_FLAGS
Definition: nt_native.h:714
#define CollectStatistics2(VCB, Field)
Definition: env_spec.h:128
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2847
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_CREATE
Definition: from_kernel.h:55
#define UDF_FCB_DELETE_ON_CLOSE
Definition: struct.h:309
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
#define GetCurrentPID()
Definition: env_spec.h:152
#define FILE_OPENED
Definition: nt_native.h:769
#define FILE_SUPERSEDED
Definition: nt_native.h:768
#define UDF_VCB_IC_IGNORE_SEQUENTIAL_IO
Definition: udf_common.h:506
struct _UDFFileControlBlock * ParentFcb
Definition: struct.h:289
#define UDF_CCB_CASE_SENSETIVE
Definition: struct.h:159
Definition: cdstruc.h:504
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define UDF_FCB_VALID
Definition: struct.h:300
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_NOTIFY_CHANGE_FILE_NAME
#define UDF_VCB_IC_UPDATE_DIR_READ
Definition: udf_common.h:498
PUDF_DATALOC_INFO Dloc
Definition: udf_rel.h:367
OSSTATUS UDFCreateStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4888
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
PDEVICE_OBJECT TargetDeviceObject
Definition: struct.h:374
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSTATUS UDFCheckAccessRights(PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: secursup.cpp:927
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1758
#define FILE_NOTIFY_CHANGE_DIR_NAME
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
struct _UDFFileControlBlock * Fcb
Definition: struct.h:111
_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:4137
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3477
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
#define FILE_SHARE_READ
Definition: compat.h:136
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_SEH2_TRY
Definition: create.c:4226
DWORD Id
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
PtrUDFObjectName FCBName
Definition: struct.h:286
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1769
NTSTATUS MyInitUnicodeString(IN PUNICODE_STRING Str1, IN PCWSTR Str2)
#define UDF_IRP_CONTEXT_FLUSH2_REQUIRED
Definition: struct.h:393
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define UDF_VCB_IC_DIRTY_RO
Definition: udf_common.h:516
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define FO_FILE_MODIFIED
Definition: iotypes.h:1768
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
struct _UDFFileControlBlock * PtrUDFFCB
NTSTATUS UDFVerifyVcb(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb)
Definition: verfysup.cpp:37
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define FILE_DELETE_CHILD
Definition: nt_native.h:645
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
#define FALSE
Definition: types.h:117
PSE_EXPORTS SeExports
Definition: semgr.c:18
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1775
#define UDFIsADirectory(FileInfo)
Definition: udf_info.h:792
NTSTATUS UDFSetAccessRights(PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: secursup.cpp:1049
#define CcIsFileCached(FO)
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
VOID __fastcall UDFAcquireParent(IN PUDF_FILE_INFO RelatedFileInfo, IN PERESOURCE *Res1, IN PERESOURCE *Res2)
Definition: create.cpp:146
BOOLEAN __fastcall UDFIsNameValid(IN PUNICODE_STRING SearchPattern, OUT BOOLEAN *StreamOpen, OUT ULONG *SNameIndex)
Definition: namesup.cpp:92
#define FILE_ACTION_MODIFIED
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
#define TmPrint(_x_)
Definition: env_spec_w32.h:290
smooth NULL
Definition: ftsmooth.c:416
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:711
uint32 IrpContextFlags
Definition: struct.h:364
_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:1230
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
uint32 NodeType
Definition: struct.h:75
__inline VOID UDFNotifyFullReportChange(PVCB V, PUDF_FILE_INFO FI, ULONG E, ULONG A)
Definition: env_spec.h:99
OSSTATUS UDFOpenStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4965
#define FO_SEQUENTIAL_ONLY
Definition: iotypes.h:1760
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
PVOID AutoFormatCount
Definition: udf_common.h:629
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
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING StreamName
Definition: fsrtlfuncs.h:738
UDFIdentifier NodeIdentifier
Definition: struct.h:252
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
int64_t LONGLONG
Definition: typedefs.h:68
#define UDFConvertExclusiveToSharedLite(Resource)
Definition: env_spec_w32.h:665
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define UDF_CCB_VOLUME_OPEN
Definition: struct.h:166
NTSTATUS MyCloneUnicodeString(IN PUNICODE_STRING Str1, IN PUNICODE_STRING Str2)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint_di Index
Definition: udf_rel.h:392
#define STATUS_PENDING
Definition: ntstatus.h:82
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4802
#define try_return(S)
Definition: cdprocs.h:2179
NTSTATUS UDFOpenFile(PVCB Vcb, PFILE_OBJECT PtrNewFileObject, PtrUDFFCB PtrNewFcb)
Definition: create.cpp:2437
#define Vcb
Definition: cdprocs.h:1415
#define UDF_NODE_TYPE_CCB
Definition: struct.h:59
#define FILE_NOTIFY_CHANGE_STREAM_NAME
#define UDF_NTREQ_FCB_VALID
Definition: struct.h:237
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define BrutePoint()
Definition: env_spec_w32.h:504
#define UDF_CCB_DELETE_ON_CLOSE
Definition: struct.h:162
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 STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define UdfIllegalFcbAccess(Vcb, DesiredAccess)
Definition: udffs.h:203
* PFILE_OBJECT
Definition: iotypes.h:1978
struct _UDF_FILE_INFO * ParentFile
Definition: udf_rel.h:381
#define UDF_FCB_ROOT_DIRECTORY
Definition: struct.h:304
#define FO_CACHE_SUPPORTED
Definition: iotypes.h:1761
#define UDF_X_PATH_LEN
Definition: udffs.h:33
#define READ_CONTROL
Definition: nt_native.h:58
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FILE_DOES_NOT_EXIST
Definition: nt_native.h:773
#define NtReqFcb
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_FCB_DELETED
Definition: struct.h:314
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDF_FCB_DELAY_CLOSE
Definition: struct.h:313
#define UDFIsDirEmpty__(fi)
Definition: udf_info.h:1070
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define FILE_EXECUTE
Definition: nt_native.h:642
#define UDF_VCB_IC_FORCE_WRITE_THROUGH
Definition: udf_common.h:504
struct _UDFNTRequiredFCB * CommonFcb
Definition: udf_rel.h:255
#define STATUS_SHARING_PAUSED
Definition: udferr_usr.h:165
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
uint32 LinkRefCount
Definition: udf_rel.h:306
#define SYNCHRONIZE
Definition: nt_native.h:61
UDFIdentifier NodeIdentifier
Definition: struct.h:109
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
VOID UDFFlushTryBreak(IN PVCB Vcb)
Definition: flush.cpp:625
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
#define FILE_OPEN
Definition: from_kernel.h:54
NTSTATUS UDFCloseFileInfoChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: cleanup.cpp:696
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:319
LUID SeBackupPrivilege
Definition: setypes.h:1156
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define FSRTL_VOLUME_LOCK
Definition: ntifs_ex.h:441
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
VOID UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry, IN ULONG NTAttr)
_SEH2_END
Definition: create.c:4400
#define OpenByFileId
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1798
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define IgnoreCase
Definition: cdprocs.h:459
unsigned short USHORT
Definition: pedump.c:61
VOID __fastcall UDFCleanUpCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:805
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
PWCHAR __fastcall UDFDissectName(IN PWCHAR Buffer, OUT PUSHORT Length)
Definition: namesup.cpp:19
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262
OSSTATUS UDFResizeFile__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo, IN int64 NewLength)
Definition: udf_info.cpp:3468
_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 DesiredAccess
Definition: create.c:4137
#define UDF_FCB_READ_ONLY
Definition: struct.h:312
#define FileOnlyRequested
PUDF_FILE_INFO FileInfo
Definition: struct.h:257
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
_SEH2_FINALLY
Definition: create.c:4371
OSSTATUS UDFUnlinkFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN FreeSpace)
Definition: udf_info.cpp:1766
UNICODE_STRING UnicodeStrSDir
Definition: udf_common.h:617
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
ULONG UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry)
VOID __fastcall UDFCleanUpFCB(PtrUDFFCB Fcb)
Definition: misc.cpp:908
#define FILE_CREATED
Definition: nt_native.h:770
#define FILE_ACTION_ADDED
#define CollectStatistics(VCB, Field)
Definition: env_spec.h:120
#define DirectoryOnlyRequested
ULONG UDFFlushLogicalVolume(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PVCB Vcb, IN ULONG FlushFlags)
Definition: flush.cpp:506
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
#define INTEGRITY_TYPE_OPEN
Definition: ecma_167.h:357
#define UDFNotifyVolumeEvent(FileObject, EventCode)
Definition: env_spec.h:114
unsigned int ULONG
Definition: retypes.h:1
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
#define UDFStreamsSupported(Vcb)
Definition: udf_info.h:1037
#define SequentialIoRequested
#define UDFSetFileAllocMode__(fi, mode)
Definition: udf_info.h:1073
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define FO_OPENED_CASE_SENSITIVE
Definition: iotypes.h:1773
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
#define EXTENT_FLAG_ALLOC_SEQUENTIAL
Definition: udf_rel.h:77
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
#define MEM_USABS_TAG
Definition: create.cpp:24
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
OSSTATUS UDFRecordDirectory__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO DirInfo)
Definition: udf_info.cpp:3384
signed int * PLONG
Definition: retypes.h:5
VOID __fastcall UDFReleaseResFromCreate(IN PERESOURCE *PagingIoRes, IN PERESOURCE *Res1, IN PERESOURCE *Res2)
Definition: create.cpp:122
#define OpenForBackup
HRESULT Create([out]ITransactionReceiver **ppReceiver)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define UDF_FCB_WRITE_THROUGH
Definition: struct.h:305
#define FILE_ACTION_ADDED_STREAM
#define UDF_IRP_CONTEXT_FLUSH_REQUIRED
Definition: struct.h:392
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
#define FO_STREAM_FILE
Definition: iotypes.h:1763
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define DELETE
Definition: nt_native.h:57
#define FO_WRITE_THROUGH
Definition: iotypes.h:1759
#define UDF_X_NAME_LEN
Definition: udffs.h:32
#define UDF_NTREQ_FCB_MODIFIED
Definition: struct.h:236
#define UDF_VCB_FLAGS_VOLUME_LOCKED
Definition: udf_common.h:460
#define UDF_VCB_IC_UPDATE_DIR_WRITE
Definition: udf_common.h:497
PACCESS_STATE AccessState
Definition: iotypes.h:2846
#define MEM_USLOC_TAG
Definition: create.cpp:25
uint32 RefCount
Definition: udf_rel.h:399

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()
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FsRtlEnterFileSystem
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
#define FsRtlExitFileSystem
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_OPENED
Definition: nt_native.h:769
_SEH2_TRY
Definition: create.c:4226
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
#define TmPrint(_x_)
Definition: env_spec_w32.h:290
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
_SEH2_END
Definition: create.c:4400
NTSTATUS UDFCommonCreate(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: create.cpp:186
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
return STATUS_SUCCESS
Definition: btrfs.c:3014

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;
2295  BOOLEAN Linked = TRUE;
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()
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
UNICODE_STRING FName
Definition: udf_rel.h:173
VOID __fastcall UDFReleaseObjectName(PtrUDFObjectName PtrObjectName)
Definition: misc.cpp:670
#define UDFPrint(Args)
Definition: udffs.h:225
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
UNICODE_STRING ObjectName
Definition: struct.h:94
NTSTATUS UDFInitializeFCB(IN PtrUDFFCB PtrNewFcb, IN PVCB Vcb, IN PtrUDFObjectName PtrObjectName, IN ULONG Flags, IN PFILE_OBJECT FileObject)
Definition: create.cpp:2517
#define TRUE
Definition: types.h:120
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
NTSTATUS MyInitUnicodeString(IN PUNICODE_STRING Str1, IN PCWSTR Str2)
VOID UDFGetFileXTime(IN PUDF_FILE_INFO FileInfo, OUT LONGLONG *CrtTime, OUT LONGLONG *AccTime, OUT LONGLONG *AttrTime, OUT LONGLONG *ChgTime)
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
#define FALSE
Definition: types.h:117
#define UDFIsADirectory(FileInfo)
Definition: udf_info.h:792
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
NTSTATUS MyCloneUnicodeString(IN PUNICODE_STRING Str1, IN PUNICODE_STRING Str2)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS UDFOpenFile(PVCB Vcb, PFILE_OBJECT PtrNewFileObject, PtrUDFFCB PtrNewFcb)
Definition: create.cpp:2437
#define Vcb
Definition: cdprocs.h:1415
#define UDF_NTREQ_FCB_VALID
Definition: struct.h:237
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define BrutePoint()
Definition: env_spec_w32.h:504
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define UDF_FCB_ROOT_DIRECTORY
Definition: struct.h:304
#define NtReqFcb
static const WCHAR L[]
Definition: oid.c:1250
#define UDFQuadAlign(Value)
Definition: udffs.h:196
PtrUDFObjectName UDFAllocateObjectName(VOID)
Definition: misc.cpp:611
#define MEM_USOBJ_TAG
Definition: create.cpp:26
#define UDF_FCB_READ_ONLY
Definition: struct.h:312
ULONG UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry)
PtrUDFFCB UDFAllocateFCB(VOID)
Definition: misc.cpp:854
static const WCHAR Linked[]
Definition: interface.c:30
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
return STATUS_SUCCESS
Definition: btrfs.c:3014
struct _UDFNTRequiredFCB * PtrUDFNTRequiredFCB

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"));
2525  NTSTATUS status;
2526  BOOLEAN Linked = TRUE;
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 UDFInitializeResourceLite(Resource)
Definition: env_spec_w32.h:667
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1261
#define TRUE
Definition: types.h:120
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1278
LONG NTSTATUS
Definition: precomp.h:26
#define UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE
Definition: struct.h:316
#define InsertTailList(ListHead, Entry)
#define UDF_NODE_TYPE_NT_REQ_FCB
Definition: struct.h:57
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1415
#define UDFDeleteResource(Resource)
Definition: env_spec_w32.h:663
#define BrutePoint()
Definition: env_spec_w32.h:504
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static const WCHAR Linked[]
Definition: interface.c:30
struct _UDFNTRequiredFCB UDFNTRequiredFCB
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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 {
2443  NTSTATUS RC = STATUS_SUCCESS;
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 
2492 try_exit: NOTHING;
2493  } _SEH2_FINALLY {
2494  NOTHING;
2495  } _SEH2_END;
2496 
2497  return(RC);
2498 } // end UDFOpenFile()
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
PFILE_OBJECT FileObject
Definition: ntfs.h:516
#define TRUE
Definition: types.h:120
struct _FCB::@712::@715 Fcb
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define CollectStatistics2(VCB, Field)
Definition: env_spec.h:128
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
ERESOURCE CcbListResource
Definition: struct.h:287
uint32 ReferenceCount
Definition: struct.h:281
LONG NTSTATUS
Definition: precomp.h:26
PtrUDFCCB UDFAllocateCCB(VOID)
Definition: misc.cpp:707
#define InsertTailList(ListHead, Entry)
_SEH2_TRY
Definition: create.c:4226
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
uint32 NodeType
Definition: struct.h:75
UDFIdentifier NodeIdentifier
Definition: struct.h:252
#define try_return(S)
Definition: cdprocs.h:2179
#define Vcb
Definition: cdprocs.h:1415
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NtReqFcb
#define UDF_FCB_DELAY_CLOSE
Definition: struct.h:313
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:588
#define NOTHING
Definition: env_spec_w32.h:461
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
_SEH2_END
Definition: create.c:4400
LIST_ENTRY NextCCB
Definition: struct.h:268
_SEH2_FINALLY
Definition: create.c:4371
return STATUS_SUCCESS
Definition: btrfs.c:3014
signed int * PLONG
Definition: retypes.h:5
ULONG CommonRefCount
Definition: struct.h:218
PtrUDFNTRequiredFCB NTRequiredFCB
Definition: struct.h:255

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()
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
smooth NULL
Definition: ftsmooth.c:416

Referenced by UDFCommonCreate().