if (found == FALSE)
{
ret = GetLastError();
- printf("The %s does not seem to be installed\n", DRIVER_DESC);
+ ReportMessage(0,"Driver does not seem to be installed", DRIVER_DESC, NULL, ret);
goto cleanup;
}
BOOL found = FALSE;
BOOL registered = FALSE;
BOOL destroyList = FALSE;
+ PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
+ DWORD detailBuf[2048]; // for our purposes, 8k buffer is more
+ // than enough to obtain the hardware ID
+ // of the loopback driver.
HKEY hkey = NULL;
DWORD cbSize;
destroyList = TRUE;
// enumerate the driver info list
- while (SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData,
- SPDIT_CLASSDRIVER, index, &DriverInfoData))
+ while (TRUE)
{
- // if the manufacture is microsoft
- if (_tcsicmp(DriverInfoData.MfgName, MANUFACTURE) == 0)
- {
- // case insensitive search for loopback
- _tcscpy(temp, DriverInfoData.Description);
- _tcslwr(temp);
- if( _tcsstr(temp, DRIVER))
- {
- found = TRUE;
- break;
- }
- }
+ BOOL ret;
+
+ ret = SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData,
+ SPDIT_CLASSDRIVER, index, &DriverInfoData);
+
+ // if the function failed and GetLastError() returned
+ // ERROR_NO_MORE_ITEMS, then we have reached the end of the
+ // list. Othewise there was something wrong with this
+ // particular driver.
+ if(!ret) {
+ if(GetLastError() == ERROR_NO_MORE_ITEMS)
+ break;
+ else {
+ index++;
+ continue;
+ }
+ }
+
+ pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
+ pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
+
+ // if we successfully find the hardware ID and it turns out to
+ // be the one for the loopback driver, then we are done.
+ if(SetupDiGetDriverInfoDetail(hDeviceInfo,
+ &DeviceInfoData,
+ &DriverInfoData,
+ pDriverInfoDetail,
+ sizeof(detailBuf),
+ NULL) &&
+ !_tcsicmp(pDriverInfoDetail->HardwareID, DRIVERHWID)) {
+
+ found = TRUE;
+ break;
+ }
+
index++;
}
if (!found)
{
ret = GetLastError();
- printf("Could not find the %s driver to install\n", DRIVER_DESC);
+ ReportMessage(0,"Could not find the driver to install", DRIVER_DESC, NULL, 0);
goto cleanup;
}
ret = RenameConnection(pCfgGuidString, pConnectionName);
if (ret)
{
- printf("Could not set the connection name to \"%S\"\n",
- pConnectionName);
+ ReportMessage(0,"Could not set the connection name", NULL, pConnectionName, 0);
goto cleanup;
}
ret = SetIpAddress(pCfgGuidString, ip, mask);
if (ret)
{
- printf("Could not set the ip address and network mask\n");
+ ReportMessage(0,"Could not set the ip address and network mask",NULL,NULL,0);
goto cleanup;
}
ret = LoopbackBindings(pCfgGuidString);
if (ret)
{
- printf("Could not properly set the bindings\n");
+ ReportMessage(0,"Could not properly set the bindings",NULL,NULL,0);
goto cleanup;
}
ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE );
if (ret)
{
- printf("Could not update hosts file\n");
+ ReportMessage(0,"Could not update hosts file",NULL,NULL,0);
goto cleanup;
}
ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE );
if (ret)
{
- printf("Could not update lmhosts file\n");
+ ReportMessage(0,"Could not update lmhosts file",NULL,NULL,0);
goto cleanup;
}
L"loopback_install", MB_ICONINFORMATION | MB_OK );
}
-static int process_args (LPWSTR lpCmdLine, Args & args) {
+static int process_args (LPWSTR lpCmdLine, int skip, Args & args) {
int i, iNumArgs;
LPWSTR * argvW;
argvW = CommandLineToArgvW (lpCmdLine, &iNumArgs);
- for (i = 0; i < iNumArgs; i++)
+ // Skip over the command name
+ for (i = skip; i < iNumArgs; i++)
{
if (wcsstr (argvW[i], L"help")
|| !_wcsicmp (argvW[i], L"?")
wcsMallocAndCpy (&args.lpSubnetMask, DEFAULT_MASK);
GlobalFree (argvW);
+
return 1;
}
{
Args args;
- if (!process_args(lpCmdLine, args))
+ if (!process_args(lpCmdLine, 0, args))
return;
InstallLoopBack(args.lpConnectionName, args.lpIPAddr, args.lpSubnetMask);
Args args;
UINT rc;
+ SetMsiReporter("InstallLoopback", "Installing loopback adapter", hInstall);
+
+ /* check if there is already one installed. If there is, we shouldn't try to
+ * install another.
+ */
+ if(IsLoopbackInstalled())
+ return ERROR_SUCCESS;
+
szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR));
while (rc = MsiGetPropertyW(hInstall, L"CustomActionData", szValueBuf, &cbValueBuf)) {
free (szValueBuf);
return ERROR_INSTALL_FAILURE;
}
- if (!process_args(szValueBuf, args))
+ if (!process_args(szValueBuf, 1, args))
return ERROR_INSTALL_FAILURE;
rc = InstallLoopBack (args.lpConnectionName, args.lpIPAddr, args.lpSubnetMask);
+ if (rc != 2 && rc != 0)
+ return ERROR_INSTALL_FAILURE;
+
+ if (rc == 2) {
+ MsiDoActionW (hInstall, L"ScheduleReboot");
+ }
+
+ return ERROR_SUCCESS;
+}
+
+UINT __stdcall uninstallLoopbackMSI (MSIHANDLE hInstall)
+{
+ LPWSTR szValueBuf;
+ DWORD cbValueBuf = 256;
+ Args args;
+ UINT rc;
+
+ SetMsiReporter("RemoveLoopback", "Removing loopback adapter", hInstall);
+
+ szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR));
+ while (rc = MsiGetPropertyW(hInstall, L"CustomActionData", szValueBuf, &cbValueBuf)) {
+ free (szValueBuf);
+ if (rc == ERROR_MORE_DATA) {
+ cbValueBuf++;
+ szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR));
+ }
+ else
+ return ERROR_INSTALL_FAILURE;
+ }
+
+ if (!process_args(szValueBuf, 1, args))
+ return ERROR_INSTALL_FAILURE;
+
+ rc = UnInstallLoopBack ();
+
if (rc == 1)
return ERROR_INSTALL_FAILURE;
return ERROR_SUCCESS;
}
+DWORD hMsiHandle = 0;
+DWORD dwReporterType = REPORT_PRINTF;
+
+extern "C" void ReportMessage(int level, LPCSTR msg, LPCSTR str, LPCWSTR wstr, DWORD dw) {
+ if(dwReporterType == REPORT_PRINTF)
+ printf("%s:[%s][%S][%d]\n", (msg?msg:""), (str?str:""), (wstr?wstr:L""), dw);
+ else if(dwReporterType == REPORT_MSI && hMsiHandle && level == 0) {
+ MSIHANDLE hRec = MsiCreateRecord(5);
+
+ MsiRecordClearData(hRec);
+ MsiRecordSetStringA(hRec,1,(msg)?msg:"");
+ MsiRecordSetStringA(hRec,2,(str)?str:"");
+ MsiRecordSetStringW(hRec,3,(wstr)?wstr:L"");
+ MsiRecordSetInteger(hRec,4,dw);
+
+ MsiProcessMessage(hMsiHandle,INSTALLMESSAGE_ACTIONDATA,hRec);
+
+ MsiCloseHandle(hRec);
+ }
+}
+
+extern "C" void SetMsiReporter(LPCSTR strAction, LPCSTR strDesc,DWORD h) {
+ dwReporterType = REPORT_MSI;
+ hMsiHandle = h;
+
+#ifdef DONT_NEED
+ /* this is performed in the Wix installer */
+ MSIHANDLE hRec = MsiCreateRecord(4);
+
+ MsiRecordClearData(hRec);
+ MsiRecordSetStringA(hRec,1,strAction);
+ MsiRecordSetStringA(hRec,2,strDesc);
+ MsiRecordSetStringA(hRec,3,"[1]:([2])([3])([4])");
+
+ MsiProcessMessage(h,INSTALLMESSAGE_ACTIONSTART, hRec);
+
+ MsiCloseHandle(hRec);
+#endif
+}