Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpackage.c
Go to the documentation of this file.
00001 /* 00002 * Implementation of the Microsoft Installer (msi.dll) 00003 * 00004 * Copyright 2004 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 #define NONAMELESSUNION 00022 #define NONAMELESSSTRUCT 00023 #define COBJMACROS 00024 00025 #include <stdarg.h> 00026 #include "windef.h" 00027 #include "winbase.h" 00028 #include "winreg.h" 00029 #include "winnls.h" 00030 #include "shlwapi.h" 00031 #include "wingdi.h" 00032 #include "wine/debug.h" 00033 #include "msi.h" 00034 #include "msiquery.h" 00035 #include "objidl.h" 00036 #include "wincrypt.h" 00037 #include "winuser.h" 00038 #include "wininet.h" 00039 #include "winver.h" 00040 #include "urlmon.h" 00041 #include "shlobj.h" 00042 #include "wine/unicode.h" 00043 #include "objbase.h" 00044 #include "msidefs.h" 00045 #include "sddl.h" 00046 00047 #include "msipriv.h" 00048 #include "msiserver.h" 00049 00050 WINE_DEFAULT_DEBUG_CHANNEL(msi); 00051 00052 static void remove_tracked_tempfiles( MSIPACKAGE *package ) 00053 { 00054 struct list *item, *cursor; 00055 00056 LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles ) 00057 { 00058 MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry ); 00059 00060 list_remove( &temp->entry ); 00061 TRACE("deleting temp file %s\n", debugstr_w( temp->Path )); 00062 DeleteFileW( temp->Path ); 00063 msi_free( temp->Path ); 00064 msi_free( temp ); 00065 } 00066 } 00067 00068 static void free_feature( MSIFEATURE *feature ) 00069 { 00070 struct list *item, *cursor; 00071 00072 LIST_FOR_EACH_SAFE( item, cursor, &feature->Children ) 00073 { 00074 FeatureList *fl = LIST_ENTRY( item, FeatureList, entry ); 00075 list_remove( &fl->entry ); 00076 msi_free( fl ); 00077 } 00078 00079 LIST_FOR_EACH_SAFE( item, cursor, &feature->Components ) 00080 { 00081 ComponentList *cl = LIST_ENTRY( item, ComponentList, entry ); 00082 list_remove( &cl->entry ); 00083 msi_free( cl ); 00084 } 00085 msi_free( feature->Feature ); 00086 msi_free( feature->Feature_Parent ); 00087 msi_free( feature->Directory ); 00088 msi_free( feature->Description ); 00089 msi_free( feature->Title ); 00090 msi_free( feature ); 00091 } 00092 00093 static void free_folder( MSIFOLDER *folder ) 00094 { 00095 struct list *item, *cursor; 00096 00097 LIST_FOR_EACH_SAFE( item, cursor, &folder->children ) 00098 { 00099 FolderList *fl = LIST_ENTRY( item, FolderList, entry ); 00100 list_remove( &fl->entry ); 00101 msi_free( fl ); 00102 } 00103 msi_free( folder->Parent ); 00104 msi_free( folder->Directory ); 00105 msi_free( folder->TargetDefault ); 00106 msi_free( folder->SourceLongPath ); 00107 msi_free( folder->SourceShortPath ); 00108 msi_free( folder->ResolvedTarget ); 00109 msi_free( folder->ResolvedSource ); 00110 msi_free( folder ); 00111 } 00112 00113 static void free_extension( MSIEXTENSION *ext ) 00114 { 00115 struct list *item, *cursor; 00116 00117 LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs ) 00118 { 00119 MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry ); 00120 00121 list_remove( &verb->entry ); 00122 msi_free( verb->Verb ); 00123 msi_free( verb->Command ); 00124 msi_free( verb->Argument ); 00125 msi_free( verb ); 00126 } 00127 00128 msi_free( ext->Extension ); 00129 msi_free( ext->ProgIDText ); 00130 msi_free( ext ); 00131 } 00132 00133 static void free_assembly( MSIASSEMBLY *assembly ) 00134 { 00135 msi_free( assembly->feature ); 00136 msi_free( assembly->manifest ); 00137 msi_free( assembly->application ); 00138 msi_free( assembly->display_name ); 00139 if (assembly->tempdir) RemoveDirectoryW( assembly->tempdir ); 00140 msi_free( assembly->tempdir ); 00141 msi_free( assembly ); 00142 } 00143 00144 void msi_free_action_script( MSIPACKAGE *package, UINT script ) 00145 { 00146 UINT i; 00147 for (i = 0; i < package->script->ActionCount[script]; i++) 00148 msi_free( package->script->Actions[script][i] ); 00149 00150 msi_free( package->script->Actions[script] ); 00151 package->script->Actions[script] = NULL; 00152 package->script->ActionCount[script] = 0; 00153 } 00154 00155 static void free_package_structures( MSIPACKAGE *package ) 00156 { 00157 INT i; 00158 struct list *item, *cursor; 00159 00160 LIST_FOR_EACH_SAFE( item, cursor, &package->features ) 00161 { 00162 MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry ); 00163 list_remove( &feature->entry ); 00164 free_feature( feature ); 00165 } 00166 00167 LIST_FOR_EACH_SAFE( item, cursor, &package->folders ) 00168 { 00169 MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry ); 00170 list_remove( &folder->entry ); 00171 free_folder( folder ); 00172 } 00173 00174 LIST_FOR_EACH_SAFE( item, cursor, &package->components ) 00175 { 00176 MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry ); 00177 00178 list_remove( &comp->entry ); 00179 msi_free( comp->Component ); 00180 msi_free( comp->ComponentId ); 00181 msi_free( comp->Directory ); 00182 msi_free( comp->Condition ); 00183 msi_free( comp->KeyPath ); 00184 msi_free( comp->FullKeypath ); 00185 if (comp->assembly) free_assembly( comp->assembly ); 00186 msi_free( comp ); 00187 } 00188 00189 LIST_FOR_EACH_SAFE( item, cursor, &package->files ) 00190 { 00191 MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry ); 00192 00193 list_remove( &file->entry ); 00194 msi_free( file->File ); 00195 msi_free( file->FileName ); 00196 msi_free( file->ShortName ); 00197 msi_free( file->LongName ); 00198 msi_free( file->Version ); 00199 msi_free( file->Language ); 00200 msi_free( file->TargetPath ); 00201 msi_free( file ); 00202 } 00203 00204 /* clean up extension, progid, class and verb structures */ 00205 LIST_FOR_EACH_SAFE( item, cursor, &package->classes ) 00206 { 00207 MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry ); 00208 00209 list_remove( &cls->entry ); 00210 msi_free( cls->clsid ); 00211 msi_free( cls->Context ); 00212 msi_free( cls->Description ); 00213 msi_free( cls->FileTypeMask ); 00214 msi_free( cls->IconPath ); 00215 msi_free( cls->DefInprocHandler ); 00216 msi_free( cls->DefInprocHandler32 ); 00217 msi_free( cls->Argument ); 00218 msi_free( cls->ProgIDText ); 00219 msi_free( cls ); 00220 } 00221 00222 LIST_FOR_EACH_SAFE( item, cursor, &package->extensions ) 00223 { 00224 MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry ); 00225 00226 list_remove( &ext->entry ); 00227 free_extension( ext ); 00228 } 00229 00230 LIST_FOR_EACH_SAFE( item, cursor, &package->progids ) 00231 { 00232 MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry ); 00233 00234 list_remove( &progid->entry ); 00235 msi_free( progid->ProgID ); 00236 msi_free( progid->Description ); 00237 msi_free( progid->IconPath ); 00238 msi_free( progid ); 00239 } 00240 00241 LIST_FOR_EACH_SAFE( item, cursor, &package->mimes ) 00242 { 00243 MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry ); 00244 00245 list_remove( &mt->entry ); 00246 msi_free( mt->suffix ); 00247 msi_free( mt->clsid ); 00248 msi_free( mt->ContentType ); 00249 msi_free( mt ); 00250 } 00251 00252 LIST_FOR_EACH_SAFE( item, cursor, &package->appids ) 00253 { 00254 MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry ); 00255 00256 list_remove( &appid->entry ); 00257 msi_free( appid->AppID ); 00258 msi_free( appid->RemoteServerName ); 00259 msi_free( appid->LocalServer ); 00260 msi_free( appid->ServiceParameters ); 00261 msi_free( appid->DllSurrogate ); 00262 msi_free( appid ); 00263 } 00264 00265 LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_info ) 00266 { 00267 MSISOURCELISTINFO *info = LIST_ENTRY( item, MSISOURCELISTINFO, entry ); 00268 00269 list_remove( &info->entry ); 00270 msi_free( info->value ); 00271 msi_free( info ); 00272 } 00273 00274 LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_media ) 00275 { 00276 MSIMEDIADISK *info = LIST_ENTRY( item, MSIMEDIADISK, entry ); 00277 00278 list_remove( &info->entry ); 00279 msi_free( info->volume_label ); 00280 msi_free( info->disk_prompt ); 00281 msi_free( info ); 00282 } 00283 00284 if (package->script) 00285 { 00286 for (i = 0; i < SCRIPT_MAX; i++) 00287 msi_free_action_script( package, i ); 00288 00289 for (i = 0; i < package->script->UniqueActionsCount; i++) 00290 msi_free( package->script->UniqueActions[i] ); 00291 00292 msi_free( package->script->UniqueActions ); 00293 msi_free( package->script ); 00294 } 00295 00296 LIST_FOR_EACH_SAFE( item, cursor, &package->binaries ) 00297 { 00298 MSIBINARY *binary = LIST_ENTRY( item, MSIBINARY, entry ); 00299 00300 list_remove( &binary->entry ); 00301 if (binary->module) 00302 FreeLibrary( binary->module ); 00303 if (!DeleteFileW( binary->tmpfile )) 00304 ERR("failed to delete %s (%u)\n", debugstr_w(binary->tmpfile), GetLastError()); 00305 msi_free( binary->source ); 00306 msi_free( binary->tmpfile ); 00307 msi_free( binary ); 00308 } 00309 00310 LIST_FOR_EACH_SAFE( item, cursor, &package->cabinet_streams ) 00311 { 00312 MSICABINETSTREAM *cab = LIST_ENTRY( item, MSICABINETSTREAM, entry ); 00313 00314 list_remove( &cab->entry ); 00315 IStorage_Release( cab->storage ); 00316 msi_free( cab->stream ); 00317 msi_free( cab ); 00318 } 00319 00320 LIST_FOR_EACH_SAFE( item, cursor, &package->patches ) 00321 { 00322 MSIPATCHINFO *patch = LIST_ENTRY( item, MSIPATCHINFO, entry ); 00323 00324 list_remove( &patch->entry ); 00325 if (patch->delete_on_close && !DeleteFileW( patch->localfile )) 00326 { 00327 ERR("failed to delete %s (%u)\n", debugstr_w(patch->localfile), GetLastError()); 00328 } 00329 msi_free_patchinfo( patch ); 00330 } 00331 00332 msi_free( package->BaseURL ); 00333 msi_free( package->PackagePath ); 00334 msi_free( package->ProductCode ); 00335 msi_free( package->ActionFormat ); 00336 msi_free( package->LastAction ); 00337 msi_free( package->langids ); 00338 00339 remove_tracked_tempfiles(package); 00340 00341 /* cleanup control event subscriptions */ 00342 ControlEvent_CleanupSubscriptions( package ); 00343 } 00344 00345 static void MSI_FreePackage( MSIOBJECTHDR *arg) 00346 { 00347 UINT i; 00348 MSIPACKAGE *package = (MSIPACKAGE *)arg; 00349 00350 if( package->dialog ) 00351 msi_dialog_destroy( package->dialog ); 00352 00353 msiobj_release( &package->db->hdr ); 00354 free_package_structures(package); 00355 CloseHandle( package->log_file ); 00356 00357 for (i = 0; i < CLR_VERSION_MAX; i++) 00358 if (package->cache_net[i]) IAssemblyCache_Release( package->cache_net[i] ); 00359 if (package->cache_sxs) IAssemblyCache_Release( package->cache_sxs ); 00360 00361 if (package->delete_on_close) DeleteFileW( package->localfile ); 00362 msi_free( package->localfile ); 00363 } 00364 00365 static UINT create_temp_property_table(MSIPACKAGE *package) 00366 { 00367 static const WCHAR query[] = { 00368 'C','R','E','A','T','E',' ','T','A','B','L','E',' ', 00369 '`','_','P','r','o','p','e','r','t','y','`',' ','(',' ', 00370 '`','_','P','r','o','p','e','r','t','y','`',' ', 00371 'C','H','A','R','(','5','6',')',' ','N','O','T',' ','N','U','L','L',' ', 00372 'T','E','M','P','O','R','A','R','Y',',',' ', 00373 '`','V','a','l','u','e','`',' ','C','H','A','R','(','9','8',')',' ', 00374 'N','O','T',' ','N','U','L','L',' ','T','E','M','P','O','R','A','R','Y', 00375 ' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ', 00376 '`','_','P','r','o','p','e','r','t','y','`',')',' ','H','O','L','D',0}; 00377 MSIQUERY *view; 00378 UINT rc; 00379 00380 rc = MSI_DatabaseOpenViewW(package->db, query, &view); 00381 if (rc != ERROR_SUCCESS) 00382 return rc; 00383 00384 rc = MSI_ViewExecute(view, 0); 00385 MSI_ViewClose(view); 00386 msiobj_release(&view->hdr); 00387 return rc; 00388 } 00389 00390 UINT msi_clone_properties(MSIPACKAGE *package) 00391 { 00392 static const WCHAR query_select[] = { 00393 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', 00394 '`','P','r','o','p','e','r','t','y','`',0}; 00395 static const WCHAR query_insert[] = { 00396 'I','N','S','E','R','T',' ','I','N','T','O',' ', 00397 '`','_','P','r','o','p','e','r','t','y','`',' ', 00398 '(','`','_','P','r','o','p','e','r','t','y','`',',','`','V','a','l','u','e','`',')',' ', 00399 'V','A','L','U','E','S',' ','(','?',',','?',')',0}; 00400 static const WCHAR query_update[] = { 00401 'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ', 00402 'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ', 00403 'W','H','E','R','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','?',0}; 00404 MSIQUERY *view_select; 00405 UINT rc; 00406 00407 rc = MSI_DatabaseOpenViewW( package->db, query_select, &view_select ); 00408 if (rc != ERROR_SUCCESS) 00409 return rc; 00410 00411 rc = MSI_ViewExecute( view_select, 0 ); 00412 if (rc != ERROR_SUCCESS) 00413 { 00414 MSI_ViewClose( view_select ); 00415 msiobj_release( &view_select->hdr ); 00416 return rc; 00417 } 00418 00419 while (1) 00420 { 00421 MSIQUERY *view_insert, *view_update; 00422 MSIRECORD *rec_select; 00423 00424 rc = MSI_ViewFetch( view_select, &rec_select ); 00425 if (rc != ERROR_SUCCESS) 00426 break; 00427 00428 rc = MSI_DatabaseOpenViewW( package->db, query_insert, &view_insert ); 00429 if (rc != ERROR_SUCCESS) 00430 { 00431 msiobj_release( &rec_select->hdr ); 00432 continue; 00433 } 00434 00435 rc = MSI_ViewExecute( view_insert, rec_select ); 00436 MSI_ViewClose( view_insert ); 00437 msiobj_release( &view_insert->hdr ); 00438 if (rc != ERROR_SUCCESS) 00439 { 00440 MSIRECORD *rec_update; 00441 00442 TRACE("insert failed, trying update\n"); 00443 00444 rc = MSI_DatabaseOpenViewW( package->db, query_update, &view_update ); 00445 if (rc != ERROR_SUCCESS) 00446 { 00447 WARN("open view failed %u\n", rc); 00448 msiobj_release( &rec_select->hdr ); 00449 continue; 00450 } 00451 00452 rec_update = MSI_CreateRecord( 2 ); 00453 MSI_RecordCopyField( rec_select, 1, rec_update, 2 ); 00454 MSI_RecordCopyField( rec_select, 2, rec_update, 1 ); 00455 rc = MSI_ViewExecute( view_update, rec_update ); 00456 if (rc != ERROR_SUCCESS) 00457 WARN("update failed %u\n", rc); 00458 00459 MSI_ViewClose( view_update ); 00460 msiobj_release( &view_update->hdr ); 00461 msiobj_release( &rec_update->hdr ); 00462 } 00463 00464 msiobj_release( &rec_select->hdr ); 00465 } 00466 00467 MSI_ViewClose( view_select ); 00468 msiobj_release( &view_select->hdr ); 00469 return rc; 00470 } 00471 00472 /* 00473 * set_installed_prop 00474 * 00475 * Sets the "Installed" property to indicate that 00476 * the product is installed for the current user. 00477 */ 00478 static UINT set_installed_prop( MSIPACKAGE *package ) 00479 { 00480 HKEY hkey; 00481 UINT r; 00482 00483 if (!package->ProductCode) return ERROR_FUNCTION_FAILED; 00484 00485 r = MSIREG_OpenUninstallKey( package->ProductCode, package->platform, &hkey, FALSE ); 00486 if (r == ERROR_SUCCESS) 00487 { 00488 RegCloseKey( hkey ); 00489 msi_set_property( package->db, szInstalled, szOne ); 00490 } 00491 return r; 00492 } 00493 00494 static UINT set_user_sid_prop( MSIPACKAGE *package ) 00495 { 00496 SID_NAME_USE use; 00497 LPWSTR user_name; 00498 LPWSTR sid_str = NULL, dom = NULL; 00499 DWORD size, dom_size; 00500 PSID psid = NULL; 00501 UINT r = ERROR_FUNCTION_FAILED; 00502 00503 size = 0; 00504 GetUserNameW( NULL, &size ); 00505 00506 user_name = msi_alloc( (size + 1) * sizeof(WCHAR) ); 00507 if (!user_name) 00508 return ERROR_OUTOFMEMORY; 00509 00510 if (!GetUserNameW( user_name, &size )) 00511 goto done; 00512 00513 size = 0; 00514 dom_size = 0; 00515 LookupAccountNameW( NULL, user_name, NULL, &size, NULL, &dom_size, &use ); 00516 00517 psid = msi_alloc( size ); 00518 dom = msi_alloc( dom_size*sizeof (WCHAR) ); 00519 if (!psid || !dom) 00520 { 00521 r = ERROR_OUTOFMEMORY; 00522 goto done; 00523 } 00524 00525 if (!LookupAccountNameW( NULL, user_name, psid, &size, dom, &dom_size, &use )) 00526 goto done; 00527 00528 if (!ConvertSidToStringSidW( psid, &sid_str )) 00529 goto done; 00530 00531 r = msi_set_property( package->db, szUserSID, sid_str ); 00532 00533 done: 00534 LocalFree( sid_str ); 00535 msi_free( dom ); 00536 msi_free( psid ); 00537 msi_free( user_name ); 00538 00539 return r; 00540 } 00541 00542 static LPWSTR get_fusion_filename(MSIPACKAGE *package) 00543 { 00544 HKEY netsetup; 00545 LONG res; 00546 LPWSTR file = NULL; 00547 DWORD index = 0, size; 00548 WCHAR ver[MAX_PATH]; 00549 WCHAR name[MAX_PATH]; 00550 WCHAR windir[MAX_PATH]; 00551 00552 static const WCHAR fusion[] = {'f','u','s','i','o','n','.','d','l','l',0}; 00553 static const WCHAR sub[] = { 00554 'S','o','f','t','w','a','r','e','\\', 00555 'M','i','c','r','o','s','o','f','t','\\', 00556 'N','E','T',' ','F','r','a','m','e','w','o','r','k',' ','S','e','t','u','p','\\', 00557 'N','D','P',0 00558 }; 00559 static const WCHAR subdir[] = { 00560 'M','i','c','r','o','s','o','f','t','.','N','E','T','\\', 00561 'F','r','a','m','e','w','o','r','k','\\',0 00562 }; 00563 00564 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, sub, 0, KEY_ENUMERATE_SUB_KEYS, &netsetup); 00565 if (res != ERROR_SUCCESS) 00566 return NULL; 00567 00568 GetWindowsDirectoryW(windir, MAX_PATH); 00569 00570 ver[0] = '\0'; 00571 size = MAX_PATH; 00572 while (RegEnumKeyExW(netsetup, index, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) 00573 { 00574 index++; 00575 00576 /* verify existence of fusion.dll .Net 3.0 does not install a new one */ 00577 if (strcmpW( ver, name ) < 0) 00578 { 00579 LPWSTR check; 00580 size = lstrlenW(windir) + lstrlenW(subdir) + lstrlenW(name) +lstrlenW(fusion) + 3; 00581 check = msi_alloc(size * sizeof(WCHAR)); 00582 00583 if (!check) 00584 { 00585 msi_free(file); 00586 return NULL; 00587 } 00588 00589 lstrcpyW(check, windir); 00590 lstrcatW(check, szBackSlash); 00591 lstrcatW(check, subdir); 00592 lstrcatW(check, name); 00593 lstrcatW(check, szBackSlash); 00594 lstrcatW(check, fusion); 00595 00596 if(GetFileAttributesW(check) != INVALID_FILE_ATTRIBUTES) 00597 { 00598 msi_free(file); 00599 file = check; 00600 lstrcpyW(ver, name); 00601 } 00602 else 00603 msi_free(check); 00604 } 00605 } 00606 00607 RegCloseKey(netsetup); 00608 return file; 00609 } 00610 00611 typedef struct tagLANGANDCODEPAGE 00612 { 00613 WORD wLanguage; 00614 WORD wCodePage; 00615 } LANGANDCODEPAGE; 00616 00617 static void set_msi_assembly_prop(MSIPACKAGE *package) 00618 { 00619 UINT val_len; 00620 DWORD size, handle; 00621 LPVOID version = NULL; 00622 WCHAR buf[MAX_PATH]; 00623 LPWSTR fusion, verstr; 00624 LANGANDCODEPAGE *translate; 00625 00626 static const WCHAR netasm[] = { 00627 'M','s','i','N','e','t','A','s','s','e','m','b','l','y','S','u','p','p','o','r','t',0 00628 }; 00629 static const WCHAR translation[] = { 00630 '\\','V','a','r','F','i','l','e','I','n','f','o', 00631 '\\','T','r','a','n','s','l','a','t','i','o','n',0 00632 }; 00633 static const WCHAR verfmt[] = { 00634 '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o', 00635 '\\','%','0','4','x','%','0','4','x', 00636 '\\','P','r','o','d','u','c','t','V','e','r','s','i','o','n',0 00637 }; 00638 00639 fusion = get_fusion_filename(package); 00640 if (!fusion) 00641 return; 00642 00643 size = GetFileVersionInfoSizeW(fusion, &handle); 00644 if (!size) return; 00645 00646 version = msi_alloc(size); 00647 if (!version) return; 00648 00649 if (!GetFileVersionInfoW(fusion, handle, size, version)) 00650 goto done; 00651 00652 if (!VerQueryValueW(version, translation, (LPVOID *)&translate, &val_len)) 00653 goto done; 00654 00655 sprintfW(buf, verfmt, translate[0].wLanguage, translate[0].wCodePage); 00656 00657 if (!VerQueryValueW(version, buf, (LPVOID *)&verstr, &val_len)) 00658 goto done; 00659 00660 if (!val_len || !verstr) 00661 goto done; 00662 00663 msi_set_property(package->db, netasm, verstr); 00664 00665 done: 00666 msi_free(fusion); 00667 msi_free(version); 00668 } 00669 00670 static VOID set_installer_properties(MSIPACKAGE *package) 00671 { 00672 WCHAR pth[MAX_PATH]; 00673 WCHAR *ptr; 00674 OSVERSIONINFOEXW OSVersion; 00675 MEMORYSTATUSEX msex; 00676 DWORD verval, len; 00677 WCHAR verstr[10], bufstr[20]; 00678 HDC dc; 00679 HKEY hkey; 00680 LPWSTR username, companyname; 00681 SYSTEM_INFO sys_info; 00682 SYSTEMTIME systemtime; 00683 LANGID langid; 00684 00685 static const WCHAR szCommonFilesFolder[] = {'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0}; 00686 static const WCHAR szProgramFilesFolder[] = {'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0}; 00687 static const WCHAR szCommonAppDataFolder[] = {'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0}; 00688 static const WCHAR szFavoritesFolder[] = {'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0}; 00689 static const WCHAR szFontsFolder[] = {'F','o','n','t','s','F','o','l','d','e','r',0}; 00690 static const WCHAR szSendToFolder[] = {'S','e','n','d','T','o','F','o','l','d','e','r',0}; 00691 static const WCHAR szStartMenuFolder[] = {'S','t','a','r','t','M','e','n','u','F','o','l','d','e','r',0}; 00692 static const WCHAR szStartupFolder[] = {'S','t','a','r','t','u','p','F','o','l','d','e','r',0}; 00693 static const WCHAR szTemplateFolder[] = {'T','e','m','p','l','a','t','e','F','o','l','d','e','r',0}; 00694 static const WCHAR szDesktopFolder[] = {'D','e','s','k','t','o','p','F','o','l','d','e','r',0}; 00695 static const WCHAR szProgramMenuFolder[] = {'P','r','o','g','r','a','m','M','e','n','u','F','o','l','d','e','r',0}; 00696 static const WCHAR szAdminToolsFolder[] = {'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0}; 00697 static const WCHAR szSystemFolder[] = {'S','y','s','t','e','m','F','o','l','d','e','r',0}; 00698 static const WCHAR szSystem16Folder[] = {'S','y','s','t','e','m','1','6','F','o','l','d','e','r',0}; 00699 static const WCHAR szLocalAppDataFolder[] = {'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0}; 00700 static const WCHAR szMyPicturesFolder[] = {'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0}; 00701 static const WCHAR szPersonalFolder[] = {'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0}; 00702 static const WCHAR szWindowsVolume[] = {'W','i','n','d','o','w','s','V','o','l','u','m','e',0}; 00703 static const WCHAR szPrivileged[] = {'P','r','i','v','i','l','e','g','e','d',0}; 00704 static const WCHAR szVersion9x[] = {'V','e','r','s','i','o','n','9','X',0}; 00705 static const WCHAR szVersionNT[] = {'V','e','r','s','i','o','n','N','T',0}; 00706 static const WCHAR szMsiNTProductType[] = {'M','s','i','N','T','P','r','o','d','u','c','t','T','y','p','e',0}; 00707 static const WCHAR szFormat[] = {'%','l','i',0}; 00708 static const WCHAR szWindowsBuild[] = {'W','i','n','d','o','w','s','B','u','i','l','d',0}; 00709 static const WCHAR szServicePackLevel[] = {'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',0}; 00710 static const WCHAR szSix[] = {'6',0 }; 00711 static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 }; 00712 static const WCHAR szVersionDatabase[] = { 'V','e','r','s','i','o','n','D','a','t','a','b','a','s','e',0 }; 00713 static const WCHAR szPhysicalMemory[] = { 'P','h','y','s','i','c','a','l','M','e','m','o','r','y',0 }; 00714 static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0}; 00715 static const WCHAR szScreenX[] = {'S','c','r','e','e','n','X',0}; 00716 static const WCHAR szScreenY[] = {'S','c','r','e','e','n','Y',0}; 00717 static const WCHAR szColorBits[] = {'C','o','l','o','r','B','i','t','s',0}; 00718 static const WCHAR szIntFormat[] = {'%','d',0}; 00719 static const WCHAR szMsiAMD64[] = { 'M','s','i','A','M','D','6','4',0 }; 00720 static const WCHAR szMsix64[] = { 'M','s','i','x','6','4',0 }; 00721 static const WCHAR szSystem64Folder[] = { 'S','y','s','t','e','m','6','4','F','o','l','d','e','r',0 }; 00722 static const WCHAR szCommonFiles64Folder[] = { 'C','o','m','m','o','n','F','i','l','e','s','6','4','F','o','l','d','e','r',0 }; 00723 static const WCHAR szProgramFiles64Folder[] = { 'P','r','o','g','r','a','m','F','i','l','e','s','6','4','F','o','l','d','e','r',0 }; 00724 static const WCHAR szVersionNT64[] = { 'V','e','r','s','i','o','n','N','T','6','4',0 }; 00725 static const WCHAR szUserInfo[] = { 00726 'S','O','F','T','W','A','R','E','\\', 00727 'M','i','c','r','o','s','o','f','t','\\', 00728 'M','S',' ','S','e','t','u','p',' ','(','A','C','M','E',')','\\', 00729 'U','s','e','r',' ','I','n','f','o',0 00730 }; 00731 static const WCHAR szDefName[] = { 'D','e','f','N','a','m','e',0 }; 00732 static const WCHAR szDefCompany[] = { 'D','e','f','C','o','m','p','a','n','y',0 }; 00733 static const WCHAR szCurrentVersion[] = { 00734 'S','O','F','T','W','A','R','E','\\', 00735 'M','i','c','r','o','s','o','f','t','\\', 00736 'W','i','n','d','o','w','s',' ','N','T','\\', 00737 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0 00738 }; 00739 static const WCHAR szRegisteredUser[] = {'R','e','g','i','s','t','e','r','e','d','O','w','n','e','r',0}; 00740 static const WCHAR szRegisteredOrganization[] = { 00741 'R','e','g','i','s','t','e','r','e','d','O','r','g','a','n','i','z','a','t','i','o','n',0 00742 }; 00743 static const WCHAR szUSERNAME[] = {'U','S','E','R','N','A','M','E',0}; 00744 static const WCHAR szCOMPANYNAME[] = {'C','O','M','P','A','N','Y','N','A','M','E',0}; 00745 static const WCHAR szDate[] = {'D','a','t','e',0}; 00746 static const WCHAR szTime[] = {'T','i','m','e',0}; 00747 static const WCHAR szUserLanguageID[] = {'U','s','e','r','L','a','n','g','u','a','g','e','I','D',0}; 00748 static const WCHAR szSystemLangID[] = {'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0}; 00749 static const WCHAR szProductState[] = {'P','r','o','d','u','c','t','S','t','a','t','e',0}; 00750 static const WCHAR szLogonUser[] = {'L','o','g','o','n','U','s','e','r',0}; 00751 static const WCHAR szNetHoodFolder[] = {'N','e','t','H','o','o','d','F','o','l','d','e','r',0}; 00752 static const WCHAR szPrintHoodFolder[] = {'P','r','i','n','t','H','o','o','d','F','o','l','d','e','r',0}; 00753 static const WCHAR szRecentFolder[] = {'R','e','c','e','n','t','F','o','l','d','e','r',0}; 00754 static const WCHAR szComputerName[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0}; 00755 00756 /* 00757 * Other things that probably should be set: 00758 * 00759 * VirtualMemory ShellAdvSupport DefaultUIFont PackagecodeChanging 00760 * CaptionHeight BorderTop BorderSide TextHeight RedirectedDllSupport 00761 */ 00762 00763 SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, pth); 00764 strcatW(pth, szBackSlash); 00765 msi_set_property(package->db, szCommonAppDataFolder, pth); 00766 00767 SHGetFolderPathW(NULL, CSIDL_FAVORITES, NULL, 0, pth); 00768 strcatW(pth, szBackSlash); 00769 msi_set_property(package->db, szFavoritesFolder, pth); 00770 00771 SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, pth); 00772 strcatW(pth, szBackSlash); 00773 msi_set_property(package->db, szFontsFolder, pth); 00774 00775 SHGetFolderPathW(NULL, CSIDL_SENDTO, NULL, 0, pth); 00776 strcatW(pth, szBackSlash); 00777 msi_set_property(package->db, szSendToFolder, pth); 00778 00779 SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, pth); 00780 strcatW(pth, szBackSlash); 00781 msi_set_property(package->db, szStartMenuFolder, pth); 00782 00783 SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, pth); 00784 strcatW(pth, szBackSlash); 00785 msi_set_property(package->db, szStartupFolder, pth); 00786 00787 SHGetFolderPathW(NULL, CSIDL_TEMPLATES, NULL, 0, pth); 00788 strcatW(pth, szBackSlash); 00789 msi_set_property(package->db, szTemplateFolder, pth); 00790 00791 SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, pth); 00792 strcatW(pth, szBackSlash); 00793 msi_set_property(package->db, szDesktopFolder, pth); 00794 00795 /* FIXME: set to AllUsers profile path if ALLUSERS is set */ 00796 SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, 0, pth); 00797 strcatW(pth, szBackSlash); 00798 msi_set_property(package->db, szProgramMenuFolder, pth); 00799 00800 SHGetFolderPathW(NULL, CSIDL_ADMINTOOLS, NULL, 0, pth); 00801 strcatW(pth, szBackSlash); 00802 msi_set_property(package->db, szAdminToolsFolder, pth); 00803 00804 SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, pth); 00805 strcatW(pth, szBackSlash); 00806 msi_set_property(package->db, szAppDataFolder, pth); 00807 00808 SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, 0, pth); 00809 strcatW(pth, szBackSlash); 00810 msi_set_property(package->db, szSystemFolder, pth); 00811 msi_set_property(package->db, szSystem16Folder, pth); 00812 00813 SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pth); 00814 strcatW(pth, szBackSlash); 00815 msi_set_property(package->db, szLocalAppDataFolder, pth); 00816 00817 SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, 0, pth); 00818 strcatW(pth, szBackSlash); 00819 msi_set_property(package->db, szMyPicturesFolder, pth); 00820 00821 SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, pth); 00822 strcatW(pth, szBackSlash); 00823 msi_set_property(package->db, szPersonalFolder, pth); 00824 00825 SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth); 00826 strcatW(pth, szBackSlash); 00827 msi_set_property(package->db, szWindowsFolder, pth); 00828 00829 SHGetFolderPathW(NULL, CSIDL_PRINTHOOD, NULL, 0, pth); 00830 strcatW(pth, szBackSlash); 00831 msi_set_property(package->db, szPrintHoodFolder, pth); 00832 00833 SHGetFolderPathW(NULL, CSIDL_NETHOOD, NULL, 0, pth); 00834 strcatW(pth, szBackSlash); 00835 msi_set_property(package->db, szNetHoodFolder, pth); 00836 00837 SHGetFolderPathW(NULL, CSIDL_RECENT, NULL, 0, pth); 00838 strcatW(pth, szBackSlash); 00839 msi_set_property(package->db, szRecentFolder, pth); 00840 00841 /* Physical Memory is specified in MB. Using total amount. */ 00842 msex.dwLength = sizeof(msex); 00843 GlobalMemoryStatusEx( &msex ); 00844 sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys / 1024 / 1024) ); 00845 msi_set_property(package->db, szPhysicalMemory, bufstr); 00846 00847 SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth); 00848 ptr = strchrW(pth,'\\'); 00849 if (ptr) *(ptr + 1) = 0; 00850 msi_set_property(package->db, szWindowsVolume, pth); 00851 00852 GetTempPathW(MAX_PATH,pth); 00853 msi_set_property(package->db, szTempFolder, pth); 00854 00855 /* in a wine environment the user is always admin and privileged */ 00856 msi_set_property(package->db, szAdminUser, szOne); 00857 msi_set_property(package->db, szPrivileged, szOne); 00858 00859 /* set the os things */ 00860 OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); 00861 GetVersionExW((OSVERSIONINFOW *)&OSVersion); 00862 verval = OSVersion.dwMinorVersion + OSVersion.dwMajorVersion * 100; 00863 sprintfW(verstr, szFormat, verval); 00864 switch (OSVersion.dwPlatformId) 00865 { 00866 case VER_PLATFORM_WIN32_WINDOWS: 00867 msi_set_property(package->db, szVersion9x, verstr); 00868 break; 00869 case VER_PLATFORM_WIN32_NT: 00870 msi_set_property(package->db, szVersionNT, verstr); 00871 sprintfW(verstr, szFormat,OSVersion.wProductType); 00872 msi_set_property(package->db, szMsiNTProductType, verstr); 00873 break; 00874 } 00875 sprintfW(verstr, szFormat, OSVersion.dwBuildNumber); 00876 msi_set_property(package->db, szWindowsBuild, verstr); 00877 /* just fudge this */ 00878 msi_set_property(package->db, szServicePackLevel, szSix); 00879 00880 sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION); 00881 msi_set_property( package->db, szVersionMsi, bufstr ); 00882 sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100); 00883 msi_set_property( package->db, szVersionDatabase, bufstr ); 00884 00885 GetNativeSystemInfo( &sys_info ); 00886 sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel ); 00887 msi_set_property( package->db, szIntel, bufstr ); 00888 if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) 00889 { 00890 GetSystemDirectoryW( pth, MAX_PATH ); 00891 PathAddBackslashW( pth ); 00892 msi_set_property( package->db, szSystemFolder, pth ); 00893 00894 SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth ); 00895 PathAddBackslashW( pth ); 00896 msi_set_property( package->db, szProgramFilesFolder, pth ); 00897 00898 SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth ); 00899 PathAddBackslashW( pth ); 00900 msi_set_property( package->db, szCommonFilesFolder, pth ); 00901 } 00902 else if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) 00903 { 00904 msi_set_property( package->db, szMsiAMD64, bufstr ); 00905 msi_set_property( package->db, szMsix64, bufstr ); 00906 msi_set_property( package->db, szVersionNT64, verstr ); 00907 00908 GetSystemDirectoryW( pth, MAX_PATH ); 00909 PathAddBackslashW( pth ); 00910 msi_set_property( package->db, szSystem64Folder, pth ); 00911 00912 GetSystemWow64DirectoryW( pth, MAX_PATH ); 00913 PathAddBackslashW( pth ); 00914 msi_set_property( package->db, szSystemFolder, pth ); 00915 00916 SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth ); 00917 PathAddBackslashW( pth ); 00918 msi_set_property( package->db, szProgramFiles64Folder, pth ); 00919 00920 SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, pth ); 00921 PathAddBackslashW( pth ); 00922 msi_set_property( package->db, szProgramFilesFolder, pth ); 00923 00924 SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth ); 00925 PathAddBackslashW( pth ); 00926 msi_set_property( package->db, szCommonFiles64Folder, pth ); 00927 00928 SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, pth ); 00929 PathAddBackslashW( pth ); 00930 msi_set_property( package->db, szCommonFilesFolder, pth ); 00931 } 00932 00933 /* Screen properties. */ 00934 dc = GetDC(0); 00935 sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, HORZRES ) ); 00936 msi_set_property( package->db, szScreenX, bufstr ); 00937 sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, VERTRES )); 00938 msi_set_property( package->db, szScreenY, bufstr ); 00939 sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, BITSPIXEL )); 00940 msi_set_property( package->db, szColorBits, bufstr ); 00941 ReleaseDC(0, dc); 00942 00943 /* USERNAME and COMPANYNAME */ 00944 username = msi_dup_property( package->db, szUSERNAME ); 00945 companyname = msi_dup_property( package->db, szCOMPANYNAME ); 00946 00947 if ((!username || !companyname) && 00948 RegOpenKeyW( HKEY_CURRENT_USER, szUserInfo, &hkey ) == ERROR_SUCCESS) 00949 { 00950 if (!username && 00951 (username = msi_reg_get_val_str( hkey, szDefName ))) 00952 msi_set_property( package->db, szUSERNAME, username ); 00953 if (!companyname && 00954 (companyname = msi_reg_get_val_str( hkey, szDefCompany ))) 00955 msi_set_property( package->db, szCOMPANYNAME, companyname ); 00956 CloseHandle( hkey ); 00957 } 00958 if ((!username || !companyname) && 00959 RegOpenKeyW( HKEY_LOCAL_MACHINE, szCurrentVersion, &hkey ) == ERROR_SUCCESS) 00960 { 00961 if (!username && 00962 (username = msi_reg_get_val_str( hkey, szRegisteredUser ))) 00963 msi_set_property( package->db, szUSERNAME, username ); 00964 if (!companyname && 00965 (companyname = msi_reg_get_val_str( hkey, szRegisteredOrganization ))) 00966 msi_set_property( package->db, szCOMPANYNAME, companyname ); 00967 CloseHandle( hkey ); 00968 } 00969 msi_free( username ); 00970 msi_free( companyname ); 00971 00972 if ( set_user_sid_prop( package ) != ERROR_SUCCESS) 00973 ERR("Failed to set the UserSID property\n"); 00974 00975 /* Date and time properties */ 00976 GetSystemTime( &systemtime ); 00977 if (GetDateFormatW( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime, 00978 NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) )) 00979 msi_set_property( package->db, szDate, bufstr ); 00980 else 00981 ERR("Couldn't set Date property: GetDateFormat failed with error %d\n", GetLastError()); 00982 00983 if (GetTimeFormatW( LOCALE_USER_DEFAULT, 00984 TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, 00985 &systemtime, NULL, bufstr, 00986 sizeof(bufstr)/sizeof(bufstr[0]) )) 00987 msi_set_property( package->db, szTime, bufstr ); 00988 else 00989 ERR("Couldn't set Time property: GetTimeFormat failed with error %d\n", GetLastError()); 00990 00991 set_msi_assembly_prop( package ); 00992 00993 langid = GetUserDefaultLangID(); 00994 sprintfW(bufstr, szIntFormat, langid); 00995 msi_set_property( package->db, szUserLanguageID, bufstr ); 00996 00997 langid = GetSystemDefaultLangID(); 00998 sprintfW(bufstr, szIntFormat, langid); 00999 msi_set_property( package->db, szSystemLangID, bufstr ); 01000 01001 sprintfW(bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode)); 01002 msi_set_property( package->db, szProductState, bufstr ); 01003 01004 len = 0; 01005 if (!GetUserNameW( NULL, &len ) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 01006 { 01007 WCHAR *username; 01008 if ((username = msi_alloc( len * sizeof(WCHAR) ))) 01009 { 01010 if (GetUserNameW( username, &len )) 01011 msi_set_property( package->db, szLogonUser, username ); 01012 msi_free( username ); 01013 } 01014 } 01015 len = 0; 01016 if (!GetComputerNameW( NULL, &len ) && GetLastError() == ERROR_BUFFER_OVERFLOW) 01017 { 01018 WCHAR *computername; 01019 if ((computername = msi_alloc( len * sizeof(WCHAR) ))) 01020 { 01021 if (GetComputerNameW( computername, &len )) 01022 msi_set_property( package->db, szComputerName, computername ); 01023 msi_free( computername ); 01024 } 01025 } 01026 } 01027 01028 static UINT msi_load_summary_properties( MSIPACKAGE *package ) 01029 { 01030 UINT rc; 01031 MSIHANDLE suminfo; 01032 MSIHANDLE hdb = alloc_msihandle( &package->db->hdr ); 01033 INT count; 01034 DWORD len; 01035 LPWSTR package_code; 01036 static const WCHAR szPackageCode[] = { 01037 'P','a','c','k','a','g','e','C','o','d','e',0}; 01038 01039 if (!hdb) { 01040 ERR("Unable to allocate handle\n"); 01041 return ERROR_OUTOFMEMORY; 01042 } 01043 01044 rc = MsiGetSummaryInformationW( hdb, NULL, 0, &suminfo ); 01045 MsiCloseHandle(hdb); 01046 if (rc != ERROR_SUCCESS) 01047 { 01048 ERR("Unable to open Summary Information\n"); 01049 return rc; 01050 } 01051 01052 rc = MsiSummaryInfoGetPropertyW( suminfo, PID_PAGECOUNT, NULL, 01053 &count, NULL, NULL, NULL ); 01054 if (rc != ERROR_SUCCESS) 01055 { 01056 WARN("Unable to query page count: %d\n", rc); 01057 goto done; 01058 } 01059 01060 /* load package code property */ 01061 len = 0; 01062 rc = MsiSummaryInfoGetPropertyW( suminfo, PID_REVNUMBER, NULL, 01063 NULL, NULL, NULL, &len ); 01064 if (rc != ERROR_MORE_DATA) 01065 { 01066 WARN("Unable to query revision number: %d\n", rc); 01067 rc = ERROR_FUNCTION_FAILED; 01068 goto done; 01069 } 01070 01071 len++; 01072 package_code = msi_alloc( len * sizeof(WCHAR) ); 01073 rc = MsiSummaryInfoGetPropertyW( suminfo, PID_REVNUMBER, NULL, 01074 NULL, NULL, package_code, &len ); 01075 if (rc != ERROR_SUCCESS) 01076 { 01077 WARN("Unable to query rev number: %d\n", rc); 01078 goto done; 01079 } 01080 01081 msi_set_property( package->db, szPackageCode, package_code ); 01082 msi_free( package_code ); 01083 01084 /* load package attributes */ 01085 count = 0; 01086 MsiSummaryInfoGetPropertyW( suminfo, PID_WORDCOUNT, NULL, 01087 &count, NULL, NULL, NULL ); 01088 package->WordCount = count; 01089 01090 done: 01091 MsiCloseHandle(suminfo); 01092 return rc; 01093 } 01094 01095 static MSIPACKAGE *msi_alloc_package( void ) 01096 { 01097 MSIPACKAGE *package; 01098 01099 package = alloc_msiobject( MSIHANDLETYPE_PACKAGE, sizeof (MSIPACKAGE), 01100 MSI_FreePackage ); 01101 if( package ) 01102 { 01103 list_init( &package->components ); 01104 list_init( &package->features ); 01105 list_init( &package->files ); 01106 list_init( &package->filepatches ); 01107 list_init( &package->tempfiles ); 01108 list_init( &package->folders ); 01109 list_init( &package->subscriptions ); 01110 list_init( &package->appids ); 01111 list_init( &package->classes ); 01112 list_init( &package->mimes ); 01113 list_init( &package->extensions ); 01114 list_init( &package->progids ); 01115 list_init( &package->RunningActions ); 01116 list_init( &package->sourcelist_info ); 01117 list_init( &package->sourcelist_media ); 01118 list_init( &package->patches ); 01119 list_init( &package->binaries ); 01120 list_init( &package->cabinet_streams ); 01121 } 01122 01123 return package; 01124 } 01125 01126 static UINT msi_load_admin_properties(MSIPACKAGE *package) 01127 { 01128 BYTE *data; 01129 UINT r, sz; 01130 01131 static const WCHAR stmname[] = {'A','d','m','i','n','P','r','o','p','e','r','t','i','e','s',0}; 01132 01133 r = read_stream_data(package->db->storage, stmname, FALSE, &data, &sz); 01134 if (r != ERROR_SUCCESS) 01135 return r; 01136 01137 r = msi_parse_command_line(package, (WCHAR *)data, TRUE); 01138 01139 msi_free(data); 01140 return r; 01141 } 01142 01143 void msi_adjust_privilege_properties( MSIPACKAGE *package ) 01144 { 01145 /* FIXME: this should depend on the user's privileges */ 01146 if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2) 01147 { 01148 TRACE("resetting ALLUSERS property from 2 to 1\n"); 01149 msi_set_property( package->db, szAllUsers, szOne ); 01150 } 01151 msi_set_property( package->db, szAdminUser, szOne ); 01152 } 01153 01154 MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) 01155 { 01156 static const WCHAR fmtW[] = {'%','u',0}; 01157 MSIPACKAGE *package; 01158 WCHAR uilevel[11]; 01159 UINT r; 01160 01161 TRACE("%p\n", db); 01162 01163 package = msi_alloc_package(); 01164 if (package) 01165 { 01166 msiobj_addref( &db->hdr ); 01167 package->db = db; 01168 01169 package->WordCount = 0; 01170 package->PackagePath = strdupW( db->path ); 01171 package->BaseURL = strdupW( base_url ); 01172 01173 create_temp_property_table( package ); 01174 msi_clone_properties( package ); 01175 msi_adjust_privilege_properties( package ); 01176 01177 package->ProductCode = msi_dup_property( package->db, szProductCode ); 01178 package->script = msi_alloc_zero( sizeof(MSISCRIPT) ); 01179 01180 set_installed_prop( package ); 01181 set_installer_properties( package ); 01182 01183 package->ui_level = gUILevel; 01184 sprintfW( uilevel, fmtW, gUILevel & INSTALLUILEVEL_MASK ); 01185 msi_set_property(package->db, szUILevel, uilevel); 01186 01187 r = msi_load_summary_properties( package ); 01188 if (r != ERROR_SUCCESS) 01189 { 01190 msiobj_release( &package->hdr ); 01191 return NULL; 01192 } 01193 01194 if (package->WordCount & msidbSumInfoSourceTypeAdminImage) 01195 msi_load_admin_properties( package ); 01196 01197 package->log_file = INVALID_HANDLE_VALUE; 01198 } 01199 return package; 01200 } 01201 01202 UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ) 01203 { 01204 LPINTERNET_CACHE_ENTRY_INFOW cache_entry; 01205 DWORD size = 0; 01206 HRESULT hr; 01207 01208 /* call will always fail, because size is 0, 01209 * but will return ERROR_FILE_NOT_FOUND first 01210 * if the file doesn't exist 01211 */ 01212 GetUrlCacheEntryInfoW( szUrl, NULL, &size ); 01213 if ( GetLastError() != ERROR_FILE_NOT_FOUND ) 01214 { 01215 cache_entry = msi_alloc( size ); 01216 if ( !GetUrlCacheEntryInfoW( szUrl, cache_entry, &size ) ) 01217 { 01218 UINT error = GetLastError(); 01219 msi_free( cache_entry ); 01220 return error; 01221 } 01222 01223 lstrcpyW( filename, cache_entry->lpszLocalFileName ); 01224 msi_free( cache_entry ); 01225 return ERROR_SUCCESS; 01226 } 01227 01228 hr = URLDownloadToCacheFileW( NULL, szUrl, filename, MAX_PATH, 0, NULL ); 01229 if ( FAILED(hr) ) 01230 { 01231 WARN("failed to download %s to cache file\n", debugstr_w(szUrl)); 01232 return ERROR_FUNCTION_FAILED; 01233 } 01234 01235 return ERROR_SUCCESS; 01236 } 01237 01238 UINT msi_create_empty_local_file( LPWSTR path, LPCWSTR suffix ) 01239 { 01240 static const WCHAR szInstaller[] = { 01241 '\\','I','n','s','t','a','l','l','e','r','\\',0}; 01242 static const WCHAR fmt[] = {'%','x',0}; 01243 DWORD time, len, i, offset; 01244 HANDLE handle; 01245 01246 time = GetTickCount(); 01247 GetWindowsDirectoryW( path, MAX_PATH ); 01248 strcatW( path, szInstaller ); 01249 CreateDirectoryW( path, NULL ); 01250 01251 len = strlenW(path); 01252 for (i = 0; i < 0x10000; i++) 01253 { 01254 offset = snprintfW( path + len, MAX_PATH - len, fmt, (time + i) & 0xffff ); 01255 memcpy( path + len + offset, suffix, (strlenW( suffix ) + 1) * sizeof(WCHAR) ); 01256 handle = CreateFileW( path, GENERIC_WRITE, 0, NULL, 01257 CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); 01258 if (handle != INVALID_HANDLE_VALUE) 01259 { 01260 CloseHandle(handle); 01261 break; 01262 } 01263 if (GetLastError() != ERROR_FILE_EXISTS && 01264 GetLastError() != ERROR_SHARING_VIOLATION) 01265 return ERROR_FUNCTION_FAILED; 01266 } 01267 01268 return ERROR_SUCCESS; 01269 } 01270 01271 static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package ) 01272 { 01273 WCHAR *template, *p, *q; 01274 DWORD i, count; 01275 01276 package->version = msi_suminfo_get_int32( si, PID_PAGECOUNT ); 01277 TRACE("version: %d\n", package->version); 01278 01279 template = msi_suminfo_dup_string( si, PID_TEMPLATE ); 01280 if (!template) 01281 return ERROR_SUCCESS; /* native accepts missing template property */ 01282 01283 TRACE("template: %s\n", debugstr_w(template)); 01284 01285 p = strchrW( template, ';' ); 01286 if (!p) 01287 { 01288 WARN("invalid template string %s\n", debugstr_w(template)); 01289 msi_free( template ); 01290 return ERROR_PATCH_PACKAGE_INVALID; 01291 } 01292 *p = 0; 01293 if ((q = strchrW( template, ',' ))) *q = 0; 01294 if (!template[0] || !strcmpW( template, szIntel )) 01295 package->platform = PLATFORM_INTEL; 01296 else if (!strcmpW( template, szIntel64 )) 01297 package->platform = PLATFORM_INTEL64; 01298 else if (!strcmpW( template, szX64 ) || !strcmpW( template, szAMD64 )) 01299 package->platform = PLATFORM_X64; 01300 else if (!strcmpW( template, szARM )) 01301 package->platform = PLATFORM_ARM; 01302 else 01303 { 01304 WARN("unknown platform %s\n", debugstr_w(template)); 01305 msi_free( template ); 01306 return ERROR_INSTALL_PLATFORM_UNSUPPORTED; 01307 } 01308 p++; 01309 if (!*p) 01310 { 01311 msi_free( template ); 01312 return ERROR_SUCCESS; 01313 } 01314 count = 1; 01315 for (q = p; (q = strchrW( q, ',' )); q++) count++; 01316 01317 package->langids = msi_alloc( count * sizeof(LANGID) ); 01318 if (!package->langids) 01319 { 01320 msi_free( template ); 01321 return ERROR_OUTOFMEMORY; 01322 } 01323 01324 i = 0; 01325 while (*p) 01326 { 01327 q = strchrW( p, ',' ); 01328 if (q) *q = 0; 01329 package->langids[i] = atoiW( p ); 01330 if (!q) break; 01331 p = q + 1; 01332 i++; 01333 } 01334 package->num_langids = i + 1; 01335 01336 msi_free( template ); 01337 return ERROR_SUCCESS; 01338 } 01339 01340 static UINT validate_package( MSIPACKAGE *package ) 01341 { 01342 BOOL is_wow64; 01343 UINT i; 01344 01345 if (package->platform == PLATFORM_INTEL64) 01346 return ERROR_INSTALL_PLATFORM_UNSUPPORTED; 01347 #ifndef __arm__ 01348 if (package->platform == PLATFORM_ARM) 01349 return ERROR_INSTALL_PLATFORM_UNSUPPORTED; 01350 #endif 01351 IsWow64Process( GetCurrentProcess(), &is_wow64 ); 01352 if (package->platform == PLATFORM_X64) 01353 { 01354 if (!is_64bit && !is_wow64) 01355 return ERROR_INSTALL_PLATFORM_UNSUPPORTED; 01356 if (package->version < 200) 01357 return ERROR_INSTALL_PACKAGE_INVALID; 01358 } 01359 if (!package->num_langids) 01360 { 01361 return ERROR_SUCCESS; 01362 } 01363 for (i = 0; i < package->num_langids; i++) 01364 { 01365 LANGID langid = package->langids[i]; 01366 01367 if (PRIMARYLANGID( langid ) == LANG_NEUTRAL) 01368 { 01369 langid = MAKELANGID( PRIMARYLANGID( GetSystemDefaultLangID() ), SUBLANGID( langid ) ); 01370 } 01371 if (SUBLANGID( langid ) == SUBLANG_NEUTRAL) 01372 { 01373 langid = MAKELANGID( PRIMARYLANGID( langid ), SUBLANGID( GetSystemDefaultLangID() ) ); 01374 } 01375 if (IsValidLocale( langid, LCID_INSTALLED )) 01376 return ERROR_SUCCESS; 01377 } 01378 return ERROR_INSTALL_LANGUAGE_UNSUPPORTED; 01379 } 01380 01381 int msi_track_tempfile( MSIPACKAGE *package, const WCHAR *path ) 01382 { 01383 MSITEMPFILE *temp; 01384 01385 TRACE("%s\n", debugstr_w(path)); 01386 01387 LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry ) 01388 { 01389 if (!strcmpW( path, temp->Path )) return 0; 01390 } 01391 if (!(temp = msi_alloc_zero( sizeof (MSITEMPFILE) ))) return -1; 01392 list_add_head( &package->tempfiles, &temp->entry ); 01393 temp->Path = strdupW( path ); 01394 return 0; 01395 } 01396 01397 static WCHAR *get_product_code( MSIDATABASE *db ) 01398 { 01399 static const WCHAR query[] = { 01400 'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ', 01401 'F','R','O','M',' ','`','P','r','o','p','e','r','t','y','`',' ', 01402 'W','H','E','R','E',' ','`','P','r','o','p','e','r','t','y','`','=', 01403 '\'','P','r','o','d','u','c','t','C','o','d','e','\'',0}; 01404 MSIQUERY *view; 01405 MSIRECORD *rec; 01406 WCHAR *ret = NULL; 01407 01408 if (MSI_DatabaseOpenViewW( db, query, &view ) != ERROR_SUCCESS) 01409 { 01410 return NULL; 01411 } 01412 if (MSI_ViewExecute( view, 0 ) != ERROR_SUCCESS) 01413 { 01414 MSI_ViewClose( view ); 01415 msiobj_release( &view->hdr ); 01416 return NULL; 01417 } 01418 if (MSI_ViewFetch( view, &rec ) == ERROR_SUCCESS) 01419 { 01420 ret = strdupW( MSI_RecordGetString( rec, 1 ) ); 01421 msiobj_release( &rec->hdr ); 01422 } 01423 MSI_ViewClose( view ); 01424 msiobj_release( &view->hdr ); 01425 return ret; 01426 } 01427 01428 static UINT get_registered_local_package( const WCHAR *product, const WCHAR *package, WCHAR *localfile ) 01429 { 01430 MSIINSTALLCONTEXT context; 01431 HKEY product_key, props_key; 01432 WCHAR *registered_package = NULL, unsquashed[GUID_SIZE]; 01433 UINT r; 01434 01435 r = msi_locate_product( product, &context ); 01436 if (r != ERROR_SUCCESS) 01437 return r; 01438 01439 r = MSIREG_OpenProductKey( product, NULL, context, &product_key, FALSE ); 01440 if (r != ERROR_SUCCESS) 01441 return r; 01442 01443 r = MSIREG_OpenInstallProps( product, context, NULL, &props_key, FALSE ); 01444 if (r != ERROR_SUCCESS) 01445 { 01446 RegCloseKey( product_key ); 01447 return r; 01448 } 01449 r = ERROR_FUNCTION_FAILED; 01450 registered_package = msi_reg_get_val_str( product_key, INSTALLPROPERTY_PACKAGECODEW ); 01451 if (!registered_package) 01452 goto done; 01453 01454 unsquash_guid( registered_package, unsquashed ); 01455 if (!strcmpiW( package, unsquashed )) 01456 { 01457 WCHAR *filename = msi_reg_get_val_str( props_key, INSTALLPROPERTY_LOCALPACKAGEW ); 01458 if (!filename) 01459 goto done; 01460 01461 strcpyW( localfile, filename ); 01462 msi_free( filename ); 01463 r = ERROR_SUCCESS; 01464 } 01465 done: 01466 msi_free( registered_package ); 01467 RegCloseKey( props_key ); 01468 RegCloseKey( product_key ); 01469 return r; 01470 } 01471 01472 static WCHAR *get_package_code( MSIDATABASE *db ) 01473 { 01474 WCHAR *ret; 01475 MSISUMMARYINFO *si; 01476 01477 if (!(si = MSI_GetSummaryInformationW( db->storage, 0 ))) 01478 { 01479 WARN("failed to load summary info\n"); 01480 return NULL; 01481 } 01482 ret = msi_suminfo_dup_string( si, PID_REVNUMBER ); 01483 msiobj_release( &si->hdr ); 01484 return ret; 01485 } 01486 01487 static UINT get_local_package( const WCHAR *filename, WCHAR *localfile ) 01488 { 01489 WCHAR *product_code, *package_code; 01490 MSIDATABASE *db; 01491 UINT r; 01492 01493 if ((r = MSI_OpenDatabaseW( filename, MSIDBOPEN_READONLY, &db )) != ERROR_SUCCESS) 01494 { 01495 if (GetFileAttributesW( filename ) == INVALID_FILE_ATTRIBUTES) 01496 return ERROR_FILE_NOT_FOUND; 01497 return r; 01498 } 01499 if (!(product_code = get_product_code( db ))) 01500 { 01501 msiobj_release( &db->hdr ); 01502 return ERROR_INSTALL_PACKAGE_INVALID; 01503 } 01504 if (!(package_code = get_package_code( db ))) 01505 { 01506 msi_free( product_code ); 01507 msiobj_release( &db->hdr ); 01508 return ERROR_INSTALL_PACKAGE_INVALID; 01509 } 01510 r = get_registered_local_package( product_code, package_code, localfile ); 01511 msi_free( package_code ); 01512 msi_free( product_code ); 01513 msiobj_release( &db->hdr ); 01514 return r; 01515 } 01516 01517 UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) 01518 { 01519 static const WCHAR dotmsi[] = {'.','m','s','i',0}; 01520 MSIDATABASE *db; 01521 MSIPACKAGE *package; 01522 MSIHANDLE handle; 01523 LPWSTR ptr, base_url = NULL; 01524 UINT r; 01525 WCHAR localfile[MAX_PATH], cachefile[MAX_PATH]; 01526 LPCWSTR file = szPackage; 01527 DWORD index = 0; 01528 MSISUMMARYINFO *si; 01529 BOOL delete_on_close = FALSE; 01530 01531 TRACE("%s %p\n", debugstr_w(szPackage), pPackage); 01532 01533 localfile[0] = 0; 01534 if( szPackage[0] == '#' ) 01535 { 01536 handle = atoiW(&szPackage[1]); 01537 db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ); 01538 if( !db ) 01539 { 01540 IWineMsiRemoteDatabase *remote_database; 01541 01542 remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle ); 01543 if ( !remote_database ) 01544 return ERROR_INVALID_HANDLE; 01545 01546 IWineMsiRemoteDatabase_Release( remote_database ); 01547 WARN("MsiOpenPackage not allowed during a custom action!\n"); 01548 01549 return ERROR_FUNCTION_FAILED; 01550 } 01551 } 01552 else 01553 { 01554 if ( UrlIsW( szPackage, URLIS_URL ) ) 01555 { 01556 r = msi_download_file( szPackage, cachefile ); 01557 if (r != ERROR_SUCCESS) 01558 return r; 01559 01560 file = cachefile; 01561 01562 base_url = strdupW( szPackage ); 01563 if (!base_url) 01564 return ERROR_OUTOFMEMORY; 01565 01566 ptr = strrchrW( base_url, '/' ); 01567 if (ptr) *(ptr + 1) = '\0'; 01568 } 01569 r = get_local_package( file, localfile ); 01570 if (r != ERROR_SUCCESS || GetFileAttributesW( localfile ) == INVALID_FILE_ATTRIBUTES) 01571 { 01572 r = msi_create_empty_local_file( localfile, dotmsi ); 01573 if (r != ERROR_SUCCESS) 01574 return r; 01575 01576 if (!CopyFileW( file, localfile, FALSE )) 01577 { 01578 r = GetLastError(); 01579 WARN("unable to copy package %s to %s (%u)\n", debugstr_w(file), debugstr_w(localfile), r); 01580 DeleteFileW( localfile ); 01581 return r; 01582 } 01583 delete_on_close = TRUE; 01584 } 01585 TRACE("opening package %s\n", debugstr_w( localfile )); 01586 r = MSI_OpenDatabaseW( localfile, MSIDBOPEN_TRANSACT, &db ); 01587 if (r != ERROR_SUCCESS) 01588 return r; 01589 } 01590 package = MSI_CreatePackage( db, base_url ); 01591 msi_free( base_url ); 01592 msiobj_release( &db->hdr ); 01593 if (!package) return ERROR_INSTALL_PACKAGE_INVALID; 01594 package->localfile = strdupW( localfile ); 01595 package->delete_on_close = delete_on_close; 01596 01597 si = MSI_GetSummaryInformationW( db->storage, 0 ); 01598 if (!si) 01599 { 01600 WARN("failed to load summary info\n"); 01601 msiobj_release( &package->hdr ); 01602 return ERROR_INSTALL_PACKAGE_INVALID; 01603 } 01604 r = msi_parse_summary( si, package ); 01605 msiobj_release( &si->hdr ); 01606 if (r != ERROR_SUCCESS) 01607 { 01608 WARN("failed to parse summary info %u\n", r); 01609 msiobj_release( &package->hdr ); 01610 return r; 01611 } 01612 r = validate_package( package ); 01613 if (r != ERROR_SUCCESS) 01614 { 01615 msiobj_release( &package->hdr ); 01616 return r; 01617 } 01618 msi_set_property( package->db, szDatabase, db->path ); 01619 01620 if( UrlIsW( szPackage, URLIS_URL ) ) 01621 msi_set_property( package->db, szOriginalDatabase, szPackage ); 01622 else if( szPackage[0] == '#' ) 01623 msi_set_property( package->db, szOriginalDatabase, db->path ); 01624 else 01625 { 01626 WCHAR fullpath[MAX_PATH]; 01627 01628 GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL ); 01629 msi_set_property( package->db, szOriginalDatabase, fullpath ); 01630 } 01631 msi_set_context( package ); 01632 01633 while (1) 01634 { 01635 WCHAR patch_code[GUID_SIZE]; 01636 r = MsiEnumPatchesExW( package->ProductCode, NULL, package->Context, 01637 MSIPATCHSTATE_APPLIED, index, patch_code, NULL, NULL, NULL, NULL ); 01638 if (r != ERROR_SUCCESS) 01639 break; 01640 01641 TRACE("found registered patch %s\n", debugstr_w(patch_code)); 01642 01643 r = msi_apply_registered_patch( package, patch_code ); 01644 if (r != ERROR_SUCCESS) 01645 { 01646 ERR("registered patch failed to apply %u\n", r); 01647 msiobj_release( &package->hdr ); 01648 return r; 01649 } 01650 index++; 01651 } 01652 if (index) 01653 { 01654 msi_clone_properties( package ); 01655 msi_adjust_privilege_properties( package ); 01656 } 01657 if (gszLogFile) 01658 package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, 01659 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 01660 *pPackage = package; 01661 return ERROR_SUCCESS; 01662 } 01663 01664 UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage) 01665 { 01666 MSIPACKAGE *package = NULL; 01667 UINT ret; 01668 01669 TRACE("%s %08x %p\n", debugstr_w(szPackage), dwOptions, phPackage ); 01670 01671 if( !szPackage || !phPackage ) 01672 return ERROR_INVALID_PARAMETER; 01673 01674 if ( !*szPackage ) 01675 { 01676 FIXME("Should create an empty database and package\n"); 01677 return ERROR_FUNCTION_FAILED; 01678 } 01679 01680 if( dwOptions ) 01681 FIXME("dwOptions %08x not supported\n", dwOptions); 01682 01683 ret = MSI_OpenPackageW( szPackage, &package ); 01684 if( ret == ERROR_SUCCESS ) 01685 { 01686 *phPackage = alloc_msihandle( &package->hdr ); 01687 if (! *phPackage) 01688 ret = ERROR_NOT_ENOUGH_MEMORY; 01689 msiobj_release( &package->hdr ); 01690 } 01691 01692 return ret; 01693 } 01694 01695 UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage) 01696 { 01697 return MsiOpenPackageExW( szPackage, 0, phPackage ); 01698 } 01699 01700 UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage) 01701 { 01702 LPWSTR szwPack = NULL; 01703 UINT ret; 01704 01705 if( szPackage ) 01706 { 01707 szwPack = strdupAtoW( szPackage ); 01708 if( !szwPack ) 01709 return ERROR_OUTOFMEMORY; 01710 } 01711 01712 ret = MsiOpenPackageExW( szwPack, dwOptions, phPackage ); 01713 01714 msi_free( szwPack ); 01715 01716 return ret; 01717 } 01718 01719 UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage) 01720 { 01721 return MsiOpenPackageExA( szPackage, 0, phPackage ); 01722 } 01723 01724 MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall) 01725 { 01726 MSIPACKAGE *package; 01727 MSIHANDLE handle = 0; 01728 IUnknown *remote_unk; 01729 IWineMsiRemotePackage *remote_package; 01730 01731 TRACE("(%d)\n",hInstall); 01732 01733 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); 01734 if( package) 01735 { 01736 handle = alloc_msihandle( &package->db->hdr ); 01737 msiobj_release( &package->hdr ); 01738 } 01739 else if ((remote_unk = msi_get_remote(hInstall))) 01740 { 01741 if (IUnknown_QueryInterface(remote_unk, &IID_IWineMsiRemotePackage, 01742 (LPVOID *)&remote_package) == S_OK) 01743 { 01744 IWineMsiRemotePackage_GetActiveDatabase(remote_package, &handle); 01745 IWineMsiRemotePackage_Release(remote_package); 01746 } 01747 else 01748 { 01749 WARN("remote handle %d is not a package\n", hInstall); 01750 } 01751 IUnknown_Release(remote_unk); 01752 } 01753 01754 return handle; 01755 } 01756 01757 INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record ) 01758 { 01759 static const WCHAR szActionData[] = {'A','c','t','i','o','n','D','a','t','a',0}; 01760 static const WCHAR szSetProgress[] = {'S','e','t','P','r','o','g','r','e','s','s',0}; 01761 static const WCHAR szActionText[] = {'A','c','t','i','o','n','T','e','x','t',0}; 01762 MSIRECORD *uirow; 01763 LPWSTR deformated, message; 01764 DWORD i, len, total_len, log_type = 0; 01765 INT rc = 0; 01766 char *msg; 01767 01768 TRACE("%x\n", eMessageType); 01769 01770 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_FATALEXIT) 01771 log_type |= INSTALLLOGMODE_FATALEXIT; 01772 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ERROR) 01773 log_type |= INSTALLLOGMODE_ERROR; 01774 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_WARNING) 01775 log_type |= INSTALLLOGMODE_WARNING; 01776 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_USER) 01777 log_type |= INSTALLLOGMODE_USER; 01778 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_INFO) 01779 log_type |= INSTALLLOGMODE_INFO; 01780 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_RESOLVESOURCE) 01781 log_type |= INSTALLLOGMODE_RESOLVESOURCE; 01782 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_OUTOFDISKSPACE) 01783 log_type |= INSTALLLOGMODE_OUTOFDISKSPACE; 01784 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_COMMONDATA) 01785 log_type |= INSTALLLOGMODE_COMMONDATA; 01786 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONSTART) 01787 log_type |= INSTALLLOGMODE_ACTIONSTART; 01788 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONDATA) 01789 log_type |= INSTALLLOGMODE_ACTIONDATA; 01790 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_PROGRESS) 01791 log_type |= INSTALLLOGMODE_PROGRESS; 01792 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_INITIALIZE) 01793 log_type |= INSTALLLOGMODE_INITIALIZE; 01794 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_TERMINATE) 01795 log_type |= INSTALLLOGMODE_TERMINATE; 01796 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_SHOWDIALOG) 01797 log_type |= INSTALLLOGMODE_SHOWDIALOG; 01798 01799 if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONSTART) 01800 { 01801 static const WCHAR template_s[]= 01802 {'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ',0}; 01803 static const WCHAR format[] = 01804 {'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0}; 01805 WCHAR timet[0x100]; 01806 LPCWSTR action_text, action; 01807 LPWSTR deformatted = NULL; 01808 01809 GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100); 01810 01811 action = MSI_RecordGetString(record, 1); 01812 action_text = MSI_RecordGetString(record, 2); 01813 01814 if (!action || !action_text) 01815 return IDOK; 01816 01817 deformat_string(package, action_text, &deformatted); 01818 01819 len = strlenW(timet) + strlenW(action) + strlenW(template_s); 01820 if (deformatted) 01821 len += strlenW(deformatted); 01822 message = msi_alloc(len*sizeof(WCHAR)); 01823 sprintfW(message, template_s, timet, action); 01824 if (deformatted) 01825 strcatW(message, deformatted); 01826 msi_free(deformatted); 01827 } 01828 else 01829 { 01830 static const WCHAR format[] = {'%','u',':',' ',0}; 01831 UINT count = MSI_RecordGetFieldCount( record ); 01832 WCHAR *p; 01833 01834 total_len = 1; 01835 for (i = 1; i <= count; i++) 01836 { 01837 len = 0; 01838 MSI_RecordGetStringW( record, i, NULL, &len ); 01839 total_len += len + 13; 01840 } 01841 p = message = msi_alloc( total_len * sizeof(WCHAR) ); 01842 if (!p) return ERROR_OUTOFMEMORY; 01843 01844 for (i = 1; i <= count; i++) 01845 { 01846 if (count > 1) 01847 { 01848 len = sprintfW( p, format, i ); 01849 total_len -= len; 01850 p += len; 01851 } 01852 len = total_len; 01853 MSI_RecordGetStringW( record, i, p, &len ); 01854 total_len -= len; 01855 p += len; 01856 if (count > 1 && total_len) 01857 { 01858 *p++ = ' '; 01859 total_len--; 01860 } 01861 } 01862 p[0] = 0; 01863 } 01864 01865 TRACE("%p %p %p %x %x %s\n", gUIHandlerA, gUIHandlerW, gUIHandlerRecord, 01866 gUIFilter, log_type, debugstr_w(message)); 01867 01868 /* convert it to ASCII */ 01869 len = WideCharToMultiByte( CP_ACP, 0, message, -1, NULL, 0, NULL, NULL ); 01870 msg = msi_alloc( len ); 01871 WideCharToMultiByte( CP_ACP, 0, message, -1, msg, len, NULL, NULL ); 01872 01873 if (gUIHandlerW && (gUIFilter & log_type)) 01874 { 01875 rc = gUIHandlerW( gUIContext, eMessageType, message ); 01876 } 01877 else if (gUIHandlerA && (gUIFilter & log_type)) 01878 { 01879 rc = gUIHandlerA( gUIContext, eMessageType, msg ); 01880 } 01881 else if (gUIHandlerRecord && (gUIFilter & log_type)) 01882 { 01883 MSIHANDLE rec = MsiCreateRecord( 1 ); 01884 MsiRecordSetStringW( rec, 0, message ); 01885 rc = gUIHandlerRecord( gUIContext, eMessageType, rec ); 01886 MsiCloseHandle( rec ); 01887 } 01888 01889 if (!rc && package->log_file != INVALID_HANDLE_VALUE && 01890 (eMessageType & 0xff000000) != INSTALLMESSAGE_PROGRESS) 01891 { 01892 DWORD written; 01893 WriteFile( package->log_file, msg, len - 1, &written, NULL ); 01894 WriteFile( package->log_file, "\n", 1, &written, NULL ); 01895 } 01896 msi_free( msg ); 01897 msi_free( message ); 01898 01899 switch (eMessageType & 0xff000000) 01900 { 01901 case INSTALLMESSAGE_ACTIONDATA: 01902 deformat_string(package, MSI_RecordGetString(record, 2), &deformated); 01903 uirow = MSI_CreateRecord(1); 01904 MSI_RecordSetStringW(uirow, 1, deformated); 01905 msi_free(deformated); 01906 01907 ControlEvent_FireSubscribedEvent(package, szActionData, uirow); 01908 01909 msiobj_release(&uirow->hdr); 01910 break; 01911 01912 case INSTALLMESSAGE_ACTIONSTART: 01913 deformat_string(package, MSI_RecordGetString(record, 2), &deformated); 01914 uirow = MSI_CreateRecord(1); 01915 MSI_RecordSetStringW(uirow, 1, deformated); 01916 msi_free(deformated); 01917 01918 ControlEvent_FireSubscribedEvent(package, szActionText, uirow); 01919 01920 msiobj_release(&uirow->hdr); 01921 break; 01922 01923 case INSTALLMESSAGE_PROGRESS: 01924 ControlEvent_FireSubscribedEvent(package, szSetProgress, record); 01925 break; 01926 } 01927 01928 return ERROR_SUCCESS; 01929 } 01930 01931 INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType, 01932 MSIHANDLE hRecord) 01933 { 01934 UINT ret = ERROR_INVALID_HANDLE; 01935 MSIPACKAGE *package = NULL; 01936 MSIRECORD *record = NULL; 01937 01938 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 01939 if( !package ) 01940 { 01941 HRESULT hr; 01942 IWineMsiRemotePackage *remote_package; 01943 01944 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 01945 if (!remote_package) 01946 return ERROR_INVALID_HANDLE; 01947 01948 hr = IWineMsiRemotePackage_ProcessMessage( remote_package, eMessageType, hRecord ); 01949 01950 IWineMsiRemotePackage_Release( remote_package ); 01951 01952 if (FAILED(hr)) 01953 { 01954 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 01955 return HRESULT_CODE(hr); 01956 01957 return ERROR_FUNCTION_FAILED; 01958 } 01959 01960 return ERROR_SUCCESS; 01961 } 01962 01963 record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD ); 01964 if( !record ) 01965 goto out; 01966 01967 ret = MSI_ProcessMessage( package, eMessageType, record ); 01968 01969 out: 01970 msiobj_release( &package->hdr ); 01971 if( record ) 01972 msiobj_release( &record->hdr ); 01973 01974 return ret; 01975 } 01976 01977 /* property code */ 01978 01979 UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue ) 01980 { 01981 LPWSTR szwName = NULL, szwValue = NULL; 01982 UINT r = ERROR_OUTOFMEMORY; 01983 01984 szwName = strdupAtoW( szName ); 01985 if( szName && !szwName ) 01986 goto end; 01987 01988 szwValue = strdupAtoW( szValue ); 01989 if( szValue && !szwValue ) 01990 goto end; 01991 01992 r = MsiSetPropertyW( hInstall, szwName, szwValue); 01993 01994 end: 01995 msi_free( szwName ); 01996 msi_free( szwValue ); 01997 01998 return r; 01999 } 02000 02001 void msi_reset_folders( MSIPACKAGE *package, BOOL source ) 02002 { 02003 MSIFOLDER *folder; 02004 02005 LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry ) 02006 { 02007 if ( source ) 02008 { 02009 msi_free( folder->ResolvedSource ); 02010 folder->ResolvedSource = NULL; 02011 } 02012 else 02013 { 02014 msi_free( folder->ResolvedTarget ); 02015 folder->ResolvedTarget = NULL; 02016 } 02017 } 02018 } 02019 02020 UINT msi_set_property( MSIDATABASE *db, LPCWSTR szName, LPCWSTR szValue ) 02021 { 02022 static const WCHAR insert_query[] = { 02023 'I','N','S','E','R','T',' ','I','N','T','O',' ', 02024 '`','_','P','r','o','p','e','r','t','y','`',' ', 02025 '(','`','_','P','r','o','p','e','r','t','y','`',',','`','V','a','l','u','e','`',')',' ', 02026 'V','A','L','U','E','S',' ','(','?',',','?',')',0}; 02027 static const WCHAR update_query[] = { 02028 'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ', 02029 'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ','W','H','E','R','E',' ', 02030 '`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0}; 02031 static const WCHAR delete_query[] = { 02032 'D','E','L','E','T','E',' ','F','R','O','M',' ', 02033 '`','_','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ', 02034 '`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0}; 02035 MSIQUERY *view; 02036 MSIRECORD *row = NULL; 02037 DWORD sz = 0; 02038 WCHAR query[1024]; 02039 UINT rc; 02040 02041 TRACE("%p %s %s\n", db, debugstr_w(szName), debugstr_w(szValue)); 02042 02043 if (!szName) 02044 return ERROR_INVALID_PARAMETER; 02045 02046 /* this one is weird... */ 02047 if (!szName[0]) 02048 return szValue ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS; 02049 02050 rc = msi_get_property(db, szName, 0, &sz); 02051 if (!szValue || !*szValue) 02052 { 02053 sprintfW(query, delete_query, szName); 02054 } 02055 else if (rc == ERROR_MORE_DATA || rc == ERROR_SUCCESS) 02056 { 02057 sprintfW(query, update_query, szName); 02058 02059 row = MSI_CreateRecord(1); 02060 MSI_RecordSetStringW(row, 1, szValue); 02061 } 02062 else 02063 { 02064 strcpyW(query, insert_query); 02065 02066 row = MSI_CreateRecord(2); 02067 MSI_RecordSetStringW(row, 1, szName); 02068 MSI_RecordSetStringW(row, 2, szValue); 02069 } 02070 02071 rc = MSI_DatabaseOpenViewW(db, query, &view); 02072 if (rc == ERROR_SUCCESS) 02073 { 02074 rc = MSI_ViewExecute(view, row); 02075 MSI_ViewClose(view); 02076 msiobj_release(&view->hdr); 02077 } 02078 if (row) msiobj_release(&row->hdr); 02079 return rc; 02080 } 02081 02082 UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue) 02083 { 02084 MSIPACKAGE *package; 02085 UINT ret; 02086 02087 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); 02088 if( !package ) 02089 { 02090 HRESULT hr; 02091 BSTR name = NULL, value = NULL; 02092 IWineMsiRemotePackage *remote_package; 02093 02094 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 02095 if (!remote_package) 02096 return ERROR_INVALID_HANDLE; 02097 02098 name = SysAllocString( szName ); 02099 value = SysAllocString( szValue ); 02100 if ((!name && szName) || (!value && szValue)) 02101 { 02102 SysFreeString( name ); 02103 SysFreeString( value ); 02104 IWineMsiRemotePackage_Release( remote_package ); 02105 return ERROR_OUTOFMEMORY; 02106 } 02107 02108 hr = IWineMsiRemotePackage_SetProperty( remote_package, name, value ); 02109 02110 SysFreeString( name ); 02111 SysFreeString( value ); 02112 IWineMsiRemotePackage_Release( remote_package ); 02113 02114 if (FAILED(hr)) 02115 { 02116 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 02117 return HRESULT_CODE(hr); 02118 02119 return ERROR_FUNCTION_FAILED; 02120 } 02121 02122 return ERROR_SUCCESS; 02123 } 02124 02125 ret = msi_set_property( package->db, szName, szValue ); 02126 if (ret == ERROR_SUCCESS && !strcmpW( szName, szSourceDir )) 02127 msi_reset_folders( package, TRUE ); 02128 02129 msiobj_release( &package->hdr ); 02130 return ret; 02131 } 02132 02133 static MSIRECORD *msi_get_property_row( MSIDATABASE *db, LPCWSTR name ) 02134 { 02135 static const WCHAR query[]= { 02136 'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ', 02137 'F','R','O','M',' ' ,'`','_','P','r','o','p','e','r','t','y','`',' ', 02138 'W','H','E','R','E',' ' ,'`','_','P','r','o','p','e','r','t','y','`','=','?',0}; 02139 MSIRECORD *rec, *row = NULL; 02140 MSIQUERY *view; 02141 UINT r; 02142 02143 if (!name || !*name) 02144 return NULL; 02145 02146 rec = MSI_CreateRecord(1); 02147 if (!rec) 02148 return NULL; 02149 02150 MSI_RecordSetStringW(rec, 1, name); 02151 02152 r = MSI_DatabaseOpenViewW(db, query, &view); 02153 if (r == ERROR_SUCCESS) 02154 { 02155 MSI_ViewExecute(view, rec); 02156 MSI_ViewFetch(view, &row); 02157 MSI_ViewClose(view); 02158 msiobj_release(&view->hdr); 02159 } 02160 msiobj_release(&rec->hdr); 02161 return row; 02162 } 02163 02164 /* internal function, not compatible with MsiGetPropertyW */ 02165 UINT msi_get_property( MSIDATABASE *db, LPCWSTR szName, 02166 LPWSTR szValueBuf, LPDWORD pchValueBuf ) 02167 { 02168 MSIRECORD *row; 02169 UINT rc = ERROR_FUNCTION_FAILED; 02170 02171 row = msi_get_property_row( db, szName ); 02172 02173 if (*pchValueBuf > 0) 02174 szValueBuf[0] = 0; 02175 02176 if (row) 02177 { 02178 rc = MSI_RecordGetStringW(row, 1, szValueBuf, pchValueBuf); 02179 msiobj_release(&row->hdr); 02180 } 02181 02182 if (rc == ERROR_SUCCESS) 02183 TRACE("returning %s for property %s\n", debugstr_w(szValueBuf), 02184 debugstr_w(szName)); 02185 else if (rc == ERROR_MORE_DATA) 02186 TRACE("need %d sized buffer for %s\n", *pchValueBuf, 02187 debugstr_w(szName)); 02188 else 02189 { 02190 *pchValueBuf = 0; 02191 TRACE("property %s not found\n", debugstr_w(szName)); 02192 } 02193 02194 return rc; 02195 } 02196 02197 LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop) 02198 { 02199 DWORD sz = 0; 02200 LPWSTR str; 02201 UINT r; 02202 02203 r = msi_get_property(db, prop, NULL, &sz); 02204 if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA) 02205 return NULL; 02206 02207 sz++; 02208 str = msi_alloc(sz * sizeof(WCHAR)); 02209 r = msi_get_property(db, prop, str, &sz); 02210 if (r != ERROR_SUCCESS) 02211 { 02212 msi_free(str); 02213 str = NULL; 02214 } 02215 02216 return str; 02217 } 02218 02219 int msi_get_property_int( MSIDATABASE *db, LPCWSTR prop, int def ) 02220 { 02221 LPWSTR str = msi_dup_property( db, prop ); 02222 int val = str ? atoiW(str) : def; 02223 msi_free(str); 02224 return val; 02225 } 02226 02227 static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name, 02228 awstring *szValueBuf, LPDWORD pchValueBuf ) 02229 { 02230 MSIPACKAGE *package; 02231 MSIRECORD *row = NULL; 02232 UINT r = ERROR_FUNCTION_FAILED; 02233 LPCWSTR val = NULL; 02234 02235 TRACE("%u %s %p %p\n", handle, debugstr_w(name), 02236 szValueBuf->str.w, pchValueBuf ); 02237 02238 if (!name) 02239 return ERROR_INVALID_PARAMETER; 02240 02241 package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ); 02242 if (!package) 02243 { 02244 HRESULT hr; 02245 IWineMsiRemotePackage *remote_package; 02246 LPWSTR value = NULL; 02247 BSTR bname; 02248 DWORD len; 02249 02250 remote_package = (IWineMsiRemotePackage *)msi_get_remote( handle ); 02251 if (!remote_package) 02252 return ERROR_INVALID_HANDLE; 02253 02254 bname = SysAllocString( name ); 02255 if (!bname) 02256 { 02257 IWineMsiRemotePackage_Release( remote_package ); 02258 return ERROR_OUTOFMEMORY; 02259 } 02260 02261 len = 0; 02262 hr = IWineMsiRemotePackage_GetProperty( remote_package, bname, NULL, &len ); 02263 if (FAILED(hr)) 02264 goto done; 02265 02266 len++; 02267 value = msi_alloc(len * sizeof(WCHAR)); 02268 if (!value) 02269 { 02270 r = ERROR_OUTOFMEMORY; 02271 goto done; 02272 } 02273 02274 hr = IWineMsiRemotePackage_GetProperty( remote_package, bname, value, &len ); 02275 if (FAILED(hr)) 02276 goto done; 02277 02278 r = msi_strcpy_to_awstring( value, szValueBuf, pchValueBuf ); 02279 02280 /* Bug required by Adobe installers */ 02281 if (!szValueBuf->unicode && !szValueBuf->str.a) 02282 *pchValueBuf *= sizeof(WCHAR); 02283 02284 done: 02285 IWineMsiRemotePackage_Release(remote_package); 02286 SysFreeString(bname); 02287 msi_free(value); 02288 02289 if (FAILED(hr)) 02290 { 02291 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 02292 return HRESULT_CODE(hr); 02293 02294 return ERROR_FUNCTION_FAILED; 02295 } 02296 02297 return r; 02298 } 02299 02300 row = msi_get_property_row( package->db, name ); 02301 if (row) 02302 val = MSI_RecordGetString( row, 1 ); 02303 02304 if (!val) 02305 val = szEmpty; 02306 02307 r = msi_strcpy_to_awstring( val, szValueBuf, pchValueBuf ); 02308 02309 if (row) 02310 msiobj_release( &row->hdr ); 02311 msiobj_release( &package->hdr ); 02312 02313 return r; 02314 } 02315 02316 UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName, 02317 LPSTR szValueBuf, LPDWORD pchValueBuf ) 02318 { 02319 awstring val; 02320 LPWSTR name; 02321 UINT r; 02322 02323 val.unicode = FALSE; 02324 val.str.a = szValueBuf; 02325 02326 name = strdupAtoW( szName ); 02327 if (szName && !name) 02328 return ERROR_OUTOFMEMORY; 02329 02330 r = MSI_GetProperty( hInstall, name, &val, pchValueBuf ); 02331 msi_free( name ); 02332 return r; 02333 } 02334 02335 UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, 02336 LPWSTR szValueBuf, LPDWORD pchValueBuf ) 02337 { 02338 awstring val; 02339 02340 val.unicode = TRUE; 02341 val.str.w = szValueBuf; 02342 02343 return MSI_GetProperty( hInstall, szName, &val, pchValueBuf ); 02344 } 02345 02346 typedef struct _msi_remote_package_impl { 02347 IWineMsiRemotePackage IWineMsiRemotePackage_iface; 02348 MSIHANDLE package; 02349 LONG refs; 02350 } msi_remote_package_impl; 02351 02352 static inline msi_remote_package_impl *impl_from_IWineMsiRemotePackage( IWineMsiRemotePackage *iface ) 02353 { 02354 return CONTAINING_RECORD(iface, msi_remote_package_impl, IWineMsiRemotePackage_iface); 02355 } 02356 02357 static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface, 02358 REFIID riid,LPVOID *ppobj) 02359 { 02360 if( IsEqualCLSID( riid, &IID_IUnknown ) || 02361 IsEqualCLSID( riid, &IID_IWineMsiRemotePackage ) ) 02362 { 02363 IUnknown_AddRef( iface ); 02364 *ppobj = iface; 02365 return S_OK; 02366 } 02367 02368 return E_NOINTERFACE; 02369 } 02370 02371 static ULONG WINAPI mrp_AddRef( IWineMsiRemotePackage *iface ) 02372 { 02373 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02374 02375 return InterlockedIncrement( &This->refs ); 02376 } 02377 02378 static ULONG WINAPI mrp_Release( IWineMsiRemotePackage *iface ) 02379 { 02380 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02381 ULONG r; 02382 02383 r = InterlockedDecrement( &This->refs ); 02384 if (r == 0) 02385 { 02386 MsiCloseHandle( This->package ); 02387 msi_free( This ); 02388 } 02389 return r; 02390 } 02391 02392 static HRESULT WINAPI mrp_SetMsiHandle( IWineMsiRemotePackage *iface, MSIHANDLE handle ) 02393 { 02394 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02395 This->package = handle; 02396 return S_OK; 02397 } 02398 02399 static HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHANDLE *handle ) 02400 { 02401 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02402 IWineMsiRemoteDatabase *rdb = NULL; 02403 HRESULT hr; 02404 MSIHANDLE hdb; 02405 02406 hr = create_msi_remote_database( NULL, (LPVOID *)&rdb ); 02407 if (FAILED(hr) || !rdb) 02408 { 02409 ERR("Failed to create remote database\n"); 02410 return hr; 02411 } 02412 02413 hdb = MsiGetActiveDatabase(This->package); 02414 02415 hr = IWineMsiRemoteDatabase_SetMsiHandle( rdb, hdb ); 02416 if (FAILED(hr)) 02417 { 02418 ERR("Failed to set the database handle\n"); 02419 return hr; 02420 } 02421 02422 *handle = alloc_msi_remote_handle( (IUnknown *)rdb ); 02423 return S_OK; 02424 } 02425 02426 static HRESULT WINAPI mrp_GetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR value, DWORD *size ) 02427 { 02428 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02429 UINT r = MsiGetPropertyW(This->package, property, value, size); 02430 if (r != ERROR_SUCCESS) return HRESULT_FROM_WIN32(r); 02431 return S_OK; 02432 } 02433 02434 static HRESULT WINAPI mrp_SetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR value ) 02435 { 02436 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02437 UINT r = MsiSetPropertyW(This->package, property, value); 02438 return HRESULT_FROM_WIN32(r); 02439 } 02440 02441 static HRESULT WINAPI mrp_ProcessMessage( IWineMsiRemotePackage *iface, INSTALLMESSAGE message, MSIHANDLE record ) 02442 { 02443 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02444 UINT r = MsiProcessMessage(This->package, message, record); 02445 return HRESULT_FROM_WIN32(r); 02446 } 02447 02448 static HRESULT WINAPI mrp_DoAction( IWineMsiRemotePackage *iface, BSTR action ) 02449 { 02450 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02451 UINT r = MsiDoActionW(This->package, action); 02452 return HRESULT_FROM_WIN32(r); 02453 } 02454 02455 static HRESULT WINAPI mrp_Sequence( IWineMsiRemotePackage *iface, BSTR table, int sequence ) 02456 { 02457 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02458 UINT r = MsiSequenceW(This->package, table, sequence); 02459 return HRESULT_FROM_WIN32(r); 02460 } 02461 02462 static HRESULT WINAPI mrp_GetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value, DWORD *size ) 02463 { 02464 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02465 UINT r = MsiGetTargetPathW(This->package, folder, value, size); 02466 return HRESULT_FROM_WIN32(r); 02467 } 02468 02469 static HRESULT WINAPI mrp_SetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value) 02470 { 02471 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02472 UINT r = MsiSetTargetPathW(This->package, folder, value); 02473 return HRESULT_FROM_WIN32(r); 02474 } 02475 02476 static HRESULT WINAPI mrp_GetSourcePath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value, DWORD *size ) 02477 { 02478 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02479 UINT r = MsiGetSourcePathW(This->package, folder, value, size); 02480 return HRESULT_FROM_WIN32(r); 02481 } 02482 02483 static HRESULT WINAPI mrp_GetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL *ret ) 02484 { 02485 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02486 *ret = MsiGetMode(This->package, mode); 02487 return S_OK; 02488 } 02489 02490 static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL state ) 02491 { 02492 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02493 UINT r = MsiSetMode(This->package, mode, state); 02494 return HRESULT_FROM_WIN32(r); 02495 } 02496 02497 static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature, 02498 INSTALLSTATE *installed, INSTALLSTATE *action ) 02499 { 02500 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02501 UINT r = MsiGetFeatureStateW(This->package, feature, installed, action); 02502 return HRESULT_FROM_WIN32(r); 02503 } 02504 02505 static HRESULT WINAPI mrp_SetFeatureState( IWineMsiRemotePackage *iface, BSTR feature, INSTALLSTATE state ) 02506 { 02507 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02508 UINT r = MsiSetFeatureStateW(This->package, feature, state); 02509 return HRESULT_FROM_WIN32(r); 02510 } 02511 02512 static HRESULT WINAPI mrp_GetComponentState( IWineMsiRemotePackage *iface, BSTR component, 02513 INSTALLSTATE *installed, INSTALLSTATE *action ) 02514 { 02515 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02516 UINT r = MsiGetComponentStateW(This->package, component, installed, action); 02517 return HRESULT_FROM_WIN32(r); 02518 } 02519 02520 static HRESULT WINAPI mrp_SetComponentState( IWineMsiRemotePackage *iface, BSTR component, INSTALLSTATE state ) 02521 { 02522 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02523 UINT r = MsiSetComponentStateW(This->package, component, state); 02524 return HRESULT_FROM_WIN32(r); 02525 } 02526 02527 static HRESULT WINAPI mrp_GetLanguage( IWineMsiRemotePackage *iface, LANGID *language ) 02528 { 02529 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02530 *language = MsiGetLanguage(This->package); 02531 return S_OK; 02532 } 02533 02534 static HRESULT WINAPI mrp_SetInstallLevel( IWineMsiRemotePackage *iface, int level ) 02535 { 02536 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02537 UINT r = MsiSetInstallLevel(This->package, level); 02538 return HRESULT_FROM_WIN32(r); 02539 } 02540 02541 static HRESULT WINAPI mrp_FormatRecord( IWineMsiRemotePackage *iface, MSIHANDLE record, 02542 BSTR *value) 02543 { 02544 DWORD size = 0; 02545 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02546 UINT r = MsiFormatRecordW(This->package, record, NULL, &size); 02547 if (r == ERROR_SUCCESS) 02548 { 02549 *value = SysAllocStringLen(NULL, size); 02550 if (!*value) 02551 return E_OUTOFMEMORY; 02552 size++; 02553 r = MsiFormatRecordW(This->package, record, *value, &size); 02554 } 02555 return HRESULT_FROM_WIN32(r); 02556 } 02557 02558 static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR condition ) 02559 { 02560 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02561 UINT r = MsiEvaluateConditionW(This->package, condition); 02562 return HRESULT_FROM_WIN32(r); 02563 } 02564 02565 static HRESULT WINAPI mrp_GetFeatureCost( IWineMsiRemotePackage *iface, BSTR feature, 02566 INT cost_tree, INSTALLSTATE state, INT *cost ) 02567 { 02568 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02569 UINT r = MsiGetFeatureCostW(This->package, feature, cost_tree, state, cost); 02570 return HRESULT_FROM_WIN32(r); 02571 } 02572 02573 static HRESULT WINAPI mrp_EnumComponentCosts( IWineMsiRemotePackage *iface, BSTR component, 02574 DWORD index, INSTALLSTATE state, BSTR drive, 02575 DWORD *buflen, INT *cost, INT *temp ) 02576 { 02577 msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface ); 02578 UINT r = MsiEnumComponentCostsW(This->package, component, index, state, drive, buflen, cost, temp); 02579 return HRESULT_FROM_WIN32(r); 02580 } 02581 02582 static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl = 02583 { 02584 mrp_QueryInterface, 02585 mrp_AddRef, 02586 mrp_Release, 02587 mrp_SetMsiHandle, 02588 mrp_GetActiveDatabase, 02589 mrp_GetProperty, 02590 mrp_SetProperty, 02591 mrp_ProcessMessage, 02592 mrp_DoAction, 02593 mrp_Sequence, 02594 mrp_GetTargetPath, 02595 mrp_SetTargetPath, 02596 mrp_GetSourcePath, 02597 mrp_GetMode, 02598 mrp_SetMode, 02599 mrp_GetFeatureState, 02600 mrp_SetFeatureState, 02601 mrp_GetComponentState, 02602 mrp_SetComponentState, 02603 mrp_GetLanguage, 02604 mrp_SetInstallLevel, 02605 mrp_FormatRecord, 02606 mrp_EvaluateCondition, 02607 mrp_GetFeatureCost, 02608 mrp_EnumComponentCosts 02609 }; 02610 02611 HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj ) 02612 { 02613 msi_remote_package_impl* This; 02614 02615 This = msi_alloc( sizeof *This ); 02616 if (!This) 02617 return E_OUTOFMEMORY; 02618 02619 This->IWineMsiRemotePackage_iface.lpVtbl = &msi_remote_package_vtbl; 02620 This->package = 0; 02621 This->refs = 1; 02622 02623 *ppObj = This; 02624 02625 return S_OK; 02626 } 02627 02628 UINT msi_package_add_info(MSIPACKAGE *package, DWORD context, DWORD options, 02629 LPCWSTR property, LPWSTR value) 02630 { 02631 MSISOURCELISTINFO *info; 02632 02633 LIST_FOR_EACH_ENTRY( info, &package->sourcelist_info, MSISOURCELISTINFO, entry ) 02634 { 02635 if (!strcmpW( info->value, value )) return ERROR_SUCCESS; 02636 } 02637 02638 info = msi_alloc(sizeof(MSISOURCELISTINFO)); 02639 if (!info) 02640 return ERROR_OUTOFMEMORY; 02641 02642 info->context = context; 02643 info->options = options; 02644 info->property = property; 02645 info->value = strdupW(value); 02646 list_add_head(&package->sourcelist_info, &info->entry); 02647 02648 return ERROR_SUCCESS; 02649 } 02650 02651 UINT msi_package_add_media_disk(MSIPACKAGE *package, DWORD context, DWORD options, 02652 DWORD disk_id, LPWSTR volume_label, LPWSTR disk_prompt) 02653 { 02654 MSIMEDIADISK *disk; 02655 02656 LIST_FOR_EACH_ENTRY( disk, &package->sourcelist_media, MSIMEDIADISK, entry ) 02657 { 02658 if (disk->disk_id == disk_id) return ERROR_SUCCESS; 02659 } 02660 02661 disk = msi_alloc(sizeof(MSIMEDIADISK)); 02662 if (!disk) 02663 return ERROR_OUTOFMEMORY; 02664 02665 disk->context = context; 02666 disk->options = options; 02667 disk->disk_id = disk_id; 02668 disk->volume_label = strdupW(volume_label); 02669 disk->disk_prompt = strdupW(disk_prompt); 02670 list_add_head(&package->sourcelist_media, &disk->entry); 02671 02672 return ERROR_SUCCESS; 02673 } Generated on Thu May 24 2012 04:25:42 for ReactOS by
1.7.6.1
|