⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 path.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (lpszPath)
  {
    if ((lpszComma = strchr(lpszPath, ',')))
    {
      *lpszComma++ = '\0';
      iRet = StrToIntA(lpszComma);
    }
    PathUnquoteSpacesA(lpszPath);
    PathRemoveBlanksA(lpszPath);
  }
  return iRet;
}

/*************************************************************************
 * PathParseIconLocationW  [SHLWAPI.@]
 *
 * See PathParseIconLocationA.
 */
int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
{
  int iRet = 0;
  LPWSTR lpszComma;

  TRACE("(%s)\n", debugstr_w(lpszPath));

  if (lpszPath)
  {
    if ((lpszComma = StrChrW(lpszPath, ',')))
    {
      *lpszComma++ = '\0';
      iRet = StrToIntW(lpszComma);
    }
    PathUnquoteSpacesW(lpszPath);
    PathRemoveBlanksW(lpszPath);
  }
  return iRet;
}

/*************************************************************************
 * @	[SHLWAPI.4]
 *
 * Unicode version of PathFileExistsDefExtA.
 */
BOOL WINAPI PathFileExistsDefExtW(LPWSTR lpszPath,DWORD dwWhich)
{
  static const WCHAR pszExts[7][5] = { { '.', 'p', 'i', 'f', 0},
                                       { '.', 'c', 'o', 'm', 0},
                                       { '.', 'e', 'x', 'e', 0},
                                       { '.', 'b', 'a', 't', 0},
                                       { '.', 'l', 'n', 'k', 0},
                                       { '.', 'c', 'm', 'd', 0},
                                       { 0, 0, 0, 0, 0} };

  TRACE("(%s,%d)\n", debugstr_w(lpszPath), dwWhich);

  if (!lpszPath || PathIsUNCServerW(lpszPath) || PathIsUNCServerShareW(lpszPath))
    return FALSE;

  if (dwWhich)
  {
    LPCWSTR szExt = PathFindExtensionW(lpszPath);
    if (!*szExt || dwWhich & 0x40)
    {
      size_t iChoose = 0;
      int iLen = lstrlenW(lpszPath);
      if (iLen > (MAX_PATH - 5))
        return FALSE;
      while ( (dwWhich & 0x1) && pszExts[iChoose][0] )
      {
        lstrcpyW(lpszPath + iLen, pszExts[iChoose]);
        if (PathFileExistsW(lpszPath))
          return TRUE;
        iChoose++;
        dwWhich >>= 1;
      }
      *(lpszPath + iLen) = (WCHAR)'\0';
      return FALSE;
    }
  }
  return PathFileExistsW(lpszPath);
}

/*************************************************************************
 * @	[SHLWAPI.3]
 *
 * Determine if a file exists locally and is of an executable type.
 *
 * PARAMS
 *  lpszPath       [I/O] File to search for
 *  dwWhich        [I]   Type of executable to search for
 *
 * RETURNS
 *  TRUE  If the file was found. lpszPath contains the file name.
 *  FALSE Otherwise.
 *
 * NOTES
 *  lpszPath is modified in place and must be at least MAX_PATH in length.
 *  If the function returns FALSE, the path is modified to its original state.
 *  If the given path contains an extension or dwWhich is 0, executable
 *  extensions are not checked.
 *
 *  Ordinals 3-6 are a classic case of MS exposing limited functionality to
 *  users (here through PathFindOnPathA()) and keeping advanced functionality for
 *  their own developers exclusive use. Monopoly, anyone?
 */
BOOL WINAPI PathFileExistsDefExtA(LPSTR lpszPath,DWORD dwWhich)
{
  BOOL bRet = FALSE;

  TRACE("(%s,%d)\n", debugstr_a(lpszPath), dwWhich);

  if (lpszPath)
  {
    WCHAR szPath[MAX_PATH];
    MultiByteToWideChar(CP_ACP,0,lpszPath,-1,szPath,MAX_PATH);
    bRet = PathFileExistsDefExtW(szPath, dwWhich);
    if (bRet)
      WideCharToMultiByte(CP_ACP,0,szPath,-1,lpszPath,MAX_PATH,0,0);
  }
  return bRet;
}

/*************************************************************************
 * SHLWAPI_PathFindInOtherDirs
 *
 * Internal helper for SHLWAPI_PathFindOnPathExA/W.
 */
