SHLWAPI path functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

More SHLWAPI updates, path functions this time.

This one doesn't rely on any of the current outstanding patches.

License: X11

ChangeLog:

  Jon Griffiths <jon_p_griffiths@yahoo.com>

  +dlls/shlwapi/path.c
   PathAppendA/W: Don't skip '\\' if path is UNC
   PathGetCharTypeA/W: '/' is invalid, make non-ASCII compatable too
   Implement PathCompactPathExA/W
   Update docs, Remove signed/unsigned warnings with -W


=====
"Don't wait for the seas to part, or messiahs to come;
 Don't you sit around and waste this chance..." - Live

jon_p_griffiths@yahoo.com

__________________________________________________
Do You Yahoo!?
Yahoo! Health - Feel better, live better
http://health.yahoo.com
--- wine/dlls/shlwapi/path.c	Sat Jun  1 11:40:52 2002
+++ wine-develop/dlls/shlwapi/path.c	Sun Jul 21 15:08:37 2002
@@ -63,8 +63,9 @@
 
   if (lpszPath && lpszAppend)
   {
-    while (*lpszAppend == '\\')
-      lpszAppend++;
+    if (!PathIsUNCA(lpszAppend))
+      while (*lpszAppend == '\\')
+        lpszAppend++;
     if (PathCombineA(lpszPath, lpszPath, lpszAppend))
       return TRUE;
   }
@@ -82,8 +83,9 @@
 
   if (lpszPath && lpszAppend)
   {
-    while (*lpszAppend == '\\')
-      lpszAppend++;
+    if (!PathIsUNCW(lpszAppend))
+      while (*lpszAppend == '\\')
+        lpszAppend++;
     if (PathCombineW(lpszPath, lpszPath, lpszAppend))
       return TRUE;
   }
@@ -1076,7 +1078,7 @@
     LPCWSTR szExt = PathFindExtensionW(lpszPath);
     if (!*szExt || dwWhich & 0x40)
     {
-      int iChoose = 0;
+      size_t iChoose = 0;
       int iLen = lstrlenW(lpszPath);
       if (iLen > (MAX_PATH - 5))
         return FALSE;
@@ -1284,16 +1286,26 @@
 /*************************************************************************
  * PathCompactPathExA   [SHLWAPI.@]
  *
- * Compact a path.
+ * Compact a path into a given number of characters.
  *
  * PARAMS
  *  lpszDest [O] Destination for compacted path
  *  lpszPath [I] Source path
- *  cchMax   [I[ Size of lpszDest
- *  dwFlags  [I] Compaction flags
+ *  cchMax   [I[ Maximum size of compacted path
+ *  dwFlags  [I] Reserved
  *
  * RETURNS
- *  FIXME
+ *  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 the compact filename, even if one is
+ *  not present in the original path.
  */
 BOOL WINAPI PathCompactPathExA(LPSTR lpszDest, LPCSTR lpszPath,
                                UINT cchMax, DWORD dwFlags)
@@ -1323,7 +1335,11 @@
 BOOL WINAPI PathCompactPathExW(LPWSTR lpszDest, LPCWSTR lpszPath,
                                UINT cchMax, DWORD dwFlags)
 {
-  FIXME("(%p,%s,%d,0x%08lx)-stub\n", lpszDest, debugstr_w(lpszPath), cchMax, dwFlags);
+  static const WCHAR szEllipses[] = { '.', '.', '.', '\0' };
+  LPCWSTR lpszFile;
+  DWORD dwLen, dwFileLen = 0;
+
+  TRACE("(%p,%s,%d,0x%08lx)\n", lpszDest, debugstr_w(lpszPath), cchMax, dwFlags);
 
   if (!lpszPath)
     return FALSE;
@@ -1334,9 +1350,77 @@
     return FALSE;
   }
 
-  /* FIXME */
+  *lpszDest = '\0';
 
-  return FALSE;
+  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 seperator */
+  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;
 }
 
 /*************************************************************************
@@ -1501,7 +1585,7 @@
    return FALSE;
  }
 
-  if ((dwAttr = GetFileAttributesA(lpszPath)) == -1)
+  if ((dwAttr = GetFileAttributesA(lpszPath)) == -1u)
     return FALSE;
   return dwAttr & FILE_ATTRIBUTE_DIRECTORY;
 }
@@ -1526,7 +1610,7 @@
    return FALSE;
  }
 
-  if ((dwAttr = GetFileAttributesW(lpszPath)) == -1)
+  if ((dwAttr = GetFileAttributesW(lpszPath)) == -1u)
     return FALSE;
   return dwAttr & FILE_ATTRIBUTE_DIRECTORY;
 }
@@ -1556,7 +1640,7 @@
   iPrevErrMode = SetErrorMode(1);
   dwAttr = GetFileAttributesA(lpszPath);
   SetErrorMode(iPrevErrMode);
-  return dwAttr == -1 ? FALSE : TRUE;
+  return dwAttr == -1u ? FALSE : TRUE;
 }
 
 /*************************************************************************
@@ -1577,7 +1661,7 @@
   iPrevErrMode = SetErrorMode(1);
   dwAttr = GetFileAttributesW(lpszPath);
   SetErrorMode(iPrevErrMode);
-  return dwAttr == -1 ? FALSE : TRUE;
+  return dwAttr == -1u ? FALSE : TRUE;
 }
 
 /*************************************************************************
@@ -1715,7 +1799,7 @@
 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
 {
   LPCSTR lpszStart;
-  DWORD dwLen;
+  int dwLen;
 
   TRACE("(%s,%s)\n", debugstr_a(lpszPath1), debugstr_a(lpszPath2));
 
@@ -1736,7 +1820,7 @@
 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
 {
   LPCWSTR lpszStart;
-  DWORD dwLen;
+  int dwLen;
 
   TRACE("(%s,%s)\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
 
@@ -1769,7 +1853,7 @@
     if (!lpstrPath || !*lpstrPath) return FALSE;
 
     /* get protocol        */
