diff --git a/dlls/netapi32/Makefile.in b/dlls/netapi32/Makefile.in index 702cda0c036..e8aba50731e 100644 --- a/dlls/netapi32/Makefile.in +++ b/dlls/netapi32/Makefile.in @@ -2,6 +2,7 @@ EXTRADEFS = -D_SVRAPI_ MODULE = netapi32.dll IMPORTLIB = netapi32 IMPORTS = rpcrt4 iphlpapi ws2_32 advapi32 dnsapi +EXTRALIBS = -Wl,--subsystem,unixlib EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/netapi32/netapi32.c b/dlls/netapi32/netapi32.c index 1efdab61be1..b66b37933e9 100644 --- a/dlls/netapi32/netapi32.c +++ b/dlls/netapi32/netapi32.c @@ -55,21 +55,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(netapi32); DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); -static HINSTANCE netapi32_instance; +static unixlib_handle_t samba_handle; + +#define SAMBA_CALL(func, args) __wine_unix_call( samba_handle, unix_ ## func, args ) static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; -static const struct samba_funcs *samba_funcs; - static BOOL WINAPI load_samba( INIT_ONCE *once, void *param, void **context ) { - __wine_init_unix_lib( netapi32_instance, DLL_PROCESS_ATTACH, NULL, &samba_funcs ); + SAMBA_CALL( netapi_init, NULL ); return TRUE; } static BOOL samba_init(void) { - return InitOnceExecuteOnce( &init_once, load_samba, NULL, NULL ) && samba_funcs; + return samba_handle && InitOnceExecuteOnce( &init_once, load_samba, NULL, NULL ); } /************************************************************ @@ -96,7 +96,8 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { case DLL_PROCESS_ATTACH: - netapi32_instance = hinstDLL; + NtQueryVirtualMemory( GetCurrentProcess(), hinstDLL, MemoryWineUnixFuncs, + &samba_handle, sizeof(samba_handle), NULL ); DisableThreadLibraryCalls(hinstDLL); NetBIOSInit(); NetBTInit(); @@ -186,12 +187,14 @@ NET_API_STATUS WINAPI NetServerGetInfo(LMSTR servername, DWORD level, LPBYTE* bu if (samba_init()) { ULONG size = 1024; + struct server_getinfo_params params = { servername, level, NULL, &size }; for (;;) { - if (!(*bufptr = malloc( size ))) return ERROR_OUTOFMEMORY; - ret = samba_funcs->server_getinfo( servername, level, *bufptr, &size ); - if (ret) free( *bufptr ); + if (!(params.buffer = malloc( size ))) return ERROR_OUTOFMEMORY; + ret = SAMBA_CALL( server_getinfo, ¶ms ); + if (!ret) *bufptr = params.buffer; + else free( params.buffer ); if (ret != ERROR_INSUFFICIENT_BUFFER) return ret; } } @@ -488,7 +491,11 @@ NET_API_STATUS WINAPI NetShareDel(LMSTR servername, LMSTR netname, DWORD reserve if (!local) { - if (samba_init()) return samba_funcs->share_del( servername, netname, reserved ); + if (samba_init()) + { + struct share_del_params params = { servername, netname, reserved }; + return SAMBA_CALL( share_del, ¶ms ); + } FIXME( "remote computers not supported\n" ); } @@ -519,7 +526,11 @@ NET_API_STATUS WINAPI NetShareAdd(LMSTR servername, if (!local) { - if (samba_init()) return samba_funcs->share_add( servername, level, buf, parm_err ); + if (samba_init()) + { + struct share_add_params params = { servername, level, buf, parm_err }; + return SAMBA_CALL( share_add, ¶ms ); + } FIXME( "remote computers not supported\n" ); } @@ -978,12 +989,14 @@ NET_API_STATUS WINAPI NetWkstaGetInfo( LMSTR servername, DWORD level, if (samba_init()) { ULONG size = 1024; + struct wksta_getinfo_params params = { servername, level, NULL, &size }; for (;;) { - if (!(*bufptr = malloc( size ))) return ERROR_OUTOFMEMORY; - ret = samba_funcs->wksta_getinfo( servername, level, *bufptr, &size ); - if (ret) free( *bufptr ); + if (!(params.buffer = malloc( size ))) return ERROR_OUTOFMEMORY; + ret = SAMBA_CALL( wksta_getinfo, ¶ms ); + if (!ret) *bufptr = params.buffer; + else free( params.buffer ); if (ret != ERROR_INSUFFICIENT_BUFFER) return ret; } } @@ -2054,12 +2067,11 @@ NET_API_STATUS WINAPI NetUserChangePassword(LPCWSTR domainname, LPCWSTR username LPCWSTR oldpassword, LPCWSTR newpassword) { struct sam_user *user; + struct change_password_params params = { domainname, username, oldpassword, newpassword }; TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username)); - if (!samba_init()) return ERROR_DLL_INIT_FAILED; - - if (!samba_funcs->change_password( domainname, username, oldpassword, newpassword )) + if (samba_init() && !SAMBA_CALL( change_password, ¶ms )) return NERR_Success; if(domainname) diff --git a/dlls/netapi32/unixlib.c b/dlls/netapi32/unixlib.c index cb2d0fc183f..565327ba4b1 100644 --- a/dlls/netapi32/unixlib.c +++ b/dlls/netapi32/unixlib.c @@ -26,6 +26,8 @@ #include "config.h" #include "wine/port.h" +#ifdef SONAME_LIBNETAPI + #include #include #include @@ -46,8 +48,6 @@ #include "unixlib.h" -#ifdef SONAME_LIBNETAPI - WINE_DEFAULT_DEBUG_CHANNEL(netapi32); WINE_DECLARE_DEBUG_CHANNEL(winediag); @@ -67,72 +67,16 @@ static NET_API_STATUS (*pNetShareAdd)( const char *, unsigned int, unsigned char static NET_API_STATUS (*pNetShareDel)( const char *, const char *, unsigned int ); static NET_API_STATUS (*pNetWkstaGetInfo)( const char *, unsigned int, unsigned char ** ); -static CPTABLEINFO unix_cptable; -static ULONG unix_cp = CP_UTF8; - -static DWORD WINAPI get_unix_codepage_once( RTL_RUN_ONCE *once, void *param, void **context ) -{ - static const WCHAR wineunixcpW[] = {'W','I','N','E','U','N','I','X','C','P',0}; - UNICODE_STRING name, value; - WCHAR value_buffer[13]; - SIZE_T size; - void *ptr; - - RtlInitUnicodeString( &name, wineunixcpW ); - value.Buffer = value_buffer; - value.MaximumLength = sizeof(value_buffer); - if (!RtlQueryEnvironmentVariable_U( NULL, &name, &value )) - RtlUnicodeStringToInteger( &value, 10, &unix_cp ); - if (unix_cp != CP_UTF8 && !NtGetNlsSectionPtr( 11, unix_cp, NULL, &ptr, &size )) - RtlInitCodePageTable( ptr, &unix_cptable ); - return TRUE; -} - -static BOOL get_unix_codepage( void ) -{ - static RTL_RUN_ONCE once = RTL_RUN_ONCE_INIT; - - return !RtlRunOnceExecuteOnce( &once, get_unix_codepage_once, NULL, NULL ); -} - static DWORD netapi_wcstoumbs( const WCHAR *src, char *dst, DWORD dstlen ) { - DWORD srclen = (strlenW( src ) + 1) * sizeof(WCHAR); - DWORD len; - - get_unix_codepage(); - - if (unix_cp == CP_UTF8) - { - RtlUnicodeToUTF8N( dst, dstlen, &len, src, srclen ); - return len; - } - else - { - len = (strlenW( src ) * 2) + 1; - if (dst) RtlUnicodeToCustomCPN( &unix_cptable, dst, dstlen, &len, src, srclen ); - return len; - } + if (!dst) return 3 * strlenW( src ) + 1; + return ntdll_wcstoumbs( src, strlenW( src ) + 1, dst, dstlen, FALSE ); } static DWORD netapi_umbstowcs( const char *src, WCHAR *dst, DWORD dstlen ) { - DWORD srclen = strlen( src ) + 1; - DWORD len; - - get_unix_codepage(); - - if (unix_cp == CP_UTF8) - { - RtlUTF8ToUnicodeN( dst, dstlen, &len, src, srclen ); - return len; - } - else - { - len = srclen * sizeof(WCHAR); - if (dst) RtlCustomCPToUnicodeN( &unix_cptable, dst, dstlen, &len, src, srclen ); - return len; - } + if (!dst) return (strlen( src ) + 1) * sizeof(WCHAR); + return ntdll_umbstowcs( src, strlen( src ) + 1, dst, dstlen ); } static char *strdup_unixcp( const WCHAR *str ) @@ -202,20 +146,21 @@ static NET_API_STATUS server_info_from_samba( DWORD level, const unsigned char * } } -static NET_API_STATUS WINAPI server_getinfo( const WCHAR *server, DWORD level, void *buffer, ULONG *size ) +static NTSTATUS server_getinfo( void *args ) { + struct server_getinfo_params *params = args; NET_API_STATUS status; char *samba_server = NULL; unsigned char *samba_buffer = NULL; if (!libnetapi_ctx) return ERROR_NOT_SUPPORTED; - if (server && !(samba_server = strdup_unixcp( server ))) return ERROR_OUTOFMEMORY; - status = pNetServerGetInfo( samba_server, level, &samba_buffer ); + if (params->server && !(samba_server = strdup_unixcp( params->server ))) return ERROR_OUTOFMEMORY; + status = pNetServerGetInfo( samba_server, params->level, &samba_buffer ); free( samba_server ); if (!status) { - status = server_info_from_samba( level, samba_buffer, buffer, size ); + status = server_info_from_samba( params->level, samba_buffer, params->buffer, params->size ); pNetApiBufferFree( samba_buffer ); } return status; @@ -762,42 +707,44 @@ static NET_API_STATUS share_info_to_samba( DWORD level, const BYTE *buf, unsigne } } -static NET_API_STATUS WINAPI share_add( const WCHAR *server, DWORD level, const BYTE *info, DWORD *err ) +static NTSTATUS share_add( void *args ) { + struct share_add_params *params = args; char *samba_server = NULL; unsigned char *samba_info; NET_API_STATUS status; if (!libnetapi_ctx) return ERROR_NOT_SUPPORTED; - if (server && !(samba_server = strdup_unixcp( server ))) return ERROR_OUTOFMEMORY; - status = share_info_to_samba( level, info, &samba_info ); + if (params->server && !(samba_server = strdup_unixcp( params->server ))) return ERROR_OUTOFMEMORY; + status = share_info_to_samba( params->level, params->info, &samba_info ); if (!status) { unsigned int samba_err; - status = pNetShareAdd( samba_server, level, samba_info, &samba_err ); + status = pNetShareAdd( samba_server, params->level, samba_info, &samba_err ); free( samba_info ); - if (err) *err = samba_err; + if (params->err) *params->err = samba_err; } free( samba_server ); return status; } -static NET_API_STATUS WINAPI share_del( const WCHAR *server, const WCHAR *share, DWORD reserved ) +static NTSTATUS share_del( void *args ) { + struct share_del_params *params = args; char *samba_server = NULL, *samba_share; NET_API_STATUS status; if (!libnetapi_ctx) return ERROR_NOT_SUPPORTED; - if (server && !(samba_server = strdup_unixcp( server ))) return ERROR_OUTOFMEMORY; - if (!(samba_share = strdup_unixcp( share ))) + if (params->server && !(samba_server = strdup_unixcp( params->server ))) return ERROR_OUTOFMEMORY; + if (!(samba_share = strdup_unixcp( params->share ))) { free( samba_server ); return ERROR_OUTOFMEMORY; } - status = pNetShareDel( samba_server, samba_share, reserved ); + status = pNetShareDel( samba_server, samba_share, params->reserved ); free( samba_server ); free( samba_share ); return status; @@ -860,26 +807,27 @@ static NET_API_STATUS wksta_info_from_samba( DWORD level, const unsigned char *b } } -static NET_API_STATUS WINAPI wksta_getinfo( const WCHAR *server, DWORD level, void *buffer, ULONG *size ) +static NTSTATUS wksta_getinfo( void *args ) { + struct wksta_getinfo_params *params = args; unsigned char *samba_buffer = NULL; char *samba_server = NULL; NET_API_STATUS status; if (!libnetapi_ctx) return ERROR_NOT_SUPPORTED; - if (server && !(samba_server = strdup_unixcp( server ))) return ERROR_OUTOFMEMORY; - status = pNetWkstaGetInfo( samba_server, level, &samba_buffer ); + if (params->server && !(samba_server = strdup_unixcp( params->server ))) return ERROR_OUTOFMEMORY; + status = pNetWkstaGetInfo( samba_server, params->level, &samba_buffer ); free( samba_server ); if (!status) { - status = wksta_info_from_samba( level, samba_buffer, buffer, size ); + status = wksta_info_from_samba( params->level, samba_buffer, params->buffer, params->size ); pNetApiBufferFree( samba_buffer ); } return status; } -static void libnetapi_init(void) +static NTSTATUS netapi_init( void *args ) { DWORD status; void *ctx; @@ -887,14 +835,14 @@ static void libnetapi_init(void) if (!(libnetapi_handle = dlopen( SONAME_LIBNETAPI, RTLD_NOW ))) { ERR_(winediag)( "failed to load %s\n", SONAME_LIBNETAPI ); - return; + return STATUS_DLL_NOT_FOUND; } #define LOAD_FUNCPTR(f) \ if (!(p##f = dlsym( libnetapi_handle, #f ))) \ { \ ERR_(winediag)( "%s not found in %s\n", #f, SONAME_LIBNETAPI ); \ - return; \ + return STATUS_DLL_NOT_FOUND; \ } LOAD_FUNCPTR(libnetapi_init) @@ -914,34 +862,35 @@ static void libnetapi_init(void) if ((status = plibnetapi_init( &ctx ))) { ERR( "Failed to initialize context, status %u\n", status ); - return; + return STATUS_DLL_NOT_FOUND; } if (TRACE_ON(netapi32) && (status = plibnetapi_set_debuglevel( ctx, "10" ))) { ERR( "Failed to set debug level, status %u\n", status ); plibnetapi_free( ctx ); - return; + return STATUS_DLL_NOT_FOUND; } /* perform an anonymous login by default (avoids a password prompt) */ if ((status = plibnetapi_set_username( ctx, "Guest" ))) { ERR( "Failed to set username, status %u\n", status ); plibnetapi_free( ctx ); - return; + return STATUS_DLL_NOT_FOUND; } if ((status = plibnetapi_set_password( ctx, "" ))) { ERR( "Failed to set password, status %u\n", status ); plibnetapi_free( ctx ); - return; + return STATUS_DLL_NOT_FOUND; } libnetapi_ctx = ctx; + return STATUS_SUCCESS; } -static NET_API_STATUS WINAPI change_password( const WCHAR *domainname, const WCHAR *username, - const WCHAR *oldpassword, const WCHAR *newpassword ) +static NTSTATUS change_password( void *args ) { + struct change_password_params *params = args; NET_API_STATUS ret = NERR_Success; static char option_silent[] = "-s"; static char option_user[] = "-U"; @@ -952,18 +901,18 @@ static NET_API_STATUS WINAPI change_password( const WCHAR *domainname, const WCH int status; char *server = NULL, *user, *argv[7], *old = NULL, *new = NULL; - if (domainname && !(server = strdup_unixcp( domainname ))) return ERROR_OUTOFMEMORY; - if (!(user = strdup_unixcp( username ))) + if (params->domain && !(server = strdup_unixcp( params->domain ))) return ERROR_OUTOFMEMORY; + if (!(user = strdup_unixcp( params->user ))) { ret = ERROR_OUTOFMEMORY; goto end; } - if (!(old = strdup_unixcp( oldpassword ))) + if (!(old = strdup_unixcp( params->old ))) { ret = ERROR_OUTOFMEMORY; goto end; } - if (!(new = strdup_unixcp( newpassword ))) + if (!(new = strdup_unixcp( params->new ))) { ret = ERROR_OUTOFMEMORY; goto end; @@ -1029,42 +978,9 @@ end: return ret; } -#else - -static NET_API_STATUS WINAPI server_getinfo( const WCHAR *server, DWORD level, BYTE **buffer ) -{ - return ERROR_NOT_SUPPORTED; -} - -static NET_API_STATUS WINAPI share_add( const WCHAR *server, DWORD level, const BYTE *info, DWORD *err ) -{ - return ERROR_NOT_SUPPORTED; -} - -static NET_API_STATUS WINAPI share_del( const WCHAR *server, const WCHAR *share, DWORD reserved ) -{ - return ERROR_NOT_SUPPORTED; -} - -static NET_API_STATUS WINAPI wksta_getinfo( const WCHAR *server, DWORD level, BYTE **buffer ) -{ - return ERROR_NOT_SUPPORTED; -} - -static NET_API_STATUS WINAPI change_password( const WCHAR *domainname, const WCHAR *username, - const WCHAR *oldpassword, const WCHAR *newpassword ) -{ - return ERROR_NOT_SUPPORTED; -} - -static void libnetapi_init(void) -{ -} - -#endif /* SONAME_LIBNETAPI */ - -static const struct samba_funcs samba_funcs = +const unixlib_entry_t __wine_unix_call_funcs[] = { + netapi_init, server_getinfo, share_add, share_del, @@ -1072,11 +988,4 @@ static const struct samba_funcs samba_funcs = change_password, }; -NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) -{ - if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS; - - libnetapi_init(); - *(const struct samba_funcs **)ptr_out = &samba_funcs; - return STATUS_SUCCESS; -} +#endif /* SONAME_LIBNETAPI */ diff --git a/dlls/netapi32/unixlib.h b/dlls/netapi32/unixlib.h index 2bcd7131939..1184d2ee385 100644 --- a/dlls/netapi32/unixlib.h +++ b/dlls/netapi32/unixlib.h @@ -18,12 +18,53 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -struct samba_funcs +#include "wine/unixlib.h" + +struct server_getinfo_params { - NET_API_STATUS (WINAPI *server_getinfo)( const WCHAR *server, DWORD level, void *buffer, ULONG *size ); - NET_API_STATUS (WINAPI *share_add)( const WCHAR *server, DWORD level, const BYTE *buffer, DWORD *err ); - NET_API_STATUS (WINAPI *share_del)( const WCHAR *server, const WCHAR *share, DWORD reserved ); - NET_API_STATUS (WINAPI *wksta_getinfo)( const WCHAR *server, DWORD level, void *buffer, ULONG *size ); - NET_API_STATUS (WINAPI *change_password)( const WCHAR *domain, const WCHAR *user, - const WCHAR *old, const WCHAR *new ); + const WCHAR *server; + DWORD level; + void *buffer; + ULONG *size; +}; + +struct share_add_params +{ + const WCHAR *server; + DWORD level; + const BYTE *info; + DWORD *err; +}; + +struct share_del_params +{ + const WCHAR *server; + const WCHAR *share; + DWORD reserved; +}; + +struct wksta_getinfo_params +{ + const WCHAR *server; + DWORD level; + void *buffer; + ULONG *size; +}; + +struct change_password_params +{ + const WCHAR *domain; + const WCHAR *user; + const WCHAR *old; + const WCHAR *new; +}; + +enum samba_funcs +{ + unix_netapi_init, + unix_server_getinfo, + unix_share_add, + unix_share_del, + unix_wksta_getinfo, + unix_change_password, };