static BOOL WINAPI SHLWAPI_PathFindInOtherDirs(LPWSTR lpszFile, DWORD dwWhich)
{
  static const WCHAR szSystem[] = { 'S','y','s','t','e','m','\0'};
  static const WCHAR szPath[] = { 'P','A','T','H','\0'};
  DWORD dwLenPATH;
  LPCWSTR lpszCurr;
  WCHAR *lpszPATH;
  WCHAR buff[MAX_PATH];

  TRACE("(%s,%08x)\n", debugstr_w(lpszFile), dwWhich);

  /* Try system directories */
  GetSystemDirectoryW(buff, MAX_PATH);
  if (!PathAppendW(buff, lpszFile))
     return FALSE;
  if (PathFileExistsDefExtW(buff, dwWhich))
  {
    strcpyW(lpszFile, buff);
    return TRUE;
  }
  GetWindowsDirectoryW(buff, MAX_PATH);
  if (!PathAppendW(buff, szSystem ) || !PathAppendW(buff, lpszFile))
    return FALSE;
  if (PathFileExistsDefExtW(buff, dwWhich))
  {
    strcpyW(lpszFile, buff);
    return TRUE;
  }
  GetWindowsDirectoryW(buff, MAX_PATH);
  if (!PathAppendW(buff, lpszFile))
    return FALSE;
  if (PathFileExistsDefExtW(buff, dwWhich))
  {
    strcpyW(lpszFile, buff);
    return TRUE;
  }
  /* Try dirs listed in %PATH% */
  dwLenPATH = GetEnvironmentVariableW(szPath, buff, MAX_PATH);

  if (!dwLenPATH || !(lpszPATH = HeapAlloc(GetProcessHeap(), 0, (dwLenPATH + 1) * sizeof (WCHAR))))
    return FALSE;

  GetEnvironmentVariableW(szPath, lpszPATH, dwLenPATH + 1);
  lpszCurr = lpszPATH;
  while (lpszCurr)
  {
    LPCWSTR lpszEnd = lpszCurr;
    LPWSTR pBuff = buff;

    while (*lpszEnd == ' ')
      lpszEnd++;
    while (*lpszEnd && *lpszEnd != ';')
      *pBuff++ = *lpszEnd++;
    *pBuff = '\0';

    if (*lpszEnd)
      lpszCurr = lpszEnd + 1;
    else
      lpszCurr = NULL; /* Last Path, terminate after this */

    if (!PathAppendW(buff, lpszFile))
    {
      HeapFree(GetProcessHeap(), 0, lpszPATH);
      return FALSE;
    }
    if (PathFileExistsDefExtW(buff, dwWhich))
    {
      strcpyW(lpszFile, buff);
      HeapFree(GetProcessHeap(), 0, lpszPATH);
      return TRUE;
    }
  }
  HeapFree(GetProcessHeap(), 0, lpszPATH);
  return FALSE;
}

/*************************************************************************
 * @	[SHLWAPI.5]
 *
 * Search a range of paths for a specific type of executable.
 *
 * PARAMS
 *  lpszFile       [I/O] File to search for
 *  lppszOtherDirs [I]   Other directories to look in
 *  dwWhich        [I]   Type of executable to search for
 *
 * RETURNS
 *  Success: TRUE. The path to the executable is stored in lpszFile.
 *  Failure: FALSE. The path to the executable is unchanged.
 */
BOOL WINAPI PathFindOnPathExA(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich)
{
  WCHAR szFile[MAX_PATH];
  WCHAR buff[MAX_PATH];

  TRACE("(%s,%p,%08x)\n", debugstr_a(lpszFile), lppszOtherDirs, dwWhich);

  if (!lpszFile || !PathIsFileSpecA(lpszFile))
    return FALSE;

  MultiByteToWideChar(CP_ACP,0,lpszFile,-1,szFile,MAX_PATH);

  /* Search provided directories first */
  if (lppszOtherDirs && *lppszOtherDirs)
  {
    WCHAR szOther[MAX_PATH];
    LPCSTR *lpszOtherPath = lppszOtherDirs;

    while (lpszOtherPath && *lpszOtherPath && (*lpszOtherPath)[0])
    {
      MultiByteToWideChar(CP_ACP,0,*lpszOtherPath,-1,szOther,MAX_PATH);
      PathCombineW(buff, szOther, szFile);
      if (PathFileExistsDefExtW(buff, dwWhich))
      {
        WideCharToMultiByte(CP_ACP,0,buff,-1,lpszFile,MAX_PATH,0,0);
        return TRUE;
      }
      lpszOtherPath++;
    }
  }
  /* Not found, try system and path dirs */
  if (SHLWAPI_PathFindInOtherDirs(szFile, dwWhich))
  {
    WideCharToMultiByte(CP_ACP,0,szFile,-1,lpszFile,MAX_PATH,0,0);
    return TRUE;
  }
  return FALSE;
}

