Пример #1
0
NTSTATUS
UcaGetFileNameInformation(_In_  PFLT_CALLBACK_DATA Data,
                          _Out_ PFLT_FILE_NAME_INFORMATION *FileNameInformation)
{
    NTSTATUS Status;

    /* Get the file name info */
    Status = FltGetFileNameInformation(Data,
                                       FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
                                       FileNameInformation);
    if (!NT_SUCCESS(Status))
    {
        /* If we failed to get the normalized, the opened should succeed */
        Status = FltGetFileNameInformation(Data,
                                           FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_DEFAULT,
                                           FileNameInformation);
    }

    /* Exit if we failed to get a filename */
    if (!NT_SUCCESS(Status)) return Status;

    /* Fill in the rest of the structure */
    Status = FltParseFileNameInformation(*FileNameInformation);
    if (!NT_SUCCESS(Status))
    {
        FltReleaseFileNameInformation(*FileNameInformation);
    }

    return Status;
}
Пример #2
0
NTSTATUS GetDirectoryName(PFLT_CALLBACK_DATA Data, PUNICODE_STRING directoryName)
{
    PFLT_FILE_NAME_INFORMATION nameInfo;

    NTSTATUS status = FltGetFileNameInformation(Data, (FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_DEFAULT), &nameInfo);

    if (NT_SUCCESS(status))
    {
        status = FltParseFileNameInformation(nameInfo);

        if (NT_SUCCESS(status))
        {
            directoryName->Length = 0;
            directoryName->Buffer = (WCHAR*)ExAllocatePoolWithTag(PagedPool, nameInfo->Name.Length * sizeof(WCHAR), UNICODE_STRING_TAG);
            directoryName->MaximumLength = nameInfo->Name.Length;

            status = RtlUnicodeStringCopy(directoryName, &nameInfo->Name);
        }
    }

    if (nameInfo != NULL)
    {
        FltReleaseFileNameInformation(nameInfo);
    }

    return status;
}
Пример #3
0
//---------------------------------------------------------------
FLT_PREOP_CALLBACK_STATUS FltPreCreate(IN OUT PFLT_CALLBACK_DATA Data,
									   IN PCFLT_RELATED_OBJECTS FltObjects,
									   OUT PVOID *CompletionContext)
{
	char tProcessName[512] = {0};
	PEPROCESS tCurProc	= PsGetCurrentProcess();
	char* tNamePtr		= (char*)tCurProc + ProcessNameOffset;
	memcpy(tProcessName, tNamePtr, 15);
	tProcessName[15] = 0;
	KdPrint(("process name:%s\n",tProcessName));
	
	NTSTATUS tRetStatus;
	char FileName[512] = {0};
	PFLT_FILE_NAME_INFORMATION tNameInfo;
	PAGED_CODE();
	tRetStatus = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &tNameInfo);
	if(NT_SUCCESS(tRetStatus))
	{
		FltParseFileNameInformation(tNameInfo);
		KdPrint(("<Pre> file name: %wZ\n", &(tNameInfo->Name)));
		FltReleaseFileNameInformation(tNameInfo);
	}
	//	return FLT_PREOP_COMPLETE;
	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
Пример #4
0
static FLT_PREOP_CALLBACK_STATUS on_pre_op (PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS fltobj, PVOID *context)
{
	struct event *event;

	if (ESCAPE_CONDITION)
		return FLT_PREOP_SUCCESS_NO_CALLBACK;

	event = event_buffer_start_add();
	if (event == NULL)
		return FLT_PREOP_SUCCESS_NO_CALLBACK;

	/* We retrieve name information in "pre" for every operation except IRP_MJ_CREATE.
	 * For IRP_MJ_CREATE, we do it in post. */
	if (data->Iopb->MajorFunction != IRP_MJ_CREATE) {
		FLT_FILE_NAME_INFORMATION *name_info = NULL;
		if (FltGetFileNameInformation(data,
					FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
					&name_info) != STATUS_SUCCESS) {
			event_buffer_cancel_add(event);
			return FLT_PREOP_SUCCESS_NO_CALLBACK;
		}
		event->path_length = MAX_PATH_SIZE - 1 < name_info->Name.Length / 2 ? MAX_PATH_SIZE - 1 : name_info->Name.Length / 2;
		RtlCopyMemory(event->path, name_info->Name.Buffer, event->path_length * 2);
		event->path[event->path_length] = 0;
		FltReleaseFileNameInformation(name_info);
	}

	event->time_pre = get_timestamp();
	*context = event;
	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
Пример #5
0
FLT_PREOP_CALLBACK_STATUS PRE_MJ_CREATE(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext)
{
	NTSTATUS status;
	PFLT_FILE_NAME_INFORMATION nameInfo = NULL;


	status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo);


	if (!NT_SUCCESS(status))
	{
		status = FltGetFileNameInformationUnsafe(FltObjects->FileObject, FltObjects->Instance, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo);
	}

	if (nameInfo)
	{
		// block access
		if (wcsstr(nameInfo->Name.Buffer, L"your_file.exe") != NULL)
		{
			Data->IoStatus.Status = STATUS_NO_SUCH_FILE;
			Data->IoStatus.Information = 0;
			return FLT_PREOP_COMPLETE;
		}

		FltReleaseFileNameInformation(nameInfo);
	}

	return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
Пример #6
0
FLT_PREOP_CALLBACK_STATUS FLTAPI DenyCreateFileRoutine(
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
	)
{
	NTSTATUS nsStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
	PFLT_FILE_NAME_INFORMATION pFileName = NULL;

	UNREFERENCED_PARAMETER(FltObjects);
	UNREFERENCED_PARAMETER(CompletionContext);

	if (	Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION 
		&&	Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileRenameInformation)
	{
		if (((FILE_RENAME_INFORMATION*)Data->Iopb->Parameters.SetFileInformation.InfoBuffer)->FileName != NULL)
		{
			UNICODE_STRING	uszFileNtPath		= {0x00};
			PUNICODE_STRING	puszStoreFilePath	= NULL;
			uszFileNtPath.Buffer = ((FILE_RENAME_INFORMATION*)Data->Iopb->Parameters.SetFileInformation.InfoBuffer)->FileName;
			uszFileNtPath.Length = (USHORT)((FILE_RENAME_INFORMATION*)Data->Iopb->Parameters.SetFileInformation.InfoBuffer)->FileNameLength;
			uszFileNtPath.MaximumLength = uszFileNtPath.Length;
			nsStatus = BDKitVolumeNameToDosName (&uszFileNtPath, &puszStoreFilePath);
			if (	NT_SUCCESS(nsStatus)
				&&	BDKitFindListNodeWithHandler (g_DenyFileHashList, puszStoreFilePath, findDenyFilePath) != NULL 
				&& !NT_SUCCESS(BDKitIsAuthorizedProcess(PsGetCurrentProcess())))
			{
				Data->IoStatus.Status = STATUS_ACCESS_DENIED;
				Data->IoStatus.Information = 0;
				nsStatus = FLT_PREOP_COMPLETE;
			}
			BDKitFreePool(puszStoreFilePath);
		}

	} else if ( Data->Iopb->MajorFunction == IRP_MJ_CREATE )
	{
		do 
		{
			nsStatus = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED, &pFileName);
			BDKit_If_Not_Break(NT_SUCCESS(nsStatus));

			if ( BDKitFindListNodeWithHandler(g_DenyFileHashList, &pFileName->Name, findDenyFilePath) != NULL )
			{
				Data->IoStatus.Status = STATUS_ACCESS_DENIED;
				Data->IoStatus.Information = 0;
				nsStatus = FLT_PREOP_COMPLETE;
			}
		} while (FALSE);

		BDKit_If_DoAction(pFileName != NULL, FltReleaseFileNameInformation (pFileName));

	} else if ( Data->Iopb->MajorFunction == IRP_MJ_UNREGISTER)
	{
		BDKitCloseListHandleWithHandler (g_DenyFileHashList, freeDenyListNode);
		g_DenyFileHashList = NULL;
	}

	return nsStatus;
}
Пример #7
0
FLT_PREOP_CALLBACK_STATUS precreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext)
{
	UNREFERENCED_PARAMETER(Data);
	UNREFERENCED_PARAMETER(FltObjects);
	UNREFERENCED_PARAMETER(CompletionContext);
	PFLT_FILE_NAME_INFORMATION info;
	PAGED_CODE();
	__try{
		FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &info);
		FltParseFileNameInformation(info);
		DbgPrint("检测到目标打开文件:%wZ\n", info->Name);
		FltReleaseFileNameInformation(info);
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		DbgPrint("error cant execute the try\n");
	}
	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
Пример #8
0
//---------------------------------------------------------------
FLT_POSTOP_CALLBACK_STATUS FltPostCreate(
										__inout PFLT_CALLBACK_DATA Data,
										__in PCFLT_RELATED_OBJECTS FltObjects,
										__in_opt PVOID CompletionContext,
										__in FLT_POST_OPERATION_FLAGS Flags )
{
	NTSTATUS tRetStatus;
	char FileName[512] = {0};
	PFLT_FILE_NAME_INFORMATION tNameInfo;
	PAGED_CODE();
	tRetStatus = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &tNameInfo);
	if(NT_SUCCESS(tRetStatus))
	{
		FltParseFileNameInformation(tNameInfo);
		KdPrint(("<post> file name: %wZ\n", &(tNameInfo->Name)));
		FltReleaseFileNameInformation(tNameInfo);
	}
	return FLT_POSTOP_FINISHED_PROCESSING;
}
Пример #9
0
FLT_PREOP_CALLBACK_STATUS
NPPreCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
{
    NTSTATUS status;
    PFLT_FILE_NAME_INFORMATION nameInfo;
    ANSI_STRING ansiStr;

    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );
    PAGED_CODE();

    __try
    {
        status = FltGetFileNameInformation( Data,
                                            FLT_FILE_NAME_NORMALIZED |
                                            FLT_FILE_NAME_QUERY_DEFAULT,
                                            &nameInfo );
        if ( !NT_SUCCESS( status ) )
            leave;

        status = FltParseFileNameInformation( nameInfo );
        if ( !NT_SUCCESS( status ) )
            leave;
        RtlUnicodeStringToAnsiString(&ansiStr, &nameInfo->Name, TRUE);
        PT_DBG_PRINT( PTDBG_TRACE_OPERATION_STATUS,
                     ("minifilter0!NPPretCreate: create [%Z]\n", &ansiStr) );
        RtlFreeAnsiString( &ansiStr );
		FltReleaseFileNameInformation( nameInfo );
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        DbgPrint("NPPreCreate EXCEPTION_EXECUTE_HANDLER\n");
    }
    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
