为什么我不能使用“WTSVirtualChannelQuery”返回的句柄?
Why can I not use the handle returned by `WTSVirtualChannelQuery`?
试图利用 RDP 动态虚拟通道。我将 WTSVirtualChannelQuery
和 WTSVirtualFileHandle
的结果传递给 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
后立即失效。在调用 WTSFreeMemory
之前调用 DuplicateHandle
并使用重复的句柄。
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);
}
试图利用 RDP 动态虚拟通道。我将 WTSVirtualChannelQuery
和 WTSVirtualFileHandle
的结果传递给 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
后立即失效。在调用 WTSFreeMemory
之前调用 DuplicateHandle
并使用重复的句柄。
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);
}