阅读:1842回复:0
急!!为什么用户模式程序不能连接到核心模式创建的端口?
代码都是参照WDK的例子写的。
用户模式代码: HANDLE port = INVALID_HANDLE_VALUE; const PWSTR PortName = L"\\Port"; HRESULT hr = FilterConnectCommunicationPort( PortName, 0, NULL, 0, NULL, &port ); if(hr != S_OK)//port == INVALID_HANDLE_VALUE) { CloseHandle(port); return ; } 核心模式代码都可以正常运行起来, 初始化代码如下: #ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(PAGE, ScannerInstanceSetup) #pragma alloc_text(PAGE, ScannerPreCreate) #pragma alloc_text(PAGE, ScannerPortConnect) #pragma alloc_text(PAGE, ScannerPortDisconnect) #pragma alloc_text(PAGE, CleanupVolumeContext) // #pragma alloc_text(PAGE, ScannerPreCleanup) // #pragma alloc_text(PAGE, ScannerQueryTeardown) // #pragma alloc_text(PAGE, ScannerUnload) #endif // // Constant FLT_REGISTRATION structure for our filter. This // initializes the callback routines our filter wants to register // for. This is only used to register with the filter manager // const FLT_OPERATION_REGISTRATION Callbacks[] = { /* { IRP_MJ_CREATE, 0, ScannerPreCreate, ScannerPostCreate}, { IRP_MJ_CLEANUP, 0, ScannerPreCleanup, NULL}, */ { IRP_MJ_READ, 0, 0,//SwapPreReadBuffers, SwapPostReadBuffers }, /* { IRP_MJ_WRITE, 0, SwapPreWriteBuffers, SwapPostWriteBuffers }, { IRP_MJ_DIRECTORY_CONTROL, 0, SwapPreDirCtrlBuffers, SwapPostDirCtrlBuffers }, */ { IRP_MJ_OPERATION_END} }; const FLT_CONTEXT_REGISTRATION ContextRegistration[] = { { FLT_VOLUME_CONTEXT, 0, CleanupVolumeContext, sizeof(VOLUME_CONTEXT), 'chBS' }, { FLT_CONTEXT_END } }; const FLT_REGISTRATION FilterRegistration = { sizeof( FLT_REGISTRATION ), // Size FLT_REGISTRATION_VERSION, // Version 0, // Flags ContextRegistration, // Context Registration. Callbacks, // Operation callbacks ScannerUnload, // FilterUnload ScannerInstanceSetup, // InstanceSetup ScannerQueryTeardown, // InstanceQueryTeardown NULL, // InstanceTeardownStart NULL, // InstanceTeardownComplete NULL, // GenerateFileName NULL, // GenerateDestinationFileName NULL // NormalizeNameComponent }; DriverEntry函数中创建通讯端口的代码如下: RtlInitUnicodeString( &uniString, PortName ); // // We secure the port so only ADMINs & SYSTEM can acecss it. // sd = (PSECURITY_DESCRIPTOR)ExAllocatePool(NonPagedPool,sizeof(SECURITY_DESCRIPTOR)); status = FltBuildDefaultSecurityDescriptor( &sd, FLT_PORT_ALL_ACCESS ); if(!NT_SUCCESS(status)) { return status; } status = RtlCreateSecurityDescriptor(sd,SECURITY_DESCRIPTOR_REVISION); // status = RtlCreateSecurityDescriptor(&sd,0); if(!NT_SUCCESS(status)) { return status; } if (status == STATUS_SUCCESS) { InitializeObjectAttributes( &oa, &uniString, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, sd ); status = FltCreateCommunicationPort( ScannerData.Filter, &ScannerData.ServerPort, &oa, NULL, ScannerPortConnect, ScannerPortDisconnect, NULL, 1 ); // // Free the security descriptor in all cases. It is not needed once // the call to FltCreateCommunicationPort() is made. // FltFreeSecurityDescriptor( sd ); if (NT_SUCCESS( status )) { // // Start filtering I/O. // status = FltStartFiltering( ScannerData.Filter ); if (NT_SUCCESS( status )) { return STATUS_SUCCESS; } FltCloseCommunicationPort( ScannerData.ServerPort ); } } 回调函数代码: NTSTATUS ScannerPortConnect ( __in PFLT_PORT ClientPort, __in_opt PVOID ServerPortCookie, __in_bcount_opt(SizeOfContext) PVOID ConnectionContext, __in ULONG SizeOfContext, __deref_out_opt PVOID *ConnectionCookie ) /*++ Routine Description This is called when user-mode connects to the server port - to establish a connection Arguments ClientPort - This is the client connection port that will be used to send messages from the filter ServerPortCookie - The context associated with this port when the minifilter created this port. ConnectionContext - Context from entity connecting to this port (most likely your user mode service) SizeofContext - Size of ConnectionContext in bytes ConnectionCookie - Context to be passed to the port disconnect routine. Return Value STATUS_SUCCESS - to accept the connection --*/ { PAGED_CODE(); UNREFERENCED_PARAMETER( ServerPortCookie ); UNREFERENCED_PARAMETER( ConnectionContext ); UNREFERENCED_PARAMETER( SizeOfContext); UNREFERENCED_PARAMETER( ConnectionCookie ); ASSERT( ScannerData.ClientPort == NULL ); ASSERT( ScannerData.UserProcess == NULL ); // // Set the user process and port. // ScannerData.UserProcess = PsGetCurrentProcess(); ScannerData.ClientPort = ClientPort; ScannerData.opr = 0; DbgPrint( "!!! --- connected, port=0x%p\n", ClientPort ); return STATUS_SUCCESS; } VOID ScannerPortDisconnect( __in_opt PVOID ConnectionCookie ) /*++ Routine Description This is called when the connection is torn-down. We use it to close our handle to the connection Arguments ConnectionCookie - Context from the port connect routine Return value None --*/ { UNREFERENCED_PARAMETER( ConnectionCookie ); PAGED_CODE(); DbgPrint( "!!! --- disconnected, port=0x%p\n", ScannerData.ClientPort ); // // Close our handle to the connection: note, since we limited max connections to 1, // another connect will not be allowed until we return from the disconnect routine. // FltCloseClientPort( ScannerData.Filter, &ScannerData.ClientPort ); // // Reset the user-process field. // ScannerData.UserProcess = NULL; } |
|
|