63
static void LogString(MSIHANDLE hInstall, LPCSTR szString, ...)
75
static void logString(MSIHANDLE hInstall, LPCSTR szString, ...)
65
77
PMSIHANDLE newHandle = MsiCreateRecord(2);
67
char szBuffer[1024] = {0};
69
va_start(pArgList, szString);
70
_vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(char), szString, pArgList);
81
va_start(va, szString);
82
_vsnprintf(szBuffer, sizeof(szBuffer), szString, va);
73
85
MsiRecordSetStringA(newHandle, 0, szBuffer);
74
86
MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_INFO), newHandle);
75
87
MsiCloseHandle(newHandle);
89
#if 0/*def DEBUG - wrong? What does '%s' expect, wchar or char? */
78
90
_tprintf(_T("Debug: %s\n"), szBuffer);
82
static void LogStringW(MSIHANDLE hInstall, LPCWSTR szString, ...)
94
static void logStringW(MSIHANDLE hInstall, LPCWSTR pwszString, ...)
84
96
PMSIHANDLE newHandle = MsiCreateRecord(2);
86
TCHAR szBuffer[1024] = {0};
88
va_start(pArgList, szString);
89
_vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), szString, pArgList);
100
va_start(va, pwszString);
101
_vsnwprintf(szBuffer, RT_ELEMENTS(szBuffer), pwszString, va);
92
104
MsiRecordSetStringW(newHandle, 0, szBuffer);
93
105
MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_INFO), newHandle);
127
139
si.cb = sizeof(si);
128
140
ZeroMemory(&pi, sizeof(pi));
130
LogStringW(hModule, TEXT("Executing command line: %s %s (Working Dir: %s)"),
131
pszAppName, pszCmdLine, pszWorkDir == NULL ? L"Current" : pszWorkDir);
142
logStringW(hModule, L"Executing command line: %s %s (Working Dir: %s)",
143
pwszAppName, pwszCmdLine, pwszWorkDir == NULL ? L"Current" : pwszWorkDir);
134
if (!CreateProcess(pszAppName, /* Module name. */
135
pszCmdLine, /* Command line. */
136
NULL, /* Process handle not inheritable. */
137
NULL, /* Thread handle not inheritable. */
138
FALSE, /* Set handle inheritance to FALSE .*/
139
0, /* No creation flags. */
140
NULL, /* Use parent's environment block. */
141
pszWorkDir, /* Use parent's starting directory. */
142
&si, /* Pointer to STARTUPINFO structure. */
143
&pi)) /* Pointer to PROCESS_INFORMATION structure. */
146
if (!CreateProcessW(pwszAppName, /* Module name. */
147
pwszCmdLine, /* Command line. */
148
NULL, /* Process handle not inheritable. */
149
NULL, /* Thread handle not inheritable. */
150
FALSE, /* Set handle inheritance to FALSE .*/
151
0, /* No creation flags. */
152
NULL, /* Use parent's environment block. */
153
pwszWorkDir, /* Use parent's starting directory. */
154
&si, /* Pointer to STARTUPINFO structure. */
155
&pi)) /* Pointer to PROCESS_INFORMATION structure. */
145
157
rc = GetLastError();
146
LogStringW(hModule, TEXT("Executing command line: CreateProcess() failed! Error: %ld"), rc);
158
logStringW(hModule, L"Executing command line: CreateProcess() failed! Error: %ld", rc);
166
178
CloseHandle(pi.hProcess);
167
179
CloseHandle(pi.hThread);
169
LogStringW(hModule, TEXT("Executing command returned: %ld (exit code %ld)"), rc, *pdwExitCode);
181
logStringW(hModule, L"Executing command returned: %u (exit code %u)", rc, *pdwExitCode);
173
185
UINT __stdcall InstallPythonAPI(MSIHANDLE hModule)
175
LogStringW(hModule, TEXT("InstallPythonAPI: Checking for installed Python environment ..."));
187
logStringW(hModule, L"InstallPythonAPI: Checking for installed Python environment ...");
177
189
HKEY hkPythonCore = NULL;
178
190
BOOL bFound = FALSE;
179
LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Python\\PythonCore", 0, KEY_READ, &hkPythonCore);
191
LONG rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Python\\PythonCore", 0, KEY_READ, &hkPythonCore);
180
192
if (rc != ERROR_SUCCESS)
182
LogStringW(hModule, TEXT("InstallPythonAPI: Python seems not to be installed."));
194
logStringW(hModule, L"InstallPythonAPI: Python seems not to be installed.");
183
195
return ERROR_SUCCESS;
186
TCHAR szPath[MAX_PATH] = { 0 };
187
TCHAR szVal[MAX_PATH] = { 0 };
198
WCHAR wszPath[MAX_PATH] = { 0 };
199
WCHAR wszVal[MAX_PATH] = { 0 };
189
201
for (int i = 0;; ++i)
191
TCHAR szRoot[MAX_PATH] = { 0 };
192
DWORD dwLen = sizeof (szPath);
203
WCHAR wszRoot[MAX_PATH] = { 0 };
204
DWORD dwLen = sizeof(wszPath);
193
205
DWORD dwKeyType = REG_SZ;
195
rc = RegEnumKeyEx(hkPythonCore, i, szRoot, &dwLen, NULL, NULL, NULL, NULL);
207
rc = RegEnumKeyExW(hkPythonCore, i, wszRoot, &dwLen, NULL, NULL, NULL, NULL);
196
208
if (rc != ERROR_SUCCESS || dwLen <= 0)
199
_stprintf_s(szPath, sizeof(szPath) / sizeof(TCHAR), L"%s\\InstallPath", szRoot);
200
dwLen = sizeof(szVal);
211
swprintf_s(wszPath, RT_ELEMENTS(wszPath), L"%s\\InstallPath", wszRoot);
212
dwLen = sizeof(wszVal);
202
214
HKEY hkPythonInstPath = NULL;
203
rc = RegOpenKeyEx(hkPythonCore, szPath, 0, KEY_READ, &hkPythonInstPath);
215
rc = RegOpenKeyExW(hkPythonCore, wszPath, 0, KEY_READ, &hkPythonInstPath);
204
216
if (rc != ERROR_SUCCESS)
207
rc = RegQueryValueEx(hkPythonInstPath, L"", NULL, &dwKeyType, (LPBYTE)szVal, &dwLen);
219
rc = RegQueryValueExW(hkPythonInstPath, L"", NULL, &dwKeyType, (LPBYTE)wszVal, &dwLen);
208
220
if (rc == ERROR_SUCCESS)
209
LogStringW(hModule, TEXT("InstallPythonAPI: Path \"%s\" detected."), szVal);
221
logStringW(hModule, L"InstallPythonAPI: Path \"%s\" detected.", wszVal);
211
223
RegCloseKey(hkPythonInstPath);
213
225
RegCloseKey(hkPythonCore);
215
227
/* Python path found? */
216
TCHAR szExec[MAX_PATH] = { 0 };
217
TCHAR szCmdLine[MAX_PATH] = { 0 };
228
WCHAR wszExec[MAX_PATH] = { 0 };
229
WCHAR wszCmdLine[MAX_PATH] = { 0 };
218
230
DWORD dwExitCode = 0;
219
if (_tcslen(szVal) > 0)
231
if (wcslen(wszVal) > 0)
221
233
/* Cool, check for installed Win32 extensions. */
222
LogStringW(hModule, TEXT("InstallPythonAPI: Python installed. Checking for Win32 extensions ..."));
223
_stprintf_s(szExec, sizeof(szExec) / sizeof(TCHAR), L"%s\\python.exe", szVal);
224
_stprintf_s(szCmdLine, sizeof(szCmdLine) / sizeof(TCHAR), L"%s\\python.exe -c \"import win32api\"", szVal);
234
logStringW(hModule, L"InstallPythonAPI: Python installed. Checking for Win32 extensions ...");
235
swprintf_s(wszExec, RT_ELEMENTS(wszExec), L"%s\\python.exe", wszVal);
236
swprintf_s(wszCmdLine, RT_ELEMENTS(wszCmdLine), L"%s\\python.exe -c \"import win32api\"", wszVal);
226
DWORD dwRetExec = Exec(hModule, szExec, szCmdLine, NULL, &dwExitCode);
238
DWORD dwRetExec = Exec(hModule, wszExec, wszCmdLine, NULL, &dwExitCode);
227
239
if ( (ERROR_SUCCESS == dwRetExec)
228
240
&& ( 0 == dwExitCode))
230
242
/* Did we get the correct error level (=0)? */
231
LogStringW(hModule, TEXT("InstallPythonAPI: Win32 extensions installed."));
243
logStringW(hModule, L"InstallPythonAPI: Win32 extensions installed.");
235
LogStringW(hModule, TEXT("InstallPythonAPI: Win32 extensions not found."));
247
logStringW(hModule, L"InstallPythonAPI: Win32 extensions not found.");
238
250
BOOL bInstalled = FALSE;
239
251
if (bFound) /* Is Python and all required stuff installed? */
241
253
/* Get the VBoxAPI setup string. */
242
TCHAR szPathTargetDir[MAX_PATH] = {0};
243
VBoxGetProperty(hModule, L"CustomActionData", szPathTargetDir, sizeof(szPathTargetDir));
244
if (_tcslen(szPathTargetDir))
254
WCHAR wszPathTargetDir[MAX_PATH] = {0};
255
VBoxGetProperty(hModule, L"CustomActionData", wszPathTargetDir, sizeof(wszPathTargetDir));
256
if (wcslen(wszPathTargetDir))
247
259
/* Set final path. */
248
_stprintf_s(szPath, sizeof(szPath) / sizeof(TCHAR), L"%s\\sdk\\install", szPathTargetDir);
260
swprintf_s(wszPath, RT_ELEMENTS(wszPath), L"%s\\sdk\\install", wszPathTargetDir);
250
262
/* Install our API module. */
251
_stprintf_s(szCmdLine, sizeof(szCmdLine) / sizeof(TCHAR), L"%s\\python.exe vboxapisetup.py install", szVal);
263
swprintf_s(wszCmdLine, RT_ELEMENTS(wszCmdLine), L"%s\\python.exe vboxapisetup.py install", wszVal);
253
265
/* Set required environment variables. */
254
if (!SetEnvironmentVariable(L"VBOX_INSTALL_PATH", szPathTargetDir))
256
LogStringW(hModule, TEXT("InstallPythonAPI: Could set environment variable VBOX_INSTALL_PATH!"));
266
if (!SetEnvironmentVariableW(L"VBOX_INSTALL_PATH", wszPathTargetDir))
267
logStringW(hModule, L"InstallPythonAPI: Could set environment variable VBOX_INSTALL_PATH!");
260
DWORD dwRetExec = Exec(hModule, szExec, szCmdLine, szPath, &dwExitCode);
270
DWORD dwRetExec = Exec(hModule, wszExec, wszCmdLine, wszPath, &dwExitCode);
261
271
if ( (ERROR_SUCCESS == dwRetExec)
262
272
&& ( 0 == dwExitCode))
265
LogStringW(hModule, TEXT("InstallPythonAPI: VBoxAPI for Python successfully installed."));
275
logStringW(hModule, L"InstallPythonAPI: VBoxAPI for Python successfully installed.");
266
276
bInstalled = TRUE;
271
LogStringW(hModule, TEXT("InstallPythonAPI: Error while executing installation of VBox API: %ld"), dwRetExec);
281
logStringW(hModule, L"InstallPythonAPI: Error while executing installation of VBox API: %ld", dwRetExec);
273
LogStringW(hModule, TEXT("InstallPythonAPI: Python reported an error while installing VBox API: %ld"), dwExitCode);
283
logStringW(hModule, L"InstallPythonAPI: Python reported an error while installing VBox API: %ld", dwExitCode);
278
LogStringW(hModule, TEXT("InstallPythonAPI: Unable to retrieve VBox installation path!"));
288
logStringW(hModule, L"InstallPythonAPI: Unable to retrieve VBox installation path!");
281
291
VBoxSetProperty(hModule, L"PYTHON_INSTALLED", bInstalled ? L"1" : L"0");
284
LogStringW(hModule, TEXT("InstallPythonAPI: VBox API not installed."));
294
logStringW(hModule, L"InstallPythonAPI: VBox API not installed.");
285
295
return ERROR_SUCCESS; /* Do not fail here. */
288
static LONG InstallBrandingValue(MSIHANDLE hModule,
289
const TCHAR* pszFileName,
290
const TCHAR* pszSection,
291
const TCHAR* pszValue)
298
static LONG installBrandingValue(MSIHANDLE hModule,
299
const WCHAR *pwszFileName,
300
const WCHAR *pwszSection,
301
const WCHAR *pwszValue)
294
TCHAR szValue[_MAX_PATH];
295
if (GetPrivateProfileString(pszSection, pszValue, NULL,
296
szValue, sizeof(szValue), pszFileName) > 0)
304
WCHAR wszValue[_MAX_PATH];
305
if (GetPrivateProfileStringW(pwszSection, pwszValue, NULL,
306
wszValue, sizeof(wszValue), pwszFileName) > 0)
299
TCHAR szKey[_MAX_PATH];
309
WCHAR wszKey[_MAX_PATH];
301
if (wcsicmp(L"General", pszSection) != 0)
302
_stprintf_s(szKey, sizeof(szKey) / sizeof(TCHAR), L"SOFTWARE\\%s\\VirtualBox\\Branding\\", VBOX_VENDOR_SHORT, pszSection);
311
if (wcsicmp(L"General", pwszSection) != 0)
312
swprintf_s(wszKey, RT_ELEMENTS(wszKey), L"SOFTWARE\\%s\\VirtualBox\\Branding\\", VBOX_VENDOR_SHORT, pwszSection);
304
_stprintf_s(szKey, sizeof(szKey) / sizeof(TCHAR), L"SOFTWARE\\%s\\VirtualBox\\Branding", VBOX_VENDOR_SHORT);
314
swprintf_s(wszKey, RT_ELEMENTS(wszKey), L"SOFTWARE\\%s\\VirtualBox\\Branding", VBOX_VENDOR_SHORT);
306
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey,
307
0, KEY_WRITE, &hkBranding);
316
rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszKey, 0, KEY_WRITE, &hkBranding);
308
317
if (rc == ERROR_SUCCESS)
310
rc = RegSetValueEx(hkBranding,
315
(DWORD)wcslen(szValue));
319
rc = RegSetValueExW(hkBranding,
324
(DWORD)wcslen(wszValue));
316
325
if (rc != ERROR_SUCCESS)
317
LogStringW(hModule, TEXT("InstallBranding: Could not write value %s! Error %ld"), pszValue, rc);
326
logStringW(hModule, L"InstallBranding: Could not write value %s! Error %ld", pwszValue, rc);
318
327
RegCloseKey (hkBranding);
418
425
UINT __stdcall UninstallBranding(MSIHANDLE hModule)
421
LogStringW(hModule, TEXT("UninstallBranding: Handling branding file ..."));
423
TCHAR szPathTargetDir[_MAX_PATH];
424
TCHAR szPathDest[_MAX_PATH];
426
rc = VBoxGetProperty(hModule, L"CustomActionData", szPathTargetDir, sizeof(szPathTargetDir));
428
logStringW(hModule, L"UninstallBranding: Handling branding file ...");
430
WCHAR wszPathTargetDir[_MAX_PATH];
431
WCHAR wszPathDest[_MAX_PATH];
433
rc = VBoxGetProperty(hModule, L"CustomActionData", wszPathTargetDir, sizeof(wszPathTargetDir));
427
434
if (rc == ERROR_SUCCESS)
429
436
/** @todo Check trailing slash after %s. */
430
_stprintf_s(szPathDest, sizeof(szPathDest) / sizeof(TCHAR), L"%scustom", szPathTargetDir);
431
rc = RemoveDir(hModule, szPathDest);
437
/** @todo r=bird: using swprintf_s for formatting paths without checking for
438
* overflow not good. You're dodging the buffer overflow issue only to end up
439
* with incorrect behavior! (Truncated file/dir names)
441
* This applies almost to all swprintf_s calls in this file!!
443
swprintf_s(wszPathDest, RT_ELEMENTS(wszPathDest), L"%scustom", wszPathTargetDir);
444
rc = RemoveDir(hModule, wszPathDest);
432
445
if (rc != ERROR_SUCCESS)
434
447
/* Check for hidden .custom directory and remove it. */
435
_stprintf_s(szPathDest, sizeof(szPathDest) / sizeof(TCHAR), L"%s.custom", szPathTargetDir);
436
rc = RemoveDir(hModule, szPathDest);
448
swprintf_s(wszPathDest, RT_ELEMENTS(wszPathDest), L"%s.custom", wszPathTargetDir);
449
rc = RemoveDir(hModule, wszPathDest);
440
LogStringW(hModule, TEXT("UninstallBranding: Handling done."));
453
logStringW(hModule, L"UninstallBranding: Handling done. (rc=%u (ignored))", rc);
441
454
return ERROR_SUCCESS; /* Do not fail here. */
444
457
UINT __stdcall InstallBranding(MSIHANDLE hModule)
447
LogStringW(hModule, TEXT("InstallBranding: Handling branding file ..."));
449
TCHAR szPathMSI[_MAX_PATH];
450
TCHAR szPathTargetDir[_MAX_PATH];
452
TCHAR szPathSource[_MAX_PATH];
453
TCHAR szPathDest[_MAX_PATH];
455
rc = VBoxGetProperty(hModule, L"SOURCEDIR", szPathMSI, sizeof(szPathMSI));
460
logStringW(hModule, L"InstallBranding: Handling branding file ...");
462
WCHAR wszPathMSI[_MAX_PATH];
463
rc = VBoxGetProperty(hModule, L"SOURCEDIR", wszPathMSI, sizeof(wszPathMSI));
456
464
if (rc == ERROR_SUCCESS)
458
rc = VBoxGetProperty(hModule, L"CustomActionData", szPathTargetDir, sizeof(szPathTargetDir));
466
WCHAR wszPathTargetDir[_MAX_PATH];
467
rc = VBoxGetProperty(hModule, L"CustomActionData", wszPathTargetDir, sizeof(wszPathTargetDir));
459
468
if (rc == ERROR_SUCCESS)
461
470
/** @todo Check for trailing slash after %s. */
462
_stprintf_s(szPathDest, sizeof(szPathDest) / sizeof(TCHAR), L"%s", szPathTargetDir);
463
_stprintf_s(szPathSource, sizeof(szPathSource) / sizeof(TCHAR), L"%s.custom", szPathMSI);
464
rc = CopyDir(hModule, szPathDest, szPathSource);
471
WCHAR wszPathDest[_MAX_PATH];
472
swprintf_s(wszPathDest, RT_ELEMENTS(wszPathDest), L"%s", wszPathTargetDir);
474
WCHAR wszPathSource[_MAX_PATH];
475
swprintf_s(wszPathSource, RT_ELEMENTS(wszPathSource), L"%s.custom", wszPathMSI);
476
rc = CopyDir(hModule, wszPathDest, wszPathSource);
465
477
if (rc == ERROR_SUCCESS)
467
_stprintf_s(szPathDest, sizeof(szPathDest) / sizeof(TCHAR), L"%scustom", szPathTargetDir);
468
_stprintf_s(szPathSource, sizeof(szPathSource) / sizeof(TCHAR), L"%s.custom", szPathTargetDir);
469
rc = RenameDir(hModule, szPathDest, szPathSource);
479
swprintf_s(wszPathDest, RT_ELEMENTS(wszPathDest), L"%scustom", wszPathTargetDir);
480
swprintf_s(wszPathSource, RT_ELEMENTS(wszPathSource), L"%s.custom", wszPathTargetDir);
481
rc = RenameDir(hModule, wszPathDest, wszPathSource);
474
LogStringW(hModule, TEXT("InstallBranding: Handling done."));
486
logStringW(hModule, L"InstallBranding: Handling done. (rc=%u (ignored))", rc);
475
487
return ERROR_SUCCESS; /* Do not fail here. */
637
static UINT vboxNetFltQueryInfArray(MSIHANDLE hModule, OUT LPWSTR *apInfFullPaths, PUINT pcInfs, DWORD dwSize)
649
static UINT vboxNetFltQueryInfArray(MSIHANDLE hModule, OUT LPWSTR pwszPtInf, OUT LPWSTR pwszMpInf, DWORD dwSize)
651
DWORD dwBuf = dwSize - RT_MAX(sizeof(NETFLT_PT_INF_REL_PATH), sizeof(NETFLT_MP_INF_REL_PATH));
652
UINT uErr = MsiGetPropertyW(hModule, L"CustomActionData", pwszPtInf, &dwBuf);
653
if ( uErr == ERROR_SUCCESS
644
DWORD dwBuf = dwSize;
645
uErr = MsiGetPropertyW(hModule, L"CustomActionData", apInfFullPaths[0], &dwBuf);
646
if ( uErr == ERROR_SUCCESS
649
/** @todo r=andy Avoid wcscpy and wcsncat, can cause buffer overruns! */
650
wcscpy(apInfFullPaths[1], apInfFullPaths[0]);
652
wcsncat(apInfFullPaths[0], NETFLT_PT_INF_REL_PATH, sizeof(NETFLT_PT_INF_REL_PATH));
653
LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: INF 1: %s"), apInfFullPaths[0]);
655
wcsncat(apInfFullPaths[1], NETFLT_MP_INF_REL_PATH, sizeof(NETFLT_MP_INF_REL_PATH));
656
LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: INF 2: %s"), apInfFullPaths[1]);
660
if (uErr != ERROR_SUCCESS)
661
LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: MsiGetPropertyW failed, error = 0x%x"), uErr);
663
LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: Empty installation directory"));
656
wcscpy(pwszMpInf, pwszPtInf);
658
wcsncat(pwszPtInf, NETFLT_PT_INF_REL_PATH, sizeof(NETFLT_PT_INF_REL_PATH));
659
logStringW(hModule, L"vboxNetFltQueryInfArray: INF 1: %s", pwszPtInf);
661
wcsncat(pwszMpInf, NETFLT_MP_INF_REL_PATH, sizeof(NETFLT_MP_INF_REL_PATH));
662
logStringW(hModule, L"vboxNetFltQueryInfArray: INF 2: %s", pwszMpInf);
664
else if (uErr != ERROR_SUCCESS)
665
logStringW(hModule, L"vboxNetFltQueryInfArray: MsiGetPropertyW failed, error = 0x%x", uErr);
668
uErr = ERROR_BUFFER_OVERFLOW;
669
LogStringW(hModule, TEXT("vboxNetFltQueryInfArray: Buffer array size is < 2 (%u)"), *pcInfs);
668
logStringW(hModule, L"vboxNetFltQueryInfArray: Empty installation directory");
669
uErr = ERROR_GEN_FAILURE;
738
LogStringW(hModule, TEXT("Installing NetFlt"));
738
logStringW(hModule, L"Installing NetFlt");
740
740
uErr = doNetCfgInit(hModule, &pNetCfg, TRUE);
741
741
if (uErr == ERROR_SUCCESS)
743
WCHAR PtInf[MAX_PATH];
744
WCHAR MpInf[MAX_PATH];
745
DWORD sz = sizeof(PtInf);
746
LPWSTR aInfs[] = {PtInf, MpInf};
748
uErr = vboxNetFltQueryInfArray(hModule, aInfs, &cInfs, sz);
743
WCHAR wszPtInf[MAX_PATH];
744
WCHAR wszMpInf[MAX_PATH];
745
uErr = vboxNetFltQueryInfArray(hModule, wszPtInf, wszMpInf, sizeof(wszMpInf));
749
746
if (uErr == ERROR_SUCCESS)
751
HRESULT hr = VBoxNetCfgWinNetFltInstall(pNetCfg, (LPCWSTR*)aInfs, cInfs);
748
LPCWSTR const apwszInfs[] = { wszPtInf, wszMpInf };
749
HRESULT hr = VBoxNetCfgWinNetFltInstall(pNetCfg, &apwszInfs[0], RT_ELEMENTS(apwszInfs));
753
LogStringW(hModule, TEXT("InstallNetFlt: VBoxNetCfgWinNetFltInstall failed, error = 0x%x"), hr);
751
logStringW(hModule, L"InstallNetFlt: VBoxNetCfgWinNetFltInstall failed, error = 0x%x", hr);
755
uErr = ErrorConvertFromHResult(hModule, hr);
753
uErr = errorConvertFromHResult(hModule, hr);
758
LogStringW(hModule, TEXT("InstallNetFlt: vboxNetFltQueryInfArray failed, error = 0x%x"), uErr);
756
logStringW(hModule, L"InstallNetFlt: vboxNetFltQueryInfArray failed, error = 0x%x", uErr);
760
758
VBoxNetCfgWinReleaseINetCfg(pNetCfg, TRUE);
762
LogStringW(hModule, TEXT("Installing NetFlt done"));
760
logStringW(hModule, L"Installing NetFlt done");
765
LogStringW(hModule, TEXT("InstallNetFlt: doNetCfgInit failed, error = 0x%x"), uErr);
763
logStringW(hModule, L"InstallNetFlt: doNetCfgInit failed, error = 0x%x", uErr);
845
843
BOOL bSetupModeInteractive = SetupSetNonInteractiveMode(FALSE);
846
844
bool bSetStaticIp = true;
848
LogStringW(hModule, TEXT("Creating host-only interface"));
846
logStringW(hModule, L"Creating host-only interface");
850
848
HRESULT hr = VBoxNetCfgWinRemoveAllNetDevicesOfId(NETADP_ID);
853
LogStringW(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinRemoveAllNetDevicesOfId failed, error = 0x%x"), hr);
851
logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinRemoveAllNetDevicesOfId failed, error = 0x%x", hr);
854
852
bSetStaticIp = false;
858
WCHAR MpInf[MAX_PATH];
859
DWORD cSize = sizeof(MpInf)/sizeof(MpInf[0]);
860
LPCWSTR pInfPath = NULL;
856
WCHAR wszMpInf[MAX_PATH];
857
DWORD cchMpInf = RT_ELEMENTS(wszMpInf) - sizeof("drivers\\network\\netadp\\VBoxNetAdp.inf") - 1;
858
LPCWSTR pwszInfPath = NULL;
861
859
bool bIsFile = false;
862
UINT uErr = MsiGetPropertyW(hModule, L"CustomActionData", MpInf, &cSize);
860
UINT uErr = MsiGetPropertyW(hModule, L"CustomActionData", wszMpInf, &cchMpInf);
863
861
if (uErr == ERROR_SUCCESS)
867
LogStringW(hModule, TEXT("CreateHostOnlyInterface: NetAdpDir property = %s"), MpInf);
868
if (MpInf[cSize-1] != L'\\')
865
logStringW(hModule, L"CreateHostOnlyInterface: NetAdpDir property = %s", wszMpInf);
866
if (wszMpInf[cchMpInf - 1] != L'\\')
870
MpInf[cSize] = L'\\';
872
MpInf[cSize] = L'\0';
868
wszMpInf[cchMpInf++] = L'\\';
869
wszMpInf[cchMpInf] = L'\0';
875
/** @todo r=andy Avoid wcscat, can cause buffer overruns! */
876
wcscat(MpInf, L"drivers\\network\\netadp\\VBoxNetAdp.inf");
872
wcscat(wszMpInf, L"drivers\\network\\netadp\\VBoxNetAdp.inf");
873
pwszInfPath = wszMpInf;
880
LogStringW(hModule, TEXT("CreateHostOnlyInterface: Resulting INF path = %s"), pInfPath);
876
logStringW(hModule, L"CreateHostOnlyInterface: Resulting INF path = %s", pwszInfPath);
883
LogStringW(hModule, TEXT("CreateHostOnlyInterface: NetAdpDir property value is empty"));
879
logStringW(hModule, L"CreateHostOnlyInterface: NetAdpDir property value is empty");
886
LogStringW(hModule, TEXT("CreateHostOnlyInterface: Failed to get NetAdpDir property, error = 0x%x"), uErr);
882
logStringW(hModule, L"CreateHostOnlyInterface: Failed to get NetAdpDir property, error = 0x%x", uErr);
888
884
/* Make sure the inf file is installed. */
889
if (!!pInfPath && bIsFile)
885
if (pwszInfPath != NULL && bIsFile)
891
hr = VBoxDrvCfgInfInstall(pInfPath);
887
logStringW(hModule, L"CreateHostOnlyInterface: Calling VBoxDrvCfgInfInstall(%s)", pwszInfPath);
888
hr = VBoxDrvCfgInfInstall(pwszInfPath);
889
logStringW(hModule, L"CreateHostOnlyInterface: VBoxDrvCfgInfInstall returns 0x%x", hr);
893
LogStringW(hModule, TEXT("CreateHostOnlyInterface: Failed to install INF file, error = 0x%x"), hr);
891
logStringW(hModule, L"CreateHostOnlyInterface: Failed to install INF file, error = 0x%x", hr);
896
894
if (SUCCEEDED(hr))
898
hr = VBoxNetCfgWinCreateHostOnlyNetworkInterface(pInfPath, bIsFile, &guid, NULL, NULL);
896
logStringW(hModule, L"CreateHostOnlyInterface: calling VBoxNetCfgWinCreateHostOnlyNetworkInterface");
897
hr = VBoxNetCfgWinCreateHostOnlyNetworkInterface(pwszInfPath, bIsFile, &guid, NULL, NULL);
898
logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinCreateHostOnlyNetworkInterface returns 0x%x", hr);
899
899
if (SUCCEEDED(hr))
901
901
ULONG ip = inet_addr("192.168.56.1");
902
902
ULONG mask = inet_addr("255.255.255.0");
903
logStringW(hModule, L"CreateHostOnlyInterface: calling VBoxNetCfgWinEnableStaticIpConfig");
903
904
hr = VBoxNetCfgWinEnableStaticIpConfig(&guid, ip, mask);
905
logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinEnableStaticIpConfig returns 0x%x", hr);
905
LogStringW(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinEnableStaticIpConfig failed, error = 0x%x"), hr);
907
logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinEnableStaticIpConfig failed, error = 0x%x", hr);
908
LogStringW(hModule, TEXT("CreateHostOnlyInterface: VBoxNetCfgWinCreateHostOnlyNetworkInterface failed, error = 0x%x"), hr);
910
logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinCreateHostOnlyNetworkInterface failed, error = 0x%x", hr);
911
913
if (SUCCEEDED(hr))
912
LogStringW(hModule, TEXT("Creating host-only interface done"));
914
logStringW(hModule, L"Creating host-only interface done");
914
916
/* Restore original setup mode. */
917
logStringW(hModule, L"CreateHostOnlyInterface: almost done...");
915
918
if (bSetupModeInteractive)
916
919
SetupSetNonInteractiveMode(bSetupModeInteractive);
955
959
return ERROR_SUCCESS;
958
static bool IsTAPDevice(const TCHAR *pcGUID)
962
static bool isTAPDevice(const WCHAR *pwszGUID)
961
965
bool bIsTapDevice = false;
962
LONG lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
963
TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
964
0, KEY_READ, &hNetcard);
966
LONG lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
967
L"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
968
0, KEY_READ, &hNetcard);
965
969
if (lStatus != ERROR_SUCCESS)
971
TCHAR szEnumName[256];
972
TCHAR szNetCfgInstanceId[256];
975
WCHAR wszEnumName[256];
976
WCHAR wszNetCfgInstanceId[256];
974
978
HKEY hNetCardGUID;
976
DWORD dwLen = sizeof(szEnumName);
977
lStatus = RegEnumKeyEx(hNetcard, i, szEnumName, &dwLen, NULL, NULL, NULL, NULL);
980
DWORD dwLen = sizeof(wszEnumName);
981
lStatus = RegEnumKeyExW(hNetcard, i, wszEnumName, &dwLen, NULL, NULL, NULL, NULL);
978
982
if (lStatus != ERROR_SUCCESS)
981
lStatus = RegOpenKeyEx(hNetcard, szEnumName, 0, KEY_READ, &hNetCardGUID);
985
lStatus = RegOpenKeyExW(hNetcard, wszEnumName, 0, KEY_READ, &hNetCardGUID);
982
986
if (lStatus == ERROR_SUCCESS)
984
dwLen = sizeof(szNetCfgInstanceId);
985
lStatus = RegQueryValueEx(hNetCardGUID, TEXT("NetCfgInstanceId"), NULL, &dwKeyType, (LPBYTE)szNetCfgInstanceId, &dwLen);
988
dwLen = sizeof(wszNetCfgInstanceId);
989
lStatus = RegQueryValueExW(hNetCardGUID, L"NetCfgInstanceId", NULL, &dwKeyType, (LPBYTE)wszNetCfgInstanceId, &dwLen);
986
990
if ( lStatus == ERROR_SUCCESS
987
991
&& dwKeyType == REG_SZ)
989
TCHAR szNetProductName[256];
990
TCHAR szNetProviderName[256];
992
szNetProductName[0] = 0;
993
dwLen = sizeof(szNetProductName);
994
lStatus = RegQueryValueEx(hNetCardGUID, TEXT("ProductName"), NULL, &dwKeyType, (LPBYTE)szNetProductName, &dwLen);
996
szNetProviderName[0] = 0;
997
dwLen = sizeof(szNetProviderName);
998
lStatus = RegQueryValueEx(hNetCardGUID, TEXT("ProviderName"), NULL, &dwKeyType, (LPBYTE)szNetProviderName, &dwLen);
1000
if ( !wcscmp(szNetCfgInstanceId, pcGUID)
1001
&& !wcscmp(szNetProductName, TEXT("VirtualBox TAP Adapter"))
1002
&& ( (!wcscmp(szNetProviderName, TEXT("innotek GmbH"))) /* Legacy stuff. */
1003
|| (!wcscmp(szNetProviderName, TEXT("Sun Microsystems, Inc."))) /* Legacy stuff. */
1004
|| (!wcscmp(szNetProviderName, TEXT(VBOX_VENDOR))) /* Reflects current vendor string. */
993
WCHAR wszNetProductName[256];
994
WCHAR wszNetProviderName[256];
996
wszNetProductName[0] = 0;
997
dwLen = sizeof(wszNetProductName);
998
lStatus = RegQueryValueExW(hNetCardGUID, L"ProductName", NULL, &dwKeyType, (LPBYTE)wszNetProductName, &dwLen);
1000
wszNetProviderName[0] = 0;
1001
dwLen = sizeof(wszNetProviderName);
1002
lStatus = RegQueryValueExW(hNetCardGUID, L"ProviderName", NULL, &dwKeyType, (LPBYTE)wszNetProviderName, &dwLen);
1004
if ( !wcscmp(wszNetCfgInstanceId, pwszGUID)
1005
&& !wcscmp(wszNetProductName, L"VirtualBox TAP Adapter")
1006
&& ( (!wcscmp(wszNetProviderName, L"innotek GmbH")) /* Legacy stuff. */
1007
|| (!wcscmp(wszNetProviderName, L"Sun Microsystems, Inc.")) /* Legacy stuff. */
1008
|| (!wcscmp(wszNetProviderName, MY_WTEXT(VBOX_VENDOR))) /* Reflects current vendor string. */
1018
RegCloseKey (hNetcard);
1022
RegCloseKey(hNetcard);
1019
1023
return bIsTapDevice;
1022
#define VBOX_TAP_HWID _T("vboxtap")
1024
1026
#define SetErrBreak(strAndArgs) \
1027
LogStringW(hModule, strAndArgs); \
1029
logStringW(hModule, strAndArgs); \
1029
1031
} else do {} while (0)
1031
int removeNetworkInterface(MSIHANDLE hModule, const TCHAR* pcGUID)
1033
int removeNetworkInterface(MSIHANDLE hModule, const WCHAR *pwszGUID)
1036
TCHAR lszPnPInstanceId [512] = {0};
1038
WCHAR wszPnPInstanceId[512] = {0};
1038
1040
/* We have to find the device instance ID through a registry search */
1040
1042
HKEY hkeyNetwork = 0;
1041
1043
HKEY hkeyConnection = 0;
1045
TCHAR strRegLocation [256];
1046
swprintf (strRegLocation,
1047
TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\")
1048
TEXT("{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s"),
1051
lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strRegLocation, 0,
1052
KEY_READ, &hkeyNetwork);
1047
WCHAR wszRegLocation[256];
1048
swprintf(wszRegLocation,
1049
L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s",
1051
LONG lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszRegLocation, 0, KEY_READ, &hkeyNetwork);
1053
1052
if ((lStatus != ERROR_SUCCESS) || !hkeyNetwork)
1054
SetErrBreak((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [1]"), strRegLocation));
1053
SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [1]", wszRegLocation));
1056
lStatus = RegOpenKeyExA(hkeyNetwork, "Connection", 0,
1057
KEY_READ, &hkeyConnection);
1055
lStatus = RegOpenKeyExW(hkeyNetwork, L"Connection", 0, KEY_READ, &hkeyConnection);
1058
1056
if ((lStatus != ERROR_SUCCESS) || !hkeyConnection)
1059
SetErrBreak((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [2]"), strRegLocation));
1057
SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [2]", wszRegLocation));
1061
DWORD len = sizeof (lszPnPInstanceId);
1059
DWORD len = sizeof(wszPnPInstanceId);
1062
1060
DWORD dwKeyType;
1063
1061
lStatus = RegQueryValueExW(hkeyConnection, L"PnPInstanceID", NULL,
1064
&dwKeyType, (LPBYTE) lszPnPInstanceId, &len);
1062
&dwKeyType, (LPBYTE)&wszPnPInstanceId[0], &len);
1065
1063
if ((lStatus != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
1066
SetErrBreak((TEXT("VBox HostInterfaces: Host interface network was not found in registry (%s)! [3]"), strRegLocation));
1064
SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [3]", wszRegLocation));
1228
1226
UINT __stdcall UninstallTAPInstances(MSIHANDLE hModule)
1230
static const TCHAR *NetworkKey = TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\")
1231
TEXT("{4D36E972-E325-11CE-BFC1-08002BE10318}");
1228
static const WCHAR *s_wszNetworkKey = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}";
1234
LONG lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NetworkKey, 0, KEY_READ, &hCtrlNet);
1231
LONG lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_wszNetworkKey, 0, KEY_READ, &hCtrlNet);
1235
1232
if (lStatus == ERROR_SUCCESS)
1237
LogStringW(hModule, TEXT("VBox HostInterfaces: Enumerating interfaces ..."));
1238
for (int i = 0;; ++ i)
1234
logStringW(hModule, L"VBox HostInterfaces: Enumerating interfaces ...");
1235
for (int i = 0; ; ++i)
1240
TCHAR szNetworkGUID [256] = { 0 };
1241
TCHAR szNetworkConnection [256] = { 0 };
1243
DWORD dwLen = (DWORD)sizeof(szNetworkGUID);
1244
lStatus = RegEnumKeyEx(hCtrlNet, i, szNetworkGUID, &dwLen, NULL, NULL, NULL, NULL);
1237
WCHAR wszNetworkGUID[256] = { 0 };
1238
DWORD dwLen = (DWORD)sizeof(wszNetworkGUID);
1239
lStatus = RegEnumKeyExW(hCtrlNet, i, wszNetworkGUID, &dwLen, NULL, NULL, NULL, NULL);
1245
1240
if (lStatus != ERROR_SUCCESS)
1247
1242
switch (lStatus)
1249
case ERROR_NO_MORE_ITEMS:
1250
LogStringW(hModule, TEXT("VBox HostInterfaces: No interfaces found."));
1253
LogStringW(hModule, TEXT("VBox HostInterfaces: Enumeration failed: %ld"), lStatus);
1244
case ERROR_NO_MORE_ITEMS:
1245
logStringW(hModule, L"VBox HostInterfaces: No interfaces found.");
1248
logStringW(hModule, L"VBox HostInterfaces: Enumeration failed: %ld", lStatus);
1259
if (IsTAPDevice(szNetworkGUID))
1254
if (isTAPDevice(wszNetworkGUID))
1261
LogStringW(hModule, TEXT("VBox HostInterfaces: Removing interface \"%s\" ..."), szNetworkGUID);
1262
removeNetworkInterface (hModule, szNetworkGUID);
1263
lStatus = RegDeleteKey (hCtrlNet, szNetworkGUID);
1256
logStringW(hModule, L"VBox HostInterfaces: Removing interface \"%s\" ...", wszNetworkGUID);
1257
removeNetworkInterface(hModule, wszNetworkGUID);
1258
lStatus = RegDeleteKeyW(hCtrlNet, wszNetworkGUID);
1266
RegCloseKey (hCtrlNet);
1267
LogStringW(hModule, TEXT("VBox HostInterfaces: Removing interfaces done."));
1261
RegCloseKey(hCtrlNet);
1262
logStringW(hModule, L"VBox HostInterfaces: Removing interfaces done.");
1269
1264
return ERROR_SUCCESS;