/* * pmmp3dec.c (C) Chris Wohlgemuth 2002 * * This helper decodes an MP3 */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * If you need another license for your project/product (commercial, * noncommercial, whatever) contact me at * * http://www.os2world.com/cdwriting * http://www.geocities.com/SiliconValley/Sector/5785/ * */ #define INCL_DOS #define INCL_DOSFILEMGR #define INCL_DOSERRORS #define INCL_WIN #define INCL_OS2MM #define INCL_MMIOOS2 #define INCL_MCIOS2 #include #include #include #include #include #include #include #include "os2me.h" #include "common.h" #include "mmres.h" #include "mmprogs_defaults.h" #include "sys_funcs.h" #if 0 #define _PMPRINTF_ #include "U:/PMPRINTF/PMPRINTF.H" #endif #define MSG_CONVERTDONE 1L #define MSG_CONVERTPERCENT 2L #define MSG_CONVERTERROR 3L #define ID_TIMER 1 #define TIMER_DELAY 200 #define CONVERTBUFFERSIZE 500000 #define NUMPARAMS 3 /* argv[0]: progname * argv[1]: wavefile * argv[2]: IO proc name */ //#define DEBUG //#define INI_NAME_APP "audioconv" //#define INI_NAME_COLOR "color" void HlpSendCommandToObject(PSZ chrObject, PSZ command); BOOL percentRegisterBarClass(void); BOOL IniSaveWindowPos(PSZ iniFile, PSZ chrApp, PSZ chrKey, HWND hwnd); BOOL IniRestoreWindowPos(PSZ iniFile, PSZ chrApp, PSZ chrKey, HWND hwnd); BOOL IniSaveWindowClrs(PSZ chrIniFile, PSZ chrApp , HWND hwnd); BOOL IniRestoreWindowClrs(PSZ chrIniFile, PSZ chrApp , HWND hwnd); BOOL HlpBuildMMProgIniFileName(PSZ chrProgname, PSZ chrBuffer, ULONG ulBufferSize); HMODULE queryResModuleHandle(PSZ chrExePath); void freeResHandle(void); BOOL getMessage(PSZ text,ULONG ulID, LONG lSizeText, HMODULE hResource,HWND hwnd); ULONG messageBox( PSZ text, ULONG ulTextID , LONG lSizeText, PSZ title, ULONG ulTitleID, LONG lSizeTitle, HMODULE hResource, HWND hwnd, ULONG ulFlags); char logName[]="convert.log"; extern SWP swpWindow; BOOL bHaveWindowPos=FALSE; UCHAR chrTargetName[CCHMAXPATH]={0}; UCHAR chrSourceName[CCHMAXPATH]={0}; UCHAR chrProcName[CCHMAXPATH]={0}; UCHAR chrIniFile[CCHMAXPATH]; int numArgs; char* params[NUMPARAMS]; #define NUMIOPROCS 1000 int iIoProc; /* Position of IO-Proc in global data area of MMOS2. 0 based */ int iPrivIOProc[NUMIOPROCS]; /* Number of possible IO-Procs. I'm lazy here and use a static array. If there ever will be more than 1000 procs there'll be a problem... */ int iSampleRate; int iBitsPerSample; SHORT sChannels; ULONG lSec; ULONG lAudioSize; TID tidThread=0; BOOL bBreak=FALSE; PMMFORMATINFO pMemFormatInfo=NULLHANDLE; HMODULE RESSOURCEHANDLE=0; BOOL bNoProcGiven=FALSE; void pmUsage(void); BOOL createTargetName(PSZ sourceName, PSZ chrExt) { PCHAR textPtr=NULL; PCHAR Ptr=NULL; strcpy((PCHAR)chrTargetName, (PCHAR)sourceName); Ptr=strstr(strlwr(chrTargetName),strlwr(chrExt)); if((textPtr=strrchr((PCHAR)chrTargetName, '.'))!=NULL) *textPtr=0; else textPtr=(PCHAR)chrTargetName; if(Ptr) strcat(textPtr,"1"); strcat(textPtr,"."); strcat(textPtr, (PCHAR)chrExt); #if 0 WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, textPtr, "", 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); #endif return TRUE; } BOOL insertIOProcItems( HWND hwndDrop ) { // CHAR szBuffer[ sizeof( FOURCC ) + CCHMAXPATH + 4 ]; MMFORMATINFO mmFormatInfo; PMMFORMATINFO pmmFormatInfoArray; ULONG ulReturnCode; LONG lFormatsRead; LONG index; LONG lBytesRead; LONG lNumIOProcs; int sIdx; memset( &mmFormatInfo, '\0', sizeof(MMFORMATINFO) ); mmFormatInfo.ulMediaType |= MMIO_MEDIATYPE_AUDIO; mmFormatInfo.ulFlags|=MMIO_CANWRITETRANSLATED; ulReturnCode = mmioQueryFormatCount ( &mmFormatInfo, &lNumIOProcs, 0, 0 ); if( ulReturnCode != MMIO_SUCCESS ) { /* * Error - mmioQueryFormatCount failed. */ return FALSE; } /* * Allocate enough memory for n number of FormatInfo blocks */ pmmFormatInfoArray = (PMMFORMATINFO) malloc (lNumIOProcs * sizeof( MMFORMATINFO ) ); pMemFormatInfo=pmmFormatInfoArray; if( pmmFormatInfoArray == NULL ) { /* * Could not allocate enough memory for mmFormatInfo array. */ return FALSE; } /* * call mmioGetFormats to get info on the formats supported. */ ulReturnCode = mmioGetFormats( &mmFormatInfo, lNumIOProcs, pmmFormatInfoArray, &lFormatsRead, 0, 0 ); if( ulReturnCode != MMIO_SUCCESS ) { /* * mmioGetFormats failed. */ free(pmmFormatInfoArray); return FALSE; } if( lFormatsRead != lNumIOProcs ) { /* * Error in MMIO - number of formats read in by * mmioGetFormats is not equal to number of formats * found by mmioQueryFormatCount. */ free(pmmFormatInfoArray); return FALSE; } for ( index = 0, sIdx=0; index szDefaultFormatExt, szName); #endif if(pmmFormatInfoArray->ulFlags & MMIO_CANWRITETRANSLATED) { /* Insert into list box */ WinSendMsg(hwndDrop, LM_INSERTITEM,(MPARAM)LIT_END, (MPARAM)szName); iPrivIOProc[sIdx]=index; #ifdef DEBUG SysWriteToTrapLog("-- %d %d, sIdx: %d %s\n", index, iPrivIOProc[sIdx], sIdx, pmmFormatInfoArray->szDefaultFormatExt ); #endif /* Set text field */ if(bNoProcGiven) { WinSetWindowText(hwndDrop, szName); createTargetName(chrSourceName, (PSZ)pmmFormatInfoArray->szDefaultFormatExt); iIoProc=iPrivIOProc[sIdx]; bNoProcGiven=FALSE; } else { if(!stricmp((PCHAR)szName, (PCHAR)chrProcName)) { WinSetWindowText(hwndDrop, szName); /* Create target name */ createTargetName(chrSourceName, (PSZ)pmmFormatInfoArray->szDefaultFormatExt); iIoProc=iPrivIOProc[sIdx]; } sIdx++; } } /* * advance to next entry in mmFormatInfo array */ pmmFormatInfoArray++; } return TRUE; } BOOL queryAudioInfo(PSZ chrFile) { HMMIO hmmio; MMAUDIOHEADER mmAudioHeader; MMIOINFO mmioinfo; LONG lBytesRead=0; APIRET rc; memset(&mmioinfo,0, sizeof(mmioinfo)); mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER; mmioinfo.ulFlags=MMIO_READ|MMIO_DENYNONE; /* open source file */ if((hmmio=mmioOpen(chrFile, &mmioinfo,MMIO_READ))==NULLHANDLE) { return FALSE; } memset(&mmAudioHeader,0,sizeof(MMAUDIOHEADER)); rc = mmioGetHeader(hmmio, &mmAudioHeader,sizeof(MMAUDIOHEADER), &lBytesRead, 0, 0); if(rc!=MMIO_SUCCESS) { mmioClose(hmmio, 0); // fprintf(stderr,"mmioGetHeader error!\n"); return FALSE; } iSampleRate=mmAudioHeader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec; sChannels=mmAudioHeader.mmXWAVHeader.WAVEHeader.usChannels; iBitsPerSample=mmAudioHeader.mmXWAVHeader.WAVEHeader.usBitsPerSample; lSec=mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes/ mmAudioHeader.mmXWAVHeader.WAVEHeader.ulAvgBytesPerSec; lAudioSize=mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes; /* close source */ mmioClose(hmmio,0); return TRUE; } #if 0 BOOL createTargetName(char *sourceName) { char *textPtr; strcpy(chrTargetName, sourceName); if((textPtr=strrchr(chrTargetName, '.'))!=NULLHANDLE) *textPtr=0; else textPtr=chrTargetName; strcat(textPtr, ".wav"); return TRUE; } #endif void convertThreadFunc (void *arg) { HAB hab; HMQ hmq; HWND hwnd=(HWND)arg; hab=WinInitialize(0); if(hab) { hmq=WinCreateMsgQueue(hab,0); if(hmq) { HMMIO hmmio, hmmioTarget; MMIOINFO mmioinfo; MMAUDIOHEADER mmAudioHeader; LONG lBytesRead=0; LONG lBytesWritten=0; ULONG rc; PCHAR buffer=NULL; do { /*******************************/ /* Set up/open the SOURCE file */ /*******************************/ memset(&mmioinfo,0, sizeof(mmioinfo)); mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA; mmioinfo.ulFlags=MMIO_READ|MMIO_DENYNONE; if((hmmio=mmioOpen(chrSourceName, &mmioinfo,MMIO_READ))==NULLHANDLE) { UCHAR text[500]; sprintf((PCHAR)text,/* sizeof(text)-1,*/"mmioOpen error with file %s\n", chrSourceName); WinMessageBox(hwnd, hwnd, (PSZ)"", text, 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); break; } memset(&mmAudioHeader,0,sizeof(MMAUDIOHEADER)); rc = mmioGetHeader(hmmio, &mmAudioHeader,sizeof(MMAUDIOHEADER), &lBytesRead, 0, 0); if(rc!=MMIO_SUCCESS) { UCHAR text[500]; mmioClose(hmmio, 0); sprintf((PCHAR)text, /*sizeof(text)-1,*/"mmioGetHeader error!"); WinMessageBox(hwnd, hwnd, (PSZ)"", text, 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); break; } /*******************************/ /* Set up/open the TARGET file */ /*******************************/ memset(&mmioinfo,0, sizeof(mmioinfo)); mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA; mmioinfo.ulFlags=MMIO_WRITE|MMIO_CREATE; // mmioinfo.fccIOProc=mmioStringToFOURCC("WAVE", MMIO_TOUPPER); mmioinfo.fccIOProc=pMemFormatInfo[iIoProc].fccIOProc; if((hmmioTarget=mmioOpen(chrTargetName, &mmioinfo, MMIO_WRITE|MMIO_CREATE))==NULLHANDLE) { UCHAR chrError[64]; UCHAR text[CCHMAXPATH*2]; rc=mmioGetLastError(hmmioTarget); mciGetErrorString(mmioinfo.ulErrorRet ,chrError, sizeof(chrError)-1); sprintf((PCHAR)text, /*sizeof(text)-1,*/"mmioOpen error with file %s:\n%s\n%lu", chrTargetName, chrError,mmioinfo.ulErrorRet); mmioClose(hmmio,0); WinMessageBox(hwnd, hwnd, (PSZ)"", text, 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); break; } /* Set parameters */ rc = mmioSetHeader(hmmioTarget, &mmAudioHeader,sizeof(MMAUDIOHEADER), &lBytesWritten, 0, 0); /* Get buffer */ if((buffer=(PCHAR)malloc(CONVERTBUFFERSIZE))==NULLHANDLE) { UCHAR text[500]; mmioClose(hmmio, 0); mmioClose(hmmioTarget,0); sprintf((PCHAR)text, /*sizeof(text)-1,*/"Can't get memory buffer!"); WinMessageBox(hwnd, hwnd, (PSZ)"", text, 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); break; } /* convert */ lBytesWritten=0; do{ rc=mmioRead(hmmio, buffer, CONVERTBUFFERSIZE); if(bBreak) break; if(rc!=0 && rc!=MMIO_ERROR ) { mmioWrite(hmmioTarget, buffer, rc); lBytesWritten+=rc; WinSendMsg(hwnd, WM_APPTERMINATENOTIFY, MPFROMLONG(MSG_CONVERTPERCENT), MPFROMLONG((lBytesWritten)/(lAudioSize/100))); } }while(rc!=0 && rc!=MMIO_ERROR && !bBreak/*&& lBytesWritten <1000000*/); if(rc==MMIO_ERROR) { UCHAR text[500]; sprintf((PCHAR)text, /*sizeof(text)-1,*/"Error while reading audio data!"); WinMessageBox(hwnd, hwnd, (PSZ)"", text, 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); } if(!bBreak) { UCHAR chrCommand[CCHMAXPATH*2]; WinSendMsg(hwnd, WM_APPTERMINATENOTIFY, MPFROMLONG(MSG_CONVERTPERCENT), MPFROMLONG(100)); /* Refresh details view */ HlpSendCommandToObject(chrTargetName, (PSZ)"CWAUDIOREFRESH=1"); sprintf((PCHAR)chrCommand,"CWAUDIOCOPYTAGTO=%s;", chrTargetName); HlpSendCommandToObject(chrSourceName, chrCommand); } free(buffer); /* close source */ mmioClose(hmmio,0); /* close target */ mmioClose(hmmioTarget,0); break; } while(TRUE); WinSendMsg(hwnd, WM_APPTERMINATENOTIFY, MPFROMLONG(MSG_CONVERTDONE), 0); WinDestroyMsgQueue(hmq); } WinTerminate(hab); } tidThread=0; bBreak=FALSE; } void convertAudioFile(HWND hwnd) { tidThread=_beginthread(convertThreadFunc,NULL, 8192*16, (void*)hwnd); //Fehlerbehandlung fehlt if(tidThread==-1) { DosBeep(100, 500); tidThread=0; } } /* This Proc handles the on-the-fly data CD writing */ MRESULT EXPENTRY decodeStatusDialogProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { UCHAR text[CCHMAXPATH*4 +10]; UCHAR title[CCHMAXPATH*4]; SWCNTRL swctl; PID pid; int iPercent; switch (msg) { case WM_INITDLG: /* Add switch entry */ memset(&swctl,0,sizeof(swctl)); WinQueryWindowProcess(hwnd,&pid,NULL); swctl.hwnd=hwnd; swctl.uchVisibility=SWL_VISIBLE; swctl.idProcess=pid; swctl.bProgType=PROG_DEFAULT; swctl.fbJump=SWL_JUMPABLE; WinAddSwitchEntry(&swctl); #if 0 sprintf(text,"1: %s, 2: %s, 3: %s 4: %s 5: %s 6: %s",params[1],params[2],params[3], params[4], params[4],params[4]); WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, text, params[4], 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); #endif WinSendMsg(WinWindowFromID(hwnd,IDST_CONVERTNAME),EM_SETTEXTLIMIT,MPFROMSHORT((SHORT)CCHMAXPATH),0); WinSetWindowText(WinWindowFromID(hwnd,IDST_CONVERTCDBITS), (PSZ)""); /* Filename */ WinSetWindowText(WinWindowFromID(hwnd,IDST_CONVERTNAME), chrSourceName); /* Set dialog font to WarpSans for Warp 4 and above */ if(SysQueryOSRelease()>=40) { WinSetPresParam(hwnd, PP_FONTNAMESIZE,(ULONG)sizeof(DEFAULT_DIALOG_FONT), DEFAULT_DIALOG_FONT ); } /* Set percent bars to 0. */ WinSetWindowText(WinWindowFromID(hwnd,IDBAR_CONVERTPROGRESS),(PSZ)"0#0%"); WinSendMsg(WinWindowFromID(hwnd,IDEF_CONVERTTARGETNAME), EM_SETTEXTLIMIT,MPFROMSHORT((SHORT)CCHMAXPATH),0); insertIOProcItems( WinWindowFromID(hwnd, IDDD_IOPROC) ); WinSetWindowText( WinWindowFromID(hwnd,IDEF_CONVERTTARGETNAME), chrTargetName ); WinEnableWindow( WinWindowFromID(hwnd,IDPB_CONVERTABORT), FALSE); /* Channels */ getMessage(title, IDSTR_CONVERTCHANNELS, sizeof(title), RESSOURCEHANDLE, hwnd); sprintf((PCHAR)text, (PCHAR)title, sChannels); WinSetWindowText(WinWindowFromID(hwnd,IDST_CONVERTCHANNELS),text); /* Samplerate */ getMessage(title, IDSTR_CONVERTSAMPLERATE, sizeof(title), RESSOURCEHANDLE, hwnd); sprintf((PCHAR)text, (PCHAR)title, iSampleRate); WinSetWindowText(WinWindowFromID(hwnd,IDST_CONVERTSAMPLERATE),text); /* Playtime */ getMessage(title, IDSTR_CONVERTPLAYTIME, sizeof(title), RESSOURCEHANDLE, hwnd); sprintf((PCHAR)text, (PCHAR)title, lSec/60, lSec%60); WinSetWindowText(WinWindowFromID(hwnd,IDST_CONVERTPLAYTIME),text); IniRestoreWindowPos(chrIniFile, INI_AUDIOCONV_APP, INI_WINDOWPOS_KEY, hwnd); IniRestoreWindowClrs(chrIniFile, INI_AUDIOCONV_APP , hwnd); WinSetFocus(HWND_DESKTOP, hwnd); return (MRESULT) TRUE; /* WM_APPTERMINATENOTIFY messages are sent from the helper programs e.g. format checker. */ case WM_APPTERMINATENOTIFY: switch(LONGFROMMP(mp1)) { case MSG_CONVERTERROR: case MSG_CONVERTDONE: WinEnableWindow( WinWindowFromID(hwnd,IDPB_CONVERTOK), TRUE); WinEnableWindow( WinWindowFromID(hwnd,IDPB_CONVERTABORT), FALSE); break; case MSG_CONVERTPERCENT: iPercent=LONGFROMMP(mp2); if(iPercent>100) iPercent=100; if(iPercent<0) iPercent=0; /* Update track percent bar value. The helper prog sends us the actual decoded %. */ sprintf(text,"%d#%d%%", iPercent, iPercent); WinSetWindowText(WinWindowFromID(hwnd,IDBAR_CONVERTPROGRESS), text); break; default: break; } return FALSE; case WM_CLOSE: if(tidThread) { bBreak=TRUE; if(!WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER, TIMER_DELAY)) { /* Save window position */ IniSaveWindowPos(chrIniFile, INI_AUDIOCONV_APP, INI_WINDOWPOS_KEY, hwnd); IniSaveWindowClrs(chrIniFile, INI_AUDIOCONV_APP , hwnd); WinDismissDlg(hwnd,0); } else return FALSE; } /* Save window position */ IniSaveWindowPos(chrIniFile, INI_AUDIOCONV_APP, INI_WINDOWPOS_KEY, hwnd); IniSaveWindowClrs(chrIniFile, INI_AUDIOCONV_APP , hwnd); WinDismissDlg(hwnd,0); return FALSE; case WM_CONTROL: if(SHORT1FROMMP(mp1)==IDDD_IOPROC) { if(SHORT2FROMMP(mp1)==EN_CHANGE) { SHORT sIdx; sIdx=SHORT1FROMMR(WinSendMsg(HWNDFROMMP(mp2),LM_QUERYSELECTION, MPFROMLONG(LIT_FIRST),0)); iIoProc=iPrivIOProc[sIdx]; #ifdef DEBUG SysWriteToTrapLog("sIdx: %d IO-Proc Idx: %d %s\n", sIdx, iPrivIOProc[sIdx], pMemFormatInfo[iIoProc].szDefaultFormatExt ); #endif createTargetName(chrSourceName, pMemFormatInfo[iIoProc].szDefaultFormatExt); WinSetWindowText( WinWindowFromID(hwnd,IDEF_CONVERTTARGETNAME), chrTargetName ); } } break; case WM_TIMER: if(SHORT1FROMMP(mp1)==ID_TIMER) { if(!tidThread) { /* Convert thread ended. Quit. */ WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER); WinPostMsg(hwnd, WM_CLOSE, 0, 0); } return MRFALSE; } break; case WM_COMMAND: switch(SHORT1FROMMP(mp1)) { case IDPB_CONVERTBROWSE: { UCHAR chrTitle[200]; FILEDLG fd = { 0 }; /* User pressed the browse button */ fd.cbSize = sizeof( fd ); /* It's an centered 'Open'-dialog */ fd.fl = FDS_OPEN_DIALOG|FDS_CENTER; /* Set the title of the file dialog */ fd.pszTitle = chrTitle; if(!getMessage(chrTitle, IDSTR_AUDIOBROWSETITLE, sizeof(chrTitle), RESSOURCEHANDLE, hwnd)) fd.pszTitle = "Wave name"; /* Only show * files */ //sprintf(fd.szFullFile,"%s","*"); strcpy(fd.szFullFile, chrTargetName); if( WinFileDlg( HWND_DESKTOP, hwnd, &fd ) == NULLHANDLE ) { /* WinFileDlg failed */ break; } if( fd.lReturn == DID_OK ) { WinSetWindowText( WinWindowFromID(hwnd,IDEF_CONVERTTARGETNAME), fd.szFullFile ); } break; } case IDPB_CONVERTHELP: { char uchArgs[CCHMAXPATH] = {0}; unsigned char LoadError[CCHMAXPATH] = {0}; PSZ Envs = NULL; RESULTCODES ChildRC = {0}; APIRET rc = NO_ERROR; char HelpFile[CCHMAXPATH] = {0}; char *lang = getenv("LANG"); if (lang) { if (!strnicmp(lang, "es", 2)) strcpy(HelpFile, "CWMM034.hlp"); else if (!strnicmp(lang, "nl", 2)) strcpy(HelpFile, "CWMM031.hlp"); else if (!strnicmp(lang, "de", 2)) strcpy(HelpFile, "CWMM049.hlp"); else if (!strnicmp(lang, "ru", 2)) strcpy(HelpFile, "CWMM007.hlp"); else if (!strnicmp(lang, "fr", 2)) strcpy(HelpFile, "CWMM033.hlp"); else if (!strnicmp(lang, "it", 2)) strcpy(HelpFile, "CWMM039.hlp"); else if (!strnicmp(lang, "tw", 2)) strcpy(HelpFile, "CWMM088.hlp"); else strcpy(HelpFile, "CWMM.hlp"); } else strcpy(HelpFile, "CWMM.hlp"); sprintf(uchArgs, "view.exe%c%c:\\MMOS2\\MMCLASS\\%s \"Convert audio file\"%c", 0, SysQueryBootDriveLetter(), HelpFile, 0); rc = DosExecPgm(LoadError, sizeof(LoadError), EXEC_ASYNCRESULT, uchArgs, Envs, &ChildRC, "view.exe"); break; } case IDPB_CONVERTCLOSE: bBreak=TRUE; if(!WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER, TIMER_DELAY)) WinPostMsg(hwnd, WM_CLOSE, 0, 0);/* Timer error so do a hard quit */ break; case IDPB_CONVERTABORT: bBreak=TRUE; WinEnableWindow( WinWindowFromID(hwnd,IDPB_CONVERTABORT), FALSE); break; case IDPB_CONVERTOK: { FSALLOCATE fsAlloc; ULONG lFreeSpace; ULONG ulDiskNum; char cLetter; ULONG cUnitAvail; WinQueryWindowText( WinWindowFromID(hwnd,IDEF_CONVERTTARGETNAME), sizeof(chrTargetName), chrTargetName ); /* Check if diskspace is sufficient. Only for *.wav */ if(!stricmp(pMemFormatInfo[iIoProc].szDefaultFormatExt, "WAV")) { cLetter=tolower(chrTargetName[0]); ulDiskNum=cLetter-'a'+1; if(DosQueryFSInfo(ulDiskNum, FSIL_ALLOC,&fsAlloc,sizeof(fsAlloc))) lFreeSpace=0; else{ cUnitAvail=0xFFFFFFFF/(fsAlloc.cbSector*fsAlloc.cSectorUnit); if(fsAlloc.cUnitAvail > cUnitAvail) lFreeSpace=0xFFFFFFFF; else lFreeSpace=fsAlloc.cUnitAvail*fsAlloc.cbSector*fsAlloc.cSectorUnit; } } else lFreeSpace=lAudioSize; /* Fake sufficient space */ if(lFreeSpace