wined3d: Light parameter fixes.
[wine/gsoc_dplay.git] / dlls / msi / source.c
blob3b3e47f6dea7554ed093d86f5e428709ea64b2b0
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, 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)
61 rc = MSIREG_OpenUserProductsKey(szProduct, &rootkey, create);
62 else
63 rc = MSIREG_OpenProductsKey(szProduct, &rootkey, create);
65 if (rc)
66 return rc;
68 if (create)
69 rc = RegCreateKeyW(rootkey, szSourceList, key);
70 else
71 rc = RegOpenKeyW(rootkey,szSourceList, key);
73 return rc;
76 static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
78 UINT rc;
79 static const WCHAR media[] = {'M','e','d','i','a',0};
81 if (create)
82 rc = RegCreateKeyW(rootkey, media, key);
83 else
84 rc = RegOpenKeyW(rootkey,media, key);
86 return rc;
89 static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
91 UINT rc;
92 static const WCHAR net[] = {'N','e','t',0};
94 if (create)
95 rc = RegCreateKeyW(rootkey, net, key);
96 else
97 rc = RegOpenKeyW(rootkey, net, key);
99 return rc;
102 static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
104 UINT rc;
105 static const WCHAR URL[] = {'U','R','L',0};
107 if (create)
108 rc = RegCreateKeyW(rootkey, URL, key);
109 else
110 rc = RegOpenKeyW(rootkey, URL, key);
112 return rc;
116 static UINT find_given_source(HKEY key, LPCWSTR szSource, media_info *ss)
118 DWORD index = 0;
119 WCHAR szIndex[10];
120 DWORD size;
121 DWORD val_size;
122 LPWSTR val;
123 UINT rc = ERROR_SUCCESS;
125 while (rc == ERROR_SUCCESS)
127 val = NULL;
128 val_size = 0;
129 size = sizeof(szIndex)/sizeof(szIndex[0]);
130 rc = RegEnumValueW(key, index, szIndex, &size, NULL, NULL, NULL, &val_size);
131 if (rc != ERROR_NO_MORE_ITEMS)
133 val = msi_alloc(val_size);
134 RegEnumValueW(key, index, szIndex, &size, NULL, NULL, (LPBYTE)val,
135 &val_size);
136 if (lstrcmpiW(szSource,val)==0)
138 ss->path = val;
139 strcpyW(ss->szIndex,szIndex);
140 break;
142 else
143 strcpyW(ss->szIndex,szIndex);
145 msi_free(val);
146 index ++;
149 return rc;
152 /******************************************************************
153 * MsiSourceListGetInfoW (MSI.@)
155 UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
156 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
157 LPCWSTR szProperty, LPWSTR szValue,
158 LPDWORD pcchValue)
160 HKEY sourcekey;
161 UINT rc;
163 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szProperty));
165 if (!szProduct || lstrlenW(szProduct) > 39)
166 return ERROR_INVALID_PARAMETER;
168 if (szValue && !pcchValue)
169 return ERROR_INVALID_PARAMETER;
171 if (dwOptions == MSICODE_PATCH)
173 FIXME("Unhandled options MSICODE_PATCH\n");
174 return ERROR_FUNCTION_FAILED;
177 if (szUserSid)
178 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
180 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
181 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
183 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
184 rc = OpenSourceKey(szProduct, &sourcekey, FALSE, FALSE);
185 else
186 rc = OpenSourceKey(szProduct, &sourcekey, TRUE, FALSE);
188 if (rc != ERROR_SUCCESS)
189 return ERROR_UNKNOWN_PRODUCT;
191 if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
193 HKEY key;
194 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
195 if (rc == ERROR_SUCCESS)
196 rc = RegQueryValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW,
197 0, 0, (LPBYTE)szValue, pcchValue);
198 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
199 rc = ERROR_UNKNOWN_PROPERTY;
200 RegCloseKey(key);
202 else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) ==0)
204 HKEY key;
205 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
206 if (rc == ERROR_SUCCESS)
207 rc = RegQueryValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0, 0,
208 (LPBYTE)szValue, pcchValue);
209 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
210 rc = ERROR_UNKNOWN_PROPERTY;
211 RegCloseKey(key);
213 else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
215 LPWSTR buffer;
216 DWORD size = 0;
218 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
219 NULL, &size);
220 if (size == 0)
221 rc = ERROR_UNKNOWN_PROPERTY;
222 else
224 LPWSTR ptr;
225 buffer = msi_alloc(size);
226 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
227 0, 0, (LPBYTE)buffer,&size);
228 ptr = strchrW(buffer,';');
229 if (ptr) ptr = strchrW(ptr+1,';');
230 if (!ptr)
231 rc = ERROR_UNKNOWN_PROPERTY;
232 else
234 ptr ++;
235 lstrcpynW(szValue, ptr, *pcchValue);
236 if (lstrlenW(ptr) > *pcchValue)
238 *pcchValue = lstrlenW(ptr)+1;
239 rc = ERROR_MORE_DATA;
241 else
242 rc = ERROR_SUCCESS;
244 msi_free(buffer);
247 else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0)
249 LPWSTR buffer;
250 DWORD size = 0;
252 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
253 NULL, &size);
254 if (size == 0)
255 rc = ERROR_UNKNOWN_PROPERTY;
256 else
258 buffer = msi_alloc(size);
259 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
260 0, 0, (LPBYTE)buffer,&size);
261 if (*pcchValue < 1)
263 rc = ERROR_MORE_DATA;
264 *pcchValue = 1;
266 else
268 szValue[0] = buffer[0];
269 rc = ERROR_SUCCESS;
271 msi_free(buffer);
274 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
276 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0,
277 (LPBYTE)szValue, pcchValue);
278 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
279 rc = ERROR_UNKNOWN_PROPERTY;
281 else
283 FIXME("Unknown property %s\n",debugstr_w(szProperty));
284 rc = ERROR_UNKNOWN_PROPERTY;
287 RegCloseKey(sourcekey);
288 return rc;
291 /******************************************************************
292 * MsiSourceListSetInfoW (MSI.@)
294 UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
295 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
296 LPCWSTR szProperty, LPCWSTR szValue)
298 HKEY sourcekey;
299 UINT rc;
301 TRACE("%s %s %x %x %s %s\n", debugstr_w(szProduct), debugstr_w(szUserSid),
302 dwContext, dwOptions, debugstr_w(szProperty), debugstr_w(szValue));
304 if (!szProduct || lstrlenW(szProduct) > 39)
305 return ERROR_INVALID_PARAMETER;
307 if (dwOptions & MSICODE_PATCH)
309 FIXME("Unhandled options MSICODE_PATCH\n");
310 return ERROR_FUNCTION_FAILED;
313 if (szUserSid)
314 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
316 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
317 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
319 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
320 rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
321 else
322 rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
324 if (rc != ERROR_SUCCESS)
325 return ERROR_UNKNOWN_PRODUCT;
328 if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
330 HKEY key;
331 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
332 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
333 if (rc == ERROR_SUCCESS)
334 rc = RegSetValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW, 0,
335 REG_SZ, (const BYTE *)szValue, size);
336 if (rc != ERROR_SUCCESS)
337 rc = ERROR_UNKNOWN_PROPERTY;
338 RegCloseKey(key);
340 else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) == 0)
342 HKEY key;
343 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
344 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
345 if (rc == ERROR_SUCCESS)
346 rc = RegSetValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0,
347 REG_SZ, (const BYTE *)szValue, size);
348 if (rc != ERROR_SUCCESS)
349 rc = ERROR_UNKNOWN_PROPERTY;
350 RegCloseKey(key);
352 else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
354 LPWSTR buffer = NULL;
355 DWORD size;
356 WCHAR typechar = 'n';
357 static const WCHAR LastUsedSource_Fmt[] = {'%','c',';','%','i',';','%','s',0};
359 /* make sure the source is registered */
360 MsiSourceListAddSourceExW(szProduct, szUserSid, dwContext,
361 dwOptions, szValue, 0);
363 if (dwOptions & MSISOURCETYPE_NETWORK)
364 typechar = 'n';
365 else if (dwOptions & MSISOURCETYPE_URL)
366 typechar = 'u';
367 else if (dwOptions & MSISOURCETYPE_MEDIA)
368 typechar = 'm';
369 else
370 ERR("Unknown source type! %x\n", dwOptions);
372 size = (lstrlenW(szValue)+5)*sizeof(WCHAR);
373 buffer = msi_alloc(size);
374 sprintfW(buffer, LastUsedSource_Fmt, typechar, 1, szValue);
375 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0,
376 REG_EXPAND_SZ, (LPBYTE)buffer, size);
377 if (rc != ERROR_SUCCESS)
378 rc = ERROR_UNKNOWN_PROPERTY;
379 msi_free( buffer );
381 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
383 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
384 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0,
385 REG_SZ, (const BYTE *)szValue, size);
386 if (rc != ERROR_SUCCESS)
387 rc = ERROR_UNKNOWN_PROPERTY;
389 else
391 FIXME("Unknown property %s\n",debugstr_w(szProperty));
392 rc = ERROR_UNKNOWN_PROPERTY;
395 RegCloseKey(sourcekey);
396 return rc;
400 /******************************************************************
401 * MsiSourceListAddSourceW (MSI.@)
403 UINT WINAPI MsiSourceListAddSourceW( LPCWSTR szProduct, LPCWSTR szUserName,
404 DWORD dwReserved, LPCWSTR szSource)
406 INT ret;
407 LPWSTR sidstr = NULL;
408 DWORD sidsize = 0;
409 DWORD domsize = 0;
411 TRACE("%s %s %s\n", debugstr_w(szProduct), debugstr_w(szUserName), debugstr_w(szSource));
413 if (LookupAccountNameW(NULL, szUserName, NULL, &sidsize, NULL, &domsize, NULL))
415 PSID psid = msi_alloc(sidsize);
417 if (LookupAccountNameW(NULL, szUserName, psid, &sidsize, NULL, &domsize, NULL))
418 ConvertSidToStringSidW(psid, &sidstr);
420 msi_free(psid);
423 ret = MsiSourceListAddSourceExW(szProduct, sidstr,
424 MSIINSTALLCONTEXT_USERMANAGED, MSISOURCETYPE_NETWORK, szSource, 0);
426 if (sidstr)
427 LocalFree(sidstr);
429 return ret;
432 /******************************************************************
433 * MsiSourceListAddSourceA (MSI.@)
435 UINT WINAPI MsiSourceListAddSourceA( LPCSTR szProduct, LPCSTR szUserName,
436 DWORD dwReserved, LPCSTR szSource)
438 INT ret;
439 LPWSTR szwproduct;
440 LPWSTR szwusername;
441 LPWSTR szwsource;
443 szwproduct = strdupAtoW( szProduct );
444 szwusername = strdupAtoW( szUserName );
445 szwsource = strdupAtoW( szSource );
447 ret = MsiSourceListAddSourceW(szwproduct, szwusername, 0, szwsource);
449 msi_free(szwproduct);
450 msi_free(szwusername);
451 msi_free(szwsource);
453 return ret;
456 /******************************************************************
457 * MsiSourceListAddSourceExW (MSI.@)
459 UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
460 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource,
461 DWORD dwIndex)
463 HKEY sourcekey;
464 HKEY typekey;
465 UINT rc;
466 media_info source_struct;
468 TRACE("%s %s %x %x %s %i\n", debugstr_w(szProduct), debugstr_w(szUserSid),
469 dwContext, dwOptions, debugstr_w(szSource), dwIndex);
471 if (!szProduct)
472 return ERROR_INVALID_PARAMETER;
474 if (!szSource)
475 return ERROR_INVALID_PARAMETER;
477 if (dwOptions & MSICODE_PATCH)
479 FIXME("Unhandled options MSICODE_PATCH\n");
480 return ERROR_FUNCTION_FAILED;
483 if (szUserSid)
484 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
486 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
487 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
489 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
490 rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
491 else
492 rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
494 if (rc != ERROR_SUCCESS)
495 return ERROR_UNKNOWN_PRODUCT;
497 if (dwOptions & MSISOURCETYPE_NETWORK)
498 rc = OpenNetworkSubkey(sourcekey, &typekey, TRUE);
499 else if (dwOptions & MSISOURCETYPE_URL)
500 rc = OpenURLSubkey(sourcekey, &typekey, TRUE);
501 else if (dwOptions & MSISOURCETYPE_MEDIA)
502 rc = OpenMediaSubkey(sourcekey, &typekey, TRUE);
503 else
505 ERR("unknown media type: %08x\n", dwOptions);
506 RegCloseKey(sourcekey);
507 return ERROR_FUNCTION_FAILED;
510 source_struct.szIndex[0] = 0;
511 if (find_given_source(typekey, szSource, &source_struct)==ERROR_SUCCESS)
513 DWORD current_index = atoiW(source_struct.szIndex);
514 /* found the source */
515 if (dwIndex > 0 && current_index != dwIndex)
516 FIXME("Need to reorder the sources!\n");
517 msi_free( source_struct.path );
519 else
521 DWORD current_index = 0;
522 static const WCHAR fmt[] = {'%','i',0};
523 DWORD size = lstrlenW(szSource)*sizeof(WCHAR);
525 if (source_struct.szIndex[0])
526 current_index = atoiW(source_struct.szIndex);
527 /* new source */
528 if (dwIndex > 0 && dwIndex < current_index)
529 FIXME("Need to reorder the sources!\n");
531 current_index ++;
532 sprintfW(source_struct.szIndex,fmt,current_index);
533 rc = RegSetValueExW(typekey, source_struct.szIndex, 0, REG_EXPAND_SZ,
534 (const BYTE *)szSource, size);
537 RegCloseKey(typekey);
538 RegCloseKey(sourcekey);
539 return rc;
542 /******************************************************************
543 * MsiSourceListAddMediaDisk(MSI.@)
545 UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
546 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId,
547 LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt)
549 HKEY sourcekey;
550 HKEY mediakey;
551 UINT rc;
552 WCHAR szIndex[10];
553 static const WCHAR fmt[] = {'%','i',0};
554 static const WCHAR disk_fmt[] = {'%','s',';','%','s',0};
555 static const WCHAR empty[1] = {0};
556 LPCWSTR pt1,pt2;
557 LPWSTR buffer;
558 DWORD size;
560 TRACE("%s %s %x %x %i %s %s\n", debugstr_w(szProduct),
561 debugstr_w(szUserSid), dwContext, dwOptions, dwDiskId,
562 debugstr_w(szVolumeLabel), debugstr_w(szDiskPrompt));
564 if (!szProduct || lstrlenW(szProduct) > 39)
565 return ERROR_INVALID_PARAMETER;
567 if (dwOptions & MSICODE_PATCH)
569 FIXME("Unhandled options MSICODE_PATCH\n");
570 return ERROR_FUNCTION_FAILED;
573 if (szUserSid)
574 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
576 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
577 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
579 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
580 rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
581 else
582 rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
584 if (rc != ERROR_SUCCESS)
585 return ERROR_UNKNOWN_PRODUCT;
587 OpenMediaSubkey(sourcekey,&mediakey,TRUE);
589 sprintfW(szIndex,fmt,dwDiskId);
591 size = 2;
592 if (szVolumeLabel)
594 size +=lstrlenW(szVolumeLabel);
595 pt1 = szVolumeLabel;
597 else
598 pt1 = empty;
599 if (szDiskPrompt)
601 size +=lstrlenW(szDiskPrompt);
602 pt2 = szDiskPrompt;
604 else
605 pt2 = empty;
607 size *=sizeof(WCHAR);
609 buffer = msi_alloc(size);
610 sprintfW(buffer,disk_fmt,pt1,pt2);
612 RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);
613 msi_free( buffer );
615 RegCloseKey(sourcekey);
616 RegCloseKey(mediakey);
618 return ERROR_SUCCESS;
621 /******************************************************************
622 * MsiSourceListAddSourceExA (MSI.@)
624 UINT WINAPI MsiSourceListClearAllA( LPCSTR szProduct, LPCSTR szUserName, DWORD dwReserved )
626 FIXME("(%s %s %d)\n", debugstr_a(szProduct), debugstr_a(szUserName), dwReserved);
627 return ERROR_SUCCESS;
630 /******************************************************************
631 * MsiSourceListAddSourceExW (MSI.@)
633 UINT WINAPI MsiSourceListClearAllW( LPCWSTR szProduct, LPCWSTR szUserName, DWORD dwReserved )
635 FIXME("(%s %s %d)\n", debugstr_w(szProduct), debugstr_w(szUserName), dwReserved);
636 return ERROR_SUCCESS;