Fopen() 2.0.0.5

More
1 week 1 day ago #1 by Karl-Heinz
Fopen() 2.0.0.5 was created by Karl-Heinz
Guys,

i´m playing with the 2.0.0.5 Fopen() and noticed that if the func fails the errorcode is always 1008 ?
Is that a known issue, or maybe even fixed in the meantime ?

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

More
1 week 1 day ago #2 by robert
Replied by robert on topic Fopen() 2.0.0.5
Karl Heinz,
Which errorcode do you mean ?

Robert

XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

More
1 week 1 day ago #3 by Karl-Heinz
Replied by Karl-Heinz on topic Fopen() 2.0.0.5
Hi Robert,

The file "D:\test\FFunction.txt" exists. when i change the dir or filename Fopen() fails, and the errorcodes are always the same.

    IF  ( h := Fopen ( "D:\test\FFunctio.txt"  )) != F_ERROR  // file doesn´t exist 	errcode should be 2
//     IF  ( h := Fopen ( "D:\tes\FFunction.txt"  )) != F_ERROR  // dir doesn´t exist   errcode should be 3	

	? "ok"

	Fclose ( h ) 

     ELSE

	? "Getlasterror()" , getlasterror()   // always 1008
        ? "Ferror()", Ferror()			// always 1008
        ? "GetDosError()" , Getdoserror() // always 1008
        ? GetSystemMessage ( fError() )   // localized text is shown

     ENDIF

To see in x# the errortext i translated the VO func GetSystemMessage( dwID AS DWORD )

FUNCTION GetSystemMessage( dwID AS DWORD ) AS STRING 
	
	RETURN System.ComponentModel.Win32Exception{ (INT) dwID }.Message
	
FUNCTION GetSystemMessage() AS STRING 
	
  	RETURN GetSystemMessage ( (DWORD) System.Runtime.InteropServices.Marshal.GetLastWin32Error() ) 

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

More
1 week 1 day ago #4 by Karl-Heinz
Replied by Karl-Heinz on topic Fopen() 2.0.0.5
BTW. The "magic" number 1008 also appears if the file is locked ( errcode 32 should be shown ) or the path or filename contains "bad chars" ( errcode 123 should be shown )

Please Log in or Create an account to join the conversation.

More
1 week 1 day ago #5 by robert
Replied by robert on topic Fopen() 2.0.0.5
Karl-Heinz,

The X# runtime does not use the same underlying OS calls when opening a file. It uses managed streams in stead.
The File Handle that is returns is just a unique id that matches the stream in a dictionary in the runtime.

Inside the FileStream constructor the "File Not Found" situation is decoded into a FileNotFoundException. We are capturing this and we are assigning Marshal.GetLastWin32Error() to Ferror().
Apparently at that moment GetLastWin32Error has already received a new value.
I can see in the constructor of FileStream that the __Error.WinIOError() method is called with the GetLastWin32Error and when this error is 2 then the FileNotFoundException is generated.

Maybe we should expose the exception object in a FException() function so you can see which exception occurred ?
Or we should decode the exception type back into the numbers and store these numbers in FError() ?

Robert

XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

More
1 week 1 day ago #6 by Karl-Heinz
Replied by Karl-Heinz on topic Fopen() 2.0.0.5
Hi Robert,

Since FError() is a vo/x​​# specific thing, my first thought is to keep using it. It seems that the CreateManagedFileStream() method is responsible for the errorcode.
private static method createManagedFileStream(cFIle as string , oMode as VOFileMode ) as FileStream
	local result as FileStream
	//
	result := null
	try
		result := FileStream{cFIle, oMode:FileMode, oMode:FileAccess, oMode:FileShare, 4096}
		return result

	catch ex as Exception
		Trace.WriteLine(ex:Message)
		Functions.FError((DWord)Marshal.GetLastWin32Error())
		return result
	end try

FileStream throws, beside others, 4 exceptions of interest:
ArgumentException   // bad param - illegal chars in pathname or filename detected  errorcode  97 
                       ( VO gives 123 - shows IMO a better explanation than 97 )
DirectoryNotFound   // should show errorcode 3 
FileNotFound        // should show errorcode 2
IOException         // should show errorcode 32  - Access violation

i have a func that returns the errorcode of an exception. Does it make any differences when you fill fError() in this way
	catch ex as Exception
		Trace.WriteLine(ex:Message)
		Functions.FError( GetErrorCodeFromException ( eX )  )
		return result

or does it make any difference to split the exceptions 

	catch ex as ArgumentException   
		Trace.WriteLine(ex:Message)
		Functions.FError( GetErrorCodeFromException ( eX )  )
		return result

	catch ex as DirectoryNotFound   
		Trace.WriteLine(ex:Message)
		Functions.FError( GetErrorCodeFromException ( eX )  )
		return result
etc.


FUNCTION GetErrorCodeFromException ( o AS Exception ) AS DWORD
RETURN  _and ( (DWORD) System.Runtime.InteropServices.Marshal.GetHRForException ( o ) , 0x0000FFFF ) 

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

More
1 week 18 hours ago #7 by robert
Replied by robert on topic Fopen() 2.0.0.5
Karl-Heinz,

Karl-Heinz wrote:

FUNCTION GetErrorCodeFromException ( o AS Exception ) AS DWORD
RETURN  _and ( (DWORD) System.Runtime.InteropServices.Marshal.GetHRForException ( o ) , 0x0000FFFF ) 


Thanks for the example. And it works !
Can I use this and add it to the exception handling code in the runtime ?
This is what I like so much about open source. Community driven code !

Robert

XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

More
1 week 11 hours ago #8 by Karl-Heinz
Replied by Karl-Heinz on topic Fopen() 2.0.0.5
Hi Robert,

Great news !

Glad to hear that it works, and of course, you may use the code !!

Compared to what you and your team is doing, this "two Liner" is nothing, it´s just a translation of a c# snippet that i´ve found somewhere.

One question: GetLastWin32Error() still shows 1008, right ?

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

More
1 week 10 hours ago #9 by robert
Replied by robert on topic Fopen() 2.0.0.5
Karl-Heinz,

If you mean the Marshal.GetLastWin32Error(). We are not touching that. So it keeps on returning 1008. And our DosError() returns the same because it calls that method.
I have changed the code that touches FError() to:

TRY
clearErrorState()
// do something
CATCH e as Exception
setErrorState(e)
END TRY

Inside clearErrorState the last errorcode and last exception are cleared.
Inside setErrorState() the exception is saved and the errorcode is retrieved using the method that you indicated.

Ferror() now returns what you expect.
I have also added FException() that returns the Exception object for more information.

Robert



Robert

XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

More
5 days 15 hours ago #10 by Karl-Heinz
Replied by Karl-Heinz on topic Fopen() 2.0.0.5
Hi Robert,

In Github i see the changes you´ve made. BTW. it´s a very nice feature to be able to jump to the latest sources via the [view source] button in the help file.

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.