rdpwsx!TSrvDoConnect函数分析和rdpwsx!TSrvStackConnect函数分析之调试记录的验证--重要

rdpwsx!TSrvDoConnect函数分析和rdpwsx!TSrvStackConnect函数分析之调试记录的验证

第一部分:

03:44:35.421 894EFF7C.E16655C8 TShrSRV: TSrvAllocInfo exit - 0x0

03:44:35.421 894EFF7C.E16655C8 TShrSRV: TSrvDoConnect entry

03:44:35.421 894EFF7C.E16655C8 TShrSRV: TSrvReferenceInfo entry

03:44:35.421 894EFF7C.E16655C8 TShrSRV: TSrvReferenceInfo exit
03:44:35.421 894EFF7C.E16655C8 TShrSRV: Waiting for connection Ind signal for pTSrvInfo 0xd62ad0

03:44:35.421 8954D5E4.00000000 TermDD: IcaChannelInput, bc=1076 (enter)

03:44:35.421 890EC1FC.E177A920 GCC: mcsCallback entry

03:44:35.421 890EC1FC.E177A920 GCC: Message 0x0, pvParam 0xe4ff40, pvContext 0xd62ad0

03:44:35.421 890EC1FC.E177A920 GCC: gccConnectProviderIndication entry (MCS userDataLength = 0x12f)

03:44:35.421 890EC1FC.E177A920 GCC: gccDecodeUserData entry

03:44:35.421 890EC1FC.E177A920 GCC: gccDecodeUserData (len=0x118) exit - 0x0

03:44:35.421 890EC1FC.E177A920 GCC: Performing GCC_CREATE_INDICATION callout

03:44:35.421 890EC1FC.E177A920 TShrSRV: TSrvGCCCallBack entry

03:44:35.421 890EC1FC.E177A920 TShrSRV: GCCCallback message 0x0 (GCC_CREATE_INDICATION) received

03:44:35.437 890EC1FC.E177A920 TShrSRV: TSrvHandleCreateInd entry

03:44:35.437 890EC1FC.E177A920 TShrSRV: Accepting create indication - Domain 00D62B68

03:44:35.437 890EC1FC.E177A920 TShrSRV: Conductor privilege list is NULL

03:44:35.437 890EC1FC.E177A920 TShrSRV: Conducted mode privilege list is NULL

03:44:35.437 890EC1FC.E177A920 TShrSRV: Non-conducted mode privilege list is NULL

03:44:35.437 890EC1FC.E177A920 TShrSRV: NULL conf name

03:44:35.437 890EC1FC.E177A920 TShrSRV: Attempting to save CreateInd userData

03:44:35.437 890EC1FC.E177A920 TShrSRV: TSrvSaveUserData entry

03:44:35.437 890EC1FC.E177A920 TShrSRV: TSrvCalculateUserDataSize entry

03:44:35.437 890EC1FC.E177A920 TShrSRV: number_of_user_data_members = 0x1

03:44:35.453 890EC1FC.E177A920 TShrSRV: Key_type = 0x2 (GCC_H221_NONSTANDARD_KEY)

03:44:35.453 890EC1FC.E177A920 TShrSRV: key long_string_length = 0x4

03:44:35.453 890EC1FC.E177A920 TShrSRV: data long_string_length = 0x118

03:44:35.453 890EC1FC.E177A920 TShrSRV: TSrvCalculateUserDataSize exit - 0x124

03:44:35.453 890EC1FC.E177A920 TShrSRV: Allocated 0x154 bytes for UserData save space

03:44:35.468 890EC1FC.E177A920 TShrSRV: Saving each UserDataMenber to save space

03:44:35.468 890EC1FC.E177A920 TShrSRV: TSrvSaveUserDataMember entry

03:44:35.468 890EC1FC.E177A920 TShrSRV: TSrvSaveUserDataMember exit

03:44:35.468 890EC1FC.E177A920 TShrSRV: TSrvSaveUserData exit - 0x0

03:44:35.468 890EC1FC.E177A920 TShrSRV: Save userData was successful

03:44:35.468 890EC1FC.E177A920 TShrSRV: TSrvSignalIndication entry

03:44:35.468 890EC1FC.E177A920 TShrSRV: Signaling workEvent 00000200, status 0x0

03:44:35.484 890EC1FC.E177A920 TShrSRV: TSrvSignalIndication exit
03:44:35.484 894EFF7C.E16655C8 TShrSRV: Connection Ind signal received for pTSrvInfo 00D62AD0 - 0x0

03:44:35.484 890EC1FC.E177A920 TShrSRV: TSrvHandleCreateInd exit
03:44:35.484 894EFF7C.E16655C8 TShrSRV: TSrvDoConnectResponse entry

03:44:35.484 890EC1FC.E177A920 TShrSRV: TSrvGCCCallBack exit - GCC_CALLBACK_PROCESSED

03:44:35.500 894EFF7C.E16655C8 TShrSRV: TSrvConfCreateResp entry

03:44:35.500 890EC1FC.E177A920 GCC: Returned from GCC_CREATE_INDICATION callout

03:44:35.500 894EFF7C.E16655C8 TShrSRV: Attempting ConfCreate response

03:44:35.500 890EC1FC.E177A920 GCC: gccConnectProviderIndication exit - 0x0

03:44:35.500 894EFF7C.E16655C8 TShrSRV: TSrvInitWD entry

03:44:35.500 890EC1FC.E177A920 GCC: mcsCallback exit - 0x0

03:44:35.500 894EFF7C.E16655C8 TShrSRV: Performing WDTShare connection info exchange

03:44:35.500 894EFF7C.E16655C8 TShrSRV: TSrvInitWDConnectInfo entry

03:44:35.500 894EFF7C.E16655C8 TShrSRV: Allocated 0x80 bytes to recieve WDTShare return data

03:44:35.500 894EFF7C.E16655C8 TShrSRV: Performing connect (size=128)

RDPWD: New: ShareClass at E1861440, size=1392

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 WDW_OnSMConn 0677 pOutData at 00D63188

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 WDW_OnSMConn 0711 Key octet at 00D631A8 (offs 00000020)

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 WDW_OnSMConn 0719 Data octet pointer at 00D631AC (offs 00000024)

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 WDW_OnSMConn 0733 Core data at 00D631B4 (offs 0000002C)

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 WDW_OnSMConn 0738 Net data at 00D631BC (offs 00000034)

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 WDW_OnSMConn 0747 Sec data at 00D631CC (offs 00000044)

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 WDW_OnSMConn 0757 Build 80 bytes of returned user data

03:44:35.500 894EFF7C.E16655C8 TermDD: IcaDeviceControlStack, fc 2304, 0x0

03:44:35.500 894EFF7C.E16655C8 TShrSRV: TSrvInitWDConnectInfo exit - 0x0

03:44:35.500 894EFF7C.E16655C8 TShrSRV: TSrvInitWD exit - 0x0

03:44:35.500 894EFF7C.E16655C8 TShrSRV: TSrvCreateGCCDataList entry

03:44:35.500 894EFF7C.E16655C8 TShrSRV: Creating UserData list

03:44:35.500 894EFF7C.E16655C8 TShrSRV: Allocated 0x4 bytes for 0x1 member UserData array

03:44:35.500 894EFF7C.E16655C8 TShrSRV: TSrvCreateGCCDataList exit = 0xd63018

03:44:35.500 894EFF7C.E16655C8 TShrSRV: Accepting conference domain 00D62B68

03:44:35.500 894EFF7C.E16655C8 GCC: GCCConferenceCreateResponse entry

03:44:35.500 894EFF7C.E16655C8 GCC: gccEncodeUserData entry

03:44:35.500 894EFF7C.E16655C8 GCC: gccEncodeUserData exit - 0x0

03:44:35.500 894EFF7C.E16655C8 GCC: Calling MCSConnectProviderResponse - hDomain 0xd62b68, result 0x0, pUserData 0xd63318, UserDataLength 0x11b

03:44:35.500 894EFF7C.E16655C8 TermDD: IcaDeviceControlStack, fc 1280, 0x0

03:44:35.500 894EFF7C.E16655C8 GCC: MCSConnectProviderResponse - MCSError 0x0 (MCS_NO_ERROR)

03:44:35.500 894EFF7C.E16655C8 GCC: gccMapMcsError: mcsError 0x0 (MCS_NO_ERROR), gbbError 0x0 (GCC_NO_ERROR)

03:44:35.500 894EFF7C.E16655C8 GCC: GCCConferenceCreateResponse exit - 0x0

03:44:35.500 894EFF7C.E16655C8 TShrSRV: GCCConferenceCreateResponse - GCC rc 0x0 (GCC_NO_ERROR)

03:44:35.500 894EFF7C.E16655C8 TShrSRV: Waiting to receive client random: msec=60000

