MCSConnectProviderResponse函数分析调试记录和调试记录详细版对比

第-1部分:分析的源码

分析1:

/****************************************************************************/

// WD_Ioctl

//

// Query/Set configuration information for the WD.

/****************************************************************************/

NTSTATUS WD_Ioctl(PTSHARE_WD pTSWd, PSD_IOCTL pSdIoctl)

{

NTSTATUS status = STATUS_SUCCESS;

UINT32 bufferLen;

unsigned fn;

PVIDEO_MODE_INFORMATION pVidInfo;

DC_BEGIN_FN("WD_Ioctl");

分析2:

else {

// Non-perf path IOCTLs.

fn = WDW_IOCTL_FUNCTION(pSdIoctl->IoControlCode);

TRC_NRM((TB, "%s (%d)",

fn == 6 ? "IOCTL_VIDEO_ENUM_MONITOR_PDO" :

fn < 49 ? wdIoctlA[fn] :

fn < 50 ? "Unknown Ioctl" :

fn < 77 ? wdIoctlB[fn - 50] :

fn < 0x100 ? "Unknown Ioctl" :

fn < 0x11f ? wdIoctlC[fn - 0x100] :

fn < 0x200 ? "Unknown Ioctl" :

fn < 0x204 ? wdIoctlD[fn - 0x200] :

fn == 0x300 ? "IOCTL_MOUSE_ICA_INPUT" :

fn < 0x400 ? "Unknown Ioctl" :

fn < 0x412 ? wdIoctlE[fn - 0x400] :

fn == 0x500 ? "IOCTL_T120_REQUEST" : //需要选择这一行

fn < 0x510 ? "Unknown Ioctl" :

fn < 0x520 ? wdIoctlTsh[fn - 0x510] :

fn == 0x900 ? "IOCTL_TSHARE_CONF_CONNECT" :

fn == 0x901 ? "IOCTL_TSHARE_CONF_DISCONNECT" :

fn == 0x903 ? "IOCTL_TSHARE_USER_LOGON" :

fn == 0x904 ? "IOCTL_TSHARE_GET_SEC_DATA" :

fn == 0x905 ? "IOCTL_TSHARE_SET_SEC_DATA" :

fn == 0x906 ? "IOCTL_TSHARE_SET_NO_ENCRYPT" :

fn == 0x907 ? "IOCTL_TSHARE_QUERY_CHANNELS" :

fn == 0x908 ? "IOCTL_TSHARE_CONSOLE_CONNECT" :

fn == 0x909 ? "IOCTL_TSHARE_SEND_CERT_DATA" :

fn == 0x90A ? "IOCTL_TSHARE_GET_CERT_DATA" :

fn == 0x90B ? "IOCTL_TSHARE_SEND_CLIENT_RANDOM" :

fn == 0x90C ? "IOCTL_TSHARE_GET_CLIENT_RANDOM" :

fn == 0x90D ? "IOCTL_TSHARE_SHADOW_CONNECT" :

fn == 0x90E ? "IOCTL_TSHARE_SET_ERROR_INFO" :

"Unknown Ioctl",

fn));

}

分析3:

switch ( pSdIoctl->IoControlCode ) {

/********************************************************************/

/* T.120 request from user mode - pass it on */

/********************************************************************/

case IOCTL_T120_REQUEST:

{

status = MCSIcaT120Request(pTSWd->hDomainKernel, pSdIoctl);

}

break;

第0部分:

20:33:22.171 89C6060C.E18BA820 GCC: GCCConferenceCreateResponse entry
20:33:22.171 89C6060C.E18BA820 GCC: gccEncodeUserData entry
20:33:22.171 89C6060C.E18BA820 GCC: gccEncodeUserData exit - 0x0
20:33:22.171 89C6060C.E18BA820 GCC: Calling MCSConnectProviderResponse - hDomain 0xd737a8, result 0x0, pUserData 0xd73318, UserDataLength 0x11b

Breakpoint 20 hit

RDPWD!SendOutBuf:

b975a0d2 55 push ebp

0: kd> kc

00 RDPWD!SendOutBuf
01 RDPWD!ConnectProviderResponseFunc
02 RDPWD!MCSIcaT120Request
03 RDPWD!WD_Ioctl

04 termdd!_IcaCallSd

05 termdd!_IcaCallStack

06 termdd!IcaDeviceControlStack

07 termdd!IcaDeviceControl

08 termdd!IcaDispatch

09 nt!IofCallDriver

0a nt!IopSynchronousServiceTail

0b nt!IopXxxControlFile

0c nt!NtDeviceIoControlFile

0d nt!_KiSystemService

0e SharedUserData!SystemCallStub

0f ntdll!NtDeviceIoControlFile

10 ICAAPI!IcaIoControl

11 ICAAPI!_IcaStackIoControlWorker

12 ICAAPI!IcaStackIoControl
13 rdpwsx!SendConnectProviderResponse
14 rdpwsx!MCSConnectProviderResponse
15 rdpwsx!GCCConferenceCreateResponse

16 rdpwsx!TSrvConfCreateResp

17 rdpwsx!TSrvDoConnectResponse

18 rdpwsx!TSrvDoConnect

19 rdpwsx!TSrvStackConnect

1a rdpwsx!WsxIcaStackIoControl

1b termsrv!WsxStackIoControl

1c ICAAPI!_IcaStackIoControl

1d ICAAPI!_IcaStackWaitForIca

1e ICAAPI!IcaStackConnectionAccept

1f termsrv!TransferConnectionToIdleWinStation

20 termsrv!WinStationTransferThread

21 kernel32!BaseThreadStart

0: kd> g

20:33:22.171 89C6060C.E18BA820 TermDD: IcaDeviceControlStack, fc 1280, 0x0

Breakpoint 20 hit

RDPWD!SendOutBuf:

b975a0d2 55 push ebp

0: kd> kc

00 RDPWD!SendOutBuf

01 RDPWD!HandleAttachUserReq

02 RDPWD!RecognizeMCSFrame

03 RDPWD!MCSIcaRawInput

04 termdd!IcaRawInput

05 TDTCP!TdInputThread

06 termdd!_IcaDriverThread

07 nt!PspSystemThreadStartup

08 nt!KiThreadStartup

0: kd> g

20:33:22.171 89C6060C.E18BA820 GCC: MCSConnectProviderResponse - MCSError 0x0 (MCS_NO_ERROR)

20:33:22.171 89C6060C.E18BA820 GCC: gccMapMcsError: mcsError 0x0 (MCS_NO_ERROR), gbbError 0x0 (GCC_NO_ERROR)

GCCError

APIENTRY

GCCConferenceCreateResponse(GCCNumericString conference_modifier,

DomainHandle hDomain,

T120Boolean use_password_in_the_clear,

DomainParameters *domain_parameters,

USHORT number_of_network_addresses,

GCCNetworkAddress **local_network_address_list,

USHORT number_of_user_data_members,

GCCUserData **user_data_list,

GCCResult result)

{

MCSError mcsError;

GCCError gccError;

PBYTE pUserData;

UINT UserDataLength;

TRACE((DEBUG_GCC_DBFLOW,
"GCC: GCCConferenceCreateResponse entry\n"));

if (gccIsInitialized(&gccError))

{

mcsError = gccEncodeUserData(number_of_user_data_members,

user_data_list,

&pUserData,

&UserDataLength);

if (mcsError == MCS_NO_ERROR)

{
TRACE((DEBUG_GCC_DBDEBUG,
"GCC: Calling MCSConnectProviderResponse - hDomain 0x%x, result 0x%x, "
"pUserData 0x%x, UserDataLength 0x%x\n",
hDomain, result, pUserData, UserDataLength));

TS_ASSERT(hDomain);

mcsError = MCSConnectProviderResponse(hDomain, result, pUserData, UserDataLength);

gccDumpMCSErrorDetails(mcsError,

"MCSConnectProviderResponse");

if (pUserData)

TShareFree(pUserData);

}

gccError = gccMapMcsError(mcsError);

}

TRACE((DEBUG_GCC_DBFLOW,
"GCC: GCCConferenceCreateResponse exit - 0x%x\n",
gccError));

return (gccError);

}

第一部分:

21:19:13.937 892767D4.E11B61D0 GCC: GCCConferenceCreateResponse entry

21:19:13.937 892767D4.E11B61D0 GCC: gccEncodeUserData entry

21:19:13.937 892767D4.E11B61D0 GCC: gccEncodeUserData exit - 0x0

21:19:13.937 892767D4.E11B61D0 GCC: Calling MCSConnectProviderResponse - hDomain 0xd75c98, result 0x0, pUserData 0xd73318, UserDataLength 0x11b

21:19:13.937 892767D4.E11B61D0 TermDD: IcaDeviceControlStack, fc 1280 (enter)
21:19:13.937 892767D4.E11B61D0 RDP E10C2010 WD_Ioctl 0489 IOCTL_T120_REQUEST (1280) //重点关注这一行

21:19:13.937 892767D4.E11B61D0 TermDD: IcaBufferAlloc: 0x892c6bf8, Status=0x0

21:19:13.937 892767D4.E11B61D0 TermDD: IcaCallNextDriver, ProcIndex=2 (enter)
21:19:13.937 892767D4.E11B61D0 TdRawWrite 0333, 892c6bf8

21:19:13.937 892767D4.E11B61D0 TermDD: IcaDeviceControlStack, fc 1280, 0x0

21:19:13.937 89DD11FC.00000000 _TdWriteCompleteWorker: 892c6bf8

21:19:13.953 89DD11FC.00000000 TermDD: IcaBufferFree: 0x892c6bf8

21:19:13.953 892767D4.E11B61D0 GCC: MCSConnectProviderResponse - MCSError 0x0 (MCS_NO_ERROR)

21:19:13.953 892767D4.E11B61D0 GCC: gccMapMcsError: mcsError 0x0 (MCS_NO_ERROR), gbbError 0x0 (GCC_NO_ERROR)
21:19:13.953 892767D4.E11B61D0 GCC: GCCConferenceCreateResponse exit - 0x0

第二部分:

下面是这一行的解释:

21:19:13.937 892767D4.E11B61D0 RDP E10C2010 WD_Ioctl 0489 IOCTL_T120_REQUEST (1280)

/*

* T.120 IOCTLs.

*/

#define IOCTL_T120_BASE (0x500) 0x500=0n1280

// Used by MCSMUX to signal on a stack IOCTL that the included data is an MCS

// request/response. An MCSXxxYyyIoctl struct is expected as the

// pSdIoctl->InputBuffer; the Header.Type value in the struct will be used

// to determine the type of the request.

#define IOCTL_T120_REQUEST _ICA_CTL_CODE (IOCTL_T120_BASE, METHOD_NEITHER)

}

else {

// Non-perf path IOCTLs.

fn = WDW_IOCTL_FUNCTION(pSdIoctl->IoControlCode);

TRC_NRM((TB, "%s (%d)",

fn == 6 ? "IOCTL_VIDEO_ENUM_MONITOR_PDO" :

fn < 49 ? wdIoctlA[fn] :

fn < 50 ? "Unknown Ioctl" :

fn < 77 ? wdIoctlB[fn - 50] :

fn < 0x100 ? "Unknown Ioctl" :

fn < 0x11f ? wdIoctlC[fn - 0x100] :

fn < 0x200 ? "Unknown Ioctl" :

fn < 0x204 ? wdIoctlD[fn - 0x200] :

fn == 0x300 ? "IOCTL_MOUSE_ICA_INPUT" :

fn < 0x400 ? "Unknown Ioctl" :

fn < 0x412 ? wdIoctlE[fn - 0x400] :

fn == 0x500 ? "IOCTL_T120_REQUEST" : //对应这一行!!!

fn < 0x510 ? "Unknown Ioctl" :

fn < 0x520 ? wdIoctlTsh[fn - 0x510] :

fn == 0x900 ? "IOCTL_TSHARE_CONF_CONNECT" :

fn == 0x901 ? "IOCTL_TSHARE_CONF_DISCONNECT" :

fn == 0x903 ? "IOCTL_TSHARE_USER_LOGON" :

fn == 0x904 ? "IOCTL_TSHARE_GET_SEC_DATA" :

fn == 0x905 ? "IOCTL_TSHARE_SET_SEC_DATA" :

fn == 0x906 ? "IOCTL_TSHARE_SET_NO_ENCRYPT" :

fn == 0x907 ? "IOCTL_TSHARE_QUERY_CHANNELS" :

fn == 0x908 ? "IOCTL_TSHARE_CONSOLE_CONNECT" :

fn == 0x909 ? "IOCTL_TSHARE_SEND_CERT_DATA" :

fn == 0x90A ? "IOCTL_TSHARE_GET_CERT_DATA" :

fn == 0x90B ? "IOCTL_TSHARE_SEND_CLIENT_RANDOM" :

fn == 0x90C ? "IOCTL_TSHARE_GET_CLIENT_RANDOM" :

fn == 0x90D ? "IOCTL_TSHARE_SHADOW_CONNECT" :

fn == 0x90E ? "IOCTL_TSHARE_SET_ERROR_INFO" :

"Unknown Ioctl",

fn));

} //文件中的489行

第三部分:

/*

* Callout from WD upon reception of a IOCTL_T120_REQUEST, i.e. a user-mode

* ioctl.

*/

NTSTATUS MCSIcaT120Request(DomainHandle hDomain, PSD_IOCTL pSdIoctl)

{

Domain *pDomain;

IoctlHeader *pHeader;

pDomain = (Domain *)hDomain;

// Get the request type.

ASSERT(pSdIoctl->InputBufferLength >= sizeof(IoctlHeader));

pHeader = (IoctlHeader *)pSdIoctl->InputBuffer;

// Make sure request within bounds.

if (pHeader->Type < MCS_ATTACH_USER_REQUEST ||

pHeader->Type > MCS_T120_START) {

ErrOut(pDomain->pContext, "Invalid IOCTL_T120_REQUEST type");

return STATUS_INVALID_DEVICE_REQUEST;

}

// Check that request is supported.

if (g_T120RequestDispatch[pHeader->Type] == NULL) {

ErrOut(pDomain->pContext, "IOCTL_T120_REQUEST type unsupported");

return STATUS_INVALID_DEVICE_REQUEST;

}

// Make the call. The entry points are defined in MCSIoctl.c.
return (g_T120RequestDispatch[pHeader->Type])(pDomain, pSdIoctl);

}

/*

* Globals

*/

// Table of function entry points for ChannelWrite() request calls.

// These entry points correspond to request defines in MCSIOCTL.h.

// NULL means unsupported, which will be handled by dispatch code in

// PdChannelWrite() in PDAPI.c.

const PT120RequestFunc g_T120RequestDispatch[] =

{

AttachUserRequestFunc,

DetachUserRequestFunc,

ChannelJoinRequestFunc,

ChannelLeaveRequestFunc,

SendDataRequestFunc, // Handles both uniform and regular.

SendDataRequestFunc, // Handles both uniform and regular.

NULL, // MCS_CHANNEL_CONVENE_REQUEST unsupported.

NULL, // MCS_CHANNEL_DISBAND_REQUEST unsupported.

NULL, // MCS_CHANNEL_ADMIT_REQUEST unsupported.

NULL, // MCS_CHANNEL_EXPEL_REQUEST unsupported.

NULL, // MCS_TOKEN_GRAB_REQUEST unsupported.

NULL, // MCS_TOKEN_INHIBIT_REQUEST unsupported.

NULL, // MCS_TOKEN_GIVE_REQUEST unsupported.

NULL, // MCS_TOKEN_GIVE_RESPONSE unsupported.

NULL, // MCS_TOKEN_PLEASE_REQUEST unsupported.

NULL, // MCS_TOKEN_RELEASE_REQUEST unsupported.

NULL, // MCS_TOKEN_TEST_REQUEST unsupported.

NULL, // MCS_CONNECT_PROVIDER_REQUEST unsupported.
ConnectProviderResponseFunc,

DisconnectProviderRequestFunc,

T120StartFunc,

};

参考:调用栈

Breakpoint 20 hit

RDPWD!SendOutBuf:

b975a0d2 55 push ebp

0: kd> kc

00 RDPWD!SendOutBuf

01 RDPWD!ConnectProviderResponseFunc

02 RDPWD!MCSIcaT120Request

03 RDPWD!WD_Ioctl

参考:调用栈 上一次是用的T120StartFunc

第四部分:

/*

* Connect provider response - ChannelWrite() request. Requires filler bytes

* in MCSConnectProviderResponseIoctl to make sure we use at least 54 bytes

* for the struct so we can reuse the OutBuf here. User data must start

* at (pSdIoctl->pBuffer + sizeof(MCSConnectProviderResponseIoctl)).

*/

NTSTATUS ConnectProviderResponseFunc(

PDomain pDomain,

PSD_IOCTL pSdIoctl)

{

POUTBUF pOutBuf;

NTSTATUS Status;

ConnectProviderResponseIoctl *pCPrs;

ASSERT(pSdIoctl->InputBufferLength ==

sizeof(ConnectProviderResponseIoctl));

pCPrs = (ConnectProviderResponseIoctl *)pSdIoctl->InputBuffer;

ASSERT(pCPrs->Header.Type == MCS_CONNECT_PROVIDER_RESPONSE);

// Verify that we are actually waiting for a CP response.

if (pDomain->State != State_ConnectProvIndPending) {

ErrOut(pDomain->pContext, "Connect-provider response call received, "

"we are in wrong state, ignoring");

return STATUS_INVALID_DOMAIN_STATE;

}

// Alloc OutBuf for sending PDU.

// This allocation is vital to the session and must succeed.

do {
Status = IcaBufferAlloc(pDomain->pContext, FALSE, TRUE,
ConnectResponseHeaderSize + pCPrs->UserDataLength, NULL,
&pOutBuf);

if (Status != STATUS_SUCCESS)

ErrOut(pDomain->pContext, "Could not allocate an OutBuf for a "

"connect-response PDU, retrying");

} while (Status != STATUS_SUCCESS);

// Encode PDU header. Param 2, the called connect ID, does not need to be

// anything special because we do not allow extra sockets to be opened

// for other data priorities.

CreateConnectResponseHeader(pDomain->pContext, pCPrs->Result, 0,

&pDomain->DomParams, pCPrs->UserDataLength, pOutBuf->pBuffer,

&pOutBuf->ByteCount);

// Copy the user data after the header.

RtlCopyMemory(pOutBuf->pBuffer + pOutBuf->ByteCount, pCPrs->pUserData,

pCPrs->UserDataLength);

pOutBuf->ByteCount += pCPrs->UserDataLength;

// Send the new PDU OutBuf down to the TD for sending out.

//MCS FUTURE: Needs to change for multiple connections.
Status = SendOutBuf(pDomain, pOutBuf);

if (!NT_SUCCESS(Status)) {

ErrOut(pDomain->pContext, "Could not send connect-response PDU OutBuf "

"to TD");

// Ignore errors here -- this should only occur if stack is going down.

return Status;

}

// Transition state depending on Result.

if (pCPrs->Result == RESULT_SUCCESSFUL) {

pDomain->State = State_MCS_Connected;

}

else {

TraceOut(pDomain->pContext, "ConnectProviderRespFunc(): Node "

"controller returned error in response, destroying call "

"data");

pDomain->State = State_Disconnected;

// Detach any users that attached during domain setup.

DisconnectProvider(pDomain, TRUE, REASON_PROVIDER_INITIATED);

}

return STATUS_SUCCESS;

}

NTSTATUS IcaBufferAlloc(

IN PSDCONTEXT pContext,

IN BOOLEAN fWait,

IN BOOLEAN fControl,

IN ULONG ByteCount,

IN POUTBUF pOutBufOrig,

OUT POUTBUF *ppOutBuf)

{

PSDLINK pSdLink;

PICA_STACK pStack;

NTSTATUS Status;

/*

* Use SD passed context to get the SDLINK pointer.

*/

pSdLink = CONTAINING_RECORD(pContext, SDLINK, SdContext);

pStack = pSdLink->pStack;

ASSERT(pSdLink->pStack->Header.Type == IcaType_Stack);

ASSERT(pSdLink->pStack->Header.pDispatchTable == IcaStackDispatchTable);

ASSERT(ExIsResourceAcquiredExclusiveLite( &pStack->Resource));

/*

* Walk up the SDLINK list looking for a driver which has specified

* a BufferAlloc callup routine. If we find one, then call the

* driver BufferAlloc routine to let it handle the call.

*/

while ((pSdLink = IcaGetPreviousSdLink(pSdLink)) != NULL) {

ASSERT( pSdLink->pStack == pStack );

if (pSdLink->SdContext.pCallup->pSdBufferAlloc) {

IcaReferenceSdLink(pSdLink);

Status = (pSdLink->SdContext.pCallup->pSdBufferAlloc)(

pSdLink->SdContext.pContext,

fWait,

fControl,

ByteCount,

pOutBufOrig,

ppOutBuf);

IcaDereferenceSdLink(pSdLink);

return Status;

}

}

/*

* We didn't find a callup routine to handle the request,

* so we'll process it here.

*/

Status = IcaBufferAllocInternal(pContext, fWait, fControl, ByteCount,

pOutBufOrig, ppOutBuf);

TRACESTACK((pStack, TC_ICADD, TT_API3,
"TermDD: IcaBufferAlloc: 0x%08x, Status=0x%x\n", *ppOutBuf,
Status));

return Status;

}

21:19:13.937 892767D4.E11B61D0 TermDD: IcaBufferAlloc: 0x892c6bf8, Status=0x0

第五部分:

void CreateConnectResponseHeader(

PSDCONTEXT pContext, // For tracing.

MCSResult Result,

int CalledConnectID,

DomainParameters *pDomParams,

unsigned UserDataLength,

BYTE *pBuffer,

unsigned *pNBytesConsumed)

{

BYTE *OutFrame, *newFrame;

unsigned NBytesConsumed, TotalSize, EncodeLength;

// Set up for creating the PDU.

OutFrame = pBuffer + X224_DataHeaderSize;

NBytesConsumed = 0;

// Encode the BER prefix, PDU type, and leave space for the PDU length.

// Note that the length is the number of bytes following this length

// indicator.

// The most-oft-encountered case is where the PDU length is less than 128

// bytes. So, special-case larger sizes at the end of the function

// when we know the total size.

OutFrame[0] = MCS_CONNECT_PDU;

OutFrame[1] = MCS_CONNECT_RESPONSE_ENUM;

// Skip OutFrame[2] for the default 1-byte (<= 128) size.

OutFrame += 3;

TotalSize = 3;

// Encode Result, CalledConnectID, DomParams. We use OutFrame

// as a current pointer.

EncodeTagBER(pContext, OutFrame, TagType_Enumeration, 0, Result,

&NBytesConsumed, &newFrame);

TotalSize += NBytesConsumed;

OutFrame = newFrame;

EncodeTagBER(pContext, OutFrame, TagType_Integer, 0, CalledConnectID,

&NBytesConsumed, &newFrame);

TotalSize += NBytesConsumed;

OutFrame = newFrame;

EncodeDomainParameters(pContext, OutFrame, &NBytesConsumed, pDomParams,

&newFrame);

TotalSize += NBytesConsumed;

OutFrame = newFrame;

// Encode only the length bytes, not the user data body.

EncodeTagBER(pContext, OutFrame, TagType_OctetString, UserDataLength,

(UINT_PTR)NULL, &NBytesConsumed, &newFrame);

TotalSize += NBytesConsumed;

OutFrame = newFrame;

// Encode the final size. Here we special-case a too-large size by

// shifting data around. The large size is the exceptional case.

EncodeLength = TotalSize - 3 + UserDataLength;

if (EncodeLength < 128) {

pBuffer[2 + X224_DataHeaderSize] = (BYTE)EncodeLength;

}

else {

unsigned i, Len = 0;

WarnOut(pContext, "CreateConnRespHeader(): Perf hit from too-large "

"PDU size");

// Since we can only send up to 64K bytes, the length determinant

// cannot be any more than 3 bytes long.

ASSERT(EncodeLength < 65535);

if (EncodeLength < 0x8000)

Len = 2;

else if (EncodeLength < 0x800000)

Len = 3;

else

ASSERT(FALSE);

// Size escape comes first.

pBuffer[2 + X224_DataHeaderSize] = LengthModifier_2 + Len - 2;

RtlMoveMemory(pBuffer + 3 + X224_DataHeaderSize + Len,

pBuffer + 3 + X224_DataHeaderSize, EncodeLength - 3);

for (i = 1; i <= Len; i++) {

pBuffer[3 + X224_DataHeaderSize + Len - i] = (BYTE)EncodeLength;

EncodeLength >>= 8;

}

// We already included one byte of the length encoding above, but

// now we need to also skip the length escape and the encoded length.

TotalSize += Len;

}

// Set up X224 header based on the final size of the packet.

CreateX224DataHeader(pBuffer, TotalSize + UserDataLength, TRUE);

*pNBytesConsumed = X224_DataHeaderSize + TotalSize;

}

第六部分:从TDTCP!TdRawWrite函数到tcpip!TCPSendData函数

D:\123>grep "TdRawWrite" -nr D:\srv03rtm\termsrv

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/asmapi.c:879: // 254514 STRESS: TS: Tdtcp!TdRawWrite needs synchronization with the write complete routine

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:53:NTSTATUS TdRawWrite( PTD, PSD_RAWWRITE );

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:110: TdRawWrite,

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:394: * TdRawWrite

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:413:NTSTATUS TdRawWrite(PTD pTd, PSD_RAWWRITE pSdRawWrite)

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:454: "TdRawWrite : No memory to allocate WorkItem. Removing Outbuf from the list %04u, %p\n",

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:485: "TdRawWrite %04u, %08x\n",

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:513: "TdRawWrite: WriteErrorThreshold exceeded\n"));

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:519: TRACE((pTd->pContext, TC_TD, TT_API2, "TdRawWrite: closing\n"));

D:\srv03rtm\termsrv/drivers/td/common/tdapi.c:542: TRACE(( pTd->pContext, TC_TD, TT_OUT1, "TdRawWrite, Status=0x%x\n", Status ));

D:\srv03rtm\termsrv/drivers/termdd/buffer.c:15: * (This size will be checked by the TdRawWrite routine.)

参考:

21:56:30.609 89617F7C.E192A9F8 GCC: GCCConferenceCreateResponse entry

21:56:30.609 89617F7C.E192A9F8 GCC: gccEncodeUserData entry

21:56:30.609 89617F7C.E192A9F8 GCC: gccEncodeUserData exit - 0x0

21:56:30.609 89617F7C.E192A9F8 GCC: Calling MCSConnectProviderResponse - hDomain 0xd63f88, result 0x0, pUserData 0xd635e0, UserDataLength 0x11b

21:56:30.609 89617F7C.E192A9F8 TermDD: IcaDeviceControlStack, fc 1280 (enter)

21:56:30.609 89617F7C.E192A9F8 RDP E1026010 WD_Ioctl 0489 IOCTL_T120_REQUEST (1280)

21:56:30.609 89617F7C.E192A9F8 TermDD: IcaBufferAlloc: 0x897a9020, Status=0x0

21:56:30.609 89617F7C.E192A9F8 TermDD: IcaCallNextDriver, ProcIndex=2 (enter)

