⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 speedcd.c

📁 虚拟光驱程序
💻 C
📖 第 1 页 / 共 3 页
字号:


//
// Include files.
//

// Comment this out to turn off the debug log
//#define DEBUG_LOG

#include <ntddk.h>          // various NT definitions
#include <ntdddisk.h>       // disk device driver I/O control codes

// needed for general cdrom structs and defines
#include <ntddcdrm.h>

// needed for check verify
#include <devioctl.h>
#include <ntiologc.h>
#include <string.h>

#include "SPEEDCD.h"

#if DBG
ULONG   SPEEDCDDebugLevel = 0;
#endif
//#define DEBUG_LOG 1



//
// Debug Log Functions
//


VOID SPEEDCDLogWriteString(char * pMessage)
{
#ifdef DEBUG_LOG
	HANDLE FileHandle;
	IO_STATUS_BLOCK IoStatusBlock;
	OBJECT_ATTRIBUTES  ObjectAttributes;
	NTSTATUS status;
	UNICODE_STRING fileName;
	WCHAR fileNameBuf[] = L"\\SystemRoot\\system32\\drivers\\SPEEDCD.log";
	ULONG length;


	// find the length of the string that is passed in
	for (length = 0; length < 512 && pMessage[length] != 0; length++)
	{
		// do nothing!!
	}


	RtlInitUnicodeString( &fileName, fileNameBuf );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &fileName,
        OBJ_CASE_INSENSITIVE, // attributes
        NULL,
        NULL
        ); 

	status = ZwCreateFile(
		&FileHandle,
		FILE_APPEND_DATA,
		&ObjectAttributes,
		&IoStatusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN_IF,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,                /* optional */
		0
		); 

	if (NT_SUCCESS(status))
	{
		// good!!!
		// write something out and then close the file
		
		status = ZwWriteFile(
			FileHandle,NULL,NULL,NULL,
			&IoStatusBlock,pMessage,length,NULL,NULL);

		ZwClose(FileHandle); 

	}
#endif
}


VOID SPEEDCDLogWriteULong(ULONG ulValue)
{
#ifdef DEBUG_LOG
	UNICODE_STRING uMessage;
	ANSI_STRING asValue;
	WCHAR uMessageBuffer[50];
	char bufValue[55];

	RtlInitUnicodeString( &uMessage, NULL );
	uMessage.Length = 0;
	uMessage.MaximumLength = sizeof (uMessageBuffer)-sizeof(WCHAR);
	uMessage.Buffer = uMessageBuffer;

    RtlInitAnsiString(&asValue,NULL);
	asValue.Length = 0;
	asValue.MaximumLength = 50;
	asValue.Buffer = bufValue;

	RtlIntegerToUnicodeString(ulValue,16,&uMessage); 

	if (NT_SUCCESS(
		RtlUnicodeStringToAnsiString(
			&asValue,
			&uMessage,
			TRUE)
		))
	{
		if (asValue.Length < 45)
		{
			// add the null to the end of the string
			asValue.Buffer[asValue.Length] = 0;
			asValue.Length++;

			SPEEDCDLogWriteString(asValue.Buffer);
		}
	}
#endif
}

VOID SPEEDCDLogL(ULONG ulValue)
{
#ifdef DEBUG_LOG
	SPEEDCDLogWriteULong(ulValue);
	SPEEDCDLogWriteString("\x0d\x0a");
#endif
}

VOID SPEEDCDLogSL(char * pMessage,ULONG ulValue)
{
#ifdef DEBUG_LOG

	SPEEDCDLogWriteString(pMessage);
	SPEEDCDLogWriteULong(ulValue);
	SPEEDCDLogWriteString("\x0d\x0a");
#endif
}

VOID SPEEDCDLogS(char * pMessage)
{
#ifdef DEBUG_LOG

	SPEEDCDLogWriteString(pMessage);
	SPEEDCDLogWriteString("\x0d\x0a");
#endif
}

VOID SPEEDCDLogPU(PUNICODE_STRING puMessage)
{
#ifdef DEBUG_LOG
	ANSI_STRING asValue;
	char bufValue[512];

    RtlInitAnsiString(&asValue,NULL);
	asValue.Length = 0;
	asValue.MaximumLength = 500;
	asValue.Buffer = bufValue;

	if (NT_SUCCESS(
		RtlUnicodeStringToAnsiString( &asValue ,puMessage, FALSE)
		))
	{
		if (asValue.Length < 501)
		{
			// add the null to the end of the string
			asValue.Buffer[asValue.Length] = 0;
			asValue.Length++;

            SPEEDCDLogS(asValue.Buffer);
		}
	}
#endif
}

//
// Utility Function for reading the data file for the CD 
//

NTSTATUS SPEEDCDReadOffset(PLARGE_INTEGER offset,PVOID dest,ULONG length,
						   PUNICODE_STRING pFileName)
{
	IO_STATUS_BLOCK IoStatusBlock;
	OBJECT_ATTRIBUTES  ObjectAttributes;
	NTSTATUS status;
	HANDLE FileHandle;

	SPEEDCDLogS("begin SPEEDCDReadOffset");

	if (pFileName == NULL)
		return STATUS_DEVICE_NOT_READY;

    InitializeObjectAttributes(
        &ObjectAttributes,
        pFileName,//&fileName,
        OBJ_CASE_INSENSITIVE, // attributes
        NULL,
        NULL
        ); 

	status = ZwCreateFile(
		&FileHandle,
		GENERIC_READ,
		&ObjectAttributes,
		&IoStatusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ, // share read so we can open the same file more than once
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,                /* optional */
		0
		); 

	if (NT_SUCCESS(status))
	{

		SPEEDCDLogS("open success");

		// good!!!
		// write something out and then close the file
		
		status = ZwReadFile(
			FileHandle,NULL,NULL,NULL,
			&IoStatusBlock,dest,length,offset,NULL);

		if (NT_SUCCESS(status))
			SPEEDCDLogS("read success");
		else
			SPEEDCDLogS("read fail");

		ZwClose(FileHandle); 
	}
	return status;
}


//
// DRIVER ENTRY
//


NTSTATUS
DriverEntry(
    IN OUT PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING      RegistryPath
    )
/*++

Routine Description:
    This routine is called by the Operating System to initialize the driver.

    It fills in the dispatch entry points in the driver object.  Then
    SPEEDCDInitializeDisk is called to create the device object and complete
    the initialization.

Arguments:
    DriverObject - a pointer to the object that represents this device
    driver.

    RegistryPath - a pointer to our Services key in the registry.
	  ... Services\\SPEEDCD

Return Value:
    STATUS_SUCCESS if this disk is initialized; an error otherwise.

--*/

{
    NTSTATUS        ntStatus;
    WCHAR DriveChar;
    static  WCHAR   SubKeyString[] = L"\\Parameters";
    UNICODE_STRING  paramPath;

	SPEEDCDLogS("-----Loading Driver-----");
    //
    // The registry path parameter points to our key, we will append
    // the Parameters key and look for any additional configuration items
    // there.  We add room for a trailing NUL for those routines which
    // require it.

    paramPath.MaximumLength = RegistryPath->Length + sizeof(SubKeyString);
    paramPath.Buffer = ExAllocatePool(PagedPool, paramPath.MaximumLength);

    if (paramPath.Buffer != NULL)
    {
        RtlMoveMemory(
            paramPath.Buffer, RegistryPath->Buffer, RegistryPath->Length);

        RtlMoveMemory(
            &paramPath.Buffer[RegistryPath->Length / 2], SubKeyString,
            sizeof(SubKeyString));

        paramPath.Length = paramPath.MaximumLength;
    }
    else
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    //
    // Initialize the driver object with this driver's entry points.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE] = SPEEDCDCreateClose;
    DriverObject->MajorFunction[IRP_MJ_READ] = SPEEDCDReadWrite;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SPEEDCDDeviceControl;

	//
	// register the driver unload function
	//

#ifdef SPEEDCD_UNLOADABLE
    DriverObject->DriverUnload = SPEEDCDUnloadDriver;
#endif

	//
	// We create one device object for our driver. This the special device that
	// we can talk to from our win32 program to send ioctls to creat and destroy
	// mounted cd devices.
	//
	// \\Devices\\SPEEDCD ====>> \\DosDevices\\SPEEDCD 
	//

	{
		UNICODE_STRING      imagePathString;     
	    NTSTATUS        ntStatus1;

	    RtlInitUnicodeString( &imagePathString, L"\\??\\c:\\notarealpath.iso");
		ntStatus1 = SPEEDCDInitializeVolumes(DriverObject, &paramPath,NULL,&imagePathString,FALSE);


		if (NT_SUCCESS(ntStatus1))
		{
			ntStatus = STATUS_SUCCESS;
		}else
		{
			ntStatus = ntStatus1;
		}
	}

////////////
    //  DriveChar = L'A' -> 'Z'
    for (DriveChar = L'A'; DriveChar <= L'Z'; DriveChar++)
    // Init the volumes as stored in the registry.
    {
        //
        // We use this to query into the registry as to whether we
        // should mount a Z drive.
        //
    
        RTL_QUERY_REGISTRY_TABLE    paramTable[2];
        WCHAR                       ZStringBuf[500];
        UNICODE_STRING              ZString;
        WCHAR                       DName[3];

        DName[0] = DriveChar;
        DName[1] = L'\0';
        
        ZString.Buffer = ZStringBuf;
        ZString.MaximumLength = 499 * sizeof(WCHAR);
        ZString.Length = 0;

        RtlZeroMemory(&paramTable[0], sizeof(paramTable));
    
        paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[0].Name = DName;
        paramTable[0].EntryContext = &ZString;
        
        if (!NT_SUCCESS(RtlQueryRegistryValues(
            RTL_REGISTRY_ABSOLUTE,
            paramPath.Buffer, paramTable, NULL, NULL)))
        {
        	SPEEDCDLogS("Error quering Y string");

            // oops failed
        }else
        {
        	SPEEDCDLogS("Success quering Y string");
            SPEEDCDLogPU(&ZString);
            if (ZString.Length > 0)
            {
                // success maybe :)
                UNICODE_STRING Letter;
        	    NTSTATUS        ntStatus2;

            	SPEEDCDLogS("Y string length > 0");
                DName[0] = DriveChar;
                DName[1] = L':';
                DName[2] = L'\0';
                RtlInitUnicodeString( &Letter, DName);
        
		        ntStatus2 = SPEEDCDInitializeVolumes(DriverObject, 
                    &paramPath,&Letter,&ZString,FALSE);
            }
        }
    }

    //
    // We don't need that path anymore.
    //
/*
    if (paramPath.Buffer)
    {
        ExFreePool( paramPath.Buffer );
    }
*/  
    return ntStatus;
}

NTSTATUS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -