Humanizing paths in Windows - winapi

The directories crate internally stores paths in Windows in their long form, such as //?/C:/Users/roey/.emacs.d. These paths are printed in this form when their .display() method is called, which is not very human friendly. Is there any way to humanize these paths without creating String and calling .replace()?

Related

Retrieving a long path from "\Device\HarddiskVolume1\Progra~1"

I'm writing a ProcessExplorer-like tool that shows all open files in the system.
Calling the NtQueryObject(,ObjectNameInformation,,,) gives me a path that looks like \Device\HarddiskVolume1\Users\ADMINI~1\AppData\Local\Temp\FXSAPIDebugLogFile.txt, so it is an NT device path that sometimes has shortened segments (ADMINI~1 in this case).
I don't really need to convert this path to a "standard" one (like C:\Users), but I need to expand it to a long form, so it should look like \Device\HarddiskVolume1\Users\Administrator\AppData\Local\Temp\FXSAPIDebugLogFile.txt. Besides, converting a device path to a standard one won't even be possible if the volume doesn't have a mountpoint.
I need a solution that works from Windows XP onwards.
Unfortunately, the most obvious method - using the GetLongPathNameW function doesn't work with a path like this, it returns a ERROR_INVALID_NAME for a path like this.
I tried different path prefixes: \\?\, \\.\, \??\, \\.\GLOBALROOT\ - none of this helped.
FindFirstFileW also doesn't accept a path like this on Vista.
It's strange, because the CreateFile function works with a \Device\HarddiskVolume path just fine.
Also I found, that if I remove the Device word from the path, making it \\.\HarddiskVolume1\Users\ADMINI~1\AppData\Local\Temp\FXSAPIDebugLogFile.txt, the GetLongPathNameW actually returns a correct long path. Unfortunately, this doesn't work on Windows XP/Vista.
I'd like to know if there is another method, that will work on Windows XP too.

Server.Execute with a fixed path

I am trying to implement server.execute() via an include from a virtual functions library (<!-- #include virtual="lib/functions.asp"-->) that I can call on from any subfolder in the system. I am trying to implement a new function that should exist on all pages in our system, and it would be virtually unfeasible to go in and add it manually to every single page. And I need it to be implemented in such a way that it does not interfere with the code on any page which is why I am doing it as a server.execute() in a virtual lib that I know already exists everywhere in the system.
For example:
'location of routine.asp = https://example.com/admin/routine/routine.asp
Server.Execute("routine/routine.asp")
'Will work if I add the virtual lib from an ASP-page in the admin subfolder, but not if I call it from another subfolder
Server.Execute("https://example.com/admin/routine/routine.asp")
'Does not work, because server.execute can't handle that kind of fixed path
The documentation clearly states that colons and double-slashes are not allowed, but I can't figure out how I can make sure the execution of the file happens no matter where in the system it's called from.
Question: How can I make server.execute(path)'s path handle a fixed path, or change the path dynamically to make sure I can always target the file correctly?
If you want to use an absolute path make sure you are using an absolute path (full path from the root).
Think you simply need to specify the absolute path explicitly;
Server.Execute("/admin/routine/routine.asp")

How to check if two paths point to the same folder location Ruby?

I have the two folder paths as string. How to check if two paths point to same folder location. I do not want to compare the string as it will not be the proper way. I tried with File.identical? but it returns false as it seems to expect two file paths not folder paths as agruments. For your information, I want to use this code in Ruby filter plugin in Logstash
I don't see anything improper in comparing strings if they provide precise and correct location. If File.identical? doesn't work and Dir does't provide similar method, I would just convert the paths with File.realdirpath() and compare them.
File.realdirpath("first/path/") == File.realdirpath("second/path/")
It follows symlinks.
https://ruby-doc.org/core-2.5.0/File.html#method-c-realdirpath
If you are on a Unix-like system and really distrust string comparisons, you can compare inode numbers.
File.stat(File.realdirpath("first/path/")).ino == File.stat(File.realdirpath("second/path/")).ino
EDITED
Didn't notice your comment about being on Windows. I don't know how File::Stat exactly works there, but it should be available and using info it provides might be better than string comparison.
File.realpath(folder_path) == File.realpath(other_folder_path)
This method returns string with absolute pathname in the actual filesystem not containing symlinks or dots.
Unlike File.realdirpath, all components of the pathname must exist when this method is called.

How can I force QueryFullProcessImageNameW to give me the full form?

I'm enumerating the running processes, and for each process, using QueryFullProcessImageNameW to get the path on disk of the process.
QueryFullProcessImageNameW returns a path like "C:\Program Files (x86)\ALongFolderName\foobar.exe" for most processes.
But for some processes, I get the old 8.3 format instead, like "C:\PROGRA~2\ALONGF~1\foobar.exe'"
How can I always retrieve the long form, as I can see it in File Explorer?
You cannot force the API to return the long form; it simply returns the path that was used to load the corresponding image in the first place.
You can instead call GetLongPathName() to translate an 8.3 name into its long form.

Embedding data in resource files

Due to some brain damage, (either in windows or in me), there appears to be no API to get the size of a windows resource produced by LoadResource. The return type is HANDLE, but it's not a real handle, and GlobalSize does not work on it.
So absent the API, I need to embed my blobs in some simple format that will
wrap them with their length. Surely there must be a utility somewhere that
rewrites a file as a length, followed by the contents of the file, or some
such trivial encoding.
Not an answer to your question as to a helper for the work-around, but the API is not missing.
When you called LoadResource, you passed in the module handle and a HRSRC handle.
If you call SizeOfResource with the same arguments, it returns the size of the resource.

Resources