ReactOS 0.4.16-dev-340-g0540c21
blockdev.c File Reference
#include "ntfs.h"
#include <debug.h>
Include dependency graph for blockdev.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NtfsReadDisk (IN PDEVICE_OBJECT DeviceObject, IN LONGLONG StartingOffset, IN ULONG Length, IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
 
NtfsWriteDisk

@implemented

Writes data from the given buffer to the given DeviceObject.

Parameters
DeviceObjectDevice to write to
StartingOffsetOffset, in bytes, from the start of the device object where the data will be written
LengthHow much data will be written, in bytes
SectorSizeSize of the sector on the disk that the write must be aligned to
BufferThe data that's being written to the device
Returns
STATUS_SUCCESS in case of success, STATUS_INSUFFICIENT_RESOURCES if a memory allocation failed, or whatever status IoCallDriver() sets.
Remarks
Called by NtfsWriteFile(). May perform a read-modify-write operation if the requested write is not sector-aligned.
NTSTATUS NtfsWriteDisk (IN PDEVICE_OBJECT DeviceObject, IN LONGLONG StartingOffset, IN ULONG Length, IN ULONG SectorSize, IN const PUCHAR Buffer)
 
NTSTATUS NtfsReadSectors (IN PDEVICE_OBJECT DeviceObject, IN ULONG DiskSector, IN ULONG SectorCount, IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
 
NTSTATUS NtfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, IN ULONG ControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer, IN OUT PULONG OutputBufferSize, IN BOOLEAN Override)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 31 of file blockdev.c.

Function Documentation

◆ NtfsDeviceIoControl()

NTSTATUS NtfsDeviceIoControl ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  ControlCode,
IN PVOID  InputBuffer,
IN ULONG  InputBufferSize,
IN OUT PVOID  OutputBuffer,
IN OUT PULONG  OutputBufferSize,
IN BOOLEAN  Override 
)

Definition at line 326 of file blockdev.c.

333{
337 PIRP Irp;
339
341
342 DPRINT("Building device I/O control request ...\n");
346 InputBufferSize,
348 (OutputBufferSize) ? *OutputBufferSize : 0,
349 FALSE,
350 &Event,
351 &IoStatus);
352 if (Irp == NULL)
353 {
354 DPRINT("IoBuildDeviceIoControlRequest() failed\n");
356 }
357
358 if (Override)
359 {
362 }
363
364 DPRINT("Calling IO Driver... with irp %p\n", Irp);
366 if (Status == STATUS_PENDING)
367 {
369 Status = IoStatus.Status;
370 }
371
372 if (OutputBufferSize)
373 {
374 *OutputBufferSize = IoStatus.Information;
375 }
376
377 return Status;
378}
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
Status
Definition: gdiplustypes.h:25
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
#define DPRINT
Definition: sndvol32.h:73
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
@ Suspended
Definition: ketypes.h:420

Referenced by NtfsGetVolumeData(), and NtfsHasFileSystem().

◆ NtfsReadDisk()

NTSTATUS NtfsReadDisk ( IN PDEVICE_OBJECT  DeviceObject,
IN LONGLONG  StartingOffset,
IN ULONG  Length,
IN ULONG  SectorSize,
IN OUT PUCHAR  Buffer,
IN BOOLEAN  Override 
)

Definition at line 37 of file blockdev.c.

