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


#include "FsTPM.h" 
 
 
NTSTATUS FsTPMCreateCompleted(IN PDEVICE_OBJECT pHookDevice, IN PIRP pIrp, IN PVOID Context) 
{ 
   PIO_STACK_LOCATION  pCurrentIrpStack = IoGetCurrentIrpStackLocation(pIrp); 
   PFILE_OBJECT        pFileObject=pCurrentIrpStack->FileObject; 
   WCHAR *WideSource=(WCHAR *) Context; 
   PFILE_PROTECT_LIST_ITEM pItem; 
    
    
   if (!NT_SUCCESS(pIrp->IoStatus.Status)) 
      return STATUS_SUCCESS; 
 
   if (pIrp->PendingReturned) 
   { 
      IoMarkIrpPending(pIrp); 
   } 
 
   if (ProtectList_Is_In( &ProtectControlBlock.FileProtectList, WideSource, &pItem)) 
   { 
      //刷新缓冲 
      CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent; 
      NTSTATUS WaitStatus; 
      LARGE_INTEGER LargeZero = {0,0}; 
       
      KeInitializeEvent( &UninitializeCompleteEvent.Event, 
                     SynchronizationEvent, 
                     FALSE); 
       
      CcUninitializeCacheMap( pFileObject, 
         &LargeZero, 
         &UninitializeCompleteEvent ); 
       
      // 
      //  Now wait for the cache manager to finish purging the file. 
      //  This will garentee that Mm gets the purge before we 
      //  delete the Vcb. 
      // 
       
      WaitStatus = KeWaitForSingleObject( &UninitializeCompleteEvent.Event, 
                                 Executive, 
                                 KernelMode, 
                                 FALSE, 
                                 NULL); 
   } 
 
    
   return STATUS_SUCCESS;  
}    
 
 
 
BOOL Notify_User_Thread() 
{ 
	ExAcquireFastMutex(&Guard_Mutex); 
 
	KeSetEvent(pReq_Event,1,FALSE); 
 
	LARGE_INTEGER times; 
	times.u.LowPart = (10000000 * 2); 
	times.u.HighPart = 0; 
	 
	// NTSTATUS ret= KeWaitForSingleObject(pAck_Event, Executive, KernelMode , FALSE, NULL); 
	while (gAck==0); 
		 
	gAck=0; 
 
	//KeClearEvent(pAck_Event); 
	KeClearEvent(pReq_Event); 
 
	if ( gUser_Command==TRUE) 
	{ 
		ExReleaseFastMutex(&Guard_Mutex); 
		return TRUE; 
	} 
	else 
	{ 
		ExReleaseFastMutex(&Guard_Mutex);		 
		return FALSE; 
	} 
 
//	ExReleaseFastMutex(&Guard_Mutex); 
	return FALSE; 
} 
 
 
 
 
//++ 
// Function:	FsTPMCreateRoutine 
// 
// Description: 
//		处理Create操作 
// 
// Arguments: 
//		HookDevice - pointer to a device object 
//	    pIrp        - pointer to an I/O Request Packet 
// 
// 
// Return value: 
//		STATUS_SUCCESS if successful, 
//		STATUS_UNSUCCESSFUL otherwise 
//-- 
NTSTATUS  
FsTPMCreateRoutine(  
				   PDEVICE_OBJECT pHookDevice,  
				   IN PIRP pIrp  
				   ) 
 
