code_twain/sln/hgsetver/hgsetver.cpp

1301 lines
41 KiB
C++

// hgsetver.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <Windows.h>
#include <iostream>
#include <file/file_util.h>
#include <process/process_util.h>
#include <coding/coding.h>
#include <time.h>
#pragma warning(disable: 4996)
enum oem
{
OEM_NOT = -1,
OEM_NONE = 0,
OEM_HANWANG,
OEM_LISICHENG,
OEM_CANGTIAN,
};
#define GET_ENUM_NAME_W(e, v) \
if(e == v) return L###e;
#define GET_ENUM_VALUE_W(e, v) \
if(L###e == v) return e;
static bool set_ver(const wchar_t* file, oem vendor, bool x86, int pid, int main = 0, bool twain_only = false, bool nov = false);
int main()
{
// hgsetver "brand.h" x86|x64 oem
process_util::ICmd* cmd = process_util::create_command_line();
if (cmd->count() < 2)
{
std::wstring pe(cmd->main_pe());
size_t pos = pe.rfind(L'\\');
if (pos++ != std::wstring::npos)
pe.erase(0, pos);
pos = pe.rfind(L'.');
if (pos != std::wstring::npos)
pe.erase(pos);
std::wcout << L"Usage: " << pe.c_str() << L"<path-file> [-pid product_id lead with '0x'] [-main main-ver, all version will be omitted if this was not given or be ZERO] [-cpu x86|x64] [-oem hw|lsc] [-only-twain change twain project only] [-nov not change version]\r\n";
cmd->release();
DWORD pid = process_util::get_parent_process(GetCurrentProcessId());
wchar_t path[MAX_PATH] = { 0 }, * n = NULL;
process_util::get_process_name(pid, path);
n = wcsrchr(path, L'\\');
if (n++ == NULL)
n = path;
if(wcsicmp(n, L"explorer.exe") == 0)
getchar();
return -1;
}
{
wchar_t* buf = NULL;
int len = 0;
cmd->to_command_line(buf, &len);
buf = new wchar_t[len + 4];
cmd->to_command_line(buf, &len);
buf[len] = 0;
std::wcout << buf << std::endl;
delete[] buf;
}
oem vendor = OEM_NONE;
bool x86 = true, twain_only = cmd->has(L"-only-twain"), nov = cmd->has(L"-nov");
int main = 0, pid = 0x100;
if (cmd->parameter(L"-main"))
{
main = _wtoi(cmd->parameter(L"-main"));
if (main <= 0)
{
main = 0;
std::wcout << L" Main version '" << cmd->parameter(L"-main") << L"' is invalid, no changes to it.\r\n";
}
}
if (cmd->parameter(L"-pid"))
{
pid = coding_util::pick_integer(cmd->parameter(L"-pid"));
}
if (cmd->parameter(L"-cpu"))
x86 = wcsicmp(cmd->parameter(L"-cpu"), L"x64") != 0;
if (cmd->parameter(L"-oem"))
{
if (wcsicmp(cmd->parameter(L"-oem"), L"hw") == 0)
vendor = OEM_HANWANG;
else if (wcsicmp(cmd->parameter(L"-oem"), L"lsc") == 0)
vendor = OEM_LISICHENG;
else if (wcsicmp(cmd->parameter(L"-oem"), L"cts") == 0)
vendor = OEM_CANGTIAN;
else
std::wcout << L" OEM '" << cmd->parameter(L"-oem") << L"' is not supported! set as OEM_NONE.\r\n";
}
std::wstring file(cmd->parameter(1));
STR_TO_ABSOLUTE_PATH(file);
set_ver(file.c_str(), vendor, x86, pid, main, twain_only, nov);
cmd->release();
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
static INTER_MODULE_CALLBACK(got_str)
{
*((std::string*)param) += std::string(data, len);
return inter_module_data::SET_RESULT_CONTINUE;
}
static INTER_MODULE_CALLBACK(got_wstr)
{
*((std::wstring*)param) += std::wstring((wchar_t*)data, len / 2);
return inter_module_data::SET_RESULT_CONTINUE;
}
enum bom
{
BOM_ANSI = 0,
BOM_UTF8,
BOM_UNICODE,
};
static std::wstring oem_str(oem o)
{
GET_ENUM_NAME_W(OEM_NONE, o);
GET_ENUM_NAME_W(OEM_HANWANG, o);
GET_ENUM_NAME_W(OEM_LISICHENG, o);
GET_ENUM_NAME_W(OEM_CANGTIAN, o);
}
static oem from_str(const wchar_t* str)
{
std::wstring s(str);
GET_ENUM_VALUE_W(OEM_NONE, s);
GET_ENUM_VALUE_W(OEM_HANWANG, s);
GET_ENUM_VALUE_W(OEM_LISICHENG, s);
GET_ENUM_VALUE_W(OEM_CANGTIAN, s);
return OEM_NOT;
}
static int oem_code(oem o)
{
if (o == OEM_HANWANG)
return 16;
else if (o == OEM_LISICHENG)
return 14;
else if (o == OEM_CANGTIAN)
return 18;
else
return 10;
}
static oem oem_from_code(int code)
{
if (code == 16)
return OEM_HANWANG;
else if (code == 14)
return OEM_LISICHENG;
else if (code == 18)
return OEM_CANGTIAN;
else
return OEM_NONE;
}
static int find_line(std::wstring& brand, const wchar_t* line_tag, int* end)
{
int bgn = 0, next = 0, start = -1;
std::wstring line(L"");
do
{
bgn += next;
line = L"";
coding_util::pick_line(brand.c_str() + bgn, got_wstr, &line, &next);
if (line.find(line_tag) != std::wstring::npos)
{
start = bgn;
if (end)
*end = bgn + next;
break;
}
} while (next > 0);
return start;
}
static bool change_oem(std::wstring& brand, oem o)
{
std::wstring oem_def(L"#define " + oem_str(o) + L"\r\n");
int end = -1,
bgn = find_line(brand, L"#define OEM_", &end);
if (bgn >= 0)
{
brand.replace(bgn, end - bgn, oem_def);
}
else
{
bgn = find_line(brand, L"#define ", &end);
if(bgn >= 0)
brand.replace(bgn, end - bgn, oem_def + L"\r\n");
else
std::wcout << L" Modify vendor to '" << oem_def.c_str() << L"' failed.\r\n";
}
return bgn >= 0;
}
static bool change_main(std::wstring& brand, int main)
{
wchar_t ver[20] = { 0 };
int next = 0,
bgn = find_line(brand, L"#define VERSION_MAIN", &next);
bool ret = false;
swprintf_s(ver, _countof(ver) - 1, L"%d\r\n", main);
if (bgn >= 0)
{
bgn += lstrlenW(L"#define VERSION_MAIN");
while (brand[bgn] == L'\t' || brand[bgn] == L' ')
bgn++;
if (brand[bgn] >= L'0' && brand[bgn] <= L'9')
{
brand.replace(bgn, next - bgn, ver);
ret = true;
}
}
if (!ret)
std::wcout << L" change VERSION_MAIN to '" << ver << L"' failed.\r\n";
return ret;
}
static bool change_sub(std::wstring& brand, int sub, int main)
{
wchar_t ver[20] = { 0 };
int next = 0,
bgn = find_line(brand, L"#define VERSION_SUB", &next);
bool ret = false;
if (bgn >= 0)
{
bgn += lstrlenW(L"#define VERSION_SUB");
while (brand[bgn] == L'\t' || brand[bgn] == L' ')
bgn++;
if (brand[bgn] >= L'0' && brand[bgn] <= L'9')
{
sub = _wtoi(brand.c_str() + bgn);
//sub += _wtoi(brand.c_str() + bgn) % 100;
//if(main)
sub++;
swprintf_s(ver, _countof(ver) - 1, L"%d\r\n", sub);
brand.replace(bgn, next - bgn, ver);
ret = true;
}
}
if (!ret)
std::wcout << L" change VERSION_SUB to '" << ver << L"+' failed.\r\n";
return ret;
}
static bool change_build(std::wstring& brand, int build)
{
wchar_t ver[20] = { 0 };
int next = 0,
bgn = find_line(brand, L"#define VERSION_BUILD1", &next);
bool ret = false;
swprintf_s(ver, _countof(ver) - 1, L"%d\r\n", build);
if (bgn >= 0)
{
bgn += lstrlenW(L"#define VERSION_BUILD1");
while (brand[bgn] == L'\t' || brand[bgn] == L' ')
bgn++;
if (brand[bgn] >= L'0' && brand[bgn] <= L'9')
{
brand.replace(bgn, next - bgn, ver);
ret = true;
}
}
if (!ret)
std::wcout << L" change VERSION_BUILD1 to '" << ver << L"+' failed.\r\n";
return ret;
}
static bool change_build(std::wstring& brand, oem o, bool x86)
{
wchar_t ver[20] = { 0 };
int next = 0,
bgn = find_line(brand, L"#define VERSION_BUILD1", &next),
build = oem_code(o);
bool ret = false;
build *= 10;
build += x86 ? 0 : 1;
build *= 100;
swprintf_s(ver, _countof(ver) - 1, L"%d\r\n", build);
if (bgn >= 0)
{
bgn += lstrlenW(L"#define VERSION_BUILD1");
while (brand[bgn] == L'\t' || brand[bgn] == L' ')
bgn++;
if (brand[bgn] >= L'0' && brand[bgn] <= L'9')
{
brand.replace(bgn, next - bgn, ver);
ret = true;
}
}
if (!ret)
std::wcout << L" change VERSION_BUILD1 to '" << ver << L"+' failed.\r\n";
return ret;
}
static bool change_patch(std::wstring& brand, int patch)
{
wchar_t ver[20] = { 0 };
int next = 0,
bgn = find_line(brand, L"#define VERSION_PATCH", &next);
bool ret = false;
swprintf_s(ver, _countof(ver) - 1, L"%d\r\n", patch);
if (bgn >= 0)
{
bgn += lstrlenW(L"#define VERSION_PATCH");
while (brand[bgn] == L'\t' || brand[bgn] == L' ')
bgn++;
if (brand[bgn] >= L'0' && brand[bgn] <= L'9')
{
brand.replace(bgn, next - bgn, ver);
ret = true;
}
}
if (!ret)
std::wcout << L" change VERSION_PATCH to '" << ver << L"+' failed.\r\n";
return ret;
}
static bool change_product_id(std::wstring& brand, int pid)
{
wchar_t ver[20] = { 0 };
int next = 0,
bgn = find_line(brand, L"#define PRODUCT_ID", &next);
bool ret = false;
swprintf_s(ver, _countof(ver) - 1, L"%x\r\n", pid);
if (bgn >= 0)
{
bgn += lstrlenW(L"#define PRODUCT_ID");
while (brand[bgn] == L'\t' || brand[bgn] == L' ')
bgn++;
if ((brand[bgn] >= L'0' && brand[bgn] <= L'9') ||
(brand[bgn] >= L'a' && brand[bgn] <= L'f') ||
(brand[bgn] >= L'A' && brand[bgn] <= L'F'))
{
brand.replace(bgn, next - bgn, ver);
ret = true;
}
}
if (!ret)
std::wcout << L" change PRODUCT_ID to '" << ver << L"+' failed.\r\n";
return ret;
}
namespace rc
{
typedef struct _change_param
{
oem o;
int product_id;
int ver1;
int ver2;
bool change_out_dir;
}CHGPARAM, *LPCHGPARAM;
bool __stdcall change_out_dir(std::wstring& cont, oem o);
static std::wstring load_file(const wchar_t* file, bom* bm)
{
std::string cont("");
std::wstring unic(L"");
file_util::load_file(file, got_str, &cont);
if (cont.length() > 3)
{
if (bm)
{
if (coding_util::bom::is_unicode(cont.c_str(), NULL))
*bm = BOM_UNICODE;
else if (coding_util::bom::is_utf8(cont.c_str()))
*bm = BOM_UTF8;
else
*bm = BOM_ANSI;
}
coding_util::bom::to_unicode(cont.c_str(), cont.length(), got_wstr, &unic);
}
return unic;
}
static void trim_left(std::wstring& str)
{
int bgn = 0;
while (str[bgn] == L'\t' || str[bgn] == L' ')
bgn++;
if (bgn)
str.erase(0, bgn);
}
static bool get_version_from_file(const wchar_t* file, int* v1, int* v2, int* v3, int* v4, std::wstring* company_name, std::wstring* short_company_name, std::wstring* vendor_name)
{
std::wstring cont(load_file(file, NULL)), line(L""), tag(L"#define VERSION_MAIN");
int end = -1, bgn = -1;
oem o = OEM_NONE;
if (v1)
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
bgn = cont.find(tag, bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
*v1 = _wtoi(cont.c_str() + bgn);
}
tag = L"#define VERSION_SUB";
if (v2)
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
bgn = cont.find(tag, bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
*v2 = _wtoi(cont.c_str() + bgn);
}
tag = L"#define VERSION_BUILD1";
if (v3)
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
bgn = cont.find(tag, bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
*v3 = _wtoi(cont.c_str() + bgn);
}
tag = L"#define VERSION_PATCH";
if (v4)
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
bgn = cont.find(tag, bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
*v4 = _wtoi(cont.c_str() + bgn);
}
tag = L"#define OEM_";
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
line = cont.substr(bgn, end - bgn);
if (line.find(oem_str(OEM_HANWANG)) != std::wstring::npos)
o = OEM_HANWANG;
else if (line.find(oem_str(OEM_LISICHENG)) != std::wstring::npos)
o = OEM_LISICHENG;
else if (line.find(oem_str(OEM_CANGTIAN)) != std::wstring::npos)
o = OEM_CANGTIAN;
}
bool found = false, is_oem = false;
std::vector<bool> embed;
bgn = end = 0;
do
{
bgn += end;
line = L"";
coding_util::pick_line(cont.c_str() + bgn, got_wstr, &line, &end);
trim_left(line);
if (line.find(L"#if") == 0)
{
if (line.find(L"#ifdef ") == 0)
{
line.erase(0, lstrlenW(L"#ifdef "));
trim_left(line);
}
else if (line.find(L"#if ") == 0)
{
line.erase(0, 4);
trim_left(line);
if (line.find(L"defined(") == 0)
{
line.erase(0, lstrlenW(L"defined("));
trim_left(line);
size_t pos = line.find(L")");
if (pos != std::wstring::npos)
line.erase(pos);
}
}
if (line == oem_str(o))
{
found = true;
cont.erase(0, bgn);
// end -= bgn;
bgn = 0;
embed.push_back(true);
}
else // if (!is_oem)
{
is_oem = from_str(line.c_str()) != OEM_NOT;
embed.push_back(is_oem);
}
}
else if (line.find(L"#el") == 0)
{
if (found && embed.size() && embed[embed.size() - 1])
{
cont.erase(bgn + end);
break;
}
else if (line.find(L"#elif ") == 0)
{
if (embed.size() && embed[embed.size() - 1])
{
line.erase(0, lstrlenW(L"elif "));
trim_left(line);
if (line.find(L"defined(") == 0)
{
line.erase(0, lstrlenW(L"defined("));
trim_left(line);
size_t pos = line.find(L")");
if (pos != std::wstring::npos)
line.erase(pos);
if (line == oem_str(o))
{
found = true;
cont.erase(0, bgn);
// end -= bgn;
bgn = 0;
}
//else // if (!is_oem)
//{
// is_oem = from_str(line.c_str()) != OEM_NOT;
// embed.push_back(is_oem);
//}
}
}
}
else if (line.find(L"#else") == 0)
{
if (embed.size() && embed[embed.size() - 1])
{
found = true;
cont.erase(0, bgn);
// end -= bgn;
bgn = 0;
}
}
}
else if (line.find(L"#endif") == 0)
{
bool over = embed.size() ? embed[embed.size() - 1] : true;
embed.pop_back();
if (found && over)
{
cont.erase(bgn + end);
break;
}
}
} while (end);
if (!found)
return false;
//
bgn = end = 0;
do
{
bgn += end;
line = L"";
coding_util::pick_line(cont.c_str() + bgn, got_wstr, &line, &end);
trim_left(line);
if (line.find(L"#define OEM_NAME") == 0)
{
line.erase(0, lstrlenW(L"#define OEM_NAME"));
trim_left(line);
size_t pos = line.find(L"\"");
if (pos++ != std::wstring::npos)
{
line.erase(0, pos);
pos = line.find(L"\"");
if(pos != std::wstring::npos)
line.erase(pos);
if(company_name)
coding_util::from_web_style(line.c_str(), got_wstr, company_name);
}
}
else if (line.find(L"#define OEM_SHORT_NAME") == 0)
{
line.erase(0, lstrlenW(L"#define OEM_SHORT_NAME"));
trim_left(line);
size_t pos = line.find(L"\"");
if (pos++ != std::wstring::npos)
{
line.erase(0, pos);
pos = line.find(L"\"");
if(pos != std::wstring::npos)
line.erase(pos);
if(short_company_name)
coding_util::from_web_style(line.c_str(), got_wstr, short_company_name);
}
}
else if (line.find(L"#define PRODUCT_VENDOR") == 0)
{
line.erase(0, lstrlenW(L"#define PRODUCT_VENDOR"));
trim_left(line);
size_t pos = line.find(L"\"");
if (pos++ != std::wstring::npos)
{
line.erase(0, pos);
pos = line.find(L"\"");
if(pos != std::wstring::npos)
line.erase(pos);
if(vendor_name)
coding_util::from_web_style(line.c_str(), got_wstr, vendor_name);
}
}
} while (end);
}
static bool change_file(const wchar_t* file, LPCHGPARAM param, bool(__stdcall* modify)(std::wstring& cont, LPCHGPARAM param))
{
bom bm = BOM_UTF8;
std::wstring cont(load_file(file, &bm));
bool ret = modify(cont, param);
if (ret)
{
std::string bomstr("");
if (bm == BOM_UNICODE)
coding_util::bom::from_unicode(cont.c_str(), cont.length() * 2, got_str, &bomstr);
else if (bm == BOM_UTF8)
{
std::string utf8("");
coding_util::unicode_2_utf8(cont.c_str(), got_str, &utf8);
coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), got_str, &bomstr);
}
else
coding_util::unicode_2_ansi(cont.c_str(), got_str, &bomstr);
file_util::save_2_file(bomstr.c_str(), bomstr.length(), file);
}
return ret;
}
static void change_post_command_dir(std::wstring& cont, const std::wstring& o)
{
std::wstring target(L"\\$(Configuration)");
size_t pos = cont.find(target);
if (pos != std::wstring::npos)
{
pos += target.length();
size_t end = cont.find(L"\"", pos);
if (cont.find(L"\r\n", pos) < end)
end = cont.find(L"\r\n", pos);
if (end == std::wstring::npos)
end = cont.length();
cont.replace(pos, end - pos, L"\\..\\oem\\" + o);
}
}
static void change_post_lib_dir(std::wstring& cont, const std::wstring& o)
{
std::wstring target(L"\\OEM");
size_t pos = cont.find(target);
if (pos != std::wstring::npos)
{
pos += target.length();
size_t end = cont.find(L";", pos);
if (cont.find(L"</", pos) < end)
end = cont.find(L"</", pos);
if (end == std::wstring::npos)
end = cont.length();
cont.replace(pos, end - pos, L"\\" + o);
}
}
bool __stdcall change_lib_outdir(std::wstring& cont, oem o)
{
std::wstring first(L"<Command>"), end(L"</Command>"), post(L""), os(L"huagao");
size_t bgn = cont.find(first), len = cont.find(end);
if (o == OEM_HANWANG)
os = L"hanvon";
else if (o == OEM_LISICHENG)
os = L"lanxum";
else if (o == OEM_CANGTIAN)
os = L"cumtenn";
while (len > bgn)
{
bgn += first.length();
len -= bgn;
post = cont.substr(bgn, len);
change_post_command_dir(post, os);
cont.replace(bgn, len, post);
bgn += post.length() + end.length();
bgn = cont.find(first, bgn);
len = cont.find(end, bgn);
}
return true;
}
bool __stdcall change_lib_indir(std::wstring& cont, oem o)
{
std::wstring first(L"<LibraryPath>"), end(L"</LibraryPath>"), post(L""), os(L"huagao");
size_t bgn = cont.find(first), len = cont.find(end);
if (o == OEM_HANWANG)
os = L"hanvon";
else if (o == OEM_LISICHENG)
os = L"lanxum";
else if (o == OEM_CANGTIAN)
os = L"cumtenn";
while (len > bgn)
{
bgn += first.length();
len -= bgn;
post = cont.substr(bgn, len);
change_post_lib_dir(post, os);
cont.replace(bgn, len, post);
bgn += post.length() + end.length();
bgn = cont.find(first, bgn);
len = cont.find(end, bgn);
}
return true;
}
bool set_rc_ver(const wchar_t* file, int v_1, int v_2, int v_3, int v_4, const wchar_t* company_name, const wchar_t* short_company_name, const wchar_t* vender)
{
bom bm = BOM_UTF8;
std::wstring cont(load_file(file, &bm)), tag(L"FILEVERSION "), cr(bm == BOM_ANSI ? L"(C)" : L"\u00a9");
int bgn = -1, end = -1;
wchar_t ver[80] = { 0 };
if (cont.length() < 1000)
return false;
swprintf_s(ver, _countof(ver) - 1, L"%d,%d,%d,%d\r\n", v_1, v_2, v_3, v_4);
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
bgn = cont.find(tag.c_str(), bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
cont.replace(bgn, end - bgn, ver);
}
tag = L"PRODUCTVERSION";
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
bgn = cont.find(tag.c_str(), bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
cont.replace(bgn, end - bgn, ver);
}
tag = L"VALUE \"CompanyName\",";
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
bgn = cont.find(tag.c_str(), bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
cont.replace(bgn, end - bgn, std::wstring(L"\"") + company_name + L"\"\r\n");
}
tag = L"VALUE \"FileDescription\",";
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
bgn = cont.find(tag.c_str(), bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
cont.replace(bgn, end - bgn, std::wstring(L"\"") + short_company_name + L"\u626B\u63CF\u4EEA\u5E94\u7528\u7A0B\u5E8F\"\r\n");
}
tag = L"VALUE \"FileVersion\",";
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
swprintf_s(ver, _countof(ver) - 1, L"\"%d.%d.%d.%d\"\r\n", v_1, v_2, v_3, v_4);
bgn = cont.find(tag.c_str(), bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
cont.replace(bgn, end - bgn, ver);
}
tag = L"VALUE \"LegalCopyright\",";
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
swprintf_s(ver, _countof(ver) - 1, L"\"Copyright %s %sScan %d\"\r\n", cr.c_str(), vender, v_4 / 1000 + 2000);
bgn = cont.find(tag.c_str(), bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
cont.replace(bgn, end - bgn, ver);
}
tag = L"VALUE \"ProductName\",";
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
swprintf_s(ver, _countof(ver) - 1, L"\"%sScan\"\r\n", vender);
bgn = cont.find(tag.c_str(), bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
cont.replace(bgn, end - bgn, ver);
}
tag = L"VALUE \"ProductVersion\",";
{
bgn = find_line(cont, tag.c_str(), &end);
if (bgn < 0)
return false;
swprintf_s(ver, _countof(ver) - 1, L"\"%d.%d.%d.%d\"\r\n", v_1, v_2, v_3, v_4);
bgn = cont.find(tag.c_str(), bgn);
bgn += tag.length();
while (cont[bgn] == L'\t' || cont[bgn] == L' ')
bgn++;
cont.replace(bgn, end - bgn, ver);
}
std::string bomstr("");
if (bm == BOM_UNICODE)
coding_util::bom::from_unicode(cont.c_str(), cont.length() * 2, got_str, &bomstr);
else if (bm == BOM_UTF8)
{
std::string utf8("");
coding_util::unicode_2_utf8(cont.c_str(), got_str, &utf8);
coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), got_str, &bomstr);
}
else
coding_util::unicode_2_ansi(cont.c_str(), got_str, &bomstr);
file_util::save_2_file(bomstr.c_str(), bomstr.length(), file);
return true;
}
bool change_vcxproj_predefine(const wchar_t* file, oem o)
{
bom bm = BOM_UTF8;
std::wstring cont(load_file(file, &bm)), backend(L""), lead(L"BACKEND_NAME=");
size_t pos = cont.find(lead), end = 0;
//if (pos == std::wstring::npos)
// return false;
if (cont.length() < 1000)
return false;
if (o == OEM_HANWANG)
backend = L"hw";
else if (o == OEM_LISICHENG)
backend = L"lsc";
else if (o == OEM_CANGTIAN)
backend = L"cts";
else
backend = L"hg";
backend += L"sane";
while (pos != std::wstring::npos)
{
pos += lead.length();
end = pos;
while (cont[end] != L';' && cont[end] != L'<')
end++;
cont.replace(pos, end - pos, backend);
pos += backend.length();
pos = cont.find(lead, pos);
}
pos = cont.find(L"OEM_");
while (pos != std::wstring::npos)
{
end = pos + 4;
while (cont[end] != L';' && cont[end] != L'<')
end++;
if (from_str(cont.substr(pos, end - pos).c_str()) != OEM_NOT)
{
cont.replace(pos, end - pos, oem_str(o));
end = pos + oem_str(o).length();
}
pos = cont.find(L"OEM_", end);
}
change_out_dir(cont, o);
change_lib_outdir(cont, o);
change_lib_indir(cont, o);
std::string bomstr("");
if (bm == BOM_UNICODE)
coding_util::bom::from_unicode(cont.c_str(), cont.length() * 2, got_str, &bomstr);
else if (bm == BOM_UTF8)
{
std::string utf8("");
coding_util::unicode_2_utf8(cont.c_str(), got_str, &utf8);
coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), got_str, &bomstr);
}
else
coding_util::unicode_2_ansi(cont.c_str(), got_str, &bomstr);
file_util::save_2_file(bomstr.c_str(), bomstr.length(), file);
return true;
}
bool __stdcall change_sane_def(std::wstring& cont, LPCHGPARAM param)
{
std::wstring backend(L"sane_"), prev(L"_hgsane_");
oem o = param->o;
if (o == OEM_HANWANG)
backend.insert(0, L"_hw");
else if (o == OEM_LISICHENG)
backend.insert(0, L"_lsc");
else if (o == OEM_CANGTIAN)
backend.insert(0, L"_cts");
else
backend.insert(0, L"_hg");
if (cont.find(backend) != std::wstring::npos)
return true;
if (cont.find(prev) == std::wstring::npos)
{
prev = L"_hwsane_";
if (cont.find(prev) == std::wstring::npos)
{
prev = L"_lscsane_";
if (cont.find(prev) == std::wstring::npos)
{
prev = L"_ctssane_";
if (cont.find(prev) == std::wstring::npos)
return false;
}
}
}
size_t pos = cont.find(prev);
while (pos != std::wstring::npos)
{
cont.replace(pos, prev.length(), backend);
pos += backend.length();
pos = cont.find(prev, pos);
}
return true;
}
bool __stdcall change_device_def(std::wstring& cont, LPCHGPARAM param)
{
std::wstring backend(L"_scanner_"), prev(L"hg_scanner_");
oem o = param->o;
if (o == OEM_HANWANG)
backend.insert(0, L"hw");
else if (o == OEM_LISICHENG)
backend.insert(0, L"lsc");
else if (o == OEM_CANGTIAN)
backend.insert(0, L"cts");
else
backend.insert(0, L"hg");
if (cont.find(backend) != std::wstring::npos)
return true;
if (cont.find(prev) == std::wstring::npos)
{
prev = L"hw_scanner_";
if (cont.find(prev) == std::wstring::npos)
{
prev = L"lsc_scanner_";
if (cont.find(prev) == std::wstring::npos)
{
prev = L"cts_scanner_";
if (cont.find(prev) == std::wstring::npos)
return false;
}
}
}
size_t pos = cont.find(prev);
while (pos != std::wstring::npos)
{
cont.replace(pos, prev.length(), backend);
pos += backend.length();
pos = cont.find(prev, pos);
}
return true;
}
bool __stdcall change_out_dir(std::wstring& cont, oem o)
{
bool ok = false;
std::wstring first = L"<OutDir>", last(first), target(L"$(SolutionDir)..\\..\\release\\win\\$(PlatformTarget)\\OEM\\");
int bgn = 0, end = 0;
last.insert(1, L"/");
if (o == OEM_HANWANG)
target += L"hanvon\\";
else if (o == OEM_LISICHENG)
target += L"lanxum\\";
else if (o == OEM_CANGTIAN)
target += L"cumtenn\\";
else
target += L"huagao\\";
while ((bgn = cont.find(first, bgn)) != std::wstring::npos)
{
bgn += first.length();
end = cont.find(last, bgn);
if (end != std::wstring::npos)
{
ok = true;
cont.replace(bgn, end - bgn, target);
bgn += target.length() + last.length();
}
}
return ok;
}
bool __stdcall change_output(std::wstring& cont, LPCHGPARAM param)
{
std::wstring target(L"huagao"), first(L"<TargetName>"), last(L"</TargetName>");
wchar_t tail[40] = { 0 };
size_t bgn = 0, end = -1;
bool ok = false;
swprintf_s(tail, _countof(tail) - 1, L"twain%x.ds", param->product_id);
if (param->o == OEM_HANWANG)
target = L"hanvon";
else if (param->o == OEM_LISICHENG)
target = L"lanxum";
else if (param->o == OEM_CANGTIAN)
target = L"cumtenn";
target += tail;
while ((bgn = cont.find(first, bgn)) != std::wstring::npos)
{
bgn += first.length();
end = cont.find(last, bgn);
if (end != std::wstring::npos)
{
ok = true;
cont.replace(bgn, end - bgn, target);
bgn += target.length() + last.length();
}
}
if (ok && param->change_out_dir)
ok = change_out_dir(cont, param->o);
change_lib_outdir(cont, param->o);
return ok;
}
static bool __stdcall change_linux_minver(std::wstring& cont, LPCHGPARAM param)
{
std::wstring tag(L"minver=\"");
int min_ver = param->ver2;
size_t pos = cont.find(tag), end = 0;
wchar_t v[20] = { 0 };
if (pos == std::wstring::npos)
return false;
swprintf_s(v, _countof(v) - 1, L"%d", min_ver);
pos += tag.length();
end = cont.find(L"\"", pos);
if (end == std::wstring::npos)
return false;
if (cont.find(L"\n", pos) < end)
return false;
cont.replace(pos, end - pos, v);
tag = L"mainverstr=\"s/ver_1/";
pos = cont.find(tag);
if (pos == std::wstring::npos)
return false;
pos += tag.length();
end = cont.find(L"/", pos);
if (end == std::wstring::npos)
return false;
if (cont.find(L"\n", pos) < end)
return false;
swprintf_s(v, _countof(v) - 1, L"%d", param->ver1);
cont.replace(pos, end - pos, v);
return true;
}
};
static bool set_ver(const wchar_t* file, oem vendor, bool x86, int pid, int main, bool twain_only, bool nov)
{
bool ret = false;
bom bm = BOM_UTF8;
std::string cont("");
std::wstring unic(rc::load_file(file, &bm));
if (unic.length() < 1000)
{
std::wcout << L"File length(" << unic.length() << L") is too small : " << file << std::endl;
}
else
{
time_t now = time(NULL);
struct tm* cur = localtime(&now);
int sub = x86 ? 1000 : 1100,
build = cur->tm_year + 1900,
patch = (cur->tm_mon + 1) * 1000 + cur->tm_mday * 10;
//if (vendor == OEM_HANWANG)
// patch += 6;
//else if (vendor == OEM_LISICHENG)
// patch += 7;
//else
// patch += 1;
patch = cur->tm_year % 100;
patch *= 1000;
patch += cur->tm_yday + 1;
while (change_oem(unic, vendor))
{
if (!nov)
{
if (main && !change_main(unic, main))
break;
if (!change_sub(unic, sub, main))
break;
}
if (!change_build(unic, vendor, x86))
break;
if (!change_patch(unic, patch))
break;
if (!change_product_id(unic, pid))
break;
ret = true;
break;
}
if (ret)
{
cont = "";
if (bm == BOM_UNICODE)
coding_util::bom::from_unicode(unic.c_str(), unic.length() * 2, got_str, &cont);
else if (bm == BOM_UTF8)
{
std::string utf8("");
coding_util::unicode_2_utf8(unic.c_str(), got_str, &utf8);
coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), got_str, &cont);
}
else
coding_util::unicode_2_ansi(unic.c_str(), got_str, &cont);
file_util::save_2_file(cont.c_str(), cont.length(), file);
std::wstring cn(L""), scn(L""), vs(L""), base(file), rcf(L"");
rc::CHGPARAM param;
param.o = vendor;
param.product_id = pid;
STR_PARENT_FOLDER(base);
base += L"\\..\\..\\..\\code_twain\\twain";
STR_TO_ABSOLUTE_PATH(base);
if (rc::get_version_from_file(file, &main, &sub, &build, &patch, &cn, &scn, &vs))
{
if (!twain_only)
{
rcf = base + L"\\..\\sane\\sane.vcxproj";
STR_SIMPLIFY_PATH(rcf);
if (!rc::change_vcxproj_predefine(rcf.c_str(), vendor))
std::wcout << "change predefines failed: " << rcf.c_str() << std::endl;
rcf = base + L"\\..\\sane\\sane.rc";
STR_SIMPLIFY_PATH(rcf);
if (!rc::set_rc_ver(rcf.c_str(), main, sub, build, patch, cn.c_str(), scn.c_str(), vs.c_str()))
std::wcout << "change version failed: " << rcf.c_str() << std::endl;
rcf = base + L"\\..\\sane\\sane.def";
STR_SIMPLIFY_PATH(rcf);
if (!rc::change_file(rcf.c_str(), &param, rc::change_sane_def))
std::wcout << "change exporting-definition failed: " << rcf.c_str() << std::endl;
rcf = base + L"\\..\\device\\scanner.vcxproj";
STR_SIMPLIFY_PATH(rcf);
if (!rc::change_vcxproj_predefine(rcf.c_str(), vendor))
std::wcout << "change predefines failed: " << rcf.c_str() << std::endl;
rcf = base + L"\\..\\device\\scanner.rc";
STR_SIMPLIFY_PATH(rcf);
if (!rc::set_rc_ver(rcf.c_str(), main, sub, build, patch, cn.c_str(), scn.c_str(), vs.c_str()))
std::wcout << "change version failed: " << rcf.c_str() << std::endl;
/* rcf = base + L"\\..\\device\\device.def";
STR_SIMPLIFY_PATH(rcf);
if (!rc::change_file(rcf.c_str(), &param, rc::change_device_def))
std::wcout << "change exporting-definition failed: " << rcf.c_str() << std::endl;*/
}
rcf = base + L"\\..\\twain\\twain.vcxproj";
STR_SIMPLIFY_PATH(rcf);
param.change_out_dir = !twain_only;
if (!rc::change_file(rcf.c_str(), &param, rc::change_output))
{
std::wcout << "change exporting-definition failed: " << rcf.c_str() << std::endl;
ret = false;
}
rcf = base + L"\\..\\..\\code_device\\build.sh";
STR_SIMPLIFY_PATH(rcf);
param.ver1 = main;
param.ver2 = sub;
rc::change_file(rcf.c_str(), &param, rc::change_linux_minver);
}
else
{
std::wcout << L"get version info failed\r\n";
}
}
else
std::wcout << L"change first file version failed: " << file << std::endl;
}
return ret;
}