source: trunk/src/shell32/shellpath.c@ 8048

Last change on this file since 8048 was 8048, checked in by sandervl, 23 years ago

PH: Wine resync + OS2 integration

File size: 27.5 KB
Line 
1/*
2 * Path Functions
3 *
4 * Many of this functions are in SHLWAPI.DLL also
5 *
6 */
7#include <string.h>
8#include <ctype.h>
9#include "debugtools.h"
10#include "windef.h"
11#include "winnls.h"
12#include "winreg.h"
13
14#include "shlobj.h"
15#include "shell32_main.h"
16#include "wine/undocshell.h"
17#include "wine/unicode.h"
18#include "shlwapi.h"
19
20DEFAULT_DEBUG_CHANNEL(shell);
21
22/*
23 ########## Combining and Constructing paths ##########
24*/
25
26/*************************************************************************
27 * PathAppendAW [SHELL32.36]
28 */
29BOOL WINAPI PathAppendAW(
30 LPVOID lpszPath1,
31 LPCVOID lpszPath2)
32{
33 if (SHELL_OsIsUnicode())
34 return PathAppendW(lpszPath1, lpszPath2);
35 return PathAppendA(lpszPath1, lpszPath2);
36}
37
38/*************************************************************************
39 * PathCombineAW [SHELL32.37]
40 */
41LPVOID WINAPI PathCombineAW(
42 LPVOID szDest,
43 LPCVOID lpszDir,
44 LPCVOID lpszFile)
45{
46 if (SHELL_OsIsUnicode())
47 return PathCombineW( szDest, lpszDir, lpszFile );
48 return PathCombineA( szDest, lpszDir, lpszFile );
49}
50
51/*************************************************************************
52 * PathAddBackslashAW [SHELL32.32]
53 */
54LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
55{
56 if(SHELL_OsIsUnicode())
57 return PathAddBackslashW(lpszPath);
58 return PathAddBackslashA(lpszPath);
59}
60
61/*************************************************************************
62 * PathBuildRootAW [SHELL32.30]
63 */
64LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
65{
66 if(SHELL_OsIsUnicode())
67 return PathBuildRootW(lpszPath, drive);
68 return PathBuildRootA(lpszPath, drive);
69}
70
71/*
72 Extracting Component Parts
73*/
74
75/*************************************************************************
76 * PathFindFileNameAW [SHELL32.34]
77 */
78LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
79{
80 if(SHELL_OsIsUnicode())
81 return PathFindFileNameW(lpszPath);
82 return PathFindFileNameA(lpszPath);
83}
84
85/*************************************************************************
86 * PathFindExtensionAW [SHELL32.31]
87 */
88LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
89{
90 if (SHELL_OsIsUnicode())
91 return PathFindExtensionW(lpszPath);
92 return PathFindExtensionA(lpszPath);
93
94}
95
96/*************************************************************************
97 * PathGetExtensionA [internal]
98 *
99 * NOTES
100 * exported by ordinal
101 * return value points to the first char after the dot
102 */
103static LPSTR PathGetExtensionA(LPCSTR lpszPath)
104{
105 TRACE("(%s)\n",lpszPath);
106
107 lpszPath = PathFindExtensionA(lpszPath);
108 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
109}
110
111/*************************************************************************
112 * PathGetExtensionW [internal]
113 */
114static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
115{
116 TRACE("(%s)\n",debugstr_w(lpszPath));
117
118 lpszPath = PathFindExtensionW(lpszPath);
119 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
120}
121
122/*************************************************************************
123 * PathGetExtensionAW [SHELL32.158]
124 */
125LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath, DWORD void1, DWORD void2)
126{
127 if (SHELL_OsIsUnicode())
128 return PathGetExtensionW(lpszPath);
129 return PathGetExtensionA(lpszPath);
130}
131
132/*************************************************************************
133 * PathGetArgsAW [SHELL32.52]
134 */
135LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
136{
137 if (SHELL_OsIsUnicode())
138 return PathGetArgsW(lpszPath);
139 return PathGetArgsA(lpszPath);
140}
141
142/*************************************************************************
143 * PathGetDriveNumber [SHELL32.57]
144 */
145int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
146{
147 if (SHELL_OsIsUnicode())
148 return PathGetDriveNumberW(lpszPath);
149 return PathGetDriveNumberA(lpszPath);
150}
151
152/*************************************************************************
153 * PathRemoveFileSpec [SHELL32.35]
154 */
155BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
156{
157 if (SHELL_OsIsUnicode())
158 return PathRemoveFileSpecW(lpszPath);
159 return PathRemoveFileSpecA(lpszPath);
160}
161
162/*************************************************************************
163 * PathStripPathAW [SHELL32.38]
164 */
165void WINAPI PathStripPathAW(LPVOID lpszPath)
166{
167 if (SHELL_OsIsUnicode())
168 return PathStripPathW(lpszPath);
169 return PathStripPathA(lpszPath);
170}
171
172/*************************************************************************
173 * PathStripToRootAW [SHELL32.50]
174 */
175BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
176{
177 if (SHELL_OsIsUnicode())
178 return PathStripToRootW(lpszPath);
179 return PathStripToRootA(lpszPath);
180}
181
182/*************************************************************************
183 * PathRemoveArgsAW [SHELL32.251]
184 */
185void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
186{
187 if (SHELL_OsIsUnicode())
188 PathRemoveArgsW(lpszPath);
189 PathRemoveArgsA(lpszPath);
190}
191
192/*************************************************************************
193 * PathRemoveExtensionAW [SHELL32.250]
194 */
195void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
196{
197 if (SHELL_OsIsUnicode())
198 return PathRemoveExtensionW(lpszPath);
199 return PathRemoveExtensionA(lpszPath);
200}
201
202
203/*
204 Path Manipulations
205*/
206
207/*************************************************************************
208 * PathGetShortPathA [internal]
209 */
210LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
211{
212 FIXME("%s stub\n", lpszPath);
213 return NULL;
214}
215
216/*************************************************************************
217 * PathGetShortPathW [internal]
218 */
219LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
220{
221 FIXME("%s stub\n", debugstr_w(lpszPath));
222 return NULL;
223}
224
225/*************************************************************************
226 * PathGetShortPathAW [SHELL32.92]
227 */
228LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
229{
230 if(SHELL_OsIsUnicode())
231 return PathGetShortPathW(lpszPath);
232 return PathGetShortPathA(lpszPath);
233}
234
235/*************************************************************************
236 * PathRemoveBlanksAW [SHELL32.33]
237 */
238void WINAPI PathRemoveBlanksAW(LPVOID str)
239{
240 if(SHELL_OsIsUnicode())
241 PathRemoveBlanksW(str);
242 PathRemoveBlanksA(str);
243}
244
245/*************************************************************************
246 * PathQuoteSpacesAW [SHELL32.55]
247 */
248LPVOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
249{
250 if(SHELL_OsIsUnicode())
251 return PathQuoteSpacesW(lpszPath);
252 return PathQuoteSpacesA(lpszPath);
253}
254
255/*************************************************************************
256 * PathUnquoteSpacesAW [SHELL32.56]
257 */
258VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
259{
260 if(SHELL_OsIsUnicode())
261 PathUnquoteSpacesW(str);
262 else
263 PathUnquoteSpacesA(str);
264}
265
266/*************************************************************************
267 * PathParseIconLocationAW [SHELL32.249]
268 */
269int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
270{
271 if(SHELL_OsIsUnicode())
272 return PathParseIconLocationW(lpszPath);
273 return PathParseIconLocationA(lpszPath);
274}
275
276/*
277 ########## Path Testing ##########
278*/
279/*************************************************************************
280 * PathIsUNCAW [SHELL32.39]
281 */
282BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
283{
284 if (SHELL_OsIsUnicode())
285 return PathIsUNCW( lpszPath );
286 return PathIsUNCA( lpszPath );
287}
288
289/*************************************************************************
290 * PathIsRelativeAW [SHELL32.40]
291 */
292BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
293{
294 if (SHELL_OsIsUnicode())
295 return PathIsRelativeW( lpszPath );
296 return PathIsRelativeA( lpszPath );
297}
298
299/*************************************************************************
300 * PathIsRootAW [SHELL32.29]
301 */
302BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
303{
304 if (SHELL_OsIsUnicode())
305 return PathIsRootW(lpszPath);
306 return PathIsRootA(lpszPath);
307}
308
309/*************************************************************************
310 * PathIsExeA [internal]
311 */
312static BOOL PathIsExeA (LPCSTR lpszPath)
313{
314 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
315 int i = 0;
316 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
317
318 TRACE("path=%s\n",lpszPath);
319
320 for(i=0; lpszExtensions[i]; i++)
321 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
322
323 return FALSE;
324}
325
326/*************************************************************************
327 * PathIsExeW [internal]
328 */
329static BOOL PathIsExeW (LPCWSTR lpszPath)
330{
331 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
332 int i = 0;
333 static WCHAR lpszExtensions[6][4] =
334 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
335 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
336
337 TRACE("path=%s\n",debugstr_w(lpszPath));
338
339 for(i=0; lpszExtensions[i][0]; i++)
340#ifdef __WIN32OS2__
341 if (!lstrcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
342#else
343 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
344#endif
345 return FALSE;
346}
347
348/*************************************************************************
349 * PathIsExeAW [SHELL32.43]
350 */
351BOOL WINAPI PathIsExeAW (LPCVOID path)
352{
353 if (SHELL_OsIsUnicode())
354 return PathIsExeW (path);
355 return PathIsExeA(path);
356}
357
358/*************************************************************************
359 * PathIsDirectoryAW [SHELL32.159]
360 */
361BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
362{
363 if (SHELL_OsIsUnicode())
364 return PathIsDirectoryW (lpszPath);
365 return PathIsDirectoryA (lpszPath);
366}
367
368/*************************************************************************
369 * PathFileExistsAW [SHELL32.45]
370 */
371BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
372{
373 if (SHELL_OsIsUnicode())
374 return PathFileExistsW (lpszPath);
375 return PathFileExistsA (lpszPath);
376}
377
378/*************************************************************************
379 * PathMatchSpecAW [SHELL32.46]
380 */
381BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
382{
383 if (SHELL_OsIsUnicode())
384 return PathMatchSpecW( name, mask );
385 return PathMatchSpecA( name, mask );
386}
387
388/*************************************************************************
389 * PathIsSameRootAW [SHELL32.650]
390 */
391BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
392{
393 if (SHELL_OsIsUnicode())
394 return PathIsSameRootW(lpszPath1, lpszPath2);
395 return PathIsSameRootA(lpszPath1, lpszPath2);
396}
397
398/*************************************************************************
399 * IsLFNDriveA [SHELL32.119]
400 *
401 * NOTES
402 * exported by ordinal Name
403 */
404BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
405{
406 DWORD fnlen;
407
408 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
409 return FALSE;
410 return fnlen>12;
411}
412
413/*
414 ########## Creating Something Unique ##########
415*/
416/*************************************************************************
417 * PathMakeUniqueNameA [internal]
418 */
419BOOL WINAPI PathMakeUniqueNameA(
420 LPSTR lpszBuffer,
421 DWORD dwBuffSize,
422 LPCSTR lpszShortName,
423 LPCSTR lpszLongName,
424 LPCSTR lpszPathName)
425{
426 FIXME("%p %lu %s %s %s stub\n",
427 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
428 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
429 return TRUE;
430}
431
432/*************************************************************************
433 * PathMakeUniqueNameW [internal]
434 */
435BOOL WINAPI PathMakeUniqueNameW(
436 LPWSTR lpszBuffer,
437 DWORD dwBuffSize,
438 LPCWSTR lpszShortName,
439 LPCWSTR lpszLongName,
440 LPCWSTR lpszPathName)
441{
442 FIXME("%p %lu %s %s %s stub\n",
443 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
444 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
445 return TRUE;
446}
447
448/*************************************************************************
449 * PathMakeUniqueNameAW [SHELL32.47]
450 */
451BOOL WINAPI PathMakeUniqueNameAW(
452 LPVOID lpszBuffer,
453 DWORD dwBuffSize,
454 LPCVOID lpszShortName,
455 LPCVOID lpszLongName,
456 LPCVOID lpszPathName)
457{
458 if (SHELL_OsIsUnicode())
459 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
460 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
461}
462
463/*************************************************************************
464 * PathYetAnotherMakeUniqueNameA [SHELL32.75]
465 *
466 * NOTES
467 * exported by ordinal
468 */
469BOOL WINAPI PathYetAnotherMakeUniqueNameA(
470 LPSTR lpszBuffer,
471 LPCSTR lpszPathName,
472 LPCSTR lpszShortName,
473 LPCSTR lpszLongName)
474{
475 FIXME("(%p,%p, %p ,%p):stub.\n",
476 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
477 return TRUE;
478}
479
480#ifdef __WIN32OS2__
481
482BOOL WINAPI PathYetAnotherMakeUniqueNameW(
483 LPWSTR lpszBuffer,
484 LPCWSTR lpszPathName,
485 LPCWSTR lpszShortName,
486 LPCWSTR lpszLongName)
487{
488 FIXME("PathYetAnotherMakeUniqueNameW (%p,%p, %p ,%p):stub.\n",
489 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
490 return TRUE;
491}
492
493BOOL WINAPI PathYetAnotherMakeUniqueNameAW(
494 LPSTR lpszBuffer,
495 LPCSTR lpszPathName,
496 LPCSTR lpszShortName,
497 LPCSTR lpszLongName)
498{
499 if (SHELL_OsIsUnicode())
500 return PathYetAnotherMakeUniqueNameW((LPWSTR)lpszBuffer,(LPCWSTR)lpszPathName, (LPCWSTR)lpszShortName,(LPCWSTR)lpszLongName);
501 return PathYetAnotherMakeUniqueNameA(lpszBuffer, lpszPathName, lpszShortName,lpszLongName);
502}
503#endif
504
505
506/*
507 ########## cleaning and resolving paths ##########
508 */
509
510/*************************************************************************
511 * PathFindOnPathAW [SHELL32]
512 */
513BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
514{
515 if (SHELL_OsIsUnicode())
516 return PathFindOnPathW(sFile, sOtherDirs);
517 return PathFindOnPathA(sFile, sOtherDirs);
518}
519
520/*************************************************************************
521 * PathCleanupSpecAW [SHELL32]
522 */
523DWORD WINAPI PathCleanupSpecAW (LPCVOID x, LPVOID y)
524{
525 FIXME("(%p, %p) stub\n",x,y);
526 return TRUE;
527}
528
529/*************************************************************************
530 * PathQualifyA [SHELL32]
531 */
532BOOL WINAPI PathQualifyA(LPCSTR pszPath)
533{
534 FIXME("%s\n",pszPath);
535 return 0;
536}
537
538/*************************************************************************
539 * PathQualifyW [SHELL32]
540 */
541BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
542{
543 FIXME("%s\n",debugstr_w(pszPath));
544 return 0;
545}
546
547/*************************************************************************
548 * PathQualifyAW [SHELL32]
549 */
550BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
551{
552 if (SHELL_OsIsUnicode())
553 return PathQualifyW(pszPath);
554 return PathQualifyA(pszPath);
555}
556
557/*************************************************************************
558 * PathResolveA [SHELL32.51]
559 */
560BOOL WINAPI PathResolveA(
561 LPSTR lpszPath,
562 LPCSTR *alpszPaths,
563 DWORD dwFlags)
564{
565 FIXME("(%s,%p,0x%08lx),stub!\n",
566 lpszPath, *alpszPaths, dwFlags);
567 return 0;
568}
569
570/*************************************************************************
571 * PathResolveW [SHELL32]
572 */
573BOOL WINAPI PathResolveW(
574 LPWSTR lpszPath,
575 LPCWSTR *alpszPaths,
576 DWORD dwFlags)
577{
578 FIXME("(%s,%p,0x%08lx),stub!\n",
579 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
580 return 0;
581}
582
583/*************************************************************************
584 * PathResolveAW [SHELL32]
585 */
586BOOL WINAPI PathResolveAW(
587 LPVOID lpszPath,
588 LPCVOID *alpszPaths,
589 DWORD dwFlags)
590{
591 if (SHELL_OsIsUnicode())
592 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
593 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
594}
595
596/*************************************************************************
597* PathProcessCommandA [SHELL32.653]
598*/
599HRESULT WINAPI PathProcessCommandA (
600 LPCSTR lpszPath,
601 LPSTR lpszBuff,
602 DWORD dwBuffSize,
603 DWORD dwFlags)
604{
605 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
606 lpszPath, lpszBuff, dwBuffSize, dwFlags);
607 strcpy(lpszBuff, lpszPath);
608 return 0;
609}
610
611/*************************************************************************
612* PathProcessCommandW
613*/
614HRESULT WINAPI PathProcessCommandW (
615 LPCWSTR lpszPath,
616 LPWSTR lpszBuff,
617 DWORD dwBuffSize,
618 DWORD dwFlags)
619{
620 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
621 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
622 strcpyW(lpszBuff, lpszPath);
623 return 0;
624}
625
626/*************************************************************************
627* PathProcessCommandAW
628*/
629HRESULT WINAPI PathProcessCommandAW (
630 LPCVOID lpszPath,
631 LPVOID lpszBuff,
632 DWORD dwBuffSize,
633 DWORD dwFlags)
634{
635 if (SHELL_OsIsUnicode())
636 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
637 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
638}
639
640/*
641 ########## special ##########
642*/
643
644/*************************************************************************
645 * PathSetDlgItemPathAW
646 */
647BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
648{ if (SHELL_OsIsUnicode())
649 return PathSetDlgItemPathW(hDlg, id, pszPath);
650 return PathSetDlgItemPathA(hDlg, id, pszPath);
651}
652
653
654/*************************************************************************
655 * SHGetSpecialFolderPathA [SHELL32.175]
656 *
657 * converts csidl to path
658 */
659
660static const char * const szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
661static const char * const szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
662static const char * const szSetup = "Software\\Microsoft\\Windows\\CurrentVersion\\Setup";
663static const char * const szCurrentVersion = "Software\\Microsoft\\Windows\\CurrentVersion";
664#if 0
665static const char * const szEnvUserProfile = "%USERPROFILE%";
666static const char * const szEnvSystemRoot = "%SYSTEMROOT%";
667#endif
668
669typedef struct
670{
671 DWORD dwFlags;
672 HKEY hRootKey;
673 LPCSTR szValueName;
674 LPCSTR szDefaultPath; /* fallback string; sub dir of windows directory */
675} CSIDL_DATA;
676
677#define CSIDL_MYFLAG_SHFOLDER 1
678#define CSIDL_MYFLAG_SETUP 2
679#define CSIDL_MYFLAG_CURRVER 4
680#define CSIDL_MYFLAG_RELATIVE 8
681
682#define HKLM HKEY_LOCAL_MACHINE
683#define HKCU HKEY_CURRENT_USER
684static const CSIDL_DATA CSIDL_Data[] =
685{
686 { /* CSIDL_DESKTOP */
687 9, HKCU,
688 "Desktop",
689 "Desktop"
690 },
691 { /* CSIDL_INTERNET (??) */
692 0, 1, /* FIXME */
693 NULL,
694 NULL,
695 },
696 { /* CSIDL_PROGRAMS */
697 9, HKCU,
698 "Programs",
699 "Start Menu\\Programs"
700 },
701 { /* CSIDL_CONTROLS (.CPL files) */
702 10, HKLM,
703 "SysDir",
704 "SYSTEM"
705 },
706 { /* CSIDL_PRINTERS */
707 10, HKLM,
708 "SysDir",
709 "SYSTEM"
710 },
711 { /* CSIDL_PERSONAL */
712 1, HKCU,
713 "Personal",
714 "My Documents"
715 },
716 { /* CSIDL_FAVORITES */
717 9, HKCU,
718 "Favorites",
719 "Favorites"
720 },
721 { /* CSIDL_STARTUP */
722 9, HKCU,
723 "StartUp",
724 "Start Menu\\Programs\\StartUp"
725 },
726 { /* CSIDL_RECENT */
727 9, HKCU,
728 "Recent",
729 "Recent"
730 },
731 { /* CSIDL_SENDTO */
732 9, HKCU,
733 "SendTo",
734 "SendTo"
735 },
736 { /* CSIDL_BITBUCKET (is this c:\recycled ?) */
737 0, 1, /* FIXME */
738 NULL,
739 "recycled"
740 },
741 { /* CSIDL_STARTMENU */
742 9, HKCU,
743 "Start Menu",
744 "Start Menu"
745 },
746 { /* CSIDL_MYDOCUMENTS */
747 0, 1, /* FIXME */
748 NULL,
749 NULL,
750 },
751 { /* CSIDL_MYMUSIC */
752 0, 1, /* FIXME */
753 NULL,
754 NULL,
755 },
756 { /*CSIDL_MYVIDEO */
757 0, 1, /* FIXME */
758 NULL,
759 NULL,
760 },
761 { /* unassigned */
762 0, 0,
763 NULL,
764 NULL,
765 },
766 { /* CSIDL_DESKTOPDIRECTORY */
767 9, HKCU,
768 "Desktop",
769 "Desktop"
770 },
771 { /* CSIDL_DRIVES */
772 0, 1, /* FIXME */
773 NULL,
774 "My Computer"
775 },
776 { /* CSIDL_NETWORK */
777 0, 1, /* FIXME */
778 NULL,
779 "Network Neighborhood"
780 },
781 { /* CSIDL_NETHOOD */
782 9, HKCU,
783 "NetHood",
784 "NetHood"
785 },
786 { /* CSIDL_FONTS */
787 9, HKCU,
788 "Fonts",
789 "Fonts"
790 },
791 { /* CSIDL_TEMPLATES */
792 9, HKCU,
793 "Templates",
794 "ShellNew"
795 },
796 { /* CSIDL_COMMON_STARTMENU */
797 9, HKLM,
798 "Common Start Menu",
799 "Start Menu"
800 },
801 { /* CSIDL_COMMON_PROGRAMS */
802 9, HKLM,
803 "Common Programs",
804 ""
805 },
806 { /* CSIDL_COMMON_STARTUP */
807 9, HKLM,
808 "Common StartUp",
809 "All Users\\Start Menu\\Programs\\StartUp"
810 },
811 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
812 9, HKLM,
813 "Common Desktop",
814 "Desktop"
815 },
816 { /* CSIDL_APPDATA */
817 9, HKCU,
818 "AppData",
819 "Application Data"
820 },
821 { /* CSIDL_PRINTHOOD */
822 9, HKCU,
823 "PrintHood",
824 "PrintHood"
825 },
826 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
827 1, HKCU,
828 "Local AppData",
829 "Local Settings\\Application Data",
830 },
831 { /* CSIDL_ALTSTARTUP */
832 0, 1, /* FIXME */
833 NULL,
834 NULL
835 },
836 { /* CSIDL_COMMON_ALTSTARTUP */
837 0, 1, /* FIXME */
838 NULL,
839 NULL
840 },
841 { /* CSIDL_COMMON_FAVORITES */
842 9, HKCU,
843 "Favorites",
844 "Favorites"
845 },
846 { /* CSIDL_INTERNET_CACHE */
847 9, HKCU,
848 "Cache",
849 "Temporary Internet Files"
850 },
851 { /* CSIDL_COOKIES */
852 9, HKCU,
853 "Cookies",
854 "Cookies"
855 },
856 { /* CSIDL_HISTORY */
857 9, HKCU,
858 "History",
859 "History"
860 },
861 { /* CSIDL_COMMON_APPDATA */
862 9, HKLM,
863 "Common AppData",
864 "All Users\\Application Data"
865 },
866 { /* CSIDL_WINDOWS */
867 2, HKLM,
868 "WinDir",
869 "Windows"
870 },
871 { /* CSIDL_SYSTEM */
872 10, HKLM,
873 "SysDir",
874 "SYSTEM"
875 },
876 { /* CSIDL_PROGRAM_FILES */
877 4, HKLM,
878 "ProgramFilesDir",
879 "Program Files"
880 },
881 { /* CSIDL_MYPICTURES */
882 1, HKCU,
883 "My Pictures",
884 "My Documents\\My Pictures"
885 },
886 { /* CSIDL_PROFILE */
887 10, HKLM,
888 "WinDir", /* correct ? */
889 ""
890 },
891 { /* CSIDL_SYSTEMX86 */
892 10, HKLM,
893 "SysDir",
894 "SYSTEM"
895 },
896 { /* CSIDL_PROGRAM_FILESX86 */
897 4, HKLM,
898 "ProgramFilesDir",
899 "Program Files"
900 },
901 { /* CSIDL_PROGRAM_FILES_COMMON */
902 4, HKLM,
903 "CommonFilesDir",
904 "Program Files\\Common Files" /* ? */
905 },
906 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
907 4, HKLM,
908 "CommonFilesDir",
909 "Program Files\\Common Files" /* ? */
910 },
911 { /* CSIDL_COMMON_TEMPLATES */
912 0, 1, /* FIXME */
913 NULL,
914 NULL
915 },
916 { /* CSIDL_COMMON_DOCUMENTS */
917 0, 1, /* FIXME */
918 NULL,
919 NULL
920 },
921 { /* CSIDL_COMMON_ADMINTOOLS */
922 0, 1, /* FIXME */
923 NULL,
924 NULL
925 },
926 { /* CSIDL_ADMINTOOLS */
927 9, HKCU,
928 "Administrative Tools",
929 "Start Menu\\Programs\\Administrative Tools"
930 },
931 { /* CSIDL_CONNECTIONS */
932 0, 1, /* FIXME */
933 NULL,
934 NULL
935 },
936 { /* unassigned 32*/
937 0, 0,
938 NULL,
939 NULL,
940 },
941 { /* unassigned 33*/
942 0, 0,
943 NULL,
944 NULL,
945 },
946 { /* unassigned 34*/
947 0, 0,
948 NULL,
949 NULL,
950 },
951 { /* CSIDL_COMMON_MUSIC */
952 0, 0, /* FIXME */
953 NULL,
954 NULL,
955 },
956 { /* CSIDL_COMMON_PICTURES */
957 0, 0, /* FIXME */
958 NULL,
959 NULL,
960 },
961 { /* CSIDL_COMMON_VIDEO */
962 0, 0, /* FIXME */
963 NULL,
964 NULL,
965 },
966 { /* CSIDL_RESOURCES */
967 0, 0, /* FIXME */
968 NULL,
969 NULL,
970 },
971 { /* CSIDL_RESOURCES_LOCALIZED */
972 0, 0, /* FIXME */
973 NULL,
974 NULL,
975 },
976 { /* CSIDL_COMMON_OEM_LINKS */
977 0, 0, /* FIXME */
978 NULL,
979 NULL,
980 },
981 { /* CSIDL_CDBURN_AREA */
982 0, 0, /* FIXME */
983 NULL,
984 NULL,
985 },
986 { /* unassigned 3C */
987 0, 0,
988 NULL,
989 NULL,
990 },
991 { /* CSIDL_COMPUTERSNEARME */
992 0, 0, /* FIXME */
993 NULL,
994 NULL,
995 }
996};
997#undef HKCU
998#undef HKLM
999
1000/**********************************************************************/
1001
1002BOOL WINAPI SHGetSpecialFolderPathA (
1003 HWND hwndOwner,
1004 LPSTR szPath,
1005 DWORD csidl,
1006 BOOL bCreate)
1007{
1008 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH];
1009 HKEY hRootKey, hKey;
1010 DWORD dwFlags;
1011 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1012 DWORD folder = csidl & CSIDL_FOLDER_MASK;
1013 CHAR *p;
1014
1015 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1016
1017 if ((folder > CSIDL_COMPUTERSNEARME) || (CSIDL_Data[folder].hRootKey == 0))
1018 {
1019 ERR("folder unknown or not allowed\n");
1020 return FALSE;
1021 }
1022 if (CSIDL_Data[folder].hRootKey == 1)
1023 {
1024 FIXME("folder unknown, please add.\n");
1025 return FALSE;
1026 }
1027
1028 dwFlags = CSIDL_Data[folder].dwFlags;
1029 hRootKey = CSIDL_Data[folder].hRootKey;
1030 strcpy(szValueName, CSIDL_Data[folder].szValueName);
1031 strcpy(szDefaultPath, CSIDL_Data[folder].szDefaultPath);
1032
1033 if (dwFlags & CSIDL_MYFLAG_SHFOLDER)
1034 {
1035 /* user shell folders */
1036 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1037
1038 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1039 {
1040 RegCloseKey(hKey);
1041
1042 /* shell folders */
1043 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1044
1045 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1046 {
1047
1048 /* value not existing */
1049 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1050 {
1051 GetWindowsDirectoryA(szPath, MAX_PATH);
1052 PathAddBackslashA(szPath);
1053 strcat(szPath, szDefaultPath);
1054 }
1055 else
1056 {
1057 strcpy(szPath, "C:\\"); /* FIXME ??? */
1058 strcat(szPath, szDefaultPath);
1059 }
1060 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1061 }
1062 }
1063 RegCloseKey(hKey);
1064 }
1065 else
1066 {
1067 LPCSTR pRegPath;
1068
1069 if (dwFlags & CSIDL_MYFLAG_SETUP)
1070 pRegPath = szSetup;
1071 else
1072 if (dwFlags & CSIDL_MYFLAG_CURRVER)
1073 pRegPath = szCurrentVersion;
1074 else
1075 {
1076 ERR("folder settings broken, please correct !\n");
1077 return FALSE;
1078 }
1079
1080 if (RegCreateKeyExA(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1081
1082 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1083 {
1084 /* value not existing */
1085 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1086 {
1087 GetWindowsDirectoryA(szPath, MAX_PATH);
1088 PathAddBackslashA(szPath);
1089 strcat(szPath, szDefaultPath);
1090 }
1091 else
1092 {
1093 strcpy(szPath, "C:\\"); /* FIXME ??? */
1094 strcat(szPath, szDefaultPath);
1095 }
1096 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1097 }
1098 RegCloseKey(hKey);
1099 }
1100
1101 /* expand paths like %USERPROFILE% */
1102 if (dwType == REG_EXPAND_SZ)
1103 {
1104 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
1105 strcpy(szPath, szDefaultPath);
1106 }
1107
1108 /* if we don't care about existing directories we are ready */
1109 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
1110
1111 if (PathFileExistsA(szPath)) return TRUE;
1112
1113 /* not existing but we are not allowed to create it */
1114 if (!bCreate) return FALSE;
1115
1116 /* create directory/directories */
1117 strcpy(szBuildPath, szPath);
1118 p = strchr(szBuildPath, '\\');
1119 while (p)
1120 {
1121 *p = 0;
1122 if (!PathFileExistsA(szBuildPath))
1123 {
1124 if (!CreateDirectoryA(szBuildPath,NULL))
1125 {
1126 ERR("Failed to create directory '%s'.\n", szPath);
1127 return FALSE;
1128 }
1129 }
1130 *p = '\\';
1131 p = strchr(p+1, '\\');
1132 }
1133 /* last component must be created too. */
1134 if (!PathFileExistsA(szBuildPath))
1135 {
1136 if (!CreateDirectoryA(szBuildPath,NULL))
1137 {
1138 ERR("Failed to create directory '%s'.\n", szPath);
1139 return FALSE;
1140 }
1141 }
1142
1143 MESSAGE("Created not existing system directory '%s'\n", szPath);
1144 return TRUE;
1145}
1146
1147/*************************************************************************
1148 * SHGetSpecialFolderPathW
1149 */
1150BOOL WINAPI SHGetSpecialFolderPathW (
1151 HWND hwndOwner,
1152 LPWSTR szPath,
1153 DWORD csidl,
1154 BOOL bCreate)
1155{
1156 char szTemp[MAX_PATH];
1157
1158 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
1159 {
1160 if (!MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szPath, MAX_PATH ))
1161 szPath[MAX_PATH-1] = 0;
1162 }
1163
1164 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1165
1166 return TRUE;
1167}
1168
1169/*************************************************************************
1170 * SHGetSpecialFolderPathAW
1171 */
1172BOOL WINAPI SHGetSpecialFolderPathAW (
1173 HWND hwndOwner,
1174 LPVOID szPath,
1175 DWORD csidl,
1176 BOOL bCreate)
1177
1178{
1179 if (SHELL_OsIsUnicode())
1180 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
1181 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
1182}
1183
1184/*************************************************************************
1185 * SHGetFolderPathA [SHFOLDER.@]
1186 */
1187HRESULT WINAPI SHGetFolderPathA(
1188 HWND hwndOwner,
1189 int nFolder,
1190 HANDLE hToken, /* [in] FIXME: get paths for specific user */
1191 DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1192 LPSTR pszPath)
1193{
1194 return (SHGetSpecialFolderPathA(
1195 hwndOwner,
1196 pszPath,
1197 CSIDL_FOLDER_MASK & nFolder,
1198 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
1199}
1200
1201/*************************************************************************
1202 * SHGetFolderPathW [SHFOLDER.@]
1203 */
1204HRESULT WINAPI SHGetFolderPathW(
1205 HWND hwndOwner,
1206 int nFolder,
1207 HANDLE hToken,
1208 DWORD dwFlags,
1209 LPWSTR pszPath)
1210{
1211 return (SHGetSpecialFolderPathW(
1212 hwndOwner,
1213 pszPath,
1214 CSIDL_FOLDER_MASK & nFolder,
1215 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
1216}
Note: See TracBrowser for help on using the repository browser.