Leaked source code of windows server 2003
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.

495 lines
12 KiB

  1. //
  2. // Sharing.cpp
  3. //
  4. // Code to install, enable, disable, and bind File and Printer sharing
  5. // for Microsoft networks (VSERVER).
  6. //
  7. // History:
  8. //
  9. // 2/02/1999 KenSh Created for JetNet
  10. // 9/29/1999 KenSh Repurposed for Home Networking Wizard
  11. //
  12. #include "stdafx.h"
  13. #include "NetConn.h"
  14. #include "nconnwrap.h"
  15. #include "Registry.h"
  16. #include "TheApp.h"
  17. #include "ParseInf.h"
  18. #include "HookUI.h"
  19. // Local functions
  20. //
  21. BOOL WINAPI FindValidSharingEnumKey(LPSTR pszBuf, int cchBuf);
  22. // Check the registry to see if file/printer sharing is installed.
  23. BOOL WINAPI IsSharingInstalled(BOOL bExhaustive)
  24. {
  25. if (!FindValidSharingEnumKey(NULL, 0))
  26. return FALSE;
  27. if (bExhaustive)
  28. {
  29. if (!CheckInfSectionInstallation("netservr.inf", "VSERVER.Install"))
  30. return FALSE;
  31. }
  32. return TRUE;
  33. }
  34. BOOL WINAPI FindValidSharingEnumKey(LPSTR pszBuf, int cchBuf)
  35. {
  36. return FindValidNetEnumKey(SZ_CLASS_SERVICE, SZ_SERVICE_VSERVER, pszBuf, cchBuf);
  37. }
  38. // Enables file/printer sharing on local NICs, disables it on Internet connections
  39. HRESULT WINAPI EnableProtocolSharingAppropriately(LPCTSTR pszProtocolDeviceID)
  40. {
  41. HRESULT hr = EnableDisableProtocolSharing(pszProtocolDeviceID, TRUE, FALSE);
  42. HRESULT hr2 = EnableDisableProtocolSharing(pszProtocolDeviceID, FALSE, TRUE);
  43. if (hr2 != NETCONN_SUCCESS)
  44. hr = hr2;
  45. return hr;
  46. }
  47. // Enables or disables file/printer sharing for either Dial-Up or non-Dial-Up connections,
  48. // but not both.
  49. HRESULT WINAPI EnableDisableProtocolSharing(LPCTSTR pszProtocolDeviceID, BOOL bEnable, BOOL bDialUp)
  50. {
  51. HRESULT hr = NETCONN_SUCCESS;
  52. NETADAPTER* prgAdapters;
  53. int cAdapters = EnumNetAdapters(&prgAdapters);
  54. for (int iAdapter = 0; iAdapter < cAdapters; iAdapter++)
  55. {
  56. NETADAPTER* pAdapter = &prgAdapters[iAdapter];
  57. BOOL bExternalNic = IsAdapterBroadband(pAdapter);
  58. if (bDialUp)
  59. {
  60. if (!bExternalNic && pAdapter->bNetType != NETTYPE_DIALUP)
  61. continue;
  62. }
  63. else
  64. {
  65. if (bExternalNic || pAdapter->bNetType == NETTYPE_DIALUP)
  66. continue;
  67. }
  68. LPTSTR* prgBindings;
  69. int cBindings = EnumMatchingNetBindings(pAdapter->szEnumKey, pszProtocolDeviceID, &prgBindings);
  70. for (int iBinding = 0; iBinding < cBindings; iBinding++)
  71. {
  72. HRESULT hr2;
  73. if (bEnable)
  74. {
  75. hr2 = EnableSharingOnNetBinding(prgBindings[iBinding]);
  76. }
  77. else
  78. {
  79. hr2 = DisableSharingOnNetBinding(prgBindings[iBinding]);
  80. }
  81. if (hr2 != NETCONN_SUCCESS)
  82. hr = hr2;
  83. }
  84. NetConnFree(prgBindings);
  85. }
  86. NetConnFree(prgAdapters);
  87. return hr;
  88. }
  89. // pszNetBinding is of the form "MSTCP\0000"
  90. HRESULT WINAPI DisableSharingOnNetBinding(LPCSTR pszNetBinding)
  91. {
  92. HRESULT hr = NETCONN_SUCCESS;
  93. CRegistry regBindings;
  94. TCHAR szRegKey[MAX_PATH];
  95. wsprintf(szRegKey, "Enum\\Network\\%s\\Bindings", pszNetBinding);
  96. if (regBindings.OpenKey(HKEY_LOCAL_MACHINE, szRegKey, KEY_ALL_ACCESS))
  97. {
  98. for (DWORD iBinding = 0; ; )
  99. {
  100. CHAR szBinding[64];
  101. DWORD cchBinding = _countof(szBinding);
  102. if (ERROR_SUCCESS != RegEnumValue(regBindings.m_hKey, iBinding, szBinding, &cchBinding, NULL, NULL, NULL, NULL))
  103. break;
  104. CHAR chSave = szBinding[8];
  105. szBinding[8] = '\0';
  106. BOOL bSharing = !lstrcmpi(szBinding, "VSERVER\\");
  107. szBinding[8] = chSave;
  108. if (bSharing)
  109. {
  110. RemoveBindingFromParent(regBindings.m_hKey, szBinding);
  111. hr = NETCONN_NEED_RESTART;
  112. // Restart the enumeration, since we've changed the key
  113. iBinding = 0;
  114. continue;
  115. }
  116. else
  117. {
  118. // Note: Sharing may still be bound to the client (VREDIR), but we
  119. // don't remove that binding because Network Control Panel doesn't.
  120. // (Verified on Win98 gold.)
  121. // HRESULT hr2 = DisableSharingOnNetBinding(szBinding);
  122. // if (hr2 != NETCONN_SUCCESS)
  123. // hr = hr2;
  124. }
  125. iBinding += 1; // advance to next binding
  126. }
  127. }
  128. return hr;
  129. }
  130. // pszNetBinding is of the form "MSTCP\0000"
  131. HRESULT WINAPI EnableSharingOnNetBinding(LPCSTR pszNetBinding)
  132. {
  133. HRESULT hr = NETCONN_SUCCESS;
  134. BOOL bFoundSharing = FALSE;
  135. CRegistry regBindings;
  136. TCHAR szRegKey[MAX_PATH];
  137. wsprintf(szRegKey, "Enum\\Network\\%s\\Bindings", pszNetBinding);
  138. if (!regBindings.CreateKey(HKEY_LOCAL_MACHINE, szRegKey, KEY_ALL_ACCESS))
  139. {
  140. ASSERT(FALSE);
  141. return NETCONN_UNKNOWN_ERROR;
  142. }
  143. DWORD iBinding = 0;
  144. for (;;)
  145. {
  146. CHAR szBinding[64];
  147. DWORD cchBinding = _countof(szBinding);
  148. if (ERROR_SUCCESS != RegEnumValue(regBindings.m_hKey, iBinding, szBinding, &cchBinding, NULL, NULL, NULL, NULL))
  149. break;
  150. CHAR chSave = szBinding[8];
  151. szBinding[8] = '\0';
  152. BOOL bSharing = !lstrcmpi(szBinding, "VSERVER\\");
  153. szBinding[8] = chSave;
  154. chSave = szBinding[7];
  155. szBinding[7] = '\0';
  156. BOOL bClient = !lstrcmpi(szBinding, "VREDIR\\");
  157. szBinding[7] = chSave;
  158. if (bSharing)
  159. {
  160. if (!IsValidNetEnumKey(SZ_CLASS_SERVICE, SZ_SERVICE_VSERVER, szBinding + _lengthof("VSERVER\\")))
  161. {
  162. // Found a dead link to nonexistent Enum item; delete it and restart search
  163. regBindings.DeleteValue(szBinding);
  164. iBinding = 0;
  165. continue;
  166. }
  167. else
  168. {
  169. bFoundSharing = TRUE;
  170. }
  171. }
  172. else if (bClient)
  173. {
  174. HRESULT hr2 = EnableSharingOnNetBinding(szBinding);
  175. if (hr2 != NETCONN_SUCCESS)
  176. hr = hr2;
  177. }
  178. iBinding++;
  179. }
  180. if (!bFoundSharing)
  181. {
  182. CHAR szBinding[64];
  183. HRESULT hr2 = CreateNewFilePrintSharing(szBinding, _countof(szBinding));
  184. if (hr2 != NETCONN_SUCCESS)
  185. hr = hr2;
  186. if (SUCCEEDED(hr2))
  187. {
  188. regBindings.SetStringValue(szBinding, "");
  189. hr = NETCONN_NEED_RESTART;
  190. }
  191. }
  192. return hr;
  193. }
  194. HRESULT WINAPI EnableSharingAppropriately()
  195. {
  196. HRESULT hr = NETCONN_SUCCESS;
  197. NETADAPTER* prgAdapters;
  198. int cAdapters = EnumNetAdapters(&prgAdapters);
  199. for (int iAdapter = 0; iAdapter < cAdapters; iAdapter++)
  200. {
  201. NETADAPTER* pAdapter = &prgAdapters[iAdapter];
  202. // Walk through each protocol bound to the adapter
  203. LPTSTR* prgBindings;
  204. int cBindings = EnumNetBindings(pAdapter->szEnumKey, &prgBindings);
  205. for (int iBinding = 0; iBinding < cBindings; iBinding++)
  206. {
  207. LPTSTR pszBinding = prgBindings[iBinding];
  208. HRESULT hr2 = NETCONN_SUCCESS;
  209. BOOL bExternalNic = IsAdapterBroadband(pAdapter);
  210. // Disable file/printer sharing on:
  211. // * Dial-Up Adapters
  212. // * PPTP connections
  213. // * NIC used by ICS to connect to the Internet
  214. if (pAdapter->bNetType == NETTYPE_DIALUP ||
  215. pAdapter->bNetType == NETTYPE_PPTP ||
  216. bExternalNic)
  217. {
  218. hr2 = DisableSharingOnNetBinding(pszBinding);
  219. }
  220. // Enable file/printer sharing on:
  221. // * Ethernet adapters
  222. // * IRDA adapters
  223. else if (pAdapter->bNetType == NETTYPE_LAN ||
  224. pAdapter->bNetType == NETTYPE_IRDA)
  225. {
  226. hr2 = EnableSharingOnNetBinding(pszBinding);
  227. }
  228. if (hr2 != NETCONN_SUCCESS)
  229. hr = hr2;
  230. }
  231. NetConnFree(prgBindings);
  232. }
  233. NetConnFree(prgAdapters);
  234. return hr;
  235. }
  236. // InstallSharing (public)
  237. //
  238. // Installs VSERVER, a.k.a. File and Printer sharing for Microsoft networks.
  239. // The standard progress UI is (mostly) suppressed, and instead the given
  240. // callback function is called so a custom progress UI can be implemented.
  241. //
  242. // Returns a NETCONN_xxx result, defined in NetConn.h
  243. //
  244. // History:
  245. //
  246. // 4/09/1999 KenSh Created
  247. // 4/22/1999 KenSh Remove file-sharing on Dial-Up connections
  248. //
  249. HRESULT WINAPI InstallSharing(HWND hwndParent, PROGRESS_CALLBACK pfnProgress, LPVOID pvProgressParam)
  250. {
  251. HRESULT hr = NETCONN_SUCCESS;
  252. BOOL bInstall = FALSE;
  253. // Remove any broken bindings
  254. RemoveBrokenNetItems(SZ_CLASS_SERVICE, SZ_SERVICE_VSERVER);
  255. if (IsSharingInstalled(FALSE))
  256. {
  257. // Sharing is set up in registry, but check for missing files
  258. if (!CheckInfSectionInstallation("netservr.inf", "VSERVER.Install"))
  259. {
  260. if (InstallInfSection("netservr.inf", "VSERVER.Install", TRUE))
  261. {
  262. hr = NETCONN_NEED_RESTART;
  263. }
  264. }
  265. }
  266. else
  267. {
  268. BeginSuppressNetdiUI(hwndParent, pfnProgress, pvProgressParam);
  269. DWORD dwResult = CallClassInstaller16(hwndParent, SZ_CLASS_SERVICE, SZ_SERVICE_VSERVER);
  270. EndSuppressNetdiUI();
  271. hr = HresultFromCCI(dwResult);
  272. if (g_bUserAbort)
  273. {
  274. hr = NETCONN_USER_ABORT;
  275. }
  276. else if (SUCCEEDED(hr))
  277. {
  278. hr = NETCONN_NEED_RESTART;
  279. }
  280. // Total hack to work around JetNet bug 1193
  281. // DoDummyDialog(hwndParent);
  282. }
  283. // if (SUCCEEDED(hr))
  284. // {
  285. // HRESULT hr2 = EnableSharingAppropriately();
  286. // if (hr2 != NETCONN_SUCCESS)
  287. // hr = hr2;
  288. // }
  289. HRESULT hr2 = EnableFileSharing();
  290. if (hr2 != NETCONN_SUCCESS)
  291. hr = hr2;
  292. hr2 = EnablePrinterSharing();
  293. if (hr2 != NETCONN_SUCCESS)
  294. hr = hr2;
  295. return hr;
  296. }
  297. // pConflict may be NULL if you don't need the details
  298. BOOL WINAPI FindConflictingService(LPCSTR pszWantService, NETSERVICE* pConflict)
  299. {
  300. CRegistry reg;
  301. if (reg.OpenKey(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Class\\NetService", KEY_READ))
  302. {
  303. TCHAR szSubKey[80];
  304. for (DWORD iService = 0; ; iService++)
  305. {
  306. DWORD cchSubKey = _countof(szSubKey);
  307. if (ERROR_SUCCESS != RegEnumKeyEx(reg.m_hKey, iService, szSubKey, &cchSubKey, NULL, NULL, NULL, NULL))
  308. break;
  309. CRegistry regSubKey;
  310. if (regSubKey.OpenKey(reg.m_hKey, szSubKey, KEY_READ))
  311. {
  312. CRegistry regNdi;
  313. if (regNdi.OpenKey(regSubKey.m_hKey, "Ndi", KEY_READ))
  314. {
  315. CRegistry regCompat;
  316. if (regCompat.OpenKey(regNdi.m_hKey, "Compatibility", KEY_READ))
  317. {
  318. CString strExclude;
  319. if (regCompat.QueryStringValue("ExcludeAll", strExclude))
  320. {
  321. if (CheckMatchingInterface(pszWantService, strExclude))
  322. {
  323. if (pConflict != NULL)
  324. {
  325. regNdi.QueryStringValue("DeviceID", pConflict->szDeviceID, _countof(pConflict->szDeviceID));
  326. regSubKey.QueryStringValue("DriverDesc", pConflict->szDisplayName, _countof(pConflict->szDisplayName));
  327. wsprintf(pConflict->szClassKey, "NetService\\%s", szSubKey);
  328. }
  329. return TRUE;
  330. }
  331. }
  332. }
  333. }
  334. }
  335. }
  336. }
  337. return FALSE;
  338. }
  339. // pszBuf is filled with the new binding's enum key, e.g. "VSERVER\0001"
  340. HRESULT CreateNewFilePrintSharing(LPSTR pszBuf, int cchBuf)
  341. {
  342. HRESULT hr;
  343. if (FAILED(hr = FindAndCloneNetEnumKey(SZ_CLASS_SERVICE, SZ_SERVICE_VSERVER, pszBuf, cchBuf)))
  344. {
  345. ASSERT(FALSE);
  346. return hr;
  347. }
  348. // Now pszBuf contains a string of the form "VSERVER\0001"
  349. CHAR szBindings[60];
  350. CRegistry regBindings;
  351. lstrcpy(szBindings, pszBuf); // "VSERVER\0001"
  352. lstrcat(szBindings, "\\Bindings"); // "VSERVER\0001\Bindings"
  353. if (FAILED(hr = OpenNetEnumKey(regBindings, szBindings, KEY_ALL_ACCESS)))
  354. {
  355. ASSERT(FALSE);
  356. return hr;
  357. }
  358. // Delete existing bindings (shouldn't be any, right?)
  359. regBindings.DeleteAllValues();
  360. return NETCONN_SUCCESS;
  361. }
  362. BOOL IsSharingEnabledHelper(LPCTSTR pszThis)
  363. {
  364. CRegistry reg;
  365. if (reg.OpenKey(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\VNETSUP", KEY_READ))
  366. {
  367. // If the value is missing or says "Yes", then sharing is enabled
  368. char szBuf[10];
  369. return (!reg.QueryStringValue(pszThis, szBuf, _countof(szBuf)) || 0 == lstrcmpi(szBuf, "Yes"));
  370. }
  371. return FALSE;
  372. }
  373. BOOL WINAPI IsFileSharingEnabled()
  374. {
  375. return IsSharingEnabledHelper("FileSharing");
  376. }
  377. BOOL WINAPI IsPrinterSharingEnabled()
  378. {
  379. return IsSharingEnabledHelper("PrintSharing");
  380. }
  381. HRESULT WINAPI EnableSharingHelper(LPCTSTR pszThis, LPCTSTR pszOther)
  382. {
  383. HRESULT hr = NETCONN_SUCCESS;
  384. CRegistry reg;
  385. if (reg.OpenKey(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\VNETSUP"))
  386. {
  387. // If Printer sharing is "No", then set File sharing to "Yes".
  388. // If Printer sharing is missing or is "Yes", delete both values (enables both).
  389. char szBuf[10];
  390. if (reg.QueryStringValue(pszOther, szBuf, _countof(szBuf)) &&
  391. 0 != lstrcmpi(szBuf, "Yes"))
  392. {
  393. // Set file sharing value to "Yes" (if it's not already set)
  394. if (!reg.QueryStringValue(pszThis, szBuf, _countof(szBuf)) ||
  395. 0 != lstrcmpi(szBuf, "Yes"))
  396. {
  397. reg.SetStringValue(pszThis, "Yes");
  398. hr = NETCONN_NEED_RESTART;
  399. }
  400. }
  401. else
  402. {
  403. // Delete file-sharing and printer-sharing entries (enables both).
  404. if (reg.QueryStringValue(pszThis, szBuf, _countof(szBuf)) &&
  405. 0 != lstrcmpi(szBuf, "Yes"))
  406. {
  407. reg.DeleteValue(pszThis);
  408. reg.DeleteValue(pszOther);
  409. hr = NETCONN_NEED_RESTART;
  410. }
  411. }
  412. }
  413. return hr;
  414. }
  415. HRESULT WINAPI EnableFileSharing()
  416. {
  417. return EnableSharingHelper("FileSharing", "PrintSharing");
  418. }
  419. HRESULT WINAPI EnablePrinterSharing()
  420. {
  421. return EnableSharingHelper("PrintSharing", "FileSharing");
  422. }