{ 
	//  
	// 获得当前堆栈,以及下一个处理IRP的堆栈 
	// 
	PIO_STACK_LOCATION  pCurrentIrpStack = IoGetCurrentIrpStackLocation(pIrp); 
	PIO_STACK_LOCATION  pNextIrpStack    = IoGetNextIrpStackLocation(pIrp); 
	// 
	// 指向我定义的扩展结构,该结构中包括了我所需要的关于下层文件系统的信息 
	// 
	PHOOK_EXTENSION     pHookExt=(PHOOK_EXTENSION)pHookDevice->DeviceExtension; 
 
	PFILE_OBJECT        pFileObject=pCurrentIrpStack->FileObject; 
 
	PDEVICE_OBJECT		pNextLowerDevice=pHookExt->Vcb.NextLowerDevice; 
 
	WCHAR Temp[256] = L""; 
 
	WCHAR WideSource[256]={0}; 
 
	NTSTATUS ntStatus; 
 
	BYTE TempHash[HASH_LENGTH]; 
 
	ULONG disposition,Options=pCurrentIrpStack->Parameters.Create.Options; 
	disposition = (Options >> 24) & 0xFF; 
	 
 
	PFILE_PROTECT_LIST_ITEM pItem; 
 
	ASSERT(pCurrentIrpStack->MajorFunction==IRP_MJ_CREATE); 
 
	if (pHookExt->Type==GUIINTERFACE) 
	{ 
		pIrp->IoStatus.Information = 0; 
		pIrp->IoStatus.Status = STATUS_SUCCESS; 
 
		IoCompleteRequest( pIrp, IO_NO_INCREMENT ); 
		return STATUS_SUCCESS; 
	} 
 
 
	GetFileFullNameByObjectW(pFileObject,pHookExt,(WCHAR*)WideSource,256); 
	UpperWordW(WideSource); 
 
	FsTPM_DbgPrint(("IRP_Create: %S Enter!\n",WideSource)); 
 
	if (ProtectList_Is_In( &ProtectControlBlock.FileProtectList, WideSource, &pItem)) 
	{		 
		FsTPM_DbgPrint(("IRP_Create: Found %S in the protected list!\n",WideSource)); 
 
		// 我们不处理一些特殊文件(如注册表数据文件 ),并且也不处理那些不要检测保护的文件 
		if (IsSomeSpecialFile(WideSource, pFileObject, pCurrentIrpStack) || !(IS_CHECK_PROTECT(pItem->ProtectedFlag)) ) 
			goto L_Pass; 
 
 
 
		if ( ProtectControlBlock.EnableStaticProtect &&  
			 IS_STATIC_PROTECT(pItem->ProtectedFlag) && 
			 (disposition == FILE_SUPERSEDE || disposition == FILE_OVERWRITE || disposition == FILE_OVERWRITE_IF ) 
			) 
		{ 
			pIrp->IoStatus.Information = 0; 
			pIrp->IoStatus.Status = STATUS_ACCESS_DENIED; 
			 
			IoCompleteRequest( pIrp, IO_NO_INCREMENT ); 
			 
			return STATUS_ACCESS_DENIED; 
		} 
 
		// 下面,我们将 
		// 1。计算文件的Hash值 
		// 2。如果计算Hash正常,我们就把请求放过去 
		// 3。Hash不正常,则通知给用户线程,请求用户裁决 
 
		ntStatus = CalHash( WideSource, TempHash, HASH_LENGTH); 
		if ( NT_SUCCESS(ntStatus) && EqualHash( TempHash , pItem->Hash, HASH_LENGTH) ) 
			goto L_Pass; 
 
		if  (!Notify_User_Thread()) 
		{ 
			// 如果Notify_User_Thread 返回FALSE,则有两种情况, 
			// 1。用户线程无响应 
			// 2。用户要求取消操作 
			// 无论是那种情况,我们都将拒绝请求 
			pIrp->IoStatus.Information = 0; 
			pIrp->IoStatus.Status = STATUS_ACCESS_DENIED; 
 
			IoCompleteRequest( pIrp, IO_NO_INCREMENT ); 
			return STATUS_ACCESS_DENIED; 
		} 
	} 
 
L_Pass: 
 
	FsTPM_DbgPrint(("IRP_CREATE: %S is not listed in protected list , now pass it to the next device\n",WideSource)); 
 
	IoCopyCurrentIrpStackLocationToNext(pIrp); 
 
    IoSetCompletionRoutine(pIrp, FsTPMCreateCompleted, WideSource,TRUE,TRUE,TRUE); 
 
    ntStatus=IoCallDriver( pNextLowerDevice, pIrp ); 
 
 
	return ntStatus; 
}