static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d) { struct inode *res=0; char *item=0; ntfs_iterate_s walk; int error; ntfs_debug(DEBUG_NAME1, "Looking up %s in %x\n",d->d_name.name, (unsigned)dir->i_ino); /* convert to wide string */ error=ntfs_decodeuni(NTFS_INO2VOL(dir),(char*)d->d_name.name, d->d_name.len,&walk.name,&walk.namelen); if(error) return ERR_PTR(-error); item=ntfs_malloc(ITEM_SIZE); if( !item ) return ERR_PTR(-ENOMEM); /* ntfs_getdir will place the directory entry into item, and the first long long is the MFT record number */ walk.type=BY_NAME; walk.dir=NTFS_LINO2NINO(dir); walk.result=item; if(ntfs_getdir_byname(&walk)) { res=iget(dir->i_sb,NTFS_GETU32(item)); } d_add(d,res); ntfs_free(item); ntfs_free(walk.name); /* Always return success, the dcache will handle negative entries. */ return NULL; }
static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d) { struct inode *res = 0; char *item = 0; ntfs_iterate_s walk; int err; ntfs_debug(DEBUG_NAME1, __FUNCTION__ "(): Looking up %s in directory " "ino 0x%x.\n", d->d_name.name, (unsigned)dir->i_ino); walk.name = NULL; walk.namelen = 0; /* Convert to wide string. */ err = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name, d->d_name.len, &walk.name, &walk.namelen); if (err) goto err_ret; item = ntfs_malloc(ITEM_SIZE); if (!item) { err = -ENOMEM; goto err_ret; } /* ntfs_getdir will place the directory entry into item, and the first * long long is the MFT record number. */ walk.type = BY_NAME; walk.dir = NTFS_LINO2NINO(dir); walk.result = item; if (ntfs_getdir_byname(&walk)) res = iget(dir->i_sb, NTFS_GETU32(item)); d_add(d, res); ntfs_free(item); ntfs_free(walk.name); /* Always return success, the dcache will handle negative entries. */ return NULL; err_ret: ntfs_free(walk.name); return ERR_PTR(err); }
/** * is_boot_sector_ntfs - check an NTFS boot sector for validity * @b: buffer containing bootsector to check * * Check whether @b contains a valid NTFS boot sector. * Return 1 if @b is a valid NTFS bootsector or 0 if not. */ static int is_boot_sector_ntfs(ntfs_u8 *b) { ntfs_u32 i; /* FIXME: We don't use checksumming yet as NT4(SP6a) doesn't either... * But we might as well have the code ready to do it. (AIA) */ #if 0 /* Calculate the checksum. */ if (b < b + 0x50) { ntfs_u32 *u; ntfs_u32 *bi = (ntfs_u32 *)(b + 0x50); for (u = bi, i = 0; u < bi; ++u) i += NTFS_GETU32(*u); } #endif /* Check magic is "NTFS " */ if (b[3] != 0x4e) goto not_ntfs; if (b[4] != 0x54) goto not_ntfs; if (b[5] != 0x46) goto not_ntfs; if (b[6] != 0x53) goto not_ntfs; for (i = 7; i < 0xb; ++i) if (b[i] != 0x20) goto not_ntfs; /* Check bytes per sector value is between 512 and 4096. */ if (b[0xb] != 0) goto not_ntfs; if (b[0xc] > 0x10) goto not_ntfs; /* Check sectors per cluster value is valid. */ switch (b[0xd]) { case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128: break; default: goto not_ntfs; } /* Check reserved sectors value and four other fields are zero. */ for (i = 0xe; i < 0x15; ++i) if (b[i] != 0) goto not_ntfs; if (b[0x16] != 0) goto not_ntfs; if (b[0x17] != 0) goto not_ntfs; for (i = 0x20; i < 0x24; ++i) if (b[i] != 0) goto not_ntfs; /* Check clusters per file record segment value is valid. */ if (b[0x40] < 0xe1 || b[0x40] > 0xf7) { switch (b[0x40]) { case 1: case 2: case 4: case 8: case 16: case 32: case 64: break; default: goto not_ntfs; } } /* Check clusters per index block value is valid. */ if (b[0x44] < 0xe1 || b[0x44] > 0xf7) { switch (b[0x44]) { case 1: case 2: case 4: case 8: case 16: case 32: case 64: break; default: goto not_ntfs; } } return 1; not_ntfs: return 0; }
static int ntfs_printcb(ntfs_u8 *entry, void *param) { unsigned long inum = NTFS_GETU64(entry) & 0xffffffffffff; struct ntfs_filldir *nf = param; u32 flags = NTFS_GETU32(entry + 0x48); char show_sys_files = 0; u8 name_len = NTFS_GETU8(entry + 0x50); u8 name_type = NTFS_GETU8(entry + 0x51); int err; unsigned file_type; switch (nf->type) { case ngt_dos: /* Don't display long names. */ if (!(name_type & 2)) return 0; break; case ngt_nt: /* Don't display short-only names. */ if ((name_type & 3) == 2) return 0; break; case ngt_posix: break; case ngt_full: show_sys_files = 1; break; default: BUG(); } err = ntfs_encodeuni(NTFS_INO2VOL(nf->dir), (ntfs_u16*)(entry + 0x52), name_len, &nf->name, &nf->namelen); if (err) { ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Skipping " "unrepresentable file.\n"); err = 0; goto err_ret; } if (!show_sys_files && inum < 0x10UL) { ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Skipping system " "file (%s).\n", nf->name); err = 0; goto err_ret; } /* Do not return ".", as this is faked. */ if (nf->namelen == 1 && nf->name[0] == '.') { ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Skipping \".\"\n"); err = 0; goto err_ret; } nf->name[nf->namelen] = 0; if (flags & 0x10000000) /* FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT */ file_type = DT_DIR; else file_type = DT_REG; ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Calling filldir for %s with " "len %i, f_pos 0x%Lx, inode %lu, %s.\n", nf->name, nf->namelen, (loff_t)(nf->ph << 16) | nf->pl, inum, file_type == DT_DIR ? "DT_DIR" : "DT_REG"); /* * Userspace side of filldir expects an off_t rather than an loff_t. * And it also doesn't like the most significant bit being set as it * then considers the value to be negative. Thus this implementation * limits the number of index records to 32766, which should be plenty. */ err = nf->filldir(nf->dirent, nf->name, nf->namelen, (loff_t)(nf->ph << 16) | nf->pl, inum, file_type); if (err) nf->ret_code = err; err_ret: nf->namelen = 0; ntfs_free(nf->name); nf->name = NULL; return err; }
static int ntfs_printcb(ntfs_u8 *entry,void *param) { struct ntfs_filldir* nf=param; int flags=NTFS_GETU8(entry+0x51); int show_hidden=0; int length=NTFS_GETU8(entry+0x50); int inum=NTFS_GETU32(entry); int error; #ifdef NTFS_NGT_NT_DOES_LOWER int i,to_lower=0; #endif switch(nf->type){ case ngt_dos: /* Don't display long names */ if((flags & 2)==0) return 0; break; case ngt_nt: /* Don't display short-only names */ switch(flags&3){ case 2: return 0; #ifdef NTFS_NGT_NT_DOES_LOWER case 3: to_lower=1; #endif } break; case ngt_posix: break; case ngt_full: show_hidden=1; break; } if(!show_hidden && ((NTFS_GETU8(entry+0x48) & 2)==2)){ ntfs_debug(DEBUG_OTHER,"Skipping hidden file\n"); return 0; } nf->name=0; if(ntfs_encodeuni(NTFS_INO2VOL(nf->dir),(ntfs_u16*)(entry+0x52), length,&nf->name,&nf->namelen)){ ntfs_debug(DEBUG_OTHER,"Skipping unrepresentable file\n"); if(nf->name)ntfs_free(nf->name); return 0; } /* Do not return ".", as this is faked */ if(length==1 && *nf->name=='.') return 0; #ifdef NTFS_NGT_NT_DOES_LOWER if(to_lower) for(i=0;i<nf->namelen;i++) /* This supports ASCII only. Since only DOS-only names get converted, and since those are restricted to ASCII, this should be correct */ if(nf->name[i]>='A' && nf->name[i]<='Z') nf->name[i]+='a'-'A'; #endif nf->name[nf->namelen]=0; ntfs_debug(DEBUG_OTHER, "readdir got %s,len %d\n",nf->name,nf->namelen); /* filldir expects an off_t rather than an loff_t. Hope we don't have more than 65535 index records */ error=nf->filldir(nf->dirent,nf->name,nf->namelen, (nf->ph<<16)|nf->pl,inum,DT_UNKNOWN); ntfs_free(nf->name); /* Linux filldir errors are negative, other errors positive */ return error; }