ReactOS 0.4.15-dev-7889-g76290a6
write.c File Reference
#include "cdprocs.h"
Include dependency graph for write.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (CDFS_BUG_CHECK_WRITE)
 
#define SafeZeroMemory(IC, AT, BYTE_COUNT)
 

Functions

 _Requires_lock_held_ (_Global_critical_region_)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (CDFS_BUG_CHECK_WRITE)

Definition at line 23 of file write.c.

◆ SafeZeroMemory

#define SafeZeroMemory (   IC,
  AT,
  BYTE_COUNT 
)
Value:
{ \
RtlZeroMemory( (AT), (BYTE_COUNT) ); \
__pragma(warning(suppress: 6320)) \
CdRaiseStatus( IC, STATUS_INVALID_USER_BUFFER ); \
} _SEH2_END; \
}
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
boolean suppress
Definition: jpeglib.h:1006
#define AT
Definition: mbstring.h:34
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define warning(s)
Definition: debug.h:83
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166

Definition at line 38 of file write.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 61 of file write.c.

87{
90
92 PFCB Fcb;
93 PCCB Ccb;
94
96 ULONG SynchronousIo;
97 PVOID UserBuffer;
98
100 LONGLONG ByteRange;
102 ULONG WriteByteCount;
103 ULONG OriginalByteCount;
104
105 BOOLEAN ReleaseFile = TRUE;
106
107 CD_IO_CONTEXT LocalIoContext;
108
109 PAGED_CODE();
110
111 //
112 // If this is a zero length write then return SUCCESS immediately.
113 //
114
115 if (IrpSp->Parameters.Write.Length == 0) {
116
117 CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
118 return STATUS_SUCCESS;
119 }
120
121 //
122 // Decode the file object and verify we support write on this. It
123 // must be a volume file.
124 //
125
126 TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
127
128 // Internal lock object is acquired if return status is STATUS_PENDING
130
131 if (TypeOfOpen != UserVolumeOpen) {
132
135 }
136
137 //
138 // Examine our input parameters to determine if this is noncached and/or
139 // a paging io operation.
140 //
141
142 Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
143 SynchronousIo = FlagOn( IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO );
144
145
146 //
147 // Extract the range of the Io.
148 //
149
150 StartingOffset = IrpSp->Parameters.Write.ByteOffset.QuadPart;
151 OriginalByteCount = ByteCount = IrpSp->Parameters.Write.Length;
152
153 ByteRange = StartingOffset + ByteCount;
154
155 //
156 // Acquire the file shared to perform the write.
157 //
158
159 CdAcquireFileShared( IrpContext, Fcb );
160
161 //
162 // Use a try-finally to facilitate cleanup.
163 //
164
165 _SEH2_TRY {
166
167 //
168 // Verify the Fcb. Allow writes if this is a DASD handle that is
169 // dismounting the volume.
170 //
171
173
174 CdVerifyFcbOperation( IrpContext, Fcb );
175 }
176
178
179 //
180 // Complete the request if it begins beyond the end of file.
181 //
182
183 if (StartingOffset >= Fcb->FileSize.QuadPart) {
184
186 }
187
188 //
189 // Truncate the write if it extends beyond the end of the file.
190 //
191
192 if (ByteRange > Fcb->FileSize.QuadPart) {
193
194 ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
195 ByteRange = Fcb->FileSize.QuadPart;
196 }
197 }
198
199 //
200 // If we have an unaligned transfer then post this request if
201 // we can't wait. Unaligned means that the starting offset
202 // is not on a sector boundary or the write is not integral
203 // sectors.
204 //
205
206 WriteByteCount = BlockAlign( Fcb->Vcb, ByteCount );
207
209 SectorOffset( WriteByteCount ) ||
210 (WriteByteCount > OriginalByteCount)) {
211
212 if (!Wait) {
213
214 CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
215 }
216
217 //
218 // Make sure we don't overwrite the buffer.
219 //
220
221 WriteByteCount = ByteCount;
222 }
223
224 //
225 // Initialize the IoContext for the write.
226 // If there is a context pointer, we need to make sure it was
227 // allocated and not a stale stack pointer.
228 //
229
230 if (IrpContext->IoContext == NULL ||
231 !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) {
232
233 //
234 // If we can wait, use the context on the stack. Otherwise
235 // we need to allocate one.
236 //
237
238 if (Wait) {
239
240 IrpContext->IoContext = &LocalIoContext;
241 ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
242
243 } else {
244
245 IrpContext->IoContext = CdAllocateIoContext();
246 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
247 }
248 }
249
250 RtlZeroMemory( IrpContext->IoContext, sizeof( CD_IO_CONTEXT ) );
251
252 //
253 // Store whether we allocated this context structure in the structure
254 // itself.
255 //
256
257 IrpContext->IoContext->AllocatedContext =
258 BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
259
260 if (Wait) {
261
262 KeInitializeEvent( &IrpContext->IoContext->SyncEvent,
264 FALSE );
265
266 } else {
267
268 IrpContext->IoContext->ResourceThreadId = ExGetCurrentResourceThread();
269 IrpContext->IoContext->Resource = Fcb->Resource;
270 IrpContext->IoContext->RequestedByteCount = ByteCount;
271 }
272
273 Irp->IoStatus.Information = WriteByteCount;
274
275 //
276 // Set the FO_MODIFIED flag here to trigger a verify when this
277 // handle is closed. Note that we can err on the conservative
278 // side with no problem, i.e. if we accidently do an extra
279 // verify there is no problem.
280 //
281
283
284 //
285 // Dasd access is always non-cached. Call the Dasd write routine to
286 // perform the actual write.
287 //
288
289 Status = CdVolumeDasdWrite( IrpContext, Fcb, StartingOffset, WriteByteCount );
290
291 //
292 // Don't complete this request now if STATUS_PENDING was returned.
293 //
294
295 if (Status == STATUS_PENDING) {
296
297 Irp = NULL;
298 ReleaseFile = FALSE;
299
300 //
301 // Test is we should zero part of the buffer or update the
302 // synchronous file position.
303 //
304
305 } else {
306
307 //
308 // Convert any unknown error code to IO_ERROR.
309 //
310
311 if (!NT_SUCCESS( Status )) {
312
313 //
314 // Set the information field to zero.
315 //
316
317 Irp->IoStatus.Information = 0;
318
319 //
320 // Raise if this is a user induced error.
321 //
322
324
325 CdRaiseStatus( IrpContext, Status );
326 }
327
329
330 //
331 // Check if there is any portion of the user's buffer to zero.
332 //
333
334 } else if (WriteByteCount != ByteCount) {
335
336 CdMapUserBuffer( IrpContext, &UserBuffer );
337
338 SafeZeroMemory( IrpContext,
339 Add2Ptr( UserBuffer,
340 ByteCount,
341 PVOID ),
342 WriteByteCount - ByteCount );
343
344 Irp->IoStatus.Information = ByteCount;
345 }
346
347 //
348 // Update the file position if this is a synchronous request.
349 //
350
351 if (SynchronousIo && NT_SUCCESS( Status )) {
352
353 IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange;
354 }
355 }
356
357 try_exit: NOTHING;
358 } _SEH2_FINALLY {
359
360 //
361 // Release the Fcb.
362 //
363
364 if (ReleaseFile) {
365
366 CdReleaseFile( IrpContext, Fcb );
367 }
368 } _SEH2_END;
369
370 //
371 // Post the request if we got CANT_WAIT.
372 //
373
374 if (Status == STATUS_CANT_WAIT) {
375
376 Status = CdFsdPostRequest( IrpContext, Irp );
377
378 //
379 // Otherwise complete the request.
380 //
381
382 } else {
383
384 CdCompleteRequest( IrpContext, Irp, Status );
385 }
386
387 return Status;
388}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define CdMapUserBuffer(IC, UB)
Definition: cdprocs.h:383
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
#define CdReleaseFile(IC, F)
Definition: cdprocs.h:1003
#define BlockAlign(V, L)
Definition: cdprocs.h:1638
@ UserVolumeOpen
Definition: cdprocs.h:575
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define CdAllocateIoContext()
Definition: cdprocs.h:1344
BOOLEAN CdVerifyFcbOperation(_In_opt_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb)
Definition: verfysup.c:615
#define SectorOffset(L)
Definition: cdprocs.h:1622
#define CdAcquireFileShared(IC, F)
Definition: cdprocs.h:997
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define try_return(S)
Definition: cdprocs.h:2179
#define CdRaiseStatus(IC, S)
Definition: cdprocs.h:1859
#define CCB_FLAG_ALLOW_EXTENDED_DASD_IO
Definition: cdstruc.h:1108
#define CCB_FLAG_DISMOUNT_ON_CLOSE
Definition: cdstruc.h:1107
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define IRP_CONTEXT_FLAG_ALLOC_IO
Definition: cdstruc.h:1221
#define _Analysis_suppress_lock_checking_(lock)
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SafeZeroMemory(IC, AT, BYTE_COUNT)
Definition: write.c:38
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define ExGetCurrentResourceThread()
Definition: env_spec_w32.h:633
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define _SEH2_FINALLY
Definition: filesup.c:21
Status
Definition: gdiplustypes.h:25
#define NOTHING
Definition: input_list.c:10
#define Add2Ptr(PTR, INC)
@ NotificationEvent
NTSTATUS NTAPI FsRtlNormalizeNtstatus(IN NTSTATUS NtStatusToNormalize, IN NTSTATUS NormalizedNtStatus)
Definition: filter.c:90
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_UNEXPECTED_IO_ERROR
Definition: ntstatus.h:469
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
PVCB Vcb
Definition: cdstruc.h:933
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3983 Write
int64_t LONGLONG
Definition: typedefs.h:68
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776