help needed stdlib not linking

spaarder spaarder at hotmail.nl
Sat Sep 12 06:11:12 CDT 2020


Gabriel Ivăncescu schreef op wo 09-09-2020 om 18:30 [+0300]:
> On 09/09/2020 15:25, spaarder wrote:
> > Hello,
> > I want to contribute to the wonderful Wine project, so I decided to
> > start with a simple patch for the CreateSymbolicLinkW WINAP in
> > kernelbase.dll .
> > In my patch I use the system() function, which is in the stdlib
> > library. The linker cannot find this library because of the "-
> > nodefautlibs" in Makefile.in .When I remove -nodefaultlibs, all
> > compiles well, but now wineboot (and probably a _lot_ of other
> > things) are broken, even if I undo my patch.
> > Why does removing -nodefaultlibs from
> > wine/dlls/kernelbase/Makefile.in break so many things? Has it
> > anything to do with @ cdecl system(str) MSVCRT_system?
> > What would be the "proper" (wine) way to solve this?
> > Big thanks!
> > Hans.
> 
> Hi Hans,
> Unfortunately, CreateSymbolicLinkW is actually complicated. There are
> patches in wine-staging that implement it, so you can take a look
> there and see why that is so (because Windows also has junction
> points and so on). See the ntdll-Junction_Points patchset in wine-
> staging.
> Now for your question about -nodefaultlibs: the wine dlls that have
> this flag are compiled as native Windows .DLL PE files. That means
> they can't use system (unix) functions. kernelbase is one such
> example: most of the functions in kernelbase are done through ntdll.
> ntdll is also compiled as PE, but it has a unix library component (to
> be able to use unix libraries or communicate with the wine server).
> So in general, the procedure would be to:
> Implement symbolic links via some ntdll API.Have kernelbase use the
> ntdll API to implement it.
> You can see a 'unix' subdir in the ntdll, which is where the unix
> library is, and it's called through function pointers from the PE
> module (all files at the root of the dir).
> Again, the wine-staging patchset might help you in with clues. I'm
> not that familiar with the details myself, so I apologize if I said
> something wrong.
> Someone more knowledgeable might clarify it better, if they have the
> time.