static
FLT_PREOP_CALLBACK_STATUS
    FileSetInfoFilterPreCallback
    (
        PFLT_CALLBACK_DATA Data,
        PCFLT_RELATED_OBJECTS FltObjects,
        PVOID *CompletionContext
    )
{
    FLT_PREOP_CALLBACK_STATUS status = FLT_PREOP_SUCCESS_NO_CALLBACK;
    PFLT_FILE_NAME_INFORMATION fileInfoSrc = NULL;

    UNREFERENCED_PARAMETER( Data );
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );

    if( FileRenameInformation == Data->Iopb->Parameters.SetFileInformation.FileInformationClass )
    {
        // For a move, we keep the original path before the move
        if( NT_SUCCESS( FltGetFileNameInformation( Data,
                                                   FLT_FILE_NAME_NORMALIZED |
                                                   FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
                                                   &fileInfoSrc ) ) )
        {
            status = FLT_PREOP_SYNCHRONIZE;
            *CompletionContext = fileInfoSrc;
        }
    }
    else if( FileDispositionInformation == Data->Iopb->Parameters.SetFileInformation.FileInformationClass ||
             FileDispositionInformationEx == Data->Iopb->Parameters.SetFileInformation.FileInformationClass )
    {
        status = FLT_PREOP_SYNCHRONIZE;
    }

    return status;
}
Пример #11
0
FLT_PREOP_CALLBACK_STATUS
FLTAPI
FilterPreCreate(
    FLT_CALLBACK_DATA* Data,
    PCFLT_RELATED_OBJECTS FltObjects,
    PVOID* CompletionContext
    )
{
    NTSTATUS status;
    FLT_FILE_NAME_INFORMATION *nameInformation;
    UNICODE_STRING *fullPath;

    status = FltGetFileNameInformation(
                Data,
                FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
                &nameInformation
                );

    if (status == STATUS_SUCCESS)
    {
        status = FltParseFileNameInformation(nameInformation);

        if (status == STATUS_SUCCESS)
        {
            FLT_FILE_LIST_ENTRY *file = FltFileList;

            fullPath = &nameInformation->Name;

            if ((Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess & FILE_EXECUTE) //Execute
                && (nameInformation->FinalComponent.Length == 16 //d3d8.dll/d3d9.dll
                || nameInformation->FinalComponent.Length == 18)) //d3d10.dll/d3d11.dll
            {
                if (wcsncmp(L"d3d8.dll", nameInformation->FinalComponent.Buffer, 8) == 0
                    || wcsncmp(L"d3d9.dll", nameInformation->FinalComponent.Buffer, 8) == 0
                    || wcsncmp(L"d3d10.dll", nameInformation->FinalComponent.Buffer, 9) == 0
                    || wcsncmp(L"d3d11.dll", nameInformation->FinalComponent.Buffer, 9) == 0)
                {
                    PROCESSID processId;
                    DEVICE_EXTENSION *deviceExtension;

                    processId = FltGetRequestorProcessId(Data);

                    deviceExtension = g_DeviceObject->DeviceExtension;
                    deviceExtension->imageEvent.processID = processId;

                    KeSetEvent(PushGpuAccelerationEvent, 0, FALSE);
                    KeClearEvent(PushGpuAccelerationEvent);

                    DbgPrint("[PUSH] %u loaded %wZ\n", processId, fullPath);
                }
            }

            while (file != 0)
            {
                if (fullPath->Length == file->NameLength
                    && wcsncmp(file->Name, fullPath->Buffer, file->NameLength / sizeof(WCHAR)) == 0)
                {
                    UNICODE_STRING newName;
                    UNICODE_STRING redirect;
                    UNICODE_STRING *currentName;
                    UINT16 newNameSize;
                    WCHAR *buffer;

                    //DbgPrint("[PUSH] %ws matches %wZ", file->Name, fullPath);

                    RtlInitUnicodeString(&newName, PUSH_RAMDISK_DEVICE_NAME L"\\");

                    // Calculate the size of the name
                    newNameSize = newName.Length + nameInformation->FinalComponent.Length;

                    redirect.Length = newName.Length;
                    redirect.MaximumLength = newNameSize;
                    redirect.Buffer = ExAllocatePool(NonPagedPool, newNameSize);

                    // Copy ramdisk device name into buffer
                    RtlCopyMemory(redirect.Buffer, newName.Buffer, newName.Length);

                    // Append original file name
                    //RtlAppendUnicodeStringToString(&redirect, &nameInformation->FinalComponent);
                    buffer = &redirect.Buffer[redirect.Length / sizeof(WCHAR)];

                    RtlMoveMemory(
                        buffer,
                        nameInformation->FinalComponent.Buffer,
                        nameInformation->FinalComponent.Length
                        );

                    redirect.Length += nameInformation->FinalComponent.Length;
                    currentName = &Data->Iopb->TargetFileObject->FileName;

                    // Throw away the current file name
                    ExFreePool(currentName->Buffer);

                    currentName->Length = 0;
                    currentName->MaximumLength = redirect.MaximumLength;
                    currentName->Buffer = ExAllocatePool(NonPagedPool, redirect.MaximumLength);

                    // Copy new path to buffer
                    RtlCopyUnicodeString(currentName, &redirect);

                    // Be nice and give back what was given to us
                    ExFreePool(redirect.Buffer);

                    Data->IoStatus.Information = IO_REPARSE;
                    Data->IoStatus.Status = STATUS_REPARSE;
                    Data->Iopb->TargetFileObject->RelatedFileObject = NULL;

                    FltSetCallbackDataDirty(Data);

                    return FLT_PREOP_COMPLETE;
                }

                file = file->NextEntry;
            }
        }
    }

    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
Пример #12
0
FLT_PREOP_CALLBACK_STATUS FilemonPreCreate (__inout PFLT_CALLBACK_DATA Data
											, __in PCFLT_RELATED_OBJECTS FltObjects
											, __deref_out_opt PVOID *CompletionContext)
{
	PFLT_FILE_NAME_INFORMATION		nameInfo;
	NTSTATUS						status;
	LONG							nType;


	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( CompletionContext );

	PAGED_CODE();

	if (FALSE == IsGuardStart()) 
	{
		KdPrint(( "!!! scanner.sys -- allowing create for trusted process \n" ));
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}

	if (!NT_SUCCESS( Data->IoStatus.Status ) ||
		(STATUS_REPARSE == Data->IoStatus.Status)) 
	{
		KdPrint(("[ScannerPreCreate] Data->IoStatus.Status:%d.\n", Data->IoStatus.Status));
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}


	status = FltGetFileNameInformation(Data
		, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT
		, &nameInfo);

	if (!NT_SUCCESS( status )) 
		return FLT_POSTOP_FINISHED_PROCESSING;
	
	FltParseFileNameInformation( nameInfo );
	KdPrint(("[ScannerPreCreate] monitoer:%wZ \n", &nameInfo->Name));
	if(IsFilemonGuardPath(nameInfo->Name.Buffer
		, FlagOn(FILE_DIRECTORY_FILE, Data->Iopb->Parameters.Create.Options) > 0
		, &nType))
	{
		WCHAR		szPath[MAX_PATH]		= {0};

		wcsncpy(szPath, nameInfo->Name.Buffer, min(MAX_PATH-1, nameInfo->Name.Length));
		FltReleaseFileNameInformation( nameInfo );
		// 获取通过与否
		if(FALSE != CheckRequestIsAllowed(MAKEGUARDTYPE(MASK_GUARDLITE_FILEMON, nType)
			, szPath
			, L""
			, L""))
		{
			return FLT_PREOP_SUCCESS_NO_CALLBACK;
		}
		// 未通过
		if(FlagOn( (FILE_CREATE<<24), Data->Iopb->Parameters.Create.Options ))
		{
			Data->IoStatus.Information = 0;
			Data->IoStatus.Status = STATUS_ACCESS_DENIED;
			return FLT_PREOP_COMPLETE;
		}
		return FLT_PREOP_SUCCESS_WITH_CALLBACK;
	}
	
	FltReleaseFileNameInformation( nameInfo );
	return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
Пример #13
0
FLT_POSTOP_CALLBACK_STATUS
claimsmanPostOperation(
_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.

--*/
{
	UNREFERENCED_PARAMETER(Data);
	UNREFERENCED_PARAMETER(CompletionContext);
	UNREFERENCED_PARAMETER(Flags);
	NTSTATUS status;
	PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
	PUNICODE_STRING fileName = NULL;
	PTOKEN_USER pTokenUser = NULL;
	UNICODE_STRING sidString;
	
	LARGE_INTEGER Timeout;
	Timeout.QuadPart = (LONGLONG)1 * 10 * 1000 * 1000;
	
	// If there is no client registered, bail out immediately!
	// If the event is from kernel, bail out immediately!
	// If the event check for existence of file, bail out immediately!
	if (
		(ClaimsmanData.ClientPort == NULL) || 
		(Data->RequestorMode == KernelMode) ||
		(Data->IoStatus.Information == FILE_DOES_NOT_EXIST) ||
		(Data->IoStatus.Information == FILE_EXISTS)
		) {
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	//  We got a log record, if there is a file object, get its name.

	if (FltObjects->FileObject != NULL) {
		status = FltGetFileNameInformation(Data,
			FLT_FILE_NAME_NORMALIZED |
			FLT_FILE_NAME_QUERY_DEFAULT,
			&nameInfo);
	}
	else {
		//  Can't get a name when there's no file object
		status = STATUS_UNSUCCESSFUL;
	}

	if (NT_SUCCESS(status)) {
		FltParseFileNameInformation(nameInfo);
		fileName = &nameInfo->Name;
		// Produces way too much logging
		//PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
		//	("claimsman!claimsmanPostOperation: fileName=%wZ\n", fileName));
	}
	else
	{
		// No point continuing because we obviously did not get a filename anyways
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	//The only IRP you can trust for user information is IRP_MJ_CREATE. Things 
	//like write can be in arbitrary thread context, and even if the call works
	//you can get the wrong SID.

	status = SeQueryInformationToken(SeQuerySubjectContextToken(&(Data->Iopb->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext)), TokenUser, &pTokenUser);
	if (STATUS_SUCCESS == status && RtlValidSid(pTokenUser->User.Sid))
	{
		// Interesting extension?
		if (ClaimsmanCheckExtension(&nameInfo->Extension)) {
			CLAIMSMAN_MESSAGE msg;

			status = RtlConvertSidToUnicodeString(&sidString, pTokenUser->User.Sid, TRUE);

			if (NT_SUCCESS(status)) {
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: SID=%wZ\n", &sidString));
			}
			else {
				// No point continuing because we obviously did not get a valid SID
				FltReleaseFileNameInformation(nameInfo);
				ExFreePool(pTokenUser);
				return FLT_POSTOP_FINISHED_PROCESSING;
			}

			if (ClaimsmanCheckUserIgnore(&sidString)) {
				// Ignored user! Bail out!
				FltReleaseFileNameInformation(nameInfo);
				ExFreePool(pTokenUser);
				RtlFreeUnicodeString(&sidString);
				return FLT_POSTOP_FINISHED_PROCESSING;
			}

			LONGLONG size;
			LONGLONG modified;
			getSizeModified(FltObjects->Instance, fileName, &size, &modified);

			InitializeMessage(&msg, &sidString, fileName, FltObjects->FileObject->ReadAccess, FltObjects->FileObject->WriteAccess, FltObjects->FileObject->DeleteAccess, size, modified, Data->IoStatus.Status);

			// Ready, send the message!
			// But only if there's a client connected
			if (ClaimsmanData.ClientPort != NULL) {

				FltSendMessage(ClaimsmanData.Filter,
					&ClaimsmanData.ClientPort,
					&msg,
					sizeof(msg),
					NULL,
					0,
					&Timeout
					);
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: sent message=%d\n", status));
			}
			else {
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: no client connected!"));
			}
			RtlFreeUnicodeString(&sidString);
		}
	}

	FltReleaseFileNameInformation(nameInfo);
	if (pTokenUser != NULL) {
		ExFreePool(pTokenUser);
	}
	return FLT_POSTOP_FINISHED_PROCESSING;
}
Пример #14
0
NTSTATUS GenerateFileName(IN PFLT_INSTANCE  Instance,
    IN PFILE_OBJECT  FileObject,
    IN PFLT_CALLBACK_DATA  CallbackData,
    IN FLT_FILE_NAME_OPTIONS  NameOptions,
    OUT PBOOLEAN  CacheFileNameInformation,
    OUT PFLT_NAME_CONTROL  FileName
) //上层的minifilter过滤驱动的名字请求进行处理
{
	NTSTATUS Status = STATUS_UNSUCCESSFUL;
	PFILE_OBJECT StreamObject = FileObject;
	PFLT_FILE_NAME_INFORMATION FileNameInformation = NULL;
	BOOLEAN bEncryptResource = FALSE;
	PFCB Fcb = FileObject->FsContext;
	PCCB Ccb = FileObject->FsContext2;

	FsRtlEnterFileSystem();

	try
	{
		if(IsMyFakeFcb(FileObject))
		{
			

			ExAcquireResourceSharedLite(Fcb->EncryptResource,TRUE);
			bEncryptResource = TRUE;

			if(BooleanFlagOn(Fcb->FcbState,SCB_STATE_SHADOW_CLOSE) || Ccb->StreamFileInfo.StreamObject == NULL)
			{
				try_return (Status = STATUS_FILE_DELETED);
			}
			else
			{			
				StreamObject = Ccb->StreamFileInfo.StreamObject;
			}
		}

		ClearFlag(NameOptions,FLT_FILE_NAME_REQUEST_FROM_CURRENT_PROVIDER);

		if(FlagOn(NameOptions,FLT_FILE_NAME_NORMALIZED))
		{
			ClearFlag(NameOptions,FLT_FILE_NAME_NORMALIZED);
			SetFlag(NameOptions,FLT_FILE_NAME_OPENED);
		}
		
		if (CallbackData) 
		{
			PFILE_OBJECT TemFileObject = CallbackData->Iopb->TargetFileObject;
			CallbackData->Iopb->TargetFileObject = StreamObject;

			FltSetCallbackDataDirty(CallbackData);

			Status = FltGetFileNameInformation(CallbackData,NameOptions, &FileNameInformation);
			
			CallbackData->Iopb->TargetFileObject = TemFileObject;
			FltClearCallbackDataDirty(CallbackData);
		} 
		else 
		{
			Status = FltGetFileNameInformationUnsafe(StreamObject,Instance, NameOptions, &FileNameInformation);
		}
		if(!NT_SUCCESS(Status))
		{
			try_return (Status);
		}
		Status = FltCheckAndGrowNameControl(FileName, FileNameInformation->Name.Length);

		if(!NT_SUCCESS(Status))
		{
			try_return (Status);
		}

		RtlCopyUnicodeString(&FileName->Name, &FileNameInformation->Name);

		if(FileNameInformation != NULL)
		{
			FltReleaseFileNameInformation(FileNameInformation);
		}
		Status = STATUS_SUCCESS;
try_exit: NOTHING;
	}
	finally
	{
		if(bEncryptResource)
		{
			ExReleaseResourceLite( Fcb->EncryptResource );
		}
	}
	FsRtlExitFileSystem();
	return Status;
}
Пример #15
0
FLT_POSTOP_CALLBACK_STATUS
CtxPostSetInfo (
    _Inout_ PFLT_CALLBACK_DATA Cbd,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Inout_opt_ PVOID CbdContext,
    _In_ FLT_POST_OPERATION_FLAGS Flags
    )
{
    PCTX_INSTANCE_CONTEXT instanceContext = NULL;
    PCTX_FILE_CONTEXT fileContext = NULL;
    PCTX_STREAM_CONTEXT streamContext = NULL;
    PCTX_STREAMHANDLE_CONTEXT streamHandleContext = NULL;
    PFLT_FILE_NAME_INFORMATION nameInfo = NULL;

    NTSTATUS status;
    BOOLEAN streamContextCreated, fileContextCreated, streamHandleContextReplaced;
    
    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CbdContext );

    //
    //  The pre-operation callback will return FLT_PREOP_SYNCHRONIZE if it needs a 
    //  post operation callback. In this case, the Filter Manager will call the 
    //  minifilter's post-operation callback in the context of the pre-operation 
    //  thread, at IRQL <= APC_LEVEL. This allows the post-operation code to be
    //  pagable and also allows it to access paged data
    //  

    PAGED_CODE();

    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Ctx]: CtxPostSetInfo -> Enter (Cbd = %p, FileObject = %p)\n",
                 Cbd,
                 FltObjects->FileObject) );


    //
    // Initialize defaults
    //
    
    status = STATUS_SUCCESS;

    //
    //  If the SetInfo has failed, do nothing
    //

    if (!NT_SUCCESS( Cbd->IoStatus.Status )) {
        
        goto CtxPostSetInfoCleanup;        
    }


    //
    //  Get the instance context for the target instance
    //

    DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> Trying to get instance context (TargetInstance = %p, Cbd = %p, FileObject = %p)\n",
                 Cbd->Iopb->TargetInstance,
                 Cbd,
                 FltObjects->FileObject) );
    
    status = FltGetInstanceContext( Cbd->Iopb->TargetInstance,
                                    &instanceContext );
    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: CtxPostSetInfo -> Failed to get instance context (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );
    
        goto CtxPostSetInfoCleanup;
    }

    DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> Instance context info for volume %wZ (Cbd = %p, FileObject = %p, InstanceContext = %p) \n\tVolumeName = %wZ \n\tInstance = %p \n\tVolume = %p\n",
                 &instanceContext->VolumeName,
                 Cbd,
                 FltObjects->FileObject,
                 instanceContext,
                 &instanceContext->VolumeName,
                 &instanceContext->Instance,
                 &instanceContext->Volume) );


    //
    // Get the directory name
    //
    
    status = FltGetFileNameInformation( Cbd,
                                        FLT_FILE_NAME_NORMALIZED |
                                        FLT_FILE_NAME_QUERY_DEFAULT,
                                        &nameInfo );
    
    if (!NT_SUCCESS( status )) {
    
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostSetInfo -> Failed to get file name information (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );
    
        goto CtxPostSetInfoCleanup;
    }

    
    //
    // Get the stream context
    //

    status = CtxFindOrCreateStreamContext(Cbd, 
                                          FALSE,     // do not create if one does not exist
                                          &streamContext,
                                          &streamContextCreated);
    if (!NT_SUCCESS( status )) {

        //
        //  This failure will most likely be because stream contexts are not supported
        //  on the object we are trying to assign a context to or the object is being 
        //  deleted
        //  
                
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostSetInfo -> Failed to find stream context (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );
    
        goto CtxPostSetInfoCleanup;
    }        

    DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> Getting stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p. StreamContextCreated = %x)\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamContext,
                 streamContextCreated) );

    //
    //  Acquire write acccess to the context
    //
    
    CtxAcquireResourceExclusive(streamContext->Resource);


    DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> Old info in stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamContext,
                 &streamContext->FileName,
                 streamContext->CreateCount,
                 streamContext->CleanupCount,
                 streamContext->CloseCount) );


    
    //
    //  Update the file name in the context
    //
    
    status = CtxUpdateNameInStreamContext( &nameInfo->Name, 
                                                  streamContext);


    DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> New info in stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamContext,
                 &streamContext->FileName,
                 streamContext->CreateCount,
                 streamContext->CleanupCount,
                 streamContext->CloseCount) );

    //
    //  Relinquish write acccess to the context
    //
    
    CtxReleaseResource(streamContext->Resource);

    //
    //  Quit on failure after we have given up
    //  the resource
    //

    if (!NT_SUCCESS( status )) {
    
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostSetInfo -> Failed to update name in stream context for file %wZ (Cbd = %p, FileObject = %p)\n",
                     &nameInfo->Name,
                     Cbd,
                     FltObjects->FileObject) );

        goto CtxPostSetInfoCleanup;
    }
            


    //
    // Create or replace a stream handle context
    //

    status = CtxCreateOrReplaceStreamHandleContext(Cbd, 
                                                   TRUE,
                                                   &streamHandleContext,
                                                   &streamHandleContextReplaced);
    if (!NT_SUCCESS( status )) {

        //
        //  This failure will most likely be because stream contexts are not supported
        //  on the object we are trying to assign a context to or the object is being 
        //  deleted
        //  
                
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostSetInfo -> Failed to find or create stream handle context (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );

        goto CtxPostSetInfoCleanup;
    }        

    DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> Creating/Replacing stream handle context for file %wZ (Cbd = %p, FileObject = %p StreamHandleContext = %p, StreamHandleContextReplaced = %x)\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamHandleContext,
                 streamHandleContextReplaced) );

    //
    //  Acquire write acccess to the context
    //

    CtxAcquireResourceExclusive(streamHandleContext->Resource);

    //
    //  Update the file name in the context
    //

    status = CtxUpdateNameInStreamHandleContext( &nameInfo->Name, 
                                                 streamHandleContext);

    DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> Stream handle context info for file %wZ (Cbd = %p, FileObject = %p, StreamHandleContext = %p) \n\tName = %wZ\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamHandleContext,
                 &streamHandleContext->FileName) );

    //
    //  Relinquish write acccess to the context
    //

    CtxReleaseResource( streamHandleContext->Resource );

    //
    //  Quit on failure after we have given up
    //  the resource
    //

    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostSetInfo -> Failed to update name in stream handle context for file %wZ (Cbd = %p, FileObject = %p)\n",
                     &nameInfo->Name,
                     Cbd,
                     FltObjects->FileObject) );

        goto CtxPostSetInfoCleanup;
    }

    
    //
    // Get the file context
    //

    status = CtxFindOrCreateFileContext( Cbd, 
                                         FALSE,     // do not create if one does not exist
                                         NULL,
                                         &fileContext,
                                         &fileContextCreated);
    if (!NT_SUCCESS( status )) {

        //
        //  This failure will most likely be because file contexts are not supported
        //  on the object we are trying to assign a context to or the object is being 
        //  deleted
        //  
                
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostSetInfo -> Failed to find file context (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );
    
        goto CtxPostSetInfoCleanup;
    }        

    DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> Getting file context for file %wZ (Cbd = %p, FileObject = %p, FileContext = %p. FileContextCreated = %x)\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 fileContext,
                 fileContextCreated) );

    DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostSetInfo -> File context info for file %wZ (Cbd = %p, FileObject = %p, FileContext = %p) \n\tName = %wZ\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 fileContext,
                 &fileContext->FileName) );
    

