📄 vaporcd.c
字号:
/*
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(
¶mPath.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, ¶mPath,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(¶mTable[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 + -