DWORD findPlexLocation(WCHAR* szPlexLocation, DWORD *sizeBuff) { UINT uiStatus = ERROR_SUCCESS; DWORD dwIndex = 0; WCHAR wszAssignmentType[10] = {0}; WCHAR wszProductCode[cchGUID+1] = {0}; WCHAR szSid[128] = L"s-1-1-0"; DWORD cchSid; DWORD cchAssignmentType = sizeof(wszAssignmentType)/sizeof(wszAssignmentType[0]); DWORD cchProductName = MAX_PATH; WCHAR* lpProductName = new WCHAR[cchProductName]; MSIINSTALLCONTEXT dwInstalledContext; bool foundPlex = false; do { uiStatus = MsiEnumProductsEx(NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE, dwIndex, wszProductCode, &dwInstalledContext, szSid, &cchSid); if(ERROR_SUCCESS == uiStatus) { // obtain the user friendly name of the product UINT uiReturn = MsiGetProductInfo(wszProductCode,INSTALLPROPERTY_PRODUCTNAME,lpProductName,&cchProductName); if (ERROR_MORE_DATA == uiReturn) { // try again, but with a larger product name buffer delete [] lpProductName; // returned character count does not include // terminating NULL ++cchProductName; lpProductName = new WCHAR[cchProductName]; if (!lpProductName) { uiStatus = ERROR_OUTOFMEMORY; break; } uiReturn = MsiGetProductInfo(wszProductCode,INSTALLPROPERTY_PRODUCTNAME,lpProductName,&cchProductName); } if (ERROR_SUCCESS != uiReturn) { // This halts the enumeration and fails. Alternatively the error // could be logged and enumeration continued for the // remainder of the products uiStatus = ERROR_FUNCTION_FAILED; break; } if(wcscmp(lpProductName, L"Plex Media Server") == 0) { // output information wprintf(L" Product %s:\n", lpProductName); //Enumerate All Components DWORD dwComponentIdx = 0; DWORD dwClientIdx = 0; DWORD maxPath = MAX_PATH; WCHAR lpComponentCode[cchGUID+1] = {0}; WCHAR* lpClientName = new WCHAR[cchGUID+1]; WCHAR* lpComponentPath = new WCHAR[maxPath]; WCHAR* lpComponentSubPath; do { uiStatus = MsiEnumComponents(dwComponentIdx, lpComponentCode); UINT clientStatus = ERROR_SUCCESS; UINT pathStatus = ERROR_SUCCESS; //For each component, enumerate the clients do { clientStatus = MsiEnumClients(lpComponentCode, dwClientIdx, lpClientName); //Only get the path if a matching client is found if(clientStatus == ERROR_SUCCESS && 0 == wcscmp(lpClientName, wszProductCode)) { maxPath = MAX_PATH; pathStatus = MsiGetComponentPath(wszProductCode, lpComponentCode, lpComponentPath, &maxPath); if(pathStatus == INSTALLSTATE_LOCAL && wcslen(lpComponentPath) > 0) { //We need to compare the end string to ensure it matches the name of the app //This just does some pointer arithmetic lpComponentSubPath = lpComponentPath + maxPath - APP_NAME_LEN; if(0 == wcscmp(APP_NAME, lpComponentSubPath)) { foundPlex = true; wcscpy_s(szPlexLocation, *sizeBuff, lpComponentPath); } } } dwClientIdx++; }while(ERROR_SUCCESS == clientStatus && !foundPlex); dwClientIdx = 0; dwComponentIdx++; }while(ERROR_SUCCESS == uiStatus && !foundPlex); delete [] lpClientName; delete [] lpComponentPath; lpClientName = lpComponentPath = lpComponentSubPath = NULL; cchProductName = MAX_PATH; } } dwIndex++; } while (ERROR_SUCCESS == uiStatus && !foundPlex); if (lpProductName) { delete [] lpProductName; lpProductName = NULL; } if(foundPlex && szPlexLocation) { *sizeBuff = (DWORD)wcslen(szPlexLocation); return TRUE; } return FALSE; }
UINT __stdcall ingres_set_odbc_reg_entries (MSIHANDLE ihnd) { HKEY hKey, hKey2; char KeyName[256], KeyNameODBC[256]; int status = 0; DWORD dwSize, dwDisposition, dwType; TCHAR tchValue[2048]; INSTALLSTATE iInstalled, iAction; BOOL ODBC_Installed = FALSE; BOOL bInstalled, bVer25, bVersion9X; char szCode[3], szComponent[39], szProduct[39]; ODBC_Installed = FALSE; bInstalled=bVer25=bVersion9X=FALSE; if (!MsiGetComponentState(ihnd, "Bin.70DC58B6_2D77_11D5_BDFC_00B0D0AD4485", &iInstalled, &iAction)) { if (iInstalled==INSTALLSTATE_ABSENT && iAction==INSTALLSTATE_UNKNOWN) return ERROR_SUCCESS; } else return ERROR_SUCCESS; dwSize = sizeof(tchValue); if (MsiGetProperty( ihnd, "II_INSTALLATION", tchValue, &dwSize ) != ERROR_SUCCESS) { return (ERROR_INSTALL_FAILURE); } else { strcpy(szCode, tchValue); sprintf(KeyName, "Software\\IngresCorporation\\Ingres\\%s_Installation", tchValue); status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); } dwSize = sizeof(szProduct); MsiGetProperty(ihnd, "ProductCode", szProduct, &dwSize); if (!_stricmp(szCode, "II")) strcpy(szComponent, "{8FA72934-D481-405A-AD90-B7BDE7988247}"); else { int idx; idx = (toupper(szCode[0]) - 'A') * 26 + toupper(szCode[1]) - 'A'; if (idx <= 0) idx = (toupper(szCode[0]) - 'A') * 26 + toupper(szCode[1]) - '0'; sprintf(szComponent, "{8FA72934-D481-405A-%04X-%012X}", idx, idx*idx); } dwSize=sizeof(tchValue); MsiGetComponentPath(szProduct, szComponent, tchValue, &dwSize); if (tchValue[0] && iInstalled==INSTALLSTATE_LOCAL) ODBC_Installed = TRUE; if (ODBC_Installed) { /* ** Set up the InstalledFeatures registry key for possible use. */ dwType = REG_SZ; dwSize = sizeof(tchValue); if (RegQueryValueEx(hKey, "InstalledFeatures", NULL, &dwType, tchValue, &dwSize) != ERROR_SUCCESS) { strcpy(tchValue, "ODBC"); } else strcat(tchValue, ",ODBC"); status = RegSetValueEx( hKey, "InstalledFeatures", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); } if (iAction==INSTALLSTATE_ABSENT) { /* ** Set up the RemovedFeatures registry key for use later on. */ dwType = REG_SZ; dwSize = sizeof(tchValue); if (RegQueryValueEx(hKey, "RemovedFeatures", NULL, &dwType, tchValue, &dwSize) != ERROR_SUCCESS) { strcpy(tchValue, "ODBC"); } else strcat(tchValue, ",ODBC"); status = RegSetValueEx( hKey, "RemovedFeatures", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); RegCloseKey(hKey); return (status==ERROR_SUCCESS ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE); } else if (ODBC_Installed || iAction!=INSTALLSTATE_LOCAL) { dwSize = sizeof(tchValue); if (!MsiGetProperty(ihnd, "INGRES_UPGRADE", tchValue, &dwSize) && strcmp(tchValue, "2")) { RegCloseKey(hKey); return (ERROR_SUCCESS); } } dwSize = sizeof(tchValue); if (status || MsiGetProperty( ihnd, "INGRES_ODBC", tchValue, &dwSize ) != ERROR_SUCCESS) { return (ERROR_INSTALL_FAILURE); } else { status = RegSetValueEx( hKey, "setup_ingresodbc", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); } dwSize = sizeof(tchValue); if (status || MsiGetProperty( ihnd, "INGRES_ODBC_READONLY", tchValue, &dwSize ) != ERROR_SUCCESS) { return (ERROR_INSTALL_FAILURE); } else { status = RegSetValueEx( hKey, "setup_ingresodbcreadonly", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); } //check if read-only odbc driver was installed by ODBC patch installer if ((!strcmp(tchValue, "") || !strcmp(tchValue, "0")) && ODBC_Installed && iAction==INSTALLSTATE_LOCAL) { sprintf(KeyNameODBC, "SOFTWARE\\ODBC\\ODBCINST.INI\\Ingres"); if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyNameODBC, 0, KEY_QUERY_VALUE, &hKey2)) { /* the comment out part is a better way of doing the check but Ingres isn't ready for it ** b/c of older releases DriverReadOnly can't be trusted yet. */ /*dwSize=sizeof(tchValue); if ((status = RegQueryValueEx(hKey2, "DriverReadOnly", 0, NULL, (BYTE *)tchValue, &dwSize)) == ERROR_SUCCESS) { if (!strcmp(tchValue, "Y")) status = RegSetValueEx( hKey, "setup_ingresodbcreadonly", 0, REG_SZ, "1", strlen("1") + 1 ); } else if (status == ERROR_FILE_NOT_FOUND) {*/ dwSize=sizeof(tchValue); if (!RegQueryValueEx(hKey2, "Driver", 0, NULL, (BYTE *)tchValue, &dwSize)) { if (strstr(tchValue, "caiiro") > 0) { status = RegSetValueEx( hKey, "setup_ingresodbcreadonly", 0, REG_SZ, "1", strlen("1") + 1 ); //Update the property for future possible upgrades of the release MsiSetProperty( ihnd, "INGRES_ODBC_READONLY", "1" ); } } //} RegCloseKey(hKey2); } } strcpy(tchValue, "TRUE"); status = RegSetValueEx( hKey, "Ingres ODBC Driver", 0, REG_SZ, (CONST BYTE *)&tchValue, strlen(tchValue) + 1 ); dwType = REG_SZ; dwSize = sizeof(tchValue); if (RegQueryValueEx(hKey, "PostInstallationNeeded", NULL, &dwType, tchValue, &dwSize) != ERROR_SUCCESS) { dwSize = sizeof(tchValue); if (status || MsiGetProperty( ihnd, "INGRES_SERVICEAUTO", tchValue, &dwSize ) != ERROR_SUCCESS) { return (ERROR_INSTALL_FAILURE); } else { char szBuf[MAX_PATH+1]; sprintf(szBuf, "Ingres_Database_%s", szCode); if (CheckServiceExists(szBuf)) { if (IsServiceStartupTypeAuto(szBuf)) sprintf(tchValue, "1"); else sprintf(tchValue, "0"); status = RegSetValueEx( hKey, "serviceauto", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); } else status = RegSetValueEx( hKey, "serviceauto", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); } dwSize = sizeof(tchValue); if (status || MsiGetProperty( ihnd, "INGRES_SERVICELOGINID", tchValue, &dwSize ) != ERROR_SUCCESS) { return (ERROR_INSTALL_FAILURE); } else { status = RegSetValueEx( hKey, "serviceloginid", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); } dwSize = sizeof(tchValue); if (status || MsiGetProperty( ihnd, "INGRES_SERVICEPASSWORD", tchValue, &dwSize ) != ERROR_SUCCESS) { return (ERROR_INSTALL_FAILURE); } else { /* Clear the password from the property table. */ MsiSetProperty(ihnd, "INGRES_SERVICEPASSWORD", ""); MsiSetProperty(ihnd, "INGRES_SERVICEPASSWORD2", ""); status = RegSetValueEx( hKey, "servicepassword", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); } strcpy(tchValue, "YES"); status = RegSetValueEx( hKey, "PostInstallationNeeded", 0, REG_SZ, tchValue, strlen(tchValue) + 1 ); MsiSetProperty(ihnd, "INGRES_POSTINSTALLATIONNEEDED", "1"); dwSize = sizeof(tchValue); MsiGetProperty(ihnd, "INGRES_RSP_LOC", tchValue, &dwSize); if (tchValue[0] && strcmp(tchValue, "0")) { strcpy(tchValue, "YES"); RegSetValueEx( hKey, "SilentInstall", 0, REG_SZ, (CONST BYTE *)&tchValue, strlen(tchValue) + 1 ); } dwSize = sizeof(tchValue); MsiGetProperty(ihnd, "Installed", tchValue, &dwSize); if (tchValue[0]) bInstalled=TRUE; dwSize = sizeof(tchValue); MsiGetProperty(ihnd, "INGRES_VER25", tchValue, &dwSize); if (tchValue[0] && !strcmp(tchValue, "1")) bVer25=0; dwSize=sizeof(tchValue); MsiGetProperty(ihnd, "Version9X", tchValue, &dwSize); if (tchValue[0]) bVersion9X=TRUE; if (!bInstalled && !bVer25 && bVersion9X) { strcpy(tchValue, "YES"); RegSetValueEx( hKey, "RebootNeeded", 0, REG_SZ, (CONST BYTE *)&tchValue, strlen(tchValue) + 1 ); } } return (status == ERROR_SUCCESS ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE); }