简体   繁体   English

名为 pipe 的客户端返回 ACCESS DENIED 但仅在初始成功连接后

[英]Named pipe client returns ACCESS DENIED but only after initial successful connections

I have a VB.NET process (non-service) that runs as admin and acts as the named pipe server.我有一个 VB.NET 进程(非服务),它以管理员身份运行并充当命名的 pipe 服务器。 A DLL is injected into certain processes and the DLL attempts to connect to the server process. DLL 被注入某些进程,DLL 尝试连接到服务器进程。 This is all on the same host.这都在同一台主机上。

I'm getting an ACCESS_DENIED (5) error from the client however, it only occurs after the first two clients successfully connect to the server.我从客户端收到一个 ACCESS_DENIED (5) 错误,但是它仅在前两个客户端成功连接到服务器后发生。 So, at least two can successfully connect then all other attempts are denied.因此,至少有两个可以成功连接,然后所有其他尝试都被拒绝。

In my test VM, at least 4 instances of the pipe server are created so it doesn't seem to be a simple case of a busy pipe (which I would assume return STATUS_PIPE_BUSY instead of ACCESS_DENIED anyway).在我的测试虚拟机中,至少创建了 4 个 pipe 服务器实例,因此这似乎不是一个简单的 pipe 的简单案例(我假设它返回 STATUS_PIPE_BUSY 而不是 ACCESS_DENIED )。 I've also added the most permissive pipe security I can (WorldSid/FullControl) and it still fails.我还添加了最宽松的 pipe 安全性(WorldSid/FullControl),但它仍然失败。

Here is the server pipe code:这是服务器 pipe 代码:

Private Sub PipeSetup() 
    For x = 1 To Environment.ProcessorCount  '4 in my test VM 
        t = New Thread(AddressOf PipeSetupProc)
        t.IsBackground = True
        t.Start()
    Next
End Sub

Private Sub PipeSetupProc() 
    Dim s As NamedPipeServerStream = Nothing
    Dim x As PipeSecurity = Nothing

    While True
        Try
            'I've made the access rule the most permissive possible
            'and I'm still getting ACCESS_DENIED from the client.

            x = New PipeSecurity()
            x.AddAccessRule(New PipeAccessRule(New SecurityIdentifier(WellKnownSidType.WorldSid, Nothing), 
                PipeAccessRights.FullControl, Security.AccessControl.AccessControlType.Allow))

            s = New NamedPipeServerStream(MY_PIPE_NAME, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, 
                PipeTransmissionMode.Message, PipeOptions.Asynchronous, 4096, 4096, x)
            s.WaitForConnection()

            'Do stuff here...

            s.Close()
            s = Nothing
        Catch ex As Exception
           'logerror()
        End Try
    End While
End Sub

During DLLMain(), a connection attempt is made using the following call and this is where it fails with ACCESS_DENIED.在 DLLMain() 期间,使用以下调用进行连接尝试,这就是连接失败并显示 ACCESS_DENIED 的地方。

hPipe = CreateFileW(MY_PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, 
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, 0);

Check your MY_PIPE_NAME on both sides.检查两侧的 MY_PIPE_NAME。 for c++ it should be similar to "\\.\pipe\MY_PIPE" and on vb side it is just "MY_PIPE".对于 c++,它应该类似于“\\.\pipe\MY_PIPE”,而在 vb 端它只是“MY_PIPE”。

If the data is always from vb to the dll, you can just declare a function in c++ to be called from vb (inside of an 'extern "c"').如果数据总是从 vb 到 dll,您只需在 c++ 中声明 function 以从 vb 调用(在“外部“c”内部)

_stdcall int Send2Cpp(char * msg, int length){ /*...*/}

I have a habit of defining my exports in a module.def.我有在 module.def 中定义导出的习惯。 If you don't, add the nessasary dll export terms.如果不这样做,请添加必要的 dll 导出条款。 Otherwise add a file module.def to your vs c++ project, contents否则将文件 module.def 添加到您的 vs c++ 项目,内容

LIBRARY
    EXPORTS
        Send2Cpp

Then from vb, just add然后从vb,只需添加

Public Declare Function Send2Cpp Lib "mydll.dll" (byval S as byte, byval L as integer) as integer

You can also supply a callback from vb.您还可以提供来自 vb 的回调。

Public Delegate Function GetCppString(ByVal str As IntPtr)
Function LogC(ByVal LI As IntPtr, ByVal lc As Int64) As Int64
        Dim F(lc) As Byte
        Marshal.Copy(LI, F, 0, lc)
        Debug.Print(System.Text.Encoding.ASCII.GetString(F))
End Function
'make sure these vars persist untill dll is done with pointer
'or you will get errors when they are GC'd
dim CBD as GetCppString=AddressOf(GetCppString)
dim CB_PTR as IntPtr = Marshal.GetFunctionPointerForDelegate(CBD)

Then you pas CB_PTR to a dll function, where you can call the function from their.然后你将 CB_PTR 传递给 dll function,你可以从他们那里调用 function。 In C++在 C++

typedef int(*send2vb)(char *, int);
void RegCB(send2vb f){ /*do something with function pointer*/}

In this case, add RegCB to your module.def and a declare in vb for it.在这种情况下,将 RegCB 添加到您的 module.def 并在 vb 中声明它。 Then you have bidirectional comms between dll and vb.然后你有 dll 和 vb 之间的双向通信。 (off course you'd have to wire it all together. In your dllmain, just wait for the function pointer to be non-null before sending data. PS I just mention this as it turns out to be much more efficient than pipes or similar, especially if you use functions that match your use case (in mine, it was video from a c++ dll to vb and back). (当然,您必须将它们全部连接在一起。在您的 dllmain 中,只需等待 function 指针在发送数据之前为非空。PS 我只是提到这一点,因为它比管道或类似的效率高得多,特别是如果您使用与您的用例匹配的功能(在我的情况下,它是从 c++ dll 到 vb 并返回的视频)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 创建命名管道时出现GLE = 5(访问被拒绝)错误 - Getting GLE=5 (Access Denied ) Error While creating Named Pipe Web服务无法打开命名管道-访问被拒绝 - Web service can't open named pipe - access denied 如何知道何时有最大数量的命名管道客户端服务连接? - How to know when there are maximum number of named pipe client's connections to service? 命名管道在后台等待客户端,直到客户端连接 - Named pipe wait for client in background until client connects 命名管道:ConnectNamedPipe返回ERROR_BROKEN_PIPE后的ReadFile - Named pipe: ReadFile after ConnectNamedPipe return ERROR_BROKEN_PIPE 仅在使用消息模式时,GetLastError()在调用PeekNamedPipe后返回ERROR_BROKEN_PIPE - GetLastError() returns ERROR_BROKEN_PIPE after call to PeekNamedPipe only when using message mode 命名管道CreateFile()返回INVALID_HANDLE_VALUE,GetLastError()返回ERROR_PIPE_BUSY - Named Pipe CreateFile() returns INVALID_HANDLE_VALUE, and GetLastError() returns ERROR_PIPE_BUSY 命名 pipe 上的 WriteFile 有时会返回 ERROR_NO_DATA - WriteFile on a named pipe sometimes returns ERROR_NO_DATA 使用C#服务器的命名管道客户端(C ++) - Named pipe client (c++) with c# server 名为 pipe 的客户端无法向服务器发送数据:“流不可写” - Named pipe client failed to send data to server: "Stream was not writable"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM