///////////////////////////////////////////////////////////////////////////////
//
//    (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:
//
//        Redirect.C -- Redirect driver V2
//
//    ABSTRACT:
//
//      This file contains the skeleton status for a WDM/Win2K device driver
//      that does absolutely Redirect.
//
//    AUTHOR(S):
//
//        OSR Open Systems Resources, Inc.
// 
//    REVISION:   
//
//        This is a WDM compatible version of the original NT V4
//        REDIRECT driver.
//
///////////////////////////////////////////////////////////////////////////////
#include "redirect.h"

//
// Forward Declarations
//
// The following function appear in this file in the following order:
//
extern "C" {

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObj, PUNICODE_STRING RegistryPath);

};


//
// The following pragma allows the DriverEntry status to be discarded once
// initialization is completed
//
#pragma alloc_text(INIT,DriverEntry)

///////////////////////////////////////////////////////////////////////////////
//
//  DriverEntry
//
//    This routine is called by NT when the driver is first loaded.  It is the
//    responsibility of this routine to find it's device and create whatever
//    device objects it needs.
//
//  INPUTS:
//
//      DriverObj - Address of the DRIVER_OBJECT created by NT for this driver.
//
//      RegistryPath - UNICODE_STRING which represents this drivers KEY in the
//                   Registry.  
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_SUCCESS. Otherwise an error indicating why the driver could not
//                    Load.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObj, PUNICODE_STRING RegistryPath)
{
    NTSTATUS status;
    PENCRYPT_DEVICE_EXT devExt;
    PDEVICE_OBJECT devObj;
    UNICODE_STRING devName, linkName;

#if DBG
    DbgPrint("\nOSR " DRIVER_NAME " Driver -- Compiled %s %s\n",
             __DATE__, __TIME__);
#endif

    //
    // Establish dispatch entry points for the functions we support
    //

    //
    // Note same function for create and close handling
    //
    DriverObj->MajorFunction[IRP_MJ_CREATE]         =  RedirectCreate;
    DriverObj->MajorFunction[IRP_MJ_CLOSE]          =  RedirectClose;

    DriverObj->MajorFunction[IRP_MJ_READ]           =  RedirectRead;
    DriverObj->MajorFunction[IRP_MJ_WRITE]          =  RedirectWrite;
    DriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] =  RedirectDeviceControl;
	DriverObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =  RedirectSystemControl;

    DriverObj->MajorFunction[IRP_MJ_PNP] = RedirectPnp;
    DriverObj->MajorFunction[IRP_MJ_POWER] = RedirectPower;

    DriverObj->DriverExtension->AddDevice = RedirectAddDevice;

    //
    // Unload function
    //
    DriverObj->DriverUnload = RedirectUnload;


#if DBG
    DbgPrint(DRIVER_NAME "DriverEntry: Leaving\n");
#endif

    return(STATUS_SUCCESS);
}


///////////////////////////////////////////////////////////////////////////////
//
//  RedirectUnload
//
//    This routine is our dynamic unload entry point.  We are called here when
//    the OS wants to unload our driver.  It is our responsibility to release
//    any global resources we allocated.  Since we delete our device object
//    (and its symbolic link) during PnP REMOVE_DEVICE processing, there's
//    really Redirect to do here.
//
//  INPUTS:
//
//      DriverObj - Address of our DRIVER_OBJECT.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
VOID
RedirectUnload(PDRIVER_OBJECT DriverObject)
{
#if DBG
    DbgPrint(DRIVER_NAME " Unload: Starting\n");

    //
    // The device object should already be deleted (and GONE) at
    // this point 
    //
    ASSERT(!DriverObject->DeviceObject);

    DbgPrint(DRIVER_NAME " Unload: Leaving... \n");
#endif // DBG
}


