#define UTILDEBUG 0 #ifdef DARWIN # define creat64 creat # define open64 open # define lseek64 lseek # define pread64 pread # define pwrite64 pwrite #endif #if defined(LINUX) || defined(DARWIN) # define PRINTAPP "lp" #endif #ifdef WINDOWS # include # include # define PRINTAPP "print" # define popen _popen # define pclose _pclose #else # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "convertlib.h" #include "hd24utils.h" #include "memutils.h" #define _LARGE_FILES #define LARGE_FILES #define LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 #define FILE_OFFSET_BITS 64 #define SECTORSIZE 512 #define FSINFO_VERSION_MAJOR 0x8 #define FSINFO_VERSION_MINOR 0x9 #define FSINFO_BLOCKSIZE_IN_SECTORS 0x10 #define FSINFO_AUDIOBLOCKS_PER_CLUSTER 0x14 #define FSINFO_STARTSECTOR_FAT 0x38 #define FSINFO_NUMSECTORS_FAT 0x3c #define FSINFO_CLUSTERS_ON_DISK 0x44 #define FSINFO_MAXPROJECTS 0x50 #define FSINFO_MAXSONGSPERPROJECT 0x54 #define FSINFO_DATAAREA 0x7c #define DRIVEINFO_VOLUME 0x1b8 #define DRIVEINFO_PROJECTCOUNT 0x0c #define DRIVEINFO_LASTPROJ 0x10 #define DRIVEINFO_PROJECTLIST 0x20 void hd24utils::gencatalog_showsongs(hd24project* currentproj,string* strcatalog) { if (currentproj==NULL) { return; } if (strcatalog==NULL) { return; } int numsongs=currentproj->songcount(); *strcatalog+=" ======================================================================\n"; if (numsongs==0) { *strcatalog+=" There are no songs in this project.\n"; return; } hd24song* currsong=NULL; for (int i=1; i<=numsongs; i++) { currsong=currentproj->getsong(i); if (currsong==NULL) continue; *strcatalog+=" "; *strcatalog+=" "; if (i<10) { *strcatalog+=" "; } string* songnum=Convert::int2str(i); *strcatalog+=*songnum; *strcatalog+=": "; delete songnum; string* currsname=currsong->songname(); string* pad=Convert::padright(*currsname,35," "); delete(currsname); *strcatalog+=*pad; delete pad; string* dur=currsong->display_duration(); *strcatalog+=*dur; delete dur; *strcatalog+= ", " ; string* chans=Convert::int2str(currsong->logical_channels()); string* chans2=Convert::padleft(*chans,2," "); *strcatalog+=*chans; delete chans; delete chans2; *strcatalog+="ch. "; string* samrate=Convert::int2str(currsong->samplerate()); *strcatalog+=*samrate; delete samrate; *strcatalog+=" Hz"; if (currsong->iswriteprotected()) { *strcatalog+="*"; } *strcatalog+="\n"; delete currsong; currsong=NULL; } return; } void hd24utils::gencatalog_showprojects(hd24fs* currenthd24,string* strcatalog) { int numprojs=currenthd24->projectcount(); hd24project* currproj=NULL; for (int i=1; i<=numprojs; i++) { currproj=currenthd24->getproject(i); *strcatalog+=" ======================================================================\n"; *strcatalog+=" Project "; string* projnum=Convert::int2str(i); *strcatalog+=*projnum; delete projnum; *strcatalog+=": "; string* currpname=currproj->projectname(); *strcatalog+= *currpname; delete(currpname); *strcatalog+="\n"; // << endl; gencatalog_showsongs (currproj,strcatalog); //to_out); delete(currproj); } } int hd24utils::gencatalog(hd24fs* currenthd24,string* strcatalog) { time_t currenttime; struct tm timestamp; char timebuf[80]; time(¤ttime); timestamp = *localtime(¤ttime); strftime(timebuf,sizeof(timebuf),"%a %Y-%m-%d %H:%M:%S %Z", ×tamp); *strcatalog+= " Catalog timestamp : "; *strcatalog+= timebuf ; *strcatalog+="\n"; *strcatalog+=" Volume name : "; string* volname=currenthd24->volumename(); *strcatalog+=*volname; delete volname; *strcatalog+="\n"; *strcatalog+=" Number of projects : "; string* pcount=Convert::int2str(currenthd24->projectcount()); *strcatalog+=*pcount; delete pcount; *strcatalog+="\n"; gencatalog_showprojects(currenthd24,strcatalog); return 0; } string* hd24utils::savecatalog(hd24fs* currenthd24,string* filename) { string* error=new string(""); // gencatalog string* catalog=new string(""); if (hd24utils::gencatalog(currenthd24,catalog)!=0) { *error+="Error generating catalog."; return error; } fstream to_out(filename->c_str(),ios::out); if (to_out==NULL) { *error+="Cannot write catalog."; return error; } to_out << *catalog ; to_out.flush(); to_out.close(); return NULL; } string* hd24utils::printcatalog(hd24fs* currenthd24) { string* error=new string(""); string catname="_hd24cat.txt"; // gencatalog string* catalog=new string(""); if (hd24utils::gencatalog(currenthd24,catalog)!=0) { *error+="Error generating catalog."; return error; } fstream to_out(catname.c_str(),ios::out); if (to_out==NULL) { *error+="Cannot write catalog."; return error; } *catalog += "\f\n"; // form feed to_out << *catalog ; to_out.flush(); to_out.close(); #ifdef WINDOWS SHELLEXECUTEINFO ShExecInfo = {0}; ShExecInfo.cbSize = sizeof (SHELLEXECUTEINFO); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; //SEE_MASK_INVOKEIDLIST; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb="print"; ShExecInfo.lpFile=catname.c_str(); ShExecInfo.lpParameters = ""; ShExecInfo.lpDirectory=NULL; ShExecInfo.nShow = SW_HIDE; ShExecInfo.hInstApp = NULL; ShellExecuteEx(&ShExecInfo); WaitForSingleObject(ShExecInfo.hProcess,INFINITE); unlink (catname.c_str()); #else char s[1024]; string* catcmd = new string (PRINTAPP); *catcmd += " "; *catcmd += catname; *catcmd += " 2>&1"; FILE *fp = popen(catcmd->c_str() , "r"); while (fgets(s, sizeof(s)-1, fp)) { *error += s; } pclose(fp); unlink (catname.c_str()); #endif return error; } void hd24utils::interlacetobuffer(unsigned char* sourcebuf,unsigned char* targetbuf, __uint32 totbytes,__uint32 bytespersam,__uint32 trackwithingroup,__uint32 trackspergroup) { __uint32 samplenum; __uint32 totsams=totbytes/bytespersam; __uint32 trackoff=(trackwithingroup*bytespersam); __uint32 q=0; // unroll loop for bytespersam=1,2,3 switch (bytespersam) { case 3: for (samplenum=0;samplenumc_str(),O_WRONLY); #endif #ifdef WINDOWS FSHANDLE handle=CreateFile(outputfilename->c_str(),GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (hd24fs::isinvalidhandle(handle)) { handle=CreateFile(outputfilename->c_str(),GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); } #endif if (hd24fs::isinvalidhandle(handle)) { // cout << "Cannot open file "<=MULTISECTOR) { numsectors=MULTISECTOR; } if (currenthd24!=NULL) { currenthd24->readsector_noheader(currenthd24,i,bootblock); // raw reading } #if defined(LINUX) || defined(DARWIN) __uint64 targetoff=i; targetoff-=firstsector; targetoff*=512; ssize_t byteswritten=0; if (currenthd24!=NULL) { byteswritten=pwrite64(handle,bootblock,512,targetoff); } else { byteswritten=pwrite64(handle,bootblock,512*numsectors,targetoff); i+=(numsectors-1); } #endif #ifdef WINDOWS //DWORD dummy; //long bytes=0; __uint64 targetoff=i; targetoff-=firstsector; __uint64 byteswritten=0; if (currenthd24!=NULL) { byteswritten=currenthd24->writesectors(handle,targetoff,bootblock,1); } else { byteswritten=currenthd24->writesectors(handle,targetoff,bootblock,numsectors); i+=(numsectors-1); } #endif if (byteswritten==0) { #if defined(LINUX) || defined(DARWIN) close (handle); #endif #ifdef WINDOWS CloseHandle(handle); #endif return 1; } if (message!=NULL) { if (q%1000==0) { sprintf(message,"Saving sector %ld of %ld",i,(endsector+1)); // cout << i << endl; Fl::wait(0); } } } #if defined(LINUX) || defined(DARWIN) close (handle); chmod(outputfilename->c_str(),0664); #endif #ifdef WINDOWS CloseHandle(handle); #endif return 0; } int hd24utils::savedriveimage(hd24fs* currenthd24,string* imagefilename,char* message,int* cancel) { unsigned long firstsector=0; unsigned long endsector=currenthd24->getlastsectornum(); return savedrivesectors(currenthd24,imagefilename,firstsector,endsector,message,cancel); } int hd24utils::newdriveimage(string* imagefilename,__uint32 endsector,char* message,int* cancel) { if (endsector<1353964) { // requested drive size is less than possible minimum size return -1; } unsigned long firstsector=0; #if (UTILDEBUG==1) cout << "about to save drive sectors" <write_enable(); #if (UTILDEBUG==1) cout << "quickformatting fs" <quickformat(message); #if (UTILDEBUG==1) cout << "format result=" << *message << endl; cout << "deleting format fs object" <find(pathsep->c_str()); if (idx==string::npos) { last=1; exepath=new string(strpath->c_str()); exename=new string(strpath->c_str()); *strpath=""; } else { exepath=new string(strpath->substr(0,idx)); exename=new string(strpath->substr(0,idx)); *strpath=strpath->substr(idx+1); } #if (UTILDEBUG==1) cout << "exepath= " << *exepath << endl; #endif if (exepath->substr(exepath->length()-1,1)!=PATHSLASH) { *exepath+=PATHSLASH; } if (exename->substr(exename->length()-1,1)!=PATHSLASH) { *exename+=PATHSLASH; } *exename+=rawname; #if (UTILDEBUG==1) cout << "test if file " << exename->c_str() << " exists" << endl; #endif if (hd24utils::fileExists(exename->c_str())) { strncpy(result,exepath->c_str(),2048); if (exename!=NULL) { delete exename; exename=NULL; } if (exepath!=NULL) { delete exepath; exepath=NULL; } if (strpath!=NULL) { delete strpath; strpath=NULL; } if (pathsep!=NULL) { delete pathsep; pathsep=NULL; } return ; } if (exename!=NULL) { delete exename; exename=NULL; } if (exepath!=NULL) { delete exepath; exepath=NULL; } } if (strpath!=NULL) { delete strpath; strpath=NULL; } if (pathsep!=NULL) { delete pathsep; pathsep=NULL; } result[0]=(char)0; return; } bool hd24utils::fileExists(const char* strFilename) { struct stat stFileInfo; int intStat; // Attempt to get the file attributes intStat = stat(strFilename,&stFileInfo); if(intStat == 0) { // We were able to get the file attributes // so the file obviously exists. return true; } // We were not able to get the file attributes. // This may mean that we don't have permission to // access the folder which contains this file. If you // need to do that level of checking, lookup the // return values of stat which will give you // more details on why stat failed. return false; } string* hd24utils::getlastdir(string which) { string* whichdir; char buffer[FL_PATH_MAX]; Fl_Preferences* userprefs=new Fl_Preferences(Fl_Preferences::USER, "HD24","HD24connect" ); /* Attempt to find last used project dir */ if (userprefs->entryExists(which.c_str())) { userprefs->get(which.c_str(),buffer,".",FL_PATH_MAX); whichdir=new string(buffer); } else { whichdir=new string("."); } delete userprefs; return whichdir; } void hd24utils::setlastdir(string which,const char* newdir) { Fl_Preferences* userprefs=new Fl_Preferences(Fl_Preferences::USER, "HD24","HD24connect" ); userprefs->set(which.c_str(),newdir); // cout << "just set " << which << " to " << newdir << endl; delete userprefs; }