CtxPostSetInfoCleanup:

    
    //
    // Release the references we have acquired
    //    
        
    if (instanceContext != NULL) {

        FltReleaseContext( instanceContext );            
    }

    if (fileContext != NULL) {

        FltReleaseContext( fileContext );            
    }

    if (streamContext != NULL) {

        FltReleaseContext( streamContext );            
    }

    if (streamHandleContext != NULL) {

        FltReleaseContext( streamHandleContext );            
    }

    if (nameInfo != NULL) {

        FltReleaseFileNameInformation( nameInfo );
    }

    if (!NT_SUCCESS( status )) {
    
        DebugTrace( DEBUG_TRACE_ERROR,
                    ("[Ctx]: CtxPostSetInfo -> Failed with status 0x%x \n",
                    status) );

        //
        //  It doesn't make sense to udate Cbd->IoStatus.Status on failure since the
        //  file system has suceesfully completed the operation
        //
    }

    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Ctx]: CtxPostSetInfo -> Exit (Cbd = %p, FileObject = %p)\n",
                 Cbd,
                 FltObjects->FileObject) );

    return FLT_POSTOP_FINISHED_PROCESSING;
}
Пример #16
0
FLT_POSTOP_CALLBACK_STATUS
CtxPostCreate (
    _Inout_ PFLT_CALLBACK_DATA Cbd,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Inout_opt_ PVOID CbdContext,
    _In_ FLT_POST_OPERATION_FLAGS Flags
    )
{

    PCTX_FILE_CONTEXT fileContext = NULL;    
    PCTX_STREAM_CONTEXT streamContext = NULL;    
    PCTX_STREAMHANDLE_CONTEXT streamHandleContext = NULL;    
    PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
    UNICODE_STRING fileName;

    NTSTATUS status;
    BOOLEAN fileContextCreated, streamContextCreated, streamHandleContextReplaced;


    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( CbdContext );

    PAGED_CODE();

    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Ctx]: CtxPostCreate -> Enter (Cbd = %p, FileObject = %p)\n",
                 Cbd,
                 FltObjects->FileObject) );

    //
    // Initialize defaults
    //

    status = STATUS_SUCCESS;

    //
    //  If the Create has failed, do nothing
    //

    if (!NT_SUCCESS( Cbd->IoStatus.Status )) {
        
        goto CtxPostCreateCleanup;        
    }


    //
    // Get the file name
    //
    
    status = FltGetFileNameInformation( Cbd,
                                        FLT_FILE_NAME_NORMALIZED |
                                        FLT_FILE_NAME_QUERY_DEFAULT,
                                        &nameInfo );    

    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostCreate -> Failed to get name information (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );

        goto CtxPostCreateCleanup;
    }

    
    //
    // Find or create a stream context
    //

    status = CtxFindOrCreateStreamContext(Cbd, 
                                          TRUE,
                                          &streamContext,
                                          &streamContextCreated);
    if (!NT_SUCCESS( status )) {

        //
        //  This failure will most likely be because stream contexts are not supported
        //  on the object we are trying to assign a context to or the object is being 
        //  deleted
        //  
                
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostCreate -> Failed to find or create stream context (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );
    
        goto CtxPostCreateCleanup;
    }        

    DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostCreate -> Getting/Creating stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p. StreamContextCreated = %x)\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamContext,
                 streamContextCreated) );

    //
    //  Acquire write acccess to the context
    //
    
    CtxAcquireResourceExclusive(streamContext->Resource);

    //
    //  Increment the create count
    //

    streamContext->CreateCount++;
    
    //
    //  Update the file name in the context
    //
    
    status = CtxUpdateNameInStreamContext( &nameInfo->Name, 
                                                  streamContext);


    DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostCreate -> Stream context info for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamContext,
                 &streamContext->FileName,
                 streamContext->CreateCount,
                 streamContext->CleanupCount,
                 streamContext->CloseCount) );

    //
    //  Relinquish write acccess to the context
    //
    
    CtxReleaseResource(streamContext->Resource);

    //
    //  Quit on failure after we have given up
    //  the resource
    //

    if (!NT_SUCCESS( status )) {
    
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostCreate -> Failed to update name in stream context for file %wZ (Cbd = %p, FileObject = %p)\n",
                     &nameInfo->Name,
                     Cbd,
                     FltObjects->FileObject) );

        goto CtxPostCreateCleanup;
    }
            


    //
    // Create or replace a stream handle context
    //

    status = CtxCreateOrReplaceStreamHandleContext(Cbd, 
                                                   TRUE,
                                                   &streamHandleContext,
                                                   &streamHandleContextReplaced);
    if (!NT_SUCCESS( status )) {

        //
        //  This failure will most likely be because stream contexts are not supported
        //  on the object we are trying to assign a context to or the object is being 
        //  deleted
        //  
                
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostCreate -> Failed to find or create stream handle context (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );

        goto CtxPostCreateCleanup;
    }        

    DebugTrace(  DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostCreate -> Creating/Replacing stream handle context for file %wZ (Cbd = %p, FileObject = %p StreamHandleContext = %p, StreamHandleContextReplaced = %x)\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamHandleContext,
                 streamHandleContextReplaced) );

    //
    //  Acquire write acccess to the context
    //

    CtxAcquireResourceExclusive( streamHandleContext->Resource );

    //
    //  Update the file name in the context
    //

    status = CtxUpdateNameInStreamHandleContext( &nameInfo->Name, 
                                                 streamHandleContext);

    DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostCreate -> Stream handle context info for file %wZ (Cbd = %p, FileObject = %p, StreamHandleContext = %p) \n\tName = %wZ\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 streamHandleContext,
                 &streamHandleContext->FileName) );

    //
    //  Relinquish write acccess to the context
    //

    CtxReleaseResource(streamHandleContext->Resource);

    //
    //  Quit on failure after we have given up
    //  the resource
    //

    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostCreate -> Failed to update name in stream handle context for file %wZ (Cbd = %p, FileObject = %p)\n",
                     &nameInfo->Name,
                     Cbd,
                     FltObjects->FileObject) );

        goto CtxPostCreateCleanup;
    }
    
    //
    //  After FltParseFileNameInformation, nameInfo->Name also
    //  contains the stream name. We need only the filename and do
    //  not want to include the stream name in the file context
    //

    fileName.Buffer = nameInfo->Name.Buffer;
    fileName.Length = nameInfo->Name.Length - nameInfo->Stream.Length;
    fileName.MaximumLength = fileName.Length;

    //
    // Find or create a file context
    //

    status = CtxFindOrCreateFileContext( Cbd, 
                                         TRUE,
                                         &fileName,
                                         &fileContext,
                                         &fileContextCreated);
    if (!NT_SUCCESS( status )) {

        //
        //  This failure will most likely be because file contexts are not supported
        //  on the object we are trying to assign a context to or the object is being 
        //  deleted
        //  
                
        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                    ("[Ctx]: CtxPostCreate -> Failed to find or create file context (Cbd = %p, FileObject = %p)\n",
                     Cbd,
                     FltObjects->FileObject) );

        goto CtxPostCreateCleanup;
    }        

    DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostCreate -> Getting/Creating file context for file %wZ (Cbd = %p, FileObject = %p, FileContext = %p. FileContextCreated = %x)\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 fileContext,
                 fileContextCreated) );


    DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                ("[Ctx]: CtxPostCreate -> File context info for file %wZ (Cbd = %p, FileObject = %p, FileContext = %p) \n\tName = %wZ\n",
                 &nameInfo->Name,
                 Cbd,
                 FltObjects->FileObject,
                 fileContext,
                 &fileContext->FileName) );


CtxPostCreateCleanup:
    
    
    //
    // Release the references we have acquired
    //    
        
    if (nameInfo != NULL) {

        FltReleaseFileNameInformation( nameInfo );
    }
    
    if (fileContext != NULL) {

        FltReleaseContext( fileContext );            
    }

    if (streamContext != NULL) {

        FltReleaseContext( streamContext );            
    }

    if (streamHandleContext != NULL) {

        FltReleaseContext( streamHandleContext );            
    }
    
    if (!NT_SUCCESS( status )) {
    
        DebugTrace( DEBUG_TRACE_ERROR,
                    ("[Ctx]: CtxPostCreate -> Failed with status 0x%x \n",
                    status) );

        //
        //  It doesn't make sense to udate Cbd->IoStatus.Status on failure since the
        //  file system has successfully completed the operation
        //
        
    }


    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Ctx]: CtxPostCreate -> Exit (Cbd = %p, FileObject = %p, Status = 0x%x)\n",
                 Cbd,
                 FltObjects->FileObject,
                 Cbd->IoStatus.Status) );

    return FLT_POSTOP_FINISHED_PROCESSING;
}
Пример #17
0
NTSTATUS 
NcGetFileNameInformation(
    _In_opt_ PFLT_CALLBACK_DATA Data,
    _In_opt_ PFILE_OBJECT FileObject,
    _In_opt_ PFLT_INSTANCE Instance,
    _In_ FLT_FILE_NAME_OPTIONS NameOptions,
    _Outptr_ PFLT_FILE_NAME_INFORMATION *FileNameInformation 
    )
/*++

Routine Description:

    This function is a wrapper to call the correct variant of
    FltGetFileNameInformation depending on the information we happen to
    have available.

Arguments:

    Data - Pointer to the callback data structure associated with a request.
        This is optional, but if not specified, FileObject and Instance must
        be supplied.

    FileObject - Pointer to the file object to query a name on.  Optional,
        but if not supplied, Data must be supplied.

    Instance - Pointer to the instance of our filter to query the name on.
        Optional, but if not supplied, Data must be supplied.

    NameOptions - FLT_FILE_NAME_* flags for this request.

    FileNameInformation - On output, contains the file name information
        resulting from this query.  On failure, contents are undefined.
        On success, caller is responsible for releasing this with
        FltReleaseFileNameInformation.

Return Value:

    Returns the status of the operation.

--*/
{
    NTSTATUS Status;

    PAGED_CODE();

    FLT_ASSERT( Data || FileObject );

    *FileNameInformation = NULL;

    if (ARGUMENT_PRESENT( Data )) {

        Status = FltGetFileNameInformation( Data,
                                            NameOptions,
                                            FileNameInformation );

    } else if (ARGUMENT_PRESENT( FileObject )) {

        Status = FltGetFileNameInformationUnsafe( FileObject,
                                                  Instance,
                                                  NameOptions,
                                                  FileNameInformation );
    //
    //  This should never happen, as either Data or FileObject must be non-NULL.
    //

    } else {

        FLT_ASSERT( FALSE );
        Status = STATUS_INVALID_PARAMETER;
    }

    return Status;
}
Пример #18
0
/* 
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
 *
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
 */
FLT_POSTOP_CALLBACK_STATUS
PostSetInformation( IN OUT PFLT_CALLBACK_DATA Data,
                    IN PCFLT_RELATED_OBJECTS FltObjects,
                    IN PVOID CompletionContext,
                    IN FLT_POST_OPERATION_FLAGS Flags )

{

PFLT_FILE_NAME_INFORMATION    FNameInfo;
NTSTATUS                      Status;


FILE_RENAME_INFORMATION       FRI;


    // If we have an error then just exit
    if ( !NT_SUCCESS( Data->IoStatus.Status ) || ( STATUS_REPARSE == Data->IoStatus.Status ) ) 
    {
     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 )) 
    {
     return FLT_POSTOP_FINISHED_PROCESSING;
    }

    FltParseFileNameInformation( FNameInfo );


    switch ( Data->Iopb->Parameters.SetFileInformation.FileInformationClass )
    {
     case FileRenameInformation:
         {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "PostSetInfo()-RENAME [%wZ] \n", &FNameInfo->Name ) );
          break;
         }
     case FileAllocationInformation:
         {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "PostSetInfo()-ALLOCATION [%wZ] \n", &FNameInfo->Name ) );
          break;
         }
     case FileBasicInformation:
         {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "PostSetInfo()-BASIC[%wZ] \n", &FNameInfo->Name ) );
          break;
         }
     case FileDispositionInformation:
         {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "PostSetInfo()-DISPOSITION [%wZ] \n", &FNameInfo->Name ) );
          break;
         }
     case FileEndOfFileInformation:
         {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "PostSetInfo()-EOF [%wZ] \n", &FNameInfo->Name ) );
          break;
         }
     case FileLinkInformation:
         {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "PostSetInfo()-LINK [%wZ] \n", &FNameInfo->Name ) );
          break;
         }
     case FilePositionInformation:
         {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "PostSetInfo()-POSITION [%wZ] \n", &FNameInfo->Name ) );
          break;
         }
     case FileValidDataLengthInformation:
         {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "PostSetInfo()-VALIDATEDATALENGTH [%wZ] \n", &FNameInfo->Name ) );
          break;
         }
     default :
            {
 DBG_PRINT( DbgOutput, DBG_IRP_MJ_SET_INFORMATION, (PRINT_TAG_SETINFO "BAD MOJO\n") );
             break;
            }
 
    } // End switch ( Data->Iopb->Parameters.SetFileInformation.FileInformationClass )


    // Free
    FltReleaseFileNameInformation( FNameInfo );


 return FLT_POSTOP_FINISHED_PROCESSING;
}
static
FLT_POSTOP_CALLBACK_STATUS
    FileCreateFilterPostCallback
    (
        PFLT_CALLBACK_DATA Data,
        PCFLT_RELATED_OBJECTS FltObjects,
        PVOID CompletionContext,
        FLT_POST_OPERATION_FLAGS Flags
    )
{
    FLT_POSTOP_CALLBACK_STATUS status = FLT_POSTOP_FINISHED_PROCESSING;
    KLOCK_QUEUE_HANDLE hMutex = { 0 };
    PFLT_FILE_NAME_INFORMATION fileInfo = NULL;
    RU32 pid = 0;
    RU64 ts = 0;
    RU32 createOptions = 0;
    RU32 createDispositions = 0;
    _fileContext* context = NULL;
    
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );
    UNREFERENCED_PARAMETER( Flags );

    // We only care about user mode for now.
    if( UserMode != Data->RequestorMode ||
        STATUS_SUCCESS != Data->IoStatus.Status )
    {
        return status;
    }

    if( FILE_CREATED == Data->IoStatus.Information )
    {
        pid = (RU32)FltGetRequestorProcessId( Data );
        ts = rpal_time_getLocal();
        
        if( !NT_SUCCESS( FltGetFileNameInformation( Data,
                                                    FLT_FILE_NAME_NORMALIZED |
                                                    FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
                                                    &fileInfo ) ) )
        {
            rpal_debug_kernel( "Failed to get file name info" );
            fileInfo = NULL;
        }
        else
        {
            //rpal_debug_kernel( "NEW: %wZ", fileInfo->Name );
        }

        if( NULL != ( context = _getOrSetContext( Data ) ) )
        {
            context->isNew = TRUE;
            FltReleaseContext( (PFLT_CONTEXT)context );
        }

        KeAcquireInStackQueuedSpinLock( &g_collector_2_mutex, &hMutex );

        g_files[ g_nextFile ].pid = pid;
        g_files[ g_nextFile ].ts = ts;
        g_files[ g_nextFile ].uid = KERNEL_ACQ_NO_USER_ID;
        g_files[ g_nextFile ].action = KERNEL_ACQ_FILE_ACTION_ADDED;

        if( NULL != fileInfo )
        {
            copyUnicodeStringToBuffer( &fileInfo->Name,
                                       g_files[ g_nextFile ].path );

            FltReleaseFileNameInformation( fileInfo );
        }

        g_nextFile++;
        if( g_nextFile == _NUM_BUFFERED_FILES )
        {
            g_nextFile = 0;
        }

        KeReleaseInStackQueuedSpinLock( &hMutex );
    }

    createOptions = Data->Iopb->Parameters.Create.Options & 0x00FFFFFF;
    createDispositions = ( Data->Iopb->Parameters.Create.Options & 0xFF000000 ) >> 24;

    if( IS_FLAG_ENABLED( createOptions, FILE_DELETE_ON_CLOSE ) )
    {
        if( NULL != ( context = _getOrSetContext( Data ) ) )
        {
            context->isDelete = TRUE;
            FltReleaseContext( (PFLT_CONTEXT)context );
        }
    }

    return status;
}
Пример #20
0
FLT_PREOP_CALLBACK_STATUS
PreFileOperationCallback (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
{
	NTSTATUS status;
	PFLT_FILE_NAME_INFORMATION pFileNameInformation;
	PFILE_EVENT pFileEvent;
	LARGE_INTEGER CurrentSystemTime;
	LARGE_INTEGER CurrentLocalTime;
	ULONG returnedLength;
	//HANDLE hThread;
	//HANDLE handle5;
	TIME_FIELDS TimeFields;
	BOOLEAN pathNameFound = FALSE;
	UNICODE_STRING filePath;
	
	FLT_PREOP_CALLBACK_STATUS returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
	
	/* If this is a callback for a FS Filter driver then we ignore the event */
	if(FLT_IS_FS_FILTER_OPERATION(Data))
	{
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}

	/* Allocate a large 64kb string ... maximum path name allowed in windows */
	filePath.Length = 0;
	filePath.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR);
	filePath.Buffer = ExAllocatePoolWithTag(NonPagedPool, filePath.MaximumLength, FILE_POOL_TAG); 

	if(filePath.Buffer == NULL)
	{
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}

	if (FltObjects->FileObject != NULL && Data != NULL) {
		status = FltGetFileNameInformation( Data,
											FLT_FILE_NAME_NORMALIZED |
											FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
											&pFileNameInformation );
		if(NT_SUCCESS(status))
		{
			if(pFileNameInformation->Name.Length > 0)
			{
				RtlUnicodeStringCopy(&filePath, &pFileNameInformation->Name);
				//RtlStringCbCopyUnicodeString(pFileEvent->filePath, 1024, &pFileNameInformation->Name);
				pathNameFound = TRUE;
			}
			/* Backup the file if it is marked for deletion */
			CopyFileIfBeingDeleted (Data,FltObjects,pFileNameInformation);

			/* Release the file name information structure if it was used */
			if(pFileNameInformation != NULL)
			{
				FltReleaseFileNameInformation(pFileNameInformation);
			}
		} else {
			NTSTATUS lstatus;
            PFLT_FILE_NAME_INFORMATION pLFileNameInformation;
            lstatus = FltGetFileNameInformation( Data,
				FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
				&pLFileNameInformation);
			if(NT_SUCCESS(lstatus))
			{
				if(pLFileNameInformation->Name.Length > 0)
				{
					RtlUnicodeStringCopy(&filePath, &pLFileNameInformation->Name);
					//RtlStringCbCopyUnicodeString(pFileEvent->filePath, 1024, &pLFileNameInformation->Name);
					pathNameFound = TRUE;
				}
				/* Backup the file if it is marked for deletion */
				CopyFileIfBeingDeleted (Data,FltObjects,pFileNameInformation);

				/* Release the file name information structure if it was used */
				if(pLFileNameInformation != NULL)
				{
					FltReleaseFileNameInformation(pLFileNameInformation);
				}
			}
		}
	}

	/* If path name could not be found the file monitor uses the file name stored
	   in the FileObject. The documentation says that we shouldn't use this info
	   as it may not be correct. It does however allow us get some nice file events
	   such as the system process writing to the $MFT file etc. Remove this code if
	   problems start to occur */
	if( (pathNameFound == FALSE) && 
		(FltObjects->FileObject != NULL) &&
		(FltObjects->FileObject->RelatedFileObject == NULL) &&
		(FltObjects->FileObject->FileName.Length > 0))
	{
		NTSTATUS status;
		ULONG size;
		UNICODE_STRING szTempPath;
		UNICODE_STRING szDevice;
		UNICODE_STRING szFileNameDevice;

		/* Check the FileObject->FileName isn't already a complete filepath */
		szFileNameDevice.Length = FltObjects->FileObject->FileName.Length;
		szFileNameDevice.MaximumLength = FltObjects->FileObject->FileName.MaximumLength;
		szFileNameDevice.Buffer = ExAllocatePoolWithTag(NonPagedPool, szFileNameDevice.MaximumLength, FILE_POOL_TAG);
		RtlInitUnicodeString(&szDevice, L"\\Device");
		if(FltObjects->FileObject->FileName.Length >= szDevice.Length)
		{
			RtlUnicodeStringCchCopyN(&szFileNameDevice, &FltObjects->FileObject->FileName, 7);
		}

		if(RtlEqualUnicodeString(&szDevice, &szFileNameDevice, TRUE))
		{
			RtlUnicodeStringCopy(&filePath, &FltObjects->FileObject->FileName);
			pathNameFound = TRUE;
		} else {
			szTempPath.Length = 0;
			szTempPath.MaximumLength = FltObjects->FileObject->FileName.MaximumLength + 2;

			/* Get the volume name of where the event came from */
			status = FltGetVolumeName(
						FltObjects->Volume,
						NULL,
						&size
						);
			if(status == STATUS_BUFFER_TOO_SMALL)
			{
				szTempPath.MaximumLength += (USHORT)size;
				szTempPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, szTempPath.MaximumLength, FILE_POOL_TAG);
				
				if(szTempPath.Buffer != NULL)
				{
					status = FltGetVolumeName(
							FltObjects->Volume,
							&szTempPath,
							&size
							);
					if(NT_SUCCESS(status))
					{
						/* Append the file event to the volume name */
						RtlUnicodeStringCat(&szTempPath, &FltObjects->FileObject->FileName);
						RtlUnicodeStringCopy(&filePath, &szTempPath);
						pathNameFound = TRUE;
					}
					ExFreePoolWithTag(szTempPath.Buffer, FILE_POOL_TAG);
				}
			}
		}
		ExFreePoolWithTag(szFileNameDevice.Buffer, FILE_POOL_TAG);
	}

	if(!pathNameFound)
	{
		RtlUnicodeStringCatString(&filePath, L"UNKNOWN"); 
	}

	/* Allocate file event and put the values into it */
	/* NOTE this is freed in the post op callback (which should always get called) */
	pFileEvent = ExAllocatePoolWithTag(NonPagedPool, sizeof(FILE_EVENT)+filePath.Length+sizeof(WCHAR), FILE_POOL_TAG);
	
	if(pFileEvent == NULL)
	{
		ExFreePoolWithTag(filePath.Buffer, FILE_POOL_TAG);
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}

	/* Copy file path into file event */
	pFileEvent->filePathLength = filePath.Length+sizeof(WCHAR);
	RtlStringCbCopyUnicodeString(pFileEvent->filePath, pFileEvent->filePathLength, &filePath);
	/* Free the allocated storage for a filepath */
	ExFreePoolWithTag(filePath.Buffer, FILE_POOL_TAG);

	pFileEvent->majorFileEventType = Data->Iopb->MajorFunction;
	pFileEvent->minorFileEventType = Data->Iopb->MinorFunction;
	pFileEvent->processId = 0;

	if (FltObjects->FileObject != NULL)
	{
		pFileEvent->flags = FltObjects->FileObject->Flags;
	}

	if(Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION)
	{
		if(Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileDispositionInformation)
		{
			PFILE_DISPOSITION_INFORMATION pFileInfo = (PFILE_DISPOSITION_INFORMATION)Data->Iopb->Parameters.SetFileInformation.InfoBuffer;
			/* If the file is marked for deletion back it up */
			if(pFileInfo->DeleteFile)
			{
				pFileEvent->majorFileEventType = 0x99;
			}
		}
	}

	/* Get the process id of the file event */
	/* NOTE we are kinda using an undocumented function here but its all available
	   on the interweb. Plus its much better than accessing the PETHREAD structure
	   which could change at any time. Also, this one is available to userspace
	   programs so it should be safe to use. We have to use this function because
	   a file I/O may either be processed in the context of the userspace program
	   or the system context. This uses the thread data from FLT_CALLBACK_DATA to
	   determine which process it actually came from. We default back to getting
	   the current process id if all else fails. */
	/* SECOND NOTE FltGetRequestorProcessId does not get the correct process id, it
	   looks like it still get the proces id of the context the pre callback gets
	   called in */
	/*
	status = ObOpenObjectByPointer(Data->Thread, 
		OBJ_KERNEL_HANDLE, 
		NULL, 
		0, 
		0, 
		KernelMode, 
		&hThread);
	if(NT_SUCCESS(status))
	{
		THREAD_BASIC_INFORMATION threadBasicInformation;

		status = ZwQueryInformationThread(hThread, 
			ThreadBasicInformation, 
			&threadBasicInformation, 
			sizeof(THREAD_BASIC_INFORMATION), 
			&returnedLength );
		if(NT_SUCCESS(status))
		{
			pFileEvent->processId = (HANDLE)threadBasicInformation.UniqueProcessId;
			handle5 = pFileEvent->processId;
			//DbgPrint("Process4: %i\n", pFileEvent->processId);
		} else {		
			DbgPrint("ZwQueryInformationThread FAILED: %08x\n", status);
		}
		ZwClose(hThread);
	} else {		
		DbgPrint("ObOpenObjectByPointer FAILED: %08x\n", status);
	}
	*/

	/* New safe get correct process id. One above causes blue screen in some cases */
	if(Data->Thread != NULL)
	{
		PEPROCESS pProcess = IoThreadToProcess( Data->Thread );
		pFileEvent->processId = PsGetProcessId(pProcess);
	} else {
		pFileEvent->processId = PsGetCurrentProcessId();
		DbgPrint("CaptureFileMonitor: Process id may be incorrect\n");
	}
