From c606eeb39a3b742e932b4534c8a14085d8d4adec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 31 Dec 2004 15:06:50 +0000 Subject: [PATCH] Import and merge Wine-20041201 svn path=/trunk/; revision=12551 --- reactos/lib/mpr/Makefile | 9 + reactos/lib/mpr/Makefile.in | 21 + reactos/lib/mpr/Makefile.ros-template | 17 + reactos/lib/mpr/auth.c | 95 ++ reactos/lib/mpr/mpr.rc | 33 + reactos/lib/mpr/mpr.spec | 116 ++ reactos/lib/mpr/mpr_Cs.rc | 26 + reactos/lib/mpr/mpr_De.rc | 26 + reactos/lib/mpr/mpr_En.rc | 26 + reactos/lib/mpr/mpr_Es.rc | 26 + reactos/lib/mpr/mpr_It.rc | 26 + reactos/lib/mpr/mpr_Ja.rc | 26 + reactos/lib/mpr/mpr_Nl.rc | 26 + reactos/lib/mpr/mpr_Pt.rc | 26 + reactos/lib/mpr/mpr_main.c | 100 ++ reactos/lib/mpr/mprres.h | 23 + reactos/lib/mpr/multinet.c | 81 + reactos/lib/mpr/nps.c | 129 ++ reactos/lib/mpr/pwcache.c | 315 ++++ reactos/lib/mpr/version.rc | 28 + reactos/lib/mpr/wnet.c | 2045 +++++++++++++++++++++++++ reactos/lib/mpr/wnetpriv.h | 27 + 22 files changed, 3247 insertions(+) create mode 100644 reactos/lib/mpr/Makefile create mode 100644 reactos/lib/mpr/Makefile.in create mode 100644 reactos/lib/mpr/Makefile.ros-template create mode 100644 reactos/lib/mpr/auth.c create mode 100644 reactos/lib/mpr/mpr.rc create mode 100644 reactos/lib/mpr/mpr.spec create mode 100644 reactos/lib/mpr/mpr_Cs.rc create mode 100644 reactos/lib/mpr/mpr_De.rc create mode 100644 reactos/lib/mpr/mpr_En.rc create mode 100644 reactos/lib/mpr/mpr_Es.rc create mode 100644 reactos/lib/mpr/mpr_It.rc create mode 100644 reactos/lib/mpr/mpr_Ja.rc create mode 100644 reactos/lib/mpr/mpr_Nl.rc create mode 100644 reactos/lib/mpr/mpr_Pt.rc create mode 100644 reactos/lib/mpr/mpr_main.c create mode 100644 reactos/lib/mpr/mprres.h create mode 100644 reactos/lib/mpr/multinet.c create mode 100644 reactos/lib/mpr/nps.c create mode 100644 reactos/lib/mpr/pwcache.c create mode 100644 reactos/lib/mpr/version.rc create mode 100644 reactos/lib/mpr/wnet.c create mode 100644 reactos/lib/mpr/wnetpriv.h diff --git a/reactos/lib/mpr/Makefile b/reactos/lib/mpr/Makefile new file mode 100644 index 00000000000..9167641e668 --- /dev/null +++ b/reactos/lib/mpr/Makefile @@ -0,0 +1,9 @@ +# $Id: Makefile 7970 2004-02-01 19:48:44Z gvg $ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = winedll + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk diff --git a/reactos/lib/mpr/Makefile.in b/reactos/lib/mpr/Makefile.in new file mode 100644 index 00000000000..87005abd05f --- /dev/null +++ b/reactos/lib/mpr/Makefile.in @@ -0,0 +1,21 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = mpr.dll +IMPORTS = user32 advapi32 kernel32 +EXTRALIBS = $(LIBUNICODE) + +C_SRCS = \ + auth.c \ + mpr_main.c \ + multinet.c \ + nps.c \ + pwcache.c \ + wnet.c + +RC_SRCS = mpr.rc + +@MAKE_DLL_RULES@ + +### Dependencies: diff --git a/reactos/lib/mpr/Makefile.ros-template b/reactos/lib/mpr/Makefile.ros-template new file mode 100644 index 00000000000..27a0d91ebcf --- /dev/null +++ b/reactos/lib/mpr/Makefile.ros-template @@ -0,0 +1,17 @@ +# $Id: Makefile.ros-template 11910 2004-12-03 23:37:44Z blight $ + +TARGET_NAME = mpr + +TARGET_OBJECTS = @C_SRCS@ + +TARGET_CFLAGS = -D__REACTOS__ + +TARGET_SDKLIBS = @IMPORTS@ kernel32.a wine.a ntdll.a + +TARGET_BASE = $(TARGET_BASE_LIB_MPR) + +default: all + +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(TOOLS_PATH)/depend.mk diff --git a/reactos/lib/mpr/auth.c b/reactos/lib/mpr/auth.c new file mode 100644 index 00000000000..f18751032f9 --- /dev/null +++ b/reactos/lib/mpr/auth.c @@ -0,0 +1,95 @@ +/* + * MPR Authentication and Logon functions + * + * Copyright 1999 Ulrich Weigand + * + * 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 + +#include "windef.h" +#include "winbase.h" +#include "winnetwk.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mpr); + + +/***************************************************************** + * WNetLogoffA [MPR.@] + */ +DWORD WINAPI WNetLogoffA( LPCSTR lpProvider, HWND hwndOwner ) +{ + FIXME( "(%s, %p): stub\n", debugstr_a(lpProvider), hwndOwner ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetLogoffW [MPR.@] + */ +DWORD WINAPI WNetLogoffW( LPCWSTR lpProvider, HWND hwndOwner ) +{ + FIXME( "(%s, %p): stub\n", debugstr_w(lpProvider), hwndOwner ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetLogonA [MPR.@] + */ +DWORD WINAPI WNetLogonA( LPCSTR lpProvider, HWND hwndOwner ) +{ + FIXME( "(%s, %p): stub\n", debugstr_a(lpProvider), hwndOwner ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetLogonW [MPR.@] + */ +DWORD WINAPI WNetLogonW( LPCWSTR lpProvider, HWND hwndOwner ) +{ + FIXME( "(%s, %p): stub\n", debugstr_w(lpProvider), hwndOwner ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetVerifyPasswordA [MPR.@] + */ +DWORD WINAPI WNetVerifyPasswordA( LPCSTR lpszPassword, BOOL *pfMatch ) +{ + FIXME( "(%p, %p): stub\n", lpszPassword, pfMatch ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetVerifyPasswordW [MPR.@] + */ +DWORD WINAPI WNetVerifyPasswordW( LPCWSTR lpszPassword, BOOL *pfMatch ) +{ + FIXME( "(%p, %p): stub\n", lpszPassword, pfMatch ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} diff --git a/reactos/lib/mpr/mpr.rc b/reactos/lib/mpr/mpr.rc new file mode 100644 index 00000000000..d6fdfe7be7d --- /dev/null +++ b/reactos/lib/mpr/mpr.rc @@ -0,0 +1,33 @@ +/* + * MPR dll resources + * + * Copyright (C) 2004 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 "windef.h" +#include "winbase.h" +#include "mprres.h" + +#include "version.rc" + +#include "mpr_Cs.rc" +#include "mpr_De.rc" +#include "mpr_En.rc" +#include "mpr_Nl.rc" +#include "mpr_Es.rc" +#include "mpr_It.rc" +#include "mpr_Ja.rc" +#include "mpr_Pt.rc" diff --git a/reactos/lib/mpr/mpr.spec b/reactos/lib/mpr/mpr.spec new file mode 100644 index 00000000000..c3afdadbfc6 --- /dev/null +++ b/reactos/lib/mpr/mpr.spec @@ -0,0 +1,116 @@ +# ordinal exports + 1 stub @ + 2 stub @ + 3 stub @ + 4 stub @ + 5 stub @ + 6 stub @ + 7 stub @ + 8 stub @ + 9 stub @ +12 stub @ +13 stub @ +14 stub @ +15 stub @ +16 stub @ +17 stub @ +18 stub @ +19 stub @ +20 stub @ +21 stub @ +22 stdcall @(long) MPR_Alloc +23 stdcall @(ptr long) MPR_ReAlloc +24 stdcall @(ptr) MPR_Free +25 stdcall @(ptr long) _MPR_25 + +@ stdcall -private DllCanUnloadNow() MPR_DllCanUnloadNow +@ stub DllGetClassObject +@ stdcall MultinetGetConnectionPerformanceA(ptr ptr) +@ stdcall MultinetGetConnectionPerformanceW(ptr ptr) +@ stdcall MultinetGetErrorTextA(long ptr long) +@ stdcall MultinetGetErrorTextW(long ptr long) +@ stdcall NPSAuthenticationDialogA(ptr) +@ stdcall NPSCopyStringA(str ptr ptr) +@ stdcall NPSDeviceGetNumberA(str ptr ptr) +@ stdcall NPSDeviceGetStringA(long long ptr long) +@ stdcall NPSGetProviderHandleA(ptr) +@ stdcall NPSGetProviderNameA(long ptr) +@ stdcall NPSGetSectionNameA(long ptr) +@ stdcall NPSNotifyGetContextA(ptr) +@ stdcall NPSNotifyRegisterA(long ptr) +@ stdcall NPSSetCustomTextA(str) +@ stdcall NPSSetExtendedErrorA(long str) +@ stub PwdChangePasswordA +@ stub PwdChangePasswordW +@ stub PwdGetPasswordStatusA +@ stub PwdGetPasswordStatusW +@ stub PwdSetPasswordStatusA +@ stub PwdSetPasswordStatusW +@ stdcall WNetAddConnection2A(ptr str str long) +@ stdcall WNetAddConnection2W(ptr wstr wstr long) +@ stdcall WNetAddConnection3A(long ptr str str long) +@ stdcall WNetAddConnection3W(long ptr wstr wstr long) +@ stdcall WNetAddConnectionA(str str str) +@ stdcall WNetAddConnectionW(wstr wstr wstr) +@ stdcall WNetCachePassword(str long str long long long) +@ stdcall WNetCancelConnection2A(str long long) +@ stdcall WNetCancelConnection2W(wstr long long) +@ stdcall WNetCancelConnectionA(str long) +@ stdcall WNetCancelConnectionW(wstr long) +@ stdcall WNetCloseEnum(long) +@ stdcall WNetConnectionDialog1A(ptr) +@ stdcall WNetConnectionDialog1W(ptr) +@ stdcall WNetConnectionDialog(long long) +@ stdcall WNetDisconnectDialog1A(ptr) +@ stdcall WNetDisconnectDialog1W(ptr) +@ stdcall WNetDisconnectDialog(long long) +@ stdcall WNetEnumCachedPasswords(str long long ptr long) +@ stdcall WNetEnumResourceA(long ptr ptr ptr) +@ stdcall WNetEnumResourceW(long ptr ptr ptr) +@ stub WNetFormatNetworkNameA +@ stub WNetFormatNetworkNameW +@ stdcall WNetGetCachedPassword(ptr long ptr ptr long) +@ stdcall WNetGetConnectionA(str ptr ptr) +@ stdcall WNetGetConnectionW(wstr ptr ptr) +@ stub WNetGetHomeDirectoryA +@ stub WNetGetHomeDirectoryW +@ stdcall WNetGetLastErrorA(ptr ptr long ptr long) +@ stdcall WNetGetLastErrorW(ptr ptr long ptr long) +@ stdcall WNetGetNetworkInformationA(str ptr) +@ stdcall WNetGetNetworkInformationW(wstr ptr) +@ stdcall WNetGetProviderNameA(long ptr ptr) +@ stdcall WNetGetProviderNameW(long ptr ptr) +@ stdcall WNetGetResourceInformationA(ptr ptr ptr ptr) +@ stdcall WNetGetResourceInformationW(ptr ptr ptr ptr) +@ stdcall WNetGetResourceParentA(ptr ptr ptr) +@ stdcall WNetGetResourceParentW(ptr ptr ptr) +@ stdcall WNetGetUniversalNameA (str long ptr ptr) +@ stdcall WNetGetUniversalNameW (wstr long ptr ptr) +@ stdcall WNetGetUserA(str ptr ptr) +@ stdcall WNetGetUserW(wstr wstr ptr) +@ stdcall WNetLogoffA(str long) +@ stdcall WNetLogoffW(wstr long) +@ stdcall WNetLogonA(str long) +@ stdcall WNetLogonW(wstr long) +@ stdcall WNetOpenEnumA(long long long ptr ptr) +@ stdcall WNetOpenEnumW(long long long ptr ptr) +@ stdcall WNetRemoveCachedPassword(long long long) +@ stdcall WNetRestoreConnectionA(long str) +@ stdcall WNetRestoreConnectionW(long wstr) +@ stdcall WNetSetConnectionA(str long ptr) +@ stdcall WNetSetConnectionW(wstr long ptr) +@ stdcall WNetUseConnectionA(long ptr str str long str ptr ptr) +@ stdcall WNetUseConnectionW(long ptr wstr wstr long wstr ptr ptr) +@ stdcall WNetVerifyPasswordA(str ptr) +@ stdcall WNetVerifyPasswordW(wstr ptr) + +#additions, not in win95 mpr.dll +@ stub WNetRestoreConnection +@ stub WNetLogonNotify +@ stub WNetPasswordChangeNotify +@ stub WNetGetPropertyTextA +@ stub WNetPropertyDialogA +@ stub WNetGetDirectoryTypeA +@ stub WNetFMXGetPermHelp +@ stub WNetFMXEditPerm +@ stub WNetFMXGetPermCaps diff --git a/reactos/lib/mpr/mpr_Cs.rc b/reactos/lib/mpr/mpr_Cs.rc new file mode 100644 index 00000000000..6b9ac4cbebe --- /dev/null +++ b/reactos/lib/mpr/mpr_Cs.rc @@ -0,0 +1,26 @@ +/* + * Czech MPR dll resources + * Copyright (C) 2004 Juan Lang + * Copyright (C) 2004 David Kredba + * + * 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 + */ + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Cel s" +} diff --git a/reactos/lib/mpr/mpr_De.rc b/reactos/lib/mpr/mpr_De.rc new file mode 100644 index 00000000000..7cfa8531822 --- /dev/null +++ b/reactos/lib/mpr/mpr_De.rc @@ -0,0 +1,26 @@ +/* + * MPR dll resources + * + * Copyright (C) 2004 Henning Gerhardt + * + * 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 + */ + +LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Gesamtes Netzwerk" +} diff --git a/reactos/lib/mpr/mpr_En.rc b/reactos/lib/mpr/mpr_En.rc new file mode 100644 index 00000000000..31f4e928845 --- /dev/null +++ b/reactos/lib/mpr/mpr_En.rc @@ -0,0 +1,26 @@ +/* + * MPR dll resources + * + * Copyright (C) 2004 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 + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Entire Network" +} diff --git a/reactos/lib/mpr/mpr_Es.rc b/reactos/lib/mpr/mpr_Es.rc new file mode 100644 index 00000000000..8ee191ae4e2 --- /dev/null +++ b/reactos/lib/mpr/mpr_Es.rc @@ -0,0 +1,26 @@ +/* + * MPR dll Spanish resources + * + * Copyright (C) 2004 Jos Manuel Ferrer Ortiz + * + * 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 + */ + +LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Toda la red" +} diff --git a/reactos/lib/mpr/mpr_It.rc b/reactos/lib/mpr/mpr_It.rc new file mode 100644 index 00000000000..4fc03a4026b --- /dev/null +++ b/reactos/lib/mpr/mpr_It.rc @@ -0,0 +1,26 @@ +/* + * MPR dll Italian resources + * + * Copyright 2004 Ivan Leo Puoti + * + * 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 + */ + +LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Tutta la rete" +} diff --git a/reactos/lib/mpr/mpr_Ja.rc b/reactos/lib/mpr/mpr_Ja.rc new file mode 100644 index 00000000000..1adcbbf59f1 --- /dev/null +++ b/reactos/lib/mpr/mpr_Ja.rc @@ -0,0 +1,26 @@ +/* + * MPR dll resources + * + * Copyright (C) 2004 Hajime Segawa + * + * 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 + */ + +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "lbg[NS" +} diff --git a/reactos/lib/mpr/mpr_Nl.rc b/reactos/lib/mpr/mpr_Nl.rc new file mode 100644 index 00000000000..dd7a79a2d35 --- /dev/null +++ b/reactos/lib/mpr/mpr_Nl.rc @@ -0,0 +1,26 @@ +/* + * Dutch resources for MPR + * + * Copyright (C) 2004 Hans Leidekker + * + * 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 + */ + +LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Gehele netwerk" +} diff --git a/reactos/lib/mpr/mpr_Pt.rc b/reactos/lib/mpr/mpr_Pt.rc new file mode 100644 index 00000000000..5ad2f9f7f99 --- /dev/null +++ b/reactos/lib/mpr/mpr_Pt.rc @@ -0,0 +1,26 @@ +/* + * MPR dll resources + * + * Copyright (C) 2004 Marcelo Duarte + * + * 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 + */ + +LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Toda a rede" +} diff --git a/reactos/lib/mpr/mpr_main.c b/reactos/lib/mpr/mpr_main.c new file mode 100644 index 00000000000..a1a9ec4e928 --- /dev/null +++ b/reactos/lib/mpr/mpr_main.c @@ -0,0 +1,100 @@ +/* + * MPR undocumented functions + * + * Copyright 1999 Ulrich Weigand + * + * 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 + +#include "windef.h" +#include "winbase.h" +#include "winnetwk.h" +#include "wine/debug.h" +#include "wnetpriv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mpr); + + /* + * FIXME: The following routines should use a private heap ... + */ + +/***************************************************************** + * @ [MPR.22] + */ +LPVOID WINAPI MPR_Alloc( DWORD dwSize ) +{ + return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize ); +} + +/***************************************************************** + * @ [MPR.23] + */ +LPVOID WINAPI MPR_ReAlloc( LPVOID lpSrc, DWORD dwSize ) +{ + if ( lpSrc ) + return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpSrc, dwSize ); + else + return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize ); +} + +/***************************************************************** + * @ [MPR.24] + */ +BOOL WINAPI MPR_Free( LPVOID lpMem ) +{ + if ( lpMem ) + return HeapFree( GetProcessHeap(), 0, lpMem ); + else + return FALSE; +} + +/***************************************************************** + * @ [MPR.25] + */ +BOOL WINAPI _MPR_25( LPBYTE lpMem, INT len ) +{ + FIXME( "(%p, %d): stub\n", lpMem, len ); + + return FALSE; +} + +/***************************************************************** + * DllCanUnloadNow [MPR.@] + */ +DWORD WINAPI MPR_DllCanUnloadNow(void) +{ + FIXME("Stub\n"); + return S_OK; +} + +/***************************************************************** + * DllMain [MPR.init] + */ +BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls( hinstDLL ); + wnetInit(hinstDLL); + break; + + case DLL_PROCESS_DETACH: + wnetFree(); + break; + } + return TRUE; +} diff --git a/reactos/lib/mpr/mprres.h b/reactos/lib/mpr/mprres.h new file mode 100644 index 00000000000..cc8f0108758 --- /dev/null +++ b/reactos/lib/mpr/mprres.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2004 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_MPRRES_H__ +#define __WINE_MPRRES_H__ + +#define IDS_ENTIRENETWORK 1 + +#endif /* ndef __WINE_MPRRES_H__ */ diff --git a/reactos/lib/mpr/multinet.c b/reactos/lib/mpr/multinet.c new file mode 100644 index 00000000000..3c41367b625 --- /dev/null +++ b/reactos/lib/mpr/multinet.c @@ -0,0 +1,81 @@ +/* + * MPR Multinet functions + * + * Copyright 1999 Ulrich Weigand + * + * 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 + +#include "windef.h" +#include "winbase.h" +#include "winnetwk.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mpr); + + +/***************************************************************** + * MultinetGetConnectionPerformanceA [MPR.@] + * + * RETURNS + * Success: NO_ERROR + * Failure: ERROR_NOT_SUPPORTED, ERROR_NOT_CONNECTED, + * ERROR_NO_NET_OR_BAD_PATH, ERROR_BAD_DEVICE, + * ERROR_BAD_NET_NAME, ERROR_INVALID_PARAMETER, + * ERROR_NO_NETWORK, ERROR_EXTENDED_ERROR + */ +DWORD WINAPI MultinetGetConnectionPerformanceA( + LPNETRESOURCEA lpNetResource, + LPNETCONNECTINFOSTRUCT lpNetConnectInfoStruct ) +{ + FIXME( "(%p, %p): stub\n", lpNetResource, lpNetConnectInfoStruct ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * MultinetGetConnectionPerformanceW [MPR.@] + */ +DWORD WINAPI MultinetGetConnectionPerformanceW( + LPNETRESOURCEW lpNetResource, + LPNETCONNECTINFOSTRUCT lpNetConnectInfoStruct ) +{ + FIXME( "(%p, %p): stub\n", lpNetResource, lpNetConnectInfoStruct ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * MultinetGetErrorTextA [MPR.@] + */ +DWORD WINAPI MultinetGetErrorTextA( DWORD x, DWORD y, DWORD z ) +{ + FIXME( "(%lx, %lx, %lx): stub\n", x, y, z ); + return 0; +} + +/***************************************************************** + * MultinetGetErrorTextW [MPR.@] + */ +DWORD WINAPI MultinetGetErrorTextW( DWORD x, DWORD y, DWORD z ) +{ + FIXME( "(%lx, %lx, %lx ): stub\n", x, y, z ); + return 0; +} + diff --git a/reactos/lib/mpr/nps.c b/reactos/lib/mpr/nps.c new file mode 100644 index 00000000000..6a65b74001c --- /dev/null +++ b/reactos/lib/mpr/nps.c @@ -0,0 +1,129 @@ +/* + * MPR Network Provider Services functions + * + * Copyright 1999 Ulrich Weigand + * + * 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 + +#include "windef.h" +#include "winbase.h" +#include "winnetwk.h" +#include "netspi.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mpr); + + +/***************************************************************** + * NPSAuthenticationDialogA [MPR.@] + */ +DWORD WINAPI NPSAuthenticationDialogA( LPAUTHDLGSTRUCTA lpAuthDlgStruct ) +{ + FIXME( "(%p): stub\n", lpAuthDlgStruct ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSGetProviderHandleA [MPR.@] + */ +DWORD WINAPI NPSGetProviderHandleA( PHPROVIDER phProvider ) +{ + FIXME( "(%p): stub\n", phProvider ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSGetProviderNameA [MPR.@] + */ +DWORD WINAPI NPSGetProviderNameA( HPROVIDER hProvider, LPCSTR *lpszProviderName ) +{ + FIXME( "(%p, %p): stub\n", hProvider, lpszProviderName ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSGetSectionNameA [MPR.@] + */ +DWORD WINAPI NPSGetSectionNameA( HPROVIDER hProvider, LPCSTR *lpszSectionName ) +{ + FIXME( "(%p, %p): stub\n", hProvider, lpszSectionName ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSSetExtendedErrorA [MPR.@] + */ +DWORD WINAPI NPSSetExtendedErrorA( DWORD NetSpecificError, LPSTR lpExtendedErrorText ) +{ + FIXME( "(%08lx, %s): stub\n", NetSpecificError, debugstr_a(lpExtendedErrorText) ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSSetCustomTextA [MPR.@] + */ +VOID WINAPI NPSSetCustomTextA( LPSTR lpCustomErrorText ) +{ + FIXME( "(%s): stub\n", debugstr_a(lpCustomErrorText) ); +} + +/***************************************************************** + * NPSCopyStringA [MPR.@] + */ +DWORD WINAPI NPSCopyStringA( LPCSTR lpString, LPVOID lpBuffer, LPDWORD lpdwBufferSize ) +{ + FIXME( "(%s, %p, %p): stub\n", debugstr_a(lpString), lpBuffer, lpdwBufferSize ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSDeviceGetNumberA [MPR.@] + */ +DWORD WINAPI NPSDeviceGetNumberA( LPSTR lpLocalName, LPDWORD lpdwNumber, LPDWORD lpdwType ) +{ + FIXME( "(%s, %p, %p): stub\n", debugstr_a(lpLocalName), lpdwNumber, lpdwType ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSDeviceGetStringA [MPR.@] + */ +DWORD WINAPI NPSDeviceGetStringA( DWORD dwNumber, DWORD dwType, LPSTR lpLocalName, LPDWORD lpdwBufferSize ) +{ + FIXME( "(%ld, %ld, %p, %p): stub\n", dwNumber, dwType, lpLocalName, lpdwBufferSize ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSNotifyRegisterA [MPR.@] + */ +DWORD WINAPI NPSNotifyRegisterA( enum NOTIFYTYPE NotifyType, NOTIFYCALLBACK pfNotifyCallBack ) +{ + FIXME( "(%d, %p): stub\n", NotifyType, pfNotifyCallBack ); + return WN_NOT_SUPPORTED; +} + +/***************************************************************** + * NPSNotifyGetContextA [MPR.@] + */ +LPVOID WINAPI NPSNotifyGetContextA( NOTIFYCALLBACK pfNotifyCallBack ) +{ + FIXME( "(%p): stub\n", pfNotifyCallBack ); + return NULL; +} + diff --git a/reactos/lib/mpr/pwcache.c b/reactos/lib/mpr/pwcache.c new file mode 100644 index 00000000000..5bffc442510 --- /dev/null +++ b/reactos/lib/mpr/pwcache.c @@ -0,0 +1,315 @@ +/* + * MPR Password Cache functions + * + * Copyright 1999 Ulrich Weigand + * Copyright 2003,2004 Mike McCormack for CodeWeavers + * + * 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 +#include + +#include "windef.h" +#include "winbase.h" +#include "winnetwk.h" +#include "winreg.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mpr); + +static const char mpr_key[] = "Software\\Wine\\Wine\\Mpr\\"; + +static inline BYTE hex( BYTE x ) +{ + if( x <= 9 ) + return x + '0'; + return x + 'A' - 10; +} + +static inline CHAR ctox( CHAR x ) +{ + if( ( x >= '0' ) && ( x <= '9' ) ) + return x - '0'; + if( ( x >= 'A' ) && ( x <= 'F' ) ) + return x - 'A' + 10; + if( ( x >= 'a' ) && ( x <= 'a' ) ) + return x - 'a' + 10; + return -1; +} + +static LPSTR MPR_GetValueName( LPSTR pbResource, WORD cbResource, BYTE nType ) +{ + LPSTR name; + DWORD i; + + name = HeapAlloc( GetProcessHeap(), 0, 6+cbResource*2 ); + if( name ) + sprintf( name, "X-%02X-", nType ); + for(i=0; i>4); + name[6+i*2]=hex(pbResource[i]&0x0f); + } + name[5+i*2]=0; + TRACE( "Value is %s\n", name ); + return name; +} + + +/************************************************************************** + * WNetCachePassword [MPR.@] Saves password in cache + * + * NOTES + * only the parameter count is verifyed + * + * ---- everything below this line might be wrong (js) ----- + * RETURNS + * Success: WN_SUCCESS + * Failure: WN_ACCESS_DENIED, WN_BAD_PASSWORD, WN_BADVALUE, WN_NET_ERROR, + * WN_NOT_SUPPORTED, WN_OUT_OF_MEMORY + */ +DWORD WINAPI WNetCachePassword( + LPSTR pbResource, /* [in] Name of workgroup, computer, or resource */ + WORD cbResource, /* [in] Size of name */ + LPSTR pbPassword, /* [in] Buffer containing password */ + WORD cbPassword, /* [in] Size of password */ + BYTE nType, /* [in] Type of password to cache */ + WORD x) + +{ + HKEY hkey; + DWORD r; + LPSTR valname; + + WARN( "(%p(%s), %d, %p(%s), %d, %d, 0x%08x): totally insecure\n", + pbResource, debugstr_a(pbResource), cbResource, + pbPassword, debugstr_a(pbPassword), cbPassword, + nType, x ); + + r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey ); + if( r ) + return WN_ACCESS_DENIED; + + valname = MPR_GetValueName( pbResource, cbResource, nType ); + if( valname ) + { + r = RegSetValueExA( hkey, valname, 0, REG_BINARY, + pbPassword, cbPassword ); + if( r ) + r = WN_CANCEL; + else + r = WN_SUCCESS; + HeapFree( GetProcessHeap(), 0, valname ); + } + else + r = WN_OUT_OF_MEMORY; + + RegCloseKey( hkey ); + + return r; +} + +/***************************************************************** + * WNetRemoveCachedPassword [MPR.@] + */ +UINT WINAPI WNetRemoveCachedPassword( + LPSTR pbResource, /* [in] resource ID to delete */ + WORD cbResource, /* [in] number of bytes in the resource ID */ + BYTE nType ) /* [in] Type of the resource to delete */ +{ + HKEY hkey; + DWORD r; + LPSTR valname; + + WARN( "(%p(%s), %d, %d): totally insecure\n", + pbResource, debugstr_a(pbResource), cbResource, nType ); + + r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey ); + if( r ) + return WN_ACCESS_DENIED; + + valname = MPR_GetValueName( pbResource, cbResource, nType ); + if( valname ) + { + r = RegDeleteValueA( hkey, valname ); + if( r ) + r = WN_ACCESS_DENIED; + else + r = WN_SUCCESS; + HeapFree( GetProcessHeap(), 0, valname ); + } + else + r = WN_OUT_OF_MEMORY; + + return r; +} + +/***************************************************************** + * WNetGetCachedPassword [MPR.@] Retrieves password from cache + * + * NOTES + * the stub seems to be wrong: + * arg1: ptr 0x40xxxxxx -> (no string) + * arg2: len 36 + * arg3: ptr 0x40xxxxxx -> (no string) + * arg4: ptr 0x40xxxxxx -> 0xc8 + * arg5: type? 4 + * + * ---- everything below this line might be wrong (js) ----- + * RETURNS + * Success: WN_SUCCESS + * Failure: WN_ACCESS_DENIED, WN_BAD_PASSWORD, WN_BAD_VALUE, + * WN_NET_ERROR, WN_NOT_SUPPORTED, WN_OUT_OF_MEMORY + */ +DWORD WINAPI WNetGetCachedPassword( + LPSTR pbResource, /* [in] Name of workgroup, computer, or resource */ + WORD cbResource, /* [in] Size of name */ + LPSTR pbPassword, /* [out] Buffer to receive password */ + LPWORD pcbPassword, /* [out] Receives size of password */ + BYTE nType) /* [in] Type of password to retrieve */ +{ + HKEY hkey; + DWORD r, type = 0, sz; + LPSTR valname; + + WARN( "(%p(%s), %d, %p, %p, %d): totally insecure\n", + pbResource, debugstr_a(pbResource), cbResource, + pbPassword, pcbPassword, nType ); + + memset( pbPassword, 0, *pcbPassword); + + r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey ); + if( r ) + return WN_ACCESS_DENIED; + + valname = MPR_GetValueName( pbResource, cbResource, nType ); + if( valname ) + { + sz = *pcbPassword; + r = RegQueryValueExA( hkey, valname, 0, &type, pbPassword, &sz ); + *pcbPassword = sz; + if( r ) + r = WN_CANCEL; + else + r = WN_SUCCESS; + HeapFree( GetProcessHeap(), 0, valname ); + } + else + r = WN_OUT_OF_MEMORY; + + return r; +} + +/******************************************************************* + * WNetEnumCachedPasswords [MPR.@] + * + * NOTES + * the parameter count is verifyed + * + * This function is a huge security risk, as virii and such can use + * it to grab all the passwords in the cache. It's bad enough to + * store the passwords (insecurely). + * + * bpPrefix and cbPrefix are used to filter the returned passwords + * the first cbPrefix bytes of the password resource identifier + * should match the same number of bytes in bpPrefix + * + * RETURNS + * Success: WN_SUCCESS (even if no entries were enumerated) + * Failure: WN_ACCESS_DENIED, WN_BAD_PASSWORD, WN_BAD_VALUE, + * WN_NET_ERROR, WN_NOT_SUPPORTED, WN_OUT_OF_MEMORY + */ + +UINT WINAPI WNetEnumCachedPasswords( + LPSTR pbPrefix, /* [in] prefix to filter cache entries */ + WORD cbPrefix, /* [in] number of bytes in Prefix substring */ + BYTE nType, /* [in] match the Type ID of the entry */ + ENUMPASSWORDPROC enumPasswordProc, /* [in] callback function */ + DWORD param) /* [in] parameter passed to enum function */ +{ + HKEY hkey; + DWORD r, type, val_sz, data_sz, i, j, size; + PASSWORD_CACHE_ENTRY *entry; + CHAR val[256], prefix[6]; + + WARN( "(%s, %d, %d, %p, 0x%08lx) totally insecure\n", + debugstr_an(pbPrefix,cbPrefix), cbPrefix, + nType, enumPasswordProc, param ); + + r = RegCreateKeyA( HKEY_CURRENT_USER, mpr_key, &hkey ); + if( r ) + return WN_ACCESS_DENIED; + + sprintf(prefix, "X-%02X-", nType ); + + i = 0; + for( i=0; ; i++ ) + { + val_sz = sizeof val; + data_sz = 0; + type = 0; + val[0] = 0; + r = RegEnumValueA( hkey, i, val, &val_sz, NULL, &type, NULL, &data_sz ); + if( r != ERROR_SUCCESS ) + break; + if( type != REG_BINARY ) + continue; + + /* check the value is in the format we expect */ + if( val_sz < sizeof prefix ) + continue; + if( memcmp( prefix, val, 5 ) ) + continue; + + /* decode the value */ + for(j=5; jabResource[0] + val_sz + data_sz; + entry = HeapAlloc( GetProcessHeap(), 0, sizeof *entry + val_sz + data_sz ); + memcpy( entry->abResource, val, val_sz ); + entry->cbEntry = size; + entry->cbResource = val_sz; + entry->cbPassword = data_sz; + entry->iEntry = i; + entry->nType = nType; + r = RegEnumValueA( hkey, i, NULL, &val_sz, NULL, &type, + &entry->abResource[val_sz], &data_sz ); + if( r == ERROR_SUCCESS ) + enumPasswordProc( entry, param ); + HeapFree( GetProcessHeap(), 0, entry ); + } + + RegCloseKey( hkey ); + + return WN_SUCCESS; +} diff --git a/reactos/lib/mpr/version.rc b/reactos/lib/mpr/version.rc new file mode 100644 index 00000000000..79a0a13c246 --- /dev/null +++ b/reactos/lib/mpr/version.rc @@ -0,0 +1,28 @@ +/* + * MPR dll version resources + * + * Copyright (C) 2004 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 + */ + +#define WINE_FILEDESCRIPTION_STR "Wine Multiprotocol Router Library" +#define WINE_FILENAME_STR "mpr.dll" +#define WINE_FILEVERSION 5,0,2195,6611 +#define WINE_FILEVERSION_STR "5.00.2195.6611" +#define WINE_PRODUCTVERSION 5,0,2195,6611 +#define WINE_PRODUCTVERSION_STR "5.00.2195.6611" + +#include "wine/wine_common_ver.rc" diff --git a/reactos/lib/mpr/wnet.c b/reactos/lib/mpr/wnet.c new file mode 100644 index 00000000000..67f723c1a23 --- /dev/null +++ b/reactos/lib/mpr/wnet.c @@ -0,0 +1,2045 @@ +/* + * MPR WNet functions + * + * Copyright 1999 Ulrich Weigand + * Copyright 2004 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 +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" +#include "winnetwk.h" +#include "npapi.h" +#include "winreg.h" +#include "winuser.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "mprres.h" +#include "wnetpriv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mpr); + +/* Data structures representing network service providers. Assumes only one + * thread creates them, and that they are constant for the life of the process + * (and therefore doesn't synchronize access). + * FIXME: only basic provider data and enumeration-related data are implemented + * so far, need to implement the rest too. + */ +typedef struct _WNetProvider +{ + HMODULE hLib; + PWSTR name; + PF_NPGetCaps getCaps; + DWORD dwSpecVersion; + DWORD dwNetType; + DWORD dwEnumScopes; + PF_NPOpenEnum openEnum; + PF_NPEnumResource enumResource; + PF_NPCloseEnum closeEnum; +} WNetProvider, *PWNetProvider; + +typedef struct _WNetProviderTable +{ + LPWSTR entireNetwork; + DWORD numAllocated; + DWORD numProviders; + WNetProvider table[1]; +} WNetProviderTable, *PWNetProviderTable; + +#define WNET_ENUMERATOR_TYPE_NULL 0 +#define WNET_ENUMERATOR_TYPE_GLOBAL 1 +#define WNET_ENUMERATOR_TYPE_PROVIDER 2 +#define WNET_ENUMERATOR_TYPE_CONTEXT 3 + +/* An WNet enumerator. Note that the type doesn't correspond to the scope of + * the enumeration; it represents one of the following types: + * - a 'null' enumeration, one that contains no members + * - a global enumeration, one that's executed across all providers + * - a provider-specific enumeration, one that's only executed by a single + * provider + * - a context enumeration. I know this contradicts what I just said about + * there being no correspondence between the scope and the type, but it's + * necessary for the special case that a "Entire Network" entry needs to + * be enumerated in an enumeration of the context scope. Thus an enumeration + * of the context scope results in a context type enumerator, which morphs + * into a global enumeration (so the enumeration continues across all + * providers). + */ +typedef struct _WNetEnumerator +{ + DWORD enumType; + DWORD providerIndex; + HANDLE handle; + BOOL providerDone; + DWORD dwScope; + DWORD dwType; + DWORD dwUsage; + LPNETRESOURCEW lpNet; +} WNetEnumerator, *PWNetEnumerator; + +#define BAD_PROVIDER_INDEX (DWORD)0xffffffff + +/* Returns an index (into the global WNetProviderTable) of the provider with + * the given name, or BAD_PROVIDER_INDEX if not found. + */ +static DWORD _findProviderIndexW(LPCWSTR lpProvider); + +PWNetProviderTable providerTable; + +/* + * Global provider table functions + */ + +static void _tryLoadProvider(PCWSTR provider) +{ + static const WCHAR servicePrefix[] = { 'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'S','e','r','v','i','c','e','s','\\',0 }; + static const WCHAR serviceFmt[] = { '%','s','%','s','\\', + 'N','e','t','w','o','r','k','P','r','o','v','i','d','e','r',0 }; + WCHAR serviceName[MAX_PATH]; + HKEY hKey; + + TRACE("%s\n", debugstr_w(provider)); + snprintfW(serviceName, sizeof(serviceName) / sizeof(WCHAR), serviceFmt, + servicePrefix, provider); + serviceName[sizeof(serviceName) / sizeof(WCHAR) - 1] = '\0'; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, serviceName, 0, KEY_READ, &hKey) == + ERROR_SUCCESS) + { + static const WCHAR szProviderPath[] = { 'P','r','o','v','i','d','e','r', + 'P','a','t','h',0 }; + WCHAR providerPath[MAX_PATH]; + DWORD type, size = sizeof(providerPath); + + if (RegQueryValueExW(hKey, szProviderPath, NULL, &type, + (LPBYTE)providerPath, &size) == ERROR_SUCCESS && type == REG_SZ) + { + static const WCHAR szProviderName[] = { 'N','a','m','e',0 }; + PWSTR name = NULL; + + size = 0; + RegQueryValueExW(hKey, szProviderName, NULL, NULL, NULL, &size); + if (size) + { + name = (PWSTR)HeapAlloc(GetProcessHeap(), 0, size); + if (RegQueryValueExW(hKey, szProviderName, NULL, &type, + (LPBYTE)name, &size) != ERROR_SUCCESS || type != REG_SZ) + { + HeapFree(GetProcessHeap(), 0, name); + name = NULL; + } + } + if (name) + { + HMODULE hLib = LoadLibraryW(providerPath); + + if (hLib) + { + PF_NPGetCaps getCaps = (PF_NPGetCaps)GetProcAddress(hLib, + "NPGetCaps"); + + TRACE("loaded lib %p\n", hLib); + if (getCaps) + { + PWNetProvider provider = + &providerTable->table[providerTable->numProviders]; + + provider->hLib = hLib; + provider->name = name; + TRACE("name is %s\n", debugstr_w(name)); + provider->getCaps = getCaps; + provider->dwSpecVersion = getCaps(WNNC_SPEC_VERSION); + provider->dwNetType = getCaps(WNNC_NET_TYPE); + TRACE("net type is 0x%08lx\n", provider->dwNetType); + provider->dwEnumScopes = getCaps(WNNC_ENUMERATION); + if (provider->dwEnumScopes) + { + TRACE("supports enumeration\n"); + provider->openEnum = (PF_NPOpenEnum) + GetProcAddress(hLib, "NPOpenEnum"); + TRACE("openEnum is %p\n", provider->openEnum); + provider->enumResource = (PF_NPEnumResource) + GetProcAddress(hLib, "NPEnumResource"); + TRACE("enumResource is %p\n", + provider->enumResource); + provider->closeEnum = (PF_NPCloseEnum) + GetProcAddress(hLib, "NPCloseEnum"); + TRACE("closeEnum is %p\n", provider->closeEnum); + if (!provider->openEnum || !provider->enumResource + || !provider->closeEnum) + { + provider->openEnum = NULL; + provider->enumResource = NULL; + provider->closeEnum = NULL; + provider->dwEnumScopes = 0; + WARN("Couldn't load enumeration functions\n"); + } + } + providerTable->numProviders++; + } + else + { + WARN("Provider %s didn't export NPGetCaps\n", + debugstr_w(provider)); + if (name) + HeapFree(GetProcessHeap(), 0, name); + FreeLibrary(hLib); + } + } + else + { + WARN("Couldn't load library %s for provider %s\n", + debugstr_w(providerPath), debugstr_w(provider)); + HeapFree(GetProcessHeap(), 0, name); + } + } + else + { + WARN("Couldn't get provider name for provider %s\n", + debugstr_w(provider)); + } + } + else + WARN("Couldn't open value %s\n", debugstr_w(szProviderPath)); + RegCloseKey(hKey); + } + else + WARN("Couldn't open service key for provider %s\n", + debugstr_w(provider)); +} + +void wnetInit(HINSTANCE hInstDll) +{ + static const WCHAR providerOrderKey[] = { 'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'C','o','n','t','r','o','l','\\', + 'N','e','t','w','o','r','k','P','r','o','v','i','d','e','r','\\', + 'O','r','d','e','r',0 }; + static const WCHAR providerOrder[] = { 'P','r','o','v','i','d','e','r', + 'O','r','d','e','r',0 }; + HKEY hKey; + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, providerOrderKey, 0, KEY_READ, &hKey) + == ERROR_SUCCESS) + { + DWORD size = 0; + + RegQueryValueExW(hKey, providerOrder, NULL, NULL, NULL, &size); + if (size) + { + PWSTR providers = (PWSTR)HeapAlloc(GetProcessHeap(), 0, size); + + if (providers) + { + DWORD type; + + if (RegQueryValueExW(hKey, providerOrder, NULL, &type, + (LPBYTE)providers, &size) == ERROR_SUCCESS && type == REG_SZ) + { + PWSTR ptr; + DWORD numToAllocate; + + TRACE("provider order is %s\n", debugstr_w(providers)); + /* first count commas as a heuristic for how many to + * allocate space for */ + for (ptr = providers, numToAllocate = 1; ptr; ) + { + ptr = strchrW(ptr, ','); + if (ptr) + numToAllocate++; + } + providerTable = (PWNetProviderTable) + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(WNetProviderTable) + + (numToAllocate - 1) * sizeof(WNetProvider)); + if (providerTable) + { + PWSTR ptrPrev; + int entireNetworkLen; + + entireNetworkLen = LoadStringW(hInstDll, + IDS_ENTIRENETWORK, NULL, 0); + providerTable->entireNetwork = (LPWSTR)HeapAlloc( + GetProcessHeap(), 0, (entireNetworkLen + 1) * + sizeof(WCHAR)); + if (providerTable->entireNetwork) + LoadStringW(hInstDll, IDS_ENTIRENETWORK, + providerTable->entireNetwork, + entireNetworkLen + 1); + providerTable->numAllocated = numToAllocate; + for (ptr = providers; ptr; ) + { + ptrPrev = ptr; + ptr = strchrW(ptr, ','); + if (ptr) + *ptr = '\0'; + _tryLoadProvider(ptrPrev); + } + } + } + HeapFree(GetProcessHeap(), 0, providers); + } + } + RegCloseKey(hKey); + } +} + +void wnetFree(void) +{ + if (providerTable) + { + DWORD i; + + for (i = 0; i < providerTable->numProviders; i++) + { + HeapFree(GetProcessHeap(), 0, providerTable->table[i].name); + FreeModule(providerTable->table[i].hLib); + } + if (providerTable->entireNetwork) + HeapFree(GetProcessHeap(), 0, providerTable->entireNetwork); + HeapFree(GetProcessHeap(), 0, providerTable); + providerTable = NULL; + } +} + +static DWORD _findProviderIndexW(LPCWSTR lpProvider) +{ + DWORD ret = BAD_PROVIDER_INDEX; + + if (providerTable && providerTable->numProviders) + { + DWORD i; + + for (i = 0; i < providerTable->numProviders && + ret == BAD_PROVIDER_INDEX; i++) + if (!strcmpW(lpProvider, providerTable->table[i].name)) + ret = i; + } + return ret; +} + +/* + * Browsing Functions + */ + +static LPNETRESOURCEW _copyNetResourceForEnumW(LPNETRESOURCEW lpNet) +{ + LPNETRESOURCEW ret; + + if (lpNet) + { + ret = (LPNETRESOURCEW)HeapAlloc(GetProcessHeap(), 0, + sizeof(NETRESOURCEW)); + if (ret) + { + size_t len; + + memcpy(ret, lpNet, sizeof(ret)); + ret->lpLocalName = ret->lpComment = ret->lpProvider = NULL; + if (lpNet->lpRemoteName) + { + len = strlenW(lpNet->lpRemoteName) + 1; + ret->lpRemoteName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, + len * sizeof(WCHAR)); + if (ret->lpRemoteName) + strcpyW(ret->lpRemoteName, lpNet->lpRemoteName); + } + } + } + else + ret = NULL; + return ret; +} + +static void _freeEnumNetResource(LPNETRESOURCEW lpNet) +{ + if (lpNet) + { + if (lpNet->lpRemoteName) + HeapFree(GetProcessHeap(), 0, lpNet->lpRemoteName); + HeapFree(GetProcessHeap(), 0, lpNet); + } +} + +static PWNetEnumerator _createNullEnumerator(void) +{ + PWNetEnumerator ret = (PWNetEnumerator)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(WNetEnumerator)); + + if (ret) + ret->enumType = WNET_ENUMERATOR_TYPE_NULL; + return ret; +} + +static PWNetEnumerator _createGlobalEnumeratorW(DWORD dwScope, DWORD dwType, + DWORD dwUsage, LPNETRESOURCEW lpNet) +{ + PWNetEnumerator ret = (PWNetEnumerator)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(WNetEnumerator)); + + if (ret) + { + ret->enumType = WNET_ENUMERATOR_TYPE_GLOBAL; + ret->dwScope = dwScope; + ret->dwType = dwType; + ret->dwUsage = dwUsage; + ret->lpNet = _copyNetResourceForEnumW(lpNet); + } + return ret; +} + +static PWNetEnumerator _createProviderEnumerator(DWORD dwScope, DWORD dwType, + DWORD dwUsage, DWORD index, HANDLE handle) +{ + PWNetEnumerator ret; + + if (!providerTable || index >= providerTable->numProviders) + ret = NULL; + else + { + ret = (PWNetEnumerator)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(WNetEnumerator)); + if (ret) + { + ret->enumType = WNET_ENUMERATOR_TYPE_PROVIDER; + ret->providerIndex = index; + ret->dwScope = dwScope; + ret->dwType = dwType; + ret->dwUsage = dwUsage; + ret->handle = handle; + } + } + return ret; +} + +static PWNetEnumerator _createContextEnumerator(DWORD dwScope, DWORD dwType, + DWORD dwUsage) +{ + PWNetEnumerator ret = (PWNetEnumerator)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(WNetEnumerator)); + + if (ret) + { + ret->enumType = WNET_ENUMERATOR_TYPE_CONTEXT; + ret->dwScope = dwScope; + ret->dwType = dwType; + ret->dwUsage = dwUsage; + } + return ret; +} + +/* Thunks the array of wide-string LPNETRESOURCEs lpNetArrayIn into buffer + * lpBuffer, with size *lpBufferSize. lpNetArrayIn contains *lpcCount entries + * to start. On return, *lpcCount reflects the number thunked into lpBuffer. + * Returns WN_SUCCESS on success (all of lpNetArrayIn thunked), WN_MORE_DATA + * if not all members of the array could be thunked, and something else on + * failure. + */ +static DWORD _thunkNetResourceArrayWToA(const LPNETRESOURCEW lpNetArrayIn, + LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + DWORD i, numToThunk, totalBytes, ret; + LPSTR strNext; + + if (!lpNetArrayIn) + return WN_BAD_POINTER; + if (!lpcCount) + return WN_BAD_POINTER; + if (*lpcCount == -1) + return WN_BAD_VALUE; + if (!lpBuffer) + return WN_BAD_POINTER; + if (!lpBufferSize) + return WN_BAD_POINTER; + + for (i = 0, numToThunk = 0, totalBytes = 0; i < *lpcCount; i++) + { + LPNETRESOURCEW lpNet = lpNetArrayIn + i; + + totalBytes += sizeof(NETRESOURCEA); + if (lpNet->lpLocalName) + totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpLocalName, + -1, NULL, 0, NULL, NULL); + if (lpNet->lpRemoteName) + totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpRemoteName, + -1, NULL, 0, NULL, NULL); + if (lpNet->lpComment) + totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpComment, + -1, NULL, 0, NULL, NULL); + if (lpNet->lpProvider) + totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpProvider, + -1, NULL, 0, NULL, NULL); + if (totalBytes < *lpBufferSize) + numToThunk = i + 1; + } + strNext = (LPSTR)((LPBYTE)lpBuffer + numToThunk * sizeof(NETRESOURCEA)); + for (i = 0; i < numToThunk; i++) + { + LPNETRESOURCEA lpNetOut = (LPNETRESOURCEA)lpBuffer + i; + LPNETRESOURCEW lpNetIn = lpNetArrayIn + i; + + memcpy(lpNetOut, lpNetIn, sizeof(NETRESOURCEA)); + /* lie about string lengths, we already verified how many + * we have space for above + */ + if (lpNetIn->lpLocalName) + { + lpNetOut->lpLocalName = strNext; + strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpLocalName, -1, + lpNetOut->lpLocalName, *lpBufferSize, NULL, NULL); + } + if (lpNetIn->lpRemoteName) + { + lpNetOut->lpRemoteName = strNext; + strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpRemoteName, -1, + lpNetOut->lpRemoteName, *lpBufferSize, NULL, NULL); + } + if (lpNetIn->lpComment) + { + lpNetOut->lpComment = strNext; + strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpComment, -1, + lpNetOut->lpComment, *lpBufferSize, NULL, NULL); + } + if (lpNetIn->lpProvider) + { + lpNetOut->lpProvider = strNext; + strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpProvider, -1, + lpNetOut->lpProvider, *lpBufferSize, NULL, NULL); + } + } + ret = numToThunk < *lpcCount ? WN_MORE_DATA : WN_SUCCESS; + TRACE("numToThunk is %ld, *lpcCount is %ld, returning %ld\n", numToThunk, + *lpcCount, ret); + return ret; +} + +/* Thunks the array of multibyte-string LPNETRESOURCEs lpNetArrayIn into buffer + * lpBuffer, with size *lpBufferSize. lpNetArrayIn contains *lpcCount entries + * to start. On return, *lpcCount reflects the number thunked into lpBuffer. + * Returns WN_SUCCESS on success (all of lpNetArrayIn thunked), WN_MORE_DATA + * if not all members of the array could be thunked, and something else on + * failure. + */ +static DWORD _thunkNetResourceArrayAToW(const LPNETRESOURCEA lpNetArrayIn, + LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + DWORD i, numToThunk, totalBytes, ret; + LPWSTR strNext; + + if (!lpNetArrayIn) + return WN_BAD_POINTER; + if (!lpcCount) + return WN_BAD_POINTER; + if (*lpcCount == -1) + return WN_BAD_VALUE; + if (!lpBuffer) + return WN_BAD_POINTER; + if (!lpBufferSize) + return WN_BAD_POINTER; + + for (i = 0, numToThunk = 0, totalBytes = 0; i < *lpcCount; i++) + { + LPNETRESOURCEA lpNet = lpNetArrayIn + i; + + totalBytes += sizeof(NETRESOURCEW); + if (lpNet->lpLocalName) + totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpLocalName, + -1, NULL, 0) * sizeof(WCHAR); + if (lpNet->lpRemoteName) + totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpRemoteName, + -1, NULL, 0) * sizeof(WCHAR); + if (lpNet->lpComment) + totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpComment, + -1, NULL, 0) * sizeof(WCHAR); + if (lpNet->lpProvider) + totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpProvider, + -1, NULL, 0) * sizeof(WCHAR); + if (totalBytes < *lpBufferSize) + numToThunk = i + 1; + } + strNext = (LPWSTR)((LPBYTE)lpBuffer + numToThunk * sizeof(NETRESOURCEW)); + for (i = 0; i < numToThunk; i++) + { + LPNETRESOURCEW lpNetOut = (LPNETRESOURCEW)lpBuffer + i; + LPNETRESOURCEA lpNetIn = lpNetArrayIn + i; + + memcpy(lpNetOut, lpNetIn, sizeof(NETRESOURCEW)); + /* lie about string lengths, we already verified how many + * we have space for above + */ + if (lpNetIn->lpLocalName) + { + lpNetOut->lpLocalName = strNext; + strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpLocalName, + -1, lpNetOut->lpLocalName, *lpBufferSize); + } + if (lpNetIn->lpRemoteName) + { + lpNetOut->lpRemoteName = strNext; + strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpRemoteName, + -1, lpNetOut->lpRemoteName, *lpBufferSize); + } + if (lpNetIn->lpComment) + { + lpNetOut->lpComment = strNext; + strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpComment, + -1, lpNetOut->lpComment, *lpBufferSize); + } + if (lpNetIn->lpProvider) + { + lpNetOut->lpProvider = strNext; + strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpProvider, + -1, lpNetOut->lpProvider, *lpBufferSize); + } + } + ret = numToThunk < *lpcCount ? WN_MORE_DATA : WN_SUCCESS; + TRACE("numToThunk is %ld, *lpcCount is %ld, returning %ld\n", numToThunk, + *lpcCount, ret); + return ret; +} + +/********************************************************************* + * WNetOpenEnumA [MPR.@] + * + * See comments for WNetOpenEnumW. + */ +DWORD WINAPI WNetOpenEnumA( DWORD dwScope, DWORD dwType, DWORD dwUsage, + LPNETRESOURCEA lpNet, LPHANDLE lphEnum ) +{ + DWORD ret; + + TRACE( "(%08lX, %08lX, %08lX, %p, %p)\n", + dwScope, dwType, dwUsage, lpNet, lphEnum ); + + if (!lphEnum) + ret = WN_BAD_POINTER; + else if (!providerTable || providerTable->numProviders == 0) + ret = WN_NO_NETWORK; + else + { + if (lpNet) + { + LPNETRESOURCEW lpNetWide = NULL; + BYTE buf[1024]; + DWORD size = sizeof(buf), count = 1; + BOOL allocated = FALSE; + + ret = _thunkNetResourceArrayAToW(lpNet, &count, buf, &size); + if (ret == WN_MORE_DATA) + { + lpNetWide = (LPNETRESOURCEW)HeapAlloc(GetProcessHeap(), 0, + size); + if (lpNetWide) + { + ret = _thunkNetResourceArrayAToW(lpNet, &count, lpNetWide, + &size); + allocated = TRUE; + } + else + ret = WN_OUT_OF_MEMORY; + } + else if (ret == WN_SUCCESS) + lpNetWide = (LPNETRESOURCEW)buf; + if (ret == WN_SUCCESS) + ret = WNetOpenEnumW(dwScope, dwType, dwUsage, lpNetWide, + lphEnum); + if (allocated && lpNetWide) + HeapFree(GetProcessHeap(), 0, lpNetWide); + } + else + ret = WNetOpenEnumW(dwScope, dwType, dwUsage, NULL, lphEnum); + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/********************************************************************* + * WNetOpenEnumW [MPR.@] + * + * Network enumeration has way too many parameters, so I'm not positive I got + * them right. What I've got so far: + * + * - If the scope is RESOURCE_GLOBALNET, and no LPNETRESOURCE is passed, + * all the network providers should be enumerated. + * + * - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and + * and neither the LPNETRESOURCE's lpRemoteName nor the LPNETRESOURCE's + * lpProvider is set, all the network providers should be enumerated. + * (This means the enumeration is a list of network providers, not that the + * enumeration is passed on to the providers.) + * + * - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and the + * resource matches the "Entire Network" resource (no remote name, no + * provider, comment is the "Entire Network" string), a RESOURCE_GLOBALNET + * enumeration is done on every network provider. + * + * - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and + * the LPNETRESOURCE's lpProvider is set, enumeration will be passed through + * only to the given network provider. + * + * - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and + * no lpProvider is set, enumeration will be tried on every network provider, + * in the order in which they're loaded. + * + * - The LPNETRESOURCE should be disregarded for scopes besides + * RESOURCE_GLOBALNET. MSDN states that lpNet must be NULL if dwScope is not + * RESOURCE_GLOBALNET, but Windows doesn't return an error if it isn't NULL. + * + * - If the scope is RESOURCE_CONTEXT, MS includes an "Entire Network" net + * resource in the enumerated list, as well as any machines in your + * workgroup. The machines in your workgroup come from doing a + * RESOURCE_CONTEXT enumeration of every Network Provider. + */ +DWORD WINAPI WNetOpenEnumW( DWORD dwScope, DWORD dwType, DWORD dwUsage, + LPNETRESOURCEW lpNet, LPHANDLE lphEnum ) +{ + DWORD ret; + + TRACE( "(%08lX, %08lX, %08lX, %p, %p)\n", + dwScope, dwType, dwUsage, lpNet, lphEnum ); + + if (!lphEnum) + ret = WN_BAD_POINTER; + else if (!providerTable || providerTable->numProviders == 0) + ret = WN_NO_NETWORK; + else + { + switch (dwScope) + { + case RESOURCE_GLOBALNET: + if (lpNet) + { + if (lpNet->lpProvider) + { + DWORD index = _findProviderIndexW(lpNet->lpProvider); + + if (index != BAD_PROVIDER_INDEX) + { + if (providerTable->table[index].openEnum && + providerTable->table[index].dwEnumScopes & dwScope) + { + HANDLE handle; + + ret = providerTable->table[index].openEnum( + dwScope, dwType, dwUsage, lpNet, &handle); + if (ret == WN_SUCCESS) + { + *lphEnum = + (HANDLE)_createProviderEnumerator( + dwScope, dwType, dwUsage, index, handle); + ret = *lphEnum ? WN_SUCCESS : + WN_OUT_OF_MEMORY; + } + } + else + ret = WN_NOT_SUPPORTED; + } + else + ret = WN_BAD_PROVIDER; + } + else if (lpNet->lpRemoteName) + { + *lphEnum = (HANDLE)_createGlobalEnumeratorW(dwScope, + dwType, dwUsage, lpNet); + ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY; + } + else + { + if (lpNet->lpComment && !strcmpW(lpNet->lpComment, + providerTable->entireNetwork)) + { + /* comment matches the "Entire Network", enumerate + * global scope of every provider + */ + *lphEnum = (HANDLE)_createGlobalEnumeratorW(dwScope, + dwType, dwUsage, lpNet); + } + else + { + /* this is the same as not having passed lpNet */ + *lphEnum = (HANDLE)_createGlobalEnumeratorW(dwScope, + dwType, dwUsage, NULL); + } + ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY; + } + } + else + { + *lphEnum = (HANDLE)_createGlobalEnumeratorW(dwScope, dwType, + dwUsage, lpNet); + ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY; + } + break; + case RESOURCE_CONTEXT: + *lphEnum = (HANDLE)_createContextEnumerator(dwScope, dwType, + dwUsage); + ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY; + break; + case RESOURCE_REMEMBERED: + case RESOURCE_CONNECTED: + *lphEnum = (HANDLE)_createNullEnumerator(); + ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY; + break; + default: + WARN("unknown scope 0x%08lx\n", dwScope); + ret = WN_BAD_VALUE; + } + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/********************************************************************* + * WNetEnumResourceA [MPR.@] + */ +DWORD WINAPI WNetEnumResourceA( HANDLE hEnum, LPDWORD lpcCount, + LPVOID lpBuffer, LPDWORD lpBufferSize ) +{ + DWORD ret; + + TRACE( "(%p, %p, %p, %p)\n", hEnum, lpcCount, lpBuffer, lpBufferSize ); + + if (!hEnum) + ret = WN_BAD_POINTER; + else if (!lpcCount) + ret = WN_BAD_POINTER; + if (!lpBuffer) + ret = WN_BAD_POINTER; + else if (!lpBufferSize) + ret = WN_BAD_POINTER; + else if (*lpBufferSize < sizeof(NETRESOURCEA)) + { + *lpBufferSize = sizeof(NETRESOURCEA); + ret = WN_MORE_DATA; + } + else + { + DWORD localCount = *lpcCount, localSize = *lpBufferSize; + LPVOID localBuffer = HeapAlloc(GetProcessHeap(), 0, localSize); + + if (localBuffer) + { + ret = WNetEnumResourceW(hEnum, &localCount, localBuffer, + &localSize); + if (ret == WN_SUCCESS || (ret == WN_MORE_DATA && localCount != -1)) + { + /* FIXME: this isn't necessarily going to work in the case of + * WN_MORE_DATA, because our enumerator may have moved on to + * the next provider. MSDN states that a large (16KB) buffer + * size is the appropriate usage of this function, so + * hopefully it won't be an issue. + */ + ret = _thunkNetResourceArrayWToA((LPNETRESOURCEW)localBuffer, + &localCount, lpBuffer, lpBufferSize); + *lpcCount = localCount; + } + HeapFree(GetProcessHeap(), 0, localBuffer); + } + else + ret = WN_OUT_OF_MEMORY; + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +static DWORD _countProviderBytesW(PWNetProvider provider) +{ + DWORD ret; + + if (provider) + { + ret = sizeof(NETRESOURCEW); + ret += 2 * (strlenW(provider->name) + 1) * sizeof(WCHAR); + } + else + ret = 0; + return ret; +} + +static DWORD _enumerateProvidersW(PWNetEnumerator enumerator, LPDWORD lpcCount, + LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + DWORD ret; + + if (!enumerator) + return WN_BAD_POINTER; + if (enumerator->enumType != WNET_ENUMERATOR_TYPE_GLOBAL) + return WN_BAD_VALUE; + if (!lpcCount) + return WN_BAD_POINTER; + if (!lpBuffer) + return WN_BAD_POINTER; + if (!lpBufferSize) + return WN_BAD_POINTER; + if (*lpBufferSize < sizeof(NETRESOURCEA)) + return WN_MORE_DATA; + + if (!providerTable || enumerator->providerIndex >= + providerTable->numProviders) + ret = WN_NO_MORE_ENTRIES; + else + { + DWORD bytes = 0, count = 0, countLimit, i; + LPNETRESOURCEW resource; + LPWSTR strNext; + + countLimit = *lpcCount == -1 ? + providerTable->numProviders - enumerator->providerIndex : *lpcCount; + while (count < countLimit && bytes < *lpBufferSize) + { + DWORD bytesNext = _countProviderBytesW( + &providerTable->table[count + enumerator->providerIndex]); + + if (bytes + bytesNext < *lpBufferSize) + { + bytes += bytesNext; + count++; + } + } + strNext = (LPWSTR)((LPBYTE)lpBuffer + count * sizeof(NETRESOURCEW)); + for (i = 0, resource = (LPNETRESOURCEW)lpBuffer; i < count; + i++, resource++) + { + resource->dwScope = RESOURCE_GLOBALNET; + resource->dwType = RESOURCETYPE_ANY; + resource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK; + resource->dwUsage = RESOURCEUSAGE_CONTAINER | + RESOURCEUSAGE_RESERVED; + resource->lpLocalName = NULL; + resource->lpRemoteName = strNext; + strcpyW(resource->lpRemoteName, + providerTable->table[i + enumerator->providerIndex].name); + strNext += strlenW(resource->lpRemoteName) + 1; + resource->lpComment = NULL; + resource->lpProvider = strNext; + strcpyW(resource->lpProvider, + providerTable->table[i + enumerator->providerIndex].name); + strNext += strlenW(resource->lpProvider) + 1; + } + enumerator->providerIndex += count; + *lpcCount = count; + ret = count > 0 ? WN_SUCCESS : WN_MORE_DATA; + } + TRACE("Returning %ld\n", ret); + return ret; +} + +/* Advances the enumerator (assumed to be a global enumerator) to the next + * provider that supports the enumeration scope passed to WNetOpenEnum. Does + * not open a handle with the next provider. + * If the existing handle is NULL, may leave the enumerator unchanged, since + * the current provider may support the desired scope. + * If the existing handle is not NULL, closes it before moving on. + * Returns WN_SUCCESS on success, WN_NO_MORE_ENTRIES if there is no available + * provider, and another error on failure. + */ +static DWORD _globalEnumeratorAdvance(PWNetEnumerator enumerator) +{ + if (!enumerator) + return WN_BAD_POINTER; + if (enumerator->enumType != WNET_ENUMERATOR_TYPE_GLOBAL) + return WN_BAD_VALUE; + if (!providerTable || enumerator->providerIndex >= + providerTable->numProviders) + return WN_NO_MORE_ENTRIES; + + if (enumerator->providerDone) + { + enumerator->providerDone = FALSE; + if (enumerator->handle) + { + providerTable->table[enumerator->providerIndex].closeEnum( + enumerator->handle); + enumerator->handle = NULL; + enumerator->providerIndex++; + } + for (; enumerator->providerIndex < providerTable->numProviders && + !(enumerator->dwScope & providerTable->table + [enumerator->providerIndex].dwEnumScopes); + enumerator->providerIndex++) + ; + } + return enumerator->providerIndex < providerTable->numProviders ? + WN_SUCCESS : WN_NO_MORE_ENTRIES; +} + +/* "Passes through" call to the next provider that supports the enumeration + * type. + * FIXME: if one call to a provider's enumerator succeeds while there's still + * space in lpBuffer, I don't call to the next provider. The caller may not + * expect that it should call EnumResourceW again with a return value of + * WN_SUCCESS (depending what *lpcCount was to begin with). That means strings + * may have to be moved around a bit, ick. + */ +static DWORD _enumerateGlobalPassthroughW(PWNetEnumerator enumerator, + LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + DWORD ret; + + if (!enumerator) + return WN_BAD_POINTER; + if (enumerator->enumType != WNET_ENUMERATOR_TYPE_GLOBAL) + return WN_BAD_VALUE; + if (!lpcCount) + return WN_BAD_POINTER; + if (!lpBuffer) + return WN_BAD_POINTER; + if (!lpBufferSize) + return WN_BAD_POINTER; + if (*lpBufferSize < sizeof(NETRESOURCEW)) + return WN_MORE_DATA; + + ret = _globalEnumeratorAdvance(enumerator); + if (ret == WN_SUCCESS) + { + ret = providerTable->table[enumerator->providerIndex]. + openEnum(enumerator->dwScope, enumerator->dwType, + enumerator->dwUsage, enumerator->lpNet, + &enumerator->handle); + if (ret == WN_SUCCESS) + { + ret = providerTable->table[enumerator->providerIndex]. + enumResource(enumerator->handle, lpcCount, lpBuffer, + lpBufferSize); + if (ret != WN_MORE_DATA) + enumerator->providerDone = TRUE; + } + } + TRACE("Returning %ld\n", ret); + return ret; +} + +static DWORD _enumerateGlobalW(PWNetEnumerator enumerator, LPDWORD lpcCount, + LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + DWORD ret; + + if (!enumerator) + return WN_BAD_POINTER; + if (enumerator->enumType != WNET_ENUMERATOR_TYPE_GLOBAL) + return WN_BAD_VALUE; + if (!lpcCount) + return WN_BAD_POINTER; + if (!lpBuffer) + return WN_BAD_POINTER; + if (!lpBufferSize) + return WN_BAD_POINTER; + if (*lpBufferSize < sizeof(NETRESOURCEW)) + return WN_MORE_DATA; + if (!providerTable) + return WN_NO_NETWORK; + + switch (enumerator->dwScope) + { + case RESOURCE_GLOBALNET: + if (enumerator->lpNet) + ret = _enumerateGlobalPassthroughW(enumerator, lpcCount, + lpBuffer, lpBufferSize); + else + ret = _enumerateProvidersW(enumerator, lpcCount, lpBuffer, + lpBufferSize); + break; + case RESOURCE_CONTEXT: + ret = _enumerateGlobalPassthroughW(enumerator, lpcCount, lpBuffer, + lpBufferSize); + break; + default: + WARN("unexpected scope 0x%08lx\n", enumerator->dwScope); + ret = WN_NO_MORE_ENTRIES; + } + TRACE("Returning %ld\n", ret); + return ret; +} + +static DWORD _enumerateProviderW(PWNetEnumerator enumerator, LPDWORD lpcCount, + LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + if (!enumerator) + return WN_BAD_POINTER; + if (enumerator->enumType != WNET_ENUMERATOR_TYPE_PROVIDER) + return WN_BAD_VALUE; + if (!enumerator->handle) + return WN_BAD_VALUE; + if (!lpcCount) + return WN_BAD_POINTER; + if (!lpBuffer) + return WN_BAD_POINTER; + if (!lpBufferSize) + return WN_BAD_POINTER; + if (!providerTable) + return WN_NO_NETWORK; + if (enumerator->providerIndex >= providerTable->numProviders) + return WN_NO_MORE_ENTRIES; + if (!providerTable->table[enumerator->providerIndex].enumResource) + return WN_BAD_VALUE; + return providerTable->table[enumerator->providerIndex].enumResource( + enumerator->handle, lpcCount, lpBuffer, lpBufferSize); +} + +static DWORD _enumerateContextW(PWNetEnumerator enumerator, LPDWORD lpcCount, + LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + DWORD ret; + size_t cchEntireNetworkLen, bytesNeeded; + + if (!enumerator) + return WN_BAD_POINTER; + if (enumerator->enumType != WNET_ENUMERATOR_TYPE_CONTEXT) + return WN_BAD_VALUE; + if (!lpcCount) + return WN_BAD_POINTER; + if (!lpBuffer) + return WN_BAD_POINTER; + if (!lpBufferSize) + return WN_BAD_POINTER; + if (!providerTable) + return WN_NO_NETWORK; + + cchEntireNetworkLen = strlenW(providerTable->entireNetwork) + 1; + bytesNeeded = sizeof(NETRESOURCEW) + cchEntireNetworkLen * sizeof(WCHAR); + if (*lpBufferSize < bytesNeeded) + { + *lpBufferSize = bytesNeeded; + ret = WN_MORE_DATA; + } + else + { + LPNETRESOURCEW lpNet = (LPNETRESOURCEW)lpBuffer; + + lpNet->dwScope = RESOURCE_GLOBALNET; + lpNet->dwType = enumerator->dwType; + lpNet->dwDisplayType = RESOURCEDISPLAYTYPE_ROOT; + lpNet->dwUsage = RESOURCEUSAGE_CONTAINER; + lpNet->lpLocalName = NULL; + lpNet->lpRemoteName = NULL; + lpNet->lpProvider = NULL; + /* odd, but correct: put comment at end of buffer, so it won't get + * overwritten by subsequent calls to a provider's enumResource + */ + lpNet->lpComment = (LPWSTR)((LPBYTE)lpBuffer + *lpBufferSize - + (cchEntireNetworkLen * sizeof(WCHAR))); + strcpyW(lpNet->lpComment, providerTable->entireNetwork); + ret = WN_SUCCESS; + } + if (ret == WN_SUCCESS) + { + DWORD bufferSize = *lpBufferSize - bytesNeeded; + + /* "Entire Network" entry enumerated--morph this into a global + * enumerator. enumerator->lpNet continues to be NULL, since it has + * no meaning when the scope isn't RESOURCE_GLOBALNET. + */ + enumerator->enumType = WNET_ENUMERATOR_TYPE_GLOBAL; + ret = _enumerateGlobalW(enumerator, lpcCount, + (LPBYTE)lpBuffer + bytesNeeded, &bufferSize); + if (ret == WN_SUCCESS) + { + /* reflect the fact that we already enumerated "Entire Network" */ + lpcCount++; + *lpBufferSize = bufferSize + bytesNeeded; + } + else + { + /* the provider enumeration failed, but we already succeeded in + * enumerating "Entire Network"--leave type as global to allow a + * retry, but indicate success with a count of one. + */ + ret = WN_SUCCESS; + *lpcCount = 1; + *lpBufferSize = bytesNeeded; + } + } + TRACE("Returning %ld\n", ret); + return ret; +} + +/********************************************************************* + * WNetEnumResourceW [MPR.@] + */ +DWORD WINAPI WNetEnumResourceW( HANDLE hEnum, LPDWORD lpcCount, + LPVOID lpBuffer, LPDWORD lpBufferSize ) +{ + DWORD ret; + + TRACE( "(%p, %p, %p, %p)\n", hEnum, lpcCount, lpBuffer, lpBufferSize ); + + if (!hEnum) + ret = WN_BAD_POINTER; + else if (!lpcCount) + ret = WN_BAD_POINTER; + else if (!lpBuffer) + ret = WN_BAD_POINTER; + else if (!lpBufferSize) + ret = WN_BAD_POINTER; + else if (*lpBufferSize < sizeof(NETRESOURCEW)) + { + *lpBufferSize = sizeof(NETRESOURCEW); + ret = WN_MORE_DATA; + } + else + { + PWNetEnumerator enumerator = (PWNetEnumerator)hEnum; + + switch (enumerator->enumType) + { + case WNET_ENUMERATOR_TYPE_NULL: + ret = WN_NO_MORE_ENTRIES; + break; + case WNET_ENUMERATOR_TYPE_GLOBAL: + ret = _enumerateGlobalW(enumerator, lpcCount, lpBuffer, + lpBufferSize); + break; + case WNET_ENUMERATOR_TYPE_PROVIDER: + ret = _enumerateProviderW(enumerator, lpcCount, lpBuffer, + lpBufferSize); + break; + case WNET_ENUMERATOR_TYPE_CONTEXT: + ret = _enumerateContextW(enumerator, lpcCount, lpBuffer, + lpBufferSize); + break; + default: + WARN("bogus enumerator type!\n"); + ret = WN_NO_NETWORK; + } + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/********************************************************************* + * WNetCloseEnum [MPR.@] + */ +DWORD WINAPI WNetCloseEnum( HANDLE hEnum ) +{ + DWORD ret; + + TRACE( "(%p)\n", hEnum ); + + if (hEnum) + { + PWNetEnumerator enumerator = (PWNetEnumerator)hEnum; + + switch (enumerator->enumType) + { + case WNET_ENUMERATOR_TYPE_NULL: + ret = WN_SUCCESS; + break; + case WNET_ENUMERATOR_TYPE_GLOBAL: + if (enumerator->lpNet) + _freeEnumNetResource(enumerator->lpNet); + if (enumerator->handle) + providerTable->table[enumerator->providerIndex]. + closeEnum(enumerator->handle); + ret = WN_SUCCESS; + break; + case WNET_ENUMERATOR_TYPE_PROVIDER: + if (enumerator->handle) + providerTable->table[enumerator->providerIndex]. + closeEnum(enumerator->handle); + ret = WN_SUCCESS; + break; + default: + WARN("bogus enumerator type!\n"); + ret = WN_BAD_HANDLE; + } + HeapFree(GetProcessHeap(), 0, hEnum); + } + else + ret = WN_BAD_HANDLE; + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/********************************************************************* + * WNetGetResourceInformationA [MPR.@] + */ +DWORD WINAPI WNetGetResourceInformationA( LPNETRESOURCEA lpNetResource, + LPVOID lpBuffer, LPDWORD cbBuffer, + LPSTR *lplpSystem ) +{ + FIXME( "(%p, %p, %p, %p): stub\n", + lpNetResource, lpBuffer, cbBuffer, lplpSystem ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetGetResourceInformationW [MPR.@] + */ +DWORD WINAPI WNetGetResourceInformationW( LPNETRESOURCEW lpNetResource, + LPVOID lpBuffer, LPDWORD cbBuffer, + LPWSTR *lplpSystem ) +{ + FIXME( "(%p, %p, %p, %p): stub\n", + lpNetResource, lpBuffer, cbBuffer, lplpSystem ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetGetResourceParentA [MPR.@] + */ +DWORD WINAPI WNetGetResourceParentA( LPNETRESOURCEA lpNetResource, + LPVOID lpBuffer, LPDWORD lpBufferSize ) +{ + FIXME( "(%p, %p, %p): stub\n", + lpNetResource, lpBuffer, lpBufferSize ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetGetResourceParentW [MPR.@] + */ +DWORD WINAPI WNetGetResourceParentW( LPNETRESOURCEW lpNetResource, + LPVOID lpBuffer, LPDWORD lpBufferSize ) +{ + FIXME( "(%p, %p, %p): stub\n", + lpNetResource, lpBuffer, lpBufferSize ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + + + +/* + * Connection Functions + */ + +/********************************************************************* + * WNetAddConnectionA [MPR.@] + */ +DWORD WINAPI WNetAddConnectionA( LPCSTR lpRemoteName, LPCSTR lpPassword, + LPCSTR lpLocalName ) +{ + FIXME( "(%s, %p, %s): stub\n", + debugstr_a(lpRemoteName), lpPassword, debugstr_a(lpLocalName) ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetAddConnectionW [MPR.@] + */ +DWORD WINAPI WNetAddConnectionW( LPCWSTR lpRemoteName, LPCWSTR lpPassword, + LPCWSTR lpLocalName ) +{ + FIXME( "(%s, %p, %s): stub\n", + debugstr_w(lpRemoteName), lpPassword, debugstr_w(lpLocalName) ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetAddConnection2A [MPR.@] + */ +DWORD WINAPI WNetAddConnection2A( LPNETRESOURCEA lpNetResource, + LPCSTR lpPassword, LPCSTR lpUserID, + DWORD dwFlags ) +{ + FIXME( "(%p, %p, %s, 0x%08lX): stub\n", + lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetAddConnection2W [MPR.@] + */ +DWORD WINAPI WNetAddConnection2W( LPNETRESOURCEW lpNetResource, + LPCWSTR lpPassword, LPCWSTR lpUserID, + DWORD dwFlags ) +{ + FIXME( "(%p, %p, %s, 0x%08lX): stub\n", + lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetAddConnection3A [MPR.@] + */ +DWORD WINAPI WNetAddConnection3A( HWND hwndOwner, LPNETRESOURCEA lpNetResource, + LPCSTR lpPassword, LPCSTR lpUserID, + DWORD dwFlags ) +{ + FIXME( "(%p, %p, %p, %s, 0x%08lX), stub\n", + hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetAddConnection3W [MPR.@] + */ +DWORD WINAPI WNetAddConnection3W( HWND hwndOwner, LPNETRESOURCEW lpNetResource, + LPCWSTR lpPassword, LPCWSTR lpUserID, + DWORD dwFlags ) +{ + FIXME( "(%p, %p, %p, %s, 0x%08lX), stub\n", + hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetUseConnectionA [MPR.@] + */ +DWORD WINAPI WNetUseConnectionA( HWND hwndOwner, LPNETRESOURCEA lpNetResource, + LPCSTR lpPassword, LPCSTR lpUserID, DWORD dwFlags, + LPSTR lpAccessName, LPDWORD lpBufferSize, + LPDWORD lpResult ) +{ + FIXME( "(%p, %p, %p, %s, 0x%08lX, %s, %p, %p), stub\n", + hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags, + debugstr_a(lpAccessName), lpBufferSize, lpResult ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetUseConnectionW [MPR.@] + */ +DWORD WINAPI WNetUseConnectionW( HWND hwndOwner, LPNETRESOURCEW lpNetResource, + LPCWSTR lpPassword, LPCWSTR lpUserID, DWORD dwFlags, + LPWSTR lpAccessName, LPDWORD lpBufferSize, + LPDWORD lpResult ) +{ + FIXME( "(%p, %p, %p, %s, 0x%08lX, %s, %p, %p), stub\n", + hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags, + debugstr_w(lpAccessName), lpBufferSize, lpResult ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetCancelConnectionA [MPR.@] + */ +DWORD WINAPI WNetCancelConnectionA( LPCSTR lpName, BOOL fForce ) +{ + FIXME( "(%s, %d), stub\n", debugstr_a(lpName), fForce ); + + return WN_SUCCESS; +} + +/********************************************************************* + * WNetCancelConnectionW [MPR.@] + */ +DWORD WINAPI WNetCancelConnectionW( LPCWSTR lpName, BOOL fForce ) +{ + FIXME( "(%s, %d), stub\n", debugstr_w(lpName), fForce ); + + return WN_SUCCESS; +} + +/********************************************************************* + * WNetCancelConnection2A [MPR.@] + */ +DWORD WINAPI WNetCancelConnection2A( LPCSTR lpName, DWORD dwFlags, BOOL fForce ) +{ + FIXME( "(%s, %08lX, %d), stub\n", debugstr_a(lpName), dwFlags, fForce ); + + return WN_SUCCESS; +} + +/********************************************************************* + * WNetCancelConnection2W [MPR.@] + */ +DWORD WINAPI WNetCancelConnection2W( LPCWSTR lpName, DWORD dwFlags, BOOL fForce ) +{ + FIXME( "(%s, %08lX, %d), stub\n", debugstr_w(lpName), dwFlags, fForce ); + + return WN_SUCCESS; +} + +/***************************************************************** + * WNetRestoreConnectionA [MPR.@] + */ +DWORD WINAPI WNetRestoreConnectionA( HWND hwndOwner, LPSTR lpszDevice ) +{ + FIXME( "(%p, %s), stub\n", hwndOwner, debugstr_a(lpszDevice) ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetRestoreConnectionW [MPR.@] + */ +DWORD WINAPI WNetRestoreConnectionW( HWND hwndOwner, LPWSTR lpszDevice ) +{ + FIXME( "(%p, %s), stub\n", hwndOwner, debugstr_w(lpszDevice) ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/************************************************************************** + * WNetGetConnectionA [MPR.@] + * + * RETURNS + * - WN_BAD_LOCALNAME lpLocalName makes no sense + * - WN_NOT_CONNECTED drive is a local drive + * - WN_MORE_DATA buffer isn't big enough + * - WN_SUCCESS success (net path in buffer) + * + * FIXME: need to test return values under different errors + */ +DWORD WINAPI WNetGetConnectionA( LPCSTR lpLocalName, + LPSTR lpRemoteName, LPDWORD lpBufferSize ) +{ + DWORD ret; + + if (!lpLocalName) + ret = WN_BAD_POINTER; + else if (!lpRemoteName) + ret = WN_BAD_POINTER; + else if (!lpBufferSize) + ret = WN_BAD_POINTER; + else + { + int len = MultiByteToWideChar(CP_ACP, 0, lpLocalName, -1, NULL, 0); + + if (len) + { + PWSTR wideLocalName = (PWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + + if (wideLocalName) + { + WCHAR wideRemoteStatic[MAX_PATH]; + DWORD wideRemoteSize = sizeof(wideRemoteStatic) / sizeof(WCHAR); + + MultiByteToWideChar(CP_ACP, 0, lpLocalName, -1, wideLocalName, len); + + /* try once without memory allocation */ + ret = WNetGetConnectionW(wideLocalName, wideRemoteStatic, + &wideRemoteSize); + if (ret == WN_SUCCESS) + { + int len = WideCharToMultiByte(CP_ACP, 0, wideRemoteStatic, + -1, NULL, 0, NULL, NULL); + + if (len <= *lpBufferSize) + { + WideCharToMultiByte(CP_ACP, 0, wideRemoteStatic, -1, + lpRemoteName, *lpBufferSize, NULL, NULL); + ret = WN_SUCCESS; + } + else + { + *lpBufferSize = len; + ret = WN_MORE_DATA; + } + } + else if (ret == WN_MORE_DATA) + { + PWSTR wideRemote = (PWSTR)HeapAlloc(GetProcessHeap(), 0, + wideRemoteSize * sizeof(WCHAR)); + + if (wideRemote) + { + ret = WNetGetConnectionW(wideLocalName, wideRemote, + &wideRemoteSize); + if (ret == WN_SUCCESS) + { + if (len <= *lpBufferSize) + { + WideCharToMultiByte(CP_ACP, 0, wideRemoteStatic, + -1, lpRemoteName, *lpBufferSize, NULL, NULL); + ret = WN_SUCCESS; + } + else + { + *lpBufferSize = len; + ret = WN_MORE_DATA; + } + } + HeapFree(GetProcessHeap(), 0, wideRemote); + } + else + ret = WN_OUT_OF_MEMORY; + } + HeapFree(GetProcessHeap(), 0, wideLocalName); + } + else + ret = WN_OUT_OF_MEMORY; + } + else + ret = WN_BAD_LOCALNAME; + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/************************************************************************** + * WNetGetConnectionW [MPR.@] + * + * FIXME: need to test return values under different errors + */ +DWORD WINAPI WNetGetConnectionW( LPCWSTR lpLocalName, + LPWSTR lpRemoteName, LPDWORD lpBufferSize ) +{ + DWORD ret; + + TRACE("(%s, %p, %p)\n", debugstr_w(lpLocalName), lpRemoteName, + lpBufferSize); + + if (!lpLocalName) + ret = WN_BAD_POINTER; + else if (!lpRemoteName) + ret = WN_BAD_POINTER; + else if (!lpBufferSize) + ret = WN_BAD_POINTER; + else if (!lpLocalName[0]) + ret = WN_BAD_LOCALNAME; + else + { + if (lpLocalName[1] == ':') + { + switch(GetDriveTypeW(lpLocalName)) + { + case DRIVE_REMOTE: + { + WCHAR remote[MAX_PATH]; + if (!QueryDosDeviceW( lpLocalName, remote, MAX_PATH )) remote[0] = 0; + if (strlenW(remote) + 1 > *lpBufferSize) + { + *lpBufferSize = strlenW(remote) + 1; + ret = WN_MORE_DATA; + } + else + { + strcpyW( lpRemoteName, remote ); + *lpBufferSize = strlenW(lpRemoteName) + 1; + ret = WN_SUCCESS; + } + break; + } + case DRIVE_REMOVABLE: + case DRIVE_FIXED: + case DRIVE_CDROM: + TRACE("file is local\n"); + ret = WN_NOT_CONNECTED; + break; + default: + ret = WN_BAD_LOCALNAME; + } + } + else + ret = WN_BAD_LOCALNAME; + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/************************************************************************** + * WNetSetConnectionA [MPR.@] + */ +DWORD WINAPI WNetSetConnectionA( LPCSTR lpName, DWORD dwProperty, + LPVOID pvValue ) +{ + FIXME( "(%s, %08lX, %p): stub\n", debugstr_a(lpName), dwProperty, pvValue ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/************************************************************************** + * WNetSetConnectionW [MPR.@] + */ +DWORD WINAPI WNetSetConnectionW( LPCWSTR lpName, DWORD dwProperty, + LPVOID pvValue ) +{ + FIXME( "(%s, %08lX, %p): stub\n", debugstr_w(lpName), dwProperty, pvValue ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetGetUniversalNameA [MPR.@] + */ +DWORD WINAPI WNetGetUniversalNameA ( LPCSTR lpLocalPath, DWORD dwInfoLevel, + LPVOID lpBuffer, LPDWORD lpBufferSize ) +{ + FIXME( "(%s, 0x%08lX, %p, %p): stub\n", + debugstr_a(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/***************************************************************** + * WNetGetUniversalNameW [MPR.@] + */ +DWORD WINAPI WNetGetUniversalNameW ( LPCWSTR lpLocalPath, DWORD dwInfoLevel, + LPVOID lpBuffer, LPDWORD lpBufferSize ) +{ + FIXME( "(%s, 0x%08lX, %p, %p): stub\n", + debugstr_w(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + + + +/* + * Other Functions + */ + +/************************************************************************** + * WNetGetUserA [MPR.@] + * + * FIXME: we should not return ourselves, but the owner of the drive lpName + */ +DWORD WINAPI WNetGetUserA( LPCSTR lpName, LPSTR lpUserID, LPDWORD lpBufferSize ) +{ + if (GetUserNameA( lpUserID, lpBufferSize )) return WN_SUCCESS; + return GetLastError(); +} + +/***************************************************************** + * WNetGetUserW [MPR.@] + * + * FIXME: we should not return ourselves, but the owner of the drive lpName + */ +DWORD WINAPI WNetGetUserW( LPCWSTR lpName, LPWSTR lpUserID, LPDWORD lpBufferSize ) +{ + if (GetUserNameW( lpUserID, lpBufferSize )) return WN_SUCCESS; + return GetLastError(); +} + +/********************************************************************* + * WNetConnectionDialog [MPR.@] + */ +DWORD WINAPI WNetConnectionDialog( HWND hwnd, DWORD dwType ) +{ + FIXME( "(%p, %08lX): stub\n", hwnd, dwType ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetConnectionDialog1A [MPR.@] + */ +DWORD WINAPI WNetConnectionDialog1A( LPCONNECTDLGSTRUCTA lpConnDlgStruct ) +{ + FIXME( "(%p): stub\n", lpConnDlgStruct ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetConnectionDialog1W [MPR.@] + */ +DWORD WINAPI WNetConnectionDialog1W( LPCONNECTDLGSTRUCTW lpConnDlgStruct ) +{ + FIXME( "(%p): stub\n", lpConnDlgStruct ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetDisconnectDialog [MPR.@] + */ +DWORD WINAPI WNetDisconnectDialog( HWND hwnd, DWORD dwType ) +{ + FIXME( "(%p, %08lX): stub\n", hwnd, dwType ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetDisconnectDialog1A [MPR.@] + */ +DWORD WINAPI WNetDisconnectDialog1A( LPDISCDLGSTRUCTA lpConnDlgStruct ) +{ + FIXME( "(%p): stub\n", lpConnDlgStruct ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetDisconnectDialog1W [MPR.@] + */ +DWORD WINAPI WNetDisconnectDialog1W( LPDISCDLGSTRUCTW lpConnDlgStruct ) +{ + FIXME( "(%p): stub\n", lpConnDlgStruct ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetGetLastErrorA [MPR.@] + */ +DWORD WINAPI WNetGetLastErrorA( LPDWORD lpError, + LPSTR lpErrorBuf, DWORD nErrorBufSize, + LPSTR lpNameBuf, DWORD nNameBufSize ) +{ + FIXME( "(%p, %p, %ld, %p, %ld): stub\n", + lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetGetLastErrorW [MPR.@] + */ +DWORD WINAPI WNetGetLastErrorW( LPDWORD lpError, + LPWSTR lpErrorBuf, DWORD nErrorBufSize, + LPWSTR lpNameBuf, DWORD nNameBufSize ) +{ + FIXME( "(%p, %p, %ld, %p, %ld): stub\n", + lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize ); + + SetLastError(WN_NO_NETWORK); + return WN_NO_NETWORK; +} + +/********************************************************************* + * WNetGetNetworkInformationA [MPR.@] + */ +DWORD WINAPI WNetGetNetworkInformationA( LPCSTR lpProvider, + LPNETINFOSTRUCT lpNetInfoStruct ) +{ + DWORD ret; + + TRACE( "(%s, %p)\n", debugstr_a(lpProvider), lpNetInfoStruct ); + + if (!lpProvider) + ret = WN_BAD_POINTER; + else + { + int len; + + len = MultiByteToWideChar(CP_ACP, 0, lpProvider, -1, NULL, 0); + if (len) + { + LPWSTR wideProvider = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, + len * sizeof(WCHAR)); + + if (wideProvider) + { + MultiByteToWideChar(CP_ACP, 0, lpProvider, -1, wideProvider, + len); + ret = WNetGetNetworkInformationW(wideProvider, lpNetInfoStruct); + HeapFree(GetProcessHeap(), 0, wideProvider); + } + else + ret = WN_OUT_OF_MEMORY; + } + else + ret = GetLastError(); + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/********************************************************************* + * WNetGetNetworkInformationW [MPR.@] + */ +DWORD WINAPI WNetGetNetworkInformationW( LPCWSTR lpProvider, + LPNETINFOSTRUCT lpNetInfoStruct ) +{ + DWORD ret; + + TRACE( "(%s, %p)\n", debugstr_w(lpProvider), lpNetInfoStruct ); + + if (!lpProvider) + ret = WN_BAD_POINTER; + else if (!lpNetInfoStruct) + ret = WN_BAD_POINTER; + else if (lpNetInfoStruct->cbStructure < sizeof(NETINFOSTRUCT)) + ret = WN_BAD_VALUE; + else + { + if (providerTable && providerTable->numProviders) + { + DWORD providerIndex = _findProviderIndexW(lpProvider); + + if (providerIndex != BAD_PROVIDER_INDEX) + { + lpNetInfoStruct->cbStructure = sizeof(NETINFOSTRUCT); + lpNetInfoStruct->dwProviderVersion = + providerTable->table[providerIndex].dwSpecVersion; + lpNetInfoStruct->dwStatus = NO_ERROR; + lpNetInfoStruct->dwCharacteristics = 0; + lpNetInfoStruct->dwHandle = (ULONG_PTR)NULL; + lpNetInfoStruct->wNetType = + HIWORD(providerTable->table[providerIndex].dwNetType); + lpNetInfoStruct->dwPrinters = -1; + lpNetInfoStruct->dwDrives = -1; + ret = WN_SUCCESS; + } + else + ret = WN_BAD_PROVIDER; + } + else + ret = WN_NO_NETWORK; + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/***************************************************************** + * WNetGetProviderNameA [MPR.@] + */ +DWORD WINAPI WNetGetProviderNameA( DWORD dwNetType, + LPSTR lpProvider, LPDWORD lpBufferSize ) +{ + DWORD ret; + + TRACE("(0x%08lx, %s, %p)\n", dwNetType, debugstr_a(lpProvider), + lpBufferSize); + + if (!lpProvider) + ret = WN_BAD_POINTER; + else if (!lpBufferSize) + ret = WN_BAD_POINTER; + else + { + if (providerTable) + { + DWORD i; + + ret = WN_NO_NETWORK; + for (i = 0; i < providerTable->numProviders && + HIWORD(providerTable->table[i].dwNetType) != HIWORD(dwNetType); + i++) + ; + if (i < providerTable->numProviders) + { + DWORD sizeNeeded = WideCharToMultiByte(CP_ACP, 0, + providerTable->table[i].name, -1, NULL, 0, NULL, NULL); + + if (*lpBufferSize < sizeNeeded) + { + *lpBufferSize = sizeNeeded; + ret = WN_MORE_DATA; + } + else + { + WideCharToMultiByte(CP_ACP, 0, providerTable->table[i].name, + -1, lpProvider, *lpBufferSize, NULL, NULL); + ret = WN_SUCCESS; + /* FIXME: is *lpBufferSize set to the number of characters + * copied? */ + } + } + } + else + ret = WN_NO_NETWORK; + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} + +/***************************************************************** + * WNetGetProviderNameW [MPR.@] + */ +DWORD WINAPI WNetGetProviderNameW( DWORD dwNetType, + LPWSTR lpProvider, LPDWORD lpBufferSize ) +{ + DWORD ret; + + TRACE("(0x%08lx, %s, %p)\n", dwNetType, debugstr_w(lpProvider), + lpBufferSize); + + if (!lpProvider) + ret = WN_BAD_POINTER; + else if (!lpBufferSize) + ret = WN_BAD_POINTER; + else + { + if (providerTable) + { + DWORD i; + + ret = WN_NO_NETWORK; + for (i = 0; i < providerTable->numProviders && + HIWORD(providerTable->table[i].dwNetType) != HIWORD(dwNetType); + i++) + ; + if (i < providerTable->numProviders) + { + DWORD sizeNeeded = strlenW(providerTable->table[i].name) + 1; + + if (*lpBufferSize < sizeNeeded) + { + *lpBufferSize = sizeNeeded; + ret = WN_MORE_DATA; + } + else + { + strcpyW(lpProvider, providerTable->table[i].name); + ret = WN_SUCCESS; + /* FIXME: is *lpBufferSize set to the number of characters + * copied? */ + } + } + } + else + ret = WN_NO_NETWORK; + } + if (ret) + SetLastError(ret); + TRACE("Returning %ld\n", ret); + return ret; +} diff --git a/reactos/lib/mpr/wnetpriv.h b/reactos/lib/mpr/wnetpriv.h new file mode 100644 index 00000000000..5b0116404bc --- /dev/null +++ b/reactos/lib/mpr/wnetpriv.h @@ -0,0 +1,27 @@ +/* + * WNet private definitions + * + * Copyright (C) 2004 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 __WNET_PRIV_H__ +#define __WNET_PRIV_H__ + +void wnetInit(HINSTANCE hInstDll); +void wnetFree(void); + +#endif /* ndef __WNET_PRIV_H__ */