diff -u sleuthkit-1.61.org/src/fstools/ffind.c sleuthkit-1.61/src/fstools/ffind.c --- sleuthkit-1.61.org/src/fstools/ffind.c Tue Apr 1 03:06:07 2003 +++ sleuthkit-1.61/src/fstools/ffind.c Wed Apr 9 01:52:43 2003 @@ -49,6 +49,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 *); @@ -57,6 +58,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"); @@ -108,8 +110,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 sleuthkit-1.61.org/src/fstools/fls.c sleuthkit-1.61/src/fstools/fls.c --- sleuthkit-1.61.org/src/fstools/fls.c Tue Apr 1 03:06:38 2003 +++ sleuthkit-1.61/src/fstools/fls.c Wed Apr 9 01:52:43 2003 @@ -58,9 +58,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"); @@ -273,11 +274,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 sleuthkit-1.61.org/src/fstools/fs_tools.h sleuthkit-1.61/src/fstools/fs_tools.h --- sleuthkit-1.61.org/src/fstools/fs_tools.h Tue Apr 1 03:03:34 2003 +++ sleuthkit-1.61/src/fstools/fs_tools.h Wed Apr 9 01:52:43 2003 @@ -358,7 +358,7 @@ /* Currently this is only used with NTFS & FAT systems */ struct FS_NAME { FS_NAME *next; - char name[256]; + char name[255*3+1]; u_int64_t par_inode; u_int32_t par_seq; }; diff -u sleuthkit-1.61.org/src/fstools/fsstat.c sleuthkit-1.61/src/fstools/fsstat.c --- sleuthkit-1.61.org/src/fstools/fsstat.c Tue Apr 1 03:07:24 2003 +++ sleuthkit-1.61/src/fstools/fsstat.c Wed Apr 9 01:52:43 2003 @@ -11,6 +11,7 @@ */ #include "fs_tools.h" #include "error.h" +#include "ntfs.h" FILE *logfp; @@ -19,7 +20,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"); @@ -38,7 +40,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: @@ -47,6 +49,10 @@ case 'f': fstype = optarg; break; + + case '8': + uni2dos = uni2utf8; + break; case 'v': verbose++; diff -u sleuthkit-1.61.org/src/fstools/istat.c sleuthkit-1.61/src/fstools/istat.c --- sleuthkit-1.61.org/src/fstools/istat.c Tue Apr 1 03:01:08 2003 +++ sleuthkit-1.61/src/fstools/istat.c Wed Apr 9 01:52:43 2003 @@ -53,6 +53,7 @@ #include "fs_tools.h" #include "error.h" #include +#include "ntfs.h" FILE *logfp; @@ -85,7 +86,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"); @@ -113,10 +115,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 sleuthkit-1.61.org/src/fstools/ntfs.c sleuthkit-1.61/src/fstools/ntfs.c --- sleuthkit-1.61.org/src/fstools/ntfs.c Tue Apr 1 03:01:24 2003 +++ sleuthkit-1.61/src/fstools/ntfs.c Wed Apr 9 01:52:43 2003 @@ -33,6 +33,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 *); @@ -133,6 +138,61 @@ return; } +/* + * Convert a UNICODE string to an UTF-8 string + * + * both uni and asc must be defined + * Notes: + * ucs2: does not NULL-terminated. + * utf8: DOES include the length of NULL termination (1byte). + * utf8len: does not include the length of NULL termination (1byte). + */ +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 ((ucs2len * 3) <= utf8len) + maxlen = ucs2len; + else + maxlen = utf8len / 3; + + 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; +} + /********************************************************************** * @@ -669,7 +729,7 @@ { ntfs_attr *attr = attrseq; FS_DATA *fs_data_attrl = NULL, *fs_data; - char name[NTFS_MAXNAMLEN+1]; + char name[NTFS_MAXNAMLEN*3+1]; u_int64_t runlen; FS_INFO *fs = (FS_INFO *)&ntfs->fs_info; @@ -697,7 +757,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); @@ -726,7 +786,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 @@ -810,7 +870,7 @@ fs_name->next = NULL; } - uni2ascii(&fname->name, fname->nlen, fs_name->name, 256); + uni2dos(&fname->name, fname->nlen, fs_name->name, NTFS_MAXNAMLEN*3); fs_name->par_inode = getu48(fs, fname->par_ref); fs_name->par_seq = getu16(fs, fname->par_seq); @@ -1252,7 +1312,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++; @@ -1542,7 +1602,7 @@ NTFS_INFO *ntfs = (NTFS_INFO *)fs; FS_INODE *fs_inode; FS_DATA *fs_data; - char asc[128]; + char asc[128*3+1]; ntfs_attrdef *attrdeftmp; fprintf(hFile, "FILE SYSTEM INFORMATION\n"); @@ -1564,7 +1624,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*3); fprintf(hFile, "Volume Name: %s\n", asc); } @@ -1610,7 +1670,7 @@ attrdeftmp = ntfs->attrdef; while (getu32(fs, attrdeftmp->type)) { - uni2ascii(attrdeftmp->label, 128, asc, 128); + uni2dos(attrdeftmp->label, 128, asc, 128*3); printf("%s: %d\n", asc, getu32(fs, attrdeftmp->type)); attrdeftmp++; @@ -1760,9 +1820,9 @@ fprintf(hFile, "\nAttributes: \n"); while ((fs_data) && (fs_data->flags & FS_DATA_INUSE)) { - char type[256]; + char type[NTFS_MAXNAMLEN*3+1]; - ntfs_attrname_lookup(fs, fs_data->type, type, 256); + ntfs_attrname_lookup(fs, fs_data->type, type, NTFS_MAXNAMLEN*3); printf("Type: %s (%i-%i) Name: %s %sResident size: %d\n", type, fs_data->type, fs_data->id, fs_data->name, diff -u sleuthkit-1.61.org/src/fstools/ntfs.h sleuthkit-1.61/src/fstools/ntfs.h --- sleuthkit-1.61.org/src/fstools/ntfs.h Tue Apr 1 03:02:41 2003 +++ sleuthkit-1.61/src/fstools/ntfs.h Wed Apr 9 01:52:43 2003 @@ -17,6 +17,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 sleuthkit-1.61.org/src/fstools/ntfs_dent.c sleuthkit-1.61/src/fstools/ntfs_dent.c --- sleuthkit-1.61.org/src/fstools/ntfs_dent.c Tue Apr 1 08:47:44 2003 +++ sleuthkit-1.61/src/fstools/ntfs_dent.c Wed Apr 9 01:52:43 2003 @@ -43,7 +43,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 */ @@ -136,7 +136,7 @@ { DADDR_T endaddr, endaddr_alloc; int myflags = 0; - FS_DENT *fs_dent = fs_dent_alloc(NTFS_MAXNAMLEN); + FS_DENT *fs_dent = fs_dent_alloc(NTFS_MAXNAMLEN*3); FS_INFO *fs = (FS_INFO *)&ntfs->fs_info; if (verbose) @@ -787,7 +787,7 @@ FS_INODE *fs_inode; FS_NAME *fs_name; - FS_DENT *fs_dent = fs_dent_alloc(NTFS_MAXNAMLEN); + FS_DENT *fs_dent = fs_dent_alloc(NTFS_MAXNAMLEN*3); int myflags; NTFS_INFO *ntfs = (NTFS_INFO *)fs;