mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
Port of netapi32 from WINE
svn path=/trunk/; revision=8131
This commit is contained in:
parent
aebff275f5
commit
f80022635e
20 changed files with 5983 additions and 0 deletions
1101
reactos/include/wine/ntstatus.h
Normal file
1101
reactos/include/wine/ntstatus.h
Normal file
File diff suppressed because it is too large
Load diff
6
reactos/lib/netapi32/.cvsignore
Normal file
6
reactos/lib/netapi32/.cvsignore
Normal file
|
@ -0,0 +1,6 @@
|
|||
Makefile
|
||||
netapi32.def
|
||||
netapi32.dll
|
||||
netapi32.dll.dbg.c
|
||||
netapi32.spec.c
|
||||
netapi32.spec.def
|
24
reactos/lib/netapi32/Makefile.in
Normal file
24
reactos/lib/netapi32/Makefile.in
Normal file
|
@ -0,0 +1,24 @@
|
|||
EXTRADEFS = -D_SVRAPI_
|
||||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = netapi32.dll
|
||||
IMPORTS = iphlpapi ws2_32 advapi32 kernel32
|
||||
|
||||
C_SRCS = \
|
||||
access.c \
|
||||
apibuf.c \
|
||||
browsr.c \
|
||||
nbcmdqueue.c \
|
||||
nbnamecache.c \
|
||||
nbt.c \
|
||||
netapi32.c \
|
||||
netbios.c \
|
||||
wksta.c
|
||||
|
||||
SUBDIRS = tests
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
### Dependencies:
|
21
reactos/lib/netapi32/Makefile.ros-template
Normal file
21
reactos/lib/netapi32/Makefile.ros-template
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: Makefile.ros-template,v 1.1 2004/02/10 16:57:23 sedwards Exp $
|
||||
|
||||
TARGET_NAME = netapi32
|
||||
|
||||
TARGET_OBJECTS = @C_SRCS@
|
||||
|
||||
TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
|
||||
|
||||
TARGET_SDKLIBS = @IMPORTS@ libwine.a ntdll.a
|
||||
|
||||
TARGET_BASE = 0x76160000
|
||||
|
||||
TARGET_RC_SRCS = @RC_SRCS@
|
||||
TARGET_RC_BINSRC = @RC_BINSRC@
|
||||
TARGET_RC_BINARIES = @RC_BINARIES@
|
||||
|
||||
default: all
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
528
reactos/lib/netapi32/access.c
Normal file
528
reactos/lib/netapi32/access.c
Normal file
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
* Copyright 2002 Andriy Palamarchuk
|
||||
*
|
||||
* netapi32 access functions
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "lmcons.h"
|
||||
#include "lmaccess.h"
|
||||
#include "lmapibuf.h"
|
||||
#include "lmerr.h"
|
||||
#include "netapi32_misc.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||
|
||||
const WCHAR sAdminUserName[] = {'A','d','m','i','n','i','s','t','r','a','t',
|
||||
'o','r',0};
|
||||
const WCHAR sGuestUserName[] = {'G','u','e','s','t',0};
|
||||
|
||||
/************************************************************
|
||||
* NETAPI_ValidateServername
|
||||
*
|
||||
* Validates server name
|
||||
*/
|
||||
NET_API_STATUS NETAPI_ValidateServername(LPCWSTR ServerName)
|
||||
{
|
||||
if (ServerName)
|
||||
{
|
||||
if (ServerName[0] == 0)
|
||||
return ERROR_BAD_NETPATH;
|
||||
else if (
|
||||
((ServerName[0] == '\\') &&
|
||||
(ServerName[1] != '\\'))
|
||||
||
|
||||
((ServerName[0] == '\\') &&
|
||||
(ServerName[1] == '\\') &&
|
||||
(ServerName[2] == 0))
|
||||
)
|
||||
return ERROR_INVALID_NAME;
|
||||
}
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NETAPI_IsKnownUser
|
||||
*
|
||||
* Checks whether the user name indicates current user.
|
||||
*/
|
||||
BOOL NETAPI_IsKnownUser(LPCWSTR UserName)
|
||||
{
|
||||
DWORD dwSize = UNLEN + 1;
|
||||
BOOL Result;
|
||||
LPWSTR buf;
|
||||
|
||||
if (!lstrcmpW(UserName, sAdminUserName) ||
|
||||
!lstrcmpW(UserName, sGuestUserName))
|
||||
return TRUE;
|
||||
NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &buf);
|
||||
Result = GetUserNameW(buf, &dwSize);
|
||||
|
||||
Result = Result && !lstrcmpW(UserName, buf);
|
||||
NetApiBufferFree(buf);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
#define NETAPI_ForceKnownUser(UserName, FailureCode) \
|
||||
if (!NETAPI_IsKnownUser(UserName)) \
|
||||
{ \
|
||||
FIXME("Can't find information for user %s\n", \
|
||||
debugstr_w(UserName)); \
|
||||
return FailureCode; \
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetUserGetInfo (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI
|
||||
NetUserGetInfo(LPCWSTR servername, LPCWSTR username, DWORD level,
|
||||
LPBYTE* bufptr)
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
TRACE("(%s, %s, %ld, %p)\n", debugstr_w(servername), debugstr_w(username),
|
||||
level, bufptr);
|
||||
status = NETAPI_ValidateServername(servername);
|
||||
if (status != NERR_Success)
|
||||
return status;
|
||||
NETAPI_ForceLocalComputer(servername, NERR_InvalidComputer);
|
||||
NETAPI_ForceKnownUser(username, NERR_UserNotFound);
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
PUSER_INFO_0 ui;
|
||||
int name_sz;
|
||||
|
||||
name_sz = lstrlenW(username) + 1;
|
||||
|
||||
/* set up buffer */
|
||||
NetApiBufferAllocate(sizeof(USER_INFO_0) + name_sz * sizeof(WCHAR),
|
||||
(LPVOID *) bufptr);
|
||||
|
||||
ui = (PUSER_INFO_0) *bufptr;
|
||||
ui->usri0_name = (LPWSTR) (*bufptr + sizeof(USER_INFO_0));
|
||||
|
||||
/* get data */
|
||||
lstrcpyW(ui->usri0_name, username);
|
||||
break;
|
||||
}
|
||||
|
||||
case 10:
|
||||
{
|
||||
PUSER_INFO_10 ui;
|
||||
PUSER_INFO_0 ui0;
|
||||
NET_API_STATUS status;
|
||||
/* sizes of the field buffers in WCHARS */
|
||||
int name_sz, comment_sz, usr_comment_sz, full_name_sz;
|
||||
|
||||
comment_sz = 1;
|
||||
usr_comment_sz = 1;
|
||||
full_name_sz = 1;
|
||||
|
||||
/* get data */
|
||||
status = NetUserGetInfo(servername, username, 0, (LPBYTE *) &ui0);
|
||||
if (status != NERR_Success)
|
||||
{
|
||||
NetApiBufferFree(ui0);
|
||||
return status;
|
||||
}
|
||||
name_sz = lstrlenW(ui0->usri0_name) + 1;
|
||||
|
||||
/* set up buffer */
|
||||
NetApiBufferAllocate(sizeof(USER_INFO_10) +
|
||||
(name_sz + comment_sz + usr_comment_sz +
|
||||
full_name_sz) * sizeof(WCHAR),
|
||||
(LPVOID *) bufptr);
|
||||
ui = (PUSER_INFO_10) *bufptr;
|
||||
ui->usri10_name = (LPWSTR) (*bufptr + sizeof(USER_INFO_10));
|
||||
ui->usri10_comment = (LPWSTR) (
|
||||
((PBYTE) ui->usri10_name) + name_sz * sizeof(WCHAR));
|
||||
ui->usri10_usr_comment = (LPWSTR) (
|
||||
((PBYTE) ui->usri10_comment) + comment_sz * sizeof(WCHAR));
|
||||
ui->usri10_full_name = (LPWSTR) (
|
||||
((PBYTE) ui->usri10_usr_comment) + usr_comment_sz * sizeof(WCHAR));
|
||||
|
||||
/* set data */
|
||||
lstrcpyW(ui->usri10_name, ui0->usri0_name);
|
||||
NetApiBufferFree(ui0);
|
||||
ui->usri10_comment[0] = 0;
|
||||
ui->usri10_usr_comment[0] = 0;
|
||||
ui->usri10_full_name[0] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
static const WCHAR homedirW[] = {'H','O','M','E',0};
|
||||
PUSER_INFO_1 ui;
|
||||
PUSER_INFO_0 ui0;
|
||||
NET_API_STATUS status;
|
||||
/* sizes of the field buffers in WCHARS */
|
||||
int name_sz, password_sz, home_dir_sz, comment_sz, script_path_sz;
|
||||
|
||||
password_sz = 1; /* not filled out for security reasons for NetUserGetInfo*/
|
||||
comment_sz = 1;
|
||||
script_path_sz = 1;
|
||||
|
||||
/* get data */
|
||||
status = NetUserGetInfo(servername, username, 0, (LPBYTE *) &ui0);
|
||||
if (status != NERR_Success)
|
||||
{
|
||||
NetApiBufferFree(ui0);
|
||||
return status;
|
||||
}
|
||||
name_sz = lstrlenW(ui0->usri0_name) + 1;
|
||||
home_dir_sz = GetEnvironmentVariableW(homedirW, NULL,0);
|
||||
/* set up buffer */
|
||||
NetApiBufferAllocate(sizeof(USER_INFO_1) +
|
||||
(name_sz + password_sz + home_dir_sz +
|
||||
comment_sz + script_path_sz) * sizeof(WCHAR),
|
||||
(LPVOID *) bufptr);
|
||||
|
||||
ui = (PUSER_INFO_1) *bufptr;
|
||||
ui->usri1_name = (LPWSTR) (ui + 1);
|
||||
ui->usri1_password = ui->usri1_name + name_sz;
|
||||
ui->usri1_home_dir = ui->usri1_password + password_sz;
|
||||
ui->usri1_comment = ui->usri1_home_dir + home_dir_sz;
|
||||
ui->usri1_script_path = ui->usri1_comment + comment_sz;
|
||||
/* set data */
|
||||
lstrcpyW(ui->usri1_name, ui0->usri0_name);
|
||||
NetApiBufferFree(ui0);
|
||||
ui->usri1_password[0] = 0;
|
||||
ui->usri1_password_age = 0;
|
||||
ui->usri1_priv = 0;
|
||||
GetEnvironmentVariableW(homedirW, ui->usri1_home_dir,home_dir_sz);
|
||||
ui->usri1_comment[0] = 0;
|
||||
ui->usri1_flags = 0;
|
||||
ui->usri1_script_path[0] = 0;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 11:
|
||||
case 20:
|
||||
case 23:
|
||||
case 1003:
|
||||
case 1005:
|
||||
case 1006:
|
||||
case 1007:
|
||||
case 1008:
|
||||
case 1009:
|
||||
case 1010:
|
||||
case 1011:
|
||||
case 1012:
|
||||
case 1013:
|
||||
case 1014:
|
||||
case 1017:
|
||||
case 1018:
|
||||
case 1020:
|
||||
case 1023:
|
||||
case 1024:
|
||||
case 1025:
|
||||
case 1051:
|
||||
case 1052:
|
||||
case 1053:
|
||||
{
|
||||
FIXME("Level %ld is not implemented\n", level);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERR("Invalid level %ld is specified\n", level);
|
||||
return ERROR_INVALID_LEVEL;
|
||||
}
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************
|
||||
* NetUserEnum (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI
|
||||
NetUserEnum(LPCWSTR servername, DWORD level, DWORD filter, LPBYTE* bufptr,
|
||||
DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries,
|
||||
LPDWORD resume_handle)
|
||||
{
|
||||
FIXME("stub!\n");
|
||||
return ERROR_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* ACCESS_QueryAdminDisplayInformation
|
||||
*
|
||||
* Creates a buffer with information for the Admin User
|
||||
*/
|
||||
void ACCESS_QueryAdminDisplayInformation(PNET_DISPLAY_USER *buf, PDWORD pdwSize)
|
||||
{
|
||||
const WCHAR sAdminUserName[] = {
|
||||
'A','d','m','i','n','i','s','t','r','a','t','o','r',0};
|
||||
|
||||
/* sizes of the field buffers in WCHARS */
|
||||
int name_sz, comment_sz, full_name_sz;
|
||||
PNET_DISPLAY_USER usr;
|
||||
|
||||
/* set up buffer */
|
||||
name_sz = lstrlenW(sAdminUserName);
|
||||
comment_sz = 1;
|
||||
full_name_sz = 1;
|
||||
|
||||
*pdwSize = sizeof(NET_DISPLAY_USER);
|
||||
*pdwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
|
||||
NetApiBufferAllocate(*pdwSize, (LPVOID *) buf);
|
||||
|
||||
usr = *buf;
|
||||
usr->usri1_name = (LPWSTR) ((PBYTE) usr + sizeof(NET_DISPLAY_USER));
|
||||
usr->usri1_comment = (LPWSTR) (
|
||||
((PBYTE) usr->usri1_name) + name_sz * sizeof(WCHAR));
|
||||
usr->usri1_full_name = (LPWSTR) (
|
||||
((PBYTE) usr->usri1_comment) + comment_sz * sizeof(WCHAR));
|
||||
|
||||
/* set data */
|
||||
lstrcpyW(usr->usri1_name, sAdminUserName);
|
||||
usr->usri1_comment[0] = 0;
|
||||
usr->usri1_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD;
|
||||
usr->usri1_full_name[0] = 0;
|
||||
usr->usri1_user_id = 500;
|
||||
usr->usri1_next_index = 0;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* ACCESS_QueryGuestDisplayInformation
|
||||
*
|
||||
* Creates a buffer with information for the Guest User
|
||||
*/
|
||||
void ACCESS_QueryGuestDisplayInformation(PNET_DISPLAY_USER *buf, PDWORD pdwSize)
|
||||
{
|
||||
const WCHAR sGuestUserName[] = {
|
||||
'G','u','e','s','t',0 };
|
||||
|
||||
/* sizes of the field buffers in WCHARS */
|
||||
int name_sz, comment_sz, full_name_sz;
|
||||
PNET_DISPLAY_USER usr;
|
||||
|
||||
/* set up buffer */
|
||||
name_sz = lstrlenW(sGuestUserName);
|
||||
comment_sz = 1;
|
||||
full_name_sz = 1;
|
||||
|
||||
*pdwSize = sizeof(NET_DISPLAY_USER);
|
||||
*pdwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
|
||||
NetApiBufferAllocate(*pdwSize, (LPVOID *) buf);
|
||||
|
||||
usr = *buf;
|
||||
usr->usri1_name = (LPWSTR) ((PBYTE) usr + sizeof(NET_DISPLAY_USER));
|
||||
usr->usri1_comment = (LPWSTR) (
|
||||
((PBYTE) usr->usri1_name) + name_sz * sizeof(WCHAR));
|
||||
usr->usri1_full_name = (LPWSTR) (
|
||||
((PBYTE) usr->usri1_comment) + comment_sz * sizeof(WCHAR));
|
||||
|
||||
/* set data */
|
||||
lstrcpyW(usr->usri1_name, sGuestUserName);
|
||||
usr->usri1_comment[0] = 0;
|
||||
usr->usri1_flags = UF_ACCOUNTDISABLE | UF_SCRIPT | UF_NORMAL_ACCOUNT |
|
||||
UF_DONT_EXPIRE_PASSWD;
|
||||
usr->usri1_full_name[0] = 0;
|
||||
usr->usri1_user_id = 500;
|
||||
usr->usri1_next_index = 0;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetQueryDisplayInformation (NETAPI32.@)
|
||||
* Copies NET_DISPLAY_USER record.
|
||||
*/
|
||||
void ACCESS_CopyDisplayUser(PNET_DISPLAY_USER dest, LPWSTR *dest_buf,
|
||||
PNET_DISPLAY_USER src)
|
||||
{
|
||||
LPWSTR str = *dest_buf;
|
||||
|
||||
src->usri1_name = str;
|
||||
lstrcpyW(src->usri1_name, dest->usri1_name);
|
||||
str = (LPWSTR) (
|
||||
((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
|
||||
|
||||
src->usri1_comment = str;
|
||||
lstrcpyW(src->usri1_comment, dest->usri1_comment);
|
||||
str = (LPWSTR) (
|
||||
((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
|
||||
|
||||
src->usri1_flags = dest->usri1_flags;
|
||||
|
||||
src->usri1_full_name = str;
|
||||
lstrcpyW(src->usri1_full_name, dest->usri1_full_name);
|
||||
str = (LPWSTR) (
|
||||
((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
|
||||
|
||||
src->usri1_user_id = dest->usri1_user_id;
|
||||
src->usri1_next_index = dest->usri1_next_index;
|
||||
*dest_buf = str;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetQueryDisplayInformation (NETAPI32.@)
|
||||
*
|
||||
* The buffer structure:
|
||||
* - array of fixed size record of the level type
|
||||
* - strings, referenced by the record of the level type
|
||||
*/
|
||||
NET_API_STATUS WINAPI
|
||||
NetQueryDisplayInformation(
|
||||
LPCWSTR ServerName, DWORD Level, DWORD Index, DWORD EntriesRequested,
|
||||
DWORD PreferredMaximumLength, PDWORD ReturnedEntryCount,
|
||||
PVOID *SortedBuffer)
|
||||
{
|
||||
TRACE("(%s, %ld, %ld, %ld, %ld, %p, %p)\n", debugstr_w(ServerName),
|
||||
Level, Index, EntriesRequested, PreferredMaximumLength,
|
||||
ReturnedEntryCount, SortedBuffer);
|
||||
NETAPI_ForceLocalComputer(ServerName, ERROR_ACCESS_DENIED);
|
||||
switch (Level)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
/* current record */
|
||||
PNET_DISPLAY_USER inf;
|
||||
/* current available strings buffer */
|
||||
LPWSTR str;
|
||||
PNET_DISPLAY_USER admin, guest;
|
||||
DWORD admin_size, guest_size;
|
||||
LPWSTR name = NULL;
|
||||
DWORD dwSize;
|
||||
|
||||
/* sizes of the field buffers in WCHARS */
|
||||
int name_sz, comment_sz, full_name_sz;
|
||||
|
||||
/* number of the records, returned in SortedBuffer
|
||||
3 - for current user, Administrator and Guest users
|
||||
*/
|
||||
int records = 3;
|
||||
|
||||
FIXME("Level %ld partially implemented\n", Level);
|
||||
*ReturnedEntryCount = records;
|
||||
comment_sz = 1;
|
||||
full_name_sz = 1;
|
||||
|
||||
/* get data */
|
||||
dwSize = UNLEN + 1;
|
||||
NetApiBufferAllocate(dwSize, (LPVOID *) &name);
|
||||
if (!GetUserNameW(name, &dwSize))
|
||||
{
|
||||
NetApiBufferFree(name);
|
||||
return ERROR_ACCESS_DENIED;
|
||||
}
|
||||
name_sz = dwSize;
|
||||
ACCESS_QueryAdminDisplayInformation(&admin, &admin_size);
|
||||
ACCESS_QueryGuestDisplayInformation(&guest, &guest_size);
|
||||
|
||||
/* set up buffer */
|
||||
dwSize = sizeof(NET_DISPLAY_USER) * records;
|
||||
dwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
|
||||
|
||||
NetApiBufferAllocate(dwSize +
|
||||
admin_size - sizeof(NET_DISPLAY_USER) +
|
||||
guest_size - sizeof(NET_DISPLAY_USER),
|
||||
(LPVOID *) SortedBuffer);
|
||||
inf = (PNET_DISPLAY_USER) *SortedBuffer;
|
||||
str = (LPWSTR) ((PBYTE) inf + sizeof(NET_DISPLAY_USER) * records);
|
||||
inf->usri1_name = str;
|
||||
str = (LPWSTR) (
|
||||
((PBYTE) str) + name_sz * sizeof(WCHAR));
|
||||
inf->usri1_comment = str;
|
||||
str = (LPWSTR) (
|
||||
((PBYTE) str) + comment_sz * sizeof(WCHAR));
|
||||
inf->usri1_full_name = str;
|
||||
str = (LPWSTR) (
|
||||
((PBYTE) str) + full_name_sz * sizeof(WCHAR));
|
||||
|
||||
/* set data */
|
||||
lstrcpyW(inf->usri1_name, name);
|
||||
NetApiBufferFree(name);
|
||||
inf->usri1_comment[0] = 0;
|
||||
inf->usri1_flags =
|
||||
UF_SCRIPT | UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD;
|
||||
inf->usri1_full_name[0] = 0;
|
||||
inf->usri1_user_id = 0;
|
||||
inf->usri1_next_index = 0;
|
||||
|
||||
inf++;
|
||||
ACCESS_CopyDisplayUser(admin, &str, inf);
|
||||
NetApiBufferFree(admin);
|
||||
|
||||
inf++;
|
||||
ACCESS_CopyDisplayUser(guest, &str, inf);
|
||||
NetApiBufferFree(guest);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
{
|
||||
FIXME("Level %ld is not implemented\n", Level);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ERR("Invalid level %ld is specified\n", Level);
|
||||
return ERROR_INVALID_LEVEL;
|
||||
}
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetGetDCName (NETAPI32.@)
|
||||
*
|
||||
* Return the name of the primary domain controller (PDC)
|
||||
*/
|
||||
|
||||
NET_API_STATUS WINAPI
|
||||
NetGetDCName(LPCWSTR servername, LPCWSTR domainname, LPBYTE *bufptr)
|
||||
{
|
||||
FIXME("stub!\n");
|
||||
return NERR_DCNotFound; /* say we can't find a domain controller */
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
* NetUserModalsGet (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetUserModalsGet(LPCWSTR szServer, DWORD level, LPBYTE *pbuffer)
|
||||
{
|
||||
FIXME("%s %ld %p\n", debugstr_w( szServer ), level, pbuffer );
|
||||
return NERR_InternalError;
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI NetLocalGroupAdd( LPCWSTR servername, DWORD level,
|
||||
LPBYTE buf, LPDWORD parm_err)
|
||||
{
|
||||
FIXME("%s %ld %p %p\n", debugstr_w( servername ), level, buf, parm_err);
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI NetLocalGroupSetMembers( LPCWSTR servername,
|
||||
LPCWSTR groupname, DWORD level, LPBYTE buf, DWORD totalentries)
|
||||
{
|
||||
FIXME("%s %s %ld %p %ld\n", debugstr_w(servername), debugstr_w(groupname),
|
||||
level, buf, totalentries);
|
||||
return NERR_Success;
|
||||
}
|
102
reactos/lib/netapi32/apibuf.c
Normal file
102
reactos/lib/netapi32/apibuf.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright 2002 Andriy Palamarchuk
|
||||
*
|
||||
* Net API buffer calls
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "lmcons.h"
|
||||
#include "lmapibuf.h"
|
||||
#include "lmerr.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||
|
||||
extern inline DWORD WINAPI GetLastError(void);
|
||||
extern inline DWORD WINAPI GetLastError(void)
|
||||
{
|
||||
DWORD ret;
|
||||
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x34,%0" : "=r" (ret) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetApiBufferAllocate (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetApiBufferAllocate(DWORD ByteCount, LPVOID* Buffer)
|
||||
{
|
||||
TRACE("(%ld, %p)\n", ByteCount, Buffer);
|
||||
*Buffer = HeapAlloc(GetProcessHeap(), 0, ByteCount);
|
||||
if (*Buffer)
|
||||
return NERR_Success;
|
||||
else
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetApiBufferFree (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetApiBufferFree(LPVOID Buffer)
|
||||
{
|
||||
TRACE("(%p)\n", Buffer);
|
||||
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetApiBufferReallocate (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetApiBufferReallocate(LPVOID OldBuffer, DWORD NewByteCount,
|
||||
LPVOID* NewBuffer)
|
||||
{
|
||||
TRACE("(%p, %ld, %p)\n", OldBuffer, NewByteCount, NewBuffer);
|
||||
if (NewByteCount)
|
||||
{
|
||||
*NewBuffer = HeapReAlloc(GetProcessHeap(), 0, OldBuffer, NewByteCount);
|
||||
return *NewBuffer ? NERR_Success : GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!HeapFree(GetProcessHeap(), 0, OldBuffer)) return GetLastError();
|
||||
*NewBuffer = 0;
|
||||
return NERR_Success;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetApiBufferSize (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetApiBufferSize(LPVOID Buffer, LPDWORD ByteCount)
|
||||
{
|
||||
DWORD dw;
|
||||
|
||||
TRACE("(%p, %p)\n", Buffer, ByteCount);
|
||||
if (Buffer == NULL)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
dw = HeapSize(GetProcessHeap(), 0, Buffer);
|
||||
TRACE("size: %ld\n", dw);
|
||||
if (dw != 0xFFFFFFFF)
|
||||
*ByteCount = dw;
|
||||
else
|
||||
*ByteCount = 0;
|
||||
|
||||
return NERR_Success;
|
||||
}
|
62
reactos/lib/netapi32/browsr.c
Normal file
62
reactos/lib/netapi32/browsr.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 2002 Andriy Palamarchuk
|
||||
*
|
||||
* netapi32 browser functions
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "lmcons.h"
|
||||
#include "lmbrowsr.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||
|
||||
/************************************************************
|
||||
* I_BrowserSetNetlogonState (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS I_BrowserSetNetlogonState(
|
||||
LPWSTR ServerName, LPWSTR DomainName, LPWSTR EmulatedServerName,
|
||||
DWORD Role)
|
||||
{
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* I_BrowserQueryEmulatedDomains (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS I_BrowserQueryEmulatedDomains(LPWSTR ServerName,PBYTE* blah,PDWORD EntriesRead)
|
||||
//NET_API_STATUS I_BrowserQueryEmulatedDomains(
|
||||
// LPWSTR ServerName, PBYTE *EmulatedDomains
|
||||
// PDWORD EntriesRead)
|
||||
{
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetShareEnum (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetShareEnum( LPWSTR servername, DWORD level, LPBYTE* bufptr,
|
||||
DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, LPDWORD resume_handle)
|
||||
{
|
||||
FIXME("%s %ld %p %ld %p %p %p\n", debugstr_w(servername), level, bufptr,
|
||||
prefmaxlen, entriesread, totalentries, resume_handle);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
199
reactos/lib/netapi32/nbcmdqueue.c
Normal file
199
reactos/lib/netapi32/nbcmdqueue.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/* Copyright (c) 2003 Juan Lang
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "wine/debug.h"
|
||||
#include "nbcmdqueue.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netbios);
|
||||
|
||||
struct NBCmdQueue
|
||||
{
|
||||
HANDLE heap;
|
||||
CRITICAL_SECTION cs;
|
||||
PNCB head;
|
||||
};
|
||||
|
||||
#define CANCEL_EVENT_PTR(ncb) (PHANDLE)((ncb)->ncb_reserve)
|
||||
#define NEXT_PTR(ncb) (PNCB *)((ncb)->ncb_reserve + sizeof(HANDLE))
|
||||
|
||||
/* The reserved area of an ncb will be used for the following data:
|
||||
* - a cancelled flag (BOOL, 4 bytes??)
|
||||
* - a handle to an event that's set by a cancelled command on completion
|
||||
* (HANDLE, 4 bytes)
|
||||
* These members are used in the following way
|
||||
* - on cancel, set the event member of the reserved field (with create event)
|
||||
* - NBCmdComplete will delete the ncb from the queue of there's no event;
|
||||
* otherwise it will set the event and not delete the ncb
|
||||
* - cancel must lock the queue before finding the ncb in it, and can unlock it
|
||||
* once it's set the event (and the cancelled flag)
|
||||
* - NBCmdComplete must lock the queue before attempting to remove the ncb or
|
||||
* check the event
|
||||
* - NBCmdQueueCancelAll will lock the queue, and cancel all ncb's in the queue.
|
||||
* It'll then unlock the queue, and wait on the event in the head of the queue
|
||||
* until there's no more ncb's in the queue.
|
||||
* Space optimization: use the handle as a boolean. NULL == 0 => not cancelled.
|
||||
* Non-NULL == valid handle => cancelled. This allows storing a next pointer
|
||||
* in the ncb's reserved field as well, avoiding a memory alloc for a new
|
||||
* command (cool).
|
||||
*/
|
||||
|
||||
struct NBCmdQueue *NBCmdQueueCreate(HANDLE heap)
|
||||
{
|
||||
struct NBCmdQueue *queue;
|
||||
|
||||
if (heap == NULL)
|
||||
heap = GetProcessHeap();
|
||||
queue = (struct NBCmdQueue *)HeapAlloc(heap, 0, sizeof(struct NBCmdQueue));
|
||||
if (queue)
|
||||
{
|
||||
queue->heap = heap;
|
||||
InitializeCriticalSection(&queue->cs);
|
||||
queue->head = NULL;
|
||||
}
|
||||
return queue;
|
||||
}
|
||||
|
||||
UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
|
||||
TRACE(": queue %p, ncb %p\n", queue, ncb);
|
||||
|
||||
if (!queue)
|
||||
return NRC_BADDR;
|
||||
if (!ncb)
|
||||
return NRC_INVADDRESS;
|
||||
|
||||
*CANCEL_EVENT_PTR(ncb) = NULL;
|
||||
EnterCriticalSection(&queue->cs);
|
||||
*NEXT_PTR(ncb) = queue->head;
|
||||
queue->head = ncb;
|
||||
ret = NRC_GOODRET;
|
||||
LeaveCriticalSection(&queue->cs);
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PNCB *NBCmdQueueFindNBC(struct NBCmdQueue *queue, PNCB ncb)
|
||||
{
|
||||
PNCB *ret;
|
||||
|
||||
if (!queue || !ncb)
|
||||
ret = NULL;
|
||||
else
|
||||
{
|
||||
ret = &queue->head;
|
||||
while (ret && *ret != ncb)
|
||||
ret = NEXT_PTR(*ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
UCHAR NBCmdQueueCancel(struct NBCmdQueue *queue, PNCB ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
PNCB *spot;
|
||||
|
||||
TRACE(": queue %p, ncb %p\n", queue, ncb);
|
||||
|
||||
if (!queue)
|
||||
return NRC_BADDR;
|
||||
if (!ncb)
|
||||
return NRC_INVADDRESS;
|
||||
|
||||
EnterCriticalSection(&queue->cs);
|
||||
spot = NBCmdQueueFindNBC(queue, ncb);
|
||||
if (spot)
|
||||
{
|
||||
*CANCEL_EVENT_PTR(*spot) = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
WaitForSingleObject(*CANCEL_EVENT_PTR(*spot), INFINITE);
|
||||
CloseHandle(*CANCEL_EVENT_PTR(*spot));
|
||||
*spot = *NEXT_PTR(*spot);
|
||||
if (ncb->ncb_retcode == NRC_CMDCAN)
|
||||
ret = NRC_CMDCAN;
|
||||
else
|
||||
ret = NRC_CANOCCR;
|
||||
}
|
||||
else
|
||||
ret = NRC_INVADDRESS;
|
||||
LeaveCriticalSection(&queue->cs);
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
UCHAR NBCmdQueueComplete(struct NBCmdQueue *queue, PNCB ncb, UCHAR retcode)
|
||||
{
|
||||
UCHAR ret;
|
||||
PNCB *spot;
|
||||
|
||||
TRACE(": queue %p, ncb %p\n", queue, ncb);
|
||||
|
||||
if (!queue)
|
||||
return NRC_BADDR;
|
||||
if (!ncb)
|
||||
return NRC_INVADDRESS;
|
||||
|
||||
EnterCriticalSection(&queue->cs);
|
||||
spot = NBCmdQueueFindNBC(queue, ncb);
|
||||
if (spot)
|
||||
{
|
||||
if (*CANCEL_EVENT_PTR(*spot))
|
||||
SetEvent(*CANCEL_EVENT_PTR(*spot));
|
||||
else
|
||||
*spot = *NEXT_PTR(*spot);
|
||||
ret = NRC_GOODRET;
|
||||
}
|
||||
else
|
||||
ret = NRC_INVADDRESS;
|
||||
LeaveCriticalSection(&queue->cs);
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
UCHAR NBCmdQueueCancelAll(struct NBCmdQueue *queue)
|
||||
{
|
||||
UCHAR ret;
|
||||
|
||||
TRACE(": queue %p\n", queue);
|
||||
|
||||
if (!queue)
|
||||
return NRC_BADDR;
|
||||
|
||||
EnterCriticalSection(&queue->cs);
|
||||
while (queue->head)
|
||||
{
|
||||
TRACE(": waiting for ncb %p (command 0x%02x)\n", queue->head,
|
||||
queue->head->ncb_command);
|
||||
NBCmdQueueCancel(queue, queue->head);
|
||||
}
|
||||
LeaveCriticalSection(&queue->cs);
|
||||
ret = NRC_GOODRET;
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NBCmdQueueDestroy(struct NBCmdQueue *queue)
|
||||
{
|
||||
TRACE(": queue %p\n", queue);
|
||||
|
||||
if (queue)
|
||||
{
|
||||
NBCmdQueueCancelAll(queue);
|
||||
DeleteCriticalSection(&queue->cs);
|
||||
HeapFree(queue->heap, 0, queue);
|
||||
}
|
||||
}
|
66
reactos/lib/netapi32/nbcmdqueue.h
Normal file
66
reactos/lib/netapi32/nbcmdqueue.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* Copyright (c) 2003 Juan Lang
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __NBCMDQUEUE_H__
|
||||
#define __NBCMDQUEUE_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "nb30.h"
|
||||
|
||||
/* This file defines a queue of pending NetBIOS commands. The queue operations
|
||||
* are thread safe, with the exception of NBCmdQueueDestroy: ensure no other
|
||||
* threads are manipulating the queue when calling NBCmdQueueDestroy.
|
||||
*/
|
||||
|
||||
struct NBCmdQueue;
|
||||
|
||||
/* Allocates a new command queue from heap. */
|
||||
struct NBCmdQueue *NBCmdQueueCreate(HANDLE heap);
|
||||
|
||||
/* Adds ncb to queue. Assumes queue is not NULL, and ncb is not already in the
|
||||
* queue. If ncb is already in the queue, returns NRC_TOOMANY.
|
||||
*/
|
||||
UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb);
|
||||
|
||||
/* Cancels the given ncb. Blocks until the command completes. Implicitly
|
||||
* removes ncb from the queue. Assumes queue and ncb are not NULL, and that
|
||||
* ncb has been added to queue previously.
|
||||
* Returns NRC_CMDCAN on a successful cancellation, NRC_CMDOCCR if the command
|
||||
* completed before it could be cancelled, and various other return values for
|
||||
* different failures.
|
||||
*/
|
||||
UCHAR NBCmdQueueCancel(struct NBCmdQueue *queue, PNCB ncb);
|
||||
|
||||
/* Sets the return code of the given ncb, and implicitly removes the command
|
||||
* from the queue. Assumes queue and ncb are not NULL, and that ncb has been
|
||||
* added to queue previously.
|
||||
* Returns NRC_GOODRET on success.
|
||||
*/
|
||||
UCHAR NBCmdQueueComplete(struct NBCmdQueue *queue, PNCB ncb, UCHAR retcode);
|
||||
|
||||
/* Cancels all pending commands in the queue (useful for a RESET or a shutdown).
|
||||
* Returns when all commands have been completed.
|
||||
*/
|
||||
UCHAR NBCmdQueueCancelAll(struct NBCmdQueue *queue);
|
||||
|
||||
/* Frees all memory associated with the queue. Blocks until all commands
|
||||
* pending in the queue have been completed.
|
||||
*/
|
||||
void NBCmdQueueDestroy(struct NBCmdQueue *queue);
|
||||
|
||||
#endif /* __NBCMDQUEUE_H__ */
|
218
reactos/lib/netapi32/nbnamecache.c
Normal file
218
reactos/lib/netapi32/nbnamecache.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
/* Copyright (c) 2003 Juan Lang
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* This implementation uses a linked list, because I don't have a decent
|
||||
* hash table implementation handy. This is somewhat inefficient, but it's
|
||||
* rather more efficient than not having a name cache at all.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "nbnamecache.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netbios);
|
||||
|
||||
typedef struct _NBNameCacheNode
|
||||
{
|
||||
DWORD expireTime;
|
||||
NBNameCacheEntry *entry;
|
||||
struct _NBNameCacheNode *next;
|
||||
} NBNameCacheNode;
|
||||
|
||||
struct NBNameCache
|
||||
{
|
||||
HANDLE heap;
|
||||
CRITICAL_SECTION cs;
|
||||
DWORD entryExpireTimeMS;
|
||||
NBNameCacheNode *head;
|
||||
};
|
||||
|
||||
/* Unlinks the node pointed to by *prev, and frees any associated memory.
|
||||
* If that node's next pointed to another node, *prev now points to it.
|
||||
* Assumes the caller owns cache's lock.
|
||||
*/
|
||||
static void NBNameCacheUnlinkNode(struct NBNameCache *cache,
|
||||
NBNameCacheNode **prev)
|
||||
{
|
||||
if (cache && prev && *prev)
|
||||
{
|
||||
NBNameCacheNode *next = (*prev)->next;
|
||||
|
||||
if ((*prev)->entry)
|
||||
HeapFree(cache->heap, 0, (*prev)->entry);
|
||||
HeapFree(cache->heap, 0, *prev);
|
||||
*prev = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Walks the list beginning with cache->head looking for the node with name
|
||||
* name. If the node is found, returns a pointer to the next pointer of the
|
||||
* node _prior_ to the found node (or head if head points to it). Thus, if the
|
||||
* node's all you want, dereference the return value twice. If you want to
|
||||
* modify the list, modify the referent of the return value.
|
||||
* While it's at it, deletes nodes whose time has expired (except the node
|
||||
* you're looking for, of course).
|
||||
* Returns NULL if the node isn't found.
|
||||
* Assumes the caller owns cache's lock.
|
||||
*/
|
||||
static NBNameCacheNode **NBNameCacheWalk(struct NBNameCache *cache,
|
||||
const char name[NCBNAMSZ])
|
||||
{
|
||||
NBNameCacheNode **ret = NULL;
|
||||
|
||||
if (cache && cache->head)
|
||||
{
|
||||
NBNameCacheNode **ptr;
|
||||
|
||||
ptr = &cache->head;
|
||||
while (ptr && *ptr && (*ptr)->entry)
|
||||
{
|
||||
if (!memcmp((*ptr)->entry->name, name, NCBNAMSZ - 1))
|
||||
ret = ptr;
|
||||
else
|
||||
{
|
||||
if (GetTickCount() > (*ptr)->expireTime)
|
||||
NBNameCacheUnlinkNode(cache, ptr);
|
||||
}
|
||||
if (*ptr)
|
||||
ptr = &(*ptr)->next;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS)
|
||||
{
|
||||
struct NBNameCache *cache;
|
||||
|
||||
|
||||
if (!heap)
|
||||
heap = GetProcessHeap();
|
||||
cache = (struct NBNameCache *)HeapAlloc(heap, 0,
|
||||
sizeof(struct NBNameCache));
|
||||
if (cache)
|
||||
{
|
||||
cache->heap = heap;
|
||||
InitializeCriticalSection(&cache->cs);
|
||||
cache->entryExpireTimeMS = entryExpireTimeMS;
|
||||
cache->head = NULL;
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
BOOL NBNameCacheAddEntry(struct NBNameCache *cache, NBNameCacheEntry *entry)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (cache && entry)
|
||||
{
|
||||
NBNameCacheNode **node;
|
||||
|
||||
EnterCriticalSection(&cache->cs);
|
||||
node = NBNameCacheWalk(cache, entry->name);
|
||||
if (node)
|
||||
{
|
||||
(*node)->expireTime = GetTickCount() +
|
||||
cache->entryExpireTimeMS;
|
||||
HeapFree(cache->heap, 0, (*node)->entry);
|
||||
(*node)->entry = entry;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
NBNameCacheNode *newNode = (NBNameCacheNode *)HeapAlloc(
|
||||
cache->heap, 0, sizeof(NBNameCacheNode));
|
||||
if (newNode)
|
||||
{
|
||||
newNode->expireTime = GetTickCount() +
|
||||
cache->entryExpireTimeMS;
|
||||
newNode->entry = entry;
|
||||
newNode->next = cache->head;
|
||||
cache->head = newNode;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
LeaveCriticalSection(&cache->cs);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const NBNameCacheEntry *NBNameCacheFindEntry(struct NBNameCache *cache,
|
||||
const UCHAR name[NCBNAMSZ])
|
||||
{
|
||||
const NBNameCacheEntry *ret;
|
||||
UCHAR printName[NCBNAMSZ];
|
||||
|
||||
memcpy(printName, name, NCBNAMSZ - 1);
|
||||
printName[NCBNAMSZ - 1] = '\0';
|
||||
if (cache)
|
||||
{
|
||||
NBNameCacheNode **node;
|
||||
|
||||
EnterCriticalSection(&cache->cs);
|
||||
node = NBNameCacheWalk(cache, name);
|
||||
if (node)
|
||||
ret = (*node)->entry;
|
||||
else
|
||||
ret = NULL;
|
||||
LeaveCriticalSection(&cache->cs);
|
||||
}
|
||||
else
|
||||
ret = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL NBNameCacheUpdateNBName(struct NBNameCache *cache,
|
||||
const UCHAR name[NCBNAMSZ], const UCHAR nbname[NCBNAMSZ])
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (cache)
|
||||
{
|
||||
NBNameCacheNode **node;
|
||||
|
||||
EnterCriticalSection(&cache->cs);
|
||||
node = NBNameCacheWalk(cache, name);
|
||||
if (node && *node && (*node)->entry)
|
||||
{
|
||||
memcpy((*node)->entry->nbname, nbname, NCBNAMSZ);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
LeaveCriticalSection(&cache->cs);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NBNameCacheDestroy(struct NBNameCache *cache)
|
||||
{
|
||||
if (cache)
|
||||
{
|
||||
DeleteCriticalSection(&cache->cs);
|
||||
while (cache->head)
|
||||
NBNameCacheUnlinkNode(cache, &cache->head);
|
||||
HeapFree(cache->heap, 0, cache);
|
||||
}
|
||||
}
|
82
reactos/lib/netapi32/nbnamecache.h
Normal file
82
reactos/lib/netapi32/nbnamecache.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* Copyright (c) 2003 Juan Lang
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __WINE_NBNAMECACHE_H
|
||||
#define __WINE_NBNAMECACHE_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "nb30.h"
|
||||
|
||||
struct NBNameCache;
|
||||
|
||||
/* Represents an entry in the name cache. If the NetBIOS name is known, it's
|
||||
* in nbname. Otherwise, nbname begins with '*'. numAddresses defines the
|
||||
* number of addresses in addresses.
|
||||
* Notice that it allows multiple addresses per name, but doesn't explicitly
|
||||
* allow group names. That's because all names so far are unique; if a use for
|
||||
* group names comes up, adding a flag here is simple enough.
|
||||
* Also, only the first NCBNAMSZ - 1 bytes are considered significant. This is
|
||||
* because a name may have been resolved using DNS, and the suffix byte is
|
||||
* always truncated for DNS lookups.
|
||||
*/
|
||||
typedef struct _NBNameCacheEntry
|
||||
{
|
||||
UCHAR name[NCBNAMSZ];
|
||||
UCHAR nbname[NCBNAMSZ];
|
||||
DWORD numAddresses;
|
||||
DWORD addresses[1];
|
||||
} NBNameCacheEntry;
|
||||
|
||||
/* Functions that create, manipulate, and destroy a name cache. Thread-safe,
|
||||
* with the exception of NBNameCacheDestroy--ensure that no other threads are
|
||||
* manipulating the cache before destoying it.
|
||||
*/
|
||||
|
||||
/* Allocates a new name cache from heap, and sets the expire time on new
|
||||
* entries to entryExpireTimeMS after a cache entry is added.
|
||||
*/
|
||||
struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS);
|
||||
|
||||
/* Adds an entry to the cache. The entry is assumed to have been allocated
|
||||
* from the same heap as the name cache; the name cache will own the entry
|
||||
* from now on. The entry's expire time is initialized at this time to
|
||||
* entryExpireTimeMS + the current time in MS. If an existing entry with the
|
||||
* same name was in the cache, the entry is replaced. Returns TRUE on success
|
||||
* or FALSE on failure.
|
||||
*/
|
||||
BOOL NBNameCacheAddEntry(struct NBNameCache *cache, NBNameCacheEntry *entry);
|
||||
|
||||
/* Finds the entry with name name in the cache and returns a pointer to it, or
|
||||
* NULL if it isn't found.
|
||||
*/
|
||||
const NBNameCacheEntry *NBNameCacheFindEntry(struct NBNameCache *cache,
|
||||
const UCHAR name[NCBNAMSZ]);
|
||||
|
||||
/* If the entry with name name is in the cache, updates its nbname member to
|
||||
* nbname. The entry's expire time is implicitly updated to entryExpireTimeMS
|
||||
* + the current time in MS, since getting the NetBIOS name meant validating
|
||||
* the name and address anyway.
|
||||
* Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
BOOL NBNameCacheUpdateNBName(struct NBNameCache *cache,
|
||||
const UCHAR name[NCBNAMSZ], const UCHAR nbname[NCBNAMSZ]);
|
||||
|
||||
void NBNameCacheDestroy(struct NBNameCache *cache);
|
||||
|
||||
#endif /* ndef __WINE_NBNAMECACHE_H */
|
1535
reactos/lib/netapi32/nbt.c
Normal file
1535
reactos/lib/netapi32/nbt.c
Normal file
File diff suppressed because it is too large
Load diff
79
reactos/lib/netapi32/netapi32.c
Normal file
79
reactos/lib/netapi32/netapi32.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* Copyright 2001 Mike McCormack
|
||||
* Copyright 2003 Juan Lang
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "netbios.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netbios);
|
||||
|
||||
HMODULE NETAPI32_hModule = 0;
|
||||
|
||||
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
|
||||
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
NETAPI32_hModule = hinstDLL;
|
||||
NetBIOSInit();
|
||||
NetBTInit();
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
NetBIOSShutdown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI NetServerEnum(
|
||||
LPCWSTR servername,
|
||||
DWORD level,
|
||||
LPBYTE* bufptr,
|
||||
DWORD prefmaxlen,
|
||||
LPDWORD entriesread,
|
||||
LPDWORD totalentries,
|
||||
DWORD servertype,
|
||||
LPCWSTR domain,
|
||||
LPDWORD resume_handle
|
||||
)
|
||||
{
|
||||
FIXME("Stub (%p, %ld %p %ld %p %p %ld %s %p)\n",servername, level, bufptr,
|
||||
prefmaxlen, entriesread, totalentries, servertype, debugstr_w(domain), resume_handle);
|
||||
|
||||
return ERROR_NO_BROWSER_SERVERS_FOUND;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
* NetStatisticsGet (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetStatisticsGet(LPWSTR server, LPWSTR service,
|
||||
DWORD level, DWORD options,
|
||||
PBYTE *bufptr)
|
||||
{
|
||||
TRACE("(%p, %p, %ld, %ld, %p)\n", server, service, level, options, bufptr);
|
||||
return NERR_InternalError;
|
||||
}
|
38
reactos/lib/netapi32/netapi32.rc
Normal file
38
reactos/lib/netapi32/netapi32.rc
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "WINE IMM32 API Client DLL\0"
|
||||
VALUE "FileVersion", RES_STR_FILE_VERSION
|
||||
VALUE "InternalName", "imm32\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "imm32.dll\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
274
reactos/lib/netapi32/netapi32.spec
Normal file
274
reactos/lib/netapi32/netapi32.spec
Normal file
|
@ -0,0 +1,274 @@
|
|||
@ stub I_BrowserDebugCall
|
||||
@ stub I_BrowserDebugTrace
|
||||
@ stdcall I_BrowserQueryEmulatedDomains(wstr ptr ptr)
|
||||
@ stub I_BrowserQueryOtherDomains
|
||||
@ stub I_BrowserQueryStatistics
|
||||
@ stub I_BrowserResetNetlogonState
|
||||
@ stub I_BrowserResetStatistics
|
||||
@ stub I_BrowserServerEnum
|
||||
@ stdcall I_BrowserSetNetlogonState(wstr wstr wstr long)
|
||||
@ stub I_NetAccountDeltas
|
||||
@ stub I_NetAccountSync
|
||||
@ stub I_NetDatabaseDeltas
|
||||
@ stub I_NetDatabaseRedo
|
||||
@ stub I_NetDatabaseSync
|
||||
@ stub I_NetDatabaseSync2
|
||||
@ stub I_NetDfsCreateExitPoint
|
||||
@ stub I_NetDfsCreateLocalPartition
|
||||
@ stub I_NetDfsDeleteExitPoint
|
||||
@ stub I_NetDfsDeleteLocalPartition
|
||||
@ stub I_NetDfsFixLocalVolume
|
||||
@ stub I_NetDfsGetVersion
|
||||
@ stub I_NetDfsIsThisADomainName
|
||||
@ stub I_NetDfsModifyPrefix
|
||||
@ stub I_NetDfsSetLocalVolumeState
|
||||
@ stub I_NetDfsSetServerInfo
|
||||
@ stub I_NetGetDCList
|
||||
@ stub I_NetListCanonicalize
|
||||
@ stub I_NetListTraverse
|
||||
@ stub I_NetLogonControl
|
||||
@ stub I_NetLogonControl2
|
||||
@ stub I_NetLogonSamLogoff
|
||||
@ stub I_NetLogonSamLogon
|
||||
@ stub I_NetLogonUasLogoff
|
||||
@ stub I_NetLogonUasLogon
|
||||
@ stub I_NetNameCanonicalize
|
||||
@ stub I_NetNameCompare
|
||||
@ stub I_NetNameValidate
|
||||
@ stub I_NetPathCanonicalize
|
||||
@ stub I_NetPathCompare
|
||||
@ stub I_NetPathType
|
||||
@ stub I_NetServerAuthenticate
|
||||
@ stub I_NetServerAuthenticate2
|
||||
@ stub I_NetServerPasswordSet
|
||||
@ stub I_NetServerReqChallenge
|
||||
@ stub I_NetServerSetServiceBits
|
||||
@ stub I_NetServerSetServiceBitsEx
|
||||
@ stub NetAlertRaise
|
||||
@ stub NetAlertRaiseEx
|
||||
@ stdcall NetApiBufferAllocate(long ptr)
|
||||
@ stdcall NetApiBufferFree(ptr)
|
||||
@ stdcall NetApiBufferReallocate(ptr long ptr)
|
||||
@ stdcall NetApiBufferSize(ptr ptr)
|
||||
@ stub NetAuditClear
|
||||
@ stub NetAuditRead
|
||||
@ stub NetAuditWrite
|
||||
@ stub NetBrowserStatisticsGet
|
||||
@ stub NetConfigGet
|
||||
@ stub NetConfigGetAll
|
||||
@ stub NetConfigSet
|
||||
@ stub NetConnectionEnum
|
||||
@ stub NetDfsAdd
|
||||
@ stub NetDfsEnum
|
||||
@ stub NetDfsGetInfo
|
||||
@ stub NetDfsManagerGetConfigInfo
|
||||
@ stub NetDfsMove
|
||||
@ stub NetDfsRemove
|
||||
@ stub NetDfsRename
|
||||
@ stub NetDfsSetInfo
|
||||
@ stub NetEnumerateTrustedDomains
|
||||
@ stub NetErrorLogClear
|
||||
@ stub NetErrorLogRead
|
||||
@ stub NetErrorLogWrite
|
||||
@ stub NetFileClose
|
||||
@ stub NetFileEnum
|
||||
@ stub NetFileGetInfo
|
||||
@ stub NetGetAnyDCName
|
||||
@ stdcall NetGetDCName(wstr wstr ptr)
|
||||
@ stub NetGetDisplayInformationIndex
|
||||
@ stub NetGroupAdd
|
||||
@ stub NetGroupAddUser
|
||||
@ stub NetGroupDel
|
||||
@ stub NetGroupDelUser
|
||||
@ stub NetGroupEnum
|
||||
@ stub NetGroupGetInfo
|
||||
@ stub NetGroupGetUsers
|
||||
@ stub NetGroupSetInfo
|
||||
@ stub NetGroupSetUsers
|
||||
@ stdcall NetLocalGroupAdd(wstr long ptr ptr)
|
||||
@ stub NetLocalGroupAddMember
|
||||
@ stub NetLocalGroupAddMembers
|
||||
@ stub NetLocalGroupDel
|
||||
@ stub NetLocalGroupDelMember
|
||||
@ stub NetLocalGroupDelMembers
|
||||
@ stub NetLocalGroupEnum
|
||||
@ stub NetLocalGroupGetInfo
|
||||
@ stub NetLocalGroupGetMembers
|
||||
@ stub NetLocalGroupSetInfo
|
||||
@ stdcall NetLocalGroupSetMembers(wstr wstr long ptr ptr)
|
||||
@ stub NetMessageBufferSend
|
||||
@ stub NetMessageNameAdd
|
||||
@ stub NetMessageNameDel
|
||||
@ stub NetMessageNameEnum
|
||||
@ stub NetMessageNameGetInfo
|
||||
@ stdcall NetQueryDisplayInformation(wstr long long long long ptr ptr)
|
||||
@ stub NetRemoteComputerSupports
|
||||
@ stub NetRemoteTOD
|
||||
@ stub NetReplExportDirAdd
|
||||
@ stub NetReplExportDirDel
|
||||
@ stub NetReplExportDirEnum
|
||||
@ stub NetReplExportDirGetInfo
|
||||
@ stub NetReplExportDirLock
|
||||
@ stub NetReplExportDirSetInfo
|
||||
@ stub NetReplExportDirUnlock
|
||||
@ stub NetReplGetInfo
|
||||
@ stub NetReplImportDirAdd
|
||||
@ stub NetReplImportDirDel
|
||||
@ stub NetReplImportDirEnum
|
||||
@ stub NetReplImportDirGetInfo
|
||||
@ stub NetReplImportDirLock
|
||||
@ stub NetReplImportDirUnlock
|
||||
@ stub NetReplSetInfo
|
||||
@ stub NetRplAdapterAdd
|
||||
@ stub NetRplAdapterDel
|
||||
@ stub NetRplAdapterEnum
|
||||
@ stub NetRplBootAdd
|
||||
@ stub NetRplBootDel
|
||||
@ stub NetRplBootEnum
|
||||
@ stub NetRplClose
|
||||
@ stub NetRplConfigAdd
|
||||
@ stub NetRplConfigDel
|
||||
@ stub NetRplConfigEnum
|
||||
@ stub NetRplGetInfo
|
||||
@ stub NetRplOpen
|
||||
@ stub NetRplProfileAdd
|
||||
@ stub NetRplProfileClone
|
||||
@ stub NetRplProfileDel
|
||||
@ stub NetRplProfileEnum
|
||||
@ stub NetRplProfileGetInfo
|
||||
@ stub NetRplProfileSetInfo
|
||||
@ stub NetRplSetInfo
|
||||
@ stub NetRplSetSecurity
|
||||
@ stub NetRplVendorAdd
|
||||
@ stub NetRplVendorDel
|
||||
@ stub NetRplVendorEnum
|
||||
@ stub NetRplWkstaAdd
|
||||
@ stub NetRplWkstaClone
|
||||
@ stub NetRplWkstaDel
|
||||
@ stub NetRplWkstaEnum
|
||||
@ stub NetRplWkstaGetInfo
|
||||
@ stub NetRplWkstaSetInfo
|
||||
@ stub NetScheduleJobAdd
|
||||
@ stub NetScheduleJobDel
|
||||
@ stub NetScheduleJobEnum
|
||||
@ stub NetScheduleJobGetInfo
|
||||
@ stub NetServerComputerNameAdd
|
||||
@ stub NetServerComputerNameDel
|
||||
@ stub NetServerDiskEnum
|
||||
@ stdcall NetServerEnum(wstr long ptr long ptr ptr long wstr ptr)
|
||||
@ stub NetServerEnumEx
|
||||
@ stub NetServerGetInfo
|
||||
@ stub NetServerSetInfo
|
||||
@ stub NetServerTransportAdd
|
||||
@ stub NetServerTransportAddEx
|
||||
@ stub NetServerTransportDel
|
||||
@ stub NetServerTransportEnum
|
||||
@ stub NetServiceControl
|
||||
@ stub NetServiceEnum
|
||||
@ stub NetServiceGetInfo
|
||||
@ stub NetServiceInstall
|
||||
@ stub NetSessionDel
|
||||
@ stub NetSessionEnum
|
||||
@ stub NetSessionGetInfo
|
||||
@ stub NetShareAdd
|
||||
@ stub NetShareCheck
|
||||
@ stub NetShareDel
|
||||
@ stub NetShareDelSticky
|
||||
@ stdcall NetShareEnum(wstr long ptr long ptr ptr ptr)
|
||||
@ stub NetShareEnumSticky
|
||||
@ stub NetShareGetInfo
|
||||
@ stub NetShareSetInfo
|
||||
@ stdcall NetStatisticsGet(wstr wstr long long ptr)
|
||||
@ stub NetUseAdd
|
||||
@ stub NetUseDel
|
||||
@ stub NetUseEnum
|
||||
@ stub NetUseGetInfo
|
||||
@ stub NetUserAdd
|
||||
@ stub NetUserChangePassword
|
||||
@ stub NetUserDel
|
||||
@ stdcall NetUserEnum(wstr long long ptr long ptr ptr ptr)
|
||||
@ stub NetUserGetGroups
|
||||
@ stdcall NetUserGetInfo(wstr wstr long ptr)
|
||||
@ stub NetUserGetLocalGroups
|
||||
@ stdcall NetUserModalsGet(wstr long ptr)
|
||||
@ stub NetUserModalsSet
|
||||
@ stub NetUserSetGroups
|
||||
@ stub NetUserSetInfo
|
||||
@ stdcall NetWkstaGetInfo(wstr long ptr)
|
||||
@ stub NetWkstaSetInfo
|
||||
@ stub NetWkstaTransportAdd
|
||||
@ stub NetWkstaTransportDel
|
||||
@ stdcall NetWkstaTransportEnum (wstr long ptr long ptr ptr ptr)
|
||||
@ stub NetWkstaUserEnum
|
||||
@ stdcall NetWkstaUserGetInfo(wstr long ptr)
|
||||
@ stub NetWkstaUserSetInfo
|
||||
@ stdcall NetapipBufferAllocate(long ptr) NetApiBufferAllocate
|
||||
@ stdcall Netbios(ptr)
|
||||
@ stub NetpAccessCheck
|
||||
@ stub NetpAccessCheckAndAudit
|
||||
@ stub NetpAllocConfigName
|
||||
@ stub NetpAllocStrFromStr
|
||||
@ stub NetpAllocStrFromWStr
|
||||
@ stub NetpAllocTStrFromString
|
||||
@ stub NetpAllocWStrFromStr
|
||||
@ stub NetpAllocWStrFromWStr
|
||||
@ stub NetpApiStatusToNtStatus
|
||||
@ stub NetpAssertFailed
|
||||
@ stub NetpCloseConfigData
|
||||
@ stub NetpCopyStringToBuffer
|
||||
@ stub NetpCreateSecurityObject
|
||||
@ stub NetpDbgDisplayServerInfo
|
||||
@ stub NetpDbgPrint
|
||||
@ stdcall NetpDeleteSecurityObject(long) ntdll.RtlDeleteSecurityObject
|
||||
@ stdcall NetpGetComputerName(ptr)
|
||||
@ stub NetpGetConfigBool
|
||||
@ stub NetpGetConfigDword
|
||||
@ stub NetpGetConfigTStrArray
|
||||
@ stub NetpGetConfigValue
|
||||
@ stub NetpGetDomainName
|
||||
@ stub NetpGetFileSecurity
|
||||
@ stub NetpGetPrivilege
|
||||
@ stub NetpHexDump
|
||||
@ stdcall NetpInitOemString(ptr str) ntdll.RtlInitAnsiString
|
||||
@ stub NetpIsRemote
|
||||
@ stub NetpIsUncComputerNameValid
|
||||
@ stub NetpLocalTimeZoneOffset
|
||||
@ stub NetpLogonPutUnicodeString
|
||||
@ stub NetpNetBiosAddName
|
||||
@ stub NetpNetBiosCall
|
||||
@ stub NetpNetBiosDelName
|
||||
@ stub NetpNetBiosGetAdapterNumbers
|
||||
@ stub NetpNetBiosHangup
|
||||
@ stub NetpNetBiosReceive
|
||||
@ stub NetpNetBiosReset
|
||||
@ stub NetpNetBiosSend
|
||||
@ stub NetpNetBiosStatusToApiStatus
|
||||
@ stub NetpNtStatusToApiStatus
|
||||
@ stub NetpOpenConfigData
|
||||
@ stub NetpPackString
|
||||
@ stub NetpReleasePrivilege
|
||||
@ stub NetpSetConfigBool
|
||||
@ stub NetpSetConfigDword
|
||||
@ stub NetpSetConfigTStrArray
|
||||
@ stub NetpSetFileSecurity
|
||||
@ stub NetpSmbCheck
|
||||
@ stub NetpStringToNetBiosName
|
||||
@ stub NetpTStrArrayEntryCount
|
||||
@ stub NetpwNameCanonicalize
|
||||
@ stub NetpwNameCompare
|
||||
@ stub NetpwNameValidate
|
||||
@ stub NetpwPathCanonicalize
|
||||
@ stub NetpwPathCompare
|
||||
@ stub NetpwPathType
|
||||
@ stub NlBindingAddServerToCache
|
||||
@ stub NlBindingRemoveServerFromCache
|
||||
@ stub NlBindingSetAuthInfo
|
||||
@ stub RxNetAccessAdd
|
||||
@ stub RxNetAccessDel
|
||||
@ stub RxNetAccessEnum
|
||||
@ stub RxNetAccessGetInfo
|
||||
@ stub RxNetAccessGetUserPerms
|
||||
@ stub RxNetAccessSetInfo
|
||||
@ stub RxNetServerEnum
|
||||
@ stub RxNetUserPasswordSet
|
||||
@ stub RxRemoteApi
|
35
reactos/lib/netapi32/netapi32_misc.h
Normal file
35
reactos/lib/netapi32/netapi32_misc.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2002 Andriy Palamarchuk
|
||||
*
|
||||
* netapi32 internal functions.
|
||||
*
|
||||
* 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, writ
|
||||
e to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_NETAPI32_MISC_H
|
||||
#define __WINE_NETAPI32_MISC_H
|
||||
|
||||
extern BOOL NETAPI_IsLocalComputer(LPCWSTR ServerName);
|
||||
|
||||
#define NETAPI_ForceLocalComputer(ServerName, FailureCode) \
|
||||
if (!NETAPI_IsLocalComputer(ServerName)) \
|
||||
{ \
|
||||
FIXME("Action Implemented for local computer only. " \
|
||||
"Requested for server %s\n", debugstr_w(ServerName)); \
|
||||
return FailureCode; \
|
||||
}
|
||||
|
||||
#endif
|
846
reactos/lib/netapi32/netbios.c
Normal file
846
reactos/lib/netapi32/netbios.c
Normal file
|
@ -0,0 +1,846 @@
|
|||
/* Copyright (c) 2003 Juan Lang
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "wine/debug.h"
|
||||
#include "nbcmdqueue.h"
|
||||
#include "netbios.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netbios);
|
||||
|
||||
/* This file provides a NetBIOS emulator that implements the NetBIOS interface,
|
||||
* including thread safety and asynchronous call support. The protocol
|
||||
* implementation is separate, with blocking (synchronous) functions.
|
||||
*/
|
||||
|
||||
#define ADAPTERS_INCR 8
|
||||
#define DEFAULT_NUM_SESSIONS 16
|
||||
|
||||
typedef struct _NetBIOSTransportTableEntry
|
||||
{
|
||||
ULONG id;
|
||||
NetBIOSTransport transport;
|
||||
} NetBIOSTransportTableEntry;
|
||||
|
||||
typedef struct _NetBIOSSession
|
||||
{
|
||||
BOOL inUse;
|
||||
UCHAR state;
|
||||
UCHAR local_name[NCBNAMSZ];
|
||||
UCHAR remote_name[NCBNAMSZ];
|
||||
void *data;
|
||||
} NetBIOSSession;
|
||||
|
||||
/* This struct needs a little explanation, unfortunately. enabled is only
|
||||
* used by nbInternalEnum (see). If transport_id is not 0 and transport
|
||||
* is not NULL, the adapter is considered valid. (transport is a pointer to
|
||||
* an entry in a NetBIOSTransportTableEntry.) data has data for the callers of
|
||||
* NetBIOSEnumAdapters to be able to see. The lana is repeated there, even
|
||||
* though I don't use it internally--it's for transports to use reenabling
|
||||
* adapters using NetBIOSEnableAdapter.
|
||||
*/
|
||||
typedef struct _NetBIOSAdapter
|
||||
{
|
||||
BOOL enabled;
|
||||
BOOL shuttingDown;
|
||||
ULONG resetting;
|
||||
ULONG transport_id;
|
||||
NetBIOSTransport *transport;
|
||||
NetBIOSAdapterImpl impl;
|
||||
struct NBCmdQueue *cmdQueue;
|
||||
CRITICAL_SECTION cs;
|
||||
DWORD sessionsLen;
|
||||
NetBIOSSession *sessions;
|
||||
} NetBIOSAdapter;
|
||||
|
||||
typedef struct _NetBIOSAdapterTable {
|
||||
CRITICAL_SECTION cs;
|
||||
BOOL enumerated;
|
||||
BOOL enumerating;
|
||||
UCHAR tableSize;
|
||||
NetBIOSAdapter *table;
|
||||
} NetBIOSAdapterTable;
|
||||
|
||||
/* Just enough space for NBT right now */
|
||||
static NetBIOSTransportTableEntry gTransports[1];
|
||||
static UCHAR gNumTransports = 0;
|
||||
static NetBIOSAdapterTable gNBTable;
|
||||
|
||||
static UCHAR nbResizeAdapterTable(UCHAR newSize)
|
||||
{
|
||||
UCHAR ret;
|
||||
|
||||
if (gNBTable.table)
|
||||
gNBTable.table = (NetBIOSAdapter *)HeapReAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY, gNBTable.table,
|
||||
newSize * sizeof(NetBIOSAdapter));
|
||||
else
|
||||
gNBTable.table = (NetBIOSAdapter *)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY, newSize * sizeof(NetBIOSAdapter));
|
||||
if (gNBTable.table)
|
||||
{
|
||||
gNBTable.tableSize = newSize;
|
||||
ret = NRC_GOODRET;
|
||||
}
|
||||
else
|
||||
ret = NRC_OSRESNOTAV;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NetBIOSInit(void)
|
||||
{
|
||||
memset(&gNBTable, 0, sizeof(gNBTable));
|
||||
InitializeCriticalSection(&gNBTable.cs);
|
||||
}
|
||||
|
||||
void NetBIOSShutdown(void)
|
||||
{
|
||||
UCHAR i;
|
||||
|
||||
EnterCriticalSection(&gNBTable.cs);
|
||||
for (i = 0; i < gNBTable.tableSize; i++)
|
||||
{
|
||||
if (gNBTable.table[i].transport &&
|
||||
gNBTable.table[i].transport->cleanupAdapter)
|
||||
gNBTable.table[i].transport->cleanupAdapter(
|
||||
gNBTable.table[i].impl.data);
|
||||
}
|
||||
for (i = 0; i < gNumTransports; i++)
|
||||
if (gTransports[i].transport.cleanup)
|
||||
gTransports[i].transport.cleanup();
|
||||
LeaveCriticalSection(&gNBTable.cs);
|
||||
DeleteCriticalSection(&gNBTable.cs);
|
||||
HeapFree(GetProcessHeap(), 0, gNBTable.table);
|
||||
}
|
||||
|
||||
BOOL NetBIOSRegisterTransport(ULONG id, NetBIOSTransport *transport)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE(": transport 0x%08lx, p %p\n", id, transport);
|
||||
if (!transport)
|
||||
ret = FALSE;
|
||||
else if (gNumTransports >= sizeof(gTransports) / sizeof(gTransports[0]))
|
||||
{
|
||||
FIXME("You tried to add %d transports, but I only have space for %d\n",
|
||||
gNumTransports + 1, sizeof(gTransports) / sizeof(gTransports[0]));
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
UCHAR i;
|
||||
|
||||
ret = FALSE;
|
||||
for (i = 0; !ret && i < gNumTransports; i++)
|
||||
{
|
||||
if (gTransports[i].id == id)
|
||||
{
|
||||
WARN("Replacing NetBIOS transport ID %ld\n", id);
|
||||
memcpy(&gTransports[i].transport, transport,
|
||||
sizeof(NetBIOSTransport));
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
gTransports[gNumTransports].id = id;
|
||||
memcpy(&gTransports[gNumTransports].transport, transport,
|
||||
sizeof(NetBIOSTransport));
|
||||
gNumTransports++;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* In this, I acquire the table lock to make sure no one else is modifying it.
|
||||
* This is _probably_ overkill since it should only be called during the
|
||||
* context of a NetBIOSEnum call, but just to be safe..
|
||||
*/
|
||||
BOOL NetBIOSRegisterAdapter(ULONG transport, DWORD ifIndex, void *data)
|
||||
{
|
||||
BOOL ret;
|
||||
UCHAR i;
|
||||
|
||||
TRACE(": transport 0x%08lx, ifIndex 0x%08lx, data %p\n", transport, ifIndex,
|
||||
data);
|
||||
for (i = 0; i < gNumTransports && gTransports[i].id != transport; i++)
|
||||
;
|
||||
if (gTransports[i].id == transport)
|
||||
{
|
||||
NetBIOSTransport *transportPtr = &gTransports[i].transport;
|
||||
|
||||
TRACE(": found transport %p for id 0x%08lx\n", transportPtr, transport);
|
||||
|
||||
EnterCriticalSection(&gNBTable.cs);
|
||||
ret = FALSE;
|
||||
for (i = 0; i < gNBTable.tableSize &&
|
||||
gNBTable.table[i].transport != 0; i++)
|
||||
;
|
||||
if (i == gNBTable.tableSize && gNBTable.tableSize < MAX_LANA + 1)
|
||||
{
|
||||
UCHAR newSize;
|
||||
|
||||
if (gNBTable.tableSize < (MAX_LANA + 1) - ADAPTERS_INCR)
|
||||
newSize = gNBTable.tableSize + ADAPTERS_INCR;
|
||||
else
|
||||
newSize = MAX_LANA + 1;
|
||||
nbResizeAdapterTable(newSize);
|
||||
}
|
||||
if (i < gNBTable.tableSize && gNBTable.table[i].transport == 0)
|
||||
{
|
||||
TRACE(": registering as LANA %d\n", i);
|
||||
gNBTable.table[i].transport_id = transport;
|
||||
gNBTable.table[i].transport = transportPtr;
|
||||
gNBTable.table[i].impl.lana = i;
|
||||
gNBTable.table[i].impl.ifIndex = ifIndex;
|
||||
gNBTable.table[i].impl.data = data;
|
||||
gNBTable.table[i].cmdQueue = NBCmdQueueCreate(GetProcessHeap());
|
||||
InitializeCriticalSection(&gNBTable.table[i].cs);
|
||||
gNBTable.table[i].enabled = TRUE;
|
||||
ret = TRUE;
|
||||
}
|
||||
LeaveCriticalSection(&gNBTable.cs);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* In this, I acquire the table lock to make sure no one else is modifying it.
|
||||
* This is _probably_ overkill since it should only be called during the
|
||||
* context of a NetBIOSEnum call, but just to be safe..
|
||||
*/
|
||||
void NetBIOSEnableAdapter(UCHAR lana)
|
||||
{
|
||||
TRACE(": %d\n", lana);
|
||||
if (lana < gNBTable.tableSize)
|
||||
{
|
||||
EnterCriticalSection(&gNBTable.cs);
|
||||
if (gNBTable.table[lana].transport != 0)
|
||||
gNBTable.table[lana].enabled = TRUE;
|
||||
LeaveCriticalSection(&gNBTable.cs);
|
||||
}
|
||||
}
|
||||
|
||||
static void nbShutdownAdapter(NetBIOSAdapter *adapter)
|
||||
{
|
||||
if (adapter)
|
||||
{
|
||||
adapter->shuttingDown = TRUE;
|
||||
NBCmdQueueCancelAll(adapter->cmdQueue);
|
||||
if (adapter->transport->cleanupAdapter)
|
||||
adapter->transport->cleanupAdapter(adapter->impl.data);
|
||||
NBCmdQueueDestroy(adapter->cmdQueue);
|
||||
DeleteCriticalSection(&adapter->cs);
|
||||
memset(adapter, 0, sizeof(NetBIOSAdapter));
|
||||
}
|
||||
}
|
||||
|
||||
static void nbInternalEnum(void)
|
||||
{
|
||||
UCHAR i;
|
||||
|
||||
EnterCriticalSection(&gNBTable.cs);
|
||||
TRACE("before mark\n");
|
||||
/* mark: */
|
||||
for (i = 0; i < gNBTable.tableSize; i++)
|
||||
if (gNBTable.table[i].enabled && gNBTable.table[i].transport != 0)
|
||||
gNBTable.table[i].enabled = FALSE;
|
||||
|
||||
TRACE("marked, before store, %d transports\n", gNumTransports);
|
||||
/* store adapters: */
|
||||
for (i = 0; i < gNumTransports; i++)
|
||||
if (gTransports[i].transport.enumerate)
|
||||
gTransports[i].transport.enumerate();
|
||||
|
||||
TRACE("before sweep\n");
|
||||
/* sweep: */
|
||||
for (i = 0; i < gNBTable.tableSize; i++)
|
||||
if (!gNBTable.table[i].enabled && gNBTable.table[i].transport != 0)
|
||||
nbShutdownAdapter(&gNBTable.table[i]);
|
||||
gNBTable.enumerated = TRUE;
|
||||
LeaveCriticalSection(&gNBTable.cs);
|
||||
}
|
||||
|
||||
UCHAR NetBIOSNumAdapters(void)
|
||||
{
|
||||
UCHAR ret, i;
|
||||
|
||||
if (!gNBTable.enumerated)
|
||||
nbInternalEnum();
|
||||
for (i = 0, ret = 0; i < gNBTable.tableSize; i++)
|
||||
if (gNBTable.table[i].transport != 0)
|
||||
ret++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NetBIOSEnumAdapters(ULONG transport, NetBIOSEnumAdaptersCallback cb,
|
||||
void *closure)
|
||||
{
|
||||
TRACE("transport 0x%08lx, callback %p, closure %p\n", transport, cb,
|
||||
closure);
|
||||
if (cb)
|
||||
{
|
||||
BOOL enumAll = memcmp(&transport, ALL_TRANSPORTS, sizeof(ULONG)) == 0;
|
||||
UCHAR i, numLANAs = 0;
|
||||
|
||||
EnterCriticalSection(&gNBTable.cs);
|
||||
if (!gNBTable.enumerating)
|
||||
{
|
||||
gNBTable.enumerating = TRUE;
|
||||
nbInternalEnum();
|
||||
gNBTable.enumerating = FALSE;
|
||||
}
|
||||
for (i = 0; i < gNBTable.tableSize; i++)
|
||||
if (enumAll || gNBTable.table[i].transport_id == transport)
|
||||
numLANAs++;
|
||||
if (numLANAs > 0)
|
||||
{
|
||||
UCHAR lanaIndex = 0;
|
||||
|
||||
for (i = 0; i < gNBTable.tableSize; i++)
|
||||
if (gNBTable.table[i].transport_id != 0 &&
|
||||
(enumAll || gNBTable.table[i].transport_id == transport))
|
||||
cb(numLANAs, lanaIndex++, gNBTable.table[i].transport_id,
|
||||
&gNBTable.table[i].impl, closure);
|
||||
}
|
||||
LeaveCriticalSection(&gNBTable.cs);
|
||||
}
|
||||
}
|
||||
|
||||
static NetBIOSAdapter *nbGetAdapter(UCHAR lana)
|
||||
{
|
||||
NetBIOSAdapter *ret = NULL;
|
||||
|
||||
TRACE(": lana %d, num allocated adapters %d\n", lana, gNBTable.tableSize);
|
||||
if (lana < gNBTable.tableSize && gNBTable.table[lana].transport_id != 0
|
||||
&& gNBTable.table[lana].transport)
|
||||
ret = &gNBTable.table[lana];
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbEnum(PNCB ncb)
|
||||
{
|
||||
PLANA_ENUM lanas = (PLANA_ENUM)ncb->ncb_buffer;
|
||||
UCHAR i, ret;
|
||||
|
||||
TRACE(": ncb %p\n", ncb);
|
||||
|
||||
if (!lanas)
|
||||
ret = NRC_BUFLEN;
|
||||
else if (ncb->ncb_length < sizeof(LANA_ENUM))
|
||||
ret = NRC_BUFLEN;
|
||||
else
|
||||
{
|
||||
nbInternalEnum();
|
||||
lanas->length = 0;
|
||||
for (i = 0; i < gNBTable.tableSize; i++)
|
||||
if (gNBTable.table[i].transport)
|
||||
{
|
||||
lanas->length++;
|
||||
lanas->lana[i] = i;
|
||||
}
|
||||
ret = NRC_GOODRET;
|
||||
}
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbInternalHangup(NetBIOSAdapter *adapter, NetBIOSSession *session);
|
||||
|
||||
static UCHAR nbCancel(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
|
||||
TRACE(": adapter %p, ncb %p\n", adapter, ncb);
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
|
||||
switch (ncb->ncb_command & 0x7f)
|
||||
{
|
||||
case NCBCANCEL:
|
||||
case NCBADDNAME:
|
||||
case NCBADDGRNAME:
|
||||
case NCBDELNAME:
|
||||
case NCBRESET:
|
||||
case NCBSSTAT:
|
||||
ret = NRC_CANCEL;
|
||||
break;
|
||||
|
||||
/* NCBCALL, NCBCHAINSEND/NCBSEND, NCBHANGUP all close the associated
|
||||
* session if cancelled */
|
||||
case NCBCALL:
|
||||
case NCBSEND:
|
||||
case NCBCHAINSEND:
|
||||
case NCBSENDNA:
|
||||
case NCBCHAINSENDNA:
|
||||
case NCBHANGUP:
|
||||
{
|
||||
if (ncb->ncb_lsn >= adapter->sessionsLen)
|
||||
ret = NRC_SNUMOUT;
|
||||
else if (!adapter->sessions[ncb->ncb_lsn].inUse)
|
||||
ret = NRC_SNUMOUT;
|
||||
else
|
||||
{
|
||||
ret = NBCmdQueueCancel(adapter->cmdQueue, ncb);
|
||||
if (ret == NRC_CMDCAN || ret == NRC_CANOCCR)
|
||||
nbInternalHangup(adapter, &adapter->sessions[ncb->ncb_lsn]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = NBCmdQueueCancel(adapter->cmdQueue, ncb);
|
||||
}
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Resizes adapter to contain space for at least sessionsLen sessions.
|
||||
* If allocating more space for sessions, sets the adapter's sessionsLen to
|
||||
* sessionsLen. If the adapter's sessionsLen was already at least sessionsLen,
|
||||
* does nothing. Does not modify existing sessions. Assumes the adapter is
|
||||
* locked.
|
||||
* Returns NRC_GOODRET on success, and something else on failure.
|
||||
*/
|
||||
static UCHAR nbResizeAdapter(NetBIOSAdapter *adapter, UCHAR sessionsLen)
|
||||
{
|
||||
UCHAR ret = NRC_GOODRET;
|
||||
|
||||
if (adapter && adapter->sessionsLen < sessionsLen)
|
||||
{
|
||||
NetBIOSSession *newSessions;
|
||||
|
||||
if (adapter->sessions)
|
||||
newSessions = (NetBIOSSession *)HeapReAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY, adapter->sessions, sessionsLen *
|
||||
sizeof(NetBIOSSession));
|
||||
else
|
||||
newSessions = (NetBIOSSession *)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY, sessionsLen * sizeof(NetBIOSSession));
|
||||
if (newSessions)
|
||||
{
|
||||
adapter->sessions = newSessions;
|
||||
adapter->sessionsLen = sessionsLen;
|
||||
}
|
||||
else
|
||||
ret = NRC_OSRESNOTAV;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbReset(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
|
||||
TRACE(": adapter %p, ncb %p\n", adapter, ncb);
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
|
||||
if (InterlockedIncrement(&adapter->resetting) == 1)
|
||||
{
|
||||
UCHAR i, resizeTo;
|
||||
|
||||
NBCmdQueueCancelAll(adapter->cmdQueue);
|
||||
|
||||
EnterCriticalSection(&adapter->cs);
|
||||
for (i = 0; i < adapter->sessionsLen; i++)
|
||||
if (adapter->sessions[i].inUse)
|
||||
nbInternalHangup(adapter, &adapter->sessions[i]);
|
||||
if (!ncb->ncb_lsn)
|
||||
resizeTo = ncb->ncb_callname[0] == 0 ? DEFAULT_NUM_SESSIONS :
|
||||
ncb->ncb_callname[0];
|
||||
else if (adapter->sessionsLen == 0)
|
||||
resizeTo = DEFAULT_NUM_SESSIONS;
|
||||
else
|
||||
resizeTo = 0;
|
||||
if (resizeTo > 0)
|
||||
ret = nbResizeAdapter(adapter, resizeTo);
|
||||
else
|
||||
ret = NRC_GOODRET;
|
||||
LeaveCriticalSection(&adapter->cs);
|
||||
}
|
||||
else
|
||||
ret = NRC_TOOMANY;
|
||||
InterlockedDecrement(&adapter->resetting);
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbSStat(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret, i, spaceFor;
|
||||
PSESSION_HEADER sstat;
|
||||
|
||||
TRACE(": adapter %p, NCB %p\n", adapter, ncb);
|
||||
|
||||
if (!adapter) return NRC_BADDR;
|
||||
if (adapter->sessionsLen == 0) return NRC_ENVNOTDEF;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
if (!ncb->ncb_buffer) return NRC_BADDR;
|
||||
if (ncb->ncb_length < sizeof(SESSION_HEADER)) return NRC_BUFLEN;
|
||||
|
||||
sstat = (PSESSION_HEADER)ncb->ncb_buffer;
|
||||
ret = NRC_GOODRET;
|
||||
memset(sstat, 0, sizeof(SESSION_HEADER));
|
||||
spaceFor = (ncb->ncb_length - sizeof(SESSION_HEADER)) /
|
||||
sizeof(SESSION_BUFFER);
|
||||
EnterCriticalSection(&adapter->cs);
|
||||
for (i = 0; ret == NRC_GOODRET && i < adapter->sessionsLen; i++)
|
||||
{
|
||||
if (adapter->sessions[i].inUse && (ncb->ncb_name[0] == '*' ||
|
||||
!memcmp(ncb->ncb_name, adapter->sessions[i].local_name, NCBNAMSZ)))
|
||||
{
|
||||
if (sstat->num_sess < spaceFor)
|
||||
{
|
||||
PSESSION_BUFFER buf;
|
||||
|
||||
buf = (PSESSION_BUFFER)((PUCHAR)sstat + sizeof(SESSION_HEADER)
|
||||
+ sstat->num_sess * sizeof(SESSION_BUFFER));
|
||||
buf->lsn = i;
|
||||
buf->state = adapter->sessions[i].state;
|
||||
memcpy(buf->local_name, adapter->sessions[i].local_name,
|
||||
NCBNAMSZ);
|
||||
memcpy(buf->remote_name, adapter->sessions[i].remote_name,
|
||||
NCBNAMSZ);
|
||||
buf->rcvs_outstanding = buf->sends_outstanding = 0;
|
||||
sstat->num_sess++;
|
||||
}
|
||||
else
|
||||
ret = NRC_BUFLEN;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&adapter->cs);
|
||||
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbCall(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret, i;
|
||||
|
||||
TRACE(": adapter %p, NCB %p\n", adapter, ncb);
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (adapter->sessionsLen == 0) return NRC_ENVNOTDEF;
|
||||
if (!adapter->transport->call) return NRC_ILLCMD;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
|
||||
EnterCriticalSection(&adapter->cs);
|
||||
for (i = 0; i < adapter->sessionsLen && adapter->sessions[i].inUse; i++)
|
||||
;
|
||||
if (i < adapter->sessionsLen)
|
||||
{
|
||||
adapter->sessions[i].inUse = TRUE;
|
||||
adapter->sessions[i].state = CALL_PENDING;
|
||||
memcpy(adapter->sessions[i].local_name, ncb->ncb_name, NCBNAMSZ);
|
||||
memcpy(adapter->sessions[i].remote_name, ncb->ncb_callname, NCBNAMSZ);
|
||||
ret = NRC_GOODRET;
|
||||
}
|
||||
else
|
||||
ret = NRC_LOCTFUL;
|
||||
LeaveCriticalSection(&adapter->cs);
|
||||
|
||||
if (ret == NRC_GOODRET)
|
||||
{
|
||||
ret = adapter->transport->call(adapter->impl.data, ncb,
|
||||
&adapter->sessions[i].data);
|
||||
if (ret == NRC_GOODRET)
|
||||
{
|
||||
ncb->ncb_lsn = i;
|
||||
adapter->sessions[i].state = SESSION_ESTABLISHED;
|
||||
}
|
||||
else
|
||||
{
|
||||
adapter->sessions[i].inUse = FALSE;
|
||||
adapter->sessions[i].state = 0;
|
||||
}
|
||||
}
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbSend(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
NetBIOSSession *session;
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (!adapter->transport->send) return NRC_ILLCMD;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
if (ncb->ncb_lsn >= adapter->sessionsLen) return NRC_SNUMOUT;
|
||||
if (!adapter->sessions[ncb->ncb_lsn].inUse) return NRC_SNUMOUT;
|
||||
if (!ncb->ncb_buffer) return NRC_BADDR;
|
||||
|
||||
session = &adapter->sessions[ncb->ncb_lsn];
|
||||
if (session->state != SESSION_ESTABLISHED)
|
||||
ret = NRC_SNUMOUT;
|
||||
else
|
||||
ret = adapter->transport->send(adapter->impl.data, session->data, ncb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbRecv(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
NetBIOSSession *session;
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (!adapter->transport->recv) return NRC_ILLCMD;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
if (ncb->ncb_lsn >= adapter->sessionsLen) return NRC_SNUMOUT;
|
||||
if (!adapter->sessions[ncb->ncb_lsn].inUse) return NRC_SNUMOUT;
|
||||
if (!ncb->ncb_buffer) return NRC_BADDR;
|
||||
|
||||
session = &adapter->sessions[ncb->ncb_lsn];
|
||||
if (session->state != SESSION_ESTABLISHED)
|
||||
ret = NRC_SNUMOUT;
|
||||
else
|
||||
ret = adapter->transport->recv(adapter->impl.data, session->data, ncb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbInternalHangup(NetBIOSAdapter *adapter, NetBIOSSession *session)
|
||||
{
|
||||
UCHAR ret;
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (!session) return NRC_SNUMOUT;
|
||||
|
||||
if (adapter->transport->hangup)
|
||||
ret = adapter->transport->hangup(adapter->impl.data, session->data);
|
||||
else
|
||||
ret = NRC_ILLCMD;
|
||||
EnterCriticalSection(&adapter->cs);
|
||||
memset(session, 0, sizeof(NetBIOSSession));
|
||||
LeaveCriticalSection(&adapter->cs);
|
||||
return NRC_GOODRET;
|
||||
}
|
||||
|
||||
static UCHAR nbHangup(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
NetBIOSSession *session;
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
if (ncb->ncb_lsn >= adapter->sessionsLen) return NRC_SNUMOUT;
|
||||
if (!adapter->sessions[ncb->ncb_lsn].inUse) return NRC_SNUMOUT;
|
||||
|
||||
session = &adapter->sessions[ncb->ncb_lsn];
|
||||
if (session->state != SESSION_ESTABLISHED)
|
||||
ret = NRC_SNUMOUT;
|
||||
else
|
||||
{
|
||||
session->state = HANGUP_PENDING;
|
||||
ret = nbInternalHangup(adapter, session);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NetBIOSHangupSession(PNCB ncb)
|
||||
{
|
||||
NetBIOSAdapter *adapter;
|
||||
|
||||
if (!ncb) return;
|
||||
|
||||
adapter = nbGetAdapter(ncb->ncb_lana_num);
|
||||
if (adapter)
|
||||
{
|
||||
if (ncb->ncb_lsn < adapter->sessionsLen &&
|
||||
adapter->sessions[ncb->ncb_lsn].inUse)
|
||||
nbHangup(adapter, ncb);
|
||||
}
|
||||
}
|
||||
|
||||
static UCHAR nbAStat(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (!adapter->transport->astat) return NRC_ILLCMD;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
if (!ncb->ncb_buffer) return NRC_BADDR;
|
||||
if (ncb->ncb_length < sizeof(ADAPTER_STATUS)) return NRC_BUFLEN;
|
||||
|
||||
ret = adapter->transport->astat(adapter->impl.data, ncb);
|
||||
if (ncb->ncb_callname[0] == '*')
|
||||
{
|
||||
PADAPTER_STATUS astat = (PADAPTER_STATUS)ncb->ncb_buffer;
|
||||
|
||||
astat->max_sess = astat->max_cfg_sess = adapter->sessionsLen;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UCHAR nbDispatch(NetBIOSAdapter *adapter, PNCB ncb)
|
||||
{
|
||||
UCHAR ret, cmd;
|
||||
|
||||
TRACE(": adapter %p, ncb %p\n", adapter, ncb);
|
||||
|
||||
if (!adapter) return NRC_BRIDGE;
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
|
||||
cmd = ncb->ncb_command & 0x7f;
|
||||
if (cmd == NCBRESET)
|
||||
ret = nbReset(adapter, ncb);
|
||||
else
|
||||
{
|
||||
ret = NBCmdQueueAdd(adapter->cmdQueue, ncb);
|
||||
if (ret == NRC_GOODRET)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case NCBCALL:
|
||||
ret = nbCall(adapter, ncb);
|
||||
break;
|
||||
|
||||
/* WinNT doesn't chain sends, it always sends immediately.
|
||||
* Doubt there's any real significance to the NA variants.
|
||||
*/
|
||||
case NCBSEND:
|
||||
case NCBSENDNA:
|
||||
case NCBCHAINSEND:
|
||||
case NCBCHAINSENDNA:
|
||||
ret = nbSend(adapter, ncb);
|
||||
break;
|
||||
|
||||
case NCBRECV:
|
||||
ret = nbRecv(adapter, ncb);
|
||||
break;
|
||||
|
||||
case NCBHANGUP:
|
||||
ret = nbHangup(adapter, ncb);
|
||||
break;
|
||||
|
||||
case NCBASTAT:
|
||||
ret = nbAStat(adapter, ncb);
|
||||
break;
|
||||
|
||||
case NCBFINDNAME:
|
||||
if (adapter->transport->findName)
|
||||
ret = adapter->transport->findName(adapter->impl.data,
|
||||
ncb);
|
||||
else
|
||||
ret = NRC_ILLCMD;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("(%p): command code 0x%02x\n", ncb, ncb->ncb_command);
|
||||
ret = NRC_ILLCMD;
|
||||
}
|
||||
NBCmdQueueComplete(adapter->cmdQueue, ncb, ret);
|
||||
}
|
||||
}
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI nbCmdThread(LPVOID lpVoid)
|
||||
{
|
||||
PNCB ncb = (PNCB)lpVoid;
|
||||
|
||||
if (ncb)
|
||||
{
|
||||
UCHAR ret;
|
||||
NetBIOSAdapter *adapter = nbGetAdapter(ncb->ncb_lana_num);
|
||||
|
||||
if (adapter)
|
||||
ret = nbDispatch(adapter, ncb);
|
||||
else
|
||||
ret = NRC_BRIDGE;
|
||||
ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret;
|
||||
if (ncb->ncb_post)
|
||||
ncb->ncb_post(ncb);
|
||||
else if (ncb->ncb_event)
|
||||
SetEvent(ncb->ncb_event);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
UCHAR WINAPI Netbios(PNCB ncb)
|
||||
{
|
||||
UCHAR ret, cmd;
|
||||
|
||||
TRACE("ncb = %p\n", ncb);
|
||||
|
||||
if (!ncb) return NRC_INVADDRESS;
|
||||
|
||||
TRACE("ncb_command 0x%02x, ncb_lana_num %d, ncb_buffer %p, ncb_length %d\n",
|
||||
ncb->ncb_command, ncb->ncb_lana_num, ncb->ncb_buffer, ncb->ncb_length);
|
||||
cmd = ncb->ncb_command & 0x7f;
|
||||
|
||||
if (cmd == NCBENUM)
|
||||
ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret = nbEnum(ncb);
|
||||
else
|
||||
{
|
||||
NetBIOSAdapter *adapter = nbGetAdapter(ncb->ncb_lana_num);
|
||||
|
||||
if (!adapter)
|
||||
ret = NRC_BRIDGE;
|
||||
else
|
||||
{
|
||||
if (adapter->shuttingDown)
|
||||
ret = NRC_IFBUSY;
|
||||
else if (adapter->resetting)
|
||||
ret = NRC_TOOMANY;
|
||||
else
|
||||
{
|
||||
/* non-asynch commands first */
|
||||
if (cmd == NCBCANCEL)
|
||||
ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret =
|
||||
nbCancel(adapter, ncb);
|
||||
else if (cmd == NCBSSTAT)
|
||||
ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret =
|
||||
nbSStat(adapter, ncb);
|
||||
else
|
||||
{
|
||||
if (ncb->ncb_command & ASYNCH)
|
||||
{
|
||||
HANDLE thread = CreateThread(NULL, 0, nbCmdThread, ncb,
|
||||
CREATE_SUSPENDED, NULL);
|
||||
|
||||
if (thread != NULL)
|
||||
{
|
||||
ncb->ncb_retcode = ncb->ncb_cmd_cplt = NRC_PENDING;
|
||||
if (ncb->ncb_event)
|
||||
ResetEvent(ncb->ncb_event);
|
||||
ResumeThread(thread);
|
||||
CloseHandle(thread);
|
||||
ret = NRC_GOODRET;
|
||||
}
|
||||
else
|
||||
ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret =
|
||||
NRC_OSRESNOTAV;
|
||||
}
|
||||
else
|
||||
ncb->ncb_retcode = ncb->ncb_cmd_cplt = ret =
|
||||
nbDispatch(adapter, ncb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
183
reactos/lib/netapi32/netbios.h
Normal file
183
reactos/lib/netapi32/netbios.h
Normal file
|
@ -0,0 +1,183 @@
|
|||
/* Copyright (c) 2003 Juan Lang
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __WINE_NETBIOS_H__
|
||||
#define __WINE_NETBIOS_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "lm.h"
|
||||
#include "nb30.h"
|
||||
|
||||
/* This file describes the interface WINE's NetBIOS implementation uses to
|
||||
* interact with a transport implementation (where a transport might be
|
||||
* NetBIOS-over-TCP/IP (aka NetBT, NBT), NetBIOS-over-IPX, etc.)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Public functions
|
||||
*/
|
||||
|
||||
void NetBIOSInit(void);
|
||||
void NetBIOSShutdown(void);
|
||||
|
||||
struct _NetBIOSTransport;
|
||||
|
||||
/* A transport should register itself during its init function (see below) with
|
||||
* a unique id (the transport_id of ACTION_HEADER, for example) and an
|
||||
* implementation. Returns TRUE on success, and FALSE on failure.
|
||||
*/
|
||||
BOOL NetBIOSRegisterTransport(ULONG id, struct _NetBIOSTransport *transport);
|
||||
|
||||
/* Registers an adapter with the given transport and ifIndex with NetBIOS.
|
||||
* ifIndex is an interface index usable by the IpHlpApi. ifIndex is not
|
||||
* required to be unique, but is required so that NetWkstaTransportEnum can use
|
||||
* GetIfEntry to get the name and hardware address of the adapter.
|
||||
* Returns TRUE on success, FALSE on failure.
|
||||
* FIXME: need functions for retrieving the name and hardware index, rather
|
||||
* than assuming a correlation with IpHlpApi.
|
||||
*/
|
||||
BOOL NetBIOSRegisterAdapter(ULONG transport, DWORD ifIndex, void *adapter);
|
||||
|
||||
/* During enumeration, all adapters from your transport are disabled
|
||||
* internally. If an adapter is still valid, reenable it with this function.
|
||||
* Adapters you don't enable will have their transport's NetBIOSCleanupAdapter
|
||||
* function (see below) called on them, and will be removed from the table.
|
||||
* (This is to deal with lack of plug-and-play--sorry.)
|
||||
*/
|
||||
void NetBIOSEnableAdapter(UCHAR lana);
|
||||
|
||||
/* Gets a quick count of the number of NetBIOS adapters. Not guaranteed not
|
||||
* to change from one call to the next, depending on what's been enumerated
|
||||
* lately. See also NetBIOSEnumAdapters.
|
||||
*/
|
||||
UCHAR NetBIOSNumAdapters(void);
|
||||
|
||||
typedef struct _NetBIOSAdapterImpl {
|
||||
UCHAR lana;
|
||||
DWORD ifIndex;
|
||||
void *data;
|
||||
} NetBIOSAdapterImpl;
|
||||
|
||||
typedef BOOL (*NetBIOSEnumAdaptersCallback)(UCHAR totalLANAs, UCHAR lanaIndex,
|
||||
ULONG transport, const NetBIOSAdapterImpl *data, void *closure);
|
||||
|
||||
/* Enumerates all NetBIOS adapters for the transport transport, or for all
|
||||
* transports if transport is ALL_TRANSPORTS. Your callback will be called
|
||||
* once for every enumerated adapter, with a count of how many adapters have
|
||||
* been enumerated, a 0-based index relative to that count, the adapter's
|
||||
* transport, and its ifIndex.
|
||||
* Your callback should return FALSE if it no longer wishes to be called.
|
||||
*/
|
||||
void NetBIOSEnumAdapters(ULONG transport, NetBIOSEnumAdaptersCallback cb,
|
||||
void *closure);
|
||||
|
||||
/* Hangs up the session identified in the NCB; the NCB need not be a NCBHANGUP.
|
||||
* Will result in the transport's hangup function being called, so release any
|
||||
* locks you own before calling to avoid deadlock.
|
||||
* This function is intended for use by a transport, if the session is closed
|
||||
* by some error in the transport layer.
|
||||
*/
|
||||
void NetBIOSHangupSession(PNCB ncb);
|
||||
|
||||
/**
|
||||
* Functions a transport implementation must implement
|
||||
*/
|
||||
|
||||
/* This function is called to ask a transport implementation to enumerate any
|
||||
* LANAs into the NetBIOS adapter table by:
|
||||
* - calling NetBIOSRegisterAdapter for any new adapters
|
||||
* - calling NetBIOSEnableAdapter for any existing adapters
|
||||
* NetBIOSEnumAdapters (see) may be of use to determine which adapters already
|
||||
* exist.
|
||||
* A transport can assume no other thread is modifying the NetBIOS adapter
|
||||
* table during the lifetime of its NetBIOSEnum function (and, therefore, that
|
||||
* this function won't be called reentrantly).
|
||||
*/
|
||||
typedef UCHAR (*NetBIOSEnum)(void);
|
||||
|
||||
/* A cleanup function for a transport. This is the last function called on a
|
||||
* transport.
|
||||
*/
|
||||
typedef void (*NetBIOSCleanup)(void);
|
||||
|
||||
/* Adapter functions */
|
||||
|
||||
/* Functions with direct mappings to the Netbios interface. These functions
|
||||
* are expected to be synchronous, although the first four bytes of the
|
||||
* reserved member of the ncb are a cancel flag. A long-running function
|
||||
* should check whether this is not FALSE from time to time (see the
|
||||
* NCB_CANCELLED macro), and return NRC_CMDCAN if it's been cancelled. (The
|
||||
* remainder of the NCB's reserved field is, well, reserved.)
|
||||
*/
|
||||
|
||||
/* Used to see whether the pointer to an NCB has been cancelled. The NetBIOS
|
||||
* interface designates certain functions as non-cancellable functions, but I
|
||||
* use this flag for all NCBs. Support it if you can.
|
||||
* FIXME: this isn't enough, need to support an EVENT or some such, because
|
||||
* some calls (recv) will block indefinitely, so a reset, shutdown, etc. will
|
||||
* never occur.
|
||||
*/
|
||||
#define NCB_CANCELLED(pncb) *(PBOOL)((pncb)->ncb_reserve)
|
||||
|
||||
typedef UCHAR (*NetBIOSAstat)(void *adapter, PNCB ncb);
|
||||
typedef UCHAR (*NetBIOSFindName)(void *adapter, PNCB ncb);
|
||||
|
||||
/* Functions to support the session service */
|
||||
|
||||
/* Implement to support the NCBCALL command. If you need data stored for the
|
||||
* session, return it in *session. You can clean it up in your NetBIOSHangup
|
||||
* function (see).
|
||||
*/
|
||||
typedef UCHAR (*NetBIOSCall)(void *adapter, PNCB ncb, void **session);
|
||||
typedef UCHAR (*NetBIOSSend)(void *adapter, void *session, PNCB ncb);
|
||||
typedef UCHAR (*NetBIOSRecv)(void *adapter, void *session, PNCB ncb);
|
||||
typedef UCHAR (*NetBIOSHangup)(void *adapter, void *session);
|
||||
|
||||
/* The last function called on an adapter; it is not called reentrantly, and
|
||||
* no new calls will be made on the adapter once this has been entered. Clean
|
||||
* up any resources allocated for the adapter here.
|
||||
*/
|
||||
typedef void (*NetBIOSCleanupAdapter)(void *adapter);
|
||||
|
||||
typedef struct _NetBIOSTransport
|
||||
{
|
||||
NetBIOSEnum enumerate;
|
||||
NetBIOSAstat astat;
|
||||
NetBIOSFindName findName;
|
||||
NetBIOSCall call;
|
||||
NetBIOSSend send;
|
||||
NetBIOSRecv recv;
|
||||
NetBIOSHangup hangup;
|
||||
NetBIOSCleanupAdapter cleanupAdapter;
|
||||
NetBIOSCleanup cleanup;
|
||||
} NetBIOSTransport;
|
||||
|
||||
/* Transport-specific functions. When adding a transport, add a call to its
|
||||
* init function in netapi32's DllMain. The transport can do any global
|
||||
* initialization it needs here. It should call NetBIOSRegisterTransport to
|
||||
* register itself with NetBIOS.
|
||||
*/
|
||||
|
||||
/* NetBIOS-over-TCP/IP (NetBT) functions */
|
||||
|
||||
/* Not defined by MS, so make my own private define: */
|
||||
#define TRANSPORT_NBT "MNBT"
|
||||
|
||||
void NetBTInit(void);
|
||||
|
||||
#endif /* ndef __WINE_NETBIOS_H__ */
|
64
reactos/lib/netapi32/stubs.c
Normal file
64
reactos/lib/netapi32/stubs.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2002 Andriy Palamarchuk
|
||||
*
|
||||
* Net API buffer calls
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "lmcons.h"
|
||||
#include "lmapibuf.h"
|
||||
#include "lmerr.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||
|
||||
/************************************************************
|
||||
* NetApiBufferFree (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetApiBufferFree(LPVOID Buffer)
|
||||
{
|
||||
FIXME("(%p)\n", Buffer);
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetUserGetInfo (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI
|
||||
NetUserGetInfo(LPCWSTR servername, LPCWSTR username, DWORD level,
|
||||
LPBYTE* bufptr)
|
||||
{
|
||||
FIXME("(%s, %s, %ld, %p)\n", debugstr_w(servername), debugstr_w(username),
|
||||
level, bufptr);
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetWkstaUserGetInfo (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS NetWkstaUserGetInfo(LPWSTR reserved, DWORD level,
|
||||
LPBYTE* bufptr)
|
||||
{
|
||||
return NERR_Success;
|
||||
}
|
520
reactos/lib/netapi32/wksta.c
Normal file
520
reactos/lib/netapi32/wksta.c
Normal file
|
@ -0,0 +1,520 @@
|
|||
/* Copyright 2002 Andriy Palamarchuk
|
||||
* Copyright (c) 2003 Juan Lang
|
||||
*
|
||||
* netapi32 user functions
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winsock2.h"
|
||||
#include "nb30.h"
|
||||
#include "lmcons.h"
|
||||
#include "lmapibuf.h"
|
||||
#include "lmerr.h"
|
||||
#include "lmwksta.h"
|
||||
#include "iphlpapi.h"
|
||||
#include "winerror.h"
|
||||
#include "ntstatus.h"
|
||||
#include "winreg.h"
|
||||
#include "ntsecapi.h"
|
||||
#include "netbios.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||
|
||||
/************************************************************
|
||||
* NETAPI_IsLocalComputer
|
||||
*
|
||||
* Checks whether the server name indicates local machine.
|
||||
*/
|
||||
BOOL NETAPI_IsLocalComputer(LPCWSTR ServerName)
|
||||
{
|
||||
if (!ServerName)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
BOOL Result;
|
||||
LPWSTR buf;
|
||||
|
||||
NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &buf);
|
||||
Result = GetComputerNameW(buf, &dwSize);
|
||||
if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
|
||||
ServerName += 2;
|
||||
Result = Result && !lstrcmpW(ServerName, buf);
|
||||
NetApiBufferFree(buf);
|
||||
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
static void wprint_mac(WCHAR* buffer, int len, PMIB_IFROW ifRow)
|
||||
{
|
||||
int i;
|
||||
unsigned char val;
|
||||
|
||||
if (!buffer)
|
||||
return;
|
||||
if (len < 1)
|
||||
return;
|
||||
if (!ifRow)
|
||||
{
|
||||
*buffer = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ifRow->dwPhysAddrLen && 2 * i < len; i++)
|
||||
{
|
||||
val = ifRow->bPhysAddr[i];
|
||||
if ((val >>4) >9)
|
||||
buffer[2*i] = (WCHAR)((val >>4) + 'A' - 10);
|
||||
else
|
||||
buffer[2*i] = (WCHAR)((val >>4) + '0');
|
||||
if ((val & 0xf ) >9)
|
||||
buffer[2*i+1] = (WCHAR)((val & 0xf) + 'A' - 10);
|
||||
else
|
||||
buffer[2*i+1] = (WCHAR)((val & 0xf) + '0');
|
||||
}
|
||||
buffer[2*i]=(WCHAR)0;
|
||||
}
|
||||
|
||||
/* Theoretically this could be too short, except that MS defines
|
||||
* MAX_ADAPTER_NAME as 128, and MAX_INTERFACE_NAME_LEN as 256, and both
|
||||
* represent a count of WCHARs, so even with an extroardinarily long header
|
||||
* this will be plenty
|
||||
*/
|
||||
#define MAX_TRANSPORT_NAME MAX_INTERFACE_NAME_LEN
|
||||
#define MAX_TRANSPORT_ADDR 13
|
||||
|
||||
#define NBT_TRANSPORT_NAME_HEADER "\\Device\\NetBT_Tcpip_"
|
||||
#define UNKNOWN_TRANSPORT_NAME_HEADER "\\Device\\UnknownTransport_"
|
||||
|
||||
static void wprint_name(WCHAR *buffer, int len, ULONG transport,
|
||||
PMIB_IFROW ifRow)
|
||||
{
|
||||
WCHAR *ptr1, *ptr2;
|
||||
const char *name;
|
||||
|
||||
if (!buffer)
|
||||
return;
|
||||
if (!ifRow)
|
||||
{
|
||||
*buffer = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!memcmp(&transport, TRANSPORT_NBT, sizeof(ULONG)))
|
||||
name = NBT_TRANSPORT_NAME_HEADER;
|
||||
else
|
||||
name = UNKNOWN_TRANSPORT_NAME_HEADER;
|
||||
|
||||
for (ptr1 = buffer; *name && ptr1 < buffer + len; ptr1++, name++)
|
||||
*ptr1 = *name;
|
||||
for (ptr2 = ifRow->wszName; *ptr2 && ptr1 < buffer + len; ptr1++, ptr2++)
|
||||
*ptr1 = *ptr2;
|
||||
*ptr1 = '\0';
|
||||
}
|
||||
|
||||
struct WkstaTransportEnumData
|
||||
{
|
||||
UCHAR n_adapt;
|
||||
UCHAR n_read;
|
||||
DWORD prefmaxlen;
|
||||
LPBYTE *pbuf;
|
||||
NET_API_STATUS ret;
|
||||
};
|
||||
|
||||
static BOOL WkstaEnumAdaptersCallback(UCHAR totalLANAs, UCHAR lanaIndex,
|
||||
ULONG transport, const NetBIOSAdapterImpl *data, void *closure)
|
||||
{
|
||||
BOOL ret;
|
||||
struct WkstaTransportEnumData *enumData = (struct WkstaTransportEnumData *)
|
||||
closure;
|
||||
|
||||
if (enumData && enumData->pbuf)
|
||||
{
|
||||
if (lanaIndex == 0)
|
||||
{
|
||||
DWORD toAllocate;
|
||||
|
||||
enumData->n_adapt = totalLANAs;
|
||||
enumData->n_read = 0;
|
||||
|
||||
toAllocate = totalLANAs * (sizeof(WKSTA_TRANSPORT_INFO_0)
|
||||
+ MAX_TRANSPORT_NAME * sizeof(WCHAR) +
|
||||
MAX_TRANSPORT_ADDR * sizeof(WCHAR));
|
||||
if (enumData->prefmaxlen != MAX_PREFERRED_LENGTH)
|
||||
toAllocate = enumData->prefmaxlen;
|
||||
NetApiBufferAllocate(toAllocate, (LPVOID *)enumData->pbuf);
|
||||
}
|
||||
if (*(enumData->pbuf))
|
||||
{
|
||||
UCHAR spaceFor;
|
||||
|
||||
if (enumData->prefmaxlen == MAX_PREFERRED_LENGTH)
|
||||
spaceFor = totalLANAs;
|
||||
else
|
||||
spaceFor = enumData->prefmaxlen /
|
||||
(sizeof(WKSTA_TRANSPORT_INFO_0) + (MAX_TRANSPORT_NAME +
|
||||
MAX_TRANSPORT_ADDR) * sizeof(WCHAR));
|
||||
if (enumData->n_read < spaceFor)
|
||||
{
|
||||
PWKSTA_TRANSPORT_INFO_0 ti;
|
||||
LPWSTR transport_name, transport_addr;
|
||||
MIB_IFROW ifRow;
|
||||
|
||||
ti = (PWKSTA_TRANSPORT_INFO_0)(*(enumData->pbuf) +
|
||||
enumData->n_read * sizeof(WKSTA_TRANSPORT_INFO_0));
|
||||
transport_name = (LPWSTR)(*(enumData->pbuf) +
|
||||
totalLANAs * sizeof(WKSTA_TRANSPORT_INFO_0) +
|
||||
enumData->n_read * MAX_TRANSPORT_NAME * sizeof(WCHAR));
|
||||
transport_addr = (LPWSTR)(*(enumData->pbuf) +
|
||||
totalLANAs * (sizeof(WKSTA_TRANSPORT_INFO_0) +
|
||||
MAX_TRANSPORT_NAME * sizeof(WCHAR)) +
|
||||
enumData->n_read * MAX_TRANSPORT_ADDR * sizeof(WCHAR));
|
||||
|
||||
ifRow.dwIndex = data->ifIndex;
|
||||
GetIfEntry(&ifRow);
|
||||
ti->wkti0_quality_of_service = 0;
|
||||
ti->wkti0_number_of_vcs = 0;
|
||||
ti->wkti0_transport_name = transport_name;
|
||||
wprint_name(ti->wkti0_transport_name, MAX_TRANSPORT_NAME,
|
||||
transport, &ifRow);
|
||||
ti->wkti0_transport_address = transport_addr;
|
||||
wprint_mac(ti->wkti0_transport_address, MAX_TRANSPORT_ADDR,
|
||||
&ifRow);
|
||||
if (!memcmp(&transport, TRANSPORT_NBT, sizeof(ULONG)))
|
||||
ti->wkti0_wan_ish = TRUE;
|
||||
else
|
||||
ti->wkti0_wan_ish = FALSE;
|
||||
TRACE("%d of %d:ti at %p\n", lanaIndex, totalLANAs, ti);
|
||||
TRACE("transport_name at %p %s\n",
|
||||
ti->wkti0_transport_name,
|
||||
debugstr_w(ti->wkti0_transport_name));
|
||||
TRACE("transport_address at %p %s\n",
|
||||
ti->wkti0_transport_address,
|
||||
debugstr_w(ti->wkti0_transport_address));
|
||||
enumData->n_read++;
|
||||
enumData->ret = NERR_Success;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
enumData->ret = ERROR_MORE_DATA;
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
enumData->ret = ERROR_OUTOFMEMORY;
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI
|
||||
NetWkstaTransportEnum(LPWSTR ServerName, DWORD level, PBYTE* pbuf,
|
||||
DWORD prefmaxlen, LPDWORD read_entries,
|
||||
PDWORD total_entries, PDWORD hresume)
|
||||
{
|
||||
NET_API_STATUS ret;
|
||||
|
||||
TRACE(":%s, 0x%08lx, %p, 0x%08lx, %p, %p, %p\n", debugstr_w(ServerName),
|
||||
level, pbuf, prefmaxlen, read_entries, total_entries,hresume);
|
||||
if (!NETAPI_IsLocalComputer(ServerName))
|
||||
{
|
||||
FIXME(":not implemented for non-local computers\n");
|
||||
ret = ERROR_INVALID_LEVEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hresume && *hresume)
|
||||
{
|
||||
FIXME(":resume handle not implemented\n");
|
||||
return ERROR_INVALID_LEVEL;
|
||||
}
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case 0: /* transport info */
|
||||
{
|
||||
ULONG allTransports;
|
||||
struct WkstaTransportEnumData enumData;
|
||||
|
||||
if (NetBIOSNumAdapters() == 0)
|
||||
return ERROR_NETWORK_UNREACHABLE;
|
||||
if (!read_entries)
|
||||
return STATUS_ACCESS_VIOLATION;
|
||||
if (!total_entries || !pbuf)
|
||||
return RPC_X_NULL_REF_POINTER;
|
||||
|
||||
enumData.prefmaxlen = prefmaxlen;
|
||||
enumData.pbuf = pbuf;
|
||||
memcpy(&allTransports, ALL_TRANSPORTS, sizeof(ULONG));
|
||||
NetBIOSEnumAdapters(allTransports, WkstaEnumAdaptersCallback,
|
||||
&enumData);
|
||||
*read_entries = enumData.n_read;
|
||||
*total_entries = enumData.n_adapt;
|
||||
if (hresume) *hresume= 0;
|
||||
ret = enumData.ret;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERR("Invalid level %ld is specified\n", level);
|
||||
ret = ERROR_INVALID_LEVEL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
* NetWkstaUserGetInfo (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetWkstaUserGetInfo(LPWSTR reserved, DWORD level,
|
||||
PBYTE* bufptr)
|
||||
{
|
||||
TRACE("(%s, %ld, %p)\n", debugstr_w(reserved), level, bufptr);
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
PWKSTA_USER_INFO_0 ui;
|
||||
DWORD dwSize = UNLEN + 1;
|
||||
|
||||
/* set up buffer */
|
||||
NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_0) + dwSize * sizeof(WCHAR),
|
||||
(LPVOID *) bufptr);
|
||||
|
||||
ui = (PWKSTA_USER_INFO_0) *bufptr;
|
||||
ui->wkui0_username = (LPWSTR) (*bufptr + sizeof(WKSTA_USER_INFO_0));
|
||||
|
||||
/* get data */
|
||||
if (!GetUserNameW(ui->wkui0_username, &dwSize))
|
||||
{
|
||||
NetApiBufferFree(ui);
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
else
|
||||
NetApiBufferReallocate(
|
||||
*bufptr, sizeof(WKSTA_USER_INFO_0) +
|
||||
(lstrlenW(ui->wkui0_username) + 1) * sizeof(WCHAR),
|
||||
(LPVOID *) bufptr);
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
PWKSTA_USER_INFO_1 ui;
|
||||
PWKSTA_USER_INFO_0 ui0;
|
||||
DWORD dwSize;
|
||||
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
LSA_HANDLE PolicyHandle;
|
||||
PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo;
|
||||
NTSTATUS NtStatus;
|
||||
|
||||
/* sizes of the field buffers in WCHARS */
|
||||
int username_sz, logon_domain_sz, oth_domains_sz, logon_server_sz;
|
||||
|
||||
FIXME("Level 1 processing is partially implemented\n");
|
||||
oth_domains_sz = 1;
|
||||
logon_server_sz = 1;
|
||||
|
||||
/* get some information first to estimate size of the buffer */
|
||||
ui0 = NULL;
|
||||
NetWkstaUserGetInfo(NULL, 0, (PBYTE *) &ui0);
|
||||
username_sz = lstrlenW(ui0->wkui0_username) + 1;
|
||||
|
||||
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
|
||||
NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes,
|
||||
POLICY_VIEW_LOCAL_INFORMATION,
|
||||
&PolicyHandle);
|
||||
if (NtStatus != STATUS_SUCCESS)
|
||||
{
|
||||
ERR("LsaOpenPolicyFailed with NT status %lx\n",
|
||||
LsaNtStatusToWinError(NtStatus));
|
||||
NetApiBufferFree(ui0);
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation,
|
||||
(PVOID*) &DomainInfo);
|
||||
logon_domain_sz = lstrlenW(DomainInfo->DomainName.Buffer) + 1;
|
||||
LsaClose(PolicyHandle);
|
||||
|
||||
/* set up buffer */
|
||||
NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1) +
|
||||
(username_sz + logon_domain_sz +
|
||||
oth_domains_sz + logon_server_sz) * sizeof(WCHAR),
|
||||
(LPVOID *) bufptr);
|
||||
ui = (WKSTA_USER_INFO_1 *) *bufptr;
|
||||
ui->wkui1_username = (LPWSTR) (*bufptr + sizeof(WKSTA_USER_INFO_1));
|
||||
ui->wkui1_logon_domain = (LPWSTR) (
|
||||
((PBYTE) ui->wkui1_username) + username_sz * sizeof(WCHAR));
|
||||
ui->wkui1_oth_domains = (LPWSTR) (
|
||||
((PBYTE) ui->wkui1_logon_domain) +
|
||||
logon_domain_sz * sizeof(WCHAR));
|
||||
ui->wkui1_logon_server = (LPWSTR) (
|
||||
((PBYTE) ui->wkui1_oth_domains) +
|
||||
oth_domains_sz * sizeof(WCHAR));
|
||||
|
||||
/* get data */
|
||||
dwSize = username_sz;
|
||||
lstrcpyW(ui->wkui1_username, ui0->wkui0_username);
|
||||
NetApiBufferFree(ui0);
|
||||
|
||||
lstrcpynW(ui->wkui1_logon_domain, DomainInfo->DomainName.Buffer,
|
||||
logon_domain_sz);
|
||||
LsaFreeMemory(DomainInfo);
|
||||
|
||||
/* FIXME. Not implemented. Populated with empty strings */
|
||||
ui->wkui1_oth_domains[0] = 0;
|
||||
ui->wkui1_logon_server[0] = 0;
|
||||
break;
|
||||
}
|
||||
case 1101:
|
||||
{
|
||||
PWKSTA_USER_INFO_1101 ui;
|
||||
DWORD dwSize = 1;
|
||||
|
||||
FIXME("Stub. Level 1101 processing is not implemented\n");
|
||||
/* FIXME see also wkui1_oth_domains for level 1 */
|
||||
|
||||
/* set up buffer */
|
||||
NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1101) + dwSize * sizeof(WCHAR),
|
||||
(LPVOID *) bufptr);
|
||||
|
||||
ui = (PWKSTA_USER_INFO_1101) *bufptr;
|
||||
ui->wkui1101_oth_domains = (LPWSTR)(ui + 1);
|
||||
|
||||
/* get data */
|
||||
ui->wkui1101_oth_domains[0] = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERR("Invalid level %ld is specified\n", level);
|
||||
return ERROR_INVALID_LEVEL;
|
||||
}
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetpGetComputerName (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetpGetComputerName(LPWSTR *Buffer)
|
||||
{
|
||||
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
|
||||
TRACE("(%p)\n", Buffer);
|
||||
NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) Buffer);
|
||||
if (GetComputerNameW(*Buffer, &dwSize))
|
||||
{
|
||||
NetApiBufferReallocate(
|
||||
*Buffer, dwSize * sizeof(WCHAR),
|
||||
(LPVOID *) Buffer);
|
||||
return NERR_Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
NetApiBufferFree(*Buffer);
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI NetWkstaGetInfo( LPWSTR servername, DWORD level,
|
||||
LPBYTE* bufptr)
|
||||
{
|
||||
NET_API_STATUS ret;
|
||||
|
||||
TRACE("%p %ld %p\n", debugstr_w( servername ), level, bufptr );
|
||||
if (servername)
|
||||
{
|
||||
FIXME("remote computers not supported\n");
|
||||
return ERROR_INVALID_LEVEL;
|
||||
}
|
||||
if (!bufptr) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case 100:
|
||||
{
|
||||
DWORD computerNameLen, domainNameLen, size;
|
||||
WCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
LSA_HANDLE PolicyHandle;
|
||||
NTSTATUS NtStatus;
|
||||
|
||||
computerNameLen = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
GetComputerNameW(computerName, &computerNameLen);
|
||||
computerNameLen++; /* include NULL terminator */
|
||||
|
||||
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
|
||||
NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes,
|
||||
POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle);
|
||||
if (NtStatus != STATUS_SUCCESS)
|
||||
ret = LsaNtStatusToWinError(NtStatus);
|
||||
else
|
||||
{
|
||||
PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo;
|
||||
|
||||
LsaQueryInformationPolicy(PolicyHandle,
|
||||
PolicyAccountDomainInformation, (PVOID*)&DomainInfo);
|
||||
domainNameLen = lstrlenW(DomainInfo->DomainName.Buffer) + 1;
|
||||
size = sizeof(WKSTA_INFO_100) + computerNameLen * sizeof(WCHAR)
|
||||
+ domainNameLen * sizeof(WCHAR);
|
||||
ret = NetApiBufferAllocate(size, (LPVOID *)bufptr);
|
||||
if (ret == NERR_Success)
|
||||
{
|
||||
PWKSTA_INFO_100 info = (PWKSTA_INFO_100)*bufptr;
|
||||
OSVERSIONINFOW verInfo;
|
||||
|
||||
info->wki100_platform_id = PLATFORM_ID_NT;
|
||||
info->wki100_computername = (LPWSTR)(*bufptr +
|
||||
sizeof(WKSTA_INFO_100));
|
||||
memcpy(info->wki100_computername, computerName,
|
||||
computerNameLen * sizeof(WCHAR));
|
||||
info->wki100_langroup = (LPWSTR)(*bufptr +
|
||||
sizeof(WKSTA_INFO_100) + computerNameLen * sizeof(WCHAR));
|
||||
memcpy(info->wki100_langroup, DomainInfo->DomainName.Buffer,
|
||||
domainNameLen * sizeof(WCHAR));
|
||||
memset(&verInfo, 0, sizeof(verInfo));
|
||||
verInfo.dwOSVersionInfoSize = sizeof(verInfo);
|
||||
GetVersionExW(&verInfo);
|
||||
info->wki100_ver_major = verInfo.dwMajorVersion;
|
||||
info->wki100_ver_minor = verInfo.dwMinorVersion;
|
||||
}
|
||||
LsaFreeMemory(DomainInfo);
|
||||
LsaClose(PolicyHandle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("level %ld unimplemented\n", level);
|
||||
ret = ERROR_INVALID_LEVEL;
|
||||
}
|
||||
return ret;
|
||||
}
|
Loading…
Reference in a new issue