diff options
Diffstat (limited to 'gs/psi/dwinst.cpp')
-rw-r--r-- | gs/psi/dwinst.cpp | 953 |
1 files changed, 953 insertions, 0 deletions
diff --git a/gs/psi/dwinst.cpp b/gs/psi/dwinst.cpp new file mode 100644 index 000000000..70726ea48 --- /dev/null +++ b/gs/psi/dwinst.cpp @@ -0,0 +1,953 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ + +// $Id$ + +#define STRICT +#include <windows.h> +#include <objbase.h> +#include <shlobj.h> +#include <stdio.h> +#include <io.h> +#include <direct.h> + +#include "dwinst.h" + +#define UNINSTALLKEY TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall") +#define UNINSTALLSTRINGKEY TEXT("UninstallString") +#define DISPLAYNAMEKEY TEXT("DisplayName") +#define UNINSTALL_FILE "uninstal.txt" +char szSection[] = "////////////////////////////////\n"; + +#ifdef _MSC_VER +#define mktemp(x) _mktemp(x) +#define chdir(x) _chdir(x) +#define mkdir(x) _mkdir(x) +#endif + + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CInstall::CInstall() +{ + CoInitialize(NULL); + + m_szTargetDir[0] = '\0'; + m_szTargetGroup[0] = '\0'; + m_szPrograms[0] = '\0'; + m_szMainDir[0] = '\0'; + AddMessageFn = NULL; + SetAllUsers(FALSE); +} + +CInstall::~CInstall() +{ + CoUninitialize(); +} + +void CInstall::CleanUp(void) +{ + // delete all temporary files + if (m_fLogNew) + fclose(m_fLogNew); + m_fLogNew = NULL; + if (m_fLogOld) + fclose(m_fLogOld); + m_fLogOld = NULL; + + if (strlen(m_szRegistryNew)) + DeleteFile(m_szRegistryNew); + m_szRegistryNew[0] = '\0'; + + if (strlen(m_szRegistryOld)) + DeleteFile(m_szRegistryOld); + m_szRegistryOld[0] = '\0'; + + if (strlen(m_szShellNew)) + DeleteFile(m_szShellNew); + m_szShellNew[0] = '\0'; + + if (strlen(m_szShellOld)) + DeleteFile(m_szShellOld); + m_szShellOld[0] = '\0'; + + if (strlen(m_szFileNew)) + DeleteFile(m_szFileNew); + m_szFileNew[0] = '\0'; +} + + +void CInstall::SetMessageFunction(void(*fn)(const char *)) +{ + AddMessageFn = fn; +} + +void CInstall::AddMessage(const char *message) +{ + if (AddMessageFn) + (*AddMessageFn)(message); +} + +void CInstall::SetTargetDir(const char *szTargetDir) +{ + strcpy(m_szTargetDir, szTargetDir); + // remove trailing backslash + char *p; + p = m_szTargetDir + strlen(m_szTargetDir) - 1; + if (*p == '\\') + *p = '\0'; +} + +void CInstall::SetTargetGroup(const char *szTargetGroup) +{ + strcpy(m_szTargetGroup, szTargetGroup); + // remove trailing backslash + char *p; + p = m_szTargetGroup + strlen(m_szTargetGroup) - 1; + if (*p == '\\') + *p = '\0'; +} + +const char *CInstall::GetMainDir() +{ + return m_szMainDir; +} + +const char *CInstall::GetUninstallName() +{ + return m_szUninstallName; +} + +BOOL CInstall::Init(const char *szSourceDir, const char *szFileList) +{ + FILE *f; + + strcpy(m_szSourceDir, szSourceDir); + // remove trailing backslash + char *p; + p = m_szSourceDir + strlen(m_szSourceDir) - 1; + if (*p == '\\') + *p = '\0'; + strcpy(m_szFileList, szFileList); + + m_szRegistryNew[0] = m_szRegistryOld[0] = + m_szShellNew[0] = m_szShellOld[0] = + m_szFileNew[0] = '\0'; + + // Open list of files + SetCurrentDirectory(m_szSourceDir); + f = fopen(m_szFileList, "r"); + if (f == (FILE *)NULL) { + char buf[MAXSTR]; + wsprintf(buf, "Failed to open \042%s\042\n", m_szFileList); + AddMessage(buf); + return FALSE; + } + + // get application and directory name + m_szUninstallName[0] = '\0'; + if (!fgets(m_szUninstallName, sizeof(m_szUninstallName), f)) { + AddMessage("Invalid file list\n"); + fclose(f); + return FALSE; + } + if (*m_szUninstallName ) + m_szUninstallName[strlen(m_szUninstallName)-1] = '\0'; + + m_szMainDir[0] = '\0'; + if (!fgets(m_szMainDir, sizeof(m_szMainDir), f)) { + AddMessage("Invalid file list\n"); + fclose(f); + return FALSE; + } + if (*m_szMainDir ) + m_szMainDir[strlen(m_szMainDir)-1] = '\0'; + fclose(f); + + // Create log directory + strcpy(m_szLogDir, m_szTargetDir); + strcat(m_szLogDir, "\\"); + strcat(m_szLogDir, m_szMainDir); + MakeDir(m_szLogDir); + + return TRUE; +} + + +////////////////////////////////////////// +// File installation methods + +BOOL CInstall::InstallFiles(BOOL bNoCopy, BOOL *pbQuit) +{ + char szLogNew[MAXSTR]; + + AddMessage(bNoCopy ? "Checking" : "Copying"); + AddMessage(" files listed in "); + AddMessage(m_szFileList); + AddMessage("\n"); + + // Open list of files + SetCurrentDirectory(m_szSourceDir); + FILE *f = fopen(m_szFileList, "r"); + if (f == (FILE *)NULL) { + AddMessage("Failed to open \042"); + AddMessage(m_szFileList); + AddMessage("\042\n"); + return FALSE; + } + + // skip application and directory name + fgets(szLogNew, sizeof(szLogNew), f); + fgets(szLogNew, sizeof(szLogNew), f); + + // Create target log + + m_fLogNew = MakeTemp(m_szFileNew); + if (!m_fLogNew) { + AddMessage("Failed to create FileNew temporary file\n"); + return FALSE; + } + + // Copy files + char line[MAXSTR]; + while (fgets(line, sizeof(line), f) != (char *)NULL) { + if (*pbQuit) + return FALSE; + if (*line) + line[strlen(line)-1] = '\0'; + if (!InstallFile(line, bNoCopy)) { + fclose(f); + fclose(m_fLogNew); + return FALSE; + } + } + fclose(f); + fclose(m_fLogNew); + m_fLogNew = NULL; + return TRUE; +} + + +void CInstall::AppendFileNew(const char *filename) +{ + FILE *f; + /* mark backup file for uninstall */ + if ((f = fopen(m_szFileNew, "a")) != (FILE *)NULL) { + fputs(filename, f); + fputs("\n", f); + fclose(f); + } +} + +// recursive mkdir +// requires a full path to be specified, so ignores root \ +// apart from root \, must not contain trailing \ +// Examples: +// c:\ (OK, but useless) +// c:\gstools (OK) +// c:\gstools\ (incorrect) +// c:gstools (incorrect) +// gstools (incorrect) +// The following UNC names should work, +// but didn't under Win3.1 because gs_chdir wouldn't accept UNC names +// Needs to be tested under Windows 95. +// \\server\sharename\gstools (OK) +// \\server\sharename\ (OK, but useless) +// + +BOOL CInstall::MakeDir(const char *dirname) +{ + char newdir[MAXSTR]; + const char *p; + if (strlen(dirname) < 3) + return -1; + + if (isalpha(dirname[0]) && dirname[1]==':' && dirname[2]=='\\') { + // drive mapped path + p = dirname+3; + } + else if (dirname[1]=='\\' && dirname[1]=='\\') { + // UNC path + p = strchr(dirname+2, '\\'); // skip servername + if (p == NULL) + return -1; + p++; + p = strchr(p, '\\'); // skip sharename + if (p == NULL) + return -1; + } + else { + // not full path so error + return -1; + } + + while (1) { + strncpy(newdir, dirname, (int)(p-dirname)); + newdir[(int)(p-dirname)] = '\0'; + if (chdir(newdir)) { + if (mkdir(newdir)) + return -1; + } + p++; + if (p >= dirname + strlen(dirname)) + break; // all done + p = strchr(p, '\\'); + if (p == NULL) + p = dirname + strlen(dirname); + } + + return SetCurrentDirectory(dirname); +} + +void CInstall::ResetReadonly(const char *filename) +{ + DWORD dwAttr = GetFileAttributes(filename); + if (dwAttr & FILE_ATTRIBUTE_READONLY) + SetFileAttributes(filename, dwAttr & (~FILE_ATTRIBUTE_READONLY)); +} + +BOOL CInstall::InstallFile(char *filename, BOOL bNoCopy) +{ + char existing_name[MAXSTR]; + char new_name[MAXSTR]; + char dir_name[MAXSTR]; + + strcpy(existing_name, m_szSourceDir); + strcat(existing_name, "\\"); + strcat(existing_name, filename); + strcpy(new_name, m_szTargetDir); + strcat(new_name, "\\"); + strcat(new_name, filename); + strcpy(dir_name, new_name); + char *p = strrchr(dir_name, '\\'); + if (p) { + *p = '\0'; + if (!MakeDir(dir_name)) { + AddMessage("Failed to make directory "); + AddMessage(dir_name); + AddMessage("\n"); + return FALSE; + } + } + AddMessage(" "); + AddMessage(new_name); + AddMessage("\n"); + + if (bNoCopy) { + // Don't copy files. Leave them where they are. + // Check that all files exist + FILE *f; + if ((f = fopen(existing_name, "r")) == (FILE *)NULL) { + AddMessage("Missing file "); + AddMessage(existing_name); + AddMessage("\n"); + return FALSE; + } + fclose(f); + } + else { + if (!CopyFile(existing_name, new_name, FALSE)) { + char message[MAXSTR+MAXSTR+100]; + wsprintf(message, "Failed to copy file %s to %s\n", + existing_name, new_name); + AddMessage(message); + return FALSE; + } + ResetReadonly(new_name); + fputs(new_name, m_fLogNew); + fputs("\n", m_fLogNew); + } + + + return TRUE; +} + +////////////////////////////////////////// +// Shell methods + +BOOL CInstall::StartMenuBegin() +{ + m_fLogNew = MakeTemp(m_szShellNew); + if (!m_fLogNew) { + AddMessage("Failed to create ShellNew temporary file\n"); + return FALSE; + } + + m_fLogOld = MakeTemp(m_szShellOld); + if (!m_fLogOld) { + AddMessage("Failed to create ShellNew temporary file\n"); + return FALSE; + } + + // make folder if needed + char szLink[MAXSTR]; + strcpy(szLink, m_szPrograms); + strcat(szLink, "\\"); + strcat(szLink, m_szTargetGroup); + if (chdir(szLink) != 0) { + if (mkdir(szLink) != 0) { + char buf[MAXSTR+64]; + wsprintf(buf, "Couldn't make Programs folder \042%s'042", szLink); + AddMessage(buf); + StartMenuEnd(); + return FALSE; + } + } + else { + fprintf(m_fLogOld, "Group=%s\n\n", szLink); + } + fprintf(m_fLogNew, "Group=%s\n\n", szLink); + + return TRUE; +} + +BOOL CInstall::StartMenuEnd() +{ + if (m_fLogOld) + fclose(m_fLogOld); + m_fLogOld = NULL; + if (m_fLogNew) + fclose(m_fLogNew); + m_fLogNew = NULL; + return TRUE; +} + +BOOL CInstall::StartMenuAdd(const char *szDescription, + const char *szProgram, const char *szArguments) +{ + if (!CreateShellLink(szDescription, szProgram, szArguments)) { + AddMessage("Couldn't make shell link for "); + AddMessage(szDescription); + AddMessage("\n"); + StartMenuEnd(); + return FALSE; + } + + return TRUE; +} + + +BOOL CInstall::CreateShellLink(LPCSTR description, LPCSTR program, + LPCSTR arguments, LPCSTR icon, int nIconIndex) +{ + HRESULT hres; + IShellLink* psl; + CHAR szLink[MAXSTR]; + strcpy(szLink, m_szPrograms); + strcat(szLink, "\\"); + strcat(szLink, m_szTargetGroup); + strcat(szLink, "\\"); + strcat(szLink, description); + strcat(szLink, ".LNK"); + AddMessage("Adding shell link\n "); + AddMessage(szLink); + AddMessage("\n"); + + // Ensure string is UNICODE. + WCHAR wsz[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, szLink, -1, wsz, MAX_PATH); + + // Save old shell link + + // Get a pointer to the IShellLink interface. + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + IID_IShellLink, (void **)&psl); + if (SUCCEEDED(hres)) { + IPersistFile* ppf; + // Query IShellLink for the IPersistFile interface. + hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); + if (SUCCEEDED(hres)) { + // Load the shell link. + hres = ppf->Load(wsz, STGM_READ); + if (SUCCEEDED(hres)) { + // Resolve the link. + hres = psl->Resolve(HWND_DESKTOP, SLR_ANY_MATCH); + if (SUCCEEDED(hres)) { + // found it, so save details + CHAR szTemp[MAXSTR]; + WIN32_FIND_DATA wfd; + int i; + + + fprintf(m_fLogOld, "Name=%s\n", szLink); + hres = psl->GetPath(szTemp, MAXSTR, (WIN32_FIND_DATA *)&wfd, + SLGP_SHORTPATH ); + if (SUCCEEDED(hres)) + fprintf(m_fLogOld, "Path=%s\n", szTemp); + hres = psl->GetDescription(szTemp, MAXSTR); + if (SUCCEEDED(hres)) + fprintf(m_fLogOld, "Description=%s\n", szTemp); + hres = psl->GetArguments(szTemp, MAXSTR); + if (SUCCEEDED(hres) && (szTemp[0] != '\0')) + fprintf(m_fLogOld, "Arguments=%s\n", szTemp); + hres = psl->GetWorkingDirectory(szTemp, MAXSTR); + if (SUCCEEDED(hres) && (szTemp[0] != '\0')) + fprintf(m_fLogOld, "Directory=%s\n", szTemp); + hres = psl->GetIconLocation(szTemp, MAXSTR, &i); + if (SUCCEEDED(hres) && (szTemp[0] != '\0')) { + fprintf(m_fLogOld, "IconLocation=%s\n", szTemp); + fprintf(m_fLogOld, "IconIndex=%d\n", i); + } + fprintf(m_fLogOld, "\n"); + } + } + // Release pointer to IPersistFile. + ppf->Release(); + } + // Release pointer to IShellLink. + psl->Release(); + } + + + // Save new shell link + + // Get a pointer to the IShellLink interface. + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + IID_IShellLink, (void **)&psl); + if (SUCCEEDED(hres)) { + IPersistFile* ppf; + // Query IShellLink for the IPersistFile interface for + // saving the shell link in persistent storage. + hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); + if (SUCCEEDED(hres)) { + fprintf(m_fLogNew, "Name=%s\n", szLink); + + // Set the path to the shell link target. + hres = psl->SetPath(program); + if (!SUCCEEDED(hres)) + AddMessage("SetPath failed!"); + fprintf(m_fLogNew, "Path=%s\n", program); + // Set the description of the shell link. + hres = psl->SetDescription(description); + if (!SUCCEEDED(hres)) + AddMessage("SetDescription failed!"); + fprintf(m_fLogNew, "Description=%s\n", description); + if (arguments != (LPCSTR)NULL) { + // Set the arguments of the shell link target. + hres = psl->SetArguments(arguments); + if (!SUCCEEDED(hres)) + AddMessage("SetArguments failed!"); + fprintf(m_fLogNew, "Arguments=%s\n", arguments); + } + if (icon != (LPCSTR)NULL) { + // Set the arguments of the shell link target. + hres = psl->SetIconLocation(icon, nIconIndex); + if (!SUCCEEDED(hres)) + AddMessage("SetIconLocation failed!"); + fprintf(m_fLogNew, "IconLocation=%s\n", icon); + fprintf(m_fLogNew, "IconIndex=%d\n", nIconIndex); + } + + // Save the link via the IPersistFile::Save method. + hres = ppf->Save(wsz, TRUE); + // Release pointer to IPersistFile. + ppf->Release(); + } + // Release pointer to IShellLink. + psl->Release(); + fprintf(m_fLogNew, "\n"); + } + + return (hres == 0); +} + + +////////////////////////////////////////// +// Registry methods + +void +reg_quote(char *d, const char *s) +{ + while (*s) { + if (*s == '\\') + *d++ = '\\'; + *d++ = *s++; + } + *d = *s; +} + +BOOL CInstall::UpdateRegistryBegin() +{ + const char regheader[]="REGEDIT4\n"; + m_fLogNew = MakeTemp(m_szRegistryNew); + if (!m_fLogNew) { + AddMessage("Failed to create RegistryNew temporary file\n"); + return FALSE; + } + fputs(regheader, m_fLogNew); + + m_fLogOld = MakeTemp(m_szRegistryOld); + if (!m_fLogOld) { + AddMessage("Failed to create RegistryOld temporary file\n"); + UpdateRegistryEnd(); + return FALSE; + } + fputs(regheader, m_fLogOld); + + return TRUE; +} + +BOOL CInstall::UpdateRegistryEnd() +{ + if (m_fLogNew) + fclose(m_fLogNew); + m_fLogNew = NULL; + if (m_fLogOld) + fclose(m_fLogOld); + m_fLogOld = NULL; + return TRUE; +} + +BOOL CInstall::UpdateRegistryKey(const char *product, const char *version) +{ + const char hkey_name[] = "HKEY_LOCAL_MACHINE"; + const HKEY hkey_key = HKEY_LOCAL_MACHINE; + const char key_format[] = "\n[%s\\%s]\n"; + + /* Create default registry entries */ + HKEY hkey; + LONG lrc; + char name[MAXSTR]; + + // Create/Open application key + sprintf(name, "SOFTWARE\\%s", product); + lrc = RegOpenKey(hkey_key, name, &hkey); + if (lrc == ERROR_SUCCESS) { + fprintf(m_fLogOld, key_format, hkey_name, name); + } + else { + lrc = RegCreateKey(hkey_key, name, &hkey); + if (lrc == ERROR_SUCCESS) + fprintf(m_fLogNew, key_format, hkey_name, name); + } + if (lrc == ERROR_SUCCESS) + RegCloseKey(hkey); + + // Create/Open application version key + sprintf(name, "SOFTWARE\\%s\\%s", product, version); + + AddMessage(" "); + AddMessage(hkey_name); + AddMessage("\\"); + AddMessage(name); + AddMessage("\n"); + lrc = RegOpenKey(hkey_key, name, &hkey); + if (lrc == ERROR_SUCCESS) + fprintf(m_fLogOld, key_format, hkey_name, name); + else + lrc = RegCreateKey(hkey_key, name, &hkey); + if (lrc == ERROR_SUCCESS) { + fprintf(m_fLogNew, key_format, hkey_name, name); + } + else { + UpdateRegistryEnd(); + } + return TRUE; +} + +BOOL CInstall::UpdateRegistryValue(const char *product, const char *version, + const char *name, const char *value) +{ + char appver[MAXSTR]; + BOOL flag = FALSE; + HKEY hkey; + // Open application/version key + sprintf(appver, "SOFTWARE\\%s\\%s", product, version); + + if (RegOpenKey(HKEY_LOCAL_MACHINE, appver, &hkey) + == ERROR_SUCCESS) { + flag = SetRegistryValue(hkey, name, value); + RegCloseKey(hkey); + } + + return flag; +} + +BOOL CInstall::SetRegistryValue(HKEY hkey, const char *value_name, const char *value) +{ + char buf[MAXSTR]; + char qbuf[MAXSTR]; + DWORD cbData; + DWORD keytype; + + cbData = sizeof(buf); + keytype = REG_SZ; + if (RegQueryValueEx(hkey, value_name, 0, &keytype, + (LPBYTE)buf, &cbData) == ERROR_SUCCESS) { + reg_quote(qbuf, buf); + fprintf(m_fLogOld, "\042%s\042=\042%s\042\n", value_name, qbuf); + } + reg_quote(qbuf, value); + fprintf(m_fLogNew, "\042%s\042=\042%s\042\n", value_name, qbuf); + AddMessage(" "); + AddMessage(value_name); + AddMessage("="); + AddMessage(value); + AddMessage("\n"); + if (RegSetValueEx(hkey, value_name, 0, REG_SZ, + (CONST BYTE *)value, strlen(value)+1) != ERROR_SUCCESS) + return FALSE; + return TRUE; +} + +//////////////////////////////////// +// Uninstall + + +BOOL CInstall::WriteUninstall(const char *szProg, BOOL bNoCopy) +{ + LONG rc; + HKEY hkey; + HKEY hsubkey; + char buffer[MAXSTR]; + char ungsprog[MAXSTR]; + + lstrcpy(ungsprog, m_szTargetDir); + lstrcat(ungsprog, "\\"); + lstrcat(ungsprog, szProg); + + lstrcpy(buffer, m_szSourceDir); + lstrcat(buffer, "\\"); + lstrcat(buffer, szProg); + + if (bNoCopy) { + // Don't copy files. Leave them where they are. + // Check that all files exist + FILE *f; + if ((f = fopen(buffer, "r")) == (FILE *)NULL) { + AddMessage("Missing file "); + AddMessage(buffer); + AddMessage("\n"); + return FALSE; + } + fclose(f); + } + else if (!CopyFile(buffer, ungsprog, FALSE)) { + char message[MAXSTR+MAXSTR+100]; + wsprintf(message, "Failed to copy file %s to %s", buffer, ungsprog); + AddMessage(message); + return FALSE; + } + ResetReadonly(ungsprog); + + /* write registry entries for uninstall */ + if ((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, UNINSTALLKEY, 0, + KEY_ALL_ACCESS, &hkey)) != ERROR_SUCCESS) { + /* failed to open key, so try to create it */ + rc = RegCreateKey(HKEY_LOCAL_MACHINE, UNINSTALLKEY, &hkey); + } + if (rc == ERROR_SUCCESS) { + // Uninstall key for program + if (RegCreateKey(hkey, m_szUninstallName, &hsubkey) == ERROR_SUCCESS) { + RegSetValueEx(hsubkey, DISPLAYNAMEKEY, 0, REG_SZ, + (CONST BYTE *)m_szUninstallName, lstrlen(m_szUninstallName)+1); + lstrcpy(buffer, ungsprog); + lstrcat(buffer, " \042"); + lstrcat(buffer, m_szTargetDir); + lstrcat(buffer, "\\"); + lstrcat(buffer, m_szMainDir); + lstrcat(buffer, "\\"); + lstrcat(buffer, UNINSTALL_FILE); + lstrcat(buffer, "\042"); + AddMessage(" "); + AddMessage(m_szUninstallName); + AddMessage("="); + AddMessage(buffer); + AddMessage("\n"); + RegSetValueEx(hsubkey, UNINSTALLSTRINGKEY, 0, REG_SZ, + (CONST BYTE *)buffer, lstrlen(buffer)+1); + RegCloseKey(hsubkey); + } + + RegCloseKey(hkey); + } + return TRUE; +} + + +void +CInstall::CopyFileContents(FILE *df, FILE *sf) +{ + char buf[MAXSTR]; + int count; + while ((count = fread(buf, 1, sizeof(buf), sf)) != 0) + fwrite(buf, 1, count, df); +} + +FILE *CInstall::MakeTemp(char *fname) +{ + char *temp; + if ( (temp = getenv("TEMP")) == NULL ) + strcpy(fname, m_szTargetDir); + else + strcpy(fname, temp); + + /* Prevent X's in path from being converted by mktemp. */ + for ( temp = fname; *temp; temp++ ) { + *temp = (char)tolower(*temp); + if (*temp == '/') + *temp = '\\'; + } + if ( strlen(fname) && (fname[strlen(fname)-1] != '\\') ) + strcat(fname, "\\"); + + strcat(fname, "gsXXXXXX"); + mktemp(fname); + AddMessage("Creating temporary file "); + AddMessage(fname); + AddMessage("\n"); + return fopen(fname, "w"); +} + +BOOL CInstall::MakeLog() +{ + FILE *f, *lf; + char szFileName[MAXSTR]; + char szLogDir[MAXSTR]; + strcpy(szLogDir, m_szTargetDir); + strcat(szLogDir, "\\"); + strcat(szLogDir, m_szMainDir); + strcat(szLogDir, "\\"); + + strcpy(szFileName, szLogDir); + strcat(szFileName, UNINSTALL_FILE); + lf = fopen(szFileName, "w"); + if (lf == (FILE *)NULL) { + AddMessage("Can't create uninstall log"); + CleanUp(); + return FALSE; + } + fputs(szSection, lf); + fputs("UninstallName\n", lf); + fputs(m_szUninstallName, lf); + fputs("\n\n", lf); + + if (strlen(m_szRegistryNew) && + (f = fopen(m_szRegistryNew, "r")) != (FILE *)NULL) { + fputs(szSection, lf); + fputs("RegistryNew\n", lf); + CopyFileContents(lf, f); + fputs("\n", lf); + fclose(f); + DeleteFile(m_szRegistryNew); + m_szRegistryNew[0] = '\0'; + } + + if (strlen(m_szRegistryOld) && + (f = fopen(m_szRegistryOld, "r")) != (FILE *)NULL) { + fputs(szSection, lf); + fputs("RegistryOld\n", lf); + CopyFileContents(lf, f); + fputs("\n", lf); + fclose(f); + DeleteFile(m_szRegistryOld); + m_szRegistryOld[0] = '\0'; + } + + if (strlen(m_szShellNew) && + (f = fopen(m_szShellNew, "r")) != (FILE *)NULL) { + fputs(szSection, lf); + fputs("ShellNew\n", lf); + CopyFileContents(lf, f); + fputs("\n", lf); + fclose(f); + DeleteFile(m_szShellNew); + m_szShellNew[0] = '\0'; + } + + if (strlen(m_szShellOld) && + (f = fopen(m_szShellOld, "r")) != (FILE *)NULL) { + fputs(szSection, lf); + fputs("ShellOld\n", lf); + CopyFileContents(lf, f); + fputs("\n", lf); + fclose(f); + DeleteFile(m_szShellOld); + m_szShellOld[0] = '\0'; + } + + if (strlen(m_szFileNew) && + (f = fopen(m_szFileNew, "r")) != (FILE *)NULL) { + fputs(szSection, lf); + fputs("FileNew\n", lf); + CopyFileContents(lf, f); + fputs("\n", lf); + fclose(f); + DeleteFile(m_szFileNew); + m_szFileNew[0] = '\0'; + } + + fputs(szSection, lf); + fclose(lf); + + return TRUE; +} + +BOOL CInstall::GetPrograms(BOOL bUseCommon, char *buf, int buflen) +{ + // Get the directory for the Program menu. This is + // stored in the Registry under HKEY_CURRENT_USER\Software\ + // Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Programs. + LONG rc; + HKEY hCU; + DWORD dwType; + ULONG ulSize = buflen; + HKEY hrkey = HKEY_CURRENT_USER; + if (bUseCommon) + hrkey = HKEY_LOCAL_MACHINE; + if (RegOpenKeyEx(hrkey, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + 0,KEY_QUERY_VALUE, + &hCU) == ERROR_SUCCESS) { + rc = RegQueryValueEx( hCU, + bUseCommon ? "Common Programs" : "Programs", + NULL, + &dwType, + (unsigned char *)buf, + &ulSize); + RegCloseKey(hCU); + return TRUE; + } + return FALSE; + +#ifdef NOTUSED + // This is an alternate version, but it needs + // Internet Explorer 4.0 with Web Integrated Desktop. + // It does not work with the standard + // Windows 95, Windows NT 4.0, Internet Explorer 3.0, + // and Internet Explorer 4.0 without Web Integrated Desktop. + + HRESULT rc; + m_szPrograms[0] = '\0'; + int nFolder = CSIDL_PROGRAMS; + if (bUseCommon) + nFolder = CSIDL_COMMON_PROGRAMS; + + rc = SHGetSpecialFolderPath(HWND_DESKTOP, m_szPrograms, + nFolder, FALSE); + return (rc == NOERROR); +#endif + +} + +BOOL CInstall::SetAllUsers(BOOL bUseCommon) +{ + m_bUseCommon = bUseCommon; + return GetPrograms(bUseCommon, m_szPrograms, sizeof(m_szPrograms)); +} + + +////////////////////////////////////////////////////////////////////// |