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.

444 lines
13 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include <atlbase.h>
  4. extern CComModule _Module; // required by atlcom.h
  5. #include <atlcom.h>
  6. #include <netcfgx.h>
  7. #include "brdgobj.h"
  8. #include "trace.h"
  9. #include "ncbase.h"
  10. #include "ncmem.h"
  11. #include "ncreg.h"
  12. // =================================================================
  13. // string constants
  14. //
  15. const WCHAR c_szSBridgeNOParams[] = L"System\\CurrentControlSet\\Services\\BridgeMP";
  16. const WCHAR c_szSBridgeDeviceValueName[] = L"Device";
  17. const WCHAR c_szSBridgeDevicePrefix[] = L"\\Device\\";
  18. const WCHAR c_szSBrigeMPID[] = L"ms_bridgemp";
  19. // =================================================================
  20. // ----------------------------------------------------------------------
  21. //
  22. // Function: CBridgeNO::CBridgeNO
  23. //
  24. // Purpose: constructor for class CBridgeNO
  25. //
  26. // Arguments: None
  27. //
  28. // Returns: None
  29. //
  30. // Notes:
  31. //
  32. CBridgeNO::CBridgeNO(VOID) :
  33. m_pncc(NULL),
  34. m_pnc(NULL),
  35. m_eApplyAction(eBrdgActUnknown)
  36. {
  37. TraceTag( ttidBrdgCfg, "CBridgeNO::CBridgeNO()" );
  38. }
  39. // ----------------------------------------------------------------------
  40. //
  41. // Function: CBridgeNO::~CBridgeNO
  42. //
  43. // Purpose: destructor for class CBridgeNO
  44. //
  45. // Arguments: None
  46. //
  47. // Returns: None
  48. //
  49. // Notes:
  50. //
  51. CBridgeNO::~CBridgeNO(VOID)
  52. {
  53. TraceTag( ttidBrdgCfg, "CBridgeNO::~CBridgeNO()" );
  54. // release interfaces if acquired
  55. ReleaseObj(m_pncc);
  56. ReleaseObj(m_pnc);
  57. }
  58. // =================================================================
  59. // INetCfgNotify
  60. //
  61. // The following functions provide the INetCfgNotify interface
  62. // =================================================================
  63. // ----------------------------------------------------------------------
  64. //
  65. // Function: CBridgeNO::Initialize
  66. //
  67. // Purpose: Initialize the notify object
  68. //
  69. // Arguments:
  70. // pnccItem [in] pointer to INetCfgComponent object
  71. // pnc [in] pointer to INetCfg object
  72. // fInstalling [in] TRUE if we are being installed
  73. //
  74. // Returns:
  75. //
  76. // Notes:
  77. //
  78. STDMETHODIMP CBridgeNO::Initialize(INetCfgComponent* pnccItem,
  79. INetCfg* pnc, BOOL fInstalling)
  80. {
  81. TraceTag( ttidBrdgCfg, "CBridgeNO::Initialize()" );
  82. // save INetCfg & INetCfgComponent and add refcount
  83. m_pncc = pnccItem;
  84. m_pnc = pnc;
  85. AddRefObj( m_pncc );
  86. AddRefObj( m_pnc );
  87. return S_OK;
  88. }
  89. // ----------------------------------------------------------------------
  90. //
  91. // Function: CBridgeNO::ReadAnswerFile
  92. //
  93. // Purpose: Read settings from answerfile and configure the bridge
  94. //
  95. // Arguments:
  96. // pszAnswerFile [in] name of AnswerFile
  97. // pszAnswerSection [in] name of parameters section
  98. //
  99. // Returns:
  100. //
  101. // Notes: Dont do anything irreversible (like modifying registry) yet
  102. // since the config. actually complete only when Apply is called!
  103. //
  104. STDMETHODIMP CBridgeNO::ReadAnswerFile(PCWSTR pszAnswerFile,
  105. PCWSTR pszAnswerSection)
  106. {
  107. TraceTag( ttidBrdgCfg, "CBridgeNO::ReadAnswerFile()" );
  108. return S_OK;
  109. }
  110. // ----------------------------------------------------------------------
  111. //
  112. // Function: CBridgeNO::Install
  113. //
  114. // Purpose: Do operations necessary for install.
  115. //
  116. // Arguments:
  117. // dwSetupFlags [in] Setup flags
  118. //
  119. // Returns: S_OK on success, otherwise an error code
  120. //
  121. // Notes: Dont do anything irreversible (like modifying registry) yet
  122. // since the config. actually complete only when Apply is called!
  123. //
  124. STDMETHODIMP CBridgeNO::Install(DWORD dw)
  125. {
  126. //
  127. // Remember that we're installing. If the user doesn't cancel, we'll actually perform
  128. // our work in ApplyRegistryChanges().
  129. //
  130. TraceTag( ttidBrdgCfg, "CBridgeNO::Install()" );
  131. m_eApplyAction = eBrdgActInstall;
  132. return S_OK;
  133. }
  134. // ----------------------------------------------------------------------
  135. //
  136. // Function: CBridgeNO::Removing
  137. //
  138. // Purpose: Do necessary cleanup when being removed
  139. //
  140. // Arguments: None
  141. //
  142. // Returns: S_OK on success, otherwise an error code
  143. //
  144. // Notes: Dont do anything irreversible (like modifying registry) yet
  145. // since the removal is actually complete only when Apply is called!
  146. //
  147. STDMETHODIMP CBridgeNO::Removing(VOID)
  148. {
  149. TraceTag( ttidBrdgCfg, "CBridgeNO::Removing()" );
  150. m_eApplyAction = eBrdgActRemove;
  151. return S_OK;
  152. }
  153. // ----------------------------------------------------------------------
  154. //
  155. // Function: CBridgeNO::CancelChanges
  156. //
  157. // Purpose: Cancel any changes made to internal data
  158. //
  159. // Arguments: None
  160. //
  161. // Returns: S_OK on success, otherwise an error code
  162. //
  163. // Notes:
  164. //
  165. STDMETHODIMP CBridgeNO::CancelChanges(VOID)
  166. {
  167. TraceTag( ttidBrdgCfg, "CBridgeNO::CancelChanges()" );
  168. m_eApplyAction = eBrdgActUnknown;
  169. return S_OK;
  170. }
  171. // ----------------------------------------------------------------------
  172. //
  173. // Function: CBridgeNO::ApplyRegistryChanges
  174. //
  175. // Purpose: Apply changes.
  176. //
  177. // Arguments: None
  178. //
  179. // Returns: S_OK on success, otherwise an error code
  180. //
  181. // Notes: We can make changes to registry etc. here.
  182. //
  183. STDMETHODIMP CBridgeNO::ApplyRegistryChanges(VOID)
  184. {
  185. HRESULT hr = S_OK;
  186. TraceTag( ttidBrdgCfg, "CBridgeNO::ApplyRegistryChanges()" );
  187. //
  188. // We only do work on install
  189. //
  190. if( m_eApplyAction == eBrdgActInstall )
  191. {
  192. INetCfgComponent *pNetCfgComp;
  193. TraceTag( ttidBrdgCfg, "Attempting to write device name in CBridgeNO::ApplyRegistryChanges()" );
  194. hr = m_pnc->FindComponent( c_szSBrigeMPID, &pNetCfgComp );
  195. if( SUCCEEDED ( hr) )
  196. {
  197. LPWSTR wszBindName;
  198. hr = pNetCfgComp->GetBindName(&wszBindName);
  199. if( SUCCEEDED(hr) )
  200. {
  201. UINT BindNameLen, PrefixLen;
  202. LPWSTR wszDeviceName;
  203. // Get enough memory to build a string with the device prefix and the bind name
  204. // concatenated
  205. BindNameLen = wcslen(wszBindName);
  206. PrefixLen = wcslen(c_szSBridgeDevicePrefix);
  207. wszDeviceName = (WCHAR*)malloc( sizeof(WCHAR) * (BindNameLen + PrefixLen + 1) );
  208. if( wszDeviceName != NULL )
  209. {
  210. HKEY hkeyServiceParams;
  211. // Create the concatenated string
  212. wcscpy( wszDeviceName, c_szSBridgeDevicePrefix );
  213. wcscat( wszDeviceName, wszBindName );
  214. // Create the reg key where we need to stash the device name
  215. hr = HrRegCreateKeyEx( HKEY_LOCAL_MACHINE, c_szSBridgeNOParams, REG_OPTION_NON_VOLATILE,
  216. KEY_ALL_ACCESS, NULL, &hkeyServiceParams, NULL );
  217. if( SUCCEEDED(hr) )
  218. {
  219. // Write out the device name
  220. hr = HrRegSetSz( hkeyServiceParams, c_szSBridgeDeviceValueName, wszDeviceName );
  221. if( FAILED(hr) )
  222. {
  223. TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "HrRegSetSz failed in CBridgeNO::ApplyRegistryChanges()");
  224. }
  225. RegCloseKey( hkeyServiceParams );
  226. }
  227. else
  228. {
  229. TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "HrRegCreateKeyEx failed in CBridgeNO::ApplyRegistryChanges()");
  230. }
  231. free( wszDeviceName );
  232. }
  233. else
  234. {
  235. hr = E_OUTOFMEMORY;
  236. TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "malloc failed in CBridgeNO::ApplyRegistryChanges()");
  237. }
  238. CoTaskMemFree( wszBindName );
  239. }
  240. else
  241. {
  242. TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "pNetCfgComp->GetBindName failed in CBridgeNO::ApplyRegistryChanges()");
  243. }
  244. pNetCfgComp->Release();
  245. }
  246. else
  247. {
  248. TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "m_pnc->FindComponent failed in CBridgeNO::ApplyRegistryChanges()");
  249. }
  250. }
  251. // Paranoia
  252. m_eApplyAction = eBrdgActUnknown;
  253. return hr;
  254. }
  255. STDMETHODIMP
  256. CBridgeNO::ApplyPnpChanges(
  257. IN INetCfgPnpReconfigCallback* pICallback)
  258. {
  259. TraceTag( ttidBrdgCfg, "CBridgeNO::ApplyPnpChanges()" );
  260. return S_OK;
  261. }
  262. // =================================================================
  263. // INetCfgSystemNotify
  264. // =================================================================
  265. // ----------------------------------------------------------------------
  266. //
  267. // Function: CBridgeNO::GetSupportedNotifications
  268. //
  269. // Purpose: Tell the system which notifications we are interested in
  270. //
  271. // Arguments:
  272. // pdwNotificationFlag [out] pointer to NotificationFlag
  273. //
  274. // Returns: S_OK on success, otherwise an error code
  275. //
  276. // Notes:
  277. //
  278. STDMETHODIMP CBridgeNO::GetSupportedNotifications(
  279. OUT DWORD* pdwNotificationFlag)
  280. {
  281. TraceTag( ttidBrdgCfg, "CBridgeNO::GetSupportedNotifications()" );
  282. *pdwNotificationFlag = NCN_ADD | NCN_ENABLE | NCN_UPDATE | NCN_BINDING_PATH;
  283. return S_OK;
  284. }
  285. // ----------------------------------------------------------------------
  286. //
  287. // Function: CBridgeNO::SysQueryBindingPath
  288. //
  289. // Purpose: Allow or veto formation of a binding path
  290. //
  291. // Arguments:
  292. // dwChangeFlag [in] type of binding change
  293. // pncbp [in] pointer to INetCfgBindingPath object
  294. //
  295. // Returns: S_OK on success, otherwise an error code
  296. //
  297. // Notes:
  298. //
  299. STDMETHODIMP CBridgeNO::SysQueryBindingPath(DWORD dwChangeFlag,
  300. INetCfgBindingPath* pncbp)
  301. {
  302. HRESULT hr = S_OK;
  303. BOOLEAN bReject = FALSE;
  304. TraceTag( ttidBrdgCfg, "CBridgeNO::SysQueryBindingPath()" );
  305. return S_OK;
  306. }
  307. // ----------------------------------------------------------------------
  308. //
  309. // Function: CBridgeNO::SysNotifyBindingPath
  310. //
  311. // Purpose: System tells us by calling this function which
  312. // binding path has just been formed.
  313. //
  314. // Arguments:
  315. // dwChangeFlag [in] type of binding change
  316. // pncbpItem [in] pointer to INetCfgBindingPath object
  317. //
  318. // Returns: S_OK on success, otherwise an error code
  319. //
  320. // Notes:
  321. //
  322. STDMETHODIMP CBridgeNO::SysNotifyBindingPath(DWORD dwChangeFlag,
  323. INetCfgBindingPath* pncbpItem)
  324. {
  325. TraceTag( ttidBrdgCfg, "CBridgeNO::SysNotifyBindingPath()" );
  326. return S_OK;
  327. }
  328. // ----------------------------------------------------------------------
  329. //
  330. // Function: CBridgeNO::SysNotifyComponent
  331. //
  332. // Purpose: System tells us by calling this function which
  333. // component has undergone a change (installed/removed)
  334. //
  335. // Arguments:
  336. // dwChangeFlag [in] type of system change
  337. // pncc [in] pointer to INetCfgComponent object
  338. //
  339. // Returns: S_OK on success, otherwise an error code
  340. //
  341. // Notes:
  342. //
  343. STDMETHODIMP CBridgeNO::SysNotifyComponent(DWORD dwChangeFlag,
  344. INetCfgComponent* pncc)
  345. {
  346. TraceTag( ttidBrdgCfg, "CBridgeNO::SysNotifyComponent()" );
  347. return S_OK;
  348. }
  349. // =================================================================
  350. // INetCfgBindNotify
  351. // =================================================================
  352. // ----------------------------------------------------------------------
  353. //
  354. // Function: CBridgeNO::QueryBindingPath
  355. //
  356. // Purpose: Allow or veto a binding path involving us
  357. //
  358. // Arguments:
  359. // dwChangeFlag [in] type of binding change
  360. // pncbi [in] pointer to INetCfgBindingPath object
  361. //
  362. // Returns: S_OK on success, otherwise an error code
  363. //
  364. // Notes:
  365. //
  366. STDMETHODIMP CBridgeNO::QueryBindingPath(DWORD dwChangeFlag,
  367. INetCfgBindingPath* pncbp)
  368. {
  369. TraceTag( ttidBrdgCfg, "CBridgeNO::QueryBindingPath()" );
  370. // The bridge protocol should never be enabled by default; it
  371. // should only be enabled programatically by the implementation
  372. // of our UI code which allows the activation of the bridge.
  373. return NETCFG_S_DISABLE_QUERY;
  374. }
  375. // ----------------------------------------------------------------------
  376. //
  377. // Function: CBridgeNO::NotifyBindingPath
  378. //
  379. // Purpose: System tells us by calling this function which
  380. // binding path involving us has just been formed.
  381. //
  382. // Arguments:
  383. // dwChangeFlag [in] type of binding change
  384. // pncbp [in] pointer to INetCfgBindingPath object
  385. //
  386. // Returns: S_OK on success, otherwise an error code
  387. //
  388. // Notes:
  389. //
  390. STDMETHODIMP CBridgeNO::NotifyBindingPath(DWORD dwChangeFlag,
  391. INetCfgBindingPath* pncbp)
  392. {
  393. TraceTag( ttidBrdgCfg, "CBridgeNO::NotifyBindingPath()" );
  394. return S_OK;
  395. }
  396. // ------------ END OF NOTIFY OBJECT FUNCTIONS --------------------