diff options
| author | Eduardo Casino <mail@eduardocasino.es> | 2022-05-16 20:12:19 +0200 | 
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2022-05-23 00:01:55 +0200 | 
| commit | 7b243074da3f4be6ed47426925f203c547c1c729 (patch) | |
| tree | e200ebfbf6d3912458db78d26da4fb152bc1c4bb | |
| parent | b8eb74ac1d31ffc382e654e19bba4e5e48f0001e (diff) | |
| download | vbados-7b243074da3f4be6ed47426925f203c547c1c729.tar.gz vbados-7b243074da3f4be6ed47426925f203c547c1c729.zip | |
Add support for windows host short file names
| -rw-r--r-- | nls.h | 78 | ||||
| -rw-r--r-- | sfmain.c | 24 | ||||
| -rw-r--r-- | sftsr.c | 92 | ||||
| -rw-r--r-- | sftsr.h | 2 | ||||
| -rw-r--r-- | unicode.h | 42 | 
5 files changed, 162 insertions, 76 deletions
| @@ -0,0 +1,78 @@ +/* + * VBSF - NLS support functions + * Copyright (C) 2011-2022 Eduardo Casino + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General License for more details. + * + * You should have received a copy of the GNU General License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. + */ + +#ifndef NLS_H +#define NLS_H + +static bool illegal_char( unsigned char c ) +{ +	int i= 0; +	 +	for ( i= 0; i < data.file_char->n_illegal; ++i ) +	{ +		if ( c == data.file_char->illegal[i] ) +		{ +			return true; +		} +	} +	if (  ( c < data.file_char->lowest || c > data.file_char->highest ) || +	     !( c < data.file_char->first_x || c > data.file_char->last_x ) ) +	{ +		return true; +	} +	 +	return false; +} + +static unsigned char nls_toupper( unsigned char c ) +{ +	if ( c > 0x60 && c < 0x7b ) +	{ +		return c & 0xDF; +	} +	 +	return ( c < 0x80 ? c : data.file_upper_case[c - 0x80] ); +} + +static inline void nls_uppercase(SHFLSTRING *str) +{ +	int i; + +	for (i= 0; i < str->u16Length; ++i) +	{ +		str->ach[i] = nls_toupper(str->ach[i]); +	} +} + +static inline bool valid_8_3_file_chars(char __far *fname ) +{ +	int i; + +	for (i = 0; i < 11; ++i) +	{ +		if ( fname[i] != ' ' && illegal_char(fname[i]) ) +		{ +			break; +		} +	} + +	return ( i == 11 ); +} + +#endif // NLS_H @@ -452,7 +452,7 @@ error:  } -static int configure_driver(LPTSRDATA data) +static int configure_driver(LPTSRDATA data, bool short_fnames)  {  	unsigned i;  	int32_t err; @@ -481,6 +481,16 @@ static int configure_driver(LPTSRDATA data)  		data->tz_offset = 0;  	} +	// Get uppercase and valid file char tables +	err = get_nls(&data->file_upper_case, &data->file_char); +	if (err) { +		puts("Cannot get the NLS tables."); +		return -1; +	} + +	// Set use of short file names from Windows hosts +	data->short_fnames = short_fnames; +  	// Now try to initialize VirtualBox communication  	err = vbox_init_device(&data->vb);  	if (err) { @@ -512,12 +522,6 @@ static int configure_driver(LPTSRDATA data)  		return -1;  	} -	err = get_nls(&data->file_upper_case, &data->file_char); -	if (err) { -		puts("Cannot get the NLS tables."); -		return -1; -	} -  	load_unicode_table( &data->unicode_table);  	printf("Connected to VirtualBox shared folder service\n"); @@ -617,6 +621,7 @@ static void print_help(void)  	    "Supported actions:\n"  	    "    install            install the driver (default)\n"  	    "        low                install in conventional memory (otherwise UMB)\n" +	    "        short              use short file names from windows hosts\n"  	    "    uninstall          uninstall the driver from memory\n"  	    "    list               list available shared folders\n"  	    "    mount <FOLD> <X:>  mount a shared folder into drive X:\n" @@ -668,6 +673,7 @@ int main(int argc, const char *argv[])  	if (argi >= argc || stricmp(argv[argi], "install") == 0) {  		bool high = true; +		bool short_fnames = false;  		argi++;  		for (; argi < argc; argi++) { @@ -675,6 +681,8 @@ int main(int argc, const char *argv[])  				high = false;  			} else if (stricmp(argv[argi], "high") == 0) {  				high = true; +			} else if (stricmp(argv[argi], "short") == 0) { +				short_fnames = true;  			} else {  				return invalid_arg(argv[argi]);  			} @@ -695,7 +703,7 @@ int main(int argc, const char *argv[])  		} else {  			deallocate_environment(_psp);  		} -		err = configure_driver(data); +		err = configure_driver(data, short_fnames);  		if (err) {  			if (high) cancel_reallocation(FP_SEG(data));  			return EXIT_FAILURE; @@ -25,8 +25,6 @@  #include "unixtime.h"  #include "vboxshfl.h"  #include "sftsr.h" -#define __IN_SFTSR__ 1 -#include "unicode.h"  TSRDATA data = {  	// TSR installation data @@ -56,6 +54,10 @@ TSRDATA data = {  		0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }  }; +#define __IN_SFTSR__ 1 +#include "unicode.h" +#include "nls.h" +  /** Private buffer for VirtualBox filenames. */  static SHFLSTRING_WITH_BUF(shflstr, SHFL_MAX_LEN); @@ -231,6 +233,17 @@ static int my_strrchr(const char __far *str, char c)  	return last;  } +static inline bool translate_filename_from_host(SHFLSTRING *str) +{ +	bool valid; + +	valid = utf8_to_local( &data, str->ach, str->ach, &str->u16Length); + +	nls_uppercase(str); + +	return valid; +} +  static const char * get_basename(const char *path)  {  	int last_sep = my_strrchr(path, '\\'); @@ -241,61 +254,6 @@ static const char * get_basename(const char *path)  	}  } -static bool illegal_char( unsigned char c ) -{ -	int i= 0; -	 -	for ( i= 0; i < data.file_char->n_illegal; ++i ) -	{ -		if ( c == data.file_char->illegal[i] ) -		{ -			return true; -		} -	} -	if (  ( c < data.file_char->lowest || c > data.file_char->highest ) || -	     !( c < data.file_char->first_x || c > data.file_char->last_x ) ) -	{ -		return true; -	} -	 -	return false; -} - -static unsigned char nls_toupper( unsigned char c ) -{ -	if ( c > 0x60 && c < 0x7b ) -	{ -		return c & 0xDF; -	} -	 -	return ( c < 0x80 ? c : data.file_upper_case[c - 0x80] ); -} - -static inline bool translate_filename_from_host(SHFLSTRING *str) -{ -	unsigned i; -	bool ret; -	unsigned dots = 0; - -	ret = utf8_to_local(&data, str->ach, str->ach, &str->u16Length); - -	for (i = 0; i < str->u16Length; i++) { -		if (str->ach[i] == '.') { -			++dots; -		} -		else { -			if (illegal_char(str->ach[i])) { -				ret = false; -			} -			else { -				str->ach[i] = nls_toupper(str->ach[i]); -			} -		} -	} - -	return ret && (dots <= 1); -} -  /** Tries to do some very simple heuristics to convert DOS-style wildcards   *  into win32-like (as expected by VirtualBox). */  static void fix_wildcards(SHFLSTRING *str) @@ -352,7 +310,7 @@ static bool copy_to_8_3_filename(char __far *dst, const SHFLSTRING *str)  {  	int last_dot = my_strrchr(str->ach, '.');  	unsigned namelen, extlen; -	bool valid_8_3 = true; +	bool valid_8_3 = true, dotfile = false;  	namelen = last_dot >= 0 ? last_dot : str->u16Length;  	extlen = last_dot >= 0 ? str->u16Length - (last_dot + 1) : 0; @@ -361,6 +319,7 @@ static bool copy_to_8_3_filename(char __far *dst, const SHFLSTRING *str)  		// . , .. files  		namelen = str->u16Length;  		extlen = 0; +		dotfile = true;  	}  	if (namelen == 0) { @@ -381,7 +340,7 @@ static bool copy_to_8_3_filename(char __far *dst, const SHFLSTRING *str)  	_fmemcpy(&dst[8], str->ach + last_dot + 1, extlen);  	_fmemset(&dst[8+extlen], ' ', 3 - extlen); -	return valid_8_3; +	return valid_8_3 && (dotfile || valid_8_3_file_chars(dst));  }  static bool is_8_3_wildcard(const char __far *name) @@ -1089,10 +1048,17 @@ static vboxerr find_next_from_vbox(unsigned openfile, const char __far *path)  		}  		// Now convert the filename -		// TODO Use the short filename if available from a windows host -		// i.e. shfldirinfo.dirinfo.cucShortName - -		if (!translate_filename_from_host(&shfldirinfo.dirinfo.name)) { +		// Use the short filename if available from a windows host +		if (data.short_fnames && shfldirinfo.dirinfo.cucShortName != 0) { +				if (!utf16_to_local( &data, &shfldirinfo.dirinfo.name.ach, &shfldirinfo.dirinfo.uszShortName, shfldirinfo.dirinfo.cucShortName)) { +				// Should not happen as Windows short names are pure ascii +				dputs("hiding file with illegal character(s)"); +				continue;	 +			} +			shfldirinfo.dirinfo.name.u16Length = shfldirinfo.dirinfo.cucShortName; +			dprintf("  Host short filename: '%s'\n", shfldirinfo.dirinfo.name.ach); +		} +		else if (!translate_filename_from_host(&shfldirinfo.dirinfo.name)) {  			dputs("hiding file with illegal character(s)");  			continue;  		} @@ -72,6 +72,8 @@ typedef struct {  	FCHAR __far *file_char;  	/** Codepage to unicode lookup table. */  	uint16_t unicode_table[128]; +	/** LFN support */ +	bool short_fnames;  	// Current status  	/** Array of all possible DOS drives. */ @@ -1,8 +1,5 @@  /* - * VBSF - unix to DOS time conversion - * Copyright (C) 2022 Javier S. Pedro - * - * unicode.h: Unicode conversion routines + * VBSF - Unicode conversion routines   * Copyright (C) 2011-2022 Eduardo Casino   *   * This program is free software; you can redistribute it and/or @@ -212,4 +209,39 @@ cont:  } -#endif +// Returns true on success, false if any unsupported char is found +// +static bool utf16_to_local( TSRDATAPTR data, uint8_t *dst, uint16_t *src, uint16_t len ) +{ +	bool ret = true; +	int i; +	uint16_t cp; +	uint8_t c; +	 +	for ( i = 0; i < len; ++i ) +	{ +		cp = src[i]; +		 +		if ( cp < 0x80 ) +		{ +			*dst++ = ( uint8_t ) cp; +		} +		else +		{ +			c = lookup_codepage( data, cp ); +			if ( c == '\0' ) +			{ +				c = '_'; +				ret = false; +			} +			*dst++ = c; +		} +	} + +	*dst = '\0'; + +	return ret; +	 +} + +#endif // UNICODE_H | 
