forked from premiere/premiere-libtorrent
merged SetFileValidData fix from RC_0_16
This commit is contained in:
parent
c937004443
commit
cc08512ee3
|
@ -41,6 +41,7 @@
|
|||
* fix uTP edge case where udp socket buffer fills up
|
||||
* fix nagle implementation in uTP
|
||||
|
||||
* fix use of SetFileValidData on windows
|
||||
* fix crash when using full allocation storage mode
|
||||
* improve error_code and error_category support in python bindings
|
||||
* fix python binding for external_ip_alert
|
||||
|
|
131
src/file.cpp
131
src/file.cpp
|
@ -1946,6 +1946,108 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
bool get_manage_volume_privs()
|
||||
{
|
||||
typedef BOOL (WINAPI *OpenProcessToken_t)(
|
||||
HANDLE ProcessHandle,
|
||||
DWORD DesiredAccess,
|
||||
PHANDLE TokenHandle);
|
||||
|
||||
typedef BOOL (WINAPI *LookupPrivilegeValue_t)(
|
||||
LPCSTR lpSystemName,
|
||||
LPCSTR lpName,
|
||||
PLUID lpLuid);
|
||||
|
||||
typedef BOOL (WINAPI *AdjustTokenPrivileges_t)(
|
||||
HANDLE TokenHandle,
|
||||
BOOL DisableAllPrivileges,
|
||||
PTOKEN_PRIVILEGES NewState,
|
||||
DWORD BufferLength,
|
||||
PTOKEN_PRIVILEGES PreviousState,
|
||||
PDWORD ReturnLength);
|
||||
|
||||
static OpenProcessToken_t pOpenProcessToken = NULL;
|
||||
static LookupPrivilegeValue_t pLookupPrivilegeValue = NULL;
|
||||
static AdjustTokenPrivileges_t pAdjustTokenPrivileges = NULL;
|
||||
static bool failed_advapi = false;
|
||||
|
||||
if (pOpenProcessToken == NULL && !failed_advapi)
|
||||
{
|
||||
HMODULE advapi = LoadLibraryA("advapi32");
|
||||
if (advapi == NULL)
|
||||
{
|
||||
failed_advapi = true;
|
||||
return false;
|
||||
}
|
||||
pOpenProcessToken = (OpenProcessToken_t)GetProcAddress(advapi, "OpenProcessToken");
|
||||
pLookupPrivilegeValue = (LookupPrivilegeValue_t)GetProcAddress(advapi, "LookupPrivilegeValueA");
|
||||
pAdjustTokenPrivileges = (AdjustTokenPrivileges_t)GetProcAddress(advapi, "AdjustTokenPrivileges");
|
||||
if (pOpenProcessToken == NULL
|
||||
|| pLookupPrivilegeValue == NULL
|
||||
|| pAdjustTokenPrivileges == NULL)
|
||||
{
|
||||
failed_advapi = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE token;
|
||||
if (!pOpenProcessToken(GetCurrentProcess()
|
||||
, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
|
||||
return false;
|
||||
|
||||
TOKEN_PRIVILEGES privs;
|
||||
if (!pLookupPrivilegeValue(NULL, "SeManageVolumePrivilege"
|
||||
, &privs.Privileges[0].Luid))
|
||||
{
|
||||
CloseHandle(token);
|
||||
return false;
|
||||
}
|
||||
|
||||
privs.PrivilegeCount = 1;
|
||||
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
bool ret = pAdjustTokenPrivileges(token, FALSE, &privs, 0, NULL, NULL)
|
||||
&& GetLastError() == ERROR_SUCCESS;
|
||||
|
||||
CloseHandle(token);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void set_file_valid_data(HANDLE f, boost::int64_t size)
|
||||
{
|
||||
static bool has_privs = get_manage_volume_privs();
|
||||
|
||||
typedef BOOL (WINAPI *SetFileValidData_t)(HANDLE, LONGLONG);
|
||||
static SetFileValidData_t pSetFileValidData = NULL;
|
||||
static bool failed_kernel32 = false;
|
||||
|
||||
if (pSetFileValidData == NULL && !failed_kernel32)
|
||||
{
|
||||
HMODULE k32 = LoadLibraryA("kernel32");
|
||||
if (k32 == NULL)
|
||||
{
|
||||
failed_kernel32 = true;
|
||||
return;
|
||||
}
|
||||
pSetFileValidData = (SetFileValidData_t)GetProcAddress(k32, "SetFileValidData");
|
||||
if (pSetFileValidData == NULL)
|
||||
{
|
||||
failed_kernel32 = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(pSetFileValidData);
|
||||
|
||||
// we don't necessarily expect to have enough
|
||||
// privilege to do this, so ignore errors.
|
||||
pSetFileValidData(f, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool file::set_size(size_type s, error_code& ec)
|
||||
{
|
||||
TORRENT_ASSERT(is_open());
|
||||
|
@ -1995,6 +2097,10 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
ec.assign(INVALID_SET_FILE_POINTER, get_system_category());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((m_open_mode & sparse) == 0)
|
||||
set_file_valid_data(m_file_handle, s);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2037,10 +2143,8 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
#else
|
||||
typedef DWORD (WINAPI *GetCompressedFileSize_t)(LPCSTR lpFileName, LPDWORD lpFileSizeHigh);
|
||||
#endif
|
||||
typedef BOOL (WINAPI *SetFileValidData_t)(HANDLE hFile, LONGLONG ValidDataLength);
|
||||
|
||||
static GetCompressedFileSize_t GetCompressedFileSize_ = NULL;
|
||||
static SetFileValidData_t SetFileValidData = NULL;
|
||||
|
||||
static bool failed_kernel32 = false;
|
||||
|
||||
|
@ -2054,11 +2158,6 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
#else
|
||||
GetCompressedFileSize_ = (GetCompressedFileSize_t)GetProcAddress(kernel32, "GetCompressedFileSizeA");
|
||||
#endif
|
||||
SetFileValidData = (SetFileValidData_t)GetProcAddress(kernel32, "SetFileValidData");
|
||||
if ((GetCompressedFileSize_ == NULL) || (SetFileValidData == NULL))
|
||||
{
|
||||
failed_kernel32 = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2066,7 +2165,8 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
}
|
||||
}
|
||||
|
||||
if (!failed_kernel32 && GetCompressedFileSize_ && SetFileValidData)
|
||||
offs.QuadPart = 0;
|
||||
if (GetCompressedFileSize_)
|
||||
{
|
||||
// only allocate the space if the file
|
||||
// is not fully allocated
|
||||
|
@ -2078,13 +2178,14 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
ec.assign(GetLastError(), get_system_category());
|
||||
if (ec) return false;
|
||||
}
|
||||
if (offs.QuadPart != s)
|
||||
{
|
||||
// if the user has permissions, avoid filling
|
||||
// the file with zeroes, but just fill it with
|
||||
// garbage instead
|
||||
SetFileValidData(m_file_handle, offs.QuadPart);
|
||||
}
|
||||
}
|
||||
|
||||
if (offs.QuadPart != s)
|
||||
{
|
||||
// if the user has permissions, avoid filling
|
||||
// the file with zeroes, but just fill it with
|
||||
// garbage instead
|
||||
set_file_valid_data(m_file_handle, s);
|
||||
}
|
||||
}
|
||||
#else // NON-WINDOWS
|
||||
|
|
Loading…
Reference in New Issue