RDPWD!SM_Connect函数里面的RDPWD!NM_Connect函数里面的Save channel data
第一部分:
21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0689 Set state from SM_STATE_INITIALIZED to SM_STATE_NM_CONNECTING
21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0691 Connect to Network Manager
21:19:13.875 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0181 Net User Data
03 C0 2C 00 03 00 00 00 72 64 70 64 72 00 00 00 ..,.....rdpdr...
00 00 80 80 63 6C 69 70 72 64 72 00 00 00 A0 C0 ....cliprdr.....
72 64 70 73 6E 64 00 00 00 00 00 C0 rdpsnd......
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0185 Protocol version 0x80004 (0x8/0x4)
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 0 (was 0): rdpdr
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 1 (was 1): cliprdr
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 2 (was 2): rdpsnd
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0289 Attach User
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0303 AttachUser OK, hUser E88724C8
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0312 Attached as user 3ea, hUser E88724C8
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0336 Joined broadcast channel 3eb (hChannel E167E190) OK
21:19:13.906 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0356 Joined user channel (hChannel E8872614) OK
21:19:13.906 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0394 Joined VC 0: 1004 (hChannel E1189EA0)
21:19:13.906 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0394 Joined VC 1: 1005 (hChannel E167E148)
21:19:13.906 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0394 Joined VC 2: 1006 (hChannel E118F638)
21:19:13.906 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0419 Copy 3 channels to user data out
21:19:13.906 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0428 Channel 0 (0) = 0x3ec
21:19:13.921 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0428 Channel 1 (1) = 0x3ed
21:19:13.921 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0428 Channel 2 (2) = 0x3ee
21:19:13.921 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0434 Tell SM we're connecting
21:19:13.921 892767D4.E11B61D0 RDP E10C2010 SM_OnConnect 0117 Connected OK as user 3ea
第二部分:
/************************************************************************/
/* Call Network Manager */
/************************************************************************/
SM_SET_STATE(SM_STATE_NM_CONNECTING);
TRC_NRM((TB, "Connect to Network Manager"));
rc = NM_Connect(pRealSMHandle->pWDHandle->pNMInfo, pNetUserData);
if (rc != TRUE)
{
status = STATUS_CANCELLED;
DC_QUIT;
}
第三部分:
21:19:13.875 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0181 Net User Data
03 C0 2C 00 03 00 00 00 72 64 70 64 72 00 00 00 ..,.....rdpdr...
00 00 80 80 63 6C 69 70 72 64 72 00 00 00 A0 C0 ....cliprdr.....
72 64 70 73 6E 64 00 00 00 00 00 C0 rdpsnd......
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0185 Protocol version 0x80004 (0x8/0x4)
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 0 (was 0): rdpdr
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 1 (was 1): cliprdr
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 2 (was 2): rdpsnd
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0289 Attach User
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0303 AttachUser OK, hUser E88724C8
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0312 Attached as user 3ea, hUser E88724C8
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0336 Joined broadcast channel 3eb (hChannel E167E190) OK
21:19:13.906 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0356 Joined user channel (hChannel E8872614) OK
BOOL RDPCALL NM_Connect(PVOID pNMHandle, PRNS_UD_CS_NET pUserDataIn)
{
BOOL rc = FALSE;
BOOLEAN bCompleted;
MCSError MCSErr;
ChannelHandle hChannel;
PNM_HANDLE_DATA pRealNMHandle = (PNM_HANDLE_DATA)pNMHandle;
unsigned i, j;
unsigned userDataOutLength;
PRNS_UD_SC_NET pUserDataOut = NULL;
PCHANNEL_DEF pChannel;
UINT16 *pMCSChannel;
ChannelID ChID;
UINT32 DataLenValidate;
// for unalignment use purpose
UserHandle UserHandleTemp;
unsigned MaxSendSizeTemp;
DC_BEGIN_FN("NM_Connect");
/************************************************************************/
/* Clear the connection status */
/************************************************************************/
pRealNMHandle->connectStatus = 0;
/************************************************************************/
/* Save virtual channel data */
/************************************************************************/
if (pUserDataIn != NULL)
{
TRC_DATA_NRM("Net User Data",
pUserDataIn,
pUserDataIn->header.length);
TRC_NRM((TB, "Protocol version %#x (%#x/%#x)",
pRealNMHandle->pWDHandle->version,
_RNS_MAJOR_VERSION(pRealNMHandle->pWDHandle->version),
_RNS_MINOR_VERSION(pRealNMHandle->pWDHandle->version)));
/********************************************************************/
/* Protocol version 0x00080002 used 2-byte channel data lengths. */
/* Protocol version 0x00080003 and higher use 4-byte data lengths. */
/* If this is a 2-byte version, ignore its virtual channels. */
/********************************************************************/
if (_RNS_MINOR_VERSION(pRealNMHandle->pWDHandle->version) >= 3)
{
// Validate channle count
DataLenValidate = pUserDataIn->channelCount * sizeof(CHANNEL_DEF);
DataLenValidate += sizeof(RNS_UD_CS_NET);
if (DataLenValidate > pUserDataIn->header.length)
{
TRC_ERR((TB, "Error: Virtual channel data length %u too short for %u",
pUserDataIn->header.length, DataLenValidate));
pRealNMHandle->channelCount = 0;
pRealNMHandle->channelArrayCount = 0;
WDW_LogAndDisconnect(pRealNMHandle->pWDHandle, TRUE,
Log_RDP_VChannelDataTooShort, (PBYTE)pUserDataIn, pUserDataIn->header.length);
DC_QUIT;
}
// we reserve channel 7 for RDPDD so we can allow only the
// buffer size - 1 channels.
if (pUserDataIn->channelCount > sizeof(pRealNMHandle->channelData)
/ sizeof(pRealNMHandle->channelData[0]) - 1) {
TRC_ERR((TB, "Error: Too many virtual channels to join: %u.",
pUserDataIn->channelCount));
pRealNMHandle->channelCount = 0;
pRealNMHandle->channelArrayCount = 0;
WDW_LogAndDisconnect(pRealNMHandle->pWDHandle, TRUE,
Log_RDP_VChannelsTooMany, (PBYTE)pUserDataIn,
pUserDataIn->header.length);
DC_QUIT;
}
pRealNMHandle->channelCount = pUserDataIn->channelCount;
pChannel = (PCHANNEL_DEF)(pUserDataIn + 1);
for (i = 0, j = 0; i < pRealNMHandle->channelCount; i++, j++)
{
/************************************************************/
/* Channel 7 is used by RDPDD, so skip it */
/************************************************************/
if (i == WD_THINWIRE_CHANNEL)
{
j++;
}
/************************************************************/
/* Save channel data */
/************************************************************/
strncpy(pRealNMHandle->channelData[j].name,
pChannel[i].name,
CHANNEL_NAME_LEN);
// make sure that the name is zero-terminated
(pRealNMHandle->channelData[j].name)[CHANNEL_NAME_LEN] = 0;
pRealNMHandle->channelData[j].flags = pChannel[i].options;
TRC_NRM((TB, "Channel %d (was %d): %s",
j, i, pChannel[i].name));
}
pRealNMHandle->channelArrayCount = j;
}
else
{
TRC_ERR((TB,
"Minor version %#x doesn't support 4-byte channel data lengths",
_RNS_MINOR_VERSION(pRealNMHandle->pWDHandle->version)));
pRealNMHandle->channelCount = 0;
pRealNMHandle->channelArrayCount = 0;
}
}
else
{
/********************************************************************/
/* No incoming user data = no virtual channels */
/********************************************************************/
TRC_NRM((TB, "No virtual channels"));
pRealNMHandle->channelCount = 0;
pRealNMHandle->channelArrayCount = 0;
}
/************************************************************************/
/* Allocate space for returned user data */
/************************************************************************/
userDataOutLength = (sizeof(RNS_UD_SC_NET) +
(sizeof(UINT16) * pRealNMHandle->channelCount));
userDataOutLength = (unsigned)(DC_ROUND_UP_4(userDataOutLength));
pUserDataOut = COM_Malloc(userDataOutLength);
if (pUserDataOut != NULL) {
memset(pUserDataOut, 0, userDataOutLength);
}
else {
TRC_ERR((TB, "Failed to alloc %d bytes for user data",
userDataOutLength));
DC_QUIT;
}
/************************************************************************/
/* Make the attach-user request call. */
/************************************************************************/
TRC_NRM((TB, "Attach User"));
UserHandleTemp = pRealNMHandle->hUser;
MaxSendSizeTemp = pRealNMHandle->maxPDUSize;
MCSErr = MCSAttachUserRequest(pRealNMHandle->hDomain,
NM_MCSUserCallback,
SM_MCSSendDataCallback,
pNMHandle,
&UserHandleTemp,
&MaxSendSizeTemp,
(BOOLEAN *)(&bCompleted));
pRealNMHandle->hUser = UserHandleTemp;
pRealNMHandle->maxPDUSize = MaxSendSizeTemp;
if (MCSErr == MCS_NO_ERROR) {
TRC_NRM((TB, "AttachUser OK, hUser %p", pRealNMHandle->hUser));
TRC_ASSERT((bCompleted),
(TB, "MCSAttachUser didn't complete synchronously"));
// Extract extra information.
pRealNMHandle->userID = MCSGetUserIDFromHandle(pRealNMHandle->hUser);
pRealNMHandle->connectStatus |= NM_CONNECT_ATTACH;
TRC_NRM((TB, "Attached as user %x, hUser %p",
pRealNMHandle->userID, pRealNMHandle->hUser));
}
else {
TRC_ERR((TB, "Failed AttachUserRequest, MCSErr %d", MCSErr));
DC_QUIT;
}
/************************************************************************/
/* Join the broadcast channel */
/************************************************************************/
MCSErr = MCSChannelJoinRequest(pRealNMHandle->hUser,
0,
&hChannel,
&bCompleted);
if (MCSErr == MCS_NO_ERROR) {
TRC_ASSERT((bCompleted),
(TB, "MCSChannelJoin didn't complete synchronously"));
// Extract information.
ChID = MCSGetChannelIDFromHandle(hChannel);
pRealNMHandle->channelID = ChID;
pRealNMHandle->hChannel = hChannel;
pRealNMHandle->connectStatus |= NM_CONNECT_JOIN_BROADCAST;
TRC_NRM((TB, "Joined broadcast channel %x (hChannel %p) OK",
ChID, hChannel));
}
else {
TRC_ERR((TB, "Failed to send ChannelJoinRequest, MCSErr %d", MCSErr));
DC_QUIT;
}
/************************************************************************/
/* Join the user channel */
/************************************************************************/
MCSErr = MCSChannelJoinRequest(pRealNMHandle->hUser,
pRealNMHandle->userID,
&hChannel,
&bCompleted);
if (MCSErr == MCS_NO_ERROR) {
TRC_ASSERT((bCompleted),
(TB, "MCSChannelJoin didn't complete synchronously"));
// Extract information.
pRealNMHandle->connectStatus |= NM_CONNECT_JOIN_USER;
TRC_NRM((TB, "Joined user channel (hChannel %p) OK", hChannel));
}
else {
TRC_ERR((TB, "Failed to send ChannelJoinRequest, MCSErr %d", MCSErr));
DC_QUIT;
}
/************************************************************************/
/* If no virtual channels, we're done. */
/************************************************************************/
if (pRealNMHandle->channelCount == 0)
{
TRC_NRM((TB, "No virtual channels to join"));
rc = TRUE;
DC_QUIT;
}
/************************************************************************/
/* Join virtual channels */
/************************************************************************/
for (i = 0; i < pRealNMHandle->channelArrayCount; i++)
{
if (i == WD_THINWIRE_CHANNEL)
{
TRC_NRM((TB, "Skip channel %d", WD_THINWIRE_CHANNEL));
continue;
}
MCSErr = MCSChannelJoinRequest(pRealNMHandle->hUser,
0,
&hChannel,
&bCompleted);
if (MCSErr == MCS_NO_ERROR) {
TRC_ASSERT((bCompleted),
(TB, "MCSChannelJoin didn't complete synchronously"));
ChID = MCSGetChannelIDFromHandle(hChannel);
pRealNMHandle->channelData[i].MCSChannelID = (UINT16)ChID;
TRC_NRM((TB, "Joined VC %d: %d (hChannel %p)", i, ChID, hChannel));
}
else {
TRC_ERR((TB, "ChannelJoinRequest failed, MCSErr %d", MCSErr));
DC_QUIT;
}
}
/************************************************************************/
/* Everything completed OK */
/************************************************************************/
rc = TRUE;
DC_EXIT_POINT:
if (rc)
{
/********************************************************************/
/* Everything is OK - Complete the user data */
/********************************************************************/
pUserDataOut->header.type = RNS_UD_SC_NET_ID;
pUserDataOut->header.length = (UINT16)userDataOutLength;
pUserDataOut->MCSChannelID = (UINT16)pRealNMHandle->channelID;
pUserDataOut->channelCount = (UINT16)pRealNMHandle->channelCount;
pMCSChannel = (UINT16 *)(pUserDataOut + 1);
TRC_NRM((TB, "Copy %d channels to user data out",
pRealNMHandle->channelCount));
for (i = 0, j = 0; i < pRealNMHandle->channelCount; i++, j++)
{
if (i == WD_THINWIRE_CHANNEL)
{
TRC_NRM((TB, "Skip channel %d", WD_THINWIRE_CHANNEL));
j++;
}
pMCSChannel[i] = pRealNMHandle->channelData[j].MCSChannelID;
TRC_NRM((TB, "Channel %d (%d) = %#x", i, j, pMCSChannel[i]));
}
/********************************************************************/
/* Tell SM we're connected now */
/********************************************************************/
TRC_NRM((TB, "Tell SM we're connecting"));
SM_OnConnected(pRealNMHandle->pSMHandle, pRealNMHandle->userID,
NM_CB_CONN_OK, pUserDataOut, pRealNMHandle->maxPDUSize);
}
else
{
/********************************************************************/
/* Something failed - abort the connection */
/********************************************************************/
TRC_NRM((TB, "Something failed - abort the connection"));
NMAbortConnect(pRealNMHandle);
}
/************************************************************************/
/* Whether we succeeded or failed, we don't need the user data any */
/* more. */
/************************************************************************/
TRC_NRM((TB, "Free user data"));
if (pUserDataOut != NULL) {
COM_Free(pUserDataOut);
}
DC_END_FN();
return(rc);
} /* NM_Connect */
第三部分:
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 0 (was 0): rdpdr
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 1 (was 1): cliprdr
21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 2 (was 2): rdpsnd
pRealNMHandle->channelCount = pUserDataIn->channelCount;
pChannel = (PCHANNEL_DEF)(pUserDataIn + 1);
for (i = 0, j = 0; i < pRealNMHandle->channelCount; i++, j++)
{
/************************************************************/
/* Channel 7 is used by RDPDD, so skip it */
/************************************************************/
if (i == WD_THINWIRE_CHANNEL)
{
j++;
}
/************************************************************/
/* Save channel data */
/************************************************************/
strncpy(pRealNMHandle->channelData[j].name,
pChannel[i].name,
CHANNEL_NAME_LEN);
// make sure that the name is zero-terminated
(pRealNMHandle->channelData[j].name)[CHANNEL_NAME_LEN] = 0;
pRealNMHandle->channelData[j].flags = pChannel[i].options;
TRC_NRM((TB, "Channel %d (was %d): %s",
j, i, pChannel[i].name));
}
pRealNMHandle->channelArrayCount = j;
}
1: kd> dt tagNM_HANDLE_DATA e116ee30
RDPWD!tagNM_HANDLE_DATA
+0x000 pSMHandle : 0xe116e7c8 Void
+0x004 pWDHandle : 0xe116e010 tagTSHARE_WD
+0x008 pContext : 0x895b736c _SDCONTEXT
+0x00c hUser : (null)
+0x010 channelID : 0
+0x014 hChannel : (null)
+0x018 hDomain : 0xe1143540 Void
+0x01c connectStatus : 0
+0x020 userID : 0
+0x024 maxPDUSize : 0
+0x028 dead : 0n0
+0x02c channelCount : 3
+0x030 channelArrayCount : 3
+0x034 channelData : [32] tagNM_CHANNEL_DATA
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!tagNM_CHANNEL_DATA (*)[32])0xe116ee64))
(*((RDPWD!tagNM_CHANNEL_DATA (*)[32])0xe116ee64)) [Type: tagNM_CHANNEL_DATA [32]]
0\] \[Type: tagNM_CHANNEL_DATA
1\] \[Type: tagNM_CHANNEL_DATA
2\] \[Type: tagNM_CHANNEL_DATA
3\] \[Type: tagNM_CHANNEL_DATA
30\] \[Type: tagNM_CHANNEL_DATA
31\] \[Type: tagNM_CHANNEL_DATA
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!tagNM_CHANNEL_DATA *)0xe116ee64))
(*((RDPWD!tagNM_CHANNEL_DATA *)0xe116ee64)) [Type: tagNM_CHANNEL_DATA]
+0x000\] name : "rdpdr" \[Type: char \[8\]
+0x008\] MCSChannelID : 0x0 \[Type: unsigned short
+0x00c\] flags : 0x80800000 \[Type: unsigned long
+0x010\] pData : 0x0 \[Type: unsigned char \*
+0x014\] pNext : 0x0 \[Type: unsigned char \*
+0x018\] dataLength : 0x0 \[Type: unsigned int
+0x01c\] lengthSoFar : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!tagNM_CHANNEL_DATA *)0xe116ee84))
(*((RDPWD!tagNM_CHANNEL_DATA *)0xe116ee84)) [Type: tagNM_CHANNEL_DATA]
+0x000\] name : "cliprdr" \[Type: char \[8\]
+0x008\] MCSChannelID : 0x0 \[Type: unsigned short
+0x00c\] flags : 0xc0a00000 \[Type: unsigned long
+0x010\] pData : 0x0 \[Type: unsigned char \*
+0x014\] pNext : 0x0 \[Type: unsigned char \*
+0x018\] dataLength : 0x0 \[Type: unsigned int
+0x01c\] lengthSoFar : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!tagNM_CHANNEL_DATA *)0xe116eea4))
(*((RDPWD!tagNM_CHANNEL_DATA *)0xe116eea4)) [Type: tagNM_CHANNEL_DATA]
+0x000\] name : "rdpsnd" \[Type: char \[8\]
+0x008\] MCSChannelID : 0x0 \[Type: unsigned short
+0x00c\] flags : 0xc0000000 \[Type: unsigned long
+0x010\] pData : 0x0 \[Type: unsigned char \*
+0x014\] pNext : 0x0 \[Type: unsigned char \*
+0x018\] dataLength : 0x0 \[Type: unsigned int
+0x01c\] lengthSoFar : 0x0 \[Type: unsigned int