This is when I noticed that if I pass an object manager path that starts with \?? and points to an existing file - and only then! - the command line argument as seen with Command() is messed up and the first parts of the path are missing, up to (but not including) the last backslash! Looking at Windows' GetCommandLine() API confirms that this is indeed happening on FreeBasic's side of things and not in my shell or Windows.
To reproduce, compile this program:
Code: Select all
#Include "windows.bi"
Print *GetCommandLine()
Print Command()
Print Command(1)
Print Command(2)
Print Command(3)
Normal:
Code: Select all
C:\>test.exe a b c
C:\test.exe a b c
a b c
a
b
c
Code: Select all
C:\>test.exe a \??\C:\Windows\System32\calc.exe c
C:\test.exe a \??\C:\Windows\System32\calc.exe c
a \calc.exe c
a
\calc.exe
c
Also happening if I put the value in doublequotes:
Code: Select all
C:\>test.exe a "\??\C:\Windows\System32\calc.exe" c
C:\test.exe a "\??\C:\Windows\System32\calc.exe" c
a \calc.exe c
a
\calc.exe
c
Code: Select all
C:\>test.exe a \??\NUL c
C:\test.exe a \??\NUL c
a \NUL c
a
\NUL
c
Code: Select all
C:\>test.exe a \??\GLOBALROOT\SystemRoot\System32\calc.exe b
C:\test.exe a "\??\GLOBALROOT\SystemRoot\System32\calc.exe b
a \calc.exe c
a
\calc.exe
c
Code: Select all
C:\>test.exe a \??\C:\Windows\System32\IDontExist.exe c
C:\test.exe a \??\C:\Windows\System32\IDontExist.exe c
a \??\C:\Windows\System32\IDontExist.exe c
a
\??\C:\Windows\System32\IDontExist.exe
c
Code: Select all
C:\>test.exe a \GLOBAL??\C:\Windows\System32\calc.exe c
C:\test.exe a \GLOBAL??\C:\Windows\System32\calc.exe c
a \GLOBAL??\C:\Windows\System32\calc.exe c
a
\GLOBAL??\C:\Windows\System32\calc.exe
c
Code: Select all
C:\>test.exe a \Device\HarddiskVolume3\Windows\System32\calc.exe c
C:\test.exe a \Device\HarddiskVolume3\Windows\System32\calc.exe c
a \Device\HarddiskVolume3\Windows\System32\calc.exe c
a
\Device\HarddiskVolume3\Windows\System32\calc.exe
c
Code: Select all
C:\>test.exe a \SystemRoot\System32\calc.exe c
C:\test.exe a \SystemRoot\System32\calc.exe c
a \SystemRoot\System32\calc.exe c
a
\SystemRoot\System32\calc.exe
c
If it was just always happening when the commandline argument started with "\??", I'd assume some kind of weird parsing bug, but the fact that it only happens for existing files makes this seem intentional but extremely unexpected.
---
EDIT: I looked at Process Monitor while starting the program and saw that it opens the file, and this is the stack:
This even happens with an entirely empty FreeBasic program, if I pass any argument starting with \??. I think this is very unexpected!
EDIT2: The Stack suggests it's part of _getmainargs which is part of msvcrt... so I'd assume that the same would happen with a C++ program compiled with Visual Studio, but it does not! I created this program to test:
Code: Select all
#include <iostream>
#include <windows.h>
int main(int argc, char* argv[]) {
std::cout << GetCommandLineA() << std::endl;
for (int i = 1; i < argc; i++) {
std::cout << argv[i] << std::endl;
}
return 0;
}