/*------------------------------------------ DRUMFILE.C -- File I/O Routines for DRUM (c) Charles Petzold, 1992 ------------------------------------------*/ #include extern "C" { #include #include } #include #include #include #include "drumdll.h" #include "drumfile.h" OPENFILENAME ofn = { sizeof (OPENFILENAME) } ; char * szFilter[] = { "Drum Files (*.DRM)", "*.drm", "" } ; char szDrumID [] = "DRUM" ; char szListID [] = "LIST" ; char szInfoID [] = "INFO" ; char szSoftID [] = "ISFT" ; char szDateID [] = "ISCD" ; char szFmtID [] = "fmt " ; char szDataID [] = "data" ; char szSoftware [] = "DRUM by Charles Petzold, " "PC Magazine, Vol. 11, Nos. 9-12" ; char szErrorNoCreate [] = "File %s could not be opened for writing." ; char szErrorCannotWrite [] = "File %s could not be written to. Disk full." ; char szErrorNotFound [] = "File %s not found or cannot be opened." ; char szErrorNotDrum [] = "File %s is not a standard DRUM file." ; char szErrorUnsupported [] = "File %s is not a supported DRUM file." ; char szErrorCannotRead [] = "File %s cannot be read." ; BOOL DrumFileParse (char * szFileName, char * szTitleName) { static char szBuffer [_MAX_PATH] ; if (_fullpath (szBuffer, szFileName, _MAX_PATH)) { strcpy (szFileName, szBuffer) ; if (!GetFileTitle (szFileName, szTitleName, _MAX_FNAME + _MAX_EXT)) return TRUE ; } return FALSE ; } BOOL DrumFileOpenDlg (HWND hwnd, char * szFileName, char * szTitleName) { ofn.hwndOwner = hwnd ; ofn.lpstrFilter = szFilter [0] ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = _MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT ; ofn.Flags = OFN_CREATEPROMPT ; ofn.lpstrDefExt = "drm" ; return GetOpenFileName (&ofn) ; } BOOL DrumFileSaveDlg (HWND hwnd, char * szFileName, char * szTitleName) { ofn.hwndOwner = hwnd ; ofn.lpstrFilter = szFilter [0] ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = _MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT ; ofn.Flags = OFN_OVERWRITEPROMPT ; ofn.lpstrDefExt = "drm" ; return GetSaveFileName (&ofn) ; } char * DrumFileWrite (DRUM * pdrum, char * szFileName) { char szDateBuf [16] ; HMMIO hmmio ; long lFormat = 1L ; MMCKINFO mmckinfo [3] ; struct tm * tmTime ; time_t lTime ; WORD wError = 0 ; memset (mmckinfo, 0, 3 * sizeof (MMCKINFO)) ; // Recreate the file for writing if ((hmmio = mmioOpen (szFileName, NULL, MMIO_CREATE | MMIO_WRITE | MMIO_ALLOCBUF)) == NULL) return szErrorNoCreate ; // Create a "RIFF" chunk with a "CPDR" type mmckinfo[0].fccType = mmioStringToFOURCC (szDrumID, 0) ; wError |= mmioCreateChunk (hmmio, &mmckinfo[0], MMIO_CREATERIFF) ; // Create "LIST" sub-chunk with an "INFO" type mmckinfo[1].fccType = mmioStringToFOURCC (szInfoID, 0) ; wError |= mmioCreateChunk (hmmio, &mmckinfo[1], MMIO_CREATELIST) ; // Create "ISFT" sub-sub-chunk mmckinfo[2].ckid = mmioStringToFOURCC (szSoftID, 0) ; wError |= mmioCreateChunk (hmmio, &mmckinfo[2], 0) ; wError |= (mmioWrite (hmmio, szSoftware, sizeof (szSoftware)) != sizeof (szSoftware)) ; wError |= mmioAscend (hmmio, &mmckinfo[2], 0) ; // Create a time string time (&lTime) ; tmTime = localtime (&lTime) ; wsprintf (szDateBuf, "%04d-%02d-%02d", tmTime->tm_year + 1900, tmTime->tm_mon + 1, tmTime->tm_mday) ; // Create "ISCD" sub-sub-chunk mmckinfo[2].ckid = mmioStringToFOURCC (szDateID, 0) ; wError |= mmioCreateChunk (hmmio, &mmckinfo[2], 0) ; wError |= (mmioWrite (hmmio, szDateBuf, strlen (szDateBuf) + 1) != (long) strlen (szDateBuf) + 1) ; wError |= mmioAscend (hmmio, &mmckinfo[2], 0) ; wError |= mmioAscend (hmmio, &mmckinfo[1], 0) ; // Create "fmt " sub-chunk mmckinfo[1].ckid = mmioStringToFOURCC (szFmtID, 0) ; wError |= mmioCreateChunk (hmmio, &mmckinfo[1], 0) ; wError |= (mmioWrite (hmmio, (LPSTR) &lFormat, sizeof (long)) != sizeof (long)) ; wError |= mmioAscend (hmmio, &mmckinfo[1], 0) ; // Create the "data" sub-chunk mmckinfo[1].ckid = mmioStringToFOURCC (szDataID, 0) ; wError |= mmioCreateChunk (hmmio, &mmckinfo[1], 0) ; wError |= (mmioWrite (hmmio, (LPSTR) pdrum, sizeof (DRUM)) != sizeof (DRUM)) ; wError |= mmioAscend (hmmio, &mmckinfo[1], 0) ; wError |= mmioAscend (hmmio, &mmckinfo[0], 0) ; // Clean up and return wError |= mmioClose (hmmio, 0) ; if (wError) { mmioOpen (szFileName, NULL, MMIO_DELETE) ; return szErrorCannotWrite ; } return NULL ; } char * DrumFileRead (DRUM * pdrum, char * szFileName) { DRUM drum ; HMMIO hmmio ; long lFormat ; MMCKINFO mmckinfo [3] ; memset (mmckinfo, 0, 2 * sizeof (MMCKINFO)) ; // Open the file if ((hmmio = mmioOpen (szFileName, NULL, MMIO_READ)) == NULL) return szErrorNotFound ; // Locate a "RIFF" chunk with a "DRUM" form-type mmckinfo[0].ckid = mmioStringToFOURCC (szDrumID, 0) ; if (mmioDescend (hmmio, &mmckinfo[0], NULL, MMIO_FINDRIFF)) { mmioClose (hmmio, 0) ; return szErrorNotDrum ; } // Locate, read, and verify the "fmt " sub-chunk mmckinfo[1].ckid = mmioStringToFOURCC (szFmtID, 0) ; if (mmioDescend (hmmio, &mmckinfo[1], &mmckinfo[0], MMIO_FINDCHUNK)) { mmioClose (hmmio, 0) ; return szErrorNotDrum ; } if (mmckinfo[1].cksize != sizeof (long)) { mmioClose (hmmio, 0) ; return szErrorUnsupported ; } if (mmioRead (hmmio, (LPSTR) &lFormat, sizeof (long)) != sizeof (long)) { mmioClose (hmmio, 0) ; return szErrorCannotRead ; } if (lFormat != 1) { mmioClose (hmmio, 0) ; return szErrorUnsupported ; } // Go to end of "fmt " sub-chunk mmioAscend (hmmio, &mmckinfo[1], 0) ; // Locate, read, and verify the "data" sub-chunk mmckinfo[1].ckid = mmioStringToFOURCC (szDataID, 0) ; if (mmioDescend (hmmio, &mmckinfo[1], &mmckinfo[0], MMIO_FINDCHUNK)) { mmioClose (hmmio, 0) ; return szErrorNotDrum ; } if (mmckinfo[1].cksize != sizeof (DRUM)) { mmioClose (hmmio, 0) ; return szErrorUnsupported ; } if (mmioRead (hmmio, (LPSTR) &drum, sizeof (DRUM)) != sizeof (DRUM)) { mmioClose (hmmio, 0) ; return szErrorCannotRead ; } // Close the file and copy the DRUM structure data mmioClose (hmmio, 0) ; memcpy (pdrum, &drum, sizeof (DRUM)) ; return NULL ; }