Ignore:
Timestamp:
Oct 27, 1999, 11:33:48 AM (26 years ago)
Author:
phaller
Message:

Fix: debug info

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shell32/shellpath.cpp

    r1215 r1470  
    1 /* $Id: shellpath.cpp,v 1.2 1999-10-09 11:17:05 sandervl 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 <wctype.h>
    11 #define HAVE_WCTYPE_H
    12 #include <odin.h>
     1/* $Id: shellpath.cpp,v 1.3 1999-10-27 09:33:48 phaller Exp $ */
     2 
     3/*
     4 * Win32 SHELL32 for OS/2
     5 *
     6 * Copyright 1997 Marcus Meissner
     7 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
     8 * Project Odin Software License can be found in LICENSE.TXT
     9 *
     10 * Path Functions
     11 *
     12 * Many of this functions are in SHLWAPI.DLL also
     13 *
     14 */
     15 
     16 
     17/*****************************************************************************
     18 * Includes                                                                  *
     19 *****************************************************************************/
     20 
     21#include <odin.h>
     22#include <odinwrap.h>
     23#include <os2sel.h>
     24 
     25#include <string.h>
     26#include <ctype.h>
     27#include <wctype.h>
     28#define HAVE_WCTYPE_H
     29#include <odin.h>
     30 
     31#define ICOM_CINTERFACE 1
     32#define CINTERFACE 1
     33 
     34#include "debugtools.h"
     35#include "winnls.h"
     36#include "winversion.h"
     37#include "winreg.h"
     38#include "crtdll.h"
     39 
     40#include "shlobj.h"
     41#include "shell32_main.h"
     42 
     43#include <heapstring.h>
     44#include <misc.h>
     45 
     46 
     47ODINDEBUGCHANNEL(SHELL32-SHELLPATH)
     48 
     49 
     50/*************************************************************************
     51 * PathIsRoot [SHELL32.29]
     52 */
     53ODINFUNCTION1(BOOL, PathIsRootA,
     54              LPCSTR, x)
     55{  TRACE("%s\n",x);
     56   if (*(x+1)==':' && *(x+2)=='\\')         /* "X:\" */
     57     return 1;
     58   if (*x=='\\')                         /* "\" */
     59     return 0;
     60   if (x[0]=='\\' && x[1]=='\\')            /* UNC "\\<xx>\" */
     61   { int foundbackslash = 0;
     62     x=x+2;
     63     while (*x)
     64     { if (*x++=='\\')
     65         foundbackslash++;
     66     }
     67     if (foundbackslash<=1)              /* max 1 \ more ... */
     68       return 1;
     69   }
     70   return 0;
     71}
     72ODINFUNCTION1(BOOL, PathIsRootW,
     73              LPCWSTR, x)
     74{  TRACE("%s\n",debugstr_w(x));
     75   if (*(x+1)==':' && *(x+2)=='\\')         /* "X:\" */
     76     return 1;
     77   if (*x == (WCHAR) '\\')                  /* "\" */
     78     return 0;
     79   if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\') /* UNC "\\<xx>\" */
     80   { int foundbackslash = 0;
     81     x=x+2;
     82     while (*x)
     83     { if (*x++==(WCHAR)'\\')
     84         foundbackslash++;
     85     }
     86     if (foundbackslash<=1)              /* max 1 \ more ... */
     87       return 1;
     88   }
     89   return 0;
     90}
     91ODINFUNCTION1(BOOL, PathIsRootAW,
     92              LPCVOID, x)
     93{  if (VERSION_OsIsUnicode())
     94     return PathIsRootW((LPWSTR)x);
     95   return PathIsRootA((LPSTR)x);
     96 
     97}
     98/*************************************************************************
     99 * PathBuildRoot [SHELL32.30]
     100 */
     101ODINFUNCTION2(LPSTR, PathBuildRootA,
     102              LPSTR, root,
     103              BYTE, drive)
     104{
     105  TRACE("%p %i\n",root, drive);
     106   strcpy(root,"A:\\");
     107   root[0]+=drive;
     108   return root;
     109}
     110 
     111/*************************************************************************
     112 * PathFindExtension [SHELL32.31]
     113 *
     114 * NOTES
     115 *     returns pointer to last . in last pathcomponent or at \0.
     116 */
     117ODINFUNCTION1(LPCSTR, PathFindExtensionA,
     118              LPCSTR, path)
     119{  LPCSTR   lastpoint = NULL;
     120   TRACE("%p %s\n",path,path);
     121   while (*path)
     122   { if (*path=='\\'||*path==' ')
     123       lastpoint=NULL;
     124     if (*path=='.')
     125       lastpoint=path;
     126     path++;
     127   }
     128   return lastpoint?lastpoint:path;
     129}
     130ODINFUNCTION1(LPCWSTR, PathFindExtensionW,
     131              LPCWSTR, path)
     132{  LPCWSTR   lastpoint = NULL;
     133   TRACE("%p L%s\n",path,debugstr_w(path));
     134   while (*path)
     135   { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
     136       lastpoint=NULL;
     137     if (*path==(WCHAR)'.')
     138       lastpoint=path;
     139     path++;
     140   }
     141   return lastpoint?lastpoint:path;
     142}
     143ODINFUNCTION1(LPCVOID, PathFindExtensionAW,
     144              LPCVOID, path)
     145{  if (VERSION_OsIsUnicode())
     146     return PathFindExtensionW((LPWSTR)path);
     147   return PathFindExtensionA((LPSTR)path);
     148 
     149}
     150 
     151/*************************************************************************
     152 * PathAddBackslash [SHELL32.32]
     153 *
     154 * NOTES
     155 *     append \ if there is none
     156 */
     157ODINFUNCTION1(LPSTR, PathAddBackslashA,
     158              LPSTR, path)
     159{  int len;
     160   TRACE("%p->%s\n",path,path);
     161 
     162   len = strlen(path);
     163   if (len && path[len-1]!='\\')
     164   { path[len]  = '\\';
     165     path[len+1]= 0x00;
     166     return path+len+1;
     167   }
     168   return path+len;
     169}
     170ODINFUNCTION1(LPWSTR, PathAddBackslashW,
     171              LPWSTR, path)
     172{  int len;
     173   TRACE("%p->%s\n",path,debugstr_w(path));
     174 
     175   len = lstrlenW(path);
     176   if (len && path[len-1]!=(WCHAR)'\\')
     177   { path[len]  = (WCHAR)'\\';
     178     path[len+1]= 0x00;
     179     return path+len+1;
     180   }
     181   return path+len;
     182}
     183ODINFUNCTION1(LPVOID, PathAddBackslashAW,
     184              LPVOID, path)
     185{  if(VERSION_OsIsUnicode())
     186     return PathAddBackslashW((LPWSTR)path);
     187   return PathAddBackslashA((LPSTR)path);
     188}
     189 
     190/*************************************************************************
     191 * PathRemoveBlanks [SHELL32.33]
     192 *
     193 * NOTES
     194 *     remove spaces from beginning and end of passed string
     195 */
     196ODINFUNCTION1(LPSTR, PathRemoveBlanksA,
     197              LPSTR, str)
     198{  LPSTR x = str;
     199   TRACE("%s\n",str);
     200   while (*x==' ') x++;
     201   if (x!=str)
     202     strcpy(str,x);
     203   if (!*str)
     204     return str;
     205   x=str+strlen(str)-1;
     206   while (*x==' ')
     207     x--;
     208   if (*x==' ')
     209     *x='\0';
     210   return x;
     211}
     212ODINFUNCTION1(LPWSTR, PathRemoveBlanksW,
     213              LPWSTR, str)
     214{  LPWSTR x = str;
     215   TRACE("%s\n",debugstr_w(str));
     216   while (*x==' ') x++;
     217   if (x!=str)
     218     lstrcpyW(str,x);
     219   if (!*str)
     220     return str;
     221   x=str+lstrlenW(str)-1;
     222   while (*x==' ')
     223     x--;
     224   if (*x==' ')
     225     *x='\0';
     226   return x;
     227}
     228ODINFUNCTION1(LPVOID, PathRemoveBlanksAW,
     229              LPVOID, str)
     230{  if(VERSION_OsIsUnicode())
     231     return PathRemoveBlanksW((LPWSTR)str);
     232   return PathRemoveBlanksA((LPSTR)str);
     233}
     234 
     235 
     236 
     237/*************************************************************************
     238 * PathFindFilename [SHELL32.34]
     239 *
     240 * NOTES
     241 *     basename(char *fn);
     242 */
     243ODINFUNCTION1(LPCSTR, PathFindFilenameA,
     244              LPCSTR, aptr)
     245{  LPCSTR aslash;
     246   aslash = aptr;
     247 
     248   TRACE("%s\n",aslash);
     249   while (aptr[0])
     250   { if (((aptr[0]=='\\') || (aptr[0]==':')) && aptr[1] && aptr[1]!='\\')
     251         aslash = aptr+1;
     252     aptr++;
     253   }
     254   return aslash;
     255 
     256}
     257ODINFUNCTION1(LPCWSTR, PathFindFilenameW,
     258              LPCWSTR, wptr)
     259{  LPCWSTR wslash;
     260   wslash = wptr;
     261 
     262   TRACE("L%s\n",debugstr_w(wslash));
     263   while (wptr[0])
     264   { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
     265       wslash = wptr+1;
     266     wptr++;
     267   }
     268   return wslash;
     269}
     270ODINFUNCTION1(LPCVOID, PathFindFilenameAW,
     271              LPCVOID, fn)
     272{
     273   if(VERSION_OsIsUnicode())
     274     return PathFindFilenameW((LPWSTR)fn);
     275   return PathFindFilenameA((LPSTR)fn);
     276}
     277 
     278/*************************************************************************
     279 * PathRemoveFileSpec [SHELL32.35]
     280 *
     281 * NOTES
     282 *     bool getpath(char *pathname); truncates passed argument to a valid path
     283 *     returns if the string was modified or not.
     284 *     "\foo\xx\foo"-> "\foo\xx"
     285 *     "\" -> "\"
     286 *     "a:\foo"   -> "a:\"
     287 */
     288ODINFUNCTION1(DWORD, PathRemoveFileSpecA,
     289              LPSTR, fn)
     290{
     291   LPSTR x,cutplace;
     292  TRACE("%s\n",fn);
     293   if (!fn[0])
     294      return 0;
     295   x=fn;
     296   cutplace = fn;
     297   while (*x) {
     298      if (*x=='\\') {
     299         cutplace=x++;
     300         continue;
     301      }
     302      if (*x==':') {
     303         x++;
     304         if (*x=='\\')
     305            cutplace=++x;
     306         continue; /* already x++ed */
     307      }
     308      x++;
     309   }
     310   if (!*cutplace)
     311      return 0;
     312   if (cutplace==fn) {
     313      if (fn[0]=='\\') {
     314         if (!fn[1])
     315            return 0;
     316         fn[0]='\0';
     317         return 1;
     318      }
     319   }
     320   *cutplace='\0';
     321   return 1;
     322}
     323 
     324/*************************************************************************
     325 * PathAppend [SHELL32.36]
     326 *
     327 * NOTES
     328 *     concat_paths(char*target,const char*add);
     329 *     concats "target\\add" and writes them to target
     330 */
     331ODINFUNCTION2(LPSTR, PathAppendA,
     332              LPSTR, x1,
     333              LPSTR, x2)
     334{
     335  TRACE("%s %s\n",x1,x2);
     336  while (x2[0]=='\\') x2++;
     337  return PathCombineA(x1,x1,x2);
     338}
     339 
     340/*************************************************************************
     341 * PathCombine [SHELL32.37]
     342 *
     343 * NOTES
     344 *  if lpszFile='.' skip it
     345 *  szDest can be equal to lpszFile. Thats why we use sTemp
     346 */
     347ODINFUNCTION3(LPSTR, PathCombineA,
     348              LPSTR, szDest,
     349              LPCSTR, lpszDir,
     350              LPCSTR, lpszFile)
     351{  char sTemp[MAX_PATH];
     352   TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
     353 
     354 
     355   if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
     356   { strcpy(szDest,lpszDir);
     357     return szDest;
     358   }
     359 
     360   /*  if lpszFile is a complete path don't care about lpszDir */
     361   if (PathIsRootA(lpszFile))
     362   { strcpy(szDest,lpszFile);
     363   }
     364   else
     365   { strcpy(sTemp,lpszDir);
     366     PathAddBackslashA(sTemp);
     367     strcat(sTemp,lpszFile);
     368     strcpy(szDest,sTemp);
     369   }
     370   return szDest;
     371}
     372ODINFUNCTION3(LPWSTR, PathCombineW,
     373              LPWSTR, szDest,
     374              LPCWSTR, lpszDir,
     375              LPCWSTR, lpszFile)
     376{  WCHAR sTemp[MAX_PATH];
     377   TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
     378          lpszFile, debugstr_w(lpszFile));
     379 
     380 
     381   if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
     382   { lstrcpyW(szDest,lpszDir);
     383     return szDest;
     384   }
     385 
     386   /*  if lpszFile is a complete path don't care about lpszDir */
     387   if (PathIsRootW(lpszFile))
     388   { lstrcpyW(szDest,lpszFile);
     389   }
     390   else
     391   { lstrcpyW(sTemp,lpszDir);
     392     PathAddBackslashW(sTemp);
     393     lstrcatW(sTemp,lpszFile);
     394     lstrcpyW(szDest,sTemp);
     395   }
     396   return szDest;
     397}
     398ODINFUNCTION3(LPVOID, PathCombineAW,
     399              LPVOID, szDest,
     400              LPCVOID, lpszDir,
     401              LPCVOID, lpszFile)
     402{  if (VERSION_OsIsUnicode())
     403     return PathCombineW( (LPWSTR)szDest, (LPWSTR)lpszDir, (LPWSTR)lpszFile );
     404   return PathCombineA( (LPSTR)szDest, (LPSTR)lpszDir, (LPSTR)lpszFile );
     405}
     406 
     407/*************************************************************************
     408 * PathIsUNC [SHELL32.39]
     409 *
     410 * NOTES
     411 *     PathIsUNC(char*path);
     412 */
     413ODINFUNCTION1(BOOL, PathIsUNCA,
     414              LPCSTR, path)
     415{  TRACE("%s\n",path);
     416 
     417   if ((path[0]=='\\') && (path[1]=='\\'))
     418     return TRUE;
     419   return FALSE;
     420}
     421ODINFUNCTION1(BOOL, PathIsUNCW,
     422              LPCWSTR, path)
     423{  TRACE("%s\n",debugstr_w(path));
     424 
     425   if ((path[0]=='\\') && (path[1]=='\\'))
     426     return TRUE;
     427   return FALSE;
     428}
     429ODINFUNCTION1(BOOL, PathIsUNCAW,
     430              LPCVOID, path)
     431{  if (VERSION_OsIsUnicode())
     432     return PathIsUNCW( (LPWSTR)path );
     433   return PathIsUNCA( (LPSTR)path );
     434}
     435/*************************************************************************
     436 *  PathIsRelativ [SHELL32.40]
     437 *
     438 */
     439ODINFUNCTION1(BOOL, PathIsRelativeA,
     440              LPCSTR, path)
     441{  TRACE("path=%s\n",path);
     442 
     443   if (path && (path[0]!='\\' && path[1]==':'))
     444     return TRUE;
     445   return FALSE;
     446}
     447ODINFUNCTION1(BOOL, PathIsRelativeW,
     448              LPCWSTR, path)
     449{  TRACE("path=%s\n",debugstr_w(path));
     450 
     451   if (path && (path[0]!='\\' && path[1]==':'))
     452     return TRUE;
     453   return FALSE;
     454}
     455ODINFUNCTION1(BOOL, PathIsRelativeAW,
     456              LPCVOID, path)
     457{  if (VERSION_OsIsUnicode())
     458     return PathIsRelativeW( (LPWSTR)path );
     459   return PathIsRelativeA( (LPSTR)path );
     460}
     461/*************************************************************************
     462 *  PathIsExe [SHELL32.43]
     463 *
     464 */
     465ODINFUNCTION1(BOOL, PathIsExeA,
     466              LPCSTR, path)
     467{  FIXME("path=%s\n",path);
     468   return FALSE;
     469}
     470ODINFUNCTION1(BOOL, PathIsExeW,
     471              LPCWSTR, path)
     472{  FIXME("path=%s\n",debugstr_w(path));
     473   return FALSE;
     474}
     475ODINFUNCTION1(BOOL, PathIsExeAW,
     476              LPCVOID, path)
     477{  if (VERSION_OsIsUnicode())
     478     return PathIsExeW ((LPWSTR)path);
     479   return PathIsExeA((LPSTR)path);
     480}
     481 
     482/*************************************************************************
     483 * PathFileExists [SHELL32.45]
     484 *
     485 * NOTES
     486 *     file_exists(char *fn);
     487 */
     488ODINFUNCTION1(BOOL, PathFileExistsA,
     489              LPSTR, fn)
     490{
     491  TRACE("%s\n",fn);
     492   if (GetFileAttributesA(fn)==-1)
     493      return FALSE;
     494    else
     495      return TRUE;
     496}
     497/*************************************************************************
     498 * PathMatchSingleMask
     499 *
     500 * NOTES
     501 *     internal (used by PathMatchSpec)
     502 */
     503static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
     504{
     505  while (*name && *mask && *mask!=';') {
     506    if (*mask=='*') {
     507      do {
     508   if (PathMatchSingleMaskA(name,mask+1)) return 1;  /* try substrings */
     509      } while (*name++);
     510      return 0;
     511    }
     512    if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
     513    name++;
     514    mask++;
     515  }
     516  if (!*name) {
     517    while (*mask=='*') mask++;
     518    if (!*mask || *mask==';') return 1;
     519  }
     520  return 0;
     521}
     522static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
     523{
     524  while (*name && *mask && *mask!=';') {
     525    if (*mask=='*') {
     526      do {
     527   if (PathMatchSingleMaskW(name,mask+1)) return 1;  /* try substrings */
     528      } while (*name++);
     529      return 0;
     530    }
     531    if (towupper(*mask)!=towupper(*name) && *mask!='?') return 0;
     532    name++;
     533    mask++;
     534  }
     535  if (!*name) {
     536    while (*mask=='*') mask++;
     537    if (!*mask || *mask==';') return 1;
     538  }
     539  return 0;
     540}
     541/*************************************************************************
     542 * PathMatchSpec [SHELL32.46]
     543 *
     544 * NOTES
     545 *     used from COMDLG32
     546 */
     547ODINFUNCTION2(BOOL, PathMatchSpecA,
     548              LPCSTR, name,
     549              LPCSTR, mask)
     550{
     551  TRACE("%s %s\n",name,mask);
     552 
     553  if (!lstrcmpA( mask, "*.*" )) return 1;   /* we don't require a period */
     554 
     555  while (*mask) {
     556    if (PathMatchSingleMaskA(name,mask)) return 1;    /* helper function */
     557    while (*mask && *mask!=';') mask++;
     558    if (*mask==';') {
     559      mask++;
     560      while (*mask==' ') mask++;      /*  masks may be separated by "; " */
     561     }
     562   }
     563  return 0;
     564}
     565ODINFUNCTION2(BOOL, PathMatchSpecW,
     566              LPCWSTR, name,
     567              LPCWSTR, mask)
     568{  WCHAR stemp[4];
     569  TRACE("%ls %ls\n",name,mask);
     570   lstrcpyAtoW(stemp,"*.*");
     571  if (!lstrcmpW( mask, stemp )) return 1;   /* we don't require a period */
     572 
     573  while (*mask) {
     574    if (PathMatchSingleMaskW(name,mask)) return 1;    /* helper function */
     575    while (*mask && *mask!=';') mask++;
     576    if (*mask==';') {
     577      mask++;
     578      while (*mask==' ') mask++;       /* masks may be separated by "; " */
     579     }
     580   }
     581  return 0;
     582}
     583ODINFUNCTION2(BOOL, PathMatchSpecAW,
     584              LPVOID, name,
     585              LPVOID, mask)
     586{  if (VERSION_OsIsUnicode())
     587     return PathMatchSpecW( (LPWSTR)name, (LPWSTR)mask );
     588   return PathMatchSpecA( (LPSTR)name, (LPSTR)mask );
     589}
     590/*************************************************************************
     591 * PathSetDlgItemPathAW [SHELL32.48]
     592 * NOTES
     593 *  use PathCompactPath to make sure, the path fits into the control
     594 */
     595 
     596ODINFUNCTION3(BOOL, PathSetDlgItemPathA,
     597              HWND, hDlg,
     598              int, id,
     599              LPCSTR, pszPath)
     600{  TRACE("%x %x %s\n",hDlg, id, pszPath);
     601   return SetDlgItemTextA(hDlg, id, pszPath);
     602}
     603ODINFUNCTION3(BOOL, PathSetDlgItemPathW,
     604              HWND, hDlg,
     605              int, id,
     606              LPCWSTR, pszPath)
     607{  TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
     608   return SetDlgItemTextW(hDlg, id, pszPath);
     609}
     610ODINFUNCTION3(BOOL, PathSetDlgItemPathAW,
     611              HWND, hDlg,
     612              int, id,
     613              LPCVOID, pszPath)
     614{  if (VERSION_OsIsUnicode())
     615     return PathSetDlgItemPathW(hDlg, id, (LPWSTR)pszPath);
     616   return PathSetDlgItemPathA(hDlg, id, (LPSTR)pszPath);
     617}
     618 
     619/*************************************************************************
     620 * PathQualifyAW [SHELL32.49]
     621 */
     622 
     623ODINFUNCTION1(BOOL, PathQualifyA,
     624              LPCSTR, pszPath)
     625{  FIXME("%s\n",pszPath);
     626   return 0;
     627}
     628ODINFUNCTION1(BOOL, PathQualifyW,
     629              LPCWSTR, pszPath)
     630{  FIXME("%s\n",debugstr_w(pszPath));
     631   return 0;
     632}
     633ODINFUNCTION1(BOOL, PathQualifyAW,
     634              LPCVOID, pszPath)
     635{  if (VERSION_OsIsUnicode())
     636     return PathQualifyW((LPWSTR)pszPath);
     637   return PathQualifyA((LPSTR)pszPath);
     638}
     639 
     640/*************************************************************************
     641 * PathResolve [SHELL32.51]
     642 */
     643ODINFUNCTION3(DWORD, PathResolve,
     644              LPCSTR, s,
     645              DWORD, x2,
     646              DWORD, x3)
     647{
     648   FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
     649   return 0;
     650}
     651 
     652/*************************************************************************
     653 * PathGetArgs [SHELL32.52]
     654 *
     655 * NOTES
     656 *     look for next arg in string. handle "quoted" strings
     657 *     returns pointer to argument *AFTER* the space. Or to the \0.
     658 */
     659ODINFUNCTION1(LPCSTR, PathGetArgsA,
     660              LPCSTR, cmdline)
     661{  BOOL  qflag = FALSE;
     662 
     663   TRACE("%s\n",cmdline);
     664 
     665   while (*cmdline)
     666   { if ((*cmdline==' ') && !qflag)
     667       return cmdline+1;
     668     if (*cmdline=='"')
     669       qflag=!qflag;
     670     cmdline++;
     671   }
     672   return cmdline;
     673 
     674}
     675ODINFUNCTION1(LPCWSTR, PathGetArgsW,
     676              LPCWSTR, cmdline)
     677{  BOOL  qflag = FALSE;
     678 
     679   TRACE("%sL\n",debugstr_w(cmdline));
     680 
     681   while (*cmdline)
     682   { if ((*cmdline==' ') && !qflag)
     683       return cmdline+1;
     684     if (*cmdline=='"')
     685       qflag=!qflag;
     686     cmdline++;
     687   }
     688   return cmdline;
     689}
     690ODINFUNCTION1(LPCVOID, PathGetArgsAW,
     691              LPVOID, cmdline)
     692{  if (VERSION_OsIsUnicode())
     693     return PathGetArgsW((LPWSTR)cmdline);
     694   return PathGetArgsA((LPSTR)cmdline);
     695}
     696/*************************************************************************
     697 * PathQuoteSpaces [SHELL32.55]
     698 *
     699 * NOTES
     700 *     basename(char *fn);
     701 */
     702ODINFUNCTION1(LPSTR, PathQuoteSpacesA,
     703              LPCSTR, aptr)
     704{  FIXME("%s\n",aptr);
     705   return 0;
     706 
     707}
     708ODINFUNCTION1(LPWSTR, PathQuoteSpacesW,
     709              LPCWSTR, wptr)
     710{  FIXME("L%s\n",debugstr_w(wptr));
     711   return 0;
     712}
     713ODINFUNCTION1(LPVOID, PathQuoteSpacesAW,
     714              LPCVOID, fn)
     715{  if(VERSION_OsIsUnicode())
     716     return PathQuoteSpacesW((LPWSTR)fn);
     717   return PathQuoteSpacesA((LPSTR)fn);
     718}
     719 
     720 
     721/*************************************************************************
     722 * PathUnquoteSpaces [SHELL32.56]
     723 *
     724 * NOTES
     725 *     unquote string (remove ")
     726 */
     727ODINPROCEDURE1(PathUnquoteSpacesA,
     728               LPSTR, str)
     729{  DWORD      len = lstrlenA(str);
     730   TRACE("%s\n",str);
     731   if (*str!='"')
     732     return;
     733   if (str[len-1]!='"')
     734     return;
     735   str[len-1]='\0';
     736   lstrcpyA(str,str+1);
     737   return;
     738}
     739ODINPROCEDURE1(PathUnquoteSpacesW,
     740               LPWSTR, str)
     741{  DWORD len = lstrlenW(str);
     742 
     743   TRACE("%s\n",debugstr_w(str));
     744 
     745   if (*str!='"')
     746     return;
     747   if (str[len-1]!='"')
     748     return;
     749   str[len-1]='\0';
     750   lstrcpyW(str,str+1);
     751   return;
     752}
     753ODINPROCEDURE1(PathUnquoteSpacesAW,
     754               LPVOID, str)
     755{  if(VERSION_OsIsUnicode())
     756     PathUnquoteSpacesW((LPWSTR)str);
     757   PathUnquoteSpacesA((LPSTR)str);
     758}
     759 
     760 
     761/*************************************************************************
     762 * PathGetDriveNumber32 [SHELL32.57]
     763 *
     764 */
     765ODINFUNCTION1(HRESULT, PathGetDriveNumber,
     766              LPSTR, u)
     767{  FIXME("%s stub\n",debugstr_a(u));
     768   return 0;
     769}
     770 
     771/*************************************************************************
     772 * PathYetAnotherMakeUniqueName [SHELL32.75]
     773 *
     774 * NOTES
     775 *     exported by ordinal
     776 */
     777ODINFUNCTION2(BOOL, PathYetAnotherMakeUniqueNameA,
     778              LPDWORD, x,
     779              LPDWORD, y)
     780{
     781    FIXME("(%p,%p):stub.\n",x,y);
     782    return TRUE;
     783}
     784 
     785/*************************************************************************
     786 * IsLFNDrive [SHELL32.119]
     787 *
     788 * NOTES
     789 *     exported by ordinal Name
     790 */
     791ODINFUNCTION1(BOOL, IsLFNDriveA,
     792              LPCSTR, path)
     793{
     794    DWORD   fnlen;
     795 
     796    if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
     797   return FALSE;
     798    return fnlen>12;
     799}
     800/*************************************************************************
     801 * PathFindOnPath [SHELL32.145]
     802 */
     803ODINFUNCTION2(BOOL, PathFindOnPathA,
     804              LPSTR, sFile,
     805              LPCSTR, sOtherDirs)
     806{  FIXME("%s %s\n",sFile, sOtherDirs);
     807   return FALSE;
     808}
     809ODINFUNCTION2(BOOL, PathFindOnPathW,
     810              LPWSTR, sFile,
     811              LPCWSTR, sOtherDirs)
     812{  FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
     813   return FALSE;
     814}
     815ODINFUNCTION2(BOOL, PathFindOnPathAW,
     816              LPVOID, sFile,
     817              LPCVOID, sOtherDirs)
     818{  if (VERSION_OsIsUnicode())
     819     return PathFindOnPathW((LPWSTR)sFile, (LPWSTR)sOtherDirs);
     820   return PathFindOnPathA((LPSTR)sFile, (LPSTR)sOtherDirs);
     821}
     822 
     823/*************************************************************************
     824 * PathGetExtension [SHELL32.158]
     825 *
     826 * NOTES
     827 *     exported by ordinal
     828 */
     829ODINFUNCTION3(LPCSTR, PathGetExtensionA,
     830              LPCSTR, path,
     831              DWORD, y,
     832              DWORD, z)
     833{  TRACE("(%s,%08lx,%08lx)\n",path,y,z);
     834   path = PathFindExtensionA(path);
     835   return *path?(path+1):path;
     836}
     837ODINFUNCTION3(LPCWSTR, PathGetExtensionW,
     838              LPCWSTR, path,
     839              DWORD, y,
     840              DWORD, z)
     841{  TRACE("(L%s,%08lx,%08lx)\n",debugstr_w(path),y,z);
     842   path = PathFindExtensionW(path);
     843   return *path?(path+1):path;
     844}
     845ODINFUNCTION3(LPCVOID, PathGetExtensionAW,
     846              LPCVOID, path,
     847              DWORD, y,
     848              DWORD, z)
     849{  if (VERSION_OsIsUnicode())
     850     return PathGetExtensionW((LPWSTR)path,y,z);
     851   return PathGetExtensionA((LPSTR)path,y,z);
     852}
     853 
     854/*************************************************************************
     855 * PathCleanupSpec                                [SHELL32.171]
     856 *
     857 */
     858ODINFUNCTION2(DWORD, PathCleanupSpecA,
     859              LPSTR, x,
     860              LPSTR, y)
     861{
     862   FIXME("%p(%s) %p(%s) stub\n",x,x,y,y);
     863   return TRUE;
     864}
     865 
     866ODINFUNCTION2(DWORD, PathCleanupSpecW,
     867              LPWSTR, x,
     868              LPWSTR, y)
     869{
     870   FIXME("%p(%s) %p(%s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
     871   return TRUE;
     872}
     873 
     874ODINFUNCTION2(DWORD, PathCleanupSpecAW,
     875              LPVOID, x,
     876              LPVOID, y)
     877{
     878   if (VERSION_OsIsUnicode())
     879     return PathCleanupSpecW((LPWSTR)x,(LPWSTR)y);
     880   return PathCleanupSpecA((LPSTR)x,(LPSTR)y);
     881}
     882 
     883/*************************************************************************
     884 * SheGetDirW [SHELL32.281]
     885 *
     886 */
     887ODINFUNCTION2(HRESULT, SheGetDirW,
     888              LPWSTR, u,
     889              LPWSTR, v)
     890{  FIXME("%p %p stub\n",u,v);
     891   return 0;
     892}
     893 
     894/*************************************************************************
     895 * SheChangeDirW [SHELL32.274]
     896 *
     897 */
     898ODINFUNCTION1(HRESULT, SheChangeDirW,
     899              LPWSTR, u)
     900{  FIXME("(%s),stub\n",debugstr_w(u));
     901   return 0;
     902}
     903 
     904/*************************************************************************
     905*  PathProcessCommand                    [SHELL32.653]
     906*/
     907ODINFUNCTION4(HRESULT, PathProcessCommandA,
     908              LPSTR, lpCommand,
     909              LPSTR, v,
     910              DWORD, w,
     911              DWORD, x)
     912{
     913   FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
     914   lpCommand, lpCommand, v, w,x );
     915   return 0;
     916}
     917 
     918ODINFUNCTION4(HRESULT, PathProcessCommandW,
     919              LPWSTR, lpCommand,
     920              LPSTR, v,
     921              DWORD, w,
     922              DWORD, x)
     923{
     924   FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
     925   lpCommand, debugstr_w(lpCommand), v, w,x );
     926   return 0;
     927}
     928 
     929ODINFUNCTION4(HRESULT, PathProcessCommandAW,
     930              LPVOID, lpCommand,
     931              LPSTR, v,
     932              DWORD, w,
     933              DWORD, x)
     934{
     935   if (VERSION_OsIsUnicode())
     936     return PathProcessCommandW((LPWSTR)lpCommand, v, w, x);
     937   return PathProcessCommandA((LPSTR)lpCommand, v, w, x);
     938}
     939 
     940/*************************************************************************
     941 * SHGetSpecialFolderPath [SHELL32.175]
     942 *
     943 * converts csidl to path
     944 *
     945 */
     946 
     947static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
     948 
     949ODINFUNCTION4(BOOL, SHGetSpecialFolderPathA,
     950              HWND, hwndOwner,
     951              LPSTR, szPath,
     952              DWORD, csidl,
     953              BOOL, bCreate)
     954{
     955   CHAR  szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
     956   HKEY  hRootKey, hKey;
     957   BOOL  bRelative = TRUE;
     958   DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
     959 
     960   TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
     961 
     962   /* build default values */
     963   switch(csidl)
     964   {
     965     case CSIDL_APPDATA:
     966       hRootKey = HKEY_CURRENT_USER;
     967       strcpy (szValueName, "AppData");
     968       strcpy (szDefaultPath, "AppData");
     969       break;
     970 
     971     case CSIDL_COOKIES:
     972       hRootKey = HKEY_CURRENT_USER;
     973       strcpy (szValueName, "Cookies");
     974       strcpy(szDefaultPath, "Cookies");
     975       break;
     976 
     977     case CSIDL_DESKTOPDIRECTORY:
     978       hRootKey = HKEY_CURRENT_USER;
     979       strcpy(szValueName, "Desktop");
     980       strcpy(szDefaultPath, "Desktop");
     981       break;
     982 
     983     case CSIDL_COMMON_DESKTOPDIRECTORY:
     984       hRootKey = HKEY_LOCAL_MACHINE;
     985       strcpy(szValueName, "Common Desktop");
     986       strcpy(szDefaultPath, "Desktop");
     987       break;
     988 
     989     case CSIDL_FAVORITES:
     990       hRootKey = HKEY_CURRENT_USER;
     991       strcpy(szValueName, "Favorites");
     992       strcpy(szDefaultPath, "Favorites");
     993       break;
     994 
     995     case CSIDL_FONTS:
     996       hRootKey = HKEY_CURRENT_USER;
     997       strcpy(szValueName, "Fonts");
     998       strcpy(szDefaultPath, "Fonts");
     999       break;
     1000 
     1001     case CSIDL_HISTORY:
     1002       hRootKey = HKEY_CURRENT_USER;
     1003       strcpy(szValueName, "History");
     1004       strcpy(szDefaultPath, "History");
     1005       break;
     1006 
     1007     case CSIDL_NETHOOD:
     1008       hRootKey = HKEY_CURRENT_USER;
     1009       strcpy(szValueName, "NetHood");
     1010       strcpy(szDefaultPath, "NetHood");
     1011       break;
     1012 
     1013     case CSIDL_INTERNET_CACHE:
     1014       hRootKey = HKEY_CURRENT_USER;
     1015       strcpy(szValueName, "Cache");
     1016       strcpy(szDefaultPath, "Temporary Internet Files");
     1017       break;
     1018 
     1019     case CSIDL_PERSONAL:
     1020       hRootKey = HKEY_CURRENT_USER;
     1021       strcpy(szValueName, "Personal");
     1022       strcpy(szDefaultPath, "My Own Files");
     1023       bRelative = FALSE;
     1024       break;
     1025 
     1026     case CSIDL_PRINTHOOD:
     1027       hRootKey = HKEY_CURRENT_USER;
     1028       strcpy(szValueName, "PrintHood");
     1029       strcpy(szDefaultPath, "PrintHood");
     1030       break;
     1031 
     1032     case CSIDL_PROGRAMS:
     1033       hRootKey = HKEY_CURRENT_USER;
     1034       strcpy(szValueName, "Programs");
     1035       strcpy(szDefaultPath, "StatrMenu\\Programs");
     1036       break;
     1037 
     1038     case CSIDL_COMMON_PROGRAMS:
     1039       hRootKey = HKEY_LOCAL_MACHINE;
     1040       strcpy(szValueName, "Common Programs");
     1041       strcpy(szDefaultPath, "");
     1042       break;
     1043 
     1044     case CSIDL_RECENT:
     1045       hRootKey = HKEY_CURRENT_USER;
     1046       strcpy(szValueName, "Recent");
     1047       strcpy(szDefaultPath, "Recent");
     1048       break;
     1049 
     1050     case CSIDL_SENDTO:
     1051       hRootKey = HKEY_CURRENT_USER;
     1052       strcpy(szValueName, "SendTo");
     1053       strcpy(szDefaultPath, "SendTo");
     1054       break;
     1055 
     1056     case CSIDL_STARTMENU:
     1057       hRootKey = HKEY_CURRENT_USER;
     1058       strcpy(szValueName, "StartMenu");
     1059       strcpy(szDefaultPath, "StartMenu");
     1060       break;
     1061 
     1062     case CSIDL_COMMON_STARTMENU:
     1063       hRootKey = HKEY_LOCAL_MACHINE;
     1064       strcpy(szValueName, "Common StartMenu");
     1065       strcpy(szDefaultPath, "StartMenu");
     1066       break;
     1067 
     1068     case CSIDL_STARTUP:
     1069       hRootKey = HKEY_CURRENT_USER;
     1070       strcpy(szValueName, "Startup");
     1071       strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
     1072       break;
     1073 
     1074     case CSIDL_COMMON_STARTUP:
     1075       hRootKey = HKEY_LOCAL_MACHINE;
     1076       strcpy(szValueName, "Common Startup");
     1077       strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
     1078       break;
     1079 
     1080     case CSIDL_TEMPLATES:
     1081       hRootKey = HKEY_CURRENT_USER;
     1082       strcpy(szValueName, "Templates");
     1083       strcpy(szDefaultPath, "ShellNew");
     1084       break;
     1085 
     1086     default:
     1087       ERR("folder unknown or not allowed\n");
     1088       return FALSE;
     1089   }
     1090 
     1091   if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisp))
     1092   {
     1093     return FALSE;
     1094   }
     1095 
     1096   if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
     1097   {
     1098     /* value not existing */
     1099     if (bRelative)
     1100     {
     1101       GetWindowsDirectoryA(szPath, MAX_PATH);
     1102       PathAddBackslashA(szPath);
     1103       strcat(szPath, szDefaultPath);
     1104     }
     1105     else
     1106     {
     1107       strcpy(szPath, szDefaultPath);
     1108     }
     1109     if (bCreate)
     1110     {
     1111       CreateDirectoryA(szPath,NULL);
     1112     }
     1113     RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
     1114   }
     1115   RegCloseKey(hKey);
     1116 
     1117   return TRUE;
     1118}
     1119ODINFUNCTION4(BOOL, SHGetSpecialFolderPathW,
     1120              HWND, hwndOwner,
     1121              LPWSTR, szPath,
     1122              DWORD, csidl,
     1123              BOOL, bCreate)
     1124{
     1125   char szTemp[MAX_PATH];
     1126 
     1127   if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
     1128   {
     1129     lstrcpynAtoW(szPath, szTemp, MAX_PATH);
     1130   }
     1131 
     1132   TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
     1133 
     1134   return TRUE;
     1135}
     1136ODINFUNCTION4(BOOL, SHGetSpecialFolderPathAW,
     1137              HWND, hwndOwner,
     1138              LPVOID, szPath,
     1139              DWORD, csidl,
     1140              BOOL, bCreate)
     1141{
     1142   if (VERSION_OsIsUnicode())
     1143     return SHGetSpecialFolderPathW (hwndOwner, (LPWSTR)szPath, csidl, bCreate);
     1144   return SHGetSpecialFolderPathA (hwndOwner, (LPSTR)szPath, csidl, bCreate);
     1145}
    131146
    14 #define ICOM_CINTERFACE 1
    15 #define CINTERFACE 1
    16 
    17 #include "debugtools.h"
    18 #include "winnls.h"
    19 #include "winversion.h"
    20 #include "winreg.h"
    21 #include "crtdll.h"
    22 
    23 #include "shlobj.h"
    24 #include "shell32_main.h"
    25 
    26 #include <heapstring.h>
    27 #include <misc.h>
    28 
    29 DEFAULT_DEBUG_CHANNEL(shell)
    30 
    31 /*************************************************************************
    32  * PathIsRoot [SHELL32.29]
    33  */
    34 BOOL WINAPI PathIsRootA(LPCSTR x)
    35 {       TRACE("%s\n",x);
    36         if (*(x+1)==':' && *(x+2)=='\\')                /* "X:\" */
    37           return 1;
    38         if (*x=='\\')           /* "\" */
    39           return 0;
    40         if (x[0]=='\\' && x[1]=='\\')           /* UNC "\\<xx>\" */
    41         { int   foundbackslash = 0;
    42           x=x+2;
    43           while (*x)
    44           { if (*x++=='\\')
    45               foundbackslash++;
    46           }
    47           if (foundbackslash<=1)        /* max 1 \ more ... */
    48             return 1;
    49         }
    50         return 0;
    51 }
    52 BOOL WINAPI PathIsRootW(LPCWSTR x)
    53 {       TRACE("%s\n",debugstr_w(x));
    54         if (*(x+1)==':' && *(x+2)=='\\')                /* "X:\" */
    55           return 1;
    56         if (*x == (WCHAR) '\\')         /* "\" */
    57           return 0;
    58         if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\')     /* UNC "\\<xx>\" */
    59         { int   foundbackslash = 0;
    60           x=x+2;
    61           while (*x)
    62           { if (*x++==(WCHAR)'\\')
    63               foundbackslash++;
    64           }
    65           if (foundbackslash<=1)        /* max 1 \ more ... */
    66             return 1;
    67         }
    68         return 0;
    69 }
    70 BOOL WINAPI PathIsRootAW(LPCVOID x)
    71 {       if (VERSION_OsIsUnicode())
    72           return PathIsRootW((LPWSTR)x);
    73         return PathIsRootA((LPSTR)x);
    74 
    75 }
    76 /*************************************************************************
    77  * PathBuildRoot [SHELL32.30]
    78  */
    79 LPSTR WINAPI PathBuildRootA(LPSTR root,BYTE drive) {
    80   TRACE("%p %i\n",root, drive);
    81         strcpy(root,"A:\\");
    82         root[0]+=drive;
    83         return root;
    84 }
    85 
    86 /*************************************************************************
    87  * PathFindExtension [SHELL32.31]
    88  *
    89  * NOTES
    90  *     returns pointer to last . in last pathcomponent or at \0.
    91  */
    92 LPCSTR WINAPI PathFindExtensionA(LPCSTR path)
    93 {       LPCSTR   lastpoint = NULL;
    94         TRACE("%p %s\n",path,path);
    95         while (*path)
    96         { if (*path=='\\'||*path==' ')
    97             lastpoint=NULL;
    98           if (*path=='.')
    99             lastpoint=path;
    100           path++;
    101         }
    102         return lastpoint?lastpoint:path;
    103 }
    104 LPCWSTR WINAPI PathFindExtensionW(LPCWSTR path)
    105 {       LPCWSTR   lastpoint = NULL;
    106         TRACE("%p L%s\n",path,debugstr_w(path));
    107         while (*path)
    108         { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
    109             lastpoint=NULL;
    110           if (*path==(WCHAR)'.')
    111             lastpoint=path;
    112           path++;
    113         }
    114         return lastpoint?lastpoint:path;
    115 }
    116 LPCVOID WINAPI PathFindExtensionAW(LPCVOID path)
    117 {       if (VERSION_OsIsUnicode())
    118           return PathFindExtensionW((LPWSTR)path);
    119         return PathFindExtensionA((LPSTR)path);
    120 
    121 }
    122 
    123 /*************************************************************************
    124  * PathAddBackslash [SHELL32.32]
    125  *
    126  * NOTES
    127  *     append \ if there is none
    128  */
    129 LPSTR WINAPI PathAddBackslashA(LPSTR path)
    130 {       int len;
    131         TRACE("%p->%s\n",path,path);
    132 
    133         len = strlen(path);
    134         if (len && path[len-1]!='\\')
    135         { path[len]  = '\\';
    136           path[len+1]= 0x00;
    137           return path+len+1;
    138         }
    139         return path+len;
    140 }
    141 LPWSTR WINAPI PathAddBackslashW(LPWSTR path)
    142 {       int len;
    143         TRACE("%p->%s\n",path,debugstr_w(path));
    144 
    145         len = lstrlenW(path);
    146         if (len && path[len-1]!=(WCHAR)'\\')
    147         { path[len]  = (WCHAR)'\\';
    148           path[len+1]= 0x00;
    149           return path+len+1;
    150         }
    151         return path+len;
    152 }
    153 LPVOID WINAPI PathAddBackslashAW(LPVOID path)
    154 {       if(VERSION_OsIsUnicode())
    155           return PathAddBackslashW((LPWSTR)path);
    156         return PathAddBackslashA((LPSTR)path);
    157 }
    158 
    159 /*************************************************************************
    160  * PathRemoveBlanks [SHELL32.33]
    161  *
    162  * NOTES
    163  *     remove spaces from beginning and end of passed string
    164  */
    165 LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
    166 {       LPSTR x = str;
    167         TRACE("%s\n",str);
    168         while (*x==' ') x++;
    169         if (x!=str)
    170           strcpy(str,x);
    171         if (!*str)
    172           return str;
    173         x=str+strlen(str)-1;
    174         while (*x==' ')
    175           x--;
    176         if (*x==' ')
    177           *x='\0';
    178         return x;
    179 }
    180 LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
    181 {       LPWSTR x = str;
    182         TRACE("%s\n",debugstr_w(str));
    183         while (*x==' ') x++;
    184         if (x!=str)
    185           lstrcpyW(str,x);
    186         if (!*str)
    187           return str;
    188         x=str+lstrlenW(str)-1;
    189         while (*x==' ')
    190           x--;
    191         if (*x==' ')
    192           *x='\0';
    193         return x;
    194 }
    195 LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
    196 {       if(VERSION_OsIsUnicode())
    197           return PathRemoveBlanksW((LPWSTR)str);
    198         return PathRemoveBlanksA((LPSTR)str);
    199 }
    200 
    201 
    202 
    203 /*************************************************************************
    204  * PathFindFilename [SHELL32.34]
    205  *
    206  * NOTES
    207  *     basename(char *fn);
    208  */
    209 LPCSTR WINAPI PathFindFilenameA(LPCSTR aptr)
    210 {       LPCSTR aslash;
    211         aslash = aptr;
    212 
    213         TRACE("%s\n",aslash);
    214         while (aptr[0])
    215         { if (((aptr[0]=='\\') || (aptr[0]==':')) && aptr[1] && aptr[1]!='\\')
    216               aslash = aptr+1;
    217           aptr++;
    218         }
    219         return aslash;
    220 
    221 }
    222 LPCWSTR WINAPI PathFindFilenameW(LPCWSTR wptr)
    223 {       LPCWSTR wslash;
    224         wslash = wptr;
    225 
    226         TRACE("L%s\n",debugstr_w(wslash));
    227         while (wptr[0])
    228         { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
    229             wslash = wptr+1;
    230           wptr++;
    231         }
    232         return wslash; 
    233 }
    234 LPCVOID WINAPI PathFindFilenameAW(LPCVOID fn)
    235 {
    236         if(VERSION_OsIsUnicode())
    237           return PathFindFilenameW((LPWSTR)fn);
    238         return PathFindFilenameA((LPSTR)fn);
    239 }
    240 
    241 /*************************************************************************
    242  * PathRemoveFileSpec [SHELL32.35]
    243  *
    244  * NOTES
    245  *     bool getpath(char *pathname); truncates passed argument to a valid path
    246  *     returns if the string was modified or not.
    247  *     "\foo\xx\foo"-> "\foo\xx"
    248  *     "\" -> "\"
    249  *     "a:\foo" -> "a:\"
    250  */
    251 DWORD WINAPI PathRemoveFileSpecA(LPSTR fn) {
    252         LPSTR   x,cutplace;
    253   TRACE("%s\n",fn);
    254         if (!fn[0])
    255                 return 0;
    256         x=fn;
    257         cutplace = fn;
    258         while (*x) {
    259                 if (*x=='\\') {
    260                         cutplace=x++;
    261                         continue;
    262                 }
    263                 if (*x==':') {
    264                         x++;
    265                         if (*x=='\\')
    266                                 cutplace=++x;
    267                         continue; /* already x++ed */
    268                 }
    269                 x++;
    270         }
    271         if (!*cutplace)
    272                 return 0;
    273         if (cutplace==fn) {
    274                 if (fn[0]=='\\') {
    275                         if (!fn[1])
    276                                 return 0;
    277                         fn[0]='\0';
    278                         return 1;
    279                 }
    280         }
    281         *cutplace='\0';
    282         return 1;
    283 }
    284 
    285 /*************************************************************************
    286  * PathAppend [SHELL32.36]
    287  *
    288  * NOTES
    289  *     concat_paths(char*target,const char*add);
    290  *     concats "target\\add" and writes them to target
    291  */
    292 LPSTR WINAPI PathAppendA(LPSTR x1,LPSTR x2) {
    293   TRACE("%s %s\n",x1,x2);
    294   while (x2[0]=='\\') x2++;
    295   return PathCombineA(x1,x1,x2);
    296 }
    297 
    298 /*************************************************************************
    299  * PathCombine [SHELL32.37]
    300  *
    301  * NOTES
    302  *  if lpszFile='.' skip it
    303  *  szDest can be equal to lpszFile. Thats why we use sTemp
    304  */
    305 LPSTR WINAPI PathCombineA(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile)
    306 {       char sTemp[MAX_PATH];
    307         TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
    308        
    309        
    310         if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
    311         { strcpy(szDest,lpszDir);
    312           return szDest;
    313         }
    314 
    315         /*  if lpszFile is a complete path don't care about lpszDir */
    316         if (PathIsRootA(lpszFile))
    317         { strcpy(szDest,lpszFile);
    318         }
    319         else
    320         { strcpy(sTemp,lpszDir);
    321           PathAddBackslashA(sTemp);
    322           strcat(sTemp,lpszFile);
    323           strcpy(szDest,sTemp);
    324         }
    325         return szDest;
    326 }
    327 LPWSTR WINAPI PathCombineW(LPWSTR szDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
    328 {       WCHAR sTemp[MAX_PATH];
    329         TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
    330                          lpszFile, debugstr_w(lpszFile));
    331        
    332        
    333         if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
    334         { lstrcpyW(szDest,lpszDir);
    335           return szDest;
    336         }
    337 
    338         /*  if lpszFile is a complete path don't care about lpszDir */
    339         if (PathIsRootW(lpszFile))
    340         { lstrcpyW(szDest,lpszFile);
    341         }
    342         else
    343         { lstrcpyW(sTemp,lpszDir);
    344           PathAddBackslashW(sTemp);
    345           lstrcatW(sTemp,lpszFile);
    346           lstrcpyW(szDest,sTemp);
    347         }
    348         return szDest;
    349 }
    350 LPVOID WINAPI PathCombineAW(LPVOID szDest, LPCVOID lpszDir, LPCVOID lpszFile)
    351 {       if (VERSION_OsIsUnicode())
    352           return PathCombineW( (LPWSTR)szDest, (LPWSTR)lpszDir, (LPWSTR)lpszFile );
    353         return PathCombineA( (LPSTR)szDest, (LPSTR)lpszDir, (LPSTR)lpszFile );
    354 }
    355 
    356 /*************************************************************************
    357  * PathIsUNC [SHELL32.39]
    358  *
    359  * NOTES
    360  *     PathIsUNC(char*path);
    361  */
    362 BOOL WINAPI PathIsUNCA(LPCSTR path)
    363 {       TRACE("%s\n",path);
    364 
    365         if ((path[0]=='\\') && (path[1]=='\\'))
    366           return TRUE;
    367         return FALSE;
    368 }
    369 BOOL WINAPI PathIsUNCW(LPCWSTR path)
    370 {       TRACE("%s\n",debugstr_w(path));
    371 
    372         if ((path[0]=='\\') && (path[1]=='\\'))
    373           return TRUE;
    374         return FALSE;
    375 }
    376 BOOL WINAPI PathIsUNCAW (LPCVOID path)
    377 {       if (VERSION_OsIsUnicode())
    378           return PathIsUNCW( (LPWSTR)path );
    379         return PathIsUNCA( (LPSTR)path );
    380 }
    381 /*************************************************************************
    382  *  PathIsRelativ [SHELL32.40]
    383  *
    384  */
    385 BOOL WINAPI PathIsRelativeA (LPCSTR path)
    386 {       TRACE("path=%s\n",path);
    387 
    388         if (path && (path[0]!='\\' && path[1]==':'))
    389           return TRUE;
    390         return FALSE;
    391 }
    392 BOOL WINAPI PathIsRelativeW (LPCWSTR path)
    393 {       TRACE("path=%s\n",debugstr_w(path));
    394 
    395         if (path && (path[0]!='\\' && path[1]==':'))
    396           return TRUE;
    397         return FALSE;
    398 }
    399 BOOL WINAPI PathIsRelativeAW (LPCVOID path)
    400 {       if (VERSION_OsIsUnicode())
    401           return PathIsRelativeW( (LPWSTR)path );
    402         return PathIsRelativeA( (LPSTR)path );
    403 }
    404 /*************************************************************************
    405  *  PathIsExe [SHELL32.43]
    406  *
    407  */
    408 BOOL WINAPI PathIsExeA (LPCSTR path)
    409 {       FIXME("path=%s\n",path);
    410         return FALSE;
    411 }
    412 BOOL WINAPI PathIsExeW (LPCWSTR path)
    413 {       FIXME("path=%s\n",debugstr_w(path));
    414         return FALSE;
    415 }
    416 BOOL WINAPI PathIsExeAW (LPCVOID path)
    417 {       if (VERSION_OsIsUnicode())
    418           return PathIsExeW ((LPWSTR)path);
    419         return PathIsExeA((LPSTR)path);
    420 }
    421 
    422 /*************************************************************************
    423  * PathFileExists [SHELL32.45]
    424  *
    425  * NOTES
    426  *     file_exists(char *fn);
    427  */
    428 BOOL WINAPI PathFileExistsA(LPSTR fn) {
    429   TRACE("%s\n",fn);
    430    if (GetFileAttributesA(fn)==-1)
    431         return FALSE;
    432     else
    433         return TRUE;
    434 }
    435 /*************************************************************************
    436  * PathMatchSingleMask
    437  *
    438  * NOTES
    439  *     internal (used by PathMatchSpec)
    440  */
    441 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
    442 {
    443   while (*name && *mask && *mask!=';') {
    444     if (*mask=='*') {
    445       do {
    446         if (PathMatchSingleMaskA(name,mask+1)) return 1;  /* try substrings */
    447       } while (*name++);
    448       return 0;
    449     }
    450     if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
    451     name++;
    452     mask++;
    453   }
    454   if (!*name) {
    455     while (*mask=='*') mask++;
    456     if (!*mask || *mask==';') return 1;
    457   }
    458   return 0;
    459 }
    460 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
    461 {
    462   while (*name && *mask && *mask!=';') {
    463     if (*mask=='*') {
    464       do {
    465         if (PathMatchSingleMaskW(name,mask+1)) return 1;  /* try substrings */
    466       } while (*name++);
    467       return 0;
    468     }
    469     if (towupper(*mask)!=towupper(*name) && *mask!='?') return 0;
    470     name++;
    471     mask++;
    472   }
    473   if (!*name) {
    474     while (*mask=='*') mask++;
    475     if (!*mask || *mask==';') return 1;
    476   }
    477   return 0;
    478 }
    479 /*************************************************************************
    480  * PathMatchSpec [SHELL32.46]
    481  *
    482  * NOTES
    483  *     used from COMDLG32
    484  */
    485 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
    486 {
    487   TRACE("%s %s\n",name,mask);
    488 
    489   if (!lstrcmpA( mask, "*.*" )) return 1;   /* we don't require a period */
    490 
    491   while (*mask) {
    492     if (PathMatchSingleMaskA(name,mask)) return 1;    /* helper function */
    493     while (*mask && *mask!=';') mask++;
    494     if (*mask==';') {
    495       mask++;
    496       while (*mask==' ') mask++;      /*  masks may be separated by "; " */
    497           }
    498         }
    499   return 0;
    500 }
    501 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
    502 {       WCHAR stemp[4];
    503   TRACE("%ls %ls\n",name,mask);
    504         lstrcpyAtoW(stemp,"*.*");       
    505   if (!lstrcmpW( mask, stemp )) return 1;   /* we don't require a period */
    506 
    507   while (*mask) {
    508     if (PathMatchSingleMaskW(name,mask)) return 1;    /* helper function */
    509     while (*mask && *mask!=';') mask++;
    510     if (*mask==';') {
    511       mask++;
    512       while (*mask==' ') mask++;       /* masks may be separated by "; " */
    513           }
    514         }
    515   return 0;
    516 }
    517 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
    518 {       if (VERSION_OsIsUnicode())
    519           return PathMatchSpecW( (LPWSTR)name, (LPWSTR)mask );
    520         return PathMatchSpecA( (LPSTR)name, (LPSTR)mask );
    521 }
    522 /*************************************************************************
    523  * PathSetDlgItemPathAW [SHELL32.48]
    524  * NOTES
    525  *  use PathCompactPath to make sure, the path fits into the control
    526  */
    527 
    528 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
    529 {       TRACE("%x %x %s\n",hDlg, id, pszPath);
    530         return SetDlgItemTextA(hDlg, id, pszPath);
    531 }
    532 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
    533 {       TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
    534         return SetDlgItemTextW(hDlg, id, pszPath);
    535 }
    536 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
    537 {       if (VERSION_OsIsUnicode())
    538           return PathSetDlgItemPathW(hDlg, id, (LPWSTR)pszPath);
    539         return PathSetDlgItemPathA(hDlg, id, (LPSTR)pszPath);
    540 }
    541 
    542 /*************************************************************************
    543  * PathQualifyAW [SHELL32.49]
    544  */
    545 
    546 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
    547 {       FIXME("%s\n",pszPath);
    548         return 0;
    549 }
    550 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
    551 {       FIXME("%s\n",debugstr_w(pszPath));
    552         return 0;
    553 }
    554 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
    555 {       if (VERSION_OsIsUnicode())
    556           return PathQualifyW((LPWSTR)pszPath);
    557         return PathQualifyA((LPSTR)pszPath);
    558 }
    559 
    560 /*************************************************************************
    561  * PathResolve [SHELL32.51]
    562  */
    563 DWORD WINAPI PathResolve(LPCSTR s,DWORD x2,DWORD x3) {
    564         FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
    565         return 0;
    566 }
    567 
    568 /*************************************************************************
    569  * PathGetArgs [SHELL32.52]
    570  *
    571  * NOTES
    572  *     look for next arg in string. handle "quoted" strings
    573  *     returns pointer to argument *AFTER* the space. Or to the \0.
    574  */
    575 LPCSTR WINAPI PathGetArgsA(LPCSTR cmdline)
    576 {       BOOL    qflag = FALSE;
    577 
    578         TRACE("%s\n",cmdline);
    579 
    580         while (*cmdline)
    581         { if ((*cmdline==' ') && !qflag)
    582             return cmdline+1;
    583           if (*cmdline=='"')
    584             qflag=!qflag;
    585           cmdline++;
    586         }
    587         return cmdline;
    588 
    589 }
    590 LPCWSTR WINAPI PathGetArgsW(LPCWSTR cmdline)
    591 {       BOOL    qflag = FALSE;
    592 
    593         TRACE("%sL\n",debugstr_w(cmdline));
    594 
    595         while (*cmdline)
    596         { if ((*cmdline==' ') && !qflag)
    597             return cmdline+1;
    598           if (*cmdline=='"')
    599             qflag=!qflag;
    600           cmdline++;
    601         }
    602         return cmdline;
    603 }
    604 LPCVOID WINAPI PathGetArgsAW(LPVOID cmdline)
    605 {       if (VERSION_OsIsUnicode())
    606           return PathGetArgsW((LPWSTR)cmdline);
    607         return PathGetArgsA((LPSTR)cmdline);
    608 }
    609 /*************************************************************************
    610  * PathQuoteSpaces [SHELL32.55]
    611  *
    612  * NOTES
    613  *     basename(char *fn);
    614  */
    615 LPSTR WINAPI PathQuoteSpacesA(LPCSTR aptr)
    616 {       FIXME("%s\n",aptr);
    617         return 0;
    618 
    619 }
    620 LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR wptr)
    621 {       FIXME("L%s\n",debugstr_w(wptr));
    622         return 0;       
    623 }
    624 LPVOID WINAPI PathQuoteSpacesAW (LPCVOID fn)
    625 {       if(VERSION_OsIsUnicode())
    626           return PathQuoteSpacesW((LPWSTR)fn);
    627         return PathQuoteSpacesA((LPSTR)fn);
    628 }
    629 
    630 
    631 /*************************************************************************
    632  * PathUnquoteSpaces [SHELL32.56]
    633  *
    634  * NOTES
    635  *     unquote string (remove ")
    636  */
    637 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
    638 {       DWORD      len = lstrlenA(str);
    639         TRACE("%s\n",str);
    640         if (*str!='"')
    641           return;
    642         if (str[len-1]!='"')
    643           return;
    644         str[len-1]='\0';
    645         lstrcpyA(str,str+1);
    646         return;
    647 }
    648 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
    649 {       DWORD len = lstrlenW(str);
    650 
    651         TRACE("%s\n",debugstr_w(str));
    652 
    653         if (*str!='"')
    654           return;
    655         if (str[len-1]!='"')
    656           return;
    657         str[len-1]='\0';
    658         lstrcpyW(str,str+1);
    659         return;
    660 }
    661 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
    662 {       if(VERSION_OsIsUnicode())
    663           PathUnquoteSpacesW((LPWSTR)str);
    664         PathUnquoteSpacesA((LPSTR)str);
    665 }
    666 
    667 
    668 /*************************************************************************
    669  * PathGetDriveNumber32 [SHELL32.57]
    670  *
    671  */
    672 HRESULT WINAPI PathGetDriveNumber(LPSTR u)
    673 {       FIXME("%s stub\n",debugstr_a(u));
    674         return 0;
    675 }
    676 
    677 /*************************************************************************
    678  * PathYetAnotherMakeUniqueName [SHELL32.75]
    679  *
    680  * NOTES
    681  *     exported by ordinal
    682  */
    683 BOOL WINAPI PathYetAnotherMakeUniqueNameA(LPDWORD x,LPDWORD y) {
    684     FIXME("(%p,%p):stub.\n",x,y);
    685     return TRUE;
    686 }
    687 
    688 /*************************************************************************
    689  * IsLFNDrive [SHELL32.119]
    690  *
    691  * NOTES
    692  *     exported by ordinal Name
    693  */
    694 BOOL WINAPI IsLFNDriveA(LPCSTR path) {
    695     DWORD       fnlen;
    696 
    697     if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
    698         return FALSE;
    699     return fnlen>12;
    700 }
    701 /*************************************************************************
    702  * PathFindOnPath [SHELL32.145]
    703  */
    704 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
    705 {       FIXME("%s %s\n",sFile, sOtherDirs);
    706         return FALSE;
    707 }
    708 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
    709 {       FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
    710         return FALSE;
    711 }
    712 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
    713 {       if (VERSION_OsIsUnicode())
    714           return PathFindOnPathW((LPWSTR)sFile, (LPWSTR)sOtherDirs);
    715         return PathFindOnPathA((LPSTR)sFile, (LPSTR)sOtherDirs);
    716 }
    717 
    718 /*************************************************************************
    719  * PathGetExtension [SHELL32.158]
    720  *
    721  * NOTES
    722  *     exported by ordinal
    723  */
    724 LPCSTR WINAPI PathGetExtensionA(LPCSTR path,DWORD y,DWORD z)
    725 {       TRACE("(%s,%08lx,%08lx)\n",path,y,z);
    726         path = PathFindExtensionA(path);
    727         return *path?(path+1):path;
    728 }
    729 LPCWSTR WINAPI PathGetExtensionW(LPCWSTR path,DWORD y,DWORD z)
    730 {       TRACE("(L%s,%08lx,%08lx)\n",debugstr_w(path),y,z);
    731         path = PathFindExtensionW(path);
    732         return *path?(path+1):path;
    733 }
    734 LPCVOID WINAPI PathGetExtensionAW(LPCVOID path,DWORD y,DWORD z)
    735 {       if (VERSION_OsIsUnicode())
    736           return PathGetExtensionW((LPWSTR)path,y,z);
    737         return PathGetExtensionA((LPSTR)path,y,z);
    738 }
    739 
    740 /*************************************************************************
    741  * PathCleanupSpec                              [SHELL32.171]
    742  *
    743  */
    744 DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
    745 {
    746         FIXME("%p(%s) %p(%s) stub\n",x,x,y,y);
    747         return TRUE;
    748 }
    749 
    750 DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
    751 {
    752         FIXME("%p(%s) %p(%s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
    753         return TRUE;
    754 }
    755 
    756 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
    757 {
    758         if (VERSION_OsIsUnicode())
    759           return PathCleanupSpecW((LPWSTR)x,(LPWSTR)y);
    760         return PathCleanupSpecA((LPSTR)x,(LPSTR)y);
    761 }
    762 
    763 /*************************************************************************
    764  * SheGetDirW [SHELL32.281]
    765  *
    766  */
    767 HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
    768 {       FIXME("%p %p stub\n",u,v);
    769         return 0;
    770 }
    771 
    772 /*************************************************************************
    773  * SheChangeDirW [SHELL32.274]
    774  *
    775  */
    776 HRESULT WINAPI SheChangeDirW(LPWSTR u)
    777 {       FIXME("(%s),stub\n",debugstr_w(u));
    778         return 0;
    779 }
    780 
    781 /*************************************************************************
    782 *       PathProcessCommand      [SHELL32.653]
    783 */
    784 HRESULT WINAPI PathProcessCommandA (LPSTR lpCommand, LPSTR v, DWORD w, DWORD x)
    785 {
    786         FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
    787         lpCommand, lpCommand, v, w,x );
    788         return 0;
    789 }
    790 
    791 HRESULT WINAPI PathProcessCommandW (LPWSTR lpCommand, LPSTR v, DWORD w, DWORD x)
    792 {
    793         FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
    794         lpCommand, debugstr_w(lpCommand), v, w,x );
    795         return 0;
    796 }
    797 
    798 HRESULT WINAPI PathProcessCommandAW (LPVOID lpCommand, LPSTR v, DWORD w, DWORD x)
    799 {
    800         if (VERSION_OsIsUnicode())
    801           return PathProcessCommandW((LPWSTR)lpCommand, v, w, x);
    802         return PathProcessCommandA((LPSTR)lpCommand, v, w, x);
    803 }
    804 
    805 /*************************************************************************
    806  * SHGetSpecialFolderPath [SHELL32.175]
    807  *
    808  * converts csidl to path
    809  *
    810  */
    811 
    812 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
    813 
    814 BOOL WINAPI SHGetSpecialFolderPathA (
    815         HWND hwndOwner,
    816         LPSTR szPath,
    817         DWORD csidl,
    818         BOOL bCreate)
    819 {
    820         CHAR    szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
    821         HKEY    hRootKey, hKey;
    822         BOOL    bRelative = TRUE;
    823         DWORD   dwType, dwDisp, dwPathLen = MAX_PATH;
    824 
    825         TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
    826 
    827         /* build default values */
    828         switch(csidl)
    829         {
    830           case CSIDL_APPDATA:
    831             hRootKey = HKEY_CURRENT_USER;
    832             strcpy (szValueName, "AppData");
    833             strcpy (szDefaultPath, "AppData");
    834             break;
    835 
    836           case CSIDL_COOKIES:
    837             hRootKey = HKEY_CURRENT_USER;
    838             strcpy (szValueName, "Cookies");
    839             strcpy(szDefaultPath, "Cookies");
    840             break;
    841 
    842           case CSIDL_DESKTOPDIRECTORY:
    843             hRootKey = HKEY_CURRENT_USER;
    844             strcpy(szValueName, "Desktop");
    845             strcpy(szDefaultPath, "Desktop");
    846             break;
    847 
    848           case CSIDL_COMMON_DESKTOPDIRECTORY:
    849             hRootKey = HKEY_LOCAL_MACHINE;
    850             strcpy(szValueName, "Common Desktop");
    851             strcpy(szDefaultPath, "Desktop");
    852             break;
    853 
    854           case CSIDL_FAVORITES:
    855             hRootKey = HKEY_CURRENT_USER;
    856             strcpy(szValueName, "Favorites");
    857             strcpy(szDefaultPath, "Favorites");
    858             break;
    859 
    860           case CSIDL_FONTS:
    861             hRootKey = HKEY_CURRENT_USER;
    862             strcpy(szValueName, "Fonts");
    863             strcpy(szDefaultPath, "Fonts");
    864             break;
    865 
    866           case CSIDL_HISTORY:
    867             hRootKey = HKEY_CURRENT_USER;
    868             strcpy(szValueName, "History");
    869             strcpy(szDefaultPath, "History");
    870             break;
    871 
    872           case CSIDL_NETHOOD:
    873             hRootKey = HKEY_CURRENT_USER;
    874             strcpy(szValueName, "NetHood");
    875             strcpy(szDefaultPath, "NetHood");
    876             break;
    877 
    878           case CSIDL_INTERNET_CACHE:
    879             hRootKey = HKEY_CURRENT_USER;
    880             strcpy(szValueName, "Cache");
    881             strcpy(szDefaultPath, "Temporary Internet Files");
    882             break;
    883 
    884           case CSIDL_PERSONAL:
    885             hRootKey = HKEY_CURRENT_USER;
    886             strcpy(szValueName, "Personal");
    887             strcpy(szDefaultPath, "My Own Files");
    888             bRelative = FALSE;
    889             break;
    890 
    891           case CSIDL_PRINTHOOD:
    892             hRootKey = HKEY_CURRENT_USER;
    893             strcpy(szValueName, "PrintHood");
    894             strcpy(szDefaultPath, "PrintHood");
    895             break;
    896 
    897           case CSIDL_PROGRAMS:
    898             hRootKey = HKEY_CURRENT_USER;
    899             strcpy(szValueName, "Programs");
    900             strcpy(szDefaultPath, "StatrMenu\\Programs");
    901             break;
    902 
    903           case CSIDL_COMMON_PROGRAMS:
    904             hRootKey = HKEY_LOCAL_MACHINE;
    905             strcpy(szValueName, "Common Programs");
    906             strcpy(szDefaultPath, "");
    907             break;
    908 
    909           case CSIDL_RECENT:
    910             hRootKey = HKEY_CURRENT_USER;
    911             strcpy(szValueName, "Recent");
    912             strcpy(szDefaultPath, "Recent");
    913             break;
    914 
    915           case CSIDL_SENDTO:
    916             hRootKey = HKEY_CURRENT_USER;
    917             strcpy(szValueName, "SendTo");
    918             strcpy(szDefaultPath, "SendTo");
    919             break;
    920 
    921           case CSIDL_STARTMENU:
    922             hRootKey = HKEY_CURRENT_USER;
    923             strcpy(szValueName, "StartMenu");
    924             strcpy(szDefaultPath, "StartMenu");
    925             break;
    926 
    927           case CSIDL_COMMON_STARTMENU:
    928             hRootKey = HKEY_LOCAL_MACHINE;
    929             strcpy(szValueName, "Common StartMenu");
    930             strcpy(szDefaultPath, "StartMenu");
    931             break;
    932 
    933           case CSIDL_STARTUP:
    934             hRootKey = HKEY_CURRENT_USER;
    935             strcpy(szValueName, "Startup");
    936             strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
    937             break;
    938 
    939           case CSIDL_COMMON_STARTUP:
    940             hRootKey = HKEY_LOCAL_MACHINE;
    941             strcpy(szValueName, "Common Startup");
    942             strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
    943             break;
    944 
    945           case CSIDL_TEMPLATES:
    946             hRootKey = HKEY_CURRENT_USER;
    947             strcpy(szValueName, "Templates");
    948             strcpy(szDefaultPath, "ShellNew");
    949             break;
    950 
    951           default:
    952             ERR("folder unknown or not allowed\n");
    953             return FALSE;
    954         }
    955 
    956         if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisp))
    957         {
    958           return FALSE;
    959         }
    960 
    961         if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
    962         {
    963           /* value not existing */
    964           if (bRelative)
    965           {
    966             GetWindowsDirectoryA(szPath, MAX_PATH);
    967             PathAddBackslashA(szPath);
    968             strcat(szPath, szDefaultPath);
    969           }
    970           else
    971           {
    972             strcpy(szPath, szDefaultPath);
    973           }
    974           if (bCreate)
    975           {
    976             CreateDirectoryA(szPath,NULL);
    977           }
    978           RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
    979         }
    980         RegCloseKey(hKey);
    981 
    982         return TRUE;
    983 }
    984 BOOL WINAPI SHGetSpecialFolderPathW (
    985         HWND hwndOwner,
    986         LPWSTR szPath,
    987         DWORD csidl,
    988         BOOL bCreate)
    989 {
    990         char szTemp[MAX_PATH];
    991        
    992         if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
    993         {
    994           lstrcpynAtoW(szPath, szTemp, MAX_PATH);
    995         }
    996 
    997         TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
    998 
    999         return TRUE;
    1000 }
    1001 BOOL WINAPI SHGetSpecialFolderPathAW (
    1002         HWND hwndOwner,
    1003         LPVOID szPath,
    1004         DWORD csidl,
    1005         BOOL bCreate)
    1006 
    1007 {
    1008         if (VERSION_OsIsUnicode())
    1009           return SHGetSpecialFolderPathW (hwndOwner, (LPWSTR)szPath, csidl, bCreate);
    1010         return SHGetSpecialFolderPathA (hwndOwner, (LPSTR)szPath, csidl, bCreate);
    1011 }
Note: See TracChangeset for help on using the changeset viewer.