Advertisement
Zeriab

[RGSSx] Retrieve file path from environment variables

May 16th, 2016
334
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 3.33 KB | None | 0 0
  1. ##
  2. # Copyright (c) 2016 Zeriab
  3. #
  4. # This software is provided 'as-is', without any express or implied
  5. # warranty. In no event will the authors be held liable for any damages
  6. # arising from the use of this software.
  7. #
  8. # Permission is granted to anyone to use this software for any purpose,
  9. # including commercial applications, and to alter it and redistribute it
  10. # freely, subject to the following restrictions:
  11. #
  12. # 1. The origin of this software must not be misrepresented; you must not
  13. #    claim that you wrote the original software. If you use this software
  14. #    in a product, an acknowledgement in the product documentation would be
  15. #    appreciated but is not required.
  16. # 2. Altered source versions must be plainly marked as such, and must not be
  17. #    misrepresented as being the original software.
  18. # 3. This notice may not be removed or altered from any source distribution.
  19. #
  20. ##
  21. # usage:
  22. #   path = EnvUtil.get_path_from_env("APPDATA")
  23. #
  24. module EnvUtil
  25.   THROW_ERRORS = true
  26.  
  27.   # Win32API bindings
  28.   GetEnvironmentVariable = Win32API.new('Kernel32', 'GetEnvironmentVariableW', 'ppi', 'i')
  29.   GetShortPathName = Win32API.new('Kernel32', 'GetShortPathNameW', 'ppi', 'i')
  30.   GetLastError = Win32API.new('Kernel32', 'GetLastError', '', 'i')
  31.  
  32.   ##
  33.   # Windows error codes
  34.   #
  35.  
  36.   # The system cannot find the path specified.
  37.   ERROR_PATH_NOT_FOUND = 3  
  38.   # The system could not find the environment option that was entered.
  39.   ERROR_ENVVAR_NOT_FOUND = 203
  40.  
  41.   module_function
  42.   def get_shortpath_from_env(name)
  43.     # Change to wide-chars with null-terminator
  44.     array = name.split('')
  45.     env_name = array.join("\0") + "\0\0\0"
  46.    
  47.     # Fetch path in wide-chars
  48.     env_buffer = "\0" * 1024
  49.     env_buffer_length = env_buffer.length - 1
  50.     env_length = GetEnvironmentVariable.call(env_name,
  51.                                              env_buffer,
  52.                                              env_buffer_length)  
  53.  
  54.     # If the function fails for any other reason, the return value is zero
  55.     if env_length <= 0
  56.       return nil unless THROW_ERRORS
  57.       raise :env_error, GetLastError.call()
  58.     end
  59.    
  60.     # Try to retrieve the short path form of the specified path
  61.     short_name_buffer = "\0" * 1024
  62.     # Ensure the string will be null-terminated
  63.     short_name_buffer_length = short_name_buffer.length - 1
  64.     short_name_length = GetShortPathName.call(env_buffer,
  65.                                               short_name_buffer,
  66.                                               short_name_buffer_length)
  67.    
  68.     # If the function fails for any other reason, the return value is zero
  69.     if short_name_length <= 0
  70.       return nil unless THROW_ERRORS
  71.       raise :shortname_error, GetLastError.call()
  72.     end
  73.    
  74.     # A short name confirming to the specification will only have left side of
  75.     # the wide characters file. Following this we can convert the string into
  76.     # UTF-8 by removing all null-terminators
  77.     return short_name_buffer.gsub("\0", '')
  78.   end
  79.  
  80.   def get_path_from_env(env_name)
  81.     # Sanity check
  82.     path = ENV[env_name]
  83.     return nil if path.nil?
  84.    
  85.     # Some paths work without being converted to short path form
  86.     return path if FileTest.exists?(path)
  87.    
  88.     # Try to fetch the short path from as a fallback
  89.     return get_shortpath_from_env(env_name)
  90.   end
  91. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement