ReactOS  0.4.13-dev-1148-g9b75b67
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;
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"));
491  }
492 
493  // If the volume has been locked, fail the request
494  if ((Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) &&
495  (Vcb->VolumeLockPID != GetCurrentPID())) {
496  AdPrint((" Volume is locked\n"));
498  try_return(RC);
499  }
500  // We need EXCLUSIVE access to Vcb to avoid parallel calls to UDFVerifyVcb()
501  UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
502  AcquiredVcb = TRUE;
503 
504  // Disk based file systems might decide to verify the logical volume
505  // (if required and only if removable media are supported) at this time
506  RC = UDFVerifyVcb(PtrIrpContext,Vcb);
507  if(!NT_SUCCESS(RC))
508  try_return(RC);
509 
510  UDFConvertExclusiveToSharedLite(&(Vcb->VCBResource));
511 
513 
514  // We fail in the following cases for Read-Only volumes
515  // - Open a target directory.
516  // - Create a file.
517  if(
518  (
519  ((Vcb->origIntegrityType == INTEGRITY_TYPE_OPEN) &&
520  (Vcb->CompatFlags & UDF_VCB_IC_DIRTY_RO))
521 #ifndef UDF_READ_ONLY_BUILD
522  || (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)
523 #endif //UDF_READ_ONLY_BUILD
524  ) &&
525  (DeleteOnCloseSpecified ||
526  OpenTargetDirectory ||
527  (RequestedDisposition == FILE_CREATE) ||
528  (RequestedDisposition == FILE_OVERWRITE) ||
529  (RequestedDisposition == FILE_OVERWRITE_IF) ||
530  (RequestedDisposition == FILE_SUPERSEDE) ||
531  AllocationSize) ) {
532  ReturnedInformation = 0;
533  AdPrint((" Write protected or dirty\n"));
535  }
536 
537 /* if(DesiredAccess & (FILE_READ_EA | FILE_WRITE_EA)) {
538  ReturnedInformation = 0;
539  AdPrint((" EAs not supported\n"));
540  try_return(RC = STATUS_ACCESS_DENIED);
541  }*/
542 
543  // ****************
544  // If a Volume open is requested, satisfy it now
545  // ****************
546  if (!(PtrNewFileObject->FileName.Length) && (!PtrRelatedFileObject ||
547  (PtrRelatedFCB->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB))) {
548 
549  BOOLEAN UndoLock = FALSE;
550 
551  AdPrint((" Opening Volume\n"));
552  // If the supplied file name is NULL *and* either there exists
553  // no related file object *or* if a related file object was supplied
554  // but it too refers to a previously opened instance of a logical
555  // volume, this open must be for a logical volume.
556 
557  // Note: the FSD might decide to do "special" things (whatever they
558  // might be) in response to an open request for the logical volume.
559 
560  // Logical volume open requests are done primarily to get/set volume
561  // information, lock the volume, dismount the volume (using the IOCTL
562  // FSCTL_DISMOUNT_VOLUME) etc.
563 
564  // If a volume open is requested, perform checks to ensure that
565  // invalid options have not also been specified ...
566  if ((OpenTargetDirectory) || (PtrExtAttrBuffer)) {
568  }
569 
571  // a volume is not a directory
573  }
574 
575 #ifndef UDF_READ_ONLY_BUILD
576  if (DeleteOnCloseSpecified) {
577  // delete volume.... hmm
579  }
580 
581  if ((RequestedDisposition != FILE_OPEN) && (RequestedDisposition != FILE_OPEN_IF)) {
582  // cannot create a new volume, I'm afraid ...
584  }
585 #endif //UDF_READ_ONLY_BUILD
586 
587  UDFPrint((" ShareAccess %x, DesiredAccess %x\n", ShareAccess, DesiredAccess));
588 /*
589  if(!(ShareAccess & (FILE_SHARE_WRITE | FILE_SHARE_DELETE)) &&
590  !(DesiredAccess & (FILE_GENERIC_WRITE & ~SYNCHRONIZE)) &&
591  (ShareAccess & FILE_SHARE_READ) ) {
592 */
595  UDFPrint((" R/O volume open\n"));
596  } else {
597 
598  UDFPrint((" R/W volume open\n"));
599  if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) {
600  UDFPrint((" media-ro\n"));
602  }
603  }
604 
608  // do nothing
609  } else {
610 
611  if(!(ShareAccess & FILE_SHARE_READ) ||
613  // As soon as OpenVolume flushes the volume
614  // we should complete all pending requests (Close)
615 
616  UDFPrint((" set UDF_IRP_CONTEXT_FLUSH2_REQUIRED\n"));
618 
619 /*
620  UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
621  UDFReleaseResource(&(Vcb->VCBResource));
622  AcquiredVcb = FALSE;
623 
624  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
625  UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
626  }
627 #ifdef UDF_DELAYED_CLOSE
628  UDFCloseAllDelayed(Vcb);
629 #endif //UDF_DELAYED_CLOSE
630 
631  UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
632  AcquiredVcb = TRUE;
633  UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
634 */
635  }
636  }
637 
638  // If the user does not want to share write or delete then we will try
639  // and take out a lock on the volume.
641  // Do a quick check here for handles on exclusive open.
642  if ((Vcb->VCBHandleCount) &&
644  // Sharing violation
645  UDFPrint((" !FILE_SHARE_READ + open handles (%d)\n", Vcb->VCBHandleCount));
647  }
648  if(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_FLUSH2_REQUIRED) {
649 
650  UDFPrint((" perform flush\n"));
652 
653  UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
654  UDFReleaseResource(&(Vcb->VCBResource));
655  AcquiredVcb = FALSE;
656 
657  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
658  UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
659  }
660 #ifdef UDF_DELAYED_CLOSE
662 #endif //UDF_DELAYED_CLOSE
663 
664  UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
665  AcquiredVcb = TRUE;
666  UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
667 
669 
670  if((ShareAccess & FILE_SHARE_READ) &&
671  ((Vcb->VCBOpenCount - UDF_RESIDUAL_REFERENCE) != (Vcb->VCBOpenCountRO))) {
672  UDFPrint((" FILE_SHARE_READ + R/W handles: %d(%d) -> STATUS_SHARING_VIOLATION ?\n",
673  Vcb->VCBOpenCount - UDF_RESIDUAL_REFERENCE,
674  Vcb->VCBOpenCountRO));
675  /* we shall not check it here, let System do it in IoCheckShareAccess() */
676  //try_return(RC = STATUS_SHARING_VIOLATION);
677  }
678  }
679  // Lock the volume
680  if(!(ShareAccess & FILE_SHARE_READ)) {
681  UDFPrint((" set Lock\n"));
682  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_LOCKED;
683  Vcb->VolumeLockFileObject = PtrNewFileObject;
684  UndoLock = TRUE;
685  } else
687  UDFPrint((" set UDF_IRP_CONTEXT_FLUSH_REQUIRED\n"));
689  }
690  }
691 
692  PtrNewFcb = (PtrUDFFCB)Vcb;
693  ASSERT(!(PtrNewFcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE));
694 
695  RC = UDFOpenFile(Vcb, PtrNewFileObject, PtrNewFcb);
696  if (!NT_SUCCESS(RC))
697  goto op_vol_accs_dnd;
698 
699  PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
700  if(PtrNewCcb) PtrNewCcb->CCBFlags |= UDF_CCB_VOLUME_OPEN;
701  // Check _Security_
702  RC = UDFCheckAccessRights(NULL, AccessState, Vcb->RootDirFCB, PtrNewCcb, DesiredAccess, ShareAccess);
703  if (!NT_SUCCESS(RC)) {
704  AdPrint((" Access violation (Volume)\n"));
705  goto op_vol_accs_dnd;
706  }
707  // Check _ShareAccess_
708  RC = UDFCheckAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
709  if(!NT_SUCCESS(RC)) {
710  AdPrint((" Sharing violation (Volume)\n"));
711 op_vol_accs_dnd:
712  if(UndoLock) {
713  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_LOCKED;
714  Vcb->VolumeLockFileObject = NULL;
715  }
716  try_return(RC);
717  }
718 
719 // NoBufferingSpecified = TRUE; See #define above
720  RequestedOptions |= FILE_NO_INTERMEDIATE_BUFFERING;
721 
722  ReturnedInformation = FILE_OPENED;
723  UDFNotifyVolumeEvent(PtrNewFileObject, FSRTL_VOLUME_LOCK);
724  try_return(RC);
725  }
726 
727  if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
729  ReturnedInformation = 0;
730  AdPrint((" Can't open anything on blank volume ;)\n"));
732  }
733 
735  ReturnedInformation = 0;
736  AdPrint((" Illegal share access\n"));
738  }
739  // we could mount blank R/RW media in order to allow
740  // user-mode applications to get access with Write privileges
742 
743  // we should check appropriate privilege if OpenForBackup requested
744  if(OpenForBackup) {
747  }
748  }
749 
750  // The FSD might wish to implement the open-by-id option. The "id"
751  // is some unique numerical representation of the on-disk object.
752  // The caller then therefore give us this file id and the FSD
753  // should be completely capable of "opening" the object (it must
754  // exist since the caller received an id for the object from the
755  // FSD in a "query file" call ...
756 
757  // If the file has been deleted in the meantime, we'll return
758  // "not found"
759 
760  // ****************
761  // Open by FileID
762  // ****************
763  if (OpenByFileId) {
764  // perform the open ...
765  PUNICODE_STRING TmpPath;
766  LONGLONG Id;
767 
768  UDFPrint((" open by File ID\n"));
769  if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
770  ReturnedInformation = 0;
771  AdPrint((" Can't open by FileID on blank volume ;)\n"));
773  }
774 
775  if (TargetObjectName.Length != sizeof(FILE_ID)) {
776  AdPrint((" Invalid file ID\n"));
778  }
779  Id = *((FILE_ID*)(TargetObjectName.Buffer));
780  AdPrint((" Opening by ID %8.8x%8.8x\n", (ULONG)(Id>>32), (ULONG)Id));
781  if ((RequestedDisposition != FILE_OPEN) &&
782  (RequestedDisposition != FILE_OPEN_IF)) {
783  AdPrint((" Illegal disposition for ID open\n"));
785  }
786 
787  RC = UDFGetOpenParamsByFileId(Vcb, Id, &TmpPath, &IgnoreCase);
788  if(!NT_SUCCESS(RC)) {
789  AdPrint((" ID open failed\n"));
790  try_return(RC);
791  }
792  // simulate absolute path open
793 /* if(!NT_SUCCESS(RC = MyInitUnicodeString(&TargetObjectName, L"")) ||
794  !NT_SUCCESS(RC = MyAppendUnicodeStringToStringTag(&TargetObjectName, TmpPath, MEM_USABS_TAG))) {*/
795  if(!NT_SUCCESS(RC = MyCloneUnicodeString(&TargetObjectName, TmpPath))) {
796  AdPrint((" Init String failed\n"));
797  try_return(RC);
798  }
799  //ASSERT(TargetObjectName.Buffer);
800  AbsolutePathName = TargetObjectName;
801  PtrRelatedFileObject = NULL;
802  } else
803  // ****************
804  // Relative open
805  // ****************
806  // Now determine the starting point from which to begin the parsing
807  if (PtrRelatedFileObject) {
808  // We have a user supplied related file object.
809  // This implies a "relative" open i.e. relative to the directory
810  // represented by the related file object ...
811 
812  UDFPrint((" PtrRelatedFileObject %x, FCB %x\n", PtrRelatedFileObject, PtrRelatedFCB));
813  // Note: The only purpose FSD implementations ever have for
814  // the related file object is to determine whether this
815  // is a relative open or not. At all other times (including
816  // during I/O operations), this field is meaningless from
817  // the FSD's perspective.
818  if (!(PtrRelatedFCB->FCBFlags & UDF_FCB_DIRECTORY)) {
819  // we must have a directory as the "related" object
821  AdPrint((" Related object must be a directory\n"));
822  AdPrint((" Flags %x\n", PtrRelatedFCB->FCBFlags));
823  _SEH2_TRY {
824  AdPrint((" ObjName %x, ", PtrRelatedFCB->FCBName->ObjectName));
825  AdPrint((" Name %S\n", PtrRelatedFCB->FCBName->ObjectName.Buffer));
827  AdPrint((" exception when printing name\n"));
828  } _SEH2_END;
829  try_return(RC);
830  }
831 
832  // So we have a directory, ensure that the name begins with
833  // a "\" i.e. begins at the root and does *not* begin with a "\\"
834  // NOTE: This is just an example of the kind of path-name string
835  // validation that a FSD must do. Although the remainder of
836  // the code may not include such checks, any commercial
837  // FSD *must* include such checking (no one else, including
838  // the I/O Manager will perform checks on the FSD's behalf)
839  if (!(RelatedObjectName.Length) || (RelatedObjectName.Buffer[0] != L'\\')) {
840  AdPrint((" Wrong pathname (1)\n"));
842  try_return(RC);
843  }
844  // similarly, if the target file name starts with a "\", it
845  // is wrong since the target file name can no longer be absolute
846  ASSERT(TargetObjectName.Buffer || !TargetObjectName.Length);
847  if (TargetObjectName.Length && (TargetObjectName.Buffer[0] == L'\\')) {
848  AdPrint((" Wrong pathname (2)\n"));
850  try_return(RC);
851  }
852  // Create an absolute path-name. We could potentially use
853  // the absolute path-name if we cache previously opened
854  // file/directory object names.
855 /* if(!NT_SUCCESS(RC = MyInitUnicodeString(&AbsolutePathName, L"")) ||
856  !NT_SUCCESS(RC MyAppendUnicodeStringToStringTag(&AbsolutePathName, &RelatedObjectName, MEM_USABS_TAG)))*/
857  if(!NT_SUCCESS(RC = MyCloneUnicodeString(&AbsolutePathName, &RelatedObjectName)))
858  try_return(RC);
859  if(RelatedObjectName.Length &&
860  (RelatedObjectName.Buffer[ (RelatedObjectName.Length/sizeof(WCHAR)) - 1 ] != L'\\')) {
861  RC = MyAppendUnicodeToString(&AbsolutePathName, L"\\");
862  if(!NT_SUCCESS(RC)) try_return(RC);
863  }
864  if(!AbsolutePathName.Length ||
865  (AbsolutePathName.Buffer[ (AbsolutePathName.Length/sizeof(WCHAR)) - 1 ] != L'\\')) {
866  ASSERT(TargetObjectName.Buffer);
867  if(TargetObjectName.Length && TargetObjectName.Buffer[0] != L'\\') {
868  RC = MyAppendUnicodeToString(&AbsolutePathName, L"\\");
869  if(!NT_SUCCESS(RC)) try_return(RC);
870  }
871  }
872  //ASSERT(TargetObjectName.Buffer);
873  RC = MyAppendUnicodeStringToStringTag(&AbsolutePathName, &TargetObjectName, MEM_USABS_TAG);
874  if(!NT_SUCCESS(RC))
875  try_return(RC);
876 
877  } else {
878  // ****************
879  // Absolute open
880  // ****************
881  // The suplied path-name must be an absolute path-name i.e.
882  // starting at the root of the file system tree
883  UDFPrint((" Absolute open\n"));
884  ASSERT(TargetObjectName.Buffer);
885  if (!TargetObjectName.Length || TargetObjectName.Buffer[0] != L'\\') {
886  AdPrint((" Wrong target name (1)\n"));
888  }
889 /* if(!NT_SUCCESS(RC = MyInitUnicodeString(&AbsolutePathName, L"")) ||
890  !NT_SUCCESS(RC = MyAppendUnicodeStringToStringTag(&AbsolutePathName, &TargetObjectName, MEM_USABS_TAG)))*/
891  ASSERT(TargetObjectName.Buffer);
892  if(!NT_SUCCESS(RC = MyCloneUnicodeString(&AbsolutePathName, &TargetObjectName)))
893  try_return(RC);
894  }
895  // Win 32 protection :)
896  if ((AbsolutePathName.Length >= sizeof(WCHAR)*2) &&
897  (AbsolutePathName.Buffer[1] == L'\\') &&
898  (AbsolutePathName.Buffer[0] == L'\\')) {
899 
900  // If there are still two beginning backslashes, the name is bogus.
901  if ((AbsolutePathName.Length > 2*sizeof(WCHAR)) &&
902  (AbsolutePathName.Buffer[2] == L'\\')) {
903  AdPrint((" Wrong target name (2)\n"));
905  }
906  // Slide the name down in the buffer.
907  RtlMoveMemory( AbsolutePathName.Buffer,
908  AbsolutePathName.Buffer + 1,
909  AbsolutePathName.Length ); // .Length includes
910  // NULL-terminator
911  AbsolutePathName.Length -= sizeof(WCHAR);
912  }
913  if ( (AbsolutePathName.Length > sizeof(WCHAR) ) &&
914  (AbsolutePathName.Buffer[ (AbsolutePathName.Length/sizeof(WCHAR)) - 1 ] == L'\\') ) {
915 
916  AbsolutePathName.Length -= sizeof(WCHAR);
917  }
918  // TERMINATOR (2) ;)
919  AbsolutePathName.Buffer[AbsolutePathName.Length/sizeof(WCHAR)] = 0;
920 
921  // Sometimes W2000 decides to duplicate handle of
922  // already opened File/Dir. In this case it sends us
923  // RelatedFileObject & specifies zero-filled RelativePath
924  if(!TargetObjectName.Length) {
925  TargetObjectName = AbsolutePathName;
926  OpenExisting = TRUE;
927  }
928  //ASSERT(TargetObjectName.Buffer);
929 
930  // ****************
931  // First, check if the caller simply wishes to open the Root
932  // of the file system tree.
933  // ****************
934  if (AbsolutePathName.Length == sizeof(WCHAR)) {
935  AdPrint((" Opening RootDir\n"));
936  // this is an open of the root directory, ensure that the caller
937  // has not requested a file only
938  if (FileOnlyRequested || (RequestedDisposition == FILE_SUPERSEDE) ||
939  (RequestedDisposition == FILE_OVERWRITE) ||
940  (RequestedDisposition == FILE_OVERWRITE_IF)) {
941  AdPrint((" Can't overwrite RootDir\n"));
943  try_return(RC);
944  }
945 
946 #if 0
947  CollectStatistics(Vcb, MetaDataReads);
948 #endif
949 
950  if (DeleteOnCloseSpecified) {
951  // delete RootDir.... rather strange idea... I dislike it
952  AdPrint((" Can't delete RootDir\n"));
954  }
955 
956  PtrNewFcb = Vcb->RootDirFCB;
957  RC = UDFOpenFile(Vcb, PtrNewFileObject, PtrNewFcb);
958  if(!NT_SUCCESS(RC)) try_return(RC);
959 // DbgPrint("UDF: Open/Create RootDir : ReferenceCount %x\n",PtrNewFcb->ReferenceCount);
960  UDFReferenceFile__(PtrNewFcb->FileInfo);
961  PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
962  TreeLength = 1;
963 
964  RC = UDFCheckAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
965  if(!NT_SUCCESS(RC)) {
966  AdPrint((" Access/Sharing violation (RootDir)\n"));
967  try_return(RC);
968  }
969 
970  ReturnedInformation = FILE_OPENED;
971 
972  try_return(RC);
973  } // end of OpenRootDir
974 
975  _SEH2_TRY {
976  AdPrint((" Opening file %ws %8.8x\n",AbsolutePathName.Buffer, PtrNewFileObject));
978  AdPrint((" Exception when printing FN\n"));
979  } _SEH2_END;
980  // ****************
981  // Check if we have DuplicateHandle (or Reopen) request
982  // ****************
983  if(OpenExisting) {
984 
985 // BrutePoint();
986  // We don't handle OpenTargetDirectory in this case
987  if(OpenTargetDirectory)
989 
990  // Init environment to simulate normal open procedure behavior
991 /* if(!NT_SUCCESS(RC = MyInitUnicodeString(&LocalPath, L"")) ||
992  !NT_SUCCESS(RC = MyAppendUnicodeStringToStringTag(&LocalPath, &TargetObjectName, MEM_USLOC_TAG)))*/
993  ASSERT(TargetObjectName.Buffer);
994  if(!NT_SUCCESS(RC = MyCloneUnicodeString(&LocalPath, &TargetObjectName)))
995  try_return(RC);
996 
997  ASSERT(PtrRelatedFCB);
998  RelatedFileInfo = PtrRelatedFCB->FileInfo;
999 
1000  RC = STATUS_SUCCESS;
1001  NewFileInfo =
1002  LastGoodFileInfo = RelatedFileInfo;
1003 
1004  RelatedFileInfo =
1005  OldRelatedFileInfo = RelatedFileInfo->ParentFile;
1006  PtrRelatedFCB = PtrRelatedFCB->ParentFcb;
1007  // prevent releasing parent structures
1008  UDFAcquireParent(RelatedFileInfo, &Res1, &Res2);
1009  TreeLength++;
1010 
1011  if(Res1) UDFReleaseResource(Res1);
1012  if(Res2) UDFReleaseResource(Res2);
1013 
1014  UDF_CHECK_PAGING_IO_RESOURCE(RelatedFileInfo->Fcb->NTRequiredFCB);
1015  UDFAcquireResourceExclusive(Res2 = &(RelatedFileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1016  PtrNewFcb = NewFileInfo->Fcb;
1017 
1018  UDF_CHECK_PAGING_IO_RESOURCE(PtrNewFcb->NTRequiredFCB);
1019  UDFAcquireResourceExclusive(Res1 = &(PtrNewFcb->NTRequiredFCB->MainResource),TRUE);
1020  UDFReferenceFile__(NewFileInfo);
1021  TreeLength++;
1022 
1023  goto AlreadyOpened;
1024  }
1025 
1026  if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
1027  ReturnedInformation = 0;
1028  AdPrint((" Can't open File on blank volume ;)\n"));
1030  }
1031 
1032  //AdPrint((" Opening file %ws %8.8x\n",AbsolutePathName.Buffer, PtrNewFileObject));
1033 
1034  if(AbsolutePathName.Length > UDF_X_PATH_LEN*sizeof(WCHAR)) {
1036  }
1037 
1038  // validate path specified
1039  // (sometimes we can see here very strange characters ;)
1040  if(!UDFIsNameValid(&AbsolutePathName, &StreamOpen, &SNameIndex)) {
1041  AdPrint((" Absolute path is not valid\n"));
1043  }
1044  if(StreamOpen && !UDFStreamsSupported(Vcb)) {
1046  }
1047 
1048  RC = MyInitUnicodeString(&LocalPath, L"");
1049  if(!NT_SUCCESS(RC))
1050  try_return(RC);
1051  if (PtrRelatedFileObject) {
1052  // Our "start directory" is the one identified
1053  // by the related file object
1054  RelatedFileInfo = PtrRelatedFCB->FileInfo;
1055  if(RelatedFileInfo != Vcb->RootDirFCB->FileInfo) {
1056  RC = MyAppendUnicodeStringToStringTag(&LocalPath, &(PtrRelatedFCB->FCBName->ObjectName), MEM_USLOC_TAG);
1057  if(!NT_SUCCESS(RC))
1058  try_return(RC);
1059  }
1060  if(TargetObjectName.Buffer != AbsolutePathName.Buffer) {
1061  ASSERT(TargetObjectName.Buffer);
1062  if(!NT_SUCCESS(RC = MyCloneUnicodeString(&TailName, &TargetObjectName))) {
1063  AdPrint((" Init String 'TargetObjectName' failed\n"));
1064  try_return(RC);
1065  }
1066  TailNameBuffer = TailName.Buffer;
1067  } else {
1068  TailName = AbsolutePathName;
1069  }
1070  } else {
1071  // Start at the root of the file system
1072  RelatedFileInfo = Vcb->RootDirFCB->FileInfo;
1073  TailName = AbsolutePathName;
1074  }
1075 
1076  if(StreamOpen) {
1077  StreamName = AbsolutePathName;
1078  StreamName.Buffer += SNameIndex;
1079  StreamName.Length -= (USHORT)SNameIndex*sizeof(WCHAR);
1080  // if StreamOpen specified & stream name starts with NULL character
1081  // we should create Stream Dir at first
1082  TailName.Length -= (AbsolutePathName.Length - (USHORT)SNameIndex*sizeof(WCHAR));
1083  AbsolutePathName.Length = (USHORT)SNameIndex*sizeof(WCHAR);
1084  }
1085  CurName.MaximumLength = TailName.MaximumLength;
1086 
1087  RC = STATUS_SUCCESS;
1088  LastGoodName.Length = 0;
1089  LastGoodFileInfo = RelatedFileInfo;
1090  // reference RelatedObject to prevent releasing parent structures
1091  UDFAcquireParent(RelatedFileInfo, &Res1, &Res2);
1092  TreeLength++;
1093 
1094  // go into a loop parsing the supplied name
1095 
1096  // Note that we may have to "open" intermediate directory objects
1097  // while traversing the path. We should __try to reuse existing code
1098  // whenever possible therefore we should consider using a common
1099  // open routine regardless of whether the open is on behalf of the
1100  // caller or an intermediate (internal) open performed by the driver.
1101 
1102  // ****************
1103  // now we'll parse path to desired file
1104  // ****************
1105 
1106  while (TRUE) {
1107 
1108  // remember last 'good' ('good' means NO ERRORS before) path tail
1109  if(NT_SUCCESS(RC)) {
1110  LastGoodTail = TailName;
1111  while(LastGoodTail.Buffer[0] == L'\\') {
1112  LastGoodTail.Buffer++;
1113  LastGoodTail.Length -= sizeof(WCHAR);
1114  }
1115  }
1116  // get next path part...
1117  TmpBuffer = TailName.Buffer;
1118  TailName.Buffer = UDFDissectName(TailName.Buffer,&(CurName.Length) );
1119  TailName.Length -= (USHORT)((ULONG_PTR)(TailName.Buffer) - (ULONG_PTR)TmpBuffer);
1120  CurName.Buffer = TailName.Buffer - CurName.Length;
1121  CurName.Length *= sizeof(WCHAR);
1122  CurName.MaximumLength = CurName.Length + sizeof(WCHAR);
1123  // check if we have already opened the component before last one
1124  // in this case OpenTargetDir request will be served in a special
1125  // way...
1126  if(OpenTargetDirectory && NT_SUCCESS(RC) && !TailName.Length) {
1127  // check if we should open SDir..
1128  if(!StreamOpen ||
1129  (TailName.Buffer[0]!=L':')) {
1130  // no, we should not. Continue with OpenTargetDir
1131  break;
1132  }
1133  }
1134 
1135  if( CurName.Length &&
1136  (NT_SUCCESS(RC) || !StreamOpen)) {
1137  // ...wow! non-zero! try to open!
1138  if(!NT_SUCCESS(RC)) {
1139  AdPrint((" Error opening path component\n"));
1140  // we haven't reached last name part... hm..
1141  // probably, the path specified is invalid..
1142  // or we had a hard error... What else can we do ?
1143  // Only say ..CK OFF !!!!
1146  try_return(RC);
1147  }
1148 
1149  ASSERT_REF(RelatedFileInfo->Fcb->ReferenceCount >= RelatedFileInfo->RefCount);
1150 
1151  if(RelatedFileInfo && (TreeLength>1)) {
1152  // it was an internal Open operation. Thus, assume
1153  // RelatedFileInfo's Fcb to be valid
1154  RelatedFileInfo->Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
1155  RelatedFileInfo->Fcb->FCBFlags |= UDF_FCB_VALID;
1156  }
1157  // check path fragment size
1158  if(CurName.Length > UDF_X_NAME_LEN * sizeof(WCHAR)) {
1159  AdPrint((" Path component is too long\n"));
1161  }
1162  // ...and now release previously acquired objects,
1163  if(Res1) UDFReleaseResource(Res1);
1164  if(Res2) {
1165  UDFReleaseResource(Res2);
1166  Res2 = NULL;
1167  }
1168  // acquire new _parent_ directory & try to open what
1169  // we want.
1170 
1171  UDF_CHECK_PAGING_IO_RESOURCE(RelatedFileInfo->Fcb->NTRequiredFCB);
1172  UDFAcquireResourceExclusive(Res1 = &(RelatedFileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1173 
1174  // check traverse rights
1175  RC = UDFCheckAccessRights(NULL, NULL, RelatedFileInfo->Fcb, PtrRelatedCCB, FILE_TRAVERSE, 0);
1176  if(!NT_SUCCESS(RC)) {
1177  NewFileInfo = NULL;
1178  AdPrint((" Traverse check failed\n"));
1179  goto Skip_open_attempt;
1180  }
1181  // check if we should open normal File/Dir or SDir
1182  if(CurName.Buffer[0] != ':') {
1183  // standard open, nothing interesting....
1184  RC = UDFOpenFile__(Vcb,
1185  IgnoreCase,TRUE,&CurName,
1186  RelatedFileInfo,&NewFileInfo,NULL);
1187  if(RC == STATUS_FILE_DELETED) {
1188  // file has gone, but system still remembers it...
1189  NewFileInfo = NULL;
1190  AdPrint((" File deleted\n"));
1191  RC = STATUS_ACCESS_DENIED;
1192 #ifdef UDF_DBG
1193  } else
1194  if(RC == STATUS_NOT_A_DIRECTORY) {
1195  AdPrint((" Not a directory\n"));
1196 #endif // UDF_DBG
1197  } else
1198  if(RC == STATUS_SHARING_PAUSED) {
1199  AdPrint((" Dloc is being initialized\n"));
1200  BrutePoint();
1202  }
1203  } else {
1204  // And here we should open Stream Dir (if any, of cource)
1205  RC = UDFOpenStreamDir__(Vcb, RelatedFileInfo, &NewFileInfo);
1206  if(NT_SUCCESS(RC)) {
1207 SuccessOpen_SDir:
1208  // this indicates that we needn't Stream Dir creation
1209  StreamExists = TRUE;
1210  StreamName.Buffer++;
1211  StreamName.Length-=sizeof(WCHAR);
1212  // update TailName
1213  TailName = StreamName;
1214  } else
1215  if(RC == STATUS_NOT_FOUND) {
1216 #ifndef UDF_READ_ONLY_BUILD
1217  // Stream Dir doesn't exist, but caller wants it to be
1218  // created. Lets try to help him...
1219  if((RequestedDisposition == FILE_CREATE) ||
1220  (RequestedDisposition == FILE_OPEN_IF) ||
1221  (RequestedDisposition == FILE_OVERWRITE_IF) ||
1222  OpenTargetDirectory ) {
1223  RC = UDFCreateStreamDir__(Vcb, RelatedFileInfo, &NewFileInfo);
1224  if(NT_SUCCESS(RC))
1225  goto SuccessOpen_SDir;
1226  }
1227 #endif //UDF_READ_ONLY_BUILD
1228  }
1229 /* } else {
1230  AdPrint((" File deleted (2)\n"));
1231  RC = STATUS_ACCESS_DENIED;*/
1232  }
1233 #if 0
1234  CollectStatistics(Vcb, MetaDataReads);
1235 #endif
1236 
1237 Skip_open_attempt:
1238 
1239  // check if we have successfully opened path component
1240  if(NT_SUCCESS(RC)) {
1241  // Yesss !!!
1242  if (!(PtrNewFcb = NewFileInfo->Fcb)) {
1243  // It is a first open operation
1244  // Allocate new FCB
1245  // Here we set FileObject pointer to NULL to avoid
1246  // new CCB allocation
1247  RC = UDFFirstOpenFile(Vcb,
1248  NULL, &PtrNewFcb, RelatedFileInfo, NewFileInfo,
1249  &LocalPath, &CurName);
1250 
1251  if(!NT_SUCCESS(RC)) {
1252  BrutePoint();
1253  AdPrint((" Can't perform FirstOpen\n"));
1254  UDFCloseFile__(Vcb, NewFileInfo);
1255  if(PtrNewFcb) UDFCleanUpFCB(PtrNewFcb);
1256  PtrNewFcb = NULL;
1257  NewFileInfo->Fcb = NULL;
1258  if(UDFCleanUpFile__(Vcb, NewFileInfo)) {
1259  MyFreePool__(NewFileInfo);
1260  NewFileInfo = NULL;
1261  }
1262  try_return(RC);
1263  }
1264  } else {
1265  // It is not a first open operation
1266  // Validate Fcb. It is possible to get
1267  // not completly initialized Fcb here.
1268  if(!(PtrNewFcb->FCBFlags & UDF_FCB_VALID)) {
1269  BrutePoint();
1270  AdPrint((" Fcb not valid\n"));
1271  UDFCloseFile__(Vcb, NewFileInfo);
1272  PtrNewFcb = NULL;
1273  if(UDFCleanUpFile__(Vcb, NewFileInfo)) {
1274  MyFreePool__(NewFileInfo);
1275  NewFileInfo = NULL;
1276  }
1278  }
1279  }
1280  // Acquire newly opened File...
1281  Res2 = Res1;
1282  UDF_CHECK_PAGING_IO_RESOURCE(NewFileInfo->Fcb->NTRequiredFCB);
1283  UDFAcquireResourceExclusive(Res1 = &(NewFileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1284  // ...and reference it
1285  UDFInterlockedIncrement((PLONG)&(PtrNewFcb->ReferenceCount));
1286  UDFInterlockedIncrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1287 
1288  ASSERT_REF(PtrNewFcb->ReferenceCount >= NewFileInfo->RefCount);
1289  // update unwind information
1290  LastGoodFileInfo = NewFileInfo;
1291  LastGoodName = CurName;
1292  TreeLength++;
1293  // update current path
1294  if(!StreamOpen ||
1295  ((CurName.Buffer[0] != L':') &&
1296  (!LocalPath.Length || (LocalPath.Buffer[LocalPath.Length/sizeof(WCHAR)-1] != L':'))) ) {
1297  // we should not insert '\' before or after ':'
1298  ASSERT(!LocalPath.Length ||
1299  (LocalPath.Buffer[LocalPath.Length/2-1] != L'\\'));
1300  RC = MyAppendUnicodeToString(&LocalPath, L"\\");
1301  if(!NT_SUCCESS(RC)) try_return(RC);
1302  }
1303  RC = MyAppendUnicodeStringToStringTag(&LocalPath, &CurName, MEM_USLOC_TAG);
1304  if(!NT_SUCCESS(RC))
1305  try_return(RC);
1306 // DbgPrint("UDF: Open/Create File %ws : ReferenceCount %x\n",CurName.Buffer,PtrNewFcb->ReferenceCount);
1307  } else {
1308  AdPrint((" Can't open file\n"));
1309  // We have failed durring last Open attempt
1310  // Roll back to last good state
1312  // Cleanup FileInfo if any
1313  if(NewFileInfo) {
1314  PtrNewFcb = NewFileInfo->Fcb;
1315  // acquire appropriate resource if possible
1316  if(PtrNewFcb &&
1317  PtrNewFcb->NTRequiredFCB) {
1318  NtReqFcb = PtrNewFcb->NTRequiredFCB;
1319  Res2 = Res1;
1321  UDFAcquireResourceExclusive(Res1 = &(NtReqFcb->MainResource),TRUE);
1322  }
1323  // cleanup pointer to Fcb in FileInfo to allow
1324  // UDF_INFO package release FileInfo if there are
1325  // no more references
1326  if(PtrNewFcb &&
1327  !PtrNewFcb->ReferenceCount &&
1328  !PtrNewFcb->OpenHandleCount) {
1329  NewFileInfo->Fcb = NULL;
1330  }
1331  // cleanup pointer to CommonFcb in Dloc to allow
1332  // UDF_INFO package release Dloc if there are
1333  // no more references
1334  if(NewFileInfo->Dloc &&
1335  !NewFileInfo->Dloc->LinkRefCount &&
1336  (!PtrNewFcb || !PtrNewFcb->ReferenceCount)) {
1337  NewFileInfo->Dloc->CommonFcb = NULL;
1338  }
1339  // try to release FileInfo
1340  if(UDFCleanUpFile__(Vcb, NewFileInfo)) {
1341  ASSERT(!PtrNewFcb);
1342  if(PtrNewFcb) {
1343  BrutePoint();
1344  UDFCleanUpFCB(PtrNewFcb);
1345  }
1346  MyFreePool__(NewFileInfo);
1347  } else {
1348  // if we can't release FileInfo
1349  // restore pointers to Fcb & CommonFcb in
1350  // FileInfo & Dloc
1351  NewFileInfo->Fcb = PtrNewFcb;
1352  if(NtReqFcb)
1353  NewFileInfo->Dloc->CommonFcb = NtReqFcb;
1354  }
1355  // forget about last FileInfo & Fcb,
1356  // further unwind staff needs only last good
1357  // structures
1358  PtrNewFcb = NULL;
1359  NewFileInfo = NULL;
1360  }
1361  }
1362 
1363  // should return error if 'delete in progress'
1364  if(LastGoodFileInfo->Fcb->FCBFlags & (UDF_FCB_DELETE_ON_CLOSE |
1365  UDF_FCB_DELETED |
1367  AdPrint((" Return DeletePending (no err)\n"));
1369  }
1370  // update last good state information...
1371  OldRelatedFileInfo = RelatedFileInfo;
1372  RelatedFileInfo = NewFileInfo;
1373  // ...and go to the next open cycle
1374  } else {
1375  // ************
1376  if(StreamOpen && (RC == STATUS_NOT_FOUND))
1377  // handle SDir return code
1379  if(RC == STATUS_OBJECT_NAME_NOT_FOUND) {
1380  // good path, but no such file.... Amen
1381  // break open loop and continue with Create
1382  break;
1383  }
1384  if (!NT_SUCCESS(RC)) {
1385  // Hard error or damaged data structures ...
1386 #ifdef UDF_DBG
1387  if((RC != STATUS_OBJECT_PATH_NOT_FOUND) &&
1388  (RC != STATUS_ACCESS_DENIED) &&
1389  (RC != STATUS_NOT_A_DIRECTORY)) {
1390  AdPrint((" Hard error or damaged data structures\n"));
1391  }
1392 #endif // UDF_DBG
1393  // ... and exit with error
1394  try_return(RC);
1395  }
1396  // discard changes for last successfully opened file
1397  UDFInterlockedDecrement((PLONG)&(PtrNewFcb->ReferenceCount));
1398  UDFInterlockedDecrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1399  RC = STATUS_SUCCESS;
1400  ASSERT(!OpenTargetDirectory);
1401  // break open loop and continue with Open
1402  // (Create will be skipped)
1403  break;
1404  }
1405  } // end of while(TRUE)
1406 
1407  // ****************
1408  // If "open target directory" was specified
1409  // ****************
1410  if(OpenTargetDirectory) {
1411 
1412  if(!UDFIsADirectory(LastGoodFileInfo)) {
1413  AdPrint((" Not a directory (2)\n"));
1415  }
1416  if(!NT_SUCCESS(RC) ||
1417  TailName.Length) {
1418  AdPrint((" Target name should not contain (back)slashes\n"));
1419  NewFileInfo = NULL;
1421  }
1422 
1423  NewFileInfo = LastGoodFileInfo;
1424  RtlCopyUnicodeString(&(PtrNewFileObject->FileName), &CurName);
1425 
1426  // now we have to check if last component exists...
1428  &CurName, RelatedFileInfo))) {
1429  // file exists, set this information in the Information field
1430  ReturnedInformation = FILE_EXISTS;
1431  AdPrint((" Open Target: FILE_EXISTS\n"));
1432  } else
1433  if(RC == STATUS_OBJECT_NAME_NOT_FOUND) {
1434 #ifdef UDF_DBG
1435  // check name. If there are '\\'s in TailName, some
1436  // directories in path specified do not exist
1437  for(TmpBuffer = LastGoodTail.Buffer; *TmpBuffer; TmpBuffer++) {
1438  if((*TmpBuffer) == L'\\') {
1439  ASSERT(FALSE);
1440  AdPrint((" Target name should not contain (back)slashes\n"));
1442  }
1443  }
1444 #endif // UDF_DBG
1445  // Tell the I/O Manager that file does not exit
1446  ReturnedInformation = FILE_DOES_NOT_EXIST;
1447  AdPrint((" Open Target: FILE_DOES_NOT_EXIST\n"));
1448  RC = STATUS_SUCCESS; // is already set here
1449  } else {
1450  AdPrint((" Open Target: unexpected error\n"));
1451  NewFileInfo = NULL;
1453  }
1454 
1455 // RC = STATUS_SUCCESS; // is already set here
1456 
1457  // Update the file object FsContext and FsContext2 fields
1458  // to reflect the fact that the parent directory of the
1459  // target has been opened
1460  PtrNewFcb = NewFileInfo->Fcb;
1461  UDFInterlockedDecrement((PLONG)&(PtrNewFcb->ReferenceCount));
1462  UDFInterlockedDecrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1463  RC = UDFOpenFile(Vcb, PtrNewFileObject, PtrNewFcb);
1464  ASSERT_REF(PtrNewFcb->ReferenceCount >= NewFileInfo->RefCount);
1465  if (!NT_SUCCESS(RC)) {
1466  AdPrint((" Can't perform OpenFile operation for target\n"));
1467  try_return(RC);
1468  }
1469  PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
1470 
1471  ASSERT(Res1);
1472  RC = UDFCheckAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
1473  if(!NT_SUCCESS(RC)) {
1474  AdPrint((" Access/Share access check failed (Open Target)\n"));
1475  }
1476 
1477  try_return(RC);
1478  }
1479 
1480  // ****************
1481  // should we CREATE a new file ?
1482  // ****************
1483  if (!NT_SUCCESS(RC)) {
1484  if (RC == STATUS_OBJECT_NAME_NOT_FOUND ||
1486  if( ((RequestedDisposition == FILE_OPEN) ||
1487  (RequestedDisposition == FILE_OVERWRITE)) /*&&
1488  (!StreamOpen || !StreamExists)*/ ){
1489  ReturnedInformation = FILE_DOES_NOT_EXIST;
1490  AdPrint((" File doesn't exist\n"));
1491  try_return(RC);
1492  }
1493  } else {
1494  // Any other operation return STATUS_ACCESS_DENIED.
1495  AdPrint((" Can't create due to unexpected error\n"));
1496  try_return(RC);
1497  }
1498  // Object was not found, create if requested
1499  if ((RequestedDisposition != FILE_CREATE) && (RequestedDisposition != FILE_OPEN_IF) &&
1500  (RequestedDisposition != FILE_OVERWRITE_IF) && (RequestedDisposition != FILE_SUPERSEDE)) {
1501  AdPrint((" File doesn't exist (2)\n"));
1502  try_return(RC);
1503  }
1504  // Check Volume ReadOnly attr
1505 #ifndef UDF_READ_ONLY_BUILD
1506  if((Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)) {
1507 #endif //UDF_READ_ONLY_BUILD
1508  ReturnedInformation = 0;
1509  AdPrint((" Write protected\n"));
1511 #ifndef UDF_READ_ONLY_BUILD
1512  }
1513  // Check r/o + delete on close
1514  if(DeleteOnCloseSpecified &&
1516  AdPrint((" Can't create r/o file marked for deletion\n"));
1518  }
1519 
1520  // Create a new file/directory here ...
1521  if(StreamOpen)
1522  StreamName.Buffer[StreamName.Length/sizeof(WCHAR)] = 0;
1523  for(TmpBuffer = LastGoodTail.Buffer; *TmpBuffer; TmpBuffer++) {
1524  if((*TmpBuffer) == L'\\') {
1525  AdPrint((" Target name should not contain (back)slashes\n"));
1527  }
1528  }
1529  if( DirectoryOnlyRequested &&
1530  ((IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_TEMPORARY) ||
1531  StreamOpen || FALSE)) {
1532  AdPrint((" Creation of _temporary_ directory not permited\n"));
1534  }
1535  // check access rights
1536  ASSERT(Res1);
1537  RC = UDFCheckAccessRights(NULL, NULL, OldRelatedFileInfo->Fcb, PtrRelatedCCB, DirectoryOnlyRequested ? FILE_ADD_SUBDIRECTORY : FILE_ADD_FILE, 0);
1538  if(!NT_SUCCESS(RC)) {
1539  AdPrint((" Creation of File/Dir not permitted\n"));
1540  try_return(RC);
1541  }
1542  // Note that a FCB structure will be allocated at this time
1543  // and so will a CCB structure. Assume that these are called
1544  // PtrNewFcb and PtrNewCcb respectively.
1545  // Further, note that since the file is being created, no other
1546  // thread can have the file stream open at this time.
1547  RelatedFileInfo = OldRelatedFileInfo;
1548 
1549  RC = UDFCreateFile__(Vcb, IgnoreCase, &LastGoodTail, 0, 0,
1550  Vcb->UseExtendedFE || (StreamOpen && !StreamExists),
1551  (RequestedDisposition == FILE_CREATE), RelatedFileInfo, &NewFileInfo);
1552  if(!NT_SUCCESS(RC)) {
1553  AdPrint((" Creation error\n"));
1554 Creation_Err_1:
1555  if(NewFileInfo) {
1556  PtrNewFcb = NewFileInfo->Fcb;
1557  ASSERT(!PtrNewFcb);
1558  if(PtrNewFcb &&
1559  !PtrNewFcb->ReferenceCount &&
1560  !PtrNewFcb->OpenHandleCount) {
1561  NewFileInfo->Fcb = NULL;
1562  }
1563  if(NewFileInfo->Dloc &&
1564  !NewFileInfo->Dloc->LinkRefCount) {
1565  NewFileInfo->Dloc->CommonFcb = NULL;
1566  }
1567  if(UDFCleanUpFile__(Vcb, NewFileInfo)) {
1568  if(PtrNewFcb) {
1569  BrutePoint();
1570  UDFCleanUpFCB(PtrNewFcb);
1571  }
1572  MyFreePool__(NewFileInfo);
1573  PtrNewFcb = PtrNewFcb;
1574  } else {
1575  NewFileInfo->Fcb = PtrNewFcb;
1576  }
1577  PtrNewFcb = NULL;
1578  }
1579  try_return(RC);
1580  }
1581  // Update parent object
1582  if((Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_WRITE) &&
1583  PtrRelatedFCB &&
1584  PtrRelatedFileObject &&
1585  (PtrRelatedFCB->FileInfo == NewFileInfo->ParentFile)) {
1586  PtrRelatedFileObject->Flags |= (FO_FILE_MODIFIED | FO_FILE_SIZE_CHANGED);
1587  }
1588 #if 0
1589  CollectStatistics(Vcb, MetaDataWrites);
1590 #endif
1591 
1593  // user wants the directory to be created
1594  RC = UDFRecordDirectory__(Vcb, NewFileInfo);
1595  if(!NT_SUCCESS(RC)) {
1596  AdPrint((" Can't transform to directory\n"));
1597 Undo_Create_1:
1598  if((RC != STATUS_FILE_IS_A_DIRECTORY) &&
1599  (RC != STATUS_NOT_A_DIRECTORY) &&
1600  (RC != STATUS_ACCESS_DENIED)) {
1601  UDFFlushFile__(Vcb, NewFileInfo);
1602  UDFUnlinkFile__(Vcb, NewFileInfo, TRUE);
1603  }
1604  UDFCloseFile__(Vcb, NewFileInfo);
1605  BrutePoint();
1606  goto Creation_Err_1;
1607  }
1608 #if 0
1609  CollectStatistics(Vcb, MetaDataWrites);
1610 #endif
1611  } else if(AllocationSize) {
1612  // set initial file size
1613 /* if(!NT_SUCCESS(RC = UDFResizeFile__(Vcb, NewFileInfo, AllocationSize))) {
1614  AdPrint((" Can't set initial file size\n"));
1615  goto Undo_Create_1;
1616  }
1617  CollectStatistics(Vcb, MetaDataWrites);*/
1618  }
1619 
1620  if(StreamOpen && !StreamExists) {
1621 
1622  // PHASE 0
1623 
1624  // Open the newly created object (file)
1625  if (!(PtrNewFcb = NewFileInfo->Fcb)) {
1626  // It is a first open operation
1627  // Allocate new FCB
1628  // Here we set FileObject pointer to NULL to avoid
1629  // new CCB allocation
1630  RC = UDFFirstOpenFile(Vcb,
1631  NULL, &PtrNewFcb, RelatedFileInfo, NewFileInfo,
1632  &LocalPath, &LastGoodTail);
1633  if(!NT_SUCCESS(RC)) {
1634  AdPrint((" Can't perform FirstOpenFile operation for file to contain stream\n"));
1635  BrutePoint();
1636  UDFCleanUpFCB(NewFileInfo->Fcb);
1637  NewFileInfo->Fcb = NULL;
1638  goto Creation_Err_1;
1639  }
1640  } else {
1641  BrutePoint();
1642  }
1643 
1644  // Update unwind information
1645  TreeLength++;
1646  LastGoodFileInfo = NewFileInfo;
1647  // update FCB tree
1648  RC = MyAppendUnicodeToString(&LocalPath, L"\\");
1649  if(!NT_SUCCESS(RC)) try_return(RC);
1650  RC = MyAppendUnicodeStringToStringTag(&LocalPath, &LastGoodTail, MEM_USLOC_TAG);
1651  if(!NT_SUCCESS(RC))
1652  goto Creation_Err_1;
1653  UDFInterlockedIncrement((PLONG)&(PtrNewFcb->ReferenceCount));
1654  UDFInterlockedIncrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1655  ASSERT_REF(PtrNewFcb->ReferenceCount >= NewFileInfo->RefCount);
1656  PtrNewFcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
1657  PtrNewFcb->FCBFlags |= UDF_FCB_VALID;
1658 
1659  UDFNotifyFullReportChange( Vcb, NewFileInfo,
1662 
1663  // PHASE 1
1664 
1665  // we need to create Stream Dir
1666  RelatedFileInfo = NewFileInfo;
1667  RC = UDFCreateStreamDir__(Vcb, RelatedFileInfo, &NewFileInfo);
1668  if(!NT_SUCCESS(RC)) {
1669  AdPrint((" Can't create SDir\n"));
1670  BrutePoint();
1671  goto Creation_Err_1;
1672  }
1673 #if 0
1674  CollectStatistics(Vcb, MetaDataWrites);
1675 #endif
1676 
1677  // normalize stream name
1678  StreamName.Buffer++;
1679  StreamName.Length-=sizeof(WCHAR);
1680  // Open the newly created object
1681  if (!(PtrNewFcb = NewFileInfo->Fcb)) {
1682  // It is a first open operation
1683  // Allocate new FCB
1684  // Here we set FileObject pointer to NULL to avoid
1685  // new CCB allocation
1686  RC = UDFFirstOpenFile(Vcb,
1687  NULL, &PtrNewFcb, RelatedFileInfo, NewFileInfo,
1688  &LocalPath, &(UDFGlobalData.UnicodeStrSDir));
1689  } else {
1690  BrutePoint();
1691  }
1692  if(!NT_SUCCESS(RC)) {
1693  AdPrint((" Can't perform OpenFile operation for SDir\n"));
1694  BrutePoint();
1695  goto Creation_Err_1;
1696  }
1697 
1698  // Update unwind information
1699  TreeLength++;
1700  LastGoodFileInfo = NewFileInfo;
1701  // update FCB tree
1702  RC = MyAppendUnicodeStringToStringTag(&LocalPath, &(UDFGlobalData.UnicodeStrSDir), MEM_USLOC_TAG);
1703  if(!NT_SUCCESS(RC)) {
1704  AdPrint((" Can't append UNC str\n"));
1705  BrutePoint();
1706  goto Creation_Err_1;
1707  }
1708  UDFInterlockedIncrement((PLONG)&(PtrNewFcb->ReferenceCount));
1709  UDFInterlockedIncrement((PLONG)&(PtrNewFcb->NTRequiredFCB->CommonRefCount));
1710  ASSERT_REF(PtrNewFcb->ReferenceCount >= NewFileInfo->RefCount);
1711  PtrNewFcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
1712  PtrNewFcb->FCBFlags |= UDF_FCB_VALID;
1713 
1714  // PHASE 2
1715 
1716  // create stream
1717  RelatedFileInfo = NewFileInfo;
1718  RC = UDFCreateFile__(Vcb, IgnoreCase, &StreamName, 0, 0,
1719  Vcb->UseExtendedFE, (RequestedDisposition == FILE_CREATE),
1720  RelatedFileInfo, &NewFileInfo);
1721  if(!NT_SUCCESS(RC)) {
1722  AdPrint((" Can't create Stream\n"));
1723  BrutePoint();
1724  goto Creation_Err_1;
1725  }
1726 #if 0
1727  CollectStatistics(Vcb, MetaDataWrites);
1728 #endif
1729 
1730  // Update unwind information
1731  LastGoodTail = StreamName;
1732  }
1733  // NT wants ARCHIVE bit to be set on Files
1736  // Open the newly created object
1737  if (!(PtrNewFcb = NewFileInfo->Fcb)) {
1738  // It is a first open operation
1739 #ifndef IFS_40
1740  // Set attributes for the file ...
1741  UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo),NewFileInfo->Index),
1742  NewFileInfo->Dloc->FileEntry, FileAttributes);
1743 #endif //IFS_40
1744  // Allocate new FCB
1745  // Here we set FileObject pointer to NULL to avoid
1746  // new CCB allocation
1747  RC = UDFFirstOpenFile(Vcb,
1748  PtrNewFileObject, &PtrNewFcb, RelatedFileInfo, NewFileInfo,
1749  &LocalPath, &LastGoodTail);
1750  } else {
1751  BrutePoint();
1752  }
1753 
1754  if(!NT_SUCCESS(RC)) {
1755  AdPrint((" Can't perform OpenFile operation for file or stream\n"));
1756  BrutePoint();
1757  goto Undo_Create_1;
1758  }
1759 
1760  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.FileSize.QuadPart =
1761  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.ValidDataLength.QuadPart = 0;
1762  if(AllocationSize) {
1763  // inform NT about size changes
1764  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart = AllocationSize;
1765  MmPrint((" CcIsFileCached()\n"));
1766  if(CcIsFileCached(PtrNewFileObject)) {
1767  MmPrint((" CcSetFileSizes()\n"));
1768  BrutePoint();
1769  CcSetFileSizes(PtrNewFileObject, (PCC_FILE_SIZES)&(PtrNewFcb->NTRequiredFCB->CommonFCBHeader.AllocationSize));
1770  PtrNewFcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
1771  }
1772  }
1773 
1774  // Update unwind information
1775  TreeLength++;
1776  LastGoodFileInfo = NewFileInfo;
1777 
1778  // Set the Share Access for the file stream.
1779  // The FCBShareAccess field will be set by the I/O Manager.
1780  PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
1781  RC = UDFSetAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
1782 
1783  if(!NT_SUCCESS(RC)) {
1784  AdPrint((" Can't set Access Rights on Create\n"));
1785  BrutePoint();
1786  UDFFlushFile__(Vcb, NewFileInfo);
1787  UDFUnlinkFile__(Vcb, NewFileInfo, TRUE);
1788  try_return(RC);
1789  }
1790 
1791 #ifdef IFS_40
1792  // Set attributes for the file ...
1793  UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo),NewFileInfo->Index),
1794  NewFileInfo->Dloc->FileEntry, FileAttributes);
1795  // It is rather strange for me, but NT requires us to allow
1796  // Create operation for r/o + WriteAccess, but denies all
1797  // the rest operations in this case. Thus, we should update
1798  // r/o flag in Fcb _after_ Access check :-/
1800  PtrNewFcb->FCBFlags |= UDF_FCB_READ_ONLY;
1801 #endif //IFS_40
1802  // We call the notify package to report that the
1803  // we have added a stream.
1804  if(UDFIsAStream(NewFileInfo)) {
1805  UDFNotifyFullReportChange( Vcb, NewFileInfo,
1808  } else {
1809  UDFNotifyFullReportChange( Vcb, NewFileInfo,
1812  }
1813 /*#ifdef UDF_DBG
1814  {
1815  ULONG i;
1816  PDIR_INDEX_HDR hDirIndex = NewFileInfo->ParentFile->Dloc->DirIndex;
1817 
1818  for(i=0;DirIndex[i].FName.Buffer;i++) {
1819  AdPrint(("%ws\n", DirIndex[i].FName.Buffer));
1820  }
1821  }
1822 #endif*/
1823  ReturnedInformation = FILE_CREATED;
1824 
1825  try_return(RC);
1826 #endif //UDF_READ_ONLY_BUILD
1827 
1828  }
1829 
1830 AlreadyOpened:
1831 
1832  // ****************
1833  // we have always STATUS_SUCCESS here
1834  // ****************
1835 
1836  ASSERT(NewFileInfo != OldRelatedFileInfo);
1837  // A new CCB will be allocated.
1838  // Assume that this structure named PtrNewCcb
1839  RC = UDFOpenFile(Vcb, PtrNewFileObject, PtrNewFcb);
1840  if (!NT_SUCCESS(RC)) try_return(RC);
1841  PtrNewCcb = (PtrUDFCCB)(PtrNewFileObject->FsContext2);
1842 
1843  if(RequestedDisposition == FILE_CREATE) {
1844  ReturnedInformation = FILE_EXISTS;
1845  AdPrint((" Object name collision\n"));
1847  }
1848 
1849  NtReqFcb = PtrNewFcb->NTRequiredFCB;
1850  NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(PtrNewFcb);
1851 
1852  // Check if caller wanted a directory only and target object
1853  // is not a directory, or caller wanted a file only and target
1854  // object is not a file ...
1855  if((PtrNewFcb->FCBFlags & UDF_FCB_DIRECTORY) && ((RequestedDisposition == FILE_SUPERSEDE) ||
1856  (RequestedDisposition == FILE_OVERWRITE) || (RequestedDisposition == FILE_OVERWRITE_IF) ||
1857  FileOnlyRequested)) {
1858  if(FileOnlyRequested) {
1859  AdPrint((" Can't open directory as a plain file\n"));
1860  } else {
1861  AdPrint((" Can't supersede directory\n"));
1862  }
1864  try_return(RC);
1865  }
1866 
1867  if(DirectoryOnlyRequested && !(PtrNewFcb->FCBFlags & UDF_FCB_DIRECTORY)) {
1868  AdPrint((" This is not a directory\n"));
1870  try_return(RC);
1871  }
1872 
1873  if(DeleteOnCloseSpecified && (PtrNewFcb->FCBFlags & UDF_FCB_READ_ONLY)) {
1874  AdPrint((" Can't delete Read-Only file\n"));
1875  RC = STATUS_CANNOT_DELETE;
1876  try_return(RC);
1877  }
1878  // Check share access and fail if the share conflicts with an existing
1879  // open.
1880  ASSERT(Res1 != NULL);
1881  ASSERT(Res2 != NULL);
1882  RC = UDFCheckAccessRights(PtrNewFileObject, AccessState, PtrNewFcb, PtrNewCcb, DesiredAccess, ShareAccess);
1883  if(!NT_SUCCESS(RC)) {
1884  AdPrint((" Access/Share access check failed\n"));
1885  try_return(RC);
1886  }
1887 
1888  RestoreShareAccess = TRUE;
1889 
1890  if(FileOnlyRequested) {
1891  // If the user wants 'write access' access to the file make sure there
1892  // is not a process mapping this file as an image. Any attempt to
1893  // delete the file will be stopped in fileinfo.cpp
1894  //
1895  // If the user wants to delete on close, we must check at this
1896  // point though.
1897  if( (DesiredAccess & FILE_WRITE_DATA) || DeleteOnCloseSpecified ) {
1898  MmPrint((" MmFlushImageSection();\n"));
1899  NtReqFcb->AcqFlushCount++;
1900  if(!MmFlushImageSection( &(NtReqFcb->SectionObject),
1901  MmFlushForWrite )) {
1902 
1903  NtReqFcb->AcqFlushCount--;
1904  RC = DeleteOnCloseSpecified ? STATUS_CANNOT_DELETE :
1906  AdPrint((" File is mapped or deletion in progress\n"));
1907  try_return (RC);
1908  }
1909  NtReqFcb->AcqFlushCount--;
1910  }
1911  if( NoBufferingSpecified &&
1912  /* (PtrNewFileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) &&*/
1913  !(PtrNewFcb->CachedOpenHandleCount) &&
1914  (NtReqFcb->SectionObject.DataSectionObject) ) {
1915  // If this is a non-cached open, and there are no open cached
1916  // handles, but there is still a data section, attempt a flush
1917  // and purge operation to avoid cache coherency overhead later.
1918  // We ignore any I/O errors from the flush.
1919  MmPrint((" CcFlushCache()\n"));
1920  CcFlushCache( &(NtReqFcb->SectionObject), NULL, 0, NULL );
1921  MmPrint((" CcPurgeCacheSection()\n"));
1922  CcPurgeCacheSection( &(NtReqFcb->SectionObject), NULL, 0, FALSE );
1923  }
1924  }
1925 
1926  if(DeleteOnCloseSpecified && UDFIsADirectory(NewFileInfo) && !UDFIsDirEmpty__(NewFileInfo)) {
1927  AdPrint((" Directory in not empry\n"));
1929  }
1930 
1931  // Get attributes for the file ...
1932  TmpFileAttributes =
1933  (USHORT)UDFAttributesToNT(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo), NewFileInfo->Index),
1934  NewFileInfo->Dloc->FileEntry);
1935 
1936  if(DeleteOnCloseSpecified &&
1937  (TmpFileAttributes & FILE_ATTRIBUTE_READONLY)) {
1938  ASSERT(Res1 != NULL);
1939  ASSERT(Res2 != NULL);
1940  RC = UDFCheckAccessRights(NULL, NULL, OldRelatedFileInfo->Fcb, PtrRelatedCCB, FILE_DELETE_CHILD, 0);
1941  if(!NT_SUCCESS(RC)) {
1942  AdPrint((" Read-only. DeleteOnClose attempt failed\n"));
1944  }
1945  }
1946 
1947  // If a supersede or overwrite was requested, do so now ...
1948  if((RequestedDisposition == FILE_SUPERSEDE) ||
1949  (RequestedDisposition == FILE_OVERWRITE) ||
1950  (RequestedDisposition == FILE_OVERWRITE_IF)) {
1951  // Attempt the operation here ...
1952 
1953 #ifndef UDF_READ_ONLY_BUILD
1954  ASSERT(!UDFIsADirectory(NewFileInfo));
1955 
1956  if(RequestedDisposition == FILE_SUPERSEDE) {
1957  BOOLEAN RestoreRO = FALSE;
1958 
1959  ASSERT(Res1 != NULL);
1960  ASSERT(Res2 != NULL);
1961  // NT wants us to allow Supersede on RO files
1962  if(PtrNewFcb->FCBFlags & UDF_FCB_READ_ONLY) {
1963  // Imagine, that file is not RO and check other permissions
1964  RestoreRO = TRUE;
1965  PtrNewFcb->FCBFlags &= ~UDF_FCB_READ_ONLY;
1966  }
1967  RC = UDFCheckAccessRights(NULL, NULL, PtrNewFcb, PtrNewCcb, DELETE, 0);
1968  if(RestoreRO) {
1969  // Restore RO state if changed
1970  PtrNewFcb->FCBFlags |= UDF_FCB_READ_ONLY;
1971  }
1972  if(!NT_SUCCESS(RC)) {
1973  AdPrint((" Can't supersede. DELETE permission required\n"));
1974  try_return (RC);
1975  }
1976  } else {
1977  ASSERT(Res1 != NULL);
1978  ASSERT(Res2 != NULL);
1979  RC = UDFCheckAccessRights(NULL, NULL, PtrNewFcb, PtrNewCcb,
1981  if(!NT_SUCCESS(RC)) {
1982  AdPrint((" Can't overwrite. Permission denied\n"));
1983  try_return (RC);
1984  }
1985  }
1986  // Existing & requested System and Hidden bits must match
1987  if( (TmpFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) &
1989  AdPrint((" The Hidden and/or System bits do not match\n"));
1991  }
1992 
1993  // Before we actually truncate, check to see if the purge
1994  // is going to fail.
1995  MmPrint((" MmCanFileBeTruncated()\n"));
1996  if (!MmCanFileBeTruncated( &NtReqFcb->SectionObject,
1997  &(UDFGlobalData.UDFLargeZero) )) {
1998  AdPrint((" Can't truncate. File is mapped\n"));
2000  }
2001 
2002  ASSERT(Res1 != NULL);
2003  ASSERT(Res2 != NULL);
2004 
2005 #if 0
2006  CollectStatistics(Vcb, MetaDataWrites);
2007 #endif
2008  // Synchronize with PagingIo
2009  UDFAcquireResourceExclusive(PagingIoRes = &(NtReqFcb->PagingIoResource),TRUE);
2010  // Set file sizes
2011  if(!NT_SUCCESS(RC = UDFResizeFile__(Vcb, NewFileInfo, 0))) {
2012  AdPrint((" Error during resize operation\n"));
2013  try_return(RC);
2014  }
2015 /* if(AllocationSize) {
2016  if(!NT_SUCCESS(RC = UDFResizeFile__(Vcb, NewFileInfo, AllocationSize))) {
2017  AdPrint((" Error during resize operation (2)\n"));
2018  try_return(RC);
2019  }
2020  }*/
2021  NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart = UDFSysGetAllocSize(Vcb, AllocationSize);
2022  NtReqFcb->CommonFCBHeader.FileSize.QuadPart =
2023  NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = 0 /*AllocationSize*/;
2024  PtrNewFcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
2025  MmPrint((" CcSetFileSizes()\n"));
2026  CcSetFileSizes(PtrNewFileObject, (PCC_FILE_SIZES)&(NtReqFcb->CommonFCBHeader.AllocationSize));
2027  NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
2028  // Release PagingIoResource
2029  UDFReleaseResource(PagingIoRes);
2030  PagingIoRes = NULL;
2031 
2032  if(NT_SUCCESS(RC)) {
2034  if (RequestedDisposition == FILE_SUPERSEDE) {
2035  // Set attributes for the file ...
2036  UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo), NewFileInfo->Index),
2037  NewFileInfo->Dloc->FileEntry, FileAttributes);
2038  ReturnedInformation = FILE_SUPERSEDED;
2039  } else {
2040  // Get attributes for the file ...
2041  FileAttributes |= TmpFileAttributes;
2042  // Set attributes for the file ...
2043  UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(NewFileInfo), NewFileInfo->Index),
2044  NewFileInfo->Dloc->FileEntry, FileAttributes);
2045  ReturnedInformation = FILE_OVERWRITTEN;
2046  }
2047  }
2048  // notify changes
2049  UDFNotifyFullReportChange( Vcb, NewFileInfo,
2052 
2053  // Update parent object
2054  if((Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_WRITE) &&
2055  PtrRelatedFCB &&
2056  PtrRelatedFileObject &&
2057  (PtrRelatedFCB->FileInfo == NewFileInfo->ParentFile)) {
2058  PtrRelatedFileObject->Flags |= (FO_FILE_MODIFIED | FO_FILE_SIZE_CHANGED);
2059  }
2060 #else //UDF_READ_ONLY_BUILD
2062 #endif //UDF_READ_ONLY_BUILD
2063  } else {
2064  ReturnedInformation = FILE_OPENED;
2065  }
2066 
2067  // Update parent object
2068  if((Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_READ) &&
2069  PtrRelatedFCB &&
2070  PtrRelatedFileObject &&
2071  (PtrRelatedFCB->FileInfo == NewFileInfo->ParentFile)) {
2072  PtrRelatedFileObject->Flags |= FO_FILE_FAST_IO_READ;
2073  }
2074 
2075 try_exit: NOTHING;
2076 
2077  } _SEH2_FINALLY {
2078  // Complete the request unless we are here as part of unwinding
2079  // when an exception condition was encountered, OR
2080  // if the request has been deferred (i.e. posted for later handling)
2081 
2082  if(RestoreVCBOpenCounter) {
2083  UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
2084  RestoreVCBOpenCounter = FALSE;
2085  }
2086 
2087  if (RC != STATUS_PENDING) {
2088  // If any intermediate (directory) open operations were performed,
2089  // implement the corresponding close (do *not* however close
2090  // the target we have opened on behalf of the caller ...).
2091 
2092 #if 0
2093  if(NT_SUCCESS(RC)) {
2094  CollectStatistics2(Vcb, SuccessfulCreates);
2095  } else {
2096  CollectStatistics2(Vcb, FailedCreates);
2097  }
2098 #endif
2099 
2100  if (NT_SUCCESS(RC) && PtrNewFcb) {
2101  // Update the file object such that:
2102  // (a) the FsContext field points to the NTRequiredFCB field
2103  // in the FCB
2104  // (b) the FsContext2 field points to the CCB created as a
2105  // result of the open operation
2106 
2107  // If write-through was requested, then mark the file object
2108  // appropriately
2109 
2110  // directories are not cached
2111  // so we should prevent flush attepmts on cleanup
2112  if(!(PtrNewFcb->FCBFlags & UDF_FCB_DIRECTORY)) {
2113 #ifndef UDF_READ_ONLY_BUILD
2114  if(WriteThroughRequested) {
2115  PtrNewFileObject->Flags |= FO_WRITE_THROUGH;
2116  PtrNewFcb->FCBFlags |= UDF_FCB_WRITE_THROUGH;
2117  MmPrint((" FO_WRITE_THROUGH\n"));
2118  }
2119 #endif //UDF_READ_ONLY_BUILD
2120  if(SequentialIoRequested &&
2121  !(Vcb->CompatFlags & UDF_VCB_IC_IGNORE_SEQUENTIAL_IO)) {
2122  PtrNewFileObject->Flags |= FO_SEQUENTIAL_ONLY;
2123  MmPrint((" FO_SEQUENTIAL_ONLY\n"));
2124 #ifndef UDF_READ_ONLY_BUILD
2125  if(Vcb->TargetDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
2126  PtrNewFileObject->Flags &= ~FO_WRITE_THROUGH;
2127  PtrNewFcb->FCBFlags &= ~UDF_FCB_WRITE_THROUGH;
2128  MmPrint((" FILE_REMOVABLE_MEDIA + FO_SEQUENTIAL_ONLY => ~FO_WRITE_THROUGH\n"));
2129  }
2130 #endif //UDF_READ_ONLY_BUILD
2131  if(PtrNewFcb->FileInfo) {
2133  }
2134  }
2135  if(NoBufferingSpecified) {
2136  PtrNewFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
2137  MmPrint((" FO_NO_INTERMEDIATE_BUFFERING\n"));
2138  } else {
2139  PtrNewFileObject->Flags |= FO_CACHE_SUPPORTED;
2140  MmPrint((" FO_CACHE_SUPPORTED\n"));
2141  }
2142  }
2143 
2144  if((DesiredAccess & FILE_EXECUTE) /*&&
2145  !(PtrNewFcb->FCBFlags & UDF_FCB_DIRECTORY)*/) {
2146  MmPrint((" FO_FILE_FAST_IO_READ\n"));
2147  PtrNewFileObject->Flags |= FO_FILE_FAST_IO_READ;
2148  }
2149  // All right. Now we can safely increment OpenHandleCount
2150  UDFInterlockedIncrement((PLONG)&(Vcb->VCBHandleCount));
2151  UDFInterlockedIncrement((PLONG)&(PtrNewFcb->OpenHandleCount));
2152 
2153  if(PtrNewFileObject->Flags & FO_CACHE_SUPPORTED)
2154  UDFInterlockedIncrement((PLONG)&(PtrNewFcb->CachedOpenHandleCount));
2155  // Store some flags in CCB
2156  if(PtrNewCcb) {
2157  PtrNewCcb->TreeLength = TreeLength;
2158  // delete on close
2159 #ifndef UDF_READ_ONLY_BUILD
2160  if(DeleteOnCloseSpecified) {
2161  ASSERT(!(PtrNewFcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
2162  PtrNewCcb->CCBFlags |= UDF_CCB_DELETE_ON_CLOSE;
2163  }
2164 #endif //UDF_READ_ONLY_BUILD
2165  // case sensetivity
2166  if(!IgnoreCase) {
2167  // remember this for possible Rename/Move operation
2168  PtrNewCcb->CCBFlags |= UDF_CCB_CASE_SENSETIVE;
2169  PtrNewFileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
2170  }
2171  if(IsFileObjectReadOnly(PtrNewFileObject)) {
2172  UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCountRO));
2173  PtrNewCcb->CCBFlags |= UDF_CCB_READ_ONLY;
2174  }
2175  } else {
2176  BrutePoint();
2177  }
2178  // it was a stream...
2179  if(StreamOpen)
2180  PtrNewFileObject->Flags |= FO_STREAM_FILE;
2181 // PtrNewCcb->CCBFlags |= UDF_CCB_VALID;
2182  // increment the number of outstanding open operations on this
2183  // logical volume (i.e. volume cannot be dismounted)
2184  UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
2185  PtrNewFcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
2186  PtrNewFcb->FCBFlags |= UDF_FCB_VALID;
2187 #ifdef UDF_DBG
2188  // We have no FileInfo for Volume
2189  if(PtrNewFcb->FileInfo) {
2190  ASSERT_REF(PtrNewFcb->ReferenceCount >= PtrNewFcb->FileInfo->RefCount);
2191  }
2192 #endif // UDF_DBG
2193  AdPrint((" FCB %x, CCB %x, FO %x, Flags %x\n", PtrNewFcb, PtrNewCcb, PtrNewFileObject, PtrNewFcb->FCBFlags));
2194 
2195  UDFReleaseResFromCreate(&PagingIoRes, &Res1, &Res2);
2196 
2197  } else if(!NT_SUCCESS(RC)) {
2198  // Perform failure related post-processing now
2199  if(RestoreShareAccess && NtReqFcb && PtrNewFileObject) {
2200  IoRemoveShareAccess(PtrNewFileObject, &(NtReqFcb->FCBShareAccess));
2201  }
2202  UDFCleanUpCCB(PtrNewCcb);
2203  if(PtrNewFileObject) {
2204  PtrNewFileObject->FsContext2 = NULL;
2205  }
2206  // We have successfully opened LastGoodFileInfo,
2207  // so mark it as VALID to avoid future troubles...
2208  if(LastGoodFileInfo && LastGoodFileInfo->Fcb) {
2209  LastGoodFileInfo->Fcb->FCBFlags |= UDF_FCB_VALID;
2210  if(LastGoodFileInfo->Fcb->NTRequiredFCB) {
2211  LastGoodFileInfo->Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_VALID;
2212  }
2213  }
2214  // Release resources...
2215  UDFReleaseResFromCreate(&PagingIoRes, &Res1, &Res2);
2216  ASSERT(AcquiredVcb);
2217  // close the chain
2218  UDFCloseFileInfoChain(Vcb, LastGoodFileInfo, TreeLength, TRUE);
2219  // cleanup FCBs (if any)
2220  if( Vcb && (PtrNewFcb != Vcb->RootDirFCB) &&
2221  LastGoodFileInfo ) {
2222  UDFCleanUpFcbChain(Vcb, LastGoodFileInfo, TreeLength, TRUE);
2223  } else {
2224  ASSERT(!LastGoodFileInfo);
2225  }
2226  } else {
2227  UDFReleaseResFromCreate(&PagingIoRes, &Res1, &Res2);
2228  }
2229  // As long as this unwinding is not being performed as a result of
2230  // an exception condition, complete the IRP ...
2231  if (!_SEH2_AbnormalTermination()) {
2232  Irp->IoStatus.Status = RC;
2233  Irp->IoStatus.Information = ReturnedInformation;
2234 
2235  // complete the IRP
2237  // Free up the Irp Context
2238  UDFReleaseIrpContext(PtrIrpContext);
2239  }
2240  } else {
2241  UDFReleaseResFromCreate(&PagingIoRes, &Res1, &Res2);
2242  }
2243 
2244  if(AcquiredVcb) {
2245  UDFReleaseResource(&(Vcb->VCBResource));
2246  }
2247  // free allocated tmp buffers (if any)
2248  if(AbsolutePathName.Buffer)
2249  MyFreePool__(AbsolutePathName.Buffer);
2250  if(LocalPath.Buffer)
2251  MyFreePool__(LocalPath.Buffer);
2252  if(TailNameBuffer)
2253  MyFreePool__(TailNameBuffer);
2254  } _SEH2_END;
2255 
2256  return(RC);
2257 } // 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:301
#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:4724
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:384
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define FILE_WRITE_EA
Definition: nt_native.h:640
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:308
#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 TRUE
Definition: types.h:120
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1777
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:1774
_In_ PIRP Irp
Definition: csq.h:116
#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:2513
#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:54
#define STATUS_FILE_INVALID
Definition: ntstatus.h:374
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:1735
#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:4157
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:125
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_SEH2_TRY
Definition: create.c:4250
DWORD Id
uint32_t ULONG_PTR
Definition: typedefs.h:63
#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:1746
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:1745
#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:568
#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
PSE_EXPORTS SeExports
Definition: semgr.c:18
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1752
#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:697
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:1737
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:66
#define UDFConvertExclusiveToSharedLite(Resource)
Definition: env_spec_w32.h:665
#define STATUS_NOT_FOUND
Definition: shellext.h:67
#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:4798
#define try_return(S)
Definition: cdprocs.h:2189
NTSTATUS UDFOpenFile(PVCB Vcb, PFILE_OBJECT PtrNewFileObject, PtrUDFFCB PtrNewFcb)
Definition: create.cpp:2430
#define Vcb
Definition: cdprocs.h:1425
#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:1955
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:1738
#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:66
#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:310
LUID SeBackupPrivilege
Definition: setypes.h:1156
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#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:2813
VOID UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry, IN ULONG NTAttr)
_SEH2_END
Definition: create.c:4424
#define OpenByFileId
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1775
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define IgnoreCase
Definition: cdprocs.h:464
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:4157
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:354
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:4157
#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:4395
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:1750
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:2772
#define MEM_USABS_TAG
Definition: create.cpp:24
return STATUS_SUCCESS
Definition: btrfs.c:2966
#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:2274
#define FO_STREAM_FILE
Definition: iotypes.h:1740
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define DELETE
Definition: nt_native.h:57
#define FO_WRITE_THROUGH
Definition: iotypes.h:1736
#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:2512
#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:4250
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#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
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
_SEH2_END
Definition: create.c:4424
NTSTATUS UDFCommonCreate(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: create.cpp:186
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
return STATUS_SUCCESS
Definition: btrfs.c:2966

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 2274 of file create.cpp.

2283 {
2284 // DIR_INDEX NewFileIndex;
2285  PtrUDFObjectName NewFCBName;
2287  NTSTATUS RC;
2288  BOOLEAN Linked = TRUE;
2289  PDIR_INDEX_HDR hDirIndex;
2290  PDIR_INDEX_ITEM DirIndex;
2291 
2292  AdPrint(("UDFFirstOpenFile\n"));
2293 
2294  if(!((*PtrNewFcb) = UDFAllocateFCB())) {
2295  AdPrint(("Can't allocate FCB\n"));
2297  }
2298 
2299  // Allocate and set new FCB unique name (equal to absolute path name)
2300  if(!(NewFCBName = UDFAllocateObjectName())) return STATUS_INSUFFICIENT_RESOURCES;
2301 
2302  if(RelatedFileInfo && RelatedFileInfo->Fcb &&
2303  !(RelatedFileInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY)) {
2304  RC = MyCloneUnicodeString(&(NewFCBName->ObjectName), &(RelatedFileInfo->Fcb->FCBName->ObjectName));
2305  } else {
2306  RC = MyInitUnicodeString(&(NewFCBName->ObjectName), L"");
2307  }
2308  if(!NT_SUCCESS(RC))
2310  if( (CurName->Buffer[0] != L':') &&
2311  (!LocalPath->Length ||
2312  ((LocalPath->Buffer[LocalPath->Length/sizeof(WCHAR)-1] != L':') /*&&
2313  (LocalPath->Buffer[LocalPath->Length/sizeof(WCHAR)-1] != L'\\')*/) )) {
2314  RC = MyAppendUnicodeToString(&(NewFCBName->ObjectName), L"\\");
2315  if(!NT_SUCCESS(RC)) {
2316  UDFReleaseObjectName(NewFCBName);
2318  }
2319  }
2320 
2321  // Make link between Fcb and FileInfo
2322  (*PtrNewFcb)->FileInfo = NewFileInfo;
2323  NewFileInfo->Fcb = (*PtrNewFcb);
2324  (*PtrNewFcb)->ParentFcb = RelatedFileInfo->Fcb;
2325 
2326  if(!((*PtrNewFcb)->NTRequiredFCB = NewFileInfo->Dloc->CommonFcb)) {
2327  (*PtrNewFcb)->NTRequiredFCB = (PtrUDFNTRequiredFCB)MyAllocatePool__(NonPagedPool, UDFQuadAlign(sizeof(UDFNTRequiredFCB)));
2328  if(!((*PtrNewFcb)->NTRequiredFCB)) {
2329  UDFReleaseObjectName(NewFCBName);
2331  }
2332 
2333  UDFPrint(("UDFAllocateNtReqFCB: %x\n", (*PtrNewFcb)->NTRequiredFCB));
2334  RtlZeroMemory((*PtrNewFcb)->NTRequiredFCB, UDFQuadAlign(sizeof(UDFNTRequiredFCB)));
2335  (*PtrNewFcb)->FileInfo->Dloc->CommonFcb = (*PtrNewFcb)->NTRequiredFCB;
2336  Linked = FALSE;
2337  } else {
2338  if(!(NewFileInfo->Dloc->CommonFcb->NtReqFCBFlags & UDF_NTREQ_FCB_VALID)) {
2339  (*PtrNewFcb)->NTRequiredFCB = NULL;
2340  BrutePoint();
2341  UDFReleaseObjectName(NewFCBName);
2342  return STATUS_ACCESS_DENIED;
2343  }
2344  }
2345 
2346  NtReqFcb = (*PtrNewFcb)->NTRequiredFCB;
2347  // Set times
2348  if(!Linked) {
2349  UDFGetFileXTime((*PtrNewFcb)->FileInfo,
2350  &(NtReqFcb->CreationTime.QuadPart),
2351  &(NtReqFcb->LastAccessTime.QuadPart),
2352  &(NtReqFcb->ChangeTime.QuadPart),
2353  &(NtReqFcb->LastWriteTime.QuadPart) );
2354 
2355  // Set the allocation size for the object is specified
2356  NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart =
2357  UDFSysGetAllocSize(Vcb, NewFileInfo->Dloc->DataLoc.Length);
2358 // NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart = UDFGetFileAllocationSize(Vcb, NewFileInfo);
2359  NtReqFcb->CommonFCBHeader.FileSize.QuadPart =
2360  NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = NewFileInfo->Dloc->DataLoc.Length;
2361  }
2362  // begin transaction
2363  UDFAcquireResourceExclusive(&(Vcb->FcbListResource), TRUE);
2364 
2365  RC = UDFInitializeFCB(*PtrNewFcb, Vcb, NewFCBName,
2366  UDFIsADirectory(NewFileInfo) ? UDF_FCB_DIRECTORY : 0, PtrNewFileObject);
2367  if(!NT_SUCCESS(RC)) {
2368  if(!Linked) {
2369  MyFreePool__((*PtrNewFcb)->NTRequiredFCB);
2370  (*PtrNewFcb)->NTRequiredFCB = NULL;
2371  }
2372  UDFReleaseResource(&(Vcb->FcbListResource));
2373  return RC;
2374  }
2375  // set Read-only attribute
2376  if(!UDFIsAStreamDir(NewFileInfo)) {
2377  hDirIndex = UDFGetDirIndexByFileInfo(NewFileInfo);
2378 #ifdef UDF_DBG
2379  if(!hDirIndex) {
2380  BrutePoint();
2381  } else {
2382 #endif // UDF_DBG
2383  if(UDFAttributesToNT(DirIndex = UDFDirIndex(hDirIndex, NewFileInfo->Index),NULL) & FILE_ATTRIBUTE_READONLY) {
2384  (*PtrNewFcb)->FCBFlags |= UDF_FCB_READ_ONLY;
2385  }
2386  MyAppendUnicodeStringToStringTag(&(NewFCBName->ObjectName), &(DirIndex->FName), MEM_USOBJ_TAG);
2387 #ifdef UDF_DBG
2388  }
2389 #endif // UDF_DBG
2390  } else if (RelatedFileInfo->ParentFile) {
2391  hDirIndex = UDFGetDirIndexByFileInfo(RelatedFileInfo);
2392  if(UDFAttributesToNT(DirIndex = UDFDirIndex(hDirIndex, RelatedFileInfo->Index),NULL) & FILE_ATTRIBUTE_READONLY) {
2393  (*PtrNewFcb)->FCBFlags |= UDF_FCB_READ_ONLY;
2394  }
2395  RC = MyAppendUnicodeStringToStringTag(&(NewFCBName->ObjectName), CurName, MEM_USOBJ_TAG);
2396 // } else {
2397 // BrutePoint();
2398  }
2399  // do not allocate CCB if it is internal Create/Open
2400  if(NT_SUCCESS(RC)) {
2401  if(PtrNewFileObject) {
2402  RC = UDFOpenFile(Vcb, PtrNewFileObject, *PtrNewFcb);
2403  } else {
2404  RC = STATUS_SUCCESS;
2405  }
2406  }
2407  UDFReleaseResource(&(Vcb->FcbListResource));
2408  // end transaction
2409 
2410 // if(!NT_SUCCESS(RC)) return RC;
2411 
2412  return RC;
2413 } // 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 TRUE
Definition: types.h:120
#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:2510
#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 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:2430
#define Vcb
Definition: cdprocs.h:1425
#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:261
return STATUS_SUCCESS
Definition: btrfs.c:2966
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 2510 of file create.cpp.

2516 {
2517  AdPrint(("UDFInitializeFCB\n"));
2518  NTSTATUS status;
2519  BOOLEAN Linked = TRUE;
2520 
2521  if(!PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource) {
2522  // record signature
2523  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeTypeCode = UDF_NODE_TYPE_NT_REQ_FCB;
2524  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeByteSize = sizeof(UDFNTRequiredFCB);
2525  // Initialize the ERESOURCE objects
2526  if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->NTRequiredFCB->MainResource)))) {
2527  AdPrint((" Can't init resource\n"));
2528  return status;
2529  }
2530  if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->NTRequiredFCB->PagingIoResource)))) {
2531  AdPrint((" Can't init resource (2)\n"));
2532  UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->MainResource));
2533  return status;
2534  }
2535  // Fill NT required Fcb part
2536  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource = &(PtrNewFcb->NTRequiredFCB->MainResource);
2537  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource = &(PtrNewFcb->NTRequiredFCB->PagingIoResource);
2538  // Itialize byte-range locks support structure
2539  FsRtlInitializeFileLock(&(PtrNewFcb->NTRequiredFCB->FileLock),NULL,NULL);
2540  // Init reference counter
2541  PtrNewFcb->NTRequiredFCB->CommonRefCount = 0;
2542  Linked = FALSE;
2543  } else {
2544  ASSERT(PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeTypeCode == UDF_NODE_TYPE_NT_REQ_FCB);
2545  }
2546  if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->CcbListResource)))) {
2547  AdPrint((" Can't init resource (3)\n"));
2548  BrutePoint();
2549  if(!Linked) {
2550  UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->PagingIoResource));
2551  UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->MainResource));
2552  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource =
2553  PtrNewFcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource = NULL;
2554  FsRtlUninitializeFileLock(&(PtrNewFcb->NTRequiredFCB->FileLock));
2555  }
2556  return status;
2557  }
2558 
2559  // caller MUST ensure that VCB has been acquired exclusively
2560  InsertTailList(&(Vcb->NextFCB), &(PtrNewFcb->NextFCB));
2561 
2562  // initialize the various list heads
2563  InitializeListHead(&(PtrNewFcb->NextCCB));
2564 
2565  PtrNewFcb->ReferenceCount = 0;
2566  PtrNewFcb->OpenHandleCount = 0;
2567 
2568  PtrNewFcb->FCBFlags = Flags | UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE;
2569 
2570  PtrNewFcb->FCBName = PtrObjectName;
2571 
2572  PtrNewFcb->Vcb = Vcb;
2573 
2574  return STATUS_SUCCESS;
2575 } // end UDFInitializeFCB()
#define UDFInitializeResourceLite(Resource)
Definition: env_spec_w32.h:667
#define TRUE
Definition: types.h:120
#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
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
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
#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:2966
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 2430 of file create.cpp.

