CachedFileStream::CachedFileStream(const char* stream, bool autoFree)
{
	ExtractFileFromPath( filename, stream );
	PathJoin( originalfile, core->CachePath, filename, NULL );

	str = _fopen( originalfile, "rb" );
	if (str == NULL) {    // File was not found in cache
		if (core->GameOnCD) {
			_FILE* src = _fopen( stream, "rb" );
#ifdef _DEBUG
			core->CachedFileStreamPtrCount++;
#endif
			_FILE* dest = _fopen( originalfile, "wb" );
#ifdef _DEBUG
			core->CachedFileStreamPtrCount++;
#endif
			void* buff = malloc( 1024 * 1000 );
			do {
				size_t len = _fread( buff, 1, 1024 * 1000, src );
				size_t c = _fwrite( buff, 1, len, dest );
				if (c != len) {
					printf("CachedFileStream failed to write to cached file '%s' (from '%s')\n", originalfile, stream);
					abort();
				}
			} while (!_feof( src ));
			free( buff );
			_fclose( src );
#ifdef _DEBUG
			core->CachedFileStreamPtrCount--;
#endif
			_fclose( dest );
#ifdef _DEBUG
			core->CachedFileStreamPtrCount--;
#endif
		} else {  // Don't cache files already on hdd
			strncpy(originalfile, stream, _MAX_PATH);
		}
		str = _fopen( originalfile, "rb" );
	}
#ifdef _DEBUG
	core->CachedFileStreamPtrCount++;
#endif
	startpos = 0;
	_fseek( str, 0, SEEK_END ); 
	size = _ftell( str );
	_fseek( str, 0, SEEK_SET );
	Pos = 0;
	this->autoFree = autoFree;
}
Exemplo n.º 2
0
/*!
  \param Option
*/
xbShort xbDbf::GetDbtHeader( xbShort Option )
{
  char *p;
  xbShort i;
  char MemoBlock[24];

  /*  Option = 0  -->  read only first four bytes
               1  -->  read the entire thing  */

  if( !mfp )
    return XB_NOT_OPEN;

  if( _fseek( mfp, 0, SEEK_SET ))
    return XB_SEEK_ERROR;

  if(( fread( MemoBlock, 24, 1, mfp )) != 1 )
    return XB_READ_ERROR;

  p = MemoBlock;
  MemoHeader.NextBlock = xbase->GetLong( p ); 
  if(IsType3Dbt() || Option == 0)
    return XB_NO_ERROR;
 
  /* version IV stuff follows */
  p+=8;
  for( i = 0; i < 8; i++, p++ ) 
    MemoHeader.FileName[i] = *p;
  MemoHeader.Version  = *p;
  p+=4;
  MemoHeader.BlockSize = xbase->GetShort( p );
  return XB_NO_ERROR;
}
Exemplo n.º 3
0
Arquivo: 3dsx.c Projeto: PLenz/ninjhax
// Calculate number of additional pages required to be allocated on heap by bootloader.
Result CalcRequiredAllocSizeFor3DSX(Handle file, u32* numOut)
{
	_fseek(file, 0x0, SEEK_SET);

	_3DSX_Header hdr;
	if (_fread(&hdr, sizeof(hdr), file) != 0)
		return -1;

	if (hdr.magic != _3DSX_MAGIC)
		return -2;

	_3DSX_LoadInfo d;
	d.segSizes[0] = (hdr.codeSegSize+0xFFF) &~ 0xFFF;
	SEC_ASSERT(d.segSizes[0] >= hdr.codeSegSize); // int overflow
	d.segSizes[1] = (hdr.rodataSegSize+0xFFF) &~ 0xFFF;
	SEC_ASSERT(d.segSizes[1] >= hdr.rodataSegSize); // int overflow
	d.segSizes[2] = (hdr.dataSegSize+0xFFF) &~ 0xFFF;
	SEC_ASSERT(d.segSizes[2] >= hdr.dataSegSize); // int overflow

	// Calculate # of pages required.
	u32 pagesRequired = d.segSizes[0]/0x1000 + d.segSizes[1]/0x1000 + d.segSizes[2]/0x1000; // XXX: int overflow

	if(pagesRequired > CN_TOTAL3DSXPAGES)
		*numOut = pagesRequired - CN_TOTAL3DSXPAGES + 1;
	else
		*numOut = 0;

	//svc_closeHandle(file);
	return 0;
}
Exemplo n.º 4
0
xbShort xbDbf::ReadMemoBlock( xbLong BlockNo, xbShort Option )
{
  size_t ReadSize;
  CurMemoBlockNo = -1;

  if( BlockNo < 1L )
    return XB_INVALID_BLOCK_NO;

  if( _fseek( mfp,((xbOffT)BlockNo*MemoHeader.BlockSize), SEEK_SET ))
    return XB_SEEK_ERROR;


  if( Option ==  0 || Option == 1 )
    ReadSize = MemoHeader.BlockSize;
  else
    ReadSize = 8L;

  if(fread( mbb, ReadSize, 1, mfp ) != 1 )
    return XB_READ_ERROR;

  if( Option == 0 || Option == 4){ // 1st block of a set of valid data blocks
    mfield1   = xbase->GetShort( (char *) mbb );
    MStartPos = xbase->GetShort( (char *) mbb+2 );
    MFieldLen = xbase->GetLong ( (char *) mbb+4 );
  }
  else if( Option == 2 ){    // 1st block of a set of free blocks
    NextFreeBlock = xbase->GetLong( (char *) mbb );
    FreeBlockCnt  = xbase->GetLong( (char *) mbb+4 );
  }
   
  if( Option ==  0 || Option == 1 )
    CurMemoBlockNo = BlockNo;

  return XB_NO_ERROR;
}
CachedFileStream::CachedFileStream(CachedFileStream* cfs, int startpos,
	int size, bool autoFree)
{
	this->size = size;
	this->startpos = startpos;
	this->autoFree = autoFree;
	char cpath[_MAX_PATH];
	PathJoin( cpath, core->CachePath, cfs->filename, NULL );
	str = _fopen( cpath, "rb" );
	if (str == NULL) {
		str = _fopen( cfs->originalfile, "rb" );
		if (str == NULL) {
			printf( "Can't open stream (maybe leaking?)\n" );
			return;
		}
		strncpy( originalfile, cfs->originalfile, sizeof(originalfile) );
		strncpy( filename, cfs->filename, sizeof(filename) );
	} else {
		strncpy( originalfile, cpath, sizeof(originalfile) );
		strncpy( filename, cfs->filename, sizeof(filename) );
	}
#ifdef _DEBUG
	core->CachedFileStreamPtrCount++;
#endif
	_fseek( str, startpos, SEEK_SET );
	
	
	Pos = 0;
}
Exemplo n.º 6
0
/* A portable fseek() function
   return 0 on success, non-zero on failure (with errno set) */
