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.

599 lines
15 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1998-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: Unk.cpp
  6. * Content: IUnknown implementation
  7. * History:
  8. * Date By Reason
  9. * ==== == ======
  10. * 11/25/98 jtk Copied from winsock provider
  11. * 11/30/98 jtk Initial checkin into SLM
  12. * 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
  13. ***************************************************************************/
  14. #include "dnmdmi.h"
  15. #define DPN_REG_LOCAL_MODEM_SERIAL_ROOT L"\\DPNSPModemSerial"
  16. #define DPN_REG_LOCAL_MODEM_MODEM_ROOT L"\\DPNSPModemModem"
  17. #undef DPF_SUBCOMP
  18. #define DPF_SUBCOMP DN_SUBCOMP_MODEM
  19. HRESULT ModemLoadAndAllocString( UINT uiResourceID, wchar_t **lpswzString );
  20. #undef DPF_MODNAME
  21. #define DPF_MODNAME "DNModemInit"
  22. BOOL DNModemInit(HANDLE hModule)
  23. {
  24. DNASSERT( g_hModemDLLInstance == NULL );
  25. g_hModemDLLInstance = (HINSTANCE) hModule;
  26. //
  27. // attempt to initialize process-global items
  28. //
  29. if ( ModemInitProcessGlobals() == FALSE )
  30. {
  31. DPFX(DPFPREP, 0, "Failed to initialize globals!" );
  32. return FALSE;
  33. }
  34. return TRUE;
  35. }
  36. #undef DPF_MODNAME
  37. #define DPF_MODNAME "DNModemDeInit"
  38. void DNModemDeInit()
  39. {
  40. DPFX(DPFPREP, 5, "Deinitializing Serial SP");
  41. DNASSERT( g_hModemDLLInstance != NULL );
  42. g_hModemDLLInstance = NULL;
  43. ModemDeinitProcessGlobals();
  44. }
  45. #ifndef DPNBUILD_NOCOMREGISTER
  46. #undef DPF_MODNAME
  47. #define DPF_MODNAME "DNModemRegister"
  48. BOOL DNModemRegister(LPCWSTR wszDLLName)
  49. {
  50. HRESULT hr = S_OK;
  51. BOOL fReturn = TRUE;
  52. if( !CRegistry::Register( L"DirectPlay8SPModem.Modem.1", L"DirectPlay8 Modem Provider Object",
  53. wszDLLName, &CLSID_DP8SP_MODEM, L"DirectPlay8SPModem.Modem") )
  54. {
  55. DPFERR( "Could not register dp8 Modem object" );
  56. fReturn = FALSE;
  57. }
  58. if( !CRegistry::Register( L"DirectPlay8SPModem.Serial.1", L"DirectPlay8 Serial Provider Object",
  59. wszDLLName, &CLSID_DP8SP_SERIAL, L"DirectPlay8SPModem.Serial") )
  60. {
  61. DPFERR( "Could not register dp8 Serial object" );
  62. fReturn = FALSE;
  63. }
  64. CRegistry creg;
  65. WCHAR *wszFriendlyName = NULL;
  66. if( !creg.Open( HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY DPN_REG_LOCAL_MODEM_MODEM_ROOT, FALSE, TRUE ) )
  67. {
  68. DPFERR( "Cannot create Modem sub-area" );
  69. fReturn = FALSE;
  70. }
  71. else
  72. {
  73. hr = ModemLoadAndAllocString( IDS_FRIENDLYNAME_MODEM, &wszFriendlyName );
  74. if( FAILED( hr ) )
  75. {
  76. DPFX(DPFPREP, 0, "Could not load Modem name hr=0x%x", hr );
  77. fReturn = FALSE;
  78. }
  79. else
  80. {
  81. // Load from resource file
  82. creg.WriteString( DPN_REG_KEYNAME_FRIENDLY_NAME, wszFriendlyName );
  83. delete [] wszFriendlyName;
  84. creg.WriteGUID( DPN_REG_KEYNAME_GUID, CLSID_DP8SP_MODEM );
  85. }
  86. creg.Close();
  87. }
  88. if( !creg.Open( HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY DPN_REG_LOCAL_MODEM_SERIAL_ROOT, FALSE, TRUE ) )
  89. {
  90. DPFERR( "Cannot create Serial sub-aread" );
  91. fReturn = FALSE;
  92. }
  93. else
  94. {
  95. hr = ModemLoadAndAllocString( IDS_FRIENDLYNAME_SERIAL, &wszFriendlyName );
  96. if( FAILED( hr ) )
  97. {
  98. DPFX(DPFPREP, 0, "Could not load Serial name hr=0x%x", hr );
  99. fReturn = FALSE;
  100. }
  101. else
  102. {
  103. // Load from resource file
  104. creg.WriteString( DPN_REG_KEYNAME_FRIENDLY_NAME, wszFriendlyName );
  105. delete [] wszFriendlyName;
  106. creg.WriteGUID( DPN_REG_KEYNAME_GUID, CLSID_DP8SP_SERIAL );
  107. }
  108. creg.Close();
  109. }
  110. return fReturn;
  111. }
  112. #undef DPF_MODNAME
  113. #define DPF_MODNAME "DNModemUnRegister"
  114. BOOL DNModemUnRegister()
  115. {
  116. HRESULT hr = S_OK;
  117. BOOL fReturn = TRUE;
  118. if( !CRegistry::UnRegister(&CLSID_DP8SP_MODEM) )
  119. {
  120. DPFX(DPFPREP, 0, "Failed to unregister Modem object" );
  121. fReturn = FALSE;
  122. }
  123. if( !CRegistry::UnRegister(&CLSID_DP8SP_SERIAL) )
  124. {
  125. DPFX(DPFPREP, 0, "Failed to unregister Serial object" );
  126. fReturn = FALSE;
  127. }
  128. CRegistry creg;
  129. if( !creg.Open( HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY, FALSE, TRUE ) )
  130. {
  131. DPFERR( "Cannot remove app, does not exist" );
  132. }
  133. else
  134. {
  135. if( !creg.DeleteSubKey( &(DPN_REG_LOCAL_MODEM_MODEM_ROOT)[1] ) )
  136. {
  137. DPFERR( "Cannot remove Modem sub-key, could have elements" );
  138. }
  139. if( !creg.DeleteSubKey( &(DPN_REG_LOCAL_MODEM_SERIAL_ROOT)[1] ) )
  140. {
  141. DPFERR( "Cannot remove Serial sub-key, could have elements" );
  142. }
  143. }
  144. return fReturn;
  145. }
  146. #endif // ! DPNBUILD_NOCOMREGISTER
  147. #ifndef DPNBUILD_LIBINTERFACE
  148. #undef DPF_MODNAME
  149. #define DPF_MODNAME "DNModemGetRemainingObjectCount"
  150. DWORD DNModemGetRemainingObjectCount()
  151. {
  152. return g_lModemOutstandingInterfaceCount;
  153. }
  154. #endif // ! DPNBUILD_LIBINTERFACE
  155. //**********************************************************************
  156. // Constant definitions
  157. //**********************************************************************
  158. //**********************************************************************
  159. // Macro definitions
  160. //**********************************************************************
  161. #ifdef __MWERKS__
  162. #define EXP __declspec(dllexport)
  163. #else
  164. #define EXP
  165. #endif
  166. //**********************************************************************
  167. // Structure definitions
  168. //**********************************************************************
  169. //**********************************************************************
  170. // Variable definitions
  171. //**********************************************************************
  172. //**********************************************************************
  173. // Function prototypes
  174. //**********************************************************************
  175. static STDMETHODIMP DNMODEMSP_QueryInterface( IDP8ServiceProvider* lpDNSP, REFIID riid, LPVOID * ppvObj );
  176. #define NOTSUPPORTED(parm) (HRESULT (__stdcall *) (struct IDP8ServiceProvider *, parm)) DNMODEMSP_NotSupported
  177. //**********************************************************************
  178. // Function pointers
  179. //**********************************************************************
  180. // these are the vtables for serial and modem. One or the other is used depending on
  181. // what is passed to DoCreateInstance
  182. static IDP8ServiceProviderVtbl g_SerialInterface =
  183. {
  184. DNMODEMSP_QueryInterface,
  185. DNMODEMSP_AddRef,
  186. DNMODEMSP_Release,
  187. DNMODEMSP_Initialize,
  188. DNMODEMSP_Close,
  189. DNMODEMSP_Connect,
  190. DNMODEMSP_Disconnect,
  191. DNMODEMSP_Listen,
  192. DNMODEMSP_SendData,
  193. DNMODEMSP_EnumQuery,
  194. DNMODEMSP_EnumRespond,
  195. DNMODEMSP_CancelCommand,
  196. NOTSUPPORTED(PSPENUMMULTICASTSCOPESDATA), // EnumMulticastScopes
  197. NOTSUPPORTED(PSPSHAREENDPOINTINFODATA), // ShareEndpointInfo
  198. NOTSUPPORTED(PSPGETENDPOINTBYADDRESSDATA), // GetEndpointByAddress
  199. NOTSUPPORTED(PSPUPDATEDATA), // Update
  200. DNMODEMSP_GetCaps,
  201. DNMODEMSP_SetCaps,
  202. DNMODEMSP_ReturnReceiveBuffers,
  203. DNMODEMSP_GetAddressInfo,
  204. DNMODEMSP_IsApplicationSupported,
  205. DNMODEMSP_EnumAdapters,
  206. NOTSUPPORTED(PSPPROXYENUMQUERYDATA) // ProxyEnumQuery
  207. };
  208. static IDP8ServiceProviderVtbl g_ModemInterface =
  209. {
  210. DNMODEMSP_QueryInterface,
  211. DNMODEMSP_AddRef,
  212. DNMODEMSP_Release,
  213. DNMODEMSP_Initialize,
  214. DNMODEMSP_Close,
  215. DNMODEMSP_Connect,
  216. DNMODEMSP_Disconnect,
  217. DNMODEMSP_Listen,
  218. DNMODEMSP_SendData,
  219. DNMODEMSP_EnumQuery,
  220. DNMODEMSP_EnumRespond,
  221. DNMODEMSP_CancelCommand,
  222. NOTSUPPORTED(PSPENUMMULTICASTSCOPESDATA), // EnumMulticastScopes
  223. NOTSUPPORTED(PSPSHAREENDPOINTINFODATA), // ShareEndpointInfo
  224. NOTSUPPORTED(PSPGETENDPOINTBYADDRESSDATA), // GetEndpointByAddress
  225. NOTSUPPORTED(PSPUPDATEDATA), // Update
  226. DNMODEMSP_GetCaps,
  227. DNMODEMSP_SetCaps,
  228. DNMODEMSP_ReturnReceiveBuffers,
  229. DNMODEMSP_GetAddressInfo,
  230. DNMODEMSP_IsApplicationSupported,
  231. DNMODEMSP_EnumAdapters,
  232. NOTSUPPORTED(PSPPROXYENUMQUERYDATA) // ProxyEnumQuery
  233. };
  234. //**********************************************************************
  235. // Function definitions
  236. //**********************************************************************
  237. //**********************************************************************
  238. // ------------------------------
  239. // DNMODEMSP_QueryInterface - query for a particular interface
  240. //
  241. // Entry: Pointer to current interface
  242. // Desired interface ID
  243. // Pointer to pointer to new interface
  244. //
  245. // Exit: Error code
  246. // ------------------------------
  247. #undef DPF_MODNAME
  248. #define DPF_MODNAME "DNMODEMSP_QueryInterface"
  249. static STDMETHODIMP DNMODEMSP_QueryInterface( IDP8ServiceProvider *lpDNSP, REFIID riid, LPVOID * ppvObj )
  250. {
  251. HRESULT hr = S_OK;
  252. // assume no interface
  253. *ppvObj=NULL;
  254. // hmmm, switch would be cleaner...
  255. if( IsEqualIID(riid, IID_IUnknown) ||
  256. IsEqualIID(riid, IID_IDP8ServiceProvider) )
  257. {
  258. *ppvObj = lpDNSP;
  259. DNMODEMSP_AddRef( lpDNSP );
  260. }
  261. else
  262. {
  263. hr = E_NOINTERFACE;
  264. }
  265. return hr;
  266. }
  267. //**********************************************************************
  268. //**********************************************************************
  269. // ------------------------------
  270. // CreateModemInterface - create a modem interface
  271. //
  272. // Entry: Pointer to pointer to SP interface
  273. //
  274. // Exit: Error code
  275. // ------------------------------
  276. #undef DPF_MODNAME
  277. #define DPF_MODNAME "CreateModemInterface"
  278. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  279. HRESULT CreateModemInterface( const XDP8CREATE_PARAMS * const pDP8CreateParams, IDP8ServiceProvider **const ppiDP8SP )
  280. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  281. HRESULT CreateModemInterface( IDP8ServiceProvider **const ppiDP8SP )
  282. #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  283. {
  284. HRESULT hr;
  285. CModemSPData *pSPData;
  286. DNASSERT( ppiDP8SP != NULL );
  287. //
  288. // initialize
  289. //
  290. hr = DPN_OK;
  291. pSPData = NULL;
  292. *ppiDP8SP = NULL;
  293. //
  294. // create main data class
  295. //
  296. hr = CreateSPData( &pSPData,
  297. TYPE_MODEM,
  298. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  299. pDP8CreateParams,
  300. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  301. &g_ModemInterface );
  302. if ( hr != DPN_OK )
  303. {
  304. DNASSERT( pSPData == NULL );
  305. DPFX(DPFPREP, 0, "Problem creating SPData!" );
  306. DisplayDNError( 0, hr );
  307. goto Failure;
  308. }
  309. DNASSERT( pSPData != NULL );
  310. *ppiDP8SP = pSPData->COMInterface();
  311. Exit:
  312. return hr;
  313. Failure:
  314. if ( pSPData != NULL )
  315. {
  316. pSPData->DecRef();
  317. pSPData = NULL;
  318. }
  319. goto Exit;
  320. }
  321. //**********************************************************************
  322. //**********************************************************************
  323. // ------------------------------
  324. // CreateSerialInterface - create a serial interface
  325. //
  326. // Entry: Pointer to pointer to SP interface
  327. //
  328. // Exit: Error code
  329. // ------------------------------
  330. #undef DPF_MODNAME
  331. #define DPF_MODNAME "CreateSerialInterface"
  332. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  333. HRESULT CreateSerialInterface( const XDP8CREATE_PARAMS * const pDP8CreateParams, IDP8ServiceProvider **const ppiDP8SP )
  334. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  335. HRESULT CreateSerialInterface( IDP8ServiceProvider **const ppiDP8SP )
  336. #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  337. {
  338. HRESULT hr;
  339. CModemSPData *pSPData;
  340. DNASSERT( ppiDP8SP != NULL );
  341. //
  342. // initialize
  343. //
  344. hr = DPN_OK;
  345. pSPData = NULL;
  346. *ppiDP8SP = NULL;
  347. //
  348. // create main data class
  349. //
  350. hr = CreateSPData( &pSPData,
  351. TYPE_SERIAL,
  352. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  353. pDP8CreateParams,
  354. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  355. &g_SerialInterface );
  356. if ( hr != DPN_OK )
  357. {
  358. DNASSERT( pSPData == NULL );
  359. DPFX(DPFPREP, 0, "Problem creating SPData!" );
  360. DisplayDNError( 0, hr );
  361. goto Failure;
  362. }
  363. DNASSERT( pSPData != NULL );
  364. *ppiDP8SP = pSPData->COMInterface();
  365. Exit:
  366. return hr;
  367. Failure:
  368. if ( pSPData != NULL )
  369. {
  370. pSPData->DecRef();
  371. pSPData = NULL;
  372. }
  373. goto Exit;
  374. }
  375. //**********************************************************************
  376. #ifndef DPNBUILD_LIBINTERFACE
  377. //**********************************************************************
  378. // ------------------------------
  379. // ModemDoCreateInstance - create an instance of an interface
  380. //
  381. // Entry: Pointer to class factory
  382. // Pointer to unknown interface
  383. // Refernce of GUID of desired interface
  384. // Reference to another GUID?
  385. // Pointer to pointer to interface
  386. //
  387. // Exit: Error code
  388. // ------------------------------
  389. #undef DPF_MODNAME
  390. #define DPF_MODNAME "DoCreateInstance"
  391. HRESULT ModemDoCreateInstance( LPCLASSFACTORY This,
  392. LPUNKNOWN pUnkOuter,
  393. REFCLSID rclsid,
  394. REFIID riid,
  395. LPVOID *ppvObj )
  396. {
  397. HRESULT hr;
  398. DNASSERT( ppvObj != NULL );
  399. //
  400. // initialize
  401. //
  402. *ppvObj = NULL;
  403. //
  404. // we can either create an IPX instance or an IP instance
  405. //
  406. if (IsEqualCLSID(rclsid, CLSID_DP8SP_MODEM))
  407. {
  408. hr = CreateModemInterface( reinterpret_cast<IDP8ServiceProvider**>( ppvObj ) );
  409. }
  410. else if (IsEqualCLSID(rclsid, CLSID_DP8SP_SERIAL))
  411. {
  412. hr = CreateSerialInterface( reinterpret_cast<IDP8ServiceProvider**>( ppvObj ) );
  413. }
  414. else
  415. {
  416. // this shouldn't happen if they called IClassFactory::CreateObject correctly
  417. DPFX(DPFPREP, 0, "Got unexpected CLSID!");
  418. hr = E_UNEXPECTED;
  419. }
  420. return hr;
  421. }
  422. //**********************************************************************
  423. #endif // ! DPNBUILD_LIBINTERFACE
  424. //**********************************************************************
  425. // ------------------------------
  426. // IsClassImplemented - tells asked if this DLL implements a given class.
  427. // DLLs may implement multiple classes and multiple interfaces on those classes
  428. //
  429. // Entry: Class reference
  430. //
  431. // Exit: Boolean indicating whether the class is implemented
  432. // TRUE = class implemented
  433. // FALSE = class not implemented
  434. // ------------------------------
  435. #undef DPF_MODNAME
  436. #define DPF_MODNAME "IsClassImplemented"
  437. BOOL IsClassImplemented( REFCLSID rclsid )
  438. {
  439. return IsSerialGUID( &rclsid );
  440. }
  441. //**********************************************************************
  442. #define MAX_RESOURCE_STRING_LENGTH _MAX_PATH
  443. #undef DPF_MODNAME
  444. #define DPF_MODNAME "ModemLoadAndAllocString"
  445. HRESULT ModemLoadAndAllocString( UINT uiResourceID, wchar_t **lpswzString )
  446. {
  447. int length;
  448. HRESULT hr;
  449. TCHAR szTmpBuffer[MAX_RESOURCE_STRING_LENGTH];
  450. length = LoadString( g_hModemDLLInstance, uiResourceID, szTmpBuffer, MAX_RESOURCE_STRING_LENGTH );
  451. if( length == 0 )
  452. {
  453. hr = GetLastError();
  454. DPFX(DPFPREP, 0, "Unable to load resource ID %d error 0x%x", uiResourceID, hr );
  455. *lpswzString = NULL;
  456. return DPNERR_GENERIC;
  457. }
  458. else
  459. {
  460. *lpswzString = new wchar_t[length+1];
  461. if( *lpswzString == NULL )
  462. {
  463. DPFX(DPFPREP, 0, "Alloc failure" );
  464. return DPNERR_OUTOFMEMORY;
  465. }
  466. #ifdef UNICODE
  467. wcscpy( *lpswzString, szTmpBuffer );
  468. #else // !UNICODE
  469. if( STR_jkAnsiToWide( *lpswzString, szTmpBuffer, length+1 ) != DPN_OK )
  470. {
  471. hr = GetLastError();
  472. delete[] *lpswzString;
  473. *lpswzString = NULL;
  474. DPFX(DPFPREP, 0, "Unable to upconvert from ansi to unicode hr=0x%x", hr );
  475. return DPNERR_GENERIC;
  476. }
  477. #endif // !UNICODE
  478. return DPN_OK;
  479. }
  480. }