ntdll / kernel32 #39-2

Eric Pouech pouech-eric at wanadoo.fr
Sat Jan 17 14:52:58 CST 2004


This part of #39 hasn't been applied, so resending for clarification.
A+
-------------- next part --------------
Index: dlls/kernel39/path.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/kernel/path.c,v
retrieving revision 1.1
diff -u -r1.1 path.c
--- dlls/kernel39/path.c	15 Jan 2004 00:20:46 -0000	1.1
+++ dlls/kernel39/path.c	17 Jan 2004 20:15:57 -0000
@@ -42,6 +42,87 @@
 
 #define MAX_PATHNAME_LEN        1024
 
+/***********************************************************************
+ *           GetFullPathNameW   (KERNEL32.@)
+ * NOTES
+ *   if the path closed with '\', *lastpart is 0
+ */
+DWORD WINAPI GetFullPathNameW( LPCWSTR name, DWORD len, LPWSTR buffer,
+                               LPWSTR *lastpart )
+{
+    LPWSTR      dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(buffer));
+    DWORD       ret;
+
+    if (!dst) return 0;
+    ret = RtlGetFullPathName_U(name, len * sizeof(WCHAR), dst, lastpart) / sizeof(WCHAR);
+    if (ret < len)
+    {
+        strcpyW(buffer, dst);
+        if (lastpart && *lastpart) *lastpart = buffer + (*lastpart - dst);
+    }
+    HeapFree(GetProcessHeap(), 0, dst);
+    return ret;
+}
+
+/***********************************************************************
+ *           GetFullPathNameA   (KERNEL32.@)
+ * NOTES
+ *   if the path closed with '\', *lastpart is 0
+ */
+DWORD WINAPI GetFullPathNameA( LPCSTR name, DWORD len, LPSTR buffer,
+                               LPSTR *lastpart )
+{
+    UNICODE_STRING nameW;
+    WCHAR bufferW[MAX_PATH];
+    DWORD ret, retW;
+
+    if (!name)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    if (!RtlCreateUnicodeStringFromAsciiz(&nameW, name))
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return 0;
+    }
+
+    retW = GetFullPathNameW( nameW.Buffer, MAX_PATH, bufferW, NULL);
+
+    if (!retW)
+        ret = 0;
+    else if (retW > MAX_PATH)
+    {
+        SetLastError(ERROR_FILENAME_EXCED_RANGE);
+        ret = 0;
+    }
+    else
+    {
+        ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
+        if (ret && ret <= len)
+        {
+            WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, len, NULL, NULL);
+            ret--; /* length without 0 */
+
+            if (lastpart)
+            {
+                LPSTR p = buffer + strlen(buffer) - 1;
+
+                if (*p != '\\')
+                {
+                    while ((p > buffer + 2) && (*p != '\\')) p--;
+                    *lastpart = p + 1;
+                }
+                else *lastpart = NULL;
+            }
+        }
+    }
+
+    RtlFreeUnicodeString(&nameW);
+    return ret;
+}
+
 
 /***********************************************************************
  *           GetLongPathNameW   (KERNEL32.@)
Index: files39/dos_fs.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/files/dos_fs.c,v
retrieving revision 1.146
diff -u -r1.146 dos_fs.c
--- files39/dos_fs.c	15 Jan 2004 01:48:44 -0000	1.146
+++ files39/dos_fs.c	16 Jan 2004 19:54:59 -0000
@@ -1173,252 +1173,6 @@
 
 
 /***********************************************************************
- *           DOSFS_DoGetFullPathName
- *
- * Implementation of GetFullPathNameA/W.
- *
- * bon at elektron 000331:
- * A test for GetFullPathName with many pathological cases
- * now gives identical output for Wine and OSR2
- */
-static DWORD DOSFS_DoGetFullPathName( LPCWSTR name, DWORD len, LPWSTR result )
-{
-    DWORD ret;
-    DOS_FULL_NAME full_name;
-    LPWSTR p, q;
-    char *p_l;
-    const char * root;
-    WCHAR drivecur[] = {'C',':','.',0};
-    WCHAR driveletter=0;
-    int namelen,drive=0;
-    static const WCHAR bkslashW[] = {'\\',0};
-    static const WCHAR dotW[] = {'.',0};
-    static const WCHAR updir_slashW[] = {'\\','.','.','\\',0};
-    static const WCHAR curdirW[] = {'\\','.','\\',0};
-    static const WCHAR updirW[] = {'\\','.','.',0};
-
-    if (!name[0])
-    {
-        SetLastError(ERROR_BAD_PATHNAME);
-        return 0;
-    }
-
-    TRACE("passed %s\n", debugstr_w(name));
-
-    if (name[1]==':')
-      /*drive letter given */
-      {
-	driveletter = name[0];
-      }
-    if ((name[1]==':') && ((name[2]=='\\') || (name[2]=='/')))
-      /*absolute path given */
-      {
-        strncpyW(full_name.short_name, name, MAX_PATHNAME_LEN);
-        full_name.short_name[MAX_PATHNAME_LEN - 1] = 0; /* ensure 0 termination */
-        drive = toupperW(name[0]) - 'A';
-      }
-    else
-      {
-	if (driveletter)
-	  drivecur[0]=driveletter;
-        else if ((name[0]=='\\') || (name[0]=='/'))
-          strcpyW(drivecur, bkslashW);
-        else
-	  strcpyW(drivecur, dotW);
-
-	if (!DOSFS_GetFullName( drivecur, FALSE, &full_name ))
-	  {
-	    FIXME("internal: error getting drive/path\n");
-	    return 0;
-	  }
-	/* find path that drive letter substitutes*/
-	drive = toupperW(full_name.short_name[0]) - 'A';
-	root= DRIVE_GetRoot(drive);
-	if (!root)
-	  {
-	    FIXME("internal: error getting DOS Drive Root\n");
-	    return 0;
-	  }
-	if (!strcmp(root,"/"))
-	  {
-	    /* we have just the last / and we need it. */
-	    p_l = full_name.long_name;
-	  }
-	else
-	  {
-	    p_l = full_name.long_name + strlen(root);
-	  }
-	/* append long name (= unix name) to drive */
-	MultiByteToWideChar(CP_UNIXCP, 0, p_l, -1, full_name.short_name + 2, MAX_PATHNAME_LEN - 3);
-	/* append name to treat */
-	namelen= strlenW(full_name.short_name);
-	p = (LPWSTR)name;
-	if (driveletter)
-	  p += 2; /* skip drive name when appending */
-	if (namelen + 2 + strlenW(p) > MAX_PATHNAME_LEN)
-	  {
-	    FIXME("internal error: buffer too small\n");
-	     return 0;
-	  }
-	full_name.short_name[namelen++] ='\\';
-	full_name.short_name[namelen] = 0;
-	strncpyW(full_name.short_name + namelen, p, MAX_PATHNAME_LEN - namelen);
-	full_name.short_name[MAX_PATHNAME_LEN - 1] = 0; /* ensure 0 termination */
-      }
-    /* reverse all slashes */
-    for (p=full_name.short_name;
-	 p < full_name.short_name + strlenW(full_name.short_name);
-	 p++)
-      {
-	if ( *p == '/' )
-	  *p = '\\';
-      }
-     /* Use memmove, as areas overlap */
-     /* Delete .. */
-    while ((p = strstrW(full_name.short_name, updir_slashW)))
-      {
-	if (p > full_name.short_name+2)
-	  {
-	    *p = 0;
-            q = strrchrW(full_name.short_name, '\\');
-            memmove(q+1, p+4, (strlenW(p+4)+1) * sizeof(WCHAR));
-	  }
-	else
-	  {
-            memmove(full_name.short_name+3, p+4, (strlenW(p+4)+1) * sizeof(WCHAR));
-	  }
-      }
-    if ((full_name.short_name[2]=='.')&&(full_name.short_name[3]=='.'))
-	{
-	  /* This case istn't treated yet : c:..\test */
-	  memmove(full_name.short_name+2,full_name.short_name+4,
-                  (strlenW(full_name.short_name+4)+1) * sizeof(WCHAR));
-	}
-     /* Delete . */
-    while ((p = strstrW(full_name.short_name, curdirW)))
-      {
-	*(p+1) = 0;
-        memmove(p+1, p+3, (strlenW(p+3)+1) * sizeof(WCHAR));
-      }
-    if (!(DRIVE_GetFlags(drive) & DRIVE_CASE_PRESERVING))
-        for (p = full_name.short_name; *p; p++) *p = toupperW(*p);
-    namelen = strlenW(full_name.short_name);
-    if (!strcmpW(full_name.short_name+namelen-3, updirW))
-	{
-	  /* one more strange case: "c:\test\test1\.."
-	   return "c:\test" */
-	  *(full_name.short_name+namelen-3)=0;
-          q = strrchrW(full_name.short_name, '\\');
-	  *q =0;
-	}
-    if (full_name.short_name[namelen-1]=='.')
-	full_name.short_name[(namelen--)-1] =0;
-    TRACE("got %s\n", debugstr_w(full_name.short_name));
-
-    /* If the lpBuffer buffer is too small, the return value is the
-    size of the buffer, in characters, required to hold the path
-    plus the terminating \0 (tested against win95osr2, bon 001118)
-    . */
-    ret = strlenW(full_name.short_name);
-    if (ret >= len )
-      {
-	/* don't touch anything when the buffer is not large enough */
-        SetLastError( ERROR_INSUFFICIENT_BUFFER );
-	return ret+1;
-      }
-    if (result)
-    {
-        strncpyW( result, full_name.short_name, len );
-        result[len - 1] = 0; /* ensure 0 termination */
-    }
-
-    TRACE("returning %s\n", debugstr_w(full_name.short_name) );
-    return ret;
-}
-
-
-/***********************************************************************
- *           GetFullPathNameA   (KERNEL32.@)
- * NOTES
- *   if the path closed with '\', *lastpart is 0
- */
-DWORD WINAPI GetFullPathNameA( LPCSTR name, DWORD len, LPSTR buffer,
-                                 LPSTR *lastpart )
-{
-    UNICODE_STRING nameW;
-    WCHAR bufferW[MAX_PATH];
-    DWORD ret, retW;
-
-    if (!name)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return 0;
-    }
-
-    if (!RtlCreateUnicodeStringFromAsciiz(&nameW, name))
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
-    }
-
-    retW = GetFullPathNameW( nameW.Buffer, MAX_PATH, bufferW, NULL);
-
-    if (!retW)
-        ret = 0;
-    else if (retW > MAX_PATH)
-    {
-        SetLastError(ERROR_FILENAME_EXCED_RANGE);
-        ret = 0;
-    }
-    else
-    {
-        ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
-        if (ret <= len)
-        {
-            WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, len, NULL, NULL);
-            ret--; /* length without 0 */
-
-            if (lastpart)
-            {
-                LPSTR p = buffer + strlen(buffer) - 1;
-
-                if (*p != '\\')
-                {
-                    while ((p > buffer + 2) && (*p != '\\')) p--;
-                    *lastpart = p + 1;
-                }
-                else *lastpart = NULL;
-            }
-        }
-    }
-
-    RtlFreeUnicodeString(&nameW);
-    return ret;
-}
-
-
-/***********************************************************************
- *           GetFullPathNameW   (KERNEL32.@)
- */
-DWORD WINAPI GetFullPathNameW( LPCWSTR name, DWORD len, LPWSTR buffer,
-                                 LPWSTR *lastpart )
-{
-    DWORD ret = DOSFS_DoGetFullPathName( name, len, buffer );
-    if (ret && (ret<=len) && buffer && lastpart)
-    {
-        LPWSTR p = buffer + strlenW(buffer) - 1;
-        if (*p != (WCHAR)'\\')
-        {
-            while ((p > buffer + 2) && (*p != (WCHAR)'\\')) p--;
-            *lastpart = p + 1;
-        }
-        else *lastpart = NULL;
-    }
-    return ret;
-}
-
-
-/***********************************************************************
  *           wine_get_unix_file_name (KERNEL32.@) Not a Windows API
  *
  * Return the full Unix file name for a given path.


More information about the wine-patches mailing list