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.

842 lines
25 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C S F M . C P P
  7. //
  8. // Contents: Installation support for Services for Macintosh.
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 5 May 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include <ncxbase.h>
  18. #include "ncatlui.h"
  19. #include "ncmisc.h"
  20. #include "ncreg.h"
  21. #include "ncsfm.h"
  22. #include "ncui.h"
  23. #include "netoc.h"
  24. #include "netocp.h"
  25. #include "resource.h"
  26. #include "sfmsec.h"
  27. #include "macfile.h"
  28. extern const WCHAR c_szBackslash[];
  29. static const WCHAR c_szNTFS[] = L"NTFS";
  30. static const WCHAR c_szColonBackslash[]= L":\\";
  31. // These will have %windir%\system32\ prepended to them
  32. static const WCHAR c_szSrcRSCFile[] = L"SFMUAM.RSC";
  33. static const WCHAR c_szSrcRSCFile5[] = L"SFMUAM5.RSC";
  34. static const WCHAR c_szSrcIFOFile[] = L"SFMUAM.IFO";
  35. static const WCHAR c_szSrcIFOFile5[] = L"SFMUAM5.IFO";
  36. static const WCHAR c_szSrcTXTFile[] = L"SFMUAM.TXT";
  37. static const WCHAR c_szSrcRSCUamInst[] = L"UAMINST.RSC";
  38. static const WCHAR c_szSrcIFOUamInst[] = L"UAMINST.IFO";
  39. // These will have UAM path prepended to them
  40. static const WCHAR c_szDstRSCFile[] = L"\\%s\\MS UAM:Afp_Resource";
  41. static const WCHAR c_szDstRSCFile5[] = L"\\%s\\MS UAM 5.0:Afp_Resource";
  42. static const WCHAR c_szDstIFOFile[] = L"\\%s\\MS UAM:Afp_AfpInfo";
  43. static const WCHAR c_szDstIFOFile5[] = L"\\%s\\MS UAM 5.0:Afp_AfpInfo";
  44. static const WCHAR c_szDstTXTFile[] = L"\\ReadMe.UAM";
  45. static const WCHAR c_szDstRSCUamInst[] = L"\\%s:Afp_Resource";
  46. static const WCHAR c_szDstIFOUamInst[] = L"\\%s:Afp_AfpInfo";
  47. // registry constants
  48. static const WCHAR c_szRegKeyVols[] = L"System\\CurrentControlSet\\Services\\MacFile\\Parameters\\Volumes";
  49. static const WCHAR c_szRegKeyParams[] = L"System\\CurrentControlSet\\Services\\MacFile\\Parameters";
  50. static const WCHAR c_szPath[] = L"PATH=";
  51. static const WCHAR c_szRegValServerOptions[] = L"ServerOptions";
  52. inline BOOL
  53. IsValidHandle(HANDLE h)
  54. {
  55. return (h && INVALID_HANDLE_VALUE != h);
  56. }
  57. //+---------------------------------------------------------------------------
  58. //
  59. // Function: FContainsUAMVolume
  60. //
  61. // Purpose: Determines whether the given drive letter contains a UAM
  62. // volume.
  63. //
  64. // Arguments:
  65. // chDrive [in] Drive letter to search.
  66. //
  67. // Returns: TRUE if drive contains a UAM volume, FALSE if not.
  68. //
  69. // Author: danielwe 22 May 1997
  70. //
  71. // Notes:
  72. //
  73. BOOL FContainsUAMVolume(WCHAR chDrive)
  74. {
  75. tstring strUAMPath;
  76. WIN32_FIND_DATA w32Data;
  77. BOOL frt = FALSE;
  78. HANDLE hfind;
  79. try
  80. {
  81. strUAMPath = chDrive;
  82. strUAMPath += c_szColonBackslash;
  83. strUAMPath += SzLoadIds(IDS_OC_SFM_VOLNAME);
  84. }
  85. catch (bad_alloc)
  86. {
  87. return frt;
  88. }
  89. hfind = FindFirstFile(strUAMPath.c_str(), &w32Data);
  90. if (hfind != INVALID_HANDLE_VALUE)
  91. {
  92. // Found a volume!
  93. frt = TRUE;
  94. FindClose(hfind);
  95. }
  96. return frt;
  97. }
  98. //+---------------------------------------------------------------------------
  99. //
  100. // Function: HrGetFirstPossibleUAMDrive
  101. //
  102. // Purpose: Obtains the first fixed or removable drive's drive letter
  103. // that has the NTFS file system installed on it and/or already
  104. // has a UAM volume on it.
  105. //
  106. // Arguments:
  107. // pchDriveLetter [out] Drive letter returned. If no drive is found,
  108. // this is the NUL character.
  109. //
  110. // Returns: S_OK if successfull, Win32 error otherwise.
  111. //
  112. // Author: danielwe 5 May 1997
  113. //
  114. // Notes:
  115. //
  116. HRESULT HrGetFirstPossibleUAMDrive(WCHAR *pchDriveLetter)
  117. {
  118. HRESULT hr = S_OK;
  119. WCHAR mszDrives[1024];
  120. Assert(pchDriveLetter);
  121. *pchDriveLetter = 0;
  122. ZeroMemory ((PVOID)mszDrives, 1024*sizeof(WCHAR));
  123. if (GetLogicalDriveStrings(celems(mszDrives), mszDrives))
  124. {
  125. PCWSTR pchDrive = NULL;
  126. WCHAR szFileSystem[64];
  127. DWORD dwType;
  128. pchDrive = mszDrives;
  129. while (*pchDrive)
  130. {
  131. // pchDrive is something like "C:\" at this point
  132. dwType = GetDriveType(pchDrive);
  133. if ((dwType == DRIVE_REMOVABLE) || (dwType == DRIVE_FIXED))
  134. {
  135. // Only look at removable or fixed drives.
  136. if (GetVolumeInformation(pchDrive, NULL, 0, NULL, NULL, NULL,
  137. szFileSystem, celems(szFileSystem)))
  138. {
  139. if (!lstrcmpiW(szFileSystem, c_szNTFS))
  140. {
  141. // Drive letter gets first char of drive root path
  142. if (!*pchDriveLetter)
  143. {
  144. // If no drive was found yet, this becomes the
  145. // first
  146. *pchDriveLetter = *pchDrive;
  147. }
  148. // Found NTFS drive. Continue looking, though
  149. // in case there exists an NTFS drive that already has
  150. // a UAM volume on it.
  151. if (FContainsUAMVolume(*pchDrive))
  152. {
  153. // Override first drive letter and use this one
  154. // and break because it already has a UAM volume
  155. // on it.
  156. *pchDriveLetter = *pchDrive;
  157. break;
  158. }
  159. }
  160. }
  161. }
  162. pchDrive += lstrlenW(pchDrive) + 1;
  163. }
  164. }
  165. else
  166. {
  167. hr = HrFromLastWin32Error();
  168. }
  169. TraceError("HrGetFirstPossibleUAMDrive", hr);
  170. return hr;
  171. }
  172. //+---------------------------------------------------------------------------
  173. //
  174. // Function: HrDeleteOldFolders
  175. //
  176. // Purpose: Removes the old AppleShare Folder directory from an NT4 to
  177. // NT5 upgrade.
  178. //
  179. // Arguments:
  180. // pszUamPath [in] Path to UAM volume.
  181. //
  182. // Returns: S_OK if success, WIN32 error otherwise
  183. //
  184. // Author: danielwe 15 Dec 1998
  185. //
  186. // Notes:
  187. //
  188. HRESULT HrDeleteOldFolders(PCWSTR pszUamPath)
  189. {
  190. HRESULT hr = S_OK;
  191. WCHAR szOldFolder[MAX_PATH];
  192. if (wcslen(pszUamPath) > (MAX_PATH - wcslen(c_szBackslash) - wcslen(SzLoadIds(IDS_OC_SFM_APPLESHARE_FOLDER)) - 1))
  193. {
  194. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  195. return hr;
  196. }
  197. lstrcpyW(szOldFolder, pszUamPath);
  198. lstrcatW(szOldFolder, c_szBackslash);
  199. lstrcatW(szOldFolder, SzLoadIds(IDS_OC_SFM_APPLESHARE_FOLDER));
  200. hr = HrDeleteDirectory(szOldFolder, TRUE);
  201. if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ||
  202. (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr))
  203. {
  204. // ok if old directory was not there
  205. hr = S_OK;
  206. }
  207. TraceError("HrDeleteOldFolders", hr);
  208. return hr;
  209. }
  210. //+---------------------------------------------------------------------------
  211. //
  212. // Function: HrInstallSFM
  213. //
  214. // Purpose: Called when SFM is being installed. Handles all of the
  215. // additional installation for SFM beyond that of the INF file.
  216. //
  217. // Arguments:
  218. // pnocd [in] Pointer to NETOC data.
  219. //
  220. // Returns: S_OK if successfull, Win32 error otherwise.
  221. //
  222. // Author: danielwe 5 May 1997
  223. //
  224. // Notes:
  225. //
  226. HRESULT HrInstallSFM(PNETOCDATA pnocd)
  227. {
  228. HRESULT hr = S_OK;
  229. WCHAR chNTFSDrive;
  230. hr = HrGetFirstPossibleUAMDrive(&chNTFSDrive);
  231. if (SUCCEEDED(hr))
  232. {
  233. if (chNTFSDrive != 0)
  234. {
  235. WCHAR szUAMPath[MAX_PATH];
  236. szUAMPath[0] = chNTFSDrive;
  237. szUAMPath[1] = 0;
  238. lstrcatW(szUAMPath, c_szColonBackslash);
  239. lstrcatW(szUAMPath, SzLoadIds(IDS_OC_SFM_VOLNAME));
  240. // UAM Path is now something like "D:\Microsoft UAM Volume".
  241. hr = HrDeleteOldFolders(szUAMPath);
  242. if (SUCCEEDED(hr))
  243. {
  244. hr = HrSetupUAM(szUAMPath);
  245. if (SUCCEEDED(hr))
  246. {
  247. WCHAR szValue[MAX_PATH];
  248. lstrcpyW(szValue, c_szPath);
  249. lstrcatW(szValue, szUAMPath);
  250. // Add the final multi_sz value to the registry
  251. hr = HrRegAddStringToMultiSz(szValue,
  252. HKEY_LOCAL_MACHINE,
  253. c_szRegKeyVols,
  254. SzLoadIds(IDS_OC_SFM_VOLNAME),
  255. STRING_FLAG_ENSURE_AT_END,
  256. 0);
  257. }
  258. }
  259. }
  260. else
  261. {
  262. // No NTFS drives present.
  263. //$ REVIEW (danielwe) 6 May 1997: For now we will fail,
  264. // but how can we do this in the future?
  265. // Not the best error code, but hopefully it's close to
  266. // what we want.
  267. hr = HRESULT_FROM_WIN32(ERROR_UNRECOGNIZED_MEDIA);
  268. }
  269. }
  270. TraceError("HrInstallSFM", hr);
  271. return hr;
  272. }
  273. //+---------------------------------------------------------------------------
  274. //
  275. // Function: HrRemoveSFM
  276. //
  277. // Purpose: Handles additional removal requirements for SFM component.
  278. //
  279. // pnocd [in] Pointer to NETOC data.
  280. //
  281. // Returns: S_OK if successfull, Win32 error otherwise.
  282. //
  283. // Author: danielwe 5 May 1997
  284. //
  285. // Notes:
  286. //
  287. HRESULT HrRemoveSFM(PNETOCDATA pnocd)
  288. {
  289. HRESULT hr = S_OK;
  290. static const WCHAR c_szRegKeyLsa[] = L"System\\CurrentControlSet\\Control\\Lsa";
  291. static const WCHAR c_szRegValueNotif[] = L"Notification Packages";
  292. static const WCHAR c_szRasSfm[] = L"RASSFM";
  293. hr = HrRegRemoveStringFromMultiSz(c_szRasSfm, HKEY_LOCAL_MACHINE,
  294. c_szRegKeyLsa, c_szRegValueNotif,
  295. STRING_FLAG_REMOVE_ALL);
  296. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  297. {
  298. // benign error
  299. hr = S_OK;
  300. }
  301. TraceError("HrRemoveSFM", hr);
  302. return hr;
  303. }
  304. //+---------------------------------------------------------------------------
  305. //
  306. // Function: HrOcExtSFM
  307. //
  308. // Purpose: NetOC external message handler
  309. //
  310. // Arguments:
  311. // pnocd []
  312. // uMsg []
  313. // wParam []
  314. // lParam []
  315. //
  316. // Returns:
  317. //
  318. // Author: danielwe 17 Sep 1998
  319. //
  320. // Notes:
  321. //
  322. HRESULT HrOcExtSFM(PNETOCDATA pnocd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  323. {
  324. HRESULT hr = S_OK;
  325. Assert(pnocd);
  326. switch (uMsg)
  327. {
  328. case NETOCM_POST_INSTALL:
  329. hr = HrOcSfmOnInstall(pnocd);
  330. break;
  331. case NETOCM_QUERY_CHANGE_SEL_STATE:
  332. hr = HrOcSfmOnQueryChangeSelState(pnocd, static_cast<BOOL>(wParam));
  333. break;
  334. }
  335. TraceError("HrOcExtSFM", hr);
  336. return hr;
  337. }
  338. //+---------------------------------------------------------------------------
  339. //
  340. // Function: HrOcSfmOnInstall
  341. //
  342. // Purpose: Called by optional components installer code to handle
  343. // additional installation requirements for SFM.
  344. //
  345. // Arguments:
  346. // pnocd [in] Pointer to NETOC data.
  347. //
  348. // Returns: S_OK if successfull, Win32 error otherwise.
  349. //
  350. // Author: danielwe 5 May 1997
  351. //
  352. // Notes:
  353. //
  354. HRESULT HrOcSfmOnInstall(PNETOCDATA pnocd)
  355. {
  356. HRESULT hr = S_OK;
  357. Assert(pnocd);
  358. if (pnocd->eit == IT_INSTALL || pnocd->eit == IT_UPGRADE)
  359. {
  360. hr = HrInstallSFM(pnocd);
  361. if (HRESULT_FROM_WIN32(ERROR_UNRECOGNIZED_MEDIA) == hr)
  362. {
  363. // This error code means no NTFS drives were present
  364. ReportErrorHr(hr,
  365. IDS_OC_SFM_NO_NTFS,
  366. g_ocmData.hwnd,
  367. SzLoadIds(IDS_OC_GENERIC_COMP));
  368. g_ocmData.fErrorReported = TRUE;
  369. }
  370. else
  371. {
  372. if (SUCCEEDED(hr) && pnocd->eit == IT_UPGRADE)
  373. {
  374. HKEY hkeyParams;
  375. TraceTag(ttidNetOc, "Upgrading MacFile server options...");
  376. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyParams,
  377. KEY_ALL_ACCESS, &hkeyParams);
  378. if (S_OK == hr)
  379. {
  380. DWORD dwOptions;
  381. hr = HrRegQueryDword(hkeyParams, c_szRegValServerOptions,
  382. &dwOptions);
  383. if (S_OK == hr)
  384. {
  385. // 'or' in the UAM option
  386. //
  387. hr = HrRegSetDword(hkeyParams, c_szRegValServerOptions,
  388. dwOptions | AFP_SRVROPT_MICROSOFT_UAM);
  389. }
  390. RegCloseKey (hkeyParams);
  391. }
  392. }
  393. }
  394. }
  395. else
  396. {
  397. // Do not call HrRemoveSFM anymore.
  398. // It removes an entry in the notification packages list for LSA.
  399. // RASSFM entry should never be removed if LSA/SAM is to notify
  400. // SFM/IAS about changes in password/guest account changes etc.
  401. //hr = HrRemoveSFM(pnocd);
  402. }
  403. TraceError("HrOcSfmOnInstall", hr);
  404. return hr;
  405. }
  406. //+---------------------------------------------------------------------------
  407. //
  408. // Function: HrOcSfmOnQueryChangeSelState
  409. //
  410. // Purpose: Handles the request of the OC framework of whether or not
  411. // the user should be allowed to install this component.
  412. //
  413. // Arguments:
  414. // pnocd [in] NetOC Data
  415. // fShowUi [in] TRUE if UI should be shown, FALSE if not
  416. //
  417. // Returns: S_OK if install is allowed, S_FALSE if not, Win32 error
  418. // otherwise
  419. //
  420. // Author: danielwe 6 Feb 1998
  421. //
  422. // Notes:
  423. //
  424. HRESULT HrOcSfmOnQueryChangeSelState(PNETOCDATA pnocd, BOOL fShowUi)
  425. {
  426. HRESULT hr = S_OK;
  427. WCHAR chNTFSDrive;
  428. Assert(pnocd);
  429. Assert(g_ocmData.hwnd);
  430. // See if an NTFS volume exists
  431. hr = HrGetFirstPossibleUAMDrive(&chNTFSDrive);
  432. if (SUCCEEDED(hr))
  433. {
  434. if (chNTFSDrive == 0)
  435. {
  436. if (fShowUi)
  437. {
  438. ReportErrorHr(hr,
  439. IDS_OC_SFM_NO_NTFS,
  440. g_ocmData.hwnd,
  441. SzLoadIds(IDS_OC_GENERIC_COMP));
  442. }
  443. hr = S_FALSE;
  444. }
  445. }
  446. TraceError("HrOcSfmOnQueryChangeSelState", (S_FALSE == hr) ? S_OK : hr);
  447. return hr;
  448. }
  449. //+---------------------------------------------------------------------------
  450. //
  451. // Function: HrCreateDirectory
  452. //
  453. // Purpose: Creates the given directory. If the directory already exists,
  454. // no error is returned.
  455. //
  456. // Arguments:
  457. // pszDir [in] Path to directory to create.
  458. //
  459. // Returns: S_OK if success, Win32 error otherwise.
  460. //
  461. // Author: danielwe 5 May 1997
  462. //
  463. // Notes:
  464. //
  465. HRESULT HrCreateDirectory(PCWSTR pszDir)
  466. {
  467. HRESULT hr = S_OK;
  468. if (!CreateDirectory(pszDir, NULL))
  469. {
  470. // Don't complain if directory already exists.
  471. if (GetLastError() != ERROR_ALREADY_EXISTS)
  472. {
  473. hr = HrFromLastWin32Error();
  474. }
  475. }
  476. TraceError("HrCreateDirectory" ,hr);
  477. return hr;
  478. }
  479. struct FOLDER
  480. {
  481. UINT idsFoldName;
  482. PCWSTR aszSrcFiles[2];
  483. PCWSTR aszDstFiles[2];
  484. };
  485. static const FOLDER c_afold[] =
  486. {
  487. {
  488. IDS_OC_SFM_FOLDNAMENT4,
  489. {
  490. c_szSrcRSCFile,
  491. c_szSrcIFOFile
  492. },
  493. {
  494. c_szDstRSCFile,
  495. c_szDstIFOFile,
  496. }
  497. },
  498. {
  499. IDS_OC_SFM_FOLDNAMENT5,
  500. {
  501. c_szSrcRSCFile5,
  502. c_szSrcIFOFile5
  503. },
  504. {
  505. c_szDstRSCFile5,
  506. c_szDstIFOFile5
  507. }
  508. }
  509. };
  510. static const INT c_cfold = celems(c_afold);
  511. static const PCWSTR c_aszRootFilesSrc[] =
  512. {
  513. c_szSrcTXTFile,
  514. c_szSrcIFOUamInst,
  515. c_szSrcRSCUamInst,
  516. };
  517. static const PCWSTR c_aszRootFilesDst[] =
  518. {
  519. c_szDstTXTFile,
  520. c_szDstIFOUamInst,
  521. c_szDstRSCUamInst,
  522. };
  523. static const INT c_cszFilesRoot = celems(c_aszRootFilesDst);
  524. //+---------------------------------------------------------------------------
  525. //
  526. // Function: HrCopyFileAsStream
  527. //
  528. // Purpose: Copies a default data stream file as a named stream file
  529. //
  530. // Arguments: Same as CopyFile
  531. //
  532. // Returns: Same as CopyFile
  533. //
  534. // Author: roelfc 30 January 2002
  535. //
  536. // Notes: This function replaces the normal CopyFile API by manually
  537. // reading the default data stream and writing it as a named
  538. // stream to the new file name.
  539. // This is because applications like eTrust can cause the normal
  540. // CopyFile API to fail, since eTrust injects an additional stream
  541. // into the file when the incremental scan option is used.
  542. // (See RAID# 493890:
  543. // SFM: File Services for Mac doesn't install with etrust installed.)
  544. //
  545. BOOL HrCopyFileAsStream(PWSTR pszSourceFileName,
  546. PWSTR pszDestFileName,
  547. BOOL bFailIfExists)
  548. {
  549. DWORD dwSize;
  550. DWORD dwResult = NO_ERROR;
  551. BOOL fResult = FALSE;
  552. PBYTE pBuffer = NULL;
  553. HANDLE hSourceFile = NULL;
  554. HANDLE hDestFile = NULL;
  555. TraceTag(ttidNetOc, "HrCopyFileAsStream: Copying \"%s\" to \"%s\"...",
  556. pszSourceFileName, pszDestFileName);
  557. // Open the unnamed stream source file first
  558. hSourceFile = CreateFile(pszSourceFileName,
  559. GENERIC_READ,
  560. FILE_SHARE_READ,
  561. NULL,
  562. OPEN_EXISTING,
  563. FILE_ATTRIBUTE_NORMAL,
  564. NULL);
  565. if (INVALID_HANDLE_VALUE != hSourceFile)
  566. {
  567. dwSize = GetFileSize(hSourceFile, NULL);
  568. if (0xFFFFFFFF != dwSize)
  569. {
  570. // Since we know we are working with small files,
  571. // we can allocate the total file size.
  572. pBuffer = (PBYTE)LocalAlloc(LPTR,dwSize);
  573. if (NULL != pBuffer)
  574. {
  575. DWORD dwBytesRead;
  576. if (ReadFile(hSourceFile, pBuffer, dwSize, &dwBytesRead, NULL))
  577. {
  578. // Sanity check
  579. Assert(dwSize == dwBytesRead);
  580. // Now try to open the named stream destination file
  581. hDestFile = CreateFile(pszDestFileName,
  582. GENERIC_WRITE,
  583. 0,
  584. NULL,
  585. bFailIfExists ? CREATE_NEW : CREATE_ALWAYS,
  586. FILE_ATTRIBUTE_NORMAL,
  587. NULL);
  588. if (INVALID_HANDLE_VALUE != hDestFile)
  589. {
  590. DWORD dwBytesWritten;
  591. if (WriteFile(hDestFile, pBuffer, dwSize, &dwBytesWritten, NULL))
  592. {
  593. // Another sanity check
  594. Assert(dwSize == dwBytesWritten);
  595. fResult = TRUE;
  596. }
  597. }
  598. }
  599. }
  600. }
  601. }
  602. // Save the last error result code
  603. if (!fResult)
  604. {
  605. dwResult = GetLastError();
  606. }
  607. if (IsValidHandle(hSourceFile))
  608. {
  609. CloseHandle(hSourceFile);
  610. }
  611. if (IsValidHandle(hDestFile))
  612. {
  613. CloseHandle(hDestFile);
  614. }
  615. if (NULL != pBuffer)
  616. {
  617. LocalFree(pBuffer);
  618. }
  619. // Set the last result code again
  620. SetLastError(dwResult);
  621. TraceError("HrCopyFileAsStream", fResult ? S_OK : HrFromLastWin32Error());
  622. return fResult;
  623. }
  624. //+---------------------------------------------------------------------------
  625. //
  626. // Function: HrSetupUAM
  627. //
  628. // Purpose: Copies the UAM files to the proper UAM path.
  629. //
  630. // Arguments:
  631. // pszPath [in] Path to UAM volume.
  632. //
  633. // Returns: S_OK if successfull, Win32 error otherwise.
  634. //
  635. // Author: danielwe 5 May 1997
  636. //
  637. // Notes:
  638. //
  639. HRESULT HrSetupUAM(PWSTR pszPath)
  640. {
  641. HRESULT hr = S_OK;
  642. WCHAR szWinDir[MAX_PATH];
  643. INT isz;
  644. // Create dir: "X:\Microsoft UAM Volume"
  645. hr = HrCreateDirectory(pszPath);
  646. if (SUCCEEDED(hr))
  647. {
  648. hr = HrSecureSfmDirectory(pszPath);
  649. if (SUCCEEDED(hr))
  650. {
  651. INT ifold;
  652. for (ifold = 0; ifold < c_cfold; ifold++)
  653. {
  654. WCHAR szNewDir[MAX_PATH];
  655. lstrcpyW(szNewDir, pszPath);
  656. lstrcatW(szNewDir, c_szBackslash);
  657. lstrcatW(szNewDir, SzLoadIds(c_afold[ifold].idsFoldName));
  658. lstrcatW(szNewDir, c_szBackslash);
  659. lstrcatW(szNewDir, SzLoadIds(IDS_OC_SFM_APPLESHARE_FOLDER));
  660. lstrcatW(szNewDir, c_szBackslash);
  661. // Create dir: "X:\Microsoft UAM Volume\<folder>\AppleShare Folder"
  662. hr = HrCreateDirectoryTree(szNewDir, NULL);
  663. if (SUCCEEDED(hr))
  664. {
  665. if (GetSystemDirectory(szWinDir, celems(szWinDir)))
  666. {
  667. WCHAR szSrcFile[MAX_PATH];
  668. WCHAR szDstFile[MAX_PATH];
  669. WCHAR szDstFilePath[MAX_PATH];
  670. INT isz;
  671. for (isz = 0; isz < celems(c_afold[ifold].aszSrcFiles);
  672. isz++)
  673. {
  674. lstrcpyW(szSrcFile, szWinDir);
  675. lstrcatW(szSrcFile, c_szBackslash);
  676. lstrcatW(szSrcFile, c_afold[ifold].aszSrcFiles[isz]);
  677. lstrcpyW(szDstFile, pszPath);
  678. lstrcatW(szDstFile, c_szBackslash);
  679. lstrcatW(szDstFile, SzLoadIds(c_afold[ifold].idsFoldName));
  680. wsprintf(szDstFilePath,
  681. c_afold[ifold].aszDstFiles[isz],
  682. SzLoadIds(IDS_OC_SFM_APPLESHARE_FOLDER));
  683. lstrcatW(szDstFile, szDstFilePath);
  684. TraceTag(ttidNetOc, "MacFile: Copying %S to %S...",
  685. szSrcFile, szDstFile);
  686. if (!HrCopyFileAsStream(szSrcFile, szDstFile, FALSE))
  687. {
  688. hr = HrFromLastWin32Error();
  689. goto err;
  690. }
  691. }
  692. }
  693. else
  694. {
  695. hr = HrFromLastWin32Error();
  696. }
  697. }
  698. }
  699. }
  700. }
  701. // Copy files to the root
  702. //
  703. if (SUCCEEDED(hr))
  704. {
  705. for (isz = 0; isz < c_cszFilesRoot; isz++)
  706. {
  707. WCHAR szSrcFile[MAX_PATH];
  708. WCHAR szDstFile[MAX_PATH];
  709. lstrcpyW(szSrcFile, szWinDir);
  710. lstrcatW(szSrcFile, c_szBackslash);
  711. lstrcatW(szSrcFile, c_aszRootFilesSrc[isz]);
  712. if ((c_aszRootFilesDst[isz] == c_szDstIFOUamInst) ||
  713. (c_aszRootFilesDst[isz] == c_szDstRSCUamInst))
  714. {
  715. WCHAR szTemp[MAX_PATH];
  716. lstrcpyW(szTemp, pszPath);
  717. lstrcatW(szTemp, c_aszRootFilesDst[isz]);
  718. wsprintfW(szDstFile, szTemp,
  719. SzLoadIds(IDS_OC_SFM_UAM_INSTALLER));
  720. }
  721. else
  722. {
  723. lstrcpyW(szDstFile, pszPath);
  724. lstrcatW(szDstFile, c_aszRootFilesDst[isz]);
  725. }
  726. TraceTag(ttidNetOc, "MacFile: Copying %S to %S", szSrcFile,
  727. szDstFile);
  728. if (!HrCopyFileAsStream(szSrcFile, szDstFile, FALSE))
  729. {
  730. hr = HrFromLastWin32Error();
  731. goto err;
  732. }
  733. }
  734. }
  735. err:
  736. TraceError("HrSetupUAM", hr);
  737. return hr;
  738. }