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.

2884 lines
93 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. infget.c
  5. Abstract:
  6. Routines to get information from security profiles (INF layout).
  7. Functions from setupapi.lib (setupapi.h), syssetup.lib (syssetup.h),
  8. netlib.lib (netlib.h) for parsing the INF layout are referenced
  9. besides ntdll, ntrtl, and etc.
  10. Author:
  11. Jin Huang (jinhuang) 28-Oct-1996
  12. Revision History:
  13. --*/
  14. #include "headers.h"
  15. #include "scedllrc.h"
  16. #include "infp.h"
  17. #include "sceutil.h"
  18. #include <sddl.h>
  19. #pragma hdrstop
  20. //#define INF_DBG 1
  21. #define SCEINF_OBJECT_FLAG_DSOBJECT 1
  22. #define SCEINF_OBJECT_FLAG_OLDSDDL 2
  23. #define SCEINF_OBJECT_FLAG_UNKNOWN_VERSION 4
  24. BOOL gbClientInDcPromo = FALSE;
  25. //
  26. // Forward references
  27. //
  28. SCESTATUS
  29. SceInfpGetSystemAccess(
  30. IN HINF hInf,
  31. IN DWORD ObjectFlag,
  32. OUT PSCE_PROFILE_INFO pSCEinfo,
  33. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  34. );
  35. SCESTATUS
  36. SceInfpGetUserSettings(
  37. IN HINF hInf,
  38. OUT PSCE_NAME_LIST *pProfileList,
  39. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  40. );
  41. SCESTATUS
  42. SceInfpGetGroupMembership(
  43. IN HINF hInf,
  44. OUT PSCE_GROUP_MEMBERSHIP *pGroupMembership,
  45. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  46. );
  47. SCESTATUS
  48. SceInfpGetObjects(
  49. IN HINF hInf,
  50. IN PCWSTR SectionName,
  51. IN DWORD ObjectFlag,
  52. OUT PSCE_OBJECT_ARRAY *pAllNodes,
  53. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  54. );
  55. SCESTATUS
  56. SceInfpGetOneObjectSecurity(
  57. IN PINFCONTEXT pInfLine,
  58. IN DWORD ObjectFlag,
  59. OUT PSCE_OBJECT_SECURITY *pObject,
  60. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  61. );
  62. SCESTATUS
  63. SceInfpGetAuditLogSetting(
  64. IN HINF hInf,
  65. IN PCWSTR SectionName,
  66. IN DWORD ObjectFlag,
  67. OUT PDWORD LogSize,
  68. OUT PDWORD Periods,
  69. OUT PDWORD RetentionDays,
  70. OUT PDWORD RestrictGuest,
  71. IN OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  72. );
  73. SCESTATUS
  74. SceInfpGetAuditing(
  75. IN HINF hInf,
  76. IN DWORD ObjectFlag,
  77. OUT PSCE_PROFILE_INFO pSCEinfo,
  78. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  79. );
  80. SCESTATUS
  81. SceInfpGetKerberosPolicy(
  82. IN HINF hInf,
  83. IN DWORD ObjectFlag,
  84. OUT PSCE_KERBEROS_TICKET_INFO * ppKerberosInfo,
  85. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  86. );
  87. SCESTATUS
  88. SceInfpGetRegistryValues(
  89. IN HINF hInf,
  90. IN DWORD ObjectFlag,
  91. OUT PSCE_REGISTRY_VALUE_INFO * ppRegValues,
  92. OUT LPDWORD pValueCount,
  93. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  94. );
  95. SCESTATUS
  96. SceInfpGetOneRegistryValue(
  97. IN PINFCONTEXT pInfLine,
  98. IN DWORD ObjectFlag,
  99. OUT PSCE_REGISTRY_VALUE_INFO pValues,
  100. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  101. );
  102. SCESTATUS
  103. SceInfpGetSystemServices(
  104. IN HINF hInf,
  105. IN DWORD ObjectFlag,
  106. OUT PSCE_SERVICES *pServiceList,
  107. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  108. );
  109. //
  110. // function definitions
  111. //
  112. SCESTATUS
  113. SceInfpGetSecurityProfileInfo(
  114. IN HINF hInf,
  115. IN AREA_INFORMATION Area,
  116. OUT PSCE_PROFILE_INFO *ppInfoBuffer,
  117. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  118. )
  119. /**++
  120. Function Description:
  121. This function reads all or part of information from a SCP file in INF
  122. format into the InfoBuffer.
  123. The memory related to the area(s) will be reset/freed before loading
  124. information from the INF file. If the return code is SCESTATUS_SUCCESS,
  125. then the output InfoBuffer contains the requested information. Otherwise,
  126. InfoBuffer contains nothing for the area(s) specified.
  127. Arguments:
  128. hInf - The INF handle to read from.
  129. Area - area(s) for which to get information from
  130. AREA_SECURITY_POLICY
  131. AREA_PRIVILEGES
  132. AREA_USER_SETTINGS
  133. AREA_GROUP_MEMBERSHIP
  134. AREA_REGISTRY_SECURITY
  135. AREA_SYSTEM_SERVICE
  136. AREA_FILE_SECURITY
  137. ppInfoBuffer - The address of SCP profile buffers. If it is NULL, a buffer
  138. will be created which must be freed by SceFreeMemory. The
  139. output is the information requested if successful, or nothing
  140. if fail.
  141. Errlog - A buffer to hold all error codes/text encountered when
  142. parsing the INF file. If Errlog is NULL, no further error
  143. information is returned except the return DWORD
  144. Return Value:
  145. SCESTATUS_SUCCESS
  146. SCESTATUS_PROFILE_NOT_FOUND
  147. SCESTATUS_NOT_ENOUGH_RESOURCE
  148. SCESTATUS_INVALID_PARAMETER
  149. SCESTATUS_BAD_FORMAT
  150. SCESTATUS_INVALID_DATA
  151. -- **/
  152. {
  153. SCESTATUS rc=SCESTATUS_SUCCESS;
  154. UINT Len;
  155. BOOL bFreeMem=FALSE;
  156. DWORD ObjectFlag=0;
  157. //
  158. // if the INF file is not loaded (hInf = 0), then return
  159. //
  160. if ( !hInf ) {
  161. return( SCESTATUS_INVALID_PARAMETER );
  162. }
  163. //
  164. // address for InfoBuffer cannot be NULL
  165. //
  166. if ( ppInfoBuffer == NULL ) {
  167. return( SCESTATUS_INVALID_PARAMETER );
  168. }
  169. //
  170. // if the Area is not valid, then return
  171. //
  172. if ( Area & ~AREA_ALL) {
  173. return( SCESTATUS_INVALID_PARAMETER );
  174. }
  175. if ( *ppInfoBuffer == NULL) {
  176. //
  177. // allocate memory
  178. //
  179. Len = sizeof(SCE_PROFILE_INFO);
  180. *ppInfoBuffer = (PSCE_PROFILE_INFO)ScepAlloc( (UINT)0, Len );
  181. if ( *ppInfoBuffer == NULL ) {
  182. return( SCESTATUS_NOT_ENOUGH_RESOURCE );
  183. }
  184. memset(*ppInfoBuffer, '\0', Len);
  185. (*ppInfoBuffer)->Type = SCE_STRUCT_INF;
  186. ScepResetSecurityPolicyArea(*ppInfoBuffer);
  187. bFreeMem = TRUE;
  188. }
  189. //
  190. // Free related memory and reset the buffer before parsing
  191. // there is a problem here for now. it clears the handle and
  192. // filename too. So comment it out.
  193. SceFreeMemory( (PVOID)(*ppInfoBuffer), Area );
  194. //
  195. // system access
  196. //
  197. INT Revision = 0;
  198. INFCONTEXT InfLine;
  199. if ( SetupFindFirstLine(hInf,L"Version",L"Revision",&InfLine) ) {
  200. if ( !SetupGetIntField(&InfLine, 1, (INT *)&Revision) ) {
  201. Revision = 0;
  202. }
  203. }
  204. if ( Revision == 0) {
  205. ObjectFlag = SCEINF_OBJECT_FLAG_OLDSDDL;
  206. }
  207. if ( Revision > SCE_TEMPLATE_MAX_SUPPORTED_VERSION ) {
  208. ObjectFlag |= SCEINF_OBJECT_FLAG_UNKNOWN_VERSION;
  209. }
  210. if ( Area & AREA_SECURITY_POLICY ) {
  211. rc = SceInfpGetSystemAccess(
  212. hInf,
  213. ObjectFlag,
  214. *ppInfoBuffer,
  215. Errlog
  216. );
  217. if( rc != SCESTATUS_SUCCESS )
  218. goto Done;
  219. //
  220. // system auditing
  221. //
  222. rc = SceInfpGetAuditing(
  223. hInf,
  224. ObjectFlag,
  225. *ppInfoBuffer,
  226. Errlog
  227. );
  228. if( rc != SCESTATUS_SUCCESS )
  229. goto Done;
  230. //
  231. // kerberos policy
  232. //
  233. rc = SceInfpGetKerberosPolicy(
  234. hInf,
  235. ObjectFlag,
  236. &((*ppInfoBuffer)->pKerberosInfo),
  237. Errlog
  238. );
  239. if( rc != SCESTATUS_SUCCESS )
  240. goto Done;
  241. //
  242. // registry values
  243. //
  244. rc = SceInfpGetRegistryValues(
  245. hInf,
  246. ObjectFlag,
  247. &((*ppInfoBuffer)->aRegValues),
  248. &((*ppInfoBuffer)->RegValueCount),
  249. Errlog
  250. );
  251. if( rc != SCESTATUS_SUCCESS )
  252. goto Done;
  253. }
  254. //
  255. // privilege/rights
  256. //
  257. if ( Area & AREA_PRIVILEGES ) {
  258. rc = SceInfpGetPrivileges(
  259. hInf,
  260. gbClientInDcPromo ? FALSE: TRUE,
  261. &( (*ppInfoBuffer)->OtherInfo.scp.u.pInfPrivilegeAssignedTo ),
  262. Errlog
  263. );
  264. if( rc != SCESTATUS_SUCCESS )
  265. goto Done;
  266. }
  267. //
  268. // account profiles list
  269. //
  270. if ( Area & AREA_USER_SETTINGS ) {
  271. rc = SceInfpGetUserSettings(
  272. hInf,
  273. &( (*ppInfoBuffer)->OtherInfo.scp.pAccountProfiles ),
  274. Errlog
  275. );
  276. if( rc != SCESTATUS_SUCCESS )
  277. goto Done;
  278. }
  279. //
  280. // group memberships
  281. //
  282. if ( Area & AREA_GROUP_MEMBERSHIP ) {
  283. rc = SceInfpGetGroupMembership(
  284. hInf,
  285. &((*ppInfoBuffer)->pGroupMembership),
  286. Errlog
  287. );
  288. if( rc != SCESTATUS_SUCCESS )
  289. goto Done;
  290. }
  291. //
  292. // registry keys security
  293. //
  294. if ( Area & AREA_REGISTRY_SECURITY ) {
  295. rc = SceInfpGetObjects(
  296. hInf,
  297. szRegistryKeys,
  298. ObjectFlag,
  299. &((*ppInfoBuffer)->pRegistryKeys.pAllNodes),
  300. Errlog
  301. );
  302. if ( rc != SCESTATUS_SUCCESS )
  303. goto Done;
  304. }
  305. //
  306. // system services
  307. //
  308. if ( Area & AREA_SYSTEM_SERVICE ) {
  309. rc = SceInfpGetSystemServices(
  310. hInf,
  311. ObjectFlag,
  312. &((*ppInfoBuffer)->pServices),
  313. Errlog
  314. );
  315. if( rc != SCESTATUS_SUCCESS )
  316. goto Done;
  317. }
  318. //
  319. // file security
  320. //
  321. if ( Area & AREA_FILE_SECURITY ) {
  322. rc = SceInfpGetObjects(
  323. hInf,
  324. szFileSecurity,
  325. ObjectFlag,
  326. &((*ppInfoBuffer)->pFiles.pAllNodes),
  327. Errlog
  328. );
  329. if ( rc != SCESTATUS_SUCCESS )
  330. goto Done;
  331. }
  332. #if 0
  333. if ( Area & AREA_DS_OBJECTS ) {
  334. rc = SceInfpGetObjects(
  335. hInf,
  336. szDSSecurity,
  337. ObjectFlag | SCEINF_OBJECT_FLAG_DSOBJECT,
  338. &((*ppInfoBuffer)->pDsObjects.pAllNodes),
  339. Errlog
  340. );
  341. if ( rc != SCESTATUS_SUCCESS )
  342. goto Done;
  343. }
  344. #endif
  345. Done:
  346. if ( rc != SCESTATUS_SUCCESS ) {
  347. //
  348. // need free memory because some fatal error happened
  349. //
  350. SceFreeMemory( (PVOID)(*ppInfoBuffer), Area );
  351. if ( bFreeMem ) {
  352. ScepFree(*ppInfoBuffer);
  353. *ppInfoBuffer = NULL;
  354. }
  355. }
  356. return(rc);
  357. }
  358. SCESTATUS
  359. SceInfpGetSystemAccess(
  360. IN HINF hInf,
  361. IN DWORD ObjectFlag,
  362. OUT PSCE_PROFILE_INFO pSCEinfo,
  363. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  364. )
  365. /*++
  366. Routine Description:
  367. This routine retrieves system access area information from the SCP INF
  368. file and stores in the output buffer pSCEinfo. System access information
  369. includes information in [System Access] section.
  370. Arguments:
  371. hInf - INF handle to the profile
  372. pSCEinfo - the output buffer to hold profile info.
  373. Errlog - A buffer to hold all error codes/text encountered when
  374. parsing the INF file. If Errlog is NULL, no further error
  375. information is returned except the return DWORD
  376. Return value:
  377. SCESTATUS - SCESTATUS_SUCCESS
  378. SCESTATUS_NOT_ENOUGH_RESOURCE
  379. SCESTATUS_INVALID_PARAMETER
  380. SCESTATUS_BAD_FORMAT
  381. SCESTATUS_INVALID_DATA
  382. --*/
  383. {
  384. INFCONTEXT InfLine;
  385. SCESTATUS rc=SCESTATUS_SUCCESS;
  386. DWORD Keyvalue=0;
  387. DWORD DataSize=0;
  388. PWSTR Strvalue=NULL;
  389. SCE_KEY_LOOKUP AccessSCPLookup[] = {
  390. {(PWSTR)TEXT("MinimumPasswordAge"), offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordAge), 'D'},
  391. {(PWSTR)TEXT("MaximumPasswordAge"), offsetof(struct _SCE_PROFILE_INFO, MaximumPasswordAge), 'D'},
  392. {(PWSTR)TEXT("MinimumPasswordLength"), offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordLength), 'D'},
  393. {(PWSTR)TEXT("PasswordComplexity"), offsetof(struct _SCE_PROFILE_INFO, PasswordComplexity), 'D'},
  394. {(PWSTR)TEXT("PasswordHistorySize"), offsetof(struct _SCE_PROFILE_INFO, PasswordHistorySize), 'D'},
  395. {(PWSTR)TEXT("LockoutBadCount"), offsetof(struct _SCE_PROFILE_INFO, LockoutBadCount), 'D'},
  396. {(PWSTR)TEXT("ResetLockoutCount"), offsetof(struct _SCE_PROFILE_INFO, ResetLockoutCount), 'D'},
  397. {(PWSTR)TEXT("LockoutDuration"), offsetof(struct _SCE_PROFILE_INFO, LockoutDuration), 'D'},
  398. {(PWSTR)TEXT("RequireLogonToChangePassword"), offsetof(struct _SCE_PROFILE_INFO, RequireLogonToChangePassword), 'D'},
  399. {(PWSTR)TEXT("ForceLogoffWhenHourExpire"), offsetof(struct _SCE_PROFILE_INFO, ForceLogoffWhenHourExpire), 'D'},
  400. {(PWSTR)TEXT("NewAdministratorName"), 0, 'A'},
  401. {(PWSTR)TEXT("NewGuestName"), 0, 'G'},
  402. {(PWSTR)TEXT("SecureSystemPartition"), offsetof(struct _SCE_PROFILE_INFO, SecureSystemPartition), 'D'},
  403. {(PWSTR)TEXT("ClearTextPassword"), offsetof(struct _SCE_PROFILE_INFO, ClearTextPassword), 'D'},
  404. {(PWSTR)TEXT("LSAAnonymousNameLookup"), offsetof(struct _SCE_PROFILE_INFO, LSAAnonymousNameLookup), 'D'},
  405. {(PWSTR)TEXT("EnableAdminAccount"), offsetof(struct _SCE_PROFILE_INFO, EnableAdminAccount), 'D'},
  406. {(PWSTR)TEXT("EnableGuestAccount"), offsetof(struct _SCE_PROFILE_INFO, EnableGuestAccount), 'D'}
  407. };
  408. DWORD cAccess = sizeof(AccessSCPLookup) / sizeof(SCE_KEY_LOOKUP);
  409. DWORD i;
  410. UINT Offset;
  411. WCHAR Keyname[SCE_KEY_MAX_LENGTH];
  412. //
  413. // Initialize to SCE_NO_VALUE
  414. //
  415. for ( i=0; i<cAccess; i++) {
  416. if ( AccessSCPLookup[i].BufferType == 'D' )
  417. *((DWORD *)((CHAR *)pSCEinfo+AccessSCPLookup[i].Offset)) = SCE_NO_VALUE;
  418. }
  419. //
  420. // Locate the [System Access] section.
  421. //
  422. if(SetupFindFirstLine(hInf,szSystemAccess,NULL,&InfLine)) {
  423. do {
  424. //
  425. // Get key names and its setting.
  426. //
  427. rc = SCESTATUS_SUCCESS;
  428. memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
  429. if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) ) {
  430. for ( i=0; i<cAccess; i++) {
  431. //
  432. // get settings in AccessLookup table
  433. //
  434. Offset = AccessSCPLookup[i].Offset;
  435. if (_wcsicmp(Keyname, AccessSCPLookup[i].KeyString ) == 0) {
  436. switch ( AccessSCPLookup[i].BufferType ) {
  437. case 'B':
  438. //
  439. // Int Field
  440. //
  441. Keyvalue = 0;
  442. SetupGetIntField( &InfLine, 1, (INT *)&Keyvalue );
  443. *((BOOL *)((CHAR *)pSCEinfo+Offset)) = Keyvalue ? TRUE : FALSE;
  444. break;
  445. case 'D':
  446. //
  447. // Int Field
  448. //
  449. if (SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) )
  450. *((DWORD *)((CHAR *)pSCEinfo+Offset)) = (DWORD)Keyvalue;
  451. break;
  452. default:
  453. //
  454. // String Field - NewAdministratorName, or NewGuestName
  455. //
  456. if(SetupGetStringField(&InfLine,1,NULL,0,&DataSize) && DataSize > 0) {
  457. Strvalue = (PWSTR)ScepAlloc( 0, (DataSize+1)*sizeof(WCHAR));
  458. if( Strvalue == NULL ) {
  459. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  460. } else {
  461. Strvalue[DataSize] = L'\0';
  462. if(SetupGetStringField(&InfLine,1,Strvalue,DataSize, NULL)) {
  463. if ( Strvalue[0] != L'\0' && Strvalue[0] != L' ') {
  464. if (AccessSCPLookup[i].BufferType == 'A') // administrator
  465. pSCEinfo->NewAdministratorName = Strvalue;
  466. else // guest
  467. pSCEinfo->NewGuestName = Strvalue;
  468. } else
  469. ScepFree(Strvalue);
  470. Strvalue = NULL;
  471. } else {
  472. ScepFree( Strvalue );
  473. rc = SCESTATUS_BAD_FORMAT;
  474. }
  475. }
  476. } else
  477. rc = SCESTATUS_BAD_FORMAT;
  478. break;
  479. }
  480. break; // for loop
  481. }
  482. }
  483. if ( i >= cAccess &&
  484. !(ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) ) {
  485. //
  486. // Did not find a match in the lookup table
  487. //
  488. ScepBuildErrorLogInfo( NO_ERROR,
  489. Errlog,
  490. SCEERR_NOT_EXPECTED,
  491. Keyname,szSystemAccess );
  492. }
  493. if ( rc != SCESTATUS_SUCCESS ) {
  494. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc),
  495. Errlog,
  496. SCEERR_QUERY_INFO,
  497. Keyname );
  498. }
  499. } else {
  500. rc = SCESTATUS_INVALID_DATA;
  501. ScepBuildErrorLogInfo( ERROR_INVALID_DATA, Errlog,
  502. SCEERR_QUERY_INFO,
  503. szSystemAccess);
  504. }
  505. //
  506. // if error happens, get out
  507. //
  508. if ( rc != SCESTATUS_SUCCESS )
  509. return(rc);
  510. } while(SetupFindNextLine(&InfLine,&InfLine));
  511. }
  512. return(rc);
  513. }
  514. SCESTATUS
  515. SceInfpGetUserSettings(
  516. IN HINF hInf,
  517. OUT PSCE_NAME_LIST *pProfileList,
  518. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  519. )
  520. /* ++
  521. Routine Description:
  522. This routine retrieves account profile list from the INF file (SCP) and
  523. stores in the output buffer pProfileList.
  524. Arguments:
  525. hInf - INF handle to the profile
  526. pProfileList - the output buffer to hold account profile list.
  527. Errlog - The error list encountered inside inf processing.
  528. Return value:
  529. SCESTATUS - SCESTATUS_SUCCESS
  530. SCESTATUS_NOT_ENOUGH_RESOURCE
  531. SCESTATUS_INVALID_PARAMETER
  532. SCESTATUS_BAD_FORMAT
  533. SCESTATUS_INVALID_DATA
  534. -- */
  535. {
  536. INFCONTEXT InfLine;
  537. SCESTATUS rc=SCESTATUS_SUCCESS;
  538. WCHAR Keyname[SCE_KEY_MAX_LENGTH];
  539. //
  540. // [Account Profiles] section
  541. //
  542. if(SetupFindFirstLine(hInf,szAccountProfiles,NULL,&InfLine)) {
  543. do {
  544. memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
  545. if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) ) {
  546. //
  547. // find a key name which is a profile name.
  548. //
  549. rc = ScepAddToNameList(pProfileList, Keyname, 0);
  550. if ( rc != SCESTATUS_SUCCESS ) {
  551. ScepBuildErrorLogInfo(ERROR_INVALID_DATA,
  552. Errlog,
  553. SCEERR_ADD,
  554. Keyname );
  555. }
  556. } else {
  557. ScepBuildErrorLogInfo(ERROR_BAD_FORMAT,
  558. Errlog,
  559. SCEERR_QUERY_INFO,
  560. L"profile name"
  561. );
  562. rc = SCESTATUS_BAD_FORMAT;
  563. }
  564. } while( rc == SCESTATUS_SUCCESS &&
  565. SetupFindNextLine(&InfLine,&InfLine));
  566. }
  567. return(rc);
  568. }
  569. SCESTATUS
  570. SceInfpGetGroupMembership(
  571. IN HINF hInf,
  572. OUT PSCE_GROUP_MEMBERSHIP *pGroupMembership,
  573. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  574. )
  575. /* ++
  576. Routine Description:
  577. This routine retrieves group membership information from the SCP INF file
  578. and stores in the output buffer pGroupMembership. Group membership info is
  579. in [Group Membership] section.
  580. Arguments:
  581. hInf - INF handle to the profile
  582. pGroupMembership - the output buffer to hold group membersip information.
  583. Errlog - the error list for errors encountered in this routine.
  584. Return value:
  585. SCESTATUS - SCESTATUS_SUCCESS
  586. SCESTATUS_NOT_ENOUGH_RESOURCE
  587. SCESTATUS_INVALID_PARAMETER
  588. SCESTATUS_BAD_FORMAT
  589. SCESTATUS_INVALID_DATA
  590. -- */
  591. {
  592. INFCONTEXT InfLine;
  593. PSCE_NAME_LIST pMembers=NULL;
  594. SCESTATUS rc=SCESTATUS_SUCCESS;
  595. PWSTR Keyname=NULL;
  596. DWORD KeyLen;
  597. DWORD ValueType;
  598. PWSTR pTemp;
  599. DWORD i;
  600. DWORD cFields;
  601. DWORD DataSize;
  602. PWSTR Strvalue=NULL;
  603. PWSTR GroupName=NULL;
  604. DWORD GroupLen;
  605. if ( pGroupMembership == NULL )
  606. return(SCESTATUS_INVALID_PARAMETER);
  607. LSA_HANDLE LsaHandle=NULL;
  608. //
  609. // Locate the [Group MemberShip] section.
  610. //
  611. if ( SetupFindFirstLine(hInf,szGroupMembership,NULL,&InfLine) ) {
  612. //
  613. // open lsa policy handle for sid/name lookup
  614. //
  615. rc = RtlNtStatusToDosError(
  616. ScepOpenLsaPolicy(
  617. POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION,
  618. &LsaHandle,
  619. TRUE
  620. ));
  621. if ( ERROR_SUCCESS != rc ) {
  622. ScepBuildErrorLogInfo(
  623. rc,
  624. Errlog,
  625. SCEERR_ADD,
  626. TEXT("LSA")
  627. );
  628. return(ScepDosErrorToSceStatus(rc));
  629. }
  630. PSID pSid=NULL;
  631. do {
  632. //
  633. // Get group names.
  634. //
  635. rc = SCESTATUS_BAD_FORMAT;
  636. if ( SetupGetStringField(&InfLine, 0, NULL, 0, &KeyLen) ) {
  637. Keyname = (PWSTR)ScepAlloc( 0, (KeyLen+1)*sizeof(WCHAR));
  638. if ( Keyname == NULL ) {
  639. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  640. goto Done;
  641. }
  642. Keyname[KeyLen] = L'\0';
  643. if ( SetupGetStringField(&InfLine, 0, Keyname, KeyLen, NULL) ) {
  644. //
  645. // look for what kind of value this line is
  646. //
  647. pTemp = ScepWcstrr(Keyname, szMembers);
  648. ValueType = 0;
  649. if ( pTemp == NULL ) {
  650. pTemp = ScepWcstrr(Keyname, szMemberof);
  651. ValueType = 1;
  652. }
  653. if ( pTemp == NULL ) {
  654. ScepBuildErrorLogInfo( ERROR_INVALID_DATA,
  655. Errlog,
  656. SCEERR_CANT_FIND_KEYWORD,
  657. Keyname
  658. );
  659. rc = SCESTATUS_SUCCESS;
  660. goto NextLine;
  661. }
  662. // terminiate Keyname for the group name only
  663. *pTemp = L'\0';
  664. if ( Keyname[0] == L'*' ) {
  665. //
  666. // *SID format, convert it into group name
  667. //
  668. if ( ConvertStringSidToSid( Keyname+1, &pSid) ) {
  669. //
  670. // if failed to convert from sid string to sid,
  671. // treat it as any name
  672. //
  673. ScepConvertSidToName(
  674. LsaHandle,
  675. pSid,
  676. TRUE,
  677. &GroupName,
  678. &GroupLen
  679. );
  680. LocalFree(pSid);
  681. pSid = NULL;
  682. }
  683. }
  684. if ( GroupName == NULL ) {
  685. GroupLen = (DWORD) (pTemp - Keyname);
  686. }
  687. //
  688. // String fields. Each string respresents a member or memberof name.
  689. //
  690. cFields = SetupGetFieldCount( &InfLine );
  691. for ( i=0; i<cFields; i++) {
  692. if(SetupGetStringField(&InfLine,i+1,NULL,0,&DataSize) && DataSize > 0 ) {
  693. Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  694. (DataSize+1)*sizeof(WCHAR) );
  695. if( Strvalue == NULL ) {
  696. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  697. } else {
  698. if(SetupGetStringField(&InfLine,i+1,Strvalue,DataSize,NULL)) {
  699. //
  700. // Get a member name and save in the list
  701. //
  702. if ( Strvalue[0] == L'*' && DataSize > 0 ) {
  703. //
  704. // this is a SID format, should look it up
  705. //
  706. rc = ScepLookupSidStringAndAddToNameList(
  707. LsaHandle,
  708. &pMembers,
  709. Strvalue, // +1,
  710. DataSize // -1
  711. );
  712. } else {
  713. rc = ScepAddToNameList(&pMembers,
  714. Strvalue,
  715. DataSize+1
  716. );
  717. }
  718. }
  719. ScepFree( Strvalue );
  720. Strvalue = NULL;
  721. }
  722. }
  723. if ( rc != SCESTATUS_SUCCESS)
  724. break; // for loop
  725. } // end of for loop
  726. if ( rc == SCESTATUS_SUCCESS ) { // && pMembers != NULL ) {
  727. //
  728. // add this list to the group
  729. //
  730. rc = ScepAddToGroupMembership(
  731. pGroupMembership,
  732. GroupName ? GroupName : Keyname,
  733. GroupLen, // wcslen(Keyname),
  734. pMembers,
  735. ValueType,
  736. TRUE,
  737. TRUE
  738. );
  739. if ( rc == SCESTATUS_SUCCESS )
  740. pMembers = NULL;
  741. }
  742. // restore the character
  743. *pTemp = L'_';
  744. }
  745. }
  746. if ( rc != SCESTATUS_SUCCESS ) {
  747. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
  748. Errlog,
  749. SCEERR_QUERY_INFO,
  750. szGroupMembership
  751. );
  752. goto Done;
  753. }
  754. NextLine:
  755. //
  756. // Free pMembers, Keyname
  757. //
  758. ScepFreeNameList(pMembers);
  759. pMembers = NULL;
  760. ScepFree(Keyname);
  761. Keyname = NULL;
  762. if ( GroupName ) {
  763. LocalFree(GroupName);
  764. GroupName = NULL;
  765. }
  766. } while(SetupFindNextLine(&InfLine,&InfLine));
  767. }
  768. Done:
  769. //
  770. // Free pMembers, Keyname
  771. //
  772. ScepFreeNameList(pMembers);
  773. if ( Keyname != NULL )
  774. ScepFree(Keyname);
  775. if ( Strvalue != NULL )
  776. ScepFree( Strvalue );
  777. if ( LsaHandle ) {
  778. LsaClose(LsaHandle);
  779. }
  780. if ( GroupName ) {
  781. LocalFree(GroupName);
  782. }
  783. return(rc);
  784. }
  785. SCESTATUS
  786. SceInfpGetObjects(
  787. IN HINF hInf,
  788. IN PCWSTR SectionName,
  789. IN DWORD ObjectFlag,
  790. OUT PSCE_OBJECT_ARRAY *pAllNodes,
  791. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  792. )
  793. /* ++
  794. Routine Description:
  795. This routine retrieves registry or files security information (names and
  796. security descriptors) from the INF file (SCP and SAP) and stores in the
  797. output buffer pSCEinfo. Registry information is in [SCRegistryKeysSecurity]
  798. section. Files information is in [SSFileSecurity], [SCIntel86Only], and
  799. [SCRISCOnly] sections. These sections have the same format, namely, 3 fields
  800. on each line - name, workstaiton setting, and server setting.
  801. Arguments:
  802. hInf - INF handle to the profile
  803. SectionName - the section name to retrieve.
  804. pAllNodes - the output buffer to hold all objects in the section.
  805. Errlog - the cummulative error list to hold errors encountered in this routine.
  806. Return value:
  807. SCESTATUS - SCESTATUS_SUCCESS
  808. SCESTATUS_NOT_ENOUGH_RESOURCE
  809. SCESTATUS_INVALID_PARAMETER
  810. SCESTATUS_BAD_FORMAT
  811. SCESTATUS_INVALID_DATA
  812. -- */
  813. {
  814. INFCONTEXT InfLine;
  815. SCESTATUS rc=SCESTATUS_SUCCESS;
  816. LONG i;
  817. LONG nLines;
  818. DWORD cFields;
  819. if ( pAllNodes == NULL || SectionName == NULL )
  820. return(SCESTATUS_INVALID_PARAMETER);
  821. //
  822. // count how many objects
  823. //
  824. nLines = SetupGetLineCount(hInf, SectionName );
  825. if ( nLines == -1 ) {
  826. // section not found
  827. return(SCESTATUS_SUCCESS);
  828. }
  829. *pAllNodes = (PSCE_OBJECT_ARRAY)ScepAlloc(0, sizeof(SCE_OBJECT_ARRAY));
  830. if ( *pAllNodes == NULL )
  831. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  832. (*pAllNodes)->Count = nLines;
  833. (*pAllNodes)->pObjectArray = NULL;
  834. if ( nLines == 0 )
  835. return(SCESTATUS_SUCCESS);
  836. //
  837. // allocate memory for all objects
  838. //
  839. (*pAllNodes)->pObjectArray = (PSCE_OBJECT_SECURITY *)ScepAlloc( LMEM_ZEROINIT,
  840. nLines*sizeof(PSCE_OBJECT_SECURITY) );
  841. if ( (*pAllNodes)->pObjectArray == NULL ) {
  842. ScepFree(*pAllNodes);
  843. *pAllNodes = NULL;
  844. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  845. }
  846. //
  847. // Locate the section.
  848. //
  849. if ( SetupFindFirstLine(hInf,SectionName,NULL,&InfLine) ) {
  850. i = 0;
  851. TCHAR tmpBuf[MAX_PATH];
  852. do {
  853. //
  854. // Get string fields. Don't care the key name or if it exist.
  855. // Must have 3 fields each line for supported versions.
  856. //
  857. cFields = SetupGetFieldCount( &InfLine );
  858. if ( cFields < 3 ) {
  859. tmpBuf[0] = L'\0';
  860. SetupGetStringField(&InfLine,1,tmpBuf,MAX_PATH,NULL);
  861. ScepBuildErrorLogInfo( ERROR_INVALID_DATA,
  862. Errlog,
  863. SCEERR_OBJECT_FIELDS,
  864. tmpBuf);
  865. if (ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) {
  866. //
  867. // maybe a new format for object,
  868. // ignore this line
  869. //
  870. rc = SCESTATUS_SUCCESS;
  871. goto NextLine;
  872. } else {
  873. rc = SCESTATUS_INVALID_DATA;
  874. }
  875. }
  876. if ( SCESTATUS_SUCCESS == rc ) {
  877. rc = SceInfpGetOneObjectSecurity(
  878. &InfLine,
  879. ObjectFlag,
  880. ( (*pAllNodes)->pObjectArray + i ),
  881. Errlog
  882. );
  883. }
  884. if ( rc != SCESTATUS_SUCCESS ) {
  885. if ( rc == SCESTATUS_BAD_FORMAT ) {
  886. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
  887. Errlog,
  888. SCEERR_QUERY_INFO,
  889. SectionName);
  890. }
  891. break; // do..while loop
  892. }
  893. i++;
  894. NextLine:
  895. if ( i > nLines ) {
  896. // more lines than allocated
  897. rc = SCESTATUS_INVALID_DATA;
  898. ScepBuildErrorLogInfo(ERROR_INVALID_DATA,
  899. Errlog,
  900. SCEERR_MORE_OBJECTS,
  901. nLines
  902. );
  903. break;
  904. }
  905. } while(SetupFindNextLine(&InfLine,&InfLine));
  906. }
  907. if ( rc != SCESTATUS_SUCCESS ) {
  908. // free memory
  909. ScepFreeObjectSecurity( *pAllNodes );
  910. // ScepFree( *pAllNodes );
  911. *pAllNodes = NULL;
  912. } else if ( ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION ) {
  913. //
  914. // reset the count because some lines may be skipped
  915. //
  916. (*pAllNodes)->Count = i;
  917. }
  918. return(rc);
  919. }
  920. SCESTATUS
  921. SceInfpGetOneObjectSecurity(
  922. IN PINFCONTEXT pInfLine,
  923. IN DWORD ObjectFlag,
  924. OUT PSCE_OBJECT_SECURITY *ppObject,
  925. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  926. )
  927. /* ++
  928. Routine Description:
  929. This routine retrieves security setting for one object (a registry key,
  930. or a file) from the INF file (SCP type). Each object in these sections
  931. is represented by one line. Each object has 3 fields, a name, a status
  932. flag, and security setting. This routine stores the output in buffer
  933. ppObject.
  934. Arguments:
  935. pInfLine - Current line context from the INF file for one object
  936. ppObject - Output buffer (tree root ) to hold the security settings for this line
  937. Errlog - The cummulative error list for errors encountered in this routine
  938. Return value:
  939. SCESTATUS - SCESTATUS_SUCCESS
  940. SCESTATUS_NOT_ENOUGH_RESOURCE
  941. SCESTATUS_INVALID_PARAMETER
  942. SCESTATUS_BAD_FORMAT
  943. SCESTATUS_INVALID_DATA
  944. -- */
  945. {
  946. DWORD cFields;
  947. DWORD DataSize;
  948. PWSTR Strvalue=NULL;
  949. PWSTR SDspec=NULL;
  950. DWORD SDsize;
  951. DWORD Status=0;
  952. PSECURITY_DESCRIPTOR pTempSD=NULL;
  953. SECURITY_INFORMATION SeInfo;
  954. SCESTATUS rc=SCESTATUS_SUCCESS;
  955. //
  956. // The Registry/File INF layout must have 3 fields for each line.
  957. // The first field is the key/file name, the 2nd field is status flag -
  958. // ignore, or check, and the 3rd field is the security descriptor text
  959. //
  960. if ( ppObject == NULL )
  961. return(SCESTATUS_INVALID_PARAMETER);
  962. cFields = SetupGetFieldCount( pInfLine );
  963. if ( cFields < 3 ) {
  964. return(SCESTATUS_INVALID_DATA);
  965. } else if(SetupGetStringField(pInfLine,1,NULL,0,&DataSize) && DataSize > 0 ) {
  966. Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  967. (DataSize+1)*sizeof(WCHAR) );
  968. if( Strvalue == NULL ) {
  969. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  970. } else {
  971. //
  972. // the first field is the key/file name.
  973. // The 2nd is a status flag.
  974. // The 3rd field is the security descriptor text
  975. //
  976. if( SetupGetStringField(pInfLine,1,Strvalue,DataSize,NULL) &&
  977. SetupGetIntField( pInfLine, 2, (INT *)&Status ) &&
  978. // SetupGetStringField(pInfLine,3,NULL,0,&SDsize) ) {
  979. SetupGetMultiSzField(pInfLine,3,NULL,0,&SDsize) ) {
  980. SDspec = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  981. (SDsize+1)*sizeof(WCHAR)
  982. );
  983. if( SDspec == NULL ) {
  984. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  985. goto Done;
  986. }
  987. // if(SetupGetStringField(pInfLine,3,SDspec,SDsize,NULL)) {
  988. if(SetupGetMultiSzField(pInfLine,3,SDspec,SDsize,NULL)) {
  989. //
  990. // convert the multi-sz delimiter to space, if there is any
  991. //
  992. if ( cFields > 3 ) {
  993. ScepConvertMultiSzToDelim(SDspec, SDsize, L'\0', L' ');
  994. }
  995. if ( ObjectFlag & SCEINF_OBJECT_FLAG_OLDSDDL ) {
  996. ScepConvertToSDDLFormat(SDspec, SDsize);
  997. }
  998. //
  999. // Convert the text to real security descriptors
  1000. //
  1001. rc = ConvertTextSecurityDescriptor(
  1002. SDspec,
  1003. &pTempSD,
  1004. &SDsize,
  1005. &SeInfo
  1006. );
  1007. if (rc == NO_ERROR) {
  1008. // create a new object node to hold these info.
  1009. if ( !(ObjectFlag & SCEINF_OBJECT_FLAG_DSOBJECT) ) {
  1010. ScepChangeAclRevision(pTempSD, ACL_REVISION);
  1011. }
  1012. *ppObject = (PSCE_OBJECT_SECURITY)ScepAlloc(0, sizeof(SCE_OBJECT_SECURITY));
  1013. if ( *ppObject == NULL )
  1014. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1015. else {
  1016. (*ppObject)->Name = Strvalue;
  1017. (*ppObject)->Status = (BYTE)Status;
  1018. (*ppObject)->IsContainer = TRUE; // always default to TRUE
  1019. (*ppObject)->pSecurityDescriptor = pTempSD;
  1020. (*ppObject)->SeInfo = SeInfo;
  1021. pTempSD = NULL;
  1022. // (*ppObject)->SDspec = SDspec;
  1023. // (*ppObject)->SDsize = SDsize;
  1024. Strvalue = NULL;
  1025. // SDspec = NULL;
  1026. rc = SCESTATUS_SUCCESS;
  1027. }
  1028. } else {
  1029. ScepBuildErrorLogInfo(rc,
  1030. Errlog,
  1031. SCEERR_BUILD_SD,
  1032. Strvalue);
  1033. rc = ScepDosErrorToSceStatus(rc);
  1034. }
  1035. } else
  1036. rc = SCESTATUS_BAD_FORMAT;
  1037. } else
  1038. rc = SCESTATUS_BAD_FORMAT;
  1039. }
  1040. } else
  1041. rc = SCESTATUS_BAD_FORMAT;
  1042. Done:
  1043. if ( Strvalue != NULL )
  1044. ScepFree( Strvalue );
  1045. if ( SDspec != NULL )
  1046. ScepFree( SDspec );
  1047. if ( pTempSD != NULL )
  1048. ScepFree( pTempSD );
  1049. return(rc);
  1050. }
  1051. SCESTATUS
  1052. SceInfpGetAuditing(
  1053. IN HINF hInf,
  1054. IN DWORD ObjectFlag,
  1055. OUT PSCE_PROFILE_INFO pSCEinfo,
  1056. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  1057. )
  1058. /* ++
  1059. Routine Description:
  1060. This routine retrieves system auditing information from the INF file and
  1061. storesin the output buffer pSCEinfo. The auditing information is stored in
  1062. [System Log], [Security Log], [Application Log], [Event Audit],
  1063. [Registry Audit], and [File Audit] sections.
  1064. Arguments:
  1065. hInf - INF handle to the profile
  1066. pSCEinfo - the output buffer to hold SCP profile info.
  1067. Errlog - The cummulative error list to hold errors encountered in this routine.
  1068. Return value:
  1069. SCESTATUS - SCESTATUS_SUCCESS
  1070. SCESTATUS_NOT_ENOUGH_RESOURCE
  1071. SCESTATUS_INVALID_PARAMETER
  1072. SCESTATUS_BAD_FORMAT
  1073. SCESTATUS_INVALID_DATA
  1074. -- */
  1075. {
  1076. INFCONTEXT InfLine;
  1077. SCESTATUS rc=SCESTATUS_SUCCESS;
  1078. DWORD Keyvalue;
  1079. WCHAR Keyname[SCE_KEY_MAX_LENGTH];
  1080. DWORD LogSize;
  1081. DWORD Periods;
  1082. DWORD RetentionDays;
  1083. DWORD RestrictGuest;
  1084. PCWSTR szAuditLog;
  1085. DWORD i;
  1086. for ( i=0; i<3; i++ ) {
  1087. //
  1088. // Get Event Log setting for system log, security log and application log
  1089. //
  1090. switch (i) {
  1091. case 0:
  1092. szAuditLog = szAuditSystemLog;
  1093. break;
  1094. case 1:
  1095. szAuditLog = szAuditSecurityLog;
  1096. break;
  1097. default:
  1098. szAuditLog = szAuditApplicationLog;
  1099. break;
  1100. }
  1101. LogSize=SCE_NO_VALUE;
  1102. Periods=SCE_NO_VALUE;
  1103. RetentionDays=SCE_NO_VALUE;
  1104. RestrictGuest=SCE_NO_VALUE;
  1105. rc = SceInfpGetAuditLogSetting(
  1106. hInf,
  1107. szAuditLog,
  1108. ObjectFlag,
  1109. &LogSize,
  1110. &Periods,
  1111. &RetentionDays,
  1112. &RestrictGuest,
  1113. Errlog
  1114. );
  1115. if ( rc != SCESTATUS_SUCCESS )
  1116. return(rc);
  1117. pSCEinfo->MaximumLogSize[i] = LogSize;
  1118. pSCEinfo->AuditLogRetentionPeriod[i] = Periods;
  1119. pSCEinfo->RetentionDays[i] = RetentionDays;
  1120. pSCEinfo->RestrictGuestAccess[i] = RestrictGuest;
  1121. }
  1122. //
  1123. // Get Audit Event info
  1124. //
  1125. if ( SetupFindFirstLine(hInf,szAuditEvent,NULL,&InfLine) ) {
  1126. do {
  1127. memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
  1128. if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) &&
  1129. SetupGetIntField( &InfLine, 1, (INT *)&Keyvalue )
  1130. ) {
  1131. if ( _wcsicmp(Keyname, TEXT("AuditSystemEvents")) == 0 ) {
  1132. pSCEinfo->AuditSystemEvents = Keyvalue;
  1133. } else if ( _wcsicmp(Keyname, TEXT("AuditLogonEvents")) == 0 ) {
  1134. pSCEinfo->AuditLogonEvents = Keyvalue;
  1135. } else if ( _wcsicmp(Keyname, TEXT("AuditObjectAccess")) == 0 ) {
  1136. pSCEinfo->AuditObjectAccess = Keyvalue;
  1137. } else if ( _wcsicmp(Keyname, TEXT("AuditPrivilegeUse")) == 0 ) {
  1138. pSCEinfo->AuditPrivilegeUse = Keyvalue;
  1139. } else if ( _wcsicmp(Keyname, TEXT("AuditPolicyChange")) == 0 ) {
  1140. pSCEinfo->AuditPolicyChange = Keyvalue;
  1141. } else if ( _wcsicmp(Keyname, TEXT("AuditAccountManage")) == 0 ) {
  1142. pSCEinfo->AuditAccountManage = Keyvalue;
  1143. } else if ( _wcsicmp(Keyname, TEXT("AuditProcessTracking")) == 0 ) {
  1144. pSCEinfo->AuditProcessTracking = Keyvalue;
  1145. } else if ( _wcsicmp(Keyname, TEXT("AuditDSAccess")) == 0 ) {
  1146. pSCEinfo->AuditDSAccess = Keyvalue;
  1147. } else if ( _wcsicmp(Keyname, TEXT("AuditAccountLogon")) == 0 ) {
  1148. pSCEinfo->AuditAccountLogon = Keyvalue;
  1149. } else if ( _wcsicmp(Keyname, TEXT("CrashOnAuditFull")) == 0 ) {
  1150. pSCEinfo->CrashOnAuditFull = Keyvalue;
  1151. } else if ( !(ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) ) {
  1152. ScepBuildErrorLogInfo(0, Errlog,
  1153. SCEERR_NOT_EXPECTED,
  1154. Keyname, szAuditEvent);
  1155. }
  1156. } else {
  1157. rc = SCESTATUS_BAD_FORMAT;
  1158. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
  1159. Errlog,
  1160. SCEERR_QUERY_INFO,
  1161. szAuditEvent
  1162. );
  1163. return(rc);
  1164. }
  1165. } while(SetupFindNextLine(&InfLine, &InfLine));
  1166. }
  1167. return(rc);
  1168. }
  1169. SCESTATUS
  1170. SceInfpGetAuditLogSetting(
  1171. IN HINF hInf,
  1172. IN PCWSTR SectionName,
  1173. IN DWORD ObjectFlag,
  1174. OUT PDWORD LogSize,
  1175. OUT PDWORD Periods,
  1176. OUT PDWORD RetentionDays,
  1177. OUT PDWORD RestrictGuest,
  1178. IN OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  1179. )
  1180. /* ++
  1181. Routine Description:
  1182. This routine retrieves audit log setting from the INF file based on the
  1183. SectionName passed in. The audit log settings include MaximumSize,
  1184. RetentionPeriod and RetentionDays. There are 3 different logs (system,
  1185. security, and application) which all have the same setting. The information
  1186. returned in in LogSize, Periods, RetentionDays. These 3 output arguments will
  1187. be reset to SCE_NO_VALUE at the begining of the routine. So if error
  1188. occurs after the reset, the original values won't be set back.
  1189. Arguments:
  1190. hInf - INF handle to the profile
  1191. SectionName - Log section name (SAdtSystemLog, SAdtSecurityLog, SAdtApplicationLog)
  1192. LogSize - The maximum size of the log
  1193. Periods - The retention period of the log
  1194. RetentionDays - The number of days for log retention
  1195. Return value:
  1196. SCESTATUS - SCESTATUS_SUCCESS
  1197. SCESTATUS_NOT_ENOUGH_RESOURCE
  1198. SCESTATUS_INVALID_PARAMETER
  1199. SCESTATUS_BAD_FORMAT
  1200. SCESTATUS_INVALID_DATA
  1201. -- */
  1202. {
  1203. INFCONTEXT InfLine;
  1204. SCESTATUS rc=SCESTATUS_SUCCESS;
  1205. DWORD Keyvalue;
  1206. WCHAR Keyname[SCE_KEY_MAX_LENGTH];
  1207. *LogSize = SCE_NO_VALUE;
  1208. *Periods = SCE_NO_VALUE;
  1209. *RetentionDays = SCE_NO_VALUE;
  1210. if ( SetupFindFirstLine(hInf,SectionName,NULL,&InfLine) ) {
  1211. do {
  1212. memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
  1213. if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) &&
  1214. SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue)
  1215. ) {
  1216. if ( _wcsicmp(Keyname, TEXT("MaximumLogSize")) == 0 )
  1217. *LogSize = Keyvalue;
  1218. else if (_wcsicmp(Keyname, TEXT("AuditLogRetentionPeriod")) == 0 )
  1219. *Periods = Keyvalue;
  1220. else if (_wcsicmp(Keyname, TEXT("RetentionDays")) == 0 )
  1221. *RetentionDays = Keyvalue;
  1222. else if (_wcsicmp(Keyname, TEXT("RestrictGuestAccess")) == 0 )
  1223. *RestrictGuest = Keyvalue;
  1224. else if ( !(ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) ) {
  1225. ScepBuildErrorLogInfo(0, Errlog,
  1226. SCEERR_NOT_EXPECTED,
  1227. Keyname, SectionName);
  1228. }
  1229. } else {
  1230. rc = SCESTATUS_BAD_FORMAT;
  1231. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT, Errlog,
  1232. SCEERR_QUERY_INFO,
  1233. SectionName
  1234. );
  1235. }
  1236. if ( rc != SCESTATUS_SUCCESS )
  1237. break;
  1238. } while(SetupFindNextLine(&InfLine, &InfLine));
  1239. }
  1240. return(rc);
  1241. }
  1242. SCESTATUS
  1243. SceInfpGetUserSection(
  1244. IN HINF hInf,
  1245. IN PWSTR Name,
  1246. OUT PSCE_USER_PROFILE *pOneProfile,
  1247. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  1248. )
  1249. {
  1250. INFCONTEXT InfLine;
  1251. SCESTATUS rc=SCESTATUS_SUCCESS;
  1252. PSCE_LOGON_HOUR pLogonHour=NULL;
  1253. PWSTR SectionName=NULL;
  1254. WCHAR Keyname[SCE_KEY_MAX_LENGTH];
  1255. DWORD Keyvalue;
  1256. DWORD Keyvalue2;
  1257. PWSTR Strvalue=NULL;
  1258. DWORD DataSize;
  1259. DWORD i, cFields;
  1260. LONG i1,i2;
  1261. PSECURITY_DESCRIPTOR pTempSD=NULL;
  1262. SECURITY_INFORMATION SeInfo;
  1263. if ( hInf == NULL || Name == NULL || pOneProfile == NULL )
  1264. return(SCESTATUS_INVALID_PARAMETER);
  1265. SectionName = (PWSTR)ScepAlloc( LMEM_ZEROINIT, (wcslen(Name)+9)*sizeof(WCHAR));
  1266. if ( SectionName == NULL )
  1267. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  1268. swprintf(SectionName, L"UserProfile %s", Name );
  1269. if ( SetupFindFirstLine(hInf, SectionName, NULL, &InfLine) ) {
  1270. //
  1271. // find the detail profile section. Allocate memory
  1272. //
  1273. *pOneProfile = (PSCE_USER_PROFILE)ScepAlloc( 0, sizeof(SCE_USER_PROFILE));
  1274. if ( *pOneProfile == NULL ) {
  1275. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1276. goto Done;
  1277. }
  1278. //
  1279. // initialize
  1280. //
  1281. (*pOneProfile)->Type = SCE_STRUCT_PROFILE;
  1282. (*pOneProfile)->ForcePasswordChange = SCE_NO_VALUE;
  1283. (*pOneProfile)->DisallowPasswordChange = SCE_NO_VALUE;
  1284. (*pOneProfile)->NeverExpirePassword = SCE_NO_VALUE;
  1285. (*pOneProfile)->AccountDisabled = SCE_NO_VALUE;
  1286. (*pOneProfile)->UserProfile = NULL;
  1287. (*pOneProfile)->LogonScript = NULL;
  1288. (*pOneProfile)->HomeDir = NULL;
  1289. (*pOneProfile)->pLogonHours = NULL;
  1290. (*pOneProfile)->pWorkstations.Length = 0;
  1291. (*pOneProfile)->pWorkstations.MaximumLength = 0;
  1292. (*pOneProfile)->pWorkstations.Buffer = NULL;
  1293. (*pOneProfile)->pGroupsBelongsTo = NULL;
  1294. (*pOneProfile)->pAssignToUsers = NULL;
  1295. (*pOneProfile)->pHomeDirSecurity = NULL;
  1296. (*pOneProfile)->HomeSeInfo = 0;
  1297. (*pOneProfile)->pTempDirSecurity = NULL;
  1298. (*pOneProfile)->TempSeInfo = 0;
  1299. do {
  1300. rc = SCESTATUS_BAD_FORMAT;
  1301. memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
  1302. if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) ) {
  1303. if ( _wcsicmp(Keyname, TEXT("DisallowPasswordChange")) == 0 ) {
  1304. //
  1305. // Int Field
  1306. //
  1307. if ( SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) ) {
  1308. (*pOneProfile)->DisallowPasswordChange = Keyvalue;
  1309. rc = SCESTATUS_SUCCESS;
  1310. }
  1311. goto NextLine;
  1312. }
  1313. if ( _wcsicmp(Keyname, TEXT("PasswordChangeStyle")) == 0 ) {
  1314. //
  1315. // Int Field
  1316. //
  1317. if ( SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) ) {
  1318. rc = SCESTATUS_SUCCESS;
  1319. switch (Keyvalue ) {
  1320. case 1:
  1321. (*pOneProfile)->NeverExpirePassword = 1;
  1322. (*pOneProfile)->ForcePasswordChange = 0;
  1323. break;
  1324. case 2:
  1325. (*pOneProfile)->NeverExpirePassword = 0;
  1326. (*pOneProfile)->ForcePasswordChange = 1;
  1327. break;
  1328. case 0:
  1329. // SCE_NO_VALUE for both. same as initialization
  1330. break;
  1331. default:
  1332. rc = SCESTATUS_INVALID_DATA;
  1333. break;
  1334. }
  1335. }
  1336. goto NextLine;
  1337. }
  1338. if ( _wcsicmp(Keyname, TEXT("AccountDisabled")) == 0 ) {
  1339. //
  1340. // Int Field
  1341. //
  1342. if ( SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) ) {
  1343. (*pOneProfile)->AccountDisabled = Keyvalue == 0 ? 0 : 1;
  1344. rc = SCESTATUS_SUCCESS;
  1345. }
  1346. goto NextLine;
  1347. }
  1348. if ( _wcsicmp(Keyname, TEXT("UserProfile")) == 0 ) {
  1349. //
  1350. // String Field
  1351. //
  1352. if( SetupGetStringField(&InfLine,1,NULL,0,&DataSize) ) {
  1353. Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  1354. (DataSize+1)*sizeof(WCHAR));
  1355. if( Strvalue == NULL ) {
  1356. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1357. } else {
  1358. if(SetupGetStringField(&InfLine,1,Strvalue,DataSize,NULL)) {
  1359. (*pOneProfile)->UserProfile = Strvalue;
  1360. rc = SCESTATUS_SUCCESS;
  1361. } else
  1362. ScepFree( Strvalue );
  1363. }
  1364. }
  1365. goto NextLine;
  1366. }
  1367. if ( _wcsicmp(Keyname, TEXT("LogonScript")) == 0 ) {
  1368. //
  1369. // String Field
  1370. //
  1371. if(SetupGetStringField(&InfLine,1,NULL,0,&DataSize) ) {
  1372. Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  1373. (DataSize+1)*sizeof(WCHAR));
  1374. if( Strvalue == NULL ) {
  1375. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1376. } else {
  1377. if(SetupGetStringField(&InfLine,1,Strvalue,DataSize,NULL)) {
  1378. (*pOneProfile)->LogonScript = Strvalue;
  1379. rc = SCESTATUS_SUCCESS;
  1380. } else
  1381. ScepFree( Strvalue );
  1382. }
  1383. }
  1384. goto NextLine;
  1385. }
  1386. if ( _wcsicmp(Keyname, TEXT("HomeDir")) == 0 ) {
  1387. //
  1388. // String Field
  1389. //
  1390. if(SetupGetStringField(&InfLine,1,NULL,0,&DataSize) ) {
  1391. Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  1392. (DataSize+1)*sizeof(WCHAR));
  1393. if( Strvalue == NULL ) {
  1394. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1395. } else {
  1396. if(SetupGetStringField(&InfLine,1,Strvalue,DataSize,NULL)) {
  1397. (*pOneProfile)->HomeDir = Strvalue;
  1398. rc = SCESTATUS_SUCCESS;
  1399. } else
  1400. ScepFree( Strvalue );
  1401. }
  1402. }
  1403. goto NextLine;
  1404. }
  1405. if ( _wcsicmp(Keyname, TEXT("LogonHours")) == 0 ) {
  1406. //
  1407. // Int fields (in pairs). Each pair represents a logon hour range
  1408. //
  1409. cFields = SetupGetFieldCount( &InfLine );
  1410. //
  1411. // The first field is the key. Logon hour ranges must be in pairs
  1412. //
  1413. if ( cFields < 2 ) {
  1414. pLogonHour = (PSCE_LOGON_HOUR)ScepAlloc( LMEM_ZEROINIT,
  1415. sizeof(SCE_LOGON_HOUR) );
  1416. if ( pLogonHour == NULL ) {
  1417. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1418. goto NextLine;
  1419. }
  1420. pLogonHour->Start = SCE_NO_VALUE;
  1421. pLogonHour->End = SCE_NO_VALUE;
  1422. pLogonHour->Next = (*pOneProfile)->pLogonHours;
  1423. (*pOneProfile)->pLogonHours = pLogonHour;
  1424. rc = SCESTATUS_SUCCESS;
  1425. goto NextLine;
  1426. }
  1427. for ( i=0; i<cFields; i+=2) {
  1428. if ( SetupGetIntField( &InfLine, i+1, (INT *)&Keyvalue ) &&
  1429. SetupGetIntField( &InfLine, i+2, (INT *)&Keyvalue2 ) ) {
  1430. //
  1431. // find a pair of logon hours.
  1432. //
  1433. pLogonHour = (PSCE_LOGON_HOUR)ScepAlloc( LMEM_ZEROINIT,
  1434. sizeof(SCE_LOGON_HOUR) );
  1435. if ( pLogonHour == NULL ) {
  1436. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1437. goto NextLine;
  1438. }
  1439. pLogonHour->Start = Keyvalue;
  1440. pLogonHour->End = Keyvalue2;
  1441. pLogonHour->Next = (*pOneProfile)->pLogonHours;
  1442. (*pOneProfile)->pLogonHours = pLogonHour;
  1443. rc = SCESTATUS_SUCCESS;
  1444. } else
  1445. rc = SCESTATUS_INVALID_DATA;
  1446. }
  1447. goto NextLine;
  1448. }
  1449. if ( _wcsicmp(Keyname, TEXT("Workstations")) == 0 ) {
  1450. if( SetupGetMultiSzField(&InfLine,1,NULL,0,&DataSize) ) {
  1451. Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  1452. (DataSize+1)*sizeof(WCHAR));
  1453. if( Strvalue == NULL ) {
  1454. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1455. } else {
  1456. if(SetupGetMultiSzField(&InfLine,1,Strvalue,DataSize,NULL)) {
  1457. (*pOneProfile)->pWorkstations.Length = (USHORT)(DataSize*sizeof(WCHAR));
  1458. (*pOneProfile)->pWorkstations.Buffer = Strvalue;
  1459. Strvalue = NULL;
  1460. rc = SCESTATUS_SUCCESS;
  1461. } else {
  1462. rc = SCESTATUS_INVALID_DATA;
  1463. ScepFree(Strvalue);
  1464. }
  1465. }
  1466. }
  1467. goto NextLine;
  1468. }
  1469. i1 = i2 = 0;
  1470. if ( (i1=_wcsicmp(Keyname, TEXT("GroupsBelongsTo"))) == 0 ||
  1471. (i2=_wcsicmp(Keyname, TEXT("AssignToUsers"))) == 0 ) {
  1472. //
  1473. // String fields. Each string respresents a workstation name,
  1474. // a group name, or a user name. These names are saved in PSCE_NAME_LIST
  1475. //
  1476. cFields = SetupGetFieldCount( &InfLine );
  1477. for ( i=0; i<cFields; i++) {
  1478. if( SetupGetStringField(&InfLine,i+1,NULL,0,&DataSize) && DataSize > 0 ) {
  1479. if ( DataSize <= 1) {
  1480. rc = SCESTATUS_SUCCESS;
  1481. continue;
  1482. }
  1483. Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  1484. (DataSize+1)*sizeof(WCHAR));
  1485. if( Strvalue == NULL ) {
  1486. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1487. } else {
  1488. if(SetupGetStringField(&InfLine,i+1,Strvalue,DataSize,NULL)) {
  1489. //
  1490. // Save information in a name list
  1491. //
  1492. if ( i1 == 0) {
  1493. rc = ScepAddToNameList(&((*pOneProfile)->pGroupsBelongsTo),
  1494. Strvalue,
  1495. DataSize+1
  1496. );
  1497. } else {
  1498. rc = ScepAddToNameList(&((*pOneProfile)->pAssignToUsers),
  1499. Strvalue,
  1500. DataSize+1
  1501. );
  1502. }
  1503. if ( rc != NO_ERROR )
  1504. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1505. }
  1506. ScepFree( Strvalue );
  1507. }
  1508. }
  1509. if ( rc != SCESTATUS_SUCCESS)
  1510. break; // for loop
  1511. }
  1512. goto NextLine;
  1513. }
  1514. i1 = i2 = 0;
  1515. if ( (i1=_wcsicmp(Keyname, TEXT("HomeDirSecurity"))) == 0 ||
  1516. (i2=_wcsicmp(Keyname, TEXT("TempDirSecurity"))) == 0 ) {
  1517. // if(SetupGetStringField(&InfLine,1,NULL,0,&DataSize) && DataSize > 0 ) {
  1518. if(SetupGetMultiSzField(&InfLine,1,NULL,0,&DataSize) && DataSize > 0 ) {
  1519. Strvalue = (PWSTR)ScepAlloc( 0, (DataSize+1)*sizeof(WCHAR));
  1520. if ( Strvalue == NULL )
  1521. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1522. else {
  1523. // if(SetupGetStringField(&InfLine,1,Strvalue,DataSize,NULL)) {
  1524. if(SetupGetMultiSzField(&InfLine,1,Strvalue,DataSize,NULL)) {
  1525. //
  1526. // convert multi-sz to space
  1527. //
  1528. if ( SetupGetFieldCount( &InfLine ) > 1 ) {
  1529. ScepConvertMultiSzToDelim(Strvalue, DataSize, L'\0', L' ');
  1530. }
  1531. //
  1532. // Convert the text to real security descriptors
  1533. //
  1534. rc = ConvertTextSecurityDescriptor(
  1535. Strvalue,
  1536. &pTempSD,
  1537. &Keyvalue2,
  1538. &SeInfo
  1539. );
  1540. if (rc == NO_ERROR) {
  1541. ScepChangeAclRevision(pTempSD, ACL_REVISION);
  1542. if ( i1 == 0 ) {
  1543. (*pOneProfile)->pHomeDirSecurity = pTempSD;
  1544. (*pOneProfile)->HomeSeInfo = SeInfo;
  1545. } else {
  1546. (*pOneProfile)->pTempDirSecurity = pTempSD;
  1547. (*pOneProfile)->TempSeInfo = SeInfo;
  1548. }
  1549. pTempSD = NULL;
  1550. } else {
  1551. ScepBuildErrorLogInfo(
  1552. rc,
  1553. Errlog,
  1554. SCEERR_BUILD_SD,
  1555. Keyname //Strvalue
  1556. );
  1557. rc = ScepDosErrorToSceStatus(rc);
  1558. }
  1559. } else
  1560. rc = SCESTATUS_INVALID_DATA;
  1561. ScepFree(Strvalue);
  1562. }
  1563. }
  1564. goto NextLine;
  1565. }
  1566. //
  1567. // no string matched. ignore
  1568. //
  1569. ScepBuildErrorLogInfo(
  1570. NO_ERROR,
  1571. Errlog,
  1572. SCEERR_NOT_EXPECTED,
  1573. Keyname, SectionName);
  1574. rc = SCESTATUS_SUCCESS;
  1575. }
  1576. NextLine:
  1577. if ( rc != SCESTATUS_SUCCESS ) {
  1578. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc),
  1579. Errlog,
  1580. SCEERR_QUERY_INFO,
  1581. SectionName
  1582. );
  1583. goto Done;
  1584. }
  1585. } while(SetupFindNextLine(&InfLine,&InfLine));
  1586. }
  1587. Done:
  1588. // free memory
  1589. if ( SectionName != NULL )
  1590. ScepFree(SectionName);
  1591. if ( pTempSD != NULL )
  1592. ScepFree( pTempSD );
  1593. if ( rc != SCESTATUS_SUCCESS ) {
  1594. // free pOneProfile memory
  1595. SceFreeMemory( *pOneProfile, 0 );
  1596. *pOneProfile = NULL;
  1597. }
  1598. return(rc);
  1599. }
  1600. SCESTATUS
  1601. SceInfpGetDescription(
  1602. IN HINF hInf,
  1603. OUT PWSTR *Description
  1604. )
  1605. {
  1606. INFCONTEXT InfLine;
  1607. SCESTATUS rc=SCESTATUS_SUCCESS;
  1608. DWORD LineLen, Len;
  1609. DWORD TotalLen=0;
  1610. DWORD i, cFields;
  1611. if(SetupFindFirstLine(hInf,szDescription,NULL,&InfLine)) {
  1612. do {
  1613. cFields = SetupGetFieldCount( &InfLine );
  1614. for ( i=0; i<cFields && rc==SCESTATUS_SUCCESS; i++) {
  1615. //
  1616. // count the total length of the description.
  1617. //
  1618. if ( !SetupGetStringField(&InfLine, i+1, NULL, 0, &LineLen) ) {
  1619. rc = SCESTATUS_BAD_FORMAT;
  1620. }
  1621. TotalLen += LineLen+1;
  1622. LineLen = 0;
  1623. }
  1624. if ( rc != SCESTATUS_SUCCESS )
  1625. break;
  1626. } while ( SetupFindNextLine(&InfLine,&InfLine) );
  1627. if ( rc == SCESTATUS_SUCCESS && TotalLen > 0 ) {
  1628. //
  1629. // allocate memory for the return buffer
  1630. //
  1631. *Description = (PWSTR)ScepAlloc( LMEM_ZEROINIT, (TotalLen+1)*sizeof(WCHAR));
  1632. if ( *Description == NULL )
  1633. return( SCESTATUS_NOT_ENOUGH_RESOURCE );
  1634. // re-position to the first line
  1635. SetupFindFirstLine(hInf,szDescription,NULL,&InfLine);
  1636. Len = 0;
  1637. LineLen = 0;
  1638. do {
  1639. //
  1640. // read each line in the section and append to the end of the buffer
  1641. // note: the required size returned from SetupGetStringField already
  1642. // has one more character space.
  1643. //
  1644. cFields = SetupGetFieldCount( &InfLine );
  1645. for ( i=0; i<cFields && rc==SCESTATUS_SUCCESS; i++) {
  1646. if ( !SetupGetStringField(&InfLine, i+1,
  1647. *Description+Len, TotalLen-Len, &LineLen) ) {
  1648. rc = SCESTATUS_INVALID_DATA;
  1649. }
  1650. if ( i == cFields-1)
  1651. *(*Description+Len+LineLen-1) = L' ';
  1652. else
  1653. *(*Description+Len+LineLen-1) = L',';
  1654. Len += LineLen;
  1655. }
  1656. if ( rc != SCESTATUS_SUCCESS )
  1657. break;
  1658. } while ( SetupFindNextLine(&InfLine,&InfLine) );
  1659. }
  1660. if ( rc != SCESTATUS_SUCCESS ) {
  1661. // if error occurs, free memory
  1662. ScepFree(*Description);
  1663. *Description = NULL;
  1664. }
  1665. } else {
  1666. rc = SCESTATUS_RECORD_NOT_FOUND;
  1667. }
  1668. return(rc);
  1669. }
  1670. SCESTATUS
  1671. SceInfpGetSystemServices(
  1672. IN HINF hInf,
  1673. IN DWORD ObjectFlag,
  1674. OUT PSCE_SERVICES *pServiceList,
  1675. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  1676. )
  1677. /*
  1678. Routine Description:
  1679. Get the list of services with startup status and security descriptors
  1680. in the inf file
  1681. Arguments:
  1682. Return Value:
  1683. */
  1684. {
  1685. INFCONTEXT InfLine;
  1686. SCESTATUS rc=SCESTATUS_SUCCESS;
  1687. PWSTR Keyname=NULL;
  1688. DWORD KeyLen;
  1689. DWORD Status;
  1690. DWORD DataSize;
  1691. PWSTR Strvalue=NULL;
  1692. SECURITY_INFORMATION SeInfo;
  1693. PSECURITY_DESCRIPTOR pSecurityDescriptor=NULL;
  1694. DWORD cFields=0;
  1695. if ( pServiceList == NULL )
  1696. return(SCESTATUS_INVALID_PARAMETER);
  1697. //
  1698. // Locate the [Service General Setting] section.
  1699. //
  1700. if ( SetupFindFirstLine(hInf,szServiceGeneral,NULL,&InfLine) ) {
  1701. TCHAR tmpBuf[MAX_PATH];
  1702. do {
  1703. //
  1704. // Get service names.
  1705. //
  1706. rc = SCESTATUS_BAD_FORMAT;
  1707. cFields = SetupGetFieldCount( &InfLine );
  1708. if ( cFields < 3 ) {
  1709. tmpBuf[0] = L'\0';
  1710. SetupGetStringField(&InfLine,1,tmpBuf,MAX_PATH,NULL);
  1711. ScepBuildErrorLogInfo( ERROR_INVALID_DATA,
  1712. Errlog,
  1713. SCEERR_OBJECT_FIELDS,
  1714. tmpBuf);
  1715. if ( ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION ) {
  1716. //
  1717. // a newer version of template, ignore this line
  1718. //
  1719. rc = SCESTATUS_SUCCESS;
  1720. goto NextLine;
  1721. } else {
  1722. //
  1723. // bad format, quit
  1724. //
  1725. break;
  1726. }
  1727. }
  1728. if ( SetupGetStringField(&InfLine, 1, NULL, 0, &KeyLen) ) {
  1729. Keyname = (PWSTR)ScepAlloc( 0, (KeyLen+1)*sizeof(WCHAR));
  1730. if ( Keyname != NULL ) {
  1731. Keyname[KeyLen] = L'\0';
  1732. if ( SetupGetStringField(&InfLine, 1, Keyname, KeyLen, NULL) ) {
  1733. //
  1734. // Get value (startup status, security descriptor SDDL)
  1735. //
  1736. if ( SetupGetIntField(&InfLine, 2, (INT *)&Status) &&
  1737. // SetupGetStringField(&InfLine,3,NULL,0,&DataSize) && DataSize > 0 ) {
  1738. SetupGetMultiSzField(&InfLine,3,NULL,0,&DataSize) && DataSize > 0 ) {
  1739. Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  1740. (DataSize+1)*sizeof(WCHAR) );
  1741. if( Strvalue != NULL ) {
  1742. // if(SetupGetStringField(&InfLine,3,Strvalue,DataSize,NULL)) {
  1743. if(SetupGetMultiSzField(&InfLine,3,Strvalue,DataSize,NULL)) {
  1744. //
  1745. // convert multi-sz to space
  1746. //
  1747. if ( cFields > 3 ) {
  1748. ScepConvertMultiSzToDelim(Strvalue, DataSize, L'\0', L' ');
  1749. }
  1750. if ( ObjectFlag & SCEINF_OBJECT_FLAG_OLDSDDL ) {
  1751. ScepConvertToSDDLFormat(Strvalue, DataSize);
  1752. }
  1753. //
  1754. // Convert to security descriptor
  1755. //
  1756. rc = ConvertTextSecurityDescriptor(
  1757. Strvalue,
  1758. &pSecurityDescriptor,
  1759. &DataSize,
  1760. &SeInfo
  1761. );
  1762. if ( rc == SCESTATUS_SUCCESS ) {
  1763. ScepChangeAclRevision(pSecurityDescriptor, ACL_REVISION);
  1764. //
  1765. // add to the service list
  1766. //
  1767. rc = ScepAddOneServiceToList(
  1768. Keyname,
  1769. NULL,
  1770. Status,
  1771. (PVOID)pSecurityDescriptor,
  1772. SeInfo,
  1773. TRUE,
  1774. pServiceList
  1775. );
  1776. if ( rc != ERROR_SUCCESS) {
  1777. LocalFree(pSecurityDescriptor);
  1778. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1779. }
  1780. }
  1781. }
  1782. ScepFree( Strvalue );
  1783. Strvalue = NULL;
  1784. } else
  1785. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1786. }
  1787. }
  1788. //
  1789. // Free Keyname
  1790. //
  1791. ScepFree(Keyname);
  1792. Keyname = NULL;
  1793. } else
  1794. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1795. }
  1796. if ( rc != SCESTATUS_SUCCESS ) {
  1797. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
  1798. Errlog,
  1799. SCEERR_QUERY_INFO,
  1800. szServiceGeneral
  1801. );
  1802. break;
  1803. }
  1804. NextLine:
  1805. ;
  1806. } while(SetupFindNextLine(&InfLine,&InfLine));
  1807. }
  1808. if ( rc != SCESTATUS_SUCCESS ) {
  1809. //
  1810. // free the service list
  1811. //
  1812. SceFreePSCE_SERVICES(*pServiceList);
  1813. *pServiceList = NULL;
  1814. }
  1815. return(rc);
  1816. }
  1817. SCESTATUS
  1818. SceInfpGetKerberosPolicy(
  1819. IN HINF hInf,
  1820. IN DWORD ObjectFlag,
  1821. OUT PSCE_KERBEROS_TICKET_INFO * ppKerberosInfo,
  1822. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  1823. )
  1824. /*++
  1825. Routine Description:
  1826. This routine retrieves kerberos policy information from the SCP INF
  1827. file and stores in the output buffer ppKerberosInfo.
  1828. Arguments:
  1829. hInf - INF handle to the profile
  1830. ppKerberosInfo - the output buffer to hold kerberos info.
  1831. Errlog - A buffer to hold all error codes/text encountered when
  1832. parsing the INF file. If Errlog is NULL, no further error
  1833. information is returned except the return DWORD
  1834. Return value:
  1835. SCESTATUS - SCESTATUS_SUCCESS
  1836. SCESTATUS_NOT_ENOUGH_RESOURCE
  1837. SCESTATUS_INVALID_PARAMETER
  1838. SCESTATUS_BAD_FORMAT
  1839. SCESTATUS_INVALID_DATA
  1840. --*/
  1841. {
  1842. INFCONTEXT InfLine;
  1843. SCESTATUS rc=SCESTATUS_SUCCESS;
  1844. SCE_KEY_LOOKUP AccessSCPLookup[] = {
  1845. {(PWSTR)TEXT("MaxTicketAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxTicketAge), 'D'},
  1846. {(PWSTR)TEXT("MaxRenewAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxRenewAge), 'D'},
  1847. {(PWSTR)TEXT("MaxServiceAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxServiceAge), 'D'},
  1848. {(PWSTR)TEXT("MaxClockSkew"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxClockSkew), 'D'},
  1849. {(PWSTR)TEXT("TicketValidateClient"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, TicketValidateClient), 'D'}
  1850. };
  1851. DWORD cAccess = sizeof(AccessSCPLookup) / sizeof(SCE_KEY_LOOKUP);
  1852. //
  1853. // check arguments
  1854. //
  1855. if ( !hInf || !ppKerberosInfo ) {
  1856. return (SCESTATUS_INVALID_PARAMETER);
  1857. }
  1858. BOOL bAllocated = FALSE;
  1859. //
  1860. // Locate the [Kerberos Policy] section.
  1861. //
  1862. if(SetupFindFirstLine(hInf,szKerberosPolicy,NULL,&InfLine)) {
  1863. //
  1864. // allocate the output buffer if it is NULL
  1865. //
  1866. if ( NULL == *ppKerberosInfo ) {
  1867. *ppKerberosInfo = (PSCE_KERBEROS_TICKET_INFO)ScepAlloc(0, sizeof(SCE_KERBEROS_TICKET_INFO));
  1868. if ( NULL == *ppKerberosInfo ) {
  1869. return (SCESTATUS_NOT_ENOUGH_RESOURCE);
  1870. }
  1871. bAllocated = TRUE;
  1872. }
  1873. //
  1874. // Initialize to SCE_NO_VALUE
  1875. //
  1876. for ( DWORD i=0; i<cAccess; i++) {
  1877. if ( AccessSCPLookup[i].BufferType == 'D' ) {
  1878. *((DWORD *)((CHAR *)(*ppKerberosInfo)+AccessSCPLookup[i].Offset)) = SCE_NO_VALUE;
  1879. }
  1880. }
  1881. UINT Offset;
  1882. WCHAR Keyname[SCE_KEY_MAX_LENGTH];
  1883. int Keyvalue=0;
  1884. do {
  1885. //
  1886. // Get key names and its setting.
  1887. //
  1888. rc = SCESTATUS_SUCCESS;
  1889. memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
  1890. if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) ) {
  1891. for ( i=0; i<cAccess; i++) {
  1892. //
  1893. // get settings in AccessLookup table
  1894. //
  1895. Offset = AccessSCPLookup[i].Offset;
  1896. if (_wcsicmp(Keyname, AccessSCPLookup[i].KeyString ) == 0) {
  1897. switch ( AccessSCPLookup[i].BufferType ) {
  1898. case 'D':
  1899. //
  1900. // Int Field
  1901. //
  1902. if (SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) ) {
  1903. *((DWORD *)((CHAR *)(*ppKerberosInfo)+Offset)) = (DWORD)Keyvalue;
  1904. } else {
  1905. rc = SCESTATUS_INVALID_DATA;
  1906. }
  1907. break;
  1908. default:
  1909. //
  1910. // should not occur
  1911. //
  1912. break;
  1913. }
  1914. break; // for loop
  1915. }
  1916. }
  1917. if ( i >= cAccess &&
  1918. !(ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) ) {
  1919. //
  1920. // Did not find a match in the lookup table
  1921. //
  1922. ScepBuildErrorLogInfo( NO_ERROR,
  1923. Errlog,
  1924. SCEERR_NOT_EXPECTED,
  1925. Keyname,szKerberosPolicy );
  1926. }
  1927. if ( rc != SCESTATUS_SUCCESS ) {
  1928. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc),
  1929. Errlog,
  1930. SCEERR_QUERY_INFO,
  1931. Keyname );
  1932. }
  1933. } else {
  1934. rc = SCESTATUS_BAD_FORMAT;
  1935. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT, Errlog,
  1936. SCEERR_QUERY_INFO,
  1937. szKerberosPolicy);
  1938. }
  1939. //
  1940. // if error happens, get out
  1941. //
  1942. if ( rc != SCESTATUS_SUCCESS ) {
  1943. break;
  1944. }
  1945. } while(SetupFindNextLine(&InfLine,&InfLine));
  1946. }
  1947. if ( SCESTATUS_SUCCESS != rc && bAllocated && *ppKerberosInfo ) {
  1948. //
  1949. // free allocated memory if error occurs
  1950. //
  1951. ScepFree(*ppKerberosInfo);
  1952. *ppKerberosInfo = NULL;
  1953. }
  1954. return(rc);
  1955. }
  1956. SCESTATUS
  1957. SceInfpGetRegistryValues(
  1958. IN HINF hInf,
  1959. IN DWORD ObjectFlag,
  1960. OUT PSCE_REGISTRY_VALUE_INFO * ppRegValues,
  1961. OUT LPDWORD pValueCount,
  1962. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  1963. )
  1964. /*++
  1965. Routine Description:
  1966. This routine retrieves kerberos policy information from the SCP INF
  1967. file and stores in the output buffer ppKerberosInfo.
  1968. Arguments:
  1969. hInf - INF handle to the profile
  1970. ppRegValues - the output array to hold registry values.
  1971. pValueCount - the buffer to hold number of registry values in the array
  1972. Errlog - A buffer to hold all error codes/text encountered when
  1973. parsing the INF file. If Errlog is NULL, no further error
  1974. information is returned except the return DWORD
  1975. Return value:
  1976. SCESTATUS - SCESTATUS_SUCCESS
  1977. SCESTATUS_NOT_ENOUGH_RESOURCE
  1978. SCESTATUS_INVALID_PARAMETER
  1979. SCESTATUS_BAD_FORMAT
  1980. SCESTATUS_INVALID_DATA
  1981. --*/
  1982. {
  1983. INFCONTEXT InfLine;
  1984. SCESTATUS rc=SCESTATUS_SUCCESS;
  1985. LONG i=0;
  1986. LONG nLines;
  1987. //
  1988. // check arguments
  1989. //
  1990. if ( !hInf || !ppRegValues || !pValueCount ) {
  1991. return (SCESTATUS_INVALID_PARAMETER);
  1992. }
  1993. //
  1994. // count how many objects
  1995. //
  1996. nLines = SetupGetLineCount(hInf, szRegistryValues );
  1997. if ( nLines == -1 ) {
  1998. //
  1999. // section not found
  2000. //
  2001. return(SCESTATUS_SUCCESS);
  2002. }
  2003. *pValueCount = nLines;
  2004. *ppRegValues = NULL;
  2005. if ( nLines == 0 ) {
  2006. //
  2007. // no value is to be secured
  2008. //
  2009. return(SCESTATUS_SUCCESS);
  2010. }
  2011. //
  2012. // allocate memory for all objects
  2013. //
  2014. *ppRegValues = (PSCE_REGISTRY_VALUE_INFO)ScepAlloc( LMEM_ZEROINIT,
  2015. nLines*sizeof(SCE_REGISTRY_VALUE_INFO) );
  2016. if ( *ppRegValues == NULL ) {
  2017. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  2018. }
  2019. //
  2020. // Locate the section.
  2021. //
  2022. if ( SetupFindFirstLine(hInf,szRegistryValues,NULL,&InfLine) ) {
  2023. do {
  2024. //
  2025. // Get string key and a int value.
  2026. //
  2027. if ( i >= nLines ) {
  2028. //
  2029. // more lines than allocated
  2030. //
  2031. rc = SCESTATUS_INVALID_DATA;
  2032. ScepBuildErrorLogInfo(ERROR_INVALID_DATA,
  2033. Errlog,
  2034. SCEERR_MORE_OBJECTS,
  2035. nLines
  2036. );
  2037. break;
  2038. }
  2039. rc = SceInfpGetOneRegistryValue(
  2040. &InfLine,
  2041. ObjectFlag,
  2042. &((*ppRegValues)[i]),
  2043. Errlog
  2044. );
  2045. if ( SCESTATUS_SUCCESS == rc ) {
  2046. i++;
  2047. } else if ( ERROR_PRODUCT_VERSION == rc ) {
  2048. //
  2049. // a newer version, should ignore this line
  2050. //
  2051. rc = SCESTATUS_SUCCESS;
  2052. } else {
  2053. break; // do..while loop
  2054. }
  2055. } while(SetupFindNextLine(&InfLine,&InfLine));
  2056. }
  2057. if ( rc != SCESTATUS_SUCCESS ) {
  2058. //
  2059. // free memory
  2060. //
  2061. ScepFreeRegistryValues( ppRegValues, *pValueCount );
  2062. *ppRegValues = NULL;
  2063. } else {
  2064. *pValueCount = i;
  2065. }
  2066. return(rc);
  2067. }
  2068. SCESTATUS
  2069. SceInfpGetOneRegistryValue(
  2070. IN PINFCONTEXT pInfLine,
  2071. IN DWORD ObjectFlag,
  2072. OUT PSCE_REGISTRY_VALUE_INFO pValues,
  2073. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  2074. )
  2075. /* ++
  2076. Routine Description:
  2077. This routine retrieves one registry value from the INF file (SCP type).
  2078. Each registry value in these sections is represented by one line.
  2079. Arguments:
  2080. pInfLine - Current line context from the INF file for one object
  2081. pValues- Output buffer to hold the regitry value name and value
  2082. Errlog - The cummulative error list for errors encountered in this routine
  2083. Return value:
  2084. SCESTATUS - SCESTATUS_SUCCESS
  2085. SCESTATUS_NOT_ENOUGH_RESOURCE
  2086. SCESTATUS_INVALID_PARAMETER
  2087. SCESTATUS_BAD_FORMAT
  2088. SCESTATUS_INVALID_DATA
  2089. -- */
  2090. {
  2091. DWORD KeySize;
  2092. PWSTR Keyvalue=NULL;
  2093. SCESTATUS rc=SCESTATUS_SUCCESS;
  2094. INT dType;
  2095. PWSTR pValueStr=NULL;
  2096. DWORD nLen;
  2097. if ( !pInfLine || !pValues )
  2098. return(SCESTATUS_INVALID_PARAMETER);
  2099. nLen = SetupGetFieldCount( pInfLine );
  2100. if ( nLen < 2 ) {
  2101. TCHAR tmpBuf[MAX_PATH];
  2102. tmpBuf[0] = L'\0';
  2103. SetupGetStringField(pInfLine,0,tmpBuf,MAX_PATH,NULL);
  2104. ScepBuildErrorLogInfo( ERROR_INVALID_DATA,
  2105. Errlog,
  2106. SCEERR_REGVALUE_FIELDS,
  2107. tmpBuf);
  2108. //
  2109. // if it's a newer version template, should ignore this line
  2110. //
  2111. if ( ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION )
  2112. return(ERROR_PRODUCT_VERSION);
  2113. else
  2114. return(SCESTATUS_INVALID_DATA);
  2115. }
  2116. //
  2117. // get the key field (string)
  2118. //
  2119. if(SetupGetStringField(pInfLine,0,NULL,0,&KeySize) && KeySize > 0 ) {
  2120. Keyvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  2121. (KeySize+1)*sizeof(WCHAR) );
  2122. if( Keyvalue == NULL ) {
  2123. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  2124. } else {
  2125. //
  2126. // get key
  2127. //
  2128. if( SetupGetStringField(pInfLine,0,Keyvalue,KeySize,NULL) ) {
  2129. //
  2130. // get the data type, if error, assume REG_DWORD type
  2131. //
  2132. if ( !SetupGetIntField( pInfLine, 1, (INT *)&dType ) ) {
  2133. dType = REG_DWORD;
  2134. }
  2135. if ( SetupGetMultiSzField(pInfLine,2,NULL,0,&nLen) ) {
  2136. pValueStr = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
  2137. (nLen+1)*sizeof(WCHAR)
  2138. );
  2139. if( pValueStr == NULL ) {
  2140. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2141. } else if ( !SetupGetMultiSzField(pInfLine,2,pValueStr,nLen,NULL) ) {
  2142. rc = SCESTATUS_BAD_FORMAT;
  2143. } else {
  2144. if ( dType == REG_MULTI_SZ &&
  2145. (0 == _wcsicmp( Keyvalue, szLegalNoticeTextKeyName))) {
  2146. //
  2147. // check for commas and escape them with "," so the UI etc.
  2148. // understands this, since, here, for lines such as
  2149. // k=7,a",",b,c
  2150. // pValueStr will be a,\0b\0c\0\0 which we should make
  2151. // a","\0b\0c\0\0
  2152. //
  2153. DWORD dwCommaCount = 0;
  2154. for ( DWORD dwIndex = 0; dwIndex < nLen; dwIndex++) {
  2155. if ( pValueStr[dwIndex] == L',' )
  2156. dwCommaCount++;
  2157. }
  2158. if ( dwCommaCount > 0 ) {
  2159. PWSTR pValueStrEscaped;
  2160. DWORD dwNumBytes;
  2161. dwNumBytes = (nLen + 1 + dwCommaCount * 2) * sizeof(WCHAR);
  2162. pValueStrEscaped = (PWSTR)ScepAlloc(LMEM_ZEROINIT, dwNumBytes);
  2163. if (pValueStrEscaped) {
  2164. memset(pValueStrEscaped, '\0', dwNumBytes);
  2165. nLen = ScepEscapeString(pValueStr,
  2166. nLen+1,
  2167. L',',
  2168. L'"',
  2169. pValueStrEscaped
  2170. );
  2171. ScepFree(pValueStr);
  2172. pValueStr = pValueStrEscaped;
  2173. }
  2174. else {
  2175. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2176. }
  2177. }
  2178. }
  2179. if ( SCESTATUS_SUCCESS == rc)
  2180. rc = ScepConvertMultiSzToDelim(pValueStr, nLen, L'\0', L',');
  2181. if ( SCESTATUS_SUCCESS == rc) {
  2182. //
  2183. // assign them to the output buffer
  2184. //
  2185. pValues->FullValueName = Keyvalue;
  2186. Keyvalue = NULL;
  2187. pValues->ValueType = (DWORD)dType;
  2188. pValues->Value = pValueStr;
  2189. pValueStr = NULL;
  2190. }
  2191. }
  2192. } else {
  2193. rc = SCESTATUS_BAD_FORMAT;
  2194. }
  2195. } else
  2196. rc = SCESTATUS_BAD_FORMAT;
  2197. }
  2198. } else
  2199. rc = SCESTATUS_BAD_FORMAT;
  2200. if ( rc == SCESTATUS_BAD_FORMAT ) {
  2201. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
  2202. Errlog,
  2203. SCEERR_QUERY_INFO,
  2204. szRegistryValues);
  2205. }
  2206. if ( Keyvalue != NULL )
  2207. ScepFree( Keyvalue );
  2208. if ( pValueStr != NULL ) {
  2209. ScepFree(pValueStr);
  2210. }
  2211. return(rc);
  2212. }
  2213. SCESTATUS
  2214. WINAPI
  2215. SceSvcGetInformationTemplate(
  2216. IN PCWSTR TemplateName,
  2217. IN PCWSTR ServiceName,
  2218. IN PCWSTR Key OPTIONAL,
  2219. OUT PSCESVC_CONFIGURATION_INFO *ServiceInfo
  2220. )
  2221. /*
  2222. Routine Description:
  2223. Read information from the service's section in the template (inf format) into
  2224. the ServiceInfo buffer. If Key is specified, only one key's information is read.
  2225. Arguments:
  2226. Template - The template's name (inf format)
  2227. ServiceName - The service's name as used in service control manager, is also the
  2228. section name used in the template
  2229. Key - if specified, it is the key information to match in the template;
  2230. if it is NULL, all information from the section is read
  2231. ServiceInfo - output buffer of a array of Key/Value pairs
  2232. Return Value:
  2233. */
  2234. {
  2235. HINF hInf;
  2236. SCESTATUS rc;
  2237. if ( TemplateName == NULL || ServiceName == NULL || ServiceInfo == NULL ) {
  2238. return(SCESTATUS_INVALID_PARAMETER);
  2239. }
  2240. //
  2241. // open the template
  2242. //
  2243. rc = SceInfpOpenProfile(
  2244. TemplateName,
  2245. &hInf
  2246. );
  2247. if ( rc != SCESTATUS_SUCCESS )
  2248. return(rc);
  2249. //
  2250. // call private API to read information.
  2251. //
  2252. rc = SceSvcpGetInformationTemplate(hInf,
  2253. ServiceName,
  2254. Key,
  2255. ServiceInfo );
  2256. //
  2257. // close the template
  2258. //
  2259. SceInfpCloseProfile(hInf);
  2260. return(rc);
  2261. }