141 lines
3.5 KiB
C
141 lines
3.5 KiB
C
/*++
|
|
|
|
Copyright (c) 2000-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
create.c
|
|
|
|
Abstract:
|
|
|
|
This module implements routines related to handling IRP_MJ_CREATE.
|
|
|
|
--*/
|
|
|
|
#include "rawx.h"
|
|
|
|
NTSTATUS
|
|
RawxFsdCreate(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the I/O manager to handle IRP_MJ_CREATE requests.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Specifies the device object that the I/O request is for.
|
|
|
|
Irp - Specifies the packet that describes the I/O request.
|
|
|
|
Return Value:
|
|
|
|
Status of operation.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS status;
|
|
PRAW_VOLUME_EXTENSION VolumeExtension;
|
|
PIO_STACK_LOCATION IrpSp;
|
|
ACCESS_MASK DesiredAccess;
|
|
USHORT ShareAccess;
|
|
ULONG CreateOptions;
|
|
PFILE_OBJECT FileObject;
|
|
ULONG CreateDisposition;
|
|
|
|
VolumeExtension = (PRAW_VOLUME_EXTENSION)DeviceObject->DeviceExtension;
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
DesiredAccess = IrpSp->Parameters.Create.DesiredAccess;
|
|
ShareAccess = IrpSp->Parameters.Create.ShareAccess;
|
|
CreateOptions = IrpSp->Parameters.Create.Options;
|
|
FileObject = IrpSp->FileObject;
|
|
|
|
RawxAcquireVolumeMutexExclusive(VolumeExtension);
|
|
|
|
//
|
|
// Check if the volume has been dismounted.
|
|
//
|
|
|
|
if (VolumeExtension->Dismounted) {
|
|
status = STATUS_VOLUME_DISMOUNTED;
|
|
goto CleanupAndExit;
|
|
}
|
|
|
|
//
|
|
// Don't allow a relative path to be opened.
|
|
//
|
|
|
|
if (IrpSp->FileObject->RelatedFileObject != NULL) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
goto CleanupAndExit;
|
|
} else if (IrpSp->Parameters.Create.RemainingName->Length != 0) {
|
|
status = STATUS_OBJECT_PATH_NOT_FOUND;
|
|
goto CleanupAndExit;
|
|
}
|
|
|
|
//
|
|
// Verify that the create disposition is for open access only.
|
|
//
|
|
|
|
CreateDisposition = (CreateOptions >> 24) & 0xFF;
|
|
|
|
if ((CreateDisposition != FILE_OPEN) && (CreateDisposition != FILE_OPEN_IF)) {
|
|
status = STATUS_ACCESS_DENIED;
|
|
goto CleanupAndExit;
|
|
}
|
|
|
|
//
|
|
// The caller shouldn't be expecting to see a directory file.
|
|
//
|
|
|
|
if (RawxIsFlagSet(CreateOptions, FILE_DIRECTORY_FILE)) {
|
|
status = STATUS_NOT_A_DIRECTORY;
|
|
goto CleanupAndExit;
|
|
}
|
|
|
|
//
|
|
// If this is the first open handle to the file, then initialize the sharing
|
|
// mode. Otherwise, verify that the requested sharing mode is compatible
|
|
// with the current sharing mode.
|
|
//
|
|
|
|
if (VolumeExtension->ShareAccess.OpenCount == 0) {
|
|
IoSetShareAccess(DesiredAccess, ShareAccess, FileObject,
|
|
&VolumeExtension->ShareAccess);
|
|
status = STATUS_SUCCESS;
|
|
} else {
|
|
status = IoCheckShareAccess(DesiredAccess, ShareAccess, FileObject,
|
|
&VolumeExtension->ShareAccess, TRUE);
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Physical volume access is always non-cached. Mark the file object as
|
|
// non-cached so that the I/O manager enforces alignment requirements.
|
|
//
|
|
|
|
FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
|
|
|
|
//
|
|
// Indicate to the caller that we opened the file as opposed to creating
|
|
// or overwriting the file.
|
|
//
|
|
|
|
Irp->IoStatus.Information = FILE_OPENED;
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
|
|
CleanupAndExit:
|
|
RawxReleaseVolumeMutex(VolumeExtension);
|
|
|
|
Irp->IoStatus.Status = status;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|