PDB downloader: workaround MS server bug Fix #8848
This commit is contained in:
parent
d9376abbf2
commit
6f53a6a69f
|
@ -63,4 +63,6 @@ Extracting cabinet: /home/inisider/Downloads/libs/user32.pd_
|
|||
extracting /home/inisider/Downloads/libs/user32.pdb
|
||||
All done, no errors.
|
||||
````
|
||||
To use the PDB downloader in unix like systems need to setup curl and cabextract, and for Windows just curl
|
||||
The following dependencies are required for PDB downloader:
|
||||
* curl
|
||||
* cabextract (non-Windows only, optional)
|
||||
|
|
|
@ -5,17 +5,24 @@
|
|||
#include <r_core.h>
|
||||
#include "pdb_downloader.h"
|
||||
|
||||
static bool checkPrograms () {
|
||||
static bool checkExtract() {
|
||||
#if __WINDOWS__ && !__CYGWIN__
|
||||
const char nul[] = "nul";
|
||||
if (r_sys_cmd ("expand -? >nul") != 0) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
const char nul[] = "/dev/null";
|
||||
if (r_sys_cmd ("cabextract -v > /dev/null") != 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool checkCurl() {
|
||||
#if __WINDOWS__ && !__CYGWIN__
|
||||
static const char nul[] = "nul";
|
||||
#else
|
||||
const char nul[] = "/dev/null";
|
||||
#endif
|
||||
if (r_sys_cmdf ("curl --version > %s", nul) != 0) {
|
||||
return false;
|
||||
|
@ -29,74 +36,98 @@ static int download(struct SPDBDownloader *pd) {
|
|||
char *extractor_cmd = NULL;
|
||||
char *abspath_to_archive = NULL;
|
||||
char *archive_name = NULL;
|
||||
size_t archive_name_len = 0;
|
||||
const char *basepath = ".";
|
||||
int res = 1, archive_name_len = 0;
|
||||
int res = 0;
|
||||
int cmd_ret;
|
||||
if (!opt->dbg_file || !*opt->dbg_file) {
|
||||
// no pdb debug file
|
||||
return 0;
|
||||
}
|
||||
if (!checkPrograms ()) {
|
||||
if (!checkCurl ()) {
|
||||
return 0;
|
||||
}
|
||||
// dbg_file len is > 0
|
||||
archive_name_len = strlen (opt->dbg_file);
|
||||
archive_name = malloc (archive_name_len+1);
|
||||
archive_name = malloc (archive_name_len + 1);
|
||||
if (!archive_name) {
|
||||
return 0;
|
||||
}
|
||||
memcpy (archive_name, opt->dbg_file, archive_name_len+1);
|
||||
memcpy (archive_name, opt->dbg_file, archive_name_len + 1);
|
||||
archive_name[archive_name_len - 1] = '_';
|
||||
if (opt->path && *opt->path) {
|
||||
basepath = opt->path;
|
||||
}
|
||||
abspath_to_archive = r_str_newf ("%s%s%s", basepath,
|
||||
R_SYS_DIR, archive_name);
|
||||
curl_cmd = r_str_newf ("curl -sA \"%s\" \"%s/%s/%s/%s\" -o \"%s\"",
|
||||
opt->user_agent,
|
||||
opt->symbol_server,
|
||||
opt->dbg_file,
|
||||
opt->guid,
|
||||
archive_name,
|
||||
abspath_to_archive);
|
||||
// eprintf ("%s\n", curl_cmd);
|
||||
if (checkExtract () || opt->extract == 0) {
|
||||
res = 1;
|
||||
abspath_to_archive = r_str_newf ("%s%s%s", basepath,
|
||||
R_SYS_DIR, archive_name);
|
||||
curl_cmd = r_str_newf ("curl -sfA \"%s\" \"%s/%s/%s/%s\" -o \"%s\"",
|
||||
opt->user_agent,
|
||||
opt->symbol_server,
|
||||
opt->dbg_file,
|
||||
opt->guid,
|
||||
archive_name,
|
||||
abspath_to_archive);
|
||||
#if __WINDOWS__ && !__CYGWIN__
|
||||
const char *cabextractor = "expand";
|
||||
const char *format = "%s %s %s";
|
||||
char *abspath_to_file = strdup (abspath_to_archive);
|
||||
if (abspath_to_file) {
|
||||
int abspath_to_archive_len = archive_name_len + strlen (basepath) + 2;
|
||||
abspath_to_file[abspath_to_archive_len - 2] = 'b';
|
||||
// extact_cmd -> %1 %2 %3
|
||||
// %1 - 'expand'
|
||||
// %2 - absolute path to archive
|
||||
// %3 - absolute path to file that will be dearchive
|
||||
extractor_cmd = r_str_newf (format, cabextractor,
|
||||
abspath_to_archive, abspath_to_file);
|
||||
}
|
||||
const char *cabextractor = "expand";
|
||||
const char *format = "%s %s %s";
|
||||
char *abspath_to_file = strdup (abspath_to_archive);
|
||||
if (abspath_to_file) {
|
||||
int abspath_to_archive_len = archive_name_len + strlen (basepath) + 2;
|
||||
abspath_to_file[abspath_to_archive_len - 2] = 'b';
|
||||
// extractor_cmd -> %1 %2 %3
|
||||
// %1 - 'expand'
|
||||
// %2 - absolute path to archive
|
||||
// %3 - absolute path to file that will be dearchive
|
||||
extractor_cmd = r_str_newf (format, cabextractor,
|
||||
abspath_to_archive, abspath_to_file);
|
||||
}
|
||||
#else
|
||||
const char *cabextractor = "cabextract";
|
||||
const char *format = "%s -d \"%s\" \"%s\"";
|
||||
// cabextract -d %1 %2
|
||||
// %1 - path to directory where to extract all files from cab arhcive
|
||||
// %2 - absolute path to cab archive
|
||||
extractor_cmd = r_str_newf (format,
|
||||
cabextractor, basepath, abspath_to_archive);
|
||||
const char *cabextractor = "cabextract";
|
||||
const char *format = "%s -d \"%s\" \"%s\"";
|
||||
// cabextract -d %1 %2
|
||||
// %1 - path to directory where to extract all files from cab archive
|
||||
// %2 - absolute path to cab archive
|
||||
extractor_cmd = r_str_newf (format,
|
||||
cabextractor, basepath, abspath_to_archive);
|
||||
#endif
|
||||
if (r_sys_cmd (curl_cmd) != 0) {
|
||||
eprintf("curl has not been finish with success\n");
|
||||
res = 0;
|
||||
}
|
||||
if (opt->extract > 0) {
|
||||
if (res && (r_sys_cmd (extractor_cmd) != 0)) {
|
||||
eprintf ("cab extrach has not been finished with success\n");
|
||||
if ((cmd_ret = r_sys_cmd (curl_cmd) != 0)) {
|
||||
eprintf("curl exited with error %d\n", cmd_ret);
|
||||
res = 0;
|
||||
}
|
||||
r_file_rm (abspath_to_archive);
|
||||
if (opt->extract > 0) {
|
||||
if (res && ((cmd_ret = r_sys_cmd (extractor_cmd)) != 0)) {
|
||||
eprintf ("cab extractor exited with error %d\n", cmd_ret);
|
||||
res = 0;
|
||||
}
|
||||
r_file_rm (abspath_to_archive);
|
||||
}
|
||||
R_FREE (curl_cmd);
|
||||
R_FREE (abspath_to_archive);
|
||||
}
|
||||
if (res == 0) {
|
||||
eprintf ("Falling back to uncompressed pdb\n");
|
||||
res = 1;
|
||||
archive_name[archive_name_len - 1] = 'b';
|
||||
abspath_to_archive = r_str_newf ("%s%s%s", basepath,
|
||||
R_SYS_DIR, archive_name);
|
||||
curl_cmd = r_str_newf ("curl -sfA \"%s\" \"%s/%s/%s/%s\" -o \"%s\"",
|
||||
opt->user_agent,
|
||||
opt->symbol_server,
|
||||
opt->dbg_file,
|
||||
opt->guid,
|
||||
archive_name,
|
||||
abspath_to_archive);
|
||||
if ((cmd_ret = r_sys_cmd (curl_cmd) != 0)) {
|
||||
eprintf("curl exited with error %d\n", cmd_ret);
|
||||
res = 0;
|
||||
}
|
||||
R_FREE (curl_cmd);
|
||||
R_FREE (abspath_to_archive);
|
||||
}
|
||||
R_FREE (archive_name);
|
||||
R_FREE (curl_cmd);
|
||||
R_FREE (extractor_cmd);
|
||||
R_FREE (abspath_to_archive);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -124,7 +155,7 @@ void deinit_pdb_downloader(SPDBDownloader *pd) {
|
|||
pd->download = 0;
|
||||
}
|
||||
|
||||
int r_bin_pdb_download(RCore* core, int isradjson, int* actions_done, SPDBOptions* options) {
|
||||
int r_bin_pdb_download(RCore *core, int isradjson, int *actions_done, SPDBOptions *options) {
|
||||
int ret;
|
||||
char *path;
|
||||
SPDBDownloaderOpt opt;
|
||||
|
@ -154,10 +185,10 @@ int r_bin_pdb_download(RCore* core, int isradjson, int* actions_done, SPDBOption
|
|||
ret = pdb_downloader.download (&pdb_downloader);
|
||||
if (isradjson && actions_done) {
|
||||
printf ("%s\"pdb\":{\"file\":\"%s\",\"download\":%s}",
|
||||
*actions_done ? "," : "", opt.dbg_file, ret ? "true" : "false");
|
||||
*actions_done ? "," : "", opt.dbg_file, ret ? "true" : "false");
|
||||
} else {
|
||||
printf ("PDB \"%s\" download %s\n",
|
||||
opt.dbg_file, ret ? "success" : "failed");
|
||||
opt.dbg_file, ret ? "success" : "failed");
|
||||
}
|
||||
if (actions_done) {
|
||||
(*actions_done)++;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef PDB_DOWNLOADER_H
|
||||
#define PDB_DOWNLOADER_H
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_core.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -9,7 +11,7 @@ extern "C" {
|
|||
typedef struct SPDBOptions {
|
||||
char *user_agent;
|
||||
char *symbol_server;
|
||||
int extract;
|
||||
ut64 extract;
|
||||
} SPDBOptions;
|
||||
|
||||
typedef struct SPDBDownloaderOpt {
|
||||
|
@ -18,7 +20,7 @@ typedef struct SPDBDownloaderOpt {
|
|||
char *dbg_file;
|
||||
char *guid;
|
||||
char *path;
|
||||
int extract;
|
||||
ut64 extract;
|
||||
} SPDBDownloaderOpt;
|
||||
|
||||
typedef struct SPDBDownloader {
|
||||
|
@ -42,7 +44,7 @@ void deinit_pdb_downloader(SPDBDownloader *pdb_downloader);
|
|||
|
||||
///
|
||||
/// \brief download PDB file
|
||||
R_API int r_bin_pdb_download (RCore* core, int isradjson, int* actions_done, SPDBOptions* options);
|
||||
R_API int r_bin_pdb_download(RCore *core, int isradjson, int *actions_done, SPDBOptions *options);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue