📄 path.c
字号:
if (!lpszPath)
return FALSE;
while (*lpszPath)
{
if (*lpszPath == '\\' || *lpszPath == ':')
return FALSE;
lpszPath = CharNextA(lpszPath);
}
return TRUE;
}
/*************************************************************************
* PathIsFileSpecW [SHLWAPI.@]
*
* See PathIsFileSpecA.
*/
BOOL WINAPI PathIsFileSpecW(LPCWSTR lpszPath)
{
TRACE("(%s)\n", debugstr_w(lpszPath));
if (!lpszPath)
return FALSE;
while (*lpszPath)
{
if (*lpszPath == '\\' || *lpszPath == ':')
return FALSE;
lpszPath++;
}
return TRUE;
}
/*************************************************************************
* PathIsPrefixA [SHLWAPI.@]
*
* Determine if a path is a prefix of another.
*
* PARAMS
* lpszPrefix [I] Prefix
* lpszPath [I] Path to check
*
* RETURNS
* TRUE If lpszPath has lpszPrefix as its prefix,
* FALSE If either path is NULL or lpszPrefix is not a prefix
*/
BOOL WINAPI PathIsPrefixA (LPCSTR lpszPrefix, LPCSTR lpszPath)
{
TRACE("(%s,%s)\n", debugstr_a(lpszPrefix), debugstr_a(lpszPath));
if (lpszPrefix && lpszPath &&
PathCommonPrefixA(lpszPath, lpszPrefix, NULL) == (int)strlen(lpszPrefix))
return TRUE;
return FALSE;
}
/*************************************************************************
* PathIsPrefixW [SHLWAPI.@]
*
* See PathIsPrefixA.
*/
BOOL WINAPI PathIsPrefixW(LPCWSTR lpszPrefix, LPCWSTR lpszPath)
{
TRACE("(%s,%s)\n", debugstr_w(lpszPrefix), debugstr_w(lpszPath));
if (lpszPrefix && lpszPath &&
PathCommonPrefixW(lpszPath, lpszPrefix, NULL) == (int)strlenW(lpszPrefix))
return TRUE;
return FALSE;
}
/*************************************************************************
* PathIsSystemFolderA [SHLWAPI.@]
*
* Determine if a path or file attributes are a system folder.
*
* PARAMS
* lpszPath [I] Path to check.
* dwAttrib [I] Attributes to check, if lpszPath is NULL.
*
* RETURNS
* TRUE If lpszPath or dwAttrib are a system folder.
* FALSE If GetFileAttributesA() fails or neither parameter is a system folder.
*/
BOOL WINAPI PathIsSystemFolderA(LPCSTR lpszPath, DWORD dwAttrib)
{
TRACE("(%s,0x%08x)\n", debugstr_a(lpszPath), dwAttrib);
if (lpszPath && *lpszPath)
dwAttrib = GetFileAttributesA(lpszPath);
if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
!(dwAttrib & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)))
return FALSE;
return TRUE;
}
/*************************************************************************
* PathIsSystemFolderW [SHLWAPI.@]
*
* See PathIsSystemFolderA.
*/
BOOL WINAPI PathIsSystemFolderW(LPCWSTR lpszPath, DWORD dwAttrib)
{
TRACE("(%s,0x%08x)\n", debugstr_w(lpszPath), dwAttrib);
if (lpszPath && *lpszPath)
dwAttrib = GetFileAttributesW(lpszPath);
if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
!(dwAttrib & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)))
return FALSE;
return TRUE;
}
/*************************************************************************
* PathIsUNCA [SHLWAPI.@]
*
* Determine if a path is in UNC format.
*
* PARAMS
* lpszPath [I] Path to check
*
* RETURNS
* TRUE: The path is UNC.
* FALSE: The path is not UNC or is NULL.
*/
BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
{
TRACE("(%s)\n",debugstr_a(lpszPath));
if (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'))
return TRUE;
return FALSE;
}
/*************************************************************************
* PathIsUNCW [SHLWAPI.@]
*
* See PathIsUNCA.
*/
BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
{
TRACE("(%s)\n",debugstr_w(lpszPath));
if (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'))
return TRUE;
return FALSE;
}
/*************************************************************************
* PathIsUNCServerA [SHLWAPI.@]
*
* Determine if a path is a UNC server name ("\\SHARENAME").
*
* PARAMS
* lpszPath [I] Path to check.
*
* RETURNS
* TRUE If lpszPath is a valid UNC server name.
* FALSE Otherwise.
*
* NOTES
* This routine is bug compatible with Win32: Server names with a
* trailing backslash (e.g. "\\FOO\"), return FALSE incorrectly.
* Fixing this bug may break other shlwapi functions!
*/
BOOL WINAPI PathIsUNCServerA(LPCSTR lpszPath)
{
TRACE("(%s)\n", debugstr_a(lpszPath));
if (lpszPath && *lpszPath++ == '\\' && *lpszPath++ == '\\')
{
while (*lpszPath)
{
if (*lpszPath == '\\')
return FALSE;
lpszPath = CharNextA(lpszPath);
}
return TRUE;
}
return FALSE;
}
/*************************************************************************
* PathIsUNCServerW [SHLWAPI.@]
*
* See PathIsUNCServerA.
*/
BOOL WINAPI PathIsUNCServerW(LPCWSTR lpszPath)
{
TRACE("(%s)\n", debugstr_w(lpszPath));
if (lpszPath && lpszPath[0] == '\\' && lpszPath[1] == '\\')
{
return !strchrW( lpszPath + 2, '\\' );
}
return FALSE;
}
/*************************************************************************
* PathIsUNCServerShareA [SHLWAPI.@]
*
* Determine if a path is a UNC server share ("\\SHARENAME\SHARE").
*
* PARAMS
* lpszPath [I] Path to check.
*
* RETURNS
* TRUE If lpszPath is a valid UNC server share.
* FALSE Otherwise.
*
* NOTES
* This routine is bug compatible with Win32: Server shares with a
* trailing backslash (e.g. "\\FOO\BAR\"), return FALSE incorrectly.
* Fixing this bug may break other shlwapi functions!
*/
BOOL WINAPI PathIsUNCServerShareA(LPCSTR lpszPath)
{
TRACE("(%s)\n", debugstr_a(lpszPath));
if (lpszPath && *lpszPath++ == '\\' && *lpszPath++ == '\\')
{
BOOL bSeenSlash = FALSE;
while (*lpszPath)
{
if (*lpszPath == '\\')
{
if (bSeenSlash)
return FALSE;
bSeenSlash = TRUE;
}
lpszPath = CharNextA(lpszPath);
}
return bSeenSlash;
}
return FALSE;
}
/*************************************************************************
* PathIsUNCServerShareW [SHLWAPI.@]
*
* See PathIsUNCServerShareA.
*/
BOOL WINAPI PathIsUNCServerShareW(LPCWSTR lpszPath)
{
TRACE("(%s)\n", debugstr_w(lpszPath));
if (lpszPath && *lpszPath++ == '\\' && *lpszPath++ == '\\')
{
BOOL bSeenSlash = FALSE;
while (*lpszPath)
{
if (*lpszPath == '\\')
{
if (bSeenSlash)
return FALSE;
bSeenSlash = TRUE;
}
lpszPath++;
}
return bSeenSlash;
}
return FALSE;
}
/*************************************************************************
* PathCanonicalizeA [SHLWAPI.@]
*
* Convert a path to its canonical form.
*
* PARAMS
* lpszBuf [O] Output path
* lpszPath [I] Path to cnonicalize
*
* RETURNS
* Success: TRUE. lpszBuf contains the output path,
* Failure: FALSE, If input path is invalid. lpszBuf is undefined
*/
BOOL WINAPI PathCanonicalizeA(LPSTR lpszBuf, LPCSTR lpszPath)
{
BOOL bRet = FALSE;
TRACE("(%p,%s)\n", lpszBuf, debugstr_a(lpszPath));
if (lpszBuf)
*lpszBuf = '\0';
if (!lpszBuf || !lpszPath)
SetLastError(ERROR_INVALID_PARAMETER);
else
{
WCHAR szPath[MAX_PATH];
WCHAR szBuff[MAX_PATH];
MultiByteToWideChar(CP_ACP,0,lpszPath,-1,szPath,MAX_PATH);
bRet = PathCanonicalizeW(szBuff, szPath);
WideCharToMultiByte(CP_ACP,0,szBuff,-1,lpszBuf,MAX_PATH,0,0);
}
return bRet;
}
/*************************************************************************
* PathCanonicalizeW [SHLWAPI.@]
*
* See PathCanonicalizeA.
*/
BOOL WINAPI PathCanonicalizeW(LPWSTR lpszBuf, LPCWSTR lpszPath)
{
LPWSTR lpszDst = lpszBuf;
LPCWSTR lpszSrc = lpszPath;
TRACE("(%p,%s)\n", lpszBuf, debugstr_w(lpszPath));
if (lpszBuf)
*lpszDst = '\0';
if (!lpszBuf || !lpszPath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!*lpszPath)
{
*lpszBuf++ = '\\';
*lpszBuf = '\0';
return TRUE;
}
/* Copy path root */
if (*lpszSrc == '\\')
{
*lpszDst++ = *lpszSrc++;
}
else if (*lpszSrc && lpszSrc[1] == ':')
{
/* X:\ */
*lpszDst++ = *lpszSrc++;
*lpszDst++ = *lpszSrc++;
if (*lpszSrc == '\\')
*lpszDst++ = *lpszSrc++;
}
/* Canonicalize the rest of the path */
while (*lpszSrc)
{
if (*lpszSrc == '.')
{
if (lpszSrc[1] == '\\' && (lpszSrc == lpszPath || lpszSrc[-1] == '\\' || lpszSrc[-1] == ':'))
{
lpszSrc += 2; /* Skip .\ */
}
else if (lpszSrc[1] == '.' && (lpszDst == lpszBuf || lpszDst[-1] == '\\'))
{
/* \.. backs up a directory, over the root if it has no \ following X:.
* .. is ignored if it would remove a UNC server name or inital \\
*/
if (lpszDst != lpszBuf)
{
*lpszDst = '\0'; /* Allow PathIsUNCServerShareA test on lpszBuf */
if (lpszDst > lpszBuf+1 && lpszDst[-1] == '\\' &&
(lpszDst[-2] != '\\' || lpszDst > lpszBuf+2))
{
if (lpszDst[-2] == ':' && (lpszDst > lpszBuf+3 || lpszDst[-3] == ':'))
{
lpszDst -= 2;
while (lpszDst > lpszBuf && *lpszDst != '\\')
lpszDst--;
if (*lpszDst == '\\')
lpszDst++; /* Reset to last '\' */
else
lpszDst = lpszBuf; /* Start path again from new root */
}
else if (lpszDst[-2] != ':' && !PathIsUNCServerShareW(lpszBuf))
lpszDst -= 2;
}
while (lpszDst > lpszBuf && *lpszDst != '\\')
lpszDst--;
if (lpszDst == lpszBuf)
{
*lpszDst++ = '\\';
lpszSrc++;
}
}
lpszSrc += 2; /* Skip .. in src path */
}
else
*lpszDst++ = *lpszSrc++;
}
else
*lpszDst++ = *lpszSrc++;
}
/* Append \ to naked drive specs */
if (lpszDst - lpszBuf == 2 && lpszDst[-1] == ':')
*lpszDst++ = '\\';
*lpszDst++ = '\0';
return TRUE;
}
/*************************************************************************
* PathFindNextComponentA [SHLWAPI.@]
*
* Find the next component in a path.
*
* PARAMS
* lpszPath [I] Path to find next component in
*
* RETURNS
* Success: A pointer to the next component, or the end of the string.
* Failure: NULL, If lpszPath is invalid
*
* NOTES
* A 'component' is either a backslash character (\) or UNC marker (\\).
* Because of this, relative paths (e.g "c:foo") are regarded as having
* only one component.
*/
LPSTR WINAPI PathFindNextComponentA(LPCSTR lpszPath)
{
LPSTR lpszSlash;
TRACE("(%s)\n", debugstr_a(lpszPath));
if(!lpszPath || !*lpszPath)
return NULL;
if ((lpszSlash = StrChrA(lpszPath, '\\')))
{
if (lpszSlash[1] == '\\')
lpszSlash++;
return lpszSlash + 1;
}
return (LPSTR)lpszPath + strlen(lpszPath);
}
/*************************************************************************
* PathFindNextComponentW [SHLWAPI.@]
*
* See PathFindNextComponentA.
*/
LPWSTR WINAPI PathFindNextComponentW(LPCWSTR lpszPath)
{
LPWSTR lpszSlash;
TRACE("(%s)\n", debugstr_w(lpszPath));
if(!lpszPath || !*lpszPath)
return NULL;
if ((lpszSlash = StrChrW(lpszPath, '\\')))
{
if (lpszSlash[1] == '\\')
lpszSlash++;
return lpszSlash + 1;
}
return (LPWSTR)lpszPath + strlenW(lpszPath);
}
/*************************************************************************
* PathAddExtensionA [SHLWAPI.@]
*
* Add a file extension to a path
*
* PARAMS
* lpszPath [I/O] Path to add extension to
* lpszExtension [I] Extension to add to lpszPath
*
* RETURNS
* TRUE If the path was modified,
* FALSE If lpszPath or lpszExtension are invalid, lpszPath has an
* extension already, or the new path length is too big.
*
* FIXME
* What version of shlwapi.dll adds "exe" if lpszExtension is NULL? Win2k
* does not do this, so the behaviour was removed.
*/
BOOL WINAPI PathAddExtensionA(LPSTR lpszPath, LPCSTR lpszExtension)
{
size_t dwLen;
TRACE("(%s,%s)\n", debugstr_a(lpszPath), debugstr_a(lpszExtension));
if (!lpszPath || !lpszExtension || *(PathFindExtensionA(lpszPath)))
return FALSE;
dwLen = strlen(lpszPath);
if (dwLen + strlen(lpszExtension) >= MAX_PATH)
return FALSE;
strcpy(lpszPath + dwLen, lpszExtension);
return TRUE;
}
/*************************************************************************
* PathAddExtensionW [SHLWAPI.@]
*
* See PathAddExtensionA.
*/
BOOL WINAPI PathAddExtensionW(LPWSTR lpszPath, LPCWSTR lpszExtension)
{
size_t dwLen;
TRACE("(%s,%s)\n", debugstr_w(lpszPath), debugstr_w(lpszExtension));
if (!lpszPath || !lpszExtension || *(PathFindExtensionW(lpszPath)))
return FALSE;
dwLen = strlenW(lpszPath
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -