[英]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.