Skip to content

Commit

Permalink
Update to 6.1.7 (#36)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Rubery <drubery@chromium.org>
  • Loading branch information
drubery and Daniel Rubery authored Oct 19, 2022
1 parent 6dd904a commit 373cfa6
Show file tree
Hide file tree
Showing 16 changed files with 282 additions and 77 deletions.
30 changes: 23 additions & 7 deletions consio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,18 +171,33 @@ static void GetPasswordText(wchar *Str,uint MaxLength)
{
#ifdef _WIN_ALL
HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE);
HANDLE hConOut=GetStdHandle(STD_OUTPUT_HANDLE);
DWORD ConInMode,ConOutMode;
DWORD Read=0;
DWORD ConInMode;
GetConsoleMode(hConIn,&ConInMode);
GetConsoleMode(hConOut,&ConOutMode);
SetConsoleMode(hConIn,ENABLE_LINE_INPUT);
SetConsoleMode(hConOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT);
SetConsoleMode(hConIn,ENABLE_LINE_INPUT); // Remove ENABLE_ECHO_INPUT.

// We prefer ReadConsole to ReadFile, so we can read Unicode input.
DWORD Read=0;
ReadConsole(hConIn,Str,MaxLength-1,&Read,NULL);
Str[Read]=0;
SetConsoleMode(hConIn,ConInMode);
SetConsoleMode(hConOut,ConOutMode);

// If entered password is longer than MAXPASSWORD and truncated,
// read its unread part anyway, so it isn't read later as the second
// password for -p switch. Low level FlushConsoleInputBuffer doesn't help
// for high level ReadConsole, which in line input mode seems to store
// the rest of string in its own internal buffer.
if (wcschr(Str,'\r')==NULL) // If '\r' is missing, the password was truncated.
while (true)
{
wchar Trail[64];
DWORD TrailRead=0;
// Use ASIZE(Trail)-1 to reserve the space for trailing 0.
ReadConsole(hConIn,Trail,ASIZE(Trail)-1,&TrailRead,NULL);
Trail[TrailRead]=0;
if (TrailRead==0 || wcschr(Trail,'\r')!=NULL)
break;
}

#else
char StrA[MAXPASSWORD*4]; // "*4" for multibyte UTF-8 characters.
#if defined(_EMX) || defined (__VMS)
Expand Down Expand Up @@ -267,6 +282,7 @@ bool getwstr(wchar *str,size_t n)
Array<char> StrA(n*4); // Up to 4 UTF-8 characters per wchar_t.
File SrcFile;
SrcFile.SetHandleType(FILE_HANDLESTD);
SrcFile.SetLineInputMode(true);
int ReadSize=SrcFile.Read(&StrA[0],StrA.Size()-1);
if (ReadSize<=0)
{
Expand Down
10 changes: 5 additions & 5 deletions dll.rc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#include <commctrl.h>

VS_VERSION_INFO VERSIONINFO
FILEVERSION 6, 10, 2, 318
PRODUCTVERSION 6, 10, 2, 318
FILEVERSION 6, 12, 100, 489
PRODUCTVERSION 6, 12, 100, 489
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
Expand All @@ -14,9 +14,9 @@ FILETYPE VFT_APP
VALUE "CompanyName", "Alexander Roshal\0"
VALUE "ProductName", "RAR decompression library\0"
VALUE "FileDescription", "RAR decompression library\0"
VALUE "FileVersion", "6.10.2\0"
VALUE "ProductVersion", "6.10.2\0"
VALUE "LegalCopyright", "Copyright � Alexander Roshal 1993-2021\0"
VALUE "FileVersion", "6.12.0\0"
VALUE "ProductVersion", "6.12.0\0"
VALUE "LegalCopyright", "Copyright � Alexander Roshal 1993-2022\0"
VALUE "OriginalFilename", "Unrar.dll\0"
}
}
Expand Down
25 changes: 12 additions & 13 deletions extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ void CmdExtract::DoExtract()
if (Code!=EXTRACT_ARC_REPEAT)
break;
}
if (FindFile::FastFind(ArcName,&FD))
DataIO.ProcessedArcSize+=FD.Size;
DataIO.ProcessedArcSize+=DataIO.LastArcSize;
}

// Clean user entered password. Not really required, just for extra safety.
Expand Down Expand Up @@ -82,7 +81,7 @@ void CmdExtract::DoExtract()

void CmdExtract::ExtractArchiveInit(Archive &Arc)
{
DataIO.UnpArcSize=Arc.IsSeekable() ? Arc.FileLength() : 0;
DataIO.AdjustTotalArcSize(&Arc);

FileCount=0;
MatchedArgs=0;
Expand Down Expand Up @@ -230,14 +229,11 @@ EXTRACT_ARC_CODE CmdExtract::ExtractArchive()
if (Repeat)
{
// If we started extraction from not first volume and need to
// restart it from first, we must correct DataIO.TotalArcSize
// for correct total progress display. We subtract the size
// of current volume and all volumes after it and add the size
// of new (first) volume.
FindData OldArc,NewArc;
if (FindFile::FastFind(Arc.FileName,&OldArc) &&
FindFile::FastFind(ArcName,&NewArc))
DataIO.TotalArcSize-=VolumeSetSize+OldArc.Size-NewArc.Size;
// restart it from first, we must set DataIO.TotalArcSize to size
// of new first volume to display the total progress correctly.
FindData NewArc;
if (FindFile::FastFind(ArcName,&NewArc))
DataIO.TotalArcSize=NewArc.Size;
return EXTRACT_ARC_REPEAT;
}
else
Expand Down Expand Up @@ -652,7 +648,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)

uint64 Preallocated=0;
if (!TestMode && !Arc.BrokenHeader && Arc.FileHead.UnpSize>1000000 &&
Arc.FileHead.PackSize*1024>Arc.FileHead.UnpSize &&
Arc.FileHead.PackSize*1024>Arc.FileHead.UnpSize && Arc.IsSeekable() &&
(Arc.FileHead.UnpSize<100000000 || Arc.FileLength()>Arc.FileHead.PackSize))
{
CurFile.Prealloc(Arc.FileHead.UnpSize);
Expand All @@ -670,8 +666,11 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)

if (Type==FSREDIR_HARDLINK || Type==FSREDIR_FILECOPY)
{
wchar RedirName[NM];
ConvertPath(Arc.FileHead.RedirName,RedirName,ASIZE(RedirName));

wchar NameExisting[NM];
ExtrPrepareName(Arc,Arc.FileHead.RedirName,NameExisting,ASIZE(NameExisting));
ExtrPrepareName(Arc,RedirName,NameExisting,ASIZE(NameExisting));
if (FileCreateMode && *NameExisting!=0) // *NameExisting can be 0 in case of excessive -ap switch.
if (Type==FSREDIR_HARDLINK)
LinkSuccess=ExtractHardlink(Cmd,DestFileName,NameExisting,ASIZE(NameExisting));
Expand Down
7 changes: 6 additions & 1 deletion file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ File::File()
NewFile=false;
LastWrite=false;
HandleType=FILE_HANDLENORMAL;
LineInput=false;
SkipClose=false;
ErrorType=FILE_SUCCESS;
OpenShared=false;
Expand Down Expand Up @@ -420,13 +421,17 @@ int File::Read(void *Data,size_t Size)
}
TotalRead+=ReadSize; // If ReadSize is -1, TotalRead is also set to -1 here.

if (HandleType==FILE_HANDLESTD && ReadSize>0 && (uint)ReadSize<Size)
if (HandleType==FILE_HANDLESTD && !LineInput && ReadSize>0 && (uint)ReadSize<Size)
{
// Unlike regular files, for pipe we can read only as much as was
// written at the other end of pipe. We had seen data coming in small
// ~80 byte chunks when piping from 'type arc.rar'. Extraction code
// would fail if we read an incomplete archive header from stdin.
// So here we ensure that requested size is completely read.
// But we return the available data immediately in "line input" mode,
// when processing user's input in console prompts. Otherwise apps
// piping user responses to multiple Ask() prompts can hang if no more
// data is available yet and pipe isn't closed.
Data=(byte*)Data+ReadSize;
Size-=ReadSize;
continue;
Expand Down
11 changes: 11 additions & 0 deletions file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ class File
FileHandle hFile;
bool LastWrite;
FILE_HANDLETYPE HandleType;

// If we read the user input in console prompts from stdin, we shall
// process the available line immediately, not waiting for rest of data.
// Otherwise apps piping user responses to multiple Ask() prompts can
// hang if no more data is available yet and pipe isn't closed.
// If we read RAR archive or other file data from stdin, we shall collect
// the entire requested block as long as pipe isn't closed, so we get
// complete archive headers, not split between different reads.
bool LineInput;

bool SkipClose;
FILE_READ_ERROR_MODE ReadErrorMode;
bool NewFile;
Expand Down Expand Up @@ -112,6 +122,7 @@ class File
virtual bool IsOpened() {return hFile!=FILE_BAD_HANDLE;} // 'virtual' for MultiFile class.
int64 FileLength();
void SetHandleType(FILE_HANDLETYPE Type) {HandleType=Type;}
void SetLineInputMode(bool Mode) {LineInput=Mode;}
FILE_HANDLETYPE GetHandleType() {return HandleType;}
bool IsSeekable() {return HandleType!=FILE_HANDLESTD;}
bool IsDevice();
Expand Down
93 changes: 91 additions & 2 deletions isnt.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "rar.hpp"

#ifdef _WIN_ALL
DWORD WinNT()
{
static int dwPlatformId=-1;
Expand All @@ -22,4 +21,94 @@ DWORD WinNT()

return Result;
}
#endif


// Replace it with documented Windows 11 check when available.
#include <comdef.h>
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")

static bool WMI_IsWindows10()
{
IWbemLocator *pLoc = NULL;

HRESULT hres = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
IID_IWbemLocator,(LPVOID *)&pLoc);

if (FAILED(hres))
return false;

IWbemServices *pSvc = NULL;

hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"),NULL,NULL,0,NULL,0,0,&pSvc);

if (FAILED(hres))
{
pLoc->Release();
return false;
}

hres = CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,
RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);

