/* Parse the root part of file name, if present. Return length and
optionally store pointer to char after root. */
static int
-parse_root (char * name, char ** pPath)
+parse_root (const char * name, const char ** pPath)
{
- char * start = name;
+ const char * start = name;
if (name == NULL)
return 0;
{
char * o = buf;
char * p;
- char * q;
+ const char * q;
char full[ MAX_UTF8_PATH ];
int len;
unixtodos_filename (full);
/* Copy root part verbatim. */
- len = parse_root (full, &p);
+ len = parse_root (full, (const char **)&p);
memcpy (o, full, len);
o += len;
*o = '\0';
add_volume_info (char * root_dir, volume_info_data * info)
{
info->root_dir = xstrdup (root_dir);
+ unixtodos_filename (info->root_dir);
info->next = volume_cache;
volume_cache = info;
}
GetCachedVolumeInformation (char * root_dir)
{
volume_info_data * info;
- char default_root[ MAX_PATH ];
+ char default_root[ MAX_UTF8_PATH ];
+ char name[MAX_PATH+1];
+ char type[MAX_PATH+1];
/* NULL for root_dir means use root from current directory. */
if (root_dir == NULL)
{
- if (GetCurrentDirectory (MAX_PATH, default_root) == 0)
- return NULL;
- parse_root (default_root, &root_dir);
+ if (w32_unicode_filenames)
+ {
+ wchar_t curdirw[MAX_PATH];
+
+ if (GetCurrentDirectoryW (MAX_PATH, curdirw) == 0)
+ return NULL;
+ filename_from_utf16 (curdirw, default_root);
+ }
+ else
+ {
+ char curdira[MAX_PATH];
+
+ if (GetCurrentDirectoryA (MAX_PATH, curdira) == 0)
+ return NULL;
+ filename_from_ansi (curdira, default_root);
+ }
+ parse_root (default_root, (const char **)&root_dir);
*root_dir = 0;
root_dir = default_root;
}
if (info == NULL || ! VOLINFO_STILL_VALID (root_dir, info))
{
- char name[ 256 ];
DWORD serialnum;
DWORD maxcomp;
DWORD flags;
- char type[ 256 ];
/* Info is not cached, or is stale. */
- if (!GetVolumeInformation (root_dir,
- name, sizeof (name),
- &serialnum,
- &maxcomp,
- &flags,
- type, sizeof (type)))
- return NULL;
+ if (w32_unicode_filenames)
+ {
+ wchar_t root_w[MAX_PATH];
+ wchar_t name_w[MAX_PATH+1];
+ wchar_t type_w[MAX_PATH+1];
+
+ filename_to_utf16 (root_dir, root_w);
+ if (!GetVolumeInformationW (root_w,
+ name_w, sizeof (name_w),
+ &serialnum,
+ &maxcomp,
+ &flags,
+ type_w, sizeof (type_w)))
+ return NULL;
+ /* Hmm... not really 100% correct, as these 2 are not file
+ names... */
+ filename_from_utf16 (name_w, name);
+ filename_from_utf16 (type_w, type);
+ }
+ else
+ {
+ char root_a[MAX_PATH];
+ char name_a[MAX_PATH+1];
+ char type_a[MAX_PATH+1];
+
+ filename_to_ansi (root_dir, root_a);
+ if (!GetVolumeInformationA (root_a,
+ name_a, sizeof (name_a),
+ &serialnum,
+ &maxcomp,
+ &flags,
+ type_a, sizeof (type_a)))
+ return NULL;
+ filename_from_ansi (name_a, name);
+ filename_from_ansi (type_a, type);
+ }
/* Cache the volume information for future use, overwriting existing
entry if present. */
}
info->name = xstrdup (name);
+ unixtodos_filename (info->name);
info->serialnum = serialnum;
info->maxcomp = maxcomp;
info->flags = flags;
static int
get_volume_info (const char * name, const char ** pPath)
{
- char temp[MAX_PATH];
+ char temp[MAX_UTF8_PATH];
char *rootname = NULL; /* default to current volume */
volume_info_data * info;
+ int root_len = parse_root (name, pPath);
if (name == NULL)
return FALSE;
- /* Find the root name of the volume if given. */
- if (isalpha (name[0]) && name[1] == ':')
+ /* Copy the root name of the volume, if given. */
+ if (root_len)
{
+ strncpy (temp, name, root_len);
+ temp[root_len] = '\0';
+ unixtodos_filename (temp);
rootname = temp;
- temp[0] = *name++;
- temp[1] = *name++;
- temp[2] = '\\';
- temp[3] = 0;
}
- else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
- {
- char *str = temp;
- int slashes = 4;
- int dbcs_p = max_filename_mbslen () > 1;
-
- rootname = temp;
- do
- {
- if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
- break;
- if (!dbcs_p)
- *str++ = *name++;
- else
- {
- const char *p = name;
-
- name = CharNextExA (file_name_codepage, name, 0);
- memcpy (str, p, name - p);
- str += name - p;
- }
- }
- while ( *name );
-
- *str++ = '\\';
- *str = 0;
- }
-
- if (pPath)
- *pPath = name;
info = GetCachedVolumeInformation (rootname);
if (info != NULL)
return FALSE;
}
-/* Map filename to a valid 8.3 name if necessary.
- The result is a pointer to a static buffer, so CAVEAT EMPTOR! */
+/* Convert all slashes in a filename to backslashes, and map filename
+ to a valid 8.3 name if necessary. The result is a pointer to a
+ static buffer, so CAVEAT EMPTOR! */
const char *
map_w32_filename (const char * name, const char ** pPath)
{
- static char shortname[MAX_PATH];
+ static char shortname[MAX_UTF8_PATH];
char * str = shortname;
char c;
char * path;
const char * save_name = name;
- if (strlen (name) >= MAX_PATH)
+ if (strlen (name) >= sizeof (shortname))
{
/* Return a filename which will cause callers to fail. */
strcpy (shortname, "?");
str[-1] = c; /* replace last character of part */
/* FALLTHRU */
default:
- if ( left )
+ if ( left && 'A' <= c && c <= 'Z' )
{
*str++ = tolower (c); /* map to lower case (looks nicer) */
left--;