Fred wrote: ↑Fri Jan 19, 2024 5:53 pmFixed.
Not fixed in beta 3.
Now a new error is raised.
---------------------------
PureBasic - Assembler error
---------------------------
purebasic.asm [652]:
file "Z:\프로그램\TXT파~1.TXT"
processed: file 'Z:\프로그램\TXT파~1.TXT'
error: file not found.
So I did an experiment.
I created a purebasic.asm file (UTF-8), converted it to ascii (system default code page) format, recompiled it, and it worked.
It seems that the assembler doesn't recognize the UTF-8 string and only sees it as ascii.
BTW, in the C backend, it compiles fine with no errors.
The problem only occurs in the assembly backend.
Edit:
According to a search on the FASM forum, FASM can only read ANSI source code.
So, it seems best to have the pb compiler read the file specified in IncludeBinary and write the data byte by byte to the data section.
For example, "dd 0xAABBCCDD" and so on.
Another way is to replace CreateFileA API called by Fasm.exe with CreateFileW API via a hook. (by using MS Detours library)
https://github.com/microsoft/Detours
I've done some testing and it seems to work, but I haven't done any in-depth testing so I don't know if it's perfect.
So, try it out only for testing purposes.
1. Compile the Detours library at the above webpage in x86 mode.
2. Compile the code below with PB x86 version to create a dll file. (for example, the name is HookCreateFileA.dll).
3. There is "SetDll.exe" file in the "bin.x86" folder of the compiled Detours library. Run it like this:
Code: Select all
setdll /d:HookCreateFileA.dll FAsm.exe
4. Copy the newly created FAsm.exe and HookCreateFileA.dll files to the PB "Compilers" folder. (Copy the same files for both x86 and x64)
This will ensure that the UTF-8 string filenames in the IncludeBinary are read correctly.
Code: Select all
CompilerIf #PB_Compiler_Processor <> #PB_Processor_x86
CompilerError "Compile with PB x86."
CompilerEndIf
CompilerIf #PB_Compiler_ExecutableFormat <> #PB_Compiler_DLL
CompilerError "Compile as DLL file."
CompilerEndIf
Import "Detours.lib"
DetourTransactionBegin.l()
DetourRestoreAfterWith()
DetourTransactionCommit.l()
DetourUpdateThread.l(hThread)
DetourAttach.l(*ppPointer, pDetour)
DetourDetach.l(*ppPointer, pDetour)
EndImport
Import "kernel32.lib"
CreateFileA(*lpFileName, dwDesiredAccess.l, dwShareMode.l, lpSecurityAttributes, dwCreationDisposition.l, dwFlagsAndAttributes.l, hTemplateFile)
CreateFileW(lpFileName.s, dwDesiredAccess.l, dwShareMode.l, lpSecurityAttributes, dwCreationDisposition.l, dwFlagsAndAttributes.l, hTemplateFile)
EndImport
Prototype CreateFile(*lpFileName, dwDesiredAccess.l, dwShareMode.l, lpSecurityAttributes, dwCreationDisposition.l, dwFlagsAndAttributes.l, hTemplateFile)
Global OriCreateFileA.CreateFile, Error.l
ProcedureDLL My_CreateFileA(*lpFileName, dwDesiredAccess.l, dwShareMode.l, lpSecurityAttributes, dwCreationDisposition.l, dwFlagsAndAttributes.l, hTemplateFile)
Protected FileName.s, Result
Result = OriCreateFileA(*lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
; The "GetLastError_() = #ERROR_INVALID_NAME" error check will fail because some UTF-8 filenames are accepted by CreateFileA but not actually processed.
; Therefore, it's better not to use the GetLastError_() at all.
If Result = #INVALID_HANDLE_VALUE And dwCreationDisposition = #OPEN_EXISTING ;And GetLastError_() = #ERROR_INVALID_NAME
If *lpFileName
FileName = PeekS(*lpFileName, -1, #PB_UTF8)
If FileName
Result = CreateFileW(FileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
ProcedureDLL AttachProcess(Instance)
Error = -1
OriCreateFileA = @CreateFileA()
DetourRestoreAfterWith()
If DetourTransactionBegin() = #NO_ERROR
DetourUpdateThread(GetCurrentThread_())
DetourAttach(@OriCreateFileA, @My_CreateFileA())
Error = DetourTransactionCommit()
EndIf
EndProcedure
ProcedureDLL DetachProcess(Instance)
If Error = #NO_ERROR
DetourTransactionBegin()
DetourUpdateThread(GetCurrentThread_())
DetourDetach(@OriCreateFileA, @My_CreateFileA())
DetourTransactionCommit()
EndIf
EndProcedure
Edit 2:
Another workaround only for Windows 10 1903+.
https://learn.microsoft.com/en-us/windo ... -code-page
The following must be added as a manifest to the fasm.exe file using a resource editing program like Resource Hacker in order to work properly.
Alternatively, you can use Visual Studio's mt.exe as described in the webpage above.
Code: Select all
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity type="win32" name="..." version="6.0.0.0"/>
<application>
<windowsSettings>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings>
</application>
</assembly>