ReactOS  0.4.14-dev-368-gfa26425
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 {
334  PIO_STACK_LOCATION Stack;
336  KEVENT Event;
337  PIRP Irp;
339 
341 
342  DPRINT("Building device I/O control request ...\n");
344  DeviceObject,
345  InputBuffer,
346  InputBufferSize,
347  OutputBuffer,
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 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
CHAR InputBuffer[80]
Definition: conmgr.c:33
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
smooth NULL
Definition: ftsmooth.c:416
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
void DPRINT(...)
Definition: polytest.cpp:61
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
#define STATUS_PENDING
Definition: ntstatus.h:82
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
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

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 {
44  PIO_STACK_LOCATION Stack;
47  KEVENT Event;
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");
83  ReadBuffer,
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 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
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
_In_ PIRP Irp
Definition: csq.h:116
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
uint64_t ULONGLONG
Definition: typedefs.h:65
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TAG_NTFS
Definition: ntfs.h:12
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
Status
Definition: gdiplustypes.h:24
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_READ
Definition: rdpdr.c:46
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_In_ ULONG SectorSize
Definition: halfuncs.h:291
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34

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 }
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
Definition: bufpool.h:45
int64_t LONGLONG
Definition: typedefs.h:66
ULONG SectorCount
Definition: part_xbox.c:32
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int ULONG
Definition: retypes.h:1
_In_ ULONG SectorSize
Definition: halfuncs.h:291
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

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 {
171  KEVENT Event;
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
259  DeviceObject,
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 TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
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
_In_ PIRP Irp
Definition: csq.h:116
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
uint64_t ULONGLONG
Definition: typedefs.h:65
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TAG_NTFS
Definition: ntfs.h:12
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_In_ ULONG SectorSize
Definition: halfuncs.h:291
return STATUS_SUCCESS
Definition: btrfs.c:2938
FORCEINLINE PVOID RtlSecureZeroMemory(_Out_writes_bytes_all_(Size) PVOID Pointer, _In_ SIZE_T Size)
Definition: rtlfuncs.h:3127
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

Referenced by WriteAttribute().