int my_fseek (FILE *fp, my_off_t offset, int whence) {
#if defined (HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
    return fseeko(fp, offset, whence);
#elif defined (HAVE_FSEEK64)
    return fseek64(fp, offset, whence);
#elif defined (__BEOS__)
    return _fseek(fp, offset, whence);
#elif SIZEOF_FPOS_T >= 8
    /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
       and fgetpos() to implement fseek()*/
    fpos_t pos;
    switch (whence) {
    case SEEK_END:
#ifdef MS_WINDOWS
        fflush (fp);
        if (_lseeki64 (fileno(fp), 0, 2) == -1)
            return -1;
#else
        if (fseek (fp, 0, SEEK_END) != 0)
            return -1;
#endif
        /* fall through */
    case SEEK_CUR:
        if (fgetpos (fp, &pos) != 0)
            return -1;
        offset += pos;
        break;
        /* case SEEK_SET: break; */
    }

    return fsetpos(fp, &offset);
#else
	#error "Large file support, but no way to fseek."
#endif
}
Exemplo n.º 7
0
/*!
*/
xbShort xbDbf::OpenMemoFile()
{
  if (Version == (char)0xf5 || Version == (char)0x30) 
    return OpenFPTFile();

  xbShort len, rc;
  xbOffT Size, NewSize, l;
  MemofileName = GetFileName();
  len = GetFileName().len() - 1;
  if( MemofileName[len] == 'F' )
    MemofileName.putAt(len, 'T');
  else if( MemofileName[len] == 'f' )
    MemofileName.putAt(len, 't');
  else
    return XB_INVALID_NAME;

  if(( mfp = fopen( MemofileName, "r+b" )) == NULL ){
    //
    //  Try to open read only if can't open read/write
    //
    if(( mfp = fopen( MemofileName, "rb" )) == NULL )
      return XB_OPEN_ERROR;
  }
#ifdef XB_LOCKING_ON
  setbuf( mfp, NULL );
#endif
  if(( rc = GetDbtHeader(1)) != 0 ){
    fclose( mfp );
    return rc;
  }

  len = GetMemoBlockSize();
  if( len == 0 || ((len % 512) != 0 )){
    fclose( mfp );
    return XB_INVALID_BLOCK_SIZE;
  }

  /* logic to verify file size is a multiple of block size */
  if(( rc = _fseek( mfp, 0, SEEK_END )) != 0 ){
    fclose( mfp );
    return XB_SEEK_ERROR;
  }

  /* if the file is not a multiple of block size, fix it, append nulls */
  Size = _ftell( mfp );
  if(( Size % MemoHeader.BlockSize ) != 0 ){
    NewSize = ( Size / MemoHeader.BlockSize + 1) * MemoHeader.BlockSize;
    for( l = Size; l < NewSize; l++ )
      fputc( 0x00, mfp );
  }

  if(( mbb = (void *) malloc(len)) == NULL ){
    fclose( mfp );
    return XB_NO_MEMORY;
  }
  return XB_NO_ERROR;
}
Exemplo n.º 8
0
/*!
*/
xbShort xbDbf::UpdateHeadNextNode() const
{
  char buf[4];
  memset( buf, 0x00, 4 );
  xbase->PutLong( buf, MemoHeader.NextBlock );
  if(( _fseek( mfp, 0, SEEK_SET )) != 0 )
    return XB_SEEK_ERROR;

  if(( fwrite( &buf, 4, 1, mfp )) != 1 )
    return XB_WRITE_ERROR;

  return XB_NO_ERROR;
}
Exemplo n.º 9
0
/*!
  \param FieldNo
*/
xbLong xbDbf::GetFPTFieldLen( xbShort FieldNo )
{
  xbLong  BlockNo;
  if(( BlockNo = GetLongField(FieldNo)) == 0L )
    return 0L;
  // Seek to start_of_block + 4
  if(_fseek(mfp, ((xbOffT)BlockNo * MemoHeader.BlockSize + 4), SEEK_SET) != 0)
    return XB_SEEK_ERROR;
  char h[4];
  if((fread(h, 4, 1, mfp)) != 1)
    return XB_READ_ERROR;

  return xbase->GetHBFULong(h);
}
int CachedFileStream::Seek(int newpos, int type)
{
	switch (type) {
		case GEM_CURRENT_POS:
			_fseek( str, newpos, SEEK_CUR );
			Pos += newpos;
			break;

		case GEM_STREAM_START:
			_fseek( str, startpos + newpos, SEEK_SET );
			Pos = newpos;
			break;

		default:
			return GEM_ERROR;
	}
	//we went past the buffer
	if (Pos>size) {
		printf("[Streams]: Invalid seek position: %ld (limit: %ld)\n",Pos, size);
		return GEM_ERROR;
	}
	return GEM_OK;
}
Exemplo n.º 11
0
int fseek ( FILE * stream, long int offset, int origin )
{
    //printf("INTERCEPTED fseek\n");

    clock_t start = clock();

    int ret = _fseek(stream,offset,origin);
    
    clock_t end = clock();

    double called_time = (double)(start-program_start)/(double)(CLOCKS_PER_SEC);

    double exec_time = (double)(end-start)/(double)(CLOCKS_PER_SEC);

    fprintf(logFile,"%lf %lf fseek %p %ld %d = %d\n",called_time,exec_time,stream,offset,origin,ret);

    return ret;
}
Exemplo n.º 12
0
/*!
  \param BlockNo
  \param Option
*/
xbShort xbDbf::WriteMemoBlock( xbLong BlockNo, xbShort Option )
{
/* Option = 0 - 1st Block of a set of valid data blocks, set buckets    */
/* Option = 1 - subsequant block of data in a multi block set or db III */
/* Option = 2 - 1st block of a set offree blocks, set buckets           */                     

  xbLong WriteSize;

  if( BlockNo < 1L )
    return XB_INVALID_BLOCK_NO;

  CurMemoBlockNo = -1;

  if( Option == 0 ){
    xbase->PutShort( (char *) mbb, mfield1 );
    xbase->PutShort( (char *) mbb+2, MStartPos );
    xbase->PutLong ( (char *) mbb+4, MFieldLen );
    WriteSize = MemoHeader.BlockSize;
  }
  else if( Option == 2 ){
    xbase->PutLong((char *) mbb, NextFreeBlock );
    xbase->PutLong((char *) mbb+4, FreeBlockCnt );
    WriteSize = 8L;
  }
  else
    WriteSize = MemoHeader.BlockSize;

  if( _fseek( mfp,((xbOffT)BlockNo*MemoHeader.BlockSize), SEEK_SET ))
    return XB_SEEK_ERROR;

  if(( fwrite( mbb, WriteSize, 1, mfp )) != 1 ) 
    return XB_WRITE_ERROR;

  if( Option == 0 || Option == 1 ) 
    CurMemoBlockNo = BlockNo;

  return XB_NO_ERROR;
}
Exemplo n.º 13
0
/*!
*/
xbLong xbDbf::CalcLastDataBlock()
{
  if( _fseek( mfp, 0, SEEK_END ) != 0 )
    return XB_SEEK_ERROR;
  return ( _ftell( mfp ) / MemoHeader.BlockSize );
}
Exemplo n.º 14
0
/*!
  \param FieldNo
  \param len
  \param Buf
  \param LockOpt
*/
xbShort xbDbf::GetFPTField(xbShort FieldNo, xbLong len,
                           char * Buf, xbShort LockOpt) {

 if (FieldNo < 0 || FieldNo > (NoOfFields - 1))
   return XB_INVALID_FIELDNO;

 if (GetFieldType(FieldNo) != 'M')
   return XB_NOT_MEMO_FIELD;

#ifdef XB_LOCKING_ON
//  if( LockOpt != -1 )
//    if( LockMemoFile( XB_LOCK ) != XB_NO_ERROR )
//      return XB_LOCK_FAILED;
#endif

  xbLong BlockNo;
  char buf[18];

  if( Version == (char)0x30 ) {
    memset( buf, 0x00, 18 ) ;
    GetField( FieldNo, buf );
    BlockNo = xbase->GetLong((char*) buf);
  } else {
    BlockNo = GetLongField(FieldNo);
  }  

  if ( BlockNo == 0L )
    return 0L;

  // Seek to start_of_block + 4


// FIXME LOCK

#ifdef XB_LOCKING_ON
//  try {
#endif
    if (_fseek(mfp, ((xbOffT)BlockNo * MemoHeader.BlockSize + 4), SEEK_SET) != 0)
      return XB_SEEK_ERROR;
    char h[4];
    if ((fread(h, 4, 1, mfp)) != 1)
     return XB_READ_ERROR;

    xbULong fLen = xbase->GetHBFULong(h);

    xbULong l = (fLen < (xbULong)len) ? fLen : len;
    if ((fread(Buf, l, 1, mfp)) != 1)
     return XB_READ_ERROR;
    Buf[l]=0;
#ifdef XB_LOCKING_ON
//  }
// catch (...) {
//     if (LockOpt != -1)
//       LockMemoFile( XB_UNLOCK );
//     throw;
//  }
#endif

#ifdef XB_LOCKING_ON
//  if (LockOpt != -1)
//    LockMemoFile( XB_UNLOCK );
#endif

  return XB_NO_ERROR;
}
Exemplo n.º 15
0
Arquivo: 3dsx.c Projeto: PLenz/ninjhax
int Load3DSX(Handle file, Handle process, void* baseAddr, u32 heapAddr)
{
	// Extra heap must be deallocated before loading a new 3DSX.
	if(hasExtraHeap)
		return -5;

	u32 i, j, k, m;
	u32 endAddr = 0x00100000+CN_NEWTOTALPAGES*0x1000;

	SEC_ASSERT(baseAddr >= (void*)0x00100000);
	SEC_ASSERT((((u32) baseAddr) & 0xFFF) == 0); // page alignment

	_fseek(file, 0x0, SEEK_SET);

	_3DSX_Header hdr;
	if (_fread(&hdr, sizeof(hdr), file) != 0)
		return -1;

	if (hdr.magic != _3DSX_MAGIC)
		return -2;

	_3DSX_LoadInfo d;
	d.segSizes[0] = (hdr.codeSegSize+0xFFF) &~ 0xFFF;
	SEC_ASSERT(d.segSizes[0] >= hdr.codeSegSize); // int overflow
	d.segSizes[1] = (hdr.rodataSegSize+0xFFF) &~ 0xFFF;
	SEC_ASSERT(d.segSizes[1] >= hdr.rodataSegSize); // int overflow
	d.segSizes[2] = (hdr.dataSegSize+0xFFF) &~ 0xFFF;
	SEC_ASSERT(d.segSizes[2] >= hdr.dataSegSize); // int overflow

	// Map extra heap.
	u32 pagesRequired = d.segSizes[0]/0x1000 + d.segSizes[1]/0x1000 + d.segSizes[2]/0x1000; // XXX: int overflow
	u32 extendedPagesSize = 0;

	if(pagesRequired > CN_TOTAL3DSXPAGES)
	{
		if(svc_unmapProcessMemory(process, 0x00100000, 0x02000000))return -12;
		u32 extendedPages = pagesRequired - CN_TOTAL3DSXPAGES + 1;

		u32 i;
		for(i=0; i<extendedPages; i++)
		{
			if(svc_controlProcessMemory(process, endAddr+i*0x1000, heapAddr+i*0x1000, 0x1000, MEMOP_MAP, 0x7))
				return -4;
		}

		if(svc_controlProcessMemory(process, heapAddr, 0, extendedPages*0x1000, MEMOP_PROTECT, 0x1))
			return -5;

		processHandle = process;
		hasExtraHeap = 1;
		extraHeapAddr = heapAddr;
		extraHeapPages = extendedPages;

		extendedPagesSize = extraHeapPages*0x1000;
		endAddr += extendedPagesSize;
		if(svc_mapProcessMemory(process, 0x00100000, 0x02000000))return -13;
	}

	u32 offsets[2] = { d.segSizes[0], d.segSizes[0] + d.segSizes[1] };
	d.segPtrs[0] = baseAddr;
	d.segPtrs[1] = (char*)d.segPtrs[0] + d.segSizes[0];
	SEC_ASSERT((u32)d.segPtrs[1] >= d.segSizes[0]); // int overflow
	d.segPtrs[2] = (char*)d.segPtrs[1] + d.segSizes[1];
	SEC_ASSERT((u32)d.segPtrs[2] >= d.segSizes[1]); // int overflow
	SEC_ASSERT((u32)d.segPtrs[2] < endAddr); // within user memory

	// Skip header for future compatibility.
	_fseek(file, hdr.headerSize, SEEK_SET);
	
	// Read the relocation headers
	SEC_ASSERT(hdr.dataSegSize >= hdr.bssSize); // int underflow
	u32* relocs = (u32*)((char*)d.segPtrs[2] + hdr.dataSegSize - hdr.bssSize);
	SEC_ASSERT((u32)relocs >= (u32)d.segPtrs[2]); // int overflow
	SEC_ASSERT((u32)relocs < endAddr); // within user memory
	u32 nRelocTables = hdr.relocHdrSize/4;
 
	u32 relocsEnd = (u32)(relocs + 3*nRelocTables);
	SEC_ASSERT((u32)relocsEnd >= (u32)relocs); // int overflow
	SEC_ASSERT((u32)relocsEnd < endAddr); // within user memory

	// XXX: Ensure enough RW pages exist at baseAddr to hold a memory block of length "totalSize".
	//    This also checks whether the memory region overflows into IPC data or loader data.
 
	for (i = 0; i < 3; i ++)
		if (_fread(&relocs[i*nRelocTables], nRelocTables*4, file) != 0)
			return -3;
 
	// Read the segments
	if (_fread(d.segPtrs[0], hdr.codeSegSize, file) != 0) return -4;
	if (_fread(d.segPtrs[1], hdr.rodataSegSize, file) != 0) return -5;
	if (_fread(d.segPtrs[2], hdr.dataSegSize - hdr.bssSize, file) != 0) return -6;
 
	// Relocate the segments
	for (i = 0; i < 3; i ++)
	{
		for (j = 0; j < nRelocTables; j ++)
		{
			u32 nRelocs = relocs[i*nRelocTables+j];
			if (j >= 2)
			{
				// We are not using this table - ignore it
				_fseek(file, nRelocs*sizeof(_3DSX_Reloc), SEEK_CUR);
				continue;
			}
 
			static _3DSX_Reloc relocTbl[RELOCBUFSIZE];
 
			u32* pos = (u32*)d.segPtrs[i];
			u32* endPos = pos + (d.segSizes[i]/4);
			SEC_ASSERT(((u32) endPos) < endAddr); // within user memory

			while (nRelocs)
			{
				u32 toDo = nRelocs > RELOCBUFSIZE ? RELOCBUFSIZE : nRelocs;
				nRelocs -= toDo;
 
				if (_fread(relocTbl, toDo*sizeof(_3DSX_Reloc), file) != 0)
					return -7;
 
				for (k = 0; k < toDo && pos < endPos; k ++)
				{
					pos += relocTbl[k].skip;
					u32 num_patches = relocTbl[k].patch;
					for (m = 0; m < num_patches && pos < endPos; m ++)
					{
						void* addr = TranslateAddr(*pos, &d, offsets);
						SEC_ASSERT(((u32) pos) < endAddr); // within user memory
						switch (j)
						{
							case 0: *pos = (u32)addr; break;
							case 1: *pos = (int)addr - (int)pos; break;
						}
						pos++;
					}
				}
			}
		}
	}

	// Detect and fill _prm structure
	u32* prmStruct = (u32*)baseAddr + 1;
	if(prmStruct[0]==0x6D72705F)
	{
		// Write service handle table pointer
		// the actual structure has to be filled out by cn_bootloader
		prmStruct[1] = (u32)__service_ptr;

		// XXX: other fields that need filling:
		// prmStruct[2] <-- __apt_appid (default: 0x300)
		// prmStruct[3] <-- __heap_size (default: 24*1024*1024)
		// prmStruct[4] <-- __gsp_heap_size (default: 32*1024*1024)
		// prmStruct[5] <-- __system_arglist (default: NULL)

		prmStruct[2] = 0x300;
		prmStruct[3] = 29*1024*1024 - extendedPagesSize;
		prmStruct[4] = 32*1024*1024;
		prmStruct[5] = CN_ARGCV_LOC;
		prmStruct[6] = RUNFLAG_APTWORKAROUND; //__system_runflags

		// XXX: Notes on __system_arglist:
		//     Contains a pointer to a u32 specifying the number of arguments immediately followed
		//     by the NULL-terminated argument strings themselves (no pointers). The first argument
		//     should always be the path to the file we are booting. Example:
		//     \x02\x00\x00\x00sd:/dir/file.3dsx\x00Argument1\x00
		//     Above corresponds to { "sd:/dir/file.3dsx", "Argument1" }.
	}

	// Protect memory at d.segPtrs[0] as CODE   (r-x) -- npages = d.segSizes[0] / 0x1000
	for(i=0;i<d.segSizes[0]>>12;i++)svc_controlProcessMemory(process, (u32)d.segPtrs[0]+i*0x1000, 0x0, 0x00001000, MEMOP_PROTECT, 0x5);
	// Protect memory at d.segPtrs[1] as RODATA (r--) -- npages = d.segSizes[1] / 0x1000
	for(i=0;i<d.segSizes[1]>>12;i++)svc_controlProcessMemory(process, (u32)d.segPtrs[1]+i*0x1000, 0x0, 0x00001000, MEMOP_PROTECT, 0x1);
	// Protect memory at d.segPtrs[2] as DATA (rw-) -- npages = d.segSizes[2] / 0x1000
	for(i=0;i<d.segSizes[2]>>12;i++)svc_controlProcessMemory(process, (u32)d.segPtrs[2]+i*0x1000, 0x0, 0x00001000, MEMOP_PROTECT, 0x3);
 
        //svc_closeHandle(process); TODO
        //svc_closeHandle(file);
	return 0; // Success.
}
Exemplo n.º 16
0
/*!
*/
xbShort xbDbf::CreateMemoFile( void )
{
  xbShort len,i;
  char  *sp;
  char  buf[4];

  len = GetMemoBlockSize();
  if( len == 0 || len % 512 != 0 )
    return XB_INVALID_BLOCK_SIZE;

  if(( sp = (char*)strrchr(GetFileName(), PATH_SEPARATOR)) != NULL )
    sp++;
  else
    sp = MemoHeader.FileName;

  memset( MemoHeader.FileName, 0x00, 8 );

  for( i = 0; i < 8 && *sp != '.'; i++ )
    MemoHeader.FileName[i] = *sp++;

  MemofileName = GetFileName();

  len = GetFileName().len() - 1;
  if( MemofileName[len] == 'F' )
    MemofileName.putAt(len, 'T');
  else if( MemofileName[len] == 'f' )
    MemofileName.putAt(len, 't');
  else
    return XB_INVALID_NAME;

  /* Initialize the variables */
  MemoHeader.NextBlock = 1L;

  if(( mfp = fopen( MemofileName, "w+b" )) == NULL )
    return XB_OPEN_ERROR;
#ifdef XB_LOCKING_ON
  setbuf( mfp, NULL );
#endif

  if(( _fseek( mfp, 0, SEEK_SET )) != 0 ){
    fclose( mfp );
    return XB_SEEK_ERROR;
  }

  memset( buf, 0x00, 4 );
  xbase->PutLong( buf, MemoHeader.NextBlock );
  if(( fwrite( &buf, 4, 1, mfp )) != 1 ){
    fclose( mfp );
    return XB_WRITE_ERROR;
  }

  if( IsType3Dbt() ){   /* dBASE III+ */
    for( i = 0; i < 12; i++ )  fputc( 0x00, mfp );
    fputc( 0x03, mfp );
    for( i = 0; i < 495; i++ ) fputc( 0x00, mfp );
  }
  else
  {
    for( i = 0; i < 4; i++ )  fputc( 0x00, mfp );
    fwrite( &MemoHeader.FileName,  8, 1, mfp );
    for( i = 0; i < 4; i++ )  fputc( 0x00, mfp );
    memset( buf, 0x00, 2 );
    xbase->PutShort( buf, MemoHeader.BlockSize );
    if(( fwrite( &buf, 2, 1, mfp )) != 1 ){
      fclose( mfp );
      return XB_WRITE_ERROR;
    }
    for( i = 22; i <  MemoHeader.BlockSize; i++ ) fputc( 0x00, mfp );
  }
        
  if(( mbb = (void *) malloc( MemoHeader.BlockSize )) == NULL ){
    fclose( mfp );
    return XB_NO_MEMORY;
  }
  return XB_NO_ERROR;
}
Exemplo n.º 17
0
Arquivo: rngplay.c Projeto: nbzwt/nPal
static INT
PAL_RNGReadFrame(
   LPBYTE          lpBuffer,
   UINT            uiBufferSize,
   UINT            uiRngNum,
   UINT            uiFrameNum,
   FILE           *fpRngMKF
)
/*++
  Purpose:

    Read a frame from a RNG animation.

  Parameters:

    [OUT] lpBuffer - pointer to the destination buffer.

    [IN]  uiBufferSize - size of the destination buffer.

    [IN]  uiRngNum - the number of the RNG animation in the MKF archive.

    [IN]  uiFrameNum - frame number in the RNG animation.

    [IN]  fpRngMKF - pointer to the fopen'ed MKF file.

  Return value:

    Integer value which indicates the size of the chunk.
    -1 if there are error in parameters.
    -2 if buffer size is not enough.

--*/
{
   UINT         uiOffset       = 0;
   UINT         uiSubOffset    = 0;
   UINT         uiNextOffset   = 0;
   UINT         uiChunkCount   = 0;
   INT          iChunkLen      = 0;

   if (lpBuffer == NULL || fpRngMKF == NULL || uiBufferSize == 0)
   {
      return -1;
   }

   //
   // Get the total number of chunks.
   //
   uiChunkCount = PAL_MKFGetChunkCount(fpRngMKF);
   if (uiRngNum >= uiChunkCount)
   {
      return -1;
   }

   //
   // Get the offset of the chunk.
   //
   _fseek(fpRngMKF, 4 * uiRngNum, SEEK_SET);
   _fread(&uiOffset, sizeof(UINT), 1, fpRngMKF);
   _fread(&uiNextOffset, sizeof(UINT), 1, fpRngMKF);
   uiOffset = SWAP32(uiOffset);
   uiNextOffset = SWAP32(uiNextOffset);

   //
   // Get the length of the chunk.
   //
   iChunkLen = uiNextOffset - uiOffset;
   if (iChunkLen != 0)
   {
      _fseek(fpRngMKF, uiOffset, SEEK_SET);
   }
   else
   {
      return -1;
   }

   //
   // Get the number of sub chunks.
   //
   _fread(&uiChunkCount, sizeof(UINT), 1, fpRngMKF);
   uiChunkCount = (SWAP32(uiChunkCount) - 4) / 4;
   if (uiFrameNum >= uiChunkCount)
   {
      return -1;
   }

   //
   // Get the offset of the sub chunk.
   //
   _fseek(fpRngMKF, uiOffset + 4 * uiFrameNum, SEEK_SET);
   _fread(&uiSubOffset, sizeof(UINT), 1, fpRngMKF);
   _fread(&uiNextOffset, sizeof(UINT), 1, fpRngMKF);
   uiSubOffset = SWAP32(uiSubOffset);
   uiNextOffset = SWAP32(uiNextOffset);

   //
   // Get the length of the sub chunk.
   //
   iChunkLen = uiNextOffset - uiSubOffset;
   if ((UINT)iChunkLen > uiBufferSize)
   {
      return -2;
   }
   if (iChunkLen != 0)
   {
      _fseek(fpRngMKF, uiOffset + uiSubOffset, SEEK_SET);
      _fread(lpBuffer, iChunkLen, 1, fpRngMKF);
   }
   else
   {
      return -1;
   }

   return iChunkLen;
}