static UINT doNetCfgInit(MSIHANDLE hModule, INetCfg **ppnc, BOOL bWrite) { MSIHANDLE hMsg = NULL; UINT uErr = ERROR_GEN_FAILURE; int MsgResult; int cRetries = 0; do { LPWSTR lpszLockedBy; HRESULT hr = VBoxNetCfgWinQueryINetCfg(ppnc, bWrite, VBOX_NETCFG_APP_NAME, 10000, &lpszLockedBy); if (hr != NETCFG_E_NO_WRITE_LOCK) { if (FAILED(hr)) logStringW(hModule, L"doNetCfgInit: VBoxNetCfgWinQueryINetCfg failed, error = 0x%x", hr); uErr = errorConvertFromHResult(hModule, hr); break; } /* hr == NETCFG_E_NO_WRITE_LOCK */ if (!lpszLockedBy) { logStringW(hModule, L"doNetCfgInit: lpszLockedBy == NULL, breaking"); break; } /* on vista the 6to4svc.dll periodically maintains the lock for some reason, * if this is the case, increase the wait period by retrying multiple times * NOTE: we could alternatively increase the wait timeout, * however it seems unneeded for most cases, e.g. in case some network connection property * dialog is opened, it would be better to post a notification to the user as soon as possible * rather than waiting for a longer period of time before displaying it */ if ( cRetries < VBOX_NETCFG_MAX_RETRIES && !wcscmp(lpszLockedBy, L"6to4svc.dll")) { cRetries++; logStringW(hModule, L"doNetCfgInit: lpszLockedBy is 6to4svc.dll, retrying %d out of %d", cRetries, VBOX_NETCFG_MAX_RETRIES); MsgResult = IDRETRY; } else { if (!hMsg) { hMsg = createNetCfgLockedMsgRecord(hModule); if (!hMsg) { logStringW(hModule, L"doNetCfgInit: Failed to create a message record, breaking"); CoTaskMemFree(lpszLockedBy); break; } } UINT rTmp = MsiRecordSetStringW(hMsg, 2, lpszLockedBy); NonStandardAssert(rTmp == ERROR_SUCCESS); if (rTmp != ERROR_SUCCESS) { logStringW(hModule, L"doNetCfgInit: MsiRecordSetStringW failed, error = 0x%x", rTmp); CoTaskMemFree(lpszLockedBy); break; } MsgResult = MsiProcessMessage(hModule, (INSTALLMESSAGE)(INSTALLMESSAGE_USER | MB_RETRYCANCEL), hMsg); NonStandardAssert(MsgResult == IDRETRY || MsgResult == IDCANCEL); logStringW(hModule, L"doNetCfgInit: MsiProcessMessage returned (0x%x)", MsgResult); } CoTaskMemFree(lpszLockedBy); } while(MsgResult == IDRETRY); if (hMsg) MsiCloseHandle(hMsg); return uErr; }
static int VBoxNetLwfUninstall() { INetCfg *pnc; LPWSTR lpszLockedBy = NULL; int r; VBoxNetCfgWinSetLogging(winNetCfgLogger); HRESULT hr = CoInitialize(NULL); if (hr == S_OK) { int i = 0; do { hr = VBoxNetCfgWinQueryINetCfg(&pnc, TRUE, VBOX_NETCFG_APP_NAME, 10000, &lpszLockedBy); if (hr == S_OK) { hr = VBoxNetCfgWinNetLwfUninstall(pnc); if (hr != S_OK) { wprintf(L"error uninstalling VBoxNetLwf (0x%x)\n", hr); r = 1; } else { wprintf(L"uninstalled successfully\n"); r = 0; } VBoxNetCfgWinReleaseINetCfg(pnc, TRUE); break; } else if (hr == NETCFG_E_NO_WRITE_LOCK && lpszLockedBy) { if (i < VBOX_NETLWF_RETRIES && !wcscmp(lpszLockedBy, L"6to4svc.dll")) { wprintf(L"6to4svc.dll is holding the lock, retrying %d out of %d\n", ++i, VBOX_NETLWF_RETRIES); CoTaskMemFree(lpszLockedBy); } else { wprintf(L"Error: write lock is owned by another application (%s), close the application and retry uninstalling\n", lpszLockedBy); r = 1; CoTaskMemFree(lpszLockedBy); break; } } else { wprintf(L"Error getting the INetCfg interface (0x%x)\n", hr); r = 1; break; } } while (true); CoUninitialize(); } else { wprintf(L"Error initializing COM (0x%x)\n", hr); r = 1; } VBoxNetCfgWinSetLogging(NULL); return r; }
static int VBoxNetAdpInstall(void) { VBoxNetCfgWinSetLogging(winNetCfgLogger); HRESULT hr = CoInitialize(NULL); if (SUCCEEDED(hr)) { wprintf(L"adding host-only interface..\n"); DWORD dwErr = ERROR_SUCCESS; WCHAR MpInf[MAX_PATH]; if (!GetFullPathNameW(VBOX_NETADP_INF, sizeof(MpInf)/sizeof(MpInf[0]), MpInf, NULL)) dwErr = GetLastError(); if (dwErr == ERROR_SUCCESS) { INetCfg *pnc; LPWSTR lpszLockedBy = NULL; hr = VBoxNetCfgWinQueryINetCfg(&pnc, TRUE, VBOX_NETADP_APP_NAME, 10000, &lpszLockedBy); if(hr == S_OK) { hr = VBoxNetCfgWinNetAdpInstall(pnc, MpInf); if(hr == S_OK) { wprintf(L"installed successfully\n"); } else { wprintf(L"error installing VBoxNetAdp (0x%x)\n", hr); } VBoxNetCfgWinReleaseINetCfg(pnc, TRUE); } else wprintf(L"VBoxNetCfgWinQueryINetCfg failed: hr = 0x%x\n", hr); /* hr = VBoxDrvCfgInfInstall(MpInf); if (FAILED(hr)) printf("VBoxDrvCfgInfInstall failed %#x\n", hr); GUID guid; BSTR name, errMsg; hr = VBoxNetCfgWinCreateHostOnlyNetworkInterface (MpInf, true, &guid, &name, &errMsg); if (SUCCEEDED(hr)) { ULONG ip, mask; hr = VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(&ip, &mask); if (SUCCEEDED(hr)) { // ip returned by VBoxNetCfgWinGenHostOnlyNetworkNetworkIp is a network ip, // i.e. 192.168.xxx.0, assign 192.168.xxx.1 for the hostonly adapter ip = ip | (1 << 24); hr = VBoxNetCfgWinEnableStaticIpConfig(&guid, ip, mask); if (SUCCEEDED(hr)) { printf("installation successful\n"); } else printf("VBoxNetCfgWinEnableStaticIpConfig failed: hr = 0x%x\n", hr); } else printf("VBoxNetCfgWinGenHostOnlyNetworkNetworkIp failed: hr = 0x%x\n", hr); } else printf("VBoxNetCfgWinCreateHostOnlyNetworkInterface failed: hr = 0x%x\n", hr); */ } else { wprintf(L"GetFullPathNameW failed: winEr = %d\n", dwErr); hr = HRESULT_FROM_WIN32(dwErr); } CoUninitialize(); } else wprintf(L"Error initializing COM (0x%x)\n", hr); VBoxNetCfgWinSetLogging(NULL); return SUCCEEDED(hr) ? 0 : 1; }