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

  1. #include "stdafx.h"
  2. // Disconnect drive dialog
  3. // History:
  4. // dsheldon 11/09/2000 created
  5. class CDisconnectDrives : public CDialog
  6. {
  7. private:
  8. void _InitializeDriveListview(HWND hwnd);
  9. BOOL _DriveAlreadyInList(HWND hwndList, NETRESOURCE* pnr);
  10. UINT _FillDriveList(HWND hwnd, DWORD dwScope);
  11. void _DoDisconnect(HWND hwnd);
  12. void _EnableButtons(HWND hwnd);
  13. INT_PTR DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  14. // Data
  15. };
  16. INT_PTR CDisconnectDrives::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  17. {
  18. INT_PTR fReturn = FALSE;
  19. switch (uMsg)
  20. {
  21. case WM_INITDIALOG:
  22. {
  23. TCHAR szCaption[256];
  24. LoadString(g_hinst, IDS_DISCONNECT_CAPTION, szCaption, ARRAYSIZE(szCaption));
  25. SetWindowText(hwndDlg, szCaption);
  26. HICON hIcon = LoadIcon(g_hinst, MAKEINTRESOURCE(IDI_PSW));
  27. SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) hIcon);
  28. SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_SMALL, (LPARAM) hIcon);
  29. _InitializeDriveListview(hwndDlg);
  30. if (_FillDriveList(hwndDlg, RESOURCE_CONNECTED) + _FillDriveList(hwndDlg, RESOURCE_REMEMBERED) == 0)
  31. {
  32. DisplayFormatMessage(hwndDlg, IDS_DISCONNECTDRIVETITLE, IDS_NONETDRIVES, MB_ICONINFORMATION | MB_OK);
  33. EndDialog(hwndDlg, IDCANCEL);
  34. }
  35. _EnableButtons(hwndDlg);
  36. fReturn = TRUE;
  37. }
  38. break;
  39. case WM_COMMAND:
  40. switch (HIWORD(wParam))
  41. {
  42. case BN_CLICKED:
  43. switch (LOWORD(wParam))
  44. {
  45. case IDOK:
  46. _DoDisconnect(hwndDlg);
  47. // Fall through
  48. case IDCANCEL:
  49. EndDialog(hwndDlg, LOWORD(wParam));
  50. fReturn = TRUE;
  51. break;
  52. }
  53. }
  54. break;
  55. case WM_NOTIFY:
  56. switch ((int) wParam)
  57. {
  58. case IDC_DRIVELIST:
  59. if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
  60. {
  61. _EnableButtons(hwndDlg);
  62. }
  63. break;
  64. }
  65. break;
  66. }
  67. return fReturn;
  68. }
  69. #define COL_LOCALNAME 0
  70. #define COL_REMOTENAME 1
  71. #define COL_COMMENT 2
  72. const UINT c_auTileColumns[] = {COL_LOCALNAME, COL_REMOTENAME, COL_COMMENT};
  73. const UINT c_auTileSubItems[] = {COL_REMOTENAME, COL_COMMENT};
  74. void CDisconnectDrives::_InitializeDriveListview(HWND hwnd)
  75. {
  76. HWND hwndList = GetDlgItem(hwnd, IDC_DRIVELIST);
  77. ListView_SetView(hwndList, LV_VIEW_TILE);
  78. for (int i=0; i<ARRAYSIZE(c_auTileColumns); i++)
  79. {
  80. LV_COLUMN col;
  81. col.mask = LVCF_SUBITEM;
  82. col.iSubItem = c_auTileColumns[i];
  83. ListView_InsertColumn(hwndList, i, &col);
  84. }
  85. RECT rc;
  86. GetClientRect(hwndList, &rc);
  87. LVTILEVIEWINFO lvtvi;
  88. lvtvi.cbSize = sizeof(LVTILEVIEWINFO);
  89. lvtvi.dwMask = LVTVIM_TILESIZE | LVTVIM_COLUMNS;
  90. lvtvi.dwFlags = LVTVIF_FIXEDWIDTH;
  91. // Bug 298835 - Leave room for the scroll bar when setting tile sizes or listview gets screwed up.
  92. lvtvi.sizeTile.cx = ((rc.right-rc.left) - GetSystemMetrics(SM_CXVSCROLL))/2;
  93. lvtvi.cLines = ARRAYSIZE(c_auTileSubItems);
  94. ListView_SetTileViewInfo(hwndList, &lvtvi);
  95. HIMAGELIST himlLarge, himlSmall;
  96. Shell_GetImageLists(&himlLarge, &himlSmall);
  97. ListView_SetImageList(hwndList, himlLarge, LVSIL_NORMAL);
  98. ListView_SetImageList(hwndList, himlSmall, LVSIL_SMALL);
  99. }
  100. BOOL CDisconnectDrives::_DriveAlreadyInList(HWND hwndList, NETRESOURCE* pnr)
  101. {
  102. BOOL fAlreadyInList = FALSE;
  103. if (pnr->lpLocalName)
  104. {
  105. int cItems = ListView_GetItemCount(hwndList);
  106. if (-1 != cItems)
  107. {
  108. int i = 0;
  109. while ((i < cItems) && !fAlreadyInList)
  110. {
  111. WCHAR szItem[MAX_PATH]; *szItem = 0;
  112. ListView_GetItemText(hwndList, i, 0, szItem, ARRAYSIZE(szItem));
  113. if (0 == StrCmpI(szItem, pnr->lpLocalName))
  114. {
  115. fAlreadyInList = TRUE;
  116. }
  117. i++;
  118. }
  119. }
  120. }
  121. return fAlreadyInList;
  122. }
  123. UINT CDisconnectDrives::_FillDriveList(HWND hwnd, DWORD dwScope)
  124. {
  125. UINT nAdded = 0;
  126. HWND hwndList = GetDlgItem(hwnd, IDC_DRIVELIST);
  127. HANDLE hEnum = NULL;
  128. DWORD dwRes = WNetOpenEnum(dwScope, RESOURCETYPE_DISK, 0, NULL, &hEnum);
  129. if (NO_ERROR == dwRes)
  130. {
  131. do
  132. {
  133. BYTE rgBuffer[16 * 1024];
  134. DWORD cbSize = sizeof (rgBuffer);
  135. DWORD cEntries = -1;
  136. dwRes = WNetEnumResource(hEnum, &cEntries, (void*) rgBuffer, &cbSize);
  137. if ((ERROR_MORE_DATA == dwRes) ||
  138. (NO_ERROR == dwRes))
  139. {
  140. NETRESOURCE* pnrResults = (NETRESOURCE*) rgBuffer;
  141. for (DWORD iEntry = 0; iEntry < cEntries; iEntry ++)
  142. {
  143. WCHAR szNone[MAX_PATH + 1];
  144. NETRESOURCE* pnr = pnrResults + iEntry;
  145. if (!_DriveAlreadyInList(hwndList, pnr))
  146. {
  147. nAdded ++;
  148. LV_ITEM lvi = {0};
  149. lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  150. if (pnr->lpLocalName)
  151. {
  152. lvi.pszText = pnr->lpLocalName;
  153. lvi.lParam = TRUE; // Flag that says, "this connection has a local name (device letter)"
  154. }
  155. else
  156. {
  157. LoadString(g_hinst, IDS_NONE, szNone, ARRAYSIZE(szNone));
  158. lvi.pszText = szNone;
  159. }
  160. lvi.iImage = Shell_GetCachedImageIndex(L"shell32.dll", II_DRIVENET, 0x0);
  161. int iItem = ListView_InsertItem(hwndList, &lvi);
  162. if (iItem != -1)
  163. {
  164. LVTILEINFO lvti;
  165. lvti.cbSize = sizeof(LVTILEINFO);
  166. lvti.iItem = iItem;
  167. lvti.cColumns = ARRAYSIZE(c_auTileSubItems);
  168. lvti.puColumns = (UINT*)c_auTileSubItems;
  169. ListView_SetTileInfo(hwndList, &lvti);
  170. ListView_SetItemText(hwndList, iItem, 1, pnr->lpRemoteName);
  171. ListView_SetItemText(hwndList, iItem, 2, pnr->lpComment);
  172. }
  173. }
  174. }
  175. }
  176. } while (ERROR_MORE_DATA == dwRes);
  177. WNetCloseEnum(hEnum);
  178. }
  179. return nAdded;
  180. }
  181. void CDisconnectDrives::_DoDisconnect(HWND hwnd)
  182. {
  183. SetCursor(LoadCursor(NULL, IDC_WAIT));
  184. HWND hwndList = GetDlgItem(hwnd, IDC_DRIVELIST);
  185. int iSelectedItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
  186. while (-1 != iSelectedItem)
  187. {
  188. WCHAR szRemoteName[MAX_PATH + 1];
  189. ListView_GetItemText(hwndList, iSelectedItem, COL_REMOTENAME, szRemoteName, ARRAYSIZE(szRemoteName));
  190. WCHAR szLocalName[MAX_PATH + 1];
  191. ListView_GetItemText(hwndList, iSelectedItem, COL_LOCALNAME, szLocalName, ARRAYSIZE(szLocalName));
  192. LVITEM lvi = {0};
  193. lvi.iItem = iSelectedItem;
  194. lvi.mask = LVIF_PARAM;
  195. ListView_GetItem(hwndList, &lvi);
  196. BOOL fHasDevice = (BOOL) lvi.lParam;
  197. // Try non-forcing disconnect
  198. DWORD dwRes = WNetCancelConnection2(fHasDevice ? szLocalName : szRemoteName, CONNECT_UPDATE_PROFILE, FALSE);
  199. if ((ERROR_OPEN_FILES == dwRes) ||
  200. (ERROR_DEVICE_IN_USE == dwRes))
  201. {
  202. if (IDYES == DisplayFormatMessage(hwnd, IDS_DISCONNECTDRIVETITLE, fHasDevice ? IDS_DISCONNECT_CONFIRM : IDS_DISCONNECT_CONFIRM_NODEV, MB_ICONWARNING | MB_YESNO, szLocalName, szRemoteName))
  203. {
  204. dwRes = WNetCancelConnection2(fHasDevice ? szLocalName : szRemoteName, CONNECT_UPDATE_PROFILE, TRUE);
  205. }
  206. else
  207. {
  208. dwRes = NO_ERROR;
  209. }
  210. }
  211. if (NO_ERROR != dwRes)
  212. {
  213. WCHAR szMessage[512];
  214. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, (DWORD) dwRes, 0, szMessage, ARRAYSIZE(szMessage), NULL))
  215. {
  216. DisplayFormatMessage(hwnd, IDS_DISCONNECTDRIVETITLE, IDS_DISCONNECTERROR, MB_ICONERROR | MB_OK, szLocalName, szRemoteName, szMessage);
  217. }
  218. }
  219. iSelectedItem = ListView_GetNextItem(hwndList, iSelectedItem, LVNI_SELECTED);
  220. }
  221. }
  222. void CDisconnectDrives::_EnableButtons(HWND hwnd)
  223. {
  224. UINT nSelected = ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_DRIVELIST));
  225. EnableWindow(GetDlgItem(hwnd, IDOK), (nSelected > 0));
  226. }
  227. STDAPI_(DWORD) SHDisconnectNetDrives(HWND hwndParent)
  228. {
  229. TCHAR szCaption[256];
  230. LoadString(g_hinst, IDS_DISCONNECT_CAPTION, szCaption, ARRAYSIZE(szCaption));
  231. CEnsureSingleInstance ESI(szCaption);
  232. if (!ESI.ShouldExit())
  233. {
  234. CDisconnectDrives disc;
  235. disc.DoModal(g_hinst, MAKEINTRESOURCE(IDD_DISCONNECTDRIVES), NULL);
  236. }
  237. return NO_ERROR;
  238. }