bool CLangPage::OnInit() { LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); _langCombo.Attach(GetItem(IDC_LANG_LANG)); UString temp = MyLoadString(IDS_LANG_ENGLISH); NativeLangString(temp, MyLoadString(IDS_LANG_NATIVE)); int index = (int)_langCombo.AddString(temp); _langCombo.SetItemData(index, _paths.Size()); _paths.Add(L"-"); _langCombo.SetCurSel(0); const FString dirPrefix = GetLangDirPrefix(); NFile::NFind::CEnumerator enumerator(dirPrefix + FTEXT("*.txt")); NFile::NFind::CFileInfo fi; CLang lang; UString error; while (enumerator.Next(fi)) { if (fi.IsDir()) continue; const int kExtSize = 4; if (fi.Name.Len() < kExtSize) continue; unsigned pos = fi.Name.Len() - kExtSize; if (!StringsAreEqualNoCase_Ascii(fi.Name.Ptr(pos), ".txt")) continue; if (!LangOpen(lang, dirPrefix + fi.Name)) { if (!error.IsEmpty()) error += L' '; error += fs2us(fi.Name); continue; } const UString shortName = fs2us(fi.Name.Left(pos)); UString s = shortName; const wchar_t *eng = lang.Get(IDS_LANG_ENGLISH); if (eng) s = eng; const wchar_t *native = lang.Get(IDS_LANG_NATIVE); if (native) NativeLangString(s, native); index = (int)_langCombo.AddString(s); _langCombo.SetItemData(index, _paths.Size()); _paths.Add(shortName); if (g_LangID.IsEqualToNoCase(shortName)) _langCombo.SetCurSel(index); } if (!error.IsEmpty()) MessageBoxW(0, error, L"Error in Lang file", MB_OK | MB_ICONSTOP); return CPropertyPage::OnInit(); }
HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix) { NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*"))); NFile::NFind::CFileInfo fileInfo; while (enumerator.Next(fileInfo)) { if (fileInfo.IsDirectory()) continue; RINOK(LoadDll(folderPrefix + fileInfo.Name)); } return S_OK; }
// If there is Reprase data already, it still writes new Reparse data bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size) { NFile::NFind::CFileInfo fi; if (fi.Find(path)) { if (fi.IsDir() != isDir) { ::SetLastError(ERROR_DIRECTORY); return false; } } else { if (isDir) { if (!NDir::CreateComplexDir(path)) return false; } else { CreatePrefixDirOfFile(path); COutFile file; if (!file.Create(path, CREATE_NEW)) return false; } } COutFile file; if (!file.Open(path, FILE_SHARE_WRITE, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS)) return false; DWORD returnedSize; if (!file.DeviceIoControl(my_FSCTL_SET_REPARSE_POINT, (void *)data, size, NULL, 0, &returnedSize)) return false; return true; }
static void Load(const CSysString &folderPrefix) { NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*"))); NFile::NFind::CFileInfo fileInfo; while (enumerator.Next(fileInfo)) { if (fileInfo.IsDirectory()) continue; CSysString filePath = folderPrefix + fileInfo.Name; { NDLL::CLibrary library; if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE)) continue; } NDLL::CLibrary library; if (!library.Load(filePath)) continue; GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc) library.GetProcAddress("GetMethodProperty"); if (getMethodProperty == NULL) continue; UInt32 numMethods = 1; GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc) library.GetProcAddress("GetNumberOfMethods"); if (getNumberOfMethodsFunc != NULL) if (getNumberOfMethodsFunc(&numMethods) != S_OK) continue; for(UInt32 i = 0; i < numMethods; i++) { CMethodInfo2 info; info.FilePath = filePath; NWindows::NCOM::CPropVariant propVariant; if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK) continue; if (propVariant.vt != VT_BSTR) continue; info.MethodID.IDSize = SysStringByteLen(propVariant.bstrVal); memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize); propVariant.Clear(); if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK) continue; if (propVariant.vt == VT_EMPTY) { } else if (propVariant.vt == VT_BSTR) info.Name = propVariant.bstrVal; else continue; propVariant.Clear(); if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK) continue; if (propVariant.vt == VT_EMPTY) info.EncoderIsAssigned = false; else if (propVariant.vt == VT_BSTR) { info.EncoderIsAssigned = true; info.Encoder = *(const GUID *)propVariant.bstrVal; } else continue; propVariant.Clear(); if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK) continue; if (propVariant.vt == VT_EMPTY) info.DecoderIsAssigned = false; else if (propVariant.vt == VT_BSTR) { info.DecoderIsAssigned = true; info.Decoder = *(const GUID *)propVariant.bstrVal; } else continue; propVariant.Clear(); if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK) continue; if (propVariant.vt == VT_EMPTY) info.NumInStreams = 1; else if (propVariant.vt == VT_UI4) info.NumInStreams = propVariant.ulVal; else continue; propVariant.Clear(); if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK) continue; if (propVariant.vt == VT_EMPTY) info.NumOutStreams = 1; else if (propVariant.vt == VT_UI4) info.NumOutStreams = propVariant.ulVal; else continue; propVariant.Clear(); g_Methods.Add(info); } } }
//TODO: clean and optimize! STDMETHODIMP ExtractCallback::GetStream( UInt32 index, ISequentialOutStream** outStream, Int32 askExtractMode ) { *outStream = 0; mOutFileStream.Release(); // Get Name NCOM::CPropVariant prop; RINOK( mArchiveHandler->GetProperty( index, kpidPath, &prop ) ); wstring fullPath; if ( prop.vt == VT_EMPTY ) { fullPath = kEmptyFileAlias; } else { if ( prop.vt != VT_BSTR ) { return E_FAIL; } fullPath = prop.bstrVal; } mFilePath = fullPath; if ( askExtractMode != NArchive::NExtract::NAskMode::kExtract ) { return S_OK; } // Get Attrib NCOM::CPropVariant prop2; RINOK( mArchiveHandler->GetProperty( index, kpidAttrib, &prop2 ) ); if ( prop2.vt == VT_EMPTY ) { mProcessedFileInfo.Attrib = 0; mProcessedFileInfo.AttribDefined = false; } else { if ( prop2.vt != VT_UI4 ) { return E_FAIL; } mProcessedFileInfo.Attrib = prop2.ulVal; mProcessedFileInfo.AttribDefined = true; } RINOK( IsArchiveItemFolder( mArchiveHandler, index, mProcessedFileInfo.isDir ) ); // Get Modified Time NCOM::CPropVariant prop3; RINOK( mArchiveHandler->GetProperty( index, kpidMTime, &prop3 ) ); mProcessedFileInfo.MTimeDefined = false; switch ( prop3.vt ) { case VT_EMPTY: // mProcessedFileInfo.MTime = _utcMTimeDefault; break; case VT_FILETIME: mProcessedFileInfo.MTime = prop3.filetime; mProcessedFileInfo.MTimeDefined = true; break; default: return E_FAIL; } // Get Size NCOM::CPropVariant prop4; RINOK( mArchiveHandler->GetProperty( index, kpidSize, &prop4 ) ); bool newFileSizeDefined = ( prop4.vt != VT_EMPTY ); UInt64 newFileSize; if ( newFileSizeDefined ) { //taken from ConvertPropVariantToUInt64 switch ( prop4.vt ) { case VT_UI1: newFileSize = prop4.bVal; break; case VT_UI2: newFileSize = prop4.uiVal; break; case VT_UI4: newFileSize = prop4.ulVal; break; case VT_UI8: newFileSize = ( UInt64 )prop4.uhVal.QuadPart; break; default: mErrorMessage = L"151199"; return E_FAIL; } //newFileSize = ConvertPropVariantToUInt64( prop4 ); } // Create folders for file size_t slashPos = mFilePath.rfind( WSTRING_PATH_SEPARATOR ); if ( slashPos != wstring::npos ) { NFile::NDir::CreateComplexDir( ( mDirectoryPath + mFilePath.substr( 0, slashPos ) ).c_str() ); } wstring fullProcessedPath = mDirectoryPath + mFilePath; mDiskFilePath = fullProcessedPath; if ( mProcessedFileInfo.isDir ) { NFile::NDir::CreateComplexDir( fullProcessedPath.c_str() ); } else { NFile::NFind::CFileInfo fi; if ( mOpener.fileCallback() ) { wstring filename; filesystem::fsutil::filename( fullProcessedPath, filename, true ); mOpener.fileCallback()( filename ); } if ( fi.Find( fullProcessedPath.c_str() ) ) { if ( !NFile::NDir::DeleteFileAlways( fullProcessedPath.c_str() ) ) { //cerr << UString( kCantDeleteOutputFile ) << fullProcessedPath << endl; //throw BitException( kCantDeleteOutputFile + fullProcessedPath ); mErrorMessage = kCantDeleteOutputFile + fullProcessedPath; return E_ABORT; } } mOutFileStreamSpec = new COutFileStream; CMyComPtr< ISequentialOutStream > outStreamLoc( mOutFileStreamSpec ); if ( !mOutFileStreamSpec->Open( fullProcessedPath.c_str(), CREATE_ALWAYS ) ) { //cerr << ( UString )L"cannot open output file " + fullProcessedPath << endl; //throw BitException( L"cannot open output file " + fullProcessedPath ); mErrorMessage = L"Cannot open output file " + fullProcessedPath; return E_ABORT; } mOutFileStream = outStreamLoc; *outStream = outStreamLoc.Detach(); } return S_OK; }