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.

605 lines
15 KiB

  1. /******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1993-1994
  4. *
  5. * TITLE: REGNET.C
  6. *
  7. * VERSION: 4.01
  8. *
  9. * AUTHOR: Tracy Sharpe
  10. *
  11. * DATE: 03 May 1994
  12. *
  13. * Remote registry support for the Registry Editor.
  14. *
  15. *******************************************************************************/
  16. #include "pch.h"
  17. #include "regedit.h"
  18. #include "regkey.h"
  19. #include "regresid.h"
  20. #include <shlobj.h>
  21. #include "reghelp.h"
  22. extern HRESULT SelectComputer(HWND hWnd, LPTSTR pszRemoteName, int cchMax);
  23. const DWORD s_RegConnectHelpIDs[] = {
  24. IDC_REMOTENAME, IDH_REGEDIT_CONNECT,
  25. IDC_BROWSE, IDH_REGEDIT_CONNECT_BROWSE,
  26. 0, 0
  27. };
  28. const DWORD s_RegDisconnectHelpIDs[] = {
  29. IDC_REMOTELIST, IDH_REGEDIT_DISCONNECT,
  30. 0, 0
  31. };
  32. INT_PTR
  33. PASCAL
  34. RegConnectDlgProc(
  35. HWND hWnd,
  36. UINT Message,
  37. WPARAM wParam,
  38. LPARAM lParam
  39. );
  40. VOID
  41. PASCAL
  42. RegConnect_OnCommandBrowse(
  43. HWND hWnd
  44. );
  45. INT_PTR
  46. PASCAL
  47. RegDisconnectDlgProc(
  48. HWND hWnd,
  49. UINT Message,
  50. WPARAM wParam,
  51. LPARAM lParam
  52. );
  53. INT_PTR
  54. PASCAL
  55. RegDisconnect_OnInitDialog(
  56. HWND hWnd
  57. );
  58. VOID
  59. PASCAL
  60. RegDisconnect_OnCommandOk(
  61. HWND hWnd
  62. );
  63. /*******************************************************************************
  64. *
  65. * RegEdit_OnCommandConnect
  66. *
  67. * DESCRIPTION:
  68. *
  69. * PARAMETERS:
  70. *
  71. *******************************************************************************/
  72. VOID
  73. PASCAL
  74. RegEdit_OnCommandConnect(HWND hWnd)
  75. {
  76. UINT ErrorStringID;
  77. TCHAR RemoteName[MAX_PATH];
  78. LPTSTR lpUnslashedRemoteName;
  79. TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  80. DWORD cbComputerName;
  81. TV_ITEM TVItem;
  82. HTREEITEM hPrevTreeItem;
  83. TCHAR ConnectedName[MAX_PATH];
  84. int CompareResult;
  85. HKEY hLocalMachineKey;
  86. HWND hKeyTreeWnd;
  87. TV_INSERTSTRUCT TVInsertStruct;
  88. UINT Index;
  89. TCHAR CheckChildrenKeyName[MAXKEYNAME];
  90. //
  91. // Query the user for the name of the remote computer to connect to.
  92. //
  93. if (SUCCEEDED(SelectComputer(hWnd, (LPTSTR)RemoteName, ARRAYSIZE(RemoteName))))
  94. {
  95. RegEdit_SetWaitCursor(TRUE);
  96. //
  97. //
  98. //
  99. lpUnslashedRemoteName = (RemoteName[0] == TEXT('\\') &&
  100. RemoteName[1] == TEXT('\\')) ? &RemoteName[2] : &RemoteName[0];
  101. CharLower(lpUnslashedRemoteName);
  102. CharUpperBuff(lpUnslashedRemoteName, 1);
  103. //
  104. // Check if the user is trying to connect to the local computer and prevent
  105. // this.
  106. //
  107. cbComputerName = sizeof(ComputerName)/sizeof(TCHAR);
  108. if (GetComputerName(ComputerName, &cbComputerName)) {
  109. if (lstrcmpi(lpUnslashedRemoteName, ComputerName) == 0) {
  110. ErrorStringID = IDS_CONNECTNOTLOCAL;
  111. goto error_ShowDialog;
  112. }
  113. }
  114. //
  115. // Check if the user is trying to connect to an already existing registry
  116. // connection and prevent this.
  117. //
  118. hKeyTreeWnd = g_RegEditData.hKeyTreeWnd;
  119. TVItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE;
  120. TVItem.hItem = TreeView_GetRoot(hKeyTreeWnd);
  121. TVItem.pszText = ConnectedName;
  122. TVItem.cchTextMax = sizeof(ConnectedName)/sizeof(TCHAR);
  123. while (TRUE) {
  124. hPrevTreeItem = TVItem.hItem;
  125. TVItem.hItem = TreeView_GetNextSibling(hKeyTreeWnd, TVItem.hItem);
  126. if (TVItem.hItem == NULL)
  127. break;
  128. TreeView_GetItem(hKeyTreeWnd, &TVItem);
  129. CompareResult = lstrcmpi(lpUnslashedRemoteName, ConnectedName);
  130. if (CompareResult == 0) {
  131. //
  132. // We're already connected to this machine. Set the focus to the
  133. // connection so the user can see where it is.
  134. //
  135. TreeView_SelectItem(hKeyTreeWnd, TVItem.hItem);
  136. return;
  137. }
  138. else if (CompareResult < 0)
  139. break;
  140. }
  141. //
  142. // Attempt to connect to the HKEY_LOCAL_MACHINE of the remote computer.
  143. // If this fails, assume that the computer doesn't exist or doesn't have
  144. // the registry server running.
  145. //
  146. switch (RegConnectRegistry(RemoteName, HKEY_LOCAL_MACHINE,
  147. &hLocalMachineKey)) {
  148. case ERROR_SUCCESS:
  149. break;
  150. case ERROR_ACCESS_DENIED:
  151. ErrorStringID = IDS_CONNECTACCESSDENIED;
  152. goto error_ShowDialog;
  153. default:
  154. ErrorStringID = IDS_CONNECTBADNAME;
  155. goto error_ShowDialog;
  156. }
  157. //
  158. // The connection to HKEY_LOCAL_MACHINE was successful, so add a tree item
  159. // for the remote computer and all of its predefined roots.
  160. //
  161. hKeyTreeWnd = g_RegEditData.hKeyTreeWnd;
  162. ErrorStringID = 0;
  163. TVInsertStruct.hParent = TVI_ROOT;
  164. TVInsertStruct.hInsertAfter = hPrevTreeItem;
  165. TVInsertStruct.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE |
  166. TVIF_PARAM | TVIF_CHILDREN;
  167. TVInsertStruct.item.iImage = IMAGEINDEX(IDI_REMOTE);
  168. TVInsertStruct.item.iSelectedImage = IMAGEINDEX(IDI_REMOTE);
  169. TVInsertStruct.item.cChildren = TRUE;
  170. TVInsertStruct.item.lParam = 0;
  171. TVInsertStruct.item.pszText = lpUnslashedRemoteName;
  172. TVInsertStruct.hParent = TreeView_InsertItem(hKeyTreeWnd, &TVInsertStruct);
  173. TVInsertStruct.item.iImage = IMAGEINDEX(IDI_FOLDER);
  174. TVInsertStruct.item.iSelectedImage = IMAGEINDEX(IDI_FOLDEROPEN);
  175. for (Index = 0; Index < NUMBER_REGISTRY_ROOTS; Index++) {
  176. TVInsertStruct.item.pszText = g_RegistryRoots[Index].lpKeyName;
  177. //There is no way to determine the current user remotely
  178. //We would end up mapping the default user to current user
  179. //so let's just not show this key remotely
  180. if ((Index == INDEX_HKEY_CURRENT_USER) || (Index == INDEX_HKEY_CLASSES_ROOT))
  181. continue;
  182. if (Index == INDEX_HKEY_LOCAL_MACHINE)
  183. TVInsertStruct.item.lParam = (LPARAM) hLocalMachineKey;
  184. else {
  185. #ifdef WINNT
  186. if((Index == INDEX_HKEY_DYN_DATA) || (Index == INDEX_HKEY_CURRENT_CONFIG)) {
  187. continue;
  188. }
  189. #endif
  190. if (RegConnectRegistry(RemoteName, g_RegistryRoots[Index].hKey,
  191. (PHKEY) &TVInsertStruct.item.lParam) != ERROR_SUCCESS) {
  192. ErrorStringID = IDS_CONNECTROOTFAILED;
  193. continue;
  194. }
  195. }
  196. TVInsertStruct.item.cChildren =
  197. (RegEnumKey((HKEY) TVInsertStruct.item.lParam, 0,
  198. CheckChildrenKeyName, sizeof(CheckChildrenKeyName)/sizeof(TCHAR)) ==
  199. ERROR_SUCCESS);
  200. TreeView_InsertItem(hKeyTreeWnd, &TVInsertStruct);
  201. }
  202. TreeView_Expand(hKeyTreeWnd, TVInsertStruct.hParent, TVE_EXPAND);
  203. TreeView_EnsureVisible(hKeyTreeWnd, TVInsertStruct.hParent);
  204. RegEdit_SetWaitCursor(FALSE);
  205. TreeView_SelectItem(hKeyTreeWnd, TVInsertStruct.hParent);
  206. SetFocus(hKeyTreeWnd);
  207. if (ErrorStringID != 0) {
  208. error_ShowDialog:
  209. InternalMessageBox(g_hInstance, hWnd, MAKEINTRESOURCE(ErrorStringID),
  210. MAKEINTRESOURCE(IDS_CONNECTERRORTITLE), MB_ICONERROR | MB_OK,
  211. RemoteName);
  212. }
  213. }
  214. }
  215. /*******************************************************************************
  216. *
  217. * RegConnectDlgProc
  218. *
  219. * DESCRIPTION:
  220. *
  221. * PARAMETERS:
  222. *
  223. *******************************************************************************/
  224. INT_PTR
  225. PASCAL
  226. RegConnectDlgProc(
  227. HWND hWnd,
  228. UINT Message,
  229. WPARAM wParam,
  230. LPARAM lParam
  231. )
  232. {
  233. LPTSTR lpRemoteName;
  234. switch (Message) {
  235. case WM_INITDIALOG:
  236. SetWindowLongPtr(hWnd, DWLP_USER, (LONG) lParam);
  237. SendDlgItemMessage(hWnd, IDC_REMOTENAME, EM_SETLIMITTEXT,
  238. MAX_PATH, 0);
  239. break;
  240. case WM_COMMAND:
  241. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  242. case IDC_REMOTENAME:
  243. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  244. EnableWindow(GetDlgItem(hWnd, IDOK),
  245. SendMessage(GET_WM_COMMAND_HWND(wParam, lParam),
  246. WM_GETTEXTLENGTH, 0, 0) != 0);
  247. break;
  248. case IDC_BROWSE:
  249. RegConnect_OnCommandBrowse(hWnd);
  250. break;
  251. case IDOK:
  252. lpRemoteName = (LPTSTR) GetWindowLongPtr(hWnd, DWLP_USER);
  253. GetDlgItemText(hWnd, IDC_REMOTENAME, lpRemoteName,
  254. MAX_PATH);
  255. // FALL THROUGH
  256. case IDCANCEL:
  257. EndDialog(hWnd, GET_WM_COMMAND_ID(wParam, lParam));
  258. break;
  259. }
  260. break;
  261. case WM_HELP:
  262. WinHelp(((LPHELPINFO) lParam)-> hItemHandle, g_pHelpFileName,
  263. HELP_WM_HELP, (ULONG_PTR) s_RegConnectHelpIDs);
  264. break;
  265. case WM_CONTEXTMENU:
  266. WinHelp((HWND) wParam, g_pHelpFileName, HELP_CONTEXTMENU,
  267. (ULONG_PTR) s_RegConnectHelpIDs);
  268. break;
  269. default:
  270. return FALSE;
  271. }
  272. return TRUE;
  273. }
  274. /*******************************************************************************
  275. *
  276. * RegConnect_OnCommandBrowse
  277. *
  278. * DESCRIPTION:
  279. *
  280. * PARAMETERS:
  281. *
  282. *******************************************************************************/
  283. VOID
  284. PASCAL
  285. RegConnect_OnCommandBrowse(
  286. HWND hWnd
  287. )
  288. {
  289. BROWSEINFO BrowseInfo;
  290. LPITEMIDLIST pidlComputer;
  291. TCHAR RemoteName[MAX_PATH];
  292. BrowseInfo.hwndOwner = hWnd;
  293. BrowseInfo.pidlRoot = (LPITEMIDLIST) MAKEINTRESOURCE(CSIDL_NETWORK);
  294. BrowseInfo.pszDisplayName = RemoteName;
  295. BrowseInfo.lpszTitle = LoadDynamicString(IDS_COMPUTERBROWSETITLE);
  296. BrowseInfo.ulFlags = BIF_BROWSEFORCOMPUTER;
  297. BrowseInfo.lpfn = NULL;
  298. if ((pidlComputer = SHBrowseForFolder(&BrowseInfo)) != NULL) {
  299. SHFree(pidlComputer);
  300. SetDlgItemText(hWnd, IDC_REMOTENAME, RemoteName);
  301. EnableWindow(GetDlgItem(hWnd, IDOK), TRUE);
  302. }
  303. DeleteDynamicString(BrowseInfo.lpszTitle);
  304. }
  305. /*******************************************************************************
  306. *
  307. * RegEdit_OnCommandDisconnect
  308. *
  309. * DESCRIPTION:
  310. *
  311. * PARAMETERS:
  312. *
  313. *******************************************************************************/
  314. VOID
  315. PASCAL
  316. RegEdit_OnCommandDisconnect(
  317. HWND hWnd
  318. )
  319. {
  320. DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_REGDISCONNECT), hWnd,
  321. RegDisconnectDlgProc);
  322. }
  323. /*******************************************************************************
  324. *
  325. * RegDisconnectDlgProc
  326. *
  327. * DESCRIPTION:
  328. *
  329. * PARAMETERS:
  330. *
  331. *******************************************************************************/
  332. INT_PTR
  333. PASCAL
  334. RegDisconnectDlgProc(
  335. HWND hWnd,
  336. UINT Message,
  337. WPARAM wParam,
  338. LPARAM lParam
  339. )
  340. {
  341. switch (Message) {
  342. case WM_INITDIALOG:
  343. return RegDisconnect_OnInitDialog(hWnd);
  344. case WM_COMMAND:
  345. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  346. case IDOK:
  347. RegDisconnect_OnCommandOk(hWnd);
  348. // FALL THROUGH
  349. case IDCANCEL:
  350. EndDialog(hWnd, 0);
  351. break;
  352. }
  353. break;
  354. case WM_HELP:
  355. WinHelp(((LPHELPINFO) lParam)-> hItemHandle, g_pHelpFileName,
  356. HELP_WM_HELP, (ULONG_PTR) s_RegDisconnectHelpIDs);
  357. break;
  358. case WM_CONTEXTMENU:
  359. WinHelp((HWND) wParam, g_pHelpFileName, HELP_CONTEXTMENU,
  360. (ULONG_PTR) s_RegDisconnectHelpIDs);
  361. break;
  362. default:
  363. return FALSE;
  364. }
  365. return TRUE;
  366. }
  367. /*******************************************************************************
  368. *
  369. * RegDisconnect_OnInitDialog
  370. *
  371. * DESCRIPTION:
  372. *
  373. * PARAMETERS:
  374. * hWnd,
  375. * hFocusWnd,
  376. * lParam,
  377. *
  378. *******************************************************************************/
  379. INT_PTR
  380. PASCAL
  381. RegDisconnect_OnInitDialog(
  382. HWND hWnd
  383. )
  384. {
  385. HWND hRemoteListWnd;
  386. RECT ClientRect;
  387. LV_COLUMN LVColumn;
  388. LV_ITEM LVItem;
  389. TCHAR RemoteName[MAX_PATH];
  390. HWND hKeyTreeWnd;
  391. TV_ITEM TVItem;
  392. hRemoteListWnd = GetDlgItem(hWnd, IDC_REMOTELIST);
  393. //
  394. // Initialize the ListView control.
  395. //
  396. ListView_SetImageList(hRemoteListWnd, g_RegEditData.hImageList,
  397. LVSIL_SMALL);
  398. LVColumn.mask = LVCF_FMT | LVCF_WIDTH;
  399. LVColumn.fmt = LVCFMT_LEFT;
  400. GetClientRect(hRemoteListWnd, &ClientRect);
  401. LVColumn.cx = ClientRect.right - GetSystemMetrics(SM_CXVSCROLL) -
  402. 2 * GetSystemMetrics(SM_CXEDGE);
  403. ListView_InsertColumn(hRemoteListWnd, 0, &LVColumn);
  404. //
  405. // Walk through each remote connection listed in the KeyTree and add it
  406. // to our RemoteList.
  407. //
  408. LVItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  409. LVItem.pszText = RemoteName;
  410. LVItem.iItem = 0;
  411. LVItem.iSubItem = 0;
  412. LVItem.iImage = IMAGEINDEX(IDI_REMOTE);
  413. hKeyTreeWnd = g_RegEditData.hKeyTreeWnd;
  414. TVItem.mask = TVIF_TEXT;
  415. TVItem.hItem = TreeView_GetNextSibling(hKeyTreeWnd,
  416. TreeView_GetRoot(hKeyTreeWnd));
  417. TVItem.pszText = RemoteName;
  418. TVItem.cchTextMax = sizeof(RemoteName)/sizeof(TCHAR);
  419. do {
  420. LVItem.lParam = (LPARAM) TVItem.hItem;
  421. TreeView_GetItem(hKeyTreeWnd, &TVItem);
  422. ListView_InsertItem(hRemoteListWnd, &LVItem);
  423. LVItem.iItem++;
  424. } while ((TVItem.hItem = TreeView_GetNextSibling(hKeyTreeWnd,
  425. TVItem.hItem)) != NULL);
  426. ListView_SetItemState(hRemoteListWnd, 0, LVIS_FOCUSED, LVIS_FOCUSED);
  427. return TRUE;
  428. }
  429. /*******************************************************************************
  430. *
  431. * RegDisconnect_OnCommandOk
  432. *
  433. * DESCRIPTION:
  434. *
  435. * PARAMETERS:
  436. * hWnd,
  437. * hFocusWnd,
  438. * lParam,
  439. *
  440. *******************************************************************************/
  441. VOID
  442. PASCAL
  443. RegDisconnect_OnCommandOk(
  444. HWND hWnd
  445. )
  446. {
  447. LV_ITEM LVItem;
  448. HWND hRemoteListWnd;
  449. //
  450. // Walk through each selected item in the ListView and disconnect the
  451. // computer.
  452. //
  453. LVItem.mask = LVIF_PARAM;
  454. LVItem.iItem = -1;
  455. LVItem.iSubItem = 0;
  456. hRemoteListWnd = GetDlgItem(hWnd, IDC_REMOTELIST);
  457. while ((LVItem.iItem = ListView_GetNextItem(hRemoteListWnd, LVItem.iItem,
  458. LVNI_SELECTED)) != -1) {
  459. ListView_GetItem(hRemoteListWnd, &LVItem);
  460. RegEdit_OnKeyTreeDisconnect(hWnd, (HTREEITEM) LVItem.lParam);
  461. }
  462. }