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.

1512 lines
45 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. rlogconf.c
  5. Abstract:
  6. This module contains the server-side logical configuration APIs.
  7. PNP_AddEmptyLogConf
  8. PNP_FreeLogConf
  9. PNP_GetFirstLogConf
  10. PNP_GetNextLogConf
  11. PNP_GetLogConfPriority
  12. Author:
  13. Paula Tomlinson (paulat) 9-27-1995
  14. Environment:
  15. User-mode only.
  16. Revision History:
  17. 27-Sept-1995 paulat
  18. Creation and initial implementation.
  19. --*/
  20. //
  21. // includes
  22. //
  23. #include "precomp.h"
  24. #pragma hdrstop
  25. #include "umpnpi.h"
  26. #include "umpnpdat.h"
  27. //
  28. // Prototypes used in this routine and in rresdes.c
  29. //
  30. CONFIGRET
  31. GetLogConfData(
  32. IN HKEY hKey,
  33. IN ULONG ulLogConfType,
  34. OUT PULONG pulRegDataType,
  35. OUT LPWSTR pszValueName,
  36. OUT LPBYTE *ppBuffer,
  37. OUT PULONG pulBufferSize
  38. );
  39. PCM_FULL_RESOURCE_DESCRIPTOR
  40. AdvanceResourcePtr(
  41. IN PCM_FULL_RESOURCE_DESCRIPTOR pRes
  42. );
  43. PIO_RESOURCE_LIST
  44. AdvanceRequirementsPtr(
  45. IN PIO_RESOURCE_LIST pReq
  46. );
  47. //
  48. // Prototypes from rresdes.c
  49. //
  50. BOOL
  51. FindLogConf(
  52. IN LPBYTE pList,
  53. OUT LPBYTE *ppLogConf,
  54. IN ULONG RegDataType,
  55. IN ULONG ulTag
  56. );
  57. PIO_RESOURCE_DESCRIPTOR
  58. AdvanceRequirementsDescriptorPtr(
  59. IN PIO_RESOURCE_DESCRIPTOR pReqDesStart,
  60. IN ULONG ulIncrement,
  61. IN ULONG ulRemainingRanges,
  62. OUT PULONG pulRangeCount
  63. );
  64. //
  65. // private prototypes
  66. //
  67. BOOL
  68. MigrateObsoleteDetectionInfo(
  69. IN LPWSTR pszDeviceID,
  70. IN HKEY hLogConfKey
  71. );
  72. //
  73. // global data
  74. //
  75. extern HKEY ghEnumKey; // Key to HKLM\CCC\System\Enum - DO NOT MODIFY
  76. CONFIGRET
  77. PNP_AddEmptyLogConf(
  78. IN handle_t hBinding,
  79. IN LPWSTR pDeviceID,
  80. IN ULONG ulPriority,
  81. OUT PULONG pulTag,
  82. IN ULONG ulFlags
  83. )
  84. /*++
  85. Routine Description:
  86. This the server-side of an RPC remote call. This routine adds
  87. an empty logical configuration.
  88. Arguments:
  89. hBinding RPC binding handle.
  90. pDeviceID Null-terminated device instance id string.
  91. ulPriority Priority for new log conf.
  92. pulTag Returns tag that identifies which log config this is.
  93. ulFlags Describes type of log conf to add.
  94. Return Value:
  95. If the specified device instance is valid, it returns CR_SUCCESS,
  96. otherwise it returns CR_ error code.
  97. --*/
  98. {
  99. CONFIGRET Status = CR_SUCCESS;
  100. HKEY hKey = NULL;
  101. WCHAR szValueName[64];
  102. LPBYTE pList = NULL;
  103. ULONG Index = 0, ulListSize = 0, ulAddListSize = 0;
  104. ULONG RegDataType = 0;
  105. //------------------------------------------------------------------
  106. // The BOOT, ALLOC, and FORCED config types are stored in a registry
  107. // value name of the format XxxConfig and the BASIC, FILTERED, and
  108. // OVERRIDE configs are stored in a registr value name of the format
  109. // XxxConfigVector. XxxConfig values contain the actual resource
  110. // description (REG_RESOURCE_LIST, CM_RESOURCE_LIST) while
  111. // XxxConfigVector values contain a list of resource requirements
  112. // (REG_RESOURCE_REQUIREMENTS_LIST, IO_RESOURCE_REQUIREMENTS_LIST).
  113. //
  114. // The policy for using the log conf and res des APIs is:
  115. // - BOOT, ALLOC, and FORCED are defined to only have one log conf.
  116. // - Although callers always specify a complete XXX_RESOURCE type
  117. // structure for the data when adding resource descriptors to
  118. // a log conf, I will ignore the resource specific portion of
  119. // the XXX_DES structure for FILTERED, BASIC, and OVERRIDE.
  120. // Likewise I will ignore any XXX_RANGE structures for ALLOC,
  121. // BOOT or FORCED log config types.
  122. //------------------------------------------------------------------
  123. try {
  124. //
  125. // Verify client "write" access
  126. //
  127. if (!VerifyClientAccess(hBinding,
  128. PLUGPLAY_WRITE)) {
  129. Status = CR_ACCESS_DENIED;
  130. goto Clean0;
  131. }
  132. //
  133. // initialize output parameters
  134. //
  135. if (!ARGUMENT_PRESENT(pulTag)) {
  136. Status = CR_INVALID_POINTER;
  137. goto Clean0;
  138. } else {
  139. *pulTag = 0;
  140. }
  141. //
  142. // validate parameters
  143. //
  144. if (INVALID_FLAGS(ulFlags, LOG_CONF_BITS | PRIORITY_BIT)) {
  145. Status = CR_INVALID_FLAG;
  146. goto Clean0;
  147. }
  148. //
  149. // make sure original caller didn't specify root devnode
  150. //
  151. if (!IsLegalDeviceId(pDeviceID) || IsRootDeviceID(pDeviceID)) {
  152. Status = CR_INVALID_DEVNODE;
  153. goto Clean0;
  154. }
  155. //
  156. // open a key to the device's LogConf subkey
  157. //
  158. Status = OpenLogConfKey(pDeviceID, ulFlags & LOG_CONF_BITS, &hKey);
  159. if (Status != CR_SUCCESS) {
  160. goto Clean0;
  161. }
  162. MigrateObsoleteDetectionInfo(pDeviceID, hKey);
  163. //
  164. // Retrieve log conf data from the registry
  165. //
  166. Status = GetLogConfData(hKey, ulFlags & LOG_CONF_BITS,
  167. &RegDataType, szValueName,
  168. &pList, &ulListSize);
  169. //-----------------------------------------------------------
  170. // Specified log conf type contains Resource Data only
  171. //-----------------------------------------------------------
  172. if (RegDataType == REG_RESOURCE_LIST) {
  173. if (Status != CR_SUCCESS || ulListSize == 0) {
  174. //
  175. // This is the first log conf of this type: create a new
  176. // log conf with an empty res des.
  177. //
  178. PCM_RESOURCE_LIST pResList = NULL;
  179. Status = CR_SUCCESS;
  180. ulListSize = sizeof(CM_RESOURCE_LIST) -
  181. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
  182. pList = HeapAlloc(ghPnPHeap, HEAP_ZERO_MEMORY, ulListSize);
  183. if (pList == NULL) {
  184. Status = CR_OUT_OF_MEMORY;
  185. goto Clean0;
  186. }
  187. //
  188. // initialize the config list header info
  189. //
  190. pResList = (PCM_RESOURCE_LIST)pList;
  191. pResList->Count = 1;
  192. pResList->List[0].InterfaceType = InterfaceTypeUndefined;
  193. pResList->List[0].BusNumber = 0;
  194. pResList->List[0].PartialResourceList.Version = NT_RESLIST_VERSION;
  195. pResList->List[0].PartialResourceList.Revision = NT_RESLIST_REVISION;
  196. pResList->List[0].PartialResourceList.Count = 0;
  197. } else {
  198. //
  199. // There is already at least one log conf of this type, so add
  200. // a new empty log conf to the log conf list (priority ignored)
  201. //
  202. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  203. PCM_FULL_RESOURCE_DESCRIPTOR pRes = NULL;
  204. //
  205. // realloc the existing log conf list structs to hold another
  206. // log conf
  207. //
  208. ulAddListSize = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
  209. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
  210. pResList = (PCM_RESOURCE_LIST)HeapReAlloc(ghPnPHeap, 0, pList,
  211. ulListSize + ulAddListSize);
  212. if (pResList == NULL) {
  213. Status = CR_OUT_OF_MEMORY;
  214. goto Clean0;
  215. }
  216. pList = (LPBYTE)pResList;
  217. //
  218. // Priorities are ignored for resource lists, so just add any
  219. // subsequent log confs to the end (they will be ignored by the
  220. // system anyway).
  221. //
  222. pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)(&pResList->List[0]); // first lc
  223. for (Index = 0; Index < pResList->Count; Index++) {
  224. pRes = AdvanceResourcePtr(pRes); // next lc
  225. }
  226. //
  227. // initialize the new empty log config
  228. //
  229. pResList->Count++;
  230. pRes->InterfaceType = InterfaceTypeUndefined;
  231. pRes->BusNumber = 0;
  232. pRes->PartialResourceList.Version = NT_RESLIST_VERSION;
  233. pRes->PartialResourceList.Revision = NT_RESLIST_REVISION;
  234. pRes->PartialResourceList.Count = 0;
  235. *pulTag = Index;
  236. }
  237. }
  238. //-----------------------------------------------------------
  239. // Specified log conf type contains requirements data only
  240. //-----------------------------------------------------------
  241. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  242. if (Status != CR_SUCCESS || ulListSize == 0) {
  243. //
  244. // This is the first log conf of this type: create a new
  245. // log conf (IO_RESOURCE_LIST) with a single res des
  246. // (IO_RESOURCE_DESCRIPTOR) for the config data.
  247. //
  248. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = NULL;
  249. PIO_RESOURCE_LIST pReq = NULL;
  250. Status = CR_SUCCESS;
  251. ulListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
  252. pReqList = HeapAlloc(ghPnPHeap, HEAP_ZERO_MEMORY, ulListSize);
  253. if (pReqList == NULL) {
  254. Status = CR_OUT_OF_MEMORY;
  255. goto Clean0;
  256. }
  257. pList = (LPBYTE)pReqList;
  258. //
  259. // initialize the config list header info
  260. //
  261. // There's room for one IO_RESOURCE_DESCRIPTOR embedded in
  262. // the IO_RESOURCE_LIST structure and by definition the first
  263. // one is a ConfigData type descriptor (user-mode always
  264. // specifies a priority value so we always have a ConfigData
  265. // struct).
  266. //
  267. pReqList->ListSize = ulListSize;
  268. pReqList->InterfaceType = InterfaceTypeUndefined;
  269. pReqList->BusNumber = 0;
  270. pReqList->SlotNumber = 0;
  271. pReqList->AlternativeLists = 1;
  272. pReq = (PIO_RESOURCE_LIST)(&pReqList->List[0]); // first lc
  273. pReq->Version = NT_REQLIST_VERSION;
  274. pReq->Revision = NT_REQLIST_REVISION;
  275. pReq->Count = 1;
  276. pReq->Descriptors[0].Option = IO_RESOURCE_PREFERRED;
  277. pReq->Descriptors[0].Type = CmResourceTypeConfigData;
  278. pReq->Descriptors[0].u.ConfigData.Priority = ulPriority;
  279. } else {
  280. //
  281. // There is already at least one log conf of this type, so add
  282. // a new empty log conf to the log conf list (always at the end)
  283. //
  284. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  285. PIO_RESOURCE_LIST pReq = NULL;
  286. //
  287. // realloc the existing log conf list structs to hold another
  288. // log conf
  289. //
  290. ulAddListSize = sizeof(IO_RESOURCE_LIST);
  291. pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)HeapReAlloc(ghPnPHeap, 0, pList,
  292. ulListSize + ulAddListSize);
  293. if (pReqList == NULL) {
  294. Status = CR_OUT_OF_MEMORY;
  295. goto Clean0;
  296. }
  297. pList = (LPBYTE)pReqList;
  298. //
  299. // Skip past all the existing log confs to the new space at the
  300. // end of the reallocated buffer.
  301. //
  302. pReq = (PIO_RESOURCE_LIST)(&pReqList->List[0]); // first lc
  303. for (Index = 0; Index < pReqList->AlternativeLists; Index++) {
  304. pReq = AdvanceRequirementsPtr(pReq); // next lc
  305. }
  306. //
  307. // initialize the new empty log config (including the embedded
  308. // ConfigData structure).
  309. //
  310. pReqList->AlternativeLists++;
  311. pReqList->ListSize = ulListSize + ulAddListSize;
  312. pReq->Version = NT_REQLIST_VERSION;
  313. pReq->Revision = NT_REQLIST_REVISION;
  314. pReq->Count = 1;
  315. memset(&pReq->Descriptors[0], 0, sizeof(IO_RESOURCE_DESCRIPTOR));
  316. pReq->Descriptors[0].Option = IO_RESOURCE_PREFERRED;
  317. pReq->Descriptors[0].Type = CmResourceTypeConfigData;
  318. pReq->Descriptors[0].u.ConfigData.Priority = ulPriority;
  319. *pulTag = Index;
  320. }
  321. } else {
  322. Status = CR_FAILURE;
  323. goto Clean0;
  324. }
  325. //
  326. // Write out the new/updated log conf list to the registry
  327. //
  328. if (RegSetValueEx(hKey, szValueName, 0, RegDataType,
  329. pList, ulListSize + ulAddListSize)
  330. != ERROR_SUCCESS) {
  331. Status = CR_REGISTRY_ERROR;
  332. goto Clean0;
  333. }
  334. Clean0:
  335. NOTHING;
  336. } except(EXCEPTION_EXECUTE_HANDLER) {
  337. Status = CR_FAILURE;
  338. }
  339. if (hKey != NULL) {
  340. RegCloseKey(hKey);
  341. }
  342. if (pList != NULL) {
  343. HeapFree(ghPnPHeap, 0, pList);
  344. }
  345. return Status;
  346. } // PNP_AddEmptyLogConf
  347. CONFIGRET
  348. PNP_FreeLogConf(
  349. IN handle_t hBinding,
  350. IN LPWSTR pDeviceID,
  351. IN ULONG ulType,
  352. IN ULONG ulTag,
  353. IN ULONG ulFlags
  354. )
  355. /*++
  356. Routine Description:
  357. This the server-side of an RPC remote call. This routine frees a
  358. logical configuration.
  359. Arguments:
  360. hBinding RPC binding handle.
  361. pDeviceID Null-terminated device instance id string.
  362. ulType Identifies which type of log conf is requested.
  363. ulTag Identifies which log conf from the specified type
  364. of log conf we want.
  365. ulFlags Not used, must be zero.
  366. Return Value:
  367. If the specified device instance is valid, it returns CR_SUCCESS,
  368. otherwise it returns CR_ error code.
  369. --*/
  370. {
  371. CONFIGRET Status = CR_SUCCESS;
  372. HKEY hKey = NULL;
  373. WCHAR szValueName[64];
  374. LPBYTE pList = NULL, pTemp = NULL, pNext = NULL;
  375. ULONG RegDataType = 0, Index = 0, ulListSize = 0, ulSize = 0;
  376. try {
  377. //
  378. // Verify client "write" access
  379. //
  380. if (!VerifyClientAccess(hBinding,
  381. PLUGPLAY_WRITE)) {
  382. Status = CR_ACCESS_DENIED;
  383. goto Clean0;
  384. }
  385. //
  386. // validate parameters
  387. //
  388. if (INVALID_FLAGS(ulFlags, 0)) {
  389. Status = CR_INVALID_FLAG;
  390. goto Clean0;
  391. }
  392. //
  393. // make sure original caller didn't specify root devnode (this
  394. // can't happen but Win95 does the check anyway)
  395. //
  396. if (!IsLegalDeviceId(pDeviceID) || IsRootDeviceID(pDeviceID)) {
  397. Status = CR_INVALID_DEVNODE;
  398. goto Clean0;
  399. }
  400. //
  401. // open a key to the device's LogConf subkey
  402. //
  403. Status = OpenLogConfKey(pDeviceID, ulType, &hKey);
  404. if (Status != CR_SUCCESS) {
  405. //
  406. // if the device id or LogConf subkey is not in registry,
  407. // that's okay, by definition the log conf is freed since it
  408. // doesn't exist
  409. //
  410. goto Clean0;
  411. }
  412. //
  413. // Retrieve log conf data from the registry
  414. //
  415. Status = GetLogConfData(hKey, ulType,
  416. &RegDataType, szValueName,
  417. &pList, &ulListSize);
  418. if (Status != CR_SUCCESS) {
  419. Status = CR_INVALID_LOG_CONF;
  420. goto Clean0;
  421. }
  422. //
  423. // If the log conf to free is the one and only log conf of this
  424. // type then delete the corresponding registry values
  425. //
  426. if ((RegDataType == REG_RESOURCE_LIST &&
  427. ((PCM_RESOURCE_LIST)pList)->Count <= 1) ||
  428. (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST &&
  429. ((PIO_RESOURCE_REQUIREMENTS_LIST)pList)->AlternativeLists <= 1)) {
  430. KdPrintEx((DPFLTR_PNPMGR_ID,
  431. DBGF_REGISTRY,
  432. "PNP_FreeLogConf: Deleting Value %ws from Device %ws\r\n",
  433. szValueName,
  434. pDeviceID));
  435. RegDeleteValue(hKey, szValueName);
  436. goto Clean0;
  437. }
  438. //
  439. // There are other log confs besides the one to delete, so I'll
  440. // have to remove the log conf from the data structs and resave
  441. // to the registry
  442. //
  443. //-----------------------------------------------------------
  444. // Specified log conf type contains Resource Data only
  445. //-----------------------------------------------------------
  446. if (RegDataType == REG_RESOURCE_LIST) {
  447. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  448. PCM_FULL_RESOURCE_DESCRIPTOR pRes = NULL;
  449. if (ulTag >= pResList->Count) {
  450. Status = CR_INVALID_LOG_CONF;
  451. goto Clean0;
  452. }
  453. //
  454. // skip to the log conf to be deleted
  455. //
  456. pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)(&pResList->List[0]); // first lc
  457. for (Index = 0; Index < ulTag; Index++) {
  458. pRes = AdvanceResourcePtr(pRes); // next lc
  459. }
  460. if (ulTag == pResList->Count-1) {
  461. //
  462. // If deleting the last log conf in the list, just truncate it
  463. //
  464. ulListSize = (ULONG)((ULONG_PTR)pRes - (ULONG_PTR)pResList);
  465. } else {
  466. //
  467. // Shift remaining log confs (after the log conf to be deleted)
  468. // up in the list, writing over the log conf to be deleted
  469. //
  470. pNext = (LPBYTE)AdvanceResourcePtr(pRes);
  471. ulSize = ulListSize - (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pResList);
  472. pTemp = HeapAlloc(ghPnPHeap, 0, ulSize);
  473. if (pTemp == NULL) {
  474. Status = CR_OUT_OF_MEMORY;
  475. goto Clean0;
  476. }
  477. memcpy(pTemp, pNext, ulSize); // save in temp buffer
  478. memcpy(pRes, pTemp, ulSize); // copy to deleted lc
  479. ulListSize -= (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pRes);
  480. }
  481. //
  482. // update the log conf list header
  483. //
  484. pResList->Count--;
  485. }
  486. //-----------------------------------------------------------
  487. // Specified log conf type contains requirements data only
  488. //-----------------------------------------------------------
  489. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  490. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  491. PIO_RESOURCE_LIST pReq = NULL;
  492. if (ulTag >= pReqList->AlternativeLists) {
  493. Status = CR_INVALID_LOG_CONF;
  494. goto Clean0;
  495. }
  496. //
  497. // skip to the log conf to be deleted
  498. //
  499. pReq = (PIO_RESOURCE_LIST)(&pReqList->List[0]); // first lc
  500. for (Index = 0; Index < ulTag; Index++) {
  501. pReq = AdvanceRequirementsPtr(pReq); // next lc
  502. }
  503. //
  504. // If there's any log confs after the log conf that will be deleted,
  505. // then write them over the top of the log conf we're deleting and
  506. // truncate any left over data.
  507. //
  508. pNext = (LPBYTE)AdvanceRequirementsPtr(pReq);
  509. if (ulListSize > ((DWORD_PTR)pNext - (DWORD_PTR)pReqList)) {
  510. ulSize = ulListSize - (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pReqList);
  511. pTemp = HeapAlloc(ghPnPHeap, 0, ulSize);
  512. if (pTemp == NULL) {
  513. Status = CR_OUT_OF_MEMORY;
  514. goto Clean0;
  515. }
  516. memcpy(pTemp, pNext, ulSize); // save in temp buffer
  517. memcpy(pReq, pTemp, ulSize); // copy to deleted lc
  518. ulListSize -= (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pReq);
  519. } else {
  520. //
  521. // No log confs trailing the log conf to be deleted so just
  522. // truncate it.
  523. //
  524. ulListSize = (ULONG)((ULONG_PTR)pReq - (ULONG_PTR)pReqList);
  525. }
  526. //
  527. // update the log conf list header
  528. //
  529. pReqList->AlternativeLists--;
  530. pReqList->ListSize = ulListSize;
  531. }
  532. //
  533. // Write out the updated log conf list to the registry
  534. //
  535. if (RegSetValueEx(hKey, szValueName, 0, RegDataType, pList,
  536. ulListSize) != ERROR_SUCCESS) {
  537. Status = CR_REGISTRY_ERROR;
  538. goto Clean0;
  539. }
  540. Clean0:
  541. NOTHING;
  542. } except(EXCEPTION_EXECUTE_HANDLER) {
  543. Status = CR_FAILURE;
  544. }
  545. if (hKey != NULL) {
  546. RegCloseKey(hKey);
  547. }
  548. if (pList != NULL) {
  549. HeapFree(ghPnPHeap, 0, pList);
  550. }
  551. if (pTemp != NULL) {
  552. HeapFree(ghPnPHeap, 0, pTemp);
  553. }
  554. return Status;
  555. } // PNP_FreeLogConf
  556. CONFIGRET
  557. PNP_GetFirstLogConf(
  558. IN handle_t hBinding,
  559. IN LPWSTR pDeviceID,
  560. IN ULONG ulType,
  561. OUT PULONG pulTag,
  562. IN ULONG ulFlags
  563. )
  564. /*++
  565. Routine Description:
  566. This the server-side of an RPC remote call. This routine finds the
  567. first log conf of this type for this devnode.
  568. Arguments:
  569. hBinding RPC binding handle, not used.
  570. pDeviceID Null-terminated device instance id string.
  571. ulType Describes the type of log conf to find.
  572. pulTag Returns tag that identifies which log config this is.
  573. ulFlags Not used (but may specify LOG_CONF_BITS).
  574. Return Value:
  575. If the specified device instance is valid, it returns CR_SUCCESS,
  576. otherwise it returns CR_ error code.
  577. --*/
  578. {
  579. CONFIGRET Status = CR_SUCCESS;
  580. HKEY hKey = NULL;
  581. LPBYTE pList = NULL;
  582. WCHAR szValueName[64];
  583. ULONG RegDataType = 0, ulListSize = 0;
  584. UNREFERENCED_PARAMETER(hBinding);
  585. try {
  586. //
  587. // Initialize output parameters. The index of the "first" lc will always
  588. // be zero as long as at least one lc exists.
  589. //
  590. if (!ARGUMENT_PRESENT(pulTag)) {
  591. Status = CR_INVALID_POINTER;
  592. goto Clean0;
  593. } else {
  594. *pulTag = 0;
  595. }
  596. //
  597. // validate parameters
  598. //
  599. if (INVALID_FLAGS(ulFlags, LOG_CONF_BITS)) {
  600. Status = CR_INVALID_FLAG;
  601. goto Clean0;
  602. }
  603. if (!IsLegalDeviceId(pDeviceID)) {
  604. Status = CR_INVALID_DEVNODE;
  605. goto Clean0;
  606. }
  607. //
  608. // open a key to the device's LogConf subkey. If the device id is not
  609. // in the registry, the devnode doesn't exist and therefore neither
  610. // does the log conf
  611. //
  612. Status = OpenLogConfKey(pDeviceID, ulType, &hKey);
  613. if (Status != CR_SUCCESS) {
  614. Status = CR_NO_MORE_LOG_CONF;
  615. goto Clean0;
  616. }
  617. //
  618. // Migrate any log conf data that might have been written to
  619. // registry by NT 4.0 Beta I code.
  620. //
  621. MigrateObsoleteDetectionInfo(pDeviceID, hKey);
  622. //
  623. // Retrieve log conf data from the registry
  624. //
  625. Status = GetLogConfData(hKey, ulType,
  626. &RegDataType, szValueName,
  627. &pList, &ulListSize);
  628. if (Status != CR_SUCCESS) {
  629. Status = CR_NO_MORE_LOG_CONF;
  630. goto Clean0;
  631. }
  632. //
  633. // Specified log conf type contains Resource Data only
  634. //
  635. if (RegDataType == REG_RESOURCE_LIST) {
  636. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  637. if (pResList->Count == 0) {
  638. Status = CR_NO_MORE_LOG_CONF;
  639. goto Clean0;
  640. }
  641. }
  642. //
  643. // Specified log conf type contains requirements data only
  644. //
  645. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  646. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  647. if (pReqList->AlternativeLists == 0) {
  648. Status = CR_NO_MORE_LOG_CONF;
  649. goto Clean0;
  650. }
  651. }
  652. Clean0:
  653. NOTHING;
  654. } except(EXCEPTION_EXECUTE_HANDLER) {
  655. Status = CR_FAILURE;
  656. }
  657. if (hKey != NULL) {
  658. RegCloseKey(hKey);
  659. }
  660. if (pList != NULL) {
  661. HeapFree(ghPnPHeap, 0, pList);
  662. }
  663. return Status;
  664. } // PNP_GetFirstLogConf
  665. CONFIGRET
  666. PNP_GetNextLogConf(
  667. IN handle_t hBinding,
  668. IN LPWSTR pDeviceID,
  669. IN ULONG ulType,
  670. IN ULONG ulCurrentTag,
  671. OUT PULONG pulNextTag,
  672. IN ULONG ulFlags
  673. )
  674. /*++
  675. Routine Description:
  676. This the server-side of an RPC remote call. This routine finds the
  677. next log conf of this type for this devnode.
  678. Arguments:
  679. hBinding RPC binding handle, not used.
  680. pDeviceID Null-terminated device instance id string.
  681. ulType Specifies what type of log conf to retrieve.
  682. ulCurrent Specifies current log conf in the enumeration.
  683. pulNext Returns next log conf of this type for this device id.
  684. ulFlags Not used, must be zero.
  685. Return Value:
  686. If the specified device instance is valid, it returns CR_SUCCESS,
  687. otherwise it returns CR_ error code.
  688. --*/
  689. {
  690. CONFIGRET Status = CR_SUCCESS;
  691. HKEY hKey = NULL;
  692. WCHAR szValueName[64];
  693. ULONG RegDataType = 0, ulListSize = 0;
  694. LPBYTE pList = NULL;
  695. UNREFERENCED_PARAMETER(hBinding);
  696. try {
  697. //
  698. // Initialize output parameters
  699. //
  700. if (!ARGUMENT_PRESENT(pulNextTag)) {
  701. Status = CR_INVALID_POINTER;
  702. goto Clean0;
  703. } else {
  704. *pulNextTag = 0;
  705. }
  706. //
  707. // validate parameters
  708. //
  709. if (INVALID_FLAGS(ulFlags, 0)) {
  710. Status = CR_INVALID_FLAG;
  711. goto Clean0;
  712. }
  713. if (!IsLegalDeviceId(pDeviceID)) {
  714. Status = CR_INVALID_DEVNODE;
  715. goto Clean0;
  716. }
  717. //
  718. // open a key to the device's LogConf subkey. If the device id is not
  719. // in the registry, the devnode doesn't exist and therefore neither
  720. // does the log conf
  721. //
  722. Status = OpenLogConfKey(pDeviceID, ulType, &hKey);
  723. if (Status != CR_SUCCESS) {
  724. Status = CR_INVALID_LOG_CONF;
  725. goto Clean0;
  726. }
  727. //
  728. // Retrieve log conf data from the registry
  729. //
  730. Status = GetLogConfData(hKey, ulType,
  731. &RegDataType, szValueName,
  732. &pList, &ulListSize);
  733. if (Status != CR_SUCCESS) {
  734. Status = CR_NO_MORE_LOG_CONF;
  735. goto Clean0;
  736. }
  737. //
  738. // Specified log conf type contains Resource Data only
  739. //
  740. if (RegDataType == REG_RESOURCE_LIST) {
  741. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  742. if (ulCurrentTag >= pResList->Count) {
  743. Status = CR_INVALID_LOG_CONF;
  744. goto Clean0;
  745. }
  746. //
  747. // Is the "current" log conf the last log conf?
  748. //
  749. if (ulCurrentTag == pResList->Count - 1) {
  750. Status = CR_NO_MORE_LOG_CONF;
  751. goto Clean0;
  752. }
  753. }
  754. //
  755. // Specified log conf type contains requirements data only
  756. //
  757. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  758. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  759. if (ulCurrentTag >= pReqList->AlternativeLists) {
  760. Status = CR_INVALID_LOG_CONF;
  761. goto Clean0;
  762. }
  763. //
  764. // Is the "current" log conf the last log conf?
  765. //
  766. if (ulCurrentTag == pReqList->AlternativeLists - 1) {
  767. Status = CR_NO_MORE_LOG_CONF;
  768. goto Clean0;
  769. }
  770. }
  771. //
  772. // There's at least one more log conf, return the next index value
  773. //
  774. *pulNextTag = ulCurrentTag + 1;
  775. Clean0:
  776. NOTHING;
  777. } except(EXCEPTION_EXECUTE_HANDLER) {
  778. Status = CR_FAILURE;
  779. }
  780. if (hKey != NULL) {
  781. RegCloseKey(hKey);
  782. }
  783. if (pList != NULL) {
  784. HeapFree(ghPnPHeap, 0, pList);
  785. }
  786. return Status;
  787. } // PNP_GetNextLogConf
  788. CONFIGRET
  789. PNP_GetLogConfPriority(
  790. IN handle_t hBinding,
  791. IN LPWSTR pDeviceID,
  792. IN ULONG ulType,
  793. IN ULONG ulTag,
  794. OUT PULONG pPriority,
  795. IN ULONG ulFlags
  796. )
  797. /*++
  798. Routine Description:
  799. This the server-side of an RPC remote call. This routine returns the
  800. priority value assigned to the specified log config.
  801. Arguments:
  802. hBinding RPC binding handle, not used.
  803. pDeviceID Null-terminated device instance id string.
  804. ulType Specifies what type of log conf to retrieve priority for.
  805. ulCurrent Specifies current log conf in the enumeration.
  806. pulNext Returns priority value of specified log conf.
  807. ulFlags Not used, must be zero.
  808. Return Value:
  809. If the specified device instance is valid, it returns CR_SUCCESS,
  810. otherwise it returns CR_ error code.
  811. --*/
  812. {
  813. CONFIGRET Status = CR_SUCCESS;
  814. HKEY hKey = NULL;
  815. WCHAR szValueName[64];
  816. ULONG RegDataType = 0, ulListSize = 0, index, count;
  817. LPBYTE pList = NULL, pLogConf = NULL;
  818. PIO_RESOURCE_LIST pReq = NULL;
  819. PIO_RESOURCE_DESCRIPTOR pReqDes = NULL;
  820. UNREFERENCED_PARAMETER(hBinding);
  821. try {
  822. //
  823. // Initialize output parameters
  824. //
  825. if (!ARGUMENT_PRESENT(pPriority)) {
  826. Status = CR_INVALID_POINTER;
  827. goto Clean0;
  828. } else {
  829. *pPriority = 0;
  830. }
  831. //
  832. // validate parameters
  833. //
  834. if (INVALID_FLAGS(ulFlags, 0)) {
  835. Status = CR_INVALID_FLAG;
  836. goto Clean0;
  837. }
  838. if (!IsLegalDeviceId(pDeviceID)) {
  839. Status = CR_INVALID_DEVNODE;
  840. goto Clean0;
  841. }
  842. //
  843. // open a key to the device's LogConf subkey. If the device id is not
  844. // in the registry, the devnode doesn't exist and therefore neither
  845. // does the log conf
  846. //
  847. Status = OpenLogConfKey(pDeviceID, ulType, &hKey);
  848. if (Status != CR_SUCCESS) {
  849. Status = CR_INVALID_LOG_CONF;
  850. goto Clean0;
  851. }
  852. //
  853. // Retrieve log conf data from the registry
  854. //
  855. Status = GetLogConfData(hKey, ulType,
  856. &RegDataType, szValueName,
  857. &pList, &ulListSize);
  858. if (Status != CR_SUCCESS) {
  859. Status = CR_INVALID_LOG_CONF;
  860. goto Clean0;
  861. }
  862. //
  863. // Priority values are only stored in requirements lists
  864. //
  865. if (RegDataType != REG_RESOURCE_REQUIREMENTS_LIST) {
  866. Status = CR_INVALID_LOG_CONF;
  867. goto Clean0;
  868. }
  869. //
  870. // Seek to the log conf that matches the log conf tag
  871. //
  872. if (!FindLogConf(pList, &pLogConf, RegDataType, ulTag)) {
  873. Status = CR_NO_SUCH_VALUE;
  874. goto Clean0;
  875. }
  876. //
  877. // Seek to the ConfigData res des, if any.
  878. //
  879. pReq = (PIO_RESOURCE_LIST)pLogConf;
  880. pReqDes = &pReq->Descriptors[0]; // first rd
  881. index = 0;
  882. count = 0;
  883. while (index < pReq->Count && pReqDes != NULL &&
  884. pReqDes->Type != CmResourceTypeConfigData) {
  885. pReqDes = AdvanceRequirementsDescriptorPtr(pReqDes, 1, pReq->Count - index, &count);
  886. index += count; // index of actual rd's in the struct
  887. }
  888. if (pReqDes == NULL || pReqDes->Type != CmResourceTypeConfigData) {
  889. //
  890. // No config data so we can't determine the priority.
  891. //
  892. Status = CR_NO_SUCH_VALUE;
  893. goto Clean0;
  894. }
  895. *pPriority = pReqDes->u.ConfigData.Priority;
  896. Clean0:
  897. NOTHING;
  898. } except(EXCEPTION_EXECUTE_HANDLER) {
  899. Status = CR_FAILURE;
  900. }
  901. if (hKey != NULL) {
  902. RegCloseKey(hKey);
  903. }
  904. if (pList != NULL) {
  905. HeapFree(ghPnPHeap, 0, pList);
  906. }
  907. return Status;
  908. } // PNP_GetLogConfPriority
  909. //------------------------------------------------------------------------
  910. // Private Utility Routines
  911. //------------------------------------------------------------------------
  912. CONFIGRET
  913. GetLogConfData(
  914. IN HKEY hKey,
  915. IN ULONG ulLogConfType,
  916. OUT PULONG pulRegDataType,
  917. OUT LPWSTR pszValueName,
  918. OUT LPBYTE *ppBuffer,
  919. OUT PULONG pulBufferSize
  920. )
  921. {
  922. HRESULT hr;
  923. switch (ulLogConfType) {
  924. //
  925. // BOOT, ALLOC, FORCED only have a Config value
  926. //
  927. case BOOT_LOG_CONF:
  928. hr = StringCchCopyEx(pszValueName,
  929. 64, // as defined by callers of GetLogConfData
  930. pszRegValueBootConfig,
  931. NULL, NULL,
  932. STRSAFE_NULL_ON_FAILURE);
  933. ASSERT(SUCCEEDED(hr));
  934. *pulRegDataType = REG_RESOURCE_LIST;
  935. break;
  936. case ALLOC_LOG_CONF:
  937. hr = StringCchCopyEx(pszValueName,
  938. 64, // as defined by callers of GetLogConfData
  939. pszRegValueAllocConfig,
  940. NULL, NULL,
  941. STRSAFE_NULL_ON_FAILURE);
  942. ASSERT(SUCCEEDED(hr));
  943. *pulRegDataType = REG_RESOURCE_LIST;
  944. break;
  945. case FORCED_LOG_CONF:
  946. hr = StringCchCopyEx(pszValueName,
  947. 64, // as defined by callers of GetLogConfData
  948. pszRegValueForcedConfig,
  949. NULL, NULL,
  950. STRSAFE_NULL_ON_FAILURE);
  951. ASSERT(SUCCEEDED(hr));
  952. *pulRegDataType = REG_RESOURCE_LIST;
  953. break;
  954. //
  955. // FILTERED, BASIC, OVERRIDE only have a Vector value
  956. //
  957. case FILTERED_LOG_CONF:
  958. hr = StringCchCopyEx(pszValueName,
  959. 64, // as defined by callers of GetLogConfData
  960. pszRegValueFilteredVector,
  961. NULL, NULL,
  962. STRSAFE_NULL_ON_FAILURE);
  963. ASSERT(SUCCEEDED(hr));
  964. *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
  965. break;
  966. case BASIC_LOG_CONF:
  967. hr = StringCchCopyEx(pszValueName,
  968. 64, // as defined by callers of GetLogConfData
  969. pszRegValueBasicVector,
  970. NULL, NULL,
  971. STRSAFE_NULL_ON_FAILURE);
  972. ASSERT(SUCCEEDED(hr));
  973. *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
  974. break;
  975. case OVERRIDE_LOG_CONF:
  976. hr = StringCchCopyEx(pszValueName,
  977. 64, // as defined by callers of GetLogConfData
  978. pszRegValueOverrideVector,
  979. NULL, NULL,
  980. STRSAFE_NULL_ON_FAILURE);
  981. ASSERT(SUCCEEDED(hr));
  982. *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
  983. break;
  984. default:
  985. return CR_FAILURE;
  986. }
  987. //
  988. // retrieve the Log Conf registry data
  989. //
  990. if (RegQueryValueEx(hKey, pszValueName, NULL, NULL, NULL,
  991. pulBufferSize) != ERROR_SUCCESS) {
  992. return CR_INVALID_LOG_CONF;
  993. }
  994. *ppBuffer = HeapAlloc(ghPnPHeap, 0, *pulBufferSize);
  995. if (*ppBuffer == NULL) {
  996. return CR_OUT_OF_MEMORY;
  997. }
  998. if (RegQueryValueEx(hKey, pszValueName, NULL, NULL,
  999. (LPBYTE)*ppBuffer, pulBufferSize) != ERROR_SUCCESS) {
  1000. HeapFree(ghPnPHeap, 0, *ppBuffer);
  1001. *ppBuffer = NULL;
  1002. return CR_INVALID_LOG_CONF;
  1003. }
  1004. return CR_SUCCESS;
  1005. } // GetLogConfData
  1006. PCM_FULL_RESOURCE_DESCRIPTOR
  1007. AdvanceResourcePtr(
  1008. IN PCM_FULL_RESOURCE_DESCRIPTOR pRes
  1009. )
  1010. {
  1011. // Given a resource pointer, this routine advances to the beginning
  1012. // of the next resource and returns a pointer to it. I assume that
  1013. // at least one more resource exists in the resource list.
  1014. LPBYTE p = NULL;
  1015. ULONG LastResIndex = 0;
  1016. if (pRes == NULL) {
  1017. return NULL;
  1018. }
  1019. //
  1020. // account for the size of the CM_FULL_RESOURCE_DESCRIPTOR
  1021. // (includes the header plus a single imbedded
  1022. // CM_PARTIAL_RESOURCE_DESCRIPTOR struct)
  1023. //
  1024. p = (LPBYTE)pRes + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
  1025. //
  1026. // account for any resource descriptors in addition to the single
  1027. // imbedded one I've already accounted for (if there aren't any,
  1028. // then I'll end up subtracting off the extra imbedded descriptor
  1029. // from the previous step)
  1030. //
  1031. p += (pRes->PartialResourceList.Count - 1) *
  1032. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
  1033. //
  1034. // finally, account for any extra device specific data at the end of
  1035. // the last partial resource descriptor (if any)
  1036. //
  1037. if (pRes->PartialResourceList.Count > 0) {
  1038. LastResIndex = pRes->PartialResourceList.Count - 1;
  1039. if (pRes->PartialResourceList.PartialDescriptors[LastResIndex].Type ==
  1040. CmResourceTypeDeviceSpecific) {
  1041. p += pRes->PartialResourceList.PartialDescriptors[LastResIndex].
  1042. u.DeviceSpecificData.DataSize;
  1043. }
  1044. }
  1045. return (PCM_FULL_RESOURCE_DESCRIPTOR)p;
  1046. } // AdvanceResourcePtr
  1047. PIO_RESOURCE_LIST
  1048. AdvanceRequirementsPtr(
  1049. IN PIO_RESOURCE_LIST pReq
  1050. )
  1051. {
  1052. LPBYTE p = NULL;
  1053. if (pReq == NULL) {
  1054. return NULL;
  1055. }
  1056. //
  1057. // account for the size of the IO_RESOURCE_LIST (includes header plus
  1058. // a single imbedded IO_RESOURCE_DESCRIPTOR struct)
  1059. //
  1060. p = (LPBYTE)pReq + sizeof(IO_RESOURCE_LIST);
  1061. //
  1062. // account for any requirements descriptors in addition to the single
  1063. // imbedded one I've already accounted for (if there aren't any,
  1064. // then I'll end up subtracting off the extra imbedded descriptor
  1065. // from the previous step)
  1066. //
  1067. p += (pReq->Count - 1) * sizeof(IO_RESOURCE_DESCRIPTOR);
  1068. return (PIO_RESOURCE_LIST)p;
  1069. } // AdvanceRequirementsPtr
  1070. BOOL
  1071. MigrateObsoleteDetectionInfo(
  1072. IN LPWSTR pszDeviceID,
  1073. IN HKEY hLogConfKey
  1074. )
  1075. {
  1076. LONG RegStatus = ERROR_SUCCESS;
  1077. HKEY hKey = NULL;
  1078. ULONG ulSize = 0;
  1079. LPBYTE ptr = NULL;
  1080. PCM_RESOURCE_LIST pResList = NULL;
  1081. PPrivate_Log_Conf pDetectData = NULL;
  1082. //
  1083. // First, delete any of the log conf pairs that aren't valid any more
  1084. //
  1085. RegDeleteValue(hLogConfKey, TEXT("BootConfigVector"));
  1086. RegDeleteValue(hLogConfKey, TEXT("AllocConfigVector"));
  1087. RegDeleteValue(hLogConfKey, TEXT("ForcedConfigVector"));
  1088. RegDeleteValue(hLogConfKey, TEXT("BasicConfig"));
  1089. RegDeleteValue(hLogConfKey, TEXT("FilteredConfig"));
  1090. RegDeleteValue(hLogConfKey, TEXT("OverrideConfig"));
  1091. //
  1092. // open the device instance key in the registry
  1093. //
  1094. if (RegOpenKeyEx(ghEnumKey, pszDeviceID, 0,
  1095. KEY_READ | KEY_WRITE, &hKey) != ERROR_SUCCESS) {
  1096. goto Clean0; // nothing to migrate
  1097. }
  1098. //
  1099. // If there is already a boot log config value then we can't
  1100. // migrate any old detect info
  1101. //
  1102. RegStatus = RegQueryValueEx(hLogConfKey, pszRegValueBootConfig,
  1103. NULL, NULL, NULL, &ulSize);
  1104. if (RegStatus == ERROR_SUCCESS && ulSize > 0) {
  1105. goto Clean0; // can't migrate
  1106. }
  1107. //
  1108. // retrieve any old detect signature info
  1109. //
  1110. RegStatus = RegQueryValueEx(hKey, pszRegValueDetectSignature,
  1111. NULL, NULL, NULL, &ulSize);
  1112. if ((RegStatus != ERROR_SUCCESS) || (ulSize == 0)) {
  1113. goto Clean0; // nothing to migrate
  1114. }
  1115. pDetectData = (PPrivate_Log_Conf)HeapAlloc(ghPnPHeap, 0, ulSize);
  1116. if (pDetectData == NULL) {
  1117. goto Clean0; // insufficient memory
  1118. }
  1119. RegStatus = RegQueryValueEx(hKey, pszRegValueDetectSignature,
  1120. NULL, NULL, (LPBYTE)pDetectData, &ulSize);
  1121. if ((RegStatus != ERROR_SUCCESS) || (ulSize == 0)) {
  1122. goto Clean0; // nothing to migrate
  1123. }
  1124. //
  1125. // Create an empty boot log conf and add this class specific data
  1126. // to it
  1127. //
  1128. ulSize = pDetectData->LC_CS.CS_Header.CSD_SignatureLength +
  1129. pDetectData->LC_CS.CS_Header.CSD_LegacyDataSize +
  1130. sizeof(GUID);
  1131. pResList = HeapAlloc(ghPnPHeap, HEAP_ZERO_MEMORY, sizeof(CM_RESOURCE_LIST) + ulSize);
  1132. if (pResList == NULL) {
  1133. goto Clean0; // insufficient memory
  1134. }
  1135. //
  1136. // initialize resource list
  1137. //
  1138. pResList->Count = 1;
  1139. pResList->List[0].InterfaceType = InterfaceTypeUndefined;
  1140. pResList->List[0].BusNumber = 0;
  1141. pResList->List[0].PartialResourceList.Version = NT_RESLIST_VERSION;
  1142. pResList->List[0].PartialResourceList.Revision = NT_RESLIST_REVISION;
  1143. pResList->List[0].PartialResourceList.Count = 1;
  1144. pResList->List[0].PartialResourceList.PartialDescriptors[0].Type =
  1145. CmResourceTypeDeviceSpecific;
  1146. pResList->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition =
  1147. CmResourceShareUndetermined;
  1148. pResList->List[0].PartialResourceList.PartialDescriptors[0].Flags =
  1149. (USHORT)pDetectData->LC_CS.CS_Header.CSD_Flags;
  1150. pResList->List[0].PartialResourceList.PartialDescriptors[0].
  1151. u.DeviceSpecificData.DataSize = ulSize;
  1152. pResList->List[0].PartialResourceList.PartialDescriptors[0].
  1153. u.DeviceSpecificData.Reserved1 =
  1154. pDetectData->LC_CS.CS_Header.CSD_LegacyDataSize;
  1155. pResList->List[0].PartialResourceList.PartialDescriptors[0].
  1156. u.DeviceSpecificData.Reserved2 =
  1157. pDetectData->LC_CS.CS_Header.CSD_SignatureLength;
  1158. //
  1159. // copy the legacy and class-specific signature data
  1160. //
  1161. ptr = (LPBYTE)(&pResList->List[0].PartialResourceList.PartialDescriptors[1]);
  1162. memcpy(ptr,
  1163. pDetectData->LC_CS.CS_Header.CSD_Signature +
  1164. pDetectData->LC_CS.CS_Header.CSD_LegacyDataOffset,
  1165. pDetectData->LC_CS.CS_Header.CSD_LegacyDataSize); // legacy data
  1166. ptr += pDetectData->LC_CS.CS_Header.CSD_LegacyDataSize;
  1167. memcpy(ptr,
  1168. pDetectData->LC_CS.CS_Header.CSD_Signature,
  1169. pDetectData->LC_CS.CS_Header.CSD_SignatureLength); // signature
  1170. ptr += pDetectData->LC_CS.CS_Header.CSD_SignatureLength;
  1171. memcpy(ptr,
  1172. &pDetectData->LC_CS.CS_Header.CSD_ClassGuid,
  1173. sizeof(GUID)); // GUID
  1174. //
  1175. // Write out the new/updated log conf list to the registry
  1176. //
  1177. RegSetValueEx(hLogConfKey, pszRegValueBootConfig, 0,
  1178. REG_RESOURCE_LIST, (LPBYTE)pResList,
  1179. ulSize + sizeof(CM_RESOURCE_LIST));
  1180. //
  1181. // Delete the old detect signature info
  1182. //
  1183. RegDeleteValue(hKey, pszRegValueDetectSignature);
  1184. Clean0:
  1185. if (hKey != NULL) {
  1186. RegCloseKey(hKey);
  1187. }
  1188. if (pDetectData != NULL) {
  1189. HeapFree(ghPnPHeap, 0, pDetectData);
  1190. }
  1191. if (pResList != NULL) {
  1192. HeapFree(ghPnPHeap, 0, pResList);
  1193. }
  1194. return TRUE;
  1195. } // MigrateObsoleteDetectionInfo