03:44:35.500 894EFF7C.E16655C8 TermDD: IcaWaitForMultipleObjects, 60000 (enter)

03:44:35.500 8954D5E4.00000000 RDP E1895010 SM_MCSSendDa 0507 Encrypting=1: security packet

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 WDW_WaitForC 0920 Primary event hit

03:44:35.500 894EFF7C.E16655C8 RDP E1895010 SM_GetSecuri 1349 Back from wait for security data

03:44:35.515 894EFF7C.E16655C8 TermDD: IcaDeviceControlStack, fc 2308, 0x0

03:44:35.515 894EFF7C.E16655C8 TShrSRV: Received encrypted client random, rc=0

03:44:35.515 8954D5E4.00000000 RDP E1895010 SM_MCSSendDa 0507 Encrypting=1: security packet

03:44:35.515 8954D5E4.00000000 RDP E1895010 SMSecurityEx 0301 About to wait for session key creation

03:44:35.515 8954D5E4.00000000 TermDD: IcaWaitForMultipleObjects, -1 (enter)

03:44:35.515 894EFF7C.E16655C8 TShrSRV: Decrypted client random: rc=0

03:44:35.515 894EFF7C.E16655C8 TShrSRV: Sending sec info to WD

03:44:35.515 894EFF7C.E16655C8 TermDD: IcaDeviceControlStack, fc 2309, 0x0

03:44:35.515 8954D5E4.00000000 RDP E1895010 WDW_WaitForC 0920 Primary event hit

03:44:35.515 8954D5E4.00000000 RDP E1895010 SMSecurityEx 0304 Back from wait for session key creation

03:44:35.515 894EFF7C.E16655C8 TShrSRV: Session key transmission succeeded, PrevStatus=0

03:44:35.515 894EFF7C.E16655C8 TShrSRV: TSrvConfCreateResp exit = 0x0

03:44:35.515 894EFF7C.E16655C8 TShrSRV: TSrvDoConnectResponse exit - 0x0

03:44:35.515 894EFF7C.E16655C8 TShrSRV: TSrvDereferenceInfo entry

03:44:35.515 894EFF7C.E16655C8 TShrSRV: TSrvDereferenceInfo exit
03:44:35.515 894EFF7C.E16655C8 TShrSRV: TSrvDoConnect exit - 0x0
03:44:35.515 894EFF7C.E16655C8 TShrSRV: TSrvStackConnect exit - 0x0
03:44:35.515 894EFF7C.E16655C8 TShrSRV: WsxIcaStackIoControl exit - 0x0
03:44:35.515 894EFF7C.E16655C8 TSAPI: _IcaWaitForIca, success
03:44:35.515 894EFF7C.E16655C8 TERMSRV: Enter WsxIcaIoControl, IoControlCode=19

03:44:35.515 894EFF7C.E16655C8 TShrSRV: WsxIcaStackIoControl entry

03:44:35.515 894EFF7C.E16655C8 TShrSRV: 00D62808:00D62AD0 IoctlDetail: Ioctl 0x38004f (IOCTL_ICA_STACK_CONNECTION_QUERY)

03:44:35.515 8954D5E4.00000000 RDP E1895010 SMSecurityEx 0309 Decrypt the packet

03:44:35.531 8954D5E4.00000000 RDP E1895010 SMDecryptPac 0186 Data decrypted: 362

第二部分:

Breakpoint 19 hit

rdpwsx!TSrvConfCreateResp:

001b:70fbba04 55 push ebp

0: kd> kc

00 rdpwsx!TSrvConfCreateResp

01 rdpwsx!TSrvDoConnectResponse

02 rdpwsx!TSrvDoConnect

03 rdpwsx!TSrvStackConnect

04 rdpwsx!WsxIcaStackIoControl

05 termsrv!WsxStackIoControl

06 ICAAPI!_IcaStackIoControl

07 ICAAPI!_IcaStackWaitForIca

08 ICAAPI!IcaStackConnectionAccept

09 termsrv!TransferConnectionToIdleWinStation

0a termsrv!WinStationTransferThread

0b kernel32!BaseThreadStart

第三部分:

第三部分A:

NTSTATUS

TSrvDoConnect(IN PTSRVINFO pTSrvInfo)

