www.pudn.com > FsTPM0.rar > FsTPM.cpp


/*++ 
Copyright (c) 2004 By LiGen , All right reserved 
Module Name: 
	fstpm.cpp 
 
Abstract: 
	本驱程序实现文件改写保护,文件完整性检测,文件加密 
	 
Environment: 
	Windows XP, Compiler Ver > 13.00 
 
Notes: 
   	 
 
Revision History: 
	created: 16:7:2004  
 
Author: 
	李根	13574849558@hnmcc.com 
 
--*/ 
 
#include "FsTPM.h" 
 
WCHAR gRequestEventNameStr[] = L"\\BaseNamedObjects\\tpmreq"; 
WCHAR gAckEventNameStr[]	 = L"\\BaseNamedObjects\\tpmack"; 
 
UNICODE_STRING gRequestEventName = {0}; 
UNICODE_STRING gAckEventName = {0}; 
 
BOOL gUser_Command = FALSE; 
ULONG  gAck=0; 
 
// Define a event whose name is the same as the event in our User Thread,  
// so we can notify user by this event object 
HANDLE HReq_Event = NULL; 
HANDLE HAck_Event = NULL; 
 
PKEVENT pReq_Event = NULL; 
PKEVENT pAck_Event; 
FAST_MUTEX Guard_Mutex = {0}; 
 
 
WCHAR gSymbol[] = L"\\Device\\FsTPM"; 
WCHAR gSymbolDos[] = L"\\DosDevices\\FsTPM"; 
 
ULONG CurrentDriveSet = 0; 
 
// 
// Table of our hook devices for each drive letter. This makes it 
// easy to look up the device object that was created to hook a  
// particular drive. 
// 
PDEVICE_OBJECT      DriveHookDevices[26] = {0}; 
 
//  
//  保存系统分配给我的驱动对象的指针 
// 
PDRIVER_OBJECT FsTPMDriverObject = NULL; 
 
// Save pointer to GUI 
PDEVICE_OBJECT pGUIDevice = NULL; 
 
// 
// Current bitmask of hooked devices 
// 
ULONG         CurrentDeviceSet = 0; 
 
ULONG ProcessNameOffset = 0;  
 
FSTPM_CONTROL_BLOCK ProtectControlBlock = {0}; 
 
// define a spin lock 
//  
KSPIN_LOCK IoDatabaseLock = {0}; 
PKSPIN_LOCK IopDatabaseLock = &IoDatabaseLock; 
 
 
 
 
NTSTATUS 
DriverEntry( 
    IN PDRIVER_OBJECT  pDriverObject, 
    IN PUNICODE_STRING pRegistryPath 
    ) 
