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.

1069 lines
34 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File Name: fxocFile.cpp
  4. //
  5. // Abstract: This provides the file/directory routines used in the
  6. // FaxOCM code base.
  7. //
  8. // Environment: Windows XP / User Mode
  9. //
  10. // Copyright (c) 2000 Microsoft Corporation
  11. //
  12. // Revision History:
  13. //
  14. // Date: Developer: Comments:
  15. // ----- ---------- ---------
  16. // 21-Mar-2000 Oren Rosenbloom (orenr) Created
  17. //////////////////////////////////////////////////////////////////////////////
  18. #include "faxocm.h"
  19. #pragma hdrstop
  20. #include <aclapi.h>
  21. #define MAX_NUM_CHARS_INF_VALUE 255
  22. //////////////////////// Static Function Prototypes //////////////////////////
  23. static BOOL prv_ProcessDirectories(const TCHAR *pszSection,const TCHAR *pszDirAction);
  24. static BOOL prv_ProcessShares(const TCHAR *pszSection,const TCHAR *pszShareAction);
  25. static BOOL prv_SetFileSecurity(const FAX_FOLDER_Description& ffdFolder);
  26. static DWORD prv_DoSetup(const TCHAR *pszSection,
  27. BOOL bInstall,
  28. const TCHAR *pszFnName,
  29. HINF hInf,
  30. const TCHAR *pszSourceRootPath,
  31. HSPFILEQ hQueue,
  32. DWORD dwFlags);
  33. FAX_SHARE_Description::FAX_SHARE_Description()
  34. : iPlatform(PRODUCT_SKU_UNKNOWN),
  35. pSD(NULL)
  36. {
  37. }
  38. FAX_SHARE_Description::~FAX_SHARE_Description()
  39. {
  40. if (pSD)
  41. {
  42. LocalFree(pSD);
  43. }
  44. }
  45. FAX_FOLDER_Description::FAX_FOLDER_Description()
  46. : iPlatform(PRODUCT_SKU_UNKNOWN),
  47. pSD(NULL),
  48. iAttributes(FILE_ATTRIBUTE_NORMAL)
  49. {
  50. }
  51. FAX_FOLDER_Description::~FAX_FOLDER_Description()
  52. {
  53. if (pSD)
  54. {
  55. LocalFree(pSD);
  56. }
  57. }
  58. ///////////////////////////////
  59. // fxocFile_Init
  60. //
  61. // Initialize this File queuing
  62. // subsystem
  63. //
  64. // Params:
  65. // - void
  66. // Returns:
  67. // - NO_ERROR on success
  68. // - error code otherwise.
  69. //
  70. DWORD fxocFile_Init(void)
  71. {
  72. DWORD dwRes = NO_ERROR;
  73. DBG_ENTER(_T("Init File Module"), dwRes);
  74. return dwRes;
  75. }
  76. ///////////////////////////////
  77. // fxocFile_Term
  78. //
  79. // Terminate this file queuing subsystem.
  80. //
  81. // Params:
  82. // - void.
  83. // Returns:
  84. // - NO_ERROR on success
  85. // - error code otherwise.
  86. //
  87. DWORD fxocFile_Term(void)
  88. {
  89. DWORD dwRes = NO_ERROR;
  90. DBG_ENTER(_T("Term File Module"), dwRes);
  91. return dwRes;
  92. }
  93. ///////////////////////////////
  94. // fxocFile_Install
  95. //
  96. // Installs files listed in
  97. // the INF setup file into their
  98. // specified location.
  99. //
  100. // Params:
  101. // - pszSubcomponentId
  102. // - pszInstallSection - install section in INF file (e.g. Fax.CleanInstall)
  103. // Returns:
  104. // - NO_ERROR on success.
  105. // - error code otherwise.
  106. //
  107. DWORD fxocFile_Install(const TCHAR *pszSubcomponentId,
  108. const TCHAR *pszInstallSection)
  109. {
  110. HINF hInf = NULL;
  111. HSPFILEQ hQueue = NULL;
  112. DWORD dwReturn = NO_ERROR;
  113. BOOL bSuccess = FALSE;
  114. DBG_ENTER( _T("fxocFile_Install"),
  115. dwReturn,
  116. _T("%s - %s"),
  117. pszSubcomponentId,
  118. pszInstallSection);
  119. if (pszInstallSection == NULL)
  120. {
  121. return ERROR_INVALID_PARAMETER;
  122. }
  123. // get the INF handle for our component inf file
  124. hInf = faxocm_GetComponentInf();
  125. // get the file queue handle
  126. hQueue = faxocm_GetComponentFileQueue();
  127. // unregister DLLs first, before a file might be deleted by the file copy below.
  128. if (::SetupInstallFromInfSection(NULL,hInf,pszInstallSection,SPINST_UNREGSVR,NULL,NULL,0,NULL,NULL,NULL,NULL))
  129. {
  130. VERBOSE(DBG_MSG,
  131. _T("Successfully processed SPINST_UNREGSVR from INF file, section '%s'"),
  132. pszInstallSection);
  133. }
  134. else
  135. {
  136. dwReturn = GetLastError();
  137. VERBOSE(SETUP_ERR,
  138. _T("Failed to process SPINST_UNREGSVR, section '%s', dwReturn = 0x%lx"),
  139. pszInstallSection,
  140. dwReturn);
  141. }
  142. // unregister platform specific DLLs first - this can happen during an upgrade from XP Beta -> XP RC1 and XP RTM
  143. dwReturn = fxocUtil_SearchAndExecute(pszInstallSection,INF_KEYWORD_UNREGISTER_DLL_PLATFORM,SPINST_UNREGSVR,NULL);
  144. if (dwReturn == NO_ERROR)
  145. {
  146. VERBOSE(DBG_MSG,
  147. _T("Successfully Unregistered Fax DLLs - platform dependent")
  148. _T("from INF file, section '%s'"),
  149. pszInstallSection);
  150. }
  151. else
  152. {
  153. VERBOSE(SETUP_ERR,
  154. _T("Failed to Unregister Fax DLLs - platform dependent")
  155. _T("from INF file, section '%s', dwReturn = 0x%lx"),
  156. pszInstallSection,
  157. dwReturn);
  158. }
  159. dwReturn = prv_DoSetup(pszInstallSection,
  160. TRUE,
  161. _T("fxocFile_Install"),
  162. hInf,
  163. NULL,
  164. hQueue,
  165. SP_COPY_NEWER);
  166. // now attemp to install platform specific files
  167. dwReturn = fxocUtil_SearchAndExecute(pszInstallSection,INF_KEYWORD_COPYFILES_PLATFORM,SP_COPY_NEWER,hQueue);
  168. if (dwReturn == NO_ERROR)
  169. {
  170. VERBOSE(DBG_MSG,
  171. _T("Successfully Queued Files - platform dependent")
  172. _T("from INF file, section '%s'"),
  173. pszInstallSection);
  174. }
  175. else
  176. {
  177. VERBOSE(SETUP_ERR,
  178. _T("Failed to Queued Files - platform dependent")
  179. _T("from INF file, section '%s', dwReturn = 0x%lx"),
  180. pszInstallSection,
  181. dwReturn);
  182. }
  183. return dwReturn;
  184. }
  185. ///////////////////////////////
  186. // fxocFile_Uninstall
  187. //
  188. // Uninstalls files listed in
  189. // the INF setup file.
  190. //
  191. // Params:
  192. // - pszSubcomponentId
  193. // - pszUninstallSection - section in INF (e.g. Fax.Uninstall)
  194. // Returns:
  195. // - NO_ERROR on success.
  196. // - error code otherwise.
  197. //
  198. DWORD fxocFile_Uninstall(const TCHAR *pszSubcomponentId,
  199. const TCHAR *pszUninstallSection)
  200. {
  201. HINF hInf = NULL;
  202. HSPFILEQ hQueue = NULL;
  203. DWORD dwReturn = NO_ERROR;
  204. BOOL bSuccess = FALSE;
  205. DBG_ENTER( _T("fxocFile_Install"),
  206. dwReturn,
  207. _T("%s - %s"),
  208. pszSubcomponentId,
  209. pszUninstallSection);
  210. if (pszUninstallSection == NULL)
  211. {
  212. return ERROR_INVALID_PARAMETER;
  213. }
  214. // get the INF handle for our component inf file
  215. hInf = faxocm_GetComponentInf();
  216. // get the file queue handle
  217. hQueue = faxocm_GetComponentFileQueue();
  218. // unregister all our DLLs first
  219. if (::SetupInstallFromInfSection(NULL,hInf,pszUninstallSection,SPINST_UNREGSVR,NULL,NULL,0,NULL,NULL,NULL,NULL))
  220. {
  221. VERBOSE(DBG_MSG,
  222. _T("Successfully processed SPINST_UNREGSVR from INF file, section '%s'"),
  223. pszUninstallSection);
  224. }
  225. else
  226. {
  227. dwReturn = GetLastError();
  228. VERBOSE(SETUP_ERR,
  229. _T("Failed to process SPINST_UNREGSVR, section '%s', dwReturn = 0x%lx"),
  230. pszUninstallSection,
  231. dwReturn);
  232. }
  233. // Now delete the files.
  234. // this function will uninstall if the section retrieved above
  235. // contains the 'DelFiles' keyword.
  236. dwReturn = prv_DoSetup(pszUninstallSection,
  237. FALSE,
  238. _T("fxocFile_Uninstall"),
  239. hInf,
  240. NULL,
  241. hQueue,
  242. 0);
  243. return dwReturn;
  244. }
  245. ///////////////////////////////
  246. // prv_DoSetup
  247. //
  248. // Generic routine to call the appropriate
  249. // Setup API fn, depending on if we are installing
  250. // or uninstalling.
  251. //
  252. // Params:
  253. // - pszSection - section we are processing
  254. // - bInstall - TRUE if installing, FALSE if uninstalling
  255. // - pszFnName - name of calling fn (for debug)
  256. // - hInf - handle to faxsetup.inf.
  257. // - pszSourceRootPath - path we are installing from.
  258. // - hQueue - handle to file queue given to us by OC Manager
  259. // - dwFlags - flags to pass to setup API.
  260. // Returns:
  261. // - NO_ERROR on success.
  262. // - error code otherwise.
  263. //
  264. static DWORD prv_DoSetup(const TCHAR *pszSection,
  265. BOOL bInstall,
  266. const TCHAR *pszFnName,
  267. HINF hInf,
  268. const TCHAR *pszSourceRootPath,
  269. HSPFILEQ hQueue,
  270. DWORD dwFlags)
  271. {
  272. DWORD dwReturn = NO_ERROR;
  273. BOOL bSuccess = FALSE;
  274. DBG_ENTER( _T("prv_DoSetup"),
  275. dwReturn,
  276. _T("%s - %s - %s"),
  277. pszSection,
  278. pszFnName,
  279. pszSourceRootPath);
  280. // this function will search the INF for the 'CopyFiles' keyword
  281. // and copy all files referenced by it.
  282. bSuccess = ::SetupInstallFilesFromInfSection(hInf,
  283. NULL,
  284. hQueue,
  285. pszSection,
  286. pszSourceRootPath,
  287. dwFlags);
  288. if (bSuccess)
  289. {
  290. VERBOSE(DBG_MSG,
  291. _T("%s, Successfully queued files ")
  292. _T("from Section: '%s'"),
  293. pszFnName,
  294. pszSection);
  295. }
  296. else
  297. {
  298. dwReturn = GetLastError();
  299. VERBOSE(DBG_MSG,
  300. _T("%s, Failed to queue files ")
  301. _T("from Section: '%s', Error Code = 0x%lx"),
  302. pszFnName,
  303. pszSection,
  304. dwReturn);
  305. }
  306. return dwReturn;
  307. }
  308. ///////////////////////////////
  309. // fxocFile_CalcDiskSpace
  310. //
  311. // Calculate the disk space requirements
  312. // of fax. This is done by the Setup APIs
  313. // based on the files we are copying and
  314. // deleting as specified in faxsetup.inf.
  315. //
  316. // Params:
  317. // - pszSubcomponentId
  318. // - bIsBeingAdded - are we installing or uninstalling.
  319. // - hDiskSpace - handle to diskspace abstraction.
  320. // Returns:
  321. // - NO_ERROR on success.
  322. // - error code otherwise
  323. //
  324. DWORD fxocFile_CalcDiskSpace(const TCHAR *pszSubcomponentId,
  325. BOOL bIsBeingAdded,
  326. HDSKSPC hDiskSpace)
  327. {
  328. HINF hInf = faxocm_GetComponentInf();
  329. DWORD dwReturn = NO_ERROR;
  330. BOOL bSuccess = FALSE;
  331. TCHAR szSectionToProcess[255 + 1];
  332. DBG_ENTER( _T("fxocFile_CalcDiskSpace"),
  333. dwReturn,
  334. _T("%s"),
  335. pszSubcomponentId);
  336. if ((hInf == NULL) ||
  337. (pszSubcomponentId == NULL))
  338. {
  339. return ERROR_INVALID_PARAMETER;
  340. }
  341. // since disk space calc needs to be consistent, select the clean install
  342. // section for the disk space calculation section. This is a good
  343. // estimate.
  344. if (dwReturn == NO_ERROR)
  345. {
  346. dwReturn = fxocUtil_GetKeywordValue(pszSubcomponentId,
  347. INF_KEYWORD_INSTALLTYPE_CLEAN,
  348. szSectionToProcess,
  349. sizeof(szSectionToProcess) / sizeof(TCHAR));
  350. }
  351. if (dwReturn == NO_ERROR)
  352. {
  353. if (bIsBeingAdded)
  354. {
  355. bSuccess = ::SetupAddInstallSectionToDiskSpaceList(
  356. hDiskSpace,
  357. hInf,
  358. NULL,
  359. szSectionToProcess,
  360. 0,
  361. 0);
  362. }
  363. else
  364. {
  365. bSuccess = ::SetupRemoveInstallSectionFromDiskSpaceList(
  366. hDiskSpace,
  367. hInf,
  368. NULL,
  369. szSectionToProcess,
  370. 0,
  371. 0);
  372. }
  373. if (!bSuccess)
  374. {
  375. dwReturn = GetLastError();
  376. VERBOSE(SETUP_ERR,
  377. _T("fxocFile_CalcDiskSpace, failed to calculate ")
  378. _T("disk space, error code = 0x%lx"), dwReturn);
  379. }
  380. else
  381. {
  382. VERBOSE(DBG_MSG,
  383. _T("fxocFile_CalcDiskSpace, ")
  384. _T("SubComponentID: '%s', Section: '%s', ")
  385. _T("bIsBeingAdded: '%lu', ")
  386. _T("rc=0x%lx"), pszSubcomponentId, szSectionToProcess,
  387. bIsBeingAdded,
  388. dwReturn);
  389. }
  390. }
  391. return dwReturn;
  392. }
  393. ///////////////////////////////
  394. // fxocFile_ProcessDirectories
  395. //
  396. // Create or Delete the directories
  397. // in the given section,
  398. //
  399. // pszINFKeyword - INF_KEYWORD_DELDIR to delete the directories
  400. // INF_KEYWORD_CREATEDIR to create the directories
  401. //
  402. DWORD fxocFile_ProcessDirectories(const TCHAR *pszSection, LPCTSTR pszINFKeyword)
  403. {
  404. DWORD dwReturn = NO_ERROR;
  405. DBG_ENTER( _T("fxocFile_ProcessDirectories"),
  406. dwReturn,
  407. _T("%s"),
  408. pszSection);
  409. // delete or create (according to pszINFKeyword) all the shares specified in the
  410. // INF section.
  411. if (!prv_ProcessDirectories(pszSection,pszINFKeyword))
  412. {
  413. dwReturn = GetLastError();
  414. VERBOSE(DBG_WARNING,_T("Problems deleting/creating directories.... [%s]"),pszINFKeyword);
  415. }
  416. return dwReturn;
  417. }
  418. ///////////////////////////////
  419. // fxocFile_ProcessShares
  420. //
  421. // Create and/or Delete shares
  422. // directories/printers specfiied
  423. // in the given section.
  424. //
  425. // Params:
  426. // - pszSection - section containing the 'CreateShare'/'DelShare'
  427. // keyword
  428. // Returns:
  429. // - NO_ERROR on success.
  430. // - error code otherwise.
  431. //
  432. DWORD fxocFile_ProcessShares(const TCHAR *pszSection)
  433. {
  434. DWORD dwReturn = NO_ERROR;
  435. DBG_ENTER( _T("fxocFile_ProcessShares"),
  436. dwReturn,
  437. _T("%s"),
  438. pszSection);
  439. // first, delete all the shares specified in the
  440. // INF section.
  441. if (!prv_ProcessShares(pszSection,INF_KEYWORD_DELSHARE))
  442. {
  443. VERBOSE(DBG_WARNING,_T("Problems deleting shares...."));
  444. }
  445. // next, create all the shares specified in the
  446. // INF section.
  447. if (!prv_ProcessShares(pszSection,INF_KEYWORD_CREATESHARE))
  448. {
  449. VERBOSE(DBG_WARNING,_T("Problems creating shares...."));
  450. }
  451. return dwReturn;
  452. }
  453. static BOOL prv_FillFolderDescriptionFromInf(const TCHAR *pszFolderSection,FAX_FOLDER_Description& fsdFolder)
  454. {
  455. INFCONTEXT Context;
  456. BOOL bSuccess = TRUE;
  457. HINF hInf = NULL;
  458. TCHAR szStringSd[MAX_PATH*3] = {0};
  459. DBG_ENTER( _T("prv_FillFolderDescriptionFromInf"),
  460. bSuccess,
  461. _T("%s"),
  462. pszFolderSection);
  463. hInf = faxocm_GetComponentInf();
  464. memset(&Context, 0, sizeof(Context));
  465. // get the Path line in the section.
  466. if (!::SetupFindFirstLine(hInf,pszFolderSection,INF_KEYWORD_PATH,&Context))
  467. {
  468. VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_PATH,GetLastError());
  469. return FALSE;
  470. }
  471. bSuccess = ::SetupGetStringField(&Context,1,fsdFolder.szPath,MAX_PATH,NULL);
  472. if (!bSuccess)
  473. {
  474. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PATH,GetLastError());
  475. return FALSE;
  476. }
  477. // get the Platform line in the section.
  478. if (!::SetupFindFirstLine(hInf,pszFolderSection,INF_KEYWORD_PLATFORM,&Context))
  479. {
  480. VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
  481. return FALSE;
  482. }
  483. bSuccess = ::SetupGetIntField(&Context, 1, &fsdFolder.iPlatform);
  484. if (!bSuccess)
  485. {
  486. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
  487. return FALSE;
  488. }
  489. // get the attributes line if it exists.
  490. if (::SetupFindFirstLine(hInf,pszFolderSection,INF_KEYWORD_ATTRIBUTES,&Context))
  491. {
  492. bSuccess = ::SetupGetIntField(&Context, 1, &fsdFolder.iAttributes);
  493. if (!bSuccess)
  494. {
  495. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
  496. return FALSE;
  497. }
  498. }
  499. else
  500. {
  501. VERBOSE( DBG_MSG,
  502. _T("SetupFindFirstLine failed (%s) (ec=%d), ")
  503. _T("this is an optional field assuming non-existant"),
  504. INF_KEYWORD_ATTRIBUTES,
  505. GetLastError());
  506. }
  507. // get the Security line in the section.
  508. if (!::SetupFindFirstLine(hInf,pszFolderSection,INF_KEYWORD_SECURITY,&Context))
  509. {
  510. VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_SECURITY,GetLastError());
  511. return FALSE;
  512. }
  513. bSuccess = ::SetupGetStringField(&Context,1,szStringSd,MAX_PATH,NULL);
  514. if (!bSuccess)
  515. {
  516. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_SECURITY,GetLastError());
  517. return FALSE;
  518. }
  519. if (!ConvertStringSecurityDescriptorToSecurityDescriptor(szStringSd,SDDL_REVISION_1,&fsdFolder.pSD,NULL))
  520. {
  521. VERBOSE(SETUP_ERR,_T("ConvertStringSecurityDescriptorToSecurityDescriptor failed (%s) (ec=%d)"),szStringSd,GetLastError());
  522. return FALSE;
  523. }
  524. return TRUE;
  525. }
  526. static BOOL prv_FillShareDescriptionFromInf(const TCHAR *pszShareSection,FAX_SHARE_Description& fsdShare)
  527. {
  528. INFCONTEXT Context;
  529. BOOL bSuccess = TRUE;
  530. HINF hInf = NULL;
  531. TCHAR szStringSd[MAX_PATH*3] = {0};
  532. DBG_ENTER( _T("prv_FillShareDescriptionFromInf"),
  533. bSuccess,
  534. _T("%s"),
  535. pszShareSection);
  536. hInf = faxocm_GetComponentInf();
  537. memset(&Context, 0, sizeof(Context));
  538. // get the Path line in the section.
  539. if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_PATH,&Context))
  540. {
  541. VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_PATH,GetLastError());
  542. return FALSE;
  543. }
  544. bSuccess = ::SetupGetStringField(&Context,1,fsdShare.szPath,MAX_PATH,NULL);
  545. if (!bSuccess)
  546. {
  547. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PATH,GetLastError());
  548. return FALSE;
  549. }
  550. // get the Name line in the section.
  551. if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_NAME,&Context))
  552. {
  553. VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_NAME,GetLastError());
  554. return FALSE;
  555. }
  556. bSuccess = ::SetupGetStringField(&Context,1,fsdShare.szName,MAX_PATH,NULL);
  557. if (!bSuccess)
  558. {
  559. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_NAME,GetLastError());
  560. return FALSE;
  561. }
  562. // get the Comment line in the section.
  563. if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_COMMENT,&Context))
  564. {
  565. VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_COMMENT,GetLastError());
  566. return FALSE;
  567. }
  568. bSuccess = ::SetupGetStringField(&Context,1,fsdShare.szComment,MAX_PATH,NULL);
  569. if (!bSuccess)
  570. {
  571. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_COMMENT,GetLastError());
  572. return FALSE;
  573. }
  574. // get the Platform line in the section.
  575. if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_PLATFORM,&Context))
  576. {
  577. VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
  578. return FALSE;
  579. }
  580. bSuccess = ::SetupGetIntField(&Context, 1, &fsdShare.iPlatform);
  581. if (!bSuccess)
  582. {
  583. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
  584. return FALSE;
  585. }
  586. // get the Security line in the section.
  587. if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_SECURITY,&Context))
  588. {
  589. VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_SECURITY,GetLastError());
  590. return FALSE;
  591. }
  592. bSuccess = ::SetupGetStringField(&Context,1,szStringSd,MAX_PATH,NULL);
  593. if (!bSuccess)
  594. {
  595. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_SECURITY,GetLastError());
  596. return FALSE;
  597. }
  598. if (!ConvertStringSecurityDescriptorToSecurityDescriptor(szStringSd,SDDL_REVISION_1,&fsdShare.pSD,NULL))
  599. {
  600. VERBOSE(SETUP_ERR,_T("ConvertStringSecurityDescriptorToSecurityDescriptor failed (%s) (ec=%d)"),szStringSd,GetLastError());
  601. return FALSE;
  602. }
  603. return TRUE;
  604. }
  605. ///////////////////////////////
  606. // prv_ProcessDirectories
  607. //
  608. // Enumerates through the specified
  609. // INF file in the specified section
  610. // and gets the value of the next
  611. // keyword 'CreateDir', or 'DelDir'
  612. //
  613. // This function looks for the following lines
  614. // in the INF section
  615. //
  616. // CreateDir = [1st dir section],[2nd dir section],...
  617. // or
  618. // DelDir = [1st dir section],[2nd dir section],...
  619. //
  620. // [dir section] - is built in the following format:
  621. // Path = <path to folder to create>
  622. // Platform = <one of the PRODUCT_SKU_* below>
  623. // Security = <DACL in string format>
  624. //
  625. // Params:
  626. // - pszSection - section in the file to iterate through.
  627. // - pszShareAction - one of INF_KEYWORD_CREATEDIR, INF_KEYWORD_DELDIR
  628. //
  629. // Returns:
  630. // - TRUE if folders were processed successfully
  631. // - FALSE otherwise
  632. //
  633. static BOOL prv_ProcessDirectories(const TCHAR *pszSection,const TCHAR *pszDirAction)
  634. {
  635. INFCONTEXT Context;
  636. BOOL bSuccess = TRUE;
  637. HINF hInf = NULL;
  638. DWORD dwFieldCount = 0;
  639. DWORD dwIndex = 0;
  640. DWORD dwNumChars = MAX_PATH;
  641. DWORD dwNumRequiredChars = 0;
  642. TCHAR pszFolderSection[MAX_PATH] = {0};
  643. DBG_ENTER( _T("prv_ProcessDirectories"),
  644. bSuccess,
  645. _T("%s - %s"),
  646. pszSection,
  647. pszDirAction);
  648. if ((pszDirAction != INF_KEYWORD_CREATEDIR) &&
  649. (pszDirAction != INF_KEYWORD_DELDIR))
  650. {
  651. SetLastError(ERROR_INVALID_PARAMETER);
  652. return FALSE;
  653. }
  654. if (pszSection == NULL)
  655. {
  656. SetLastError(ERROR_INVALID_PARAMETER);
  657. return FALSE;
  658. }
  659. hInf = faxocm_GetComponentInf();
  660. memset(&Context, 0, sizeof(Context));
  661. // get the first CreateDir or DelDir in the section.
  662. bSuccess = ::SetupFindFirstLine(hInf,
  663. pszSection,
  664. pszDirAction,
  665. &Context);
  666. if (!bSuccess)
  667. {
  668. VERBOSE(DBG_WARNING,
  669. _T("Did not find '%s' keyword in ")
  670. _T("section '%s'. No action will be taken."),
  671. pszDirAction,
  672. pszSection);
  673. return FALSE;
  674. }
  675. // Found the CreateDir or DelDir
  676. // now let's see how many dirs to create/delete
  677. dwFieldCount = SetupGetFieldCount(&Context);
  678. if (dwFieldCount==0)
  679. {
  680. VERBOSE(SETUP_ERR,_T("SetupGetFieldCount failed (ec=%d)"),GetLastError());
  681. return FALSE;
  682. }
  683. for (dwIndex=0; dwIndex<dwFieldCount; dwIndex++)
  684. {
  685. FAX_FOLDER_Description ffdFolder;
  686. // iterate through fields, get the share section and process it.
  687. bSuccess = ::SetupGetStringField(&Context, dwIndex+1, pszFolderSection, dwNumChars, &dwNumRequiredChars);
  688. if (!bSuccess)
  689. {
  690. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (ec=%d)"),GetLastError());
  691. return FALSE;
  692. }
  693. // we have the share name in pszShareSection, fill out the FAX_SHARE_Description structure
  694. if (!prv_FillFolderDescriptionFromInf(pszFolderSection,ffdFolder))
  695. {
  696. VERBOSE(SETUP_ERR,_T("prv_FillFolderDescriptionFromInf failed (ec=%d)"),GetLastError());
  697. return FALSE;
  698. }
  699. // now we have all the data
  700. // check if we should act on this platform...
  701. if (!(ffdFolder.iPlatform & GetProductSKU()))
  702. {
  703. VERBOSE(DBG_MSG,_T("Folder should not be processed on this Platform, skipping..."));
  704. continue;
  705. }
  706. if (pszDirAction == INF_KEYWORD_CREATEDIR)
  707. {
  708. // create the folder
  709. bSuccess = MakeDirectory(ffdFolder.szPath);
  710. if (!bSuccess)
  711. {
  712. DWORD dwReturn = ::GetLastError();
  713. if (dwReturn != ERROR_ALREADY_EXISTS)
  714. {
  715. VERBOSE(SETUP_ERR,_T("MakeDirectory failed (ec=%d)"),dwReturn);
  716. }
  717. }
  718. // set the folder's security and the files in it
  719. if (!prv_SetFileSecurity(ffdFolder))
  720. {
  721. VERBOSE(SETUP_ERR, _T("prv_SetFileSecurity"), GetLastError());
  722. }
  723. // set the folder's attributes
  724. if (ffdFolder.iAttributes!=FILE_ATTRIBUTE_NORMAL)
  725. {
  726. // no sense in setting normal attributes, since this is the default
  727. // the attributes member is initialized to FILE_ATTRIBUTE_NORMAL so
  728. // if we failed to read it from the INF it's still the same
  729. // and if someone specifies it in the INF it'll be set by default.
  730. DWORD dwFileAttributes = GetFileAttributes(ffdFolder.szPath);
  731. if (dwFileAttributes!=-1)
  732. {
  733. dwFileAttributes |= ffdFolder.iAttributes;
  734. if (!SetFileAttributes(ffdFolder.szPath,dwFileAttributes))
  735. {
  736. VERBOSE(SETUP_ERR, TEXT("SetFileAttributes"), GetLastError());
  737. }
  738. }
  739. else
  740. {
  741. VERBOSE(SETUP_ERR, TEXT("GetFileAttributes"), GetLastError());
  742. }
  743. }
  744. }
  745. else
  746. {
  747. // delete the directory
  748. DeleteDirectory(ffdFolder.szPath);
  749. }
  750. }
  751. return TRUE;
  752. }
  753. ///////////////////////////////
  754. // prv_ProcessShares
  755. //
  756. // Enumerates through the specified
  757. // INF file in the specified section
  758. // and gets the value of the next
  759. // keyword 'CreateShare', or 'DelShare'
  760. //
  761. // This function looks for the following lines
  762. // in the INF section
  763. //
  764. // CreateShare = [1st share section],[2nd share section],...
  765. // or
  766. // DelShare = [1st share section],[2nd share section],...
  767. //
  768. // [share section] - is built in the following format:
  769. // Path = <path to folder on which share is created>
  770. // Name = <name of share as it appears to the user>
  771. // Comment = <share comment as it appears to the user>
  772. // Platform = <one of the below platform specifiers>
  773. // Security = <DACL in string format>
  774. //
  775. // Params:
  776. // - pszSection - section in the file to iterate through.
  777. // - pszShareAction - one of INF_KEYWORD_CREATESHARE, INF_KEYWORD_DELSHARE
  778. //
  779. // Returns:
  780. // - TRUE if shares were processed successfully
  781. // - FALSE otherwise
  782. //
  783. static BOOL prv_ProcessShares(const TCHAR *pszSection,const TCHAR *pszShareAction)
  784. {
  785. INFCONTEXT Context;
  786. BOOL bSuccess = TRUE;
  787. HINF hInf = NULL;
  788. DWORD dwFieldCount = 0;
  789. DWORD dwIndex = 0;
  790. DWORD dwNumChars = MAX_PATH;
  791. DWORD dwNumRequiredChars = 0;
  792. TCHAR pszShareSection[MAX_PATH] = {0};
  793. DBG_ENTER( _T("prv_ProcessShares"),
  794. bSuccess,
  795. _T("%s - %s"),
  796. pszSection,
  797. pszShareAction);
  798. if ((pszShareAction != INF_KEYWORD_CREATESHARE) &&
  799. (pszShareAction != INF_KEYWORD_DELSHARE))
  800. {
  801. SetLastError(ERROR_INVALID_PARAMETER);
  802. return FALSE;
  803. }
  804. if (pszSection == NULL)
  805. {
  806. SetLastError(ERROR_INVALID_PARAMETER);
  807. return FALSE;
  808. }
  809. hInf = faxocm_GetComponentInf();
  810. memset(&Context, 0, sizeof(Context));
  811. // get the first CreateShare or DelShare in the section.
  812. bSuccess = ::SetupFindFirstLine(hInf,
  813. pszSection,
  814. pszShareAction,
  815. &Context);
  816. if (!bSuccess)
  817. {
  818. VERBOSE(DBG_WARNING,
  819. _T("Did not find '%s' keyword in ")
  820. _T("section '%s'. No action will be taken."),
  821. pszShareAction,
  822. pszSection);
  823. return FALSE;
  824. }
  825. // Found the CreateShare or DelShare.
  826. // now let's see how many shares to create/delete
  827. dwFieldCount = SetupGetFieldCount(&Context);
  828. if (dwFieldCount==0)
  829. {
  830. VERBOSE(SETUP_ERR,_T("SetupGetFieldCount failed (ec=%d)"),GetLastError());
  831. return FALSE;
  832. }
  833. for (dwIndex=0; dwIndex<dwFieldCount; dwIndex++)
  834. {
  835. FAX_SHARE_Description fsdShare;
  836. // iterate through fields, get the share section and process it.
  837. bSuccess = ::SetupGetStringField(&Context, dwIndex+1, pszShareSection, dwNumChars, &dwNumRequiredChars);
  838. if (!bSuccess)
  839. {
  840. VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (ec=%d)"),GetLastError());
  841. return FALSE;
  842. }
  843. // we have the share name in pszShareSection, fill out the FAX_SHARE_Description structure
  844. if (!prv_FillShareDescriptionFromInf(pszShareSection,fsdShare))
  845. {
  846. VERBOSE(SETUP_ERR,_T("prv_FillShareDescriptionFromInf failed (ec=%d)"),GetLastError());
  847. return FALSE;
  848. }
  849. // now we have all the data
  850. // check if we should act on this platform...
  851. if (!(fsdShare.iPlatform & GetProductSKU()))
  852. {
  853. VERBOSE(DBG_MSG,_T("Share should not be processed on this Platform, skipping..."));
  854. continue;
  855. }
  856. if (pszShareAction == INF_KEYWORD_CREATESHARE)
  857. {
  858. // create the share...
  859. bSuccess = fxocUtil_CreateNetworkShare(&fsdShare);
  860. if (!bSuccess)
  861. {
  862. VERBOSE(SETUP_ERR,
  863. _T("Failed to create share name '%s', path '%s', ")
  864. _T("comment '%s', rc=0x%lx"),
  865. fsdShare.szName,
  866. fsdShare.szPath,
  867. fsdShare.szComment,
  868. GetLastError());
  869. }
  870. }
  871. else
  872. {
  873. // delete the share..
  874. bSuccess = fxocUtil_DeleteNetworkShare(fsdShare.szName);
  875. if (!bSuccess)
  876. {
  877. VERBOSE(SETUP_ERR,
  878. _T("Failed to delete share name '%s', ")
  879. _T("rc=0x%lx"),
  880. fsdShare.szPath,
  881. GetLastError());
  882. }
  883. }
  884. }
  885. return TRUE;
  886. }
  887. ///////////////////////////////////////////////////////////////////////////////////////
  888. // Function:
  889. // prv_SetFileSecurity
  890. //
  891. // Purpose:
  892. // Secure a folder and set the ACL on all the files contained in it
  893. //
  894. // Params:
  895. // FAX_FOLDER_Description ffdFolder - folder to secure
  896. //
  897. // Return Value:
  898. // TRUE - in case of success
  899. // FALSE - otherwise
  900. //
  901. // Author:
  902. // Mooly Beery (MoolyB) 22-May-2002
  903. ///////////////////////////////////////////////////////////////////////////////////////
  904. static BOOL prv_SetFileSecurity(const FAX_FOLDER_Description& ffFolder)
  905. {
  906. BOOL bRet = TRUE;
  907. BOOL bDaclPresent = TRUE;
  908. BOOL bDaclDefaulted = TRUE;
  909. PACL pDacl = NULL;
  910. DWORD dwRet = ERROR_SUCCESS;
  911. HANDLE hFolder = INVALID_HANDLE_VALUE;
  912. DBG_ENTER(_T("prv_SetFileSecurity"),bRet);
  913. hFolder = CreateFile( ffFolder.szPath,
  914. GENERIC_WRITE | WRITE_DAC,
  915. FILE_SHARE_READ | FILE_SHARE_WRITE,
  916. NULL,
  917. OPEN_EXISTING,
  918. FILE_FLAG_BACKUP_SEMANTICS,
  919. NULL);
  920. if (hFolder==INVALID_HANDLE_VALUE)
  921. {
  922. VERBOSE(SETUP_ERR,_T("CreateFile failed (ec=%d)"),GetLastError());
  923. bRet = FALSE;
  924. goto exit;
  925. }
  926. bRet = GetSecurityDescriptorDacl( ffFolder.pSD,
  927. &bDaclPresent,
  928. &pDacl,
  929. &bDaclDefaulted);
  930. if (!bRet)
  931. {
  932. VERBOSE(SETUP_ERR,_T("GetSecurityDescriptorDacl failed (ec=%d)"),GetLastError());
  933. bRet = FALSE;
  934. goto exit;
  935. }
  936. if (!bDaclPresent)
  937. {
  938. VERBOSE(SETUP_ERR,_T("Security Descriptor does not contain a DACL"));
  939. bRet = FALSE;
  940. goto exit;
  941. }
  942. dwRet = SetSecurityInfo(hFolder,
  943. SE_FILE_OBJECT,
  944. DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
  945. NULL,
  946. NULL,
  947. pDacl,
  948. NULL);
  949. if (dwRet!=ERROR_SUCCESS)
  950. {
  951. VERBOSE(SETUP_ERR,_T("SetSecurityInfo failed (ec=%d)"),GetLastError());
  952. bRet = FALSE;
  953. goto exit;
  954. }
  955. exit:
  956. if (hFolder)
  957. {
  958. CloseHandle(hFolder);
  959. }
  960. return bRet;
  961. }
  962. // eof