Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

default rules for "makefile" (no file extension) #15

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# These are supported funding model platforms

github: Maximus5
liberapay: conemu.maximus5
custom: ['https://www.paypal.me/conemu/5']
274 changes: 274 additions & 0 deletions Dir_b3/Dir_fmt_exe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
// Dir_fmt_exe.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <string.h>
#include <tuple>
#include <memory>
#include <vector>
#include <tchar.h>
#include <windows.h>

#include "plugin.hpp"
#include "fmt.hpp"

int help();
int fail(int nCode);
BOOL WINAPI _export OpenArchive(char *Name, int *Type);
int WINAPI _export GetArcItem(struct PluginPanelItem *Item, struct ArcItemInfo *Info);
BOOL WINAPI _export CloseArchive(struct ArcInfo *Info);
int CreateItem ( PluginPanelItem& Item );

enum class WorkMode
{
ExtractNoPath,
ExtractWithPath,
Information,
ListFiles,
};

WorkMode work_mode;

int main(int argc, char* argv[])
{
int nRc = 0;

printf("Arg count: %i\n", argc);
for (int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
}

if (argc <= 2)
return help();

const auto* mode = argv[1];
if (strcmp(mode, "e") == 0)
{
if (argc <= 3)
return help();
work_mode = WorkMode::ExtractNoPath;
}
else if (strcmp(mode, "x") == 0)
{
if (argc <= 3)
return help();
work_mode = WorkMode::ExtractWithPath;
}
else if (strcmp(mode, "i") == 0)
{
work_mode = WorkMode::Information;
}
else if (strcmp(mode, "l") == 0)
{
work_mode = WorkMode::ListFiles;
}
else
{
return help();
}

int nType = 0;
if (!OpenArchive(argv[2], &nType))
return fail(101);

#ifdef _DEBUG
if (!IsDebuggerPresent())
MessageBox(nullptr, "Wait", "Dir.Fmt", 0);
#endif


std::vector<TCHAR*> psNeeds;
std::unique_ptr<TCHAR[]> pszList;
HANDLE hList = INVALID_HANDLE_VALUE;
while (work_mode == WorkMode::ExtractNoPath || work_mode == WorkMode::ExtractWithPath) {
hList = CreateFile(argv[3], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, 0);
if (hList == INVALID_HANDLE_VALUE) {
nRc = 102; break;
}
DWORD dwSize, dwHigh = 0;
dwSize = GetFileSize(hList, &dwHigh);
if (dwHigh != 0 || dwSize == static_cast<DWORD>(-1) || dwSize == 0) {
nRc = 103; break;
}

// ReSharper disable once CppJoinDeclarationAndAssignment
pszList = std::make_unique<TCHAR[]>(dwSize + 1);
if (!pszList) {
nRc = 104; break;
}
if (!ReadFile(hList, pszList.get(), dwSize, &dwSize, 0)) {
nRc = 105; break;
}

OemToCharBuff(pszList.get(), pszList.get(), dwSize);

TCHAR* psz = pszList.get();
TCHAR* pszLine = nullptr;
while ((pszLine = _tcschr(psz, _T('\r')))) {
*pszLine = 0;
if (pszLine[1] == _T('\n')) pszLine += 2; else pszLine++;
psNeeds.push_back(psz);
psz = pszLine;
}

break;
}

if (hList != INVALID_HANDLE_VALUE)
CloseHandle(hList);

const auto prevCp = GetConsoleOutputCP();

uint32_t fileCount = 0;
uint32_t dirCount = 0;
if (nRc == 0)
{
SetConsoleOutputCP(1251);

PluginPanelItem item{};
ArcItemInfo info{};

//MessageBox(nullptr, "Wait", "Dir.fmt.exe", MB_OK);

wchar_t utfBuffer[MAX_PATH + 32];
bool switchedToUtf8 = false;
HANDLE hStdOut = NULL;
//TCHAR szFromDir[MAX_PATH+1]; szFromDir[0]=0;
while (GETARC_SUCCESS == GetArcItem(&item, &info)) {
if (item.UserData == CP_UTF8)
{
if (!hStdOut)
{
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
switchedToUtf8 = true;
}
}

if (item.UserData == CP_OEMCP)
{
OemToCharBuff(item.FindData.cFileName, item.FindData.cFileName, strlen(item.FindData.cFileName));
}

if (item.FindData.cFileName[0] == _T('<'))
continue; // <VOLUMELABEL:...>
//if (Item.FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
if (strchr(item.FindData.cFileName, '\\')) {
std::ignore = 0;
}

if (item.FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
++dirCount;
else
++fileCount;

if (work_mode == WorkMode::ListFiles) {
if (switchedToUtf8 && hStdOut && hStdOut != INVALID_HANDLE_VALUE && item.UserData == CP_UTF8)
{
swprintf_s(utfBuffer, L"%c '", (item.FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 'D' : 'F');
MultiByteToWideChar(CP_UTF8, 0, item.FindData.cFileName, -1, utfBuffer + 3, MAX_PATH + 1);
wcscat_s(utfBuffer, L"'\n");
DWORD written = 0;
WriteConsoleW(hStdOut, utfBuffer, wcslen(utfBuffer), &written, nullptr);
}
else
{
printf("%c '%s'\n", (item.FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 'D' : 'F',
item.FindData.cFileName);
}
}

// ReSharper disable once IdentifierTypo
for (auto* psTest : psNeeds)
{
BOOL lbOurFile = FALSE;
if (_tcsnicmp(psTest, item.FindData.cFileName, strlen(psTest)) == 0)
{
lbOurFile = TRUE;
if (item.FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
psTest += _tcslen(psTest);
if (*(psTest - 1) != _T('\\')) {
if (psTest[1] != _T('\n')) {
nRc = 200;
break;
}
*psTest = _T('\\');
psTest[1] = 0;
}
}
}

if (lbOurFile) {
nRc = CreateItem(item);
break;
}
}
}

CloseArchive(nullptr);
}

if (work_mode == WorkMode::Information || work_mode == WorkMode::ListFiles)
printf("Directories: %u\nFiles: %u\n", dirCount, fileCount);

if (nRc != 0)
printf("Can't extract\nRc: %i\n", nRc);
else
printf("Rc: %i\n", nRc);
SetConsoleOutputCP(prevCp);
return nRc;
}

int help()
{
printf("Dir.fmt.exe {e|x} \"dir_file\" \"file_list\"\n");
return 100;
}

int fail(int nCode)
{
printf("Can't extract!\nRc: %i\n", nCode);
return nCode;
}

int CreateItem(PluginPanelItem& Item)
{
int nRc = 0;
// ReSharper disable once CppEntityAssignedButNoRead
DWORD dwLastError = 0;

TCHAR* pszFile = Item.FindData.cFileName;
if (work_mode == WorkMode::ExtractNoPath) {
TCHAR* pszSlash = _tcsrchr(pszFile, _T('\\'));
if (pszSlash)
pszFile = pszSlash + 1;
}

if (Item.FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
printf("Creating folder: %s", pszFile);
CreateDirectory(pszFile, nullptr);
printf("\n");
}
else {
printf("Creating file: %s", pszFile);
// ReSharper disable once CppLocalVariableMayBeConst
HANDLE hFile = CreateFile(pszFile, GENERIC_WRITE, FILE_SHARE_READ, nullptr,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL/*Item.FindData.dwFileAttributes*/, nullptr);

if (hFile == INVALID_HANDLE_VALUE) {
nRc = 110;
}
else {
SetFilePointer(hFile, Item.FindData.nFileSizeLow, reinterpret_cast<PLONG>(&Item.FindData.nFileSizeHigh), FILE_BEGIN);
SetEndOfFile(hFile);
if (!SetFileTime(hFile, nullptr, nullptr, &Item.FindData.ftLastWriteTime))
dwLastError = GetLastError();
CloseHandle(hFile);
if (!SetFileAttributes(pszFile, Item.FindData.dwFileAttributes | FILE_ATTRIBUTE_HIDDEN))
dwLastError = GetLastError();
}
printf("\n");
}

std::ignore = dwLastError;
return nRc;
}
113 changes: 113 additions & 0 deletions Dir_b3/ModuleDef.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#ifndef _MODULE_DEF_H_
#define _MODULE_DEF_H_

#define MODULE_EXPORT __stdcall

// Extract progress callbacks
typedef int (CALLBACK *ExtractProgressFunc)(HANDLE, __int64);

#pragma pack(push, 1)

struct ExtractProcessCallbacks
{
HANDLE signalContext;
ExtractProgressFunc FileProgress;
};

#define ACTUAL_API_VERSION 6
#define STORAGE_FORMAT_NAME_MAX_LEN 32
#define STORAGE_PARAM_MAX_LEN 64

struct StorageGeneralInfo
{
wchar_t Format[STORAGE_FORMAT_NAME_MAX_LEN];
wchar_t Compression[STORAGE_PARAM_MAX_LEN];
wchar_t Comment[STORAGE_PARAM_MAX_LEN];
FILETIME Created;
};

struct StorageOpenParams
{
size_t StructSize;
const wchar_t* FilePath;
const char* Password;
const void* Data;
size_t DataSize;
};

struct StorageItemInfo
{
__int64 Size;
__int64 PackedSize;
DWORD Attributes;
FILETIME CreationTime;
FILETIME ModificationTime;
WORD NumHardlinks;
wchar_t Owner[64];
wchar_t Path[1024];
};

struct ExtractOperationParams
{
int ItemIndex;
int Flags;
const wchar_t* DestPath;
const char* Password;
ExtractProcessCallbacks Callbacks;
};

typedef int (MODULE_EXPORT *OpenStorageFunc)(StorageOpenParams params, HANDLE *storage, StorageGeneralInfo *info);
typedef int (MODULE_EXPORT *PrepareFilesFunc)(HANDLE storage);
typedef void (MODULE_EXPORT *CloseStorageFunc)(HANDLE storage);
typedef int (MODULE_EXPORT *GetItemFunc)(HANDLE storage, int item_index, StorageItemInfo* item_info);
typedef int (MODULE_EXPORT *ExtractFunc)(HANDLE storage, ExtractOperationParams params);

struct module_cbs
{
OpenStorageFunc OpenStorage;
CloseStorageFunc CloseStorage;
GetItemFunc GetItem;
ExtractFunc ExtractItem;
PrepareFilesFunc PrepareFiles;
};

struct ModuleLoadParameters
{
//IN
size_t StructSize;
const wchar_t* Settings;
//OUT
GUID ModuleId;
DWORD ModuleVersion;
DWORD ApiVersion;
module_cbs ApiFuncs;
};

#pragma pack(pop)

// Function that should be exported from modules
typedef int (MODULE_EXPORT *LoadSubModuleFunc)(ModuleLoadParameters*);
typedef void (MODULE_EXPORT *UnloadSubModuleFunc)(void);

#define MAKEMODULEVERSION(mj,mn) ((mj << 16) | mn)
#define STRBUF_SIZE(x) ( sizeof(x) / sizeof(x[0]) )

// Open storage return results
#define SOR_INVALID_FILE 0
#define SOR_SUCCESS 1
#define SOR_PASSWORD_REQUIRED 2

// Item retrieval result
#define GET_ITEM_ERROR 0
#define GET_ITEM_OK 1
#define GET_ITEM_NOMOREITEMS 2

// Extract result
#define SER_SUCCESS 0
#define SER_ERROR_WRITE 1
#define SER_ERROR_READ 2
#define SER_ERROR_SYSTEM 3
#define SER_USERABORT 4
#define SER_PASSWORD_REQUIRED 5

#endif
Loading