ReactOS  0.4.13-dev-563-g0561610
create.c File Reference
#include "cdprocs.h"
Include dependency graph for create.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (CDFS_BUG_CHECK_CREATE)
 

Functions

 _When_ (RelatedTypeOfOpen !=UnopenedFileObject, _At_(RelatedCcb, _In_))
 
 _Requires_lock_held_ (_Global_critical_region_)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (CDFS_BUG_CHECK_CREATE)

Definition at line 23 of file create.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 1477 of file create.c.

1527 {
1529 
1530  BOOLEAN UnlockVcb = FALSE;
1531  BOOLEAN Found;
1532 
1533  ULONG StreamOffset;
1534 
1535  NODE_TYPE_CODE NodeTypeCode;
1537 
1539  BOOLEAN CleanupFileContext = FALSE;
1540 
1541  COMPOUND_PATH_ENTRY CompoundPathEntry = {{0}};/* ReactOS Change: GCC "missing braces around initializer" */
1542  BOOLEAN CleanupCompoundPathEntry = FALSE;
1543 
1544  FILE_ID FileId;
1545  FILE_ID ParentFileId;
1546 
1547  PFCB NextFcb;
1548 
1549  PAGED_CODE();
1550 
1551  //
1552  // Extract the FileId from the FileObject.
1553  //
1554 
1555  RtlCopyMemory( &FileId, IrpSp->FileObject->FileName.Buffer, sizeof( FILE_ID ));
1556 
1557  //
1558  // Use a try-finally to facilitate cleanup.
1559  //
1560 
1561  _SEH2_TRY {
1562 
1563  //
1564  // Go ahead and figure out the TypeOfOpen and NodeType. We can
1565  // get these from the input FileId.
1566  //
1567 
1568  if (CdFidIsDirectory( FileId )) {
1569 
1571  NodeTypeCode = CDFS_NTC_FCB_INDEX;
1572 
1573  //
1574  // If the offset isn't zero then the file Id is bad.
1575  //
1576 
1577  if (CdQueryFidDirentOffset( FileId ) != 0) {
1578 
1580  }
1581 
1582  } else {
1583 
1585  NodeTypeCode = CDFS_NTC_FCB_DATA;
1586  }
1587 
1588  //
1589  // Acquire the Vcb and check if there is already an Fcb.
1590  // If not we will need to carefully verify the Fcb.
1591  // We will post the request if we don't find the Fcb and this
1592  // request can't wait.
1593  //
1594 
1595  CdLockVcb( IrpContext, Vcb );
1596  UnlockVcb = TRUE;
1597 
1598  NextFcb = CdLookupFcbTable( IrpContext, Vcb, FileId );
1599 
1600  if (NextFcb == NULL) {
1601 
1602  //
1603  // Get the path table offset from the file id.
1604  //
1605 
1606  StreamOffset = CdQueryFidPathTableOffset( FileId );
1607 
1608  //
1609  // Build the parent FileId for this and try looking it
1610  // up in the PathTable.
1611  //
1612 
1613  CdSetFidDirentOffset( ParentFileId, 0 );
1614  CdSetFidPathTableOffset( ParentFileId, StreamOffset );
1615  CdFidSetDirectory( ParentFileId );
1616 
1617  NextFcb = CdLookupFcbTable( IrpContext, Vcb, ParentFileId );
1618 
1619  //
1620  // If not present then walk through the PathTable to this point.
1621  //
1622 
1623  if (NextFcb == NULL) {
1624 
1625  CdUnlockVcb( IrpContext, Vcb );
1626  UnlockVcb = FALSE;
1627 
1628  //
1629  // Check that the path table offset lies within the path
1630  // table.
1631  //
1632 
1633  if (StreamOffset > Vcb->PathTableFcb->FileSize.LowPart) {
1634 
1636  }
1637 
1639  CleanupCompoundPathEntry = TRUE;
1640 
1641  //
1642  // Start at the first entry in the PathTable.
1643  //
1644 
1645  CdLookupPathEntry( IrpContext,
1646  Vcb->PathTableFcb->StreamOffset,
1647  1,
1648  TRUE,
1649  &CompoundPathEntry );
1650 
1651  //
1652  // Continue looking until we have passed our target offset.
1653  //
1654 
1655  while (TRUE) {
1656 
1657  //
1658  // Move to the next entry.
1659  //
1660 
1661  Found = CdLookupNextPathEntry( IrpContext,
1662  &CompoundPathEntry.PathContext,
1663  &CompoundPathEntry.PathEntry );
1664 
1665  //
1666  // If we didn't find the entry or are beyond it then the
1667  // input Id is invalid.
1668  //
1669 
1670  if (!Found ||
1671  (CompoundPathEntry.PathEntry.PathTableOffset > StreamOffset)) {
1672 
1674  }
1675  }
1676 
1677  //
1678  // If the FileId specified a directory then we have found
1679  // the entry. Make sure our caller wanted to open a directory.
1680  //
1681 
1682  if ((TypeOfOpen == UserDirectoryOpen) &&
1684 
1686  }
1687 
1688  //
1689  // Lock the Vcb and create the Fcb if necessary.
1690  //
1691 
1692  CdLockVcb( IrpContext, Vcb );
1693  UnlockVcb = TRUE;
1694 
1695  NextFcb = CdCreateFcb( IrpContext, ParentFileId, NodeTypeCode, &Found );
1696 
1697  //
1698  // It's possible that someone got in here ahead of us.
1699  //
1700 
1701  if (!Found) {
1702 
1703  CdInitializeFcbFromPathEntry( IrpContext,
1704  NextFcb,
1705  NULL,
1706  &CompoundPathEntry.PathEntry );
1707  }
1708 
1709  //
1710  // If the user wanted to open a directory then we have found
1711  // it. Store this Fcb into the CurrentFcb and skip the
1712  // directory scan.
1713  //
1714 
1715  if (TypeOfOpen == UserDirectoryOpen) {
1716 
1717  *CurrentFcb = NextFcb;
1718  NextFcb = NULL;
1719  }
1720  }
1721 
1722  //
1723  // Perform the directory scan if we don't already have our target.
1724  //
1725 
1726  if (NextFcb != NULL) {
1727 
1728  //
1729  // Acquire the parent. We currently own the Vcb lock so
1730  // do this without waiting first.
1731  //
1732 
1733  if (!CdAcquireFcbExclusive( IrpContext,
1734  NextFcb,
1735  TRUE )) {
1736 
1737  NextFcb->FcbReference += 1;
1738  CdUnlockVcb( IrpContext, Vcb );
1739 
1740  CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE );
1741 
1742  CdLockVcb( IrpContext, Vcb );
1743  NextFcb->FcbReference -= 1;
1744  CdUnlockVcb( IrpContext, Vcb );
1745 
1746  } else {
1747 
1748  CdUnlockVcb( IrpContext, Vcb );
1749  }
1750 
1751  UnlockVcb = FALSE;
1752 
1753  //
1754  // Set up the CurrentFcb pointers. We know there was
1755  // no previous parent in this case.
1756  //
1757 
1758  *CurrentFcb = NextFcb;
1759 
1760  //
1761  // Calculate the offset in the stream.
1762  //
1763 
1764  StreamOffset = CdQueryFidDirentOffset( FileId );
1765 
1766  //
1767  // Create the stream file if it doesn't exist. This will update
1768  // the Fcb with the size from the self entry.
1769  //
1770 
1771  CdVerifyOrCreateDirStreamFile( IrpContext, NextFcb);
1772 
1773  //
1774  // If our offset is beyond the end of the directory then the
1775  // FileId is invalid.
1776  //
1777 
1778  if (StreamOffset > NextFcb->FileSize.LowPart) {
1779 
1781  }
1782 
1783  //
1784  // Otherwise position ourselves at the self entry and walk
1785  // through dirent by dirent until this location is found.
1786  //
1787 
1788  CdInitializeFileContext( IrpContext, &FileContext );
1789  CdLookupInitialFileDirent( IrpContext,
1790  NextFcb,
1791  &FileContext,
1792  NextFcb->StreamOffset );
1793 
1794  CleanupFileContext = TRUE;
1795 
1796  while (TRUE) {
1797 
1798  //
1799  // Move to the first entry of the next file.
1800  //
1801 
1802  Found = CdLookupNextInitialFileDirent( IrpContext,
1803  NextFcb,
1804  &FileContext );
1805 
1806  //
1807  // If we didn't find the entry or are beyond it then the
1808  // input Id is invalid.
1809  //
1810 
1811  if (!Found ||
1812  (FileContext.InitialDirent->Dirent.DirentOffset > StreamOffset)) {
1813 
1815  }
1816  }
1817 
1818  //
1819  // This better not be a directory. Directory FileIds must
1820  // refer to the self entry for directories.
1821  //
1822 
1823  if (FlagOn( FileContext.InitialDirent->Dirent.DirentFlags,
1825 
1827  }
1828 
1829  //
1830  // Check that our caller wanted to open a file.
1831  //
1832 
1833  if (FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) {
1834 
1836  }
1837 
1838  //
1839  // Otherwise we want to collect all of the dirents for this file
1840  // and create an Fcb with this.
1841  //
1842 
1843  CdLookupLastFileDirent( IrpContext, NextFcb, &FileContext );
1844 
1845  CdLockVcb( IrpContext, Vcb );
1846  UnlockVcb = TRUE;
1847 
1848  NextFcb = CdCreateFcb( IrpContext, FileId, NodeTypeCode, &Found );
1849 
1850  //
1851  // It's possible that someone has since created this Fcb since we
1852  // first checked. If so then can simply use this. Otherwise
1853  // we need to initialize a new Fcb and attach it to our parent
1854  // and insert it into the Fcb Table.
1855  //
1856 
1857  if (!Found) {
1858 
1859  CdInitializeFcbFromFileContext( IrpContext,
1860  NextFcb,
1861  *CurrentFcb,
1862  &FileContext );
1863  }
1864  }
1865 
1866  //
1867  // We have the Fcb. Check that the type of the file is compatible with
1868  // the desired type of file to open.
1869  //
1870 
1871  } else {
1872 
1873  if (FlagOn( NextFcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {
1874 
1876 
1878  }
1879 
1880  } else if (FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) {
1881 
1883  }
1884  }
1885 
1886  //
1887  // If we have a the previous Fcb and have inserted the next Fcb into
1888  // the Fcb Table. It is safe to release the current Fcb if present
1889  // since it is referenced through the child Fcb.
1890  //
1891 
1892  if (*CurrentFcb != NULL) {
1893 
1894  CdReleaseFcb( IrpContext, *CurrentFcb );
1895  }
1896 
1897  //
1898  // We now know the Fcb and currently hold the Vcb lock.
1899  // Try to acquire this Fcb without waiting. Otherwise we
1900  // need to reference it, drop the Vcb, acquire the Fcb and
1901  // then dereference the Fcb.
1902  //
1903 
1904  if (!CdAcquireFcbExclusive( IrpContext, NextFcb, TRUE )) {
1905 
1906  NextFcb->FcbReference += 1;
1907 
1908  CdUnlockVcb( IrpContext, Vcb );
1909 
1910  CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE );
1911 
1912  CdLockVcb( IrpContext, Vcb );
1913  NextFcb->FcbReference -= 1;
1914  CdUnlockVcb( IrpContext, Vcb );
1915 
1916  } else {
1917 
1918  CdUnlockVcb( IrpContext, Vcb );
1919  }
1920 
1921  UnlockVcb = FALSE;
1922 
1923  //
1924  // Move to this Fcb.
1925  //
1926 
1927  *CurrentFcb = NextFcb;
1928 
1929  // Lock object is acquired using internal state
1931 
1932  //
1933  // Check the requested access on this Fcb.
1934  //
1935 
1936  if (!CdIllegalFcbAccess( IrpContext,
1937  TypeOfOpen,
1938  IrpSp->Parameters.Create.SecurityContext->DesiredAccess )) {
1939 
1940  //
1941  // Call our worker routine to complete the open.
1942  //
1943 
1944  Status = CdCompleteFcbOpen( IrpContext,
1945  IrpSp,
1946  Vcb,
1947  CurrentFcb,
1948  TypeOfOpen,
1950  IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
1951 
1952  }
1953 
1954  try_exit: NOTHING;
1955  } _SEH2_FINALLY {
1956 
1957  if (UnlockVcb) {
1958 
1959  CdUnlockVcb( IrpContext, Vcb );
1960  }
1961 
1962  if (CleanupFileContext) {
1963 
1964  CdCleanupFileContext( IrpContext, &FileContext );
1965  }
1966 
1967  if (CleanupCompoundPathEntry) {
1968 
1970  }
1971  } _SEH2_END;
1972 
1973  return Status;
1974 }
VOID CdCleanupFileContext(_In_ PIRP_CONTEXT IrpContext, _In_ PFILE_ENUM_CONTEXT FileContext)
Definition: dirsup.c:1636
PFCB CdCreateFcb(_In_ PIRP_CONTEXT IrpContext, _In_ FILE_ID FileId, _In_ NODE_TYPE_CODE NodeTypeCode, _Out_opt_ PBOOLEAN FcbExisted)
Definition: strucsup.c:986
#define _Analysis_suppress_lock_checking_(lock)
Definition: no_sal2.h:685
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
_Inout_ PFCB * CurrentFcb
Definition: cdprocs.h:806
#define CdQueryFidPathTableOffset(I)
Definition: cdstruc.h:1838
Iosb Status
Definition: create.c:4311
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
ULONG FileAttributes
Definition: cdstruc.h:983
LONG NTSTATUS
Definition: precomp.h:26
#define CdReleaseFcb(IC, F)
Definition: cdprocs.h:1017
#define CdInitializeCompoundPathEntry(IC, CP)
Definition: cdprocs.h:768
#define CdFidSetDirectory(I)
Definition: cdstruc.h:1842
#define CdAcquireFcbExclusive(IC, F, I)
Definition: cdprocs.h:1011
#define CDFS_NTC_FCB_INDEX
Definition: nodetype.h:30
_SEH2_TRY
Definition: create.c:4250
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:593
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4157
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
VOID CdInitializeFcbFromPathEntry(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_opt_ PFCB ParentFcb, _In_ PPATH_ENTRY PathEntry)
Definition: strucsup.c:1136
#define CDFS_NTC_FCB_DATA
Definition: nodetype.h:31
CdLookupInitialFileDirent(IrpContext, Fcb, FileContext, Fcb->StreamOffset)
#define CD_ATTRIBUTE_DIRECTORY
Definition: cd.h:354
__volatile LONG FcbReference
Definition: cdstruc.h:970
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PFCB CdLookupFcbTable(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _In_ FILE_ID FileId)
Definition: strucsup.c:2107
#define CdQueryFidDirentOffset(I)
Definition: cdstruc.h:1837
return Found
Definition: dirsup.c:1270
_In_ PFCB _In_ PCD_NAME _In_ BOOLEAN _Inout_ PFILE_ENUM_CONTEXT FileContext
Definition: cdprocs.h:444
#define CdFidIsDirectory(I)
Definition: cdstruc.h:1841
VOID CdLookupLastFileDirent(_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ PFILE_ENUM_CONTEXT FileContext)
Definition: dirsup.c:1426
PAGED_CODE()
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
CdVerifyOrCreateDirStreamFile(IrpContext, Fcb)
#define try_return(S)
Definition: cdprocs.h:2189
#define CdUnlockVcb(IC, V)
Definition: cdprocs.h:1033
BOOLEAN CdLookupNextInitialFileDirent(_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _Inout_ PFILE_ENUM_CONTEXT FileContext)
Definition: dirsup.c:1275
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define CdLockVcb(IC, V)
Definition: cdprocs.h:1028
#define CCB_FLAG_OPEN_BY_ID
Definition: cdstruc.h:1109
BOOLEAN CdLookupNextPathEntry(_In_ PIRP_CONTEXT IrpContext, _Inout_ PPATH_ENUM_CONTEXT PathContext, _Inout_ PPATH_ENTRY PathEntry)
Definition: pathsup.c:207
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define NOTHING
Definition: env_spec_w32.h:461
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define CdCleanupCompoundPathEntry(IC, CP)
Definition: cdprocs.h:771
Status
Definition: gdiplustypes.h:24
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
_SEH2_END
Definition: create.c:4424
Definition: cdstruc.h:1531
#define CdSetFidPathTableOffset(I, P)
Definition: cdstruc.h:1840
ERESOURCE FcbResource
Definition: cdstruc.h:885
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
VOID CdLookupPathEntry(_In_ PIRP_CONTEXT IrpContext, _In_ ULONG PathEntryOffset, _In_ ULONG Ordinal, _In_ BOOLEAN VerifyBounds, _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry)
unsigned int ULONG
Definition: retypes.h:1
#define CdIllegalFcbAccess(IC, T, DA)
Definition: cdprocs.h:127
USHORT NODE_TYPE_CODE
Definition: nodetype.h:22
VOID CdInitializeFcbFromFileContext(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_ PFCB ParentFcb, _In_ PFILE_ENUM_CONTEXT FileContext)
Definition: strucsup.c:1225
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
PFCB_NONPAGED FcbNonpaged
Definition: cdstruc.h:1009
#define CdSetFidDirentOffset(I, D)
Definition: cdstruc.h:1839
HRESULT Create([out]ITransactionReceiver **ppReceiver)
#define CdInitializeFileContext(IC, FC)
Definition: cdprocs.h:532
_In_ PFCB _In_ PCD_NAME _In_ BOOLEAN _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
Definition: cdprocs.h:741

◆ _When_()

_When_ ( RelatedTypeOfOpen !  = UnopenedFileObject,
_At_(RelatedCcb, _In_  
)

Definition at line 29 of file create.c.

123  :26165, "Esp:1153")
124 #endif
125 CdCommonCreate (
126  _Inout_ PIRP_CONTEXT IrpContext,
128  )
129 
130 /*++
131 
132 Routine Description:
133 
134  This is the common routine for opening a file called by both the
135  Fsp and Fsd threads.
136 
137  The file can be opened either by name or by file Id either with or without
138  a relative name. The file name field in the file object passed to this routine
139  contains either a unicode string or a 64 bit value which is the file Id.
140  If this is not a Joliet disk then we will convert the unicode name to
141  an Oem string in this routine. If there is a related file object with
142  a name then we will already have converted that name to Oem.
143 
144  We will store the full name for the file in the file object on a successful
145  open. We will allocate a larger buffer if necessary and combine the
146  related and file object names. The only exception is the relative open
147  when the related file object is for an OpenByFileId file. If we need to
148  allocate a buffer for a case insensitive name then we allocate it at
149  the tail of the buffer we will store into the file object. The upcased
150  portion will begin immediately after the name defined by the FileName
151  in the file object.
152 
153  Once we have the full name in the file object we don't want to split the
154  name in the event of a retry. We use a flag in the IrpContext to indicate
155  that the name has been split.
156 
157 Arguments:
158 
159  Irp - Supplies the Irp to process
160 
161 Return Value:
162 
163  NTSTATUS - This is the status from this open operation.
164 
165 --*/
166 
167 {
170 
172 
173  COMPOUND_PATH_ENTRY CompoundPathEntry = {{0}};/* ReactOS Change: GCC "missing braces around initializer" */
174  BOOLEAN CleanupCompoundPathEntry = FALSE;
175 
177  BOOLEAN CleanupFileContext = FALSE;
178  BOOLEAN FoundEntry;
179 
180  PVCB Vcb;
181 
185 
186  BOOLEAN ShortNameMatch;
188 
189  BOOLEAN VolumeOpen = FALSE;
190 
191  //
192  // We will be acquiring and releasing file Fcb's as we move down the
193  // directory tree during opens. At any time we need to know the deepest
194  // point we have traversed down in the tree in case we need to cleanup
195  // any structures created here.
196  //
197  // CurrentFcb - represents this point. If non-null it means we have
198  // acquired it and need to release it in finally clause.
199  //
200  // NextFcb - represents the NextFcb to walk to but haven't acquired yet.
201  //
202 
203  TYPE_OF_OPEN RelatedTypeOfOpen = UnopenedFileObject;
204  PFILE_OBJECT RelatedFileObject;
205  PCCB RelatedCcb = NULL;
206 
207  PFCB NextFcb;
208  PFCB CurrentFcb = NULL;
209 
210  //
211  // During the open we need to combine the related file object name
212  // with the remaining name. We also may need to upcase the file name
213  // in order to do a case-insensitive name comparison. We also need
214  // to restore the name in the file object in the event that we retry
215  // the request. We use the following string variables to manage the
216  // name. We will can put these strings into either Unicode or Ansi
217  // form.
218  //
219  // FileName - Pointer to name as currently stored in the file
220  // object. We store the full name into the file object early in
221  // the open operation.
222  //
223  // RelatedFileName - Pointer to the name in the related file object.
224  //
225  // RemainingName - String containing remaining name to parse.
226  //
227  // MatchingName - Address of name structure in FileContext which matched.
228  // We need this to know whether we matched the long or short name.
229  //
230 
232  PUNICODE_STRING RelatedFileName = NULL;
233 
234  CD_NAME RemainingName = {{0}};/* ReactOS Change: GCC "missing braces around initializer" */
235  CD_NAME FinalName;
237 
238  PAGED_CODE();
239 
240  //
241  // If we were called with our file system device object instead of a
242  // volume device object, just complete this request with STATUS_SUCCESS.
243  //
244 
245  if (IrpContext->Vcb == NULL) {
246 
247  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
248  return STATUS_SUCCESS;
249  }
250 
251  //
252  // Get create parameters from the Irp.
253  //
254 
257  CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
258 
259  //
260  // Do some preliminary checks to make sure the operation is supported.
261  // We fail in the following cases immediately.
262  //
263  // - Open a paging file.
264  // - Open a target directory.
265  // - Open a file with Eas.
266  // - Create a file.
267  //
268 
270  (IrpSp->Parameters.Create.EaLength != 0) ||
272 
274  return STATUS_ACCESS_DENIED;
275  }
276 
277 #if (NTDDI_VERSION >= NTDDI_WIN7)
278  //
279  // CDFS does not support FILE_OPEN_REQUIRING_OPLOCK
280  //
281 
283 
286  }
287 #endif
288 
289  //
290  // Copy the Vcb to a local. Assume the starting directory is the root.
291  //
292 
293  Vcb = IrpContext->Vcb;
294  NextFcb = Vcb->RootIndexFcb;
295 
296  //
297  // Reference our input parameters to make things easier
298  //
299 
301  RelatedFileObject = NULL;
302 
304 
305  //
306  // Set up the file object's Vpb pointer in case anything happens.
307  // This will allow us to get a reasonable pop-up.
308  //
309 
310  if ((FileObject->RelatedFileObject != NULL) && !OpenByFileId) {
311 
312  RelatedFileObject = FileObject->RelatedFileObject;
313  FileObject->Vpb = RelatedFileObject->Vpb;
314 
315  RelatedTypeOfOpen = CdDecodeFileObject( IrpContext, RelatedFileObject, &NextFcb, &RelatedCcb );
316 
317  //
318  // Fail the request if this is not a user file object.
319  //
320 
321  if (RelatedTypeOfOpen < UserVolumeOpen) {
322 
325  }
326 
327  //
328  // Remember the name in the related file object.
329  //
330 
331  RelatedFileName = &RelatedFileObject->FileName;
332  }
333 
334  //
335  // If we haven't initialized the names then make sure the strings are valid.
336  // If this an OpenByFileId then verify the file id buffer.
337  //
338  // After this routine returns we know that the full name is in the
339  // FileName buffer and the buffer will hold the upcased portion
340  // of the name yet to parse immediately after the full name in the
341  // buffer. Any trailing backslash has been removed and the flag
342  // in the IrpContext will indicate whether we removed the
343  // backslash.
344  //
345 
346  Status = CdNormalizeFileNames( IrpContext,
347  Vcb,
348  OpenByFileId,
349  IgnoreCase,
350  RelatedTypeOfOpen,
351  RelatedCcb,
352  RelatedFileName,
353  FileName,
354  &RemainingName );
355 
356  //
357  // Return the error code if not successful.
358  //
359 
360  if (!NT_SUCCESS( Status )) {
361 
362  CdCompleteRequest( IrpContext, Irp, Status );
363  return Status;
364  }
365 
366  //
367  // We want to acquire the Vcb. Exclusively for a volume open, shared otherwise.
368  // The file name is empty for a volume open.
369  //
370 
371  if ((FileName->Length == 0) &&
372  (RelatedTypeOfOpen <= UserVolumeOpen) &&
373  !OpenByFileId) {
374 
375  VolumeOpen = TRUE;
376  CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
377 
378  } else {
379 
380  CdAcquireVcbShared( IrpContext, Vcb, FALSE );
381  }
382 
383  //
384  // Use a try-finally to facilitate cleanup.
385  //
386 
387  _SEH2_TRY {
388 
389  //
390  // Verify that the Vcb is not in an unusable condition. This routine
391  // will raise if not usable.
392  //
393 
394  CdVerifyVcb( IrpContext, Vcb );
395 
396  //
397  // If the Vcb is locked then we cannot open another file
398  //
399 
400  if (FlagOn( Vcb->VcbState, VCB_STATE_LOCKED )) {
401 
403  }
404 
405  //
406  // If we are opening this file by FileId then process this immediately
407  // and exit.
408  //
409 
410  if (OpenByFileId) {
411 
412  //
413  // We only allow Dasd opens of audio disks. Fail this request at
414  // this point.
415  //
416 
417  if (FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK )) {
418 
420  }
421 
422  //
423  // The only create disposition we allow is OPEN.
424  //
425 
426  if ((CreateDisposition != FILE_OPEN) &&
428 
430  }
431 
432  //
433  // Make sure we can wait for this request.
434  //
435 
436  if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {
437 
438  CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
439  }
440 
441  try_return( Status = CdOpenByFileId( IrpContext,
442  IrpSp,
443  Vcb,
444  &CurrentFcb ));
445  }
446 
447  //
448  // If we are opening this volume Dasd then process this immediately
449  // and exit.
450  //
451 
452  if (VolumeOpen) {
453 
454  //
455  // The only create disposition we allow is OPEN.
456  //
457 
458  if ((CreateDisposition != FILE_OPEN) &&
460 
462  }
463 
464  //
465  // If they wanted to open a directory, surprise.
466  //
467 
468  if (FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) {
469 
471  }
472 
473  //
474  // Acquire the Fcb first.
475  //
476 
477  CurrentFcb = Vcb->VolumeDasdFcb;
478  CdAcquireFcbExclusive( IrpContext, CurrentFcb, FALSE );
479 
480  try_return( Status = CdOpenExistingFcb( IrpContext,
481  IrpSp,
482  &CurrentFcb,
484  FALSE,
485  NULL ));
486  }
487 
488  //
489  // At this point CurrentFcb points to the deepest Fcb for this open
490  // in the tree. Let's acquire this Fcb to keep it from being deleted
491  // beneath us.
492  //
493 
494  CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE );
495  CurrentFcb = NextFcb;
496 
497  //
498  // Do a prefix search if there is more of the name to parse.
499  //
500 
501  if (RemainingName.FileName.Length != 0) {
502 
503  //
504  // Do the prefix search to find the longest matching name.
505  //
506 
507  CdFindPrefix( IrpContext,
508  &CurrentFcb,
509  &RemainingName.FileName,
510  IgnoreCase );
511  }
512 
513  //
514  // If the remaining name length is zero then we have found our
515  // target.
516  //
517 
518  if (RemainingName.FileName.Length == 0) {
519 
520  //
521  // If this is a file so verify the user didn't want to open
522  // a directory.
523  //
524 
526 
527  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH ) ||
529 
531  }
532 
533  //
534  // The only create disposition we allow is OPEN.
535  //
536 
537  if ((CreateDisposition != FILE_OPEN) &&
539 
541  }
542 
543  try_return( Status = CdOpenExistingFcb( IrpContext,
544  IrpSp,
545  &CurrentFcb,
546  UserFileOpen,
547  IgnoreCase,
548  RelatedCcb ));
549 
550  //
551  // This is a directory. Verify the user didn't want to open
552  // as a file.
553  //
554 
555  } else if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE )) {
556 
558 
559  //
560  // Open the file as a directory.
561  //
562 
563  } else {
564 
565  //
566  // The only create disposition we allow is OPEN.
567  //
568 
569  if ((CreateDisposition != FILE_OPEN) &&
571 
573  }
574 
575  try_return( Status = CdOpenExistingFcb( IrpContext,
576  IrpSp,
577  &CurrentFcb,
579  IgnoreCase,
580  RelatedCcb ));
581  }
582  }
583 
584  //
585  // We have more work to do. We have a starting Fcb which we own shared.
586  // We also have the remaining name to parse. Walk through the name
587  // component by component looking for the full name.
588  //
589 
590  //
591  // Our starting Fcb better be a directory.
592  //
593 
595 
597  }
598 
599  //
600  // If we can't wait then post this request.
601  //
602 
603  if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {
604 
605  CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
606  }
607 
608  //
609  // Make sure the final name has no version string.
610  //
611 
612  FinalName.VersionString.Length = 0;
613 
614  while (TRUE) {
615 
616  ShortNameMatch = FALSE;
617 
618  //
619  // Split off the next component from the name.
620  //
621 
622  CdDissectName( IrpContext,
623  &RemainingName.FileName,
624  &FinalName.FileName );
625 
626  //
627  // Go ahead and look this entry up in the path table.
628  //
629 
631  CleanupCompoundPathEntry = TRUE;
632 
633  FoundEntry = CdFindPathEntry( IrpContext,
634  CurrentFcb,
635  &FinalName,
636  IgnoreCase,
638 
639  //
640  // If we didn't find the entry then check if the current name
641  // is a possible short name.
642  //
643 
644  if (!FoundEntry) {
645 
646  ShortNameDirentOffset = CdShortNameDirentOffset( IrpContext, &FinalName.FileName );
647 
648  //
649  // If there is an embedded short name offset then look for the
650  // matching long name in the directory.
651  //
652 
654 
655  if (CleanupFileContext) {
656 
657  CdCleanupFileContext( IrpContext, &FileContext );
658  }
659 
660  CdInitializeFileContext( IrpContext, &FileContext );
661  CleanupFileContext = TRUE;
662 
663  FoundEntry = CdFindFileByShortName( IrpContext,
664  CurrentFcb,
665  &FinalName,
666  IgnoreCase,
668  &FileContext );
669 
670  //
671  // If we found an entry and it is a directory then look
672  // this up in the path table.
673  //
674 
675  if (FoundEntry) {
676 
677  ShortNameMatch = TRUE;
678 
679  if (FlagOn( FileContext.InitialDirent->Dirent.DirentFlags,
681 
684 
685  FoundEntry = CdFindPathEntry( IrpContext,
686  CurrentFcb,
687  &FileContext.InitialDirent->Dirent.CdCaseFileName,
688  IgnoreCase,
690 
691  //
692  // We better find this entry.
693  //
694 
695  if (!FoundEntry) {
696 
698  }
699 
700  //
701  // Upcase the name with the short name if case
702  // insensitive.
703  //
704 
705  if (IgnoreCase) {
706 
707  CdUpcaseName( IrpContext, &FinalName, &FinalName );
708  }
709 
710  //
711  // We found a matching file. If we are at the last
712  // entry then break out of the loop and open the
713  // file below. Otherwise we return an error.
714  //
715 
716  } else if (RemainingName.FileName.Length == 0) {
717 
718  //
719  // Break out of the loop. We will process the dirent
720  // below.
721  //
722 
724  break;
725 
726  } else {
727 
729  }
730  }
731  }
732 
733  //
734  // We didn't find the name in either the path table or as
735  // a short name in a directory. If the remaining name
736  // length is zero then break out of the loop to search
737  // the directory.
738  //
739 
740  if (!FoundEntry) {
741 
742  if (RemainingName.FileName.Length == 0) {
743 
744  break;
745 
746  //
747  // Otherwise this path could not be cracked.
748  //
749 
750  } else {
751 
753  }
754  }
755  }
756 
757  //
758  // If this is an ignore case open then copy the exact case
759  // in the file object name. If it was a short name match then
760  // the name must be upcase already.
761  //
762 
763  if (IgnoreCase && !ShortNameMatch) {
764 
765  RtlCopyMemory( FinalName.FileName.Buffer,
766  CompoundPathEntry.PathEntry.CdDirName.FileName.Buffer,
767  CompoundPathEntry.PathEntry.CdDirName.FileName.Length );
768  }
769 
770  //
771  // If we have found the last component then open this as a directory
772  // and return to our caller.
773  //
774 
775  if (RemainingName.FileName.Length == 0) {
776 
778 
780  }
781 
782  //
783  // The only create disposition we allow is OPEN.
784  //
785 
786  if ((CreateDisposition != FILE_OPEN) &&
788 
790  }
791 
792  try_return( Status = CdOpenDirectoryFromPathEntry( IrpContext,
793  IrpSp,
794  Vcb,
795  &CurrentFcb,
796  &FinalName,
797  IgnoreCase,
798  ShortNameMatch,
799  &CompoundPathEntry.PathEntry,
800  TRUE,
801  RelatedCcb ));
802  }
803 
804  //
805  // Otherwise open an Fcb for this intermediate index Fcb.
806  //
807 
808  CdOpenDirectoryFromPathEntry( IrpContext,
809  IrpSp,
810  Vcb,
811  &CurrentFcb,
812  &FinalName,
813  IgnoreCase,
814  ShortNameMatch,
815  &CompoundPathEntry.PathEntry,
816  FALSE,
817  NULL );
818 
820  CleanupCompoundPathEntry = FALSE;
821  }
822 
823  //
824  // We need to scan the current directory for a matching file name
825  // if we don't already have one.
826  //
827 
828  if (!FoundEntry) {
829 
830  if (CleanupFileContext) {
831 
832  CdCleanupFileContext( IrpContext, &FileContext );
833  }
834 
835  CdInitializeFileContext( IrpContext, &FileContext );
836  CleanupFileContext = TRUE;
837 
838  //
839  // Split our search name into separate components.
840  //
841 
842  CdConvertNameToCdName( IrpContext, &FinalName );
843 
844  FoundEntry = CdFindFile( IrpContext,
845  CurrentFcb,
846  &FinalName,
847  IgnoreCase,
848  &FileContext,
849  &MatchingName );
850  }
851 
852  //
853  // If we didn't find a match then check if the name is invalid to
854  // determine which error code to return.
855  //
856 
857  if (!FoundEntry) {
858 
859  if ((CreateDisposition == FILE_OPEN) ||
861 
863  }
864 
865  //
866  // Any other operation return STATUS_ACCESS_DENIED.
867  //
868 
870  }
871 
872  //
873  // If this is a directory then the disk is corrupt because it wasn't
874  // in the Path Table.
875  //
876 
877  if (FlagOn( FileContext.InitialDirent->Dirent.Flags, CD_ATTRIBUTE_DIRECTORY )) {
878 
880  }
881 
882  //
883  // Make sure our opener didn't want a directory.
884  //
885 
886  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH ) ||
888 
890  }
891 
892  //
893  // The only create disposition we allow is OPEN.
894  //
895 
896  if ((CreateDisposition != FILE_OPEN) &&
898 
900  }
901 
902  //
903  // If this is an ignore case open then copy the exact case
904  // in the file object name. Any version portion should
905  // already be upcased.
906  //
907 
908  if (IgnoreCase) {
909 
910  RtlCopyMemory( FinalName.FileName.Buffer,
911  MatchingName->FileName.Buffer,
912  MatchingName->FileName.Length );
913  }
914 
915  //
916  // Open the file using the file context. We already have the
917  // first and last dirents.
918  //
919 
920  try_return( Status = CdOpenFileFromFileContext( IrpContext,
921  IrpSp,
922  Vcb,
923  &CurrentFcb,
924  &FinalName,
925  IgnoreCase,
927  &FileContext,
928  RelatedCcb ));
929 
930  try_exit: NOTHING;
931  } _SEH2_FINALLY {
932 
933  //
934  // Cleanup the PathEntry if initialized.
935  //
936 
937  if (CleanupCompoundPathEntry) {
938 
940  }
941 
942  //
943  // Cleanup the FileContext if initialized.
944  //
945 
946  if (CleanupFileContext) {
947 
948  CdCleanupFileContext( IrpContext, &FileContext );
949  }
950 
951  //
952  // The result of this open could be success, pending or some error
953  // condition.
954  //
955 
957 
958 
959  //
960  // In the error path we start by calling our teardown routine if we
961  // have a CurrentFcb and its not the volume Dasd Fcb.
962  //
963 
964  if ((CurrentFcb != NULL) &&
965  (CurrentFcb != Vcb->VolumeDasdFcb)) {
966 
967  BOOLEAN RemovedFcb;
968 
969  CdTeardownStructures( IrpContext, CurrentFcb, &RemovedFcb );
970 
971  if (RemovedFcb) {
972 
973  CurrentFcb = NULL;
974  }
975  }
976 
977  //
978  // No need to complete the request.
979  //
980 
981  IrpContext = NULL;
982  Irp = NULL;
983 
984  //
985  // If we posted this request through the oplock package we need
986  // to show that there is no reason to complete the request.
987  //
988 
989  } else if (Status == STATUS_PENDING) {
990 
991  IrpContext = NULL;
992  Irp = NULL;
993  }
994 
995  //
996  // Release the Current Fcb if still acquired.
997  //
998 
999  if (CurrentFcb != NULL) {
1001  CdReleaseFcb( IrpContext, CurrentFcb );
1002  }
1003 
1004  //
1005  // Release the Vcb.
1006  //
1007 
1008  CdReleaseVcb( IrpContext, Vcb );
1009 
1010  //
1011  // Call our completion routine. It will handle the case where either
1012  // the Irp and/or IrpContext are gone.
1013  //
1014 
1015  CdCompleteRequest( IrpContext, Irp, Status );
1016  } _SEH2_END;
1017 
1018  return Status;
1019 }
UNICODE_STRING VersionString
Definition: cdstruc.h:256
VOID CdCleanupFileContext(_In_ PIRP_CONTEXT IrpContext, _In_ PFILE_ENUM_CONTEXT FileContext)
Definition: dirsup.c:1636
#define FILE_OPEN_REQUIRING_OPLOCK
Definition: winternl.h:186
#define VCB_STATE_AUDIO_DISK
Definition: cdstruc.h:718
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1776
_Inout_ PFCB * CurrentFcb
Definition: cdprocs.h:806
#define CdAcquireVcbShared(IC, V, I)
Definition: cdprocs.h:987
#define FILE_OPEN_IF
Definition: from_kernel.h:56
Iosb Status
Definition: create.c:4311
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1773
_In_ PIRP Irp
Definition: csq.h:116
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
Definition: cdstruc.h:1073
#define SafeNodeType(Ptr)
Definition: nodetype.h:54
ULONG FileAttributes
Definition: cdstruc.h:983
VOID CdUpcaseName(_In_ PIRP_CONTEXT IrpContext, _In_ PCD_NAME Name, _Inout_ PCD_NAME UpcaseName)
Definition: namesup.c:194
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_CREATE
Definition: from_kernel.h:55
ULONG CdShortNameDirentOffset(_In_ PIRP_CONTEXT IrpContext, _In_ PUNICODE_STRING Name)
Definition: namesup.c:955
#define CdReleaseFcb(IC, F)
Definition: cdprocs.h:1017
#define CdInitializeCompoundPathEntry(IC, CP)
Definition: cdprocs.h:768
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
Definition: cdstruc.h:504
#define FILE_OVERWRITE
Definition: from_kernel.h:57
_In_ PFCB _In_ PCD_NAME _In_ BOOLEAN _Inout_ PFILE_ENUM_CONTEXT _Out_ PCD_NAME * MatchingName
Definition: cdprocs.h:444
#define CdAcquireFcbExclusive(IC, F, I)
Definition: cdprocs.h:1011
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
_SEH2_TRY
Definition: create.c:4250
_In_ PFCB _In_ PCD_NAME _In_ BOOLEAN _In_ ULONG ShortNameDirentOffset
Definition: cdprocs.h:464
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4157
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define _Analysis_assume_lock_held_(lock)
Definition: no_sal2.h:682
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define CDFS_NTC_FCB_DATA
Definition: nodetype.h:31
#define IRP_CONTEXT_FLAG_TRAIL_BACKSLASH
Definition: cdstruc.h:1236
#define CD_ATTRIBUTE_DIRECTORY
Definition: cd.h:354
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT FileObject
Definition: create.c:4157
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define VCB_STATE_LOCKED
Definition: cdstruc.h:715
_In_ PFCB _In_ PCD_NAME _In_ BOOLEAN _Inout_ PFILE_ENUM_CONTEXT FileContext
Definition: cdprocs.h:444
PAGED_CODE()
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define CdAcquireVcbExclusive(IC, V, I)
Definition: cdprocs.h:984
#define CdReleaseVcb(IC, V)
Definition: cdprocs.h:990
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define try_return(S)
Definition: cdprocs.h:2189
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define _Inout_
Definition: no_sal2.h:244
* PFILE_OBJECT
Definition: iotypes.h:1954
ULONG Flags
Definition: ntfs.h:520
PUNICODE_STRING FileName
Definition: iotypes.h:2792
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define NOTHING
Definition: env_spec_w32.h:461
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define CdCleanupCompoundPathEntry(IC, CP)
Definition: cdprocs.h:771
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
#define MAXULONG
Definition: typedefs.h:250
VOID CdDissectName(_In_ PIRP_CONTEXT IrpContext, _Inout_ PUNICODE_STRING RemainingName, _Out_ PUNICODE_STRING FinalName)
Definition: namesup.c:301
VOID CdVerifyVcb(_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB Vcb)
Definition: verfysup.c:411
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _FileName FileName
Definition: fatprocs.h:884
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
_SEH2_END
Definition: create.c:4424
#define OpenByFileId
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1774
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
Definition: cdstruc.h:1531
#define IgnoreCase
Definition: cdprocs.h:464
#define CdRaiseStatus(IC, S)
Definition: cdprocs.h:1869
ERESOURCE FcbResource
Definition: cdstruc.h:885
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
unsigned int ULONG
Definition: retypes.h:1
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2777
PFCB_NONPAGED FcbNonpaged
Definition: cdstruc.h:1009
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1111
UNICODE_STRING FileName
Definition: cdstruc.h:250
_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 _In_ ULONG CreateDisposition
Definition: create.c:4157
HRESULT Create([out]ITransactionReceiver **ppReceiver)
#define CdInitializeFileContext(IC, FC)
Definition: cdprocs.h:532
_In_ PFCB _In_ PCD_NAME _In_ BOOLEAN _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
Definition: cdprocs.h:741
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806