WIP fix download manager on windows
All checks were successful
/ build (pull_request) Successful in 12m50s
All checks were successful
/ build (pull_request) Successful in 12m50s
This commit is contained in:
parent
53a758688e
commit
aaff53e0f2
2 changed files with 63 additions and 44 deletions
|
@ -13,66 +13,78 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <winerror.h>
|
||||
#include <shellapi.h>
|
||||
#include <cerrno>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
static char *getdir(const char *path)
|
||||
{
|
||||
/* SHFileOperation requires a double null-terminated string. */
|
||||
static const char end[] = {'\0', '\0'};
|
||||
size_t sz = strlen(path) + sizeof end;
|
||||
char *ret = static_cast<char *>(malloc(sz));
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno));
|
||||
goto failure;
|
||||
}
|
||||
|
||||
strcpy(ret, path);
|
||||
ret[sz - 1] = '\0';
|
||||
return ret;
|
||||
|
||||
failure:
|
||||
free(ret);
|
||||
return nullptr;
|
||||
}
|
||||
#include <string>
|
||||
|
||||
int portability::rmdir_r(const char *path)
|
||||
{
|
||||
int ret = -1, res;
|
||||
char *dir = getdir(path);
|
||||
SHFILEOPSTRUCT op = {0};
|
||||
int ret = -1;
|
||||
_finddata_t fd;
|
||||
std::string wildcard_s = std::string(path) + "/*.*";
|
||||
const char *wildcard = wildcard_s.c_str();
|
||||
intptr_t h = _findfirst(wildcard, &fd);
|
||||
|
||||
if (!dir)
|
||||
if (h < 0 && errno != ENOENT)
|
||||
{
|
||||
fprintf(stderr, "%s: getdir failed\n", __func__);
|
||||
fprintf(stderr, "_findfirst %s: %s\n", wildcard, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
op.wFunc = FO_DELETE;
|
||||
op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
|
||||
op.lpszProgressTitle = "";
|
||||
op.pFrom = dir;
|
||||
for (;;)
|
||||
{
|
||||
if (*fd.name && strcmp(fd.name, ".") && strcmp(fd.name, ".."))
|
||||
{
|
||||
std::string entry_s = std::string(path) + "/" + fd.name;
|
||||
const char *entry = entry_s.c_str();
|
||||
|
||||
if ((res = SHFileOperation(&op)))
|
||||
{
|
||||
fprintf(stderr, "%s: SHFileOperation failed with %#x\n", __func__, res);
|
||||
goto end;
|
||||
}
|
||||
else if (op.fAnyOperationsAborted)
|
||||
{
|
||||
fprintf(stderr, "%s: operation aborted\n", __func__);
|
||||
goto end;
|
||||
if (fd.attrib & _A_SUBDIR)
|
||||
{
|
||||
if ((ret = rmdir_r(entry)))
|
||||
goto end;
|
||||
else if (!RemoveDirectoryA(entry))
|
||||
{
|
||||
fprintf(stderr, "RemoveDirectoryA %s: %#jx\n",
|
||||
entry, (intmax_t)GetLastError());
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else if (remove(entry))
|
||||
{
|
||||
fprintf(stderr, "remove(3) %s: %s\n", entry, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (_findnext(h, &fd))
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
break;
|
||||
|
||||
fprintf(stderr, "_findnext %s: %s\n", path, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
free(dir);
|
||||
|
||||
if (h >= 0 && _findclose(h))
|
||||
{
|
||||
fprintf(stderr, "_findclose %s: %s\n", path, strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
else if (!ret && !RemoveDirectoryA(path)
|
||||
&& GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
fprintf(stderr, "RemoveDirectoryA %s: %s\n", path, strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ end:
|
|||
|
||||
int unzip::extract(const std::string &path) const
|
||||
{
|
||||
std::ofstream out(path);
|
||||
std::ofstream out(path, std::ios::binary);
|
||||
int ret = -1, error = unzOpenCurrentFile(f);
|
||||
|
||||
if (error)
|
||||
|
@ -87,7 +87,7 @@ int unzip::extract(const std::string &path) const
|
|||
|
||||
if (!n)
|
||||
break;
|
||||
if (n < 0)
|
||||
else if (n < 0)
|
||||
{
|
||||
GfLogError("%s: unzReadCurrentFile %s failed with %d\n",
|
||||
src.c_str(), path.c_str(), n);
|
||||
|
@ -97,6 +97,13 @@ int unzip::extract(const std::string &path) const
|
|||
try
|
||||
{
|
||||
out.write(buf, n);
|
||||
out.flush();
|
||||
|
||||
if (!out.good())
|
||||
{
|
||||
GfLogError("Failed to write %d bytes\n", n);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch (const std::ios_base::failure &failure)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue