DialogItemEx *DialogBuilder::AddListControl(FARDIALOGITEMTYPES Type, IntOption& Value, string *Text, int Width, int Height, const std::vector<FarDialogBuilderListItem2> &Items, FARDIALOGITEMFLAGS Flags)
{
	const auto Item = AddDialogItem(Type, Text ? Text->c_str() : L"");
	SetNextY(Item);
	Item->X2 = Item->X1 + Width;
	Item->Y2 = Item->Y1 + Height;
	Item->Flags |= DIF_DROPDOWNLIST|Flags;

	m_NextY += Height;

	const auto ListItems = new FarListItem[Items.size()];
	std::transform(ALL_CONST_RANGE(Items), ListItems, [&Value](const auto& i)
	{
		FarListItem NewItem = {};
		NewItem.Text = i.Text.c_str();
		NewItem.Flags = i.Flags | ((Value == i.ItemValue)? LIF_SELECTED : 0);
		NewItem.UserData = i.ItemValue;
		return NewItem;
	});
	const auto List = new FarList;
	List->StructSize = sizeof(FarList);
	List->Items = ListItems;
	List->ItemsNumber = Items.size();
	Item->ListItems = List;

	SetLastItemBinding(new FarListControlBinding<IntOption>(Value, Text, List));
	return Item;
}
Exemple #2
0
static wchar_t* AddString(const string& String)
{
    auto result = new wchar_t[String.size() + 1];
    std::copy(ALL_CONST_RANGE(String), result);
    result[String.size()] = 0;
    return result;
}
Exemple #3
0
size_t find_icase(string_view const Str, string_view const What, size_t Pos)
{
	if (Pos >= Str.size())
		return Str.npos;

	const auto It = std::search(Str.cbegin() + Pos, Str.cend(), ALL_CONST_RANGE(What), equal_icase_t{});
	return It == Str.cend()? Str.npos : It - Str.cbegin();
}
Exemple #4
0
void ScreenBuf::DebugDump() const
{
#ifdef _DEBUG
	string s(Buf.width() + 1, L' ');
	s.back() = L'\n';

	for (size_t row_num = 0; row_num != Buf.height(); ++row_num)
	{
		const auto&& row = Buf[row_num];
		std::transform(ALL_CONST_RANGE(row), s.begin(), [](CONST_REFERENCE(row) i) { return i.Char; });
		OutputDebugString(s.data());
	}
Exemple #5
0
bool NamesList::SetCurName(const string& Name)
{
	bool Result = false;
	const auto ItemIterator = std::find(ALL_CONST_RANGE(Names), Name);

	if (ItemIterator != Names.cend())
	{
		CurPos = ItemIterator;
		Result = true;
	}
	return Result;
}
Exemple #6
0
/* Заполнение виртуального буфера значением из консоли.
*/
void ScreenBuf::FillBuf()
{
	SCOPED_ACTION(CriticalSectionLock)(CS);
	COORD BufferSize={BufX, BufY}, BufferCoord={};
	SMALL_RECT ReadRegion={0, 0, static_cast<SHORT>(BufX-1), static_cast<SHORT>(BufY-1)};
	Global->Console->ReadOutput(Buf.data(), BufferSize, BufferCoord, ReadRegion);
	std::copy(ALL_CONST_RANGE(Buf), Shadow.begin());
	SBFlags.Set(SBFLAGS_USESHADOW);
	COORD CursorPosition;
	Global->Console->GetCursorPosition(CursorPosition);
	CurX=CursorPosition.X;
	CurY=CursorPosition.Y;
}
Exemple #7
0
// try to replace volume GUID (if present) with drive letter
// used by ConvertNameToReal() only
static string TryConvertVolumeGuidToDrivePath(string_view const Path, const string_view AbsPath = {})
{
	string Result(Path);
	size_t DirectoryOffset;
	if (ParsePath(Path, &DirectoryOffset) == root_type::volume)
	{
		if (imports.GetVolumePathNamesForVolumeNameW)
		{
			string VolumePathNames;
			if (os::fs::GetVolumePathNamesForVolumeName(ExtractPathRoot(Path), VolumePathNames))
			{
				for(const auto& i: enum_substrings(VolumePathNames.c_str()))
				{
					if (!AbsPath.empty() && starts_with_icase(AbsPath, i))
						return string(i);

					if (IsRootPath(i))
					{
						Result.replace(0, DirectoryOffset, i.data(), i.size());
						break;
					}
				}
			}

			if (!AbsPath.empty())
				Result.clear();
		}

		else if (!AbsPath.empty())
			Result.clear();

		else
		{
			string strVolumeGuid;
			const os::fs::enum_drives Enumerator(os::fs::get_logical_drives());
			const auto ItemIterator = std::find_if(ALL_CONST_RANGE(Enumerator), [&](const auto& i)
			{
				return os::fs::GetVolumeNameForVolumeMountPoint(os::fs::get_root_directory(i), strVolumeGuid) && starts_with(Path, string_view(strVolumeGuid).substr(0, DirectoryOffset));
			});
			if (ItemIterator != Enumerator.cend())
			{
				Result.replace(0, DirectoryOffset, os::fs::get_drive(*ItemIterator));
			}
		}
	}

	else if (!AbsPath.empty())
		Result.clear();

	return Result;
}
Exemple #8
0
int DialogBuilder::AddTextWrap(const wchar_t *text, bool center, int width)
{
	string str(text);
	FarFormatText(str, width <= 0 ? ScrX-1-10 : width, str, L"\n", 0);
	int LineCount = 1 + std::count(ALL_CONST_RANGE(str), L'\n');
	std::replace(ALL_RANGE(str), L'\n', L'\0');
	const wchar_t *ps = str.data();
	for (int i = 0; i < LineCount; ++i, ps += wcslen(ps) + 1)
	{
		const auto Text = AddText(ps);
		Text->Flags = (center ? DIF_CENTERTEXT : 0);
	}
	return LineCount;
}
Exemple #9
0
DizList::desc_map::iterator DizList::AddRecord(const string& DizText)
{
	string::const_iterator NameBegin, NameEnd, DescBegin;

	if (DizText.front() == L'"')
	{
		NameBegin = DizText.cbegin() + 1;
		NameEnd = std::find(NameBegin, DizText.cend(), L'"');
		DescBegin = NameEnd == DizText.cend()? NameEnd : NameEnd + 1;
	}
	else
	{
		NameBegin = DizText.cbegin();
		NameEnd = std::find_if(ALL_CONST_RANGE(DizText), IsSpace);
		DescBegin = NameEnd;
	}

	return AddRecord(string(NameBegin, NameEnd), string(DescBegin, DizText.end()));
}
Exemple #10
0
bool filemasks::Set(const string& masks, DWORD Flags)
{
	bool Result = false;

	if (!masks.empty())
	{
		Free();

		string expmasks(masks);
		std::list<string> UsedGroups;
		size_t LBPos, RBPos;

		while((LBPos = expmasks.find(L'<')) != string::npos && (RBPos = expmasks.find(L'>', LBPos)) != string::npos)
		{
			string MaskGroupNameWB = expmasks.substr(LBPos, RBPos-LBPos+1);
			string MaskGroupName = expmasks.substr(LBPos+1, RBPos-LBPos-1);
			string MaskGroupValue;
			if (std::find(ALL_CONST_RANGE(UsedGroups), MaskGroupName) == UsedGroups.cend())
			{
				Global->Db->GeneralCfg()->GetValue(L"Masks", MaskGroupName, MaskGroupValue, L"");
				ReplaceStrings(expmasks, MaskGroupNameWB, MaskGroupValue);
				UsedGroups.emplace_back(MaskGroupName);
			}
			else
			{
				ReplaceStrings(expmasks, MaskGroupNameWB, L"");	
			}
		}

		if (!expmasks.empty())
		{
			const wchar_t* ptr = expmasks.data();

			string SimpleMasksInclude, SimpleMasksExclude;

			auto DestContainer = &Include;
			auto DestString = &SimpleMasksInclude;

			Result = true;

			while(*ptr)
			{
				ptr = SkipSeparators(ptr);
				auto nextpos = SkipRE(ptr);
				if (nextpos != ptr)
				{
					filemasks::masks m;
					Result = m.Set(string(ptr, nextpos-ptr));
					if (Result)
					{
						DestContainer->emplace_back(std::move(m));
						ptr = nextpos;
					}
					else
					{
						break;
					}
					ptr = nextpos;
				}
				ptr = SkipSeparators(ptr);
				nextpos = SkipMasks(ptr);
				if (nextpos != ptr)
				{
					*DestString += string(ptr, nextpos-ptr);
					ptr = nextpos;
				}
				if (*ptr == ExcludeMaskSeparator)
				{
					if (DestContainer != &Exclude)
					{
						DestContainer = &Exclude;
						DestString = &SimpleMasksExclude;
					}
					else
					{
						break;
					}
					++ptr;
				}
			}

			if (Result && !SimpleMasksInclude.empty())
			{
				filemasks::masks m;
				Result = m.Set(SimpleMasksInclude);
				if (Result)
					Include.emplace_back(std::move(m));
			}

			if (Result && !SimpleMasksExclude.empty())
			{
				filemasks::masks m;
				Result = m.Set(SimpleMasksExclude);
				if (Result)
					Exclude.emplace_back(std::move(m));
			}

			if (Result && Include.empty() && !Exclude.empty())
			{
				Include.emplace_back(VALUE_TYPE(Include)());
				Result = Include.back().Set(L"*");
			}

			Result = !empty();
		}

		if (!Result)
		{
			if (!(Flags & FMF_SILENT))
			{
				ErrorMessage();
			}
			Free();
		}

	}

	return Result;
}
Exemple #11
0
bool filemasks::empty() const
{
	return std::all_of(ALL_CONST_RANGE(Include), std::mem_fn(&masks::empty)) &&
	       std::all_of(ALL_CONST_RANGE(Exclude), std::mem_fn(&masks::empty));
}
Exemple #12
0
bool contains_icase(const string_view Str, const string_view Token)
{
	return std::search(ALL_CONST_RANGE(Str), ALL_CONST_RANGE(Token), equal_icase_t{}) != Str.cend();
}
Exemple #13
0
bool GetFileFormat(
	api::fs::file& file, uintptr_t& nCodePage, bool* pSignatureFound, bool bUseHeuristics, bool* pPureAscii)
{
	DWORD dwTemp = 0;
	bool bSignatureFound = false;
	bool bDetect = false;
	bool bPureAscii = false;

	size_t Readed = 0;
	if (file.Read(&dwTemp, sizeof(dwTemp), Readed) && Readed > 1 ) // minimum signature size is 2 bytes
	{
		if (LOWORD(dwTemp) == SIGN_UNICODE)
		{
			nCodePage = CP_UNICODE;
			file.SetPointer(2, nullptr, FILE_BEGIN);
			bSignatureFound = true;
		}
		else if (LOWORD(dwTemp) == SIGN_REVERSEBOM)
		{
			nCodePage = CP_REVERSEBOM;
			file.SetPointer(2, nullptr, FILE_BEGIN);
			bSignatureFound = true;
		}
		else if ((dwTemp & 0x00FFFFFF) == SIGN_UTF8)
		{
			nCodePage = CP_UTF8;
			file.SetPointer(3, nullptr, FILE_BEGIN);
			bSignatureFound = true;
		}
		else
		{
			file.SetPointer(0, nullptr, FILE_BEGIN);
		}
	}

	if (bSignatureFound)
	{
		bDetect = true;
	}
	else if (bUseHeuristics)
	{
		file.SetPointer(0, nullptr, FILE_BEGIN);
		size_t Size = 0x8000; // BUGBUG. TODO: configurable
		char_ptr Buffer(Size);
		size_t ReadSize = 0;
		bool ReadResult = file.Read(Buffer.get(), Size, ReadSize);
		file.SetPointer(0, nullptr, FILE_BEGIN);

		bPureAscii = ReadResult && !ReadSize; // empty file == pure ascii

		if (ReadResult && ReadSize)
		{
			// BUGBUG MSDN documents IS_TEXT_UNICODE_BUFFER_TOO_SMALL but there is no such thing
			if (ReadSize > 1)
			{
				int test = IS_TEXT_UNICODE_UNICODE_MASK | IS_TEXT_UNICODE_REVERSE_MASK | IS_TEXT_UNICODE_NOT_UNICODE_MASK | IS_TEXT_UNICODE_NOT_ASCII_MASK;

				IsTextUnicode(Buffer.get(), static_cast<int>(ReadSize), &test); // return value is ignored, it's ok.

				if (!(test & IS_TEXT_UNICODE_NOT_UNICODE_MASK) && (test & IS_TEXT_UNICODE_NOT_ASCII_MASK))
				{
					if (test & IS_TEXT_UNICODE_UNICODE_MASK)
					{
						nCodePage = CP_UNICODE;
						bDetect = true;
					}
					else if (test & IS_TEXT_UNICODE_REVERSE_MASK)
					{
						nCodePage = CP_REVERSEBOM;
						bDetect = true;
					}
				}

				if (!bDetect && IsTextUTF8(Buffer.get(), ReadSize, bPureAscii))
				{
					nCodePage = CP_UTF8;
					bDetect = true;
				}
			}

			if (!bDetect && !bPureAscii)
			{
				int cp = GetCpUsingUniversalDetector(Buffer.get(), ReadSize);
				if ( cp >= 0 )
				{
					if (Global->Opt->strNoAutoDetectCP.Get() == L"-1")
					{
						if ( Global->Opt->CPMenuMode )
						{
							if ( static_cast<UINT>(cp) != GetACP() && static_cast<UINT>(cp) != GetOEMCP() )
							{
								long long selectType = Codepages().GetFavorite(cp);
								if (0 == (selectType & CPST_FAVORITE))
									cp = -1;
							}
						}
					}
					else
					{
						std::vector<string> BannedCpList;
						split(BannedCpList, Global->Opt->strNoAutoDetectCP, STLF_UNIQUE);

						if (std::find(ALL_CONST_RANGE(BannedCpList), std::to_wstring(cp)) != BannedCpList.cend())
						{
							cp = -1;
						}
					}
				}

				if (cp != -1)
				{
					nCodePage = cp;
					bDetect = true;
				}
			}
		}
	}

	if (pSignatureFound)
		*pSignatureFound = bSignatureFound;

	if (pPureAscii)
		*pPureAscii = bPureAscii;

	return bDetect;
}
Exemple #14
0
int Panel::SetPluginCommand(int Command,int Param1,void* Param2)
{
	_ALGO(CleverSysLog clv(L"Panel::SetPluginCommand"));
	_ALGO(SysLog(L"(Command=%s, Param1=[%d/0x%08X], Param2=[%d/0x%08X])",_FCTL_ToName(Command),(int)Param1,Param1,(int)Param2,Param2));
	int Result=FALSE;
	ProcessingPluginCommand++;

	switch (Command)
	{
		case FCTL_SETVIEWMODE:
			Result = Parent()->ChangePanelViewMode(shared_from_this(), Param1, Parent()->IsTopWindow());
			break;

		case FCTL_SETSORTMODE:
		{
			int Mode=Param1;

			if ((Mode>SM_DEFAULT) && (Mode < SM_COUNT))
			{
				SetSortMode(panel_sort(Mode - 1)); // Уменьшим на 1 из-за SM_DEFAULT
				Result=TRUE;
			}
			break;
		}

		case FCTL_SETSORTORDER:
		{
			ChangeSortOrder(Param1 != 0);
			Result=TRUE;
			break;
		}

		case FCTL_SETDIRECTORIESFIRST:
		{
			ChangeDirectoriesFirst(Param1 != 0);
			Result=TRUE;
			break;
		}

		case FCTL_CLOSEPANEL:
			if (m_PanelMode == panel_mode::PLUGIN_PANEL)
			{
				string folder=NullToEmpty((const wchar_t *)Param2);
				SetCurDir(folder,true);
				if (folder.empty())
					Update(UPDATE_KEEP_SELECTION);
				Redraw();
			}
			Result=TRUE;
			break;

		case FCTL_GETPANELINFO:
		{
			PanelInfo *Info=(PanelInfo *)Param2;

			if(!CheckStructSize(Info))
				break;

			*Info = {};
			Info->StructSize = sizeof(PanelInfo);

			UpdateIfRequired();
			Info->OwnerGuid=FarGuid;
			Info->PluginHandle=nullptr;

			switch (GetType())
			{
			case panel_type::FILE_PANEL:
				Info->PanelType=PTYPE_FILEPANEL;
				break;
			case panel_type::TREE_PANEL:
				Info->PanelType=PTYPE_TREEPANEL;
				break;
			case panel_type::QVIEW_PANEL:
				Info->PanelType=PTYPE_QVIEWPANEL;
				break;
			case panel_type::INFO_PANEL:
				Info->PanelType=PTYPE_INFOPANEL;
				break;
			}

			int X1,Y1,X2,Y2;
			GetPosition(X1,Y1,X2,Y2);
			Info->PanelRect.left=X1;
			Info->PanelRect.top=Y1;
			Info->PanelRect.right=X2;
			Info->PanelRect.bottom=Y2;
			Info->ViewMode=GetViewMode();
			Info->SortMode = static_cast<OPENPANELINFO_SORTMODES>((GetSortMode() < panel_sort::COUNT? SM_UNSORTED - static_cast<int>(panel_sort::UNSORTED) : 0) + static_cast<int>(GetSortMode()));

			Info->Flags |= Global->Opt->ShowHidden? PFLAGS_SHOWHIDDEN : 0;
			Info->Flags |= Global->Opt->Highlight? PFLAGS_HIGHLIGHT : 0;
			Info->Flags |= GetSortOrder()? PFLAGS_REVERSESORTORDER : 0;
			Info->Flags |= GetSortGroups()? PFLAGS_USESORTGROUPS : 0;
			Info->Flags |= GetSelectedFirstMode()? PFLAGS_SELECTEDFIRST : 0;
			Info->Flags |= GetDirectoriesFirst()? PFLAGS_DIRECTORIESFIRST : 0;
			Info->Flags |= (GetMode() == panel_mode::PLUGIN_PANEL)? PFLAGS_PLUGIN : 0;
			Info->Flags |= IsVisible()? PFLAGS_VISIBLE : 0;
			Info->Flags |= IsFocused()? PFLAGS_FOCUS : 0;
			Info->Flags |= Parent()->IsLeft(this)? PFLAGS_PANELLEFT : 0;

			if (GetType() == panel_type::FILE_PANEL)
			{
				FileList *DestFilePanel=(FileList *)this;

				if (Info->Flags&PFLAGS_PLUGIN)
				{
					Info->OwnerGuid = DestFilePanel->GetPluginHandle()->plugin()->Id();
					Info->PluginHandle = DestFilePanel->GetPluginHandle()->panel();
					static int Reenter=0;
					if (!Reenter)
					{
						Reenter++;
						OpenPanelInfo PInfo;
						DestFilePanel->GetOpenPanelInfo(&PInfo);

						if (PInfo.Flags & OPIF_REALNAMES)
							Info->Flags |= PFLAGS_REALNAMES;

						if (PInfo.Flags & OPIF_DISABLEHIGHLIGHTING)
							Info->Flags &= ~PFLAGS_HIGHLIGHT;

						if (PInfo.Flags & OPIF_USECRC32)
							Info->Flags |= PFLAGS_USECRC32;

						if (PInfo.Flags & OPIF_SHORTCUT)
							Info->Flags |= PFLAGS_SHORTCUT;

						Reenter--;
					}
				}

				DestFilePanel->PluginGetPanelInfo(*Info);
			}

			if (!(Info->Flags&PFLAGS_PLUGIN)) // $ 12.12.2001 DJ - на неплагиновой панели - всегда реальные имена
				Info->Flags |= PFLAGS_REALNAMES;

			Result=TRUE;
			break;
		}

		case FCTL_GETPANELPREFIX:
		{
			string strTemp;

			if (GetType() == panel_type::FILE_PANEL && GetMode() == panel_mode::PLUGIN_PANEL)
			{
				PluginInfo PInfo = {sizeof(PInfo)};
				FileList *DestPanel = ((FileList*)this);
				if (DestPanel->GetPluginInfo(&PInfo))
					strTemp = NullToEmpty(PInfo.CommandPrefix);
			}

			if (Param1&&Param2)
				xwcsncpy((wchar_t*)Param2, strTemp.c_str(), Param1);

			Result=(int)strTemp.size()+1;
			break;
		}

		case FCTL_GETPANELHOSTFILE:
		case FCTL_GETPANELFORMAT:
		{
			string strTemp;

			if (GetType() == panel_type::FILE_PANEL)
			{
				FileList *DestFilePanel=(FileList *)this;
				static int Reenter=0;

				if (!Reenter && GetMode() == panel_mode::PLUGIN_PANEL)
				{
					Reenter++;

					OpenPanelInfo PInfo;
					DestFilePanel->GetOpenPanelInfo(&PInfo);

					switch (Command)
					{
						case FCTL_GETPANELHOSTFILE:
							strTemp=NullToEmpty(PInfo.HostFile);
							break;
						case FCTL_GETPANELFORMAT:
							strTemp=NullToEmpty(PInfo.Format);
							break;
					}

					Reenter--;
				}
			}

			if (Param1&&Param2)
				xwcsncpy((wchar_t*)Param2, strTemp.c_str(), Param1);

			Result=(int)strTemp.size()+1;
			break;
		}
		case FCTL_GETPANELDIRECTORY:
		{
			static int Reenter=0;
			if(!Reenter)
			{
				Reenter++;
				ShortcutInfo Info;
				GetShortcutInfo(Info);
				Result = static_cast<int>(aligned_sizeof<FarPanelDirectory>());
				const auto folderOffset = Result;
				Result+=static_cast<int>(sizeof(wchar_t)*(Info.ShortcutFolder.size()+1));
				const auto pluginFileOffset = Result;
				Result+=static_cast<int>(sizeof(wchar_t)*(Info.PluginFile.size()+1));
				const auto pluginDataOffset = Result;
				Result+=static_cast<int>(sizeof(wchar_t)*(Info.PluginData.size()+1));
				const auto dirInfo = static_cast<FarPanelDirectory*>(Param2);
				if(Param1>=Result && CheckStructSize(dirInfo))
				{
					dirInfo->StructSize=sizeof(FarPanelDirectory);
					dirInfo->PluginId=Info.PluginGuid;
					dirInfo->Name = static_cast<wchar_t*>(static_cast<void*>(static_cast<char*>(Param2) + folderOffset));
					dirInfo->Param = static_cast<wchar_t*>(static_cast<void*>(static_cast<char*>(Param2) + pluginDataOffset));
					dirInfo->File = static_cast<wchar_t*>(static_cast<void*>(static_cast<char*>(Param2) + pluginFileOffset));
					*std::copy(ALL_CONST_RANGE(Info.ShortcutFolder), const_cast<wchar_t*>(dirInfo->Name)) = L'\0';
					*std::copy(ALL_CONST_RANGE(Info.PluginData), const_cast<wchar_t*>(dirInfo->Param)) = L'\0';
					*std::copy(ALL_CONST_RANGE(Info.PluginFile), const_cast<wchar_t*>(dirInfo->File)) = L'\0';
				}
				Reenter--;
			}
			break;
		}

		case FCTL_GETCOLUMNTYPES:
		case FCTL_GETCOLUMNWIDTHS:

			if (GetType() == panel_type::FILE_PANEL)
			{
				string strColumnTypes,strColumnWidths;
				((FileList *)this)->PluginGetColumnTypesAndWidths(strColumnTypes,strColumnWidths);

				if (Command==FCTL_GETCOLUMNTYPES)
				{
					if (Param1&&Param2)
						xwcsncpy((wchar_t*)Param2,strColumnTypes.c_str(),Param1);

					Result=(int)strColumnTypes.size()+1;
				}
				else
				{
					if (Param1&&Param2)
						xwcsncpy((wchar_t*)Param2,strColumnWidths.c_str(),Param1);

					Result=(int)strColumnWidths.size()+1;
				}
			}
			break;

		case FCTL_GETPANELITEM:
		{
			if (GetType() == panel_type::FILE_PANEL && CheckNullOrStructSize(static_cast<FarGetPluginPanelItem*>(Param2)))
				Result = static_cast<int>(static_cast<FileList*>(this)->PluginGetPanelItem(Param1, static_cast<FarGetPluginPanelItem*>(Param2)));
			break;
		}

		case FCTL_GETSELECTEDPANELITEM:
		{
			if (GetType() == panel_type::FILE_PANEL && CheckNullOrStructSize(static_cast<FarGetPluginPanelItem*>(Param2)))
				Result = static_cast<int>(static_cast<FileList*>(this)->PluginGetSelectedPanelItem(Param1, static_cast<FarGetPluginPanelItem*>(Param2)));
			break;
		}

		case FCTL_GETCURRENTPANELITEM:
		{
			if (GetType() == panel_type::FILE_PANEL && CheckNullOrStructSize(static_cast<FarGetPluginPanelItem*>(Param2)))
			{
				PanelInfo Info;
				const auto DestPanel = static_cast<FileList*>(this);
				DestPanel->PluginGetPanelInfo(Info);
				Result = static_cast<int>(DestPanel->PluginGetPanelItem(static_cast<int>(Info.CurrentItem), static_cast<FarGetPluginPanelItem*>(Param2)));
			}
			break;
		}

		case FCTL_BEGINSELECTION:
		{
			if (GetType() == panel_type::FILE_PANEL)
			{
				((FileList *)this)->PluginBeginSelection();
				Result=TRUE;
			}
			break;
		}

		case FCTL_SETSELECTION:
		{
			if (GetType() == panel_type::FILE_PANEL)
			{
				((FileList *)this)->PluginSetSelection(Param1, Param2 != nullptr);
				Result=TRUE;
			}
			break;
		}

		case FCTL_CLEARSELECTION:
		{
			if (GetType() == panel_type::FILE_PANEL)
			{
				static_cast<FileList*>(this)->PluginClearSelection(Param1);
				Result=TRUE;
			}
			break;
		}

		case FCTL_ENDSELECTION:
		{
			if (GetType() == panel_type::FILE_PANEL)
			{
				((FileList *)this)->PluginEndSelection();
				Result=TRUE;
			}
			break;
		}

		case FCTL_UPDATEPANEL:
			Update(Param1?UPDATE_KEEP_SELECTION:0);

			if (GetType() == panel_type::QVIEW_PANEL)
				UpdateViewPanel();

			Result=TRUE;
			break;

		case FCTL_REDRAWPANEL:
		{
			PanelRedrawInfo *Info=(PanelRedrawInfo *)Param2;

			if (CheckStructSize(Info))
			{
				m_CurFile=static_cast<int>(Info->CurrentItem);
				m_CurTopFile=static_cast<int>(Info->TopPanelItem);
			}

			// $ 12.05.2001 DJ перерисовываемся только в том случае, если мы - текущее окно
			if (Parent()->IsTopWindow())
				Redraw();

			Result=TRUE;
			break;
		}

		case FCTL_SETPANELDIRECTORY:
		{
			const auto dirInfo = static_cast<const FarPanelDirectory*>(Param2);
			if (CheckStructSize(dirInfo))
			{
				Result = ExecShortcutFolder(NullToEmpty(dirInfo->Name), dirInfo->PluginId, NullToEmpty(dirInfo->File), NullToEmpty(dirInfo->Param), false, false, true);
				// restore current directory to active panel path
				if (!IsFocused())
				{
					Parent()->ActivePanel()->SetCurPath();
				}
			}
			break;
		}

		case FCTL_SETACTIVEPANEL:
		{
			if (IsVisible())
			{
				Parent()->SetActivePanel(this);
				Result=TRUE;
			}
			break;
		}
	}

	ProcessingPluginCommand--;
	return Result;
}
Exemple #15
0
static bool FillREPARSE_DATA_BUFFER(REPARSE_DATA_BUFFER* rdb, const string& PrintName, const string& SubstituteName)
{
	switch (rdb->ReparseTag)
	{
	// IO_REPARSE_TAG_MOUNT_POINT and IO_REPARSE_TAG_SYMLINK buffers are filled differently:
	// different order of print and substitute names and additional zero bytes in IO_REPARSE_TAG_MOUNT_POINT.
	// No particular reason to do that, but Windows for some reason does and we just mimic its approach to make
	// reparse points created by Far indistinguishable from created by, say, mklink.

	case IO_REPARSE_TAG_MOUNT_POINT:
		{
			const size_t SubstituteNameOffset = 0;
			const size_t SubstituteNameLength = SubstituteName.size() * sizeof(wchar_t);
			const size_t PrintNameOffset = SubstituteNameLength + 1 * sizeof(wchar_t);
			const size_t PrintNameLength = PrintName.size() * sizeof(wchar_t);
			const size_t ReparseDataLength = offsetof(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) - REPARSE_DATA_BUFFER_HEADER_SIZE + PrintNameOffset + PrintNameLength + 1 * sizeof(wchar_t);

			if (ReparseDataLength + REPARSE_DATA_BUFFER_HEADER_SIZE > MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
				return false;

			rdb->ReparseDataLength = static_cast<USHORT>(ReparseDataLength);
			rdb->Reserved = 0;

			auto& Buffer = rdb->MountPointReparseBuffer;
			Buffer.SubstituteNameOffset = static_cast<USHORT>(SubstituteNameOffset);
			Buffer.SubstituteNameLength = static_cast<USHORT>(SubstituteNameLength);
			Buffer.PrintNameOffset = static_cast<USHORT>(PrintNameOffset);
			Buffer.PrintNameLength = static_cast<USHORT>(PrintNameLength);
			*std::copy(ALL_CONST_RANGE(SubstituteName), Buffer.PathBuffer + SubstituteNameOffset / sizeof(wchar_t)) = 0;
			*std::copy(ALL_CONST_RANGE(PrintName), Buffer.PathBuffer + PrintNameOffset / sizeof(wchar_t)) = 0;
			return true;
		}

	case IO_REPARSE_TAG_SYMLINK:
		{
			const size_t PrintNameOffset = 0;
			const size_t PrintNameLength = PrintName.size() * sizeof(wchar_t);
			const size_t SubstituteNameOffset = PrintNameLength;
			const size_t SubstituteNameLength = SubstituteName.size() * sizeof(wchar_t);
			const size_t ReparseDataLength = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) - REPARSE_DATA_BUFFER_HEADER_SIZE + SubstituteNameOffset + SubstituteNameLength;

			if (ReparseDataLength + REPARSE_DATA_BUFFER_HEADER_SIZE > MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
				return false;

			rdb->ReparseDataLength = static_cast<USHORT>(ReparseDataLength);
			rdb->Reserved = 0;

			auto& Buffer = rdb->SymbolicLinkReparseBuffer;
			Buffer.SubstituteNameOffset = static_cast<USHORT>(SubstituteNameOffset);
			Buffer.SubstituteNameLength = static_cast<USHORT>(SubstituteNameLength);
			Buffer.PrintNameOffset = static_cast<USHORT>(PrintNameOffset);
			Buffer.PrintNameLength = static_cast<USHORT>(PrintNameLength);
			std::copy(ALL_CONST_RANGE(SubstituteName), Buffer.PathBuffer + SubstituteNameOffset / sizeof(wchar_t));
			std::copy(ALL_CONST_RANGE(PrintName), Buffer.PathBuffer + PrintNameOffset / sizeof(wchar_t));
			return true;
		}

	default:
		return false;
	}
}
Exemple #16
0
/* $ 06.07.2001
   + Используем filemasks вместо GetCommaWord, этим самым добиваемся того, что
     можно использовать маски исключения
   - Убрал непонятный мне запрет на использование маски файлов типа "*.*"
     (был когда-то, вроде, такой баг-репорт)
*/
bool ProcessLocalFileTypes(const string& Name, const string& ShortName, FILETYPE_MODE Mode, bool AlwaysWaitFinish)
{
	string strCommand, strDescription, strMask;
	{
		const auto TypesMenu = VMenu2::create(MSG(MSelectAssocTitle), nullptr, 0, ScrY - 4);
		TypesMenu->SetHelp(L"FileAssoc");
		TypesMenu->SetMenuFlags(VMENU_WRAPMODE);
		TypesMenu->SetId(SelectAssocMenuId);

		int ActualCmdCount=0; // отображаемых ассоциаций в меню
		filemasks FMask; // для работы с масками файлов

		int CommandCount=0;
		DWORD Index=0;
		unsigned __int64 id;
		string FileName = PointToName(Name);

		while (ConfigProvider().AssocConfig()->EnumMasksForType(Mode,Index++,&id,strMask))
		{
			strCommand.clear();

			if (FMask.Set(strMask,FMF_SILENT))
			{
				if (FMask.Compare(FileName))
				{
					ConfigProvider().AssocConfig()->GetCommand(id,Mode,strCommand);

					if (!strCommand.empty())
					{
						ConfigProvider().AssocConfig()->GetDescription(id,strDescription);
						CommandCount++;
					}
				}

				if (strCommand.empty())
					continue;
			}

			string strCommandText = strCommand;
			SubstFileName(nullptr,strCommandText,Name, ShortName,nullptr,nullptr,nullptr,nullptr,TRUE);

			// все "подставлено", теперь проверим условия "if exist"
			if (!ExtractIfExistCommand(strCommandText))
				continue;

			ActualCmdCount++;

			if (!strDescription.empty())
				SubstFileName(nullptr,strDescription, Name, ShortName, nullptr, nullptr, nullptr, nullptr, TRUE);
			else
				strDescription = strCommandText;

			MenuItemEx TypesMenuItem(strDescription);
			TypesMenuItem.SetSelect(Index==1);
			TypesMenuItem.UserData = strCommand;
			TypesMenu->AddItem(TypesMenuItem);
		}

		if (!CommandCount)
			return false;

		if (!ActualCmdCount)
			return true;

		int ExitCode=0;

		if (ActualCmdCount>1)
		{
			ExitCode=TypesMenu->Run();

			if (ExitCode<0)
				return true;
		}

		strCommand = *TypesMenu->GetUserDataPtr<string>(ExitCode);
	}

	string strListName, strAnotherListName, strShortListName, strAnotherShortListName;

	const string* ListNames[] =
	{
		&strListName,
		&strAnotherListName,
		&strShortListName,
		&strAnotherShortListName
	};

	int PreserveLFN=SubstFileName(nullptr,strCommand, Name, ShortName, &strListName, &strAnotherListName, &strShortListName, &strAnotherShortListName);
	const auto ListFileUsed = !std::all_of(ALL_CONST_RANGE(ListNames), std::mem_fn(&string::empty));

	// Снова все "подставлено", теперь проверим условия "if exist"
	if (ExtractIfExistCommand(strCommand))
	{
		SCOPED_ACTION(PreserveLongName)(ShortName, PreserveLFN);
		RemoveExternalSpaces(strCommand);

		if (!strCommand.empty())
		{
			Global->CtrlObject->CmdLine()->ExecString(strCommand,AlwaysWaitFinish, false, false, ListFileUsed, false,
				Mode == FILETYPE_VIEW || Mode == FILETYPE_ALTVIEW || Mode == FILETYPE_EDIT || Mode == FILETYPE_ALTEDIT);
			if (!(Global->Opt->ExcludeCmdHistory&EXCLUDECMDHISTORY_NOTFARASS) && !AlwaysWaitFinish) //AN
			{
				const auto curDir = Global->CtrlObject->CmdLine()->GetCurDir();
				Global->CtrlObject->CmdHistory->AddToHistory(strCommand, HR_DEFAULT, nullptr, nullptr, curDir.data());
			}
		}
	}

	std::for_each(CONST_RANGE(ListNames, i)
	{
		if (!i->empty())
			os::DeleteFile(*i);
	});
Exemple #17
0
bool equal_icase(const string_view Str1, const string_view Str2)
{
	return std::equal(ALL_CONST_RANGE(Str1), ALL_CONST_RANGE(Str2), equal_icase_t{});
}
void EnumFiles(VMenu2& Menu, const string& Str)
{
	if(!Str.empty())
	{
		string strStr(Str);

		size_t Pos = 0;
		if(std::count(ALL_CONST_RANGE(strStr), L'"') & 1) // odd quotes count
		{
			Pos = strStr.rfind(L'"');
		}
		else
		{
			for(Pos=strStr.size()-1; Pos!=static_cast<size_t>(-1); Pos--)
			{
				if(strStr[Pos]==L'"')
				{
					Pos--;
					while(strStr[Pos]!=L'"' && Pos!=static_cast<size_t>(-1))
					{
						Pos--;
					}
				}
				else if(strStr[Pos]==L' ')
				{
					Pos++;
					break;
				}
			}
		}
		if(Pos==static_cast<size_t>(-1))
		{
			Pos=0;
		}
		bool StartQuote=false;
		if(Pos < strStr.size() && strStr[Pos]==L'"')
		{
			Pos++;
			StartQuote=true;
		}
		string strStart(strStr.data(),Pos);
		Unquote(strStr.erase(0, Pos));
		if(!strStr.empty())
		{
			string strExp = os::env::expand_strings(strStr);
			os::fs::enum_file Find(strExp+L"*");
			bool Separator=false;
			std::for_each(CONST_RANGE(Find, i)
			{
				const wchar_t* FileName=PointToName(strStr);
				bool NameMatch=!StrCmpNI(FileName, i.strFileName.data(), StrLength(FileName)), AltNameMatch = NameMatch? false : !StrCmpNI(FileName, i.strAlternateFileName.data(), StrLength(FileName));
				if(NameMatch || AltNameMatch)
				{
					strStr.resize(FileName-strStr.data());
					string strAdd (strStr + (NameMatch ? i.strFileName : i.strAlternateFileName));
					if (!StartQuote)
						QuoteSpace(strAdd);

					string strTmp(strStart+strAdd);
					if(StartQuote)
						strTmp += L'"';

					if(!Separator)
					{
						if(Menu.GetItemCount())
						{
							MenuItemEx Item;
							Item.strName = MSG(MCompletionFilesTitle);
							Item.Flags=LIF_SEPARATOR;
							Menu.AddItem(Item);
						}
						else
						{
							Menu.SetTitle(MSG(MCompletionFilesTitle));
						}
						Separator=true;
					}
					Menu.AddItem(strTmp);
				}
			});
Exemple #19
0
/* "Сбросить" виртуальный буфер на консоль
*/
void ScreenBuf::Flush(bool SuppressIndicators)
{
	SCOPED_ACTION(CriticalSectionLock)(CS);

	if (!LockCount)
	{
		if (!SuppressIndicators)
		{
			if(Global->CtrlObject &&
				(Global->CtrlObject->Macro.IsRecording() ||
				(Global->CtrlObject->Macro.IsExecuting() && Global->Opt->Macro.ShowPlayIndicator))
			)
			{
				MacroChar=Buf[0];
				MacroCharUsed=true;

				if(Global->CtrlObject->Macro.IsRecording())
				{
					Buf[0].Char=L'R';
					Buf[0].Attributes = Colors::ConsoleColorToFarColor(B_LIGHTRED|F_WHITE);
				}
				else
				{
					Buf[0].Char=L'P';
					Buf[0].Attributes = Colors::ConsoleColorToFarColor(B_GREEN|F_WHITE);
				}
			}

			if(Global->Elevation->Elevated())
			{
				ElevationChar=Buf[BufX*BufY-1];
				ElevationCharUsed=true;

				Buf[BufX*BufY-1].Char=L'A';
				Buf[BufX*BufY-1].Attributes = Colors::ConsoleColorToFarColor(B_LIGHTRED|F_WHITE);
			}
		}

		if (!SBFlags.Check(SBFLAGS_FLUSHEDCURTYPE) && !CurVisible)
		{
			CONSOLE_CURSOR_INFO cci={CurSize,CurVisible};
			Global->Console->SetCursorInfo(cci);
			SBFlags.Set(SBFLAGS_FLUSHEDCURTYPE);
		}

		if (!SBFlags.Check(SBFLAGS_FLUSHED))
		{
			SBFlags.Set(SBFLAGS_FLUSHED);

			if (Global->WaitInMainLoop && Global->Opt->Clock && !Global->ProcessShowClock)
			{
				ShowTime(FALSE);
			}

			std::list<SMALL_RECT>WriteList;
			bool Changes=false;

			if (SBFlags.Check(SBFLAGS_USESHADOW))
			{
				FAR_CHAR_INFO* PtrBuf = Buf.data(), *PtrShadow = Shadow.data();

				if (Global->Opt->ClearType)
				{
					//Для полного избавления от артефактов ClearType будем перерисовывать на всю ширину.
					//Чревато тормозами/миганием в зависимости от конфигурации системы.
					SMALL_RECT WriteRegion={0,0,static_cast<SHORT>(BufX-1),0};

					for (SHORT I=0; I<BufY; I++, PtrBuf+=BufX, PtrShadow+=BufX)
					{
						WriteRegion.Top=I;
						WriteRegion.Bottom=I-1;

						while (I<BufY && memcmp(PtrBuf,PtrShadow,BufX*sizeof(FAR_CHAR_INFO))!=0)
						{
							I++;
							PtrBuf+=BufX;
							PtrShadow+=BufX;
							WriteRegion.Bottom++;
						}

						if (WriteRegion.Bottom >= WriteRegion.Top)
						{
							WriteList.emplace_back(WriteRegion);
							Changes=true;
						}
					}
				}
				else
				{
					bool Started=false;
					SMALL_RECT WriteRegion={static_cast<SHORT>(BufX-1),static_cast<SHORT>(BufY-1),0,0};

					for (SHORT I=0; I<BufY; I++)
					{
						for (SHORT J=0; J<BufX; J++,++PtrBuf,++PtrShadow)
						{
							if (memcmp(PtrBuf,PtrShadow,sizeof(FAR_CHAR_INFO))!=0)
							{
								WriteRegion.Left=std::min(WriteRegion.Left,J);
								WriteRegion.Top=std::min(WriteRegion.Top,I);
								WriteRegion.Right=std::max(WriteRegion.Right,J);
								WriteRegion.Bottom=std::max(WriteRegion.Bottom,I);
								Changes=true;
								Started=true;
							}
							else if (Started && I>WriteRegion.Bottom && J>=WriteRegion.Left)
							{
								//BUGBUG: при включенном СlearType-сглаживании на экране остаётся "мусор" - тонкие вертикальные полосы
								// кстати, и при выключенном тоже (но реже).
								// баг, конечно, не наш, но что делать.
								// расширяем область прорисовки влево-вправо на 1 символ:
								WriteRegion.Left=std::max(static_cast<SHORT>(0),static_cast<SHORT>(WriteRegion.Left-1));
								WriteRegion.Right=std::min(static_cast<SHORT>(WriteRegion.Right+1),static_cast<SHORT>(BufX-1));
								bool Merge=false;
								if (!WriteList.empty())
								{
									SMALL_RECT& Last=WriteList.back();
									const int MAX_DELTA = 5;
									if (WriteRegion.Top-1==Last.Bottom && ((WriteRegion.Left>=Last.Left && WriteRegion.Left-Last.Left<MAX_DELTA) || (Last.Right>=WriteRegion.Right && Last.Right-WriteRegion.Right<MAX_DELTA)))
									{
										Last.Bottom=WriteRegion.Bottom;
										Last.Left=std::min(Last.Left,WriteRegion.Left);
										Last.Right=std::max(Last.Right,WriteRegion.Right);
										Merge=true;
									}
								}

								if (!Merge)
									WriteList.emplace_back(WriteRegion);

								WriteRegion.Left=BufX-1;
								WriteRegion.Top=BufY-1;
								WriteRegion.Right=0;
								WriteRegion.Bottom=0;
								Started=false;
							}
						}
					}

					if (Started)
					{
						WriteList.emplace_back(WriteRegion);
					}
				}
			}
			else
			{
				Changes=true;
				SMALL_RECT WriteRegion={0,0,static_cast<SHORT>(BufX-1),static_cast<SHORT>(BufY-1)};
				WriteList.emplace_back(WriteRegion);
			}

			if (Changes)
			{
				std::for_each(CONST_RANGE(WriteList, i)
				{
					COORD BufferSize={BufX, BufY}, BufferCoord={i.Left, i.Top};
					SMALL_RECT WriteRegion = i;
					Global->Console->WriteOutput(Buf.data(), BufferSize, BufferCoord, WriteRegion);
				});
				Global->Console->Commit();
				std::copy(ALL_CONST_RANGE(Buf), Shadow.begin());
			}
int OperationFailed(const string& Object, LNGID Title, const string& Description, bool AllowSkip)
{
	std::vector<string> Msg;
	IFileIsInUse *pfiu = nullptr;
	LNGID Reason = MObjectLockedReasonOpened;
	bool SwitchBtn = false, CloseBtn = false;
	DWORD Error = Global->CaughtError();
	if(Error == ERROR_ACCESS_DENIED ||
		Error == ERROR_SHARING_VIOLATION ||
		Error == ERROR_LOCK_VIOLATION ||
		Error == ERROR_DRIVE_LOCKED)
	{
		string FullName;
		ConvertNameToFull(Object, FullName);
		pfiu = CreateIFileIsInUse(FullName);
		if (pfiu)
		{
			FILE_USAGE_TYPE UsageType = FUT_GENERIC;
			pfiu->GetUsage(&UsageType);
			switch(UsageType)
			{
			case FUT_PLAYING:
				Reason = MObjectLockedReasonPlayed;
				break;
			case FUT_EDITING:
				Reason = MObjectLockedReasonEdited;
				break;
			case FUT_GENERIC:
				Reason = MObjectLockedReasonOpened;
				break;
			}
			DWORD Capabilities = 0;
			pfiu->GetCapabilities(&Capabilities);
			if(Capabilities&OF_CAP_CANSWITCHTO)
			{
				SwitchBtn = true;
			}
			if(Capabilities&OF_CAP_CANCLOSE)
			{
				CloseBtn = true;
			}
			LPWSTR AppName = nullptr;
			if(SUCCEEDED(pfiu->GetAppName(&AppName)))
			{
				Msg.emplace_back(AppName);
			}
		}
		else
		{
			DWORD dwSession;
			WCHAR szSessionKey[CCH_RM_SESSION_KEY+1] = {};
			if (Imports().RmStartSession(&dwSession, 0, szSessionKey) == ERROR_SUCCESS)
			{
				PCWSTR pszFile = FullName.data();
				if (Imports().RmRegisterResources(dwSession, 1, &pszFile, 0, nullptr, 0, nullptr) == ERROR_SUCCESS)
				{
					DWORD dwReason;
					DWORD RmGetListResult;
					UINT nProcInfoNeeded;
					UINT nProcInfo = 1;
					std::vector<RM_PROCESS_INFO> rgpi(nProcInfo);
					while((RmGetListResult=Imports().RmGetList(dwSession, &nProcInfoNeeded, &nProcInfo, rgpi.data(), &dwReason)) == ERROR_MORE_DATA)
					{
						nProcInfo = nProcInfoNeeded;
						rgpi.resize(nProcInfo);
					}
					if(RmGetListResult ==ERROR_SUCCESS)
					{
						for (size_t i = 0; i < nProcInfo; i++)
						{
							string tmp = rgpi[i].strAppName;
							if (*rgpi[i].strServiceShortName)
							{
								tmp.append(L" [").append(rgpi[i].strServiceShortName).append(L"]");
							}
							tmp += L" (PID: " + std::to_wstring(rgpi[i].Process.dwProcessId);
							HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, rgpi[i].Process.dwProcessId);
							if (hProcess)
							{
								FILETIME ftCreate, ftExit, ftKernel, ftUser;
								if (GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser) && rgpi[i].Process.ProcessStartTime == ftCreate)
								{
									string Name;
									if (os::GetModuleFileNameEx(hProcess, nullptr, Name))
									{
										tmp += L", " + Name;
									}
								}
								CloseHandle(hProcess);
							}
							tmp += L")";
							Msg.emplace_back(tmp);
						}
					}
				}
				Imports().RmEndSession(dwSession);
			}
		}
	}

	auto Msgs = make_vector(Description, QuoteLeadingSpace(string(Object)));
	if(!Msg.empty())
	{
		Msgs.emplace_back(LangString(MObjectLockedReason) << MSG(Reason));
		Msgs.insert(Msgs.end(), ALL_CONST_RANGE(Msg));
	}

	std::vector<string> Buttons;
	Buttons.reserve(4);
	if(SwitchBtn)
	{
		Buttons.emplace_back(MSG(MObjectLockedSwitchTo));
	}
	Buttons.emplace_back(MSG(CloseBtn? MObjectLockedClose : MDeleteRetry));
	if(AllowSkip)
	{
		Buttons.emplace_back(MSG(MDeleteSkip));
		Buttons.emplace_back(MSG(MDeleteFileSkipAll));
	}
	Buttons.emplace_back(MSG(MDeleteCancel));

	int Result = -1;
	for(;;)
	{
		Result = Message(MSG_WARNING|MSG_ERRORTYPE, MSG(Title), Msgs, Buttons);

		if(SwitchBtn)
		{
			if(Result == 0)
			{
				HWND Wnd = nullptr;
				if (pfiu && SUCCEEDED(pfiu->GetSwitchToHWND(&Wnd)))
				{
					SetForegroundWindow(Wnd);
					if (IsIconic(Wnd))
						ShowWindow(Wnd, SW_RESTORE);
				}
				continue;
			}
			else if(Result > 0)
			{
				--Result;
			}
		}

		if(CloseBtn && Result == 0)
		{
			// close & retry
			if (pfiu)
			{
				pfiu->CloseFile();
			}
		}
		break;
	}

	if (pfiu)
	{
		pfiu->Release();
	}

	return Result;
}
Exemple #21
0
bool GetFileFormat(api::File& file, uintptr_t& nCodePage, bool* pSignatureFound, bool bUseHeuristics)
{
	DWORD dwTemp=0;
	bool bSignatureFound = false;
	bool bDetect=false;

	DWORD Readed = 0;
	if (file.Read(&dwTemp, sizeof(dwTemp), Readed) && Readed > 1 ) // minimum signature size is 2 bytes
	{
		if (LOWORD(dwTemp) == SIGN_UNICODE)
		{
			nCodePage = CP_UNICODE;
			file.SetPointer(2, nullptr, FILE_BEGIN);
			bSignatureFound = true;
		}
		else if (LOWORD(dwTemp) == SIGN_REVERSEBOM)
		{
			nCodePage = CP_REVERSEBOM;
			file.SetPointer(2, nullptr, FILE_BEGIN);
			bSignatureFound = true;
		}
		else if ((dwTemp & 0x00FFFFFF) == SIGN_UTF8)
		{
			nCodePage = CP_UTF8;
			file.SetPointer(3, nullptr, FILE_BEGIN);
			bSignatureFound = true;
		}
		else
		{
			file.SetPointer(0, nullptr, FILE_BEGIN);
		}
	}

	if (bSignatureFound)
	{
		bDetect = true;
	}
	else if (bUseHeuristics)
	{
		file.SetPointer(0, nullptr, FILE_BEGIN);
		DWORD Size=0x8000; // BUGBUG. TODO: configurable
		char_ptr Buffer(Size);
		DWORD ReadSize = 0;
		bool ReadResult = file.Read(Buffer.get(), Size, ReadSize);
		file.SetPointer(0, nullptr, FILE_BEGIN);

		if (ReadResult && ReadSize)
		{
			int test=
				IS_TEXT_UNICODE_STATISTICS|
				IS_TEXT_UNICODE_REVERSE_STATISTICS|
				IS_TEXT_UNICODE_CONTROLS|
				IS_TEXT_UNICODE_REVERSE_CONTROLS|
				IS_TEXT_UNICODE_ILLEGAL_CHARS|
				IS_TEXT_UNICODE_ODD_LENGTH|
				IS_TEXT_UNICODE_NULL_BYTES;

			if (IsTextUnicode(Buffer.get(), ReadSize, &test))
			{
				if (!(test&IS_TEXT_UNICODE_ODD_LENGTH) && !(test&IS_TEXT_UNICODE_ILLEGAL_CHARS))
				{
					if ((test&IS_TEXT_UNICODE_NULL_BYTES) || (test&IS_TEXT_UNICODE_CONTROLS) || (test&IS_TEXT_UNICODE_REVERSE_CONTROLS))
					{
						if ((test&IS_TEXT_UNICODE_CONTROLS) || (test&IS_TEXT_UNICODE_STATISTICS))
						{
							nCodePage=CP_UNICODE;
							bDetect=true;
						}
						else if ((test&IS_TEXT_UNICODE_REVERSE_CONTROLS) || (test&IS_TEXT_UNICODE_REVERSE_STATISTICS))
						{
							nCodePage=CP_REVERSEBOM;
							bDetect=true;
						}
					}
				}
			}
			else if (IsTextUTF8(Buffer.get(), ReadSize))
			{
				nCodePage=CP_UTF8;
				bDetect=true;
			}
			else
			{
				int cp = GetCpUsingUniversalDetector(Buffer.get(), ReadSize);
				if ( cp >= 0 )
				{
					if (Global->Opt->strNoAutoDetectCP.Get() == L"-1")
					{
						if ( Global->Opt->CPMenuMode )
						{
							if ( static_cast<UINT>(cp) != GetACP() && static_cast<UINT>(cp) != GetOEMCP() )
							{
								long long selectType = Global->CodePages->GetFavorite(cp);
								if (0 == (selectType & CPST_FAVORITE))
									cp = -1;
							}
						}
					}
					else
					{
						const auto BannedCpList = StringToList(Global->Opt->strNoAutoDetectCP, STLF_UNIQUE);

						if (std::find(ALL_CONST_RANGE(BannedCpList), std::to_wstring(cp)) != BannedCpList.cend())
						{
							cp = -1;
						}
					}
				}

				if (cp != -1)
				{
					nCodePage = cp;
					bDetect = true;
				}
			}
		}
	}

	if (pSignatureFound)
	{
		*pSignatureFound = bSignatureFound;
	}
	return bDetect;
}