diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5985931 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +CXX := i686-w64-mingw32-g++ +CXXFLAGS := -std=c++11 -Wall + +all: dpnet.dll + +dpnet.dll: src/dpnet.o src/dpnet.def src/DirectPlay8Peer.o + $(CXX) $(CXXFLAGS) -Wl,--enable-stdcall-fixup -shared -o $@ $^ -ldxguid -static-libstdc++ -static-libgcc + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< diff --git a/src/DirectPlay8Peer.cpp b/src/DirectPlay8Peer.cpp new file mode 100644 index 0000000..ed2a91a --- /dev/null +++ b/src/DirectPlay8Peer.cpp @@ -0,0 +1,230 @@ +#include +#include +#include +#include +#include + +#include "DirectPlay8Peer.hpp" + +#define UNIMPLEMENTED(fmt, ...) \ + fprintf(stderr, "Unimplemented method: " fmt "\n", ## __VA_ARGS__); \ + return E_NOTIMPL; + +DirectPlay8Peer::DirectPlay8Peer(std::atomic *global_refcount): + global_refcount(global_refcount), + local_refcount(0) +{ + AddRef(); +} + +HRESULT DirectPlay8Peer::QueryInterface(REFIID riid, void **ppvObject) +{ + if(riid == IID_IDirectPlay8Peer || riid == IID_IUnknown) + { + *((IUnknown**)(ppvObject)) = this; + AddRef(); + + return S_OK; + } + else{ + return E_NOINTERFACE; + } +} + +ULONG DirectPlay8Peer::AddRef(void) +{ + if(global_refcount != NULL) + { + ++(*global_refcount); + } + + return ++local_refcount; +} + +ULONG DirectPlay8Peer::Release(void) +{ + std::atomic *global_refcount = this->global_refcount; + + ULONG rc = --local_refcount; + if(rc == 0) + { + delete this; + } + + if(global_refcount != NULL) + { + --(*global_refcount); + } + + return rc; +} + +HRESULT DirectPlay8Peer::Initialize(PVOID CONST pvUserContext, CONST PFNDPNMESSAGEHANDLER pfn, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::Initialize"); +} + +HRESULT DirectPlay8Peer::EnumServiceProviders(CONST GUID* CONST pguidServiceProvider, CONST GUID* CONST pguidApplication, DPN_SERVICE_PROVIDER_INFO* CONST pSPInfoBuffer, DWORD* CONST pcbEnumData, DWORD* CONST pcReturned, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::EnumServiceProviders"); +} + +HRESULT DirectPlay8Peer::CancelAsyncOperation(CONST DPNHANDLE hAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::CancelAsyncOperation"); +} + +HRESULT DirectPlay8Peer::Connect(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDirectPlay8Address* CONST pHostAddr, IDirectPlay8Address* CONST pDeviceInfo, CONST DPN_SECURITY_DESC* CONST pdnSecurity, CONST DPN_SECURITY_CREDENTIALS* CONST pdnCredentials, CONST void* CONST pvUserConnectData, CONST DWORD dwUserConnectDataSize, void* CONST pvPlayerContext, void* CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::Connect"); +} + +HRESULT DirectPlay8Peer::SendTo(CONST DPNID dpnid, CONST DPN_BUFFER_DESC* CONST prgBufferDesc, CONST DWORD cBufferDesc, CONST DWORD dwTimeOut, void* CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::SendTo"); +} + +HRESULT DirectPlay8Peer::GetSendQueueInfo(CONST DPNID dpnid, DWORD* CONST pdwNumMsgs, DWORD* CONST pdwNumBytes, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetSendQueueInfo"); +} + +HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDirectPlay8Address **CONST prgpDeviceInfo, CONST DWORD cDeviceInfo, CONST DPN_SECURITY_DESC* CONST pdnSecurity, CONST DPN_SECURITY_CREDENTIALS* CONST pdnCredentials, void* CONST pvPlayerContext, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::Host"); +} + +HRESULT DirectPlay8Peer::GetApplicationDesc(DPN_APPLICATION_DESC* CONST pAppDescBuffer, DWORD* CONST pcbDataSize, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetApplicationDesc"); +} + +HRESULT DirectPlay8Peer::SetApplicationDesc(CONST DPN_APPLICATION_DESC* CONST pad, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::SetApplicationDesc"); +} + +HRESULT DirectPlay8Peer::CreateGroup(CONST DPN_GROUP_INFO* CONST pdpnGroupInfo, void* CONST pvGroupContext, void* CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::CreateGroup"); +} + +HRESULT DirectPlay8Peer::DestroyGroup(CONST DPNID idGroup, PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::DestroyGroup"); +} + +HRESULT DirectPlay8Peer::AddPlayerToGroup(CONST DPNID idGroup, CONST DPNID idClient, PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::AddPlayerToGroup"); +} + +HRESULT DirectPlay8Peer::RemovePlayerFromGroup(CONST DPNID idGroup, CONST DPNID idClient, PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::RemovePlayerFromGroup"); +} + +HRESULT DirectPlay8Peer::SetGroupInfo(CONST DPNID dpnid, DPN_GROUP_INFO* CONST pdpnGroupInfo,PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::SetGroupInfo"); +} + +HRESULT DirectPlay8Peer::GetGroupInfo(CONST DPNID dpnid, DPN_GROUP_INFO* CONST pdpnGroupInfo, DWORD* CONST pdwSize, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetGroupInfo"); +} + +HRESULT DirectPlay8Peer::EnumPlayersAndGroups(DPNID* CONST prgdpnid, DWORD* CONST pcdpnid, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::EnumPlayersAndGroups"); +} + +HRESULT DirectPlay8Peer::EnumGroupMembers(CONST DPNID dpnid, DPNID* CONST prgdpnid, DWORD* CONST pcdpnid, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::EnumGroupMembers"); +} + +HRESULT DirectPlay8Peer::SetPeerInfo(CONST DPN_PLAYER_INFO* CONST pdpnPlayerInfo,PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::SetPeerInfo"); +} + +HRESULT DirectPlay8Peer::GetPeerInfo(CONST DPNID dpnid, DPN_PLAYER_INFO* CONST pdpnPlayerInfo, DWORD* CONST pdwSize, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetPeerInfo"); +} + +HRESULT DirectPlay8Peer::GetPeerAddress(CONST DPNID dpnid, IDirectPlay8Address** CONST pAddress, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetPeerAddress"); +} + +HRESULT DirectPlay8Peer::GetLocalHostAddresses(IDirectPlay8Address** CONST prgpAddress, DWORD* CONST pcAddress, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetLocalHostAddresses"); +} + +HRESULT DirectPlay8Peer::Close(CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::Close"); +} + +HRESULT DirectPlay8Peer::EnumHosts(PDPN_APPLICATION_DESC CONST pApplicationDesc, IDirectPlay8Address* CONST pAddrHost, IDirectPlay8Address* CONST pDeviceInfo,PVOID CONST pUserEnumData, CONST DWORD dwUserEnumDataSize, CONST DWORD dwEnumCount, CONST DWORD dwRetryInterval, CONST DWORD dwTimeOut,PVOID CONST pvUserContext, DPNHANDLE* CONST pAsyncHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::EnumHosts"); +} + +HRESULT DirectPlay8Peer::DestroyPeer(CONST DPNID dpnidClient, CONST void* CONST pvDestroyData, CONST DWORD dwDestroyDataSize, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::DestroyPeer"); +} + +HRESULT DirectPlay8Peer::ReturnBuffer(CONST DPNHANDLE hBufferHandle, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::ReturnBuffer"); +} + +HRESULT DirectPlay8Peer::GetPlayerContext(CONST DPNID dpnid,PVOID* CONST ppvPlayerContext, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetPlayerContext"); +} + +HRESULT DirectPlay8Peer::GetGroupContext(CONST DPNID dpnid,PVOID* CONST ppvGroupContext, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetGroupContext"); +} + +HRESULT DirectPlay8Peer::GetCaps(DPN_CAPS* CONST pdpCaps, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetCaps"); +} + +HRESULT DirectPlay8Peer::SetCaps(CONST DPN_CAPS* CONST pdpCaps, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::SetCaps"); +} + +HRESULT DirectPlay8Peer::SetSPCaps(CONST GUID* CONST pguidSP, CONST DPN_SP_CAPS* CONST pdpspCaps, CONST DWORD dwFlags ) +{ + UNIMPLEMENTED("DirectPlay8Peer::SetSPCaps"); +} + +HRESULT DirectPlay8Peer::GetSPCaps(CONST GUID* CONST pguidSP, DPN_SP_CAPS* CONST pdpspCaps, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetSPCaps"); +} + +HRESULT DirectPlay8Peer::GetConnectionInfo(CONST DPNID dpnid, DPN_CONNECTION_INFO* CONST pdpConnectionInfo, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::GetConnectionInfo"); +} + +HRESULT DirectPlay8Peer::RegisterLobby(CONST DPNHANDLE dpnHandle, struct IDirectPlay8LobbiedApplication* CONST pIDP8LobbiedApplication, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::RegisterLobby"); +} + +HRESULT DirectPlay8Peer::TerminateSession(void* CONST pvTerminateData, CONST DWORD dwTerminateDataSize, CONST DWORD dwFlags) +{ + UNIMPLEMENTED("DirectPlay8Peer::TerminateSession"); +} diff --git a/src/DirectPlay8Peer.hpp b/src/DirectPlay8Peer.hpp new file mode 100644 index 0000000..2e218ff --- /dev/null +++ b/src/DirectPlay8Peer.hpp @@ -0,0 +1,60 @@ +#ifndef DPLITE_DIRECTPLAY8PEER_HPP +#define DPLITE_DIRECTPLAY8PEER_HPP + +#include +#include +#include + +class DirectPlay8Peer: public IDirectPlay8Peer +{ + private: + std::atomic * const global_refcount; + ULONG local_refcount; + + public: + DirectPlay8Peer(std::atomic *global_refcount); + virtual ~DirectPlay8Peer() {} + + /* IUnknown */ + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; + virtual ULONG STDMETHODCALLTYPE AddRef(void) override; + virtual ULONG STDMETHODCALLTYPE Release(void) override; + + /* IDirectPlay8Peer */ + virtual HRESULT STDMETHODCALLTYPE Initialize(PVOID CONST pvUserContext, CONST PFNDPNMESSAGEHANDLER pfn, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE EnumServiceProviders(CONST GUID* CONST pguidServiceProvider, CONST GUID* CONST pguidApplication, DPN_SERVICE_PROVIDER_INFO* CONST pSPInfoBuffer, DWORD* CONST pcbEnumData, DWORD* CONST pcReturned, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE CancelAsyncOperation(CONST DPNHANDLE hAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE Connect(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDirectPlay8Address* CONST pHostAddr, IDirectPlay8Address* CONST pDeviceInfo, CONST DPN_SECURITY_DESC* CONST pdnSecurity, CONST DPN_SECURITY_CREDENTIALS* CONST pdnCredentials, CONST void* CONST pvUserConnectData, CONST DWORD dwUserConnectDataSize, void* CONST pvPlayerContext, void* CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE SendTo(CONST DPNID dpnid, CONST DPN_BUFFER_DESC* CONST prgBufferDesc, CONST DWORD cBufferDesc, CONST DWORD dwTimeOut, void* CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetSendQueueInfo(CONST DPNID dpnid, DWORD* CONST pdwNumMsgs, DWORD* CONST pdwNumBytes, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDirectPlay8Address **CONST prgpDeviceInfo, CONST DWORD cDeviceInfo, CONST DPN_SECURITY_DESC* CONST pdnSecurity, CONST DPN_SECURITY_CREDENTIALS* CONST pdnCredentials, void* CONST pvPlayerContext, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetApplicationDesc(DPN_APPLICATION_DESC* CONST pAppDescBuffer, DWORD* CONST pcbDataSize, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE SetApplicationDesc(CONST DPN_APPLICATION_DESC* CONST pad, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE CreateGroup(CONST DPN_GROUP_INFO* CONST pdpnGroupInfo, void* CONST pvGroupContext, void* CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE DestroyGroup(CONST DPNID idGroup, PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE AddPlayerToGroup(CONST DPNID idGroup, CONST DPNID idClient, PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE RemovePlayerFromGroup(CONST DPNID idGroup, CONST DPNID idClient, PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE SetGroupInfo(CONST DPNID dpnid, DPN_GROUP_INFO* CONST pdpnGroupInfo,PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetGroupInfo(CONST DPNID dpnid, DPN_GROUP_INFO* CONST pdpnGroupInfo, DWORD* CONST pdwSize, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE EnumPlayersAndGroups(DPNID* CONST prgdpnid, DWORD* CONST pcdpnid, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE EnumGroupMembers(CONST DPNID dpnid, DPNID* CONST prgdpnid, DWORD* CONST pcdpnid, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE SetPeerInfo(CONST DPN_PLAYER_INFO* CONST pdpnPlayerInfo,PVOID CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetPeerInfo(CONST DPNID dpnid, DPN_PLAYER_INFO* CONST pdpnPlayerInfo, DWORD* CONST pdwSize, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetPeerAddress(CONST DPNID dpnid, IDirectPlay8Address** CONST pAddress, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetLocalHostAddresses(IDirectPlay8Address** CONST prgpAddress, DWORD* CONST pcAddress, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE Close(CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE EnumHosts(PDPN_APPLICATION_DESC CONST pApplicationDesc, IDirectPlay8Address* CONST pAddrHost, IDirectPlay8Address* CONST pDeviceInfo,PVOID CONST pUserEnumData, CONST DWORD dwUserEnumDataSize, CONST DWORD dwEnumCount, CONST DWORD dwRetryInterval, CONST DWORD dwTimeOut,PVOID CONST pvUserContext, DPNHANDLE* CONST pAsyncHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE DestroyPeer(CONST DPNID dpnidClient, CONST void* CONST pvDestroyData, CONST DWORD dwDestroyDataSize, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE ReturnBuffer(CONST DPNHANDLE hBufferHandle, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetPlayerContext(CONST DPNID dpnid,PVOID* CONST ppvPlayerContext, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetGroupContext(CONST DPNID dpnid,PVOID* CONST ppvGroupContext, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetCaps(DPN_CAPS* CONST pdpCaps, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE SetCaps(CONST DPN_CAPS* CONST pdpCaps, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE SetSPCaps(CONST GUID* CONST pguidSP, CONST DPN_SP_CAPS* CONST pdpspCaps, CONST DWORD dwFlags ) override; + virtual HRESULT STDMETHODCALLTYPE GetSPCaps(CONST GUID* CONST pguidSP, DPN_SP_CAPS* CONST pdpspCaps, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE GetConnectionInfo(CONST DPNID dpnid, DPN_CONNECTION_INFO* CONST pdpConnectionInfo, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE RegisterLobby(CONST DPNHANDLE dpnHandle, struct IDirectPlay8LobbiedApplication* CONST pIDP8LobbiedApplication, CONST DWORD dwFlags) override; + virtual HRESULT STDMETHODCALLTYPE TerminateSession(void* CONST pvTerminateData, CONST DWORD dwTerminateDataSize, CONST DWORD dwFlags) override; +}; + +#endif /* !DPLITE_DIRECTPLAY8PEER_HPP */ diff --git a/src/Factory.hpp b/src/Factory.hpp new file mode 100644 index 0000000..a99fbab --- /dev/null +++ b/src/Factory.hpp @@ -0,0 +1,87 @@ +#ifndef DPLITE_FACTORY_HPP +#define DPLITE_FACTORY_HPP + +#include + +template class Factory: public IClassFactory +{ + private: + std::atomic * const global_refcount; + ULONG local_refcount; + + public: + Factory(std::atomic *global_refcount): + global_refcount(global_refcount), + local_refcount(0) + { + AddRef(); + } + + virtual ~Factory() {} + + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override + { + if(riid == IID_IClassFactory || riid == IID_IUnknown) + { + *((IUnknown**)(ppvObject)) = this; + AddRef(); + + return S_OK; + } + else{ + return E_NOINTERFACE; + } + } + + virtual ULONG STDMETHODCALLTYPE AddRef(void) override + { + if(global_refcount != NULL) + { + ++(*global_refcount); + } + + return ++local_refcount; + } + + virtual ULONG STDMETHODCALLTYPE Release(void) override + { + std::atomic *global_refcount = this->global_refcount; + + ULONG rc = --local_refcount; + if(rc == 0) + { + delete this; + } + + if(global_refcount != NULL) + { + --(*global_refcount); + } + + return rc; + } + + virtual HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, const IID &riid, void **ppvObject) override + { + if(pUnkOuter != NULL) + { + return CLASS_E_NOAGGREGATION; + } + + if(riid == IMPLEMENTS || riid == IID_IUnknown) + { + *((IUnknown**)(ppvObject)) = new T(global_refcount); + return S_OK; + } + else{ + return E_NOINTERFACE; + } + } + + virtual HRESULT STDMETHODCALLTYPE LockServer(WINBOOL) override + { + return S_OK; + } +}; + +#endif /* !DPLITE_FACTORY_HPP */ diff --git a/src/dpnet.cpp b/src/dpnet.cpp new file mode 100644 index 0000000..eba9b12 --- /dev/null +++ b/src/dpnet.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +#include "DirectPlay8Peer.hpp" +#include "Factory.hpp" + +/* Sum of refcounts of all created COM objects. */ +static std::atomic global_refcount; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + if(fdwReason == DLL_PROCESS_ATTACH) + { + global_refcount = 0; + } + + return TRUE; +} + +HRESULT CALLBACK DllCanUnloadNow() +{ + return (global_refcount == 0 ? S_OK : S_FALSE); +} + +HRESULT CALLBACK DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + if(riid != IID_IClassFactory && riid != IID_IUnknown) + { + return CLASS_E_CLASSNOTAVAILABLE; + } + + if(rclsid == CLSID_DirectPlay8Peer) + { + *((IUnknown**)(ppv)) = new Factory(&global_refcount); + return S_OK; + } + else{ + return CLASS_E_CLASSNOTAVAILABLE; + } +} diff --git a/src/dpnet.def b/src/dpnet.def new file mode 100644 index 0000000..1d465df --- /dev/null +++ b/src/dpnet.def @@ -0,0 +1,7 @@ +LIBRARY dpnet.dll +EXPORTS + ; DirectPlay8Create @1 + DllCanUnloadNow @2 + DllGetClassObject @3 + ; DllRegisterServer @4 + ; DllUnregisterServer @5