Source code of Windows XP (NT5)
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

/*++
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