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.

1355 lines
40 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N W C L I I N F . C P P
  7. //
  8. // Contents: NetWare client configuration notify object.
  9. // Functionality from old INF
  10. //
  11. // Notes:
  12. //
  13. // Author: jeffspr 24 Jun 1997
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "lmerr.h"
  19. #include "lmcons.h"
  20. #include "lmserver.h"
  21. #include "ncreg.h"
  22. #include "nwclidef.h"
  23. #include "nwcliobj.h"
  24. extern const WCHAR c_szRegKeyCtlLsa[];
  25. //---[ Constants ]------------------------------------------------------------
  26. const WCHAR c_szConfigDLLName[] = NW_CONFIG_DLL_NAME;
  27. const WCHAR c_szAuthPackageName[] = NW_AUTH_PACKAGE_NAME;
  28. const WCHAR c_szParamOptionKeyPath[] = NW_NWC_PARAM_OPTION_KEY;
  29. const WCHAR c_szParamLogonKeyPath[] = NW_NWC_PARAM_LOGON_KEY;
  30. const WCHAR c_szNwDocGWHelpName[] = L"nwdocgw.hlp";
  31. const WCHAR c_szNwDocGWCNTName[] = L"nwdocgw.cnt";
  32. const WCHAR c_szNwDocHelpName[] = L"nwdoc.hlp";
  33. const WCHAR c_szNwDocCNTName[] = L"nwdoc.cnt";
  34. const DWORD c_dwOptionKeyPermissions = KEY_SET_VALUE | KEY_CREATE_SUB_KEY;
  35. //---[ Prototypes ]-----------------------------------------------------------
  36. // See the function headers for descriptions
  37. //
  38. HRESULT HrAppendNetwareToAuthPackages();
  39. HRESULT HrCreateParametersSubkeys();
  40. HRESULT HrMungeAutoexecNT();
  41. BOOL FMoveSzToEndOfFile( PSTR pszAutoexecName, PSTR pszMatch);
  42. HRESULT HrAddNetWareToWOWKnownList();
  43. HRESULT HrUpdateLanmanSharedDrivesValue();
  44. HRESULT HrRemoveNetwareFromAuthPackages();
  45. HRESULT HrRemoveNetWareFromWOWKnownList();
  46. HRESULT HrDeleteParametersSubkeys();
  47. HRESULT HrRenameNWDocFiles();
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Member: CNWClient::HrLoadConfigDLL
  51. //
  52. // Purpose: Load nwcfg.dll, so we can call some of the functions within.
  53. // Also, do the GetProcAddress calls for all of the functions
  54. // that we might need.
  55. //
  56. // Arguments:
  57. // (none)
  58. //
  59. // Returns: S_OK or valid Win32 error code.
  60. //
  61. // Author: jeffspr 24 Jun 1997
  62. //
  63. // Notes:
  64. //
  65. HRESULT CNWClient::HrLoadConfigDLL()
  66. {
  67. HRESULT hr = S_OK;
  68. AssertSz(!m_hlibConfig, "This should not be getting initialized twice");
  69. TraceTag(ttidNWClientCfgFn, ">> CNWClient::HrLoadConfigDLL");
  70. m_hlibConfig = LoadLibrary(c_szConfigDLLName);
  71. if (!m_hlibConfig)
  72. {
  73. DWORD dwLastError = GetLastError();
  74. TraceLastWin32Error("HrLoadConfigDLL() failed");
  75. // More specific info
  76. //
  77. TraceTag(ttidNWClientCfg,
  78. "HrLoadConfigDLL() - LoadLibrary failed on %S, Err: %d",
  79. c_szConfigDLLName, dwLastError);
  80. hr = E_FAIL;
  81. goto Exit;
  82. }
  83. // $$REVIEW: We probably won't need all of these, so make sure that we've
  84. // cut out the ones that we're no longer using (or have never used).
  85. //
  86. m_pfnAppendSzToFile = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "AppendSzToFile");
  87. m_pfnRemoveSzFromFile = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "RemoveSzFromFile");
  88. m_pfnGetKernelVersion = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "GetKernelVersion");
  89. m_pfnSetEverybodyPermission = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "SetEverybodyPermission");
  90. m_pfnlodctr = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "lodctr");
  91. m_pfnunlodctr = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "unlodctr");
  92. m_pfnDeleteGatewayPassword = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "DeleteGatewayPassword");
  93. m_pfnSetFileSysChangeValue = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "SetFileSysChangeValue");
  94. m_pfnCleanupRegistryForNWCS = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "CleanupRegistryForNWCS");
  95. m_pfnSetupRegistryForNWCS = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "SetupRegistryForNWCS");
  96. if (!m_pfnAppendSzToFile || !m_pfnRemoveSzFromFile ||
  97. !m_pfnGetKernelVersion || !m_pfnSetEverybodyPermission ||
  98. !m_pfnlodctr || !m_pfnunlodctr ||
  99. !m_pfnDeleteGatewayPassword || !m_pfnSetFileSysChangeValue ||
  100. !m_pfnCleanupRegistryForNWCS || !m_pfnSetupRegistryForNWCS)
  101. {
  102. TraceLastWin32Error("HrLoadConfigDLL() - GetProcAddress failed");
  103. hr = E_FAIL;
  104. goto Exit;
  105. }
  106. Exit:
  107. TraceTag(ttidNWClientCfgFn, "<< CNWClient::HrLoadConfigDLL");
  108. TraceError("HrLoadConfigDLL", hr);
  109. return hr;
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CNWClient::FreeConfigDLL
  114. //
  115. // Purpose: Free nwcfg.dll, and NULL out the function pointers.
  116. //
  117. // Arguments:
  118. // (none)
  119. //
  120. // Returns: No return (VOID)
  121. //
  122. // Author: jeffspr 24 Jun 1997
  123. //
  124. // Notes:
  125. //
  126. VOID CNWClient::FreeConfigDLL()
  127. {
  128. TraceTag(ttidNWClientCfgFn, ">> CNWClient::FreeConfigDLL()");
  129. // If we successfully loaded the library, free it.
  130. if (m_hlibConfig)
  131. {
  132. // Free up the library resources.
  133. FreeLibrary(m_hlibConfig);
  134. m_hlibConfig = NULL;
  135. m_pfnAppendSzToFile = NULL;
  136. m_pfnRemoveSzFromFile = NULL;
  137. m_pfnGetKernelVersion = NULL;
  138. m_pfnSetEverybodyPermission = NULL;
  139. m_pfnlodctr = NULL;
  140. m_pfnunlodctr = NULL;
  141. m_pfnDeleteGatewayPassword = NULL;
  142. m_pfnSetFileSysChangeValue = NULL;
  143. m_pfnCleanupRegistryForNWCS = NULL;
  144. m_pfnSetupRegistryForNWCS = NULL;
  145. }
  146. TraceTag(ttidNWClientCfgFn, "<< CNWClient::FreeConfigDLL()");
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Member: CNWClient::HrInstallCodeFromOldINF
  151. //
  152. // Purpose: This contains all of the logic from the old oemnsvnw.inf, or
  153. // at least calls to helper functions that perform all of the
  154. // logic. This runs pretty much straight through the old
  155. // installadapter code.
  156. //
  157. // Arguments:
  158. // (none)
  159. //
  160. // Returns: S_OK or valid Win32 error code.
  161. //
  162. // Author: jeffspr 24 Jun 1997
  163. //
  164. // Notes:
  165. //
  166. HRESULT CNWClient::HrInstallCodeFromOldINF()
  167. {
  168. HRESULT hr = S_OK;
  169. BOOL fResult = FALSE;
  170. // Get result from NWCFG functions. We won't use it though.
  171. PWSTR pszDummy = NULL;
  172. TraceTag(ttidNWClientCfgFn, ">> CNWClient::HrInstallCodeFromOldINF()");
  173. hr = HrLoadConfigDLL();
  174. if (FAILED(hr))
  175. {
  176. // Error traced in the call itself.
  177. goto Exit;
  178. }
  179. // Call the NWCFG function that does (their comment):
  180. // "set the FileSysChangeValue to please NETWARE.DRV.
  181. // also set win.ini parameter so wfwnet.drv knows we are there."
  182. fResult = m_pfnSetupRegistryForNWCS(0, NULL, &pszDummy);
  183. if (!fResult)
  184. {
  185. TraceTag(ttidNWClientCfg, "HrInstallCodeFromOldINF() - m_pfnSetupRegistryForNWCS failed");
  186. goto Exit;
  187. }
  188. // Append our name to the Lsa Authentication packages reg value.
  189. hr = HrAppendNetwareToAuthPackages();
  190. if (FAILED(hr))
  191. {
  192. // Error traced within the function itself.
  193. //
  194. goto Exit;
  195. }
  196. // Create the required subkeys under the services\NWCWorkstation\parameters
  197. // key
  198. //
  199. hr = HrCreateParametersSubkeys();
  200. if (FAILED(hr))
  201. {
  202. // Error traced within the function itself.
  203. //
  204. goto Exit;
  205. }
  206. // Munge the autoexec.nt (or autoexec.tmp) file. Pass the function pointers
  207. // to the munge that will allow it to manipulate the autoexec.nt
  208. hr = HrMungeAutoexecNT();
  209. if (FAILED(hr))
  210. {
  211. // Error traced within the function itself.
  212. //
  213. goto Exit;
  214. }
  215. hr = HrAddNetWareToWOWKnownList();
  216. if (FAILED(hr))
  217. {
  218. // Error traced within the function itself.
  219. //
  220. goto Exit;
  221. }
  222. // If this is the gateway that we're installing, do the work that will
  223. // allow us to share a redirected resource.
  224. //
  225. if (PF_SERVER == m_pf)
  226. {
  227. hr = HrUpdateLanmanSharedDrivesValue();
  228. if (FAILED(hr))
  229. {
  230. // Error traced within the function itself.
  231. //
  232. goto Exit;
  233. }
  234. // On the server build, rename nwdocgw.* to nwdoc.*
  235. hr = HrRenameNWDocFiles();
  236. if (FAILED(hr))
  237. {
  238. goto Exit;
  239. }
  240. }
  241. Exit:
  242. // This will work even if the handle is NULL.
  243. FreeConfigDLL();
  244. TraceTag(ttidNWClientCfgFn, "<< CNWClient::HrInstallCodeFromOldINF()");
  245. TraceError("CNWClient::HrInstallCodeFromOldINF()", hr);
  246. return hr;
  247. }
  248. //+---------------------------------------------------------------------------
  249. //
  250. // Member: CNWClient::HrRemoveCodeFromOldINF
  251. //
  252. // Purpose: This contains all of the remove logic from the old
  253. // oemnsvnw.inf, or at least calls to helper functions that
  254. // perform all of the logic. This runs pretty much straight
  255. // through the old removeadapter code.
  256. //
  257. // Arguments:
  258. // (none)
  259. //
  260. // Returns: S_OK or valid Win32 error code.
  261. //
  262. // Author: jeffspr 24 Jun 1997
  263. //
  264. // Notes:
  265. //
  266. HRESULT CNWClient::HrRemoveCodeFromOldINF()
  267. {
  268. HRESULT hr = S_OK;
  269. BOOL fResult = FALSE;
  270. // Get result from NWCFG functions. We won't use it though.
  271. PWSTR pszDummy = NULL;
  272. TraceTag(ttidNWClientCfgFn, ">> CNWClient::HrRemoveCodeFromOldINF()");
  273. hr = HrLoadConfigDLL();
  274. if (FAILED(hr))
  275. {
  276. // Error traced in the call itself.
  277. goto Exit;
  278. }
  279. // Call the NWCFG function that does (their comment):
  280. // "set the FileSysChangeValue to please NETWARE.DRV.
  281. // also set win.ini parameter so wfwnet.drv knows we are there."
  282. fResult = m_pfnCleanupRegistryForNWCS(0, NULL, &pszDummy);
  283. if (!fResult)
  284. {
  285. TraceTag(ttidNWClientCfg, "HrRemoveCodeFromOldINF() - m_pfnCleanupRegistryForNWCS failed");
  286. goto Exit;
  287. }
  288. // Remove our name from the Lsa Authentication packages reg value.
  289. hr = HrRemoveNetwareFromAuthPackages();
  290. if (FAILED(hr))
  291. {
  292. // Error traced within the function itself.
  293. //
  294. goto Exit;
  295. }
  296. // Delete the NWC subkeys under the services\NWCWorkstation\parameters
  297. // key
  298. //
  299. hr = HrDeleteParametersSubkeys();
  300. if (FAILED(hr))
  301. {
  302. // Error traced within the function itself.
  303. //
  304. goto Exit;
  305. }
  306. hr = HrRemoveNetWareFromWOWKnownList();
  307. if (FAILED(hr))
  308. {
  309. // Error traced within the function itself.
  310. //
  311. goto Exit;
  312. }
  313. Exit:
  314. // This will work even if the handle is NULL.
  315. FreeConfigDLL();
  316. TraceTag(ttidNWClientCfgFn, "<< CNWClient::HrRemoveCodeFromOldINF()");
  317. TraceError("CNWClient::HrRemoveCodeFromOldINF()", hr);
  318. return hr;
  319. }
  320. //+---------------------------------------------------------------------------
  321. //
  322. // Function: HrAppendNetwareToAuthPackages
  323. //
  324. // Purpose: Helper function for HrCodeFromOldINF() - Appends the netware
  325. // authentication provider name to the end of the LSA
  326. // authentication packages value.
  327. //
  328. // Arguments:
  329. // (none)
  330. //
  331. // Returns: S_OK or valid Win32 Error code.
  332. //
  333. // Author: jeffspr 24 Jun 1997
  334. //
  335. // Notes:
  336. //
  337. HRESULT HrAppendNetwareToAuthPackages()
  338. {
  339. HRESULT hr = S_OK;
  340. TraceTag(ttidNWClientCfgFn, ">> HrAppendNetwareToAuthPackages");
  341. // Call the cool new AddString... function
  342. //
  343. hr = HrRegAddStringToMultiSz(
  344. (PWSTR) c_szAuthPackageName,
  345. HKEY_LOCAL_MACHINE,
  346. c_szRegKeyCtlLsa,
  347. L"Authentication Packages",
  348. STRING_FLAG_ENSURE_AT_END,
  349. 0);
  350. if (FAILED(hr))
  351. {
  352. TraceTag(ttidNWClientCfg, "HrAppendNetwareToAuthPackages() - Failed to "
  353. "Add string to multi-sz 'Authentication Packages' in key: %S",
  354. c_szRegKeyCtlLsa);
  355. goto Exit;
  356. }
  357. Exit:
  358. TraceTag(ttidNWClientCfgFn, "<< HrAppendNetwareToAuthPackages");
  359. TraceError("HrAppendNetwareToAuthPackages", hr);
  360. return hr;
  361. }
  362. //+---------------------------------------------------------------------------
  363. //
  364. // Function: HrRemoveNetwareFromAuthPackages
  365. //
  366. // Purpose: Helper function for HrCodeFromOldINF() - Appends the netware
  367. // authentication provider name to the end of the LSA
  368. // authentication packages value.
  369. //
  370. // Arguments:
  371. // (none)
  372. //
  373. // Returns: S_OK or valid Win32 Error code.
  374. //
  375. // Author: jeffspr 24 Jun 1997
  376. //
  377. // Notes:
  378. //
  379. HRESULT HrRemoveNetwareFromAuthPackages()
  380. {
  381. HRESULT hr = S_OK;
  382. TraceTag(ttidNWClientCfgFn, ">> HrRemoveNetwareFromAuthPackages");
  383. // Call the cool new AddString... function
  384. //
  385. hr = HrRegRemoveStringFromMultiSz(
  386. (PWSTR) c_szAuthPackageName,
  387. HKEY_LOCAL_MACHINE,
  388. c_szRegKeyCtlLsa,
  389. L"Authentication Packages",
  390. STRING_FLAG_REMOVE_ALL);
  391. if (FAILED(hr))
  392. {
  393. TraceTag(ttidNWClientCfg, "HrRemoveNetwareFromAuthPackages() - Failed to "
  394. "Remove string to multi-sz 'Authentication Packages' in key: %S",
  395. c_szRegKeyCtlLsa);
  396. goto Exit;
  397. }
  398. Exit:
  399. TraceTag(ttidNWClientCfgFn, "<< HrRemoveNetwareFromAuthPackages");
  400. TraceError("HrRemoveNetwareFromAuthPackages", hr);
  401. return hr;
  402. }
  403. //+---------------------------------------------------------------------------
  404. //
  405. // Function: HrNwLibSetEverybodyPermission
  406. //
  407. // Purpose: Set the registry key to everybody "Set Value" (or whatever
  408. // the caller want.)
  409. //
  410. // Arguments:
  411. // hKey [] The handle of the registry key to set security on
  412. // dwPermission [] The permission to add to "everybody"
  413. //
  414. // Returns:
  415. //
  416. // Author: jeffspr 18 Jun 1997
  417. //
  418. // Notes:
  419. //
  420. HRESULT HrNwLibSetEverybodyPermission( IN HKEY hKey,
  421. IN DWORD dwPermission)
  422. {
  423. LONG err; // error code
  424. PSECURITY_DESCRIPTOR psd = NULL; // related SD
  425. PSID pSid = NULL; // original SID
  426. PACL pDacl = NULL; // Absolute DACL
  427. PACL pSacl = NULL; // Absolute SACL
  428. PSID pOSid = NULL; // Absolute Owner SID
  429. PSID pPSid = NULL; // Absolute Primary SID
  430. do { // Not a loop, just for breaking out of error
  431. //
  432. // Initialize all the variables...
  433. //
  434. // world sid authority
  435. SID_IDENTIFIER_AUTHORITY SidAuth= SECURITY_WORLD_SID_AUTHORITY;
  436. DWORD cbSize=0; // Security key size
  437. PACL pAcl; // original ACL
  438. BOOL fDaclPresent;
  439. BOOL fDaclDefault;
  440. SECURITY_DESCRIPTOR absSD; // Absolute SD
  441. DWORD AbsSize = sizeof(SECURITY_DESCRIPTOR); // Absolute SD size
  442. DWORD DaclSize; // Absolute DACL size
  443. DWORD SaclSize; // Absolute SACL size
  444. DWORD OSidSize; // Absolute OSID size
  445. DWORD PSidSize; // Absolute PSID size
  446. // Get the original DACL list
  447. RegGetKeySecurity( hKey, DACL_SECURITY_INFORMATION, NULL, &cbSize);
  448. psd = (PSECURITY_DESCRIPTOR *)LocalAlloc(LMEM_ZEROINIT, cbSize+sizeof(ACCESS_ALLOWED_ACE)+sizeof(ACCESS_MASK)+sizeof(SID));
  449. pDacl = (PACL)LocalAlloc(LMEM_ZEROINIT, cbSize+sizeof(ACCESS_ALLOWED_ACE)+sizeof(ACCESS_MASK)+sizeof(SID));
  450. pSacl = (PACL)LocalAlloc(LMEM_ZEROINIT, cbSize);
  451. pOSid = (PSID)LocalAlloc(LMEM_ZEROINIT, cbSize);
  452. pPSid = (PSID)LocalAlloc(LMEM_ZEROINIT, cbSize);
  453. DaclSize = cbSize+sizeof(ACCESS_ALLOWED_ACE)+sizeof(ACCESS_MASK)+sizeof(SID);
  454. SaclSize = cbSize;
  455. OSidSize = cbSize;
  456. PSidSize = cbSize;
  457. if (( NULL == psd) ||
  458. ( NULL == pDacl) ||
  459. ( NULL == pSacl) ||
  460. ( NULL == pOSid) ||
  461. ( NULL == pPSid))
  462. {
  463. err = ERROR_INSUFFICIENT_BUFFER;
  464. break;
  465. }
  466. if ( (err = RegGetKeySecurity( hKey, DACL_SECURITY_INFORMATION, psd, &cbSize )) != ERROR_SUCCESS )
  467. {
  468. break;
  469. }
  470. if ( !GetSecurityDescriptorDacl( psd, &fDaclPresent, &pAcl, &fDaclDefault ))
  471. {
  472. err = GetLastError();
  473. break;
  474. }
  475. // Increase the size for an extra ACE
  476. pAcl->AclSize += sizeof(ACCESS_ALLOWED_ACE)+sizeof(ACCESS_MASK)+sizeof(SID);
  477. // Get World SID
  478. if ( (err = RtlAllocateAndInitializeSid( &SidAuth, 1,
  479. SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSid)) != ERROR_SUCCESS)
  480. {
  481. break;
  482. }
  483. // Add Permission ACE
  484. if ( !AddAccessAllowedAce(pAcl, ACL_REVISION, dwPermission ,pSid))
  485. {
  486. err = GetLastError();
  487. break;
  488. }
  489. // Convert from relate format to absolute format
  490. if ( !MakeAbsoluteSD( psd, &absSD, &AbsSize, pDacl, &DaclSize, pSacl, &SaclSize,
  491. pOSid, &OSidSize, pPSid, &PSidSize ))
  492. {
  493. err = GetLastError();
  494. break;
  495. }
  496. // Set SD
  497. if ( !SetSecurityDescriptorDacl( &absSD, TRUE, pAcl, FALSE ))
  498. {
  499. err = GetLastError();
  500. break;
  501. }
  502. if ( (err = RegSetKeySecurity( hKey, DACL_SECURITY_INFORMATION, psd ))
  503. != ERROR_SUCCESS )
  504. {
  505. break;
  506. }
  507. } while (FALSE);
  508. // Clean up the memory
  509. RtlFreeSid( pSid );
  510. LocalFree( psd );
  511. LocalFree( pDacl );
  512. LocalFree( pSacl );
  513. LocalFree( pOSid );
  514. LocalFree( pPSid );
  515. return (HRESULT_FROM_WIN32(err));
  516. }
  517. //+---------------------------------------------------------------------------
  518. //
  519. // Function: HrSetEverybodyPermissionsOnOptionsKeys
  520. //
  521. // Purpose: Recurse through the options keys (if any), and set the
  522. // "Everybody" permissions on them.
  523. //
  524. // Arguments:
  525. // hkeyOptions []
  526. // dwPermissions []
  527. //
  528. // Returns:
  529. //
  530. // Author: jeffspr 10 Sep 1997
  531. //
  532. // Notes:
  533. //
  534. HRESULT HrSetEverybodyPermissionsOnOptionsKeys(HKEY hkeyOptions, DWORD dwPermissions)
  535. {
  536. HRESULT hr = S_OK;
  537. DWORD dwIndex = 0;
  538. WCHAR szSubkeyName[MAX_PATH+1];
  539. FILETIME ft;
  540. Assert(hkeyOptions);
  541. // First, do it on the root key.
  542. //
  543. hr = HrNwLibSetEverybodyPermission(hkeyOptions, dwPermissions);
  544. // Enumerate the keys, and set it on them as well
  545. //
  546. while (SUCCEEDED(hr))
  547. {
  548. DWORD dwSubkeyNameSize = MAX_PATH+1;
  549. // Get the next key (starting with 0)
  550. //
  551. hr = HrRegEnumKeyEx( hkeyOptions,
  552. dwIndex++,
  553. szSubkeyName,
  554. &dwSubkeyNameSize,
  555. NULL,
  556. NULL,
  557. &ft);
  558. if (SUCCEEDED(hr))
  559. {
  560. HKEY hkeyUser = NULL;
  561. // Open that key for write
  562. hr = HrRegOpenKeyEx(hkeyOptions,
  563. szSubkeyName,
  564. KEY_ALL_ACCESS,
  565. &hkeyUser);
  566. if (SUCCEEDED(hr))
  567. {
  568. hr = HrNwLibSetEverybodyPermission(hkeyUser, dwPermissions);
  569. }
  570. RegSafeCloseKey(hkeyUser);
  571. }
  572. }
  573. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
  574. {
  575. hr = S_OK;
  576. }
  577. TraceError("HrSetEverybodyPermissionsOnOptionsKeys", hr);
  578. return hr;
  579. }
  580. //+---------------------------------------------------------------------------
  581. //
  582. // Function: HrCreateParametersSubkeys
  583. //
  584. // Purpose: Creates the subkeys under the NWCWorkstation parameters key.
  585. // This could have been done in the INF, but there were some
  586. // permissions that needed to be set on the keys as well, so
  587. // all of the work now takes place in this function.
  588. //
  589. // Arguments:
  590. // (none)
  591. //
  592. // Returns: S_OK or valid Win32 error code.
  593. //
  594. // Author: jeffspr 24 Jun 1997
  595. //
  596. // Notes:
  597. //
  598. HRESULT HrCreateParametersSubkeys()
  599. {
  600. HRESULT hr = S_OK;
  601. HKEY hkeyOption = NULL;
  602. HKEY hkeyLogon = NULL;
  603. DWORD dwDisposition = 0;
  604. TraceTag(ttidNWClientCfgFn, ">> HrCreateParametersSubkeys");
  605. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE,
  606. c_szParamOptionKeyPath,
  607. 0,
  608. KEY_ALL_ACCESS,
  609. NULL,
  610. &hkeyOption,
  611. &dwDisposition);
  612. if (FAILED(hr))
  613. {
  614. TraceTag(ttidNWClientCfg, "HrCreateParametersSubkeys() - failed to "
  615. "create/open key %S", c_szParamOptionKeyPath);
  616. goto Exit;
  617. }
  618. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE,
  619. c_szParamLogonKeyPath,
  620. 0,
  621. KEY_SET_VALUE,
  622. NULL,
  623. &hkeyLogon,
  624. &dwDisposition);
  625. if (FAILED(hr))
  626. {
  627. TraceTag(ttidNWClientCfg, "HrCreateParametersSubkeys() - failed to "
  628. "create/open key %S", c_szParamLogonKeyPath);
  629. goto Exit;
  630. }
  631. hr = HrSetEverybodyPermissionsOnOptionsKeys(hkeyOption, c_dwOptionKeyPermissions);
  632. if (FAILED(hr))
  633. {
  634. TraceTag(ttidNWClientCfg, "HrSetEverybodyPermissionsOnOptionsKeys failed, hr: 0x%08x", hr);
  635. goto Exit;
  636. }
  637. Exit:
  638. // Close the hkeys, if they're open
  639. RegSafeCloseKey(hkeyLogon);
  640. RegSafeCloseKey(hkeyOption);
  641. TraceTag(ttidNWClientCfgFn, ">> HrCreateParametersSubkeys");
  642. TraceError("HrCreateParametersSubkeys", hr);
  643. return hr;
  644. }
  645. //+---------------------------------------------------------------------------
  646. //
  647. // Function: HrDeleteParametersSubkeys
  648. //
  649. // Purpose: Deletes the subkeys under the NWCWorkstation parameters key.
  650. //
  651. // Arguments:
  652. // (none)
  653. //
  654. // Returns: S_OK or valid Win32 error code.
  655. //
  656. // Author: jeffspr 24 Jun 1997
  657. //
  658. // Notes:
  659. //
  660. HRESULT HrDeleteParametersSubkeys()
  661. {
  662. HRESULT hr = S_OK;
  663. TraceTag(ttidNWClientCfgFn, ">> HrDeleteParametersSubkeys");
  664. // Note: We need to be taking ownership of these keys so we can delete
  665. // them. Regardless, ignore if the key deletions fail.
  666. hr = HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE,
  667. c_szParamOptionKeyPath);
  668. if (FAILED(hr))
  669. {
  670. TraceTag(ttidNWClientCfg, "HrDeleteParametersSubkeys() - failed to "
  671. "delete key %S, hr = 0x%08x", c_szParamOptionKeyPath, hr);
  672. hr = S_OK;
  673. }
  674. hr = HrRegDeleteKey(HKEY_LOCAL_MACHINE,
  675. c_szParamLogonKeyPath);
  676. if (FAILED(hr))
  677. {
  678. TraceTag(ttidNWClientCfg, "HrDeleteParametersSubkeys() - failed to "
  679. "delete key %S, hr = 0x%08x", c_szParamLogonKeyPath, hr);
  680. hr = S_OK;
  681. }
  682. TraceTag(ttidNWClientCfgFn, ">> HrDeleteParametersSubkeys");
  683. TraceError("HrDeleteParametersSubkeys", hr);
  684. return hr;
  685. }
  686. //+---------------------------------------------------------------------------
  687. //
  688. // Function: FCheckForExistingFile
  689. //
  690. // Purpose: Checks for the existance of the passed in file. Should be
  691. // common-ized.
  692. //
  693. // Arguments:
  694. // pszFileToCheck [] The file name to verify
  695. //
  696. // Returns: TRUE if the file was found, FALSE otherwise.
  697. //
  698. // Author: jeffspr 24 Jun 1997
  699. //
  700. // Notes: $$TODO: Should be improved if we move this to common code.
  701. // The thing that it doesn't do is distinguish between a file
  702. // being "not found" and a file error (such as access rights
  703. // or sharing violations) on the CreateFile call.
  704. //
  705. BOOL FCheckForExistingFile( PSTR pszFileToCheck )
  706. {
  707. BOOL fReturn = TRUE;
  708. HANDLE hFile = NULL;
  709. TraceTag(ttidNWClientCfgFn, ">> FCheckForExistingFile");
  710. hFile = CreateFileA(pszFileToCheck,
  711. GENERIC_READ,
  712. 0, // No sharing allowed
  713. NULL, // No security attributes
  714. OPEN_EXISTING, // Fail if file doesn't exist
  715. FILE_ATTRIBUTE_NORMAL,
  716. NULL);
  717. if (hFile != INVALID_HANDLE_VALUE)
  718. {
  719. CloseHandle(hFile);
  720. hFile = NULL;
  721. }
  722. else
  723. {
  724. // This was previously a bug. We weren't setting FALSE here, which made
  725. // the function somewhat useless.
  726. fReturn = FALSE;
  727. }
  728. TraceTag(ttidNWClientCfgFn, "<< FCheckForExistingFile");
  729. return fReturn;
  730. }
  731. //+---------------------------------------------------------------------------
  732. //
  733. // Function: KillTrailingWhitespace
  734. //
  735. // Purpose: Remove whitespace from a non-UNICODE string. This is a utility
  736. // function for the autoexec.nt parser
  737. //
  738. // Arguments:
  739. // pszKillMyWhitespace [] String from which to remove whitespace
  740. //
  741. // Returns:
  742. //
  743. // Author: jeffspr 24 Jun 1997
  744. //
  745. // Notes:
  746. //
  747. VOID KillTrailingWhitespace( PSTR pszKillMyWhitespace )
  748. {
  749. long lLength = 0;
  750. if (!pszKillMyWhitespace)
  751. {
  752. Assert(pszKillMyWhitespace);
  753. goto Exit;
  754. }
  755. lLength = lstrlenA(pszKillMyWhitespace);
  756. if (lLength == 0)
  757. {
  758. goto Exit;
  759. }
  760. while (isspace(pszKillMyWhitespace[lLength-1]))
  761. {
  762. pszKillMyWhitespace[--lLength] = '\0';
  763. }
  764. Exit:
  765. return;
  766. }
  767. //+---------------------------------------------------------------------------
  768. //
  769. // Function: FMoveSzToEndOfFile
  770. //
  771. // Purpose: Find a string in the file of this name, and if it's present,
  772. // move the string to the end of the file. This is used by the
  773. // autoexec.nt parser to move the IPX stuff to the end of the
  774. // file. This is a rewrite of similar code in the nwcfg.dll
  775. // stuff. That code apparently wasn't UNICODE, and didn't work
  776. // for what we were doing.
  777. //
  778. // Arguments:
  779. // pszAutoexecName [] Name of the file to modify
  780. // pszMatch [] String to move
  781. //
  782. // Returns:
  783. //
  784. // Author: jeffspr 24 Jun 1997
  785. //
  786. // Notes:
  787. //
  788. BOOL FMoveSzToEndOfFile( PSTR pszAutoexecName, PSTR pszMatch )
  789. {
  790. FILE * hsrcfile = NULL;
  791. FILE * hdesfile = NULL;
  792. char * pszTempname = NULL;
  793. char szInput[1000];
  794. TraceTag(ttidNWClientCfgFn, ">> FMoveSzToEndOfFile");
  795. // Get a temp name
  796. //
  797. pszTempname = tmpnam(NULL);
  798. // Open the original and the destination files
  799. //
  800. hsrcfile = fopen(pszAutoexecName, "r");
  801. hdesfile = fopen(pszTempname, "w");
  802. if (( hsrcfile != NULL ) && ( hdesfile != NULL ))
  803. {
  804. while (fgets(szInput,1000,hsrcfile))
  805. {
  806. CHAR szInputCopy[1000];
  807. // Copy to another temp buffer so that when we remove the
  808. // trailing whitespace for the comparison, we won't lose the
  809. // original text.
  810. //
  811. strcpy(szInputCopy, szInput);
  812. // Remove the trailing whitespace, so we only have to compare the
  813. // real text
  814. //
  815. KillTrailingWhitespace(szInputCopy);
  816. // Compare the strings
  817. //
  818. if (lstrcmpiA(szInputCopy, pszMatch) != 0)
  819. {
  820. // If the strings weren't identical, then we still want
  821. // to copy the line
  822. //
  823. fputs(szInput,hdesfile);
  824. }
  825. }
  826. // Append the string to the end of the file.
  827. fputs(pszMatch, hdesfile);
  828. fputs("\r\n",hdesfile);
  829. }
  830. if (hsrcfile != NULL)
  831. {
  832. fclose(hsrcfile);
  833. }
  834. if (hdesfile != NULL)
  835. {
  836. fclose(hdesfile);
  837. }
  838. if (( hsrcfile != NULL ) && ( hdesfile != NULL ))
  839. {
  840. CopyFileA(pszTempname,pszAutoexecName, FALSE);
  841. DeleteFileA(pszTempname);
  842. }
  843. TraceTag(ttidNWClientCfgFn, "<< FMoveSzToEndOfFile");
  844. return TRUE;
  845. }
  846. //+---------------------------------------------------------------------------
  847. //
  848. // Function: HrMungeAutoexecNT
  849. //
  850. // Purpose: Move the IPX stuff to the end of the autoexec.nt. Do this by
  851. // calling FMoveSzToEndOfFile on each of our lines.
  852. //
  853. // Arguments:
  854. // (none)
  855. //
  856. // Returns: S_OK or valid Win32 error code.
  857. //
  858. // Author: jeffspr 24 Jun 1997
  859. //
  860. // Notes:
  861. //
  862. HRESULT HrMungeAutoexecNT()
  863. {
  864. HRESULT hr = S_OK;
  865. CHAR szAutoNTPath[MAX_PATH+1] = {0};
  866. CHAR szAutoTmpPath[MAX_PATH+1] = {0};
  867. CHAR szWindowsDirANSI[MAX_PATH+1] = {0};
  868. PSTR pszAutoPath = NULL;
  869. BOOL fResult = FALSE;
  870. PCWSTR pszRem1 = NULL;
  871. PSTR pszaRem1MultiByte = NULL;
  872. int iLength = 0;
  873. TraceTag(ttidNWClientCfgFn, ">> HrMungeAutoexecNT");
  874. // Get the windows directory
  875. if (GetSystemWindowsDirectoryA(szWindowsDirANSI, sizeof(szWindowsDirANSI)) == 0)
  876. {
  877. TraceLastWin32Error("HrMungeAutoexecNT - Call to GetWindowsDirectoryA");
  878. hr = HrFromLastWin32Error();
  879. goto Exit;
  880. }
  881. // Build the path to the autoexec.nt
  882. //
  883. wsprintfA(szAutoNTPath, "%s\\system32\\%s", szWindowsDirANSI, "autoexec.nt");
  884. if (FCheckForExistingFile(szAutoNTPath) == FALSE)
  885. {
  886. wsprintfA(szAutoTmpPath, "%s\\system32\\%s", szWindowsDirANSI, "autoexec.tmp");
  887. if (FCheckForExistingFile(szAutoTmpPath) == FALSE)
  888. {
  889. // Per the old INF, skip the whole shebang.
  890. goto Exit;
  891. }
  892. else
  893. {
  894. pszAutoPath = szAutoTmpPath;
  895. }
  896. }
  897. else
  898. {
  899. pszAutoPath = szAutoNTPath;
  900. }
  901. // At this point, we should have found at least one valid
  902. // autoexec.nt or .tmp file. If not, we should have dropped out of the
  903. // function
  904. Assert(pszAutoPath);
  905. pszRem1 = SzLoadStringPcch(_Module.GetResourceInstance(), IDS_AUTOEXEC_REM1, &iLength);
  906. if (!pszRem1 || iLength == 0)
  907. {
  908. AssertSz(FALSE, "Failed to load STR_AUTOEXEC_REM from the resources");
  909. TraceTag(ttidNWClientCfg,
  910. "ERROR: Failed to load STR_AUTOEXEC_REM from the resources");
  911. hr = E_FAIL;
  912. goto Exit;
  913. }
  914. // Allocate memory for the demoted string.
  915. pszaRem1MultiByte = (PSTR) MemAlloc(lstrlenW(pszRem1) + 1);
  916. if (!pszaRem1MultiByte)
  917. {
  918. TraceTag(ttidNWClientCfg, "ERROR: Failed to alloc memory for demoted string");
  919. hr = E_OUTOFMEMORY;
  920. goto Exit;
  921. }
  922. // Demote the loaded string to multibyte (single char)
  923. WideCharToMultiByte(
  924. CP_ACP, // ANSI code page
  925. 0, // flags for non-mapped character action
  926. pszRem1, // source string
  927. -1, // source string is NULL terminated
  928. pszaRem1MultiByte, // destination string (multibyte)
  929. lstrlenW(pszRem1) + 1, // size of destination string
  930. NULL, // default char on non-mapped char
  931. NULL); // return for default char mapping action
  932. // Move the REM from the autoexec.nt
  933. //
  934. fResult = FMoveSzToEndOfFile(pszAutoPath, pszaRem1MultiByte);
  935. if (!fResult)
  936. {
  937. // Traced in called function.
  938. hr = E_FAIL;
  939. goto Exit;
  940. }
  941. // Move the line that loads nw16
  942. //
  943. fResult = FMoveSzToEndOfFile(pszAutoPath, "lh %SystemRoot%\\system32\\nw16");
  944. if (!fResult)
  945. {
  946. // Traced in called function.
  947. hr = E_FAIL;
  948. goto Exit;
  949. }
  950. // Move the line that loads vwipxspx
  951. //
  952. fResult = FMoveSzToEndOfFile(pszAutoPath, "lh %SystemRoot%\\system32\\vwipxspx");
  953. if (!fResult)
  954. {
  955. // Traced in called function.
  956. hr = E_FAIL;
  957. goto Exit;
  958. }
  959. Exit:
  960. MemFree(pszaRem1MultiByte);
  961. TraceTag(ttidNWClientCfgFn, "<< HrMungeAutoexecNT");
  962. TraceError("HrMungeAutoexecNT", hr);
  963. return hr;
  964. }
  965. //+---------------------------------------------------------------------------
  966. //
  967. // Function: HrAddNetWareToWOWKnownList
  968. //
  969. // Purpose: Add the netware.drv to the WOW "known DLLS" list.
  970. //
  971. // Arguments:
  972. // (none)
  973. //
  974. // Returns: S_OK or valid Win32 error code.
  975. //
  976. // Author: jeffspr 24 Jun 1997
  977. //
  978. // Notes:
  979. //
  980. HRESULT HrAddNetWareToWOWKnownList()
  981. {
  982. HRESULT hr = S_OK;
  983. TraceTag(ttidNWClientCfgFn, ">> HrAddNetWareToWOWKnownList");
  984. // Call the cool new AddString... function
  985. //
  986. hr = HrRegAddStringToSz(
  987. L"netware.drv",
  988. HKEY_LOCAL_MACHINE,
  989. L"System\\CurrentControlSet\\Control\\WOW",
  990. L"KnownDLLS",
  991. L' ',
  992. STRING_FLAG_ENSURE_AT_END,
  993. 0);
  994. TraceTag(ttidNWClientCfgFn, "<< HrAddNetWareToWOWKnownList");
  995. TraceError("HrAddNetWareToWOWKnownList", hr);
  996. return hr;
  997. }
  998. //+---------------------------------------------------------------------------
  999. //
  1000. // Function: HrRemoveNetWareFromWOWKnownList
  1001. //
  1002. // Purpose: Add the netware.drv to the WOW "known DLLS" list.
  1003. //
  1004. // Arguments:
  1005. // (none)
  1006. //
  1007. // Returns: S_OK or valid Win32 error code.
  1008. //
  1009. // Author: jeffspr 24 Jun 1997
  1010. //
  1011. // Notes:
  1012. //
  1013. HRESULT HrRemoveNetWareFromWOWKnownList()
  1014. {
  1015. HRESULT hr = S_OK;
  1016. TraceTag(ttidNWClientCfgFn, ">> HrRemoveNetWareFromWOWKnownList");
  1017. // Call the cool new AddString... function
  1018. //
  1019. hr = HrRegRemoveStringFromSz(
  1020. L"netware.drv",
  1021. HKEY_LOCAL_MACHINE,
  1022. L"System\\CurrentControlSet\\Control\\WOW",
  1023. L"KnownDLLS",
  1024. L' ',
  1025. STRING_FLAG_REMOVE_SINGLE);
  1026. TraceTag(ttidNWClientCfgFn, "<< HrRemoveNetWareFromWOWKnownList");
  1027. TraceError("HrRemoveNetWareFromWOWKnownList", hr);
  1028. return hr;
  1029. }
  1030. //+---------------------------------------------------------------------------
  1031. //
  1032. // Function: HrUpdateLanmanSharedDrivesValue
  1033. //
  1034. // Purpose: If the LanmanServer service exists, make sure that they have the
  1035. // EnableSharedNetDrives value turned on.
  1036. //
  1037. // Arguments:
  1038. // (none)
  1039. //
  1040. // Returns: S_OK or valid Win32 error code.
  1041. //
  1042. // Author: jeffspr 24 Jun 1997
  1043. //
  1044. // Notes:
  1045. //
  1046. HRESULT HrUpdateLanmanSharedDrivesValue()
  1047. {
  1048. HRESULT hr = S_OK;
  1049. const DWORD c_dwESNDValue = 1;
  1050. HKEY hkeyLMSP = NULL;
  1051. SERVER_INFO_1540 si1540 = {0};
  1052. NET_API_STATUS nas = ERROR_SUCCESS;
  1053. DWORD dwDisposition = 0;
  1054. TraceTag(ttidNWClientCfgFn, ">> HrUpdateLanmanSharedDrivesValue");
  1055. // Open the LanmanServer parameters key, if it exists. If it doesn't exist,
  1056. // it will still return S_OK, but the hkey will still be NULL.
  1057. //
  1058. hr = HrRegCreateKeyEx(
  1059. HKEY_LOCAL_MACHINE,
  1060. L"System\\CurrentControlSet\\Services\\LanmanServer\\Parameters",
  1061. REG_OPTION_NON_VOLATILE,
  1062. KEY_SET_VALUE, // samDesired
  1063. NULL,
  1064. &hkeyLMSP,
  1065. &dwDisposition);
  1066. if (FAILED(hr))
  1067. {
  1068. TraceTag(ttidNWClientCfgFn, "Failed to create/open the "
  1069. "LanmanServer\\Parameters key");
  1070. goto Exit;
  1071. }
  1072. Assert(hkeyLMSP);
  1073. hr = HrRegSetDword(
  1074. hkeyLMSP,
  1075. L"EnableSharedNetDrives",
  1076. c_dwESNDValue);
  1077. if (FAILED(hr))
  1078. {
  1079. TraceTag(ttidNWClientCfgFn, "Failed to set the EnabledSharedNetDrives value in "
  1080. "HrUpdateLanmanSharedDrivesValue()");
  1081. goto Exit;
  1082. }
  1083. // Call the NetServerSetInfo with the Enable Shared Net Drives info (1540).
  1084. // This will allow this info to be set dynamically (so as not to require a
  1085. // restart of the "Server" service.
  1086. //
  1087. si1540.sv1540_enablesharednetdrives = TRUE;
  1088. // Set the server info for the EnableSharedDrives value. This will cause it to
  1089. // take effect if the service is running (and will do nothing if it is not).
  1090. //
  1091. nas = NetServerSetInfo(NULL, 1540, (LPBYTE) &si1540, NULL);
  1092. if (nas != NERR_Success)
  1093. {
  1094. // It's actually OK if this fails in one condition (0x842), because
  1095. // it WILL fail if the server service That's not a problem, because
  1096. // the value that I set in the registry above will be picked up the
  1097. // next time the server service starts.
  1098. //
  1099. // OK, cheesy, but I don't know the define, I just know that this is the
  1100. // right return code for our ignorable failure.
  1101. //
  1102. if (nas != 0x842)
  1103. {
  1104. AssertSz(nas == 0x842, "NetServerSetInfo failed for a reason other "
  1105. "than the service not running (which would have been ok)");
  1106. }
  1107. }
  1108. Exit:
  1109. // Close the hkey, if it's open
  1110. RegSafeCloseKey(hkeyLMSP);
  1111. TraceTag(ttidNWClientCfgFn, "<< HrUpdateLanmanSharedDrivesValue");
  1112. TraceError("HrUpdateLanmanSharedDrivesValue()", hr);
  1113. return hr;
  1114. }
  1115. //+---------------------------------------------------------------------------
  1116. //
  1117. // Function: HrRenameNWDocFiles
  1118. //
  1119. // Purpose: On the server install, rename the nwdocgw.* files, since
  1120. // whether we're on CSNW or GSNW, the files are always called
  1121. // nwdoc.*
  1122. //
  1123. // Arguments:
  1124. // (none)
  1125. //
  1126. // Returns:
  1127. //
  1128. // Author: jeffspr 13 Jul 1997
  1129. //
  1130. // Notes:
  1131. //
  1132. HRESULT HrRenameNWDocFiles()
  1133. {
  1134. HRESULT hr = S_OK;
  1135. WCHAR szWindowsDir[MAX_PATH+1];
  1136. WCHAR szSourceName[MAX_PATH+1];
  1137. WCHAR szTargetName[MAX_PATH+1];
  1138. // Get the windows directory
  1139. if (GetSystemWindowsDirectory(szWindowsDir, MAX_PATH) == 0)
  1140. {
  1141. TraceLastWin32Error("HrRenameNWDocFiles - Call to GetSystemWindowsDirectory");
  1142. hr = HrFromLastWin32Error();
  1143. goto Exit;
  1144. }
  1145. // Build the path for the first rename
  1146. //
  1147. wsprintfW(szSourceName, L"%s\\system32\\%s", szWindowsDir, c_szNwDocGWHelpName);
  1148. wsprintfW(szTargetName, L"%s\\system32\\%s", szWindowsDir, c_szNwDocHelpName);
  1149. // Rename the .HLP file. If this fails, no big deal.
  1150. //
  1151. if (!MoveFileEx(szSourceName, szTargetName, MOVEFILE_REPLACE_EXISTING))
  1152. {
  1153. // For debugging only.
  1154. //
  1155. DWORD dwLastError = GetLastError();
  1156. }
  1157. // Build the path for the second rename
  1158. //
  1159. wsprintfW(szSourceName, L"%s\\system32\\%s", szWindowsDir, c_szNwDocGWCNTName);
  1160. wsprintfW(szTargetName, L"%s\\system32\\%s", szWindowsDir, c_szNwDocCNTName);
  1161. // Rename the .CNT file. If this fails, no big deal.
  1162. //
  1163. if (!MoveFileEx(szSourceName, szTargetName, MOVEFILE_REPLACE_EXISTING))
  1164. {
  1165. // For debugging only.
  1166. //
  1167. DWORD dwLastError = GetLastError();
  1168. }
  1169. Exit:
  1170. return hr;
  1171. }