mirror of https://github.com/aria2/aria2
mingw: Defer the falloc warning until falloc is specified by option
parent
c9e2223741
commit
1126722bd3
|
@ -34,14 +34,33 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "FallocFileAllocationIterator.h"
|
#include "FallocFileAllocationIterator.h"
|
||||||
#include "DlAbortEx.h"
|
#include "DlAbortEx.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "LogFactory.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
bool FallocFileAllocationIterator::gainPrivilegeAttempted_ = false;
|
||||||
|
#endif // __MINGW32__
|
||||||
|
|
||||||
FallocFileAllocationIterator::FallocFileAllocationIterator(BinaryStream* stream,
|
FallocFileAllocationIterator::FallocFileAllocationIterator(BinaryStream* stream,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t totalLength)
|
int64_t totalLength)
|
||||||
: stream_(stream), offset_(offset), totalLength_(totalLength)
|
: stream_(stream), offset_(offset), totalLength_(totalLength)
|
||||||
{
|
{
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
// Windows build: --file-allocation=falloc uses SetFileValidData
|
||||||
|
// which requires SE_MANAGE_VOLUME_NAME privilege. SetFileValidData
|
||||||
|
// has security implications (see
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365544%28v=vs.85%29.aspx).
|
||||||
|
if (!gainPrivilegeAttempted_) {
|
||||||
|
if (!util::gainPrivilege(SE_MANAGE_VOLUME_NAME)) {
|
||||||
|
A2_LOG_WARN("--file-allocation=falloc will not work properly.");
|
||||||
|
}
|
||||||
|
|
||||||
|
gainPrivilegeAttempted_ = true;
|
||||||
|
}
|
||||||
|
#endif // __MINGW32__
|
||||||
}
|
}
|
||||||
|
|
||||||
void FallocFileAllocationIterator::allocateChunk()
|
void FallocFileAllocationIterator::allocateChunk()
|
||||||
|
|
|
@ -47,6 +47,10 @@ private:
|
||||||
int64_t offset_;
|
int64_t offset_;
|
||||||
int64_t totalLength_;
|
int64_t totalLength_;
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
static bool gainPrivilegeAttempted_;
|
||||||
|
#endif // __MINGW32__
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FallocFileAllocationIterator(BinaryStream* stream, int64_t offset,
|
FallocFileAllocationIterator(BinaryStream* stream, int64_t offset,
|
||||||
int64_t totalLength);
|
int64_t totalLength);
|
||||||
|
|
|
@ -94,79 +94,6 @@ Platform::Platform() { setUp(); }
|
||||||
|
|
||||||
Platform::~Platform() { tearDown(); }
|
Platform::~Platform() { tearDown(); }
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
namespace {
|
|
||||||
bool gainPrivilege(LPCTSTR privName)
|
|
||||||
{
|
|
||||||
LUID luid;
|
|
||||||
TOKEN_PRIVILEGES tp;
|
|
||||||
|
|
||||||
if (!LookupPrivilegeValue(nullptr, privName, &luid)) {
|
|
||||||
auto errNum = GetLastError();
|
|
||||||
A2_LOG_WARN(fmt("Lookup for privilege name %s failed. cause: %s", privName,
|
|
||||||
util::formatLastError(errNum).c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
tp.PrivilegeCount = 1;
|
|
||||||
tp.Privileges[0].Luid = luid;
|
|
||||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
||||||
|
|
||||||
HANDLE token;
|
|
||||||
if (!OpenProcessToken(GetCurrentProcess(),
|
|
||||||
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
|
|
||||||
auto errNum = GetLastError();
|
|
||||||
A2_LOG_WARN(fmt("Getting process token failed. cause: %s",
|
|
||||||
util::formatLastError(errNum).c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto tokenCloser = defer(token, CloseHandle);
|
|
||||||
|
|
||||||
if (!AdjustTokenPrivileges(token, FALSE, &tp, 0, NULL, NULL)) {
|
|
||||||
auto errNum = GetLastError();
|
|
||||||
A2_LOG_WARN(fmt("Gaining privilege %s failed. cause: %s", privName,
|
|
||||||
util::formatLastError(errNum).c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check privilege was really gained
|
|
||||||
DWORD bufsize = 0;
|
|
||||||
GetTokenInformation(token, TokenPrivileges, nullptr, 0, &bufsize);
|
|
||||||
if (bufsize == 0) {
|
|
||||||
A2_LOG_WARN("Checking privilege failed.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto buf = make_unique<char[]>(bufsize);
|
|
||||||
if (!GetTokenInformation(token, TokenPrivileges, buf.get(), bufsize,
|
|
||||||
&bufsize)) {
|
|
||||||
auto errNum = GetLastError();
|
|
||||||
A2_LOG_WARN(fmt("Checking privilege failed. cause: %s",
|
|
||||||
util::formatLastError(errNum).c_str()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto privs = reinterpret_cast<TOKEN_PRIVILEGES*>(buf.get());
|
|
||||||
for (size_t i = 0; i < privs->PrivilegeCount; ++i) {
|
|
||||||
auto& priv = privs->Privileges[i];
|
|
||||||
if (memcmp(&priv.Luid, &luid, sizeof(luid)) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (priv.Attributes == SE_PRIVILEGE_ENABLED) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
A2_LOG_WARN(fmt("Gaining privilege %s failed.", privName));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
#endif // __MINGW32__
|
|
||||||
|
|
||||||
bool Platform::setUp()
|
bool Platform::setUp()
|
||||||
{
|
{
|
||||||
if (initialized_) {
|
if (initialized_) {
|
||||||
|
@ -239,15 +166,6 @@ bool Platform::setUp()
|
||||||
(void)_setmode(_fileno(stdin), _O_BINARY);
|
(void)_setmode(_fileno(stdin), _O_BINARY);
|
||||||
(void)_setmode(_fileno(stdout), _O_BINARY);
|
(void)_setmode(_fileno(stdout), _O_BINARY);
|
||||||
(void)_setmode(_fileno(stderr), _O_BINARY);
|
(void)_setmode(_fileno(stderr), _O_BINARY);
|
||||||
|
|
||||||
// Windows build: --file-allocation=falloc uses SetFileValidData
|
|
||||||
// which requires SE_MANAGE_VOLUME_NAME privilege. SetFileValidData
|
|
||||||
// has security implications (see
|
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365544%28v=vs.85%29.aspx).
|
|
||||||
if (!gainPrivilege(SE_MANAGE_VOLUME_NAME)) {
|
|
||||||
A2_LOG_WARN("--file-allocation=falloc will not work properly.");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __MINGW32__
|
#endif // __MINGW32__
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
71
src/util.cc
71
src/util.cc
|
@ -2121,6 +2121,77 @@ void make_fd_cloexec(int fd)
|
||||||
#endif // !__MINGW32__
|
#endif // !__MINGW32__
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
bool gainPrivilege(LPCTSTR privName)
|
||||||
|
{
|
||||||
|
LUID luid;
|
||||||
|
TOKEN_PRIVILEGES tp;
|
||||||
|
|
||||||
|
if (!LookupPrivilegeValue(nullptr, privName, &luid)) {
|
||||||
|
auto errNum = GetLastError();
|
||||||
|
A2_LOG_WARN(fmt("Lookup for privilege name %s failed. cause: %s", privName,
|
||||||
|
util::formatLastError(errNum).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp.PrivilegeCount = 1;
|
||||||
|
tp.Privileges[0].Luid = luid;
|
||||||
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
|
||||||
|
HANDLE token;
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(),
|
||||||
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
|
||||||
|
auto errNum = GetLastError();
|
||||||
|
A2_LOG_WARN(fmt("Getting process token failed. cause: %s",
|
||||||
|
util::formatLastError(errNum).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tokenCloser = defer(token, CloseHandle);
|
||||||
|
|
||||||
|
if (!AdjustTokenPrivileges(token, FALSE, &tp, 0, NULL, NULL)) {
|
||||||
|
auto errNum = GetLastError();
|
||||||
|
A2_LOG_WARN(fmt("Gaining privilege %s failed. cause: %s", privName,
|
||||||
|
util::formatLastError(errNum).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check privilege was really gained
|
||||||
|
DWORD bufsize = 0;
|
||||||
|
GetTokenInformation(token, TokenPrivileges, nullptr, 0, &bufsize);
|
||||||
|
if (bufsize == 0) {
|
||||||
|
A2_LOG_WARN("Checking privilege failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto buf = make_unique<char[]>(bufsize);
|
||||||
|
if (!GetTokenInformation(token, TokenPrivileges, buf.get(), bufsize,
|
||||||
|
&bufsize)) {
|
||||||
|
auto errNum = GetLastError();
|
||||||
|
A2_LOG_WARN(fmt("Checking privilege failed. cause: %s",
|
||||||
|
util::formatLastError(errNum).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto privs = reinterpret_cast<TOKEN_PRIVILEGES*>(buf.get());
|
||||||
|
for (size_t i = 0; i < privs->PrivilegeCount; ++i) {
|
||||||
|
auto& priv = privs->Privileges[i];
|
||||||
|
if (memcmp(&priv.Luid, &luid, sizeof(luid)) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (priv.Attributes == SE_PRIVILEGE_ENABLED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
A2_LOG_WARN(fmt("Gaining privilege %s failed.", privName));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif // __MINGW32__
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -867,6 +867,10 @@ std::string formatLastError(int errNum);
|
||||||
// CreateProcess call.
|
// CreateProcess call.
|
||||||
void make_fd_cloexec(int fd);
|
void make_fd_cloexec(int fd);
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
bool gainPrivilege(LPCTSTR privName);
|
||||||
|
#endif // __MINGW32__
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue