ReactOS 0.4.16-dev-336-gb667d82
fastio.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for fastio.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI FsRtlIncrementCcFastReadResourceMiss (VOID)
 
VOID NTAPI FsRtlIncrementCcFastReadNotPossible (VOID)
 
VOID NTAPI FsRtlIncrementCcFastReadWait (VOID)
 
VOID NTAPI FsRtlIncrementCcFastReadNoWait (VOID)
 
BOOLEAN NTAPI FsRtlCopyRead (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI FsRtlCopyWrite (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI FsRtlGetFileSize (IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize)
 
BOOLEAN NTAPI FsRtlMdlRead (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
 
BOOLEAN NTAPI FsRtlMdlReadComplete (IN PFILE_OBJECT FileObject, IN OUT PMDL MdlChain)
 
BOOLEAN NTAPI FsRtlMdlReadCompleteDev (IN PFILE_OBJECT FileObject, IN PMDL MemoryDescriptorList, IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI FsRtlMdlReadDev (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI FsRtlMdlWriteComplete (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
 
BOOLEAN NTAPI FsRtlMdlWriteCompleteDev (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI FsRtlPrepareMdlWrite (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
 
BOOLEAN NTAPI FsRtlPrepareMdlWriteDev (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI FsRtlAcquireFileExclusiveCommon (IN PFILE_OBJECT FileObject, IN FS_FILTER_SECTION_SYNC_TYPE SyncType, IN ULONG Reserved)
 
VOID NTAPI FsRtlAcquireFileExclusive (IN PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection (_In_ PFILE_OBJECT FileObject, _In_ ULONG SectionPageProtection)
 
VOID NTAPI FsRtlReleaseFile (IN PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI FsRtlAcquireFileForCcFlushEx (IN PFILE_OBJECT FileObject)
 
VOID NTAPI FsRtlAcquireFileForCcFlush (IN PFILE_OBJECT FileObject)
 
VOID NTAPI FsRtlReleaseFileForCcFlush (IN PFILE_OBJECT FileObject)
 
static BOOLEAN FsRtlpGetResourceForModWrite (_In_ PFSRTL_COMMON_FCB_HEADER FcbHeader, _In_ PLARGE_INTEGER EndingOffset, _Outptr_result_maybenull_ PERESOURCE *ResourceToAcquire)
 Get the resource to acquire when Mod Writer flushes data to disk.
 
_Check_return_ NTSTATUS NTAPI FsRtlAcquireFileForModWriteEx (_In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER EndingOffset, _Outptr_result_maybenull_ PERESOURCE *ResourceToRelease)
 Lock a file object before flushing pages to disk. To be called by the Modified Page Writer (MPW)
 
VOID NTAPI FsRtlReleaseFileForModWrite (_In_ PFILE_OBJECT FileObject, _In_ PERESOURCE ResourceToRelease)
 Unlock a file object after flushing pages to disk. To be called by the Modified Page Writer (MPW) after a succesful call to FsRtlAcquireFileForModWriteEx.
 
NTSTATUS NTAPI FsRtlRegisterFileSystemFilterCallbacks (PDRIVER_OBJECT FilterDriverObject, PFS_FILTER_CALLBACKS Callbacks)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file fastio.c.

Function Documentation

◆ FsRtlAcquireFileExclusive()

VOID NTAPI FsRtlAcquireFileExclusive ( IN PFILE_OBJECT  FileObject)

Definition at line 1640 of file fastio.c.

1641{
1642 PAGED_CODE();
1643
1644 /* Call the common routine. Don't care about the result */
1646}
#define PAGED_CODE()
#define VOID
Definition: acefi.h:82
NTSTATUS NTAPI FsRtlAcquireFileExclusiveCommon(IN PFILE_OBJECT FileObject, IN FS_FILTER_SECTION_SYNC_TYPE SyncType, IN ULONG Reserved)
Definition: fastio.c:1557
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
@ SyncTypeOther
Definition: iotypes.h:7364

Referenced by MiRosUnmapViewOfSection(), and MmNotPresentFaultSectionView().

◆ FsRtlAcquireFileExclusiveCommon()

NTSTATUS NTAPI FsRtlAcquireFileExclusiveCommon ( IN PFILE_OBJECT  FileObject,
IN FS_FILTER_SECTION_SYNC_TYPE  SyncType,
IN ULONG  Reserved 
)

Definition at line 1557 of file fastio.c.

1560{
1561 PFSRTL_COMMON_FCB_HEADER FcbHeader;
1563 PFAST_IO_DISPATCH FastDispatch;
1565 PFS_FILTER_CALLBACKS FilterCallbacks;
1566
1567 /* Get Device Object and Fast Calls */
1568 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
1570
1571 /* Get master FsRtl lock */
1573
1574 DriverExtension = (PEXTENDED_DRIVER_EXTENSION)DeviceObject->DriverObject->DriverExtension;
1575 FilterCallbacks = DriverExtension->FsFilterCallbacks;
1576
1577 /* Check if Filter Cllbacks are supported */
1578 if (FilterCallbacks && FilterCallbacks->PreAcquireForSectionSynchronization)
1579 {
1582
1584
1585 RtlZeroMemory(&CbData, sizeof(CbData));
1586
1587 CbData.SizeOfFsFilterCallbackData = sizeof(CbData);
1589 CbData.DeviceObject = DeviceObject;
1590 CbData.FileObject = FileObject;
1592 CbData.Parameters.AcquireForSectionSynchronization.SyncType = SyncType;
1593
1594 Status = FilterCallbacks->PreAcquireForSectionSynchronization(&CbData, &CompletionContext);
1595 if (!NT_SUCCESS(Status))
1596 {
1598 return Status;
1599 }
1600
1601 /* Should we do something in-between ? */
1602
1603 if (FilterCallbacks->PostAcquireForSectionSynchronization)
1604 {
1606 }
1607
1608 /* Return here when the status is based on the synchonization type and write access to the file */
1612 {
1613 return Status;
1614 }
1615 }
1616
1617 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
1618
1619 /* Check if Fast Calls are supported, and check AcquireFileForNtCreateSection */
1620 if (FastDispatch &&
1621 FastDispatch->AcquireFileForNtCreateSection)
1622 {
1623 /* Call the AcquireFileForNtCreateSection FastIo handler */
1625 }
1626 else
1627 {
1628 /* No FastIo handler, acquire file's resource exclusively */
1629 if (FcbHeader && FcbHeader->Resource) ExAcquireResourceExclusiveLite(FcbHeader->Resource, TRUE);
1630 }
1631
1632 return STATUS_SUCCESS;
1633}
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
struct _FSRTL_COMMON_FCB_HEADER * PFSRTL_COMMON_FCB_HEADER
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
if(dx< 0)
Definition: linetemp.h:194
struct _EXTENDED_DRIVER_EXTENSION * PEXTENDED_DRIVER_EXTENSION
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
#define STATUS_FILE_LOCKED_WITH_ONLY_READERS
Definition: ntstatus.h:111
#define STATUS_FILE_LOCKED_WITH_WRITERS
Definition: ntstatus.h:112
#define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY
Definition: ntstatus.h:110
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
#define STATUS_SUCCESS
Definition: shellext.h:65
PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection
Definition: iotypes.h:1744
PFS_FILTER_COMPLETION_CALLBACK PostAcquireForSectionSynchronization
Definition: iotypes.h:7429
PFS_FILTER_CALLBACK PreAcquireForSectionSynchronization
Definition: iotypes.h:7428
FS_FILTER_PARAMETERS Parameters
Definition: iotypes.h:7411
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:7409
ULONG SizeOfFsFilterCallbackData
Definition: iotypes.h:7406
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:7410
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _FS_FILTER_PARAMETERS::@4097 AcquireForSectionSynchronization
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE _In_opt_ __drv_aliasesMem WDFCONTEXT CompletionContext
Definition: wdfrequest.h:898
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
Definition: iotypes.h:7398

Referenced by FsRtlAcquireFileExclusive(), and FsRtlAcquireToCreateMappedSection().

◆ FsRtlAcquireFileForCcFlush()

VOID NTAPI FsRtlAcquireFileForCcFlush ( IN PFILE_OBJECT  FileObject)

Definition at line 1757 of file fastio.c.

1758{
1759 PAGED_CODE();
1760
1761 /* Call the common routine. Don't care about the result */
1763}
NTSTATUS NTAPI FsRtlAcquireFileForCcFlushEx(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1698

◆ FsRtlAcquireFileForCcFlushEx()

NTSTATUS NTAPI FsRtlAcquireFileForCcFlushEx ( IN PFILE_OBJECT  FileObject)

Definition at line 1698 of file fastio.c.

1699{
1700 PFSRTL_COMMON_FCB_HEADER FcbHeader;
1701 PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
1702 PFAST_IO_DISPATCH FastDispatch;
1704
1705 /* Get the Base File System (Volume) and Fast Calls */
1706 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
1708 BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
1709 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
1710
1711 /* Get master FsRtl lock */
1713
1714 /* Check if Fast Calls are supported, and check AcquireForCcFlush */
1715 if (FastDispatch &&
1716 FastDispatch->AcquireForCcFlush)
1717 {
1718 /* Call the AcquireForCcFlush FastIo handler */
1719 Status = FastDispatch->AcquireForCcFlush(FileObject, BaseDeviceObject);
1720
1721 /* Return either success or inability to wait.
1722 In case of other failure - fall through */
1723 if (NT_SUCCESS(Status))
1724 return Status;
1725
1726 if (Status == STATUS_CANT_WAIT)
1727 {
1728 DPRINT1("STATUS_CANT_WAIT\n");
1730 return Status;
1731 }
1732 }
1733
1734 /* No FastIo handler (or it failed). Acquire Main resource */
1735 if (FcbHeader->Resource)
1736 {
1737 /* Acquire it - either shared if it's already acquired
1738 or exclusively if we are the first */
1741 else
1743 }
1744
1745 /* Also acquire its PagingIO resource */
1746 if (FcbHeader->PagingIoResource)
1748
1749 return STATUS_SUCCESS;
1750}
#define DPRINT1
Definition: precomp.h:8
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1663
PDEVICE_OBJECT NTAPI IoGetBaseFileSystemDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1627
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush
Definition: iotypes.h:1759

Referenced by CcRosFlushVacb(), and FsRtlAcquireFileForCcFlush().

◆ FsRtlAcquireFileForModWriteEx()

_Check_return_ NTSTATUS NTAPI FsRtlAcquireFileForModWriteEx ( _In_ PFILE_OBJECT  FileObject,
_In_ PLARGE_INTEGER  EndingOffset,
_Outptr_result_maybenull_ PERESOURCE ResourceToRelease 
)

Lock a file object before flushing pages to disk. To be called by the Modified Page Writer (MPW)

Parameters
FileObject- The file object to lock
EndingOffset- The end offset of the write to be done
ResourceToRelease- Pointer receiving the resource to release after the write
Returns
Relevant NTSTATUS value

Definition at line 1858 of file fastio.c.

1861{
1862 PFSRTL_COMMON_FCB_HEADER FcbHeader;
1863 PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
1864 PFAST_IO_DISPATCH FastDispatch;
1865 PERESOURCE ResourceToAcquire = NULL;
1869
1870 /* Get Device Object and Fast Calls */
1871 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
1873 BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
1874 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
1875
1876 /* Check if Fast Calls are supported, and check AcquireForModWrite */
1877 if (FastDispatch &&
1878 FastDispatch->AcquireForModWrite)
1879 {
1880 /* Call the AcquireForModWrite FastIo handler */
1881 Status = FastDispatch->AcquireForModWrite(FileObject,
1884 BaseDeviceObject);
1885
1886 /* Return either success or inability to wait.
1887 In case of other failure - fall through */
1888 if (Status == STATUS_SUCCESS ||
1890 {
1891 return Status;
1892 }
1893 }
1894
1895 /* Check what and how we should acquire */
1896 Exclusive = FsRtlpGetResourceForModWrite(FcbHeader, EndingOffset, &ResourceToAcquire);
1897
1898 /* Acquire the resource and loop until we're sure we got this right. */
1899 while (TRUE)
1900 {
1901 BOOLEAN OldExclusive;
1902 PERESOURCE OldResourceToAcquire;
1903
1904 if (ResourceToAcquire == NULL)
1905 {
1906 /*
1907 * There's nothing to acquire, we can simply return success
1908 */
1909
1910 break;
1911 }
1912
1913 if (Exclusive)
1914 {
1915 Result = ExAcquireResourceExclusiveLite(ResourceToAcquire, FALSE);
1916 }
1917 else
1918 {
1919 Result = ExAcquireSharedWaitForExclusive(ResourceToAcquire, FALSE);
1920 }
1921
1922 if (!Result)
1923 {
1924 return STATUS_CANT_WAIT;
1925 }
1926
1927 /* Does this still hold true? */
1928 OldExclusive = Exclusive;
1929 OldResourceToAcquire = ResourceToAcquire;
1930 Exclusive = FsRtlpGetResourceForModWrite(FcbHeader, EndingOffset, &ResourceToAcquire);
1931
1932 if ((OldExclusive == Exclusive) && (OldResourceToAcquire == ResourceToAcquire))
1933 {
1934 /* We're good */
1935 break;
1936 }
1937
1938 /* Can we fix this situation? */
1939 if ((OldResourceToAcquire == ResourceToAcquire) && !Exclusive)
1940 {
1941 /* We can easily do so */
1942 ExConvertExclusiveToSharedLite(ResourceToAcquire);
1943 break;
1944 }
1945
1946 /* Things have changed since we acquired the lock. Start again */
1947 ExReleaseResourceLite(OldResourceToAcquire);
1948 }
1949
1950 /* If we're here, this means that we succeeded */
1951 *ResourceToRelease = ResourceToAcquire;
1952 return STATUS_SUCCESS;
1953}
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define ExConvertExclusiveToSharedLite(res)
Definition: env_spec_w32.h:652
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
__in PWDFDEVICE_INIT __in BOOLEAN Exclusive
BOOLEAN NTAPI ExAcquireSharedWaitForExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1222
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
static BOOLEAN FsRtlpGetResourceForModWrite(_In_ PFSRTL_COMMON_FCB_HEADER FcbHeader, _In_ PLARGE_INTEGER EndingOffset, _Outptr_result_maybenull_ PERESOURCE *ResourceToAcquire)
Get the resource to acquire when Mod Writer flushes data to disk.
Definition: fastio.c:1815
PFAST_IO_ACQUIRE_FOR_MOD_WRITE AcquireForModWrite
Definition: iotypes.h:1748
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_In_ PLARGE_INTEGER _Out_ struct _ERESOURCE ** ResourceToRelease
Definition: iotypes.h:1598
_In_ PLARGE_INTEGER EndingOffset
Definition: iotypes.h:1597

◆ FsRtlAcquireToCreateMappedSection()

NTSTATUS NTAPI FsRtlAcquireToCreateMappedSection ( _In_ PFILE_OBJECT  FileObject,
_In_ ULONG  SectionPageProtection 
)

Definition at line 1653 of file fastio.c.

1655{
1656 PAGED_CODE();
1657
1659}
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:363
@ SyncTypeCreateSection
Definition: iotypes.h:7365

Referenced by MmCreateArm3Section(), and MmCreateSection().

◆ FsRtlCopyRead()

BOOLEAN NTAPI FsRtlCopyRead ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN BOOLEAN  Wait,
IN ULONG  LockKey,
OUT PVOID  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 64 of file fastio.c.

72{
73
80
81 PAGED_CODE();
83 ASSERT(FileObject->FsContext);
84
85 /* No actual read */
86 if (!Length)
87 {
88 /* Return success */
89 IoStatus->Status = STATUS_SUCCESS;
90 IoStatus->Information = 0;
91 return TRUE;
92 }
93
94 if (Length > MAXLONGLONG - FileOffset->QuadPart)
95 {
97 IoStatus->Information = 0;
98 return FALSE;
99 }
100
101 /* Get the offset and FCB header */
102 Offset.QuadPart = FileOffset->QuadPart + Length;
103 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
104
105 if (Wait)
106 {
107 /* Use a Resource Acquire */
111 }
112 else
113 {
114 /* Acquire the resource without blocking. Return false and the I/O manager
115 * will retry using the standard IRP method. Use a Resource Acquire.
116 */
119 {
122 return FALSE;
123 }
124 }
125
126 /* Check if this is a fast I/O cached file */
127 if (!(FileObject->PrivateCacheMap) ||
129 {
130 /* It's not, so fail */
131 Result = FALSE;
132 goto Cleanup;
133 }
134
135 /* Check if we need to find out if fast I/O is available */
136 if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable)
137 {
138 /* Sanity check */
140
141 /* Get the Fast I/O table */
143 FastIoDispatch = Device->DriverObject->FastIoDispatch;
144
145 /* Sanity check */
148
149 /* Ask the driver if we can do it */
152 Length,
153 TRUE,
154 LockKey,
155 TRUE,
156 IoStatus,
157 Device))
158 {
159 /* It's not, fail */
160 Result = FALSE;
161 goto Cleanup;
162 }
163 }
164
165 /* Check if we read too much */
166 if (Offset.QuadPart > FcbHeader->FileSize.QuadPart)
167 {
168 /* We did, check if the file offset is past the end */
169 if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart)
170 {
171 /* Set end of file */
173 IoStatus->Information = 0;
174 goto Cleanup;
175 }
176
177 /* Otherwise, just normalize the length */
178 Length = (ULONG)(FcbHeader->FileSize.QuadPart - FileOffset->QuadPart);
179 }
180
181 /* Set this as top-level IRP */
183
185 {
186 /* Make sure the IO and file size is below 4GB */
187 if (Wait && !(Offset.HighPart | FcbHeader->FileSize.HighPart))
188 {
189
190 /* Call the cache controller */
192 FileOffset->LowPart,
193 Length,
194 PageCount,
195 Buffer,
196 IoStatus);
197
198 /* File was accessed */
200
201 if (IoStatus->Status != STATUS_END_OF_FILE)
202 {
203 ASSERT((ULONGLONG)FcbHeader->FileSize.QuadPart >=
204 ((ULONGLONG)FileOffset->QuadPart + IoStatus->Information));
205 }
206 }
207 else
208 {
209
210 /* Call the cache controller */
213 Length,
214 Wait,
215 Buffer,
216 IoStatus);
217
218 /* File was accessed */
220
221 if (Result != FALSE)
222 {
223 ASSERT((IoStatus->Status == STATUS_END_OF_FILE) ||
224 (((ULONGLONG)FileOffset->QuadPart + IoStatus->Information) <=
225 (ULONGLONG)FcbHeader->FileSize.QuadPart));
226 }
227 }
228
229 /* Update the current file offset */
230 if (Result != FALSE)
231 {
232 FileObject->CurrentByteOffset.QuadPart = FileOffset->QuadPart + IoStatus->Information;
233 }
234 }
237 {
238 Result = FALSE;
239 }
240 _SEH2_END;
241
242 PsGetCurrentThread()->TopLevelIrp = 0;
243
244 /* Return to caller */
245Cleanup:
246
249
250 if (Result == FALSE)
251 {
253 }
254
255 return Result;
256}
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
Definition: bufpool.h:45
static const WCHAR Cleanup[]
Definition: register.c:80
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
Definition: dpc.c:965
FAST_IO_DISPATCH FastIoDispatch
Definition: fastio.c:20
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2666
@ FastIoIsQuestionable
Definition: fsrtltypes.h:242
@ FastIoIsNotPossible
Definition: fsrtltypes.h:240
#define FSRTL_FAST_IO_TOP_LEVEL_IRP
Definition: fsrtltypes.h:62
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define ASSERT(a)
Definition: mode.c:44
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define MAXLONGLONG
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:43
ULONG CcFastReadNotPossible
Definition: copysup.c:21
VOID NTAPI CcFastCopyRead(IN PFILE_OBJECT FileObject, IN ULONG FileOffset, IN ULONG Length, IN ULONG PageCount, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:117
ULONG CcFastReadWait
Definition: copysup.c:22
VOID NTAPI FsRtlIncrementCcFastReadResourceMiss(VOID)
Definition: fastio.c:24
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define STATUS_END_OF_FILE
Definition: shellext.h:67
PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible
Definition: iotypes.h:1734
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1795
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)

Referenced by CdInitializeGlobalData(), Ext2FastIoRead(), FsRtlTest_StartTest(), init_fast_io_dispatch(), and UDFInitializeFunctionPointers().

◆ FsRtlCopyWrite()

BOOLEAN NTAPI FsRtlCopyWrite ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN BOOLEAN  Wait,
IN ULONG  LockKey,
OUT PVOID  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 264 of file fastio.c.

272{
276 PFSRTL_COMMON_FCB_HEADER FcbHeader;
277 PSHARED_CACHE_MAP SharedCacheMap;
278
279 /* WDK doc.
280 * Offset == 0xffffffffffffffff indicates append to the end of file.
281 */
282 BOOLEAN FileOffsetAppend = (FileOffset->HighPart == (LONG)0xffffffff) &&
283 (FileOffset->LowPart == 0xffffffff);
284
285 BOOLEAN ResourceAcquiredShared = FALSE;
286 BOOLEAN b_4GB = FALSE;
287 BOOLEAN FileSizeModified = FALSE;
288 LARGE_INTEGER OldFileSize;
289 LARGE_INTEGER OldValidDataLength;
292
293 PAGED_CODE();
294
296 ASSERT(FileObject->FsContext);
297
298 /* Initialize some of the vars and pointers */
299 NewSize.QuadPart = 0;
300 Offset.QuadPart = FileOffset->QuadPart + Length;
301 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
302
303 /* Nagar p.544.
304 * Check with Cc if we can write and check if the IO > 64kB (WDK macro).
305 */
308 ((FileObject->Flags & FO_WRITE_THROUGH)))
309 {
310 return FALSE;
311 }
312
313 /* Already init IO_STATUS_BLOCK */
314 IoStatus->Status = STATUS_SUCCESS;
315 IoStatus->Information = Length;
316
317 /* No actual read */
318 if (!Length)
319 {
320 return TRUE;
321 }
322
324
325 /* Nagar p.544/545.
326 * The CcFastCopyWrite doesn't deal with filesize beyond 4GB.
327 */
328 if (Wait && (FcbHeader->AllocationSize.HighPart == 0))
329 {
330 /* If the file offset is not past the file size,
331 * then we can acquire the lock shared.
332 */
333 if ((FileOffsetAppend == FALSE) &&
334 (Offset.LowPart <= FcbHeader->ValidDataLength.LowPart))
335 {
337 ResourceAcquiredShared = TRUE;
338 }
339 else
340 {
342 }
343
344 /* Nagar p.544/545.
345 * If we append, use the file size as offset.
346 * Also, check that we aren't crossing the 4GB boundary.
347 */
348 if (FileOffsetAppend != FALSE)
349 {
350 Offset.LowPart = FcbHeader->FileSize.LowPart;
351 NewSize.LowPart = FcbHeader->FileSize.LowPart + Length;
352 b_4GB = (NewSize.LowPart < FcbHeader->FileSize.LowPart);
353
354 }
355 else
356 {
357 Offset.LowPart = FileOffset->LowPart;
358 NewSize.LowPart = FileOffset->LowPart + Length;
359 b_4GB = (NewSize.LowPart < FileOffset->LowPart) ||
360 (FileOffset->HighPart != 0);
361 }
362
363 /* Nagar p.544/545.
364 * Make sure that caching is initated.
365 * That fast are allowed for this file stream.
366 * That we are not extending past the allocated size.
367 * That we are not creating a hole bigger than 8k.
368 * That we are not crossing the 4GB boundary.
369 */
370 if ((FileObject->PrivateCacheMap != NULL) &&
371 (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) &&
372 (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) &&
373 (Offset.LowPart < FcbHeader->ValidDataLength.LowPart + 0x2000) &&
374 !b_4GB)
375 {
376 /* If we are extending past the file size, we need to
377 * release the lock and acquire it exclusively, because
378 * we are going to need to update the FcbHeader.
379 */
380 if (ResourceAcquiredShared &&
381 (NewSize.LowPart > FcbHeader->ValidDataLength.LowPart + 0x2000))
382 {
383 /* Then we need to acquire the resource exclusive */
386 if (FileOffsetAppend != FALSE)
387 {
388 Offset.LowPart = FcbHeader->FileSize.LowPart; // ??
389 NewSize.LowPart = FcbHeader->FileSize.LowPart + Length;
390
391 /* Make sure we don't cross the 4GB boundary */
392 b_4GB = (NewSize.LowPart < Offset.LowPart);
393 }
394
395 /* Recheck some of the conditions since we let the lock go */
396 if ((FileObject->PrivateCacheMap != NULL) &&
397 (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) &&
398 (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) &&
399 (FcbHeader->AllocationSize.HighPart == 0) &&
400 !b_4GB)
401 {
402 /* Do nothing? */
403 }
404 else
405 {
406 goto FailAndCleanup;
407 }
408 }
409
410 }
411 else
412 {
413 goto FailAndCleanup;
414 }
415
416 /* Check if we need to find out if fast I/O is available */
417 if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable)
418 {
419 IO_STATUS_BLOCK FastIoCheckIfPossibleStatus;
420
421 /* Sanity check */
423
424 /* Get the Fast I/O table */
426 FastIoDispatch = Device->DriverObject->FastIoDispatch;
427
428 /* Sanity check */
431
432 /* Ask the driver if we can do it */
434 FileOffsetAppend ?
435 &FcbHeader->FileSize :
437 Length,
438 TRUE,
439 LockKey,
440 FALSE,
441 &FastIoCheckIfPossibleStatus,
442 Device))
443 {
444 /* It's not, fail */
445 goto FailAndCleanup;
446 }
447 }
448
449 /* If we are going to extend the file then save
450 * the old file size in case the operation fails.
451 */
452 if (NewSize.LowPart > FcbHeader->FileSize.LowPart)
453 {
454 FileSizeModified = TRUE;
455 OldFileSize.LowPart = FcbHeader->FileSize.LowPart;
456 OldValidDataLength.LowPart = FcbHeader->ValidDataLength.LowPart;
457 FcbHeader->FileSize.LowPart = NewSize.LowPart;
458 }
459
460 /* Set this as top-level IRP */
462
464 {
465 if (Offset.LowPart > FcbHeader->ValidDataLength.LowPart)
466 {
467 LARGE_INTEGER OffsetVar;
468 OffsetVar.LowPart = Offset.LowPart;
469 OffsetVar.HighPart = 0;
470 CcZeroData(FileObject, &FcbHeader->ValidDataLength, &OffsetVar, TRUE);
471 }
472
473 /* Call the cache manager */
475 }
479 {
480 Result = FALSE;
481 }
482 _SEH2_END;
483
484 /* Remove ourselves at the top level component after the IO is done */
485 PsGetCurrentThread()->TopLevelIrp = 0;
486
487 /* Did the operation succeed? */
488 if (Result != FALSE)
489 {
490 /* Update the valid file size if necessary */
491 if (NewSize.LowPart > FcbHeader->ValidDataLength.LowPart)
492 {
493 FcbHeader->ValidDataLength.LowPart = NewSize.LowPart;
494 }
495
496 /* Flag the file as modified */
498
499 /* Update the strucutres if the file size changed */
500 if (FileSizeModified)
501 {
502 SharedCacheMap =
503 (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
504 SharedCacheMap->FileSize.LowPart = NewSize.LowPart;
506 }
507
508 /* Update the file object current file offset */
509 FileObject->CurrentByteOffset.QuadPart = NewSize.LowPart;
510
511 }
512 else
513 {
514 /* Result == FALSE if we get here */
515 if (FileSizeModified)
516 {
517 /* If the file size was modified then restore the old file size */
518 if (FcbHeader->PagingIoResource != NULL)
519 {
520 /* Nagar P.544.
521 * Restore the old file size if operation didn't succeed.
522 */
524 FcbHeader->FileSize.LowPart = OldFileSize.LowPart;
525 FcbHeader->ValidDataLength.LowPart = OldValidDataLength.LowPart;
527 }
528 else
529 {
530 /* If there is no lock and do it without */
531 FcbHeader->FileSize.LowPart = OldFileSize.LowPart;
532 FcbHeader->ValidDataLength.LowPart = OldValidDataLength.LowPart;
533 }
534 }
535 else
536 {
537 /* Do nothing? */
538 }
539 }
540
541 goto Cleanup;
542 }
543 else
544 {
545 LARGE_INTEGER OldFileSize;
546
547 /* Sanity check */
549
550 /* Nagar P.544.
551 * Check if we need to acquire the resource exclusive.
552 */
553 if ((FileOffsetAppend == FALSE) &&
554 (FileOffset->QuadPart + Length <= FcbHeader->ValidDataLength.QuadPart))
555 {
556 /* Acquire the resource shared */
557 if (!ExAcquireResourceSharedLite(FcbHeader->Resource, Wait))
558 {
559 goto LeaveCriticalAndFail;
560 }
561 ResourceAcquiredShared = TRUE;
562 }
563 else
564 {
565 /* Acquire the resource exclusive */
567 {
568 goto LeaveCriticalAndFail;
569 }
570 }
571
572 /* Check if we are appending */
573 if (FileOffsetAppend != FALSE)
574 {
575 Offset.QuadPart = FcbHeader->FileSize.QuadPart;
576 NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length;
577 }
578 else
579 {
580 Offset.QuadPart = FileOffset->QuadPart;
581 NewSize.QuadPart += FileOffset->QuadPart + Length;
582 }
583
584 /* Nagar p.544/545.
585 * Make sure that caching is initated.
586 * That fast are allowed for this file stream.
587 * That we are not extending past the allocated size.
588 * That we are not creating a hole bigger than 8k.
589 */
590 if ((FileObject->PrivateCacheMap != NULL) &&
591 (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) &&
592 (FcbHeader->ValidDataLength.QuadPart + 0x2000 > Offset.QuadPart) &&
593 (Length <= MAXLONGLONG - Offset.QuadPart) &&
594 (FcbHeader->AllocationSize.QuadPart >= NewSize.QuadPart))
595 {
596 /* Check if we can keep the lock shared */
597 if (ResourceAcquiredShared &&
598 (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart))
599 {
602 {
603 goto LeaveCriticalAndFail;
604 }
605
606 /* Compute the offset and the new filesize */
607 if (FileOffsetAppend)
608 {
609 Offset.QuadPart = FcbHeader->FileSize.QuadPart;
610 NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length;
611 }
612
613 /* Recheck the above points since we released and reacquire the lock */
614 if ((FileObject->PrivateCacheMap != NULL) &&
615 (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) &&
616 (FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart))
617 {
618 /* Do nothing */
619 }
620 else
621 {
622 goto FailAndCleanup;
623 }
624 }
625
626 /* Check if we need to find out if fast I/O is available */
627 if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable)
628 {
629 IO_STATUS_BLOCK FastIoCheckIfPossibleStatus;
630
631 /* Sanity check */
633
634 /* Get the Fast I/O table */
636 FastIoDispatch = Device->DriverObject->FastIoDispatch;
637
638 /* Sanity check */
641
642 /* Ask the driver if we can do it */
644 FileOffsetAppend ?
645 &FcbHeader->FileSize :
647 Length,
648 Wait,
649 LockKey,
650 FALSE,
651 &FastIoCheckIfPossibleStatus,
652 Device))
653 {
654 /* It's not, fail */
655 goto FailAndCleanup;
656 }
657 }
658
659 /* If we are going to modify the filesize,
660 * save the old fs in case the operation fails.
661 */
662 if (NewSize.QuadPart > FcbHeader->FileSize.QuadPart)
663 {
664 FileSizeModified = TRUE;
665 OldFileSize.QuadPart = FcbHeader->FileSize.QuadPart;
666 OldValidDataLength.QuadPart = FcbHeader->ValidDataLength.QuadPart;
667
668 /* If the high part of the filesize is going
669 * to change, grab the Paging IoResouce.
670 */
671 if (NewSize.HighPart != FcbHeader->FileSize.HighPart &&
672 FcbHeader->PagingIoResource)
673 {
675 FcbHeader->FileSize.QuadPart = NewSize.QuadPart;
677 }
678 else
679 {
680 FcbHeader->FileSize.QuadPart = NewSize.QuadPart;
681 }
682 }
683
684 /* Nagar p.544.
685 * Set ourselves as top component.
686 */
688
690 {
691 BOOLEAN CallCc = TRUE;
692
693 /* Check if there is a gap between the end of the file
694 * and the offset. If yes, then we have to zero the data.
695 */
696 if (Offset.QuadPart > FcbHeader->ValidDataLength.QuadPart)
697 {
699 &FcbHeader->ValidDataLength,
700 &Offset,
701 Wait)))
702 {
703 /* If this operation fails, then we have to exit. We can't jump
704 * outside the SEH, so I am using a variable to exit normally.
705 */
706 CallCc = FALSE;
707 }
708 }
709
710 /* Unless the CcZeroData failed, call the cache manager */
711 if (CallCc)
712 {
714 }
715 }
719 {
720 Result = FALSE;
721 }
722 _SEH2_END;
723
724 /* Reset the top component */
726
727 /* Did the operation suceeded */
728 if (Result)
729 {
730 /* Check if we need to update the filesize */
731 if (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart)
732 {
733 if (NewSize.HighPart != FcbHeader->ValidDataLength.HighPart &&
734 FcbHeader->PagingIoResource)
735 {
737 FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart;
739 }
740 else
741 {
742 FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart;
743 }
744 }
745
746 /* Flag the file as modified */
748
749 /* Check if the filesize has changed */
750 if (FileSizeModified)
751 {
752 /* Update the file sizes */
753 SharedCacheMap =
754 (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
755 SharedCacheMap->FileSize.QuadPart = NewSize.QuadPart;
757 }
758
759 /* Update the current FO byte offset */
760 FileObject->CurrentByteOffset.QuadPart = NewSize.QuadPart;
761 }
762 else
763 {
764 /* The operation did not succeed.
765 * Reset the file size to what it should be.
766 */
767 if (FileSizeModified)
768 {
769 if (FcbHeader->PagingIoResource)
770 {
772 FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart;
773 FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart;
775 }
776 else
777 {
778 FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart;
779 FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart;
780 }
781 }
782 }
783
784 goto Cleanup;
785 }
786 else
787 {
788 goto FailAndCleanup;
789 }
790 }
791
792LeaveCriticalAndFail:
793
795 return FALSE;
796
797FailAndCleanup:
798
801 return FALSE;
802
803Cleanup:
804
807 return Result;
808}
NTKERNELAPI BOOLEAN NTAPI CcCopyWriteWontFlush(_In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER FileOffset, _In_ ULONG Length)
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:414
VOID NTAPI CcFastCopyWrite(IN PFILE_OBJECT FileObject, IN ULONG FileOffset, IN ULONG Length, IN PVOID Buffer)
Definition: copysup.c:204
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
long LONG
Definition: pedump.c:60
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
ULONG LowPart
Definition: typedefs.h:106
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1789