-    base.size = 24;
+    base.size = sizeof(base);
     res1 = SHLWAPI_1(lpstrPath, &base);
     return (base.fcncde) ? TRUE : FALSE;
 }
@@ -1785,7 +1869,7 @@
     if (!lpstrPath || !*lpstrPath) return FALSE;
 
     /* get protocol        */
-    base.size = 24;
+    base.size = sizeof(base);
     res1 = SHLWAPI_2(lpstrPath, &base);
     return (base.fcncde) ? TRUE : FALSE;
 }
@@ -1793,14 +1877,19 @@
 /*************************************************************************
  * PathIsContentTypeA   [SHLWAPI.@]
  *
- * Determine if a file is of a registered content type.
+ * Determine if a file is of a given registered content type.
  *
  * PARAMS
- *  lpszPath [I] file to chack
+ *  lpszPath [I] file to check
  *
  * RETURNS
- *  TRUE  If lpszPath is a registered content type
+ *  TRUE  If lpszPath is a given registered content type
  *  FALSE Otherwise.
+ *
+ * NOTES
+ *  This function looks up the registered content type for lpszPath. If
+ *  a content type is registered, it is compared (case insensitively) to
+ *  lpszContentType. Only if this matches does the function succeed.
  */
 BOOL WINAPI PathIsContentTypeA(LPCSTR lpszPath, LPCSTR lpszContentType)
 {
@@ -1911,7 +2000,7 @@
   TRACE("(%s,%s)\n", debugstr_a(lpszPrefix), debugstr_a(lpszPath));
 
   if (lpszPrefix && lpszPath &&
-      PathCommonPrefixA(lpszPath, lpszPrefix, NULL) == strlen(lpszPrefix))
+      PathCommonPrefixA(lpszPath, lpszPrefix, NULL) == (int)strlen(lpszPrefix))
     return TRUE;
   return FALSE;
 }
@@ -1926,7 +2015,7 @@
   TRACE("(%s,%s)\n", debugstr_w(lpszPrefix), debugstr_w(lpszPath));
 
   if (lpszPrefix && lpszPath &&
-      PathCommonPrefixW(lpszPath, lpszPrefix, NULL) == strlenW(lpszPrefix))
+      PathCommonPrefixW(lpszPath, lpszPrefix, NULL) == (int)strlenW(lpszPrefix))
     return TRUE;
   return FALSE;
 }
@@ -1951,7 +2040,7 @@
   if (lpszPath && *lpszPath)
     dwAttrib = GetFileAttributesA(lpszPath);
 
-  if (dwAttrib == -1 || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
+  if (dwAttrib == -1u || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
       !(dwAttrib & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)))
     return FALSE;
   return TRUE;
@@ -1969,7 +2058,7 @@
   if (lpszPath && *lpszPath)
     dwAttrib = GetFileAttributesW(lpszPath);
 
-  if (dwAttrib == -1 || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
+  if (dwAttrib == -1u || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
       !(dwAttrib & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)))
     return FALSE;
   return TRUE;
