c# - 为什么我不能使用 `WTSVirtualChannelQuery` 返回的句柄?
问题描述
试图利用 RDP 动态虚拟通道。我将WTSVirtualChannelQuery
with的结果传递WTSVirtualFileHandle
给 a FileStream
,但它会引发各种异常。为什么?
称呼:
public static FileStream Open(string channelName, WTS_CHANNEL_OPTION option = WTS_CHANNEL_OPTION.DYNAMIC)
{
// Open
SafeFileHandle pFile = null;
using (var sfh = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, channelName, option))
{
WtsAllocSafeHandle pBuffer = null;
try
{
int cbReturned;
if (!WTSVirtualChannelQuery(sfh, WTS_VIRTUAL_CLASS.FileHandle, out pBuffer, out cbReturned)
|| cbReturned < IntPtr.Size)
{
throw new Win32Exception();
}
pFile = new SafeFileHandle(Marshal.ReadIntPtr(pBuffer.DangerousGetHandle()), false);
}
finally
{
pBuffer?.Dispose();
}
}
// create
return new FileStream(pFile, FileAccess.ReadWrite, bufferSize: 32 * 1024 * 1024, isAsync: true);
}
例外:
System.ArgumentException: Handle does not support asynchronous operations. The parameters to the FileStream constructor may need to be changed to indicate that the handle was opened synchronously (that is, it was not opened for overlapped I/O).
at System.IO.FileStream..ctor(SafeFileHandle handle, FileAccess access, Int32 bufferSize, Boolean isAsync)
和
System.IO.IOException: The handle is invalid.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.VerifyHandleIsSync()
at System.IO.FileStream..ctor(SafeFileHandle handle, FileAccess access, Int32 bufferSize, Boolean isAsync)
解决方案
返回的句柄WTSVirtualChannelQuery
似乎一WTSFreeMemory
被调用就失效了。在调用DuplicateHandle
之前调用WTSFreeMemory
并使用重复的句柄。
public static FileStream Open(string channelName, WTS_CHANNEL_OPTION option = WTS_CHANNEL_OPTION.DYNAMIC)
{
// Open
SafeFileHandle pFile = null;
using (var sfh = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, channelName, option))
{
WtsAllocSafeHandle pBuffer = null;
try
{
int cbReturned;
if (!WTSVirtualChannelQuery(sfh, WTS_VIRTUAL_CLASS.FileHandle, out pBuffer, out cbReturned)
|| cbReturned < IntPtr.Size)
{
throw new Win32Exception();
}
var pWtsFile = Marshal.ReadIntPtr(pBuffer.DangerousGetHandle());
if (!DuplicateHandle(
GetCurrentProcess(), pWtsFile,
GetCurrentProcess(), out pFile,
0, false, DUPLICATE_SAME_ACCESS))
{
throw new Win32Exception();
}
}
finally
{
pBuffer?.Dispose();
}
}
// create
return new FileStream(pFile, FileAccess.ReadWrite, bufferSize: 32 * 1024 * 1024, isAsync: true);
}
推荐阅读
- arrays - 拆分 pyspark 数据框中的 Array 列
- amazon-web-services - AWS 负载均衡器返回 403 响应?
- ruby - 如何在 Rspec 测试期间关闭 TCP 服务器?
- postgresql - postgresql - 根据当前时间选择记录
- amazon-dynamodb - 过滤器表达式中的 dynamodb AND 条件
- python - 犰狳 3D 网格的未完成渲染图像
- android - 点击选项卡导航器图标的监听器不起作用
- node.js - 使用 ssh 上传文件
- c - 将 DLL 与 C 程序正确捆绑
- javascript - Bot 将反应用户分配给 Discord 中的角色