/*
	DbgPrint("%i [%i %i] %s %i %i (%i, %i, %i) %i %i %i %i %i : %ls\n", 
			KeGetCurrentIrql(),
			PsIsSystemThread(Data->Thread),
			PsIsSystemThread(PsGetCurrentThread()),
			FltGetIrpName(Data->Iopb->MajorFunction),
			Data->Iopb->MajorFunction,
			Data->Iopb->MinorFunction,
			pFileEvent->processId,
			PsGetCurrentProcessId(),
			FltGetRequestorProcessId(Data),
			FLT_IS_FASTIO_OPERATION(Data),
			FLT_IS_FS_FILTER_OPERATION(Data),
			FLT_IS_IRP_OPERATION(Data),
			FLT_IS_REISSUED_IO(Data),
			FLT_IS_SYSTEM_BUFFER(Data),
			pFileEvent->filePath);
*/			
	//ASSERT(pFileEvent->processId != 0);

	/* Get the time this event occured */
	KeQuerySystemTime(&CurrentSystemTime);
	ExSystemTimeToLocalTime(&CurrentSystemTime,&CurrentLocalTime);
	RtlTimeToTimeFields(&CurrentLocalTime,&TimeFields);
	pFileEvent->time = TimeFields;



	/* Pass the created file event to the post operation of this pre file operation */
	if (Data->Iopb->MajorFunction == IRP_MJ_SHUTDOWN)
	{
		PostFileOperationCallback( Data,
						FltObjects,
						pFileEvent,
						0 );
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	} else {
		*CompletionContext = pFileEvent;
		return FLT_PREOP_SUCCESS_WITH_CALLBACK;
	}

    
}
Пример #21
0
static FLT_POSTOP_CALLBACK_STATUS on_post_op (PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS fltobj, struct event *event, FLT_POST_OPERATION_FLAGS flags)
{
	if (event == NULL)
		return FLT_POSTOP_FINISHED_PROCESSING;

	event->time_post = get_timestamp();
	event->status = data->IoStatus.Status;

	if (data->Iopb->MajorFunction == IRP_MJ_CREATE) {
		FLT_FILE_NAME_INFORMATION *name_info = NULL;
		if (FltGetFileNameInformation(data,
					FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
					&name_info) != STATUS_SUCCESS) {
			event_buffer_cancel_add(event);
			return FLT_POSTOP_FINISHED_PROCESSING;
		}
		event->path_length = MAX_PATH_SIZE - 1 < name_info->Name.Length / 2 ? MAX_PATH_SIZE - 1 : name_info->Name.Length / 2;
		RtlCopyMemory(event->path, name_info->Name.Buffer, event->path_length * 2);
		event->path[event->path_length] = 0;
		FltReleaseFileNameInformation(name_info);
	}

	switch (data->Iopb->MajorFunction) {
	case IRP_MJ_CLOSE:
		event->type = ET_FILE_CLOSE;
		break;
	case IRP_MJ_CREATE:
		event->type = ET_FILE_CREATE;
		event->file_create.desired_access       = data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
		event->file_create.share_mode           = data->Iopb->Parameters.Create.ShareAccess;
		event->file_create.attributes           = data->Iopb->Parameters.Create.FileAttributes;
		event->file_create.creation_disposition = data->Iopb->Parameters.Create.Options >> 24;
		event->file_create.create_options       = data->Iopb->Parameters.Create.Options & 0x00ffffff;
		event->file_create.status_information   = data->IoStatus.Information;
		break;
	case IRP_MJ_READ:
		event->type = ET_FILE_READ;
		event->file_rw.offset = data->Iopb->Parameters.Read.ByteOffset;
		event->file_rw.req_length = data->Iopb->Parameters.Read.Length;
		event->file_rw.ret_length = data->IoStatus.Information;
		break;
	case IRP_MJ_WRITE:
		event->type = ET_FILE_WRITE;
		event->file_rw.offset = data->Iopb->Parameters.Write.ByteOffset;
		event->file_rw.req_length = data->Iopb->Parameters.Write.Length;
		event->file_rw.ret_length = data->IoStatus.Information;
		break;
	case IRP_MJ_CREATE_MAILSLOT:
		event->type = ET_FILE_CREATE_MAILSLOT;
		break;
	case IRP_MJ_CREATE_NAMED_PIPE:
		event->type = ET_FILE_CREATE_NAMED_PIPE;
		break;
	case IRP_MJ_QUERY_INFORMATION:
		event->type = ET_FILE_QUERY_INFORMATION;
		if (data->IoStatus.Status == STATUS_SUCCESS || data->IoStatus.Status == STATUS_BUFFER_OVERFLOW) {
			event->file_info.info_type = data->Iopb->Parameters.QueryFileInformation.FileInformationClass;
			event->file_info.info_size = data->Iopb->Parameters.QueryFileInformation.Length <
				sizeof(event->file_info.info_data) ?
				data->Iopb->Parameters.QueryFileInformation.Length :
				sizeof(event->file_info.info_data);
			// NOTE: string inside the info structure is not zero terminated.
			RtlCopyMemory(&event->file_info.info_data,
					data->Iopb->Parameters.QueryFileInformation.InfoBuffer,
					event->file_info.info_size);
		}
		break;
	case IRP_MJ_SET_INFORMATION:
		event->type = ET_FILE_SET_INFORMATION;
		event->file_info.info_type = data->Iopb->Parameters.SetFileInformation.FileInformationClass;
		event->file_info.info_size = data->Iopb->Parameters.SetFileInformation.Length <
			sizeof(event->file_info.info_data) ?
			data->Iopb->Parameters.SetFileInformation.Length :
			sizeof(event->file_info.info_data);
		// NOTE: string inside the info structure is not zero terminated.
		RtlCopyMemory(&event->file_info.info_data,
				data->Iopb->Parameters.SetFileInformation.InfoBuffer,
				event->file_info.info_size);
		break;
	default:
		DbgPrint("resmon: unknown post MajorFunction %d\n", data->Iopb->MajorFunction);
		event_buffer_cancel_add(event);
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	event_buffer_finish_add(event);
	return FLT_POSTOP_FINISHED_PROCESSING;
}