[10/10] netapi32: Add support for remote computers in NetServerGetInfo.
Hans Leidekker
hans at codeweavers.com
Tue Nov 12 03:04:51 CST 2013
---
configure.ac | 3 +
dlls/netapi32/netapi32.c | 184 +++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 172 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index 63435d2..d3f73d7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1756,6 +1756,9 @@ fi
dnl **** Check for libodbc ****
WINE_CHECK_SONAME(odbc,SQLConnect,,[AC_DEFINE_UNQUOTED(SONAME_LIBODBC,["libodbc.$LIBEXT"])])
+dnl **** Check for libnetapi ****
+WINE_CHECK_SONAME(netapi,libnetapi_init,,[AC_DEFINE_UNQUOTED(SONAME_LIBNETAPI,["libnetapi.$LIBEXT"])])
+
dnl **** Disable unsupported winmm drivers ****
test -n "$ALSALIBS" || enable_winealsa_drv=${enable_winealsa_drv:-no}
test -n "$COREAUDIO" || enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no}
diff --git a/dlls/netapi32/netapi32.c b/dlls/netapi32/netapi32.c
index 313d1ac..e09c6ce 100644
--- a/dlls/netapi32/netapi32.c
+++ b/dlls/netapi32/netapi32.c
@@ -3,6 +3,7 @@
* Copyright 2003 Juan Lang
* Copyright 2005,2006 Paul Vriens
* Copyright 2006 Robert Reif
+ * Copyright 2013 Hans Leidekker for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,6 +21,8 @@
*/
#include "config.h"
+#include "wine/port.h"
+
#include <stdarg.h>
#include <fcntl.h>
#include <errno.h>
@@ -49,11 +52,171 @@
#include "dsrole.h"
#include "dsgetdc.h"
#include "wine/debug.h"
+#include "wine/library.h"
#include "wine/list.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
+static char *strdup_unixcp( const WCHAR *str )
+{
+ char *ret;
+ int len = WideCharToMultiByte( CP_UNIXCP, 0, str, -1, NULL, 0, NULL, NULL );
+ if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
+ WideCharToMultiByte( CP_UNIXCP, 0, str, -1, ret, len, NULL, NULL );
+ return ret;
+}
+
+#ifdef SONAME_LIBNETAPI
+
+static void *libnetapi_handle;
+static void *libnetapi_ctx;
+
+static DWORD (*plibnetapi_init)(void **);
+static DWORD (*plibnetapi_free)(void *);
+static DWORD (*plibnetapi_set_debuglevel)(void *, const char *);
+
+static NET_API_STATUS (*pNetApiBufferAllocate)(unsigned int, void **);
+static NET_API_STATUS (*pNetApiBufferFree)(void *);
+static NET_API_STATUS (*pNetServerGetInfo)(const char *, unsigned int, unsigned char **);
+
+static BOOL libnetapi_init(void)
+{
+ char buf[200];
+ DWORD status;
+
+ if (libnetapi_handle) return TRUE;
+ if (!(libnetapi_handle = wine_dlopen( SONAME_LIBNETAPI, RTLD_NOW, buf, sizeof(buf) )))
+ {
+ WARN( "Failed to load libnetapi: %s\n", buf );
+ return FALSE;
+ }
+
+#define LOAD_FUNCPTR(f) \
+ if (!(p##f = wine_dlsym( libnetapi_handle, #f, buf, sizeof(buf) ))) \
+ { \
+ ERR( "Failed to load %s: %s\n", #f, buf ); \
+ goto error; \
+ }
+
+ LOAD_FUNCPTR(libnetapi_init)
+ LOAD_FUNCPTR(libnetapi_free)
+ LOAD_FUNCPTR(libnetapi_set_debuglevel)
+
+ LOAD_FUNCPTR(NetApiBufferAllocate)
+ LOAD_FUNCPTR(NetApiBufferFree)
+ LOAD_FUNCPTR(NetServerGetInfo)
+#undef LOAD_FUNCPTR
+
+ if ((status = plibnetapi_init( &libnetapi_ctx )))
+ {
+ ERR( "Failed to initialize context %u\n", status );
+ goto error;
+ }
+ if (TRACE_ON( netapi32 ) && (status = plibnetapi_set_debuglevel( libnetapi_ctx, "10" )))
+ {
+ ERR( "Failed to set debug level %u\n", status );
+ goto error;
+ }
+ return TRUE;
+
+error:
+ if (libnetapi_ctx)
+ {
+ plibnetapi_free( libnetapi_ctx );
+ libnetapi_ctx = NULL;
+ }
+ wine_dlclose( libnetapi_handle, NULL, 0 );
+ libnetapi_handle = NULL;
+ return FALSE;
+}
+
+struct server_info_101
+{
+ unsigned int sv101_platform_id;
+ const char *sv101_name;
+ unsigned int sv101_version_major;
+ unsigned int sv101_version_minor;
+ unsigned int sv101_type;
+ const char *sv101_comment;
+};
+
+static NET_API_STATUS server_info_101_from_samba( const unsigned char *buf, BYTE **bufptr )
+{
+ SERVER_INFO_101 *ret;
+ struct server_info_101 *info = (struct server_info_101 *)buf;
+ DWORD len = 0;
+ WCHAR *ptr;
+
+ if (info->sv101_name) len += MultiByteToWideChar( CP_UNIXCP, 0, info->sv101_name, -1, NULL, 0 );
+ if (info->sv101_comment) len += MultiByteToWideChar( CP_UNIXCP, 0, info->sv101_comment, -1, NULL, 0 );
+ if (!(ret = HeapAlloc( GetProcessHeap(), 0, sizeof(*ret) + (len * sizeof(WCHAR) ))))
+ return ERROR_OUTOFMEMORY;
+
+ ptr = (WCHAR *)(ret + 1);
+ ret->sv101_platform_id = info->sv101_platform_id;
+ if (!info->sv101_name) ret->sv101_name = NULL;
+ else
+ {
+ ret->sv101_name = ptr;
+ ptr += MultiByteToWideChar( CP_UNIXCP, 0, info->sv101_name, -1, ptr, len );
+ }
+ ret->sv101_version_major = info->sv101_version_major;
+ ret->sv101_version_minor = info->sv101_version_minor;
+ ret->sv101_type = info->sv101_type;
+ if (!info->sv101_comment) ret->sv101_comment = NULL;
+ else
+ {
+ ret->sv101_comment = ptr;
+ MultiByteToWideChar( CP_UNIXCP, 0, info->sv101_comment, -1, ptr, len );
+ }
+ *bufptr = (BYTE *)ret;
+ return NERR_Success;
+}
+
+static NET_API_STATUS server_info_from_samba( DWORD level, const unsigned char *buf, BYTE **bufptr )
+{
+ switch (level)
+ {
+ case 101: return server_info_101_from_samba( buf, bufptr );
+ default:
+ FIXME( "level %u not supported\n", level );
+ return ERROR_NOT_SUPPORTED;
+ }
+}
+
+static NET_API_STATUS server_getinfo( LMSTR servername, DWORD level, LPBYTE *bufptr )
+{
+ NET_API_STATUS status;
+ char *server = NULL;
+ unsigned char *buf = NULL;
+
+ if (servername && !(server = strdup_unixcp( servername ))) return ERROR_OUTOFMEMORY;
+ status = pNetServerGetInfo( server, level, &buf );
+ HeapFree( GetProcessHeap(), 0, server );
+ if (!status)
+ {
+ status = server_info_from_samba( level, buf, bufptr );
+ pNetApiBufferFree( buf );
+ }
+ return status;
+}
+
+#else
+
+static BOOL libnetapi_init(void)
+{
+ return FALSE;
+}
+
+static NET_API_STATUS server_getinfo( LMSTR servername, DWORD level, LPBYTE *bufptr )
+{
+ ERR( "\n" );
+ return ERROR_NOT_SUPPORTED;
+}
+
+#endif /* SONAME_LIBNETAPI */
+
/************************************************************
* NETAPI_IsLocalComputer
*
@@ -158,15 +321,15 @@ NET_API_STATUS WINAPI NetServerDiskEnum(
NET_API_STATUS WINAPI NetServerGetInfo(LMSTR servername, DWORD level, LPBYTE* bufptr)
{
NET_API_STATUS ret;
+ BOOL local = NETAPI_IsLocalComputer( servername );
TRACE("%s %d %p\n", debugstr_w( servername ), level, bufptr );
- if (servername)
+
+ if (!local)
{
- if (!NETAPI_IsLocalComputer(servername))
- {
- FIXME("remote computers not supported\n");
- return ERROR_INVALID_LEVEL;
- }
+ if (libnetapi_init()) return server_getinfo( servername, level, bufptr );
+ FIXME( "remote computers not supported\n" );
+ return ERROR_INVALID_LEVEL;
}
if (!bufptr) return ERROR_INVALID_PARAMETER;
@@ -1809,15 +1972,6 @@ NET_API_STATUS WINAPI NetUserModalsGet(
return NERR_Success;
}
-static char *strdup_unixcp( const WCHAR *str )
-{
- char *ret;
- int len = WideCharToMultiByte( CP_UNIXCP, 0, str, -1, NULL, 0, NULL, NULL );
- if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
- WideCharToMultiByte( CP_UNIXCP, 0, str, -1, ret, len, NULL, NULL );
- return ret;
-}
-
static NET_API_STATUS change_password_smb( LPCWSTR domainname, LPCWSTR username,
LPCWSTR oldpassword, LPCWSTR newpassword )
{
--
1.8.1.5
More information about the wine-patches
mailing list