[NETPLWIZ] Implement the Disconnect Network Drive dialog. (#1522)
[reactos.git] / dll / shellext / netplwiz / SHDisconnectNetDrives.c
1 /*
2 * PROJECT: ReactOS Shell
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Implements the Disconnct Network Drive dialog
5 * COPYRIGHT: Copyright 2018 Jared Smudde (computerwhiz02@hotmail.com)
6 */
7
8 #include "netplwiz.h"
9 #include <wine/debug.h>
10
11 WINE_DEFAULT_DEBUG_CHANNEL(netplwiz);
12
13 HINSTANCE hInstance;
14
15 VOID InitializeListView(HWND hDlg)
16 {
17 HWND hListView = GetDlgItem(hDlg, IDC_CONNECTEDDRIVELIST);
18 LV_COLUMN column;
19 WCHAR szLetter[100], szPath[100];
20
21 if (hListView == NULL)
22 return;
23
24 LoadStringW(hInstance, IDS_DRIVE_LETTER, szLetter, _countof(szLetter));
25 LoadStringW(hInstance, IDS_NETWORK_PATH, szPath, _countof(szPath));
26
27 column.mask = LVCF_WIDTH | LVCF_TEXT;
28 column.pszText = szLetter;
29 column.cx = 75;
30 ListView_InsertColumn(hListView, 0, &column);
31
32 column.mask = LVCF_WIDTH | LVCF_TEXT;
33 column.pszText = szPath;
34 column.cx = 150;
35 ListView_InsertColumn(hListView, 1, &column);
36 }
37
38 VOID EnumerateConnectedDrives(HWND hDlg)
39 {
40 LV_ITEM item;
41 HIMAGELIST hImgList;
42 HICON hIconDrive = NULL;
43 HMODULE hShell32;
44 HWND hListView = GetDlgItem(hDlg, IDC_CONNECTEDDRIVELIST);
45
46 DWORD dRet;
47 HANDLE hEnum;
48 LPNETRESOURCE lpRes;
49 DWORD dwSize = 0x1000;
50 DWORD dwCount = -1;
51 LPNETRESOURCE lpCur;
52
53 /* List View Icons */
54 hShell32 = GetModuleHandleW(L"shell32.dll");
55 if (hShell32 == NULL)
56 return;
57
58 hIconDrive = LoadImageW(hShell32, MAKEINTRESOURCEW(10), IMAGE_ICON,
59 GetSystemMetrics(SM_CXSMICON),
60 GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
61 if (hIconDrive == NULL)
62 return;
63
64 hImgList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 1, 1);
65 if (hImgList == NULL)
66 {
67 DestroyIcon(hIconDrive);
68 return;
69 }
70
71 ImageList_AddIcon(hImgList, hIconDrive);
72 DestroyIcon(hIconDrive);
73 ListView_SetImageList(hListView, hImgList, LVSIL_SMALL);
74
75 dRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, 0, NULL, &hEnum);
76 if (dRet != WN_SUCCESS)
77 {
78 return;
79 }
80
81 lpRes = HeapAlloc(GetProcessHeap(), 0, dwSize);
82 if (!lpRes)
83 {
84 WNetCloseEnum(hEnum);
85 return;
86 }
87
88 do
89 {
90 ZeroMemory(lpRes, dwSize);
91 dRet = WNetEnumResource(hEnum, &dwCount, lpRes, &dwSize);
92 if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
93 {
94 lpCur = lpRes;
95 for (; dwCount; dwCount--)
96 {
97 ZeroMemory(&item, sizeof(item));
98 item.mask = LVIF_TEXT | LVIF_IMAGE;
99 item.iImage = 0;
100 item.pszText = lpCur->lpLocalName;
101 item.lParam = 0;
102 item.iItem = ListView_InsertItem(hListView, &item);
103 ListView_SetItemText(hListView, item.iItem, 1, lpCur->lpRemoteName);
104 lpCur++;
105 }
106 }
107 } while (dRet != WN_NO_MORE_ENTRIES);
108
109 HeapFree(GetProcessHeap(), 0, lpRes);
110 WNetCloseEnum(hEnum);
111 }
112
113
114 VOID UpdateButtonStatus(WPARAM wParam, LPARAM lParam, HWND hDlg)
115 {
116 LPNMHDR pnmh = (LPNMHDR)lParam;
117 HWND hListView = GetDlgItem(hDlg, IDC_CONNECTEDDRIVELIST);
118 HWND hOkButton = GetDlgItem(hDlg, ID_OK);
119
120 if (pnmh->hwndFrom == hListView)
121 {
122 switch (pnmh->code)
123 {
124 case LVN_ITEMCHANGED:
125 if (ListView_GetSelectedCount(hListView))
126 {
127 EnableWindow(hOkButton, TRUE);
128 }
129 else
130 {
131 EnableWindow(hOkButton, FALSE);
132 }
133 break;
134 }
135 }
136 }
137
138 DWORD DisconnectDriveExit(HWND hDlg)
139 {
140 TCHAR driveLetter[10];
141 HRESULT hr;
142 HWND hListView = GetDlgItem(hDlg, IDC_CONNECTEDDRIVELIST);
143 INT nItem = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
144
145 if (nItem == -1)
146 return 0;
147
148 ListView_GetItemText(hListView, nItem, 0, driveLetter, _countof(driveLetter));
149 hr = WNetCancelConnection2(driveLetter, CONNECT_UPDATE_PROFILE, FALSE);
150
151 EndDialog(hDlg, ID_OK);
152 return hr;
153 }
154
155 static INT_PTR CALLBACK DisconnectDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
156 {
157 HICON hIcon, hIconSm;
158 switch (uMsg)
159 {
160 case WM_INITDIALOG:
161 hIcon = (HICON)LoadImageW(hInstance, MAKEINTRESOURCEW(IDI_DISCONNECT_NET_DRIVES), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
162 hIconSm = (HICON)CopyImage(hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE);
163 SendMessageW(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
164 SendMessageW(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
165 EnableWindow(GetDlgItem(hDlg, ID_OK), FALSE);
166 InitializeListView(hDlg);
167 EnumerateConnectedDrives(hDlg);
168 return TRUE;
169
170 case WM_COMMAND:
171 switch (LOWORD(wParam))
172 {
173 case ID_OK:
174 DisconnectDriveExit(hDlg);
175 break;
176 case IDCANCEL:
177 EndDialog(hDlg, IDCANCEL);
178 break;
179 }
180 break;
181
182 case WM_NOTIFY:
183 UpdateButtonStatus(wParam, lParam, hDlg);
184 break;
185
186 default:
187 return FALSE;
188 }
189
190 return TRUE;
191 }
192
193 HRESULT WINAPI SHDisconnectNetDrives(PVOID Unused)
194 {
195 DialogBoxW(hInstance, MAKEINTRESOURCEW(IDD_DISCONNECTDRIVES), NULL, DisconnectDlgProc);
196 return S_OK;
197 }