status_t fs_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) { nspace *ns = (nspace*)_vol->private_volume; attrdircookie *cookie = (attrdircookie *)_cookie; status_t result = B_NO_ERROR; ERRPRINT("%s - ENTER\n", __FUNCTION__); LOCK_VOL(ns); if (cookie->ctx) ntfs_attr_put_search_ctx(cookie->ctx); cookie->ctx = ntfs_attr_get_search_ctx(cookie->inode, NULL); if (cookie->ctx == NULL) { result = errno; //goto exit; } //exit: ERRPRINT("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); return result; }
status_t fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, void *buffer, size_t *len) { nspace *ns = (nspace *)_vol->private_volume; //vnode *node = (vnode *)_node->private_node; attrcookie *cookie = (attrcookie *)_cookie; ntfs_inode *ni = cookie->inode; ntfs_attr *na = cookie->stream; size_t size = *len; int total = 0; status_t result = B_NO_ERROR; if (pos < 0) { *len = 0; return EINVAL; } LOCK_VOL(ns); ERRPRINT("%s - ENTER\n", __FUNCTION__); // it is a named stream if (na) { if (pos + size > na->data_size) size = na->data_size - pos; while (size) { off_t bytesRead = ntfs_attr_pread(na, pos, size, buffer); if (bytesRead < (s64)size) { ntfs_log_error("ntfs_attr_pread returned less bytes than " "requested.\n"); } if (bytesRead <= 0) { *len = 0; result = EINVAL; goto exit; } size -= bytesRead; pos += bytesRead; total += bytesRead; } *len = total; } else { *len = 0; result = ENOENT; // TODO } fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_ATIME); // XXX needed ? exit: ERRPRINT("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); return result; }
status_t fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) { nspace *ns = (nspace*)_vol->private_volume; vnode *node = (vnode*)_node->private_node; attrdircookie *cookie = NULL; ntfs_inode *ni = NULL; ntfs_attr_search_ctx *ctx = NULL; status_t result = B_NO_ERROR; ERRPRINT("%s - ENTER\n", __FUNCTION__); LOCK_VOL(ns); ni = ntfs_inode_open(ns->ntvol, node->vnid); if (ni == NULL) { result = errno; goto exit; } ctx = ntfs_attr_get_search_ctx(ni, NULL); if (ctx == NULL) { result = errno; goto exit; } cookie = (attrdircookie*)ntfs_calloc(sizeof(attrdircookie)); if (cookie == NULL) { result = ENOMEM; goto exit; } cookie->inode = ni; cookie->ctx = ctx; ni = NULL; ctx = NULL; *_cookie = cookie; exit: if (ctx) ntfs_attr_put_search_ctx(ctx); if (ni) ntfs_inode_close(ni); ERRPRINT("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); return result; }
status_t fs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *stbuf) { nspace *ns = (nspace*)_vol->private_volume; vnode *node = (vnode*)_node->private_node; ntfs_inode *ni = NULL; ntfs_attr *na; status_t result = B_NO_ERROR; LOCK_VOL(ns); ERRPRINT("fs_rstat - ENTER:\n"); if (ns == NULL || node == NULL ||stbuf == NULL) { result = ENOENT; goto exit; } ni = ntfs_inode_open(ns->ntvol, node->vnid); if (ni == NULL) { result = ENOENT; goto exit; } if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) { // Directory stbuf->st_mode = FS_DIR_MODE; na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4); if (na) { stbuf->st_size = na->data_size; stbuf->st_blocks = na->allocated_size >> 9; ntfs_attr_close(na); } stbuf->st_nlink = 1; } else {
status_t set_mime(vnode *node, const char *filename) { struct ext_mime *p; int32 namelen, ext_len; ERRPRINT("set_mime - for [%s]\n", filename); node->mime = NULL; namelen = strlen(filename); for (p=mimes;p->extension;p++) { ext_len = strlen(p->extension); if (namelen <= ext_len) continue; if (filename[namelen-ext_len-1] != '.') continue; if (!strcasecmp(filename + namelen - ext_len, p->extension)) break; } node->mime = p->mime; return B_NO_ERROR; }
uint64_t Util_GetTime(void) { double retval=0; char tmp[64]={0x0}; uint64_t u64MillSec = 0; if(s_psTimeFile == NULL){ s_psTimeFile = fopen("/proc/uptime", "r"); if(s_psTimeFile == NULL){ perror("fopen(/proc/uptime)"); return 0; } } while(u64MillSec == 0){ fseek(s_psTimeFile, 0, SEEK_SET); fflush(s_psTimeFile); fgets(tmp, sizeof(tmp), s_psTimeFile); retval=atof(tmp); //fscanf u64MillSec = (uint64_t)(retval*1000); if(u64MillSec == 0){ ERRPRINT("Get time, but return value is %f \n", retval); } } return u64MillSec; }
void check_bitvec_to_int( vartype *bv, int len, int expected ) { if (bitvec_to_int( bv, len ) != expected) { ERRPRINT( "Unexpected return value of bitvec_to_int" ); fprintf( stderr, "bitvec_to_int( " ); print_arr( stderr, bv, len ); fprintf( stderr, ", %d ) != 0x%X\n\n", len, expected ); abort(); } }
status_t fs_write_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter) { nspace *ns = (nspace*)_vol->private_volume; vnode *node = (vnode*)_node->private_node; status_t result = B_NO_ERROR; if (!reenter) LOCK_VOL(ns); ERRPRINT("fs_write_vnode - ENTER (%Ld)\n", node->vnid); free(node); ERRPRINT("fs_write_vnode - EXIT\n"); if (!reenter) UNLOCK_VOL(ns); return result; }
void test_int_to_bitvec() { check_int_to_bitvec( 0, 1 ); check_int_to_bitvec( 0xA, 4 ); /* Check error conditions */ if (int_to_bitvec( 2, 0 ) != NULL) { ERRPRINT( "Unexpected return value of int_to_bitvec" ); fprintf( stderr, "int_to_bitvec( 2, 0 ) did not return NULL.\n" ); abort(); } }
status_t fs_rfsstat(fs_volume *_vol, struct fs_info *fss) { nspace *ns = (nspace*)_vol->private_volume; int i; LOCK_VOL(ns); ERRPRINT("fs_rfsstat - ENTER\n"); ntfs_calc_free_space(ns); fss->dev = ns->id; fss->root = FILE_root; fss->flags = B_FS_IS_PERSISTENT | B_FS_HAS_MIME | B_FS_HAS_ATTR | ns->flags; fss->block_size = ns->ntvol->cluster_size; fss->io_size = 65536; fss->total_blocks = ns->ntvol->nr_clusters; fss->free_blocks = ns->free_clusters; strncpy(fss->device_name, ns->devicePath, sizeof(fss->device_name)); strncpy(fss->volume_name, ns->ntvol->vol_name, sizeof(fss->volume_name)); for (i = strlen(fss->volume_name) - 1; i >=0 ; i--) { if (fss->volume_name[i] != ' ') break; } if (i < 0) strcpy(fss->volume_name, "NTFS Untitled"); else fss->volume_name[i + 1] = 0; strcpy(fss->fsh_name, "NTFS"); ERRPRINT("fs_rfsstat - EXIT\n"); UNLOCK_VOL(ns); return B_NO_ERROR; }
status_t fs_remove_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter) { nspace *ns = (nspace*)_vol->private_volume; vnode *node = (vnode*)_node->private_node; status_t result = B_NO_ERROR; // TODO: this does not look right! The space if the node must be freed *here* if (!reenter) LOCK_VOL(ns); ERRPRINT("fs_remove_vnode - ENTER (%Ld)\n", node->vnid); free(node); ERRPRINT("fs_remove_vnode - EXIT, result is %s\n", strerror(result)); if (!reenter) UNLOCK_VOL(ns); return result; }
float fs_identify_partition(int fd, partition_data *partition, void **_cookie) { NTFS_BOOT_SECTOR boot; identify_cookie *cookie; ntfs_volume *ntVolume; uint8 *buf = (uint8*)&boot; char devpath[256]; // read in the boot sector ERRPRINT("fs_identify_partition: read in the boot sector\n"); if (read_pos(fd, 0, (void*)&boot, 512) != 512) { return -1; } // check boot signature if ((buf[0x1fe] != 0x55 || buf[0x1ff] != 0xaa) && buf[0x15] == 0xf8) return -1; // check boot signature NTFS if (memcmp(buf + 3, "NTFS ", 8) != 0) return -1; // get path for device if (!ioctl(fd, B_GET_PATH_FOR_DEVICE, devpath)) return -1; // try mount ntVolume = utils_mount_volume(devpath, MS_RDONLY, true); if (!ntVolume) return -1; // allocate identify_cookie cookie = (identify_cookie *)malloc(sizeof(identify_cookie)); if (!cookie) return -1; memcpy(&cookie->boot, &boot, 512); strcpy(cookie->label, "NTFS Volume"); if (ntVolume->vol_name && ntVolume->vol_name[0] != '\0') strcpy(cookie->label, ntVolume->vol_name); ntfs_umount(ntVolume, true); *_cookie = cookie; return 0.8f; }
ERRCODE OSS_PlaySetVolume( uint32_t u32Volume // [in] Set volume 0 ~ 0x3F ) { if ((int32_t)u32Volume < OSS_VOLUME_MIN) u32Volume = OSS_VOLUME_MIN; if (u32Volume > OSS_VOLUME_MAX) u32Volume = OSS_VOLUME_MAX; if (u32Volume == g_u32NMPlayer_Volume) return ERR_OSS_NONE; FUN_MUTEX_LOCK(&s_sOSSFunMutex); if (s_i32DSPFD < 0) { FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); return ERR_OSS_DEV; } if (s_i32MixerFD < 0) { s_i32MixerFD = open("/dev/mixer", O_RDWR); if (s_i32MixerFD < 0) { ERRPRINT("open(/dev/mixer) failed"); close(s_i32DSPFD); FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); return ERR_OSS_DEV; } // if } if (s_i32MixerFD >= 0) { const int i32Volume = (u32Volume << 8) | u32Volume; // H/L: Right/Left if (ioctl(s_i32MixerFD, MIXER_WRITE(SOUND_MIXER_PCM), &i32Volume) < 0) { perror("ioctl(/dev/mixer, MIXER_WRITE(SOUND_MIXER_PCM)) failed"); return ERR_OSS_VOLUME; } // if g_u32NMPlayer_Volume = u32Volume; close(s_i32MixerFD); s_i32MixerFD = -1; } // if FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); return ERR_OSS_NONE; }
void check_int_to_bitvec( int x, int vec_len ) { int k; /* counter */ int actual = 0; vartype *bv = int_to_bitvec( x, vec_len ); for (k = 0; k < vec_len; k++) { if (*(bv+k) != 0) actual += 1 << k; } if (actual != x) { ERRPRINT( "Unexpected return value of int_to_bitvec" ); fprintf( stderr, "int_to_bitvec( %d, %d ) returned ", x, vec_len ); print_arr( stderr, bv, vec_len ); fprintf( stderr, "\n" ); abort(); } free( bv ); }
status_t fs_wfsstat(fs_volume *_vol, const struct fs_info *fss, uint32 mask) { nspace* ns = (nspace*)_vol->private_volume; status_t result = B_NO_ERROR; if (ns->flags & B_FS_IS_READONLY) { ERRPRINT("ntfs is read-only\n"); return EROFS; } LOCK_VOL(ns); if (mask & FS_WRITE_FSINFO_NAME) { result = ntfs_change_label(ns->ntvol, (char*)fss->volume_name); goto exit; } exit: UNLOCK_VOL(ns); return result; }
status_t fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, ino_t *_rootID) { nspace *ns; vnode *newNode = NULL; char lockname[32]; void *handle; unsigned long mountFlags = 0; status_t result = B_NO_ERROR; ERRPRINT("fs_mount - ENTER\n"); ns = ntfs_malloc(sizeof(nspace)); if (!ns) { result = ENOMEM; goto exit; } *ns = (nspace) { .state = NF_FreeClustersOutdate | NF_FreeMFTOutdate, .show_sys_files = false, .ro = false, .flags = 0 }; strcpy(ns->devicePath,device); sprintf(lockname, "ntfs_lock %lx", ns->id); recursive_lock_init_etc(&(ns->vlock), lockname, MUTEX_FLAG_CLONE_NAME); handle = load_driver_settings("ntfs"); ns->show_sys_files = ! (strcasecmp(get_driver_parameter(handle, "hide_sys_files", "true", "true"), "true") == 0); ns->ro = strcasecmp(get_driver_parameter(handle, "read_only", "false", "false"), "false") != 0; ns->noatime = strcasecmp(get_driver_parameter(handle, "no_atime", "true", "true"), "true") == 0; unload_driver_settings(handle); if (ns->ro || (flags & B_MOUNT_READ_ONLY) != 0) { mountFlags |= MS_RDONLY; ns->flags |= B_FS_IS_READONLY; } // TODO: this does not take read-only volumes into account! ns->ntvol = utils_mount_volume(device, mountFlags, true); if (ns->ntvol != NULL) result = B_NO_ERROR; else result = errno; if (result == B_NO_ERROR) { *_rootID = FILE_root; ns->id = _vol->id; _vol->private_volume = (void *)ns; _vol->ops = &gNTFSVolumeOps; newNode = (vnode*)ntfs_calloc(sizeof(vnode)); if (newNode == NULL) result = ENOMEM; else { newNode->vnid = *_rootID; newNode->parent_vnid = -1; result = publish_vnode(_vol, *_rootID, (void*)newNode, &gNTFSVnodeOps, S_IFDIR, 0); if (result != B_NO_ERROR) { free(ns); result = EINVAL; goto exit; } else { result = B_NO_ERROR; ntfs_mark_free_space_outdated(ns); ntfs_calc_free_space(ns); } } } exit: ERRPRINT("fs_mount - EXIT, result code is %s\n", strerror(result)); return result; } status_t fs_unmount(fs_volume *_vol) { nspace *ns = (nspace*)_vol->private_volume; status_t result = B_NO_ERROR; ERRPRINT("fs_unmount - ENTER\n"); ntfs_umount(ns->ntvol, true); recursive_lock_destroy(&(ns->vlock)); free(ns); ERRPRINT("fs_unmount - EXIT, result is %s\n", strerror(result)); return result; }
ERRCODE OSS_PlayOpen( S_NM_AUDIOCTX *psCtx // [in] Audio context. ) { int32_t i32DSPFD = -1; int32_t i32MixerFD = -1; int32_t i32OSS_Format = AFMT_S16_LE; int32_t i32Volume = 0x2020; int32_t i32DSPBlockSize; FUN_MUTEX_LOCK(&s_sOSSFunMutex); if (psCtx == NULL) { FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); return ERR_OSS_CTX; } if (s_i32DSPFD > 0) { s_i32PlayRefCnt ++; FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); DEBUGPRINT("s_i32PlayRefCnt %d ++++++++++++++++++++\n", s_i32PlayRefCnt); return ERR_OSS_NONE; } if (psCtx->ePCMType != eNM_PCM_S16LE) { FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); return ERR_OSS_CTX; } i32DSPFD = open(DEF_OSS_SPK, O_RDWR); if (i32DSPFD < 0) { ERRPRINT("open failed" DEF_OSS_SPK); i32DSPFD = open("/dev/dsp2", O_RDWR); if (i32DSPFD < 0) { ERRPRINT("open(/dev/dsp2) failed"); FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); return ERR_OSS_DEV; } } // if i32MixerFD = open("/dev/mixer", O_RDWR); if (i32MixerFD < 0) { ERRPRINT("open(/dev/mixer) failed"); close(i32DSPFD); FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); return ERR_OSS_DEV; } // if ioctl(i32DSPFD, SNDCTL_DSP_SETFMT, &i32OSS_Format); ioctl(i32MixerFD, MIXER_WRITE(SOUND_MIXER_VOLUME), &i32Volume); ioctl(i32DSPFD, SNDCTL_DSP_SPEED, &psCtx->u32SampleRate); ioctl(i32DSPFD, SNDCTL_DSP_CHANNELS, &psCtx->u32ChannelNum); ioctl(i32DSPFD, SNDCTL_DSP_GETBLKSIZE, &i32DSPBlockSize); s_i32DSPFD = i32DSPFD; s_i32MixerFD = i32MixerFD; s_i32DSPBlockSize = i32DSPBlockSize; g_u32NMPlayer_Volume = 0x20; s_i32PlayRefCnt ++; close(s_i32MixerFD); s_i32MixerFD = -1; FUN_MUTEX_UNLOCK(&s_sOSSFunMutex); return ERR_OSS_NONE; }
status_t fs_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, struct dirent *entry, size_t bufsize, uint32 *num) { nspace *ns = (nspace *)_vol->private_volume; vnode *node = (vnode *)_node->private_node; char *name = NULL; attrdircookie *cookie = (attrdircookie *)_cookie; uint32 numEntries = 0; status_t result = B_NO_ERROR; if (cookie->ctx == NULL) panic("cookie->ctx == NULL"); LOCK_VOL(ns); ERRPRINT("%s - ENTER\n", __FUNCTION__); while (!(result = ntfs_attrs_walk(cookie->ctx))) { ATTR_RECORD *attr = cookie->ctx->attr; if (attr->type == AT_DATA) { // it's the actual file body if (attr->name_length == 0) continue; name = ntfs_attr_name_get((const ntfschar *)(((char *)attr) + attr->name_offset), attr->name_length); dprintf("found AT_DATA '%s'\n", name); bufsize = MIN(bufsize, sizeof(struct dirent) + strlen(name) + 1); entry->d_ino = node->vnid; entry->d_dev = ns->id; entry->d_reclen = sizeof(struct dirent) + strlen(name); //XXX size strcpy(entry->d_name, name); ntfs_attr_name_free(&name); numEntries++; if (numEntries >= *num) break; break; } } if (result && errno != ENOENT) { result = errno; goto exit; } else { result = B_OK; } exit: ERRPRINT("%s - EXIT, result is %s, *num %d\n", __FUNCTION__, strerror(result), *num); UNLOCK_VOL(ns); if (result) *num = 0; else *num = numEntries; return result; }
int main( int argc, char **argv ) { char *result; FILE *fp; char filename[STRING_MAXLEN]; char instr[STRING_MAXLEN]; anode_t *head, *node, *out_node; vartype state[2], next_state[2]; strcpy( filename, "temp_automaton_io_dumpXXXXXX" ); result = mktemp( filename ); if (result == NULL) { perror( "test_automaton_io, mktemp" ); abort(); } fp = fopen( filename, "w+" ); if (fp == NULL) { perror( "test_automaton_io, fopen" ); abort(); } fprintf( fp, REF_GR1CAUT_TRIVIAL ); if (fseek( fp, 0, SEEK_SET )) { perror( "test_automaton_io, fseek" ); abort(); } /* Load in "gr1c automaton" format */ head = aut_aut_load( 2, fp ); if (head == NULL) { ERRPRINT( "Failed to read 3-node automaton in \"gr1c automaton\" format." ); abort(); } /* Check number of nodes, labels, and outgoing edges */ if (aut_size( head ) != 3) { ERRPRINT1( "size 3 automaton detected as having size %d.", aut_size( head ) ); abort(); } state[0] = 1; state[1] = 0; node = find_anode( head, 0, state, 2 ); if (node == NULL) { ERRPRINT2( "could not find expected node with state [%d %d].", state[0], state[1] ); abort(); } if (node->rgrad != 2) { ERRPRINT1( "node should have reach annotation value of 2 but actually has %d", node->rgrad ); abort(); } state[0] = 0; state[1] = 0; out_node = find_anode( head, 0, state, 2 ); if (out_node == NULL) { ERRPRINT2( "could not find expected node with state [%d %d].", state[0], state[1] ); abort(); } if (out_node->rgrad != 1) { ERRPRINT1( "node should have reach annotation value of 1 but actually has %d", out_node->rgrad ); abort(); } if (node->trans_len != 2) { ERRPRINT1( "node should have 2 outgoing transitions but actually has %d.", node->trans_len ); abort(); } if (*(node->trans) != out_node && *(node->trans+1) != out_node) { ERRPRINT( "an edge is missing." ); abort(); } /* Modify the automaton and dump the result */ *(node->trans+1) = node; state[0] = 0; state[1] = 1; head = insert_anode( head, 0, -1, False, state, 2 ); if (head == NULL) { ERRPRINT( "failed to insert new node into automaton." ); abort(); } next_state[0] = 1; next_state[1] = 0; head = append_anode_trans( head, 0, state, 2, 0, next_state ); if (head == NULL) { ERRPRINT( "failed to append transition to new node." ); abort(); } fclose( fp ); fp = fopen( filename, "w+" ); if (fp == NULL) { perror( "test_automaton_io, fopen" ); abort(); } aut_aut_dump( head, 2, fp ); if (fseek( fp, 0, SEEK_SET )) { perror( "test_automaton_io, fseek" ); abort(); } /* NB, assumed width may cause problems if we start using Unicode. */ if (fread( instr, sizeof(char), strlen(REF_GR1CAUT_TRIVIAL_MOD), fp ) < strlen(REF_GR1CAUT_TRIVIAL_MOD)) { ERRPRINT( "output of aut_aut_dump is too short." ); abort(); } if (!strncmp( instr, REF_GR1CAUT_TRIVIAL_MOD, strlen(REF_GR1CAUT_TRIVIAL_MOD) )) { ERRPRINT( "output of aut_aut_dump does not match expectation." ); abort(); } fclose( fp ); if (remove( filename )) { perror( "test_automaton_io, remove" ); abort(); } return 0; }
status_t fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, int openMode, void **_cookie) { nspace *ns = (nspace*)_vol->private_volume; vnode *node = (vnode*)_node->private_node; attrcookie *cookie = NULL; ntfschar *uname = NULL; int ulen; ntfs_inode *ni = NULL; ntfs_attr *na = NULL; status_t result = B_NO_ERROR; ERRPRINT("%s - ENTER\n", __FUNCTION__); LOCK_VOL(ns); if (node == NULL) { result = EINVAL; goto exit; } ni = ntfs_inode_open(ns->ntvol, node->vnid); if (ni == NULL) { result = errno; goto exit; } // UXA demangling TODO // check for EA first... TODO: WRITEME // check for a named stream if (true) { uname = ntfs_calloc(MAX_PATH); ulen = ntfs_mbstoucs(name, &uname); if (ulen < 0) { result = EILSEQ; goto exit; } na = ntfs_attr_open(ni, AT_DATA, uname, ulen); if (na) { if (openMode & O_TRUNC) { if (ntfs_attr_truncate(na, 0)) result = errno; } } } cookie = (attrcookie*)ntfs_calloc(sizeof(attrcookie)); if (cookie != NULL) { cookie->omode = openMode; *_cookie = (void*)cookie; cookie->inode = ni; cookie->stream = na; ni = NULL; na = NULL; } else result = ENOMEM; exit: if (uname) free(uname); if (na) ntfs_attr_close(na); if (ni) ntfs_inode_close(ni); ERRPRINT("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); return result; }
status_t fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie,off_t pos, const void *buffer, size_t *_length) { nspace *ns = (nspace *)_vol->private_volume; //vnode *node = (vnode *)_node->private_node; attrcookie *cookie = (attrcookie *)_cookie; ntfs_inode *ni = cookie->inode; ntfs_attr *na = cookie->stream; size_t size = *_length; int total = 0; status_t result = B_NO_ERROR; ERRPRINT("%s - ENTER!!\n", __FUNCTION__); if (ns->flags & B_FS_IS_READONLY) { ERRPRINT("ntfs is read-only\n"); return EROFS; } if (pos < 0) { *_length = 0; return EINVAL; } LOCK_VOL(ns); ERRPRINT("%s - ENTER\n", __FUNCTION__); // it is a named stream if (na) { if (cookie->omode & O_APPEND) pos = na->data_size; if (pos + size > na->data_size) { ntfs_mark_free_space_outdated(ns); if (ntfs_attr_truncate(na, pos + size)) size = na->data_size - pos; else notify_stat_changed(ns->id, MREF(ni->mft_no), B_STAT_SIZE); } while (size) { off_t bytesWritten = ntfs_attr_pwrite(na, pos, size, buffer); if (bytesWritten < (s64)size) ERRPRINT("%s - ntfs_attr_pwrite returned less bytes than requested.\n", __FUNCTION__); if (bytesWritten <= 0) { ERRPRINT(("%s - ntfs_attr_pwrite()<=0\n", __FUNCTION__)); *_length = 0; result = EINVAL; goto exit; } size -= bytesWritten; pos += bytesWritten; total += bytesWritten; } *_length = total; } else { *_length = 0; return EINVAL; } if (total > 0) fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_ATIME); // XXX needed ? exit: ERRPRINT("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); return result; }
status_t fs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type, uint32 *_flags, bool reenter) { nspace *ns = (nspace*)_vol->private_volume; vnode *newNode = NULL; ntfs_inode *ni = NULL; status_t result = B_NO_ERROR; if (!reenter) LOCK_VOL(ns); ERRPRINT("fs_read_vnode - ENTER\n"); _node->private_node = NULL; _node->ops = &gNTFSVnodeOps; _flags = 0; newNode = (vnode*)ntfs_calloc(sizeof(vnode)); if (newNode != NULL) { char *name = NULL; ni = ntfs_inode_open(ns->ntvol, vnid); if (ni == NULL) { result = ENOENT; goto exit; } // get the node type result = get_node_type(ni, _type); if (result != B_OK) goto exit; newNode->vnid = vnid; newNode->parent_vnid = ntfs_get_parent_ref(ni); if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) set_mime(newNode, ".***"); else { name = (char*)malloc(MAX_PATH); if (name != NULL) { if (utils_inode_get_name(ni, name,MAX_PATH) == 1) set_mime(newNode, name); free(name); } } _node->private_node = newNode; } else result = ENOMEM; exit: if (ni != NULL) ntfs_inode_close(ni); if (result != B_OK && newNode != NULL) free(newNode); ERRPRINT("fs_read_vnode - EXIT, result is %s\n", strerror(result)); if (!reenter) UNLOCK_VOL(ns); return result; }
status_t fs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *vnid) { nspace *ns = (nspace*)_vol->private_volume; vnode *baseNode = (vnode*)_dir->private_node; vnode *newNode = NULL; ntfschar *unicode = NULL; ntfs_inode *bi = NULL; status_t result = B_NO_ERROR; int len; LOCK_VOL(ns); ERRPRINT("fs_walk - ENTER : find for \"%s\"\n",file); if (ns == NULL || _dir == NULL || file == NULL || vnid == NULL) { result = EINVAL; goto exit; } if (!strcmp(file, ".")) { *vnid = baseNode->vnid; if (get_vnode(_vol, *vnid, (void**)&newNode) != 0) result = ENOENT; } else if (!strcmp(file, "..") && baseNode->vnid != FILE_root) { *vnid = baseNode->parent_vnid; if (get_vnode(_vol, *vnid, (void**)&newNode) != 0) result = ENOENT; } else { unicode = ntfs_calloc(MAX_PATH); len = ntfs_mbstoucs(file, &unicode); if (len < 0) { result = EILSEQ; goto exit; } bi = ntfs_inode_open(ns->ntvol, baseNode->vnid); if (!bi) { result = ENOENT; goto exit; } *vnid = MREF(ntfs_inode_lookup_by_name(bi, unicode, len)); ERRPRINT("fs_walk - VNID = %d\n",*vnid); ntfs_inode_close(bi); free(unicode); if (*vnid == (u64)-1) { result = EINVAL; goto exit; } if (get_vnode(_vol, *vnid, (void**)&newNode) != 0) result = ENOENT; if (newNode!=NULL) newNode->parent_vnid = baseNode->vnid; } exit: ERRPRINT("fs_walk - EXIT, result is %s\n", strerror(result)); UNLOCK_VOL(ns); return result; }