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.

1113 lines
30 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. svcsrv.cpp
  5. Abstract:
  6. Server Service attachment APIs
  7. Author:
  8. Jin Huang (jinhuang) 23-Jun-1997
  9. Revision History:
  10. jinhuang 23-Jan-1998 splitted to client-server
  11. --*/
  12. #include "serverp.h"
  13. #include "pfp.h"
  14. #include "srvrpcp.h"
  15. #include "service.h"
  16. #pragma hdrstop
  17. //
  18. // private prototypes
  19. //
  20. SCESTATUS
  21. SceSvcpGetOneKey(
  22. IN PSCESECTION hSection,
  23. IN PWSTR Prefix,
  24. IN DWORD PrefixLen,
  25. IN SCESVC_INFO_TYPE Type,
  26. OUT PVOID *Info
  27. );
  28. SCESTATUS
  29. SceSvcpEnumNext(
  30. IN PSCESECTION hSection,
  31. IN DWORD RequestCount,
  32. IN SCESVC_INFO_TYPE Type,
  33. OUT PVOID *Info,
  34. OUT PDWORD CountReturned
  35. );
  36. //
  37. // prototypes called from RPC interfaces
  38. //
  39. SCESTATUS
  40. SceSvcpUpdateInfo(
  41. IN PSCECONTEXT Context,
  42. IN PCWSTR ServiceName,
  43. IN PSCESVC_CONFIGURATION_INFO Info
  44. )
  45. /*
  46. Routine Description:
  47. Load service's engine dll and pass the Info buffer to service engine's
  48. update API (SceSvcAttachmentUpdate). Currently security manager engine
  49. is not doing any processing for the service data.
  50. This routine triggers the update of configuration database and/or
  51. analysis information by the service engine. Info may contain the
  52. modifications only, or the whole configuratio data for the service,
  53. or partial configuration data, depending on the agreement between service
  54. extension and service engine.
  55. This routine does not really write info to security manager database directly,
  56. instead, it passes the info buffer to the service engine's update interface
  57. and service engine will determine what and when to write inot the database.
  58. Arguments:
  59. hProfile - the security database context handle
  60. ServiceName - The service's name as used by service control manager
  61. Info - The information modified
  62. */
  63. {
  64. if ( Context == NULL || ServiceName == NULL ||
  65. Info == NULL ) {
  66. return(SCESTATUS_INVALID_PARAMETER);
  67. }
  68. SCESTATUS rc;
  69. //
  70. // get service's dll name
  71. //
  72. DWORD KeyLen;
  73. PWSTR KeyStr=NULL;
  74. KeyLen = wcslen(SCE_ROOT_SERVICE_PATH) + 1 + wcslen(ServiceName);
  75. KeyStr = (PWSTR)ScepAlloc(0, (KeyLen+1)*sizeof(WCHAR));
  76. if ( KeyStr == NULL ) {
  77. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  78. }
  79. PWSTR Setting=NULL;
  80. DWORD RegType;
  81. swprintf(KeyStr, L"%s\\%s", SCE_ROOT_SERVICE_PATH, ServiceName);
  82. KeyStr[KeyLen] = L'\0';
  83. rc = ScepRegQueryValue(
  84. HKEY_LOCAL_MACHINE,
  85. KeyStr,
  86. L"ServiceAttachmentPath",
  87. (PVOID *)&Setting,
  88. &RegType
  89. );
  90. rc = ScepDosErrorToSceStatus(rc);
  91. if ( rc == SCESTATUS_SUCCESS ) {
  92. if ( Setting != NULL ) {
  93. //
  94. // load the dll.
  95. //
  96. HINSTANCE hService;
  97. hService = LoadLibrary(Setting);
  98. if ( hService != NULL ) {
  99. //
  100. // call SceSvcAttachmentUpdate from the dll
  101. //
  102. PF_UpdateService pfTemp;
  103. pfTemp = (PF_UpdateService)
  104. GetProcAddress(hService,
  105. "SceSvcAttachmentUpdate") ;
  106. if ( pfTemp != NULL ) {
  107. SCEP_HANDLE sceHandle;
  108. SCESVC_CALLBACK_INFO sceCbInfo;
  109. sceHandle.hProfile = (PVOID)Context;
  110. sceHandle.ServiceName = ServiceName;
  111. sceCbInfo.sceHandle = &sceHandle;
  112. sceCbInfo.pfQueryInfo = &SceCbQueryInfo;
  113. sceCbInfo.pfSetInfo = &SceCbSetInfo;
  114. sceCbInfo.pfFreeInfo = &SceSvcpFreeMemory;
  115. sceCbInfo.pfLogInfo = &ScepLogOutput2;
  116. //
  117. // call the SceSvcAttachmentUpdate from the DLL
  118. //
  119. __try {
  120. rc = (*pfTemp)((PSCESVC_CALLBACK_INFO)&sceCbInfo, Info );
  121. } __except (EXCEPTION_EXECUTE_HANDLER) {
  122. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  123. }
  124. } else {
  125. //
  126. // this API is not supported
  127. //
  128. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  129. }
  130. //
  131. // try to free the library handle. If it fails, just leave it
  132. // to to the process to terminate
  133. //
  134. FreeLibrary(hService);
  135. } else
  136. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  137. ScepFree(Setting);
  138. } else
  139. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  140. }
  141. ScepFree(KeyStr);
  142. return(rc);
  143. }
  144. SCESTATUS
  145. SceSvcpQueryInfo(
  146. IN PSCECONTEXT Context,
  147. IN SCESVC_INFO_TYPE SceSvcType,
  148. IN PCWSTR ServiceName,
  149. IN PWSTR Prefix OPTIONAL,
  150. IN BOOL bExact,
  151. OUT PVOID *ppvInfo,
  152. IN OUT PSCE_ENUMERATION_CONTEXT psceEnumHandle
  153. )
  154. /*
  155. Routine Description:
  156. Query information for the service in the configuration/analysis database
  157. which contains the modified configuration and last analysis information.
  158. One enumeration returns maximum SCESVC_ENUMERATION_MAX lines (key/value)
  159. matching the lpPrefix for the service. If lpPrefix is NULL, all information
  160. for the service is enumerated. If there is more information, psceEnumHandle
  161. must be used to get next set of keys/values, until *ppvInfo is NULL or Count is 0.
  162. When bExact is set and lpPrefix is not NULL, exact match on the lpPrefix is
  163. searched and only one line is returned.
  164. The output buffer must be freed by SceSvcFree
  165. Arguments:
  166. Context - the database context handle
  167. SceSvcType - the information type to query
  168. ServiceName - the service name to query info for
  169. Prefix - the optional key name prefix for the query
  170. bExact - TRUE = exact match on key
  171. ppvInfo - the output buffer
  172. psceEnumHandle - the output enumeration handle for next enumeartion
  173. */
  174. {
  175. if ( Context == NULL || ppvInfo == NULL ||
  176. psceEnumHandle == NULL ) {
  177. return(SCESTATUS_INVALID_PARAMETER);
  178. }
  179. PSCESECTION hSection=NULL;
  180. DOUBLE SectionID;
  181. SCESTATUS rc;
  182. switch ( SceSvcType ) {
  183. case SceSvcConfigurationInfo:
  184. //
  185. // query data in configuration database
  186. //
  187. rc = ScepOpenSectionForName(
  188. Context,
  189. SCE_ENGINE_SMP,
  190. ServiceName,
  191. &hSection
  192. );
  193. break;
  194. case SceSvcAnalysisInfo:
  195. //
  196. // query data in analysis database
  197. //
  198. rc = ScepOpenSectionForName(
  199. Context,
  200. SCE_ENGINE_SAP,
  201. ServiceName,
  202. &hSection
  203. );
  204. break;
  205. case SceSvcInternalUse:
  206. case SceSvcMergedPolicyInfo:
  207. //
  208. // query data in SCP database
  209. //
  210. rc = SceJetGetSectionIDByName(
  211. Context,
  212. ServiceName,
  213. &SectionID
  214. );
  215. if ( rc == SCESTATUS_SUCCESS ) {
  216. rc = SceJetOpenSection(
  217. Context,
  218. SectionID,
  219. SCEJET_TABLE_SCP,
  220. &hSection
  221. );
  222. }
  223. break;
  224. default:
  225. rc = SCESTATUS_INVALID_PARAMETER;
  226. break;
  227. }
  228. if ( rc == SCESTATUS_SUCCESS ) {
  229. *ppvInfo = NULL;
  230. DWORD PrefixLen, CountReturned;
  231. if ( Prefix != NULL ) {
  232. PrefixLen = wcslen(Prefix);
  233. } else
  234. PrefixLen = 0;
  235. if ( bExact && Prefix != NULL ) {
  236. //
  237. // one single key match
  238. //
  239. rc = SceSvcpGetOneKey(
  240. hSection,
  241. Prefix,
  242. PrefixLen,
  243. SceSvcType,
  244. ppvInfo
  245. );
  246. *psceEnumHandle = 0;
  247. } else {
  248. //
  249. // count total number of lines matching Prefix
  250. //
  251. DWORD LineCount;
  252. rc = SceJetGetLineCount(
  253. hSection,
  254. Prefix,
  255. TRUE,
  256. &LineCount
  257. );
  258. if ( rc == SCESTATUS_SUCCESS && LineCount <= 0 )
  259. rc = SCESTATUS_RECORD_NOT_FOUND;
  260. if ( rc == SCESTATUS_SUCCESS ) {
  261. if ( LineCount <= *psceEnumHandle ) {
  262. //
  263. // no more entries
  264. //
  265. } else {
  266. //
  267. // go to the first line of Prefix
  268. //
  269. rc = SceJetSeek(
  270. hSection,
  271. Prefix,
  272. PrefixLen*sizeof(WCHAR),
  273. SCEJET_SEEK_GE
  274. );
  275. if ( rc == SCESTATUS_SUCCESS ) {
  276. //
  277. // skip the first *EnumHandle lines
  278. //
  279. JET_ERR JetErr;
  280. JetErr = JetMove(hSection->JetSessionID,
  281. hSection->JetTableID,
  282. *psceEnumHandle,
  283. 0
  284. );
  285. rc = SceJetJetErrorToSceStatus(JetErr);
  286. if ( rc == SCESTATUS_SUCCESS ) {
  287. //
  288. // find the right start point
  289. //
  290. DWORD CountToReturn;
  291. if ( LineCount - *psceEnumHandle > SCESVC_ENUMERATION_MAX ) {
  292. CountToReturn = SCESVC_ENUMERATION_MAX;
  293. } else
  294. CountToReturn = LineCount - *psceEnumHandle;
  295. //
  296. // get next block of data
  297. //
  298. rc = SceSvcpEnumNext(
  299. hSection,
  300. CountToReturn,
  301. SceSvcType,
  302. ppvInfo,
  303. &CountReturned
  304. );
  305. if ( rc == SCESTATUS_SUCCESS ) {
  306. //
  307. // update the enumeration handle
  308. //
  309. *psceEnumHandle += CountReturned;
  310. }
  311. }
  312. }
  313. }
  314. }
  315. }
  316. if ( rc != SCESTATUS_SUCCESS ) {
  317. *psceEnumHandle = 0;
  318. }
  319. //
  320. // close the section
  321. //
  322. SceJetCloseSection(&hSection, TRUE);
  323. }
  324. return(rc);
  325. }
  326. SCESTATUS
  327. SceSvcpGetOneKey(
  328. IN PSCESECTION hSection,
  329. IN PWSTR Prefix,
  330. IN DWORD PrefixLen,
  331. IN SCESVC_INFO_TYPE Type,
  332. OUT PVOID *Info
  333. )
  334. /*
  335. Read key and value information into *Info for exact matched Prefix
  336. */
  337. {
  338. if ( hSection == NULL || Prefix == NULL ||
  339. Info == NULL ) {
  340. return(SCESTATUS_INVALID_PARAMETER);
  341. }
  342. SCESTATUS rc;
  343. DWORD ValueLen;
  344. PBYTE Value=NULL;
  345. rc = SceJetGetValue(
  346. hSection,
  347. SCEJET_EXACT_MATCH,
  348. Prefix,
  349. NULL,
  350. 0,
  351. NULL,
  352. NULL,
  353. 0,
  354. &ValueLen
  355. );
  356. if ( rc == SCESTATUS_SUCCESS ) {
  357. //
  358. // allocate buffer for Value
  359. //
  360. Value = (PBYTE)ScepAlloc(0, ValueLen+2);
  361. if ( Value != NULL ) {
  362. rc = SceJetGetValue(
  363. hSection,
  364. SCEJET_CURRENT,
  365. NULL,
  366. NULL,
  367. 0,
  368. NULL,
  369. (PWSTR)Value,
  370. ValueLen,
  371. &ValueLen
  372. );
  373. if ( rc == SCESTATUS_SUCCESS ) {
  374. //
  375. // allocate output buffer and assign
  376. //
  377. PSCESVC_ANALYSIS_INFO pAnalysisInfo=NULL;
  378. PSCESVC_CONFIGURATION_INFO pConfigInfo=NULL;
  379. if ( Type == SceSvcAnalysisInfo ) {
  380. *Info = ScepAlloc(0, sizeof(SCESVC_ANALYSIS_INFO));
  381. pAnalysisInfo = (PSCESVC_ANALYSIS_INFO)(*Info);
  382. } else {
  383. *Info = ScepAlloc(0, sizeof(SCESVC_CONFIGURATION_INFO));
  384. pConfigInfo = (PSCESVC_CONFIGURATION_INFO)(*Info);
  385. }
  386. if ( *Info != NULL ) {
  387. //
  388. // Lines buffer
  389. //
  390. if ( Type == SceSvcAnalysisInfo ) {
  391. pAnalysisInfo->Lines = (PSCESVC_ANALYSIS_LINE)ScepAlloc(0,
  392. sizeof(SCESVC_ANALYSIS_LINE));
  393. if ( pAnalysisInfo->Lines != NULL ) {
  394. //
  395. // Key buffer
  396. //
  397. pAnalysisInfo->Lines->Key = (PWSTR)ScepAlloc(0, (PrefixLen+1)*sizeof(WCHAR));
  398. if ( pAnalysisInfo->Lines->Key != NULL ) {
  399. wcscpy( pAnalysisInfo->Lines->Key, Prefix );
  400. pAnalysisInfo->Lines->Value = Value;
  401. pAnalysisInfo->Lines->ValueLen = ValueLen;
  402. pAnalysisInfo->Count = 1;
  403. Value = NULL;
  404. } else {
  405. //
  406. // free *Info->Lines
  407. //
  408. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  409. ScepFree( pAnalysisInfo->Lines );
  410. pAnalysisInfo->Lines = NULL;
  411. }
  412. } else
  413. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  414. if ( rc != SCESTATUS_SUCCESS ) {
  415. //
  416. // free buffer allocate
  417. //
  418. ScepFree(*Info);
  419. *Info = NULL;
  420. }
  421. } else {
  422. pConfigInfo->Lines = (PSCESVC_CONFIGURATION_LINE)ScepAlloc(0,
  423. sizeof(SCESVC_CONFIGURATION_LINE));
  424. if ( pConfigInfo->Lines != NULL ) {
  425. //
  426. // Key buffer
  427. //
  428. pConfigInfo->Lines->Key = (PWSTR)ScepAlloc(0, (PrefixLen+1)*sizeof(WCHAR));
  429. if ( pConfigInfo->Lines->Key != NULL ) {
  430. wcscpy( pConfigInfo->Lines->Key, Prefix );
  431. pConfigInfo->Lines->Value = (PWSTR)Value;
  432. pConfigInfo->Lines->ValueLen = ValueLen;
  433. pConfigInfo->Count = 1;
  434. Value = NULL;
  435. } else {
  436. //
  437. // free *Info->Lines
  438. //
  439. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  440. ScepFree( pConfigInfo->Lines );
  441. pConfigInfo->Lines = NULL;
  442. }
  443. } else
  444. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  445. if ( rc != SCESTATUS_SUCCESS ) {
  446. //
  447. // free buffer allocate
  448. //
  449. ScepFree(*Info);
  450. *Info = NULL;
  451. }
  452. }
  453. //
  454. // free *Info
  455. //
  456. if ( rc != SCESTATUS_SUCCESS ) {
  457. ScepFree( *Info );
  458. *Info = NULL;
  459. }
  460. } else
  461. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  462. }
  463. if ( Value != NULL ) {
  464. ScepFree(Value);
  465. Value = NULL;
  466. }
  467. }
  468. }
  469. return(rc);
  470. }
  471. SCESTATUS
  472. SceSvcpEnumNext(
  473. IN PSCESECTION hSection,
  474. IN DWORD RequestCount,
  475. IN SCESVC_INFO_TYPE Type,
  476. OUT PVOID *Info,
  477. OUT PDWORD CountReturned
  478. )
  479. {
  480. if ( hSection == NULL || Info == NULL || CountReturned == NULL ) {
  481. return(SCESTATUS_INVALID_PARAMETER);
  482. }
  483. if ( RequestCount <= 0 ) {
  484. *CountReturned = 0;
  485. return(SCESTATUS_SUCCESS);
  486. }
  487. SCESTATUS rc=SCESTATUS_SUCCESS;
  488. //
  489. // allocate output buffer
  490. //
  491. PSCESVC_ANALYSIS_INFO pAnalysisInfo=NULL;
  492. PSCESVC_CONFIGURATION_INFO pConfigInfo=NULL;
  493. if ( Type == SceSvcAnalysisInfo ) {
  494. *Info = ScepAlloc(0, sizeof(SCESVC_ANALYSIS_INFO));
  495. pAnalysisInfo = (PSCESVC_ANALYSIS_INFO)(*Info);
  496. } else {
  497. *Info = ScepAlloc(0, sizeof(SCESVC_CONFIGURATION_INFO));
  498. pConfigInfo = (PSCESVC_CONFIGURATION_INFO)(*Info);
  499. }
  500. if ( *Info != NULL ) {
  501. DWORD Count=0;
  502. if ( Type == SceSvcAnalysisInfo ) {
  503. pAnalysisInfo->Lines = (PSCESVC_ANALYSIS_LINE)ScepAlloc(0,
  504. RequestCount*sizeof(SCESVC_ANALYSIS_LINE));
  505. if ( pAnalysisInfo->Lines == NULL ) {
  506. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  507. }
  508. } else {
  509. pConfigInfo->Lines = (PSCESVC_CONFIGURATION_LINE)ScepAlloc(0,
  510. RequestCount*sizeof(SCESVC_CONFIGURATION_LINE));
  511. if ( pConfigInfo->Lines == NULL ) {
  512. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  513. }
  514. }
  515. if ( rc == SCESTATUS_SUCCESS ) { // if Lines is NULL, rc will be NOT_ENOUGH_RESOURCE
  516. //
  517. // loop through each line
  518. //
  519. DWORD KeyLen, ValueLen;
  520. PWSTR Key=NULL, Value=NULL;
  521. do {
  522. rc = SceJetGetValue(
  523. hSection,
  524. SCEJET_CURRENT,
  525. NULL,
  526. NULL,
  527. 0,
  528. &KeyLen,
  529. NULL,
  530. 0,
  531. &ValueLen
  532. );
  533. if ( rc == SCESTATUS_SUCCESS ) {
  534. //
  535. // allocate memory for the Key and Value
  536. //
  537. Key = (PWSTR)ScepAlloc(LMEM_ZEROINIT, KeyLen+2);
  538. Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
  539. if ( Key == NULL || Value == NULL ) {
  540. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  541. ScepFree(Key);
  542. ScepFree(Value);
  543. } else {
  544. //
  545. // Get the Key and Value
  546. //
  547. rc = SceJetGetValue(
  548. hSection,
  549. SCEJET_CURRENT,
  550. NULL,
  551. Key,
  552. KeyLen,
  553. &KeyLen,
  554. Value,
  555. ValueLen,
  556. &ValueLen
  557. );
  558. if ( rc == SCESTATUS_SUCCESS ) {
  559. //
  560. // assign to the output buffer
  561. //
  562. if ( Type == SceSvcAnalysisInfo ) {
  563. pAnalysisInfo->Lines[Count].Key = Key;
  564. pAnalysisInfo->Lines[Count].Value = (PBYTE)Value;
  565. pAnalysisInfo->Lines[Count].ValueLen = ValueLen;
  566. } else {
  567. pConfigInfo->Lines[Count].Key = Key;
  568. pConfigInfo->Lines[Count].Value = Value;
  569. pConfigInfo->Lines[Count].ValueLen = ValueLen;
  570. }
  571. } else {
  572. ScepFree(Key);
  573. ScepFree(Value);
  574. }
  575. }
  576. }
  577. //
  578. // move to next line
  579. //
  580. if ( rc == SCESTATUS_SUCCESS ) {
  581. rc = SceJetMoveNext(hSection);
  582. Count++;
  583. }
  584. } while (rc == SCESTATUS_SUCCESS && Count < RequestCount );
  585. }
  586. *CountReturned = Count;
  587. if (Type == SceSvcAnalysisInfo) {
  588. pAnalysisInfo->Count = Count;
  589. } else {
  590. pConfigInfo->Count = Count;
  591. }
  592. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  593. rc = SCESTATUS_SUCCESS;
  594. } else if ( rc != SCESTATUS_SUCCESS ) {
  595. //
  596. // free memory allocated for output buffer
  597. //
  598. DWORD i;
  599. if (Type == SceSvcAnalysisInfo) {
  600. for ( i=0; i<Count; i++ ) {
  601. ScepFree(pAnalysisInfo->Lines[i].Key);
  602. ScepFree(pAnalysisInfo->Lines[i].Value);
  603. }
  604. ScepFree(pAnalysisInfo->Lines);
  605. } else {
  606. for ( i=0; i<Count; i++ ) {
  607. ScepFree(pConfigInfo->Lines[i].Key);
  608. ScepFree(pConfigInfo->Lines[i].Value);
  609. }
  610. ScepFree(pConfigInfo->Lines);
  611. }
  612. ScepFree(*Info);
  613. *Info = NULL;
  614. *CountReturned = 0;
  615. }
  616. } else
  617. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  618. return(rc);
  619. }
  620. SCESTATUS
  621. SceSvcpSetInfo(
  622. IN PSCECONTEXT Context,
  623. IN SCESVC_INFO_TYPE SceSvcType,
  624. IN PCWSTR ServiceName,
  625. IN PWSTR Prefix OPTIONAL,
  626. IN BOOL bExact,
  627. IN LONG GpoID,
  628. IN PVOID pvInfo OPTIONAL
  629. )
  630. /*
  631. Routine Description:
  632. Save information of a service into security manager internal database. It's up
  633. to the service to collect/decide the information to write.
  634. Type indicates the type of internal database: CONFIGURATION or ANALYSIS.
  635. If the service section does not exist, create it.
  636. */
  637. {
  638. if (!Context || !ServiceName ) {
  639. return(SCESTATUS_INVALID_PARAMETER);
  640. }
  641. PSCESECTION hSection=NULL;
  642. SCESTATUS rc;
  643. //
  644. // open/create the sections
  645. //
  646. rc = SceJetStartTransaction( Context );
  647. if ( rc == SCESTATUS_SUCCESS ) {
  648. switch ( SceSvcType ) {
  649. case SceSvcConfigurationInfo:
  650. rc = ScepStartANewSection(
  651. Context,
  652. &hSection,
  653. SCEJET_TABLE_SMP,
  654. ServiceName
  655. );
  656. break;
  657. case SceSvcAnalysisInfo:
  658. rc = ScepStartANewSection(
  659. Context,
  660. &hSection,
  661. SCEJET_TABLE_SAP,
  662. ServiceName
  663. );
  664. break;
  665. case SceSvcInternalUse:
  666. case SceSvcMergedPolicyInfo:
  667. rc = ScepStartANewSection(
  668. Context,
  669. &hSection,
  670. SCEJET_TABLE_SCP,
  671. ServiceName
  672. );
  673. break;
  674. default:
  675. rc = SCESTATUS_INVALID_PARAMETER;
  676. }
  677. if ( rc == SCESTATUS_SUCCESS ) {
  678. if ( pvInfo == NULL ) {
  679. //
  680. // delete the whole section, partial for Prefix, or a single line
  681. //
  682. if (Prefix == NULL ) {
  683. rc = SceJetDelete(
  684. hSection,
  685. NULL,
  686. FALSE,
  687. SCEJET_DELETE_SECTION
  688. );
  689. } else if ( bExact ) {
  690. //
  691. // delete single line
  692. //
  693. rc = SceJetDelete(
  694. hSection,
  695. Prefix,
  696. FALSE,
  697. SCEJET_DELETE_LINE
  698. );
  699. } else {
  700. rc = SceJetDelete(
  701. hSection,
  702. Prefix,
  703. FALSE,
  704. SCEJET_DELETE_PARTIAL
  705. );
  706. }
  707. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  708. rc = SCESTATUS_SUCCESS;
  709. }
  710. } else {
  711. //
  712. // if bExact is not set, delete the whole section first
  713. //
  714. if ( !bExact ) {
  715. rc = SceJetDelete(
  716. hSection,
  717. NULL,
  718. FALSE,
  719. SCEJET_DELETE_SECTION
  720. );
  721. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  722. rc = SCESTATUS_SUCCESS;
  723. }
  724. }
  725. //
  726. // overwrite some keys in Info
  727. //
  728. DWORD Count;
  729. PWSTR Key;
  730. PBYTE Value;
  731. DWORD ValueLen;
  732. if ( SceSvcType == SceSvcAnalysisInfo )
  733. Count = ((PSCESVC_ANALYSIS_INFO)pvInfo)->Count;
  734. else
  735. Count = ((PSCESVC_CONFIGURATION_INFO)pvInfo)->Count;
  736. for ( DWORD i=0; i<Count; i++ ) {
  737. if ( SceSvcType == SceSvcAnalysisInfo ) {
  738. Key = ((PSCESVC_ANALYSIS_INFO)pvInfo)->Lines[i].Key;
  739. Value = ((PSCESVC_ANALYSIS_INFO)pvInfo)->Lines[i].Value;
  740. ValueLen = ((PSCESVC_ANALYSIS_INFO)pvInfo)->Lines[i].ValueLen;
  741. } else {
  742. Key = ((PSCESVC_CONFIGURATION_INFO)pvInfo)->Lines[i].Key;
  743. Value = (PBYTE)(((PSCESVC_CONFIGURATION_INFO)pvInfo)->Lines[i].Value);
  744. ValueLen = ((PSCESVC_CONFIGURATION_INFO)pvInfo)->Lines[i].ValueLen;
  745. }
  746. rc = SceJetSetLine(
  747. hSection,
  748. Key,
  749. TRUE,
  750. (PWSTR)Value,
  751. ValueLen,
  752. GpoID
  753. );
  754. if ( rc != SCESTATUS_SUCCESS ) {
  755. break;
  756. }
  757. }
  758. }
  759. }
  760. //
  761. // close the section
  762. //
  763. SceJetCloseSection(&hSection, TRUE);
  764. if ( rc == SCESTATUS_SUCCESS ) {
  765. //
  766. // commit the change
  767. //
  768. rc = SceJetCommitTransaction(Context, 0);
  769. }
  770. if ( rc != SCESTATUS_SUCCESS ) {
  771. SceJetRollback(Context, 0);
  772. }
  773. }
  774. return(rc);
  775. }
  776. //
  777. // attachment engine call back functions
  778. //
  779. SCESTATUS
  780. SceCbQueryInfo(
  781. IN SCE_HANDLE sceHandle,
  782. IN SCESVC_INFO_TYPE sceType,
  783. IN LPTSTR lpPrefix OPTIONAL,
  784. IN BOOL bExact,
  785. OUT PVOID *ppvInfo,
  786. OUT PSCE_ENUMERATION_CONTEXT psceEnumHandle
  787. )
  788. {
  789. PVOID hProfile;
  790. SCESTATUS rc=ERROR_SUCCESS;
  791. __try {
  792. hProfile = ((SCEP_HANDLE *)sceHandle)->hProfile;
  793. if ( !hProfile ||
  794. ((SCEP_HANDLE *)sceHandle)->ServiceName == NULL ) {
  795. rc = SCESTATUS_INVALID_PARAMETER;
  796. }
  797. } __except(EXCEPTION_EXECUTE_HANDLER) {
  798. rc = SCESTATUS_INVALID_PARAMETER;
  799. }
  800. if ( SCESTATUS_SUCCESS == rc ) {
  801. //
  802. // call the private function
  803. //
  804. rc = SceSvcpQueryInfo(
  805. (PSCECONTEXT)hProfile,
  806. sceType,
  807. ((SCEP_HANDLE *)sceHandle)->ServiceName,
  808. lpPrefix,
  809. bExact,
  810. ppvInfo,
  811. psceEnumHandle
  812. );
  813. }
  814. return(rc);
  815. }
  816. SCESTATUS
  817. SceCbSetInfo(
  818. IN SCE_HANDLE sceHandle,
  819. IN SCESVC_INFO_TYPE sceType,
  820. IN LPTSTR lpPrefix OPTIONAL,
  821. IN BOOL bExact,
  822. IN PVOID pvInfo
  823. )
  824. {
  825. PVOID hProfile;
  826. SCESTATUS rc=ERROR_SUCCESS;
  827. __try {
  828. hProfile = ((SCEP_HANDLE *)sceHandle)->hProfile;
  829. if ( !hProfile ||
  830. ((SCEP_HANDLE *)sceHandle)->ServiceName == NULL ) {
  831. rc = SCESTATUS_INVALID_PARAMETER;
  832. }
  833. } __except(EXCEPTION_EXECUTE_HANDLER) {
  834. rc = SCESTATUS_INVALID_PARAMETER;
  835. }
  836. if ( SCESTATUS_SUCCESS == rc ) {
  837. //
  838. // call the private function
  839. //
  840. rc = SceSvcpSetInfo(
  841. (PSCECONTEXT)hProfile,
  842. sceType,
  843. ((SCEP_HANDLE *)sceHandle)->ServiceName,
  844. lpPrefix,
  845. bExact,
  846. 0,
  847. pvInfo
  848. );
  849. }
  850. return(rc);
  851. }