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.

1904 lines
54 KiB

  1. /*++
  2. Copyright (c) 1995-2001 Microsoft Corporation
  3. Module Name:
  4. resdes.c
  5. Abstract:
  6. This module contains the API routines that operate directly on resource
  7. descriptions.
  8. CM_Add_Res_Des
  9. CM_Free_Res_Des
  10. CM_Get_Next_Res_Des
  11. CM_Get_Res_Des_Data
  12. CM_Get_Res_Des_Data_Size
  13. CM_Modify_Res_Des
  14. CM_Detect_Resource_Conflict
  15. CM_Free_Res_Des_Handle
  16. Author:
  17. Paula Tomlinson (paulat) 9-26-1995
  18. Environment:
  19. User mode only.
  20. Revision History:
  21. 26-Sept-1995 paulat
  22. Creation and initial implementation.
  23. --*/
  24. //
  25. // includes
  26. //
  27. #include "precomp.h"
  28. #include "cfgi.h"
  29. #include "setupapi.h"
  30. #include "spapip.h"
  31. //
  32. // Private prototypes
  33. //
  34. CONFIGRET
  35. CreateResDesHandle(
  36. PRES_DES prdResDes,
  37. DEVINST dnDevInst,
  38. ULONG ulLogType,
  39. ULONG ulLogTag,
  40. ULONG ulResType,
  41. ULONG ulResTag
  42. );
  43. BOOL
  44. ValidateResDesHandle(
  45. PPrivate_Res_Des_Handle pResDes
  46. );
  47. CONFIGRET
  48. Get32bitResDesFrom64bitResDes(
  49. IN RESOURCEID ResourceID,
  50. IN PCVOID ResData64,
  51. IN ULONG ResLen64,
  52. OUT PVOID * ResData32,
  53. OUT ULONG * ResLen32
  54. );
  55. CONFIGRET
  56. Convert32bitResDesTo64bitResDes(
  57. IN RESOURCEID ResourceID,
  58. IN OUT PVOID ResData,
  59. IN ULONG ResLen
  60. );
  61. CONFIGRET
  62. Convert32bitResDesSizeTo64bitResDesSize(
  63. IN RESOURCEID ResourceID,
  64. IN OUT PULONG ResLen
  65. );
  66. //
  67. // private prototypes from logconf.c
  68. //
  69. CONFIGRET
  70. CreateLogConfHandle(
  71. PLOG_CONF plcLogConf,
  72. DEVINST dnDevInst,
  73. ULONG ulLogType,
  74. ULONG ulLogTag
  75. );
  76. BOOL
  77. ValidateLogConfHandle(
  78. PPrivate_Log_Conf_Handle pLogConf
  79. );
  80. CONFIGRET
  81. CM_Add_Res_Des_Ex(
  82. OUT PRES_DES prdResDes,
  83. IN LOG_CONF lcLogConf,
  84. IN RESOURCEID ResourceID,
  85. IN PCVOID ResourceData,
  86. IN ULONG ResourceLen,
  87. IN ULONG ulFlags,
  88. IN HMACHINE hMachine
  89. )
  90. /*++
  91. Routine Description:
  92. This routine adds a resource descriptor to a logical configuration.
  93. Parameters:
  94. prdResDes Address of a variable that receives a handle for the new
  95. resource descriptor.
  96. lcLogConf Supplies the handle of the logical configuration to which
  97. the resource descriptor is added.
  98. ResourceID Specifies the type of the resource. Can be one of the
  99. ResType values defined in Section 2.1..
  100. ResourceData Supplies the address of an IO_DES, MEM_DES, DMA_DES, or
  101. IRQ_DES structure, depending on the given resource type.
  102. ResourceLen Supplies the size, in bytes, of the structure pointed to
  103. by ResourceData.
  104. ulFlags Specifies the width of certain variable-size resource
  105. descriptor structure fields, where applicable.
  106. Currently, the following flags are defined:
  107. CM_RESDES_WIDTH_32 or
  108. CM_RESDES_WIDTH_64
  109. If no flags are specified, the width of the variable-sized
  110. resource data supplied is assumed to be that native to the
  111. platform of the caller.
  112. hMachine Machine handle returned from CM_Connect_Machine or NULL.
  113. Return Value:
  114. If the function succeeds, the return value is CR_SUCCESS.
  115. If the function fails, the return value is one of the following:
  116. CR_INVALID_LOG_CONF,
  117. CR_INVALID_FLAG,
  118. CR_INVALID_POINTER,
  119. CR_INVALID_RESOURCE_ID,
  120. CR_OUT_OF_MEMORY.
  121. --*/
  122. {
  123. CONFIGRET Status = CR_SUCCESS;
  124. DEVINST dnDevInst;
  125. WCHAR pDeviceID [MAX_DEVICE_ID_LEN];
  126. ULONG ulResTag, ulLogTag, ulLogType,ulLen = MAX_DEVICE_ID_LEN;
  127. PVOID hStringTable = NULL;
  128. handle_t hBinding = NULL;
  129. BOOL Success;
  130. PVOID ResourceData32 = NULL;
  131. ULONG ResourceLen32 = 0;
  132. try {
  133. //
  134. // validate parameters
  135. //
  136. if (!ValidateLogConfHandle((PPrivate_Log_Conf_Handle)lcLogConf)) {
  137. Status = CR_INVALID_LOG_CONF;
  138. goto Clean0;
  139. }
  140. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  141. Status = CR_INVALID_FLAG;
  142. goto Clean0;
  143. }
  144. if ((ulFlags & CM_RESDES_WIDTH_32) && (ulFlags & CM_RESDES_WIDTH_64)) {
  145. Status = CR_INVALID_FLAG;
  146. goto Clean0;
  147. }
  148. #ifdef _WIN64
  149. if ((ulFlags & CM_RESDES_WIDTH_BITS) == CM_RESDES_WIDTH_DEFAULT) {
  150. ulFlags |= CM_RESDES_WIDTH_64;
  151. }
  152. #endif // _WIN64
  153. if (ulFlags & CM_RESDES_WIDTH_32) {
  154. ulFlags &= ~CM_RESDES_WIDTH_BITS;
  155. }
  156. if (ResourceData == NULL || ResourceLen == 0) {
  157. Status = CR_INVALID_POINTER;
  158. goto Clean0;
  159. }
  160. #if 0
  161. if (ResourceID > ResType_MAX && ResourceID != ResType_ClassSpecific) {
  162. Status = CR_INVALID_RESOURCEID;
  163. goto Clean0;
  164. }
  165. #endif
  166. if (ResourceID == ResType_All) {
  167. Status = CR_INVALID_RESOURCEID; // can't specify All on an add
  168. }
  169. //
  170. // Initialize parameters
  171. //
  172. if (prdResDes != NULL) { // prdResDes is optional param
  173. *prdResDes = 0;
  174. }
  175. //
  176. // extract info from the log conf handle
  177. //
  178. dnDevInst = ((PPrivate_Log_Conf_Handle)lcLogConf)->LC_DevInst;
  179. ulLogType = ((PPrivate_Log_Conf_Handle)lcLogConf)->LC_LogConfType;
  180. ulLogTag = ((PPrivate_Log_Conf_Handle)lcLogConf)->LC_LogConfTag;
  181. //
  182. // setup rpc binding handle and string table handle
  183. //
  184. if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
  185. Status = CR_FAILURE;
  186. goto Clean0;
  187. }
  188. //
  189. // Make sure the server can support the client's 64-bit resdes request.
  190. // Only server versions 0x0501 and greater support CM_RESDES_WIDTH_64.
  191. //
  192. if (ulFlags & CM_RESDES_WIDTH_64) {
  193. if (!CM_Is_Version_Available_Ex((WORD)0x0501,
  194. hMachine)) {
  195. //
  196. // Server can only support 32-bit resdes. Have the client
  197. // convert the caller's 64-bit resdes to a 32-bit resdes for the
  198. // server.
  199. //
  200. ulFlags &= ~CM_RESDES_WIDTH_BITS;
  201. Status = Get32bitResDesFrom64bitResDes(ResourceID,ResourceData,ResourceLen,&ResourceData32,&ResourceLen32);
  202. if(Status != CR_SUCCESS) {
  203. goto Clean0;
  204. }
  205. if(ResourceData32) {
  206. ResourceData = ResourceData32;
  207. ResourceLen = ResourceLen32;
  208. }
  209. }
  210. }
  211. //
  212. // retreive device instance string that corresponds to dnDevInst
  213. //
  214. Success = pSetupStringTableStringFromIdEx(hStringTable, dnDevInst,pDeviceID,&ulLen);
  215. if (Success == FALSE || INVALID_DEVINST(pDeviceID)) {
  216. Status = CR_INVALID_LOG_CONF;
  217. goto Clean0;
  218. }
  219. RpcTryExcept {
  220. //
  221. // call rpc service entry point
  222. //
  223. Status = PNP_AddResDes(
  224. hBinding, // rpc binding handle
  225. pDeviceID, // device id string
  226. ulLogTag, // log conf tag
  227. ulLogType, // log conf type
  228. ResourceID, // resource type
  229. &ulResTag, // resource tag
  230. (LPBYTE)ResourceData, // actual res des data
  231. ResourceLen, // size in bytes of ResourceData
  232. ulFlags); // currently zero
  233. }
  234. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode())) {
  235. KdPrintEx((DPFLTR_PNPMGR_ID,
  236. DBGF_ERRORS,
  237. "PNP_AddResDes caused an exception (%d)\n",
  238. RpcExceptionCode()));
  239. Status = MapRpcExceptionToCR(RpcExceptionCode());
  240. }
  241. RpcEndExcept
  242. if (Status == CR_SUCCESS && prdResDes != NULL) {
  243. Status = CreateResDesHandle(prdResDes,
  244. dnDevInst,
  245. ulLogType,
  246. ulLogTag,
  247. ResourceID,
  248. ulResTag);
  249. }
  250. Clean0:
  251. NOTHING;
  252. } except(EXCEPTION_EXECUTE_HANDLER) {
  253. Status = CR_FAILURE;
  254. }
  255. if(ResourceData32) {
  256. pSetupFree(ResourceData32);
  257. }
  258. return Status;
  259. } // CM_Add_Res_Des_Ex
  260. CONFIGRET
  261. CM_Free_Res_Des_Ex(
  262. OUT PRES_DES prdResDes,
  263. IN RES_DES rdResDes,
  264. IN ULONG ulFlags,
  265. IN HMACHINE hMachine
  266. )
  267. /*++
  268. Routine Description:
  269. This routine destroys a resource descriptor. This API returns
  270. CR_NO_MORE_RES_DES if rdResDes specifies the last resource descriptor.
  271. Parameters:
  272. prdResDes Supplies the address of the variable that receives the
  273. handle of the previous resource descriptor. If rdResDes
  274. is the handle of the first resource descriptor, this
  275. address receives the handle of the logical configuration.
  276. rdResDes Supplies the handle of the resource descriptor to be destroyed.
  277. ulFlags Must be zero.
  278. hMachine Machine handle returned from CM_Connect_Machine or NULL.
  279. Return Value:
  280. If the function succeeds, the return value is CR_SUCCESS.
  281. If the function fails, the return value is one of the following:
  282. CR_INVALID_FLAG,
  283. CR_INVALID_POINTER,
  284. CR_INVALID_RES_DES,
  285. CR_NO_MORE_RES_DES.
  286. --*/
  287. {
  288. CONFIGRET Status = CR_SUCCESS;
  289. DEVINST dnDevInst;
  290. WCHAR pDeviceID[MAX_DEVICE_ID_LEN];
  291. ULONG ulLogType, ulLogTag, ulResType, ulResTag,ulLen=MAX_DEVICE_ID_LEN;
  292. ULONG ulPreviousResType = 0, ulPreviousResTag = 0;
  293. PVOID hStringTable = NULL;
  294. handle_t hBinding = NULL;
  295. BOOL Success;
  296. try {
  297. //
  298. // validate parameters
  299. //
  300. if (!ValidateResDesHandle((PPrivate_Res_Des_Handle)rdResDes)) {
  301. Status = CR_INVALID_RES_DES;
  302. goto Clean0;
  303. }
  304. if (INVALID_FLAGS(ulFlags, 0)) {
  305. Status = CR_INVALID_FLAG;
  306. goto Clean0;
  307. }
  308. //
  309. // Initialize parameters
  310. //
  311. if (prdResDes != NULL) { // optional parameter
  312. *prdResDes = 0;
  313. }
  314. //
  315. // extract info from the res des handle
  316. //
  317. dnDevInst = ((PPrivate_Res_Des_Handle)rdResDes)->RD_DevInst;
  318. ulLogType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfType;
  319. ulLogTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfTag;
  320. ulResType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResourceType;
  321. ulResTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResDesTag;
  322. //
  323. // setup rpc binding handle and string table handle
  324. //
  325. if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
  326. Status = CR_FAILURE;
  327. goto Clean0;
  328. }
  329. //
  330. // retreive device instance string that corresponds to dnDevInst
  331. //
  332. Success = pSetupStringTableStringFromIdEx(hStringTable, dnDevInst,pDeviceID,&ulLen);
  333. if (Success == FALSE || INVALID_DEVINST(pDeviceID)) {
  334. Status = CR_INVALID_RES_DES;
  335. goto Clean0;
  336. }
  337. RpcTryExcept {
  338. //
  339. // call rpc service entry point
  340. //
  341. Status = PNP_FreeResDes(
  342. hBinding, // rpc binding handle
  343. pDeviceID, // device id string
  344. ulLogTag, // log conf tag
  345. ulLogType, // log conf type
  346. ulResType, // resource type
  347. ulResTag, // resource tag
  348. &ulPreviousResType, // resource type of previous res des
  349. &ulPreviousResTag, // tag of previous res des
  350. ulFlags); // currently zero
  351. }
  352. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode())) {
  353. KdPrintEx((DPFLTR_PNPMGR_ID,
  354. DBGF_ERRORS,
  355. "PNP_FreeResDes caused an exception (%d)\n",
  356. RpcExceptionCode()));
  357. Status = MapRpcExceptionToCR(RpcExceptionCode());
  358. }
  359. RpcEndExcept
  360. if (Status != CR_SUCCESS && Status != CR_NO_MORE_RES_DES) {
  361. goto Clean0; // quit for any other error
  362. }
  363. //
  364. // if prdResDes supplied, fill in with previous res des or
  365. // the log conf info
  366. //
  367. if (prdResDes != NULL) {
  368. //
  369. // if the previous tag value is set to 0xFFFFFFFF, then
  370. // there are no previous tages so return the log conf
  371. // info instead
  372. //
  373. if (Status == CR_NO_MORE_RES_DES) {
  374. CONFIGRET Status1;
  375. Status1 = CreateLogConfHandle(prdResDes, dnDevInst,
  376. ulLogType, ulLogTag);
  377. if (Status1 != CR_SUCCESS) {
  378. Status = Status1;
  379. }
  380. }
  381. else {
  382. //
  383. // allocate a res des handle
  384. //
  385. Status = CreateResDesHandle(prdResDes, dnDevInst,
  386. ulLogType, ulLogTag,
  387. ulPreviousResType,
  388. ulPreviousResTag);
  389. }
  390. }
  391. Clean0:
  392. NOTHING;
  393. } except(EXCEPTION_EXECUTE_HANDLER) {
  394. Status = CR_FAILURE;
  395. }
  396. return Status;
  397. } // CM_Free_Res_Des_Ex
  398. CONFIGRET
  399. CM_Get_Next_Res_Des_Ex(
  400. OUT PRES_DES prdResDes,
  401. IN RES_DES rdResDes,
  402. IN RESOURCEID ForResource,
  403. OUT PRESOURCEID pResourceID,
  404. IN ULONG ulFlags,
  405. IN HMACHINE hMachine
  406. )
  407. /*++
  408. Routine Description:
  409. This routine returns the handle of the next resource descriptor in
  410. a logical configuration.
  411. Parameters:
  412. prdResDes Supplies the address of the variable that receives the
  413. handle of the next resource descriptor.
  414. rdResDes Supplies the handle of the current resource
  415. descriptor or the handle of a logical configuration.
  416. (Both are 32-bit numbers--Configuration Manager must can
  417. distinguish between them.)
  418. ForResource Specifies the type of the resource to retrieve. Can be
  419. one of the ResType values listed in Section 2.1..
  420. pResourceID Supplies the address of the variable that receives the
  421. resource type, when ForResource specifies ResType_All.
  422. (When ForResource is not ResType_All, this parameter can
  423. be NULL.)
  424. ulFlags Must be zero.
  425. hMachine Machine handle returned from CM_Connect_Machine or NULL.
  426. Return Value:
  427. If the function succeeds, the return value is CR_SUCCESS.
  428. If the function fails, the return value is one of the following:
  429. CR_INVALID_LOG_CONF,
  430. CR_INVALID_FLAG,
  431. CR_INVALID_POINTER,
  432. CR_INVALID_RES_DES,
  433. CR_NO_MORE_RES_DES.
  434. --*/
  435. {
  436. CONFIGRET Status = CR_SUCCESS;
  437. DEVINST dnDevInst;
  438. WCHAR pDeviceID [MAX_DEVICE_ID_LEN];
  439. ULONG ulLogTag, ulLogType, ulResTag,ulLen = MAX_DEVICE_ID_LEN;
  440. ULONG ulNextResType = 0, ulNextResTag = 0;
  441. PVOID hStringTable = NULL;
  442. handle_t hBinding = NULL;
  443. BOOL Success;
  444. try {
  445. //
  446. // validate parameters
  447. //
  448. if (prdResDes == NULL) {
  449. Status = CR_INVALID_POINTER;
  450. goto Clean0;
  451. }
  452. #if 0
  453. if (ForResource > ResType_MAX &&
  454. ForResource != ResType_ClassSpecific) {
  455. Status = CR_INVALID_RESOURCEID;
  456. goto Clean0;
  457. }
  458. #endif
  459. if (ForResource == ResType_All && pResourceID == NULL) {
  460. Status = CR_INVALID_POINTER;
  461. goto Clean0;
  462. }
  463. if (INVALID_FLAGS(ulFlags, 0)) {
  464. Status = CR_INVALID_FLAG;
  465. goto Clean0;
  466. }
  467. //
  468. // this handle could be a res des or a log conf, determine
  469. // which and extract info handle
  470. //
  471. if (ValidateResDesHandle((PPrivate_Res_Des_Handle)rdResDes)) {
  472. //
  473. // it was a valid res des handle
  474. //
  475. dnDevInst = ((PPrivate_Res_Des_Handle)rdResDes)->RD_DevInst;
  476. ulLogType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfType;
  477. ulLogTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfTag;
  478. ulResTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResDesTag;
  479. }
  480. else if (ValidateLogConfHandle((PPrivate_Log_Conf_Handle)rdResDes)) {
  481. //
  482. // it was a valid log conf handle, so assume it's the first
  483. // res des we want
  484. //
  485. dnDevInst = ((PPrivate_Log_Conf_Handle)rdResDes)->LC_DevInst;
  486. ulLogType = ((PPrivate_Log_Conf_Handle)rdResDes)->LC_LogConfType;
  487. ulLogTag = ((PPrivate_Log_Conf_Handle)rdResDes)->LC_LogConfTag;
  488. ulResTag = MAX_RESDES_TAG;
  489. }
  490. else {
  491. //
  492. // it was neither a valid log conf nor a valid res des handle
  493. //
  494. Status = CR_INVALID_RES_DES;
  495. goto Clean0;
  496. }
  497. //
  498. // setup rpc binding handle and string table handle
  499. //
  500. if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
  501. Status = CR_FAILURE;
  502. goto Clean0;
  503. }
  504. //
  505. // retreive device instance string that corresponds to dnDevInst
  506. //
  507. Success = pSetupStringTableStringFromIdEx(hStringTable, dnDevInst,pDeviceID,&ulLen);
  508. if (Success == FALSE || INVALID_DEVINST(pDeviceID)) {
  509. Status = CR_INVALID_LOG_CONF;
  510. goto Clean0;
  511. }
  512. RpcTryExcept {
  513. //
  514. // call rpc service entry point
  515. //
  516. Status = PNP_GetNextResDes(
  517. hBinding, // rpc binding handle
  518. pDeviceID, // device id string
  519. ulLogTag, // log conf tag
  520. ulLogType, // log conf type
  521. ForResource, // resource type
  522. ulResTag, // resource tag
  523. &ulNextResTag, // next res des of type ForResource
  524. &ulNextResType, // type of next res des
  525. ulFlags); // 32/64 bit data
  526. }
  527. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode())) {
  528. KdPrintEx((DPFLTR_PNPMGR_ID,
  529. DBGF_ERRORS,
  530. "PNP_GetNextResDes caused an exception (%d)\n",
  531. RpcExceptionCode()));
  532. Status = MapRpcExceptionToCR(RpcExceptionCode());
  533. }
  534. RpcEndExcept
  535. if (Status != CR_SUCCESS) {
  536. goto Clean0;
  537. }
  538. if (ForResource == ResType_All) {
  539. *pResourceID = ulNextResType;
  540. }
  541. Status = CreateResDesHandle(prdResDes,
  542. dnDevInst,
  543. ulLogType,
  544. ulLogTag,
  545. ulNextResType,
  546. ulNextResTag);
  547. Clean0:
  548. NOTHING;
  549. } except(EXCEPTION_EXECUTE_HANDLER) {
  550. Status = CR_FAILURE;
  551. }
  552. return Status;
  553. } // CM_Get_Next_Res_Des_Ex
  554. CONFIGRET
  555. CM_Get_Res_Des_Data_Ex(
  556. IN RES_DES rdResDes,
  557. OUT PVOID Buffer,
  558. IN ULONG BufferLen,
  559. IN ULONG ulFlags,
  560. IN HMACHINE hMachine
  561. )
  562. /*++
  563. Routine Description:
  564. This routine copies the data from a specified resource descriptor
  565. into a buffer. Use the CM_Get_Res_Des_Data_Size API to determine
  566. the buffer size needed to receive the data. Alternately, set a
  567. size that is at least as large as the maximum possible size of the
  568. resource. If the size given is too small, the data is truncated and
  569. the API returns CR_BUFFER_SMALL.
  570. Parameters:
  571. rdResDes Supplies the handle of the resource descriptor from which
  572. data is to be copied.
  573. Buffer Supplies the address of the buffer that receives the data.
  574. BufferLen Supplies the size of the buffer, in bytes.
  575. ulFlags Specifies the width of certain variable-size resource
  576. descriptor structure fields, where applicable.
  577. Currently, the following flags are defined:
  578. CM_RESDES_WIDTH_32 or
  579. CM_RESDES_WIDTH_64
  580. If no flags are specified, the width of the variable-sized
  581. resource data expected is assumed to be that native to the
  582. platform of the caller.
  583. hMachine Machine handle returned from CM_Connect_Machine or NULL.
  584. Return Value:
  585. If the function succeeds, the return value is CR_SUCCESS.
  586. If the function fails, the return value is one of the following:
  587. CR_INVALID_FLAG,
  588. CR_INVALID_POINTER,
  589. CR_INVALID_RES_DES,
  590. CR_BUFFER_SMALL.
  591. --*/
  592. {
  593. CONFIGRET Status = CR_SUCCESS;
  594. DEVINST dnDevInst;
  595. WCHAR pDeviceID [MAX_DEVICE_ID_LEN];
  596. ULONG ulLogType, ulLogTag, ulResType, ulResTag,ulLen = MAX_DEVICE_ID_LEN;
  597. PVOID hStringTable = NULL;
  598. handle_t hBinding = NULL;
  599. BOOL Success;
  600. BOOL ConvertResDes = FALSE;
  601. try {
  602. //
  603. // validate parameters
  604. //
  605. if (!ValidateResDesHandle((PPrivate_Res_Des_Handle)rdResDes)) {
  606. Status = CR_INVALID_RES_DES;
  607. goto Clean0;
  608. }
  609. if (Buffer == NULL || BufferLen == 0) {
  610. Status = CR_INVALID_POINTER;
  611. goto Clean0;
  612. }
  613. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  614. Status = CR_INVALID_FLAG;
  615. goto Clean0;
  616. }
  617. if ((ulFlags & CM_RESDES_WIDTH_32) && (ulFlags & CM_RESDES_WIDTH_64)) {
  618. Status = CR_INVALID_FLAG;
  619. goto Clean0;
  620. }
  621. #ifdef _WIN64
  622. if ((ulFlags & CM_RESDES_WIDTH_BITS) == CM_RESDES_WIDTH_DEFAULT) {
  623. ulFlags |= CM_RESDES_WIDTH_64;
  624. }
  625. #endif // _WIN64
  626. if (ulFlags & CM_RESDES_WIDTH_32) {
  627. ulFlags &= ~CM_RESDES_WIDTH_BITS;
  628. }
  629. //
  630. // extract info from the res des handle
  631. //
  632. dnDevInst = ((PPrivate_Res_Des_Handle)rdResDes)->RD_DevInst;
  633. ulLogType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfType;
  634. ulLogTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfTag;
  635. ulResType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResourceType;
  636. ulResTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResDesTag;
  637. //
  638. // setup rpc binding handle and string table handle
  639. //
  640. if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
  641. Status = CR_FAILURE;
  642. goto Clean0;
  643. }
  644. //
  645. // Make sure the server can support the client's 64-bit resdes request.
  646. // Only server versions 0x0501 and greater support CM_RESDES_WIDTH_64.
  647. //
  648. if (ulFlags & CM_RESDES_WIDTH_64) {
  649. if (!CM_Is_Version_Available_Ex((WORD)0x0501,
  650. hMachine)) {
  651. //
  652. // Client will only give us 32-bit resdes. Request a 32-bit
  653. // resdes from the server, and we'll convert it to 64-bit here
  654. // on the client.
  655. //
  656. ulFlags &= ~CM_RESDES_WIDTH_BITS;
  657. ConvertResDes = TRUE;
  658. }
  659. }
  660. //
  661. // retreive device instance string that corresponds to dnDevInst
  662. //
  663. Success = pSetupStringTableStringFromIdEx(hStringTable, dnDevInst,pDeviceID,&ulLen);
  664. if (Success == FALSE || INVALID_DEVINST(pDeviceID)) {
  665. Status = CR_INVALID_RES_DES;
  666. goto Clean0;
  667. }
  668. RpcTryExcept {
  669. //
  670. // call rpc service entry point
  671. //
  672. Status = PNP_GetResDesData(
  673. hBinding, // rpc binding handle
  674. pDeviceID, // device id string
  675. ulLogTag, // log conf tag
  676. ulLogType, // log conf type
  677. ulResType, // resource type
  678. ulResTag, // resource tag
  679. Buffer, // return res des data
  680. BufferLen, // size in bytes of Buffer
  681. ulFlags); // 32/64 bit data
  682. }
  683. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode())) {
  684. KdPrintEx((DPFLTR_PNPMGR_ID,
  685. DBGF_ERRORS,
  686. "PNP_GetResDesData caused an exception (%d)\n",
  687. RpcExceptionCode()));
  688. Status = MapRpcExceptionToCR(RpcExceptionCode());
  689. }
  690. RpcEndExcept
  691. if((Status == CR_SUCCESS) && ConvertResDes) {
  692. Status = Convert32bitResDesTo64bitResDes(ulResType,Buffer,BufferLen);
  693. }
  694. Clean0:
  695. NOTHING;
  696. } except(EXCEPTION_EXECUTE_HANDLER) {
  697. Status = CR_FAILURE;
  698. }
  699. return Status;
  700. } // CM_Get_Res_Des_Data_Ex
  701. CONFIGRET
  702. CM_Get_Res_Des_Data_Size_Ex(
  703. OUT PULONG pulSize,
  704. IN RES_DES rdResDes,
  705. IN ULONG ulFlags,
  706. IN HMACHINE hMachine
  707. )
  708. /*++
  709. Routine Description:
  710. This routine retrieves the size of a resource descriptor, not
  711. including the resource descriptor header.
  712. Parameters:
  713. pulSize Supplies the address of the variable that receives the
  714. size, in bytes, of the resource descriptor data.
  715. rdResDes Supplies the handle of the resource descriptor for which
  716. to retrieve the size.
  717. ulFlags Specifies the width of certain variable-size resource
  718. descriptor structure fields, where applicable.
  719. Currently, the following flags are defined:
  720. CM_RESDES_WIDTH_32 or
  721. CM_RESDES_WIDTH_64
  722. If no flags are specified, the width of the variable-sized
  723. resource data expected is assumed to be that native to the
  724. platform of the caller.
  725. hMachine Machine handle returned from CM_Connect_Machine or NULL.
  726. Return Value:
  727. If the function succeeds, the return value is CR_SUCCESS.
  728. If the function fails, the return value is one of the following:
  729. CR_INVALID_RES_DES,
  730. CR_INVALID_FLAG,
  731. CR_INVALID_POINTER.
  732. --*/
  733. {
  734. CONFIGRET Status = CR_SUCCESS;
  735. DEVINST dnDevInst;
  736. WCHAR pDeviceID [MAX_DEVICE_ID_LEN];
  737. ULONG ulLogType, ulLogTag, ulResType, ulResTag,ulLen = MAX_DEVICE_ID_LEN;
  738. PVOID hStringTable = NULL;
  739. handle_t hBinding = NULL;
  740. BOOL Success;
  741. BOOL ConvertResDesSize = FALSE;
  742. try {
  743. //
  744. // validate parameters
  745. //
  746. if (!ValidateResDesHandle((PPrivate_Res_Des_Handle)rdResDes)) {
  747. Status = CR_INVALID_RES_DES;
  748. goto Clean0;
  749. }
  750. if (pulSize == NULL) {
  751. Status = CR_INVALID_POINTER;
  752. goto Clean0;
  753. }
  754. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  755. Status = CR_INVALID_FLAG;
  756. goto Clean0;
  757. }
  758. if ((ulFlags & CM_RESDES_WIDTH_32) && (ulFlags & CM_RESDES_WIDTH_64)) {
  759. Status = CR_INVALID_FLAG;
  760. goto Clean0;
  761. }
  762. #ifdef _WIN64
  763. if ((ulFlags & CM_RESDES_WIDTH_BITS) == CM_RESDES_WIDTH_DEFAULT) {
  764. ulFlags |= CM_RESDES_WIDTH_64;
  765. }
  766. #endif // _WIN64
  767. if (ulFlags & CM_RESDES_WIDTH_32) {
  768. ulFlags &= ~CM_RESDES_WIDTH_BITS;
  769. }
  770. //
  771. // Initialize output parameters
  772. //
  773. *pulSize = 0;
  774. //
  775. // extract info from the res des handle
  776. //
  777. dnDevInst = ((PPrivate_Res_Des_Handle)rdResDes)->RD_DevInst;
  778. ulLogType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfType;
  779. ulLogTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfTag;
  780. ulResType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResourceType;
  781. ulResTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResDesTag;
  782. //
  783. // setup rpc binding handle and string table handle
  784. //
  785. if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
  786. Status = CR_FAILURE;
  787. goto Clean0;
  788. }
  789. //
  790. // Make sure the server can support the client's 64-bit resdes request.
  791. // Only server versions 0x0501 and greater support CM_RESDES_WIDTH_64.
  792. //
  793. if (ulFlags & CM_RESDES_WIDTH_64) {
  794. if (!CM_Is_Version_Available_Ex((WORD)0x0501,
  795. hMachine)) {
  796. //
  797. // Server only supports 32-bit resdes. Request a 32-bit
  798. // resdes size from the server, and we'll convert it to 64-bit here
  799. // on the client.
  800. //
  801. ulFlags &= ~CM_RESDES_WIDTH_BITS;
  802. ConvertResDesSize = TRUE;
  803. }
  804. }
  805. //
  806. // retreive device instance string that corresponds to dnDevInst
  807. //
  808. Success = pSetupStringTableStringFromIdEx(hStringTable, dnDevInst,pDeviceID,&ulLen);
  809. if (Success == FALSE || INVALID_DEVINST(pDeviceID)) {
  810. Status = CR_INVALID_RES_DES;
  811. goto Clean0;
  812. }
  813. RpcTryExcept {
  814. //
  815. // call rpc service entry point
  816. //
  817. Status = PNP_GetResDesDataSize(
  818. hBinding, // rpc binding handle
  819. pDeviceID, // device id string
  820. ulLogTag, // log conf tag
  821. ulLogType, // log conf type
  822. ulResType, // resource type
  823. ulResTag, // resource tag
  824. pulSize, // returns size of res des data
  825. ulFlags); // currently zero
  826. }
  827. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode())) {
  828. KdPrintEx((DPFLTR_PNPMGR_ID,
  829. DBGF_ERRORS,
  830. "PNP_GetResDesDataSize caused an exception (%d)\n",
  831. RpcExceptionCode()));
  832. Status = MapRpcExceptionToCR(RpcExceptionCode());
  833. }
  834. RpcEndExcept
  835. if(Status == CR_SUCCESS) {
  836. Status = Convert32bitResDesSizeTo64bitResDesSize(ulResType,pulSize);
  837. }
  838. Clean0:
  839. NOTHING;
  840. } except(EXCEPTION_EXECUTE_HANDLER) {
  841. Status = CR_FAILURE;
  842. }
  843. return Status;
  844. } // CM_Get_Res_Des_Data_Size_Ex
  845. CONFIGRET
  846. CM_Modify_Res_Des_Ex(
  847. OUT PRES_DES prdResDes,
  848. IN RES_DES rdResDes,
  849. IN RESOURCEID ResourceID,
  850. IN PCVOID ResourceData,
  851. IN ULONG ResourceLen,
  852. IN ULONG ulFlags,
  853. IN HMACHINE hMachine
  854. )
  855. /*++
  856. Routine Description:
  857. This routine modifies a resource descriptor. This API retrieves a
  858. handle to the new resource descriptor. This may or may not be the
  859. handle of the original resource descriptor. The original resource
  860. descriptor handle is invalid after calling this API.
  861. Parameters:
  862. prdResDes Supplies the address of the variable that receives the
  863. handle of the modified resource descriptor.
  864. rdResDes Supplies the handle of the resource descriptor to be
  865. modified.
  866. ResourceID Specifies the type of resource to modify. Can be one
  867. of the ResType values described in Section 2.1..
  868. ResourceData Supplies the address of a resource data structure.
  869. ResourceLen Supplies the size, in bytes, of the new resource data
  870. structure. This size can be different from the size of
  871. the original resource data.
  872. ulFlags Specifies the width of certain variable-size resource
  873. descriptor structure fields, where applicable.
  874. Currently, the following flags are defined:
  875. CM_RESDES_WIDTH_32 or
  876. CM_RESDES_WIDTH_64
  877. If no flags are specified, the width of the variable-sized
  878. resource data supplied is assumed to be that native to the
  879. platform of the caller.
  880. hMachine Machine handle returned from CM_Connect_Machine or NULL.
  881. Return Value:
  882. If the function succeeds, the return value is CR_SUCCESS.
  883. If the function fails, the return value is one of the following:
  884. CR_INVALID_RES_DES,
  885. CR_INVALID_FLAG,
  886. CR_INVALID_POINTER,
  887. CR_OUT_OF_MEMORY.
  888. --*/
  889. {
  890. CONFIGRET Status = CR_SUCCESS;
  891. DEVINST dnDevInst;
  892. WCHAR pDeviceID [MAX_DEVICE_ID_LEN];
  893. ULONG ulLogType, ulLogTag, ulResType, ulResTag,ulLen = MAX_DEVICE_ID_LEN;
  894. PVOID hStringTable = NULL;
  895. handle_t hBinding = NULL;
  896. BOOL Success;
  897. PVOID ResourceData32 = NULL;
  898. ULONG ResourceLen32 = 0;
  899. try {
  900. //
  901. // validate parameters
  902. //
  903. if (!ValidateResDesHandle((PPrivate_Res_Des_Handle)rdResDes)) {
  904. Status = CR_INVALID_RES_DES;
  905. goto Clean0;
  906. }
  907. if (prdResDes == NULL) {
  908. Status = CR_INVALID_POINTER;
  909. goto Clean0;
  910. }
  911. #if 0
  912. if (ResourceID > ResType_MAX && ResourceID != ResType_ClassSpecific) {
  913. Status = CR_INVALID_RESOURCEID;
  914. goto Clean0;
  915. }
  916. #endif
  917. if (ResourceData == NULL || ResourceLen == 0) {
  918. Status = CR_INVALID_POINTER;
  919. goto Clean0;
  920. }
  921. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  922. Status = CR_INVALID_FLAG;
  923. goto Clean0;
  924. }
  925. if ((ulFlags & CM_RESDES_WIDTH_32) && (ulFlags & CM_RESDES_WIDTH_64)) {
  926. Status = CR_INVALID_FLAG;
  927. goto Clean0;
  928. }
  929. #ifdef _WIN64
  930. if ((ulFlags & CM_RESDES_WIDTH_BITS) == CM_RESDES_WIDTH_DEFAULT) {
  931. ulFlags |= CM_RESDES_WIDTH_64;
  932. }
  933. #endif // _WIN64
  934. if (ulFlags & CM_RESDES_WIDTH_32) {
  935. ulFlags &= ~CM_RESDES_WIDTH_BITS;
  936. }
  937. //
  938. // initialize output parameters
  939. //
  940. *prdResDes = 0;
  941. //
  942. // extract info from the res des handle
  943. //
  944. dnDevInst = ((PPrivate_Res_Des_Handle)rdResDes)->RD_DevInst;
  945. ulLogType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfType;
  946. ulLogTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_LogConfTag;
  947. ulResType = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResourceType;
  948. ulResTag = ((PPrivate_Res_Des_Handle)rdResDes)->RD_ResDesTag;
  949. //
  950. // setup rpc binding handle and string table handle
  951. //
  952. if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
  953. Status = CR_FAILURE;
  954. goto Clean0;
  955. }
  956. //
  957. // Make sure the server can support the client's 64-bit resdes request.
  958. // Only server versions 0x0501 and greater support CM_RESDES_WIDTH_64.
  959. //
  960. if (ulFlags & CM_RESDES_WIDTH_64) {
  961. if (!CM_Is_Version_Available_Ex((WORD)0x0501,
  962. hMachine)) {
  963. //
  964. // Server can only support 32-bit resdes. Have the client
  965. // convert the caller's 64-bit resdes to a 32-bit resdes for the
  966. // server.
  967. //
  968. ulFlags &= ~CM_RESDES_WIDTH_BITS;
  969. Status = Get32bitResDesFrom64bitResDes(ResourceID,ResourceData,ResourceLen,&ResourceData32,&ResourceLen32);
  970. if(Status != CR_SUCCESS) {
  971. goto Clean0;
  972. }
  973. if(ResourceData32) {
  974. ResourceData = ResourceData32;
  975. ResourceLen = ResourceLen32;
  976. }
  977. }
  978. }
  979. //
  980. // retreive device instance string that corresponds to dnDevInst
  981. //
  982. Success = pSetupStringTableStringFromIdEx(hStringTable, dnDevInst,pDeviceID,&ulLen);
  983. if (Success == FALSE || INVALID_DEVINST(pDeviceID)) {
  984. Status = CR_INVALID_LOG_CONF;
  985. goto Clean0;
  986. }
  987. RpcTryExcept {
  988. //
  989. // call rpc service entry point
  990. //
  991. Status = PNP_ModifyResDes(
  992. hBinding, // rpc binding handle
  993. pDeviceID, // device id string
  994. ulLogTag, // log conf tag
  995. ulLogType, // log conf type
  996. ulResType, // current resource type
  997. ResourceID, // new resource type
  998. ulResTag, // resource tag
  999. (LPBYTE)ResourceData, // actual res des data
  1000. ResourceLen, // size in bytes of ResourceData
  1001. ulFlags); // currently zero
  1002. }
  1003. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode())) {
  1004. KdPrintEx((DPFLTR_PNPMGR_ID,
  1005. DBGF_ERRORS,
  1006. "PNP_ModifyResDes caused an exception (%d)\n",
  1007. RpcExceptionCode()));
  1008. Status = MapRpcExceptionToCR(RpcExceptionCode());
  1009. }
  1010. RpcEndExcept
  1011. if (Status == CR_SUCCESS) {
  1012. //
  1013. // The resource type may change so a new handle is required and
  1014. // returned to caller.
  1015. //
  1016. Status = CreateResDesHandle(prdResDes,
  1017. dnDevInst,
  1018. ulLogType,
  1019. ulLogTag,
  1020. ResourceID,
  1021. ulResTag);
  1022. }
  1023. Clean0:
  1024. NOTHING;
  1025. } except(EXCEPTION_EXECUTE_HANDLER) {
  1026. Status = CR_FAILURE;
  1027. }
  1028. if(ResourceData32) {
  1029. pSetupFree(ResourceData32);
  1030. }
  1031. return Status;
  1032. } // CM_Modify_Res_Des_Ex
  1033. CMAPI
  1034. CONFIGRET
  1035. WINAPI
  1036. CM_Detect_Resource_Conflict_Ex(
  1037. IN DEVINST dnDevInst,
  1038. IN RESOURCEID ResourceID, OPTIONAL
  1039. IN PCVOID ResourceData, OPTIONAL
  1040. IN ULONG ResourceLen, OPTIONAL
  1041. OUT PBOOL pbConflictDetected,
  1042. IN ULONG ulFlags,
  1043. IN HMACHINE hMachine
  1044. )
  1045. /*++
  1046. Routine Description:
  1047. This depreciated routine calls CM_Query_Resource_Conflict_List to see if
  1048. dnDevInst is conflicting with any other devices. It is used for a simple
  1049. "has a conflict" check. CM_Query_Resource_Conflict_List returns more
  1050. details of the conflicts.
  1051. Parameters:
  1052. dnDevInst DEVINST we're doing the test for (ie, that resource belongs to)
  1053. ResourceID,ResourceData,ResourceLen
  1054. See if this resource conflicts with a device other than dnDevInst
  1055. pbConflictDetected
  1056. Set to TRUE on conflict, FALSE if no conflict
  1057. ulFlags Specifies the width of certain variable-size resource
  1058. descriptor structure fields, where applicable.
  1059. Currently, the following flags are defined:
  1060. CM_RESDES_WIDTH_32 or
  1061. CM_RESDES_WIDTH_64
  1062. If no flags are specified, the width of the variable-sized
  1063. resource data supplied is assumed to be that native to the
  1064. platform of the caller.
  1065. hMachine Machine handle returned from CM_Connect_Machine or NULL.
  1066. Return Value:
  1067. If the function succeeds, the return value is CR_SUCCESS.
  1068. If the function fails, the return value is one of the following:
  1069. CR_INVALID_RES_DES,
  1070. CR_INVALID_FLAG,
  1071. CR_INVALID_POINTER,
  1072. CR_OUT_OF_MEMORY.
  1073. --*/
  1074. {
  1075. CONFIGRET Status = CR_SUCCESS;
  1076. CONFLICT_LIST ConflictList = 0;
  1077. ULONG ConflictCount = 0;
  1078. WCHAR pDeviceID [MAX_DEVICE_ID_LEN]; // )
  1079. PVOID hStringTable = NULL; // > for validation only
  1080. handle_t hBinding = NULL; // )
  1081. ULONG ulLen = MAX_DEVICE_ID_LEN; // )
  1082. try {
  1083. //
  1084. // validate parameters - must maintain compatability with original implementation
  1085. // even though some of the error codes don't make sense
  1086. // don't change any of the parameters here, as they are needed for
  1087. // CM_Query_Resource_Conflict_List
  1088. //
  1089. if (dnDevInst == 0) {
  1090. Status = CR_INVALID_DEVINST;
  1091. goto Clean0;
  1092. }
  1093. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  1094. Status = CR_INVALID_FLAG;
  1095. goto Clean0;
  1096. }
  1097. if ((ulFlags & CM_RESDES_WIDTH_32) && (ulFlags & CM_RESDES_WIDTH_64)) {
  1098. Status = CR_INVALID_FLAG;
  1099. goto Clean0;
  1100. }
  1101. if (pbConflictDetected == NULL) {
  1102. Status = CR_INVALID_POINTER;
  1103. goto Clean0;
  1104. }
  1105. if (ResourceData == NULL || ResourceLen == 0) {
  1106. Status = CR_INVALID_POINTER;
  1107. goto Clean0;
  1108. }
  1109. if (ResourceID == ResType_All) {
  1110. Status = CR_INVALID_RESOURCEID; // can't specify All on a detect
  1111. goto Clean0;
  1112. }
  1113. //
  1114. // setup rpc binding handle and string table handle - for validation only
  1115. //
  1116. if (!PnPGetGlobalHandles(hMachine, &hStringTable, &hBinding)) {
  1117. Status = CR_FAILURE;
  1118. goto Clean0;
  1119. }
  1120. //
  1121. // retreive device instance string that corresponds to dnDevInst
  1122. // stupid status code for this check, but someone may rely on it
  1123. //
  1124. if ((pSetupStringTableStringFromIdEx(hStringTable,dnDevInst,pDeviceID,&ulLen) == FALSE)
  1125. || INVALID_DEVINST(pDeviceID)) {
  1126. Status = CR_INVALID_LOG_CONF;
  1127. goto Clean0;
  1128. }
  1129. //
  1130. // now implement via CM_Query_Resource_Conflict_List
  1131. // the only difference here is that this new implementation should return
  1132. // only valid conflicts
  1133. //
  1134. Status = CM_Query_Resource_Conflict_List(&ConflictList,
  1135. dnDevInst,
  1136. ResourceID,
  1137. ResourceData,
  1138. ResourceLen,
  1139. ulFlags,
  1140. hMachine);
  1141. if (Status != CR_SUCCESS) {
  1142. goto Clean0;
  1143. }
  1144. Status = CM_Get_Resource_Conflict_Count(ConflictList,&ConflictCount);
  1145. if (Status != CR_SUCCESS) {
  1146. goto Clean0;
  1147. }
  1148. *pbConflictDetected = ConflictCount ? TRUE : FALSE;
  1149. Clean0:
  1150. NOTHING;
  1151. } except(EXCEPTION_EXECUTE_HANDLER) {
  1152. Status = CR_FAILURE;
  1153. }
  1154. if (ConflictList) {
  1155. CM_Free_Resource_Conflict_Handle(ConflictList);
  1156. }
  1157. return Status;
  1158. } // CM_Detect_Resource_Conflict
  1159. CONFIGRET
  1160. CM_Free_Res_Des_Handle(
  1161. IN RES_DES rdResDes
  1162. )
  1163. /*++
  1164. Routine Description:
  1165. This routine frees the handle to the specified res des and frees and
  1166. memory associated with that res des handle.
  1167. Parameters:
  1168. rdResDes Supplies the handle of the resource descriptor.
  1169. Return Value:
  1170. If the function succeeds, the return value is CR_SUCCESS.
  1171. If the function fails, the return value is one of the following:
  1172. CR_INVALID_RES_DES.
  1173. --*/
  1174. {
  1175. CONFIGRET Status = CR_SUCCESS;
  1176. try {
  1177. //
  1178. // Validate parameters
  1179. //
  1180. if (!ValidateResDesHandle((PPrivate_Res_Des_Handle)rdResDes)) {
  1181. Status = CR_INVALID_RES_DES;
  1182. goto Clean0;
  1183. }
  1184. //
  1185. // It's a valid log conf handle, which is a pointer to memory
  1186. // allocated when the log conf was created or retrieved using
  1187. // the first/next routines. Free the associated memory.
  1188. //
  1189. ((PPrivate_Res_Des_Handle)rdResDes)->RD_Signature = 0;
  1190. pSetupFree((PPrivate_Res_Des_Handle)rdResDes);
  1191. Clean0:
  1192. NOTHING;
  1193. } except(EXCEPTION_EXECUTE_HANDLER) {
  1194. Status = CR_FAILURE;
  1195. }
  1196. return Status;
  1197. } // CM_Free_Res_Des_Handle
  1198. //-------------------------------------------------------------------
  1199. // Local Stubs
  1200. //-------------------------------------------------------------------
  1201. CONFIGRET
  1202. CM_Add_Res_Des(
  1203. OUT PRES_DES prdResDes,
  1204. IN LOG_CONF lcLogConf,
  1205. IN RESOURCEID ResourceID,
  1206. IN PCVOID ResourceData,
  1207. IN ULONG ResourceLen,
  1208. IN ULONG ulFlags
  1209. )
  1210. {
  1211. return CM_Add_Res_Des_Ex(prdResDes, lcLogConf, ResourceID, ResourceData,
  1212. ResourceLen, ulFlags, NULL);
  1213. }
  1214. CONFIGRET
  1215. CM_Free_Res_Des(
  1216. OUT PRES_DES prdResDes,
  1217. IN RES_DES rdResDes,
  1218. IN ULONG ulFlags
  1219. )
  1220. {
  1221. return CM_Free_Res_Des_Ex(prdResDes, rdResDes, ulFlags, NULL);
  1222. }
  1223. CONFIGRET
  1224. CM_Get_Next_Res_Des(
  1225. OUT PRES_DES prdResDes,
  1226. IN RES_DES rdResDes,
  1227. IN RESOURCEID ForResource,
  1228. OUT PRESOURCEID pResourceID,
  1229. IN ULONG ulFlags
  1230. )
  1231. {
  1232. return CM_Get_Next_Res_Des_Ex(prdResDes, rdResDes, ForResource,
  1233. pResourceID, ulFlags, NULL);
  1234. }
  1235. CONFIGRET
  1236. CM_Get_Res_Des_Data(
  1237. IN RES_DES rdResDes,
  1238. OUT PVOID Buffer,
  1239. IN ULONG BufferLen,
  1240. IN ULONG ulFlags
  1241. )
  1242. {
  1243. return CM_Get_Res_Des_Data_Ex(rdResDes, Buffer, BufferLen, ulFlags, NULL);
  1244. }
  1245. CONFIGRET
  1246. CM_Get_Res_Des_Data_Size(
  1247. OUT PULONG pulSize,
  1248. IN RES_DES rdResDes,
  1249. IN ULONG ulFlags
  1250. )
  1251. {
  1252. return CM_Get_Res_Des_Data_Size_Ex(pulSize, rdResDes, ulFlags, NULL);
  1253. }
  1254. CONFIGRET
  1255. CM_Modify_Res_Des(
  1256. OUT PRES_DES prdResDes,
  1257. IN RES_DES rdResDes,
  1258. IN RESOURCEID ResourceID,
  1259. IN PCVOID ResourceData,
  1260. IN ULONG ResourceLen,
  1261. IN ULONG ulFlags
  1262. )
  1263. {
  1264. return CM_Modify_Res_Des_Ex(prdResDes, rdResDes, ResourceID, ResourceData,
  1265. ResourceLen, ulFlags, NULL);
  1266. }
  1267. CONFIGRET
  1268. WINAPI
  1269. CM_Detect_Resource_Conflict(
  1270. IN DEVINST dnDevInst,
  1271. IN RESOURCEID ResourceID, OPTIONAL
  1272. IN PCVOID ResourceData, OPTIONAL
  1273. IN ULONG ResourceLen, OPTIONAL
  1274. OUT PBOOL pbConflictDetected,
  1275. IN ULONG ulFlags
  1276. )
  1277. {
  1278. return CM_Detect_Resource_Conflict_Ex(dnDevInst, ResourceID, ResourceData,
  1279. ResourceLen, pbConflictDetected,
  1280. ulFlags, NULL);
  1281. }
  1282. //-------------------------------------------------------------------
  1283. // Local Utility Routines
  1284. //-------------------------------------------------------------------
  1285. CONFIGRET
  1286. CreateResDesHandle(
  1287. PRES_DES prdResDes,
  1288. DEVINST dnDevInst,
  1289. ULONG ulLogType,
  1290. ULONG ulLogTag,
  1291. ULONG ulResType,
  1292. ULONG ulResTag
  1293. )
  1294. {
  1295. PPrivate_Res_Des_Handle pResDesHandle;
  1296. //
  1297. // allocate memory for the res des handle data
  1298. //
  1299. pResDesHandle = (PPrivate_Res_Des_Handle)pSetupMalloc(
  1300. sizeof(Private_Res_Des_Handle));
  1301. if (pResDesHandle == NULL) {
  1302. return CR_OUT_OF_MEMORY;
  1303. }
  1304. //
  1305. // fill in the private res des info and return as handle
  1306. //
  1307. pResDesHandle->RD_Signature = CM_PRIVATE_RESDES_SIGNATURE;
  1308. pResDesHandle->RD_DevInst = dnDevInst;
  1309. pResDesHandle->RD_LogConfType = ulLogType;
  1310. pResDesHandle->RD_LogConfTag = ulLogTag;
  1311. pResDesHandle->RD_ResourceType = ulResType;
  1312. pResDesHandle->RD_ResDesTag = ulResTag;
  1313. *prdResDes = (RES_DES)pResDesHandle;
  1314. return CR_SUCCESS;
  1315. } // CreateResDesHandle
  1316. BOOL
  1317. ValidateResDesHandle(
  1318. PPrivate_Res_Des_Handle pResDes
  1319. )
  1320. {
  1321. //
  1322. // validate parameters
  1323. //
  1324. if (pResDes == NULL || pResDes == 0) {
  1325. return FALSE;
  1326. }
  1327. //
  1328. // check for the private log conf signature
  1329. //
  1330. if (pResDes->RD_Signature != CM_PRIVATE_RESDES_SIGNATURE) {
  1331. return FALSE;
  1332. }
  1333. return TRUE;
  1334. } // ValidateResDesHandle
  1335. CONFIGRET
  1336. Convert32bitResDesSizeTo64bitResDesSize(
  1337. IN RESOURCEID ResourceID,
  1338. IN OUT PULONG ResLen
  1339. )
  1340. /*++
  1341. Routine Description:
  1342. This routine resizes ResLen for ResourceID
  1343. old structure: [DES32][RANGE32][RANGE32]...
  1344. new structure: [DES64 ][RANGE64 ][RANGE 64]...
  1345. #elements = (len-sizeof(DES32))/sizeof(RANGE32)
  1346. new len = sizeof(DES64)+#elements*sizeof(RANGE64)
  1347. (+ allow for alignment issues)
  1348. Parameters:
  1349. ResourceID - type of resource to adjust
  1350. ResLen - adjusted resource length
  1351. Return Value:
  1352. If the function succeeds, the return value is CR_SUCCESS.
  1353. --*/
  1354. {
  1355. switch(ResourceID) {
  1356. case ResType_All:
  1357. case ResType_Mem:
  1358. case ResType_IO:
  1359. case ResType_DMA:
  1360. case ResType_BusNumber:
  1361. //
  1362. // no change in resource size
  1363. //
  1364. return CR_SUCCESS;
  1365. case ResType_IRQ:
  1366. //
  1367. // header only
  1368. // use offsetof to handle non-obvious structure alignment padding
  1369. //
  1370. *ResLen += offsetof(IRQ_RESOURCE_64,IRQ_Data)-offsetof(IRQ_RESOURCE_32,IRQ_Data);
  1371. return CR_SUCCESS;
  1372. default:
  1373. //
  1374. // unknown resource
  1375. // shouldn't be a problem as this is for downlevel platforms
  1376. //
  1377. ASSERT(ResourceID & ResType_Ignored_Bit);
  1378. return CR_SUCCESS;
  1379. }
  1380. }
  1381. CONFIGRET
  1382. Get32bitResDesFrom64bitResDes(
  1383. IN RESOURCEID ResourceID,
  1384. IN PCVOID ResData64,
  1385. IN ULONG ResLen64,
  1386. OUT PVOID * ResData32,
  1387. OUT ULONG * ResLen32
  1388. )
  1389. /*++
  1390. Routine Description:
  1391. This routine allocates ResData32 and converts ResData64 into ResData32 if needed
  1392. In the cases where no conversion is required, CR_SUCCESS is returned and
  1393. ResData32 is NULL.
  1394. In the cases where conversion is required, ResData32 holds new data
  1395. old structure: [DES64 ][RANGE64 ][RANGE 64]...
  1396. new structure: [DES32][RANGE32][RANGE32]...
  1397. #elements from 64-bit structure
  1398. new len = sizeof(DES32)+#elements*sizeof(RANGE32)
  1399. (+ allow for alignment issues)
  1400. Parameters:
  1401. ResourceID - type of resource to adjust
  1402. ResData64 - incoming data to convert (constant buffer)
  1403. ResLen64 - incoming length of data
  1404. ResData32 - converted data (if non-NULL)
  1405. ResLen32 - converted length
  1406. Return Value:
  1407. If the function succeeds, the return value is CR_SUCCESS.
  1408. --*/
  1409. {
  1410. *ResData32 = NULL;
  1411. *ResLen32 = ResLen64;
  1412. switch(ResourceID) {
  1413. case ResType_All:
  1414. case ResType_Mem:
  1415. case ResType_IO:
  1416. case ResType_DMA:
  1417. case ResType_BusNumber:
  1418. //
  1419. // no change in resource structure
  1420. //
  1421. return CR_SUCCESS;
  1422. case ResType_IRQ:
  1423. {
  1424. PIRQ_RESOURCE_64 pIrq64 = (PIRQ_RESOURCE_64)ResData64;
  1425. ULONG HdrDiff = offsetof(IRQ_RESOURCE_64,IRQ_Data) - offsetof(IRQ_RESOURCE_32,IRQ_Data);
  1426. ULONG DataSize = ResLen64-offsetof(IRQ_RESOURCE_64,IRQ_Data);
  1427. ULONG NewResSize = DataSize+offsetof(IRQ_RESOURCE_32,IRQ_Data);
  1428. PVOID NewResData = pSetupMalloc(NewResSize);
  1429. PIRQ_RESOURCE_32 pIrq32 = (PIRQ_RESOURCE_32)NewResData;
  1430. if(NewResData == NULL) {
  1431. return CR_OUT_OF_MEMORY;
  1432. }
  1433. //
  1434. // copy header
  1435. //
  1436. MoveMemory(pIrq32,pIrq64,offsetof(IRQ_RESOURCE_32,IRQ_Data));
  1437. //
  1438. // copy/truncate Affinity (to ensure it's correct)
  1439. //
  1440. pIrq32->IRQ_Header.IRQD_Affinity = (ULONG32)pIrq64->IRQ_Header.IRQD_Affinity;
  1441. //
  1442. // copy data (trivial in this case)
  1443. //
  1444. MoveMemory(pIrq32->IRQ_Data,pIrq64->IRQ_Data,DataSize);
  1445. *ResLen32 = NewResSize;
  1446. *ResData32 = NewResData;
  1447. }
  1448. return CR_SUCCESS;
  1449. default:
  1450. //
  1451. // unknown resource
  1452. // shouldn't be a problem as this is for downlevel platforms
  1453. //
  1454. ASSERT(ResourceID & ResType_Ignored_Bit);
  1455. return CR_SUCCESS;
  1456. }
  1457. }
  1458. CONFIGRET
  1459. Convert32bitResDesTo64bitResDes(
  1460. IN RESOURCEID ResourceID,
  1461. IN OUT PVOID ResData,
  1462. IN ULONG ResLen
  1463. )
  1464. /*++
  1465. Routine Description:
  1466. This routine reuses ResData and ResLen converting the 32-bit data provided
  1467. into 64-bit. Return error if buffer (reslen) isn't big enough
  1468. old structure: [DES32][RANGE32][RANGE32]...
  1469. new structure: [DES64 ][RANGE64 ][RANGE 64]...
  1470. #elements from 32-bit structure
  1471. (+ allow for alignment issues)
  1472. Parameters:
  1473. ResourceID - type of resource to adjust
  1474. ResData - in, 32-bit, out, 64-bit
  1475. ResData32 - size of ResData buffer
  1476. Return Value:
  1477. If the function succeeds, the return value is CR_SUCCESS.
  1478. --*/
  1479. {
  1480. switch(ResourceID) {
  1481. case ResType_All:
  1482. case ResType_Mem:
  1483. case ResType_IO:
  1484. case ResType_DMA:
  1485. case ResType_BusNumber:
  1486. //
  1487. // no change in resource structure
  1488. //
  1489. return CR_SUCCESS;
  1490. case ResType_IRQ:
  1491. {
  1492. PIRQ_RESOURCE_64 pIrq64 = (PIRQ_RESOURCE_64)ResData;
  1493. PIRQ_RESOURCE_32 pIrq32 = (PIRQ_RESOURCE_32)ResData;
  1494. ULONG HdrDiff = offsetof(IRQ_RESOURCE_64,IRQ_Data) - offsetof(IRQ_RESOURCE_32,IRQ_Data);
  1495. ULONG DataSize = pIrq32->IRQ_Header.IRQD_Count * sizeof(IRQ_RANGE);
  1496. ULONG NewResSize = DataSize+offsetof(IRQ_RESOURCE_64,IRQ_Data);
  1497. if(NewResSize > ResLen) {
  1498. return CR_BUFFER_SMALL;
  1499. }
  1500. //
  1501. // work top to bottom
  1502. // copy data (trivial in this case)
  1503. // MoveMemory handles overlap
  1504. //
  1505. MoveMemory(pIrq64->IRQ_Data,pIrq32->IRQ_Data,DataSize);
  1506. //
  1507. // header is in correct position
  1508. // but we need to deal with affinity... copy only low 32-bits
  1509. //
  1510. pIrq64->IRQ_Header.IRQD_Affinity = pIrq32->IRQ_Header.IRQD_Affinity;
  1511. }
  1512. return CR_SUCCESS;
  1513. default:
  1514. //
  1515. // unknown resource
  1516. // shouldn't be a problem as this is for downlevel platforms
  1517. //
  1518. ASSERT(ResourceID & ResType_Ignored_Bit);
  1519. return CR_SUCCESS;
  1520. }
  1521. }