Jump to page: 1 2 3
Thread overview
std.file.read makes AV in Win9x
Jan 04, 2004
yaneurao
Jan 04, 2004
Ilya Minkov
Jan 05, 2004
yaneurao
Jan 05, 2004
Sean L. Palmer
Jan 12, 2004
Walter
Jan 12, 2004
yaneurao
Jan 12, 2004
Walter
Jan 12, 2004
Matthew
Jan 13, 2004
Walter
Jan 13, 2004
Matthew
Jan 13, 2004
J Anderson
Jan 13, 2004
J Anderson
Jan 13, 2004
Matthew
Jan 13, 2004
J Anderson
Jan 13, 2004
Ian Johnston
Jan 13, 2004
J Anderson
Jan 13, 2004
Matthew
Jan 13, 2004
J Anderson
Jan 13, 2004
Matthew
Jan 13, 2004
Ian Johnston
Old Windows support was Re: std.file.read makes AV in Win9x
Jan 16, 2004
Mark T
Jan 17, 2004
Matthew
Jan 17, 2004
Georg Wrede
January 04, 2004
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
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
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
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
<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
>> 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
<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
> <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
"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
> > > 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. :(


« First   ‹ Prev
1 2 3