static void readdir(const pal::string_t& path, const pal::string_t& pattern, bool onlydirectories, std::vector<pal::string_t>* list) { assert(list != nullptr); std::vector<pal::string_t>& files = *list; pal::string_t normalized_path(path); if (LongFile::ShouldNormalize(normalized_path)) { if (!pal::realpath(&normalized_path)) { return; } } pal::string_t search_string(normalized_path); append_path(&search_string, pattern.c_str()); WIN32_FIND_DATAW data = { 0 }; auto handle = ::FindFirstFileExW(search_string.c_str(), FindExInfoStandard, &data, FindExSearchNameMatch, NULL, 0); if (handle == INVALID_HANDLE_VALUE) { return; } do { if (!onlydirectories || (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { pal::string_t filepath(data.cFileName); if (filepath != _X(".") && filepath != _X("..")) { files.push_back(filepath); } } } while (::FindNextFileW(handle, &data)); ::FindClose(handle); }
IResFile* gkResFileManager::CreateFileInternal( TCHAR * szExecRelativePath, bool loadheader ) { gkStdString normalized_path(szExecRelativePath); gkNormalizeResName( normalized_path ); { gkAutoLock<gkCritcalSectionLock> lock(eLGID_global, eLID_resfile_close); ResFileMap::iterator it = m_mapFiles.find( normalized_path.c_str() ); if (it != m_mapFiles.end()) { it->second->AddRef(); return it->second; } } TCHAR szFullPath[MAX_PATH]; _tcscpy( szFullPath, gkGetExecRootDir().c_str() ); _tcscat( szFullPath, normalized_path.c_str() ); gkResFile* pNewfile = NULL; bool pakPriority = false; if ( g_pSystemCVars->sys_loadPakFirst && !gEnv->pSystem->IsEditor() ) { // 如果打开优先从PAK读取,且不是编辑器模式 [3/7/2013 Kaiming] pakPriority = true; } if (pakPriority) { pNewfile = new gkResFile( normalized_path.c_str(), loadheader ); } else { pNewfile = new gkResFile( szFullPath, loadheader ); } if (!pNewfile->IsOpen()) { SAFE_DELETE( pNewfile ); // 如果pak / file 不存在,反向读取 if (pakPriority) { pNewfile = new gkResFile( szFullPath, loadheader ); } else { pNewfile = new gkResFile( normalized_path.c_str(), loadheader ); } // 还是失败,打开错误 if (!pNewfile->IsOpen()) { gkLogError( _T("Loading File %s Failed."), normalized_path.c_str() ); SAFE_DELETE( pNewfile ); return NULL; } } // file opened { gkAutoLock<gkCritcalSectionLock> lock(eLGID_global, eLID_resfile_close); pNewfile->AddRef(); m_mapFiles.insert( ResFileMap::value_type( normalized_path.c_str(), pNewfile ) ); } return pNewfile; }
static void test_path_normalization(void) { static const char *abs_input[] = { "/", "///", "/dir1", "///dir1", "/dir1/", "/dir1/dir2", "/dir1///dir2", "/dir1/dir2/", "/dir1/./dir2/././dir3", "/dir1/dir2/.", "/dir1/dir2/./", "/dir1/dir2/..", "/dir1/dir2/../", "/dir1/dir2/dir3/../dir4", "/dir1/dir2/dir3/../dir4/", "/dir1/dir2/dir3/../../../../../dir4", "/dir1/dir2/dir3/../../../../../dir4/", "/../../dir1", NULL }; static const char *abs_expected[] = { "/", "/", "/dir1", "/dir1", "/dir1", "/dir1/dir2", "/dir1/dir2", "/dir1/dir2", "/dir1/dir2/dir3", "/dir1/dir2", "/dir1/dir2", "/dir1", "/dir1", "/dir1/dir2/dir4", "/dir1/dir2/dir4", "/dir4", "/dir4", "/dir1", NULL }; int i; g_assert(normalized_path(NULL) == NULL); g_assert(normalized_path("not/absolute") == NULL); for (i = 0; abs_input[i]; i++) { gchar *result = normalized_path(abs_input[i]); g_assert_cmpstr(result, ==, abs_expected[i]); g_free(result); } }