Needed for native mfc42u.dll.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51850 Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- The bug report does not mention that the tool cannot run without mfc42u.dll, which requires this API set. --- configure.ac | 1 + .../Makefile.in | 1 + .../api-ms-win-core-privateprofile-l1-1-0.spec | 14 ++++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 dlls/api-ms-win-core-privateprofile-l1-1-0/Makefile.in create mode 100644 dlls/api-ms-win-core-privateprofile-l1-1-0/api-ms-win-core-privateprofile-l1-1-0.spec
diff --git a/configure.ac b/configure.ac index 9b2c111119f..9630405bfcd 100644 --- a/configure.ac +++ b/configure.ac @@ -2416,6 +2416,7 @@ WINE_CONFIG_MAKEFILE(dlls/api-ms-win-core-namedpipe-l1-2-0) WINE_CONFIG_MAKEFILE(dlls/api-ms-win-core-namespace-l1-1-0) WINE_CONFIG_MAKEFILE(dlls/api-ms-win-core-normalization-l1-1-0) WINE_CONFIG_MAKEFILE(dlls/api-ms-win-core-path-l1-1-0) +WINE_CONFIG_MAKEFILE(dlls/api-ms-win-core-privateprofile-l1-1-0) WINE_CONFIG_MAKEFILE(dlls/api-ms-win-core-privateprofile-l1-1-1) WINE_CONFIG_MAKEFILE(dlls/api-ms-win-core-processenvironment-l1-1-0) WINE_CONFIG_MAKEFILE(dlls/api-ms-win-core-processenvironment-l1-2-0) diff --git a/dlls/api-ms-win-core-privateprofile-l1-1-0/Makefile.in b/dlls/api-ms-win-core-privateprofile-l1-1-0/Makefile.in new file mode 100644 index 00000000000..c8b8ef84aef --- /dev/null +++ b/dlls/api-ms-win-core-privateprofile-l1-1-0/Makefile.in @@ -0,0 +1 @@ +MODULE = api-ms-win-core-privateprofile-l1-1-0.dll diff --git a/dlls/api-ms-win-core-privateprofile-l1-1-0/api-ms-win-core-privateprofile-l1-1-0.spec b/dlls/api-ms-win-core-privateprofile-l1-1-0/api-ms-win-core-privateprofile-l1-1-0.spec new file mode 100644 index 00000000000..c8153c3a296 --- /dev/null +++ b/dlls/api-ms-win-core-privateprofile-l1-1-0/api-ms-win-core-privateprofile-l1-1-0.spec @@ -0,0 +1,14 @@ +@ stdcall GetPrivateProfileIntA(str str long str) kernel32.GetPrivateProfileIntA +@ stdcall GetPrivateProfileIntW(wstr wstr long wstr) kernel32.GetPrivateProfileIntW +@ stdcall GetPrivateProfileSectionW(wstr ptr long wstr) kernel32.GetPrivateProfileSectionW +@ stdcall GetPrivateProfileStringA(str str str ptr long str) kernel32.GetPrivateProfileStringA +@ stdcall GetPrivateProfileStringW(wstr wstr wstr ptr long wstr) kernel32.GetPrivateProfileStringW +@ stdcall GetProfileIntA(str str long) kernel32.GetProfileIntA +@ stdcall GetProfileIntW(wstr wstr long) kernel32.GetProfileIntW +@ stdcall GetProfileSectionA(str ptr long) kernel32.GetProfileSectionA +@ stdcall GetProfileSectionW(wstr ptr long) kernel32.GetProfileSectionW +@ stdcall GetProfileStringA(str str str ptr long) kernel32.GetProfileStringA +@ stdcall GetProfileStringW(wstr wstr wstr ptr long) kernel32.GetProfileStringW +@ stdcall WritePrivateProfileSectionA(str str str) kernel32.WritePrivateProfileSectionA +@ stdcall WritePrivateProfileStringA(str str str str) kernel32.WritePrivateProfileStringA +@ stdcall WritePrivateProfileStringW(wstr wstr wstr wstr) kernel32.WritePrivateProfileStringW
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51850 Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- The function is undocumented. It does not seem to take any arguments, but I don't know how to verify this without a doubt. --- dlls/wdscore/Makefile.in | 3 +++ dlls/wdscore/main.c | 35 +++++++++++++++++++++++++++++++++++ dlls/wdscore/wdscore.spec | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 dlls/wdscore/main.c
diff --git a/dlls/wdscore/Makefile.in b/dlls/wdscore/Makefile.in index 20ba1d3b1c9..92a733474f8 100644 --- a/dlls/wdscore/Makefile.in +++ b/dlls/wdscore/Makefile.in @@ -1,3 +1,6 @@ MODULE = wdscore.dll
EXTRADLLFLAGS = -Wb,--prefer-native + +C_SRCS = \ + main.c \ No newline at end of file diff --git a/dlls/wdscore/main.c b/dlls/wdscore/main.c new file mode 100644 index 00000000000..2bec81bcc92 --- /dev/null +++ b/dlls/wdscore/main.c @@ -0,0 +1,35 @@ +/* + * Copyright 2021 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wdscore); + +/*********************************************************************** + * CurrentIP (wdscore.@) + */ +DWORD WINAPI CurrentIP() +{ + FIXME("stub\n"); + return 0; +} \ No newline at end of file diff --git a/dlls/wdscore/wdscore.spec b/dlls/wdscore/wdscore.spec index 15958b86aba..8b6febe6b3b 100644 --- a/dlls/wdscore/wdscore.spec +++ b/dlls/wdscore/wdscore.spec @@ -71,7 +71,7 @@ @ stub ConstructPartialMsgIfW @ stub ConstructPartialMsgVA @ stub ConstructPartialMsgVW -@ stub CurrentIP +@ stdcall CurrentIP() @ stub EndMajorTask @ stub EndMinorTask @ stub GetMajorTask
On 12/23/21 19:43, Mohamad Al-Jaf wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51850 Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com
The function is undocumented. It does not seem to take any arguments, but I don't know how to verify this without a doubt.
The most effective way I'm aware of is to call it on i386 and check the stack alignment.
Yeah, that's also what the wiki says: https://wiki.winehq.org/Wine_Developer%27s_Guide/Other_Debugging_Techniques
But it also says that some functions can be wrongly interpreted as having more arguments than originally thought.
Honestly, I have no idea how to begin this, my knowledge of assembly is rudimentary. I see that WineDbg has a disassemble option, but I'm not sure how to use it in this context.
If you could guide me through this so that I can learn, I'd really appreciate it.
On Fri, Dec 24, 2021 at 5:28 PM Zebediah Figura (she/her) < zfigura@codeweavers.com> wrote:
On 12/23/21 19:43, Mohamad Al-Jaf wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51850 Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com
The function is undocumented. It does not seem to take any arguments, but I don't know how to verify this without a doubt.
The most effective way I'm aware of is to call it on i386 and check the stack alignment.
I don't understand this, I thought disassembly of Microsoft DLLs wasn't allowed? Why then does the example show assembly code of the undocumented function?
On Fri, Dec 24, 2021 at 9:54 PM Mohamad Al-Jaf mohamadaljaf@gmail.com wrote:
Yeah, that's also what the wiki says: https://wiki.winehq.org/Wine_Developer%27s_Guide/Other_Debugging_Techniques
But it also says that some functions can be wrongly interpreted as having more arguments than originally thought.
Honestly, I have no idea how to begin this, my knowledge of assembly is rudimentary. I see that WineDbg has a disassemble option, but I'm not sure how to use it in this context.
If you could guide me through this so that I can learn, I'd really appreciate it.
On Fri, Dec 24, 2021 at 5:28 PM Zebediah Figura (she/her) < zfigura@codeweavers.com> wrote:
On 12/23/21 19:43, Mohamad Al-Jaf wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51850 Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com
The function is undocumented. It does not seem to take any arguments, but I don't know how to verify this without a doubt.
The most effective way I'm aware of is to call it on i386 and check the stack alignment.
On Mon, Dec 27, 2021 at 9:00 PM Mohamad Al-Jaf mohamadaljaf@gmail.com wrote:
I don't understand this, I thought disassembly of Microsoft DLLs wasn't allowed? Why then does the example show assembly code of the undocumented function?
They're just example functions that some Wine developer wrote and compiled on their own to validate this method of guessing function arguments. They're not Microsoft code.
-Alex
I see, but I still don't understand the method used here. How can you see the stack entries if you don't disassemble the file? The only way I know of is through WineDbg and that does not seem to be correct. The method on that wiki page appears to require looking at the assembly code. Specifically, it says "ret hhll (where hhll is the number of bytes to remove, i.e. the number of arguments times 4)". As far as I know, ret is assembly code. So the method listed requires disassembly, no?
On Tue, Dec 28, 2021 at 12:02 AM Alex Henrie alexhenrie24@gmail.com wrote:
On Mon, Dec 27, 2021 at 9:00 PM Mohamad Al-Jaf mohamadaljaf@gmail.com wrote:
I don't understand this, I thought disassembly of Microsoft DLLs wasn't
allowed? Why then does the example show assembly code of the undocumented function?
They're just example functions that some Wine developer wrote and compiled on their own to validate this method of guessing function arguments. They're not Microsoft code.
-Alex
(I am not an I.P. lawyer and certainly not a binary reverser, and long time Wine non-contributor already, but just my .02 €¢)
* On 2021-12-28 07:50, Mohamad Al-Jaf wrote:
How can you see the stack entries if you don't disassemble the file? The only way I know of is through WineDbg and that does not seem to be correct. The method on that wiki page appears to require looking at the assembly code.
(1) The stack doesn't belong to a binary file, it's an ephemeral, entirely runtime entity. So looking at it is safe.
(2) A binary file saved onto disk and the one loaded into memory as executable image are already a bit different things, IMO.
Differences are introduced at least during runtime relocations of (the position-dependent) sections of an executable image.
(3) Actually there are two methods here: - 3a, creating the wrapper + looking at the stack pointer change after the call, and - 3b, finding the function epilogues [1], the `ret` instructions.
(3a) It doesn't require disassembly of the function, reading an ESP value just before the call and after it.
As this is not a low-level dll (like `ntdll.dll`), there would be probably no BSODs during the wrapper run.
It even could be done using `winedbg` and the `br` + `next` commands, IIRC, in debug session of the Media Creation Tool.
Maybe it would just do for you. (ie. maybe you'll see that the ESP register remains the same right before and just after the call)
(3b) The epilogue reflects only a small, non-core part of the function implementation. It merely shows how the interface between caller (an app) and callee (native lib) is organized.
And as the saying goes, https://www.google.com/search?q=interfaces+cannot+be+copyrighted
(4) Main concern here seems to be about "submitting disassembled or decompiled code" + "what the code does generally". [2]
--- quote --- While in theory it is still possible for someone that has disassembled Microsoft code to document what the code does generally, in their own words, this can become a legal grey area. --- quote ---
Specifically, it says "ret hhll (where hhll is the number of bytes to remove, i.e. the number of arguments times 4)". As far as I know, ret is assembly code. So the method listed requires disassembly, no?
Umm, yes and no. My summary would be following:
By looking at the disassembled calling points of the function and its' epilogues [1] _and_ by avoiding to memorize what does core of the function do (particularly which other WinAPI functions does it call), you stay safe and in compliance with copyrights and other stuff of Intellectual Property law.
This is my personal interpretation.
S.
[1] https://en.wikipedia.org/wiki/Function_prologue_and_epilogue#Epilogue [2] https://wiki.winehq.org/Disassembly#:~:text=While%20in%20theory,legal%20grey....
Saulius Krasuckas saulius2@ar-fi.lt writes:
Specifically, it says "ret hhll (where hhll is the number of bytes to remove, i.e. the number of arguments times 4)". As far as I know, ret is assembly code. So the method listed requires disassembly, no?
Umm, yes and no. My summary would be following:
By looking at the disassembled calling points of the function and its' epilogues [1] _and_ by avoiding to memorize what does core of the function do (particularly which other WinAPI functions does it call), you stay safe and in compliance with copyrights and other stuff of Intellectual Property law.
No, you should never look at a disassembly of a Windows dll, period.
Please read https://wiki.winehq.org/Clean_Room_Guidelines for details.
On 2021-12-28 18:22, Alexandre Julliard wrote:
Saulius Krasuckas saulius2@ar-fi.lt writes:
By looking at the disassembled calling points of the function and its' epilogues [1] _and_ by avoiding to memorize what does core of the function do (particularly which other WinAPI functions does it call), you stay safe and in compliance with copyrights and other stuff of Intellectual Property law.
No, you should never look at a disassembly of a Windows dll, period.
Please read https://wiki.winehq.org/Clean_Room_Guidelines for details.
Alexandre, I have read it before my answer and I found it to be contradicting other documentation page. So I had to interpret this contradiction.
Do you and other folks agree that part of the documentation is misleading or even incorrect in that regard?
Namely this block: https://wiki.winehq.org/Wine_Developer%27s_Guide/Other_Debugging_Techniques#...
--- quote --- Another method that has been much more successful is to attempt to figure out how many arguments each function is removing from the stack. This instruction, ret hhll (where hhll is the number of bytes to remove, i.e. the number of arguments times 4), contains the bytes 0xc2 ll hh in memory. It is a reasonable assumption that few, if any, functions take more than 16 arguments; therefore, simply searching for hh == 0 and ll < 0x40 starting from the address of a function yields the correct number of arguments most of the time.
Of course, this is not without errors. ret 00ll is not the only instruction that can can have the byte sequence 0xc2 ll 0x0; for example, push 0x000040c2 has the byte sequence 0x68 0xc2 0x40 0x0 0x0, which matches the above. Properly, the utility should look for this sequence only on an instruction boundary; unfortunately, finding instruction boundaries on an i386 requires implementing a full disassembler -- quite a daunting task. Besides, the probability of having such a byte sequence that is not the actual return instruction is fairly low.
Much more troublesome is the non-linear flow of a function. For example, consider the following two functions:
somefunction1: jmp somefunction1_impl
somefunction2: ret 0004
somefunction1_impl: ret 0008
In this case, we would incorrectly detect both somefunction1 and somefunction2 as taking only a single argument, whereas somefunction1 really takes two arguments. --- quote ---
That would help to answer the original question by Mohamad. And would indicate the page to be fixed.
Sadly the content seems to be imported into Wiki on 13:47, 3 February 2016 from the static docs, and now I am not sure how to trace back author of the quoted lines.
S.
On 12/28/21 12:24, Saulius Krasuckas wrote:
On 2021-12-28 18:22, Alexandre Julliard wrote:
Saulius Krasuckas saulius2@ar-fi.lt writes:
By looking at the disassembled calling points of the function and its' epilogues [1] _and_ by avoiding to memorize what does core of the function do (particularly which other WinAPI functions does it call), you stay safe and in compliance with copyrights and other stuff of Intellectual Property law.
No, you should never look at a disassembly of a Windows dll, period.
Please read https://wiki.winehq.org/Clean_Room_Guidelines for details.
Alexandre, I have read it before my answer and I found it to be contradicting other documentation page. So I had to interpret this contradiction.
Do you and other folks agree that part of the documentation is misleading or even incorrect in that regard?
It doesn't seem clear to me whether that page advises disassembling the function or its caller, but since it's ambiguous (and not particularly helpful) I've just removed the entire section.
Interesting discussion, but it looks like Zebediah's method is superior in all respects.
I can confirm that CurrentIP takes 0 arguments. I also tested her method with other, documented functions, that I know the argument counts of and it works perfectly.
On Tue, Dec 28, 2021 at 1:31 PM Zebediah Figura (she/her) < zfigura@codeweavers.com> wrote:
On 12/28/21 12:24, Saulius Krasuckas wrote:
On 2021-12-28 18:22, Alexandre Julliard wrote:
Saulius Krasuckas saulius2@ar-fi.lt writes:
By looking at the disassembled calling points of the function and its' epilogues [1] _and_ by avoiding to memorize what does core of the function do (particularly which other WinAPI functions does it call), you stay safe and in compliance with copyrights and other stuff of Intellectual Property law.
No, you should never look at a disassembly of a Windows dll, period.
Please read https://wiki.winehq.org/Clean_Room_Guidelines for details.
Alexandre, I have read it before my answer and I found it to be contradicting other documentation page. So I had to interpret this contradiction.
Do you and other folks agree that part of the documentation is misleading or even incorrect in that regard?
It doesn't seem clear to me whether that page advises disassembling the function or its caller, but since it's ambiguous (and not particularly helpful) I've just removed the entire section.
Whoops, I was simultaneously thinking of "in every respect" and "in all aspects" and mangled them together haha. I meant to say "Zebediah's method is superior in all aspects".
On Wed, Dec 29, 2021 at 7:41 PM Mohamad Al-Jaf mohamadaljaf@gmail.com wrote:
Interesting discussion, but it looks like Zebediah's method is superior in all respects.
I can confirm that CurrentIP takes 0 arguments. I also tested her method with other, documented functions, that I know the argument counts of and it works perfectly.
On Tue, Dec 28, 2021 at 1:31 PM Zebediah Figura (she/her) < zfigura@codeweavers.com> wrote:
On 12/28/21 12:24, Saulius Krasuckas wrote:
On 2021-12-28 18:22, Alexandre Julliard wrote:
Saulius Krasuckas saulius2@ar-fi.lt writes:
By looking at the disassembled calling points of the function and its' epilogues [1] _and_ by avoiding to memorize what does core of the function do (particularly which other WinAPI functions does it call), you stay safe and in compliance with copyrights and other stuff of Intellectual Property law.
No, you should never look at a disassembly of a Windows dll, period.
Please read https://wiki.winehq.org/Clean_Room_Guidelines for details.
Alexandre, I have read it before my answer and I found it to be contradicting other documentation page. So I had to interpret this contradiction.
Do you and other folks agree that part of the documentation is misleading or even incorrect in that regard?
It doesn't seem clear to me whether that page advises disassembling the function or its caller, but since it's ambiguous (and not particularly helpful) I've just removed the entire section.
On Tue, Dec 28, 2021 at 11:31 AM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
It doesn't seem clear to me whether that page advises disassembling the function or its caller, but since it's ambiguous (and not particularly helpful) I've just removed the entire section.
I've been meaning to look at this for a while and finally did it today. The first half of the original section (the half that explains the stdcall calling convention) was helpful to me, and what's even more helpful is the example code that you posted earlier in this thread. Consequently, I have restored the first half and added an example based on your code, as well as an explicit warning against disassembly:
https://wiki.winehq.org/Wine_Developer%27s_Guide/Other_Debugging_Techniques
Please let me know if you think that more changes are necessary.
-Alex
Hi Alex,
On Tue, Mar 29, 2022 at 3:00 AM Alex Henrie alexhenrie24@gmail.com wrote:
I've been meaning to look at this for a while and finally did it today. The first half of the original section (the half that explains the stdcall calling convention) was helpful to me, and what's even more helpful is the example code that you posted earlier in this thread. Consequently, I have restored the first half and added an example based on your code, as well as an explicit warning against disassembly:
https://wiki.winehq.org/Wine_Developer%27s_Guide/Other_Debugging_Techniques
Thanks for adding that section, it looks great.
Please let me know if you think that more changes are necessary.
I'd also add in Zebediah's suggestion if one cannot reasonably guess their type:
If you can't tell I'd recommend using "void *" or "DWORD_PTR" so that the entire value is captured.
-- Kind regards, Mohamad
On 12/27/21 23:50, Mohamad Al-Jaf wrote:
I see, but I still don't understand the method used here. How can you see the stack entries if you don't disassemble the file? The only way I know of is through WineDbg and that does not seem to be correct. The method on that wiki page appears to require looking at the assembly code. Specifically, it says "ret hhll (where hhll is the number of bytes to remove, i.e. the number of arguments times 4)". As far as I know, ret is assembly code. So the method listed requires disassembly, no?
The page is confusingly written, and I'm not sure whether it's telling the user to disassemble the function or its caller. Doing the latter is usually okay, provided you don't have some other reason to avoid it (e.g. it's also a Microsoft DLL).
Anyway, what I was proposing is something like the attached patch. Running it on the testbot yields an argument count of zero for CurrentIP() [1].