From a7a6a4a0dacadde6d1bf9dd92679457da3e8482b Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Tue, 6 Nov 2018 23:53:33 +0000 Subject: [PATCH] Implement tests for CreateGroup() and AddPlayerToGroup() They pass against DirectX, if not my code yet. --- tests/DirectPlay8Peer.cpp | 1134 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1134 insertions(+) diff --git a/tests/DirectPlay8Peer.cpp b/tests/DirectPlay8Peer.cpp index 18cf7fd..fa2f880 100644 --- a/tests/DirectPlay8Peer.cpp +++ b/tests/DirectPlay8Peer.cpp @@ -7921,3 +7921,1137 @@ TEST(DirectPlay8Peer, TerminateSession) peer1.expect_end(); host.expect_end(); } + +TEST(DirectPlay8Peer, CreateGroupSync) +{ + const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + DPN_APPLICATION_DESC app_desc; + memset(&app_desc, 0, sizeof(app_desc)); + + app_desc.dwSize = sizeof(app_desc); + app_desc.guidApplication = APP_GUID_1; + app_desc.pwszSessionName = L"Session 1"; + + IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT); + + TestPeer host("host"); + ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK); + + IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT); + + TestPeer peer1("peer1"); + ASSERT_EQ(peer1->Connect( + &app_desc, /* pdnAppDesc */ + connect_addr, /* pHostAddr */ + NULL, /* pDeviceInfo */ + NULL, /* pdnSecurity */ + NULL, /* pdnCredentials */ + NULL, /* pvUserConnectData */ + 0, /* dwUserConnectDataSize */ + 0, /* pvPlayerContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCONNECT_SYNC /* dwFlags */ + ), S_OK); + + Sleep(100); + + DPNID h_cg_dpnidGroup; + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->dwSize, sizeof(DPNMSG_CREATE_GROUP)); + EXPECT_EQ(cg->pvGroupContext, (void*)(0x9876)); + + h_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPNID p1_cg_dpnidGroup; + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->dwSize, sizeof(DPNMSG_CREATE_GROUP)); + EXPECT_EQ(cg->pvGroupContext, (void*)(NULL)); + + p1_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPN_GROUP_INFO group_info; + memset(&group_info, 0, sizeof(group_info)); + + group_info.dwSize = sizeof(group_info); + group_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA; + group_info.pwszName = L"Test Group"; + group_info.pvData = (void*)(GROUP_DATA); + group_info.dwDataSize = sizeof(GROUP_DATA); + group_info.dwGroupFlags = 0; + + ASSERT_EQ(host->CreateGroup( + &group_info, /* pdpnGroupInfo */ + (void*)(0x9876), /* pvGroupContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCREATEGROUP_SYNC), /* dwFlags */ + S_OK); + + Sleep(250); + + peer1.expect_end(); + host.expect_end(); + + EXPECT_EQ(h_cg_dpnidGroup, p1_cg_dpnidGroup); + + { + DWORD num_groups = 0; + EXPECT_EQ(host->EnumPlayersAndGroups(NULL, &num_groups, DPNENUM_GROUPS), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_groups, 1); + + DPNID group; + num_groups = 1; + EXPECT_EQ(host->EnumPlayersAndGroups(&group, &num_groups, DPNENUM_GROUPS), S_OK); + EXPECT_EQ(num_groups, 1); + EXPECT_EQ(group, h_cg_dpnidGroup); + + DPNID groups[2]; + num_groups = 2; + EXPECT_EQ(host->EnumPlayersAndGroups(groups, &num_groups, DPNENUM_GROUPS), S_OK); + EXPECT_EQ(num_groups, 1); + EXPECT_EQ(groups[0], h_cg_dpnidGroup); + } + + { + DWORD num_groups = 0; + EXPECT_EQ(peer1->EnumPlayersAndGroups(NULL, &num_groups, DPNENUM_GROUPS), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_groups, 1); + + DPNID group; + num_groups = 1; + EXPECT_EQ(peer1->EnumPlayersAndGroups(&group, &num_groups, DPNENUM_GROUPS), S_OK); + EXPECT_EQ(num_groups, 1); + EXPECT_EQ(group, h_cg_dpnidGroup); + + DPNID groups[2]; + num_groups = 2; + EXPECT_EQ(peer1->EnumPlayersAndGroups(groups, &num_groups, DPNENUM_GROUPS), S_OK); + EXPECT_EQ(num_groups, 1); + EXPECT_EQ(groups[0], h_cg_dpnidGroup); + } +} + +TEST(DirectPlay8Peer, CreateGroupAsync) +{ + const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + DPN_APPLICATION_DESC app_desc; + memset(&app_desc, 0, sizeof(app_desc)); + + app_desc.dwSize = sizeof(app_desc); + app_desc.guidApplication = APP_GUID_1; + app_desc.pwszSessionName = L"Session 1"; + + IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT); + + TestPeer host("host"); + ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK); + + IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT); + + TestPeer peer1("peer1"); + ASSERT_EQ(peer1->Connect( + &app_desc, /* pdnAppDesc */ + connect_addr, /* pHostAddr */ + NULL, /* pDeviceInfo */ + NULL, /* pdnSecurity */ + NULL, /* pdnCredentials */ + NULL, /* pvUserConnectData */ + 0, /* dwUserConnectDataSize */ + 0, /* pvPlayerContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCONNECT_SYNC /* dwFlags */ + ), S_OK); + + Sleep(100); + + DPNID h_cg_dpnidGroup; + DPNHANDLE handle; + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->dwSize, sizeof(DPNMSG_CREATE_GROUP)); + EXPECT_EQ(cg->pvGroupContext, (void*)(0x9876)); + + h_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + host.expect_push([&handle](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ASYNC_OP_COMPLETE); + if(dwMessageType == DPN_MSGID_ASYNC_OP_COMPLETE) + { + DPNMSG_ASYNC_OP_COMPLETE *oc = (DPNMSG_ASYNC_OP_COMPLETE*)(pMessage); + + EXPECT_EQ(oc->dwSize, sizeof(DPNMSG_ASYNC_OP_COMPLETE)); + EXPECT_EQ(oc->hAsyncOp, handle); + EXPECT_EQ(oc->pvUserContext, (void*)(0x5432)); + EXPECT_EQ(oc->hResultCode, S_OK); + } + + return S_OK; + }); + + DPNID p1_cg_dpnidGroup; + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->dwSize, sizeof(DPNMSG_CREATE_GROUP)); + EXPECT_EQ(cg->pvGroupContext, (void*)(NULL)); + + p1_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPN_GROUP_INFO group_info; + memset(&group_info, 0, sizeof(group_info)); + + group_info.dwSize = sizeof(group_info); + group_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA; + group_info.pwszName = L"Test Group"; + group_info.pvData = (void*)(GROUP_DATA); + group_info.dwDataSize = sizeof(GROUP_DATA); + group_info.dwGroupFlags = 0; + + ASSERT_EQ(host->CreateGroup( + &group_info, /* pdpnGroupInfo */ + (void*)(0x9876), /* pvGroupContext */ + (void*)(0x5432), /* pvAsyncContext */ + &handle, /* phAsyncHandle */ + 0), /* dwFlags */ + DPNSUCCESS_PENDING); + + Sleep(250); + + peer1.expect_end(); + host.expect_end(); + + EXPECT_EQ(h_cg_dpnidGroup, p1_cg_dpnidGroup); + + { + DWORD num_groups = 0; + EXPECT_EQ(host->EnumPlayersAndGroups(NULL, &num_groups, DPNENUM_GROUPS), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_groups, 1); + + DPNID groups[2]; + num_groups = 2; + EXPECT_EQ(host->EnumPlayersAndGroups(groups, &num_groups, DPNENUM_GROUPS), S_OK); + EXPECT_EQ(num_groups, 1); + EXPECT_EQ(groups[0], h_cg_dpnidGroup); + } + + { + DWORD num_groups = 0; + EXPECT_EQ(peer1->EnumPlayersAndGroups(NULL, &num_groups, DPNENUM_GROUPS), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_groups, 1); + + DPNID groups[2]; + num_groups = 2; + EXPECT_EQ(peer1->EnumPlayersAndGroups(groups, &num_groups, DPNENUM_GROUPS), S_OK); + EXPECT_EQ(num_groups, 1); + EXPECT_EQ(groups[0], h_cg_dpnidGroup); + } +} + +TEST(DirectPlay8Peer, CreateGroupBeforeJoin) +{ + const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + DPN_APPLICATION_DESC app_desc; + memset(&app_desc, 0, sizeof(app_desc)); + + app_desc.dwSize = sizeof(app_desc); + app_desc.guidApplication = APP_GUID_1; + app_desc.pwszSessionName = L"Session 1"; + + IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT); + + TestPeer host("host"); + ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK); + + Sleep(100); + + DPNID h_cg_dpnidGroup; + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->dwSize, sizeof(DPNMSG_CREATE_GROUP)); + EXPECT_EQ(cg->pvGroupContext, (void*)(0x9876)); + + h_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPN_GROUP_INFO group_info; + memset(&group_info, 0, sizeof(group_info)); + + group_info.dwSize = sizeof(group_info); + group_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA; + group_info.pwszName = L"Test Group"; + group_info.pvData = (void*)(GROUP_DATA); + group_info.dwDataSize = sizeof(GROUP_DATA); + group_info.dwGroupFlags = 0; + + ASSERT_EQ(host->CreateGroup( + &group_info, /* pdpnGroupInfo */ + (void*)(0x9876), /* pvGroupContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCREATEGROUP_SYNC), /* dwFlags */ + S_OK); + + host.expect_end(); + + { + DWORD num_groups = 0; + EXPECT_EQ(host->EnumPlayersAndGroups(NULL, &num_groups, DPNENUM_GROUPS), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_groups, 1); + + DPNID groups[2]; + num_groups = 2; + EXPECT_EQ(host->EnumPlayersAndGroups(groups, &num_groups, DPNENUM_GROUPS), S_OK); + EXPECT_EQ(num_groups, 1); + EXPECT_EQ(groups[0], h_cg_dpnidGroup); + } + + IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT); + + TestPeer peer1("peer1"); + + DPNID p1_cg_dpnidGroup; + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->dwSize, sizeof(DPNMSG_CREATE_GROUP)); + EXPECT_EQ(cg->pvGroupContext, (void*)(NULL)); + + p1_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + peer1.expect_push([&host](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER); + return S_OK; + }); + peer1.expect_push([&host](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER); + return S_OK; + }); + peer1.expect_push([&host](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CONNECT_COMPLETE); + return S_OK; + }); + + ASSERT_EQ(peer1->Connect( + &app_desc, /* pdnAppDesc */ + connect_addr, /* pHostAddr */ + NULL, /* pDeviceInfo */ + NULL, /* pdnSecurity */ + NULL, /* pdnCredentials */ + NULL, /* pvUserConnectData */ + 0, /* dwUserConnectDataSize */ + 0, /* pvPlayerContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCONNECT_SYNC /* dwFlags */ + ), S_OK); + + Sleep(250); + + peer1.expect_end(); + + EXPECT_EQ(h_cg_dpnidGroup, p1_cg_dpnidGroup); + + { + DWORD num_groups = 0; + EXPECT_EQ(peer1->EnumPlayersAndGroups(NULL, &num_groups, DPNENUM_GROUPS), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_groups, 1); + + DPNID groups[2]; + num_groups = 2; + EXPECT_EQ(peer1->EnumPlayersAndGroups(groups, &num_groups, DPNENUM_GROUPS), S_OK); + EXPECT_EQ(num_groups, 1); + EXPECT_EQ(groups[0], h_cg_dpnidGroup); + } +} + +TEST(DirectPlay8Peer, AddPlayerToGroupSync) +{ + const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + DPN_APPLICATION_DESC app_desc; + memset(&app_desc, 0, sizeof(app_desc)); + + app_desc.dwSize = sizeof(app_desc); + app_desc.guidApplication = APP_GUID_1; + app_desc.pwszSessionName = L"Session 1"; + + IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT); + + TestPeer host("host"); + ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK); + + IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT); + + TestPeer peer1("peer1"); + ASSERT_EQ(peer1->Connect( + &app_desc, /* pdnAppDesc */ + connect_addr, /* pHostAddr */ + NULL, /* pDeviceInfo */ + NULL, /* pdnSecurity */ + NULL, /* pdnCredentials */ + NULL, /* pvUserConnectData */ + 0, /* dwUserConnectDataSize */ + 0, /* pvPlayerContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCONNECT_SYNC /* dwFlags */ + ), S_OK); + + Sleep(100); + + DPNID h_cg_dpnidGroup; + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->pvGroupContext, (void*)(0x9876)); + cg->pvGroupContext = (void*)(0xABCD); + + h_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPNID p1_cg_dpnidGroup; + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->pvGroupContext, (void*)(NULL)); + cg->pvGroupContext = (void*)(0xBCDE); + + p1_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPN_GROUP_INFO group_info; + memset(&group_info, 0, sizeof(group_info)); + + group_info.dwSize = sizeof(group_info); + group_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA; + group_info.pwszName = L"Test Group"; + group_info.pvData = (void*)(GROUP_DATA); + group_info.dwDataSize = sizeof(GROUP_DATA); + group_info.dwGroupFlags = 0; + + ASSERT_EQ(host->CreateGroup( + &group_info, /* pdpnGroupInfo */ + (void*)(0x9876), /* pvGroupContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCREATEGROUP_SYNC), /* dwFlags */ + S_OK); + + Sleep(250); + + peer1.expect_end(); + host.expect_end(); + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ADD_PLAYER_TO_GROUP); + if(dwMessageType == DPN_MSGID_ADD_PLAYER_TO_GROUP) + { + DPNMSG_ADD_PLAYER_TO_GROUP *ap = (DPNMSG_ADD_PLAYER_TO_GROUP*)(pMessage); + + EXPECT_EQ(ap->dwSize, sizeof(DPNMSG_ADD_PLAYER_TO_GROUP)); + EXPECT_EQ(ap->dpnidGroup, h_cg_dpnidGroup); + EXPECT_EQ(ap->pvGroupContext, (void*)(0xABCD)); + EXPECT_EQ(ap->dpnidPlayer, host.first_cp_dpnidPlayer); + EXPECT_EQ(ap->pvPlayerContext, (void*)~(uintptr_t)(host.first_cp_dpnidPlayer)); + } + + return S_OK; + }); + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ADD_PLAYER_TO_GROUP); + if(dwMessageType == DPN_MSGID_ADD_PLAYER_TO_GROUP) + { + DPNMSG_ADD_PLAYER_TO_GROUP *ap = (DPNMSG_ADD_PLAYER_TO_GROUP*)(pMessage); + + EXPECT_EQ(ap->dwSize, sizeof(DPNMSG_ADD_PLAYER_TO_GROUP)); + EXPECT_EQ(ap->dpnidGroup, p1_cg_dpnidGroup); + EXPECT_EQ(ap->pvGroupContext, (void*)(0xBCDE)); + EXPECT_EQ(ap->dpnidPlayer, host.first_cp_dpnidPlayer); + EXPECT_EQ(ap->pvPlayerContext, (void*)~(uintptr_t)(host.first_cp_dpnidPlayer)); + } + + return S_OK; + }); + + ASSERT_EQ(host->AddPlayerToGroup( + h_cg_dpnidGroup, /* idGroup */ + host.first_cp_dpnidPlayer, /* idClient */ + (void*)(0x8765), /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNADDPLAYERTOGROUP_SYNC), /* dwFlags */ + S_OK); + + Sleep(250); + + peer1.expect_end(); + host.expect_end(); + + { + DWORD num_members = 0; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, NULL, &num_members, 0), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_members, 1); + + DPNID member; + num_members = 1; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, &member, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(member, host.first_cp_dpnidPlayer); + + DPNID members[2]; + num_members = 2; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, members, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(members[0], host.first_cp_dpnidPlayer); + } + + { + DWORD num_members = 0; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, NULL, &num_members, 0), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_members, 1); + + DPNID member; + num_members = 1; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, &member, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(member, host.first_cp_dpnidPlayer); + + DPNID members[2]; + num_members = 2; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, members, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(members[0], host.first_cp_dpnidPlayer); + } +} + +TEST(DirectPlay8Peer, AddPlayerToGroupAsync) +{ + const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + DPN_APPLICATION_DESC app_desc; + memset(&app_desc, 0, sizeof(app_desc)); + + app_desc.dwSize = sizeof(app_desc); + app_desc.guidApplication = APP_GUID_1; + app_desc.pwszSessionName = L"Session 1"; + + IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT); + + TestPeer host("host"); + ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK); + + IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT); + + TestPeer peer1("peer1"); + ASSERT_EQ(peer1->Connect( + &app_desc, /* pdnAppDesc */ + connect_addr, /* pHostAddr */ + NULL, /* pDeviceInfo */ + NULL, /* pdnSecurity */ + NULL, /* pdnCredentials */ + NULL, /* pvUserConnectData */ + 0, /* dwUserConnectDataSize */ + 0, /* pvPlayerContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCONNECT_SYNC /* dwFlags */ + ), S_OK); + + Sleep(100); + + DPNID h_cg_dpnidGroup; + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->pvGroupContext, (void*)(0x9876)); + cg->pvGroupContext = (void*)(0xABCD); + + h_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPNID p1_cg_dpnidGroup; + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->pvGroupContext, (void*)(NULL)); + cg->pvGroupContext = (void*)(0xBCDE); + + p1_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPN_GROUP_INFO group_info; + memset(&group_info, 0, sizeof(group_info)); + + group_info.dwSize = sizeof(group_info); + group_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA; + group_info.pwszName = L"Test Group"; + group_info.pvData = (void*)(GROUP_DATA); + group_info.dwDataSize = sizeof(GROUP_DATA); + group_info.dwGroupFlags = 0; + + ASSERT_EQ(host->CreateGroup( + &group_info, /* pdpnGroupInfo */ + (void*)(0x9876), /* pvGroupContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCREATEGROUP_SYNC), /* dwFlags */ + S_OK); + + Sleep(250); + + peer1.expect_end(); + host.expect_end(); + + DPNHANDLE handle; + + host.expect_begin(); + host.expect_push([&peer1, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ADD_PLAYER_TO_GROUP); + if(dwMessageType == DPN_MSGID_ADD_PLAYER_TO_GROUP) + { + DPNMSG_ADD_PLAYER_TO_GROUP *ap = (DPNMSG_ADD_PLAYER_TO_GROUP*)(pMessage); + + EXPECT_EQ(ap->dwSize, sizeof(DPNMSG_ADD_PLAYER_TO_GROUP)); + EXPECT_EQ(ap->dpnidGroup, h_cg_dpnidGroup); + EXPECT_EQ(ap->pvGroupContext, (void*)(0xABCD)); + EXPECT_EQ(ap->dpnidPlayer, peer1.first_cc_dpnidLocal); + EXPECT_EQ(ap->pvPlayerContext, (void*)~(uintptr_t)(peer1.first_cc_dpnidLocal)); + } + + return S_OK; + }); + host.expect_push([&handle](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ASYNC_OP_COMPLETE); + if(dwMessageType == DPN_MSGID_ASYNC_OP_COMPLETE) + { + DPNMSG_ASYNC_OP_COMPLETE *oc = (DPNMSG_ASYNC_OP_COMPLETE*)(pMessage); + + EXPECT_EQ(oc->dwSize, sizeof(DPNMSG_ASYNC_OP_COMPLETE)); + EXPECT_EQ(oc->hAsyncOp, handle); + EXPECT_EQ(oc->pvUserContext, (void*)(0x8765)); + EXPECT_EQ(oc->hResultCode, S_OK); + } + + return S_OK; + }); + + peer1.expect_begin(); + peer1.expect_push([&peer1, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ADD_PLAYER_TO_GROUP); + if(dwMessageType == DPN_MSGID_ADD_PLAYER_TO_GROUP) + { + DPNMSG_ADD_PLAYER_TO_GROUP *ap = (DPNMSG_ADD_PLAYER_TO_GROUP*)(pMessage); + + EXPECT_EQ(ap->dwSize, sizeof(DPNMSG_ADD_PLAYER_TO_GROUP)); + EXPECT_EQ(ap->dpnidGroup, p1_cg_dpnidGroup); + EXPECT_EQ(ap->pvGroupContext, (void*)(0xBCDE)); + EXPECT_EQ(ap->dpnidPlayer, peer1.first_cc_dpnidLocal); + EXPECT_EQ(ap->pvPlayerContext, (void*)~(uintptr_t)(peer1.first_cc_dpnidLocal)); + } + + return S_OK; + }); + + ASSERT_EQ(host->AddPlayerToGroup( + h_cg_dpnidGroup, /* idGroup */ + peer1.first_cc_dpnidLocal, /* idClient */ + (void*)(0x8765), /* pvAsyncContext */ + &handle, /* phAsyncHandle */ + 0), /* dwFlags */ + DPNSUCCESS_PENDING); + + Sleep(250); + + peer1.expect_end(); + host.expect_end(); + + { + DWORD num_members = 0; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, NULL, &num_members, 0), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_members, 1); + + DPNID members[2]; + num_members = 2; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, members, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(members[0], peer1.first_cc_dpnidLocal); + } + + { + DWORD num_members = 0; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, NULL, &num_members, 0), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_members, 1); + + DPNID members[2]; + num_members = 2; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, members, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(members[0], peer1.first_cc_dpnidLocal); + } +} + +TEST(DirectPlay8Peer, AddPlayerToGroupBeforeJoin) +{ + const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + DPN_APPLICATION_DESC app_desc; + memset(&app_desc, 0, sizeof(app_desc)); + + app_desc.dwSize = sizeof(app_desc); + app_desc.guidApplication = APP_GUID_1; + app_desc.pwszSessionName = L"Session 1"; + + IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT); + + TestPeer host("host"); + ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK); + + DPNID h_cg_dpnidGroup; + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->pvGroupContext, (void*)(0x9876)); + cg->pvGroupContext = (void*)(0xABCD); + + h_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPN_GROUP_INFO group_info; + memset(&group_info, 0, sizeof(group_info)); + + group_info.dwSize = sizeof(group_info); + group_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA; + group_info.pwszName = L"Test Group"; + group_info.pvData = (void*)(GROUP_DATA); + group_info.dwDataSize = sizeof(GROUP_DATA); + group_info.dwGroupFlags = 0; + + ASSERT_EQ(host->CreateGroup( + &group_info, /* pdpnGroupInfo */ + (void*)(0x9876), /* pvGroupContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCREATEGROUP_SYNC), /* dwFlags */ + S_OK); + + host.expect_end(); + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ADD_PLAYER_TO_GROUP); + if(dwMessageType == DPN_MSGID_ADD_PLAYER_TO_GROUP) + { + DPNMSG_ADD_PLAYER_TO_GROUP *ap = (DPNMSG_ADD_PLAYER_TO_GROUP*)(pMessage); + + EXPECT_EQ(ap->dwSize, sizeof(DPNMSG_ADD_PLAYER_TO_GROUP)); + EXPECT_EQ(ap->dpnidGroup, h_cg_dpnidGroup); + EXPECT_EQ(ap->pvGroupContext, (void*)(0xABCD)); + EXPECT_EQ(ap->dpnidPlayer, host.first_cp_dpnidPlayer); + EXPECT_EQ(ap->pvPlayerContext, (void*)~(uintptr_t)(host.first_cp_dpnidPlayer)); + } + + return S_OK; + }); + + ASSERT_EQ(host->AddPlayerToGroup( + h_cg_dpnidGroup, /* idGroup */ + host.first_cp_dpnidPlayer, /* idClient */ + (void*)(0x8765), /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNADDPLAYERTOGROUP_SYNC), /* dwFlags */ + S_OK); + + host.expect_end(); + + Sleep(250); + + { + DWORD num_members = 0; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, NULL, &num_members, 0), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_members, 1); + + DPNID members[2]; + num_members = 2; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, members, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(members[0], host.first_cp_dpnidPlayer); + } + + TestPeer peer1("peer1"); + + DPNID p1_cg_dpnidGroup; + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->pvGroupContext, (void*)(NULL)); + cg->pvGroupContext = (void*)(0xBCDE); + + p1_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + peer1.expect_push([&host](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER); + return S_OK; + }); + peer1.expect_push([&host](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER); + return S_OK; + }); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ADD_PLAYER_TO_GROUP); + if(dwMessageType == DPN_MSGID_ADD_PLAYER_TO_GROUP) + { + DPNMSG_ADD_PLAYER_TO_GROUP *ap = (DPNMSG_ADD_PLAYER_TO_GROUP*)(pMessage); + + EXPECT_EQ(ap->dwSize, sizeof(DPNMSG_ADD_PLAYER_TO_GROUP)); + EXPECT_EQ(ap->dpnidGroup, p1_cg_dpnidGroup); + EXPECT_EQ(ap->pvGroupContext, (void*)(0xBCDE)); + EXPECT_EQ(ap->dpnidPlayer, host.first_cp_dpnidPlayer); + EXPECT_EQ(ap->pvPlayerContext, (void*)(NULL)); + } + + return S_OK; + }); + peer1.expect_push([&host](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CONNECT_COMPLETE); + return S_OK; + }); + + IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT); + ASSERT_EQ(peer1->Connect( + &app_desc, /* pdnAppDesc */ + connect_addr, /* pHostAddr */ + NULL, /* pDeviceInfo */ + NULL, /* pdnSecurity */ + NULL, /* pdnCredentials */ + NULL, /* pvUserConnectData */ + 0, /* dwUserConnectDataSize */ + 0, /* pvPlayerContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCONNECT_SYNC /* dwFlags */ + ), S_OK); + + Sleep(250); + + peer1.expect_end(); + + { + DWORD num_members = 0; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, NULL, &num_members, 0), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_members, 1); + + DPNID members[2]; + num_members = 2; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, members, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(members[0], host.first_cp_dpnidPlayer); + } +} + +TEST(DirectPlay8Peer, AddPlayerToGroupByPeer) +{ + const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; + + DPN_APPLICATION_DESC app_desc; + memset(&app_desc, 0, sizeof(app_desc)); + + app_desc.dwSize = sizeof(app_desc); + app_desc.guidApplication = APP_GUID_1; + app_desc.pwszSessionName = L"Session 1"; + + IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT); + + TestPeer host("host"); + ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK); + + IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT); + + TestPeer peer1("peer1"); + ASSERT_EQ(peer1->Connect( + &app_desc, /* pdnAppDesc */ + connect_addr, /* pHostAddr */ + NULL, /* pDeviceInfo */ + NULL, /* pdnSecurity */ + NULL, /* pdnCredentials */ + NULL, /* pvUserConnectData */ + 0, /* dwUserConnectDataSize */ + 0, /* pvPlayerContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCONNECT_SYNC /* dwFlags */ + ), S_OK); + + Sleep(100); + + DPNID h_cg_dpnidGroup; + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->pvGroupContext, (void*)(0x9876)); + cg->pvGroupContext = (void*)(0xABCD); + + h_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPNID p1_cg_dpnidGroup; + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP); + if(dwMessageType == DPN_MSGID_CREATE_GROUP) + { + DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage); + + EXPECT_EQ(cg->pvGroupContext, (void*)(NULL)); + cg->pvGroupContext = (void*)(0xBCDE); + + p1_cg_dpnidGroup = cg->dpnidGroup; + } + + return S_OK; + }); + + DPN_GROUP_INFO group_info; + memset(&group_info, 0, sizeof(group_info)); + + group_info.dwSize = sizeof(group_info); + group_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA; + group_info.pwszName = L"Test Group"; + group_info.pvData = (void*)(GROUP_DATA); + group_info.dwDataSize = sizeof(GROUP_DATA); + group_info.dwGroupFlags = 0; + + ASSERT_EQ(host->CreateGroup( + &group_info, /* pdpnGroupInfo */ + (void*)(0x9876), /* pvGroupContext */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNCREATEGROUP_SYNC), /* dwFlags */ + S_OK); + + Sleep(250); + + peer1.expect_end(); + host.expect_end(); + + host.expect_begin(); + host.expect_push([&host, &h_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ADD_PLAYER_TO_GROUP); + if(dwMessageType == DPN_MSGID_ADD_PLAYER_TO_GROUP) + { + DPNMSG_ADD_PLAYER_TO_GROUP *ap = (DPNMSG_ADD_PLAYER_TO_GROUP*)(pMessage); + + EXPECT_EQ(ap->dwSize, sizeof(DPNMSG_ADD_PLAYER_TO_GROUP)); + EXPECT_EQ(ap->dpnidGroup, h_cg_dpnidGroup); + EXPECT_EQ(ap->pvGroupContext, (void*)(0xABCD)); + EXPECT_EQ(ap->dpnidPlayer, host.first_cp_dpnidPlayer); + EXPECT_EQ(ap->pvPlayerContext, (void*)~(uintptr_t)(host.first_cp_dpnidPlayer)); + } + + return S_OK; + }); + + peer1.expect_begin(); + peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage) + { + EXPECT_EQ(dwMessageType, DPN_MSGID_ADD_PLAYER_TO_GROUP); + if(dwMessageType == DPN_MSGID_ADD_PLAYER_TO_GROUP) + { + DPNMSG_ADD_PLAYER_TO_GROUP *ap = (DPNMSG_ADD_PLAYER_TO_GROUP*)(pMessage); + + EXPECT_EQ(ap->dwSize, sizeof(DPNMSG_ADD_PLAYER_TO_GROUP)); + EXPECT_EQ(ap->dpnidGroup, p1_cg_dpnidGroup); + EXPECT_EQ(ap->pvGroupContext, (void*)(0xBCDE)); + EXPECT_EQ(ap->dpnidPlayer, host.first_cp_dpnidPlayer); + EXPECT_EQ(ap->pvPlayerContext, (void*)~(uintptr_t)(host.first_cp_dpnidPlayer)); + } + + return S_OK; + }); + + ASSERT_EQ(peer1->AddPlayerToGroup( + p1_cg_dpnidGroup, /* idGroup */ + host.first_cp_dpnidPlayer, /* idClient */ + NULL, /* pvAsyncContext */ + NULL, /* phAsyncHandle */ + DPNADDPLAYERTOGROUP_SYNC), /* dwFlags */ + S_OK); + + Sleep(250); + + peer1.expect_end(); + host.expect_end(); + + { + DWORD num_members = 0; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, NULL, &num_members, 0), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_members, 1); + + DPNID members[2]; + num_members = 2; + EXPECT_EQ(host->EnumGroupMembers(h_cg_dpnidGroup, members, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(members[0], host.first_cp_dpnidPlayer); + } + + { + DWORD num_members = 0; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, NULL, &num_members, 0), DPNERR_BUFFERTOOSMALL); + EXPECT_EQ(num_members, 1); + + DPNID members[2]; + num_members = 2; + EXPECT_EQ(peer1->EnumGroupMembers(p1_cg_dpnidGroup, members, &num_members, 0), S_OK); + EXPECT_EQ(num_members, 1); + EXPECT_EQ(members[0], host.first_cp_dpnidPlayer); + } +}