Advertisement
Guest User

avoid unicode paths because of ctypes

a guest
Dec 19th, 2012
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.91 KB | None | 0 0
  1. #http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130
  2. #http://code.google.com/p/pywinauto/source/browse/pywinauto/win32defines.py?r=ab2f9eb3fc0cfb5d2faaa4326ca7d598474a39ca
  3. from ctypes import *
  4. from ctypes.wintypes import *
  5. import sys
  6.  
  7. def wide2multibyte(fn):
  8.     """Map a UTF-16 (wide character) string to a new character string. The new
  9.    character string is not necessarily from a multibyte character set.
  10.    Objective: take a unicode string and convert it to a multibyte string that
  11.    Windows can use to represent file names in e.g. Chinese (mbcs will only work
  12.    if the host system 'happens to be' in the right geographical location)."""
  13.     if not sys.platform.startswith("win"):
  14.         return fn
  15.  
  16.     # constants, taken from pywinauto package
  17.     CP_UTF8 = 65001 # Variable c_int
  18.     CP_ACP = 0      # Variable c_int
  19.     NULL = 0        # Variable c_int
  20.     LPBOOL = POINTER(c_long)
  21.  
  22.     fnEnc = fn.encode("utf-16-le")
  23.     codePage = CP_UTF8 # --> Ergo: lpDefaultChar, lpUsedDefaultChar must be NULL
  24.     codePage = CP_ACP
  25.     dwFlags = 0
  26.     lpWideCharStr = fnEnc
  27.     cchWideChar = len(fn)   # counts the number of chars, not bytes
  28.     lpMultiByteStr = create_string_buffer(len(fnEnc))
  29.     cbMultiByte = 0
  30.     lpDefaultChar = c_char_p(NULL)  # ???
  31.     lpUsedDefaultChar = c_int(NULL)
  32.  
  33.     #Returns the number of bytes written to the buffer pointed to by lpMultiByteStr if successful.
  34.     wideCharToMultiByte = windll.kernel32.WideCharToMultiByte
  35.     wideCharToMultiByte.restype = c_int
  36.     wideCharToMultiByte.argtypes = [UINT, DWORD, LPCWSTR,
  37.                                     c_int, LPSTR, c_int,
  38.                                     LPCSTR, LPBOOL]
  39.     # why don't ArgumentErrors have a zero-based origin?
  40.     # E.g. 'ArgumentError: argument 1:...' means 'wrong type for codePage parameter'!
  41.  
  42.     # determine size
  43.     mbcssize = wideCharToMultiByte(codePage, dwFlags, lpWideCharStr,
  44.                                    cchWideChar, lpMultiByteStr, cbMultiByte,
  45.                                    lpDefaultChar, lpUsedDefaultChar)
  46.     # do conversion
  47.     retcode = wideCharToMultiByte(codePage, dwFlags, lpWideCharStr,
  48.                                   cchWideChar, lpMultiByteStr, mbcssize,
  49.                                   lpDefaultChar, lpUsedDefaultChar)
  50.     print retcode
  51.     print mbcssize
  52.     print repr(lpMultiByteStr.value), lpMultiByteStr.value
  53.  
  54.     if mbcssize <= 0:
  55.         getLastError = windll.kernel32.GetLastError
  56.         getLastError.restype = DWORD
  57.         retcodes = {122: "ERROR_INSUFFICIENT_BUFFER",
  58.                     1004: "ERROR_INVALID_FLAGS",
  59.                     87: "ERROR_INVALID_PARAMETER",
  60.                     1113: "ERROR_NO_UNICODE_TRANSLATION"}
  61.         retcode = getLastError()
  62.         print "Error:", retcodes.get(retcode, retcode) # error code: 0
  63.     return lpMultiByteStr.value
  64.  
  65. fn = u'\u0c0f\u0c2e\u0c02\u0c21\u0c40' + '.txt'
  66. wide2multibyte(fn)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement