source: trunk/src/shell32/shellpath.c

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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