/*++ 
Follow Routine Description: 
 
    Installable driver initialization entry point. 
    This entry point is called directly by the I/O system. 
 
Arguments: 
 
    pDriverObject - pointer to the driver object 
 
    pRegistryPath - pointer to a unicode string representing the path 
                   to driver-specific key in the registry 
 
Return Value: 
 
    STATUS_SUCCESS if successful, 
    STATUS_UNSUCCESSFUL otherwise 
 
--*/ 
{ 
	NTSTATUS	ntStatus; 
	int			i; 
	 
	FsTPM_DbgPrint(("FsTPM.SYS: entering DriverEntry\n"));  
	FsTPM_DbgPrint(("Enter Entry : RegPath=%S\n",pRegistryPath->Buffer)); 
 
	// 读入配置信息 
//	ReadParamFromReg(pRegistryPath,pDriverObject); 
 
	ProcessNameOffset=FsTPMGetProcessNameOffset(); 
 
	FsTPMDriverObject = pDriverObject; 
 
	CreateList( &ProtectControlBlock.FileProtectList , MAX_LIST_ITEM_NUM ); 
		 
	RtlInitUnicodeString(&gRequestEventName,gRequestEventNameStr); 
	RtlInitUnicodeString(&gAckEventName,gAckEventNameStr); 
 
	// Initial event 
	pReq_Event = IoCreateSynchronizationEvent(&gRequestEventName,&HReq_Event); 
	pAck_Event = IoCreateSynchronizationEvent(&gAckEventName,&HAck_Event); 
	ExInitializeFastMutex(&Guard_Mutex); 
	 
 
	KeClearEvent (pReq_Event); 
	KeClearEvent (pAck_Event); 
	 
	// 
	// Create dispatch points for all routines that must be handled.  
    // All entry points are registered since we might filter a 
	// file system that processes all of them. 
    // 
    for( i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++ ) { 
	    pDriverObject->MajorFunction[i] = FsTPMDispatch; 
    } 
 
	pDriverObject->MajorFunction[IRP_MJ_CREATE]=FsTPMCreateRoutine; 
	pDriverObject->MajorFunction[IRP_MJ_WRITE]=FsTPMWriteRoutine; 
	pDriverObject->MajorFunction[IRP_MJ_READ]=FsTPMReadRoutine; 
	pDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]=FsTPMQueryInformationRoutine; 
	pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]=FsTPMSetInformationRoutine; 
 
	// 
    // 置 Fast I/O dispatch 表 
    // 
    pDriverObject->FastIoDispatch = &FastIOHook; 
 
	pDriverObject->DriverUnload = FsTPMUnload; 
 
	ntStatus=CreateDevice(pDriverObject);          //创建一个与USER下的GUI程序通信的设备 
 
	if (!NT_SUCCESS(ntStatus)) 
	{ 
		FsTPM_DbgPrint(("Creating Device Failed !\n")); 
		return ntStatus; 
	} 
 
	// 挂载所有文件系统设备 
	CurrentDriveSet=0; 
	HookDeviceSet(0x3FFFFFC,pDriverObject); 
 
	return STATUS_SUCCESS; 
} 
 
 
NTSTATUS CreateDevice ( 
		IN PDRIVER_OBJECT	pDriverObject 
		)  
//++ 
// Function:	CreateDevice 
// 
// Description: 
//		创建一个我自己的设备对象,这样我就有了一个与WIN32沟通的桥梁 
// 
// Arguments: 
//		pDriverObject - Passed from I/O Manager 
// 
// Return value: 
//		STATUS_SUCCESS if successful, 
//		STATUS_UNSUCCESSFUL otherwise 
//-- 
{ 
	NTSTATUS status; 
	PDEVICE_OBJECT         pGUIObject        = NULL; 
 
	UNICODE_STRING		   GUIObjectNameString; 
	UNICODE_STRING		   GUIObjectLinkString; 
    PHOOK_EXTENSION        pGUIExt;	 
	 
	RtlInitUnicodeString( &GUIObjectNameString , gSymbol); 
	RtlInitUnicodeString( &GUIObjectLinkString , gSymbolDos); 
 
	// Now create the device 
	status = IoCreateDevice( pDriverObject, 
							sizeof(HOOK_EXTENSION), 
							&GUIObjectNameString, 
							FILE_DEVICE_FSTPM, 
							0, TRUE, 
							&pGUIObject ); 
	if (!NT_SUCCESS(status)) 
	{ 
		FsTPM_DbgPrint(("FsTPM.SYS: IoCreateDevice failed\n"));	 
		return status; 
	} 
	 
	pGUIDevice=pGUIObject; 
 
	 
	// Initialize the Device Extension 
	// Get the Device Extension Pointer 
	pGUIExt=(PHOOK_EXTENSION) pGUIObject->DeviceExtension; 
	// 
    // Mark this as our GUI device 
    // 
    pGUIExt->Type = GUIINTERFACE; 
	pGUIExt->thisDriver=FsTPMDriverObject; 
 
	// Now create the link name 
	status =  
		IoCreateSymbolicLink( &GUIObjectLinkString, 
							  &GUIObjectNameString); 
	if (!NT_SUCCESS(status)) { 
		// if it fails now, must delete Device object 
		FsTPM_DbgPrint(("FsTPM.SYS: IoCreateSymbolicLink failed\n")); 
		IoDeleteDevice( pGUIObject ); 
		return status; 
	} 
 
	 
	// Made it 
	return STATUS_SUCCESS; 
} 
 
 
VOID FsTPMUnload ( 
		IN PDRIVER_OBJECT	pDriverObject	 
		)  
