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.

2408 lines
67 KiB

  1. // Direct.cpp : Implementation of DLL Exports.
  2. // To fully complete this project follow these steps
  3. // You will need the new MIDL compiler to build this project. Additionally,
  4. // if you are building the proxy stub DLL, you will need new headers and libs.
  5. // 1) Add a custom build step to Direct.idl
  6. // You can select all of the .IDL files by holding Ctrl and clicking on
  7. // each of them.
  8. //
  9. // Description
  10. // Running MIDL
  11. // Build Command(s)
  12. // midl Direct.idl
  13. // Outputs
  14. // Direct.tlb
  15. // Direct.h
  16. // Direct_i.c
  17. //
  18. // NOTE: You must use the MIDL compiler from NT 4.0,
  19. // preferably 3.00.15 or greater
  20. //
  21. // 2) Add a custom build step to the project to register the DLL
  22. // For this, you can select all projects at once
  23. // Description
  24. // Registering OLE Server...
  25. // Build Command(s)
  26. // regsvr32 /s /c "$(TargetPath)"
  27. // echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
  28. // Outputs
  29. // $(OutDir)\regsvr32.trg
  30. // 3) To add UNICODE support, follow these steps
  31. // Select Build|Configurations...
  32. // Press Add...
  33. // Change the configuration name to Unicode Release
  34. // Change the "Copy Settings From" combo to Direct - Win32 Release
  35. // Press OK
  36. // Press Add...
  37. // Change the configuration name to Unicode Debug
  38. // Change the "Copy Settings From" combo to Direct - Win32 Debug
  39. // Press OK
  40. // Press "Close"
  41. // Select Build|Settings...
  42. // Select the two UNICODE projects and press the C++ tab.
  43. // Select the "General" category
  44. // Add _UNICODE to the Preprocessor definitions
  45. // Select the Unicode Debug project
  46. // Press the "General" tab
  47. // Specify DebugU for the intermediate and output directories
  48. // Select the Unicode Release project
  49. // Press the "General" tab
  50. // Specify ReleaseU for the intermediate and output directories
  51. // 4) Proxy stub DLL
  52. // To build a separate proxy/stub DLL,
  53. // run nmake -f ps.mak in the project directory.
  54. #define DIRECTSOUND_VERSION 0x600
  55. #define DIRECTINPUT_VERSION 0x0500
  56. #include "stdafx.h"
  57. #include "resource.h"
  58. #include "initguid.h"
  59. #include "Direct.h"
  60. #include "dms.h"
  61. #include "DxGlob7Obj.h"
  62. #include "dSound.h"
  63. #include "dSoundObj.h"
  64. #include "dSoundBufferObj.h"
  65. #include "dSound3DListener.h"
  66. #include "dSound3DBuffer.h"
  67. #include "dSoundCaptureObj.h"
  68. #include "dSoundCaptureBufferObj.h"
  69. #include "DPAddressObj.h"
  70. #include "DPLConnectionObj.h"
  71. #include "dPlay4Obj.h"
  72. #include "dPlayLobby3Obj.h"
  73. #include "dDraw7obj.h"
  74. #include "ddSurface7obj.h"
  75. #include "ddClipperObj.h"
  76. #include "ddColorControlObj.h"
  77. #include "ddPaletteObj.h"
  78. #include "d3d7Obj.h"
  79. #include "d3dDevice7Obj.h"
  80. #include "d3drmViewport2Obj.h"
  81. #include "d3drmDevice3Obj.h"
  82. #include "d3drmFrame3Obj.h"
  83. #include "d3drm3Obj.h"
  84. #include "d3drmMeshObj.h"
  85. #include "d3drmFace2Obj.h"
  86. #include "d3drmLightObj.h"
  87. #include "d3drmTexture3Obj.h"
  88. #include "d3drmMeshBuilder3Obj.h"
  89. #include "d3drmWrapObj.h"
  90. #include "d3drmMaterial2Obj.h"
  91. #include "d3drmAnimation2Obj.h"
  92. #include "d3drmAnimationSet2Obj.h"
  93. #include "d3drmShadow2Obj.h"
  94. #include "d3drmArrayObj.h"
  95. #include "d3drmDeviceArrayObj.h"
  96. #include "d3drmViewportArrayObj.h"
  97. #include "d3drmFrameArrayObj.h"
  98. #include "d3drmVisualArrayObj.h"
  99. #include "d3drmProgressiveMeshObj.h"
  100. #include "d3drmLightArrayObj.h"
  101. #include "d3drmPickedArrayObj.h"
  102. #include "d3drmPick2ArrayObj.h"
  103. #include "d3drmFaceArrayObj.h"
  104. #include "dInput1Obj.h"
  105. #include "dInputDeviceObj.h"
  106. #include "d3drmLightInterObj.h"
  107. #include "d3drmMaterialInterObj.h"
  108. #include "d3drmMeshInterObj.h"
  109. #include "d3drmTextureInterObj.h"
  110. #include "d3drmViewportInterObj.h"
  111. #include "d3drmFrameInterObj.h"
  112. #define IID_DEFINED
  113. #include "Direct_i.c"
  114. #include "d3drmobj.h"
  115. // When floating-point types are used, the compiler emits a reference to
  116. // _fltused to initialize the CRT's floating-point package. We're not
  117. // using any of that support and the OS is responsible for initializing
  118. // the FPU, so we'll link to the following _fltused instead to avoid CRT
  119. // bloat.
  120. //
  121. // win2k doesnt like this so its been removed
  122. // #ifdef NDEBUG
  123. // extern "C" int _fltused = 0;
  124. // #endif
  125. // ATL COM OBJECT MAP
  126. CComModule _Module;
  127. BEGIN_OBJECT_MAP(ObjectMap)
  128. OBJECT_ENTRY(CLSID__dxj_DirectX7, C_dxj_DirectX7Object)
  129. END_OBJECT_MAP()
  130. //
  131. // thanks to precompiled headers, we never get this properly!
  132. //
  133. #undef DEFINE_GUID
  134. #define __based(a)
  135. #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
  136. EXTERN_C const GUID CDECL __based(__segname("_CODE")) name \
  137. = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
  138. // LINK LIST OF TEXTURE CALLBACKS
  139. // get cleaned up on DLL exit
  140. extern "C" TextureCallback3 *TextureCallbacks3 = NULL;
  141. extern "C" TextureCallback *TextureCallbacks = NULL;
  142. extern "C" FrameMoveCallback3 *FrameMoveCallbacks3 = NULL;
  143. extern "C" DeviceUpdateCallback3 *DeviceUpdateCallbacks3 = NULL;
  144. extern "C" DestroyCallback *DestroyCallbacks = NULL;
  145. extern "C" EnumerateObjectsCallback *EnumCallbacks = NULL;
  146. extern "C" LoadCallback *LoadCallbacks = NULL;
  147. // MISC GLOBALS
  148. static const char c_szWav[] = "WAVE";
  149. long g_debuglevel=0;
  150. extern "C" int nObjects = 0;
  151. BOOL is4Bit = FALSE;
  152. int g_creationcount=0;
  153. CRITICAL_SECTION g_cbCriticalSection;
  154. OSVERSIONINFOA sysinfo;
  155. // HANDLES TO DX DLLS
  156. HINSTANCE g_hDDrawHandle=NULL;
  157. HINSTANCE g_hDSoundHandle=NULL;
  158. HINSTANCE g_hDPlay=NULL;
  159. HINSTANCE g_hInstD3DRMDLL=NULL;
  160. HINSTANCE g_hInstDINPUTDLL=NULL;
  161. HINSTANCE g_hInstD3DXOFDLL=NULL;
  162. HINSTANCE g_hInst=NULL;
  163. //LINK LISTS OF AVAILABLE OBJECTS
  164. void *g_dxj_Direct3dRMAnimation2 = 0;
  165. void *g_dxj_Direct3dRMAnimationSet2 = 0;
  166. void *g_dxj_Direct3dRMAnimationArray = 0;
  167. void *g_dxj_Direct3dRMObjectArray = 0;
  168. void *g_dxj_Direct3dRMDeviceArray = 0;
  169. void *g_dxj_Direct3dRMDevice3 = 0;
  170. void *g_dxj_Direct3dRMFaceArray = 0;
  171. void *g_dxj_Direct3dRMFace2 = 0;
  172. void *g_dxj_Direct3dRMFrameArray = 0;
  173. void *g_dxj_Direct3dRMFrame3 = 0;
  174. void *g_dxj_Direct3dRMLightArray = 0;
  175. void *g_dxj_Direct3dRMLight = 0;
  176. void *g_dxj_Direct3dRMMaterial2 = 0;
  177. void *g_dxj_Direct3dRMMeshBuilder3 = 0;
  178. void *g_dxj_Direct3dRMMesh = 0;
  179. void *g_dxj_Direct3dRMProgressiveMesh = 0;
  180. void *g_dxj_Direct3dRM3 = 0;
  181. void *g_dxj_Direct3dRMObject = 0;
  182. void *g_dxj_Direct3dRMPickArray = 0;
  183. void *g_dxj_Direct3dRMPick2Array = 0;
  184. void *g_dxj_Direct3dRMShadow2 = 0;
  185. void *g_dxj_Direct3dRMTexture3 = 0;
  186. void *g_dxj_Direct3dRMClippedVisual = 0;
  187. void *g_dxj_Direct3dRMViewportArray = 0;
  188. void *g_dxj_Direct3dRMViewport2 = 0;
  189. void *g_dxj_Direct3dRMVisualArray = 0;
  190. void *g_dxj_Direct3dRMVisual = 0;
  191. void *g_dxj_Direct3dRMWinDevice = 0;
  192. void *g_dxj_Direct3dRMWrap = 0;
  193. void *g_dxj_Direct3dRMMeshInterpolator = 0;
  194. void *g_dxj_Direct3dRMLightInterpolator = 0;
  195. void *g_dxj_Direct3dRMFrameInterpolator = 0;
  196. void *g_dxj_Direct3dRMTextureInterpolator = 0;
  197. void *g_dxj_Direct3dRMViewportInterpolator = 0;
  198. void *g_dxj_Direct3dRMMaterialInterpolator = 0;
  199. void *g_dxj_DirectSound3dListener = 0;
  200. void *g_dxj_DirectSoundBuffer = 0;
  201. void *g_dxj_DirectSound3dBuffer = 0;
  202. void *g_dxj_DirectSound = 0;
  203. void *g_dxj_DirectSoundCapture = 0;
  204. void *g_dxj_DirectSoundCaptureBuffer = 0;
  205. void *g_dxj_DirectPlay4 = 0;
  206. void *g_dxj_DirectPlayLobby3 = 0;
  207. void *g_dxj_DPLConnection = 0;
  208. void *g_dxj_DPAddress = 0;
  209. void *g_dxj_DirectInput = 0;
  210. void *g_dxj_DirectInputDevice = 0;
  211. void *g_dxj_DirectInputEffect = 0;
  212. void *g_dxj_DirectDraw4 = 0;
  213. void *g_dxj_DirectDrawSurface4 = 0;
  214. void *g_dxj_DirectDrawClipper = 0;
  215. void *g_dxj_DirectDrawPalette = 0;
  216. void *g_dxj_DirectDrawColorControl = 0;
  217. void *g_dxj_DirectDrawGammaControl = 0;
  218. void *g_dxj_DirectDraw7 = 0;
  219. void *g_dxj_DirectDrawSurface7 = 0;
  220. void *g_dxj_Direct3dDevice7 = 0;
  221. void *g_dxj_Direct3dVertexBuffer7 = 0;
  222. void *g_dxj_Direct3d7 = 0;
  223. void *g_dxj_DirectMusicLoader = 0;
  224. void *g_dxj_DirectMusicPerformance = 0;
  225. void *g_dxj_DirectMusicComposer = 0;
  226. void *g_dxj_DirectMusicStyle = 0;
  227. void *g_dxj_DirectMusicBand = 0;
  228. void *g_dxj_DirectMusicChordMap = 0;
  229. void *g_dxj_DirectMusicSegment = 0;
  230. void *g_dxj_DirectMusicSegmentState = 0;
  231. void *g_dxj_DirectMusicCollection = 0;
  232. /////////////////////////////////////////////////////////////////////////////
  233. /////////////////////////////////////////////////////////////////////////////
  234. /////////////////////////////////////////////////////////////////////////////
  235. //
  236. // DLL LOADING
  237. //
  238. /////////////////////////////////////////////////////////////////////////////
  239. /////////////////////////////////////////////////////////////////////////////
  240. /////////////////////////////////////////////////////////////////////////////
  241. HINSTANCE LoadD3DXOFDLL()
  242. {
  243. char Path[MAX_PATH] = {'\0'};
  244. if (!g_hInstD3DXOFDLL)
  245. {
  246. GetSystemDirectory( Path, MAX_PATH );
  247. strcat(Path, "\\d3dXOF.dll" );
  248. g_hInstD3DXOFDLL=LoadLibrary(Path);
  249. }
  250. return g_hInstD3DXOFDLL;
  251. }
  252. HINSTANCE LoadDDrawDLL()
  253. {
  254. char Path[MAX_PATH] = {'\0'};
  255. if (!g_hDDrawHandle)
  256. {
  257. GetSystemDirectory( Path, MAX_PATH );
  258. strcat(Path, "\\ddraw.dll" );
  259. g_hDDrawHandle=LoadLibrary( Path );
  260. }
  261. return g_hDDrawHandle;
  262. }
  263. HINSTANCE LoadDSoundDLL()
  264. {
  265. char Path[MAX_PATH] = {'\0'};
  266. if (!g_hDSoundHandle)
  267. {
  268. GetSystemDirectory( Path, MAX_PATH );
  269. strcat(Path, "\\dsound.dll" );
  270. g_hDSoundHandle=LoadLibrary( Path );
  271. }
  272. return g_hDSoundHandle;
  273. }
  274. HINSTANCE LoadDPlayDLL()
  275. {
  276. char Path[MAX_PATH] = {'\0'};
  277. if (!g_hDPlay)
  278. {
  279. GetSystemDirectory( Path, MAX_PATH );
  280. strcat(Path, "\\dplayx.dll" );
  281. g_hDPlay=LoadLibrary( Path );
  282. }
  283. return g_hDPlay;
  284. }
  285. HINSTANCE LoadD3DRMDLL()
  286. {
  287. char Path[MAX_PATH] = {'\0'};
  288. if (!g_hInstD3DRMDLL)
  289. {
  290. GetSystemDirectory( Path, MAX_PATH );
  291. strcat(Path, "\\d3drm.dll" );
  292. g_hInstD3DRMDLL=LoadLibrary( Path );
  293. }
  294. return g_hInstD3DRMDLL;
  295. }
  296. HINSTANCE LoadDINPUTDLL()
  297. {
  298. if (!g_hInstDINPUTDLL) {
  299. char Path[MAX_PATH] = {'\0'};
  300. GetSystemDirectory( Path, MAX_PATH );
  301. strcat(Path, "\\dinput.dll" );
  302. g_hInstDINPUTDLL=LoadLibrary( Path );
  303. }
  304. return g_hInstDINPUTDLL;
  305. }
  306. /////////////////////////////////////////////////////////////////////////////
  307. /////////////////////////////////////////////////////////////////////////////
  308. /////////////////////////////////////////////////////////////////////////////
  309. //
  310. // DLL ENTRY POINTS
  311. //
  312. /////////////////////////////////////////////////////////////////////////////
  313. /////////////////////////////////////////////////////////////////////////////
  314. /////////////////////////////////////////////////////////////////////////////
  315. /////////////////////////////////////////////////////////////////////////////
  316. // DLL Entry Point
  317. extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  318. {
  319. g_hInst=hInstance;
  320. if (dwReason == DLL_PROCESS_ATTACH)
  321. {
  322. //
  323. // Get the current display pixel depth
  324. // If it is 4-bit we are in trouble.
  325. //
  326. HDC hDisplayIC;
  327. BOOL bPalette = FALSE;
  328. hDisplayIC = CreateIC("DISPLAY", NULL, NULL, NULL);
  329. if (hDisplayIC)
  330. {
  331. if (GetDeviceCaps(hDisplayIC, BITSPIXEL) < 8)
  332. is4Bit = TRUE;
  333. DeleteDC(hDisplayIC);
  334. }
  335. //
  336. // Get the platform I'm running on. Used for NT or Win32 Checks.
  337. //
  338. GetVersionEx((OSVERSIONINFOA*)&sysinfo);
  339. /* now delay loading dlls
  340. g_hDSoundHandle = LoadDSoundDLL();
  341. g_hDDrawHandle = LoadDDrawDLL();
  342. g_hDPlay = LoadDPlayDLL();
  343. g_hInstD3DRMDLL = LoadD3DRMDLL();
  344. g_hInstSETUPDLL=NULL;
  345. g_hInstDINPUTDLL=LoadDINPUTDLL();
  346. g_hInstD3DXOFDLL=LoadD3DXOFDLL();
  347. */
  348. _Module.Init(ObjectMap, hInstance);
  349. DisableThreadLibraryCalls(hInstance);
  350. InitializeCriticalSection(&g_cbCriticalSection);
  351. nObjects = 0;
  352. }
  353. else if (dwReason == DLL_PROCESS_DETACH)
  354. {
  355. UINT i; //for easy debugging
  356. //TEAR DOWN CALLBACK LISTS
  357. {
  358. TextureCallback3 *pNext=NULL;
  359. for (TextureCallback3 *pCB=TextureCallbacks3; (pCB); pCB=pNext)
  360. {
  361. if (pCB->c) i=(pCB->c)->Release();
  362. if (pCB->pUser) i=(pCB->pUser)->Release();
  363. if (pCB->pParent) i=(pCB->pParent)->Release();
  364. if (pCB->m_obj) i=(pCB->m_obj)->Release();
  365. pNext=pCB->next;
  366. delete pCB;
  367. }
  368. }
  369. {
  370. FrameMoveCallback3 *pNext=NULL;
  371. for (FrameMoveCallback3 *pCB=FrameMoveCallbacks3; (pCB); pCB=pNext)
  372. {
  373. if (pCB->c) i=(pCB->c)->Release();
  374. if (pCB->pUser) i=(pCB->pUser)->Release();
  375. if (pCB->pParent) i=(pCB->pParent)->Release();
  376. if (pCB->m_obj) i=(pCB->m_obj)->Release();
  377. pNext=pCB->next;
  378. delete pCB;
  379. }
  380. }
  381. {
  382. DeviceUpdateCallback3 *pNext=NULL;
  383. for (DeviceUpdateCallback3 *pCB=DeviceUpdateCallbacks3; (pCB); pCB=pNext)
  384. {
  385. if (pCB->c) i=(pCB->c)->Release();
  386. if (pCB->pUser) i=(pCB->pUser)->Release();
  387. if (pCB->pParent) i=(pCB->pParent)->Release();
  388. if (pCB->m_obj) i=(pCB->m_obj)->Release();
  389. pNext=pCB->next;
  390. delete pCB;
  391. }
  392. }
  393. {
  394. TextureCallback *pNext=NULL;
  395. for (TextureCallback *pCB=TextureCallbacks; (pCB); pCB=pNext)
  396. {
  397. if (pCB->c) i=(pCB->c)->Release();
  398. if (pCB->pUser) i=(pCB->pUser)->Release();
  399. if (pCB->pParent) i=(pCB->pParent)->Release();
  400. if (pCB->m_obj) i=(pCB->m_obj)->Release();
  401. pNext=pCB->next;
  402. delete pCB;
  403. }
  404. }
  405. DPF (1,"Final Destroy Callbacks \n");
  406. {
  407. DestroyCallback *pNext=NULL;
  408. for (DestroyCallback *pCB=DestroyCallbacks; (pCB); pCB=pNext)
  409. {
  410. if (pCB->c) i=(pCB->c)->Release();
  411. if (pCB->pUser) i=(pCB->pUser)->Release();
  412. if (pCB->pParent) i=(pCB->pParent)->Release();
  413. if (pCB->m_obj) i=(pCB->m_obj)->Release();
  414. pNext=pCB->next;
  415. delete pCB;
  416. }
  417. }
  418. DPF (1,"Final Destroy Callbacks Exit \n");
  419. {
  420. EnumerateObjectsCallback *pNext=NULL;
  421. for (EnumerateObjectsCallback *pCB=EnumCallbacks; (pCB); pCB=pNext)
  422. {
  423. if (pCB->c) i=(pCB->c)->Release();
  424. if (pCB->pUser) i=(pCB->pUser)->Release();
  425. if (pCB->pParent) i=(pCB->pParent)->Release();
  426. if (pCB->m_obj) i=(pCB->m_obj)->Release();
  427. pNext=pCB->next;
  428. delete pCB;
  429. }
  430. }
  431. {
  432. LoadCallback *pNext=NULL;
  433. for (LoadCallback *pCB=LoadCallbacks; (pCB); pCB=pNext)
  434. {
  435. if (pCB->c) i=(pCB->c)->Release();
  436. if (pCB->pUser) i=(pCB->pUser)->Release();
  437. if (pCB->pParent) i=(pCB->pParent)->Release();
  438. if (pCB->m_obj) i=(pCB->m_obj)->Release();
  439. pNext=pCB->next;
  440. delete pCB;
  441. }
  442. }
  443. //Andrewke bug30341 06/12/2000
  444. DeleteCriticalSection(&g_cbCriticalSection);
  445. //DEBUG CHECK ON REF COUNT FOR PROBLEMATIC OBJECTS
  446. #ifdef DEBUG
  447. OBJCHECK("Direct3d7 ",_dxj_Direct3d7 )
  448. OBJCHECK("Direct3dDevice7 ",_dxj_Direct3dDevice7 )
  449. OBJCHECK("DirectDrawSurface7 ",_dxj_DirectDrawSurface7 )
  450. OBJCHECK("DirectDraw7 ",_dxj_DirectDraw7 )
  451. DPF(4,"Dx7vb.dll will about to unload dx dlls\n\r");
  452. #endif
  453. //FREE DLLS
  454. if ( g_hDPlay )
  455. FreeLibrary(g_hDPlay);
  456. if ( g_hDSoundHandle )
  457. FreeLibrary(g_hDSoundHandle);
  458. if ( g_hDDrawHandle )
  459. FreeLibrary(g_hDDrawHandle);
  460. if ( g_hInstD3DRMDLL )
  461. FreeLibrary(g_hInstD3DRMDLL);
  462. if ( g_hInstDINPUTDLL )
  463. FreeLibrary(g_hInstDINPUTDLL);
  464. if (g_hInstD3DXOFDLL)
  465. FreeLibrary(g_hInstD3DXOFDLL);
  466. _Module.Term();
  467. }
  468. return TRUE;
  469. }
  470. /////////////////////////////////////////////////////////////////////////////
  471. // Used to determine whether the DLL can be unloaded by OLE
  472. STDAPI DllCanUnloadNow(void)
  473. {
  474. return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
  475. }
  476. /////////////////////////////////////////////////////////////////////////////
  477. // Returns a class factory to create an object of the requested type
  478. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  479. {
  480. return _Module.GetClassObject(rclsid, riid, ppv);
  481. }
  482. /////////////////////////////////////////////////////////////////////////////
  483. // DllRegisterServer - Adds entries to the system registry
  484. STDAPI DllRegisterServer(void)
  485. {
  486. HRESULT hRes = S_OK;
  487. // registers object, typelib and all interfaces in typelib
  488. hRes = _Module.RegisterServer(TRUE);
  489. if(hRes == S_OK)
  490. {
  491. //hRes = RegSecurityClass();
  492. }
  493. //now look
  494. HKEY hk=0;
  495. char szDocPath[MAX_PATH];
  496. DWORD cb=MAX_PATH;
  497. LONG res;
  498. DWORD type=REG_SZ;
  499. ZeroMemory(szDocPath,MAX_PATH);
  500. res=RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Directx",&hk);
  501. if ((ERROR_SUCCESS!=res)||(hk==0) )
  502. return hRes;
  503. res=RegQueryValueEx(hk,"DXSDK Doc Path",NULL,&type,(LPBYTE)szDocPath,&cb);
  504. RegCloseKey(hk);
  505. if (ERROR_SUCCESS!=res) return hRes;
  506. hk=0;
  507. res=RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\CLASSES\\TypeLib\\{E1211242-8E94-11D1-8808-00C04FC2C602}\\1.0\\HELPDIR",&hk);
  508. if (ERROR_SUCCESS!=res) return hRes;
  509. RegSetValueEx(hk,NULL,0,REG_SZ,(LPBYTE)szDocPath,cb);
  510. RegCloseKey(hk);
  511. return hRes;
  512. }
  513. /////////////////////////////////////////////////////////////////////////////
  514. // DllUnregisterServer - Adds entries to the system registry
  515. STDAPI DllUnregisterServer(void)
  516. {
  517. HRESULT hRes = S_OK;
  518. hRes = _Module.UnregisterServer();
  519. if(hRes == S_OK)
  520. {
  521. //hRes = UnRegSecurityClass();
  522. }
  523. return hRes;
  524. }
  525. /////////////////////////////////////////////////////////////////////////////
  526. /////////////////////////////////////////////////////////////////////////////
  527. /////////////////////////////////////////////////////////////////////////////
  528. //
  529. // GUID CONVERSION FUNCTIONS
  530. //
  531. /////////////////////////////////////////////////////////////////////////////
  532. /////////////////////////////////////////////////////////////////////////////
  533. /////////////////////////////////////////////////////////////////////////////
  534. /////////////////////////////////////////////////////////////////////////////
  535. // GUIDS_EQUAL - consider moving to dms.h
  536. #define GUIDS_EQUAL(g,g2) (\
  537. (g.Data1==g2->Data1) && \
  538. (g.Data2==g2->Data2) && \
  539. (g.Data3==g2->Data3) && \
  540. (g.Data4[0]==g2->Data4[0]) && \
  541. (g.Data4[1]==g2->Data4[1]) && \
  542. (g.Data4[2]==g2->Data4[2]) && \
  543. (g.Data4[3]==g2->Data4[3]) && \
  544. (g.Data4[4]==g2->Data4[4]) && \
  545. (g.Data4[5]==g2->Data4[5]) && \
  546. (g.Data4[6]==g2->Data4[6]) && \
  547. (g.Data4[7]==g2->Data4[7]) )
  548. /////////////////////////////////////////////////////////////////////////////
  549. // GUIDtoBSTR - does conversion
  550. BSTR GUIDtoBSTR(LPGUID pGuid){
  551. char szOut[256];
  552. char szTemp[10];
  553. char *pAt=NULL;
  554. int i;
  555. BSTR bstrOut;
  556. // 00000000001111111111222222222233333333
  557. // 01234567890123456789012345678901234567
  558. // {XXXXXXXX-XXXX-XXXX-X XXX-XXXXXXXXXXXX}
  559. if (pGuid!=NULL){
  560. szOut[0]='{';
  561. wsprintf(&(szOut)[1],"%.8X",pGuid->Data1);
  562. szOut[9]='-';
  563. wsprintf(szTemp,"%.4X",pGuid->Data2);
  564. memcpy(&(szOut[10]),szTemp,4);
  565. szOut[14]='-';
  566. wsprintf(szTemp,"%.4X",pGuid->Data3);
  567. memcpy(&(szOut[15]),szTemp,4);
  568. szOut[19]='-';
  569. for (i=0;i<2;i++){
  570. wsprintf(szTemp,"%.2X",pGuid->Data4[i]);
  571. memcpy(&(szOut[20+i*2]),szTemp,2);
  572. }
  573. szOut[24]='-';
  574. for (i=2;i<8;i++){
  575. wsprintf(szTemp,"%.2X",pGuid->Data4[i]);
  576. memcpy(&(szOut[21+i*2]),szTemp,2);
  577. }
  578. szOut[37]='}';
  579. szOut[38]='\0';
  580. USES_CONVERSION;
  581. bstrOut = T2BSTR(szOut);
  582. }
  583. else {
  584. bstrOut = T2BSTR("");
  585. }
  586. return bstrOut;
  587. }
  588. //////////////////////////////////////////////////////////////////////////////
  589. // convertChar
  590. // helper for GUIDtoBSTR
  591. HRESULT convertChar(char *szIn,int i,char *valOut){
  592. int val[2]; //using int for easy out of bounds check
  593. char c;
  594. int j;
  595. for (j=0;j<2;j++){
  596. c= szIn[i+j];
  597. switch (c)
  598. {
  599. case 'a':
  600. case 'A':
  601. val[j]=10;
  602. break;
  603. case 'b':
  604. case 'B':
  605. val[j]=11;
  606. break;
  607. case 'c':
  608. case 'C':
  609. val[j]=12;
  610. break;
  611. case 'd':
  612. case 'D':
  613. val[j]=13;
  614. break;
  615. case 'e':
  616. case 'E':
  617. val[j]=14;
  618. break;
  619. case 'f':
  620. case 'F':
  621. val[j]=15;
  622. break;
  623. default:
  624. val[j]=c-'0';
  625. if (val[j]<0) return E_INVALIDARG;
  626. if (val[j]>15) return E_INVALIDARG;
  627. break;
  628. }
  629. }
  630. *valOut=(char)((val[0]<<4)|val[1]);
  631. return S_OK;
  632. }
  633. /////////////////////////////////////////////////////////////////////////////
  634. // BSTRtoGUID - does conversion
  635. //
  636. HRESULT BSTRtoGUID(LPGUID pGuid, BSTR bstr){
  637. HRESULT hr;
  638. //byte
  639. //
  640. //
  641. //char
  642. // 1111111111222222222233333333
  643. // 01234567890123456789012345678901234567
  644. // {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
  645. USES_CONVERSION;
  646. if(!pGuid) return E_INVALIDARG;
  647. ZeroMemory(pGuid,sizeof(GUID));
  648. if (!bstr) return S_OK;
  649. if (bstr[0]==0x00) return S_OK;
  650. LPSTR szGuid = NULL;
  651. __try { szGuid = W2T(bstr); /* Now convert to ANSI */ } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; }
  652. //first and last char should be { }
  653. if ((szGuid[0]!='{')||(szGuid[37]!='}'))
  654. return E_INVALIDARG;
  655. if ((szGuid[9]!='-')||(szGuid[14]!='-')||(szGuid[19]!='-')||(szGuid[24]!='-'))
  656. return E_INVALIDARG;
  657. char val;
  658. char *pData=(char*)pGuid;
  659. int j=0;
  660. int i;
  661. //FIRST DWORD
  662. for ( i=7;i>=1;i=i-2){
  663. hr=convertChar(szGuid,i,&val);
  664. if FAILED(hr) return hr;
  665. pData[j++]=val;
  666. }
  667. //FIRST WORD
  668. for ( i=12;i>=10;i=i-2){
  669. hr=convertChar(szGuid,i,&val);
  670. if FAILED(hr) return hr;
  671. pData[j++]=val;
  672. }
  673. //2nd WORD
  674. for ( i=17;i>=15;i=i-2){
  675. hr=convertChar(szGuid,i,&val);
  676. if FAILED(hr) return hr;
  677. pData[j++]=val;
  678. }
  679. //3rd DWORD - BYTE ARRAY
  680. for ( i=20;i<24;i=i+2){
  681. hr=convertChar(szGuid,i,&val);
  682. if FAILED(hr) return hr;
  683. pData[j++]=val;
  684. }
  685. //BYTE ARRAY
  686. for ( i=25;i<37;i=i+2){
  687. hr=convertChar(szGuid,i,&val);
  688. if FAILED(hr) return hr;
  689. pData[j++]=val;
  690. }
  691. return S_OK;
  692. }
  693. /////////////////////////////////////////////////////////////////////////////
  694. //
  695. //
  696. HRESULT BSTRtoPPGUID(LPGUID *ppGuid, BSTR bstr){
  697. if (!ppGuid) return E_INVALIDARG;
  698. if ((bstr==NULL)||(bstr[0]=='\0')){
  699. *ppGuid=NULL;
  700. return S_OK;
  701. }
  702. return BSTRtoGUID(*ppGuid,bstr);
  703. }
  704. /////////////////////////////////////////////////////////////////////////////
  705. // D3DBSTRtoGUID - does conversion
  706. //
  707. HRESULT D3DBSTRtoGUID(LPGUID pGuid,BSTR str){
  708. HRESULT hr=S_OK;
  709. if (!pGuid) return E_INVALIDARG;
  710. if (!str) {
  711. ZeroMemory(pGuid,sizeof(GUID));
  712. return S_OK;
  713. }
  714. if( 0==_wcsicmp(str,L"iid_idirect3drgbdevice")){
  715. memcpy(pGuid,&IID_IDirect3DRGBDevice,sizeof(GUID));
  716. }
  717. else if( 0==_wcsicmp(str,L"iid_idirect3dhaldevice")){
  718. memcpy(pGuid,&IID_IDirect3DHALDevice,sizeof(GUID));
  719. }
  720. else if( 0==_wcsicmp(str,L"iid_idirect3dmmxdevice")){
  721. memcpy(pGuid,&IID_IDirect3DMMXDevice,sizeof(GUID));
  722. }
  723. else if( 0==_wcsicmp(str,L"iid_idirect3drefdevice")){
  724. memcpy(pGuid,&IID_IDirect3DRefDevice,sizeof(GUID));
  725. }
  726. else if( 0==_wcsicmp(str,L"iid_idirect3dnulldevice")){
  727. memcpy(pGuid,&IID_IDirect3DNullDevice,sizeof(GUID));
  728. }
  729. else {
  730. hr = BSTRtoGUID(pGuid,str);
  731. }
  732. return hr;
  733. }
  734. /////////////////////////////////////////////////////////////////////////////
  735. // D3DGUIDtoBSTR - does conversion
  736. //
  737. BSTR D3DGUIDtoBSTR(LPGUID pg){
  738. HRESULT hr=S_OK;
  739. WCHAR *pStr=NULL;
  740. if (!pg)
  741. return NULL;
  742. else if (GUIDS_EQUAL(IID_IDirect3DNullDevice,pg)){
  743. pStr=L"IID_IDirect3DNullDevice";
  744. }
  745. else if (GUIDS_EQUAL(IID_IDirect3DRefDevice,pg)){
  746. pStr=L"IID_IDirect3DRefDevice";
  747. }
  748. else if (GUIDS_EQUAL(IID_IDirect3DMMXDevice,pg)){
  749. pStr=L"IID_IDirect3DMMXDevice";
  750. }
  751. else if (GUIDS_EQUAL(IID_IDirect3DHALDevice,pg)){
  752. pStr=L"IID_IDirect3DHALDevice";
  753. }
  754. else if (GUIDS_EQUAL(IID_IDirect3DRGBDevice,pg)){
  755. pStr=L"IID_IDirect3DRGBDevice";
  756. }
  757. if (pStr){
  758. return DXALLOCBSTR(pStr);
  759. }
  760. else {
  761. return GUIDtoBSTR(pg);
  762. }
  763. }
  764. /////////////////////////////////////////////////////////////////////////////
  765. // DINPUTGUIDtoBSTR
  766. //
  767. BSTR DINPUTGUIDtoBSTR(LPGUID pg){
  768. HRESULT hr=S_OK;
  769. WCHAR *pStr=NULL;
  770. if (!pg)
  771. return NULL;
  772. else if (GUIDS_EQUAL(GUID_XAxis,pg)){
  773. pStr=L"GUID_XAxis";
  774. }
  775. else if (GUIDS_EQUAL(GUID_YAxis,pg)){
  776. pStr=L"GUID_YAxis";
  777. }
  778. else if (GUIDS_EQUAL(GUID_ZAxis,pg)){
  779. pStr=L"GUID_ZAxis";
  780. }
  781. else if (GUIDS_EQUAL(GUID_RxAxis,pg)){
  782. pStr=L"GUID_RxAxis";
  783. }
  784. else if (GUIDS_EQUAL(GUID_RyAxis,pg)){
  785. pStr=L"GUID_RyAxis";
  786. }
  787. else if (GUIDS_EQUAL(GUID_RzAxis,pg)){
  788. pStr=L"GUID_RzAxis";
  789. }
  790. else if (GUIDS_EQUAL(GUID_Slider,pg)){
  791. pStr=L"GUID_Slider";
  792. }
  793. else if (GUIDS_EQUAL(GUID_Button,pg)){
  794. pStr=L"GUID_Button";
  795. }
  796. else if (GUIDS_EQUAL(GUID_Key,pg)){
  797. pStr=L"GUID_Key";
  798. }
  799. else if (GUIDS_EQUAL(GUID_POV,pg)){
  800. pStr=L"GUID_POV";
  801. }
  802. else if (GUIDS_EQUAL(GUID_Unknown,pg)){
  803. pStr=L"GUID_Unknown";
  804. }
  805. else if (GUIDS_EQUAL(GUID_SysMouse,pg)){
  806. pStr=L"GUID_SysMouse";
  807. }
  808. else if (GUIDS_EQUAL(GUID_SysKeyboard,pg)){
  809. pStr=L"GUID_SysKeyboard";
  810. }
  811. else if (GUIDS_EQUAL(GUID_ConstantForce,pg)){
  812. pStr=L"GUID_ConstantForce";
  813. }
  814. else if (GUIDS_EQUAL(GUID_Square,pg)){
  815. pStr=L"GUID_Square";
  816. }
  817. else if (GUIDS_EQUAL(GUID_Sine,pg)){
  818. pStr=L"GUID_Sine";
  819. }
  820. else if (GUIDS_EQUAL(GUID_Triangle,pg)){
  821. pStr=L"GUID_Triangle";
  822. }
  823. else if (GUIDS_EQUAL(GUID_SawtoothUp,pg)){
  824. pStr=L"GUID_SawtoothUp";
  825. }
  826. else if (GUIDS_EQUAL(GUID_SawtoothDown,pg)){
  827. pStr=L"GUID_SawtoothDown";
  828. }
  829. else if (GUIDS_EQUAL(GUID_Spring,pg)){
  830. pStr=L"GUID_Spring";
  831. }
  832. else if (GUIDS_EQUAL(GUID_Damper,pg)){
  833. pStr=L"GUID_Damper";
  834. }
  835. else if (GUIDS_EQUAL(GUID_Inertia,pg)){
  836. pStr=L"GUID_Inertia";
  837. }
  838. else if (GUIDS_EQUAL(GUID_Friction,pg)){
  839. pStr=L"GUID_Friction";
  840. }
  841. else if (GUIDS_EQUAL(GUID_CustomForce,pg)){
  842. pStr=L"GUID_CustomForce";
  843. }
  844. else if (GUIDS_EQUAL(GUID_RampForce,pg)){
  845. pStr=L"GUID_RampForce";
  846. }
  847. //else if (GUIDS_EQUAL(GUID_Joystick,pg)){
  848. // pStr=L"GUID_JoyStick";
  849. //}
  850. if (pStr){
  851. return DXALLOCBSTR(pStr);
  852. }
  853. else {
  854. return GUIDtoBSTR(pg);
  855. }
  856. }
  857. /////////////////////////////////////////////////////////////////////////////
  858. // DINPUTBSTRtoGUID
  859. //
  860. HRESULT DINPUTBSTRtoGUID(LPGUID pGuid,BSTR str){
  861. HRESULT hr=S_OK;
  862. if (!pGuid) return E_INVALIDARG;
  863. if (!str) {
  864. ZeroMemory(pGuid,sizeof(GUID));
  865. return S_OK;
  866. }
  867. if( 0==_wcsicmp(str,L"guid_xaxis")){
  868. memcpy(pGuid,&GUID_XAxis,sizeof(GUID));
  869. }
  870. else if( 0==_wcsicmp(str,L"guid_yaxis")){
  871. memcpy(pGuid,&GUID_YAxis,sizeof(GUID));
  872. }
  873. else if( 0==_wcsicmp(str,L"guid_zaxis")){
  874. memcpy(pGuid,&GUID_ZAxis,sizeof(GUID));
  875. }
  876. else if( 0==_wcsicmp(str,L"guid_rxaxis")){
  877. memcpy(pGuid,&GUID_RxAxis,sizeof(GUID));
  878. }
  879. else if( 0==_wcsicmp(str,L"guid_ryaxis")){
  880. memcpy(pGuid,&GUID_RyAxis,sizeof(GUID));
  881. }
  882. else if( 0==_wcsicmp(str,L"guid_rzaxis")){
  883. memcpy(pGuid,&GUID_RzAxis,sizeof(GUID));
  884. }
  885. else if( 0==_wcsicmp(str,L"guid_slider")){
  886. memcpy(pGuid,&GUID_Slider,sizeof(GUID));
  887. }
  888. else if( 0==_wcsicmp(str,L"guid_button")){
  889. memcpy(pGuid,&GUID_Button,sizeof(GUID));
  890. }
  891. else if( 0==_wcsicmp(str,L"guid_key")){
  892. memcpy(pGuid,&GUID_Key,sizeof(GUID));
  893. }
  894. else if( 0==_wcsicmp(str,L"guid_pov")){
  895. memcpy(pGuid,&GUID_POV,sizeof(GUID));
  896. }
  897. else if( 0==_wcsicmp(str,L"guid_unknown")){
  898. memcpy(pGuid,&GUID_Unknown,sizeof(GUID));
  899. }
  900. else if( 0==_wcsicmp(str,L"guid_sysmouse")){
  901. memcpy(pGuid,&GUID_SysMouse,sizeof(GUID));
  902. }
  903. else if( 0==_wcsicmp(str,L"guid_syskeyboard")){
  904. memcpy(pGuid,&GUID_SysKeyboard,sizeof(GUID));
  905. }
  906. else if( 0==_wcsicmp(str,L"guid_constantforce")){
  907. memcpy(pGuid,&GUID_ConstantForce,sizeof(GUID));
  908. }
  909. else if( 0==_wcsicmp(str,L"guid_square")){
  910. memcpy(pGuid,&GUID_Square,sizeof(GUID));
  911. }
  912. else if( 0==_wcsicmp(str,L"guid_sine")){
  913. memcpy(pGuid,&GUID_Sine,sizeof(GUID));
  914. }
  915. else if( 0==_wcsicmp(str,L"guid_triangle")){
  916. memcpy(pGuid,&GUID_Triangle,sizeof(GUID));
  917. }
  918. else if( 0==_wcsicmp(str,L"guid_sawtoothup")){
  919. memcpy(pGuid,&GUID_SawtoothUp,sizeof(GUID));
  920. }
  921. else if( 0==_wcsicmp(str,L"guid_sawtoothdown")){
  922. memcpy(pGuid,&GUID_SawtoothDown,sizeof(GUID));
  923. }
  924. else if( 0==_wcsicmp(str,L"guid_spring")){
  925. memcpy(pGuid,&GUID_Spring,sizeof(GUID));
  926. }
  927. else if( 0==_wcsicmp(str,L"guid_damper")){
  928. memcpy(pGuid,&GUID_Damper,sizeof(GUID));
  929. }
  930. else if( 0==_wcsicmp(str,L"guid_inertia")){
  931. memcpy(pGuid,&GUID_Inertia,sizeof(GUID));
  932. }
  933. else if( 0==_wcsicmp(str,L"guid_friction")){
  934. memcpy(pGuid,&GUID_Friction,sizeof(GUID));
  935. }
  936. else if( 0==_wcsicmp(str,L"guid_customforce")){
  937. memcpy(pGuid,&GUID_CustomForce,sizeof(GUID));
  938. }
  939. else if( 0==_wcsicmp(str,L"guid_rampforce")){
  940. memcpy(pGuid,&GUID_RampForce,sizeof(GUID));
  941. }
  942. //else if( 0==_wcsicmp(str,L"guid_joystick")){
  943. // memcpy(pGuid,&GUID_Joystick,sizeof(GUID));
  944. //}
  945. else {
  946. hr = BSTRtoGUID(pGuid,str);
  947. }
  948. return hr;
  949. }
  950. /////////////////////////////////////////////////////////////////////////////
  951. /////////////////////////////////////////////////////////////////////////////
  952. /////////////////////////////////////////////////////////////////////////////
  953. //
  954. // GENERAL HELPER FUNCTIONS
  955. //
  956. /////////////////////////////////////////////////////////////////////////////
  957. /////////////////////////////////////////////////////////////////////////////
  958. /////////////////////////////////////////////////////////////////////////////
  959. /////////////////////////////////////////////////////////////////////////////
  960. // CreateCoverObject
  961. //
  962. // NOTE this function call INTERNAL_CREATE_NOADDREF alot
  963. // the only difference from INTERNAL_CREATE is that these objects will not
  964. // have a reference to the object that created them if they are not
  965. // available to the user in an existing user variable.. (not in the ll allready)
  966. //
  967. // The parent pointer is a vestige of DX5 support where we had to
  968. // manage the order of release calls. But that only happens for ddraw api
  969. HRESULT CreateCoverObject(LPDIRECT3DRMOBJECT lpo, I_dxj_Direct3dRMObject **coverObj)
  970. {
  971. IUnknown *realThing=NULL;
  972. IUnknown *coverThing=NULL;
  973. IDirect3DRMInterpolator *pInter=NULL;
  974. //See if we where passed an interpolator
  975. if (S_OK==lpo->QueryInterface(IID_IDirect3DRMInterpolator,(void**)&pInter)){
  976. // Figure out what kind
  977. if (S_OK==pInter->QueryInterface(IID_IDirect3DRMFrame3,(void**)&realThing)){
  978. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMFrameInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  979. }
  980. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMMeshBuilder3,(void**)&realThing)){
  981. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMeshInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  982. }
  983. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMViewport2,(void**)&realThing)){
  984. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMViewportInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  985. }
  986. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMTexture3,(void**)&realThing)){
  987. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMTextureInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  988. }
  989. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMMaterial2,(void**)&realThing)){
  990. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMaterialInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  991. }
  992. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMLight,(void**)&realThing)){
  993. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMLightInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  994. }
  995. else {
  996. // release reference from original Interpolator QI and exit
  997. DPF(1,"CreateCoverObject unable to find interpolator\r\n");
  998. pInter->Release();
  999. return E_FAIL;
  1000. }
  1001. //dont need pinter anymore
  1002. pInter->Release();
  1003. }
  1004. else {
  1005. // Not an interpolator.. See what else it could be.
  1006. if (S_OK==lpo->QueryInterface(IID_IDirect3DRMMeshBuilder3,(void**)&realThing)){
  1007. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMeshBuilder3,(IDirect3DRMMeshBuilder3*)realThing,&coverThing);
  1008. }
  1009. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMAnimation2,(void**)&realThing)){
  1010. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMAnimation2,(IDirect3DRMAnimation2*)realThing,&coverThing);
  1011. }
  1012. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMAnimationSet2,(void**)&realThing)){
  1013. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMAnimationSet2,(IDirect3DRMAnimationSet2*)realThing,&coverThing);
  1014. }
  1015. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMFrame3,(void**)&realThing)){
  1016. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMFrame3,(IDirect3DRMFrame3*)realThing,&coverThing);
  1017. }
  1018. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMFace2,(void**)&realThing)){
  1019. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMFace2,(IDirect3DRMFace2*)realThing,&coverThing);
  1020. }
  1021. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMDevice3,(void**)&realThing)){
  1022. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMDevice3,(IDirect3DRMDevice3*)realThing,&coverThing);
  1023. }
  1024. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMTexture3,(void**)&realThing)){
  1025. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMTexture3,(IDirect3DRMTexture3*)realThing,&coverThing);
  1026. }
  1027. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMLight,(void**)&realThing)){
  1028. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMLight,(IDirect3DRMLight*)realThing,&coverThing);
  1029. }
  1030. // no longer support USERVISUALS
  1031. // else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMUserVisual,(void**)&realThing)){
  1032. // INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMUserVisual,(IDirect3DRMUserVisual*)realThing,&coverThing);
  1033. // }
  1034. else {
  1035. DPF(4,"CreateCoverObject didnt recognize guid");
  1036. return E_FAIL;
  1037. }
  1038. }
  1039. if (!coverThing) return E_OUTOFMEMORY;
  1040. // All objects should support RMObject so get that interface
  1041. if (FAILED(coverThing->QueryInterface(IID_I_dxj_Direct3dRMObject, (void **)coverObj))) {
  1042. coverThing->Release();
  1043. return E_NOINTERFACE;
  1044. }
  1045. // Pass back cover object to user - has inc ref count from QI
  1046. coverThing->Release();
  1047. return S_OK;
  1048. }
  1049. /////////////////////////////////////////////////////////////////////////////
  1050. // CreateCoverVisual
  1051. //
  1052. // Similar to CreateCoverObject
  1053. //
  1054. HRESULT CreateCoverVisual(LPDIRECT3DRMOBJECT lpo, I_dxj_Direct3dRMVisual **ppret)
  1055. {
  1056. IUnknown *realThing=NULL;
  1057. IUnknown *coverThing=NULL;
  1058. I_dxj_Direct3dRMVisual *pObj=NULL;
  1059. *ppret=NULL;
  1060. //What kind of visual are we
  1061. if (S_OK==lpo->QueryInterface(IID_IDirect3DRMMeshBuilder3,(void**)&realThing)) {
  1062. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMeshBuilder3,(IDirect3DRMMeshBuilder3*)realThing,&coverThing);
  1063. }
  1064. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMTexture3,(void**)&realThing)){
  1065. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMTexture3,(IDirect3DRMTexture3*)realThing,&coverThing);
  1066. }
  1067. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMMesh,(void**)&realThing)){
  1068. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMesh,(IDirect3DRMMesh*)realThing,&coverThing);
  1069. }
  1070. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMProgressiveMesh,(void**)&realThing)){
  1071. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMProgressiveMesh,(IDirect3DRMProgressiveMesh*)realThing,&coverThing);
  1072. }
  1073. else {
  1074. DPF(4," didnt recognize Visual in CreateCoverVisual");
  1075. return E_FAIL;
  1076. }
  1077. //release first QI
  1078. if (realThing) realThing->Release();
  1079. //make sure we have a coverThing.
  1080. if (!coverThing) return E_FAIL;
  1081. //QI for Visual Base Interface
  1082. if (FAILED(coverThing->QueryInterface(IID_I_dxj_Direct3dRMVisual, (void **)ppret))){
  1083. DPF(4,"CreateCoverVisual QI for object failed");
  1084. coverThing->Release ();
  1085. return E_FAIL;
  1086. }
  1087. //release 2nd QI
  1088. coverThing->Release();
  1089. return S_OK;
  1090. }
  1091. /////////////////////////////////////////////////////////////////////////////
  1092. // _GetName helper function for RM object base class
  1093. //
  1094. extern "C" HRESULT _GetName(IDirect3DRMObject *iface, BSTR *Name, BOOL bNameNotClassName)
  1095. {
  1096. DWORD cnt = 0;
  1097. LPSTR str ; // ANSI buffer on stack;
  1098. if( bNameNotClassName )
  1099. {
  1100. if((iface->GetName(&cnt,(char*)NULL)) != D3DRM_OK) // size
  1101. return E_FAIL;
  1102. __try { str = (LPSTR)alloca(cnt); /* Now convert to ANSI */ } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; }
  1103. if((iface->GetName(&cnt, str)) != D3DRM_OK)
  1104. return E_FAIL;
  1105. }
  1106. else
  1107. {
  1108. if((iface->GetClassName(&cnt,(char*)NULL)) != D3DRM_OK) // size
  1109. return E_FAIL;
  1110. __try { str = (LPSTR)alloca(cnt); /* Now convert to ANSI */ } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; }
  1111. if((iface->GetClassName(&cnt, str)) != D3DRM_OK)
  1112. return E_FAIL;
  1113. }
  1114. PassBackUnicode(str, Name, cnt);
  1115. return D3DRM_OK;
  1116. }
  1117. /////////////////////////////////////////////////////////////////////////////
  1118. // Given an ANSI string, pass back a UNICODE string
  1119. // SysAllocString is your big friend here.
  1120. //
  1121. // CONSIDER finding all occerence of use and replacint with the
  1122. // T2BSTR macro .. much cleaner
  1123. //
  1124. extern "C" void PassBackUnicode(LPSTR str, BSTR *Name, DWORD cnt)
  1125. {
  1126. //NOTE: length header is required to be filled, but the BSTR pointer
  1127. // points to the first character, not the length.
  1128. // note, the count can never be too small as we get that from the string
  1129. // before we pass it in!
  1130. USES_CONVERSION;
  1131. LPWSTR lpw = (LPWSTR)malloc((cnt+1)*2);
  1132. if (!lpw) return; //fix for bug45158 -no way of producing error code. (hmm)
  1133. void *l = (void *)lpw;
  1134. lpw = AtlA2WHelper(lpw, str, cnt);
  1135. lpw[cnt] = 0;
  1136. *Name = SysAllocString(lpw);
  1137. free(l);
  1138. }
  1139. /////////////////////////////////////////////////////////////////////////////
  1140. // CopyOutDDSurfaceDesc2 real->cover
  1141. //
  1142. HRESULT CopyOutDDSurfaceDesc2(DDSurfaceDesc2 *dOut,DDSURFACEDESC2 *d){
  1143. ZeroMemory(dOut, sizeof(DDSurfaceDesc2));
  1144. memcpy (dOut,d,sizeof(DDSURFACEDESC2));
  1145. dOut->lMipMapCount=d->dwMipMapCount;
  1146. dOut->lRefreshRate=d->dwRefreshRate;
  1147. // Get Caps
  1148. dOut->ddsCaps.lCaps = d->ddsCaps.dwCaps;
  1149. dOut->ddsCaps.lCaps2 = d->ddsCaps.dwCaps2;
  1150. dOut->ddsCaps.lCaps3 = d->ddsCaps.dwCaps3;
  1151. dOut->ddsCaps.lCaps4 = d->ddsCaps.dwCaps4;
  1152. CopyOutDDPixelFormat(&(dOut->ddpfPixelFormat) ,&(d->ddpfPixelFormat));
  1153. return S_OK;
  1154. }
  1155. /////////////////////////////////////////////////////////////////////////////
  1156. // CopyInDDSurfaceDesc2 cover->real
  1157. //
  1158. HRESULT CopyInDDSurfaceDesc2(DDSURFACEDESC2 *dOut,DDSurfaceDesc2 *d){
  1159. if(!d) return E_POINTER;
  1160. else if(!dOut) return E_POINTER;
  1161. else if ( DDSD_MIPMAPCOUNT & d->lFlags ) d->lZBufferBitDepth = d->lMipMapCount;
  1162. else if ( DDSD_REFRESHRATE & d->lFlags ) d->lZBufferBitDepth = d->lRefreshRate;
  1163. memcpy (dOut,d,sizeof(DDSURFACEDESC2));
  1164. CopyInDDPixelFormat(&(dOut->ddpfPixelFormat) ,&(d->ddpfPixelFormat));
  1165. memcpy (&dOut->ddsCaps,&d->ddsCaps,sizeof(DDSCAPS2));
  1166. dOut->dwSize=sizeof(DDSURFACEDESC2);
  1167. return S_OK;
  1168. }
  1169. /////////////////////////////////////////////////////////////////////////////
  1170. // CopyInDDPixelFormat cover->real
  1171. //
  1172. // note param ordering differnt that DDSURFACEDESC helpers
  1173. //
  1174. HRESULT CopyInDDPixelFormat(DDPIXELFORMAT *pfOut, DDPixelFormat *pf)
  1175. {
  1176. if (!pf) return E_POINTER;
  1177. if (!pfOut) return E_POINTER;
  1178. if ((pf->lFlags & DDPF_RGB)||(pf->lFlags &DDPF_RGBTOYUV)) {
  1179. pf->internalVal1=pf->lRGBBitCount;
  1180. pf->internalVal2=pf->lRBitMask;
  1181. pf->internalVal3=pf->lGBitMask;
  1182. pf->internalVal4=pf->lBBitMask;
  1183. if (pf->lFlags & DDPF_ALPHAPIXELS ){
  1184. pf->internalVal5=pf->lRGBAlphaBitMask;
  1185. }
  1186. else if (pf->lFlags & DDPF_ZPIXELS ){
  1187. pf->internalVal5=pf->lRGBZBitMask;
  1188. }
  1189. }
  1190. else if (pf->lFlags & DDPF_YUV){
  1191. pf->internalVal1=pf->lYUVBitCount;
  1192. pf->internalVal2=pf->lYBitMask;
  1193. pf->internalVal3=pf->lUBitMask;
  1194. pf->internalVal4=pf->lVBitMask;
  1195. if (pf->lFlags & DDPF_ALPHAPIXELS ){
  1196. pf->internalVal5=pf->lYUVAlphaBitMask;
  1197. }
  1198. else if (pf->lFlags & DDPF_ZPIXELS ){
  1199. pf->internalVal5=pf->lYUVZBitMask;
  1200. }
  1201. }
  1202. else if (pf->lFlags & DDPF_BUMPDUDV) {
  1203. pf->internalVal1=pf->lBumpBitCount;
  1204. pf->internalVal2=pf->lBumpDuBitMask;
  1205. pf->internalVal3=pf->lBumpDvBitMask;
  1206. pf->internalVal4=pf->lBumpLuminanceBitMask;
  1207. }
  1208. //rest of internalVal1
  1209. if (pf->lFlags & DDPF_ZBUFFER){
  1210. pf->internalVal1=pf->lZBufferBitDepth;
  1211. }
  1212. else if (pf->lFlags & DDPF_ALPHA){
  1213. pf->internalVal1=pf->lAlphaBitDepth;
  1214. }
  1215. else if (pf->lFlags & DDPF_LUMINANCE){
  1216. pf->internalVal1=pf->lLuminanceBitCount;
  1217. }
  1218. //rest of internalVal2
  1219. if (pf->lFlags & DDPF_STENCILBUFFER) {
  1220. pf->internalVal2=pf->lStencilBitDepth;
  1221. }
  1222. else if ((pf ->lFlags & DDPF_LUMINANCE) || ( pf->lFlags & DDPF_BUMPLUMINANCE)){
  1223. pf->internalVal2=pf->lLuminanceBitMask;
  1224. }
  1225. // internalVal3
  1226. if ((pf->lFlags & DDPF_ZBUFFER)){
  1227. pf->internalVal3=pf->lZBitMask;
  1228. }
  1229. // internalVal4
  1230. if (pf->lFlags & DDPF_STENCILBUFFER){
  1231. pf->internalVal4=pf->lStencilBitMask;
  1232. }
  1233. // internalVal5
  1234. if (pf->lFlags & DDPF_LUMINANCE) {
  1235. pf->internalVal5=pf->lLuminanceAlphaBitMask;
  1236. }
  1237. /* map to indicate what is valid and when..
  1238. long lRGBBitCount; //DDPF_RGB
  1239. long lYUVBitCount; //DDPF_YUV
  1240. long lZBufferBitDepth; //DDPF_ZBUFFER
  1241. long lAlphaBitDepth; //DDPF_ALPHA
  1242. long lLuminanceBitCount; //DDPF_LUMINANCE
  1243. long lBumpBitCount; //DDPF_BUMPDUDV
  1244. // union for internalVal2
  1245. long lRBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1246. long lYBitMask; //DDPF_YUV
  1247. long lStencilBitMask; //DDPF_STENCILBUFFER
  1248. long lLuminanceBitMask; //DDPF_BUMPLUMINANCE or DDPF_LUMINANCE
  1249. long lBumpDiBitMask; //DDPF_BUMPDUDV
  1250. // union for internalVal3
  1251. long lGBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1252. long lUBitMask; //DPDF_YUV
  1253. long lZBitMask; //DDPF_STENCILBUFFER ?
  1254. long lBumpDvBitMask; //DDPF_BUMPDUDV
  1255. // union for internalVal4
  1256. long lBBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1257. long lVBitMask; //DDPF_YUV
  1258. long lStencilBitMask; //DDPF_STENCILBUFFER
  1259. long lBumpLuminanceBitMask; //DDPF_BUMPDUDV
  1260. // union for internalVal5
  1261. long lRGBAlphaBitMask; //DDPF_RGB and DDPF_ALPHAPIXELS
  1262. long lYUVAlphaBitMask; //DDPF_YUV & DDPF_ALPHAPIXELS
  1263. long lLuminanceAlphaBitMask; //DDPF_LUMINANCE
  1264. long lRGBZBitMask; //DDPF_ZPIXELS & DDPF_RGB
  1265. long lYUVZBitMask; //DDPF_ZPIXELS & DDPF_YUV
  1266. */
  1267. memcpy(pfOut,pf,sizeof(DDPIXELFORMAT));
  1268. pfOut->dwSize=sizeof(DDPIXELFORMAT);
  1269. return S_OK;
  1270. }
  1271. /////////////////////////////////////////////////////////////////////////////
  1272. // CopyOutDDPixelFormat real->cover
  1273. //
  1274. // note param ordering differnt that DDSURFACEDESC helpers
  1275. //
  1276. HRESULT CopyOutDDPixelFormat(DDPixelFormat *pfOut, DDPIXELFORMAT *pf)
  1277. {
  1278. if (!pf) return E_POINTER;
  1279. if (!pfOut) return E_POINTER;
  1280. pfOut->lSize=pf->dwSize;
  1281. pfOut->lFlags=pf->dwFlags;
  1282. pfOut->lFourCC=pf->dwFourCC ;
  1283. pfOut->lRGBBitCount=pf->dwRGBBitCount; //DDPF_RGB
  1284. pfOut->lRGBBitCount=pf->dwRGBBitCount; //DDPF_YUV
  1285. pfOut->lZBufferBitDepth=pf->dwZBufferBitDepth; //DDPF_ZBUFFER
  1286. pfOut->lAlphaBitDepth=pf->dwAlphaBitDepth; //DDPF_ALPHA
  1287. pfOut->lLuminanceBitCount=pf->dwLuminanceBitCount; //DDPF_LUMINANCE
  1288. pfOut->lBumpBitCount=pf->dwBumpBitCount; //DDPF_BUMPDUDV
  1289. // union for internalVal2
  1290. pfOut->lRBitMask=pf->dwRBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1291. pfOut->lYBitMask=pf->dwYBitMask; //DDPF_YUV
  1292. pfOut->lStencilBitDepth=pf->dwStencilBitDepth; //DDPF_STENCILBUFFER
  1293. pfOut->lLuminanceBitMask=pf->dwLuminanceBitMask; //DDPF_BUMPLUMINANCE or DDPF_LUMINANCE
  1294. pfOut->lBumpDuBitMask=pf->dwBumpDuBitMask; //DDPF_BUMPDUDV
  1295. // union for internalVal3
  1296. pfOut->lGBitMask=pf->dwGBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1297. pfOut->lUBitMask=pf->dwUBitMask; //DPDF_YUV
  1298. pfOut->lZBitMask=pf->dwZBitMask; //DDPF_STENCILBUFFER ?
  1299. pfOut->lBumpDvBitMask=pf->dwBumpDvBitMask; //DDPF_BUMPDUDV
  1300. // union for internalVal4
  1301. pfOut->lBBitMask=pf->dwBBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1302. pfOut->lVBitMask=pf->dwVBitMask; //DDPF_YUV
  1303. pfOut->lStencilBitMask=pf->dwStencilBitMask; //DDPF_STENCILBUFFER
  1304. pfOut->lBumpLuminanceBitMask=pf->dwBumpLuminanceBitMask; //DDPF_BUMPDUDV
  1305. // union for internalVal5
  1306. pfOut->lRGBAlphaBitMask=pf->dwRGBAlphaBitMask; //DDPF_RGB and DDPF_ALPHAPIXELS
  1307. pfOut->lYUVAlphaBitMask=pf->dwYUVAlphaBitMask; //DDPF_YUV & DDPF_ALPHAPIXELS
  1308. pfOut->lLuminanceAlphaBitMask=pf->dwLuminanceAlphaBitMask; //DDPF_LUMINANCE
  1309. pfOut->lRGBZBitMask=pf->dwRGBZBitMask; //DDPF_ZPIXELS & DDPF_RGB
  1310. pfOut->lYUVZBitMask=pf->dwYUVZBitMask; //DDPF_ZPIXELS & DDPF_YUV
  1311. return S_OK;
  1312. }
  1313. /////////////////////////////////////////////////////////////////////////////
  1314. // CopyOutDDPixelFormat cover->real
  1315. //
  1316. //
  1317. HRESULT FillRealSessionDesc(DPSESSIONDESC2 *dpSessionDesc,DPSessionDesc2 *sessionDesc){
  1318. long l=0;
  1319. HRESULT hr;
  1320. memset(dpSessionDesc,0,sizeof(DPSESSIONDESC2));
  1321. dpSessionDesc->dwSize = sizeof(DPSESSIONDESC2);
  1322. dpSessionDesc->dwFlags = sessionDesc->lFlags;
  1323. hr=BSTRtoGUID(&(dpSessionDesc->guidInstance),sessionDesc->strGuidInstance);
  1324. if FAILED(hr) return hr;
  1325. hr=BSTRtoGUID(&(dpSessionDesc->guidApplication),sessionDesc->strGuidApplication);
  1326. if FAILED(hr) return hr;
  1327. dpSessionDesc->dwMaxPlayers = sessionDesc->lMaxPlayers;
  1328. dpSessionDesc->dwCurrentPlayers = sessionDesc->lCurrentPlayers;
  1329. //using wide strings
  1330. dpSessionDesc->lpszSessionName=NULL;
  1331. if ((sessionDesc->strSessionName)&& (sessionDesc->strSessionName[0]!='\0')){
  1332. dpSessionDesc->lpszSessionName=SysAllocString(sessionDesc->strSessionName);
  1333. }
  1334. dpSessionDesc->lpszPassword=NULL;
  1335. if ((sessionDesc->strPassword)&& (sessionDesc->strPassword[0]!='\0')){
  1336. dpSessionDesc->lpszPassword=SysAllocString(sessionDesc->strPassword);
  1337. }
  1338. dpSessionDesc->dwReserved1 = 0;
  1339. dpSessionDesc->dwReserved2 = 0;
  1340. dpSessionDesc->dwUser1 = sessionDesc->lUser1;
  1341. dpSessionDesc->dwUser2 = sessionDesc->lUser2;
  1342. dpSessionDesc->dwUser3 = sessionDesc->lUser3;
  1343. dpSessionDesc->dwUser4 = sessionDesc->lUser4;
  1344. return S_OK;
  1345. }
  1346. /////////////////////////////////////////////////////////////////////////////
  1347. // FillCoverSessionDesc real->cover
  1348. //
  1349. //
  1350. void FillCoverSessionDesc(DPSessionDesc2 *sessionDesc,DPSESSIONDESC2 *dpSessionDesc)
  1351. {
  1352. sessionDesc->lFlags = dpSessionDesc->dwFlags;
  1353. sessionDesc->lMaxPlayers = dpSessionDesc->dwMaxPlayers;
  1354. sessionDesc->lCurrentPlayers = dpSessionDesc->dwCurrentPlayers;
  1355. sessionDesc->lUser1 = (long)dpSessionDesc->dwUser1;
  1356. sessionDesc->lUser2 = (long)dpSessionDesc->dwUser2;
  1357. sessionDesc->lUser3 = (long)dpSessionDesc->dwUser3;
  1358. sessionDesc->lUser4 = (long)dpSessionDesc->dwUser4;
  1359. // NOTE: if sessiondesc came in as [out] param then
  1360. // strGuidInstance -strPassword etc. would all be NULL
  1361. // if it pas passed as in out we need to free the existing contents
  1362. // before moving. Consulted with Matt curland to verify if ok.
  1363. if (sessionDesc->strGuidInstance) SysFreeString((BSTR)sessionDesc->strGuidInstance);
  1364. if (sessionDesc->strGuidApplication) SysFreeString((BSTR)sessionDesc->strGuidApplication);
  1365. if (sessionDesc->strSessionName) SysFreeString((BSTR)sessionDesc->strSessionName);
  1366. if (sessionDesc->strPassword) SysFreeString((BSTR)sessionDesc->strPassword);
  1367. sessionDesc->strGuidInstance=GUIDtoBSTR(&(dpSessionDesc->guidInstance));
  1368. sessionDesc->strGuidApplication=GUIDtoBSTR(&(dpSessionDesc->guidApplication));
  1369. sessionDesc->strSessionName = SysAllocString(dpSessionDesc->lpszSessionName);
  1370. sessionDesc->strPassword = SysAllocString(dpSessionDesc->lpszPassword);
  1371. }
  1372. /////////////////////////////////////////////////////////////////////////////
  1373. // IsAllZeros
  1374. //
  1375. BOOL IsAllZeros(void *pStruct,DWORD size){
  1376. for (DWORD i=0;i<size;i++){
  1377. if (((char*)pStruct)[i]!='\0'){
  1378. return FALSE;
  1379. }
  1380. }
  1381. return TRUE;
  1382. }
  1383. /////////////////////////////////////////////////////////////////////////////
  1384. // CopyFloats
  1385. //
  1386. extern "C" void CopyFloats(D3DVALUE *dst, D3DVALUE *src, DWORD count)
  1387. {
  1388. D3DVALUE *ptr1 = dst, *ptr2 = src;
  1389. if (!count) return;
  1390. for (; count; count--) *ptr1++ = *ptr2++;
  1391. return;
  1392. }
  1393. /////////////////////////////////////////////////////////////////////////////
  1394. // IsWin95
  1395. //
  1396. // no longer needed since we support w95 now
  1397. #if 0
  1398. BOOL IsWin95(void)
  1399. {
  1400. return FALSE;
  1401. //We work on win95
  1402. OSVERSIONINFO osvi;
  1403. ZeroMemory(&osvi, sizeof(osvi));
  1404. osvi.dwOSVersionInfoSize = sizeof(osvi);
  1405. if (!GetVersionEx(&osvi))
  1406. {
  1407. DPF(1,"GetVersionEx failed - assuming Win95");
  1408. return TRUE;
  1409. }
  1410. if ( VER_PLATFORM_WIN32_WINDOWS == osvi.dwPlatformId )
  1411. {
  1412. if( ( osvi.dwMajorVersion > 4UL ) ||
  1413. ( ( osvi.dwMajorVersion == 4UL ) &&
  1414. ( osvi.dwMinorVersion >= 10UL ) &&
  1415. ( LOWORD( osvi.dwBuildNumber ) >= 1373 ) ) )
  1416. {
  1417. // is Win98
  1418. DPF(2,"Detected Win98");
  1419. return FALSE;
  1420. }
  1421. else
  1422. {
  1423. // is Win95
  1424. DPF(2,"Detected Win95");
  1425. return TRUE;
  1426. }
  1427. }
  1428. else if ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId )
  1429. {
  1430. DPF(2,"Detected WinNT");
  1431. return FALSE;
  1432. }
  1433. DPF(2,"OS Detection failed");
  1434. return TRUE;
  1435. }
  1436. #endif
  1437. #define DICONDITION_USE_BOTH_AXIS 1
  1438. #define DICONDITION_USE_DIRECTION 2
  1439. /////////////////////////////////////////////////////////////////////////////
  1440. // FixUpRealEffect cover->real
  1441. //
  1442. HRESULT FixUpRealEffect(GUID g,DIEFFECT *realEffect,DIEffect *cover)
  1443. {
  1444. if (!cover) return E_INVALIDARG;
  1445. memcpy(realEffect,cover,sizeof(DIEFFECT));
  1446. realEffect->dwSize =sizeof(DIEFFECT);
  1447. realEffect->lpEnvelope =NULL;
  1448. realEffect->cbTypeSpecificParams =0;
  1449. realEffect->lpvTypeSpecificParams =NULL;
  1450. realEffect->cAxes =2;
  1451. realEffect->dwFlags=realEffect->dwFlags | DIEFF_OBJECTOFFSETS ;
  1452. realEffect->rglDirection =(long*)&(cover->x);
  1453. realEffect->rgdwAxes =(DWORD*)&(cover->axisOffsets);
  1454. if (cover->bUseEnvelope){
  1455. realEffect->lpEnvelope=(DIENVELOPE*)&(cover->envelope);
  1456. ((DIENVELOPE*)&(cover->envelope))->dwSize=sizeof(DIENVELOPE);
  1457. }
  1458. if (!cover->lFlags)
  1459. realEffect->dwFlags= DIEFF_POLAR | DIEFF_OBJECTOFFSETS ;
  1460. //constant
  1461. if (g==GUID_ConstantForce)
  1462. {
  1463. realEffect->cbTypeSpecificParams =sizeof (DICONSTANTFORCE);
  1464. realEffect->lpvTypeSpecificParams =&(cover->constantForce);
  1465. }
  1466. //periodic
  1467. else if ((g==GUID_Square)||(g==GUID_Triangle)||(g==GUID_SawtoothUp)||(g==GUID_SawtoothDown)||(g==GUID_Sine))
  1468. {
  1469. realEffect->cbTypeSpecificParams =sizeof (DIPERIODIC);
  1470. realEffect->lpvTypeSpecificParams =&(cover->periodicForce);
  1471. }
  1472. else if ((g==GUID_Spring)|| (g==GUID_Damper)|| (g==GUID_Inertia)|| (g==GUID_Friction)){
  1473. if (cover->conditionFlags==DICONDITION_USE_BOTH_AXIS){
  1474. realEffect->cbTypeSpecificParams =sizeof(DICONDITION)*2;
  1475. realEffect->lpvTypeSpecificParams =&(cover->conditionX);
  1476. }
  1477. else{
  1478. realEffect->cbTypeSpecificParams =sizeof(DICONDITION);
  1479. realEffect->lpvTypeSpecificParams =&(cover->conditionX);
  1480. }
  1481. }
  1482. else if (g==GUID_RampForce){
  1483. realEffect->cbTypeSpecificParams =sizeof(DIRAMPFORCE);
  1484. realEffect->lpvTypeSpecificParams =&(cover->rampForce);
  1485. }
  1486. cover->axisOffsets.x=DIJOFS_X;
  1487. cover->axisOffsets.y=DIJOFS_Y;
  1488. realEffect->rgdwAxes=(DWORD*)&(cover->axisOffsets);
  1489. return S_OK;
  1490. }
  1491. /////////////////////////////////////////////////////////////////////////////
  1492. // FixUpCoverEffect real->cover
  1493. //
  1494. HRESULT FixUpCoverEffect(GUID g, DIEffect *cover,DIEFFECT *realEffect)
  1495. {
  1496. ZeroMemory(cover,sizeof(DIEffect));
  1497. memcpy(cover,realEffect,sizeof(DIEFFECT));
  1498. if (realEffect->lpEnvelope){
  1499. memcpy(&cover->envelope,realEffect->lpEnvelope ,sizeof(DIENVELOPE));
  1500. cover->bUseEnvelope=VARIANT_TRUE;
  1501. }
  1502. if (realEffect->rglDirection){
  1503. cover->x=realEffect->rglDirection[0];
  1504. cover->y=realEffect->rglDirection[1];
  1505. }
  1506. if (realEffect->lpvTypeSpecificParams){
  1507. if (g==GUID_ConstantForce)
  1508. {
  1509. memcpy(&(cover->constantForce),realEffect->lpvTypeSpecificParams,sizeof(DICONSTANTFORCE));
  1510. }
  1511. //periodic
  1512. else if ((g==GUID_Square)||(g==GUID_Triangle)||(g==GUID_SawtoothUp)||(g==GUID_SawtoothDown)||(g==GUID_Sine))
  1513. {
  1514. memcpy(&(cover->periodicForce),realEffect->lpvTypeSpecificParams,sizeof(DIPERIODIC));
  1515. }
  1516. else if ((g==GUID_Spring)|| (g==GUID_Damper)|| (g==GUID_Inertia)|| (g==GUID_Friction)){
  1517. if (realEffect->cbTypeSpecificParams ==sizeof(DICONDITION)*2){
  1518. memcpy(&(cover->conditionY),realEffect->lpvTypeSpecificParams,sizeof(DICONDITION)*2);
  1519. cover->conditionFlags=DICONDITION_USE_BOTH_AXIS;
  1520. }
  1521. else{
  1522. memcpy(&(cover->conditionX),realEffect->lpvTypeSpecificParams,sizeof(DICONDITION));
  1523. cover->conditionFlags=DICONDITION_USE_DIRECTION;
  1524. }
  1525. }
  1526. else if (g==GUID_RampForce){
  1527. memcpy(&(cover->rampForce),realEffect->lpvTypeSpecificParams,sizeof(DIRAMPFORCE));
  1528. }
  1529. }
  1530. return S_OK;
  1531. }
  1532. /////////////////////////////////////////////////////////////////////////////
  1533. /////////////////////////////////////////////////////////////////////////////
  1534. /////////////////////////////////////////////////////////////////////////////
  1535. //
  1536. // CALLBACK FUNCTIONS
  1537. //
  1538. /////////////////////////////////////////////////////////////////////////////
  1539. /////////////////////////////////////////////////////////////////////////////
  1540. /////////////////////////////////////////////////////////////////////////////
  1541. /////////////////////////////////////////////////////////////////////////////
  1542. // myLoadTextureCallback - rm texture callback
  1543. // only userd by pmesh...
  1544. //
  1545. extern "C" HRESULT __cdecl myLoadTextureCallback(char *tex_name, void *lpArg,
  1546. LPDIRECT3DRMTEXTURE * lpD3DRMTex)
  1547. {
  1548. // user arg will contain our own struct
  1549. struct TextureCallback3 *tcb = (struct TextureCallback3 *)lpArg;
  1550. I_dxj_Direct3dRMTexture3 *iunk = NULL;
  1551. LPDIRECT3DRMTEXTURE lpTex= NULL;
  1552. int i=0;
  1553. // convert to Unicode
  1554. USES_CONVERSION;;
  1555. BSTR tex=T2BSTR(tex_name);
  1556. // user arg is an object -- hang on to it during our callback as a precaution
  1557. if (tcb->pUser) tcb->pUser->AddRef();
  1558. // call the VB callback..
  1559. tcb->c->callbackRMLoadTexture(tex,tcb->pUser , &iunk);
  1560. // give up the extra reference
  1561. if (tcb->pUser) tcb->pUser->Release();
  1562. // free the string allocated by T2BSTR
  1563. SysFreeString((BSTR)tex);
  1564. // given the user returned something in iunk..
  1565. if ( iunk != NULL )
  1566. {
  1567. // get the real object iunk covers
  1568. // note DO_GETOBJECT_NOTNULL does not addref and assumes
  1569. // the cover object allready has a reference.
  1570. DO_GETOBJECT_NOTNULL(LPDIRECT3DRMTEXTURE3,lp,iunk)
  1571. lp->QueryInterface(IID_IDirect3DRMTexture,(void**)&lpTex);
  1572. // give it up to rm
  1573. *lpD3DRMTex = lpTex;
  1574. // we addref the real rm texture (as we are in a callback and
  1575. // need to return an object to rm that it will later release)
  1576. (*lpD3DRMTex)->AddRef();
  1577. // release our reference to the cover object vb gave us
  1578. iunk->Release();
  1579. }
  1580. else
  1581. {
  1582. //otherwise return null to RM
  1583. *lpD3DRMTex = NULL;
  1584. }
  1585. return S_OK;
  1586. }
  1587. /////////////////////////////////////////////////////////////////////////////
  1588. // myLoadTextureCallback3 - rm texture callback
  1589. extern "C" HRESULT __cdecl myLoadTextureCallback3(char *tex_name, void *lpArg,
  1590. LPDIRECT3DRMTEXTURE3 * lpD3DRMTex)
  1591. {
  1592. // user arg will contain our own struct
  1593. struct TextureCallback3 *tcb = (struct TextureCallback3 *)lpArg;
  1594. I_dxj_Direct3dRMTexture3 *iunk = NULL;
  1595. int i=0;
  1596. // convert to Unicode
  1597. USES_CONVERSION;;
  1598. BSTR tex=T2BSTR(tex_name);
  1599. // user arg is an object -- hang on to it during our callback as a precaution
  1600. if (tcb->pUser) tcb->pUser->AddRef();
  1601. // call the VB callback..
  1602. tcb->c->callbackRMLoadTexture(tex,tcb->pUser , &iunk);
  1603. // give up the extra reference
  1604. if (tcb->pUser) tcb->pUser->Release();
  1605. // free the string allocated by T2BSTR
  1606. SysFreeString((BSTR)tex);
  1607. // given the user returned something in iunk..
  1608. if ( iunk != NULL )
  1609. {
  1610. // get the real object iunk covers
  1611. // note DO_GETOBJECT_NOTNULL does not addref and assumes
  1612. // the cover object allready has a reference.
  1613. DO_GETOBJECT_NOTNULL(LPDIRECT3DRMTEXTURE3,lp,iunk)
  1614. // give it up to rm
  1615. *lpD3DRMTex = lp;
  1616. // we addref the real rm texture (as we are in a callback and
  1617. // need to return an object to rm that it will later release)
  1618. (*lpD3DRMTex)->AddRef();
  1619. // release our reference to the cover object vb gave us
  1620. iunk->Release();
  1621. }
  1622. else
  1623. {
  1624. //otherwise return null to RM
  1625. *lpD3DRMTex = NULL;
  1626. }
  1627. return S_OK;
  1628. }
  1629. /////////////////////////////////////////////////////////////////////////////
  1630. // myFrameMoveCallback - rm frame move callback
  1631. //
  1632. // we use a helper so we can call into INTERNAL_CREATE ..
  1633. //
  1634. HRESULT myFrameMoveCallbackHelper(LPDIRECT3DRMFRAME lpf1, void *lpArg, D3DVALUE delta)
  1635. {
  1636. // get our structure from the user args..
  1637. FrameMoveCallback3 *fmcb = (FrameMoveCallback3 *)lpArg;
  1638. LPDIRECT3DRMFRAME3 lpf=NULL;
  1639. I_dxj_Direct3dRMFrame3 *frame3=NULL;
  1640. HRESULT hr;
  1641. // if RM gave is a frame (which it always will) then get the
  1642. // Frame3 interface as the VB api only has 1 frame type
  1643. if (lpf1){
  1644. hr=lpf1->QueryInterface(IID_IDirect3DRMFrame3,(void**)&lpf);
  1645. if FAILED(hr) return hr;
  1646. }
  1647. // Try and find the object in our link list of cover objects
  1648. // if its not there then create one.
  1649. //
  1650. // note: will eat the reference to lpf so dont release
  1651. // bug gives us a frame3 with incrermented ref count
  1652. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMFrame3,lpf,&frame3);
  1653. // if Out of memory try and exit gracefully
  1654. if (!frame3) return E_FAIL;
  1655. // make sure we have a reference to any user arg object
  1656. if (fmcb->pUser) fmcb->pUser->AddRef();
  1657. // make sure our vb callback doesnt go away
  1658. fmcb->c->AddRef ();
  1659. // call into VB
  1660. fmcb->c->callbackRMFrameMove(frame3, fmcb->pUser, delta);
  1661. // clean up our reference to the vb callback
  1662. fmcb->c->Release();
  1663. // clean up our reference to the user arg
  1664. if (fmcb->pUser) fmcb->pUser->Release();
  1665. // clean up of our reference to frame3
  1666. frame3->Release();
  1667. // clean up our reference created when we QI for Frame3
  1668. lpf->Release();
  1669. // clean up the variable passed to us..
  1670. // lpf1->Release();
  1671. return S_OK;
  1672. }
  1673. /////////////////////////////////////////////////////////////////////////////
  1674. // myFrameMoveCallback - rm frame move callback
  1675. //
  1676. extern "C" void __cdecl myFrameMoveCallback( LPDIRECT3DRMFRAME lpf1, void *lpArg, D3DVALUE delta)
  1677. {
  1678. DPF(4,"Entered myFrameMoveCallback\r\n");
  1679. myFrameMoveCallbackHelper(lpf1,lpArg,delta);
  1680. DPF(4,"Exiting myFrameMoveCallback\r\n");
  1681. }
  1682. /////////////////////////////////////////////////////////////////////////////
  1683. // myAddDestroyCallback
  1684. //
  1685. extern "C" void __cdecl myAddDestroyCallback(LPDIRECT3DRMOBJECT obj, void *lpArg)
  1686. {
  1687. DPF(4,"Entered myAddDestroyCallback\r\n");
  1688. // dont play with obj.... this can get you in a recursive
  1689. // situation obj is at refcount zero but calling addref and release
  1690. // on it will get you re-entered into this callback..
  1691. // I guess in rm folks were expected to not do that but could
  1692. // get the name..
  1693. // we will just pass pack any user arg
  1694. // Get our struct from the user args
  1695. d3drmCallback *destroyCb = (d3drmCallback*)lpArg;
  1696. // make sure we keep are reference to the vb callback
  1697. destroyCb->c->AddRef ();
  1698. DPF(4,"myAddDestroyCallback: completed Addref VBCallback\r\n");
  1699. // make sure we have a reference to any user arg object
  1700. if (destroyCb->pUser) destroyCb->pUser->AddRef();
  1701. DPF(4,"myAddDestroyCallback: completed Addref userargs\r\n");
  1702. // call into VB..
  1703. // CONSIDER what happens when VB is being shut down.
  1704. // if we get a reference to the object does that mean that
  1705. // we can still execute the code
  1706. destroyCb->c->callbackRMDestroyObject(destroyCb->pUser);
  1707. DPF(4,"myAddDestroyCallback: call into VB\r\n");
  1708. // release reference to user object
  1709. if (destroyCb->pUser) destroyCb->pUser->AddRef();
  1710. DPF(4,"myAddDestroyCallback: completed release userargs\r\n");
  1711. // release our reference to vb callback
  1712. destroyCb->c->Release();
  1713. DPF(4,"myAddDestroyCallback: completed release VBCallback\r\n");
  1714. DPF(4,"Leaving myAddDestroyCallback\r\n");
  1715. }
  1716. /////////////////////////////////////////////////////////////////////////////
  1717. // myAddUpdateCallback3
  1718. //
  1719. // NOTE: we can only pass the first update rect to VB
  1720. //
  1721. // note we use a cover function so that we can make calls to INTERNAL_CREATE
  1722. //
  1723. #define MYVARIANTINIT(inArg,puser) \
  1724. VariantInit(puser); \
  1725. user.vt=VT_UNKNOWN; \
  1726. user.punkVal = inArg; \
  1727. user.punkVal->AddRef();
  1728. ///////////////////////////////////////////////////////////////////////////
  1729. // myAddUpdateCallback3Helper - called by Load callback
  1730. //
  1731. // seperated out only because have multiple load callbacks
  1732. //
  1733. HRESULT myAddUpdateCallback3Helper ( LPDIRECT3DRMDEVICE3 ref,void *lpArg, int x, LPD3DRECT update)
  1734. {
  1735. // Get our struct from the user args
  1736. DeviceUpdateCallback3 *updateCb = (DeviceUpdateCallback3*)lpArg;
  1737. I_dxj_Direct3dRMDevice3 *device3 = NULL;
  1738. VARIANT user;
  1739. // Try and find the object in our link list of cover objects
  1740. // if its not there then create one.
  1741. //
  1742. // note: will eat the reference to lpf so dont release
  1743. // bug gives us a frame3 with incrermented ref count
  1744. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMDevice3,ref,&device3);
  1745. // for reason unbeknown to me we user a variant here instead
  1746. // of an object in our callback
  1747. MYVARIANTINIT(updateCb->pUser,&user);
  1748. // keep a reference to the callback
  1749. updateCb->c->AddRef();
  1750. // call the callback
  1751. updateCb->c->callbackRMUpdate( device3, NULL, x, (D3dRect*)update);
  1752. // releae our reference to the callback
  1753. updateCb->c->Release();
  1754. // clear any refernce to user args
  1755. VariantClear(&user);
  1756. device3->Release();
  1757. return S_OK;
  1758. }
  1759. ///////////////////////////////////////////////////////////////////////////
  1760. // myLoadCoverFunc - called by Load callback
  1761. //
  1762. // seperated out only because have multiple load callbacks
  1763. //
  1764. extern "C" void __cdecl myAddUpdateCallback3 ( LPDIRECT3DRMDEVICE3 ref,void *lpArg, int x, LPD3DRECT update)
  1765. {
  1766. DPF(4,"Entered myAddUpdateCallback\r\n");
  1767. myAddUpdateCallback3Helper(ref,lpArg,x,update);
  1768. DPF(4,"Exiting myAddUpdateCallback\r\n");
  1769. }
  1770. ///////////////////////////////////////////////////////////////////////////
  1771. // myLoadCoverFunc - called by Load callback
  1772. //
  1773. // seperated out only because have multiple load callbacks
  1774. //
  1775. HRESULT myLoadCoverFunc(LPDIRECT3DRMOBJECT lpo, REFIID ObjGuid, LPVOID lpArg){
  1776. I_dxj_Direct3dRMObject *pObj=NULL;
  1777. HRESULT hr;
  1778. // Get our callback struct from the user args
  1779. LoadCallback *loadcb = (LoadCallback*)lpArg;
  1780. hr =CreateCoverObject(lpo,&pObj);
  1781. // If no coverthing exit
  1782. if ((pObj==NULL) ||(hr!=S_OK)) {
  1783. DPF(4,"Load callback - unrecognized type");
  1784. return E_FAIL;
  1785. }
  1786. // get a string represenation of whats passed in
  1787. BSTR guid=GUIDtoBSTR((LPGUID)&ObjGuid);
  1788. // addref the user arg
  1789. if (loadcb->pUser) loadcb->pUser->AddRef();
  1790. //call into VB
  1791. hr=((I_dxj_Direct3dRMLoadCallback*)(loadcb->c))->callbackRMLoad(&pObj,guid,loadcb->pUser);
  1792. //release the user arg
  1793. if (loadcb->pUser) loadcb->pUser->Release();
  1794. //free the guid string
  1795. SysFreeString((BSTR)guid);
  1796. //then release pObj
  1797. pObj->Release();
  1798. return S_OK;
  1799. }
  1800. /////////////////////////////////////////////////////////////////////////////
  1801. // myd3drmLoadCallback
  1802. //
  1803. extern "C" void __cdecl myd3drmLoadCallback(LPDIRECT3DRMOBJECT lpo, REFIID ObjGuid, LPVOID lpArg)
  1804. {
  1805. DPF(4,"Entered d3drmLoadCallback \r\n");
  1806. myLoadCoverFunc( lpo, ObjGuid, lpArg);
  1807. DPF(4,"Exited d3drmLoadCallback \r\n");
  1808. return;
  1809. }
  1810. /////////////////////////////////////////////////////////////////////////////
  1811. // myCoverEnumObjects
  1812. //
  1813. // NOTE the RM bug this deals with..
  1814. //
  1815. HRESULT myCoverEnumObjects( LPDIRECT3DRMOBJECT lpo,void *lpArg){
  1816. EnumerateObjectsCallback *cb = (EnumerateObjectsCallback*)lpArg;
  1817. I_dxj_Direct3dRMObject *pObj=NULL;
  1818. HRESULT hr;
  1819. hr=CreateCoverObject(lpo,&pObj);
  1820. //RM has a bug in it that gives an extra addreff to lpo
  1821. //get rid of it
  1822. if (lpo) lpo->Release();
  1823. //Make sure things went ok
  1824. if FAILED(hr) return hr;
  1825. if (!pObj ) return E_FAIL;
  1826. //addref user args
  1827. if (cb->pUser) cb->pUser->AddRef();
  1828. //call into VB
  1829. cb->c->callbackRMEnumerateObjects(pObj, cb->pUser);
  1830. //release user args
  1831. if (cb->pUser) cb->pUser->Release();
  1832. //release pObj
  1833. pObj->Release();
  1834. return S_OK;
  1835. }
  1836. /////////////////////////////////////////////////////////////////////////////
  1837. // myEnumerateObjectsCallback
  1838. //
  1839. extern "C" void __cdecl myEnumerateObjectsCallback( LPDIRECT3DRMOBJECT lpo,void *lpArg)
  1840. {
  1841. DPF(4,"Entered myEnumerateObjectsCallback\r\n");
  1842. myCoverEnumObjects(lpo,lpArg);
  1843. DPF(4,"Exited myEnumerateObjectsCallback\r\n");
  1844. return;
  1845. }
  1846. /////////////////////////////////////////////////////////////////////////////
  1847. // UndoCallbackLink
  1848. //
  1849. extern "C" void UndoCallbackLink(GeneralCallback *entry, GeneralCallback **head)
  1850. {
  1851. if (entry->next)
  1852. entry->next->prev = entry->prev; // pick members below us
  1853. else
  1854. *head = entry->prev; // possibly NULL
  1855. if (entry->prev)
  1856. entry->prev->next = entry->next; // link to members above us
  1857. if (entry->pUser) entry->pUser->Release();
  1858. delete entry;
  1859. }
  1860. /////////////////////////////////////////////////////////////////////////////
  1861. // AddCallbackLink
  1862. //
  1863. // Add another entry in the object link list
  1864. extern "C" void* AddCallbackLink(void **ptr2,I_dxj_Direct3dRMCallback *enumC,void *args)
  1865. {
  1866. d3drmCallback *enumcb = new d3drmCallback; // new link entry
  1867. if ( !enumcb ) {
  1868. DPF(4,"Creation using new failed\r\n");
  1869. return (d3drmCallback*)NULL;
  1870. }
  1871. enumcb->c = enumC; // user callback
  1872. enumcb->pUser = (struct IUnknown *)args; // callback args
  1873. enumcb->pParent = NULL;
  1874. enumcb->prev = (d3drmCallback*)NULL;
  1875. enumcb->m_stopflag = FALSE;
  1876. enumcb->m_obj = NULL;
  1877. //CONSIDER: locking the linked list here with a semaphore
  1878. // to be more multithread friendly..
  1879. // shame shame- possible gpf otherwise
  1880. enumcb->next = (d3drmCallback*)(*ptr2); // link to other calls
  1881. *ptr2 = enumcb; // we are at the top
  1882. if (enumcb->pUser) enumcb->pUser->AddRef();
  1883. if (enumcb->prev != NULL) // nested callbacks
  1884. {
  1885. enumcb->prev->next = enumcb; // back link
  1886. DPF(4,"Callback nesting encountered\r\n");
  1887. }
  1888. // Need unlock here.
  1889. return enumcb;
  1890. }
  1891. /////////////////////////////////////////////////////////////////////////////
  1892. extern "C" HRESULT _AddDestroyCallback(IDirect3DRMObject *iface, I_dxj_Direct3dRMCallback *oC,
  1893. IUnknown *args)
  1894. {
  1895. return E_NOTIMPL;
  1896. #if 0
  1897. DestroyCallback *dcb;
  1898. // killed by companion DeleteDestroyCallback
  1899. dcb = (DestroyCallback*)AddCallbackLink((void**)&DestroyCallbacks,
  1900. (I_dxj_Direct3dRMCallback*)oC, (void*) args);
  1901. if (!(dcb))
  1902. {
  1903. DPF(4,"AddDestroyCallback failed!\r\n");
  1904. return E_FAIL;
  1905. }
  1906. if (iface->AddDestroyCallback(
  1907. myAddDestroyCallback, dcb))
  1908. return E_FAIL;
  1909. oC->AddRef(); // callback is persistent so make it so in Java/VB Land
  1910. //oC->AddRef(); //? 2 ...
  1911. return S_OK;
  1912. #endif
  1913. }
  1914. /////////////////////////////////////////////////////////////////////////////
  1915. extern "C" HRESULT _DeleteDestroyCallback(IDirect3DRMObject *iface, I_dxj_Direct3dRMCallback *oC,
  1916. IUnknown *args)
  1917. {
  1918. return E_NOTIMPL;
  1919. #if 0
  1920. DestroyCallback *dcb = DestroyCallbacks;
  1921. // look for our own specific entry
  1922. for ( ; dcb; dcb = dcb->next ) {
  1923. if( (dcb->c == oC) && (dcb->pUser == args) ) {
  1924. //note: assume the callback is not called: only removed from a list.
  1925. iface->DeleteDestroyCallback(
  1926. myAddDestroyCallback, dcb);
  1927. // Remove ourselves in a thread-safe manner.
  1928. UndoCallbackLink((GeneralCallback*)dcb,
  1929. (GeneralCallback**)&DestroyCallbacks);
  1930. iface->Release();
  1931. return S_OK;
  1932. }
  1933. }
  1934. iface->Release(); // none found so a release is not needed
  1935. return E_FAIL;
  1936. #endif
  1937. }