static void mmap_read(uint64_t id, void *addr){ hold_lock hl(mmap_lock, false); //dbgpf("MM2: MMAP read at %p.\n", addr); if(mmappings->has_key(id)){ mmapping m = (*mmappings)[id]; bt_filesize_t pos = fs_seek(m.file, 0, FS_Relative); if(addr < m.page_addr || addr > m.page_addr + (m.pages * MM2_Page_Size)) panic("(MM2) Out-of range memory-mapped read!"); uint32_t flags = MM2_PageFlags::Present | MM2_PageFlags::Writable; if((uint32_t)m.addr >= MM2_Kernel_Boundary) flags |= MM2_PageFlags::Usermode; void *pageaddr = (void*)((uint32_t)addr & MM2_Address_Mask); bt_filesize_t readofs = ((uint32_t)pageaddr - (uint32_t)m.page_addr) + m.page_offset; //dbgpf("MM2: Reading page from %i at %p.\n", (int)readofs, pageaddr); sch_hold_proc(); current_pagedir->map_page_at(pageaddr, flags); bt_filesize_t npos = fs_seek(m.file, readofs, FS_Set); if(npos != readofs) panic("(MM2) MMAP Seek failed!"); bt_filesize_t rd = fs_read(m.file, MM2_Page_Size, (char*)pageaddr); if(rd != MM2_Page_Size) panic("(MM2) MMAP Read failed!"); fs_seek(m.file, pos, FS_Set); sch_unhold_proc(); }else{ panic("(MM2) Invalid MMAP read request!"); } }
static off_t http_seek(uint32 hnd, off_t offset, int whence) { HTTPContext *s = (HTTPContext *)hnd; file_t hd; //printf("http_seek %d %d\n", offset, whence); if (whence == SEEK_SET) { whence = SEEK_CUR; offset = offset - s->tread; } if (whence == SEEK_CUR) { int pos = fs_seek(s->hd, 0, SEEK_CUR); int res = fs_seek(s->hd, offset, SEEK_CUR) - pos; //printf("http_seek res = %d\n", res); s->tread += res; return s->tread; } if (whence != SEEK_SET) return -1; fs_close(s->hd); s->hd = -1; //printf("location = '%s'\n", s->location); hd = fs_open(s->location, O_RDWR); if (hd<0) { printf("http_seek : could not reconnect to '%s'\n", s->location); goto fail; } s->hd = hd; if (http_connect(s, s->path, s->hoststr, s->flags, 0) < 0) goto fail; if (offset) { int pos = fs_seek(s->hd, 0, SEEK_CUR); s->tread = fs_seek(s->hd, offset, SEEK_CUR) - pos; //printf("http_seek res = %d\n", s->tread); return s->tread; } s->tread = 0; return 0; fail: printf("http_seek : failed reopen\n"); if (s->hd >= 0) fs_close(s->hd); s->hd = 0; return -1; }
int main(int argc, char *argv[]) { uint32_t wav_buf[WAV_HEADER_SIZE / 4 + 1]; struct wav_info wav_info; off_t file_end, data_off; char *caf = NULL; char *wav = NULL; if (argc > 1) caf = argv[1]; if (argc > 2) wav = argv[2]; if (caf == NULL) { fputs("Usage: test <caf> [wav]\n", stderr); return 1; } if (load(caf) < 0) return 1; if (wav != NULL) { if ((wav_fd = fs_open(wav, FS_CREAT | FS_TRUNC | FS_WRONLY)) < 0) perror("Open failed"); else { fs_write(wav_fd, wav_buf, WAV_HEADER_SIZE); data_off = fs_seek(wav_fd, 0, FS_SEEK_CUR); assert(data_off == WAV_HEADER_SIZE); } } play(); if (wav_fd > 0) { file_end = fs_seek(wav_fd, 0, FS_SEEK_CUR); fs_seek(wav_fd, 0, FS_SEEK_SET); wav_info.blocks = NULL; wav_info.size = file_end - data_off; wav_info.sample_rate = ima_info.sample_rate; wav_info.frame_count = ima_info.frame_count; wav_info.sample_format = WAV_FORMAT_INT16; wav_info.channel_count = ima_info.channel_count; wav_write(wav_buf, &wav_info); fs_write(wav_fd, wav_buf, WAV_HEADER_SIZE); fs_close(wav_fd); } return 0; }
static void e_jpgskipdata(j_decompress_ptr cinfo,long numbytes) { e_jpgsource_t* src=(e_jpgsource_t*)cinfo->src; if(numbytes>0) fs_seek(src->file,numbytes,FS_SEEK_CUR); }
int fs_sync (fs_t *fs, int force) { int i; if (! fs->writable) return 0; if (! force && ! fs->dirty) return 1; time (&fs->utime); if (! fs_seek (fs, 0)) return 0; if (! fs_write32 (fs, FSMAGIC1)) /* magic word */ return 0; if (! fs_write32 (fs, fs->isize)) /* size in blocks of I list */ return 0; if (! fs_write32 (fs, fs->fsize)) /* size in blocks of entire volume */ return 0; if (! fs_write32 (fs, fs->swapsz)) /* size in blocks of swap area */ return 0; if (! fs_write32 (fs, fs->nfree)) /* number of in core free blocks */ return 0; for (i=0; i<NICFREE; ++i) { /* in core free blocks */ if (! fs_write32 (fs, fs->free[i])) return 0; } if (! fs_write32 (fs, fs->ninode)) /* number of in core I nodes */ return 0; for (i=0; i<NICINOD; ++i) { /* in core free I nodes */ if (! fs_write32 (fs, fs->inode[i])) return 0; } if (! fs_write32 (fs, fs->flock)) return 0; if (! fs_write32 (fs, fs->fmod)) return 0; if (! fs_write32 (fs, fs->ilock)) return 0; if (! fs_write32 (fs, fs->ronly)) return 0; if (! fs_write32 (fs, fs->utime)) /* current date of last update */ return 0; if (! fs_write32 (fs, fs->tfree)) /* total free blocks */ return 0; if (! fs_write32 (fs, fs->tinode)) /* total free inodes */ return 0; if (! fs_write (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN)) return 0; /* ordinary file mounted on */ if (! fs_write32 (fs, 0)) /* lasti*/ return 0; if (! fs_write32 (fs, 0)) /* nbehind */ return 0; if (! fs_write32 (fs, 0)) /* flags */ return 0; if (! fs_write32 (fs, FSMAGIC2)) /* magic word */ return 0; fs->dirty = 0; return 1; }
uint32 gzip_get_file_size(const char *filename) { file_t fd; uint32 len; uint32 size; fd = fs_open(filename, O_RDONLY); if(fd < 0) return 0; if(fs_seek(fd, -4, SEEK_END) <= 0) { fs_close(fd); return 0; } len = fs_read(fd, &size, sizeof(size)); fs_close(fd); if(len != 4) { return 0; } return size; }
/* Common code for both fat_read and fat_write */ static int vmdfs_fat_read(const char *vmdfile, vmd_root_t * root, uint16 * fat_buf) { uint16 fat_block, fat_size; /* Find the FAT starting block and length */ fat_block = root->fat_loc; fat_size = root->fat_size; /* We can't reliably handle VMDs with a larger FAT... */ if(fat_size > 1) { dbglog(DBG_ERROR, "vmdfs_fat_read: VMD has >1 (%d) FAT blocks\n",(int)fat_size); return -1; } file_t f = fs_open(vmdfile,O_RDONLY); fs_seek(f,fat_block*BLOCK_SIZE,SEEK_SET); fs_read(f,(uint8 *)fat_buf,BLOCK_SIZE); fs_close(f); if(!*fat_buf) { dbglog(DBG_ERROR, "vmdfs_fat_read: can't read block %d\n",(int)fat_block); return -2; } return 0; }
static int SDLCALL dc_seek(SDL_RWops *context, int offset, int whence) { off_t pos; int dc_whence; switch (whence) { case RW_SEEK_SET: dc_whence = SEEK_SET; break; case RW_SEEK_CUR: dc_whence = SEEK_CUR; break; case RW_SEEK_END: dc_whence = SEEK_END; break; default: SDL_SetError("dc_seek: Unknown value for 'whence'"); return -1; } pos = fs_seek(context->hidden.dc.fd, offset, dc_whence); if ( pos < 0 ) { SDL_Error(SDL_EFSEEK); return(-1); } return pos; }
static int check_gdi_image(file_t fd) { char line[MAX_FN_LEN]; uint32 track_count; fs_seek(fd, 0, SEEK_SET); if(fs_gets(fd, line, MAX_FN_LEN) == NULL) { #ifdef DEBUG dbglog(DBG_DEBUG, "%s: Not a GDI image\n", __func__); #endif return -1; } track_count = strtoul(line, NULL, 0); if(track_count == 0 || track_count > 99) { #ifdef DEBUG dbglog(DBG_DEBUG, "%s: Invalid GDI image\n", __func__); #endif return -1; } return (int)track_count; }
bool fs_getData( S_FPATH *fp, S_FSTREAM *fs, S_FINFO *fi ) { fs->start=fsstart; fs->size=fssize+6; fs->pos=0; if( !fstream_read( fs, (iu8 *)fi, sizeof(S_FINFO) ) ) return FALSE; fs->start=fsstart+FS_HEADER_SIZE; fs->size=fssize; fs->pos=0; if( !fs_seek( fp->df, fs, fi, FS_TYPE_DF ) ) return FALSE; if( !fs_seek( fp->ef, fs, fi, FS_TYPE_EF ) ) return FALSE; return TRUE; }
CISO_header_t *ciso_open(file_t fd) { if(check_cso_image(fd) < 0) { return NULL; } int ret; uint32 *magic; CISO_header_t *hdr; hdr = (CISO_header_t*)malloc(sizeof(CISO_header_t)); if(hdr == NULL) { return NULL; } memset_sh4(hdr, 0, sizeof(CISO_header_t)); hdr->magic[0] = '\0'; fs_seek(fd, 0, SEEK_SET); ret = fs_read(fd, hdr, sizeof(CISO_header_t)); if(ret != sizeof(CISO_header_t)) { free(hdr); return NULL; } magic = (uint32*)hdr->magic; #ifdef DEBUG dbglog(DBG_DEBUG, "Magic: %c%c%c%c\n", hdr->magic[0], hdr->magic[1], hdr->magic[2], hdr->magic[3]); dbglog(DBG_DEBUG, "Hdr size: %u\n", hdr->header_size); dbglog(DBG_DEBUG, "Total bytes: %u\n", hdr->total_bytes); dbglog(DBG_DEBUG, "Block size: %u\n", hdr->block_size); dbglog(DBG_DEBUG, "Version: %02x\n", hdr->ver); dbglog(DBG_DEBUG, "Align: %d\n", 1 << hdr->align); #endif if(*magic == CISO_MAGIC_CISO) { ; } else if(*magic == CISO_MAGIC_ZISO) { if(lzo_init() != LZO_E_OK) { ds_printf("DS_ERROR: lzo_init() failed\n"); free(hdr); hdr = NULL; } } else { free(hdr); hdr = NULL; } return hdr; }
GNUC_NONNULL_ALL static void add_zip (const char *filename, GNUC_UNUSED void *data) { fs_file_t *f = NULL; bool error = true; uint8_t *dir = NULL; if (unlikely(!fs_open_unsafe(filename, &f, FS_MODE_RDONLY, true))) { return; } size_t size; if (unlikely(!fs_get_size(f, &size) || size <= ZIP_ENTRY_SIZE + sizeof(zip_end_header_t))) { fs_print_error(f, "bad size"); goto done; } zip_end_header_t end; if (unlikely(!get_end_header(f, size, &end))) { fs_print_error(f, "can\'t find end of central dir"); goto done; } if (unlikely(end.disk || end.disk_wcd)) { fs_print_error(f, "multivolume zip; not supported"); goto done; } zip_t *z; if (unlikely(!(dir = mem_alloc(fs_mem_pool, end.size)) || !fs_seek(f, end.offset, FS_ORIGIN_START) || !fs_read(f, dir, end.size, NULL, "central dir read failed") || !parse_dir(f, dir, &end, &z))) { fs_print_error(f, "failed to parse central directory"); goto done; } z->f = f; z->next = zips; zips = z; qsort(z->files, z->num_files, sizeof(z->files[0]), cmp_file_zip); g_message("added \"%s\" with %i files", filename, z->num_files); error = false; done: if (error) { fs_close(f); } mem_free(dir); }
static int check_cso_image(file_t fd) { uint32 magic = 0; fs_seek(fd, 0, SEEK_SET); fs_read(fd, &magic, sizeof(magic)); if(magic != CISO_MAGIC_CISO && magic != CISO_MAGIC_ZISO) { return -1; } return 0; }
int fs_read_block (fs_t *fs, unsigned bnum, unsigned char *data) { if (verbose > 3) printf ("read block %d\n", bnum); if (bnum < fs->isize) return 0; if (! fs_seek (fs, bnum * BSDFS_BSIZE)) return 0; if (! fs_read (fs, data, BSDFS_BSIZE)) return 0; return 1; }
/* ================= eflac_decoder_seek ================= */ static FLAC__StreamDecoderSeekStatus eflac_decoder_seek (GNUC_UNUSED const FLAC__StreamDecoder *decoder, FLAC__uint64 abs_offset, void *client_data) { snd_stream_t *s = client_data; int offset = (int)abs_offset; if (offset == fs_seek(s->file, offset, FS_START)) return FLAC__STREAM_DECODER_SEEK_STATUS_OK; return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; }
static void do_mapping(mmapping &m){ bt_filesize_t pos = fs_seek(m.file, 0, FS_Relative); if(m.size <= MM2_Page_Size){ //dbgpf("MM2: Reading %i bytes from %i to %p.\n", (int)m.size, (int)m.offset, (void*)m.addr); fs_seek(m.file, m.offset, FS_Set); fs_read(m.file, m.size, m.addr); fs_seek(m.file, pos, FS_Set); return; } if(m.pre){ fs_seek(m.file, m.offset, FS_Set); fs_read(m.file, m.pre, m.addr); //dbgpf("MM2: Loading pre (%i bytes) from offset %i at %p.\n", (int)m.pre, (int)m.offset, (void*)m.addr); } if(m.post){ bt_filesize_t postoffset = m.page_offset + (m.pages * MM2_Page_Size); char *postaddr = (char*)((uint32_t)m.page_addr + (m.pages * MM2_Page_Size)); fs_seek(m.file, postoffset, FS_Set); fs_read(m.file, m.post, postaddr); //dbgpf("MM2: Loading post (%i bytes) from offset %i at %p.\n", (int)m.post, (int)postoffset, (void*)postaddr); } current_pagedir->free_pages((void*)m.page_addr, m.pages); for(size_t i = 0; i < m.pages; ++i){ current_pagedir->guard_page_at(m.page_addr + (i * MM2_Page_Size)); } fs_seek(m.file, pos, FS_Set); }
e_texture_t* e_loadtexture(e_device_t* device,int mipmaps,fs_handle_t file) { //Try to load the texture as a png first e_texture_t* texture; texture=e_loadpng(device,mipmaps,file); if(!texture) { //Restart stream and try to read as JPG fs_seek(file,0,FS_SEEK_SET); return e_loadjpg(device,mipmaps,file); } return texture; }
int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data) { if (verbose > 3) printf ("write block %d\n", bnum); if (! fs->writable || bnum < fs->isize) return 0; if (! fs_seek (fs, bnum * BSDFS_BSIZE)) return 0; if (! fs_write (fs, data, BSDFS_BSIZE)) return 0; fs->modified = 1; return 1; }
static int f_seek (lua_State *L) { static const int mode[] = {FS_SEEK_SET, FS_SEEK_CUR, FS_SEEK_END}; static const char *const modenames[] = {"set", "cur", "end", NULL}; int f = tofile(L); int op = luaL_checkoption(L, 2, "cur", modenames); long offset = luaL_optlong(L, 3, 0); op = fs_seek(f, offset, mode[op]); if (op) return pushresult(L, 0, NULL); /* error */ else { lua_pushinteger(L, fs_tell(f)); return 1; } }
static int vmdfs_file_read(const char *vmdfile, uint16 * fat, vmd_dir_t * dirent, void * outbuf) { int curblk, blkleft; uint8 * out; out = (uint8 *)outbuf; /* Find the first block */ curblk = dirent->firstblk; /* And the blocks remaining */ blkleft = dirent->filesize; /* While we've got stuff remaining... */ while(blkleft > 0) { /* Make sure the FAT matches up with the directory */ if(curblk == 0xfffc || curblk == 0xfffa) { char fn[13] = {0}; memcpy(fn, dirent->filename, 12); dbglog(DBG_ERROR, "vmdfs_file_read: file '%s' ends prematurely in fat\n",fn); return -1; } /* Read the block */ file_t f = fs_open(vmdfile,O_RDONLY); fs_seek(f,curblk*BLOCK_SIZE,SEEK_SET); int rv = fs_read(f,(uint8 *)out,BLOCK_SIZE); fs_close(f); if(rv != BLOCK_SIZE) { dbglog(DBG_ERROR, "vmdfs_file_read: can't read block %d\n",curblk); return -2; } /* Scoot our counters */ curblk = fat[curblk]; blkleft--; out += 512; } /* Make sure the FAT matches up with the directory */ if(curblk != 0xfffa) { char fn[13] = {0}; memcpy(fn, dirent->filename, 12); dbglog(DBG_ERROR, "vmdfs_file_read: file '%s' is sized shorter than in the FAT\n",fn); return -3; } return 0; }
static int file_seek (lua_State *L) { static const int mode[] = {FS_SEEK_SET, FS_SEEK_CUR, FS_SEEK_END}; static const char *const modenames[] = {"set", "cur", "end", NULL}; if((FS_OPEN_OK - 1)==file_fd) return luaL_error(L, "open a file first"); int op = luaL_checkoption(L, 1, "cur", modenames); long offset = luaL_optlong(L, 2, 0); op = fs_seek(file_fd, offset, mode[op]); if (op) lua_pushnil(L); /* error */ else lua_pushinteger(L, fs_tell(file_fd)); return 1; }
int gdi_read_sectors(GDI_header_t *hdr, uint8 *buff, uint32 start, uint32 count) { uint16 sector_size; uint32 offset = gdi_get_offset(hdr, start, §or_size); if(offset == (uint32)-1) { return -1; } #ifdef DEBUG dbglog(DBG_DEBUG, "%s: %ld %ld at %ld mode %d\n", __func__, start, count, offset, sector_size); #endif fs_seek(hdr->track_fd, offset, SEEK_SET); return read_sectors_data(hdr->track_fd, count, sector_size, buff); }
GNUC_NONNULL_ALL static bool seek_file_zip (fs_zip_file_t *f) { if (unlikely(!f->zip->f)) { return false; } uint32_t position_in_zip = f->zipfile->offset_in_zip + f->position_zipped; if (f->zip->position != position_in_zip) { if (unlikely(!fs_seek(f->zip->f, (fs_offset_t)position_in_zip, FS_ORIGIN_START))) { return false; } f->zip->position = position_in_zip; } return true; }
static bool fs_zip_open (const char *name, fs_file_t **file, GNUC_UNUSED fs_open_mode_e mode) { struct { const char *name; }search = { .name = name }; ZIPS_ITERATOR(z) { zip_file_t *f = bsearch(&search, z->files, z->num_files, sizeof(*f), cmp_file_zip); if (f) { fs_zip_file_t *zipfile; size_t buffer_size = (f->compressed ? fs_zip_file_buffer_size : fs_zip_file_uncompressed); zipfile = mem_alloc(fs_mem_pool, sizeof(*zipfile) + buffer_size); zipfile->zip = z; zipfile->zipfile = f; if (!f->calculated_offset) { uint8_t tmp[ZIP_CHUNK_SIZE]; if (unlikely(!fs_seek(z->f, f->offset_in_zip, FS_ORIGIN_START) || !fs_read(z->f, tmp, sizeof(tmp), NULL, "file info read failed") || ZIP_DATA_ID != be_puint32(tmp))) { g_critical("failed to calculate real offset"); break; } f->offset_in_zip += ZIP_CHUNK_SIZE + le_puint16(tmp + 26) + le_puint16(tmp + 28); f->calculated_offset = true; } if (unlikely(f->compressed && Z_OK != inflateInit2(&zipfile->stream, -MAX_WBITS))) { g_critical("inflateInit2 failed"); break; } *file = &zipfile->common; return true; } } return false; }
static Elf32_Shdr *elfgetshdr(fileio_ctx_t *fsctx,void *ref,Elf32_Ehdr *ep) { Elf32_Shdr *shtab; unsigned size = ep->e_shnum * sizeof(Elf32_Shdr); shtab = (Elf32_Shdr *) KMALLOC(size,0); if (!shtab) { return NULL; } if (fs_seek(fsctx,ref,ep->e_shoff,FILE_SEEK_BEGINNING) != ep->e_shoff || fs_read(fsctx,ref,(uint8_t *)shtab,size) != size) { KFREE(shtab); return NULL; } return (shtab); }
/* Common code for both dir_read and dir_write */ static int vmdfs_dir_read(const char *vmdfile, vmd_root_t * root, vmd_dir_t * dir_buf) { uint16 dir_block, dir_size; unsigned int i; int needsop;//, rv; int write = 0; /* Find the directory starting block and length */ dir_block = root->dir_loc; dir_size = root->dir_size; /* The dir is stored backwards, so we start at the end and go back. */ while(dir_size > 0) { if(write) { /* Scan this block for changes */ for(i = 0, needsop = 0; i < 512 / sizeof(vmd_dir_t); i++) { if(dir_buf[i].dirty) { needsop = 1; } dir_buf[i].dirty = 0; } } else needsop = 1; if(needsop) { if(!write){ file_t f = fs_open(vmdfile,O_RDONLY); fs_seek(f,dir_block*BLOCK_SIZE,SEEK_SET); fs_read(f,(uint8 *)dir_buf,BLOCK_SIZE); fs_close(f); } } dir_block--; dir_size--; dir_buf += 512 / sizeof(vmd_dir_t); /* == 16 */ } return 0; }
int ciso_get_blocks(CISO_header_t *hdr, file_t fd, uint *blocks, uint32 sector, uint32 cnt) { #ifdef DEBUG dbglog(DBG_DEBUG, "%s: fd=%d seek=%u\n", __func__, fd, sizeof(CISO_header_t) + (sector * sizeof(uint))); #endif int r = 0; //uint len = (uint)(hdr->total_bytes / hdr->block_size) + 1; fs_seek(fd, sizeof(CISO_header_t) + (sector * sizeof(uint)), SEEK_SET); r = fs_read(fd, blocks, sizeof(uint) * cnt); #ifdef DEBUG int i; for(i = 0; i < cnt; i++) dbglog(DBG_DEBUG, " blocks[%d]=%08u\n", i, blocks[i]); #endif return r; }
GNUC_NONNULL_ALL static bool get_end_header (fs_file_t *f, uint32_t size, zip_end_header_t *end) { uint8_t *tmp = NULL; bool error = true; // read the end of the file with central dir in it uint32_t end_size = MIN(size, ZIP_COMMENTS_SIZE_MAX + sizeof(*end)); tmp = mem_alloc(fs_mem_pool, end_size); if (unlikely(!tmp || !fs_seek(f, size - end_size, FS_ORIGIN_START) || !fs_read(f, tmp, end_size, NULL, "end header read failed"))) { goto done; } // find zip header end for (uint32_t i = end_size - sizeof(*end); i > 0; i--) { if (be_puint32(tmp + i) == ZIP_END_ID) { memcpy(end, &tmp[i], sizeof(*end)); LE_UINT16(end->disk); LE_UINT16(end->disk_wcd); LE_UINT16(end->disk_num_entries); LE_UINT16(end->total_num_entries); LE_UINT32(end->size); LE_UINT32(end->offset); error = false; break; } } done: mem_free(tmp); return !error; }
static void flush_mapping(mmapping &m){ pid_t curpid = proc_current_pid; proc_switch(m.pid); bt_filesize_t pos = fs_seek(m.file, 0, FS_Relative); if(m.size <= MM2_Page_Size){ fs_seek(m.file, m.offset, FS_Set); fs_write(m.file, m.size, m.addr); fs_seek(m.file, pos, FS_Set); proc_switch(curpid); return; } if(m.pre){ fs_seek(m.file, m.offset, FS_Set); fs_write(m.file, m.pre, m.addr); } if(m.post){ bt_filesize_t postoffset = m.page_offset + (m.pages * MM2_Page_Size); char *postaddr = (char*)((uint32_t)m.page_addr + (m.pages * MM2_Page_Size)); fs_seek(m.file, postoffset, FS_Set); fs_write(m.file, m.post, postaddr); } for(size_t i = 0; i < m.pages; ++i){ char *pageaddr = m.page_addr + (i * MM2_Page_Size); if(current_pagedir->is_mapped(pageaddr)){ bt_filesize_t fileoffset = m.page_offset + (i * MM2_Page_Size); fs_seek(m.file, fileoffset, FS_Set); fs_write(m.file, MM2_Page_Size, pageaddr); current_pagedir->free_pages(pageaddr, 1); } current_pagedir->guard_page_at(pageaddr); } fs_seek(m.file, pos, FS_Set); proc_switch(curpid); }
bool fs_create( S_FINFO *fi ) { S_FPATH fp; S_FSTREAM fs; S_FINFO fitmp; iu8 size, dfend; if( fi->fid==0x3F00 ) { sw_set( SW_FILE_EXISTS ); return FALSE; } if( (!fi->size) || (fi->size>0x7FFF) || (fi->fid==0xFFFF) || ((fi->type!=FS_TYPE_DF) && (fi->type!=FS_TYPE_EF)) ) { sw_set( SW_WRONG_DATA ); return FALSE; } if( selected.ef!=0xFFFF ) { selected.ef=0xFFFF; } if( (fi->type==FS_TYPE_DF) && (selected.df!=0xFFFF) ) { sw_set( SW_WRONG_DATA ); return FALSE; } /* Get end of DF */ memcpy( &fp, &selected, sizeof(selected) ); if( !fs_getData( &fp, &fs, &fitmp ) ) return FALSE; dfend = fs.start+fs.size; /* Look if file exists already */ if( fi->type==FS_TYPE_DF ) fp.df=fi->fid; else fp.ef=fi->fid; if( fs_getData( &fp, &fs, &fitmp ) ) { sw_set( SW_FILE_EXISTS ); return FALSE; } /* Begin with MF */ fs.start=fsstart+FS_HEADER_SIZE; fs.size=fssize; fs.pos=0; if( selected.df!=0xFFFF ) { if( !fs_seek( selected.df, &fs, &fitmp, FS_TYPE_DF ) ) return FALSE; } /* Seek to free data */ if( !fs_seekEnd( &fs ) ) return FALSE; if( (fs.pos+FS_HEADER_SIZE+fi->size+sizeof(iu16))>fs.size ) { sw_set( SW_FILE_TO_SHORT ); return FALSE; } /* Set fs to file dimensions. */ fs.start+=fs.pos; fs.size=FS_HEADER_SIZE+fi->size+sizeof(iu16); fs.pos=sizeof(iu16); /* Clear all */ memset( &fitmp, 0, sizeof(fitmp) ); while( fs.pos<fs.size ) { size=(fs.size-fs.pos)<sizeof(fitmp) ? fs.size-fs.pos : sizeof(fitmp); if( !fstream_write( &fs, (iu8*)&fitmp, size ) ) return FALSE; } /* Write file header */ #if CONF_WITH_TRANSACTIONS==1 if( !( ta_setdata( (iu8*)fi, sizeof(S_FINFO), fs.start ) && ta_commit() ) ) return FALSE; #else /* !CONF_WITH_TRANSACTIONS==1 */ fs.pos=0; if( !fstream_write( &fs, (iu8*)fi, sizeof(S_FINFO) ) ) return FALSE; #endif /* !CONF_WITH_TRANSACTIONS==1 */ return TRUE; }