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