@@ -2633,7 +2722,7 @@
   dwLen = strlenW(lpszPath);
   GetTextExtentPointW(hDC, lpszPath, dwLen, &size);
 
-  if (size.cx > dx)
+  if ((UINT)size.cx > dx)
   {
     /* Path too big, must reduce it */
     LPWSTR sFile;
@@ -2765,24 +2854,23 @@
   TRACE("(%d)\n", ch);
 
   if (!ch || ch < ' ' || ch == '<' || ch == '>' ||
-      ch == '"' || ch == '|' || ch == 255)
+      ch == '"' || ch == '|' || ch == '/')
     flags = GCT_INVALID; /* Invalid */
   else if (ch == '*' || ch=='?')
     flags = GCT_WILD; /* Wildchars */
-  else if ((ch == '\\') || (ch=='/') || (ch == ':'))
+  else if ((ch == '\\') || (ch == ':'))
     return GCT_SEPARATOR; /* Path separators */
   else
   {
      if (ch < 126)
      {
-       if (!ch || isalnum(ch) || ch == '$' || ch == '&' || ch == '(' ||
+       if ((ch & 0x1 && ch != ';') || !ch || isalnum(ch) || ch == '$' || ch == '&' || ch == '(' ||
             ch == '.' || ch == '@' || ch == '^' ||
             ch == '\'' || ch == 130 || ch == '`')
          flags |= GCT_SHORTCHAR; /* All these are valid for DOS */
      }
      else
-       if (!(ch & 0x1))
-         flags |= GCT_SHORTCHAR; /* Bug compatable with win32 */
+       flags |= GCT_SHORTCHAR; /* Bug compatable with win32 */
      flags |= GCT_LFNCHAR; /* Valid for long file names */
   }
   return flags;
@@ -2866,7 +2954,7 @@
   if (SHLWAPI_UseSystemForSystemFolders())
     dwDefaultAttr = FILE_ATTRIBUTE_SYSTEM;
 
-  if ((dwAttr = GetFileAttributesW(lpszPath)) == -1)
+  if ((dwAttr = GetFileAttributesW(lpszPath)) == -1u)
     return FALSE;
 
   /* Change file attributes to system attributes */
@@ -2925,11 +3013,11 @@
 /*************************************************************************
  * PathSearchAndQualifyA   [SHLWAPI.@]
  *
- * Unimplemented.
+ * Determine if a given path is correct and fully qualified.
  *
  * PARAMS
- *  lpszPath [I]
- *  lpszBuf  [O]
+ *  lpszPath [I] Path to check
+ *  lpszBuf  [O] Output for correct path
  *  cchBuf   [I] Size of lpszBuf
  *
  * RETURNS
@@ -3206,7 +3294,7 @@
 
   TRACE("(%s)\n", debugstr_a(lpszPath));
 
-  if (!lpszPath || !*lpszPath || (dwAttr = GetFileAttributesA(lpszPath)) == -1 ||
+  if (!lpszPath || !*lpszPath || (dwAttr = GetFileAttributesA(lpszPath)) == -1u ||
       !(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
     return FALSE;
 
@@ -3225,7 +3313,7 @@
 
   TRACE("(%s)\n", debugstr_w(lpszPath));
 
-  if (!lpszPath || !*lpszPath || (dwAttr = GetFileAttributesW(lpszPath)) == -1 ||
+  if (!lpszPath || !*lpszPath || (dwAttr = GetFileAttributesW(lpszPath)) == -1u ||
     !(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
     return FALSE;
 
@@ -3325,7 +3413,7 @@
   if (*lpszPath == '\\' && lpszPath[1] == '\\')
     return TRUE;
   dwDriveNum = PathGetDriveNumberA(lpszPath);
-  if (dwDriveNum == -1)
+  if (dwDriveNum == -1u)
     return FALSE;
   GET_FUNC(pIsNetDrive, shell32, (LPCSTR)66, FALSE); /* ord 66 = shell32.IsNetDrive */
   return pIsNetDrive(dwDriveNum);
@@ -3347,7 +3435,7 @@
   if (*lpszPath == '\\' && lpszPath[1] == '\\')
     return TRUE;
   dwDriveNum = PathGetDriveNumberW(lpszPath);
-  if (dwDriveNum == -1)
+  if (dwDriveNum == -1u)
     return FALSE;
   GET_FUNC(pIsNetDrive, shell32, (LPCSTR)66, FALSE); /* ord 66 = shell32.IsNetDrive */
   return pIsNetDrive(dwDriveNum);

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux