⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 support.c

📁 NTFS(NT文件系统) for Linux的一个实现源码
💻 C
字号:
/* *  support.c *  Specific support functions * *  Copyright (C) 1997 Martin von L鰓is *  Copyright (C) 1997 R間is Duchesne * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "ntfstypes.h"#include "struct.h"#include "support.h"#include <stdarg.h>#include <linux/slab.h>#include <linux/locks.h>#include <linux/nls.h>#include "util.h"#include "inode.h"#include "macros.h"static char print_buf[1024];#ifdef DEBUG#include "sysctl.h"#include <linux/kernel.h>/* Debugging output */void ntfs_debug(int mask, const char *fmt, ...){	va_list ap;	/* Filter it with the debugging level required */	if(ntdebug & mask){		va_start(ap,fmt);		strcpy(print_buf, KERN_DEBUG);		vsprintf(print_buf + 3, fmt, ap);		printk(print_buf);		va_end(ap);	}}#ifndef ntfs_malloc/* Verbose kmalloc */void *ntfs_malloc(int size){	void *ret;	ret = kmalloc(size, GFP_KERNEL);	ntfs_debug(DEBUG_MALLOC, "Allocating %x at %p\n", size, ret);	return ret;}#endif#ifndef ntfs_free/* Verbose kfree() */void ntfs_free(void *block){        ntfs_debug(DEBUG_MALLOC, "Freeing memory at %p\n", block);	kfree(block);}#endif#elsevoid ntfs_debug(int mask, const char *fmt, ...){}#ifndef ntfs_mallocvoid *ntfs_malloc(int size){	return kmalloc(size, GFP_KERNEL);}#endif#ifndef ntfs_freevoid ntfs_free(void *block){	kfree(block);}#endif#endif /* DEBUG */void ntfs_bzero(void *s, int n){	memset(s, 0, n);}/* These functions deliberately return no value. It is dest, anyway,   and not used anywhere in the NTFS code.  */void ntfs_memcpy(void *dest, const void *src, ntfs_size_t n){	memcpy(dest, src, n);}void ntfs_memmove(void *dest, const void *src, ntfs_size_t n){	memmove(dest, src, n);}/* Warn that an error occured. */void ntfs_error(const char *fmt,...){        va_list ap;        va_start(ap, fmt);        strcpy(print_buf, KERN_ERR);        vsprintf(print_buf + 3, fmt, ap);        printk(print_buf);        va_end(ap);}int ntfs_read_mft_record(ntfs_volume *vol, int mftno, char *buf){	int error;	ntfs_io io;	ntfs_debug(DEBUG_OTHER, "read_mft_record %x\n",mftno);	if(mftno==FILE_MFT)	{		ntfs_memcpy(buf,vol->mft,vol->mft_recordsize);		return 0;	}	if(!vol->mft_ino)	{		printk("ntfs:something is terribly wrong here\n");		return ENODATA;	} 	io.fn_put=ntfs_put;	io.fn_get=0;	io.param=buf;	io.size=vol->mft_recordsize;	error=ntfs_read_attr(vol->mft_ino,vol->at_data,NULL,			     mftno*vol->mft_recordsize,&io);	if(error || (io.size!=vol->mft_recordsize))	{		ntfs_debug(DEBUG_OTHER, "read_mft_record: read %x failed (%d,%d,%d)\n",			   mftno,error,io.size,vol->mft_recordsize);		return error?error:ENODATA;	}	ntfs_debug(DEBUG_OTHER, "read_mft_record: finished read %x\n",mftno);	if(!ntfs_check_mft_record(vol,buf))	{		printk("Invalid MFT record for %x\n",mftno);		return EINVAL;	}	ntfs_debug(DEBUG_OTHER, "read_mft_record: Done %x\n",mftno);	return 0;}int ntfs_getput_clusters(ntfs_volume *vol, int cluster,	ntfs_size_t start_offs,	 ntfs_io *buf){	struct super_block *sb=NTFS_SB(vol);	struct buffer_head *bh;	ntfs_size_t to_copy;	int length=buf->size;	if(buf->do_read)		ntfs_debug(DEBUG_OTHER, "get_clusters %d %d %d\n",cluster,start_offs,length);	else		ntfs_debug(DEBUG_OTHER, "put_clusters %d %d %d\n",cluster,start_offs,length);	while(length)	{		if(!(bh=bread(sb->s_dev,cluster,vol->clustersize)))		{			ntfs_debug(DEBUG_OTHER, "%s failed\n", buf->do_read?"Reading":"Writing");			return EIO;		}		to_copy=min(vol->clustersize-start_offs,length);		lock_buffer(bh);		if(buf->do_read)			buf->fn_put(buf,bh->b_data+start_offs,to_copy);		else		{			buf->fn_get(bh->b_data+start_offs,buf,to_copy);			mark_buffer_dirty(bh,1);		}		unlock_buffer(bh);		length-=to_copy;		start_offs=0;		cluster++;		brelse(bh);	}	return 0;}ntfs_time64_t ntfs_now(void){	return ntfs_unixutc2ntutc(CURRENT_TIME);}/* when printing unicode characters base64, use this table.   It is not strictly base64, but the Linux vfat encoding.   base64 has the disadvantage of using the slash.*/static char uni2esc[64]=  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-";static unsigned charesc2uni(char c){	if(c<'0')return 255;	if(c<='9')return c-'0';	if(c<'A')return 255;	if(c<='Z')return c-'A'+10;	if(c<'a')return 255;	if(c<='z')return c-'a'+36;	if(c=='+')return 62;	if(c=='-')return 63;	return 255;}int ntfs_dupuni2map(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,  int *out_len){	int i,o,val;	char *result,*buf;	struct nls_table* nls=vol->nls_map;	result=ntfs_malloc(in_len+1);	if(!result)return ENOMEM;	*out_len=in_len;	result[in_len]='\0';	for(i=o=0;i<in_len;i++){		int cl,ch;		unsigned char* uni_page;		/* FIXME: byte order */		cl=in[i] & 0xFF;		ch=(in[i] >> 8) & 0xFF;		if(!nls){			if(!ch){				result[o++]=cl;				continue;			}		}else{			uni_page=nls->page_uni2charset[ch];			if(uni_page && uni_page[cl]){				result[o++]=uni_page[cl];				continue;			}		}		if(!(vol->nct & nct_uni_xlate))goto inval;		/* realloc */		buf=ntfs_malloc(*out_len+3);		if( !buf ) {			ntfs_free( result );			return ENOMEM;		}		memcpy(buf,result,o);		ntfs_free(result);		result=buf;		*out_len+=3;		result[o++]=':';		if(vol->nct & nct_uni_xlate_vfat){			val=(cl<<8)+ch;			result[o+2]=uni2esc[val & 0x3f];			val>>=6;			result[o+1]=uni2esc[val & 0x3f];			val>>=6;			result[o]=uni2esc[val & 0x3f];			o+=3;		}else{			val=(ch<<8)+cl;			result[o++]=uni2esc[val & 0x3f];			val>>=6;			result[o++]=uni2esc[val & 0x3f];			val>>=6;			result[o++]=uni2esc[val & 0x3f];		}	}	*out=result;	return 0; inval:	ntfs_free(result);	*out=0;	return EILSEQ;}int ntfs_dupmap2uni(ntfs_volume *vol, char* in, int in_len, ntfs_u16 **out,  int *out_len){	int i,o;	ntfs_u16* result;	struct nls_table* nls=vol->nls_map;	*out=result=ntfs_malloc(2*in_len);	if(!result)return ENOMEM;	*out_len=in_len;	for(i=o=0;i<in_len;i++,o++){		unsigned short cl,ch;		if(in[i]!=':' || (vol->nct & nct_uni_xlate)==0){			cl=nls->charset2uni[(unsigned char)in[i]].uni1;			ch=nls->charset2uni[(unsigned char)in[i]].uni2;		}else{			unsigned char c1,c2,c3;			*out_len-=3;			c1=esc2uni(in[++i]);			c2=esc2uni(in[++i]);			c3=esc2uni(in[++i]);			if(c1==255 || c2==255 || c3==255)				cl=ch=0;			else if(vol->nct & nct_uni_xlate_vfat){				cl = (c1 << 4) + (c2 >> 2);				ch = ((c2 & 0x3) << 6) + c3;			}else{				ch=(c3 << 4) + (c2 >> 2);				cl=((c2 & 0x3) << 6) + c1;			}		}					/* FIXME: byte order */		result[o] = (ch<<8) | cl;		if(!result[o]){			ntfs_free(result);			return EILSEQ;		}	}	return 0;}/* * Local variables: * c-file-style: "linux" * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -