Skip to content

Commit 92c1b26

Browse files
Handle both an ASCII (UTF8) and a WIDE (UTF16) version of image/vm name/path
Note: the Microsoft windows API mostly uses the W version (for enabling internationalized image name/path) the image uses UTF8 encoded bytes string for communication with the VM (this is best for compatibility with Unix/Mac) The idea here is that the implementation maintains both versions of the UTF8 and UTF16 path/name The appropriate macro returning a TCHAR * are also provided. This is in order to support the generic version using TCHAR, which are normally used to ease transition to UNICODE. Note about string length: No effort has been made so far to support long path names for image and VM. The path is limited to MAX_PATH in UTF16. UTF8 can eventually consume more characters than UTF16 (not necessarily more bytes). Thus, the ASCII version has been made longer (MAX_PATH_UTF8) in order to avoid an even more restrictive limit.
1 parent 1229447 commit 92c1b26

File tree

5 files changed

+124
-79
lines changed

5 files changed

+124
-79
lines changed

platforms/win32/vm/sqWin32.h

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,21 +259,46 @@ int reverse_image_words(unsigned int *dst, unsigned int *src,int depth, int widt
259259
/********************************************************/
260260
/* Declarations we may need by other modules */
261261
/********************************************************/
262-
extern char imageName[]; /* full path and name to image */
263-
extern TCHAR imagePath[]; /* full path to image */
264-
extern TCHAR vmPath[]; /* full path to interpreter's directory */
265-
extern TCHAR vmName[]; /* name of the interpreter's executable */
266-
extern char windowTitle[]; /* window title string */
267-
extern char vmBuildString[]; /* the vm build string */
268-
extern TCHAR windowClassName[]; /* class name for the window */
262+
263+
/* Note: a character can require up to 4 bytes in UTF8 encoding
264+
But the expansion from UTF16 -> UTF8 is never more than 3 bytes for 1 short
265+
U+ 0000-U+ 007F - 1byte in utf8, 1 short in utf16.
266+
U+ 0080-U+ 07FF - 2byte in utf8, 1 short in utf16.
267+
U+ 0800-U+ FFFF - 3byte in utf8, 1 short in utf16.
268+
U+10000-U+10FFFF - 4byte in utf8, 2 short in utf16.
269+
*/
270+
#define MAX_PATH_UTF8 (MAX_PATH*3)
271+
272+
extern char imageName []; /* full path and name to image - UTF8 */
273+
extern WCHAR imageNameW[]; /* full path and name to image - UTF16 */
274+
extern char imagePathA[]; /* full path to image - UTF8 */
275+
extern WCHAR imagePathW[]; /* full path to image - UTF16 */
276+
extern char vmPathA[]; /* full path to interpreter's directory - UTF8 */
277+
extern WCHAR vmPathW[]; /* full path to interpreter's directory - UTF16 */
278+
extern char vmNameA[]; /* name of the interpreter's executable - UTF8 */
279+
extern WCHAR vmNameW[]; /* name of the interpreter's executable - UTF16 */
280+
extern char windowTitle[]; /* window title string - UTF8 */
281+
extern char vmBuildString[]; /* the vm build string */
282+
extern TCHAR windowClassName[]; /* class name for the window */
283+
284+
#ifdef UNICODE
285+
#define imageNameT imageNameW /* define the generic TCHAR* version */
286+
#define imagePath imagePathW
287+
#define vmName vmNameW
288+
#define vmPath vmPathW
289+
#else
290+
#define imageNameT imageNameA
291+
#define imagePath imagePathA
292+
#define vmName vmNameA
293+
#define vmPath vmPathA
294+
#endif
269295

270296
extern UINT SQ_LAUNCH_DROP;
271297

272298
extern const TCHAR U_ON[];
273299
extern const TCHAR U_OFF[];
274300
extern const TCHAR U_GLOBAL[];
275-
extern const TCHAR U_SLASH[];
276-
extern const TCHAR U_BACKSLASH[];
301+
extern const WCHAR W_BACKSLASH[];
277302

278303
#ifndef NO_PREFERENCES
279304
extern HMENU vmPrefsMenu; /* preferences menu */
@@ -380,7 +405,7 @@ void vprintLastError(TCHAR *fmt, ...);
380405
/******************************************************/
381406
/* Misc functions */
382407
/******************************************************/
383-
DWORD SqueakImageLength(TCHAR *fileName);
408+
DWORD SqueakImageLength(WCHAR *fileName);
384409
int isLocalFileName(TCHAR *fileName);
385410

386411
#ifndef NO_PLUGIN_SUPPORT

platforms/win32/vm/sqWin32Main.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ TCHAR consoleBuffer[4096];
130130
char stderrName[MAX_PATH+1];
131131
char stdoutName[MAX_PATH+1];
132132

133-
static char vmLogDirA[MAX_PATH];
133+
static char vmLogDirA[MAX_PATH_UTF8];
134134
static WCHAR vmLogDirW[MAX_PATH];
135135

136136
TCHAR *logName = TEXT(""); /* full path and name to log file */
@@ -462,7 +462,7 @@ char *ioGetLogDirectory(void) {
462462
}
463463

464464
sqInt ioSetLogDirectoryOfSize(void* lblIndex, sqInt sz) {
465-
if (sz >= MAX_PATH) return 0;
465+
if (sz >= MAX_PATH_UTF8) return 0;
466466
strncpy(vmLogDirA, lblIndex, sz);
467467
vmLogDirA[sz] = 0;
468468
MultiByteToWideChar(CP_UTF8, 0, vmLogDirA, -1, vmLogDirW, MAX_PATH);
@@ -1405,7 +1405,7 @@ sqImageFile findEmbeddedImage(void) {
14051405
int start;
14061406
int length;
14071407

1408-
f = sqImageFileOpen(vmName, "rb");
1408+
f = sqImageFileOpen(vmNameA, "rb");
14091409
if(!f) {
14101410
MessageBox(0,"Error opening VM",VM_NAME,MB_OK);
14111411
return 0;
@@ -1441,6 +1441,7 @@ sqImageFile findEmbeddedImage(void) {
14411441
/* Gotcha! */
14421442
sqImageFileSeek(f, sqImageFilePosition(f) - 4);
14431443
strcpy(imageName, name);
1444+
MultiByteToWideChar(CP_UTF8,0,imageName,-1,imageNameW,MAX_PATH,NULL,NULL);
14441445
imageSize = endMarker - sqImageFilePosition(f);
14451446
return f;
14461447
}
@@ -1577,7 +1578,7 @@ sqMain(int argc, char *argv[])
15771578
}
15781579

15791580
SetupFilesAndPath();
1580-
ioSetLogDirectoryOfSize(vmPath, strlen(vmPath));
1581+
ioSetLogDirectoryOfSize(vmPathA, strlen(vmPathA));
15811582

15821583
/* release resources on exit */
15831584
atexit(Cleanup);
@@ -1620,7 +1621,7 @@ sqMain(int argc, char *argv[])
16201621

16211622

16221623
if(!imageFile) {
1623-
imageSize = SqueakImageLength(toUnicode(imageName));
1624+
imageSize = SqueakImageLength(imageNameW);
16241625
if(imageSize == 0) printUsage(2);
16251626
}
16261627

@@ -1650,13 +1651,13 @@ sqMain(int argc, char *argv[])
16501651

16511652
#if !NewspeakVM
16521653
/* set the CWD to the image location */
1653-
if(*imageName) {
1654-
char path[MAX_PATH+1], *ptr;
1655-
strcpy(path,imageName);
1656-
ptr = strrchr(path, '\\');
1654+
if(*imageNameW) {
1655+
WCHAR path[MAX_PATH+1], *ptr;
1656+
wcsncpy(path,imageNameW,MAX_PATH);
1657+
ptr = wcsrchr(path, '\\');
16571658
if(ptr) {
1658-
*ptr = 0;
1659-
SetCurrentDirectory(path);
1659+
*ptr = 0;
1660+
SetCurrentDirectoryW(path);
16601661
}
16611662
}
16621663
#endif /* !NewspeakVM */
@@ -1723,9 +1724,8 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
17231724

17241725
/* fetch us the name of the executable */
17251726
{
1726-
WCHAR vmNameW[MAX_PATH];
17271727
GetModuleFileNameW(hInst, vmNameW, MAX_PATH);
1728-
WideCharToMultiByte(CP_UTF8, 0, vmNameW, -1, vmName, MAX_PATH, NULL, NULL);
1728+
WideCharToMultiByte(CP_UTF8, 0, vmNameW, -1, vmNameA, MAX_PATH_UTF8, NULL, NULL);
17291729
}
17301730
/* parse the command line into the unix-style argc, argv, converting to
17311731
* UTF-8 on the way. */
@@ -2086,7 +2086,7 @@ SubsystemType()
20862086
IMAGE_OPTIONAL_HEADER image_optional_header;
20872087

20882088
/* Open the reference file. */
2089-
hImage = CreateFile(vmName,
2089+
hImage = CreateFileW(vmNameW,
20902090
GENERIC_READ,
20912091
FILE_SHARE_READ,
20922092
NULL,
@@ -2150,7 +2150,8 @@ parseGenericArgs(int argc, char *argv[])
21502150

21512151
if (*imageName == 0) { /* only try to use image name if none is provided */
21522152
if (*argv[0] && IsImage(argv[0])) {
2153-
strcpy(imageName, argv[0]);
2153+
strncpy(imageName, argv[0],MAX_PATH_UTF8);
2154+
MultiByteToWideChar(CP_UTF8, 0, imageName, -1, imageNameW, MAX_PATH);
21542155
/* if provided, the image is a vm argument. */
21552156
vmOptions[numOptionsVM++] = argv[0];
21562157
}

platforms/win32/vm/sqWin32Prefs.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,15 +194,17 @@ void LoadPreferences()
194194

195195
/* get image file name from ini file */
196196
size = GetPrivateProfileString(U_GLOBAL, TEXT("ImageFile"),
197-
TEXT(""), imageName, MAX_PATH, squeakIniName);
197+
TEXT(""), imageNameT, MAX_PATH, squeakIniName);
198198
if(size > 0) {
199199
if( !(imageName[0] == '\\' && imageName[1] == '\\') && !(imageName[1] == ':' && imageName[2] == '\\')) {
200200
/* make the path relative to VM directory */
201-
lstrcpy(imageName, vmName);
202-
(lstrrchr(imageName,U_BACKSLASH[0]))[1] = 0;
203-
size = lstrlen(imageName);
201+
strcpy(imageName , vmNameA);
202+
wcscpy(imageNameW, vmNameW);
203+
(strrchr(imageName ,'\\' ))[1] = 0;
204+
(wcsrchr(imageNameW, W_BACKSLASH[0]))[1] = 0;
205+
size = lstrlen(imageNameT);
204206
size = GetPrivateProfileString(U_GLOBAL, TEXT("ImageFile"),
205-
TEXT(""), imageName + size, MAX_PATH - size, squeakIniName);
207+
TEXT(""), imageNameT + size, MAX_PATH - size, squeakIniName);
206208
}
207209
}
208210

platforms/win32/vm/sqWin32Service.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -413,12 +413,12 @@ void sqServiceInstall(void)
413413
return;
414414
}
415415
/* Add the image name to the subkey. */
416-
ok = RegSetValueEx(hk, /* subkey handle */
417-
TEXT("Image"), /* value name */
418-
0, /* must be zero */
419-
REG_EXPAND_SZ, /* value type */
420-
(LPBYTE) imageName, /* address of value data */
421-
strlen(imageName) + 1); /* length of value data */
416+
ok = RegSetValueExW(hk, /* subkey handle */
417+
L"Image", /* value name */
418+
0, /* must be zero */
419+
REG_EXPAND_SZ, /* value type */
420+
(LPBYTE) imageNameW, /* address of value data */
421+
(wcslen(imageNameW)+1)*sizeof(WCHAR)); /* length of value data */
422422
if(ok != ERROR_SUCCESS)
423423
{
424424
printLastError(TEXT("RegSetValueEX failed"));
@@ -517,14 +517,15 @@ DWORD WINAPI sqThreadMain(DWORD ignored)
517517
TerminateThread(GetCurrentThread(), 0);
518518
}
519519
/* Read the image name from the subkey. */
520-
dwSize = MAX_PATH;
521-
ok = RegQueryValueEx(hk,TEXT("Image"),NULL, &dwType, (LPBYTE) imageName, &dwSize);
520+
dwSize = MAX_PATH*sizeof(WCHAR);
521+
ok = RegQueryValueExW(hk,L"Image",NULL, &dwType, (LPBYTE) imageNameW, &dwSize);
522522
if(ok != ERROR_SUCCESS || dwType != REG_EXPAND_SZ)
523523
{
524524
sqStopService(TEXT("Failed to read the image name from registry"));
525525
TerminateThread(GetCurrentThread(), 0);
526526
}
527-
imageName[dwSize] = 0;
527+
imageNameW[(dwSize+1)/2] = 0;
528+
WideCharToMultiByte(CP_UTF8, 0, imageNameW, -1, imageName, MAX_PATH_UTF8, NULL, NULL);
528529
/* Read the log file name from the subkey. */
529530
dwSize = MAX_PATH;
530531
ok = RegQueryValueEx(hk,TEXT("Log"),NULL, &dwType, (LPBYTE) &tmpString, &dwSize);

0 commit comments

Comments
 (0)