Thank you for your answer Gabriel, it helped me a lot! I looked at the
patch in staging, and I noticed it is HUGE and COMPLICATED.I found a
much simpler solution, that is working fine (extensively tested):
================================================begin of
patch======================================diff -Naur
wine.orig/dlls/kernelbase/Makefile.in
wine.test3/dlls/kernelbase/Makefile.in---
wine.orig/dlls/kernelbase/Makefile.in	2020-09-06 19:22:23.817571221
+0000+++ wine.test3/dlls/kernelbase/Makefile.in	2020-09-11
12:37:20.173994185 +0000@@ -1,6 +1,6 @@ MODULE    =
kernelbase.dll IMPORTLIB = kernelbase-IMPORTS   = uuid ntdll
winecrt0+IMPORTS   = uuid ntdll winecrt0 kernel32 EXTRADLLFLAGS =
-nodefaultlibs -nostartfiles -mno-cygwin -Wl,--image-
base,0x7b000000  C_SRCS = \diff -Naur wine.orig/dlls/kernelbase/file.c
wine.test3/dlls/kernelbase/file.c--- wine.orig/dlls/kernelbase/file.c	
2020-09-06 19:22:23.817571221 +0000+++
wine.test3/dlls/kernelbase/file.c	2020-09-12 10:38:41.844739386
+0000@@ -920,16 +920,61 @@     return ret; } -+extern int system2(char
*
cmd); /****************************************************************
*********  *	CreateSymbolicLinkW   (kernelbase.@)  */ BOOLEAN WINAPI
/* DECLSPEC_HOTPATCH */ CreateSymbolicLinkW( LPCWSTR link, LPCWSTR
target, DWORD flags ) {-    FIXME( "(%s %s %d): stub\n",
debugstr_w(link), debugstr_w(target), flags );-    return TRUE;-
}+    if (flags != 2) {+        //flags=0: target is a
file+        //flags=1: link target is a directory+        //flags=2:
allow creation of symbolic links when the process is not elevated.
Developer Mode must first be enabled on the machine before this option
will function.+        int ret = -2;+        char *link_unix =
NULL;+        char *target_unix = NULL;+        //works for macOS, BSD
and linux:+        static const char ln[] = "ln -s '";+        //max
path length in windows is 260 char, +7 for ln command, +        //+3
for quoted space between link and target, +1 for quote at
end+        char
cmd[531];+        link_unix=wine_get_unix_file_name(link);+        targ
et_unix=wine_get_unix_file_name(target);+        strcpy( cmd, ln
);+        strcat( cmd, target_unix );+        strcat( cmd, "'
'");+        strcat( cmd, link_unix );+        strcat( cmd,
"'");+        //FIXME( "(%s): DINGO\n", cmd);+        ret = system2(
cmd ); +        if (!link_unix)+            free(link_unix);+        if
(!target_unix)+            free(target_unix);++        switch(ret)
{+            //return code in WINDOWS: success = non-zero =
TRUE+            //return code of system: -1 = error in system call,
other codes are from exit code of called program: 0 = success, others
are errors+            case
0:+                //success+                return
TRUE;+            case -2:+                SetLastError(
ERROR_INSUFFICIENT_BUFFER );+                break;+            case
-1:+                SetLastError(ERROR_CALL_NOT_IMPLEMENTED);+         
       break;+            default:+                SetLastError(ERROR_I
NVALID_PARAMETER);+        }+    }+    else {+        FIXME( "(%s %s %s
%d): stub\n", "Developer mode not supported.", debugstr_w(link),
debugstr_w(target), flags );+        return TRUE;+    }+    return
FALSE;+}  /************************************************************
***********  *	DeleteFileA   (kernelbase.@)diff -Naur
wine.orig/dlls/ntdll/ntdll.spec wine.test3/dlls/ntdll/ntdll.spec---
wine.orig/dlls/ntdll/ntdll.spec	2020-09-06 19:22:23.977570502 +0000+++
wine.test3/dlls/ntdll/ntdll.spec	2020-09-11 12:37:20.177993944
+0000@@ -1554,6 +1554,7 @@ @ cdecl strstr(str str) @ cdecl strtol(str
ptr long) @ cdecl strtoul(str ptr long)+@ cdecl system2(str) @ varargs
swprintf(ptr wstr) NTDLL_swprintf @ varargs swprintf_s(ptr long wstr) @
cdecl tan(double)diff -Naur wine.orig/dlls/ntdll/path.c
wine.test3/dlls/ntdll/path.c--- wine.orig/dlls/ntdll/path.c	2020-
09-06 19:22:23.977570502 +0000+++ wine.test3/dlls/ntdll/path.c	2020-
09-11 12:37:20.177993944 +0000@@ -134,6 +134,13 @@     return
0; } +//int WINAPI system2(char* cmd)+int CDECL system2(char*
cmd)+{+    int ret = unix_funcs->system3(cmd);+    return
ret;+}+ /**************************************************************
************ 
*                 RtlDosPathNameToNtPathName_U_WithStatus    [NTDLL.@] 
*diff -Naur wine.orig/dlls/ntdll/unix/file.c
wine.test3/dlls/ntdll/unix/file.c--- wine.orig/dlls/ntdll/unix/file.c	
2020-09-06 19:22:23.989570448 +0000+++
wine.test3/dlls/ntdll/unix/file.c	2020-09-11 13:15:43.337430667
+0000@@ -3492,6 +3492,10 @@     show_dot_files = enable; } +int CDECL
system3( char * cmd )+{+    return system( cmd
);+}  /****************************************************************
**************  *              open_unix_filediff -Naur
wine.orig/dlls/ntdll/unix/loader.c wine.test3/dlls/ntdll/unix/loader.c-
-- wine.orig/dlls/ntdll/unix/loader.c	2020-09-06 19:22:23.993570430
+0000+++ wine.test3/dlls/ntdll/unix/loader.c	2020-09-11
12:37:10.382585289 +0000@@ -1409,6 +1409,7
@@     get_locales,     virtual_release_address_space,     set_show_dot
_files,+    system3,     load_so_dll,     load_builtin_dll,     unload_
builtin_dll,diff -Naur wine.orig/dlls/ntdll/unix/unix_private.h
wine.test3/dlls/ntdll/unix/unix_private.h---
wine.orig/dlls/ntdll/unix/unix_private.h	2020-09-06
19:22:23.993570430 +0000+++ wine.test3/dlls/ntdll/unix/unix_private.h	
2020-09-11 12:37:20.177993944 +0000@@ -109,6 +109,7 @@ extern void
CDECL get_initial_directory( UNICODE_STRING *dir )
DECLSPEC_HIDDEN; extern void CDECL get_initial_console( HANDLE *handle,
HANDLE *std_in, HANDLE *std_out, HANDLE *std_err )
DECLSPEC_HIDDEN; extern USHORT * CDECL get_unix_codepage_data(void)
DECLSPEC_HIDDEN;+extern int CDECL system3(char *cmd)
DECLSPEC_HIDDEN; extern void CDECL get_locales( WCHAR *sys, WCHAR *user
) DECLSPEC_HIDDEN; extern void CDECL
virtual_release_address_space(void) DECLSPEC_HIDDEN; diff -Naur
wine.orig/dlls/ntdll/unixlib.h wine.test3/dlls/ntdll/unixlib.h---
wine.orig/dlls/ntdll/unixlib.h	2020-09-06 19:22:23.993570430 +0000+++
wine.test3/dlls/ntdll/unixlib.h	2020-09-11 12:37:20.177993944 +0000@@
-27,7 +27,7 @@ struct _DISPATCHER_CONTEXT;  /* increment this when you
change the function table */-#define NTDLL_UNIXLIB_VERSION 104+#define
NTDLL_UNIXLIB_VERSION 105  struct unix_funcs {@@ -83,6 +83,7 @@      /*
file functions */     void          (CDECL *set_show_dot_files)( BOOL
enable );+    int           (CDECL *system3)(char *cmd);      /* loader
functions */     NTSTATUS      (CDECL *load_so_dll)( UNICODE_STRING
*nt_name, void **module );
================================================end of
patch======================================
I realise this is not upto the goal of "translating winapi calls to
posix calls", but this way I could keep my code much more compact
and much more readable than the CreateSymbolicLinkW patch that is in
wine-staging; I copied the use of the "system" userland call from the
umount routines, so it is not a new thing to the wine code.
Please give me your comments and guidelines on if and how this patch
could make it into the master branch.
Thank you!
Hans.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20200912/72430cf8/attachment-0001.htm>


More information about the wine-devel mailing list