问题描述
大家好。
最近,我正在试图编写一个文件系统minifilter驱动程序来拦截一些I / O操作,例如"IRP_MJ_CREATE"。做一些跟踪记录。我写了一个Windows服务,它将在系统启动时启用并加载minifilter驱动程序。但是,在我安装了我的minifilter驱动程序之后
,我的Windows无法启动。它坚持做"启动修复"。我的平台是windows 7 build 7601,windows kit 6.9.9200.16384。
Recently, I'm triying to write a file system minifilter driver to intercept some I/O operations like "IRP_MJ_CREATE" to do some trace logging. I wrote a windows service which is to be enabled at system startup and load the minifilter driver. However, after I installed my minifilter driver, My windows cannot startup. It's stuck doing "startup repair". My platform is windows 7 build 7601, windows kits 6.9.9200.16384.
这是我的DriverEntry函数
Here is my DriverEntry function
NTSTATUS
DriverEntry (
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
PSECURITY_DESCRIPTOR sd;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uniString; //for communication port name
UNICODE_STRING uniEventName;
UNREFERENCED_PARAMETER( RegistryPath );
DbgPrint (" hpp DriverObject base addr : %X \n",(ULONG)DriverObject->DriverStart);
DbgPrint (" hpp DriverObject DriverSize : %u \n",DriverObject->DriverSize);
thisDriInfo.DriverStart=DriverObject->DriverStart;
thisDriInfo.DriverSize=DriverObject->DriverSize;
ExInitializeFastMutex( &LogMutex );
InitializeListHead( &OutputBufferList );
KeInitializeSpinLock( &OutputBufferLock );
MaxRecordsToAllocate = DEFAULT_MAX_RECORDS_TO_ALLOCATE;
RecordsAllocated = 0;
ExInitializeNPagedLookasideList( &FreeBufferList,
NULL,
NULL,
0,
RECORD_SIZE,
SPY_TAG,
0 );
//
// Register with FltMgr to tell it our callback routines
//
KdPrint(("hpp-----MzfFile-----DriverEntry---\n "));
status = FltRegisterFilter( DriverObject,
&FilterRegistration,
&gFilterHandle );
ASSERT( NT_SUCCESS( status ) );
if (NT_SUCCESS( status )) {
//
// Start filtering i/o
//
status = FltStartFiltering( gFilterHandle );
if (!NT_SUCCESS( status )) {
FltUnregisterFilter( gFilterHandle );
}
}
//Communication Port
status = FltBuildDefaultSecurityDescriptor( &sd, FLT_PORT_ALL_ACCESS );
if (!NT_SUCCESS( status )) {
goto final;
}
status = FltBuildDefaultSecurityDescriptor( &sd, FLT_PORT_ALL_ACCESS );
if (!NT_SUCCESS( status )) {
goto final;
}
RtlInitUnicodeString( &uniString, MINISPY_PORT_NAME );
InitializeObjectAttributes( &oa,
&uniString,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
sd );
status = FltCreateCommunicationPort( gFilterHandle,
&gServerPort,
&oa,
NULL,
NPMiniConnect,
NPMiniDisconnect,
NPMiniMessage,
1 );
FltFreeSecurityDescriptor( sd );
if (!NT_SUCCESS( status )) {
goto final;
}
RtlInitUnicodeString(&uniEventName, EVENT_NAME);
//pEvent = IoCreateNotificationEvent(&uniEventName, &gEventHandle);
//if (pEvent != NULL)
//{
//KeClearEvent(pEvent);
//}
//ExInitializeFastMutex( &LogMutex );
//CurrentLog = ExAllocatePool( NonPagedPool, sizeof(*CurrentLog) );
//if( !CurrentLog ) {
//return STATUS_INSUFFICIENT_RESOURCES;
//goto final;
//}
//CurrentLog->Len = 0;
//CurrentLog->Next = NULL;
NumLog = 1;
//DebugLogNum=0;
final :
if (!NT_SUCCESS( status ) ) {
if (NULL != gServerPort) {
FltCloseCommunicationPort( gServerPort );
}
if (NULL != gFilterHandle) {
FltUnregisterFilter( gFilterHandle );
}
//if(!CurrentLog){
//不需要处理, 因为进入这里面的话说明还没初始化成功就挂了
//}
ExDeleteNPagedLookasideList( &FreeBufferList );
}
KdPrint(("hpp-----MzfFile-----DriverEntry--end-\n "));
return status;
}
这是我的主要I / O事件处理函数:
And this is my major I/O event process function:
FLT_POSTOP_CALLBACK_STATUS
PtPostOperationPassThrough (
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_opt_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
)
/*++
Routine Description:
This routine is the post-operation completion routine for this
miniFilter.
This is non-pageable because it may be called at DPC level.
Arguments:
Data - Pointer to the filter callbackData that is passed to us.
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance, its associated volume and
file object.
CompletionContext - The completion context set in the pre-operation routine.
Flags - Denotes whether the completion is successful or is being drained.
Return Value:
The return value is the status of the operation.
FilemonHookRoutine
--*/
{
PFLT_FILE_NAME_INFORMATION FNameInfo;
NTSTATUS Status;
CHAR attributeString[ERRORLEN];
CHAR optionString[ERRORLEN];
CHAR fileName[MAXPATHLEN] = "";
CHAR volumeName[MAXPATHLEN] = "";
//CHAR fileAttr[500] = "";
UNICODE_STRING DosName;
CHAR pathName[MAXPATHLEN] = "";
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
UNREFERENCED_PARAMETER( Flags );
//这部分先预留
/***
if( Data->Iopb->MajorFunction == IRP_MJ_CREATE ) {
//
// Clear any existing fileobject/name association stored in the
// hash table
//
//FilemonFreeHashEntry( FileObject );
//createPath = TRUE;
} else if( currentIrpStack->MajorFunction == IRP_MJ_CLOSE ) {
//
// We treat close as a special case of create for name querying
// since calling into NTFS during a close can result in a deadlock.
//
//createPath = TRUE;
} else if( currentIrpStack->MajorFunction == IRP_MJ_CLEANUP &&
FileObject->Flags & FO_STREAM_FILE ) {
//
// Treat cleanup of stream file objects as special create case, because
// querying them causes NTFS to screwup on NT 4
//
} else {
//createPath = FALSE;
}
GETPATHNAME( createPath );
***/
//DbgPrint(("hpp---------PtPostOperationPassThrough-111-\n"));
//分析一下这个判断是否通用
if ( !NT_SUCCESS( Data->IoStatus.Status ) || ( STATUS_REPARSE == Data->IoStatus.Status ) )
{
//DbgPrint(("hpp---------PtPostOperationPassThrough-22-\n"));
//return FLT_POSTOP_FINISHED_PROCESSING;
}
Status = FltGetFileNameInformation( Data,
FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
&FNameInfo );
// If we could not get the name information then exit
if (!NT_SUCCESS( Status ))
{
//DbgPrint(("hpp---------PtPostOperationPassThrough-333-\n"));
return FLT_POSTOP_FINISHED_PROCESSING;
}
Status = FltParseFileNameInformation( FNameInfo );
// If we could not get the name information then exit
if (!NT_SUCCESS( Status ))
{
//DbgPrint(("hpp---------PtPostOperationPassThrough-333---11-\n"));
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (!NPUnicodeStringToChar(&FNameInfo->Name, fileName)){
DbgPrint(("hpp----- NPUnicodeStringToChar-- -\n"));
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (!NPUnicodeStringToChar(&FNameInfo->Volume, volumeName)){
DbgPrint(("hpp----- NPUnicodeStringToChar-- -\n"));
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (! FilterVolumeDeviceNameToDosName(&FNameInfo->Volume,&DosName)){
DbgPrint(("hpp----- NPUnicodeStringToChar-- -\n"));
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (!NPUnicodeStringToChar(&DosName, pathName)){
DbgPrint(("hpp----- NPUnicodeStringToChar-- -\n"));
return FLT_POSTOP_FINISHED_PROCESSING;
}
//getFullFileName(pathName,fileName);
strcat_s(pathName,MAXPATHLEN,fileName+strlen(volumeName));
switch( Data->Iopb->MajorFunction ) {
case IRP_MJ_CREATE:
/**
DbgPrint("hpp IRP_MJ_CREATE\t%s\tAttributes: %s Options:%s\n",
pathName,
CreateAttributesString( Data->Iopb->Parameters.Create.FileAttributes,
attributeString ),
CreateOptionsString( Data->Iopb->Parameters.Create.Options,
optionString ));
**/
LogRecord("hpp IRP_MJ_CREATE\tbegin\\%s\\end\tAttributes: %s Options:%s\n",
pathName,
CreateAttributesString( Data->Iopb->Parameters.Create.FileAttributes,
attributeString ),
CreateOptionsString( Data->Iopb->Parameters.Create.Options,
optionString ));
// If its an open-by-id we free the hash entry now so that on the next access to
// the file we'll pick up the file's real name.
// //这里是预留的代码
// if( currentIrpStack->Parameters.Create.Options & FILE_OPEN_BY_FILE_ID ) {
// FilemonFreeHashEntry( FileObject );
// }
break;
case IRP_MJ_READ :
LogRecord("hpp IRP_MJ_READ begin\\%s\\end\n",pathName );
break;
case IRP_MJ_WRITE:
LogRecord("hpp IRP_MJ_WRITE begin\\%s\\end \n",pathName );
//DbgPrint(("hpp IRP_MJ_WRITE\n"));
break;
case IRP_MJ_QUERY_INFORMATION :
LogRecord("hpp IRP_MJ_QUERY_INFORMATION begin\\%s\\end \n",pathName );
//DbgPrint(("hpp IRP_MJ_QUERY_INFORMATION\n"));
break;
case IRP_MJ_SET_INFORMATION :
if (Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileDispositionInformation){
//strcpy(fileAttr,"FileDispositionInformation");
LogRecord(" hpp IRP_MJ_SET_INFORMATION begin\\%s\\end FileDispositionInformation ",pathName );
}else if (Data->Iopb->Parameters.SetFileInformation.FileInformationClass ==FileRenameInformation){
//strcpy(fileAttr,"FileRenameInformation");
LogRecord(" hpp IRP_MJ_SET_INFORMATION begin\\%s\\end FileRenameInformation",pathName );
}else{
//strcpy(fileAttr,"Any");
LogRecord(" hpp IRP_MJ_SET_INFORMATION begin\\%s\\end Any",pathName );
}
break;
case IRP_MJ_QUERY_EA :
LogRecord("hpp IRP_MJ_QUERY_EA begin\\%s\\end \n",pathName );
//DbgPrint(("hpp IRP_MJ_QUERY_EA\n"));
break;
case IRP_MJ_SET_EA :
LogRecord("hpp IRP_MJ_SET_EA begin\\%s\\end \n",pathName );
break;
case IRP_MJ_QUERY_VOLUME_INFORMATION:
LogRecord("hpp IRP_MJ_QUERY_VOLUME_INFORMATION\tbegin\\%s\\end\t%s",
pathName,
VolumeInformation[Data->Iopb->Parameters.QueryVolumeInformation.FsInformationClass] );
break;
case IRP_MJ_SET_VOLUME_INFORMATION :
LogRecord("%hpp IRP_MJ_SET_VOLUME_INFORMATION begin\\%s\\end",
pathName);
// VolumeInformation[Data->Iopb->Parameters.QueryVolumeInformation.FsInformationClass] );
break;
case IRP_MJ_DIRECTORY_CONTROL :
switch( Data->Iopb->MinorFunction ) {
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
LogRecord("hpp IRP_MJ_DIRECTORY_CONTROL begin\\%s\\end Change Notify", pathName);
break;
default:
LogRecord("hpp IRP_MJ_DIRECTORY_CONTROL begin\\%s\\end", pathName);
break;
}
break;
case IRP_MJ_FILE_SYSTEM_CONTROL :
LogRecord("hpp IRP_MJ_FILE_SYSTEM_CONTROL begin\\%s\\end\n", fileName);
break;
case IRP_MJ_DEVICE_CONTROL:
LogRecord("hpp IRP_MJ_DEVICE_CONTROL begin\\%s\\end \n", fileName);
break;
case IRP_MJ_INTERNAL_DEVICE_CONTROL :
LogRecord("hpp IRP_MJ_INTERNAL_DEVICE_CONTROL begin\\%s\\end\n", fileName);
break;
case IRP_MJ_CLEANUP :
LogRecord("hpp IRP_MJ_CLEANUP begin\\%s\\end\n", fileName);
break;
case IRP_MJ_QUERY_QUOTA :
LogRecord("hpp IRP_MJ_QUERY_QUOTA begin\\%s\\end \n", fileName);
break;
case IRP_MJ_SET_QUOTA :
LogRecord("hpp IRP_MJ_SET_QUOTA begin\\%s\\end \n", fileName);
break;
case IRP_MJ_CLOSE :
LogRecord("hpp IRP_MJ_CLOSE begin\\%s\\end \n", fileName);
break;
default:
break;
}
//DbgPrint("hpp---------PtPostOperationPassThrough-444-\n");
return FLT_POSTOP_FINISHED_PROCESSING;
}
请帮帮我,谢谢
推荐答案
-Brian
-Brian
这篇关于安装我的minifilter驱动程序后,Windows无法启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!