Source code of Windows XP (NT5)
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.

2407 lines
65 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=W2T(bstr);
  651. //first and last char should be { }
  652. if ((szGuid[0]!='{')||(szGuid[37]!='}'))
  653. return E_INVALIDARG;
  654. if ((szGuid[9]!='-')||(szGuid[14]!='-')||(szGuid[19]!='-')||(szGuid[24]!='-'))
  655. return E_INVALIDARG;
  656. char val;
  657. char *pData=(char*)pGuid;
  658. int j=0;
  659. int i;
  660. //FIRST DWORD
  661. for ( i=7;i>=1;i=i-2){
  662. hr=convertChar(szGuid,i,&val);
  663. if FAILED(hr) return hr;
  664. pData[j++]=val;
  665. }
  666. //FIRST WORD
  667. for ( i=12;i>=10;i=i-2){
  668. hr=convertChar(szGuid,i,&val);
  669. if FAILED(hr) return hr;
  670. pData[j++]=val;
  671. }
  672. //2nd WORD
  673. for ( i=17;i>=15;i=i-2){
  674. hr=convertChar(szGuid,i,&val);
  675. if FAILED(hr) return hr;
  676. pData[j++]=val;
  677. }
  678. //3rd DWORD - BYTE ARRAY
  679. for ( i=20;i<24;i=i+2){
  680. hr=convertChar(szGuid,i,&val);
  681. if FAILED(hr) return hr;
  682. pData[j++]=val;
  683. }
  684. //BYTE ARRAY
  685. for ( i=25;i<37;i=i+2){
  686. hr=convertChar(szGuid,i,&val);
  687. if FAILED(hr) return hr;
  688. pData[j++]=val;
  689. }
  690. return S_OK;
  691. }
  692. /////////////////////////////////////////////////////////////////////////////
  693. //
  694. //
  695. HRESULT BSTRtoPPGUID(LPGUID *ppGuid, BSTR bstr){
  696. if (!ppGuid) return E_INVALIDARG;
  697. if ((bstr==NULL)||(bstr[0]=='\0')){
  698. *ppGuid=NULL;
  699. return S_OK;
  700. }
  701. return BSTRtoGUID(*ppGuid,bstr);
  702. }
  703. /////////////////////////////////////////////////////////////////////////////
  704. // D3DBSTRtoGUID - does conversion
  705. //
  706. HRESULT D3DBSTRtoGUID(LPGUID pGuid,BSTR str){
  707. HRESULT hr=S_OK;
  708. if (!pGuid) return E_INVALIDARG;
  709. if (!str) {
  710. ZeroMemory(pGuid,sizeof(GUID));
  711. return S_OK;
  712. }
  713. if( 0==_wcsicmp(str,L"iid_idirect3drgbdevice")){
  714. memcpy(pGuid,&IID_IDirect3DRGBDevice,sizeof(GUID));
  715. }
  716. else if( 0==_wcsicmp(str,L"iid_idirect3dhaldevice")){
  717. memcpy(pGuid,&IID_IDirect3DHALDevice,sizeof(GUID));
  718. }
  719. else if( 0==_wcsicmp(str,L"iid_idirect3dmmxdevice")){
  720. memcpy(pGuid,&IID_IDirect3DMMXDevice,sizeof(GUID));
  721. }
  722. else if( 0==_wcsicmp(str,L"iid_idirect3drefdevice")){
  723. memcpy(pGuid,&IID_IDirect3DRefDevice,sizeof(GUID));
  724. }
  725. else if( 0==_wcsicmp(str,L"iid_idirect3dnulldevice")){
  726. memcpy(pGuid,&IID_IDirect3DNullDevice,sizeof(GUID));
  727. }
  728. else {
  729. hr = BSTRtoGUID(pGuid,str);
  730. }
  731. return hr;
  732. }
  733. /////////////////////////////////////////////////////////////////////////////
  734. // D3DGUIDtoBSTR - does conversion
  735. //
  736. BSTR D3DGUIDtoBSTR(LPGUID pg){
  737. HRESULT hr=S_OK;
  738. WCHAR *pStr=NULL;
  739. if (!pg)
  740. return NULL;
  741. else if (GUIDS_EQUAL(IID_IDirect3DNullDevice,pg)){
  742. pStr=L"IID_IDirect3DNullDevice";
  743. }
  744. else if (GUIDS_EQUAL(IID_IDirect3DRefDevice,pg)){
  745. pStr=L"IID_IDirect3DRefDevice";
  746. }
  747. else if (GUIDS_EQUAL(IID_IDirect3DMMXDevice,pg)){
  748. pStr=L"IID_IDirect3DMMXDevice";
  749. }
  750. else if (GUIDS_EQUAL(IID_IDirect3DHALDevice,pg)){
  751. pStr=L"IID_IDirect3DHALDevice";
  752. }
  753. else if (GUIDS_EQUAL(IID_IDirect3DRGBDevice,pg)){
  754. pStr=L"IID_IDirect3DRGBDevice";
  755. }
  756. if (pStr){
  757. return DXALLOCBSTR(pStr);
  758. }
  759. else {
  760. return GUIDtoBSTR(pg);
  761. }
  762. }
  763. /////////////////////////////////////////////////////////////////////////////
  764. // DINPUTGUIDtoBSTR
  765. //
  766. BSTR DINPUTGUIDtoBSTR(LPGUID pg){
  767. HRESULT hr=S_OK;
  768. WCHAR *pStr=NULL;
  769. if (!pg)
  770. return NULL;
  771. else if (GUIDS_EQUAL(GUID_XAxis,pg)){
  772. pStr=L"GUID_XAxis";
  773. }
  774. else if (GUIDS_EQUAL(GUID_YAxis,pg)){
  775. pStr=L"GUID_YAxis";
  776. }
  777. else if (GUIDS_EQUAL(GUID_ZAxis,pg)){
  778. pStr=L"GUID_ZAxis";
  779. }
  780. else if (GUIDS_EQUAL(GUID_RxAxis,pg)){
  781. pStr=L"GUID_RxAxis";
  782. }
  783. else if (GUIDS_EQUAL(GUID_RyAxis,pg)){
  784. pStr=L"GUID_RyAxis";
  785. }
  786. else if (GUIDS_EQUAL(GUID_RzAxis,pg)){
  787. pStr=L"GUID_RzAxis";
  788. }
  789. else if (GUIDS_EQUAL(GUID_Slider,pg)){
  790. pStr=L"GUID_Slider";
  791. }
  792. else if (GUIDS_EQUAL(GUID_Button,pg)){
  793. pStr=L"GUID_Button";
  794. }
  795. else if (GUIDS_EQUAL(GUID_Key,pg)){
  796. pStr=L"GUID_Key";
  797. }
  798. else if (GUIDS_EQUAL(GUID_POV,pg)){
  799. pStr=L"GUID_POV";
  800. }
  801. else if (GUIDS_EQUAL(GUID_Unknown,pg)){
  802. pStr=L"GUID_Unknown";
  803. }
  804. else if (GUIDS_EQUAL(GUID_SysMouse,pg)){
  805. pStr=L"GUID_SysMouse";
  806. }
  807. else if (GUIDS_EQUAL(GUID_SysKeyboard,pg)){
  808. pStr=L"GUID_SysKeyboard";
  809. }
  810. else if (GUIDS_EQUAL(GUID_ConstantForce,pg)){
  811. pStr=L"GUID_ConstantForce";
  812. }
  813. else if (GUIDS_EQUAL(GUID_Square,pg)){
  814. pStr=L"GUID_Square";
  815. }
  816. else if (GUIDS_EQUAL(GUID_Sine,pg)){
  817. pStr=L"GUID_Sine";
  818. }
  819. else if (GUIDS_EQUAL(GUID_Triangle,pg)){
  820. pStr=L"GUID_Triangle";
  821. }
  822. else if (GUIDS_EQUAL(GUID_SawtoothUp,pg)){
  823. pStr=L"GUID_SawtoothUp";
  824. }
  825. else if (GUIDS_EQUAL(GUID_SawtoothDown,pg)){
  826. pStr=L"GUID_SawtoothDown";
  827. }
  828. else if (GUIDS_EQUAL(GUID_Spring,pg)){
  829. pStr=L"GUID_Spring";
  830. }
  831. else if (GUIDS_EQUAL(GUID_Damper,pg)){
  832. pStr=L"GUID_Damper";
  833. }
  834. else if (GUIDS_EQUAL(GUID_Inertia,pg)){
  835. pStr=L"GUID_Inertia";
  836. }
  837. else if (GUIDS_EQUAL(GUID_Friction,pg)){
  838. pStr=L"GUID_Friction";
  839. }
  840. else if (GUIDS_EQUAL(GUID_CustomForce,pg)){
  841. pStr=L"GUID_CustomForce";
  842. }
  843. else if (GUIDS_EQUAL(GUID_RampForce,pg)){
  844. pStr=L"GUID_RampForce";
  845. }
  846. //else if (GUIDS_EQUAL(GUID_Joystick,pg)){
  847. // pStr=L"GUID_JoyStick";
  848. //}
  849. if (pStr){
  850. return DXALLOCBSTR(pStr);
  851. }
  852. else {
  853. return GUIDtoBSTR(pg);
  854. }
  855. }
  856. /////////////////////////////////////////////////////////////////////////////
  857. // DINPUTBSTRtoGUID
  858. //
  859. HRESULT DINPUTBSTRtoGUID(LPGUID pGuid,BSTR str){
  860. HRESULT hr=S_OK;
  861. if (!pGuid) return E_INVALIDARG;
  862. if (!str) {
  863. ZeroMemory(pGuid,sizeof(GUID));
  864. return S_OK;
  865. }
  866. if( 0==_wcsicmp(str,L"guid_xaxis")){
  867. memcpy(pGuid,&GUID_XAxis,sizeof(GUID));
  868. }
  869. else if( 0==_wcsicmp(str,L"guid_yaxis")){
  870. memcpy(pGuid,&GUID_YAxis,sizeof(GUID));
  871. }
  872. else if( 0==_wcsicmp(str,L"guid_zaxis")){
  873. memcpy(pGuid,&GUID_ZAxis,sizeof(GUID));
  874. }
  875. else if( 0==_wcsicmp(str,L"guid_rxaxis")){
  876. memcpy(pGuid,&GUID_RxAxis,sizeof(GUID));
  877. }
  878. else if( 0==_wcsicmp(str,L"guid_ryaxis")){
  879. memcpy(pGuid,&GUID_RyAxis,sizeof(GUID));
  880. }
  881. else if( 0==_wcsicmp(str,L"guid_rzaxis")){
  882. memcpy(pGuid,&GUID_RzAxis,sizeof(GUID));
  883. }
  884. else if( 0==_wcsicmp(str,L"guid_slider")){
  885. memcpy(pGuid,&GUID_Slider,sizeof(GUID));
  886. }
  887. else if( 0==_wcsicmp(str,L"guid_button")){
  888. memcpy(pGuid,&GUID_Button,sizeof(GUID));
  889. }
  890. else if( 0==_wcsicmp(str,L"guid_key")){
  891. memcpy(pGuid,&GUID_Key,sizeof(GUID));
  892. }
  893. else if( 0==_wcsicmp(str,L"guid_pov")){
  894. memcpy(pGuid,&GUID_POV,sizeof(GUID));
  895. }
  896. else if( 0==_wcsicmp(str,L"guid_unknown")){
  897. memcpy(pGuid,&GUID_Unknown,sizeof(GUID));
  898. }
  899. else if( 0==_wcsicmp(str,L"guid_sysmouse")){
  900. memcpy(pGuid,&GUID_SysMouse,sizeof(GUID));
  901. }
  902. else if( 0==_wcsicmp(str,L"guid_syskeyboard")){
  903. memcpy(pGuid,&GUID_SysKeyboard,sizeof(GUID));
  904. }
  905. else if( 0==_wcsicmp(str,L"guid_constantforce")){
  906. memcpy(pGuid,&GUID_ConstantForce,sizeof(GUID));
  907. }
  908. else if( 0==_wcsicmp(str,L"guid_square")){
  909. memcpy(pGuid,&GUID_Square,sizeof(GUID));
  910. }
  911. else if( 0==_wcsicmp(str,L"guid_sine")){
  912. memcpy(pGuid,&GUID_Sine,sizeof(GUID));
  913. }
  914. else if( 0==_wcsicmp(str,L"guid_triangle")){
  915. memcpy(pGuid,&GUID_Triangle,sizeof(GUID));
  916. }
  917. else if( 0==_wcsicmp(str,L"guid_sawtoothup")){
  918. memcpy(pGuid,&GUID_SawtoothUp,sizeof(GUID));
  919. }
  920. else if( 0==_wcsicmp(str,L"guid_sawtoothdown")){
  921. memcpy(pGuid,&GUID_SawtoothDown,sizeof(GUID));
  922. }
  923. else if( 0==_wcsicmp(str,L"guid_spring")){
  924. memcpy(pGuid,&GUID_Spring,sizeof(GUID));
  925. }
  926. else if( 0==_wcsicmp(str,L"guid_damper")){
  927. memcpy(pGuid,&GUID_Damper,sizeof(GUID));
  928. }
  929. else if( 0==_wcsicmp(str,L"guid_inertia")){
  930. memcpy(pGuid,&GUID_Inertia,sizeof(GUID));
  931. }
  932. else if( 0==_wcsicmp(str,L"guid_friction")){
  933. memcpy(pGuid,&GUID_Friction,sizeof(GUID));
  934. }
  935. else if( 0==_wcsicmp(str,L"guid_customforce")){
  936. memcpy(pGuid,&GUID_CustomForce,sizeof(GUID));
  937. }
  938. else if( 0==_wcsicmp(str,L"guid_rampforce")){
  939. memcpy(pGuid,&GUID_RampForce,sizeof(GUID));
  940. }
  941. //else if( 0==_wcsicmp(str,L"guid_joystick")){
  942. // memcpy(pGuid,&GUID_Joystick,sizeof(GUID));
  943. //}
  944. else {
  945. hr = BSTRtoGUID(pGuid,str);
  946. }
  947. return hr;
  948. }
  949. /////////////////////////////////////////////////////////////////////////////
  950. /////////////////////////////////////////////////////////////////////////////
  951. /////////////////////////////////////////////////////////////////////////////
  952. //
  953. // GENERAL HELPER FUNCTIONS
  954. //
  955. /////////////////////////////////////////////////////////////////////////////
  956. /////////////////////////////////////////////////////////////////////////////
  957. /////////////////////////////////////////////////////////////////////////////
  958. /////////////////////////////////////////////////////////////////////////////
  959. // CreateCoverObject
  960. //
  961. // NOTE this function call INTERNAL_CREATE_NOADDREF alot
  962. // the only difference from INTERNAL_CREATE is that these objects will not
  963. // have a reference to the object that created them if they are not
  964. // available to the user in an existing user variable.. (not in the ll allready)
  965. //
  966. // The parent pointer is a vestige of DX5 support where we had to
  967. // manage the order of release calls. But that only happens for ddraw api
  968. HRESULT CreateCoverObject(LPDIRECT3DRMOBJECT lpo, I_dxj_Direct3dRMObject **coverObj)
  969. {
  970. IUnknown *realThing=NULL;
  971. IUnknown *coverThing=NULL;
  972. IDirect3DRMInterpolator *pInter=NULL;
  973. //See if we where passed an interpolator
  974. if (S_OK==lpo->QueryInterface(IID_IDirect3DRMInterpolator,(void**)&pInter)){
  975. // Figure out what kind
  976. if (S_OK==pInter->QueryInterface(IID_IDirect3DRMFrame3,(void**)&realThing)){
  977. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMFrameInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  978. }
  979. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMMeshBuilder3,(void**)&realThing)){
  980. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMeshInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  981. }
  982. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMViewport2,(void**)&realThing)){
  983. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMViewportInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  984. }
  985. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMTexture3,(void**)&realThing)){
  986. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMTextureInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  987. }
  988. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMMaterial2,(void**)&realThing)){
  989. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMaterialInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  990. }
  991. else if (S_OK==pInter->QueryInterface(IID_IDirect3DRMLight,(void**)&realThing)){
  992. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMLightInterpolator,(IDirect3DRMInterpolator*)pInter,&coverThing);
  993. }
  994. else {
  995. // release reference from original Interpolator QI and exit
  996. DPF(1,"CreateCoverObject unable to find interpolator\r\n");
  997. pInter->Release();
  998. return E_FAIL;
  999. }
  1000. //dont need pinter anymore
  1001. pInter->Release();
  1002. }
  1003. else {
  1004. // Not an interpolator.. See what else it could be.
  1005. if (S_OK==lpo->QueryInterface(IID_IDirect3DRMMeshBuilder3,(void**)&realThing)){
  1006. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMeshBuilder3,(IDirect3DRMMeshBuilder3*)realThing,&coverThing);
  1007. }
  1008. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMAnimation2,(void**)&realThing)){
  1009. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMAnimation2,(IDirect3DRMAnimation2*)realThing,&coverThing);
  1010. }
  1011. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMAnimationSet2,(void**)&realThing)){
  1012. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMAnimationSet2,(IDirect3DRMAnimationSet2*)realThing,&coverThing);
  1013. }
  1014. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMFrame3,(void**)&realThing)){
  1015. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMFrame3,(IDirect3DRMFrame3*)realThing,&coverThing);
  1016. }
  1017. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMFace2,(void**)&realThing)){
  1018. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMFace2,(IDirect3DRMFace2*)realThing,&coverThing);
  1019. }
  1020. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMDevice3,(void**)&realThing)){
  1021. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMDevice3,(IDirect3DRMDevice3*)realThing,&coverThing);
  1022. }
  1023. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMTexture3,(void**)&realThing)){
  1024. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMTexture3,(IDirect3DRMTexture3*)realThing,&coverThing);
  1025. }
  1026. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMLight,(void**)&realThing)){
  1027. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMLight,(IDirect3DRMLight*)realThing,&coverThing);
  1028. }
  1029. // no longer support USERVISUALS
  1030. // else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMUserVisual,(void**)&realThing)){
  1031. // INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMUserVisual,(IDirect3DRMUserVisual*)realThing,&coverThing);
  1032. // }
  1033. else {
  1034. DPF(4,"CreateCoverObject didnt recognize guid");
  1035. return E_FAIL;
  1036. }
  1037. }
  1038. if (!coverThing) return E_OUTOFMEMORY;
  1039. // All objects should support RMObject so get that interface
  1040. if (FAILED(coverThing->QueryInterface(IID_I_dxj_Direct3dRMObject, (void **)coverObj))) {
  1041. coverThing->Release();
  1042. return E_NOINTERFACE;
  1043. }
  1044. // Pass back cover object to user - has inc ref count from QI
  1045. coverThing->Release();
  1046. return S_OK;
  1047. }
  1048. /////////////////////////////////////////////////////////////////////////////
  1049. // CreateCoverVisual
  1050. //
  1051. // Similar to CreateCoverObject
  1052. //
  1053. HRESULT CreateCoverVisual(LPDIRECT3DRMOBJECT lpo, I_dxj_Direct3dRMVisual **ppret)
  1054. {
  1055. IUnknown *realThing=NULL;
  1056. IUnknown *coverThing=NULL;
  1057. I_dxj_Direct3dRMVisual *pObj=NULL;
  1058. *ppret=NULL;
  1059. //What kind of visual are we
  1060. if (S_OK==lpo->QueryInterface(IID_IDirect3DRMMeshBuilder3,(void**)&realThing)) {
  1061. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMeshBuilder3,(IDirect3DRMMeshBuilder3*)realThing,&coverThing);
  1062. }
  1063. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMTexture3,(void**)&realThing)){
  1064. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMTexture3,(IDirect3DRMTexture3*)realThing,&coverThing);
  1065. }
  1066. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMMesh,(void**)&realThing)){
  1067. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMMesh,(IDirect3DRMMesh*)realThing,&coverThing);
  1068. }
  1069. else if (S_OK==lpo->QueryInterface(IID_IDirect3DRMProgressiveMesh,(void**)&realThing)){
  1070. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMProgressiveMesh,(IDirect3DRMProgressiveMesh*)realThing,&coverThing);
  1071. }
  1072. else {
  1073. DPF(4," didnt recognize Visual in CreateCoverVisual");
  1074. return E_FAIL;
  1075. }
  1076. //release first QI
  1077. if (realThing) realThing->Release();
  1078. //make sure we have a coverThing.
  1079. if (!coverThing) return E_FAIL;
  1080. //QI for Visual Base Interface
  1081. if (FAILED(coverThing->QueryInterface(IID_I_dxj_Direct3dRMVisual, (void **)ppret))){
  1082. DPF(4,"CreateCoverVisual QI for object failed");
  1083. coverThing->Release ();
  1084. return E_FAIL;
  1085. }
  1086. //release 2nd QI
  1087. coverThing->Release();
  1088. return S_OK;
  1089. }
  1090. /////////////////////////////////////////////////////////////////////////////
  1091. // _GetName helper function for RM object base class
  1092. //
  1093. extern "C" HRESULT _GetName(IDirect3DRMObject *iface, BSTR *Name, BOOL bNameNotClassName)
  1094. {
  1095. DWORD cnt = 0;
  1096. LPSTR str ; // ANSI buffer on stack;
  1097. if( bNameNotClassName )
  1098. {
  1099. if((iface->GetName(&cnt,(char*)NULL)) != D3DRM_OK) // size
  1100. return E_FAIL;
  1101. str = (LPSTR)alloca(cnt); // ANSI buffer on stack;
  1102. if((iface->GetName(&cnt, str)) != D3DRM_OK)
  1103. return E_FAIL;
  1104. }
  1105. else
  1106. {
  1107. if((iface->GetClassName(&cnt,(char*)NULL)) != D3DRM_OK) // size
  1108. return E_FAIL;
  1109. str = (LPSTR)alloca(cnt); // ANSI buffer on stack;
  1110. if((iface->GetClassName(&cnt, str)) != D3DRM_OK)
  1111. return E_FAIL;
  1112. }
  1113. PassBackUnicode(str, Name, cnt);
  1114. return D3DRM_OK;
  1115. }
  1116. /////////////////////////////////////////////////////////////////////////////
  1117. // Given an ANSI string, pass back a UNICODE string
  1118. // SysAllocString is your big friend here.
  1119. //
  1120. // CONSIDER finding all occerence of use and replacint with the
  1121. // T2BSTR macro .. much cleaner
  1122. //
  1123. extern "C" void PassBackUnicode(LPSTR str, BSTR *Name, DWORD cnt)
  1124. {
  1125. //NOTE: length header is required to be filled, but the BSTR pointer
  1126. // points to the first character, not the length.
  1127. // note, the count can never be too small as we get that from the string
  1128. // before we pass it in!
  1129. USES_CONVERSION;
  1130. LPWSTR lpw = (LPWSTR)malloc((cnt+1)*2);
  1131. if (!lpw) return; //fix for bug45158 -no way of producing error code. (hmm)
  1132. void *l = (void *)lpw;
  1133. lpw = AtlA2WHelper(lpw, str, cnt);
  1134. lpw[cnt] = 0;
  1135. *Name = SysAllocString(lpw);
  1136. free(l);
  1137. }
  1138. /////////////////////////////////////////////////////////////////////////////
  1139. // CopyOutDDSurfaceDesc2 real->cover
  1140. //
  1141. HRESULT CopyOutDDSurfaceDesc2(DDSurfaceDesc2 *dOut,DDSURFACEDESC2 *d){
  1142. ZeroMemory(dOut, sizeof(DDSurfaceDesc2));
  1143. memcpy (dOut,d,sizeof(DDSURFACEDESC2));
  1144. dOut->lMipMapCount=d->dwMipMapCount;
  1145. dOut->lRefreshRate=d->dwRefreshRate;
  1146. // Get Caps
  1147. dOut->ddsCaps.lCaps = d->ddsCaps.dwCaps;
  1148. dOut->ddsCaps.lCaps2 = d->ddsCaps.dwCaps2;
  1149. dOut->ddsCaps.lCaps3 = d->ddsCaps.dwCaps3;
  1150. dOut->ddsCaps.lCaps4 = d->ddsCaps.dwCaps4;
  1151. CopyOutDDPixelFormat(&(dOut->ddpfPixelFormat) ,&(d->ddpfPixelFormat));
  1152. return S_OK;
  1153. }
  1154. /////////////////////////////////////////////////////////////////////////////
  1155. // CopyInDDSurfaceDesc2 cover->real
  1156. //
  1157. HRESULT CopyInDDSurfaceDesc2(DDSURFACEDESC2 *dOut,DDSurfaceDesc2 *d){
  1158. if(!d) return E_POINTER;
  1159. else if(!dOut) return E_POINTER;
  1160. else if ( DDSD_MIPMAPCOUNT & d->lFlags ) d->lZBufferBitDepth = d->lMipMapCount;
  1161. else if ( DDSD_REFRESHRATE & d->lFlags ) d->lZBufferBitDepth = d->lRefreshRate;
  1162. memcpy (dOut,d,sizeof(DDSURFACEDESC2));
  1163. CopyInDDPixelFormat(&(dOut->ddpfPixelFormat) ,&(d->ddpfPixelFormat));
  1164. memcpy (&dOut->ddsCaps,&d->ddsCaps,sizeof(DDSCAPS2));
  1165. dOut->dwSize=sizeof(DDSURFACEDESC2);
  1166. return S_OK;
  1167. }
  1168. /////////////////////////////////////////////////////////////////////////////
  1169. // CopyInDDPixelFormat cover->real
  1170. //
  1171. // note param ordering differnt that DDSURFACEDESC helpers
  1172. //
  1173. HRESULT CopyInDDPixelFormat(DDPIXELFORMAT *pfOut, DDPixelFormat *pf)
  1174. {
  1175. if (!pf) return E_POINTER;
  1176. if (!pfOut) return E_POINTER;
  1177. if ((pf->lFlags & DDPF_RGB)||(pf->lFlags &DDPF_RGBTOYUV)) {
  1178. pf->internalVal1=pf->lRGBBitCount;
  1179. pf->internalVal2=pf->lRBitMask;
  1180. pf->internalVal3=pf->lGBitMask;
  1181. pf->internalVal4=pf->lBBitMask;
  1182. if (pf->lFlags & DDPF_ALPHAPIXELS ){
  1183. pf->internalVal5=pf->lRGBAlphaBitMask;
  1184. }
  1185. else if (pf->lFlags & DDPF_ZPIXELS ){
  1186. pf->internalVal5=pf->lRGBZBitMask;
  1187. }
  1188. }
  1189. else if (pf->lFlags & DDPF_YUV){
  1190. pf->internalVal1=pf->lYUVBitCount;
  1191. pf->internalVal2=pf->lYBitMask;
  1192. pf->internalVal3=pf->lUBitMask;
  1193. pf->internalVal4=pf->lVBitMask;
  1194. if (pf->lFlags & DDPF_ALPHAPIXELS ){
  1195. pf->internalVal5=pf->lYUVAlphaBitMask;
  1196. }
  1197. else if (pf->lFlags & DDPF_ZPIXELS ){
  1198. pf->internalVal5=pf->lYUVZBitMask;
  1199. }
  1200. }
  1201. else if (pf->lFlags & DDPF_BUMPDUDV) {
  1202. pf->internalVal1=pf->lBumpBitCount;
  1203. pf->internalVal2=pf->lBumpDuBitMask;
  1204. pf->internalVal3=pf->lBumpDvBitMask;
  1205. pf->internalVal4=pf->lBumpLuminanceBitMask;
  1206. }
  1207. //rest of internalVal1
  1208. if (pf->lFlags & DDPF_ZBUFFER){
  1209. pf->internalVal1=pf->lZBufferBitDepth;
  1210. }
  1211. else if (pf->lFlags & DDPF_ALPHA){
  1212. pf->internalVal1=pf->lAlphaBitDepth;
  1213. }
  1214. else if (pf->lFlags & DDPF_LUMINANCE){
  1215. pf->internalVal1=pf->lLuminanceBitCount;
  1216. }
  1217. //rest of internalVal2
  1218. if (pf->lFlags & DDPF_STENCILBUFFER) {
  1219. pf->internalVal2=pf->lStencilBitDepth;
  1220. }
  1221. else if ((pf ->lFlags & DDPF_LUMINANCE) || ( pf->lFlags & DDPF_BUMPLUMINANCE)){
  1222. pf->internalVal2=pf->lLuminanceBitMask;
  1223. }
  1224. // internalVal3
  1225. if ((pf->lFlags & DDPF_ZBUFFER)){
  1226. pf->internalVal3=pf->lZBitMask;
  1227. }
  1228. // internalVal4
  1229. if (pf->lFlags & DDPF_STENCILBUFFER){
  1230. pf->internalVal4=pf->lStencilBitMask;
  1231. }
  1232. // internalVal5
  1233. if (pf->lFlags & DDPF_LUMINANCE) {
  1234. pf->internalVal5=pf->lLuminanceAlphaBitMask;
  1235. }
  1236. /* map to indicate what is valid and when..
  1237. long lRGBBitCount; //DDPF_RGB
  1238. long lYUVBitCount; //DDPF_YUV
  1239. long lZBufferBitDepth; //DDPF_ZBUFFER
  1240. long lAlphaBitDepth; //DDPF_ALPHA
  1241. long lLuminanceBitCount; //DDPF_LUMINANCE
  1242. long lBumpBitCount; //DDPF_BUMPDUDV
  1243. // union for internalVal2
  1244. long lRBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1245. long lYBitMask; //DDPF_YUV
  1246. long lStencilBitMask; //DDPF_STENCILBUFFER
  1247. long lLuminanceBitMask; //DDPF_BUMPLUMINANCE or DDPF_LUMINANCE
  1248. long lBumpDiBitMask; //DDPF_BUMPDUDV
  1249. // union for internalVal3
  1250. long lGBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1251. long lUBitMask; //DPDF_YUV
  1252. long lZBitMask; //DDPF_STENCILBUFFER ?
  1253. long lBumpDvBitMask; //DDPF_BUMPDUDV
  1254. // union for internalVal4
  1255. long lBBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1256. long lVBitMask; //DDPF_YUV
  1257. long lStencilBitMask; //DDPF_STENCILBUFFER
  1258. long lBumpLuminanceBitMask; //DDPF_BUMPDUDV
  1259. // union for internalVal5
  1260. long lRGBAlphaBitMask; //DDPF_RGB and DDPF_ALPHAPIXELS
  1261. long lYUVAlphaBitMask; //DDPF_YUV & DDPF_ALPHAPIXELS
  1262. long lLuminanceAlphaBitMask; //DDPF_LUMINANCE
  1263. long lRGBZBitMask; //DDPF_ZPIXELS & DDPF_RGB
  1264. long lYUVZBitMask; //DDPF_ZPIXELS & DDPF_YUV
  1265. */
  1266. memcpy(pfOut,pf,sizeof(DDPIXELFORMAT));
  1267. pfOut->dwSize=sizeof(DDPIXELFORMAT);
  1268. return S_OK;
  1269. }
  1270. /////////////////////////////////////////////////////////////////////////////
  1271. // CopyOutDDPixelFormat real->cover
  1272. //
  1273. // note param ordering differnt that DDSURFACEDESC helpers
  1274. //
  1275. HRESULT CopyOutDDPixelFormat(DDPixelFormat *pfOut, DDPIXELFORMAT *pf)
  1276. {
  1277. if (!pf) return E_POINTER;
  1278. if (!pfOut) return E_POINTER;
  1279. pfOut->lSize=pf->dwSize;
  1280. pfOut->lFlags=pf->dwFlags;
  1281. pfOut->lFourCC=pf->dwFourCC ;
  1282. pfOut->lRGBBitCount=pf->dwRGBBitCount; //DDPF_RGB
  1283. pfOut->lRGBBitCount=pf->dwRGBBitCount; //DDPF_YUV
  1284. pfOut->lZBufferBitDepth=pf->dwZBufferBitDepth; //DDPF_ZBUFFER
  1285. pfOut->lAlphaBitDepth=pf->dwAlphaBitDepth; //DDPF_ALPHA
  1286. pfOut->lLuminanceBitCount=pf->dwLuminanceBitCount; //DDPF_LUMINANCE
  1287. pfOut->lBumpBitCount=pf->dwBumpBitCount; //DDPF_BUMPDUDV
  1288. // union for internalVal2
  1289. pfOut->lRBitMask=pf->dwRBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1290. pfOut->lYBitMask=pf->dwYBitMask; //DDPF_YUV
  1291. pfOut->lStencilBitDepth=pf->dwStencilBitDepth; //DDPF_STENCILBUFFER
  1292. pfOut->lLuminanceBitMask=pf->dwLuminanceBitMask; //DDPF_BUMPLUMINANCE or DDPF_LUMINANCE
  1293. pfOut->lBumpDuBitMask=pf->dwBumpDuBitMask; //DDPF_BUMPDUDV
  1294. // union for internalVal3
  1295. pfOut->lGBitMask=pf->dwGBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1296. pfOut->lUBitMask=pf->dwUBitMask; //DPDF_YUV
  1297. pfOut->lZBitMask=pf->dwZBitMask; //DDPF_STENCILBUFFER ?
  1298. pfOut->lBumpDvBitMask=pf->dwBumpDvBitMask; //DDPF_BUMPDUDV
  1299. // union for internalVal4
  1300. pfOut->lBBitMask=pf->dwBBitMask; //DDPF_RGB or DDPF_RGBTOYUV
  1301. pfOut->lVBitMask=pf->dwVBitMask; //DDPF_YUV
  1302. pfOut->lStencilBitMask=pf->dwStencilBitMask; //DDPF_STENCILBUFFER
  1303. pfOut->lBumpLuminanceBitMask=pf->dwBumpLuminanceBitMask; //DDPF_BUMPDUDV
  1304. // union for internalVal5
  1305. pfOut->lRGBAlphaBitMask=pf->dwRGBAlphaBitMask; //DDPF_RGB and DDPF_ALPHAPIXELS
  1306. pfOut->lYUVAlphaBitMask=pf->dwYUVAlphaBitMask; //DDPF_YUV & DDPF_ALPHAPIXELS
  1307. pfOut->lLuminanceAlphaBitMask=pf->dwLuminanceAlphaBitMask; //DDPF_LUMINANCE
  1308. pfOut->lRGBZBitMask=pf->dwRGBZBitMask; //DDPF_ZPIXELS & DDPF_RGB
  1309. pfOut->lYUVZBitMask=pf->dwYUVZBitMask; //DDPF_ZPIXELS & DDPF_YUV
  1310. return S_OK;
  1311. }
  1312. /////////////////////////////////////////////////////////////////////////////
  1313. // CopyOutDDPixelFormat cover->real
  1314. //
  1315. //
  1316. HRESULT FillRealSessionDesc(DPSESSIONDESC2 *dpSessionDesc,DPSessionDesc2 *sessionDesc){
  1317. long l=0;
  1318. HRESULT hr;
  1319. memset(dpSessionDesc,0,sizeof(DPSESSIONDESC2));
  1320. dpSessionDesc->dwSize = sizeof(DPSESSIONDESC2);
  1321. dpSessionDesc->dwFlags = sessionDesc->lFlags;
  1322. hr=BSTRtoGUID(&(dpSessionDesc->guidInstance),sessionDesc->strGuidInstance);
  1323. if FAILED(hr) return hr;
  1324. hr=BSTRtoGUID(&(dpSessionDesc->guidApplication),sessionDesc->strGuidApplication);
  1325. if FAILED(hr) return hr;
  1326. dpSessionDesc->dwMaxPlayers = sessionDesc->lMaxPlayers;
  1327. dpSessionDesc->dwCurrentPlayers = sessionDesc->lCurrentPlayers;
  1328. //using wide strings
  1329. dpSessionDesc->lpszSessionName=NULL;
  1330. if ((sessionDesc->strSessionName)&& (sessionDesc->strSessionName[0]!='\0')){
  1331. dpSessionDesc->lpszSessionName=SysAllocString(sessionDesc->strSessionName);
  1332. }
  1333. dpSessionDesc->lpszPassword=NULL;
  1334. if ((sessionDesc->strPassword)&& (sessionDesc->strPassword[0]!='\0')){
  1335. dpSessionDesc->lpszPassword=SysAllocString(sessionDesc->strPassword);
  1336. }
  1337. dpSessionDesc->dwReserved1 = 0;
  1338. dpSessionDesc->dwReserved2 = 0;
  1339. dpSessionDesc->dwUser1 = sessionDesc->lUser1;
  1340. dpSessionDesc->dwUser2 = sessionDesc->lUser2;
  1341. dpSessionDesc->dwUser3 = sessionDesc->lUser3;
  1342. dpSessionDesc->dwUser4 = sessionDesc->lUser4;
  1343. return S_OK;
  1344. }
  1345. /////////////////////////////////////////////////////////////////////////////
  1346. // FillCoverSessionDesc real->cover
  1347. //
  1348. //
  1349. void FillCoverSessionDesc(DPSessionDesc2 *sessionDesc,DPSESSIONDESC2 *dpSessionDesc)
  1350. {
  1351. sessionDesc->lFlags = dpSessionDesc->dwFlags;
  1352. sessionDesc->lMaxPlayers = dpSessionDesc->dwMaxPlayers;
  1353. sessionDesc->lCurrentPlayers = dpSessionDesc->dwCurrentPlayers;
  1354. sessionDesc->lUser1 = (long)dpSessionDesc->dwUser1;
  1355. sessionDesc->lUser2 = (long)dpSessionDesc->dwUser2;
  1356. sessionDesc->lUser3 = (long)dpSessionDesc->dwUser3;
  1357. sessionDesc->lUser4 = (long)dpSessionDesc->dwUser4;
  1358. // NOTE: if sessiondesc came in as [out] param then
  1359. // strGuidInstance -strPassword etc. would all be NULL
  1360. // if it pas passed as in out we need to free the existing contents
  1361. // before moving. Consulted with Matt curland to verify if ok.
  1362. if (sessionDesc->strGuidInstance) SysFreeString(sessionDesc->strGuidInstance);
  1363. if (sessionDesc->strGuidApplication) SysFreeString(sessionDesc->strGuidApplication);
  1364. if (sessionDesc->strSessionName) SysFreeString(sessionDesc->strSessionName);
  1365. if (sessionDesc->strPassword) SysFreeString(sessionDesc->strPassword);
  1366. sessionDesc->strGuidInstance=GUIDtoBSTR(&(dpSessionDesc->guidInstance));
  1367. sessionDesc->strGuidApplication=GUIDtoBSTR(&(dpSessionDesc->guidApplication));
  1368. sessionDesc->strSessionName = SysAllocString(dpSessionDesc->lpszSessionName);
  1369. sessionDesc->strPassword = SysAllocString(dpSessionDesc->lpszPassword);
  1370. }
  1371. /////////////////////////////////////////////////////////////////////////////
  1372. // IsAllZeros
  1373. //
  1374. BOOL IsAllZeros(void *pStruct,DWORD size){
  1375. for (DWORD i=0;i<size;i++){
  1376. if (((char*)pStruct)[i]!='\0'){
  1377. return FALSE;
  1378. }
  1379. }
  1380. return TRUE;
  1381. }
  1382. /////////////////////////////////////////////////////////////////////////////
  1383. // CopyFloats
  1384. //
  1385. extern "C" void CopyFloats(D3DVALUE *dst, D3DVALUE *src, DWORD count)
  1386. {
  1387. D3DVALUE *ptr1 = dst, *ptr2 = src;
  1388. if (!count) return;
  1389. for (; count; count--) *ptr1++ = *ptr2++;
  1390. return;
  1391. }
  1392. /////////////////////////////////////////////////////////////////////////////
  1393. // IsWin95
  1394. //
  1395. // no longer needed since we support w95 now
  1396. #if 0
  1397. BOOL IsWin95(void)
  1398. {
  1399. return FALSE;
  1400. //We work on win95
  1401. OSVERSIONINFO osvi;
  1402. ZeroMemory(&osvi, sizeof(osvi));
  1403. osvi.dwOSVersionInfoSize = sizeof(osvi);
  1404. if (!GetVersionEx(&osvi))
  1405. {
  1406. DPF(1,"GetVersionEx failed - assuming Win95");
  1407. return TRUE;
  1408. }
  1409. if ( VER_PLATFORM_WIN32_WINDOWS == osvi.dwPlatformId )
  1410. {
  1411. if( ( osvi.dwMajorVersion > 4UL ) ||
  1412. ( ( osvi.dwMajorVersion == 4UL ) &&
  1413. ( osvi.dwMinorVersion >= 10UL ) &&
  1414. ( LOWORD( osvi.dwBuildNumber ) >= 1373 ) ) )
  1415. {
  1416. // is Win98
  1417. DPF(2,"Detected Win98");
  1418. return FALSE;
  1419. }
  1420. else
  1421. {
  1422. // is Win95
  1423. DPF(2,"Detected Win95");
  1424. return TRUE;
  1425. }
  1426. }
  1427. else if ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId )
  1428. {
  1429. DPF(2,"Detected WinNT");
  1430. return FALSE;
  1431. }
  1432. DPF(2,"OS Detection failed");
  1433. return TRUE;
  1434. }
  1435. #endif
  1436. #define DICONDITION_USE_BOTH_AXIS 1
  1437. #define DICONDITION_USE_DIRECTION 2
  1438. /////////////////////////////////////////////////////////////////////////////
  1439. // FixUpRealEffect cover->real
  1440. //
  1441. HRESULT FixUpRealEffect(GUID g,DIEFFECT *realEffect,DIEffect *cover)
  1442. {
  1443. if (!cover) return E_INVALIDARG;
  1444. memcpy(realEffect,cover,sizeof(DIEFFECT));
  1445. realEffect->dwSize =sizeof(DIEFFECT);
  1446. realEffect->lpEnvelope =NULL;
  1447. realEffect->cbTypeSpecificParams =0;
  1448. realEffect->lpvTypeSpecificParams =NULL;
  1449. realEffect->cAxes =2;
  1450. realEffect->dwFlags=realEffect->dwFlags | DIEFF_OBJECTOFFSETS ;
  1451. realEffect->rglDirection =(long*)&(cover->x);
  1452. realEffect->rgdwAxes =(DWORD*)&(cover->axisOffsets);
  1453. if (cover->bUseEnvelope){
  1454. realEffect->lpEnvelope=(DIENVELOPE*)&(cover->envelope);
  1455. ((DIENVELOPE*)&(cover->envelope))->dwSize=sizeof(DIENVELOPE);
  1456. }
  1457. if (!cover->lFlags)
  1458. realEffect->dwFlags= DIEFF_POLAR | DIEFF_OBJECTOFFSETS ;
  1459. //constant
  1460. if (g==GUID_ConstantForce)
  1461. {
  1462. realEffect->cbTypeSpecificParams =sizeof (DICONSTANTFORCE);
  1463. realEffect->lpvTypeSpecificParams =&(cover->constantForce);
  1464. }
  1465. //periodic
  1466. else if ((g==GUID_Square)||(g==GUID_Triangle)||(g==GUID_SawtoothUp)||(g==GUID_SawtoothDown)||(g==GUID_Sine))
  1467. {
  1468. realEffect->cbTypeSpecificParams =sizeof (DIPERIODIC);
  1469. realEffect->lpvTypeSpecificParams =&(cover->periodicForce);
  1470. }
  1471. else if ((g==GUID_Spring)|| (g==GUID_Damper)|| (g==GUID_Inertia)|| (g==GUID_Friction)){
  1472. if (cover->conditionFlags==DICONDITION_USE_BOTH_AXIS){
  1473. realEffect->cbTypeSpecificParams =sizeof(DICONDITION)*2;
  1474. realEffect->lpvTypeSpecificParams =&(cover->conditionX);
  1475. }
  1476. else{
  1477. realEffect->cbTypeSpecificParams =sizeof(DICONDITION);
  1478. realEffect->lpvTypeSpecificParams =&(cover->conditionX);
  1479. }
  1480. }
  1481. else if (g==GUID_RampForce){
  1482. realEffect->cbTypeSpecificParams =sizeof(DIRAMPFORCE);
  1483. realEffect->lpvTypeSpecificParams =&(cover->rampForce);
  1484. }
  1485. cover->axisOffsets.x=DIJOFS_X;
  1486. cover->axisOffsets.y=DIJOFS_Y;
  1487. realEffect->rgdwAxes=(DWORD*)&(cover->axisOffsets);
  1488. return S_OK;
  1489. }
  1490. /////////////////////////////////////////////////////////////////////////////
  1491. // FixUpCoverEffect real->cover
  1492. //
  1493. HRESULT FixUpCoverEffect(GUID g, DIEffect *cover,DIEFFECT *realEffect)
  1494. {
  1495. ZeroMemory(cover,sizeof(DIEffect));
  1496. memcpy(cover,realEffect,sizeof(DIEFFECT));
  1497. if (realEffect->lpEnvelope){
  1498. memcpy(&cover->envelope,realEffect->lpEnvelope ,sizeof(DIENVELOPE));
  1499. cover->bUseEnvelope=VARIANT_TRUE;
  1500. }
  1501. if (realEffect->rglDirection){
  1502. cover->x=realEffect->rglDirection[0];
  1503. cover->y=realEffect->rglDirection[1];
  1504. }
  1505. if (realEffect->lpvTypeSpecificParams){
  1506. if (g==GUID_ConstantForce)
  1507. {
  1508. memcpy(&(cover->constantForce),realEffect->lpvTypeSpecificParams,sizeof(DICONSTANTFORCE));
  1509. }
  1510. //periodic
  1511. else if ((g==GUID_Square)||(g==GUID_Triangle)||(g==GUID_SawtoothUp)||(g==GUID_SawtoothDown)||(g==GUID_Sine))
  1512. {
  1513. memcpy(&(cover->periodicForce),realEffect->lpvTypeSpecificParams,sizeof(DIPERIODIC));
  1514. }
  1515. else if ((g==GUID_Spring)|| (g==GUID_Damper)|| (g==GUID_Inertia)|| (g==GUID_Friction)){
  1516. if (realEffect->cbTypeSpecificParams ==sizeof(DICONDITION)*2){
  1517. memcpy(&(cover->conditionY),realEffect->lpvTypeSpecificParams,sizeof(DICONDITION)*2);
  1518. cover->conditionFlags=DICONDITION_USE_BOTH_AXIS;
  1519. }
  1520. else{
  1521. memcpy(&(cover->conditionX),realEffect->lpvTypeSpecificParams,sizeof(DICONDITION));
  1522. cover->conditionFlags=DICONDITION_USE_DIRECTION;
  1523. }
  1524. }
  1525. else if (g==GUID_RampForce){
  1526. memcpy(&(cover->rampForce),realEffect->lpvTypeSpecificParams,sizeof(DIRAMPFORCE));
  1527. }
  1528. }
  1529. return S_OK;
  1530. }
  1531. /////////////////////////////////////////////////////////////////////////////
  1532. /////////////////////////////////////////////////////////////////////////////
  1533. /////////////////////////////////////////////////////////////////////////////
  1534. //
  1535. // CALLBACK FUNCTIONS
  1536. //
  1537. /////////////////////////////////////////////////////////////////////////////
  1538. /////////////////////////////////////////////////////////////////////////////
  1539. /////////////////////////////////////////////////////////////////////////////
  1540. /////////////////////////////////////////////////////////////////////////////
  1541. // myLoadTextureCallback - rm texture callback
  1542. // only userd by pmesh...
  1543. //
  1544. extern "C" HRESULT __cdecl myLoadTextureCallback(char *tex_name, void *lpArg,
  1545. LPDIRECT3DRMTEXTURE * lpD3DRMTex)
  1546. {
  1547. // user arg will contain our own struct
  1548. struct TextureCallback3 *tcb = (struct TextureCallback3 *)lpArg;
  1549. I_dxj_Direct3dRMTexture3 *iunk = NULL;
  1550. LPDIRECT3DRMTEXTURE lpTex= NULL;
  1551. int i=0;
  1552. // convert to Unicode
  1553. USES_CONVERSION;;
  1554. BSTR tex=T2BSTR(tex_name);
  1555. // user arg is an object -- hang on to it during our callback as a precaution
  1556. if (tcb->pUser) tcb->pUser->AddRef();
  1557. // call the VB callback..
  1558. tcb->c->callbackRMLoadTexture(tex,tcb->pUser , &iunk);
  1559. // give up the extra reference
  1560. if (tcb->pUser) tcb->pUser->Release();
  1561. // free the string allocated by T2BSTR
  1562. SysFreeString(tex);
  1563. // given the user returned something in iunk..
  1564. if ( iunk != NULL )
  1565. {
  1566. // get the real object iunk covers
  1567. // note DO_GETOBJECT_NOTNULL does not addref and assumes
  1568. // the cover object allready has a reference.
  1569. DO_GETOBJECT_NOTNULL(LPDIRECT3DRMTEXTURE3,lp,iunk)
  1570. lp->QueryInterface(IID_IDirect3DRMTexture,(void**)&lpTex);
  1571. // give it up to rm
  1572. *lpD3DRMTex = lpTex;
  1573. // we addref the real rm texture (as we are in a callback and
  1574. // need to return an object to rm that it will later release)
  1575. (*lpD3DRMTex)->AddRef();
  1576. // release our reference to the cover object vb gave us
  1577. iunk->Release();
  1578. }
  1579. else
  1580. {
  1581. //otherwise return null to RM
  1582. *lpD3DRMTex = NULL;
  1583. }
  1584. return S_OK;
  1585. }
  1586. /////////////////////////////////////////////////////////////////////////////
  1587. // myLoadTextureCallback3 - rm texture callback
  1588. extern "C" HRESULT __cdecl myLoadTextureCallback3(char *tex_name, void *lpArg,
  1589. LPDIRECT3DRMTEXTURE3 * lpD3DRMTex)
  1590. {
  1591. // user arg will contain our own struct
  1592. struct TextureCallback3 *tcb = (struct TextureCallback3 *)lpArg;
  1593. I_dxj_Direct3dRMTexture3 *iunk = NULL;
  1594. int i=0;
  1595. // convert to Unicode
  1596. USES_CONVERSION;;
  1597. BSTR tex=T2BSTR(tex_name);
  1598. // user arg is an object -- hang on to it during our callback as a precaution
  1599. if (tcb->pUser) tcb->pUser->AddRef();
  1600. // call the VB callback..
  1601. tcb->c->callbackRMLoadTexture(tex,tcb->pUser , &iunk);
  1602. // give up the extra reference
  1603. if (tcb->pUser) tcb->pUser->Release();
  1604. // free the string allocated by T2BSTR
  1605. SysFreeString(tex);
  1606. // given the user returned something in iunk..
  1607. if ( iunk != NULL )
  1608. {
  1609. // get the real object iunk covers
  1610. // note DO_GETOBJECT_NOTNULL does not addref and assumes
  1611. // the cover object allready has a reference.
  1612. DO_GETOBJECT_NOTNULL(LPDIRECT3DRMTEXTURE3,lp,iunk)
  1613. // give it up to rm
  1614. *lpD3DRMTex = lp;
  1615. // we addref the real rm texture (as we are in a callback and
  1616. // need to return an object to rm that it will later release)
  1617. (*lpD3DRMTex)->AddRef();
  1618. // release our reference to the cover object vb gave us
  1619. iunk->Release();
  1620. }
  1621. else
  1622. {
  1623. //otherwise return null to RM
  1624. *lpD3DRMTex = NULL;
  1625. }
  1626. return S_OK;
  1627. }
  1628. /////////////////////////////////////////////////////////////////////////////
  1629. // myFrameMoveCallback - rm frame move callback
  1630. //
  1631. // we use a helper so we can call into INTERNAL_CREATE ..
  1632. //
  1633. HRESULT myFrameMoveCallbackHelper(LPDIRECT3DRMFRAME lpf1, void *lpArg, D3DVALUE delta)
  1634. {
  1635. // get our structure from the user args..
  1636. FrameMoveCallback3 *fmcb = (FrameMoveCallback3 *)lpArg;
  1637. LPDIRECT3DRMFRAME3 lpf=NULL;
  1638. I_dxj_Direct3dRMFrame3 *frame3=NULL;
  1639. HRESULT hr;
  1640. // if RM gave is a frame (which it always will) then get the
  1641. // Frame3 interface as the VB api only has 1 frame type
  1642. if (lpf1){
  1643. hr=lpf1->QueryInterface(IID_IDirect3DRMFrame3,(void**)&lpf);
  1644. if FAILED(hr) return hr;
  1645. }
  1646. // Try and find the object in our link list of cover objects
  1647. // if its not there then create one.
  1648. //
  1649. // note: will eat the reference to lpf so dont release
  1650. // bug gives us a frame3 with incrermented ref count
  1651. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMFrame3,lpf,&frame3);
  1652. // if Out of memory try and exit gracefully
  1653. if (!frame3) return E_FAIL;
  1654. // make sure we have a reference to any user arg object
  1655. if (fmcb->pUser) fmcb->pUser->AddRef();
  1656. // make sure our vb callback doesnt go away
  1657. fmcb->c->AddRef ();
  1658. // call into VB
  1659. fmcb->c->callbackRMFrameMove(frame3, fmcb->pUser, delta);
  1660. // clean up our reference to the vb callback
  1661. fmcb->c->Release();
  1662. // clean up our reference to the user arg
  1663. if (fmcb->pUser) fmcb->pUser->Release();
  1664. // clean up of our reference to frame3
  1665. frame3->Release();
  1666. // clean up our reference created when we QI for Frame3
  1667. lpf->Release();
  1668. // clean up the variable passed to us..
  1669. // lpf1->Release();
  1670. return S_OK;
  1671. }
  1672. /////////////////////////////////////////////////////////////////////////////
  1673. // myFrameMoveCallback - rm frame move callback
  1674. //
  1675. extern "C" void __cdecl myFrameMoveCallback( LPDIRECT3DRMFRAME lpf1, void *lpArg, D3DVALUE delta)
  1676. {
  1677. DPF(4,"Entered myFrameMoveCallback\r\n");
  1678. myFrameMoveCallbackHelper(lpf1,lpArg,delta);
  1679. DPF(4,"Exiting myFrameMoveCallback\r\n");
  1680. }
  1681. /////////////////////////////////////////////////////////////////////////////
  1682. // myAddDestroyCallback
  1683. //
  1684. extern "C" void __cdecl myAddDestroyCallback(LPDIRECT3DRMOBJECT obj, void *lpArg)
  1685. {
  1686. DPF(4,"Entered myAddDestroyCallback\r\n");
  1687. // dont play with obj.... this can get you in a recursive
  1688. // situation obj is at refcount zero but calling addref and release
  1689. // on it will get you re-entered into this callback..
  1690. // I guess in rm folks were expected to not do that but could
  1691. // get the name..
  1692. // we will just pass pack any user arg
  1693. // Get our struct from the user args
  1694. d3drmCallback *destroyCb = (d3drmCallback*)lpArg;
  1695. // make sure we keep are reference to the vb callback
  1696. destroyCb->c->AddRef ();
  1697. DPF(4,"myAddDestroyCallback: completed Addref VBCallback\r\n");
  1698. // make sure we have a reference to any user arg object
  1699. if (destroyCb->pUser) destroyCb->pUser->AddRef();
  1700. DPF(4,"myAddDestroyCallback: completed Addref userargs\r\n");
  1701. // call into VB..
  1702. // CONSIDER what happens when VB is being shut down.
  1703. // if we get a reference to the object does that mean that
  1704. // we can still execute the code
  1705. destroyCb->c->callbackRMDestroyObject(destroyCb->pUser);
  1706. DPF(4,"myAddDestroyCallback: call into VB\r\n");
  1707. // release reference to user object
  1708. if (destroyCb->pUser) destroyCb->pUser->AddRef();
  1709. DPF(4,"myAddDestroyCallback: completed release userargs\r\n");
  1710. // release our reference to vb callback
  1711. destroyCb->c->Release();
  1712. DPF(4,"myAddDestroyCallback: completed release VBCallback\r\n");
  1713. DPF(4,"Leaving myAddDestroyCallback\r\n");
  1714. }
  1715. /////////////////////////////////////////////////////////////////////////////
  1716. // myAddUpdateCallback3
  1717. //
  1718. // NOTE: we can only pass the first update rect to VB
  1719. //
  1720. // note we use a cover function so that we can make calls to INTERNAL_CREATE
  1721. //
  1722. #define MYVARIANTINIT(inArg,puser) \
  1723. VariantInit(puser); \
  1724. user.vt=VT_UNKNOWN; \
  1725. user.punkVal = inArg; \
  1726. user.punkVal->AddRef();
  1727. ///////////////////////////////////////////////////////////////////////////
  1728. // myAddUpdateCallback3Helper - called by Load callback
  1729. //
  1730. // seperated out only because have multiple load callbacks
  1731. //
  1732. HRESULT myAddUpdateCallback3Helper ( LPDIRECT3DRMDEVICE3 ref,void *lpArg, int x, LPD3DRECT update)
  1733. {
  1734. // Get our struct from the user args
  1735. DeviceUpdateCallback3 *updateCb = (DeviceUpdateCallback3*)lpArg;
  1736. I_dxj_Direct3dRMDevice3 *device3 = NULL;
  1737. VARIANT user;
  1738. // Try and find the object in our link list of cover objects
  1739. // if its not there then create one.
  1740. //
  1741. // note: will eat the reference to lpf so dont release
  1742. // bug gives us a frame3 with incrermented ref count
  1743. INTERNAL_CREATE_NOADDREF(_dxj_Direct3dRMDevice3,ref,&device3);
  1744. // for reason unbeknown to me we user a variant here instead
  1745. // of an object in our callback
  1746. MYVARIANTINIT(updateCb->pUser,&user);
  1747. // keep a reference to the callback
  1748. updateCb->c->AddRef();
  1749. // call the callback
  1750. updateCb->c->callbackRMUpdate( device3, NULL, x, (D3dRect*)update);
  1751. // releae our reference to the callback
  1752. updateCb->c->Release();
  1753. // clear any refernce to user args
  1754. VariantClear(&user);
  1755. device3->Release();
  1756. return S_OK;
  1757. }
  1758. ///////////////////////////////////////////////////////////////////////////
  1759. // myLoadCoverFunc - called by Load callback
  1760. //
  1761. // seperated out only because have multiple load callbacks
  1762. //
  1763. extern "C" void __cdecl myAddUpdateCallback3 ( LPDIRECT3DRMDEVICE3 ref,void *lpArg, int x, LPD3DRECT update)
  1764. {
  1765. DPF(4,"Entered myAddUpdateCallback\r\n");
  1766. myAddUpdateCallback3Helper(ref,lpArg,x,update);
  1767. DPF(4,"Exiting myAddUpdateCallback\r\n");
  1768. }
  1769. ///////////////////////////////////////////////////////////////////////////
  1770. // myLoadCoverFunc - called by Load callback
  1771. //
  1772. // seperated out only because have multiple load callbacks
  1773. //
  1774. HRESULT myLoadCoverFunc(LPDIRECT3DRMOBJECT lpo, REFIID ObjGuid, LPVOID lpArg){
  1775. I_dxj_Direct3dRMObject *pObj=NULL;
  1776. HRESULT hr;
  1777. // Get our callback struct from the user args
  1778. LoadCallback *loadcb = (LoadCallback*)lpArg;
  1779. hr =CreateCoverObject(lpo,&pObj);
  1780. // If no coverthing exit
  1781. if ((pObj==NULL) ||(hr!=S_OK)) {
  1782. DPF(4,"Load callback - unrecognized type");
  1783. return E_FAIL;
  1784. }
  1785. // get a string represenation of whats passed in
  1786. BSTR guid=GUIDtoBSTR((LPGUID)&ObjGuid);
  1787. // addref the user arg
  1788. if (loadcb->pUser) loadcb->pUser->AddRef();
  1789. //call into VB
  1790. hr=((I_dxj_Direct3dRMLoadCallback*)(loadcb->c))->callbackRMLoad(&pObj,guid,loadcb->pUser);
  1791. //release the user arg
  1792. if (loadcb->pUser) loadcb->pUser->Release();
  1793. //free the guid string
  1794. SysFreeString(guid);
  1795. //then release pObj
  1796. pObj->Release();
  1797. return S_OK;
  1798. }
  1799. /////////////////////////////////////////////////////////////////////////////
  1800. // myd3drmLoadCallback
  1801. //
  1802. extern "C" void __cdecl myd3drmLoadCallback(LPDIRECT3DRMOBJECT lpo, REFIID ObjGuid, LPVOID lpArg)
  1803. {
  1804. DPF(4,"Entered d3drmLoadCallback \r\n");
  1805. myLoadCoverFunc( lpo, ObjGuid, lpArg);
  1806. DPF(4,"Exited d3drmLoadCallback \r\n");
  1807. return;
  1808. }
  1809. /////////////////////////////////////////////////////////////////////////////
  1810. // myCoverEnumObjects
  1811. //
  1812. // NOTE the RM bug this deals with..
  1813. //
  1814. HRESULT myCoverEnumObjects( LPDIRECT3DRMOBJECT lpo,void *lpArg){
  1815. EnumerateObjectsCallback *cb = (EnumerateObjectsCallback*)lpArg;
  1816. I_dxj_Direct3dRMObject *pObj=NULL;
  1817. HRESULT hr;
  1818. hr=CreateCoverObject(lpo,&pObj);
  1819. //RM has a bug in it that gives an extra addreff to lpo
  1820. //get rid of it
  1821. if (lpo) lpo->Release();
  1822. //Make sure things went ok
  1823. if FAILED(hr) return hr;
  1824. if (!pObj ) return E_FAIL;
  1825. //addref user args
  1826. if (cb->pUser) cb->pUser->AddRef();
  1827. //call into VB
  1828. cb->c->callbackRMEnumerateObjects(pObj, cb->pUser);
  1829. //release user args
  1830. if (cb->pUser) cb->pUser->Release();
  1831. //release pObj
  1832. pObj->Release();
  1833. return S_OK;
  1834. }
  1835. /////////////////////////////////////////////////////////////////////////////
  1836. // myEnumerateObjectsCallback
  1837. //
  1838. extern "C" void __cdecl myEnumerateObjectsCallback( LPDIRECT3DRMOBJECT lpo,void *lpArg)
  1839. {
  1840. DPF(4,"Entered myEnumerateObjectsCallback\r\n");
  1841. myCoverEnumObjects(lpo,lpArg);
  1842. DPF(4,"Exited myEnumerateObjectsCallback\r\n");
  1843. return;
  1844. }
  1845. /////////////////////////////////////////////////////////////////////////////
  1846. // UndoCallbackLink
  1847. //
  1848. extern "C" void UndoCallbackLink(GeneralCallback *entry, GeneralCallback **head)
  1849. {
  1850. if (entry->next)
  1851. entry->next->prev = entry->prev; // pick members below us
  1852. else
  1853. *head = entry->prev; // possibly NULL
  1854. if (entry->prev)
  1855. entry->prev->next = entry->next; // link to members above us
  1856. if (entry->pUser) entry->pUser->Release();
  1857. delete entry;
  1858. }
  1859. /////////////////////////////////////////////////////////////////////////////
  1860. // AddCallbackLink
  1861. //
  1862. // Add another entry in the object link list
  1863. extern "C" void* AddCallbackLink(void **ptr2,I_dxj_Direct3dRMCallback *enumC,void *args)
  1864. {
  1865. d3drmCallback *enumcb = new d3drmCallback; // new link entry
  1866. if ( !enumcb ) {
  1867. DPF(4,"Creation using new failed\r\n");
  1868. return (d3drmCallback*)NULL;
  1869. }
  1870. enumcb->c = enumC; // user callback
  1871. enumcb->pUser = (struct IUnknown *)args; // callback args
  1872. enumcb->pParent = NULL;
  1873. enumcb->prev = (d3drmCallback*)NULL;
  1874. enumcb->m_stopflag = FALSE;
  1875. enumcb->m_obj = NULL;
  1876. //CONSIDER: locking the linked list here with a semaphore
  1877. // to be more multithread friendly..
  1878. // shame shame- possible gpf otherwise
  1879. enumcb->next = (d3drmCallback*)(*ptr2); // link to other calls
  1880. *ptr2 = enumcb; // we are at the top
  1881. if (enumcb->pUser) enumcb->pUser->AddRef();
  1882. if (enumcb->prev != NULL) // nested callbacks
  1883. {
  1884. enumcb->prev->next = enumcb; // back link
  1885. DPF(4,"Callback nesting encountered\r\n");
  1886. }
  1887. // Need unlock here.
  1888. return enumcb;
  1889. }
  1890. /////////////////////////////////////////////////////////////////////////////
  1891. extern "C" HRESULT _AddDestroyCallback(IDirect3DRMObject *iface, I_dxj_Direct3dRMCallback *oC,
  1892. IUnknown *args)
  1893. {
  1894. return E_NOTIMPL;
  1895. #if 0
  1896. DestroyCallback *dcb;
  1897. // killed by companion DeleteDestroyCallback
  1898. dcb = (DestroyCallback*)AddCallbackLink((void**)&DestroyCallbacks,
  1899. (I_dxj_Direct3dRMCallback*)oC, (void*) args);
  1900. if (!(dcb))
  1901. {
  1902. DPF(4,"AddDestroyCallback failed!\r\n");
  1903. return E_FAIL;
  1904. }
  1905. if (iface->AddDestroyCallback(
  1906. myAddDestroyCallback, dcb))
  1907. return E_FAIL;
  1908. oC->AddRef(); // callback is persistent so make it so in Java/VB Land
  1909. //oC->AddRef(); //? 2 ...
  1910. return S_OK;
  1911. #endif
  1912. }
  1913. /////////////////////////////////////////////////////////////////////////////
  1914. extern "C" HRESULT _DeleteDestroyCallback(IDirect3DRMObject *iface, I_dxj_Direct3dRMCallback *oC,
  1915. IUnknown *args)
  1916. {
  1917. return E_NOTIMPL;
  1918. #if 0
  1919. DestroyCallback *dcb = DestroyCallbacks;
  1920. // look for our own specific entry
  1921. for ( ; dcb; dcb = dcb->next ) {
  1922. if( (dcb->c == oC) && (dcb->pUser == args) ) {
  1923. //note: assume the callback is not called: only removed from a list.
  1924. iface->DeleteDestroyCallback(
  1925. myAddDestroyCallback, dcb);
  1926. // Remove ourselves in a thread-safe manner.
  1927. UndoCallbackLink((GeneralCallback*)dcb,
  1928. (GeneralCallback**)&DestroyCallbacks);
  1929. iface->Release();
  1930. return S_OK;
  1931. }
  1932. }
  1933. iface->Release(); // none found so a release is not needed
  1934. return E_FAIL;
  1935. #endif
  1936. }