Breakpoint 10 hit

TDTCP!TdRawWrite:

b9ebfcd6 55 push ebp

0: kd> kc

00 TDTCP!TdRawWrite

01 termdd!_IcaCallSd

02 termdd!IcaCallNextDriver

03 RDPWD!SendOutBuf

04 RDPWD!ConnectProviderResponseFunc

05 RDPWD!MCSIcaT120Request

06 RDPWD!WD_Ioctl

参考:

NTSTATUS TdRawWrite(PTD pTd, PSD_RAWWRITE pSdRawWrite)

{

// Call the device driver

// From this point on we must NOT free the outbuf.

// It will be free'd by the write complete routine.
Status = IoCallDriver(pTd->pDeviceObject, pOutBuf->pIrp);

if (NT_SUCCESS(Status)) {

// Update output counters

pTd->pStatus->Output.Bytes += pOutBuf->ByteCount;

pTd->pStatus->Output.Frames++;

TRACE((pTd->pContext, TC_TD, TT_OUT1,
"TdRawWrite %04u, %08x\n",
pOutBuf->ByteCount, pOutBuf));

TRACEBUF((pTd->pContext, TC_TD, TT_ORAW,

pOutBuf->pBuffer, pOutBuf->ByteCount));

21:19:13.937 892767D4.E11B61D0 TdRawWrite 0333, 892c6bf8

21:55:25.125 8959EAD4.E18646A0 TShrSRV: Accepting conference domain 00D644D0

21:55:25.125 8959EAD4.E18646A0 GCC: GCCConferenceCreateResponse entry

21:55:25.125 8959EAD4.E18646A0 GCC: gccEncodeUserData entry

21:55:25.125 8959EAD4.E18646A0 GCC: gccEncodeUserData exit - 0x0

21:55:25.125 8959EAD4.E18646A0 GCC: Calling MCSConnectProviderResponse - hDomain 0xd644d0, result 0x0, pUserData 0xd635e0, UserDataLength 0x11b

Breakpoint 10 hit

TDTCP!TdRawWrite:

b9ebfcd6 55 push ebp

0: kd> kc

00 TDTCP!TdRawWrite

01 termdd!_IcaCallSd

02 termdd!IcaCallNextDriver

03 RDPWD!SendOutBuf

04 RDPWD!ConnectProviderResponseFunc

05 RDPWD!MCSIcaT120Request

06 RDPWD!WD_Ioctl

07 termdd!_IcaCallSd

08 termdd!_IcaCallStack

09 termdd!IcaDeviceControlStack

0a termdd!IcaDeviceControl

0b termdd!IcaDispatch

0c nt!IofCallDriver

0d nt!IopSynchronousServiceTail

0e nt!IopXxxControlFile

0f nt!NtDeviceIoControlFile

10 nt!_KiSystemService

11 SharedUserData!SystemCallStub

12 ntdll!NtDeviceIoControlFile

13 icaapi!IcaIoControl

14 icaapi!_IcaStackIoControlWorker

15 icaapi!IcaStackIoControl

16 rdpwsx!SendConnectProviderResponse

17 rdpwsx!MCSConnectProviderResponse

18 rdpwsx!GCCConferenceCreateResponse

19 rdpwsx!TSrvConfCreateResp

1a rdpwsx!TSrvDoConnectResponse

1b rdpwsx!TSrvDoConnect

1c rdpwsx!TSrvStackConnect

1d rdpwsx!WsxIcaStackIoControl

1e termsrv!WsxStackIoControl

1f icaapi!_IcaStackIoControl

20 icaapi!_IcaStackWaitForIca

21 icaapi!IcaStackConnectionAccept

22 termsrv!TransferConnectionToIdleWinStation

23 termsrv!WinStationTransferThread

24 kernel32!BaseThreadStart

0: kd> dv

pTd = 0x89432b90

pSdRawWrite = 0xb9ba0458

Status = 0n-1178991528

oldIrql = 0xb9 ''

pWorkItem = 0x00000008

0: kd> dx -r1 ((TDTCP!_SD_RAWWRITE *)0xb9ba0458)

((TDTCP!_SD_RAWWRITE *)0xb9ba0458) : 0xb9ba0458 [Type: _SD_RAWWRITE *]

+0x000\] pOutBuf : 0x897a9020 \[Type: _OUTBUF \*

+0x004\] pBuffer : 0x0 \[Type: unsigned char \*

+0x008\] ByteCount : 0x0 \[Type: unsigned long

0: kd> db 0x897a9020

897a9020 51 01 00 00 00 00 00 00-28 90 7a 89 28 90 7a 89 Q.......(.z.(.z.

897a9030 88 91 7a 89 4d 01 00 00-51 01 00 00 00 10 03 f7 ..z.M...Q.......

897a9040 58 90 7a 89 60 91 7a 89-90 2b 43 89 00 00 00 00 X.z.`.z..+C.....

897a9050 00 00 00 00 4a 90 7a 89-06 00 08 01 00 00 00 00 ....J.z.........

897a9060 00 00 00 00 00 00 00 00-68 90 7a 89 68 90 7a 89 ........h.z.h.z.

897a9070 00 00 00 00 00 00 00 00-00 00 04 05 00 00 00 00 ................

897a9080 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

897a9090 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

0: kd> p

_TdCancelReceiveQueue [00000000]: Endpoint 0x8941DF40

TDTCP!TdRawWrite+0x4:

b9ebfcda 8b450c mov eax,dword ptr [ebp+0Ch]

0: kd> p

TDTCP!TdRawWrite+0x10:

b9ebfce6 85ff test edi,edi

0: kd> p

TDTCP!TdRawWrite+0x2a:

b9ebfd00 8b7508 mov esi,dword ptr [ebp+8]

0: kd> p

TDTCP!TdRawWrite+0x34:

b9ebfd0a 57 push edi

0: kd> p

TDTCP!TdRawWrite+0x53:

b9ebfd29 85c0 test eax,eax

0: kd> p

TDTCP!TdRawWrite+0x5a:

b9ebfd30 57 push edi

0: kd> p

TDTCP!TdRawWrite+0x61:

b9ebfd37 85c0 test eax,eax

0: kd> p

TDTCP!TdRawWrite+0x68:

b9ebfd3e 8b4724 mov eax,dword ptr [edi+24h]

0: kd> p

TDTCP!TdRawWrite+0x71:

b9ebfd47 897728 mov dword ptr [edi+28h],esi

0: kd> p

TDTCP!TdRawWrite+0x74:

b9ebfd4a 8d867c020000 lea eax,[esi+27Ch]

0: kd> dv

pTd = 0x89432b90

pSdRawWrite = 0x00000000

Status = 0n0

oldIrql = 0x00 ''

pWorkItem = 0x00000000

0: kd> dx -r1 ((TDTCP!_OUTBUF *)0x897a9020)

((TDTCP!_OUTBUF *)0x897a9020) : 0x897a9020 [Type: _OUTBUF *]

+0x000\] OutBufLength : 0x151 \[Type: unsigned long

+0x004\] PoolIndex : 0 \[Type: int

+0x008\] Links \[Type: _LIST_ENTRY

+0x010\] pBuffer : 0x897a9188 : 0x3 \[Type: unsigned char \*

+0x014\] ByteCount : 0x14d \[Type: unsigned long

+0x018\] MaxByteCount : 0x151 \[Type: unsigned long

+0x01c\] ThreadId : 0xf7031000 \[Type: _ETHREAD \*

+0x020\] pIrp : 0x897a9058 \[Type: _IRP \*

+0x024\] pMdl : 0x897a9160 \[Type: _MDL \*

+0x028\] pPrivate : 0x89432b90 \[Type: void \*

+0x02c\] StartTime : 0x0 \[Type: unsigned long

+0x030\] Sequence : 0x0 \[Type: unsigned char

+0x031\] Fragment : 0x0 \[Type: unsigned char

+0x034 ( 0: 0)\] fWait : 0x0 \[Type: unsigned long

+0x034 ( 1: 1)\] fControl : 0x1 \[Type: unsigned long

+0x034 ( 2: 2)\] fRetransmit : 0x0 \[Type: unsigned long

+0x034 ( 3: 3)\] fCompress : 0x1 \[Type: unsigned long

+0x034 ( 4: 4)\] fIrpCompleted : 0x0 \[Type: unsigned long

0: kd> p

TDTCP!TdRawWrite+0x8a:

b9ebfd60 8d45fc lea eax,[ebp-4]

0: kd> p

TDTCP!TdRawWrite+0x199:

b9ebfe6f 8b5720 mov edx,dword ptr [edi+20h]

0: kd> t

nt!IofCallDriver:

80a266fa 55 push ebp

0: kd> p

nt!IofCallDriver+0x1:

80a266fb 8bec mov ebp,esp

0: kd> p

nt!IofCallDriver+0x5c:

80a26756 56 push esi

0: kd> p

nt!IofCallDriver+0x5d:

80a26757 57 push edi

0: kd> p

nt!IofCallDriver+0x5e:

80a26758 ff548138 call dword ptr [ecx+eax*4+38h]

0: kd> r

eax=0000000f ebx=00000000 ecx=8980c468 edx=897a9058 esi=897a9058 edi=895d2540

eip=80a26758 esp=b9ba03d8 ebp=b9ba03ec iopl=0 nv up ei ng nz na po nc

cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000282

nt!IofCallDriver+0x5e:

80a26758 ff548138 call dword ptr [ecx+eax*4+38h] ds:0023:8980c4dc={tcpip!TCPDispatchInternalDeviceControl (baa180ec)}

0: kd> t

tcpip!TCPDispatchInternalDeviceControl:

baa180ec 55 push ebp

0: kd> p

tcpip!TCPDispatchInternalDeviceControl+0x3:

baa180ef a1206ca3ba mov eax,dword ptr [tcpip!DbgSettingsLevel (baa36c20)]

0: kd> p

tcpip!TCPDispatchInternalDeviceControl+0x36:

baa18122 8b5d08 mov ebx,dword ptr [ebp+8]

0: kd> p

tcpip!TCPDispatchInternalDeviceControl+0x4f:

baa1813b 3b1d206da3ba cmp ebx,dword ptr [tcpip!IPDeviceObject (baa36d20)]

0: kd> p

tcpip!TCPDispatchInternalDeviceControl+0x5b:

baa18147 8b750c mov esi,dword ptr [ebp+0Ch]

0: kd> p

tcpip!TCPDispatchInternalDeviceControl+0x61:

baa1814d 8b4718 mov eax,dword ptr [edi+18h]

0: kd> p

tcpip!TCPDispatchInternalDeviceControl+0x6f:

baa1815b 8a4701 mov al,byte ptr [edi+1]

0: kd> p

tcpip!TCPDispatchInternalDeviceControl+0x76:

baa18162 57 push edi

0: kd> t

tcpip!TCPSendData:

baa162de 55 push ebp

0: kd> kc

00 tcpip!TCPSendData

01 tcpip!TCPDispatchInternalDeviceControl

02 nt!IofCallDriver

03 TDTCP!TdRawWrite

04 termdd!_IcaCallSd

05 termdd!IcaCallNextDriver

06 RDPWD!SendOutBuf

07 RDPWD!ConnectProviderResponseFunc

08 RDPWD!MCSIcaT120Request

09 RDPWD!WD_Ioctl

0a termdd!_IcaCallSd

0b termdd!_IcaCallStack

0c termdd!IcaDeviceControlStack

0d termdd!IcaDeviceControl

0e termdd!IcaDispatch

0f nt!IofCallDriver

10 nt!IopSynchronousServiceTail

11 nt!IopXxxControlFile

12 nt!NtDeviceIoControlFile

13 nt!_KiSystemService

14 SharedUserData!SystemCallStub

15 ntdll!NtDeviceIoControlFile

16 icaapi!IcaIoControl

17 icaapi!_IcaStackIoControlWorker

18 icaapi!IcaStackIoControl

19 rdpwsx!SendConnectProviderResponse

1a rdpwsx!MCSConnectProviderResponse

1b rdpwsx!GCCConferenceCreateResponse

1c rdpwsx!TSrvConfCreateResp

1d rdpwsx!TSrvDoConnectResponse

1e rdpwsx!TSrvDoConnect

1f rdpwsx!TSrvStackConnect

20 rdpwsx!WsxIcaStackIoControl

21 termsrv!WsxStackIoControl

22 icaapi!_IcaStackIoControl

23 icaapi!_IcaStackWaitForIca

24 icaapi!IcaStackConnectionAccept

25 termsrv!TransferConnectionToIdleWinStation

26 termsrv!WinStationTransferThread

27 kernel32!BaseThreadStart

21:56:30.609 89617F7C.E192A9F8 GCC: GCCConferenceCreateResponse entry

21:56:30.609 89617F7C.E192A9F8 GCC: gccEncodeUserData entry

21:56:30.609 89617F7C.E192A9F8 GCC: gccEncodeUserData exit - 0x0

21:56:30.609 89617F7C.E192A9F8 GCC: Calling MCSConnectProviderResponse - hDomain 0xd63f88, result 0x0, pUserData 0xd635e0, UserDataLength 0x11b

21:56:30.609 89617F7C.E192A9F8 TermDD: IcaDeviceControlStack, fc 1280 (enter)

21:56:30.609 89617F7C.E192A9F8 RDP E1026010 WD_Ioctl 0489 IOCTL_T120_REQUEST (1280)

21:56:30.609 89617F7C.E192A9F8 TermDD: IcaBufferAlloc: 0x897a9020, Status=0x0

21:56:30.609 89617F7C.E192A9F8 TermDD: IcaCallNextDriver, ProcIndex=2 (enter)

Breakpoint 10 hit

TDTCP!TdRawWrite:

b9ebfcd6 55 push ebp

0: kd> kc

00 TDTCP!TdRawWrite

01 termdd!_IcaCallSd

02 termdd!IcaCallNextDriver

03 RDPWD!SendOutBuf

04 RDPWD!ConnectProviderResponseFunc

05 RDPWD!MCSIcaT120Request

06 RDPWD!WD_Ioctl

07 termdd!_IcaCallSd

08 termdd!_IcaCallStack

09 termdd!IcaDeviceControlStack

0a termdd!IcaDeviceControl

0b termdd!IcaDispatch

0c nt!IofCallDriver

0d nt!IopSynchronousServiceTail

0e nt!IopXxxControlFile

0f nt!NtDeviceIoControlFile

10 nt!_KiSystemService

11 SharedUserData!SystemCallStub

12 ntdll!NtDeviceIoControlFile

13 icaapi!IcaIoControl

14 icaapi!_IcaStackIoControlWorker

15 icaapi!IcaStackIoControl

16 rdpwsx!SendConnectProviderResponse

17 rdpwsx!MCSConnectProviderResponse

18 rdpwsx!GCCConferenceCreateResponse

19 rdpwsx!TSrvConfCreateResp

1a rdpwsx!TSrvDoConnectResponse

1b rdpwsx!TSrvDoConnect

1c rdpwsx!TSrvStackConnect

1d rdpwsx!WsxIcaStackIoControl

1e termsrv!WsxStackIoControl

1f icaapi!_IcaStackIoControl

20 icaapi!_IcaStackWaitForIca

21 icaapi!IcaStackConnectionAccept

22 termsrv!TransferConnectionToIdleWinStation

23 termsrv!WinStationTransferThread

24 kernel32!BaseThreadStart

0: kd> g

21:56:30.609 89617F7C.E192A9F8 TdRawWrite 0333, 897a9020

相关推荐
sitelist6 天前
RDPWD!ShareClass::UPSendOrders函数中的RDPWD!ShareClass::SC_FlushAndAllocPackage函数分析
tcpsenddata·nm_senddata