From: amdrit on
I would appreciate any assistance you can offer.

To the quick here is my issue:

I am getting a System.AccessViolationException when attempting to read
the channel on the server side.

I am using:

//All C# 2005
//I believe i have to call VirtualChannelOpen() again eventhough I have
a pointer
//eitherway I get the same exception

IntPtr intHandle = RDPManager.WTSVirtualChannelOpen(IntPtr.Zero, -1,
"Impact");
RDPManager.WTSVirtualChannelRead(intHandle, intTimeOut, bytes,
bytes.Length, ref written);

//The API Call looks like

[DllImport("Wtsapi32.dll", SetLastError = true)]
public static extern bool WTSVirtualChannelRead(IntPtr hChannelHandle,
ulong timeout, byte[] Buffer, int Length, ref int pBytesWritten);


Here is how I got there:


Currently I am working with documentation found:
http://www.microsoft.com/technet/archive/termsrv/maintain/featusability/tsrvapi.mspx?mfr=true
http://msdn2.microsoft.com/en-us/library/aa383580.aspx
http://msdn2.microsoft.com/en-us/library/aa383853.aspx
http://www.codeproject.com/cs/system/TSAddinInCS.asp?df=100&forumid=358838&exp=0&select=1961960

That is all I can really find about the topic.

I am still having problems with WTSVirtualChannelRead, at least I think I
am. Nothing seems to be writtin.

Here is a brief overview of What I have done:

I created a messagelib that will contain messages I am sending back and
forth.

Class MessageHeader
int MessageType
MessageBase Message

Abstract Class MessageBase

Class StatusMessage: MessageBase
String StatusText


Now on my session component I do:

1. Call WTSVirtualChannelOpen to get a handle on the channel
2. Create a StatusMessage
StatusText = "ACK"
3. Serialize the message
4. Send the message

Now on my client component I do:

1. VirtualChannelEntry waits to be called (This is what loads the
assembly), store the handle in mHandle point my VirtualChannelInit to the
function VirtualChannelInitEventProc
2. Once the VirtualChannelInitEventProc determines that a complete
message was send over, I deserialize and process the message
3. Determine the type of message that was send (type == 1
//StatusMessage)
4. Determine what the StatusText is "ACK"
5. Generate a reply StatusMessage "NACK"
6. Serialize the message
7. Send the message
a. open the channel using the WTSVirtualChannelOpen(mHandle,-1,
"Impact"), store the new pointer in intTemp
b. write the data using WTSVirtualChannelWrite at this point, I
believe my data is waiting for the server to pick it up. I get a true
returned from WTSVirtualChannelWrite

Back to the session component

I have a background worker process that is monitoring for pending
messages.

1. Open the channel with WTSVirtualChannelOpen
2. Read until there is nothing left to read, add the read bytes into
list<byte> using WTSVirtualChannelRead
3. If anything was read
a. Deserialize the MessageHeader
b. Determine Message Type (type == 1//StatusMessage)
c. Report StatusText "NACK"

//At this point, nothing is read by the WTSVirtualChannelRead. I don't
know where my message is.
I am getting a System.AccessViolationException when attempting to read
the channel.

I am using:

//I believe i have to call VirtualChannelOpen() again eventhough I have
a pointer
//eitherway I get the same exception
IntPtr intHandle = RDPManager.VirtualChannelOpen(IntPtr.Zero, -1,
"Impact");
RDPManager.VirtualChannelRead(intHandle, intTimeOut, bytes,
bytes.Length, ref written);

//The API Call looks like
[DllImport("Wtsapi32.dll", SetLastError = true)]
public static extern bool WTSVirtualChannelRead(IntPtr hChannelHandle,
ulong timeout, byte[] Buffer, int Length, ref int pBytesWritten);


Does anyone have any ideas of where to start?

BTW, I am using C# 2005. But the concept should be the same.

Server: Win2K3 server with Terminal Services Installed
Client: WinXP workstation with platform SDK installed

Thanks in advance.