// Douglas Thrift's Search Engine Installer // // Douglas Thrift // // Worker.cpp #include "Worker.h" Worker::Worker() { OSVERSIONINFO os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&os); nt = os.dwPlatformId == VER_PLATFORM_WIN32_NT ? true : false; if (nt) { single = false; HKEY hkey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, NULL, 0, KEY_WRITE, &hkey) != ERROR_SUCCESS) { single = true; } else { unsigned char* crackers = new unsigned char[2]; crackers[0] = '#'; crackers[1] = '\0'; if (RegSetValueEx(hkey, "cheese", 0, REG_SZ, crackers, 2) != ERROR_SUCCESS) { single = true; } RegDeleteValue(hkey, "cheese"); } RegCloseKey(hkey); } else { single = true; } templates = true; char* programs = new char[MAX_PATH + 1]; SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, programs); string search = "\\Douglas Thrift's Search Engine"; folder = programs + search; delete [] programs; } void Worker::work(HWND bar) { prepare(bar); files(bar); shortcuts(bar); registry(bar); SendMessage(GetGrandParent(bar), PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0); } void Worker::prepare(HWND bar) { SendMessage(bar, PBM_SETRANGE, 0, MAKELPARAM(0, 50)); ifstream fin("search.cgi.win"); ofstream fout("search.cgi"); string perl; { HKEY key; const string BinDir = "BinDir"; if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Perl", 0, KEY_READ, &key) == ERROR_SUCCESS) { char* value = new char[16383 + 1]; unsigned long valueSize = 16383 + 1; unsigned long type; unsigned char* data = new unsigned char[MAX_PATH + 1]; unsigned long dataSize = MAX_PATH + 1; for (unsigned long index = 0; RegEnumValue(key, index, value, &valueSize, NULL, &type, data, &dataSize) != ERROR_NO_MORE_ITEMS; index++) { if (value == BinDir && type == REG_SZ) { char* buffer = new char[dataSize + 1]; sprintf(buffer, "%s", data); perl = buffer; delete [] buffer; break; } else { valueSize = 16383 + 1; dataSize = MAX_PATH + 1; } } delete [] value; delete [] data; } else if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Perl", 0, KEY_READ, &key) == ERROR_SUCCESS) { char* value = new char[16383 + 1]; unsigned long valueSize = 16383 + 1; unsigned long type; unsigned char* data = new unsigned char[MAX_PATH + 1]; unsigned long dataSize = MAX_PATH + 1; for (unsigned long index = 0; RegEnumValue(key, index, value, &valueSize, NULL, &type, data, &dataSize) != ERROR_NO_MORE_ITEMS; index++) { if (value == BinDir && type == REG_SZ) { char* buffer = new char[dataSize + 1]; sprintf(buffer, "%s", data); perl = buffer; delete [] buffer; break; } else { valueSize = 16383 + 1; dataSize = MAX_PATH + 1; } } delete [] value; delete [] data; } RegCloseKey(key); SendMessage(bar, PBM_STEPIT, 0, 0); } CreateDirectory(folder.c_str(), NULL); do { string line; getline(fin, line); if (line == "#!C:\\Perl\\bin\\perl.exe") { if (perl != "" && line != "#!" + perl) { line = "#!" + perl; } SendMessage(bar, PBM_STEPIT, 0, 0); } else if (line.find("my $root = ") == 0) { char* buffer = new char[MAX_PATH + 1]; GetShortPathName(folder.c_str(), buffer, MAX_PATH + 1); string root = buffer; delete [] buffer; unsigned begin = 0; do { unsigned slash = root.find('\\', begin); if (slash == string::npos) break; root.insert(slash, 1, '\\'); begin = slash + 2; } while (begin < root.length()); if (line != "my $root = \"" + root + "\";") { line = "my $root = \"" + root + "\";"; } SendMessage(bar, PBM_STEPIT, 0, 0); } fout << line << (fin.good() ? "\n" : ""); } while (fin.good()); fin.close(); fout.close(); SendMessage(bar, PBM_STEPIT, 0, 0); if (nt) { fout.open("SearchPrompt.cmd"); fout << "@echo off\n" << "set PATH=" << folder << "\\bin;%PATH%\n" << "set PROMPT=[Search$SEngine]$$$S\n" << "Search -help\n"; fout.close(); } else { fout.open("SearchPrompt.bat"); char* buffer = new char[MAX_PATH + 1]; GetShortPathName(folder.c_str(), buffer, MAX_PATH + 1); fout << "@echo off\n" << "set PATH=" << buffer << "\\bin;%PATH%\n" << "set PROMPT=[Search Engine]$$ $S\n" << "Search -help\n"; delete [] buffer; fout.close(); } SendMessage(bar, PBM_STEPIT, 0, 0); } void Worker::files(HWND bar) { SendMessage(bar, PBM_SETPOS, 0, 0); SendDlgItemMessage(GetParent(bar), IDC_PROGRESS_TEXT, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)"Installing files..."); vector base; base.push_back("LICENSE"); base.push_back("LICENSE.html"); base.push_back("README"); base.push_back("README.html"); base.push_back("osi-certified-90x75.png"); base.push_back("SearchUninstaller.exe"); vector bin; bin.push_back("Search.exe"); bin.push_back(nt ? "SearchPrompt.cmd" : "SearchPrompt.bat"); bin.push_back("SearchPrompt.ico"); vector http; http.push_back("search.cgi"); http.push_back("dtse_pb.png"); vector data; if (templates) { data.push_back("header.html"); data.push_back("body.html"); data.push_back("footer.html"); data.push_back("notfound.html"); data.push_back("pages.html"); } SendMessage(bar, PBM_SETRANGE, 0, MAKELPARAM(0, (base.size() + bin.size() + http.size() + data.size()) * 10)); for (unsigned index = 0; index < base.size(); index++) { CopyFile(base[index].c_str(), (folder + '\\' + base[index]).c_str(), false); SendMessage(bar, PBM_STEPIT, 0, 0); } CreateDirectory((folder + "\\bin").c_str(), NULL); for (index = 0; index < bin.size(); index++) { CopyFile(bin[index].c_str(), (folder + "\\bin\\" + bin[index]).c_str(), false); SendMessage(bar, PBM_STEPIT, 0, 0); } CreateDirectory((folder + "\\http").c_str(), NULL); for (index = 0; index < http.size(); index++) { CopyFile(http[index].c_str(), (folder + "\\http\\" + http[index]).c_str(), false); SendMessage(bar, PBM_STEPIT, 0, 0); } CreateDirectory((folder + "\\data").c_str(), NULL); for (index = 0; index < data.size(); index++) { CopyFile(data[index].c_str(), (folder + "\\data\\" + data[index]).c_str(), false); SendMessage(bar, PBM_STEPIT, 0, 0); } } void Worker::shortcuts(HWND bar) { SendMessage(bar, PBM_SETPOS, 0, 0); SendDlgItemMessage(GetParent(bar), IDC_PROGRESS_TEXT, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)"Creating shortcuts..."); SendMessage(bar, PBM_SETRANGE, 0, MAKELPARAM(0, 40)); char* buffer = new char[MAX_PATH + 1]; SHGetFolderPath(GetGrandParent(bar), single ? CSIDL_PROGRAMS : CSIDL_COMMON_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, buffer); string programs = buffer; delete [] buffer; CreateDirectory((programs + "\\Douglas Thrift\'s Search Engine").c_str(), NULL); IPersistFile* link; IShellLink* prompt; string description = string("Command Prompt for configuring Douglas Thrif") +"t\'s Search Engine"; CoInitialize(NULL); CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&prompt); prompt->SetPath(getenv("ComSpec")); if (nt) { string arguments = "/k \"" + folder + "\\bin\\SearchPrompt.cmd\""; prompt->SetArguments(arguments.c_str()); prompt->SetDescription(description.c_str()); } else { char* buffer = new char[MAX_PATH + 1]; GetShortPathName((folder + "\\bin\\SearchPrompt.bat").c_str(), buffer, MAX_PATH + 1); string arguments = string("/e:4096 /k ") + buffer; delete [] buffer; prompt->SetArguments(arguments.c_str()); prompt->SetDescription("Search Engine Prompt"); } prompt->SetIconLocation((folder + "\\bin\\SearchPrompt.ico").c_str(), 0); prompt->SetWorkingDirectory((folder + "\\data").c_str()); prompt->QueryInterface(IID_IPersistFile, (LPVOID*)&link); unsigned short* file = new unsigned short[MAX_PATH + 1]; MultiByteToWideChar(CP_ACP, 0, (programs + "\\Douglas Thrift\'s Search Eng" + "ine\\Search Engine Prompt." + (nt ? "lnk" : "pif")).c_str(), -1, file, MAX_PATH + 1); link->Save(file, true); link->Release(); prompt->Release(); delete [] file; SendMessage(bar, PBM_STEPIT, 0, 0); IShellLink* license; description = "Douglas Thrift\'s Search Engine License"; CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&license); license->SetPath((folder + "\\LICENSE.html").c_str()); license->SetDescription(description.c_str()); license->QueryInterface(IID_IPersistFile, (LPVOID*)&link); file = new unsigned short[MAX_PATH + 1]; MultiByteToWideChar(CP_ACP, 0, (programs + "\\Douglas Thrift\'s Search Eng" + "ine\\License.lnk").c_str(), -1, file, MAX_PATH + 1); link->Save(file, true); link->Release(); license->Release(); delete [] file; SendMessage(bar, PBM_STEPIT, 0, 0); IShellLink* readme; description = "Douglas Thrift\'s Search Engine ReadMe"; CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&readme); readme->SetPath((folder + "\\README.html").c_str()); readme->SetDescription(description.c_str()); readme->QueryInterface(IID_IPersistFile, (LPVOID*)&link); file = new unsigned short[MAX_PATH + 1]; MultiByteToWideChar(CP_ACP, 0, (programs + "\\Douglas Thrift\'s Search Eng" + "ine\\ReadMe.lnk").c_str(), -1, file, MAX_PATH + 1); link->Save(file, true); link->Release(); readme->Release(); delete [] file; SendMessage(bar, PBM_STEPIT, 0, 0); IShellLink* uninstall; description = "Uninstall Douglas Thrift\'s Search Engine"; CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&uninstall); uninstall->SetPath((folder + "\\SearchUninstaller.exe").c_str()); uninstall->SetIconLocation((folder + "\\SearchUninstaller.exe").c_str(), 0); uninstall->SetDescription(description.c_str()); uninstall->QueryInterface(IID_IPersistFile, (LPVOID*)&link); file = new unsigned short[MAX_PATH + 1]; MultiByteToWideChar(CP_ACP, 0, (programs + "\\Douglas Thrift\'s Search Eng" + "ine\\Uninstall.lnk").c_str(), -1, file, MAX_PATH + 1); link->Save(file, true); link->Release(); uninstall->Release(); delete [] file; SendMessage(bar, PBM_STEPIT, 0, 0); } void Worker::registry(HWND bar) { SendMessage(bar, PBM_SETPOS, 0, 0); SendDlgItemMessage(GetParent(bar), IDC_PROGRESS_TEXT, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)"Registering files..."); SendMessage(bar, PBM_SETRANGE, 0, MAKELPARAM(0, 90)); HKEY hkey; string subkey = string("Software\\Microsoft\\Windows\\CurrentVersion\\Uni") + "nstall\\Douglas Thrift\'s Search Engine"; RegCreateKeyEx(single && nt ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, subkey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL); vector values; vector data; values.push_back("Contact"); data.push_back("Douglas Thrift"); values.push_back("DisplayIcon"); data.push_back(folder + "\\bin\\Search.exe,0"); values.push_back("DisplayName"); data.push_back("Douglas Thrift\'s Search Engine"); values.push_back("DisplayVersion"); data.push_back("1.1"); values.push_back("InstallLocation"); data.push_back(folder); values.push_back("Publisher"); data.push_back("DouglasThrift.net"); values.push_back("Readme"); data.push_back(folder + "\\README.html"); values.push_back("UninstallString"); data.push_back(folder + "\\SearchUninstaller.exe"); values.push_back("URLInfoAbout"); data.push_back("http://computers.douglasthrift.net/searchengine/"); for (unsigned index = 0; index < values.size(); index++) { unsigned char* buffer = new unsigned char[data[index].length() + 1]; for (unsigned number = 0; number < data[index].length(); number++) { buffer[number] = data[index][number]; } buffer[number] = '\0'; RegSetValueEx(hkey, values[index].c_str(), 0, REG_SZ, buffer, number + 1); delete [] buffer; SendMessage(bar, PBM_STEPIT, 0, 0); } RegCloseKey(hkey); }