Referenced by _Function_class_(), Ext2FastIoWrite(), FsRtlTest_StartTest(), and UDFFastIoCopyWrite().

◆ FsRtlGetFileSize()

NTSTATUS NTAPI FsRtlGetFileSize ( IN PFILE_OBJECT  FileObject,
IN OUT PLARGE_INTEGER  FileSize 
)

Definition at line 815 of file fastio.c.

817{
822 PFAST_IO_DISPATCH FastDispatch;
824 PIO_STACK_LOCATION IoStackLocation;
825 PIRP Irp;
826 BOOLEAN OldHardError;
827
828 PAGED_CODE();
829
830 /* Get Device Object and Fast Calls */
832 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
833
834 /* Check if we support Fast Calls, and check FastIoQueryStandardInfo.
835 * Call the function and see if it succeeds.
836 */
837 if (!FastDispatch ||
838 !FastDispatch->FastIoQueryStandardInfo ||
839 !FastDispatch->FastIoQueryStandardInfo(FileObject,
840 TRUE,
841 &Info,
842 &IoStatus,
844 {
845 /* If any of the above failed, then we are going to send an
846 * IRP to the device object. Initialize the event for the IO.
847 */
849
850 /* Allocate the IRP */
851 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
852
853 if (Irp == NULL)
854 {
856 }
857
858 /* Don't process hard error */
859 OldHardError = IoSetThreadHardErrorMode(FALSE);
860
861 /* Setup the IRP */
862 Irp->UserIosb = &IoStatus;
863 Irp->UserEvent = &Event;
864 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
866 Irp->RequestorMode = KernelMode;
867 Irp->Tail.Overlay.OriginalFileObject = FileObject;
868 Irp->AssociatedIrp.SystemBuffer = &Info;
869
870 /* Setup out stack location */
871 IoStackLocation = Irp->Tail.Overlay.CurrentStackLocation;
872 IoStackLocation--;
873 IoStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
874 IoStackLocation->FileObject = FileObject;
875 IoStackLocation->DeviceObject = DeviceObject;
876 IoStackLocation->Parameters.QueryFile.Length =
878 IoStackLocation->Parameters.QueryFile.FileInformationClass =
880
881 /* Send the IRP to the related device object */
883
884 /* Standard DDK IRP result processing */
885 if (Status == STATUS_PENDING)
886 {
888 }
889
890 /* If there was a synchronous error, signal it */
891 if (!NT_SUCCESS(Status))
892 {
893 IoStatus.Status = Status;
894 }
895
896 IoSetThreadHardErrorMode(OldHardError);
897 }
898
899 /* Check the sync/async IO result */
900 if (NT_SUCCESS(IoStatus.Status))
901 {
902 /* Was the request for a directory? */
903 if (Info.Directory)
904 {
906 }
907 else
908 {
909 FileSize->QuadPart = Info.EndOfFile.QuadPart;
910 }
911 }
912
913 return IoStatus.Status;
914}
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:726
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define FileStandardInformation
Definition: propsheet.cpp:61
PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo
Definition: iotypes.h:1738
struct _IO_STACK_LOCATION::@3980::@3989 QueryFile
union _IO_STACK_LOCATION::@1581 Parameters
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
#define IRP_PAGING_IO
#define IRP_SYNCHRONOUS_PAGING_IO
@ Executive
Definition: ketypes.h:415

Referenced by FsRtlTest_StartTest(), and MmCreateDataFileSection().

◆ FsRtlIncrementCcFastReadNotPossible()

VOID NTAPI FsRtlIncrementCcFastReadNotPossible ( VOID  )

Definition at line 34 of file fastio.c.

35{
37}

◆ FsRtlIncrementCcFastReadNoWait()

VOID NTAPI FsRtlIncrementCcFastReadNoWait ( VOID  )

Definition at line 54 of file fastio.c.

55{
57}
ULONG CcFastReadNoWait
Definition: copysup.c:23

◆ FsRtlIncrementCcFastReadResourceMiss()

VOID NTAPI FsRtlIncrementCcFastReadResourceMiss ( VOID  )

Definition at line 24 of file fastio.c.

25{
27}
ULONG CcFastReadResourceMiss
Definition: copysup.c:24

Referenced by FsRtlCopyRead().

◆ FsRtlIncrementCcFastReadWait()

VOID NTAPI FsRtlIncrementCcFastReadWait ( VOID  )

Definition at line 44 of file fastio.c.

45{
47}

◆ FsRtlMdlRead()

BOOLEAN NTAPI FsRtlMdlRead ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN ULONG  LockKey,
OUT PMDL MdlChain,
OUT PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 921 of file fastio.c.

927{
928 PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
929 PFAST_IO_DISPATCH FastDispatch;
930
931 /* Get Device Object and Fast Calls */
933 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
934
935 /* Check if we support Fast Calls, and check this one */
936 if (FastDispatch && FastDispatch->MdlRead)
937 {
938 /* Use the fast path */
939 return FastDispatch->MdlRead(FileObject,
941 Length,
942 LockKey,
943 MdlChain,
944 IoStatus,
946 }
947
948 /* Get the Base File System (Volume) and Fast Calls */
950 FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
951
952 /* If the Base Device Object has its own FastDispatch Routine, fail */
953 if (FastDispatch && FastDispatch->MdlRead && BaseDeviceObject != DeviceObject)
954 {
955 return FALSE;
956 }
957
958 /* No fast path, use slow path */
961 Length,
962 LockKey,
963 MdlChain,
964 IoStatus,
966}
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _Outptr_ PMDL * MdlChain
Definition: fsrtlfuncs.h:49
BOOLEAN NTAPI FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:1025
PFAST_IO_MDL_READ MdlRead
Definition: iotypes.h:1749

Referenced by FsRtlTest_StartTest().

◆ FsRtlMdlReadComplete()

BOOLEAN NTAPI FsRtlMdlReadComplete ( IN PFILE_OBJECT  FileObject,
IN OUT PMDL  MdlChain 
)

Definition at line 973 of file fastio.c.

975{
976 PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
977 PFAST_IO_DISPATCH FastDispatch;
978
979 /* Get Device Object and Fast Calls */
981 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
982
983 /* Check if we support Fast Calls, and check this one */
984 if (FastDispatch && FastDispatch->MdlReadComplete)
985 {
986 /* Use the fast path */
987 return FastDispatch->MdlReadComplete(FileObject, MdlChain, DeviceObject);
988 }
989
990 /* Get the Base File System (Volume) and Fast Calls */
992 FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
993
994 /* If the Base Device Object has its own FastDispatch Routine, fail */
995 if ((BaseDeviceObject != DeviceObject) &&
996 FastDispatch &&
997 FastDispatch->MdlReadComplete)
998 {
999 return FALSE;
1000 }
1001
1002 /* No fast path, use slow path */
1004}
BOOLEAN NTAPI FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, IN PMDL MemoryDescriptorList, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:1011
PFAST_IO_MDL_READ_COMPLETE MdlReadComplete
Definition: iotypes.h:1750

Referenced by FsRtlTest_StartTest().

◆ FsRtlMdlReadCompleteDev()

BOOLEAN NTAPI FsRtlMdlReadCompleteDev ( IN PFILE_OBJECT  FileObject,
IN PMDL  MemoryDescriptorList,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 1011 of file fastio.c.

1014{
1015 /* Call the Cache Manager */
1017 return TRUE;
1018}
VOID NTAPI CcMdlReadComplete2(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:83
_Inout_ PMDL MemoryDescriptorList
Definition: mmfuncs.h:405

Referenced by CdInitializeGlobalData(), FsRtlMdlReadComplete(), FsRtlTest_StartTest(), and init_fast_io_dispatch().

◆ FsRtlMdlReadDev()

BOOLEAN NTAPI FsRtlMdlReadDev ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN ULONG  LockKey,
OUT PMDL MdlChain,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 1025 of file fastio.c.

1032{
1033 PFSRTL_COMMON_FCB_HEADER FcbHeader;
1038 PAGED_CODE();
1039
1040 /* No actual read */
1041 if (!Length)
1042 {
1043 /* Return success */
1044 IoStatus->Status = STATUS_SUCCESS;
1045 IoStatus->Information = 0;
1046 return TRUE;
1047 }
1048
1049 /* Sanity check */
1050 ASSERT(MAXLONGLONG - FileOffset->QuadPart >= (LONGLONG)Length);
1051
1052 /* Get the offset and FCB header */
1053 Offset.QuadPart = FileOffset->QuadPart + Length;
1054 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
1055
1056 /* Enter the FS */
1059
1060 /* Lock the FCB */
1062
1063 /* Check if this is a fast I/O cached file */
1064 if (!(FileObject->PrivateCacheMap) ||
1065 (FcbHeader->IsFastIoPossible == FastIoIsNotPossible))
1066 {
1067 /* It's not, so fail */
1069 Result = FALSE;
1070 goto Cleanup;
1071 }
1072
1073 /* Check if we need to find out if fast I/O is available */
1074 if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable)
1075 {
1076 /* Get the Fast I/O table */
1078 FastIoDispatch = Device->DriverObject->FastIoDispatch;
1079
1080 /* Sanity check */
1084
1085 /* Ask the driver if we can do it */
1087 FileOffset,
1088 Length,
1089 TRUE,
1090 LockKey,
1091 TRUE,
1092 IoStatus,
1093 Device))
1094 {
1095 /* It's not, fail */
1097 Result = FALSE;
1098 goto Cleanup;
1099 }
1100 }
1101
1102 /* Check if we read too much */
1103 if (Offset.QuadPart > FcbHeader->FileSize.QuadPart)
1104 {
1105 /* We did, check if the file offset is past the end */
1106 if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart)
1107 {
1108 /* Set end of file */
1109 IoStatus->Status = STATUS_END_OF_FILE;
1110 IoStatus->Information = 0;
1111 goto Cleanup;
1112 }
1113
1114 /* Otherwise, just normalize the length */
1115 Length = (ULONG)(FcbHeader->FileSize.QuadPart - FileOffset->QuadPart);
1116 }
1117
1118 /* Set this as top-level IRP */
1120
1121 _SEH2_TRY
1122 {
1123 /* Attempt a read */
1126 }
1130 {
1131 Result = FALSE;
1132 }
1133 _SEH2_END;
1134
1135
1136 /* Remove the top-level IRP flag */
1137 PsGetCurrentThread()->TopLevelIrp = 0;
1138
1139 /* Return to caller */
1140Cleanup:
1141
1142 ExReleaseResourceLite(FcbHeader->Resource);
1144
1145 return Result;
1146}
VOID NTAPI CcMdlRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:64
ULONG CcFastMdlReadNotPossible
Definition: copysup.c:20
ULONG CcFastMdlReadWait
Definition: copysup.c:19
int64_t LONGLONG
Definition: typedefs.h:68
#define ExAcquireResourceShared
Definition: exfuncs.h:343

Referenced by CdInitializeGlobalData(), FsRtlMdlRead(), FsRtlTest_StartTest(), and init_fast_io_dispatch().

◆ FsRtlMdlWriteComplete()

BOOLEAN NTAPI FsRtlMdlWriteComplete ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN PMDL  MdlChain 
)

Definition at line 1153 of file fastio.c.

1156{
1157 PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
1158 PFAST_IO_DISPATCH FastDispatch;
1159
1160 /* Get Device Object and Fast Calls */
1162 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
1163
1164 /* Check if we support Fast Calls, and check this one */
1165 if (FastDispatch && FastDispatch->MdlWriteComplete)
1166 {
1167 /* Use the fast path */
1168 return FastDispatch->MdlWriteComplete(FileObject,
1169 FileOffset,
1170 MdlChain,
1171 DeviceObject);
1172 }
1173
1174 /* Get the Base File System (Volume) and Fast Calls */
1175 BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
1176 FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
1177
1178 /* If the Base Device Object has its own FastDispatch Routine, fail */
1179 if (FastDispatch &&
1180 FastDispatch->MdlWriteComplete &&
1181 BaseDeviceObject != DeviceObject)
1182 {
1183 return FALSE;
1184 }
1185
1186 /* No fast path, use slow path */
1188 FileOffset,
1189 MdlChain,
1190 DeviceObject);
1191}
BOOLEAN NTAPI FsRtlMdlWriteCompleteDev(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:1198
PFAST_IO_MDL_WRITE_COMPLETE MdlWriteComplete
Definition: iotypes.h:1752

Referenced by FsRtlTest_StartTest().

◆ FsRtlMdlWriteCompleteDev()

BOOLEAN NTAPI FsRtlMdlWriteCompleteDev ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN PMDL  MdlChain,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 1198 of file fastio.c.

1202{
1203 if (FileObject->Flags & FO_WRITE_THROUGH)
1204 {
1205 return FALSE;
1206 }
1207
1208 /* Call the Cache Manager */
1210 return TRUE;
1211}
VOID NTAPI CcMdlWriteComplete2(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:111

Referenced by CdInitializeGlobalData(), FsRtlMdlWriteComplete(), FsRtlTest_StartTest(), and init_fast_io_dispatch().

◆ FsRtlpGetResourceForModWrite()

static BOOLEAN FsRtlpGetResourceForModWrite ( _In_ PFSRTL_COMMON_FCB_HEADER  FcbHeader,
_In_ PLARGE_INTEGER  EndingOffset,
_Outptr_result_maybenull_ PERESOURCE ResourceToAcquire 
)
static

Get the resource to acquire when Mod Writer flushes data to disk.

Parameters
FcbHeader- FCB header from the file object
EndingOffset- The end offset of the write to be done
ResourceToAcquire- Pointer receiving the resource to acquire before doing the write
Returns
BOOLEAN specifying whether the resource must be acquired exclusively

Definition at line 1815 of file fastio.c.

1818{
1819 /*
1820 * Decide on type of locking and type of resource based on
1821 * - Flags
1822 * - Whether we're extending ValidDataLength
1823 */
1824 if (FlagOn(FcbHeader->Flags, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX))
1825 {
1826 /* Acquire main resource, exclusive */
1827 *ResourceToAcquire = FcbHeader->Resource;
1828 return TRUE;
1829 }
1830
1831 /* We will acquire shared. Which one ? */
1832 if (FlagOn(FcbHeader->Flags, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH))
1833 {
1834 *ResourceToAcquire = FcbHeader->Resource;
1835 }
1836 else
1837 {
1838 *ResourceToAcquire = FcbHeader->PagingIoResource;
1839 }
1840
1841 /* We force exclusive lock if this write modifies the valid data length */
1842 return (EndingOffset->QuadPart > FcbHeader->ValidDataLength.QuadPart);
1843}
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX
Definition: fsrtltypes.h:48
#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH
Definition: fsrtltypes.h:49

Referenced by FsRtlAcquireFileForModWriteEx().

◆ FsRtlPrepareMdlWrite()

BOOLEAN NTAPI FsRtlPrepareMdlWrite ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN ULONG  LockKey,
OUT PMDL MdlChain,
OUT PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 1218 of file fastio.c.

1224{
1225 PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
1226 PFAST_IO_DISPATCH FastDispatch;
1227
1228 /* Get Device Object and Fast Calls */
1230 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
1231
1232 /* Check if we support Fast Calls, and check this one */
1233 if (FastDispatch && FastDispatch->PrepareMdlWrite)
1234 {
1235 /* Use the fast path */
1236 return FastDispatch->PrepareMdlWrite(FileObject,
1237 FileOffset,
1238 Length,
1239 LockKey,
1240 MdlChain,
1241 IoStatus,
1242 DeviceObject);
1243 }
1244
1245 /* Get the Base File System (Volume) and Fast Calls */
1246 BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
1247 FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
1248
1249 /* If the Base Device Object has its own FastDispatch Routine, fail */
1250 if (FastDispatch &&
1251 FastDispatch->PrepareMdlWrite &&
1252 BaseDeviceObject != DeviceObject)
1253 {
1254 return FALSE;
1255 }
1256
1257 /* No fast path, use slow path */
1259 FileOffset,
1260 Length,
1261 LockKey,
1262 MdlChain,
1263 IoStatus,
1264 DeviceObject);
1265}
BOOLEAN NTAPI FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:1272
PFAST_IO_PREPARE_MDL_WRITE PrepareMdlWrite
Definition: iotypes.h:1751

Referenced by FsRtlTest_StartTest().

◆ FsRtlPrepareMdlWriteDev()

BOOLEAN NTAPI FsRtlPrepareMdlWriteDev ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN ULONG  LockKey,
OUT PMDL MdlChain,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 1272 of file fastio.c.

1279{
1283 PFSRTL_COMMON_FCB_HEADER FcbHeader;
1284 PSHARED_CACHE_MAP SharedCacheMap;
1285
1286 LARGE_INTEGER OldFileSize;
1287 LARGE_INTEGER OldValidDataLength;
1290
1291 /* WDK doc.
1292 * Offset == 0xffffffffffffffff indicates append to the end of file.
1293 */
1294 BOOLEAN FileOffsetAppend = (FileOffset->HighPart == (LONG)0xffffffff) &&
1295 (FileOffset->LowPart == 0xffffffff);
1296
1297 BOOLEAN FileSizeModified = FALSE;
1298 BOOLEAN ResourceAcquiredShared = FALSE;
1299
1300 /* Initialize some of the vars and pointers */
1301 OldFileSize.QuadPart = 0;
1302 OldValidDataLength.QuadPart = 0;
1303
1304 PAGED_CODE();
1305
1306 Offset.QuadPart = FileOffset->QuadPart + Length;
1307
1308 /* Nagar p.544.
1309 * Check with Cc if we can write.
1310 */
1312 (FileObject->Flags & FO_WRITE_THROUGH))
1313 {
1314 return FALSE;
1315 }
1316
1317 IoStatus->Status = STATUS_SUCCESS;
1318
1319 /* No actual read */
1320 if (!Length)
1321 {
1322 return TRUE;
1323 }
1324
1325 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
1327
1328 /* Check we are going to extend the file */
1329 if ((FileOffsetAppend == FALSE) &&
1330 (FileOffset->QuadPart + Length <= FcbHeader->ValidDataLength.QuadPart))
1331 {
1332 /* Acquire the resource shared */
1334 ResourceAcquiredShared = TRUE;
1335 }
1336 else
1337 {
1338 /* Acquire the resource exclusive */
1340 }
1341
1342 /* Check if we are appending */
1343 if (FileOffsetAppend != FALSE)
1344 {
1345 Offset.QuadPart = FcbHeader->FileSize.QuadPart;
1346 NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length;
1347 }
1348 else
1349 {
1350 Offset.QuadPart = FileOffset->QuadPart;
1351 NewSize.QuadPart = FileOffset->QuadPart + Length;
1352 }
1353
1354 if ((FileObject->PrivateCacheMap) &&
1355 (FcbHeader->IsFastIoPossible) &&
1356 (Length <= MAXLONGLONG - FileOffset->QuadPart) &&
1357 (NewSize.QuadPart <= FcbHeader->AllocationSize.QuadPart))
1358 {
1359 /* Check if we can keep the lock shared */
1360 if (ResourceAcquiredShared &&
1361 (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart))
1362 {
1363 ExReleaseResourceLite(FcbHeader->Resource);
1365
1366 /* Compute the offset and the new filesize */
1367 if (FileOffsetAppend)
1368 {
1369 Offset.QuadPart = FcbHeader->FileSize.QuadPart;
1370 NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length;
1371 }
1372
1373 /* Recheck the above points since we released and reacquire the lock */
1374 if ((FileObject->PrivateCacheMap != NULL) &&
1375 (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) &&
1376 (FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart))
1377 {
1378 /* Do nothing */
1379 }
1380 else
1381 {
1382 goto FailAndCleanup;
1383 }
1384 }
1385
1386 /* Check if we need to find out if fast I/O is available */
1387 if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable)
1388 {
1389 /* Sanity check */
1390 /* ASSERT(!KeIsExecutingDpc()); */
1391
1392 /* Get the Fast I/O table */
1394 FastIoDispatch = Device->DriverObject->FastIoDispatch;
1395
1396 /* Sanity check */
1399
1400 /* Ask the driver if we can do it */
1402 FileOffset,
1403 Length,
1404 TRUE,
1405 LockKey,
1406 FALSE,
1407 IoStatus,
1408 Device))
1409 {
1410 /* It's not, fail */
1411 goto FailAndCleanup;
1412 }
1413 }
1414
1415 /* If we are going to modify the filesize,
1416 * save the old fs in case the operation fails.
1417 */
1418 if (NewSize.QuadPart > FcbHeader->FileSize.QuadPart)
1419 {
1420 FileSizeModified = TRUE;
1421 OldFileSize.QuadPart = FcbHeader->FileSize.QuadPart;
1422 OldValidDataLength.QuadPart = FcbHeader->ValidDataLength.QuadPart;
1423
1424 /* If the high part of the filesize is going
1425 * to change, grab the Paging IoResouce.
1426 */
1427 if (NewSize.HighPart != FcbHeader->FileSize.HighPart &&
1428 FcbHeader->PagingIoResource)
1429 {
1431 FcbHeader->FileSize.QuadPart = NewSize.QuadPart;
1433 }
1434 else
1435 {
1436 FcbHeader->FileSize.QuadPart = NewSize.QuadPart;
1437 }
1438 }
1439
1440
1441 /* Nagar p.544.
1442 * Set ourselves as top component.
1443 */
1445 _SEH2_TRY
1446 {
1447 /* Check if there is a gap between the end of the file and the offset.
1448 * If yes, then we have to zero the data.
1449 */
1450 if (Offset.QuadPart > FcbHeader->ValidDataLength.QuadPart)
1451 {
1453 &FcbHeader->ValidDataLength,
1454 &Offset,
1455 TRUE);
1456 if (Result)
1457 {
1459 &Offset,
1460 Length,
1461 MdlChain,
1462 IoStatus);
1463 }
1464 }
1465 else
1466 {
1468 }
1469
1470 }
1474 {
1475 Result = FALSE;
1476 }
1477 _SEH2_END;
1478
1479 /* Reset the top component */
1480 PsGetCurrentThread()->TopLevelIrp = 0;
1481
1482 /* Did the operation suceeded */
1483 if (Result)
1484 {
1485 /* Check if we need to update the filesize */
1486 if (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart)
1487 {
1488 if (NewSize.HighPart != FcbHeader->ValidDataLength.HighPart &&
1489 FcbHeader->PagingIoResource)
1490 {
1492 FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart;
1494 }
1495 else
1496 {
1497 FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart;
1498 }
1499 }
1500
1501 /* Flag the file as modified */
1502 FileObject->Flags |= FO_FILE_MODIFIED;
1503
1504 /* Check if the filesize has changed */
1505 if (FileSizeModified)
1506 {
1507 SharedCacheMap =
1508 (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
1509 SharedCacheMap->FileSize.QuadPart = NewSize.QuadPart;
1511 }
1512 }
1513 else
1514 {
1515 /* The operation did not succeed.
1516 * Reset the file size to what it should be.
1517 */
1518 if (FileSizeModified)
1519 {
1520 if (FcbHeader->PagingIoResource)
1521 {
1523 FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart;
1524 FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart;
1526 }
1527 else
1528 {
1529 FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart;
1530 FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart;
1531 }
1532 }
1533 }
1534
1535 goto Cleanup;
1536 }
1537 else
1538 {
1539 goto FailAndCleanup;
1540 }
1541
1542FailAndCleanup:
1543
1544 ExReleaseResourceLite(FcbHeader->Resource);
1546 return FALSE;
1547
1548Cleanup:
1549
1550 ExReleaseResourceLite(FcbHeader->Resource);
1552 return Result;
1553}
VOID NTAPI CcPrepareMdlWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:91
ret QuadPart
Definition: rtlfuncs.h:3106

Referenced by CdInitializeGlobalData(), FsRtlPrepareMdlWrite(), FsRtlTest_StartTest(), and init_fast_io_dispatch().

◆ FsRtlRegisterFileSystemFilterCallbacks()

NTSTATUS NTAPI FsRtlRegisterFileSystemFilterCallbacks ( PDRIVER_OBJECT  FilterDriverObject,
PFS_FILTER_CALLBACKS  Callbacks 
)

Definition at line 2014 of file fastio.c.

2017{
2018 PFS_FILTER_CALLBACKS NewCallbacks;
2020 PAGED_CODE();
2021
2022 /* Verify parameters */
2023 if ((FilterDriverObject == NULL) || (Callbacks == NULL))
2024 {
2026 }
2027
2028 /* Allocate a buffer for a copy of the callbacks */
2029 NewCallbacks = ExAllocatePoolWithTag(NonPagedPool,
2030 Callbacks->SizeOfFsFilterCallbacks,
2031 'gmSF');
2032 if (NewCallbacks == NULL)
2033 {
2035 }
2036
2037 /* Copy the callbacks */
2038 RtlCopyMemory(NewCallbacks, Callbacks, Callbacks->SizeOfFsFilterCallbacks);
2039
2040 /* Set the callbacks in the driver extension */
2042 DriverExtension->FsFilterCallbacks = NewCallbacks;
2043
2044 return STATUS_SUCCESS;
2045}
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by DriverEntry(), and SetupDispatchAndCallbacksTables().

◆ FsRtlReleaseFile()

VOID NTAPI FsRtlReleaseFile ( IN PFILE_OBJECT  FileObject)

Definition at line 1665 of file fastio.c.

1666{
1667 PFSRTL_COMMON_FCB_HEADER FcbHeader;
1669 PFAST_IO_DISPATCH FastDispatch;
1670
1671 /* Get Device Object and Fast Calls */
1672 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
1674 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
1675
1676 /* Check if Fast Calls are supported and check ReleaseFileForNtCreateSection */
1677 if (FastDispatch &&
1678 FastDispatch->ReleaseFileForNtCreateSection)
1679 {
1680 /* Call the ReleaseFileForNtCreateSection FastIo handler */
1682 }
1683 else
1684 {
1685 /* No FastIo handler, release file's resource */
1686 if (FcbHeader && FcbHeader->Resource) ExReleaseResourceLite(FcbHeader->Resource);
1687 }
1688
1689 /* Release master FsRtl lock */
1691}
PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection
Definition: iotypes.h:1745

Referenced by MiRosUnmapViewOfSection(), MmCreateSection(), and MmNotPresentFaultSectionView().

◆ FsRtlReleaseFileForCcFlush()

VOID NTAPI FsRtlReleaseFileForCcFlush ( IN PFILE_OBJECT  FileObject)

Definition at line 1771 of file fastio.c.

1772{
1773 PFSRTL_COMMON_FCB_HEADER FcbHeader;
1774 PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
1775 PFAST_IO_DISPATCH FastDispatch;
1777
1778 /* Get Device Object and Fast Calls */
1779 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
1781 BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
1782 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
1783
1784 /* Check if Fast Calls are supported, and check ReleaseForCcFlush */
1785 if (FastDispatch &&
1786 FastDispatch->ReleaseForCcFlush)
1787 {
1788 /* Call the ReleaseForCcFlush FastIo handler */
1789 Status = FastDispatch->ReleaseForCcFlush(FileObject, BaseDeviceObject);
1790 }
1791
1792 if (!NT_SUCCESS(Status))
1793 {
1794 /* No FastIo handler (or it failed). Release PagingIO resource and
1795 then Main resource */
1796 if (FcbHeader->PagingIoResource) ExReleaseResourceLite(FcbHeader->PagingIoResource);
1797 if (FcbHeader->Resource) ExReleaseResourceLite(FcbHeader->Resource);
1798 }
1799
1800 /* Release master FsRtl lock */
1802}
PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush
Definition: iotypes.h:1760
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

Referenced by CcRosFlushVacb().

◆ FsRtlReleaseFileForModWrite()

