std::string ANSIToUTF8(std::string path, const std::string& name) { path += name; int len = MultiByteToWideChar(CP_ACP, 0, path.c_str(), -1, NULL, 0); LPWSTR buf = (LPWSTR)malloc(2*len); if (buf) { MultiByteToWideChar(CP_ACP, 0, path.c_str(), -1, buf, len); int plen = GetLongPathNameW(buf, NULL, 0); LPWSTR buf2 = (LPWSTR)malloc(plen*2+2); if (buf2) { GetLongPathNameW(buf, buf2, plen); LPWSTR buf3 = wcsrchr((wchar_t*)buf2, L'\\')+1; int ulen = WideCharToMultiByte(CP_UTF8, 0, buf3, -1, NULL, 0, NULL, NULL); if (ulen) { std::string tmp; tmp.resize(ulen-1); WideCharToMultiByte(CP_UTF8, 0, buf3, -1, (LPSTR)tmp.c_str(), ulen-1, NULL, NULL); free(buf2); free(buf); return tmp; } free(buf2); } free(buf); } return ""; }
QTCREATOR_UTILS_EXPORT QString getLongPathName(const QString &name) { if (name.isEmpty()) return name; // Determine length, then convert. const LPCTSTR nameC = reinterpret_cast<LPCTSTR>(name.utf16()); // MinGW const DWORD length = GetLongPathNameW(nameC, NULL, 0); if (length == 0) return name; QScopedArrayPointer<TCHAR> buffer(new TCHAR[length]); GetLongPathNameW(nameC, buffer.data(), length); const QString rc = QString::fromUtf16(reinterpret_cast<const ushort *>(buffer.data()), length - 1); return rc; }
/*--------------------------------------------------------------------------*/ wchar_t *getlongpathnameW(wchar_t *wcshortpathname, BOOL *convertok) { wchar_t *wcLongName = NULL; #ifdef _MSC_VER /* first we try to call to know path length */ int length = GetLongPathNameW(wcshortpathname, NULL, 0); if (length <= 0 ) { length = MAX_PATH_LONG; } wcLongName = (wchar_t*)MALLOC((length + 1) * sizeof(wchar_t)); if (wcLongName) { /* second converts path */ if (GetLongPathNameW(wcshortpathname, wcLongName, length)) { *convertok = TRUE; } else { /* FAILED */ if (wcLongName) { wcscpy(wcLongName, wcshortpathname); } *convertok = FALSE; } } else { /* FAILED */ *convertok = FALSE; } #else /* Linux */ int len = (int)wcslen(wcshortpathname) + 1; wcLongName = (wchar_t*)MALLOC(len * sizeof(wchar_t)); if (wcLongName) { wcscpy(wcLongName, wcshortpathname); } *convertok = FALSE; #endif return wcLongName; }
/* allocate the win16 TIB for a new 16-bit task */ static WIN16_SUBSYSTEM_TIB *allocate_win16_tib( TDB *pTask ) { WCHAR path[MAX_PATH]; WIN16_SUBSYSTEM_TIB *tib; UNICODE_STRING *curdir; NE_MODULE *pModule = NE_GetPtr( pTask->hModule ); if (!(tib = HeapAlloc( GetProcessHeap(), 0, sizeof(*tib) ))) return NULL; MultiByteToWideChar( CP_ACP, 0, NE_MODULE_NAME(pModule), -1, path, MAX_PATH ); GetLongPathNameW( path, path, MAX_PATH ); if (RtlCreateUnicodeString( &tib->exe_str, path )) tib->exe_name = &tib->exe_str; else tib->exe_name = NULL; RtlAcquirePebLock(); if (NtCurrentTeb()->Tib.SubSystemTib) curdir = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath; else curdir = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath; tib->curdir.DosPath.MaximumLength = sizeof(tib->curdir_buffer); tib->curdir.DosPath.Length = min( curdir->Length, tib->curdir.DosPath.MaximumLength-sizeof(WCHAR) ); tib->curdir.DosPath.Buffer = tib->curdir_buffer; tib->curdir.Handle = 0; memcpy( tib->curdir_buffer, curdir->Buffer, tib->curdir.DosPath.Length ); tib->curdir_buffer[tib->curdir.DosPath.Length/sizeof(WCHAR)] = 0; RtlReleasePebLock(); return tib; }
virtual void SetUp() { // Compute link filename. wchar_t temp_dir[MAX_PATH]; int len = GetTempPathW(BUFFER_SIZE_ELEMENTS(temp_dir), temp_dir); // GetTempPathW sometimes gives an 8.3 path, so canonicalize into a long // path. wchar_t long_dir[MAX_PATH]; len = GetLongPathNameW(temp_dir, long_dir, BUFFER_SIZE_ELEMENTS(long_dir)); EXPECT_NE(0, len) << "GetLongPathNameW failed: " << GetLastError() << '\n'; link_path_.clear(); link_path_ += long_dir; // Documented to end in trailing slash. link_path_ += kTempLinkName; // Create a text file. file_path_.clear(); file_path_ += long_dir; // Documented to end in trailing slash. file_path_ += kTempFileName; std::wofstream file; file.open(file_path_.c_str()); file << L"File contents\r\n"; file.close(); // Initialize COM. HRESULT hr = CoInitialize(NULL); EXPECT_TRUE(SUCCEEDED(hr)); }
SString SharedUtil::GetSystemLongPathName( const SString& strPath ) { wchar_t szBuffer[32000]; szBuffer[0] = 0; GetLongPathNameW( FromUTF8( strPath ), szBuffer, NUMELMS( szBuffer ) - 1 ); return ToUTF8( szBuffer ); }
/// @TODO split raw fetching from settings file from path finding logic. The latter has nothing to do with the Settings class QString Settings::downloadDir() const { QStringList tempPathes; tempPathes << m_downloadDir; tempPathes << m_settingsMain->value("tempdir","").toString(); #ifdef Q_OS_WIN32 { // why not using Qt related methods ? WCHAR *buf = new WCHAR[256]; int iRet = GetTempPathW(256, buf); if( iRet > 255 ) { delete[] buf; buf = new WCHAR[iRet]; GetTempPathW(iRet, buf); } WCHAR *buf2 = new WCHAR[256]; iRet = GetLongPathNameW(buf, buf2, 256); if( iRet > 255 ) { delete[] buf2; buf2 = new WCHAR[iRet]; GetLongPathNameW(buf, buf2, iRet); } tempPathes << QString::fromUtf16((const ushort*)buf2, iRet) + "/KDE"; delete[] buf; delete[] buf2; } #else tempPathes << QDir::tempPath(); #endif foreach(const QString &path, tempPathes) { if (path.trimmed().isEmpty()) continue; QDir d(path); if (d.exists()) return QDir::toNativeSeparators(d.absolutePath()); if (d.mkpath(d.absolutePath())) return QDir::toNativeSeparators(d.absolutePath()); qWarning() << "could not setup temporay directory" << d.absolutePath(); } qCritical() << "could not create any temporay directory from" << tempPathes; return QString(); }
nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult) { nsCOMPtr<nsIFile> appDir = GetAppDir(); nsAutoString appPath; nsresult rv = appDir->GetPath(appPath); NS_ENSURE_SUCCESS(rv, rv); // AppDir may be a short path. Convert to long path to make sure // the consistency of the update folder location nsString longPath; PRUnichar* buf; uint32_t bufLength = longPath.GetMutableData(&buf, MAXPATHLEN); NS_ENSURE_TRUE(bufLength >= MAXPATHLEN, NS_ERROR_OUT_OF_MEMORY); DWORD len = GetLongPathNameW(appPath.get(), buf, bufLength); // Failing GetLongPathName() is not fatal. if (len <= 0 || len >= bufLength) longPath.Assign(appPath); else longPath.SetLength(len); // Use <UserLocalDataDir>\updates\<relative path to app dir from // Program Files> if app dir is under Program Files to avoid the // folder virtualization mess on Windows Vista nsAutoString programFiles; rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, programFiles); NS_ENSURE_SUCCESS(rv, rv); programFiles.AppendLiteral("\\"); uint32_t programFilesLen = programFiles.Length(); if (longPath.Length() < programFilesLen) return NS_ERROR_FAILURE; nsAutoString programName; if (_wcsnicmp(programFiles.get(), longPath.get(), programFilesLen) == 0) { programName = Substring(longPath, programFilesLen); } else { // We need the update root directory to live outside of the installation // directory, because otherwise the updater writing the log file can cause // the directory to be locked, which prevents it from being replaced after // background updates. programName.AssignASCII(MOZ_APP_NAME); } nsCOMPtr<nsIFile> updRoot; rv = GetUserLocalDataDirectory(getter_AddRefs(updRoot)); NS_ENSURE_SUCCESS(rv, rv); rv = updRoot->AppendRelativePath(programName); NS_ENSURE_SUCCESS(rv, rv); NS_ADDREF(*aResult = updRoot); return NS_OK; }
DWORD WINAPI GetLongPathNameU(LPCTSTR lpShortName, LPTSTR lpBuf, DWORD nBufferLength) { WCHAR *pwszShortName = NULL; WCHAR *pwBuf = NULL; int n; int lResult; int lName = lstrlen(lpShortName); int lNameNul = lName + 1; int lwBuf = lNameNul + MAX_PATH; /* In most cases, the long path will be shorter than MAX_PATH. If not, the buffer will be extended below. */ DEBUG_ENTER(("GetLongPathNameU(\"%s\", %p, %d);\n", lpShortName, lpBuf, nBufferLength)); pwszShortName = MultiByteToNewWidePath(CP_UTF8, lpShortName); if (!pwszShortName) { out_of_mem: RETURN_INT_COMMENT(0, ("Not enough memory\n")); } realloc_wBuf: pwBuf = GlobalAlloc(GMEM_FIXED, sizeof(WCHAR) * lwBuf); if (!pwBuf) { free(pwszShortName); goto out_of_mem; } lResult = (int)GetLongPathNameW(pwszShortName, pwBuf, lwBuf); if (lResult > lwBuf) { /* In the possible but unlikely case that the result does not fit in pwBuf, */ GlobalFree(pwBuf); /* then extend the buffer and retry. */ lwBuf = lResult; goto realloc_wBuf; } free(pwszShortName); /* We won't need this buffer anymore */ if (!lResult) { GlobalFree(pwBuf); RETURN_INT_COMMENT(0, ("GetLongPathNameW() failed\n")); } /* nRead = UnicodeToBytes(pwStr, len, buf, bufsize); */ n = WideCharToMultiByte(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ 0, /* dwFlags, */ pwBuf, /* lpWideCharStr, */ lResult + 1, /* cchWideChar, */ lpBuf, /* lpMultiByteStr, */ (int)nBufferLength, /* cbMultiByte, */ NULL, /* lpDefaultChar, */ NULL /* lpUsedDefaultChar */ ); GlobalFree(pwBuf); if (!n) RETURN_INT_COMMENT(0, ("Failed to convert the Long name from Unicode\n")); n -= 1; /* Do not count the final NUL */ /* Remove the long pathname \\?\ prefix, if it was not there before */ if ((!strncmp(lpBuf, "\\\\?\\", 4)) && strncmp(lpShortName, "\\\\?\\", 4)) { n = TrimLongPathPrefix(lpBuf); } RETURN_INT_COMMENT(n, ("\"%s\"\n", lpBuf)); }
// Case-Normalize file name via GetShortPathNameW()/GetLongPathNameW() QString normalizeFileName(const QString &name) { wchar_t shortBuffer[MAX_PATH]; const QString nativeFileName = QDir::toNativeSeparators(name); if (!GetShortPathNameW((wchar_t *)nativeFileName.utf16(), shortBuffer, MAX_PATH)) return name; wchar_t result[MAX_PATH]; if (!GetLongPathNameW(shortBuffer, result, MAX_PATH)) return name; return QDir::fromNativeSeparators(QString::fromWCharArray(result)); }
nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult) { nsCOMPtr<nsIFile> appDir = GetAppDir(); nsAutoString appPath; nsresult rv = appDir->GetPath(appPath); NS_ENSURE_SUCCESS(rv, rv); // AppDir may be a short path. Convert to long path to make sure // the consistency of the update folder location nsString longPath; PRUnichar* buf; PRUint32 bufLength = longPath.GetMutableData(&buf, MAXPATHLEN); NS_ENSURE_TRUE(bufLength >= MAXPATHLEN, NS_ERROR_OUT_OF_MEMORY); #ifdef WINCE longPath.Assign(appPath); #else DWORD len = GetLongPathNameW(appPath.get(), buf, bufLength); // Failing GetLongPathName() is not fatal. if (len <= 0 || len >= bufLength) longPath.Assign(appPath); else longPath.SetLength(len); #endif // Use <UserLocalDataDir>\updates\<relative path to app dir from // Program Files> if app dir is under Program Files to avoid the // folder virtualization mess on Windows Vista nsAutoString programFiles; rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, programFiles); NS_ENSURE_SUCCESS(rv, rv); programFiles.AppendLiteral("\\"); PRUint32 programFilesLen = programFiles.Length(); if (longPath.Length() < programFilesLen) return NS_ERROR_FAILURE; if (_wcsnicmp(programFiles.get(), longPath.get(), programFilesLen) != 0) return NS_ERROR_FAILURE; nsCOMPtr<nsILocalFile> updRoot; rv = GetUserLocalDataDirectory(getter_AddRefs(updRoot)); NS_ENSURE_SUCCESS(rv, rv); rv = updRoot->AppendRelativePath(Substring(longPath, programFilesLen)); NS_ENSURE_SUCCESS(rv, rv); NS_ADDREF(*aResult = updRoot); return NS_OK; }
BOOL CHistoryManager::PrepareTempDirs() { for (int i = 0; i < TEMP_KEY_COUNT; i++) { HKEY key; if (RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEMP_FOLDER, 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) continue; g_TempPaths[i].strRegKey = g_TempKey[i]; WCHAR szPath[1024]; DWORD Size = 1024; if (RegQueryValueExW(key, g_TempPaths[i].strRegKey.c_str(), NULL, NULL, (LPBYTE)szPath, &Size) != ERROR_SUCCESS) { RegCloseKey(key); continue; } CStringW strPath = szPath; strPath.Replace(L'/', L'\\'); if (strPath[strPath.GetLength() - 1] != L'\\') strPath += L'\\'; ////////////////////////////////////////////////////////////////////////// // Create Redirect Directory CStringW strTemp = m_strRedirectPath + CStringW(g_TempPaths[i].strRegKey.c_str()); if (!CreateDirectoryW(strTemp, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) continue; SetFileAttributesW(strTemp, FILE_ATTRIBUTE_HIDDEN); ////////////////////////////////////////////////////////////////////////// // WCHAR szDir[1024], szShort[1024], szLong[1024]; ExpandEnvironmentStringsW((LPWSTR)(LPCWSTR)strPath, (LPWSTR)szDir, _countof(szDir)); GetShortPathNameW(szDir, szShort, _countof(szShort)); GetLongPathNameW(szDir, szLong, _countof(szLong)); _wcslwr_s(szShort); _wcslwr_s(szLong); g_TempPaths[i].strShortTempDir = szShort; g_TempPaths[i].strLongTempDir = szLong; SplitPath(g_TempPaths[i].strShortTempDir, g_TempPaths[i].vecShortParts); SplitPath(g_TempPaths[i].strLongTempDir, g_TempPaths[i].vecLongParts); RegCloseKey(key); } return true; }
int is_ignored_process() { wchar_t process_path[MAX_PATH]; GetModuleFileNameW(NULL, process_path, MAX_PATH); GetLongPathNameW(process_path, process_path, MAX_PATH); for (uint32_t idx = 0; g_ignored_processpaths[idx] != NULL; idx++) { if(!wcsicmp(g_ignored_processpaths[idx], process_path)) { return 1; } } return 0; }
VDStringW VDGetLongPathW(const wchar_t *s) { WCHAR buf[MAX_PATH]; DWORD len = GetLongPathNameW(s, buf, MAX_PATH); VDStringW longPath; if (!len) longPath = s; else if (len <= MAX_PATH) longPath = buf; else if (len > MAX_PATH) { vdfastvector<WCHAR> extbuf(len, 0); DWORD len2 = GetLongPathNameW(s, extbuf.data(), len); if (len2 && len2 <= len) longPath = extbuf.data(); else longPath = s; } return longPath; }
std::string PathImpl::systemImpl() { Buffer<wchar_t> buffer(MAX_PATH_LEN); DWORD n = GetSystemDirectoryW(buffer.begin(), static_cast<DWORD>(buffer.size())); if (n > 0) { n = GetLongPathNameW(buffer.begin(), buffer.begin(), static_cast<DWORD>(buffer.size())); if (n <= 0) throw SystemException("Cannot get system directory long path name"); std::string result; UnicodeConverter::toUTF8(buffer.begin(), result); if (result[result.size() - 1] != '\\') result.append("\\"); return result; } throw SystemException("Cannot get system directory path"); }
CString Directory::GetLongPathName_(const CString& fileName) { long length = GetLongPathNameW(fileName, NULL, 0); if(length < 1 )return _T(""); wchar_t *buffer = new wchar_t[length]; if (buffer == NULL)return _T(""); length = GetLongPathName(fileName, buffer, length); if(length == 0) { delete []buffer; return _T(""); } CString sPathFileName(buffer); delete []buffer; return sPathFileName; }
std::string FileUtils::GetTempDirectory() { wchar_t tempDirectory[MAX_PATH]; tempDirectory[MAX_PATH-1] = '\0'; GetTempPathW(MAX_PATH - 1, tempDirectory); // This function seem to return Windows stubby paths, so // let's convert it to a full path name. std::wstring dir(tempDirectory); GetLongPathNameW(dir.c_str(), tempDirectory, MAX_PATH - 1); std::string out = UTILS_NS::WideToUTF8(tempDirectory); srand(GetTickCount()); // initialize seed std::ostringstream s; s << "k" << (double) rand(); std::string end = s.str(); return FileUtils::Join(out.c_str(), end.c_str(), NULL); }
/** * 获得下载目录 */ std::wstring CDownloadOperation::getBankCachePath(bool bChoose) { LPWSTR lpszTempPath = new wchar_t[MAX_PATH + 1]; int nLength = 0; if( bChoose ) nLength = GetTempPathW(MAX_PATH, lpszTempPath); else nLength = ExpandEnvironmentStringsW(L"%appdata%", lpszTempPath, MAX_PATH); while (nLength > MAX_PATH) { delete[] lpszTempPath; lpszTempPath = new wchar_t[nLength + 1]; if( bChoose ) nLength = GetTempPathW(nLength, lpszTempPath); else nLength = ExpandEnvironmentStringsW(L"%appdata%", lpszTempPath, nLength); } wchar_t tmp[500]; wcscpy_s(tmp,_countof(tmp),lpszTempPath); GetLongPathNameW(tmp,lpszTempPath,MAX_PATH+1 ); wcscpy_s(lpszTempPath,MAX_PATH+1,tmp); lpszTempPath[nLength] = L'\0'; std::wstring path = lpszTempPath; delete[] lpszTempPath; if (path[path.size() - 1] != L'\\') path += L"\\"; path += L"BankUpdate"; path += L'\\'; if( true == bChoose) CreateDirectory(path.c_str(), NULL); return path; }
CAMLprim value win_getcwd (value unit) { int res; wchar_t s[NT_MAX_PATH]; CAMLparam0(); CAMLlocal1 (path); res = GetCurrentDirectoryW (NT_MAX_PATH, s); if (res == 0) { win32_maperr(GetLastError()); uerror("getcwd", Nothing); } /* Normalize the path */ res = GetLongPathNameW (s, s, NT_MAX_PATH); if (res == 0) { win32_maperr(GetLastError()); uerror("getcwd", Nothing); } /* Convert the drive letter to uppercase */ if (s[0] >= L'a' && s[0] <= L'z') s[0] -= 32; path = copy_wstring(s); CAMLreturn (path); }
wstring CFileMonitorRequest::GetNotifyPath( CONST FILE_NOTIFY_INFORMATION * aNotifyInfo ) { _ASSERT( aNotifyInfo ); wstring wstrFullPath( aNotifyInfo->FileName , aNotifyInfo->FileNameLength/sizeof(WCHAR) ); //Handle a trailing backslash, such as for a root directory if ( m_wstrMonitorPath.length() > 0 && m_wstrMonitorPath[m_wstrMonitorPath.length()-1] != L'\\' ) wstrFullPath = ( m_wstrMonitorPath + L"\\" ) + wstrFullPath; else wstrFullPath = m_wstrMonitorPath + wstrFullPath; //Handle the case it's a 8.3 short filename. Convert it to long name WCHAR * wzFilename = PathFindFileNameW( wstrFullPath.c_str() ); if ( wcslen( wzFilename ) <= 12 && wcschr(wzFilename , L'~') ) { // Convert to the long filename form. Unfortunately, this does not work for deletions, so it's an imperfect fix WCHAR wzBuf[MAX_PATH]; if ( GetLongPathNameW( wstrFullPath.c_str() , wzBuf, _countof(wzBuf) ) > 0 ) wstrFullPath = wzBuf; } return wstrFullPath; }
nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult) { nsCOMPtr<nsIFile> updRoot; #if defined(MOZ_WIDGET_GONK) nsresult rv = NS_NewNativeLocalFile(nsDependentCString("/data/local"), true, getter_AddRefs(updRoot)); NS_ENSURE_SUCCESS(rv, rv); #else nsCOMPtr<nsIFile> appFile; bool per = false; nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile)); NS_ENSURE_SUCCESS(rv, rv); rv = appFile->GetParent(getter_AddRefs(updRoot)); NS_ENSURE_SUCCESS(rv, rv); #ifdef XP_MACOSX nsCOMPtr<nsIFile> appRootDirFile; nsCOMPtr<nsIFile> localDir; nsAutoString appDirPath; if (NS_FAILED(appFile->GetParent(getter_AddRefs(appRootDirFile))) || NS_FAILED(appRootDirFile->GetPath(appDirPath)) || NS_FAILED(GetUserDataDirectoryHome(getter_AddRefs(localDir), true))) { return NS_ERROR_FAILURE; } int32_t dotIndex = appDirPath.RFind(".app"); if (dotIndex == kNotFound) { dotIndex = appDirPath.Length(); } appDirPath = Substring(appDirPath, 1, dotIndex - 1); bool hasVendor = gAppData->vendor && strlen(gAppData->vendor) != 0; if (hasVendor || gAppData->name) { if (NS_FAILED(localDir->AppendNative(nsDependentCString(hasVendor ? gAppData->vendor : gAppData->name)))) { return NS_ERROR_FAILURE; } } else if (NS_FAILED(localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla")))) { return NS_ERROR_FAILURE; } if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("updates"))) || NS_FAILED(localDir->AppendRelativePath(appDirPath))) { return NS_ERROR_FAILURE; } localDir.forget(aResult); return NS_OK; #elif XP_WIN nsAutoString pathHash; bool pathHashResult = false; bool hasVendor = gAppData->vendor && strlen(gAppData->vendor) != 0; nsAutoString appDirPath; if (SUCCEEDED(updRoot->GetPath(appDirPath))) { // Figure out where we should check for a cached hash value. If the // application doesn't have the nsXREAppData vendor value defined check // under SOFTWARE\Mozilla. wchar_t regPath[1024] = { L'\0' }; swprintf_s(regPath, mozilla::ArrayLength(regPath), L"SOFTWARE\\%S\\%S\\TaskBarIDs", (hasVendor ? gAppData->vendor : "Mozilla"), MOZ_APP_BASENAME); // If we pre-computed the hash, grab it from the registry. pathHashResult = GetCachedHash(HKEY_LOCAL_MACHINE, nsDependentString(regPath), appDirPath, pathHash); if (!pathHashResult) { pathHashResult = GetCachedHash(HKEY_CURRENT_USER, nsDependentString(regPath), appDirPath, pathHash); } } // Get the local app data directory and if a vendor name exists append it. // If only a product name exists, append it. If neither exist fallback to // old handling. We don't use the product name on purpose because we want a // shared update directory for different apps run from the same path. nsCOMPtr<nsIFile> localDir; if (pathHashResult && (hasVendor || gAppData->name) && NS_SUCCEEDED(GetUserDataDirectoryHome(getter_AddRefs(localDir), true)) && NS_SUCCEEDED(localDir->AppendNative(nsDependentCString(hasVendor ? gAppData->vendor : gAppData->name))) && NS_SUCCEEDED(localDir->Append(NS_LITERAL_STRING("updates"))) && NS_SUCCEEDED(localDir->Append(pathHash))) { localDir.forget(aResult); return NS_OK; } nsAutoString appPath; rv = updRoot->GetPath(appPath); NS_ENSURE_SUCCESS(rv, rv); // AppDir may be a short path. Convert to long path to make sure // the consistency of the update folder location nsString longPath; wchar_t* buf; uint32_t bufLength = longPath.GetMutableData(&buf, MAXPATHLEN); NS_ENSURE_TRUE(bufLength >= MAXPATHLEN, NS_ERROR_OUT_OF_MEMORY); DWORD len = GetLongPathNameW(appPath.get(), buf, bufLength); // Failing GetLongPathName() is not fatal. if (len <= 0 || len >= bufLength) longPath.Assign(appPath); else longPath.SetLength(len); // Use <UserLocalDataDir>\updates\<relative path to app dir from // Program Files> if app dir is under Program Files to avoid the // folder virtualization mess on Windows Vista nsAutoString programFiles; rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, programFiles); NS_ENSURE_SUCCESS(rv, rv); programFiles.Append('\\'); uint32_t programFilesLen = programFiles.Length(); nsAutoString programName; if (_wcsnicmp(programFiles.get(), longPath.get(), programFilesLen) == 0) { programName = Substring(longPath, programFilesLen); } else { // We need the update root directory to live outside of the installation // directory, because otherwise the updater writing the log file can cause // the directory to be locked, which prevents it from being replaced after // background updates. programName.AssignASCII(MOZ_APP_NAME); } rv = GetUserLocalDataDirectory(getter_AddRefs(updRoot)); NS_ENSURE_SUCCESS(rv, rv); rv = updRoot->AppendRelativePath(programName); NS_ENSURE_SUCCESS(rv, rv); #endif // XP_WIN #endif updRoot.forget(aResult); return NS_OK; }
/* * Main function */ int wmain(int argc, WCHAR *argv[]) { LPSTR (*CDECL wine_get_unix_file_name_ptr)(LPCWSTR) = NULL; LPWSTR (*CDECL wine_get_dos_file_name_ptr)(LPCSTR) = NULL; WCHAR dos_pathW[MAX_PATH]; char path[MAX_PATH]; int outputformats; int i; outputformats = parse_options(argv); if (outputformats == 0) outputformats = UNIXFORMAT; if (outputformats & UNIXFORMAT) { wine_get_unix_file_name_ptr = (void*) GetProcAddress(GetModuleHandleA("KERNEL32"), "wine_get_unix_file_name"); if (wine_get_unix_file_name_ptr == NULL) { fprintf(stderr, "%s: cannot get the address of " "'wine_get_unix_file_name'\n", progname); exit(3); } } if (outputformats & WINDOWSFORMAT) { wine_get_dos_file_name_ptr = (void*) GetProcAddress(GetModuleHandleA("KERNEL32"), "wine_get_dos_file_name"); if (wine_get_dos_file_name_ptr == NULL) { fprintf(stderr, "%s: cannot get the address of " "'wine_get_dos_file_name'\n", progname); exit(3); } } for (i = 1; argv[i]; i++) { *path='\0'; if (outputformats & LONGFORMAT) { if (GetLongPathNameW(argv[i], dos_pathW, MAX_PATH)) WideCharToMultiByte(CP_UNIXCP, 0, dos_pathW, -1, path, MAX_PATH, NULL, NULL); printf("%s\n", path); } if (outputformats & SHORTFORMAT) { if (GetShortPathNameW(argv[i], dos_pathW, MAX_PATH)) WideCharToMultiByte(CP_UNIXCP, 0, dos_pathW, -1, path, MAX_PATH, NULL, NULL); printf("%s\n", path); } if (outputformats & UNIXFORMAT) { WCHAR *ntpath, *tail; int ntpathlen=lstrlenW(argv[i]); ntpath=HeapAlloc(GetProcessHeap(), 0, sizeof(*ntpath)*(ntpathlen+1)); lstrcpyW(ntpath, argv[i]); tail=NULL; while (1) { char *unix_name; WCHAR *slash, *c; unix_name = wine_get_unix_file_name_ptr(ntpath); if (unix_name) { if (tail) { WideCharToMultiByte(CP_UNIXCP, 0, tail+1, -1, path, MAX_PATH, NULL, NULL); printf("%s/%s\n", unix_name, path); } else { printf("%s\n", unix_name); } HeapFree( GetProcessHeap(), 0, unix_name ); break; } slash=(tail ? tail : ntpath+ntpathlen); while (slash != ntpath && *slash != '/' && *slash != '\\') slash--; if (slash == ntpath) { /* This is a complete path conversion failure. * It would typically happen if ntpath == "". */ printf("\n"); break; } c=slash+1; while (*c != '\0' && *c != '*' && *c != '?' && *c != '<' && *c != '>' && *c != '|' && *c != '"') c++; if (*c != '\0') { /* If this is not a valid NT path to start with, * then obviously we cannot convert it. */ printf("\n"); break; } if (tail) *tail='/'; tail=slash; *tail='\0'; } HeapFree(GetProcessHeap(), 0, ntpath); } if (outputformats & WINDOWSFORMAT) { WCHAR* windows_name; char* unix_name; DWORD size; size=WideCharToMultiByte(CP_UNIXCP, 0, argv[i], -1, NULL, 0, NULL, NULL); unix_name=HeapAlloc(GetProcessHeap(), 0, size); WideCharToMultiByte(CP_UNIXCP, 0, argv[i], -1, unix_name, size, NULL, NULL); if ((windows_name = wine_get_dos_file_name_ptr(unix_name))) { WideCharToMultiByte(CP_UNIXCP, 0, windows_name, -1, path, MAX_PATH, NULL, NULL); printf("%s\n", path); HeapFree( GetProcessHeap(), 0, windows_name ); } else printf( "\n" ); HeapFree( GetProcessHeap(), 0, unix_name ); } } exit(0); }
/* GetNativeSystemInfo is XP or later */ pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); if(NULL != pGNSI) pGNSI(&si); else GetSystemInfo(&si); if(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) strcat(ver, " x64"); } SET_STRING_ELT(ans, 1, mkChar(ver)); if((int)osvi.dwMajorVersion >= 5) { if(osvi.wServicePackMajor > 0) snprintf(ver, 256, "build %d, Service Pack %d", LOWORD(osvi.dwBuildNumber), (int) osvi.wServicePackMajor); else snprintf(ver, 256, "build %d", LOWORD(osvi.dwBuildNumber)); } else snprintf(ver, 256, "build %d, %s", LOWORD(osvi.dwBuildNumber), osvi.szCSDVersion); SET_STRING_ELT(ans, 2, mkChar(ver)); GetComputerNameW(name, &namelen); wcstoutf8(buf, name, 1000); SET_STRING_ELT(ans, 3, mkCharCE(buf, CE_UTF8)); #ifdef WIN64 SET_STRING_ELT(ans, 4, mkChar("x86-64")); #else SET_STRING_ELT(ans, 4, mkChar("x86")); #endif GetUserNameW(user, &userlen); wcstoutf8(buf, user, 1000); SET_STRING_ELT(ans, 5, mkCharCE(buf, CE_UTF8)); SET_STRING_ELT(ans, 6, STRING_ELT(ans, 5)); SET_STRING_ELT(ans, 7, STRING_ELT(ans, 5)); PROTECT(ansnames = allocVector(STRSXP, 8)); SET_STRING_ELT(ansnames, 0, mkChar("sysname")); SET_STRING_ELT(ansnames, 1, mkChar("release")); SET_STRING_ELT(ansnames, 2, mkChar("version")); SET_STRING_ELT(ansnames, 3, mkChar("nodename")); SET_STRING_ELT(ansnames, 4, mkChar("machine")); SET_STRING_ELT(ansnames, 5, mkChar("login")); SET_STRING_ELT(ansnames, 6, mkChar("user")); SET_STRING_ELT(ansnames, 7, mkChar("effective_user")); setAttrib(ans, R_NamesSymbol, ansnames); UNPROTECT(2); return ans; } SEXP do_syssleep(SEXP call, SEXP op, SEXP args, SEXP rho) { DWORD mtime; int ntime; double time; checkArity(op, args); time = asReal(CAR(args)); if (ISNAN(time) || time < 0) errorcall(call, _("invalid '%s' value"), "time"); ntime = 1000*(time) + 0.5; while (ntime > 0) { mtime = min(500, ntime); ntime -= mtime; Sleep(mtime); R_ProcessEvents(); } return R_NilValue; } #ifdef LEA_MALLOC #define MALLINFO_FIELD_TYPE size_t struct mallinfo { MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ MALLINFO_FIELD_TYPE smblks; /* number of fastbin blocks */ MALLINFO_FIELD_TYPE hblks; /* number of mmapped regions */ MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ MALLINFO_FIELD_TYPE fsmblks; /* space available in freed fastbin blocks */ MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ MALLINFO_FIELD_TYPE fordblks; /* total free space */ MALLINFO_FIELD_TYPE keepcost; /* top-most, releasable (via malloc_trim) space */ }; extern R_size_t R_max_memory; struct mallinfo mallinfo(void); #endif SEXP in_memsize(SEXP ssize) { SEXP ans; int maxmem = NA_LOGICAL; if(isLogical(ssize)) maxmem = asLogical(ssize); else if(isReal(ssize)) { R_size_t newmax; double mem = asReal(ssize); if (!R_FINITE(mem)) error(_("incorrect argument")); #ifdef LEA_MALLOC #ifndef WIN64 if(mem >= 4096) error(_("don't be silly!: your machine has a 4Gb address limit")); #endif newmax = mem * 1048576.0; if (newmax < R_max_memory) warning(_("cannot decrease memory limit: ignored")); else R_max_memory = newmax; #endif } else error(_("incorrect argument")); PROTECT(ans = allocVector(REALSXP, 1)); #ifdef LEA_MALLOC if(maxmem == NA_LOGICAL) REAL(ans)[0] = R_max_memory; else if(maxmem) REAL(ans)[0] = mallinfo().usmblks; else REAL(ans)[0] = mallinfo().uordblks; REAL(ans)[0] /= 1048576.0; #else REAL(ans)[0] = NA_REAL; #endif UNPROTECT(1); return ans; } SEXP do_dllversion(SEXP call, SEXP op, SEXP args, SEXP rho) { SEXP path = R_NilValue, ans; const wchar_t *dll; DWORD dwVerInfoSize; DWORD dwVerHnd; checkArity(op, args); path = CAR(args); if(!isString(path) || LENGTH(path) != 1) errorcall(call, _("invalid '%s' argument"), "path"); dll = filenameToWchar(STRING_ELT(path, 0), FALSE); dwVerInfoSize = GetFileVersionInfoSizeW(dll, &dwVerHnd); PROTECT(ans = allocVector(STRSXP, 2)); SET_STRING_ELT(ans, 0, mkChar("")); SET_STRING_ELT(ans, 1, mkChar("")); if (dwVerInfoSize) { BOOL fRet; LPSTR lpstrVffInfo; LPSTR lszVer = NULL; UINT cchVer = 0; lpstrVffInfo = (LPSTR) malloc(dwVerInfoSize); if (GetFileVersionInfoW(dll, 0L, dwVerInfoSize, lpstrVffInfo)) { fRet = VerQueryValue(lpstrVffInfo, TEXT("\\StringFileInfo\\040904E4\\FileVersion"), (LPVOID)&lszVer, &cchVer); if(fRet) SET_STRING_ELT(ans, 0, mkChar(lszVer)); fRet = VerQueryValue(lpstrVffInfo, TEXT("\\StringFileInfo\\040904E4\\R Version"), (LPVOID)&lszVer, &cchVer); if(fRet) SET_STRING_ELT(ans, 1, mkChar(lszVer)); else { fRet = VerQueryValue(lpstrVffInfo, TEXT("\\StringFileInfo\\040904E4\\Compiled under R Version"), (LPVOID)&lszVer, &cchVer); if(fRet) SET_STRING_ELT(ans, 1, mkChar(lszVer)); } } else ans = R_NilValue; free(lpstrVffInfo); } else ans = R_NilValue; UNPROTECT(1); return ans; } int Rwin_rename(const char *from, const char *to) { return (MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH) == 0); } int Rwin_wrename(const wchar_t *from, const wchar_t *to) { return (MoveFileExW(from, to, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH) == 0); } const char *formatError(DWORD res) { static char buf[1000], *p; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 1000, NULL); p = buf+strlen(buf) -1; if(*p == '\n') *p = '\0'; p = buf+strlen(buf) -1; if(*p == '\r') *p = '\0'; p = buf+strlen(buf) -1; if(*p == '.') *p = '\0'; return buf; } void R_UTF8fixslash(char *s); /* from main/util.c */ SEXP do_normalizepath(SEXP call, SEXP op, SEXP args, SEXP rho) { SEXP ans, paths = CAR(args), el, slash; int i, n = LENGTH(paths), res; char tmp[MAX_PATH], longpath[MAX_PATH], *tmp2; wchar_t wtmp[32768], wlongpath[32768], *wtmp2; int mustWork, fslash = 0; checkArity(op, args); if(!isString(paths)) errorcall(call, _("'path' must be a character vector")); slash = CADR(args); if(!isString(slash) || LENGTH(slash) != 1) errorcall(call, "'winslash' must be a character string"); const char *sl = CHAR(STRING_ELT(slash, 0)); if (strcmp(sl, "/") && strcmp(sl, "\\")) errorcall(call, "'winslash' must be '/' or '\\\\'"); if (strcmp(sl, "/") == 0) fslash = 1; mustWork = asLogical(CADDR(args)); PROTECT(ans = allocVector(STRSXP, n)); for (i = 0; i < n; i++) { int warn = 0; SEXP result; el = STRING_ELT(paths, i); result = el; if(getCharCE(el) == CE_UTF8) { if ((res = GetFullPathNameW(filenameToWchar(el, FALSE), 32768, wtmp, &wtmp2)) && res <= 32768) { if ((res = GetLongPathNameW(wtmp, wlongpath, 32768)) && res <= 32768) { wcstoutf8(longpath, wlongpath, wcslen(wlongpath)+1); if(fslash) R_UTF8fixslash(longpath); result = mkCharCE(longpath, CE_UTF8); } else if(mustWork == 1) { errorcall(call, "path[%d]=\"%s\": %s", i+1, translateChar(el), formatError(GetLastError())); } else { wcstoutf8(tmp, wtmp, wcslen(wtmp)+1); if(fslash) R_UTF8fixslash(tmp); result = mkCharCE(tmp, CE_UTF8); warn = 1; } } else if(mustWork == 1) { errorcall(call, "path[%d]=\"%s\": %s", i+1, translateChar(el), formatError(GetLastError())); } else { if (fslash) { strcpy(tmp, translateCharUTF8(el)); R_UTF8fixslash(tmp); result = mkCharCE(tmp, CE_UTF8); } warn = 1; } if (warn && (mustWork == NA_LOGICAL)) warningcall(call, "path[%d]=\"%ls\": %s", i+1, filenameToWchar(el,FALSE), formatError(GetLastError())); } else { if ((res = GetFullPathName(translateChar(el), MAX_PATH, tmp, &tmp2)) && res <= MAX_PATH) { if ((res = GetLongPathName(tmp, longpath, MAX_PATH)) && res <= MAX_PATH) { if(fslash) R_fixslash(longpath); result = mkChar(longpath); } else if(mustWork == 1) { errorcall(call, "path[%d]=\"%s\": %s", i+1, translateChar(el), formatError(GetLastError())); } else { if(fslash) R_fixslash(tmp); result = mkChar(tmp); warn = 1; } } else if(mustWork == 1) { errorcall(call, "path[%d]=\"%s\": %s", i+1, translateChar(el), formatError(GetLastError())); } else { if (fslash) { strcpy(tmp, translateChar(el)); R_fixslash(tmp); result = mkChar(tmp); } warn = 1; } if (warn && (mustWork == NA_LOGICAL)) warningcall(call, "path[%d]=\"%s\": %s", i+1, translateChar(el), formatError(GetLastError())); } SET_STRING_ELT(ans, i, result); } UNPROTECT(1); return ans; }
int main() { LPWSTR *argv; int argc; argv = CommandLineToArgvW(GetCommandLineW(), &argc); if(argv == NULL) { error("Error parsing commandline options!\n"); } if(argc < 4) { error( "Usage: %S <options..>\n" "Options:\n" " --crt CreateRemoteThread injection\n" " --apc QueueUserAPC injection\n" " --free Do not inject our monitor\n" " --dll <dll> DLL to inject\n" " --app <app> Path to application to start\n" " --args <args> Command-line arguments\n" " Excluding the application path!\n" " --curdir <dirpath> Current working directory\n" " --maximize Maximize the newly created GUI\n" " --pid <pid> Process identifier to inject\n" " --process-name <name> Process name to inject\n" " --tid <tid> Thread identifier to inject\n" " --from <pid> Inject from another process\n" " --from-process <name> " "Inject from another process, resolves pid\n" " --only-start " "Start the application and print pid/tid\n" " --resume-thread " "Resume the thread of the pid/tid target\n" " --config <path> " "Configuration file for the monitor\n" " --dbg <path> " "Attach debugger to target process\n" " --dump <filepath> " "Dump process memory with --pid to filepath\n" " --verbose Verbose switch\n", argv[0] ); } const wchar_t *dll_path = NULL, *app_path = NULL, *arguments = L""; const wchar_t *config_file = NULL, *from_process = NULL, *dbg_path = NULL; const wchar_t *curdir = NULL, *process_name = NULL, *dump_path = NULL; uint32_t pid = 0, tid = 0, from = 0, inj_mode = INJECT_NONE; uint32_t show_window = SW_SHOWNORMAL, only_start = 0, resume_thread_ = 0; for (int idx = 1; idx < argc; idx++) { if(wcscmp(argv[idx], L"--crt") == 0) { inj_mode = INJECT_CRT; continue; } if(wcscmp(argv[idx], L"--apc") == 0) { inj_mode = INJECT_APC; continue; } if(wcscmp(argv[idx], L"--free") == 0) { inj_mode = INJECT_FREE; continue; } if(wcscmp(argv[idx], L"--dll") == 0) { dll_path = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--app") == 0) { app_path = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--args") == 0) { arguments = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--curdir") == 0) { curdir = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--maximize") == 0) { show_window = SW_MAXIMIZE; continue; } if(wcscmp(argv[idx], L"--pid") == 0) { pid = wcstol(argv[++idx], NULL, 10); continue; } if(wcscmp(argv[idx], L"--process-name") == 0) { process_name = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--tid") == 0) { tid = wcstol(argv[++idx], NULL, 10); continue; } if(wcscmp(argv[idx], L"--from") == 0) { from = wcstol(argv[++idx], NULL, 10); continue; } if(wcscmp(argv[idx], L"--from-process") == 0) { from_process = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--only-start") == 0) { only_start = 1; continue; } if(wcscmp(argv[idx], L"--resume-thread") == 0) { resume_thread_ = 1; continue; } if(wcscmp(argv[idx], L"--config") == 0) { config_file = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--dbg") == 0) { dbg_path = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--dump") == 0) { dump_path = argv[++idx]; continue; } if(wcscmp(argv[idx], L"--verbose") == 0) { verbose = 1; continue; } error("[-] Found unsupported argument: %S\n", argv[idx]); return 1; } // Dump memory of a process. if(dump_path != NULL && pid != 0) { dump(pid, dump_path); return 0; } if(inj_mode == INJECT_NONE) { error("[-] No injection method has been provided!\n"); } if(inj_mode == INJECT_CRT && pid == 0 && process_name == NULL && app_path == NULL) { error("[-] No injection target has been provided!\n"); } if(inj_mode == INJECT_APC && tid == 0 && process_name == NULL && app_path == NULL) { error("[-] No injection target has been provided!\n"); } if(inj_mode == INJECT_FREE && app_path == NULL) { error("[-] An app path is required when not injecting!\n"); } if(pid != 0 && process_name != NULL) { error("[-] Both pid and process-name were set!\n"); } static wchar_t dllpath[MAX_PATH_W]; if(inj_mode == INJECT_FREE) { if(dll_path != NULL || tid != 0 || pid != 0) { error("[-] Unused --tid/--pid/--dll provided in --free mode!\n"); } } if(inj_mode != INJECT_FREE) { if(PathFileExistsW(dll_path) == FALSE) { error("[-] Invalid DLL filepath has been provided\n"); } if(GetFullPathNameW(dll_path, MAX_PATH_W, dllpath, NULL) == 0) { error("[-] Invalid DLL filepath has been provided\n"); } if(GetLongPathNameW(dllpath, dllpath, MAX_PATH_W) == 0) { error("[-] Error obtaining the dll long path name\n"); } } if(from != 0 && from_process != NULL) { error("[-] Both --from and --from-process are specified\n"); } grant_debug_privileges(GetCurrentProcessId()); if(app_path != NULL) { // If a process name has been provided as source process, then find // its process identifier (or first, if multiple). if(from_process != NULL) { from = pid_from_process_name(from_process); } // If no source process has been specified, then we use our // own process. if(from == 0) { from = GetCurrentProcessId(); } if(PathFileExistsW(app_path) == FALSE) { error("[-] Invalid app filepath has been provided\n"); } static wchar_t dirpath[MAX_PATH_W], filepath[MAX_PATH_W]; // If a current working directory has been set then we use that // current working directory. Otherwise default to $TEMP. if(curdir != NULL) { // Allow the current working directory to be // specified as, e.g., %TEMP%. if(ExpandEnvironmentStringsW(curdir, dirpath, MAX_PATH_W) == 0) { error("[-] Error expanding environment variables\n"); } curdir = dirpath; } else { // We don't want to be expanding the environment variable buffer // as that will probably corrupt the heap or so. curdir = wcscpy(dirpath, _wgetenv(L"TEMP")); } if(GetLongPathNameW(dirpath, dirpath, MAX_PATH_W) == 0) { error("[-] Error obtaining the curdir long path name\n"); } if(GetFullPathNameW(app_path, MAX_PATH_W, filepath, NULL) == 0) { error("[-] Invalid app filepath has been provided\n"); } if(GetLongPathNameW(filepath, filepath, MAX_PATH_W) == 0) { error("[-] Error obtaining the app long path name\n"); } pid = start_app(from, filepath, arguments, curdir, &tid, show_window); } if(pid == 0 && process_name != NULL) { pid = pid_from_process_name(process_name); } // Drop the configuration file if available. if(config_file != NULL) { static wchar_t filepath[MAX_PATH_W]; wsprintfW(filepath, L"C:\\cuckoo_%d.ini", pid); if(MoveFileW(config_file, filepath) == FALSE) { error("[-] Error dropping configuration file: %ld\n", GetLastError()); } } // Do not do actual injection here, just have the application launched. if(only_start != 0) { printf("%d %d", pid, tid); return 0; } switch (inj_mode) { case INJECT_CRT: load_dll_crt(pid, dllpath); break; case INJECT_APC: load_dll_apc(pid, tid, dllpath); break; case INJECT_FREE: break; default: error("[-] Unhandled injection mode: %d\n", inj_mode); } if(dbg_path != NULL) { wchar_t buf[1024]; wsprintfW(buf, L"\"%s\" -p %d", dbg_path, pid); start_app(GetCurrentProcessId(), dbg_path, buf, NULL, NULL, SW_SHOWNORMAL); Sleep(5000); } if((app_path != NULL || resume_thread_ != 0) && tid != 0) { resume_thread(tid); } // Report the process identifier. printf("%d", pid); return 0; }
void PolycodePlayer::loadFile(const char *fileName) { FILE *t = fopen("C:\\out.txt", "a"); fwrite(fileName, strlen(fileName), 1, t); fclose(t); String mainFile = ""; String basePath = fileName; Number red = 0.2f; Number green = 0.2f; Number blue = 0.2f; frameRate = 60; Object configFile; String nameString = fileName; bool loadingArchive = false; if(nameString != "") { String ext = nameString.substr(nameString.length() - 8, nameString.length()); Logger::log("Loading %s\n", fileName); String configPath; if(ext == ".polyapp" || _knownArchive) { ResourceManager *rman = CoreServices::getInstance()->getResourceManager(); rman->addArchive(nameString); configPath = "runinfo.polyrun"; loadingArchive = true; Logger::log("Reading configuration from POLYAPP file... (%s)\n", nameString.c_str()); } else { ResourceManager *rman = CoreServices::getInstance()->getResourceManager(); String fileDir = ""; vector<String> bits = String(fileName).split("/"); for(int i=0; i < bits.size()-1; i++) { fileDir += "/"+bits[i]; } rman->addArchive(fileDir); configPath = fileName; Logger::log("Reading configuration from .polycode file directly... (%s)\n", fileName); } if(!configFile.loadFromXML(configPath)) { Logger::log("Error loading config file\n"); } else { if(configFile.root["entryPoint"]) { mainFile = configFile.root["entryPoint"]->stringVal; } if(configFile.root["defaultWidth"]) { xRes = configFile.root["defaultWidth"]->intVal; } if(configFile.root["defaultHeight"]) { yRes = configFile.root["defaultHeight"]->intVal; } if(configFile.root["frameRate"]) { frameRate = configFile.root["frameRate"]->intVal; } if(configFile.root["antiAliasingLevel"]) { aaLevel = configFile.root["antiAliasingLevel"]->intVal; } if(configFile.root["fullScreen"]) { fullScreen = configFile.root["fullScreen"]->boolVal; } if(configFile.root["backgroundColor"]) { ObjectEntry *color = configFile.root["backgroundColor"]; if((*color)["red"] && (*color)["green"] && (*color)["blue"]) { red = (*color)["red"]->NumberVal; green = (*color)["green"]->NumberVal; blue = (*color)["blue"]->NumberVal; } } ObjectEntry *modules = configFile.root["modules"]; if(modules) { for(int i=0; i < modules->length; i++) { String moduleName = (*modules)[i]->stringVal; Logger::log("Loading module: %s\n", moduleName.c_str()); #ifdef _WINDOWS TCHAR _tempPath[4098]; TCHAR tempPath[4098]; GetTempPathW(4098, _tempPath); GetLongPathNameW(_tempPath, tempPath, 4098); String moduleDestPath = String(tempPath) + String("\\") + moduleName+ String(".dll"); String moduleFileName = String("__lib/win/") + moduleName+ String(".dll"); #else String moduleFileName = String("__lib/osx/") + moduleName+ String(".dylib"); String moduleDestPath = String("/tmp/") + moduleName+ String(".dylib"); #endif OSFILE *inFile = OSBasics::open(moduleFileName, "rb"); if(inFile) { OSBasics::seek(inFile, 0, SEEK_END); long progsize = OSBasics::tell(inFile); OSBasics::seek(inFile, 0, SEEK_SET); char *buffer = (char*)malloc(progsize+1); memset(buffer, 0, progsize+1); OSBasics::read(buffer, progsize, 1, inFile); OSFILE *outFile = OSBasics::open(moduleDestPath, "wb"); OSBasics::write(buffer, progsize, 1, outFile); OSBasics::close(outFile); free(buffer); OSBasics::close(inFile); loadedModules.push_back(moduleName); } else { Logger::log("Error loading module: %s\n", (*modules)[i]->stringVal.c_str()); } } } } Logger::log("Mainfile: %s\n", mainFile.c_str()); PolycodeDebugEvent *event = new PolycodeDebugEvent(); event->xRes = xRes; event->yRes = yRes; } createCore(); if(nameString == "") { return; } Logger::log("Core created...\n"); CoreServices::getInstance()->getResourceManager()->addArchive("api.pak"); if(configFile.root["packedItems"]) { ObjectEntry *packed = configFile.root["packedItems"]; if(packed) { for(int i=0; i < packed->length; i++) { ObjectEntry *entryIsResource = (*(*packed)[i])["isResource"]; ObjectEntry *entryPath = (*(*packed)[i])["path"]; if(entryIsResource && entryPath) { if(entryIsResource->boolVal == true) { CoreServices::getInstance()->getResourceManager()->addDirResource(entryPath->stringVal, true); } } } } } core->setUserPointer(this); //core->addEventListener(this, Core::EVENT_CORE_RESIZE); core->setVideoMode(xRes, yRes, fullScreen, aaLevel); CoreServices::getInstance()->getResourceManager()->addArchive("default.pak"); CoreServices::getInstance()->getResourceManager()->addDirResource("default", false); // dispatchEvent(event, PolycodeDebugEvent::EVENT_RESIZE); CoreServices::getInstance()->getRenderer()->setClearColor(red, green, blue); // CoreServices::getInstance()->getRenderer()->setClearColor(1,0,0); srand(core->getTicks()); String fullPath; if(loadingArchive) { fullPath = mainFile; } else { int lindex = basePath.find_last_of("/"); fullPath = basePath.substr(0, lindex); fullPath += mainFile; Logger::log(fullPath.c_str()); } runFile(fullPath); }
void PolycodePlayer::runFile(String fileName) { Logger::log("Running %s\n", fileName.c_str()); L=lua_open(); /* luaopen_base(L); // load basic libs (eg. print) luaopen_math(L); luaopen_table(L); luaopen_package(L); */ luaL_openlibs(L); luaopen_Polycode(L); //luaopen_Tau(L); // load the wrappered module lua_getfield(L, LUA_GLOBALSINDEX, "package"); // push "package" lua_getfield(L, -1, "loaders"); // push "package.loaders" lua_remove(L, -2); // remove "package" // Count the number of entries in package.loaders. // Table is now at index -2, since 'nil' is right on top of it. // lua_next pushes a key and a value onto the stack. int numLoaders = 0; lua_pushnil(L); while (lua_next(L, -2) != 0) { lua_pop(L, 1); numLoaders++; } lua_pushinteger(L, numLoaders + 1); lua_pushcfunction(L, MyLoader); lua_rawset(L, -3); // Table is still on the stack. Get rid of it now. lua_pop(L, 1); lua_register(L, "debugPrint", debugPrint); lua_getfield(L, LUA_GLOBALSINDEX, "require"); lua_pushstring(L, "class"); lua_call(L, 1, 0); lua_getfield(L, LUA_GLOBALSINDEX, "require"); lua_pushstring(L, "Polycode"); lua_call(L, 1, 0); lua_getfield(L, LUA_GLOBALSINDEX, "require"); lua_pushstring(L, "defaults"); lua_call(L, 1, 0); for(int i=0; i < loadedModules.size(); i++) { String moduleName = loadedModules[i]; #ifdef _WINDOWS TCHAR _tempPath[4098]; TCHAR tempPath[4098]; GetTempPathW(4098, _tempPath); GetLongPathNameW(_tempPath, tempPath, 4098); String moduleDestPath = String(tempPath) + String("\\") + moduleName+ String(".dll"); #else String moduleDestPath = String("/tmp/") + moduleName+ String(".dylib"); #endif String moduleLoadCall = String("luaopen_") + moduleName; lua_getfield(L, LUA_GLOBALSINDEX, "require"); lua_pushstring(L, moduleName.c_str()); lua_call(L, 1, 0); lua_getfield(L, LUA_GLOBALSINDEX, "package"); lua_getfield(L, -1, "loadlib"); lua_pushstring(L, moduleDestPath.c_str()); lua_pushstring(L, moduleLoadCall.c_str()); lua_call(L, 2, 1); lua_setfield(L, LUA_GLOBALSINDEX, "f"); lua_getfield(L, LUA_GLOBALSINDEX, "f"); lua_getfield(L, LUA_GLOBALSINDEX, "__core__services__instance"); lua_call(L, 1, 0); //local f = package.loadlib("/Users/ivansafrin/Desktop/Workshop/HelloPolycodeLUA/libPolycode2DPhysicsModule.dylib", "luaopen_Physics2D") //f(Polycore.CoreServices_getInstance()) } String fileData = ""; OSFILE *inFile = OSBasics::open(fileName, "r"); if(inFile) { Logger::log("Opened entrypoint file..."); OSBasics::seek(inFile, 0, SEEK_END); long progsize = OSBasics::tell(inFile); OSBasics::seek(inFile, 0, SEEK_SET); char *buffer = (char*)malloc(progsize+1); memset(buffer, 0, progsize+1); OSBasics::read(buffer, progsize, 1, inFile); fileData = String(buffer); free(buffer); OSBasics::close(inFile); } else { Logger::log("Error opening entrypoint file (%s)\n", fileName.c_str()); } String postpend = ""; //" \nif update == nil then\nfunction update(e)\nend\nend\nwhile CORE:Update() do\nupdate(CORE:getElapsed())\nend"; //String fullScript = prepend + prepend2 + prepend3 + fileData;// + postpend; String fullScript = fileData; //String fullScript = fileData;// + postpend; doneLoading = true; //lua_gc(L, LUA_GCSTOP, 0); /* lua_pushliteral(L, "debug"); lua_gettable(L, LUA_GLOBALSINDEX); lua_pushliteral(L, "traceback"); // correct fn name? lua_gettable(L, -2); */ //CoreServices::getInstance()->getCore()->lockMutex(CoreServices::getRenderMutex()); if (report(L, luaL_loadstring(L, fullScript.c_str()) || lua_pcall(L, 0,0,0))) { //CoreServices::getInstance()->getCore()->unlockMutex(CoreServices::getRenderMutex()); Logger::log("CRASH LOADING SCRIPT FILE\n"); // exit(1); } else { // CoreServices::getInstance()->getCore()->unlockMutex(CoreServices::getRenderMutex()); if (report(L, luaL_loadstring(L, postpend.c_str()) || lua_pcall(L, 0,0,0))) { // exit(1); Logger::log("CRASH IN SCRIPT EXECUTION FILE\n"); } else { } } }
void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, uv_fs_event_t* handle) { FILE_NOTIFY_INFORMATION* file_info; int err, sizew, size, result; char* filename = NULL; WCHAR* filenamew, *long_filenamew = NULL; DWORD offset = 0; assert(req->type == UV_FS_EVENT_REQ); assert(handle->req_pending); handle->req_pending = 0; /* Don't report any callbacks if: * - We're closing, just push the handle onto the endgame queue * - We are not active, just ignore the callback */ if (!uv__is_active(handle)) { if (handle->flags & UV__HANDLE_CLOSING) { uv_want_endgame(loop, (uv_handle_t*) handle); } return; } file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset); if (REQ_SUCCESS(req)) { if (req->u.io.overlapped.InternalHigh > 0) { do { file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset); assert(!filename); assert(!long_filenamew); /* * Fire the event only if we were asked to watch a directory, * or if the filename filter matches. */ if (handle->dirw || _wcsnicmp(handle->filew, file_info->FileName, file_info->FileNameLength / sizeof(WCHAR)) == 0 || _wcsnicmp(handle->short_filew, file_info->FileName, file_info->FileNameLength / sizeof(WCHAR)) == 0) { if (handle->dirw) { /* * We attempt to resolve the long form of the file name explicitly. * We only do this for file names that might still exist on disk. * If this fails, we use the name given by ReadDirectoryChangesW. * This may be the long form or the 8.3 short name in some cases. */ if (file_info->Action != FILE_ACTION_REMOVED && file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) { /* Construct a full path to the file. */ size = wcslen(handle->dirw) + file_info->FileNameLength / sizeof(WCHAR) + 2; filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); if (!filenamew) { uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw, file_info->FileNameLength / sizeof(WCHAR), file_info->FileName); filenamew[size - 1] = L'\0'; /* Convert to long name. */ size = GetLongPathNameW(filenamew, NULL, 0); if (size) { long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); if (!long_filenamew) { uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } size = GetLongPathNameW(filenamew, long_filenamew, size); if (size) { long_filenamew[size] = '\0'; } else { uv__free(long_filenamew); long_filenamew = NULL; } } uv__free(filenamew); if (long_filenamew) { /* Get the file name out of the long path. */ result = uv_relative_path(long_filenamew, handle->dirw, &filenamew); uv__free(long_filenamew); if (result == 0) { long_filenamew = filenamew; sizew = -1; } else { long_filenamew = NULL; } } /* * We could not resolve the long form explicitly. * We therefore use the name given by ReadDirectoryChangesW. * This may be the long form or the 8.3 short name in some cases. */ if (!long_filenamew) { filenamew = file_info->FileName; sizew = file_info->FileNameLength / sizeof(WCHAR); } } else { /* * Removed or renamed events cannot be resolved to the long form. * We therefore use the name given by ReadDirectoryChangesW. * This may be the long form or the 8.3 short name in some cases. */ if (!long_filenamew) { filenamew = file_info->FileName; sizew = file_info->FileNameLength / sizeof(WCHAR); } } } else { /* We already have the long name of the file, so just use it. */ filenamew = handle->filew; sizew = -1; } if (filenamew) { /* Convert the filename to utf8. */ size = uv_utf16_to_utf8(filenamew, sizew, NULL, 0); if (size) { filename = (char*)uv__malloc(size + 1); if (!filename) { uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } size = uv_utf16_to_utf8(filenamew, sizew, filename, size); if (size) { filename[size] = '\0'; } else { uv__free(filename); filename = NULL; } } } switch (file_info->Action) { case FILE_ACTION_ADDED: case FILE_ACTION_REMOVED: case FILE_ACTION_RENAMED_OLD_NAME: case FILE_ACTION_RENAMED_NEW_NAME: handle->cb(handle, filename, UV_RENAME, 0); break; case FILE_ACTION_MODIFIED: handle->cb(handle, filename, UV_CHANGE, 0); break; } uv__free(filename); filename = NULL; uv__free(long_filenamew); long_filenamew = NULL; } offset = file_info->NextEntryOffset; } while (offset && !(handle->flags & UV__HANDLE_CLOSING)); } else { handle->cb(handle, NULL, UV_CHANGE, 0); } } else { err = GET_REQ_ERROR(req); handle->cb(handle, NULL, 0, uv_translate_sys_error(err)); } if (!(handle->flags & UV__HANDLE_CLOSING)) { uv_fs_event_queue_readdirchanges(loop, handle); } else { uv_want_endgame(loop, (uv_handle_t*)handle); } }
/* Wrapper for Windows stat function, which provides st_dev and st_ino. These are calculated as follows: st_dev is set to the drive number (0=A 1=B ...). Our virtual root "/" gets a st_dev of 0xff. st_ino is hashed from the full file path. Each half produces a 32 bit hash. These are concatenated to a 64 bit value. The risk that st_ino is the same for two files on the system is, if I'm not mistaken, b=pigeon(2**32, f)**2. For f=1000, b=1e-08. By using a 64 bit hash function this risk can be lowered. Possible future enhancement. pigeon() can be calculated in Python with: def pigeon(m, n): res = 1.0 for i in range(m - n + 1, m): res = res * i / m return 1 - res */ int win_stat(const char *file_name, backend_statstruct * buf) { wchar_t *winpath; int ret; wchar_t pathbuf[4096]; int retval; size_t namelen; wchar_t *splitpoint; char savedchar; struct _stat win_statbuf; /* Special case: Our top-level virtual root, containing each drive represented as a directory. Compare with "My Computer" etc. This virtual root has a hardcoded hash value of 1, to simplify debugging etc. */ if (!strcmp(file_name, "/")) { buf->st_mode = S_IFDIR | S_IRUSR | S_IWUSR; buf->st_nlink = MAX_NUM_DRIVES + 3; /* 3 extra for: . .. / */ buf->st_uid = 1; buf->st_gid = 1; buf->st_rdev = 0; buf->st_size = 4096; buf->st_atime = 0; buf->st_mtime = 0; buf->st_ctime = 0; buf->st_dev = 0xff; buf->st_ino = 1; return 0; } winpath = intpath2winpath(file_name); if (!winpath) { errno = EINVAL; return -1; } ret = _wstat(winpath, &win_statbuf); if (ret < 0) { free(winpath); return ret; } /* Copy values to our struct */ buf->st_mode = win_statbuf.st_mode; buf->st_nlink = win_statbuf.st_nlink; buf->st_uid = win_statbuf.st_uid; buf->st_gid = win_statbuf.st_gid; buf->st_rdev = win_statbuf.st_rdev; buf->st_size = win_statbuf.st_size; buf->st_atime = win_statbuf.st_atime; buf->st_mtime = win_statbuf.st_mtime; buf->st_ctime = win_statbuf.st_ctime; buf->st_blocks = win_statbuf.st_size / 512; retval = GetFullPathNameW(winpath, wsizeof(pathbuf), pathbuf, NULL); if (!retval) { errno = ENOENT; return -1; } /* Set st_dev to the drive number */ buf->st_dev = tolower(pathbuf[0]) - 'a'; /* GetLongPathName fails if called with only x:\, and drive x is not ready. So, only call it for other paths. */ if (pathbuf[0] && wcscmp(pathbuf + 1, L":\\")) { retval = GetLongPathNameW(pathbuf, pathbuf, wsizeof(pathbuf)); if (!retval || (unsigned) retval > wsizeof(pathbuf)) { /* Strangely enough, GetLongPathName returns ERROR_SHARING_VIOLATION for locked files, such as hiberfil.sys */ if (GetLastError() != ERROR_SHARING_VIOLATION) { errno = ENAMETOOLONG; return -1; } } } /* Hash st_ino, by splitting in two halves */ namelen = wcslen(pathbuf); splitpoint = &pathbuf[namelen / 2]; savedchar = *splitpoint; *splitpoint = '\0'; buf->st_ino = wfnv1a_32(pathbuf, 0); assert(sizeof(buf->st_ino) == 8); buf->st_ino = buf->st_ino << 32; *splitpoint = savedchar; buf->st_ino |= wfnv1a_32(splitpoint, 0); #if 0 fprintf(stderr, "win_stat: file=%s, ret=%d, st_dev=0x%x, st_ino=0x%I64x\n", file_name, ret, buf->st_dev, buf->st_ino); #endif free(winpath); return ret; }
/* * argv parsing. * Parse the argv[0] and split to ExePath and * Executable name. Strip the extension ('.exe'). * Check for command in argv[1] //CMD//Application * Parse the options --option value or --option==value * break on first argument that doesn't start with '--' */ LPAPXCMDLINE apxCmdlineParse( APXHANDLE hPool, APXCMDLINEOPT *lpOptions, LPCWSTR *lpszCommands, LPCWSTR *lpszAltcmds) { LPAPXCMDLINE lpCmdline = NULL; DWORD l, i, s = 1; LPWSTR p; DWORD match; WCHAR mh[SIZ_HUGLEN]; if (_st_sys_argc < 1) return NULL; if (!(lpCmdline = (LPAPXCMDLINE)apxPoolCalloc(hPool, sizeof(APXCMDLINE)))) return NULL; lpCmdline->hPool = hPool; lpCmdline->lpOptions = lpOptions; if (GetModuleFileNameW(GetModuleHandle(NULL), mh, SIZ_HUGLEN)) { GetLongPathNameW(mh, mh, SIZ_HUGLEN); lpCmdline->szExePath = apxPoolStrdupW(hPool, mh); lpCmdline->szArgv0 = apxPoolStrdupW(hPool, mh); if (lpCmdline->szExePath == NULL || lpCmdline->szArgv0 == NULL) return NULL; if ((p = wcsrchr(lpCmdline->szExePath, L'\\'))) *p++ = L'\0'; else return NULL; } else return NULL; lpCmdline->szExecutable = p; p = wcsrchr(lpCmdline->szExecutable, L'.'); if (p && lstrcmpiW(p, EXE_SUFFIX) == 0) *p = L'\0'; if ((p = wcsrchr(lpCmdline->szExecutable, L'.'))) { if (lstrcmpiW(p, X86_SUFFIX) == 0) { *p = L'\0'; } else if (lstrcmpiW(p, X64_SUFFIX) == 0) { *p = L'\0'; } else if (lstrcmpiW(p, A64_SUFFIX) == 0) { *p = L'\0'; } } if (_st_sys_argc > 1 && lstrlenW(_st_sys_argvw[1]) > 2) { LPWSTR cp = _st_sys_argvw[1]; LPWSTR cn = _st_sys_argc > 2 ? _st_sys_argvw[2] : NULL; LPWSTR ca = cp; i = 0; if (ca[0] == L'/' && ca[1] == L'/') { ca += 2; if ((cn = wcschr(ca, L'/'))) { *cn++ = L'\0'; while (*cn == L'/') cn++; if (*cn == L'\0') cn = NULL; } if (cn == NULL) cn = lpCmdline->szExecutable; while (lpszCommands[i]) { if (lstrcmpW(lpszCommands[i++], ca) == 0) { lpCmdline->dwCmdIndex = i; break; } } if (lpCmdline->dwCmdIndex) { lpCmdline->szApplication = cn; s = 2; } else { apxLogWrite(APXLOG_MARK_ERROR "Unrecognized cmd option %S", cp); return NULL; } } else { while (lpszAltcmds[i]) { if (lstrcmpW(lpszAltcmds[i++], ca) == 0) { lpCmdline->dwCmdIndex = i; break; } } if (lpCmdline->dwCmdIndex) { s = 2; if (cn && iswalnum(*cn)) { s++; lpCmdline->szApplication = cn; } else lpCmdline->szApplication = lpCmdline->szExecutable; } else { apxLogWrite(APXLOG_MARK_ERROR "Unrecognized cmd option %S", cp); return NULL; } } } else { lpCmdline->szApplication = lpCmdline->szExecutable; lpCmdline->dwCmdIndex = 1; return lpCmdline; } for (i = s; i < (DWORD)_st_sys_argc; i++) { LPWSTR e = NULL; LPWSTR a = _st_sys_argvw[i]; BOOL add = FALSE; if (a[0] == L'+' && a[1] == L'+') add = TRUE; else if (a[0] != L'-' || a[1] != L'-') break; p = a + 2; /* Find if the option has '=' char * for --option==value or --option value cases. */ while (*p) { if (*p == L'=') { *p = L'\0'; e = p + 1; break; } else p++; } match = 0; for (l = 0; lpOptions[l].szName; l++) { if (lstrcmpW(lpOptions[l].szName, a + 2) == 0) { LPWSTR val; /* check if arg is needed */ if (e) val = e; else if ((i + 1) < (DWORD)_st_sys_argc) val = _st_sys_argvw[++i]; else { lpOptions[l].dwValue = 0; lpOptions[l].szValue = NULL; lpOptions[l].dwType |= APXCMDOPT_FOUND; break; } if (add) { if (!(lpOptions[l].dwType & APXCMDOPT_FOUND)) { /* Only set add flag in case there was no --option */ lpOptions[l].dwType |= APXCMDOPT_ADD; } } else if (lpOptions[l].dwType & APXCMDOPT_ADD) { /* We have ++option --option ... * Discard earlier values and go over. */ lpOptions[l].dwType &= ~APXCMDOPT_ADD; lpOptions[l].dwValue = 0; lpOptions[l].szValue = 0; } if (lpOptions[l].dwType & APXCMDOPT_STR) lpOptions[l].szValue = val; else if (lpOptions[l].dwType & APXCMDOPT_INT) lpOptions[l].dwValue = (DWORD)apxAtoulW(val); else if (lpOptions[l].dwType & APXCMDOPT_MSZ) { LPWSTR pp; BOOL insquote = FALSE, indquote=FALSE; DWORD sp = 0; LPWSTR ov = lpOptions[l].szValue; if (lpOptions[l].dwValue > 2) { sp = (lpOptions[l].dwValue - sizeof(WCHAR)) / sizeof(WCHAR); } lpOptions[l].dwValue = (sp + lstrlenW(val) + 2) * sizeof(WCHAR); lpOptions[l].szValue = (LPWSTR)apxPoolCalloc(hPool, lpOptions[l].dwValue); if (sp) { AplMoveMemory(lpOptions[l].szValue, ov, sp * sizeof(WCHAR)); apxFree(ov); } pp = val; while(*pp) { if (*pp == L'\'') insquote = !insquote; else if (*pp == L'"') { indquote = !indquote; lpOptions[l].szValue[sp++] = L'"'; } else if ((*pp == L'#' || *pp == L';') && !insquote && !indquote) lpOptions[l].szValue[sp++] = L'\0'; else lpOptions[l].szValue[sp++] = *pp; pp++; } } lpOptions[l].dwType |= APXCMDOPT_FOUND; match = l + 1; break; } } if (match == 0) { /* --unknown option * */ apxLogWrite(APXLOG_MARK_ERROR "Unrecognized program option %S", _st_sys_argvw[i]); return NULL; } } if (i < (DWORD)_st_sys_argc) { lpCmdline->dwArgc = _st_sys_argc - i; lpCmdline->lpArgvw = &_st_sys_argvw[i]; } return lpCmdline; }
std::string ResolvePath(const std::string &path) { #ifdef _WIN32 typedef DWORD (WINAPI *getFinalPathNameByHandleW_f)(HANDLE hFile, LPWSTR lpszFilePath, DWORD cchFilePath, DWORD dwFlags); static getFinalPathNameByHandleW_f getFinalPathNameByHandleW = nullptr; #if PPSSPP_PLATFORM(UWP) getFinalPathNameByHandleW = &GetFinalPathNameByHandleW; #else if (!getFinalPathNameByHandleW) { HMODULE kernel32 = GetModuleHandle(L"kernel32.dll"); getFinalPathNameByHandleW = (getFinalPathNameByHandleW_f)GetProcAddress(kernel32, "GetFinalPathNameByHandleW"); } #endif static const int BUF_SIZE = 32768; wchar_t *buf = new wchar_t[BUF_SIZE]; memset(buf, 0, BUF_SIZE); std::wstring input = ConvertUTF8ToWString(path); if (getFinalPathNameByHandleW) { #if PPSSPP_PLATFORM(UWP) HANDLE hFile = CreateFile2(input.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr); #else HANDLE hFile = CreateFile(input.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); #endif if (hFile == INVALID_HANDLE_VALUE) { wcscpy_s(buf, BUF_SIZE - 1, input.c_str()); } else { int result = getFinalPathNameByHandleW(hFile, buf, BUF_SIZE - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); if (result >= BUF_SIZE || result == 0) wcscpy_s(buf, BUF_SIZE - 1, input.c_str()); CloseHandle(hFile); } } else { wchar_t *longBuf = new wchar_t[BUF_SIZE]; memset(buf, 0, BUF_SIZE); int result = GetLongPathNameW(input.c_str(), longBuf, BUF_SIZE - 1); if (result >= BUF_SIZE || result == 0) wcscpy_s(longBuf, BUF_SIZE - 1, input.c_str()); result = GetFullPathNameW(longBuf, BUF_SIZE - 1, buf, nullptr); if (result >= BUF_SIZE || result == 0) wcscpy_s(buf, BUF_SIZE - 1, input.c_str()); delete [] longBuf; // Normalize slashes just in case. for (int i = 0; i < BUF_SIZE; ++i) { if (buf[i] == '\\') buf[i] = '/'; } } // Undo the \\?\C:\ syntax that's normally returned. std::string output = ConvertWStringToUTF8(buf); if (buf[0] == '\\' && buf[1] == '\\' && buf[2] == '?' && buf[3] == '\\' && isalpha(buf[4]) && buf[5] == ':') output = output.substr(4); delete [] buf; return output; #else std::unique_ptr<char[]> buf(new char[PATH_MAX + 32768]); if (realpath(path.c_str(), buf.get()) == nullptr) return path; return buf.get(); #endif }