43{
48 PIRP Irp;
50 ULONGLONG RealReadOffset;
51 ULONG RealLength;
52 BOOLEAN AllocatedBuffer = FALSE;
54
55 DPRINT("NtfsReadDisk(%p, %I64x, %lu, %lu, %p, %d)\n", DeviceObject, StartingOffset, Length, SectorSize, Buffer, Override);
56
59 FALSE);
60
61 RealReadOffset = (ULONGLONG)StartingOffset;
62 RealLength = Length;
63
64 if ((RealReadOffset % SectorSize) != 0 || (RealLength % SectorSize) != 0)
65 {
66 RealReadOffset = ROUND_DOWN(StartingOffset, SectorSize);
67 RealLength = ROUND_UP(Length, SectorSize);
68
70 if (ReadBuffer == NULL)
71 {
72 DPRINT1("Not enough memory!\n");
74 }
75 AllocatedBuffer = TRUE;
76 }
77
78 Offset.QuadPart = RealReadOffset;
79
80 DPRINT("Building synchronous FSD Request...\n");
84 RealLength,
85 &Offset,
86 &Event,
87 &IoStatus);
88 if (Irp == NULL)
89 {
90 DPRINT("IoBuildSynchronousFsdRequest failed\n");
91
92 if (AllocatedBuffer)
93 {
95 }
96
98 }
99
100 if (Override)
101 {
104 }
105
106 DPRINT("Calling IO Driver... with irp %p\n", Irp);
108
109 DPRINT("Waiting for IO Operation for %p\n", Irp);
110 if (Status == STATUS_PENDING)
111 {
112 DPRINT("Operation pending\n");
114 DPRINT("Getting IO Status... for %p\n", Irp);
115 Status = IoStatus.Status;
116 }
117
118 if (AllocatedBuffer)
119 {
120 if (NT_SUCCESS(Status))
121 {
122 RtlCopyMemory(Buffer, ReadBuffer + (StartingOffset - RealReadOffset), Length);
123 }
124
126 }
127
128 DPRINT("NtfsReadDisk() done (Status %x)\n", Status);
129
130 return Status;
131}
unsigned char BOOLEAN
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define DPRINT1
Definition: precomp.h:8
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
Definition: bufpool.h:45
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define TAG_NTFS
Definition: ntfs.h:12
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
_In_ ULONG SectorSize
Definition: halfuncs.h:291

Referenced by NtfsReadSectors(), NtfsWriteDisk(), and ReadAttribute().

◆ NtfsReadSectors()

NTSTATUS NtfsReadSectors ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  DiskSector,
IN ULONG  SectorCount,
IN ULONG  SectorSize,
IN OUT PUCHAR  Buffer,
IN BOOLEAN  Override 
)

Definition at line 308 of file blockdev.c.

314{
316 ULONG BlockSize;
317
318 Offset = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
319 BlockSize = SectorCount * SectorSize;
320
321 return NtfsReadDisk(DeviceObject, Offset, BlockSize, SectorSize, Buffer, Override);
322}
NTSTATUS NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject, IN LONGLONG StartingOffset, IN ULONG Length, IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:37
ULONG SectorCount
Definition: part_xbox.c:31
int64_t LONGLONG
Definition: typedefs.h:68

Referenced by NtfsGetVolumeData(), NtfsHasFileSystem(), and ReadLCN().

◆ NtfsWriteDisk()

NTSTATUS NtfsWriteDisk ( IN PDEVICE_OBJECT  DeviceObject,
IN LONGLONG  StartingOffset,
IN ULONG  Length,
IN ULONG  SectorSize,
IN const PUCHAR  Buffer 
)

Definition at line 163 of file blockdev.c.

168{
172 PIRP Irp;
174 ULONGLONG RealWriteOffset;
175 ULONG RealLength;
176 BOOLEAN AllocatedBuffer = FALSE;
177 PUCHAR TempBuffer = NULL;
178
179 DPRINT("NtfsWriteDisk(%p, %I64x, %lu, %lu, %p)\n", DeviceObject, StartingOffset, Length, SectorSize, Buffer);
180
181 if (Length == 0)
182 return STATUS_SUCCESS;
183
184 RealWriteOffset = (ULONGLONG)StartingOffset;
185 RealLength = Length;
186
187 // Does the write need to be adjusted to be sector-aligned?
188 if ((RealWriteOffset % SectorSize) != 0 || (RealLength % SectorSize) != 0)
189 {
190 ULONGLONG relativeOffset;
191
192 // We need to do a read-modify-write. We'll start be copying the entire
193 // contents of every sector that will be overwritten.
194 // TODO: Optimize (read no more than necessary)
195
196 RealWriteOffset = ROUND_DOWN(StartingOffset, SectorSize);
197 RealLength = ROUND_UP(Length, SectorSize);
198
199 // Would the end of our sector-aligned write fall short of the requested write?
200 if (RealWriteOffset + RealLength < StartingOffset + Length)
201 {
202 RealLength += SectorSize;
203 }
204
205 // Did we underestimate the memory required somehow?
206 if (RealLength + RealWriteOffset < StartingOffset + Length)
207 {
208 DPRINT1("\a\t\t\t\t\tFIXME: calculated less memory than needed!\n");
209 DPRINT1("StartingOffset: %lu\tLength: %lu\tRealWriteOffset: %lu\tRealLength: %lu\n",
210 StartingOffset, Length, RealWriteOffset, RealLength);
211
212 RealLength += SectorSize;
213 }
214
215 // Allocate a buffer to copy the existing data to
216 TempBuffer = ExAllocatePoolWithTag(NonPagedPool, RealLength, TAG_NTFS);
217
218 // Did we fail to allocate it?
219 if (TempBuffer == NULL)
220 {
221 DPRINT1("Not enough memory!\n");
222
224 }
225
226 // Read the sectors we'll be overwriting into TempBuffer
227 Status = NtfsReadDisk(DeviceObject, RealWriteOffset, RealLength, SectorSize, TempBuffer, FALSE);
228
229 // Did we fail the read?
230 if (!NT_SUCCESS(Status))
231 {
232 RtlSecureZeroMemory(TempBuffer, RealLength);
233 ExFreePoolWithTag(TempBuffer, TAG_NTFS);
234 return Status;
235 }
236
237 // Calculate where the new data should be written to, relative to the start of TempBuffer
238 relativeOffset = StartingOffset - RealWriteOffset;
239
240 // Modify the tempbuffer with the data being read
241 RtlCopyMemory(TempBuffer + relativeOffset, Buffer, Length);
242
243 AllocatedBuffer = TRUE;
244 }
245
246 // set the destination offset
247 Offset.QuadPart = RealWriteOffset;
248
249 // setup the notification event for the write
252 FALSE);
253
254 DPRINT("Building synchronous FSD Request...\n");
255
256 // Build an IRP requesting the lower-level [disk] driver to perform the write
257 // TODO: Forward the existing IRP instead
260 // if we allocated a temp buffer, use that instead of the Buffer parameter
261 ((AllocatedBuffer) ? TempBuffer : Buffer),
262 RealLength,
263 &Offset,
264 &Event,
265 &IoStatus);
266 // Did we fail to build the IRP?
267 if (Irp == NULL)
268 {
269 DPRINT1("IoBuildSynchronousFsdRequest failed\n");
270
271 if (AllocatedBuffer)
272 {
273 RtlSecureZeroMemory(TempBuffer, RealLength);
274 ExFreePoolWithTag(TempBuffer, TAG_NTFS);
275 }
276
278 }
279
280 // Call the next-lower driver to perform the write
281 DPRINT("Calling IO Driver with irp %p\n", Irp);
283
284 // Wait until the next-lower driver has completed the IRP
285 DPRINT("Waiting for IO Operation for %p\n", Irp);
286 if (Status == STATUS_PENDING)
287 {
288 DPRINT("Operation pending\n");
290 DPRINT("Getting IO Status... for %p\n", Irp);
291 Status = IoStatus.Status;
292 }
293
294 if (AllocatedBuffer)
295 {
296 // zero the buffer before freeing it, so private user data can't be snooped
297 RtlSecureZeroMemory(TempBuffer, RealLength);
298
299 ExFreePoolWithTag(TempBuffer, TAG_NTFS);
300 }
301
302 DPRINT("NtfsWriteDisk() done (Status %x)\n", Status);
303
304 return Status;
305}
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_SUCCESS
Definition: shellext.h:65
FORCEINLINE PVOID RtlSecureZeroMemory(_Out_writes_bytes_all_(Size) PVOID Pointer, _In_ SIZE_T Size)
Definition: rtlfuncs.h:3142

Referenced by WriteAttribute().