有关采用Filter实现禁用缓存和使用缓存操作实现与分析

1.缓存:

  为了提高访问网页速率,InternetExplorer浏览器会采用累积式加速的方法,将曾经访问的网页内容(包括图片以及cookie文件等)存放在电脑里。这个存放空间,就称它为IE缓存。以后每次访问网站时,IE会首先搜索这个目录,其中已经有访问过的内容,那IE就不必从网上下载,而直接从缓存中调出来,从而提高了访问网站的速率

2.jsp采用模板元素设置禁用缓存的代码

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0"> 

说明:
<meta http-equiv="pragma" content="no-cache">
禁止浏览器从本地缓存中调阅页面,网页不保存在缓存中,每次访问都刷新页面
<meta http-equiv="cache-control" content="no-cache">
同上说明
<meta http-equiv="expires" content="0">
网页在缓存中的过期时间为0,一旦网页过期,必须从服务器上重新订阅


一::::根据以上的了解,我们进行采用Filter过滤器 进行完成动态web资源访问的时候,禁用缓存的操作效果的实现
1.创建Filter过滤器的实现类

package www.csdn.net.day55.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class NoCacheFilter implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {

		HttpServletResponse response = (HttpServletResponse) res;
		HttpServletRequest request = (HttpServletRequest) req;

		response.setDateHeader("Expires", -1);
		response.setHeader("Cache-Control", "no-cache");
		response.setHeader("Pragma", "no-cache");
		// 修改
		chain.doFilter(request, response);// 执行目标方法
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub

	}

}

2.在web.xml文件进行配置操作

  <filter>
        <filter-name>NoCacheFilter</filter-name>
        <filter-class>www.csdn.net.day55.filter.NoCacheFilter</filter-class>
    </filter>
    
    
    <filter-mapping>
        <filter-name>NoCacheFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>

根据以上配置 就可以实现,当以.do结尾,访问web资源的时候,即可达到实现禁用缓存的效果.
怎么演示尼,下面我创建一个演示的servlet

package www.csdn.net.day55.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class UserServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("--------------------doGet------------------");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}

}

serlvet的映射为文件web.xml中的陪配置


<servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>www.csdn.net.day55.servlet.UserServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/userOper.do</url-pattern>
  </servlet-mapping>

3.演示采用最新IE版本中自带的开发人员工具 (通过一下设置打开)

1.找到锯齿工具条



2.选择F12开发人员工具,弹出一下效果


3.在地址栏中输入访问的地址,例如:http://localhost:8080/day55/userOper.do,点击上图中的绿色三角形.变成如下效果


4.然后可以在地址栏中回车,观察效果,可以看到每次返回的结果都是200,这也说明了每次都是从服务器获取页面,并刷新的操作.




备注: 在每次请求后 servlet 都会在后台打印输出一次




 

二::::根据以上的了解,我们进行采用Filter过滤器 进行完成动态web资源访问的时候,采用缓存的操作的效果实现

1.创建Filter过滤器的实现类

package www.csdn.net.day55.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CacheFilter  implements Filter{

	private FilterConfig filterConfig;
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		//设置缓存
		//把请求的 req,res 造型为HttpServletResponse,HttpServletRequest
		HttpServletResponse response = (HttpServletResponse) res;
		HttpServletRequest request = (HttpServletRequest) req;
		String date = filterConfig.getInitParameter("date");
		response.setDateHeader("Expires", System.currentTimeMillis()+Integer.valueOf(date)*1000);	
		chain.doFilter(request, response);
		
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig=filterConfig;
		
	}

}
2.在web.xml文件进行配置操作

     <filter>
        <filter-name>CacheFilter</filter-name>
        <filter-class>www.csdn.net.day55.filter.CacheFilter</filter-class>
        <init-param>
          <param-name>date</param-name>
          <!-- 10毫秒 -->
          <param-value>10</param-value>
          </init-param>
    </filter>
    
    
    
     <filter-mapping>
        <filter-name>CacheFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>



根据以上配置 就可以实现,当以.do结尾,访问web资源的时候,即可达到实现缓存的效果.

怎么演示尼(采用上面的那个写好的Servlet即可测试)

3.演示采用最新IE版本中自带的开发人员工具 (通过一下设置打开)

1.找到锯齿工具条



2.选择F12开发人员工具,弹出一下效果


3.在地址栏中输入访问的地址,例如:http://localhost:8080/day55/userOper.do,点击上图中的绿色三角形.变成如下效果



4.然后可以在地址栏中回车,观察效果

 
 
 
 


效果说明:

     当第一次访问的时候,返回结果是200,代表从服务获取,并刷新。
     当第二次访问的时候如果在缓存的有效时间内 ,就直接使用,返回的结果可以看到是304

     上图可以说明:第三次,第四次访问 ,都在缓存的有效时间内。

    当第五次访问的时候,由于不在缓存的有效时间内,又重新从服务获取,并刷新

    第六次,第七次访问 ,都在缓存的有效时间内,直接使用.

通过以上分析 ,希望你对缓存的使用有更深入的了解.


备注: 在每次请求后 ,会根据返回的结果是否是200,如果是200 servlet 都会在后台打印输出一次,否则就不打印




  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
很抱歉,我无法为您提供完整的代码。但是,我可以为您提供一个简单的示例,以说明如何使用minifilter缓存机制实现透明加解密处理。 在此示例中,我们将使用minifilter驱动程序来拦截文件访问,并使用缓存机制对文件进行加解密处理。我们将使用AES算法进行加解密,并使用Windows CryptoAPI来实现加解密过程。 以下是示例代码的主要部分: ```c // 定义双缓存结构体 typedef struct _DOUBLE_BUFFER { PVOID DataBuffer; // 数据缓存 ULONG DataLength; // 数据长度 PVOID AuxBuffer; // 辅助缓存 ULONG AuxLength; // 辅助缓存长度 ULONG TotalLength; // 数据总长度 CRITICAL_SECTION Lock; // 互斥锁 } DOUBLE_BUFFER, *PDOUBLE_BUFFER; // 初始化双缓存 NTSTATUS InitializeDoubleBuffer(PDOUBLE_BUFFER pBuffer, ULONG TotalLength) { NTSTATUS status = STATUS_SUCCESS; pBuffer->DataBuffer = ExAllocatePoolWithTag(NonPagedPool, TotalLength, 'Tag1'); if (pBuffer->DataBuffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Exit; } pBuffer->DataLength = 0; pBuffer->AuxBuffer = ExAllocatePoolWithTag(NonPagedPool, TotalLength, 'Tag2'); if (pBuffer->AuxBuffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Exit; } pBuffer->AuxLength = 0; pBuffer->TotalLength = TotalLength; InitializeCriticalSection(&pBuffer->Lock); Exit: if (!NT_SUCCESS(status)) { if (pBuffer->DataBuffer != NULL) { ExFreePoolWithTag(pBuffer->DataBuffer, 'Tag1'); } if (pBuffer->AuxBuffer != NULL) { ExFreePoolWithTag(pBuffer->AuxBuffer, 'Tag2'); } } return status; } // 销毁双缓存 VOID DestroyDoubleBuffer(PDOUBLE_BUFFER pBuffer) { if (pBuffer->DataBuffer != NULL) { ExFreePoolWithTag(pBuffer->DataBuffer, 'Tag1'); } if (pBuffer->AuxBuffer != NULL) { ExFreePoolWithTag(pBuffer->AuxBuffer, 'Tag2'); } DeleteCriticalSection(&pBuffer->Lock); } // 读取文件到缓存 NTSTATUS ReadFileToBuffer(PFLT_CALLBACK_DATA Data, PFLT_RELATED_OBJECTS FltObjects, PVOID* pBuffer, PULONG pLength) { NTSTATUS status = STATUS_SUCCESS; HANDLE hFile = NULL; OBJECT_ATTRIBUTES objAttr; IO_STATUS_BLOCK ioStatus; FILE_STANDARD_INFORMATION fileInfo; LARGE_INTEGER byteOffset; ULONG length = 0; ULONG bytesRead = 0; InitializeObjectAttributes(&objAttr, &Data->Iopb->TargetFileObject->FileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); status = FltCreateFile(FltObjects->Instance, FltObjects->FileObject, &hFile, FILE_READ_DATA, &objAttr, &ioStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0, IO_IGNORE_SHARE_ACCESS_CHECK); if (!NT_SUCCESS(status)) { goto Exit; } status = ZwQueryInformationFile(hFile, &ioStatus, &fileInfo, sizeof(fileInfo), FileStandardInformation); if (!NT_SUCCESS(status)) { goto Exit; } length = (ULONG)fileInfo.EndOfFile.QuadPart; *pBuffer = ExAllocatePoolWithTag(NonPagedPool, length, 'Tag3'); if (*pBuffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Exit; } byteOffset.QuadPart = 0; status = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatus, *pBuffer, length, &byteOffset, NULL); if (!NT_SUCCESS(status)) { goto Exit; } bytesRead = (ULONG)ioStatus.Information; if (bytesRead != length) { status = STATUS_FILE_CORRUPT_ERROR; goto Exit; } *pLength = length; Exit: if (hFile != NULL) { ZwClose(hFile); } if (!NT_SUCCESS(status) && *pBuffer != NULL) { ExFreePoolWithTag(*pBuffer, 'Tag3'); *pBuffer = NULL; *pLength = 0; } return status; } // 写入缓存到文件 NTSTATUS WriteBufferToFile(PFLT_CALLBACK_DATA Data, PFLT_RELATED_OBJECTS FltObjects, PVOID pBuffer, ULONG Length) { NTSTATUS status = STATUS_SUCCESS; HANDLE hFile = NULL; OBJECT_ATTRIBUTES objAttr; IO_STATUS_BLOCK ioStatus; LARGE_INTEGER byteOffset; InitializeObjectAttributes(&objAttr, &Data->Iopb->TargetFileObject->FileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); status = FltCreateFile(FltObjects->Instance, FltObjects->FileObject, &hFile, FILE_WRITE_DATA, &objAttr, &ioStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE, NULL, 0, IO_IGNORE_SHARE_ACCESS_CHECK); if (!NT_SUCCESS(status)) { goto Exit; } byteOffset.QuadPart = 0; status = ZwWriteFile(hFile, NULL, NULL, NULL, &ioStatus, pBuffer, Length, &byteOffset, NULL); if (!NT_SUCCESS(status)) { goto Exit; } Exit: if (hFile != NULL) { ZwClose(hFile); } return status; } // AES加密 NTSTATUS EncryptData(PVOID pData, ULONG Length, PVOID pKey, ULONG KeyLength) { NTSTATUS status = STATUS_SUCCESS; HCRYPTPROV hProv = 0; HCRYPTKEY hKey = 0; ULONG blockSize = 0; ULONG bufferLength = 0; PVOID pBuffer = NULL; // 获取加密算法的块大小 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { status = STATUS_INTERNAL_ERROR; goto Exit; } if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, NULL, NULL)) { status = STATUS_INTERNAL_ERROR; goto Exit; } if (!CryptDeriveKey(hProv, CALG_AES_256, NULL, 0, &hKey)) { status = STATUS_INTERNAL_ERROR; goto Exit; } if (!CryptGetKeyParam(hKey, KP_BLOCKLEN, (PBYTE)&blockSize, &bufferLength, 0)) { status = STATUS_INTERNAL_ERROR; goto Exit; } // 分配缓存 bufferLength = ROUND_UP(Length, blockSize); pBuffer = ExAllocatePoolWithTag(NonPagedPool, bufferLength, 'Tag4'); if (pBuffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Exit; } RtlZeroMemory(pBuffer, bufferLength); RtlCopyMemory(pBuffer, pData, Length); // 加密数据 if (!CryptEncrypt(hKey, NULL, TRUE, 0, (PBYTE)pBuffer, &Length, bufferLength)) { status = STATUS_INTERNAL_ERROR; goto Exit; } RtlCopyMemory(pData, pBuffer, Length); Exit: if (hKey != 0) { CryptDestroyKey(hKey); } if (hProv != 0) { CryptReleaseContext(hProv, 0); } if (pBuffer != NULL) { ExFreePoolWithTag(pBuffer, 'Tag4'); } return status; } // AES解密 NTSTATUS DecryptData(PVOID pData, ULONG Length, PVOID pKey, ULONG KeyLength) { NTSTATUS status = STATUS_SUCCESS; HCRYPTPROV hProv = 0; HCRYPTKEY hKey = 0; ULONG blockSize = 0; ULONG bufferLength = 0; PVOID pBuffer = NULL; // 获取解密算法的块大小 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { status = STATUS_INTERNAL_ERROR; goto Exit; } if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, NULL, NULL)) { status = STATUS_INTERNAL_ERROR; goto Exit; } if (!CryptDeriveKey(hProv, CALG_AES_256, NULL, 0, &hKey)) { status = STATUS_INTERNAL_ERROR; goto Exit; } if (!CryptGetKeyParam(hKey, KP_BLOCKLEN, (PBYTE)&blockSize, &bufferLength, 0)) { status = STATUS_INTERNAL_ERROR; goto Exit; } // 分配缓存 bufferLength = ROUND_UP(Length, blockSize); pBuffer = ExAllocatePoolWithTag(NonPagedPool, bufferLength, 'Tag5'); if (pBuffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Exit; } RtlZeroMemory(pBuffer, bufferLength); RtlCopyMemory(pBuffer, pData, Length); // 解密数据 if (!CryptDecrypt(hKey, NULL, TRUE, 0, (PBYTE)pBuffer, &Length)) { status = STATUS_INTERNAL_ERROR; goto Exit; } RtlCopyMemory(pData, pBuffer, Length); Exit: if (hKey != 0) { CryptDestroyKey(hKey); } if (hProv != 0) { CryptReleaseContext(hProv, 0); } if (pBuffer != NULL) { ExFreePoolWithTag(pBuffer, 'Tag5'); } return status; } // 处理文件读取操作 FLT_PREOP_CALLBACK_STATUS PreReadCallback(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) { NTSTATUS status = STATUS_SUCCESS; PFILE_OBJECT pFileObject = FltObjects->FileObject; PVOID pBuffer = NULL; ULONG length = 0; PDOUBLE_BUFFER pDoubleBuffer = NULL; // 检查文件对象是否是普通文件 if ((pFileObject->Flags & FO_STREAM_FILE) != 0) { goto Exit; } // 检查文件大小是否超过双缓存的总长度 if (pFileObject->SectionObjectPointer->FileSize.QuadPart > MAX_DOUBLE_BUFFER_LENGTH) { goto Exit; } // 创建双缓存 pDoubleBuffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(DOUBLE_BUFFER), 'Tag6'); if (pDoubleBuffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Exit; } status = InitializeDoubleBuffer(pDoubleBuffer, (ULONG)pFileObject->SectionObjectPointer->FileSize.QuadPart); if (!NT_SUCCESS(status)) { goto Exit; } // 读取文件到缓存 status = ReadFileToBuffer(Data, FltObjects, &pDoubleBuffer->DataBuffer, &pDoubleBuffer->DataLength); if (!NT_SUCCESS(status)) { goto Exit; } // 复制数据到辅助缓存 EnterCriticalSection(&pDoubleBuffer->Lock); RtlCopyMemory(pDoubleBuffer->AuxBuffer, pDoubleBuffer->DataBuffer, pDoubleBuffer->DataLength); pDoubleBuffer->AuxLength = pDoubleBuffer->DataLength; LeaveCriticalSection(&pDoubleBuffer->Lock); // 加密缓存中的数据 status = EncryptData(pDoubleBuffer->DataBuffer, pDoubleBuffer->DataLength, g_Key, g_KeyLength); if (!NT_SUCCESS(status)) { goto Exit; } // 将双缓存设置为完成上下文 *CompletionContext = pDoubleBuffer; Exit: if (!NT_SUCCESS(status)) { if (pDoubleBuffer != NULL) { DestroyDoubleBuffer(pDoubleBuffer); ExFreePoolWithTag(pDoubleBuffer, 'Tag6'); } Data->IoStatus.Status = status; return FLT_PREOP_COMPLETE; } return FLT_PREOP_SYNCHRONIZE; } // 处理文件写入操作 FLT_POSTOP_CALLBACK_STATUS PostWriteCallback(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID CompletionContext, FLT_POST_OPERATION_FLAGS Flags) { NTSTATUS status = STATUS_SUCCESS; PFILE_OBJECT pFileObject = FltObjects->FileObject; PDOUBLE_BUFFER pDoubleBuffer = (PDOUBLE_BUFFER)CompletionContext; // 检查文件对象是否是普通文件 if ((pFileObject->Flags & FO_STREAM_FILE) != 0) { goto Exit; } // 复制数据到辅助缓存 EnterCriticalSection(&pDoubleBuffer->Lock); RtlCopyMemory(pDoubleBuffer->AuxBuffer, pDoubleBuffer->DataBuffer, pDoubleBuffer->DataLength); pDoubleBuffer->AuxLength = pDoubleBuffer->DataLength; LeaveCriticalSection(&pDoubleBuffer->Lock); // 解密辅助缓存中的数据 status = DecryptData(pDoubleBuffer->AuxBuffer, pDoubleBuffer->AuxLength, g_Key, g_KeyLength); if (!NT_SUCCESS(status)) { goto Exit; } // 写入缓存到文件 status = WriteBufferToFile(Data, FltObjects, pDoubleBuffer->AuxBuffer, pDoubleBuffer->AuxLength); if (!NT_SUCCESS(status)) { goto Exit; } Exit: if (pDoubleBuffer != NULL) { DestroyDoubleBuffer(pDoubleBuffer); ExFreePoolWithTag(pDoubleBuffer, 'Tag6'); } Data->IoStatus.Status = status; return FLT_POSTOP_FINISHED_PROCESSING; } // 注册minifilter回调 FLT_PREOP_CALLBACK_STATUS PreOperationCallback(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) { switch (Data->Iopb->MajorFunction) { case IRP_MJ_READ: return PreReadCallback(Data, FltObjects, CompletionContext); default: return FLT_PREOP_SUCCESS_WITH_CALLBACK; } } FLT_POSTOP_CALLBACK_STATUS PostOperationCallback(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID CompletionContext, FLT_POST_OPERATION_FLAGS Flags) { switch (Data->Iopb->MajorFunction) { case IRP_MJ_WRITE: return PostWriteCallback(Data, FltObjects, CompletionContext, Flags); default: return FLT_POSTOP_FINISHED_PROCESSING; } } // 注册minifilter驱动程序 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; PFLT_FILTER pFilter = NULL; OBJECT_ATTRIBUTES objAttr; UNICODE_STRING uniString; // 初始化互斥锁 InitializeCriticalSection(&g_Lock); // 初始化加密密钥 RtlInitUnicodeString(&uniString, L"Password"); status = BCryptGenerateSymmetricKey(&g_hKey, &g_Algorithm, NULL, 0, (PUCHAR)uniString.Buffer, uniString.Length, 0); if (!NT_SUCCESS(status)) { goto Exit; } // 创建过滤器 RtlInitUnicodeString(&uniString, L"FileEncryptionFilter"); InitializeObjectAttributes(&objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); status = FltCreateFilter(&g_FilterHandle, FLT_REGISTRATION_VERSION, &g_FilterRegistration, &g_FilterContext, &pFilter); if (!NT_SUCCESS(status)) { goto Exit; } // 注册回调函数 status = FltRegisterFilter(pFilter, DriverObject, &uniString, &g_FilterHandle); if (!NT_SUCCESS(status)) { goto Exit; } status = FltStartFiltering(pFilter); if (!NT_SUCCESS(status)) { goto Exit; } Exit: if (!NT_SUCCESS(status)) { if (g_hKey != NULL) { BCryptDestroyKey(g_hKey); g_hKey = NULL; } if (pFilter != NULL) { FltUnregisterFilter(pFilter); } if (g_FilterHandle != NULL) { FltClose(g_FilterHandle); } DeleteCriticalSection(&g_Lock); } return status; } // 卸载minifilter驱动程序 VOID DriverUnload(PDRIVER_OBJECT DriverObject) { PFLT_FILTER pFilter = NULL; if (g_FilterHandle != NULL) { FltGetFilterFromInstance(g_FilterHandle, &pFilter); FltStopFiltering(pFilter); FltUnregisterFilter(pFilter); FltClose(g_FilterHandle); } if (g_hKey != NULL) { BCryptDestroyKey(g_hKey); g_hKey = NULL; } DeleteCriticalSection(&g_Lock); } ``` 这只是一个简单的示例,实际实现中可能需要更多的代码来处理各种情况和错误。此外,请注意,此示例仅用于演示目的,并且未经过完整测试或优化,因此可能存在问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值