int RemoveToRecycleBin(const wchar_t *Name) { string strFullName; ConvertNameToFull(Name, strFullName); // При удалении в корзину папки с симлинками получим траблу, если предварительно линки не убрать. if (WinVer.dwMajorVersion<6 && Opt.DeleteToRecycleBinKillLink && apiGetFileAttributes(Name) == FILE_ATTRIBUTE_DIRECTORY) { string strFullName2; FAR_FIND_DATA_EX FindData; ScanTree ScTree(TRUE,TRUE,FALSE); ScTree.SetFindPath(Name,L"*", 0); while (ScTree.GetNextName(&FindData,strFullName2)) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && FindData.dwFileAttributes&FILE_ATTRIBUTE_REPARSE_POINT) ERemoveDirectory(strFullName2,FALSE); } } wchar_t *lpwszName = strFullName.GetBuffer(strFullName.GetLength()+2); lpwszName[strFullName.GetLength()+1] = 0; //dirty trick to make strFullName end with DOUBLE zero!!! return MoveToRecycleBinInternal(lpwszName); }
void Shortcuts::EditItem(VMenu* Menu, ShortcutItem* Item, bool Root) { string strNewDir = Item->strFolder; string strNewPluginModule = Item->strPluginModule; string strNewPluginFile = Item->strPluginFile; string strNewPluginData = Item->strPluginData; DialogBuilder Builder(MFolderShortcutsTitle, HelpFolderShortcuts); Builder.AddText(MFSShortcut); Builder.AddEditField(&strNewDir, 50, L"FS_Path", DIF_EDITPATH); if (!strNewPluginModule.IsEmpty()) { Builder.AddSeparator(); Builder.AddText(MFSShortcutModule); Builder.AddEditField(&strNewPluginModule, 50, nullptr, DIF_READONLY); Builder.AddText(MFSShortcutFile); Builder.AddEditField(&strNewPluginFile, 50, nullptr, DIF_READONLY); Builder.AddText(MFSShortcutData); Builder.AddEditField(&strNewPluginData, 50, nullptr, DIF_READONLY); } Builder.AddOKCancel(); if (Builder.ShowDialog()) { Unquote(strNewDir); if (!IsLocalRootPath(strNewDir)) DeleteEndSlash(strNewDir); bool Save=true; string strTemp(strNewDir); apiExpandEnvironmentStrings(strNewDir,strTemp); if (apiGetFileAttributes(strTemp) == INVALID_FILE_ATTRIBUTES) { Save=!Message(MSG_WARNING | MSG_ERRORTYPE, 2, MSG(MError), strNewDir, MSG(MSaveThisShortcut), MSG(MYes), MSG(MNo)); } if (Save) { Item->strPluginData.Clear(); Item->strPluginFile.Clear(); Item->strPluginModule.Clear(); Item->strFolder = strNewDir; MenuItemEx* MenuItem = Menu->GetItemPtr(); MenuItem->strName = Item->strFolder; if(Root) { MakeItemName(Menu->GetSelectPos(), MenuItem); } Menu->SetPosition(-1, -1, -1, -1); Menu->SetUpdateRequired(TRUE); Menu->Show(); } } }
void UserMenu::SaveMenu(const string& MenuFileName) { if (MenuModified) { DWORD FileAttr=apiGetFileAttributes(MenuFileName); if (FileAttr != INVALID_FILE_ATTRIBUTES) { if (FileAttr & FILE_ATTRIBUTE_READONLY) { int AskOverwrite; AskOverwrite=Message(MSG_WARNING,2,MSG(MUserMenuTitle),LocalMenuFileName,MSG(MEditRO),MSG(MEditOvr),MSG(MYes),MSG(MNo)); if (!AskOverwrite) apiSetFileAttributes(MenuFileName,FileAttr & ~FILE_ATTRIBUTE_READONLY); } if (FileAttr & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) apiSetFileAttributes(MenuFileName,FILE_ATTRIBUTE_NORMAL); } // Don't use CreationDisposition=CREATE_ALWAYS here - it kills alternate streams File MenuFile; if (MenuFile.Open(MenuFileName,GENERIC_WRITE, FILE_SHARE_READ, nullptr, FileAttr==INVALID_FILE_ATTRIBUTES?CREATE_NEW:TRUNCATE_EXISTING)) { CachedWrite CW(MenuFile); WCHAR Data = SIGN_UNICODE; CW.Write(&Data, 1*sizeof(WCHAR)); MenuListToFile(&Menu, CW); CW.Flush(); UINT64 Size = 0; MenuFile.GetSize(Size); MenuFile.Close(); // если файл FarMenu.ini пуст, то удалим его if (Size<3) // 2 for BOM { apiDeleteFile(MenuFileName); } else if (FileAttr!=INVALID_FILE_ATTRIBUTES) { apiSetFileAttributes(MenuFileName,FileAttr); } } } }
bool SetREPARSE_DATA_BUFFER(const wchar_t *Object,PREPARSE_DATA_BUFFER rdb) { bool Result=false; if (IsReparseTagValid(rdb->ReparseTag)) { Privilege CreateSymlinkPrivilege(SE_CREATE_SYMBOLIC_LINK_NAME); File fObject; bool ForceElevation=false; DWORD Attributes = apiGetFileAttributes(Object); if(Attributes&FILE_ATTRIBUTE_READONLY) { apiSetFileAttributes(Object, Attributes&~FILE_ATTRIBUTE_READONLY); } for(size_t i=0;i<2;i++) { if (fObject.Open(Object,GENERIC_WRITE,0,nullptr,OPEN_EXISTING,FILE_FLAG_OPEN_REPARSE_POINT,nullptr,ForceElevation)) { DWORD dwBytesReturned; if (fObject.IoControl(FSCTL_SET_REPARSE_POINT,rdb,rdb->ReparseDataLength+REPARSE_DATA_BUFFER_HEADER_SIZE,nullptr,0,&dwBytesReturned)) { Result=true; } fObject.Close(); // Open() success, but IoControl() fails. We can't handle this automatically :( if(!i && !Result && ElevationRequired(ELEVATION_MODIFY_REQUEST)) { ForceElevation=true; continue; } break; } } if(Attributes&FILE_ATTRIBUTE_READONLY) { apiSetFileAttributes(Object, Attributes); } } return Result; }
void Manager::PluginsMenu() { _MANAGER(SysLog(1)); int curType = CurrentFrame->GetType(); if (curType == MODALTYPE_PANELS || curType == MODALTYPE_EDITOR || curType == MODALTYPE_VIEWER || curType == MODALTYPE_DIALOG) { /* 02.01.2002 IS ! Вывод правильной помощи по Shift-F1 в меню плагинов в редакторе/вьюере/диалоге ! Если на панели QVIEW или INFO открыт файл, то считаем, что это полноценный вьюер и запускаем с соответствующим параметром плагины */ if (curType==MODALTYPE_PANELS) { int pType=CtrlObject->Cp()->ActivePanel->GetType(); if (pType==QVIEW_PANEL || pType==INFO_PANEL) { string strType, strCurFileName; CtrlObject->Cp()->GetTypeAndName(strType, strCurFileName); if (!strCurFileName.IsEmpty()) { DWORD Attr=apiGetFileAttributes(strCurFileName); // интересуют только обычные файлы if (Attr!=INVALID_FILE_ATTRIBUTES && !(Attr&FILE_ATTRIBUTE_DIRECTORY)) curType=MODALTYPE_VIEWER; } } } // в редакторе, вьюере или диалоге покажем свою помощь по Shift-F1 const wchar_t *Topic=curType==MODALTYPE_EDITOR?L"Editor": curType==MODALTYPE_VIEWER?L"Viewer": curType==MODALTYPE_DIALOG?L"Dialog":nullptr; CtrlObject->Plugins->CommandsMenu(curType,0,Topic); } _MANAGER(SysLog(-1)); }
bool GetREPARSE_DATA_BUFFER(const wchar_t *Object,PREPARSE_DATA_BUFFER rdb) { bool Result=false; const DWORD FileAttr = apiGetFileAttributes(Object); if (FileAttr!=INVALID_FILE_ATTRIBUTES && (FileAttr&FILE_ATTRIBUTE_REPARSE_POINT)) { File fObject; if(fObject.Open(Object,0,0,nullptr,OPEN_EXISTING,FILE_FLAG_OPEN_REPARSE_POINT)) { DWORD dwBytesReturned; if(fObject.IoControl(FSCTL_GET_REPARSE_POINT, nullptr, 0, rdb, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwBytesReturned) && IsReparseTagValid(rdb->ReparseTag)) { Result=true; } fObject.Close(); } } return Result; }
/* v - точка prefXXX X X XXX \ / ^ ^^^\ PID + TID | \------/ | +---------- [0A-Z] */ string& FarMkTempEx(string &strDest, const wchar_t *Prefix, BOOL WithTempPath, const wchar_t *UserTempPath) { if (!(Prefix && *Prefix)) Prefix=L"FTMP"; string strPath = L"."; if (WithTempPath) { apiGetTempPath(strPath); } else if(UserTempPath) { strPath=UserTempPath; } AddEndSlash(strPath); wchar_t *lpwszDest = strDest.GetBuffer(StrLength(Prefix)+strPath.GetLength()+13); UINT uniq = GetCurrentProcessId(), savePid = uniq; for (;;) { if (!uniq) ++uniq; if (GetTempFileName(strPath, Prefix, uniq, lpwszDest) && apiGetFileAttributes(lpwszDest) == INVALID_FILE_ATTRIBUTES) break; if (++uniq == savePid) { *lpwszDest = 0; break; } } strDest.ReleaseBuffer(); return strDest; }
void ShellMakeDir(Panel *SrcPanel) { string strDirName; string strOriginalDirName; wchar_t *lpwszDirName; UserDefinedList DirList(0,0,ULF_UNIQUE); DialogDataEx MkDirDlgData[]= { DI_DOUBLEBOX,3,1,72,8,0,0,MSG(MMakeFolderTitle), DI_TEXT, 5,2, 0,2,0,0,MSG(MCreateFolder), DI_EDIT, 5,3,70,3,(DWORD_PTR)L"NewFolder",DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L"", DI_TEXT, 0,4, 0,4,0,DIF_SEPARATOR,L"", DI_CHECKBOX, 5,5, 0,5,Opt.MultiMakeDir,0,MSG(MMultiMakeDir), DI_TEXT, 0,6, 0,6,0,DIF_SEPARATOR,L"", DI_BUTTON, 0,7, 0,7,0,DIF_DEFAULT|DIF_CENTERGROUP,MSG(MOk), DI_BUTTON, 0,7, 0,7,0,DIF_CENTERGROUP,MSG(MCancel), }; MakeDialogItemsEx(MkDirDlgData,MkDirDlg); Dialog Dlg(MkDirDlg,ARRAYSIZE(MkDirDlg),MkDirDlgProc,reinterpret_cast<LONG_PTR>(&DirList)); Dlg.SetPosition(-1,-1,76,10); Dlg.SetHelp(L"MakeFolder"); Dlg.SetId(MakeFolderId); Dlg.Process(); if (Dlg.GetExitCode()==MKDIR_OK) { strDirName=MkDirDlg[MKDIR_EDIT].strData; const wchar_t *OneDir; DirList.Reset(); while (nullptr!=(OneDir=DirList.GetNext())) { strDirName = OneDir; strOriginalDirName = strDirName; //Unquote(DirName); if (Opt.CreateUppercaseFolders && !IsCaseMixed(strDirName)) strDirName.Upper(); DeleteEndSlash(strDirName,true); lpwszDirName = strDirName.GetBuffer(); bool bSuccess = false; if(HasPathPrefix(lpwszDirName)) { lpwszDirName += 4; } for (wchar_t *ChPtr=lpwszDirName; *ChPtr; ChPtr++) { if (IsSlash(*ChPtr)) { WCHAR Ch = ChPtr[1]; ChPtr[1] = 0; if (*lpwszDirName && (apiGetFileAttributes(lpwszDirName) == INVALID_FILE_ATTRIBUTES) && apiCreateDirectory(lpwszDirName,nullptr)) { TreeList::AddTreeName(lpwszDirName); bSuccess = true; } ChPtr[1] = Ch; } } strDirName.ReleaseBuffer(); BOOL bSuccess2; bool bSkip=false; while (!(bSuccess2=apiCreateDirectory(strDirName,nullptr))) { int LastError=GetLastError(); if (LastError==ERROR_ALREADY_EXISTS || LastError==ERROR_BAD_PATHNAME || LastError==ERROR_INVALID_NAME || LastError == ERROR_DIRECTORY) { int ret; if (DirList.IsEmpty()) ret=Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MCannotCreateFolder),strOriginalDirName,MSG(MCancel)); else ret=Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MError),MSG(MCannotCreateFolder),strOriginalDirName,MSG(MOk),MSG(MSkip)); bSkip = ret==1; if (bSuccess || bSkip) break; else return; } else { int ret; if (DirList.IsEmpty()) { ret=Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MError),MSG(MCannotCreateFolder),strOriginalDirName,MSG(MRetry),MSG(MCancel)); } else { ret=Message(MSG_WARNING|MSG_ERRORTYPE,3,MSG(MError),MSG(MCannotCreateFolder),strOriginalDirName,MSG(MRetry),MSG(MSkip),MSG(MCancel)); bSkip = ret==1; } if (ret) { if (bSuccess || bSkip) break; else return; } } } if (bSuccess2) TreeList::AddTreeName(strDirName); else if (!bSkip) break; } SrcPanel->Update(UPDATE_KEEP_SELECTION); if (!strDirName.IsEmpty()) { size_t pos; if (FindSlash(pos,strDirName)) strDirName.SetLength(pos); if (!SrcPanel->GoToFile(strDirName) && strDirName.At(strDirName.GetLength()-1)==L'.') { strDirName.SetLength(strDirName.GetLength()-1); SrcPanel->GoToFile(strDirName); } } SrcPanel->Redraw(); Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(SrcPanel); int AnotherType=AnotherPanel->GetType(); if (AnotherPanel->NeedUpdatePanel(SrcPanel) || AnotherType==QVIEW_PANEL) { AnotherPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY); AnotherPanel->Redraw(); } } }
void FileList::PutDizToPlugin(FileList *DestPanel,PluginPanelItem *ItemList, int ItemNumber,int Delete,int Move,DizList *SrcDiz, DizList *DestDiz) { _ALGO(CleverSysLog clv(L"FileList::PutDizToPlugin()")); OpenPanelInfo Info; CtrlObject->Plugins->GetOpenPanelInfo(DestPanel->hPlugin,&Info); if (DestPanel->strPluginDizName.IsEmpty() && Info.DescrFilesNumber>0) DestPanel->strPluginDizName = Info.DescrFiles[0]; if (((Opt.Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED && IsDizDisplayed()) || Opt.Diz.UpdateMode==DIZ_UPDATE_ALWAYS) && !DestPanel->strPluginDizName.IsEmpty() && (!Info.HostFile || !*Info.HostFile || DestPanel->GetModalMode() || apiGetFileAttributes(Info.HostFile)!=INVALID_FILE_ATTRIBUTES)) { CtrlObject->Cp()->LeftPanel->ReadDiz(); CtrlObject->Cp()->RightPanel->ReadDiz(); if (DestPanel->GetModalMode()) DestPanel->ReadDiz(); int DizPresent=FALSE; for (int I=0; I<ItemNumber; I++) if (ItemList[I].Flags & PPIF_PROCESSDESCR) { string strName = ItemList[I].FileName; string strShortName = ItemList[I].AlternateFileName; int Code; if (Delete) Code=DestDiz->DeleteDiz(strName,strShortName); else { Code=SrcDiz->CopyDiz(strName,strShortName,strName,strShortName,DestDiz); if (Code && Move) SrcDiz->DeleteDiz(strName,strShortName); } if (Code) DizPresent=TRUE; } if (DizPresent) { string strTempDir; if (FarMkTempEx(strTempDir) && apiCreateDirectory(strTempDir,nullptr)) { string strSaveDir; apiGetCurrentDirectory(strSaveDir); string strDizName=strTempDir+L"\\"+DestPanel->strPluginDizName; DestDiz->Flush(L"", &strDizName); if (Move) SrcDiz->Flush(L""); PluginPanelItem PanelItem; if (FileNameToPluginItem(strDizName,&PanelItem)) CtrlObject->Plugins->PutFiles(DestPanel->hPlugin,&PanelItem,1,FALSE,OPM_SILENT|OPM_DESCR); else if (Delete) { PluginPanelItem pi={}; pi.FileName = xf_wcsdup(DestPanel->strPluginDizName); CtrlObject->Plugins->DeleteFiles(DestPanel->hPlugin,&pi,1,OPM_SILENT); xf_free(pi.FileName); } FarChDir(strSaveDir); DeleteFileWithFolder(strDizName); } } } }
int FarAppMain(int argc, char **argv) { Opt.IsUserAdmin = (geteuid()==0); _OT(SysLog(L"[[[[[[[[New Session of FAR]]]]]]]]]")); FARString strEditName; FARString strViewName; FARString DestNames[2]; int StartLine=-1,StartChar=-1; int CntDestName=0; // количество параметров-имен каталогов /*$ 18.04.2002 SKV Попользуем floating point что бы проинициализировался vc-ный fprtl. */ #ifdef _MSC_VER float x=1.1f; wchar_t buf[15]; swprintf(buf,L"%f",x); #endif // если под дебагером, то отключаем исключения однозначно, // иначе - смотря что указал юзвер. #if defined(_DEBUGEXC) Opt.ExceptRules=-1; #else Opt.ExceptRules=-1;//IsDebuggerPresent()?0:-1; #endif // Opt.ExceptRules=-1; #ifdef __GNUC__ Opt.ExceptRules=0; #endif //_SVS(SysLog(L"Opt.ExceptRules=%d",Opt.ExceptRules)); SetRegRootKey(HKEY_CURRENT_USER); Opt.strRegRoot = L"Software/Far2"; // По умолчанию - брать плагины из основного каталога Opt.LoadPlug.MainPluginDir=TRUE; Opt.LoadPlug.PluginsPersonal=TRUE; Opt.LoadPlug.PluginsCacheOnly=FALSE; g_strFarPath = g_strFarModuleName; bool translated = TranslateFarString<TranslateInstallPath_Bin2Share>(g_strFarPath); CutToSlash(g_strFarPath, true); if (translated) { // /usr/bin/something -> /usr/share/far2l g_strFarPath+= L"/" FAR_BASENAME; } WINPORT(SetEnvironmentVariable)(L"FARHOME", g_strFarPath); AddEndSlash(g_strFarPath); // don't inherit from parent process in any case WINPORT(SetEnvironmentVariable)(L"FARUSER", nullptr); WINPORT(SetEnvironmentVariable)(L"FARADMINMODE", Opt.IsUserAdmin?L"1":nullptr); // макросы не дисаблим Opt.Macro.DisableMacro=0; for (int I=1; I<argc; I++) { std::wstring arg_w = MB2Wide(argv[I]); if ((arg_w[0]==L'/' || arg_w[0]==L'-') && arg_w[1]) { switch (Upper(arg_w[1])) { case L'A': switch (Upper(arg_w[2])) { case 0: Opt.CleanAscii=TRUE; break; case L'G': if (!arg_w[3]) Opt.NoGraphics=TRUE; break; } break; case L'E': if (iswdigit(arg_w[2])) { StartLine=_wtoi((const wchar_t *)&arg_w[2]); wchar_t *ChPtr=wcschr((wchar_t *)&arg_w[2],L':'); if (ChPtr) StartChar=_wtoi(ChPtr+1); } if (I+1<argc) { strEditName = argv[I+1]; I++; } break; case L'V': if (I+1<argc) { strViewName = argv[I+1]; I++; } break; case L'M': switch (Upper(arg_w[2])) { case 0: Opt.Macro.DisableMacro|=MDOL_ALL; break; case L'A': if (!arg_w[3]) Opt.Macro.DisableMacro|=MDOL_AUTOSTART; break; } break; case L'I': Opt.SmallIcon=TRUE; break; case L'X': Opt.ExceptRules=0; #if defined(_DEBUGEXC) if (Upper(arg_w[2])==L'D' && !arg_w[3]) Opt.ExceptRules=1; #endif break; case L'C': if (Upper(arg_w[2])==L'O' && !arg_w[3]) { Opt.LoadPlug.PluginsCacheOnly=TRUE; Opt.LoadPlug.PluginsPersonal=FALSE; } break; case L'?': case L'H': ControlObject::ShowCopyright(1); show_help(); return 0; #ifdef DIRECT_RT case L'D': if (Upper(arg_w[2])==L'O' && !arg_w[3]) DirectRT=1; break; #endif case L'W': { Opt.WindowMode=TRUE; } break; } } else // простые параметры. Их может быть max две штукА. { if (CntDestName < 2) { if (IsPluginPrefixPath((const wchar_t *)arg_w.c_str())) { DestNames[CntDestName++] = (const wchar_t *)arg_w.c_str(); } else { apiExpandEnvironmentStrings((const wchar_t *)arg_w.c_str(), DestNames[CntDestName]); Unquote(DestNames[CntDestName]); ConvertNameToFull(DestNames[CntDestName],DestNames[CntDestName]); if (apiGetFileAttributes(DestNames[CntDestName]) != INVALID_FILE_ATTRIBUTES) CntDestName++; //??? } } } } //Настройка OEM сортировки. Должна быть после CopyGlobalSettings и перед InitKeysArray! //LocalUpperInit(); //InitLCIDSort(); //Инициализация массива клавиш. Должна быть после CopyGlobalSettings! InitKeysArray(); //WaitForInputIdle(GetCurrentProcess(),0); std::set_new_handler(nullptr); if (!Opt.LoadPlug.MainPluginDir) //если есть ключ /p то он отменяет /co Opt.LoadPlug.PluginsCacheOnly=FALSE; if (Opt.LoadPlug.PluginsCacheOnly) { Opt.LoadPlug.strCustomPluginsPath.Clear(); Opt.LoadPlug.MainPluginDir=FALSE; Opt.LoadPlug.PluginsPersonal=FALSE; } InitConsole(); GetRegKey(L"Language",L"Main",Opt.strLanguage,L"English"); if (!Lang.Init(g_strFarPath,true,MNewFileName)) { ControlObject::ShowCopyright(1); LPCWSTR LngMsg; switch(Lang.GetLastError()) { case LERROR_BAD_FILE: LngMsg = L"\nError: language data is incorrect or damaged.\n\nPress any key to exit..."; break; case LERROR_FILE_NOT_FOUND: LngMsg = L"\nError: cannot find language data.\n\nPress any key to exit..."; break; default: LngMsg = L"\nError: cannot load language data.\n\nPress any key to exit..."; break; } Console.Write(LngMsg,StrLength(LngMsg)); Console.FlushInputBuffer(); WaitKey(); // А стоит ли ожидать клавишу??? Стоит return 1; } WINPORT(SetEnvironmentVariable)(L"FARLANG",Opt.strLanguage); SetHighlighting(); initMacroVarTable(1); if (Opt.ExceptRules == -1) { GetRegKey(L"System",L"ExceptRules",Opt.ExceptRules,1); } //ErrorMode=SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX|(Opt.ExceptRules?SEM_NOGPFAULTERRORBOX:0)|(GetRegKey(L"System/Exception", L"IgnoreDataAlignmentFaults", 0)?SEM_NOALIGNMENTFAULTEXCEPT:0); //SetErrorMode(ErrorMode); int Result=MainProcessSEH(strEditName,strViewName,DestNames[0],DestNames[1],StartLine,StartChar); EmptyInternalClipboard(); doneMacroVarTable(1); VTShell_Shutdown();//ensure VTShell deinitialized before statics destructors called _OT(SysLog(L"[[[[[Exit of FAR]]]]]]]]]")); return Result; }
void ShellDelete(Panel *SrcPanel,int Wipe) { ChangePriority ChPriority(Opt.DelThreadPriority); TPreRedrawFuncGuard preRedrawFuncGuard(PR_ShellDeleteMsg); FAR_FIND_DATA_EX FindData; string strDeleteFilesMsg; string strSelName; string strSelShortName; string strDizName; string strFullName; DWORD FileAttr; int SelCount,UpdateDiz; int DizPresent; int Ret; BOOL NeedUpdate=TRUE, NeedSetUpADir=FALSE; int Opt_DeleteToRecycleBin=Opt.DeleteToRecycleBin; /*& 31.05.2001 OT Запретить перерисовку текущего фрейма*/ Frame *FrameFromLaunched=FrameManager->GetCurrentFrame(); FrameFromLaunched->Lock(); DeleteAllFolders=!Opt.Confirm.DeleteFolder; UpdateDiz=(Opt.Diz.UpdateMode==DIZ_UPDATE_ALWAYS || (SrcPanel->IsDizDisplayed() && Opt.Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED)); if (!(SelCount=SrcPanel->GetSelCount())) goto done; // Удаление в корзину только для FIXED-дисков { string strRoot; // char FSysNameSrc[NM]; SrcPanel->GetSelName(nullptr,FileAttr); SrcPanel->GetSelName(&strSelName,FileAttr); ConvertNameToFull(strSelName, strRoot); GetPathRoot(strRoot,strRoot); //_SVS(SysLog(L"Del: SelName='%s' Root='%s'",SelName,Root)); if (Opt.DeleteToRecycleBin && FAR_GetDriveType(strRoot) != DRIVE_FIXED) Opt.DeleteToRecycleBin=0; } if (SelCount==1) { SrcPanel->GetSelName(nullptr,FileAttr); SrcPanel->GetSelName(&strSelName,FileAttr); if (TestParentFolderName(strSelName) || strSelName.IsEmpty()) { NeedUpdate=FALSE; goto done; } strDeleteFilesMsg = strSelName; } else { // в зависимости от числа ставим нужное окончание const wchar_t *Ends; wchar_t StrItems[16]; _itow(SelCount,StrItems,10); Ends=MSG(MAskDeleteItemsA); int LenItems=StrLength(StrItems); if (LenItems > 0) { if ((LenItems >= 2 && StrItems[LenItems-2] == L'1') || StrItems[LenItems-1] >= L'5' || StrItems[LenItems-1] == L'0') Ends=MSG(MAskDeleteItemsS); else if (StrItems[LenItems-1] == L'1') Ends=MSG(MAskDeleteItems0); } strDeleteFilesMsg.Format(MSG(MAskDeleteItems),SelCount,Ends); } Ret=1; // Обработка "удаления" линков if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT) && SelCount==1) { string strJuncName; ConvertNameToFull(strSelName,strJuncName); if (GetReparsePointInfo(strJuncName, strJuncName)) // ? SelName ? { NormalizeSymlinkName(strJuncName); //SetMessageHelp(L"DeleteLink"); string strAskDeleteLink=MSG(MAskDeleteLink); DWORD dwAttr=apiGetFileAttributes(strJuncName); if (dwAttr!=INVALID_FILE_ATTRIBUTES) { strAskDeleteLink+=L" "; strAskDeleteLink+=dwAttr&FILE_ATTRIBUTE_DIRECTORY?MSG(MAskDeleteLinkFolder):MSG(MAskDeleteLinkFile); } Ret=Message(0,3,MSG(MDeleteLinkTitle), strDeleteFilesMsg, strAskDeleteLink, strJuncName, MSG(MDeleteLinkDelete),MSG(MDeleteLinkUnlink),MSG(MCancel)); if (Ret == 1) { ConvertNameToFull(strSelName, strJuncName); if (Opt.Confirm.Delete) { ; // ;-% } if ((NeedSetUpADir=CheckUpdateAnotherPanel(SrcPanel,strSelName)) != -1) //JuncName? { DeleteReparsePoint(strJuncName); ShellUpdatePanels(SrcPanel,NeedSetUpADir); } goto done; } if (Ret ) goto done; } } if (Ret && (Opt.Confirm.Delete || SelCount>1 || (FileAttr & FILE_ATTRIBUTE_DIRECTORY))) { const wchar_t *DelMsg; const wchar_t *TitleMsg=MSG(Wipe?MDeleteWipeTitle:MDeleteTitle); /* $ 05.01.2001 IS ! Косметика в сообщениях - разные сообщения в зависимости от того, какие и сколько элементов выделено. */ BOOL folder=(FileAttr & FILE_ATTRIBUTE_DIRECTORY); if (SelCount==1) { if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) DelMsg=MSG(folder?MAskWipeFolder:MAskWipeFile); else { if (Opt.DeleteToRecycleBin && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) DelMsg=MSG(folder?MAskDeleteRecycleFolder:MAskDeleteRecycleFile); else DelMsg=MSG(folder?MAskDeleteFolder:MAskDeleteFile); } } else { if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) { DelMsg=MSG(MAskWipe); TitleMsg=MSG(MDeleteWipeTitle); } else if (Opt.DeleteToRecycleBin && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) DelMsg=MSG(MAskDeleteRecycle); else DelMsg=MSG(MAskDelete); } SetMessageHelp(L"DeleteFile"); if (Message(0,2,TitleMsg,DelMsg,strDeleteFilesMsg,MSG(Wipe?MDeleteWipe:Opt.DeleteToRecycleBin?MDeleteRecycle:MDelete),MSG(MCancel))) { NeedUpdate=FALSE; goto done; } } if (Opt.Confirm.Delete && SelCount>1) { //SaveScreen SaveScr; SetCursorType(FALSE,0); SetMessageHelp(L"DeleteFile"); if (Message(MSG_WARNING,2,MSG(Wipe?MWipeFilesTitle:MDeleteFilesTitle),MSG(Wipe?MAskWipe:MAskDelete), strDeleteFilesMsg,MSG(MDeleteFileAll),MSG(MDeleteFileCancel))) { NeedUpdate=FALSE; goto done; } } if (UpdateDiz) SrcPanel->ReadDiz(); SrcPanel->GetDizName(strDizName); DizPresent=(!strDizName.IsEmpty() && apiGetFileAttributes(strDizName)!=INVALID_FILE_ATTRIBUTES); DeleteTitle = new ConsoleTitle(MSG(MDeletingTitle)); if ((NeedSetUpADir=CheckUpdateAnotherPanel(SrcPanel,strSelName)) == -1) goto done; if (SrcPanel->GetType()==TREE_PANEL) FarChDir(L"\\"); { TaskBar TB; wakeful W; bool Cancel=false; //SaveScreen SaveScr; SetCursorType(FALSE,0); ReadOnlyDeleteMode=-1; SkipMode=-1; SkipWipeMode=-1; SkipFoldersMode=-1; ULONG ItemsCount=0; ProcessedItems=0; if (Opt.DelOpt.DelShowTotal) { SrcPanel->GetSelName(nullptr,FileAttr); DWORD StartTime=GetTickCount(); bool FirstTime=true; while (SrcPanel->GetSelName(&strSelName,FileAttr,&strSelShortName) && !Cancel) { if (!(FileAttr&FILE_ATTRIBUTE_REPARSE_POINT)) { if (FileAttr&FILE_ATTRIBUTE_DIRECTORY) { DWORD CurTime=GetTickCount(); if (CurTime-StartTime>RedrawTimeout || FirstTime) { StartTime=CurTime; FirstTime=false; if (CheckForEscSilent() && ConfirmAbortOp()) { Cancel=true; break; } ShellDeleteMsg(strSelName,Wipe,-1); } ULONG CurrentFileCount,CurrentDirCount,ClusterSize; UINT64 FileSize,CompressedFileSize,RealSize; if (GetDirInfo(nullptr,strSelName,CurrentDirCount,CurrentFileCount,FileSize,CompressedFileSize,RealSize,ClusterSize,-1,nullptr,0)>0) { ItemsCount+=CurrentFileCount+CurrentDirCount+1; } else { Cancel=true; } } else { ItemsCount++; } } } } SrcPanel->GetSelName(nullptr,FileAttr); DWORD StartTime=GetTickCount(); bool FirstTime=true; while (SrcPanel->GetSelName(&strSelName,FileAttr,&strSelShortName) && !Cancel) { int Length=(int)strSelName.GetLength(); if (!Length || (strSelName.At(0)==L'\\' && Length<2) || (strSelName.At(1)==L':' && Length<4)) continue; DWORD CurTime=GetTickCount(); if (CurTime-StartTime>RedrawTimeout || FirstTime) { StartTime=CurTime; FirstTime=false; if (CheckForEscSilent() && ConfirmAbortOp()) { Cancel=true; break; } ShellDeleteMsg(strSelName,Wipe,Opt.DelOpt.DelShowTotal?(ItemsCount?(ProcessedItems*100/ItemsCount):0):-1); } if (FileAttr & FILE_ATTRIBUTE_DIRECTORY) { if (!DeleteAllFolders) { ConvertNameToFull(strSelName, strFullName); if (TestFolder(strFullName) == TSTFLD_NOTEMPTY) { int MsgCode=0; // для symlink`а не нужно подтверждение if (!(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) MsgCode=Message(MSG_WARNING,4,MSG(Wipe?MWipeFolderTitle:MDeleteFolderTitle), MSG(Wipe?MWipeFolderConfirm:MDeleteFolderConfirm),strFullName, MSG(Wipe?MDeleteFileWipe:MDeleteFileDelete),MSG(MDeleteFileAll), MSG(MDeleteFileSkip),MSG(MDeleteFileCancel)); if (MsgCode<0 || MsgCode==3) { NeedSetUpADir=FALSE; break; } if (MsgCode==1) DeleteAllFolders=1; if (MsgCode==2) continue; } } bool DirSymLink=(FileAttr&FILE_ATTRIBUTE_DIRECTORY && FileAttr&FILE_ATTRIBUTE_REPARSE_POINT); if (!DirSymLink && (!Opt.DeleteToRecycleBin || Wipe)) { string strFullName; ScanTree ScTree(TRUE,TRUE,FALSE); string strSelFullName; if (IsAbsolutePath(strSelName)) { strSelFullName=strSelName; } else { SrcPanel->GetCurDir(strSelFullName); AddEndSlash(strSelFullName); strSelFullName+=strSelName; } ScTree.SetFindPath(strSelFullName,L"*", 0); DWORD StartTime=GetTickCount(); while (ScTree.GetNextName(&FindData,strFullName)) { DWORD CurTime=GetTickCount(); if (CurTime-StartTime>RedrawTimeout) { StartTime=CurTime; if (CheckForEscSilent()) { int AbortOp = ConfirmAbortOp(); if (AbortOp) { Cancel=true; break; } } ShellDeleteMsg(strFullName,Wipe,Opt.DelOpt.DelShowTotal?(ItemsCount?(ProcessedItems*100/ItemsCount):0):-1); } if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL); int MsgCode=ERemoveDirectory(strFullName,Wipe); if (MsgCode==DELETE_CANCEL) { Cancel=true; break; } else if (MsgCode==DELETE_SKIP) { ScTree.SkipDir(); continue; } TreeList::DelTreeName(strFullName); if (UpdateDiz) SrcPanel->DeleteDiz(strFullName,strSelShortName); continue; } if (!DeleteAllFolders && !ScTree.IsDirSearchDone() && TestFolder(strFullName) == TSTFLD_NOTEMPTY) { int MsgCode=Message(MSG_WARNING,4,MSG(Wipe?MWipeFolderTitle:MDeleteFolderTitle), MSG(Wipe?MWipeFolderConfirm:MDeleteFolderConfirm),strFullName, MSG(Wipe?MDeleteFileWipe:MDeleteFileDelete),MSG(MDeleteFileAll), MSG(MDeleteFileSkip),MSG(MDeleteFileCancel)); if (MsgCode<0 || MsgCode==3) { Cancel=true; break; } if (MsgCode==1) DeleteAllFolders=1; if (MsgCode==2) { ScTree.SkipDir(); continue; } } if (ScTree.IsDirSearchDone()) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL); int MsgCode=ERemoveDirectory(strFullName,Wipe); if (MsgCode==DELETE_CANCEL) { Cancel=true;; break; } else if (MsgCode==DELETE_SKIP) { //ScTree.SkipDir(); continue; } TreeList::DelTreeName(strFullName); } } else { int AskCode=AskDeleteReadOnly(strFullName,FindData.dwFileAttributes,Wipe); if (AskCode==DELETE_CANCEL) { Cancel=true; break; } if (AskCode==DELETE_YES) if (ShellRemoveFile(strFullName,Wipe)==DELETE_CANCEL) { Cancel=true; break; } } } } if (!Cancel) { if (FileAttr & FILE_ATTRIBUTE_READONLY) apiSetFileAttributes(strSelName,FILE_ATTRIBUTE_NORMAL); int DeleteCode; // нефига здесь выделываться, а надо учесть, что удаление // симлинка в корзину чревато потерей оригинала. if (DirSymLink || !Opt.DeleteToRecycleBin || Wipe) { DeleteCode=ERemoveDirectory(strSelName,Wipe); if (DeleteCode==DELETE_CANCEL) break; else if (DeleteCode==DELETE_SUCCESS) { TreeList::DelTreeName(strSelName); if (UpdateDiz) SrcPanel->DeleteDiz(strSelName,strSelShortName); } } else { DeleteCode=RemoveToRecycleBin(strSelName); if (!DeleteCode) Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError), MSG(MCannotDeleteFolder),strSelName,MSG(MOk)); else { TreeList::DelTreeName(strSelName); if (UpdateDiz) SrcPanel->DeleteDiz(strSelName,strSelShortName); } } } } else { int AskCode=AskDeleteReadOnly(strSelName,FileAttr,Wipe); if (AskCode==DELETE_CANCEL) break; if (AskCode==DELETE_YES) { int DeleteCode=ShellRemoveFile(strSelName,Wipe); if (DeleteCode==DELETE_SUCCESS && UpdateDiz) { SrcPanel->DeleteDiz(strSelName,strSelShortName); } if (DeleteCode==DELETE_CANCEL) break; } } } } if (UpdateDiz) if (DizPresent==(!strDizName.IsEmpty() && apiGetFileAttributes(strDizName)!=INVALID_FILE_ATTRIBUTES)) SrcPanel->FlushDiz(); delete DeleteTitle; done: Opt.DeleteToRecycleBin=Opt_DeleteToRecycleBin; // Разрешить перерисовку фрейма FrameFromLaunched->Unlock(); if (NeedUpdate) { ShellUpdatePanels(SrcPanel,NeedSetUpADir); } }
void ShellMakeDir(Panel *SrcPanel) { FarList ComboList={sizeof(FarList)}; FarListItem LinkTypeItems[3]={}; ComboList.ItemsNumber=ARRAYSIZE(LinkTypeItems); ComboList.Items=LinkTypeItems; ComboList.Items[0].Text=MSG(MMakeFolderLinkNone); ComboList.Items[1].Text=MSG(MMakeFolderLinkJunction); ComboList.Items[2].Text=MSG(MMakeFolderLinkSymlink); ComboList.Items[0].Flags|=LIF_SELECTED; FarDialogItem MkDirDlgData[]= { {DI_DOUBLEBOX,3,1,72,10,0,nullptr,nullptr,0,MSG(MMakeFolderTitle)}, {DI_TEXT, 5,2, 0,2,0,nullptr,nullptr,0,MSG(MCreateFolder)}, {DI_EDIT, 5,3,70,3,0,L"NewFolder",nullptr,DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""}, {DI_TEXT, 0,4, 0,4,0,nullptr,nullptr,DIF_SEPARATOR,L""}, {DI_TEXT, 5,5, 0,5,0,nullptr,nullptr,0,MSG(MMakeFolderLinkType)}, {DI_COMBOBOX,20,5,70,5,0,nullptr,nullptr,DIF_DROPDOWNLIST|DIF_LISTNOAMPERSAND|DIF_LISTWRAPMODE,L""}, {DI_TEXT, 5,6, 0,6,0,nullptr,nullptr,0,MSG(MMakeFolderLinkTarget)}, {DI_EDIT, 20,6,70,6,0,L"NewFolderLinkTarget",nullptr,DIF_DISABLE|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""}, {DI_CHECKBOX, 5,7, 0,7,Opt.MultiMakeDir,nullptr,nullptr,0,MSG(MMultiMakeDir)}, {DI_TEXT, 0,8, 0,8,0,nullptr,nullptr,DIF_SEPARATOR,L""}, {DI_BUTTON, 0,9, 0,9,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)}, {DI_BUTTON, 0,9, 0,9,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MCancel)}, }; MakeDialogItemsEx(MkDirDlgData,MkDirDlg); MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListItems=&ComboList; UserDefinedList DirList(ULF_UNIQUE); Dialog Dlg(MkDirDlg,ARRAYSIZE(MkDirDlg),MkDirDlgProc,&DirList); Dlg.SetPosition(-1,-1,76,12); Dlg.SetHelp(L"MakeFolder"); Dlg.SetId(MakeFolderId); Dlg.Process(); if (Dlg.GetExitCode()==MKDIR_OK) { string strDirName=MkDirDlg[MKDIR_EDIT].strData; string strOriginalDirName; const wchar_t *OneDir; DirList.Reset(); bool SkipAll = false; while (nullptr!=(OneDir=DirList.GetNext())) { strDirName = OneDir; strOriginalDirName = strDirName; //Unquote(DirName); if (Opt.CreateUppercaseFolders && !IsCaseMixed(strDirName)) strDirName.Upper(); DeleteEndSlash(strDirName,true); wchar_t* lpwszDirName = strDirName.GetBuffer(); bool bSuccess = false; wchar_t *ChPtr; if(ParsePath(lpwszDirName, const_cast<const wchar_t **>(&ChPtr)) == PATH_UNKNOWN) { ChPtr = lpwszDirName; } for (; ; ChPtr++) { if (IsSlash(*ChPtr) || !*ChPtr) { WCHAR Ch=0; if(*ChPtr) { Ch = ChPtr[1]; ChPtr[1] = 0; } if (*lpwszDirName) { string _strDirName(lpwszDirName); if (apiGetFileAttributes(_strDirName) == INVALID_FILE_ATTRIBUTES || !*ChPtr) // skip all intermediate dirs, but not last. { while(!(bSuccess=(apiCreateDirectory(_strDirName, nullptr)!=FALSE)) && !SkipAll) { int Ret = OperationFailed(strOriginalDirName, MError, MSG(MCannotCreateFolder)); if(Ret == 1) // skip { break; } else if(Ret == 2) { SkipAll = true; break; } else if (Ret < 0 || Ret == 3) // cancel { return; } } if(bSuccess) { TreeList::AddTreeName(_strDirName); } } } if(*ChPtr) { ChPtr[1] = Ch; } else { break; } } } strDirName.ReleaseBuffer(); if (bSuccess) { if(MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos) { string strTarget=MkDirDlg[MKDIR_EDIT_LINKPATH].strData; Unquote(strTarget); while(!CreateReparsePoint(strTarget, strDirName, MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos==1?RP_JUNCTION:RP_SYMLINKDIR) && !SkipAll) { int Ret = OperationFailed(strDirName, MError, MSG(MCopyCannotCreateLink)); if(Ret == 1) // skip { break; } else if(Ret == 2) { SkipAll = true; break; } else if (Ret < 0 || Ret == 3) // cancel { return; } } } TreeList::AddTreeName(strDirName); } } SrcPanel->Update(UPDATE_KEEP_SELECTION); if (!strDirName.IsEmpty()) { size_t pos; if (FindSlash(pos,strDirName)) strDirName.SetLength(pos); if (!SrcPanel->GoToFile(strDirName) && strDirName.At(strDirName.GetLength()-1)==L'.') { strDirName.SetLength(strDirName.GetLength()-1); SrcPanel->GoToFile(strDirName); } } SrcPanel->Redraw(); Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(SrcPanel); int AnotherType=AnotherPanel->GetType(); if (AnotherPanel->NeedUpdatePanel(SrcPanel) || AnotherType==QVIEW_PANEL) { AnotherPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY); AnotherPanel->Redraw(); } } }
// Кусок для создания SymLink для каталогов. int MkSymLink(const wchar_t *SelName,const wchar_t *Dest,ReparsePointTypes LinkType,DWORD Flags) { if (SelName && *SelName && Dest && *Dest) { string strSrcFullName, strDestFullName, strSelOnlyName; string strMsgBuf, strMsgBuf2; // выделим имя strSelOnlyName = SelName; DeleteEndSlash(strSelOnlyName); const wchar_t *PtrSelName=LastSlash(strSelOnlyName); if (!PtrSelName) PtrSelName=strSelOnlyName; else ++PtrSelName; if (SelName[1] == L':' && (!SelName[2] || (IsSlash(SelName[2]) && !SelName[3]))) // C: или C:/ { // if(Flags&FCOPY_VOLMOUNT) { strSrcFullName = SelName; AddEndSlash(strSrcFullName); } /* Вот здесь - ну очень умное поведение! Т.е. если в качестве SelName передали "C:", то в этом куске происходит коррекция типа линка - с symlink`а на volmount */ LinkType=RP_VOLMOUNT; } else ConvertNameToFull(SelName,strSrcFullName); ConvertNameToFull(Dest,strDestFullName); if (IsSlash(strDestFullName.At(strDestFullName.GetLength()-1))) { if (LinkType!=RP_VOLMOUNT) strDestFullName += PtrSelName; else { const wchar_t Tmp[]={L'D',L'i',L's',L'k',L'_',*SelName,L'\0'}; strDestFullName+=Tmp; } } if (LinkType==RP_VOLMOUNT) { AddEndSlash(strSrcFullName); AddEndSlash(strDestFullName); } DWORD JSAttr=apiGetFileAttributes(strDestFullName); if (JSAttr != INVALID_FILE_ATTRIBUTES) // Существует такой? { if ((JSAttr&FILE_ATTRIBUTE_DIRECTORY)!=FILE_ATTRIBUTE_DIRECTORY) { if (!(Flags&FCOPY_NOSHOWMSGLINK)) { Message(MSG_WARNING,1,MSG(MError), MSG(MCopyCannotCreateJunctionToFile), strDestFullName,MSG(MOk)); } return 0; } if (TestFolder(strDestFullName) == TSTFLD_NOTEMPTY) // а пустой? { // не пустой, ну что же, тогда пробуем сделать dest\srcname AddEndSlash(strDestFullName); if (LinkType==RP_VOLMOUNT) { string strTmpName; strTmpName.Format(MSG(MCopyMountName),*SelName); strDestFullName += strTmpName; AddEndSlash(strDestFullName); } else strDestFullName += PtrSelName; JSAttr=apiGetFileAttributes(strDestFullName); if (JSAttr != INVALID_FILE_ATTRIBUTES) // И такой тоже есть??? { if (TestFolder(strDestFullName) == TSTFLD_NOTEMPTY) // а пустой? { if (!(Flags&FCOPY_NOSHOWMSGLINK)) { if (LinkType==RP_VOLMOUNT) { strMsgBuf.Format(MSG(MCopyMountVolFailed), SelName); strMsgBuf2.Format(MSG(MCopyMountVolFailed2), strDestFullName.CPtr()); Message(MSG_WARNING,1,MSG(MError), strMsgBuf, strMsgBuf2, MSG(MCopyFolderNotEmpty), MSG(MOk)); } else Message(MSG_WARNING,1,MSG(MError), MSG(MCopyCannotCreateLink),strDestFullName, MSG(MCopyFolderNotEmpty),MSG(MOk)); } return 0; // однозначно в морг } } else // создаем. { if (apiCreateDirectory(strDestFullName,nullptr)) TreeList::AddTreeName(strDestFullName); else CreatePath(strDestFullName); } if (apiGetFileAttributes(strDestFullName) == INVALID_FILE_ATTRIBUTES) // так, все очень даже плохо. { if (!(Flags&FCOPY_NOSHOWMSGLINK)) { Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError), MSG(MCopyCannotCreateFolder), strDestFullName,MSG(MOk)); } return 0; } } } else { if (LinkType==RP_SYMLINK || LinkType==RP_SYMLINKFILE || LinkType==RP_SYMLINKDIR) { // в этом случае создается путь, но не сам каталог string strPath=strDestFullName; if (CutToSlash(strPath)) { if (apiGetFileAttributes(strPath)==INVALID_FILE_ATTRIBUTES) CreatePath(strPath); } } else { bool CreateDir=true; if (LinkType==RP_EXACTCOPY) { // в этом случае создается или каталог, или пустой файл DWORD dwSrcAttr=apiGetFileAttributes(strSrcFullName); if (dwSrcAttr!=INVALID_FILE_ATTRIBUTES && !(dwSrcAttr&FILE_ATTRIBUTE_DIRECTORY)) CreateDir=false; } if (CreateDir) { if (apiCreateDirectory(strDestFullName,nullptr)) TreeList::AddTreeName(strDestFullName); else CreatePath(strDestFullName); } else { string strPath=strDestFullName; if (CutToSlash(strPath)) { // создаём if (apiGetFileAttributes(strPath)==INVALID_FILE_ATTRIBUTES) CreatePath(strPath); File file; if(file.Open(strDestFullName, 0, 0, 0, CREATE_NEW, apiGetFileAttributes(strSrcFullName))) { file.Close(); } } } if (apiGetFileAttributes(strDestFullName) == INVALID_FILE_ATTRIBUTES) // так. все очень даже плохо. { if (!(Flags&FCOPY_NOSHOWMSGLINK)) { Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError), MSG(MCopyCannotCreateLink),strDestFullName,MSG(MOk)); } return 0; } } } if (LinkType!=RP_VOLMOUNT) { if (CreateReparsePoint(strSrcFullName,strDestFullName,LinkType)) { return 1; } else { if (!(Flags&FCOPY_NOSHOWMSGLINK)) { Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError), MSG(MCopyCannotCreateLink),strDestFullName,MSG(MOk)); } return 0; } } else { if (CreateVolumeMountPoint(strSrcFullName,strDestFullName)) { return 1; } else { if (!(Flags&FCOPY_NOSHOWMSGLINK)) { strMsgBuf.Format(MSG(MCopyMountVolFailed),SelName); strMsgBuf2.Format(MSG(MCopyMountVolFailed2),strDestFullName.CPtr()); Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),strMsgBuf,strMsgBuf2,MSG(MOk)); } return 0; } } } return 2; }
bool WINAPI CreateReparsePoint(const wchar_t *Target, const wchar_t *Object,DWORD Type) { bool Result=false; if (Object && *Object && Target && *Target) { switch (Type) { case RP_EXACTCOPY: Result=DuplicateReparsePoint(Target,Object); break; case RP_SYMLINK: case RP_SYMLINKFILE: case RP_SYMLINKDIR: if(Type == RP_SYMLINK) { DWORD Attr = apiGetFileAttributes(Target); Type = ((Attr != INVALID_FILE_ATTRIBUTES) && (Attr&FILE_ATTRIBUTE_DIRECTORY)? RP_SYMLINKDIR : RP_SYMLINKFILE); } if (ifn.pfnCreateSymbolicLink) { Result=apiCreateSymbolicLink(Object,Target,Type==RP_SYMLINKDIR?SYMBOLIC_LINK_FLAG_DIRECTORY:0); } else { bool ObjectCreated=false; if (Type==RP_SYMLINKDIR) { ObjectCreated=apiCreateDirectory(Object,nullptr)!=FALSE; } else { File file; if(file.Open(Object,0,0,nullptr,CREATE_NEW)) { ObjectCreated=true; file.Close(); } } if (ObjectCreated) { LPBYTE szBuff=new BYTE[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; if(szBuff) { PREPARSE_DATA_BUFFER rdb=reinterpret_cast<PREPARSE_DATA_BUFFER>(szBuff); rdb->ReparseTag=IO_REPARSE_TAG_SYMLINK; string strPrintName=Target,strSubstituteName=Target; if (IsAbsolutePath(Target)) { strSubstituteName=L"\\??\\"; strSubstituteName+=(strPrintName.CPtr()+(HasPathPrefix(strPrintName)?4:0)); rdb->SymbolicLinkReparseBuffer.Flags=0; } else { rdb->SymbolicLinkReparseBuffer.Flags=SYMLINK_FLAG_RELATIVE; } if (FillREPARSE_DATA_BUFFER(rdb,strPrintName,strPrintName.GetLength(),strSubstituteName,strSubstituteName.GetLength())) { Result=SetREPARSE_DATA_BUFFER(Object,rdb); } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } delete[] szBuff; } } } break; case RP_JUNCTION: case RP_VOLMOUNT: { string strPrintName,strSubstituteName; ConvertNameToFull(Target,strPrintName); strSubstituteName=L"\\??\\"; strSubstituteName+=(strPrintName.CPtr()+(HasPathPrefix(strPrintName)?4:0)); BYTE szBuff[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; PREPARSE_DATA_BUFFER rdb=reinterpret_cast<PREPARSE_DATA_BUFFER>(szBuff); rdb->ReparseTag=IO_REPARSE_TAG_MOUNT_POINT; if (FillREPARSE_DATA_BUFFER(rdb,strPrintName,strPrintName.GetLength(),strSubstituteName,strSubstituteName.GetLength())) { Result=SetREPARSE_DATA_BUFFER(Object,rdb); } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } } break; } } return Result; }
void FilePanels::Init(int DirCount) { SetPanelPositions(FileList::IsModeFullScreen(Opt.LeftPanel.ViewMode), FileList::IsModeFullScreen(Opt.RightPanel.ViewMode)); LeftPanel->SetViewMode(Opt.LeftPanel.ViewMode); RightPanel->SetViewMode(Opt.RightPanel.ViewMode); LeftPanel->SetSortMode(Opt.LeftPanel.SortMode); RightPanel->SetSortMode(Opt.RightPanel.SortMode); LeftPanel->SetNumericSort(Opt.LeftPanel.NumericSort); RightPanel->SetNumericSort(Opt.RightPanel.NumericSort); LeftPanel->SetCaseSensitiveSort(Opt.LeftPanel.CaseSensitiveSort); RightPanel->SetCaseSensitiveSort(Opt.RightPanel.CaseSensitiveSort); LeftPanel->SetSortOrder(Opt.LeftPanel.SortOrder); RightPanel->SetSortOrder(Opt.RightPanel.SortOrder); LeftPanel->SetSortGroups(Opt.LeftPanel.SortGroups); RightPanel->SetSortGroups(Opt.RightPanel.SortGroups); LeftPanel->SetShowShortNamesMode(Opt.LeftPanel.ShowShortNames); RightPanel->SetShowShortNamesMode(Opt.RightPanel.ShowShortNames); LeftPanel->SetSelectedFirstMode(Opt.LeftSelectedFirst); RightPanel->SetSelectedFirstMode(Opt.RightSelectedFirst); LeftPanel->SetDirectoriesFirst(Opt.LeftPanel.DirectoriesFirst); RightPanel->SetDirectoriesFirst(Opt.RightPanel.DirectoriesFirst); SetCanLoseFocus(TRUE); Panel *PassivePanel=nullptr; int PassiveIsLeftFlag=TRUE; if (Opt.LeftPanel.Focus) { ActivePanel=LeftPanel; PassivePanel=RightPanel; PassiveIsLeftFlag=FALSE; } else { ActivePanel=RightPanel; PassivePanel=LeftPanel; PassiveIsLeftFlag=TRUE; } ActivePanel->SetFocus(); // пытаемся избавится от зависания при запуске int IsLocalPath_FarPath = ParsePath(g_strFarPath)==PATH_DRIVELETTER; string strLeft = Opt.strLeftFolder.Get(), strRight = Opt.strRightFolder.Get(); PrepareOptFolder(strLeft, IsLocalPath_FarPath); PrepareOptFolder(strRight, IsLocalPath_FarPath); Opt.strLeftFolder = strLeft; Opt.strRightFolder = strRight; if (Opt.AutoSaveSetup || !DirCount) { if (apiGetFileAttributes(Opt.strLeftFolder)!=INVALID_FILE_ATTRIBUTES) LeftPanel->InitCurDir(Opt.strLeftFolder); if (apiGetFileAttributes(Opt.strRightFolder)!=INVALID_FILE_ATTRIBUTES) RightPanel->InitCurDir(Opt.strRightFolder); } if (!Opt.AutoSaveSetup) { if (DirCount >= 1) { if (ActivePanel==RightPanel) { if (apiGetFileAttributes(Opt.strRightFolder)!=INVALID_FILE_ATTRIBUTES) RightPanel->InitCurDir(Opt.strRightFolder); } else { if (apiGetFileAttributes(Opt.strLeftFolder)!=INVALID_FILE_ATTRIBUTES) LeftPanel->InitCurDir(Opt.strLeftFolder); } if (DirCount == 2) { if (ActivePanel==LeftPanel) { if (apiGetFileAttributes(Opt.strRightFolder)!=INVALID_FILE_ATTRIBUTES) RightPanel->InitCurDir(Opt.strRightFolder); } else { if (apiGetFileAttributes(Opt.strLeftFolder)!=INVALID_FILE_ATTRIBUTES) LeftPanel->InitCurDir(Opt.strLeftFolder); } } } const string& PassiveFolder=PassiveIsLeftFlag?Opt.strLeftFolder:Opt.strRightFolder; if (DirCount < 2 && *PassiveFolder && (apiGetFileAttributes(PassiveFolder)!=INVALID_FILE_ATTRIBUTES)) { PassivePanel->InitCurDir(PassiveFolder); } } #if 1 //! Вначале "показываем" пассивную панель if (PassiveIsLeftFlag) { if (Opt.LeftPanel.Visible) { LeftPanel->Show(); } if (Opt.RightPanel.Visible) { RightPanel->Show(); } } else { if (Opt.RightPanel.Visible) { RightPanel->Show(); } if (Opt.LeftPanel.Visible) { LeftPanel->Show(); } } #endif // при понашенных панелях не забыть бы выставить корректно каталог в CmdLine if (!Opt.RightPanel.Visible && !Opt.LeftPanel.Visible) { CtrlObject->CmdLine->SetCurDir(PassiveIsLeftFlag?Opt.strRightFolder:Opt.strLeftFolder); } SetKeyBar(&MainKeyBar); MainKeyBar.SetOwner(this); }
/* Return: -1 - Error??? 0 - Esc 1 - Enter 2 - Shift-Enter 3 - Ctrl-Enter 4 - F3 5 - F4 6 - Ctrl-Shift-Enter 7 - Ctrl-Alt-Enter */ int History::ProcessMenu(string &strStr, const wchar_t *Title, VMenu &HistoryMenu, int Height, int &Type, Dialog *Dlg) { MenuItemEx MenuItem; HistoryRecord *SelectedRecord=nullptr; FarListPos Pos={0,0}; int Code=-1; int RetCode=1; bool Done=false; bool SetUpMenuPos=false; if (TypeHistory == HISTORYTYPE_DIALOG && HistoryList.Empty()) return 0; while (!Done) { bool IsUpdate=false; HistoryMenu.DeleteItems(); HistoryMenu.Modal::ClearDone(); // заполнение пунктов меню for (const HistoryRecord *HistoryItem=TypeHistory==HISTORYTYPE_DIALOG?HistoryList.Last():HistoryList.First(); HistoryItem ; HistoryItem=TypeHistory==HISTORYTYPE_DIALOG?HistoryList.Prev(HistoryItem):HistoryList.Next(HistoryItem)) { string strRecord = HistoryItem->strName; strRecord.Clear(); if (TypeHistory == HISTORYTYPE_VIEW) { strRecord += GetTitle(HistoryItem->Type); strRecord += L":"; strRecord += (HistoryItem->Type==4?L"-":L" "); } /* TODO: возможно здесь! или выше.... char Date[16],Time[16], OutStr[32]; ConvertDate(HistoryItem->Timestamp,Date,Time,5,TRUE,FALSE,TRUE,TRUE); а дальше strRecord += дату и время */ strRecord += HistoryItem->strName;; if (TypeHistory != HISTORYTYPE_DIALOG) ReplaceStrings(strRecord, L"&",L"&&", -1); MenuItem.Clear(); MenuItem.strName = strRecord; MenuItem.SetCheck(HistoryItem->Lock?1:0); if (!SetUpMenuPos) MenuItem.SetSelect(CurrentItem==HistoryItem || (!CurrentItem && HistoryItem==HistoryList.Last())); HistoryMenu.SetUserData(HistoryItem,sizeof(HistoryItem),HistoryMenu.AddItem(&MenuItem)); } //MenuItem.Clear (); //MenuItem.strName = L" "; //if (!SetUpMenuPos) //MenuItem.SetSelect(CurLastPtr==-1 || CurLastPtr>=HistoryList.Length); //HistoryMenu.SetUserData(nullptr,sizeof(OneItem *),HistoryMenu.AddItem(&MenuItem)); if (TypeHistory == HISTORYTYPE_DIALOG) Dlg->SetComboBoxPos(); else HistoryMenu.SetPosition(-1,-1,0,0); if (SetUpMenuPos) { Pos.SelectPos=Pos.SelectPos < (int)HistoryList.Count() ? Pos.SelectPos : (int)HistoryList.Count()-1; Pos.TopPos=Min(Pos.TopPos,HistoryMenu.GetItemCount()-Height); HistoryMenu.SetSelectPos(&Pos); SetUpMenuPos=false; } /*BUGBUG??? if (TypeHistory == HISTORYTYPE_DIALOG) { // Перед отрисовкой спросим об изменении цветовых атрибутов BYTE RealColors[VMENU_COLOR_COUNT]; FarListColors ListColors={0}; ListColors.ColorCount=VMENU_COLOR_COUNT; ListColors.Colors=RealColors; HistoryMenu.GetColors(&ListColors); if(DlgProc((HANDLE)this,DN_CTLCOLORDLGLIST,CurItem->ID,(LONG_PTR)&ListColors)) HistoryMenu.SetColors(&ListColors); } */ HistoryMenu.Show(); while (!HistoryMenu.Done()) { if (TypeHistory == HISTORYTYPE_DIALOG && (!Dlg->GetDropDownOpened() || HistoryList.Empty())) { HistoryMenu.ProcessKey(KEY_ESC); continue; } int Key=HistoryMenu.ReadInput(); if (TypeHistory == HISTORYTYPE_DIALOG && Key==KEY_TAB) // Tab в списке хистори диалогов - аналог Enter { HistoryMenu.ProcessKey(KEY_ENTER); continue; } HistoryMenu.GetSelectPos(&Pos); HistoryRecord *CurrentRecord=(HistoryRecord *)HistoryMenu.GetUserData(nullptr,sizeof(HistoryRecord *),Pos.SelectPos); switch (Key) { case KEY_CTRLR: // обновить с удалением недоступных { if (TypeHistory == HISTORYTYPE_FOLDER || TypeHistory == HISTORYTYPE_VIEW) { bool ModifiedHistory=false; for (HistoryRecord *HistoryItem=HistoryList.First(); HistoryItem ; HistoryItem=HistoryList.Next(HistoryItem)) { if (HistoryItem->Lock) // залоченные не трогаем continue; // убить запись из истории if (apiGetFileAttributes(HistoryItem->strName) == INVALID_FILE_ATTRIBUTES) { HistoryItem=HistoryList.Delete(HistoryItem); ModifiedHistory=true; } } if (ModifiedHistory) // избавляемся от лишних телодвижений { SaveHistory(); // сохранить HistoryMenu.Modal::SetExitCode(Pos.SelectPos); HistoryMenu.SetUpdateRequired(TRUE); IsUpdate=true; } ResetPosition(); } break; } case KEY_CTRLSHIFTNUMENTER: case KEY_CTRLNUMENTER: case KEY_SHIFTNUMENTER: case KEY_CTRLSHIFTENTER: case KEY_CTRLENTER: case KEY_SHIFTENTER: case KEY_CTRLALTENTER: case KEY_CTRLALTNUMENTER: { if (TypeHistory == HISTORYTYPE_DIALOG) break; HistoryMenu.Modal::SetExitCode(Pos.SelectPos); Done=true; RetCode = Key==KEY_CTRLALTENTER||Key==KEY_CTRLALTNUMENTER?7:(Key==KEY_CTRLSHIFTENTER||Key==KEY_CTRLSHIFTNUMENTER?6:(Key==KEY_SHIFTENTER||Key==KEY_SHIFTNUMENTER?2:3)); break; } case KEY_F3: case KEY_F4: case KEY_NUMPAD5: case KEY_SHIFTNUMPAD5: { if (TypeHistory == HISTORYTYPE_DIALOG) break; HistoryMenu.Modal::SetExitCode(Pos.SelectPos); Done=true; RetCode=(Key==KEY_F4? 5 : 4); break; } // $ 09.04.2001 SVS - Фича - копирование из истории строки в Clipboard case KEY_CTRLC: case KEY_CTRLINS: case KEY_CTRLNUMPAD0: { if (CurrentRecord) CopyToClipboard(CurrentRecord->strName); break; } // Lock/Unlock case KEY_INS: case KEY_NUMPAD0: { if (HistoryMenu.GetItemCount()/* > 1*/) { CurrentItem=CurrentRecord; CurrentItem->Lock=CurrentItem->Lock?false:true; HistoryMenu.Hide(); ResetPosition(); SaveHistory(); HistoryMenu.Modal::SetExitCode(Pos.SelectPos); HistoryMenu.SetUpdateRequired(TRUE); IsUpdate=true; SetUpMenuPos=true; } break; } case KEY_SHIFTNUMDEL: case KEY_SHIFTDEL: { if (HistoryMenu.GetItemCount()/* > 1*/) { if (!CurrentRecord->Lock) { HistoryMenu.Hide(); Delete(CurrentRecord); HistoryMenu.Modal::SetExitCode(Pos.SelectPos); HistoryMenu.SetUpdateRequired(TRUE); IsUpdate=true; SetUpMenuPos=true; } } break; } case KEY_NUMDEL: case KEY_DEL: { if (HistoryMenu.GetItemCount()/* > 1*/ && (!Opt.Confirm.HistoryClear || (Opt.Confirm.HistoryClear && !Message(MSG_WARNING,2, MSG((TypeHistory==HISTORYTYPE_CMD || TypeHistory==HISTORYTYPE_DIALOG?MHistoryTitle: (TypeHistory==HISTORYTYPE_FOLDER?MFolderHistoryTitle:MViewHistoryTitle))), MSG(MHistoryClear), MSG(MClear),MSG(MCancel))))) { for (HistoryRecord *HistoryItem=HistoryList.First(); HistoryItem ; HistoryItem=HistoryList.Next(HistoryItem)) { if (HistoryItem->Lock) // залоченные не трогаем continue; HistoryItem=HistoryList.Delete(HistoryItem); } ResetPosition(); HistoryMenu.Hide(); SaveHistory(); HistoryMenu.Modal::SetExitCode(Pos.SelectPos); HistoryMenu.SetUpdateRequired(TRUE); IsUpdate=true; } break; } default: HistoryMenu.ProcessInput(); break; } } if (IsUpdate) continue; Done=true; Code=HistoryMenu.Modal::GetExitCode(); if (Code >= 0) { SelectedRecord=(HistoryRecord *)HistoryMenu.GetUserData(nullptr,sizeof(HistoryRecord *),Code); if (!SelectedRecord) return -1; //BUGUBUG: eliminate those magic numbers! if (SelectedRecord->Type != 2 && SelectedRecord->Type != 3 // ignore external && RetCode != 3 && ((TypeHistory == HISTORYTYPE_FOLDER && !SelectedRecord->Type) || TypeHistory == HISTORYTYPE_VIEW) && apiGetFileAttributes(SelectedRecord->strName) == INVALID_FILE_ATTRIBUTES) { SetLastError(ERROR_FILE_NOT_FOUND); if (SelectedRecord->Type == 1 && TypeHistory == HISTORYTYPE_VIEW) // Edit? тогда спросим и если надо создадим { if (!Message(MSG_WARNING|MSG_ERRORTYPE,2,Title,SelectedRecord->strName,MSG(MViewHistoryIsCreate),MSG(MHYes),MSG(MHNo))) break; } else { Message(MSG_WARNING|MSG_ERRORTYPE,1,Title,SelectedRecord->strName,MSG(MOk)); } Done=false; SetUpMenuPos=true; HistoryMenu.Modal::SetExitCode(Pos.SelectPos=Code); continue; } } } if (Code < 0 || !SelectedRecord) return 0; if (KeepSelectedPos) { CurrentItem = SelectedRecord; } strStr = SelectedRecord->strName; if (RetCode < 4 || RetCode == 6 || RetCode == 7) { Type=SelectedRecord->Type; } else { Type=RetCode-4; if (Type == 1 && SelectedRecord->Type == 4) Type=4; RetCode=1; } return RetCode; }
int FolderTree::ProcessKey(int Key) { if (Key>=KEY_ALT_BASE+0x01 && Key<=KEY_ALT_BASE+65535) Key=Lower(Key-KEY_ALT_BASE); else if (Key>=KEY_RALT_BASE+0x01 && Key<=KEY_RALT_BASE+65535) Key=Lower(Key-KEY_RALT_BASE); switch (Key) { case KEY_F1: { Help Hlp(L"FindFolder"); } break; case KEY_ESC: case KEY_F10: FrameManager->DeleteFrame(); SetExitCode(XC_MODIFIED); break; case KEY_NUMENTER: case KEY_ENTER: Tree->GetCurDir(strNewFolder); if (apiGetFileAttributes(strNewFolder)!=INVALID_FILE_ATTRIBUTES) { FrameManager->DeleteFrame(); SetExitCode(XC_MODIFIED); } else { Tree->ProcessKey(KEY_ENTER); DrawEdit(); } break; case KEY_F5: IsFullScreen=!IsFullScreen; ResizeConsole(); return TRUE; case KEY_CTRLR: case KEY_RCTRLR: case KEY_F2: Tree->ProcessKey(KEY_CTRLR); DrawEdit(); break; case KEY_CTRLNUMENTER: case KEY_RCTRLNUMENTER: case KEY_CTRLSHIFTNUMENTER: case KEY_RCTRLSHIFTNUMENTER: case KEY_CTRLENTER: case KEY_RCTRLENTER: case KEY_CTRLSHIFTENTER: case KEY_RCTRLSHIFTENTER: { string strName; FindEdit->GetString(strName); Tree->FindPartName(strName,TRUE,Key==KEY_CTRLSHIFTENTER||Key==KEY_RCTRLSHIFTENTER||Key == KEY_CTRLSHIFTNUMENTER||Key == KEY_RCTRLSHIFTNUMENTER?-1:1,1); DrawEdit(); } break; case KEY_UP: case KEY_NUMPAD8: case KEY_DOWN: case KEY_NUMPAD2: case KEY_PGUP: case KEY_NUMPAD9: case KEY_PGDN: case KEY_NUMPAD3: case KEY_HOME: case KEY_NUMPAD7: case KEY_END: case KEY_NUMPAD1: case KEY_MSWHEEL_UP: case(KEY_MSWHEEL_UP | KEY_ALT): case(KEY_MSWHEEL_UP | KEY_RALT): case KEY_MSWHEEL_DOWN: case(KEY_MSWHEEL_DOWN | KEY_ALT): case(KEY_MSWHEEL_DOWN | KEY_RALT): FindEdit->SetString(L""); Tree->ProcessKey(Key); DrawEdit(); break; default: if (Key == KEY_ADD || Key == KEY_SUBTRACT) // OFM: Gray+/Gray- navigation { Tree->ProcessKey(Key); DrawEdit(); break; } /* else { if((Key&(~KEY_CTRLMASK)) == KEY_ADD) Key='+'; else if((Key&(~KEY_CTRLMASK)) == KEY_SUBTRACT) Key='-'; } */ if (FindEdit->ProcessKey(Key)) { string strName; FindEdit->GetString(strName); if (Tree->FindPartName(strName,FALSE,1,1)) strLastName = strName; else { FindEdit->SetString(strLastName); strName = strLastName; } DrawEdit(); } break; } return TRUE; }
bool DizList::Flush(const string& Path,const string* DizName) { if (!Modified) return true; if (DizName) { strDizFileName = *DizName; } else if (strDizFileName.IsEmpty()) { if (!DizData || !Path) return false; strDizFileName = Path; AddEndSlash(strDizFileName); string strArgName; GetCommaWord(Opt.Diz.strListNames,strArgName); strDizFileName += strArgName; } DWORD FileAttr=apiGetFileAttributes(strDizFileName); if (FileAttr != INVALID_FILE_ATTRIBUTES) { if (FileAttr&FILE_ATTRIBUTE_READONLY) { if(Opt.Diz.ROUpdate) { if(apiSetFileAttributes(strDizFileName,FileAttr)) { FileAttr^=FILE_ATTRIBUTE_READONLY; } } } if(!(FileAttr&FILE_ATTRIBUTE_READONLY)) { #if 1 //Maximus5: На некоторых сетевых устройствах атрибуты вообще не устанавливаются // Поэтому возвращается ошибка, и производится попытка Elevation (что бессмысленно) DisableElevation DE; #endif apiSetFileAttributes(strDizFileName,FILE_ATTRIBUTE_ARCHIVE); } else { Message(MSG_WARNING,1,MSG(MError),MSG(MCannotUpdateDiz),MSG(MCannotUpdateRODiz),MSG(MOk)); return false; } } File DizFile; bool AnyError=false; bool EmptyDiz=true; // Don't use CreationDisposition=CREATE_ALWAYS here - it's kills alternate streams if(DizCount && DizFile.Open(strDizFileName, GENERIC_WRITE, FILE_SHARE_READ, nullptr, FileAttr==INVALID_FILE_ATTRIBUTES?CREATE_NEW:TRUNCATE_EXISTING)) { uintptr_t CodePage = Opt.Diz.SaveInUTF ? CP_UTF8 : (Opt.Diz.AnsiByDefault ? CP_ACP : CP_OEMCP); CachedWrite Cache(DizFile); if (CodePage == CP_UTF8) { DWORD dwSignature = SIGN_UTF8; if(!Cache.Write(&dwSignature, 3)) { AnyError=true; } } if(!AnyError) { for (size_t I=0; I<DizCount; I++) { if (!DizData[I]->Deleted) { DWORD Size=static_cast<DWORD>((DizData[I]->DizText.GetLength()+1)*(CodePage == CP_UTF8?3:1)); //UTF-8, up to 3 bytes per char support char* lpDizText = new char[Size]; if (lpDizText) { int BytesCount=WideCharToMultiByte(CodePage, 0, DizData[I]->DizText, static_cast<int>(DizData[I]->DizText.GetLength()+1), lpDizText, Size, nullptr, nullptr); if (BytesCount && BytesCount-1) { if(Cache.Write(lpDizText, BytesCount-1)) { EmptyDiz=false; } else { AnyError=true; break; } if(!Cache.Write("\r\n", 2)) { AnyError=true; break; } } delete[] lpDizText; } } } } if(!AnyError) { if(!Cache.Flush()) { AnyError=true; } } DizFile.Close(); } if (!EmptyDiz && !AnyError) { if (FileAttr==INVALID_FILE_ATTRIBUTES) { FileAttr=FILE_ATTRIBUTE_ARCHIVE|(Opt.Diz.SetHidden?FILE_ATTRIBUTE_HIDDEN:0); } apiSetFileAttributes(strDizFileName,FileAttr); } else { apiDeleteFile(strDizFileName); if(AnyError) { Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MCannotUpdateDiz),MSG(MOk)); return false; } } Modified=false; return true; }