/*************************************************************************
 * @	[SHLWAPI.6]
 *
 * Unicode version of PathFindOnPathExA.
 */
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich)
{
  WCHAR buff[MAX_PATH];

  TRACE("(%s,%p,%08x)\n", debugstr_w(lpszFile), lppszOtherDirs, dwWhich);

  if (!lpszFile || !PathIsFileSpecW(lpszFile))
    return FALSE;

  /* Search provided directories first */
  if (lppszOtherDirs && *lppszOtherDirs)
  {
    LPCWSTR *lpszOtherPath = lppszOtherDirs;
    while (lpszOtherPath && *lpszOtherPath && (*lpszOtherPath)[0])
    {
      PathCombineW(buff, *lpszOtherPath, lpszFile);
      if (PathFileExistsDefExtW(buff, dwWhich))
      {
        strcpyW(lpszFile, buff);
        return TRUE;
      }
      lpszOtherPath++;
    }
  }
  /* Not found, try system and path dirs */
  return SHLWAPI_PathFindInOtherDirs(lpszFile, dwWhich);
}

/*************************************************************************
 * PathFindOnPathA	[SHLWAPI.@]
 *
 * Search a range of paths for an executable.
 *
 * PARAMS
 *  lpszFile       [I/O] File to search for
 *  lppszOtherDirs [I]   Other directories to look in
 *
 * RETURNS
 *  Success: TRUE. The path to the executable is stored in lpszFile.
 *  Failure: FALSE. The path to the executable is unchanged.
 */
BOOL WINAPI PathFindOnPathA(LPSTR lpszFile, LPCSTR *lppszOtherDirs)
{
  TRACE("(%s,%p)\n", debugstr_a(lpszFile), lppszOtherDirs);
  return PathFindOnPathExA(lpszFile, lppszOtherDirs, 0);
 }

/*************************************************************************
 * PathFindOnPathW      [SHLWAPI.@]
 *
 * See PathFindOnPathA.
 */
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
{
  TRACE("(%s,%p)\n", debugstr_w(lpszFile), lppszOtherDirs);
  return PathFindOnPathExW(lpszFile,lppszOtherDirs, 0);
}

/*************************************************************************
 * PathCompactPathExA   [SHLWAPI.@]
 *
 * Compact a path into a given number of characters.
 *
 * PARAMS
 *  lpszDest [O] Destination for compacted path
 *  lpszPath [I] Source path
 *  cchMax   [I] Maximum size of compacted path
 *  dwFlags  [I] Reserved
 *
 * RETURNS
 *  Success: TRUE. The compacted path is written to lpszDest.
 *  Failure: FALSE. lpszPath is undefined.
 *
 * NOTES
 *  If cchMax is given as 0, lpszDest will still be NUL terminated.
 *
 *  The Win32 version of this function contains a bug: When cchMax == 7,
 *  8 bytes will be written to lpszDest. This bug is fixed in the Wine
 *  implementation.
 *
 *  Some relative paths will be different when cchMax == 5 or 6. This occurs
 *  because Win32 will insert a "\" in lpszDest, even if one is
 *  not present in the original path.
 */
BOOL WINAPI PathCompactPathExA(LPSTR lpszDest, LPCSTR lpszPath,
                               UINT cchMax, DWORD dwFlags)
{
  BOOL bRet = FALSE;

  TRACE("(%p,%s,%d,0x%08x)\n", lpszDest, debugstr_a(lpszPath), cchMax, dwFlags);

  if (lpszPath && lpszDest)
  {
    WCHAR szPath[MAX_PATH];
    WCHAR szDest[MAX_PATH];

    MultiByteToWideChar(CP_ACP,0,lpszPath,-1,szPath,MAX_PATH);
    szDest[0] = '\0';
    bRet = PathCompactPathExW(szDest, szPath, cchMax, dwFlags);
    WideCharToMultiByte(CP_ACP,0,szDest,-1,lpszDest,MAX_PATH,0,0);
  }
  return bRet;
}

/*************************************************************************
 * PathCompactPathExW   [SHLWAPI.@]
 *
 * See PathCompactPathExA.
 */
