ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

upgrade.c
Go to the documentation of this file.
00001 /*
00002  * Implementation of the Microsoft Installer (msi.dll)
00003  *
00004  * Copyright 2005 Aric Stewart for CodeWeavers
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 /*
00022  * Actions focused on in this module
00023  *
00024  * FindRelatedProducts
00025  * MigrateFeatureStates (TODO)
00026  * RemoveExistingProducts (TODO)
00027  */
00028 
00029 #include <stdarg.h>
00030 
00031 #include "windef.h"
00032 #include "winbase.h"
00033 #include "winerror.h"
00034 #include "winreg.h"
00035 #include "wine/debug.h"
00036 #include "msidefs.h"
00037 #include "msipriv.h"
00038 #include "winuser.h"
00039 #include "wine/unicode.h"
00040 
00041 WINE_DEFAULT_DEBUG_CHANNEL(msi);
00042 
00043 static BOOL check_language(DWORD lang1, LPCWSTR lang2, DWORD attributes)
00044 {
00045     DWORD langdword;
00046 
00047     if (!lang2 || lang2[0]==0)
00048         return TRUE;
00049 
00050     langdword = atoiW(lang2);
00051 
00052     if (attributes & msidbUpgradeAttributesLanguagesExclusive)
00053         return (lang1 != langdword);
00054     else
00055         return (lang1 == langdword);
00056 }
00057 
00058 static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property,
00059                                LPCWSTR productid)
00060 {
00061     LPWSTR prop;
00062     LPWSTR newprop;
00063     DWORD len;
00064     UINT r;
00065 
00066     prop = msi_dup_property(package->db, action_property );
00067     if (prop)
00068         len = strlenW(prop);
00069     else
00070         len = 0;
00071 
00072     /*separator*/
00073     len ++;
00074 
00075     len += strlenW(productid);
00076 
00077     /*null*/
00078     len++;
00079 
00080     newprop = msi_alloc( len*sizeof(WCHAR) );
00081 
00082     if (prop)
00083     {
00084         strcpyW(newprop,prop);
00085         strcatW(newprop,szSemiColon);
00086     }
00087     else
00088         newprop[0] = 0;
00089     strcatW(newprop,productid);
00090 
00091     r = msi_set_property( package->db, action_property, newprop );
00092     if (r == ERROR_SUCCESS && !strcmpW( action_property, szSourceDir ))
00093         msi_reset_folders( package, TRUE );
00094 
00095     TRACE("Found Related Product... %s now %s\n",
00096           debugstr_w(action_property), debugstr_w(newprop));
00097 
00098     msi_free( prop );
00099     msi_free( newprop );
00100 }
00101 
00102 static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param)
00103 {
00104     MSIPACKAGE *package = param;
00105     WCHAR product[GUID_SIZE];
00106     DWORD index = 0;
00107     DWORD attributes = 0;
00108     DWORD sz = GUID_SIZE;
00109     LPCWSTR upgrade_code;
00110     HKEY hkey = 0;
00111     UINT rc = ERROR_SUCCESS;
00112     MSIRECORD *uirow;
00113 
00114     upgrade_code = MSI_RecordGetString(rec,1);
00115 
00116     rc = MSIREG_OpenUpgradeCodesKey(upgrade_code, &hkey, FALSE);
00117     if (rc != ERROR_SUCCESS)
00118         return ERROR_SUCCESS;
00119 
00120     uirow = MSI_CreateRecord(1);
00121     attributes = MSI_RecordGetInteger(rec,5);
00122 
00123     while (rc == ERROR_SUCCESS)
00124     {
00125         rc = RegEnumValueW(hkey, index, product, &sz, NULL, NULL, NULL, NULL);
00126         if (rc == ERROR_SUCCESS)
00127         {
00128             WCHAR productid[GUID_SIZE];
00129             LPCWSTR ver, language, action_property;
00130             DWORD check = 0, comp_ver, sz = 0x100;
00131             HKEY hukey;
00132             INT r;
00133 
00134             TRACE("Looking at index %u product %s\n", index, debugstr_w(product));
00135 
00136             unsquash_guid(product, productid);
00137             if (MSIREG_OpenProductKey(productid, NULL, MSIINSTALLCONTEXT_USERMANAGED, &hukey, FALSE) &&
00138                 MSIREG_OpenProductKey(productid, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, &hukey, FALSE) &&
00139                 MSIREG_OpenProductKey(productid, NULL, MSIINSTALLCONTEXT_MACHINE, &hukey, FALSE))
00140             {
00141                 TRACE("product key not found\n");
00142                 rc = ERROR_SUCCESS;
00143                 index ++;
00144                 continue;
00145             }
00146 
00147             sz = sizeof(DWORD);
00148             RegQueryValueExW(hukey, INSTALLPROPERTY_VERSIONW, NULL, NULL, (LPBYTE)&check, &sz);
00149 
00150             /* check version minimum */
00151             ver = MSI_RecordGetString(rec,2);
00152             if (ver)
00153             {
00154                 comp_ver = msi_version_str_to_dword(ver);
00155                 r = check - comp_ver;
00156                 if (r < 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMinInclusive)))
00157                 {
00158                     TRACE("version below minimum\n");
00159                     RegCloseKey(hukey);
00160                     index ++;
00161                     continue;
00162                 }
00163             }
00164 
00165             /* check version maximum */
00166             ver = MSI_RecordGetString(rec,3);
00167             if (ver)
00168             {
00169                 comp_ver = msi_version_str_to_dword(ver);
00170                 r = check - comp_ver;
00171                 if (r > 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMaxInclusive)))
00172                 {
00173                     RegCloseKey(hukey);
00174                     index ++;
00175                     continue;
00176                 }
00177                 TRACE("version above maximum\n");
00178             }
00179 
00180             /* check language */
00181             sz = sizeof(DWORD);
00182             RegQueryValueExW(hukey, INSTALLPROPERTY_LANGUAGEW, NULL, NULL, (LPBYTE)&check, &sz);
00183             RegCloseKey(hukey);
00184             language = MSI_RecordGetString(rec,4);
00185             if (!check_language(check, language, attributes))
00186             {
00187                 index ++;
00188                 TRACE("language doesn't match\n");
00189                 continue;
00190             }
00191             TRACE("found related product\n");
00192 
00193             action_property = MSI_RecordGetString(rec, 7);
00194             append_productcode(package, action_property, productid);
00195             MSI_RecordSetStringW(uirow, 1, productid);
00196             msi_ui_actiondata(package, szFindRelatedProducts, uirow);
00197         }
00198         index ++;
00199     }
00200     RegCloseKey(hkey);
00201     msiobj_release( &uirow->hdr);
00202     
00203     return ERROR_SUCCESS;
00204 }
00205 
00206 UINT ACTION_FindRelatedProducts(MSIPACKAGE *package)
00207 {
00208     static const WCHAR query[] = {
00209         'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
00210         '`','U','p','g','r','a','d','e','`',0};
00211     MSIQUERY *view;
00212     UINT rc;
00213 
00214     if (msi_get_property_int(package->db, szInstalled, 0))
00215     {
00216         TRACE("Skipping FindRelatedProducts action: product already installed\n");
00217         return ERROR_SUCCESS;
00218     }
00219     if (msi_action_is_unique(package, szFindRelatedProducts))
00220     {
00221         TRACE("Skipping FindRelatedProducts action: already done in UI sequence\n");
00222         return ERROR_SUCCESS;
00223     }
00224     else
00225         msi_register_unique_action(package, szFindRelatedProducts);
00226 
00227     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
00228     if (rc != ERROR_SUCCESS)
00229         return ERROR_SUCCESS;
00230     
00231     rc = MSI_IterateRecords(view, NULL, ITERATE_FindRelatedProducts, package);
00232     msiobj_release(&view->hdr);
00233     return rc;
00234 }

Generated on Sat May 26 2012 04:23:52 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.