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

Last change on this file since 6666 was 6650, checked in by bird, 24 years ago

Added $Id:$ keyword.

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