diff --git a/platforms/win32/plugins/DropPlugin/sqWin32Drop.c b/platforms/win32/plugins/DropPlugin/sqWin32Drop.c index 9606691aa7..9962f7a15d 100644 --- a/platforms/win32/plugins/DropPlugin/sqWin32Drop.c +++ b/platforms/win32/plugins/DropPlugin/sqWin32Drop.c @@ -212,19 +212,26 @@ HANDLE DibFromBitmap ( } BOOL WriteDIB ( - LPSTR szFile, + LPCWSTR szFile, HANDLE hdib) { BITMAPFILEHEADER hdr; LPBITMAPINFOHEADER lpbi; - HFILE fh; - OFSTRUCT of; + HANDLE fh; + DWORD nbwritten; if (!hdib) return FALSE; - fh = OpenFile(szFile, &of, (UINT)OF_CREATE|OF_READWRITE); - if (fh == -1) + fh = CreateFileW(szFile, + (GENERIC_READ | GENERIC_WRITE) , + FILE_SHARE_READ , + NULL, /* No security descriptor */ + OPEN_ALWAYS , + FILE_ATTRIBUTE_NORMAL, + NULL /* No template */); + + if (fh == INVALID_HANDLE_VALUE) return FALSE; lpbi = (VOID FAR *)GlobalLock (hdib); @@ -240,16 +247,16 @@ BOOL WriteDIB ( /* Write the file header */ /* write bfType*/ - _lwrite(fh, (LPSTR)&hdr.bfType, (UINT)sizeof (WORD)); + WriteFile(fh, (LPSTR)&hdr.bfType, (UINT)sizeof (WORD),&nbwritten,NULL); /* now pass over extra word, and only write next 3 DWORDS!*/ - _lwrite(fh, (LPSTR)&hdr.bfSize, sizeof(DWORD) * 3); + WriteFile(fh, (LPSTR)&hdr.bfSize, sizeof(DWORD) * 3, &nbwritten, NULL); /* this struct already DWORD aligned!*/ /* Write the DIB header and the bits */ - _lwrite (fh, (LPSTR)lpbi, GlobalSize (hdib)); + WriteFile(fh, (LPSTR)lpbi, GlobalSize (hdib), &nbwritten, NULL); GlobalUnlock (hdib); - _lclose(fh); + CloseHandle(fh); return TRUE; } @@ -509,7 +516,7 @@ STDMETHODIMP DropTarget_Drop(DropTarget *dt, DWORD i; DPRINTF(("Success\n")); - numDropFiles = DragQueryFile(hDrop, -1, NULL, 0); + numDropFiles = DragQueryFileW(hDrop, -1, NULL, 0); dropFiles = calloc(numDropFiles, sizeof(char*)); for(i=0; ilpVtbl->GetData(ido, &fmtetc, &medium); if(hRes == S_OK) { - TCHAR tmpName[MAX_PATH+1]; + WCHAR tmpNameW[MAX_PATH+1]; HANDLE hDib = medium.hGlobal; DPRINTF(("Success\n")); - GetTempPath(MAX_PATH,tmpName); - strcat(tmpName,"$$squeak$$.bmp"); - if(WriteDIB(tmpName, hDib)) { - numDropFiles = 1; - dropFiles = calloc(1, sizeof(void*)); - dropFiles[0] = _strdup(tmpName); + GetTempPathW(MAX_PATH,tmpNameW); + wcscat(tmpNameW,L"$$squeak$$.bmp"); + if(WriteDIB(tmpNameW, hDib)) { + char tmpNameA[MAX_PATH_UTF8 + 1]; + if(WideCharToMultiByte(CP_UTF8, 0, tmpNameW, -1, tmpNameA, MAX_PATH_UTF8, NULL, NULL)) { + numDropFiles = 1; + dropFiles = calloc(1, sizeof(void*)); + dropFiles[0] = _strdup(tmpNameA); + } } if(medium.pUnkForRelease == NULL) { GlobalFree(hDib); @@ -580,20 +590,23 @@ STDMETHODIMP DropTarget_Drop(DropTarget *dt, hRes = ido->lpVtbl->GetData(ido, &fmtetc, &medium); if(hRes == S_OK) { - TCHAR tmpName[MAX_PATH+1]; + WCHAR tmpNameW[MAX_PATH+1]; HANDLE hDib; HBITMAP hBM = medium.hBitmap; DPRINTF(("Success\n")); - GetTempPath(MAX_PATH,tmpName); - strcat(tmpName,"$$squeak$$.bmp"); + GetTempPathW(MAX_PATH,tmpNameW); + wcscat(tmpNameW,L"$$squeak$$.bmp"); hDib = DibFromBitmap(hBM, BI_RGB, 0, NULL); if(hDib) { - if(WriteDIB(tmpName, hDib)) { - numDropFiles = 1; - dropFiles = calloc(1, sizeof(void*)); - dropFiles[0] = _strdup(tmpName); + if(WriteDIB(tmpNameW, hDib)) { + char tmpNameA[MAX_PATH_UTF8 + 1]; + if (WideCharToMultiByte(CP_UTF8, 0, tmpNameW, -1, tmpNameA, MAX_PATH_UTF8, NULL, NULL)) { + numDropFiles = 1; + dropFiles = calloc(1, sizeof(void*)); + dropFiles[0] = _strdup(tmpNameA); + } } DeleteObject(hDib); } @@ -618,7 +631,7 @@ STDMETHODIMP DropTarget_Drop(DropTarget *dt, hRes = ido->lpVtbl->GetData(ido, &fmtetc, &medium); if(hRes == S_OK) { - TCHAR tmpName[MAX_PATH+1]; + WCHAR tmpNameW[MAX_PATH+1]; HANDLE hMF = medium.hGlobal; HANDLE hDib; BITMAPINFO bmi; @@ -661,12 +674,15 @@ STDMETHODIMP DropTarget_Drop(DropTarget *dt, DeleteObject(hBM); } - GetTempPath(MAX_PATH,tmpName); - strcat(tmpName,"$$squeak$$.bmp"); - if(WriteDIB(tmpName, hDib)) { - numDropFiles = 1; - dropFiles = calloc(1, sizeof(void*)); - dropFiles[0] = _strdup(tmpName); + GetTempPathW(MAX_PATH,tmpNameW); + wcscat(tmpNameW,L"$$squeak$$.bmp"); + if(WriteDIB(tmpNameW, hDib)) { + char tmpNameA[MAX_PATH_UTF8 + 1]; + if (WideCharToMultiByte(CP_UTF8, 0, tmpNameW, -1, tmpNameA, MAX_PATH_UTF8, NULL, NULL)) { + numDropFiles = 1; + dropFiles = calloc(1, sizeof(void*)); + dropFiles[0] = _strdup(tmpNameA); + } } GlobalFree(hDib); if(medium.pUnkForRelease == NULL) { diff --git a/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c b/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c index d32f8a9f24..63965b61d0 100644 --- a/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c +++ b/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c @@ -517,7 +517,7 @@ size_t sqImageFileRead(void *ptr, size_t sz, size_t count, sqImageFile h) ReadFile((HANDLE)(h-1), (LPVOID) ptr, count*sz, &dwReallyRead, NULL); while(dwReallyRead != (DWORD)(count*sz)) { DWORD err = GetLastError(); - if(sqMessageBox(MB_ABORTRETRYIGNORE, TEXT("Squeak Warning"),"Image file read problem (%d out of %d bytes read)", dwReallyRead, count*sz) + if(sqMessageBox(MB_ABORTRETRYIGNORE, TEXT("Squeak Warning"),TEXT("Image file read problem (%d out of %d bytes read)"), dwReallyRead, count*sz) == IDABORT) return (dwReallyRead / sz); sqImageFileSeek(h, position); ReadFile((HANDLE)(h-1), (LPVOID) ptr, count*sz, &dwReallyRead, NULL); diff --git a/platforms/win32/plugins/HostWindowPlugin/sqWin32HostWindowPlugin.c b/platforms/win32/plugins/HostWindowPlugin/sqWin32HostWindowPlugin.c index d65368fe94..b81f378587 100644 --- a/platforms/win32/plugins/HostWindowPlugin/sqWin32HostWindowPlugin.c +++ b/platforms/win32/plugins/HostWindowPlugin/sqWin32HostWindowPlugin.c @@ -415,12 +415,17 @@ sqInt ioSetTitleOfWindow(sqInt windowIndex, char * newTitle, sqInt sizeOfTitle) * int size of new logo path. If one of the function is failing, the logo is not set. */ sqInt ioSetIconOfWindow(sqInt windowIndex, char * iconPath, sqInt sizeOfPath) { + WCHAR iconPathW[MAX_PATH + 1]; HWND hwnd = (windowIndex == 1 ? stWindow : ((HWND)windowIndex)); + int len; if (!IsWindow(hwnd)) return 0; + len = MultiByteToWideChar(CP_UTF8, 0, iconPath, sizeOfPath, iconPathW, MAX_PATH); + if(len <= 0) return -1; /* invalid UTF8 ? */ + iconPathW[len] = 0; //Check if file exists and have read rights - if (access(iconPath, 4) == -1) { return -1; }; + if (_waccess(iconPath, 4) == -1) { return -1; }; //Load the image into an icon - HICON hIcon = (HICON)LoadImage(NULL, iconPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); + HICON hIcon = (HICON)LoadImageW(NULL, iconPathW, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); if (hIcon == 0) return -2; SendMessage(hwnd, WM_SETICON, ICON_BIG, (LONG_PTR)hIcon); diff --git a/platforms/win32/plugins/MIDIPlugin/sqWin32MIDI.c b/platforms/win32/plugins/MIDIPlugin/sqWin32MIDI.c index 0366d070e9..3bceb4e7d2 100644 --- a/platforms/win32/plugins/MIDIPlugin/sqWin32MIDI.c +++ b/platforms/win32/plugins/MIDIPlugin/sqWin32MIDI.c @@ -605,7 +605,7 @@ int finishSysExCommand(sqMidiPort *port, char *bufferPtr, int count) /* Return the port with the given number or NULL */ static sqMidiPort* GetPort(int portNum) { - if(portNum > MAX_DEVICES || portNum < 0) + if(portNum >= MAX_DEVICES || portNum < 0) { success(false); return NULL; diff --git a/platforms/win32/plugins/SocketPlugin/sqWin32NewNet.c b/platforms/win32/plugins/SocketPlugin/sqWin32NewNet.c index 5fd1b3504d..4c32f0df1b 100644 --- a/platforms/win32/plugins/SocketPlugin/sqWin32NewNet.c +++ b/platforms/win32/plugins/SocketPlugin/sqWin32NewNet.c @@ -2179,7 +2179,7 @@ void sqResolverGetAddressInfoHostSizeServiceSizeFlagsFamilyTypeProtocol(char *ho if (gaiError) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gaiError)); + fwprintf(stderr, L"getaddrinfo: %s\n", gai_strerrorW(gaiError)); addrList= 0; /* succeed with zero results for impossible constraints */ } @@ -2349,7 +2349,7 @@ void sqResolverGetNameInfoSizeFlags(char *addr, sqInt addrSize, sqInt flags) if (gaiError) { - fprintf(stderr, "getnameinfo: %s\n", gai_strerror(gaiError)); + fwprintf(stderr, L"getnameinfo: %s\n", gai_strerrorW(gaiError)); lastError= gaiError; goto fail; } diff --git a/platforms/win32/vm/sqPlatformSpecific.h b/platforms/win32/vm/sqPlatformSpecific.h index ed4ab94f65..30f3f37c72 100644 --- a/platforms/win32/vm/sqPlatformSpecific.h +++ b/platforms/win32/vm/sqPlatformSpecific.h @@ -30,6 +30,7 @@ #ifdef WIN32_FILE_SUPPORT +#define NO_STD_FILE_SUPPORT /* STD_FILE or WIN32_FILE are mutually exclusive options */ #undef sqImageFile #undef sqImageFileClose #undef sqImageFileOpen diff --git a/platforms/win32/vm/sqWin32.h b/platforms/win32/vm/sqWin32.h index e48fcfd04d..4123ca98fd 100644 --- a/platforms/win32/vm/sqWin32.h +++ b/platforms/win32/vm/sqWin32.h @@ -104,7 +104,7 @@ /* Definition for Intel Processors */ #if defined(_M_IX86) || defined(i386) # define WIN32_NAME "Win32" -# define WIN32_OS_NAME (fWindows95 ? "95" : "NT") +# define WIN32_OS_NAME "NT" # define WIN32_PROCESSOR_NAME "IX86" # if defined(X86) @@ -143,16 +143,6 @@ #endif /* (_WIN32_WCE) */ -/* THE FOLLOWING IS WRONG (& HENCE I'VE IF 0'ed IT OUT. WE CAN'T MERELY DEFINE - * WIN32 BECAUSE WE MAY BE ON WIN64. eem 2017/05/16 - */ -#if 0 -/* due to weird include orders, make sure WIN32 is defined */ -# if !defined(WIN32) -# define WIN32 1 -# endif -#endif - /* Experimental */ #ifdef MINIMAL /* The hardcoded defs: @@ -189,7 +179,6 @@ void SetupKeymap(); void SetupWindows(); void SetupPixmaps(); void SetupPrinter(); -void SetupPreferences(); void SetupMIDI(); /********************************************************/ @@ -259,21 +248,46 @@ int reverse_image_words(unsigned int *dst, unsigned int *src,int depth, int widt /********************************************************/ /* Declarations we may need by other modules */ /********************************************************/ -extern char imageName[]; /* full path and name to image */ -extern TCHAR imagePath[]; /* full path to image */ -extern TCHAR vmPath[]; /* full path to interpreter's directory */ -extern TCHAR vmName[]; /* name of the interpreter's executable */ -extern char windowTitle[]; /* window title string */ -extern char vmBuildString[]; /* the vm build string */ -extern TCHAR windowClassName[]; /* class name for the window */ + +/* Note: a character can require up to 4 bytes in UTF8 encoding + But the expansion from UTF16 -> UTF8 is never more than 3 bytes for 1 short + U+ 0000-U+ 007F - 1byte in utf8, 1 short in utf16. + U+ 0080-U+ 07FF - 2byte in utf8, 1 short in utf16. + U+ 0800-U+ FFFF - 3byte in utf8, 1 short in utf16. + U+10000-U+10FFFF - 4byte in utf8, 2 short in utf16. +*/ +#define MAX_PATH_UTF8 (MAX_PATH*3) + +extern char imageName []; /* full path and name to image - UTF8 */ +extern WCHAR imageNameW[]; /* full path and name to image - UTF16 */ +extern char imagePathA[]; /* full path to image - UTF8 */ +extern WCHAR imagePathW[]; /* full path to image - UTF16 */ +extern char vmPathA[]; /* full path to interpreter's directory - UTF8 */ +extern WCHAR vmPathW[]; /* full path to interpreter's directory - UTF16 */ +extern char vmNameA[]; /* name of the interpreter's executable - UTF8 */ +extern WCHAR vmNameW[]; /* name of the interpreter's executable - UTF16 */ +extern char windowTitle[]; /* window title string - UTF8 */ +extern char vmBuildString[]; /* the vm build string */ +extern TCHAR windowClassName[]; /* class name for the window */ + +#ifdef UNICODE +#define imageNameT imageNameW /* define the generic TCHAR* version */ +#define imagePath imagePathW +#define vmName vmNameW +#define vmPath vmPathW +#else +#define imageNameT imageName +#define imagePath imagePathA +#define vmName vmNameA +#define vmPath vmPathA +#endif extern UINT SQ_LAUNCH_DROP; extern const TCHAR U_ON[]; extern const TCHAR U_OFF[]; extern const TCHAR U_GLOBAL[]; -extern const TCHAR U_SLASH[]; -extern const TCHAR U_BACKSLASH[]; +extern const WCHAR W_BACKSLASH[]; #ifndef NO_PREFERENCES extern HMENU vmPrefsMenu; /* preferences menu */ @@ -293,7 +307,6 @@ extern BITMAPINFO *bmi4; /* 4 bit depth bitmap info */ extern BITMAPINFO *bmi8; /* 8 bit depth bitmap info */ extern BITMAPINFO *bmi16; /* 16 bit depth bitmap info */ extern BITMAPINFO *bmi32; /* 32 bit depth bitmap info */ -extern BOOL fWindows95; /* Are we running on Win95 or NT? */ extern BOOL fIsConsole; /* Are we running as a console app? */ /* Startup options */ @@ -332,32 +345,11 @@ extern BOOL f3ButtonMouse; /* Should we use a real 3 button mouse mapping? */ extern BOOL fBufferMouse; /* Should we buffer mouse input? */ -/******************************************************/ -/* String conversions between Unicode / Ansi / Squeak */ -/******************************************************/ -/* Note: fromSqueak() and fromSqueak2() are inline conversions - but operate on two different buffers. The maximum length - of strings that can be converted is MAX_PATH */ -TCHAR* fromSqueak(const char *sqPtr, int sqLen); /* Inline Squeak -> C */ -TCHAR* fromSqueak2(const char *sqPtr, int sqLen); /* 2nd inline conversion */ -/* Note: toUnicode() and fromUnicode() are inline conversions - with for at most MAX_PATH sized strings. If the VM - is not compiled with UNICODE defined they just return - the input strings. Also, toUnicode operates on the - same buffer as fromSqueak() */ -TCHAR* toUnicode(const char *ptr); /* Inline Ansi -> Unicode */ -char* fromUnicode(const TCHAR *ptr); /* Inline Unicode -> Ansi */ -/* Note: toUnicodeNew and fromUnicodeNew malloc() new strings. - It is up to the caller to free these! */ -TCHAR* toUnicodeNew(const char *ptr); /* Inline Ansi -> Unicode */ -char* fromUnicodeNew(const TCHAR *ptr); /* Inline Unicode -> Ansi */ -TCHAR *lstrrchr(TCHAR *source, TCHAR c); - /******************************************************/ /* Output stuff */ /******************************************************/ #ifndef sqMessageBox -int __cdecl sqMessageBox(DWORD dwFlags, const TCHAR *titleString, const char* fmt, ...); +int __cdecl sqMessageBox(DWORD dwFlags, const TCHAR *titleString, const TCHAR* fmt, ...); #endif #ifndef warnPrintf @@ -380,7 +372,7 @@ void vprintLastError(TCHAR *fmt, ...); /******************************************************/ /* Misc functions */ /******************************************************/ -DWORD SqueakImageLength(TCHAR *fileName); +DWORD SqueakImageLength(WCHAR *fileName); int isLocalFileName(TCHAR *fileName); #ifndef NO_PLUGIN_SUPPORT diff --git a/platforms/win32/vm/sqWin32Alloc.c b/platforms/win32/vm/sqWin32Alloc.c index a3b51dd364..e5f857fdf0 100644 --- a/platforms/win32/vm/sqWin32Alloc.c +++ b/platforms/win32/vm/sqWin32Alloc.c @@ -76,7 +76,7 @@ void *sqAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize) } while(!pageBase); if(!pageBase) { sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), - "Unable to allocate memory (%d bytes requested)", + TEXT("Unable to allocate memory (%d bytes requested)"), maxReserved); return pageBase; } @@ -84,7 +84,7 @@ void *sqAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize) commit = nowReserved; if(!VirtualAlloc(pageBase, commit, MEM_COMMIT, PAGE_READWRITE)) { sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), - "Unable to commit memory (%d bytes requested)", + TEXT("Unable to commit memory (%d bytes requested)"), commit); return NULL; } diff --git a/platforms/win32/vm/sqWin32DnsInfo.c b/platforms/win32/vm/sqWin32DnsInfo.c index bd4e6d20c2..d219ffe326 100644 --- a/platforms/win32/vm/sqWin32DnsInfo.c +++ b/platforms/win32/vm/sqWin32DnsInfo.c @@ -15,8 +15,8 @@ static void lookup(HKEY hk, char *key, char lkupbuf[LOOKUPBUFSIZ]) { DWORD dwLength = LOOKUPBUFSIZ - 1; lkupbuf[0] = 0; - (void)RegQueryValueEx(hk, key, NULL, NULL, (BYTE *)lkupbuf, &dwLength); - if (lkupbuf[dwLength]) lkupbuf[dwLength] = 0; + (void)RegQueryValueExA(hk, key, NULL, NULL, (BYTE *)lkupbuf, &dwLength); + lkupbuf[dwLength] = 0; } /* Print base registry info. Return true if DNS info was provided. */ @@ -27,9 +27,9 @@ printBaseInfo(char *hkeyName) { int result = 0; char value[LOOKUPBUFSIZ]; - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, hkeyName, 0, KEY_READ, &hkey); + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, hkeyName, 0, KEY_READ, &hkey); if(ret != ERROR_SUCCESS) { - printf("RegOpenKeyEx failed\n"); + printf("RegOpenKeyExA failed\n"); return vm->primitiveFail(); } @@ -89,9 +89,9 @@ printAdapterInfo(char *hkeyName) { int result = 0; char value[LOOKUPBUFSIZ]; - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, hkeyName, 0, KEY_READ, &hkey); + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, hkeyName, 0, KEY_READ, &hkey); if(ret != ERROR_SUCCESS) { - printf("RegOpenKeyEx failed\n"); + printf("RegOpenKeyExA failed\n"); return vm->primitiveFail(); } @@ -166,11 +166,11 @@ EXPORT(int) primitiveDnsInfo(void) { goto done; /* Enumerate the available interfaces */ - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, BASE_KEY, 0, KEY_READ, &hkey); + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, BASE_KEY, 0, KEY_READ, &hkey); for(index=0;;index++) { char keyName[1024]; dwLength = sizeof(adapter); - ret = RegEnumKeyEx(hkey, index, adapter, &dwLength, NULL, NULL, NULL, NULL); + ret = RegEnumKeyExA(hkey, index, adapter, &dwLength, NULL, NULL, NULL, NULL); if(ret != ERROR_SUCCESS) break; strcpy(keyName, BASE_KEY); strcat(keyName, "\\"); diff --git a/platforms/win32/vm/sqWin32ExternalPrims.c b/platforms/win32/vm/sqWin32ExternalPrims.c index 3c05397ba5..8653472393 100644 --- a/platforms/win32/vm/sqWin32ExternalPrims.c +++ b/platforms/win32/vm/sqWin32ExternalPrims.c @@ -41,7 +41,10 @@ void *ioLoadModule(char *pluginName) TCHAR *name; #ifdef UNICODE - name = toUnicode(pluginName); + int len = MultiByteToWideChar(CP_UTF8, 0, pluginName, -1, NULL, 0); + if (len <= 0) return 0; /* invalid UTF8 ? */ + name = alloca(len*sizeof(WCHAR)); + if (MultiByteToWideChar(CP_UTF8, 0, pluginName, -1, name, len) == 0) return 0; #else name = pluginName; #endif diff --git a/platforms/win32/vm/sqWin32Main.c b/platforms/win32/vm/sqWin32Main.c index 7f292669eb..51b91b2e9c 100644 --- a/platforms/win32/vm/sqWin32Main.c +++ b/platforms/win32/vm/sqWin32Main.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /* _O_BINARY */ #include #include @@ -127,13 +128,13 @@ BOOL fIsConsole = 0; TCHAR consoleBuffer[4096]; /* stderr and stdout names */ -char stderrName[MAX_PATH+1]; -char stdoutName[MAX_PATH+1]; +WCHAR stderrName[MAX_PATH+1]; +WCHAR stdoutName[MAX_PATH+1]; -static char vmLogDirA[MAX_PATH]; +static char vmLogDirA[MAX_PATH_UTF8]; static WCHAR vmLogDirW[MAX_PATH]; -TCHAR *logName = TEXT(""); /* full path and name to log file */ +WCHAR *logName = L""; /* full path and name to log file */ #ifdef VISTA_SECURITY BOOL fLowRights = 0; /* started as low integiry process, @@ -141,9 +142,8 @@ BOOL fLowRights = 0; /* started as low integiry process, #endif /* VISTA_SECURITY */ /* Service stuff */ -TCHAR serviceName[MAX_PATH+1]; /* The name of the NT service */ -TCHAR *installServiceName = NULL; /* the name under which the service is to install */ -BOOL fBroadcastService95 = 0; /* Do we need a broadcast when a user has logged on? */ +WCHAR serviceName[MAX_PATH+1]; /* The name of the NT service */ +WCHAR *installServiceName = NULL; /* the name under which the service is to install */ UINT WM_BROADCAST_SERVICE = 0; /* The broadcast message we send */ TCHAR *msgBroadcastService = TEXT("SQUEAK_SERVICE_BROADCAST_MESSAGE"); /* The name of the broadcast message */ @@ -159,8 +159,17 @@ void SetSystemTrayIcon(BOOL on); _RC_NEAR: round to nearest _PC_53 : double precision arithmetic (instead of extended) _EM_XXX: silent operations (no signals please) + NOTE: precision control and infinity control are not defined on ARM or X64 (SSE oblige), only X86 */ +# if defined(_M_IX86) || defined(X86) || defined(_M_I386) || defined(_X86_) \ + || defined(i386) || defined(i486) || defined(i586) || defined(i686) \ + || defined(__i386__) || defined(__386__) || defined(I386) #define FPU_DEFAULT (_RC_NEAR + _PC_53 + _EM_INVALID + _EM_ZERODIVIDE + _EM_OVERFLOW + _EM_UNDERFLOW + _EM_INEXACT + _EM_DENORMAL) +#define FPU_MASK (_MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC) +#else +#define FPU_DEFAULT (_RC_NEAR + _EM_INVALID + _EM_ZERODIVIDE + _EM_OVERFLOW + _EM_UNDERFLOW + _EM_INEXACT + _EM_DENORMAL) +#define FPU_MASK (_MCW_EM | _MCW_RC) +#endif /****************************************************************************/ /* Exception handling */ @@ -191,7 +200,7 @@ extern sqInt primitiveFailForFFIExceptionat(usqLong exceptionCode, usqInt pc); DWORD code = exp->ExceptionRecord->ExceptionCode; if ((code >= EXCEPTION_FLT_DENORMAL_OPERAND) && (code <= EXCEPTION_FLT_UNDERFLOW)) { /* turn on the default masking of exceptions in the FPU and proceed */ - _controlfp(FPU_DEFAULT, _MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC); + _controlfp(FPU_DEFAULT, FPU_MASK); result = EXCEPTION_CONTINUE_EXECUTION; } } @@ -234,17 +243,17 @@ void UninstallExceptionHandler(void) #if __MINGW32__ # include static FILE * -fopen_for_append(char *filename) +fopen_for_append(WCHAR *filename) { - FILE *f = !access(filename, F_OK) /* access is bass ackwards */ - ? fopen(filename,"r+") - : fopen(filename,"w+"); + FILE *f = !_waccess(filename, F_OK) /* access is bass ackwards */ + ? _wfopen(filename,L"r+") + : _wfopen(filename,L"w+"); if (f) fseek(f,0,SEEK_END); return f; } #else -# define fopen_for_append(filename) fopen(filename,"a+t") +# define fopen_for_append(filename) _wfopen(filename,L"a+t") #endif /****************************************************************************/ @@ -263,6 +272,19 @@ OutputLogMessage(char *string) return 1; } +static int +OutputLogMessageW(WCHAR *string) +{ + int len = WideCharToMultiByte(CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL); + char *utf8 = malloc(len); + if (!utf8) return 1; + WideCharToMultiByte(CP_UTF8, 0, string, -1, utf8, len, NULL, NULL); + OutputLogMessage(utf8); + free(utf8); + return 1; +} + + static int OutputConsoleString(char *string) { @@ -292,7 +314,7 @@ OutputConsoleString(char *string) } // recommend using DPRINTF ifdef'ing to DPRINTF for debug output -int __cdecl DPRINTF(const char *fmt, ...) +int __cdecl DPRINTF(const TCHAR *fmt, ...) { va_list al; va_start(al, fmt); @@ -300,7 +322,7 @@ int __cdecl DPRINTF(const char *fmt, ...) wvsprintf(consoleBuffer, fmt, al); OutputDebugString(consoleBuffer); } - vfprintf(stdout, fmt, al); + _vftprintf(stdout, fmt, al); va_end(al); return 1; } @@ -358,12 +380,6 @@ static messageHook nextMessageHook = NULL; int ServiceMessageHook(void * hwnd, unsigned int message, unsigned int wParam, long lParam) { - if (fRunService && fWindows95 && message == WM_BROADCAST_SERVICE && hwnd == stWindow) - { - /* broadcast notification - install the running Win95 service in the system tray */ - SetSystemTrayIcon(1); - return 1; - } if (message == WM_USERCHANGED) { SetSystemTrayIcon(1); @@ -402,40 +418,13 @@ void SetSystemTrayIcon(BOOL on) nid.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; nid.uCallbackMessage = WM_USER+42; nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(1)); - strcpy(nid.szTip, VM_NAME "!"); + _tcscpy(nid.szTip, TEXT(VM_NAME) TEXT("!")); if (on) (*ShellNotifyIcon)(NIM_ADD, &nid); else (*ShellNotifyIcon)(NIM_DELETE, &nid); } -void SetupService95() -{ -#ifndef NO_SERVICE -#ifndef RSP_SIMPLE_SERVICE -#define RSP_SIMPLE_SERVICE 1 -#endif - BOOL (WINAPI *RegisterServiceProcess)(DWORD,DWORD); - static HMODULE hKernel32 = NULL; - - /* Inform Windows95 that we're running as a service process */ - if (!fRunService || !fWindows95) return; - hKernel32 = LoadLibrary(TEXT("kernel32.dll")); - if (!hKernel32) - { - printLastError(TEXT("Unable to load kernel32.dll")); - return; - } - (FARPROC) RegisterServiceProcess = GetProcAddress(hKernel32, "RegisterServiceProcess"); - if (!RegisterServiceProcess) - { - printLastError(TEXT("Unable to find RegisterServiceProcess")); - return; - } - if ( !(*RegisterServiceProcess)(GetCurrentProcessId(), RSP_SIMPLE_SERVICE ) ) - printLastError(TEXT("RegisterServiceProcess failed")); -#endif /* NO_SERVICE */ -} /****************************************************************************/ /* System Attributes */ @@ -462,7 +451,7 @@ char *ioGetLogDirectory(void) { } sqInt ioSetLogDirectoryOfSize(void* lblIndex, sqInt sz) { - if (sz >= MAX_PATH) return 0; + if (sz >= MAX_PATH_UTF8) return 0; strncpy(vmLogDirA, lblIndex, sz); vmLogDirA[sz] = 0; MultiByteToWideChar(CP_UTF8, 0, vmLogDirA, -1, vmLogDirW, MAX_PATH); @@ -509,6 +498,18 @@ char *hwInfoString = ""; char *gdInfoString = ""; char *win32VersionName = ""; +void RegLookupUTF8String(HKEY hk, WCHAR *name, char *utf8, size_t utf8_len) +{ + WCHAR bufferW[MAX_PATH]; + DWORD dwSize = MAX_PATH * sizeof(WCHAR); + LSTATUS ok = RegQueryValueExW(hk, name, NULL, NULL,(LPBYTE)bufferW, &dwSize); + if (ok != ERROR_SUCCESS) strncpy(utf8, "???",utf8_len); + else { + int len = WideCharToMultiByte(CP_UTF8, 0, bufferW, -1, utf8, utf8_len, NULL, NULL); + if (len <= 0) strncpy(utf8, "???", utf8_len); + } +} + void gatherSystemInfo(void) { OSVERSIONINFOEX osInfo; MEMORYSTATUS memStat; @@ -517,7 +518,7 @@ void gatherSystemInfo(void) { int proc, screenX, screenY; char tmpString[2048]; - char keyName[256]; + WCHAR keyName[256]; DWORD ok, dwSize; HKEY hk; @@ -549,18 +550,21 @@ void gatherSystemInfo(void) { } { /* Figure out make and model from OEMINFO.ini */ - char iniName[256]; - char manufacturer[256]; - char model[256]; + WCHAR iniName[MAX_PATH]; + WCHAR bufferW[MAX_PATH]; + char manufacturer[MAX_PATH_UTF8]; + char model[MAX_PATH_UTF8]; - GetSystemDirectory(iniName, 256); - strcat(iniName,"\\OEMINFO.INI"); + GetSystemDirectoryW(iniName, MAX_PATH); + wcsncat(iniName,L"\\OEMINFO.INI",MAX_PATH-1-wcslen(iniName)); - GetPrivateProfileString("General", "Manufacturer", "Unknown", - manufacturer, 256, iniName); + GetPrivateProfileStringW(L"General", L"Manufacturer", L"Unknown", + bufferW, MAX_PATH, iniName); + if (WideCharToMultiByte(CP_UTF8, 0, bufferW, -1, manufacturer, MAX_PATH_UTF8, NULL, NULL) == 0) strcpy(manufacturer, "???"); - GetPrivateProfileString("General", "Model", "Unknown", - model, 256, iniName); + GetPrivateProfileStringW(L"General", L"Model", L"Unknown", + bufferW, MAX_PATH, iniName); + if (WideCharToMultiByte(CP_UTF8, 0, bufferW, -1, model, MAX_PATH_UTF8, NULL, NULL) == 0) strcpy(model, "???"); sprintf(tmpString, "Hardware information: \n" @@ -593,30 +597,23 @@ void gatherSystemInfo(void) { char *tmp = tmpString + strlen(tmpString); - strcpy(keyName, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"); - keyName[strlen(keyName)-1] = 48+proc; /* 0, 1, 2 etc. */ + wcscpy(keyName, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"); + keyName[wcslen(keyName)-1] = 48+proc; /* 0, 1, 2 etc. */ - ok = RegOpenKey(HKEY_LOCAL_MACHINE, keyName, &hk); + ok = RegOpenKeyW(HKEY_LOCAL_MACHINE, keyName, &hk); if (!ok) { - char nameString[256]; - char identifier[256]; + char nameString[MAX_PATH_UTF8]; + char identifier[MAX_PATH_UTF8]; DWORD mhz; - dwSize = 256; - ok = RegQueryValueEx(hk, "ProcessorNameString", NULL, NULL, - (LPBYTE)nameString, &dwSize); - if (ok) strcpy(nameString, "???"); - - dwSize = 256; - ok = RegQueryValueEx(hk, "Identifier", NULL, NULL, - (LPBYTE)identifier, &dwSize); - if (ok) strcpy(identifier, "???"); + RegLookupUTF8String(hk, L"ProcessorNameString", nameString, MAX_PATH_UTF8); + RegLookupUTF8String(hk, L"Identifier", identifier, MAX_PATH_UTF8); dwSize = sizeof(DWORD); - ok = RegQueryValueEx(hk, "~MHz", NULL, NULL, + ok = RegQueryValueExW(hk, L"~MHz", NULL, NULL, (LPBYTE)&mhz, &dwSize); if (ok) mhz = -1; - sprintf(tmp, + snprintf(tmp, sizeof(tmpString)-strlen(tmpString), "\nProcessor %d: %s\n" "\tIdentifier: %s\n" "\t~MHZ: %lu\n", @@ -628,30 +625,50 @@ void gatherSystemInfo(void) { hwInfoString = _strdup(tmpString); { - char owner[256]; - char company[256]; - char product[256]; + char owner[MAX_PATH_UTF8]; + char company[MAX_PATH_UTF8]; + char product[MAX_PATH_UTF8]; if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { - strcpy(keyName, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"); + wcscpy(keyName, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"); } else { - strcpy(keyName, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion"); + wcscpy(keyName, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion"); } - ok = RegOpenKey(HKEY_LOCAL_MACHINE, keyName, &hk); + ok = RegOpenKeyW(HKEY_LOCAL_MACHINE, keyName, &hk); if (!ok) { - dwSize = 256; - if (RegQueryValueEx(hk, "RegisteredOwner", NULL, NULL, - (LPBYTE)owner, &dwSize)) strcpy(owner, "???"); - dwSize = 256; - if (RegQueryValueEx(hk, "RegisteredOrganization", NULL, NULL, - (LPBYTE)company, &dwSize)) strcpy(company, "???"); - dwSize = 256; - if (RegQueryValueEx(hk, "ProductName", NULL, NULL, - (LPBYTE)product, &dwSize)) strcpy(product, "???"); - RegCloseKey(hk); - } + RegLookupUTF8String(hk, L"RegisteredOwner", owner, MAX_PATH_UTF8); + RegLookupUTF8String(hk, L"RegisteredOrganization", company, MAX_PATH_UTF8); + RegLookupUTF8String(hk, L"ProductName", product, MAX_PATH_UTF8); + } else { + strcpy(owner, "???"); + strcpy(company, "???"); + strcpy(product, "???"); + } - sprintf(tmpString, +#if defined(_MSC_VER) && _MSC_VER < 1300 +# define wSuiteMask wReserved[0] +# define wProductType wReserved[1] & 0xFF +#endif +#ifdef UNICODE + { + char buf[128 * 3]; + if(WideCharToMultiByte(CP_UTF8,0, osInfo.szCSDVersion,-1,buf,sizeof(buf),NULL,NULL)) + snprintf(tmpString, sizeof(tmpString), + "Operating System: %s (Build %lu %s)\n" + "\tRegistered Owner: %s\n" + "\tRegistered Company: %s\n" + "\tSP major version: %d\n" + "\tSP minor version: %d\n" + "\tSuite mask: %x\n" + "\tProduct type: %x\n", + product, + osInfo.dwBuildNumber, buf, + owner, company, + osInfo.wServicePackMajor, osInfo.wServicePackMinor, + osInfo.wSuiteMask, osInfo.wProductType); + } +#else + snprintf(tmpString,sizeof(tmpString), "Operating System: %s (Build %lu %s)\n" "\tRegistered Owner: %s\n" "\tRegistered Company: %s\n" @@ -663,41 +680,50 @@ void gatherSystemInfo(void) { osInfo.dwBuildNumber, osInfo.szCSDVersion, owner, company, osInfo.wServicePackMajor, osInfo.wServicePackMinor, -#if defined(_MSC_VER) && _MSC_VER < 1300 -# define wSuiteMask wReserved[0] -# define wProductType wReserved[1] & 0xFF -#endif osInfo.wSuiteMask, osInfo.wProductType); +#endif osInfoString = _strdup(tmpString); } - sprintf(tmpString, - "Display Information: \n" - "\tGraphics adapter name: %s\n" - "\tPrimary monitor resolution: %d x %d\n", +#ifdef UNICODE + { + char buf[128*3]; + if(WideCharToMultiByte(CP_UTF8,0,gDev.DeviceString,-1,buf,sizeof(buf),NULL,NULL)) snprintf(tmpString, sizeof(tmpString), + "Display Information: \n" + "\tGraphics adapter name: %s\n" + "\tPrimary monitor resolution: %d x %d\n", + buf, + screenX, screenY); + } +#else + snprintf(tmpString, sizeof(tmpString), + TEXT("Display Information: \n") + TEXT("\tGraphics adapter name: %s\n") + TEXT("\tPrimary monitor resolution: %d x %d\n"), gDev.DeviceString, screenX, screenY); +#endif /* Find the driver key in the registry */ keyName[0] = 0; - ok = RegOpenKey(HKEY_LOCAL_MACHINE, - "HARDWARE\\DEVICEMAP\\VIDEO", + ok = RegOpenKeyW(HKEY_LOCAL_MACHINE, + L"HARDWARE\\DEVICEMAP\\VIDEO", &hk); if (!ok) { - dwSize = 256; - RegQueryValueEx(hk,"\\Device\\Video0", NULL, NULL, + dwSize = 256*sizeof(WCHAR); + RegQueryValueExW(hk,L"\\Device\\Video0", NULL, NULL, (LPBYTE)keyName, &dwSize); RegCloseKey(hk); } if (*keyName) { /* Got the key name; open it and get the info out of there */ char *tmp = tmpString + strlen(tmpString); - char deviceDesc[256]; - char adapterString[256]; - char biosString[256]; - char chipType[256]; - char dacType[256]; - char *drivers, *drv; + char deviceDesc[MAX_PATH_UTF8]; + char adapterString[MAX_PATH_UTF8]; + char biosString[MAX_PATH_UTF8]; + char chipType[MAX_PATH_UTF8]; + char dacType[MAX_PATH_UTF8]; + WCHAR *drivers, *drv; WCHAR buffer[256]; DWORD memSize; @@ -705,48 +731,20 @@ void gatherSystemInfo(void) { with \Registry\Machine\ which doesn't work with RegOpenKey below. I have no idea why but for now I'll just truncate that part if we recognize it... */ - if (_strnicmp(keyName, "\\registry\\machine\\", 18) == 0) { - memcpy(keyName, keyName+18, strlen(keyName)-17); + if (_wcsnicmp(keyName, L"\\registry\\machine\\", 18) == 0) { + memmove(keyName, keyName+18, (wcslen(keyName)+1-18)*sizeof(WCHAR)); /* +1 for terminating NULL */ } - ok = RegOpenKey(HKEY_LOCAL_MACHINE, keyName, &hk); - if (ok) MessageBox(0, keyName, "Cannot open:", MB_OK); + ok = RegOpenKeyW(HKEY_LOCAL_MACHINE, keyName, &hk); + if (ok) MessageBoxW(0, keyName, L"Cannot open:", MB_OK); if (!ok) { - dwSize = 256; - ok = RegQueryValueEx(hk,"Device Description", NULL, NULL, - (LPBYTE)deviceDesc, &dwSize); - if (ok) strcpy(deviceDesc, "???"); - - dwSize = 256*sizeof(WCHAR); - ok = RegQueryValueEx(hk,"HardwareInformation.AdapterString", NULL, NULL, - (LPBYTE)buffer, &dwSize); - if (!ok) { - WideCharToMultiByte(CP_UTF8,0,buffer,-1,adapterString,256,NULL,NULL); - } else strcpy(adapterString, "???"); - - dwSize = 256*sizeof(WCHAR); - ok = RegQueryValueEx(hk,"HardwareInformation.BiosString", NULL, NULL, - (LPBYTE)buffer, &dwSize); - if (!ok) { - WideCharToMultiByte(CP_UTF8,0,buffer,-1,biosString,256,NULL,NULL); - } else strcpy(biosString, "???"); - - dwSize = 256*sizeof(WCHAR); - ok = RegQueryValueEx(hk,"HardwareInformation.ChipType", NULL, NULL, - (LPBYTE)buffer, &dwSize); - if (!ok) { - WideCharToMultiByte(CP_UTF8,0,buffer,-1,chipType,256,NULL,NULL); - } else strcpy(chipType, "???"); - - dwSize = 256*sizeof(WCHAR); - ok = RegQueryValueEx(hk,"HardwareInformation.DacType", NULL, NULL, - (LPBYTE)buffer, &dwSize); - if (!ok) { - WideCharToMultiByte(CP_UTF8,0,buffer,-1,dacType,256,NULL,NULL); - } else strcpy(dacType, "???"); - + RegLookupUTF8String(hk, L"Device Description", deviceDesc, MAX_PATH_UTF8); + RegLookupUTF8String(hk, L"HardwareInformation.AdapterString", adapterString, MAX_PATH_UTF8); + RegLookupUTF8String(hk, L"HardwareInformation.BiosString", biosString, MAX_PATH_UTF8); + RegLookupUTF8String(hk, L"HardwareInformation.ChipType", chipType, MAX_PATH_UTF8); + RegLookupUTF8String(hk, L"HardwareInformation.DacType", dacType, MAX_PATH_UTF8); dwSize = sizeof(DWORD); - ok = RegQueryValueEx(hk,"HardwareInformation.MemorySize", NULL, NULL, + ok = RegQueryValueExW(hk,L"HardwareInformation.MemorySize", NULL, NULL, (LPBYTE)&memSize, &dwSize); if (ok) memSize = -1; @@ -765,47 +763,62 @@ void gatherSystemInfo(void) { memSize); /* Now process the installed drivers */ - ok = RegQueryValueEx(hk,"InstalledDisplayDrivers", + ok = RegQueryValueExW(hk,L"InstalledDisplayDrivers", NULL, NULL, NULL, &dwSize); if (!ok) { drivers = malloc(dwSize); - ok = RegQueryValueEx(hk,"InstalledDisplayDrivers", + ok = RegQueryValueExW(hk,L"InstalledDisplayDrivers", NULL, NULL, (LPBYTE)drivers, &dwSize); } if (!ok) { - strcat(tmpString,"\nDriver Versions:"); + strncat(tmpString,"\nDriver Versions:",sizeof(tmpString) - 1 - strlen(tmpString)); /* InstalledDrivers is REG_MULTI_SZ (extra terminating zero) */ - for(drv = drivers; drv[0]; drv +=strlen(drv)) { + for(drv = drivers; drv[0]; drv +=wcslen(drv)) { DWORD verSize, hh; UINT vLen; LPVOID verInfo = NULL, vInfo; + char drvA[MAX_PATH_UTF8]; /* Concat driver name */ - strcat(tmpString,"\n\t"); - strcat(tmpString, drv); - strcat(tmpString,": "); + if (WideCharToMultiByte(CP_UTF8,0,drv,-1,drvA,MAX_PATH_UTF8,NULL,NULL)>0) { + strncat(tmpString, "\n\t", sizeof(tmpString) - 1 - strlen(tmpString)); + strncat(tmpString, drvA , sizeof(tmpString) - 1 - strlen(tmpString)); + strncat(tmpString, ": " , sizeof(tmpString) - 1 - strlen(tmpString)); + } - verSize = GetFileVersionInfoSize(drv, &hh); + verSize = GetFileVersionInfoSizeW(drv, &hh); if (!verSize) goto done; verInfo = malloc(verSize); - if (!GetFileVersionInfo(drv, 0, verSize, verInfo)) goto done; + if (!GetFileVersionInfoW(drv, 0, verSize, verInfo)) goto done; /* Try Unicode first */ - if (VerQueryValue(verInfo,"\\StringFileInfo\\040904B0\\FileVersion", + if (VerQueryValueW(verInfo,L"\\StringFileInfo\\040904B0\\FileVersion", &vInfo, &vLen)) { - strcat(tmpString, vInfo); - goto done; + int utf8_len = WideCharToMultiByte(CP_UTF8, 0, vInfo, -1, NULL, 0, NULL, NULL); + char *utf8 = (char *)malloc(utf8_len); + if(utf8) { + WideCharToMultiByte(CP_UTF8, 0, vInfo, -1, utf8, utf8_len, NULL, NULL); + strncat(tmpString, utf8,sizeof(tmpString) - 1 - strlen(tmpString)); + free(utf8); + goto done; + } } /* Try US/English next */ - if (VerQueryValue(verInfo,"\\StringFileInfo\\040904E4\\FileVersion", + if (VerQueryValueW(verInfo,L"\\StringFileInfo\\040904E4\\FileVersion", &vInfo, &vLen)) { - strcat(tmpString, vInfo); - goto done; + int utf8_len = WideCharToMultiByte(CP_UTF8, 0, vInfo, -1, NULL, 0, NULL, NULL); + char *utf8 = (char *)malloc(utf8_len); + if (utf8) { + WideCharToMultiByte(CP_UTF8, 0, vInfo, -1, utf8, utf8_len, NULL, NULL); + strncat(tmpString, utf8, sizeof(tmpString) - 1 - strlen(tmpString)); + free(utf8); + goto done; + } } - strcat(tmpString, "???"); + strncat(tmpString, "???", sizeof(tmpString) - 1 - strlen(tmpString)); done: if (verInfo) { @@ -813,7 +826,7 @@ void gatherSystemInfo(void) { verInfo = NULL; } } - strcat(tmpString,"\n"); + strncat(tmpString,"\n",sizeof(tmpString) - 1 - strlen(tmpString)); } RegCloseKey(hk); } @@ -992,22 +1005,22 @@ versionInfo(void) /* Error handling */ /****************************************************************************/ void SetupStderr() -{ TCHAR tmpName[MAX_PATH+1]; +{ WCHAR tmpName[MAX_PATH+1]; *stderrName = *stdoutName = 0; /* re-open stdout && stderr */ - GetTempPath(MAX_PATH,tmpName); + GetTempPathW(MAX_PATH,tmpName); if(GetStdHandle(STD_ERROR_HANDLE) == INVALID_HANDLE_VALUE) { - GetTempFileName(tmpName,TEXT("sq"),0,stderrName); - freopen(stderrName,"w+t",stderr); + GetTempFileNameW(tmpName,L"sq",0,stderrName); + _wfreopen(stderrName,L"w+t",stderr); } else *stderrName = 0; if(GetStdHandle(STD_OUTPUT_HANDLE) == INVALID_HANDLE_VALUE) { - GetTempFileName(tmpName,TEXT("sq"),0,stdoutName); - freopen(stdoutName,"w+t",stdout); + GetTempFileNameW(tmpName,L"sq",0,stdoutName); + _wfreopen(stdoutName,L"w+t",stdout); } else *stdoutName = 0; } @@ -1080,7 +1093,7 @@ extern char *__cogitBuildInfo; fprintf(f,"\n%s", gdInfoString); /* print VM version information */ - fprintf(f,"\nVM Version: %s\n", VM_VERSION_TEXT); + fprintf(f,"\nVM Version: %s\n", VM_VERSION_VERBOSE); #if STACKVM fprintf(f,"Interpreter Build: %s\n", __interpBuildInfo); # if COGVM @@ -1121,41 +1134,54 @@ static int inError = 0; void error(char *msg) { FILE *f; - TCHAR crashInfo[1024]; + WCHAR crashInfo[1024]; void *callstack[MAXFRAMES]; symbolic_pc symbolic_pcs[MAXFRAMES]; int nframes; int inVMThread = ioOSThreadsEqual(ioCurrentOSThread(),getVMOSThread()); + int len; + WCHAR *msgW; if (inError) exit(-2); inError = 1; - nframes = backtrace(callstack, MAXFRAMES); - symbolic_backtrace(++nframes, callstack, symbolic_pcs); - - wsprintf(crashInfo, - TEXT("Sorry but the VM has crashed.\n\n") - TEXT("Reason: %s\n\n") - TEXT("Current byte code: %d\n") - TEXT("Primitive index: %d\n\n") - TEXT("This information will be stored in the file\n") - TEXT("%s\\%s\n") - TEXT("with a complete stack dump"), - msg, - getCurrentBytecode(), - methodPrimitiveIndex(), - vmLogDirA, - TEXT("crash.dmp")); + nframes = backtrace(callstack, MAXFRAMES); + symbolic_backtrace(++nframes, callstack, symbolic_pcs); + + len = MultiByteToWideChar(CP_UTF8, 0, msg, -1, NULL, 0); + if (len > 0) { + msgW = alloca(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, msg, -1, msgW, len); + } + else { + msgW = alloca(4 * sizeof(WCHAR)); + wcscpy(msgW, L"???"); + } +#define __UNICODE_TEXT(x) L##x +#define _UNICODE_TEXT(x) __UNICODE_TEXT(x) + _snwprintf(crashInfo,1024, + L"Sorry but the VM has crashed.\n\n" + L"Reason: %s\n\n" + L"Current byte code: %d\n" + L"Primitive index: %" _UNICODE_TEXT(PRIdSQINT) L"\n\n" + L"This information will be stored in the file\n" + L"%s\\%s\n" + L"with a complete stack dump", + msgW, + getCurrentBytecode(), + methodPrimitiveIndex(), + vmLogDirW, + L"crash.dmp"); if(!fHeadlessImage) - MessageBox(stWindow,crashInfo,TEXT("Fatal VM error"), + MessageBoxW(stWindow,crashInfo,L"Fatal VM error", MB_OK | MB_APPLMODAL | MB_ICONSTOP); #if !NewspeakVM SetCurrentDirectoryW(vmLogDirW); #endif /* print the above information */ - f = fopen_for_append("crash.dmp"); + f = fopen_for_append(L"crash.dmp"); if(f){ time_t crashTime = time(NULL); fprintf(f,"---------------------------------------------------------------------\n"); @@ -1210,7 +1236,7 @@ printCrashDebugInformation(LPEXCEPTION_POINTERS exp) void *callstack[MAXFRAMES]; symbolic_pc symbolic_pcs[MAXFRAMES]; int nframes, inVMThread; - TCHAR crashInfo[1024]; + WCHAR crashInfo[1024]; FILE *f; int byteCode = -2; @@ -1237,32 +1263,36 @@ printCrashDebugInformation(LPEXCEPTION_POINTERS exp) callstack+1, MAXFRAMES-1); symbolic_backtrace(++nframes, callstack, symbolic_pcs); - wsprintf(crashInfo, - TEXT("Sorry but the VM has crashed.\n\n") - TEXT("Exception code: %08X\n") - TEXT("Exception address: %08X\n") - TEXT("Current byte code: %d\n") - TEXT("Primitive index: %d\n\n") - TEXT("Crashed in %s thread\n\n") - TEXT("This information will be stored in the file\n") - TEXT("%s\\%s\n") - TEXT("with a complete stack dump"), + _snwprintf(crashInfo,1024, + L"Sorry but the VM has crashed.\n\n" + L"Exception code: %08x\n" +#ifdef _WIN64 + L"Exception address: %016" _UNICODE_TEXT(PRIxSQPTR) L"\n" +#else + L"Exception address: %08" _UNICODE_TEXT(PRIxSQPTR) L"\n" +#endif + L"Current byte code: %d\n" + L"Primitive index: %" _UNICODE_TEXT(PRIdSQINT) L"\n\n" + L"Crashed in %s thread\n\n" + L"This information will be stored in the file\n" + L"%s\\%s\n" + L"with a complete stack dump", exp->ExceptionRecord->ExceptionCode, - exp->ExceptionRecord->ExceptionAddress, + (sqIntptr_t) (exp->ExceptionRecord->ExceptionAddress), byteCode, methodPrimitiveIndex(), - inVMThread ? "the VM" : "some other", - vmLogDirA, - TEXT("crash.dmp")); + inVMThread ? L"the VM" : L"some other", + vmLogDirW, + L"crash.dmp"); if(!fHeadlessImage) - MessageBox(stWindow,crashInfo,TEXT("Fatal VM error"), + MessageBoxW(stWindow,crashInfo,L"Fatal VM error", MB_OK | MB_APPLMODAL | MB_ICONSTOP); #if !NewspeakVM SetCurrentDirectoryW(vmLogDirW); #endif /* print the above information */ - f = fopen_for_append("crash.dmp"); + f = fopen_for_append(L"crash.dmp"); if(f){ time_t crashTime = time(NULL); fprintf(f,"---------------------------------------------------------------------\n"); @@ -1372,7 +1402,7 @@ void __cdecl Cleanup(void) ioReleaseTime(); /* tricky ... we have no systray icon when running headfull or when running as service on NT */ - if(fHeadlessImage && (!fRunService || fWindows95)) + if(fHeadlessImage && (!fRunService)) SetSystemTrayIcon(0); if(palette) DeleteObject(palette); PROFILE_SHOW(ticksForReversal); @@ -1380,12 +1410,12 @@ void __cdecl Cleanup(void) if(*stderrName) { fclose(stderr); - remove(stderrName); + _wremove(stderrName); } if(*stdoutName) { fclose(stdout); - remove(stdoutName); + _wremove(stdoutName); } OleUninitialize(); } @@ -1405,7 +1435,7 @@ sqImageFile findEmbeddedImage(void) { int start; int length; - f = sqImageFileOpen(vmName, "rb"); + f = sqImageFileOpen(vmNameA, "rb"); if(!f) { MessageBox(0,"Error opening VM",VM_NAME,MB_OK); return 0; @@ -1415,7 +1445,7 @@ sqImageFile findEmbeddedImage(void) { sqImageFileSeek(f, endMarker); sqImageFileRead(&magic, 1, 4, f); sqImageFileRead(&start, 1, 4, f); - sqMessageBox(MB_OK, "Magic number", "Expected:\t%x\nFound:\t\t%x", SQ_IMAGE_MAGIC, magic); + sqMessageBox(MB_OK, TEXT("Magic number", "Expected:\t%x\nFound:\t\t%x"), SQ_IMAGE_MAGIC, magic); /* Magic number must be okay and start must be within executable boundaries */ if(magic != SQ_IMAGE_MAGIC || start < 0 || start >= endMarker) { /* nope */ @@ -1425,7 +1455,7 @@ sqImageFile findEmbeddedImage(void) { /* Might have an embedded image; seek back and double check */ sqImageFileSeek(f,start); sqImageFileRead(&magic, 1, 4, f); - sqMessageBox(MB_OK, "Magic number", "Expected:\t%x\nFound:\t\t%x", SQ_IMAGE_MAGIC, magic); + sqMessageBox(MB_OK, TEXT("Magic number", "Expected:\t%x\nFound:\t\t%x"), SQ_IMAGE_MAGIC, magic); if(magic != SQ_IMAGE_MAGIC) { /* nope */ sqImageFileClose(f); @@ -1441,6 +1471,7 @@ sqImageFile findEmbeddedImage(void) { /* Gotcha! */ sqImageFileSeek(f, sqImageFilePosition(f) - 4); strcpy(imageName, name); + MultiByteToWideChar(CP_UTF8,0,imageName,-1,imageNameW,MAX_PATH,NULL,NULL); imageSize = endMarker - sqImageFilePosition(f); return f; } @@ -1490,7 +1521,7 @@ sqMain(int argc, char *argv[]) int virtualMemory; /* set default fpu control word */ - _controlfp(FPU_DEFAULT, _MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC); + _controlfp(FPU_DEFAULT, FPU_MASK); LoadPreferences(); @@ -1498,9 +1529,9 @@ sqMain(int argc, char *argv[]) if(fRunSingleApp) { HWND win = GetTopWindow(0); while (win != NULL) { - char buf[MAX_PATH]; - GetClassName(win, buf, 80); - if(strcmp(windowClassName, buf) == 0) break; + TCHAR buf[MAX_PATH]; + GetClassName(win, buf, MAX_PATH); + if(_tcscmp(windowClassName, buf) == 0) break; win = GetNextWindow(win, GW_HWNDNEXT); } @@ -1547,11 +1578,6 @@ sqMain(int argc, char *argv[]) fRunService = 0; #endif - /* look for a few things easy to handle */ - if(fWindows95 && fBroadcastService95) { - PostMessage(HWND_BROADCAST, WM_BROADCAST_SERVICE, 0, 0); - return 0; - } /* set time zone accordingly */ _tzset(); @@ -1567,17 +1593,14 @@ sqMain(int argc, char *argv[]) svcStart = time(NULL); OutputLogMessage("\n\n"); OutputLogMessage(ctime(&svcStart)); - if(fWindows95) /* don't have a service name */ - OutputLogMessage("The service"); - else - OutputLogMessage(serviceName); + OutputLogMessageW(serviceName); OutputLogMessage(" started with the following command line\n"); OutputLogMessage(initialCmdLine); OutputLogMessage("\n"); } SetupFilesAndPath(); - ioSetLogDirectoryOfSize(vmPath, strlen(vmPath)); + ioSetLogDirectoryOfSize(vmPathA, strlen(vmPathA)); /* release resources on exit */ atexit(Cleanup); @@ -1585,7 +1608,7 @@ sqMain(int argc, char *argv[]) #ifndef NO_SERVICE /* if service installing is requested, do so */ if(installServiceName && *installServiceName) { - strcpy(serviceName, installServiceName); + wcscpy(serviceName, installServiceName); sqServiceInstall(); /* When installing was successful we won't come to this point. Otherwise ... */ @@ -1597,7 +1620,6 @@ sqMain(int argc, char *argv[]) SetupKeymap(); SetupWindows(); SetupPixmaps(); - SetupService95(); { extern void ioInitTime(void); extern void ioInitThreads(void); ioInitTime(); @@ -1620,7 +1642,7 @@ sqMain(int argc, char *argv[]) if(!imageFile) { - imageSize = SqueakImageLength(toUnicode(imageName)); + imageSize = SqueakImageLength(imageNameW); if(imageSize == 0) printUsage(2); } @@ -1650,13 +1672,13 @@ sqMain(int argc, char *argv[]) #if !NewspeakVM /* set the CWD to the image location */ - if(*imageName) { - char path[MAX_PATH+1], *ptr; - strcpy(path,imageName); - ptr = strrchr(path, '\\'); + if(*imageNameW) { + WCHAR path[MAX_PATH+1], *ptr; + wcsncpy(path,imageNameW,MAX_PATH); + ptr = wcsrchr(path, '\\'); if(ptr) { - *ptr = 0; - SetCurrentDirectory(path); + *ptr = 0; + SetCurrentDirectoryW(path); } } #endif /* !NewspeakVM */ @@ -1666,7 +1688,7 @@ sqMain(int argc, char *argv[]) /* if headless running is requested, try to to create an icon in the Win95/NT system tray */ - if(fHeadlessImage && (!fRunService || fWindows95)) + if(fHeadlessImage && (!fRunService)) SetSystemTrayIcon(1); /* read the image file */ @@ -1715,17 +1737,13 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) /* a few things which need to be done first */ gatherSystemInfo(); - /* check if we're running NT or 95 */ - fWindows95 = (GetVersion() & 0x80000000) != 0; - /* fetch us a copy of the command line */ initialCmdLine = _strdup(lpCmdLine); /* fetch us the name of the executable */ { - WCHAR vmNameW[MAX_PATH]; GetModuleFileNameW(hInst, vmNameW, MAX_PATH); - WideCharToMultiByte(CP_UTF8, 0, vmNameW, -1, vmName, MAX_PATH, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, vmNameW, -1, vmNameA, MAX_PATH_UTF8, NULL, NULL); } /* parse the command line into the unix-style argc, argv, converting to * UTF-8 on the way. */ @@ -1774,20 +1792,13 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) if somebody out there knows how to find out when we're starting as a service - LET ME KNOW! */ - if(!fWindows95) /* 1) running NT */ - if(!*lpCmdLine) /* 2) No command line */ - if(sqServiceMain()) /* try starting the service */ - return 0; /* service was run - exit */ + if(!*lpCmdLine) /* No command line */ + if(sqServiceMain()) /* try starting the service */ + return 0; /* service was run - exit */ #endif - SQ_LAUNCH_DROP = RegisterWindowMessage("SQUEAK_LAUNCH_DROP"); - - /* Special startup stuff for windows 95 */ - if(fWindows95) { - /* The message we use for notifying services of user logon */ - WM_BROADCAST_SERVICE = RegisterWindowMessage(msgBroadcastService); - } + SQ_LAUNCH_DROP = RegisterWindowMessage(TEXT("SQUEAK_LAUNCH_DROP")); /* start the non-service version */ sqMain(clargc, clargv); @@ -1836,19 +1847,27 @@ parseVMArgument(int argc, char *argv[]) /* parameters */ else if (argc > 1 && !strcmp(argv[0], VMOPTION("service"))) { - installServiceName = argv[1]; + int len = MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, installServiceName, 0); + installServiceName = malloc(len * sizeof(WCHAR)); /* note: we will never free installServiceName - it's a global for lifetime of the VM */ + MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, installServiceName, len); return 2; } else if (!strncmp(argv[0], VMOPTION("service:"), strlen(VMOPTION("service:")))) { - installServiceName = argv[0] + strlen(VMOPTION("service:")); + int len = MultiByteToWideChar(CP_UTF8, 0, argv[0] + strlen(VMOPTION("log:")), -1, installServiceName, 0); + logName = malloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, argv[0] + strlen(VMOPTION("log:")), -1, installServiceName, len); return 1; } else if (argc > 1 && !strcmp(argv[0], VMOPTION("log"))) { - logName = argv[1]; + int len=MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, logName, 0); + logName = malloc(len * sizeof(WCHAR)); /* note: we will never free logName - it's a global for lifetime of the VM */ + MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, logName, len); return 2; } else if (!strncmp(argv[0], VMOPTION("log:"), strlen(VMOPTION("log:")))) { - logName = argv[0] + strlen(VMOPTION("log:")); + int len = MultiByteToWideChar(CP_UTF8, 0, argv[0] + strlen(VMOPTION("log:")), -1, logName, 0); + logName = malloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, argv[0] + strlen(VMOPTION("log:")), -1, logName, len); return 1; } else if (argc > 1 && !strcmp(argv[0], VMOPTION("memory"))) { @@ -2013,10 +2032,6 @@ parseVMArgument(int argc, char *argv[]) #endif return 1; } - /* service support on 95 */ - else if (!strcmp(argv[0], VMOPTION("service95"))) { fRunService = true; return 1; } - else if (!strcmp(argv[0], VMOPTION("broadcast95"))) { fBroadcastService95 = true; return 1; } - return 0; /* option not recognised */ } @@ -2086,7 +2101,7 @@ SubsystemType() IMAGE_OPTIONAL_HEADER image_optional_header; /* Open the reference file. */ - hImage = CreateFile(vmName, + hImage = CreateFileW(vmNameW, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -2150,7 +2165,8 @@ parseGenericArgs(int argc, char *argv[]) if (*imageName == 0) { /* only try to use image name if none is provided */ if (*argv[0] && IsImage(argv[0])) { - strcpy(imageName, argv[0]); + strncpy(imageName, argv[0],MAX_PATH_UTF8); + MultiByteToWideChar(CP_UTF8, 0, imageName, -1, imageNameW, MAX_PATH); /* if provided, the image is a vm argument. */ vmOptions[numOptionsVM++] = argv[0]; } diff --git a/platforms/win32/vm/sqWin32Prefs.c b/platforms/win32/vm/sqWin32Prefs.c index b6339803a4..a2a5cc5645 100644 --- a/platforms/win32/vm/sqWin32Prefs.c +++ b/platforms/win32/vm/sqWin32Prefs.c @@ -194,15 +194,17 @@ void LoadPreferences() /* get image file name from ini file */ size = GetPrivateProfileString(U_GLOBAL, TEXT("ImageFile"), - TEXT(""), imageName, MAX_PATH, squeakIniName); + TEXT(""), imageNameT, MAX_PATH, squeakIniName); if(size > 0) { if( !(imageName[0] == '\\' && imageName[1] == '\\') && !(imageName[1] == ':' && imageName[2] == '\\')) { /* make the path relative to VM directory */ - lstrcpy(imageName, vmName); - (lstrrchr(imageName,U_BACKSLASH[0]))[1] = 0; - size = lstrlen(imageName); + strcpy(imageName , vmNameA); + wcscpy(imageNameW, vmNameW); + (strrchr(imageName ,'\\' ))[1] = 0; + (wcsrchr(imageNameW, W_BACKSLASH[0]))[1] = 0; + size = lstrlen(imageNameT); size = GetPrivateProfileString(U_GLOBAL, TEXT("ImageFile"), - TEXT(""), imageName + size, MAX_PATH - size, squeakIniName); + TEXT(""), imageNameT + size, MAX_PATH - size, squeakIniName); } } @@ -225,7 +227,7 @@ void LoadPreferences() /* get the window class name from the ini file */ GetPrivateProfileString(U_GLOBAL, TEXT("WindowClassName"), #if NewspeakVM - TEXT(VM_NAME"WindowClass"), + TEXT(VM_NAME) TEXT("WindowClass"), #else TEXT("SqueakWindowClass"), #endif @@ -431,8 +433,8 @@ void TrackPrefsMenu(void) { void HandlePrefsMenu(int cmd) { switch(cmd) { case ID_ABOUT: - MessageBox(stWindow,VM_VERSION_TEXT, - TEXT("About ") TEXT(VM_NAME) TEXT(" on Win32"), MB_OK); + MessageBoxA(stWindow,VM_VERSION_VERBOSE, + "About " VM_NAME " on Win32", MB_OK); break; case ID_DEFERUPDATES: fDeferredUpdate = !fDeferredUpdate; diff --git a/platforms/win32/vm/sqWin32Prefs.h b/platforms/win32/vm/sqWin32Prefs.h index 26864d4925..0133d1b3e3 100644 --- a/platforms/win32/vm/sqWin32Prefs.h +++ b/platforms/win32/vm/sqWin32Prefs.h @@ -50,7 +50,7 @@ int prefsEnableF2Menu(void); # define NICKNAME_EXTRA " VM " #endif -#define VM_VERSION_TEXT TEXT(NICKNAME) TEXT(NICKNAME_EXTRA) TEXT(VM_VERSION) \ - TEXT(" (release) from ") TEXT(__DATE__) TEXT("\n") \ - TEXT("Compiler: ") TEXT(COMPILER) TEXT(VERSION) +#define VM_VERSION_VERBOSE NICKNAME NICKNAME_EXTRA VM_VERSION \ + " (release) from " __DATE__ "\n" \ + "Compiler: " COMPILER VERSION #endif diff --git a/platforms/win32/vm/sqWin32Service.c b/platforms/win32/vm/sqWin32Service.c index 95470d8ae5..80e22f9e9e 100644 --- a/platforms/win32/vm/sqWin32Service.c +++ b/platforms/win32/vm/sqWin32Service.c @@ -22,8 +22,8 @@ /* Imports from sqWin32Main.c */ /****************************************************************/ -extern TCHAR *logName; /* full path and name to log file */ -extern TCHAR serviceName[]; /* The name of the NT service */ +extern WCHAR *logName; /* full path and name to log file */ +extern WCHAR serviceName[]; /* The name of the NT service */ HANDLE hServDoneEvent = NULL; @@ -32,12 +32,12 @@ SERVICE_STATUS ssStatus; /* current status of the service */ SERVICE_STATUS_HANDLE sshStatusHandle; DWORD dwGlobalErr; -void sqStopService(LPTSTR lpszMsg); +void sqStopService(LPWSTR lpszMsg); void sqEventLogMessage(LPTSTR lpszMsg); BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwCheckPoint,DWORD dwWaitHint); void sqServiceControl(DWORD dwCtrlCode); -void sqServiceMainFunction(DWORD dwArgc, LPTSTR *lpszArgv); +void sqServiceMainFunction(DWORD dwArgc, LPWSTR *lpszArgv); #define failOn(condition, msg)\ if(condition)\ @@ -46,65 +46,49 @@ void sqServiceMainFunction(DWORD dwArgc, LPTSTR *lpszArgv); return 0;\ } -/* printCommandLine(): Return a command line string from the current settings */ +/* printCommandLine(): Return a command line string from the current settings, UTF8 encoded */ -TCHAR *printCommandLine(int printFor95) -{ static TCHAR buffer[1024]; - TCHAR lbuf[50]; +char *printCommandLine() +{ static WCHAR buffer[1024]; + static char utf8[1024*3]; /* remember: at most 3 byte char for 1 WCHAR - See comment of MAX_PATH_UTF8 */ + WCHAR lbuf[50]; *buffer = 0; - if(printFor95) - { - GetModuleFileName(hInstance, buffer, 1024); - lstrcat(buffer,TEXT(" -service95 -headless ")); - } - if(dwMemorySize) /* need -memory: mb */ { - lstrcat(buffer,TEXT("-memory: ")); -#ifdef UNICODE - lstrcat(buffer, _ltow(dwMemorySize, lbuf, 10)); -#else - lstrcat(buffer, _ltoa(dwMemorySize, lbuf, 10)); -#endif - lstrcat(buffer,TEXT(" ")); + wcsncat(buffer,L"-memory: ",1024 - 1 - wcslen(buffer)); + wcsncat(buffer, _ltow(dwMemorySize, lbuf, 10),1024 - 1 - wcslen(buffer)); + wcsncat(buffer,L" ",1024 - 1 - wcslen(buffer)); } #if STACKVM { extern sqInt desiredNumStackPages; extern sqInt desiredEdenBytes; if (desiredEdenBytes) { - lstrcat(buffer,TEXT("-eden: ")); -# ifdef UNICODE - lstrcat(buffer, _ltow(desiredEdenBytes, lbuf, 10)); -# else - lstrcat(buffer, _ltoa(desiredEdenBytes, lbuf, 10)); -# endif - lstrcat(buffer,TEXT(" ")); + wcsncat(buffer,L"-eden: ",1024 - 1 - wcslen(buffer)); + wcsncat(buffer, _ltow(desiredEdenBytes, lbuf, 10),1024 - 1 - wcslen(buffer)); + wcsncat(buffer,L" ",1024 - 1 - wcslen(buffer)); } if (desiredNumStackPages) { - lstrcat(buffer,TEXT("-stackpages: ")); -# ifdef UNICODE - lstrcat(buffer, _ltow(desiredNumStackPages, lbuf, 10)); -# else - lstrcat(buffer, _ltoa(desiredNumStackPages, lbuf, 10)); -# endif - lstrcat(buffer,TEXT(" ")); + wcsncat(buffer,L"-stackpages: ",1024 - 1 - wcslen(buffer)); + wcsncat(buffer, _ltow(desiredNumStackPages, lbuf, 10),1024 - 1 - wcslen(buffer)); + wcsncat(buffer,L" ",1024 - 1 - wcslen(buffer)); } } #endif /* STACKVM */ if(*logName) /* need -log: "logName" */ { - lstrcat(buffer, TEXT("-log: \"")); - lstrcat(buffer, logName); - lstrcat(buffer, TEXT("\" ")); + wcsncat(buffer, L"-log: \"",1024 - 1 - wcslen(buffer)); + wcsncat(buffer, logName,1024 - 1 - wcslen(buffer)); + wcsncat(buffer, L"\" ",1024 - 1 - wcslen(buffer)); } /* add image name */ - lstrcat(buffer, TEXT("\"")); - lstrcat(buffer, toUnicode(imageName)); - lstrcat(buffer, TEXT("\"\0")); + wcsncat(buffer, L"\"",1024 - 1 - wcslen(buffer)); + wcsncat(buffer, imageNameW,1024 - 1 - wcslen(buffer)); + wcsncat(buffer, L"\"\0",1024 - 1 - wcslen(buffer)); - return buffer; + WideCharToMultiByte(CP_UTF8, 0, buffer, -1, utf8, 1024 * 3, NULL, NULL); + return utf8; } /**************************************************************************** @@ -113,7 +97,7 @@ TCHAR *printCommandLine(int printFor95) /* sqStartService: start the named service */ int -sqStartService(LPCTSTR serviceName) +sqStartService(LPCWSTR serviceName) { SC_HANDLE schService; SC_HANDLE schSCManager; @@ -123,7 +107,7 @@ sqStartService(LPCTSTR serviceName) schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); failOn(!schSCManager, TEXT("OpenSCManager failed")); - schService = OpenService(schSCManager, serviceName, SERVICE_ALL_ACCESS); + schService = OpenServiceW(schSCManager, serviceName, SERVICE_ALL_ACCESS); if(schService) { /* This may take some time */ @@ -145,7 +129,7 @@ sqStartService(LPCTSTR serviceName) /* sqChangeServiceConfig: change the startup type of the named service */ int -sqChangeServiceConfig(LPCTSTR serviceName, DWORD startType) +sqChangeServiceConfig(LPCWSTR serviceName, DWORD startType) { SC_HANDLE schService; SC_HANDLE schSCManager; @@ -155,7 +139,7 @@ sqChangeServiceConfig(LPCTSTR serviceName, DWORD startType) schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); failOn(!schSCManager, TEXT("OpenSCManager failed")); - schService = OpenService(schSCManager, serviceName, SERVICE_ALL_ACCESS); + schService = OpenServiceW(schSCManager, serviceName, SERVICE_ALL_ACCESS); if (schService != NULL) { if(ChangeServiceConfig(schService, @@ -184,7 +168,7 @@ sqChangeServiceConfig(LPCTSTR serviceName, DWORD startType) /* sqRemoveService: remove the named service */ int -sqRemoveService(LPCTSTR serviceName) +sqRemoveService(LPCWSTR serviceName) { SC_HANDLE schService; SC_HANDLE schSCManager; @@ -194,7 +178,7 @@ sqRemoveService(LPCTSTR serviceName) schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); failOn(!schSCManager, TEXT("OpenSCManager failed")); - schService = OpenService(schSCManager, serviceName, SERVICE_ALL_ACCESS); + schService = OpenServiceW(schSCManager, serviceName, SERVICE_ALL_ACCESS); if (schService == NULL) { printLastError(TEXT("OpenService failed")); @@ -213,17 +197,17 @@ sqRemoveService(LPCTSTR serviceName) /* sqInstallService: install the named service */ int -sqInstallService(LPCTSTR serviceName, LPCTSTR serviceExe) +sqInstallService(LPCWSTR serviceName, LPCWSTR serviceExe) { - LPCTSTR lpszBinaryPathName = serviceExe; + LPCWSTR lpszBinaryPathName = serviceExe; SC_HANDLE schService; SC_HANDLE schSCManager; /* open service control manager on the local machine with default database */ - schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + schSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); failOn(!schSCManager, TEXT("OpenSCManager failed")); - schService = CreateService( + schService = CreateServiceW( schSCManager, /* SCManager database */ serviceName, /* name of service */ serviceName, /* name to display */ @@ -245,7 +229,7 @@ sqInstallService(LPCTSTR serviceName, LPCTSTR serviceExe) if(GetLastError() == ERROR_SERVICE_EXISTS) { /* The service already exists - ask the user to remove it */ - if(MessageBox(0,TEXT("A service of this name already exists. Try to remove it?"), + if(MessageBoxW(0,L"A service of this name already exists. Try to remove it?", serviceName, MB_YESNOCANCEL) == IDYES) { /* Now close the service manager ... */ @@ -265,109 +249,6 @@ sqInstallService(LPCTSTR serviceName, LPCTSTR serviceExe) return schService != NULL; } -/**************************************************************************** - Service Install/deinstall functions for Windows 95 - ****************************************************************************/ - -/* sqInstallService95: install the named service on a Windows 95 system */ -int -sqInstallService95(LPTSTR serviceName) -{ TCHAR tmpString[1024]; - DWORD dwSize, dwType; - HKEY hk; - int ok; - - /* Add a broadcast for user startup */ - ok = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"), &hk); - failOn(ok != ERROR_SUCCESS, TEXT("RegOpenKey failed")); - dwSize = 1024; - ok = RegQueryValueEx(hk, TEXT("SqueakBroadcastNotification"),NULL, &dwType, (LPBYTE) &tmpString, &dwSize); - /* ERROR_SUCCESS indicates that we have already an entry */ - if(ok != ERROR_SUCCESS) - /* ERROR_FILE_NOT_FOUND indicates no entry */ - if(ok != ERROR_FILE_NOT_FOUND) - failOn(1 ,TEXT("RegQueryValueEx failed")); - - /* set the new service entry */ - GetModuleFileName(hInstance, tmpString, 1024); - lstrcat(tmpString,TEXT(" -broadcast95")); - ok = RegSetValueEx(hk, /* subkey handle */ - TEXT("SqueakBroadcastNotification"), /* value name */ - 0, /* must be zero */ - REG_SZ, /* value type */ - (LPBYTE) &tmpString, /* address of value data */ - lstrlen(tmpString)); /* length of value data */ - failOn(ok != ERROR_SUCCESS, TEXT("RegSetValueEx failed")); - RegCloseKey(hk); - - ok = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices"), &hk); - if(ok != ERROR_SUCCESS) { - /* ERROR_FILE_NOT_FOUND indicates no entry */ - if(ok != ERROR_FILE_NOT_FOUND) - failOn(1, TEXT("RegOpenKey failed")); - ok = RegCreateKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices"), &hk); - failOn(ok != ERROR_SUCCESS, TEXT("RegCreateKey failed")); - } else { /* check for any existing service */ - dwSize = 1024; - ok = RegQueryValueEx(hk,serviceName,NULL, &dwType, (LPBYTE) &tmpString, &dwSize); - /* ERROR_SUCCESS indicates that we have already an entry */ - if(ok == ERROR_SUCCESS) { - /* The service already exists - ask the user to remove it */ - if(MessageBox(0,TEXT("A service of this name already exists. Try to remove it?"), - serviceName, MB_YESNOCANCEL) != IDYES) - return 0; /* Just return, in any other case we just overwrite the entry */ - } else { /* ERROR_FILE_NOT_FOUND indicates no entry */ - if(ok != ERROR_FILE_NOT_FOUND) - failOn(1 , TEXT("RegQueryValueEx failed")); - } - } - /* set the new service entry */ - lstrcpy(tmpString, printCommandLine(1)); - ok = RegSetValueEx(hk, /* subkey handle */ - serviceName, /* value name */ - 0, /* must be zero */ - REG_SZ, /* value type */ - (LPBYTE) &tmpString, /* address of value data */ - lstrlen(tmpString)); /* length of value data */ - failOn(ok != ERROR_SUCCESS, TEXT("RegSetValueEx failed")); - RegCloseKey(hk); - - return 1; -} - -/* sqStartService95: start the named service on a Windows 95 system */ -int -sqStartService95(LPTSTR serviceName) -{ TCHAR tmpString[1024]; - STARTUPINFO sInfo; - PROCESS_INFORMATION pInfo; - DWORD dwSize, dwType; - HKEY hk; - int ok; - - ok = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices"), &hk); - failOn(ok != ERROR_SUCCESS, TEXT("RegOpenKey failed")); - /* get the name of the program to run */ - dwSize = 1024; - ok = RegQueryValueEx(hk,serviceName,NULL, &dwType, (LPBYTE) &tmpString, &dwSize); - failOn(ok != ERROR_SUCCESS, TEXT("RegQueryValueEx failed")); - RegCloseKey(hk); - tmpString[dwSize] = 0; - /* and start up */ - ZeroMemory(&sInfo, sizeof(sInfo)); - ok = CreateProcess(NULL, /* no image name */ - tmpString, /* but full command line */ - NULL, /* no process security attributes */ - NULL, /* no thread security attributes */ - FALSE, /* don't inherit handles */ - 0, /* no special flags */ - NULL, /* no separate environment */ - NULL, /* no startup dir */ - &sInfo, /* startup info */ - &pInfo); /* process info */ - failOn(ok == 0, TEXT("CreateProcess failed")); - return 1; -} /**************************************************************************** Main service install function @@ -376,61 +257,43 @@ sqStartService95(LPTSTR serviceName) NT Service. Run it afterwards */ void sqServiceInstall(void) { HKEY hk; - TCHAR tmp[1024]; + WCHAR tmp[1024]; DWORD ok; - if( fWindows95 ) - { /* Running on Win95 */ - if(!sqInstallService95(serviceName)) - { - warnPrintf(TEXT("The service was NOT installed.")); - return; - } - if(MessageBox(0,TEXT("Service installation successful.\n") - TEXT("Do you wish to start the service right now?"), - serviceName,MB_YESNOCANCEL) == IDYES) - { - if(!sqStartService95(serviceName)) - warnPrintf(TEXT("The service was NOT started.\n") - TEXT("You have to restart your system first.")); - } - /* success */ - exit(0); - } /* get the VM name */ - GetModuleFileName(hInstance,tmp, 255); + GetModuleFileNameW(hInstance,tmp, 255); if(!sqInstallService(serviceName, tmp)) { warnPrintf(TEXT("The service has NOT been installed.")); return; } /* Create a new key for our service */ - wsprintf(tmp,TEXT("SYSTEM\\CurrentControlSet\\Services\\%s\\Startup"),serviceName); - ok = RegCreateKey(HKEY_LOCAL_MACHINE, tmp, &hk); + _snwprintf(tmp,1024,L"SYSTEM\\CurrentControlSet\\Services\\%s\\Startup",serviceName); + ok = RegCreateKeyW(HKEY_LOCAL_MACHINE, tmp, &hk); if(ok != ERROR_SUCCESS) { printLastError(TEXT("RegCreateKey failed")); return; } /* Add the image name to the subkey. */ - ok = RegSetValueEx(hk, /* subkey handle */ - TEXT("Image"), /* value name */ - 0, /* must be zero */ - REG_EXPAND_SZ, /* value type */ - (LPBYTE) imageName, /* address of value data */ - strlen(imageName) + 1); /* length of value data */ + ok = RegSetValueExW(hk, /* subkey handle */ + L"Image", /* value name */ + 0, /* must be zero */ + REG_EXPAND_SZ, /* value type */ + (LPBYTE) imageNameW, /* address of value data */ + (wcslen(imageNameW)+1)*sizeof(WCHAR)); /* length of value data */ if(ok != ERROR_SUCCESS) { printLastError(TEXT("RegSetValueEX failed")); return; } /* Add the log file to the subkey. */ - ok = RegSetValueEx(hk, /* subkey handle */ - TEXT("Log"), /* value name */ - 0, /* must be zero */ - REG_EXPAND_SZ, /* value type */ - (LPBYTE) logName, /* address of value data */ - lstrlen(logName) + 1); /* length of value data */ + ok = RegSetValueEx(hk, /* subkey handle */ + TEXT("Log"), /* value name */ + 0, /* must be zero */ + REG_EXPAND_SZ, /* value type */ + (LPBYTE) logName, /* address of value data */ + wcslen(logName) + 1)*sizeof(WCHAR); /* length of value data */ if(ok != ERROR_SUCCESS) { printLastError(TEXT("RegSetValueEX failed")); @@ -450,15 +313,15 @@ void sqServiceInstall(void) } RegCloseKey(hk); /* Successfully finished install */ - if(MessageBox(0,TEXT("Service installation successful. ") - TEXT("Do you wish to start the service automatically on system startup?"), + if(MessageBoxW(0,L"Service installation successful. " + L"Do you wish to start the service automatically on system startup?", serviceName,MB_YESNOCANCEL) == IDYES) { if(!sqChangeServiceConfig(serviceName, SERVICE_AUTO_START)) warnPrintf(TEXT("The service was NOT configured.\n") TEXT("Please go to control panel and configure the service manually.\n")); } - if(MessageBox(0,TEXT("Do you wish to start the service right now?"), + if(MessageBoxW(0,L"Do you wish to start the service right now?", serviceName,MB_YESNOCANCEL) == IDYES) { if(!sqStartService(serviceName)) @@ -499,8 +362,7 @@ int sqServiceMain(void) DWORD WINAPI sqThreadMain(DWORD ignored) { DWORD dwSize, dwType, ok; HKEY hk; - static TCHAR tmpString[256]; - static TCHAR lbuf[50]; + static WCHAR tmpString[MAX_PATH+1]; char *cmd; /* first of all set a few flags */ @@ -509,45 +371,46 @@ DWORD WINAPI sqThreadMain(DWORD ignored) /* get values from the registry settings */ /* Create a new key for our service */ - wsprintf(tmpString,TEXT("SYSTEM\\CurrentControlSet\\Services\\%s\\Startup"),serviceName); - ok = RegOpenKey(HKEY_LOCAL_MACHINE, tmpString, &hk); + _snwprintf(tmpString,MAX_PATH+1,L"SYSTEM\\CurrentControlSet\\Services\\%s\\Startup",serviceName); + ok = RegOpenKeyW(HKEY_LOCAL_MACHINE, tmpString, &hk); if(ok != ERROR_SUCCESS) { - sqStopService(TEXT("Failed to open registry for startup parameters")); + sqStopService(L"Failed to open registry for startup parameters"); TerminateThread(GetCurrentThread(), 0); } /* Read the image name from the subkey. */ - dwSize = MAX_PATH; - ok = RegQueryValueEx(hk,TEXT("Image"),NULL, &dwType, (LPBYTE) imageName, &dwSize); + dwSize = MAX_PATH*sizeof(WCHAR); + ok = RegQueryValueExW(hk,L"Image",NULL, &dwType, (LPBYTE) imageNameW, &dwSize); if(ok != ERROR_SUCCESS || dwType != REG_EXPAND_SZ) { - sqStopService(TEXT("Failed to read the image name from registry")); + sqStopService(L"Failed to read the image name from registry"); TerminateThread(GetCurrentThread(), 0); } - imageName[dwSize] = 0; + imageNameW[dwSize/2] = 0; + WideCharToMultiByte(CP_UTF8, 0, imageNameW, -1, imageName, MAX_PATH_UTF8, NULL, NULL); /* Read the log file name from the subkey. */ - dwSize = MAX_PATH; - ok = RegQueryValueEx(hk,TEXT("Log"),NULL, &dwType, (LPBYTE) &tmpString, &dwSize); + dwSize = MAX_PATH*sizeof(WCHAR); + ok = RegQueryValueExW(hk,L"Log",NULL, &dwType, (LPBYTE) &tmpString, &dwSize); if(ok != ERROR_SUCCESS || dwType != REG_EXPAND_SZ) { - sqStopService(TEXT("Failed to read the log file name from registry")); + sqStopService(L"Failed to read the log file name from registry"); TerminateThread(GetCurrentThread(), 0); } - tmpString[dwSize] = 0; - logName = malloc(lstrlen(tmpString)+1); - lstrcpy(logName, tmpString); + tmpString[dwSize/2] = 0; + logName = malloc((wcslen(tmpString)+1)*sizeof(WCHAR)); + wcscpy(logName, tmpString); /* Read the memory size from the subkey. */ dwSize = sizeof(DWORD); - ok = RegQueryValueEx(hk,TEXT("Memory"),NULL, &dwType, (LPBYTE) &dwMemorySize, &dwSize); + ok = RegQueryValueExW(hk,L"Memory",NULL, &dwType, (LPBYTE) &dwMemorySize, &dwSize); if(ok != ERROR_SUCCESS || dwType != REG_DWORD) { - sqStopService(TEXT("Failed to read the memory amount from registry")); + sqStopService(L"Failed to read the memory amount from registry"); TerminateThread(GetCurrentThread(), 0); } RegCloseKey(hk); /* and away we go ... */ - cmd = printCommandLine(0); + cmd = printCommandLine(); sqMain(0,&cmd); return 1; } @@ -555,15 +418,15 @@ DWORD WINAPI sqThreadMain(DWORD ignored) /**************************************************************************** sqServiceMain(): This function will be called when the service is about to run ****************************************************************************/ -void sqServiceMainFunction(DWORD dwArgc, LPTSTR *lpszArgv) +void sqServiceMainFunction(DWORD dwArgc, LPWSTR *lpszArgv) { DWORD id; HANDLE eventList[2]; /* store the name of our service */ - lstrcpy(serviceName, lpszArgv[0]); + wcscpy(serviceName, lpszArgv[0]); /* register our service control handler: */ - sshStatusHandle = RegisterServiceCtrlHandler( serviceName, + sshStatusHandle = RegisterServiceCtrlHandlerW( serviceName, (LPHANDLER_FUNCTION) sqServiceControl); if (!sshStatusHandle) goto cleanup; @@ -712,31 +575,31 @@ ReportStatusToSCMgr(DWORD dwCurrentState, if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) { /* If an error occurs, stop the service. */ - sqStopService(TEXT("SetServiceStatus")); + sqStopService(L"SetServiceStatus"); } return fResult; } /* sqStopService: report an error, and stop the service. */ -void sqStopService(LPTSTR lpszMsg) +void sqStopService(LPWSTR lpszMsg) { - TCHAR chMsg[256]; + WCHAR chMsg[256]; HANDLE hEventSource; - LPTSTR lpszStrings[2]; + LPWSTR lpszStrings[2]; dwGlobalErr = GetLastError(); /* Use event logging to log the error. */ - hEventSource = RegisterEventSource(NULL, serviceName); + hEventSource = RegisterEventSourceW(NULL, serviceName); - wsprintf(chMsg, TEXT("%s error: %d"), serviceName, dwGlobalErr); + _snwprintf(chMsg, 256, L"%s error: %d", serviceName, dwGlobalErr); lpszStrings[0] = chMsg; lpszStrings[1] = lpszMsg; if (hEventSource != NULL) { - ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 2, 0, (LPCTSTR*)lpszStrings, NULL); + ReportEventW(hEventSource, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 2, 0, (LPCWSTR*)lpszStrings, NULL); DeregisterEventSource(hEventSource); } @@ -751,7 +614,7 @@ void sqEventLogMessage(LPTSTR lpszMsg) HANDLE hEventSource; LPTSTR lpszStrings[1]; - hEventSource = RegisterEventSource(NULL, serviceName); + hEventSource = RegisterEventSourceW(NULL, serviceName); lpszStrings[0] = lpszMsg; if (hEventSource != NULL) { diff --git a/platforms/win32/vm/sqWin32SpurAlloc.c b/platforms/win32/vm/sqWin32SpurAlloc.c index 9b65a39bb8..d20a57800a 100644 --- a/platforms/win32/vm/sqWin32SpurAlloc.c +++ b/platforms/win32/vm/sqWin32SpurAlloc.c @@ -29,8 +29,8 @@ LONG CALLBACK sqExceptionFilter(LPEXCEPTION_POINTERS exp) return EXCEPTION_WRONG_ACCESS; } -static DWORD pageMask; /* bit mask for the start of a memory page */ -static DWORD pageSize; /* size of a memory page */ +static sqIntptr_t pageMask; /* bit mask for the start of a memory page */ +static sqIntptr_t pageSize; /* size of a memory page */ static char *minAppAddr; /* SYSTEM_INFO lpMinimumApplicationAddress */ static char *maxAppAddr; /* SYSTEM_INFO lpMaximumApplicationAddress */ @@ -50,7 +50,7 @@ sqAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize) if (pageSize) { sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), - "sqAllocateMemory already called"); + TEXT("sqAllocateMemory already called")); exit(1); } @@ -77,7 +77,7 @@ sqAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize) if (!alloc) { exit(errno); sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), - "sqAllocateMemory: initial alloc failed!\n"); + TEXT("sqAllocateMemory: initial alloc failed!\n")); exit(1); } return alloc; @@ -114,7 +114,7 @@ address_space_used(char *address, usqInt bytes) return 1; if (!VirtualQuery(address, &info, sizeof(info))) sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), - "Unable to VirtualQuery range [%p, %p), Error: %u", + TEXT("Unable to VirtualQuery range [%p, %p), Error: %u"), address, (char *)address + bytes, GetLastError()); addressSpaceUnused = info.BaseAddress == address @@ -160,7 +160,7 @@ sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt size, void *minAddress DWORD lastError = GetLastError(); #if 0 /* Can't report this without making the system unusable... */ sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), - "Unable to VirtualAlloc committed memory at desired address (%" PRIuSQINT " bytes requested at %p, above %p), Error: %lu", + TEXT("Unable to VirtualAlloc committed memory at desired address (%") TEXT(PRIuSQINT) TEXT(" bytes requested at %p, above %p), Error: %lu"), bytes, address, minAddress, lastError); #else if (fIsConsole) @@ -175,7 +175,7 @@ sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt size, void *minAddress */ if (alloc && !VirtualFree(alloc, SizeForRelease(bytes), MEM_RELEASE)) sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Warning:"), - "Unable to VirtualFree committed memory (%" PRIuSQINT " bytes requested), Error: %ul", + TEXT("Unable to VirtualFree committed memory (%") TEXT(PRIuSQINT) TEXT(" bytes requested), Error: %ul"), bytes, GetLastError()); address += delta; } @@ -190,7 +190,7 @@ sqDeallocateMemorySegmentAtOfSize(void *addr, sqInt sz) { if (!VirtualFree(addr, SizeForRelease(sz), MEM_RELEASE)) sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Warning:"), - "Unable to VirtualFree committed memory (%" PRIuSQINT " bytes requested), Error: %ul", + TEXT("Unable to VirtualFree committed memory (%") TEXT(PRIuSQINT) TEXT(" bytes requested), Error: %ul"), sz, GetLastError()); } @@ -257,7 +257,7 @@ main() return 0; } int __cdecl -sqMessageBox(DWORD dwFlags, const TCHAR *titleString, const char* fmt, ...) +sqMessageBox(DWORD dwFlags, const TCHAR *titleString, const TCHAR* fmt, ...) { va_list args; int result; diff --git a/platforms/win32/vm/sqWin32Utils.c b/platforms/win32/vm/sqWin32Utils.c index f8554007c1..0ca78bc604 100644 --- a/platforms/win32/vm/sqWin32Utils.c +++ b/platforms/win32/vm/sqWin32Utils.c @@ -13,123 +13,23 @@ #include #include "sq.h" -/***************************************************************************** - String conversions: Unicode / Ansi / Squeak - NOTES: - 1) The length of strings in inline functions MUST NOT exceed MAX_PATH. - 2) fromSqueak() and fromSqueak2() are inline conversions - but operate on two different buffers. - 3) toUnicode() and fromUnicode() are inline conversions - with for at most MAX_PATH sized strings. If the VM - is not compiled with UNICODE defined they just return - the input strings. Also, toUnicode operates on the - same buffer as fromSqueak() - 4) toUnicodeNew and fromUnicodeNew malloc() new strings. - It is up to the caller to free these! -*****************************************************************************/ - - -#define MAX_BUFFER MAX_PATH -static TCHAR w_buffer1[MAX_BUFFER]; /* wide buffer 1 */ -static TCHAR w_buffer2[MAX_BUFFER]; /* wide buffer 2 */ -static char a_buffer1[MAX_BUFFER]; /* ansi buffer 1 */ - -static TCHAR *fromSqueakInto(const char *sqPtr, int sqSize, TCHAR* buffer) -{ - int i; - if(sqSize >= MAX_BUFFER) sqSize = MAX_BUFFER-1; - for(i=0;i= MAX_BUFFER) size = MAX_BUFFER - 1; - for(i=0;i= source) - if(*tmp == c) return tmp; - else tmp--; - return NULL; -} - /****************************************************************************/ /* Helper to pop up a message box with a message formatted from the */ /* printf() format string and arguments */ /****************************************************************************/ #ifndef sqMessageBox -int __cdecl sqMessageBox(DWORD dwFlags, const TCHAR *titleString, const char* fmt, ...) -{ TCHAR *ptr, *buf; - va_list args; +int __cdecl sqMessageBox(DWORD dwFlags, const TCHAR *titleString, const TCHAR* fmt, ...) +{ TCHAR *buf; + va_list args; DWORD result; - ptr = toUnicodeNew(fmt); buf = (TCHAR*) calloc(sizeof(TCHAR), 4096); - va_start(args, fmt); - wvsprintf(buf, ptr, args); - va_end(args); + va_start(args, fmt); + _vsntprintf(buf, 4096-1, fmt, args); + va_end(args); - result = MessageBox(stWindow,buf,titleString,dwFlags|MB_SETFOREGROUND); - free(ptr); + result = MessageBox(stWindow,buf,titleString,dwFlags|MB_SETFOREGROUND); free(buf); return result; } diff --git a/platforms/win32/vm/sqWin32Window.c b/platforms/win32/vm/sqWin32Window.c index fc5f9084e0..941d4d8048 100644 --- a/platforms/win32/vm/sqWin32Window.c +++ b/platforms/win32/vm/sqWin32Window.c @@ -56,21 +56,30 @@ extern sqInt deferDisplayUpdates; /*** Variables -- image and path names ***/ -#define IMAGE_NAME_SIZE MAX_PATH +#define IMAGE_NAME_SIZE MAX_PATH_UTF8 -char imageName[MAX_PATH+1]; /* full path and name to image */ -TCHAR imagePath[MAX_PATH+1]; /* full path to image */ -TCHAR vmPath[MAX_PATH+1]; /* full path to interpreter's directory */ -TCHAR vmName[MAX_PATH+1]; /* name of the interpreter's executable */ -char windowTitle[MAX_PATH]; /* what should we display in the title? */ -TCHAR squeakIniName[MAX_PATH+1]; /* full path and name to ini file */ -TCHAR windowClassName[MAX_PATH+1]; /* Window class name */ +/* IMPLEMENTATION NOTE: +- both UTF8 and UTF16 versions are maintained in parallel +- UTF8 version is for interaction with image +- UTF16 version is for interaction with WIN32 API +whichever code modifies one version is responsible for updating the other +*/ +char imageName [MAX_PATH_UTF8 + 1]; /* full path and name to image */ +WCHAR imageNameW[MAX_PATH + 1]; /* full path and name to image */ +char imagePathA[MAX_PATH_UTF8 + 1]; /* full path to image */ +WCHAR imagePathW[MAX_PATH + 1]; /* full path to image */ +char vmPathA[MAX_PATH_UTF8 + 1]; /* full path to interpreter's directory */ +WCHAR vmPathW[MAX_PATH + 1]; /* full path to interpreter's directory */ +char vmNameA[MAX_PATH_UTF8 + 1]; /* name of the interpreter's executable UTF8 */ +WCHAR vmNameW[MAX_PATH + 1]; /* name of the interpreter's executable UTF16 */ +char windowTitle[MAX_PATH+1]; /* what should we display in the title? */ +TCHAR squeakIniName[MAX_PATH+1]; /* full path and name to ini file */ +TCHAR windowClassName[MAX_PATH+1]; /* Window class name */ const TCHAR U_ON[] = TEXT("1"); const TCHAR U_OFF[] = TEXT("0"); const TCHAR U_GLOBAL[] = TEXT("Global"); -const TCHAR U_SLASH[] = TEXT("/"); -const TCHAR U_BACKSLASH[] = TEXT("\\"); +const WCHAR W_BACKSLASH[] = L"\\"; /*** Variables -- Event Recording ***/ int inputSemaphoreIndex = 0;/* if non-zero the event semaphore index */ @@ -98,7 +107,6 @@ BITMAPINFO *bmi4; /* 4 bit depth bitmap info */ BITMAPINFO *bmi8; /* 8 bit depth bitmap info */ BITMAPINFO *bmi16; /* 16 bit depth bitmap info */ BITMAPINFO *bmi32; /* 32 bit depth bitmap info */ -BOOL fWindows95; /* Are we running on Win95 or NT? */ BOOL fHasFocus = 0; /* if Squeak has the input focus */ /* Preference values */ @@ -195,7 +203,7 @@ extern int sqAskSecurityYesNoQuestion(const char *question) extern const char *sqGetCurrentImagePath(void) { - return imagePath; + return imagePathA; } /****************************************************************************/ @@ -910,7 +918,7 @@ void SetupWindows() updateRgn = CreateRectRgn(0,0,1,1); /* No windows at all when running as NT service */ - if(fRunService && !fWindows95) return; + if(fRunService) return; wc.style = CS_OWNDC; /* don't waste resources ;-) */ wc.lpfnWndProc = (WNDPROC)MainWndProcA; @@ -1619,7 +1627,7 @@ sqInt ioProcessEvents(void) int result; extern sqInt inIOProcessEvents; - if (fRunService && !fWindows95) return 1; + if (fRunService) return 1; #if NewspeakVM /* inIOProcessEvents controls ioProcessEvents. If negative then @@ -1704,7 +1712,7 @@ ioDrainEventQueue(void) { static MSG msg; POINT mousePt; - if(fRunService && !fWindows95) return 1; + if(fRunService) return 1; /* WinCE doesn't retrieve WM_PAINTs from the queue with PeekMessage, so we won't get anything painted unless we use GetMessage() if there @@ -2753,7 +2761,7 @@ sqInt clipboardReadIntoAt(sqInt count, sqInt byteArrayIndex, sqInt startIndex) { sqInt vmPathSize(void) { - return lstrlen(vmPath); + return strlen(vmPathA); } sqInt vmPathGetLength(sqInt sqVMPathIndex, sqInt length) @@ -2761,12 +2769,12 @@ sqInt vmPathGetLength(sqInt sqVMPathIndex, sqInt length) char *stVMPath= (char *)sqVMPathIndex; int count, i; - count= lstrlen(vmPath); + count= strlen(vmPathA); count= (length < count) ? length : count; /* copy the file name into the Squeak string */ for (i= 0; i < count; i++) - stVMPath[i]= (char) vmPath[i]; /* will remove leading zeros from unicode */ + stVMPath[i]= vmPathA[i]; return count; } @@ -2799,7 +2807,7 @@ sqInt imageNameGetLength(sqInt sqImageNameIndex, sqInt length) sqInt imageNamePutLength(sqInt sqImageNameIndex, sqInt length) { char *sqImageName= (char *)sqImageNameIndex; - char tmpImageName[MAX_PATH+1]; + char tmpImageName[IMAGE_NAME_SIZE +1]; char *tmp; int count, i; @@ -2831,6 +2839,7 @@ sqInt imageNamePutLength(sqInt sqImageNameIndex, sqInt length) strcat(imageName,tmpImageName); } } + MultiByteToWideChar(CP_UTF8, 0, imageName, -1, imageNameW, MAX_PATH); SetWindowTitle(); return 1; } @@ -2856,7 +2865,7 @@ char * GetAttributeString(sqInt id) { could be reported this way as well. */ /* id == 0 : return the full name of the VM */ - if(id == 0) return fromUnicode(vmName); + if(id == 0) return vmNameA; /* 0 < id <= 1000 : return options of the image (e.g. given *after* the image name) */ if(id > 0 && id <= 1000) return GetImageOption(id-1); @@ -3001,34 +3010,45 @@ int isLocalFileName(TCHAR *fileName) void SetupFilesAndPath(){ char *tmp; - lstrcpy(imagePath, imageName); - tmp = lstrrchr(imagePath,'\\'); + WCHAR *wtmp; + strcpy(imagePathA, imageNameA); + wcscpy(imagePathW, imageNameW); + tmp = strrchr(imagePathA,'\\'); if(tmp) tmp[1] = 0; + wtmp = wcsrchr(imagePathW, '\\'); + if (wtmp) wtmp[1] = 0; } #else /* defined(_WIN32_WCE) */ void SetupFilesAndPath() { char *tmp; - WCHAR tmpName[MAX_PATH]; - WCHAR imageNameW[MAX_PATH]; + WCHAR *wtmp; + WCHAR tmpName[MAX_PATH+1]; /* get the full path for the image */ - MultiByteToWideChar(CP_UTF8, 0, imageName, -1, tmpName, MAX_PATH); + MultiByteToWideChar(CP_UTF8, 0, imageName , -1, tmpName, MAX_PATH); GetFullPathNameW(tmpName, MAX_PATH, imageNameW, NULL); /* and copy back to a UTF-8 string */ - WideCharToMultiByte(CP_UTF8, 0, imageNameW,-1,imageName,MAX_PATH,NULL,NULL); + WideCharToMultiByte(CP_UTF8, 0, imageNameW,-1,imageName ,MAX_PATH_UTF8,NULL,NULL); /* get the VM directory */ - lstrcpy(vmPath, vmName); - tmp = lstrrchr(vmPath,U_BACKSLASH[0]); + strcpy(vmPathA, vmNameA); + wcscpy(vmPathW, vmNameW); + tmp = strrchr(vmPathA, '\\'); + wtmp = wcsrchr(vmPathW, W_BACKSLASH[0]); if(tmp) *tmp = 0; - lstrcat(vmPath,U_BACKSLASH); - - lstrcpy(imagePath, imageName); - tmp = lstrrchr(imagePath,U_BACKSLASH[0]); + if (wtmp) *wtmp = 0; + strcat(vmPathA,"\\"); + wcscat(vmPathW, W_BACKSLASH); + + strcpy(imagePathA, imageName ); + wcscpy(imagePathW, imageNameW); + tmp = strrchr(imagePathA,'\\'); + wtmp = wcsrchr(imagePathW, W_BACKSLASH[0]); if(tmp) tmp[1] = 0; + if (wtmp) wtmp[1] = 0; } #endif /* !defined(_WIN32_WCE) */ @@ -3056,20 +3076,13 @@ DWORD SqueakImageLengthFromHandle(HANDLE hFile) { return 0; } -DWORD SqueakImageLength(TCHAR *fileName) { +DWORD SqueakImageLength(WCHAR *fileName) { DWORD dwSize; HANDLE hFile; /* open image file */ -#ifdef UNICODE hFile = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#else - WCHAR wideName[MAX_PATH]; - MultiByteToWideChar(CP_UTF8, 0, fileName, -1, wideName, MAX_PATH); - hFile = CreateFileW(wideName, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#endif if (hFile == INVALID_HANDLE_VALUE) return 0; dwSize = SqueakImageLengthFromHandle(hFile); CloseHandle(hFile); @@ -3094,8 +3107,9 @@ int findImageFile(void) { nextFound = FindNextFileW(findHandle,&findData); FindClose(findHandle); if(nextFound) return 0; /* more than one entry */ - WideCharToMultiByte(CP_UTF8, 0, findData.cFileName, -1, - imageName, MAX_PATH, NULL, NULL); + wcsncpy(imageNameW,findData.cFileName,MAX_PATH); + WideCharToMultiByte(CP_UTF8, 0, imageNameW, -1, + imageName, MAX_PATH_UTF8, NULL, NULL); return 1; } @@ -3121,7 +3135,8 @@ int openImageFile(void) { ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrDefExt = L"image"; if (!GetOpenFileNameW(&ofn)) return 0; - WideCharToMultiByte(CP_UTF8, 0, path, -1, + wcsncpy(imageNameW,path, MAX_PATH); + WideCharToMultiByte(CP_UTF8, 0, imageNameW, -1, imageName, MAX_PATH, NULL, NULL); return 1; } @@ -3317,7 +3332,7 @@ int printUsage(int level) TEXT("There are several ways to open an image file. You can:\n") TEXT(" 1. Double-click on the desired image file.\n") TEXT(" 2. Drop the image file onto the application.\n") - TEXT("Aborting...\n"), toUnicode(imageName)); + TEXT("Aborting...\n"), imageNameT); } return -1; }