2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2005 Aric Stewart for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
38 #include "wine/unicode.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msi);
44 * These apis are defined in MSI 3.0
47 typedef struct tagMediaInfo
55 static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, DWORD dwOptions, BOOL user, BOOL create)
59 static const WCHAR szSourceList[] = {'S','o','u','r','c','e','L','i','s','t',0};
63 if (dwOptions == MSICODE_PATCH)
64 rc = MSIREG_OpenUserPatchesKey(szProduct, &rootkey, create);
66 rc = MSIREG_OpenUserProductsKey(szProduct, &rootkey, create);
70 if (dwOptions == MSICODE_PATCH)
71 rc = MSIREG_OpenPatchesKey(szProduct, &rootkey, create);
73 rc = MSIREG_OpenProductsKey(szProduct, &rootkey, create);
78 if (dwOptions == MSICODE_PATCH)
79 return ERROR_UNKNOWN_PATCH;
81 return ERROR_UNKNOWN_PRODUCT;
85 rc = RegCreateKeyW(rootkey, szSourceList, key);
88 rc = RegOpenKeyW(rootkey,szSourceList, key);
89 if (rc != ERROR_SUCCESS)
90 rc = ERROR_BAD_CONFIGURATION;
96 static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
99 static const WCHAR media[] = {'M','e','d','i','a',0};
102 rc = RegCreateKeyW(rootkey, media, key);
104 rc = RegOpenKeyW(rootkey,media, key);
109 static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
112 static const WCHAR net[] = {'N','e','t',0};
115 rc = RegCreateKeyW(rootkey, net, key);
117 rc = RegOpenKeyW(rootkey, net, key);
122 static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
125 static const WCHAR URL[] = {'U','R','L',0};
128 rc = RegCreateKeyW(rootkey, URL, key);
130 rc = RegOpenKeyW(rootkey, URL, key);
135 /******************************************************************
136 * MsiSourceListEnumSourcesA (MSI.@)
138 UINT WINAPI MsiSourceListEnumSourcesA(LPCSTR szProductCodeOrPatch, LPCSTR szUserSid,
139 MSIINSTALLCONTEXT dwContext,
140 DWORD dwOptions, DWORD dwIndex,
141 LPSTR szSource, LPDWORD pcchSource)
143 FIXME("(%s, %s, %d, %d, %d, %p, %p): stub!\n", szProductCodeOrPatch, szUserSid,
144 dwContext, dwOptions, dwIndex, szSource, pcchSource);
145 return ERROR_CALL_NOT_IMPLEMENTED;
148 /******************************************************************
149 * MsiSourceListGetInfoA (MSI.@)
151 UINT WINAPI MsiSourceListGetInfoA( LPCSTR szProduct, LPCSTR szUserSid,
152 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
153 LPCSTR szProperty, LPSTR szValue,
157 LPWSTR product = NULL;
158 LPWSTR usersid = NULL;
159 LPWSTR property = NULL;
163 if (szValue && !pcchValue)
164 return ERROR_INVALID_PARAMETER;
166 if (szProduct) product = strdupAtoW(szProduct);
167 if (szUserSid) usersid = strdupAtoW(szUserSid);
168 if (szProperty) property = strdupAtoW(szProperty);
170 ret = MsiSourceListGetInfoW(product, usersid, dwContext, dwOptions,
171 property, NULL, &len);
172 if (ret != ERROR_SUCCESS)
175 value = msi_alloc(++len * sizeof(WCHAR));
177 return ERROR_OUTOFMEMORY;
180 ret = MsiSourceListGetInfoW(product, usersid, dwContext, dwOptions,
181 property, value, &len);
182 if (ret != ERROR_SUCCESS)
185 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
186 if (*pcchValue >= len)
187 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
189 ret = ERROR_MORE_DATA;
191 *pcchValue = len - 1;
201 /******************************************************************
202 * MsiSourceListGetInfoW (MSI.@)
204 UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
205 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
206 LPCWSTR szProperty, LPWSTR szValue,
212 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szProperty));
214 if (!szProduct || !*szProduct)
215 return ERROR_INVALID_PARAMETER;
217 if (lstrlenW(szProduct) != GUID_SIZE - 1 ||
218 (szProduct[0] != '{' && szProduct[GUID_SIZE - 2] != '}'))
219 return ERROR_INVALID_PARAMETER;
221 if (szValue && !pcchValue)
222 return ERROR_INVALID_PARAMETER;
224 if (dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
225 dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
226 dwContext != MSIINSTALLCONTEXT_MACHINE)
227 return ERROR_INVALID_PARAMETER;
230 return ERROR_INVALID_PARAMETER;
233 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
235 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
236 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
238 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
239 rc = OpenSourceKey(szProduct, &sourcekey, dwOptions, FALSE, FALSE);
241 rc = OpenSourceKey(szProduct, &sourcekey, dwOptions, TRUE, FALSE);
243 if (rc != ERROR_SUCCESS)
246 if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
249 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
250 if (rc == ERROR_SUCCESS)
251 rc = RegQueryValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW,
252 0, 0, (LPBYTE)szValue, pcchValue);
253 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
254 rc = ERROR_UNKNOWN_PROPERTY;
257 else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) ==0)
260 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
261 if (rc == ERROR_SUCCESS)
262 rc = RegQueryValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0, 0,
263 (LPBYTE)szValue, pcchValue);
264 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
265 rc = ERROR_UNKNOWN_PROPERTY;
268 else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
273 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
276 rc = ERROR_UNKNOWN_PROPERTY;
280 buffer = msi_alloc(size);
281 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
282 0, 0, (LPBYTE)buffer,&size);
283 ptr = strchrW(buffer,';');
284 if (ptr) ptr = strchrW(ptr+1,';');
286 rc = ERROR_UNKNOWN_PROPERTY;
290 lstrcpynW(szValue, ptr, *pcchValue);
291 if (lstrlenW(ptr) > *pcchValue)
293 *pcchValue = lstrlenW(ptr)+1;
294 rc = ERROR_MORE_DATA;
302 else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0)
307 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
310 rc = ERROR_UNKNOWN_PROPERTY;
313 buffer = msi_alloc(size);
314 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
315 0, 0, (LPBYTE)buffer,&size);
318 rc = ERROR_MORE_DATA;
323 szValue[0] = buffer[0];
329 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
331 *pcchValue = *pcchValue * sizeof(WCHAR);
332 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0,
333 (LPBYTE)szValue, pcchValue);
334 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
342 *pcchValue = (*pcchValue - 1) / sizeof(WCHAR);
344 szValue[*pcchValue] = '\0';
349 FIXME("Unknown property %s\n",debugstr_w(szProperty));
350 rc = ERROR_UNKNOWN_PROPERTY;
353 RegCloseKey(sourcekey);
357 /******************************************************************
358 * MsiSourceListSetInfoW (MSI.@)
360 UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
361 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
362 LPCWSTR szProperty, LPCWSTR szValue)
367 TRACE("%s %s %x %x %s %s\n", debugstr_w(szProduct), debugstr_w(szUserSid),
368 dwContext, dwOptions, debugstr_w(szProperty), debugstr_w(szValue));
370 if (!szProduct || lstrlenW(szProduct) > 39)
371 return ERROR_INVALID_PARAMETER;
373 if (dwOptions & MSICODE_PATCH)
375 FIXME("Unhandled options MSICODE_PATCH\n");
376 return ERROR_FUNCTION_FAILED;
380 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
382 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
383 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
385 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
386 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, FALSE, TRUE);
388 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, TRUE, TRUE);
390 if (rc != ERROR_SUCCESS)
391 return ERROR_UNKNOWN_PRODUCT;
394 if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
397 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
398 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
399 if (rc == ERROR_SUCCESS)
400 rc = RegSetValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW, 0,
401 REG_SZ, (const BYTE *)szValue, size);
402 if (rc != ERROR_SUCCESS)
403 rc = ERROR_UNKNOWN_PROPERTY;
406 else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) == 0)
409 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
410 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
411 if (rc == ERROR_SUCCESS)
412 rc = RegSetValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0,
413 REG_SZ, (const BYTE *)szValue, size);
414 if (rc != ERROR_SUCCESS)
415 rc = ERROR_UNKNOWN_PROPERTY;
418 else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
420 LPWSTR buffer = NULL;
422 WCHAR typechar = 'n';
423 static const WCHAR LastUsedSource_Fmt[] = {'%','c',';','%','i',';','%','s',0};
425 /* make sure the source is registered */
426 MsiSourceListAddSourceExW(szProduct, szUserSid, dwContext,
427 dwOptions, szValue, 0);
429 if (dwOptions & MSISOURCETYPE_NETWORK)
431 else if (dwOptions & MSISOURCETYPE_URL)
433 else if (dwOptions & MSISOURCETYPE_MEDIA)
436 ERR("Unknown source type! %x\n", dwOptions);
438 size = (lstrlenW(szValue)+5)*sizeof(WCHAR);
439 buffer = msi_alloc(size);
440 sprintfW(buffer, LastUsedSource_Fmt, typechar, 1, szValue);
441 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0,
442 REG_EXPAND_SZ, (LPBYTE)buffer, size);
443 if (rc != ERROR_SUCCESS)
444 rc = ERROR_UNKNOWN_PROPERTY;
447 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
449 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
450 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0,
451 REG_SZ, (const BYTE *)szValue, size);
452 if (rc != ERROR_SUCCESS)
453 rc = ERROR_UNKNOWN_PROPERTY;
457 FIXME("Unknown property %s\n",debugstr_w(szProperty));
458 rc = ERROR_UNKNOWN_PROPERTY;
461 RegCloseKey(sourcekey);
466 /******************************************************************
467 * MsiSourceListAddSourceW (MSI.@)
469 UINT WINAPI MsiSourceListAddSourceW( LPCWSTR szProduct, LPCWSTR szUserName,
470 DWORD dwReserved, LPCWSTR szSource)
473 LPWSTR sidstr = NULL;
477 TRACE("%s %s %s\n", debugstr_w(szProduct), debugstr_w(szUserName), debugstr_w(szSource));
479 if (LookupAccountNameW(NULL, szUserName, NULL, &sidsize, NULL, &domsize, NULL))
481 PSID psid = msi_alloc(sidsize);
483 if (LookupAccountNameW(NULL, szUserName, psid, &sidsize, NULL, &domsize, NULL))
484 ConvertSidToStringSidW(psid, &sidstr);
489 ret = MsiSourceListAddSourceExW(szProduct, sidstr,
490 MSIINSTALLCONTEXT_USERMANAGED, MSISOURCETYPE_NETWORK, szSource, 0);
498 /******************************************************************
499 * MsiSourceListAddSourceA (MSI.@)
501 UINT WINAPI MsiSourceListAddSourceA( LPCSTR szProduct, LPCSTR szUserName,
502 DWORD dwReserved, LPCSTR szSource)
509 szwproduct = strdupAtoW( szProduct );
510 szwusername = strdupAtoW( szUserName );
511 szwsource = strdupAtoW( szSource );
513 ret = MsiSourceListAddSourceW(szwproduct, szwusername, 0, szwsource);
515 msi_free(szwproduct);
516 msi_free(szwusername);
522 /******************************************************************
523 * MsiSourceListAddSourceExA (MSI.@)
525 UINT WINAPI MsiSourceListAddSourceExA(LPCSTR szProduct, LPCSTR szUserSid,
526 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCSTR szSource, DWORD dwIndex)
529 LPWSTR product, usersid, source;
531 product = strdupAtoW(szProduct);
532 usersid = strdupAtoW(szUserSid);
533 source = strdupAtoW(szSource);
535 ret = MsiSourceListAddSourceExW(product, usersid, dwContext,
536 dwOptions, source, dwIndex);
545 static void free_source_list(struct list *sourcelist)
547 while (!list_empty(sourcelist))
549 media_info *info = LIST_ENTRY(list_head(sourcelist), media_info, entry);
550 list_remove(&info->entry);
551 msi_free(info->path);
556 static void add_source_to_list(struct list *sourcelist, media_info *info)
560 static const WCHAR fmt[] = {'%','i',0};
562 if (list_empty(sourcelist))
564 list_add_head(sourcelist, &info->entry);
568 LIST_FOR_EACH_ENTRY(iter, sourcelist, media_info, entry)
570 if (!found && info->index < iter->index)
573 list_add_before(&iter->entry, &info->entry);
576 /* update the rest of the list */
578 sprintfW(iter->szIndex, fmt, ++iter->index);
582 list_add_after(&iter->entry, &info->entry);
585 static UINT fill_source_list(struct list *sourcelist, HKEY sourcekey, DWORD *count)
587 UINT r = ERROR_SUCCESS;
590 DWORD size, val_size;
595 while (r == ERROR_SUCCESS)
597 size = sizeof(name) / sizeof(name[0]);
598 r = RegEnumValueW(sourcekey, index, name, &size, NULL, NULL, NULL, &val_size);
599 if (r != ERROR_SUCCESS)
602 entry = msi_alloc(sizeof(media_info));
606 entry->path = msi_alloc(val_size);
610 lstrcpyW(entry->szIndex, name);
611 entry->index = atoiW(name);
614 r = RegEnumValueW(sourcekey, index, name, &size, NULL,
615 NULL, (LPBYTE)entry->path, &val_size);
616 if (r != ERROR_SUCCESS)
620 add_source_to_list(sourcelist, entry);
625 free_source_list(sourcelist);
626 return ERROR_OUTOFMEMORY;
629 /******************************************************************
630 * MsiSourceListAddSourceExW (MSI.@)
632 UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
633 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource,
639 struct list sourcelist;
641 WCHAR squished_pc[GUID_SIZE];
647 static const WCHAR fmt[] = {'%','i',0};
648 static const WCHAR one[] = {'1',0};
649 static const WCHAR backslash[] = {'\\',0};
650 static const WCHAR forwardslash[] = {'/',0};
652 TRACE("%s %s %x %x %s %i\n", debugstr_w(szProduct), debugstr_w(szUserSid),
653 dwContext, dwOptions, debugstr_w(szSource), dwIndex);
655 if (!szProduct || !squash_guid(szProduct, squished_pc))
656 return ERROR_INVALID_PARAMETER;
658 if (!szSource || !*szSource)
659 return ERROR_INVALID_PARAMETER;
661 if (!(dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL)))
662 return ERROR_INVALID_PARAMETER;
664 if (dwOptions & MSICODE_PATCH)
666 FIXME("Unhandled options MSICODE_PATCH\n");
667 return ERROR_FUNCTION_FAILED;
671 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
673 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
674 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
676 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
677 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, FALSE, FALSE);
679 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, TRUE, FALSE);
681 if (rc != ERROR_SUCCESS)
684 if (dwOptions & MSISOURCETYPE_NETWORK)
685 rc = OpenNetworkSubkey(sourcekey, &typekey, TRUE);
686 else if (dwOptions & MSISOURCETYPE_URL)
687 rc = OpenURLSubkey(sourcekey, &typekey, TRUE);
688 else if (dwOptions & MSISOURCETYPE_MEDIA)
689 rc = OpenMediaSubkey(sourcekey, &typekey, TRUE);
692 ERR("unknown media type: %08x\n", dwOptions);
693 RegCloseKey(sourcekey);
694 return ERROR_FUNCTION_FAILED;
697 postfix = (dwOptions & MSISOURCETYPE_NETWORK) ? backslash : forwardslash;
698 if (szSource[lstrlenW(szSource) - 1] == *postfix)
699 source = strdupW(szSource);
702 size = lstrlenW(szSource) + 2;
703 source = msi_alloc(size * sizeof(WCHAR));
704 lstrcpyW(source, szSource);
705 lstrcatW(source, postfix);
708 list_init(&sourcelist);
709 rc = fill_source_list(&sourcelist, typekey, &count);
710 if (rc != ERROR_NO_MORE_ITEMS)
713 size = (lstrlenW(source) + 1) * sizeof(WCHAR);
717 rc = RegSetValueExW(typekey, one, 0, REG_EXPAND_SZ, (LPBYTE)source, size);
720 else if (dwIndex > count)
722 sprintfW(name, fmt, count + 1);
723 rc = RegSetValueExW(typekey, name, 0, REG_EXPAND_SZ, (LPBYTE)source, size);
728 /* add to the end of the list */
732 sprintfW(name, fmt, dwIndex);
733 info = msi_alloc(sizeof(media_info));
736 rc = ERROR_OUTOFMEMORY;
740 info->path = strdupW(source);
741 lstrcpyW(info->szIndex, name);
742 info->index = dwIndex;
743 add_source_to_list(&sourcelist, info);
745 LIST_FOR_EACH_ENTRY(info, &sourcelist, media_info, entry)
747 size = (lstrlenW(info->path) + 1) * sizeof(WCHAR);
748 rc = RegSetValueExW(typekey, info->szIndex, 0,
749 REG_EXPAND_SZ, (LPBYTE)info->path, size);
750 if (rc != ERROR_SUCCESS)
756 free_source_list(&sourcelist);
758 RegCloseKey(typekey);
759 RegCloseKey(sourcekey);
763 /******************************************************************
764 * MsiSourceListAddMediaDisk(MSI.@)
766 UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
767 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId,
768 LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt)
774 static const WCHAR fmt[] = {'%','i',0};
775 static const WCHAR disk_fmt[] = {'%','s',';','%','s',0};
776 static const WCHAR empty[1] = {0};
781 TRACE("%s %s %x %x %i %s %s\n", debugstr_w(szProduct),
782 debugstr_w(szUserSid), dwContext, dwOptions, dwDiskId,
783 debugstr_w(szVolumeLabel), debugstr_w(szDiskPrompt));
785 if (!szProduct || lstrlenW(szProduct) > 39)
786 return ERROR_INVALID_PARAMETER;
788 if (dwOptions & MSICODE_PATCH)
790 FIXME("Unhandled options MSICODE_PATCH\n");
791 return ERROR_FUNCTION_FAILED;
795 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
797 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
798 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
800 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
801 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, FALSE, TRUE);
803 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, TRUE, TRUE);
805 if (rc != ERROR_SUCCESS)
806 return ERROR_UNKNOWN_PRODUCT;
808 OpenMediaSubkey(sourcekey,&mediakey,TRUE);
810 sprintfW(szIndex,fmt,dwDiskId);
815 size +=lstrlenW(szVolumeLabel);
822 size +=lstrlenW(szDiskPrompt);
828 size *=sizeof(WCHAR);
830 buffer = msi_alloc(size);
831 sprintfW(buffer,disk_fmt,pt1,pt2);
833 RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);
836 RegCloseKey(sourcekey);
837 RegCloseKey(mediakey);
839 return ERROR_SUCCESS;
842 /******************************************************************
843 * MsiSourceListClearAllA (MSI.@)
845 UINT WINAPI MsiSourceListClearAllA( LPCSTR szProduct, LPCSTR szUserName, DWORD dwReserved )
847 FIXME("(%s %s %d)\n", debugstr_a(szProduct), debugstr_a(szUserName), dwReserved);
848 return ERROR_SUCCESS;
851 /******************************************************************
852 * MsiSourceListClearAllW (MSI.@)
854 UINT WINAPI MsiSourceListClearAllW( LPCWSTR szProduct, LPCWSTR szUserName, DWORD dwReserved )
856 FIXME("(%s %s %d)\n", debugstr_w(szProduct), debugstr_w(szUserName), dwReserved);
857 return ERROR_SUCCESS;