BOOL WINAPI PathCompactPathExW(LPWSTR lpszDest, LPCWSTR lpszPath,
                               UINT cchMax, DWORD dwFlags)
{
  static const WCHAR szEllipses[] = { '.', '.', '.', '\0' };
  LPCWSTR lpszFile;
  DWORD dwLen, dwFileLen = 0;

  TRACE("(%p,%s,%d,0x%08x)\n", lpszDest, debugstr_w(lpszPath), cchMax, dwFlags);

  if (!lpszPath)
    return FALSE;

  if (!lpszDest)
  {
    WARN("Invalid lpszDest would crash under Win32!\n");
    return FALSE;
  }

  *lpszDest = '\0';

  if (cchMax < 2)
    return TRUE;

  dwLen = strlenW(lpszPath) + 1;

  if (dwLen < cchMax)
  {
    /* Don't need to compact */
    memcpy(lpszDest, lpszPath, dwLen * sizeof(WCHAR));
    return TRUE;
  }

  /* Path must be compacted to fit into lpszDest */
  lpszFile = PathFindFileNameW(lpszPath);
  dwFileLen = lpszPath + dwLen - lpszFile;

  if (dwFileLen == dwLen)
  {
    /* No root in psth */
    if (cchMax <= 4)
    {
      while (--cchMax > 0) /* No room left for anything but ellipses */
        *lpszDest++ = '.';
      *lpszDest = '\0';
      return TRUE;
    }
    /* Compact the file name with ellipses at the end */
    cchMax -= 4;
    memcpy(lpszDest, lpszFile, cchMax * sizeof(WCHAR));
    strcpyW(lpszDest + cchMax, szEllipses);
    return TRUE;
  }
  /* We have a root in the path */
  lpszFile--; /* Start compacted filename with the path separator */
  dwFileLen++;

  if (dwFileLen + 3 > cchMax)
  {
    /* Compact the file name */
    if (cchMax <= 4)
    {
      while (--cchMax > 0) /* No room left for anything but ellipses */
        *lpszDest++ = '.';
      *lpszDest = '\0';
      return TRUE;
    }
    strcpyW(lpszDest, szEllipses);
    lpszDest += 3;
    cchMax -= 4;
    *lpszDest++ = *lpszFile++;
    if (cchMax <= 4)
    {
      while (--cchMax > 0) /* No room left for anything but ellipses */
        *lpszDest++ = '.';
      *lpszDest = '\0';
      return TRUE;
    }
    cchMax -= 4;
    memcpy(lpszDest, lpszFile, cchMax * sizeof(WCHAR));
    strcpyW(lpszDest + cchMax, szEllipses);
    return TRUE;
  }

  /* Only the root needs to be Compacted */
  dwLen = cchMax - dwFileLen - 3;
  memcpy(lpszDest, lpszPath, dwLen * sizeof(WCHAR));
  strcpyW(lpszDest + dwLen, szEllipses);
  strcpyW(lpszDest + dwLen + 3, lpszFile);
  return TRUE;
}

/*************************************************************************
 * PathIsRelativeA	[SHLWAPI.@]
 *
 * Determine if a path is a relative path.
 *
 * PARAMS
 *  lpszPath [I] Path to check
 *
 * RETURNS
 *  TRUE:  The path is relative, or is invalid.
 *  FALSE: The path is not relative.
 */
BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
{
  TRACE("(%s)\n",debugstr_a(lpszPath));

  if (!lpszPath || !*lpszPath || IsDBCSLeadByte(*lpszPath))
    return TRUE;
  if (*lpszPath == '\\' || (*lpszPath && lpszPath[1] == ':'))
    return FALSE;
  return TRUE;
}

/*************************************************************************
 *  PathIsRelativeW	[SHLWAPI.@]
 *
 * See PathIsRelativeA.
 */
BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
{
  TRACE("(%s)\n",debugstr_w(lpszPath));

  if (!lpszPath || !*lpszPath)
    return TRUE;
  if (*lpszPath == '\\' || (*lpszPath && lpszPath[1] == ':'))
    return FALSE;
  return TRUE;
}

/*************************************************************************
 * PathIsRootA		[SHLWAPI.@]
 *
 * Determine if a path is a root path.
 *
 * PARAMS
 *  lpszPath [I] Path to check
 *
 * RETURNS
 *  TRUE  If lpszPath is valid and a root path,
 *  FALSE Otherwise
 */
BOOL WINAPI PathIsRootA(LPCSTR lpszPath)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -