33
44#include < stdio.h>
55#include < string.h>
6+ #include < tuple>
7+ #include < memory>
68#include < vector>
79#include < tchar.h>
810#include < windows.h>
911
10- #include " \VCProject\MLib\farsdk\ascii\ plugin.hpp"
11- #include " \VCProject\MLib\farsdk\ascii\ fmt.hpp"
12+ #include " plugin.hpp"
13+ #include " fmt.hpp"
1214
1315int help ();
1416int fail (int nCode);
@@ -17,153 +19,256 @@ int WINAPI _export GetArcItem(struct PluginPanelItem *Item, struct ArcItemInfo *
1719BOOL WINAPI _export CloseArchive (struct ArcInfo *Info);
1820int CreateItem ( PluginPanelItem& Item );
1921
20- BOOL lbNoPath=FALSE ;
22+ enum class WorkMode
23+ {
24+ ExtractNoPath,
25+ ExtractWithPath,
26+ Information,
27+ ListFiles,
28+ };
29+
30+ WorkMode work_mode;
2131
2232int main (int argc, char * argv[])
2333{
2434 int nRc = 0 ;
25- printf (" Arg count: %i\n " , argc);
26- for (int i=0 ; i<argc; i++) {
27- printf (argv[i]); printf (" \n " );
35+
36+ printf (" Arg count: %i\n " , argc);
37+ for (int i = 0 ; i < argc; i++) {
38+ printf (" %s\n " , argv[i]);
2839 }
2940
30- if (argc<= 3 )
41+ if (argc <= 2 )
3142 return help ();
3243
33- if (strcmp (argv[1 ]," e" ) && strcmp (argv[1 ]," x" ))
44+ const auto * mode = argv[1 ];
45+ if (strcmp (mode, " e" ) == 0 )
46+ {
47+ if (argc <= 3 )
48+ return help ();
49+ work_mode = WorkMode::ExtractNoPath;
50+ }
51+ else if (strcmp (mode, " x" ) == 0 )
52+ {
53+ if (argc <= 3 )
54+ return help ();
55+ work_mode = WorkMode::ExtractWithPath;
56+ }
57+ else if (strcmp (mode, " i" ) == 0 )
58+ {
59+ work_mode = WorkMode::Information;
60+ }
61+ else if (strcmp (mode, " l" ) == 0 )
62+ {
63+ work_mode = WorkMode::ListFiles;
64+ }
65+ else
66+ {
3467 return help ();
35- lbNoPath = strcmp (argv[ 1 ], " e " )== 0 ;
68+ }
3669
37- int nType= 0 ;
70+ int nType = 0 ;
3871 if (!OpenArchive (argv[2 ], &nType))
3972 return fail (101 );
4073
4174#ifdef _DEBUG
4275 if (!IsDebuggerPresent ())
43- MessageBox (NULL , " Wait" , " Dir.Fmt" , 0 );
76+ MessageBox (nullptr , " Wait" , " Dir.Fmt" , 0 );
4477#endif
4578
46- HANDLE hList = CreateFile (argv[3 ], GENERIC_READ, FILE_SHARE_READ, NULL , OPEN_EXISTING, 0 , 0 );
47- if (hList==INVALID_HANDLE_VALUE)
48- return fail (102 );
49- DWORD dwSize, dwHigh=0 ;
50- dwSize = GetFileSize (hList, &dwHigh);
51- if (dwHigh!=0 || dwSize==-1 || dwSize==0 ) return fail (103 );
52- TCHAR* pszList = (TCHAR*)calloc (dwSize+1 , sizeof (TCHAR));
53- if (!pszList) return fail (104 );
54- if (!ReadFile (hList, pszList, dwSize, &dwSize, 0 )) nRc = 105 ;
55- OemToCharBuff (pszList, pszList, dwSize);
56- CloseHandle (hList);
57-
58- SetConsoleOutputCP (1251 );
59-
60- if (nRc==0 )
61- {
62- std::vector<TCHAR*> psNeeds;
63- TCHAR *psz = pszList;
64- TCHAR *pszLine = NULL ;
65- while ((pszLine=_tcschr (psz, _T (' \r ' )))) {
79+
80+ std::vector<TCHAR*> psNeeds;
81+ std::unique_ptr<TCHAR[]> pszList;
82+ HANDLE hList = INVALID_HANDLE_VALUE;
83+ while (work_mode == WorkMode::ExtractNoPath || work_mode == WorkMode::ExtractWithPath) {
84+ hList = CreateFile (argv[3 ], GENERIC_READ, FILE_SHARE_READ, nullptr , OPEN_EXISTING, 0 , 0 );
85+ if (hList == INVALID_HANDLE_VALUE) {
86+ nRc = 102 ; break ;
87+ }
88+ DWORD dwSize, dwHigh = 0 ;
89+ dwSize = GetFileSize (hList, &dwHigh);
90+ if (dwHigh != 0 || dwSize == static_cast <DWORD>(-1 ) || dwSize == 0 ) {
91+ nRc = 103 ; break ;
92+ }
93+
94+ // ReSharper disable once CppJoinDeclarationAndAssignment
95+ pszList = std::make_unique<TCHAR[]>(dwSize + 1 );
96+ if (!pszList) {
97+ nRc = 104 ; break ;
98+ }
99+ if (!ReadFile (hList, pszList.get (), dwSize, &dwSize, 0 )) {
100+ nRc = 105 ; break ;
101+ }
102+
103+ OemToCharBuff (pszList.get (), pszList.get (), dwSize);
104+
105+ TCHAR* psz = pszList.get ();
106+ TCHAR* pszLine = nullptr ;
107+ while ((pszLine = _tcschr (psz, _T (' \r ' )))) {
66108 *pszLine = 0 ;
67- if (pszLine[1 ]== _T (' \n ' )) pszLine+= 2 ; else pszLine++;
109+ if (pszLine[1 ] == _T (' \n ' )) pszLine += 2 ; else pszLine++;
68110 psNeeds.push_back (psz);
69111 psz = pszLine;
70112 }
71113
114+ break ;
115+ }
72116
73- PluginPanelItem Item; memset (&Item, 0 , sizeof (Item));
74- ArcItemInfo Info; memset (&Info, 0 , sizeof (Info) );
117+ if (hList != INVALID_HANDLE_VALUE)
118+ CloseHandle (hList );
75119
76- // MessageBox(NULL, "Wait", "Dir.fmt.exe", MB_OK );
120+ const auto prevCp = GetConsoleOutputCP ( );
77121
122+ uint32_t fileCount = 0 ;
123+ uint32_t dirCount = 0 ;
124+ if (nRc == 0 )
125+ {
126+ SetConsoleOutputCP (1251 );
127+
128+ PluginPanelItem item{};
129+ ArcItemInfo info{};
130+
131+ // MessageBox(nullptr, "Wait", "Dir.fmt.exe", MB_OK);
132+
133+ wchar_t utfBuffer[MAX_PATH + 32 ];
134+ bool switchedToUtf8 = false ;
135+ HANDLE hStdOut = NULL ;
78136 // TCHAR szFromDir[MAX_PATH+1]; szFromDir[0]=0;
79- while (GETARC_SUCCESS==GetArcItem (&Item, &Info)) {
80- OemToCharBuff (Item.FindData .cFileName , Item.FindData .cFileName , strlen (Item.FindData .cFileName ));
81- if (Item.FindData .cFileName [0 ]==_T (' <' )) continue ; // <VOLUMELABEL:...>
82- // if (Item.FindData.dwFileAttributes&&FILE_ATTRIBUTE_DIRECTORY) continue;
83- if (strchr (Item.FindData .cFileName ,' \\ ' )) {
84- int nDbg=0 ;
137+ while (GETARC_SUCCESS == GetArcItem (&item, &info)) {
138+ if (item.UserData == CP_UTF8)
139+ {
140+ if (!hStdOut)
141+ {
142+ hStdOut = GetStdHandle (STD_OUTPUT_HANDLE);
143+ switchedToUtf8 = true ;
144+ }
145+ }
146+
147+ if (item.UserData == CP_OEMCP)
148+ {
149+ OemToCharBuff (item.FindData .cFileName , item.FindData .cFileName , strlen (item.FindData .cFileName ));
150+ }
151+
152+ if (item.FindData .cFileName [0 ] == _T (' <' ))
153+ continue ; // <VOLUMELABEL:...>
154+ // if (Item.FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
155+ if (strchr (item.FindData .cFileName , ' \\ ' )) {
156+ std::ignore = 0 ;
157+ }
158+
159+ if (item.FindData .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
160+ ++dirCount;
161+ else
162+ ++fileCount;
163+
164+ if (work_mode == WorkMode::ListFiles) {
165+ if (switchedToUtf8 && hStdOut && hStdOut != INVALID_HANDLE_VALUE && item.UserData == CP_UTF8)
166+ {
167+ swprintf_s (utfBuffer, L" %c '" , (item.FindData .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? ' D' : ' F' );
168+ MultiByteToWideChar (CP_UTF8, 0 , item.FindData .cFileName , -1 , utfBuffer + 3 , MAX_PATH + 1 );
169+ wcscat_s (utfBuffer, L" '\n " );
170+ DWORD written = 0 ;
171+ WriteConsoleW (hStdOut, utfBuffer, wcslen (utfBuffer), &written, nullptr );
172+ }
173+ else
174+ {
175+ printf (" %c '%s'\n " , (item.FindData .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? ' D' : ' F' ,
176+ item.FindData .cFileName );
177+ }
85178 }
86179
87- for (std::vector<TCHAR*>::iterator iter=psNeeds.begin (); iter!=psNeeds.end (); iter++)
180+ // ReSharper disable once IdentifierTypo
181+ for (auto * psTest : psNeeds)
88182 {
89- TCHAR *psTest = *iter;
90- BOOL lbOurFile=FALSE ;
91- if (_tcsnicmp (psTest, Item.FindData .cFileName , strlen (psTest))==0 )
183+ BOOL lbOurFile = FALSE ;
184+ if (_tcsnicmp (psTest, item.FindData .cFileName , strlen (psTest)) == 0 )
92185 {
93- lbOurFile= TRUE ;
94- if (Item .FindData .dwFileAttributes && FILE_ATTRIBUTE_DIRECTORY) {
95- psTest+= _tcslen (psTest);
96- if (*(psTest- 1 )!= _T (' \\ ' )) {
97- if (psTest[1 ]!= ' \n ' ) {
186+ lbOurFile = TRUE ;
187+ if (item .FindData .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
188+ psTest += _tcslen (psTest);
189+ if (*(psTest - 1 ) != _T (' \\ ' )) {
190+ if (psTest[1 ] != _T ( ' \n ' ) ) {
98191 nRc = 200 ;
99192 break ;
100193 }
101- *psTest= _T (' \\ ' );
194+ *psTest = _T (' \\ ' );
102195 psTest[1 ] = 0 ;
103196 }
104197 }
105198 }
106199
107200 if (lbOurFile) {
108- nRc = CreateItem (Item );
201+ nRc = CreateItem (item );
109202 break ;
110203 }
111204 }
112205 }
113206
114- CloseArchive (NULL );
207+ CloseArchive (nullptr );
115208 }
116- free (pszList);
117- printf (" Rc: %i\n " , nRc);
118- SetConsoleOutputCP (866 );
209+
210+ if (work_mode == WorkMode::Information || work_mode == WorkMode::ListFiles)
211+ printf (" Directories: %u\n Files: %u\n " , dirCount, fileCount);
212+
213+ if (nRc != 0 )
214+ printf (" Can't extract\n Rc: %i\n " , nRc);
215+ else
216+ printf (" Rc: %i\n " , nRc);
217+ SetConsoleOutputCP (prevCp);
119218 return nRc;
120219}
121220
122221int help ()
123222{
124- printf (" Dir.fmt.exe {e|x} \" dir_file\" \" file_list\"\n " );
223+ printf (" Dir.fmt.exe {e|x} \" dir_file\" \" file_list\"\n " );
125224 return 100 ;
126225}
127226
128227int fail (int nCode)
129228{
130- printf (" Can't extract!\n " );
229+ printf (" Can't extract!\n Rc: %i \n " , nCode );
131230 return nCode;
132231}
133232
134- int CreateItem ( PluginPanelItem& Item )
233+ int CreateItem ( PluginPanelItem& Item)
135234{
136235 int nRc = 0 ;
137- DWORD dwLastError=0 ;
236+ // ReSharper disable once CppEntityAssignedButNoRead
237+ DWORD dwLastError = 0 ;
138238
139239 TCHAR* pszFile = Item.FindData .cFileName ;
140- if (lbNoPath ) {
141- TCHAR * pszSlash = _tcsrchr (pszFile, _T (' \\ ' ));
240+ if (work_mode == WorkMode::ExtractNoPath ) {
241+ TCHAR* pszSlash = _tcsrchr (pszFile, _T (' \\ ' ));
142242 if (pszSlash)
143- pszFile = pszSlash+ 1 ;
243+ pszFile = pszSlash + 1 ;
144244 }
145245
146- if (Item.FindData .dwFileAttributes && FILE_ATTRIBUTE_DIRECTORY) {
246+ if (Item.FindData .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
147247 printf (" Creating folder: %s" , pszFile);
148- CreateDirectory (pszFile, NULL );
248+ CreateDirectory (pszFile, nullptr );
149249 printf (" \n " );
150- } else {
250+ }
251+ else {
151252 printf (" Creating file: %s" , pszFile);
152- HANDLE hFile = CreateFile (pszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL ,
153- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL/* Item.FindData.dwFileAttributes*/ , NULL );
253+ // ReSharper disable once CppLocalVariableMayBeConst
254+ HANDLE hFile = CreateFile (pszFile, GENERIC_WRITE, FILE_SHARE_READ, nullptr ,
255+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL/* Item.FindData.dwFileAttributes*/ , nullptr );
154256
155- if (hFile== INVALID_HANDLE_VALUE) {
257+ if (hFile == INVALID_HANDLE_VALUE) {
156258 nRc = 110 ;
157- } else {
158- SetFilePointer (hFile, Item.FindData .nFileSizeLow , (long *)&Item.FindData .nFileSizeHigh , FILE_BEGIN);
259+ }
260+ else {
261+ SetFilePointer (hFile, Item.FindData .nFileSizeLow , reinterpret_cast <PLONG>(&Item.FindData .nFileSizeHigh ), FILE_BEGIN);
159262 SetEndOfFile (hFile);
160- if (!SetFileTime (hFile, NULL , NULL , &Item.FindData .ftLastWriteTime ))
263+ if (!SetFileTime (hFile, nullptr , nullptr , &Item.FindData .ftLastWriteTime ))
161264 dwLastError = GetLastError ();
162265 CloseHandle (hFile);
163- if (!SetFileAttributes (pszFile, Item.FindData .dwFileAttributes | FILE_ATTRIBUTE_HIDDEN))
266+ if (!SetFileAttributes (pszFile, Item.FindData .dwFileAttributes | FILE_ATTRIBUTE_HIDDEN))
164267 dwLastError = GetLastError ();
165268 }
166269 printf (" \n " );
167270 }
271+
272+ std::ignore = dwLastError;
168273 return nRc;
169274}
0 commit comments