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.

1962 lines
58 KiB

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