///////////////////////////////////////////////////////////////////////////////
//
//    (C) Copyright 1995 - 2005 OSR Open Systems Resources, Inc.
//    All Rights Reserved
//
//    This sofware is supplied for instructional purposes only.
//
//    OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
//    for this software.  THIS SOFTWARE IS PROVIDED  "AS IS" WITHOUT WARRANTY
//    OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
//    THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
//    PURPOSE.  THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
//    WITH YOU.  OSR's entire liability and your exclusive remedy shall not
//    exceed the price paid for this material.  In no event shall OSR or its
//    suppliers be liable for any damages whatsoever (including, without
//    limitation, damages for loss of business profit, business interruption,
//    loss of business information, or any other pecuniary loss) arising out
//    of the use or inability to use this software, even if OSR has been
//    advised of the possibility of such damages.  Because some states/
//    jurisdictions do not allow the exclusion or limitation of liability for
//    consequential or incidental damages, the above limitation may not apply
//    to you.
//
//    OSR Open Systems Resources, Inc.
//    105 Route 101A Suite 19
//    Amherst, NH 03031  (603) 595-6500 FAX: (603) 595-6503
//    email bugs to: bugs@osr.com
//
//
//    MODULE:
//
//        OSR_PCI.H
//
//    ABSTRACT:
//
//		This is the general include file for the REDIRECT sample driver.
//
//    AUTHOR(S):
//
//        OSR Open Systems Resources, Inc.
// 
//    REVISION:   
//
//
///////////////////////////////////////////////////////////////////////////////
#ifndef __OSR_REDIRECT_H__
#define __OSR_REDIRECT_H__ (1) // suppress duplicate loading of this file

extern "C" {

#include <ntddk.h>
#include <ntstrsafe.h>

}

//
// This is used to disable prefast warning messages.
//
#ifdef _PREFAST_
#pragma prefast(disable:316)
#pragma prefast(disable:8101)
#endif

#include "REDIRECT_IOCTL.h"

#define DRIVER_NAME "Redirect"

//
// Client Identification Address used to identify Driver Object
// Extension used by Redirect Driver.
//
#define REDIRECT_EXTENSION_IDENTIFICATION_ADDRESS  0x456534EE

//
// Driver Object Extension.   Used by Redirector device.
//
typedef struct _REDIRECT_DRIVER_OBJECT_EXT
{
    //
    // Magic Number, used for authenticity.
    //
    ULONG               MagicNumber;

    //
    // Address of Controller Device Object.
    //
    PDEVICE_OBJECT      RedirectorDeviceObject;

} REDIRECT_DRIVER_OBJECT_EXT, *PREDIRECT_DRIVER_OBJECT_EXT;

#define REDIRECT_DRIVER_OBJECT_EXT_MAGIC_NUMBER  0x46831456

//
// Common Device Object Extension, used by Redirector device
// and other devices created by this driver.
//
typedef struct _COMMON_EXT
{
    //
    // Set to TRUE if this is the Redirector
    // device. FALSE if ENCRYPT Device.
    //
    BOOLEAN                     Redirector;

    //
    // Address of Driver Extension, used by Redirector.
    //
    PREDIRECT_DRIVER_OBJECT_EXT DriverObjectExt;

} COMMON_EXT, *PCOMMON_EXT;

//
// Redirector Device Extension
//
typedef struct _REDIRECT_CTL_EXT
{
    //
    // Common Device Extension.
    //
    COMMON_EXT          Common;

    //
    // Mutex protect Device Name List.
    //
    FAST_MUTEX          DeviceNameListLock;

    //
    // List of all known Device Names. Protected by
    // DeviceNameListLock.
    //
    LIST_ENTRY          DeviceNameList;

    //
    // Count of the number of entries in the list.
    //
    ULONG               DeviceNameListCount;

    //
    // Next List Entry to redirect to.
    //
    ULONG               DeviceNameListIndex;

} REDIRECT_CTL_EXT, *PREDIRECT_CTL_EXT;

//
// ENCRYPT Device Extension
//
// This is the per-device component of the device object.
//
typedef struct _ENCRYPT_DEV_EXT
{
    //
    // Common Device Extension.
    //
    COMMON_EXT          Common;

	//
	// Device information
	//
	PDEVICE_OBJECT		DeviceObject;

    //
    // Registered with Controller synchronized by
    // DeviceNameListLock in Controller.
    //
    BOOLEAN             Registered;

    //
    // If registered, then this is the List Entry used to
    // Link the Device Object into the list of registed
    // devices.   Synchronized by DeviceNameListLock in Controller.
    //
    LIST_ENTRY          RegisteredListEntry;

    //
    // Device Name, used when registering with Controller
    //
    UNICODE_STRING      DeviceName;

	//
	// PDO
	//
	PDEVICE_OBJECT		Pdo;

    //
    // Underlying device object (could be a filter of the PDO)
    //
    PDEVICE_OBJECT      DeviceToSendIrpsTo;

	//
	// Other cool stuff would normally go here
	//

    UNICODE_STRING      InterfaceUnicodeString;

    // 
	// Power States
	//

	SYSTEM_POWER_STATE	SystemPowerState;
	DEVICE_POWER_STATE	DevicePowerState;

    //
    // IRP storage
    //
    PIRP                SystemIrp;

} ENCRYPT_DEVICE_EXT, *PENCRYPT_DEVICE_EXT;

//
// Function Declarations
//

//
// File Redirect.c
//
VOID     RedirectUnload(PDRIVER_OBJECT DriverObject);


//
// File RedirectIO.cpp
//
NTSTATUS RedirectDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS RedirectCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS RedirectClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS RedirectWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS RedirectRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS RedirectSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);

//
// File RedirectPnp.cpp
//
NTSTATUS RedirectPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS RedirectAddDevice(IN PDRIVER_OBJECT  DriverObject,
                           IN PDEVICE_OBJECT  PhysicalDeviceObject);

//
// File RedirectPower.cpp
//
NTSTATUS RedirectPower(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
VOID RedirectFDOPowerTransitionPoRequestComplete (IN PDEVICE_OBJECT      DeviceObject,
                                                 IN UCHAR               MinorFunction,
                                                 IN POWER_STATE         DevicePowerState,
                                                 IN PVOID               Context, 
                                                 IN PIO_STATUS_BLOCK    IoStatus);
NTSTATUS RedirectFDOPowerComplete(IN PDEVICE_OBJECT  DeviceObject,
                                 IN PIRP            Irp,
                                 IN PVOID           Context);

//
// File Redirectctrl.cpp
//
void RegisterWithRedirect(PENCRYPT_DEVICE_EXT DevExt);
void UnregisterWithRedirect(PENCRYPT_DEVICE_EXT DevExt);
NTSTATUS RedirectCreateRequest(PREDIRECT_CTL_EXT CtlExt,PIRP Irp);


#endif /* __OSR_REDIRECT_H__ */
