Skip to content

Commit e70ab80

Browse files
committed
dir_so: version 3.0.0.7
* don't use heap to allocate small structures * fix leading space in some file names * test console tool to list contents
1 parent 1942216 commit e70ab80

File tree

6 files changed

+430
-287
lines changed

6 files changed

+430
-287
lines changed

Dir_b3/Dir_fmt_exe.cpp

Lines changed: 178 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
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

1315
int help();
1416
int fail(int nCode);
@@ -17,153 +19,256 @@ int WINAPI _export GetArcItem(struct PluginPanelItem *Item, struct ArcItemInfo *
1719
BOOL WINAPI _export CloseArchive(struct ArcInfo *Info);
1820
int 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

2232
int 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\nFiles: %u\n", dirCount, fileCount);
212+
213+
if (nRc != 0)
214+
printf("Can't extract\nRc: %i\n", nRc);
215+
else
216+
printf("Rc: %i\n", nRc);
217+
SetConsoleOutputCP(prevCp);
119218
return nRc;
120219
}
121220

122221
int 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

128227
int fail(int nCode)
129228
{
130-
printf ("Can't extract!\n");
229+
printf("Can't extract!\nRc: %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

Comments
 (0)