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.

1242 lines
28 KiB

  1. //
  2. // global.cpp
  3. //
  4. #include "StdAfx.h"
  5. #include <sddl.h>
  6. #include "global.h"
  7. #include "util.h"
  8. #include "SSRLog.h"
  9. CFBLogMgr g_fblog;
  10. WCHAR g_wszSsrRoot[MAX_PATH + 1];
  11. DWORD g_dwSsrRootLen = 0;
  12. LPCWSTR g_pwszSSRRootToExpand = L"%windir%\\Security\\SSR";
  13. //
  14. // this is our ACL list
  15. //
  16. //LPCWSTR g_pwszSsrDCOMSecDescripACL = L"D:(A;;GA;;;SY)(A;;GA;;;BA)";
  17. LPCWSTR g_pwszAppID = L"SOFTWARE\\Classes\\APPID\\{3f2db10f-6368-4702-a4b1-e5149d931370}";
  18. LPCWSTR g_pwszAccessPermission = L"AccessPermission";
  19. LPCWSTR g_pwszLaunchPermission = L"LaunchPermission";
  20. //
  21. // registry's SSR root
  22. //
  23. LPCWSTR g_pwszSSRRegRoot = L"Software\\Microsoft\\Security\\SSR";
  24. LPCWSTR g_pwszSSR = L"SSR";
  25. LPCWSTR g_pwszLogs = L"Logs";
  26. //
  27. // The following are reserved action verbs
  28. //
  29. CComBSTR g_bstrConfigure(L"Configure");
  30. CComBSTR g_bstrRollback(L"Rollback");
  31. CComBSTR g_bstrReport(L"Report");
  32. //
  33. // the following are reserved file-usage values
  34. //
  35. CComBSTR g_bstrLaunch(L"Launch");
  36. CComBSTR g_bstrResult(L"Result");
  37. //
  38. // the following is the reserved action data's names
  39. //
  40. LPCWSTR g_pwszCurrSecurityPolicy = L"CurrSecurityPolicy";
  41. LPCWSTR g_pwszTransformFiles = L"TransformFiles";
  42. LPCWSTR g_pwszScriptFiles = L"ScriptFiles";
  43. //
  44. // the following are element tag names
  45. //
  46. CComBSTR g_bstrSsrMemberInfo(L"SsrMemberInfo");
  47. CComBSTR g_bstrDescription(L"Description");
  48. CComBSTR g_bstrSupportedAction(L"SupportedAction");
  49. CComBSTR g_bstrProcedures(L"Procedures");
  50. CComBSTR g_bstrDefaultProc(L"DefaultProc");
  51. CComBSTR g_bstrCustomProc(L"CustomProc");
  52. CComBSTR g_bstrTransformInfo(L"TransformInfo");
  53. CComBSTR g_bstrScriptInfo(L"ScriptInfo");
  54. //
  55. // the following are attribute names
  56. //
  57. CComBSTR g_bstrAttrUniqueName(L"UniqueName");
  58. CComBSTR g_bstrAttrMajorVersion(L"MajorVersion");
  59. CComBSTR g_bstrAttrMinorVersion(L"MinorVersion");
  60. CComBSTR g_bstrAttrProgID(L"ProgID");
  61. CComBSTR g_bstrAttrActionName(L"ActionName");
  62. CComBSTR g_bstrAttrActionType(L"ActionType");
  63. CComBSTR g_bstrAttrTemplateFile(L"TemplateFile");
  64. CComBSTR g_bstrAttrResultFile(L"ResultFile");
  65. CComBSTR g_bstrAttrScriptFile(L"ScriptFile");
  66. CComBSTR g_bstrAttrIsStatic(L"IsStatic");
  67. CComBSTR g_bstrAttrIsExecutable(L"IsExecutable");
  68. //
  69. // these are the known action types
  70. //
  71. LPCWSTR g_pwszApply = L"Prepare";
  72. LPCWSTR g_pwszPrepare = L"Prepare";
  73. CComBSTR g_bstrReportFilesDir;
  74. CComBSTR g_bstrConfigureFilesDir;
  75. CComBSTR g_bstrRollbackFilesDir;
  76. CComBSTR g_bstrTransformFilesDir;
  77. CComBSTR g_bstrMemberFilesDir;
  78. CComBSTR g_bstrTrue(L"True");
  79. CComBSTR g_bstrFalse(L"False");
  80. //
  81. // A guid can be represented in string form such as
  82. // {aabbccdd-1234-4321-abcd-1234567890ab}.
  83. // The length of such string format guid returned from StringFromGUID2 etc.
  84. // is 38
  85. //
  86. const long g_lGuidStringLen = 38;
  87. //
  88. // global helper function implementations
  89. //
  90. const BSTR
  91. SsrPGetActionVerbString (
  92. IN SsrActionVerb action
  93. )
  94. /*++
  95. Routine Description:
  96. Functionality:
  97. This will translate an SsrActionVerb value into
  98. the corresponding BSTR
  99. Virtual:
  100. N/A.
  101. Arguments:
  102. action - The SsrActionVerb value
  103. Return Value:
  104. Success: const BSTR of that verb's string;
  105. Failure: NULL.
  106. Notes:
  107. Callers must not release in any form of the returned
  108. BSTR. It is a const BSTR, and you must honor that.
  109. --*/
  110. {
  111. switch (action)
  112. {
  113. case ActionConfigure:
  114. return g_bstrConfigure;
  115. case ActionRollback:
  116. return g_bstrRollback;
  117. case ActionReport:
  118. return g_bstrReport;
  119. }
  120. return NULL;
  121. }
  122. SsrActionVerb
  123. SsrPGetActionVerbFromString (
  124. IN LPCWSTR pwszVerb
  125. )
  126. /*++
  127. Routine Description:
  128. Functionality:
  129. This will translate an string action verb value into
  130. the corresponding SsrActionVerb value.
  131. Virtual:
  132. N/A.
  133. Arguments:
  134. pwszVerb - The action verb string
  135. Return Value:
  136. Success: the appropriate SsrActionVerb value if the verb is recognized
  137. Failure: ActionInvalid.
  138. Notes:
  139. --*/
  140. {
  141. SsrActionVerb ActVerb = ActionInvalid;
  142. if (pwszVerb != NULL)
  143. {
  144. if (_wcsicmp(pwszVerb, g_bstrConfigure) == 0)
  145. {
  146. ActVerb = ActionConfigure;
  147. }
  148. else if (_wcsicmp(pwszVerb, g_bstrRollback) == 0)
  149. {
  150. ActVerb = ActionRollback;
  151. }
  152. else if (_wcsicmp(pwszVerb, g_bstrReport) == 0)
  153. {
  154. ActVerb = ActionReport;
  155. }
  156. }
  157. return ActVerb;
  158. }
  159. HRESULT
  160. SsrPDeleteEntireDirectory (
  161. IN LPCWSTR pwszDirPath
  162. )
  163. /*++
  164. Routine Description:
  165. Functionality:
  166. This will do a recursive delete of all files and subdirectories of the given
  167. directory. RemoveDirectory API only deletes empty directories.
  168. Virtual:
  169. N/A.
  170. Arguments:
  171. pwszDirPath - The path of the directory
  172. Return Value:
  173. Success: S_OK;
  174. Failure: various error codes.
  175. Notes:
  176. --*/
  177. {
  178. HRESULT hr = S_OK;
  179. WIN32_FIND_DATA FindFileData;
  180. //
  181. // prepare the find file filter
  182. //
  183. DWORD dwDirLen = wcslen(pwszDirPath);
  184. if (dwDirLen > MAX_PATH)
  185. {
  186. return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
  187. }
  188. CComBSTR bstrPath(pwszDirPath);
  189. bstrPath += CComBSTR(L"\\*");
  190. if (bstrPath.m_str == NULL)
  191. {
  192. return E_OUTOFMEMORY;
  193. }
  194. HANDLE hFind = ::FindFirstFile(bstrPath, &FindFileData);
  195. //
  196. // IF we have find something, then we have to do a recursive delete,
  197. // Copy the given directory path to our local memory so that we can
  198. // create a full path for the found file/directory
  199. //
  200. if (hFind != INVALID_HANDLE_VALUE)
  201. {
  202. WCHAR wszFullName[MAX_PATH + 2];
  203. wszFullName[MAX_PATH + 1] = L'\0';
  204. ::memcpy(wszFullName, pwszDirPath, sizeof(WCHAR) * (dwDirLen + 1));
  205. DWORD dwFileNameLength;
  206. while (hFind != INVALID_HANDLE_VALUE)
  207. {
  208. //
  209. // don't do anything to the parent directories
  210. //
  211. bool bDots = wcscmp(FindFileData.cFileName, L".") == 0 ||
  212. wcscmp(FindFileData.cFileName, L"..") == 0;
  213. if (!bDots)
  214. {
  215. //
  216. // create the full name of the file/directory
  217. //
  218. dwFileNameLength = wcslen(FindFileData.cFileName);
  219. if (dwDirLen + 1 + dwFileNameLength > MAX_PATH)
  220. {
  221. //
  222. // we don't want names longer than MAX_PATH
  223. //
  224. hr = HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
  225. break;
  226. }
  227. //
  228. // pwszFullName + dwDirLen is where the directory path ends
  229. //
  230. _snwprintf(wszFullName + dwDirLen,
  231. 1 + dwFileNameLength + 1, // backslah plus 0 term.
  232. L"\\%s",
  233. FindFileData.cFileName
  234. );
  235. if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
  236. {
  237. //
  238. // a directory. recursively delete the entire directory
  239. //
  240. hr = ::SsrPDeleteEntireDirectory(wszFullName);
  241. }
  242. else
  243. {
  244. //
  245. // a file
  246. //
  247. if (!::DeleteFile(wszFullName))
  248. {
  249. hr = HRESULT_FROM_WIN32(GetLastError());
  250. break;
  251. }
  252. }
  253. }
  254. if (!::FindNextFile(hFind, &FindFileData))
  255. {
  256. break;
  257. }
  258. }
  259. ::FindClose(hFind);
  260. }
  261. if (SUCCEEDED(hr) && !::RemoveDirectory(pwszDirPath))
  262. {
  263. hr = HRESULT_FROM_WIN32(GetLastError());
  264. }
  265. return hr;
  266. }
  267. HRESULT
  268. SsrPCreateSubDirectories (
  269. IN OUT LPWSTR pwszPath,
  270. IN LPCWSTR pwszSubRoot
  271. )
  272. /*++
  273. Routine Description:
  274. Functionality:
  275. This will create all subdirectory leading to the path.
  276. The assumption is that the path contains a subdirectory
  277. identified by pwszSubRoot, the creation will start from
  278. there.
  279. Virtual:
  280. N/A.
  281. Arguments:
  282. pwszPath - The path of the directory
  283. pwszSubRoot - The subdirectory where the creation sequence
  284. will start.
  285. Return Value:
  286. Success: S_OK;
  287. Failure: various error codes.
  288. Notes:
  289. We actually don't change pwszPath. But we will temporarily
  290. modify the buffer during our operation, but upon returning,
  291. the buffer is fully restored to the original value.
  292. --*/
  293. {
  294. if (pwszPath == NULL || *pwszPath == L'\0')
  295. {
  296. return E_INVALIDARG;
  297. }
  298. HRESULT hr = S_OK;
  299. LPCWSTR pwszCurrReadHead = pwszPath;
  300. if (pwszSubRoot != NULL && *pwszSubRoot != L'\0')
  301. {
  302. pwszCurrReadHead = ::wcsstr(pwszPath, pwszSubRoot);
  303. //
  304. // if you specify a subroot, then it must exists in the path
  305. //
  306. if (pwszCurrReadHead == NULL)
  307. {
  308. return E_INVALIDARG;
  309. }
  310. }
  311. LPWSTR pwszNextReadHead = ::wcsstr(pwszCurrReadHead, L"\\");
  312. //
  313. // will try to create all subdirectories under SSR
  314. //
  315. while (true)
  316. {
  317. //
  318. // Temporarily zero terminate it so that we can try
  319. // to create the directory
  320. //
  321. if (pwszNextReadHead != NULL)
  322. {
  323. *pwszNextReadHead = L'\0';
  324. }
  325. if (!::CreateDirectory(pwszPath, NULL))
  326. {
  327. DWORD dwError = GetLastError();
  328. if (dwError == ERROR_ALREADY_EXISTS)
  329. {
  330. hr = S_OK;
  331. }
  332. else
  333. {
  334. hr = HRESULT_FROM_WIN32(dwError);
  335. //
  336. // log the directory that failed to create
  337. //
  338. g_fblog.LogFeedback(SSR_FB_ERROR_GENERIC | FBLog_Log,
  339. hr,
  340. pwszPath,
  341. IDS_FAIL_CREATE_DIRECTORY
  342. );
  343. break;
  344. }
  345. }
  346. //
  347. // if we don't have any more backslash, then it's over
  348. //
  349. if (pwszNextReadHead == NULL)
  350. {
  351. break;
  352. }
  353. //
  354. // Restore the backslash
  355. //
  356. *pwszNextReadHead = L'\\';
  357. pwszNextReadHead = ::wcsstr(pwszNextReadHead + 1, L"\\");
  358. }
  359. return hr;
  360. }
  361. HRESULT
  362. SsrPLoadDOM (
  363. BSTR bstrFile, // [in],
  364. LONG lFlag, // [in],
  365. IXMLDOMDocument2 * pDOM // [in]
  366. )
  367. /*++
  368. Routine Description:
  369. Functionality:
  370. Do the XML DOM loading
  371. Virtual:
  372. n/a.
  373. Arguments:
  374. bstrFile- the XML/XSL file path
  375. uFlag - The flag that determines the transformation characteristics.
  376. The one we use is SSR_LOADDOM_VALIDATE_ON_PARSE.
  377. pDOM - The IXMLDOMDocument2 object interface.
  378. Return Value:
  379. Success:
  380. various success codes returned from DOM or ourselves.
  381. Use SUCCEEDED(hr) to test.
  382. Failure:
  383. various error codes returned from DOM or ourselves.
  384. Use FAILED(hr) to test.
  385. Notes:
  386. --*/
  387. {
  388. USES_CONVERSION;
  389. HRESULT hr = S_OK;
  390. if ( NULL == pDOM) {
  391. return E_INVALIDARG;
  392. }
  393. //
  394. // set the validateOnParse property
  395. //
  396. if (lFlag & SSR_LOADDOM_VALIDATE_ON_PARSE)
  397. {
  398. hr = pDOM->put_validateOnParse(VARIANT_TRUE);
  399. }
  400. else
  401. {
  402. hr = pDOM->put_validateOnParse(VARIANT_FALSE);
  403. }
  404. if (FAILED(hr))
  405. {
  406. g_fblog.LogFeedback(SSR_FB_ERROR_LOAD_MEMBER | FBLog_Log,
  407. hr,
  408. L"put_validateOnParse",
  409. IDS_DOM_PROPERTY_PUT_FAILED
  410. );
  411. }
  412. CComVariant varInput(bstrFile);
  413. //
  414. // we should try to see what happens if we set it to VARIANT_TRUE
  415. //
  416. VARIANT_BOOL fSuccess;
  417. hr = pDOM->load(varInput, &fSuccess);
  418. if (fSuccess == VARIANT_FALSE)
  419. {
  420. //
  421. // somehow it fails, we want to figure out what is going on,
  422. // potential parsing errors
  423. //
  424. CComPtr<IXMLDOMParseError> srpParseError;
  425. //
  426. // in case of any failure, we will use the bstrReason
  427. // to log and feedback.
  428. //
  429. CComBSTR bstrReason;
  430. long ulLine = 0, ulColumn = 0, ulCode = 0;
  431. //
  432. // if any of the following fails, there is nothing we can do
  433. // other than logging the error.
  434. //
  435. hr = pDOM->get_parseError(&srpParseError);
  436. if (FAILED(hr))
  437. {
  438. bstrReason = L"SsrPLoadDOM failed on pDOM->get_parseError.";
  439. }
  440. else
  441. {
  442. hr = srpParseError->get_reason(&bstrReason);
  443. if (FAILED(hr))
  444. {
  445. bstrReason = L"SsrPLoadDOM failed on srpParseError->get_reason.";
  446. }
  447. else
  448. {
  449. hr = srpParseError->get_errorCode(&ulCode);
  450. if (FAILED(hr))
  451. {
  452. bstrReason = L"SsrPLoadDOM failed on srpParseError->get_errorCode.";
  453. }
  454. hr = srpParseError->get_line(&ulLine);
  455. if (FAILED(hr))
  456. {
  457. bstrReason = L"SsrPLoadDOM failed on srpParseError->get_line.";
  458. }
  459. }
  460. }
  461. const ULONG uHexMaxLen = 8;
  462. const ULONG uDecMaxLen = 16;
  463. LPWSTR pwszError = NULL;
  464. //
  465. // we can't continue creating more specific error info
  466. // if we fail to get the reason - which may include out-of-memory
  467. // system errors. We don't bother to modify our error to
  468. // out-of-memory because we are guessing in that case and also
  469. // others will catch that error fairly quickly.
  470. //
  471. if (SUCCEEDED(hr) && bstrReason != NULL && ulLine != 0)
  472. {
  473. //
  474. // It's a parsing error
  475. //
  476. srpParseError->get_linepos(&ulColumn);
  477. CComBSTR bstrFmt;
  478. if (SUCCEEDED(bstrFmt.LoadString(IDS_XML_PARSING_ERROR)))
  479. {
  480. ULONG uTotLen = bstrFmt.Length() +
  481. uHexMaxLen +
  482. uDecMaxLen +
  483. ::wcslen(bstrReason) +
  484. ::wcslen(bstrFile) +
  485. uDecMaxLen + 1;
  486. pwszError = new WCHAR[uTotLen];
  487. if (pwszError == NULL)
  488. {
  489. hr = E_OUTOFMEMORY;
  490. }
  491. else
  492. {
  493. _snwprintf( pwszError,
  494. uTotLen,
  495. bstrFmt,
  496. ulCode,
  497. ulLine,
  498. bstrReason,
  499. bstrFile,
  500. ulColumn
  501. );
  502. }
  503. }
  504. }
  505. else
  506. {
  507. if ((HRESULT) ulCode == INET_E_OBJECT_NOT_FOUND)
  508. {
  509. g_fblog.LogString(IDS_OBJECT_NOT_FOUND, bstrFile);
  510. }
  511. }
  512. //
  513. // loading DOM failure is critical, do both logging and feedback
  514. //
  515. g_fblog.LogFeedback(SSR_FB_ERROR_MEMBER_XML | FBLog_Log,
  516. bstrFile,
  517. ((pwszError != NULL) ? pwszError : bstrReason),
  518. IDS_DOM_LOAD_FAILED
  519. );
  520. delete [] pwszError;
  521. //
  522. // I have seen the HRESULT code being a success code while
  523. // it can't transform fSuccess == VARIANT_FALSE
  524. //
  525. if (SUCCEEDED(hr))
  526. {
  527. hr = E_SSR_INVALID_XML_FILE;
  528. }
  529. }
  530. return hr;
  531. }
  532. HRESULT
  533. SsrPGetBSTRAttrValue (
  534. IN IXMLDOMNamedNodeMap * pNodeMap,
  535. IN BSTR bstrName,
  536. OUT BSTR * pbstrValue
  537. )
  538. /*++
  539. Routine Description:
  540. Functionality:
  541. A helper function to get string attribute values
  542. Virtual:
  543. N/A.
  544. Arguments:
  545. pNodeMap - The map of attributes
  546. bstrName - The name of the attribute
  547. pbstrValue - Receives the string value.
  548. Return Value:
  549. S_OK if succeeded.
  550. Various error codes. Watch out for E_SSR_MISSING_STRING_ATTRIBUTE
  551. because if it is an optional attribute, then we should allow
  552. this failure.
  553. Notes:
  554. --*/
  555. {
  556. if (pNodeMap == NULL || pbstrValue == NULL)
  557. {
  558. return E_INVALIDARG;
  559. }
  560. *pbstrValue = NULL;
  561. CComPtr<IXMLDOMNode> srpAttr;
  562. CComVariant varValue;
  563. HRESULT hr = pNodeMap->getNamedItem(bstrName, &srpAttr);
  564. if (SUCCEEDED(hr) && srpAttr != NULL)
  565. {
  566. hr = srpAttr->get_nodeValue(&varValue);
  567. }
  568. if (SUCCEEDED(hr) && varValue.vt == VT_BSTR)
  569. {
  570. *pbstrValue = varValue.bstrVal;
  571. //
  572. // detach the bstr value so that we can reuse the variant
  573. //
  574. varValue.vt = VT_EMPTY;
  575. varValue.bstrVal = NULL;
  576. }
  577. else if (varValue.vt != VT_BSTR)
  578. {
  579. hr = E_SSR_MISSING_STRING_ATTRIBUTE;
  580. }
  581. return hr;
  582. }
  583. HRESULT
  584. SsrPCreateUniqueTempDirectory (
  585. OUT LPWSTR pwszTempDirPath,
  586. IN DWORD dwBufLen
  587. )
  588. /*++
  589. Routine Description:
  590. Functionality:
  591. Will create a unique (guid) temporary directory under ssr root
  592. Virtual:
  593. No.
  594. Arguments:
  595. pwszTempDirPath - The path of the temporary directory
  596. dwBufLen - The buffer length in WCHAR counts
  597. Return Value:
  598. succeess: S_OK
  599. failure: various error codes
  600. Notes:
  601. --*/
  602. {
  603. //
  604. // we need the ssr root, the backslash and the guid (36 wchars) and 0 terminator
  605. //
  606. if (dwBufLen < g_dwSsrRootLen + 1 + g_lGuidStringLen + 1)
  607. {
  608. return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  609. }
  610. WCHAR wszGuid[g_lGuidStringLen + 1];
  611. GUID guid;
  612. memset(&guid, 0, sizeof(GUID));
  613. memset(wszGuid, 0, sizeof(WCHAR) * (g_lGuidStringLen + 1) );
  614. HRESULT hr = ::CoCreateGuid(&guid);
  615. if (S_OK == hr)
  616. {
  617. ::StringFromGUID2(guid, wszGuid, g_lGuidStringLen + 1);
  618. memcpy(pwszTempDirPath, g_wszSsrRoot, g_dwSsrRootLen * sizeof(WCHAR));
  619. pwszTempDirPath[g_dwSsrRootLen] = L'\\';
  620. //
  621. // skip the starting '{', and do not copy '}' either.
  622. //
  623. memcpy(pwszTempDirPath + g_dwSsrRootLen + 1,
  624. wszGuid + 1,
  625. (g_lGuidStringLen - 2) * sizeof(WCHAR)
  626. );
  627. //
  628. // NULL terminate it
  629. //
  630. pwszTempDirPath[g_dwSsrRootLen + g_lGuidStringLen - 1] = L'\0';
  631. if (!CreateDirectory(pwszTempDirPath, NULL))
  632. {
  633. hr = HRESULT_FROM_WIN32(GetLastError());
  634. }
  635. }
  636. return hr;
  637. }
  638. HRESULT
  639. SsrPMoveFiles (
  640. IN LPCWSTR pwszSrcDirRoot,
  641. IN LPCWSTR pwszDesDirRoot,
  642. IN LPCWSTR pwszRelPath
  643. )
  644. /*++
  645. Routine Description:
  646. Functionality:
  647. Will move a file given by the relative path of the src directory
  648. to the destination directory of the same relative path
  649. Virtual:
  650. No.
  651. Arguments:
  652. pwszSrcDirRoot - The src directory root path. Combined with the
  653. pwszRelPath, it becomes the full path of the src file
  654. pwszDesDirRoot - The dest directory root path. Combined with the pwszRelPath,
  655. it becomes the full path of the destination file.
  656. pwszRelPath - the file path relative to the src directory root.
  657. Return Value:
  658. Success: S_OK.
  659. Failure: various error codes.
  660. Notes:
  661. If the destination directory doesn't exist, then we will create it
  662. --*/
  663. {
  664. HRESULT hr = S_OK;
  665. //
  666. // first, we must the source and destination files paths
  667. //
  668. DWORD dwSrcRootLen = wcslen(pwszSrcDirRoot);
  669. DWORD dwDesRootLen = wcslen(pwszDesDirRoot);
  670. DWORD dwRelPathLen = wcslen(pwszRelPath);
  671. LPWSTR pwszSrcPath = new WCHAR[dwSrcRootLen + 1 + dwRelPathLen + 1];
  672. LPWSTR pwszDesPath = new WCHAR[dwDesRootLen + 1 + dwRelPathLen + 1];
  673. if (pwszSrcPath != NULL && pwszDesPath != NULL)
  674. {
  675. ::memcpy(pwszSrcPath, pwszSrcDirRoot, sizeof(WCHAR) * dwSrcRootLen);
  676. pwszSrcPath[dwSrcRootLen] = L'\\';
  677. //
  678. // copy one WCHAR more then length so that the 0 terminator is set
  679. //
  680. ::memcpy(pwszSrcPath + dwSrcRootLen + 1,
  681. pwszRelPath, sizeof(WCHAR) * (dwRelPathLen + 1));
  682. ::memcpy(pwszDesPath, pwszDesDirRoot, sizeof(WCHAR) * dwDesRootLen);
  683. pwszDesPath[dwDesRootLen] = L'\\';
  684. ::memcpy(pwszDesPath + dwDesRootLen + 1,
  685. pwszRelPath, sizeof(WCHAR) * (dwRelPathLen + 1));
  686. if (!::MoveFile(pwszSrcPath, pwszDesPath))
  687. {
  688. DWORD dwError = GetLastError();
  689. if (ERROR_FILE_NOT_FOUND != dwError)
  690. {
  691. hr = HRESULT_FROM_WIN32(dwError);
  692. }
  693. //
  694. // log the file name that fails to move
  695. //
  696. g_fblog.LogFeedback(SSR_FB_ERROR_GENERIC | FBLog_Log,
  697. dwError,
  698. pwszSrcPath,
  699. IDS_FAIL_MOVE_FILE
  700. );
  701. }
  702. }
  703. else
  704. {
  705. hr = E_OUTOFMEMORY;
  706. }
  707. delete [] pwszSrcPath;
  708. delete [] pwszDesPath;
  709. return hr;
  710. }
  711. bool SsrPPressOn (
  712. IN SsrActionVerb lActionVerb,
  713. IN LONG lActionType,
  714. IN HRESULT hr
  715. )
  716. /*++
  717. Routine Description:
  718. Functionality:
  719. Determines if we should continue based on the error
  720. Virtual:
  721. No.
  722. Arguments:
  723. lActionVerb - The action
  724. lActionType - The type of the action
  725. hr - The HRESULT to test
  726. Return Value:
  727. true or false
  728. Notes:
  729. This function is just a placeholder for the need of the test. The implementation
  730. is far from complete.
  731. --*/
  732. {
  733. UNREFERENCED_PARAMETER(lActionVerb);
  734. UNREFERENCED_PARAMETER(lActionType);
  735. if (hr == E_OUTOFMEMORY ||
  736. hr == E_SSR_MEMBER_XSD_INVALID)
  737. {
  738. return false;
  739. }
  740. return true;
  741. }
  742. const BSTR
  743. SsrPGetDirectory (
  744. IN SsrActionVerb lActionVerb,
  745. IN BOOL bScriptFile
  746. )
  747. /*++
  748. Routine Description:
  749. Functionality:
  750. SSR controls the physical location for its members to place their files.
  751. This function returns to the caller the physical directory path for a given
  752. member. Since SSR is an action oriented architecture, such locations are also
  753. relative to action. If bstrActionVerb is a non-empty string, then the function
  754. retrieves the loction for that action. Otherwise, the function retrieves the
  755. location for the member's root (actions are sub-directories of this root)
  756. Virtual:
  757. No.
  758. Arguments:
  759. lActionVerb - The action verb in long format
  760. bScriptFile - Whether or not it is asking for a script file. If false,
  761. it is asking for transformation file
  762. Return Value:
  763. the file path if we recognize the call.
  764. Notes:
  765. !!!Warning!!!
  766. Caller should never release the BSTR
  767. --*/
  768. {
  769. if (!bScriptFile)
  770. {
  771. //
  772. // asking for transformation files. All of them goes to
  773. // the TransformFiles directory
  774. //
  775. return g_bstrTransformFilesDir;
  776. }
  777. if (lActionVerb == ActionConfigure)
  778. {
  779. return g_bstrConfigureFilesDir;
  780. }
  781. else if (lActionVerb == ActionRollback)
  782. {
  783. return g_bstrRollbackFilesDir;
  784. }
  785. else if (lActionVerb == ActionReport)
  786. {
  787. return g_bstrReportFilesDir;
  788. }
  789. else
  790. {
  791. return NULL;
  792. }
  793. }
  794. HRESULT
  795. SsrPDoDCOMSettings (
  796. bool bReg
  797. )
  798. /*++
  799. Routine Description:
  800. Functionality:
  801. This function will set the security related registry settings for our
  802. SSR engine com objects
  803. Virtual:
  804. No.
  805. Arguments:
  806. bReg - whether this is to register or to un-register
  807. Return Value:
  808. S_OK if succeeded.
  809. Otherwise, various error codes
  810. Notes:
  811. --*/
  812. {
  813. HRESULT hr = S_OK;
  814. PSECURITY_DESCRIPTOR pSD = NULL;
  815. BOOL bDaclPresent = FALSE, bDaclDefault = FALSE;
  816. ULONG ulSDSize = 0;
  817. return 0;
  818. /*
  819. if (bReg)
  820. {
  821. if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
  822. g_pwszSsrDCOMSecDescripACL,
  823. SDDL_REVISION_1,
  824. &pSD,
  825. &ulSDSize
  826. ) )
  827. {
  828. return HRESULT_FROM_WIN32(GetLastError());
  829. }
  830. }
  831. else
  832. {
  833. //
  834. // unregister, easy, just delete the AppID key
  835. //
  836. LONG lStatus = RegDeleteKey(HKEY_LOCAL_MACHINE,
  837. g_pwszAppID);
  838. if ( lStatus != NO_ERROR )
  839. {
  840. hr = HRESULT_FROM_WIN32(GetLastError());
  841. }
  842. return hr;
  843. }
  844. if (SUCCEEDED(hr))
  845. {
  846. //
  847. // now let's set the ACLs on these keys
  848. //
  849. HKEY hKey = NULL;
  850. BYTE * lpData = (BYTE*)pSD;
  851. DWORD dwDataSize = ulSDSize;
  852. if (FAILED(hr))
  853. {
  854. return hr;
  855. }
  856. LONG lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  857. g_pwszAppID,
  858. 0,
  859. KEY_WRITE,
  860. &hKey );
  861. if ( lStatus != NO_ERROR )
  862. {
  863. hr = HRESULT_FROM_WIN32(GetLastError());
  864. }
  865. else
  866. {
  867. //
  868. // set the access
  869. //
  870. lStatus = RegSetValueEx(
  871. hKey,
  872. g_pwszAccessPermission,
  873. 0,
  874. REG_BINARY,
  875. lpData,
  876. dwDataSize
  877. );
  878. if ( lStatus == NO_ERROR )
  879. {
  880. //
  881. // set the launch permission
  882. //
  883. lStatus = RegSetValueEx(
  884. hKey,
  885. g_pwszLaunchPermission,
  886. 0,
  887. REG_BINARY,
  888. lpData,
  889. dwDataSize
  890. );
  891. }
  892. if ( lStatus != NO_ERROR )
  893. {
  894. hr = HRESULT_FROM_WIN32(GetLastError());
  895. }
  896. RegCloseKey(hKey);
  897. }
  898. }
  899. if (pSD != NULL)
  900. {
  901. LocalFree(pSD);
  902. }
  903. return hr;
  904. */}