Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

279 lines
9.0 KiB

#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;
}