Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

978 lines
24 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: dxglob7obj.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "windows.h"
  11. #include "mmsystem.h"
  12. #include "stdafx.h"
  13. #include "d3d8.h"
  14. #include "d3dx8.h"
  15. #include "Direct.h"
  16. #include "dms.h"
  17. #include "math.h"
  18. #include "dxGlob7Obj.h"
  19. #include "dmusici.h"
  20. #include "dmusicf.h"
  21. #include "dvoice.h"
  22. #include "dxfile.h"
  23. #include "dsoundObj.h"
  24. #include "dsoundCaptureObj.h"
  25. #include "DSEnumObj.h"
  26. #include "DPlayPeerObj.h"
  27. #include "DPlayServerObj.h"
  28. #include "DPlayClientObj.h"
  29. #include "DPlayLobbyClientObj.h"
  30. #include "DPlayLobbiedAppObj.h"
  31. #include "DPlayVoiceClientObj.h"
  32. #include "DPlayVoiceServerObj.h"
  33. #include "DPlayVoiceSetupObj.h"
  34. #include "DPlayAddressObj.h"
  35. #include "dinput1Obj.h"
  36. #include "dmSegmentObj.h"
  37. #include "dmSegmentStateObj.h"
  38. #include "dmChordMapObj.h"
  39. #include "dmBandObj.h"
  40. #include "dmCollectionObj.h"
  41. #include "dmStyleObj.h"
  42. #include "dmPerformanceObj.h"
  43. #include "dmLoaderObj.h"
  44. #include "dmComposerObj.h"
  45. #include "xfileobj.h"
  46. #include "verinfo.h"
  47. extern HINSTANCE g_hDSoundHandle;
  48. extern HINSTANCE g_hDPlay;
  49. extern HINSTANCE g_hInstDINPUTDLL;
  50. extern HINSTANCE g_hInst;
  51. extern HINSTANCE g_hD3D8;
  52. extern HRESULT BSTRtoPPGUID(LPGUID*,BSTR);
  53. extern HRESULT BSTRtoGUID(LPGUID,BSTR);
  54. extern void *g_dxj_DirectMusic;
  55. extern void *g_dxj_DirectMusicLoader;
  56. extern void *g_dxj_DirectMusicComposer;
  57. extern void *g_dxj_DirectMusicPerformance;
  58. extern void *g_dxj_DirectPlay;
  59. extern void *g_dxj_DirectPlayPeer;
  60. extern void *g_dxj_DirectPlayLobbyClient;
  61. extern void *g_dxj_DirectPlayLobbiedApplication;
  62. extern void *g_dxj_DirectPlayServer;
  63. extern void *g_dxj_DirectPlayClient;
  64. extern void *g_dxj_DirectPlayAddress;
  65. extern BSTR GUIDtoBSTR(LPGUID);
  66. extern HRESULT DPLBSTRtoGUID(LPGUID pGuid,BSTR str);
  67. extern HINSTANCE LoadD3D8DLL();
  68. extern HINSTANCE LoadD3DXOFDLL();
  69. extern HINSTANCE LoadDPlayDLL();
  70. extern HINSTANCE LoadDSoundDLL();
  71. extern HINSTANCE LoadDINPUTDLL();
  72. DWORD WINAPI ThreadFunc(LPVOID param);
  73. #ifndef DX_FINAL_RELEASE
  74. // shut 'em down if they try to use the beta bits too long
  75. HRESULT TimeBomb()
  76. {
  77. #pragma message("BETA EXPIRATION TIME BOMB! Remove for final build!")
  78. SYSTEMTIME st;
  79. GetSystemTime(&st);
  80. if ( st.wYear > DX_EXPIRE_YEAR ||
  81. ((st.wYear == DX_EXPIRE_YEAR) && (MAKELONG(st.wDay, st.wMonth) > MAKELONG(DX_EXPIRE_DAY, DX_EXPIRE_MONTH)))
  82. ) {
  83. MessageBox(0, DX_EXPIRE_TEXT,
  84. TEXT("Microsoft DirectX For Visual Basic"), MB_OK);
  85. return S_OK;// let it work anyway.
  86. }
  87. return S_OK;
  88. } // TimeBomb
  89. #endif
  90. C_dxj_DirectX7Object::C_dxj_DirectX7Object(){
  91. m_pDirectSoundCreate=NULL;
  92. m_pDirectSoundEnumerate=NULL;
  93. m_pDirectSoundCaptureEnumerate=NULL;
  94. m_pDirectSoundCaptureCreate=NULL;
  95. m_pDirect3DCreate8=NULL;
  96. m_pEventList=NULL;
  97. }
  98. void C_dxj_DirectX7Object::LoadDSOUND()
  99. {
  100. if (!g_hDSoundHandle ) LoadDSoundDLL();
  101. if (!m_pDirectSoundCreate) m_pDirectSoundCreate = (DSOUNDCREATE)GetProcAddress( g_hDSoundHandle, "DirectSoundCreate8" );
  102. if (!m_pDirectSoundCaptureCreate) m_pDirectSoundCaptureCreate = (DSOUNDCAPTURECREATE)GetProcAddress( g_hDSoundHandle, "DirectSoundCaptureCreate" );
  103. if (!m_pDirectSoundEnumerate) m_pDirectSoundEnumerate = (DSOUNDENUMERATE)GetProcAddress( g_hDSoundHandle, "DirectSoundEnumerateA" );
  104. if (!m_pDirectSoundCaptureEnumerate) m_pDirectSoundCaptureEnumerate = (DSOUNDCAPTUREENUMERATE)GetProcAddress( g_hDSoundHandle, "DirectSoundCaptureEnumerateA" );
  105. }
  106. void C_dxj_DirectX7Object::LoadD3D8()
  107. {
  108. if (!g_hD3D8 ) LoadD3D8DLL();
  109. if (!m_pDirect3DCreate8) m_pDirect3DCreate8 = (D3DCREATE8)GetProcAddress( g_hD3D8, "Direct3DCreate8" );
  110. }
  111. C_dxj_DirectX7Object::~C_dxj_DirectX7Object()
  112. {
  113. DWORD i=1;
  114. while (m_pEventList) {
  115. #ifdef _WIN64
  116. destroyEvent((HANDLE)m_pEventList->hEvent);
  117. #else
  118. destroyEvent((LONG)PtrToLong(m_pEventList->hEvent));
  119. #endif
  120. }
  121. }
  122. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayVoiceClientCreate(I_dxj_DirectPlayVoiceClient **ret){
  123. HRESULT hr;
  124. LPDIRECTPLAYVOICECLIENT realvoice=NULL;
  125. DWORD i=0;
  126. #ifndef DX_FINAL_RELEASE
  127. hr = TimeBomb();
  128. if (FAILED(hr))
  129. {
  130. return E_FAIL;
  131. }
  132. #endif
  133. if( FAILED(hr = CoCreateInstance(CLSID_DirectPlayVoiceClient,NULL,
  134. CLSCTX_INPROC_SERVER,
  135. IID_IDirectPlayVoiceClient,
  136. (LPVOID*) &realvoice)))
  137. return hr;
  138. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayVoiceClient,realvoice,ret);
  139. if (*ret==NULL) {
  140. i=realvoice->Release();
  141. return E_FAIL;
  142. }
  143. return hr;
  144. }
  145. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayLobbyClientCreate(I_dxj_DirectPlayLobbyClient **ret) {
  146. HRESULT hr;
  147. IDirectPlay8LobbyClient *realLC=NULL;
  148. #ifndef DX_FINAL_RELEASE
  149. hr = TimeBomb();
  150. if (FAILED(hr))
  151. {
  152. return E_FAIL;
  153. }
  154. #endif
  155. if( FAILED(hr = CoCreateInstance(CLSID_DirectPlay8LobbyClient,NULL,
  156. CLSCTX_INPROC_SERVER,
  157. IID_IDirectPlay8LobbyClient,
  158. (void**) &realLC)))
  159. return hr;
  160. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayLobbyClient,realLC,ret);
  161. if (*ret==NULL) {
  162. realLC->Release();
  163. return E_FAIL;
  164. }
  165. return hr;
  166. }
  167. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayLobbiedApplicationCreate(I_dxj_DirectPlayLobbiedApplication **ret) {
  168. HRESULT hr;
  169. IDirectPlay8LobbiedApplication *realLA=NULL;
  170. #ifndef DX_FINAL_RELEASE
  171. hr = TimeBomb();
  172. if (FAILED(hr))
  173. {
  174. return E_FAIL;
  175. }
  176. #endif
  177. if( FAILED(hr = CoCreateInstance(CLSID_DirectPlay8LobbiedApplication,NULL,
  178. CLSCTX_INPROC_SERVER,
  179. IID_IDirectPlay8LobbiedApplication,
  180. (void**) &realLA)))
  181. return hr;
  182. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayLobbiedApplication,realLA,ret);
  183. if (*ret==NULL) {
  184. realLA->Release();
  185. return E_FAIL;
  186. }
  187. return hr;
  188. }
  189. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayVoiceServerCreate(I_dxj_DirectPlayVoiceServer **ret){
  190. HRESULT hr;
  191. LPDIRECTPLAYVOICESERVER realvoice=NULL;
  192. DWORD i=0;
  193. #ifndef DX_FINAL_RELEASE
  194. hr = TimeBomb();
  195. if (FAILED(hr))
  196. {
  197. return E_FAIL;
  198. }
  199. #endif
  200. if( FAILED(hr = CoCreateInstance(CLSID_DirectPlayVoiceServer,NULL,
  201. CLSCTX_INPROC_SERVER,
  202. IID_IDirectPlayVoiceServer,
  203. (LPVOID*) &realvoice)))
  204. return hr;
  205. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayVoiceServer,realvoice,ret);
  206. if (*ret==NULL) {
  207. i=realvoice->Release();
  208. return E_FAIL;
  209. }
  210. return hr;
  211. }
  212. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayVoiceTestCreate(I_dxj_DirectPlayVoiceSetup **ret){
  213. HRESULT hr;
  214. LPDIRECTPLAYVOICETEST realsetup=NULL;
  215. DWORD i=0;
  216. #ifndef DX_FINAL_RELEASE
  217. hr = TimeBomb();
  218. if (FAILED(hr))
  219. {
  220. return E_FAIL;
  221. }
  222. #endif
  223. if( FAILED(hr = CoCreateInstance(CLSID_DirectPlayVoiceTest,NULL,
  224. CLSCTX_INPROC_SERVER,
  225. IID_IDirectPlayVoiceTest,
  226. (LPVOID*) &realsetup)))
  227. return hr;
  228. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayVoiceSetup,realsetup,ret);
  229. if (*ret==NULL) {
  230. i=realsetup->Release();
  231. return E_FAIL;
  232. }
  233. return hr;
  234. }
  235. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayPeerCreate(I_dxj_DirectPlayPeer **ret)
  236. {
  237. HRESULT hr;
  238. IDirectPlay8Peer *lpDplayPeer = NULL;
  239. #ifndef DX_FINAL_RELEASE
  240. hr = TimeBomb();
  241. if (FAILED(hr))
  242. {
  243. return E_FAIL;
  244. }
  245. #endif
  246. if ( FAILED (hr = CoCreateInstance( CLSID_DirectPlay8Peer, NULL,CLSCTX_INPROC_SERVER,
  247. IID_IDirectPlay8Peer, (LPVOID*) &lpDplayPeer ) ) )
  248. return hr;
  249. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayPeer, lpDplayPeer, ret);
  250. if (*ret == NULL)
  251. {
  252. lpDplayPeer->Release();
  253. return E_FAIL;
  254. }
  255. return hr;
  256. }
  257. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayServerCreate(I_dxj_DirectPlayServer **ret)
  258. {
  259. HRESULT hr;
  260. IDirectPlay8Server *lpDplayServer = NULL;
  261. #ifndef DX_FINAL_RELEASE
  262. hr = TimeBomb();
  263. if (FAILED(hr))
  264. {
  265. return E_FAIL;
  266. }
  267. #endif
  268. if ( FAILED (hr = CoCreateInstance( CLSID_DirectPlay8Server, NULL,CLSCTX_INPROC_SERVER,
  269. IID_IDirectPlay8Server, (LPVOID*) &lpDplayServer ) ) )
  270. return hr;
  271. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayServer, lpDplayServer, ret);
  272. if (*ret == NULL)
  273. {
  274. lpDplayServer->Release();
  275. return E_FAIL;
  276. }
  277. return hr;
  278. }
  279. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayAddressCreate(I_dxj_DirectPlayAddress **ret)
  280. {
  281. HRESULT hr;
  282. IDirectPlay8Address *lpDplayAddress = NULL;
  283. #ifndef DX_FINAL_RELEASE
  284. hr = TimeBomb();
  285. if (FAILED(hr))
  286. {
  287. return E_FAIL;
  288. }
  289. #endif
  290. if ( FAILED (hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL,CLSCTX_INPROC_SERVER,
  291. IID_IDirectPlay8Address, (LPVOID*) &lpDplayAddress ) ) )
  292. return hr;
  293. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayAddress, lpDplayAddress, ret);
  294. if (*ret == NULL)
  295. {
  296. lpDplayAddress->Release();
  297. return E_FAIL;
  298. }
  299. return hr;
  300. }
  301. STDMETHODIMP C_dxj_DirectX7Object::DirectPlayClientCreate(I_dxj_DirectPlayClient **ret)
  302. {
  303. HRESULT hr;
  304. IDirectPlay8Client *lpDplayClient = NULL;
  305. #ifndef DX_FINAL_RELEASE
  306. hr = TimeBomb();
  307. if (FAILED(hr))
  308. {
  309. return E_FAIL;
  310. }
  311. #endif
  312. if ( FAILED (hr = CoCreateInstance( CLSID_DirectPlay8Client, NULL,CLSCTX_INPROC_SERVER,
  313. IID_IDirectPlay8Client, (LPVOID*) &lpDplayClient ) ) )
  314. return hr;
  315. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayClient, lpDplayClient, ret);
  316. if (*ret == NULL)
  317. {
  318. lpDplayClient->Release();
  319. return E_FAIL;
  320. }
  321. return hr;
  322. }
  323. STDMETHODIMP C_dxj_DirectX7Object::directSoundCreate(BSTR strGuid, I_dxj_DirectSound **ret){
  324. HRESULT hr;
  325. LPDIRECTSOUND8 realsound8=NULL;
  326. GUID guid;
  327. LPGUID pguid=&guid;
  328. #ifndef DX_FINAL_RELEASE
  329. hr = TimeBomb();
  330. if (FAILED(hr))
  331. {
  332. return E_FAIL;
  333. }
  334. #endif
  335. LoadDSOUND();
  336. hr=BSTRtoPPGUID(&pguid,strGuid);
  337. if FAILED(hr) return hr;
  338. if (!m_pDirectSoundCreate) return E_FAIL;
  339. hr=(m_pDirectSoundCreate)((GUID*)pguid,&realsound8,NULL);
  340. if FAILED(hr) return hr;
  341. INTERNAL_CREATE(_dxj_DirectSound,realsound8,ret);
  342. if (*ret==NULL) {
  343. realsound8->Release();
  344. return E_FAIL;
  345. }
  346. return hr;
  347. }
  348. STDMETHODIMP C_dxj_DirectX7Object::directSoundCaptureCreate(BSTR strGuid, I_dxj_DirectSoundCapture **ret){
  349. HRESULT hr;
  350. LPDIRECTSOUNDCAPTURE realsound1=NULL;
  351. LPDIRECTSOUNDCAPTURE8 realsound8=NULL;
  352. GUID guid;
  353. LPGUID pguid=&guid;
  354. hr=BSTRtoPPGUID(&pguid,strGuid);
  355. if FAILED(hr) return hr;
  356. #ifndef DX_FINAL_RELEASE
  357. hr = TimeBomb();
  358. if (FAILED(hr))
  359. {
  360. return E_FAIL;
  361. }
  362. #endif
  363. LoadDSOUND();
  364. if (!m_pDirectSoundCaptureCreate) return E_FAIL;
  365. hr=(m_pDirectSoundCaptureCreate)(pguid,&realsound1,NULL);
  366. if FAILED(hr) return hr;
  367. // I'm getting No Such interface on this call. - BUG
  368. hr=realsound1->QueryInterface(IID_IDirectSoundCapture8,(void**)&realsound8);
  369. realsound1->Release();
  370. if FAILED(hr) return hr;
  371. INTERNAL_CREATE(_dxj_DirectSoundCapture,realsound8,ret);
  372. if (*ret==NULL) {
  373. realsound8->Release();
  374. return E_FAIL;
  375. }
  376. if (*ret==NULL) {
  377. realsound1->Release();
  378. return E_FAIL;
  379. }
  380. return hr;
  381. }
  382. STDMETHODIMP C_dxj_DirectX7Object::getDSCaptureEnum( I_dxj_DSEnum **retVal)
  383. {
  384. HRESULT hr;
  385. #ifndef DX_FINAL_RELEASE
  386. hr = TimeBomb();
  387. if (FAILED(hr))
  388. {
  389. return E_FAIL;
  390. }
  391. #endif
  392. LoadDSOUND();
  393. if (!m_pDirectSoundCaptureEnumerate) return E_FAIL;
  394. hr=C_dxj_DSEnumObject::create(NULL,m_pDirectSoundCaptureEnumerate,retVal);
  395. return hr;
  396. }
  397. /////////////////////////////////////////////////////////////////////////////
  398. STDMETHODIMP C_dxj_DirectX7Object::getDSEnum( I_dxj_DSEnum **retVal)
  399. {
  400. HRESULT hr;
  401. #ifndef DX_FINAL_RELEASE
  402. hr = TimeBomb();
  403. if (FAILED(hr))
  404. {
  405. return E_FAIL;
  406. }
  407. #endif
  408. LoadDSOUND();
  409. if (!m_pDirectSoundEnumerate) return E_FAIL;
  410. hr=C_dxj_DSEnumObject::create(m_pDirectSoundEnumerate,NULL,retVal);
  411. return hr;
  412. }
  413. ////////////////////////////////////////////////////////////////
  414. STDMETHODIMP C_dxj_DirectX7Object::directInputCreate(I_dxj_DirectInput8 **ret){
  415. HRESULT hr;
  416. #ifndef DX_FINAL_RELEASE
  417. hr = TimeBomb();
  418. if (FAILED(hr))
  419. {
  420. return E_FAIL;
  421. }
  422. #endif
  423. LoadDINPUTDLL();
  424. //DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);
  425. static HRESULT (WINAPI *ProcAdd)(HINSTANCE , DWORD , REFIID , LPVOID *, LPUNKNOWN)=NULL;
  426. if (ProcAdd==NULL){
  427. if (g_hInstDINPUTDLL==NULL) return E_NOINTERFACE;
  428. ProcAdd = (HRESULT (WINAPI *)(HINSTANCE , DWORD , REFIID , LPVOID *, LPUNKNOWN)) GetProcAddress(g_hInstDINPUTDLL, "DirectInput8Create");
  429. if (ProcAdd==NULL) return E_FAIL;
  430. }
  431. LPDIRECTINPUT8W lpInput8=NULL;
  432. hr= (ProcAdd)(g_hInst,(DWORD)DIRECTINPUT_VERSION,IID_IDirectInput8W,(void**)&lpInput8,NULL);
  433. if FAILED(hr) return hr;
  434. INTERNAL_CREATE(_dxj_DirectInput8,lpInput8,ret);
  435. return hr;
  436. }
  437. // STDMETHODIMP C_dxj_DirectX7Object::systemBpp(long *retval)
  438. // {
  439. // HDC hdc;
  440. //
  441. // hdc = ::GetDC(NULL);
  442. // *retval = GetDeviceCaps(hdc, BITSPIXEL);
  443. // ::ReleaseDC(NULL, hdc);
  444. //
  445. // return S_OK;
  446. // }
  447. STDMETHODIMP C_dxj_DirectX7Object::directMusicLoaderCreate (
  448. /* [retval][out] */ I_dxj_DirectMusicLoader __RPC_FAR *__RPC_FAR *ret)
  449. {
  450. HRESULT hr;
  451. #ifndef DX_FINAL_RELEASE
  452. hr = TimeBomb();
  453. if (FAILED(hr))
  454. {
  455. return E_FAIL;
  456. }
  457. #endif
  458. IDirectMusicLoader8 *pLoader=NULL;
  459. hr =CoCreateInstance(
  460. CLSID_DirectMusicLoader,
  461. NULL,
  462. CLSCTX_INPROC,
  463. IID_IDirectMusicLoader8,
  464. (void**)&pLoader);
  465. if (FAILED(hr)) return E_NOINTERFACE;
  466. if (!pLoader) return E_FAIL;
  467. INTERNAL_CREATE_NOADDREF(_dxj_DirectMusicLoader,pLoader,ret);
  468. return S_OK;
  469. }
  470. STDMETHODIMP C_dxj_DirectX7Object::directMusicComposerCreate (
  471. /* [retval][out] */ I_dxj_DirectMusicComposer __RPC_FAR *__RPC_FAR *ret)
  472. {
  473. IDirectMusicComposer8 *pComp=NULL;
  474. HRESULT hr;
  475. #ifndef DX_FINAL_RELEASE
  476. hr = TimeBomb();
  477. if (FAILED(hr))
  478. {
  479. return E_FAIL;
  480. }
  481. #endif
  482. if (FAILED(CoCreateInstance(
  483. CLSID_DirectMusicComposer,
  484. NULL,
  485. CLSCTX_INPROC,
  486. IID_IDirectMusicComposer8,
  487. (void**)&pComp ))) {
  488. return E_NOINTERFACE;
  489. }
  490. if (!pComp) return E_FAIL;
  491. INTERNAL_CREATE_NOADDREF(_dxj_DirectMusicComposer,pComp,ret);
  492. return S_OK;
  493. }
  494. STDMETHODIMP C_dxj_DirectX7Object::directMusicPerformanceCreate (
  495. /* [retval][out] */ I_dxj_DirectMusicPerformance __RPC_FAR *__RPC_FAR *ret)
  496. {
  497. IDirectMusicPerformance8 *pPerf=NULL;
  498. HRESULT hr;
  499. #ifndef DX_FINAL_RELEASE
  500. hr = TimeBomb();
  501. if (FAILED(hr))
  502. {
  503. return E_FAIL;
  504. }
  505. #endif
  506. if (FAILED(CoCreateInstance(
  507. CLSID_DirectMusicPerformance,
  508. NULL,
  509. CLSCTX_INPROC,
  510. IID_IDirectMusicPerformance8,
  511. (void**)&pPerf ))) {
  512. return E_NOINTERFACE;
  513. }
  514. if (!pPerf) return E_FAIL;
  515. INTERNAL_CREATE_NOADDREF(_dxj_DirectMusicPerformance,pPerf,ret);
  516. return S_OK;
  517. }
  518. #ifdef _WIN64
  519. STDMETHODIMP C_dxj_DirectX7Object::createEvent(
  520. /* [in] */ I_dxj_DirectXEvent8 __RPC_FAR *event,
  521. /* [retval][out] */ HANDLE __RPC_FAR *h)
  522. #else
  523. STDMETHODIMP C_dxj_DirectX7Object::createEvent(
  524. /* [in] */ I_dxj_DirectXEvent8 __RPC_FAR *event,
  525. /* [retval][out] */ LONG __RPC_FAR *h)
  526. #endif
  527. {
  528. HRESULT hr;
  529. LPSTREAM pStm=NULL;
  530. IUnknown *pUnk=NULL;
  531. HANDLE hEvent=NULL;
  532. EVENTTHREADINFO *pNewEvent=NULL;
  533. EVENTTHREADINFO *pTemp=NULL;
  534. if (!event) return E_INVALIDARG;
  535. if (!h) return E_INVALIDARG;
  536. pNewEvent=(EVENTTHREADINFO*)malloc(sizeof(EVENTTHREADINFO));
  537. if (!pNewEvent) return E_OUTOFMEMORY;
  538. ZeroMemory(pNewEvent, sizeof(EVENTTHREADINFO));
  539. pNewEvent->pNext=NULL;
  540. pNewEvent->fEnd=FALSE;
  541. pNewEvent->pCallback=event;
  542. pNewEvent->pStream=NULL;
  543. event->AddRef();
  544. pNewEvent->hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  545. if (!pNewEvent->hEvent){
  546. free(pNewEvent);
  547. event->Release();
  548. return E_FAIL;
  549. }
  550. //pNewEvent->hEndEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  551. hr=event->QueryInterface(IID_IUnknown,(void**)&pUnk);
  552. if FAILED(hr) {
  553. free(pNewEvent);
  554. event->Release();
  555. return E_FAIL;
  556. }
  557. hr=CoMarshalInterThreadInterfaceInStream(IID_IUnknown,pUnk,&pStm);
  558. if (pUnk) pUnk->Release();
  559. if FAILED(hr) {
  560. free(pNewEvent);
  561. event->Release();
  562. return E_FAIL;
  563. }
  564. pNewEvent->pStream=pStm;
  565. pNewEvent->hThread=CreateThread(NULL,0,ThreadFunc,(unsigned long*)pNewEvent,CREATE_SUSPENDED ,&pNewEvent->threadID);
  566. if (!pNewEvent->threadID) {
  567. CloseHandle(pNewEvent->hEvent);
  568. free(pNewEvent);
  569. event->Release();
  570. return E_FAIL;
  571. }
  572. if (!m_pEventList){
  573. m_pEventList=pNewEvent;
  574. }
  575. else{
  576. pTemp=m_pEventList;
  577. m_pEventList=pNewEvent;
  578. pNewEvent->pNext=pTemp;
  579. }
  580. ResumeThread(pNewEvent->hThread);
  581. #ifdef _WIN64
  582. *h=(pNewEvent->hEvent);
  583. #else
  584. *h=(LONG)PtrToLong(pNewEvent->hEvent);
  585. #endif
  586. return S_OK;
  587. }
  588. #ifdef _WIN64
  589. STDMETHODIMP C_dxj_DirectX7Object::setEvent(
  590. /* [in] */ HANDLE eventId)
  591. {
  592. SetEvent(eventId);
  593. return S_OK;
  594. }
  595. #else
  596. STDMETHODIMP C_dxj_DirectX7Object::setEvent(
  597. /* [in] */ LONG eventId)
  598. {
  599. SetEvent((HANDLE)eventId);
  600. return S_OK;
  601. }
  602. #endif
  603. #ifdef _WIN64
  604. STDMETHODIMP C_dxj_DirectX7Object::destroyEvent(
  605. /* [in] */ HANDLE eventId)
  606. #else
  607. STDMETHODIMP C_dxj_DirectX7Object::destroyEvent(
  608. /* [in] */ LONG eventId)
  609. #endif
  610. {
  611. //find the info on the stack
  612. if (!m_pEventList) return E_INVALIDARG;
  613. EVENTTHREADINFO *pTemp=NULL;
  614. EVENTTHREADINFO *pLast=NULL;
  615. //rely on lazy evaluation
  616. for (pTemp=m_pEventList; ((pTemp)&&(pTemp->hEvent!=(HANDLE)eventId));pLast=pTemp,pTemp=pTemp->pNext);
  617. if (!pTemp) return E_INVALIDARG;
  618. //remove it from our Link List
  619. if (!pLast) {
  620. m_pEventList=pTemp->pNext;
  621. }
  622. else {
  623. pLast->pNext=pTemp->pNext;
  624. }
  625. //indicate that we want to kill the thread
  626. pTemp->fEnd=TRUE;
  627. //Fire the event in case we are waiting
  628. if (pTemp->hEvent) SetEvent(pTemp->hEvent);
  629. //Wait for it to finish out
  630. if (pTemp->hThread) WaitForSingleObject(pTemp->hThread,1000);
  631. //wait for the end event to signal
  632. //if (pTemp->hEndEvent) WaitForSingleObject(pTemp->hEndEvent,1000);
  633. //desctroy the event
  634. if (pTemp->hEvent) CloseHandle(pTemp->hEvent);
  635. //if (pTemp->hEndEvent) CloseHandle (pTemp->hEndEvent);
  636. if (pTemp->pCallback) pTemp->pCallback->Release();
  637. //thread is gone..
  638. //free the memory
  639. free(pTemp);
  640. return S_OK;
  641. }
  642. DWORD WINAPI ThreadFunc(LPVOID param){
  643. HRESULT hr;
  644. IUnknown *pUnk=NULL;
  645. EVENTTHREADINFO *pCntrl=(EVENTTHREADINFO *)param;
  646. I_dxj_DirectXEvent8 *pVBCallback=NULL;
  647. OleInitialize(NULL);
  648. LCID LOCAL_SYSTEM_DEFAULT=GetSystemDefaultLCID();
  649. //note pstrm is released even on failure
  650. hr=CoGetInterfaceAndReleaseStream(pCntrl->pStream,IID_IUnknown,(void**)&pUnk);
  651. pCntrl->pCallback=NULL; //since released to 0
  652. if FAILED(hr) return -1;
  653. if (!pUnk) return -1;
  654. hr=pUnk->QueryInterface(IID_I_dxj_DirectXEvent8,(void**)&pVBCallback);
  655. pUnk->Release();
  656. if FAILED(hr) return -1;
  657. while (pCntrl->fEnd==FALSE)
  658. {
  659. WaitForSingleObject(pCntrl->hEvent,INFINITE);
  660. if ((pVBCallback )&&(pCntrl->fEnd==FALSE))
  661. {
  662. pVBCallback->AddRef();
  663. #ifdef _WIN64
  664. pVBCallback->DXCallback(pCntrl->hEvent);
  665. #else
  666. pVBCallback->DXCallback((LONG)PtrToLong(pCntrl->hEvent));
  667. #endif
  668. pVBCallback->Release();
  669. }
  670. }
  671. if (pVBCallback) pVBCallback->Release();
  672. OleUninitialize();
  673. //we need to syncronize the ending of the thread..
  674. //if (pCntrl->hEndEvent) SetEvent(pCntrl->hEndEvent);
  675. return 0;
  676. }
  677. STDMETHODIMP C_dxj_DirectX7Object::createNewGuid(BSTR *ret)
  678. {
  679. GUID g=GUID_NULL;
  680. if (!ret) return E_INVALIDARG;
  681. ::CoCreateGuid(&g);
  682. *ret=GUIDtoBSTR(&g);
  683. return S_OK;
  684. }
  685. STDMETHODIMP C_dxj_DirectX7Object::DirectXFileCreate(I_dxj_DirectXFile **ret)
  686. {
  687. HRESULT hr;
  688. #ifndef DX_FINAL_RELEASE
  689. hr = TimeBomb();
  690. if (FAILED(hr))
  691. {
  692. return E_FAIL;
  693. }
  694. #endif
  695. hr=C_dxj_DirectXFileObject::create(ret);
  696. return hr;
  697. }
  698. STDMETHODIMP C_dxj_DirectX7Object::Direct3DCreate(IUnknown **ppRet)
  699. {
  700. HRESULT hr;
  701. #ifndef DX_FINAL_RELEASE
  702. hr = TimeBomb();
  703. if (FAILED(hr))
  704. {
  705. return E_FAIL;
  706. }
  707. #endif
  708. LoadD3D8();
  709. if (!m_pDirect3DCreate8) return E_FAIL;
  710. *ppRet=(IUnknown*) m_pDirect3DCreate8(D3D_SDK_VERSION);
  711. return S_OK;
  712. }