Files
TempleOS-Rijn/Windows/LTZ/LTZ.cpp
T
2018-09-08 21:45:20 +02:00

336 lines
8.3 KiB
C++

// LTZ.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "LTZ.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
CWinApp theApp;
using namespace std;
#define F_ASCII 1
#define F_MAKE 2
#define F_EXTRACT 4
#define F_COMPRESS 8
#define F_EXPAND 16
DWORD ltz_flags,pfile_blks,cur_signature=0x78123456;
char cur_dir[MAX_PATH],cur_pfile[MAX_PATH];
class tree_node
{
public:
tree_node *next_sibling,*first_child,*parent;
TCHAR name[MAX_PATH];
tree_node(tree_node *_parent);
~tree_node();
CString path();
CString full_name();
};
typedef tree_node *tree_node_ptr;
tree_node::tree_node(tree_node *_parent)
{
parent=_parent;
next_sibling=NULL;
first_child=NULL;
*name=0; //So path() works for root
}
tree_node::~tree_node()
{
delete first_child;
delete next_sibling;
}
CString tree_node::path()
{
CString result;
if (parent) {
result=parent->path();
if (result.Right(1)==CString(_T("\\")))
result+=parent->name;
else
result+=CString(_T("\\"))+parent->name;
}
else
result=cur_dir;
return result;
}
CString tree_node::full_name()
{
CString result=path();
if (result.Right(1)!=CString(_T("\\")))
result+=_T("\\");
result+=name;
return result;
}
void convert(CString nname,double in_size)
{
DWORD out_size,i;
ArcCompressStruct *in_buf;
BYTE *out_buf;
FILE *io_file;
char name[512];
strcpy(name,nname.GetBuffer(512));
nname.ReleaseBuffer();
in_buf=(ArcCompressStruct *)malloc(in_size);
io_file=fopen(name,"rb");
fread(in_buf,1,in_size,io_file);
out_size=in_buf->expanded_size;
printf("%-45s %d-->%d\r\n",name,(DWORD) in_size,out_size);
fclose(io_file);
out_buf=ExpandBuf(in_buf);
if (out_buf) {
if (ltz_flags & F_ASCII) {
for (i=0;i<out_size;i++)
if (out_buf[i]==5 ||out_buf[i]==31) out_buf[i]=32;
}
name[strlen(name)-1]='z';
io_file=fopen(name,"wb");
fwrite(out_buf,1,out_size,io_file);
fclose(io_file);
free(out_buf);
}
free(in_buf);
}
double AddFolder(LPCTSTR path,tree_node *parent)
{
CString str,str2;
HANDLE file_search;
WIN32_FIND_DATA find_data;
tree_node *tempt,**back_link;
double total=0.0;
back_link=&(parent->first_child);
str=path;
if (str.Right(1)==CString(_T("\\")))
str+=_T("*.*");
else
str+=_T("\\*.*");
if ((file_search=FindFirstFile(str,&find_data))
!=INVALID_HANDLE_VALUE)
{
do {
if (strcmp(find_data.cFileName,_T(".")) &&
strcmp(find_data.cFileName,_T("..")) ) {
tempt=new tree_node(parent);
strcpy(tempt->name,find_data.cFileName);
*back_link=tempt;
back_link=&(tempt->next_sibling);
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
str=path;
if (str.Right(1)!=CString(_T("\\")))
str+=_T("\\");
str+=find_data.cFileName;
total+=AddFolder(str,tempt);
} else {
total+=find_data.nFileSizeLow+
((double)0xFFFFFFFF+1)*find_data.nFileSizeHigh;
if (find_data.cFileName[strlen(find_data.cFileName)-1]=='Z') {
str2=path;
if (str2.Right(1)!=CString(_T("\\")))
str2+=_T("\\");
str2+=find_data.cFileName;
convert(str2,find_data.nFileSizeLow+
((double)0xFFFFFFFF+1)*find_data.nFileSizeHigh);
}
}
}
} while (FindNextFile(file_search,&find_data));
FindClose(file_search);
}
return total;
}
void SetBlk(FILE *f,DWORD blk)
{
fseek(f,blk*512,SEEK_SET);
}
void SetCluster(FILE *f,DWORD cluster_lo,LTBootStruct *b)
{
SetBlk(f,(cluster_lo-1)*b->sectors_per_cluster+1+b->bitmap_sectors);
}
void ExtractFile(CString str,FILE *in_file,LTDirEntry *d,LTBootStruct *b)
{
FILE *out_file;
BYTE *buf=(BYTE *)malloc(d->size_lo);
SetCluster(in_file,d->cluster_lo,b);
fread(buf,d->size_lo,1,in_file);
out_file=fopen((const char *)str,"wb");
fwrite(buf,d->size_lo,1,out_file);
fclose(out_file);
free(buf);
}
void ExtractDir(CString str,FILE *in_file,DWORD lo,DWORD size,LTBootStruct *b)
{
LTDirEntry *d=(LTDirEntry *)malloc(size);
DWORD i;
CString str2;
char sysbuf[MAX_PATH];
sprintf(sysbuf,"MD %s",(const char *)str);
system(sysbuf);
if (str.Right(1)!=CString(_T("\\")))
str+=_T("\\");
SetCluster(in_file,lo,b);
fread(d,size,1,in_file);
for (i=2;i<size/sizeof(LTDirEntry);i++) {
if (*d[i].name) {
if (!(d[i].attr & LT_ATTR_DELETED)) {
str2=str;
str2+=d[i].name;
printf("%s\r\n",(const char *)str2);
if (d[i].attr & LT_ATTR_DIR)
ExtractDir(str2,in_file,d[i].cluster_lo,d[i].size_lo,b);
else
ExtractFile(str2,in_file,&d[i],b);
}
} else
break;
}
free(d);
}
void ExtractFiles()
{
LTBootStruct b;
LTDirEntry d[8];
FILE *in_file=fopen(cur_pfile,"rb");
if (!in_file) return;
fread(&b,512,1,in_file);
SetCluster(in_file,b.root_cluster_lo,&b);
fread(&d,512,1,in_file);
ExtractDir(cur_dir,in_file,b.root_cluster_lo,d[0].size_lo,&b);
fclose(in_file);
}
void MakePFile()
{
BYTE buf[512];
DWORD i,*d;
FILE *out_file=fopen(cur_pfile,"wb");
if (!out_file) return;
for (i=0;i<512;i++)
buf[i]=i;
for (i=0;i<pfile_blks;i++) {
d=(DWORD *)&buf;
*d=i;
d=(DWORD *)&buf[4];
*d=0;
d=(DWORD *)&buf[8];
*d=pfile_blks;
d=(DWORD *)&buf[12];
*d=0;
d=(DWORD *)&buf[512-4];
*d=cur_signature;
fwrite(buf,512,1,out_file);
}
fclose(out_file);
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
char *st;
DWORD i;
BOOL valid;
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) {
cerr << _T("Fatal Error: MFC initialization failed") << endl;
return EXIT_FAILURE;
}
ltz_flags=0;
valid=TRUE;
cur_dir[0]=0;
cur_pfile[0]=0;
for (i=1;i<argc;i++) {
st=argv[i];
if (!strcmp(st,"-ascii"))
ltz_flags|=F_ASCII;
else if (!strcmp(st,"-make"))
ltz_flags|=F_MAKE;
else if (!strcmp(st,"-extract"))
ltz_flags|=F_EXTRACT;
else if (!strcmp(st,"-compress"))
ltz_flags|=F_COMPRESS;
else if (!strcmp(st,"-expand"))
ltz_flags|=F_EXPAND;
else if (*st=='-') {
valid=FALSE;
break;
} else if (!cur_dir[0])
strcpy(cur_dir,st);
else if (!cur_pfile[0])
strcpy(cur_pfile,st);
else
cur_signature=atoi(st);
}
if (ltz_flags & F_MAKE) {
if (!cur_pfile[0])
valid=FALSE;
if (ltz_flags & ~F_MAKE)
valid=FALSE;
} else if (ltz_flags & F_EXTRACT) {
if (!cur_pfile[0])
valid=FALSE;
if (ltz_flags & ~F_EXTRACT)
valid=FALSE;
} else if (ltz_flags & F_COMPRESS) {
valid=FALSE; //todo
if (!cur_pfile[0])
valid=FALSE;
if (ltz_flags & ~F_COMPRESS)
valid=FALSE;
} else if (ltz_flags & F_EXPAND) {
if (!cur_dir[0] || cur_pfile[0])
valid=FALSE;
if (ltz_flags & ~(F_EXPAND|F_ASCII))
valid=FALSE;
} else
valid=FALSE;
if (!valid) {
printf("LTZ -make blkcnt partitionfile signature\r\n");
printf("LTZ -extract dirname partitionfile\r\n");
//todo printf("LTZ -compress dirname partitionfile");
printf("LTZ -expand [-ascii] dirname\r\n");
printf("\r\n\r\n dirname\tWindows directory.\r\n");
printf(" partitionfile\tfile used to go between Windows and LoseThos.\r\n");
printf(" signature\tenter a unique numeric value which LoseThos can find.\r\n");
printf(" -ascii\twill convert cursor position and shifted spaces to spaces.\r\n");
} else {
if (ltz_flags & F_MAKE) {
pfile_blks=atoi(cur_dir);
if (pfile_blks<0x100000/512)
printf("Minimum of 1 Meg\r\n");
else
MakePFile();
} else if (ltz_flags & F_EXTRACT)
ExtractFiles();
else if (ltz_flags & F_EXPAND) {
tree_node tree_root(NULL);
AddFolder(cur_dir,&tree_root);
}
}
return EXIT_SUCCESS;
}