{

DWORD dwStatus;

NTSTATUS ntStatus;

TRACE((DEBUG_TSHRSRV_FLOW,

"TShrSRV: TSrvDoConnect entry\n"));

ntStatus = STATUS_TRANSACTION_ABORTED;

if (pTSrvInfo->fDisconnect == FALSE)

{

TSrvReferenceInfo(pTSrvInfo);

// Wait to be told that a connection is being

// requested via the client

TRACE((DEBUG_TSHRSRV_NORMAL,

"TShrSRV: Waiting for connection Ind signal for pTSrvInfo 0x%x\n",

pTSrvInfo));

dwStatus = WaitForSingleObject(pTSrvInfo->hWorkEvent, 60000);

TRACE((DEBUG_TSHRSRV_NORMAL,

"TShrSRV: Connection Ind signal received for pTSrvInfo %p - 0x%x\n",

pTSrvInfo, dwStatus));

// If a client connection request has been recieved, then proceed

// with the acknowledgement process (CreateResponse)

switch (dwStatus)

{

case WAIT_OBJECT_0:

if (pTSrvInfo->fDisconnect == FALSE)

ntStatus = TSrvDoConnectResponse(pTSrvInfo);

else

ntStatus = STATUS_TRANSACTION_ABORTED;

break;

case WAIT_TIMEOUT:

ntStatus = STATUS_IO_TIMEOUT;

break;

}

TSrvDereferenceInfo(pTSrvInfo);

}

TRACE((DEBUG_TSHRSRV_FLOW,

"TShrSRV: TSrvDoConnect exit - 0x%x\n", ntStatus));

return (ntStatus);

}

第三部分B:

TRACE((DEBUG_TSHRSRV_NORMAL,

"TShrSRV: Waiting for connection Ind signal for pTSrvInfo 0x%x\n",

pTSrvInfo));

dwStatus = WaitForSingleObject(pTSrvInfo->hWorkEvent, 60000);

TRACE((DEBUG_TSHRSRV_NORMAL,

"TShrSRV: Connection Ind signal received for pTSrvInfo %p - 0x%x\n",

pTSrvInfo, dwStatus));

WaitForSingleObject函数之前有调试信息,有事件,也就是客户端发来请求之后才返回。

等待时间是60秒,也就是1分钟。

调试记录对应的部分:

03:44:35.421 894EFF7C.E16655C8 TShrSRV: Waiting for connection Ind signal for pTSrvInfo 0xd62ad0

03:44:35.421 8954D5E4.00000000 TermDD: IcaChannelInput, bc=1076 (enter)

03:44:35.421 890EC1FC.E177A920 GCC: mcsCallback entry

03:44:35.421 890EC1FC.E177A920 GCC: Message 0x0, pvParam 0xe4ff40, pvContext 0xd62ad0

03:44:35.421 890EC1FC.E177A920 GCC: gccConnectProviderIndication entry (MCS userDataLength = 0x12f)

03:44:35.421 890EC1FC.E177A920 GCC: gccDecodeUserData entry

03:44:35.421 890EC1FC.E177A920 GCC: gccDecodeUserData (len=0x118) exit - 0x0

03:44:35.421 890EC1FC.E177A920 GCC: Performing GCC_CREATE_INDICATION callout

03:44:35.421 890EC1FC.E177A920 TShrSRV: TSrvGCCCallBack entry

03:44:35.421 890EC1FC.E177A920 TShrSRV: GCCCallback message 0x0 (GCC_CREATE_INDICATION) received

03:44:35.437 890EC1FC.E177A920 TShrSRV: TSrvHandleCreateInd entry

03:44:35.437 890EC1FC.E177A920 TShrSRV: Accepting create indication - Domain 00D62B68

03:44:35.437 890EC1FC.E177A920 TShrSRV: Conductor privilege list is NULL

03:44:35.437 890EC1FC.E177A920 TShrSRV: Conducted mode privilege list is NULL

03:44:35.437 890EC1FC.E177A920 TShrSRV: Non-conducted mode privilege list is NULL

03:44:35.437 890EC1FC.E177A920 TShrSRV: NULL conf name

03:44:35.437 890EC1FC.E177A920 TShrSRV: Attempting to save CreateInd userData

03:44:35.437 890EC1FC.E177A920 TShrSRV: TSrvSaveUserData entry

03:44:35.437 890EC1FC.E177A920 TShrSRV: TSrvCalculateUserDataSize entry

03:44:35.437 890EC1FC.E177A920 TShrSRV: number_of_user_data_members = 0x1

03:44:35.453 890EC1FC.E177A920 TShrSRV: Key_type = 0x2 (GCC_H221_NONSTANDARD_KEY)

03:44:35.453 890EC1FC.E177A920 TShrSRV: key long_string_length = 0x4

