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

📄 vaporcd.c

📁 一个虚拟光驱程序(驱动程序和exe)-VaporCDSource141
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
    VaporCD CD-ROM Volume Emulation for Windows NT/2000
    Copyright (C) 2000  Brad Johnson

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    http://vaporcd.sourceforge.net/

    Brad Johnson
    3305 2nd PL #222
    Lubbock, TX 79415
*/

/*++

Module Name:

    VaporCD.c

Abstract:

    Virtual CD ROM driver to mount CD Images

Author:

    Brad Johnson - August 7th 1999

Environment:

    Kernel mode only.

Notes:

Revision History:
	Current PreRelease

--*/


//
// 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 "vaporcd.h"

#if DBG
ULONG   VaporCDDebugLevel = 0;
#endif




//
// Debug Log Functions
//


VOID VaporCDLogWriteString(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\\vaporcd.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 VaporCDLogWriteULong(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++;

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

VOID VaporCDLogL(ULONG ulValue)
{
#ifdef DEBUG_LOG
	VaporCDLogWriteULong(ulValue);
	VaporCDLogWriteString("\x0d\x0a");
#endif
}

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

	VaporCDLogWriteString(pMessage);
	VaporCDLogWriteULong(ulValue);
	VaporCDLogWriteString("\x0d\x0a");
#endif
}

VOID VaporCDLogS(char * pMessage)
{
#ifdef DEBUG_LOG

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

VOID VaporCDLogPU(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++;

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

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

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

	VaporCDLogS("begin VaporCDReadOffset");

	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))
	{

		VaporCDLogS("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))
			VaporCDLogS("read success");
		else
			VaporCDLogS("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
    VaporCDInitializeDisk 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\\VaporCD

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

--*/

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

	VaporCDLogS("-----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] = VaporCDCreateClose;
    DriverObject->MajorFunction[IRP_MJ_READ] = VaporCDReadWrite;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VaporCDDeviceControl;

	//
	// register the driver unload function
	//

#ifdef VAPORCD_UNLOADABLE
    DriverObject->DriverUnload = VaporCDUnloadDriver;
#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\\VaporCD ====>> \\DosDevices\\VaporCD 
	//

	{
		UNICODE_STRING      imagePathString;     
	    NTSTATUS        ntStatus1;

	    RtlInitUnicodeString( &imagePathString, L"\\??\\c:\\notarealpath.iso");
		ntStatus1 = VaporCDInitializeVolumes(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,

⌨️ 快捷键说明

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