https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d1404a7a2a8237da2321d…
commit d1404a7a2a8237da2321d07c9edbcbf633d9696a
Author: Jared Smudde <computerwhiz02(a)hotmail.com>
AuthorDate: Tue Apr 23 00:45:49 2019 -0500
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Apr 24 04:26:12 2019 +0200
[NETPLWIZ] Implement the Disconnect Network Drive dialog. (#1522)
CORE-13516, CORE-13518
---
dll/shellext/CMakeLists.txt | 1 +
dll/shellext/netplwiz/CMakeLists.txt | 17 +++
dll/shellext/netplwiz/SHDisconnectNetDrives.c | 197 ++++++++++++++++++++++++++
dll/shellext/netplwiz/lang/en-US.rc | 21 +++
dll/shellext/netplwiz/netplwiz.c | 51 +++++++
dll/shellext/netplwiz/netplwiz.h | 19 +++
dll/shellext/netplwiz/netplwiz.rc | 26 ++++
dll/shellext/netplwiz/netplwiz.spec | 14 ++
dll/shellext/netplwiz/res/4400.ico | Bin 0 -> 22486 bytes
dll/shellext/netplwiz/resource.h | 21 +++
10 files changed, 367 insertions(+)
diff --git a/dll/shellext/CMakeLists.txt b/dll/shellext/CMakeLists.txt
index 0f57882163..89980c3f5f 100644
--- a/dll/shellext/CMakeLists.txt
+++ b/dll/shellext/CMakeLists.txt
@@ -5,6 +5,7 @@ add_subdirectory(deskadp)
add_subdirectory(deskmon)
add_subdirectory(devcpux)
add_subdirectory(fontext)
+add_subdirectory(netplwiz)
add_subdirectory(netshell)
add_subdirectory(ntobjshex)
add_subdirectory(shellbtrfs)
diff --git a/dll/shellext/netplwiz/CMakeLists.txt b/dll/shellext/netplwiz/CMakeLists.txt
new file mode 100644
index 0000000000..7d1fc15dc2
--- /dev/null
+++ b/dll/shellext/netplwiz/CMakeLists.txt
@@ -0,0 +1,17 @@
+
+spec2def(netplwiz.dll netplwiz.spec)
+
+list(APPEND SOURCE
+ netplwiz.c
+ SHDisconnectNetDrives.c)
+
+add_library(netplwiz SHARED
+ ${SOURCE}
+ netplwiz.rc
+ ${CMAKE_CURRENT_BINARY_DIR}/netplwiz_stubs.c
+ ${CMAKE_CURRENT_BINARY_DIR}/netplwiz.def)
+
+set_module_type(netplwiz win32dll UNICODE)
+target_link_libraries(netplwiz wine)
+add_importlibs(netplwiz comctl32 mpr ole32 user32 msvcrt kernel32 ntdll)
+add_cd_file(TARGET netplwiz DESTINATION reactos/system32 FOR all)
diff --git a/dll/shellext/netplwiz/SHDisconnectNetDrives.c
b/dll/shellext/netplwiz/SHDisconnectNetDrives.c
new file mode 100644
index 0000000000..c886052d5b
--- /dev/null
+++ b/dll/shellext/netplwiz/SHDisconnectNetDrives.c
@@ -0,0 +1,197 @@
+/*
+ * PROJECT: ReactOS Shell
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Implements the Disconnct Network Drive dialog
+ * COPYRIGHT: Copyright 2018 Jared Smudde (computerwhiz02(a)hotmail.com)
+ */
+
+#include "netplwiz.h"
+#include <wine/debug.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(netplwiz);
+
+HINSTANCE hInstance;
+
+VOID InitializeListView(HWND hDlg)
+{
+ HWND hListView = GetDlgItem(hDlg, IDC_CONNECTEDDRIVELIST);
+ LV_COLUMN column;
+ WCHAR szLetter[100], szPath[100];
+
+ if (hListView == NULL)
+ return;
+
+ LoadStringW(hInstance, IDS_DRIVE_LETTER, szLetter, _countof(szLetter));
+ LoadStringW(hInstance, IDS_NETWORK_PATH, szPath, _countof(szPath));
+
+ column.mask = LVCF_WIDTH | LVCF_TEXT;
+ column.pszText = szLetter;
+ column.cx = 75;
+ ListView_InsertColumn(hListView, 0, &column);
+
+ column.mask = LVCF_WIDTH | LVCF_TEXT;
+ column.pszText = szPath;
+ column.cx = 150;
+ ListView_InsertColumn(hListView, 1, &column);
+}
+
+VOID EnumerateConnectedDrives(HWND hDlg)
+{
+ LV_ITEM item;
+ HIMAGELIST hImgList;
+ HICON hIconDrive = NULL;
+ HMODULE hShell32;
+ HWND hListView = GetDlgItem(hDlg, IDC_CONNECTEDDRIVELIST);
+
+ DWORD dRet;
+ HANDLE hEnum;
+ LPNETRESOURCE lpRes;
+ DWORD dwSize = 0x1000;
+ DWORD dwCount = -1;
+ LPNETRESOURCE lpCur;
+
+ /* List View Icons */
+ hShell32 = GetModuleHandleW(L"shell32.dll");
+ if (hShell32 == NULL)
+ return;
+
+ hIconDrive = LoadImageW(hShell32, MAKEINTRESOURCEW(10), IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
+ if (hIconDrive == NULL)
+ return;
+
+ hImgList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 1, 1);
+ if (hImgList == NULL)
+ {
+ DestroyIcon(hIconDrive);
+ return;
+ }
+
+ ImageList_AddIcon(hImgList, hIconDrive);
+ DestroyIcon(hIconDrive);
+ ListView_SetImageList(hListView, hImgList, LVSIL_SMALL);
+
+ dRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, 0, NULL, &hEnum);
+ if (dRet != WN_SUCCESS)
+ {
+ return;
+ }
+
+ lpRes = HeapAlloc(GetProcessHeap(), 0, dwSize);
+ if (!lpRes)
+ {
+ WNetCloseEnum(hEnum);
+ return;
+ }
+
+ do
+ {
+ ZeroMemory(lpRes, dwSize);
+ dRet = WNetEnumResource(hEnum, &dwCount, lpRes, &dwSize);
+ if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
+ {
+ lpCur = lpRes;
+ for (; dwCount; dwCount--)
+ {
+ ZeroMemory(&item, sizeof(item));
+ item.mask = LVIF_TEXT | LVIF_IMAGE;
+ item.iImage = 0;
+ item.pszText = lpCur->lpLocalName;
+ item.lParam = 0;
+ item.iItem = ListView_InsertItem(hListView, &item);
+ ListView_SetItemText(hListView, item.iItem, 1, lpCur->lpRemoteName);
+ lpCur++;
+ }
+ }
+ } while (dRet != WN_NO_MORE_ENTRIES);
+
+ HeapFree(GetProcessHeap(), 0, lpRes);
+ WNetCloseEnum(hEnum);
+}
+
+
+VOID UpdateButtonStatus(WPARAM wParam, LPARAM lParam, HWND hDlg)
+{
+ LPNMHDR pnmh = (LPNMHDR)lParam;
+ HWND hListView = GetDlgItem(hDlg, IDC_CONNECTEDDRIVELIST);
+ HWND hOkButton = GetDlgItem(hDlg, ID_OK);
+
+ if (pnmh->hwndFrom == hListView)
+ {
+ switch (pnmh->code)
+ {
+ case LVN_ITEMCHANGED:
+ if (ListView_GetSelectedCount(hListView))
+ {
+ EnableWindow(hOkButton, TRUE);
+ }
+ else
+ {
+ EnableWindow(hOkButton, FALSE);
+ }
+ break;
+ }
+ }
+}
+
+DWORD DisconnectDriveExit(HWND hDlg)
+{
+ TCHAR driveLetter[10];
+ HRESULT hr;
+ HWND hListView = GetDlgItem(hDlg, IDC_CONNECTEDDRIVELIST);
+ INT nItem = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
+
+ if (nItem == -1)
+ return 0;
+
+ ListView_GetItemText(hListView, nItem, 0, driveLetter, _countof(driveLetter));
+ hr = WNetCancelConnection2(driveLetter, CONNECT_UPDATE_PROFILE, FALSE);
+
+ EndDialog(hDlg, ID_OK);
+ return hr;
+}
+
+static INT_PTR CALLBACK DisconnectDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
+{
+ HICON hIcon, hIconSm;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ hIcon = (HICON)LoadImageW(hInstance,
MAKEINTRESOURCEW(IDI_DISCONNECT_NET_DRIVES), IMAGE_ICON, 0, 0, LR_SHARED |
LR_DEFAULTSIZE);
+ hIconSm = (HICON)CopyImage(hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE);
+ SendMessageW(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
+ SendMessageW(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
+ EnableWindow(GetDlgItem(hDlg, ID_OK), FALSE);
+ InitializeListView(hDlg);
+ EnumerateConnectedDrives(hDlg);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case ID_OK:
+ DisconnectDriveExit(hDlg);
+ break;
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ break;
+ }
+ break;
+
+ case WM_NOTIFY:
+ UpdateButtonStatus(wParam, lParam, hDlg);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+HRESULT WINAPI SHDisconnectNetDrives(PVOID Unused)
+{
+ DialogBoxW(hInstance, MAKEINTRESOURCEW(IDD_DISCONNECTDRIVES), NULL,
DisconnectDlgProc);
+ return S_OK;
+}
diff --git a/dll/shellext/netplwiz/lang/en-US.rc b/dll/shellext/netplwiz/lang/en-US.rc
new file mode 100644
index 0000000000..4fae14baf7
--- /dev/null
+++ b/dll/shellext/netplwiz/lang/en-US.rc
@@ -0,0 +1,21 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+IDD_DISCONNECTDRIVES DIALOGEX 0, 0, 300, 200
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Disconnect Network Drives"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Select the network drive(s) you want to disconnect, then click OK.",
-1, 7, 7, 286, 8
+ LTEXT "&Network Drives:", -1, 7, 23, 286, 8
+ CONTROL "", IDC_CONNECTEDDRIVELIST, "SysListView32", LVS_REPORT |
LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_SINGLESEL | WS_CHILD | WS_VISIBLE | WS_BORDER
| WS_TABSTOP, 7, 31, 286, 140
+ PUSHBUTTON "OK", ID_OK, 189, 179, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 243, 179, 50, 14
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DIALOG_CAPTION "Disconnect Network Drive"
+ IDS_DRIVE_LETTER "Drive Letter"
+ IDS_NETWORK_PATH "Network Path"
+ IDS_NO_DRIVES "You have no network drives to disconnect."
+END
diff --git a/dll/shellext/netplwiz/netplwiz.c b/dll/shellext/netplwiz/netplwiz.c
new file mode 100644
index 0000000000..27fa3872ed
--- /dev/null
+++ b/dll/shellext/netplwiz/netplwiz.c
@@ -0,0 +1,51 @@
+/*
+ * PROJECT: ReactOS Shell
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Implements the Connect/Disconnect Network places dialogs
+ * COPYRIGHT: Copyright 2018 Jared Smudde (computerwhiz02(a)hotmail.com)
+ */
+
+#include "netplwiz.h"
+
+HRESULT WINAPI
+DllCanUnloadNow(VOID)
+{
+ return S_OK;
+}
+
+HRESULT WINAPI
+DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ *ppv = NULL;
+ return E_NOINTERFACE;
+}
+
+HRESULT WINAPI
+DllRegisterServer(VOID)
+{
+ return S_OK;
+}
+
+HRESULT WINAPI
+DllUnregisterServer(VOID)
+{
+ return S_OK;
+}
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
+{
+ INITCOMMONCONTROLSEX iccx;
+ hInstance = hinstDLL;
+ switch (dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ iccx.dwICC = ICC_STANDARD_CLASSES | ICC_LISTVIEW_CLASSES;
+ InitCommonControlsEx(&iccx);
+ DisableThreadLibraryCalls(hInstance);
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/dll/shellext/netplwiz/netplwiz.h b/dll/shellext/netplwiz/netplwiz.h
new file mode 100644
index 0000000000..13e8b71ffc
--- /dev/null
+++ b/dll/shellext/netplwiz/netplwiz.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "resource.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+
+#include <windef.h>
+#include <winbase.h>
+#include <winuser.h>
+#include <winnetwk.h>
+#include <commctrl.h>
+
+#include <strsafe.h>
+
+extern HINSTANCE hInstance;
diff --git a/dll/shellext/netplwiz/netplwiz.rc b/dll/shellext/netplwiz/netplwiz.rc
new file mode 100644
index 0000000000..aac48703fb
--- /dev/null
+++ b/dll/shellext/netplwiz/netplwiz.rc
@@ -0,0 +1,26 @@
+#include <windef.h>
+#include <winuser.h>
+#include <commctrl.h>
+
+#include "resource.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "Map Network Drives"
+#define REACTOS_STR_INTERNAL_NAME "netplwiz.dll"
+#define REACTOS_STR_ORIGINAL_FILENAME "netplwiz.dll"
+
+#include <reactos/version.rc>
+
+#include <reactos/manifest_hosted.rc>
+
+/* Icons */
+IDI_DISCONNECT_NET_DRIVES ICON "res/4400.ico"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+#ifdef LANGUAGE_EN_US
+ #include "lang/en-US.rc"
+#endif
diff --git a/dll/shellext/netplwiz/netplwiz.spec b/dll/shellext/netplwiz/netplwiz.spec
new file mode 100644
index 0000000000..433874cb0b
--- /dev/null
+++ b/dll/shellext/netplwiz/netplwiz.spec
@@ -0,0 +1,14 @@
+1 stub AddNetPlaceRunDll
+2 stub PassportWizardRunDll
+3 stub PublishRunDll
+4 stub UsersRunDll
+5 stub ClearAutoLogon
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+8 stub -private DllInstall
+9 stdcall DllMain(ptr long ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
+12 stub NetAccessWizard
+13 stub NetPlacesWizardDoModal
+14 stdcall SHDisconnectNetDrives(ptr)
diff --git a/dll/shellext/netplwiz/res/4400.ico b/dll/shellext/netplwiz/res/4400.ico
new file mode 100644
index 0000000000..1498e69384
Binary files /dev/null and b/dll/shellext/netplwiz/res/4400.ico differ
diff --git a/dll/shellext/netplwiz/resource.h b/dll/shellext/netplwiz/resource.h
new file mode 100644
index 0000000000..71fe598490
--- /dev/null
+++ b/dll/shellext/netplwiz/resource.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#ifndef IDC_STATIC
+#define IDC_STATIC -1
+#endif
+
+/* Controls */
+#define IDC_CONNECTEDDRIVELIST 1071
+#define ID_OK 100
+
+/* Dialogs */
+#define IDD_DISCONNECTDRIVES 2100
+
+/* Icons */
+#define IDI_DISCONNECT_NET_DRIVES 4400
+
+/* Strings */
+#define IDS_DIALOG_CAPTION 13000
+#define IDS_DRIVE_LETTER 13001
+#define IDS_NETWORK_PATH 13002
+#define IDS_NO_DRIVES 13003