netapi32: Convert the Unix library to the __wine_unix_call interface.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-08-12 16:16:36 +02:00
parent fe6c25167f
commit 5d869cad7a
4 changed files with 122 additions and 159 deletions

View File

@ -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

View File

@ -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, &params );
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, &params );
}
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, &params );
}
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, &params );
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, &params ))
return NERR_Success;
if(domainname)

View File

@ -26,6 +26,8 @@
#include "config.h"
#include "wine/port.h"
#ifdef SONAME_LIBNETAPI
#include <stdarg.h>
#include <fcntl.h>
#include <errno.h>
@ -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 */

View File

@ -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,
};