280 lines
9 KiB
C++
280 lines
9 KiB
C++
|
#include "stdafx.h"
|
||
|
|
||
|
// Disconnect drive dialog
|
||
|
// History:
|
||
|
// dsheldon 11/09/2000 created
|
||
|
|
||
|
class CDisconnectDrives : public CDialog
|
||
|
{
|
||
|
private:
|
||
|
void _InitializeDriveListview(HWND hwnd);
|
||
|
BOOL _DriveAlreadyInList(HWND hwndList, NETRESOURCE* pnr);
|
||
|
UINT _FillDriveList(HWND hwnd, DWORD dwScope);
|
||
|
void _DoDisconnect(HWND hwnd);
|
||
|
void _EnableButtons(HWND hwnd);
|
||
|
INT_PTR DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
|
||
|
// Data
|
||
|
};
|
||
|
|
||
|
INT_PTR CDisconnectDrives::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
INT_PTR fReturn = FALSE;
|
||
|
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
{
|
||
|
TCHAR szCaption[256];
|
||
|
LoadString(g_hinst, IDS_DISCONNECT_CAPTION, szCaption, ARRAYSIZE(szCaption));
|
||
|
SetWindowText(hwndDlg, szCaption);
|
||
|
|
||
|
HICON hIcon = LoadIcon(g_hinst, MAKEINTRESOURCE(IDI_PSW));
|
||
|
SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) hIcon);
|
||
|
SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_SMALL, (LPARAM) hIcon);
|
||
|
_InitializeDriveListview(hwndDlg);
|
||
|
if (_FillDriveList(hwndDlg, RESOURCE_CONNECTED) + _FillDriveList(hwndDlg, RESOURCE_REMEMBERED) == 0)
|
||
|
{
|
||
|
DisplayFormatMessage(hwndDlg, IDS_DISCONNECTDRIVETITLE, IDS_NONETDRIVES, MB_ICONINFORMATION | MB_OK);
|
||
|
EndDialog(hwndDlg, IDCANCEL);
|
||
|
}
|
||
|
_EnableButtons(hwndDlg);
|
||
|
|
||
|
fReturn = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
case WM_COMMAND:
|
||
|
switch (HIWORD(wParam))
|
||
|
{
|
||
|
case BN_CLICKED:
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
case IDOK:
|
||
|
_DoDisconnect(hwndDlg);
|
||
|
// Fall through
|
||
|
case IDCANCEL:
|
||
|
EndDialog(hwndDlg, LOWORD(wParam));
|
||
|
fReturn = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case WM_NOTIFY:
|
||
|
switch ((int) wParam)
|
||
|
{
|
||
|
case IDC_DRIVELIST:
|
||
|
if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
|
||
|
{
|
||
|
_EnableButtons(hwndDlg);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return fReturn;
|
||
|
}
|
||
|
|
||
|
#define COL_LOCALNAME 0
|
||
|
#define COL_REMOTENAME 1
|
||
|
#define COL_COMMENT 2
|
||
|
|
||
|
const UINT c_auTileColumns[] = {COL_LOCALNAME, COL_REMOTENAME, COL_COMMENT};
|
||
|
const UINT c_auTileSubItems[] = {COL_REMOTENAME, COL_COMMENT};
|
||
|
|
||
|
void CDisconnectDrives::_InitializeDriveListview(HWND hwnd)
|
||
|
{
|
||
|
HWND hwndList = GetDlgItem(hwnd, IDC_DRIVELIST);
|
||
|
ListView_SetView(hwndList, LV_VIEW_TILE);
|
||
|
|
||
|
for (int i=0; i<ARRAYSIZE(c_auTileColumns); i++)
|
||
|
{
|
||
|
LV_COLUMN col;
|
||
|
col.mask = LVCF_SUBITEM;
|
||
|
col.iSubItem = c_auTileColumns[i];
|
||
|
ListView_InsertColumn(hwndList, i, &col);
|
||
|
}
|
||
|
|
||
|
RECT rc;
|
||
|
GetClientRect(hwndList, &rc);
|
||
|
|
||
|
LVTILEVIEWINFO lvtvi;
|
||
|
lvtvi.cbSize = sizeof(LVTILEVIEWINFO);
|
||
|
lvtvi.dwMask = LVTVIM_TILESIZE | LVTVIM_COLUMNS;
|
||
|
lvtvi.dwFlags = LVTVIF_FIXEDWIDTH;
|
||
|
|
||
|
// Bug 298835 - Leave room for the scroll bar when setting tile sizes or listview gets screwed up.
|
||
|
lvtvi.sizeTile.cx = ((rc.right-rc.left) - GetSystemMetrics(SM_CXVSCROLL))/2;
|
||
|
lvtvi.cLines = ARRAYSIZE(c_auTileSubItems);
|
||
|
ListView_SetTileViewInfo(hwndList, &lvtvi);
|
||
|
|
||
|
HIMAGELIST himlLarge, himlSmall;
|
||
|
Shell_GetImageLists(&himlLarge, &himlSmall);
|
||
|
ListView_SetImageList(hwndList, himlLarge, LVSIL_NORMAL);
|
||
|
ListView_SetImageList(hwndList, himlSmall, LVSIL_SMALL);
|
||
|
}
|
||
|
|
||
|
BOOL CDisconnectDrives::_DriveAlreadyInList(HWND hwndList, NETRESOURCE* pnr)
|
||
|
{
|
||
|
BOOL fAlreadyInList = FALSE;
|
||
|
if (pnr->lpLocalName)
|
||
|
{
|
||
|
int cItems = ListView_GetItemCount(hwndList);
|
||
|
if (-1 != cItems)
|
||
|
{
|
||
|
int i = 0;
|
||
|
while ((i < cItems) && !fAlreadyInList)
|
||
|
{
|
||
|
WCHAR szItem[MAX_PATH]; *szItem = 0;
|
||
|
ListView_GetItemText(hwndList, i, 0, szItem, ARRAYSIZE(szItem));
|
||
|
if (0 == StrCmpI(szItem, pnr->lpLocalName))
|
||
|
{
|
||
|
fAlreadyInList = TRUE;
|
||
|
}
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return fAlreadyInList;
|
||
|
}
|
||
|
|
||
|
UINT CDisconnectDrives::_FillDriveList(HWND hwnd, DWORD dwScope)
|
||
|
{
|
||
|
UINT nAdded = 0;
|
||
|
HWND hwndList = GetDlgItem(hwnd, IDC_DRIVELIST);
|
||
|
|
||
|
HANDLE hEnum = NULL;
|
||
|
DWORD dwRes = WNetOpenEnum(dwScope, RESOURCETYPE_DISK, 0, NULL, &hEnum);
|
||
|
if (NO_ERROR == dwRes)
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
BYTE rgBuffer[16 * 1024];
|
||
|
DWORD cbSize = sizeof (rgBuffer);
|
||
|
DWORD cEntries = -1;
|
||
|
dwRes = WNetEnumResource(hEnum, &cEntries, (void*) rgBuffer, &cbSize);
|
||
|
|
||
|
if ((ERROR_MORE_DATA == dwRes) ||
|
||
|
(NO_ERROR == dwRes))
|
||
|
{
|
||
|
NETRESOURCE* pnrResults = (NETRESOURCE*) rgBuffer;
|
||
|
|
||
|
for (DWORD iEntry = 0; iEntry < cEntries; iEntry ++)
|
||
|
{
|
||
|
WCHAR szNone[MAX_PATH + 1];
|
||
|
NETRESOURCE* pnr = pnrResults + iEntry;
|
||
|
|
||
|
if (!_DriveAlreadyInList(hwndList, pnr))
|
||
|
{
|
||
|
nAdded ++;
|
||
|
|
||
|
LV_ITEM lvi = {0};
|
||
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
||
|
if (pnr->lpLocalName)
|
||
|
{
|
||
|
lvi.pszText = pnr->lpLocalName;
|
||
|
lvi.lParam = TRUE; // Flag that says, "this connection has a local name (device letter)"
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LoadString(g_hinst, IDS_NONE, szNone, ARRAYSIZE(szNone));
|
||
|
lvi.pszText = szNone;
|
||
|
}
|
||
|
|
||
|
lvi.iImage = Shell_GetCachedImageIndex(L"shell32.dll", II_DRIVENET, 0x0);
|
||
|
|
||
|
int iItem = ListView_InsertItem(hwndList, &lvi);
|
||
|
if (iItem != -1)
|
||
|
{
|
||
|
LVTILEINFO lvti;
|
||
|
lvti.cbSize = sizeof(LVTILEINFO);
|
||
|
lvti.iItem = iItem;
|
||
|
lvti.cColumns = ARRAYSIZE(c_auTileSubItems);
|
||
|
lvti.puColumns = (UINT*)c_auTileSubItems;
|
||
|
ListView_SetTileInfo(hwndList, &lvti);
|
||
|
|
||
|
ListView_SetItemText(hwndList, iItem, 1, pnr->lpRemoteName);
|
||
|
ListView_SetItemText(hwndList, iItem, 2, pnr->lpComment);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} while (ERROR_MORE_DATA == dwRes);
|
||
|
|
||
|
WNetCloseEnum(hEnum);
|
||
|
}
|
||
|
|
||
|
return nAdded;
|
||
|
}
|
||
|
|
||
|
void CDisconnectDrives::_DoDisconnect(HWND hwnd)
|
||
|
{
|
||
|
SetCursor(LoadCursor(NULL, IDC_WAIT));
|
||
|
|
||
|
HWND hwndList = GetDlgItem(hwnd, IDC_DRIVELIST);
|
||
|
int iSelectedItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
|
||
|
while (-1 != iSelectedItem)
|
||
|
{
|
||
|
WCHAR szRemoteName[MAX_PATH + 1];
|
||
|
ListView_GetItemText(hwndList, iSelectedItem, COL_REMOTENAME, szRemoteName, ARRAYSIZE(szRemoteName));
|
||
|
WCHAR szLocalName[MAX_PATH + 1];
|
||
|
ListView_GetItemText(hwndList, iSelectedItem, COL_LOCALNAME, szLocalName, ARRAYSIZE(szLocalName));
|
||
|
|
||
|
LVITEM lvi = {0};
|
||
|
lvi.iItem = iSelectedItem;
|
||
|
lvi.mask = LVIF_PARAM;
|
||
|
ListView_GetItem(hwndList, &lvi);
|
||
|
|
||
|
BOOL fHasDevice = (BOOL) lvi.lParam;
|
||
|
|
||
|
// Try non-forcing disconnect
|
||
|
DWORD dwRes = WNetCancelConnection2(fHasDevice ? szLocalName : szRemoteName, CONNECT_UPDATE_PROFILE, FALSE);
|
||
|
|
||
|
if ((ERROR_OPEN_FILES == dwRes) ||
|
||
|
(ERROR_DEVICE_IN_USE == dwRes))
|
||
|
{
|
||
|
if (IDYES == DisplayFormatMessage(hwnd, IDS_DISCONNECTDRIVETITLE, fHasDevice ? IDS_DISCONNECT_CONFIRM : IDS_DISCONNECT_CONFIRM_NODEV, MB_ICONWARNING | MB_YESNO, szLocalName, szRemoteName))
|
||
|
{
|
||
|
dwRes = WNetCancelConnection2(fHasDevice ? szLocalName : szRemoteName, CONNECT_UPDATE_PROFILE, TRUE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwRes = NO_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (NO_ERROR != dwRes)
|
||
|
{
|
||
|
WCHAR szMessage[512];
|
||
|
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, (DWORD) dwRes, 0, szMessage, ARRAYSIZE(szMessage), NULL))
|
||
|
{
|
||
|
DisplayFormatMessage(hwnd, IDS_DISCONNECTDRIVETITLE, IDS_DISCONNECTERROR, MB_ICONERROR | MB_OK, szLocalName, szRemoteName, szMessage);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
iSelectedItem = ListView_GetNextItem(hwndList, iSelectedItem, LVNI_SELECTED);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CDisconnectDrives::_EnableButtons(HWND hwnd)
|
||
|
{
|
||
|
UINT nSelected = ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_DRIVELIST));
|
||
|
EnableWindow(GetDlgItem(hwnd, IDOK), (nSelected > 0));
|
||
|
}
|
||
|
|
||
|
STDAPI_(DWORD) SHDisconnectNetDrives(HWND hwndParent)
|
||
|
{
|
||
|
TCHAR szCaption[256];
|
||
|
LoadString(g_hinst, IDS_DISCONNECT_CAPTION, szCaption, ARRAYSIZE(szCaption));
|
||
|
CEnsureSingleInstance ESI(szCaption);
|
||
|
|
||
|
if (!ESI.ShouldExit())
|
||
|
{
|
||
|
CDisconnectDrives disc;
|
||
|
disc.DoModal(g_hinst, MAKEINTRESOURCE(IDD_DISCONNECTDRIVES), NULL);
|
||
|
}
|
||
|
return NO_ERROR;
|
||
|
}
|