RDPWD!SM_Connect函数里面的SM_CHECK_STATE和RDPWD!smStatetable全局变量的关系
RDPWD!SM_Connect函数里面的SM_CHECK_STATE和RDPWD!smStatetable全局变量的关系
第0部分:综述
RDPWD!smStatetable是二维数组
RDPWD!smStatetable[0]表示第0个事件,
RDPWD!smStatetable[0][0] 第0个事件第0个元素代表事件0状态是否是OK的?还是WARN的还是error的。
RDPWD!smStatetable[0][1] 第0个事件第0个元素代表事件1状态是否是OK的?还是WARN的还是error的。
ok=0 warn=1 error=2
举例说明:下面是RDPWD!smStatetable[3]代表SM_EVT_CONNECT事件,在0状态是2,也就是error的,不该发生。
在0状态是2,也就是error的,不该发生。
在1状态是0,也就是OK的,应该发生。
在2状态是2,也就是error的,不该发生。
在3状态是2,也就是error的,不该发生。
在4状态是2,也就是error的,不该发生。
在5状态是2,也就是error的,不该发生。
在6状态是2,也就是error的,不该发生。
在7状态是2,也就是error的,不该发生。
1状态的定义:
#define SM_STATE_INITIALIZED 1
0: kd> dx -r1 (*((RDPWD!unsigned char (*)[8])0xb9d81500))
(*((RDPWD!unsigned char (*)[8])0xb9d81500)) [Type: unsigned char [8]]
[0] : 0x2 [Type: unsigned char]
[1] : 0x0 [Type: unsigned char]
[2] : 0x2 [Type: unsigned char]
[3] : 0x2 [Type: unsigned char]
[4] : 0x2 [Type: unsigned char]
[5] : 0x2 [Type: unsigned char]
[6] : 0x2 [Type: unsigned char]
[7] : 0x2 [Type: unsigned char]
第一部分:
NTSTATUS RDPCALL SM_Connect(PVOID pSMHandle,
PRNS_UD_CS_SEC pUserDataIn,
PRNS_UD_CS_NET pNetUserData,
BOOLEAN bOldShadow)
{
NTSTATUS status = STATUS_SUCCESS;
BOOL rc = FALSE;
PSM_HANDLE_DATA pRealSMHandle = (PSM_HANDLE_DATA)pSMHandle;
UINT32 encMethodPicked = 0;
DC_BEGIN_FN("SM_Connect");
SM_CHECK_STATE(SM_EVT_CONNECT);
pRealSMHandle->pUserData = NULL;
/************************************************************************/
/* pick a matching encryption method. */
/************************************************************************/
TRC_ALT((TB, "Client supports encryption: %lx",
pUserDataIn->encryptionMethods));
TRC_NRM((TB, "Server supports encryption: %lx",
pRealSMHandle->encryptionMethodsSupported));
第二部分:
/****************************************************************************/
/* SM_CHECK_STATE checks whether we have violated the SM state table. */
/* */
/* smStateTable is filled in in ASMDATA.C. */
/* */
/* Possible values of STATE are defined in ASMINT.H. */
/* Possible events are defined in ASMINT.H */
/****************************************************************************/
#define SM_CHECK_STATE(event) \
{ \
if (smStateTable[event][pRealSMHandle->state] != SM_TABLE_OK) \
{ \
if (smStateTable[event][pRealSMHandle->state] == SM_TABLE_WARN) \
{ \
TRC_ALT((TB, "Unusual event %s in state %s", \
smEventName[event], smStateName[pRealSMHandle->state]));\
} \
else \
{ \
TRC_ABORT((TB, "Invalid event %s in state %s", \
smEventName[event], smStateName[pRealSMHandle->state]));\
} \
DC_QUIT; \
} \
}
第三部分:
/****************************************************************************/
/* Values in the state table */
/****************************************************************************/
#define SM_TABLE_OK 0
#define SM_TABLE_WARN 1
#define SM_TABLE_ERROR 2
/****************************************************************************/
/* SM States */
/****************************************************************************/
#define SM_STATE_STARTED 0
#define SM_STATE_INITIALIZED 1
#define SM_STATE_NM_CONNECTING 2
#define SM_STATE_SM_CONNECTING 3
#define SM_STATE_LICENSING 4
#define SM_STATE_CONNECTED 5
#define SM_STATE_SC_REGISTERED 6
#define SM_STATE_DISCONNECTING 7
#define SM_NUM_STATES 8
/****************************************************************************/
/* SM Events */
/****************************************************************************/
#define SM_EVT_INIT 0
#define SM_EVT_TERM 1
#define SM_EVT_REGISTER 2
#define SM_EVT_CONNECT 3
#define SM_EVT_DISCONNECT 4
#define SM_EVT_CONNECTED 5
#define SM_EVT_DISCONNECTED 6
#define SM_EVT_DATA_PACKET 7
// Note that Alloc & Send have the same event ID, as the conditions
// under which these may be called are identical.
#define SM_EVT_ALLOCBUFFER 8
#define SM_EVT_SENDDATA 8
#define SM_EVT_SEC_PACKET 9
#define SM_EVT_LIC_PACKET 10
#define SM_EVT_ALIVE 11
#define SM_NUM_EVENTS 12
第四部分:
/****************************************************************************/
/* This state table simply shows which events are valid in which states. */
/* */
/* Values mean */
/* */
/* - 0 event OK in this state. */
/* */
/* - 1 warning - event should not occur in this state, but does in */
/* some race conditions - ignore it. */
/* */
/* - 2 error - event should not occur in ths state at all. */
/* */
/* These values are hard-coded here in ordeer to make the table readable. */
/* They correspond to the constants SM_TABLE_OK, SM_TABLE_WARN & */
/* SM_TABLE_ERROR. */
/****************************************************************************/
/* The events and states are defined in asmint.h. The events are */
/* prefixed with SM_EVT and the states are prefixed with SM_STATE */
/* */
/* Started */
/* | Initialized */
/* | | NM_Connecting */
/* | | | SM_Connecting */
/* | | | | Licensing */
/* | | | | | Connected */
/* | | | | | | SC_Registered */
/* | | | | | | | Disconnecting */
/* | | | | | | | | */
/* 0 1 2 3 4 5 6 7 */
/****************************************************************************/
DC_STRUCT8( 0, 2, 2, 2, 2, 2, 2, 2 ), /* Init */
DC_STRUCT8( 1, 0, 0, 0, 0, 0, 0, 0 ), /* Term */
DC_STRUCT8( 2, 2, 2, 2, 2, 0, 0, 2 ), /* Register */
DC_STRUCT8( 2, 0, 2, 2, 2, 2, 2, 2 ), /* Connect */
DC_STRUCT8( 2, 2, 2, 0, 0, 0, 0, 2 ), /* Disconnect */
DC_STRUCT8( 2, 2, 0, 2, 2, 2, 2, 2 ), /* Connected */
DC_STRUCT8( 1, 1, 0, 0, 0, 0, 0, 0 ), /* Disconnected */
DC_STRUCT8( 1, 1, 1, 1, 1, 1, 0, 1 ), /* Data Packet */
DC_STRUCT8( 1, 1, 1, 0, 0, 1, 0, 1 ), /* Send Data */
DC_STRUCT8( 2, 2, 2, 0, 2, 2, 2, 1 ), /* Security Packet */
DC_STRUCT8( 2, 2, 2, 2, 0, 1, 1, 1 ), /* Licensing Packet */
DC_STRUCT8( 2, 2, 2, 2, 2, 2, 0, 0 ) /* Alive */
));
第五部分:
DC_STRUCT8( 2, 0, 2, 2, 2, 2, 2, 2 ), /* Connect */
SM_Init函数里面把状态设置为SM_STATE_INITIALIZED
NTSTATUS RDPCALL SM_Init(PVOID pSMHandle,
PTSHARE_WD pWDHandle,
BOOLEAN bOldShadow)
{
/************************************************************************/
/* Update the state */
/************************************************************************/
SM_SET_STATE(SM_STATE_INITIALIZED);
smStateTable[event][pRealSM_STATE_INITIALIZED] = SM_TABLE_OK
smStateTable[SM_EVT_CONNECT][pRealSM_STATE_INITIALIZED] = SM_TABLE_OK
第六部分:
0: kd> x RDPWD!smStatetable
b9d814e8 RDPWD!smStateTable = unsigned char [12][8]
0: kd> dx -r1 (*((RDPWD!unsigned char (*)[12][8])0xb9d814e8))
(*((RDPWD!unsigned char (*)[12][8])0xb9d814e8)) [Type: unsigned char [12][8]]
[0] [Type: unsigned char [8]]
[1] [Type: unsigned char [8]]
[2] [Type: unsigned char [8]]
[3] [Type: unsigned char [8]]
[4] [Type: unsigned char [8]]
[5] [Type: unsigned char [8]]
[6] [Type: unsigned char [8]]
[7] [Type: unsigned char [8]]
[8] [Type: unsigned char [8]]
[9] [Type: unsigned char [8]]
[10] [Type: unsigned char [8]]
[11] [Type: unsigned char [8]]
0: kd> dx -r1 (*((RDPWD!unsigned char (*)[8])0xb9d814e8))
(*((RDPWD!unsigned char (*)[8])0xb9d814e8)) [Type: unsigned char [8]]
[0] : 0x0 [Type: unsigned char]
[1] : 0x2 [Type: unsigned char]
[2] : 0x2 [Type: unsigned char]
[3] : 0x2 [Type: unsigned char]
[4] : 0x2 [Type: unsigned char]
[5] : 0x2 [Type: unsigned char]
[6] : 0x2 [Type: unsigned char]
[7] : 0x2 [Type: unsigned char]
0: kd> dx -r1 (*((RDPWD!unsigned char (*)[8])0xb9d814f0))
(*((RDPWD!unsigned char (*)[8])0xb9d814f0)) [Type: unsigned char [8]]
[0] : 0x1 [Type: unsigned char]
[1] : 0x0 [Type: unsigned char]
[2] : 0x0 [Type: unsigned char]
[3] : 0x0 [Type: unsigned char]
[4] : 0x0 [Type: unsigned char]
[5] : 0x0 [Type: unsigned char]
[6] : 0x0 [Type: unsigned char]
[7] : 0x0 [Type: unsigned char]
0: kd> dx -r1 (*((RDPWD!unsigned char (*)[8])0xb9d81500))
(*((RDPWD!unsigned char (*)[8])0xb9d81500)) [Type: unsigned char [8]]
[0] : 0x2 [Type: unsigned char]
[1] : 0x0 [Type: unsigned char]
[2] : 0x2 [Type: unsigned char]
[3] : 0x2 [Type: unsigned char]
[4] : 0x2 [Type: unsigned char]
[5] : 0x2 [Type: unsigned char]
[6] : 0x2 [Type: unsigned char]
[7] : 0x2 [Type: unsigned char]
0: kd> dx -r1 (*((RDPWD!unsigned char (*)[8])0xb9d81500))
(*((RDPWD!unsigned char (*)[8])0xb9d81500)) [Type: unsigned char [8]]
[0] : 0x2 [Type: unsigned char]
[1] : 0x0 [Type: unsigned char]
[2] : 0x2 [Type: unsigned char]
[3] : 0x2 [Type: unsigned char]
[4] : 0x2 [Type: unsigned char]
[5] : 0x2 [Type: unsigned char]
[6] : 0x2 [Type: unsigned char]
[7] : 0x2 [Type: unsigned char]
