diff -u ../task-1.60/src/fstools/ffind.c src/fstools/ffind.c --- ../task-1.60/src/fstools/ffind.c Tue Jan 7 01:08:55 2003 +++ src/fstools/ffind.c Fri Feb 28 02:38:24 2003 @@ -46,6 +46,7 @@ */ #include "fs_tools.h" #include "error.h" +#include "ntfs.h" /* NTFS has an optimized version of this function */ extern void ntfs_find_file (FS_INFO *, INUM_T, int, FS_DENT_WALK_FN, char *); @@ -54,6 +55,7 @@ usage(char *myProg) { printf("usage: %s [-aduvV] [-f fstype] image inode\n", myProg); + printf("\t-8: Use UTF-8 to display NTFS filename\n"); printf("\t-a: Find all occurrences\n"); printf("\t-d: Find deleted entries ONLY\n"); printf("\t-u: Find undeleted entries ONLY\n"); @@ -105,8 +107,11 @@ extern int optind; progname= argv[0]; - while ((ch = getopt(argc, argv, "adf:uvV")) > 0) { + while ((ch = getopt(argc, argv, "8adf:uvV")) > 0) { switch (ch) { + case '8': + uni2dos = uni2utf8; + break; case 'a': localflags |= FIND_ALL; break; diff -u ../task-1.60/src/fstools/fls.c src/fstools/fls.c --- ../task-1.60/src/fstools/fls.c Mon Jan 13 07:03:21 2003 +++ src/fstools/fls.c Fri Feb 28 02:42:06 2003 @@ -56,9 +56,10 @@ void usage(char *myProg) { - printf("usage: %s [-adDFlpruvV] [-f fstype] [-m dir/] [-z ZONE] [-s seconds] image [inode]\n", + printf("usage: %s [-8adDFlpruvV] [-f fstype] [-m dir/] [-z ZONE] [-s seconds] image [inode]\n", myProg); printf("\tIf [inode] is not given, the root directory is used\n"); + printf("\t-8: Use UTF-8 to display NTFS filename\n"); printf("\t-a: Display \".\" and \"..\" entries\n"); printf("\t-d: Display deleted entries only\n"); printf("\t-D: Display directory entries only\n"); @@ -271,11 +272,14 @@ localFlags = LCL_DIR | LCL_FILE; - while ((ch = getopt(argc, argv, "adDf:Fm:lprs:uvVz:")) > 0) { + while ((ch = getopt(argc, argv, "8adDf:Fm:lprs:uvVz:")) > 0) { switch (ch) { case '?': default: usage(argv[0]); + case '8': + uni2dos = uni2utf8; + break; case 'a': localFlags |= LCL_DOT; break; diff -u ../task-1.60/src/fstools/fsstat.c src/fstools/fsstat.c --- ../task-1.60/src/fstools/fsstat.c Tue Jan 7 01:08:56 2003 +++ src/fstools/fsstat.c Wed Mar 5 03:50:49 2003 @@ -9,6 +9,7 @@ */ #include "fs_tools.h" #include "error.h" +#include "ntfs.h" FILE *logfp; @@ -17,7 +18,8 @@ static void usage(char *prog) { - printf("usage: %s [-vV] [-f fstype] image\n", prog); + printf("usage: %s [-8vV] [-f fstype] image\n", prog); + printf("\t-8: Use UTF-8 to display NTFS filename\n"); printf("\t-v: verbose output to stderr\n"); printf("\t-V: Print version\n"); printf("\t-f fstype: Image file system type\n"); @@ -36,7 +38,7 @@ FS_INFO *fs; progname = argv[0]; - while ((ch = getopt(argc, argv, "f:vV")) > 0) { + while ((ch = getopt(argc, argv, "f:8vV")) > 0) { switch (ch) { case '?': default: @@ -45,6 +47,10 @@ case 'f': fstype = optarg; break; + + case '8': + uni2dos = uni2utf8; + break; case 'v': verbose++; diff -u ../task-1.60/src/fstools/istat.c src/fstools/istat.c --- ../task-1.60/src/fstools/istat.c Mon Jan 13 07:03:59 2003 +++ src/fstools/istat.c Fri Feb 28 02:45:39 2003 @@ -50,6 +50,7 @@ #include "fs_tools.h" #include "error.h" #include +#include "ntfs.h" FILE *logfp; @@ -82,7 +83,8 @@ /* usage - explain and terminate */ static void usage() { - printf("usage: %s [-b num] [-f fstype] [-z zone] [-s seconds] [-vV] image inum\n", progname); + printf("usage: %s [-b num] [-f fstype] [-z zone] [-s seconds] [-8vV] image inum\n", progname); + printf("\t-8: Use UTF-8 to display NTFS filename\n"); printf("\t-v: verbose output to stderr\n"); printf("\t-V: print version\n"); printf("\t-b num: force the display of NUM address of block pointers\n"); @@ -110,10 +112,13 @@ progname = argv[0]; - while ((ch = getopt(argc, argv, "b:f:s:vVz:")) > 0) { + while ((ch = getopt(argc, argv, "8b:f:s:vVz:")) > 0) { switch (ch) { default: usage(); + case '8': + uni2dos = uni2utf8; + break; case 'b': numblock = atoi(optarg); if (numblock < 1) { diff -u ../task-1.60/src/fstools/ntfs.c src/fstools/ntfs.c --- ../task-1.60/src/fstools/ntfs.c Mon Jan 13 06:58:16 2003 +++ src/fstools/ntfs.c Fri Feb 28 02:48:30 2003 @@ -30,6 +30,11 @@ */ +/* what to convert UCS-2 filename to? the default is to ASCII */ +void +(*uni2dos)(char *, int, char *, int) = uni2ascii; + + /* needs to be predefined for proc_attrseq */ static void ntfs_proc_attrlist(NTFS_INFO *, FS_INODE *, FS_DATA *); @@ -130,6 +135,57 @@ return; } +/* + * Convert a UNICODE string to an UTF-8 string + * + * both uni and asc must be defined + */ +void +uni2utf8(char *ucs2, int ucs2len, char *utf8, int utf8len) +{ + int utf8pos, ucs2pos, maxlen; + + /* find the maximum that we can go + * we will break when we hit NULLs, but this is the + * absolute max + */ + if (((utf8len - 1) / 3 ) < ucs2len) + maxlen = (utf8len - 1) / 3; + else + maxlen = ucs2len; + + utf8pos = 0; ucs2pos = 0; + + while (ucs2pos < maxlen) { + unsigned short *ucs2p = (unsigned short *)ucs2; + /* If this value is NULL, then stop */ + if (ucs2p[ucs2pos] == 0) + break; + /* If this value is NULL, then stop */ + + if (ucs2p[ucs2pos] <= 0x7f) { + utf8[utf8pos] = ucs2p[ucs2pos] & 0x007f; + utf8pos++; + } + else if (ucs2p[ucs2pos] <= 0x7ff) { + utf8[utf8pos] = 0xc0 | ((ucs2p[ucs2pos] & 0x7c0) >> 6); + utf8[utf8pos+1] = 0x80 | (ucs2p[ucs2pos] & 0x003f); + utf8pos = utf8pos + 2; + } + else if (ucs2p[ucs2pos] > 0x800) { + utf8[utf8pos] = 0xe0 | ((ucs2p[ucs2pos] & 0xf000) >> 12); + utf8[utf8pos+1] = 0x80 | (ucs2p[ucs2pos] & 0xfc0) >> 6; + utf8[utf8pos+2] = 0x80 | (ucs2p[ucs2pos] & 0x003f); + utf8pos = utf8pos + 3; + } + ucs2pos++; + } + /* NULL Terminate */ + utf8[utf8pos] = '\0'; + utf8pos++; + return; +} + /********************************************************************** * @@ -693,7 +749,7 @@ /* Copy the name into ASCII */ if (attr->nlen) - uni2ascii(&attr->c.r.name, attr->nlen, name, sizeof(name)); + uni2dos(&attr->c.r.name, attr->nlen, name, sizeof(name)); /* Call the unnamed $Data attribute, $Data */ else if (type == NTFS_ATYPE_DATA) strncpy(name, "$Data", NTFS_MAXNAMLEN+1); @@ -722,7 +778,7 @@ /* Copy the name */ if (attr->nlen) - uni2ascii(&attr->c.nr.name, attr->nlen, name, sizeof(name)); + uni2dos(&attr->c.nr.name, attr->nlen, name, sizeof(name)); else if (type == NTFS_ATYPE_DATA) strncpy(name, "$Data", NTFS_MAXNAMLEN+1); else @@ -806,7 +862,7 @@ fs_name->next = NULL; } - uni2ascii(&fname->name, fname->nlen, fs_name->name, 256); + uni2dos(&fname->name, fname->nlen, fs_name->name, 256); fs_name->par_inode = getu48(fs, fname->par_ref); fs_name->par_seq = getu16(fs, fname->par_seq); @@ -1248,7 +1304,7 @@ while (getu32(fs, attrdef->type)) { if (getu32(fs, attrdef->type) == type) { - uni2ascii(attrdef->label, 128, name, len); + uni2dos(attrdef->label, 128, name, len); return; } attrdef++; @@ -1560,7 +1616,7 @@ error ("Volume Name attribute not found in $Volume"); if ((fs_data->flags & FS_DATA_RES) && (fs_data->size)) { - uni2ascii(fs_data->buf, fs_data->size, asc, 128); + uni2dos(fs_data->buf, fs_data->size, asc, 128); fprintf(hFile, "Volume Name: %s\n", asc); } @@ -1606,7 +1662,7 @@ attrdeftmp = ntfs->attrdef; while (getu32(fs, attrdeftmp->type)) { - uni2ascii(attrdeftmp->label, 128, asc, 128); + uni2dos(attrdeftmp->label, 128, asc, 128); printf("%s: %d\n", asc, getu32(fs, attrdeftmp->type)); attrdeftmp++; diff -u ../task-1.60/src/fstools/ntfs.h src/fstools/ntfs.h --- ../task-1.60/src/fstools/ntfs.h Tue Jan 7 01:08:56 2003 +++ src/fstools/ntfs.h Fri Feb 28 02:34:50 2003 @@ -7,6 +7,10 @@ extern void uni2ascii(char *, int, char *, int); +extern void +uni2utf8(char *, int, char *, int); +extern void +(*uni2dos)(char *, int, char *, int); extern u_int32_t nt2unixtime(u_int64_t ntdate); diff -u ../task-1.60/src/fstools/ntfs_dent.c src/fstools/ntfs_dent.c --- ../task-1.60/src/fstools/ntfs_dent.c Tue Jan 7 01:08:55 2003 +++ src/fstools/ntfs_dent.c Fri Feb 28 01:17:55 2003 @@ -40,7 +40,7 @@ /* Copy the name */ fs_dent->namlen = fname->nlen; - uni2ascii((char *)&fname->name, fname->nlen, + uni2dos((char *)&fname->name, fname->nlen, fs_dent->name, fs_dent->maxnamlen); /* copy the path data */