diff --git a/Makefile b/Makefile index c4f22eb..d3e8ec0 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,21 @@ CXX := i686-w64-mingw32-g++ CXXFLAGS := -std=c++11 -Wall +TEST_CXXFLAGS := $(CXXFLAGS) -I./googletest/include/ + all: dpnet.dll dpnet.dll: src/dpnet.o src/dpnet.def src/DirectPlay8Address.o src/DirectPlay8Peer.o $(CXX) $(CXXFLAGS) -Wl,--enable-stdcall-fixup -shared -o $@ $^ -ldxguid -static-libstdc++ -static-libgcc -%.o: %.cpp +tests/DirectPlay8Address.exe: tests/DirectPlay8Address.o src/DirectPlay8Address.o googletest/src/gtest-all.o googletest/src/gtest_main.o + $(CXX) $(TEST_CXXFLAGS) -o $@ $^ -ldxguid -lole32 -static-libstdc++ -static-libgcc + +src/%.o: src/%.cpp $(CXX) $(CXXFLAGS) -c -o $@ $< + +tests/%.o: tests/%.cpp + $(CXX) $(TEST_CXXFLAGS) -c -o $@ $< + +googletest/src/%.o: googletest/src/%.cc + $(CXX) $(TEST_CXXFLAGS) -I./googletest/ -c -o $@ $< diff --git a/src/DirectPlay8Address.cpp b/src/DirectPlay8Address.cpp index 743d6ba..1c323d4 100644 --- a/src/DirectPlay8Address.cpp +++ b/src/DirectPlay8Address.cpp @@ -203,7 +203,8 @@ HRESULT DirectPlay8Address::SetUserData(CONST void* CONST pvUserData, CONST DWOR HRESULT DirectPlay8Address::GetNumComponents(PDWORD pdwNumComponents) { - return components.size(); + *pdwNumComponents = components.size(); + return S_OK; } HRESULT DirectPlay8Address::GetComponentByName(CONST WCHAR* CONST pwszName, LPVOID pvBuffer, PDWORD pdwBufferSize, PDWORD pdwDataType) @@ -339,7 +340,7 @@ DirectPlay8Address::Component::Component(const std::wstring &name, DWORD type): DirectPlay8Address::Component::~Component() {} DirectPlay8Address::StringComponentW::StringComponentW(const std::wstring &name, const wchar_t *lpvData, DWORD dwDataSize): - Component(name, DPNA_DATATYPE_STRING), value(lpvData, dwDataSize) {} + Component(name, DPNA_DATATYPE_STRING), value(lpvData, dwDataSize / sizeof(wchar_t)) {} DirectPlay8Address::Component *DirectPlay8Address::StringComponentW::clone() { @@ -350,14 +351,14 @@ HRESULT DirectPlay8Address::StringComponentW::get_component(LPVOID pvBuffer, PDW { *pdwDataType = DPNA_DATATYPE_STRING; - if(*pdwBufferSize > value.length() && pvBuffer != NULL) + if(*pdwBufferSize >= (value.length() * sizeof(wchar_t)) && pvBuffer != NULL) { - wcscpy((wchar_t*)(pvBuffer), value.c_str()); - *pdwBufferSize = value.length() + 1; + wcsncpy((wchar_t*)(pvBuffer), value.data(), value.length()); + *pdwBufferSize = value.length() * sizeof(wchar_t); return S_OK; } else{ - *pdwBufferSize = value.length() + 1; + *pdwBufferSize = value.length() * sizeof(wchar_t); return DPNERR_BUFFERTOOSMALL; } } diff --git a/tests/DirectPlay8Address.cpp b/tests/DirectPlay8Address.cpp new file mode 100644 index 0000000..5dce47b --- /dev/null +++ b/tests/DirectPlay8Address.cpp @@ -0,0 +1,201 @@ +#include + +#include "../src/DirectPlay8Address.hpp" + +// #define INSTANTIATE_FROM_COM + +class DirectPlay8AddressInitial: public ::testing::Test { + private: + DirectPlay8Address *addr; + + protected: + IDirectPlay8Address *idp8; + + DirectPlay8AddressInitial() + { + #ifdef INSTANTIATE_FROM_COM + CoInitialize(NULL); + CoCreateInstance(CLSID_DirectPlay8Address, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Address, (void**)(&idp8)); + #else + addr = new DirectPlay8Address(NULL); + idp8 = addr; + #endif + } + + ~DirectPlay8AddressInitial() + { + #ifdef INSTANTIATE_FROM_COM + idp8->Release(); + CoUninitialize(); + #else + delete addr; + #endif + } +}; + +TEST_F(DirectPlay8AddressInitial, HasNoComponents) +{ + DWORD num; + ASSERT_EQ(idp8->GetNumComponents(&num), S_OK); + EXPECT_EQ(num, (DWORD)(0)); +} + +class DirectPlay8AddressWithWStringComponent: public DirectPlay8AddressInitial +{ + protected: + const wchar_t *REFKEY = L"key"; + const DWORD REFKSIZE = 4; + + const wchar_t *REFVAL = L"wide string value"; + const DWORD REFVSIZE = 18 * sizeof(wchar_t); + + wchar_t kbuf[256]; + unsigned char vbuf[256]; + + virtual void SetUp() override + { + memset(kbuf, 0xFF, sizeof(kbuf)); + memset(vbuf, 0xFF, sizeof(vbuf)); + + ASSERT_EQ(idp8->AddComponent(REFKEY, REFVAL, REFVSIZE, DPNA_DATATYPE_STRING), S_OK); + } +}; + +TEST_F(DirectPlay8AddressWithWStringComponent, HasOneComponent) +{ + DWORD num; + ASSERT_EQ(idp8->GetNumComponents(&num), S_OK); + EXPECT_EQ(num, (DWORD)(1)); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByIndexNameSizeZero) +{ + DWORD ksize = 0; + DWORD vsize = REFVSIZE; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByIndex(0, (wchar_t*)(kbuf), &ksize, (void*)(vbuf), &vsize, &type), DPNERR_BUFFERTOOSMALL); + + EXPECT_EQ(ksize, REFKSIZE); + EXPECT_EQ(vsize, REFVSIZE); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByIndexBufferSizeZero) +{ + DWORD ksize = REFKSIZE; + DWORD vsize = 0; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByIndex(0, (wchar_t*)(kbuf), &ksize, (void*)(vbuf), &vsize, &type), DPNERR_BUFFERTOOSMALL); + + EXPECT_EQ(ksize, REFKSIZE); + EXPECT_EQ(vsize, REFVSIZE); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByIndexNameSizeSmall) +{ + DWORD ksize = REFKSIZE - 1; + DWORD vsize = REFVSIZE; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByIndex(0, (wchar_t*)(kbuf), &ksize, (void*)(vbuf), &vsize, &type), DPNERR_BUFFERTOOSMALL); + + EXPECT_EQ(ksize, REFKSIZE); + EXPECT_EQ(vsize, REFVSIZE); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByIndexBufferSizeSmall) +{ + DWORD ksize = REFKSIZE; + DWORD vsize = REFVSIZE - 1; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByIndex(0, (wchar_t*)(kbuf), &ksize, (void*)(vbuf), &vsize, &type), DPNERR_BUFFERTOOSMALL); + + EXPECT_EQ(ksize, REFKSIZE); + EXPECT_EQ(vsize, REFVSIZE); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByIndexSizeExact) +{ + DWORD ksize = REFKSIZE; + DWORD vsize = REFVSIZE; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByIndex(0, (wchar_t*)(kbuf), &ksize, (void*)(vbuf), &vsize, &type), S_OK); + + EXPECT_EQ(ksize, REFKSIZE); + EXPECT_EQ(vsize, REFVSIZE); + EXPECT_EQ(type, (DWORD)(DPNA_DATATYPE_STRING)); + + EXPECT_EQ(std::wstring((const wchar_t*)(kbuf), ksize), std::wstring(REFKEY, REFKSIZE)); + + EXPECT_EQ(std::wstring((const wchar_t*)(vbuf), (vsize / sizeof(wchar_t))), + std::wstring(REFVAL, (REFVSIZE / sizeof(wchar_t)))); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByIndexSizeBig) +{ + DWORD ksize = REFKSIZE * 2; + DWORD vsize = REFVSIZE * 2; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByIndex(0, (wchar_t*)(kbuf), &ksize, (void*)(vbuf), &vsize, &type), S_OK); + + EXPECT_EQ(ksize, REFKSIZE); + EXPECT_EQ(vsize, REFVSIZE); + EXPECT_EQ(type, (DWORD)(DPNA_DATATYPE_STRING)); + + EXPECT_EQ(std::wstring((const wchar_t*)(kbuf), ksize), std::wstring(REFKEY, REFKSIZE)); + + EXPECT_EQ(std::wstring((const wchar_t*)(vbuf), (vsize / sizeof(wchar_t))), + std::wstring(REFVAL, (REFVSIZE / sizeof(wchar_t)))); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByNameBufferSizeZero) +{ + DWORD vsize = 0; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByName(REFKEY, NULL, &vsize, &type), DPNERR_BUFFERTOOSMALL); + + EXPECT_EQ(vsize, REFVSIZE); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByNameBufferSizeSmall) +{ + DWORD vsize = REFVSIZE - 1; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByName(REFKEY, (void*)(vbuf), &vsize, &type), DPNERR_BUFFERTOOSMALL); + + EXPECT_EQ(vsize, REFVSIZE); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByNameBufferSizeExact) +{ + DWORD vsize = REFVSIZE; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByName(REFKEY, (void*)(vbuf), &vsize, &type), S_OK); + + EXPECT_EQ(vsize, REFVSIZE); + EXPECT_EQ(type, (DWORD)(DPNA_DATATYPE_STRING)); + + EXPECT_EQ(std::wstring((const wchar_t*)(vbuf), (vsize / sizeof(wchar_t))), + std::wstring(REFVAL, (REFVSIZE / sizeof(wchar_t)))); +} + +TEST_F(DirectPlay8AddressWithWStringComponent, ComponentByNameBufferSizeBig) +{ + DWORD vsize = REFVSIZE * 2; + DWORD type; + + ASSERT_EQ(idp8->GetComponentByName(REFKEY, (void*)(vbuf), &vsize, &type), S_OK); + + EXPECT_EQ(vsize, REFVSIZE); + EXPECT_EQ(type, (DWORD)(DPNA_DATATYPE_STRING)); + + EXPECT_EQ(std::wstring((const wchar_t*)(vbuf), (vsize / sizeof(wchar_t))), + std::wstring(REFVAL, (REFVSIZE / sizeof(wchar_t)))); +}