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.

574 lines
16 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dplclassfac.cpp
  6. * Content: DirectPlay Lobby COM Class Factory
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 02/21/00 mjn Created
  12. * 03/22/2000 jtk Changed interface names
  13. * 04/18/2000 rmt Updated object create to set param validation flag
  14. * 05/09/2000 rmt Bug #34306 QueryInterface on lobbyclient for lobbiedapp works (and shouldn't).
  15. * 06/07/2000 rmt Bug #34383 Must provide CLSID for each IID to fix issues with Whistler
  16. * 06/20/2000 rmt Bugfix - QueryInterface had bug which was limiting interface list to 2 elements
  17. * 07/08/2000 rmt Added guard bytes
  18. * 08/05/2000 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
  19. * 08/08/2000 rmt Removed assert which wasn't needed
  20. * 01/11/2001 rmt MANBUG #48487 - DPLAY: Crashes if CoCreate() isn't called.
  21. * 03/14/2001 rmt WINBUG #342420 - Restore COM emulation layer to operation.
  22. *@@END_MSINTERNAL
  23. *
  24. ***************************************************************************/
  25. #include "dnlobbyi.h"
  26. //**********************************************************************
  27. // Constant definitions
  28. //**********************************************************************
  29. //**********************************************************************
  30. // Macro definitions
  31. //**********************************************************************
  32. //**********************************************************************
  33. // Structure definitions
  34. //**********************************************************************
  35. typedef STDMETHODIMP IUnknownQueryInterface( IUnknown *pInterface, REFIID riid, LPVOID *ppvObj );
  36. typedef STDMETHODIMP_(ULONG) IUnknownAddRef( IUnknown *pInterface );
  37. typedef STDMETHODIMP_(ULONG) IUnknownRelease( IUnknown *pInterface );
  38. //
  39. // VTable for IUnknown interface
  40. //
  41. IUnknownVtbl DN_LobbyUnknownVtbl =
  42. {
  43. (IUnknownQueryInterface*) DPL_QueryInterface,
  44. (IUnknownAddRef*) DPL_AddRef,
  45. (IUnknownRelease*) DPL_Release
  46. };
  47. //
  48. // VTable for Class Factory
  49. //
  50. IClassFactoryVtbl DPLCF_Vtbl =
  51. {
  52. DPCF_QueryInterface, // dnet\common\classfactory.cpp will provide these
  53. DPCF_AddRef,
  54. DPCF_Release,
  55. DPLCF_CreateInstance,
  56. DPCF_LockServer
  57. };
  58. //**********************************************************************
  59. // Variable definitions
  60. //**********************************************************************
  61. #ifndef DPNBUILD_LIBINTERFACE
  62. //
  63. // Globals
  64. //
  65. extern LONG g_lLobbyObjectCount;
  66. #endif // ! DPNBUILD_LIBINTERFACE
  67. //**********************************************************************
  68. // Function prototypes
  69. //**********************************************************************
  70. //**********************************************************************
  71. // Function definitions
  72. //**********************************************************************
  73. #undef DPF_MODNAME
  74. #define DPF_MODNAME "DPLCF_CreateObject"
  75. HRESULT DPLCF_CreateObject(IClassFactory *pInterface, LPVOID *lplpv, REFIID riid)
  76. {
  77. HRESULT hResultCode = S_OK;
  78. PDIRECTPLAYLOBBYOBJECT pdpLobbyObject = NULL;
  79. const _IDirectPlayClassFactory* lpcfObj = (_PIDirectPlayClassFactory)pInterface;
  80. DPFX(DPFPREP, 3,"Parameters: lplpv [%p]",lplpv);
  81. /*
  82. *
  83. * TIME BOMB
  84. *
  85. */
  86. #ifndef DX_FINAL_RELEASE
  87. {
  88. #pragma message("BETA EXPIRATION TIME BOMB! Remove for final build!")
  89. SYSTEMTIME st;
  90. GetSystemTime(&st);
  91. if ( st.wYear > DX_EXPIRE_YEAR || ((st.wYear == DX_EXPIRE_YEAR) && (MAKELONG(st.wDay, st.wMonth) > MAKELONG(DX_EXPIRE_DAY, DX_EXPIRE_MONTH))) )
  92. {
  93. MessageBox(0, DX_EXPIRE_TEXT,TEXT("Microsoft Direct Play"), MB_OK);
  94. // return E_FAIL;
  95. }
  96. }
  97. #endif // !DX_FINAL_RELEASE
  98. if ((pdpLobbyObject = (PDIRECTPLAYLOBBYOBJECT)DNMalloc(sizeof(DIRECTPLAYLOBBYOBJECT))) == NULL)
  99. {
  100. return(E_OUTOFMEMORY);
  101. }
  102. DPFX(DPFPREP, 5,"pdpLobbyObject [%p]",pdpLobbyObject);
  103. // Set allocatable elements to NULL to simplify free'ing later on
  104. pdpLobbyObject->dwSignature = DPLSIGNATURE_LOBBYOBJECT;
  105. pdpLobbyObject->hReceiveThread = NULL;
  106. pdpLobbyObject->dwFlags = 0;
  107. pdpLobbyObject->hConnectEvent = NULL;
  108. pdpLobbyObject->pfnMessageHandler = NULL;
  109. pdpLobbyObject->pvUserContext = NULL;
  110. pdpLobbyObject->lLaunchCount = 0;
  111. pdpLobbyObject->dpnhLaunchedConnection = NULL;
  112. pdpLobbyObject->pReceiveQueue = NULL;
  113. pdpLobbyObject->dwPID = GetCurrentProcessId();
  114. pdpLobbyObject->m_dwConnectionCount = 0;
  115. pdpLobbyObject->m_blConnections.Initialize();
  116. if (FAILED(pdpLobbyObject->m_HandleTable.Initialize()))
  117. {
  118. DPLCF_FreeObject(pdpLobbyObject);
  119. return(hResultCode);
  120. }
  121. pdpLobbyObject->dwFlags |= DPL_OBJECT_FLAG_HANDLETABLE_INITED;
  122. if (!DNInitializeCriticalSection(&pdpLobbyObject->m_cs))
  123. {
  124. DPLCF_FreeObject(pdpLobbyObject);
  125. hResultCode = DPNERR_OUTOFMEMORY;
  126. return(hResultCode);
  127. }
  128. pdpLobbyObject->dwFlags |= DPL_OBJECT_FLAG_CRITSEC_INITED;
  129. if ((pdpLobbyObject->hConnectEvent = DNCreateEvent(NULL,TRUE,FALSE,NULL)) == NULL)
  130. {
  131. DPLCF_FreeObject(pdpLobbyObject);
  132. hResultCode = DPNERR_OUTOFMEMORY;
  133. return(hResultCode);
  134. }
  135. if ((pdpLobbyObject->hLobbyLaunchConnectEvent = DNCreateEvent(NULL,TRUE,FALSE,NULL)) == NULL )
  136. {
  137. DPLCF_FreeObject(pdpLobbyObject);
  138. hResultCode = DPNERR_OUTOFMEMORY;
  139. return(hResultCode);
  140. }
  141. DPFX(DPFPREP, 5,"InitializeHandles() succeeded");
  142. if (IsEqualIID(riid,IID_IDirectPlay8LobbyClient) ||
  143. (riid == IID_IUnknown && lpcfObj->clsid == CLSID_DirectPlay8LobbyClient ) )
  144. {
  145. DPFX(DPFPREP, 5,"DirectPlay Lobby Client");
  146. pdpLobbyObject->dwFlags |= DPL_OBJECT_FLAG_LOBBYCLIENT;
  147. }
  148. else if (IsEqualIID(riid,IID_IDirectPlay8LobbiedApplication) ||
  149. (riid == IID_IUnknown && lpcfObj->clsid == CLSID_DirectPlay8LobbiedApplication ) )
  150. {
  151. DPFX(DPFPREP, 5,"DirectPlay Lobbied Application");
  152. pdpLobbyObject->dwFlags |= DPL_OBJECT_FLAG_LOBBIEDAPPLICATION;
  153. }
  154. else
  155. {
  156. DPFX(DPFPREP, 5,"Invalid DirectPlay Lobby Interface");
  157. DPLCF_FreeObject(pdpLobbyObject);
  158. return(E_NOTIMPL);
  159. }
  160. pdpLobbyObject->dwFlags |= DPL_OBJECT_FLAG_PARAMVALIDATION;
  161. *lplpv = pdpLobbyObject;
  162. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx], *lplpv = [%p]",hResultCode,*lplpv);
  163. return(hResultCode);
  164. }
  165. #undef DPF_MODNAME
  166. #define DPF_MODNAME "DPLCF_FreeObject"
  167. HRESULT DPLCF_FreeObject(LPVOID lpv)
  168. {
  169. HRESULT hResultCode = S_OK;
  170. PDIRECTPLAYLOBBYOBJECT pdpLobbyObject = NULL;
  171. if (lpv != NULL)
  172. {
  173. pdpLobbyObject = (PDIRECTPLAYLOBBYOBJECT)lpv;
  174. if (pdpLobbyObject->pReceiveQueue)
  175. {
  176. delete pdpLobbyObject->pReceiveQueue;
  177. pdpLobbyObject->pReceiveQueue = NULL;
  178. }
  179. if (pdpLobbyObject->hLobbyLaunchConnectEvent)
  180. {
  181. DNCloseHandle(pdpLobbyObject->hLobbyLaunchConnectEvent);
  182. pdpLobbyObject->hLobbyLaunchConnectEvent = 0;
  183. }
  184. if (pdpLobbyObject->hConnectEvent)
  185. {
  186. DNCloseHandle(pdpLobbyObject->hConnectEvent);
  187. pdpLobbyObject->hConnectEvent = 0;
  188. }
  189. if (pdpLobbyObject->dwFlags & DPL_OBJECT_FLAG_HANDLETABLE_INITED)
  190. {
  191. pdpLobbyObject->m_HandleTable.Deinitialize();
  192. }
  193. if (pdpLobbyObject->dwFlags & DPL_OBJECT_FLAG_CRITSEC_INITED)
  194. {
  195. DNDeleteCriticalSection(&pdpLobbyObject->m_cs);
  196. }
  197. pdpLobbyObject->dwSignature = DPLSIGNATURE_LOBBYOBJECT_FREE;
  198. pdpLobbyObject->dwFlags = 0;
  199. DPFX(DPFPREP, 5,"free pdpLobbyObject [%p]",pdpLobbyObject);
  200. DNFree(pdpLobbyObject);
  201. }
  202. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
  203. return(hResultCode);
  204. }
  205. #undef DPF_MODNAME
  206. #define DPF_MODNAME "DPLCF_CreateInstance"
  207. STDMETHODIMP DPLCF_CreateInstance(IClassFactory *pInterface,
  208. LPUNKNOWN lpUnkOuter,
  209. REFIID riid,
  210. LPVOID *ppv)
  211. {
  212. HRESULT hResultCode = S_OK;
  213. LPINTERFACE_LIST lpIntList = NULL;
  214. LPOBJECT_DATA lpObjectData = NULL;
  215. DPFX(DPFPREP, 3,"Parameters: pInterface [0x%p], lpUnkOuter [0x%p], riid [0x%p], ppv [0x%p]",pInterface,lpUnkOuter,riid,ppv);
  216. if (lpUnkOuter != NULL)
  217. {
  218. return(CLASS_E_NOAGGREGATION);
  219. }
  220. lpObjectData = (LPOBJECT_DATA)g_fpObjectDatas.Get();
  221. if (lpObjectData == NULL)
  222. {
  223. DPFERR("Failed to get new object data from pool");
  224. return(E_OUTOFMEMORY);
  225. }
  226. DPFX(DPFPREP, 5,"lpObjectData [%p]",lpObjectData);
  227. // Object creation and initialization
  228. if ((hResultCode = DPLCF_CreateObject(pInterface,&lpObjectData->pvData,riid)) != S_OK)
  229. {
  230. g_fpObjectDatas.Release(lpObjectData);
  231. return(hResultCode);
  232. }
  233. DPFX(DPFPREP, 5,"Created and initialized object");
  234. // Get requested interface
  235. if ((hResultCode = DPL_CreateInterface(lpObjectData,riid,&lpIntList)) != S_OK)
  236. {
  237. DPLCF_FreeObject(lpObjectData->pvData);
  238. g_fpObjectDatas.Release(lpObjectData);
  239. return(hResultCode);
  240. }
  241. DPFX(DPFPREP, 5,"Found interface");
  242. lpObjectData->pIntList = lpIntList;
  243. lpObjectData->lRefCount = 1;
  244. DNInterlockedIncrement(&lpIntList->lRefCount );
  245. DNInterlockedIncrement(&g_lLobbyObjectCount);
  246. *ppv = lpIntList;
  247. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx], *ppv = [%p]",hResultCode,*ppv);
  248. return(S_OK);
  249. }
  250. #undef DPF_MODNAME
  251. #define DPF_MODNAME "DPL_CreateInterface"
  252. static HRESULT DPL_CreateInterface(LPOBJECT_DATA lpObject,
  253. REFIID riid,
  254. LPINTERFACE_LIST *const ppv)
  255. {
  256. LPINTERFACE_LIST lpIntNew;
  257. LPVOID lpVtbl;
  258. DPFX(DPFPREP, 3,"Parameters: lpObject [%p], riid [%p], ppv [%p]",lpObject,riid,ppv);
  259. if (IsEqualIID(riid,IID_IUnknown))
  260. {
  261. DPFX(DPFPREP, 5,"riid = IID_IUnknown");
  262. lpVtbl = &DN_LobbyUnknownVtbl;
  263. }
  264. else if (IsEqualIID(riid,IID_IDirectPlay8LobbyClient))
  265. {
  266. DPFX(DPFPREP, 5,"riid = IID_IDirectPlay8LobbyClient");
  267. lpVtbl = &DPL_Lobby8ClientVtbl;
  268. }
  269. else if (IsEqualIID(riid,IID_IDirectPlay8LobbiedApplication))
  270. {
  271. DPFX(DPFPREP, 5,"riid = IID_IDirectPlay8LobbiedApplication");
  272. lpVtbl = &DPL_8LobbiedApplicationVtbl;
  273. }
  274. else
  275. {
  276. DPFX(DPFPREP, 5,"riid not found !");
  277. return(E_NOINTERFACE);
  278. }
  279. lpIntNew = (LPINTERFACE_LIST)g_fpInterfaceLists.Get();
  280. if (lpIntNew == NULL)
  281. {
  282. DPFERR("Failed to get new interface list from pool");
  283. return(E_OUTOFMEMORY);
  284. }
  285. lpIntNew->lpVtbl = lpVtbl;
  286. lpIntNew->lRefCount = 0;
  287. lpIntNew->pIntNext = NULL;
  288. DBG_CASSERT( sizeof( lpIntNew->iid ) == sizeof( riid ) );
  289. memcpy( &(lpIntNew->iid), &riid, sizeof( lpIntNew->iid ) );
  290. lpIntNew->pObject = lpObject;
  291. *ppv = lpIntNew;
  292. DPFX(DPFPREP, 3,"Returning: hResultCode = [S_OK], *ppv = [%p]",*ppv);
  293. return(S_OK);
  294. }
  295. #undef DPF_MODNAME
  296. #define DPF_MODNAME "DPL_FindInterface"
  297. LPINTERFACE_LIST DPL_FindInterface(LPVOID lpv, REFIID riid)
  298. {
  299. LPINTERFACE_LIST lpIntList;
  300. DPFX(DPFPREP, 3,"Parameters: lpv [%p], riid [%p]",lpv,riid);
  301. lpIntList = ((LPINTERFACE_LIST)lpv)->pObject->pIntList; // Find first interface
  302. while (lpIntList != NULL)
  303. {
  304. if (IsEqualIID(riid,lpIntList->iid))
  305. break;
  306. lpIntList = lpIntList->pIntNext;
  307. }
  308. DPFX(DPFPREP, 3,"Returning: lpIntList = [%p]",lpIntList);
  309. return(lpIntList);
  310. }
  311. #undef DPF_MODNAME
  312. #define DPF_MODNAME "DPL_QueryInterface"
  313. STDMETHODIMP DPL_QueryInterface(LPVOID lpv,REFIID riid,LPVOID *ppv)
  314. {
  315. LPINTERFACE_LIST lpIntList;
  316. LPINTERFACE_LIST lpIntNew;
  317. HRESULT hResultCode;
  318. PDIRECTPLAYLOBBYOBJECT pdpLobbyObject;
  319. DPFX(DPFPREP, 3,"Parameters: lpv [0x%p], riid [0x%p], ppv [0x%p]",lpv,riid,ppv);
  320. #ifndef DPNBUILD_NOPARAMVAL
  321. TRY
  322. {
  323. #endif // !DPNBUILD_NOPARAMVAL
  324. pdpLobbyObject = static_cast<DIRECTPLAYLOBBYOBJECT*>(GET_OBJECT_FROM_INTERFACE(lpv));
  325. lpIntList = (LPINTERFACE_LIST)lpv;
  326. #ifndef DPNBUILD_NOPARAMVAL
  327. // TODO: MASONB: Why no paramval flag wrapping this?
  328. if( FAILED( hResultCode = DPL_ValidateQueryInterface( lpv,riid,ppv ) ) )
  329. {
  330. DPFX(DPFPREP, 0, "Error validating QueryInterface params hr=[0x%lx]", hResultCode );
  331. DPF_RETURN(hResultCode);
  332. }
  333. if( pdpLobbyObject->dwFlags & DPL_OBJECT_FLAG_LOBBIEDAPPLICATION &&
  334. riid == IID_IDirectPlay8LobbyClient )
  335. {
  336. DPFERR( "Cannot request lobbyclient interface from lobbyapp object" );
  337. return DPNERR_NOINTERFACE;
  338. }
  339. if( pdpLobbyObject->dwFlags & DPL_OBJECT_FLAG_LOBBYCLIENT &&
  340. riid == IID_IDirectPlay8LobbiedApplication )
  341. {
  342. DPFERR( "Cannot request lobbied application interface from lobbyclient object" );
  343. return DPNERR_NOINTERFACE;
  344. }
  345. }
  346. EXCEPT(EXCEPTION_EXECUTE_HANDLER)
  347. {
  348. DPFERR("Invalid object" );
  349. DPF_RETURN(DPNERR_INVALIDOBJECT);
  350. }
  351. #endif // !DPNBUILD_NOPARAMVAL
  352. if ((lpIntList = DPL_FindInterface(lpv,riid)) == NULL)
  353. { // Interface must be created
  354. lpIntList = ((LPINTERFACE_LIST)lpv)->pObject->pIntList;
  355. if ((hResultCode = DPL_CreateInterface(lpIntList->pObject,riid,&lpIntNew)) != S_OK)
  356. {
  357. DPF_RETURN(hResultCode);
  358. }
  359. lpIntNew->pIntNext = lpIntList;
  360. ((LPINTERFACE_LIST)lpv)->pObject->pIntList = lpIntNew;
  361. lpIntList = lpIntNew;
  362. }
  363. if (lpIntList->lRefCount == 0) // New interface exposed
  364. {
  365. DNInterlockedIncrement( &lpIntList->pObject->lRefCount );
  366. }
  367. DNInterlockedIncrement( &lpIntList->lRefCount );
  368. *ppv = lpIntList;
  369. DPF_RETURN(S_OK);
  370. }
  371. #undef DPF_MODNAME
  372. #define DPF_MODNAME "DPL_AddRef"
  373. STDMETHODIMP_(ULONG) DPL_AddRef(LPVOID lpv)
  374. {
  375. LPINTERFACE_LIST lpIntList;
  376. DPFX(DPFPREP, 3,"Parameters: lpv [%p]",lpv);
  377. lpIntList = (LPINTERFACE_LIST)lpv;
  378. #ifndef DPNBUILD_NOPARAMVAL
  379. HRESULT hResultCode;
  380. PDIRECTPLAYLOBBYOBJECT pdpLobbyObject;
  381. TRY
  382. {
  383. pdpLobbyObject = static_cast<DIRECTPLAYLOBBYOBJECT*>(GET_OBJECT_FROM_INTERFACE(lpv));
  384. // TODO: MASONB: Why no paramval flag wrapping this?
  385. if( FAILED( hResultCode = DPL_ValidateAddRef( lpv ) ) )
  386. {
  387. DPFX(DPFPREP, 0, "Error validating AddRef params hr=[0x%lx]", hResultCode );
  388. DPF_RETURN(0);
  389. }
  390. }
  391. EXCEPT(EXCEPTION_EXECUTE_HANDLER)
  392. {
  393. DPFERR("Invalid object" );
  394. DPF_RETURN(0);
  395. }
  396. #endif // !DPNBUILD_NOPARAMVAL
  397. DNInterlockedIncrement( &lpIntList->lRefCount );
  398. DPF_RETURN(lpIntList->lRefCount);
  399. }
  400. #undef DPF_MODNAME
  401. #define DPF_MODNAME "DPL_Release"
  402. STDMETHODIMP_(ULONG) DPL_Release(LPVOID lpv)
  403. {
  404. LPINTERFACE_LIST lpIntList;
  405. LPINTERFACE_LIST lpIntCurrent;
  406. PDIRECTPLAYLOBBYOBJECT pdpLobbyObject;
  407. DPFX(DPFPREP, 3,"Parameters: lpv [%p]",lpv);
  408. #ifndef DPNBUILD_NOPARAMVAL
  409. TRY
  410. {
  411. #endif // !DPNBUILD_NOPARAMVAL
  412. pdpLobbyObject = static_cast<DIRECTPLAYLOBBYOBJECT*>(GET_OBJECT_FROM_INTERFACE(lpv));
  413. lpIntList = (LPINTERFACE_LIST)lpv;
  414. #ifndef DPNBUILD_NOPARAMVAL
  415. HRESULT hResultCode;
  416. if( FAILED( hResultCode = DPL_ValidateRelease( lpv ) ) )
  417. {
  418. DPFX(DPFPREP, 0, "Error validating release params hr=[0x%lx]", hResultCode );
  419. DPF_RETURN(0);
  420. }
  421. }
  422. EXCEPT(EXCEPTION_EXECUTE_HANDLER)
  423. {
  424. DPFERR("Invalid object" );
  425. DPF_RETURN(0);
  426. }
  427. #endif // !DPNBUILD_NOPARAMVAL
  428. DPFX(DPFPREP, 5,"Original : lpIntList->lRefCount = %ld",lpIntList->lRefCount);
  429. DPFX(DPFPREP, 5,"Original : lpIntList->pObject->lRefCount = %ld",lpIntList->pObject->lRefCount);
  430. if( DNInterlockedDecrement( &lpIntList->lRefCount ) == 0 )
  431. { // Decrease interface count
  432. if( DNInterlockedDecrement( &lpIntList->pObject->lRefCount ) == 0 )
  433. { // Free object and all interfaces
  434. DPFX(DPFPREP, 5,"Free object");
  435. if( pdpLobbyObject->pReceiveQueue )
  436. {
  437. DPFX(DPFPREP, 0, "*******************************************************************" );
  438. DPFX(DPFPREP, 0, "ERROR: Releasing object without calling close!" );
  439. DPFX(DPFPREP, 0, "You MUST call Close before destroying the object" );
  440. DPFX(DPFPREP, 0, "*******************************************************************" );
  441. DPL_Close( lpv, 0 );
  442. }
  443. // Free object here
  444. DPLCF_FreeObject(lpIntList->pObject->pvData);
  445. lpIntList = lpIntList->pObject->pIntList; // Get head of interface list
  446. DPFX(DPFPREP, 5,"lpIntList->pObject [%p]",lpIntList->pObject);
  447. g_fpObjectDatas.Release(lpIntList->pObject);
  448. // Free Interfaces
  449. DPFX(DPFPREP, 5,"Free interfaces");
  450. while(lpIntList != NULL)
  451. {
  452. lpIntCurrent = lpIntList;
  453. lpIntList = lpIntList->pIntNext;
  454. DPFX(DPFPREP, 5,"\tinterface [%p]",lpIntCurrent);
  455. g_fpInterfaceLists.Release(lpIntCurrent);
  456. }
  457. DNInterlockedDecrement(&g_lLobbyObjectCount);
  458. DPFX(DPFPREP, 3,"Returning: 0");
  459. return(0);
  460. }
  461. }
  462. DPFX(DPFPREP, 3,"Returning: lpIntList->lRefCount = [%lx]",lpIntList->lRefCount);
  463. DPF_RETURN(lpIntList->lRefCount);
  464. }