CString GitAdminDir::ReadGitLink(const CString& topDir, const CString& dotGitPath) { CAutoFILE pFile = _wfsopen(dotGitPath, L"r", SH_DENYWR); if (!pFile) return L""; int size = 65536; auto buffer = std::make_unique<char[]>(size); int length = (int)fread(buffer.get(), sizeof(char), size, pFile); CStringA gitPathA(buffer.get(), length); if (length < 8 || !CStringUtils::StartsWith(gitPathA, "gitdir: ")) return L""; CString gitPath = CUnicodeUtils::GetUnicode(gitPathA); // trim after converting to UTF-16, because CStringA trim does not work when having UTF-8 chars gitPath = gitPath.Trim().Mid((int)wcslen(L"gitdir: ")); gitPath.Replace('/', '\\'); if (!gitPath.IsEmpty() && gitPath[0] == L'.') { gitPath = CPathUtils::BuildPathWithPathDelimiter(topDir) + gitPath; CString adminDir; PathCanonicalize(CStrBuf(adminDir, MAX_PATH), gitPath); return adminDir; } CPathUtils::TrimTrailingPathDelimiter(gitPath); return gitPath; }
static void ForcePathQuoteSpaces( WCHAR * _quotePath, const std::wstring & _path ) { if( _path.empty() == true ) { wcscpy_s( _quotePath, 2, L"" ); return; } std::wstring true_path = _path; if( _path[0] == L'/' ) { true_path[0] = true_path[1]; true_path[1] = L':'; } const WCHAR * pathBuffer = true_path.c_str(); size_t pathSize = true_path.size(); PathCanonicalize( _quotePath, pathBuffer ); if( PathQuoteSpaces( _quotePath ) == FALSE ) { wmemmove( _quotePath + 1, _quotePath, pathSize ); _quotePath[0] = '\"'; _quotePath[pathSize + 1] = '\"'; _quotePath[pathSize + 2] = 0; } };
static BOOL CreateFolder(LPCTSTR pszFolder) { char *pszWork; pszWork = (char*)malloc(MAX_PATH); lstrcpy(pszWork, pszFolder); if (!PathFileExists(pszWork)) { if (PathIsRoot(pszWork)) { free(pszWork); return FALSE; } char *pszWork2; pszWork2 = (char *)malloc(MAX_PATH); lstrcpy(pszWork2, pszWork); PathAddBackslash(pszWork2); lstrcpy(pszWork2, ".."); PathCanonicalize(pszWork, pszWork2); free(pszWork2); if (CreateFolder(pszWork)) { BOOL ret = CreateDirectory(pszFolder, NULL); free(pszWork); return ret; } else { free(pszWork); return FALSE; } } free(pszWork); return TRUE; }
/** * Try to figure out the absolute path based on the application name * (usually argv[0]). If the path is already absolute return a copy, if * it start with . look into the current directory, if not dig into * the $PATH. * In case of error or if executable was not found (as an example if * the application did a cwd between the start and this call), the * function will return NULL. Otherwise, an newly allocated string * will be returned. */ char* opal_find_absolute_path( char* app_name ) { char* abs_app_name; char cwd[OPAL_PATH_MAX], *pcwd; if( opal_path_is_absolute(app_name) ) { /* already absolute path */ abs_app_name = app_name; } else if ( '.' == app_name[0] || NULL != strchr(app_name, OPAL_PATH_SEP[0])) { /* the app is in the current directory or below it */ pcwd = getcwd( cwd, OPAL_PATH_MAX ); if( NULL == pcwd ) { /* too bad there is no way we can get the app absolute name */ return NULL; } abs_app_name = opal_os_path( false, pcwd, app_name, NULL ); } else { /* Otherwise try to search for the application in the PATH ... */ abs_app_name = opal_path_findv( app_name, X_OK, NULL, NULL ); } if( NULL != abs_app_name ) { char* resolved_path = (char*)malloc(OPAL_PATH_MAX); #if !defined(__WINDOWS__) realpath( abs_app_name, resolved_path ); #else #ifdef HAVE_SHLWAPI_H PathCanonicalize(resolved_path, abs_app_name); #endif #endif /* !defined(__WINDOWS__) */ if( abs_app_name != app_name ) free(abs_app_name); return resolved_path; } return NULL; }
/// Directory handling /// ================== BOOL md_dir_set(UINT32 dir_seg4, UINT16 dir_off) { CHAR dir_raw[MAX_PATH]; TCHAR dir_ucs2[MAX_PATH]; OEMCHAR *dos_dir; OEMCHAR *real_dir; BOOL ret; dos_dir = mem_read_sjis2ucs2(dir_raw, dir_ucs2, dir_seg4, dir_off, MAX_PATH); real_dir = md_drive_parse(dos_dir); // Changing to an empty string would lead to an error, crashing DOS if(real_dir[0] == _T('\0')) { ret = 1; } else { ret = SetCurrentDirectory(real_dir); } // Don't set errors here! // Changing the registers quickly leads to // DOS crashing inside its own DIR function if(ret) { if(PathIsRelative(dos_dir)) { OEMCHAR tmp[MAX_PATH]; lstrcpy(tmp, cur_dir); PathAddBackslash(tmp); lstrcat(tmp, real_dir); PathCanonicalize(cur_dir, tmp); } else { lstrcpy(cur_dir, real_dir); } } // Don't override DOS' handling of this one return FALSE; }
CString GitAdminDir::ReadGitLink(const CString& topDir, const CString& dotGitPath) { CAutoFILE pFile = _tfsopen(dotGitPath, _T("r"), SH_DENYWR); if (!pFile) return _T(""); int size = 65536; auto buffer = std::make_unique<char[]>(size); int length = (int)fread(buffer.get(), sizeof(char), size, pFile); CStringA gitPathA(buffer.get(), length); if (length < 8 || gitPathA.Left(8) != "gitdir: ") return _T(""); CString gitPath = CUnicodeUtils::GetUnicode(gitPathA); // trim after converting to UTF-16, because CStringA trim does not work when having UTF-8 chars gitPath = gitPath.Trim().Mid(8); // 8 = len("gitdir: ") gitPath.Replace('/', '\\'); gitPath.TrimRight('\\'); if (!gitPath.IsEmpty() && gitPath[0] == _T('.')) { gitPath = topDir + _T("\\") + gitPath; CString adminDir; PathCanonicalize(CStrBuf(adminDir, MAX_PATH), gitPath); return adminDir; } return gitPath; }
CString CPathUtils::GetLongPathname(const CString& path) { if (path.IsEmpty()) return path; TCHAR pathbufcanonicalized[MAX_PATH]; // MAX_PATH ok. DWORD ret = 0; CString sRet; if (!PathIsURL(path) && PathIsRelative(path)) { ret = GetFullPathName(path, 0, NULL, NULL); if (ret) { std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 1]); if ((ret = GetFullPathName(path, ret, pathbuf.get(), NULL)) != 0) sRet = CString(pathbuf.get(), ret); } } else if (PathCanonicalize(pathbufcanonicalized, path)) { ret = ::GetLongPathName(pathbufcanonicalized, NULL, 0); std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 2]); ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret + 1); sRet = CString(pathbuf.get(), ret); } else { ret = ::GetLongPathName(path, NULL, 0); std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 2]); ret = ::GetLongPathName(path, pathbuf.get(), ret + 1); sRet = CString(pathbuf.get(), ret); } if (ret == 0) return path; return sRet; }
bool testPathCanonicalize(TCHAR *path) { generic_string strPath(path); TCHAR output[MAX_PATH]; BOOL charRet = PathCanonicalize(output, path); BOOL strRet = PathCanonicalize(strPath); if (charRet != strRet || strPath != output) { _tprintf(_T("Testing |%s| String (ours) |%s| returned %d Char (system) |%s| returned %d\r\n"), path, strPath.c_str(), strRet, output, charRet); } return ((charRet == strRet) && (strPath == output)); }
bool DOS_MakeName(char const* const name, char* fullname, Bit8u* drive) // Nb, returns path w/o leading '\\'! { char makename_out[MAX_PATH]; // This will make sure that the PathCanonicalize function doesn't fail. char makename_in[DOS_PATHLENGTH * 2]; if (!name || *name == 0 || *name == ' ') // Both \0 and space are seperators and empty filenames report file not found { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } char const* name_ptr = name; if (name_ptr[1] == ':') // First get the drive { *drive = (*name_ptr | 0x20)-'a'; name_ptr += 2; } else *drive = DOS_GetDefaultDrive(); if (*drive >= DOS_DRIVES || !Drives[*drive] || strlen(name_ptr) >= DOS_PATHLENGTH) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; } char * oPtr = makename_in; if (*name_ptr != '\\' && *name_ptr != '/' && *Drives[*drive]->curdir) oPtr += strlen(strcat(strcat(strcpy(oPtr, "\\"), Drives[*drive]->curdir), "\\")); char const * iPtr = name_ptr; for (int sRem = 0; *iPtr; iPtr++) // Strip bare filenames and extensions from trailing spaces { if (*iPtr == ' ') sRem++; else { if (*iPtr != '.' && *iPtr != '\\') for (; sRem; sRem--) *oPtr++ = ' '; else sRem = 0; *oPtr++ = *iPtr; } } *oPtr = 0; if (!(PathCanonicalize(makename_out, makename_in) && NormalizePath(makename_out))) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; } if ( strlen(makename_out) >= DOS_PATHLENGTH ) { // Make sure that we dont try to create a path that is longer than DOS_PATHLENGTH (80 chars) DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; } strcpy(fullname, makename_out + (*makename_out =='\\' ? 1 : 0)); // Leading '\\' dropped again return true; }
void updateRegistry() { if (versionNum && versionNum != 0x7FFFFFFF) { writeLog(L"Updating registry.."); versionStr[versionLen / 2] = 0; HKEY rkey; LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{53F49750-6209-4FBF-9CA8-7A333C87D1ED}_is1", 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &rkey); if (status == ERROR_SUCCESS) { writeLog(L"Checking registry install location.."); static const int bufSize = 4096; DWORD locationType, locationSize = bufSize * 2; WCHAR locationStr[bufSize], exp[bufSize]; if (RegQueryValueEx(rkey, L"InstallLocation", 0, &locationType, (BYTE*)locationStr, &locationSize) == ERROR_SUCCESS) { locationSize /= 2; if (locationStr[locationSize - 1]) { locationStr[locationSize++] = 0; } if (locationType == REG_EXPAND_SZ) { DWORD copy = ExpandEnvironmentStrings(locationStr, exp, bufSize); if (copy <= bufSize) { memcpy(locationStr, exp, copy * sizeof(WCHAR)); } } if (locationType == REG_EXPAND_SZ || locationType == REG_SZ) { if (PathCanonicalize(exp, locationStr)) { memcpy(locationStr, exp, bufSize * sizeof(WCHAR)); if (GetFullPathName(L".", bufSize, exp, 0) < bufSize) { wstring installpath = locationStr, mypath = exp; if (installpath == mypath + L"\\" || true) { // always update reg info, if we found it WCHAR nameStr[bufSize], dateStr[bufSize], publisherStr[bufSize], icongroupStr[bufSize]; SYSTEMTIME stLocalTime; GetLocalTime(&stLocalTime); RegSetValueEx(rkey, L"DisplayVersion", 0, REG_SZ, (BYTE*)versionStr, ((versionLen / 2) + 1) * sizeof(WCHAR)); wsprintf(nameStr, L"Telegram Desktop version %s", versionStr); RegSetValueEx(rkey, L"DisplayName", 0, REG_SZ, (BYTE*)nameStr, (wcslen(nameStr) + 1) * sizeof(WCHAR)); wsprintf(publisherStr, L"Telegram Messenger LLP"); RegSetValueEx(rkey, L"Publisher", 0, REG_SZ, (BYTE*)publisherStr, (wcslen(publisherStr) + 1) * sizeof(WCHAR)); wsprintf(icongroupStr, L"Telegram Desktop"); RegSetValueEx(rkey, L"Inno Setup: Icon Group", 0, REG_SZ, (BYTE*)icongroupStr, (wcslen(icongroupStr) + 1) * sizeof(WCHAR)); wsprintf(dateStr, L"%04d%02d%02d", stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay); RegSetValueEx(rkey, L"InstallDate", 0, REG_SZ, (BYTE*)dateStr, (wcslen(dateStr) + 1) * sizeof(WCHAR)); WCHAR *appURL = L"https://desktop.telegram.org"; RegSetValueEx(rkey, L"HelpLink", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR)); RegSetValueEx(rkey, L"URLInfoAbout", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR)); RegSetValueEx(rkey, L"URLUpdateInfo", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR)); } } } } } RegCloseKey(rkey); } } }
static void fixRelativePaths(strings &dirs, const char_t *basepath) { for (strings::iterator d = dirs.begin(); d != dirs.end(); d++) if (PathIsRelative(d->c_str())) { char_t absdir[MAX_PATH]; _makepath_s(absdir, countof(absdir), NULL, basepath, d->c_str(), NULL); char_t absdirC[MAX_PATH]; PathCanonicalize(absdirC, absdir); *d = absdirC; } }
static void on_dir_dblclick (void) { char buf[MAX_PATH]; if (DlgDirSelectEx (hMainWindow, buf, sizeof(buf), IDC_DIRS)) { strcat (CurrentPath, buf); strcpy (buf, CurrentPath); PathCanonicalize(CurrentPath, buf); current_path_to_edit (); populate_dir (); } }
bool CConfigIni::LoadPath(const CString& strSection, const CString& strItem, CString& value) const { CString v; if(!LoadString(strSection, strItem, v)) return false; value = m_szPath; value += v; PathCanonicalize(v.GetBuffer(MAX_LENGTH_SECTION_OR_NODE), value.GetBuffer()); v.ReleaseBuffer(); value.ReleaseBuffer(); value = v; return true; }
void my_canonicalize_path(const TCHAR *path, TCHAR *out, int size) { TCHAR tmp[MAX_DPATH]; int v; v = GetLongPathName (path, tmp, sizeof tmp / sizeof (TCHAR)); if (!v || v > sizeof tmp / sizeof (TCHAR)) { _tcsncpy (out, path, size); out[size - 1] = 0; return; } PathCanonicalize(out, tmp); }
/** * Returns the .git-path (if .git is a file, read the repository path and return it) * adminDir always ends with "\" */ bool GitAdminDir::GetAdminDirPath(const CString &projectTopDir, CString &adminDir) const { if (IsBareRepo(projectTopDir)) { adminDir = projectTopDir; adminDir.TrimRight('\\'); adminDir.Append(_T("\\")); return true; } CString sDotGitPath = projectTopDir + _T("\\") + g_GitAdminDir.GetAdminDirName(); if (CTGitPath(sDotGitPath).IsDirectory()) { sDotGitPath.TrimRight('\\'); sDotGitPath.Append(_T("\\")); adminDir = sDotGitPath; return true; } else { FILE *pFile; _tfopen_s(&pFile, sDotGitPath, _T("r")); if (!pFile) return false; int size = 65536; std::unique_ptr<char[]> buffer(new char[size]); SecureZeroMemory(buffer.get(), size); fread(buffer.get(), sizeof(char), size, pFile); fclose(pFile); CStringA gitPathA(buffer.get()); if (gitPathA.Left(8) != "gitdir: ") return false; CString gitPath = CUnicodeUtils::GetUnicode(gitPathA.Trim().Mid(8)); // 8 = len("gitdir: ") gitPath.Replace('/', '\\'); gitPath.TrimRight('\\'); gitPath.Append(_T("\\")); if (gitPath.GetLength() > 0 && gitPath[0] == _T('.')) { gitPath = projectTopDir + _T("\\") + gitPath; PathCanonicalize(adminDir.GetBuffer(MAX_PATH), gitPath.GetBuffer()); adminDir.ReleaseBuffer(); gitPath.ReleaseBuffer(); return true; } adminDir = gitPath; return true; } }
/** *\fn void addFile() *\brief 添加一个新文件 *\return void 无 */ void CBrowseWnd::addFile() { int fileId = 0; int count = ListView_GetItemCount(list_.m_hWnd); char filename[256] = ""; for (int i = 0; i < count; i++) { ListView_GetItemText(list_.m_hWnd, i, 0, filename, sizeof(filename)-1); if (NULL != strstr(filename, NEW_FILE_NAME)) { if (atoi(&filename[strlen(NEW_FILE_NAME)]) >= fileId) { fileId = atoi(&filename[strlen(NEW_FILE_NAME)]) + 1; } } } sprintf_s(filename, NEW_FILE_NAME"%d", fileId); char path[1024] = ""; GetCurrentDirectory(MAX_PATH, path); int len = strlen(path); sprintf_s(&path[len], sizeof(path)-len-1, "\\%s\\%s", tempPath_, filename); char localPath[1024] = ""; PathCanonicalize(localPath, path); char remotePath[1024] = ""; path_.GetWindowText(remotePath, sizeof(remotePath)-1); strcat_s(remotePath, filename); if (!PathFileExists(tempPath_)) { ::CreateDirectory(tempPath_, NULL); } FILE *file = NULL; fopen_s(&file, localPath, "w+"); fwrite(filename, 1, strlen(filename), file); fclose(file); int ret = sftp_upload_file(&ssh_param_, localPath, remotePath); if (0 != ret) return; updateFileList(TreeView_GetSelection(tree_.m_hWnd)); }
static void on_drives_select (void) { char buf[_MAX_PATH]; //HWND wnd = GetDlgItem (hMainWindow, IDC_DRIVES); int drive; if (DlgDirSelectComboBoxEx (hMainWindow, buf, sizeof(buf), IDC_DRIVES)) { drive = toupper(buf[0]) - 'A' + 1; if(_getdcwd (drive, buf, _MAX_PATH) != NULL) { strcat (buf, "\\"); PathCanonicalize(CurrentPath, buf); current_path_to_edit (); populate_dir (); } } }
static int QualifyPath( const char *szPath) { char szCwd[MAX_PATH + 1]; char szTmp[MAX_PATH + 1]; char *p; GetCurrentDirectory(MAX_PATH, szCwd); while ((p = strchr(szPath, '/')) && *p) *p = '\\'; PathCombine(szTmp, szCwd, szPath); PathCanonicalize(szCwd, szTmp); printf("%s\n", szCwd); return 0; }
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, TCHAR* CmdLine, int ShowCmd) { (void)hPrevInstance; (void)ShowCmd; // Get the current module filename WCHAR CurrentModuleFile[MAX_PATH]; GetModuleFileNameW(hInstance, CurrentModuleFile, sizeof(CurrentModuleFile)); // Get the base directory from the current module filename WCHAR BaseDirectory[MAX_PATH]; PathCanonicalize(BaseDirectory, CurrentModuleFile); PathRemoveFileSpec(BaseDirectory); // Get the executable to run WCHAR* ExecFile = ReadResourceString(hInstance, MAKEINTRESOURCE(IDI_EXEC_FILE)); if(ExecFile == NULL) { MessageBoxW(NULL, L"This program is used for packaged games and is not meant to be run directly.", NULL, MB_OK); return 9000; } // Create a full command line for the program to run WCHAR* BaseArgs = ReadResourceString(hInstance, MAKEINTRESOURCE(IDI_EXEC_ARGS)); WCHAR* ChildCmdLine = new WCHAR[wcslen(BaseDirectory) + wcslen(ExecFile) + wcslen(BaseArgs) + wcslen(CmdLine) + 20]; wsprintf(ChildCmdLine, L"\"%s\\%s\" %s %s", BaseDirectory, ExecFile, BaseArgs, CmdLine); delete BaseArgs; delete ExecFile; // Install the prerequisites int ExitCode = InstallMissingPrerequisites(BaseDirectory); if(ExitCode != 0) { delete ChildCmdLine; return ExitCode; } // Spawn the target executable ExitCode = SpawnTarget(ChildCmdLine); if(ExitCode != 0) { delete ChildCmdLine; return ExitCode; } delete ChildCmdLine; return ExitCode; }
CString CPathFinder::GetAbsolutePath(LPCTSTR szBaseFolder) { if (!IsRelativePath()) return (LPCTSTR)sCEmptyString; TCHAR szAbsolutePath[_MAX_PATH]; CString sFullPath(szBaseFolder); if (sFullPath.IsEmpty()) return (LPCTSTR)sCEmptyString; sFullPath = CPathFinder::AddBackSlash(sFullPath); sFullPath += GetPath(); if (!PathCanonicalize(szAbsolutePath, sFullPath)) return (LPCTSTR)sCEmptyString; return szAbsolutePath; }
CFilePath &CFilePath::Canonicalize() { if (!msPath.GetLength()) return *this; if (msPath.Find(L"\\.") >= 0) { CString sTarget = msPath; CStringLock Buffer(sTarget, msPath.GetLength() + 2); PathCanonicalize(Buffer, msPath); Buffer.Release(); msPath = sTarget; } return *this; }
/* 010509 Carl Corcoran */ void CCString::Path_AbsoluteToRelative(PCWSTR wszNewRoot) { WCHAR wszNewString[MAX_PATH]; WCHAR wszCanonString[MAX_PATH]; PathRelativePathTo(wszNewString, wszNewRoot, FILE_ATTRIBUTE_DIRECTORY, this->wszString, FILE_ATTRIBUTE_NORMAL ); PathCanonicalize(wszCanonString, wszNewString); this->cpy(wszCanonString); return; }
void EvalRealPath(const void *mode, qCtx *ctx, qStr *out, qArgAry *args) { VALID_ARGC("realpath", 1, 1); CStr src = (*args)[0]; if (!src.Length()) return; CStr dest; dest.Grow(MAX_PATH); #ifdef WIN32 PathCanonicalize(dest.Data(), src.Data()); #else realpath(src.Data(), dest.Data()); #endif dest.Grow(strlen(dest.Data())); out->PutS(dest); }
HRESULT GetCacheLocationFromReg() { HRESULT hr = S_OK; WCHAR szBuf[MAX_PATH+1]; if (!PAL_FetchConfigurationString(TRUE, REG_VAL_FUSION_CACHE_LOCATION, szBuf, MAX_PATH)) { hr = E_FAIL; goto exit; } if(!PathCanonicalize(g_szWindowsDir, szBuf)) { hr = E_FAIL; goto exit; } g_cchWindowsDir = lstrlen(g_szWindowsDir); if(g_cchWindowsDir && (IsPathSeparator(g_szWindowsDir[g_cchWindowsDir - 1]))) g_szWindowsDir[g_cchWindowsDir - 1] = L'\0'; // remove trailing "\" // cache location cannot be = MAX_PATH; that won't leave any space for fusion dirs. if ((g_cchWindowsDir + TEMP_RANDOM_DIR_LENGTH)>= (MAX_PATH/2) ) { hr = HRESULT_FROM_WIN32(FUSION_E_INVALID_NAME); goto exit; } g_cchWindowsDir = lstrlen(g_szWindowsDir); if(GetFileAttributes(g_szWindowsDir) != (DWORD) -1) goto exit; if(SUCCEEDED(hr = CreateFilePathHierarchy(g_szWindowsDir))) { if(!CreateDirectory(g_szWindowsDir, NULL)) hr = FusionpHresultFromLastError(); } exit: return hr; }
static BOOL get_release_notes(wchar_t rpath[MAX_PATH]) { BOOL rv = FALSE; HKEY hk_client = NULL; wchar_t cpath[MAX_PATH]; DWORD cb_data; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\TransarcCorporation\\AFS Client\\CurrentVersion", 0, KEY_READ, &hk_client) != ERROR_SUCCESS) return FALSE; cb_data = sizeof(cpath); if (RegQueryValueEx(hk_client, L"PathName", NULL, NULL, (LPBYTE) cpath, &cb_data) != ERROR_SUCCESS) goto done; cpath[min(cb_data, MAX_PATH - 1)] = L'\0'; if (!PathRemoveFileSpec(cpath)) goto done; if (!PathAppend(cpath, L"Documentation")) goto done; if (!PathAppend(cpath, L"ReleaseNotes.chm")) goto done; if (!PathCanonicalize(rpath, cpath)) goto done; if (!PathFileExists(rpath)) goto done; rv = TRUE; done: if (hk_client) RegCloseKey(hk_client); return rv; }
/** * Makes sure a library named "Subversion" exists and has our template * set to it. * If the library already exists, the template is set. * If the library doesn't exist, it is created. */ void EnsureSVNLibrary(bool bCreate /* = true*/) { // when running the 32-bit version of TortoiseProc on x64 OS, // we must not create the library! This would break // the library in the x64 explorer. BOOL bIsWow64 = FALSE; IsWow64Process(GetCurrentProcess(), &bIsWow64); if (bIsWow64) return; CComPtr<IShellLibrary> pLibrary = NULL; if (FAILED(OpenShellLibrary(L"Subversion", &pLibrary))) { if (!bCreate) return; if (FAILED(SHCreateLibrary(IID_PPV_ARGS(&pLibrary)))) return; // Save the new library under the user's Libraries folder. CComPtr<IShellItem> pSavedTo = NULL; if (FAILED(pLibrary->SaveInKnownFolder(FOLDERID_UsersLibraries, L"Subversion", LSF_OVERRIDEEXISTING, &pSavedTo))) return; } if (SUCCEEDED(pLibrary->SetFolderType(IsWindows8OrGreater() ? FOLDERTYPEID_Documents : FOLDERTYPEID_SVNWC))) { // create the path for the icon CString path; CString appDir = CPathUtils::GetAppDirectory(); if (appDir.GetLength() < MAX_PATH) { TCHAR buf[MAX_PATH] = {0}; PathCanonicalize(buf, (LPCTSTR)appDir); appDir = buf; } path.Format(L"%s%s,-%d", (LPCTSTR)appDir, L"TortoiseProc.exe", IsWin10OrLater() ? IDI_LIBRARY_WIN10 : IDI_LIBRARY); pLibrary->SetIcon((LPCTSTR)path); pLibrary->Commit(); } }
BOOL kull_m_file_getAbsolutePathOf(wchar_t *thisData, wchar_t ** reponse) { BOOL reussite = FALSE; wchar_t *monRep; *reponse = (wchar_t *) LocalAlloc(LPTR, MAX_PATH); if(PathIsRelative(thisData)) { if(kull_m_file_getCurrentDirectory(&monRep)) { reussite = (PathCombine(*reponse , monRep, thisData) != NULL); LocalFree(monRep); } } else reussite = PathCanonicalize(*reponse, thisData); if(!reussite) LocalFree(*reponse); return reussite; }
CString CPathUtils::GetLongPathname(const CString& path) { if (path.IsEmpty()) return path; TCHAR pathbufcanonicalized[MAX_PATH] = {0}; // MAX_PATH ok. DWORD ret = 0; CString sRet; if (!PathIsURL(path) && PathIsRelative(path)) { ret = GetFullPathName(path, 0, nullptr, nullptr); if (ret) { auto pathbuf = std::make_unique<TCHAR[]>(ret + 1); if ((ret = GetFullPathName(path, ret, pathbuf.get(), nullptr)) != 0) sRet = CString(pathbuf.get(), ret); } } else if (PathCanonicalize(pathbufcanonicalized, path)) { ret = ::GetLongPathName(pathbufcanonicalized, nullptr, 0); if (ret == 0) return path; auto pathbuf = std::make_unique<TCHAR[]>(ret + 2); ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret + 1); sRet = CString(pathbuf.get(), ret); } else { ret = ::GetLongPathName(path, nullptr, 0); if (ret == 0) return path; auto pathbuf = std::make_unique<TCHAR[]>(ret + 2); ret = ::GetLongPathName(path, pathbuf.get(), ret + 1); sRet = CString(pathbuf.get(), ret); } if (ret == 0) return path; return sRet; }
//=========================================================================== //スレッド実行 //=========================================================================== void __fastcall TAttacheCaseFileDecrypt1::Execute() { int i, c, len; float ProgressPercentNumF; //進捗パーセンテージ(浮動小数点) // バッファ char buffer[BUF_SIZE]; char source_buffer[BUF_SIZE]; char temp_buffer[BUF_SIZE]; char output_buffer[LARGE_BUF_SIZE]; char *headerbuffer; //パスワード bool fPasswordOk; String FilePath, FileName; // ファイルストリーム TFileStream *fsIn; TFileStream *fsOut; bool fInputFileOpen = false; bool fOutputFileOpen = false; float free_space_required; __int64 CurrentPos, TotalSize; __int64 CurrentDriveFreeSpaceSize; //処理する合計サイズ AllTotalSize = 0; int ret; //バッファ出力の返値 int FileIndex = 0; //Blowfish CBlowFish *bf; char token[17] = {0, }; const String PrefixString = "Fn_"; const char charTokenString[17] = "_AttacheCaseData"; //復号の正否に使う String AtcFileTokenString; //暗号化ファイルのトークン(文字列) String AtcFileCreateDateString; //暗号化ファイルの生成日時(文字列) //同名ファイル/フォルダーはすべて上書きして復号する //(ユーザーがダイアログで「すべてはい」を選択したとき = true ) fOverwirteYesToAll = false; //「復号したファイルを関連付けされたソフトで開く」一時的な設定 fTempOpenFile = fOpenFile; //フォルダーを一度開いたか(深いフォルダーすべてを開かないように) fOpenFolderOnce = false; // 出力するディレクトリ OutDirPath = IncludeTrailingPathDelimiter(OutDirPath); String TempRelativePath; // 暗号化部分のヘッダサイズ int EncryptHeaderSize = 0; int DataVersion; // ver.2.00~は "5", ver.2.70~は "6" int flush, status; // zlib z_stream z; // zlibライブラリとやりとりするための構造体 bool fInputEnd = false; // 入力ストリームの終了 //ヘッダデータから必要情報を取り出すための TMemoryStream *pms; // メモリストリーム int idx; TStringList *DataList; TStringList *tsv; TStringList *FileList = new TStringList(); // 0: ファイル名 __int64 *FileSizeList = 0; // 1: ファイルサイズ(フォルダは-1) int *FileAttrList = 0; // 2: 属性 int *FileAgeList = 0; // 3: タイムスタンプ int rest; int buf_size; //---------------------------------------------------------------------- // 平文のヘッダ内容チェック try { fsIn = new TFileStream(AtcFilePath, fmOpenRead | fmShareDenyNone); } catch(...) { //'復号するファイルを開けません。他のアプリケーションが使用中の可能性があります。' MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_OPEN); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } fInputFileOpen = true; // 暗号部ヘッダサイズを取得 fsIn->Read(&EncryptHeaderSize, sizeof(int)); // トークンを取得 fsIn->Read(token, 16); if (StrComp(token, charTokenString) != 0 ) { //-------------------------------------------------------- //実は自己実行形式ファイル?(拡張子偽装されている場合も) //-------------------------------------------------------- // サイズを再取得 fsIn->Seek(-(__int64)sizeof(__int64), TSeekOrigin::soEnd); fsIn->Read(&AllTotalSize, sizeof(__int64)); // 位置を戻す fsIn->Seek(-(AllTotalSize + sizeof(__int64)), TSeekOrigin::soEnd); // もう一度、暗号部ヘッダサイズを取得 fsIn->Read(&EncryptHeaderSize, sizeof(int)); // もう一度、トークンを取得 fsIn->Read(token, 16); // トークンを再チェック if (StrComp(token, charTokenString) != 0 ) { // '暗号化ファイルではありません。アタッシェケースによって暗号化されたファイルでないか、'+#13+ // 'ファイルが壊れている可能性があります。' MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_NOT_ATC); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } } else{ AllTotalSize = fsIn->Size; } //----------------------------------- // データバージョンチェック //----------------------------------- DataVersion = -1; fsIn->Read(&DataVersion, sizeof(int)); if (DataVersion <= 103) { // Blowfishで暗号化されたファイル } else{ //'バージョンがちがいます。復号できません。'+#13+ //'ファイルはver.1のアタッシェケースで暗号化されていません。'; MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_NOT_BLOWFISH_ENCRYPTION); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } //----------------------------------- // 復号の準備 //----------------------------------- bf = new CBlowFish; bf->Initialize( KeyString.c_str(), KeyString.Length() ); //初期化 //----------------------------------- // 暗号部ヘッダの復号(ECBモード) //----------------------------------- pms = new TMemoryStream; len = 0; while (len < EncryptHeaderSize) { // 読み出しバッファ for (c = 0; c < BUF_SIZE; c++) { source_buffer[c] = 0; } // 暗号化されたデータブロックの読み出し len += fsIn->Read(source_buffer, BUF_SIZE); // 復号処理 bf->Decode( source_buffer, buffer, BUF_SIZE); pms->Write(buffer, BUF_SIZE); } pms->Seek((__int64)0, TSeekOrigin::soBeginning); //ポインタを先頭へ戻す DataList = new TStringList; DataList->LoadFromStream(pms, TEncoding::GetEncoding(932)); // shift-jis //----------------------------------- // 復号正否(復号できたか) //----------------------------------- if (DataList->Count == 0 || DataList->Strings[0].Pos("AttacheCase") == 0) { fPasswordOk = false; } else{ fPasswordOk = true; //パスワード合致 } if ( fPasswordOk == false ) { //'パスワードがちがいます。復号できません。'+#13+ //'場合によってはファイルが壊れている可能性もあります。'; MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_PASSWORD_WRONG); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete DataList; goto LabelTypeMiss; } //----------------------------------- // 復号時のエンコーディング判定 //----------------------------------- pms->Position = 0; DataList->LoadFromStream(pms, TEncoding::GetEncoding(932)); // shift-jis //=================================== // デバッグ //ShowMessage(DataList->Text); //=================================== delete pms; //----------------------------------- // 暗号化ファイルの生成日時 //----------------------------------- //※特に今は使用していないが、将来的に // 期限付きでファイルを復号できなくなる // などの機能を追加しても良いかも。 //----------------------------------- AtcFileCreateDateString = DataList->Strings[1]; //----------------------------------- // ヘッダデータからファイルリストや // ファイル情報などを各変数を動的確保 //----------------------------------- FileSizeList = new __int64[DataList->Count]; // 1: ファイルサイズ(フォルダは-1) FileAttrList = new int[DataList->Count]; // 2: 属性 FileAgeList = new int[DataList->Count]; // 3: タイムスタンプ DataList->NameValueSeparator = ':'; tsv = new TStringList; tsv->Delimiter = '\t'; tsv->StrictDelimiter = true; char lpPath[MAX_PATH]; for (i = 0; i < DataList->Count; i++) { idx = DataList->IndexOfName(PrefixString+IntToStr(i)); if (idx > 0) { tsv->DelimitedText = DataList->ValueFromIndex[idx]; // ディレクトリ・トラバーサル対策(ver.2.8.5.0~) bool fDirectoryTraversal = false; AnsiString CanonicalizePath = AnsiString(OutDirPath + tsv->Strings[0]); if (CanonicalizePath.Length() < MAX_PATH) { // ファイルパスを正規化 if (PathCanonicalize(lpPath, CanonicalizePath.c_str()) == true) { // 正規化したパスが保存先と一致するか if (AnsiString(lpPath).Pos(OutDirPath) != 1 ){ fDirectoryTraversal = true; } } else{ fDirectoryTraversal = true; } } else{ fDirectoryTraversal = true; } if (fDirectoryTraversal == true) { //'不正なファイルパスが含まれています。復号できません。'; MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_INVALID_FILE_PATH) + "\n" + CanonicalizePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete DataList; goto LabelTypeMiss; } FileList->Add(tsv->Strings[0]); // 0: ファイルパス FileSizeList[i] = StrToIntDef(tsv->Strings[1], -1); // 1: ファイルサイズ(フォルダは-1) FileAttrList[i] = StrToIntDef(tsv->Strings[2], -1); // 2: 属性 FileAgeList[i] = StrToIntDef(tsv->Strings[3], -1); // 3: タイムスタンプ } } delete tsv; delete DataList; //----------------------------------- //ディスクの空き容量チェック //----------------------------------- CurrentDriveFreeSpaceSize = GetDiskFreeSpaceNum(OutDirPath); if (CurrentDriveFreeSpaceSize > -1) { if ( AllTotalSize > CurrentDriveFreeSpaceSize ) { //'復号する先のドライブの空き容量が足りません。'+#13+ //'復号するには、約%dMBの空き容量が必要です。復号処理を中止します。'; MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_DRIVE_NO_FREE_SPACE); free_space_required = (float)AllTotalSize/1024/1024; // MB MsgText = String().sprintf(MsgText.c_str(), free_space_required); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } } else{ // OK! // } //----------------------------------- //複数フォルダ/ファイルを開こうとしているので確認 //----------------------------------- //復号したファイルを関連付けされたソフトで開くか if ( fTempOpenFile == true && FileList->Count > 4) { //'5つ以上のファイルを復号後に開こうとしていますが、処理を続けますか?'+#13+ //'「いいえ」を選択すると、開かず復号します。'; MsgText = LoadResourceString(&Msgdecrypt::_MSG_CONFIRM_OPEN_DECRYPTED_FILES); MsgType = mtConfirmation; MsgButtons = TMsgDlgButtons() << mbYes << mbNo << mbCancel; MsgDefaultButton = mbCancel; Synchronize(&PostConfirmMessageForm); if ( MsgReturnVal == mrCancel ) { goto LabelStop; } else if ( MsgReturnVal == mrNo ) { fTempOpenFile = true; } } //----------------------------------- // 復号開始 //----------------------------------- //'復号しています...' ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_DECRYPTING); ProgressMsgText = ExtractFileName(AtcFilePath); // ファイル(データ本体)サイズを取得する AllTotalSize = fsIn->Size - fsIn->Position + 1; // zlib 前準備 // 圧縮においてすべてのメモリ管理をライブラリに任せる z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; if (inflateInit(&z) != Z_OK) { // エラー // zlibエラーは最後でまとめてメッセージ処理 goto LabelError; } // 通常は deflate() の第2引数は Z_NO_FLUSH にして呼び出す flush = Z_NO_FLUSH; // 入出力バッファ for (i = 0; i < LARGE_BUF_SIZE; i++) { output_buffer[i] = 0; } z.avail_in = 0; // 入力バッファ中のデータのバイト数 z.next_in = Z_NULL; // 入力バッファ中のデータのバイト数 z.next_out = output_buffer; // 出力バッファ残量 z.avail_out = LARGE_BUF_SIZE; // 出力ポインタ(展開するので大きめに) status = Z_OK; while (Terminated == false) { //----------------------------------- // 入力 //----------------------------------- if (z.avail_in == 0) { TotalSize = InputBuffer(bf, len, source_buffer, fsIn, fInputFileOpen, TotalSize); z.avail_in = len; z.next_in = source_buffer; if ( len == 0 ) { //入力ストリーム終了 fInputEnd = true; } } //----------------------------------- // 展開 //----------------------------------- status = inflate(&z, flush); //----------------------------------- // 処理ステータス //----------------------------------- if ( status == Z_OK ){ if ( z.avail_out == 0 ) { ret = OutputBuffer(output_buffer, LARGE_BUF_SIZE, fsOut, fOutputFileOpen, FileList, FileIndex, FileSizeList, FileAttrList, FileAgeList); if ( ret == 0) { z.next_out = output_buffer; z.avail_out = LARGE_BUF_SIZE; } else if (ret == -1) { goto LabelError; } else{ goto LabelStop; } }//end if (z.avail_out == 0); } //----------------------------------- // バッファエラー //----------------------------------- else if ( status == Z_BUF_ERROR ) { //出力バッファがいっぱいの可能性 //出力バッファをクリアにして継続させる len = LARGE_BUF_SIZE - z.avail_out; ret = OutputBuffer(output_buffer, len, fsOut, fOutputFileOpen, FileList, FileIndex, FileSizeList, FileAttrList, FileAgeList); if (ret == 0) { z.next_out = output_buffer; z.avail_out = LARGE_BUF_SIZE; } else if ( ret == -1) { goto LabelError; } else{ goto LabelStop; } } //----------------------------------- // 終了 //----------------------------------- else if (status == Z_STREAM_END) { break; } //----------------------------------- // エラー //----------------------------------- else{ // #define Z_OK 0 // #define Z_STREAM_END 1 // #define Z_NEED_DICT 2 // #define Z_ERRNO (-1) // #define Z_STREAM_ERROR (-2) // #define Z_DATA_ERROR (-3) // #define Z_MEM_ERROR (-4) // #define Z_BUF_ERROR (-5) // #define Z_VERSION_ERROR (-6) goto LabelError; } //----------------------------------- //進捗状況表示 ProgressPercentNumF = (float)TotalSize/AllTotalSize; ProgressPercentNum = (int)(ProgressPercentNumF*100); if (AllTotalSize < 104857600) { // 100MB未満 ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%"; } else{ ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%"; } if ( fInputEnd == true) { break; } }//while (!Terminated); if (Terminated == true) { //ユーザーキャンセルで抜けてきた goto LabelStop; } //---------------------------------------------------------------------- // 万が一、出力バッファに余りがある場合 //---------------------------------------------------------------------- len = LARGE_BUF_SIZE - z.avail_out; ret = OutputBuffer(output_buffer, len, fsOut, fOutputFileOpen, FileList, FileIndex, FileSizeList, FileAttrList, FileAgeList); if ( ret == 0 ) { } else if ( ret == -1 ){ goto LabelError; } else{ goto LabelStop; } if (inflateEnd(&z) != Z_OK) { goto LabelError; } ProgressPercentNum = 100; //'完了' ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_COMPLETE); ProgressMsgText = ExtractFileName(AtcFilePath); if ( fInputFileOpen == true ) { delete fsIn; fInputFileOpen = false; } if ( fOutputFileOpen == true ) { delete fsOut; fOutputFileOpen = false; } delete FileList; delete [] FileSizeList; // 1: ファイルサイズ(フォルダは-1) delete [] FileAttrList; // 2: 属性 delete [] FileAgeList; // 3: 更新日 //復号成功 StatusNum = 1; return; //----------------------------------- //パスワード入力ミスの後始末 //----------------------------------- LabelTypeMiss: ProgressPercentNum = 0; //'エラー' ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_ERROR); //'復号に失敗しました。' ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_FAILED); if ( fInputFileOpen == true ) { delete fsIn; fInputFileOpen = false; } if ( fOutputFileOpen == true ) { delete fsOut; fOutputFileOpen = false; } delete FileList; delete [] FileSizeList; delete [] FileAttrList; delete [] FileAgeList; StatusNum = -1; return; //----------------------------------- //エラーの後始末 //----------------------------------- LabelError: ProgressPercentNum = 0; if ( status < 0 ){ //'zlibライブラリからエラーを返されました。' //'エラー番号:' MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_ZLIB) + IntToStr(status) + "\n" + z.msg; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); } //'エラー' ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_ERROR); //'復号に失敗しました。' ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_FAILED); if ( fInputFileOpen == true ) { delete fsIn; fInputFileOpen = false; } if ( fOutputFileOpen == true ) { delete fsOut; fOutputFileOpen = false; } delete FileList; delete [] FileSizeList; delete [] FileAttrList; delete [] FileAgeList; StatusNum = -2; return; //----------------------------------- //ユーザーキャンセルの後始末 //----------------------------------- LabelStop: ProgressPercentNum = 0; //'キャンセル' ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_USER_CANCEL); //'復号が中止されました。' ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_STOPPED); if ( fInputFileOpen == true ) { delete fsIn; fInputFileOpen = false; } if ( fOutputFileOpen == true ) { delete fsOut; fOutputFileOpen = false; } delete FileList; delete [] FileSizeList; delete [] FileAttrList; delete [] FileAgeList; StatusNum = 0; return; }
void updateRegistry() { writeLog(L"Updating registry.."); HANDLE versionFile = CreateFile(L"tdata\\version", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (versionFile != INVALID_HANDLE_VALUE) { DWORD versionNum = 0, versionLen = 0, readLen = 0; WCHAR versionStr[32]; if (ReadFile(versionFile, &versionNum, sizeof(DWORD), &readLen, NULL) != TRUE || readLen != sizeof(DWORD)) { versionNum = 0; } else if (ReadFile(versionFile, &versionLen, sizeof(DWORD), &readLen, NULL) != TRUE || readLen != sizeof(DWORD) || versionLen > 63) { versionNum = 0; } else if (ReadFile(versionFile, versionStr, versionLen, &readLen, NULL) != TRUE || readLen != versionLen) { versionNum = 0; } CloseHandle(versionFile); writeLog(L"Version file read."); if (versionNum) { versionStr[versionLen / 2] = 0; HKEY rkey; LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{53F49750-6209-4FBF-9CA8-7A333C87D1ED}_is1", 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &rkey); if (status == ERROR_SUCCESS) { writeLog(L"Checking registry install location.."); static const int bufSize = 4096; DWORD locationType, locationSize = bufSize * 2; WCHAR locationStr[bufSize], exp[bufSize]; if (RegQueryValueEx(rkey, L"InstallLocation", 0, &locationType, (BYTE*)locationStr, &locationSize) == ERROR_SUCCESS) { locationSize /= 2; if (locationStr[locationSize - 1]) { locationStr[locationSize++] = 0; } if (locationType == REG_EXPAND_SZ) { DWORD copy = ExpandEnvironmentStrings(locationStr, exp, bufSize); if (copy <= bufSize) { memcpy(locationStr, exp, copy * sizeof(WCHAR)); } } if (locationType == REG_EXPAND_SZ || locationType == REG_SZ) { if (PathCanonicalize(exp, locationStr) == TRUE) { memcpy(locationStr, exp, bufSize * sizeof(WCHAR)); if (GetFullPathName(L".", bufSize, exp, 0) < bufSize) { wstring installpath = locationStr, mypath = exp; if (installpath == mypath + L"\\" || true) { // always update reg info, if we found it WCHAR nameStr[bufSize], dateStr[bufSize], publisherStr[bufSize], icongroupStr[bufSize]; SYSTEMTIME stLocalTime; GetLocalTime(&stLocalTime); RegSetValueEx(rkey, L"DisplayVersion", 0, REG_SZ, (BYTE*)versionStr, ((versionLen / 2) + 1) * sizeof(WCHAR)); wsprintf(nameStr, L"Telegram Desktop version %s", versionStr); RegSetValueEx(rkey, L"DisplayName", 0, REG_SZ, (BYTE*)nameStr, (wcslen(nameStr) + 1) * sizeof(WCHAR)); wsprintf(publisherStr, L"Telegram Messenger LLP"); RegSetValueEx(rkey, L"Publisher", 0, REG_SZ, (BYTE*)publisherStr, (wcslen(publisherStr) + 1) * sizeof(WCHAR)); wsprintf(icongroupStr, L"Telegram Desktop"); RegSetValueEx(rkey, L"Inno Setup: Icon Group", 0, REG_SZ, (BYTE*)icongroupStr, (wcslen(icongroupStr) + 1) * sizeof(WCHAR)); wsprintf(dateStr, L"%04d%02d%02d", stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay); RegSetValueEx(rkey, L"InstallDate", 0, REG_SZ, (BYTE*)dateStr, (wcslen(dateStr) + 1) * sizeof(WCHAR)); WCHAR *appURL = L"https://tdesktop.com"; RegSetValueEx(rkey, L"HelpLink", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR)); RegSetValueEx(rkey, L"URLInfoAbout", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR)); RegSetValueEx(rkey, L"URLUpdateInfo", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR)); } } } } } RegCloseKey(rkey); } } } }