https://bugs.winehq.org/show_bug.cgi?id=52441 sizuku2718(a)gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |sizuku2718(a)gmail.com --- Comment #9 from sizuku2718(a)gmail.com --- Created attachment 75291 --> https://bugs.winehq.org/attachment.cgi?id=75291 CryptBinaryToStringATest.cpp, output_friendly.txt, output.txt I implemented `CryptBinaryToStringA` for `CRYPT_STRING_HEX` and I tested this patch. In the process, I found a slight bug (please look at `How to implement this`). Now the daemon runs without crashing, but it doesn't works correctly. I start to talking, supposing to use Wine 8.18. First, I want to apologize for me not directly contributing the code. I have reservations about sharing my real name on the Internet due to privacy concern. I worry that someone who see my code might not be allowed to send the implementation to Wine if I attach the patch. Please understand my hesitation, and I hope you can accept my efforts to explain my observations and suggestions. (If I seem to misunderstand, let me know.) # The function's behavior I tested CryptBinaryTostringA for some sequences in my Windows 11 machine with the attached script I wrote, and I checked outputs. (please see the attachments: CryptBinaryToStringATest.cpp, output_friendly.txt, output.txt) And please refer to the [Microsoft documentation](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cry...). I'll explain what I found out. Note that `_` means a space (0x20) and `$` CR (0x0D) below. First, let `str` be the string generated from the original byte sequence by `CryptBinaryToStringA` with ``CRYPT_STRING_HEXRAW`, and `len` the length of `str`. `len` is always even number because if the hexademical number sequence had odd length, the `0` would added to the last. Second, define `s[len/2] = {s[0], ... ,s[len/2 - 1]}` as the sequence made by separete `str` into the two charcters block. ## Case 1 (with `CRYPT_STRING_NOCRLF` and optionaly `CRYPT_STRING_NOCR`): 1. join `s` with a space (0x20). 2. return it. ### Example - `48656c6c6f2c20776f726c64212020` to `48_65_6c_6c_6f_2c_20_77_6f_72_6c_64_21_20_20` - `727432666e3025676e2a` to `72_74_32_66_6e_30_25_67_6e_2a` ## Case 2 (with `CRYPT_STRING_NOCR`): 1. join `s[8*k], s[8*k + 1], ... ,s[8*k + 7]` with a space (0x20), and put it `t[k]`. (remark that the sequence might stop below `8*k + 7` if `k` is the maximum.) 2. join `t[2*k]` and `t[2*k + 1]` with two spaces and put it `u[k]`. (if `2*k` is the maximum for a `k`, you should set `u[k] = t[2*k]`.) 3. join `u` with LF (0x0A) and, put it also on the last. 4. return it. ### Example - `727432666e3025676e2a` to `72_74_32_66_6e_30_25_67__6e_2a` - `3633394b71775c2d37395c646b0a4f676532723378522b3151397d594c32434b` to the following. (the last character is LF.) ``` 36_33_39_4b_71_77_5c_2d__37_39_5c_64_6b_0a_4f_67 65_32_72_33_78_52_2b_31__51_39_7d_59_4c_32_43_4b ``` - `364c76360a41322d265c34246e6d396d6f0d54313079333171657b6e305c432623403724` to the following (the last character is LF.) ``` 36_4c_76_36_0a_41_32_2d__26_5c_34_24_6e_6d_39_6d 6f_0d_54_31_30_79_33_31__71_65_7b_6e_30_5c_43_26 23_40_37_24 ``` ## Case 3 (with no more flags): It is almost the same as Case 2. Please replace the LF with CR LF. # Implement Suggstions I guess it's not difficult. Please look at [base64.c](https://gitlab.winehq.org/wine/wine/-/blob/wine-8.18/dlls/crypt32/base64.c?r...) All you have to do is copy `BinaryToHexRawA()` and change it a little (and also edit the switch block in `CryptBinaryToStringA()`) ## `needed` `needed` has to be change. If `nbin` == 0, it should be 0, 1, or 2 (depends on the flags). Now I suppose `nbin` != 0. - if `NOCRLF`, `needed` = 0 + 1 + (3 * nbin - 1). - else if `NOCR`, `needed` = 1 + 1 + ((3 * nbin - 1) + (nbin - 1) / 8). - else, `needed` = 1 + 1 + ((3 * nbin - 1) + (nbin - 1) / 8 + (nbin - 1) / 16). ## main loop - if `!nbin`, break. - else if `!(count & 15)`, insert " ", "\n", or "\r\n". - else if `!(count & 7)`, insert " " or " ". - else, insert " ". ## The Last Part There's a bug in the implementation of BinaryToHexRawA `BinaryToHexRawA`'s implementation has a bug here. If both `CRYPT_STRING_NOCR` and `CRYPT_STRING_NOCRLF` are set, it shouldn't insert any character at the end, but it currently does. If both are set, the function probably causes overflow because `needed` is smaller. # Identified Issues During my testing with `$ wine ./sdrt5080_x64.exe`, I encountered the following error:
Error 1904.Module C:\Program Files (x86)\SoftDenchi\UCX.ocx failed to register. HRESULT -2147220473. Contact your support personnel.
(`sdrt5080_x64.exe` : https://acf.paltio.co.jp/sdrt/sdrt5080_x64.exe) I also attempted to manually run the daemon with the command:
$ wine Program\ Files\ \(x86\)/SoftDenchi/UCManSvc.exe
However, an application that relies on SoftDenchi still prompted me to install SoftDenchi. # In Conclusion I'm not very experienced with using English, so I had ChatGPT proof-read it. But I guess it is still have some difficult point to understand, so I want to apologize for it. I hope my findings will be of assistance to the Wine community. Thank you for considering these suggestions. Best regards, sizuku2718 -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.