Thread overview | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 04, 2004 std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
I am reported that my game library doesn't go well in Win9x. So I examined the reason , and at first,I had recoganized std.file.read is a bad code : : namez = std.utf.toUTF16z(name); : h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, : FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,(HANDLE)null); : if (h == INVALID_HANDLE_VALUE) : goto err1; : size = GetFileSize(h, null); : buf = new byte[size]; There are several miss-coding here. 1. CreateFileW is only for WinNT system(NT/2k/XP..) so we can't assume CreateFileW always exist. CreateFileA should be used for here , or to be prepared two version A and W. 2. In Win9x , CreateFileW would fail and return null, not INVALID_HANDLE_VALUE , so it is better to be check null or use getLastError. getLastError return 120 if it is not implemented, 120 (ERROR_CALL_NOT_IMPLEMENTED) 3.GetFileSize returns -1 if file handle is invalid. so it is better to be checked if it is an error or not. 4.new allcator had better to throw bad_alloc or return null if it can't allocated. In a foregoing case, GetFileSize returns -1 , and buf = new byte [-1]; is executed and makes an access violation. d_new takes a unsigned interger parameter for length like size_t. So d_new's implementation has a problem , I traced the source code. : p = _gc.malloc(length * size); : debug(PRINTF) printf(" p = %p\n", p); : memset(p, 0, length * size); Oh! My God! There is no checking for null. when _gc.malloc can't allocate a memory and returns null, memset would makes an access violation. 5. Many API with be suffixed W are used in phobos. I've checked all source code on phobos , and found many API with be suffixed W are used. Doesn't Phobos support Win9x? I'm very deploring about it. yaneurao. |
January 04, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to yaneurao | Phobos is buggy. It is a starter, more of a guideline to the library interface. yaneurao@sun-inet.or.jp wrote: > 4.new allcator had better to throw bad_alloc or return null > if it can't allocated. > In a foregoing case, GetFileSize returns -1 , and > > buf = new byte [-1]; > > is executed and makes an access violation. I think it may thow an assertion failure or something like wrong input failure. Or simply leave ir as is, since you should be able to see the problem in the debugger, but i'd say that giving -1 to malloc is a bug in your program. To return null i would say this would be a very, very bad idea, since you will notice a bug in your program much later! > d_new takes a unsigned interger parameter for length like size_t. > So d_new's implementation has a problem , I traced the source code. > > : p = _gc.malloc(length * size); > : debug(PRINTF) printf(" p = %p\n", p); > : memset(p, 0, length * size); > > Oh! My God! There is no checking for null. > when _gc.malloc can't allocate a memory and returns null, > memset would makes an access violation. DigitalMars C++ compiler doesn't do it either. On Windows, this should never happen anyway. And if it does, there is *no* way your application can help itself. I think the malloc implementation simply has to wait until memory becomes available on such memory rich systems like a PC. If the signature is changed, it would cut off the pathologic cases when range checking is on? > 5. Many API with be suffixed W are used in phobos. > Doesn't Phobos support Win9x? > I'm very deploring about it. Wasn't there a platform update, which adds simple implementation of W APIs into Windows 9x? Like, if it does work, then why should we compromise the quality of unicode support in Windows NT derivatives? I know languages with different scripts (russian and german), and i'm very happy that NT and other operating systems can suport them properly and simultaneously - but only so long as software does. And it's a pity to see it often doesn't and spoils it all, because of ties to the old API. -eye |
January 05, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Minkov | In article <bt9j6q$1pr6$1@digitaldaemon.com>, Ilya Minkov says... > Wasn't there a platform update, which adds simple implementation of W APIs into Windows 9x? Like, if it does work, then why should we compromise the quality of unicode support in Windows NT derivatives? I know languages with different scripts (russian and german), and i'm very happy that NT and other operating systems can suport them properly and simultaneously - but only so long as software does. And it's a pity to see it often doesn't and spoils it all, because of ties to the old API. No need to *COMPROMISE*. We can use Unicode *AND* we can run our programs on Win9x , just coding like this: enum { ERROR_CALL_NOT_IMPLEMENTED = 120 } // --- std.file.read void[] read(char[] name) { DWORD size; DWORD numread; HANDLE h; byte[] buf; wchar* namez = std.utf.toUTF16z(name); h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,(HANDLE)null); if (GetLastError()== ERROR_CALL_NOT_IMPLEMENTED){ h = CreateFileA(toMBSz(namez),GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,(HANDLE)null); } if (h == INVALID_HANDLE_VALUE) goto err1; size = GetFileSize(h, null); buf = new byte[size]; if (ReadFile(h,buf,size,&numread,null) != 1) goto err2; if (numread != size) goto err2; if (!CloseHandle(h)) goto err; return buf; err2: CloseHandle(h); err: delete buf; err1: throw new FileException(name, GetLastError()); } // mcb <-> wcb convertion module widestring; private import std.string; version(Win32){ extern(Windows) export int WideCharToMultiByte( uint CodePage, uint dwFlags, char* lpWideCharStr, int cchWideChar, char* lpMultiByteStr, int cbMultiByte, char* lpDefaultChar, bool* lpUsedDefaultChar); extern(Windows) export int MultiByteToWideChar( uint CodePage, uint dwFlags, char* lpMultiByteStr, int cchMultiByte, wchar* lpWideCharStr, int cchWideChar); } else { extern(C){ enum { LC_ALL = 0 } char* setlocale(int, char*); int mbstowcs(wchar*, char*, int); int wcstombs(char*, wchar*, int); } } char[] toMBS(wchar[] s) { char[] result; version(Win32){ result.length = WideCharToMultiByte(0, 0, (char*)s, s.length, null, 0, null, null); WideCharToMultiByte(0, 0, (char*)s, s.length, result, result.length, null, null); }else{ synchronized (locale_sync_object) { char* o = setlocale(LC_ALL, null); setlocale(LC_ALL, ""); result.length = wcstombs(null, s, 0); wcstombs(result, s, result.length); setlocale(LC_ALL, o); } } return result; } char* toMBSz(wchar* s) { return std.string.toStringz(toMBS(s[0..std.string.wcslen(s)])); } version(Win32){ } else { private static Object locale_sync_object; // note that 'setlocale' should be used in 'synchronized'. } |
January 05, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to yaneurao | Only Microsoft could turn FILE h = OpenFile("foo"); into that mess. ;) In the old days, things were somewhat simpler. Maybe once 95/98/Me die completely, and everyone switches over to Unicode, things will get better. Sean <yaneurao@sun-inet.or.jp> wrote in message news:btadkb$30bl$1@digitaldaemon.com... > In article <bt9j6q$1pr6$1@digitaldaemon.com>, Ilya Minkov says... > > > Wasn't there a platform update, which adds simple implementation of W APIs into Windows 9x? Like, if it does work, then why should we compromise the quality of unicode support in Windows NT derivatives? I know languages with different scripts (russian and german), and i'm very happy that NT and other operating systems can suport them properly and simultaneously - but only so long as software does. And it's a pity to see it often doesn't and spoils it all, because of ties to the old API. > > No need to *COMPROMISE*. > > We can use Unicode *AND* > we can run our programs on Win9x , > just coding like this: > > enum { ERROR_CALL_NOT_IMPLEMENTED = 120 } > > // --- std.file.read > void[] read(char[] name) > { > DWORD size; > DWORD numread; > HANDLE h; > byte[] buf; > wchar* namez = std.utf.toUTF16z(name); > > h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, > FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,(HANDLE)null); > if (GetLastError()== ERROR_CALL_NOT_IMPLEMENTED){ > h = CreateFileA(toMBSz(namez),GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, > FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,(HANDLE)null); > } > > if (h == INVALID_HANDLE_VALUE) > goto err1; > > size = GetFileSize(h, null); > buf = new byte[size]; > > if (ReadFile(h,buf,size,&numread,null) != 1) > goto err2; > > if (numread != size) > goto err2; > > if (!CloseHandle(h)) > goto err; > > return buf; > > err2: > CloseHandle(h); > err: > delete buf; > err1: > throw new FileException(name, GetLastError()); > } > > // mcb <-> wcb convertion > module widestring; > > private import std.string; > > version(Win32){ > extern(Windows) export int WideCharToMultiByte( > uint CodePage, > uint dwFlags, > char* lpWideCharStr, > int cchWideChar, > char* lpMultiByteStr, > int cbMultiByte, > char* lpDefaultChar, > bool* lpUsedDefaultChar); > > extern(Windows) export int MultiByteToWideChar( > uint CodePage, > uint dwFlags, > char* lpMultiByteStr, > int cchMultiByte, > wchar* lpWideCharStr, > int cchWideChar); > > } else { > extern(C){ > enum { LC_ALL = 0 } > char* setlocale(int, char*); > int mbstowcs(wchar*, char*, int); > int wcstombs(char*, wchar*, int); > } > } > > char[] toMBS(wchar[] s) > { > char[] result; > version(Win32){ > result.length = WideCharToMultiByte(0, 0, (char*)s, s.length, > null, 0, null, null); > WideCharToMultiByte(0, 0, (char*)s, s.length, result, > result.length, null, null); > }else{ > synchronized (locale_sync_object) { > char* o = setlocale(LC_ALL, null); > setlocale(LC_ALL, ""); > result.length = wcstombs(null, s, 0); > wcstombs(result, s, result.length); > setlocale(LC_ALL, o); > } > } > return result; > } > > char* toMBSz(wchar* s) { return > std.string.toStringz(toMBS(s[0..std.string.wcslen(s)])); } > > version(Win32){ > } else { > private static Object locale_sync_object; > // note that 'setlocale' should be used in 'synchronized'. > } |
January 12, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to yaneurao | <yaneurao@sun-inet.or.jp> wrote in message news:bt9ds1$1htl$1@digitaldaemon.com... > I am reported that my game library doesn't go well in Win9x. I'll see if I can get this fixed for the next update. -Walter |
January 12, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | >> I am reported that my game library doesn't go well in Win9x. >I'll see if I can get this fixed for the next update. -Walter my game library can download here: http://www.sun-inet.or.jp/~yaneurao/dlang/english.html in yaneSDK4D , y4d_aux/file.d is a fixed version of std.file. I hope std.file.d will be replaced by y4d_aux/file.d note : std.file.read should try *W version API first , and if it fails , convert wchar[](UTF-16) into MBS(MultiByteString) and try *A version API. I think it is better to have a global flag indicates what *W APIs are not implemented. |
January 12, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to yaneurao | <yaneurao@sun-inet.or.jp> wrote in message news:bttg9u$309d$1@digitaldaemon.com... > >> I am reported that my game library doesn't go well in Win9x. > >I'll see if I can get this fixed for the next update. -Walter > > my game library can download here: http://www.sun-inet.or.jp/~yaneurao/dlang/english.html > > in yaneSDK4D , y4d_aux/file.d is a fixed version of std.file. I hope std.file.d will be replaced by y4d_aux/file.d Thanks! > note : std.file.read should try *W version API first , and if it fails , > convert wchar[](UTF-16) into MBS(MultiByteString) and try *A version API. > I think it is better to have a global flag indicates > what *W APIs are not implemented. That was my first approach. But I think it is unnecessary, one only needs to check GetVersion() for 95, 98, and ME. This is because the lack of support is confined to 95, 98 and ME, and since they are officially abandoned by Microsoft, it will never get fixed. |
January 12, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | > <yaneurao@sun-inet.or.jp> wrote in message news:bttg9u$309d$1@digitaldaemon.com... > > >> I am reported that my game library doesn't go well in Win9x. > > >I'll see if I can get this fixed for the next update. -Walter > > > > my game library can download here: http://www.sun-inet.or.jp/~yaneurao/dlang/english.html > > > > in yaneSDK4D , y4d_aux/file.d is a fixed version of std.file. I hope std.file.d will be replaced by y4d_aux/file.d > > Thanks! > > > note : std.file.read should try *W version API first , and if it fails , > > convert wchar[](UTF-16) into MBS(MultiByteString) and try *A version API. > > I think it is better to have a global flag indicates > > what *W APIs are not implemented. > > That was my first approach. But I think it is unnecessary, one only needs to > check GetVersion() for 95, 98, and ME. This is because the lack of support is confined to 95, 98 and ME, and since they are officially abandoned by Microsoft, it will never get fixed. That's true for the A vs W issue, but there are also API functions that are added as the OSs, and even the Service Packs, progress. |
January 13, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | "Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:btts7n$kj8$1@digitaldaemon.com... > > That was my first approach. But I think it is unnecessary, one only needs > to > > check GetVersion() for 95, 98, and ME. This is because the lack of support > > is confined to 95, 98 and ME, and since they are officially abandoned by Microsoft, it will never get fixed. > > That's true for the A vs W issue, but there are also API functions that are > added as the OSs, and even the Service Packs, progress. In general, I'd prefer to rely on failure indications rather than version numbers to check for features. But my experience with that with the win32 API has been rather negative, the failure indications are unreliable. For example, the 'copy-on-write' for memory mapped files is not implemented on Win95, but the API, instead of failing, silently converts it to 'write'. |
January 13, 2004 Re: std.file.read makes AV in Win9x | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | > > > That was my first approach. But I think it is unnecessary, one only > needs > > to > > > check GetVersion() for 95, 98, and ME. This is because the lack of > support > > > is confined to 95, 98 and ME, and since they are officially abandoned by > > > Microsoft, it will never get fixed. > > > > That's true for the A vs W issue, but there are also API functions that > are > > added as the OSs, and even the Service Packs, progress. > > In general, I'd prefer to rely on failure indications rather than version numbers to check for features. But my experience with that with the win32 API has been rather negative, the failure indications are unreliable. For example, the 'copy-on-write' for memory mapped files is not implemented on Win95, but the API, instead of failing, silently converts it to 'write'. Indeed. All this argues for a win32 layer, but I think several people have already questioned whether it is better as a separate library rather than in the language. I'm still in two (or three) minds about the whole issue. :( |
Copyright © 1999-2021 by the D Language Foundation