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.

261 lines
6.4 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include <netcfgx.h>
  4. #include <devguid.h>
  5. HRESULT
  6. HrCreateINetCfg (
  7. IN BOOL fAcquireWriteLock,
  8. OUT INetCfg** ppINetCfg)
  9. {
  10. HRESULT hr;
  11. INetCfg* pINetCfg;
  12. // Get the INetCfg interface.
  13. //
  14. hr = CoCreateInstance(
  15. CLSID_CNetCfg,
  16. NULL,
  17. CLSCTX_INPROC_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  18. IID_INetCfg,
  19. reinterpret_cast<void**>(&pINetCfg));
  20. if (S_OK == hr) {
  21. INetCfgLock * pnclock = NULL;
  22. if (fAcquireWriteLock) {
  23. // Get the locking interface
  24. hr = pINetCfg->QueryInterface(IID_INetCfgLock,
  25. reinterpret_cast<LPVOID *>(&pnclock));
  26. if (SUCCEEDED(hr)) {
  27. LPWSTR pwszLockHolder;
  28. // Attempt to lock the INetCfg for read/write
  29. hr = pnclock->AcquireWriteLock(100, L"InstallIPv6",
  30. &pwszLockHolder);
  31. if (S_FALSE == hr) {
  32. // Couldn't acquire the lock
  33. hr = NETCFG_E_NO_WRITE_LOCK;
  34. DisplayMessage(g_hModule, EMSG_NO_WRITE_LOCK,
  35. pwszLockHolder);
  36. }
  37. if (pwszLockHolder) {
  38. CoTaskMemFree(pwszLockHolder);
  39. }
  40. }
  41. }
  42. if (S_OK == hr) {
  43. hr = pINetCfg->Initialize (NULL);
  44. if (S_OK == hr) {
  45. *ppINetCfg = pINetCfg;
  46. pINetCfg->AddRef();
  47. }
  48. else {
  49. if (pnclock) {
  50. pnclock->ReleaseWriteLock();
  51. }
  52. }
  53. }
  54. if (pnclock) {
  55. pnclock->Release();
  56. }
  57. //Transfer ownership to caller.
  58. pINetCfg->Release();
  59. }
  60. return hr;
  61. }
  62. DWORD
  63. pAddOrRemoveIpv6(BOOL fAddIpv6)
  64. {
  65. HRESULT hr;
  66. INetCfg* pINetCfg;
  67. DWORD dwErr = NO_ERROR;
  68. hr = HrCreateINetCfg (TRUE, &pINetCfg);
  69. if (S_OK == hr) {
  70. INetCfgClassSetup* pSetup;
  71. // Get the setup interface used for installing
  72. // and uninstalling components.
  73. //
  74. hr = pINetCfg->QueryNetCfgClass (
  75. &GUID_DEVCLASS_NETTRANS,
  76. IID_INetCfgClassSetup,
  77. (VOID**)&pSetup);
  78. if (S_OK == hr) {
  79. OBO_TOKEN OboToken;
  80. INetCfgComponent* pIComp;
  81. ZeroMemory (&OboToken, sizeof(OboToken));
  82. OboToken.Type = OBO_USER;
  83. if (fAddIpv6) {
  84. hr = pSetup->Install (
  85. L"MS_TCPIP6",
  86. &OboToken,
  87. 0, 0, NULL, NULL,
  88. &pIComp);
  89. if (pIComp) {
  90. pIComp->Release();
  91. }
  92. } else {
  93. // Need to remove the component.
  94. // Find it first.
  95. //
  96. hr = pINetCfg->FindComponent (
  97. L"MS_TCPIP6",
  98. &pIComp);
  99. if (S_OK == hr) {
  100. hr = pSetup->DeInstall (
  101. pIComp,
  102. &OboToken,
  103. NULL);
  104. pIComp->Release();
  105. } else {
  106. DisplayMessage(g_hModule, EMSG_PROTO_NOT_INSTALLED);
  107. dwErr = ERROR_SUPPRESS_OUTPUT;
  108. }
  109. }
  110. if (SUCCEEDED(hr)) {
  111. if (NETCFG_S_REBOOT == hr) {
  112. hr = S_OK;
  113. DisplayMessage(g_hModule, EMSG_REBOOT_NEEDED);
  114. dwErr = ERROR_SUPPRESS_OUTPUT;
  115. } else {
  116. dwErr = ERROR_OKAY;
  117. }
  118. } else {
  119. if (NETCFG_E_NEED_REBOOT == hr) {
  120. DisplayMessage(g_hModule, EMSG_REBOOT_NEEDED);
  121. dwErr = ERROR_SUPPRESS_OUTPUT;
  122. } else {
  123. dwErr = hr;
  124. }
  125. }
  126. pSetup->Release();
  127. }
  128. hr = pINetCfg->Uninitialize();
  129. if (SUCCEEDED(hr)) {
  130. INetCfgLock *pnclock;
  131. // Get the locking interface
  132. hr = pINetCfg->QueryInterface(IID_INetCfgLock,
  133. reinterpret_cast<LPVOID *>(&pnclock));
  134. if (SUCCEEDED(hr)) {
  135. // Attempt to lock the INetCfg for read/write
  136. hr = pnclock->ReleaseWriteLock();
  137. pnclock->Release();
  138. }
  139. }
  140. pINetCfg->Release();
  141. }
  142. else if (NETCFG_E_NO_WRITE_LOCK == hr) {
  143. // Message has already been printed
  144. dwErr = ERROR_SUPPRESS_OUTPUT;
  145. }
  146. else if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr) {
  147. dwErr = ERROR_ACCESS_DENIED;
  148. }
  149. else {
  150. dwErr = hr;
  151. }
  152. return dwErr;
  153. }
  154. EXTERN_C
  155. DWORD
  156. IsIpv6Installed(
  157. BOOL *bInstalled)
  158. {
  159. HRESULT hr = S_OK;
  160. BOOL fInitCom = TRUE;
  161. BOOL fPresent = FALSE;
  162. DWORD dwErr = NO_ERROR;
  163. // Initialize COM.
  164. //
  165. hr = CoInitializeEx( NULL,
  166. COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED );
  167. if (RPC_E_CHANGED_MODE == hr) {
  168. // If we changed mode, then we won't uninitialize COM when we are done.
  169. //
  170. hr = S_OK;
  171. fInitCom = FALSE;
  172. }
  173. if (SUCCEEDED(hr)) {
  174. HRESULT hr;
  175. INetCfg* pINetCfg;
  176. hr = HrCreateINetCfg (FALSE, &pINetCfg);
  177. if (S_OK == hr) {
  178. fPresent = (S_OK == pINetCfg->FindComponent(L"MS_TCPIP6", NULL));
  179. pINetCfg->Uninitialize();
  180. pINetCfg->Release();
  181. } else {
  182. dwErr = hr;
  183. }
  184. if (fInitCom) {
  185. CoUninitialize();
  186. }
  187. } else {
  188. dwErr = hr;
  189. }
  190. *bInstalled = fPresent;
  191. return dwErr;
  192. }
  193. EXTERN_C
  194. DWORD
  195. AddOrRemoveIpv6 (
  196. IN BOOL fAddIpv6)
  197. {
  198. HRESULT hr = S_OK;
  199. BOOL fInitCom = TRUE;
  200. DWORD dwErr = NO_ERROR;
  201. // Initialize COM.
  202. //
  203. hr = CoInitializeEx( NULL,
  204. COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED );
  205. if (RPC_E_CHANGED_MODE == hr) {
  206. // If we changed mode, then we won't uninitialize COM when we are done.
  207. //
  208. hr = S_OK;
  209. fInitCom = FALSE;
  210. }
  211. if (SUCCEEDED(hr)) {
  212. dwErr = pAddOrRemoveIpv6(fAddIpv6);
  213. if (fInitCom) {
  214. CoUninitialize();
  215. }
  216. }
  217. else {
  218. dwErr = hr;
  219. }
  220. return dwErr;
  221. }