/**************/ /* wincdfil.c */ /***************************************************************************** PROGRAM: wincdfil.c Windows: Win 3.1 & WIN32 PURPOSE: WinCD:n käyttämät tiedostorutiinit Editor: Vesa Lappalainen 17.7.1994 PROJECT: wincdfil ALI\mjonot.c *****************************************************************************/ #include #include /* Mitä nyt aina Windowsissa tarvitaan */ #include /* mm. strlen */ #include /* mm. chdir */ #include /* mm. diskfree_t */ #include /* filelength */ #include /* mm. time_t */ #include /* toupper */ #include "mjonot.h" /* mm. kopioi_jono */ #include "transdlg.h" /* TranslateHandler */ #include "language.h" /* mm. T() */ #include "optdlg.h" #include "wincd.h" #include "wincdfil.h" /* Tarkistuksen vuoksi, etti tyyppi muuttunut */ /****************************************************************************/ #define ArgS 255 static char ArgStr[ArgS]; static char ArgStrA[ArgS]; static char *ArgP[]={ArgStr,ArgStrA}; static char *ArgN[]={"ARGS","ARGSA"}; /****************************************************************************/ /****************************************************************************/ /* Optioiden käsittely */ /****************************************************************************/ #define NPK N_P_K #define WO tWinCDOptions #define K2(t) t,t tWinCDOptions WinCDOptions = {"","","",":CUR:\\",1,"",0,26,0,0}; const KontrolliKuvaus WinCDOptCtrl[] = { {K2(IDC_WINCDDIR) , C_edte, NPK(WO,WinCDDir) ,T_str ,0,NULL}, {K2(IDC_LOGFILE) , C_edte, NPK(WO,LogFile) ,T_str ,0,NULL}, {K2(IDC_CURDIRFILE) , C_edte, NPK(WO,CurrentDirFile) ,T_str ,0,NULL}, {K2(IDC_FILEPAD) , C_edte, NPK(WO,FilePad) ,T_str ,0,NULL}, {K2(IDC_CB_FILEPAD) , C_acbo, NPK(WO,DoFilePad) ,T_byte,0,NULL}, {K2(IDC_RUNAFTER) , C_edte, NPK(WO,RunAfter) ,T_str ,0,NULL}, {K2(IDC_CB_RUNAFTER) , C_acbo, NPK(WO,DoRunAfter) ,T_byte,0,NULL}, // {K2(IDC_NRTEXT) , C_edte, NPK(WO,NrText) ,T_int ,1,NULL}, {K2(IDC_AUTOCLIPBOARD) , C_acbo, NPK(WO,AutoClipboard) ,T_byte,0,NULL}, {K2(IDC_AUTOFILECLIPBOARD), C_acbo, NPK(WO,AutoFileClipboard) ,T_byte,0,NULL}, {K2(0) , 0 , 0 ,0, 0,NULL} }; #undef NPK #undef WO #undef K2 const DialogiParam WincdOptDlgParam = { "WINCDOPT", D_modal, WinCDOptCtrl, WINCDINI, MAINITEM, &WinCDOptions, sizeof(WinCDOptions) }; int WinCDOptionDialog(HWND hWnd) { return OptioDialogiJaIni(hWnd,&WincdOptDlgParam,OPT_SAVE); } int InitWinCDOptions(void) { SetOptPreHandler(TranslateHandler); return AlustaOptiot(&WincdOptDlgParam); } /****************************************************************************/ /* Optioiden käsittely tehty */ /****************************************************************************/ /****************************************************************************/ static char str[255]; /* Apumuuttuja paluuarvoihin */ /****************************************************************************/ int WCD_MessageBox(HWND hwndParent, LPCSTR lpszText, LPCSTR lpszTitle, UINT fuStyle) { int ret; POINT pt1,pt2; RECT rc; // WORD x,y; GetWindowRect(GetDesktopWindow(), &rc); GetCursorPos(&pt1); // x = rc.right / 2; y = rc.bottom / 2; // SetCursorPos(x,y); ret = MessageBox(hwndParent, lpszText, lpszTitle, fuStyle); GetCursorPos(&pt2); // SetCursorPos(pt1.x+pt2.x-x,pt1.y+pt2.y-y); return ret; } /****************************************************************************/ const char *jono_pieneksi_cond(char *s) { int i,len = strlen(s); for (i=0; i mika.oma */ { char *p; for (p=s; *p; p++) if ( *p == ' ' ) { *p = 0; break; } return s; } /****************************************************************************/ char *WCD_Extension(const char *o) /* Palauttaa jonon pelkän tarkenneosan */ { while ( *o ) if ( *o++ == '.' ) return (char *)o; return (char *)o; } /************************************************************************/ static const char *wcd_Path(const char *filename) /* Palautetaan nimen polkuosa */ { static char spath[200]; int i; kopioi_jono(N_S(spath),filename); wcd_FirstName(spath); for (i=strlen(spath); i>=0; i--) if ( spath[i]=='\\' ) { spath[i]=0; return spath; } for (i=strlen(spath); i>=0; i--) if ( spath[i]==':' ) { spath[i+1]=0; return spath; } return ""; } /************************************************************************/ static char *wcd_Name(char *filename) /* Palautetaan nimestä vain tiedoston nimiosa */ { static char fname[200]; int i; kopioi_jono(N_S(fname),filename); i = strlen(wcd_FirstName(fname))-1; while ( i >= 0 && fname[i]!='\\' && fname[i]!=':' ) i--; return fname+i+1; } /************************************************************************/ const char *WCD_FileExist(const char *name) { OFSTRUCT OfStruct; if ( OpenFile(name, &OfStruct, OF_EXIST) != HFILE_ERROR ) return name; return NULL; } /************************************************************************/ char *WCD_IsProg(const char *o,char *FullName,int mfn) /* Jos o on ohjelman nimi (mahd. .EXE, .COM yms. lisättynä, niin ** palautetaan TRUE ja täydennetään ohjelman polku kokonaisuudessaan ** muuttujaan FullName */ { char extensions[80]=""; char ohjelma[80]=""; char *ext; const char *loput, *path; char *pext; int is_path,is_ext=0; if ( *o == '\"' ) { kopioi_jono(FullName,mfn,o); return FullName; } kopioi_jono(N_S(ohjelma),o); wcd_FirstName(ohjelma); loput = strchr(o,' '); path = wcd_Path(ohjelma); is_path = (path[0]!=0); GetProfileString("Windows","Programs","exe com bat pif",N_S(extensions)); pext = WCD_Extension(ohjelma); if ( *pext ) is_ext = 1; else { liita_jono(N_S(ohjelma),"."); pext++; } for ( ext = strtok(extensions," "); ext; ext = strtok(NULL," ") ) { if ( is_ext && strcmpi(WCD_Extension(ohjelma),ext) != 0 ) continue; if ( is_ext == 0 ) { *pext = 0; liita_jono(N_S(ohjelma),ext); } if ( is_path ) path = WCD_FileExist(ohjelma); else path = searchpath(ohjelma); if ( path ) { kopioi_jono(FullName,mfn,path); if ( loput ) liita_jono(FullName,mfn,loput); return FullName; } } return NULL; } /************************************************************************/ int WCD_CopyFile(char *source,char *dest,int dont_dup) { #define BUFFSIZE 4096 OFSTRUCT sOfStruct,dOfStruct; HFILE hSource,hDest; #ifndef __WIN32__ PBYTE pbBuf; #else char *pbBuf; #endif UINT cbRead; int error = 0; if ( dont_dup && OpenFile(dest, &dOfStruct, OF_EXIST) != HFILE_ERROR ) return 0; hSource = OpenFile(source,&sOfStruct,OF_READ); if ( hSource == HFILE_ERROR ) return -1; hDest = OpenFile(dest,&dOfStruct,OF_CREATE); if ( hDest == HFILE_ERROR ) { _lclose(hSource); return -2; } #ifndef __WIN32__ if ( ( pbBuf = (PBYTE) LocalAlloc(LMEM_FIXED, BUFFSIZE) ) != NULL ) #else if ( ( pbBuf = LocalAlloc(LMEM_FIXED, BUFFSIZE) ) != NULL ) #endif do { cbRead = _lread(hSource, pbBuf, BUFFSIZE); if ( cbRead != _lwrite(hDest, pbBuf, cbRead) ) error = -3; } while ( cbRead != 0 && !error ); LocalFree((HLOCAL) pbBuf); _lclose(hSource); _lclose(hDest); return error; } #ifdef PATH /************************************************************************/ static LPSTR wcd_StrAdd(LPSTR str,int strsize,int *si,const char *s) { while (*s && (*si 0 && strchr("\\:",p[i-1]) == NULL ) liita_jono(s,ms,"\\"); liita_jono(s,ms,n); return s; } /****************************************************************************/ static char *wcd_ReplaceChars(char *d,int ds,const char *s, const char *f,const char *rep) /* Korvataan kaikki jonot f jonoilla rep. Jos rep loppuu \ ** ja jonosta s löytyisi seuraavana \ ei tätä laiteta. */ { char *p; int fl = strlen(f); int rll = ( rep[strlen(rep)-1]=='\\' ); d[0] = 0; for (; ( p=strstr(s,f) ) != NULL;) { *p=0; liita_jono(d,ds,s); liita_jono(d,ds,rep); s = p+fl; if ( *s == '\\' && rll ) s++; } liita_jono(d,ds,s); return d; } static char progdir[80]; /****************************************************************************/ static const char *wcd_SetProgDir(const char *pname) { kopioi_jono(N_S(progdir),pname); if ( progdir[1]==':' && !progdir[2] ) { progdir[2]='\\'; progdir[3]=0; } return progdir; } /****************************************************************************/ static const char *wcd_GetProgDir(void) { return progdir; } /****************************************************************************/ char *wcd_DoReplace(char *d,int ds,const char *s) /* Korvataan s:än kaikki korvattavaksi tarkoitetut jonot ja tulos d:hen ** s saa olla myös d! */ { static char s1[500],s2[500]; wcd_GetCurdirfile(); if ( s[0] == '.' && s[1] == 0 ) { kopioi_jono(d,ds,WCD_GetCurrent()); return d; } kopioi_jono(N_S(s1),s); wcd_ReplaceChars(N_S(s2),s1,":CUR:",WCD_GetCurrent()); wcd_ReplaceChars(N_S(s1),s2,":WINCD:",WCD_GetWincdDir()); wcd_ReplaceChars(N_S(s2),s1,":WIN:",wcd_GetWindowsDir()); return wcd_ReplaceChars(d,ds,s2,":PROG:",wcd_GetProgDir()); } /****************************************************************************/ static int wcd_CheckName(char *wincdname,int mw,const char *pname, const char *sname) /* Tarkistetaan onko tiedostoa pname\sname.WCD */ /* Palautetaan täydennetty nimi, jos oli */ { OFSTRUCT OpenBuff; kopioi_jono(wincdname,mw,pname); if ( wincdname[0] && wincdname[strlen(wincdname)-1]!='\\' ) liita_jono(wincdname,mw,"\\"); liita_jono(wincdname,mw,sname); liita_jono(wincdname,mw,".WCD"); return ( OpenFile(wincdname,&OpenBuff,OF_EXIST) == HFILE_ERROR ); } /****************************************************************************/ int WCD_FindINIname(char *wincdname,int mw,const char *pname,const char *sname) /* Katsotaan löytyykö tiedostoa sname.WCD hakemistoista: ** 1. WinCD:n nykyhakemisto ** 2. pname -hakemistosta ** 3. WinCD-hakemistosta ** 4. ilman hakemiston nimiä */ { if ( !wcd_CheckName(wincdname,mw,WCD_GetCurrent(),sname) ) return 1; if ( !wcd_CheckName(wincdname,mw,pname,sname) ) return 1; if ( !wcd_CheckName(wincdname,mw,WCD_GetWincdDir(),sname) ) return 1; if ( !wcd_CheckName(wincdname,mw,"",sname) ) return 1; return 0; } /****************************************************************************/ static char rundir[80] = ""; /****************************************************************************/ static char *wcd_GetRunDir(void) { return rundir; } /****************************************************************************/ static char *wcd_SetRunDir(const char *wincdname) { char s[80]; rundir[0] = 0; if ( GetPrivateProfileString("RUNDIR","rundir","",s,sizeof(s),wincdname) ) { wcd_DoReplace(N_S(rundir),s); } return rundir; } /************************************************************************/ static int wcd_DoCommands(char *pathname) /* Toteutetaan WCD-makro ohjelma.WCD ** Tunnettuja komentoja: ** [COPY] tiedoston kopiointi ** Jos kopioitavan polku on sanottu, kopioidaan sieltä, muuten kopioidaan ** polun ilmoittamasta paikasta. Jos kohdetta ei ole sanottu, kopioidaan ** oletushakemistoon samannimiseksi tiedostoksi. ** [INSERT] tiedoston lisäys ** Kuten [COPY] muttei tehdä jos kohdeniminen tiedosto on jo olemassa ** [PROFILE?] Profile-tiedostojen muuttaminen ** [ARGS] ** komentorivin loppuargumentit jollei assoc.run käynnistys (eli on ** normaali käynnistys) ** [ARGSA] ** komentorivin loppuargumentit jos assoc.run käynnitys (eli käynnistys ** dokumentin nimellä (esim. koe.pas) ** [RUNDIR] ** hakemisto, jossa ohjelma käynnistetään ** :CUR: tekstirivillä tarkoittaa WinCD:n määräämää oletushakemistoa ** :PROG: tekstirivillä tarkoittaa ohjelelman hakemistoa. ** :WINCD: WinCD-hakemisto ** :WIN: Windows-hakemisto ** ** ** Tiedoston muoto: ** [INSERT] - lisättävät tiedostot ** 1 = c:\config.sys a.a - kopioidaan a.a:ksi oletushakemistoon ** 2 = setup.dat - kopioidaan setup.dat:ksi ** [COPY] - aina kopioitavat tiedostot ** 1 = myset.dat ** [PROFILE1] ** file = WORKSHOP.INI ** section = "Resource Workshop" ** str1 = LastDir ** to1 = . ** str2 = UndoLevels ** to2 = 10 ** [ARGS] - argumentit kun ei assosioinnilla käyn ** arg1 = :CUR:\*.rc ** [ARGSA] - argumentit kun käyn. assosioinnilla ** arg1 = /s /d ** [RUNDIR] ** rundir = :PROG: */ { static char wincdname[120]; static char pname[120],*p; static char sname[120],dname[120]; static char profstr[20]; static char profto[20]; static char s[128],/* s1[128] ,*/s2[128]; static char *secstr[2] = {"COPY","INSERT"}; static char secst[30]; static int secmode[2] = { 0 , 1 }; int sec,i,l; // getcwd(current,sizeof(current)); // if ( current[1]==':' && !current[2] ) { current[2]='\\'; current[3]=0; } kopioi_jono(N_S(pname),wcd_Path(pathname)); wcd_SetProgDir(pname); l =strlen(pname); // if ( !l ) return 0; /* Ei tarvitse kopioida itselleen! */ p = pname + l-1; if ( *p != ':' ) liita_jono(N_S(pname),"\\"); kopioi_jono(N_S(sname),wcd_Name(pathname)); for (i=strlen(sname)-1;i>=0;i--) /* Poistetaan tarkennin */ if ( sname[i]=='.' ) { sname[i]=0; break; } // if ( FindINIname(wincdname,pname,sname) ) return 0; WCD_FindINIname(N_S(wincdname),pname,sname); /* [COPY] ja [INSERT] */ for (sec=0; sec<2; sec++) { for (i=1; ; i++) { sprintf(profstr,"%d",i); if ( !GetPrivateProfileString(secstr[sec],profstr,"",s,sizeof(s),wincdname) ) break; wcd_DoReplace(N_S(s),s); if ( (p = strtok(s," ")) == NULL ) continue; wcd_MakeName(N_S(sname),p,pname); if ( (p = strtok(NULL," ")) == NULL ) kopioi_jono(N_S(dname),wcd_Name(sname)); else kopioi_jono(N_S(dname),p); wcd_MakeName(N_S(s),dname,WCD_GetCurrent()); WCD_CopyFile(sname,s,secmode[sec]); } } /* [PROFILE?] */ for (sec=1;;sec++) { sprintf(secst,"PROFILE%d",sec); if ( !GetPrivateProfileString(secst,"file","",sname,sizeof(sname),wincdname) ) break; wcd_DoReplace(N_S(sname),sname); if ( !GetPrivateProfileString(secst,"section","",dname,sizeof(dname),wincdname) ) break; wcd_DoReplace(N_S(dname),dname); for (i=1;;i++) { sprintf(profstr,"str%d",i); sprintf(profto,"to%d",i); if ( !GetPrivateProfileString(secst,profstr,"",s,sizeof(s),wincdname) ) break; wcd_DoReplace(N_S(s),s); GetPrivateProfileString(secst,profto,"",s2,sizeof(s2),wincdname); WritePrivateProfileString(dname,s,wcd_DoReplace(N_S(s2),s2),sname); } WritePrivateProfileString(NULL,NULL,NULL,sname); /* Flush cache!!! */ } /* [ARGS] */ for (sec=0;sec<2;sec++) { ArgP[sec][0]=0; for (i=1;;i++) { sprintf(profstr,"arg%d",i); if ( !GetPrivateProfileString(ArgN[sec],profstr,"",s,sizeof(s),wincdname) ) break; liita_jono(ArgP[sec],ArgS," "); liita_jono(ArgP[sec],ArgS,wcd_DoReplace(N_S(s),s)); } } /* [RUNDIR] */ wcd_SetRunDir(wincdname); return 0; } /************************************************************************/ static struct { UINT nr; char *text; } Errors[] = { { 0 , "System was out of memory, executable file was corrupt,\n" " or relocations were invalid."}, { 2 , "File was not found."}, { 3 , "Path was not found."}, { 5 , "Attempt was made to dynamically link to a task,\n" "or there was a sharing or network-protection error."}, { 6 , "Library required separate data segments for each task."}, { 8 , "There was insufficient memory to start the application."}, {10 , "Windows version was incorrect."}, {11 , "Executable file was invalid.\n" "Either it was not a Windows application or\n" "there was an error in the .EXE image."}, {12 , "Application was designed for a different operating system."}, {13 , "Application was designed for MS-DOS 4.0."}, {14 , "Type of executable file was unknown."}, {15 , "Attempt was made to load a real-mode application \n" "(developed for an earlier version of Windows)."}, {16 , "Attempt was made to load a second instance\n" "of an executable file containing multiple data\n" "segments that were not marked read-only."}, {19 , "Attempt was made to load a compressed executable file.\n" "The file must be decompressed before it can be loaded."}, {20 , "Dynamic-link library (DLL) file was invalid. \n" "One of the DLLs required to run this application was corrupt."}, {21 , "Application requires 32-bit extensions."}, {-1 , ""} }; /************************************************************************/ char *WCD_ErrorText(UINT nr) { int i; if ( nr <= 21 ) for (i=0; Errors[i].nr != (UINT)-1; i++) if ( Errors[i].nr == nr ) return Errors[i].text; return "?"; } /************************************************************************/ static char *wcd_GetTimeStr(void) { static char timestr[80]; struct tm *time_now; time_t secs_now; time(&secs_now); time_now = localtime(&secs_now); strftime(timestr, 80, "%Y-%m-%d %H:%M:%S", time_now); return timestr; } /************************************************************************/ static char *wcd_Head(const char *s) { static char HeadText[100]; char *p; kopioi_jono(N_S(HeadText),s); p = strchr(HeadText,'\n'); if ( p ) *p = 0; return HeadText; } /************************************************************************/ int WCD_DoLogFile(char *app,int error) { FILE *f; char LogFile[200]; if ( !GetPrivateProfileString(MAINITEM,"LogFile","",LogFile,sizeof(LogFile), WINCDINI) ) return 1; if ( ( f = fopen(LogFile,"a+") ) == NULL ) return 1; fprintf(f,wcd_GetTimeStr()); fprintf(f," %s",app); if ( error < 32 ) fprintf(f," Error: %d: %s", error,wcd_Head(WCD_ErrorText(error))); fprintf(f,"\n"); fclose(f); return 0; } /****************************************************************************/ int WCD_Error(UINT Error,const char *app) { sprintf(str,T("Virhe %d: \n%s\nOhjelma:\n %s"), Error,WCD_ErrorText(Error),app); WCD_MessageBox(GetFocus(),str,"Error",MB_OK|MB_ICONINFORMATION); return 1; } //#define LOAD //#define PATH /****************************************************************************/ #define ENVSIZE 4000 int WCD_Run(LPSTR lapp,int asso) { UINT Error; int RetVal = 0; static char app[255]; SetCursor(LoadCursor(NULL,IDC_WAIT)); kopioi_jono(N_S(app),lapp); // lstrcpyn(app,lapp,sizeof(app)); app[sizeof(app)-1]=0; { #ifdef LOAD typedef struct _LOADPARMS { WORD segEnv; /* child environment */ LPSTR lpszCmdLine; /* child command tail */ UINT FAR* lpShow; /* how to show child */ UINT FAR* lpReserved; /* must be NULL */ } LOADPARMS; static char appname[200]; UINT lpShow[2] = {2,SW_SHOWNORMAL}; int i; #ifdef PATH HGLOBAL henv = GlobalAlloc(GMEM_FIXED,ENVSIZE); LPSTR env = GlobalLock(henv); #endif LOADPARMS lparams = {0,"",NULL,NULL}; /* wsprintf(env,"WHAT= WINCD:%d%c%c",random(300),0,0); */ #ifdef PATH lparams.segEnv = henv; #else lparams.segEnv = 0; #endif lparams.lpShow = lpShow; for (i = 0; app[i] && app[i]!=' '; i++); lparams.lpszCmdLine = &app[i]; strncpy(appname,app,i+1); appname[i]=0; #ifdef PATH MakeEnvCopyPlusPath(env,ENVSIZE,appname); GlobalUnlock(henv); #endif DoCommands(app); Error = LoadModule(appname,&lparams); if ( Error == 11 ) Error = WinExec(app,SW_SHOWNORMAL); if ( Error < 32 ) RetVal = WincdError(Error,appname); #ifdef PATH // GlobalFree(henv); #endif /* FreeModule(Error); */ #endif #ifndef LOAD wcd_DoCommands(app); if (asso) liita_jono(N_S(app),ArgStrA); else liita_jono(N_S(app),ArgStr); WCD_ChDir(wcd_GetRunDir()); Error = WinExec(app,SW_SHOWNORMAL); WCD_ChDir(WCD_GetCurrent()); if ( Error < 32 ) RetVal = WCD_Error(Error,app); WCD_DoLogFile(app,Error); #endif #if 0 sprintf(str,"Kahva: %d\nOhjelma:\n %s",Error,app); CMessageBox(GetFocus(),str,"WinCD",MB_OK|MB_ICONINFORMATION); #endif } return RetVal; } int GetRegAss(const char *ext, char *as, int mas) { char pext[100] = "."; long err; DWORD typ = 0; DWORD siz = mas; HKEY hkey; LIITA(pext,ext); // LIITA(pext,"\\"); err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Extensions", 0, KEY_QUERY_VALUE, &hkey ); if ( err != ERROR_SUCCESS ) return 1; err = RegQueryValueEx( hkey, pext, NULL, &typ, (LPBYTE)as, &siz ); return err; } /************************************************************************/ int WCD_AssocRun(const char *o) { char as[80],*s,*ss,app[200],ext[10]; const char *os,*path; int i,loytyi,lastbackslash=0; i = strlen(current); if ( i > 0 ) lastbackslash = (current[i-1] == '\\'); os = WCD_Extension(o); for (i=0; i