Using GetLongPathNameW to determine file names to check for case sensitivity on windows instead of creating a file.

This commit is contained in:
Malte Ried 2015-09-11 12:35:41 +02:00
parent 951a11809f
commit 4c249ac25b

View file

@ -16,6 +16,7 @@
from __future__ import (division, absolute_import, print_function,
unicode_literals)
import ctypes
import os
import sys
@ -781,26 +782,30 @@ def is_filesystem_case_sensitive(path):
# python < 3.0
return not os.path.samefile(path.lower(),
path.upper())
# On windows we create a file with a lower case name
# and try to find the file using an upper case name.
base_file_name = 'beetsCaseSensitivityCheck'
lower = os.path.join(path, base_file_name.lower())
upper = os.path.join(path, base_file_name.upper())
# Check if one of the files (upper and lower case) do exist
# already
i = 0
while os.path.exists(lower) or os.path.exists(upper):
file_name = '{0}{1}'.format(base_file_name, i)
lower = os.path.join(path, file_name.lower())
upper = os.path.join(path, file_name.upper())
# Create the file using a lower case name
with open(lower, 'w'):
pass
# Check if the file can be found using the upper cas name
case_sensitive = not os.path.exists(upper)
# Remove the temporary file
os.remove(lower)
return case_sensitive
# On windows we use GetLongPathNameW to determine the real path
# using the actual case.
def get_long_path_name(short_path):
if not isinstance(short_path, unicode):
short_path = unicode(short_path)
buf = ctypes.create_unicode_buffer(260)
get_long_path_name_w = ctypes.windll.kernel32.GetLongPathNameW
return_value = get_long_path_name_w(short_path, buf, 260)
if return_value == 0 or return_value > 260:
# An error occurred
return short_path
else:
long_path = buf.value
# GetLongPathNameW does not change the case of the drive
# letter.
if len(long_path) > 1 and long_path[1] == ':':
long_path = long_path[0].upper() + long_path[1:]
return long_path
lower = get_long_path_name(path.lower())
upper = get_long_path_name(path.upper())
return lower != upper
else:
return True
# By default, the case sensitivity depends on the platform.