Skip to content

Commit

Permalink
Properly handle short file names on the command line in Windows [TAKE 2]
Browse files Browse the repository at this point in the history
Trying to expand short names with a relative path doesn't work, so this
first gets the module name to get a full path (which can still have short
names).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273171 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
amccarth-google committed Jun 20, 2016
1 parent 307efec commit 741101d
Showing 1 changed file with 34 additions and 2 deletions.
36 changes: 34 additions & 2 deletions lib/Support/Windows/Process.inc
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
const int DirSize = Dir.size();

// Search for matching files.
// FIXME: This assumes the wildcard is only in the file name and not in the
// directory portion of the file path. For example, it doesn't handle
// "*\foo.c" nor "s?c\bar.cpp".
WIN32_FIND_DATAW FileData;
HANDLE FindHandle = FindFirstFileW(Arg, &FileData);
if (FindHandle == INVALID_HANDLE_VALUE) {
Expand All @@ -215,7 +218,7 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
if (ec)
break;

// Push the filename onto Dir, and remove it afterwards.
// Append FileName to Dir, and remove it afterwards.
llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size()));
AllocateAndPush(Dir, Args, Allocator);
Dir.resize(DirSize);
Expand All @@ -225,6 +228,23 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
return ec;
}

static std::error_code
ExpandShortFileName(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
SpecificBumpPtrAllocator<char> &Allocator) {
SmallVector<wchar_t, MAX_PATH> LongPath;
DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity());
if (Length == 0)
return mapWindowsError(GetLastError());
if (Length > LongPath.capacity()) {
// We're not going to try to deal with paths longer than MAX_PATH, so we'll
// treat this as an error. GetLastError() returns ERROR_SUCCESS, which
// isn't useful, so we'll hardcode an appropriate error value.
return mapWindowsError(ERROR_INSUFFICIENT_BUFFER);
}
LongPath.set_size(Length);
return ConvertAndPushArg(LongPath.data(), Args, Allocator);
}

std::error_code
Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
ArrayRef<const char *>,
Expand All @@ -238,7 +258,19 @@ Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
Args.reserve(ArgCount);
std::error_code ec;

for (int i = 0; i < ArgCount; ++i) {
// The first argument may contain just the name of the executable (e.g.,
// "clang") rather than the full path, so swap it with the full path.
wchar_t ModuleName[MAX_PATH];
int Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH);
if (0 < Length && Length < MAX_PATH)
UnicodeCommandLine[0] = ModuleName;

// If the first argument is a shortened (8.3) name (which is possible even
// if we got the module name), the driver will have trouble distinguishing it
// (e.g., clang.exe v. clang++.exe), so expand it now.
ec = ExpandShortFileName(UnicodeCommandLine[0], Args, ArgAllocator);

for (int i = 1; i < ArgCount && !ec; ++i) {
ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator);
if (ec)
break;
Expand Down

0 comments on commit 741101d

Please sign in to comment.