03:44:35.453 890EC1FC.E177A920 TShrSRV: data long_string_length = 0x118

03:44:35.453 890EC1FC.E177A920 TShrSRV: TSrvCalculateUserDataSize exit - 0x124

03:44:35.453 890EC1FC.E177A920 TShrSRV: Allocated 0x154 bytes for UserData save space

03:44:35.468 890EC1FC.E177A920 TShrSRV: Saving each UserDataMenber to save space

03:44:35.468 890EC1FC.E177A920 TShrSRV: TSrvSaveUserDataMember entry

03:44:35.468 890EC1FC.E177A920 TShrSRV: TSrvSaveUserDataMember exit

03:44:35.468 890EC1FC.E177A920 TShrSRV: TSrvSaveUserData exit - 0x0

03:44:35.468 890EC1FC.E177A920 TShrSRV: Save userData was successful

03:44:35.468 890EC1FC.E177A920 TShrSRV: TSrvSignalIndication entry

03:44:35.468 890EC1FC.E177A920 TShrSRV: Signaling workEvent 00000200, status 0x0

03:44:35.484 890EC1FC.E177A920 TShrSRV: TSrvSignalIndication exit

03:44:35.484 894EFF7C.E16655C8 TShrSRV: Connection Ind signal received for pTSrvInfo 00D62AD0 - 0x0

890EC1FC.E177A920是其他线程的调试信息,把上面的890EC1FC.E177A920线程输出的信息过滤掉就剩两行了。

03:44:35.421 894EFF7C.E16655C8 TShrSRV: Waiting for connection Ind signal for pTSrvInfo 0xd62ad0

。。。

03:44:35.484 894EFF7C.E16655C8 TShrSRV: Connection Ind signal received for pTSrvInfo 00D62AD0 - 0x0

第四部分:rdpwsx!TSrvStackConnect函数分析的两大部分

NTSTATUS

TSrvStackConnect(IN HANDLE hIca,

IN HANDLE hStack,

OUT PTSRVINFO *ppTSrvInfo)

{

NTSTATUS ntStatus;

TRACE((DEBUG_TSHRSRV_FLOW,

"TShrSRV: TSrvStackConnect entry\n"));

ntStatus = STATUS_UNSUCCESSFUL;

if (TSrvIsReady(TRUE))

{

TS_ASSERT(hStack);

// Allocate a TSrvInfo object which will be used to

// track this connection instance

ntStatus = TSrvAllocInfo(ppTSrvInfo, hIca, hStack);

if (NT_SUCCESS(ntStatus))

{

TS_ASSERT(*ppTSrvInfo);

ntStatus = TSrvDoConnect(*ppTSrvInfo);

}

}

TRACE((DEBUG_TSHRSRV_FLOW,

"TShrSRV: TSrvStackConnect exit - 0x%x\n", ntStatus));

return (ntStatus);

}

17 rdpwsx!TSrvAllocInfo

18 rdpwsx!TSrvStackConnect

19 rdpwsx!WsxIcaStackIoControl

1a termsrv!WsxStackIoControl

1b ICAAPI!_IcaStackIoControl

1c ICAAPI!_IcaStackWaitForIca

02 rdpwsx!TSrvDoConnect

03 rdpwsx!TSrvStackConnect

04 rdpwsx!WsxIcaStackIoControl

05 termsrv!WsxStackIoControl

06 ICAAPI!_IcaStackIoControl

07 ICAAPI!_IcaStackWaitForIca

第五部分:ICAAPI!IcaStackConnectionAccept函数分析之ICAAPI!_IcaStackWaitForIca和之后的IOCTL_ICA_STACK_CONNECTION_QUERY

07 ICAAPI!_IcaStackWaitForIca

08 ICAAPI!IcaStackConnectionAccept

03:44:35.515 894EFF7C.E16655C8 TShrSRV: TSrvDoConnect exit - 0x0

03:44:35.515 894EFF7C.E16655C8 TShrSRV: TSrvStackConnect exit - 0x0

03:44:35.515 894EFF7C.E16655C8 TShrSRV: WsxIcaStackIoControl exit - 0x0

03:44:35.515 894EFF7C.E16655C8 TSAPI: _IcaWaitForIca, success

03:44:35.515 894EFF7C.E16655C8 TERMSRV: Enter WsxIcaIoControl, IoControlCode=19

03:44:35.515 894EFF7C.E16655C8 TShrSRV: WsxIcaStackIoControl entry

