einsti
驱动牛犊
驱动牛犊
  • 注册日期2011-05-13
  • 最后登录2011-09-01
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望111点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1842回复:0

急!!为什么用户模式程序不能连接到核心模式创建的端口?

楼主#
更多 发布于:2011-05-13 10:56
代码都是参照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;
}

龙九
游客

返回顶部