/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * WinIoEx - DriverEntry.c
 *
 * WinIoEx Copyright (C) 2009-2010 Doug Chen.
 * 
 *
 * You can use the binary files or source code, I DO NOT restrict you anything on anywhere even 
 * commercial purpose, but please send a mail or leave a message on MSN to me before releasing your 
 * project for encourage me keep going on the project, thank you.
 *
 *
 *                                                           Doug Chen, 2009/11/10 20:23 Taiwan Taipei
 *	
 *	Name		: Doug Chen  (³―Αδ·½)
 * 	Email		: dougchen850208@gmail.com
 * 	MSN			: dougchen850208@gmail.com
 *  Location	: Taiwan Taipei
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


#include "Driver.h"



//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
NTSTATUS DriverEntry (  IN PDRIVER_OBJECT   DriverObject, 
                        IN PUNICODE_STRING  RegistryPath)
{

    PDEVICE_EXTENSION 	m_pDevExt		= NULL;
    PDEVICE_OBJECT  	m_pDevObj 		= NULL;
	
	NTSTATUS 			m_NtStatus   	= STATUS_SUCCESS;
    ULONG 				m_DevExSize     = sizeof(DEVICE_EXTENSION);
	
	UNICODE_STRING 		m_DevName;
    UNICODE_STRING 		m_DevSymboName;
	
	KdPrint((DRVNAME "DriverEntry() Begin \r\n"));              
	
	
    DriverObject->DriverUnload                  		= DriverUnload;
    
    DriverObject->MajorFunction[IRP_MJ_CREATE]          = DispatchCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           = DispatchClose;
    DriverObject->MajorFunction[IRP_MJ_PNP]             = DispatchPnp;       
    DriverObject->MajorFunction[IRP_MJ_POWER]           = DispatchPower;            //Ayr++
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = DispatchDeviceIoControl;     
	
	

    
	RtlInitUnicodeString(&m_DevName, 		NT_DEVICE_NAME);
    RtlInitUnicodeString(&m_DevSymboName, 	DOS_DEVICE_NAME);
	
	
    m_NtStatus = IoCreateDevice( DriverObject,
								 m_DevExSize,
								&m_DevName,
								 FILE_DEVICE_UNKNOWN,
								 0,
								 FALSE,
								&m_pDevObj);
	                          
	if (!NT_SUCCESS(m_NtStatus)) 
	{	
		KdPrint((DRVNAME "IoCreateDevice() false \r\n"));   
		return m_NtStatus;
    }
		
	
	m_NtStatus = IoCreateSymbolicLink(&m_DevSymboName, &m_DevName);
	
	if (!NT_SUCCESS(m_NtStatus)) 
	{
		KdPrint((DRVNAME "IoCreateSymbolicLink() false \r\n"));   
		IoDeleteDevice(DriverObject->DeviceObject);
		return m_NtStatus;
	}
	
	
	m_pDevExt = (PDEVICE_EXTENSION)m_pDevObj->DeviceExtension;
	RtlZeroMemory(m_pDevExt, m_DevExSize);
	
	m_pDevExt->pdo = m_pDevObj;	
	//m_pDevExt->LowerDeviceObject = IoAttachDeviceToDeviceStack(m_pDevObj, m_pDevObj);
	
    // if (m_pDevExt->LowerDeviceObject == NULL)                                          
	// {		  	
        // KdPrint((DRVNAME "LowerDeviceObject object null!\r\n"));              
        // m_NtStatus = STATUS_DEVICE_REMOVED;                                        
        // IoDeleteDevice(m_pDevObj);                                         
        // return m_NtStatus;                                             
    // }                                                                
               
	m_pDevObj->Flags |= DO_BUFFERED_IO;
	m_pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
	                        

	KdPrint((DRVNAME "DriverEntry() Terminate \r\n"));              
    return m_NtStatus;            
}












//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING m_DevSymbName;
        
    KdPrint((DRVNAME "DriverUnload() Begin\r\n"));
    
	//Remark below section because PNP feature will do it.
	RtlInitUnicodeString(&m_DevSymbName, DOS_DEVICE_NAME);
	
    IoDeleteSymbolicLink(&m_DevSymbName);
    IoDeleteDevice(DriverObject->DeviceObject);
    
	
	
	
	KdPrint((DRVNAME "DriverUnload() Terminate\r\n"));
}	







//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
NTSTATUS CompleteRequest(   PIRP        Irp, 
                            NTSTATUS    status, 
                            ULONG       info)
{
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = info;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}










//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
NTSTATUS CompleteIrp(   PIRP        Irp,
                        NTSTATUS    status,
                        ULONG       info)
{
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = info;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}						    












//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
void SysDelay(ULONG delayTime)
{
    LARGE_INTEGER   SysTimeout;
    ULONG Cnt;

    if (KeGetCurrentIrql() >= DISPATCH_LEVEL) 
    {
        Cnt = 20 * delayTime;
        while (Cnt--) 
        {
            KeStallExecutionProcessor(50);
        }
    }
    else 
    {
        SysTimeout.QuadPart = (LONGLONG)-10 * 1000 * delayTime;
        KeDelayExecutionThread(KernelMode, FALSE, &SysTimeout);
    }
}