2435 {
2436  NTSTATUS RC = STATUS_SUCCESS;
2437  PtrUDFCCB Ccb = NULL;
2439 
2440  AdPrint(("UDFOpenFile\n"));
2442  ||(PtrNewFcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB));
2443 
2444  _SEH2_TRY {
2445 
2446 #if 0
2447  CollectStatistics2(Vcb, CreateHits);
2448 #endif
2449  // create a new CCB structure
2450  if (!(Ccb = UDFAllocateCCB())) {
2451  AdPrint(("Can't allocate CCB\n"));
2452  PtrNewFileObject->FsContext2 = NULL;
2453  //
2457  try_return(RC);
2458  }
2459  // initialize the CCB
2460  Ccb->Fcb = PtrNewFcb;
2461  // initialize the CCB to point to the file object
2462  Ccb->FileObject = PtrNewFileObject;
2463 
2464  // initialize the file object appropriately
2465  PtrNewFileObject->FsContext2 = (PVOID)(Ccb);
2466  PtrNewFileObject->Vpb = Vcb->Vpb;
2467  PtrNewFileObject->FsContext = (PVOID)(NtReqFcb = PtrNewFcb->NTRequiredFCB);
2468  PtrNewFileObject->SectionObjectPointer = &(NtReqFcb->SectionObject);
2469 #ifdef DBG
2470 // NtReqFcb ->FileObject = PtrNewFileObject;
2471 #endif //DBG
2472 
2473 #ifdef UDF_DELAYED_CLOSE
2474  PtrNewFcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
2475 #endif //UDF_DELAYED_CLOSE
2476 
2478  // insert CCB into linked list of open file object to Fcb or
2479  // to Vcb and do other intialization
2480  InsertTailList(&(PtrNewFcb->NextCCB), &(Ccb->NextCCB));
2483  UDFReleaseResource(&(PtrNewFcb->CcbListResource));
2484 
2485 try_exit: NOTHING;
2486  } _SEH2_FINALLY {
2487  NOTHING;
2488  } _SEH2_END;
2489 
2490  return(RC);
2491 } // end UDFOpenFile()
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
struct _FCB::@692::@695 Fcb
PFILE_OBJECT FileObject
Definition: ntfs.h:516
#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:4250
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:2189
#define Vcb
Definition: cdprocs.h:1425
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:593
#define NOTHING
Definition: env_spec_w32.h:461
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
_SEH2_END
Definition: create.c:4424
LIST_ENTRY NextCCB
Definition: struct.h:268
_SEH2_FINALLY
Definition: create.c:4395
return STATUS_SUCCESS
Definition: btrfs.c:2966
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().