Changeset 8584 for trunk/src


Ignore:
Timestamp:
Jun 7, 2002, 10:02:20 AM (23 years ago)
Author:
sandervl
Message:

resynced with latest Wine

Location:
trunk/src/shlwapi
Files:
2 added
1 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shlwapi/LICENSE.TXT

    r6379 r8584  
    1 $Id: LICENSE.TXT,v 1.2 2001-07-21 08:48:22 sandervl Exp $
    2 @c This is an additional Odin license agreement.
    3 @c It supercedes the main Odin license, but is only valid in
    4 @c the source directory in which it is present.
     1$Id: LICENSE.TXT,v 1.3 2002-06-07 08:02:16 sandervl Exp $
     2This is an additional Odin license agreement.
     3It supercedes the main Odin license, but is only valid in
     4the source directory in which it is present.
    55
    6 @c This file is processed by GNU's TeXinfo
    7 @c If you modify it or move it to another location, make sure that
    8 @c TeXinfo works (type `make' in directory documentation).
    9 
    10 Copyright (c) 1993-2000 the Wine project authors (see the file AUTHORS
     6Copyright (c) 1993-2002 the Wine project authors (see the file AUTHORS
    117for a complete list)
    128
    13 Permission is hereby granted, free of charge, to any person obtaining a copy
    14 of this software and associated documentation files (the "Software"), to deal
    15 in the Software without restriction, including without limitation the rights
    16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17 copies of the Software, and to permit persons to whom the Software is
    18 furnished to do so, subject to the following conditions:
     9Wine is free software; you can redistribute it and/or modify it under
     10the terms of the GNU Lesser General Public License as published by the
     11Free Software Foundation; either version 2.1 of the License, or (at
     12your option) any later version.
    1913
    20 The above copyright notice and this permission notice shall be included in
    21 all copies or substantial portions of the Software.
     14This program is distributed in the hope that it will be useful, but
     15WITHOUT ANY WARRANTY; without even the implied warranty of
     16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17Lesser General Public License for more details.
    2218
    23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    27 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    28 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     19A copy of the GNU Lesser General Public License is included in the
     20Wine distribution in the file COPYING.LIB. If you did not receive this
     21copy, write to the Free Software Foundation, Inc., 59 Temple Place,
     22Suite 330, Boston, MA 02111-1307 USA.
  • trunk/src/shlwapi/dbgwrap.cpp

    r7900 r8584  
    6161NODEF_DEBUGWRAP12(SHLWAPI_153)
    6262NODEF_DEBUGWRAP12(SHLWAPI_154)
     63NODEF_DEBUGWRAP8(SHLWAPI_155)
    6364NODEF_DEBUGWRAP8(SHLWAPI_156)
    6465NODEF_DEBUGWRAP8(SHLWAPI_158)
     
    7172NODEF_DEBUGWRAP8(SHLWAPI_172)
    7273NODEF_DEBUGWRAP8(SHLWAPI_174)
     74NODEF_DEBUGWRAP8(SHLWAPI_175)
    7375NODEF_DEBUGWRAP16(SHLWAPI_176)
    7476NODEF_DEBUGWRAP12(SHLWAPI_181)
     
    8284NODEF_DEBUGWRAP24(SHLWAPI_206)
    8385NODEF_DEBUGWRAP20(SHLWAPI_208)
     86NODEF_DEBUGWRAP4(SHLWAPI_209)
    8487NODEF_DEBUGWRAP12(SHLWAPI_210)
    8588NODEF_DEBUGWRAP8(SHLWAPI_211)
     
    101104NODEF_DEBUGWRAP24(SHLWAPI_278)
    102105NODEF_DEBUGWRAP12(SHLWAPI_289)
     106NODEF_DEBUGWRAP20(SHLWAPI_294)
    103107NODEF_DEBUGWRAP20(SHLWAPI_313)
    104108NODEF_DEBUGWRAP16(SHLWAPI_318)
     
    113117NODEF_DEBUGWRAP20(SHLWAPI_337)
    114118NODEF_DEBUGWRAP12(SHLWAPI_346)
     119NODEF_DEBUGWRAP8(SHLWAPI_350)
     120NODEF_DEBUGWRAP16(SHLWAPI_351)
     121NODEF_DEBUGWRAP16(SHLWAPI_352)
    115122NODEF_DEBUGWRAP12(SHLWAPI_356)
    116123NODEF_DEBUGWRAP20(SHLWAPI_357)
     
    128135NODEF_DEBUGWRAP4(SHLWAPI_403)
    129136NODEF_DEBUGWRAP4(SHLWAPI_413)
     137NODEF_DEBUGWRAP4(SHLWAPI_418)
    130138NODEF_DEBUGWRAP4(SHLWAPI_431)
     139NODEF_DEBUGWRAP8(SHLWAPI_436)
    131140NODEF_DEBUGWRAP4(SHLWAPI_437)
    132141
     
    180189DEBUGWRAP4(PathIsDirectoryA)
    181190DEBUGWRAP4(PathIsDirectoryW)
     191DEBUGWRAP4(PathIsDirectoryEmptyA)
     192DEBUGWRAP4(PathIsDirectoryEmptyW)
    182193DEBUGWRAP4(PathIsFileSpecA)
    183194DEBUGWRAP4(PathIsFileSpecW)
     
    365376
    366377
     378DEBUGWRAP16(wvnsprintfA)
     379DEBUGWRAP16(wvnsprintfW)
     380DEBUGWRAP20(SHRegSetPathA)
     381DEBUGWRAP20(SHRegSetPathW)
     382NODEF_DEBUGWRAP4(SHGetThreadRef)
     383NODEF_DEBUGWRAP4(SHSetThreadRef)
     384NODEF_DEBUGWRAP4(SHRegDuplicateHKey)
     385DEBUGWRAP4(PathUndecorateA)
     386DEBUGWRAP4(PathUndecorateW)
     387DEBUGWRAP4(PathIsLFNFileSpecA)
     388DEBUGWRAP4(PathIsLFNFileSpecW)
     389DEBUGWRAP4(PathIsNetworkPathA)
     390DEBUGWRAP4(PathIsNetworkPathW)
     391DEBUGWRAP12(PathFindSuffixArrayA)
     392DEBUGWRAP12(PathFindSuffixArrayW)
  • trunk/src/shlwapi/makefile

    r7900 r8584  
    1 # $Id: makefile,v 1.26 2002-02-13 16:15:07 sandervl Exp $
     1# $Id: makefile,v 1.27 2002-06-07 08:02:17 sandervl Exp $
    22
    33#
     
    3131$(OBJDIR)\reg.obj \
    3232$(OBJDIR)\regstream.obj \
    33 $(OBJDIR)\pathcpp.obj \
    3433$(OBJDIR)\path.obj \
    3534$(OBJDIR)\string_odin.obj \
     
    3736$(OBJDIR)\ordinal.obj \
    3837$(OBJDIR)\ordinal_odin.obj \
     38$(OBJDIR)\wsprintf.obj \
    3939!if "$(DEBUG)" == "1"
    4040$(OBJDIR)\dbgwrap.obj \
     
    4949LIBS = \
    5050$(ODIN32_LIB)/kernel32.lib \
     51$(ODIN32_LIB)/advapi32.lib \
    5152$(ODIN32_LIB)/ntdll.lib \
    5253$(ODIN32_LIB)/user32.lib \
  • trunk/src/shlwapi/ordinal.c

    r7820 r8584  
    55 *           1998 Jürgen Schmied
    66 *           2001 Jon Griffiths
     7 *
     8 * This library is free software; you can redistribute it and/or
     9 * modify it under the terms of the GNU Lesser General Public
     10 * License as published by the Free Software Foundation; either
     11 * version 2.1 of the License, or (at your option) any later version.
     12 *
     13 * This library is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16 * Lesser General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU Lesser General Public
     19 * License along with this library; if not, write to the Free Software
     20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    721 */
    822
     
    2438#include "winreg.h"
    2539#include "winuser.h"
    26 #include "debugtools.h"
     40#include "wine/debug.h"
    2741#include "ordinal.h"
    2842#include "shlwapi.h"
    2943
    30 DEFAULT_DEBUG_CHANNEL(shell);
     44WINE_DEFAULT_DEBUG_CHANNEL(shell);
    3145
    3246extern HINSTANCE shlwapi_hInstance;
     
    3650extern HMODULE SHLWAPI_hmpr;
    3751extern HMODULE SHLWAPI_hmlang;
     52extern HMODULE SHLWAPI_hversion;
     53
     54extern DWORD SHLWAPI_ThreadRef_index;
    3855
    3956typedef HANDLE HSHARED; /* Shared memory */
     
    98115};
    99116
    100 /* Macro to get function pointer for a module*/
    101 #define GET_FUNC(module, name, fail) \
    102   if (!SHLWAPI_h##module) SHLWAPI_h##module = LoadLibraryA(#module ".dll"); \
    103   if (!SHLWAPI_h##module) return fail; \
    104   if (!pfnFunc) pfnFunc = (void*)GetProcAddress(SHLWAPI_h##module, name); \
    105   if (!pfnFunc) return fail
     117/* function pointers for GET_FUNC macro; these need to be global because of gcc bug */
     118#ifdef __WIN32OS2__
     119static LPITEMIDLIST (* WINAPI pSHBrowseForFolderW)(LPBROWSEINFOW);
     120static HRESULT (* WINAPI pConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
     121static BOOL    (* WINAPI pPlaySoundW)(LPCWSTR, HMODULE, DWORD);
     122static DWORD   (* WINAPI pSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
     123static UINT    (* WINAPI pDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
     124static BOOL    (* WINAPI pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
     125static BOOL    (* WINAPI pShellExecuteExW)(LPSHELLEXECUTEINFOW);
     126static HICON   (* WINAPI pSHFileOperationW)(LPSHFILEOPSTRUCTW);
     127static HICON   (* WINAPI pExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
     128static BOOL    (* WINAPI pSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
     129static DWORD   (* WINAPI pSHDefExtractIconW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
     130static HICON   (* WINAPI pExtractIconW)(HINSTANCE, LPCWSTR, UINT);
     131static BOOL    (* WINAPI pGetSaveFileNameW)(LPOPENFILENAMEW);
     132static DWORD   (* WINAPI pWNetRestoreConnectionW)(LPVOID, LPVOID); /* FIXME: Correct args */
     133static DWORD   (* WINAPI pWNetGetLastErrorW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
     134static BOOL    (* WINAPI pPageSetupDlgW)(LPPAGESETUPDLGW);
     135static BOOL    (* WINAPI pPrintDlgW)(LPPRINTDLGW);
     136static BOOL    (* WINAPI pGetOpenFileNameW)(LPOPENFILENAMEW);
     137static HRESULT (* WINAPI pSHGetInstanceExplorer)(LPUNKNOWN *);
     138static DWORD   (* WINAPI pGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
     139static BOOL    (* WINAPI pGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
     140static WORD    (* WINAPI pVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
     141#else
     142static LPITEMIDLIST (WINAPI *pSHBrowseForFolderW)(LPBROWSEINFOW);
     143static HRESULT (WINAPI *pConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
     144static BOOL    (WINAPI *pPlaySoundW)(LPCWSTR, HMODULE, DWORD);
     145static DWORD   (WINAPI *pSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
     146static UINT    (WINAPI *pDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
     147static BOOL    (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
     148static BOOL    (WINAPI *pShellExecuteExW)(LPSHELLEXECUTEINFOW);
     149static HICON   (WINAPI *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
     150static HICON   (WINAPI *pExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
     151static BOOL    (WINAPI *pSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
     152static DWORD   (WINAPI *pSHDefExtractIconW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
     153static HICON   (WINAPI *pExtractIconW)(HINSTANCE, LPCWSTR, UINT);
     154static BOOL    (WINAPI *pGetSaveFileNameW)(LPOPENFILENAMEW);
     155static DWORD   (WINAPI *pWNetRestoreConnectionW)(LPVOID, LPVOID); /* FIXME: Correct args */
     156static DWORD   (WINAPI *pWNetGetLastErrorW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
     157static BOOL    (WINAPI *pPageSetupDlgW)(LPPAGESETUPDLGW);
     158static BOOL    (WINAPI *pPrintDlgW)(LPPRINTDLGW);
     159static BOOL    (WINAPI *pGetOpenFileNameW)(LPOPENFILENAMEW);
     160static HRESULT (WINAPI *pSHGetInstanceExplorer)(LPUNKNOWN *);
     161static DWORD   (WINAPI *pGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
     162static BOOL    (WINAPI *pGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
     163static WORD    (WINAPI *pVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
     164#endif
    106165
    107166/*
     
    127186
    128187    if (y->size != 0x18) return E_INVALIDARG;
    129     /* FIXME: leading white space generates error of 0x80041001 which 
     188    /* FIXME: leading white space generates error of 0x80041001 which
    130189     *        is undefined
    131190     */
     
    183242
    184243    if (y->size != 0x18) return E_INVALIDARG;
    185     /* FIXME: leading white space generates error of 0x80041001 which 
     244    /* FIXME: leading white space generates error of 0x80041001 which
    186245     *        is undefined
    187246     */
     
    230289
    231290/*************************************************************************
     291 * @    [SHLWAPI.3]
     292 *
     293 * Determine if a file exists locally and is of an executable type.
     294 *
     295 * PARAMS
     296 *  lpszFile       [O] File to search for
     297 *  dwWhich        [I] Type of executable to search for
     298 *
     299 * RETURNS
     300 *  TRUE  If the file was found. lpszFile contains the file name.
     301 *  FALSE Otherwise.
     302 *
     303 * NOTES
     304 *  lpszPath is modified in place and must be at least MAX_PATH in length.
     305 *  If the function returns FALSE, the path is modified to its orginal state.
     306 *  If the given path contains an extension or dwWhich is 0, executable
     307 *  extensions are not checked.
     308 *
     309 *  Ordinals 3-6 are a classic case of MS exposing limited functionality to
     310 *  users (here through PathFindOnPath) and keeping advanced functionality for
     311 *  their own developers exclusive use. Monopoly, anyone?
     312 */
     313BOOL WINAPI SHLWAPI_3(LPSTR lpszFile,DWORD dwWhich)
     314{
     315  return SHLWAPI_PathFindLocalExeA(lpszFile,dwWhich);
     316}
     317
     318/*************************************************************************
     319 * @    [SHLWAPI.4]
     320 *
     321 * Unicode version of SHLWAPI_3.
     322 */
     323BOOL WINAPI SHLWAPI_4(LPWSTR lpszFile,DWORD dwWhich)
     324{
     325  return SHLWAPI_PathFindLocalExeW(lpszFile,dwWhich);
     326}
     327
     328/*************************************************************************
     329 * @    [SHLWAPI.5]
     330 *
     331 * Search a range of paths for a specific type of executable.
     332 *
     333 * PARAMS
     334 *  lpszFile       [O] File to search for
     335 *  lppszOtherDirs [I] Other directories to look in
     336 *  dwWhich        [I] Type of executable to search for
     337 *
     338 * RETURNS
     339 *  Success: TRUE. The path to the executable is stored in sFile.
     340 *  Failure: FALSE. The path to the executable is unchanged.
     341 */
     342BOOL WINAPI SHLWAPI_5(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich)
     343{
     344  return SHLWAPI_PathFindOnPathExA(lpszFile,lppszOtherDirs,dwWhich);
     345}
     346
     347/*************************************************************************
     348 * @    [SHLWAPI.6]
     349 *
     350 * Unicode version of SHLWAPI_5.
     351 */
     352BOOL WINAPI SHLWAPI_6(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich)
     353{
     354  return SHLWAPI_PathFindOnPathExW(lpszFile,lppszOtherDirs,dwWhich);
     355}
     356
     357/*************************************************************************
    232358 * SHLWAPI_DupSharedHandle
    233359 *
     
    304430 * SHLWAPI_11           - Helper function; Duplicate cross-process handles
    305431   */
    306 HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, LPCVOID lpvData, DWORD dwSize)
     432HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
    307433{
    308434  HANDLE hMap;
     
    528654 * Function:
    529655 *    Retrieves IE "AcceptLanguage" value from registry. ASCII mode.
    530  * 
     656 *
    531657 */
    532658HRESULT WINAPI SHLWAPI_14 (
     
    540666
    541667        mystrlen = (*buflen > 6) ? *buflen : 6;
    542         mystr = (CHAR*)HeapAlloc(GetProcessHeap(), 
     668        mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
    543669                                 HEAP_ZERO_MEMORY, mystrlen);
    544         RegOpenKeyA(HKEY_CURRENT_USER, 
    545                     "Software\\Microsoft\\Internet Explorer\\International", 
     670        RegOpenKeyA(HKEY_CURRENT_USER,
     671                    "Software\\Microsoft\\Internet Explorer\\International",
    546672                    &mykey);
    547         if (RegQueryValueExA(mykey, "AcceptLanguage", 
     673        if (RegQueryValueExA(mykey, "AcceptLanguage",
    548674                              0, &mytype, mystr, &mystrlen)) {
    549675            /* Did not find value */
     
    564690            FIXME("missing code\n");
    565691        }
    566         if (mystrlen > *buflen) 
     692        if (mystrlen > *buflen)
    567693            lstrcpynA(langbuf, mystr, *buflen);
    568694        else {
    569695            lstrcpyA(langbuf, mystr);
    570696            *buflen = lstrlenA(langbuf);
    571         }       
     697        }
    572698        RegCloseKey(mykey);
    573699        HeapFree(GetProcessHeap(), 0, mystr);
     
    581707 * Function:
    582708 *    Retrieves IE "AcceptLanguage" value from registry. UNICODE mode.
    583  * 
     709 *
    584710 */
    585711HRESULT WINAPI SHLWAPI_15 (
     
    593719
    594720        mystrlen = (*buflen > 6) ? *buflen : 6;
    595         mystr = (CHAR*)HeapAlloc(GetProcessHeap(), 
     721        mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
    596722                                 HEAP_ZERO_MEMORY, mystrlen);
    597         RegOpenKeyA(HKEY_CURRENT_USER, 
    598                     "Software\\Microsoft\\Internet Explorer\\International", 
     723        RegOpenKeyA(HKEY_CURRENT_USER,
     724                    "Software\\Microsoft\\Internet Explorer\\International",
    599725                    &mykey);
    600         if (RegQueryValueExA(mykey, "AcceptLanguage", 
     726        if (RegQueryValueExA(mykey, "AcceptLanguage",
    601727                              0, &mytype, mystr, &mystrlen)) {
    602728            /* Did not find value */
     
    870996BOOL WINAPI SHLWAPI_36(HMENU h1, UINT ui2, UINT h3, LPCWSTR p4)
    871997{
    872     TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n", 
     998    TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n",
    873999          h1, ui2, h3, debugstr_w(p4));
    8741000    return AppendMenuW(h1, ui2, h3, p4);
    875 }
    876 
    877 /*************************************************************************
    878  *      @       [SHLWAPI.40]
    879  *
    880  * Get pointer to next Unicode character.
    881  */
    882 LPCWSTR WINAPI SHLWAPI_40(LPCWSTR str)
    883 {
    884   return *str ? str + 1 : str;
    8851001}
    8861002
     
    9411057{
    9421058    return strncmpiW( str1, str2, len );
     1059}
     1060
     1061/*************************************************************************
     1062 *      @       [SHLWAPI.155]
     1063 *
     1064 *      Case sensitive string compare (ASCII). Does not SetLastError().
     1065 */
     1066DWORD WINAPI SHLWAPI_155 ( LPSTR str1, LPSTR str2)
     1067{
     1068    return strcmp(str1, str2);
    9431069}
    9441070
     
    10731199 *      @       [SHLWAPI.174]
    10741200 *
    1075  * Seems to do call either IObjectWithSite::SetSite or 
     1201 * Seems to do call either IObjectWithSite::SetSite or
    10761202 *   IPersistMoniker::GetClassID.  But since we do not implement either
    10771203 *   of those classes in our headers, we will fake it out.
     
    10791205DWORD WINAPI SHLWAPI_174(
    10801206        IUnknown *p1,     /* [in]   OLE object                          */
    1081         LPVOID *p2)       /* [out]  ptr to result of either GetClassID 
     1207        LPVOID *p2)       /* [out]  ptr to result of either GetClassID
    10821208                                    or SetSite call.                    */
    10831209{
     
    10891215    ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
    10901216    TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
    1091     if (ret) { 
     1217    if (ret) {
    10921218
    10931219        /* see if GetClassId interface exists for IPersistMoniker object */
     
    10981224        /* fake a GetClassId call */
    10991225        ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
    1100         TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret, 
     1226        TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
    11011227              *(LPDWORD)p2);
    11021228        IUnknown_Release((IUnknown *)aa);
     
    11051231        /* fake a SetSite call */
    11061232        ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
    1107         TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret, 
     1233        TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
    11081234              *(LPDWORD)p2);
    11091235        IUnknown_Release((IUnknown *)p1);
     
    11121238}
    11131239
     1240/*************************************************************************
     1241 *      @       [SHLWAPI.175]
     1242 *
     1243 *      NOTE:
     1244 *        Param1 can be an IShellFolder Object
     1245 */
     1246HRESULT WINAPI SHLWAPI_175 (LPVOID x, LPVOID y)
     1247{
     1248        FIXME("(%p %p) stub\n", x,y);
     1249        return E_FAIL;
     1250}
    11141251/*************************************************************************
    11151252 *      @       [SHLWAPI.176]
     
    11331270    if (!unk) return E_FAIL;
    11341271    ret = IUnknown_QueryInterface(unk, &IID_IServiceProvider, &aa);
    1135     TRACE("did IU_QI retval=%08lx, aa=%p\n", ret, aa); 
     1272    TRACE("did IU_QI retval=%08lx, aa=%p\n", ret, aa);
    11361273    if (ret) return ret;
    1137     ret = IServiceProvider_QueryService((IServiceProvider *)aa, sid, riid, 
     1274    ret = IServiceProvider_QueryService((IServiceProvider *)aa, sid, riid,
    11381275                                        (void **)z);
    1139     TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret, (LPVOID)*z); 
     1276    TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret, (LPVOID)*z);
    11401277    IUnknown_Release((IUnknown*)aa);
    11411278    return ret;
     
    12201357
    12211358/*************************************************************************
     1359 *      @       [SHLWAPI.209]
     1360 *
     1361 * Some sort of memory management process - associated with _208
     1362 */
     1363DWORD WINAPI SHLWAPI_209 (
     1364        LPVOID   a)
     1365{
     1366    FIXME("(%p) stub\n",
     1367          a);
     1368    return 1;
     1369}
     1370
     1371/*************************************************************************
    12221372 *      @       [SHLWAPI.210]
    12231373 *
     
    12611411        len_a = lstrlenA(lpStrSrc);
    12621412        ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
    1263         TRACE("%s %s %d, ret=%d\n", 
     1413        TRACE("%s %s %d, ret=%d\n",
    12641414              debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
    12651415        return ret;
     
    12741424                       LPINT lpnMultiCharCount)
    12751425{
    1276   static HRESULT (* WINAPI pfnFunc)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
    12771426  WCHAR emptyW[] = { '\0' };
    12781427  int len , reqLen;
     
    13001449      INT nWideCharCount = len - 1;
    13011450
    1302       GET_FUNC(mlang, "ConvertINetUnicodeToMultiByte", 0);
    1303       if (!pfnFunc(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
    1304                    lpnMultiCharCount))
     1451      GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
     1452      if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
     1453                                          lpnMultiCharCount))
    13051454        return 0;
    13061455
     
    13131462        *lpnMultiCharCount = 0;
    13141463
    1315         if (pfnFunc(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
     1464        if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
    13161465        {
    13171466          SHLWAPI_162 (mem, *lpnMultiCharCount);
     
    14001549            xmove = x;
    14011550            while (xmove->refid) {
    1402                 TRACE("trying (indx %ld) %s\n", xmove->indx, 
     1551                TRACE("trying (indx %ld) %s\n", xmove->indx,
    14031552                      debugstr_guid(xmove->refid));
    14041553                if (IsEqualIID(riid, xmove->refid)) {
     
    15431692/*************************************************************************
    15441693 *      @       [SHLWAPI.266]
     1694 *
     1695 * native does at least approximately:
     1696 *     strcpyW(newstr, x);
     1697 *     strcatW(newstr, "\\Restrictions");
     1698 *     if (RegOpenKeyExA(80000001, newstr, 00000000,00000001,40520b78))
     1699 *        return 0;
     1700 *    *unknown*
    15451701 */
    15461702DWORD WINAPI SHLWAPI_266 (
    15471703        LPVOID w,
    1548         LPVOID x,
     1704        LPVOID x,   /* [in] partial registry key */
    15491705        LPVOID y,
    15501706        LPVOID z)
    15511707{
    15521708        FIXME("(%p %p %p %p)stub\n",w,x,y,z);
    1553         return 0xabba1248;
     1709        return /* 0xabba1248 */ 0;
    15541710}
    15551711
     
    15581714 */
    15591715HRESULT WINAPI SHLWAPI_267 (
    1560         LPVOID w, /* [???] NOTE: same as 1th parameter of SHLWAPI_219 */
    1561         LPVOID x, /* [???] NOTE: same as 2nd parameter of SHLWAPI_219 */
    1562         LPVOID y,
    1563         LPVOID z)
     1716        LPVOID w,
     1717        LPVOID x,
     1718        LPVOID y, /* [???] NOTE: same as 3rd parameter of SHLWAPI_219 */
     1719        LPVOID z) /* [???] NOTE: same as 4th parameter of SHLWAPI_219 */
    15641720{
    15651721        FIXME("(%p %p %p %p)stub\n",w,x,y,z);
     1722
     1723        /* native seems to do:
     1724         *  SHLWAPI_219 ((LPVOID)(((LPSTR)x)-4), ???, (REFIID) y, (LPVOID*) z);
     1725         */
     1726
    15661727        *((LPDWORD)z) = 0xabba1200;
    1567         return 0xabba1254;
     1728        return /* 0xabba1254 */ 0;
    15681729}
    15691730
     
    15821743 *      @       [SHLWAPI.276]
    15831744 *
     1745 * on first call process does following:  other calls just returns 2
     1746 *  instance = LoadLibraryA("SHELL32.DLL");
     1747 *  func = GetProcAddress(instance, "DllGetVersion");
     1748 *  ret = RegOpenKeyExA(80000002, "Software\\Microsoft\\Internet Explorer",00000000,0002001f, newkey);
     1749 *  ret = RegQueryValueExA(newkey, "IntegratedBrowser",00000000,00000000,4052588c,40525890);
     1750 *  RegCloseKey(newkey);
     1751 *  FreeLibrary(instance);
     1752 *  return 2;
    15841753 */
    15851754DWORD WINAPI SHLWAPI_276 ()
    15861755{
    15871756        FIXME("()stub\n");
    1588         return /* 0xabba1244 */ 0;
     1757        return /* 0xabba1244 */ 2;
    15891758}
    15901759
     
    16371806BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
    16381807{
    1639   static BOOL (* WINAPI pfnFunc)(LPCWSTR, HMODULE, DWORD) = NULL;
    1640 
    1641   GET_FUNC(winmm, "PlaySoundW", FALSE);
    1642   return pfnFunc(pszSound, hmod, fdwSound);
     1808  GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
     1809  return pPlaySoundW(pszSound, hmod, fdwSound);
    16431810}
    16441811
     
    16751842                         SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
    16761843{
    1677   static DWORD (* WINAPI pfnFunc)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT) = NULL;
    1678 
    1679   GET_FUNC(shell32, "SHGetFileInfoW", 0);
    1680   return pfnFunc(path, dwFileAttributes, psfi, sizeofpsfi, flags);
     1844  GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
     1845  return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
    16811846}
    16821847
     
    16881853UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
    16891854{
    1690   static UINT (* WINAPI pfnFunc)(HDROP, UINT, LPWSTR, UINT) = NULL;
    1691 
    1692   GET_FUNC(shell32, "DragQueryFileW", 0);
    1693   return pfnFunc(hDrop, lFile, lpszFile, lLength);
     1855  GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
     1856  return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
    16941857}
    16951858
     
    17011864LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
    17021865{
    1703   static LPITEMIDLIST (* WINAPI pfnFunc)(LPBROWSEINFOW) = NULL;
    1704 
    1705   GET_FUNC(shell32, "SHBrowseForFolderW", NULL);
    1706   return pfnFunc(lpBi);
     1866  GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
     1867  return pSHBrowseForFolderW(lpBi);
    17071868}
    17081869
     
    17141875BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
    17151876{
    1716   static BOOL (* WINAPI pfnFunc)(LPCITEMIDLIST, LPWSTR) = NULL;
    1717 
    1718   GET_FUNC(shell32, "SHGetPathFromIDListW", 0);
    1719   return pfnFunc(pidl, pszPath);
     1877  GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
     1878  return pSHGetPathFromIDListW(pidl, pszPath);
    17201879}
    17211880
     
    17271886BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
    17281887{
    1729   static BOOL (* WINAPI pfnFunc)(LPSHELLEXECUTEINFOW) = NULL;
    1730 
    1731   GET_FUNC(shell32, "ShellExecuteExW", FALSE);
    1732   return pfnFunc(lpExecInfo);
     1888  GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
     1889  return pShellExecuteExW(lpExecInfo);
    17331890}
    17341891
     
    17401897DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
    17411898{
    1742   static HICON (* WINAPI pfnFunc)(LPSHFILEOPSTRUCTW) = NULL;
    1743 
    1744   GET_FUNC(shell32, "SHFileOperationW", 0);
    1745   return pfnFunc(lpFileOp);
     1899  GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
     1900  return pSHFileOperationW(lpFileOp);
    17461901}
    17471902
     
    17541909                         HICON *phiconSmall, UINT nIcons)
    17551910{
    1756   static HICON (* WINAPI pfnFunc)(LPCWSTR, INT,HICON *,HICON *, UINT) = NULL;
    1757 
    1758   GET_FUNC(shell32, "ExtractIconExW", (HICON)0);
    1759   return pfnFunc(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
     1911  GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", (HICON)0);
     1912  return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
    17601913}
    17611914
     
    17641917 *
    17651918 */
    1766 DWORD WINAPI SHLWAPI_342 (
    1767         LPDWORD  w,   /* [out] location to put HKEY value???   */
    1768         HKEY     x,   /* [in]  appears to be HKEY_CURRENT_USER */
    1769         LPVOID y)
    1770 {
    1771         FIXME("(%p 0x%08x %p)stub\n", w,x,y);
    1772         *w = (DWORD)x;
    1773         return /* 0xabba1249 */ 0;
     1919LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
     1920{
     1921        return InterlockedCompareExchange(dest, xchg, compare);
    17741922}
    17751923
     
    17881936
    17891937/*************************************************************************
    1790  *      @       [SHLWAPI.356]
    1791  */
    1792 DWORD WINAPI SHLWAPI_356 (
    1793         LPVOID x,
    1794         LPVOID y,
    1795         LPVOID z)
    1796 {
    1797         FIXME("(%p %p %p)stub\n", x,y,z);
    1798         return 0;
    1799 }
     1938 *      @       [SHLWAPI.350]
     1939 *
     1940 * seems to be late bound call to GetFileVersionInfoSizeW
     1941 */
     1942DWORD WINAPI SHLWAPI_350 (
     1943        LPWSTR x,
     1944        LPVOID y)
     1945{
     1946        DWORD ret;
     1947
     1948        GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
     1949        ret = pGetFileVersionInfoSizeW(x, y);
     1950        return 0x208 + ret;
     1951}
     1952
     1953/*************************************************************************
     1954 *      @       [SHLWAPI.351]
     1955 *
     1956 * seems to be late bound call to GetFileVersionInfoW
     1957 */
     1958BOOL  WINAPI SHLWAPI_351 (
     1959        LPWSTR w,   /* [in] path to dll */
     1960        DWORD  x,   /* [in] parm 2 to GetFileVersionInfoA */
     1961        DWORD  y,   /* [in] return value from .350 - assume length */
     1962        LPVOID z)   /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
     1963{
     1964    GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
     1965#ifdef __WIN32OS2__
     1966    return pGetFileVersionInfoW(w, x, y-0x208, (LPSTR)z+0x208);
     1967#else
     1968    return pGetFileVersionInfoW(w, x, y-0x208, z+0x208);
     1969#endif
     1970}
     1971
     1972/*************************************************************************
     1973 *      @       [SHLWAPI.352]
     1974 *
     1975 * seems to be late bound call to VerQueryValueW
     1976 */
     1977WORD WINAPI SHLWAPI_352 (
     1978        LPVOID w,   /* [in] buffer from _351 */
     1979        LPWSTR x,   /* [in]   value to retrieve -
     1980                              converted and passed to VerQueryValueA as #2 */
     1981        LPVOID y,   /* [out]  ver buffer - passed to VerQueryValueA as #3 */
     1982        UINT*  z)   /* [in]   ver length - passed to VerQueryValueA as #4 */
     1983{
     1984    GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
     1985#ifdef __WIN32OS2__
     1986    return pVerQueryValueW((LPSTR)w+0x208, x, y, z);
     1987#else
     1988    return pVerQueryValueW(w+0x208, x, y, z);
     1989#endif
     1990}
     1991
     1992/**************************************************************************
     1993 *      @       [SHLWAPI.356]
     1994 *
     1995 *      mbc - this function is undocumented, The parameters are correct and
     1996 *            the calls to InitializeSecurityDescriptor and
     1997 *            SetSecurityDescriptorDacl are correct, but apparently some
     1998 *            apps call this function with all zero parameters.
     1999 */
     2000
     2001DWORD WINAPI SHLWAPI_356(PACL pDacl, PSECURITY_DESCRIPTOR pSD, LPCSTR *str)
     2002{
     2003  if(str != 0){
     2004    *str = 0;
     2005  }
     2006
     2007  if(!pDacl){
     2008    return 0;
     2009  }
     2010
     2011  if (!InitializeSecurityDescriptor(pSD, 1)) return 0;
     2012  return SetSecurityDescriptorDacl(pSD, 1, pDacl, 0);
     2013}
     2014
    18002015
    18012016/*************************************************************************
     
    18072022                        BOOL *pfMustCopy, UINT uFlags)
    18082023{
    1809   static BOOL (* WINAPI pfnFunc)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT) = NULL;
    1810 
    1811   GET_FUNC(shell32, "SHGetNewLinkInfoW", FALSE);
    1812   return pfnFunc(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
     2024  GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
     2025  return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
    18132026}
    18142027
     
    18212034                         LPVOID arg5, LPVOID arg6)
    18222035{
    1823   /* FIXME: Correct args */
    1824   static DWORD (* WINAPI pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
    1825 
    1826   GET_FUNC(shell32, "SHDefExtractIconW", 0);
    1827   return pfnFunc(arg1, arg2, arg3, arg4, arg5, arg6);
     2036  GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
     2037  return pSHDefExtractIconW(arg1, arg2, arg3, arg4, arg5, arg6);
    18282038}
    18292039
     
    18472057                         UINT nIconIndex)
    18482058{
    1849   static HICON (* WINAPI pfnFunc)(HINSTANCE, LPCWSTR, UINT) = NULL;
    1850 
    1851   GET_FUNC(shell32, "ExtractIconW", (HICON)0);
    1852   return pfnFunc(hInstance, lpszExeFileName, nIconIndex);
     2059  GET_FUNC(pExtractIconW, shell32, "ExtractIconW", (HICON)0);
     2060  return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
    18532061}
    18542062
     
    18682076 *      @       [SHLWAPI.377]
    18692077 *
    1870  * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for 
     2078 * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
    18712079 *        each call here.
    18722080 * FIXME: Native shows calls to:
     
    19312139BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
    19322140{
    1933   static BOOL (* WINAPI pfnFunc)(LPOPENFILENAMEW) = NULL;
    1934 
    1935   GET_FUNC(comdlg32, "GetSaveFileNameW", FALSE);
    1936   return pfnFunc(ofn);
     2141  GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
     2142  return pGetSaveFileNameW(ofn);
    19372143}
    19382144
     
    19442150DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
    19452151{
    1946   /* FIXME: Correct args */
    1947   static DWORD (* WINAPI pfnFunc)(LPVOID, LPVOID) = NULL;
    1948 
    1949   GET_FUNC(mpr, "WNetRestoreConnectionW", 0);
    1950   return pfnFunc(arg1, arg2);
     2152  GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
     2153  return pWNetRestoreConnectionW(arg1, arg2);
    19512154}
    19522155
     
    19592162                         LPVOID arg5)
    19602163{
    1961   /* FIXME: Correct args */
    1962   static DWORD (* WINAPI pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
    1963 
    1964   GET_FUNC(mpr, "WNetGetLastErrorW", 0);
    1965   return pfnFunc(arg1, arg2, arg3, arg4, arg5);
     2164  GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
     2165  return pWNetGetLastErrorW(arg1, arg2, arg3, arg4, arg5);
    19662166}
    19672167
     
    19732173BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
    19742174{
    1975   static BOOL (* WINAPI pfnFunc)(LPPAGESETUPDLGW) = NULL;
    1976 
    1977   GET_FUNC(comdlg32, "PageSetupDlgW", FALSE);
    1978   return pfnFunc(pagedlg);
     2175  GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
     2176  return pPageSetupDlgW(pagedlg);
    19792177}
    19802178
     
    19862184BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
    19872185{
    1988   static BOOL (* WINAPI pfnFunc)(LPPRINTDLGW) = NULL;
    1989 
    1990   GET_FUNC(comdlg32, "PrintDlgW", FALSE);
    1991   return pfnFunc(printdlg);
     2186  GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
     2187  return pPrintDlgW(printdlg);
    19922188}
    19932189
     
    19992195BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
    20002196{
    2001   static BOOL (* WINAPI pfnFunc)(LPOPENFILENAMEW) = NULL;
    2002 
    2003   GET_FUNC(comdlg32, "GetOpenFileNameW", FALSE);
    2004   return pfnFunc(ofn);
     2197  GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
     2198  return pGetOpenFileNameW(ofn);
    20052199}
    20062200
     
    20692263
    20702264/*************************************************************************
     2265 *      @       [SHLWAPI.418]
     2266 *
     2267 * Function seems to do FreeLibrary plus other things.
     2268 *
     2269 * FIXME native shows the following calls:
     2270 *   RtlEnterCriticalSection
     2271 *   LocalFree
     2272 *   GetProcAddress(Comctl32??, 150L)
     2273 *   DPA_DeletePtr
     2274 *   RtlLeaveCriticalSection
     2275 *  followed by the FreeLibrary.
     2276 *  The above code may be related to .377 above.
     2277 */
     2278BOOL  WINAPI SHLWAPI_418 (HMODULE x)
     2279{
     2280        FIXME("(0x%08lx) partial stub\n", (LONG)x);
     2281        return FreeLibrary(x);
     2282}
     2283
     2284/*************************************************************************
    20712285 *      @       [SHLWAPI.431]
    20722286 */
     
    20772291}
    20782292
     2293/*************************************************************************
     2294 *      @       [SHLWAPI.436]
     2295 *
     2296 *  This is really CLSIDFromString which is exported by ole32.dll,
     2297 *  however the native shlwapi.dll does *not* import ole32. Nor does
     2298 *  ole32.dll import this ordinal from shlwapi. Therefore we must conclude
     2299 *  that MS duplicated the code for CLSIDFromString.
     2300 *
     2301 *  This is a duplicate (with changes for UNICODE) of CLSIDFromString16
     2302 *  in dlls/ole32/compobj.c
     2303 */
     2304DWORD WINAPI SHLWAPI_436 (LPWSTR idstr, CLSID *id)
     2305{
     2306    LPWSTR s = idstr;
     2307    BYTE *p;
     2308    INT i;
     2309    WCHAR table[256];
     2310
     2311    if (!s) {
     2312        memset(s, 0, sizeof(CLSID));
     2313        return S_OK;
     2314    }
     2315    else {  /* validate the CLSID string */
     2316
     2317        if (strlenW(s) != 38)
     2318            return CO_E_CLASSSTRING;
     2319
     2320        if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
     2321            return CO_E_CLASSSTRING;
     2322
     2323        for (i=1; i<37; i++)
     2324            {
     2325                if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
     2326                if (!(((s[i] >= L'0') && (s[i] <= L'9'))  ||
     2327                      ((s[i] >= L'a') && (s[i] <= L'f'))  ||
     2328                      ((s[i] >= L'A') && (s[i] <= L'F')))
     2329                    )
     2330                    return CO_E_CLASSSTRING;
     2331            }
     2332    }
     2333
     2334    TRACE("%s -> %p\n", debugstr_w(s), id);
     2335
     2336  /* quick lookup table */
     2337    memset(table, 0, 256*sizeof(WCHAR));
     2338
     2339    for (i = 0; i < 10; i++) {
     2340        table['0' + i] = i;
     2341    }
     2342    for (i = 0; i < 6; i++) {
     2343        table['A' + i] = i+10;
     2344        table['a' + i] = i+10;
     2345    }
     2346
     2347    /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
     2348
     2349    p = (BYTE *) id;
     2350
     2351    s++;        /* skip leading brace  */
     2352    for (i = 0; i < 4; i++) {
     2353        p[3 - i] = table[*s]<<4 | table[*(s+1)];
     2354        s += 2;
     2355    }
     2356    p += 4;
     2357    s++;        /* skip - */
     2358
     2359    for (i = 0; i < 2; i++) {
     2360        p[1-i] = table[*s]<<4 | table[*(s+1)];
     2361        s += 2;
     2362    }
     2363    p += 2;
     2364    s++;        /* skip - */
     2365
     2366    for (i = 0; i < 2; i++) {
     2367        p[1-i] = table[*s]<<4 | table[*(s+1)];
     2368        s += 2;
     2369    }
     2370    p += 2;
     2371    s++;        /* skip - */
     2372
     2373    /* these are just sequential bytes */
     2374    for (i = 0; i < 2; i++) {
     2375        *p++ = table[*s]<<4 | table[*(s+1)];
     2376        s += 2;
     2377    }
     2378    s++;        /* skip - */
     2379
     2380    for (i = 0; i < 6; i++) {
     2381        *p++ = table[*s]<<4 | table[*(s+1)];
     2382        s += 2;
     2383    }
     2384
     2385    return S_OK;
     2386}
    20792387#ifndef __WIN32OS2__
    20802388/*************************************************************************
     
    21042412 * Input HLS values are constrained to the range (0..240).
    21052413 */
    2106 VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue, 
     2414VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue,
    21072415                          LPWORD wLuminance, LPWORD pwSaturation)
    21082416{
     
    21232431 *      SHGetInverseCMAP (SHLWAPI.@)
    21242432 */
    2125 DWORD WINAPI SHGetInverseCMAP (LPVOID x, DWORD why)
    2126 {
    2127         FIXME("(%p, %#lx)stub\n", x, why);
     2433DWORD WINAPI SHGetInverseCMAP (LPDWORD* x, DWORD why)
     2434{
     2435    if (why == 4) {
     2436        FIXME(" - returning bogus address for SHGetInverseCMAP\n");
     2437        *x = (LPDWORD)0xabba1249;
    21282438        return 0;
    2129 }
    2130 
    2131 #ifndef __WIN32OS2__
     2439    }
     2440    FIXME("(%p, %#lx)stub\n", x, why);
     2441    return 0;
     2442}
     2443
    21322444/*************************************************************************
    21332445 *      SHIsLowMemoryMachine    [SHLWAPI.@]
     
    21382450        return 0;
    21392451}
    2140 #endif
     2452
    21412453/*************************************************************************
    21422454 *      GetMenuPosFromID        [SHLWAPI.@]
     
    21642476HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
    21652477{
    2166   static HRESULT (* WINAPI pfnFunc)(LPUNKNOWN *) = NULL;
    2167 
    2168   GET_FUNC(shell32, "SHGetInstanceExplorer", E_FAIL);
    2169   return pfnFunc(lpUnknown);
    2170 }
     2478  GET_FUNC(pSHGetInstanceExplorer, shell32, "SHGetInstanceExplorer", E_FAIL);
     2479  return pSHGetInstanceExplorer(lpUnknown);
     2480}
     2481
     2482/*************************************************************************
     2483 *      SHGetThreadRef  [SHLWAPI.@]
     2484 *
     2485 * Retrieves the per-thread object reference set by SHSetThreadRef
     2486 * "punk" - Address of a pointer to the IUnknown interface. Returns S_OK if
     2487 *          successful or E_NOINTERFACE otherwise.
     2488 */
     2489HRESULT WINAPI SHGetThreadRef (IUnknown ** ppunk)
     2490{
     2491    if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
     2492    *ppunk = (IUnknown *)TlsGetValue(SHLWAPI_ThreadRef_index);
     2493    return S_OK;
     2494}
     2495
     2496/*************************************************************************
     2497 *      SHSetThreadRef  [SHLWAPI.@]
     2498 *
     2499 * Stores a per-thread reference to a COM object
     2500 * "punk" - Pointer to the IUnknown interface of the object to
     2501 *          which you want to store a reference. Returns S_OK if successful
     2502 *          or an OLE error value.
     2503 */
     2504HRESULT WINAPI SHSetThreadRef (IUnknown * punk)
     2505{
     2506    if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
     2507    TlsSetValue(SHLWAPI_ThreadRef_index, (LPVOID) punk);
     2508    return S_OK;
     2509}
  • trunk/src/shlwapi/ordinal.h

    r7820 r8584  
    44 *
    55 * Determined by experimentation.
     6 *
     7 * Copyright 2001 Guy Albertelli
     8 *
     9 * This library is free software; you can redistribute it and/or
     10 * modify it under the terms of the GNU Lesser General Public
     11 * License as published by the Free Software Foundation; either
     12 * version 2.1 of the License, or (at your option) any later version.
     13 *
     14 * This library is distributed in the hope that it will be useful,
     15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17 * Lesser General Public License for more details.
     18 *
     19 * You should have received a copy of the GNU Lesser General Public
     20 * License along with this library; if not, write to the Free Software
     21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    622 */
    723
     
    2844DWORD WINAPI SHLWAPI_2(LPCWSTR x, UNKNOWN_SHLWAPI_2 *y);
    2945
     46/* Macro to get function pointer for a module*/
     47#ifdef __WIN32OS2__
     48#define GET_FUNC(func, module, name, fail) \
     49  do { \
     50    if (!func) { \
     51      if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
     52      if (!(*(DWORD *)&func = (DWORD)GetProcAddress(SHLWAPI_h##module, name))) return fail; \
     53    } \
     54  } while (0)
     55#else
     56#define GET_FUNC(func, module, name, fail) \
     57  do { \
     58    if (!func) { \
     59      if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
     60      if (!(func = (void*)GetProcAddress(SHLWAPI_h##module, name))) return fail; \
     61    } \
     62  } while (0)
     63#endif
     64
     65extern HMODULE SHLWAPI_hshell32;
     66
     67/* Shared internal functions */
     68BOOL WINAPI SHLWAPI_PathFindLocalExeA(LPSTR lpszPath, DWORD dwWhich);
     69BOOL WINAPI SHLWAPI_PathFindLocalExeW(LPWSTR lpszPath, DWORD dwWhich);
     70BOOL WINAPI SHLWAPI_PathFindOnPathExA(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich);
     71BOOL WINAPI SHLWAPI_PathFindOnPathExW(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich);
  • trunk/src/shlwapi/ordinal_odin.cpp

    r7820 r8584  
    1 /* $Id: ordinal_odin.cpp,v 1.5 2002-02-06 20:18:27 sandervl Exp $ */
     1/* $Id: ordinal_odin.cpp,v 1.6 2002-06-07 08:02:17 sandervl Exp $ */
    22
    33/*
     
    5555#include "shellapi.h"
    5656#include "shlobj.h"
    57 #include "wine/undocshell.h"
    5857
    5958#include "shlwapi.h"
     
    6564 *****************************************************************************/
    6665
    67 ODINDEBUGCHANNEL(SHLWAPI-ORDINAL)
    68 
    69 
    70 #if 0
    71 /*****************************************************************************
    72  * Prototypes                                                                *
    73  *****************************************************************************/
    74 
    75 HANDLE WIN32API SHLWAPI_11(HANDLE, DWORD, DWORD, DWORD, DWORD);
     66
     67
     68
     69
     70
     71/*****************************************************************************
     72 * Name      : ???
     73 * Purpose   : Looks like a strdup()
     74 * Parameters: Unknown (wrong)
     75 * Variables :
     76 * Result    : Unknown
     77 * Remark    :
     78 * Status    : UNTESTED STUB
     79 *
     80 * Author    : Patrick Haller [Sun, 2000/06/09 04:47]
     81 *****************************************************************************/
     82
     83DWORD WIN32API SHLWAPI_12(DWORD arg0, DWORD arg1)
     84{
     85  dprintf(("not implemented, explorer.exe will trap now"));
     86
     87  return 0;
     88}
     89
    7690
    7791
     
    86100 * Status    : UNTESTED STUB
    87101 *
    88  * Author    : Christoph Bratschi [Wed, 2000/03/29 19:47]
    89  *****************************************************************************/
    90 
    91 // return characters in protocol part
    92 static INT extractProtocolFromURL(LPSTR  pszURL,
    93                                   LPSTR* ppszColon)
    94 {
    95   int i = 0;  // number of characters scanned
    96   LPSTR s = pszURL;
    97 
    98   *ppszColon = NULL;
    99 
    100   if (*pszURL == 0)
    101     return 0;
    102 
    103 
    104   // scan through the string for the 1st colon
    105   while(*s)
    106   {
    107     // filter non-printable characters
    108     if (*s < ' ')
    109       return 0;
    110     else
    111       if (*s > 0x80)
    112         return 0;     
    113 
    114     // Note: actually, the original code has a table with
    115     // "forbidden" characters, we don't reproduce this here yet.
    116 
    117     if (*s == ':')
    118     {
    119        // yes, first colon found!
    120        if ( (pszURL[0] == 'U' || pszURL[0] == 'u') &&
    121             (pszURL[1] == 'R' || pszURL[1] == 'r') &&
    122             (pszURL[2] == 'L' || pszURL[2] == 'l') )
    123        {
    124          // restart scan!
    125          pszURL = s+1;
    126          i = 0;
    127        }
    128        else
    129        {
    130          // OK, protocol extracted
    131          *ppszColon = s;
    132          return i;
    133        }
    134     }
    135 
    136     // skip to next character
    137     i++;
    138     s++;
    139   } 
     102 * Author    : Patrick Haller [Sun, 2000/06/09 04:47]
     103 *****************************************************************************/
     104
     105DWORD WIN32API SHLWAPI_17(DWORD arg0, DWORD arg1)
     106{
     107  dprintf(("not implemented, explorer.exe will trap now"));
    140108
    141109  return 0;
    142110}
    143111
    144 typedef struct tabProtocolTableEntry
    145 {
    146   LPSTR  pszName; // Note: original is unicode
    147   DWORD  ID;
    148   DWORD  dwNameLength;
    149   DWORD  dwCharacteristic;
    150 } PROTOCOLTABLEENTRY, *LPPROTOCOLTABLEENTRY;
    151 
    152 
    153 #define PROTOCOL_HTTP 2
    154 #define PROTOCOL_FILE 9
    155 
    156 static PROTOCOLTABLEENTRY tabProtocolTable[] =
    157 {
    158   { "http",        PROTOCOL_HTTP,  4, 0x0a },
    159   { "file",        PROTOCOL_FILE,  4, 0x08 },
    160   { "ftp",         1,  3, 0x0a },
    161   { "https",      11,  5, 0x0a },
    162   { "news",        5,  4, 0x0a },
    163   { "mailto",      0,  6, 0x01 },
    164   { "gopher",      3,  6, 0x0a },
    165   { "nntp",        6,  4, 0x0a },
    166   { "telnet",      7,  6, 0x0a },
    167   { "wais",        8,  4, 0x00 },
    168   { "mk",         10,  2, 0x04 },
    169   { "shell",      12,  5, 0x01 },
    170   { "local",      14,  5, 0x00 },
    171   { "javascript", 15, 10, 0x05 },
    172   { "vbscript",   16,  8, 0x05 },
    173   { "snews",      13,  5, 0x0a },
    174   { "about",      17,  5, 0x05 },
    175   { "res",        18,  3, 0x04 }
    176 };
    177 #define END_OF_PROTOCOLTABLE (tabProtocolTable + (sizeof(tabProtocolTable) / sizeof(PROTOCOLTABLEENTRY)) )
    178 
    179 
    180 
    181 static DWORD getProtocolTableEntry(LPSTR pszProtocol, DWORD dwNameLength)
    182 {
    183   LPPROTOCOLTABLEENTRY lpEntry = tabProtocolTable;
    184 
    185   for(;;)
    186   {
    187     if (lpEntry->dwNameLength == dwNameLength)
    188       if (lstrncmpiA( lpEntry->pszName, pszProtocol, dwNameLength) == 0)
    189       {
    190         return lpEntry->ID;
    191       }
    192 
    193     lpEntry++;
    194 
    195     // if scanning beyond end of the table,
    196     // abort and return null
    197     if (lpEntry > END_OF_PROTOCOLTABLE)
    198       return 0;
    199   }
    200 }
    201 
    202 typedef struct tagProtocolHandlerA
    203 {
    204   DWORD  dwSize;
    205   DWORD  dwProtocolNameLength;
    206   LPSTR  lpszProtocolName;
    207   LPSTR  lpszURL;
    208   DWORD  dwURLNameLength;
    209   DWORD  ProtocolID;
    210 } PROTOCOLHANDLERA, *LPPROTOCOLHANDLERA;
    211 
    212 typedef struct tagProtocolHandlerW
    213 {
    214   DWORD  dwSize;
    215   DWORD  dwProtocolNameLength;
    216   LPWSTR lpszProtocolName;
    217   LPWSTR lpszURL;
    218   DWORD  dwURLNameLength;
    219   DWORD  ProtocolID;
    220 } PROTOCOLHANDLERW, *LPPROTOCOLHANDLERW;
    221 
    222 
    223 ODINFUNCTION2(DWORD,   SHLWAPI_1,
    224               LPSTR,   lpszURL,
    225               LPPROTOCOLHANDLERA, lpHandler)
    226 {
    227   dprintf(("not implemented"));
    228 
    229   if (NULL == lpszURL)
    230     return E_INVALIDARG;
    231 
    232   if (NULL == lpHandler)
    233     return E_INVALIDARG;
    234 
    235   if (lpHandler->dwSize != sizeof( PROTOCOLHANDLERA) )
    236     return E_INVALIDARG;
    237 
    238   dprintf(("SHLWAPI-SHLWAPI1: URL=%s",
    239     lpszURL));
    240  
    241   LPSTR lpszColon;
    242   INT iProtocolLength = extractProtocolFromURL(lpszURL,
    243                                                &lpszColon);
    244   lpHandler->dwProtocolNameLength = iProtocolLength;
    245   if (0 == iProtocolLength)
    246     return 0x80041001; // unknown error constant
    247 
    248   lpHandler->lpszProtocolName = lpszURL;
    249 
    250   DWORD ID = getProtocolTableEntry(lpszURL,
    251                                    iProtocolLength);
    252   lpHandler->ProtocolID = ID;
    253   lpHandler->lpszURL    = (LPSTR)(lpszURL + iProtocolLength + 1);
    254  
    255   if (ID == PROTOCOL_FILE)
    256   {
    257     // cut off leading slashes as required
    258     if (lpHandler->lpszURL[0] == '/' &&
    259         lpHandler->lpszURL[1] == '/')
    260       lpHandler->lpszURL = lpHandler->lpszURL + 2;
    261 
    262     if (lpHandler->lpszURL[0] == '/')
    263       lpHandler->lpszURL = lpHandler->lpszURL + 1;
    264   }
    265 
    266   lpHandler->dwURLNameLength = lstrlenA(lpHandler->lpszURL);
    267 
    268   return NO_ERROR;
    269 }
    270 #endif
    271 
    272 
    273 
    274 /*****************************************************************************
    275  * Name      : SHLWAPI_3
    276  * Purpose   :
    277  * Parameters:
    278  * Variables :
    279  * Result    :
    280  * Remark    :
    281  * Status    : STUB UNTESTED
    282  *
    283  * Author    : Patrick Haller [Sun, 2000/06/10 04:02]
    284  *****************************************************************************/
    285 
    286 ODINFUNCTION2(BOOL,  SHLWAPI_3,
    287               LPSTR, lpPath,
    288               LPSTR, lpFile)
    289 {
    290   dprintf(("not properly implemented"));
    291 
    292   return TRUE;
    293 
    294 #if 0
    295   if (lpPath == NULL)                return FALSE;
    296   if (PathIsUNCServerA(lpPath))      return FALSE;
    297   if (PathIsUNCServerShareA(lpPath)) return FALSE;
    298 
    299   if (lpFile == NULL)
    300     return PathFileExistsA(lpPath);
    301   else
    302   {
    303     // PathFindExtensionA
    304     // lstrlenA
    305     // lstrcpyA
    306     // PathFileExistsA
    307     return FALSE;
    308   }
    309 
    310   return FALSE;
    311 #endif
    312 }
    313 
    314 
    315 /*****************************************************************************
    316  * Name      : SHLWAPI_4
    317  * Purpose   :
    318  * Parameters:
    319  * Variables :
    320  * Result    :
    321  * Remark    :
    322  * Status    : STUB UNTESTED
    323  *
    324  * Author    : Patrick Haller [Sun, 2000/06/10 04:02]
    325  *****************************************************************************/
    326 
    327 ODINFUNCTION2(BOOL,   SHLWAPI_4,
    328               LPWSTR, lpPath,
    329               LPWSTR, lpFile)
    330 {
    331   dprintf(("not properly implemented"));
    332 
    333   return TRUE;
    334 
    335 #if 0
    336   if (lpPath == NULL)                return FALSE;
    337   if (PathIsUNCServerW(lpPath))      return FALSE;
    338   if (PathIsUNCServerShareW(lpPath)) return FALSE;
    339 
    340   if (lpFile == NULL)
    341     return PathFileExtensionW(lpPath);
    342   else
    343   {
    344     // PathFindExtensionW
    345     // lstrlenW
    346     // lstrcpyW
    347     // PathFileExistsW
    348     return FALSE;
    349   }
    350 
    351   return FALSE;
    352 #endif
    353 }
     112
    354113
    355114
    356115/*****************************************************************************
    357116 * Name      : ???
    358  * Purpose   : extended version of PathFindOnPathA
     117 * Purpose   : Unknown (used by explorer.exe)
    359118 * Parameters: Unknown (wrong)
    360119 * Variables :
     
    366125 *****************************************************************************/
    367126
    368 ODINFUNCTION3(DWORD, SHLWAPI_5,
    369               LPSTR, lpFile,
    370               LPSTR, lpDirectories,
    371               DWORD, dwUnknown)
    372 
    373 {
    374   dprintf(("not implemented"));
    375 
    376   return 0;
    377 }
    378 
    379 
    380 /*****************************************************************************
    381  * Name      : ???
    382  * Purpose   : extended version of PathFindOnPathA
    383  * Parameters: Unknown (wrong)
    384  * Variables :
    385  * Result    : Unknown
    386  * Remark    :
    387  * Status    : UNTESTED STUB
    388  *
    389  * Author    : Patrick Haller [Sun, 2000/06/09 04:47]
    390  *****************************************************************************/
    391 
    392 ODINFUNCTION3(DWORD, SHLWAPI_6,
    393               DWORD, arg0,
    394               DWORD, arg1,
    395               DWORD, arg2)
    396 
    397 {
    398   dprintf(("not implemented"));
    399 
    400   return 0;
    401 }
    402 
    403 
    404 
    405 
    406 
    407 /*****************************************************************************
    408  * Name      : ???
    409  * Purpose   : Looks like a strdup()
    410  * Parameters: Unknown (wrong)
    411  * Variables :
    412  * Result    : Unknown
    413  * Remark    :
    414  * Status    : UNTESTED STUB
    415  *
    416  * Author    : Patrick Haller [Sun, 2000/06/09 04:47]
    417  *****************************************************************************/
    418 
    419 ODINFUNCTION2(DWORD,SHLWAPI_12,
    420               DWORD,arg0,
    421               DWORD,arg1)
    422 {
    423   dprintf(("not implemented, explorer.exe will trap now"));
    424 
    425   return 0;
    426 }
    427 
    428 
    429 
    430 
    431 /*****************************************************************************
    432  * Name      : ???
    433  * Purpose   : Unknown (used by explorer.exe)
    434  * Parameters: Unknown (wrong)
    435  * Variables :
    436  * Result    : Unknown
    437  * Remark    :
    438  * Status    : UNTESTED STUB
    439  *
    440  * Author    : Patrick Haller [Sun, 2000/06/09 04:47]
    441  *****************************************************************************/
    442 
    443 ODINFUNCTION2(DWORD,SHLWAPI_17,
    444               DWORD, arg0,
    445               DWORD, arg1)
    446 {
    447   dprintf(("not implemented, explorer.exe will trap now"));
    448 
    449   return 0;
    450 }
    451 
    452 
    453 
    454 
    455 /*****************************************************************************
    456  * Name      : ???
    457  * Purpose   : Unknown (used by explorer.exe)
    458  * Parameters: Unknown (wrong)
    459  * Variables :
    460  * Result    : Unknown
    461  * Remark    :
    462  * Status    : UNTESTED STUB
    463  *
    464  * Author    : Patrick Haller [Sun, 2000/06/09 04:47]
    465  *****************************************************************************/
    466 
    467 ODINFUNCTION2(DWORD,SHLWAPI_20,
    468               DWORD, arg0,
    469               DWORD, arg1)
     127DWORD WIN32API SHLWAPI_20(DWORD arg0, DWORD arg1)
    470128{
    471129  dprintf(("not implemented, explorer.exe will trap now"));
     
    493151 *****************************************************************************/
    494152
    495 ODINFUNCTION2(DWORD,  SHLWAPI_160,
    496               DWORD,  arg0,
    497               DWORD,  arg1)
     153DWORD WIN32API SHLWAPI_160(DWORD arg0, DWORD arg1)
    498154{
    499155  dprintf(("not implemented.\n"));
     
    517173 *****************************************************************************/
    518174
    519 ODINFUNCTION6(DWORD,   SHLWAPI_185,
    520               DWORD, arg0,
    521               LPSTR, lpStr1,
    522               LPSTR, lpStr2,
    523               DWORD, arg3,
    524               DWORD, dwDefault,
    525               LPSTR, lpstrValueName)
     175DWORD WIN32API SHLWAPI_185(DWORD arg0, LPSTR lpStr1, LPSTR lpStr2,
     176                           DWORD arg3, DWORD dwDefault, LPSTR lpstrValueName)
    526177{
    527178  BOOL  fDontShow;
     
    587238 *****************************************************************************/
    588239
    589 ODINFUNCTION6(DWORD,  SHLWAPI_191,
    590               HWND,   hwndParent,
    591               DWORD,  arg1,
    592               DWORD,  arg2,
    593               DWORD,  arg3,
    594               DWORD,  dwDefault,
    595               LPWSTR, lpstrDialog)
     240DWORD WIN32API SHLWAPI_191(HWND hwndParent, DWORD arg1, DWORD arg2,
     241                           DWORD arg3, DWORD dwDefault, LPWSTR lpstrDialog)
    596242{
    597243  BOOL rc = SHRegGetBoolUSValueW((LPCWSTR)L"Software\\Microsoft\\Windows\\CurrentVersion"
     
    644290 *****************************************************************************/
    645291
    646 ODINFUNCTION3(BOOL,         SHLWAPI_197,
    647               HDC,          hdc,
    648               CONST RECT*,  lprc,
    649               COLORREF,     crColor)
     292BOOL WIN32API SHLWAPI_197(HDC hdc, CONST RECT*lprc, COLORREF crColor)
    650293{
    651294  COLORREF crOld;
     
    680323 *****************************************************************************/
    681324
    682 ODINFUNCTION5(DWORD, SHLWAPI_243,
    683               DWORD, arg0,
    684               DWORD, arg1,
    685               DWORD, arg2,
    686               DWORD, arg3,
    687               DWORD, arg4)
     325DWORD WIN32API SHLWAPI_243(DWORD arg0, DWORD arg1, DWORD arg2, DWORD arg3,
     326                           DWORD arg4)
    688327{
    689328  dprintf(("not implementes.\n"));
     
    708347#define REG_OPTIONS_DATACENTER  "DataCenter"
    709348
    710 ODINFUNCTION1(DWORD,  SHLWAPI_437,
    711               DWORD,  nFunction)
     349DWORD WIN32API SHLWAPI_437(DWORD  nFunction)
    712350{
    713351  static BOOL           flagProductOptionsInitialized = FALSE;
     
    868506
    869507
    870 /*****************************************************************************
    871  * Name      : SHIsLowMemoryMachine
    872  * Purpose   :
    873  * Parameters: BOOL fRetest - TRUE if testing shall be repeated
    874  *                          - FALSE if cached result is to be used
    875  * Variables :
    876  * Result    : 0 - machine is not memory-constrained
    877  *             1 - machine is memory-constrained
    878  * Remark    : SHLWAPI.584
    879  * Status    : COMPLETELY IMPLEMENTED ? UNTESTED
    880  *
    881  * Author    : Patrick Haller [Mon, 2000/06/11 02:02]
    882  *****************************************************************************/
    883 
    884 ODINFUNCTION1(int,     SHIsLowMemoryMachine,
    885               BOOL,    fRetest)
    886 {
    887          MEMORYSTATUS memBuffer;
    888   static int          flagIsLowMemoryMachine = -1;
    889          ULONG        ulMem;
    890 
    891   // use cached result?
    892   if ( (fRetest == TRUE) ||
    893        (flagIsLowMemoryMachine == -1) )
    894   {
    895     // determine and store result
    896     GlobalMemoryStatus(&memBuffer);
    897     if (VERSION_OsIsUnicode())
    898       ulMem = 0x1000000; // unicode operation mode
    899     else
    900       ulMem = 0x0800000; // ascii operation mode
    901 
    902     // enough memory?
    903     if (memBuffer.dwTotalPhys <= ulMem)
    904       flagIsLowMemoryMachine = 1;
    905     else
    906       flagIsLowMemoryMachine = 0;
    907   }
    908 
    909   return flagIsLowMemoryMachine;
    910 }
    911 
  • trunk/src/shlwapi/path.c

    r8047 r8584  
    11/*
    22 * Path Functions
     3 *
     4 * Copyright 1999, 2000 Juergen Schmied
     5 * Copyright 2001, 2002 Jon Griffiths
     6 *
     7 * This library is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU Lesser General Public
     9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * This library is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with this library; if not, write to the Free Software
     19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    320 */
    421
     
    1532#define NO_SHLWAPI_STREAM
    1633#include "shlwapi.h"
    17 #include "debugtools.h"
     34#include "wine/debug.h"
    1835#include "ordinal.h"
    1936
    20 DEFAULT_DEBUG_CHANNEL(shell);
    21 
    22 INT __cdecl _wtoi(LPWSTR string);
    23 
    24 #define isSlash(x) ((x)=='\\' || (x)=='/')
    25 /*
    26         ########## Combining and Constructing paths ##########
     37WINE_DEFAULT_DEBUG_CHANNEL(shell);
     38
     39/* function pointers for GET_FUNC macro; these need to be global because of gcc bug */
     40#ifdef __WIN32OS2__
     41static BOOL (* WINAPI pIsNetDrive)(DWORD);
     42#else
     43static BOOL (WINAPI *pIsNetDrive)(DWORD);
     44#endif
     45
     46/*************************************************************************
     47 * PathAppendA    [SHLWAPI.@]
     48 *
     49 * Append one path to another.
     50 *
     51 * PARAMS
     52 *  lpszPath   [O] Initial part of path
     53 *  lpszAppend [I] Path to append
     54 *
     55 * RETURNS
     56 *  Success: TRUE. lpszPath contains the newly created path.
     57 *  Failure: FALSE, if either path is NULL, or PathCombineA fails.
     58 *
     59 * NOTES
     60 *  lpszAppend must contain at least one backslash ('\') if not NULL.
     61 *  Because PathCombineA is used to join the paths, the resulting
     62 *  path is also canonicalized.
     63 */
     64BOOL WINAPI PathAppendA (LPSTR lpszPath, LPCSTR lpszAppend)
     65{
     66  TRACE("(%s,%s)\n",debugstr_a(lpszPath), debugstr_a(lpszAppend));
     67
     68  if (lpszPath && lpszAppend)
     69  {
     70    while (*lpszAppend == '\\')
     71      lpszAppend++;
     72    if (PathCombineA(lpszPath, lpszPath, lpszAppend))
     73      return TRUE;
     74  }
     75  return FALSE;
     76}
     77
     78/*************************************************************************
     79 * PathAppendW    [SHLWAPI.@]
     80 *
     81 * See PathAppendA.
     82 */
     83BOOL WINAPI PathAppendW(LPWSTR lpszPath, LPCWSTR lpszAppend)
     84{
     85  TRACE("(%s,%s)\n",debugstr_w(lpszPath), debugstr_w(lpszAppend));
     86
     87  if (lpszPath && lpszAppend)
     88  {
     89    while (*lpszAppend == '\\')
     90      lpszAppend++;
     91    if (PathCombineW(lpszPath, lpszPath, lpszAppend))
     92      return TRUE;
     93  }
     94  return FALSE;
     95}
     96
     97/*************************************************************************
     98 * PathCombineA         [SHLWAPI.@]
     99 *
     100 * Combine two paths together.
     101 *
     102 * PARAMS
     103 *  lpszDest [O] Destination for combined path
     104 *  lpszDir  [I] Directory path
     105 *  liszFile [I] File path
     106 *
     107 * RETURNS
     108 *  Success: The output path
     109 *  Failure: NULL, if inputs are invalid.
     110 *
     111 * NOTES
     112 *  lpszDest should be at least MAX_PATH in size, and may point to the same
     113 *  memory location as lpszDir. The combined path is canonicalised.
     114 */
     115LPSTR WINAPI PathCombineA(LPSTR lpszDest, LPCSTR lpszDir, LPCSTR lpszFile)
     116{
     117  TRACE("(%p,%s,%s)\n", lpszDest, debugstr_a(lpszDir), debugstr_a(lpszFile));
     118
     119  if (!lpszDest || (!lpszDir && !lpszFile))
     120    return NULL; /* Invalid parameters */
     121  else
     122  {
     123    WCHAR szDest[MAX_PATH];
     124    WCHAR szDir[MAX_PATH];
     125    WCHAR szFile[MAX_PATH];
     126    if (lpszDir)
     127      MultiByteToWideChar(0,0,lpszDir,-1,szDir,MAX_PATH);
     128    if (lpszFile)
     129      MultiByteToWideChar(0,0,lpszFile,-1,szFile,MAX_PATH);
     130    PathCombineW(szDest, lpszDir ? szDir : NULL, lpszFile ? szFile : NULL);
     131    WideCharToMultiByte(0,0,szDest,-1,lpszDest,MAX_PATH,0,0);
     132  }
     133  return lpszDest;
     134}
     135
     136/*************************************************************************
     137 * PathCombineW          [SHLWAPI.@]
     138 *
     139 * See PathCombineA.
     140 */
     141LPWSTR WINAPI PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
     142{
     143  WCHAR szTemp[MAX_PATH];
     144  BOOL bUseBoth = FALSE, bStrip = FALSE;
     145
     146  TRACE("(%p,%s,%s)\n", lpszDest, debugstr_w(lpszDir), debugstr_w(lpszFile));
     147
     148  if (!lpszDest || (!lpszDir && !lpszFile))
     149    return lpszDest; /* Invalid parameters */
     150
     151  if (!lpszFile || !*lpszFile)
     152  {
     153    /* Use dir only */
     154    strncpyW(szTemp, lpszDir, MAX_PATH);
     155  }
     156  else if (!lpszDir || !*lpszDir || !PathIsRelativeW(lpszFile))
     157  {
     158    if (!lpszDir || !*lpszDir || *lpszFile != '\\' || PathIsUNCW(lpszFile))
     159    {
     160      /* Use file only */
     161      strncpyW(szTemp, lpszFile, MAX_PATH);
     162    }
     163    else
     164    {
     165      bUseBoth = TRUE;
     166      bStrip = TRUE;
     167    }
     168  }
     169  else
     170    bUseBoth = TRUE;
     171
     172  if (bUseBoth)
     173  {
     174    strncpyW(szTemp, lpszDir, MAX_PATH);
     175    if (bStrip)
     176    {
     177      PathStripToRootW(szTemp);
     178      lpszFile++; /* Skip '\' */
     179    }
     180    if (!PathAddBackslashW(szTemp))
     181      return NULL;
     182    if (strlenW(szTemp) + strlenW(lpszFile) >= MAX_PATH)
     183      return NULL;
     184    strcatW(szTemp, lpszFile);
     185  }
     186
     187  PathCanonicalizeW(lpszDest, szTemp);
     188  return lpszDest;
     189}
     190
     191/*************************************************************************
     192 * PathAddBackslashA    [SHLWAPI.@]
     193 *
     194 * Append a backslash ('\') to a path if one doesn't exist.
     195 *
     196 * PARAMS
     197 *  lpszPath [O] The path to append a backslash to.
     198 *
     199 * RETURNS
     200 *  Success: The position of the last backslash in the path.
     201 *  Failure: NULL, if lpszPath is NULL or the path is too large.
     202 */
     203LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
     204{
     205  int iLen;
     206
     207  TRACE("(%s)\n",debugstr_a(lpszPath));
     208
     209  if (!lpszPath || (iLen = strlen(lpszPath)) >= MAX_PATH)
     210    return NULL;
     211
     212  if (iLen)
     213  {
     214    lpszPath += iLen;
     215    if (lpszPath[-1] != '\\')
     216    {
     217     *lpszPath++ = '\\';
     218     *lpszPath = '\0';
     219    }
     220  }
     221  return lpszPath;
     222}
     223
     224/*************************************************************************
     225 * PathAddBackslashW  [SHLWAPI.@]
     226 *
     227 * See PathAddBackslashA.
     228 */
     229LPWSTR WINAPI PathAddBackslashW( LPWSTR lpszPath )
     230{
     231  int iLen;
     232
     233  TRACE("(%s)\n",debugstr_w(lpszPath));
     234
     235  if (!lpszPath || (iLen = strlenW(lpszPath)) >= MAX_PATH)
     236    return NULL;
     237
     238  if (iLen)
     239  {
     240    lpszPath += iLen;
     241    if (lpszPath[-1] != '\\')
     242    {
     243      *lpszPath++ = '\\';
     244      *lpszPath = '\0';
     245    }
     246  }
     247  return lpszPath;
     248}
     249
     250/*************************************************************************
     251 * PathBuildRootA    [SHLWAPI.@]
     252 *
     253 * Create a root drive string (e.g. "A:\") from a drive number.
     254 *
     255 * PARAMS
     256 *  lpszPath [O] Destination for the drive string
     257 *
     258 * RETURNS
     259 *  lpszPath
     260 *
     261 * NOTES
     262 *  If lpszPath is NULL or drive is invalid, nothing is written to lpszPath.
     263 */
     264LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
     265{
     266  TRACE("(%p,%d)\n", debugstr_a(lpszPath), drive);
     267
     268  if (lpszPath && drive >= 0 && drive < 26)
     269  {
     270    lpszPath[0] = 'A' + drive;
     271    lpszPath[1] = ':';
     272    lpszPath[2] = '\\';
     273    lpszPath[3] = '\0';
     274  }
     275  return lpszPath;
     276}
     277
     278/*************************************************************************
     279 * PathBuildRootW    [SHLWAPI.@]
     280 *
     281 * See PathBuildRootA.
     282 */
     283LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
     284{
     285  TRACE("(%p,%d)\n",debugstr_w(lpszPath), drive);
     286
     287  if (lpszPath && drive >= 0 && drive < 26)
     288  {
     289    lpszPath[0] = 'A' + drive;
     290    lpszPath[1] = ':';
     291    lpszPath[2] = '\\';
     292    lpszPath[3] = '\0';
     293  }
     294  return lpszPath;
     295}
     296
     297/*************************************************************************
     298 * PathFindFileNameA  [SHLWAPI.@]
     299 *
     300 * Locate the start of the file name in a path
     301 *
     302 * PARAMS
     303 *  lpszPath [I] Path to search
     304 *
     305 * RETURNS
     306 *  A pointer to the first character of the file name
     307 */
     308LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
     309{
     310  LPCSTR lastSlash = lpszPath;
     311
     312  TRACE("(%s)\n",debugstr_a(lpszPath));
     313
     314  while (lpszPath && *lpszPath)
     315  {
     316    if ((*lpszPath == '\\' || *lpszPath == '/' || *lpszPath == ':') &&
     317        lpszPath[1] && lpszPath[1] != '\\' && lpszPath[1] != '/')
     318      lastSlash = lpszPath + 1;
     319    lpszPath = CharNextA(lpszPath);
     320  }
     321  return (LPSTR)lastSlash;
     322}
     323
     324/*************************************************************************
     325 * PathFindFileNameW  [SHLWAPI.@]
     326 *
     327 * See PathFindFileNameA.
     328 */
     329LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
     330{
     331  LPCWSTR lastSlash = lpszPath;
     332
     333  TRACE("(%s)\n",debugstr_w(lpszPath));
     334
     335  while (lpszPath && *lpszPath)
     336  {
     337    if ((*lpszPath == '\\' || *lpszPath == '/' || *lpszPath == ':') &&
     338        lpszPath[1] && lpszPath[1] != '\\' && lpszPath[1] != '/')
     339      lastSlash = lpszPath + 1;
     340    lpszPath = CharNextW(lpszPath);
     341  }
     342  return (LPWSTR)lastSlash;
     343}
     344
     345/*************************************************************************
     346 * PathFindExtensionA  [SHLWAPI.@]
     347 *
     348 * Locate the start of the file extension in a path
     349 *
     350 * PARAMS
     351 *  lpszPath [I] The path to search
     352 *
     353 * RETURNS
     354 *  A pointer to the first character of the extension, the end of
     355 *  the string if the path has no extension, or NULL If lpszPath is NULL
     356 */
     357LPSTR WINAPI PathFindExtensionA( LPCSTR lpszPath )
     358{
     359  LPCSTR lastpoint = NULL;
     360
     361  TRACE("(%s)\n", debugstr_a(lpszPath));
     362
     363  if (lpszPath)
     364  {
     365    while (*lpszPath)
     366    {
     367      if (*lpszPath == '\\' || *lpszPath==' ')
     368        lastpoint = NULL;
     369      else if (*lpszPath == '.')
     370        lastpoint = lpszPath;
     371      lpszPath = CharNextA(lpszPath);
     372    }
     373  }
     374  return (LPSTR)(lastpoint ? lastpoint : lpszPath);
     375}
     376
     377/*************************************************************************
     378 * PathFindExtensionW  [SHLWAPI.@]
     379 *
     380 * See PathFindExtensionA.
     381 */
     382LPWSTR WINAPI PathFindExtensionW( LPCWSTR lpszPath )
     383{
     384  LPCWSTR lastpoint = NULL;
     385
     386  TRACE("(%s)\n", debugstr_w(lpszPath));
     387
     388  if (lpszPath)
     389  {
     390    while (*lpszPath)
     391    {
     392      if (*lpszPath == '\\' || *lpszPath==' ')
     393        lastpoint = NULL;
     394      else if (*lpszPath == '.')
     395        lastpoint = lpszPath;
     396      lpszPath = CharNextW(lpszPath);
     397    }
     398  }
     399  return (LPWSTR)(lastpoint ? lastpoint : lpszPath);
     400}
     401
     402/*************************************************************************
     403 * PathGetArgsA    [SHLWAPI.@]
     404 *
     405 * Find the next argument in a string delimited by spaces.
     406 *
     407 * PARAMS
     408 *  lpszPath [I] The string to search for arguments in
     409 *
     410 * RETURNS
     411 *  The start of the next argument in lpszPath, or NULL if lpszPath is NULL
     412 *
     413 * NOTES
     414 *  Spaces in quoted strings are ignored as delimiters.
     415 */
     416LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
     417{
     418  BOOL bSeenQuote = FALSE;
     419
     420  TRACE("(%s)\n",debugstr_a(lpszPath));
     421
     422  if (lpszPath)
     423  {
     424    while (*lpszPath)
     425    {
     426      if ((*lpszPath==' ') && !bSeenQuote)
     427        return (LPSTR)lpszPath + 1;
     428      if (*lpszPath == '"')
     429        bSeenQuote = !bSeenQuote;
     430      lpszPath = CharNextA(lpszPath);
     431    }
     432  }
     433  return (LPSTR)lpszPath;
     434}
     435
     436/*************************************************************************
     437 * PathGetArgsW    [SHLWAPI.@]
     438 *
     439 * See PathGetArgsA.
     440 */
     441LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
     442{
     443  BOOL bSeenQuote = FALSE;
     444
     445  TRACE("(%s)\n",debugstr_w(lpszPath));
     446
     447  if (lpszPath)
     448  {
     449    while (*lpszPath)
     450    {
     451      if ((*lpszPath==' ') && !bSeenQuote)
     452        return (LPWSTR)lpszPath + 1;
     453      if (*lpszPath == '"')
     454        bSeenQuote = !bSeenQuote;
     455      lpszPath = CharNextW(lpszPath);
     456    }
     457  }
     458  return (LPWSTR)lpszPath;
     459}
     460
     461/*************************************************************************
     462 * PathGetDriveNumberA  [SHLWAPI.@]
     463 *
     464 * Return the drive number from a path
     465 *
     466 * PARAMS
     467 *  lpszPath [I] Path to get the drive number from
     468 *
     469 * RETURNS
     470 *  Success: The drive number corresponding to the drive in the path
     471 *  Failure: -1, if lpszPath contains no valid drive
     472 */
     473int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
     474{
     475  TRACE ("(%s)\n",debugstr_a(lpszPath));
     476
     477  if (lpszPath && !IsDBCSLeadByte(*lpszPath) && lpszPath[1] == ':' &&
     478      tolower(*lpszPath) >= 'a' && tolower(*lpszPath) <= 'z')
     479    return tolower(*lpszPath) - 'a';
     480  return -1;
     481}
     482
     483/*************************************************************************
     484 * PathGetDriveNumberW  [SHLWAPI.@]
     485 *
     486 * See PathGetDriveNumberA.
     487 */
     488int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
     489{
     490  TRACE ("(%s)\n",debugstr_w(lpszPath));
     491
     492  if (lpszPath && lpszPath[1] == ':' &&
     493      tolowerW(*lpszPath) >= 'a' && tolowerW(*lpszPath) <= 'z')
     494    return tolowerW(*lpszPath) - 'a';
     495  return -1;
     496}
     497
     498/*************************************************************************
     499 * PathRemoveFileSpecA  [SHLWAPI.@]
     500 *
     501 * Remove the file specification from a path.
     502 *
     503 * PARAMS
     504 *  lpszPath [O] Path to remove the file spec from
     505 *
     506 * RETURNS
     507 *  TRUE  If the path was valid and modified
     508 *  FALSE Otherwise
     509 */
     510BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
     511{
     512  LPSTR lpszFileSpec = lpszPath;
     513  BOOL bModified = FALSE;
     514
     515  TRACE("(%s)\n",debugstr_a(lpszPath));
     516
     517  if(lpszPath)
     518  {
     519    /* Skip directory or UNC path */
     520    if (*lpszPath == '\\')
     521      lpszFileSpec = ++lpszPath;
     522    if (*lpszPath == '\\')
     523      lpszFileSpec = ++lpszPath;
     524
     525    while (*lpszPath)
     526    {
     527      if(*lpszPath == '\\')
     528        lpszFileSpec = lpszPath; /* Skip dir */
     529      else if(*lpszPath == ':')
     530      {
     531        lpszFileSpec = ++lpszPath; /* Skip drive */
     532        if (*lpszPath == '\\')
     533          lpszFileSpec++;
     534      }
     535      if (!(lpszPath = CharNextA(lpszPath)))
     536        break;
     537    }
     538
     539    if (*lpszFileSpec)
     540    {
     541      *lpszFileSpec = '\0';
     542      bModified = TRUE;
     543    }
     544  }
     545  return bModified;
     546}
     547
     548/*************************************************************************
     549 * PathRemoveFileSpecW  [SHLWAPI.@]
     550 *
     551 * See PathRemoveFileSpecA.
     552 */
     553BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
     554{
     555  LPWSTR lpszFileSpec = lpszPath;
     556  BOOL bModified = FALSE;
     557
     558  TRACE("(%s)\n",debugstr_w(lpszPath));
     559
     560  if(lpszPath)
     561  {
     562    /* Skip directory or UNC path */
     563    if (*lpszPath == '\\')
     564      lpszFileSpec = ++lpszPath;
     565    if (*lpszPath == '\\')
     566      lpszFileSpec = ++lpszPath;
     567
     568    while (*lpszPath)
     569    {
     570      if(*lpszPath == '\\')
     571        lpszFileSpec = lpszPath; /* Skip dir */
     572      else if(*lpszPath == ':')
     573      {
     574        lpszFileSpec = ++lpszPath; /* Skip drive */
     575        if (*lpszPath == '\\')
     576          lpszFileSpec++;
     577      }
     578      if (!(lpszPath = CharNextW(lpszPath)))
     579        break;
     580    }
     581
     582    if (*lpszFileSpec)
     583    {
     584      *lpszFileSpec = '\0';
     585      bModified = TRUE;
     586    }
     587  }
     588  return bModified;
     589}
     590
     591/*************************************************************************
     592 * PathStripPathA       [SHLWAPI.@]
     593 *
     594 * Remove the initial path from the beginning of a filename
     595 *
     596 * PARAMS
     597 *  lpszPath [O] Path to remove the initial path from
     598 *
     599 * RETURNS
     600 *  Nothing.
     601 */
     602void WINAPI PathStripPathA(LPSTR lpszPath)
     603{
     604  TRACE("(%s)\n", debugstr_a(lpszPath));
     605
     606  if (lpszPath)
     607  {
     608    LPSTR lpszFileName = PathFindFileNameA(lpszPath);
     609    if(lpszFileName)
     610      RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
     611  }
     612}
     613
     614/*************************************************************************
     615 * PathStripPathW       [SHLWAPI.@]
     616 *
     617 * See PathStripPathA.
     618 */
     619void WINAPI PathStripPathW(LPWSTR lpszPath)
     620{
     621  LPWSTR lpszFileName;
     622
     623  TRACE("(%s)\n", debugstr_w(lpszPath));
     624  lpszFileName = PathFindFileNameW(lpszPath);
     625  if(lpszFileName)
     626    RtlMoveMemory(lpszPath, lpszFileName, (strlenW(lpszFileName)+1)*sizeof(WCHAR));
     627}
     628
     629/*************************************************************************
     630 * PathStripToRootA     [SHLWAPI.@]
     631 *
     632 * Reduce a path to its root.
     633 *
     634 * PARAMS
     635 *  lpszPath [O] the path to reduce
     636 *
     637 * RETURNS
     638 *  Success: TRUE if the stripped path is a root path
     639 *  Failure: FALSE if the path cannot be stripped or is NULL
     640 */
     641BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
     642{
     643  TRACE("(%s)\n", debugstr_a(lpszPath));
     644
     645  if (!lpszPath)
     646    return FALSE;
     647  while(!PathIsRootA(lpszPath))
     648    if (!PathRemoveFileSpecA(lpszPath))
     649      return FALSE;
     650  return TRUE;
     651}
     652
     653/*************************************************************************
     654 * PathStripToRootW     [SHLWAPI.@]
     655 *
     656 * See PathStripToRootA.
     657 */
     658BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
     659{
     660  TRACE("(%s)\n", debugstr_w(lpszPath));
     661
     662  if (!lpszPath)
     663    return FALSE;
     664  while(!PathIsRootW(lpszPath))
     665    if (!PathRemoveFileSpecW(lpszPath))
     666      return FALSE;
     667  return TRUE;
     668}
     669
     670/*************************************************************************
     671 * PathRemoveArgsA      [SHLWAPI.@]
     672 *
     673 * Strip space seperated arguments from a path.
     674 *
     675 * PARAMS
     676 *  lpszPath [I] Path to remove arguments from
     677 *
     678 * RETURNS
     679 *  Nothing.
     680 */
     681void WINAPI PathRemoveArgsA(LPSTR lpszPath)
     682{
     683  TRACE("(%s)\n",debugstr_a(lpszPath));
     684
     685  if(lpszPath)
     686  {
     687    LPSTR lpszArgs = PathGetArgsA(lpszPath);
     688    if (*lpszArgs)
     689      lpszArgs[-1] = '\0';
     690    else
     691    {
     692      LPSTR lpszLastChar = CharPrevA(lpszPath, lpszArgs);
     693      if(*lpszLastChar == ' ')
     694        *lpszLastChar = '\0';
     695    }
     696  }
     697}
     698
     699/*************************************************************************
     700 * PathRemoveArgsW      [SHLWAPI.@]
     701 *
     702 * See PathRemoveArgsA.
     703 */
     704void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
     705{
     706  TRACE("(%s)\n",debugstr_w(lpszPath));
     707
     708  if(lpszPath)
     709  {
     710    LPWSTR lpszArgs = PathGetArgsW(lpszPath);
     711    if (*lpszArgs)
     712      lpszArgs[-1] = '\0';
     713    else
     714    {
     715      LPWSTR lpszLastChar = CharPrevW(lpszPath, lpszArgs);
     716      if(*lpszLastChar == ' ')
     717        *lpszLastChar = '\0';
     718    }
     719  }
     720}
     721
     722/*************************************************************************
     723 * PathRemoveExtensionA         [SHLWAPI.@]
     724 *
     725 * Remove the file extension from a path
     726 *
     727 * PARAMS
     728 *  lpszPath [O] Path to remove the extension from
     729 *
     730 * RETURNS
     731 *  Nothing.
     732 */
     733void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
     734{
     735  TRACE("(%s)\n", debugstr_a(lpszPath));
     736
     737  if (lpszPath)
     738  {
     739    lpszPath = PathFindExtensionA(lpszPath);
     740    *lpszPath = '\0';
     741  }
     742}
     743
     744/*************************************************************************
     745 * PathRemoveExtensionW         [SHLWAPI.@]
     746 *
     747 * See PathRemoveExtensionA.
    27748*/
    28 
    29 /*************************************************************************
    30  * PathAppendA          [SHLWAPI.@]
    31  *
     749void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
     750{
     751  TRACE("(%s)\n", debugstr_w(lpszPath));
     752
     753  if (lpszPath)
     754  {
     755    lpszPath = PathFindExtensionW(lpszPath);
     756    *lpszPath = '\0';
     757  }
     758}
     759
     760/*************************************************************************
     761 * PathRemoveBackslashA [SHLWAPI.@]
     762 *
     763 * Remove a trailing backslash from a path.
     764 *
     765 * PARAMS
     766 *  lpszPath [O] Path to remove backslash from
     767 *
     768 * RETURNS
     769 *  Success: A pointer to the end of the path
     770 *  Failure: NULL, if lpszPath is NULL
     771 */
     772LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
     773{
     774  LPSTR szTemp = NULL;
     775
     776  TRACE("(%s)\n", debugstr_a(lpszPath));
     777
     778  if(lpszPath)
     779  {
     780    szTemp = CharPrevA(lpszPath, lpszPath + strlen(lpszPath));
     781    if (!PathIsRootA(lpszPath) && *szTemp == '\\')
     782      *szTemp = '\0';
     783  }
     784  return szTemp;
     785}
     786
     787/*************************************************************************
     788 * PathRemoveBackslashW [SHLWAPI.@]
     789 *
     790 * See PathRemoveBackslashA.
     791 */
     792LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
     793{
     794  LPWSTR szTemp = NULL;
     795
     796  TRACE("(%s)\n", debugstr_w(lpszPath));
     797
     798  if(lpszPath)
     799  {
     800    szTemp = CharPrevW(lpszPath, lpszPath + strlenW(lpszPath));
     801    if (!PathIsRootW(lpszPath) && *szTemp == '\\')
     802      *szTemp = '\0';
     803  }
     804  return szTemp;
     805}
     806
     807/*************************************************************************
     808 * PathRemoveBlanksA [SHLWAPI.@]
     809 *
     810 * Remove Spaces from the start and end of a path.
     811 *
     812 * PARAMS
     813 *  lpszPath [O] Path to strip blanks from
     814 *
     815 * RETURNS
     816 *  Nothing.
     817 */
     818VOID WINAPI PathRemoveBlanksA(LPSTR lpszPath)
     819{
     820  TRACE("(%s)\n", debugstr_a(lpszPath));
     821
     822  if(lpszPath && *lpszPath)
     823  {
     824    LPSTR start = lpszPath;
     825
     826    while (*lpszPath == ' ')
     827      lpszPath = CharNextA(lpszPath);
     828
     829    while(*lpszPath)
     830      *start++ = *lpszPath++;
     831
     832    if (start != lpszPath)
     833      while (start[-1] == ' ')
     834        start--;
     835    *start = '\0';
     836  }
     837}
     838
     839/*************************************************************************
     840 * PathRemoveBlanksW [SHLWAPI.@]
     841 *
     842 * See PathRemoveBlanksA.
     843 */
     844VOID WINAPI PathRemoveBlanksW(LPWSTR lpszPath)
     845{
     846  TRACE("(%s)\n", debugstr_w(lpszPath));
     847
     848  if(lpszPath && *lpszPath)
     849  {
     850    LPWSTR start = lpszPath;
     851
     852    while (*lpszPath == ' ')
     853      lpszPath++;
     854
     855    while(*lpszPath)
     856      *start++ = *lpszPath++;
     857
     858    if (start != lpszPath)
     859      while (start[-1] == ' ')
     860        start--;
     861    *start = '\0';
     862  }
     863}
     864
     865/*************************************************************************
     866 * PathQuoteSpacesA [SHLWAPI.@]
     867 *
     868 * Surround a path containg spaces in quotes.
     869 *
     870 * PARAMS
     871 *  lpszPath [O] Path to quote
     872 *
     873 * RETURNS
     874 *  Nothing.
     875 *
    32876 * NOTES
    33  *  concat path lpszPath2 onto lpszPath1
    34  *
    35  * FIXME
    36  *  the resulting path is also canonicalized
    37  */
    38 BOOL WINAPI PathAppendA(
    39         LPSTR lpszPath1,
    40         LPCSTR lpszPath2)
    41 {
    42         TRACE("%s %s\n",lpszPath1, lpszPath2);
    43         while (lpszPath2[0]=='\\') lpszPath2++;
    44         PathCombineA(lpszPath1,lpszPath1,lpszPath2);
    45         return TRUE;
    46 }
    47 
    48 /*************************************************************************
    49  * PathAppendW          [SHLWAPI.@]
    50  */
    51 BOOL WINAPI PathAppendW(
    52         LPWSTR lpszPath1,
    53         LPCWSTR lpszPath2)
    54 {
    55         TRACE("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
    56         while (lpszPath2[0]=='\\') lpszPath2++;
    57         PathCombineW(lpszPath1,lpszPath1,lpszPath2);
    58         return TRUE;
    59 }
    60 
    61 /*************************************************************************
    62  * PathCombineA         [SHLWAPI.@]
    63  *
     877 *  The path is not changed if it is invalid or has no spaces.
     878 */
     879VOID WINAPI PathQuoteSpacesA(LPSTR lpszPath)
     880{
     881  TRACE("(%s)\n", debugstr_a(lpszPath));
     882
     883  if(lpszPath && StrChrA(lpszPath,' '))
     884  {
     885    int iLen = strlen(lpszPath) + 1;
     886
     887    if (iLen + 2 < MAX_PATH)
     888    {
     889      memmove(lpszPath + 1, lpszPath, iLen);
     890      lpszPath[0] = '"';
     891      lpszPath[iLen] = '"';
     892      lpszPath[iLen + 1] = '\0';
     893    }
     894  }
     895}
     896
     897/*************************************************************************
     898 * PathQuoteSpacesW [SHLWAPI.@]
     899 *
     900 * See PathQuoteSpacesA.
     901 */
     902VOID WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
     903{
     904  TRACE("(%s)\n", debugstr_w(lpszPath));
     905
     906  if(lpszPath && StrChrW(lpszPath,' '))
     907  {
     908    int iLen = strlenW(lpszPath) + 1;
     909
     910    if (iLen + 2 < MAX_PATH)
     911    {
     912      memmove(lpszPath + 1, lpszPath, iLen * sizeof(WCHAR));
     913      lpszPath[0] = '"';
     914      lpszPath[iLen] = '"';
     915      lpszPath[iLen + 1] = '\0';
     916    }
     917  }
     918}
     919
     920/*************************************************************************
     921 * PathUnquoteSpacesA [SHLWAPI.@]
     922 *
     923 * Remove quotes ("") from around a path, if present.
     924 *
     925 * PARAMS
     926 *  lpszPath [O] Path to strip quotes from
     927 *
     928 * RETURNS
     929 *  Nothing
     930 *
    64931 * NOTES
    65  *  if lpszFile='.' skip it
    66  *  szDest can be equal to lpszFile. Thats why we use sTemp
    67  *
    68  * FIXME
    69  *  the resulting path is also canonicalized
    70  */
    71 LPSTR WINAPI PathCombineA(
    72         LPSTR szDest,
    73         LPCSTR lpszDir,
    74         LPCSTR lpszFile)
    75 {
    76         char sTemp[MAX_PATH];
    77         TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
    78        
    79        
    80         if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
    81         {
    82           strcpy(szDest,lpszDir);
    83           return szDest;
    84         }
    85 
    86         /*  if lpszFile is a complete path don't care about lpszDir */
    87         if (PathGetDriveNumberA(lpszFile) != -1)
    88         {
    89           strcpy(szDest,lpszFile);
    90         }
    91         else if (lpszFile[0] == '\\' )
    92         {
    93           strcpy(sTemp,lpszDir);
    94           PathStripToRootA(sTemp);
    95           strcat(sTemp,lpszFile);
    96           strcpy(szDest,sTemp);
    97         }
    98         else
    99         {
    100           strcpy(sTemp,lpszDir);
    101           PathAddBackslashA(sTemp);
    102           strcat(sTemp,lpszFile);
    103           strcpy(szDest,sTemp);
    104         }
    105         return szDest;
    106 }
    107 
    108 /*************************************************************************
    109  * PathCombineW          [SHLWAPI.@]
    110  */
    111 LPWSTR WINAPI PathCombineW(
    112         LPWSTR szDest,
    113         LPCWSTR lpszDir,
    114         LPCWSTR lpszFile)
    115 {
    116         WCHAR sTemp[MAX_PATH];
    117         TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
    118                          lpszFile, debugstr_w(lpszFile));
    119        
    120        
    121         if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
    122         {
    123           strcpyW(szDest,lpszDir);
    124           return szDest;
    125         }
    126 
    127         /*  if lpszFile is a complete path don't care about lpszDir */
    128         if (PathGetDriveNumberW(lpszFile) != -1)
    129         {
    130             strcpyW(szDest,lpszFile);
    131         }
    132         else if (lpszFile[0] == (WCHAR)'\\' )
    133         {
    134           strcpyW(sTemp,lpszDir);
    135           PathStripToRootW(sTemp);
    136           strcatW(sTemp,lpszFile);
    137           strcpyW(szDest,sTemp);
    138         }
    139         else
    140         {
    141           strcpyW(sTemp,lpszDir);
    142           PathAddBackslashW(sTemp);
    143           strcatW(sTemp,lpszFile);
    144           strcpyW(szDest,sTemp);
    145         }
    146         return szDest;
    147 }
    148 
    149 /*************************************************************************
    150  * PathAddBackslashA    [SHLWAPI.@]
     932 *  If the path contains a single quote only, an empty string will result.
     933 *  Otherwise quotes are only removed if they appear at the start and end
     934 *  of the path.
     935 */
     936VOID WINAPI PathUnquoteSpacesA(LPSTR lpszPath)
     937{
     938  TRACE("(%s)\n", debugstr_a(lpszPath));
     939
     940  if (lpszPath && *lpszPath == '"')
     941  {
     942    DWORD dwLen = strlen(lpszPath) - 1;
     943
     944    if (lpszPath[dwLen] == '"')
     945    {
     946      lpszPath[dwLen] = '\0';
     947      for (; *lpszPath; lpszPath++)
     948        *lpszPath = lpszPath[1];
     949    }
     950  }
     951}
     952
     953/*************************************************************************
     954 * PathUnquoteSpacesW [SHLWAPI.@]
     955 *
     956 * See PathUnquoteSpacesA.
     957 */
     958VOID WINAPI PathUnquoteSpacesW(LPWSTR lpszPath)
     959{
     960  TRACE("(%s)\n", debugstr_w(lpszPath));
     961
     962  if (lpszPath && *lpszPath == '"')
     963  {
     964    DWORD dwLen = strlenW(lpszPath) - 1;
     965
     966    if (lpszPath[dwLen] == '"')
     967    {
     968      lpszPath[dwLen] = '\0';
     969      for (; *lpszPath; lpszPath++)
     970        *lpszPath = lpszPath[1];
     971    }
     972  }
     973}
     974
     975/*************************************************************************
     976 * PathParseIconLocationA  [SHLWAPI.@]
     977 *
     978 * Parse the location of an icon from a path.
     979 *
     980 * PARAMS
     981 *  lpszPath [O] The path to parse the icon location from.
     982 *
     983 * RETURNS
     984 *  Success: The number of the icon
     985 *  Failure: 0 if the path does not contain an icon location or is NULL
    151986 *
    152987 * NOTES
    153  *     append \ if there is none
    154  */
    155 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
    156 {
    157         int len;
    158         TRACE("%p->%s\n",lpszPath,lpszPath);
    159 
    160         len = strlen(lpszPath);
    161         if (len && lpszPath[len-1]!='\\')
    162         {
    163           lpszPath[len]  = '\\';
    164           lpszPath[len+1]= 0x00;
    165           return lpszPath+len+1;
    166         }
    167         return lpszPath+len;
    168 }
    169 
    170 /*************************************************************************
    171  * PathAddBackslashW    [SHLWAPI.@]
    172  */
    173 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
    174 {
    175         int len;
    176         TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
    177 
    178         len = strlenW(lpszPath);
    179         if (len && lpszPath[len-1]!=(WCHAR)'\\')
    180         {
    181           lpszPath[len]  = (WCHAR)'\\';
    182           lpszPath[len+1]= 0x00;
    183           return lpszPath+len+1;
    184         }
    185         return lpszPath+len;
    186 }
    187 
    188 /*************************************************************************
    189  * PathBuildRootA               [SHLWAPI.@]
    190  */
    191 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
    192 {
    193         TRACE("%p %i\n",lpszPath, drive);
    194 
    195         strcpy(lpszPath,"A:\\");
    196         lpszPath[0]+=drive;
    197         return lpszPath;
    198 }
    199 
    200 /*************************************************************************
    201  * PathBuildRootW               [SHLWAPI.@]
    202  */
    203 LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
    204 {
    205         lpszPath[0] = 'A' + drive;
    206         lpszPath[1] = ':';
    207         lpszPath[2] = '\\';
    208         lpszPath[3] = 0;
    209         TRACE("%p %i\n",debugstr_w(lpszPath), drive);
    210         return lpszPath;
    211 }
    212 
    213 /*
    214         Extracting Component Parts
    215 */
    216 
    217 /*************************************************************************
    218  * PathFindFileNameA    [SHLWAPI.@]
    219  */
    220 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
    221 {
    222         LPCSTR lastSlash = lpszPath;
    223 
    224         TRACE("%s\n",lpszPath);
    225         while (*lpszPath)
    226         {
    227           if ( isSlash(lpszPath[0]) && lpszPath[1])
    228               lastSlash = lpszPath+1;
    229           lpszPath = CharNextA(lpszPath);
    230         }
    231         return (LPSTR)lastSlash;
    232 
    233 }
    234 
    235 /*************************************************************************
    236  * PathFindFileNameW    [SHLWAPI.@]
    237  */
    238 LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
    239 {
    240         LPCWSTR wslash;
    241         wslash = lpszPath;
    242 
    243         TRACE("%s\n",debugstr_w(wslash));
    244         while (lpszPath[0])
    245         {
    246           if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
    247             wslash = lpszPath+1;
    248           lpszPath = CharNextW(lpszPath);
    249         }
    250         return (LPWSTR)wslash; 
    251 }
    252 
    253 /*************************************************************************
    254  * PathFindExtensionA   [SHLWAPI.@]
     988 *  The path has surrounding quotes and spaces removed regardless
     989 *  of whether the call succeeds or not.
     990 */
     991int WINAPI PathParseIconLocationA(LPSTR lpszPath)
     992{
     993  int iRet = 0;
     994  LPSTR lpszComma;
     995
     996  TRACE("(%s)\n", debugstr_a(lpszPath));
     997
     998  if (lpszPath)
     999  {
     1000    if ((lpszComma = strchr(lpszPath, ',')))
     1001    {
     1002      *lpszComma++ = '\0';
     1003      iRet = StrToIntA(lpszComma);
     1004    }
     1005    PathUnquoteSpacesA(lpszPath);
     1006    PathRemoveBlanksA(lpszPath);
     1007  }
     1008  return iRet;
     1009}
     1010
     1011/*************************************************************************
     1012 * PathParseIconLocationW  [SHLWAPI.@]
     1013 *
     1014 * See PathParseIconLocationA.
     1015 */
     1016int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
     1017{
     1018  int iRet = 0;
     1019  LPWSTR lpszComma;
     1020
     1021  TRACE("(%s)\n", debugstr_w(lpszPath));
     1022
     1023  if (lpszPath)
     1024  {
     1025    if ((lpszComma = StrChrW(lpszPath, ',')))
     1026    {
     1027      *lpszComma++ = '\0';
     1028      iRet = StrToIntW(lpszComma);
     1029    }
     1030    PathUnquoteSpacesW(lpszPath);
     1031    PathRemoveBlanksW(lpszPath);
     1032  }
     1033  return iRet;
     1034}
     1035
     1036/*************************************************************************
     1037 * SHLWAPI_PathFindLocalExeA
     1038 *
     1039 * Internal implementation of SHLWAPI_3.
     1040 */
     1041BOOL WINAPI SHLWAPI_PathFindLocalExeA (LPSTR lpszPath, DWORD dwWhich)
     1042{
     1043  BOOL bRet = FALSE;
     1044
     1045  TRACE("(%s,%ld)\n", debugstr_a(lpszPath), dwWhich);
     1046
     1047  if (lpszPath)
     1048  {
     1049    WCHAR szPath[MAX_PATH];
     1050    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
     1051    bRet = SHLWAPI_PathFindLocalExeW(szPath, dwWhich);
     1052    if (bRet)
     1053      WideCharToMultiByte(0,0,szPath,-1,lpszPath,MAX_PATH,0,0);
     1054  }
     1055  return bRet;
     1056}
     1057
     1058/*************************************************************************
     1059 * SHLWAPI_PathFindLocalExeW
     1060 *
     1061 * Internal implementation of SHLWAPI_4.
     1062 */
     1063BOOL WINAPI SHLWAPI_PathFindLocalExeW (LPWSTR lpszPath, DWORD dwWhich)
     1064{
     1065  static const WCHAR pszExts[7][5] = { { '.', 'p', 'i', 'f', '0'},
     1066                                       { '.', 'c', 'o', 'm', '0'},
     1067                                       { '.', 'e', 'x', 'e', '0'},
     1068                                       { '.', 'b', 'a', 't', '0'},
     1069                                       { '.', 'l', 'n', 'k', '0'},
     1070                                       { '.', 'c', 'm', 'd', '0'},
     1071                                       { '0', '0', '0', '0', '0'} };
     1072
     1073  TRACE("(%s,%ld)\n", debugstr_w(lpszPath), dwWhich);
     1074
     1075  if (!lpszPath || PathIsUNCServerW(lpszPath) || PathIsUNCServerShareW(lpszPath))
     1076    return FALSE;
     1077
     1078  if (dwWhich)
     1079  {
     1080    LPCWSTR szExt = PathFindExtensionW(lpszPath);
     1081    if (!*szExt || dwWhich & 0x40)
     1082    {
     1083      int iChoose = 0;
     1084      int iLen = lstrlenW(lpszPath);
     1085      if (iLen > (MAX_PATH - 5))
     1086        return FALSE;
     1087      while (dwWhich & 0x1 && iChoose < sizeof(pszExts))
     1088      {
     1089        lstrcpyW(lpszPath + iLen, pszExts[iChoose]);
     1090        if (PathFileExistsW(lpszPath))
     1091          return TRUE;
     1092        iChoose++;
     1093        dwWhich >>= 1;
     1094      }
     1095      *(lpszPath + iLen) = (WCHAR)'\0';
     1096      return FALSE;
     1097    }
     1098  }
     1099  return PathFileExistsW(lpszPath);
     1100}
     1101
     1102/*************************************************************************
     1103 * SHLWAPI_PathFindInOtherDirs
     1104 *
     1105 * Internal helper for SHLWAPI_PathFindOnPathExA/W.
     1106 */
     1107static BOOL WINAPI SHLWAPI_PathFindInOtherDirs(LPWSTR lpszFile, DWORD dwWhich)
     1108{
     1109  static WCHAR szSystem[] = { 'S','y','s','t','e','m','\0'};
     1110  static WCHAR szPath[] = { 'P','A','T','H','\0'};
     1111  DWORD dwLenPATH;
     1112  LPCWSTR lpszCurr;
     1113  WCHAR *lpszPATH;
     1114  WCHAR buff[MAX_PATH];
     1115
     1116  TRACE("(%s,%08lx)\n", debugstr_w(lpszFile), dwWhich);
     1117
     1118  /* Try system directories */
     1119  GetSystemDirectoryW(buff, MAX_PATH);
     1120  if (!PathAppendW(buff, lpszFile))
     1121     return FALSE;
     1122  if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
     1123  {
     1124    strcpyW(lpszFile, buff);
     1125    return TRUE;
     1126  }
     1127  GetWindowsDirectoryW(buff, MAX_PATH);
     1128  if (!PathAppendW(buff, szSystem ) || !PathAppendW(buff, lpszFile))
     1129    return FALSE;
     1130  if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
     1131  {
     1132    strcpyW(lpszFile, buff);
     1133    return TRUE;
     1134  }
     1135  GetWindowsDirectoryW(buff, MAX_PATH);
     1136  if (!PathAppendW(buff, lpszFile))
     1137    return FALSE;
     1138  if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
     1139  {
     1140    strcpyW(lpszFile, buff);
     1141    return TRUE;
     1142  }
     1143  /* Try dirs listed in %PATH% */
     1144  dwLenPATH = GetEnvironmentVariableW(szPath, buff, MAX_PATH);
     1145
     1146  if (!dwLenPATH || !(lpszPATH = malloc((dwLenPATH + 1) * sizeof (WCHAR))))
     1147    return FALSE;
     1148
     1149  GetEnvironmentVariableW(szPath, lpszPATH, dwLenPATH + 1);
     1150  lpszCurr = lpszPATH;
     1151  while (lpszCurr)
     1152  {
     1153    LPCWSTR lpszEnd = lpszCurr;
     1154    LPWSTR pBuff = buff;
     1155
     1156    while (*lpszEnd == ' ')
     1157      lpszEnd++;
     1158    while (*lpszEnd && *lpszEnd != ';')
     1159      *pBuff++ = *lpszEnd++;
     1160    *pBuff = '\0';
     1161
     1162    if (*lpszEnd)
     1163      lpszCurr = lpszEnd + 1;
     1164    else
     1165      lpszCurr = NULL; /* Last Path, terminate after this */
     1166
     1167    if (!PathAppendW(buff, lpszFile))
     1168      return FALSE;
     1169    if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
     1170    {
     1171      strcpyW(lpszFile, buff);
     1172      free(lpszPATH);
     1173      return TRUE;
     1174    }
     1175  }
     1176  free(lpszPATH);
     1177  return FALSE;
     1178}
     1179
     1180
     1181/*************************************************************************
     1182 * SHLWAPI_PathFindOnPathExA
     1183 *
     1184 * Internal implementation of SHLWAPI_5
     1185 */
     1186BOOL WINAPI SHLWAPI_PathFindOnPathExA(LPSTR lpszFile, LPCSTR *lppszOtherDirs, DWORD dwWhich)
     1187{
     1188  WCHAR szFile[MAX_PATH];
     1189  WCHAR buff[MAX_PATH];
     1190
     1191  TRACE("(%s,%p,%08lx)\n", debugstr_a(lpszFile), lppszOtherDirs, dwWhich);
     1192
     1193  if (!lpszFile || !PathIsFileSpecA(lpszFile))
     1194    return FALSE;
     1195
     1196  MultiByteToWideChar(0,0,lpszFile,-1,szFile,MAX_PATH);
     1197
     1198  /* Search provided directories first */
     1199  if (lppszOtherDirs && *lppszOtherDirs)
     1200  {
     1201    WCHAR szOther[MAX_PATH];
     1202    LPCSTR *lpszOtherPath = lppszOtherDirs;
     1203
     1204    while (lpszOtherPath && *lpszOtherPath && (*lpszOtherPath)[0])
     1205    {
     1206      MultiByteToWideChar(0,0,*lpszOtherPath,-1,szOther,MAX_PATH);
     1207      PathCombineW(buff, szOther, szFile);
     1208      if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
     1209      {
     1210        WideCharToMultiByte(0,0,buff,-1,lpszFile,MAX_PATH,0,0);
     1211        return TRUE;
     1212      }
     1213      lpszOtherPath++;
     1214    }
     1215  }
     1216  /* Not found, try system and path dirs */
     1217  if (SHLWAPI_PathFindInOtherDirs(szFile, dwWhich))
     1218  {
     1219    WideCharToMultiByte(0,0,szFile,-1,lpszFile,MAX_PATH,0,0);
     1220    return TRUE;
     1221  }
     1222  return FALSE;
     1223}
     1224
     1225/*************************************************************************
     1226 * SHLWAPI_PathFindOnPathExW
     1227 *
     1228 * Internal implementation of SHLWAPI_6.
     1229 */
     1230BOOL WINAPI SHLWAPI_PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
     1231{
     1232  WCHAR buff[MAX_PATH];
     1233
     1234  TRACE("(%s,%p,%08lx)\n", debugstr_w(lpszFile), lppszOtherDirs, dwWhich);
     1235
     1236  if (!lpszFile || !PathIsFileSpecW(lpszFile))
     1237    return FALSE;
     1238
     1239  /* Search provided directories first */
     1240  if (lppszOtherDirs && *lppszOtherDirs)
     1241  {
     1242    LPCWSTR *lpszOtherPath = lppszOtherDirs;
     1243    while (lpszOtherPath && *lpszOtherPath && (*lpszOtherPath)[0])
     1244    {
     1245      PathCombineW(buff, *lpszOtherPath, lpszFile);
     1246      if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
     1247      {
     1248        strcpyW(lpszFile, buff);
     1249        return TRUE;
     1250      }
     1251      lpszOtherPath++;
     1252    }
     1253  }
     1254  /* Not found, try system and path dirs */
     1255  return SHLWAPI_PathFindInOtherDirs(lpszFile, dwWhich);
     1256}
     1257
     1258/*************************************************************************
     1259 * PathFindOnPathA      [SHLWAPI.@]
     1260 *
     1261 * Search a range of paths for an executable.
     1262 *
     1263 * PARAMS
     1264 *  lpszFile       [O] File to search for
     1265 *  lppszOtherDirs [I] Other directories to look in
     1266 *
     1267 * RETURNS
     1268 *  Success: TRUE. The path to the executable is stored in lpszFile.
     1269 *  Failure: FALSE. The path to the executable is unchanged.
     1270 */
     1271BOOL WINAPI PathFindOnPathA(LPSTR lpszFile, LPCSTR *lppszOtherDirs)
     1272{
     1273  TRACE("(%s,%p)\n", debugstr_a(lpszFile), lppszOtherDirs);
     1274  return SHLWAPI_PathFindOnPathExA(lpszFile, lppszOtherDirs, 0);
     1275 }
     1276
     1277/*************************************************************************
     1278 * PathFindOnPathW      [SHLWAPI.@]
     1279 *
     1280 * See PathFindOnPathA.
     1281 */
     1282BOOL WINAPI PathFindOnPathW (LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
     1283{
     1284  TRACE("(%s,%p)\n", debugstr_w(lpszFile), lppszOtherDirs);
     1285  return SHLWAPI_PathFindOnPathExW(lpszFile,lppszOtherDirs, 0);
     1286}
     1287
     1288/*************************************************************************
     1289 * PathCompactPathExA   [SHLWAPI.@]
     1290 *
     1291 * Compact a path.
     1292 *
     1293 * PARAMS
     1294 *  lpszDest [O] Destination for compacted path
     1295 *  lpszPath [I] Source path
     1296 *  cchMax   [I[ Size of lpszDest
     1297 *  dwFlags  [I] Compaction flags
     1298 *
     1299 * RETURNS
     1300 *  FIXME
     1301 */
     1302BOOL WINAPI PathCompactPathExA(LPSTR lpszDest, LPCSTR lpszPath,
     1303                               UINT cchMax, DWORD dwFlags)
     1304{
     1305  BOOL bRet = FALSE;
     1306
     1307  TRACE("(%p,%s,%d,0x%08lx)\n", lpszDest, debugstr_a(lpszPath), cchMax, dwFlags);
     1308
     1309  if (lpszPath && lpszDest)
     1310  {
     1311    WCHAR szPath[MAX_PATH];
     1312    WCHAR szDest[MAX_PATH];
     1313
     1314    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
     1315    szDest[0] = '\0';
     1316    bRet = PathCompactPathExW(szDest, szPath, cchMax, dwFlags);
     1317    WideCharToMultiByte(0,0,szDest,-1,lpszDest,MAX_PATH,0,0);
     1318  }
     1319  return bRet;
     1320}
     1321
     1322/*************************************************************************
     1323 * PathCompactPathExW   [SHLWAPI.@]
     1324 *
     1325 * See PathCompactPathExA.
     1326 */
     1327BOOL WINAPI PathCompactPathExW(LPWSTR lpszDest, LPCWSTR lpszPath,
     1328                               UINT cchMax, DWORD dwFlags)
     1329{
     1330  FIXME("(%p,%s,%d,0x%08lx)-stub\n", lpszDest, debugstr_w(lpszPath), cchMax, dwFlags);
     1331
     1332  if (!lpszPath)
     1333    return FALSE;
     1334
     1335  if (!lpszDest)
     1336  {
     1337    WARN("Invalid lpszDest would crash under Win32!\n");
     1338    return FALSE;
     1339  }
     1340
     1341  /* FIXME */
     1342
     1343  return FALSE;
     1344}
     1345
     1346/*************************************************************************
     1347 * PathIsRelativeA      [SHLWAPI.@]
     1348 *
     1349 * Determine if a path is a relative path.
     1350 *
     1351 * PARAMS
     1352 *  lpszPath [I] Path to check
     1353 *
     1354 * RETURNS
     1355 *  TRUE:  The path is relative, or is invalid.
     1356 *  FALSE: The path is not relative.
     1357 */
     1358BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
     1359{
     1360  TRACE("(%s)\n",debugstr_a(lpszPath));
     1361
     1362  if (!lpszPath || !*lpszPath || IsDBCSLeadByte(*lpszPath))
     1363    return TRUE;
     1364  if (*lpszPath == '\\' || (*lpszPath && lpszPath[1] == ':'))
     1365    return FALSE;
     1366  return TRUE;
     1367}
     1368
     1369/*************************************************************************
     1370 *  PathIsRelativeW     [SHLWAPI.@]
     1371 *
     1372 * See PathIsRelativeA.
     1373 */
     1374BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
     1375{
     1376  TRACE("(%s)\n",debugstr_w(lpszPath));
     1377
     1378  if (!lpszPath || !*lpszPath)
     1379    return TRUE;
     1380  if (*lpszPath == '\\' || (*lpszPath && lpszPath[1] == ':'))
     1381    return FALSE;
     1382  return TRUE;
     1383}
     1384
     1385/*************************************************************************
     1386 * PathIsRootA          [SHLWAPI.@]
     1387 *
     1388 * Determine if a path is a root path.
     1389 *
     1390 * PARAMS
     1391 *  lpszPath [I] Path to check
     1392 *
     1393 * RETURNS
     1394 *  TRUE  If lpszPath is valid and a root path
     1395 *  FALSE Otherwise
     1396 */
     1397BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
     1398{
     1399  TRACE("(%s)\n", debugstr_a(lpszPath));
     1400
     1401  if (lpszPath && *lpszPath)
     1402  {
     1403    if (*lpszPath == '\\')
     1404    {
     1405      if (!lpszPath[1])
     1406        return TRUE; /* \ */
     1407      else if (lpszPath[1]=='\\')
     1408      {
     1409        BOOL bSeenSlash = FALSE;
     1410        lpszPath += 2;
     1411
     1412        /* Check for UNC root path */
     1413        while (*lpszPath)
     1414        {
     1415          if (*lpszPath == '\\')
     1416          {
     1417            if (bSeenSlash)
     1418              return FALSE;
     1419            bSeenSlash = TRUE;
     1420          }
     1421          lpszPath = CharNextA(lpszPath);
     1422        }
     1423        return TRUE;
     1424      }
     1425    }
     1426    else if (lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0')
     1427      return TRUE; /* X:\ */
     1428  }
     1429  return FALSE;
     1430}
     1431
     1432/*************************************************************************
     1433 * PathIsRootW          [SHLWAPI.@]
     1434 *
     1435 * See PathIsRootA.
     1436 */
     1437BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
     1438{
     1439  TRACE("(%s)\n", debugstr_w(lpszPath));
     1440
     1441  if (lpszPath && *lpszPath)
     1442  {
     1443    if (*lpszPath == '\\')
     1444    {
     1445      if (!lpszPath[1])
     1446        return TRUE; /* \ */
     1447      else if (lpszPath[1]=='\\')
     1448      {
     1449        BOOL bSeenSlash = FALSE;
     1450        lpszPath += 2;
     1451
     1452        /* Check for UNC root path */
     1453        while (*lpszPath)
     1454        {
     1455          if (*lpszPath == '\\')
     1456          {
     1457            if (bSeenSlash)
     1458              return FALSE;
     1459            bSeenSlash = TRUE;
     1460          }
     1461          lpszPath = CharNextW(lpszPath);
     1462        }
     1463        return TRUE;
     1464      }
     1465    }
     1466    else if (lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0')
     1467      return TRUE; /* X:\ */
     1468  }
     1469  return FALSE;
     1470}
     1471
     1472/*************************************************************************
     1473 * PathIsDirectoryA     [SHLWAPI.@]
     1474 *
     1475 * Determine if a path is a valid directory
     1476 *
     1477 * PARAMS
     1478 *  lpszPath [I] Path to check.
     1479 *
     1480 * RETURNS
     1481 *  FILE_ATTRIBUTE_DIRECTORY if lpszPath exists and can be read (See Notes)
     1482 *  FALSE if lpszPath is invalid or not a directory.
    2551483 *
    2561484 * NOTES
    257  *     returns pointer to last . in last lpszPath component or at \0.
    258  */
    259 
    260 LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
    261 {
    262         LPCSTR   lastpoint = NULL;
    263 
    264         TRACE("%p %s\n",lpszPath,lpszPath);
    265 
    266         while (*lpszPath)
    267         {
    268           if (*lpszPath=='\\'||*lpszPath==' ')
    269             lastpoint=NULL;
    270           if (*lpszPath=='.')
    271             lastpoint=lpszPath;
    272           lpszPath = CharNextA(lpszPath);
    273         }
    274         return (LPSTR)(lastpoint?lastpoint:lpszPath);
    275 }
    276 
    277 /*************************************************************************
    278  * PathFindExtensionW   [SHLWAPI.@]
    279  */
    280 LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
    281 {
    282         LPCWSTR   lastpoint = NULL;
    283 
    284         TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
    285 
    286         while (*lpszPath)
    287         {
    288           if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
    289             lastpoint=NULL;
    290           if (*lpszPath==(WCHAR)'.')
    291             lastpoint=lpszPath;
    292           lpszPath = CharNextW(lpszPath);
    293         }
    294         return (LPWSTR)(lastpoint?lastpoint:lpszPath);
    295 }
    296 
    297 /*************************************************************************
    298  * PathGetArgsA         [SHLWAPI.@]
    299  *
    300  * NOTES
    301  *     look for next arg in string. handle "quoted" strings
    302  *     returns pointer to argument *AFTER* the space. Or to the \0.
    303  *
    304  * FIXME
    305  *     quoting by '\'
    306  */
    307 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
    308 {
    309         BOOL    qflag = FALSE;
    310 
    311         TRACE("%s\n",lpszPath);
    312 
    313         while (*lpszPath)
    314         {
    315           if ((*lpszPath==' ') && !qflag)
    316             return (LPSTR)lpszPath+1;
    317           if (*lpszPath=='"')
    318             qflag=!qflag;
    319           lpszPath = CharNextA(lpszPath);
    320         }
    321         return (LPSTR)lpszPath;
    322 }
    323 
    324 /*************************************************************************
    325  * PathGetArgsW         [SHLWAPI.@]
    326  */
    327 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
    328 {
    329         BOOL    qflag = FALSE;
    330 
    331         TRACE("%s\n",debugstr_w(lpszPath));
    332 
    333         while (*lpszPath)
    334         {
    335           if ((*lpszPath==' ') && !qflag)
    336             return (LPWSTR)lpszPath+1;
    337           if (*lpszPath=='"')
    338             qflag=!qflag;
    339           lpszPath = CharNextW(lpszPath);
    340         }
    341         return (LPWSTR)lpszPath;
    342 }
    343 
    344 /*************************************************************************
    345  * PathGetDriveNumberA  [SHLWAPI.@]
    346  */
    347 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
    348 {
    349         int chr = tolower(lpszPath[0]);
    350        
    351         TRACE ("%s\n",debugstr_a(lpszPath));
    352 
    353         if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
    354         return tolower(lpszPath[0]) - 'a' ;
    355 }
    356 
    357 /*************************************************************************
    358  * PathGetDriveNumberW  [SHLWAPI.@]
    359  */
    360 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
    361 {
    362         int chr = tolowerW(lpszPath[0]);
    363        
    364         TRACE ("%s\n",debugstr_w(lpszPath));
    365 
    366         if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
    367         return tolowerW(lpszPath[0]) - 'a' ;
    368 }
    369 
    370 /*************************************************************************
    371  * PathRemoveFileSpecA  [SHLWAPI.@]
    372  *
    373  * NOTES
    374  *     truncates passed argument to a valid path
    375  *     returns if the string was modified or not.
    376  *     "\foo\xx\foo"-> "\foo\xx"
    377  *     "\" -> "\"
    378  *     "a:\foo" -> "a:\"
    379  */
    380 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
    381 {
    382         LPSTR cutplace = lpszPath;
    383         BOOL ret = FALSE;
    384        
    385         TRACE("%s\n",lpszPath);
    386 
    387         if(lpszPath)
    388         {
    389           while (*lpszPath == '\\') cutplace = ++lpszPath;
    390          
    391           while (*lpszPath)
    392           {
    393             if(lpszPath[0] == '\\') cutplace = lpszPath;
    394          
    395             if(lpszPath[0] == ':')
    396             {
    397               cutplace = lpszPath + 1;
    398               if (lpszPath[1] == '\\') cutplace++;
    399               lpszPath++;
    400             }
    401             lpszPath = CharNextA(lpszPath);
    402             if (!lpszPath) break;
    403           }
    404          
    405           ret = (*cutplace!='\0');
    406           *cutplace = '\0';
    407         }
    408         return ret;
    409 }
    410 
    411 /*************************************************************************
    412  * PathRemoveFileSpecW  [SHLWAPI.@]
    413  */
    414 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
    415 {
    416         LPWSTR cutplace = lpszPath;
    417         BOOL ret = FALSE;
    418 
    419         TRACE("%s\n",debugstr_w(lpszPath));
    420 
    421         if(lpszPath)
    422         {
    423           while (*lpszPath == '\\') cutplace = ++lpszPath;
    424          
    425           while (*lpszPath)
    426           {
    427             if(lpszPath[0] == '\\') cutplace = lpszPath;
    428          
    429             if(lpszPath[0] == ':')
    430             {
    431               cutplace = lpszPath + 1;
    432               if (lpszPath[1] == '\\') cutplace++;
    433               lpszPath++;
    434             }
    435             lpszPath = CharNextW(lpszPath);
    436             if (!lpszPath) break;
    437           }
    438          
    439           ret = (*cutplace!='\0');
    440           *cutplace = '\0';
    441         }
    442         return ret;
    443 }
    444 
    445 /*************************************************************************
    446  * PathStripPathA       [SHLWAPI.@]
    447  *
    448  * NOTES
    449  *  removes the path from the beginning of a filename
    450  */
    451 void WINAPI PathStripPathA(LPSTR lpszPath)
    452 {
    453         LPSTR lpszFileName = PathFindFileNameA(lpszPath);
    454 
    455         TRACE("%s\n", lpszPath);
    456 
    457         if(lpszFileName)
    458           RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
    459 }
    460 
    461 /*************************************************************************
    462  * PathStripPathW       [SHLWAPI.@]
    463  */
    464 void WINAPI PathStripPathW(LPWSTR lpszPath)
    465 {
    466         LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
    467 
    468         TRACE("%s\n", debugstr_w(lpszPath));
    469         if(lpszFileName)
    470           RtlMoveMemory(lpszPath, lpszFileName, (strlenW(lpszFileName)+1)*sizeof(WCHAR));
    471 }
    472 
    473 /*************************************************************************
    474  * PathStripToRootA     [SHLWAPI.@]
    475  */
    476 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
    477 {
    478         TRACE("%s\n", lpszPath);
    479 
    480         if (!lpszPath) return FALSE;
    481         while(!PathIsRootA(lpszPath))
    482           if (!PathRemoveFileSpecA(lpszPath)) return FALSE;
    483         return TRUE;
    484 }
    485 
    486 /*************************************************************************
    487  * PathStripToRootW     [SHLWAPI.@]
    488  */
    489 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
    490 {
    491         TRACE("%s\n", debugstr_w(lpszPath));
    492 
    493         if (!lpszPath) return FALSE;
    494         while(!PathIsRootW(lpszPath))
    495           if (!PathRemoveFileSpecW(lpszPath)) return FALSE;
    496         return TRUE;
    497 }
    498 
    499 /*************************************************************************
    500  * PathRemoveArgsA      [SHLWAPI.@]
    501  *
    502  */
    503 void WINAPI PathRemoveArgsA(LPSTR lpszPath)
    504 {
    505         TRACE("%s\n",lpszPath);
    506        
    507         if(lpszPath)
    508         {
    509           LPSTR lpszArgs = PathGetArgsA(lpszPath);
    510           if (!*lpszArgs)
    511           {
    512             LPSTR lpszLastChar = CharPrevA(lpszPath, lpszArgs);
    513             if(*lpszLastChar==' ') *lpszLastChar = '\0';
    514           }
    515         }
    516 }
    517 
    518 /*************************************************************************
    519  * PathRemoveArgsW      [SHLWAPI.@]
    520  */
    521 void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
    522 {
    523         TRACE("%s\n", debugstr_w(lpszPath));
    524 
    525         if(lpszPath)
    526         {
    527           LPWSTR lpszArgs = PathGetArgsW(lpszPath);
    528           if (!*lpszArgs)
    529           {
    530             LPWSTR lpszLastChar = CharPrevW(lpszPath, lpszArgs);
    531             if(*lpszLastChar==' ') *lpszLastChar = '\0';
    532           }
    533         }
    534 }
    535 
    536 /*************************************************************************
    537  * PathRemoveExtensionA         [SHLWAPI.@]
    538  */
    539 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
    540 {
    541         LPSTR lpszExtension = PathFindExtensionA(lpszPath);
    542 
    543         TRACE("%s\n", lpszPath);
    544 
    545         if (lpszExtension) *lpszExtension='\0';
    546 }
    547 
    548 /*************************************************************************
    549  * PathRemoveExtensionW         [SHLWAPI.@]
    550  */
    551 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
    552 {
    553         LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
    554 
    555         TRACE("%s\n", debugstr_w(lpszPath));
    556 
    557         if (lpszExtension) *lpszExtension='\0';
    558 }
    559 
    560 /*************************************************************************
    561  * PathRemoveBackslashA [SHLWAPI.@]
    562  *
    563  * If the path ends in a backslash it is replaced by a NULL
    564  * and the address of the NULL is returned
    565  * Otherwise
    566  * the address of the last character is returned.
    567  *
    568  * FIXME
    569  *  "c:\": keep backslash
    570  */
    571 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
    572 {
    573         int len;
    574         LPSTR szTemp = NULL;
    575        
    576         if(lpszPath)
    577         {
    578           len = strlen(lpszPath);
    579           szTemp = CharPrevA(lpszPath, lpszPath+len);
    580           if (! PathIsRootA(lpszPath))
    581           {
    582             if (*szTemp == '\\') *szTemp = '\0';
    583           }
    584         }
    585         return szTemp;
    586 }
    587 
    588 /*************************************************************************
    589  * PathRemoveBackslashW [SHLWAPI.@]
    590  */
    591 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
    592 {
    593         int len;
    594         LPWSTR szTemp = NULL;
    595        
    596         if(lpszPath)
    597         {
    598           len = strlenW(lpszPath);
    599           szTemp = CharPrevW(lpszPath, lpszPath+len);
    600           if (! PathIsRootW(lpszPath))
    601           {
    602             if (*szTemp == '\\') *szTemp = '\0';
    603           }
    604         }
    605         return szTemp;
    606 }
    607 
    608 
    609 /*
    610         Path Manipulations
    611 */
    612 
    613 /*************************************************************************
    614  * PathRemoveBlanksA [SHLWAPI.@]
    615  *
    616  * NOTES
    617  *     remove spaces from beginning and end of passed string
    618  */
    619 void WINAPI PathRemoveBlanksA(LPSTR str)
    620 {
    621         LPSTR x = str;
    622 
    623         TRACE("%s\n",str);
    624 
    625         if(str)
    626         {
    627           while (*x==' ') x = CharNextA(x);
    628           if (x!=str) strcpy(str,x);
    629           x=str+strlen(str)-1;
    630           while (*x==' ') x = CharPrevA(str, x);
    631           if (*x==' ') *x='\0';
    632         }
    633 }
    634 
    635 /*************************************************************************
    636  * PathRemoveBlanksW [SHLWAPI.@]
    637  */
    638 void WINAPI PathRemoveBlanksW(LPWSTR str)
    639 {
    640         LPWSTR x = str;
    641 
    642         TRACE("%s\n",debugstr_w(str));
    643 
    644         if(str)
    645         {
    646           while (*x==' ') x = CharNextW(x);
    647           if (x!=str) strcpyW(str,x);
    648           x=str+strlenW(str)-1;
    649           while (*x==' ') x = CharPrevW(str, x);
    650           if (*x==' ') *x='\0';
    651         }
    652 }
    653 
    654 /*************************************************************************
    655  * PathQuoteSpacesA [SHLWAPI.@]
    656  *
    657  */
    658 LPSTR WINAPI PathQuoteSpacesA(LPSTR lpszPath)
    659 {
    660         TRACE("%s\n",lpszPath);
    661 
    662         if(StrChrA(lpszPath,' '))
    663         {
    664           int len = strlen(lpszPath);
    665           RtlMoveMemory(lpszPath+1, lpszPath, len);
    666           *(lpszPath++) = '"';
    667           lpszPath += len;
    668           *(lpszPath++) = '"';
    669           *(lpszPath) = '\0';
    670           return --lpszPath;
    671         }
    672         return 0;
    673 }
    674 
    675 /*************************************************************************
    676  * PathQuoteSpacesW [SHLWAPI.@]
    677  */
    678 LPWSTR WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
    679 {
    680         TRACE("%s\n",debugstr_w(lpszPath));
    681 
    682         if(StrChrW(lpszPath,' '))
    683         {
    684           int len = strlenW(lpszPath);
    685           RtlMoveMemory(lpszPath+1, lpszPath, len*sizeof(WCHAR));
    686           *(lpszPath++) = '"';
    687           lpszPath += len;
    688           *(lpszPath++) = '"';
    689           *(lpszPath) = '\0';
    690           return --lpszPath;
    691         }
    692         return 0;
    693 }
    694 
    695 /*************************************************************************
    696  * PathUnquoteSpacesA [SHLWAPI.@]
    697  *
    698  * NOTES
    699  *     unquote string (remove ")
    700  */
    701 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
    702 {
    703         DWORD len = strlen(str);
    704 
    705         TRACE("%s\n",str);
    706 
    707         if (*str!='"')
    708           return;
    709         if (str[len-1]!='"')
    710           return;
    711         str[len-1]='\0';
    712         strcpy(str,str+1);
    713         return;
    714 }
    715 
    716 /*************************************************************************
    717  * PathUnquoteSpacesW [SHLWAPI.@]
    718  */
    719 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
    720 {
    721         DWORD len = strlenW(str);
    722 
    723         TRACE("%s\n",debugstr_w(str));
    724 
    725         if (*str!='"')
    726           return;
    727         if (str[len-1]!='"')
    728           return;
    729         str[len-1]='\0';
    730         strcpyW(str,str+1);
    731         return;
    732 }
    733 
    734 /*************************************************************************
    735  * PathParseIconLocationA       [SHLWAPI.@]
    736  */
    737 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
    738 {
    739         LPSTR lpstrComma = strchr(lpszPath, ',');
    740         int ret = 0;
    741        
    742         TRACE("%s\n", debugstr_a(lpszPath));
    743 
    744         if (lpstrComma && lpstrComma[1])
    745         {
    746           lpstrComma[0]='\0';
    747           ret = atoi(&lpstrComma[1]);
    748         }
    749        
    750         PathUnquoteSpacesA(lpszPath);
    751         return ret;
    752 }
    753 
    754 /*************************************************************************
    755  * PathParseIconLocationW       [SHLWAPI.@]
    756  */
    757 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
    758 {
    759         LPWSTR lpstrComma = strchrW(lpszPath, ',');
    760         int ret = 0;
    761        
    762         TRACE("%s\n", debugstr_w(lpszPath));
    763 
    764         if (lpstrComma && lpstrComma[1])
    765         {
    766           lpstrComma[0]='\0';
    767           ret = _wtoi(&lpstrComma[1]);
    768         }
    769         PathUnquoteSpacesW(lpszPath);
    770         return ret;
    771 }
    772 
    773 /*
    774         ########## cleaning and resolving paths ##########
    775  */
    776 
    777 /*************************************************************************
    778  * PathFindOnPathA      [SHLWAPI.@]
    779  */
    780 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR *sOtherDirs)
    781 {
    782         FIXME("%s %p\n",sFile, sOtherDirs);
    783         return FALSE;
    784 }
    785 
    786 /*************************************************************************
    787  * PathFindOnPathW      [SHLWAPI.@]
    788  */
    789 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR *sOtherDirs)
    790 {
    791         FIXME("%s %p\n",debugstr_w(sFile), sOtherDirs);
    792         return FALSE;
    793 }
    794 
    795 /*************************************************************************
    796  *      PathCompactPathExA   [SHLWAPI.@]
    797  */
    798 BOOL WINAPI PathCompactPathExA(
    799         LPSTR pszOut,
    800         LPCSTR pszSrc,
    801         UINT cchMax,
    802         DWORD dwFlags)
    803 {
    804         FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, pszSrc, cchMax, dwFlags);
    805         return FALSE;
    806 }
    807 
    808 /*************************************************************************
    809  *      PathCompactPathExW   [SHLWAPI.@]
    810  */
    811 BOOL WINAPI PathCompactPathExW(
    812         LPWSTR pszOut,
    813         LPCWSTR pszSrc,
    814         UINT cchMax,
    815         DWORD dwFlags)
    816 {
    817         FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, debugstr_w(pszSrc), cchMax, dwFlags);
    818         return FALSE;
    819 }
    820 
    821 /*
    822         ########## Path Testing ##########
    823 */
    824 
    825 /*************************************************************************
    826  * PathIsUNCA           [SHLWAPI.@]
    827  *
    828  * NOTES
    829  *     PathIsUNC(char*path);
    830  */
    831 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
    832 {
    833         TRACE("%s\n",lpszPath);
    834 
    835         return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
    836 }
    837 
    838 /*************************************************************************
    839  * PathIsUNCW           [SHLWAPI.@]
    840  */
    841 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
    842 {
    843         TRACE("%s\n",debugstr_w(lpszPath));
    844 
    845         return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
    846 }
    847 
    848 /*************************************************************************
    849  *  PathIsRelativeA     [SHLWAPI.@]
    850  */
    851 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
    852 {
    853         TRACE("lpszPath=%s\n",lpszPath);
    854 
    855         return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
    856 }
    857 
    858 /*************************************************************************
    859  *  PathIsRelativeW     [SHLWAPI.@]
    860  */
    861 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
    862 {
    863         TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
    864 
    865         return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
    866 }
    867 
    868 /*************************************************************************
    869  * PathIsRootA          [SHLWAPI.@]
    870  *
    871  * notes
    872  *  TRUE if the path points to a root directory
    873  */
    874 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
    875 {
    876         TRACE("%s\n",lpszPath);
    877 
    878         /* X:\ */
    879         if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
    880           return TRUE;
    881 
    882         /* "\" */
    883         if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
    884           return TRUE;
    885 
    886         /* UNC "\\<computer>\<share>" */
    887         if (lpszPath[0]=='\\' && lpszPath[1]=='\\')             
    888         {
    889           int foundbackslash = 0;
    890           lpszPath += 2;
    891           while (*lpszPath)
    892           {
    893             if (*lpszPath=='\\') foundbackslash++;
    894             lpszPath = CharNextA(lpszPath);
    895           }
    896           if (foundbackslash <= 1)
    897             return TRUE;
    898         }
    899         return FALSE;
    900 }
    901 
    902 /*************************************************************************
    903  * PathIsRootW          [SHLWAPI.@]
    904  */
    905 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
    906 {
    907         TRACE("%s\n",debugstr_w(lpszPath));
    908 
    909         /* X:\ */
    910         if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
    911           return TRUE;
    912 
    913         /* "\" */
    914         if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
    915           return TRUE;
    916 
    917         /* UNC "\\<computer>\<share>" */
    918         if (lpszPath[0]=='\\' && lpszPath[1]=='\\')             
    919         {
    920           int foundbackslash = 0;
    921           lpszPath += 2;
    922           while (*lpszPath)
    923           {
    924             if (*lpszPath=='\\') foundbackslash++;
    925             lpszPath = CharNextW(lpszPath);
    926           }
    927           if (foundbackslash <= 1)
    928             return TRUE;
    929         }
    930         return FALSE;
    931 
    932 }
    933 
    934 /*************************************************************************
    935  * PathIsDirectoryA     [SHLWAPI.@]
     1485 *  Although this function is prototyped as returning a BOOL, it returns
     1486 *  FILE_ATTRIBUTE_DIRECTORY for success. This means that code such as:
     1487 *
     1488 *  if (PathIsDirectoryA("c:\\windows\\") == TRUE)
     1489 *    ...
     1490 *
     1491 *  will always fail.
    9361492 */
    9371493BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
    9381494{
    939         DWORD dwAttr;
    940 
    941         TRACE("%s\n", debugstr_a(lpszPath));
    942 
    943         dwAttr = GetFileAttributesA(lpszPath);
    944         return  (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
     1495  DWORD dwAttr;
     1496
     1497  TRACE("(%s)\n", debugstr_a(lpszPath));
     1498
     1499  if (!lpszPath || PathIsUNCServerA(lpszPath))
     1500    return FALSE;
     1501
     1502 if (PathIsUNCServerShareA(lpszPath))
     1503 {
     1504   FIXME("UNC Server Share not yet supported - FAILING\n");
     1505   return FALSE;
     1506 }
     1507
     1508  if ((dwAttr = GetFileAttributesA(lpszPath)) == -1)
     1509    return FALSE;
     1510  return dwAttr & FILE_ATTRIBUTE_DIRECTORY;
    9451511}
    9461512
    9471513/*************************************************************************
    9481514 * PathIsDirectoryW     [SHLWAPI.@]
     1515 *
     1516 * See PathIsDirectoryA.
    9491517 */
    9501518BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
    9511519{
    952         DWORD dwAttr;
    953        
    954         TRACE("%s\n", debugstr_w(lpszPath));
    955 
    956         dwAttr = GetFileAttributesW(lpszPath);
    957         return  (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
     1520  DWORD dwAttr;
     1521
     1522  TRACE("(%s)\n", debugstr_w(lpszPath));
     1523
     1524  if (!lpszPath || PathIsUNCServerW(lpszPath))
     1525    return FALSE;
     1526
     1527 if (PathIsUNCServerShareW(lpszPath))
     1528 {
     1529   FIXME("UNC Server Share not yet supported - FAILING\n");
     1530   return FALSE;
     1531 }
     1532
     1533  if ((dwAttr = GetFileAttributesW(lpszPath)) == -1)
     1534    return FALSE;
     1535  return dwAttr & FILE_ATTRIBUTE_DIRECTORY;
    9581536}
    9591537
    9601538/*************************************************************************
    9611539 * PathFileExistsA      [SHLWAPI.@]
    962  *
    963  * NOTES
    964  *     file_exists(char *fn);
    965  */
    966 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
    967 {
    968         TRACE("%s\n",lpszPath);
    969         return  (GetFileAttributesA(lpszPath)!=-1);
     1540 *
     1541 * Determine if a file exists.
     1542 *
     1543 * PARAMS
     1544 *  lpszPath [I] Path to check
     1545 *
     1546 * RETURNS
     1547 *  TRUE  If the file exists and is readable
     1548 *  FALSE Otherwise
     1549 */
     1550BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
     1551{
     1552  UINT iPrevErrMode;
     1553  DWORD dwAttr;
     1554
     1555  TRACE("(%s)\n",debugstr_a(lpszPath));
     1556
     1557  if (!lpszPath)
     1558    return FALSE;
     1559
     1560  iPrevErrMode = SetErrorMode(1);
     1561  dwAttr = GetFileAttributesA(lpszPath);
     1562  SetErrorMode(iPrevErrMode);
     1563  return dwAttr == -1 ? FALSE : TRUE;
    9701564}
    9711565
    9721566/*************************************************************************
    9731567 * PathFileExistsW      [SHLWAPI.@]
    974  */
    975 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
    976 {
    977         TRACE("%s\n",debugstr_w(lpszPath));
    978         return  (GetFileAttributesW(lpszPath)!=-1);
     1568 *
     1569 * See PathFileExistsA
     1570 */
     1571BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
     1572{
     1573  UINT iPrevErrMode;
     1574  DWORD dwAttr;
     1575
     1576  TRACE("(%s)\n",debugstr_w(lpszPath));
     1577
     1578  if (!lpszPath)
     1579    return FALSE;
     1580
     1581  iPrevErrMode = SetErrorMode(1);
     1582  dwAttr = GetFileAttributesW(lpszPath);
     1583  SetErrorMode(iPrevErrMode);
     1584  return dwAttr == -1 ? FALSE : TRUE;
    9791585}
    9801586
    9811587/*************************************************************************
    9821588 * PathMatchSingleMaskA [internal]
    983  * 
     1589 *
    9841590 * NOTES
    9851591 *     internal (used by PathMatchSpec)
     
    9871593static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
    9881594{
    989         while (*name && *mask && *mask!=';') 
     1595        while (*name && *mask && *mask!=';')
    9901596        {
    991           if (*mask=='*') 
     1597          if (*mask=='*')
    9921598          {
    993             do 
     1599            do
    9941600            {
    9951601              if (PathMatchSingleMaskA(name,mask+1)) return 1;  /* try substrings */
     
    10011607          mask = CharNextA(mask);
    10021608        }
    1003         if (!*name) 
     1609        if (!*name)
    10041610        {
    10051611          while (*mask=='*') mask++;
     
    10141620static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
    10151621{
    1016         while (*name && *mask && *mask!=';') 
     1622        while (*name && *mask && *mask!=';')
    10171623        {
    1018           if (*mask=='*') 
     1624          if (*mask=='*')
    10191625          {
    1020             do 
     1626            do
    10211627            {
    10221628              if (PathMatchSingleMaskW(name,mask+1)) return 1;  /* try substrings */
     
    10281634          mask = CharNextW(mask);
    10291635        }
    1030         if (!*name) 
     1636        if (!*name)
    10311637        {
    10321638          while (*mask=='*') mask++;
     
    10351641        return 0;
    10361642}
     1643
    10371644/*************************************************************************
    10381645 * PathMatchSpecA       [SHLWAPI.@]
    1039  *
     1646 *
     1647 * Determine if a path matches one or more search masks.
     1648 *
     1649 * PARAMS
     1650 *  lpszPath [I] Path to check
     1651 *  lpszMask [I} Search mask(s)
     1652 *
     1653 * RETURNS
     1654 *  TRUE  If lpszPath is valid and is matched
     1655 *  FALSE Otherwise
     1656 *
    10401657 * NOTES
    1041  *     used from COMDLG32
    1042  */
    1043 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
     1658 *  Multiple search masks may be given if they are seperated by ";". The
     1659 *  pattern "*.*" is treated specially in that it matches all paths (for
     1660 *  backwards compatability with DOS).
     1661 */
     1662BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
    10441663{
    10451664        TRACE("%s %s\n",name,mask);
     
    10471666        if (!lstrcmpA( mask, "*.*" )) return 1;   /* we don't require a period */
    10481667
    1049         while (*mask) 
     1668        while (*mask)
    10501669        {
    10511670          if (PathMatchSingleMaskA(name,mask)) return 1;    /* helper function */
    10521671          while (*mask && *mask!=';') mask = CharNextA(mask);
    1053           if (*mask==';') 
     1672          if (*mask==';')
    10541673          {
    10551674            mask++;
     
    10621681/*************************************************************************
    10631682 * PathMatchSpecW       [SHLWAPI.@]
    1064  */
    1065 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
     1683 *
     1684 * See PathMatchSpecA.
     1685 */
     1686BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
    10661687{
    10671688    static const WCHAR stemp[] = { '*','.','*',0 };
     
    10701691        if (!lstrcmpW( mask, stemp )) return 1;   /* we don't require a period */
    10711692
    1072         while (*mask) 
     1693        while (*mask)
    10731694        {
    10741695          if (PathMatchSingleMaskW(name,mask)) return 1;    /* helper function */
    10751696          while (*mask && *mask!=';') mask = CharNextW(mask);
    1076           if (*mask==';') 
     1697          if (*mask==';')
    10771698          {
    10781699            mask++;
     
    10861707 * PathIsSameRootA      [SHLWAPI.@]
    10871708 *
    1088  * FIXME
    1089  *  what to do with "\path" ??
     1709 * Determine if two paths share the same root.
     1710 *
     1711 * PARAMS
     1712 *  lpszPath1 [I] Source path
     1713 *  lpszPath2 [I] Path to compare with
     1714 *
     1715 * RETURNS
     1716 *  TRUE  If both paths are valid and share the same root.
     1717 *  FALSE If either path is invalid or the paths do not share the same root.
    10901718 */
    10911719BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
    10921720{
    1093         TRACE("%s %s\n", lpszPath1, lpszPath2);
    1094        
    1095         if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
    1096 
    1097         /* usual path */
    1098         if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
    1099              lpszPath1[1]==':' && lpszPath2[1]==':' &&
    1100              lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
    1101           return TRUE;
    1102 
    1103         /* UNC */
    1104         if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
    1105             lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
    1106         {
    1107           int pos=2, bsfound=0;
    1108           while (lpszPath1[pos] && lpszPath2[pos] &&
    1109                 (lpszPath1[pos] == lpszPath2[pos]))
    1110           {
    1111             if (lpszPath1[pos]=='\\') bsfound++;
    1112             if (bsfound == 2) return TRUE;
    1113             pos++; /* FIXME: use CharNext*/
    1114           }
    1115           return (lpszPath1[pos] == lpszPath2[pos]);
    1116         }
    1117         return FALSE;
     1721  LPCSTR lpszStart;
     1722  DWORD dwLen;
     1723
     1724  TRACE("(%s,%s)\n", debugstr_a(lpszPath1), debugstr_a(lpszPath2));
     1725
     1726  if (!lpszPath1 || !lpszPath2 || !(lpszStart = PathSkipRootA(lpszPath1)))
     1727    return FALSE;
     1728
     1729  dwLen = PathCommonPrefixA(lpszPath1, lpszPath2, NULL) + 1;
     1730  if (lpszStart - lpszPath1 > dwLen)
     1731    return FALSE; /* Paths not common up to length of the root */
     1732  return TRUE;
    11181733}
    11191734
    11201735/*************************************************************************
    11211736 * PathIsSameRootW      [SHLWAPI.@]
     1737 *
     1738 * See PathIsSameRootA.
    11221739 */
    11231740BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
    11241741{
    1125         TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
    1126        
    1127         if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
    1128 
    1129         /* usual path */
    1130         if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
    1131              lpszPath1[1]==':' && lpszPath2[1]==':' &&
    1132              lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
    1133           return TRUE;
    1134 
    1135         /* UNC */
    1136         if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
    1137             lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
    1138         {
    1139           int pos=2, bsfound=0;
    1140           while (lpszPath1[pos] && lpszPath2[pos] &&
    1141                 (lpszPath1[pos] == lpszPath2[pos]))
    1142           {
    1143             if (lpszPath1[pos]=='\\') bsfound++;
    1144             if (bsfound == 2) return TRUE;
    1145             pos++;/* FIXME: use CharNext*/
    1146           }
    1147           return (lpszPath1[pos] == lpszPath2[pos]);
    1148         }
    1149         return FALSE;
    1150 }
    1151 
    1152 /*************************************************************************
    1153  * PathIsURLA (SHLWAPI.@)
     1742  LPCWSTR lpszStart;
     1743  DWORD dwLen;
     1744
     1745  TRACE("(%s,%s)\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
     1746
     1747  if (!lpszPath1 || !lpszPath2 || !(lpszStart = PathSkipRootW(lpszPath1)))
     1748    return FALSE;
     1749
     1750  dwLen = PathCommonPrefixW(lpszPath1, lpszPath2, NULL) + 1;
     1751  if (lpszStart - lpszPath1 > dwLen)
     1752    return FALSE; /* Paths not common up to length of the root */
     1753  return TRUE;
     1754}
     1755
     1756/*************************************************************************
     1757 * PathIsURLA   [SHLWAPI.@]
     1758 *
     1759 * Check if the given path is a URL.
     1760 *
     1761 * PARAMS
     1762 *  lpszPath [I] Path to check.
     1763 *
     1764 * RETURNS
     1765 *  TRUE  if lpszPath is a URL.
     1766 *  FALSE if lpszPath is NULL or not a URL.
    11541767 */
    11551768BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
     
    11631776    base.size = 24;
    11641777    res1 = SHLWAPI_1(lpstrPath, &base);
    1165 
    1166 #ifdef __WIN32OS2__ 
    1167     // PH 2002-02-26 Fixes crash on Flask->About
    1168     // ShellExecute("..\doc\readme.html")
    1169     if (S_OK != res1)
    1170       return FALSE;
    1171 #endif
    1172  
    11731778    return (base.fcncde) ? TRUE : FALSE;
    1174 } 
    1175 
    1176 /*************************************************************************
    1177  * PathIsURLW (SHLWAPI.@)
     1779}
     1780
     1781/*************************************************************************
     1782 * PathIsURLW   [SHLWAPI.@]
    11781783 */
    11791784BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
     
    11871792    base.size = 24;
    11881793    res1 = SHLWAPI_2(lpstrPath, &base);
    1189  
    1190 #ifdef __WIN32OS2__ 
    1191     // PH 2002-02-26 Fixes crash on Flask->About
    1192     // ShellExecute("..\doc\readme.html")
    1193     if (S_OK != res1)
     1794    return (base.fcncde) ? TRUE : FALSE;
     1795}
     1796
     1797/*************************************************************************
     1798 * PathIsContentTypeA   [SHLWAPI.@]
     1799 *
     1800 * Determine if a file is of a registered content type.
     1801 *
     1802 * PARAMS
     1803 *  lpszPath [I] file to chack
     1804 *
     1805 * RETURNS
     1806 *  TRUE  If lpszPath is a registered content type
     1807 *  FALSE Otherwise.
     1808 */
     1809BOOL WINAPI PathIsContentTypeA(LPCSTR lpszPath, LPCSTR lpszContentType)
     1810{
     1811  LPCSTR szExt;
     1812  DWORD dwDummy;
     1813  char szBuff[MAX_PATH];
     1814
     1815  TRACE("(%s,%s)\n", debugstr_a(lpszPath), debugstr_a(lpszContentType));
     1816
     1817  if (lpszPath && (szExt = PathFindExtensionA(lpszPath)) && *szExt &&
     1818      !SHGetValueA(HKEY_CLASSES_ROOT, szExt, "Content Type",
     1819                   REG_NONE, szBuff, &dwDummy) &&
     1820      !strcasecmp(lpszContentType, szBuff))
     1821  {
     1822    return TRUE;
     1823  }
     1824  return FALSE;
     1825}
     1826
     1827/*************************************************************************
     1828 * PathIsContentTypeW   [SHLWAPI.@]
     1829 *
     1830 * See PathIsContentTypeA.
     1831 */
     1832BOOL WINAPI PathIsContentTypeW(LPCWSTR lpszPath, LPCWSTR lpszContentType)
     1833{
     1834  static const WCHAR szContentType[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0' };
     1835  LPCWSTR szExt;
     1836  DWORD dwDummy;
     1837  WCHAR szBuff[MAX_PATH];
     1838
     1839  TRACE("(%s,%s)\n", debugstr_w(lpszPath), debugstr_w(lpszContentType));
     1840
     1841  if (lpszPath && (szExt = PathFindExtensionW(lpszPath)) && *szExt &&
     1842      !SHGetValueW(HKEY_CLASSES_ROOT, szExt, szContentType,
     1843                   REG_NONE, szBuff, &dwDummy) &&
     1844      !strcmpiW(lpszContentType, szBuff))
     1845  {
     1846    return TRUE;
     1847  }
     1848  return FALSE;
     1849}
     1850
     1851/*************************************************************************
     1852 * PathIsFileSpecA   [SHLWAPI.@]
     1853 *
     1854 * Determine if a path is a file specification.
     1855 *
     1856 * PARAMS
     1857 *  lpszPath [I] Path to chack
     1858 *
     1859 * RETURNS
     1860 *  TRUE  If lpszPath is a file spec (contains no directories).
     1861 *  FALSE Otherwise.
     1862 */
     1863BOOL WINAPI PathIsFileSpecA(LPCSTR lpszPath)
     1864{
     1865  TRACE("(%s)\n", debugstr_a(lpszPath));
     1866
     1867  if (!lpszPath)
     1868    return FALSE;
     1869
     1870  while (*lpszPath)
     1871  {
     1872    if (*lpszPath == '\\' || *lpszPath == ':')
    11941873      return FALSE;
    1195 #endif
    1196  
    1197     return (base.fcncde) ? TRUE : FALSE;
    1198 
    1199 
    1200 
    1201 /*************************************************************************
    1202  *      PathIsContentTypeA   [SHLWAPI.@]
    1203  */
    1204 BOOL WINAPI PathIsContentTypeA(LPCSTR pszPath, LPCSTR pszContentType)
    1205 {
    1206         FIXME("%s %s\n", pszPath, pszContentType);
    1207         return FALSE;
    1208 }
    1209 
    1210 /*************************************************************************
    1211  *      PathIsContentTypeW   [SHLWAPI.@]
    1212  */
    1213 BOOL WINAPI PathIsContentTypeW(LPCWSTR pszPath, LPCWSTR pszContentType)
    1214 {
    1215         FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszContentType));
    1216         return FALSE;
    1217 }
    1218 
    1219 /*************************************************************************
    1220  *      PathIsFileSpecA   [SHLWAPI.@]
    1221  */
    1222 BOOL WINAPI PathIsFileSpecA(LPCSTR pszPath)
    1223 {
    1224         FIXME("%s\n", pszPath);
    1225         return FALSE;
    1226 }
    1227 
    1228 /*************************************************************************
    1229  *      PathIsFileSpecW   [SHLWAPI.@]
    1230  */
    1231 BOOL WINAPI PathIsFileSpecW(LPCWSTR pszPath)
    1232 {
    1233         FIXME("%s\n", debugstr_w(pszPath));
    1234         return FALSE;
    1235 }
    1236 
    1237 /*************************************************************************
    1238  *      PathIsPrefixA   [SHLWAPI.@]
    1239  */
    1240 BOOL WINAPI PathIsPrefixA(LPCSTR pszPrefix, LPCSTR pszPath)
    1241 {
    1242         FIXME("%s %s\n", pszPrefix, pszPath);
    1243         return FALSE;
    1244 }
    1245 
    1246 /*************************************************************************
    1247  *      PathIsPrefixW   [SHLWAPI.@]
    1248  */
    1249 BOOL WINAPI PathIsPrefixW(LPCWSTR pszPrefix, LPCWSTR pszPath)
    1250 {
    1251         FIXME("%s %s\n", debugstr_w(pszPrefix), debugstr_w(pszPath));
    1252         return FALSE;
    1253 }
    1254 
    1255 /*************************************************************************
    1256  *      PathIsSystemFolderA   [SHLWAPI.@]
    1257  */
    1258 BOOL WINAPI PathIsSystemFolderA(LPCSTR pszPath, DWORD dwAttrb)
    1259 {
    1260         FIXME("%s 0x%08lx\n", pszPath, dwAttrb);
    1261         return FALSE;
    1262 }
    1263 
    1264 /*************************************************************************
    1265  *      PathIsSystemFolderW   [SHLWAPI.@]
    1266  */
    1267 BOOL WINAPI PathIsSystemFolderW(LPCWSTR pszPath, DWORD dwAttrb)
    1268 {
    1269         FIXME("%s 0x%08lx\n", debugstr_w(pszPath), dwAttrb);
    1270         return FALSE;
    1271 }
    1272 
    1273 /*************************************************************************
    1274  *      PathIsUNCServerA   [SHLWAPI.@]
    1275  */
    1276 BOOL WINAPI PathIsUNCServerA(
    1277         LPCSTR lpszPath)
    1278 {
    1279         TRACE("%s\n", debugstr_a(lpszPath));
    1280         if (lpszPath[0]=='\\' && lpszPath[1]=='\\')             
    1281         {
    1282           int foundbackslash = 0;
    1283           lpszPath += 2;
    1284           while (*lpszPath)
    1285           {
    1286             if (*lpszPath=='\\') foundbackslash++;
    1287             lpszPath = CharNextA(lpszPath);
    1288           }
    1289           if (foundbackslash == 0)
    1290             return TRUE;
    1291         }
    1292         return FALSE;
    1293 }
    1294 
    1295 /*************************************************************************
    1296  *      PathIsUNCServerW   [SHLWAPI.@]
    1297  */
    1298 BOOL WINAPI PathIsUNCServerW(
    1299         LPCWSTR lpszPath)
    1300 {
    1301         TRACE("%s\n", debugstr_w(lpszPath));
    1302         if (lpszPath[0]=='\\' && lpszPath[1]=='\\')             
    1303         {
    1304           int foundbackslash = 0;
    1305           lpszPath += 2;
    1306           while (*lpszPath)
    1307           {
    1308             if (*lpszPath=='\\') foundbackslash++;
    1309             lpszPath = CharNextW(lpszPath);
    1310           }
    1311           if (foundbackslash == 0)
    1312             return TRUE;
    1313         }
    1314         return FALSE;
    1315 }
    1316 
    1317 /*************************************************************************
    1318  *      PathIsUNCServerShareA   [SHLWAPI.@]
    1319  */
    1320 BOOL WINAPI PathIsUNCServerShareA(
    1321         LPCSTR lpszPath)
    1322 {
    1323         TRACE("%s\n", debugstr_a(lpszPath));
    1324         if (lpszPath[0]=='\\' && lpszPath[1]=='\\')             
    1325         {
    1326           int foundbackslash = 0;
    1327           lpszPath += 2;
    1328           while (*lpszPath)
    1329           {
    1330             if (*lpszPath=='\\') foundbackslash++;
    1331             lpszPath = CharNextA(lpszPath);
    1332           }
    1333           if (foundbackslash == 1)
    1334             return TRUE;
    1335         }
    1336         return FALSE;
    1337 }
    1338 
    1339 /*************************************************************************
    1340  *      PathIsUNCServerShareW   [SHLWAPI.@]
    1341  */
    1342 BOOL WINAPI PathIsUNCServerShareW(
    1343         LPCWSTR lpszPath)
    1344 {
    1345         TRACE("%s\n", debugstr_w(lpszPath));
    1346         if (lpszPath[0]=='\\' && lpszPath[1]=='\\')             
    1347         {
    1348           int foundbackslash = 0;
    1349           lpszPath += 2;
    1350           while (*lpszPath)
    1351           {
    1352             if (*lpszPath=='\\') foundbackslash++;
    1353             lpszPath = CharNextW(lpszPath);
    1354           }
    1355           if (foundbackslash == 1)
    1356             return TRUE;
    1357         }
    1358         return FALSE;
     1874    lpszPath = CharNextA(lpszPath);
     1875  }
     1876  return TRUE;
     1877}
     1878
     1879/*************************************************************************
     1880 * PathIsFileSpecW   [SHLWAPI.@]
     1881 *
     1882 * See PathIsFileSpecA.
     1883 */
     1884BOOL WINAPI PathIsFileSpecW(LPCWSTR lpszPath)
     1885{
     1886  TRACE("(%s)\n", debugstr_w(lpszPath));
     1887
     1888  if (!lpszPath)
     1889    return FALSE;
     1890
     1891  while (*lpszPath)
     1892  {
     1893    if (*lpszPath == '\\' || *lpszPath == ':')
     1894      return FALSE;
     1895    lpszPath = CharNextW(lpszPath);
     1896  }
     1897  return TRUE;
     1898}
     1899
     1900/*************************************************************************
     1901 * PathIsPrefixA   [SHLWAPI.@]
     1902 *
     1903 * Determine if a path is a prefix of another.
     1904 *
     1905 * PARAMS
     1906 *  lpszPrefix [I] Prefix
     1907 *  lpszPath   [i] Path to check
     1908 *
     1909 * RETURNS
     1910 *  TRUE  If lpszPath has lpszPrefix as its prefix
     1911 *  FALSE If either path is NULL or lpszPrefix is not a prefix
     1912 */
     1913BOOL WINAPI PathIsPrefixA (LPCSTR lpszPrefix, LPCSTR lpszPath)
     1914{
     1915  TRACE("(%s,%s)\n", debugstr_a(lpszPrefix), debugstr_a(lpszPath));
     1916
     1917  if (lpszPrefix && lpszPath &&
     1918      PathCommonPrefixA(lpszPath, lpszPrefix, NULL) == strlen(lpszPrefix))
     1919    return TRUE;
     1920  return FALSE;
     1921}
     1922
     1923/*************************************************************************
     1924 *  PathIsPrefixW   [SHLWAPI.@]
     1925 *
     1926 *  See PathIsPrefixA.
     1927 */
     1928BOOL WINAPI PathIsPrefixW(LPCWSTR lpszPrefix, LPCWSTR lpszPath)
     1929{
     1930  TRACE("(%s,%s)\n", debugstr_w(lpszPrefix), debugstr_w(lpszPath));
     1931
     1932  if (lpszPrefix && lpszPath &&
     1933      PathCommonPrefixW(lpszPath, lpszPrefix, NULL) == strlenW(lpszPrefix))
     1934    return TRUE;
     1935  return FALSE;
     1936}
     1937
     1938/*************************************************************************
     1939 * PathIsSystemFolderA   [SHLWAPI.@]
     1940 *
     1941 * Determine if a path or file attributes are a system folder.
     1942 *
     1943 * PARAMS
     1944 *  lpszPath  [I] Path to check.
     1945 *  dwAttrib  [I] Attributes to check, if lpszPath is NULL.
     1946 *
     1947 * RETURNS
     1948 *  TRUE   If lpszPath or dwAttrib are a system folder.
     1949 *  FALSE  If GetFileAttributesA fails or neither parameter is a system folder.
     1950 */
     1951BOOL WINAPI PathIsSystemFolderA(LPCSTR lpszPath, DWORD dwAttrib)
     1952{
     1953  TRACE("(%s,0x%08lx)\n", debugstr_a(lpszPath), dwAttrib);
     1954
     1955  if (lpszPath && *lpszPath)
     1956    dwAttrib = GetFileAttributesA(lpszPath);
     1957
     1958  if (dwAttrib == -1 || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
     1959      !(dwAttrib & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)))
     1960    return FALSE;
     1961  return TRUE;
     1962}
     1963
     1964/*************************************************************************
     1965 * PathIsSystemFolderW   [SHLWAPI.@]
     1966 *
     1967 * See PathIsSystemFolderA.
     1968 */
     1969BOOL WINAPI PathIsSystemFolderW(LPCWSTR lpszPath, DWORD dwAttrib)
     1970{
     1971  TRACE("(%s,0x%08lx)\n", debugstr_w(lpszPath), dwAttrib);
     1972
     1973  if (lpszPath && *lpszPath)
     1974    dwAttrib = GetFileAttributesW(lpszPath);
     1975
     1976  if (dwAttrib == -1 || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
     1977      !(dwAttrib & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)))
     1978    return FALSE;
     1979  return TRUE;
     1980}
     1981
     1982/*************************************************************************
     1983 * PathIsUNCA           [SHLWAPI.@]
     1984 *
     1985 * Determine if a path is in UNC format.
     1986 *
     1987 * PARAMS
     1988 *  lpszPath [I] Path to check
     1989 *
     1990 * RETURNS
     1991 *  TRUE: The path is UNC.
     1992 *  FALSE: The path is not UNC or is NULL.
     1993 */
     1994BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
     1995{
     1996  TRACE("(%s)\n",debugstr_a(lpszPath));
     1997
     1998  if (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'))
     1999    return TRUE;
     2000  return FALSE;
     2001}
     2002
     2003/*************************************************************************
     2004 * PathIsUNCW           [SHLWAPI.@]
     2005 *
     2006 * See PathIsUNCA.
     2007 */
     2008BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
     2009{
     2010  TRACE("(%s)\n",debugstr_w(lpszPath));
     2011
     2012  if (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'))
     2013    return TRUE;
     2014  return FALSE;
     2015}
     2016
     2017/*************************************************************************
     2018 * PathIsUNCServerA   [SHLWAPI.@]
     2019 *
     2020 * Determine if a path is a UNC server name ("\\SHARENAME").
     2021 *
     2022 * PARAMS
     2023 *  lpszPath  [I] Path to check.
     2024 *
     2025 * RETURNS
     2026 *  TRUE   If lpszPath is a valid UNC server name.
     2027 *  FALSE  Otherwise.
     2028 *
     2029 * NOTES
     2030 *  This routine is bug compatible with Win32: Server names with a
     2031 *  trailing backslash (e.g. "\\FOO\"), return FALSE incorrectly.
     2032 *  Fixing this bug may break other shlwapi functions!
     2033 */
     2034BOOL WINAPI PathIsUNCServerA(LPCSTR lpszPath)
     2035{
     2036  TRACE("(%s)\n", debugstr_a(lpszPath));
     2037
     2038  if (lpszPath && *lpszPath++ == '\\' && *lpszPath++ == '\\')
     2039  {
     2040    while (*lpszPath)
     2041    {
     2042      if (*lpszPath == '\\')
     2043        return FALSE;
     2044      lpszPath = CharNextA(lpszPath);
     2045    }
     2046    return TRUE;
     2047  }
     2048  return FALSE;
     2049}
     2050
     2051/*************************************************************************
     2052 * PathIsUNCServerW   [SHLWAPI.@]
     2053 *
     2054 * See PathIsUNCServerA.
     2055 */
     2056BOOL WINAPI PathIsUNCServerW(LPCWSTR lpszPath)
     2057{
     2058  TRACE("(%s)\n", debugstr_w(lpszPath));
     2059
     2060  if (lpszPath && *lpszPath++ == '\\' && *lpszPath++ == '\\')
     2061  {
     2062    while (*lpszPath)
     2063    {
     2064      if (*lpszPath == '\\')
     2065        return FALSE;
     2066      lpszPath = CharNextW(lpszPath);
     2067    }
     2068    return TRUE;
     2069  }
     2070  return FALSE;
     2071}
     2072
     2073/*************************************************************************
     2074 * PathIsUNCServerShareA   [SHLWAPI.@]
     2075 *
     2076 * Determine if a path is a UNC server share ("\\SHARENAME\SHARE").
     2077 *
     2078 * PARAMS
     2079 *  lpszPath  [I] Path to check.
     2080 *
     2081 * RETURNS
     2082 *  TRUE   If lpszPath is a valid UNC server share.
     2083 *  FALSE  Otherwise.
     2084 *
     2085 * NOTES
     2086 *  This routine is bug compatible with Win32: Server shares with a
     2087 *  trailing backslash (e.g. "\\FOO\BAR\"), return FALSE incorrectly.
     2088 *  Fixing this bug may break other shlwapi functions!
     2089 */
     2090BOOL WINAPI PathIsUNCServerShareA(LPCSTR lpszPath)
     2091{
     2092  TRACE("(%s)\n", debugstr_a(lpszPath));
     2093
     2094  if (lpszPath && *lpszPath++ == '\\' && *lpszPath++ == '\\')
     2095  {
     2096    BOOL bSeenSlash = FALSE;
     2097    while (*lpszPath)
     2098    {
     2099      if (*lpszPath == '\\')
     2100      {
     2101        if (bSeenSlash)
     2102          return FALSE;
     2103        bSeenSlash = TRUE;
     2104      }
     2105      lpszPath = CharNextA(lpszPath);
     2106    }
     2107    return bSeenSlash;
     2108  }
     2109  return FALSE;
     2110}
     2111
     2112/*************************************************************************
     2113 * PathIsUNCServerShareW   [SHLWAPI.@]
     2114 *
     2115 * See PathIsUNCServerShareA.
     2116 */
     2117BOOL WINAPI PathIsUNCServerShareW(LPCWSTR lpszPath)
     2118{
     2119  TRACE("(%s)\n", debugstr_w(lpszPath));
     2120
     2121  if (lpszPath && *lpszPath++ == '\\' && *lpszPath++ == '\\')
     2122  {
     2123    BOOL bSeenSlash = FALSE;
     2124    while (*lpszPath)
     2125    {
     2126      if (*lpszPath == '\\')
     2127      {
     2128        if (bSeenSlash)
     2129          return FALSE;
     2130        bSeenSlash = TRUE;
     2131      }
     2132      lpszPath = CharNextW(lpszPath);
     2133    }
     2134    return bSeenSlash;
     2135  }
     2136  return FALSE;
    13592137}
    13602138
     
    13622140 * PathCanonicalizeA   [SHLWAPI.@]
    13632141 *
    1364  *  FIXME
    1365  *   returnvalue, use CharNext
    1366  */
    1367  
    1368 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
    1369 {
    1370         int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
    1371         BOOL bModifyed = FALSE;
    1372 
    1373         TRACE("%p %s\n", pszBuf, pszPath);
    1374        
    1375         pszBuf[OffsetDst]='\0';
    1376 
    1377         /* keep the root of the path */
    1378         if( LenSrc && (pszPath[OffsetSrc]=='\\'))
    1379         {
    1380           pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
    1381         }
    1382         else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
    1383         {
    1384           pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
    1385           pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
    1386           if (LenSrc && (pszPath[OffsetSrc] == '\\'))
    1387           {
    1388             pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
    1389             if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
    1390             {
    1391               /* C:\. */
    1392               OffsetSrc++; LenSrc--; bModifyed = TRUE;
    1393             }
    1394             else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
    1395             {
    1396               /* C:\.. */
    1397               OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
    1398             }
     2142 * Convert a path to its canonical form.
     2143 *
     2144 * PARAMS
     2145 *  lpszBuf  [O] Output path
     2146 *  lpszPath [I] Path to cnonicalize
     2147 *
     2148 * RETURNS
     2149 *  Success: TRUE.  lpszBuf contains the output path
     2150 *  Failure: FALSE, If input path is invalid. lpszBuf is undefined
     2151 */
     2152BOOL WINAPI PathCanonicalizeA(LPSTR lpszBuf, LPCSTR lpszPath)
     2153{
     2154  BOOL bRet = FALSE;
     2155
     2156  TRACE("(%p,%s)\n", lpszBuf, debugstr_a(lpszPath));
     2157
     2158  if (lpszBuf)
     2159    *lpszBuf = '\0';
     2160
     2161  if (!lpszBuf || !lpszPath)
     2162    SetLastError(ERROR_INVALID_PARAMETER);
     2163  else
     2164  {
     2165    WCHAR szPath[MAX_PATH];
     2166    WCHAR szBuff[MAX_PATH];
     2167    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
     2168    bRet = PathCanonicalizeW(szBuff, szPath);
     2169    WideCharToMultiByte(0,0,szBuff,-1,lpszBuf,MAX_PATH,0,0);
     2170  }
     2171  return bRet;
     2172}
     2173
     2174
     2175/*************************************************************************
     2176 * PathCanonicalizeW   [SHLWAPI.@]
     2177 *
     2178 * See PathCanonicalizeA.
     2179 */
     2180BOOL WINAPI PathCanonicalizeW(LPWSTR lpszBuf, LPCWSTR lpszPath)
     2181{
     2182  LPWSTR lpszDst = lpszBuf;
     2183  LPCWSTR lpszSrc = lpszPath;
     2184
     2185  TRACE("(%p,%s)\n", lpszBuf, debugstr_w(lpszPath));
     2186
     2187  if (lpszBuf)
     2188    *lpszDst = '\0';
     2189
     2190  if (!lpszBuf || !lpszPath)
     2191  {
     2192    SetLastError(ERROR_INVALID_PARAMETER);
     2193    return FALSE;
     2194  }
     2195
     2196  if (!*lpszPath)
     2197  {
     2198    *lpszBuf++ = '\\';
     2199    *lpszBuf = '\0';
     2200    return TRUE;
     2201  }
     2202
     2203  /* Copy path root */
     2204  if (*lpszSrc == '\\')
     2205  {
     2206    *lpszDst++ = *lpszSrc++;
     2207  }
     2208  else if (*lpszSrc && lpszSrc[1] == ':')
     2209  {
     2210    /* X:\ */
     2211    *lpszDst++ = *lpszSrc++;
     2212    *lpszDst++ = *lpszSrc++;
     2213    if (*lpszSrc == '\\')
     2214      *lpszDst++ = *lpszSrc++;
     2215  }
     2216
     2217  /* Canonicalize the rest of the path */
     2218  while (*lpszSrc)
     2219  {
     2220    if (*lpszSrc == '.')
     2221    {
     2222      if (lpszSrc[1] == '\\' && (lpszSrc == lpszPath || lpszSrc[-1] == '\\' || lpszSrc[-1] == ':'))
     2223      {
     2224        lpszSrc += 2; /* Skip .\ */
     2225      }
     2226      else if (lpszSrc[1] == '.' && (lpszDst == lpszBuf || lpszDst[-1] == '\\'))
     2227      {
     2228        /* \.. backs up a directory, over the root if it has no \ following X:.
     2229         * .. is ignored if it would remove a UNC server name or inital \\
     2230         */
     2231        if (lpszDst != lpszBuf)
     2232        {
     2233          *lpszDst = '\0'; /* Allow PathIsUNCServerShareA test on lpszBuf */
     2234          if (lpszDst > lpszBuf+1 && lpszDst[-1] == '\\' &&
     2235             (lpszDst[-2] != '\\' || lpszDst > lpszBuf+2))
     2236          {
     2237            if (lpszDst[-2] == ':' && (lpszDst > lpszBuf+3 || lpszDst[-3] == ':'))
     2238            {
     2239              lpszDst -= 2;
     2240              while (lpszDst > lpszBuf && *lpszDst != '\\')
     2241                lpszDst--;
     2242              if (*lpszDst == '\\')
     2243                lpszDst++; /* Reset to last '\' */
     2244              else
     2245                lpszDst = lpszBuf; /* Start path again from new root */
     2246            }
     2247            else if (lpszDst[-2] != ':' && !PathIsUNCServerShareW(lpszBuf))
     2248              lpszDst -= 2;
    13992249          }
    1400         }
    1401        
    1402         /* ".\" at the beginning of the path */
    1403         if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
    1404         {
    1405           OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
    1406         }
    1407        
    1408         while ( LenSrc )
    1409         {
    1410           if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
    1411           {
    1412             /* "\.." found, go one deeper */
    1413             while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
    1414             OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
    1415             if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
    1416             pszBuf[OffsetDst] = '\0';                   /* important for \..\.. */
    1417           }
    1418           else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
    1419           {
    1420             /* "\." found, skip it */
    1421             OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
    1422           }
    1423           else
    1424           {
    1425             pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
    1426           }
    1427         }
    1428         pszBuf[OffsetDst] = '\0';
    1429         TRACE("-- %s %u\n", pszBuf, bModifyed);
    1430         return bModifyed;
    1431 }
    1432 
    1433 
    1434 /*************************************************************************
    1435  * PathCanonicalizeW   [SHLWAPI.@]
    1436  *
    1437  *  FIXME
    1438  *   returnvalue, use CharNext
    1439  */
    1440 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
    1441 {
    1442         int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlenW(pszPath);
    1443         BOOL bModifyed = FALSE;
    1444 
    1445         TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
    1446        
    1447         pszBuf[OffsetDst]='\0';
    1448 
    1449         /* keep the root of the path */
    1450         if( LenSrc && (pszPath[OffsetSrc]=='\\'))
    1451         {
    1452           pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
    1453         }
    1454         else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
    1455         {
    1456           pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
    1457           pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
    1458           if (LenSrc && (pszPath[OffsetSrc] == '\\'))
    1459           {
    1460             pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
    1461             if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
    1462             {
    1463               /* C:\. */
    1464               OffsetSrc++; LenSrc--; bModifyed = TRUE;
    1465             }
    1466             else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
    1467             {
    1468               /* C:\.. */
    1469               OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
    1470             }
     2250          while (lpszDst > lpszBuf && *lpszDst != '\\')
     2251            lpszDst--;
     2252          if (lpszDst == lpszBuf)
     2253          {
     2254            *lpszDst++ = '\\';
     2255            lpszSrc++;
    14712256          }
    1472         }
    1473        
    1474         /* ".\" at the beginning of the path */
    1475         if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
    1476         {
    1477           OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
    1478         }
    1479        
    1480         while ( LenSrc )
    1481         {
    1482           if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
    1483           {
    1484             /* "\.." found, go one deeper */
    1485             while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
    1486             OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
    1487             if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
    1488             pszBuf[OffsetDst] = '\0';                   /* important for \..\.. */
    1489           }
    1490           else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
    1491           {
    1492             /* "\." found, skip it */
    1493             OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
    1494           }
    1495           else
    1496           {
    1497             pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
    1498           }
    1499         }
    1500         pszBuf[OffsetDst] = '\0';
    1501         TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
    1502         return bModifyed;
     2257        }
     2258        lpszSrc += 2; /* Skip .. in src path */
     2259      }
     2260      else
     2261        *lpszDst++ = *lpszSrc++;
     2262    }
     2263    else
     2264      *lpszDst++ = *lpszSrc++;
     2265  }
     2266  /* Append \ to naked drive specs */
     2267  if (lpszDst - lpszBuf == 2 && lpszDst[-1] == ':')
     2268    *lpszDst++ = '\\';
     2269  *lpszDst++ = '\0';
     2270  return TRUE;
    15032271}
    15042272
     
    15062274 * PathFindNextComponentA   [SHLWAPI.@]
    15072275 *
     2276 * Find the next component in a path.
     2277 *
     2278 * PARAMS
     2279 *   lpszPath [I] Path to find next component in
     2280 *
     2281 * RETURNS
     2282 *  Success: A pointer to the next component, or the end of the string
     2283 *  Failure: NULL, If lpszPath is invalid
     2284 *
    15082285 * NOTES
    1509  * special cases:
    1510  *      ""              null
    1511  *      aa              "" (pointer to traling NULL)
    1512  *      aa\             "" (pointer to traling NULL)
    1513  *      aa\\            "" (pointer to traling NULL)
    1514  *      aa\\bb          bb
    1515  *      aa\\\bb         \bb
    1516  *      c:\aa\          "aa\"
    1517  *      \\aa            aa
    1518  *      \\aa\b          aa\b
    1519 */
    1520 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
    1521 {
    1522         LPSTR pos;
    1523 
    1524         TRACE("%s\n", pszPath);
    1525 
    1526         if(!pszPath || !*pszPath) return NULL;
    1527         if(!(pos = StrChrA(pszPath, '\\')))
    1528           return (LPSTR) pszPath + strlen(pszPath);
    1529         pos++;
    1530         if(pos[0] == '\\') pos++;
    1531         return pos;
     2286 *  A 'component' is either a backslash character (\) or UNC marker (\\).
     2287 *  Because of this, relative paths (e.g "c:foo") are regarded as having
     2288 *  only one component.
     2289 */
     2290LPSTR WINAPI PathFindNextComponentA(LPCSTR lpszPath)
     2291{
     2292  LPSTR lpszSlash;
     2293
     2294  TRACE("(%s)\n", debugstr_a(lpszPath));
     2295
     2296  if(!lpszPath || !*lpszPath)
     2297    return NULL;
     2298
     2299  if ((lpszSlash = StrChrA(lpszPath, '\\')))
     2300  {
     2301    if (lpszSlash[1] == '\\')
     2302      lpszSlash++;
     2303    return lpszSlash + 1;
     2304  }
     2305  return (LPSTR)lpszPath + strlen(lpszPath);
    15322306}
    15332307
    15342308/*************************************************************************
    15352309 * PathFindNextComponentW   [SHLWAPI.@]
    1536  */
    1537 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
    1538 {
    1539         LPWSTR pos;
    1540 
    1541         TRACE("%s\n", debugstr_w(pszPath));
    1542        
    1543         if(!pszPath || !*pszPath) return NULL;
    1544         if (!(pos = StrChrW(pszPath, '\\')))
    1545           return (LPWSTR) pszPath + strlenW(pszPath);
    1546         pos++;
    1547         if(pos[0] == '\\') pos++;
    1548         return pos;
     2310 *
     2311 * See PathFindNextComponentA.
     2312 */
     2313LPWSTR WINAPI PathFindNextComponentW(LPCWSTR lpszPath)
     2314{
     2315  LPWSTR lpszSlash;
     2316
     2317  TRACE("(%s)\n", debugstr_w(lpszPath));
     2318
     2319  if(!lpszPath || !*lpszPath)
     2320    return NULL;
     2321
     2322  if ((lpszSlash = StrChrW(lpszPath, '\\')))
     2323  {
     2324    if (lpszSlash[1] == '\\')
     2325      lpszSlash++;
     2326    return lpszSlash + 1;
     2327  }
     2328  return (LPWSTR)lpszPath + strlenW(lpszPath);
    15492329}
    15502330
     
    15522332 * PathAddExtensionA   [SHLWAPI.@]
    15532333 *
     2334 * Add a file extension to a path
     2335 *
     2336 * PARAMS
     2337 *  lpszPath      [O] Path to add extension to
     2338 *  lpszExtension [I} Extension to add to lpszPath
     2339 *
     2340 * RETURNS
     2341 *  TRUE  If the path was modified
     2342 *  FALSE If lpszPath or lpszExtension are invalid, lpszPath has an
     2343 *        extension allready, or the new path length is too big.
     2344 *
     2345 * FIXME
     2346 *  What version of shlwapi.dll adds "exe" if pszExtension is NULL? Win2k
     2347 *  does not do this, so the behaviour was removed.
     2348 */
     2349BOOL WINAPI PathAddExtensionA(LPSTR lpszPath, LPCSTR lpszExtension)
     2350{
     2351  DWORD dwLen;
     2352
     2353  TRACE("(%s,%s)\n", debugstr_a(lpszPath), debugstr_a(lpszExtension));
     2354
     2355  if (!lpszPath || !lpszExtension || *(PathFindExtensionA(lpszPath)))
     2356    return FALSE;
     2357
     2358  dwLen = strlen(lpszPath);
     2359
     2360  if (dwLen + strlen(lpszExtension) >= MAX_PATH)
     2361    return FALSE;
     2362
     2363  strcpy(lpszPath + dwLen, lpszExtension);
     2364  return TRUE;
     2365}
     2366
     2367/*************************************************************************
     2368 * PathAddExtensionW   [SHLWAPI.@]
     2369 *
     2370 * See PathAddExtensionA.
     2371 */
     2372BOOL WINAPI PathAddExtensionW(LPWSTR lpszPath, LPCWSTR lpszExtension)
     2373{
     2374  DWORD dwLen;
     2375
     2376  TRACE("(%s,%s)\n", debugstr_w(lpszPath), debugstr_w(lpszExtension));
     2377
     2378  if (!lpszPath || !lpszExtension || *(PathFindExtensionW(lpszPath)))
     2379    return FALSE;
     2380
     2381  dwLen = strlenW(lpszPath);
     2382
     2383  if (dwLen + strlenW(lpszExtension) >= MAX_PATH)
     2384    return FALSE;
     2385
     2386  strcpyW(lpszPath + dwLen, lpszExtension);
     2387  return TRUE;
     2388}
     2389
     2390/*************************************************************************
     2391 * PathMakePrettyA   [SHLWAPI.@]
     2392 *
     2393 * Convert an uppercase DOS filename into lowercase.
     2394 *
     2395 * PARAMS
     2396 *  lpszPath [O] Path to convert.
     2397 *
     2398 * RETURNS
     2399 *  TRUE  If the path was an uppercase DOS path and was converted
     2400 *  FALSE Otherwise.
     2401 */
     2402BOOL WINAPI PathMakePrettyA(LPSTR lpszPath)
     2403{
     2404  LPSTR pszIter = lpszPath;
     2405
     2406  TRACE("(%s)\n", debugstr_a(lpszPath));
     2407
     2408  if (!pszIter || !*pszIter)
     2409    return FALSE;
     2410
     2411  while (*pszIter)
     2412  {
     2413    if (islower(*pszIter) || IsDBCSLeadByte(*pszIter))
     2414      return FALSE; /* Not DOS path */
     2415    pszIter++;
     2416  }
     2417  pszIter = lpszPath + 1;
     2418  while (*pszIter)
     2419  {
     2420    *pszIter = tolower(*pszIter);
     2421    pszIter++;
     2422  }
     2423  return TRUE;
     2424}
     2425
     2426/*************************************************************************
     2427 * PathMakePrettyW   [SHLWAPI.@]
     2428 *
     2429 * See PathMakePrettyA
     2430 */
     2431BOOL WINAPI PathMakePrettyW(LPWSTR lpszPath)
     2432{
     2433  LPWSTR pszIter = lpszPath;
     2434
     2435  TRACE("(%s)\n", debugstr_w(lpszPath));
     2436
     2437  if (!pszIter || !*pszIter)
     2438    return FALSE;
     2439
     2440  while (*pszIter)
     2441  {
     2442    if (islowerW(*pszIter))
     2443      return FALSE; /* Not DOS path */
     2444    pszIter++;
     2445  }
     2446  pszIter = lpszPath + 1;
     2447  while (*pszIter)
     2448  {
     2449    *pszIter = tolowerW(*pszIter);
     2450    pszIter++;
     2451  }
     2452  return TRUE;
     2453}
     2454
     2455/*************************************************************************
     2456 * PathCommonPrefixA   [SHLWAPI.@]
     2457 *
     2458 * Determine the length of the common prefix between two paths.
     2459 *
     2460 * PARAMS
     2461 *  lpszFile1 [I] First path for comparason
     2462 *  lpszFile2 [I] Second path for comparason
     2463 *  achPath   [O] Destination for common prefix string
     2464 *
     2465 * RETURNS
     2466 *  The length of the common prefix. This is 0 if there is no common
     2467 *  prefix between the paths or if any parameters are invalid. If the prefix
     2468 *  is non-zero and achPath is not NULL, achPath is filled with the common
     2469 *  part of the prefix and NUL terminated.
     2470 *
    15542471 * NOTES
    1555  *  it adds never a dot
    1556  */
    1557  
    1558 BOOL WINAPI PathAddExtensionA(
    1559         LPSTR  pszPath,
    1560         LPCSTR pszExtension)
    1561 {
    1562         if (*pszPath)
    1563         {
    1564           if (*(PathFindExtensionA(pszPath))) return FALSE;
    1565 
    1566           if (!pszExtension || *pszExtension=='\0')
    1567             strcat(pszPath, "exe");
    1568           else
    1569             strcat(pszPath, pszExtension);
    1570         }
    1571 
    1572         return TRUE;
    1573 }
    1574 
    1575 /*************************************************************************
    1576  *      PathAddExtensionW   [SHLWAPI.@]
    1577  */
    1578 BOOL WINAPI PathAddExtensionW(
    1579         LPWSTR  pszPath,
    1580         LPCWSTR pszExtension)
    1581 {
    1582         static const WCHAR ext[] = { 'e','x','e',0 };
    1583 
    1584         if (*pszPath)
    1585         {
    1586           if (*(PathFindExtensionW(pszPath))) return FALSE;
    1587 
    1588           if (!pszExtension || *pszExtension=='\0')
    1589             strcatW(pszPath, ext);
    1590           else
    1591             strcatW(pszPath, pszExtension);
    1592         }
    1593         return TRUE;
    1594 
    1595 }
    1596 
    1597 /*************************************************************************
    1598  *      PathMakePrettyA   [SHLWAPI.@]
    1599  */
    1600 BOOL WINAPI PathMakePrettyA(
    1601         LPSTR lpPath)
    1602 {
    1603         FIXME("%s\n", lpPath);
    1604         return TRUE;
    1605 }
    1606 
    1607 /*************************************************************************
    1608  *      PathMakePrettyW   [SHLWAPI.@]
    1609  */
    1610 BOOL WINAPI PathMakePrettyW(
    1611         LPWSTR lpPath)
    1612 {
    1613         FIXME("%s\n", debugstr_w(lpPath));
    1614         return TRUE;
    1615 
    1616 }
    1617 
    1618 /*************************************************************************
    1619  *      PathCommonPrefixA   [SHLWAPI.@]
    1620  */
    1621 int WINAPI PathCommonPrefixA(
    1622         LPCSTR pszFile1,
    1623         LPCSTR pszFile2,
    1624         LPSTR achPath)
    1625 {
    1626         FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
    1627         return 0;
    1628 }
    1629 
    1630 /*************************************************************************
    1631  *      PathCommonPrefixW   [SHLWAPI.@]
    1632  */
    1633 int WINAPI PathCommonPrefixW(
    1634         LPCWSTR pszFile1,
    1635         LPCWSTR pszFile2,
    1636         LPWSTR achPath)
    1637 {
    1638         FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );
    1639         return 0;
    1640 }
    1641 
    1642 /*************************************************************************
    1643  *      PathCompactPathA   [SHLWAPI.@]
    1644  */
    1645 BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR pszPath, UINT dx)
    1646 {
    1647         FIXME("0x%08x %s 0x%08x\n", hDC, pszPath, dx);
    1648         return FALSE;
    1649 }
    1650 
    1651 /*************************************************************************
    1652  *      PathCompactPathW   [SHLWAPI.@]
    1653  */
    1654 BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR pszPath, UINT dx)
    1655 {
    1656         FIXME("0x%08x %s 0x%08x\n", hDC, debugstr_w(pszPath), dx);
    1657         return FALSE;
    1658 }
    1659 
    1660 /*************************************************************************
    1661  *      PathGetCharTypeA   [SHLWAPI.@]
     2472 *  A common prefix of 2 is always returned as 3. It is thus possible for
     2473 *  the length returned to be invalid (i.e. Longer than one or both of the
     2474 *  strings given as parameters). This Win32 behaviour has been implimented
     2475 *  here, and cannot be changed (fixed?) without breaking other SHLWAPI calls.
     2476 *  To work around this when using this function, always check that the byte
     2477 *  at [common_prefix_len-1] is not a NUL. If it is, deduct 1 from the prefix.
     2478 */
     2479int WINAPI PathCommonPrefixA(LPCSTR lpszFile1, LPCSTR lpszFile2, LPSTR achPath)
     2480{
     2481  int iLen = 0;
     2482  LPCSTR lpszIter1 = lpszFile1;
     2483  LPCSTR lpszIter2 = lpszFile2;
     2484
     2485  TRACE("(%s,%s,%p)\n", debugstr_a(lpszFile1), debugstr_a(lpszFile2), achPath);
     2486
     2487  if (achPath)
     2488    *achPath = '\0';
     2489
     2490  if (!lpszFile1 || !lpszFile2)
     2491    return 0;
     2492
     2493  /* Handle roots first */
     2494  if (PathIsUNCA(lpszFile1))
     2495  {
     2496    if (!PathIsUNCA(lpszFile2))
     2497      return 0;
     2498    lpszIter1 += 2;
     2499    lpszIter2 += 2;
     2500  }
     2501  else if (PathIsUNCA(lpszFile2))
     2502      return 0; /* Know already lpszFile1 is not UNC */
     2503
     2504  do
     2505  {
     2506    /* Update len */
     2507    if ((!*lpszIter1 || *lpszIter1 == '\\') &&
     2508        (!*lpszIter2 || *lpszIter2 == '\\'))
     2509      iLen = lpszIter1 - lpszFile1; /* Common to this point */
     2510
     2511    if (!*lpszIter1 || (tolower(*lpszIter1) != tolower(*lpszIter2)))
     2512      break; /* Strings differ at this point */
     2513
     2514    lpszIter1++;
     2515    lpszIter2++;
     2516  } while (1);
     2517
     2518  if (iLen == 2)
     2519    iLen++; /* Feature/Bug compatable with Win32 */
     2520
     2521  if (iLen && achPath)
     2522  {
     2523    memcpy(achPath,lpszFile1,iLen);
     2524    achPath[iLen] = '\0';
     2525  }
     2526  return iLen;
     2527}
     2528
     2529/*************************************************************************
     2530 * PathCommonPrefixW   [SHLWAPI.@]
     2531 *
     2532 * See PathCommonPrefixA.
     2533 */
     2534int WINAPI PathCommonPrefixW(LPCWSTR lpszFile1, LPCWSTR lpszFile2, LPWSTR achPath)
     2535{
     2536  int iLen = 0;
     2537  LPCWSTR lpszIter1 = lpszFile1;
     2538  LPCWSTR lpszIter2 = lpszFile2;
     2539
     2540  TRACE("(%s,%s,%p)\n", debugstr_w(lpszFile1), debugstr_w(lpszFile2), achPath);
     2541
     2542  if (achPath)
     2543    *achPath = '\0';
     2544
     2545  if (!lpszFile1 || !lpszFile2)
     2546    return 0;
     2547
     2548  /* Handle roots first */
     2549  if (PathIsUNCW(lpszFile1))
     2550  {
     2551    if (!PathIsUNCW(lpszFile2))
     2552      return 0;
     2553    lpszIter1 += 2;
     2554    lpszIter2 += 2;
     2555  }
     2556  else if (PathIsUNCW(lpszFile2))
     2557      return 0; /* Know already lpszFile1 is not UNC */
     2558
     2559  do
     2560  {
     2561    /* Update len */
     2562    if ((!*lpszIter1 || *lpszIter1 == '\\') &&
     2563        (!*lpszIter2 || *lpszIter2 == '\\'))
     2564      iLen = lpszIter1 - lpszFile1; /* Common to this point */
     2565
     2566    if (!*lpszIter1 || (tolowerW(*lpszIter1) != tolowerW(*lpszIter2)))
     2567      break; /* Strings differ at this point */
     2568
     2569    lpszIter1++;
     2570    lpszIter2++;
     2571  } while (1);
     2572
     2573  if (iLen == 2)
     2574    iLen++; /* Feature/Bug compatable with Win32 */
     2575
     2576  if (iLen && achPath)
     2577  {
     2578    memcpy(achPath,lpszFile1,iLen * sizeof(WCHAR));
     2579    achPath[iLen] = '\0';
     2580  }
     2581  return iLen;
     2582}
     2583
     2584/*************************************************************************
     2585 * PathCompactPathA   [SHLWAPI.@]
     2586 *
     2587 * Make a path fit into a given width when printed to a DC.
     2588 *
     2589 * PARAMS
     2590 *  hDc      [I] Destination DC
     2591 *  lpszPath [O] Path to be printed to hDc
     2592 *  dx       [i] Desired width
     2593 *
     2594 * RETURNS
     2595 *  TRUE  If the path was modified.
     2596 *  FALSE Otherwise.
     2597 */
     2598BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR lpszPath, UINT dx)
     2599{
     2600  BOOL bRet = FALSE;
     2601
     2602  TRACE("(%08x,%s,%d)\n", hDC, debugstr_a(lpszPath), dx);
     2603
     2604  if (lpszPath)
     2605  {
     2606    WCHAR szPath[MAX_PATH];
     2607    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
     2608    bRet = PathCompactPathW(hDC, szPath, dx);
     2609    WideCharToMultiByte(0,0,szPath,-1,lpszPath,MAX_PATH,0,0);
     2610  }
     2611  return bRet;
     2612}
     2613
     2614/*************************************************************************
     2615 * PathCompactPathW   [SHLWAPI.@]
     2616 *
     2617 * See PathCompactPathA.
     2618 */
     2619BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR lpszPath, UINT dx)
     2620{
     2621  static const WCHAR szEllipses[] = { '.', '.', '.', '\0' };
     2622  BOOL bRet = TRUE;
     2623  HDC hdc = 0;
     2624  WCHAR buff[MAX_PATH];
     2625  SIZE size;
     2626  DWORD dwLen;
     2627
     2628  TRACE("(%08x,%s,%d)\n", hDC, debugstr_w(lpszPath), dx);
     2629
     2630  if (!lpszPath)
     2631    return bRet;
     2632
     2633  if (!hDC)
     2634    hdc = hDC = GetDC(0);
     2635
     2636  /* Get the length of the whole path */
     2637  dwLen = strlenW(lpszPath);
     2638  GetTextExtentPointW(hDC, lpszPath, dwLen, &size);
     2639
     2640  if (size.cx > dx)
     2641  {
     2642    /* Path too big, must reduce it */
     2643    LPWSTR sFile;
     2644    DWORD dwEllipsesLen = 0, dwPathLen = 0;
     2645
     2646    sFile = PathFindFileNameW(lpszPath);
     2647    if (sFile != lpszPath)
     2648      sFile = CharPrevW(lpszPath, sFile);
     2649
     2650    /* Get the size of ellipses */
     2651    GetTextExtentPointW(hDC, szEllipses, 3, &size);
     2652    dwEllipsesLen = size.cx;
     2653    /* Get the size of the file name */
     2654    GetTextExtentPointW(hDC, sFile, strlenW(sFile), &size);
     2655    dwPathLen = size.cx;
     2656
     2657    if (sFile != lpszPath)
     2658    {
     2659      LPWSTR sPath = sFile;
     2660      BOOL bEllipses = FALSE;
     2661
     2662      /* The path includes a file name. Include as much of the path prior to
     2663       * the file name as possible, allowing for the ellipses, e.g:
     2664       * c:\some very long path\filename ==> c:\some v...\filename
     2665       */
     2666      strncpyW(buff, sFile, MAX_PATH);
     2667
     2668      do
     2669      {
     2670        DWORD dwTotalLen = bEllipses? dwPathLen + dwEllipsesLen : dwPathLen;
     2671
     2672        GetTextExtentPointW(hDC, lpszPath, sPath - lpszPath, &size);
     2673        dwTotalLen += size.cx;
     2674        if (dwTotalLen <= dx)
     2675          break;
     2676        sPath = CharPrevW(lpszPath, sPath);
     2677        if (!bEllipses)
     2678        {
     2679          bEllipses = TRUE;
     2680          sPath = CharPrevW(lpszPath, sPath);
     2681          sPath = CharPrevW(lpszPath, sPath);
     2682        }
     2683      } while (sPath > lpszPath);
     2684
     2685      if (sPath > lpszPath)
     2686      {
     2687        if (bEllipses)
     2688        {
     2689          strcpyW(sPath, szEllipses);
     2690          strcpyW(sPath+3, buff);
     2691        }
     2692        if (hdc)
     2693          ReleaseDC(0, hdc);
     2694        return TRUE;
     2695      }
     2696      strcpyW(lpszPath, szEllipses);
     2697      strcpyW(lpszPath+3, buff);
     2698      return FALSE;
     2699    }
     2700
     2701    /* Trim the path by adding ellipses to the end, e.g:
     2702     * A very long file name.txt ==> A very...
     2703     */
     2704    dwLen = strlenW(lpszPath);
     2705
     2706    if (dwLen > MAX_PATH - 3)
     2707      dwLen =  MAX_PATH - 3;
     2708    strncpyW(buff, sFile, dwLen);
     2709
     2710    do {
     2711      dwLen--;
     2712      GetTextExtentPointW(hDC, buff, dwLen, &size);
     2713    } while (dwLen && size.cx + dwEllipsesLen > dx);
     2714
     2715   if (!dwLen)
     2716   {
     2717     DWORD dwWritten = 0;
     2718
     2719     dwEllipsesLen /= 3; /* Size of a single '.' */
     2720
     2721     /* Write as much of the Ellipses string as possible */
     2722     while (dwWritten + dwEllipsesLen < dx && dwLen < 3)
     2723     {
     2724       *lpszPath++ = '.';
     2725       dwWritten += dwEllipsesLen;
     2726       dwLen++;
     2727     }
     2728     *lpszPath = '\0';
     2729     bRet = FALSE;
     2730   }
     2731   else
     2732   {
     2733     strcpyW(buff + dwLen, szEllipses);
     2734     strcpyW(lpszPath, buff);
     2735    }
     2736  }
     2737
     2738  if (hdc)
     2739    ReleaseDC(0, hdc);
     2740
     2741  return bRet;
     2742}
     2743
     2744/*************************************************************************
     2745 * PathGetCharTypeA   [SHLWAPI.@]
     2746 *
     2747 * Categorise a character from a file path.
     2748 *
     2749 * PARAMS
     2750 *  ch [I] Character to get the type of
     2751 *
     2752 * RETURNS
     2753 *  A set of GCT_ bit flags (from shlwapi.h) indicating the character type.
    16622754 */
    16632755UINT WINAPI PathGetCharTypeA(UCHAR ch)
    16642756{
    1665         UINT flags = 0;
    1666 
    1667         TRACE("%c\n", ch);
    1668 
    1669         /* We could use them in filenames, but this would confuse 'ls' */
    1670         if (iscntrl(ch))
    1671             return GCT_INVALID;
    1672         if ((ch == '*') || (ch=='?'))
    1673             return GCT_WILD;
    1674         if ((ch == '\\') || (ch=='/'))
    1675             return GCT_SEPARATOR;
    1676         flags = 0;
    1677         /* all normal characters, no lower case letters */
    1678         if ((ch > ' ') && (ch < 0x7f) && !islower(ch))
    1679             flags |= GCT_SHORTCHAR;
    1680         /* All other characters are valid in long filenames, even umlauts */
    1681         return flags | GCT_LFNCHAR;
    1682 }
    1683 
    1684 /*************************************************************************
    1685  *      PathGetCharTypeW   [SHLWAPI.@]
     2757  return PathGetCharTypeW(ch);
     2758}
     2759
     2760/*************************************************************************
     2761 * PathGetCharTypeW   [SHLWAPI.@]
     2762 *
     2763 * See PathGetCharTypeA.
    16862764 */
    16872765UINT WINAPI PathGetCharTypeW(WCHAR ch)
    16882766{
    1689         FIXME("%c, using ascii version\n", ch);
    1690         return PathGetCharTypeA(ch);
    1691 }
    1692 
    1693 /*************************************************************************
    1694  *      PathMakeSystemFolderA   [SHLWAPI.@]
    1695  */
    1696 BOOL WINAPI PathMakeSystemFolderA(LPCSTR pszPath)
    1697 {
    1698         FIXME("%s\n", pszPath);
    1699         return FALSE;
    1700 }
    1701 
    1702 /*************************************************************************
    1703  *      PathMakeSystemFolderW   [SHLWAPI.@]
    1704  */
    1705 BOOL WINAPI PathMakeSystemFolderW(LPCWSTR pszPath)
    1706 {
    1707         FIXME("%s\n", debugstr_w(pszPath));
    1708         return FALSE;
    1709 }
    1710 
    1711 /*************************************************************************
    1712  *      PathRenameExtensionA   [SHLWAPI.@]
    1713  */
    1714 BOOL WINAPI PathRenameExtensionA(LPSTR pszPath, LPCSTR pszExt)
    1715 {
    1716         LPSTR pszExtension = PathFindExtensionA(pszPath);
    1717 
    1718         if (!pszExtension) return FALSE;
    1719         if (pszExtension-pszPath + strlen(pszExt) > MAX_PATH) return FALSE;
    1720 
    1721         strcpy(pszExtension, pszExt);
    1722         TRACE("%s\n", pszPath);
    1723         return TRUE;
    1724 }
    1725 
    1726 /*************************************************************************
    1727  *      PathRenameExtensionW   [SHLWAPI.@]
    1728  */
    1729 BOOL WINAPI PathRenameExtensionW(LPWSTR pszPath, LPCWSTR pszExt)
    1730 {
    1731         LPWSTR pszExtension = PathFindExtensionW(pszPath);
    1732 
    1733         if (!pszExtension) return FALSE;
    1734         if (pszExtension-pszPath + strlenW(pszExt) > MAX_PATH) return FALSE;
    1735 
    1736         strcpyW(pszExtension, pszExt);
    1737         TRACE("%s\n", debugstr_w(pszPath));
    1738         return TRUE;
    1739 }
    1740 
    1741 /*************************************************************************
    1742  *      PathSearchAndQualifyA   [SHLWAPI.@]
    1743  */
    1744 BOOL WINAPI PathSearchAndQualifyA(
    1745         LPCSTR pszPath,
    1746         LPSTR pszBuf,
    1747         UINT cchBuf)
    1748 {
    1749         FIXME("%s %s 0x%08x\n", pszPath, pszBuf, cchBuf);
    1750         return FALSE;
    1751 }
    1752 
    1753 /*************************************************************************
    1754  *      PathSearchAndQualifyW   [SHLWAPI.@]
    1755  */
    1756 BOOL WINAPI PathSearchAndQualifyW(
    1757         LPCWSTR pszPath,
    1758         LPWSTR pszBuf,
    1759         UINT cchBuf)
    1760 {
    1761         FIXME("%s %s 0x%08x\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
    1762         return FALSE;
    1763 }
    1764 
    1765 #ifndef __WIN32OS2__
    1766 /*************************************************************************
    1767  *      PathSkipRootA   [SHLWAPI.@]
    1768  */
    1769 LPSTR WINAPI PathSkipRootA(LPCSTR pszPath)
    1770 {
    1771         FIXME("%s\n", pszPath);
    1772         return (LPSTR)pszPath;
    1773 }
    1774 
    1775 /*************************************************************************
    1776  *      PathSkipRootW   [SHLWAPI.@]
    1777  */
    1778 LPWSTR WINAPI PathSkipRootW(LPCWSTR pszPath)
    1779 {
    1780         FIXME("%s\n", debugstr_w(pszPath));
    1781         return (LPWSTR)pszPath;
    1782 }
    1783 #endif
    1784 
    1785 /*************************************************************************
    1786  *      PathCreateFromUrlA   [SHLWAPI.@]
    1787  */
    1788 HRESULT WINAPI PathCreateFromUrlA(
    1789         LPCSTR pszUrl,
    1790         LPSTR pszPath,
    1791         LPDWORD pcchPath,
    1792         DWORD dwFlags)
    1793 {
     2767  UINT flags = 0;
     2768
     2769  TRACE("(%d)\n", ch);
     2770
     2771  if (!ch || ch < ' ' || ch == '<' || ch == '>' ||
     2772      ch == '"' || ch == '|' || ch == 255)
     2773    flags = GCT_INVALID; /* Invalid */
     2774  else if (ch == '*' || ch=='?')
     2775    flags = GCT_WILD; /* Wildchars */
     2776  else if ((ch == '\\') || (ch=='/') || (ch == ':'))
     2777    return GCT_SEPARATOR; /* Path separators */
     2778  else
     2779  {
     2780     if (ch < 126)
     2781     {
     2782       if (!ch || isalnum(ch) || ch == '$' || ch == '&' || ch == '(' ||
     2783            ch == '.' || ch == '@' || ch == '^' ||
     2784            ch == '\'' || ch == 130 || ch == '`')
     2785         flags |= GCT_SHORTCHAR; /* All these are valid for DOS */
     2786     }
     2787     else
     2788       if (!(ch & 0x1))
     2789         flags |= GCT_SHORTCHAR; /* Bug compatable with win32 */
     2790     flags |= GCT_LFNCHAR; /* Valid for long file names */
     2791  }
     2792  return flags;
     2793}
     2794
     2795/*************************************************************************
     2796 * SHLWAPI_UseSystemForSystemFolders
     2797 *
     2798 * Internal helper for PathMakeSystemFolderW.
     2799 */
     2800static BOOL SHLWAPI_UseSystemForSystemFolders()
     2801{
     2802  static BOOL bCheckedReg = FALSE;
     2803  static BOOL bUseSystemForSystemFolders = FALSE;
     2804
     2805  if (!bCheckedReg)
     2806  {
     2807    bCheckedReg = TRUE;
     2808
     2809    /* Key tells Win what file attributes to use on system folders */
     2810    if (SHGetValueA(HKEY_LOCAL_MACHINE,
     2811        "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
     2812        "UseSystemForSystemFolders", 0, 0, 0))
     2813      bUseSystemForSystemFolders = TRUE;
     2814  }
     2815  return bUseSystemForSystemFolders;
     2816}
     2817
     2818/*************************************************************************
     2819 * PathMakeSystemFolderA   [SHLWAPI.@]
     2820 *
     2821 * Set system folder attribute for a path.
     2822 *
     2823 * PARAMS
     2824 *  lpszPath [I] The path to turn into a system folder
     2825 *
     2826 * RETURNS
     2827 *  TRUE  If the path was changed to/already was a system folder
     2828 *  FALSE If the path is invalid or SetFileAttributesA fails
     2829 */
     2830BOOL WINAPI PathMakeSystemFolderA(LPCSTR lpszPath)
     2831{
     2832  BOOL bRet = FALSE;
     2833
     2834  TRACE("(%s)\n", debugstr_a(lpszPath));
     2835
     2836  if (lpszPath && *lpszPath)
     2837  {
     2838    WCHAR szPath[MAX_PATH];
     2839    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
     2840    bRet = PathMakeSystemFolderW(szPath);
     2841  }
     2842  return bRet;
     2843}
     2844
     2845/*************************************************************************
     2846 * PathMakeSystemFolderW   [SHLWAPI.@]
     2847 *
     2848 * See PathMakeSystemFolderA.
     2849 */
     2850BOOL WINAPI PathMakeSystemFolderW(LPCWSTR lpszPath)
     2851{
     2852  DWORD dwDefaultAttr = FILE_ATTRIBUTE_READONLY, dwAttr;
     2853  WCHAR buff[MAX_PATH];
     2854
     2855  TRACE("(%s)\n", debugstr_w(lpszPath));
     2856
     2857  if (!lpszPath || !*lpszPath)
     2858    return FALSE;
     2859
     2860  /* If the directory is already a system directory, dont do anything */
     2861  GetSystemDirectoryW(buff, MAX_PATH);
     2862  if (!strcmpW(buff, lpszPath))
     2863    return TRUE;
     2864
     2865  GetWindowsDirectoryW(buff, MAX_PATH);
     2866  if (!strcmpW(buff, lpszPath))
     2867    return TRUE;
     2868
     2869  /* "UseSystemForSystemFolders" Tells Win what attributes to use */
     2870  if (SHLWAPI_UseSystemForSystemFolders())
     2871    dwDefaultAttr = FILE_ATTRIBUTE_SYSTEM;
     2872
     2873  if ((dwAttr = GetFileAttributesW(lpszPath)) == -1)
     2874    return FALSE;
     2875
     2876  /* Change file attributes to system attributes */
     2877  dwAttr &= ~(FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_READONLY);
     2878  return SetFileAttributesW(lpszPath, dwAttr | dwDefaultAttr);
     2879}
     2880
     2881/*************************************************************************
     2882 * PathRenameExtensionA   [SHLWAPI.@]
     2883 *
     2884 * Swap the file extension in a path with another extension.
     2885 *
     2886 * PARAMS
     2887 *  pszPath [O] Path to swap the extension in
     2888 *  pszExt  [I] The new extension
     2889 *
     2890 * RETURNS
     2891 *  TRUE  if pszPath was modified
     2892 *  FALSE if pszPath or pszExt is NULL, or the new path is too long
     2893 */
     2894BOOL WINAPI PathRenameExtensionA(LPSTR lpszPath, LPCSTR lpszExt)
     2895{
     2896  LPSTR lpszExtension;
     2897
     2898  TRACE("(%s,%s)\n", debugstr_a(lpszPath), debugstr_a(lpszExt));
     2899
     2900  lpszExtension = PathFindExtensionA(lpszPath);
     2901
     2902  if (!lpszExtension || (lpszExtension - lpszPath + strlen(lpszExt) >= MAX_PATH))
     2903    return FALSE;
     2904
     2905  strcpy(lpszExtension, lpszExt);
     2906  return TRUE;
     2907}
     2908
     2909/*************************************************************************
     2910 * PathRenameExtensionW   [SHLWAPI.@]
     2911 *
     2912 * See PathRenameExtensionA.
     2913 */
     2914BOOL WINAPI PathRenameExtensionW(LPWSTR lpszPath, LPCWSTR lpszExt)
     2915{
     2916  LPWSTR lpszExtension;
     2917
     2918  TRACE("(%s,%s)\n", debugstr_w(lpszPath), debugstr_w(lpszExt));
     2919
     2920  lpszExtension = PathFindExtensionW(lpszPath);
     2921
     2922  if (!lpszExtension || (lpszExtension - lpszPath + strlenW(lpszExt) >= MAX_PATH))
     2923    return FALSE;
     2924
     2925  strcpyW(lpszExtension, lpszExt);
     2926  return TRUE;
     2927}
     2928
     2929/*************************************************************************
     2930 * PathSearchAndQualifyA   [SHLWAPI.@]
     2931 *
     2932 * Unimplemented.
     2933 *
     2934 * PARAMS
     2935 *  lpszPath [I]
     2936 *  lpszBuf  [O]
     2937 *  cchBuf   [I] Size of lpszBuf
     2938 *
     2939 * RETURNS
     2940 *  Unknown.
     2941 */
     2942BOOL WINAPI PathSearchAndQualifyA(LPCSTR lpszPath, LPSTR lpszBuf, UINT cchBuf)
     2943{
     2944  FIXME("(%s,%p,0x%08x)-stub\n", debugstr_a(lpszPath), lpszBuf, cchBuf);
     2945  return FALSE;
     2946}
     2947
     2948/*************************************************************************
     2949 * PathSearchAndQualifyW   [SHLWAPI.@]
     2950 *
     2951 * See PathSearchAndQualifyA
     2952 */
     2953BOOL WINAPI PathSearchAndQualifyW(LPCWSTR lpszPath, LPWSTR lpszBuf, UINT cchBuf)
     2954{
     2955  FIXME("(%s,%p,0x%08x)-stub\n", debugstr_w(lpszPath), lpszBuf, cchBuf);
     2956  return FALSE;
     2957}
     2958
     2959/*************************************************************************
     2960 * PathSkipRootA   [SHLWAPI.@]
     2961 *
     2962 * Return the portion of a path following the drive letter or mount point.
     2963 *
     2964 * PARAMS
     2965 *  lpszPath [I] The path to skip on
     2966 *
     2967 * RETURNS
     2968 *  Success: A pointer to the next character after the root.
     2969 *  Failure: NULL, if lpszPath is invalid, has no root or is a MB string.
     2970 */
     2971LPSTR WINAPI PathSkipRootA(LPCSTR lpszPath)
     2972{
     2973  TRACE("(%s)\n", debugstr_a(lpszPath));
     2974
     2975  if (!lpszPath || !*lpszPath)
     2976    return NULL;
     2977
     2978  if (*lpszPath == '\\' && lpszPath[1] == '\\')
     2979  {
     2980    /* Network share: skip share server and mount point */
     2981    lpszPath += 2;
     2982    if ((lpszPath = StrChrA(lpszPath, '\\')) &&
     2983        (lpszPath = StrChrA(lpszPath + 1, '\\')))
     2984      lpszPath++;
     2985    return (LPSTR)lpszPath;
     2986  }
     2987
     2988  if (IsDBCSLeadByte(*lpszPath))
     2989    return NULL;
     2990
     2991  /* Check x:\ */
     2992  if (lpszPath[0] && lpszPath[1] == ':' && lpszPath[2] == '\\')
     2993    return (LPSTR)lpszPath + 3;
     2994  return NULL;
     2995}
     2996
     2997/*************************************************************************
     2998 * PathSkipRootW   [SHLWAPI.@]
     2999 *
     3000 * See PathSkipRootA.
     3001 */
     3002LPWSTR WINAPI PathSkipRootW(LPCWSTR lpszPath)
     3003{
     3004  TRACE("(%s)\n", debugstr_w(lpszPath));
     3005
     3006  if (!lpszPath || !*lpszPath)
     3007    return NULL;
     3008
     3009  if (*lpszPath == '\\' && lpszPath[1] == '\\')
     3010  {
     3011    /* Network share: skip share server and mount point */
     3012    lpszPath += 2;
     3013    if ((lpszPath = StrChrW(lpszPath, '\\')) &&
     3014        (lpszPath = StrChrW(lpszPath + 1, '\\')))
     3015     lpszPath++;
     3016    return (LPWSTR)lpszPath;
     3017  }
     3018
     3019  /* Check x:\ */
     3020  if (lpszPath[0] && lpszPath[1] == ':' && lpszPath[2] == '\\')
     3021    return (LPWSTR)lpszPath + 3;
     3022  return NULL;
     3023}
     3024
     3025/*************************************************************************
     3026 * PathCreateFromUrlA   [SHLWAPI.@]
     3027 *
     3028 * Create a path from a URL
     3029 *
     3030 * PARAMS
     3031 *  lpszUrl  [I] URL to convert into a path
     3032 *  lpszPath [O] Output buffer for the resulting Path
     3033 *  pcchPath [I] Length of lpszPath
     3034 *  dwFlags  [I] Flags controlling the conversion
     3035 *
     3036 * RETURNS
     3037 *  Success: S_OK. lpszPath contains the URL in path format
     3038 *  Failure: An HRESULT error code such as E_INVALIDARG.
     3039 */
     3040HRESULT WINAPI PathCreateFromUrlA(LPCSTR lpszUrl, LPSTR lpszPath,
     3041                                  LPDWORD pcchPath, DWORD dwFlags)
     3042{
     3043  FIXME("(%s,%p,%p,0x%08lx)-stub\n", debugstr_a(lpszUrl), lpszPath, pcchPath, dwFlags);
     3044
     3045  if (!lpszUrl || !lpszPath || !pcchPath || !*pcchPath)
     3046    return E_INVALIDARG;
     3047
    17943048    /* extracts thing prior to : in pszURL and checks against:
    17953049     *   https
     
    17983052     *   about  - if match returns E_INVALIDARG
    17993053     */
    1800         FIXME("%s %p %p 0x%08lx\n",
    1801           pszUrl, pszPath, pcchPath, dwFlags);
    1802         return E_INVALIDARG;
    1803 }
    1804 
    1805 /*************************************************************************
    1806  *      PathCreateFromUrlW   [SHLWAPI.@]
    1807  */
    1808 HRESULT WINAPI PathCreateFromUrlW(
    1809         LPCWSTR pszUrl,
    1810         LPWSTR pszPath,
    1811         LPDWORD pcchPath,
    1812         DWORD dwFlags)
    1813 {
    1814     /* extracts thing prior to : in pszURL and checks against:
    1815      *   https
    1816      *   shell
    1817      *   local
    1818      *   about  - if match returns E_INVALIDARG
    1819      */
    1820         FIXME("%s %p %p 0x%08lx\n",
    1821           debugstr_w(pszUrl), pszPath, pcchPath, dwFlags);
    1822         return E_INVALIDARG;
    1823 }
    1824 
    1825 /*************************************************************************
    1826  *      PathRelativePathToA   [SHLWAPI.@]
    1827  */
    1828 BOOL WINAPI PathRelativePathToA(
    1829         LPSTR pszPath,
    1830         LPCSTR pszFrom,
    1831         DWORD dwAttrFrom,
    1832         LPCSTR pszTo,
    1833         DWORD dwAttrTo)
    1834 {
    1835         FIXME("%s %s 0x%08lx %s 0x%08lx\n",
    1836           pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo);
    1837         return FALSE;
    1838 }
    1839 
    1840 /*************************************************************************
    1841  *      PathRelativePathToW   [SHLWAPI.@]
    1842  */
    1843 BOOL WINAPI PathRelativePathToW(
    1844         LPWSTR pszPath,
    1845         LPCWSTR pszFrom,
    1846         DWORD dwAttrFrom,
    1847         LPCWSTR pszTo,
    1848         DWORD dwAttrTo)
    1849 {
    1850         FIXME("%s %s 0x%08lx %s 0x%08lx\n",
    1851           debugstr_w(pszPath), debugstr_w(pszFrom), dwAttrFrom, debugstr_w(pszTo), dwAttrTo);
    1852         return FALSE;
    1853 }
    1854 
    1855 /*************************************************************************
    1856  *      PathUnmakeSystemFolderA   [SHLWAPI.@]
    1857  */
    1858 BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR pszPath)
    1859 {
    1860         FIXME("%s\n", pszPath);
    1861         return FALSE;
    1862 }
    1863 
    1864 /*************************************************************************
    1865  *      PathUnmakeSystemFolderW   [SHLWAPI.@]
    1866  */
    1867 BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR pszPath)
    1868 {
    1869         FIXME("%s\n", debugstr_w(pszPath));
    1870         return FALSE;
    1871 }
    1872 
    1873 /*
    1874         ########## special ##########
    1875 */
     3054
     3055  return S_OK;
     3056}
     3057
     3058/*************************************************************************
     3059 * PathCreateFromUrlW   [SHLWAPI.@]
     3060 *
     3061 * See PathCreateFromUrlA.
     3062 */
     3063HRESULT WINAPI PathCreateFromUrlW(LPCWSTR lpszUrl, LPWSTR lpszPath,
     3064                                  LPDWORD pcchPath, DWORD dwFlags)
     3065{
     3066  FIXME("(%s,%p,%p,0x%08lx)-stub\n", debugstr_w(lpszUrl), lpszPath, pcchPath, dwFlags);
     3067
     3068  if (!lpszUrl || !lpszPath || !pcchPath || !*pcchPath)
     3069    return E_INVALIDARG;
     3070
     3071  return S_OK;
     3072}
     3073
     3074/*************************************************************************
     3075 * PathRelativePathToA   [SHLWAPI.@]
     3076 *
     3077 * Create a relative path from one path to another.
     3078 *
     3079 * PARAMS
     3080 *  lpszPath   [O] Destination for relative path
     3081 *  lpszFrom   [I] Source path
     3082 *  dwAttrFrom [I] File attribute of source path
     3083 *  lpszTo     [I] Destination path
     3084 *  dwAttrTo   [I] File attributes of destination path
     3085 *
     3086 * RETURNS
     3087 *  TRUE  If a relative path can be formed. lpszPath contains the new path
     3088 *  FALSE If the paths are not relavtive or any parameters are invalid
     3089 *
     3090 * NOTES
     3091 *  lpszTo should be at least MAX_PATH in length.
     3092 *  Calling this function with relative paths for lpszFrom or lpszTo may
     3093 *  give erroneous results.
     3094 *
     3095 *  The Win32 version of this function contains a bug where the lpszTo string
     3096 *  may be referenced 1 byte beyond the end of the string. As a result random
     3097 *  garbage may be written to the output path, depending on what lies beyond
     3098 *  the last byte of the string. This bug occurs because of the behaviour of
     3099 *  PathCommonPrefix (see notes for that function), and no workaround seems
     3100 *  possible with Win32.
     3101 *  This bug has been fixed here, so for example the relative path from "\\"
     3102 *  to "\\" is correctly determined as "." in this implementation.
     3103 */
     3104BOOL WINAPI PathRelativePathToA(LPSTR lpszPath, LPCSTR lpszFrom, DWORD dwAttrFrom,
     3105                                LPCSTR lpszTo, DWORD dwAttrTo)
     3106{
     3107  BOOL bRet = FALSE;
     3108
     3109  TRACE("(%p,%s,0x%08lx,%s,0x%08lx)\n", lpszPath, debugstr_a(lpszFrom),
     3110        dwAttrFrom, debugstr_a(lpszTo), dwAttrTo);
     3111
     3112  if(lpszPath && lpszFrom && lpszTo)
     3113  {
     3114    WCHAR szPath[MAX_PATH];
     3115    WCHAR szFrom[MAX_PATH];
     3116    WCHAR szTo[MAX_PATH];
     3117    MultiByteToWideChar(0,0,lpszFrom,-1,szFrom,MAX_PATH);
     3118    MultiByteToWideChar(0,0,lpszTo,-1,szTo,MAX_PATH);
     3119    bRet = PathRelativePathToW(szPath,szFrom,dwAttrFrom,szTo,dwAttrTo);
     3120    WideCharToMultiByte(0,0,szPath,-1,lpszPath,MAX_PATH,0,0);
     3121  }
     3122  return bRet;
     3123}
     3124
     3125/*************************************************************************
     3126 * PathRelativePathToW   [SHLWAPI.@]
     3127 *
     3128 * See PathRelativePathToA.
     3129 */
     3130BOOL WINAPI PathRelativePathToW(LPWSTR lpszPath, LPCWSTR lpszFrom, DWORD dwAttrFrom,
     3131                                LPCWSTR lpszTo, DWORD dwAttrTo)
     3132{
     3133  static const WCHAR szPrevDirSlash[] = { '.', '.', '\\', '\0' };
     3134  static const WCHAR szPrevDir[] = { '.', '.', '\0' };
     3135  WCHAR szFrom[MAX_PATH];
     3136  WCHAR szTo[MAX_PATH];
     3137  DWORD dwLen;
     3138
     3139  TRACE("(%p,%s,0x%08lx,%s,0x%08lx)\n", lpszPath, debugstr_w(lpszFrom),
     3140        dwAttrFrom, debugstr_w(lpszTo), dwAttrTo);
     3141
     3142  if(!lpszPath || !lpszFrom || !lpszTo)
     3143    return FALSE;
     3144
     3145  *lpszPath = '\0';
     3146  strncpyW(szFrom, lpszFrom, MAX_PATH);
     3147  strncpyW(szTo, lpszTo, MAX_PATH);
     3148
     3149  if(!(dwAttrFrom & FILE_ATTRIBUTE_DIRECTORY))
     3150    PathRemoveFileSpecW(szFrom);
     3151  if(!(dwAttrFrom & FILE_ATTRIBUTE_DIRECTORY))
     3152    PathRemoveFileSpecW(szTo);
     3153
     3154  /* Paths can only be relative if they have a common root */
     3155  if(!(dwLen = PathCommonPrefixW(szFrom, szTo, 0)))
     3156    return FALSE;
     3157
     3158  /* Strip off lpszFrom components to the root, by adding "..\" */
     3159  lpszFrom = szFrom + dwLen;
     3160  if (!*lpszFrom)
     3161  {
     3162    lpszPath[0] = '.';
     3163    lpszPath[1] = '\0';
     3164  }
     3165  if (*lpszFrom == '\\')
     3166    lpszFrom++;
     3167
     3168  while (*lpszFrom)
     3169  {
     3170    lpszFrom = PathFindNextComponentW(lpszFrom);
     3171    strcatW(lpszPath, *lpszFrom ? szPrevDirSlash : szPrevDir);
     3172  }
     3173
     3174  /* From the root add the components of lpszTo */
     3175  lpszTo += dwLen;
     3176  /* We check lpszTo[-1] to avoid skipping end of string. See the notes for
     3177   * this function.
     3178   */
     3179  if (*lpszTo && lpszTo[-1])
     3180  {
     3181    if (*lpszTo != '\\')
     3182      lpszTo--;
     3183    dwLen = strlenW(lpszPath);
     3184    if (dwLen + strlenW(lpszTo) >= MAX_PATH)
     3185    {
     3186      *lpszPath = '\0';
     3187      return FALSE;
     3188    }
     3189    strcpyW(lpszPath + dwLen, lpszTo);
     3190  }
     3191  return TRUE;
     3192}
     3193
     3194/*************************************************************************
     3195 * PathUnmakeSystemFolderA   [SHLWAPI.@]
     3196 *
     3197 * Remove the system folder attributes from a path.
     3198 *
     3199 * PARAMS
     3200 *  lpszPath [I] The path to remove attributes from
     3201 *
     3202 * RETURNS
     3203 *  Success: TRUE.
     3204 *  Failure: FALSE, if lpszPath is NULL, empty, not a directory, or calling
     3205 *           SetFileAttributesA fails.
     3206 */
     3207BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR lpszPath)
     3208{
     3209  DWORD dwAttr;
     3210
     3211  TRACE("(%s)\n", debugstr_a(lpszPath));
     3212
     3213  if (!lpszPath || !*lpszPath || (dwAttr = GetFileAttributesA(lpszPath)) == -1 ||
     3214      !(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
     3215    return FALSE;
     3216
     3217  dwAttr &= ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
     3218  return SetFileAttributesA(lpszPath, dwAttr);
     3219}
     3220
     3221/*************************************************************************
     3222 * PathUnmakeSystemFolderW   [SHLWAPI.@]
     3223 *
     3224 * See PathUnmakeSystemFolderA.
     3225 */
     3226BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR lpszPath)
     3227{
     3228  DWORD dwAttr;
     3229
     3230  TRACE("(%s)\n", debugstr_w(lpszPath));
     3231
     3232  if (!lpszPath || !*lpszPath || (dwAttr = GetFileAttributesW(lpszPath)) == -1 ||
     3233    !(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
     3234    return FALSE;
     3235
     3236  dwAttr &= ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
     3237  return SetFileAttributesW(lpszPath, dwAttr);
     3238}
     3239
    18763240
    18773241/*************************************************************************
    18783242 * PathSetDlgItemPathA   [SHLWAPI.@]
    18793243 *
     3244 * Set the text of a dialog item to a path, shrinking the path to fit
     3245 * if it is too big for the item.
     3246 *
     3247 * PARAMS
     3248 *  hDlg     [I] Dialog handle
     3249 *  id       [I] ID of item in the dialog
     3250 *  lpszPath [I] Path to set as the items text
     3251 *
     3252 * RETURNS
     3253 *  Nothing.
     3254 *
    18803255 * NOTES
    1881  *  use PathCompactPath to make sure, the path fits into the control
    1882  */
    1883 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
    1884 {       TRACE("%x %x %s\n",hDlg, id, pszPath);
    1885         return SetDlgItemTextA(hDlg, id, pszPath);
     3256 *  If lpszPath is NULL, a blank string ("") is set (i.e. The previous
     3257 *  window text is erased).
     3258 */
     3259VOID WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR lpszPath)
     3260{
     3261  WCHAR szPath[MAX_PATH];
     3262
     3263  TRACE("(%8x,%8x,%s)\n",hDlg, id, debugstr_a(lpszPath));
     3264
     3265  if (lpszPath)
     3266    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
     3267  else
     3268    szPath[0] = '\0';
     3269  PathSetDlgItemPathW(hDlg, id, szPath);
    18863270}
    18873271
    18883272/*************************************************************************
    18893273 * PathSetDlgItemPathW   [SHLWAPI.@]
    1890  */
    1891 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
    1892 {       TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
    1893         return SetDlgItemTextW(hDlg, id, pszPath);
    1894 }
     3274 *
     3275 * See PathSetDlgItemPathA.
     3276 */
     3277VOID WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR lpszPath)
     3278{
     3279  WCHAR path[MAX_PATH + 1];
     3280  HWND hwItem;
     3281  RECT rect;
     3282  HDC hdc;
     3283  HGDIOBJ hPrevObj;
     3284
     3285  TRACE("(%8x,%8x,%s)\n",hDlg, id, debugstr_w(lpszPath));
     3286
     3287  if (!(hwItem = GetDlgItem(hDlg, id)))
     3288    return;
     3289
     3290  if (lpszPath)
     3291    strncpyW(path, lpszPath, sizeof(path));
     3292  else
     3293    path[0] = '\0';
     3294
     3295  GetClientRect(hwItem, &rect);
     3296  hdc = GetDC(hDlg);
     3297  hPrevObj = SelectObject(hdc, (HGDIOBJ)SendMessageW(hwItem,WM_GETFONT,0,0));
     3298
     3299  if (hPrevObj)
     3300  {
     3301    PathCompactPathW(hdc, path, rect.right);
     3302    SelectObject(hdc, hPrevObj);
     3303  }
     3304
     3305  ReleaseDC(hDlg, hdc);
     3306  SetWindowTextW(hwItem, path);
     3307}
     3308
     3309/*************************************************************************
     3310 * PathIsNetworkPathA [SHLWAPI.@]
     3311 *
     3312 * Determine if the given path is a network path.
     3313 *
     3314 * PARAMS
     3315 *  lpszPath [I] Path to check
     3316 *
     3317 * RETURNS
     3318 *  TRUE  If path is a UNC share or mapped network drive
     3319 *  FALSE If path is a local drive or cannot be determined
     3320 */
     3321BOOL WINAPI PathIsNetworkPathA(LPCSTR lpszPath)
     3322{
     3323  DWORD dwDriveNum;
     3324
     3325  TRACE("(%s)\n",debugstr_a(lpszPath));
     3326
     3327  if (!lpszPath)
     3328    return FALSE;
     3329  if (*lpszPath == '\\' && lpszPath[1] == '\\')
     3330    return TRUE;
     3331  dwDriveNum = PathGetDriveNumberA(lpszPath);
     3332  if (dwDriveNum == -1)
     3333    return FALSE;
     3334  GET_FUNC(pIsNetDrive, shell32, (LPCSTR)66, FALSE); /* ord 66 = shell32.IsNetDrive */
     3335  return pIsNetDrive(dwDriveNum);
     3336}
     3337
     3338/*************************************************************************
     3339 * PathIsNetworkPathW [SHLWAPI.@]
     3340 *
     3341 * See PathIsNetworkPathA.
     3342 */
     3343BOOL WINAPI PathIsNetworkPathW(LPCWSTR lpszPath)
     3344{
     3345  DWORD dwDriveNum;
     3346
     3347  TRACE("(%s)\n", debugstr_w(lpszPath));
     3348
     3349  if (!lpszPath)
     3350    return FALSE;
     3351  if (*lpszPath == '\\' && lpszPath[1] == '\\')
     3352    return TRUE;
     3353  dwDriveNum = PathGetDriveNumberW(lpszPath);
     3354  if (dwDriveNum == -1)
     3355    return FALSE;
     3356  GET_FUNC(pIsNetDrive, shell32, (LPCSTR)66, FALSE); /* ord 66 = shell32.IsNetDrive */
     3357  return pIsNetDrive(dwDriveNum);
     3358}
     3359
     3360/*************************************************************************
     3361 * PathIsLFNFileSpecA [SHLWAPI.@]
     3362 *
     3363 * Determine if the given path is a long file name
     3364 *
     3365 * PARAMS
     3366 *  lpszPath [I] Path to check
     3367 *
     3368 * RETURNS
     3369 *  TRUE  If path is a long file name
     3370 *  FALSE If path is a valid DOS 8.3 file name
     3371 */
     3372BOOL WINAPI PathIsLFNFileSpecA(LPCSTR lpszPath)
     3373{
     3374  DWORD dwNameLen = 0, dwExtLen = 0;
     3375
     3376  TRACE("(%s)\n",debugstr_a(lpszPath));
     3377
     3378  if (!lpszPath)
     3379    return FALSE;
     3380
     3381  while (*lpszPath)
     3382  {
     3383    if (*lpszPath == ' ')
     3384      return TRUE; /* DOS names cannot have spaces */
     3385    if (*lpszPath == '.')
     3386    {
     3387      if (dwExtLen)
     3388        return TRUE; /* DOS names have only one dot */
     3389      dwExtLen = 1;
     3390    }
     3391    else if (dwExtLen)
     3392    {
     3393      dwExtLen++;
     3394      if (dwExtLen > 4)
     3395        return TRUE; /* DOS extensions are <= 3 chars*/
     3396    }
     3397    else
     3398    {
     3399      dwNameLen++;
     3400      if (dwNameLen > 8)
     3401        return TRUE; /* DOS names are <= 8 chars */
     3402    }
     3403    lpszPath += IsDBCSLeadByte(*lpszPath) ? 2 : 1;
     3404  }
     3405  return FALSE; /* Valid DOS path */
     3406}
     3407
     3408/*************************************************************************
     3409 * PathIsLFNFileSpecW [SHLWAPI.@]
     3410 *
     3411 * See PathIsLFNFileSpecA.
     3412 */
     3413BOOL WINAPI PathIsLFNFileSpecW(LPCWSTR lpszPath)
     3414{
     3415  DWORD dwNameLen = 0, dwExtLen = 0;
     3416
     3417  TRACE("(%s)\n",debugstr_w(lpszPath));
     3418
     3419  if (!lpszPath)
     3420    return FALSE;
     3421
     3422  while (*lpszPath)
     3423  {
     3424    if (*lpszPath == ' ')
     3425      return TRUE; /* DOS names cannot have spaces */
     3426    if (*lpszPath == '.')
     3427    {
     3428      if (dwExtLen)
     3429        return TRUE; /* DOS names have only one dot */
     3430      dwExtLen = 1;
     3431    }
     3432    else if (dwExtLen)
     3433    {
     3434      dwExtLen++;
     3435      if (dwExtLen > 4)
     3436        return TRUE; /* DOS extensions are <= 3 chars*/
     3437    }
     3438    else
     3439    {
     3440      dwNameLen++;
     3441      if (dwNameLen > 8)
     3442        return TRUE; /* DOS names are <= 8 chars */
     3443    }
     3444    lpszPath++;
     3445  }
     3446  return FALSE; /* Valid DOS path */
     3447}
     3448
     3449/*************************************************************************
     3450 * PathIsDirectoryEmptyA [SHLWAPI.@]
     3451 *
     3452 * Determine if a given directory is empty.
     3453 *
     3454 * PARAMS
     3455 *  lpszPath [I] Directory to check
     3456 *
     3457 * RETURNS
     3458 *  TRUE  If the directory exists and contains no files
     3459 *  FALSE Otherwise
     3460 */
     3461BOOL WINAPI PathIsDirectoryEmptyA(LPCSTR lpszPath)
     3462{
     3463  BOOL bRet = FALSE;
     3464
     3465  TRACE("(%s)\n",debugstr_a(lpszPath));
     3466
     3467  if (lpszPath)
     3468  {
     3469    WCHAR szPath[MAX_PATH];
     3470    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
     3471    bRet = PathIsDirectoryEmptyW(szPath);
     3472  }
     3473  return bRet;
     3474}
     3475
     3476/*************************************************************************
     3477 * PathIsDirectoryEmptyW [SHLWAPI.@]
     3478 *
     3479 * See PathIsDirectoryEmptyA.
     3480 */
     3481BOOL WINAPI PathIsDirectoryEmptyW(LPCWSTR lpszPath)
     3482{
     3483  static const WCHAR szAllFiles[] = { '*', '.', '*', '\0' };
     3484  WCHAR szSearch[MAX_PATH];
     3485  DWORD dwLen;
     3486  HANDLE hfind;
     3487  BOOL retVal = FALSE;
     3488  WIN32_FIND_DATAW find_data;
     3489
     3490  TRACE("(%s)\n",debugstr_w(lpszPath));
     3491
     3492  if (!lpszPath || !PathIsDirectoryW(lpszPath))
     3493      return FALSE;
     3494
     3495  strncpyW(szSearch, lpszPath, MAX_PATH);
     3496  PathAddBackslashW(szSearch);
     3497  dwLen = strlenW(szSearch);
     3498  if (dwLen > MAX_PATH - 4)
     3499    return FALSE;
     3500
     3501  strcpyW(szSearch + dwLen, szAllFiles);
     3502  hfind = FindFirstFileW(szSearch, &find_data);
     3503
     3504  if (hfind != INVALID_HANDLE_VALUE &&
     3505      find_data.cFileName[0] == '.' &&
     3506      find_data.cFileName[1] == '.')
     3507  {
     3508    /* The only directory entry should be the parent */
     3509    if (!FindNextFileW(hfind, &find_data))
     3510      retVal = TRUE;
     3511    FindClose(hfind);
     3512  }
     3513  return retVal;
     3514}
     3515
     3516
     3517/*************************************************************************
     3518 * PathFindSuffixArrayA [SHLWAPI.@]
     3519 *
     3520 * Find a suffix string in an array of suffix strings
     3521 *
     3522 * PARAMS
     3523 *  lpszSuffix [I] Suffix string to search for
     3524 *  lppszArray [I] Array of suffix strings to search
     3525 *  dwCount    [I] Number of elements in lppszArray
     3526 *
     3527 * RETURNS
     3528 *  Success The index of the position of lpszSuffix in lppszArray
     3529 *  Failure 0, if any parameters are invalid or lpszSuffix is not found
     3530 *
     3531 * NOTES
     3532 *  The search is case sensitive.
     3533 *  The match is made against the end of the suffix string, so for example:
     3534 *  lpszSuffix=fooBAR matches BAR, but lpszSuffix=fooBARfoo does not.
     3535 */
     3536int WINAPI PathFindSuffixArrayA(LPCSTR lpszSuffix, LPCSTR *lppszArray, int dwCount)
     3537{
     3538  DWORD dwLen;
     3539  int dwRet = 0;
     3540
     3541  TRACE("(%s,%p,%d)\n",debugstr_a(lpszSuffix), lppszArray, dwCount);
     3542
     3543  if (lpszSuffix && lppszArray && dwCount > 0)
     3544  {
     3545    dwLen = strlen(lpszSuffix);
     3546
     3547    while (dwRet < dwCount)
     3548    {
     3549      DWORD dwCompareLen = strlen(*lppszArray);
     3550      if (dwCompareLen < dwLen)
     3551      {
     3552        if (!strcmp(lpszSuffix + dwLen - dwCompareLen, *lppszArray))
     3553          return dwRet; /* Found */
     3554      }
     3555      dwRet++;
     3556      lppszArray++;
     3557    }
     3558  }
     3559  return 0;
     3560}
     3561
     3562/*************************************************************************
     3563 * PathFindSuffixArrayW [SHLWAPI.@]
     3564 *
     3565 * See PathFindSuffixArrayA.
     3566 */
     3567int WINAPI PathFindSuffixArrayW(LPCWSTR lpszSuffix, LPCWSTR *lppszArray, int dwCount)
     3568{
     3569  DWORD dwLen;
     3570  int dwRet = 0;
     3571
     3572  TRACE("(%s,%p,%d)\n",debugstr_w(lpszSuffix), lppszArray, dwCount);
     3573
     3574  if (lpszSuffix && lppszArray && dwCount > 0)
     3575  {
     3576    dwLen = strlenW(lpszSuffix);
     3577
     3578    while (dwRet < dwCount)
     3579    {
     3580      DWORD dwCompareLen = strlenW(*lppszArray);
     3581      if (dwCompareLen < dwLen)
     3582      {
     3583        if (!strcmpW(lpszSuffix + dwLen - dwCompareLen, *lppszArray))
     3584          return dwRet; /* Found */
     3585      }
     3586      dwRet++;
     3587      lppszArray++;
     3588    }
     3589  }
     3590  return 0;
     3591}
     3592
     3593/*************************************************************************
     3594 * PathUndecorateA [SHLWAPI.@]
     3595 *
     3596 * Undecorate a file path
     3597 *
     3598 * PARAMS
     3599 *  lpszPath [O] Path to undecorate
     3600 *
     3601 * RETURNS
     3602 *  Nothing
     3603 *
     3604 * NOTES
     3605 *  A decorations form is "path[n].ext" where n is an optional decimal number.
     3606 */
     3607VOID WINAPI PathUndecorateA(LPSTR lpszPath)
     3608{
     3609  TRACE("(%s)\n",debugstr_a(lpszPath));
     3610
     3611  if (lpszPath)
     3612  {
     3613    LPSTR lpszExt = PathFindExtensionA(lpszPath);
     3614    if (lpszExt > lpszPath && lpszExt[-1] == ']')
     3615    {
     3616      LPSTR lpszSkip = lpszExt - 2;
     3617      if (*lpszSkip == '[')
     3618        lpszSkip++;  /* [] (no number) */
     3619      else
     3620        while (lpszSkip > lpszPath && isdigit(lpszSkip[-1]))
     3621          lpszSkip--;
     3622      if (lpszSkip > lpszPath && lpszSkip[-1] == '[' && lpszSkip[-2] != '\\')
     3623      {
     3624        /* remove the [n] */
     3625        lpszSkip--;
     3626        while (*lpszExt)
     3627          *lpszSkip++ = *lpszExt++;
     3628        *lpszSkip = '\0';
     3629      }
     3630    }
     3631  }
     3632}
     3633
     3634/*************************************************************************
     3635 * PathUndecorateW [SHLWAPI.@]
     3636 *
     3637 * See PathUndecorateA.
     3638 */
     3639VOID WINAPI PathUndecorateW(LPWSTR lpszPath)
     3640{
     3641  TRACE("(%s)\n",debugstr_w(lpszPath));
     3642
     3643  if (lpszPath)
     3644  {
     3645    LPWSTR lpszExt = PathFindExtensionW(lpszPath);
     3646    if (lpszExt > lpszPath && lpszExt[-1] == ']')
     3647    {
     3648      LPWSTR lpszSkip = lpszExt - 2;
     3649      if (*lpszSkip == '[')
     3650        lpszSkip++; /* [] (no number) */
     3651      else
     3652        while (lpszSkip > lpszPath && isdigitW(lpszSkip[-1]))
     3653          lpszSkip--;
     3654      if (lpszSkip > lpszPath && lpszSkip[-1] == '[' && lpszSkip[-2] != '\\')
     3655      {
     3656        /* remove the [n] */
     3657        lpszSkip--;
     3658        while (*lpszExt)
     3659          *lpszSkip++ = *lpszExt++;
     3660        *lpszSkip = '\0';
     3661      }
     3662    }
     3663  }
     3664}
  • trunk/src/shlwapi/reg.c

    r7820 r8584  
    11/*
    22 * SHLWAPI registry functions
     3 *
     4 * Copyright 1998 Juergen Schmied
     5 * Copyright 2001 Guy Albertelli
     6 *
     7 * This library is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU Lesser General Public
     9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * This library is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with this library; if not, write to the Free Software
     19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    320 */
    421
     
    1128#include "winnls.h"
    1229#include "winreg.h"
    13 #include "debugtools.h"
     30#include "wine/debug.h"
    1431#define NO_SHLWAPI_STREAM
    1532#include "shlwapi.h"
    1633#include "wine/unicode.h"
    1734
    18 DEFAULT_DEBUG_CHANNEL(shell);
    19 
    20 #ifdef __WIN32OS2__
    21 typedef DWORD (* WINAPI RegQueryFn)(HKEY,LPCVOID,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
    22 #else
    23 typedef DWORD (WINAPI *RegQueryFn)(HKEY,LPCVOID,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
    24 #endif
     35WINE_DEFAULT_DEBUG_CHANNEL(shell);
    2536
    2637static const char *lpszContentTypeA = "Content Type";
     
    8293    LPInternal_HUSKEY ihky;
    8394
    84     TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_a(Path), 
    85           (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey, 
     95    TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_a(Path),
     96          (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey,
    8697          (fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM");
    8798
    8899    /* now create the internal version of HUSKEY */
    89     ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 , 
     100    ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 ,
    90101                                        sizeof(Internal_HUSKEY));
    91102    MultiByteToWideChar(0, 0, Path, -1, ihky->key_string,
     
    104115    ihky->HKLMkey = 0;
    105116    if (!fIgnoreHKCU) {
    106         ret1 = RegOpenKeyExA(openHKCUkey, Path, 
     117        ret1 = RegOpenKeyExA(openHKCUkey, Path,
    107118                             0, AccessType, &ihky->HKCUkey);
    108119        /* if successful, then save real starting point */
     
    110121            ihky->HKCUkey = 0;
    111122    }
    112     ret2 = RegOpenKeyExA(openHKLMkey, Path, 
     123    ret2 = RegOpenKeyExA(openHKLMkey, Path,
    113124                         0, AccessType, &ihky->HKLMkey);
    114125    if (ret2 != ERROR_SUCCESS)
     
    149160    LPInternal_HUSKEY ihky;
    150161
    151     TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_w(Path), 
    152           (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey, 
     162    TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_w(Path),
     163          (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey,
    153164          (fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM");
    154165
    155166    /* now create the internal version of HUSKEY */
    156     ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 , 
     167    ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 ,
    157168                                        sizeof(Internal_HUSKEY));
    158169    lstrcpynW(ihky->key_string, Path, sizeof(ihky->key_string));
     
    170181    ihky->HKLMkey = 0;
    171182    if (!fIgnoreHKCU) {
    172         ret1 = RegOpenKeyExW(openHKCUkey, Path, 
     183        ret1 = RegOpenKeyExW(openHKCUkey, Path,
    173184                            0, AccessType, &ihky->HKCUkey);
    174185        /* if successful, then save real starting point */
     
    176187            ihky->HKCUkey = 0;
    177188    }
    178     ret2 = RegOpenKeyExW(openHKLMkey, Path, 
     189    ret2 = RegOpenKeyExW(openHKLMkey, Path,
    179190                        0, AccessType, &ihky->HKLMkey);
    180191    if (ret2 != ERROR_SUCCESS)
     
    401412
    402413        datalen = sizeof(data)-1;
    403         if (!(retvalue = SHRegGetUSValueA( pszSubKey, pszValue, &type, 
     414        if (!(retvalue = SHRegGetUSValueA( pszSubKey, pszValue, &type,
    404415                                           data, &datalen,
    405416                                           fIgnoreHKCU, 0, 0))) {
     
    460471
    461472        datalen = (sizeof(data)-1) * sizeof(WCHAR);
    462         if (!(retvalue = SHRegGetUSValueW( pszSubKey, pszValue, &type, 
     473        if (!(retvalue = SHRegGetUSValueW( pszSubKey, pszValue, &type,
    463474                                           data, &datalen,
    464475                                           fIgnoreHKCU, 0, 0))) {
     
    522533                                   pcValues, pcchMaxValueNameLen, 0, 0, 0);
    523534            if ((ret == ERROR_SUCCESS) ||
    524                 (enumRegFlags == SHREGENUM_HKCU)) 
     535                (enumRegFlags == SHREGENUM_HKCU))
    525536                return ret;
    526537        }
    527538        if (((enumRegFlags == SHREGENUM_HKLM) ||
    528              (enumRegFlags == SHREGENUM_DEFAULT)) && 
     539             (enumRegFlags == SHREGENUM_DEFAULT)) &&
    529540            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
    530541            return RegQueryInfoKeyA(dokey, 0, 0, 0,
     
    555566        /* if user wants HKCU, and it exists, then try it */
    556567        if (((enumRegFlags == SHREGENUM_HKCU) ||
    557              (enumRegFlags == SHREGENUM_DEFAULT)) && 
     568             (enumRegFlags == SHREGENUM_DEFAULT)) &&
    558569            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
    559570            ret = RegQueryInfoKeyW(dokey, 0, 0, 0,
     
    561572                                   pcValues, pcchMaxValueNameLen, 0, 0, 0);
    562573            if ((ret == ERROR_SUCCESS) ||
    563                 (enumRegFlags == SHREGENUM_HKCU)) 
     574                (enumRegFlags == SHREGENUM_HKCU))
    564575                return ret;
    565576        }
    566577        if (((enumRegFlags == SHREGENUM_HKLM) ||
    567              (enumRegFlags == SHREGENUM_DEFAULT)) && 
     578             (enumRegFlags == SHREGENUM_DEFAULT)) &&
    568579            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
    569580            return RegQueryInfoKeyW(dokey, 0, 0, 0,
     
    591602
    592603        if (((enumRegFlags == SHREGENUM_HKCU) ||
    593              (enumRegFlags == SHREGENUM_DEFAULT)) && 
     604             (enumRegFlags == SHREGENUM_DEFAULT)) &&
    594605            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
    595             return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen, 
     606            return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen,
    596607                                0, 0, 0, 0);
    597608        }
    598609
    599610        if (((enumRegFlags == SHREGENUM_HKLM) ||
    600              (enumRegFlags == SHREGENUM_DEFAULT)) && 
     611             (enumRegFlags == SHREGENUM_DEFAULT)) &&
    601612            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
    602613            return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen,
     
    624635
    625636        if (((enumRegFlags == SHREGENUM_HKCU) ||
    626              (enumRegFlags == SHREGENUM_DEFAULT)) && 
     637             (enumRegFlags == SHREGENUM_DEFAULT)) &&
    627638            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
    628639            return RegEnumKeyExW(dokey, dwIndex, pszName, pcchValueNameLen,
     
    646657                                LPVOID pvData, DWORD cbData, DWORD dwFlags)
    647658{
    648     FIXME("(0x%lx,%s,%ld,%p,%ld,%ld): stub\n",
     659    HKEY dokey;
     660
     661    TRACE("(0x%lx,%s,%ld,%p,%ld,%ld)\n",
    649662          (LONG)hUSKey, debugstr_a(pszValue), dwType, pvData, cbData, dwFlags);
     663
     664    if ((dwFlags & SHREGSET_FORCE_HKCU) &&
     665            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
     666        RegSetValueExA(dokey, pszValue, 0, dwType, pvData, cbData);
     667    }
     668
     669    if ((dwFlags & SHREGSET_FORCE_HKLM) &&
     670            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
     671        RegSetValueExA(dokey, pszValue, 0, dwType, pvData, cbData);
     672    }
     673
     674    if (dwFlags & (SHREGSET_FORCE_HKCU | SHREGSET_FORCE_HKLM))
     675        return ERROR_SUCCESS;
     676
     677    FIXME("SHREGSET_HKCU or SHREGSET_HKLM not supported\n");
    650678    return ERROR_SUCCESS;
    651679}
     
    657685                                LPVOID pvData, DWORD cbData, DWORD dwFlags)
    658686{
    659     FIXME("(0x%lx,%s,%ld,%p,%ld,%ld): stub\n",
     687    HKEY dokey;
     688
     689    TRACE("(0x%lx,%s,%ld,%p,%ld,%ld)\n",
    660690          (LONG)hUSKey, debugstr_w(pszValue), dwType, pvData, cbData, dwFlags);
     691
     692    if ((dwFlags & SHREGSET_FORCE_HKCU) &&
     693            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
     694        RegSetValueExW(dokey, pszValue, 0, dwType, pvData, cbData);
     695    }
     696
     697    if ((dwFlags & SHREGSET_FORCE_HKLM) &&
     698            (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
     699        RegSetValueExW(dokey, pszValue, 0, dwType, pvData, cbData);
     700    }
     701
     702    if (dwFlags & (SHREGSET_FORCE_HKCU | SHREGSET_FORCE_HKLM))
     703        return ERROR_SUCCESS;
     704
     705    FIXME("SHREGSET_HKCU or SHREGSET_HKLM not supported\n");
    661706    return ERROR_SUCCESS;
    662707}
     
    681726                           LPSTR lpszPath, DWORD dwFlags)
    682727{
    683   HKEY hSubKey;
    684   DWORD dwType = REG_SZ, dwSize = MAX_PATH, dwRet = ERROR_SUCCESS;
     728  DWORD dwSize = MAX_PATH;
    685729
    686730  TRACE("(hkey=0x%08x,%s,%s,%p,%ld)\n", hKey, debugstr_a(lpszSubKey),
    687731        debugstr_a(lpszValue), lpszPath, dwFlags);
    688732
    689   if (lpszSubKey && *lpszSubKey)
    690     dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
    691   else
    692     hSubKey = hKey;
    693 
    694   if (!dwRet)
    695     dwRet = SHQueryValueExA(hSubKey, lpszValue, NULL, &dwType, lpszPath, &dwSize);
    696 
    697   if (hSubKey != hKey)
    698     RegCloseKey(hSubKey);
    699 
    700   return dwRet;
     733  return SHGetValueA(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize);
    701734}
    702735
     
    709742                           LPWSTR lpszPath, DWORD dwFlags)
    710743{
    711   HKEY hSubKey;
    712   DWORD dwType = REG_SZ, dwSize = MAX_PATH, dwRet = ERROR_SUCCESS;
     744  DWORD dwSize = MAX_PATH;
    713745
    714746  TRACE("(hkey=0x%08x,%s,%s,%p,%ld)\n", hKey, debugstr_w(lpszSubKey),
    715747        debugstr_w(lpszValue), lpszPath, dwFlags);
    716748
    717   if (lpszSubKey && *lpszSubKey)
    718     dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
    719   else
    720     hSubKey = hKey;
    721 
    722   if (!dwRet)
    723     dwRet = SHQueryValueExW(hSubKey, lpszValue, NULL, &dwType, lpszPath, &dwSize);
    724 
    725   if (hSubKey != hKey)
    726     RegCloseKey(hSubKey);
    727 
    728   return dwRet;
     749  return SHGetValueW(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize);
    729750}
    730751
     
    751772  char szBuff[MAX_PATH];
    752773
    753   FIXME("(hkey=0x%08x,%s,%s,%p,%ld) - semi-stub",hKey, debugstr_a(lpszSubKey),
     774  FIXME("(hkey=0x%08x,%s,%s,%p,%ld) - semi-stub\n",hKey, debugstr_a(lpszSubKey),
    754775        debugstr_a(lpszValue), lpszPath, dwFlags);
    755776
     
    772793  WCHAR szBuff[MAX_PATH];
    773794
    774   FIXME("(hkey=0x%08x,%s,%s,%p,%ld) - semi-stub",hKey, debugstr_w(lpszSubKey),
     795  FIXME("(hkey=0x%08x,%s,%s,%p,%ld) - semi-stub\n",hKey, debugstr_w(lpszSubKey),
    775796        debugstr_w(lpszValue), lpszPath, dwFlags);
    776797
     
    798819 * RETURNS
    799820 *   Success: ERROR_SUCCESS. Output parameters contain the details read.
    800  *   Failure: An error code from RegOpenKeyExA or RegQueryValueExA.
     821 *   Failure: An error code from RegOpenKeyExA or SHQueryValueExA.
    801822 */
    802823DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
    803824                         LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
    804825{
    805   DWORD dwRet;
    806   HKEY hSubKey;
     826  DWORD dwRet = 0;
     827  HKEY hSubKey = 0;
    807828
    808829  TRACE("(hkey=0x%08x,%s,%s,%p,%p,%p)\n", hKey, debugstr_a(lpszSubKey),
    809830        debugstr_a(lpszValue), pwType, pvData, pcbData);
    810831
    811   dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
    812   if (!dwRet)
     832  /*   lpszSubKey can be 0. In this case the value is taken from the
     833   *   current key.
     834   */
     835  if(lpszSubKey)
     836    dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
     837
     838  if (! dwRet)
    813839  {
    814     dwRet = RegQueryValueExA(hSubKey, lpszValue, 0, pwType, pvData, pcbData);
    815     RegCloseKey(hSubKey);
     840    /* SHQueryValueEx expands Environment strings */
     841    dwRet = SHQueryValueExA(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
     842    if (hSubKey) RegCloseKey(hSubKey);
    816843  }
    817844  return dwRet;
     
    826853                         LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
    827854{
    828   DWORD dwRet;
    829   HKEY hSubKey;
     855  DWORD dwRet = 0;
     856  HKEY hSubKey = 0;
    830857
    831858  TRACE("(hkey=0x%08x,%s,%s,%p,%p,%p)\n", hKey, debugstr_w(lpszSubKey),
    832859        debugstr_w(lpszValue), pwType, pvData, pcbData);
    833860
    834   dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
    835   if (!dwRet)
     861  if(lpszSubKey)
     862    dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
     863
     864  if (! dwRet)
    836865  {
    837     dwRet = RegQueryValueExW(hSubKey, lpszValue, 0, pwType, pvData, pcbData);
    838     RegCloseKey(hSubKey);
     866    dwRet = SHQueryValueExW(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
     867    if (hSubKey) RegCloseKey(hSubKey);
    839868  }
    840869  return dwRet;
     
    944973}
    945974
    946 /*************************************************************************
    947  * SHQueryValueExAW
    948  *
    949  * Internal implementation of SHQueryValueExA/SHQueryValueExW.
    950  */
    951 static DWORD WINAPI SHQueryValueExAW(RegQueryFn pfn,
    952                                      HKEY hKey, LPCVOID lpszValue,
    953                                      LPDWORD lpReserved, LPDWORD pwType,
    954                                      LPBYTE pvData, LPDWORD pcbData)
    955 {
     975/*
    956976  DWORD dwRet, dwType, dwDataLen;
    957977
    958   if (pcbData)
    959     dwDataLen = *pcbData;
    960 
    961   dwRet = pfn(hKey, lpszValue, lpReserved, &dwType, pvData, &dwDataLen);
     978  FIXME("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_a(lpszValue),
     979        lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
     980
     981  if (pcbData) dwDataLen = *pcbData;
     982
     983  dwRet = RegQueryValueExA(hKey, lpszValue, lpReserved, &dwType, pvData, &dwDataLen);
    962984  if (!dwRet)
    963985  {
    964986    if (dwType == REG_EXPAND_SZ)
    965987    {
    966       /* Expand type REG_EXPAND_SZ into REG_SZ */
    967988      LPSTR szExpand;
    968989      LPBYTE pData = pvData;
     
    970991      if (!pData)
    971992      {
    972         /* Create a buffer to hold the data, to get the size */
    973         if (!pcbData ||
    974             !(pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pcbData)))
     993        if (!pcbData || !(pData = (LPBYTE) LocalAlloc(GMEM_ZEROINIT, *pcbData)))
    975994          return ERROR_OUTOFMEMORY;
    976         /* Read the data in to the buffer */
    977         if ((dwRet = pfn(hKey, lpszValue, lpReserved, &dwType,
    978                          pData, &dwDataLen)))
     995
     996        if ((dwRet = RegQueryValueExA (hKey, lpszValue, lpReserved, &dwType, pData, &dwDataLen)))
    979997          return dwRet;
    980998      }
     
    9821000      if (!pcbData && pData != pvData)
    9831001      {
    984         /* Note: In this case the caller will crash under Win32 */
    985         WARN("Invalid pcbData would crash under Win32!");
     1002        WARN("Invalid pcbData would crash under Win32!\n");
    9861003        return ERROR_OUTOFMEMORY;
    9871004      }
    9881005
    989       szExpand = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pcbData);
     1006      szExpand = (LPBYTE) LocalAlloc(GMEM_ZEROINIT, *pcbData);
    9901007      if (!szExpand)
    9911008      {
    992         if (pData != pvData)
    993           HeapFree(GetProcessHeap(), 0, pData);
     1009        if ( pData != pvData ) LocalFree((HLOCAL)pData);
    9941010        return ERROR_OUTOFMEMORY;
    9951011      }
    996       if ((ExpandEnvironmentStringsA(pvData, szExpand, *pcbData) <= 0))
     1012      if ((ExpandEnvironmentStringsA(pvData, szExpand, *pcbData) > 0))
    9971013      {
    9981014        dwDataLen = strlen(szExpand) + 1;
     
    10011017      else
    10021018      {
    1003         if (pData != pvData)
    1004           HeapFree(GetProcessHeap(), 0, pData);
    1005         HeapFree(GetProcessHeap(), 0, szExpand);
     1019        if ( pData != pvData ) LocalFree((HLOCAL)pData);
     1020        LocalFree((HLOCAL)szExpand);
    10061021        return GetLastError();
    10071022      }
    1008       if (pData != pvData)
    1009         HeapFree(GetProcessHeap(), 0, pData);
    1010       HeapFree(GetProcessHeap(), 0, szExpand);
     1023      if (pData != pvData) LocalFree((HLOCAL)pData);
     1024      LocalFree((HLOCAL)szExpand);
    10111025      dwType = REG_SZ;
    10121026    }
    10131027    if (dwType == REG_SZ && pvData && pcbData && dwDataLen >= *pcbData)
    10141028    {
    1015       /* String type too long: truncate it */
    1016       pvData[*pcbData] = '\0';
     1029      ((LPBYTE) pvData)[*pcbData] = '\0';
    10171030    }
    10181031  }
    1019   /* Update the type and data size if the caller wanted them */
    1020   if (pwType)
    1021     *pwType = dwType;
    1022   if (pcbData)
    1023     *pcbData  = dwDataLen;
     1032  if ( pwType ) *pwType = dwType;
     1033  if ( pcbData ) *pcbData = dwDataLen;
    10241034  return dwRet;
    1025 }
     1035*/
    10261036
    10271037/*************************************************************************
     
    10321042 * PARAMS
    10331043 *   hKey       [I] Handle to registry key
    1034  *   lpszValue  [I] Name of value to delete
     1044 *   lpszValue  [I] Name of value to query
    10351045 *   lpReserved [O] Reserved for future use; must be NULL
    10361046 *   pwType     [O] Optional pointer updated with the values type
     
    10531063 *   the buffer given to store it.
    10541064 */
    1055 DWORD WINAPI SHQueryValueExA(HKEY hKey, LPCSTR lpszValue,
    1056                              LPDWORD lpReserved, LPDWORD pwType,
    1057                              LPVOID pvData, LPDWORD pcbData)
    1058 {
     1065DWORD WINAPI SHQueryValueExA( HKEY hKey, LPCSTR lpszValue,
     1066                              LPDWORD lpReserved, LPDWORD pwType,
     1067                              LPVOID pvData, LPDWORD pcbData)
     1068{
     1069  DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen;
     1070
    10591071  TRACE("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_a(lpszValue),
    10601072        lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
    10611073
    1062   return SHQueryValueExAW((RegQueryFn)RegQueryValueExA, hKey, lpszValue,
    1063                           lpReserved, pwType, pvData, pcbData);
    1064 }
     1074  if (pcbData) dwUnExpDataLen = *pcbData;
     1075
     1076  dwRet = RegQueryValueExA(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen);
     1077
     1078  if (pcbData && (dwType == REG_EXPAND_SZ))
     1079  {
     1080    DWORD nBytesToAlloc;
     1081
     1082    /* Expand type REG_EXPAND_SZ into REG_SZ */
     1083    LPSTR szData;
     1084
     1085    /* If the caller didn't supply a buffer or the buffer is to small we have
     1086     * to allocate our own
     1087     */
     1088    if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
     1089    {
     1090      char cNull = '\0';
     1091      nBytesToAlloc = (!pvData || (dwRet == ERROR_MORE_DATA)) ? dwUnExpDataLen : *pcbData;
     1092
     1093      szData = (LPSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc);
     1094      RegQueryValueExA (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
     1095      dwExpDataLen = ExpandEnvironmentStringsA(szData, &cNull, 1);
     1096      dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
     1097      LocalFree((HLOCAL) szData);
     1098    }
     1099    else
     1100    {
     1101      nBytesToAlloc = lstrlenA(pvData) * sizeof (CHAR);
     1102      szData = (LPSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc + 1);
     1103      lstrcpyA(szData, pvData);
     1104      dwExpDataLen = ExpandEnvironmentStringsA(szData, pvData, *pcbData / sizeof(CHAR));
     1105      if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
     1106      dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
     1107      LocalFree((HLOCAL) szData);
     1108    }
     1109  }
     1110
     1111  /* Update the type and data size if the caller wanted them */
     1112  if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ;
     1113  if ( pwType ) *pwType = dwType;
     1114  if ( pcbData ) *pcbData = dwUnExpDataLen;
     1115  return dwRet;
     1116}
     1117
    10651118
    10661119/*************************************************************************
     
    10731126                             LPVOID pvData, LPDWORD pcbData)
    10741127{
     1128  DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen;
     1129
    10751130  TRACE("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_w(lpszValue),
    10761131        lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
    10771132
    1078   return SHQueryValueExAW((RegQueryFn)RegQueryValueExW, hKey, lpszValue,
    1079                           lpReserved, pwType, pvData, pcbData);
     1133  if (pcbData) dwUnExpDataLen = *pcbData;
     1134
     1135  dwRet = RegQueryValueExW(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen);
     1136
     1137  if (pcbData && (dwType == REG_EXPAND_SZ))
     1138  {
     1139    DWORD nBytesToAlloc;
     1140
     1141    /* Expand type REG_EXPAND_SZ into REG_SZ */
     1142    LPWSTR szData;
     1143
     1144    /* If the caller didn't supply a buffer or the buffer is to small we have
     1145     * to allocate our own
     1146     */
     1147    if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
     1148    {
     1149      WCHAR cNull = '\0';
     1150      nBytesToAlloc = (!pvData || (dwRet == ERROR_MORE_DATA)) ? dwUnExpDataLen : *pcbData;
     1151
     1152      szData = (LPWSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc);
     1153      RegQueryValueExW (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
     1154      dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1);
     1155      dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
     1156      LocalFree((HLOCAL) szData);
     1157    }
     1158    else
     1159    {
     1160      nBytesToAlloc = lstrlenW(pvData) * sizeof(WCHAR);
     1161      szData = (LPWSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc + 1);
     1162      lstrcpyW(szData, pvData);
     1163      dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, *pcbData/sizeof(WCHAR) );
     1164      if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
     1165      dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
     1166      LocalFree((HLOCAL) szData);
     1167    }
     1168  }
     1169
     1170  /* Update the type and data size if the caller wanted them */
     1171  if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ;
     1172  if ( pwType ) *pwType = dwType;
     1173  if ( pcbData ) *pcbData = dwUnExpDataLen;
     1174  return dwRet;
    10801175}
    10811176
     
    12761371  DWORD dwKeyCount = 0, dwValueCount = 0, dwRet;
    12771372
    1278   TRACE("(hkey=0x%08x,%s)", hKey, debugstr_a(lpszSubKey));
     1373  TRACE("(hkey=0x%08x,%s)\n", hKey, debugstr_a(lpszSubKey));
    12791374
    12801375  dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
     
    13051400  DWORD dwKeyCount = 0, dwValueCount = 0, dwRet;
    13061401
    1307   TRACE("(hkey=0x%08x,%s)", hKey, debugstr_w(lpszSubKey));
     1402  TRACE("(hkey=0x%08x,%s)\n", hKey, debugstr_w(lpszSubKey));
    13081403
    13091404  dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
     
    15021597  if (!lpszValue)
    15031598  {
    1504     WARN("Invalid lpszValue would crash under Win32!");
     1599    WARN("Invalid lpszValue would crash under Win32!\n");
    15051600    return FALSE;
    15061601  }
     
    15221617  if (!lpszValue)
    15231618  {
    1524     WARN("Invalid lpszValue would crash under Win32!");
     1619    WARN("Invalid lpszValue would crash under Win32!\n");
    15251620    return FALSE;
    15261621  }
  • trunk/src/shlwapi/regstream.c

    r7821 r8584  
    11/*
    22 *      SHRegOpenStream
     3 *
     4 * Copyright 1999 Juergen Schmied
     5 *
     6 * This library is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU Lesser General Public
     8 * License as published by the Free Software Foundation; either
     9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * This library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, write to the Free Software
     18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    319 */
    4 #ifdef __WIN32OS2__
    5 #define SHLWAPI_STREAM
    6 #endif
     20
    721#include <string.h>
    822
     
    1226#include "shlobj.h"
    1327
    14 #include "debugtools.h"
    15 
    16 DEFAULT_DEBUG_CHANNEL(shell);
    17 
    18 typedef struct 
     28#include "wine/debug.h"
     29
     30WINE_DEFAULT_DEBUG_CHANNEL(shell);
     31
     32typedef struct
    1933{       ICOM_VFIELD(IStream);
    2034        DWORD           ref;
     
    3448        ISHRegStream*   rstr;
    3549        DWORD           dwType;
    36        
     50
    3751        rstr = (ISHRegStream*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ISHRegStream));
    3852
     
    4357        {
    4458          if (!(RegQueryValueExA(rstr->hKey, pszValue,0,0,0,&(rstr->dwLength))))
    45           { 
     59          {
    4660            /* read the binary data into the buffer */
    4761            if((rstr->pbBuffer = HeapAlloc(GetProcessHeap(),0,rstr->dwLength)))
     
    7185        ISHRegStream*   rstr;
    7286        DWORD           dwType;
    73        
     87
    7488        rstr = (ISHRegStream*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ISHRegStream));
    7589
     
    8094        {
    8195          if (!(RegQueryValueExW(rstr->hKey, pszValue,0,0,0,&(rstr->dwLength))))
    82           { 
     96          {
    8397            /* read the binary data into the buffer */
    8498            if((rstr->pbBuffer = HeapAlloc(GetProcessHeap(),0,rstr->dwLength)))
     
    113127
    114128        if(IsEqualIID(riid, &IID_IUnknown))     /*IUnknown*/
    115         { *ppvObj = This; 
     129        { *ppvObj = This;
    116130        }
    117131        else if(IsEqualIID(riid, &IID_IStream)) /*IStream*/
    118132        { *ppvObj = This;
    119         }   
     133        }
    120134
    121135        if(*ppvObj)
    122         { 
    123           IStream_AddRef((IStream*)*ppvObj);     
     136        {
     137          IStream_AddRef((IStream*)*ppvObj);
    124138          TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
    125139          return S_OK;
     
    150164        TRACE("(%p)->()\n",This);
    151165
    152         if (!--(This->ref)) 
     166        if (!--(This->ref))
    153167        { TRACE(" destroying SHReg IStream (%p)\n",This);
    154168
     
    170184
    171185        DWORD dwBytesToRead, dwBytesLeft;
    172        
     186
    173187        TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
    174        
     188
    175189        if ( !pv )
    176190          return STG_E_INVALIDPOINTER;
    177          
     191
    178192        dwBytesLeft = This->dwLength - This->dwPos;
    179193
    180194        if ( 0 >= dwBytesLeft )                                         /* end of buffer */
    181195          return S_FALSE;
    182        
     196
    183197        dwBytesToRead = ( cb > dwBytesLeft) ? dwBytesLeft : cb;
    184198
    185199        memmove ( pv, (This->pbBuffer) + (This->dwPos), dwBytesToRead);
    186        
     200
    187201        This->dwPos += dwBytesToRead;                                   /* adjust pointer */
    188202
     
    273287}
    274288
    275 static struct ICOM_VTABLE(IStream) rstvt = 
    276 {       
     289static struct ICOM_VTABLE(IStream) rstvt =
     290{
    277291        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    278292        IStream_fnQueryInterface,
     
    290304        IStream_fnStat,
    291305        IStream_fnClone
    292        
     306
    293307};
    294308
  • trunk/src/shlwapi/shlwapi.def

    r7900 r8584  
    1 ; $Id: shlwapi.def,v 1.29 2002-02-13 16:15:07 sandervl Exp $
     1; $Id: shlwapi.def,v 1.30 2002-06-07 08:02:19 sandervl Exp $
    22
    33; updated export ordinals to NT4 SP6 version of SHLWAPI.DLL
     
    3434                             _SHLWAPI_8@8                         @8  NONAME
    3535                             _SHLWAPI_9@4                         @9  NONAME
    36                              _SHLWAPI_10@8                        @10 NONAME
    37 
     36                             
     37                             _SHLWAPI_10@8                        @10 NONAME                             
    3838                             _SHLWAPI_11@20                       @11 NONAME
    3939                             _SHLWAPI_12@8                        @12 NONAME
     
    4545                             _SHLWAPI_18@8                        @18 NONAME
    4646                             _SHLWAPI_19@4                        @19 NONAME
    47 
     47                             
    4848                             _SHLWAPI_20@8                        @20 NONAME
    4949                             _SHLWAPI_21@8                        @21 NONAME
     
    7777                             _CreateAcceleratorTableW@8           @47 NONAME
    7878                             _CreateDCW@16                        @48 NONAME
    79                              _CreateDialogParamW@20               @49 NONAME ; @@@PH imcomplete
     79                             _CreateDialogParamA@20               @49 NONAME
    8080
    8181                             _CreateDirectoryW@8                  @50 NONAME
     
    194194                             _SHLWAPI_153@12                      @153 NONAME
    195195                             _SHLWAPI_154@12                      @154 NONAME
    196 ;;;;_SHLWAPI_155@??                      @155 NONAME
     196                             _SHLWAPI_155@8                       @155 NONAME
    197197                             _SHLWAPI_156@8                       @156 NONAME
    198198                             _SHLWAPI_158@8                       @158 NONAME
     
    209209                             _SHLWAPI_172@8                       @172 NONAME
    210210                             _SHLWAPI_174@8                       @174 NONAME
     211                             _SHLWAPI_175@8                       @175 NONAME
    211212                             _SHLWAPI_176@16                      @176 NONAME
    212213
     
    224225                             _SHLWAPI_206@24                      @206 NONAME
    225226                             _SHLWAPI_208@20                      @208 NONAME
    226 
     227                             _SHLWAPI_209@4                       @209 NONAME
     228                             
    227229                             _SHLWAPI_210@12                      @210 NONAME
    228230                             _SHLWAPI_211@8                       @211 NONAME
     
    241243
    242244                             _SHLWAPI_240@16                      @240 NONAME
    243 ;;PH                             _SHLWAPI_241@0                       @241 NONAME
    244                              _PathRemoveArgsA@4                   @241 NONAME
     245                             _SHLWAPI_241@0                       @241 NONAME
    245246                             _SHLWAPI_243@20                      @243 NONAME
    246247
    247 ;   AssocCreate            = _AssocCreate@20                      @253 ;by name
    248 ;   AssocQueryKeyA         = _AssocQueryKeyA@20                   @254 ;by name
    249 ;   AssocQueryKeyW         = _AssocQueryKeyW@20                   @255 ;by name
     248;    AssocCreate            = _AssocCreate@20                      @253 ;by name
     249;    AssocQueryKeyA         = _AssocQueryKeyA@20                   @254 ;by name
     250;    AssocQueryKeyW         = _AssocQueryKeyW@20                   @255 ;by name
    250251
    251252                             _SHLWAPI_266@16                      @266 NONAME
     
    257258
    258259                             _SHLWAPI_289@12                      @289 NONAME
    259 ;;                             _SHLWAPI_284@20                      @294 NONAME
     260                             _SHLWAPI_294@20                      @294 NONAME
    260261                             _WritePrivateProfileStringW@16       @298 NONAME
    261262
     
    270271                             _IsBadStringPtrW@8                   @308 NONAME
    271272                             _LoadLibraryW@4                      @309 NONAME
     273                             
    272274                             _GetTimeFormatW@24                   @310 NONAME
    273275                             _GetDateFormatW@24                   @311 NONAME
     
    294296                             _SetFileAttributesW@8                @338 NONAME
    295297                             _GetNumberFormatW@24                 @339 NONAME
     298                             
    296299                             _MessageBoxW@16                      @340 NONAME
    297300                             _FindNextFileW@8                     @341 NONAME
    298   _SHLWAPI_342@12 = _InterlockedCompareExchange@12                @342 NONAME
     301                             _SHInterlockedCompareExchange@12     @342 NONAME
    299302                             _SHLWAPI_346@12                      @346 NONAME
    300303                             _RegDeleteValueW@8                   @347 NONAME
    301304
     305                             _SHLWAPI_350@8                       @350 NONAME
     306                             _SHLWAPI_351@16                      @351 NONAME
     307                             _SHLWAPI_352@16                      @352 NONAME
    302308                             _SHLWAPI_356@12                      @356 NONAME
    303309                             _SHLWAPI_357@20                      @357 NONAME
     
    342348
    343349                             _SHLWAPI_413@4                       @413 NONAME
    344 
     350                             _SHLWAPI_418@4                       @418 NONAME
     351                             
    345352                             _TrackPopupMenuEx@24                 @428 NONAME
    346353
     
    349356                             _SendMessageTimeoutW@28              @434 NONAME
    350357
     358                             _SHLWAPI_436@8                       @436 NONAME
    351359                             _SHLWAPI_437@4                       @437 NONAME
    352360
     
    356364    ColorRGBToHLS          = _ColorRGBToHLS@16                    @445
    357365
    358     DllGetVersion          = _SHLWAPI_DllGetVersion@4             @446
    359     GetMenuPosFromID       = _GetMenuPosFromID@8                  @447
    360     HashData               = _HashData@16                         @448
    361   ; IntlStrEqWorkerA       = _StrIsIntlEqualA@16                  @449
    362   ; IntlStrEqWorkerW       = _StrIsIntlEqualw@16                  @450
    363     PathAddBackslashA      = _PathAddBackslashA@4                 @451
    364     PathAddBackslashW      = _PathAddBackslashW@4                 @452
    365     PathAddExtensionA      = _PathAddExtensionA@8                 @453
    366     PathAddExtensionW      = _PathAddExtensionW@8                 @454
    367     PathAppendA            = _PathAppendA@8                       @455
    368     PathAppendW            = _PathAppendW@8                       @456
    369     PathBuildRootA         = _PathBuildRootA@8                    @457
    370     PathBuildRootW         = _PathBuildRootW@8                    @458
    371     PathCanonicalizeA      = _PathCanonicalizeA@8                 @459
    372     PathCanonicalizeW      = _PathCanonicalizeW@8                 @460
    373     PathCombineA           = _PathCombineA@12                     @461
    374     PathCombineW           = _PathCombineW@12                     @462
    375     PathCommonPrefixA      = _PathCommonPrefixA@12                @463
    376     PathCommonPrefixW      = _PathCommonPrefixW@12                @464
    377     PathCompactPathA       = _PathCompactPathA@12                 @465
    378     PathCompactPathExA     = _PathCompactPathExA@16               @466
    379     PathCompactPathExW     = _PathCompactPathExW@16               @467
    380     PathCompactPathW       = _PathCompactPathW@12                 @468
    381     PathCreateFromUrlA     = _PathCreateFromUrlA@16               @469
    382     PathCreateFromUrlW     = _PathCreateFromUrlW@16               @470
    383     PathFileExistsA        = _PathFileExistsA@4                   @471
    384     PathFileExistsW        = _PathFileExistsW@4                   @472
    385     PathFindExtensionA     = _PathFindExtensionA@4                @473
    386     PathFindExtensionW     = _PathFindExtensionW@4                @474
    387     PathFindFileNameA      = _PathFindFileNameA@4                 @475
    388     PathFindFileNameW      = _PathFindFileNameW@4                 @476
    389     PathFindNextComponentA = _PathFindNextComponentA@4            @477
    390     PathFindNextComponentW = _PathFindNextComponentW@4            @478
    391     PathFindOnPathA        = _PathFindOnPathA@8                   @479
    392     PathFindOnPathW        = _PathFindOnPathW@8                   @480
    393 ;   PathFindSuffixArrayA   = _PathFindSuffixArrayA@12             @481
    394 ;   PathFindSuffixArrayW   = _PathFindSuffixArrayW@12             @482
    395     PathGetArgsA           = _PathGetArgsA@4                      @483
    396     PathGetArgsW           = _PathGetArgsW@4                      @484
    397     PathGetCharTypeA       = _PathGetCharTypeA@4                  @485
    398     PathGetCharTypeW       = _PathGetCharTypeW@4                  @486
    399     PathGetDriveNumberA    = _PathGetDriveNumberA@4               @487
    400     PathGetDriveNumberW    = _PathGetDriveNumberW@4               @488
    401     PathIsContentTypeA     = _PathIsContentTypeA@8                @489
    402     PathIsContentTypeW     = _PathIsContentTypeW@8                @490
    403     PathIsDirectoryA       = _PathIsDirectoryA@4                  @491
    404 ;   PathIsDirectoryEmptyA  = _PathIsDirectoryEmptyA@4             @492
    405 ;   PathIsDirectoryEmptyW  = _PathIsDirectoryEmptyW@4             @493
    406     PathIsDirectoryW       = _PathIsDirectoryW@4                  @494
    407     PathIsFileSpecA        = _PathIsFileSpecA@4                   @495
    408     PathIsFileSpecW        = _PathIsFileSpecW@4                   @496
    409 ;   PathIsLFNFileSpecA     = _PathIsLFNFileSpecA@4                @497
    410 ;   PathIsLFNFileSpecW     = _PathIsLFNFileSpecW@4                @498
    411 ;   PathIsNetworkPathA     = _PathIsNetworkPathA@4                @499
    412 ;   PathIsNetworkPathW     = _PathIsNetworkPathW@4                @500
    413     PathIsPrefixA          = _PathIsPrefixA@8                     @501
    414     PathIsPrefixW          = _PathIsPrefixW@8                     @502
    415     PathIsRelativeA        = _PathIsRelativeA@4                   @503
    416     PathIsRelativeW        = _PathIsRelativeW@4                   @504
    417     PathIsRootA            = _PathIsRootA@4                       @505
    418     PathIsRootW            = _PathIsRootW@4                       @506
    419     PathIsSameRootA        = _PathIsSameRootA@8                   @507
    420     PathIsSameRootW        = _PathIsSameRootW@8                   @508
    421     PathIsSystemFolderA    = _PathIsSystemFolderA@8               @509
    422     PathIsSystemFolderW    = _PathIsSystemFolderW@8               @510
    423     PathIsUNCA             = _PathIsUNCA@4                        @511
    424     PathIsUNCServerA       = _PathIsUNCServerA@4                  @512
    425     PathIsUNCServerShareA  = _PathIsUNCServerShareA@4             @513
    426     PathIsUNCServerShareW  = _PathIsUNCServerShareW@4             @514
    427     PathIsUNCServerW       = _PathIsUNCServerW@4                  @515
    428     PathIsUNCW             = _PathIsUNCW@4                        @516
    429     PathIsURLA             = _PathIsURLA@4                        @517
    430     PathIsURLW             = _PathIsURLW@4                        @518
    431     PathMakePrettyA        = _PathMakePrettyA@4                   @519
    432     PathMakePrettyW        = _PathMakePrettyW@4                   @520
    433     PathMakeSystemFolderA  = _PathMakeSystemFolderA@4             @521
    434     PathMakeSystemFolderW  = _PathMakeSystemFolderW@4             @522
    435     PathMatchSpecA         = _PathMatchSpecA@8                    @523
    436     PathMatchSpecW         = _PathMatchSpecW@8                    @524
    437     PathParseIconLocationA = _PathParseIconLocationA@4            @525
    438     PathParseIconLocationW = _PathParseIconLocationW@4            @526
    439     PathQuoteSpacesA       = _PathQuoteSpacesA@4                  @527
    440     PathQuoteSpacesW       = _PathQuoteSpacesW@4                  @528
    441     PathRelativePathToA    = _PathRelativePathToA@20              @529
    442     PathRelativePathToW    = _PathRelativePathToW@20              @530
    443     PathRemoveArgsA        = _PathRemoveArgsA@4                   @531
    444     PathRemoveArgsW        = _PathRemoveArgsW@4                   @532
    445     PathRemoveBackslashA   = _PathRemoveBackslashA@4              @533
    446     PathRemoveBackslashW   = _PathRemoveBackslashW@4              @534
    447     PathRemoveBlanksA      = _PathRemoveBlanksA@4                 @535
    448     PathRemoveBlanksW      = _PathRemoveBlanksW@4                 @536
    449     PathRemoveExtensionA   = _PathRemoveExtensionA@4              @537
    450     PathRemoveExtensionW   = _PathRemoveExtensionW@4              @538
    451     PathRemoveFileSpecA    = _PathRemoveFileSpecA@4               @539
    452     PathRemoveFileSpecW    = _PathRemoveFileSpecW@4               @540
    453     PathRenameExtensionA   = _PathRenameExtensionA@8              @541
    454     PathRenameExtensionW   = _PathRenameExtensionW@8              @542
    455     PathSearchAndQualifyA  = _PathSearchAndQualifyA@12            @543
    456     PathSearchAndQualifyW  = _PathSearchAndQualifyW@12            @544
    457     PathSetDlgItemPathA    = _PathSetDlgItemPathA@12              @545
    458     PathSetDlgItemPathW    = _PathSetDlgItemPathW@12              @546
    459     PathSkipRootA          = _PathSkipRootA@4                     @547
    460     PathSkipRootW          = _PathSkipRootW@4                     @548
    461     PathStripPathA         = _PathStripPathA@4                    @549
    462     PathStripPathW         = _PathStripPathW@4                    @550
    463     PathStripToRootA       = _PathStripToRootA@4                  @551
    464     PathStripToRootW       = _PathStripToRootW@4                  @552
    465 ;   PathUndecorateA        = _PathUndecorateA@4                   @553
    466 ;   PathUndecorateW        = _PathUndecorateW@4                   @554
    467     PathUnmakeSystemFolderA= _PathUnmakeSystemFolderA@4           @555
    468     PathUnmakeSystemFolderW= _PathUnmakeSystemFolderW@4           @556
    469     PathUnquoteSpacesA     = _PathUnquoteSpacesA@4                @557
    470     PathUnquoteSpacesW     = _PathUnquoteSpacesW@4                @558
    471 
    472 ;   SHAutoComplete         = _SHAutoComplete@8                    @559
    473   ; SHCopyKeyA             = _SHCopyKeyA@?                        @560
    474   ; SHCopyKeyW             = _SHCopyKeyW@?                        @561
    475     SHCreateShellPalette   = _SHCreateShellPalette@4              @562
    476   ; SHCreateStreamOnFileA  = _SHCreateStreamOnFileA@?             @563
    477   ; SHCreateStreamOnFileW  = _SHCreateStreamOnFileW@?             @564
    478   ; SHCreateStreamWrapper  = _SHCreateStreamWrapper@?             @565
    479 
    480     SHDeleteEmptyKeyA      = _SHDeleteEmptyKeyA@8                 @567
    481     SHDeleteEmptyKeyW      = _SHDeleteEmptyKeyW@8                 @568
    482     SHDeleteKeyA           = _SHDeleteKeyA@8                      @569
    483     SHDeleteKeyW           = _SHDeleteKeyW@8                      @570
    484     SHDeleteOrphanKeyA     = _SHDeleteOrphanKeyA@8                @571
    485     SHDeleteOrphanKeyW     = _SHDeleteOrphanKeyW@8                @572
    486     SHDeleteValueA         = _SHDeleteValueA@12                   @573
    487     SHDeleteValueW         = _SHDeleteValueW@12                   @574
    488     SHEnumKeyExA           = _SHEnumKeyExA@16                     @575
    489     SHEnumKeyExW           = _SHEnumKeyExW@16                     @576
    490     SHEnumValueA           = _SHEnumValueA@28                     @577
    491     SHEnumValueW           = _SHEnumValueW@28                     @578
    492     _SHGetInstanceExplorer = __SHGetInstanceExplorer@4            @579
    493     SHGetInverseCMAP       = _SHGetInverseCMAP@8                  @580
    494 ;   SHGetThreadRef         = _SHGetThreadRef@?                    @581
    495     SHGetValueA            = _SHGetValueA@24                      @582
    496     SHGetValueW            = _SHGetValueW@24                      @583
    497     SHIsLowMemoryMachine   = _SHIsLowMemoryMachine@4              @584
    498     SHOpenRegStream2A      = _SHOpenRegStreamA@16                 @585
    499     SHOpenRegStream2W      = _SHOpenRegStreamW@16                 @586
    500     SHOpenRegStreamA       = _SHOpenRegStreamA@16                 @587
    501     SHOpenRegStreamW       = _SHOpenRegStreamW@16                 @588
    502     SHQueryInfoKeyA        = _SHQueryInfoKeyA@20                  @589
    503     SHQueryInfoKeyW        = _SHQueryInfoKeyW@20                  @590
    504     SHQueryValueExA        = _SHQueryValueExA@24                  @591
    505     SHQueryValueExW        = _SHQueryValueExW@24                  @592
    506     SHRegCloseUSKey        = _SHRegCloseUSKey@4                   @593
    507     SHRegCreateUSKeyA      = _SHRegCreateUSKeyA@20                @594
    508     SHRegCreateUSKeyW      = _SHRegCreateUSKeyW@20                @595
    509     SHRegDeleteEmptyUSKeyA = _SHRegDeleteEmptyUSKeyA@12           @596
    510     SHRegDeleteEmptyUSKeyW = _SHRegDeleteEmptyUSKeyW@12           @597
    511     SHRegDeleteUSKeyA      = _SHRegDeleteUSKeyA@12                @598
    512     SHRegDeleteUSKeyW      = _SHRegDeleteUSKeyW@12                @599
    513   ; SHRegDuplicateHKey     = _SHRegDuplicateHKey@?                @600
    514     SHRegEnumUSKeyA        = _SHRegEnumUSKeyA@20                  @601
    515     SHRegEnumUSKeyW        = _SHRegEnumUSKeyW@20                  @602
    516     SHRegEnumUSValueA      = _SHRegEnumUSValueA@32                @603
    517     SHRegEnumUSValueW      = _SHRegEnumUSValueW@32                @604
    518     SHRegGetBoolUSValueA   = _SHRegGetBoolUSValueA@16             @605
    519     SHRegGetBoolUSValueW   = _SHRegGetBoolUSValueW@16             @606
    520     SHRegGetUSValueA       = _SHRegGetUSValueA@32                 @607
    521     SHRegGetUSValueW       = _SHRegGetUSValueW@32                 @608
    522     SHRegOpenUSKeyA        = _SHRegOpenUSKeyA@20                  @609
    523     SHRegOpenUSKeyW        = _SHRegOpenUSKeyW@20                  @610
    524 ;    SHRegQueryInfoKeyA     = _SHRegQueryInfoKeyA@24               @611
    525 ;    SHRegQueryInfoKeyW     = _SHRegQueryInfoKeyW@24               @612
    526     SHRegQueryUSValueA     = _SHRegQueryUSValueA@32               @613
    527     SHRegQueryUSValueW     = _SHRegQueryUSValueW@32               @614
    528     SHRegSetUSValueA       = _SHRegSetUSValueA@24                 @615
    529     SHRegSetUSValueW       = _SHRegSetUSValueW@24                 @616
    530     SHRegWriteUSValueA     = _SHRegWriteUSValueA@24               @617
    531     SHRegWriteUSValueW     = _SHRegWriteUSValueW@24               @618
    532 ;   SHSetSetThreadRef      = _SHSetThreadRef@?                    @619
    533     SHSetValueA            = _SHSetValueA@24                      @620
    534     SHSetValueW            = _SHSetValueW@24                      @621
    535 ;   SHSkipJunction         = _SHSkipJunction@8                    @622
    536 ;   SHStrDupA              = _SHStrDupA@?                         @623
    537 ;   SHStrDupW              = _SHStrDUpW@?                         @624
    538     StrCSpnA               = _StrCSpnA@8                          @625
    539   ; StrCSpnIA              = _StrCSpnIA@?                         @626
    540   ; StrCSpnIW              = _StrCSpnIW@?                         @627
    541     StrCSpnW               = _StrCSpnW@8                          @628
    542     StrCatBuffA            = _StrCatBuffA@12                      @629
    543     StrCatBuffW            = _StrCatBuffW@12                      @630
     366    DllGetVersion          = _SHLWAPI_DllGetVersion@4             @1046
     367    GetMenuPosFromID       = _GetMenuPosFromID@8                  @1047
     368    HashData               = _HashData@16                         @1048
     369  ; IntlStrEqWorkerA       = _StrIsIntlEqualA@16                  @1049
     370  ; IntlStrEqWorkerW       = _StrIsIntlEqualw@16                  @1050
     371    PathAddBackslashA      = _PathAddBackslashA@4                 @1051
     372    PathAddBackslashW      = _PathAddBackslashW@4                 @1052
     373    PathAddExtensionA      = _PathAddExtensionA@8                 @1053
     374    PathAddExtensionW      = _PathAddExtensionW@8                 @1054
     375    PathAppendA            = _PathAppendA@8                       @1055
     376    PathAppendW            = _PathAppendW@8                       @1056
     377    PathBuildRootA         = _PathBuildRootA@8                    @1057
     378    PathBuildRootW         = _PathBuildRootW@8                    @1058
     379    PathCanonicalizeA      = _PathCanonicalizeA@8                 @1059
     380    PathCanonicalizeW      = _PathCanonicalizeW@8                 @1060
     381    PathCombineA           = _PathCombineA@12                     @1061
     382    PathCombineW           = _PathCombineW@12                     @1062
     383    PathCommonPrefixA      = _PathCommonPrefixA@12                @1063
     384    PathCommonPrefixW      = _PathCommonPrefixW@12                @1064
     385    PathCompactPathA       = _PathCompactPathA@12                 @1065
     386    PathCompactPathExA     = _PathCompactPathExA@16               @1066
     387    PathCompactPathExW     = _PathCompactPathExW@16               @1067
     388    PathCompactPathW       = _PathCompactPathW@12                 @1068
     389    PathCreateFromUrlA     = _PathCreateFromUrlA@16               @1069
     390    PathCreateFromUrlW     = _PathCreateFromUrlW@16               @1070
     391    PathFileExistsA        = _PathFileExistsA@4                   @1071
     392    PathFileExistsW        = _PathFileExistsW@4                   @1072
     393    PathFindExtensionA     = _PathFindExtensionA@4                @1073
     394    PathFindExtensionW     = _PathFindExtensionW@4                @1074
     395    PathFindFileNameA      = _PathFindFileNameA@4                 @1075
     396    PathFindFileNameW      = _PathFindFileNameW@4                 @1076
     397    PathFindNextComponentA = _PathFindNextComponentA@4            @1077
     398    PathFindNextComponentW = _PathFindNextComponentW@4            @1078
     399    PathFindOnPathA        = _PathFindOnPathA@8                   @1079
     400    PathFindOnPathW        = _PathFindOnPathW@8                   @1080
     401    PathFindSuffixArrayA   = _PathFindSuffixArrayA@12             @1081
     402    PathFindSuffixArrayW   = _PathFindSuffixArrayW@12             @1082
     403    PathGetArgsA           = _PathGetArgsA@4                      @1083
     404    PathGetArgsW           = _PathGetArgsW@4                      @1084
     405    PathGetCharTypeA       = _PathGetCharTypeA@4                  @1085
     406    PathGetCharTypeW       = _PathGetCharTypeW@4                  @1086
     407    PathGetDriveNumberA    = _PathGetDriveNumberA@4               @1087
     408    PathGetDriveNumberW    = _PathGetDriveNumberW@4               @1088
     409    PathIsContentTypeA     = _PathIsContentTypeA@8                @1089
     410    PathIsContentTypeW     = _PathIsContentTypeW@8                @1090
     411    PathIsDirectoryA       = _PathIsDirectoryA@4                  @1091
     412    PathIsDirectoryEmptyA  = _PathIsDirectoryEmptyA@4             @1092
     413    PathIsDirectoryEmptyW  = _PathIsDirectoryEmptyW@4             @1093
     414    PathIsDirectoryW       = _PathIsDirectoryW@4                  @1094
     415    PathIsFileSpecA        = _PathIsFileSpecA@4                   @1095
     416    PathIsFileSpecW        = _PathIsFileSpecW@4                   @1096
     417    PathIsLFNFileSpecA     = _PathIsLFNFileSpecA@4                @1097
     418    PathIsLFNFileSpecW     = _PathIsLFNFileSpecW@4                @1098
     419    PathIsNetworkPathA     = _PathIsNetworkPathA@4                @1099
     420    PathIsNetworkPathW     = _PathIsNetworkPathW@4                @1100
     421    PathIsPrefixA          = _PathIsPrefixA@8                     @1101
     422    PathIsPrefixW          = _PathIsPrefixW@8                     @1102
     423    PathIsRelativeA        = _PathIsRelativeA@4                   @1103
     424    PathIsRelativeW        = _PathIsRelativeW@4                   @1104
     425    PathIsRootA            = _PathIsRootA@4                       @1105
     426    PathIsRootW            = _PathIsRootW@4                       @1106
     427    PathIsSameRootA        = _PathIsSameRootA@8                   @1107
     428    PathIsSameRootW        = _PathIsSameRootW@8                   @1108
     429    PathIsSystemFolderA    = _PathIsSystemFolderA@8               @1109
     430    PathIsSystemFolderW    = _PathIsSystemFolderW@8               @1110
     431    PathIsUNCA             = _PathIsUNCA@4                        @1111
     432    PathIsUNCServerA       = _PathIsUNCServerA@4                  @1112
     433    PathIsUNCServerShareA  = _PathIsUNCServerShareA@4             @1113
     434    PathIsUNCServerShareW  = _PathIsUNCServerShareW@4             @1114
     435    PathIsUNCServerW       = _PathIsUNCServerW@4                  @1115
     436    PathIsUNCW             = _PathIsUNCW@4                        @1116
     437    PathIsURLA             = _PathIsURLA@4                        @1117
     438    PathIsURLW             = _PathIsURLW@4                        @1118
     439    PathMakePrettyA        = _PathMakePrettyA@4                   @1119
     440    PathMakePrettyW        = _PathMakePrettyW@4                   @1120
     441    PathMakeSystemFolderA  = _PathMakeSystemFolderA@4             @1121
     442    PathMakeSystemFolderW  = _PathMakeSystemFolderW@4             @1122
     443    PathMatchSpecA         = _PathMatchSpecA@8                    @1123
     444    PathMatchSpecW         = _PathMatchSpecW@8                    @1124
     445    PathParseIconLocationA = _PathParseIconLocationA@4            @1125
     446    PathParseIconLocationW = _PathParseIconLocationW@4            @1126
     447    PathQuoteSpacesA       = _PathQuoteSpacesA@4                  @1127
     448    PathQuoteSpacesW       = _PathQuoteSpacesW@4                  @1128
     449    PathRelativePathToA    = _PathRelativePathToA@20              @1129
     450    PathRelativePathToW    = _PathRelativePathToW@20              @1130
     451    PathRemoveArgsA        = _PathRemoveArgsA@4                   @1131
     452    PathRemoveArgsW        = _PathRemoveArgsW@4                   @1132
     453    PathRemoveBackslashA   = _PathRemoveBackslashA@4              @1133
     454    PathRemoveBackslashW   = _PathRemoveBackslashW@4              @1134
     455    PathRemoveBlanksA      = _PathRemoveBlanksA@4                 @1135
     456    PathRemoveBlanksW      = _PathRemoveBlanksW@4                 @1136
     457    PathRemoveExtensionA   = _PathRemoveExtensionA@4              @1137
     458    PathRemoveExtensionW   = _PathRemoveExtensionW@4              @1138
     459    PathRemoveFileSpecA    = _PathRemoveFileSpecA@4               @1139
     460    PathRemoveFileSpecW    = _PathRemoveFileSpecW@4               @1140
     461    PathRenameExtensionA   = _PathRenameExtensionA@8              @1141
     462    PathRenameExtensionW   = _PathRenameExtensionW@8              @1142
     463    PathSearchAndQualifyA  = _PathSearchAndQualifyA@12            @1143
     464    PathSearchAndQualifyW  = _PathSearchAndQualifyW@12            @1144
     465    PathSetDlgItemPathA    = _PathSetDlgItemPathA@12              @1145
     466    PathSetDlgItemPathW    = _PathSetDlgItemPathW@12              @1146
     467    PathSkipRootA          = _PathSkipRootA@4                     @1147
     468    PathSkipRootW          = _PathSkipRootW@4                     @1148
     469    PathStripPathA         = _PathStripPathA@4                    @1149
     470    PathStripPathW         = _PathStripPathW@4                    @1150
     471    PathStripToRootA       = _PathStripToRootA@4                  @1151
     472    PathStripToRootW       = _PathStripToRootW@4                  @1152
     473    PathUndecorateA        = _PathUndecorateA@4                   @1153
     474    PathUndecorateW        = _PathUndecorateW@4                   @1154
     475    PathUnmakeSystemFolderA= _PathUnmakeSystemFolderA@4           @1155
     476    PathUnmakeSystemFolderW= _PathUnmakeSystemFolderW@4           @1156
     477    PathUnquoteSpacesA     = _PathUnquoteSpacesA@4                @1157
     478    PathUnquoteSpacesW     = _PathUnquoteSpacesW@4                @1158
     479
     480;   SHAutoComplete         = _SHAutoComplete@8                    @1159
     481  ; SHCopyKeyA             = _SHCopyKeyA@?                        @1160
     482  ; SHCopyKeyW             = _SHCopyKeyW@?                        @1161
     483    SHCreateShellPalette   = _SHCreateShellPalette@4              @1162
     484  ; SHCreateStreamOnFileA  = _SHCreateStreamOnFileA@?             @1163
     485  ; SHCreateStreamOnFileW  = _SHCreateStreamOnFileW@?             @1164
     486  ; SHCreateStreamWrapper  = _SHCreateStreamWrapper@?             @1165
     487
     488    SHDeleteEmptyKeyA      = _SHDeleteEmptyKeyA@8                 @1167
     489    SHDeleteEmptyKeyW      = _SHDeleteEmptyKeyW@8                 @1168
     490    SHDeleteKeyA           = _SHDeleteKeyA@8                      @1169
     491    SHDeleteKeyW           = _SHDeleteKeyW@8                      @1170
     492    SHDeleteOrphanKeyA     = _SHDeleteOrphanKeyA@8                @1171
     493    SHDeleteOrphanKeyW     = _SHDeleteOrphanKeyW@8                @1172
     494    SHDeleteValueA         = _SHDeleteValueA@12                   @1173
     495    SHDeleteValueW         = _SHDeleteValueW@12                   @1174
     496    SHEnumKeyExA           = _SHEnumKeyExA@16                     @1175
     497    SHEnumKeyExW           = _SHEnumKeyExW@16                     @1176
     498    SHEnumValueA           = _SHEnumValueA@28                     @1177
     499    SHEnumValueW           = _SHEnumValueW@28                     @1178
     500    _SHGetInstanceExplorer = __SHGetInstanceExplorer@4            @1179
     501    SHGetInverseCMAP       = _SHGetInverseCMAP@8                  @1180
     502    SHGetThreadRef         = _SHGetThreadRef@4                    @1181
     503    SHGetValueA            = _SHGetValueA@24                      @1182
     504    SHGetValueW            = _SHGetValueW@24                      @1183
     505    SHIsLowMemoryMachine   = _SHIsLowMemoryMachine@4              @1184
     506    SHOpenRegStream2A      = _SHOpenRegStreamA@16                 @1185
     507    SHOpenRegStream2W      = _SHOpenRegStreamW@16                 @1186
     508    SHOpenRegStreamA       = _SHOpenRegStreamA@16                 @1187
     509    SHOpenRegStreamW       = _SHOpenRegStreamW@16                 @1188
     510    SHQueryInfoKeyA        = _SHQueryInfoKeyA@20                  @1189
     511    SHQueryInfoKeyW        = _SHQueryInfoKeyW@20                  @1190
     512    SHQueryValueExA        = _SHQueryValueExA@24                  @1191
     513    SHQueryValueExW        = _SHQueryValueExW@24                  @1192
     514    SHRegCloseUSKey        = _SHRegCloseUSKey@4                   @1193
     515    SHRegCreateUSKeyA      = _SHRegCreateUSKeyA@20                @1194
     516    SHRegCreateUSKeyW      = _SHRegCreateUSKeyW@20                @1195
     517    SHRegDeleteEmptyUSKeyA = _SHRegDeleteEmptyUSKeyA@12           @1196
     518    SHRegDeleteEmptyUSKeyW = _SHRegDeleteEmptyUSKeyW@12           @1197
     519    SHRegDeleteUSKeyA      = _SHRegDeleteUSKeyA@12                @1198
     520    SHRegDeleteUSKeyW      = _SHRegDeleteUSKeyW@12                @1199
     521    SHRegDuplicateHKey     = _SHRegDuplicateHKey@4                @1200
     522    SHRegEnumUSKeyA        = _SHRegEnumUSKeyA@20                  @1201
     523    SHRegEnumUSKeyW        = _SHRegEnumUSKeyW@20                  @1202
     524    SHRegEnumUSValueA      = _SHRegEnumUSValueA@32                @1203
     525    SHRegEnumUSValueW      = _SHRegEnumUSValueW@32                @1204
     526    SHRegGetBoolUSValueA   = _SHRegGetBoolUSValueA@16             @1205
     527    SHRegGetBoolUSValueW   = _SHRegGetBoolUSValueW@16             @1206
     528    SHRegGetUSValueA       = _SHRegGetUSValueA@32                 @1207
     529    SHRegGetUSValueW       = _SHRegGetUSValueW@32                 @1208
     530    SHRegOpenUSKeyA        = _SHRegOpenUSKeyA@20                  @1209
     531    SHRegOpenUSKeyW        = _SHRegOpenUSKeyW@20                  @1210
     532;    SHRegQueryInfoKeyA     = _SHRegQueryInfoKeyA@24               @1211
     533;    SHRegQueryInfoKeyW     = _SHRegQueryInfoKeyW@24               @1212
     534    SHRegQueryUSValueA     = _SHRegQueryUSValueA@32               @1213
     535    SHRegQueryUSValueW     = _SHRegQueryUSValueW@32               @1214
     536    SHRegSetUSValueA       = _SHRegSetUSValueA@24                 @1215
     537    SHRegSetUSValueW       = _SHRegSetUSValueW@24                 @1216
     538    SHRegWriteUSValueA     = _SHRegWriteUSValueA@24               @1217
     539    SHRegWriteUSValueW     = _SHRegWriteUSValueW@24               @1218
     540    SHSetSetThreadRef      = _SHSetThreadRef@4                    @1219
     541    SHSetValueA            = _SHSetValueA@24                      @1220
     542    SHSetValueW            = _SHSetValueW@24                      @1221
     543;   SHSkipJunction         = _SHSkipJunction@8                    @1222
     544;   SHStrDupA              = _SHStrDupA@?                         @1223
     545;   SHStrDupW              = _SHStrDUpW@?                         @1224
     546    StrCSpnA               = _StrCSpnA@8                          @1225
     547  ; StrCSpnIA              = _StrCSpnIA@?                         @1226
     548  ; StrCSpnIW              = _StrCSpnIW@?                         @1227
     549    StrCSpnW               = _StrCSpnW@8                          @1228
     550    StrCatBuffA            = _StrCatBuffA@12                      @1229
     551    StrCatBuffW            = _StrCatBuffW@12                      @1230
    544552;    StrCatA                = _StrCatA@8                                 ; not exported ?
    545     StrCatW                = _StrCatW@8                           @631
    546     StrChrA                = _StrChrA@8                           @632
    547     StrChrIA               = _StrChrIA@8                          @633
    548     StrChrIW               = _StrChrIW@8                          @634
    549     StrChrW                = _StrChrW@8                           @635
    550     StrCmpIW               = _lstrcmpiW@8                         @636
    551     StrCmpNA               = _StrCmpNA@12                         @637
    552     StrCmpNIA              = _StrCmpNIA@12                        @638
    553     StrCmpNIW              = _StrCmpNIW@12                        @639
    554     StrCmpNW               = _StrCmpNW@12                         @640
    555     StrCmpW                = _lstrcmpW@8                          @641
    556     StrCpyNW               = _lstrcpynW@12                        @642
     553    StrCatW                = _StrCatW@8                           @1231
     554    StrChrA                = _StrChrA@8                           @1232
     555    StrChrIA               = _StrChrIA@8                          @1233
     556    StrChrIW               = _StrChrIW@8                          @1234
     557    StrChrW                = _StrChrW@8                           @1235
     558    StrCmpIW               = _lstrcmpiW@8                         @1236
     559    StrCmpNA               = _StrCmpNA@12                         @1237
     560    StrCmpNIA              = _StrCmpNIA@12                        @1238
     561    StrCmpNIW              = _StrCmpNIW@12                        @1239
     562    StrCmpNW               = _StrCmpNW@12                         @1240
     563    StrCmpW                = _lstrcmpW@8                          @1241
     564    StrCpyNW               = _lstrcpynW@12                        @1242
    557565;;;    StrCpyA                = _StrCpyA@8                                 ; not exported ?
    558     StrCpyW                = _StrCpyW@8                           @643
    559     StrDupA                = _StrDupA@4                           @644
    560     StrDupW                = _StrDupW@4                           @645
    561 ;   StrFormatByteSize64A   = _StrFormatByteSize64A@16             @646
    562     StrFormatByteSizeA     = _StrFormatByteSizeA@12               @647
    563     StrFormatByteSizeW     = _StrFormatByteSizeW@12               @648
    564 ;   StrFormatKBSizeA       = _StrFormatKBSizeA@16                 @649
    565 ;   StrFormatKBSizeW       = _StrFormatKBSizeW@16                 @650
    566     StrFromTimeIntervalA   = _StrFromTimeIntervalA@16             @651
    567     StrFromTimeIntervalW   = _StrFromTimeIntervalW@16             @652
    568   ; IntlStrEqWorkerA       = _StrIsIntlEqualA@16                  @653
    569   ; StrIsIntlEqualW        = _StrIsIntlEqualW@?                   @654
    570     StrNCatA               = _StrNCatA@12                         @655
    571     StrNCatW               = _StrNCatW@12                         @656
    572     StrPBrkA               = _StrPBrkA@8                          @657
    573     StrPBrkW               = _StrPBrkW@8                          @658
    574     StrRChrA               = _StrRChrA@12                         @659
    575     StrRChrIA              = _StrRChrIA@12                        @660
    576     StrRChrIW              = _StrRChrIW@12                        @661
    577     StrRChrW               = _StrRChrW@12                         @662
    578     StrRStrIA              = _StrRStrIA@12                        @663
    579     StrRStrIW              = _StrRStrIW@12                        @664
    580     StrRetToBufA           = _StrRetToBufA@16                     @665
    581     StrRetToBufW           = _StrRetToBufW@16                     @666
    582 ;   StrRetToStrA           = _StrRetToStrA@12                     @667
    583 ;   StrRetToStrW           = _StrRetToStrW@12                     @668
    584     StrSpnA                = _StrSpnA@8                           @669
    585     StrSpnW                = _StrSpnW@8                           @670
    586     StrStrA                = _StrStrA@8                           @671
    587     StrStrIA               = _StrStrIA@8                          @672
    588     StrStrIW               = _StrStrIW@8                          @673
    589     StrStrW                = _StrStrW@8                           @674
    590     StrToIntA              = _StrToIntA@4                         @675
    591     StrToIntExA            = _StrToIntExA@12                      @676
    592     StrToIntExW            = _StrToIntExW@12                      @677
    593     StrToIntW              = _StrToIntW@4                         @678
    594     StrTrimA               = _StrTrimA@8                          @679
    595   ; StrTrimW               = _StrTrimW@?                          @680
    596     UrlApplySchemeA        = _UrlApplySchemeA@16                  @681
    597     UrlApplySchemeW        = _UrlApplySchemeW@16                  @682
    598     UrlCanonicalizeA       = _UrlCanonicalizeA@16                 @683
    599     UrlCanonicalizeW       = _UrlCanonicalizeW@16                 @684
    600     UrlCombineA            = _UrlCombineA@20                      @685
    601     UrlCombineW            = _UrlCombineW@20                      @686
    602     UrlCompareA            = _UrlCompareA@12                      @687
    603     UrlCompareW            = _UrlCompareW@12                      @688
    604     UrlCreateFromPathA     = _UrlCreateFromPathA@16               @689
    605     UrlCreateFromPathW     = _UrlCreateFromPathW@16               @690
    606     UrlEscapeA             = _UrlEscapeA@16                       @691
    607     UrlEscapeW             = _UrlEscapeW@16                       @692
    608     UrlGetLocationA        = _UrlGetLocationA@4                   @693
    609     UrlGetLocationW        = _UrlGetLocationW@4                   @694
    610     UrlGetPartA            = _UrlGetPartA@20                      @695
    611     UrlGetPartW            = _UrlGetPartW@20                      @696
    612     UrlHashA               = _UrlHashA@12                         @697
    613     UrlHashW               = _UrlHashW@12                         @698
    614     UrlIsA                 = _UrlIsA@8                            @699
    615     UrlIsNoHistoryA        = _UrlIsNoHistoryA@4                   @700
    616     UrlIsNoHistoryW        = _UrlIsNoHistoryW@4                   @701
    617     UrlIsOpaqueA           = _UrlIsOpaqueA@4                      @702
    618     UrlIsOpaqueW           = _UrlIsOpaqueW@4                      @703
    619     UrlIsW                 = _UrlIsW@8                            @704
    620     UrlUnescapeA           = _UrlUnescapeA@16                     @705
    621     UrlUnescapeW           = _UrlUnescapeW@16                     @706
    622     wnsprintfA             = _wnsprintfA                          @707
    623     wnsprintfW             = _wnsprintfW                          @708
    624 ;    wvnsprintfA            = _wvnsprintfA@16                      @709
    625 ;    wvnsprintfW            = _wvnsprintfW@16                      @710
    626 
    627     SHRegGetPathA          = _SHRegGetPathA@20                    @802
    628     SHRegGetPathW          = _SHRegGetPathW@20                    @803
    629     SHRegDeleteUSValueA    = _SHRegDeleteUSValueA@12
    630     SHRegDeleteUSValueW    = _SHRegDeleteUSValueW@12
     566    StrCpyW                = _StrCpyW@8                           @1243
     567    StrDupA                = _StrDupA@4                           @1244
     568    StrDupW                = _StrDupW@4                           @1245
     569;   StrFormatByteSize64A   = _StrFormatByteSize64A@16             @1246
     570    StrFormatByteSizeA     = _StrFormatByteSizeA@12               @1247
     571    StrFormatByteSizeW     = _StrFormatByteSizeW@12               @1248
     572;   StrFormatKBSizeA       = _StrFormatKBSizeA@16                 @1249
     573;   StrFormatKBSizeW       = _StrFormatKBSizeW@16                 @1250
     574    StrFromTimeIntervalA   = _StrFromTimeIntervalA@16             @1251
     575    StrFromTimeIntervalW   = _StrFromTimeIntervalW@16             @1252
     576  ; IntlStrEqWorkerA       = _StrIsIntlEqualA@16                  @1253
     577  ; StrIsIntlEqualW        = _StrIsIntlEqualW@?                   @1254
     578    StrNCatA               = _StrNCatA@12                         @1255
     579    StrNCatW               = _StrNCatW@12                         @1256
     580    StrPBrkA               = _StrPBrkA@8                          @1257
     581    StrPBrkW               = _StrPBrkW@8                          @1258
     582    StrRChrA               = _StrRChrA@12                         @1259
     583    StrRChrIA              = _StrRChrIA@12                        @1260
     584    StrRChrIW              = _StrRChrIW@12                        @1261
     585    StrRChrW               = _StrRChrW@12                         @1262
     586    StrRStrIA              = _StrRStrIA@12                        @1263
     587    StrRStrIW              = _StrRStrIW@12                        @1264
     588    StrRetToBufA           = _StrRetToBufA@16                     @1265
     589    StrRetToBufW           = _StrRetToBufW@16                     @1266
     590;   StrRetToStrA           = _StrRetToStrA@12                     @1267
     591;   StrRetToStrW           = _StrRetToStrW@12                     @1268
     592    StrSpnA                = _StrSpnA@8                           @1269
     593    StrSpnW                = _StrSpnW@8                           @1270
     594    StrStrA                = _StrStrA@8                           @1271
     595    StrStrIA               = _StrStrIA@8                          @1272
     596    StrStrIW               = _StrStrIW@8                          @1273
     597    StrStrW                = _StrStrW@8                           @1274
     598    StrToIntA              = _StrToIntA@4                         @1275
     599    StrToIntExA            = _StrToIntExA@12                      @1276
     600    StrToIntExW            = _StrToIntExW@12                      @1277
     601    StrToIntW              = _StrToIntW@4                         @1278
     602    StrTrimA               = _StrTrimA@8                          @1279
     603  ; StrTrimW               = _StrTrimW@?                          @1280
     604 
     605    UrlApplySchemeA        = _UrlApplySchemeA@16                  @1281
     606    UrlApplySchemeW        = _UrlApplySchemeW@16                  @1282
     607    UrlCanonicalizeA       = _UrlCanonicalizeA@16                 @1283
     608    UrlCanonicalizeW       = _UrlCanonicalizeW@16                 @1284
     609    UrlCombineA            = _UrlCombineA@20                      @1285
     610    UrlCombineW            = _UrlCombineW@20                      @1286
     611    UrlCompareA            = _UrlCompareA@12                      @1287
     612    UrlCompareW            = _UrlCompareW@12                      @1288
     613    UrlCreateFromPathA     = _UrlCreateFromPathA@16               @1289
     614    UrlCreateFromPathW     = _UrlCreateFromPathW@16               @1290
     615    UrlEscapeA             = _UrlEscapeA@16                       @1291
     616    UrlEscapeW             = _UrlEscapeW@16                       @1292
     617    UrlGetLocationA        = _UrlGetLocationA@4                   @1293
     618    UrlGetLocationW        = _UrlGetLocationW@4                   @1294
     619    UrlGetPartA            = _UrlGetPartA@20                      @1295
     620    UrlGetPartW            = _UrlGetPartW@20                      @1296
     621    UrlHashA               = _UrlHashA@12                         @1297
     622    UrlHashW               = _UrlHashW@12                         @1298
     623    UrlIsA                 = _UrlIsA@8                            @1299
     624    UrlIsNoHistoryA        = _UrlIsNoHistoryA@4                   @1300
     625    UrlIsNoHistoryW        = _UrlIsNoHistoryW@4                   @1301
     626    UrlIsOpaqueA           = _UrlIsOpaqueA@4                      @1302
     627    UrlIsOpaqueW           = _UrlIsOpaqueW@4                      @1303
     628    UrlIsW                 = _UrlIsW@8                            @1304
     629    UrlUnescapeA           = _UrlUnescapeA@16                     @1305
     630    UrlUnescapeW           = _UrlUnescapeW@16                     @1306
     631    wnsprintfA             = _wnsprintfA                          @1307
     632    wnsprintfW             = _wnsprintfW                          @1308
     633    wvnsprintfA            = _wvnsprintfA@16                      @1309
     634    wvnsprintfW            = _wvnsprintfW@16                      @1310
     635
     636;; exported in later versions
     637    SHRegGetPathA          = _SHRegGetPathA@20                    @1402
     638    SHRegGetPathW          = _SHRegGetPathW@20                    @1403
     639    SHRegDeleteUSValueA    = _SHRegDeleteUSValueA@12              @1404
     640    SHRegDeleteUSValueW    = _SHRegDeleteUSValueW@12              @1405   
     641    SHRegSetPathA          = _SHRegSetPathA@20                    @1406
     642    SHRegSetPathW          = _SHRegSetPathW@20                    @1407
     643
  • trunk/src/shlwapi/shlwapi_main.c

    r7820 r8584  
    44 *  Copyright 1998 Marcus Meissner
    55 *  Copyright 1998 Juergen Schmied (jsch)
     6 *
     7 * This library is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU Lesser General Public
     9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * This library is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with this library; if not, write to the Free Software
     19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    620 */
    721
     
    923#include "winerror.h"
    1024#include "winreg.h"
    11 #include "debugtools.h"
     25#include "wine/debug.h"
    1226#define NO_SHLWAPI_STREAM
    13 #ifndef __WIN32OS2__
    1427#include "shlwapi.h"
    15 #endif
    1628
    17 DEFAULT_DEBUG_CHANNEL(shell);
     29WINE_DEFAULT_DEBUG_CHANNEL(shell);
    1830
    19 HINSTANCE shlwapi_hInstance = 0; 
     31HINSTANCE shlwapi_hInstance = 0;
    2032HMODULE SHLWAPI_hshell32 = 0;
    2133HMODULE SHLWAPI_hwinmm = 0;
     
    2335HMODULE SHLWAPI_hmpr = 0;
    2436HMODULE SHLWAPI_hmlang = 0;
     37HMODULE SHLWAPI_hversion = 0;
     38
     39DWORD SHLWAPI_ThreadRef_index = -1;
    2540
    2641/*************************************************************************
     
    3752          case DLL_PROCESS_ATTACH:
    3853            shlwapi_hInstance = hinstDLL;
     54            SHLWAPI_ThreadRef_index = TlsAlloc();
    3955            break;
    4056          case DLL_PROCESS_DETACH:
     
    4460            if (SHLWAPI_hmpr)      FreeLibrary(SHLWAPI_hmpr);
    4561            if (SHLWAPI_hmlang)    FreeLibrary(SHLWAPI_hmlang);
     62            if (SHLWAPI_hversion)  FreeLibrary(SHLWAPI_hversion);
     63            if (SHLWAPI_ThreadRef_index >= 0) TlsFree(SHLWAPI_ThreadRef_index);
    4664            break;
    4765        }
  • trunk/src/shlwapi/shlwapidbg.def

    r7900 r8584  
    1 ; $Id: shlwapidbg.def,v 1.1 2002-02-13 16:15:08 sandervl Exp $
     1; $Id: shlwapidbg.def,v 1.2 2002-06-07 08:02:19 sandervl Exp $
    22
    33; updated export ordinals to NT4 SP6 version of SHLWAPI.DLL
     
    7777                             _CreateAcceleratorTableW@8           @47 NONAME
    7878                             _CreateDCW@16                        @48 NONAME
    79                              _CreateDialogParamW@20               @49 NONAME ; @@@PH imcomplete
     79                             _CreateDialogParamA@20               @49 NONAME
    8080
    8181                             _CreateDirectoryW@8                  @50 NONAME
     
    194194                             _DbgSHLWAPI_153@12                      @153 NONAME
    195195                             _DbgSHLWAPI_154@12                      @154 NONAME
    196 ;;;;_DbgSHLWAPI_155@??                      @155 NONAME
     196                             _DbgSHLWAPI_155@8                       @155 NONAME
    197197                             _DbgSHLWAPI_156@8                       @156 NONAME
    198198                             _DbgSHLWAPI_158@8                       @158 NONAME
     
    209209                             _DbgSHLWAPI_172@8                       @172 NONAME
    210210                             _DbgSHLWAPI_174@8                       @174 NONAME
     211                             _DbgSHLWAPI_175@8                       @175 NONAME
    211212                             _DbgSHLWAPI_176@16                      @176 NONAME
    212213
     
    224225                             _DbgSHLWAPI_206@24                      @206 NONAME
    225226                             _DbgSHLWAPI_208@20                      @208 NONAME
     227                             _DbgSHLWAPI_209@4                       @209 NONAME
    226228
    227229                             _DbgSHLWAPI_210@12                      @210 NONAME
     
    257259
    258260                             _DbgSHLWAPI_289@12                      @289 NONAME
    259 ;;                             _DbgSHLWAPI_284@20                      @294 NONAME
     261                             _DbgSHLWAPI_294@20                      @294 NONAME
    260262                             _WritePrivateProfileStringW@16       @298 NONAME
    261263
     
    296298                             _MessageBoxW@16                      @340 NONAME
    297299                             _FindNextFileW@8                     @341 NONAME
    298   _SHLWAPI_342@12 = _InterlockedCompareExchange@12                @342 NONAME
     300                             _SHInterlockedCompareExchange@12     @342 NONAME
    299301                             _DbgSHLWAPI_346@12                      @346 NONAME
    300302                             _RegDeleteValueW@8                   @347 NONAME
    301303
     304                             _DbgSHLWAPI_350@8                       @350 NONAME
     305                             _DbgSHLWAPI_351@16                      @351 NONAME
     306                             _DbgSHLWAPI_352@16                      @352 NONAME
    302307                             _DbgSHLWAPI_356@12                      @356 NONAME
    303308                             _DbgSHLWAPI_357@20                      @357 NONAME
     
    342347
    343348                             _DbgSHLWAPI_413@4                       @413 NONAME
     349                             _DbgSHLWAPI_418@4                       @418 NONAME
    344350
    345351                             _TrackPopupMenuEx@24                 @428 NONAME
     
    349355                             _SendMessageTimeoutW@28              @434 NONAME
    350356
     357                             _DbgSHLWAPI_436@8                       @436 NONAME
    351358                             _DbgSHLWAPI_437@4                       @437 NONAME
    352359
     
    356363    ColorRGBToHLS          = _DbgColorRGBToHLS@16                    @445
    357364
    358     DllGetVersion          = _DbgSHLWAPI_DllGetVersion@4             @446
    359     GetMenuPosFromID       = _DbgGetMenuPosFromID@8                  @447
    360     HashData               = _DbgHashData@16                         @448
    361   ; IntlStrEqWorkerA       = _DbgStrIsIntlEqualA@16                  @449
    362   ; IntlStrEqWorkerW       = _DbgStrIsIntlEqualw@16                  @450
    363     PathAddBackslashA      = _DbgPathAddBackslashA@4                 @451
    364     PathAddBackslashW      = _DbgPathAddBackslashW@4                 @452
    365     PathAddExtensionA      = _DbgPathAddExtensionA@8                 @453
    366     PathAddExtensionW      = _DbgPathAddExtensionW@8                 @454
    367     PathAppendA            = _DbgPathAppendA@8                       @455
    368     PathAppendW            = _DbgPathAppendW@8                       @456
    369     PathBuildRootA         = _DbgPathBuildRootA@8                    @457
    370     PathBuildRootW         = _DbgPathBuildRootW@8                    @458
    371     PathCanonicalizeA      = _DbgPathCanonicalizeA@8                 @459
    372     PathCanonicalizeW      = _DbgPathCanonicalizeW@8                 @460
    373     PathCombineA           = _DbgPathCombineA@12                     @461
    374     PathCombineW           = _DbgPathCombineW@12                     @462
    375     PathCommonPrefixA      = _DbgPathCommonPrefixA@12                @463
    376     PathCommonPrefixW      = _DbgPathCommonPrefixW@12                @464
    377     PathCompactPathA       = _DbgPathCompactPathA@12                 @465
    378     PathCompactPathExA     = _DbgPathCompactPathExA@16               @466
    379     PathCompactPathExW     = _DbgPathCompactPathExW@16               @467
    380     PathCompactPathW       = _DbgPathCompactPathW@12                 @468
    381     PathCreateFromUrlA     = _DbgPathCreateFromUrlA@16               @469
    382     PathCreateFromUrlW     = _DbgPathCreateFromUrlW@16               @470
    383     PathFileExistsA        = _DbgPathFileExistsA@4                   @471
    384     PathFileExistsW        = _DbgPathFileExistsW@4                   @472
    385     PathFindExtensionA     = _DbgPathFindExtensionA@4                @473
    386     PathFindExtensionW     = _DbgPathFindExtensionW@4                @474
    387     PathFindFileNameA      = _DbgPathFindFileNameA@4                 @475
    388     PathFindFileNameW      = _DbgPathFindFileNameW@4                 @476
    389     PathFindNextComponentA = _DbgPathFindNextComponentA@4            @477
    390     PathFindNextComponentW = _DbgPathFindNextComponentW@4            @478
    391     PathFindOnPathA        = _DbgPathFindOnPathA@8                   @479
    392     PathFindOnPathW        = _DbgPathFindOnPathW@8                   @480
    393 ;   PathFindSuffixArrayA   = _DbgPathFindSuffixArrayA@12             @481
    394 ;   PathFindSuffixArrayW   = _DbgPathFindSuffixArrayW@12             @482
    395     PathGetArgsA           = _DbgPathGetArgsA@4                      @483
    396     PathGetArgsW           = _DbgPathGetArgsW@4                      @484
    397     PathGetCharTypeA       = _DbgPathGetCharTypeA@4                  @485
    398     PathGetCharTypeW       = _DbgPathGetCharTypeW@4                  @486
    399     PathGetDriveNumberA    = _DbgPathGetDriveNumberA@4               @487
    400     PathGetDriveNumberW    = _DbgPathGetDriveNumberW@4               @488
    401     PathIsContentTypeA     = _DbgPathIsContentTypeA@8                @489
    402     PathIsContentTypeW     = _DbgPathIsContentTypeW@8                @490
    403     PathIsDirectoryA       = _DbgPathIsDirectoryA@4                  @491
    404 ;   PathIsDirectoryEmptyA  = _DbgPathIsDirectoryEmptyA@4             @492
    405 ;   PathIsDirectoryEmptyW  = _DbgPathIsDirectoryEmptyW@4             @493
    406     PathIsDirectoryW       = _DbgPathIsDirectoryW@4                  @494
    407     PathIsFileSpecA        = _DbgPathIsFileSpecA@4                   @495
    408     PathIsFileSpecW        = _DbgPathIsFileSpecW@4                   @496
    409 ;   PathIsLFNFileSpecA     = _DbgPathIsLFNFileSpecA@4                @497
    410 ;   PathIsLFNFileSpecW     = _DbgPathIsLFNFileSpecW@4                @498
    411 ;   PathIsNetworkPathA     = _DbgPathIsNetworkPathA@4                @499
    412 ;   PathIsNetworkPathW     = _DbgPathIsNetworkPathW@4                @500
    413     PathIsPrefixA          = _DbgPathIsPrefixA@8                     @501
    414     PathIsPrefixW          = _DbgPathIsPrefixW@8                     @502
    415     PathIsRelativeA        = _DbgPathIsRelativeA@4                   @503
    416     PathIsRelativeW        = _DbgPathIsRelativeW@4                   @504
    417     PathIsRootA            = _DbgPathIsRootA@4                       @505
    418     PathIsRootW            = _DbgPathIsRootW@4                       @506
    419     PathIsSameRootA        = _DbgPathIsSameRootA@8                   @507
    420     PathIsSameRootW        = _DbgPathIsSameRootW@8                   @508
    421     PathIsSystemFolderA    = _DbgPathIsSystemFolderA@8               @509
    422     PathIsSystemFolderW    = _DbgPathIsSystemFolderW@8               @510
    423     PathIsUNCA             = _DbgPathIsUNCA@4                        @511
    424     PathIsUNCServerA       = _DbgPathIsUNCServerA@4                  @512
    425     PathIsUNCServerShareA  = _DbgPathIsUNCServerShareA@4             @513
    426     PathIsUNCServerShareW  = _DbgPathIsUNCServerShareW@4             @514
    427     PathIsUNCServerW       = _DbgPathIsUNCServerW@4                  @515
    428     PathIsUNCW             = _DbgPathIsUNCW@4                        @516
    429     PathIsURLA             = _DbgPathIsURLA@4                        @517
    430     PathIsURLW             = _DbgPathIsURLW@4                        @518
    431     PathMakePrettyA        = _DbgPathMakePrettyA@4                   @519
    432     PathMakePrettyW        = _DbgPathMakePrettyW@4                   @520
    433     PathMakeSystemFolderA  = _DbgPathMakeSystemFolderA@4             @521
    434     PathMakeSystemFolderW  = _DbgPathMakeSystemFolderW@4             @522
    435     PathMatchSpecA         = _DbgPathMatchSpecA@8                    @523
    436     PathMatchSpecW         = _DbgPathMatchSpecW@8                    @524
    437     PathParseIconLocationA = _DbgPathParseIconLocationA@4            @525
    438     PathParseIconLocationW = _DbgPathParseIconLocationW@4            @526
    439     PathQuoteSpacesA       = _DbgPathQuoteSpacesA@4                  @527
    440     PathQuoteSpacesW       = _DbgPathQuoteSpacesW@4                  @528
    441     PathRelativePathToA    = _DbgPathRelativePathToA@20              @529
    442     PathRelativePathToW    = _DbgPathRelativePathToW@20              @530
    443     PathRemoveArgsA        = _DbgPathRemoveArgsA@4                   @531
    444     PathRemoveArgsW        = _DbgPathRemoveArgsW@4                   @532
    445     PathRemoveBackslashA   = _DbgPathRemoveBackslashA@4              @533
    446     PathRemoveBackslashW   = _DbgPathRemoveBackslashW@4              @534
    447     PathRemoveBlanksA      = _DbgPathRemoveBlanksA@4                 @535
    448     PathRemoveBlanksW      = _DbgPathRemoveBlanksW@4                 @536
    449     PathRemoveExtensionA   = _DbgPathRemoveExtensionA@4              @537
    450     PathRemoveExtensionW   = _DbgPathRemoveExtensionW@4              @538
    451     PathRemoveFileSpecA    = _DbgPathRemoveFileSpecA@4               @539
    452     PathRemoveFileSpecW    = _DbgPathRemoveFileSpecW@4               @540
    453     PathRenameExtensionA   = _DbgPathRenameExtensionA@8              @541
    454     PathRenameExtensionW   = _DbgPathRenameExtensionW@8              @542
    455     PathSearchAndQualifyA  = _DbgPathSearchAndQualifyA@12            @543
    456     PathSearchAndQualifyW  = _DbgPathSearchAndQualifyW@12            @544
    457     PathSetDlgItemPathA    = _DbgPathSetDlgItemPathA@12              @545
    458     PathSetDlgItemPathW    = _DbgPathSetDlgItemPathW@12              @546
    459     PathSkipRootA          = _DbgPathSkipRootA@4                     @547
    460     PathSkipRootW          = _DbgPathSkipRootW@4                     @548
    461     PathStripPathA         = _DbgPathStripPathA@4                    @549
    462     PathStripPathW         = _DbgPathStripPathW@4                    @550
    463     PathStripToRootA       = _DbgPathStripToRootA@4                  @551
    464     PathStripToRootW       = _DbgPathStripToRootW@4                  @552
    465 ;   PathUndecorateA        = _DbgPathUndecorateA@4                   @553
    466 ;   PathUndecorateW        = _DbgPathUndecorateW@4                   @554
    467     PathUnmakeSystemFolderA= _DbgPathUnmakeSystemFolderA@4           @555
    468     PathUnmakeSystemFolderW= _DbgPathUnmakeSystemFolderW@4           @556
    469     PathUnquoteSpacesA     = _DbgPathUnquoteSpacesA@4                @557
    470     PathUnquoteSpacesW     = _DbgPathUnquoteSpacesW@4                @558
    471 
    472 ;   SHAutoComplete         = _DbgSHAutoComplete@8                    @559
    473   ; SHCopyKeyA             = _DbgSHCopyKeyA@?                        @560
    474   ; SHCopyKeyW             = _DbgSHCopyKeyW@?                        @561
    475     SHCreateShellPalette   = _DbgSHCreateShellPalette@4              @562
    476   ; SHCreateStreamOnFileA  = _DbgSHCreateStreamOnFileA@?             @563
    477   ; SHCreateStreamOnFileW  = _DbgSHCreateStreamOnFileW@?             @564
    478   ; SHCreateStreamWrapper  = _DbgSHCreateStreamWrapper@?             @565
    479 
    480     SHDeleteEmptyKeyA      = _DbgSHDeleteEmptyKeyA@8                 @567
    481     SHDeleteEmptyKeyW      = _DbgSHDeleteEmptyKeyW@8                 @568
    482     SHDeleteKeyA           = _DbgSHDeleteKeyA@8                      @569
    483     SHDeleteKeyW           = _DbgSHDeleteKeyW@8                      @570
    484     SHDeleteOrphanKeyA     = _DbgSHDeleteOrphanKeyA@8                @571
    485     SHDeleteOrphanKeyW     = _DbgSHDeleteOrphanKeyW@8                @572
    486     SHDeleteValueA         = _DbgSHDeleteValueA@12                   @573
    487     SHDeleteValueW         = _DbgSHDeleteValueW@12                   @574
    488     SHEnumKeyExA           = _DbgSHEnumKeyExA@16                     @575
    489     SHEnumKeyExW           = _DbgSHEnumKeyExW@16                     @576
    490     SHEnumValueA           = _DbgSHEnumValueA@28                     @577
    491     SHEnumValueW           = _DbgSHEnumValueW@28                     @578
    492     _SHGetInstanceExplorer = _Dbg_SHGetInstanceExplorer@4            @579
    493     SHGetInverseCMAP       = _DbgSHGetInverseCMAP@8                  @580
    494 ;   SHGetThreadRef         = _DbgSHGetThreadRef@?                    @581
    495     SHGetValueA            = _DbgSHGetValueA@24                      @582
    496     SHGetValueW            = _DbgSHGetValueW@24                      @583
    497     SHIsLowMemoryMachine   = _DbgSHIsLowMemoryMachine@4              @584
    498     SHOpenRegStream2A      = _DbgSHOpenRegStreamA@16                 @585
    499     SHOpenRegStream2W      = _DbgSHOpenRegStreamW@16                 @586
    500     SHOpenRegStreamA       = _DbgSHOpenRegStreamA@16                 @587
    501     SHOpenRegStreamW       = _DbgSHOpenRegStreamW@16                 @588
    502     SHQueryInfoKeyA        = _DbgSHQueryInfoKeyA@20                  @589
    503     SHQueryInfoKeyW        = _DbgSHQueryInfoKeyW@20                  @590
    504     SHQueryValueExA        = _DbgSHQueryValueExA@24                  @591
    505     SHQueryValueExW        = _DbgSHQueryValueExW@24                  @592
    506     SHRegCloseUSKey        = _DbgSHRegCloseUSKey@4                   @593
    507     SHRegCreateUSKeyA      = _DbgSHRegCreateUSKeyA@20                @594
    508     SHRegCreateUSKeyW      = _DbgSHRegCreateUSKeyW@20                @595
    509     SHRegDeleteEmptyUSKeyA = _DbgSHRegDeleteEmptyUSKeyA@12           @596
    510     SHRegDeleteEmptyUSKeyW = _DbgSHRegDeleteEmptyUSKeyW@12           @597
    511     SHRegDeleteUSKeyA      = _DbgSHRegDeleteUSKeyA@12                @598
    512     SHRegDeleteUSKeyW      = _DbgSHRegDeleteUSKeyW@12                @599
    513   ; SHRegDuplicateHKey     = _DbgSHRegDuplicateHKey@?                @600
    514     SHRegEnumUSKeyA        = _DbgSHRegEnumUSKeyA@20                  @601
    515     SHRegEnumUSKeyW        = _DbgSHRegEnumUSKeyW@20                  @602
    516     SHRegEnumUSValueA      = _DbgSHRegEnumUSValueA@32                @603
    517     SHRegEnumUSValueW      = _DbgSHRegEnumUSValueW@32                @604
    518     SHRegGetBoolUSValueA   = _DbgSHRegGetBoolUSValueA@16             @605
    519     SHRegGetBoolUSValueW   = _DbgSHRegGetBoolUSValueW@16             @606
    520     SHRegGetUSValueA       = _DbgSHRegGetUSValueA@32                 @607
    521     SHRegGetUSValueW       = _DbgSHRegGetUSValueW@32                 @608
    522     SHRegOpenUSKeyA        = _DbgSHRegOpenUSKeyA@20                  @609
    523     SHRegOpenUSKeyW        = _DbgSHRegOpenUSKeyW@20                  @610
    524 ;    SHRegQueryInfoKeyA     = _DbgSHRegQueryInfoKeyA@24               @611
    525 ;    SHRegQueryInfoKeyW     = _DbgSHRegQueryInfoKeyW@24               @612
    526     SHRegQueryUSValueA     = _DbgSHRegQueryUSValueA@32               @613
    527     SHRegQueryUSValueW     = _DbgSHRegQueryUSValueW@32               @614
    528     SHRegSetUSValueA       = _DbgSHRegSetUSValueA@24                 @615
    529     SHRegSetUSValueW       = _DbgSHRegSetUSValueW@24                 @616
    530     SHRegWriteUSValueA     = _DbgSHRegWriteUSValueA@24               @617
    531     SHRegWriteUSValueW     = _DbgSHRegWriteUSValueW@24               @618
    532 ;   SHSetSetThreadRef      = _DbgSHSetThreadRef@?                    @619
    533     SHSetValueA            = _DbgSHSetValueA@24                      @620
    534     SHSetValueW            = _DbgSHSetValueW@24                      @621
    535 ;   SHSkipJunction         = _DbgSHSkipJunction@8                    @622
    536 ;   SHStrDupA              = _DbgSHStrDupA@?                         @623
    537 ;   SHStrDupW              = _DbgSHStrDUpW@?                         @624
    538     StrCSpnA               = _DbgStrCSpnA@8                          @625
    539   ; StrCSpnIA              = _DbgStrCSpnIA@?                         @626
    540   ; StrCSpnIW              = _DbgStrCSpnIW@?                         @627
    541     StrCSpnW               = _DbgStrCSpnW@8                          @628
    542     StrCatBuffA            = _DbgStrCatBuffA@12                      @629
    543     StrCatBuffW            = _DbgStrCatBuffW@12                      @630
     365    DllGetVersion          = _DbgSHLWAPI_DllGetVersion@4             @1046
     366    GetMenuPosFromID       = _DbgGetMenuPosFromID@8                  @1047
     367    HashData               = _DbgHashData@16                         @1048
     368  ; IntlStrEqWorkerA       = _DbgStrIsIntlEqualA@16                  @1049
     369  ; IntlStrEqWorkerW       = _DbgStrIsIntlEqualw@16                  @1050
     370    PathAddBackslashA      = _DbgPathAddBackslashA@4                 @1051
     371    PathAddBackslashW      = _DbgPathAddBackslashW@4                 @1052
     372    PathAddExtensionA      = _DbgPathAddExtensionA@8                 @1053
     373    PathAddExtensionW      = _DbgPathAddExtensionW@8                 @1054
     374    PathAppendA            = _DbgPathAppendA@8                       @1055
     375    PathAppendW            = _DbgPathAppendW@8                       @1056
     376    PathBuildRootA         = _DbgPathBuildRootA@8                    @1057
     377    PathBuildRootW         = _DbgPathBuildRootW@8                    @1058
     378    PathCanonicalizeA      = _DbgPathCanonicalizeA@8                 @1059
     379    PathCanonicalizeW      = _DbgPathCanonicalizeW@8                 @1060
     380    PathCombineA           = _DbgPathCombineA@12                     @1061
     381    PathCombineW           = _DbgPathCombineW@12                     @1062
     382    PathCommonPrefixA      = _DbgPathCommonPrefixA@12                @1063
     383    PathCommonPrefixW      = _DbgPathCommonPrefixW@12                @1064
     384    PathCompactPathA       = _DbgPathCompactPathA@12                 @1065
     385    PathCompactPathExA     = _DbgPathCompactPathExA@16               @1066
     386    PathCompactPathExW     = _DbgPathCompactPathExW@16               @1067
     387    PathCompactPathW       = _DbgPathCompactPathW@12                 @1068
     388    PathCreateFromUrlA     = _DbgPathCreateFromUrlA@16               @1069
     389    PathCreateFromUrlW     = _DbgPathCreateFromUrlW@16               @1070
     390    PathFileExistsA        = _DbgPathFileExistsA@4                   @1071
     391    PathFileExistsW        = _DbgPathFileExistsW@4                   @1072
     392    PathFindExtensionA     = _DbgPathFindExtensionA@4                @1073
     393    PathFindExtensionW     = _DbgPathFindExtensionW@4                @1074
     394    PathFindFileNameA      = _DbgPathFindFileNameA@4                 @1075
     395    PathFindFileNameW      = _DbgPathFindFileNameW@4                 @1076
     396    PathFindNextComponentA = _DbgPathFindNextComponentA@4            @1077
     397    PathFindNextComponentW = _DbgPathFindNextComponentW@4            @1078
     398    PathFindOnPathA        = _DbgPathFindOnPathA@8                   @1079
     399    PathFindOnPathW        = _DbgPathFindOnPathW@8                   @1080
     400    PathFindSuffixArrayA   = _DbgPathFindSuffixArrayA@12             @1081
     401    PathFindSuffixArrayW   = _DbgPathFindSuffixArrayW@12             @1082
     402    PathGetArgsA           = _DbgPathGetArgsA@4                      @1083
     403    PathGetArgsW           = _DbgPathGetArgsW@4                      @1084
     404    PathGetCharTypeA       = _DbgPathGetCharTypeA@4                  @1085
     405    PathGetCharTypeW       = _DbgPathGetCharTypeW@4                  @1086
     406    PathGetDriveNumberA    = _DbgPathGetDriveNumberA@4               @1087
     407    PathGetDriveNumberW    = _DbgPathGetDriveNumberW@4               @1088
     408    PathIsContentTypeA     = _DbgPathIsContentTypeA@8                @1089
     409    PathIsContentTypeW     = _DbgPathIsContentTypeW@8                @1090
     410    PathIsDirectoryA       = _DbgPathIsDirectoryA@4                  @1091
     411    PathIsDirectoryEmptyA  = _DbgPathIsDirectoryEmptyA@4             @1092
     412    PathIsDirectoryEmptyW  = _DbgPathIsDirectoryEmptyW@4             @1093
     413    PathIsDirectoryW       = _DbgPathIsDirectoryW@4                  @1094
     414    PathIsFileSpecA        = _DbgPathIsFileSpecA@4                   @1095
     415    PathIsFileSpecW        = _DbgPathIsFileSpecW@4                   @1096
     416    PathIsLFNFileSpecA     = _DbgPathIsLFNFileSpecA@4                @1097
     417    PathIsLFNFileSpecW     = _DbgPathIsLFNFileSpecW@4                @1098
     418    PathIsNetworkPathA     = _DbgPathIsNetworkPathA@4                @1099
     419    PathIsNetworkPathW     = _DbgPathIsNetworkPathW@4                @1100
     420    PathIsPrefixA          = _DbgPathIsPrefixA@8                     @1101
     421    PathIsPrefixW          = _DbgPathIsPrefixW@8                     @1102
     422    PathIsRelativeA        = _DbgPathIsRelativeA@4                   @1103
     423    PathIsRelativeW        = _DbgPathIsRelativeW@4                   @1104
     424    PathIsRootA            = _DbgPathIsRootA@4                       @1105
     425    PathIsRootW            = _DbgPathIsRootW@4                       @1106
     426    PathIsSameRootA        = _DbgPathIsSameRootA@8                   @1107
     427    PathIsSameRootW        = _DbgPathIsSameRootW@8                   @1108
     428    PathIsSystemFolderA    = _DbgPathIsSystemFolderA@8               @1109
     429    PathIsSystemFolderW    = _DbgPathIsSystemFolderW@8               @1110
     430    PathIsUNCA             = _DbgPathIsUNCA@4                        @1111
     431    PathIsUNCServerA       = _DbgPathIsUNCServerA@4                  @1112
     432    PathIsUNCServerShareA  = _DbgPathIsUNCServerShareA@4             @1113
     433    PathIsUNCServerShareW  = _DbgPathIsUNCServerShareW@4             @1114
     434    PathIsUNCServerW       = _DbgPathIsUNCServerW@4                  @1115
     435    PathIsUNCW             = _DbgPathIsUNCW@4                        @1116
     436    PathIsURLA             = _DbgPathIsURLA@4                        @1117
     437    PathIsURLW             = _DbgPathIsURLW@4                        @1118
     438    PathMakePrettyA        = _DbgPathMakePrettyA@4                   @1119
     439    PathMakePrettyW        = _DbgPathMakePrettyW@4                   @1120
     440    PathMakeSystemFolderA  = _DbgPathMakeSystemFolderA@4             @1121
     441    PathMakeSystemFolderW  = _DbgPathMakeSystemFolderW@4             @1122
     442    PathMatchSpecA         = _DbgPathMatchSpecA@8                    @1123
     443    PathMatchSpecW         = _DbgPathMatchSpecW@8                    @1124
     444    PathParseIconLocationA = _DbgPathParseIconLocationA@4            @1125
     445    PathParseIconLocationW = _DbgPathParseIconLocationW@4            @1126
     446    PathQuoteSpacesA       = _DbgPathQuoteSpacesA@4                  @1127
     447    PathQuoteSpacesW       = _DbgPathQuoteSpacesW@4                  @1128
     448    PathRelativePathToA    = _DbgPathRelativePathToA@20              @1129
     449    PathRelativePathToW    = _DbgPathRelativePathToW@20              @1130
     450    PathRemoveArgsA        = _DbgPathRemoveArgsA@4                   @1131
     451    PathRemoveArgsW        = _DbgPathRemoveArgsW@4                   @1132
     452    PathRemoveBackslashA   = _DbgPathRemoveBackslashA@4              @1133
     453    PathRemoveBackslashW   = _DbgPathRemoveBackslashW@4              @1134
     454    PathRemoveBlanksA      = _DbgPathRemoveBlanksA@4                 @1135
     455    PathRemoveBlanksW      = _DbgPathRemoveBlanksW@4                 @1136
     456    PathRemoveExtensionA   = _DbgPathRemoveExtensionA@4              @1137
     457    PathRemoveExtensionW   = _DbgPathRemoveExtensionW@4              @1138
     458    PathRemoveFileSpecA    = _DbgPathRemoveFileSpecA@4               @1139
     459    PathRemoveFileSpecW    = _DbgPathRemoveFileSpecW@4               @1140
     460    PathRenameExtensionA   = _DbgPathRenameExtensionA@8              @1141
     461    PathRenameExtensionW   = _DbgPathRenameExtensionW@8              @1142
     462    PathSearchAndQualifyA  = _DbgPathSearchAndQualifyA@12            @1143
     463    PathSearchAndQualifyW  = _DbgPathSearchAndQualifyW@12            @1144
     464    PathSetDlgItemPathA    = _DbgPathSetDlgItemPathA@12              @1145
     465    PathSetDlgItemPathW    = _DbgPathSetDlgItemPathW@12              @1146
     466    PathSkipRootA          = _DbgPathSkipRootA@4                     @1147
     467    PathSkipRootW          = _DbgPathSkipRootW@4                     @1148
     468    PathStripPathA         = _DbgPathStripPathA@4                    @1149
     469    PathStripPathW         = _DbgPathStripPathW@4                    @1150
     470    PathStripToRootA       = _DbgPathStripToRootA@4                  @1151
     471    PathStripToRootW       = _DbgPathStripToRootW@4                  @1152
     472    PathUndecorateA        = _DbgPathUndecorateA@4                   @1153
     473    PathUndecorateW        = _DbgPathUndecorateW@4                   @1154
     474    PathUnmakeSystemFolderA= _DbgPathUnmakeSystemFolderA@4           @1155
     475    PathUnmakeSystemFolderW= _DbgPathUnmakeSystemFolderW@4           @1156
     476    PathUnquoteSpacesA     = _DbgPathUnquoteSpacesA@4                @1157
     477    PathUnquoteSpacesW     = _DbgPathUnquoteSpacesW@4                @1158
     478
     479;   SHAutoComplete         = _DbgSHAutoComplete@8                    @1159
     480  ; SHCopyKeyA             = _DbgSHCopyKeyA@?                        @1160
     481  ; SHCopyKeyW             = _DbgSHCopyKeyW@?                        @1161
     482    SHCreateShellPalette   = _DbgSHCreateShellPalette@4              @1162
     483  ; SHCreateStreamOnFileA  = _DbgSHCreateStreamOnFileA@?             @1163
     484  ; SHCreateStreamOnFileW  = _DbgSHCreateStreamOnFileW@?             @1164
     485  ; SHCreateStreamWrapper  = _DbgSHCreateStreamWrapper@?             @1165
     486
     487    SHDeleteEmptyKeyA      = _DbgSHDeleteEmptyKeyA@8                 @1167
     488    SHDeleteEmptyKeyW      = _DbgSHDeleteEmptyKeyW@8                 @1168
     489    SHDeleteKeyA           = _DbgSHDeleteKeyA@8                      @1169
     490    SHDeleteKeyW           = _DbgSHDeleteKeyW@8                      @1170
     491    SHDeleteOrphanKeyA     = _DbgSHDeleteOrphanKeyA@8                @1171
     492    SHDeleteOrphanKeyW     = _DbgSHDeleteOrphanKeyW@8                @1172
     493    SHDeleteValueA         = _DbgSHDeleteValueA@12                   @1173
     494    SHDeleteValueW         = _DbgSHDeleteValueW@12                   @1174
     495    SHEnumKeyExA           = _DbgSHEnumKeyExA@16                     @1175
     496    SHEnumKeyExW           = _DbgSHEnumKeyExW@16                     @1176
     497    SHEnumValueA           = _DbgSHEnumValueA@28                     @1177
     498    SHEnumValueW           = _DbgSHEnumValueW@28                     @1178
     499    _SHGetInstanceExplorer = _Dbg_SHGetInstanceExplorer@4            @1179
     500    SHGetInverseCMAP       = _DbgSHGetInverseCMAP@8                  @1180
     501    SHGetThreadRef         = _DbgSHGetThreadRef@4                    @1181
     502    SHGetValueA            = _DbgSHGetValueA@24                      @1182
     503    SHGetValueW            = _DbgSHGetValueW@24                      @1183
     504    SHIsLowMemoryMachine   = _DbgSHIsLowMemoryMachine@4              @1184
     505    SHOpenRegStream2A      = _DbgSHOpenRegStreamA@16                 @1185
     506    SHOpenRegStream2W      = _DbgSHOpenRegStreamW@16                 @1186
     507    SHOpenRegStreamA       = _DbgSHOpenRegStreamA@16                 @1187
     508    SHOpenRegStreamW       = _DbgSHOpenRegStreamW@16                 @1188
     509    SHQueryInfoKeyA        = _DbgSHQueryInfoKeyA@20                  @1189
     510    SHQueryInfoKeyW        = _DbgSHQueryInfoKeyW@20                  @1190
     511    SHQueryValueExA        = _DbgSHQueryValueExA@24                  @1191
     512    SHQueryValueExW        = _DbgSHQueryValueExW@24                  @1192
     513    SHRegCloseUSKey        = _DbgSHRegCloseUSKey@4                   @1193
     514    SHRegCreateUSKeyA      = _DbgSHRegCreateUSKeyA@20                @1194
     515    SHRegCreateUSKeyW      = _DbgSHRegCreateUSKeyW@20                @1195
     516    SHRegDeleteEmptyUSKeyA = _DbgSHRegDeleteEmptyUSKeyA@12           @1196
     517    SHRegDeleteEmptyUSKeyW = _DbgSHRegDeleteEmptyUSKeyW@12           @1197
     518    SHRegDeleteUSKeyA      = _DbgSHRegDeleteUSKeyA@12                @1198
     519    SHRegDeleteUSKeyW      = _DbgSHRegDeleteUSKeyW@12                @1199
     520    SHRegDuplicateHKey     = _DbgSHRegDuplicateHKey@4                @1200
     521    SHRegEnumUSKeyA        = _DbgSHRegEnumUSKeyA@20                  @1201
     522    SHRegEnumUSKeyW        = _DbgSHRegEnumUSKeyW@20                  @1202
     523    SHRegEnumUSValueA      = _DbgSHRegEnumUSValueA@32                @1203
     524    SHRegEnumUSValueW      = _DbgSHRegEnumUSValueW@32                @1204
     525    SHRegGetBoolUSValueA   = _DbgSHRegGetBoolUSValueA@16             @1205
     526    SHRegGetBoolUSValueW   = _DbgSHRegGetBoolUSValueW@16             @1206
     527    SHRegGetUSValueA       = _DbgSHRegGetUSValueA@32                 @1207
     528    SHRegGetUSValueW       = _DbgSHRegGetUSValueW@32                 @1208
     529    SHRegOpenUSKeyA        = _DbgSHRegOpenUSKeyA@20                  @1209
     530    SHRegOpenUSKeyW        = _DbgSHRegOpenUSKeyW@20                  @1210
     531;    SHRegQueryInfoKeyA     = _DbgSHRegQueryInfoKeyA@24               @1211
     532;    SHRegQueryInfoKeyW     = _DbgSHRegQueryInfoKeyW@24               @1212
     533    SHRegQueryUSValueA     = _DbgSHRegQueryUSValueA@32               @1213
     534    SHRegQueryUSValueW     = _DbgSHRegQueryUSValueW@32               @1214
     535    SHRegSetUSValueA       = _DbgSHRegSetUSValueA@24                 @1215
     536    SHRegSetUSValueW       = _DbgSHRegSetUSValueW@24                 @1216
     537    SHRegWriteUSValueA     = _DbgSHRegWriteUSValueA@24               @1217
     538    SHRegWriteUSValueW     = _DbgSHRegWriteUSValueW@24               @1218
     539    SHSetSetThreadRef      = _DbgSHSetThreadRef@4                    @1219
     540    SHSetValueA            = _DbgSHSetValueA@24                      @1220
     541    SHSetValueW            = _DbgSHSetValueW@24                      @1221
     542;   SHSkipJunction         = _DbgSHSkipJunction@8                    @1222
     543;   SHStrDupA              = _DbgSHStrDupA@?                         @1223
     544;   SHStrDupW              = _DbgSHStrDUpW@?                         @1224
     545    StrCSpnA               = _DbgStrCSpnA@8                          @1225
     546  ; StrCSpnIA              = _DbgStrCSpnIA@?                         @1226
     547  ; StrCSpnIW              = _DbgStrCSpnIW@?                         @1227
     548    StrCSpnW               = _DbgStrCSpnW@8                          @1228
     549    StrCatBuffA            = _DbgStrCatBuffA@12                      @1229
     550    StrCatBuffW            = _DbgStrCatBuffW@12                      @1230
    544551;    StrCatA                = _DbgStrCatA@8                                 ; not exported ?
    545     StrCatW                = _DbgStrCatW@8                           @631
    546     StrChrA                = _DbgStrChrA@8                           @632
    547     StrChrIA               = _DbgStrChrIA@8                          @633
    548     StrChrIW               = _DbgStrChrIW@8                          @634
    549     StrChrW                = _DbgStrChrW@8                           @635
    550     StrCmpIW               = _lstrcmpiW@8                         @636
    551     StrCmpNA               = _DbgStrCmpNA@12                         @637
    552     StrCmpNIA              = _DbgStrCmpNIA@12                        @638
    553     StrCmpNIW              = _DbgStrCmpNIW@12                        @639
    554     StrCmpNW               = _DbgStrCmpNW@12                         @640
    555     StrCmpW                = _lstrcmpW@8                          @641
    556     StrCpyNW               = _lstrcpynW@12                        @642
     552    StrCatW                = _DbgStrCatW@8                           @1231
     553    StrChrA                = _DbgStrChrA@8                           @1232
     554    StrChrIA               = _DbgStrChrIA@8                          @1233
     555    StrChrIW               = _DbgStrChrIW@8                          @1234
     556    StrChrW                = _DbgStrChrW@8                           @1235
     557    StrCmpIW               = _lstrcmpiW@8                         @1236
     558    StrCmpNA               = _DbgStrCmpNA@12                         @1237
     559    StrCmpNIA              = _DbgStrCmpNIA@12                        @1238
     560    StrCmpNIW              = _DbgStrCmpNIW@12                        @1239
     561    StrCmpNW               = _DbgStrCmpNW@12                         @1240
     562    StrCmpW                = _lstrcmpW@8                          @1241
     563    StrCpyNW               = _lstrcpynW@12                        @1242
    557564;;;    StrCpyA                = _DbgStrCpyA@8                                 ; not exported ?
    558     StrCpyW                = _DbgStrCpyW@8                           @643
    559     StrDupA                = _DbgStrDupA@4                           @644
    560     StrDupW                = _DbgStrDupW@4                           @645
    561 ;   StrFormatByteSize64A   = _DbgStrFormatByteSize64A@16             @646
    562     StrFormatByteSizeA     = _DbgStrFormatByteSizeA@12               @647
    563     StrFormatByteSizeW     = _DbgStrFormatByteSizeW@12               @648
    564 ;   StrFormatKBSizeA       = _DbgStrFormatKBSizeA@16                 @649
    565 ;   StrFormatKBSizeW       = _DbgStrFormatKBSizeW@16                 @650
    566     StrFromTimeIntervalA   = _DbgStrFromTimeIntervalA@16             @651
    567     StrFromTimeIntervalW   = _DbgStrFromTimeIntervalW@16             @652
    568   ; IntlStrEqWorkerA       = _DbgStrIsIntlEqualA@16                  @653
    569   ; StrIsIntlEqualW        = _DbgStrIsIntlEqualW@?                   @654
    570     StrNCatA               = _DbgStrNCatA@12                         @655
    571     StrNCatW               = _DbgStrNCatW@12                         @656
    572     StrPBrkA               = _DbgStrPBrkA@8                          @657
    573     StrPBrkW               = _DbgStrPBrkW@8                          @658
    574     StrRChrA               = _DbgStrRChrA@12                         @659
    575     StrRChrIA              = _DbgStrRChrIA@12                        @660
    576     StrRChrIW              = _DbgStrRChrIW@12                        @661
    577     StrRChrW               = _DbgStrRChrW@12                         @662
    578     StrRStrIA              = _DbgStrRStrIA@12                        @663
    579     StrRStrIW              = _DbgStrRStrIW@12                        @664
    580     StrRetToBufA           = _DbgStrRetToBufA@16                     @665
    581     StrRetToBufW           = _DbgStrRetToBufW@16                     @666
    582 ;   StrRetToStrA           = _DbgStrRetToStrA@12                     @667
    583 ;   StrRetToStrW           = _DbgStrRetToStrW@12                     @668
    584     StrSpnA                = _DbgStrSpnA@8                           @669
    585     StrSpnW                = _DbgStrSpnW@8                           @670
    586     StrStrA                = _DbgStrStrA@8                           @671
    587     StrStrIA               = _DbgStrStrIA@8                          @672
    588     StrStrIW               = _DbgStrStrIW@8                          @673
    589     StrStrW                = _DbgStrStrW@8                           @674
    590     StrToIntA              = _DbgStrToIntA@4                         @675
    591     StrToIntExA            = _DbgStrToIntExA@12                      @676
    592     StrToIntExW            = _DbgStrToIntExW@12                      @677
    593     StrToIntW              = _DbgStrToIntW@4                         @678
    594     StrTrimA               = _DbgStrTrimA@8                          @679
    595   ; StrTrimW               = _DbgStrTrimW@?                          @680
    596     UrlApplySchemeA        = _DbgUrlApplySchemeA@16                  @681
    597     UrlApplySchemeW        = _DbgUrlApplySchemeW@16                  @682
    598     UrlCanonicalizeA       = _DbgUrlCanonicalizeA@16                 @683
    599     UrlCanonicalizeW       = _DbgUrlCanonicalizeW@16                 @684
    600     UrlCombineA            = _DbgUrlCombineA@20                      @685
    601     UrlCombineW            = _DbgUrlCombineW@20                      @686
    602     UrlCompareA            = _DbgUrlCompareA@12                      @687
    603     UrlCompareW            = _DbgUrlCompareW@12                      @688
    604     UrlCreateFromPathA     = _DbgUrlCreateFromPathA@16               @689
    605     UrlCreateFromPathW     = _DbgUrlCreateFromPathW@16               @690
    606     UrlEscapeA             = _DbgUrlEscapeA@16                       @691
    607     UrlEscapeW             = _DbgUrlEscapeW@16                       @692
    608     UrlGetLocationA        = _DbgUrlGetLocationA@4                   @693
    609     UrlGetLocationW        = _DbgUrlGetLocationW@4                   @694
    610     UrlGetPartA            = _DbgUrlGetPartA@20                      @695
    611     UrlGetPartW            = _DbgUrlGetPartW@20                      @696
    612     UrlHashA               = _DbgUrlHashA@12                         @697
    613     UrlHashW               = _DbgUrlHashW@12                         @698
    614     UrlIsA                 = _DbgUrlIsA@8                            @699
    615     UrlIsNoHistoryA        = _DbgUrlIsNoHistoryA@4                   @700
    616     UrlIsNoHistoryW        = _DbgUrlIsNoHistoryW@4                   @701
    617     UrlIsOpaqueA           = _DbgUrlIsOpaqueA@4                      @702
    618     UrlIsOpaqueW           = _DbgUrlIsOpaqueW@4                      @703
    619     UrlIsW                 = _DbgUrlIsW@8                            @704
    620     UrlUnescapeA           = _DbgUrlUnescapeA@16                     @705
    621     UrlUnescapeW           = _DbgUrlUnescapeW@16                     @706
    622     wnsprintfA             = _wnsprintfA                          @707
    623     wnsprintfW             = _wnsprintfW                          @708
    624 ;    wvnsprintfA            = _DbgwvnsprintfA@16                      @709
    625 ;    wvnsprintfW            = _DbgwvnsprintfW@16                      @710
    626 
    627     SHRegGetPathA          = _DbgSHRegGetPathA@20                    @802
    628     SHRegGetPathW          = _DbgSHRegGetPathW@20                    @803
    629     SHRegDeleteUSValueA    = _DbgSHRegDeleteUSValueA@12
    630     SHRegDeleteUSValueW    = _DbgSHRegDeleteUSValueW@12
     565    StrCpyW                = _DbgStrCpyW@8                           @1243
     566    StrDupA                = _DbgStrDupA@4                           @1244
     567    StrDupW                = _DbgStrDupW@4                           @1245
     568;   StrFormatByteSize64A   = _DbgStrFormatByteSize64A@16             @1246
     569    StrFormatByteSizeA     = _DbgStrFormatByteSizeA@12               @1247
     570    StrFormatByteSizeW     = _DbgStrFormatByteSizeW@12               @1248
     571;   StrFormatKBSizeA       = _DbgStrFormatKBSizeA@16                 @1249
     572;   StrFormatKBSizeW       = _DbgStrFormatKBSizeW@16                 @1250
     573    StrFromTimeIntervalA   = _DbgStrFromTimeIntervalA@16             @1251
     574    StrFromTimeIntervalW   = _DbgStrFromTimeIntervalW@16             @1252
     575  ; IntlStrEqWorkerA       = _DbgStrIsIntlEqualA@16                  @1253
     576  ; StrIsIntlEqualW        = _DbgStrIsIntlEqualW@?                   @1254
     577    StrNCatA               = _DbgStrNCatA@12                         @1255
     578    StrNCatW               = _DbgStrNCatW@12                         @1256
     579    StrPBrkA               = _DbgStrPBrkA@8                          @1257
     580    StrPBrkW               = _DbgStrPBrkW@8                          @1258
     581    StrRChrA               = _DbgStrRChrA@12                         @1259
     582    StrRChrIA              = _DbgStrRChrIA@12                        @1260
     583    StrRChrIW              = _DbgStrRChrIW@12                        @1261
     584    StrRChrW               = _DbgStrRChrW@12                         @1262
     585    StrRStrIA              = _DbgStrRStrIA@12                        @1263
     586    StrRStrIW              = _DbgStrRStrIW@12                        @1264
     587    StrRetToBufA           = _DbgStrRetToBufA@16                     @1265
     588    StrRetToBufW           = _DbgStrRetToBufW@16                     @1266
     589;   StrRetToStrA           = _DbgStrRetToStrA@12                     @1267
     590;   StrRetToStrW           = _DbgStrRetToStrW@12                     @1268
     591    StrSpnA                = _DbgStrSpnA@8                           @1269
     592    StrSpnW                = _DbgStrSpnW@8                           @1270
     593    StrStrA                = _DbgStrStrA@8                           @1271
     594    StrStrIA               = _DbgStrStrIA@8                          @1272
     595    StrStrIW               = _DbgStrStrIW@8                          @1273
     596    StrStrW                = _DbgStrStrW@8                           @1274
     597    StrToIntA              = _DbgStrToIntA@4                         @1275
     598    StrToIntExA            = _DbgStrToIntExA@12                      @1276
     599    StrToIntExW            = _DbgStrToIntExW@12                      @1277
     600    StrToIntW              = _DbgStrToIntW@4                         @1278
     601    StrTrimA               = _DbgStrTrimA@8                          @1279
     602  ; StrTrimW               = _DbgStrTrimW@?                          @1280
     603    UrlApplySchemeA        = _DbgUrlApplySchemeA@16                  @1281
     604    UrlApplySchemeW        = _DbgUrlApplySchemeW@16                  @1282
     605    UrlCanonicalizeA       = _DbgUrlCanonicalizeA@16                 @1283
     606    UrlCanonicalizeW       = _DbgUrlCanonicalizeW@16                 @1284
     607    UrlCombineA            = _DbgUrlCombineA@20                      @1285
     608    UrlCombineW            = _DbgUrlCombineW@20                      @1286
     609    UrlCompareA            = _DbgUrlCompareA@12                      @1287
     610    UrlCompareW            = _DbgUrlCompareW@12                      @1288
     611    UrlCreateFromPathA     = _DbgUrlCreateFromPathA@16               @1289
     612    UrlCreateFromPathW     = _DbgUrlCreateFromPathW@16               @1290
     613    UrlEscapeA             = _DbgUrlEscapeA@16                       @1291
     614    UrlEscapeW             = _DbgUrlEscapeW@16                       @1292
     615    UrlGetLocationA        = _DbgUrlGetLocationA@4                   @1293
     616    UrlGetLocationW        = _DbgUrlGetLocationW@4                   @1294
     617    UrlGetPartA            = _DbgUrlGetPartA@20                      @1295
     618    UrlGetPartW            = _DbgUrlGetPartW@20                      @1296
     619    UrlHashA               = _DbgUrlHashA@12                         @1297
     620    UrlHashW               = _DbgUrlHashW@12                         @1298
     621    UrlIsA                 = _DbgUrlIsA@8                            @1299
     622    UrlIsNoHistoryA        = _DbgUrlIsNoHistoryA@4                   @1300
     623    UrlIsNoHistoryW        = _DbgUrlIsNoHistoryW@4                   @1301
     624    UrlIsOpaqueA           = _DbgUrlIsOpaqueA@4                      @1302
     625    UrlIsOpaqueW           = _DbgUrlIsOpaqueW@4                      @1303
     626    UrlIsW                 = _DbgUrlIsW@8                            @1304
     627    UrlUnescapeA           = _DbgUrlUnescapeA@16                     @1305
     628    UrlUnescapeW           = _DbgUrlUnescapeW@16                     @1306
     629    wnsprintfA             = _wnsprintfA                             @1307
     630    wnsprintfW             = _wnsprintfW                             @1308
     631    wvnsprintfA            = _DbgwvnsprintfA@16                      @1309
     632    wvnsprintfW            = _DbgwvnsprintfW@16                      @1310
     633
     634;; exported in later versions
     635    SHRegGetPathA          = _DbgSHRegGetPathA@20                    @1402
     636    SHRegGetPathW          = _DbgSHRegGetPathW@20                    @1403
     637    SHRegDeleteUSValueA    = _DbgSHRegDeleteUSValueA@12              @1404
     638    SHRegDeleteUSValueW    = _DbgSHRegDeleteUSValueW@12              @1405
     639    SHRegSetPathA          = _DbgSHRegSetPathA@20                    @1406
     640    SHRegSetPathW          = _DbgSHRegSetPathW@20                    @1407
     641   
  • trunk/src/shlwapi/string.c

    r7820 r8584  
     1/*
     2 * Shlwapi string functions
     3 *
     4 * Copyright 1998 Juergen Schmied
     5 *
     6 * This library is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU Lesser General Public
     8 * License as published by the Free Software Foundation; either
     9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * This library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, write to the Free Software
     18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     19 */
     20
    121#include <ctype.h>
    2 #include <stdlib.h> 
     22#include <stdlib.h>
    323#include <stdio.h>
    424#include <string.h>
     
    1030#include "winuser.h"
    1131#include "winreg.h"
    12 #ifdef __WIN32OS2__
    13 #include "shlobj.h"
    14 #define NO_SHLWAPI_STREAM
    15 #include "shlwapi.h"
    16 #else
    1732#define NO_SHLWAPI_STREAM
    1833#include "shlwapi.h"
    1934#include "shlobj.h"
    20 #endif
    2135#include "wine/unicode.h"
    22 #include "debugtools.h"
    23 
    24 DEFAULT_DEBUG_CHANNEL(shell);
     36#include "wine/debug.h"
     37
     38WINE_DEFAULT_DEBUG_CHANNEL(shell);
    2539
    2640/*************************************************************************
     
    255269        int len = strlen(lpSrc);
    256270        LPSTR lpDest = (LPSTR) LocalAlloc(LMEM_FIXED, len+1);
    257        
     271
    258272        TRACE("%s\n", lpSrc);
    259273
     
    269283        int len = strlenW(lpSrc);
    270284        LPWSTR lpDest = (LPWSTR) LocalAlloc(LMEM_FIXED, sizeof(WCHAR) * (len+1));
    271        
     285
    272286        TRACE("%s\n", debugstr_w(lpSrc));
    273287
     
    295309            }
    296310          }
    297         }     
     311        }
    298312        TRACE("-- %u\n", pos);
    299         return pos;     
     313        return pos;
    300314}
    301315
     
    319333            }
    320334          }
    321         }     
     335        }
    322336        TRACE("-- %u\n", pos);
    323         return pos;     
     337        return pos;
    324338}
    325339
     
    342356        if (dbcs && lpStart[1] != HIBYTE(wMatch)) continue;
    343357        lpGotIt = lpStart;
    344     }   
     358    }
    345359    return (LPSTR)lpGotIt;
    346360}
     
    390404            if (toupper(*lpStart) == toupper(wMatch)) lpGotIt = lpStart;
    391405        }
    392     }   
     406    }
    393407    return (LPSTR)lpGotIt;
    394408}
     
    452466/*************************************************************************
    453467 * StrRetToBufA                                 [SHLWAPI.@]
    454  * 
     468 *
    455469 * converts a STRRET to a normal string
    456470 *
     
    497511/*************************************************************************
    498512 * StrRetToBufW                                 [SHLWAPI.@]
    499  * 
     513 *
    500514 * converts a STRRET to a normal string
    501515 *
     
    564578        }
    565579        lstrcpynA (pszBuf, buf, cchBuf);
    566         return pszBuf; 
     580        return pszBuf;
    567581}
    568582
     
    621635    return trimmed;
    622636}
    623 
    624 /*************************************************************************
    625  *      wnsprintfA      [SHLWAPI.@]
    626  */
    627 int WINAPIV wnsprintfA(LPSTR lpOut, int cchLimitIn, LPCSTR lpFmt, ...)
    628 {
    629     va_list valist;
    630     INT res;
    631 
    632     va_start( valist, lpFmt );
    633     res = wvsnprintfA( lpOut, cchLimitIn, lpFmt, valist );
    634     va_end( valist );
    635     return res;
    636 }
    637 
    638 /*************************************************************************
    639  *      wnsprintfW      [SHLWAPI.@]
    640  */
    641 int WINAPIV wnsprintfW(LPWSTR lpOut, int cchLimitIn, LPCWSTR lpFmt, ...)
    642 {
    643     va_list valist;
    644     INT res;
    645 
    646     va_start( valist, lpFmt );
    647     res = wvsnprintfW( lpOut, cchLimitIn, lpFmt, valist );
    648     va_end( valist );
    649     return res;
    650 }
  • trunk/src/shlwapi/string_odin.cpp

    r7838 r8584  
    1  /* $Id: string_odin.cpp,v 1.7 2002-02-08 10:23:35 sandervl Exp $ */
     1 /* $Id: string_odin.cpp,v 1.8 2002-06-07 08:02:20 sandervl Exp $ */
    22
    33/*
     
    5858#include "shellapi.h"
    5959#include "shlobj.h"
    60 #include "wine/undocshell.h"
    6160
    6261#include "shlwapi_odin.h"
  • trunk/src/shlwapi/url.c

    r7820 r8584  
    33 *
    44 * Copyright 2000 Huw D M Davies for CodeWeavers.
    5  */
    6 #ifdef __WIN32OS2__
    7 #include <ctype.h>
    8 #include <stdarg.h>
    9 #include <winuser.h>
    10 #endif
     5 *
     6 * This library is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU Lesser General Public
     8 * License as published by the Free Software Foundation; either
     9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * This library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, write to the Free Software
     18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     19 */
    1120
    1221#include <string.h>
     
    2130#define NO_SHLWAPI_STREAM
    2231#include "shlwapi.h"
    23 #include "debugtools.h"
     32#include "wine/debug.h"
    2433#include "ordinal.h"
    2534
    26 
    27 DEFAULT_DEBUG_CHANNEL(shell);
     35WINE_DEFAULT_DEBUG_CHANNEL(shell);
    2836
    2937typedef struct {
     
    191199          pcchCanonicalized, dwFlags);
    192200
    193     base = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, 
     201    base = (LPWSTR) HeapAlloc(GetProcessHeap(), 0,
    194202                              (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
    195203    canonical = base + INTERNET_MAX_URL_LENGTH;
     
    210218        return E_POINTER;
    211219    }
    212     WideCharToMultiByte(0, 0, canonical, len+1, pszCanonicalized, 
     220    WideCharToMultiByte(0, 0, canonical, len+1, pszCanonicalized,
    213221                        *pcchCanonicalized, 0, 0);
    214222    *pcchCanonicalized = len2;
     
    221229 *
    222230 *
    223  * MSDN is wrong (at 10/30/01 - go figure). This should support the 
     231 * MSDN is wrong (at 10/30/01 - go figure). This should support the
    224232 * following flags:                                      GLA
    225233 *    URL_DONT_ESCAPE_EXTRA_INFO    0x02000000
     
    231239 *    URL_ESCAPE_SEGMENT_ONLY       0x00002000
    232240 */
    233 HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, 
     241HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
    234242                                LPDWORD pcchCanonicalized, DWORD dwFlags)
    235243{
     
    357365        UrlUnescapeW(lpszUrlCpy, NULL, NULL, URL_UNESCAPE_INPLACE);
    358366
    359     if((EscapeFlags = dwFlags & (URL_ESCAPE_UNSAFE | 
     367    if((EscapeFlags = dwFlags & (URL_ESCAPE_UNSAFE |
    360368                                 URL_ESCAPE_SPACES_ONLY |
    361369                                 URL_ESCAPE_PERCENT |
     
    377385
    378386    HeapFree(GetProcessHeap(), 0, lpszUrlCpy);
    379  
     387
    380388    if (hr == S_OK)
    381389        TRACE("result %s\n", debugstr_w(pszCanonicalized));
     
    400408          *pcchCombined,dwFlags);
    401409
    402     base = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, 
     410    base = (LPWSTR) HeapAlloc(GetProcessHeap(), 0,
    403411                              (3*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
    404412    relative = base + INTERNET_MAX_URL_LENGTH;
     
    501509         *    .sizep2   length of location (above) and rest less the last
    502510         *              leaf (if any)
    503          *    sizeloc   length of location (above) up to but not including 
     511         *    sizeloc   length of location (above) up to but not including
    504512         *              the last '/'
    505513         */
     
    541549
    542550        /* handle cases where pszRelative has scheme */
    543         if ((base.sizep1 == relative.sizep1) && 
     551        if ((base.sizep1 == relative.sizep1) &&
    544552            (strncmpW(base.ap1, relative.ap1, base.sizep1) == 0)) {
    545553
     
    583591            ret = E_POINTER;
    584592            break;
    585         } 
     593        }
    586594        strcatW(preliminary, mrelative);
    587595        break;
     
    596604            ret = E_POINTER;
    597605            break;
    598         } 
     606        }
    599607        strcpyW(preliminary, mrelative);
    600608        if (!(dwFlags & URL_PLUGGABLE_PROTOCOL) &&
     
    612620            ret = E_POINTER;
    613621            break;
    614         } 
     622        }
    615623        strncpyW(preliminary, base.ap1, base.sizep1 + 1);
    616624        work = preliminary + base.sizep1 + 1;
     
    631639            ret = E_POINTER;
    632640            break;
    633         } 
     641        }
    634642        strncpyW(preliminary, base.ap1, base.sizep1+1+sizeloc);
    635643        work = preliminary + base.sizep1 + 1 + sizeloc;
     
    640648
    641649    case 5:  /*
    642               * Return the pszBase without its document (if any) and 
     650              * Return the pszBase without its document (if any) and
    643651              * append pszRelative after its scheme.
    644652              */
     
    648656            ret = E_POINTER;
    649657            break;
    650         } 
     658        }
    651659        strncpyW(preliminary, base.ap1, base.sizep1+1+base.sizep2);
    652660        work = preliminary + base.sizep1+1+base.sizep2 - 1;
     
    663671    if (ret == S_OK) {
    664672        /*
    665          * Now that the combining is done, process the escape options if 
     673         * Now that the combining is done, process the escape options if
    666674         * necessary, otherwise just copy the string.
    667675         */
     
    780788    *pcchEscaped = needed;
    781789    return ret;
    782 }       
     790}
    783791
    784792/*************************************************************************
     
    877885 *
    878886 * Converts escape sequences back to ordinary characters.
    879  * 
     887 *
    880888 * If URL_ESCAPE_INPLACE is set in dwFlags then pszUnescaped and
    881889 * pcchUnescaped are ignored and the converted string is returned in
     
    942950
    943951    if (ret == S_OK) {
    944         TRACE("result %s\n", (dwFlags & URL_UNESCAPE_INPLACE) ? 
     952        TRACE("result %s\n", (dwFlags & URL_UNESCAPE_INPLACE) ?
    945953              debugstr_a(pszUrl) : debugstr_a(pszUnescaped));
    946954    }
     
    10061014
    10071015    if (ret == S_OK) {
    1008         TRACE("result %s\n", (dwFlags & URL_UNESCAPE_INPLACE) ? 
     1016        TRACE("result %s\n", (dwFlags & URL_UNESCAPE_INPLACE) ?
    10091017              debugstr_w(pszUrl) : debugstr_w(pszUnescaped));
    10101018    }
     
    10171025 *
    10181026 * Bugs/Features:
    1019  *  MSDN (as of 2001-11-01) says that: 
    1020  *         "The location is the segment of the URL starting with a ? 
    1021  *          or # character." 
     1027 *  MSDN (as of 2001-11-01) says that:
     1028 *         "The location is the segment of the URL starting with a ?
     1029 *          or # character."
    10221030 *     Neither V4 nor V5 of shlwapi.dll implement the '?' and always return
    10231031 *     a NULL.
    10241032 *  MSDN further states that:
    1025  *         "If a file URL has a query string, ther returned string 
     1033 *         "If a file URL has a query string, ther returned string
    10261034 *          the query string."
    1027  *     In all test cases if the scheme starts with "fi" then a NULL is 
     1035 *     In all test cases if the scheme starts with "fi" then a NULL is
    10281036 *     returned. V5 gives the following results:
    10291037 *       NULL     file://aa/b/cd#hohoh
     
    11791187          debugstr_a(pszIn), *pcchOut, dwFlags);
    11801188
    1181     in = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, 
     1189    in = (LPWSTR) HeapAlloc(GetProcessHeap(), 0,
    11821190                              (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
    11831191    out = in + INTERNET_MAX_URL_LENGTH;
     
    12931301
    12941302    if (dwFlags & URL_APPLY_GUESSFILE) {
    1295         FIXME("(%s %p %p(%ld) 0x%08lx): stub URL_APPLY_GUESSFILE not implemented\n", 
     1303        FIXME("(%s %p %p(%ld) 0x%08lx): stub URL_APPLY_GUESSFILE not implemented\n",
    12961304              debugstr_w(pszIn), pszOut, pcchOut, *pcchOut, dwFlags);
    12971305        strcpyW(pszOut, pszIn);
     
    13061314        /* no scheme in input, need to see if we need to guess */
    13071315        if (dwFlags & URL_APPLY_GUESSSCHEME) {
    1308             if ((ret = URL_GuessScheme(pszIn, pszOut, pcchOut)) != -1) 
     1316            if ((ret = URL_GuessScheme(pszIn, pszOut, pcchOut)) != -1)
    13091317                return ret;
    13101318        }
     
    13251333    }
    13261334
    1327     /* If we are here, then either invalid scheme, 
     1335    /* If we are here, then either invalid scheme,
    13281336     * or no scheme and can't/failed guess.
    13291337     */
     
    14951503                (*size)++;
    14961504            } else if (*start == L'%') {
    1497                 if (isxdigitW(*(start+1)) && 
     1505                if (isxdigitW(*(start+1)) &&
    14981506                    isxdigitW(*(start+2))) {
    14991507                    start += 3;
     
    15531561    if ((*work != L'/') || (*(work+1) != L'/')) goto __ERROR;
    15541562#else
    1555     if (!*work || (*work != L':')) goto ERROR1;
     1563    if (!*work || (*work != L':')) goto ERROR;
    15561564    work++;
    15571565    if ((*work != L'/') || (*(work+1) != L'/')) goto ERROR;
     
    15831591    } else goto __ERROR;
    15841592#else
    1585     } else goto ERROR1;
     1593    } else goto ERROR;
    15861594#endif
    15871595    /* now start parsing hostname or hostnumber */
     
    16201628 *      UrlGetPartA     [SHLWAPI.@]
    16211629 */
    1622 HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut, 
     1630HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
    16231631                           DWORD dwPart, DWORD dwFlags)
    16241632{
     
    16261634    DWORD ret, len, len2;
    16271635
    1628     in = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, 
     1636    in = (LPWSTR) HeapAlloc(GetProcessHeap(), 0,
    16291637                              (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
    16301638    out = in + INTERNET_MAX_URL_LENGTH;
     
    16551663 *      UrlGetPartW     [SHLWAPI.@]
    16561664 */
    1657 HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut, 
     1665HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
    16581666                           DWORD dwPart, DWORD dwFlags)
    16591667{
Note: See TracChangeset for help on using the changeset viewer.