123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /*++
- Copyright (c) 2013 Minoca Corp. All Rights Reserved
- Module Name:
- iohandle.c
- Abstract:
- This module implements support for managing I/O handles.
- Author:
- Evan Green 25-Apr-2013
- Environment:
- Kernel
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <minoca/kernel/kernel.h>
- #include "iop.h"
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define IO_HANDLE_ALLOCATION_TAG 0x61486F49 // 'aHoI'
- #define IO_HANDLE_MAX_REFERENCE_COUNT 0x10000000
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // ------------------------------------------------------------------ Functions
- //
- KERNEL_API
- ULONG
- IoGetIoHandleAccessPermissions (
- PIO_HANDLE IoHandle
- )
- /*++
- Routine Description:
- This routine returns the access permissions for the given I/O handle.
- Arguments:
- IoHandle - Supplies a pointer to an I/O handle.
- Return Value:
- Returns the access permissions for the given I/O handle.
- --*/
- {
- return IoHandle->Access;
- }
- KERNEL_API
- ULONG
- IoGetIoHandleOpenFlags (
- PIO_HANDLE IoHandle
- )
- /*++
- Routine Description:
- This routine returns the current open flags for a given I/O handle. Some
- of these flags can change.
- Arguments:
- IoHandle - Supplies a pointer to an I/O handle.
- Return Value:
- Returns the current open flags for the I/O handle.
- --*/
- {
- return IoHandle->OpenFlags;
- }
- VOID
- IoIoHandleAddReference (
- PIO_HANDLE IoHandle
- )
- /*++
- Routine Description:
- This routine increments the reference count on an I/O handle.
- Arguments:
- IoHandle - Supplies a pointer to the I/O handle.
- Return Value:
- None.
- --*/
- {
- ULONG OldValue;
- OldValue = RtlAtomicAdd32(&(IoHandle->ReferenceCount), 1);
- ASSERT((OldValue != 0) && (OldValue < IO_HANDLE_MAX_REFERENCE_COUNT));
- return;
- }
- KSTATUS
- IoIoHandleReleaseReference (
- PIO_HANDLE IoHandle
- )
- /*++
- Routine Description:
- This routine decrements the reference count on an I/O handle. If the
- reference count becomes zero, the I/O handle will be destroyed.
- Arguments:
- IoHandle - Supplies a pointer to the I/O handle.
- Return Value:
- None.
- --*/
- {
- ULONG OldValue;
- KSTATUS Status;
- Status = STATUS_SUCCESS;
- OldValue = RtlAtomicAdd32(&(IoHandle->ReferenceCount), -1);
- ASSERT((OldValue != 0) && (OldValue < IO_HANDLE_MAX_REFERENCE_COUNT));
- if (OldValue == 1) {
- Status = IopClose(IoHandle);
- if (!KSUCCESS(Status)) {
- //
- // Restore the reference to the I/O handle.
- //
- RtlAtomicAdd32(&(IoHandle->ReferenceCount), 1);
- return Status;
- }
- MmFreePagedPool(IoHandle);
- }
- return Status;
- }
- PIMAGE_SECTION_LIST
- IoGetImageSectionListFromIoHandle (
- PIO_HANDLE IoHandle
- )
- /*++
- Routine Description:
- This routine gets the image section list for the given I/O handle.
- Arguments:
- IoHandle - Supplies a pointer to an I/O handle.
- Return Value:
- Returns a pointer to the I/O handles image section list or NULL on failure.
- --*/
- {
- PFILE_OBJECT FileObject;
- FileObject = IoHandle->FileObject;
- return IopGetImageSectionListFromFileObject(FileObject);
- }
- BOOL
- IoIoHandleIsCacheable (
- PIO_HANDLE IoHandle
- )
- /*++
- Routine Description:
- This routine determines whether or not data for the I/O object specified by
- the given handle is cached in the page cache.
- Arguments:
- IoHandle - Supplies a pointer to an I/O handle.
- Return Value:
- Returns TRUE if the I/O handle's object is cached or FALSE otherwise.
- --*/
- {
- PFILE_OBJECT FileObject;
- //
- // The I/O handle is deemed cacheable if the file object is cacheable.
- //
- FileObject = IoHandle->FileObject;
- if (IO_IS_FILE_OBJECT_CACHEABLE(FileObject) != FALSE) {
- return TRUE;
- }
- return FALSE;
- }
- KSTATUS
- IopCreateIoHandle (
- PIO_HANDLE *Handle
- )
- /*++
- Routine Description:
- This routine creates a new I/O handle with a reference count of one.
- Arguments:
- Handle - Supplies a pointer where a pointer to the new I/O handle will be
- returned on success.
- Return Value:
- Status code.
- --*/
- {
- PIO_HANDLE NewHandle;
- KSTATUS Status;
- //
- // Create the I/O handle structure.
- //
- NewHandle = MmAllocatePagedPool(sizeof(IO_HANDLE),
- IO_HANDLE_ALLOCATION_TAG);
- if (NewHandle == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto CreateIoHandleEnd;
- }
- RtlZeroMemory(NewHandle, sizeof(IO_HANDLE));
- NewHandle->HandleType = IoHandleTypeDefault;
- NewHandle->ReferenceCount = 1;
- ASSERT(NewHandle->DeviceContext == NULL);
- Status = STATUS_SUCCESS;
- CreateIoHandleEnd:
- if (!KSUCCESS(Status)) {
- if (NewHandle != NULL) {
- MmFreePagedPool(NewHandle);
- NewHandle = NULL;
- }
- }
- *Handle = NewHandle;
- return Status;
- }
- VOID
- IopOverwriteIoHandle (
- PIO_HANDLE Destination,
- PIO_HANDLE IoSource
- )
- /*++
- Routine Description:
- This routine takes the contents of the given source handle and overwrites
- the destination handle with it. I/O actions performed on the destination
- handle appear as if they were done to the I/O object of the source handle.
- This replacement does not replace any information about the original path
- opened in the destination. It also does not modify the access and open
- flags in the destination. This routine is not thread safe.
- Arguments:
- Destination - Supplies a pointer to the I/O handle that should magically
- redirect elsewhere.
- IoSource - Supplies a pointer to the I/O handle that contains the
- underlying I/O object the destination should interact with.
- Return Value:
- None.
- --*/
- {
- PFILE_OBJECT OldFileObject;
- //
- // The destination I/O handle really shouldn't be handed to anyone yet,
- // since I/O might get wonky during the switch.
- //
- ASSERT(Destination->ReferenceCount == 1);
- OldFileObject = Destination->FileObject;
- Destination->FileObject = IoSource->FileObject;
- if (OldFileObject != Destination->PathPoint.PathEntry->FileObject) {
- IopFileObjectReleaseReference(OldFileObject);
- }
- IopFileObjectAddReference(IoSource->FileObject);
- return;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
|