Fix Unix->Windows path conversion
Francois Gouget
fgouget at codeweavers.com
Fri Oct 7 10:14:11 CDT 2005
Currently winepath uses the GetFullPathName() to convert Unix paths to
Windows paths but that's not garanteed to work. In particular if 'y:'
points to your home directory, cwd()==$HOME and you call
GetFullPathName("../otheruser/foo.txt") then you get
"y:\otheruser\foo.txt" which is wrong.
Alexandre told me that's by design and GetFullPathName() will just get
things wrong for relative paths. That's why we now have
wine_get_dos_file_name(). So I modified winepath to use the new
function. I also fixed the description of the --long and --short
operations to reflect what they really do.
Changelog:
* programs/winepath/winepath.c
Francois Gouget <fgouget at codeweavers.com>
Add a --windows option for converting a Unix path to a long Windows
path.
Fix the description of --long and --short. They are only garanteed
to work on Windows paths though they will often successfully convert
Unix paths to Windows paths too.
--
Francois Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: programs/winepath/winepath.c
===================================================================
RCS file: /var/cvs/wine/programs/winepath/winepath.c,v
retrieving revision 1.8
diff -u -p -r1.8 winepath.c
--- programs/winepath/winepath.c 25 Jan 2005 16:41:50 -0000 1.8
+++ programs/winepath/winepath.c 7 Oct 2005 14:55:01 -0000
@@ -1,8 +1,9 @@
/*
- * Translate between Wine and Unix paths
+ * Translate between Windows and Unix paths formats
*
* Copyright 2002 Mike Wetherell
* Copyright 2005 Dmitry Timoshkov
+ * Copyright 2005 Francois Gouget
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -30,15 +31,14 @@
#define VERSION "0.1 (" PACKAGE_STRING ")"
enum {
- SHORTFORMAT = 1,
- LONGFORMAT = 2,
- UNIXFORMAT = 4
+ SHORTFORMAT = 1,
+ LONGFORMAT = 2,
+ UNIXFORMAT = 4,
+ WINDOWSFORMAT = 8
};
static const char progname[] = "winepath";
-/* Wine specific functions */
-typedef LPSTR (*wine_get_unix_file_name_t) ( LPCWSTR dos );
/*
* handle an option
*/
@@ -47,15 +47,16 @@ static int option(int shortopt, const WC
static const char helpmsg[] =
"Convert PATH(s) to Unix or Windows long or short paths.\n"
"\n"
- " -u, --unix output Unix format\n"
- " -l, --long output Windows long format\n"
- " -s, --short output Windows short format \n"
+ " -u, --unix converts a Windows path to a Unix path\n"
+ " -w, --windows converts a Unix path to a long Windows path\n"
+ " -l, --long converts a short Windows path to the long format\n"
+ " -s, --short converts a long Windows path to the short format\n"
" -h, --help output this help message and exit\n"
" -v, --version output version information and exit\n"
"\n"
- "The input paths can be in any format. If more than one option is given\n"
- "then the input paths are output in all formats specified, in the order\n"
- "Unix, long, short. If no option is given the default is Unix format.\n";
+ "If more than one option is given then the input paths are output in\n"
+ "all formats specified, in the order long, short, Unix, Windows.\n"
+ "If no option is given the default is Unix format.\n";
switch (shortopt) {
case 'h':
@@ -71,6 +72,8 @@ static int option(int shortopt, const WC
return SHORTFORMAT;
case 'u':
return UNIXFORMAT;
+ case 'w':
+ return WINDOWSFORMAT;
}
fprintf(stderr, "%s: invalid option ", progname);
@@ -90,10 +93,11 @@ static int parse_options(const WCHAR *ar
static const WCHAR longW[] = { 'l','o','n','g',0 };
static const WCHAR shortW[] = { 's','h','o','r','t',0 };
static const WCHAR unixW[] = { 'u','n','i','x',0 };
+ static const WCHAR windowsW[] = { 'w','i','n','d','o','w','s',0 };
static const WCHAR helpW[] = { 'h','e','l','p',0 };
static const WCHAR versionW[] = { 'v','e','r','s','i','o','n',0 };
static const WCHAR nullW[] = { 0 };
- static const WCHAR *longopts[] = { longW, shortW, unixW, helpW, versionW, nullW };
+ static const WCHAR *longopts[] = { longW, shortW, unixW, windowsW, helpW, versionW, nullW };
int outputformats = 0;
int done = 0;
int i, j;
@@ -136,7 +140,8 @@ static int parse_options(const WCHAR *ar
*/
int wmain(int argc, const WCHAR *argv[])
{
- wine_get_unix_file_name_t wine_get_unix_file_name_ptr = NULL;
+ LPSTR (*wine_get_unix_file_name_ptr)(LPCWSTR) = NULL;
+ LPWSTR (*wine_get_dos_file_name_ptr)(LPCSTR) = NULL;
WCHAR dos_pathW[MAX_PATH];
char path[MAX_PATH];
int outputformats;
@@ -147,7 +152,7 @@ int wmain(int argc, const WCHAR *argv[])
outputformats = UNIXFORMAT;
if (outputformats & UNIXFORMAT) {
- wine_get_unix_file_name_ptr = (wine_get_unix_file_name_t)
+ wine_get_unix_file_name_ptr = (void*)
GetProcAddress(GetModuleHandle("KERNEL32"),
"wine_get_unix_file_name");
if (wine_get_unix_file_name_ptr == NULL) {
@@ -157,6 +162,17 @@ int wmain(int argc, const WCHAR *argv[])
}
}
+ if (outputformats & WINDOWSFORMAT) {
+ wine_get_dos_file_name_ptr = (void*)
+ GetProcAddress(GetModuleHandle("KERNEL32"),
+ "wine_get_dos_file_name");
+ if (wine_get_dos_file_name_ptr == NULL) {
+ fprintf(stderr, "%s: cannot get the address of "
+ "'wine_get_dos_file_name'\n", progname);
+ exit(3);
+ }
+ }
+
for (i = 1; argv[i]; i++)
{
*path='\0';
@@ -180,6 +196,24 @@ int wmain(int argc, const WCHAR *argv[])
}
else printf( "\n" );
}
+ if (outputformats & WINDOWSFORMAT) {
+ WCHAR* windows_name;
+ char* unix_name;
+ DWORD size;
+
+ size=WideCharToMultiByte(CP_UNIXCP, 0, argv[i], -1, NULL, 0, NULL, NULL);
+ unix_name=HeapAlloc(GetProcessHeap(), 0, size);
+ WideCharToMultiByte(CP_UNIXCP, 0, argv[i], -1, unix_name, size, NULL, NULL);
+
+ if ((windows_name = wine_get_dos_file_name_ptr(unix_name)))
+ {
+ WideCharToMultiByte(CP_UNIXCP, 0, windows_name, -1, path, MAX_PATH, NULL, NULL);
+ printf("%s\n", path);
+ HeapFree( GetProcessHeap(), 0, windows_name );
+ }
+ else printf( "\n" );
+ HeapFree( GetProcessHeap(), 0, unix_name );
+ }
}
exit(0);
More information about the wine-patches
mailing list