03:44:35.515 894EFF7C.E16655C8 TShrSRV: 00D62808:00D62AD0 IoctlDetail: Ioctl 0x38004f (IOCTL_ICA_STACK_CONNECTION_QUERY)

04 rdpwsx!WsxIcaStackIoControl

05 termsrv!WsxStackIoControl

06 ICAAPI!_IcaStackIoControl

ICAAPI!_IcaStackIoControl函数最终会调用到rdpwsx!WsxIcaStackIoControl

ICAAPI!_IcaStackIoControl函数并没有什么输出信息,一般调用到rdpwsx!WsxIcaStackIoControl会有调试信息输出

03:44:35.515 894EFF7C.E16655C8 TERMSRV: Enter WsxIcaIoControl, IoControlCode=19

NTSTATUS

_IcaStackIoControl( IN HANDLE pContext,

IN ULONG IoControlCode,

IN PVOID pInBuffer,

IN ULONG InBufferSize,

OUT PVOID pOutBuffer,

IN ULONG OutBufferSize,

OUT PULONG pBytesReturned )

{

NTSTATUS Status;

PSTACK pStack;

pStack = (PSTACK) pContext;

/*

* Call callback function to handle StackIoControl

*/

if ( pStack->pStackIoControlCallback ) {

/*

* Unlock critical section

*/

pStack->RefCount++;

UNLOCK( &pStack->CritSec );

Status = pStack->pStackIoControlCallback(

pStack->pCallbackContext,

pStack,

IoControlCode,

pInBuffer,

InBufferSize,

pOutBuffer,

OutBufferSize,

pBytesReturned );

/*

* Re-lock critical section

*/

LOCK( &pStack->CritSec );

_DecrementStackRef( pStack );

} else {

Status = _IcaStackIoControlWorker( pStack,

IoControlCode,

pInBuffer,

InBufferSize,

pOutBuffer,

OutBufferSize,

pBytesReturned );

}

return( Status );

}

NTSTATUS

WsxStackIoControl(

IN PVOID pContext,

IN HANDLE pStack,

IN ULONG IoControlCode,

IN PVOID pInBuffer,

IN ULONG InBufferSize,

OUT PVOID pOutBuffer,

IN ULONG OutBufferSize,

OUT PULONG pBytesReturned )

{

PWINSTATION pWinStation = (PWINSTATION)pContext;

NTSTATUS Status;

TRACE((hTrace, TC_ICASRV, TT_API1,

"TERMSRV: Enter WsxIcaIoControl, IoControlCode=%d\n",

(IoControlCode >> 2) & 0xfff));

NTSTATUS

IcaStackConnectionAccept( IN HANDLE hIca,

IN HANDLE pContext,

IN PWINSTATIONNAME pWinStationName,

IN PWINSTATIONCONFIG2 pWinStationConfig,

IN PVOID pEndpoint,

IN ULONG EndpointLength,

IN PICA_STACK_STATE_HEADER pStackState,

IN ULONG BufferLength,

IN PICA_TRACE pTrace )

{

/*

* Wait for ICA Detect string from client

*/

Status = _IcaStackWaitForIca( pContext,

pWinStationConfig,

&fStackModified );

if ( !NT_SUCCESS(Status) ) {

goto badaccept;

}

/*

* Check if the query stack is different than the template stack

*/

if ( fStackModified ) {

TRACESTACK(( pContext, TC_ICAAPI, TT_API1, "TSAPI: IcaStackConnectionAccept, load query stack\n"));

ASSERT(FALSE);

#ifdef notdef

/*

* Unload all stack drivers except the transport

* and connection drivers

* -- we can not pop the td or cd

* -- we can not issue a cancel i/o

*/

_IcaPopStack( pContext );

/*

* Load and open the new query stack

*/

Status = _IcaPushStackAndOpenEndpoint( pContext,

pWinStationName,

pWinStationConfig,

pEndpoint,

EndpointLength );

if ( !NT_SUCCESS(Status) ) {

goto badaccept;

}

#endif

}

}

/*

* At this point the stack is now set up (again). The client is

* now queried for any configuration changes.

*

* - repeat this loop until WD does not change

*/

do {

/*

* Clear query again flag

*/

fQueryAgain = FALSE;

/*

* Query the client for the optional PD's

*/

Status = _IcaStackIoControl( pStack,

IOCTL_ICA_STACK_CONNECTION_QUERY,

NULL,

0,

&IcaStackConfig,

sizeof(IcaStackConfig),

&cbReturned );