mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
6.7 KiB
274 lines
6.7 KiB
/*++
|
|
|
|
Copyright (c) 1998-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
create.cxx
|
|
|
|
Abstract:
|
|
|
|
This module contains code for opening a handle to UL.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 10-Jun-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text( PAGE, UlCreate )
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
This is the routine that handles Create IRPs in UL. Create IRPs are
|
|
issued when the file object is created.
|
|
|
|
Arguments:
|
|
|
|
pDeviceObject - Supplies a pointer to the target device object.
|
|
|
|
pIrp - Supplies a pointer to IO request packet.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Completion status.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
UlCreate(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN PIRP pIrp
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PIO_STACK_LOCATION pIrpSp;
|
|
PFILE_OBJECT pFileObject;
|
|
PFILE_FULL_EA_INFORMATION pEaBuffer;
|
|
PHTTP_OPEN_PACKET pOpenPacket;
|
|
UCHAR createDisposition;
|
|
PWSTR pName;
|
|
ULONG nameLength;
|
|
PIO_SECURITY_CONTEXT pSecurityContext;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
UL_ENTER_DRIVER( "UlCreate", pIrp );
|
|
|
|
//
|
|
// Find and validate the open packet.
|
|
//
|
|
|
|
pEaBuffer = (PFILE_FULL_EA_INFORMATION)(pIrp->AssociatedIrp.SystemBuffer);
|
|
|
|
if (pEaBuffer == NULL ||
|
|
pEaBuffer->EaValueLength != sizeof(*pOpenPacket) ||
|
|
pEaBuffer->EaNameLength != HTTP_OPEN_PACKET_NAME_LENGTH ||
|
|
strcmp( pEaBuffer->EaName, HTTP_OPEN_PACKET_NAME ) )
|
|
{
|
|
status = STATUS_REVISION_MISMATCH;
|
|
goto complete;
|
|
}
|
|
|
|
pOpenPacket =
|
|
(PHTTP_OPEN_PACKET)( pEaBuffer->EaName + pEaBuffer->EaNameLength + 1 );
|
|
|
|
ASSERT( (((ULONG_PTR)pOpenPacket) & 7) == 0 );
|
|
|
|
//
|
|
// For now, we'll fail if the incoming version doesn't EXACTLY match
|
|
// the expected version. In future, we may need to be a bit more
|
|
// flexible to allow down-level clients.
|
|
//
|
|
|
|
if (pOpenPacket->MajorVersion != HTTP_INTERFACE_VERSION_MAJOR ||
|
|
pOpenPacket->MinorVersion != HTTP_INTERFACE_VERSION_MINOR)
|
|
{
|
|
status = STATUS_REVISION_MISMATCH;
|
|
goto complete;
|
|
}
|
|
|
|
//
|
|
// Snag the current IRP stack pointer, then extract the creation
|
|
// disposition. IO stores this as the high byte of the Options field.
|
|
// Also snag the file object; we'll need it often.
|
|
//
|
|
|
|
pIrpSp = IoGetCurrentIrpStackLocation( pIrp );
|
|
|
|
createDisposition = (UCHAR)( pIrpSp->Parameters.Create.Options >> 24 );
|
|
pFileObject = pIrpSp->FileObject;
|
|
pSecurityContext = pIrpSp->Parameters.Create.SecurityContext;
|
|
ASSERT( pSecurityContext != NULL );
|
|
|
|
//
|
|
// Determine if this is a request to open a control channel or
|
|
// open/create an app pool.
|
|
//
|
|
|
|
if (pDeviceObject == g_pUlControlDeviceObject)
|
|
{
|
|
//
|
|
// It's a control channel.
|
|
//
|
|
// Validate the creation disposition. We allow open only.
|
|
//
|
|
|
|
if (createDisposition != FILE_OPEN)
|
|
{
|
|
status = STATUS_INVALID_PARAMETER;
|
|
goto complete;
|
|
}
|
|
|
|
//
|
|
// Open the control channel.
|
|
//
|
|
|
|
status = UlOpenControlChannel(GET_PP_CONTROL_CHANNEL(pFileObject));
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
ASSERT( GET_CONTROL_CHANNEL(pFileObject) != NULL );
|
|
MARK_VALID_CONTROL_CHANNEL( pFileObject );
|
|
}
|
|
}
|
|
else if (pDeviceObject == g_pUlFilterDeviceObject)
|
|
{
|
|
//
|
|
// It's a filter channel.
|
|
//
|
|
// Validate the creation disposition. We allow create and open
|
|
//
|
|
|
|
if (createDisposition != FILE_CREATE && createDisposition != FILE_OPEN)
|
|
{
|
|
status = STATUS_INVALID_PARAMETER;
|
|
goto complete;
|
|
}
|
|
|
|
//
|
|
// Make sure there's a name with a reasonable length
|
|
//
|
|
if (pFileObject->FileName.Buffer == NULL ||
|
|
pFileObject->FileName.Length < sizeof(WCHAR) ||
|
|
pFileObject->FileName.Length > UL_MAX_FILTER_NAME_LENGTH)
|
|
{
|
|
status = STATUS_OBJECT_NAME_INVALID;
|
|
goto complete;
|
|
}
|
|
|
|
//
|
|
// Bind to the specified filter channel.
|
|
//
|
|
pName = pFileObject->FileName.Buffer + 1;
|
|
nameLength = pFileObject->FileName.Length - sizeof(WCHAR);
|
|
|
|
status = UlAttachFilterProcess(
|
|
pName,
|
|
nameLength,
|
|
(BOOLEAN)(createDisposition == FILE_CREATE),
|
|
pSecurityContext->AccessState,
|
|
pSecurityContext->DesiredAccess,
|
|
pIrp->RequestorMode,
|
|
GET_PP_FILTER_PROCESS(pFileObject)
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
ASSERT( GET_FILTER_PROCESS(pFileObject) != NULL );
|
|
MARK_VALID_FILTER_CHANNEL( pFileObject );
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
ASSERT( pDeviceObject == g_pUlAppPoolDeviceObject );
|
|
|
|
//
|
|
// It's an app pool.
|
|
//
|
|
// Validate the creation disposition. We allow create and open.
|
|
//
|
|
|
|
if (createDisposition != FILE_CREATE && createDisposition != FILE_OPEN)
|
|
{
|
|
status = STATUS_INVALID_PARAMETER;
|
|
goto complete;
|
|
}
|
|
|
|
//
|
|
// Bind to the specified app pool.
|
|
//
|
|
|
|
if (pFileObject->FileName.Buffer == NULL ||
|
|
pFileObject->FileName.Length < sizeof(WCHAR))
|
|
{
|
|
pName = NULL;
|
|
nameLength = 0;
|
|
}
|
|
else
|
|
{
|
|
pName = pFileObject->FileName.Buffer + 1;
|
|
nameLength = pFileObject->FileName.Length - sizeof(WCHAR);
|
|
}
|
|
|
|
status = UlAttachProcessToAppPool(
|
|
pName,
|
|
nameLength,
|
|
(BOOLEAN)(createDisposition == FILE_CREATE),
|
|
pSecurityContext->AccessState,
|
|
pSecurityContext->DesiredAccess,
|
|
pIrp->RequestorMode,
|
|
GET_PP_APP_POOL_PROCESS(pFileObject)
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
ASSERT( GET_APP_POOL_PROCESS(pFileObject) != NULL );
|
|
MARK_VALID_APP_POOL( pFileObject );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Complete the request.
|
|
//
|
|
|
|
complete:
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
IF_DEBUG( OPEN_CLOSE )
|
|
{
|
|
KdPrint((
|
|
"UlCreate: opened file object = %lx\n",
|
|
pFileObject
|
|
));
|
|
}
|
|
}
|
|
|
|
pIrp->IoStatus.Status = status;
|
|
|
|
UlCompleteRequest( pIrp, g_UlPriorityBoost );
|
|
|
|
UL_LEAVE_DRIVER( "UlCreate" );
|
|
RETURN(status);
|
|
|
|
} // UlCreate
|
|
|