// ********************************************************************************
// *** C/C++ example (Visual C++) to read out Sidecar files ***
// *** Lists all internal files in a Sidecar ***
// *** ***
// *** Last modified: 2012APR28 ***
// *** (c) Christian Schnettelker 2011, 2012 ***
// *** ***
// *** Command line usage: Sierra <sidecar-file> ***
// *** ***
// *** www.finefiles.com mail@finefiles.com ***
// ********************************************************************************
#include <stdio.h>
#include <strsafe.h> // for sprintf_s()
#include "ffBasic.h"
#include "scBasic.h"
#pragma warning(disable: 4996) // Visual C++: donīt warn because of fopen security
//////////////////////////////////////////////////////////////////
//
// Sub-function: read and check the main header
//
//////////////////////////////////////////////
bool ____readCheckMainHeader( FILE *fp )
{
SCMAINHEADER xSCmainHeader = { 0 };
if ( fread(&xSCmainHeader,sizeof(SCMAINHEADER),1,fp) != 1 ) return false;
if ( xSCmainHeader.cStart != 0x89 ) return false;
if ( strncmp((const char *)xSCmainHeader.cSignature,__SC__SIGNATURE,34) != 0 ) return false;
if ( xSCmainHeader.cCRLF[ 0 ] != 0x0D ) return false;
if ( xSCmainHeader.cCRLF[ 1 ] != 0x0A ) return false;
if ( xSCmainHeader.cEOF != 0x1A ) return false;
if ( xSCmainHeader.cLF != 0x0A ) return false;
return true; // Main header is valid
}
//////////////////////////////////////////////////////////////////
//
// Sub-function: read and check the FAT header
//
//////////////////////////////////////////////
bool ____readSCfatHeader( FILE *fp, SCFATHEADER *pSCfatHeader )
{
if ( fread(pSCfatHeader,sizeof(SCFATHEADER),1,fp) != 1 ) return false;
if ( strncmp((const char *)pSCfatHeader->cSignature,__SCFAT__HEADER100,12) != 0 ) return false;
return true; // FAT header is valid
}
//////////////////////////////////////////////////////////////////
//
// Sub-function: read a sidecar FAT entry to pSCfatEntry
//
//////////////////////////////////////////////
bool ____readSCfatEntry( FILE *fp, SCFATENTRY *pSCfatEntry )
{
if ( fread(pSCfatEntry,sizeof(SCFATENTRY),1,fp) != 1 ) return false;
if ( pSCfatEntry->cMagic != '#' ) return false;
return true; // FAT entry is valid
}
//////////////////////////////////////////////////////////////////////////
//
// main
//
//////////////////////////////////////////////
#define __QUIT fclose( fp ); return 0
int wmain( int argc, wchar_t *argv[] )
{
// Create the filename to access the sidecar stream
wchar_t swSCnamePath[ MAX_PATH + 1 ] = L""; swprintf_s( swSCnamePath,MAX_PATH,L"%ls%ls",argv[ 1 ],__SC__NAME );
// Open the source file
FILE *fp = _wfopen( swSCnamePath,L"rb" ); if ( fp == NULL ) { puts( "sidecar file not found" ); return 0; }
// --------------------- Read and check the main header
if ( !____readCheckMainHeader(fp) ) { puts( "The sidecar isnīt valid" ); __QUIT; }
// --------------------- Read, check and display the FAT header
SCFATHEADER xSCfatHeader = { 0 };
if ( !____readSCfatHeader(fp,&xSCfatHeader) ) { puts( "Error reading the FAT header" ); __QUIT; }
if ( !xSCfatHeader.wEntries ) { puts( "No embedded files in this sidecar" ); __QUIT; }
printf( "The sidecar has %d valid entries (files)\r\n", xSCfatHeader.wEntries );
printf( "There are %d deleted entries\r\n", xSCfatHeader.wDelEntries );
printf( "The sidecar contains %u bytes of file data\r\n\r\n",xSCfatHeader.u32BytesAllFiles );
// --------------------- Read, check and display the FAT entries
SCFATENTRY xSCfatEntry = { 0 };
for( UWORD u=0; u<xSCfatHeader.wEntries + xSCfatHeader.wDelEntries; u++ )
{
if ( !____readSCfatEntry(fp,&xSCfatEntry) ) { puts( "Error reading FAT entry" ); __QUIT; }
if ( xSCfatEntry.cAttribute & SCFAT__ATT__DELETED ) continue; // skip deleted entries
printf( "Entry %02u: %ls\r\n",u+1,xSCfatEntry.cwFileName );
}
// Job finished
fclose( fp ); return 0;
}
/* eof */