VOID NTAPI FsRtlReleaseFileForModWrite ( _In_ PFILE_OBJECT  FileObject,
_In_ PERESOURCE  ResourceToRelease 
)

Unlock a file object after flushing pages to disk. To be called by the Modified Page Writer (MPW) after a succesful call to FsRtlAcquireFileForModWriteEx.

Parameters
FileObject- The file object to unlock
ResourceToRelease- The resource to release

Definition at line 1965 of file fastio.c.

1967{
1968 PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
1969 PFAST_IO_DISPATCH FastDispatch;
1971
1972 /* Get Device Object and Fast Calls */
1974 BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
1975 FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
1976
1977 /* Check if Fast Calls are supported and check ReleaseForModWrite */
1978 if (FastDispatch &&
1979 FastDispatch->ReleaseForModWrite)
1980 {
1981 /* Call the ReleaseForModWrite FastIo handler */
1982 Status = FastDispatch->ReleaseForModWrite(FileObject,
1984 BaseDeviceObject);
1985 }
1986
1987 /* Just release the resource if previous op failed */
1988 if (!NT_SUCCESS(Status))
1989 {
1991 }
1992}
PFAST_IO_RELEASE_FOR_MOD_WRITE ReleaseForModWrite
Definition: iotypes.h:1758
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132