UNRAR9X.DLL ver.6.1.1
Moderators: Hacker, petermad, Stefan2, white
UNRAR9X.DLL ver.6.1.1
Unpack tc1050x32_64_b8
UnRAR.dll and UnRAR64.dll are ver.6.11.0
UNRAR9X.DLL is ver.6.1.1
Do you plan to update UNRAR9X.DLL ?
UnRAR.dll and UnRAR64.dll are ver.6.11.0
UNRAR9X.DLL is ver.6.1.1
Do you plan to update UNRAR9X.DLL ?
Ukrainian Total Commander Translator. Feedback and discuss.
- sqa_wizard
- Power Member
- Posts: 3893
- Joined: 2003-02-06, 11:41 UTC
- Location: Germany
Re: UNRAR9X.DLL ver.6.1.1
AFAIK the api has changed meanwhile and UnRar.dll 6.11 does not support Windows 95/98 anymore.
#5767 Personal license
Re: UNRAR9X.DLL ver.6.1.1
This DLL works, I did my tests when it released.
Ukrainian Total Commander Translator. Feedback and discuss.
- ghisler(Author)
- Site Admin
- Posts: 50475
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Re: UNRAR9X.DLL ver.6.1.1
What DLL do you mean with "this dll"? Where can I find an update?This DLL works, I did my tests when it released.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Re: UNRAR9X.DLL ver.6.1.1
I mean existing UNRAR9X.DLL is ver.6.1.1 --- This DLL works, I did my tests when it released.
Strange question... Where did you got existing UNRAR9X.DLL ver.6.1.1 from TC installer?
Ukrainian Total Commander Translator. Feedback and discuss.
- ghisler(Author)
- Site Admin
- Posts: 50475
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Re: UNRAR9X.DLL ver.6.1.1
Sorry, I understood that you had found a newer dll version working on Windows 9x/ME.
I compiled this DLL myself from unrar sources after making some modifications. Newer source may or may not work.
I compiled this DLL myself from unrar sources after making some modifications. Newer source may or may not work.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Re: UNRAR9X.DLL ver.6.1.1
The last official working for XP is 6.02, may be it would have more sense to take it, if something goes wrong with 6.11.
Ukrainian Total Commander Translator. Feedback and discuss.
Re: UNRAR9X.DLL ver.6.1.1
2ghisler(Author)
Don't feel sorry - that is how I understood it too.Sorry, I understood that you had found a newer dll version working on Windows 9x/ME.
License #524 (1994)
Danish Total Commander Translator
TC 11.51 32+64bit on Win XP 32bit & Win 7, 8.1 & 10 (22H2) 64bit, 'Everything' 1.5.0.1391a
TC 3.60b4 on Android 6, 13, 14
TC Extended Menus | TC Languagebar | TC Dark Help | PHSM-Calendar
Danish Total Commander Translator
TC 11.51 32+64bit on Win XP 32bit & Win 7, 8.1 & 10 (22H2) 64bit, 'Everything' 1.5.0.1391a
TC 3.60b4 on Android 6, 13, 14
TC Extended Menus | TC Languagebar | TC Dark Help | PHSM-Calendar
- ghisler(Author)
- Site Admin
- Posts: 50475
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Re: UNRAR9X.DLL ver.6.1.1
Is there any problem with 6.11? It's much newer than 6.02.The last official working for XP is 6.02, may be it would have more sense to take it, if something goes wrong with 6.11.
Anyway, I will try to compile the latest 6.17.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Re: UNRAR9X.DLL ver.6.1.1
I don't have any problems with regular RAR.EXE 6.11 and unrar.DLL 6.11 on XP, but WinRAR.exe 6.11 does not work on XP.
Hope, there should be no problems in UNRAR9X.DLL even in the newest version.
Hope, there should be no problems in UNRAR9X.DLL even in the newest version.
Ukrainian Total Commander Translator. Feedback and discuss.
Re: UNRAR9X.DLL ver.6.1.1
I've done my tests for tc1050x32_64_rc1 with new UNRAR9X.DLL v6.12, it works fine for me and unpacks both RAR4 and RAR5. That's awesome. Thanks.
Ukrainian Total Commander Translator. Feedback and discuss.
Re: UNRAR9X.DLL ver.6.1.1
2MaxX
It seems that only winrar.exe (GUI version) is currently compiled for Vista+. Command line tools (rar.exe and unrar.exe) still work in Windows XP, so there should be no problem also for other tools in the nearest future.
It seems that only winrar.exe (GUI version) is currently compiled for Vista+. Command line tools (rar.exe and unrar.exe) still work in Windows XP, so there should be no problem also for other tools in the nearest future.
Last edited by Usher on 2022-06-09, 17:52 UTC, edited 1 time in total.
Andrzej P. Wozniak
Polish subforum moderator
Polish subforum moderator
- ghisler(Author)
- Site Admin
- Posts: 50475
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Re: UNRAR9X.DLL ver.6.1.1
I have compiled the latest sources from rarlab.com to unrar9x.dll.
Although the sources are using the name unrarsrc-6.1.7.tar.gz which would make me assume version 6.1.7, the DLL will report version 6.12.0. Reason:
unrar\version.hpp contains:
#define RARVER_MAJOR 6
#define RARVER_MINOR 12
#define RARVER_BETA 0
The following functions are not used in this version because they don't work on Windows 9x(ME:
CompareStringW
CharLower
CharUpper
TzSpecificLocalTimeToSystemTime
#define USE_SSE
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
WMI_IsWindows10()
IsWindows11OrGreater()
ExtractHardlink()
The following was added by myself:
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
uni2ansi.hpp
uni2ansi.cpp
Although the sources are using the name unrarsrc-6.1.7.tar.gz which would make me assume version 6.1.7, the DLL will report version 6.12.0. Reason:
unrar\version.hpp contains:
#define RARVER_MAJOR 6
#define RARVER_MINOR 12
#define RARVER_BETA 0
The following functions are not used in this version because they don't work on Windows 9x(ME:
CompareStringW
CharLower
CharUpper
TzSpecificLocalTimeToSystemTime
#define USE_SSE
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
WMI_IsWindows10()
IsWindows11OrGreater()
ExtractHardlink()
The following was added by myself:
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
uni2ansi.hpp
Code: Select all
// Added for VCC2005
#ifndef SE_CREATE_SYMBOLIC_LINK_NAME
#define SE_CREATE_SYMBOLIC_LINK_NAME TEXT("SeCreateSymolicLinkName")
#endif
// Added for VCC2005
#ifndef IO_REPARSE_TAG_SYMLINK
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#endif
HANDLE W_CreateFile(
const wchar * lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
#undef CreateFile
#define CreateFile W_CreateFile
BOOL W_DeleteFile(
const wchar * lpFileName
);
#undef DeleteFile
#define DeleteFile W_DeleteFile
BOOL W_CreateDirectory(
const wchar * lpPathName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
#undef CreateDirectory
#define CreateDirectory W_CreateDirectory
BOOL W_RemoveDirectory(
const wchar * lpPathName
);
#undef RemoveDirectory
#define RemoveDirectory W_RemoveDirectory
HANDLE W_CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
const wchar * lpName
);
#undef CreateEvent
#define CreateEvent W_CreateEvent
HANDLE W_CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
const wchar * lpName
);
#undef CreateSemaphore
#define CreateSemaphore W_CreateSemaphore
HANDLE W_FindFirstFile(
const wchar * lpFileName,
LPWIN32_FIND_DATAW lpFindFileData
);
#undef FindFirstFile
#define FindFirstFile W_FindFirstFile
BOOL W_FindNextFile(
HANDLE hFindFile,
LPWIN32_FIND_DATAW lpFindFileData
);
#undef FindNextFile
#define FindNextFile W_FindNextFile
DWORD W_GetCurrentDirectory(
DWORD nBufferLength,
wchar *lpBuffer
);
#undef GetCurrentDirectory
#define GetCurrentDirectory W_GetCurrentDirectory
DWORD W_GetFileAttributes(
const wchar * lpFileName
);
#undef GetFileAttributes
#define GetFileAttributes W_GetFileAttributes
HMODULE W_LoadLibrary(
const wchar * lpLibFileName
);
#undef LoadLibrary
#define LoadLibrary W_LoadLibrary
UINT W_GetSystemDirectory(
wchar* lpBuffer,
UINT uSize
);
#undef GetSystemDirectory
#define GetSystemDirectory W_GetSystemDirectory
BOOL W_SetFileAttributes(
const wchar* lpFileName,
DWORD dwFileAttributes
);
#undef SetFileAttributes
#define SetFileAttributes W_SetFileAttributes
DWORD W_GetFullPathName(
const wchar* lpFileName,
DWORD nBufferLength,
wchar* lpBuffer,
wchar** lpFilePart
);
#undef GetFullPathName
#define GetFullPathName W_GetFullPathName
BOOL W_CharToOemBuff(
const wchar* lpszSrc,
char* lpszDst,
DWORD cchDstLength
);
#define CharToOemBuffWOrg CharToOemBuffW
#undef CharToOemBuff
#define CharToOemBuff W_CharToOemBuff
#undef CharToOemBuffW
#define CharToOemBuffW W_CharToOemBuff
#undef OSVERSIONINFO
#define OSVERSIONINFO OSVERSIONINFOA
#undef GetVersionEx
#define GetVersionEx GetVersionExA
DWORD W_GetLongPathName(
const wchar* lpszShortPath,
wchar* lpszLongPath,
DWORD cchBuffer
);
#undef GetLongPathName
#define GetLongPathName W_GetLongPathName
DWORD W_GetShortPathName(
const wchar* lpszLongPath,
wchar* lpszShortPath,
DWORD cchBuffer
);
#undef GetShortPathName
#define GetShortPathName W_GetShortPathName
BOOL W_MoveFile(
const wchar* lpExistingFileName,
const wchar* lpNewFileName
);
#undef MoveFile
#define MoveFile W_MoveFile
Code: Select all
#include "rar.hpp"
// default char must be a fobidden character!
#define DEFAULTCHAR "<"
int wastrlcpy(char* PcharName,const wchar *WideName,int maxlen) {
PcharName[0]=0; // if widename==NULL
if (WideName==NULL)
return 0;
int result=WideCharToMultiByte(CP_ACP,0,WideName,-1,PcharName,maxlen,DEFAULTCHAR,NULL);
if (result==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER) // It may not be 0-terminated!
PcharName[maxlen]=0;
return result;
}
int awstrlcpy(wchar *WideName,const char* PcharName,int maxlen) {
WideName[0]=0; // if widename==NULL
if (PcharName==NULL)
return 0;
int result=MultiByteToWideChar(CP_ACP, 0, PcharName, -1, WideName, maxlen);
if (result==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER) // It may not be 0-terminated!
WideName[maxlen]=0;
return result;
}
HANDLE W_CreateFile(
const wchar * lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
) {
if (WinNT())
return CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,
dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
char FileNameA[MAX_PATH];
wastrlcpy(FileNameA,lpFileName,sizeof(FileNameA)-1);
return CreateFileA(
FileNameA,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
BOOL W_DeleteFile(
const wchar * lpFileName
) {
if (WinNT())
return DeleteFileW(lpFileName);
char FileNameA[MAX_PATH];
wastrlcpy(FileNameA,lpFileName,sizeof(FileNameA)-1);
return DeleteFileA(FileNameA);
}
BOOL W_CreateDirectory(
const wchar * lpPathName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
) {
if (WinNT())
return CreateDirectoryW(lpPathName,lpSecurityAttributes);
char PathNameA[MAX_PATH];
wastrlcpy(PathNameA,lpPathName,sizeof(PathNameA)-1);
return CreateDirectoryA(
PathNameA,
lpSecurityAttributes);
}
BOOL W_RemoveDirectory(
const wchar * lpPathName
) {
if (WinNT())
RemoveDirectoryW(lpPathName);
char PathNameA[MAX_PATH];
wastrlcpy(PathNameA,lpPathName,sizeof(PathNameA)-1);
return RemoveDirectoryA(
PathNameA);
}
HANDLE W_CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
const wchar * lpName
) {
if (WinNT())
return CreateEventW(lpEventAttributes,bManualReset,bInitialState,lpName);
char NameA[MAX_PATH];
if (lpName) {
wastrlcpy(NameA,lpName,sizeof(NameA)-1);
return CreateEventA(
lpEventAttributes,
bManualReset,
bInitialState,
NameA);
} else {
return CreateEventA(
lpEventAttributes,
bManualReset,
bInitialState,
NULL);
}
}
HANDLE W_CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
const wchar * lpName
) {
if (WinNT())
return CreateSemaphoreW(lpSemaphoreAttributes,lInitialCount,lMaximumCount,lpName);
char NameA[MAX_PATH];
if (lpName) {
wastrlcpy(NameA,lpName,sizeof(NameA)-1);
return CreateSemaphoreA(
lpSemaphoreAttributes,
lInitialCount,
lMaximumCount,
NameA);
} else {
return CreateSemaphoreA(
lpSemaphoreAttributes,
lInitialCount,
lMaximumCount,
NULL);
}
}
void CopyFindDateAW(LPWIN32_FIND_DATAW lpFindFileDataW,LPWIN32_FIND_DATAA lpFindFileDataA) {
lpFindFileDataW->dwFileAttributes=lpFindFileDataA->dwFileAttributes;
lpFindFileDataW->ftCreationTime=lpFindFileDataA->ftCreationTime;
lpFindFileDataW->ftLastAccessTime=lpFindFileDataA->ftLastAccessTime;
lpFindFileDataW->ftLastWriteTime=lpFindFileDataA->ftLastWriteTime;
lpFindFileDataW->nFileSizeHigh=lpFindFileDataA->nFileSizeHigh;
lpFindFileDataW->nFileSizeLow=lpFindFileDataA->nFileSizeLow;
lpFindFileDataW->dwReserved0=lpFindFileDataA->dwReserved0;
lpFindFileDataW->dwReserved1=lpFindFileDataA->dwReserved1;
awstrlcpy(lpFindFileDataW->cFileName,lpFindFileDataA->cFileName,MAX_PATH-1);
awstrlcpy(lpFindFileDataW->cAlternateFileName,lpFindFileDataA->cAlternateFileName,14-1);
}
HANDLE W_FindFirstFile(
const wchar * lpFileName,
LPWIN32_FIND_DATAW lpFindFileData
) {
if (WinNT())
return FindFirstFileW(lpFileName,lpFindFileData);
WIN32_FIND_DATAA FindFileDataA;
char FileNameA[MAX_PATH];
wastrlcpy(FileNameA,lpFileName,sizeof(FileNameA)-1);
HANDLE ret=FindFirstFileA(
FileNameA,
&FindFileDataA);
if (INVALID_HANDLE_VALUE!=ret)
CopyFindDateAW(lpFindFileData,&FindFileDataA);
return ret;
}
BOOL W_FindNextFile(
HANDLE hFindFile,
LPWIN32_FIND_DATAW lpFindFileData
) {
if (WinNT())
return FindNextFileW(hFindFile,lpFindFileData);
WIN32_FIND_DATAA FindFileDataA;
BOOL ret=FindNextFileA(
hFindFile,
&FindFileDataA);
if (ret)
CopyFindDateAW(lpFindFileData,&FindFileDataA);
return ret;
}
DWORD W_GetCurrentDirectory(
DWORD nBufferLength,
wchar *lpBuffer
) {
if (WinNT())
return GetCurrentDirectoryW(nBufferLength,lpBuffer);
char BufferA[MAX_PATH];
DWORD ret=GetCurrentDirectoryA(
sizeof(BufferA)-1,
BufferA);
if (lpBuffer) {
if (ret==0)
lpBuffer[0]=0;
else
awstrlcpy(lpBuffer,BufferA,nBufferLength);
}
return ret;
}
DWORD W_GetFileAttributes(
const wchar * lpFileName
) {
if (WinNT())
return GetFileAttributesW(lpFileName);
char FileNameA[MAX_PATH];
wastrlcpy(FileNameA,lpFileName,sizeof(FileNameA)-1);
return GetFileAttributesA(FileNameA);
}
HMODULE W_LoadLibrary(
const wchar * lpLibFileName
) {
if (WinNT())
return LoadLibraryW(lpLibFileName);
char FileNameA[MAX_PATH];
wastrlcpy(FileNameA,lpLibFileName,sizeof(FileNameA)-1);
return LoadLibraryA(FileNameA);
}
UINT W_GetSystemDirectory(
wchar* lpBuffer,
UINT uSize
) {
if (WinNT())
return GetSystemDirectoryW(lpBuffer,uSize);
char BufferA[MAX_PATH];
DWORD ret=GetSystemDirectoryA(
BufferA,
sizeof(BufferA));
if (lpBuffer) {
if (ret==0)
lpBuffer[0]=0;
else
awstrlcpy(lpBuffer,BufferA,uSize);
}
return ret;
}
BOOL W_SetFileAttributes(
const wchar* lpFileName,
DWORD dwFileAttributes
) {
if (WinNT())
return SetFileAttributesW(lpFileName,dwFileAttributes);
char FileNameA[MAX_PATH];
wastrlcpy(FileNameA,lpFileName,sizeof(FileNameA)-1);
return SetFileAttributesA(
FileNameA,
dwFileAttributes
);
}
DWORD W_GetFullPathName(
const wchar* lpFileName,
DWORD nBufferLength,
wchar* lpBuffer,
wchar** lpFilePart
)
{
if (WinNT())
return GetFullPathNameW(lpFileName,nBufferLength,lpBuffer,lpFilePart);
char *lpFilePartA;
char FileNameA[MAX_PATH];
char FullNameA[MAX_PATH];
wastrlcpy(FileNameA,lpFileName,sizeof(FileNameA)-1);
DWORD result = GetFullPathNameA(FileNameA, MAX_PATH, FullNameA, &lpFilePartA);
if (result==0)
return 0;
awstrlcpy(lpBuffer,FullNameA,nBufferLength);
if (lpFilePart) {
wchar* pFilePart = lpBuffer + wcslen(lpBuffer)-1;
while (*pFilePart != L'\\')
--pFilePart;
*lpFilePart = pFilePart;
}
return wcslen(lpBuffer); // do not include the NULL
}
BOOL W_CharToOemBuff(
const wchar* lpszSrc,
char* lpszDst,
DWORD cchDstLength
) {
if (WinNT())
return CharToOemBuffWOrg(lpszSrc,lpszDst,cchDstLength);
char SrcA[MAX_PATH];
wastrlcpy(SrcA,lpszSrc,sizeof(SrcA)-1);
return CharToOemBuffA(SrcA,
lpszDst,
cchDstLength);
}
// this function only exists on Windows 98 and newer!
typedef DWORD (WINAPI *DEF_GetLongPathName)(const char* lpszShortPath,char* lpszLongPath,DWORD cchBuffer);
DEF_GetLongPathName GetLongPathNameX=NULL;
typedef DWORD (WINAPI *DEF_GetLongPathNameW)(const wchar* lpszShortPath,wchar* lpszLongPath,DWORD cchBuffer);
DEF_GetLongPathNameW GetLongPathNameWX=NULL;
BOOL GetLongPathNameLoaded=false;
DWORD W_GetLongPathName(
const wchar* lpszShortPath,
wchar* lpszLongPath,
DWORD cchBuffer
) {
if (!GetLongPathNameLoaded) {
int OldErrorMode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
HINSTANCE hLib;
GetLongPathNameLoaded=true;
hLib=GetModuleHandleA("kernel32.dll");
if (WinNT())
GetLongPathNameWX=(DEF_GetLongPathNameW)GetProcAddress((HMODULE)hLib,"GetLongPathNameW");
else
GetLongPathNameX=(DEF_GetLongPathName)GetProcAddress((HMODULE)hLib,"GetLongPathNameA");
SetErrorMode(OldErrorMode);
}
if (WinNT()) {
if (!GetLongPathNameWX)
return 0;
return GetLongPathNameWX(lpszShortPath,lpszLongPath,cchBuffer);
}
if (!GetLongPathNameX)
return 0;
char ShortPathA[MAX_PATH];
char LongPathA[MAX_PATH];
wastrlcpy(ShortPathA,lpszShortPath,sizeof(ShortPathA)-1);
if (strchr(ShortPathA,DEFAULTCHAR[0]))
return 0; // forbidden Unicode chars
DWORD result=GetLongPathNameX(
ShortPathA,
LongPathA,
MAX_PATH);
if (result && lpszLongPath)
awstrlcpy(lpszLongPath,LongPathA,cchBuffer-1);
return result;
}
DWORD W_GetShortPathName(
const wchar* lpszLongPath,
wchar* lpszShortPath,
DWORD cchBuffer
) {
if (WinNT())
return GetShortPathNameW(lpszLongPath,lpszShortPath,cchBuffer);
char LongPathA[MAX_PATH];
char ShortPathA[MAX_PATH];
wastrlcpy(LongPathA,lpszLongPath,sizeof(LongPathA)-1);
if (strchr(LongPathA,DEFAULTCHAR[0]))
return 0; // forbidden Unicode chars
DWORD result=GetShortPathNameA(
LongPathA,
ShortPathA,
MAX_PATH);
if (result && lpszShortPath)
awstrlcpy(lpszShortPath,ShortPathA,cchBuffer-1);
return result;
}
BOOL W_MoveFile(
const wchar* lpExistingFileName,
const wchar* lpNewFileName
) {
if (WinNT())
return MoveFileW(lpExistingFileName,lpNewFileName);
char ExistingFileNameA[MAX_PATH];
char NewFileNameA[MAX_PATH];
wastrlcpy(ExistingFileNameA,lpExistingFileName,sizeof(ExistingFileNameA)-1);
if (strchr(ExistingFileNameA,DEFAULTCHAR[0]))
return FALSE; // forbidden Unicode chars
wastrlcpy(NewFileNameA,lpNewFileName,sizeof(NewFileNameA)-1);
if (strchr(NewFileNameA,DEFAULTCHAR[0]))
return FALSE; // forbidden Unicode chars
return MoveFileA(ExistingFileNameA,NewFileNameA);
}
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com