Source code of Windows XP (NT5)
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.

1929 lines
50 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. secedit.c
  5. Abstract:
  6. Command line tool "secedit" to configure/analyze security
  7. Author:
  8. Jin Huang (jinhuang) 7-Nov-1996
  9. --*/
  10. //
  11. // System header files
  12. //
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <string.h>
  18. #include <shlwapi.h>
  19. //
  20. // CRT header files
  21. //
  22. #include <process.h>
  23. #include <wchar.h>
  24. #include <stddef.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <time.h>
  28. #include <limits.h>
  29. #include "secedit.h"
  30. #include "scesetup.h"
  31. #include "stringid.h"
  32. //#include <aclapi.h>
  33. #include <io.h>
  34. #include "userenv.h"
  35. #include <locale.h>
  36. #define GPT_EFS_NEW_PATH TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions\\{B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A}")
  37. #define GPT_SCEDLL_NEW_PATH TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions\\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}")
  38. #define SECEDITP_MAX_STRING_LENGTH 50
  39. #define SCE_ENGINE_GENERATE 1
  40. #define SCE_ENGINE_COMPILE 2
  41. #define SCE_ENGINE_REGISTER 3
  42. #define SCE_ENGINE_REFRESH 4
  43. #define SCE_ENGINE_BROWSE 5
  44. #define SECEDIT_DETAIL_HELP 1
  45. #define SECEDIT_AREA_HELP 2
  46. #define SECEDIT_OVERWRITE_HELP 4
  47. #define SeceditpArgumentConfigure TEXT("/configure")
  48. #define SeceditpArgumentAnalyze TEXT("/analyze")
  49. #define SeceditpArgumentGenerate TEXT("/export")
  50. #define SeceditpArgumentScpPath TEXT("/CFG")
  51. #define SeceditpArgumentSadPath TEXT("/DB")
  52. #define SeceditpArgumentArea TEXT("/areas")
  53. #define SeceditpArgumentLog TEXT("/log")
  54. #define SeceditpArgumentVerbose TEXT("/verbose")
  55. #define SeceditpArgumentQuiet TEXT("/quiet")
  56. #define SeceditpArgumentAppend TEXT("/overwrite")
  57. #define SeceditpArgumentCompile TEXT("/validate")
  58. #define SeceditpArgumentRegister TEXT("/register")
  59. #define SeceditpArgumentRefresh TEXT("/RefreshPolicy")
  60. #define SeceditpArgumentMerge TEXT("/MergedPolicy")
  61. #define SeceditpArgumentEnforce TEXT("/Enforce")
  62. #define SeceditpAreaPolicy TEXT("SECURITYPOLICY")
  63. #define SeceditpAreaUser TEXT("USER_MGMT")
  64. #define SeceditpAreaGroup TEXT("GROUP_MGMT")
  65. #define SeceditpAreaRight TEXT("USER_RIGHTS")
  66. #define SeceditpAreaDsObject TEXT("DSOBJECTS")
  67. #define SeceditpAreaRegistry TEXT("REGKEYS")
  68. #define SeceditpAreaFile TEXT("FILESTORE")
  69. #define SeceditpAreaService TEXT("SERVICES")
  70. #define SCE_LOCAL_FREE(ptr) if (ptr != NULL) LocalFree(ptr)
  71. HMODULE hMod=NULL;
  72. static DWORD dOptions=0;
  73. static HANDLE hCmdToolLogFile=INVALID_HANDLE_VALUE;
  74. static PWSTR LogFile=NULL;
  75. VOID
  76. ScepPrintHelp(DWORD nLevel);
  77. WCHAR *
  78. SecEditPConvertToFullPath(
  79. WCHAR *UserFilename,
  80. DWORD *retCode
  81. );
  82. BOOL
  83. ScepCmdToolLogInit(
  84. PWSTR logname
  85. );
  86. VOID
  87. ScepCmdToolLogWrite(
  88. PWSTR pErrString
  89. );
  90. SCESTATUS
  91. ScepCmdToolLogClose(
  92. );
  93. SCESTATUS
  94. SeceditpErrOut(
  95. IN DWORD rc,
  96. IN LPTSTR buf OPTIONAL
  97. );
  98. DWORD
  99. SeceditpSceStatusToDosError(
  100. IN SCESTATUS SceStatus
  101. );
  102. BOOL CALLBACK
  103. SceCmdVerboseCallback(
  104. IN HANDLE CallbackHandle,
  105. IN AREA_INFORMATION Area,
  106. IN DWORD TotalTicks,
  107. IN DWORD CurrentTicks
  108. );
  109. DWORD
  110. pProgressRoutine(
  111. IN PWSTR StringUpdate
  112. );
  113. BOOL
  114. ScepPrintConfigureWarning();
  115. BOOL CALLBACK
  116. pBrowseCallback(
  117. IN LONG ID,
  118. IN PWSTR KeyName OPTIONAL,
  119. IN PWSTR GpoName OPTIONAL,
  120. IN PWSTR Value OPTIONAL,
  121. IN DWORD Len
  122. );
  123. #define SECEDIT_OPTION_DEBUG 0x01L
  124. #define SECEDIT_OPTION_VERBOSE 0x02L
  125. #define SECEDIT_OPTION_QUIET 0x04L
  126. #define SECEDIT_OPTION_OVERWRITE 0x08L
  127. #define SECEDIT_OPTION_MACHINE 0x10L
  128. #define SECEDIT_OPTION_MERGE 0x20L
  129. #define SECEDIT_OPTION_APPEND 0x40L
  130. #define SECEDIT_OPTION_ENFORCE 0x80L
  131. int __cdecl
  132. My_wprintf(
  133. const wchar_t *format,
  134. ...
  135. );
  136. int __cdecl
  137. My_fwprintf(
  138. FILE *str,
  139. const wchar_t *format,
  140. ...
  141. );
  142. int __cdecl
  143. My_vfwprintf(
  144. FILE *str,
  145. const wchar_t *format,
  146. va_list argptr
  147. );
  148. int __cdecl
  149. My_printf(
  150. const char *format,
  151. ...
  152. );
  153. int __cdecl wmain(int argc, WCHAR * argv[])
  154. {
  155. PWSTR InfFile=NULL;
  156. // PWSTR LogFile=NULL;
  157. PWSTR SadFile=NULL;
  158. PWSTR pTemp=NULL;
  159. AREA_INFORMATION Area=AREA_ALL;
  160. SCESTATUS rc;
  161. int rCode=0;
  162. DWORD EngineType=0;
  163. LONG i;
  164. DWORD j;
  165. DWORD Len, TotalLen;
  166. BOOL bTest=FALSE;
  167. BOOL bVerbose=TRUE;
  168. BOOL bQuiet=FALSE;
  169. BOOL bAppend=TRUE;
  170. PVOID hProfile=NULL;
  171. PSCE_PROFILE_INFO ProfileInfo=NULL;
  172. PSCE_ERROR_LOG_INFO ErrBuf=NULL;
  173. PSCE_ERROR_LOG_INFO pErr;
  174. DWORD dWarning=0;
  175. WCHAR LineString[256];
  176. WCHAR WarningStr[256];
  177. BOOL bMachine=FALSE, bMerge=FALSE, bEnforce=FALSE;
  178. UINT rId=0;
  179. HKEY hKey=NULL, hKey1=NULL;
  180. UINT ConsoleCP;
  181. char szConsoleCP[6];
  182. // check for /quiet and LogFile if any - set relevant flags (need this info immediately to log errors)
  183. for ( i=1; i<argc; i++ ){
  184. if ( _wcsicmp(argv[i], SeceditpArgumentLog ) == 0 ) {
  185. if ( i+1 < argc && argv[i+1][0] != L'/' ) {
  186. LogFile = SecEditPConvertToFullPath(argv[i+1], &rCode);
  187. if (rCode == 2) {
  188. goto Done;
  189. }
  190. } else {
  191. ScepPrintHelp(EngineType);
  192. rCode = 1;
  193. goto Done;
  194. }
  195. i++;
  196. continue;
  197. }
  198. if ( _wcsicmp(argv[i], SeceditpArgumentQuiet ) == 0 ) {
  199. bQuiet = TRUE;
  200. dOptions |= SCE_DISABLE_LOG;
  201. }
  202. }
  203. if ( rCode == 0 )
  204. ScepCmdToolLogInit(LogFile);
  205. ConsoleCP = GetConsoleOutputCP();
  206. // szConsoleCP[0] = '.';
  207. // itoa(ConsoleCP, &szConsoleCP[1], 10);
  208. sprintf(szConsoleCP, ".%d", ConsoleCP);
  209. // setlocale(LC_ALL, ".OCP");
  210. setlocale(LC_ALL, szConsoleCP);
  211. hMod = GetModuleHandle(NULL);
  212. if ( hMod == NULL ) {
  213. My_wprintf(L"Cannot find the module handle\n");
  214. return 2; // system error
  215. }
  216. for ( i=1; i<argc; i++ )
  217. if ( _wcsicmp(argv[i], L"/?") == 0 ) {
  218. ScepPrintHelp(0);
  219. goto Done;
  220. }
  221. if ( argc < 2 ) {
  222. ScepPrintHelp(0);
  223. return 1;
  224. } else {
  225. for ( i=1; i<argc; i++ ) {
  226. SCE_LOCAL_FREE(pTemp);
  227. Len = wcslen(argv[i]);
  228. pTemp = (PWSTR)LocalAlloc( 0, (Len+1)*sizeof(WCHAR));
  229. if ( pTemp == NULL ) {
  230. My_wprintf(L"Not enough memory\n");
  231. rCode=2; //system error
  232. goto Done;
  233. }
  234. wcscpy(pTemp, argv[i]);
  235. //
  236. // configure engine type ?
  237. //
  238. if ( _wcsicmp(pTemp, SeceditpArgumentConfigure) == 0 ) {
  239. if ( EngineType != 0 ) {
  240. ScepPrintHelp(EngineType);
  241. rCode = 1; // invalid parameter
  242. goto Done;
  243. }
  244. EngineType = SCE_ENGINE_SCP;
  245. continue;
  246. }
  247. //
  248. // analyze engine type ?
  249. //
  250. if ( _wcsicmp(pTemp, SeceditpArgumentAnalyze) == 0 ) {
  251. if ( EngineType != 0 ) {
  252. ScepPrintHelp(EngineType);
  253. rCode = 1; //invalid parameter
  254. goto Done;
  255. }
  256. EngineType = SCE_ENGINE_SAP;
  257. continue;
  258. }
  259. //
  260. // generate template ?
  261. //
  262. if ( _wcsicmp(pTemp, SeceditpArgumentGenerate) == 0 ) {
  263. if ( EngineType != 0 ) {
  264. ScepPrintHelp(EngineType);
  265. rCode = 1;
  266. goto Done;
  267. }
  268. EngineType = SCE_ENGINE_GENERATE;
  269. continue;
  270. }
  271. //
  272. // compile a template ?
  273. //
  274. if ( _wcsicmp(pTemp, SeceditpArgumentCompile) == 0 ) {
  275. if ( EngineType != 0 ) {
  276. ScepPrintHelp(EngineType);
  277. rCode = 1;
  278. goto Done;
  279. }
  280. EngineType = SCE_ENGINE_COMPILE;
  281. //
  282. // compile requires a INF template name
  283. //
  284. if ( i+1 < argc && argv[i+1][0] != L'/' ) {
  285. InfFile = SecEditPConvertToFullPath(argv[i+1], &rCode);
  286. if (rCode == 2) {
  287. goto Done;
  288. }
  289. } else {
  290. ScepPrintHelp(EngineType);
  291. rCode = 1;
  292. goto Done;
  293. }
  294. i++;
  295. continue;
  296. }
  297. //
  298. // register a template for registry values ?
  299. //
  300. if ( _wcsicmp(pTemp, SeceditpArgumentRegister) == 0 ) {
  301. if ( EngineType != 0 ) {
  302. ScepPrintHelp(EngineType);
  303. rCode = 1;
  304. goto Done;
  305. }
  306. EngineType = SCE_ENGINE_REGISTER;
  307. //
  308. // register requires a INF template name
  309. //
  310. if ( i+1 < argc && argv[i+1][0] != L'/' ) {
  311. InfFile = SecEditPConvertToFullPath(argv[i+1], &rCode);
  312. if (rCode == 2) {
  313. goto Done;
  314. }
  315. } else {
  316. ScepPrintHelp(EngineType);
  317. rCode = 1;
  318. goto Done;
  319. }
  320. i++;
  321. continue;
  322. }
  323. //
  324. // refresh policy
  325. //
  326. if ( _wcsicmp(pTemp, SeceditpArgumentRefresh) == 0 ) {
  327. //
  328. // do not support refresh policy because it's supported by refgp.exe
  329. //
  330. ScepPrintHelp(EngineType);
  331. rCode = 1;
  332. goto Done;
  333. /*
  334. if ( EngineType != 0 ) {
  335. ScepPrintHelp(EngineType);
  336. rCode = 1;
  337. goto Done;
  338. }
  339. EngineType = SCE_ENGINE_REFRESH;
  340. //
  341. // next argument is the policy area
  342. //
  343. if ( i+1 < argc && argv[i+1][0] != L'/' ) {
  344. if ( 0 == _wcsicmp(argv[i+1], L"MACHINE_POLICY") ) {
  345. bMachine = TRUE;
  346. } else if ( 0 == _wcsicmp(argv[i+1], L"USER_POLICY") ) {
  347. bMachine = FALSE;
  348. } else {
  349. ScepPrintHelp(EngineType);
  350. rCode = 1;
  351. goto Done;
  352. }
  353. } else {
  354. ScepPrintHelp(EngineType);
  355. rCode = 1;
  356. goto Done;
  357. }
  358. i++;
  359. continue;
  360. */
  361. }
  362. if ( _wcsicmp(pTemp, L"/browse") == 0 ) {
  363. if ( EngineType != 0 ) {
  364. ScepPrintHelp(EngineType);
  365. rCode = 1;
  366. goto Done;
  367. }
  368. EngineType = SCE_ENGINE_BROWSE;
  369. //
  370. // next argument is the table
  371. //
  372. if ( i+1 < argc && argv[i+1][0] != L'/' ) {
  373. if ( 0 == _wcsicmp(argv[i+1], L"scp") ) {
  374. dWarning = SCE_ENGINE_SCP;
  375. } else if ( 0 == _wcsicmp(argv[i+1], L"smp") ) {
  376. dWarning = SCE_ENGINE_SMP;
  377. } else if ( 0 == _wcsicmp(argv[i+1], L"sap") ) {
  378. dWarning = SCE_ENGINE_SAP;
  379. } else if ( 0 == _wcsicmp(argv[i+1], L"tattoo") ) {
  380. dWarning = SCE_ENGINE_SAP;
  381. bMerge = TRUE;
  382. } else {
  383. ScepPrintHelp(EngineType);
  384. rCode = 1;
  385. goto Done;
  386. }
  387. } else {
  388. ScepPrintHelp(EngineType);
  389. rCode = 1;
  390. goto Done;
  391. }
  392. i++;
  393. continue;
  394. }
  395. if ( _wcsicmp(pTemp, L"/debug") == 0 ) {
  396. bTest = TRUE;
  397. continue;
  398. }
  399. if ( _wcsicmp(pTemp, SeceditpArgumentVerbose ) == 0 ) {
  400. bVerbose = TRUE;
  401. continue;
  402. }
  403. if ( _wcsicmp(pTemp, SeceditpArgumentQuiet ) == 0 ) {
  404. bQuiet = TRUE;
  405. continue;
  406. }
  407. if ( _wcsicmp(pTemp, SeceditpArgumentAppend ) == 0 ) {
  408. bAppend = FALSE;
  409. continue;
  410. }
  411. if ( _wcsicmp(pTemp, SeceditpArgumentMerge ) == 0 ) {
  412. bMerge = TRUE;
  413. continue;
  414. }
  415. if ( _wcsicmp(pTemp, SeceditpArgumentEnforce ) == 0 ) {
  416. bEnforce = TRUE;
  417. continue;
  418. }
  419. //
  420. // scp profile name, it may be empty "/scppath"
  421. //
  422. if ( _wcsicmp(pTemp, SeceditpArgumentScpPath) == 0 ) {
  423. if ( i+1 < argc && argv[i+1][0] != L'/' ) {
  424. InfFile = SecEditPConvertToFullPath(argv[i+1], &rCode);
  425. if (rCode == 2) {
  426. goto Done;
  427. }
  428. } else {
  429. ScepPrintHelp(EngineType);
  430. rCode = 1;
  431. goto Done;
  432. }
  433. i++;
  434. continue;
  435. }
  436. //
  437. // sad database name, it may be empty
  438. //
  439. if ( _wcsicmp(pTemp, SeceditpArgumentSadPath) == 0 ) {
  440. if ( i+1 < argc && argv[i+1][0] != L'/' ) {
  441. SadFile = SecEditPConvertToFullPath(argv[i+1], &rCode);
  442. if (rCode == 2) {
  443. goto Done;
  444. }
  445. } else {
  446. ScepPrintHelp(EngineType);
  447. rCode = 1;
  448. goto Done;
  449. }
  450. i++;
  451. continue;
  452. }
  453. //
  454. // area(s)
  455. //
  456. if ( _wcsicmp(pTemp, SeceditpArgumentArea ) == 0 ) {
  457. //
  458. //
  459. for ( j=(DWORD)i, Area=0; j+1 < (DWORD)argc && argv[j+1][0] != L'/'; j++ ) {
  460. SCE_LOCAL_FREE(pTemp);
  461. Len = wcslen(argv[j+1]);
  462. pTemp = (PWSTR)LocalAlloc( 0, (Len+1)*sizeof(WCHAR));
  463. if ( pTemp == NULL ) {
  464. My_wprintf(L"Not enough memory\n");
  465. rCode = 2;
  466. goto Done;
  467. }
  468. wcscpy(pTemp, argv[j+1]);
  469. //
  470. // Process all arguments for Areas
  471. //
  472. if ( _wcsicmp( pTemp, SeceditpAreaPolicy) == 0 ) {
  473. // security policy
  474. Area |= AREA_SECURITY_POLICY;
  475. continue;
  476. }
  477. /*
  478. if ( _wcsicmp( pTemp, SeceditpAreaUser) == 0 ) {
  479. // user
  480. Area |= AREA_USER_SETTINGS;
  481. continue;
  482. }
  483. */
  484. if ( _wcsicmp( pTemp, SeceditpAreaGroup) == 0 ) {
  485. // group
  486. Area |= AREA_GROUP_MEMBERSHIP;
  487. continue;
  488. }
  489. if ( _wcsicmp( pTemp, SeceditpAreaRight) == 0 ) {
  490. // privilege rights
  491. Area |= AREA_PRIVILEGES;
  492. continue;
  493. }
  494. #if 0
  495. if ( _wcsicmp( pTemp, SeceditpAreaDsObject) == 0 ) {
  496. // ds objects
  497. Area |= AREA_DS_OBJECTS;
  498. continue;
  499. }
  500. #endif
  501. if ( _wcsicmp( pTemp, SeceditpAreaRegistry) == 0 ) {
  502. // Registry
  503. Area |= AREA_REGISTRY_SECURITY;
  504. continue;
  505. }
  506. if ( _wcsicmp( pTemp, SeceditpAreaFile) == 0 ) {
  507. // file
  508. Area |= AREA_FILE_SECURITY;
  509. continue;
  510. }
  511. if ( _wcsicmp( pTemp, SeceditpAreaService) == 0 ) {
  512. // services
  513. Area |= AREA_SYSTEM_SERVICE;
  514. continue;
  515. }
  516. //
  517. // unrecognized parameter
  518. //
  519. ScepPrintHelp(EngineType);
  520. rCode = 1;
  521. goto Done;
  522. }
  523. i = (LONG)j;
  524. continue;
  525. }
  526. //
  527. // ignore if "/log filename" since already processed at the beginning
  528. //
  529. if ( _wcsicmp(pTemp, SeceditpArgumentLog ) == 0 ) {
  530. if ( i+1 < argc && argv[i+1][0] != L'/' ) {
  531. } else {
  532. ScepPrintHelp(EngineType);
  533. rCode = 1;
  534. goto Done;
  535. }
  536. i++;
  537. continue;
  538. }
  539. //
  540. // unrecognized argument
  541. //
  542. ScepPrintHelp(EngineType);
  543. rCode = 1;
  544. goto Done;
  545. }
  546. }
  547. if ( EngineType == 0 ) {
  548. ScepPrintHelp(0);
  549. rCode = 1;
  550. goto Done;
  551. }
  552. SetConsoleCtrlHandler(NULL, TRUE);
  553. //
  554. // Initialize
  555. //
  556. if ( bTest ) {
  557. dOptions |= SCE_DEBUG_LOG;
  558. } else if ( bVerbose ) {
  559. dOptions |= SCE_VERBOSE_LOG;
  560. }
  561. switch ( EngineType ) {
  562. case SCE_ENGINE_SCP:
  563. //
  564. // configure the system
  565. //
  566. if ( (SadFile == NULL) ||
  567. SceIsSystemDatabase(SadFile) ) {
  568. rc = SCESTATUS_INVALID_PARAMETER;
  569. LoadString( hMod,
  570. SECEDITP_CONFIG_NOT_ALLOWED_1,
  571. LineString,
  572. 256
  573. );
  574. My_wprintf(LineString);
  575. LoadString( hMod,
  576. SECEDITP_CONFIG_NOT_ALLOWED_2,
  577. LineString,
  578. 256
  579. );
  580. My_wprintf(LineString);
  581. EngineType = 0;
  582. } else {
  583. bMachine = TRUE;
  584. if ( bAppend && InfFile != NULL ) {
  585. dOptions |= SCE_UPDATE_DB;
  586. } else {
  587. dOptions |= SCE_OVERWRITE_DB;
  588. if ( FALSE == bAppend && InfFile != NULL && !bQuiet ) {
  589. //
  590. // will overwrite the database with the new inf file.
  591. // warn users for this serious problem.
  592. // If this is a normal user logon, the operation will fail
  593. // by the server site.
  594. //
  595. bMachine = ScepPrintConfigureWarning(); // temp. use of bMachine
  596. }
  597. }
  598. if ( bMachine ) {
  599. rc = SceConfigureSystem(
  600. NULL,
  601. InfFile,
  602. SadFile,
  603. LogFile,
  604. dOptions,
  605. Area,
  606. (bVerbose || bTest ) ?
  607. (PSCE_AREA_CALLBACK_ROUTINE)SceCmdVerboseCallback : NULL,
  608. NULL,
  609. &dWarning
  610. );
  611. } else {
  612. rc = SCESTATUS_SUCCESS;
  613. dWarning = ERROR_REQUEST_ABORTED;
  614. goto Done;
  615. }
  616. }
  617. break;
  618. case SCE_ENGINE_SAP:
  619. //
  620. // analyze the system
  621. //
  622. if ( !bTest )
  623. Area = AREA_ALL;
  624. // if ( bAppend && InfFile != NULL ) {
  625. // dOptions |= SCE_UPDATE_DB;
  626. // } else {
  627. // dOptions |= SCE_OVERWRITE_DB;
  628. // }
  629. dOptions |= SCE_OVERWRITE_DB;
  630. // if ( InfFile == NULL || SadFile != NULL ) {
  631. if ( (SadFile != NULL) &&
  632. !SceIsSystemDatabase(SadFile) ) {
  633. rc = SceAnalyzeSystem(
  634. NULL,
  635. InfFile,
  636. SadFile,
  637. LogFile,
  638. dOptions,
  639. Area,
  640. (bVerbose || bTest ) ?
  641. (PSCE_AREA_CALLBACK_ROUTINE)SceCmdVerboseCallback : NULL,
  642. NULL,
  643. &dWarning
  644. );
  645. } else {
  646. rc = SCESTATUS_INVALID_PARAMETER;
  647. LoadString( hMod,
  648. SECEDITP_ANALYSIS_NOT_ALLOWED_1,
  649. LineString,
  650. 256
  651. );
  652. My_wprintf(LineString);
  653. LoadString( hMod,
  654. SECEDITP_ANALYSIS_NOT_ALLOWED_2,
  655. LineString,
  656. 256
  657. );
  658. My_wprintf(LineString);
  659. EngineType = 0;
  660. }
  661. break;
  662. case SCE_ENGINE_GENERATE:
  663. if ( InfFile != NULL ) {
  664. //
  665. // must have a inf file name
  666. //
  667. rc = SceSetupGenerateTemplate(NULL,
  668. SadFile,
  669. bMerge,
  670. InfFile,
  671. LogFile,
  672. Area);
  673. if (ERROR_NOT_ENOUGH_MEMORY == rc ||
  674. ERROR_SERVICE_ALREADY_RUNNING == rc ) {
  675. rCode = 2;
  676. } else if ( rc ) {
  677. rCode = 1;
  678. }
  679. } else {
  680. rCode = 1;
  681. ScepPrintHelp(EngineType);
  682. goto Done;
  683. }
  684. break;
  685. case SCE_ENGINE_BROWSE:
  686. //
  687. // must have a inf file name
  688. //
  689. if ( Area == 0 ) {
  690. Area = AREA_ALL;
  691. }
  692. rc = SceBrowseDatabaseTable(SadFile,
  693. (SCETYPE)dWarning,
  694. Area,
  695. bMerge,
  696. (PSCE_BROWSE_CALLBACK_ROUTINE)pBrowseCallback
  697. );
  698. dWarning = 0; // reset the value
  699. if (ERROR_NOT_ENOUGH_MEMORY == rc ||
  700. ERROR_SERVICE_ALREADY_RUNNING == rc ) {
  701. rCode = 2;
  702. } else if ( rc ) {
  703. rCode = 1;
  704. }
  705. break;
  706. case SCE_ENGINE_COMPILE:
  707. rc = 0;
  708. if ( InfFile != NULL ) {
  709. //
  710. // must have a inf file name
  711. //
  712. rc = SceOpenProfile(InfFile,
  713. SCE_INF_FORMAT,
  714. &hProfile);
  715. if ( rc == SCESTATUS_SUCCESS && hProfile ) {
  716. //
  717. // get profile info will parse the template first
  718. //
  719. rc = SceGetSecurityProfileInfo(hProfile,
  720. SCE_ENGINE_SCP,
  721. AREA_ALL,
  722. &ProfileInfo,
  723. &ErrBuf);
  724. if ( SCESTATUS_SUCCESS == rc && ErrBuf ) {
  725. //
  726. // this is a new version template
  727. //
  728. LoadString( hMod,
  729. SECEDITP_TEMPLATE_NEWVERSION,
  730. LineString,
  731. 256
  732. );
  733. SeceditpErrOut(0, LineString);
  734. rc = SCESTATUS_INVALID_DATA;
  735. }
  736. for ( pErr=ErrBuf; pErr != NULL; pErr = pErr->next ) {
  737. if ( pErr->buffer != NULL ) {
  738. SeceditpErrOut( pErr->rc, pErr->buffer );
  739. }
  740. }
  741. SceFreeMemory((PVOID)ErrBuf, SCE_STRUCT_ERROR_LOG_INFO);
  742. ErrBuf = NULL;
  743. if ( ProfileInfo != NULL ) {
  744. SceFreeMemory((PVOID)ProfileInfo, Area);
  745. LocalFree(ProfileInfo);
  746. }
  747. SceCloseProfile(&hProfile);
  748. } else {
  749. if (SCESTATUS_OTHER_ERROR == rc) {
  750. LoadString( hMod,
  751. SECEDITP_FILE_MAY_CORRUPTED,
  752. LineString,
  753. 256
  754. );
  755. }
  756. else {
  757. LoadString( hMod,
  758. SECEDITP_CANNOT_FIND_TEMPLATE,
  759. LineString,
  760. 256
  761. );
  762. }
  763. SeceditpErrOut(SeceditpSceStatusToDosError(rc),
  764. LineString);
  765. }
  766. if (SCESTATUS_NOT_ENOUGH_RESOURCE == rc ||
  767. SCESTATUS_ALREADY_RUNNING == rc ) {
  768. rCode = 2;
  769. } else if ( rc ) {
  770. rCode = 1;
  771. }
  772. } else {
  773. rCode = 1;
  774. ScepPrintHelp(EngineType);
  775. goto Done;
  776. }
  777. if ( SCESTATUS_SUCCESS == rc && InfFile) {
  778. LoadString( hMod,
  779. SECEDITP_COMPILE_OK,
  780. LineString,
  781. 256
  782. );
  783. My_wprintf(LineString, InfFile);
  784. }
  785. break;
  786. case SCE_ENGINE_REGISTER:
  787. rc = 0;
  788. if ( InfFile != NULL ) {
  789. rc = SceRegisterRegValues(InfFile);
  790. if (ERROR_NOT_ENOUGH_MEMORY == rc ) {
  791. rCode = 2;
  792. } else if ( rc ) {
  793. rCode = 1;
  794. }
  795. } else {
  796. rCode = 1;
  797. ScepPrintHelp(EngineType);
  798. goto Done;
  799. }
  800. if ( SCESTATUS_SUCCESS == rc && InfFile) {
  801. LoadString( hMod,
  802. SECEDITP_REGISTER_OK,
  803. LineString,
  804. 256
  805. );
  806. My_wprintf(LineString, InfFile);
  807. }
  808. break;
  809. case SCE_ENGINE_REFRESH:
  810. break;
  811. default:
  812. rc = 0;
  813. rCode = 1;
  814. ScepPrintHelp(EngineType);
  815. break;
  816. }
  817. SetConsoleCtrlHandler(NULL, FALSE);
  818. if ( EngineType == SCE_ENGINE_SCP ||
  819. EngineType == SCE_ENGINE_SAP ||
  820. EngineType == SCE_ENGINE_GENERATE ||
  821. EngineType == SCE_ENGINE_BROWSE ) {
  822. My_wprintf(L" \n");
  823. if ( SCESTATUS_SUCCESS == rc ) {
  824. if ( ERROR_SUCCESS == dWarning ) {
  825. rId = SECEDITP_TASK_COMPLETE_NO_ERROR;
  826. } else {
  827. // SeceditpErrOut( dWarning, NULL);
  828. rId = SECEDITP_TASK_COMPLETE_WARNING;
  829. }
  830. } else {
  831. SeceditpErrOut( SeceditpSceStatusToDosError(rc), NULL);
  832. rId = SECEDITP_TASK_COMPLETE_ERROR;
  833. }
  834. LoadString( hMod,
  835. rId,
  836. LineString,
  837. 256
  838. );
  839. if ( rId == SECEDITP_TASK_COMPLETE_WARNING ) {
  840. //
  841. // explain the warnings
  842. //
  843. WarningStr[0] = L'\0';
  844. switch ( dWarning ) {
  845. case ERROR_FILE_NOT_FOUND:
  846. case ERROR_PATH_NOT_FOUND:
  847. LoadString( hMod,
  848. SECEDITP_WARNING_NOT_FOUND,
  849. WarningStr,
  850. 256
  851. );
  852. break;
  853. case ERROR_SHARING_VIOLATION:
  854. LoadString( hMod,
  855. SECEDITP_WARNING_IN_USE,
  856. WarningStr,
  857. 256
  858. );
  859. break;
  860. default:
  861. LoadString( hMod,
  862. SECEDITP_WARNING_OTHER_WARNING,
  863. WarningStr,
  864. 256
  865. );
  866. break;
  867. }
  868. My_wprintf(LineString, WarningStr);
  869. } else {
  870. My_wprintf(LineString);
  871. }
  872. if (bQuiet == FALSE) {
  873. if ( LogFile ) {
  874. LoadString( hMod,
  875. SECEDITP_TASK_SEE_LOG,
  876. LineString,
  877. 256
  878. );
  879. My_wprintf(LineString, LogFile);
  880. } else {
  881. LoadString( hMod,
  882. SECEDITP_TASK_SEE_DEF_LOG,
  883. LineString,
  884. 256
  885. );
  886. My_wprintf(L"%s", LineString);
  887. }
  888. }
  889. }
  890. Done:
  891. if ( dOptions & SCE_DISABLE_LOG ){
  892. ScepCmdToolLogClose();
  893. }
  894. SCE_LOCAL_FREE(InfFile);
  895. SCE_LOCAL_FREE(SadFile);
  896. SCE_LOCAL_FREE(LogFile);
  897. SCE_LOCAL_FREE(pTemp);
  898. FreeLibrary( hMod );
  899. if ( rCode )
  900. return rCode;
  901. else if ( rc ) {
  902. if (SCESTATUS_NOT_ENOUGH_RESOURCE == rc ||
  903. SCESTATUS_ALREADY_RUNNING == rc )
  904. return 2;
  905. else
  906. return 1;
  907. } else if ( dWarning ) {
  908. return 3;
  909. } else
  910. return 0;
  911. }
  912. VOID
  913. ScepPrintHelp(DWORD nLevel)
  914. {
  915. PROCESS_INFORMATION ProcInfo;
  916. STARTUPINFOA StartInfo;
  917. BOOL fOk;
  918. RtlZeroMemory(&StartInfo,sizeof(StartInfo));
  919. StartInfo.cb = sizeof(StartInfo);
  920. StartInfo.dwFlags = STARTF_USESHOWWINDOW;
  921. StartInfo.wShowWindow = (WORD)SW_SHOWNORMAL;
  922. fOk = CreateProcessA(NULL, "hh secedit.chm",
  923. NULL, NULL, FALSE,
  924. 0,
  925. NULL,
  926. NULL,
  927. &StartInfo,
  928. &ProcInfo
  929. );
  930. if ( fOk ) {
  931. CloseHandle(ProcInfo.hProcess);
  932. CloseHandle(ProcInfo.hThread);
  933. }
  934. }
  935. SCESTATUS
  936. SeceditpErrOut(
  937. IN DWORD rc,
  938. IN LPTSTR buf OPTIONAL
  939. )
  940. {
  941. LPVOID lpMsgBuf=NULL;
  942. if ( rc != NO_ERROR ) {
  943. //
  944. // get error description of rc
  945. //
  946. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  947. NULL,
  948. rc,
  949. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  950. (LPTSTR)&lpMsgBuf,
  951. 0,
  952. NULL
  953. );
  954. }
  955. //
  956. // Display to screen
  957. //
  958. if ( buf ) {
  959. if (lpMsgBuf != NULL )
  960. My_fwprintf( stdout, L"%s %s\n", (PWSTR)lpMsgBuf, buf );
  961. else
  962. My_fwprintf( stdout, L"%s\n", buf );
  963. } else {
  964. if (lpMsgBuf != NULL )
  965. My_fwprintf( stdout, L"%s\n", (PWSTR)lpMsgBuf);
  966. }
  967. SCE_LOCAL_FREE(lpMsgBuf);
  968. return(SCESTATUS_SUCCESS);
  969. }
  970. DWORD
  971. SeceditpSceStatusToDosError(
  972. IN SCESTATUS SceStatus
  973. )
  974. // converts SCESTATUS error code to dos error defined in winerror.h
  975. {
  976. switch(SceStatus) {
  977. case SCESTATUS_SUCCESS:
  978. return(NO_ERROR);
  979. case SCESTATUS_OTHER_ERROR:
  980. return(ERROR_EXTENDED_ERROR);
  981. case SCESTATUS_INVALID_PARAMETER:
  982. return(ERROR_INVALID_PARAMETER);
  983. case SCESTATUS_RECORD_NOT_FOUND:
  984. return(ERROR_NO_MORE_ITEMS);
  985. case SCESTATUS_NO_MAPPING:
  986. return(ERROR_NONE_MAPPED);
  987. case SCESTATUS_TRUST_FAIL:
  988. return(ERROR_TRUSTED_DOMAIN_FAILURE);
  989. case SCESTATUS_INVALID_DATA:
  990. return(ERROR_INVALID_DATA);
  991. case SCESTATUS_OBJECT_EXIST:
  992. return(ERROR_FILE_EXISTS);
  993. case SCESTATUS_BUFFER_TOO_SMALL:
  994. return(ERROR_INSUFFICIENT_BUFFER);
  995. case SCESTATUS_PROFILE_NOT_FOUND:
  996. return(ERROR_FILE_NOT_FOUND);
  997. case SCESTATUS_BAD_FORMAT:
  998. return(ERROR_BAD_FORMAT);
  999. case SCESTATUS_NOT_ENOUGH_RESOURCE:
  1000. return(ERROR_NOT_ENOUGH_MEMORY);
  1001. case SCESTATUS_ACCESS_DENIED:
  1002. return(ERROR_ACCESS_DENIED);
  1003. case SCESTATUS_CANT_DELETE:
  1004. return(ERROR_CURRENT_DIRECTORY);
  1005. case SCESTATUS_PREFIX_OVERFLOW:
  1006. return(ERROR_BUFFER_OVERFLOW);
  1007. case SCESTATUS_ALREADY_RUNNING:
  1008. return(ERROR_SERVICE_ALREADY_RUNNING);
  1009. case SCESTATUS_SERVICE_NOT_SUPPORT:
  1010. return(ERROR_NOT_SUPPORTED);
  1011. case SCESTATUS_MOD_NOT_FOUND:
  1012. return(ERROR_MOD_NOT_FOUND);
  1013. case SCESTATUS_EXCEPTION_IN_SERVER:
  1014. return(ERROR_EXCEPTION_IN_SERVICE);
  1015. case SCESTATUS_JET_DATABASE_ERROR:
  1016. return(ERROR_DATABASE_FAILURE);
  1017. case SCESTATUS_TIMEOUT:
  1018. return(ERROR_TIMEOUT);
  1019. case SCESTATUS_PENDING_IGNORE:
  1020. return(ERROR_IO_PENDING);
  1021. case SCESTATUS_SPECIAL_ACCOUNT:
  1022. return(ERROR_SPECIAL_ACCOUNT);
  1023. default:
  1024. return(ERROR_EXTENDED_ERROR);
  1025. }
  1026. }
  1027. BOOL CALLBACK
  1028. SceCmdVerboseCallback(
  1029. IN HANDLE CallbackHandle,
  1030. IN AREA_INFORMATION Area,
  1031. IN DWORD TotalTicks,
  1032. IN DWORD CurrentTicks
  1033. )
  1034. {
  1035. LPCTSTR SectionName;
  1036. DWORD nProg;
  1037. WCHAR LineString[256];
  1038. switch ( Area ) {
  1039. case AREA_SECURITY_POLICY:
  1040. SectionName = NULL;
  1041. break;
  1042. case AREA_PRIVILEGES:
  1043. SectionName = szPrivilegeRights;
  1044. break;
  1045. case AREA_GROUP_MEMBERSHIP:
  1046. SectionName = szGroupMembership;
  1047. break;
  1048. case AREA_FILE_SECURITY:
  1049. SectionName = szFileSecurity;
  1050. break;
  1051. case AREA_REGISTRY_SECURITY:
  1052. SectionName = szRegistryKeys;
  1053. break;
  1054. case AREA_DS_OBJECTS:
  1055. SectionName = szDSSecurity;
  1056. break;
  1057. case AREA_SYSTEM_SERVICE:
  1058. SectionName = NULL;
  1059. break;
  1060. default:
  1061. SectionName = NULL;
  1062. break;
  1063. }
  1064. if ( TotalTicks ) {
  1065. nProg = (CurrentTicks+1)*100/TotalTicks;
  1066. if ( nProg > 100 ) {
  1067. nProg = 100;
  1068. }
  1069. } else {
  1070. nProg = 0;
  1071. }
  1072. if ( SectionName ) {
  1073. LoadString( hMod,
  1074. SECEDITP_WITH_SECTIONNAME,
  1075. LineString,
  1076. 256
  1077. );
  1078. My_wprintf(LineString, nProg, CurrentTicks, TotalTicks, SectionName);
  1079. } else if ( Area == AREA_SECURITY_POLICY ) {
  1080. LoadString( hMod,
  1081. SECEDITP_SICURITY_POLICY,
  1082. LineString,
  1083. 256
  1084. );
  1085. My_wprintf(LineString, nProg, CurrentTicks, TotalTicks);
  1086. } else if ( Area == AREA_SYSTEM_SERVICE ) {
  1087. LoadString( hMod,
  1088. SECEDITP_SYSTEM_SERVICE,
  1089. LineString,
  1090. 256
  1091. );
  1092. My_wprintf(LineString, nProg, CurrentTicks, TotalTicks);
  1093. } else {
  1094. LoadString( hMod,
  1095. SECEDITP_NO_SECTIONNAME,
  1096. LineString,
  1097. 256
  1098. );
  1099. My_wprintf(LineString, nProg, CurrentTicks, TotalTicks);
  1100. }
  1101. return TRUE;
  1102. }
  1103. DWORD
  1104. pProgressRoutine(
  1105. IN PWSTR StringUpdate
  1106. )
  1107. {
  1108. if ( StringUpdate ) {
  1109. My_wprintf(L"Process %s\n", StringUpdate);
  1110. }
  1111. return 0;
  1112. }
  1113. BOOL
  1114. ScepPrintConfigureWarning()
  1115. {
  1116. WCHAR LineString[256];
  1117. WCHAR wch;
  1118. LoadString( hMod,
  1119. SECEDITP_CONFIG_WARNING_LINE1,
  1120. LineString,
  1121. 256
  1122. );
  1123. My_wprintf(LineString);
  1124. LoadString( hMod,
  1125. SECEDITP_CONFIG_WARNING_LINE2,
  1126. LineString,
  1127. 256
  1128. );
  1129. My_wprintf(LineString);
  1130. LoadString( hMod,
  1131. SECEDITP_CONFIG_WARNING_LINE3,
  1132. LineString,
  1133. 256
  1134. );
  1135. My_wprintf(LineString);
  1136. //
  1137. // get user input
  1138. //
  1139. LoadString( hMod,
  1140. SECEDITP_CONFIG_WARNING_CONFIRM,
  1141. LineString,
  1142. 256
  1143. );
  1144. My_wprintf(LineString);
  1145. wch = getwc(stdin);
  1146. getwc(stdin);
  1147. //
  1148. // load string for Yes
  1149. //
  1150. LineString[0] = L'\0';
  1151. LoadString( hMod,
  1152. SECEDITP_IDS_YES,
  1153. LineString,
  1154. 256
  1155. );
  1156. if ( towlower(wch) == towlower(LineString[0]) ) {
  1157. return(TRUE);
  1158. } else {
  1159. return(FALSE);
  1160. }
  1161. }
  1162. BOOL CALLBACK
  1163. pBrowseCallback(
  1164. IN LONG ID,
  1165. IN PWSTR KeyName OPTIONAL,
  1166. IN PWSTR GpoName OPTIONAL,
  1167. IN PWSTR Value OPTIONAL,
  1168. IN DWORD Len
  1169. )
  1170. {
  1171. BYTE *pb=NULL;
  1172. My_wprintf(L"\n");
  1173. if ( ID > 0 ) {
  1174. My_printf("%d\t", ID);
  1175. }
  1176. if (GpoName ) {
  1177. My_wprintf(L"%s ", GpoName);
  1178. }
  1179. if ( KeyName ) {
  1180. My_wprintf(L"%s", KeyName);
  1181. if ( Value && Len > 0 ) {
  1182. if ( Len > 30 ) {
  1183. My_wprintf(L"\n");
  1184. } else {
  1185. My_wprintf(L"\t");
  1186. }
  1187. if ( iswprint(Value[0]) ) {
  1188. My_wprintf(L"%c%s\n", Value[0], (Len>1) ? Value+1 : L"");
  1189. } else {
  1190. pb = (BYTE *)Value;
  1191. My_wprintf(L"%d %d ", pb[1], pb[0]);
  1192. /*
  1193. if ( isprint( pc[0] ) ) {
  1194. My_printf("%c ", pc[0] );
  1195. } else {
  1196. My_printf("%d ", (int)(pc[0]) );
  1197. }
  1198. if ( isprint( pc[1] ) ) {
  1199. My_printf("%c ", pc[1] );
  1200. } else {
  1201. My_printf("%d ", (int)pc[1] );
  1202. }
  1203. */
  1204. if ( Len > 1 && Value[1] != L'\0' ) {
  1205. My_wprintf(L"%s\n", Value+1);
  1206. } else {
  1207. My_wprintf(L"No value\n");
  1208. }
  1209. }
  1210. } else {
  1211. My_wprintf(L"\n");
  1212. }
  1213. } else {
  1214. My_wprintf(L"\n");
  1215. }
  1216. return(TRUE);
  1217. }
  1218. /***
  1219. * My_wprintf(format) - print formatted data
  1220. *
  1221. * Prints Unicode formatted string to console window using WriteConsoleW.
  1222. * Note: This My_wprintf() is used to workaround the problem in c-runtime
  1223. * which looks up LC_CTYPE even for Unicode string.
  1224. *
  1225. */
  1226. int __cdecl
  1227. My_wprintf(
  1228. const wchar_t *format,
  1229. ...
  1230. )
  1231. {
  1232. DWORD cchWChar = 0;
  1233. DWORD dwBytesWritten;
  1234. va_list args;
  1235. va_start( args, format );
  1236. cchWChar = My_vfwprintf(stdout, format, args);
  1237. va_end(args);
  1238. return cchWChar;
  1239. }
  1240. /***
  1241. * My_fwprintf(stream, format) - print formatted data
  1242. *
  1243. * Prints Unicode formatted string to console window using WriteConsoleW.
  1244. * Note: This My_fwprintf() is used to workaround the problem in c-runtime
  1245. * which looks up LC_CTYPE even for Unicode string.
  1246. *
  1247. */
  1248. int __cdecl
  1249. My_fwprintf(
  1250. FILE *str,
  1251. const wchar_t *format,
  1252. ...
  1253. )
  1254. {
  1255. DWORD cchWChar = 0;
  1256. va_list args;
  1257. va_start( args, format );
  1258. cchWChar = My_vfwprintf(str, format, args);
  1259. va_end(args);
  1260. return cchWChar;
  1261. }
  1262. int __cdecl
  1263. My_vfwprintf(
  1264. FILE *str,
  1265. const wchar_t *format,
  1266. va_list argptr
  1267. )
  1268. {
  1269. HANDLE hOut;
  1270. // if the /quiet option is specified, suppress printing to stdout
  1271. // and instead print to the logfile. If logfile not specified
  1272. // don't print at all
  1273. if (dOptions & SCE_DISABLE_LOG){
  1274. DWORD cchWChar = 0;
  1275. LPTSTR szBufferMessage = (LPTSTR) LocalAlloc (LPTR, 2048 * sizeof(TCHAR));
  1276. if (szBufferMessage) {
  1277. vswprintf( szBufferMessage, format, argptr );
  1278. cchWChar = wcslen(szBufferMessage);
  1279. // remove trailing LFs
  1280. if (szBufferMessage[cchWChar-1] == L'\n')
  1281. szBufferMessage[cchWChar-1] = L'\0';
  1282. // remove leading LFs
  1283. if (szBufferMessage[0] == L'\n')
  1284. szBufferMessage[0] = L' ';
  1285. ScepCmdToolLogWrite(szBufferMessage);
  1286. SCE_LOCAL_FREE(szBufferMessage);
  1287. }
  1288. return cchWChar;
  1289. }
  1290. if (str == stderr) {
  1291. hOut = GetStdHandle(STD_ERROR_HANDLE);
  1292. }
  1293. else {
  1294. hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  1295. }
  1296. if ((GetFileType(hOut) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR) {
  1297. DWORD cchWChar;
  1298. WCHAR szBufferMessage[1024];
  1299. vswprintf( szBufferMessage, format, argptr );
  1300. cchWChar = wcslen(szBufferMessage);
  1301. WriteConsoleW(hOut, szBufferMessage, cchWChar, &cchWChar, NULL);
  1302. return cchWChar;
  1303. }
  1304. return fwprintf(str, format, argptr);
  1305. }
  1306. ///////////////////////////////////////////////////////////////////////////////
  1307. // This function is to suppress printf if the /quiet option is specified
  1308. ///////////////////////////////////////////////////////////////////////////////
  1309. int __cdecl
  1310. My_printf(
  1311. const char *format,
  1312. ...
  1313. )
  1314. {
  1315. int cchChar = 0;
  1316. va_list argptr;
  1317. va_start( argptr, format );
  1318. cchChar = printf(format, argptr);
  1319. va_end(argptr);
  1320. return cchChar;
  1321. }
  1322. ///////////////////////////////////////////////////////////////////////////////
  1323. // This function takes the user string that is supplied at the command line
  1324. // and converts it into full path names for eg. it takes ..\%windir%\hisecws.inf
  1325. // and converts it to C:\winnt\security\templates\hisecws.inf
  1326. ///////////////////////////////////////////////////////////////////////////////
  1327. WCHAR *
  1328. SecEditPConvertToFullPath(
  1329. WCHAR *pUserFilename,
  1330. DWORD *pRetCode
  1331. )
  1332. {
  1333. BOOL NeedCurrDirFlag = TRUE;
  1334. SCESTATUS rc;
  1335. DWORD Len;
  1336. DWORD LenCurrDir;
  1337. PWSTR pCurrentDir = NULL;
  1338. PWSTR pAbsolutePath = NULL;
  1339. PWSTR pAbsolutePathDirOnly = NULL;
  1340. PWSTR pToMerge = NULL;
  1341. PWSTR pLastSlash = NULL;
  1342. WCHAR FirstThree[4];
  1343. WCHAR LineString[256];
  1344. if (pUserFilename == NULL) {
  1345. *pRetCode = 2;
  1346. goto ScePathConvertFuncError;
  1347. }
  1348. // PathIsRoot() works only if exact strings
  1349. // such as C:\ are passed - so need to extract
  1350. wcsncpy(FirstThree, pUserFilename, 3);
  1351. FirstThree[3] = L'\0';
  1352. // if pUserFilename C:\ etc. then we do not need the current directory -
  1353. // Note: extraction hack not needed if PathIsRoot() worked as published
  1354. NeedCurrDirFlag = !PathIsRoot(FirstThree);
  1355. if (NeedCurrDirFlag){
  1356. LenCurrDir = GetCurrentDirectory(0, NULL);
  1357. pCurrentDir = (PWSTR)LocalAlloc(LMEM_ZEROINIT, (LenCurrDir+1)*sizeof(WCHAR));
  1358. if ( pCurrentDir == NULL ) {
  1359. rc = GetLastError();
  1360. LoadString( hMod,
  1361. SECEDITP_OUT_OF_MEMORY,
  1362. LineString,
  1363. 256
  1364. );
  1365. SeceditpErrOut(rc, LineString );
  1366. *pRetCode = 2;
  1367. goto ScePathConvertFuncError;
  1368. }
  1369. GetCurrentDirectory(LenCurrDir, pCurrentDir);
  1370. if (pCurrentDir[LenCurrDir - 2] != L'\\')
  1371. wcscat(pCurrentDir, L"\\");
  1372. }
  1373. // allocate space for string that holds the to-be-expanded string
  1374. Len = wcslen(pUserFilename);
  1375. if (NeedCurrDirFlag)
  1376. Len += LenCurrDir;
  1377. pToMerge = (PWSTR)LocalAlloc(LMEM_ZEROINIT, (Len+1)*sizeof(WCHAR));
  1378. if ( pToMerge == NULL ) {
  1379. rc = GetLastError();
  1380. LoadString( hMod,
  1381. SECEDITP_OUT_OF_MEMORY,
  1382. LineString,
  1383. 256
  1384. );
  1385. SeceditpErrOut(rc, LineString );
  1386. *pRetCode = 2;
  1387. goto ScePathConvertFuncError;
  1388. }
  1389. if (NeedCurrDirFlag)
  1390. wcscat(pToMerge, pCurrentDir);
  1391. wcscat(pToMerge, pUserFilename);
  1392. // allocate space for string that holds the final full path - can't be > wcslen(pToMerge)
  1393. #ifdef DBG
  1394. // shlwapi is lame on chk builds and verifies that the dest buffer is MAX_PATH
  1395. pAbsolutePath = (PWSTR)LocalAlloc(LMEM_ZEROINIT, MAX_PATH*sizeof(WCHAR));
  1396. #else
  1397. pAbsolutePath = (PWSTR)LocalAlloc(LMEM_ZEROINIT, (Len+1)*sizeof(WCHAR));
  1398. #endif
  1399. if ( pAbsolutePath == NULL ) {
  1400. rc = GetLastError();
  1401. LoadString( hMod,
  1402. SECEDITP_OUT_OF_MEMORY,
  1403. LineString,
  1404. 256
  1405. );
  1406. SeceditpErrOut(rc, LineString );
  1407. *pRetCode = 2;
  1408. goto ScePathConvertFuncError;
  1409. }
  1410. // canonicalize pToMerge i.e. collapse all ..\, .\ and merge
  1411. if (PathCanonicalize(pAbsolutePath, pToMerge) == FALSE){
  1412. LoadString( hMod,
  1413. SECEDITP_PATH_NOT_CANONICALIZABLE,
  1414. LineString,
  1415. 256
  1416. );
  1417. My_wprintf(LineString);
  1418. SCE_LOCAL_FREE(pAbsolutePath);
  1419. *pRetCode = 2;
  1420. goto ScePathConvertFuncError;
  1421. }
  1422. // allocate string to verify validity of directory
  1423. pAbsolutePathDirOnly = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((wcslen(pAbsolutePath)+1)*sizeof(WCHAR)));
  1424. if ( pAbsolutePathDirOnly == NULL ) {
  1425. rc = GetLastError();
  1426. LoadString( hMod,
  1427. SECEDITP_OUT_OF_MEMORY,
  1428. LineString,
  1429. 256
  1430. );
  1431. SeceditpErrOut(rc, LineString );
  1432. SCE_LOCAL_FREE(pAbsolutePath);
  1433. *pRetCode = 2;
  1434. goto ScePathConvertFuncError;
  1435. }
  1436. // prepare pAbsolutePathDirOnly to have directory part only
  1437. wcscpy(pAbsolutePathDirOnly, pAbsolutePath);
  1438. pLastSlash = wcsrchr(pAbsolutePathDirOnly, L'\\');
  1439. if (pLastSlash)
  1440. *pLastSlash = L'\0';
  1441. if (PathIsDirectory(pAbsolutePathDirOnly) == FALSE){
  1442. LoadString( hMod,
  1443. SECEDITP_PATH_NOT_VALID,
  1444. LineString,
  1445. 256
  1446. );
  1447. My_wprintf(L"\n%s - %s\n", LineString, pAbsolutePathDirOnly);
  1448. SCE_LOCAL_FREE(pAbsolutePath);
  1449. *pRetCode = 2;
  1450. goto ScePathConvertFuncError;
  1451. }
  1452. ScePathConvertFuncError:
  1453. SCE_LOCAL_FREE(pCurrentDir);
  1454. SCE_LOCAL_FREE(pToMerge);
  1455. SCE_LOCAL_FREE(pAbsolutePathDirOnly);
  1456. return pAbsolutePath;
  1457. }
  1458. ///////////////////////////////////////////////////////////////////////////////
  1459. // This function opens the log file specified and saves the name and its handle
  1460. // in global variables
  1461. ///////////////////////////////////////////////////////////////////////////////
  1462. BOOL
  1463. ScepCmdToolLogInit(
  1464. PWSTR logname
  1465. )
  1466. {
  1467. DWORD rc=NO_ERROR;
  1468. if ( logname && wcslen(logname) > 3 ) {
  1469. hCmdToolLogFile = CreateFile(logname,
  1470. GENERIC_WRITE,
  1471. FILE_SHARE_READ,
  1472. NULL,
  1473. OPEN_ALWAYS,
  1474. FILE_ATTRIBUTE_NORMAL,
  1475. NULL);
  1476. if ( INVALID_HANDLE_VALUE != hCmdToolLogFile ) {
  1477. DWORD dwBytesWritten;
  1478. CHAR TmpBuf[3];
  1479. SetFilePointer (hCmdToolLogFile, 0, NULL, FILE_BEGIN);
  1480. TmpBuf[0] = (CHAR)0xFF;
  1481. TmpBuf[1] = (CHAR)0xFE;
  1482. TmpBuf[2] = '\0';
  1483. WriteFile (hCmdToolLogFile, (LPCVOID)TmpBuf, 2,
  1484. &dwBytesWritten,
  1485. NULL);
  1486. SetFilePointer (hCmdToolLogFile, 0, NULL, FILE_END);
  1487. }
  1488. } else {
  1489. hCmdToolLogFile = INVALID_HANDLE_VALUE;
  1490. }
  1491. if ( hCmdToolLogFile == INVALID_HANDLE_VALUE && (logname != NULL ) ) {
  1492. rc = ERROR_INVALID_NAME;
  1493. }
  1494. if ( INVALID_HANDLE_VALUE != hCmdToolLogFile ) {
  1495. CloseHandle( hCmdToolLogFile );
  1496. }
  1497. hCmdToolLogFile = INVALID_HANDLE_VALUE;
  1498. return(rc);
  1499. }
  1500. VOID
  1501. ScepCmdToolLogWrite(
  1502. PWSTR pErrString
  1503. )
  1504. {
  1505. DWORD cchWChar;
  1506. const TCHAR c_szCRLF[] = TEXT("\r\n");
  1507. if ( LogFile && wcslen(LogFile) > 3 ) {
  1508. hCmdToolLogFile = CreateFile(LogFile,
  1509. GENERIC_WRITE,
  1510. FILE_SHARE_READ,
  1511. NULL,
  1512. OPEN_ALWAYS,
  1513. FILE_ATTRIBUTE_NORMAL,
  1514. NULL);
  1515. if ( INVALID_HANDLE_VALUE != hCmdToolLogFile ) {
  1516. SetFilePointer (hCmdToolLogFile, 0, NULL, FILE_END);
  1517. cchWChar = wcslen( pErrString );
  1518. WriteFile(hCmdToolLogFile,
  1519. (LPCVOID)pErrString,
  1520. sizeof(WCHAR) * cchWChar,
  1521. &cchWChar,
  1522. NULL);
  1523. WriteFile (hCmdToolLogFile, (LPCVOID) c_szCRLF,
  1524. 2 * sizeof(WCHAR),
  1525. &cchWChar,
  1526. NULL);
  1527. // SetFilePointer (hCmdToolLogFile, 0, NULL, FILE_END);
  1528. CloseHandle( hCmdToolLogFile );
  1529. hCmdToolLogFile = INVALID_HANDLE_VALUE;
  1530. return;
  1531. }
  1532. }
  1533. }
  1534. ///////////////////////////////////////////////////////////////////////////////
  1535. // This function closes the log file if there is one opened and
  1536. // clears the log variables
  1537. ///////////////////////////////////////////////////////////////////////////////
  1538. SCESTATUS
  1539. ScepCmdToolLogClose()
  1540. {
  1541. if ( INVALID_HANDLE_VALUE != hCmdToolLogFile ) {
  1542. CloseHandle( hCmdToolLogFile );
  1543. }
  1544. hCmdToolLogFile = INVALID_HANDLE_VALUE;
  1545. return(SCESTATUS_SUCCESS);
  1546. }