home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
WIN_UTL2
/
VULCAN.ZIP
/
VULSRC.ZIP
/
VULCAN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-08
|
38KB
|
964 lines
// VULCAN.CPP Part of VULCAN
// Copyright (c) 1993 John Deurbrouck
// #define COMPRESSION to enable compression check box, misc. support
// comment out line following ==++== to enable WarnOnDoesntFit check box
// this feature is disabled by default
#include<windows.h>
#include<stdio.h>
#include<commdlg.h>
#include<shellapi.h>
#include<ctype.h>
#include<dos.h>
#include<fcntl.h>
#include<share.h>
#include<sys\stat.h>
#include<sys\types.h>
#include"resource.h"
#include"vulcan.hpp"
#include"browse.hpp"
#include"cancel.hpp"
#include"vcn.hpp"
#define IDM_ABOUT (0x1010)
#define IDM_HELP (0x1020)
#define IDM_ONTOP (0x1030)
#define IDM_BROWSE (0x1040)
#define IDM_CONFIGURE (0x1050)
#define IDM_VULCANIZE (0x1060)
#define DC_FIRST '/'
#define DC_MIDDLE '|'
#define DC_LAST '\\'
#define DC_LONER '<'
// globals
////////////////////// configuration details
int IsDeleting=0,IsOnTop=0,MaxMegs=10,LeaveMegs=10,UseLeaveMegsNumber=0;
int WarnOnOverwrite=1,WarnOnDeleteSome=1,WarnOnDoesntFit=1;
int UseClassicIcons=0;
#ifdef COMPRESSION
int CompressFiles=1;
#else
int CompressFiles=0;
#endif
char szUserCaption[128]="";
int configuration_info_successfully_read=0;
////////////////////// following used to avoid rewriting .INI
int o_IsDeleting=-1,o_IsOnTop=-1;
int o_MaxMegs=-1,o_LeaveMegs=-1,o_UseLeaveMegsNumber=-1;
int o_WarnOnOverwrite=-1,o_WarnOnDeleteSome=-1,o_WarnOnDoesntFit=-1;
#ifdef COMPRESSION
int o_CompressFiles=-1;
#else
int o_CompressFiles=0;
#endif
char o_szUserCaption[sizeof(szUserCaption)]="";
////////////////////// main window/task data
char szCaption[128]="Vulcan";
HINSTANCE hMainInstance=NULL;
HWND hMainWindow=NULL;
HMENU gm=NULL;
////////////////////// general globals
HICON hIconVault=NULL,hIconTrash=NULL,hIconVulcan=NULL,hIconCurrent=NULL;
////////////////////// tons o' strings
char szIniFile[135];
char szTargetDirectory[135];
char *pszTargetDirFile;
char szAppName[]="Vulcan";
char szAppWarningTitle[]="Vulcan Warning";
char szAppErrorTitle[]="Vulcan Error";
char szVulcanVcn[]="VULCAN.VCN";
char szTempFileName[]="~TEMP.VCN";
char szClassName[]="VulcanClassDeurbrouck";
char pacBigScratchBuffer[BSB_SIZE]="";
char pacBigScratchBuffer2[BSB_SIZE]="";
static char copyright[]=
"VULCAN.EXE 1.0\n"
"File storage and archiving utility. It's a vault and a trashcan!\n"
"Copyright ⌐ 1993 John Deurbrouck\n\n"
"First published in PC Magazine February 8, 1994 (Vol 13 Nbr 3)\n";
static char helpstring_main[]=
"Use Add File... to put files into Vulcan, or drag and drop from Program Manager. "
"Use Browse... to examine your archive and restore files. "
"Configure... allows you to alter Vulcan's settings. "
"\n"
"Doubleclick Vulcan's caption to change between Vault and Trashcan modes. "
;
static char helpstring[]=
"Set archive size limits and deletion preference with this dialog "
"box. Cancel leaves previous settings (if any) unaltered."
"\n"
"Trashcan mode copies files then deletes the originals; Vault mode "
"only copies."
;
static char drag_drop_error[]=
"Error processing drag and drop. Files may not have been placed into "
"Vulcan archive. None of the original unstored files have been damaged "
"or deleted by Vulcan.";
// prototypes
LRESULT CALLBACK MainWindowProc(HWND,UINT,WPARAM,LPARAM);
BOOL CALLBACK ConfigureDialogProc(HWND,UINT,WPARAM,LPARAM);
void set_redraw_main_cursor(int show_main_cursor);
void adjust_to_configuration(void);
void read_configuration_information(void);
void write_configuration_information(void);
int set_szIniFile(void);
int set_szTargetDirectory(LPSTR cmdline);
int verify_target_not_in_use(HWND *activate);
int ProcessFile(LPSTR complete,LPSTR eight_three,int disp_char);
static int store_filedata(unsigned i,unsigned o,long bytes);
// not using last int (nCmdShow)
int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,int){
{ // try to get a larger message queue
int mqs;
for(mqs=8*6;mqs;mqs-=8){
if(SetMessageQueue(mqs))break;
}
if(!mqs){
char temp[128];
wsprintf(temp,"Internal error %d",__LINE__);
MessageBox(CURR_WINDOW,temp,szAppErrorTitle,MB_OK);
return 0;
}
}
hMainInstance=hInstance;
if(!set_szIniFile()){
char temp[128];
wsprintf(temp,"Internal error %d",__LINE__);
MessageBox(CURR_WINDOW,temp,szAppErrorTitle,MB_OK);
return 0;
}
for(;;){
if(!set_szTargetDirectory(lpszCmdLine))return 0;
{ // coerce szTargetDirectory to all caps
char *p=szTargetDirectory;
while(*p){
*p=toupper(*p);
p++;
}
}
{
HWND old_one=NULL;
if(!verify_target_not_in_use(&old_one)){
MessageBox(CURR_WINDOW,
"This VULCAN archive already in use -- "
"please choose another",
szAppErrorTitle,MB_OK);
//if(old_one!=NULL)SetActiveWindow(old_one);
lpszCmdLine="";
}
else break;
}
}
read_configuration_information();
if(UseClassicIcons){
hIconVault=LoadIcon(hMainInstance,MAKEINTRESOURCE(IDI_VAULT_OLD));
hIconTrash=LoadIcon(hMainInstance,MAKEINTRESOURCE(IDI_TRASH_OLD));
hIconVulcan=LoadIcon(hMainInstance,MAKEINTRESOURCE(IDI_VULCAN_OLD));
}
else{
hIconVault=LoadIcon(hMainInstance,MAKEINTRESOURCE(IDI_VAULT));
hIconTrash=LoadIcon(hMainInstance,MAKEINTRESOURCE(IDI_TRASH));
hIconVulcan=LoadIcon(hMainInstance,MAKEINTRESOURCE(IDI_VULCAN));
}
if(hIconVault==NULL||hIconTrash==NULL||hIconVulcan==NULL){
MessageBox(CURR_WINDOW,"VULCAN.EXE corrupted\nExiting",
szAppErrorTitle,MB_ICONSTOP|MB_OK);
return 0;
}
hIconCurrent=IsDeleting?hIconTrash:hIconVault;
if(hPrevInstance==NULL){
WNDCLASS wc;
wc.style=CS_DBLCLKS;
wc.lpfnWndProc=(WNDPROC)MainWindowProc;
wc.cbClsExtra=wc.cbWndExtra=0;
wc.hInstance=hMainInstance;
wc.hIcon=NULL;
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=NULL;
wc.lpszMenuName=NULL;
wc.lpszClassName=szClassName;
if(!RegisterClass(&wc)){
MessageBox(NULL,"Can't register\nExiting",
szAppErrorTitle,MB_ICONSTOP|MB_OK);
return 0;
}
}
hMainWindow=CreateWindowEx(0/*WS_EX_ACCEPTFILES*/,szClassName,szAppName,
WS_OVERLAPPED|/*WS_VISIBLE|*/WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,CW_USEDEFAULT,
/*SW_MINIMIZE*/CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hMainInstance,NULL);
if(hMainWindow==NULL){
MessageBox(NULL,"Can't create window\nExiting",
szAppErrorTitle,MB_ICONSTOP|MB_OK);
return 0;
}
ShowWindow(hMainWindow,SW_MINIMIZE);
if(!vcnSetup())PostMessage(hMainWindow,WM_SYSCOMMAND,SC_CLOSE,0L); // set up queue, exit if error
UINT old_errormode=SetErrorMode(SEM_FAILCRITICALERRORS); // Critical error
MSG msg;
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
SetErrorMode(old_errormode);
vcnDestroy();
return msg.wParam;
}
LRESULT CALLBACK MainWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,
LPARAM lParam){
static int doubleclick_status=0,doubleclick_time_delta=550;
static DWORD doubleclick_time;
switch(uMsg){
case WM_NCLBUTTONDOWN:
doubleclick_status=1;
doubleclick_time=GetTickCount();
break;
case WM_INITMENUPOPUP:
if(doubleclick_status){
if((doubleclick_status==1)&&
(wParam==gm)&&
HIWORD(lParam))
doubleclick_status=2;
else doubleclick_status=0;
}
break;
case WM_MENUSELECT:
if((doubleclick_status)&&(wParam==0)&&(lParam==0xFFFFL)){
doubleclick_status=(doubleclick_status==2)?3:0;
}
break;
case WM_NCLBUTTONUP:
if(doubleclick_status){
if((doubleclick_status==3)&&
(GetTickCount()<=(doubleclick_time+(DWORD)doubleclick_time_delta)))
PostMessage(hMainWindow,WM_SYSCOMMAND,(WPARAM)IDM_BROWSE,0L);
doubleclick_status=0;
}
break;
case WM_NCLBUTTONDBLCLK: // quick toggle of delete mode
doubleclick_status=0;
++IsDeleting%=2;
adjust_to_configuration();
break;
case WM_QUERYOPEN:
return 0;
case WM_CREATE: PostMessage(hWnd,WM_COMMAND,IDM_GETSTARTED,0L); return 0;
case WM_WININICHANGE:
doubleclick_time_delta=GetProfileInt("windows","DoubleClickSpeed",doubleclick_time_delta);
return 0;
case WM_COMMAND:
switch(wParam){
case IDM_GETSTARTED:
doubleclick_time_delta=GetProfileInt("windows","DoubleClickSpeed",doubleclick_time_delta);
gm=GetSystemMenu(hWnd,FALSE);
DeleteMenu(gm,SC_MINIMIZE,MF_BYCOMMAND);
DeleteMenu(gm,SC_RESTORE,MF_BYCOMMAND);
DeleteMenu(gm,SC_SIZE,MF_BYCOMMAND);
DeleteMenu(gm,SC_MAXIMIZE,MF_BYCOMMAND);
AppendMenu(gm,MF_SEPARATOR,0,NULL);
if(UseClassicIcons)AppendMenu(gm,MF_STRING,IDM_VULCANIZE,"&Vulcanize...");
else AppendMenu(gm,MF_STRING,IDM_VULCANIZE,"Add &File...");
AppendMenu(gm,MF_STRING,IDM_BROWSE,"&Browse...");
AppendMenu(gm,MF_STRING,IDM_CONFIGURE,"Con&figure...");
AppendMenu(gm,MF_STRING,IDM_ONTOP,"Always on &Top");
AppendMenu(gm,MF_STRING,IDM_HELP,"&Help...");
AppendMenu(gm,MF_STRING,IDM_ABOUT,"&About...");
adjust_to_configuration();
if(!configuration_info_successfully_read)
PostMessage(hWnd,WM_SYSCOMMAND,IDM_CONFIGURE,0L);
return 0;
}
break;
case WM_SYSCOMMAND:
switch(wParam&0xFFF0){
case SC_CLOSE: // allow shift-close to save VULCAN.VCN
if(0x8000&GetAsyncKeyState(VK_SHIFT)){
vcnSaveVcnFile();
return 0;
}
break;
case IDM_ABOUT:
set_redraw_main_cursor(1);
MessageBox(hWnd,copyright,"About Vulcan",MB_OK);
set_redraw_main_cursor(0);
return 0;
case IDM_HELP:
set_redraw_main_cursor(1);
MessageBox(hWnd,helpstring_main,"Vulcan Help",MB_OK);
set_redraw_main_cursor(0);
return 0;
case IDM_VULCANIZE:
{
static DWORD last_filter=1;
static char directory[128]="";
char whole_file_name[128]="";
set_redraw_main_cursor(1);
OPENFILENAME ofn={sizeof(ofn),hWnd,hMainInstance,
"All Files\0*.*\0Batch Files\0*.BAT\0"
"Documents\0*.DOC;*.TXT;*.WRI\0",NULL,0,
last_filter, // set to filter user chose last time
whole_file_name,sizeof(whole_file_name),0,0,
directory[0]?directory:NULL, // use last dir if possible
IsDeleting?"Vulcan -- Select file for Trashcan":
"Vulcan -- Select file for Vault",
OFN_FILEMUSTEXIST| // user can't save nonexistent files!
OFN_HIDEREADONLY| // IsDeleting covers this ground
OFN_NOCHANGEDIR| // don't leave a mess behind us
OFN_NOTESTFILECREATE, // shouldn't need this
0,0,NULL,0L,NULL,NULL};
if(IsDeleting)ofn.Flags|=OFN_NOREADONLYRETURN; // can't delete!
if(GetOpenFileName(&ofn)&&whole_file_name[0]){
char *p=&whole_file_name[ofn.nFileOffset]; // filename
start_cancel_dialog_box();
ProcessFile(whole_file_name,p,DC_LONER);
end_cancel_dialog_box();
*p=0;
if(p[-2]!=':')p[-1]=0; // strip trailing backslash
lstrcpy(directory,whole_file_name); // save dir
last_filter=ofn.nFilterIndex;
}
set_redraw_main_cursor(0);
return 0;
}
case IDM_ONTOP:
++IsOnTop%=2;
adjust_to_configuration();
return 0;
case IDM_BROWSE:
set_redraw_main_cursor(1);
start_browse_dialog_box();
set_redraw_main_cursor(0);
return 0;
case IDM_CONFIGURE:
set_redraw_main_cursor(1);
{
DLGPROC dbp=(DLGPROC)MakeProcInstance(
(FARPROC)ConfigureDialogProc,hMainInstance);
if(NULL!=dbp){
int retval=DialogBox(hMainInstance,
MAKEINTRESOURCE(IDD_CONFIGURATION),hMainWindow,dbp);
FreeProcInstance((FARPROC)dbp);
if(retval){
configuration_info_successfully_read=1;
adjust_to_configuration();
}
else{
set_redraw_main_cursor(0);
if(!configuration_info_successfully_read){
PostMessage(hWnd,WM_SYSCOMMAND,SC_CLOSE,0L);
}
}
}
}
return 0;
}
break;
case WM_PAINT:
{
RECT rect;
PAINTSTRUCT ps;
if(GetUpdateRect(hMainWindow,&rect,FALSE)){
HDC hdc=BeginPaint(hMainWindow,&ps);
if(hdc!=NULL){
DefWindowProc(hMainWindow, // erase bkgnd
WM_ICONERASEBKGND,(WORD)ps.hdc,0L);
DrawIcon(hdc,0,0,hIconCurrent);
}
EndPaint(hMainWindow,&ps);
}
return 0;
}
case WM_DROPFILES:
{
WORD total_files,current_file,x;
int disp_char;
char whole_name_buf[200],*p;
total_files=DragQueryFile((HDROP)wParam,-1,NULL,0);
if(total_files){
set_redraw_main_cursor(1);
start_cancel_dialog_box();
for(x=0;x<total_files;x++){
// switch so that first in drag-drop block will be last
// one sent to archive; on display, the first in the
// drag-drop block will be at the _top_ of the list
current_file=total_files-x-1;
UINT dqf=DragQueryFile((HDROP)wParam,current_file,
whole_name_buf,sizeof(whole_name_buf));
if(dqf<1){
MessageBox(hMainWindow,drag_drop_error,
szAppErrorTitle,MB_OK|MB_ICONSTOP);
break;
}
p=whole_name_buf;
while(*p)p++; // point at null terminator
p--; // points at last char in filename
for(;;){
if(p<=whole_name_buf)break; // don't go before start
if(*p=='\\'||*p==':'){ // found path
p++;
break; // p points at filename
}
p--; // move back...
}
if(total_files==1)disp_char=DC_LONER;
else if(current_file==0)disp_char=DC_FIRST;
else if(current_file==(total_files-1))disp_char=DC_LAST;
else disp_char=DC_MIDDLE;
if(!ProcessFile(whole_name_buf,p,disp_char))break;
}
end_cancel_dialog_box();
set_redraw_main_cursor(0);
}
DragFinish((HDROP)wParam);
return 0;
}
case WM_QUERYDRAGICON:
if(hIconCurrent!=NULL)return (LRESULT)MAKELONG((UINT)hIconCurrent,0);
break;
case WM_QUERYENDSESSION:
vcnSaveVcnFile();
break;
case WM_DESTROY:
vcnDestroy();
PostQuitMessage(0);
return FALSE;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
BOOL CALLBACK ConfigureDialogProc(HWND hWnd,UINT msg,WPARAM wParam,
LPARAM lParam){
switch(msg){
case WM_INITDIALOG:
pszTargetDirFile[-1]=0; // cut off terminating backslash
wsprintf(pacBigScratchBuffer,"Configuring Vulcan archive stored in %s",
(LPSTR)szTargetDirectory);
pszTargetDirFile[-1]='\\'; // restore terminating backslash
SetWindowText(GetDlgItem(hWnd,IDC_LOCATIONSTATIC),pacBigScratchBuffer);
SetWindowText(GetDlgItem(hWnd,IDC_ICONCAPTION),szUserCaption);
SetDlgItemInt(hWnd,IDC_MAXMEGS,MaxMegs,FALSE);
SetDlgItemInt(hWnd,IDC_LEAVEMEGS,LeaveMegs,FALSE);
CheckRadioButton(hWnd,IDC_MAXMEGSRADIO,IDC_LEAVEMEGSRADIO,
UseLeaveMegsNumber?IDC_LEAVEMEGSRADIO:IDC_MAXMEGSRADIO);
EnableWindow(GetDlgItem(hWnd,
UseLeaveMegsNumber?IDC_MAXMEGS:IDC_LEAVEMEGS),FALSE);
CheckRadioButton(hWnd,IDC_VAULTRADIO,IDC_TRASHCANRADIO,
IsDeleting?IDC_TRASHCANRADIO:IDC_VAULTRADIO);
CheckDlgButton(hWnd,IDC_ALWAYSONTOP,IsOnTop?1:0);
CheckDlgButton(hWnd,IDC_WARNOVERWRITE,WarnOnOverwrite?1:0);
CheckDlgButton(hWnd,IDC_WARNDELETE,WarnOnDeleteSome?1:0);
CheckDlgButton(hWnd,IDC_WARNNOTFIT,WarnOnDoesntFit?1:0);
// next line disables WarnOnDoesntFit ==++==
ShowWindow(GetDlgItem(hWnd,IDC_WARNNOTFIT),SW_HIDE);
#ifdef COMPRESSION
CheckDlgButton(hWnd,IDC_COMPRESSFILES,CompressFiles?1:0);
#else
CheckDlgButton(hWnd,IDC_COMPRESSFILES,0);
ShowWindow(GetDlgItem(hWnd,IDC_COMPRESSFILES),SW_HIDE);
#endif
return 1;
case WM_COMMAND:
switch(wParam){
case IDC_MAXMEGSRADIO:
if(BN_CLICKED==HIWORD(lParam)){
EnableWindow(GetDlgItem(hWnd,IDC_MAXMEGS),TRUE);
EnableWindow(GetDlgItem(hWnd,IDC_LEAVEMEGS),FALSE);
}
break;
case IDC_LEAVEMEGSRADIO:
if(BN_CLICKED==HIWORD(lParam)){
EnableWindow(GetDlgItem(hWnd,IDC_LEAVEMEGS),TRUE);
EnableWindow(GetDlgItem(hWnd,IDC_MAXMEGS),FALSE);
}
break;
case IDOK:
int iUseLeaveMegs,iNumber;
{
BOOL iGotItOk=0;
iUseLeaveMegs=IsDlgButtonChecked(hWnd,IDC_LEAVEMEGSRADIO)?1:0;
iNumber=(int)GetDlgItemInt(hWnd,
iUseLeaveMegs?IDC_LEAVEMEGS:IDC_MAXMEGS,&iGotItOk,FALSE);
if((!iGotItOk)||iNumber<1||iNumber>1024){
MessageBox(hWnd,"Must enter value from 1 to 1024",
"Vulcan Configuration Error",MB_OK);
SetFocus(GetDlgItem(hWnd,
iUseLeaveMegs?IDC_LEAVEMEGS:IDC_MAXMEGS));
return TRUE;
}
}
GetWindowText(GetDlgItem(hWnd,IDC_ICONCAPTION),
szUserCaption,(int)sizeof(szUserCaption)-1);
UseLeaveMegsNumber=iUseLeaveMegs;
if(UseLeaveMegsNumber)LeaveMegs=iNumber; else MaxMegs=iNumber;
IsDeleting=IsDlgButtonChecked(hWnd,IDC_TRASHCANRADIO)?1:0;
IsOnTop=IsDlgButtonChecked(hWnd,IDC_ALWAYSONTOP)?1:0;
WarnOnOverwrite=IsDlgButtonChecked(hWnd,IDC_WARNOVERWRITE)?1:0;
WarnOnDeleteSome=IsDlgButtonChecked(hWnd,IDC_WARNDELETE)?1:0;
WarnOnDoesntFit=IsDlgButtonChecked(hWnd,IDC_WARNNOTFIT)?1:0;
CompressFiles=IsDlgButtonChecked(hWnd,IDC_COMPRESSFILES)?1:0;
EndDialog(hWnd,TRUE);
return TRUE;
case IDCANCEL:
EndDialog(hWnd,FALSE);
return TRUE;
case IDC_BUTTONHELP:
MessageBox(hWnd,helpstring,"Vulcan Configuration Help",MB_OK);
return TRUE;
}
}
return 0;
}
void set_redraw_main_cursor(int show_main_cursor){
// set and redraw cursor for main window
// cursor is IDI_VULCAN if show_main_cursor is nonzero
// when called with 1, turns drag and drop receptivity off
// turns drag and drop receptivity on when called with 0
hIconCurrent=show_main_cursor?hIconVulcan:
(IsDeleting?hIconTrash:hIconVault);
InvalidateRect(hMainWindow,NULL,TRUE);
UpdateWindow(hMainWindow);
DragAcceptFiles(hMainWindow,show_main_cursor?FALSE:TRUE);
}
void adjust_to_configuration(void){
if(IsOnTop){
CheckMenuItem(gm,IDM_ONTOP,MF_BYCOMMAND|MF_CHECKED);
SetWindowPos(hMainWindow,HWND_TOPMOST,0,0,0,0,
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE);
}
else{
CheckMenuItem(gm,IDM_ONTOP,MF_BYCOMMAND|MF_UNCHECKED);
SetWindowPos(hMainWindow,HWND_NOTOPMOST,0,0,0,0,
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE);
}
if(szUserCaption[0])
wsprintf(szCaption,"%s -- %s",(LPSTR)szAppName,(LPSTR)szUserCaption);
else wsprintf(szCaption,"%s",(LPSTR)szAppName);
SetWindowText(hMainWindow,szCaption);
DrawMenuBar(hMainWindow);
set_redraw_main_cursor(0);
write_configuration_information();
}
void read_configuration_information(void){
// INI file is szIniFile, section is szTargetDirectory
// if all items successfully read (but szUserCaption, optional),
// set configuration_info_successfully_read to 1
LPCSTR sec=szTargetDirectory;
int success=1,itemp;
*pszTargetDirFile=0; // get raw dirname
// MaxMegs
itemp=GetPrivateProfileInt(sec,"MaxMegs",-1,szIniFile);
if(itemp<1)success=0;
else o_MaxMegs=MaxMegs=itemp;
// LeaveMegs
itemp=GetPrivateProfileInt(sec,"LeaveMegs",-1,szIniFile);
if(itemp<1)success=0;
else o_LeaveMegs=LeaveMegs=itemp;
// UseLeaveMegsNumber
itemp=GetPrivateProfileInt(sec,"UseLeaveMegsNumber",-1,szIniFile);
if(itemp<0||itemp>1)success=0;
else o_UseLeaveMegsNumber=UseLeaveMegsNumber=itemp;
// IsOnTop
itemp=GetPrivateProfileInt(sec,"IsOnTop",-1,szIniFile);
if(itemp<0||itemp>1)success=0;
else o_IsOnTop=IsOnTop=itemp;
// IsDeleting
itemp=GetPrivateProfileInt(sec,"IsDeleting",-1,szIniFile);
if(itemp<0||itemp>1)success=0;
else o_IsDeleting=IsDeleting=itemp;
// UseClassicIcons
itemp=GetPrivateProfileInt("Globals","UseClassicIcons",0,szIniFile);
UseClassicIcons=itemp?1:0;
// CompressFiles
#ifdef COMPRESSION
itemp=GetPrivateProfileInt(sec,"CompressFiles",-1,szIniFile);
if(itemp<0||itemp>1)success=0;
else o_CompressFiles=CompressFiles=itemp;
#else
o_CompressFiles=CompressFiles=0;
#endif
// WarnOnOverwrite
itemp=GetPrivateProfileInt(sec,"WarnOnOverwrite",-1,szIniFile);
if(itemp<0||itemp>1)success=0;
else o_WarnOnOverwrite=WarnOnOverwrite=itemp;
// WarnOnDeleteSome
itemp=GetPrivateProfileInt(sec,"WarnOnDeleteSome",-1,szIniFile);
if(itemp<0||itemp>1)success=0;
else o_WarnOnDeleteSome=WarnOnDeleteSome=itemp;
// WarnOnDoesntFit
itemp=GetPrivateProfileInt(sec,"WarnOnDoesntFit",-1,szIniFile);
if(itemp<0||itemp>1)success=0;
else o_WarnOnDoesntFit=WarnOnDoesntFit=itemp;
// szUserCaption
itemp=GetPrivateProfileString(sec,"IconCaption","",
szUserCaption,sizeof(szUserCaption),szIniFile);
if(!itemp)szUserCaption[0]=0;
if(success)configuration_info_successfully_read=1;
}
void write_configuration_information(void){
char number_buf[20];
*pszTargetDirFile=0;
char printstring[]="%d";
#define WRITE_INI_INT_IF_NEEDED(x) if(x!=o_##x){\
wsprintf(number_buf,printstring,x);\
if(WritePrivateProfileString(szTargetDirectory,#x,\
number_buf,szIniFile))o_##x=x;\
else o_##x=-1;\
}
WRITE_INI_INT_IF_NEEDED(IsDeleting)
WRITE_INI_INT_IF_NEEDED(IsOnTop)
WRITE_INI_INT_IF_NEEDED(MaxMegs)
WRITE_INI_INT_IF_NEEDED(LeaveMegs)
WRITE_INI_INT_IF_NEEDED(UseLeaveMegsNumber)
WRITE_INI_INT_IF_NEEDED(WarnOnOverwrite)
WRITE_INI_INT_IF_NEEDED(WarnOnDeleteSome)
WRITE_INI_INT_IF_NEEDED(WarnOnDoesntFit)
WRITE_INI_INT_IF_NEEDED(CompressFiles)
if(lstrcmp(szUserCaption,o_szUserCaption)){
if(WritePrivateProfileString(szTargetDirectory,"IconCaption",
szUserCaption[0]?szUserCaption:NULL,szIniFile)){
lstrcpy(o_szUserCaption,szUserCaption);
}
}
}
int set_szIniFile(void){
// sets szIniFile name for use as private profile file
// return 0 if fail, 1 if success
if(!GetModuleFileName(hMainInstance,szIniFile,sizeof(szIniFile)))
lstrcpy(szIniFile,"VULCAN.EXE");
char *p=szIniFile;
while(*p)p++;
for(;;){
if(p==szIniFile)return 0;
if(*p=='.')break; // pointing at .EXE extension
p--;
}
lstrcpy(p,".INI");
return 1;
}
int set_szTargetDirectory(LPSTR cmdline){
// checks cmd line to see if VULCAN.VCN file specified with
// complete path. If not, uses common dialog to choose the
// file, then sets szTargetDirectory to the pathname (including
// trailing backslash
// also sets pszTargetDirFile to point at the spot _after_ the
// trailing backslash
int ok=0;
LPSTR candidate_name;
if(cmdline!=NULL&&*cmdline){
candidate_name=cmdline;
LPSTR p=cmdline;
for(;;){
int got_colon=0;
while(*p){
if(*p==':')got_colon=1;
*p=toupper(*p);
p++;
} // point at null terminator
if(!got_colon)break; // can't be full path without one
for(;;){
if(p==cmdline)break;
if(*p==':'||*p=='\\'){p++;break;}
p--;
} // point at filename
lstrcpy(p,szVulcanVcn); // coerce to right filename
if(lstrcmp(szVulcanVcn,p))break;
*p=0;
ok=1;
break;
}
}
else{
szTargetDirectory[0]=0;
OPENFILENAME ofn={sizeof(ofn),NULL,hMainInstance,
"Vulcan Index File\0VULCAN.VCN\0",NULL,0,
1,szTargetDirectory,sizeof(szTargetDirectory),0,0,
NULL, // use last dir if possible
"Vulcan -- Select directory for Trashcan/Vault",
OFN_HIDEREADONLY| // IsDeleting covers this ground
OFN_NOCHANGEDIR| // don't leave a mess behind us
OFN_PATHMUSTEXIST| // directory must exist
OFN_NOREADONLYRETURN| // can't be read-only for archive!
OFN_NOTESTFILECREATE| // shouldn't need this
OFN_ENABLETEMPLATE, // using custom template
0,0,NULL,0L,NULL,
MAKEINTRESOURCE(IDD_OPENFILE)}; // template
for(;;){
candidate_name=NULL;
if(!GetSaveFileName(&ofn)||!szTargetDirectory[0])break;
candidate_name=szTargetDirectory;
char *p=szTargetDirectory;
while(*p){
*p=toupper(*p);
p++;
} // point at end of string
for(;;){
if(p==szTargetDirectory)break;
if(*p==':'||*p=='\\'){p++;break;}
p--;
} // point at filename
lstrcpy(p,szVulcanVcn); // coerce to right filename
if(lstrcmp(szVulcanVcn,p))break;
*p=0;
ok=1;
break;
}
}
if((!ok)&&(candidate_name!=NULL)){
char temp[160];
wsprintf(temp,"%s is not a valid, fully qualified name for "
"VULCAN.VCN",candidate_name);
MessageBox(CURR_WINDOW,temp,szAppErrorTitle,MB_OK); // ==++CURR_WINDOW
}
else{
lstrcpy(szTargetDirectory,candidate_name);
pszTargetDirFile=szTargetDirectory;
while(*pszTargetDirFile)pszTargetDirFile++;
}
return ok;
}
int verify_target_not_in_use(HWND *activate){
// returns 1 if all is OK i.e. target not yet in use
// returns 0 if target already in use
// first save our target directory...
lstrcpy(pacBigScratchBuffer2,szTargetDirectory);
HWND next=GetWindow(GetDesktopWindow(),GW_CHILD);
while(next!=NULL){ // process each child of the desktop window
// don't check our own!
for(;;){
if(hMainInstance==(HINSTANCE)GetWindowWord(next,GWW_HINSTANCE)){
break; // same instance is us! don't check...
}
// get class name
if(!GetClassName(next,pacBigScratchBuffer,BSB_SIZE))break;
// if it's not ours, don't bother...
if(lstrcmp(pacBigScratchBuffer,szClassName))break;
// ok, it's a window of our class but not us
// let's find out what its szTargetDirectory is
// new get theirs
GetInstanceData(GetWindowWord(next,GWW_HINSTANCE),
(unsigned char *)szTargetDirectory,
sizeof(szTargetDirectory));
// strip string down to directory only
{
char *p=szTargetDirectory;
while(*p)p++;
while((p>szTargetDirectory)&&(*p!='\\'))*p--=0;
}
// if they're the same, we've got trouble
if(!lstrcmp(szTargetDirectory,pacBigScratchBuffer2)){
*activate=next;
return 0;
}
break;
}
next=GetWindow(next,GW_HWNDNEXT);
}
lstrcpy(szTargetDirectory,pacBigScratchBuffer2);
return 1;
}
int ProcessFile(LPSTR complete,LPSTR eight_three,int disp_char){
// returns 0 if user pressed cancel, 1 for success or file too large
// also returns 1 if a single file failed and user knows...
// handles whole process of confirmation, copy, rename, etc.
set_cancel_dialog_box_text(IsDeleting?"Copying and deleting"
:"Copying",complete);
if(check_cancel_dialog_box())return 0;
char dir[138],*p;
if(!complete||!*complete||!eight_three||!*eight_three||!disp_char){
wsprintf(pacBigScratchBuffer,"Internal error %d",__LINE__);
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
return 0;
}
lstrcpy(dir,complete);
p=dir;
while(*p)p++; // point at terminating null
p--; // last char of string
for(;;){
if(p==dir){
wsprintf(pacBigScratchBuffer,"Internal error %d",__LINE__);
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
}
if(*p=='\\'||*p==':'){
p[1]=0;
break;
}
p--;
}
// ok now we have verified original file's name
// now get file's size, attributes
vcn_info vi;
long t,b;
vcnGetFilenumberRange(b,t);
vi.version=1;
vi.signature=SIGNATURE;
vi.DispChar=disp_char;
vi.Index=t+1L;
int fh;
unsigned attrib;
lstrcpy(pacBigScratchBuffer,complete);
if(_dos_getfileattr(pacBigScratchBuffer,&attrib)||
_dos_open(pacBigScratchBuffer,_O_RDONLY,&fh)){
wsprintf(pacBigScratchBuffer,"Can't open %s\n\nFile not %s.",
(LPSTR)complete,(LPSTR)(IsDeleting?"moved":"copied"));
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
return 1; // user knows, now get rest of files
}
vi.Attrib=attrib;
struct _stat statbuf;
unsigned filedate,filetime;
if(_fstat(fh,&statbuf)||_dos_getftime(fh,&filedate,&filetime)){
_dos_close(fh);
wsprintf(pacBigScratchBuffer,"Error accessing %s\n\nFile not %s.",
(LPSTR)complete,(LPSTR)(IsDeleting?"moved":"copied"));
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
_dos_close(fh);
return 1; // get rest of files...
}
vi.FileSize=statbuf.st_size;
vi.FileDate=filedate;
vi.FileTime=filetime;
vi.compressed=CompressFiles?1:0;
vi.FullName=complete;
// ok, now vi is full
// now determine if file should be copied
// if it won't fit no matter what, we'll be punting
if(vcnGetTargetDiskBytes()<
vcnAdjustForClusterSize(vi.FileSize+INFLATION)){
if(WarnOnDoesntFit){
wsprintf(pacBigScratchBuffer,"Cannot put %s into archive -- "
"alone it is larger than the space you have available "
"for your VULCAN archive. File not %s.",
(LPSTR)complete,
(LPSTR)(IsDeleting?"moved":"copied"));
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
}
_dos_close(fh);
return 1; // user knows this one file didn't make it, why not
// allow rest of files to move?
}
// ok, so it can fit. do we have to delete files to do it?
if(vcnAddBytesRequiresSomeDelete(vi.FileSize)){
if(WarnOnDeleteSome){ // give user the option...
wsprintf(pacBigScratchBuffer,"Must delete some files to %s "
"%s to VULCAN's archive. You may choose to allow this deletion "
"or cancel the operation.\n\n"
"YES means go ahead, add the new file and delete old files as "
"necessary.\n\n"
"NO means don't add the file, and don't delete any existing "
"files.",(LPSTR)(IsDeleting?"move":"copy"),(LPSTR)complete);
switch(MessageBox(CURR_WINDOW,pacBigScratchBuffer,
szAppErrorTitle,MB_YESNO)){
case IDYES:
break;
default:
case IDNO:
_dos_close(fh);
return 0;
}
}
vcnForceToCorrectSize(vi.FileSize); // pare the archive
}
// ok, now we have adequate space and we want to copy the file
// first, get filename like C:\VULCAN\ARC\~TEMP.VCN -- target name
lstrcpy(pszTargetDirFile,szTempFileName);
// now delete any old ~TEMP.VCN
_dos_setfileattr(szTargetDirectory,_A_NORMAL);
remove(szTargetDirectory);
// now open ~TEMP.VCN
int ofh;
if(_dos_creatnew(szTargetDirectory,_A_NORMAL,&ofh)){
wsprintf(pacBigScratchBuffer,"Could not open %s. File not %s.",
(LPSTR)complete,(LPSTR)(IsDeleting?"moved":"copied"));
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
_dos_close(fh);
return 0;
}
// now both files open, fh for read and ofh for write
// first, write header data to ofh
int store_result=1,header_size=0;
if(vcnWriteEntry(vi,ofh,&header_size)){ // success
store_result=store_filedata(fh,ofh,vi.FileSize);
}
_dos_close(fh);
_dos_close(ofh);
switch(store_result){
case 1: // error forced quit
wsprintf(pacBigScratchBuffer,"Error copying %s. File not %s.",
(LPSTR)complete,(LPSTR)(IsDeleting?"moved":"copied"));
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
remove(szTargetDirectory); // delete the file
return 1; // user knows, let it ride
case 2: // user pressed cancel
remove(szTargetDirectory); // delete the file
return 0;
}
// ok, we have successfully copied file and closed it -- rename it
lstrcpy(pacBigScratchBuffer2,szTargetDirectory); // "C:\A\~TEMP.VCN"
wsprintf(pszTargetDirFile,"%08ld.VCN",vi.Index); // "C:\A\00000422.VCN"
if(rename(pacBigScratchBuffer2,szTargetDirectory)){
wsprintf(pacBigScratchBuffer,"Cannot rename %s to %s. File not %s.",
(LPSTR)pacBigScratchBuffer2,(LPSTR)szTargetDirectory,
(LPSTR)(IsDeleting?"moved":"copied"));
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
remove(pacBigScratchBuffer2);
return 0; // this means we're really messed up, force cancel
}
// now add StoredDate, StoredTime and StoredSize elements
// get data from file rather than computation to allow for
// compression and variable header size
{
struct _stat ss;
if(!_stat(szTargetDirectory,&ss))vi.StoredSize=ss.st_size;
else vi.StoredSize=vi.FileSize+(long)header_size;
vi.StoredDate=vi.StoredTime=0;
if(!_dos_open(szTargetDirectory,_O_RDONLY,&fh)){
unsigned d,t;
if(!_dos_getftime(fh,&d,&t)){
vi.StoredDate=d;
vi.StoredTime=t;
}
_dos_close(fh);
}
}
// now add to queue
if(!vcnPutInfo(vi)){
wsprintf(pacBigScratchBuffer,"Out of memory adding %s. File not %s.",
(LPSTR)complete,(LPSTR)(IsDeleting?"moved":"copied"));
MessageBox(CURR_WINDOW,pacBigScratchBuffer,szAppErrorTitle,MB_OK);
remove(szTargetDirectory); // delete the file
return 0; // we're messed up, force cancel
}
// now delete the original if necessary
if(IsDeleting){
set_cancel_dialog_box_text("Deleting",NULL);
lstrcpy(pacBigScratchBuffer,complete);
_dos_setfileattr(pacBigScratchBuffer,_A_NORMAL);
remove(pacBigScratchBuffer);
}
return 1;
}
static int store_filedata(unsigned i,unsigned o,long bytes){
// returns 0 for success, 1 for failure, 2 for user quit
// doesn't close files, does no renames or deletes on fail
unsigned numwanted,numdone;
while(bytes){
// copy BSB_SIZE bytes at a time from i to o
if(check_cancel_dialog_box())return 2;
numwanted=(unsigned)(BSB_SIZE<bytes?BSB_SIZE:bytes);
if(_dos_read(i,pacBigScratchBuffer,numwanted,&numdone)||
numdone!=numwanted){
return 1; // read failure
}
if(_dos_write(o,pacBigScratchBuffer,numwanted,&numdone)||
numwanted!=numdone){
return 1; // write failure
}
bytes-=(long)numwanted;
}
return 0;
}