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.
293 lines
7.2 KiB
293 lines
7.2 KiB
/*++
|
|
|
|
Copyright (c) 1998-2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
close.c
|
|
|
|
Abstract:
|
|
|
|
This module contains code for cleanup and close IRPs.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 10-Jun-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text( PAGE, UlClose )
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
#if 0
|
|
NOT PAGEABLE -- UlCleanup
|
|
#endif
|
|
|
|
|
|
/*
|
|
|
|
|
|
Relationship between Cleanup & Close IRPs --> IOCTLs won't be called after the
|
|
handle has been "Cleaned", but there can be a race between IOCTLs & Cleanup.
|
|
Close is called only when all IOCTLs are completed. Abnormal termination of an
|
|
application (e.g. AV) will exercize the cleanup paths in a different way than
|
|
CloseHandle(). Make sure we have tests that do abnormal termination.
|
|
|
|
|
|
*/
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
This is the routine that handles Cleanup IRPs in UL. Cleanup IRPs
|
|
are issued after the last handle to the file object is closed.
|
|
|
|
Arguments:
|
|
|
|
pDeviceObject - Supplies a pointer to the target device object.
|
|
|
|
pIrp - Supplies a pointer to IO request packet.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Completion status.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
UlCleanup(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN PIRP pIrp
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PIO_STACK_LOCATION pIrpSp;
|
|
|
|
UL_ENTER_DRIVER( "UlCleanup", pIrp );
|
|
|
|
//
|
|
// Snag the current IRP stack pointer.
|
|
//
|
|
|
|
pIrpSp = IoGetCurrentIrpStackLocation( pIrp );
|
|
|
|
//
|
|
// app pool or control channel?
|
|
//
|
|
|
|
if (pDeviceObject == g_pUlAppPoolDeviceObject &&
|
|
IS_APP_POOL( pIrpSp->FileObject ))
|
|
{
|
|
//
|
|
// App pool, let's detach this process from the app pool.
|
|
// The detach will also take care of the Irp completion
|
|
// for us.
|
|
//
|
|
|
|
UlTrace(OPEN_CLOSE,(
|
|
"UlCleanup: cleanup on AppPool object %p\n",
|
|
pIrpSp->FileObject
|
|
));
|
|
|
|
status = UlDetachProcessFromAppPool( pIrp, pIrpSp );
|
|
|
|
UL_LEAVE_DRIVER("UlCleanup");
|
|
RETURN(status);
|
|
}
|
|
|
|
if (pDeviceObject == g_pUlFilterDeviceObject &&
|
|
IS_FILTER_PROCESS( pIrpSp->FileObject ))
|
|
{
|
|
//
|
|
// filter channel
|
|
//
|
|
|
|
UlTrace(OPEN_CLOSE,(
|
|
"UlCleanup: cleanup on FilterProcess object %p\n",
|
|
pIrpSp->FileObject
|
|
));
|
|
|
|
status = UlDetachFilterProcess(
|
|
GET_FILTER_PROCESS(pIrpSp->FileObject)
|
|
);
|
|
|
|
MARK_INVALID_FILTER_CHANNEL( pIrpSp->FileObject );
|
|
}
|
|
else if (pDeviceObject == g_pUlControlDeviceObject &&
|
|
IS_CONTROL_CHANNEL( pIrpSp->FileObject ))
|
|
{
|
|
PUL_CONTROL_CHANNEL pControlChannel =
|
|
GET_CONTROL_CHANNEL( pIrpSp->FileObject );
|
|
|
|
UlTrace(OPEN_CLOSE,(
|
|
"UlCleanup: cleanup on ControlChannel object %p, %p\n",
|
|
pIrpSp->FileObject,pControlChannel
|
|
));
|
|
|
|
MARK_INVALID_CONTROL_CHANNEL( pIrpSp->FileObject );
|
|
|
|
UlCleanUpControlChannel( pControlChannel );
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else if (pDeviceObject == g_pUcServerDeviceObject &&
|
|
IS_SERVER( pIrpSp->FileObject ))
|
|
{
|
|
UlTrace(OPEN_CLOSE,(
|
|
"UlCleanup: cleanup on Server object %p\n",
|
|
pIrpSp->FileObject
|
|
));
|
|
|
|
MARK_INVALID_SERVER( pIrpSp->FileObject );
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
UlTrace(OPEN_CLOSE,(
|
|
"UlCleanup: cleanup on invalid object %p\n",
|
|
pIrpSp->FileObject
|
|
));
|
|
|
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
|
}
|
|
|
|
pIrp->IoStatus.Status = status;
|
|
|
|
UlCompleteRequest( pIrp, IO_NO_INCREMENT );
|
|
|
|
UL_LEAVE_DRIVER( "UlCleanup" );
|
|
RETURN(status);
|
|
|
|
} // UlCleanup
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
This is the routine that handles Close IRPs in UL. Close IRPs are
|
|
issued after the last reference to the file object is removed.
|
|
|
|
Once the close IRP is called, it is guaranteed by IO Manager that no
|
|
other IOCTL call will happen for the object we are about to close.
|
|
Therefore actual cleanup for the object must happen at this time,
|
|
but * not * at the cleanup time.
|
|
|
|
Arguments:
|
|
|
|
pDeviceObject - Supplies a pointer to the target device object.
|
|
|
|
pIrp - Supplies a pointer to IO request packet.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Completion status.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
UlClose(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN PIRP pIrp
|
|
)
|
|
{
|
|
|
|
NTSTATUS status;
|
|
PIO_STACK_LOCATION pIrpSp;
|
|
|
|
UNREFERENCED_PARAMETER( pDeviceObject );
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
UL_ENTER_DRIVER( "UlClose", pIrp );
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
//
|
|
// Snag the current IRP stack pointer.
|
|
//
|
|
|
|
pIrpSp = IoGetCurrentIrpStackLocation( pIrp );
|
|
|
|
//
|
|
// We have to delete the associated object.
|
|
//
|
|
if (pDeviceObject == g_pUlAppPoolDeviceObject &&
|
|
IS_EX_APP_POOL( pIrpSp->FileObject ))
|
|
{
|
|
UlTrace(OPEN_CLOSE, (
|
|
"UlClose: closing AppPool object %p\n",
|
|
pIrpSp->FileObject
|
|
));
|
|
|
|
UlCloseAppPoolProcess(GET_APP_POOL_PROCESS(pIrpSp->FileObject));
|
|
}
|
|
else if (pDeviceObject == g_pUlFilterDeviceObject &&
|
|
IS_EX_FILTER_PROCESS( pIrpSp->FileObject ))
|
|
{
|
|
UlTrace(OPEN_CLOSE, (
|
|
"UlClose: closing Filter object %p\n",
|
|
pIrpSp->FileObject
|
|
));
|
|
|
|
UlCloseFilterProcess(GET_FILTER_PROCESS(pIrpSp->FileObject));
|
|
}
|
|
else if (pDeviceObject == g_pUcServerDeviceObject &&
|
|
IS_EX_SERVER(pIrpSp->FileObject ))
|
|
{
|
|
PUC_PROCESS_SERVER_INFORMATION pServInfo;
|
|
|
|
pServInfo = (PUC_PROCESS_SERVER_INFORMATION)
|
|
pIrpSp->FileObject->FsContext;
|
|
|
|
UlTrace(OPEN_CLOSE, (
|
|
"UlClose: closing Server object %p, %p\n",
|
|
pIrpSp->FileObject, pServInfo
|
|
));
|
|
|
|
//
|
|
// Free our context.
|
|
//
|
|
UcCloseServerInformation(pServInfo);
|
|
}
|
|
else if (pDeviceObject == g_pUlControlDeviceObject &&
|
|
IS_EX_CONTROL_CHANNEL( pIrpSp->FileObject ))
|
|
{
|
|
PUL_CONTROL_CHANNEL pControlChannel =
|
|
GET_CONTROL_CHANNEL( pIrpSp->FileObject );
|
|
|
|
UlTrace(OPEN_CLOSE, (
|
|
"UlClose: closing control channel object %p, %p\n",
|
|
pIrpSp->FileObject, pControlChannel
|
|
));
|
|
|
|
UlCloseControlChannel( pControlChannel );
|
|
}
|
|
else
|
|
{
|
|
ASSERT(!"Invalid Device Object !");
|
|
}
|
|
|
|
pIrp->IoStatus.Status = status;
|
|
|
|
UlCompleteRequest( pIrp, IO_NO_INCREMENT );
|
|
|
|
UL_LEAVE_DRIVER( "UlClose" );
|
|
RETURN(status);
|
|
|
|
} // UlClose
|
|
|