3 * Specific support functions
5 * Copyright (C) 1997 Martin von Löwis
6 * Copyright (C) 1997 Régis Duchesne
13 #include "ntfstypes.h"
18 #include <linux/slab.h>
19 #include <linux/locks.h>
20 #include <linux/nls.h>
25 static char print_buf
[1024];
29 #include <linux/kernel.h>
31 /* Debugging output */
32 void ntfs_debug(int mask
, const char *fmt
, ...)
36 /* Filter it with the debugging level required */
39 strcpy(print_buf
, KERN_DEBUG
);
40 vsprintf(print_buf
+ 3, fmt
, ap
);
48 void *ntfs_malloc(int size
)
52 ret
= kmalloc(size
, GFP_KERNEL
);
53 ntfs_debug(DEBUG_MALLOC
, "Allocating %x at %p\n", size
, ret
);
61 void ntfs_free(void *block
)
63 ntfs_debug(DEBUG_MALLOC
, "Freeing memory at %p\n", block
);
68 void ntfs_debug(int mask
, const char *fmt
, ...)
73 void *ntfs_malloc(int size
)
75 return kmalloc(size
, GFP_KERNEL
);
80 void ntfs_free(void *block
)
87 void ntfs_bzero(void *s
, int n
)
92 /* These functions deliberately return no value. It is dest, anyway,
93 and not used anywhere in the NTFS code. */
95 void ntfs_memcpy(void *dest
, const void *src
, ntfs_size_t n
)
100 void ntfs_memmove(void *dest
, const void *src
, ntfs_size_t n
)
102 memmove(dest
, src
, n
);
105 /* Warn that an error occured. */
106 void ntfs_error(const char *fmt
,...)
111 strcpy(print_buf
, KERN_ERR
);
112 vsprintf(print_buf
+ 3, fmt
, ap
);
117 int ntfs_read_mft_record(ntfs_volume
*vol
, int mftno
, char *buf
)
122 ntfs_debug(DEBUG_OTHER
, "read_mft_record %x\n",mftno
);
125 ntfs_memcpy(buf
,vol
->mft
,vol
->mft_recordsize
);
130 printk("ntfs:something is terribly wrong here\n");
136 io
.size
=vol
->mft_recordsize
;
137 error
=ntfs_read_attr(vol
->mft_ino
,vol
->at_data
,NULL
,
138 mftno
*vol
->mft_recordsize
,&io
);
139 if(error
|| (io
.size
!=vol
->mft_recordsize
))
141 ntfs_debug(DEBUG_OTHER
, "read_mft_record: read %x failed (%d,%d,%d)\n",
142 mftno
,error
,io
.size
,vol
->mft_recordsize
);
143 return error
?error
:ENODATA
;
145 ntfs_debug(DEBUG_OTHER
, "read_mft_record: finished read %x\n",mftno
);
146 if(!ntfs_check_mft_record(vol
,buf
))
148 printk("Invalid MFT record for %x\n",mftno
);
151 ntfs_debug(DEBUG_OTHER
, "read_mft_record: Done %x\n",mftno
);
155 int ntfs_getput_clusters(ntfs_volume
*vol
, int cluster
, ntfs_size_t start_offs
,
158 struct super_block
*sb
=NTFS_SB(vol
);
159 struct buffer_head
*bh
;
161 int length
=buf
->size
;
163 ntfs_debug(DEBUG_OTHER
, "get_clusters %d %d %d\n",cluster
,start_offs
,length
);
165 ntfs_debug(DEBUG_OTHER
, "put_clusters %d %d %d\n",cluster
,start_offs
,length
);
168 if(!(bh
=bread(sb
->s_dev
,cluster
,vol
->clustersize
)))
170 ntfs_debug(DEBUG_OTHER
, "%s failed\n", buf
->do_read
?"Reading":"Writing");
173 to_copy
=min(vol
->clustersize
-start_offs
,length
);
176 buf
->fn_put(buf
,bh
->b_data
+start_offs
,to_copy
);
179 buf
->fn_get(bh
->b_data
+start_offs
,buf
,to_copy
);
180 mark_buffer_dirty(bh
,1);
191 ntfs_time64_t
ntfs_now(void)
193 return ntfs_unixutc2ntutc(CURRENT_TIME
);
196 /* when printing unicode characters base64, use this table.
197 It is not strictly base64, but the Linux vfat encoding.
198 base64 has the disadvantage of using the slash.
200 static char uni2esc
[64]=
201 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-";
207 if(c
<='9')return c
-'0';
209 if(c
<='Z')return c
-'A'+10;
211 if(c
<='z')return c
-'a'+36;
217 int ntfs_dupuni2map(ntfs_volume
*vol
, ntfs_u16
*in
, int in_len
, char **out
,
222 struct nls_table
* nls
=vol
->nls_map
;
224 result
=ntfs_malloc(in_len
+1);
225 if(!result
)return ENOMEM
;
228 for(i
=o
=0;i
<in_len
;i
++){
230 unsigned char* uni_page
;
231 /* FIXME: byte order */
233 ch
=(in
[i
] >> 8) & 0xFF;
240 uni_page
=nls
->page_uni2charset
[ch
];
241 if(uni_page
&& uni_page
[cl
]){
242 result
[o
++]=uni_page
[cl
];
246 if(!(vol
->nct
& nct_uni_xlate
))goto inval
;
248 buf
=ntfs_malloc(*out_len
+3);
253 memcpy(buf
,result
,o
);
258 if(vol
->nct
& nct_uni_xlate_vfat
){
260 result
[o
+2]=uni2esc
[val
& 0x3f];
262 result
[o
+1]=uni2esc
[val
& 0x3f];
264 result
[o
]=uni2esc
[val
& 0x3f];
268 result
[o
++]=uni2esc
[val
& 0x3f];
270 result
[o
++]=uni2esc
[val
& 0x3f];
272 result
[o
++]=uni2esc
[val
& 0x3f];
283 int ntfs_dupmap2uni(ntfs_volume
*vol
, char* in
, int in_len
, ntfs_u16
**out
,
288 struct nls_table
* nls
=vol
->nls_map
;
290 *out
=result
=ntfs_malloc(2*in_len
);
291 if(!result
)return ENOMEM
;
293 for(i
=o
=0;i
<in_len
;i
++,o
++){
294 unsigned short cl
,ch
;
295 if(in
[i
]!=':' || (vol
->nct
& nct_uni_xlate
)==0){
296 cl
=nls
->charset2uni
[(unsigned char)in
[i
]].uni1
;
297 ch
=nls
->charset2uni
[(unsigned char)in
[i
]].uni2
;
299 unsigned char c1
,c2
,c3
;
304 if(c1
==255 || c2
==255 || c3
==255)
306 else if(vol
->nct
& nct_uni_xlate_vfat
){
307 cl
= (c1
<< 4) + (c2
>> 2);
308 ch
= ((c2
& 0x3) << 6) + c3
;
310 ch
=(c3
<< 4) + (c2
>> 2);
311 cl
=((c2
& 0x3) << 6) + c1
;
314 /* FIXME: byte order */
315 result
[o
] = (ch
<<8) | cl
;
326 * c-file-style: "linux"