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