if (FAILED(hres))
{
pSvc->Release();
pLoc->Release();
return false;
}

IEnumWbemClassObject *pEnumerator = NULL;
hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_OperatingSystem"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);

if (FAILED(hres))
{
pSvc->Release();
pLoc->Release();
return false;
}

IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;

bool Win10=false;
while (pEnumerator!=NULL)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

if (uReturn==0)
break;

VARIANT vtProp;

hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
Win10|=wcsstr(vtProp.bstrVal,L"Windows 10")!=NULL;
VariantClear(&vtProp);

pclsObj->Release();
}

pSvc->Release();
pLoc->Release();
pEnumerator->Release();

return Win10;
}


// Replace it with actual check when available.
bool IsWindows11OrGreater()
{
static bool IsSet=false,IsWin11=false;
if (!IsSet)
{
OSVERSIONINFO WinVer;
WinVer.dwOSVersionInfoSize=sizeof(WinVer);
GetVersionEx(&WinVer);
IsWin11=WinVer.dwMajorVersion>10 ||
WinVer.dwMajorVersion==10 && WinVer.dwBuildNumber >= 22000 && !WMI_IsWindows10();
IsSet=true;
}
return IsWin11;
}
3 changes: 3 additions & 0 deletions isnt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ enum WINNT_VERSION {
DWORD WinNT();


// Replace it with actual check when available.
bool IsWindows11OrGreater();

#endif
15 changes: 8 additions & 7 deletions list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,15 +377,16 @@ void ListFileHeader(Archive &Arc,FileHeader &hd,bool &TitleShown,bool Verbose,bo
{
mprintf(L"\n%12ls: ",L"Unix owner");
if (*hd.UnixOwnerName!=0)
mprintf(L"%ls:",GetWide(hd.UnixOwnerName));
mprintf(L"%ls",GetWide(hd.UnixOwnerName));
else
if (hd.UnixOwnerNumeric)
mprintf(L"#%d",hd.UnixOwnerID);
mprintf(L":");
if (*hd.UnixGroupName!=0)
mprintf(L"%ls",GetWide(hd.UnixGroupName));
if ((*hd.UnixOwnerName!=0 || *hd.UnixGroupName!=0) && (hd.UnixOwnerNumeric || hd.UnixGroupNumeric))
mprintf(L" ");
if (hd.UnixOwnerNumeric)
mprintf(L"#%d:",hd.UnixOwnerID);
if (hd.UnixGroupNumeric)
mprintf(L"#%d:",hd.UnixGroupID);
else
if (hd.UnixGroupNumeric)
mprintf(L"#%d",hd.UnixGroupID);
}

mprintf(L"\n");
Expand Down
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ UNRAR_OBJ=filestr.o recvol.o rs.o scantree.o qopen.o
LIB_OBJ=filestr.o scantree.o dll.o qopen.o

OBJECTS=rar.o strlist.o strfn.o pathfn.o smallfn.o global.o file.o filefn.o filcreat.o \
archive.o arcread.o unicode.o system.o isnt.o crypt.o crc.o rawread.o encname.o \
archive.o arcread.o unicode.o system.o crypt.o crc.o rawread.o encname.o \
resource.o match.o timefn.o rdwrfn.o consio.o options.o errhnd.o rarvm.o secpassword.o \
rijndael.o getbits.o sha1.o sha256.o blake2s.o hash.o extinfo.o extract.o volume.o \
list.o find.o unpack.o headers.o threadpool.o rs16.o cmddata.o ui.o
Expand Down
4 changes: 3 additions & 1 deletion pathfn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,9 @@ void MakeNameCompatible(wchar *Name,size_t MaxSize)
else
if (Devices[J][K]==0)
{
MatchFound=s[K]==0 || s[K]=='.' || IsPathDiv(s[K]);
// Names like aux.txt are accessible without \\?\ prefix
// since Windows 11. Pure aux is still prohibited.
MatchFound=s[K]==0 || s[K]=='.' && !IsWindows11OrGreater() || IsPathDiv(s[K]);
break;
}
else
Expand Down
Loading

0 comments on commit 373cfa6

Please sign in to comment.