summaryrefslogtreecommitdiffstats
path: root/private/ntos/mailslot/createms.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/mailslot/createms.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/mailslot/createms.c')
-rw-r--r--private/ntos/mailslot/createms.c593
1 files changed, 593 insertions, 0 deletions
diff --git a/private/ntos/mailslot/createms.c b/private/ntos/mailslot/createms.c
new file mode 100644
index 000000000..81cccbcb6
--- /dev/null
+++ b/private/ntos/mailslot/createms.c
@@ -0,0 +1,593 @@
+/*++
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ createms.c
+
+Abstract:
+
+ This module implements the file create mailslot routine for MSFS called
+ by the dispatch driver.
+
+Author:
+
+ Manny Weiser (mannyw) 17-Jan-1991
+
+Revision History:
+
+--*/
+
+#include "mailslot.h"
+
+//
+// The debug trace level
+//
+
+#define Dbg (DEBUG_TRACE_CREATE_MAILSLOT)
+
+//
+// local procedure prototypes
+//
+
+NTSTATUS
+MsCommonCreateMailslot (
+ IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
+ IN PIRP Irp
+ );
+
+IO_STATUS_BLOCK
+MsCreateMailslot (
+ IN PROOT_DCB RootDcb,
+ IN PFILE_OBJECT FileObject,
+ IN UNICODE_STRING FileName,
+ IN ACCESS_MASK DesiredAccess,
+ IN ULONG CreateDisposition,
+ IN USHORT ShareAccess,
+ IN ULONG MailslotQuota,
+ IN ULONG MaximumMessageSize,
+ IN LARGE_INTEGER ReadTimeout,
+ IN PEPROCESS CreatorProcess,
+ IN PACCESS_STATE AccessState
+ );
+
+BOOLEAN
+MsIsNameValid (
+ PUNICODE_STRING Name
+ );
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text( PAGE, MsCommonCreateMailslot )
+#pragma alloc_text( PAGE, MsCreateMailslot )
+#pragma alloc_text( PAGE, MsFsdCreateMailslot )
+#pragma alloc_text( PAGE, MsIsNameValid )
+#endif
+
+
+
+NTSTATUS
+MsFsdCreateMailslot (
+ IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
+ IN PIRP Irp
+ )
+
+/*++
+
+Routine Description:
+
+ This routine implements the FSD part of the NtCreateMailslotFile
+ API call.
+
+Arguments:
+
+ MsfsDeviceObject - Supplies the device object to use.
+
+ Irp - Supplies the Irp being processed
+
+Return Value:
+
+ NTSTATUS - The Fsd status for the Irp
+
+--*/
+
+{
+ NTSTATUS status;
+
+ PAGED_CODE();
+ DebugTrace(+1, Dbg, "MsFsdCreateMailslot\n", 0);
+
+ //
+ // Call the common create routine.
+ //
+
+ try {
+
+ status = MsCommonCreateMailslot( MsfsDeviceObject, Irp );
+
+ } except(MsExceptionFilter( GetExceptionCode() )) {
+
+ //
+ // We had some trouble trying to perform the requested
+ // operation, so we'll abort the I/O request with
+ // the error status that we get back from the
+ // execption code.
+ //
+
+ status = MsProcessException( MsfsDeviceObject, Irp, GetExceptionCode() );
+ }
+
+ //
+ // Return to the caller.
+ //
+
+ DebugTrace(-1, Dbg, "MsFsdCreateMailslot -> %08lx\n", status );
+ return status;
+}
+
+NTSTATUS
+MsCommonCreateMailslot (
+ IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
+ IN PIRP Irp
+ )
+
+/*++
+
+Routine Description:
+
+ This is the common routine for creating a mailslot.
+
+Arguments:
+
+ Irp - Supplies the Irp to process
+
+Return Value:
+
+ NTSTATUS - the return status for the operation
+
+--*/
+
+{
+ NTSTATUS status;
+ PIO_STACK_LOCATION irpSp;
+
+ PFILE_OBJECT fileObject;
+ PFILE_OBJECT relatedFileObject;
+ UNICODE_STRING fileName;
+ ACCESS_MASK desiredAccess;
+ ULONG options;
+ USHORT shareAccess;
+ PMAILSLOT_CREATE_PARAMETERS parameters;
+ ULONG mailslotQuota;
+ ULONG maximumMessageSize;
+ PEPROCESS creatorProcess;
+ LARGE_INTEGER readTimeout;
+
+ BOOLEAN caseInsensitive = TRUE; //**** Make all searches case insensitive
+
+ PVCB vcb;
+ PFCB fcb;
+
+ ULONG createDisposition;
+ UNICODE_STRING remainingPart;
+
+ PAGED_CODE();
+
+ //
+ // Make local copies of the input parameters to make things easier.
+ //
+
+ irpSp = IoGetCurrentIrpStackLocation( Irp );
+ fileObject = irpSp->FileObject;
+ relatedFileObject = irpSp->FileObject->RelatedFileObject;
+ fileName = *(PUNICODE_STRING)&irpSp->FileObject->FileName;
+ desiredAccess = irpSp->Parameters.CreateMailslot.SecurityContext->DesiredAccess;
+ options = irpSp->Parameters.CreateMailslot.Options;
+ shareAccess = irpSp->Parameters.CreateMailslot.ShareAccess;
+ parameters = irpSp->Parameters.CreateMailslot.Parameters;
+ mailslotQuota = parameters->MailslotQuota;
+ maximumMessageSize = parameters->MaximumMessageSize;
+
+ if (parameters->TimeoutSpecified) {
+ readTimeout = parameters->ReadTimeout;
+ } else {
+ readTimeout.QuadPart = -1;
+ }
+
+ creatorProcess = IoGetRequestorProcess( Irp );
+
+ DebugTrace(+1, Dbg, "MsCommonCreateMailslot\n", 0 );
+ DebugTrace( 0, Dbg, "MsfsDeviceObject = %08lx\n", (ULONG)MsfsDeviceObject );
+ DebugTrace( 0, Dbg, "Irp = %08lx\n", (ULONG)Irp );
+ DebugTrace( 0, Dbg, "FileObject = %08lx\n", (ULONG)fileObject );
+ DebugTrace( 0, Dbg, "RelatedFileObject = %08lx\n", (ULONG)relatedFileObject );
+ DebugTrace( 0, Dbg, "FileName = %wZ\n", (ULONG)&fileName );
+ DebugTrace( 0, Dbg, "DesiredAccess = %08lx\n", desiredAccess );
+ DebugTrace( 0, Dbg, "Options = %08lx\n", options );
+ DebugTrace( 0, Dbg, "ShareAccess = %08lx\n", shareAccess );
+ DebugTrace( 0, Dbg, "Parameters = %08lx\n", (ULONG)parameters );
+ DebugTrace( 0, Dbg, "MailslotQuota = %08lx\n", mailslotQuota );
+ DebugTrace( 0, Dbg, "MaximumMesssageSize = %08lx\n", maximumMessageSize );
+ DebugTrace( 0, Dbg, "CreatorProcess = %08lx\n", (ULONG)creatorProcess );
+
+ //
+ // Get the VCB we are trying to access and extract the
+ // create disposition.
+ //
+
+ vcb = &MsfsDeviceObject->Vcb;
+ createDisposition = (options >> 24) & 0x000000ff;
+
+ //
+ // Acquire exclusive access to the VCB.
+ //
+
+ MsAcquireExclusiveVcb( vcb );
+
+ try {
+
+ //
+ // If there is a related file object then this is a relative open
+ // and it better be the root DCB. Both the then and the else clause
+ // return an FCB.
+ //
+
+ if (relatedFileObject != NULL) {
+
+ PDCB dcb;
+
+ dcb = relatedFileObject->FsContext;
+
+ if (NodeType(dcb) != MSFS_NTC_ROOT_DCB) {
+
+ DebugTrace(0, Dbg, "Bad file name\n", 0);
+
+ MsCompleteRequest( Irp, STATUS_OBJECT_NAME_INVALID );
+ try_return( status = STATUS_OBJECT_NAME_INVALID );
+ }
+
+ fcb = MsFindRelativePrefix(
+ dcb,
+ &fileName,
+ caseInsensitive,
+ &remainingPart
+ );
+
+ } else {
+
+ //
+ // The only nonrelative name we allow are of the form
+ // "\mailslot-name".
+ //
+
+ if ((fileName.Length <= sizeof( WCHAR )) || (fileName.Buffer[0] != L'\\')) {
+
+ DebugTrace(0, Dbg, "Bad file name\n", 0);
+
+ MsCompleteRequest( Irp, STATUS_OBJECT_NAME_INVALID );
+ try_return( status = STATUS_OBJECT_NAME_INVALID );
+ }
+
+ fcb = MsFindPrefix(
+ vcb,
+ &fileName,
+ caseInsensitive,
+ &remainingPart
+ );
+
+ }
+
+ //
+ // If the remaining name is empty then we better have an FCB
+ // otherwise we were given a illegal object name.
+ //
+
+ if (remainingPart.Length == 0) {
+
+ if (fcb->Header.NodeTypeCode == MSFS_NTC_FCB) {
+
+ DebugTrace(0,
+ Dbg,
+ "Attempt to create an existing mailslot, "
+ "Fcb = %08lx\n",
+ (ULONG)fcb );
+
+ status = STATUS_OBJECT_NAME_COLLISION;
+
+ } else {
+
+ DebugTrace(0, Dbg, "Illegal object name\n", 0);
+ status = STATUS_OBJECT_NAME_INVALID;
+
+ }
+
+ } else {
+
+ //
+ // The remaining name is not empty so we better have the root DCB
+ // and then have a valid object path.
+ //
+
+ if ( fcb->Header.NodeTypeCode == MSFS_NTC_ROOT_DCB &&
+ MsIsNameValid( &remainingPart ) ) {
+
+ DebugTrace(0,
+ Dbg,
+ "Create new mailslot, Fcb = %08lx\n",
+ (ULONG)fcb );
+
+ Irp->IoStatus = MsCreateMailslot(
+ fcb,
+ fileObject,
+ fileName,
+ desiredAccess,
+ createDisposition,
+ shareAccess,
+ mailslotQuota,
+ maximumMessageSize,
+ readTimeout,
+ creatorProcess,
+ irpSp->Parameters.CreateMailslot.SecurityContext->AccessState
+ );
+
+ status = Irp->IoStatus.Status;
+
+ } else {
+
+ DebugTrace(0, Dbg, "Illegal object name\n", 0);
+ status = STATUS_OBJECT_NAME_INVALID;
+
+ }
+ }
+
+ //
+ // Complete the IRP and return to the caller.
+ //
+
+ MsCompleteRequest( Irp, status );
+ try_return( NOTHING );
+
+ try_exit: NOTHING;
+ } finally {
+
+ MsReleaseVcb( vcb );
+ }
+
+ DebugTrace(-1, Dbg, "MsCommonCreateMailslot -> %08lx\n", status);
+ return status;
+}
+
+
+IO_STATUS_BLOCK
+MsCreateMailslot (
+ IN PROOT_DCB RootDcb,
+ IN PFILE_OBJECT FileObject,
+ IN UNICODE_STRING FileName,
+ IN ACCESS_MASK DesiredAccess,
+ IN ULONG CreateDisposition,
+ IN USHORT ShareAccess,
+ IN ULONG MailslotQuota,
+ IN ULONG MaximumMessageSize,
+ IN LARGE_INTEGER ReadTimeout,
+ IN PEPROCESS CreatorProcess,
+ IN PACCESS_STATE AccessState
+ )
+
+/*++
+
+Routine Description:
+
+ This routine performs the operation for creating a new mailslot
+ Fcb. This routine does not complete any IRP, it preforms its
+ function and then returns an iosb.
+
+Arguments:
+
+ RootDcb - Supplies the root dcb where this is going to be added.
+
+ FileObject - Supplies the file object associated with the mailslot.
+
+ FileName - Supplies the name of the mailslot (not qualified i.e.,
+ simply "mailslot-name" and not "\mailslot-name".
+
+ DesiredAccess - Supplies the caller's desired access.
+
+ CreateDisposition - Supplies the caller's create disposition flags.
+
+ ShareAccess - Supplies the caller specified share access.
+
+ MailslotQuota - Supplies the mailslot quota amount.
+
+ MaximumMessageSize - Supplies the size of the largest message that
+ can be written to this mailslot.
+
+ CreatorProcess - Supplies the process creating the mailslot.
+
+Return Value:
+
+ IO_STATUS_BLOCK - Returns the status of the operation.
+
+--*/
+
+{
+ // FIX, FIX - TEMPORARY ONLY.
+ UCHAR SDBody[SECURITY_DESCRIPTOR_MIN_LENGTH];
+ PSECURITY_DESCRIPTOR TmpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&SDBody[0]);
+ // FIX, FIX - TEMPORARY ONLY.
+
+ IO_STATUS_BLOCK iosb;
+ PFCB fcb;
+
+ PAGED_CODE();
+ DebugTrace(+1, Dbg, "MsCreateMailslot\n", 0 );
+
+ fcb = NULL;
+ iosb.Status = STATUS_UNSUCCESSFUL;
+
+ try {
+
+ //
+ // Check the parameters that must be supplied for a mailslot
+ //
+
+ if (CreateDisposition == FILE_OPEN) {
+ try_return( iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND );
+ }
+
+ //
+ // Create a new FCB for the mailslot.
+ //
+
+ fcb = MsCreateFcb( RootDcb->Vcb,
+ RootDcb,
+ &FileName,
+ CreatorProcess,
+ MailslotQuota,
+ MaximumMessageSize );
+
+ fcb->Specific.Fcb.ReadTimeout = ReadTimeout;
+
+ //
+ // Set the security descriptor in the Fcb
+ //
+
+ SeLockSubjectContext( &AccessState->SubjectSecurityContext );
+
+ iosb.Status = SeAssignSecurity( NULL,
+ AccessState->SecurityDescriptor,
+ &fcb->SecurityDescriptor,
+ FALSE,
+ &AccessState->SubjectSecurityContext,
+ IoGetFileObjectGenericMapping(),
+ PagedPool );
+
+ SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
+
+ if (!NT_SUCCESS(iosb.Status)) {
+
+ DebugTrace(0, Dbg, "Error calling SeAssignSecurity\n", 0 );
+
+ try_return( iosb.Status );
+ }
+
+ //
+ // Set the new share access.
+ //
+
+ IoSetShareAccess( DesiredAccess,
+ ShareAccess,
+ FileObject,
+ &fcb->ShareAccess );
+
+ //
+ // Set the file object back pointers and our pointer to the
+ // server file object.
+ //
+
+ MsSetFileObject( FileObject,
+ fcb,
+ NULL );
+
+ fcb->FileObject = FileObject;
+
+ //
+ // Update the FCB timestamps.
+ //
+
+ KeQuerySystemTime( &fcb->Specific.Fcb.CreationTime );
+ fcb->Specific.Fcb.LastModificationTime = fcb->Specific.Fcb.CreationTime;
+ fcb->Specific.Fcb.LastAccessTime = fcb->Specific.Fcb.CreationTime;
+ fcb->Specific.Fcb.LastChangeTime = fcb->Specific.Fcb.CreationTime;
+
+ //
+ // Set the return status.
+ //
+
+ iosb.Status = STATUS_SUCCESS;
+ iosb.Information = FILE_CREATED;
+
+ //
+ // The root directory has changed. Complete any notify change
+ // directory requests.
+ //
+
+ MsCheckForNotify( fcb->ParentDcb, TRUE );
+
+ try_exit: NOTHING;
+ } finally {
+
+ //
+ // Now if we ever terminate the preceding try-statement with
+ // a status that is not successful and the FCB pointer
+ // is non-null then we need to deallocate the structure.
+ //
+
+ if (!NT_SUCCESS(iosb.Status) && fcb != NULL) {
+
+ //
+ // Remove the Fcb from the prefix table.
+ //
+
+ MsAcquirePrefixTableLock();
+ RtlRemoveUnicodePrefix( &fcb->Vcb->PrefixTable, &fcb->PrefixTableEntry );
+ MsReleasePrefixTableLock();
+
+ //
+ // Remove the Fcb from our parent DCB's queue.
+ //
+
+ RemoveEntryList( &fcb->ParentDcbLinks );
+
+ MsDeleteFcb( fcb );
+ }
+
+ }
+
+ //
+ // Return to the caller.
+ //
+
+ DebugTrace(-1, Dbg, "MsCreateMailslot -> %08lx\n", iosb.Status);
+ return iosb;
+}
+
+BOOLEAN
+MsIsNameValid (
+ PUNICODE_STRING Name
+ )
+
+/*++
+
+Routine Description:
+
+ This routine tests for illegal characters in a name. The same character
+ set as Npfs/Ntfs is used. Also preceding backslashes, wildcards, and
+ path names are not allowed.
+
+Arguments:
+
+ Name - The name to search for illegal characters
+
+Return Value:
+
+ BOOLEAN - TRUE if the name is valid, FALSE otherwise.
+
+--*/
+
+{
+ ULONG i;
+
+ PAGED_CODE();
+ for (i=0; i < Name->Length / sizeof(WCHAR); i += 1) {
+
+ WCHAR Char = Name->Buffer[i];
+
+ if ( (Char <= 0xff) && (Char != L'\\') &&
+ !FsRtlIsAnsiCharacterLegalNtfs(Char, FALSE) ) {
+
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}