libyal / libewf

Libewf is a library to access the Expert Witness Compression Format (EWF)
GNU Lesser General Public License v3.0
263 stars 76 forks source link

How do I use/enable wide character support ? #166

Closed mikebbt closed 2 years ago

mikebbt commented 2 years ago

I have modified my build script to include --enable-wide-character-type=yes when running configure (Windows builds only). When I run my app it doesn't look like the wide calls are being made. Is there something else that I need to do (other dependencies, additional configure args etc...) to get wide character working?

joachimmetz commented 2 years ago

@mikebbt can you provide more detail about

When I run my app it doesn't look like the wide calls are being made.

which app? how does this app use the API?

mikebbt commented 2 years ago

When writing or reading an L01 from our app the path/filename may contain Unicode characters (Russian, Chinese are most prevalent). The build environment cross-compiles libewf for Windows from a Mac, I'm not the custodian so can try to find more detail from the devops team if needed. So I have modified their build script as I have mentioned above to simply add the wide character enable flag. The library builds fine, when the app is run I'm calling libewf_handle_open_wide(), the issue occurs on the closure:

Error is 'libewf_handle_write_finalize: unable to write finalize. [libcfile_file_open_with_error_code: unable to open file: with error: The filename, directory name, or volume label syntax is incorrect.]'.

Added some prints in the libewf code and checked to see if HAVE_WIDE_SYSTEM_CHARACTER was defined and it's not so I've missed something on the build side I'm assuming.

joachimmetz commented 2 years ago

First of all L01 is a proprietary format.

Which paths? Those in the the L01 or those of the local file system?

The library builds fine, when the app is run I'm calling libewf_handle_open_wide(), the issue occurs on the closure:

what path is your app passing to this function?

mikebbt commented 2 years ago

Understood we are using libewf as part of our proprietary exporting. The paths for the local file system is what I'm dealing with, a simple path on a Windows machine. My test case has the destination directory in Russian.

To keep it simple I would most likely have the same issues exporting or importing an E01 file using libewf, so if my path/filename had unicode chars is setting --enable-wide-character-type=yes when building libewf for Windows all I need to do?

joachimmetz commented 2 years ago

My test case has the destination directory in Russian.

so windows has a char (or ansi) and wchar_t (or unicode) file system methods (most other platforms have Unicode char support). --enable-wide-character-type=yes enables these wchar_t methods so you calling application can use the _wide functions. You'll need to pass them native Unicode encoded paths, which on Windows is UTF-16.

--enable-wide-character-type=yes should do the trick for build systems that use the configure script. For visual studio you have to make the necessary configuration changes

mikebbt commented 2 years ago

Thanks for the confirmation, will go back and review how libewf is being built as the issue must be there somewhere.

mikebbt commented 2 years ago

Finally did get this working, needed to change a #ifdef in types.h.in:

FROM:

if defined( WINAPI ) && ( defined( _UNICODE ) || defined( UNICODE ) )

TO:

if defined ( WINAPI )

I couldn't see anywhere that UNICODE was defined so tweaked it for now, in my case always having wide char support for Windows is what we want.

joachimmetz commented 2 years ago

UNICODE is defined by Visual studio and is dependent on the configuration of the project.

HAVE_WIDE_SYSTEM_CHARACTER is an libewf and ewftools internal setting to define if the platform provides wchar_t main capable function. This is not related to your initial question.

mikebbt commented 2 years ago

My question was asking if passing "enable for wide char" to the config would allow me support, it didn't. I assumed (maybe wrongly) that setting that would have defined HAVE_WIDE_SYSTEM_CHARACTER in the code but it didn't without this tweak to types.h.in. Was there something else I could have done in the build stage to accomplish the same thing?

joachimmetz commented 2 years ago

Was there something else I could have done in the build stage to accomplish the same thing?

I don't know, you have not provided me sufficient information to answer this question:

mikebbt commented 2 years ago

Build env: cross-compile of libewf for Windows on MacOS using mingw

Usage: libewf is built as a dll

Functions called to read:

Path: "C:\Users\user-test\еуыеД01\files.e01"

joachimmetz commented 2 years ago

Has --enable-winapi has been provided to configure as well?

If winapi is enabled then CreateFile is returning ERROR_INVALID_NAME you might need to check what path it is actually passed to CreateFile https://github.com/libyal/libcfile/blob/b6048bc8f41ad8c2bd32b5e0f50a7a989e15730e/libcfile/libcfile_file.c#L945

If not enabled it might try to fallback on narrow character/string WINAPI methods and in that case make sure the corresponding codepage is set accordingly https://github.com/libyal/libewf/blob/main/include/libewf.h.in#L90

mikebbt commented 2 years ago

Checked the build script and I don't see --enable-winapi, will investigate the path and look into the codepage calls.