msi: Add support for the MSICODE_PATCH option.
[wine/multimedia.git] / dlls / msi / source.c
blob975b0f27bc5fb0bc3d3cf065b4ec95e6a11ab291
1 /*
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
21 #include <stdarg.h>
23 #define COBJMACROS
24 #define NONAMELESSUNION
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "winnls.h"
30 #include "shlwapi.h"
31 #include "wine/debug.h"
32 #include "msi.h"
33 #include "msiquery.h"
34 #include "msipriv.h"
35 #include "wincrypt.h"
36 #include "winver.h"
37 #include "winuser.h"
38 #include "wine/unicode.h"
39 #include "sddl.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msi);
44 * These apis are defined in MSI 3.0
47 typedef struct tagMediaInfo
49 LPWSTR path;
50 WCHAR szIndex[10];
51 WCHAR type;
52 } media_info;
54 static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, DWORD dwOptions, BOOL user, BOOL create)
56 HKEY rootkey = 0;
57 UINT rc;
58 static const WCHAR szSourceList[] = {'S','o','u','r','c','e','L','i','s','t',0};
60 if (user)
62 if (dwOptions == MSICODE_PATCH)
63 rc = MSIREG_OpenUserPatchesKey(szProduct, &rootkey, create);
64 else
65 rc = MSIREG_OpenUserProductsKey(szProduct, &rootkey, create);
67 else
69 if (dwOptions == MSICODE_PATCH)
70 rc = MSIREG_OpenPatchesKey(szProduct, &rootkey, create);
71 else
72 rc = MSIREG_OpenProductsKey(szProduct, &rootkey, create);
75 if (rc)
77 if (dwOptions == MSICODE_PATCH)
78 return ERROR_UNKNOWN_PATCH;
79 else
80 return ERROR_UNKNOWN_PRODUCT;
83 if (create)
84 rc = RegCreateKeyW(rootkey, szSourceList, key);
85 else
87 rc = RegOpenKeyW(rootkey,szSourceList, key);
88 if (rc != ERROR_SUCCESS)
89 rc = ERROR_BAD_CONFIGURATION;
92 return rc;
95 static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
97 UINT rc;
98 static const WCHAR media[] = {'M','e','d','i','a',0};
100 if (create)
101 rc = RegCreateKeyW(rootkey, media, key);
102 else
103 rc = RegOpenKeyW(rootkey,media, key);
105 return rc;
108 static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
110 UINT rc;
111 static const WCHAR net[] = {'N','e','t',0};
113 if (create)
114 rc = RegCreateKeyW(rootkey, net, key);
115 else
116 rc = RegOpenKeyW(rootkey, net, key);
118 return rc;
121 static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
123 UINT rc;
124 static const WCHAR URL[] = {'U','R','L',0};
126 if (create)
127 rc = RegCreateKeyW(rootkey, URL, key);
128 else
129 rc = RegOpenKeyW(rootkey, URL, key);
131 return rc;
135 static UINT find_given_source(HKEY key, LPCWSTR szSource, media_info *ss)
137 DWORD index = 0;
138 WCHAR szIndex[10];
139 DWORD size;
140 DWORD val_size;
141 LPWSTR val;
142 UINT rc = ERROR_SUCCESS;
144 while (rc == ERROR_SUCCESS)
146 val = NULL;
147 val_size = 0;
148 size = sizeof(szIndex)/sizeof(szIndex[0]);
149 rc = RegEnumValueW(key, index, szIndex, &size, NULL, NULL, NULL, &val_size);
150 if (rc != ERROR_NO_MORE_ITEMS)
152 val = msi_alloc(val_size);
153 RegEnumValueW(key, index, szIndex, &size, NULL, NULL, (LPBYTE)val,
154 &val_size);
155 if (lstrcmpiW(szSource,val)==0)
157 ss->path = val;
158 strcpyW(ss->szIndex,szIndex);
159 break;
161 else
162 strcpyW(ss->szIndex,szIndex);
164 msi_free(val);
165 index ++;
168 return rc;
171 /******************************************************************
172 * MsiSourceListGetInfoA (MSI.@)
174 UINT WINAPI MsiSourceListGetInfoA( LPCSTR szProduct, LPCSTR szUserSid,
175 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
176 LPCSTR szProperty, LPSTR szValue,
177 LPDWORD pcchValue)
179 UINT ret;
180 LPWSTR product = NULL;
181 LPWSTR usersid = NULL;
182 LPWSTR property = NULL;
183 LPWSTR value = NULL;
184 DWORD len = 0;
186 if (szValue && !pcchValue)
187 return ERROR_INVALID_PARAMETER;
189 if (szProduct) product = strdupAtoW(szProduct);
190 if (szUserSid) usersid = strdupAtoW(szUserSid);
191 if (szProperty) property = strdupAtoW(szProperty);
193 ret = MsiSourceListGetInfoW(product, usersid, dwContext, dwOptions,
194 property, NULL, &len);
195 if (ret != ERROR_SUCCESS)
196 goto done;
198 value = msi_alloc(++len * sizeof(WCHAR));
199 if (!value)
200 return ERROR_OUTOFMEMORY;
202 *value = '\0';
203 ret = MsiSourceListGetInfoW(product, usersid, dwContext, dwOptions,
204 property, value, &len);
205 if (ret != ERROR_SUCCESS)
206 goto done;
208 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
209 if (*pcchValue >= len)
210 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
211 else if (szValue)
212 ret = ERROR_MORE_DATA;
214 *pcchValue = len - 1;
216 done:
217 msi_free(product);
218 msi_free(usersid);
219 msi_free(property);
220 msi_free(value);
221 return ret;
224 /******************************************************************
225 * MsiSourceListGetInfoW (MSI.@)
227 UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
228 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
229 LPCWSTR szProperty, LPWSTR szValue,
230 LPDWORD pcchValue)
232 HKEY sourcekey;
233 UINT rc;
235 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szProperty));
237 if (!szProduct || !*szProduct)
238 return ERROR_INVALID_PARAMETER;
240 if (lstrlenW(szProduct) != GUID_SIZE - 1 ||
241 (szProduct[0] != '{' && szProduct[GUID_SIZE - 2] != '}'))
242 return ERROR_INVALID_PARAMETER;
244 if (szValue && !pcchValue)
245 return ERROR_INVALID_PARAMETER;
247 if (dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
248 dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
249 dwContext != MSIINSTALLCONTEXT_MACHINE)
250 return ERROR_INVALID_PARAMETER;
252 if (!szProperty)
253 return ERROR_INVALID_PARAMETER;
255 if (szUserSid)
256 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
258 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
259 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
261 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
262 rc = OpenSourceKey(szProduct, &sourcekey, dwOptions, FALSE, FALSE);
263 else
264 rc = OpenSourceKey(szProduct, &sourcekey, dwOptions, TRUE, FALSE);
266 if (rc != ERROR_SUCCESS)
267 return rc;
269 if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
271 HKEY key;
272 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
273 if (rc == ERROR_SUCCESS)
274 rc = RegQueryValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW,
275 0, 0, (LPBYTE)szValue, pcchValue);
276 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
277 rc = ERROR_UNKNOWN_PROPERTY;
278 RegCloseKey(key);
280 else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) ==0)
282 HKEY key;
283 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
284 if (rc == ERROR_SUCCESS)
285 rc = RegQueryValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0, 0,
286 (LPBYTE)szValue, pcchValue);
287 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
288 rc = ERROR_UNKNOWN_PROPERTY;
289 RegCloseKey(key);
291 else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
293 LPWSTR buffer;
294 DWORD size = 0;
296 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
297 NULL, &size);
298 if (size == 0)
299 rc = ERROR_UNKNOWN_PROPERTY;
300 else
302 LPWSTR ptr;
303 buffer = msi_alloc(size);
304 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
305 0, 0, (LPBYTE)buffer,&size);
306 ptr = strchrW(buffer,';');
307 if (ptr) ptr = strchrW(ptr+1,';');
308 if (!ptr)
309 rc = ERROR_UNKNOWN_PROPERTY;
310 else
312 ptr ++;
313 lstrcpynW(szValue, ptr, *pcchValue);
314 if (lstrlenW(ptr) > *pcchValue)
316 *pcchValue = lstrlenW(ptr)+1;
317 rc = ERROR_MORE_DATA;
319 else
320 rc = ERROR_SUCCESS;
322 msi_free(buffer);
325 else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0)
327 LPWSTR buffer;
328 DWORD size = 0;
330 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
331 NULL, &size);
332 if (size == 0)
333 rc = ERROR_UNKNOWN_PROPERTY;
334 else
336 buffer = msi_alloc(size);
337 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
338 0, 0, (LPBYTE)buffer,&size);
339 if (*pcchValue < 1)
341 rc = ERROR_MORE_DATA;
342 *pcchValue = 1;
344 else
346 szValue[0] = buffer[0];
347 rc = ERROR_SUCCESS;
349 msi_free(buffer);
352 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
354 *pcchValue = *pcchValue * sizeof(WCHAR);
355 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0,
356 (LPBYTE)szValue, pcchValue);
357 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
359 *pcchValue = 0;
360 rc = ERROR_SUCCESS;
362 else
364 if (*pcchValue)
365 *pcchValue = (*pcchValue - 1) / sizeof(WCHAR);
366 if (szValue)
367 szValue[*pcchValue] = '\0';
370 else
372 FIXME("Unknown property %s\n",debugstr_w(szProperty));
373 rc = ERROR_UNKNOWN_PROPERTY;
376 RegCloseKey(sourcekey);
377 return rc;
380 /******************************************************************
381 * MsiSourceListSetInfoW (MSI.@)
383 UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
384 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
385 LPCWSTR szProperty, LPCWSTR szValue)
387 HKEY sourcekey;
388 UINT rc;
390 TRACE("%s %s %x %x %s %s\n", debugstr_w(szProduct), debugstr_w(szUserSid),
391 dwContext, dwOptions, debugstr_w(szProperty), debugstr_w(szValue));
393 if (!szProduct || lstrlenW(szProduct) > 39)
394 return ERROR_INVALID_PARAMETER;
396 if (dwOptions & MSICODE_PATCH)
398 FIXME("Unhandled options MSICODE_PATCH\n");
399 return ERROR_FUNCTION_FAILED;
402 if (szUserSid)
403 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
405 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
406 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
408 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
409 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, FALSE, TRUE);
410 else
411 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, TRUE, TRUE);
413 if (rc != ERROR_SUCCESS)
414 return ERROR_UNKNOWN_PRODUCT;
417 if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
419 HKEY key;
420 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
421 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
422 if (rc == ERROR_SUCCESS)
423 rc = RegSetValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW, 0,
424 REG_SZ, (const BYTE *)szValue, size);
425 if (rc != ERROR_SUCCESS)
426 rc = ERROR_UNKNOWN_PROPERTY;
427 RegCloseKey(key);
429 else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) == 0)
431 HKEY key;
432 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
433 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
434 if (rc == ERROR_SUCCESS)
435 rc = RegSetValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0,
436 REG_SZ, (const BYTE *)szValue, size);
437 if (rc != ERROR_SUCCESS)
438 rc = ERROR_UNKNOWN_PROPERTY;
439 RegCloseKey(key);
441 else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
443 LPWSTR buffer = NULL;
444 DWORD size;
445 WCHAR typechar = 'n';
446 static const WCHAR LastUsedSource_Fmt[] = {'%','c',';','%','i',';','%','s',0};
448 /* make sure the source is registered */
449 MsiSourceListAddSourceExW(szProduct, szUserSid, dwContext,
450 dwOptions, szValue, 0);
452 if (dwOptions & MSISOURCETYPE_NETWORK)
453 typechar = 'n';
454 else if (dwOptions & MSISOURCETYPE_URL)
455 typechar = 'u';
456 else if (dwOptions & MSISOURCETYPE_MEDIA)
457 typechar = 'm';
458 else
459 ERR("Unknown source type! %x\n", dwOptions);
461 size = (lstrlenW(szValue)+5)*sizeof(WCHAR);
462 buffer = msi_alloc(size);
463 sprintfW(buffer, LastUsedSource_Fmt, typechar, 1, szValue);
464 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0,
465 REG_EXPAND_SZ, (LPBYTE)buffer, size);
466 if (rc != ERROR_SUCCESS)
467 rc = ERROR_UNKNOWN_PROPERTY;
468 msi_free( buffer );
470 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
472 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
473 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0,
474 REG_SZ, (const BYTE *)szValue, size);
475 if (rc != ERROR_SUCCESS)
476 rc = ERROR_UNKNOWN_PROPERTY;
478 else
480 FIXME("Unknown property %s\n",debugstr_w(szProperty));
481 rc = ERROR_UNKNOWN_PROPERTY;
484 RegCloseKey(sourcekey);
485 return rc;
489 /******************************************************************
490 * MsiSourceListAddSourceW (MSI.@)
492 UINT WINAPI MsiSourceListAddSourceW( LPCWSTR szProduct, LPCWSTR szUserName,
493 DWORD dwReserved, LPCWSTR szSource)
495 INT ret;
496 LPWSTR sidstr = NULL;
497 DWORD sidsize = 0;
498 DWORD domsize = 0;
500 TRACE("%s %s %s\n", debugstr_w(szProduct), debugstr_w(szUserName), debugstr_w(szSource));
502 if (LookupAccountNameW(NULL, szUserName, NULL, &sidsize, NULL, &domsize, NULL))
504 PSID psid = msi_alloc(sidsize);
506 if (LookupAccountNameW(NULL, szUserName, psid, &sidsize, NULL, &domsize, NULL))
507 ConvertSidToStringSidW(psid, &sidstr);
509 msi_free(psid);
512 ret = MsiSourceListAddSourceExW(szProduct, sidstr,
513 MSIINSTALLCONTEXT_USERMANAGED, MSISOURCETYPE_NETWORK, szSource, 0);
515 if (sidstr)
516 LocalFree(sidstr);
518 return ret;
521 /******************************************************************
522 * MsiSourceListAddSourceA (MSI.@)
524 UINT WINAPI MsiSourceListAddSourceA( LPCSTR szProduct, LPCSTR szUserName,
525 DWORD dwReserved, LPCSTR szSource)
527 INT ret;
528 LPWSTR szwproduct;
529 LPWSTR szwusername;
530 LPWSTR szwsource;
532 szwproduct = strdupAtoW( szProduct );
533 szwusername = strdupAtoW( szUserName );
534 szwsource = strdupAtoW( szSource );
536 ret = MsiSourceListAddSourceW(szwproduct, szwusername, 0, szwsource);
538 msi_free(szwproduct);
539 msi_free(szwusername);
540 msi_free(szwsource);
542 return ret;
545 /******************************************************************
546 * MsiSourceListAddSourceExW (MSI.@)
548 UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
549 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource,
550 DWORD dwIndex)
552 HKEY sourcekey;
553 HKEY typekey;
554 UINT rc;
555 media_info source_struct;
557 TRACE("%s %s %x %x %s %i\n", debugstr_w(szProduct), debugstr_w(szUserSid),
558 dwContext, dwOptions, debugstr_w(szSource), dwIndex);
560 if (!szProduct)
561 return ERROR_INVALID_PARAMETER;
563 if (!szSource)
564 return ERROR_INVALID_PARAMETER;
566 if (dwOptions & MSICODE_PATCH)
568 FIXME("Unhandled options MSICODE_PATCH\n");
569 return ERROR_FUNCTION_FAILED;
572 if (szUserSid)
573 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
575 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
576 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
578 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
579 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, FALSE, TRUE);
580 else
581 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, TRUE, TRUE);
583 if (rc != ERROR_SUCCESS)
584 return ERROR_UNKNOWN_PRODUCT;
586 if (dwOptions & MSISOURCETYPE_NETWORK)
587 rc = OpenNetworkSubkey(sourcekey, &typekey, TRUE);
588 else if (dwOptions & MSISOURCETYPE_URL)
589 rc = OpenURLSubkey(sourcekey, &typekey, TRUE);
590 else if (dwOptions & MSISOURCETYPE_MEDIA)
591 rc = OpenMediaSubkey(sourcekey, &typekey, TRUE);
592 else
594 ERR("unknown media type: %08x\n", dwOptions);
595 RegCloseKey(sourcekey);
596 return ERROR_FUNCTION_FAILED;
599 source_struct.szIndex[0] = 0;
600 if (find_given_source(typekey, szSource, &source_struct)==ERROR_SUCCESS)
602 DWORD current_index = atoiW(source_struct.szIndex);
603 /* found the source */
604 if (dwIndex > 0 && current_index != dwIndex)
605 FIXME("Need to reorder the sources!\n");
606 msi_free( source_struct.path );
608 else
610 DWORD current_index = 0;
611 static const WCHAR fmt[] = {'%','i',0};
612 DWORD size = lstrlenW(szSource)*sizeof(WCHAR);
614 if (source_struct.szIndex[0])
615 current_index = atoiW(source_struct.szIndex);
616 /* new source */
617 if (dwIndex > 0 && dwIndex < current_index)
618 FIXME("Need to reorder the sources!\n");
620 current_index ++;
621 sprintfW(source_struct.szIndex,fmt,current_index);
622 rc = RegSetValueExW(typekey, source_struct.szIndex, 0, REG_EXPAND_SZ,
623 (const BYTE *)szSource, size);
626 RegCloseKey(typekey);
627 RegCloseKey(sourcekey);
628 return rc;
631 /******************************************************************
632 * MsiSourceListAddMediaDisk(MSI.@)
634 UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
635 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId,
636 LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt)
638 HKEY sourcekey;
639 HKEY mediakey;
640 UINT rc;
641 WCHAR szIndex[10];
642 static const WCHAR fmt[] = {'%','i',0};
643 static const WCHAR disk_fmt[] = {'%','s',';','%','s',0};
644 static const WCHAR empty[1] = {0};
645 LPCWSTR pt1,pt2;
646 LPWSTR buffer;
647 DWORD size;
649 TRACE("%s %s %x %x %i %s %s\n", debugstr_w(szProduct),
650 debugstr_w(szUserSid), dwContext, dwOptions, dwDiskId,
651 debugstr_w(szVolumeLabel), debugstr_w(szDiskPrompt));
653 if (!szProduct || lstrlenW(szProduct) > 39)
654 return ERROR_INVALID_PARAMETER;
656 if (dwOptions & MSICODE_PATCH)
658 FIXME("Unhandled options MSICODE_PATCH\n");
659 return ERROR_FUNCTION_FAILED;
662 if (szUserSid)
663 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
665 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
666 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
668 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
669 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, FALSE, TRUE);
670 else
671 rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, TRUE, TRUE);
673 if (rc != ERROR_SUCCESS)
674 return ERROR_UNKNOWN_PRODUCT;
676 OpenMediaSubkey(sourcekey,&mediakey,TRUE);
678 sprintfW(szIndex,fmt,dwDiskId);
680 size = 2;
681 if (szVolumeLabel)
683 size +=lstrlenW(szVolumeLabel);
684 pt1 = szVolumeLabel;
686 else
687 pt1 = empty;
688 if (szDiskPrompt)
690 size +=lstrlenW(szDiskPrompt);
691 pt2 = szDiskPrompt;
693 else
694 pt2 = empty;
696 size *=sizeof(WCHAR);
698 buffer = msi_alloc(size);
699 sprintfW(buffer,disk_fmt,pt1,pt2);
701 RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);
702 msi_free( buffer );
704 RegCloseKey(sourcekey);
705 RegCloseKey(mediakey);
707 return ERROR_SUCCESS;
710 /******************************************************************
711 * MsiSourceListAddSourceExA (MSI.@)
713 UINT WINAPI MsiSourceListClearAllA( LPCSTR szProduct, LPCSTR szUserName, DWORD dwReserved )
715 FIXME("(%s %s %d)\n", debugstr_a(szProduct), debugstr_a(szUserName), dwReserved);
716 return ERROR_SUCCESS;
719 /******************************************************************
720 * MsiSourceListAddSourceExW (MSI.@)
722 UINT WINAPI MsiSourceListClearAllW( LPCWSTR szProduct, LPCWSTR szUserName, DWORD dwReserved )
724 FIXME("(%s %s %d)\n", debugstr_w(szProduct), debugstr_w(szUserName), dwReserved);
725 return ERROR_SUCCESS;