[NETPLWIZ] Implement the Disconnect Network Drive dialog. (#1522)
authorJared Smudde <computerwhiz02@hotmail.com>
Tue, 23 Apr 2019 05:45:49 +0000 (00:45 -0500)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 24 Apr 2019 02:26:12 +0000 (04:26 +0200)
CORE-13516, CORE-13518

dll/shellext/CMakeLists.txt
dll/shellext/netplwiz/CMakeLists.txt [new file with mode: 0644]
dll/shellext/netplwiz/SHDisconnectNetDrives.c [new file with mode: 0644]
dll/shellext/netplwiz/lang/en-US.rc [new file with mode: 0644]
dll/shellext/netplwiz/netplwiz.c [new file with mode: 0644]
dll/shellext/netplwiz/netplwiz.h [new file with mode: 0644]
dll/shellext/netplwiz/netplwiz.rc [new file with mode: 0644]
dll/shellext/netplwiz/netplwiz.spec [new file with mode: 0644]
dll/shellext/netplwiz/res/4400.ico [new file with mode: 0644]
dll/shellext/netplwiz/resource.h [new file with mode: 0644]

index 0f57882..89980c3 100644 (file)
@@ -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 (file)
index 0000000..7d1fc15
--- /dev/null
@@ -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 (file)
index 0000000..c886052
--- /dev/null
@@ -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@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 (file)
index 0000000..4fae14b
--- /dev/null
@@ -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 (file)
index 0000000..27fa387
--- /dev/null
@@ -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@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 (file)
index 0000000..13e8b71
--- /dev/null
@@ -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 (file)
index 0000000..aac4870
--- /dev/null
@@ -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 (file)
index 0000000..433874c
--- /dev/null
@@ -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 (file)
index 0000000..1498e69
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 (file)
index 0000000..71fe598
--- /dev/null
@@ -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