Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensource.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 #include <stdarg.h> 00022 00023 #define COBJMACROS 00024 #define NONAMELESSUNION 00025 00026 #include "windef.h" 00027 #include "winbase.h" 00028 #include "winreg.h" 00029 #include "winnls.h" 00030 #include "shlwapi.h" 00031 #include "wine/debug.h" 00032 #include "msi.h" 00033 #include "msiquery.h" 00034 #include "msipriv.h" 00035 #include "wincrypt.h" 00036 #include "winver.h" 00037 #include "winuser.h" 00038 #include "wine/unicode.h" 00039 #include "sddl.h" 00040 00041 WINE_DEFAULT_DEBUG_CHANNEL(msi); 00042 00043 /* 00044 * These apis are defined in MSI 3.0 00045 */ 00046 00047 typedef struct tagMediaInfo 00048 { 00049 struct list entry; 00050 LPWSTR path; 00051 WCHAR szIndex[10]; 00052 DWORD index; 00053 } media_info; 00054 00055 static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, DWORD dwOptions, 00056 MSIINSTALLCONTEXT context, BOOL create) 00057 { 00058 HKEY rootkey = 0; 00059 UINT rc = ERROR_FUNCTION_FAILED; 00060 00061 if (context == MSIINSTALLCONTEXT_USERUNMANAGED) 00062 { 00063 if (dwOptions & MSICODE_PATCH) 00064 rc = MSIREG_OpenUserPatchesKey(szProduct, &rootkey, create); 00065 else 00066 rc = MSIREG_OpenProductKey(szProduct, NULL, context, 00067 &rootkey, create); 00068 } 00069 else if (context == MSIINSTALLCONTEXT_USERMANAGED) 00070 { 00071 if (dwOptions & MSICODE_PATCH) 00072 rc = MSIREG_OpenUserPatchesKey(szProduct, &rootkey, create); 00073 else 00074 rc = MSIREG_OpenProductKey(szProduct, NULL, context, 00075 &rootkey, create); 00076 } 00077 else if (context == MSIINSTALLCONTEXT_MACHINE) 00078 { 00079 if (dwOptions & MSICODE_PATCH) 00080 rc = MSIREG_OpenPatchesKey(szProduct, &rootkey, create); 00081 else 00082 rc = MSIREG_OpenProductKey(szProduct, NULL, context, 00083 &rootkey, create); 00084 } 00085 00086 if (rc != ERROR_SUCCESS) 00087 { 00088 if (dwOptions & MSICODE_PATCH) 00089 return ERROR_UNKNOWN_PATCH; 00090 else 00091 return ERROR_UNKNOWN_PRODUCT; 00092 } 00093 00094 if (create) 00095 rc = RegCreateKeyW(rootkey, szSourceList, key); 00096 else 00097 { 00098 rc = RegOpenKeyW(rootkey,szSourceList, key); 00099 if (rc != ERROR_SUCCESS) 00100 rc = ERROR_BAD_CONFIGURATION; 00101 } 00102 00103 return rc; 00104 } 00105 00106 static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create) 00107 { 00108 UINT rc; 00109 static const WCHAR media[] = {'M','e','d','i','a',0}; 00110 00111 if (create) 00112 rc = RegCreateKeyW(rootkey, media, key); 00113 else 00114 rc = RegOpenKeyW(rootkey,media, key); 00115 00116 return rc; 00117 } 00118 00119 static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create) 00120 { 00121 UINT rc; 00122 static const WCHAR net[] = {'N','e','t',0}; 00123 00124 if (create) 00125 rc = RegCreateKeyW(rootkey, net, key); 00126 else 00127 rc = RegOpenKeyW(rootkey, net, key); 00128 00129 return rc; 00130 } 00131 00132 static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create) 00133 { 00134 UINT rc; 00135 static const WCHAR URL[] = {'U','R','L',0}; 00136 00137 if (create) 00138 rc = RegCreateKeyW(rootkey, URL, key); 00139 else 00140 rc = RegOpenKeyW(rootkey, URL, key); 00141 00142 return rc; 00143 } 00144 00145 /****************************************************************** 00146 * MsiSourceListEnumMediaDisksA (MSI.@) 00147 */ 00148 UINT WINAPI MsiSourceListEnumMediaDisksA(LPCSTR szProductCodeOrPatchCode, 00149 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, 00150 DWORD dwOptions, DWORD dwIndex, LPDWORD pdwDiskId, 00151 LPSTR szVolumeLabel, LPDWORD pcchVolumeLabel, 00152 LPSTR szDiskPrompt, LPDWORD pcchDiskPrompt) 00153 { 00154 LPWSTR product = NULL; 00155 LPWSTR usersid = NULL; 00156 LPWSTR volume = NULL; 00157 LPWSTR prompt = NULL; 00158 UINT r = ERROR_INVALID_PARAMETER; 00159 00160 TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n", debugstr_a(szProductCodeOrPatchCode), 00161 debugstr_a(szUserSid), dwContext, dwOptions, dwIndex, pdwDiskId, 00162 szVolumeLabel, pcchVolumeLabel, szDiskPrompt, pcchDiskPrompt); 00163 00164 if (szDiskPrompt && !pcchDiskPrompt) 00165 return ERROR_INVALID_PARAMETER; 00166 00167 if (szProductCodeOrPatchCode) product = strdupAtoW(szProductCodeOrPatchCode); 00168 if (szUserSid) usersid = strdupAtoW(szUserSid); 00169 00170 /* FIXME: add tests for an invalid format */ 00171 00172 if (pcchVolumeLabel) 00173 volume = msi_alloc(*pcchVolumeLabel * sizeof(WCHAR)); 00174 00175 if (pcchDiskPrompt) 00176 prompt = msi_alloc(*pcchDiskPrompt * sizeof(WCHAR)); 00177 00178 if (volume) *volume = '\0'; 00179 if (prompt) *prompt = '\0'; 00180 r = MsiSourceListEnumMediaDisksW(product, usersid, dwContext, dwOptions, 00181 dwIndex, pdwDiskId, volume, pcchVolumeLabel, 00182 prompt, pcchDiskPrompt); 00183 if (r != ERROR_SUCCESS) 00184 goto done; 00185 00186 if (szVolumeLabel && pcchVolumeLabel) 00187 WideCharToMultiByte(CP_ACP, 0, volume, -1, szVolumeLabel, 00188 *pcchVolumeLabel + 1, NULL, NULL); 00189 00190 if (szDiskPrompt) 00191 WideCharToMultiByte(CP_ACP, 0, prompt, -1, szDiskPrompt, 00192 *pcchDiskPrompt + 1, NULL, NULL); 00193 00194 done: 00195 msi_free(product); 00196 msi_free(usersid); 00197 msi_free(volume); 00198 msi_free(prompt); 00199 00200 return r; 00201 } 00202 00203 /****************************************************************** 00204 * MsiSourceListEnumMediaDisksW (MSI.@) 00205 */ 00206 UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode, 00207 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext, 00208 DWORD dwOptions, DWORD dwIndex, LPDWORD pdwDiskId, 00209 LPWSTR szVolumeLabel, LPDWORD pcchVolumeLabel, 00210 LPWSTR szDiskPrompt, LPDWORD pcchDiskPrompt) 00211 { 00212 WCHAR squished_pc[GUID_SIZE]; 00213 WCHAR convert[11]; 00214 LPWSTR value = NULL; 00215 LPWSTR data = NULL; 00216 LPWSTR ptr, ptr2; 00217 HKEY source, media; 00218 DWORD valuesz, datasz = 0; 00219 DWORD type; 00220 DWORD numvals, size; 00221 LONG res; 00222 UINT r; 00223 static DWORD index = 0; 00224 00225 static const WCHAR fmt[] = {'#','%','d',0}; 00226 00227 TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p)\n", debugstr_w(szProductCodeOrPatchCode), 00228 debugstr_w(szUserSid), dwContext, dwOptions, dwIndex, szVolumeLabel, 00229 pcchVolumeLabel, szDiskPrompt, pcchDiskPrompt); 00230 00231 if (!szProductCodeOrPatchCode || 00232 !squash_guid(szProductCodeOrPatchCode, squished_pc)) 00233 return ERROR_INVALID_PARAMETER; 00234 00235 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid) 00236 return ERROR_INVALID_PARAMETER; 00237 00238 if (dwOptions != MSICODE_PRODUCT && dwOptions != MSICODE_PATCH) 00239 return ERROR_INVALID_PARAMETER; 00240 00241 if (szDiskPrompt && !pcchDiskPrompt) 00242 return ERROR_INVALID_PARAMETER; 00243 00244 if (dwIndex == 0) 00245 index = 0; 00246 00247 if (dwIndex != index) 00248 return ERROR_INVALID_PARAMETER; 00249 00250 r = OpenSourceKey(szProductCodeOrPatchCode, &source, 00251 dwOptions, dwContext, FALSE); 00252 if (r != ERROR_SUCCESS) 00253 return r; 00254 00255 r = OpenMediaSubkey(source, &media, FALSE); 00256 if (r != ERROR_SUCCESS) 00257 { 00258 RegCloseKey(source); 00259 return ERROR_NO_MORE_ITEMS; 00260 } 00261 00262 if (!pcchVolumeLabel && !pcchDiskPrompt) 00263 { 00264 r = RegEnumValueW(media, dwIndex, NULL, NULL, NULL, 00265 &type, NULL, NULL); 00266 goto done; 00267 } 00268 00269 res = RegQueryInfoKeyW(media, NULL, NULL, NULL, NULL, NULL, 00270 NULL, &numvals, &valuesz, &datasz, NULL, NULL); 00271 if (res != ERROR_SUCCESS) 00272 { 00273 r = ERROR_BAD_CONFIGURATION; 00274 goto done; 00275 } 00276 00277 value = msi_alloc(++valuesz * sizeof(WCHAR)); 00278 data = msi_alloc(++datasz * sizeof(WCHAR)); 00279 if (!value || !data) 00280 { 00281 r = ERROR_OUTOFMEMORY; 00282 goto done; 00283 } 00284 00285 r = RegEnumValueW(media, dwIndex, value, &valuesz, 00286 NULL, &type, (LPBYTE)data, &datasz); 00287 if (r != ERROR_SUCCESS) 00288 goto done; 00289 00290 if (pdwDiskId) 00291 *pdwDiskId = atolW(value); 00292 00293 ptr2 = data; 00294 ptr = strchrW(data, ';'); 00295 if (!ptr) 00296 ptr = data; 00297 else 00298 *ptr = '\0'; 00299 00300 if (pcchVolumeLabel) 00301 { 00302 if (type == REG_DWORD) 00303 { 00304 sprintfW(convert, fmt, *data); 00305 size = lstrlenW(convert); 00306 ptr2 = convert; 00307 } 00308 else 00309 size = lstrlenW(data); 00310 00311 if (size >= *pcchVolumeLabel) 00312 r = ERROR_MORE_DATA; 00313 else if (szVolumeLabel) 00314 lstrcpyW(szVolumeLabel, ptr2); 00315 00316 *pcchVolumeLabel = size; 00317 } 00318 00319 if (pcchDiskPrompt) 00320 { 00321 if (!*ptr) 00322 ptr++; 00323 00324 if (type == REG_DWORD) 00325 { 00326 sprintfW(convert, fmt, *ptr); 00327 size = lstrlenW(convert); 00328 ptr = convert; 00329 } 00330 else 00331 size = lstrlenW(ptr); 00332 00333 if (size >= *pcchDiskPrompt) 00334 r = ERROR_MORE_DATA; 00335 else if (szDiskPrompt) 00336 lstrcpyW(szDiskPrompt, ptr); 00337 00338 *pcchDiskPrompt = size; 00339 } 00340 00341 index++; 00342 00343 done: 00344 msi_free(value); 00345 msi_free(data); 00346 RegCloseKey(source); 00347 00348 return r; 00349 } 00350 00351 /****************************************************************** 00352 * MsiSourceListEnumSourcesA (MSI.@) 00353 */ 00354 UINT WINAPI MsiSourceListEnumSourcesA(LPCSTR szProductCodeOrPatch, LPCSTR szUserSid, 00355 MSIINSTALLCONTEXT dwContext, 00356 DWORD dwOptions, DWORD dwIndex, 00357 LPSTR szSource, LPDWORD pcchSource) 00358 { 00359 LPWSTR product = NULL; 00360 LPWSTR usersid = NULL; 00361 LPWSTR source = NULL; 00362 DWORD len = 0; 00363 UINT r = ERROR_INVALID_PARAMETER; 00364 static DWORD index = 0; 00365 00366 TRACE("(%s, %s, %d, %d, %d, %p, %p)\n", debugstr_a(szProductCodeOrPatch), 00367 debugstr_a(szUserSid), dwContext, dwOptions, dwIndex, szSource, pcchSource); 00368 00369 if (dwIndex == 0) 00370 index = 0; 00371 00372 if (szSource && !pcchSource) 00373 goto done; 00374 00375 if (dwIndex != index) 00376 goto done; 00377 00378 if (szProductCodeOrPatch) product = strdupAtoW(szProductCodeOrPatch); 00379 if (szUserSid) usersid = strdupAtoW(szUserSid); 00380 00381 r = MsiSourceListEnumSourcesW(product, usersid, dwContext, dwOptions, 00382 dwIndex, NULL, &len); 00383 if (r != ERROR_SUCCESS) 00384 goto done; 00385 00386 source = msi_alloc(++len * sizeof(WCHAR)); 00387 if (!source) 00388 { 00389 r = ERROR_OUTOFMEMORY; 00390 goto done; 00391 } 00392 00393 *source = '\0'; 00394 r = MsiSourceListEnumSourcesW(product, usersid, dwContext, dwOptions, 00395 dwIndex, source, &len); 00396 if (r != ERROR_SUCCESS) 00397 goto done; 00398 00399 len = WideCharToMultiByte(CP_ACP, 0, source, -1, NULL, 0, NULL, NULL); 00400 if (pcchSource && *pcchSource >= len) 00401 WideCharToMultiByte(CP_ACP, 0, source, -1, szSource, len, NULL, NULL); 00402 else if (szSource) 00403 r = ERROR_MORE_DATA; 00404 00405 if (pcchSource) 00406 *pcchSource = len - 1; 00407 00408 done: 00409 msi_free(product); 00410 msi_free(usersid); 00411 msi_free(source); 00412 00413 if (r == ERROR_SUCCESS) 00414 { 00415 if (szSource || !pcchSource) index++; 00416 } 00417 else if (dwIndex > index) 00418 index = 0; 00419 00420 return r; 00421 } 00422 00423 /****************************************************************** 00424 * MsiSourceListEnumSourcesW (MSI.@) 00425 */ 00426 UINT WINAPI MsiSourceListEnumSourcesW(LPCWSTR szProductCodeOrPatch, LPCWSTR szUserSid, 00427 MSIINSTALLCONTEXT dwContext, 00428 DWORD dwOptions, DWORD dwIndex, 00429 LPWSTR szSource, LPDWORD pcchSource) 00430 { 00431 WCHAR squished_pc[GUID_SIZE]; 00432 WCHAR name[32]; 00433 HKEY source = NULL; 00434 HKEY subkey = NULL; 00435 LONG res; 00436 UINT r = ERROR_INVALID_PARAMETER; 00437 static DWORD index = 0; 00438 00439 static const WCHAR format[] = {'%','d',0}; 00440 00441 TRACE("(%s, %s, %d, %d, %d, %p, %p)\n", debugstr_w(szProductCodeOrPatch), 00442 debugstr_w(szUserSid), dwContext, dwOptions, dwIndex, szSource, pcchSource); 00443 00444 if (dwIndex == 0) 00445 index = 0; 00446 00447 if (!szProductCodeOrPatch || !squash_guid(szProductCodeOrPatch, squished_pc)) 00448 goto done; 00449 00450 if (szSource && !pcchSource) 00451 goto done; 00452 00453 if (!(dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL))) 00454 goto done; 00455 00456 if ((dwOptions & MSISOURCETYPE_NETWORK) && (dwOptions & MSISOURCETYPE_URL)) 00457 goto done; 00458 00459 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid) 00460 goto done; 00461 00462 if (dwIndex != index) 00463 goto done; 00464 00465 r = OpenSourceKey(szProductCodeOrPatch, &source, 00466 dwOptions, dwContext, FALSE); 00467 if (r != ERROR_SUCCESS) 00468 goto done; 00469 00470 if (dwOptions & MSISOURCETYPE_NETWORK) 00471 r = OpenNetworkSubkey(source, &subkey, FALSE); 00472 else if (dwOptions & MSISOURCETYPE_URL) 00473 r = OpenURLSubkey(source, &subkey, FALSE); 00474 00475 if (r != ERROR_SUCCESS) 00476 { 00477 r = ERROR_NO_MORE_ITEMS; 00478 goto done; 00479 } 00480 00481 sprintfW(name, format, dwIndex + 1); 00482 00483 res = RegQueryValueExW(subkey, name, 0, 0, (LPBYTE)szSource, pcchSource); 00484 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) 00485 r = ERROR_NO_MORE_ITEMS; 00486 00487 done: 00488 RegCloseKey(subkey); 00489 RegCloseKey(source); 00490 00491 if (r == ERROR_SUCCESS) 00492 { 00493 if (szSource || !pcchSource) index++; 00494 } 00495 else if (dwIndex > index) 00496 index = 0; 00497 00498 return r; 00499 } 00500 00501 /****************************************************************** 00502 * MsiSourceListGetInfoA (MSI.@) 00503 */ 00504 UINT WINAPI MsiSourceListGetInfoA( LPCSTR szProduct, LPCSTR szUserSid, 00505 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, 00506 LPCSTR szProperty, LPSTR szValue, 00507 LPDWORD pcchValue) 00508 { 00509 UINT ret; 00510 LPWSTR product = NULL; 00511 LPWSTR usersid = NULL; 00512 LPWSTR property = NULL; 00513 LPWSTR value = NULL; 00514 DWORD len = 0; 00515 00516 if (szValue && !pcchValue) 00517 return ERROR_INVALID_PARAMETER; 00518 00519 if (szProduct) product = strdupAtoW(szProduct); 00520 if (szUserSid) usersid = strdupAtoW(szUserSid); 00521 if (szProperty) property = strdupAtoW(szProperty); 00522 00523 ret = MsiSourceListGetInfoW(product, usersid, dwContext, dwOptions, 00524 property, NULL, &len); 00525 if (ret != ERROR_SUCCESS) 00526 goto done; 00527 00528 value = msi_alloc(++len * sizeof(WCHAR)); 00529 if (!value) 00530 return ERROR_OUTOFMEMORY; 00531 00532 *value = '\0'; 00533 ret = MsiSourceListGetInfoW(product, usersid, dwContext, dwOptions, 00534 property, value, &len); 00535 if (ret != ERROR_SUCCESS) 00536 goto done; 00537 00538 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL); 00539 if (*pcchValue >= len) 00540 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL); 00541 else if (szValue) 00542 ret = ERROR_MORE_DATA; 00543 00544 *pcchValue = len - 1; 00545 00546 done: 00547 msi_free(product); 00548 msi_free(usersid); 00549 msi_free(property); 00550 msi_free(value); 00551 return ret; 00552 } 00553 00554 /****************************************************************** 00555 * MsiSourceListGetInfoW (MSI.@) 00556 */ 00557 UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, 00558 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, 00559 LPCWSTR szProperty, LPWSTR szValue, 00560 LPDWORD pcchValue) 00561 { 00562 WCHAR squished_pc[GUID_SIZE]; 00563 HKEY sourcekey, media; 00564 LPWSTR source, ptr; 00565 DWORD size; 00566 UINT rc; 00567 00568 static const WCHAR mediapack[] = { 00569 'M','e','d','i','a','P','a','c','k','a','g','e',0}; 00570 00571 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szProperty)); 00572 00573 if (!szProduct || !squash_guid(szProduct, squished_pc)) 00574 return ERROR_INVALID_PARAMETER; 00575 00576 if (szValue && !pcchValue) 00577 return ERROR_INVALID_PARAMETER; 00578 00579 if (dwContext != MSIINSTALLCONTEXT_USERMANAGED && 00580 dwContext != MSIINSTALLCONTEXT_USERUNMANAGED && 00581 dwContext != MSIINSTALLCONTEXT_MACHINE) 00582 return ERROR_INVALID_PARAMETER; 00583 00584 if (!szProperty) 00585 return ERROR_INVALID_PARAMETER; 00586 00587 if (szUserSid) 00588 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid)); 00589 00590 rc = OpenSourceKey(szProduct, &sourcekey, dwOptions, dwContext, FALSE); 00591 if (rc != ERROR_SUCCESS) 00592 return rc; 00593 00594 if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ) || 00595 !strcmpW( szProperty, INSTALLPROPERTY_DISKPROMPTW )) 00596 { 00597 rc = OpenMediaSubkey(sourcekey, &media, FALSE); 00598 if (rc != ERROR_SUCCESS) 00599 { 00600 RegCloseKey(sourcekey); 00601 return ERROR_SUCCESS; 00602 } 00603 00604 if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW )) 00605 szProperty = mediapack; 00606 00607 RegQueryValueExW(media, szProperty, 0, 0, (LPBYTE)szValue, pcchValue); 00608 RegCloseKey(media); 00609 } 00610 else if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW ) || 00611 !strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDTYPEW )) 00612 { 00613 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 00614 0, 0, NULL, &size); 00615 if (rc != ERROR_SUCCESS) 00616 { 00617 RegCloseKey(sourcekey); 00618 return ERROR_SUCCESS; 00619 } 00620 00621 source = msi_alloc(size); 00622 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 00623 0, 0, (LPBYTE)source, &size); 00624 00625 if (!*source) 00626 { 00627 msi_free(source); 00628 RegCloseKey(sourcekey); 00629 return ERROR_SUCCESS; 00630 } 00631 00632 if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDTYPEW )) 00633 { 00634 if (*source != 'n' && *source != 'u' && *source != 'm') 00635 { 00636 msi_free(source); 00637 RegCloseKey(sourcekey); 00638 return ERROR_SUCCESS; 00639 } 00640 00641 ptr = source; 00642 source[1] = '\0'; 00643 } 00644 else 00645 { 00646 ptr = strrchrW(source, ';'); 00647 if (!ptr) 00648 ptr = source; 00649 else 00650 ptr++; 00651 } 00652 00653 if (szValue) 00654 { 00655 if (strlenW(ptr) < *pcchValue) 00656 lstrcpyW(szValue, ptr); 00657 else 00658 rc = ERROR_MORE_DATA; 00659 } 00660 00661 *pcchValue = lstrlenW(ptr); 00662 msi_free(source); 00663 } 00664 else if (!strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW )) 00665 { 00666 *pcchValue = *pcchValue * sizeof(WCHAR); 00667 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0, 00668 (LPBYTE)szValue, pcchValue); 00669 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA) 00670 { 00671 *pcchValue = 0; 00672 rc = ERROR_SUCCESS; 00673 } 00674 else 00675 { 00676 if (*pcchValue) 00677 *pcchValue = (*pcchValue - 1) / sizeof(WCHAR); 00678 if (szValue) 00679 szValue[*pcchValue] = '\0'; 00680 } 00681 } 00682 else 00683 { 00684 FIXME("Unknown property %s\n",debugstr_w(szProperty)); 00685 rc = ERROR_UNKNOWN_PROPERTY; 00686 } 00687 00688 RegCloseKey(sourcekey); 00689 return rc; 00690 } 00691 00692 /****************************************************************** 00693 * MsiSourceListSetInfoA (MSI.@) 00694 */ 00695 UINT WINAPI MsiSourceListSetInfoA(LPCSTR szProduct, LPCSTR szUserSid, 00696 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, 00697 LPCSTR szProperty, LPCSTR szValue) 00698 { 00699 UINT ret; 00700 LPWSTR product = NULL; 00701 LPWSTR usersid = NULL; 00702 LPWSTR property = NULL; 00703 LPWSTR value = NULL; 00704 00705 if (szProduct) product = strdupAtoW(szProduct); 00706 if (szUserSid) usersid = strdupAtoW(szUserSid); 00707 if (szProperty) property = strdupAtoW(szProperty); 00708 if (szValue) value = strdupAtoW(szValue); 00709 00710 ret = MsiSourceListSetInfoW(product, usersid, dwContext, dwOptions, 00711 property, value); 00712 00713 msi_free(product); 00714 msi_free(usersid); 00715 msi_free(property); 00716 msi_free(value); 00717 00718 return ret; 00719 } 00720 00721 UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid, 00722 MSIINSTALLCONTEXT context, DWORD options, 00723 LPCWSTR value) 00724 { 00725 HKEY source; 00726 LPWSTR buffer; 00727 WCHAR typechar; 00728 DWORD size; 00729 UINT r; 00730 int index = 1; 00731 00732 static const WCHAR format[] = {'%','c',';','%','i',';','%','s',0}; 00733 00734 if (options & MSISOURCETYPE_NETWORK) 00735 typechar = 'n'; 00736 else if (options & MSISOURCETYPE_URL) 00737 typechar = 'u'; 00738 else if (options & MSISOURCETYPE_MEDIA) 00739 typechar = 'm'; 00740 else 00741 return ERROR_INVALID_PARAMETER; 00742 00743 if (!(options & MSISOURCETYPE_MEDIA)) 00744 { 00745 r = MsiSourceListAddSourceExW(product, usersid, context, 00746 options, value, 0); 00747 if (r != ERROR_SUCCESS) 00748 return r; 00749 00750 index = 0; 00751 while ((r = MsiSourceListEnumSourcesW(product, usersid, context, options, 00752 index, NULL, NULL)) == ERROR_SUCCESS) 00753 index++; 00754 00755 if (r != ERROR_NO_MORE_ITEMS) 00756 return r; 00757 } 00758 00759 size = (lstrlenW(format) + lstrlenW(value) + 7) * sizeof(WCHAR); 00760 buffer = msi_alloc(size); 00761 if (!buffer) 00762 return ERROR_OUTOFMEMORY; 00763 00764 r = OpenSourceKey(product, &source, MSICODE_PRODUCT, context, FALSE); 00765 if (r != ERROR_SUCCESS) 00766 return r; 00767 00768 sprintfW(buffer, format, typechar, index, value); 00769 00770 size = (lstrlenW(buffer) + 1) * sizeof(WCHAR); 00771 r = RegSetValueExW(source, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 00772 REG_SZ, (LPBYTE)buffer, size); 00773 msi_free(buffer); 00774 00775 RegCloseKey(source); 00776 return r; 00777 } 00778 00779 /****************************************************************** 00780 * MsiSourceListSetInfoW (MSI.@) 00781 */ 00782 UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, 00783 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, 00784 LPCWSTR szProperty, LPCWSTR szValue) 00785 { 00786 WCHAR squished_pc[GUID_SIZE]; 00787 HKEY sourcekey, media; 00788 LPCWSTR property; 00789 UINT rc; 00790 00791 static const WCHAR media_package[] = { 00792 'M','e','d','i','a','P','a','c','k','a','g','e',0 00793 }; 00794 00795 TRACE("%s %s %x %x %s %s\n", debugstr_w(szProduct), debugstr_w(szUserSid), 00796 dwContext, dwOptions, debugstr_w(szProperty), debugstr_w(szValue)); 00797 00798 if (!szProduct || !squash_guid(szProduct, squished_pc)) 00799 return ERROR_INVALID_PARAMETER; 00800 00801 if (!szProperty) 00802 return ERROR_INVALID_PARAMETER; 00803 00804 if (!szValue) 00805 return ERROR_UNKNOWN_PROPERTY; 00806 00807 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid) 00808 return ERROR_INVALID_PARAMETER; 00809 00810 if (dwOptions & MSICODE_PATCH) 00811 { 00812 FIXME("Unhandled options MSICODE_PATCH\n"); 00813 return ERROR_UNKNOWN_PATCH; 00814 } 00815 00816 property = szProperty; 00817 if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW )) 00818 property = media_package; 00819 00820 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, dwContext, FALSE); 00821 if (rc != ERROR_SUCCESS) 00822 return rc; 00823 00824 if (strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW ) && 00825 dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL)) 00826 { 00827 RegCloseKey(sourcekey); 00828 return ERROR_INVALID_PARAMETER; 00829 } 00830 00831 if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ) || 00832 !strcmpW( szProperty, INSTALLPROPERTY_DISKPROMPTW )) 00833 { 00834 rc = OpenMediaSubkey(sourcekey, &media, TRUE); 00835 if (rc == ERROR_SUCCESS) 00836 { 00837 rc = msi_reg_set_val_str(media, property, szValue); 00838 RegCloseKey(media); 00839 } 00840 } 00841 else if (!strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW )) 00842 { 00843 DWORD size = (lstrlenW(szValue) + 1) * sizeof(WCHAR); 00844 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 00845 REG_SZ, (const BYTE *)szValue, size); 00846 if (rc != ERROR_SUCCESS) 00847 rc = ERROR_UNKNOWN_PROPERTY; 00848 } 00849 else if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW )) 00850 { 00851 if (!(dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL))) 00852 rc = ERROR_INVALID_PARAMETER; 00853 else 00854 rc = msi_set_last_used_source(szProduct, szUserSid, dwContext, 00855 dwOptions, szValue); 00856 } 00857 else 00858 rc = ERROR_UNKNOWN_PROPERTY; 00859 00860 RegCloseKey(sourcekey); 00861 return rc; 00862 } 00863 00864 /****************************************************************** 00865 * MsiSourceListAddSourceW (MSI.@) 00866 */ 00867 UINT WINAPI MsiSourceListAddSourceW( LPCWSTR szProduct, LPCWSTR szUserName, 00868 DWORD dwReserved, LPCWSTR szSource) 00869 { 00870 WCHAR squished_pc[GUID_SIZE]; 00871 INT ret; 00872 LPWSTR sidstr = NULL; 00873 DWORD sidsize = 0; 00874 DWORD domsize = 0; 00875 DWORD context; 00876 HKEY hkey = 0; 00877 UINT r; 00878 00879 TRACE("%s %s %s\n", debugstr_w(szProduct), debugstr_w(szUserName), debugstr_w(szSource)); 00880 00881 if (!szSource || !*szSource) 00882 return ERROR_INVALID_PARAMETER; 00883 00884 if (dwReserved != 0) 00885 return ERROR_INVALID_PARAMETER; 00886 00887 if (!szProduct || !squash_guid(szProduct, squished_pc)) 00888 return ERROR_INVALID_PARAMETER; 00889 00890 if (!szUserName || !*szUserName) 00891 context = MSIINSTALLCONTEXT_MACHINE; 00892 else 00893 { 00894 if (LookupAccountNameW(NULL, szUserName, NULL, &sidsize, NULL, &domsize, NULL)) 00895 { 00896 PSID psid = msi_alloc(sidsize); 00897 00898 if (LookupAccountNameW(NULL, szUserName, psid, &sidsize, NULL, &domsize, NULL)) 00899 ConvertSidToStringSidW(psid, &sidstr); 00900 00901 msi_free(psid); 00902 } 00903 00904 r = MSIREG_OpenProductKey(szProduct, NULL, 00905 MSIINSTALLCONTEXT_USERMANAGED, &hkey, FALSE); 00906 if (r == ERROR_SUCCESS) 00907 context = MSIINSTALLCONTEXT_USERMANAGED; 00908 else 00909 { 00910 r = MSIREG_OpenProductKey(szProduct, NULL, 00911 MSIINSTALLCONTEXT_USERUNMANAGED, 00912 &hkey, FALSE); 00913 if (r != ERROR_SUCCESS) 00914 return ERROR_UNKNOWN_PRODUCT; 00915 00916 context = MSIINSTALLCONTEXT_USERUNMANAGED; 00917 } 00918 00919 RegCloseKey(hkey); 00920 } 00921 00922 ret = MsiSourceListAddSourceExW(szProduct, sidstr, 00923 context, MSISOURCETYPE_NETWORK, szSource, 0); 00924 00925 if (sidstr) 00926 LocalFree(sidstr); 00927 00928 return ret; 00929 } 00930 00931 /****************************************************************** 00932 * MsiSourceListAddSourceA (MSI.@) 00933 */ 00934 UINT WINAPI MsiSourceListAddSourceA( LPCSTR szProduct, LPCSTR szUserName, 00935 DWORD dwReserved, LPCSTR szSource) 00936 { 00937 INT ret; 00938 LPWSTR szwproduct; 00939 LPWSTR szwusername; 00940 LPWSTR szwsource; 00941 00942 szwproduct = strdupAtoW( szProduct ); 00943 szwusername = strdupAtoW( szUserName ); 00944 szwsource = strdupAtoW( szSource ); 00945 00946 ret = MsiSourceListAddSourceW(szwproduct, szwusername, dwReserved, szwsource); 00947 00948 msi_free(szwproduct); 00949 msi_free(szwusername); 00950 msi_free(szwsource); 00951 00952 return ret; 00953 } 00954 00955 /****************************************************************** 00956 * MsiSourceListAddSourceExA (MSI.@) 00957 */ 00958 UINT WINAPI MsiSourceListAddSourceExA(LPCSTR szProduct, LPCSTR szUserSid, 00959 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCSTR szSource, DWORD dwIndex) 00960 { 00961 UINT ret; 00962 LPWSTR product, usersid, source; 00963 00964 product = strdupAtoW(szProduct); 00965 usersid = strdupAtoW(szUserSid); 00966 source = strdupAtoW(szSource); 00967 00968 ret = MsiSourceListAddSourceExW(product, usersid, dwContext, 00969 dwOptions, source, dwIndex); 00970 00971 msi_free(product); 00972 msi_free(usersid); 00973 msi_free(source); 00974 00975 return ret; 00976 } 00977 00978 static void free_source_list(struct list *sourcelist) 00979 { 00980 while (!list_empty(sourcelist)) 00981 { 00982 media_info *info = LIST_ENTRY(list_head(sourcelist), media_info, entry); 00983 list_remove(&info->entry); 00984 msi_free(info->path); 00985 msi_free(info); 00986 } 00987 } 00988 00989 static void add_source_to_list(struct list *sourcelist, media_info *info, 00990 DWORD *index) 00991 { 00992 media_info *iter; 00993 BOOL found = FALSE; 00994 static const WCHAR fmt[] = {'%','i',0}; 00995 00996 if (index) *index = 0; 00997 00998 if (list_empty(sourcelist)) 00999 { 01000 list_add_head(sourcelist, &info->entry); 01001 return; 01002 } 01003 01004 LIST_FOR_EACH_ENTRY(iter, sourcelist, media_info, entry) 01005 { 01006 if (!found && info->index < iter->index) 01007 { 01008 found = TRUE; 01009 list_add_before(&iter->entry, &info->entry); 01010 } 01011 01012 /* update the rest of the list */ 01013 if (found) 01014 sprintfW(iter->szIndex, fmt, ++iter->index); 01015 else if (index) 01016 (*index)++; 01017 } 01018 01019 if (!found) 01020 list_add_after(&iter->entry, &info->entry); 01021 } 01022 01023 static UINT fill_source_list(struct list *sourcelist, HKEY sourcekey, DWORD *count) 01024 { 01025 UINT r = ERROR_SUCCESS; 01026 DWORD index = 0; 01027 WCHAR name[10]; 01028 DWORD size, val_size; 01029 media_info *entry; 01030 01031 *count = 0; 01032 01033 while (r == ERROR_SUCCESS) 01034 { 01035 size = sizeof(name) / sizeof(name[0]); 01036 r = RegEnumValueW(sourcekey, index, name, &size, NULL, NULL, NULL, &val_size); 01037 if (r != ERROR_SUCCESS) 01038 return r; 01039 01040 entry = msi_alloc(sizeof(media_info)); 01041 if (!entry) 01042 goto error; 01043 01044 entry->path = msi_alloc(val_size); 01045 if (!entry->path) 01046 { 01047 msi_free(entry); 01048 goto error; 01049 } 01050 01051 lstrcpyW(entry->szIndex, name); 01052 entry->index = atoiW(name); 01053 01054 size++; 01055 r = RegEnumValueW(sourcekey, index, name, &size, NULL, 01056 NULL, (LPBYTE)entry->path, &val_size); 01057 if (r != ERROR_SUCCESS) 01058 { 01059 msi_free(entry->path); 01060 msi_free(entry); 01061 goto error; 01062 } 01063 01064 index = ++(*count); 01065 add_source_to_list(sourcelist, entry, NULL); 01066 } 01067 01068 error: 01069 *count = -1; 01070 free_source_list(sourcelist); 01071 return ERROR_OUTOFMEMORY; 01072 } 01073 01074 /****************************************************************** 01075 * MsiSourceListAddSourceExW (MSI.@) 01076 */ 01077 UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid, 01078 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource, 01079 DWORD dwIndex) 01080 { 01081 HKEY sourcekey; 01082 HKEY typekey; 01083 UINT rc; 01084 struct list sourcelist; 01085 media_info *info; 01086 WCHAR squished_pc[GUID_SIZE]; 01087 WCHAR name[10]; 01088 LPWSTR source; 01089 LPCWSTR postfix; 01090 DWORD size, count; 01091 DWORD index; 01092 01093 static const WCHAR fmt[] = {'%','i',0}; 01094 01095 TRACE("%s %s %x %x %s %i\n", debugstr_w(szProduct), debugstr_w(szUserSid), 01096 dwContext, dwOptions, debugstr_w(szSource), dwIndex); 01097 01098 if (!szProduct || !squash_guid(szProduct, squished_pc)) 01099 return ERROR_INVALID_PARAMETER; 01100 01101 if (!szSource || !*szSource) 01102 return ERROR_INVALID_PARAMETER; 01103 01104 if (!(dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL))) 01105 return ERROR_INVALID_PARAMETER; 01106 01107 if (dwOptions & MSICODE_PATCH) 01108 { 01109 FIXME("Unhandled options MSICODE_PATCH\n"); 01110 return ERROR_FUNCTION_FAILED; 01111 } 01112 01113 if (szUserSid && (dwContext & MSIINSTALLCONTEXT_MACHINE)) 01114 return ERROR_INVALID_PARAMETER; 01115 01116 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, dwContext, FALSE); 01117 if (rc != ERROR_SUCCESS) 01118 return rc; 01119 01120 if (dwOptions & MSISOURCETYPE_NETWORK) 01121 rc = OpenNetworkSubkey(sourcekey, &typekey, TRUE); 01122 else if (dwOptions & MSISOURCETYPE_URL) 01123 rc = OpenURLSubkey(sourcekey, &typekey, TRUE); 01124 else if (dwOptions & MSISOURCETYPE_MEDIA) 01125 rc = OpenMediaSubkey(sourcekey, &typekey, TRUE); 01126 else 01127 { 01128 ERR("unknown media type: %08x\n", dwOptions); 01129 RegCloseKey(sourcekey); 01130 return ERROR_FUNCTION_FAILED; 01131 } 01132 if (rc != ERROR_SUCCESS) 01133 { 01134 ERR("can't open subkey %u\n", rc); 01135 RegCloseKey(sourcekey); 01136 return rc; 01137 } 01138 01139 postfix = (dwOptions & MSISOURCETYPE_NETWORK) ? szBackSlash : szForwardSlash; 01140 if (szSource[lstrlenW(szSource) - 1] == *postfix) 01141 source = strdupW(szSource); 01142 else 01143 { 01144 size = lstrlenW(szSource) + 2; 01145 source = msi_alloc(size * sizeof(WCHAR)); 01146 lstrcpyW(source, szSource); 01147 lstrcatW(source, postfix); 01148 } 01149 01150 list_init(&sourcelist); 01151 rc = fill_source_list(&sourcelist, typekey, &count); 01152 if (rc != ERROR_NO_MORE_ITEMS) 01153 return rc; 01154 01155 size = (lstrlenW(source) + 1) * sizeof(WCHAR); 01156 01157 if (count == 0) 01158 { 01159 rc = RegSetValueExW(typekey, szOne, 0, REG_EXPAND_SZ, (LPBYTE)source, size); 01160 goto done; 01161 } 01162 else if (dwIndex > count || dwIndex == 0) 01163 { 01164 sprintfW(name, fmt, count + 1); 01165 rc = RegSetValueExW(typekey, name, 0, REG_EXPAND_SZ, (LPBYTE)source, size); 01166 goto done; 01167 } 01168 else 01169 { 01170 sprintfW(name, fmt, dwIndex); 01171 info = msi_alloc(sizeof(media_info)); 01172 if (!info) 01173 { 01174 rc = ERROR_OUTOFMEMORY; 01175 goto done; 01176 } 01177 01178 info->path = strdupW(source); 01179 lstrcpyW(info->szIndex, name); 01180 info->index = dwIndex; 01181 add_source_to_list(&sourcelist, info, &index); 01182 01183 LIST_FOR_EACH_ENTRY(info, &sourcelist, media_info, entry) 01184 { 01185 if (info->index < index) 01186 continue; 01187 01188 size = (lstrlenW(info->path) + 1) * sizeof(WCHAR); 01189 rc = RegSetValueExW(typekey, info->szIndex, 0, 01190 REG_EXPAND_SZ, (LPBYTE)info->path, size); 01191 if (rc != ERROR_SUCCESS) 01192 goto done; 01193 } 01194 } 01195 01196 done: 01197 free_source_list(&sourcelist); 01198 msi_free(source); 01199 RegCloseKey(typekey); 01200 RegCloseKey(sourcekey); 01201 return rc; 01202 } 01203 01204 /****************************************************************** 01205 * MsiSourceListAddMediaDiskA (MSI.@) 01206 */ 01207 UINT WINAPI MsiSourceListAddMediaDiskA(LPCSTR szProduct, LPCSTR szUserSid, 01208 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId, 01209 LPCSTR szVolumeLabel, LPCSTR szDiskPrompt) 01210 { 01211 UINT r; 01212 LPWSTR product = NULL; 01213 LPWSTR usersid = NULL; 01214 LPWSTR volume = NULL; 01215 LPWSTR prompt = NULL; 01216 01217 if (szProduct) product = strdupAtoW(szProduct); 01218 if (szUserSid) usersid = strdupAtoW(szUserSid); 01219 if (szVolumeLabel) volume = strdupAtoW(szVolumeLabel); 01220 if (szDiskPrompt) prompt = strdupAtoW(szDiskPrompt); 01221 01222 r = MsiSourceListAddMediaDiskW(product, usersid, dwContext, dwOptions, 01223 dwDiskId, volume, prompt); 01224 01225 msi_free(product); 01226 msi_free(usersid); 01227 msi_free(volume); 01228 msi_free(prompt); 01229 01230 return r; 01231 } 01232 01233 /****************************************************************** 01234 * MsiSourceListAddMediaDiskW (MSI.@) 01235 */ 01236 UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid, 01237 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId, 01238 LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt) 01239 { 01240 HKEY sourcekey; 01241 HKEY mediakey; 01242 UINT rc; 01243 WCHAR szIndex[10]; 01244 WCHAR squished_pc[GUID_SIZE]; 01245 LPWSTR buffer; 01246 DWORD size; 01247 01248 static const WCHAR fmt[] = {'%','i',0}; 01249 01250 TRACE("%s %s %x %x %i %s %s\n", debugstr_w(szProduct), 01251 debugstr_w(szUserSid), dwContext, dwOptions, dwDiskId, 01252 debugstr_w(szVolumeLabel), debugstr_w(szDiskPrompt)); 01253 01254 if (!szProduct || !squash_guid(szProduct, squished_pc)) 01255 return ERROR_INVALID_PARAMETER; 01256 01257 if (dwOptions != MSICODE_PRODUCT && dwOptions != MSICODE_PATCH) 01258 return ERROR_INVALID_PARAMETER; 01259 01260 if ((szVolumeLabel && !*szVolumeLabel) || (szDiskPrompt && !*szDiskPrompt)) 01261 return ERROR_INVALID_PARAMETER; 01262 01263 if ((dwContext & MSIINSTALLCONTEXT_MACHINE) && szUserSid) 01264 return ERROR_INVALID_PARAMETER; 01265 01266 if (dwOptions & MSICODE_PATCH) 01267 { 01268 FIXME("Unhandled options MSICODE_PATCH\n"); 01269 return ERROR_FUNCTION_FAILED; 01270 } 01271 01272 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, dwContext, FALSE); 01273 if (rc != ERROR_SUCCESS) 01274 return rc; 01275 01276 OpenMediaSubkey(sourcekey, &mediakey, TRUE); 01277 01278 sprintfW(szIndex, fmt, dwDiskId); 01279 01280 size = 2; 01281 if (szVolumeLabel) size += lstrlenW(szVolumeLabel); 01282 if (szDiskPrompt) size += lstrlenW(szDiskPrompt); 01283 01284 size *= sizeof(WCHAR); 01285 buffer = msi_alloc(size); 01286 *buffer = '\0'; 01287 01288 if (szVolumeLabel) lstrcpyW(buffer, szVolumeLabel); 01289 lstrcatW(buffer, szSemiColon); 01290 if (szDiskPrompt) lstrcatW(buffer, szDiskPrompt); 01291 01292 RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size); 01293 msi_free(buffer); 01294 01295 RegCloseKey(sourcekey); 01296 RegCloseKey(mediakey); 01297 01298 return ERROR_SUCCESS; 01299 } 01300 01301 /****************************************************************** 01302 * MsiSourceListClearAllA (MSI.@) 01303 */ 01304 UINT WINAPI MsiSourceListClearAllA( LPCSTR szProduct, LPCSTR szUserName, DWORD dwReserved ) 01305 { 01306 FIXME("(%s %s %d)\n", debugstr_a(szProduct), debugstr_a(szUserName), dwReserved); 01307 return ERROR_SUCCESS; 01308 } 01309 01310 /****************************************************************** 01311 * MsiSourceListClearAllW (MSI.@) 01312 */ 01313 UINT WINAPI MsiSourceListClearAllW( LPCWSTR szProduct, LPCWSTR szUserName, DWORD dwReserved ) 01314 { 01315 FIXME("(%s %s %d)\n", debugstr_w(szProduct), debugstr_w(szUserName), dwReserved); 01316 return ERROR_SUCCESS; 01317 } 01318 01319 /****************************************************************** 01320 * MsiSourceListClearAllExA (MSI.@) 01321 */ 01322 UINT WINAPI MsiSourceListClearAllExA( LPCSTR szProduct, LPCSTR szUserSid, 01323 MSIINSTALLCONTEXT dwContext, DWORD dwOptions ) 01324 { 01325 FIXME("(%s %s %d %08x)\n", debugstr_a(szProduct), debugstr_a(szUserSid), 01326 dwContext, dwOptions); 01327 return ERROR_SUCCESS; 01328 } 01329 01330 /****************************************************************** 01331 * MsiSourceListClearAllExW (MSI.@) 01332 */ 01333 UINT WINAPI MsiSourceListClearAllExW( LPCWSTR szProduct, LPCWSTR szUserSid, 01334 MSIINSTALLCONTEXT dwContext, DWORD dwOptions ) 01335 { 01336 FIXME("(%s %s %d %08x)\n", debugstr_w(szProduct), debugstr_w(szUserSid), 01337 dwContext, dwOptions); 01338 return ERROR_SUCCESS; 01339 } 01340 01341 /****************************************************************** 01342 * MsiSourceListClearSourceA (MSI.@) 01343 */ 01344 UINT WINAPI MsiSourceListClearSourceA(LPCSTR szProductCodeOrPatchCode, LPCSTR szUserSid, 01345 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, 01346 LPCSTR szSource) 01347 { 01348 FIXME("(%s %s %x %x %s)\n", debugstr_a(szProductCodeOrPatchCode), debugstr_a(szUserSid), 01349 dwContext, dwOptions, debugstr_a(szSource)); 01350 return ERROR_SUCCESS; 01351 } 01352 01353 /****************************************************************** 01354 * MsiSourceListClearSourceW (MSI.@) 01355 */ 01356 UINT WINAPI MsiSourceListClearSourceW(LPCWSTR szProductCodeOrPatchCode, LPCWSTR szUserSid, 01357 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, 01358 LPCWSTR szSource) 01359 { 01360 FIXME("(%s %s %x %x %s)\n", debugstr_w(szProductCodeOrPatchCode), debugstr_w(szUserSid), 01361 dwContext, dwOptions, debugstr_w(szSource)); 01362 return ERROR_SUCCESS; 01363 } Generated on Sat May 26 2012 04:22:01 for ReactOS by
1.7.6.1
|