//++ 
// Function:	FsTPMUnload 
// 
// Description: 
//		一般的,在文件系统编程中,我们并不提供UnLoad函数, 
//      但为了测试方便,故提供之。 
// 
// Arguments: 
//		pDriverObject - Passed from I/O Manager 
// 
// Return value: 
//		none 
//-- 
{	 
	UNICODE_STRING wstrGuiLinkName; 
 
	RtlInitUnicodeString( &wstrGuiLinkName, gSymbolDos); 
 
	FsTPM_DbgPrint(("FsTPM.SYS: Unloading...\n")); 
 
    // 
    // Delete the symbolic link for our GUI device 
    // 
    IoDeleteSymbolicLink( &wstrGuiLinkName ); 
	FsTPM_DbgPrint(("FsTPM.SYS: Deleteing GUI Link ... OK\n")); 
	 
	// 
	// Delete the Device Drivers that we've attached to... 
	// 
	UnloadDetach(); 
	FsTPM_DbgPrint(("FsTPM.SYS: Devices are detached ... OK \n")); 
 
	IoDeleteDevice( pGUIDevice ); 
	FsTPM_DbgPrint(("FsTPM.SYS: I/O Control Device deleted ... OK \n")); 
 
	ZwClose(HReq_Event); 
	ZwClose(HAck_Event); 
 
	FsTPM_DbgPrint(("FsTPM.SYS: Close event ... OK \n")); 
 
	FsTPM_DbgPrint(("FsTPM.SYS:  Unload All, Completed ! \n")); 
} 
//#endif 
 
 
NTSTATUS 
FsTPMDispatch( 
    IN PDEVICE_OBJECT pDeviceObject, 
    IN PIRP           pIrp 
    ) 
/*++ 
 
Followed Routine Description: 
 
    Process the IRPs sent to this device. 
 
Arguments: 
 
    pDeviceObject - pointer to a device object 
 
    pIrp          - pointer to an I/O Request Packet 
 
Return Value: 
 
--*/ 
{ 
	 
	//  
	// 获得当前堆栈,以及下一个处理IRP的堆栈 
	// 
    PIO_STACK_LOCATION  pCurrentIrpStack = IoGetCurrentIrpStackLocation(pIrp); 
    PIO_STACK_LOCATION  pNextIrpStack    = IoGetNextIrpStackLocation(pIrp); 
 
    // 
    // 指向我定义的扩展结构,该结构中包括了我所需要的关于下层文件系统的信息 
    // 
	PHOOK_EXTENSION     pHookExt=(PHOOK_EXTENSION)pDeviceObject->DeviceExtension; 
	 
	PDEVICE_OBJECT		pNextLowerDevice=pHookExt->Vcb.NextLowerDevice; 
 
	PFILE_OBJECT        pFileObject=pCurrentIrpStack->FileObject; 
 
	if (pHookExt->Type==GUIINTERFACE) 
	{ 
		pIrp->IoStatus.Information = 0; 
		pIrp->IoStatus.Status = STATUS_SUCCESS; 
 
		IoCompleteRequest( pIrp, IO_NO_INCREMENT ); 
		return STATUS_SUCCESS; 
	} 
	 
	// 
	// 其他情况我们不作处理直接交给下方的设备处理 
	// 
	IoSkipCurrentIrpStackLocation(pIrp); 
 
	NTSTATUS ntStatus=IoCallDriver( pNextLowerDevice, pIrp ); 
 
	return ntStatus; 
} 
 
 
VOID 
ReadParamFromReg        ( 
						 IN     PUNICODE_STRING  RegistryPath, 
						 IN     PDRIVER_OBJECT   DriverObject 
						 ) 
						 /*++ 
 
						 Routine Description: 
 
						 This routine tries to read the FsTPM-specific parameters from 
						 the registry.  These values will be found in the registry location 
						 indicated by the RegistryPath passed in. 
 
						 Arguments: 
 
						 RegistryPath - the path key which contains the values that are 
						 the FsTPM parameters 
 
						 Return Value: 
 
						 None. 
 
						 --*/ 
{ 
 
	return; 
}