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.

4984 lines
163 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. rresdes.c
  5. Abstract:
  6. This module contains the server-side resource description APIs.
  7. PNP_AddResDes
  8. PNP_FreeResDes
  9. PNP_GetNextResDes
  10. PNP_GetResDesData
  11. PNP_GetResDesDataSize
  12. PNP_ModifyResDes
  13. PNP_DetectResourceConflict
  14. Author:
  15. Paula Tomlinson (paulat) 9-27-1995
  16. Environment:
  17. User-mode only.
  18. Revision History:
  19. 27-Sept-1995 paulat
  20. Creation and initial implementation.
  21. --*/
  22. //
  23. // includes
  24. //
  25. #include "precomp.h"
  26. #pragma hdrstop
  27. #include "umpnpi.h"
  28. #include <pcmciap.h>
  29. //
  30. // private prototypes
  31. //
  32. BOOL
  33. FindLogConf(
  34. IN LPBYTE pList,
  35. OUT LPBYTE *ppLogConf,
  36. IN ULONG RegDataType,
  37. IN ULONG ulTag
  38. );
  39. BOOL
  40. FindResDes(
  41. IN LPBYTE pList,
  42. IN ULONG RegDataType,
  43. IN ULONG ulLogConfTag,
  44. IN ULONG ulResTag,
  45. IN RESOURCEID ResType,
  46. OUT LPBYTE *ppRD,
  47. OUT LPBYTE *ppLogConf,
  48. OUT PULONG pulSubIndex OPTIONAL
  49. );
  50. PIO_RESOURCE_DESCRIPTOR
  51. AdvanceRequirementsDescriptorPtr(
  52. IN PIO_RESOURCE_DESCRIPTOR pReqDesStart,
  53. IN ULONG ulIncrement,
  54. IN ULONG ulRemainingRanges,
  55. OUT PULONG pulRangeCount
  56. );
  57. ULONG
  58. RANGE_COUNT(
  59. IN PIO_RESOURCE_DESCRIPTOR pReqDes,
  60. IN LPBYTE pLastReqAddr
  61. );
  62. ULONG
  63. GetResDesSize(
  64. IN ULONG ResourceID,
  65. IN ULONG ulFlags
  66. );
  67. ULONG
  68. GetReqDesSize(
  69. IN ULONG ResourceID,
  70. IN PIO_RESOURCE_DESCRIPTOR pReqDes,
  71. IN LPBYTE pLastReqAddr,
  72. IN ULONG ulFlags
  73. );
  74. CONFIGRET
  75. ResDesToNtResource(
  76. IN PCVOID ResourceData,
  77. IN RESOURCEID ResourceID,
  78. IN ULONG ResourceLen,
  79. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes,
  80. IN ULONG ulTag,
  81. IN ULONG ulFlags
  82. );
  83. CONFIGRET
  84. ResDesToNtRequirements(
  85. IN PCVOID ResourceData,
  86. IN RESOURCEID ResourceType,
  87. IN ULONG ResourceLen,
  88. IN PIO_RESOURCE_DESCRIPTOR pReqDes,
  89. IN OUT PULONG pulResCount,
  90. IN ULONG ulTag,
  91. IN ULONG ulFlags
  92. );
  93. CONFIGRET
  94. NtResourceToResDes(
  95. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes,
  96. IN OUT LPBYTE Buffer,
  97. IN ULONG BufferLen,
  98. IN LPBYTE pLastAddr,
  99. IN ULONG ulFlags
  100. );
  101. CONFIGRET
  102. NtRequirementsToResDes(
  103. IN PIO_RESOURCE_DESCRIPTOR pReqDes,
  104. IN OUT LPBYTE Buffer,
  105. IN ULONG BufferLen,
  106. IN LPBYTE pLastAddr,
  107. IN ULONG ulFlags
  108. );
  109. UCHAR
  110. NT_RES_TYPE(
  111. IN RESOURCEID ResourceID
  112. );
  113. ULONG
  114. CM_RES_TYPE(
  115. IN UCHAR ResourceType
  116. );
  117. USHORT MapToNtMemoryFlags(IN DWORD);
  118. DWORD MapFromNtMemoryFlags(IN USHORT);
  119. USHORT MapToNtPortFlags(IN DWORD, IN DWORD);
  120. DWORD MapFromNtPortFlags(IN USHORT);
  121. DWORD MapAliasFromNtPortFlags(IN USHORT);
  122. ULONG MapToNtAlignment(IN DWORDLONG);
  123. DWORDLONG MapFromNtAlignment(IN ULONG);
  124. USHORT MapToNtDmaFlags(IN DWORD);
  125. DWORD MapFromNtDmaFlags(IN USHORT);
  126. USHORT MapToNtIrqFlags(IN DWORD);
  127. DWORD MapFromNtIrqFlags(IN USHORT);
  128. UCHAR MapToNtIrqShare(IN DWORD);
  129. DWORD MapFromNtIrqShare(IN UCHAR);
  130. //
  131. // prototypes from rlogconf.c
  132. //
  133. CONFIGRET
  134. GetLogConfData(
  135. IN HKEY hKey,
  136. IN ULONG ulLogConfType,
  137. OUT PULONG pulRegDataType,
  138. OUT LPWSTR pszValueName,
  139. OUT LPBYTE *ppBuffer,
  140. OUT PULONG pulBufferSize
  141. );
  142. PCM_FULL_RESOURCE_DESCRIPTOR
  143. AdvanceResourcePtr(
  144. IN PCM_FULL_RESOURCE_DESCRIPTOR pRes
  145. );
  146. PIO_RESOURCE_LIST
  147. AdvanceRequirementsPtr(
  148. IN PIO_RESOURCE_LIST pReq
  149. );
  150. //
  151. // global data
  152. //
  153. #define HIDWORD(x) ((DWORD)(((DWORDLONG)(x) >> 32) & 0xFFFFFFFF))
  154. #define LODWORD(x) ((DWORD)(x))
  155. #define MAKEDWORDLONG(x,y) ((DWORDLONG)(((DWORD)(x)) | ((DWORDLONG)((DWORD)(y))) << 32))
  156. CONFIGRET
  157. PNP_AddResDes(
  158. IN handle_t hBinding,
  159. IN LPWSTR pDeviceID,
  160. IN ULONG LogConfTag,
  161. IN ULONG LogConfType,
  162. IN RESOURCEID ResourceID,
  163. OUT PULONG pResourceTag,
  164. IN LPBYTE ResourceData,
  165. IN ULONG ResourceLen,
  166. IN ULONG ulFlags
  167. )
  168. /*++
  169. Routine Description:
  170. This the server-side of an RPC remote call. This routine adds
  171. a res des to the specified log conf.
  172. Arguments:
  173. hBinding RPC binding handle.
  174. pDeviceID Null-terminated device instance id string.
  175. LogConfTag Specifies the log conf within a given type.
  176. LogConfType Specifies the log conf type.
  177. ResourceID Specifies the resource type.
  178. ResourceTag Returns with resource within a given type.
  179. ResourceData Resource data (of ResourceID type) to add to log conf.
  180. ResourceLen Size of ResourceData in bytes.
  181. ulFlags Specifies the width of certain variable-size resource
  182. descriptor structure fields, where applicable.
  183. Currently, the following flags are defined:
  184. CM_RESDES_WIDTH_32 or
  185. CM_RESDES_WIDTH_64
  186. If no flags are specified, the width of the variable-sized
  187. resource data supplied is assumed to be that native to the
  188. platform of the caller.
  189. Return Value:
  190. If the specified device instance is valid, it returns CR_SUCCESS,
  191. otherwise it returns CR_ error code.
  192. --*/
  193. {
  194. CONFIGRET Status = CR_SUCCESS;
  195. HKEY hKey = NULL;
  196. WCHAR szValueName[64];
  197. ULONG RegDataType = 0, ulListSize = 0, i = 0, ulSize = 0, ulOffset = 0,
  198. ulAddListSize = 0;
  199. LPBYTE pList = NULL, pLogConf = NULL, pTemp = NULL;
  200. //
  201. // Always add the res des to the end, except in the case where a
  202. // class-specific res des has already been added. The class-specific
  203. // res des always MUST be last so add any new (non-class specific)
  204. // res des just before the class specific. Note that there can be
  205. // only one class-specific res des.
  206. //
  207. try {
  208. //
  209. // Verify client "write" access
  210. //
  211. if (!VerifyClientAccess(hBinding,
  212. PLUGPLAY_WRITE)) {
  213. Status = CR_ACCESS_DENIED;
  214. goto Clean0;
  215. }
  216. //
  217. // validate/initialize output parameters
  218. //
  219. if (!ARGUMENT_PRESENT(pResourceTag)) {
  220. Status = CR_INVALID_POINTER;
  221. goto Clean0;
  222. } else {
  223. *pResourceTag = 0;
  224. }
  225. //
  226. // validate parameters
  227. //
  228. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  229. Status = CR_INVALID_FLAG;
  230. goto Clean0;
  231. }
  232. //
  233. // validate res des size
  234. //
  235. if (ResourceLen < GetResDesSize(ResourceID, ulFlags)) {
  236. Status = CR_INVALID_DATA;
  237. goto Clean0;
  238. }
  239. //
  240. // make sure original caller didn't specify root devnode
  241. //
  242. if (!IsLegalDeviceId(pDeviceID) || IsRootDeviceID(pDeviceID)) {
  243. Status = CR_INVALID_LOG_CONF;
  244. goto Clean0;
  245. }
  246. //
  247. // open a key to the device's LogConf subkey
  248. //
  249. Status = OpenLogConfKey(pDeviceID, LogConfType, &hKey);
  250. if (Status != CR_SUCCESS) {
  251. goto Clean0;
  252. }
  253. //
  254. // Retrieve log conf data from the registry
  255. //
  256. Status = GetLogConfData(hKey, LogConfType,
  257. &RegDataType, szValueName,
  258. &pList, &ulListSize);
  259. if (Status != CR_SUCCESS) {
  260. goto Clean0;
  261. }
  262. //
  263. // Seek to the log conf that matches the log conf tag
  264. //
  265. if (!FindLogConf(pList, &pLogConf, RegDataType, LogConfTag)) {
  266. Status = CR_INVALID_LOG_CONF;
  267. goto Clean0;
  268. }
  269. //-------------------------------------------------------------
  270. // Specified log conf type contains Resource Data only
  271. //-------------------------------------------------------------
  272. if (RegDataType == REG_RESOURCE_LIST) {
  273. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  274. PCM_FULL_RESOURCE_DESCRIPTOR pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)pLogConf;
  275. PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes = NULL;
  276. //
  277. // determine size required to hold the new res des
  278. //
  279. ulAddListSize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
  280. if (ResourceID == ResType_ClassSpecific) {
  281. PCS_RESOURCE pCsRes = (PCS_RESOURCE)ResourceData;
  282. //
  283. // first make sure there isn't already a cs (only one per lc)
  284. //
  285. if (pRes->PartialResourceList.Count != 0 &&
  286. pRes->PartialResourceList.PartialDescriptors[pRes->PartialResourceList.Count-1].Type
  287. == CmResourceTypeDeviceSpecific) {
  288. Status = CR_INVALID_RES_DES;
  289. goto Clean0;
  290. }
  291. //
  292. // account for any extra class specific data in res list
  293. //
  294. ulAddListSize += sizeof(GUID) +
  295. pCsRes->CS_Header.CSD_SignatureLength +
  296. pCsRes->CS_Header.CSD_LegacyDataSize;
  297. }
  298. //
  299. // reallocate the resource buffers to hold the new res des
  300. //
  301. ulOffset = (DWORD)((ULONG_PTR)pRes - (ULONG_PTR)pResList); // for restoring later
  302. pResList = HeapReAlloc(ghPnPHeap, 0, pList, ulListSize + ulAddListSize);
  303. if (pResList == NULL) {
  304. Status = CR_OUT_OF_MEMORY;
  305. goto Clean0;
  306. }
  307. pList = (LPBYTE)pResList;
  308. pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)((LPBYTE)pResList + ulOffset);
  309. //
  310. // Find location for new res des (make a hole if necessary)
  311. //
  312. // If the following conditions are true, then can just append the
  313. // new data to the end of the rsource list:
  314. // - The selected LogConf is the last LogConf, and
  315. // - No ClassSpecific resource has been added yet (or no resource period)
  316. //
  317. i = pRes->PartialResourceList.Count;
  318. if ((LogConfTag == pResList->Count - 1) &&
  319. (i == 0 ||
  320. pRes->PartialResourceList.PartialDescriptors[i-1].Type !=
  321. CmResourceTypeDeviceSpecific)) {
  322. *pResourceTag = i;
  323. pResDes = &pRes->PartialResourceList.PartialDescriptors[i];
  324. } else {
  325. //
  326. // Need to make a hole for the new data before copying it.
  327. // Find the spot to add the new res des data at - either as the
  328. // last res des for this log conf or just before the class
  329. // specific res des if it exists.
  330. //
  331. if (i == 0) {
  332. *pResourceTag = 0;
  333. pResDes = &pRes->PartialResourceList.PartialDescriptors[0];
  334. } else if (pRes->PartialResourceList.PartialDescriptors[i-1].Type ==
  335. CmResourceTypeDeviceSpecific) {
  336. *pResourceTag = i-1;
  337. pResDes = &pRes->PartialResourceList.PartialDescriptors[i-1];
  338. } else {
  339. *pResourceTag = i;
  340. pResDes = &pRes->PartialResourceList.PartialDescriptors[i];
  341. }
  342. //
  343. // Move any data after this point down a notch to make room for
  344. // the new res des
  345. //
  346. ulSize = ulListSize - (DWORD)((ULONG_PTR)pResDes - (ULONG_PTR)pResList);
  347. pTemp = HeapAlloc(ghPnPHeap, 0, ulSize);
  348. if (pTemp == NULL) {
  349. Status = CR_OUT_OF_MEMORY;
  350. goto Clean0;
  351. }
  352. memcpy(pTemp, pResDes, ulSize);
  353. memcpy((LPBYTE)((LPBYTE)pResDes + ulAddListSize), pTemp, ulSize);
  354. }
  355. if (ResourceID == ResType_ClassSpecific) {
  356. *pResourceTag = RESDES_CS_TAG;
  357. }
  358. //
  359. // Add res des to the log conf
  360. //
  361. Status = ResDesToNtResource(ResourceData, ResourceID, ResourceLen,
  362. pResDes, *pResourceTag, ulFlags);
  363. //
  364. // update the lc and res header
  365. //
  366. pRes->PartialResourceList.Count += 1; // added a single res des (_DES)
  367. }
  368. //-------------------------------------------------------------
  369. // Specified log conf type contains requirements data only
  370. //-------------------------------------------------------------
  371. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  372. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  373. PIO_RESOURCE_LIST pReq = (PIO_RESOURCE_LIST)pLogConf;
  374. PIO_RESOURCE_DESCRIPTOR pReqDes = NULL;
  375. PGENERIC_RESOURCE pGenRes = (PGENERIC_RESOURCE)ResourceData;
  376. //
  377. // validate res des type - ClassSpecific not allowed in
  378. // requirements list (only resource list)
  379. //
  380. if (ResourceID == ResType_ClassSpecific ||
  381. pGenRes->GENERIC_Header.GENERIC_Count == 0) {
  382. Status = CR_INVALID_RES_DES;
  383. goto Clean0;
  384. }
  385. //
  386. // determine size required to hold the new res des
  387. //
  388. ulAddListSize = pGenRes->GENERIC_Header.GENERIC_Count *
  389. sizeof(IO_RESOURCE_DESCRIPTOR);
  390. //
  391. // reallocate the resource buffers to hold the new res des
  392. //
  393. ulOffset = (DWORD)((ULONG_PTR)pReq - (ULONG_PTR)pReqList); // for restoring later
  394. pReqList = HeapReAlloc(ghPnPHeap, 0, pList, ulListSize + ulAddListSize);
  395. if (pReqList == NULL) {
  396. Status = CR_OUT_OF_MEMORY;
  397. goto Clean0;
  398. }
  399. pList = (LPBYTE)pReqList;
  400. pReq = (PIO_RESOURCE_LIST)((LPBYTE)pReqList + ulOffset);
  401. //
  402. // Find location for new res des - the new res des always ends
  403. // up being added as the last res des for this log conf.
  404. //
  405. *pResourceTag = pReq->Count;
  406. pReqDes = &pReq->Descriptors[*pResourceTag];
  407. //
  408. // If the selected LogConf is the last LogConf then can just
  409. // append the new res des data to the end of the requirements
  410. // list. Otherwise, need to make a whole for the new data
  411. // before copying it.
  412. //
  413. if (LogConfTag != pReqList->AlternativeLists - 1) {
  414. ulSize = ulListSize - (DWORD)((ULONG_PTR)pReqDes - (ULONG_PTR)pReqList);
  415. pTemp = HeapAlloc(ghPnPHeap, 0, ulSize);
  416. if (pTemp == NULL) {
  417. Status = CR_OUT_OF_MEMORY;
  418. goto Clean0;
  419. }
  420. memcpy(pTemp, pReqDes, ulSize);
  421. memcpy((LPBYTE)((LPBYTE)pReqDes + ulAddListSize), pTemp, ulSize);
  422. }
  423. //
  424. // Add res des to the log conf.
  425. //
  426. Status = ResDesToNtRequirements(ResourceData, ResourceID, ResourceLen,
  427. pReqDes, &i, *pResourceTag, ulFlags);
  428. //
  429. // update the lc and res header
  430. //
  431. pReq->Count += i; // _RANGES added
  432. pReqList->ListSize = ulListSize + ulAddListSize;
  433. }
  434. //
  435. // Write out the new/updated log conf list to the registry
  436. //
  437. if (RegSetValueEx(hKey, szValueName, 0, RegDataType,
  438. pList, ulListSize + ulAddListSize)
  439. != ERROR_SUCCESS) {
  440. Status = CR_REGISTRY_ERROR;
  441. goto Clean0;
  442. }
  443. Clean0:
  444. NOTHING;
  445. } except(EXCEPTION_EXECUTE_HANDLER) {
  446. Status = CR_FAILURE;
  447. }
  448. if (pList != NULL) {
  449. HeapFree(ghPnPHeap, 0, pList);
  450. }
  451. if (pTemp != NULL) {
  452. HeapFree(ghPnPHeap, 0, pTemp);
  453. }
  454. if (hKey != NULL) {
  455. RegCloseKey(hKey);
  456. }
  457. return Status;
  458. } // PNP_AddResDes
  459. CONFIGRET
  460. PNP_FreeResDes(
  461. IN handle_t hBinding,
  462. IN LPWSTR pDeviceID,
  463. IN ULONG LogConfTag,
  464. IN ULONG LogConfType,
  465. IN RESOURCEID ResourceID,
  466. IN ULONG ResourceTag,
  467. OUT PULONG pulPreviousResType,
  468. OUT PULONG pulPreviousResTag,
  469. IN ULONG ulFlags
  470. )
  471. /*++
  472. Routine Description:
  473. This the server-side of an RPC remote call. This routine frees
  474. a res des to the specified log conf.
  475. Arguments:
  476. hBinding RPC binding handle.
  477. pDeviceID Null-terminated device instance id string.
  478. LogConfTag Specifies the log conf within a given type.
  479. LogConfType Specifies the log conf type.
  480. ResourceID Specifies the resource type.
  481. ResourceTag Specifies the resource within a given type.
  482. pulPreviousResType Receives the previous resource type.
  483. pulPreviousResTag Receives the previous resource within a given type.
  484. ulFlags Not used, must be zero.
  485. Return Value:
  486. If the specified device instance is valid, it returns CR_SUCCESS,
  487. otherwise it returns CR_ error code.
  488. --*/
  489. {
  490. CONFIGRET Status = CR_SUCCESS;
  491. HKEY hKey = NULL;
  492. WCHAR szValueName[64];
  493. ULONG RegDataType=0, RdCount=0, ulCount=0, ulListSize=0, ulSize=0;
  494. LPBYTE pList=NULL, pLogConf=NULL, pRD=NULL, pTemp=NULL, pNext=NULL;
  495. try {
  496. //
  497. // Verify client "write" access
  498. //
  499. if (!VerifyClientAccess(hBinding,
  500. PLUGPLAY_WRITE)) {
  501. Status = CR_ACCESS_DENIED;
  502. goto Clean0;
  503. }
  504. //
  505. // validate parameters
  506. //
  507. if (INVALID_FLAGS(ulFlags, 0)) {
  508. Status = CR_INVALID_FLAG;
  509. goto Clean0;
  510. }
  511. //
  512. // make sure original caller didn't specify root devnode
  513. //
  514. if (!IsLegalDeviceId(pDeviceID) || IsRootDeviceID(pDeviceID)) {
  515. Status = CR_INVALID_LOG_CONF;
  516. goto Clean0;
  517. }
  518. //
  519. // open a key to the device's LogConf subkey
  520. //
  521. Status = OpenLogConfKey(pDeviceID, LogConfType, &hKey);
  522. if (Status != CR_SUCCESS) {
  523. goto Clean0;
  524. }
  525. //
  526. // Retrieve log conf data from the registry
  527. //
  528. Status = GetLogConfData(hKey, LogConfType,
  529. &RegDataType, szValueName,
  530. &pList, &ulListSize);
  531. if (Status != CR_SUCCESS) {
  532. Status = CR_INVALID_RES_DES; // log conf doesn't exist
  533. goto Clean0;
  534. }
  535. //
  536. // seek to the res des that matches the resource tag.
  537. //
  538. if (!FindResDes(pList, RegDataType, LogConfTag,
  539. ResourceTag, ResourceID, &pRD, &pLogConf, &ulCount)) {
  540. Status = CR_INVALID_RES_DES;
  541. goto Clean0;
  542. }
  543. //-------------------------------------------------------------
  544. // Specified log conf type contains Resource Data only
  545. //-------------------------------------------------------------
  546. if (RegDataType == REG_RESOURCE_LIST) {
  547. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  548. PCM_FULL_RESOURCE_DESCRIPTOR pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)pLogConf;
  549. PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)pRD;
  550. //
  551. // If this is the last log conf and last res des, then don't
  552. // need to do anything except truncate it by writing less data
  553. // back into the registry.
  554. //
  555. if ((LogConfTag == pResList->Count - 1) &&
  556. ((ResourceTag == pRes->PartialResourceList.Count - 1) ||
  557. (ResourceTag == RESDES_CS_TAG))) {
  558. pRes->PartialResourceList.Count -= 1;
  559. ulListSize = (DWORD)((ULONG_PTR)(pResDes) - (ULONG_PTR)(pResList));
  560. } else {
  561. //
  562. // If the res des is not at the end of the structure, then
  563. // migrate the remainder of the structure up to keep the
  564. // struct contiguous when removing a res des.
  565. //
  566. // pResDes points to the beginning of the res des to remove,
  567. // pNext points to the byte just after the res des to remove
  568. //
  569. pNext = (LPBYTE)((LPBYTE)pResDes + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  570. if (pResDes->Type == CmResourceTypeDeviceSpecific) {
  571. pNext += pResDes->u.DeviceSpecificData.DataSize;
  572. }
  573. ulSize = ulListSize - (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pResList);
  574. ulListSize -= (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pResDes); // new lc list size
  575. pTemp = HeapAlloc(ghPnPHeap, 0, ulSize);
  576. if (pTemp == NULL) {
  577. Status = CR_OUT_OF_MEMORY;
  578. goto Clean0;
  579. }
  580. memcpy(pTemp, pNext, ulSize);
  581. memcpy((LPBYTE)pResDes, pTemp, ulSize);
  582. pRes->PartialResourceList.Count -= 1;
  583. }
  584. //
  585. // if no more res des's in this log conf, then return that
  586. // status (the client side will return a handle to the lc)
  587. //
  588. if (pRes->PartialResourceList.Count == 0) {
  589. Status = CR_NO_MORE_RES_DES;
  590. } else {
  591. //
  592. // return the previous res des type and tag
  593. //
  594. *pulPreviousResType =
  595. CM_RES_TYPE(pRes->PartialResourceList.PartialDescriptors[ResourceTag-1].Type);
  596. if (*pulPreviousResType == ResType_ClassSpecific) {
  597. *pulPreviousResTag = RESDES_CS_TAG; // special tag for cs
  598. } else {
  599. *pulPreviousResTag = ResourceTag - 1;
  600. }
  601. }
  602. }
  603. //-------------------------------------------------------------
  604. // Specified log conf type contains requirements data only
  605. //-------------------------------------------------------------
  606. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  607. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  608. PIO_RESOURCE_LIST pReq = (PIO_RESOURCE_LIST)pLogConf;
  609. PIO_RESOURCE_DESCRIPTOR pReqDes = (PIO_RESOURCE_DESCRIPTOR)pRD;
  610. //
  611. // If this is the last log conf and last res des, then don't
  612. // need to do anything except truncate it by writing less data
  613. // back into the registry.
  614. //
  615. RdCount = RANGE_COUNT(pReqDes, (LPBYTE)pReqList + ulListSize - 1);
  616. if ((LogConfTag == pReqList->AlternativeLists - 1) &&
  617. (RdCount + ulCount == pReq->Count - 1)) {
  618. ulListSize = (DWORD)((ULONG_PTR)(pReqDes) - (ULONG_PTR)pReqList);
  619. } else {
  620. //
  621. // If the res des is not at the end of the structure, then
  622. // migrate the remainder of the structure up to keep the
  623. // struct contiguous when removing a res des.
  624. //
  625. // pReqDes points to the beginning of the res des(s) to remove,
  626. // pNext points to the byte just after the res des(s) to remove
  627. //
  628. pNext = (LPBYTE)((LPBYTE)pReqDes +
  629. RdCount * sizeof(IO_RESOURCE_DESCRIPTOR));
  630. ulSize = ulListSize - (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pReqList);
  631. ulListSize -= (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pReqDes); // new lc list size
  632. pTemp = HeapAlloc(ghPnPHeap, 0, ulSize);
  633. if (pTemp == NULL) {
  634. Status = CR_OUT_OF_MEMORY;
  635. goto Clean0;
  636. }
  637. memcpy(pTemp, pNext, ulSize);
  638. memcpy((LPBYTE)pReqDes, pTemp, ulSize);
  639. }
  640. pReqList->ListSize = ulListSize;
  641. pReq->Count -= RdCount;
  642. //
  643. // if no more res des's in this log conf, then return that status
  644. // (the client side will return a handle to the log conf)
  645. //
  646. if (pReq->Count == 0) {
  647. Status = CR_NO_MORE_RES_DES;
  648. } else {
  649. //
  650. // return the previous res des type and tag
  651. //
  652. pReqDes =
  653. AdvanceRequirementsDescriptorPtr(
  654. &pReq->Descriptors[0],
  655. ResourceTag-1, pReq->Count, NULL);
  656. //
  657. // Double check whether this is the first ConfigData res des,
  658. // skip it if so.
  659. //
  660. if (pReqDes == NULL || pReqDes->Type == CmResourceTypeConfigData) {
  661. Status = CR_NO_MORE_RES_DES;
  662. } else {
  663. *pulPreviousResType = CM_RES_TYPE(pReqDes->Type);
  664. *pulPreviousResTag = ResourceTag - 1;
  665. }
  666. }
  667. }
  668. //
  669. // Write out the updated log conf list to the registry
  670. //
  671. if (RegSetValueEx(hKey, szValueName, 0, RegDataType,
  672. pList, ulListSize) != ERROR_SUCCESS) {
  673. Status = CR_REGISTRY_ERROR;
  674. goto Clean0;
  675. }
  676. Clean0:
  677. NOTHING;
  678. } except(EXCEPTION_EXECUTE_HANDLER) {
  679. Status = CR_INVALID_RES_DES; // mostly likely reason we got here
  680. }
  681. if (pList != NULL) {
  682. HeapFree(ghPnPHeap, 0, pList);
  683. }
  684. if (pTemp != NULL) {
  685. HeapFree(ghPnPHeap, 0, pTemp);
  686. }
  687. if (hKey != NULL) {
  688. RegCloseKey(hKey);
  689. }
  690. return Status;
  691. } // PNP_FreeResDes
  692. CONFIGRET
  693. PNP_GetNextResDes(
  694. IN handle_t hBinding,
  695. IN LPWSTR pDeviceID,
  696. IN ULONG LogConfTag,
  697. IN ULONG LogConfType,
  698. IN RESOURCEID ResourceID,
  699. IN ULONG ResourceTag,
  700. OUT PULONG pulNextResDesTag,
  701. OUT PULONG pulNextResDesType,
  702. IN ULONG ulFlags
  703. )
  704. /*++
  705. Routine Description:
  706. This the server-side of an RPC remote call. This routine gets the
  707. next res des in the specified log conf.
  708. Arguments:
  709. hBinding RPC binding handle, not used.
  710. pDeviceID Null-terminated device instance id string.
  711. LogConfTag Specifies the log conf within a given type.
  712. LogConfType Specifies the log conf type.
  713. ResourceID Specifies the resource type.
  714. ResourceTag Specifies current resource descriptor (if any).
  715. pulNextResDesTag Receives the next resource type.
  716. pulNextResDesType Receives the next resource within a given type.
  717. ulFlags Not used, must be zero.
  718. Return Value:
  719. If the specified device instance is valid, it returns CR_SUCCESS,
  720. otherwise it returns CR_ error code.
  721. --*/
  722. {
  723. CONFIGRET Status = CR_SUCCESS;
  724. HKEY hKey = NULL;
  725. WCHAR szValueName[64];
  726. ULONG RegDataType = 0, ulListSize = 0, i = 0, ulCount = 0;
  727. LPBYTE pList = NULL, pLogConf = NULL;
  728. UNREFERENCED_PARAMETER(hBinding);
  729. try {
  730. //
  731. // validate/initialize output parameters
  732. //
  733. if (!ARGUMENT_PRESENT(pulNextResDesTag)) {
  734. Status = CR_INVALID_POINTER;
  735. goto Clean0;
  736. } else {
  737. *pulNextResDesTag = 0;
  738. }
  739. //
  740. // validate parameters
  741. //
  742. if (INVALID_FLAGS(ulFlags, 0)) {
  743. Status = CR_INVALID_FLAG;
  744. goto Clean0;
  745. }
  746. //
  747. // make sure original caller didn't specify root devnode
  748. //
  749. if (!IsLegalDeviceId(pDeviceID) || IsRootDeviceID(pDeviceID)) {
  750. Status = CR_INVALID_LOG_CONF;
  751. goto Clean0;
  752. }
  753. //
  754. // open a key to the device's LogConf subkey
  755. //
  756. Status = OpenLogConfKey(pDeviceID, LogConfType, &hKey);
  757. if (Status != CR_SUCCESS) {
  758. goto Clean0;
  759. }
  760. //
  761. // Retrieve log conf data from the registry
  762. //
  763. Status = GetLogConfData(hKey, LogConfType,
  764. &RegDataType, szValueName,
  765. &pList, &ulListSize);
  766. if (Status != CR_SUCCESS) {
  767. Status = CR_INVALID_RES_DES; // log conf doesn't exist
  768. goto Clean0;
  769. }
  770. //
  771. // Seek to the log conf that matches the log conf tag
  772. //
  773. if (!FindLogConf(pList, &pLogConf, RegDataType, LogConfTag)) {
  774. Status = CR_INVALID_LOG_CONF;
  775. goto Clean0;
  776. }
  777. //
  778. // find the next res des. A resource tag of max indicates that we want
  779. // a find first operation.
  780. //
  781. if (ResourceTag == MAX_RESDES_TAG) {
  782. //
  783. // This is essentially a Get-First operation
  784. //
  785. *pulNextResDesTag = 0;
  786. } else if (ResourceTag == RESDES_CS_TAG) {
  787. //
  788. // By definition, if the resource type is classspecific, it's last,
  789. // so there aren't any more after this.
  790. //
  791. Status = CR_NO_MORE_RES_DES;
  792. goto Clean0;
  793. } else {
  794. *pulNextResDesTag = ResourceTag + 1; // we want the "next" res des
  795. }
  796. //-------------------------------------------------------------
  797. // Specified log conf type contains Resource Data only
  798. //-------------------------------------------------------------
  799. if (RegDataType == REG_RESOURCE_LIST) {
  800. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  801. PCM_FULL_RESOURCE_DESCRIPTOR pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)pLogConf;
  802. ULONG ulTmpResDesTag, ulTmpLogConfTag;
  803. DBG_UNREFERENCED_PARAMETER(pResList);
  804. ulTmpResDesTag = *pulNextResDesTag;
  805. ulTmpLogConfTag = LogConfTag;
  806. for ( ; ; ) {
  807. while (ulTmpResDesTag >= pRes->PartialResourceList.Count) {
  808. ulTmpResDesTag -= pRes->PartialResourceList.Count;
  809. ulTmpLogConfTag++;
  810. //
  811. // Seek to the log conf that matches the log conf tag
  812. //
  813. if (!FindLogConf(pList, &pLogConf, RegDataType, ulTmpLogConfTag)) {
  814. Status = CR_NO_MORE_RES_DES; // there is no "next"
  815. goto Clean0;
  816. }
  817. pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)pLogConf;
  818. }
  819. //
  820. // Not done yet, if a specific resource type was specified, then
  821. // we may need to keep looking.
  822. //
  823. if (ResourceID != ResType_All) {
  824. UCHAR NtResType = NT_RES_TYPE(ResourceID);
  825. if (pRes->PartialResourceList.PartialDescriptors[ulTmpResDesTag].Type
  826. != NtResType) {
  827. (*pulNextResDesTag)++;
  828. ulTmpResDesTag++;
  829. continue;
  830. }
  831. }
  832. break;
  833. }
  834. //
  835. // Return the type and tag of the "next" res des
  836. //
  837. *pulNextResDesType = CM_RES_TYPE(pRes->PartialResourceList.
  838. PartialDescriptors[ulTmpResDesTag].Type);
  839. if (*pulNextResDesType == ResType_ClassSpecific) {
  840. *pulNextResDesTag = RESDES_CS_TAG; // special tag for cs
  841. }
  842. }
  843. //-------------------------------------------------------------
  844. // Specified log conf type contains requirements data only
  845. //-------------------------------------------------------------
  846. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  847. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  848. PIO_RESOURCE_LIST pReq = (PIO_RESOURCE_LIST)pLogConf;
  849. PIO_RESOURCE_DESCRIPTOR pReqDes;
  850. DBG_UNREFERENCED_PARAMETER(pReqList);
  851. //
  852. // Point pResDes at the first possible "next" res des
  853. //
  854. if (*pulNextResDesTag == 0) {
  855. if (pReq->Count == 0) {
  856. Status = CR_NO_MORE_RES_DES; // there is no "next"
  857. goto Clean0;
  858. }
  859. if (pReq->Descriptors[0].Type == CmResourceTypeConfigData) {
  860. //
  861. // This one doesn't count, it's privately created and maintained,
  862. // skip to the next rd
  863. //
  864. *pulNextResDesTag = 1;
  865. }
  866. }
  867. if (*pulNextResDesTag > 0) {
  868. pReqDes =
  869. AdvanceRequirementsDescriptorPtr(
  870. &pReq->Descriptors[0],
  871. *pulNextResDesTag, pReq->Count, &ulCount); // current
  872. if (pReqDes == NULL) {
  873. Status = CR_NO_MORE_RES_DES; // there is no "next"
  874. goto Clean0;
  875. }
  876. } else {
  877. ulCount = 0;
  878. pReqDes = &pReq->Descriptors[0];
  879. }
  880. //
  881. // Not done yet, if a specific resource type was specified, then
  882. // we may need to keep looking.
  883. //
  884. if (ResourceID != ResType_All) {
  885. UCHAR NtResType = NT_RES_TYPE(ResourceID);
  886. while (pReqDes->Type != NtResType) {
  887. if (ulCount >= pReq->Count) {
  888. Status = CR_NO_MORE_RES_DES;
  889. goto Clean0;
  890. }
  891. pReqDes =
  892. AdvanceRequirementsDescriptorPtr(
  893. pReqDes,
  894. 1, pReq->Count - ulCount, &i);
  895. if (pReqDes == NULL) {
  896. Status = CR_NO_MORE_RES_DES;
  897. goto Clean0;
  898. }
  899. ulCount += i;
  900. *pulNextResDesTag += 1;
  901. }
  902. }
  903. *pulNextResDesType = CM_RES_TYPE(pReqDes->Type);
  904. }
  905. Clean0:
  906. NOTHING;
  907. } except(EXCEPTION_EXECUTE_HANDLER) {
  908. Status = CR_FAILURE;
  909. }
  910. if (pList != NULL) {
  911. HeapFree(ghPnPHeap, 0, pList);
  912. }
  913. if (hKey != NULL) {
  914. RegCloseKey(hKey);
  915. }
  916. return Status;
  917. } // PNP_GetNextResDes
  918. CONFIGRET
  919. PNP_GetResDesData(
  920. IN handle_t hBinding,
  921. IN LPWSTR pDeviceID,
  922. IN ULONG LogConfTag,
  923. IN ULONG LogConfType,
  924. IN RESOURCEID ResourceID,
  925. IN ULONG ResourceTag,
  926. OUT LPBYTE Buffer,
  927. IN ULONG BufferLen,
  928. IN ULONG ulFlags
  929. )
  930. /*++
  931. Routine Description:
  932. This the server-side of an RPC remote call. This routine retrieves
  933. the data for the specified res des.
  934. Arguments:
  935. hBinding RPC binding handle, not used.
  936. pDeviceID Null-terminated device instance id string.
  937. LogConfTag Specifies the log conf within a given type.
  938. LogConfType Specifies the log conf type.
  939. ResourceID Specifies the resource type.
  940. ResourceTag Returns with resource within a given type.
  941. Buffer Returns resource data (of ResourceID type) from log conf.
  942. BufferLen Size of Buffer in bytes.
  943. ulFlags Specifies the width of certain variable-size resource
  944. descriptor structure fields, where applicable.
  945. Currently, the following flags are defined:
  946. CM_RESDES_WIDTH_32 or
  947. CM_RESDES_WIDTH_64
  948. If no flags are specified, the width of the variable-sized
  949. resource data expected is assumed to be that native to the
  950. platform of the caller.
  951. Return Value:
  952. If the specified device instance is valid, it returns CR_SUCCESS,
  953. otherwise it returns CR_ error code.
  954. --*/
  955. {
  956. CONFIGRET Status = CR_SUCCESS;
  957. HKEY hKey = NULL;
  958. WCHAR szValueName[64];
  959. ULONG RegDataType = 0, ulListSize = 0, ulCount = 0;
  960. LPBYTE pList = NULL, pLogConf = NULL, pRD = NULL;
  961. UNREFERENCED_PARAMETER(hBinding);
  962. try {
  963. //
  964. // validate parameters
  965. //
  966. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  967. Status = CR_INVALID_FLAG;
  968. goto Clean0;
  969. }
  970. //
  971. // make sure original caller didn't specify root devnode
  972. //
  973. if (!IsLegalDeviceId(pDeviceID) || IsRootDeviceID(pDeviceID)) {
  974. Status = CR_INVALID_LOG_CONF;
  975. goto Clean0;
  976. }
  977. //
  978. // open a key to the device's LogConf subkey
  979. //
  980. Status = OpenLogConfKey(pDeviceID, LogConfType, &hKey);
  981. if (Status != CR_SUCCESS) {
  982. goto Clean0;
  983. }
  984. //
  985. // Retrieve log conf data from the registry
  986. //
  987. Status = GetLogConfData(hKey, LogConfType,
  988. &RegDataType, szValueName,
  989. &pList, &ulListSize);
  990. if (Status != CR_SUCCESS) {
  991. Status = CR_INVALID_RES_DES; // log conf doesn't exist
  992. goto Clean0;
  993. }
  994. //
  995. // seek to the res des that matches the resource tag.
  996. //
  997. if (!FindResDes(pList, RegDataType, LogConfTag,
  998. ResourceTag, ResourceID, &pRD, &pLogConf, &ulCount)) {
  999. Status = CR_INVALID_RES_DES;
  1000. goto Clean0;
  1001. }
  1002. //-------------------------------------------------------------
  1003. // Specified log conf type contains Resource Data only
  1004. //-------------------------------------------------------------
  1005. if (RegDataType == REG_RESOURCE_LIST) {
  1006. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  1007. PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)pRD;
  1008. //
  1009. // map the NT-style info into ConfigMgr-style structures
  1010. //
  1011. Status = NtResourceToResDes(pResDes, Buffer, BufferLen,
  1012. (LPBYTE)pResList + ulListSize - 1, ulFlags);
  1013. }
  1014. //-------------------------------------------------------------
  1015. // Specified log conf type contains requirements data only
  1016. //-------------------------------------------------------------
  1017. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  1018. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  1019. PIO_RESOURCE_DESCRIPTOR pReqDes = (PIO_RESOURCE_DESCRIPTOR)pRD;
  1020. //
  1021. // map the NT-style info into ConfigMgr-style structures
  1022. //
  1023. Status = NtRequirementsToResDes(pReqDes, Buffer, BufferLen,
  1024. (LPBYTE)pReqList + ulListSize - 1, ulFlags);
  1025. }
  1026. Clean0:
  1027. NOTHING;
  1028. } except(EXCEPTION_EXECUTE_HANDLER) {
  1029. Status = CR_FAILURE;
  1030. }
  1031. if (hKey != NULL) {
  1032. RegCloseKey(hKey);
  1033. }
  1034. if (pList != NULL) {
  1035. HeapFree(ghPnPHeap, 0, pList);
  1036. }
  1037. return Status;
  1038. } // PNP_GetResDesData
  1039. CONFIGRET
  1040. PNP_GetResDesDataSize(
  1041. IN handle_t hBinding,
  1042. IN LPWSTR pDeviceID,
  1043. IN ULONG LogConfTag,
  1044. IN ULONG LogConfType,
  1045. IN RESOURCEID ResourceID,
  1046. IN ULONG ResourceTag,
  1047. OUT PULONG pulSize,
  1048. IN ULONG ulFlags
  1049. )
  1050. /*++
  1051. Routine Description:
  1052. This the server-side of an RPC remote call. This routine retrieves
  1053. the data size for the specified res des.
  1054. Arguments:
  1055. hBinding RPC binding handle, not used.
  1056. pDeviceID Null-terminated device instance id string.
  1057. LogConfTag Specifies the log conf within a given type.
  1058. LogConfType Specifies the log conf type.
  1059. ResourceID Specifies the resource type.
  1060. ResourceTag Returns with resource within a given type.
  1061. pulSize Returns size of buffer in bytes required to hold the
  1062. resource data (of ResourceID type) from log conf.
  1063. ulFlags Specifies the width of certain variable-size resource
  1064. descriptor structure fields, where applicable.
  1065. Currently, the following flags are defined:
  1066. CM_RESDES_WIDTH_32 or
  1067. CM_RESDES_WIDTH_64
  1068. If no flags are specified, the width of the variable-sized
  1069. resource data expected is assumed to be that native to the
  1070. platform of the caller.
  1071. Return Value:
  1072. If the specified device instance is valid, it returns CR_SUCCESS,
  1073. otherwise it returns CR_ error code.
  1074. --*/
  1075. {
  1076. CONFIGRET Status = CR_SUCCESS;
  1077. HKEY hKey = NULL;
  1078. WCHAR szValueName[64];
  1079. ULONG RegDataType = 0, ulListSize = 0, ulCount = 0;
  1080. LPBYTE pList = NULL, pLogConf = NULL, pRD = NULL;
  1081. UNREFERENCED_PARAMETER(hBinding);
  1082. try {
  1083. //
  1084. // validate/initialize output parameters
  1085. //
  1086. if (!ARGUMENT_PRESENT(pulSize)) {
  1087. Status = CR_INVALID_POINTER;
  1088. goto Clean0;
  1089. } else {
  1090. *pulSize = 0;
  1091. }
  1092. //
  1093. // validate parameters
  1094. //
  1095. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  1096. Status = CR_INVALID_FLAG;
  1097. goto Clean0;
  1098. }
  1099. //
  1100. // make sure original caller didn't specify root devnode
  1101. //
  1102. if (!IsLegalDeviceId(pDeviceID) || IsRootDeviceID(pDeviceID)) {
  1103. Status = CR_INVALID_LOG_CONF;
  1104. goto Clean0;
  1105. }
  1106. //
  1107. // open a key to the device's LogConf subkey
  1108. //
  1109. Status = OpenLogConfKey(pDeviceID, LogConfType, &hKey);
  1110. if (Status != CR_SUCCESS) {
  1111. goto Clean0;
  1112. }
  1113. //
  1114. // Retrieve log conf data from the registry
  1115. //
  1116. Status = GetLogConfData(hKey, LogConfType,
  1117. &RegDataType, szValueName,
  1118. &pList, &ulListSize);
  1119. if (Status != CR_SUCCESS) {
  1120. Status = CR_INVALID_RES_DES; // log conf doesn't exist
  1121. goto Clean0;
  1122. }
  1123. //
  1124. // seek to the res des that matches the resource tag.
  1125. //
  1126. if (!FindResDes(pList, RegDataType, LogConfTag,
  1127. ResourceTag, ResourceID, &pRD, &pLogConf, &ulCount)) {
  1128. Status = CR_INVALID_RES_DES;
  1129. goto Clean0;
  1130. }
  1131. //-------------------------------------------------------------
  1132. // Specified log conf type contains Resource Data only
  1133. //-------------------------------------------------------------
  1134. if (RegDataType == REG_RESOURCE_LIST) {
  1135. PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)pRD;
  1136. //
  1137. // calculate data size required (in terms of ConfigMgr structures)
  1138. //
  1139. *pulSize = GetResDesSize(ResourceID, ulFlags);
  1140. if (ResourceID == ResType_ClassSpecific) {
  1141. //
  1142. // the Reserved fields should not exceed DataSize. if so, they
  1143. // may have been incorrectly initialized, so set them 0.
  1144. // we expect DataSize to be correct in all cases.
  1145. //
  1146. if (pResDes->u.DeviceSpecificData.Reserved1 > pResDes->u.DeviceSpecificData.DataSize) {
  1147. pResDes->u.DeviceSpecificData.Reserved1 = 0;
  1148. }
  1149. if (pResDes->u.DeviceSpecificData.Reserved2 > pResDes->u.DeviceSpecificData.DataSize) {
  1150. pResDes->u.DeviceSpecificData.Reserved2 = 0;
  1151. }
  1152. //
  1153. // add space for legacy and signature data but not the
  1154. // GUID - it's already included in the CM structures
  1155. //
  1156. if (pResDes->u.DeviceSpecificData.DataSize == 0) {
  1157. //
  1158. // no legacy data or class-specific data
  1159. //
  1160. ;
  1161. } else if (pResDes->u.DeviceSpecificData.Reserved2 == 0) {
  1162. //
  1163. // add space for legacy data
  1164. //
  1165. *pulSize += pResDes->u.DeviceSpecificData.DataSize - 1;
  1166. } else {
  1167. //
  1168. // add space for class-specific data and/or legacy data
  1169. //
  1170. *pulSize += pResDes->u.DeviceSpecificData.Reserved1 +
  1171. pResDes->u.DeviceSpecificData.Reserved2 - 1;
  1172. }
  1173. }
  1174. }
  1175. //-------------------------------------------------------------
  1176. // Specified log conf type contains requirements data only
  1177. //-------------------------------------------------------------
  1178. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  1179. PIO_RESOURCE_DESCRIPTOR pReqDes = (PIO_RESOURCE_DESCRIPTOR)pRD;
  1180. LPBYTE pLastReqAddr = (LPBYTE)pList + ulListSize - 1;
  1181. //
  1182. // calculate data size required (in terms of ConfigMgr structures)
  1183. //
  1184. *pulSize = GetReqDesSize(ResourceID, pReqDes, pLastReqAddr, ulFlags);
  1185. }
  1186. Clean0:
  1187. NOTHING;
  1188. } except(EXCEPTION_EXECUTE_HANDLER) {
  1189. Status = CR_FAILURE;
  1190. }
  1191. if (hKey != NULL) {
  1192. RegCloseKey(hKey);
  1193. }
  1194. if (pList != NULL) {
  1195. HeapFree(ghPnPHeap, 0, pList);
  1196. }
  1197. return Status;
  1198. } // PNP_GetResDesDataSize
  1199. CONFIGRET
  1200. PNP_ModifyResDes(
  1201. IN handle_t hBinding,
  1202. IN LPWSTR pDeviceID,
  1203. IN ULONG LogConfTag,
  1204. IN ULONG LogConfType,
  1205. IN RESOURCEID CurrentResourceID,
  1206. IN RESOURCEID NewResourceID,
  1207. IN ULONG ResourceTag,
  1208. IN LPBYTE ResourceData,
  1209. IN ULONG ResourceLen,
  1210. IN ULONG ulFlags
  1211. )
  1212. /*++
  1213. Routine Description:
  1214. This the server-side of an RPC remote call. This routine modifies
  1215. the specified res des.
  1216. Arguments:
  1217. hBinding RPC binding handle.
  1218. pDeviceID Null-terminated device instance id string.
  1219. LogConfTag Specifies the log conf within a given type.
  1220. LogConfType Specifies the log conf type.
  1221. ResourceID Specifies the resource type.
  1222. ResourceIndex Returns with resource within a given type.
  1223. ResourceData New resource data (of ResourceID type).
  1224. ResourceLen Size of ResourceData in bytes.
  1225. ulFlags Specifies the width of certain variable-size resource
  1226. descriptor structure fields, where applicable.
  1227. Currently, the following flags are defined:
  1228. CM_RESDES_WIDTH_32 or
  1229. CM_RESDES_WIDTH_64
  1230. If no flags are specified, the width of the variable-sized
  1231. resource data supplied is assumed to be that native to the
  1232. platform of the caller.
  1233. Return Value:
  1234. If the specified device instance is valid, it returns CR_SUCCESS,
  1235. otherwise it returns CR_ error code.
  1236. --*/
  1237. {
  1238. CONFIGRET Status = CR_SUCCESS;
  1239. HKEY hKey = NULL;
  1240. WCHAR szValueName[64];
  1241. ULONG ulListSize = 0, ulOldSize = 0, ulNewSize = 0, ulSize = 0,
  1242. ulOldCount = 0, ulNewCount = 0, RegDataType = 0, ulCount = 0;
  1243. LONG AddSize = 0;
  1244. LPBYTE pList = NULL, pRD = NULL, pLogConf = NULL,
  1245. pTemp = NULL, pNext = NULL;
  1246. try {
  1247. //
  1248. // Verify client "write" access
  1249. //
  1250. if (!VerifyClientAccess(hBinding,
  1251. PLUGPLAY_WRITE)) {
  1252. Status = CR_ACCESS_DENIED;
  1253. goto Clean0;
  1254. }
  1255. //
  1256. // validate parameters
  1257. //
  1258. if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
  1259. Status = CR_INVALID_FLAG;
  1260. goto Clean0;
  1261. }
  1262. //
  1263. // validate res des size
  1264. //
  1265. if (ResourceLen < GetResDesSize(NewResourceID, ulFlags)) {
  1266. Status = CR_INVALID_DATA;
  1267. goto Clean0;
  1268. }
  1269. //
  1270. // make sure original caller didn't specify root devnode
  1271. //
  1272. if (!IsLegalDeviceId(pDeviceID) || IsRootDeviceID(pDeviceID)) {
  1273. Status = CR_INVALID_LOG_CONF;
  1274. goto Clean0;
  1275. }
  1276. //
  1277. // open a key to the device's LogConf subkey
  1278. //
  1279. Status = OpenLogConfKey(pDeviceID, LogConfType, &hKey);
  1280. if (Status != CR_SUCCESS) {
  1281. goto Clean0;
  1282. }
  1283. //
  1284. // Retrieve log conf data from the registry
  1285. //
  1286. Status = GetLogConfData(hKey, LogConfType,
  1287. &RegDataType, szValueName,
  1288. &pList, &ulListSize);
  1289. if (Status != CR_SUCCESS) {
  1290. Status = CR_INVALID_RES_DES; // log conf doesn't exist
  1291. goto Clean0;
  1292. }
  1293. //
  1294. // seek to the res des that matches the resource tag.
  1295. //
  1296. if (!FindResDes(pList, RegDataType, LogConfTag,
  1297. ResourceTag, CurrentResourceID, &pRD, &pLogConf, &ulCount)) {
  1298. Status = CR_INVALID_RES_DES;
  1299. goto Clean0;
  1300. }
  1301. //-------------------------------------------------------------
  1302. // Specified log conf type contains Resource Data only
  1303. //-------------------------------------------------------------
  1304. if (RegDataType == REG_RESOURCE_LIST) {
  1305. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  1306. PCM_FULL_RESOURCE_DESCRIPTOR pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)pLogConf;
  1307. PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)pRD;
  1308. //
  1309. // If new res des type is ClassSpecific, then it must be the last
  1310. // res des that is attempting to be modified (only last res des can
  1311. // be class specific).
  1312. //
  1313. if (NewResourceID == ResType_ClassSpecific &&
  1314. ResourceTag != RESDES_CS_TAG) {
  1315. Status = CR_INVALID_RES_DES;
  1316. goto Clean0;
  1317. }
  1318. //
  1319. // calculate the current size and the new size of the res des data
  1320. //
  1321. ulNewSize = ulOldSize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
  1322. if (CurrentResourceID == ResType_ClassSpecific) {
  1323. ulOldSize += pResDes->u.DeviceSpecificData.DataSize;
  1324. }
  1325. if (NewResourceID == ResType_ClassSpecific) {
  1326. PCS_RESOURCE pCsRes = (PCS_RESOURCE)ResourceData;
  1327. ulNewSize += sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
  1328. sizeof(GUID) +
  1329. pCsRes->CS_Header.CSD_SignatureLength +
  1330. pCsRes->CS_Header.CSD_LegacyDataSize;
  1331. }
  1332. //
  1333. // How much does data need to grow/shrink to accomodate the change?
  1334. //
  1335. AddSize = ulNewSize - ulOldSize;
  1336. //
  1337. // reallocate the buffers and shrink/expand the contents as
  1338. // necessary
  1339. //
  1340. if (AddSize != 0) {
  1341. if (AddSize > 0) {
  1342. //
  1343. // only bother reallocating if the buffer size is growing
  1344. //
  1345. ULONG ulOffset = (ULONG)((ULONG_PTR)pResDes - (ULONG_PTR)pResList);
  1346. pResList = HeapReAlloc(ghPnPHeap, 0, pList, ulListSize + AddSize);
  1347. if (pResList == NULL) {
  1348. Status = CR_OUT_OF_MEMORY;
  1349. goto Clean0;
  1350. }
  1351. pList = (LPBYTE)pResList;
  1352. pResDes = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)((LPBYTE)pResList + ulOffset);
  1353. }
  1354. //
  1355. // if not the last lc and rd, then need to move the following data
  1356. // either up or down to account for changed res des data size
  1357. //
  1358. if ((LogConfTag != pResList->Count - 1) ||
  1359. ((ResourceTag != pRes->PartialResourceList.Count - 1) &&
  1360. ResourceTag != RESDES_CS_TAG)) {
  1361. pNext = (LPBYTE)((LPBYTE)pResDes + ulOldSize);
  1362. ulSize = ulListSize - (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pResList);
  1363. pTemp = HeapAlloc(ghPnPHeap, 0, ulSize);
  1364. if (pTemp == NULL) {
  1365. Status = CR_OUT_OF_MEMORY;
  1366. goto Clean0;
  1367. }
  1368. memcpy(pTemp, pNext, ulSize);
  1369. memcpy((LPBYTE)((LPBYTE)pResDes + ulNewSize), pTemp, ulSize);
  1370. }
  1371. }
  1372. //
  1373. // write out modified data
  1374. //
  1375. Status = ResDesToNtResource(ResourceData, NewResourceID, ResourceLen,
  1376. pResDes, ResourceTag, ulFlags);
  1377. }
  1378. //-------------------------------------------------------------
  1379. // Specified log conf type contains requirements data only
  1380. //-------------------------------------------------------------
  1381. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  1382. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  1383. PIO_RESOURCE_LIST pReq = (PIO_RESOURCE_LIST)pLogConf;
  1384. PIO_RESOURCE_DESCRIPTOR pReqDes = (PIO_RESOURCE_DESCRIPTOR)pRD;
  1385. LPBYTE pLastReqAddr = (LPBYTE)pReqList + ulListSize - 1;
  1386. PGENERIC_RESOURCE pGenRes = (PGENERIC_RESOURCE)ResourceData;
  1387. //
  1388. // Can't add class specific resdes to this type of log conf
  1389. //
  1390. if (NewResourceID == ResType_ClassSpecific) {
  1391. Status = CR_INVALID_RES_DES;
  1392. goto Clean0;
  1393. }
  1394. //
  1395. // calculate the current size and the new size of the res des data
  1396. //
  1397. ulOldCount = RANGE_COUNT(pReqDes, pLastReqAddr);
  1398. ulOldSize = sizeof(IO_RESOURCE_DESCRIPTOR) * ulOldCount;
  1399. ulNewSize = sizeof(IO_RESOURCE_DESCRIPTOR) *
  1400. pGenRes->GENERIC_Header.GENERIC_Count;
  1401. //
  1402. // How much does data need to grow/shrink to accomodate the change?
  1403. //
  1404. AddSize = ulNewSize - ulOldSize;
  1405. //
  1406. // reallocate the buffers and shrink/expand the contents as
  1407. // necessary
  1408. //
  1409. if (AddSize != 0) {
  1410. if (AddSize > 0) {
  1411. //
  1412. // only bother reallocating if the buffer size is growing
  1413. //
  1414. ULONG ulOffset = (ULONG)((ULONG_PTR)pReqDes - (ULONG_PTR)pReqList);
  1415. pReqList = HeapReAlloc(ghPnPHeap, 0, pList, ulListSize + AddSize);
  1416. if (pReqList == NULL) {
  1417. Status = CR_OUT_OF_MEMORY;
  1418. goto Clean0;
  1419. }
  1420. pList = (LPBYTE)pReqList;
  1421. pReqDes = (PIO_RESOURCE_DESCRIPTOR)((LPBYTE)pReqList + ulOffset);
  1422. }
  1423. //
  1424. // set to last index for this res des (whole)
  1425. //
  1426. ulCount += RANGE_COUNT(pReqDes, (LPBYTE)((ULONG_PTR)pList + ulListSize));
  1427. //
  1428. // if not the last lc and rd, then need to move the following data
  1429. // either up or down to account for changed res des data size
  1430. //
  1431. if (LogConfTag != pReqList->AlternativeLists - 1 ||
  1432. ulCount != pReq->Count - 1) {
  1433. pNext = (LPBYTE)((LPBYTE)pReqDes + ulOldSize);
  1434. ulSize = ulListSize - (DWORD)((ULONG_PTR)pNext - (ULONG_PTR)pReqList);
  1435. pTemp = HeapAlloc(ghPnPHeap, 0, ulSize);
  1436. if (pTemp == NULL) {
  1437. Status = CR_OUT_OF_MEMORY;
  1438. goto Clean0;
  1439. }
  1440. memcpy(pTemp, pNext, ulSize);
  1441. memcpy((LPBYTE)((LPBYTE)pReqDes + ulNewSize), pTemp, ulSize);
  1442. }
  1443. }
  1444. //
  1445. // write out modified data
  1446. //
  1447. Status = ResDesToNtRequirements(ResourceData, NewResourceID, ResourceLen,
  1448. pReqDes, &ulNewCount, ResourceTag, ulFlags);
  1449. if (Status == CR_SUCCESS) {
  1450. //
  1451. // update the requirements header (changes will be zero if CS)
  1452. //
  1453. pReq->Count += ulNewCount - ulOldCount;
  1454. pReqList->ListSize = ulListSize + AddSize;
  1455. }
  1456. }
  1457. if (Status == CR_SUCCESS) {
  1458. //
  1459. // Write out the new/updated log conf list to the registry
  1460. //
  1461. if (RegSetValueEx(hKey, szValueName, 0, RegDataType, pList,
  1462. ulListSize + AddSize) != ERROR_SUCCESS) {
  1463. Status = CR_REGISTRY_ERROR;
  1464. goto Clean0;
  1465. }
  1466. }
  1467. Clean0:
  1468. NOTHING;
  1469. } except(EXCEPTION_EXECUTE_HANDLER) {
  1470. Status = CR_FAILURE;
  1471. }
  1472. if (hKey != NULL) {
  1473. RegCloseKey(hKey);
  1474. }
  1475. if (pList != NULL) {
  1476. HeapFree(ghPnPHeap, 0, pList);
  1477. }
  1478. if (pTemp != NULL) {
  1479. HeapFree(ghPnPHeap, 0, pTemp);
  1480. }
  1481. return Status;
  1482. } // PNP_ModifyResDes
  1483. CONFIGRET
  1484. PNP_DetectResourceConflict(
  1485. IN handle_t hBinding,
  1486. IN LPWSTR pDeviceID,
  1487. IN RESOURCEID ResourceID,
  1488. IN LPBYTE ResourceData,
  1489. IN ULONG ResourceLen,
  1490. OUT PBOOL pbConflictDetected,
  1491. IN ULONG ulFlags
  1492. )
  1493. /*++
  1494. Routine Description:
  1495. This the server-side of an RPC remote call. This routine detects
  1496. conflicts with the specified res des.
  1497. Arguments:
  1498. hBinding RPC binding handle, not used.
  1499. pDeviceID Null-terminated device instance id string.
  1500. ResourceID Specifies the resource type.
  1501. ResourceData Specifies resource data (of ResourceID type).
  1502. ResourceLen Size of ResourceData in bytes.
  1503. pbConflictDetected Returns whether a conflict was detected.
  1504. ulFlags Not used, must be zero.
  1505. Return Value:
  1506. ** PRESENTLY, ALWAYS RETURNS CR_CALL_NOT_IMPLEMENTED **
  1507. Note:
  1508. This routine is currently not implemented. It initializes
  1509. pbConflictDetected to FALSE, and returns CR_CALL_NOT_IMPLEMENTED.
  1510. --*/
  1511. {
  1512. CONFIGRET Status;
  1513. UNREFERENCED_PARAMETER(hBinding);
  1514. UNREFERENCED_PARAMETER(pDeviceID);
  1515. UNREFERENCED_PARAMETER(ResourceID);
  1516. UNREFERENCED_PARAMETER(ResourceData);
  1517. UNREFERENCED_PARAMETER(ResourceLen);
  1518. UNREFERENCED_PARAMETER(ulFlags);
  1519. try {
  1520. //
  1521. // initialize output parameters
  1522. //
  1523. if (ARGUMENT_PRESENT(pbConflictDetected)) {
  1524. *pbConflictDetected = FALSE;
  1525. }
  1526. Status = CR_CALL_NOT_IMPLEMENTED;
  1527. } except(EXCEPTION_EXECUTE_HANDLER) {
  1528. Status = CR_FAILURE;
  1529. }
  1530. return Status;
  1531. } // PNP_DetectResourceConflict
  1532. //------------------------------------------------------------------------
  1533. // Private Utility Functions
  1534. //------------------------------------------------------------------------
  1535. BOOL
  1536. FindLogConf(
  1537. IN LPBYTE pList,
  1538. OUT LPBYTE *ppLogConf,
  1539. IN ULONG RegDataType,
  1540. IN ULONG ulTag
  1541. )
  1542. {
  1543. ULONG Index = 0;
  1544. //
  1545. // Input data is a Resource List
  1546. //
  1547. if (RegDataType == REG_RESOURCE_LIST) {
  1548. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  1549. PCM_FULL_RESOURCE_DESCRIPTOR pRes = NULL;
  1550. if (ulTag >= pResList->Count) {
  1551. return FALSE;
  1552. }
  1553. pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)(&pResList->List[0]); // first lc
  1554. for (Index = 0; Index < ulTag; Index++) {
  1555. pRes = AdvanceResourcePtr(pRes); // next lc
  1556. }
  1557. *ppLogConf = (LPBYTE)pRes;
  1558. }
  1559. //
  1560. // Input data is a Requirments List
  1561. //
  1562. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  1563. PIO_RESOURCE_REQUIREMENTS_LIST pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)pList;
  1564. PIO_RESOURCE_LIST pReq = NULL;
  1565. if (ulTag >= pReqList->AlternativeLists) {
  1566. return FALSE;
  1567. }
  1568. pReq = (PIO_RESOURCE_LIST)(&pReqList->List[0]); // first lc
  1569. for (Index = 0; Index < ulTag; Index++) {
  1570. pReq = AdvanceRequirementsPtr(pReq); // next lc
  1571. }
  1572. *ppLogConf = (LPBYTE)pReq;
  1573. } else {
  1574. return FALSE;
  1575. }
  1576. return TRUE;
  1577. } // FindLogConf
  1578. BOOL
  1579. FindResDes(
  1580. IN LPBYTE pList,
  1581. IN ULONG RegDataType,
  1582. IN ULONG ulLogConfTag,
  1583. IN ULONG ulResTag,
  1584. IN RESOURCEID ResType,
  1585. OUT LPBYTE *ppRD,
  1586. OUT LPBYTE *ppLogConf,
  1587. OUT PULONG pulSubIndex OPTIONAL
  1588. )
  1589. {
  1590. ULONG ulIndex;
  1591. //
  1592. // Input data is a Resource List
  1593. //
  1594. if (RegDataType == REG_RESOURCE_LIST) {
  1595. PCM_RESOURCE_LIST pResList = (PCM_RESOURCE_LIST)pList;
  1596. PCM_FULL_RESOURCE_DESCRIPTOR pRes = NULL;
  1597. PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes = NULL;
  1598. ULONG ulSubIndex;
  1599. ULONG ulResTagOffset;
  1600. if (ulLogConfTag != 0) {
  1601. return FALSE;
  1602. }
  1603. if (pResList->Count == 0) {
  1604. return FALSE;
  1605. }
  1606. //
  1607. // The tag is just the res des index with the exception of a
  1608. // DeviceSpecificData type which has a unique tag. This is
  1609. // necessary because new res des's will always get placed at
  1610. // the end unless there's already a device specific res des,
  1611. // in which case new res des get added just before it.
  1612. //
  1613. if (ulResTag == RESDES_CS_TAG) {
  1614. //
  1615. // If there is a devicespecific res des, it will be the last.
  1616. //
  1617. pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)&pResList->List[0]; // first lc
  1618. ulSubIndex = 0;
  1619. for (ulIndex = 0; ulIndex < (pResList->Count - 1); ulIndex++) {
  1620. ulSubIndex += pRes->PartialResourceList.Count;
  1621. pRes = AdvanceResourcePtr(pRes); // next lc
  1622. }
  1623. ulResTagOffset = pRes->PartialResourceList.Count - 1;
  1624. pResDes = &pRes->PartialResourceList.PartialDescriptors[ulResTagOffset];
  1625. if (pResDes->Type != CmResourceTypeDeviceSpecific) {
  1626. return FALSE;
  1627. }
  1628. if (pulSubIndex) {
  1629. *pulSubIndex = ulSubIndex + ulResTagOffset; // for res list, subindex = index
  1630. }
  1631. } else {
  1632. pRes = (PCM_FULL_RESOURCE_DESCRIPTOR)&pResList->List[0]; // first lc
  1633. ulResTagOffset = ulResTag;
  1634. for (ulIndex = 0; ulIndex < pResList->Count; ulIndex++) {
  1635. if (ulResTagOffset >= pRes->PartialResourceList.Count) {
  1636. ulResTagOffset -= pRes->PartialResourceList.Count;
  1637. pRes = AdvanceResourcePtr(pRes); // next lc
  1638. } else {
  1639. break;
  1640. }
  1641. }
  1642. if (ulResTagOffset >= pRes->PartialResourceList.Count) {
  1643. return FALSE;
  1644. }
  1645. if (pulSubIndex) {
  1646. *pulSubIndex = ulResTag; // for res list, subindex = index = tag
  1647. }
  1648. pResDes = &pRes->PartialResourceList.PartialDescriptors[ulResTagOffset];
  1649. }
  1650. //
  1651. // Validate against res des type
  1652. //
  1653. if (pResDes->Type != NT_RES_TYPE(ResType)) {
  1654. return FALSE;
  1655. }
  1656. *ppLogConf = (LPBYTE)pRes;
  1657. *ppRD = (LPBYTE)pResDes;
  1658. }
  1659. //
  1660. // Input data is a Requirments List
  1661. //
  1662. else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) {
  1663. LPBYTE pLogConf = NULL;
  1664. PIO_RESOURCE_LIST pReq = NULL;
  1665. PIO_RESOURCE_DESCRIPTOR pReqDes = NULL;
  1666. ULONG Count = 0;
  1667. if (!FindLogConf(pList, &pLogConf, RegDataType, ulLogConfTag)) {
  1668. return FALSE;
  1669. }
  1670. pReq = (PIO_RESOURCE_LIST)pLogConf;
  1671. if (pReq == NULL || pReq->Count == 0 || ulResTag >= pReq->Count) {
  1672. return FALSE;
  1673. }
  1674. //
  1675. // Find the res des that matches the specified tag. In this case the
  1676. // tag is the index based on res des groupings.
  1677. //
  1678. pReqDes =
  1679. AdvanceRequirementsDescriptorPtr(
  1680. &pReq->Descriptors[0],
  1681. ulResTag, pReq->Count, &Count);
  1682. if (pReqDes == NULL) {
  1683. return FALSE;
  1684. }
  1685. if (pulSubIndex) {
  1686. *pulSubIndex = Count;
  1687. }
  1688. //
  1689. // Validate against res des type
  1690. //
  1691. if (pReqDes->Type != NT_RES_TYPE(ResType)) {
  1692. return FALSE;
  1693. }
  1694. *ppLogConf = (LPBYTE)pReq;
  1695. *ppRD = (LPBYTE)pReqDes;
  1696. }
  1697. return TRUE;
  1698. } // FindResDes
  1699. PIO_RESOURCE_DESCRIPTOR
  1700. AdvanceRequirementsDescriptorPtr(
  1701. IN PIO_RESOURCE_DESCRIPTOR pReqDesStart,
  1702. IN ULONG ulIncrement,
  1703. IN ULONG ulRemainingRanges,
  1704. OUT PULONG pulRangeCount
  1705. )
  1706. {
  1707. PIO_RESOURCE_DESCRIPTOR pReqDes = NULL;
  1708. ULONG i = 0, Count = 0;
  1709. //
  1710. // Advance requirements descriptor pointer by number passed
  1711. // in ulIncrement parameter. Return the actual index to the
  1712. // first range in this descriptor list and range count if
  1713. // desired. This routine assumes there is at least one more
  1714. // requirements descriptor in the list.
  1715. //
  1716. if (pReqDesStart == NULL) {
  1717. return NULL;
  1718. }
  1719. try {
  1720. pReqDes = pReqDesStart;
  1721. for (i = 0; i < ulIncrement; i++) {
  1722. //
  1723. // skip to next "whole" res des
  1724. //
  1725. if (Count < ulRemainingRanges &&
  1726. (pReqDes->Option == 0 ||
  1727. pReqDes->Option == IO_RESOURCE_PREFERRED ||
  1728. pReqDes->Option == IO_RESOURCE_DEFAULT)) {
  1729. //
  1730. // This is a valid Option, there may be one or more alternate
  1731. // descriptor in the set associated with this descriptor,
  1732. // treat the set as "one" descriptor. (loop through the
  1733. // descriptors until I find another non-alternative descriptor)
  1734. //
  1735. pReqDes++; // next range
  1736. Count++;
  1737. while (Count < ulRemainingRanges &&
  1738. (pReqDes->Option == IO_RESOURCE_ALTERNATIVE ||
  1739. pReqDes->Option == IO_RESOURCE_ALTERNATIVE + IO_RESOURCE_PREFERRED ||
  1740. pReqDes->Option == IO_RESOURCE_ALTERNATIVE + IO_RESOURCE_DEFAULT)) {
  1741. pReqDes++; // next range
  1742. Count++;
  1743. }
  1744. if (Count >= ulRemainingRanges) {
  1745. pReqDes = NULL;
  1746. Count = 0;
  1747. break;
  1748. }
  1749. } else {
  1750. //
  1751. // invalid Option value
  1752. //
  1753. pReqDes = NULL;
  1754. Count = 0;
  1755. break;
  1756. }
  1757. }
  1758. } except(EXCEPTION_EXECUTE_HANDLER) {
  1759. pReqDes = NULL;
  1760. Count = 0;
  1761. }
  1762. if (pulRangeCount) {
  1763. *pulRangeCount = Count;
  1764. }
  1765. return pReqDes;
  1766. } // AdvanceRequirementsDescriptorPtr
  1767. ULONG
  1768. RANGE_COUNT(
  1769. IN PIO_RESOURCE_DESCRIPTOR pReqDes,
  1770. IN LPBYTE pLastReqAddr
  1771. )
  1772. {
  1773. ULONG ulRangeCount = 0;
  1774. try {
  1775. if (pReqDes == NULL) {
  1776. goto Clean0;
  1777. }
  1778. ulRangeCount++;
  1779. if (pReqDes->Option == 0 ||
  1780. pReqDes->Option == IO_RESOURCE_PREFERRED ||
  1781. pReqDes->Option == IO_RESOURCE_DEFAULT) {
  1782. PIO_RESOURCE_DESCRIPTOR p = pReqDes;
  1783. p++;
  1784. while (((LPBYTE)p < pLastReqAddr) &&
  1785. (p->Option == IO_RESOURCE_ALTERNATIVE ||
  1786. p->Option == IO_RESOURCE_ALTERNATIVE + IO_RESOURCE_PREFERRED ||
  1787. p->Option == IO_RESOURCE_ALTERNATIVE + IO_RESOURCE_DEFAULT)) {
  1788. ulRangeCount++;
  1789. p++; // skip to next res des
  1790. }
  1791. }
  1792. Clean0:
  1793. NOTHING;
  1794. } except(EXCEPTION_EXECUTE_HANDLER) {
  1795. ulRangeCount = 0;
  1796. }
  1797. return ulRangeCount;
  1798. } // RANGE_COUNT
  1799. ULONG
  1800. GetResDesSize(
  1801. IN ULONG ResourceID,
  1802. IN ULONG ulFlags
  1803. )
  1804. {
  1805. switch (ResourceID) {
  1806. case ResType_Mem:
  1807. return sizeof(MEM_RESOURCE);
  1808. case ResType_IO:
  1809. return sizeof(IO_RESOURCE);
  1810. case ResType_DMA:
  1811. return sizeof(DMA_RESOURCE);
  1812. case ResType_IRQ:
  1813. if (ulFlags & CM_RESDES_WIDTH_64) {
  1814. return sizeof(IRQ_RESOURCE_64);
  1815. } else {
  1816. return sizeof(IRQ_RESOURCE_32);
  1817. }
  1818. case ResType_ClassSpecific:
  1819. return sizeof(CS_RESOURCE);
  1820. case ResType_DevicePrivate:
  1821. return sizeof(DEVPRIVATE_RESOURCE);
  1822. case ResType_BusNumber:
  1823. return sizeof(BUSNUMBER_RESOURCE);
  1824. case ResType_PcCardConfig:
  1825. return sizeof(PCCARD_RESOURCE);
  1826. case ResType_MfCardConfig:
  1827. return sizeof(MFCARD_RESOURCE);
  1828. default:
  1829. return 0;
  1830. }
  1831. } // GetResDesSize
  1832. ULONG
  1833. GetReqDesSize(
  1834. IN ULONG ResourceID,
  1835. IN PIO_RESOURCE_DESCRIPTOR pReqDes,
  1836. IN LPBYTE pLastReqAddr,
  1837. IN ULONG ulFlags
  1838. )
  1839. {
  1840. ULONG ulSize = 0;
  1841. switch (ResourceID) {
  1842. case ResType_Mem:
  1843. ulSize = sizeof(MEM_RESOURCE);
  1844. ulSize += (RANGE_COUNT(pReqDes, pLastReqAddr) - 1) * sizeof(MEM_RANGE);
  1845. break;
  1846. case ResType_IO:
  1847. ulSize = sizeof(IO_RESOURCE);
  1848. ulSize += (RANGE_COUNT(pReqDes, pLastReqAddr) - 1) * sizeof(IO_RANGE);
  1849. break;
  1850. case ResType_DMA:
  1851. ulSize = sizeof(DMA_RESOURCE);
  1852. ulSize += (RANGE_COUNT(pReqDes, pLastReqAddr) - 1) * sizeof(DMA_RANGE);
  1853. break;
  1854. case ResType_IRQ:
  1855. if (ulFlags & CM_RESDES_WIDTH_64) {
  1856. ulSize = sizeof(IRQ_RESOURCE_64);
  1857. } else {
  1858. ulSize = sizeof(IRQ_RESOURCE_32);
  1859. }
  1860. ulSize += (RANGE_COUNT(pReqDes, pLastReqAddr) - 1) * sizeof(IRQ_RANGE);
  1861. break;
  1862. case ResType_DevicePrivate:
  1863. ulSize = sizeof(DEVPRIVATE_RESOURCE);
  1864. ulSize += (RANGE_COUNT(pReqDes, pLastReqAddr) - 1) * sizeof(DEVPRIVATE_RANGE);
  1865. break;
  1866. case ResType_BusNumber:
  1867. ulSize = sizeof(BUSNUMBER_RESOURCE);
  1868. ulSize += (RANGE_COUNT(pReqDes, pLastReqAddr) - 1) * sizeof(BUSNUMBER_RANGE);
  1869. break;
  1870. case ResType_PcCardConfig:
  1871. //
  1872. // Non-arbitrated types don't have a range side in the user-mode structs
  1873. //
  1874. ulSize = sizeof(PCCARD_RESOURCE);
  1875. break;
  1876. case ResType_MfCardConfig:
  1877. //
  1878. // Non-arbitrated types don't have a range side in the user-mode structs
  1879. //
  1880. ulSize = sizeof(MFCARD_RESOURCE);
  1881. break;
  1882. default:
  1883. break;
  1884. }
  1885. return ulSize;
  1886. } // GetReqDesSize
  1887. UCHAR
  1888. NT_RES_TYPE(
  1889. IN RESOURCEID ResourceID
  1890. )
  1891. {
  1892. ULONG resid = 0;
  1893. if ((ResourceID < 0x06)) {
  1894. //
  1895. // First handle the divergent cases that can only be mapped
  1896. // on a case by case basis. These are the values from zero
  1897. // through five plus the special class specific case.
  1898. //
  1899. switch(ResourceID) {
  1900. case ResType_None:
  1901. return CmResourceTypeNull;
  1902. break;
  1903. case ResType_Mem:
  1904. return CmResourceTypeMemory;
  1905. case ResType_IO:
  1906. return CmResourceTypePort;
  1907. case ResType_DMA:
  1908. return CmResourceTypeDma;
  1909. case ResType_IRQ:
  1910. return CmResourceTypeInterrupt;
  1911. case ResType_DoNotUse:
  1912. return (UCHAR)-1;
  1913. DEFAULT_UNREACHABLE;
  1914. }
  1915. } else if (ResourceID == ResType_ClassSpecific) {
  1916. //
  1917. // ResType_ClassSpecific is another special case.
  1918. //
  1919. return CmResourceTypeDeviceSpecific;
  1920. } else {
  1921. //
  1922. // For all other cases, rules apply as to how to map a kernel-mode
  1923. // resource type id to a user-mode resource type id.
  1924. //
  1925. if (ResourceID >= 0x8080) {
  1926. //
  1927. // Anything larger this can't be mapped to the kernel-mode USHORT
  1928. // values so it's invalid.
  1929. //
  1930. return (UCHAR)-1;
  1931. } else if (!(ResourceID & ResType_Ignored_Bit)) {
  1932. //
  1933. // Values in the range [0x6,0x8000] use the same values
  1934. // for ConfigMgr as for kernel-mode.
  1935. //
  1936. return (UCHAR)ResourceID;
  1937. } else if (ResourceID & ResType_Ignored_Bit) {
  1938. //
  1939. // For the non arbitrated types (0x8000 bit set), do special
  1940. // mapping to get the kernel-mode resource id type.
  1941. //
  1942. resid = ResourceID;
  1943. resid &= ~(ResType_Ignored_Bit); // clear um non-arbitrated bit
  1944. resid |= CmResourceTypeNonArbitrated; // set km non-arbitrated bit
  1945. return (UCHAR)resid;
  1946. } else {
  1947. return (UCHAR)-1;
  1948. }
  1949. }
  1950. } // NT_RES_TYPE
  1951. ULONG
  1952. CM_RES_TYPE(
  1953. IN UCHAR ResourceType
  1954. )
  1955. {
  1956. ULONG resid = 0;
  1957. if ((ResourceType < 0x06)) {
  1958. //
  1959. // First handle the divergent cases that can only be mapped
  1960. // on a case by case basis. These are the values from zero
  1961. // through five plus the special class specific case.
  1962. //
  1963. switch(ResourceType) {
  1964. case CmResourceTypeNull:
  1965. return ResType_None;
  1966. case CmResourceTypePort:
  1967. return ResType_IO;
  1968. case CmResourceTypeInterrupt:
  1969. return ResType_IRQ;
  1970. case CmResourceTypeMemory:
  1971. return ResType_Mem;
  1972. case CmResourceTypeDma:
  1973. return ResType_DMA;
  1974. case CmResourceTypeDeviceSpecific:
  1975. return ResType_ClassSpecific;
  1976. DEFAULT_UNREACHABLE;
  1977. }
  1978. } else {
  1979. //
  1980. // For all other cases, rules apply as to how to map a kernel-mode
  1981. // resource type id to a user-mode resource type id.
  1982. //
  1983. if (!(ResourceType & CmResourceTypeNonArbitrated)) {
  1984. //
  1985. // Values in the range [0x6,0x80] use the same values
  1986. // for ConfigMgr as for kernel-mode.
  1987. //
  1988. return (ULONG)ResourceType;
  1989. } else if (ResourceType & CmResourceTypeNonArbitrated) {
  1990. //
  1991. // For the non arbitrated types (0x80 bit set), do special
  1992. // mapping to get the user-mode resource id type.
  1993. //
  1994. resid = (ULONG)ResourceType;
  1995. resid &= ~(CmResourceTypeNonArbitrated); // clear km non-arbitrated bit
  1996. resid |= ResType_Ignored_Bit; // set um non-arbitrated bit
  1997. return resid;
  1998. } else {
  1999. return (ULONG)-1;
  2000. }
  2001. }
  2002. } // NT_RES_TYPE
  2003. CONFIGRET
  2004. ResDesToNtResource(
  2005. IN PCVOID ResourceData,
  2006. IN RESOURCEID ResourceType,
  2007. IN ULONG ResourceLen,
  2008. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes,
  2009. IN ULONG ulTag,
  2010. IN ULONG ulFlags
  2011. )
  2012. {
  2013. CONFIGRET Status = CR_SUCCESS;
  2014. UNREFERENCED_PARAMETER(ulTag);
  2015. //
  2016. // fill in resource type specific info
  2017. //
  2018. switch (ResourceType) {
  2019. case ResType_Mem: {
  2020. //-------------------------------------------------------
  2021. // Memory Resource Type
  2022. //-------------------------------------------------------
  2023. //
  2024. // NOTE: pMemData->MEM_Header.MD_Reserved is not mapped
  2025. // pMemData->MEM_Data.MR_Reserved is not mapped
  2026. //
  2027. PMEM_RESOURCE pMemData = (PMEM_RESOURCE)ResourceData;
  2028. //
  2029. // validate resource data
  2030. //
  2031. if (ResourceLen < sizeof(MEM_RESOURCE)) {
  2032. Status = CR_INVALID_RES_DES;
  2033. goto Clean0;
  2034. }
  2035. if (pMemData->MEM_Header.MD_Type != MType_Range) {
  2036. Status = CR_INVALID_RES_DES;
  2037. goto Clean0;
  2038. }
  2039. //
  2040. // copy MEM_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2041. //
  2042. pResDes->Type = CmResourceTypeMemory;
  2043. pResDes->ShareDisposition = CmResourceShareUndetermined;
  2044. //pResDes->ShareDisposition = MapToNtDisposition(pMemData->MEM_Header.MD_Flags, 0);
  2045. pResDes->Flags = MapToNtMemoryFlags(pMemData->MEM_Header.MD_Flags);
  2046. pResDes->u.Memory.Start.HighPart = HIDWORD(pMemData->MEM_Header.MD_Alloc_Base);
  2047. pResDes->u.Memory.Start.LowPart = LODWORD(pMemData->MEM_Header.MD_Alloc_Base);
  2048. pResDes->u.Memory.Length = (DWORD)(pMemData->MEM_Header.MD_Alloc_End -
  2049. pMemData->MEM_Header.MD_Alloc_Base + 1);
  2050. break;
  2051. }
  2052. case ResType_IO: {
  2053. //-------------------------------------------------------
  2054. // IO Port Resource Type
  2055. //
  2056. // NOTE: alias info lost during this conversion process
  2057. //-------------------------------------------------------
  2058. PIO_RESOURCE pIoData = (PIO_RESOURCE)ResourceData;
  2059. //
  2060. // validate resource data
  2061. //
  2062. if (ResourceLen < sizeof(IO_RESOURCE)) {
  2063. Status = CR_FAILURE;
  2064. goto Clean0;
  2065. }
  2066. if (pIoData->IO_Header.IOD_Type != IOType_Range) {
  2067. Status = CR_INVALID_RES_DES;
  2068. goto Clean0;
  2069. }
  2070. //
  2071. // copy IO_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2072. //
  2073. pResDes->Type = CmResourceTypePort;
  2074. pResDes->ShareDisposition = CmResourceShareUndetermined;
  2075. //pResDes->ShareDisposition = MapToNtDisposition(pIoData->IO_Header.IOD_DesFlags, 0);
  2076. pResDes->Flags = MapToNtPortFlags(pIoData->IO_Header.IOD_DesFlags, 0);
  2077. pResDes->u.Port.Start.HighPart = HIDWORD(pIoData->IO_Header.IOD_Alloc_Base);
  2078. pResDes->u.Port.Start.LowPart = LODWORD(pIoData->IO_Header.IOD_Alloc_Base);
  2079. pResDes->u.Port.Length = (DWORD)(pIoData->IO_Header.IOD_Alloc_End -
  2080. pIoData->IO_Header.IOD_Alloc_Base + 1);
  2081. break;
  2082. }
  2083. case ResType_DMA: {
  2084. //-------------------------------------------------------
  2085. // DMA Resource Type
  2086. //-------------------------------------------------------
  2087. //
  2088. // Note: u.Dma.Port is not mapped
  2089. // u.Dma.Reserved is not mapped
  2090. //
  2091. PDMA_RESOURCE pDmaData = (PDMA_RESOURCE)ResourceData;
  2092. //
  2093. // validate resource data
  2094. //
  2095. if (ResourceLen < sizeof(DMA_RESOURCE)) {
  2096. Status = CR_FAILURE;
  2097. goto Clean0;
  2098. }
  2099. if (pDmaData->DMA_Header.DD_Type != DType_Range) {
  2100. Status = CR_INVALID_RES_DES;
  2101. goto Clean0;
  2102. }
  2103. //
  2104. // copy DMA_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2105. //
  2106. pResDes->Type = CmResourceTypeDma;
  2107. pResDes->ShareDisposition = CmResourceShareUndetermined;
  2108. //pResDes->ShareDisposition = MapToNtDisposition(pDmaData->DMA_Header.DD_Flags, 0);
  2109. pResDes->Flags = MapToNtDmaFlags(pDmaData->DMA_Header.DD_Flags);
  2110. pResDes->u.Dma.Channel = pDmaData->DMA_Header.DD_Alloc_Chan;
  2111. pResDes->u.Dma.Port = 0;
  2112. pResDes->u.Dma.Reserved1 = 0;
  2113. break;
  2114. }
  2115. case ResType_IRQ: {
  2116. //-------------------------------------------------------
  2117. // IRQ Resource Type
  2118. //-------------------------------------------------------
  2119. if (ulFlags & CM_RESDES_WIDTH_64) {
  2120. //
  2121. // CM_RESDES_WIDTH_64
  2122. //
  2123. PIRQ_RESOURCE_64 pIrqData = (PIRQ_RESOURCE_64)ResourceData;
  2124. //
  2125. // validate resource data
  2126. //
  2127. if (ResourceLen < GetResDesSize(ResourceType, ulFlags)) {
  2128. Status = CR_FAILURE;
  2129. goto Clean0;
  2130. }
  2131. if (pIrqData->IRQ_Header.IRQD_Type != IRQType_Range) {
  2132. Status = CR_INVALID_RES_DES;
  2133. goto Clean0;
  2134. }
  2135. //
  2136. // copy IRQ_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2137. //
  2138. pResDes->Type = CmResourceTypeInterrupt;
  2139. pResDes->ShareDisposition = MapToNtIrqShare(pIrqData->IRQ_Header.IRQD_Flags);
  2140. //pResDes->ShareDisposition = MapToNtDisposition(pIrqData->IRQ_Header.IRQD_Flags, 1);
  2141. pResDes->Flags = MapToNtIrqFlags(pIrqData->IRQ_Header.IRQD_Flags);
  2142. pResDes->u.Interrupt.Level = pIrqData->IRQ_Header.IRQD_Alloc_Num;
  2143. pResDes->u.Interrupt.Vector = pIrqData->IRQ_Header.IRQD_Alloc_Num;
  2144. #ifdef _WIN64
  2145. pResDes->u.Interrupt.Affinity = pIrqData->IRQ_Header.IRQD_Affinity;
  2146. #else // !_WIN64
  2147. pResDes->u.Interrupt.Affinity = (ULONG)pIrqData->IRQ_Header.IRQD_Affinity;
  2148. #endif // !_WIN64
  2149. } else {
  2150. //
  2151. // CM_RESDES_WIDTH_32
  2152. //
  2153. PIRQ_RESOURCE_32 pIrqData = (PIRQ_RESOURCE_32)ResourceData;
  2154. //
  2155. // validate resource data
  2156. //
  2157. if (ResourceLen < GetResDesSize(ResourceType, ulFlags)) {
  2158. Status = CR_FAILURE;
  2159. goto Clean0;
  2160. }
  2161. if (pIrqData->IRQ_Header.IRQD_Type != IRQType_Range) {
  2162. Status = CR_INVALID_RES_DES;
  2163. goto Clean0;
  2164. }
  2165. //
  2166. // copy IRQ_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2167. //
  2168. pResDes->Type = CmResourceTypeInterrupt;
  2169. pResDes->ShareDisposition = MapToNtIrqShare(pIrqData->IRQ_Header.IRQD_Flags);
  2170. //pResDes->ShareDisposition = MapToNtDisposition(pIrqData->IRQ_Header.IRQD_Flags, 1);
  2171. pResDes->Flags = MapToNtIrqFlags(pIrqData->IRQ_Header.IRQD_Flags);
  2172. pResDes->u.Interrupt.Level = pIrqData->IRQ_Header.IRQD_Alloc_Num;
  2173. pResDes->u.Interrupt.Vector = pIrqData->IRQ_Header.IRQD_Alloc_Num;
  2174. pResDes->u.Interrupt.Affinity = pIrqData->IRQ_Header.IRQD_Affinity;
  2175. }
  2176. break;
  2177. }
  2178. case ResType_DevicePrivate: {
  2179. //-------------------------------------------------------
  2180. // Device Private Resource Type
  2181. //-------------------------------------------------------
  2182. PDEVPRIVATE_RESOURCE pPrvData = (PDEVPRIVATE_RESOURCE)ResourceData;
  2183. //
  2184. // validate resource data
  2185. //
  2186. if (ResourceLen < sizeof(DEVPRIVATE_RESOURCE)) {
  2187. Status = CR_INVALID_RES_DES;
  2188. goto Clean0;
  2189. }
  2190. if (pPrvData->PRV_Header.PD_Type != PType_Range) {
  2191. Status = CR_INVALID_RES_DES;
  2192. goto Clean0;
  2193. }
  2194. //
  2195. // copy DEVICEPRIVATE_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2196. //
  2197. pResDes->Type = CmResourceTypeDevicePrivate;
  2198. pResDes->ShareDisposition = CmResourceShareUndetermined;
  2199. pResDes->Flags = (USHORT)pPrvData->PRV_Header.PD_Flags;
  2200. pResDes->u.DevicePrivate.Data[0] = pPrvData->PRV_Header.PD_Data1;
  2201. pResDes->u.DevicePrivate.Data[1] = pPrvData->PRV_Header.PD_Data2;
  2202. pResDes->u.DevicePrivate.Data[2] = pPrvData->PRV_Header.PD_Data3;
  2203. break;
  2204. }
  2205. case ResType_BusNumber: {
  2206. //-------------------------------------------------------
  2207. // Bus Number Resource Type
  2208. //-------------------------------------------------------
  2209. PBUSNUMBER_RESOURCE pBusData = (PBUSNUMBER_RESOURCE)ResourceData;
  2210. //
  2211. // validate resource data
  2212. //
  2213. if (ResourceLen < sizeof(BUSNUMBER_RESOURCE)) {
  2214. Status = CR_INVALID_RES_DES;
  2215. goto Clean0;
  2216. }
  2217. if (pBusData->BusNumber_Header.BUSD_Type != BusNumberType_Range) {
  2218. Status = CR_INVALID_RES_DES;
  2219. goto Clean0;
  2220. }
  2221. //
  2222. // copy BUSNUMBER_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2223. //
  2224. pResDes->Type = CmResourceTypeBusNumber;
  2225. pResDes->ShareDisposition = CmResourceShareUndetermined;
  2226. pResDes->Flags = (USHORT)pBusData->BusNumber_Header.BUSD_Flags;
  2227. pResDes->u.BusNumber.Start = pBusData->BusNumber_Header.BUSD_Alloc_Base;
  2228. pResDes->u.BusNumber.Length = pBusData->BusNumber_Header.BUSD_Alloc_End;
  2229. pResDes->u.BusNumber.Reserved = 0;
  2230. break;
  2231. }
  2232. case ResType_PcCardConfig: {
  2233. //-------------------------------------------------------
  2234. // PcCarConfig Resource Type
  2235. //-------------------------------------------------------
  2236. PPCCARD_RESOURCE pPcData = (PPCCARD_RESOURCE)ResourceData;
  2237. ULONG index;
  2238. ULONG flags;
  2239. ULONG waitstate[2];
  2240. //
  2241. // validate resource data
  2242. //
  2243. if (ResourceLen < sizeof(PCCARD_RESOURCE)) {
  2244. Status = CR_INVALID_RES_DES;
  2245. goto Clean0;
  2246. }
  2247. //
  2248. // The following macros use bit manipulation, initialize data
  2249. // fields first.
  2250. //
  2251. pResDes->u.DevicePrivate.Data[0] = 0;
  2252. pResDes->u.DevicePrivate.Data[1] = 0;
  2253. pResDes->u.DevicePrivate.Data[2] = 0;
  2254. //
  2255. // copy PCCARD_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2256. //
  2257. PCMRES_SET_DESCRIPTOR_TYPE(pResDes, DPTYPE_PCMCIA_CONFIGURATION);
  2258. PCMRES_SET_CONFIG_INDEX(pResDes, pPcData->PcCard_Header.PCD_ConfigIndex);
  2259. PCMRES_SET_MEMORY_CARDBASE(pResDes, 0, pPcData->PcCard_Header.PCD_MemoryCardBase1);
  2260. PCMRES_SET_MEMORY_CARDBASE(pResDes, 1, pPcData->PcCard_Header.PCD_MemoryCardBase2);
  2261. flags = pPcData->PcCard_Header.PCD_Flags;
  2262. if (flags & (fPCD_MEM_16 | fPCD_MEM1_16)) {
  2263. PCMRES_SET_MEMORY_FLAG(pResDes, 0, PCMRESF_MEM_16BIT_ACCESS);
  2264. }
  2265. if (flags & (fPCD_MEM_16 | fPCD_MEM2_16)) {
  2266. PCMRES_SET_MEMORY_FLAG(pResDes, 1, PCMRESF_MEM_16BIT_ACCESS);
  2267. }
  2268. if (flags & fPCD_MEM1_A) {
  2269. PCMRES_SET_MEMORY_FLAG(pResDes, 0, PCMRESF_MEM_ATTRIBUTE);
  2270. }
  2271. if (flags & fPCD_MEM2_A) {
  2272. PCMRES_SET_MEMORY_FLAG(pResDes, 1, PCMRESF_MEM_ATTRIBUTE);
  2273. }
  2274. if (flags & fPCD_ATTRIBUTES_PER_WINDOW) {
  2275. waitstate[0] = flags & mPCD_MEM1_WS;
  2276. waitstate[1] = flags & mPCD_MEM2_WS;
  2277. } else {
  2278. waitstate[0] = waitstate[1] = flags & mPCD_MEM_WS;
  2279. }
  2280. for (index = 0; index < 2; index++) {
  2281. switch (waitstate[index]) {
  2282. case fPCD_MEM_WS_ONE:
  2283. case fPCD_MEM1_WS_ONE:
  2284. case fPCD_MEM2_WS_ONE:
  2285. PCMRES_SET_MEMORY_WAITSTATES(pResDes, index, PCMRESF_MEM_WAIT_1);
  2286. break;
  2287. case fPCD_MEM_WS_TWO:
  2288. case fPCD_MEM1_WS_TWO:
  2289. case fPCD_MEM2_WS_TWO:
  2290. PCMRES_SET_MEMORY_WAITSTATES(pResDes, index, PCMRESF_MEM_WAIT_2);
  2291. break;
  2292. case fPCD_MEM_WS_THREE:
  2293. case fPCD_MEM1_WS_THREE:
  2294. case fPCD_MEM2_WS_THREE:
  2295. PCMRES_SET_MEMORY_WAITSTATES(pResDes, index, PCMRESF_MEM_WAIT_3);
  2296. break;
  2297. }
  2298. }
  2299. if (flags & (fPCD_IO_16 | fPCD_IO1_16)) {
  2300. PCMRES_SET_IO_FLAG(pResDes, 0, PCMRESF_IO_16BIT_ACCESS);
  2301. }
  2302. if (flags & (fPCD_IO_16 | fPCD_IO2_16)) {
  2303. PCMRES_SET_IO_FLAG(pResDes, 1, PCMRESF_IO_16BIT_ACCESS);
  2304. }
  2305. if (flags & (fPCD_IO_ZW_8 | fPCD_IO1_ZW_8)) {
  2306. PCMRES_SET_IO_FLAG(pResDes, 0, PCMRESF_IO_ZERO_WAIT_8);
  2307. }
  2308. if (flags & (fPCD_IO_ZW_8 | fPCD_IO2_ZW_8)) {
  2309. PCMRES_SET_IO_FLAG(pResDes, 1, PCMRESF_IO_ZERO_WAIT_8);
  2310. }
  2311. if (flags & (fPCD_IO_SRC_16 | fPCD_IO1_SRC_16)) {
  2312. PCMRES_SET_IO_FLAG(pResDes, 0, PCMRESF_IO_SOURCE_16);
  2313. }
  2314. if (flags & (fPCD_IO_SRC_16 | fPCD_IO2_SRC_16)) {
  2315. PCMRES_SET_IO_FLAG(pResDes, 1, PCMRESF_IO_SOURCE_16);
  2316. }
  2317. if (flags & (fPCD_IO_WS_16 | fPCD_IO1_WS_16)) {
  2318. PCMRES_SET_IO_FLAG(pResDes, 0, PCMRESF_IO_WAIT_16);
  2319. }
  2320. if (flags & (fPCD_IO_WS_16 | fPCD_IO2_WS_16)) {
  2321. PCMRES_SET_IO_FLAG(pResDes, 1, PCMRESF_IO_WAIT_16);
  2322. }
  2323. break;
  2324. }
  2325. case ResType_MfCardConfig: {
  2326. //-------------------------------------------------------
  2327. // MfCardConfig Resource Type
  2328. //-------------------------------------------------------
  2329. PMFCARD_RESOURCE pMfData = (PMFCARD_RESOURCE)ResourceData;
  2330. //
  2331. // validate resource data
  2332. //
  2333. if (ResourceLen < sizeof(MFCARD_RESOURCE)) {
  2334. Status = CR_INVALID_RES_DES;
  2335. goto Clean0;
  2336. }
  2337. //
  2338. // The following macros use bit manipulation, initialize data
  2339. // fields first.
  2340. //
  2341. pResDes->u.DevicePrivate.Data[0] = 0;
  2342. pResDes->u.DevicePrivate.Data[1] = 0;
  2343. pResDes->u.DevicePrivate.Data[2] = 0;
  2344. //
  2345. // copy MFCARD_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2346. //
  2347. PCMRES_SET_DESCRIPTOR_TYPE(pResDes, DPTYPE_PCMCIA_MF_CONFIGURATION);
  2348. PCMRES_SET_CONFIG_OPTIONS(pResDes, pMfData->MfCard_Header.PMF_ConfigOptions);
  2349. PCMRES_SET_PORT_RESOURCE_INDEX(pResDes, pMfData->MfCard_Header.PMF_IoResourceIndex);
  2350. PCMRES_SET_CONFIG_REGISTER_BASE(pResDes, pMfData->MfCard_Header.PMF_ConfigRegisterBase);
  2351. if ((pMfData->MfCard_Header.PMF_Flags & mPMF_AUDIO_ENABLE) == fPMF_AUDIO_ENABLE) {
  2352. PCMRES_SET_AUDIO_ENABLE(pResDes);
  2353. }
  2354. break;
  2355. }
  2356. case ResType_ClassSpecific: {
  2357. //-------------------------------------------------------
  2358. // Class Specific Resource Type
  2359. //-------------------------------------------------------
  2360. PCS_RESOURCE pCsData = (PCS_RESOURCE)ResourceData;
  2361. LPBYTE ptr = NULL;
  2362. //
  2363. // validate resource data
  2364. //
  2365. if (ResourceLen < sizeof(CS_RESOURCE)) {
  2366. Status = CR_FAILURE;
  2367. goto Clean0;
  2368. }
  2369. //
  2370. // copy CS_DES info to CM_PARTIAL_RESOURCE_DESCRIPTOR format
  2371. //
  2372. pResDes->Type = CmResourceTypeDeviceSpecific;
  2373. pResDes->ShareDisposition = CmResourceShareUndetermined;
  2374. pResDes->Flags = (USHORT)pCsData->CS_Header.CSD_Flags; // none defined
  2375. pResDes->u.DeviceSpecificData.DataSize = pCsData->CS_Header.CSD_LegacyDataSize +
  2376. sizeof(GUID) +
  2377. pCsData->CS_Header.CSD_SignatureLength;
  2378. pResDes->u.DeviceSpecificData.Reserved1 = pCsData->CS_Header.CSD_LegacyDataSize;
  2379. pResDes->u.DeviceSpecificData.Reserved2 = pCsData->CS_Header.CSD_SignatureLength;
  2380. //
  2381. // copy the legacy and class-specific signature data
  2382. //
  2383. ptr = (LPBYTE)((LPBYTE)pResDes + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  2384. memcpy(ptr,
  2385. pCsData->CS_Header.CSD_Signature + pCsData->CS_Header.CSD_LegacyDataOffset,
  2386. pCsData->CS_Header.CSD_LegacyDataSize); // copy legacy data first...
  2387. ptr += pCsData->CS_Header.CSD_LegacyDataSize;
  2388. memcpy(ptr,
  2389. pCsData->CS_Header.CSD_Signature,
  2390. pCsData->CS_Header.CSD_SignatureLength); // then copy signature...
  2391. ptr += pCsData->CS_Header.CSD_SignatureLength;
  2392. memcpy(ptr,
  2393. &pCsData->CS_Header.CSD_ClassGuid,
  2394. sizeof(GUID)); // then copy GUID
  2395. break;
  2396. }
  2397. default:
  2398. Status = CR_INVALID_RESOURCEID;
  2399. break;
  2400. }
  2401. Clean0:
  2402. return Status;
  2403. } // ResDesToNtResource
  2404. CONFIGRET
  2405. ResDesToNtRequirements(
  2406. IN PCVOID ResourceData,
  2407. IN RESOURCEID ResourceType,
  2408. IN ULONG ResourceLen,
  2409. IN PIO_RESOURCE_DESCRIPTOR pReqDes,
  2410. IN OUT PULONG pulResCount,
  2411. IN ULONG ulTag,
  2412. IN ULONG ulFlags
  2413. )
  2414. {
  2415. CONFIGRET Status = CR_SUCCESS;
  2416. ULONG i = 0;
  2417. PIO_RESOURCE_DESCRIPTOR pCurrent = NULL;
  2418. UNREFERENCED_PARAMETER(ulTag);
  2419. //
  2420. // fill in resource type specific info
  2421. //
  2422. switch (ResourceType) {
  2423. case ResType_Mem: {
  2424. //-------------------------------------------------------
  2425. // Memory Resource Type
  2426. //-------------------------------------------------------
  2427. //
  2428. // NOTE: pMemData->MEM_Header.MD_Reserved is not mapped
  2429. // pMemData->MEM_Data.MR_Reserved is not mapped
  2430. //
  2431. PMEM_RESOURCE pMemData = (PMEM_RESOURCE)ResourceData;
  2432. //
  2433. // validate resource data
  2434. //
  2435. if (ResourceLen < sizeof(MEM_RESOURCE)) {
  2436. Status = CR_INVALID_RES_DES;
  2437. goto Clean0;
  2438. }
  2439. if (pMemData->MEM_Header.MD_Type != MType_Range) {
  2440. Status = CR_INVALID_RES_DES;
  2441. goto Clean0;
  2442. }
  2443. *pulResCount = pMemData->MEM_Header.MD_Count;
  2444. //
  2445. // copy MEM_RANGE info to IO_RESOURCE_DESCRIPTOR format
  2446. //
  2447. for (i = 0, pCurrent = pReqDes;
  2448. i < *pulResCount;
  2449. i++, pCurrent++) {
  2450. if (i == 0) {
  2451. pCurrent->Option = 0;
  2452. } else {
  2453. pCurrent->Option = IO_RESOURCE_ALTERNATIVE;
  2454. }
  2455. pCurrent->Type = CmResourceTypeMemory;
  2456. pCurrent->ShareDisposition = CmResourceShareUndetermined;
  2457. //pCurrent->ShareDisposition = MapToNtDisposition(pMemData->MEM_Data[i].MR_Flags, 0);
  2458. pCurrent->Spare1 = 0;
  2459. pCurrent->Spare2 = 0;
  2460. pCurrent->Flags = MapToNtMemoryFlags(pMemData->MEM_Data[i].MR_Flags);
  2461. pCurrent->u.Memory.Length = pMemData->MEM_Data[i].MR_nBytes;
  2462. pCurrent->u.Memory.Alignment = MapToNtAlignment(pMemData->MEM_Data[i].MR_Align);
  2463. pCurrent->u.Memory.MinimumAddress.HighPart = HIDWORD(pMemData->MEM_Data[i].MR_Min);
  2464. pCurrent->u.Memory.MinimumAddress.LowPart = LODWORD(pMemData->MEM_Data[i].MR_Min);
  2465. pCurrent->u.Memory.MaximumAddress.HighPart = HIDWORD(pMemData->MEM_Data[i].MR_Max);
  2466. pCurrent->u.Memory.MaximumAddress.LowPart = LODWORD(pMemData->MEM_Data[i].MR_Max);
  2467. }
  2468. break;
  2469. }
  2470. case ResType_IO: {
  2471. //-------------------------------------------------------
  2472. // IO Port Resource Type
  2473. //-------------------------------------------------------
  2474. PIO_RESOURCE pIoData = (PIO_RESOURCE)ResourceData;
  2475. //
  2476. // validate resource data
  2477. //
  2478. if (ResourceLen < sizeof(IO_RESOURCE)) {
  2479. Status = CR_FAILURE;
  2480. goto Clean0;
  2481. }
  2482. if (pIoData->IO_Header.IOD_Type != IOType_Range) {
  2483. Status = CR_INVALID_RES_DES;
  2484. goto Clean0;
  2485. }
  2486. *pulResCount = pIoData->IO_Header.IOD_Count;
  2487. //
  2488. // copy IO_RANGE info to IO_RESOURCE_DESCRIPTOR format
  2489. //
  2490. for (i = 0, pCurrent = pReqDes;
  2491. i < *pulResCount;
  2492. i++, pCurrent++) {
  2493. if (i == 0) {
  2494. pCurrent->Option = 0;
  2495. } else {
  2496. pCurrent->Option = IO_RESOURCE_ALTERNATIVE;
  2497. }
  2498. pCurrent->Type = CmResourceTypePort;
  2499. pCurrent->ShareDisposition = CmResourceShareUndetermined;
  2500. //pCurrent->ShareDisposition = MapToNtDisposition(pIoData->IO_Data[i].IOR_RangeFlags, 0);
  2501. pCurrent->Spare1 = 0;
  2502. pCurrent->Spare2 = 0;
  2503. pCurrent->Flags = MapToNtPortFlags(pIoData->IO_Data[i].IOR_RangeFlags,
  2504. (DWORD)pIoData->IO_Data[i].IOR_Alias);
  2505. pCurrent->u.Port.Length = pIoData->IO_Data[i].IOR_nPorts;
  2506. pCurrent->u.Port.Alignment = MapToNtAlignment(pIoData->IO_Data[i].IOR_Align);
  2507. pCurrent->u.Port.MinimumAddress.HighPart = HIDWORD(pIoData->IO_Data[i].IOR_Min);
  2508. pCurrent->u.Port.MinimumAddress.LowPart = LODWORD(pIoData->IO_Data[i].IOR_Min);
  2509. pCurrent->u.Port.MaximumAddress.HighPart = HIDWORD(pIoData->IO_Data[i].IOR_Max);
  2510. pCurrent->u.Port.MaximumAddress.LowPart = LODWORD(pIoData->IO_Data[i].IOR_Max);
  2511. }
  2512. break;
  2513. }
  2514. case ResType_DMA: {
  2515. //-------------------------------------------------------
  2516. // DMA Resource Type
  2517. //-------------------------------------------------------
  2518. //
  2519. // Note: u.Dma.Port is not mapped
  2520. // u.Dma.Reserved is not mapped
  2521. //
  2522. PDMA_RESOURCE pDmaData = (PDMA_RESOURCE)ResourceData;
  2523. //
  2524. // validate resource data
  2525. //
  2526. if (ResourceLen < sizeof(DMA_RESOURCE)) {
  2527. Status = CR_FAILURE;
  2528. goto Clean0;
  2529. }
  2530. if (pDmaData->DMA_Header.DD_Type != DType_Range) {
  2531. Status = CR_INVALID_RES_DES;
  2532. goto Clean0;
  2533. }
  2534. *pulResCount = pDmaData->DMA_Header.DD_Count;
  2535. //
  2536. // copy DMA_RANGE info to IO_RESOURCE_DESCRIPTOR format
  2537. //
  2538. for (i = 0, pCurrent = pReqDes;
  2539. i < *pulResCount;
  2540. i++, pCurrent++) {
  2541. if (i == 0) {
  2542. pCurrent->Option = 0;
  2543. } else {
  2544. pCurrent->Option = IO_RESOURCE_ALTERNATIVE;
  2545. }
  2546. pCurrent->Type = CmResourceTypeDma;
  2547. pCurrent->ShareDisposition = CmResourceShareUndetermined;
  2548. //pCurrent->ShareDisposition = MapToNtDisposition(pDmaData->DMA_Data[i].DR_Flags, 0);
  2549. pCurrent->Spare1 = 0;
  2550. pCurrent->Spare2 = 0;
  2551. pCurrent->Flags = MapToNtDmaFlags(pDmaData->DMA_Data[i].DR_Flags);
  2552. pCurrent->u.Dma.MinimumChannel = pDmaData->DMA_Data[i].DR_Min;
  2553. pCurrent->u.Dma.MaximumChannel = pDmaData->DMA_Data[i].DR_Max;
  2554. }
  2555. break;
  2556. }
  2557. case ResType_IRQ: {
  2558. //-------------------------------------------------------
  2559. // IRQ Resource Type
  2560. //-------------------------------------------------------
  2561. if (ulFlags & CM_RESDES_WIDTH_64) {
  2562. //
  2563. // CM_RESDES_WIDTH_64
  2564. //
  2565. PIRQ_RESOURCE_64 pIrqData = (PIRQ_RESOURCE_64)ResourceData;
  2566. //
  2567. // validate resource data
  2568. //
  2569. if (ResourceLen < GetResDesSize(ResourceType, ulFlags)) {
  2570. Status = CR_FAILURE;
  2571. goto Clean0;
  2572. }
  2573. if (pIrqData->IRQ_Header.IRQD_Type != IRQType_Range) {
  2574. Status = CR_INVALID_RES_DES;
  2575. goto Clean0;
  2576. }
  2577. *pulResCount = pIrqData->IRQ_Header.IRQD_Count;
  2578. //
  2579. // copy IO_RANGE info to IO_RESOURCE_DESCRIPTOR format
  2580. //
  2581. for (i = 0, pCurrent = pReqDes;
  2582. i < *pulResCount;
  2583. i++, pCurrent++) {
  2584. if (i == 0) {
  2585. pCurrent->Option = 0;
  2586. } else {
  2587. pCurrent->Option = IO_RESOURCE_ALTERNATIVE;
  2588. }
  2589. pCurrent->Type = CmResourceTypeInterrupt;
  2590. pCurrent->Spare1 = 0;
  2591. pCurrent->Spare2 = 0;
  2592. pCurrent->ShareDisposition = MapToNtIrqShare(pIrqData->IRQ_Data[i].IRQR_Flags);
  2593. //pCurrent->ShareDisposition = MapToNtDisposition(pIrqData->IRQ_Data[i].IRQR_Flags, 1);
  2594. pCurrent->Flags = MapToNtIrqFlags(pIrqData->IRQ_Data[i].IRQR_Flags);
  2595. pCurrent->u.Interrupt.MinimumVector = pIrqData->IRQ_Data[i].IRQR_Min;
  2596. pCurrent->u.Interrupt.MaximumVector = pIrqData->IRQ_Data[i].IRQR_Max;
  2597. }
  2598. } else {
  2599. //
  2600. // CM_RESDES_WIDTH_32
  2601. //
  2602. PIRQ_RESOURCE_32 pIrqData = (PIRQ_RESOURCE_32)ResourceData;
  2603. //
  2604. // validate resource data
  2605. //
  2606. if (ResourceLen < GetResDesSize(ResourceType, ulFlags)) {
  2607. Status = CR_FAILURE;
  2608. goto Clean0;
  2609. }
  2610. if (pIrqData->IRQ_Header.IRQD_Type != IRQType_Range) {
  2611. Status = CR_INVALID_RES_DES;
  2612. goto Clean0;
  2613. }
  2614. *pulResCount = pIrqData->IRQ_Header.IRQD_Count;
  2615. //
  2616. // copy IO_RANGE info to IO_RESOURCE_DESCRIPTOR format
  2617. //
  2618. for (i = 0, pCurrent = pReqDes;
  2619. i < *pulResCount;
  2620. i++, pCurrent++) {
  2621. if (i == 0) {
  2622. pCurrent->Option = 0;
  2623. } else {
  2624. pCurrent->Option = IO_RESOURCE_ALTERNATIVE;
  2625. }
  2626. pCurrent->Type = CmResourceTypeInterrupt;
  2627. pCurrent->Spare1 = 0;
  2628. pCurrent->Spare2 = 0;
  2629. pCurrent->ShareDisposition = MapToNtIrqShare(pIrqData->IRQ_Data[i].IRQR_Flags);
  2630. //pCurrent->ShareDisposition = MapToNtDisposition(pIrqData->IRQ_Data[i].IRQR_Flags, 1);
  2631. pCurrent->Flags = MapToNtIrqFlags(pIrqData->IRQ_Data[i].IRQR_Flags);
  2632. pCurrent->u.Interrupt.MinimumVector = pIrqData->IRQ_Data[i].IRQR_Min;
  2633. pCurrent->u.Interrupt.MaximumVector = pIrqData->IRQ_Data[i].IRQR_Max;
  2634. }
  2635. }
  2636. break;
  2637. }
  2638. case ResType_DevicePrivate: {
  2639. //-------------------------------------------------------
  2640. // Device Private Resource Type
  2641. //-------------------------------------------------------
  2642. PDEVPRIVATE_RESOURCE pPrvData = (PDEVPRIVATE_RESOURCE)ResourceData;
  2643. //
  2644. // validate resource data
  2645. //
  2646. if (ResourceLen < sizeof(DEVPRIVATE_RESOURCE)) {
  2647. Status = CR_INVALID_RES_DES;
  2648. goto Clean0;
  2649. }
  2650. if (pPrvData->PRV_Header.PD_Type != PType_Range) {
  2651. Status = CR_INVALID_RES_DES;
  2652. goto Clean0;
  2653. }
  2654. *pulResCount = pPrvData->PRV_Header.PD_Count;
  2655. //
  2656. // copy DEVICEPRIVATE_RANGE info to IO_RESOURCE_DESCRIPTOR format
  2657. //
  2658. for (i = 0, pCurrent = pReqDes;
  2659. i < *pulResCount;
  2660. i++, pCurrent++) {
  2661. if (i == 0) {
  2662. pCurrent->Option = 0;
  2663. } else {
  2664. pCurrent->Option = IO_RESOURCE_ALTERNATIVE;
  2665. }
  2666. pCurrent->Type = CmResourceTypeDevicePrivate;
  2667. pCurrent->ShareDisposition = CmResourceShareUndetermined;
  2668. pCurrent->Spare1 = 0;
  2669. pCurrent->Spare2 = 0;
  2670. pCurrent->Flags = (USHORT)pPrvData->PRV_Header.PD_Flags;
  2671. pCurrent->u.DevicePrivate.Data[0] = pPrvData->PRV_Data[i].PR_Data1;
  2672. pCurrent->u.DevicePrivate.Data[1] = pPrvData->PRV_Data[i].PR_Data2;
  2673. pCurrent->u.DevicePrivate.Data[2] = pPrvData->PRV_Data[i].PR_Data3;
  2674. }
  2675. break;
  2676. }
  2677. case ResType_BusNumber: {
  2678. //-------------------------------------------------------
  2679. // Bus Number Resource Type
  2680. //-------------------------------------------------------
  2681. PBUSNUMBER_RESOURCE pBusData = (PBUSNUMBER_RESOURCE)ResourceData;
  2682. //
  2683. // validate resource data
  2684. //
  2685. if (ResourceLen < sizeof(BUSNUMBER_RESOURCE)) {
  2686. Status = CR_INVALID_RES_DES;
  2687. goto Clean0;
  2688. }
  2689. if (pBusData->BusNumber_Header.BUSD_Type != BusNumberType_Range) {
  2690. Status = CR_INVALID_RES_DES;
  2691. goto Clean0;
  2692. }
  2693. *pulResCount = pBusData->BusNumber_Header.BUSD_Count;
  2694. //
  2695. // copy BUSNUMBER_RANGE info to IO_RESOURCE_DESCRIPTOR format
  2696. //
  2697. for (i = 0, pCurrent = pReqDes;
  2698. i < *pulResCount;
  2699. i++, pCurrent++) {
  2700. if (i == 0) {
  2701. pCurrent->Option = 0;
  2702. } else {
  2703. pCurrent->Option = IO_RESOURCE_ALTERNATIVE;
  2704. }
  2705. pCurrent->Type = CmResourceTypeBusNumber;
  2706. pCurrent->ShareDisposition = CmResourceShareUndetermined;
  2707. pCurrent->Spare1 = 0;
  2708. pCurrent->Spare2 = 0;
  2709. pCurrent->Flags = (USHORT)pBusData->BusNumber_Data[i].BUSR_Flags;
  2710. pCurrent->u.BusNumber.Length = pBusData->BusNumber_Data[i].BUSR_nBusNumbers;
  2711. pCurrent->u.BusNumber.MinBusNumber = pBusData->BusNumber_Data[i].BUSR_Min;
  2712. pCurrent->u.BusNumber.MaxBusNumber = pBusData->BusNumber_Data[i].BUSR_Max;
  2713. pCurrent->u.BusNumber.Reserved = 0;
  2714. }
  2715. break;
  2716. }
  2717. case ResType_PcCardConfig: {
  2718. //-------------------------------------------------------
  2719. // PcCardConfig Resource Type
  2720. //-------------------------------------------------------
  2721. PPCCARD_RESOURCE pPcData = (PPCCARD_RESOURCE)ResourceData;
  2722. ULONG index;
  2723. ULONG flags;
  2724. ULONG waitstate[2];
  2725. //
  2726. // validate resource data
  2727. //
  2728. if (ResourceLen < sizeof(PCCARD_RESOURCE)) {
  2729. Status = CR_INVALID_RES_DES;
  2730. goto Clean0;
  2731. }
  2732. *pulResCount = 1;
  2733. //
  2734. // copy PCCARD_DES info to IO_RESOURCE_DESCRIPTOR format
  2735. //
  2736. pReqDes->Option = 0;
  2737. pReqDes->Type = CmResourceTypeDevicePrivate;
  2738. pReqDes->ShareDisposition = CmResourceShareUndetermined;
  2739. pReqDes->Spare1 = 0;
  2740. pReqDes->Spare2 = 0;
  2741. pReqDes->Flags = 0;
  2742. //
  2743. // The following macros use bit manipulation, initialize data
  2744. // fields first.
  2745. //
  2746. pReqDes->u.DevicePrivate.Data[0] = 0;
  2747. pReqDes->u.DevicePrivate.Data[1] = 0;
  2748. pReqDes->u.DevicePrivate.Data[2] = 0;
  2749. PCMRES_SET_DESCRIPTOR_TYPE(pReqDes, DPTYPE_PCMCIA_CONFIGURATION);
  2750. PCMRES_SET_CONFIG_INDEX(pReqDes, pPcData->PcCard_Header.PCD_ConfigIndex);
  2751. PCMRES_SET_MEMORY_CARDBASE(pReqDes, 0, pPcData->PcCard_Header.PCD_MemoryCardBase1);
  2752. PCMRES_SET_MEMORY_CARDBASE(pReqDes, 1, pPcData->PcCard_Header.PCD_MemoryCardBase2);
  2753. flags = pPcData->PcCard_Header.PCD_Flags;
  2754. if (flags & (fPCD_MEM_16 | fPCD_MEM1_16)) {
  2755. PCMRES_SET_MEMORY_FLAG(pReqDes, 0, PCMRESF_MEM_16BIT_ACCESS);
  2756. }
  2757. if (flags & (fPCD_MEM_16 | fPCD_MEM2_16)) {
  2758. PCMRES_SET_MEMORY_FLAG(pReqDes, 1, PCMRESF_MEM_16BIT_ACCESS);
  2759. }
  2760. if (flags & fPCD_MEM1_A) {
  2761. PCMRES_SET_MEMORY_FLAG(pReqDes, 0, PCMRESF_MEM_ATTRIBUTE);
  2762. }
  2763. if (flags & fPCD_MEM2_A) {
  2764. PCMRES_SET_MEMORY_FLAG(pReqDes, 1, PCMRESF_MEM_ATTRIBUTE);
  2765. }
  2766. if (flags & fPCD_ATTRIBUTES_PER_WINDOW) {
  2767. waitstate[0] = flags & mPCD_MEM1_WS;
  2768. waitstate[1] = flags & mPCD_MEM2_WS;
  2769. } else {
  2770. waitstate[0] = waitstate[1] = flags & mPCD_MEM_WS;
  2771. }
  2772. for (index = 0; index < 2; index++) {
  2773. switch (waitstate[index]) {
  2774. case fPCD_MEM_WS_ONE:
  2775. case fPCD_MEM1_WS_ONE:
  2776. case fPCD_MEM2_WS_ONE:
  2777. PCMRES_SET_MEMORY_WAITSTATES(pReqDes, index, PCMRESF_MEM_WAIT_1);
  2778. break;
  2779. case fPCD_MEM_WS_TWO:
  2780. case fPCD_MEM1_WS_TWO:
  2781. case fPCD_MEM2_WS_TWO:
  2782. PCMRES_SET_MEMORY_WAITSTATES(pReqDes, index, PCMRESF_MEM_WAIT_2);
  2783. break;
  2784. case fPCD_MEM_WS_THREE:
  2785. case fPCD_MEM1_WS_THREE:
  2786. case fPCD_MEM2_WS_THREE:
  2787. PCMRES_SET_MEMORY_WAITSTATES(pReqDes, index, PCMRESF_MEM_WAIT_3);
  2788. break;
  2789. }
  2790. }
  2791. if (flags & (fPCD_IO_16 | fPCD_IO1_16)) {
  2792. PCMRES_SET_IO_FLAG(pReqDes, 0, PCMRESF_IO_16BIT_ACCESS);
  2793. }
  2794. if (flags & (fPCD_IO_16 | fPCD_IO2_16)) {
  2795. PCMRES_SET_IO_FLAG(pReqDes, 1, PCMRESF_IO_16BIT_ACCESS);
  2796. }
  2797. if (flags & (fPCD_IO_ZW_8 | fPCD_IO1_ZW_8)) {
  2798. PCMRES_SET_IO_FLAG(pReqDes, 0, PCMRESF_IO_ZERO_WAIT_8);
  2799. }
  2800. if (flags & (fPCD_IO_ZW_8 | fPCD_IO2_ZW_8)) {
  2801. PCMRES_SET_IO_FLAG(pReqDes, 1, PCMRESF_IO_ZERO_WAIT_8);
  2802. }
  2803. if (flags & (fPCD_IO_SRC_16 | fPCD_IO1_SRC_16)) {
  2804. PCMRES_SET_IO_FLAG(pReqDes, 0, PCMRESF_IO_SOURCE_16);
  2805. }
  2806. if (flags & (fPCD_IO_SRC_16 | fPCD_IO2_SRC_16)) {
  2807. PCMRES_SET_IO_FLAG(pReqDes, 1, PCMRESF_IO_SOURCE_16);
  2808. }
  2809. if (flags & (fPCD_IO_WS_16 | fPCD_IO1_WS_16)) {
  2810. PCMRES_SET_IO_FLAG(pReqDes, 0, PCMRESF_IO_WAIT_16);
  2811. }
  2812. if (flags & (fPCD_IO_WS_16 | fPCD_IO2_WS_16)) {
  2813. PCMRES_SET_IO_FLAG(pReqDes, 1, PCMRESF_IO_WAIT_16);
  2814. }
  2815. break;
  2816. }
  2817. case ResType_MfCardConfig: {
  2818. //-------------------------------------------------------
  2819. // PcCardConfig Resource Type
  2820. //-------------------------------------------------------
  2821. PMFCARD_RESOURCE pMfData = (PMFCARD_RESOURCE)ResourceData;
  2822. //
  2823. // validate resource data
  2824. //
  2825. if (ResourceLen < sizeof(MFCARD_RESOURCE)) {
  2826. Status = CR_INVALID_RES_DES;
  2827. goto Clean0;
  2828. }
  2829. *pulResCount = 1;
  2830. //
  2831. // copy PCCARD_DES info to IO_RESOURCE_DESCRIPTOR format
  2832. //
  2833. pReqDes->Option = 0;
  2834. pReqDes->Type = CmResourceTypeDevicePrivate;
  2835. pReqDes->ShareDisposition = CmResourceShareUndetermined;
  2836. pReqDes->Spare1 = 0;
  2837. pReqDes->Spare2 = 0;
  2838. pReqDes->Flags = 0;
  2839. //
  2840. // The following macros use bit manipulation, initialize data
  2841. // fields first.
  2842. //
  2843. pReqDes->u.DevicePrivate.Data[0] = 0;
  2844. pReqDes->u.DevicePrivate.Data[1] = 0;
  2845. pReqDes->u.DevicePrivate.Data[2] = 0;
  2846. PCMRES_SET_DESCRIPTOR_TYPE(pReqDes, DPTYPE_PCMCIA_MF_CONFIGURATION);
  2847. PCMRES_SET_CONFIG_OPTIONS(pReqDes, pMfData->MfCard_Header.PMF_ConfigOptions);
  2848. PCMRES_SET_PORT_RESOURCE_INDEX(pReqDes, pMfData->MfCard_Header.PMF_IoResourceIndex);
  2849. PCMRES_SET_CONFIG_REGISTER_BASE(pReqDes, pMfData->MfCard_Header.PMF_ConfigRegisterBase);
  2850. if ((pMfData->MfCard_Header.PMF_Flags & mPMF_AUDIO_ENABLE) == fPMF_AUDIO_ENABLE) {
  2851. PCMRES_SET_AUDIO_ENABLE(pReqDes);
  2852. }
  2853. break;
  2854. }
  2855. default:
  2856. Status = CR_INVALID_RESOURCEID;
  2857. break;
  2858. }
  2859. Clean0:
  2860. return Status;
  2861. } // ResDesToNtRequirements
  2862. CONFIGRET
  2863. NtResourceToResDes(
  2864. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes,
  2865. IN OUT LPBYTE Buffer,
  2866. IN ULONG BufferLen,
  2867. IN LPBYTE pLastAddr,
  2868. IN ULONG ulFlags
  2869. )
  2870. {
  2871. CONFIGRET Status = CR_SUCCESS;
  2872. UNREFERENCED_PARAMETER(pLastAddr);
  2873. //
  2874. // fill in resource type specific info
  2875. //
  2876. switch (pResDes->Type) {
  2877. case CmResourceTypeMemory: {
  2878. //-------------------------------------------------------
  2879. // Memory Resource Type
  2880. //-------------------------------------------------------
  2881. //
  2882. // NOTE: pMemData->MEM_Header.MD_Reserved is not mapped
  2883. // pMemData->MEM_Data.MR_Reserved is not mapped
  2884. //
  2885. PMEM_RESOURCE pMemData = (PMEM_RESOURCE)Buffer;
  2886. //
  2887. // verify passed in buffer size
  2888. //
  2889. if (BufferLen < sizeof(MEM_RESOURCE)) {
  2890. Status = CR_BUFFER_SMALL;
  2891. goto Clean0;
  2892. }
  2893. //
  2894. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to MEM_DES format
  2895. //
  2896. pMemData->MEM_Header.MD_Count = 0;
  2897. pMemData->MEM_Header.MD_Type = MType_Range;
  2898. pMemData->MEM_Header.MD_Flags = MapFromNtMemoryFlags(pResDes->Flags);
  2899. //pMemData->MEM_Header.MD_Flags |= MapFromNtDisposition(pResDes->ShareDisposition, 0);
  2900. pMemData->MEM_Header.MD_Reserved = 0;
  2901. if (pResDes->u.Memory.Length != 0) {
  2902. pMemData->MEM_Header.MD_Alloc_Base = MAKEDWORDLONG(pResDes->u.Memory.Start.LowPart,
  2903. pResDes->u.Memory.Start.HighPart);
  2904. pMemData->MEM_Header.MD_Alloc_End = pMemData->MEM_Header.MD_Alloc_Base +
  2905. (DWORDLONG)pResDes->u.Memory.Length - 1;
  2906. } else {
  2907. pMemData->MEM_Header.MD_Alloc_Base = 1;
  2908. pMemData->MEM_Header.MD_Alloc_End = 0;
  2909. }
  2910. break;
  2911. }
  2912. case CmResourceTypePort: {
  2913. //-------------------------------------------------------
  2914. // IO Port Resource Type
  2915. //
  2916. // NOTE: alias info lost during this conversion process
  2917. //-------------------------------------------------------
  2918. PIO_RESOURCE pIoData = (PIO_RESOURCE)Buffer;
  2919. //
  2920. // verify passed in buffer size
  2921. //
  2922. if (BufferLen < sizeof(IO_RESOURCE)) {
  2923. Status = CR_BUFFER_SMALL;
  2924. goto Clean0;
  2925. }
  2926. //
  2927. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to IO_DES format
  2928. //
  2929. pIoData->IO_Header.IOD_Count = 0;
  2930. pIoData->IO_Header.IOD_Type = IOType_Range;
  2931. pIoData->IO_Header.IOD_DesFlags = MapFromNtPortFlags(pResDes->Flags);
  2932. //pIoData->IO_Header.IOD_DesFlags |= MapFromNtDisposition(pResDes->ShareDisposition, 0);
  2933. if (pResDes->u.Port.Length) {
  2934. pIoData->IO_Header.IOD_Alloc_Base = MAKEDWORDLONG(pResDes->u.Port.Start.LowPart,
  2935. pResDes->u.Port.Start.HighPart);
  2936. pIoData->IO_Header.IOD_Alloc_End = pIoData->IO_Header.IOD_Alloc_Base +
  2937. (DWORDLONG)pResDes->u.Port.Length - 1;
  2938. } else {
  2939. pIoData->IO_Header.IOD_Alloc_Base = 1;
  2940. pIoData->IO_Header.IOD_Alloc_End = 0;
  2941. }
  2942. break;
  2943. }
  2944. case CmResourceTypeDma: {
  2945. //-------------------------------------------------------
  2946. // DMA Resource Type
  2947. //-------------------------------------------------------
  2948. //
  2949. // Note: u.Dma.Port is not mapped
  2950. // u.Dma.Reserved is not mapped
  2951. //
  2952. PDMA_RESOURCE pDmaData = (PDMA_RESOURCE)Buffer;
  2953. //
  2954. // verify passed in buffer size
  2955. //
  2956. if (BufferLen < sizeof(DMA_RESOURCE)) {
  2957. Status = CR_BUFFER_SMALL;
  2958. goto Clean0;
  2959. }
  2960. //
  2961. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to DMA_DES format
  2962. //
  2963. pDmaData->DMA_Header.DD_Count = 0;
  2964. pDmaData->DMA_Header.DD_Type = DType_Range;
  2965. pDmaData->DMA_Header.DD_Flags = MapFromNtDmaFlags(pResDes->Flags);
  2966. //pDmaData->DMA_Header.DD_Flags |= MapFromNtDisposition(pResDes->ShareDisposition, 0);
  2967. pDmaData->DMA_Header.DD_Alloc_Chan = pResDes->u.Dma.Channel;
  2968. break;
  2969. }
  2970. case CmResourceTypeInterrupt: {
  2971. //-------------------------------------------------------
  2972. // IRQ Resource Type
  2973. //-------------------------------------------------------
  2974. if (ulFlags & CM_RESDES_WIDTH_64) {
  2975. //
  2976. // CM_RESDES_WIDTH_64
  2977. //
  2978. PIRQ_RESOURCE_64 pIrqData = (PIRQ_RESOURCE_64)Buffer;
  2979. //
  2980. // verify passed in buffer size
  2981. //
  2982. if (BufferLen < GetResDesSize(ResType_IRQ, ulFlags)) {
  2983. Status = CR_BUFFER_SMALL;
  2984. goto Clean0;
  2985. }
  2986. //
  2987. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to IRQ_DES format
  2988. //
  2989. pIrqData->IRQ_Header.IRQD_Count = 0;
  2990. pIrqData->IRQ_Header.IRQD_Type = IRQType_Range;
  2991. pIrqData->IRQ_Header.IRQD_Flags = MapFromNtIrqFlags(pResDes->Flags) |
  2992. MapFromNtIrqShare(pResDes->ShareDisposition);
  2993. //pIrqData->IRQ_Header.IRQD_Flags |= MapFromNtDisposition(pResDes->ShareDisposition, 1);
  2994. pIrqData->IRQ_Header.IRQD_Alloc_Num = pResDes->u.Interrupt.Level;
  2995. pIrqData->IRQ_Header.IRQD_Affinity = pResDes->u.Interrupt.Affinity;
  2996. } else {
  2997. //
  2998. // CM_RESDES_WIDTH_32
  2999. //
  3000. PIRQ_RESOURCE_32 pIrqData = (PIRQ_RESOURCE_32)Buffer;
  3001. //
  3002. // verify passed in buffer size
  3003. //
  3004. if (BufferLen < GetResDesSize(ResType_IRQ, ulFlags)) {
  3005. Status = CR_BUFFER_SMALL;
  3006. goto Clean0;
  3007. }
  3008. //
  3009. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to IRQ_DES format
  3010. //
  3011. pIrqData->IRQ_Header.IRQD_Count = 0;
  3012. pIrqData->IRQ_Header.IRQD_Type = IRQType_Range;
  3013. pIrqData->IRQ_Header.IRQD_Flags = MapFromNtIrqFlags(pResDes->Flags) |
  3014. MapFromNtIrqShare(pResDes->ShareDisposition);
  3015. //pIrqData->IRQ_Header.IRQD_Flags |= MapFromNtDisposition(pResDes->ShareDisposition, 1);
  3016. pIrqData->IRQ_Header.IRQD_Alloc_Num = pResDes->u.Interrupt.Level;
  3017. #ifdef _WIN64
  3018. pIrqData->IRQ_Header.IRQD_Affinity = (ULONG)((pResDes->u.Interrupt.Affinity >> 32) |
  3019. pResDes->u.Interrupt.Affinity);
  3020. #else // !_WIN64
  3021. pIrqData->IRQ_Header.IRQD_Affinity = pResDes->u.Interrupt.Affinity;
  3022. #endif // !_WIN64
  3023. }
  3024. break;
  3025. }
  3026. case CmResourceTypeDevicePrivate: {
  3027. //-------------------------------------------------------
  3028. // Device Private Resource Type
  3029. //-------------------------------------------------------
  3030. PDEVPRIVATE_RESOURCE pPrvData = (PDEVPRIVATE_RESOURCE)Buffer;
  3031. //
  3032. // verify passed in buffer size
  3033. //
  3034. if (BufferLen < sizeof(DEVPRIVATE_RESOURCE)) {
  3035. Status = CR_BUFFER_SMALL;
  3036. goto Clean0;
  3037. }
  3038. //
  3039. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to DEVICEPRIVATE_DES format
  3040. //
  3041. pPrvData->PRV_Header.PD_Count = 0;
  3042. pPrvData->PRV_Header.PD_Type = PType_Range;
  3043. pPrvData->PRV_Header.PD_Data1 = pResDes->u.DevicePrivate.Data[0];
  3044. pPrvData->PRV_Header.PD_Data2 = pResDes->u.DevicePrivate.Data[1];
  3045. pPrvData->PRV_Header.PD_Data3 = pResDes->u.DevicePrivate.Data[2];
  3046. pPrvData->PRV_Header.PD_Flags = pResDes->Flags;
  3047. break;
  3048. }
  3049. case CmResourceTypeBusNumber: {
  3050. //-------------------------------------------------------
  3051. // Bus Number Resource Type
  3052. //-------------------------------------------------------
  3053. PBUSNUMBER_RESOURCE pBusData = (PBUSNUMBER_RESOURCE)Buffer;
  3054. //
  3055. // verify passed in buffer size
  3056. //
  3057. if (BufferLen < sizeof(BUSNUMBER_RESOURCE)) {
  3058. Status = CR_BUFFER_SMALL;
  3059. goto Clean0;
  3060. }
  3061. //
  3062. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to BUSNUMBER_DES format
  3063. //
  3064. pBusData->BusNumber_Header.BUSD_Count = 0;
  3065. pBusData->BusNumber_Header.BUSD_Type = BusNumberType_Range;
  3066. pBusData->BusNumber_Header.BUSD_Flags = pResDes->Flags;
  3067. pBusData->BusNumber_Header.BUSD_Alloc_Base = pResDes->u.BusNumber.Start;
  3068. pBusData->BusNumber_Header.BUSD_Alloc_End = pResDes->u.BusNumber.Start +
  3069. pResDes->u.BusNumber.Length - 1;
  3070. break;
  3071. }
  3072. case CmResourceTypePcCardConfig: {
  3073. //-------------------------------------------------------
  3074. // PcCardConfig Resource Type
  3075. //-------------------------------------------------------
  3076. PPCCARD_RESOURCE pPcData = (PPCCARD_RESOURCE)Buffer;
  3077. //
  3078. // verify passed in buffer size
  3079. //
  3080. if (BufferLen < sizeof(PCCARD_RESOURCE)) {
  3081. Status = CR_BUFFER_SMALL;
  3082. goto Clean0;
  3083. }
  3084. //
  3085. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to PCCARD_DES format
  3086. //
  3087. pPcData->PcCard_Header.PCD_Reserved[0] = 0;
  3088. pPcData->PcCard_Header.PCD_Reserved[1] = 0;
  3089. pPcData->PcCard_Header.PCD_Reserved[2] = 0;
  3090. pPcData->PcCard_Header.PCD_ConfigIndex = PCMRES_GET_CONFIG_INDEX(pResDes);
  3091. pPcData->PcCard_Header.PCD_MemoryCardBase1 = PCMRES_GET_MEMORY_CARDBASE(pResDes, 0);
  3092. pPcData->PcCard_Header.PCD_MemoryCardBase2 = PCMRES_GET_MEMORY_CARDBASE(pResDes, 1);
  3093. if (PCMRES_GET_IO_FLAG(pResDes, 0, PCMRESF_IO_16BIT_ACCESS)) {
  3094. pPcData->PcCard_Header.PCD_Flags = fPCD_IO_16;
  3095. } else {
  3096. pPcData->PcCard_Header.PCD_Flags = fPCD_IO_8;
  3097. }
  3098. if (PCMRES_GET_MEMORY_FLAG(pResDes, 0, PCMRESF_MEM_16BIT_ACCESS)) {
  3099. pPcData->PcCard_Header.PCD_Flags |= fPCD_MEM_16;
  3100. } else {
  3101. pPcData->PcCard_Header.PCD_Flags |= fPCD_MEM_8;
  3102. }
  3103. break;
  3104. }
  3105. case CmResourceTypeDeviceSpecific: {
  3106. //-------------------------------------------------------
  3107. // Class Specific Resource Type
  3108. //-------------------------------------------------------
  3109. PCS_RESOURCE pCsData = (PCS_RESOURCE)Buffer;
  3110. LPBYTE ptr1 = NULL, ptr2 = NULL;
  3111. ULONG ulRequiredSize = sizeof(CS_RESOURCE);
  3112. //
  3113. // the Reserved fields should not exceed DataSize. if so, they
  3114. // may have been incorrectly initialized, so set them 0.
  3115. // we expect DataSize to be correct in all cases.
  3116. //
  3117. if (pResDes->u.DeviceSpecificData.Reserved1 > pResDes->u.DeviceSpecificData.DataSize) {
  3118. pResDes->u.DeviceSpecificData.Reserved1 = 0;
  3119. }
  3120. if (pResDes->u.DeviceSpecificData.Reserved2 > pResDes->u.DeviceSpecificData.DataSize) {
  3121. pResDes->u.DeviceSpecificData.Reserved2 = 0;
  3122. }
  3123. //
  3124. // verify passed in buffer size
  3125. //
  3126. if (pResDes->u.DeviceSpecificData.DataSize == 0) {
  3127. //
  3128. // there is no legacy data and no class-specific data
  3129. //
  3130. ;
  3131. } else if (pResDes->u.DeviceSpecificData.Reserved2 == 0) {
  3132. //
  3133. // add space for legacy data
  3134. //
  3135. ulRequiredSize += pResDes->u.DeviceSpecificData.DataSize - 1;
  3136. } else {
  3137. //
  3138. // add space for legacy and signature data, as necessary
  3139. //
  3140. ulRequiredSize += pResDes->u.DeviceSpecificData.Reserved1 +
  3141. pResDes->u.DeviceSpecificData.Reserved2 - 1;
  3142. }
  3143. if (BufferLen < ulRequiredSize) {
  3144. Status = CR_BUFFER_SMALL;
  3145. goto Clean0;
  3146. }
  3147. //
  3148. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to CS_DES format
  3149. //
  3150. pCsData->CS_Header.CSD_Flags = (DWORD)pResDes->Flags; // none defined
  3151. if (pResDes->u.DeviceSpecificData.DataSize == 0) {
  3152. //
  3153. // There is no legacy data and no class-specific data
  3154. //
  3155. pCsData->CS_Header.CSD_SignatureLength = 0;
  3156. pCsData->CS_Header.CSD_LegacyDataOffset = 0;
  3157. pCsData->CS_Header.CSD_LegacyDataSize = 0;
  3158. pCsData->CS_Header.CSD_Signature[0] = 0x0;
  3159. memset(&pCsData->CS_Header.CSD_ClassGuid, 0, sizeof(GUID));
  3160. }
  3161. else if (pResDes->u.DeviceSpecificData.Reserved2 == 0) {
  3162. //
  3163. // There is only legacy data
  3164. //
  3165. pCsData->CS_Header.CSD_SignatureLength = 0;
  3166. pCsData->CS_Header.CSD_LegacyDataOffset = 0;
  3167. pCsData->CS_Header.CSD_LegacyDataSize =
  3168. pResDes->u.DeviceSpecificData.DataSize;
  3169. pCsData->CS_Header.CSD_Signature[0] = 0x0;
  3170. memset(&pCsData->CS_Header.CSD_ClassGuid, 0, sizeof(GUID));
  3171. ptr1 = (LPBYTE)((LPBYTE)pResDes + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  3172. memcpy(&pCsData->CS_Header.CSD_Signature, ptr1,
  3173. pResDes->u.DeviceSpecificData.DataSize);
  3174. }
  3175. else if (pResDes->u.DeviceSpecificData.Reserved1 == 0) {
  3176. //
  3177. // There is only class-specific data
  3178. //
  3179. pCsData->CS_Header.CSD_LegacyDataOffset = 0;
  3180. pCsData->CS_Header.CSD_LegacyDataSize = 0;
  3181. pCsData->CS_Header.CSD_SignatureLength =
  3182. pResDes->u.DeviceSpecificData.Reserved2;
  3183. ptr1 = (LPBYTE)((LPBYTE)pResDes + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  3184. memcpy(pCsData->CS_Header.CSD_Signature, ptr1,
  3185. pResDes->u.DeviceSpecificData.Reserved2);
  3186. ptr1 += pResDes->u.DeviceSpecificData.Reserved2;
  3187. memcpy((LPBYTE)&pCsData->CS_Header.CSD_ClassGuid, ptr1, sizeof(GUID));
  3188. }
  3189. else {
  3190. //
  3191. // There is both legacy data and class-specific data
  3192. //
  3193. //
  3194. // copy legacy data
  3195. //
  3196. pCsData->CS_Header.CSD_LegacyDataOffset =
  3197. pResDes->u.DeviceSpecificData.Reserved2;
  3198. pCsData->CS_Header.CSD_LegacyDataSize =
  3199. pResDes->u.DeviceSpecificData.Reserved1;
  3200. ptr1 = pCsData->CS_Header.CSD_Signature +
  3201. pCsData->CS_Header.CSD_LegacyDataOffset;
  3202. ptr2 = (LPBYTE)((LPBYTE)pResDes + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  3203. memcpy(ptr1, ptr2, pResDes->u.DeviceSpecificData.Reserved1);
  3204. //
  3205. // copy signature and class guid
  3206. //
  3207. pCsData->CS_Header.CSD_SignatureLength =
  3208. pResDes->u.DeviceSpecificData.Reserved2;
  3209. ptr2 += pResDes->u.DeviceSpecificData.Reserved1;
  3210. memcpy(pCsData->CS_Header.CSD_Signature, ptr2,
  3211. pResDes->u.DeviceSpecificData.Reserved2);
  3212. ptr2 += pResDes->u.DeviceSpecificData.Reserved2;
  3213. memcpy((LPBYTE)&pCsData->CS_Header.CSD_ClassGuid, ptr2, sizeof(GUID));
  3214. }
  3215. break;
  3216. }
  3217. default:
  3218. break;
  3219. }
  3220. Clean0:
  3221. return Status;
  3222. } // NtResourceToResDes
  3223. CONFIGRET
  3224. NtRequirementsToResDes(
  3225. IN PIO_RESOURCE_DESCRIPTOR pReqDes,
  3226. IN OUT LPBYTE Buffer,
  3227. IN ULONG BufferLen,
  3228. IN LPBYTE pLastAddr,
  3229. IN ULONG ulFlags
  3230. )
  3231. {
  3232. CONFIGRET Status = CR_SUCCESS;
  3233. ULONG count = 0, i = 0, ReqPartialCount = 0;
  3234. PIO_RESOURCE_DESCRIPTOR pCurrent = NULL;
  3235. //
  3236. // fill in resource type specific info
  3237. //
  3238. switch (pReqDes->Type) {
  3239. case CmResourceTypeMemory: {
  3240. //-------------------------------------------------------
  3241. // Memory Resource Type
  3242. //-------------------------------------------------------
  3243. //
  3244. // NOTE: pMemData->MEM_Header.MD_Reserved is not mapped
  3245. // pMemData->MEM_Data.MR_Reserved is not mapped
  3246. //
  3247. PMEM_RESOURCE pMemData = (PMEM_RESOURCE)Buffer;
  3248. //
  3249. // verify passed in buffer size
  3250. //
  3251. ReqPartialCount = RANGE_COUNT(pReqDes, pLastAddr);
  3252. if (BufferLen < sizeof(MEM_RESOURCE) +
  3253. sizeof(MEM_RANGE) * (ReqPartialCount - 1)) {
  3254. Status = CR_BUFFER_SMALL;
  3255. goto Clean0;
  3256. }
  3257. //
  3258. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to MEM_DES format
  3259. //
  3260. pMemData->MEM_Header.MD_Count = ReqPartialCount;
  3261. pMemData->MEM_Header.MD_Type = MType_Range;
  3262. pMemData->MEM_Header.MD_Flags = 0;
  3263. pMemData->MEM_Header.MD_Reserved = 0;
  3264. pMemData->MEM_Header.MD_Alloc_Base = 0;
  3265. pMemData->MEM_Header.MD_Alloc_End = 0;
  3266. //
  3267. // copy IO_RESOURCE_DESCRIPTOR info to MEM_RANGE format
  3268. //
  3269. for (count = 0, i = 0, pCurrent = pReqDes;
  3270. count < ReqPartialCount;
  3271. count++, pCurrent++) {
  3272. if (pCurrent->Type == CmResourceTypeMemory) {
  3273. pMemData->MEM_Data[i].MR_Align = MapFromNtAlignment(pCurrent->u.Memory.Alignment);
  3274. pMemData->MEM_Data[i].MR_nBytes = pCurrent->u.Memory.Length;
  3275. pMemData->MEM_Data[i].MR_Min = MAKEDWORDLONG(
  3276. pCurrent->u.Memory.MinimumAddress.LowPart,
  3277. pCurrent->u.Memory.MinimumAddress.HighPart);
  3278. pMemData->MEM_Data[i].MR_Max = MAKEDWORDLONG(
  3279. pCurrent->u.Memory.MaximumAddress.LowPart,
  3280. pCurrent->u.Memory.MaximumAddress.HighPart);
  3281. pMemData->MEM_Data[i].MR_Flags = MapFromNtMemoryFlags(pCurrent->Flags);
  3282. //pMemData->MEM_Data[i].MR_Flags |= MapFromNtDisposition(pCurrent->ShareDisposition, 0);
  3283. pMemData->MEM_Data[i].MR_Reserved = 0;
  3284. i++;
  3285. }
  3286. }
  3287. pMemData->MEM_Header.MD_Count = i;
  3288. break;
  3289. }
  3290. case CmResourceTypePort: {
  3291. //-------------------------------------------------------
  3292. // IO Port Resource Type
  3293. //-------------------------------------------------------
  3294. PIO_RESOURCE pIoData = (PIO_RESOURCE)Buffer;
  3295. //
  3296. // verify passed in buffer size
  3297. //
  3298. ReqPartialCount = RANGE_COUNT(pReqDes, pLastAddr);
  3299. if (BufferLen < sizeof(IO_RESOURCE) +
  3300. sizeof(IO_RANGE) * (ReqPartialCount - 1)) {
  3301. Status = CR_BUFFER_SMALL;
  3302. goto Clean0;
  3303. }
  3304. //
  3305. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to IO_DES format
  3306. //
  3307. pIoData->IO_Header.IOD_Count = ReqPartialCount;
  3308. pIoData->IO_Header.IOD_Type = IOType_Range;
  3309. pIoData->IO_Header.IOD_Alloc_Base = 0;
  3310. pIoData->IO_Header.IOD_Alloc_End = 0;
  3311. pIoData->IO_Header.IOD_DesFlags = 0;
  3312. //
  3313. // copy IO_RESOURCE_DESCRIPTOR info to IO_RANGE format
  3314. //
  3315. for (count = 0, i = 0, pCurrent = pReqDes;
  3316. count < ReqPartialCount;
  3317. count++, pCurrent++) {
  3318. if (pCurrent->Type == CmResourceTypePort) {
  3319. pIoData->IO_Data[i].IOR_Align = MapFromNtAlignment(pCurrent->u.Port.Alignment);
  3320. pIoData->IO_Data[i].IOR_nPorts = pCurrent->u.Port.Length;
  3321. pIoData->IO_Data[i].IOR_Min = MAKEDWORDLONG(
  3322. pCurrent->u.Port.MinimumAddress.LowPart,
  3323. pCurrent->u.Port.MinimumAddress.HighPart);
  3324. pIoData->IO_Data[i].IOR_Max = MAKEDWORDLONG(
  3325. pCurrent->u.Port.MaximumAddress.LowPart,
  3326. pCurrent->u.Port.MaximumAddress.HighPart);
  3327. pIoData->IO_Data[i].IOR_RangeFlags = MapFromNtPortFlags(pCurrent->Flags);
  3328. //pIoData->IO_Data[i].IOR_RangeFlags |= MapFromNtDisposition(pCurrent->ShareDisposition, 0);
  3329. pIoData->IO_Data[i].IOR_Alias = MapAliasFromNtPortFlags(pCurrent->Flags);
  3330. i++;
  3331. }
  3332. }
  3333. pIoData->IO_Header.IOD_Count = i;
  3334. break;
  3335. }
  3336. case CmResourceTypeDma: {
  3337. //-------------------------------------------------------
  3338. // DMA Resource Type
  3339. //-------------------------------------------------------
  3340. //
  3341. // Note: u.Dma.Port is not mapped
  3342. // u.Dma.Reserved is not mapped
  3343. //
  3344. PDMA_RESOURCE pDmaData = (PDMA_RESOURCE)Buffer;
  3345. //
  3346. // verify passed in buffer size
  3347. //
  3348. ReqPartialCount = RANGE_COUNT(pReqDes, pLastAddr);
  3349. if (BufferLen < sizeof(DMA_RESOURCE) +
  3350. sizeof(DMA_RANGE) * (ReqPartialCount - 1)) {
  3351. Status = CR_BUFFER_SMALL;
  3352. goto Clean0;
  3353. }
  3354. //
  3355. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to DMA_DES format
  3356. //
  3357. pDmaData->DMA_Header.DD_Count = ReqPartialCount;
  3358. pDmaData->DMA_Header.DD_Type = DType_Range;
  3359. pDmaData->DMA_Header.DD_Flags = 0;
  3360. pDmaData->DMA_Header.DD_Alloc_Chan = 0;
  3361. //
  3362. // copy DMA_RANGE info to IO_RESOURCE_DESCRIPTOR format
  3363. //
  3364. for (count = 0, i = 0, pCurrent = pReqDes;
  3365. count < ReqPartialCount;
  3366. count++, pCurrent++) {
  3367. if (pCurrent->Type == CmResourceTypeDma) {
  3368. pDmaData->DMA_Data[i].DR_Min = pCurrent->u.Dma.MinimumChannel;
  3369. pDmaData->DMA_Data[i].DR_Max = pCurrent->u.Dma.MaximumChannel;
  3370. pDmaData->DMA_Data[i].DR_Flags = MapFromNtDmaFlags(pCurrent->Flags);
  3371. //pDmaData->DMA_Data[i].DR_Flags |= MapFromNtDisposition(pCurrent->ShareDisposition, 0);
  3372. i++;
  3373. }
  3374. }
  3375. pDmaData->DMA_Header.DD_Count = i;
  3376. break;
  3377. }
  3378. case CmResourceTypeInterrupt: {
  3379. //-------------------------------------------------------
  3380. // IRQ Resource Type
  3381. //-------------------------------------------------------
  3382. if (ulFlags & CM_RESDES_WIDTH_64) {
  3383. //
  3384. // CM_RESDES_WIDTH_64
  3385. //
  3386. PIRQ_RESOURCE_64 pIrqData = (PIRQ_RESOURCE_64)Buffer;
  3387. //
  3388. // verify passed in buffer size
  3389. //
  3390. ReqPartialCount = RANGE_COUNT(pReqDes, pLastAddr);
  3391. if (BufferLen < sizeof(IRQ_RESOURCE_64) +
  3392. sizeof(IRQ_RANGE) * (ReqPartialCount - 1)) {
  3393. Status = CR_BUFFER_SMALL;
  3394. goto Clean0;
  3395. }
  3396. //
  3397. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to IRQ_DES format
  3398. //
  3399. pIrqData->IRQ_Header.IRQD_Count = ReqPartialCount;
  3400. pIrqData->IRQ_Header.IRQD_Type = IRQType_Range;
  3401. pIrqData->IRQ_Header.IRQD_Flags = 0;
  3402. pIrqData->IRQ_Header.IRQD_Alloc_Num = 0;
  3403. pIrqData->IRQ_Header.IRQD_Affinity = 0;
  3404. //
  3405. // copy IO_RANGE info to IO_RESOURCE_DESCRIPTOR format
  3406. //
  3407. for (count = 0, i = 0, pCurrent = pReqDes;
  3408. count < ReqPartialCount;
  3409. count++, pCurrent++) {
  3410. if (pCurrent->Type == CmResourceTypeInterrupt) {
  3411. pIrqData->IRQ_Data[i].IRQR_Min = pCurrent->u.Interrupt.MinimumVector;
  3412. pIrqData->IRQ_Data[i].IRQR_Max = pCurrent->u.Interrupt.MaximumVector;
  3413. pIrqData->IRQ_Data[i].IRQR_Flags = MapFromNtIrqFlags(pCurrent->Flags) |
  3414. MapFromNtIrqShare(pCurrent->ShareDisposition);
  3415. //pIrqData->IRQ_Data[i].IRQR_Flags |= MapFromNtDisposition(pCurrent->ShareDisposition, 1);
  3416. i++;
  3417. }
  3418. }
  3419. pIrqData->IRQ_Header.IRQD_Count = i;
  3420. } else {
  3421. //
  3422. // CM_RESDES_WIDTH_32
  3423. //
  3424. PIRQ_RESOURCE_32 pIrqData = (PIRQ_RESOURCE_32)Buffer;
  3425. //
  3426. // verify passed in buffer size
  3427. //
  3428. ReqPartialCount = RANGE_COUNT(pReqDes, pLastAddr);
  3429. if (BufferLen < sizeof(IRQ_RESOURCE_32) +
  3430. sizeof(IRQ_RANGE) * (ReqPartialCount - 1)) {
  3431. Status = CR_BUFFER_SMALL;
  3432. goto Clean0;
  3433. }
  3434. //
  3435. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to IRQ_DES format
  3436. //
  3437. pIrqData->IRQ_Header.IRQD_Count = ReqPartialCount;
  3438. pIrqData->IRQ_Header.IRQD_Type = IRQType_Range;
  3439. pIrqData->IRQ_Header.IRQD_Flags = 0;
  3440. pIrqData->IRQ_Header.IRQD_Alloc_Num = 0;
  3441. pIrqData->IRQ_Header.IRQD_Affinity = 0;
  3442. //
  3443. // copy IO_RANGE info to IO_RESOURCE_DESCRIPTOR format
  3444. //
  3445. for (count = 0, i = 0, pCurrent = pReqDes;
  3446. count < ReqPartialCount;
  3447. count++, pCurrent++) {
  3448. if (pCurrent->Type == CmResourceTypeInterrupt) {
  3449. pIrqData->IRQ_Data[i].IRQR_Min = pCurrent->u.Interrupt.MinimumVector;
  3450. pIrqData->IRQ_Data[i].IRQR_Max = pCurrent->u.Interrupt.MaximumVector;
  3451. pIrqData->IRQ_Data[i].IRQR_Flags = MapFromNtIrqFlags(pCurrent->Flags) |
  3452. MapFromNtIrqShare(pCurrent->ShareDisposition);
  3453. //pIrqData->IRQ_Data[i].IRQR_Flags |= MapFromNtDisposition(pCurrent->ShareDisposition, 1);
  3454. i++;
  3455. }
  3456. }
  3457. pIrqData->IRQ_Header.IRQD_Count = i;
  3458. }
  3459. break;
  3460. }
  3461. case CmResourceTypeDevicePrivate: {
  3462. //-------------------------------------------------------
  3463. // Device Private Resource Type
  3464. //-------------------------------------------------------
  3465. PDEVPRIVATE_RESOURCE pPrvData = (PDEVPRIVATE_RESOURCE)Buffer;
  3466. //
  3467. // verify passed in buffer size
  3468. //
  3469. ReqPartialCount = RANGE_COUNT(pReqDes, pLastAddr);
  3470. if (BufferLen < sizeof(DEVPRIVATE_RESOURCE) +
  3471. sizeof(DEVPRIVATE_RANGE) * (ReqPartialCount - 1)) {
  3472. Status = CR_BUFFER_SMALL;
  3473. goto Clean0;
  3474. }
  3475. //
  3476. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to MEM_DES format
  3477. //
  3478. pPrvData->PRV_Header.PD_Count = ReqPartialCount;
  3479. pPrvData->PRV_Header.PD_Type = PType_Range;
  3480. pPrvData->PRV_Header.PD_Data1 = 0;
  3481. pPrvData->PRV_Header.PD_Data2 = 0;
  3482. pPrvData->PRV_Header.PD_Data3 = 0;
  3483. pPrvData->PRV_Header.PD_Flags = 0;
  3484. //
  3485. // copy IO_RESOURCE_DESCRIPTOR info to MEM_RANGE format
  3486. //
  3487. for (i = 0, pCurrent = pReqDes;
  3488. i < ReqPartialCount;
  3489. i++, pCurrent++) {
  3490. pPrvData->PRV_Data[i].PR_Data1 = pCurrent->u.DevicePrivate.Data[0];
  3491. pPrvData->PRV_Data[i].PR_Data2 = pCurrent->u.DevicePrivate.Data[1];
  3492. pPrvData->PRV_Data[i].PR_Data3 = pCurrent->u.DevicePrivate.Data[2];
  3493. }
  3494. break;
  3495. }
  3496. case CmResourceTypeBusNumber: {
  3497. //-------------------------------------------------------
  3498. // Bus Number Resource Type
  3499. //-------------------------------------------------------
  3500. PBUSNUMBER_RESOURCE pBusData = (PBUSNUMBER_RESOURCE)Buffer;
  3501. //
  3502. // verify passed in buffer size
  3503. //
  3504. ReqPartialCount = RANGE_COUNT(pReqDes, pLastAddr);
  3505. if (BufferLen < sizeof(BUSNUMBER_RESOURCE) +
  3506. sizeof(BUSNUMBER_RANGE) * (ReqPartialCount - 1)) {
  3507. Status = CR_BUFFER_SMALL;
  3508. goto Clean0;
  3509. }
  3510. //
  3511. // copy CM_PARTIAL_RESOURCE_DESCRIPTOR info to BUSNUMBER_DES format
  3512. //
  3513. pBusData->BusNumber_Header.BUSD_Count = ReqPartialCount;
  3514. pBusData->BusNumber_Header.BUSD_Type = BusNumberType_Range;
  3515. pBusData->BusNumber_Header.BUSD_Flags = 0;
  3516. pBusData->BusNumber_Header.BUSD_Alloc_Base = 0;
  3517. pBusData->BusNumber_Header.BUSD_Alloc_End = 0;
  3518. //
  3519. // copy IO_RESOURCE_DESCRIPTOR info to MEM_RANGE format
  3520. //
  3521. for (i = 0, pCurrent = pReqDes;
  3522. i < ReqPartialCount;
  3523. i++, pCurrent++) {
  3524. pBusData->BusNumber_Data[i].BUSR_Min = pCurrent->u.BusNumber.MinBusNumber;
  3525. pBusData->BusNumber_Data[i].BUSR_Max = pCurrent->u.BusNumber.MaxBusNumber;
  3526. pBusData->BusNumber_Data[i].BUSR_nBusNumbers = pCurrent->u.BusNumber.Length;
  3527. pBusData->BusNumber_Data[i].BUSR_Flags = pCurrent->Flags;
  3528. }
  3529. break;
  3530. }
  3531. case CmResourceTypePcCardConfig: {
  3532. //-------------------------------------------------------
  3533. // PcCardConfig Resource Type
  3534. //-------------------------------------------------------
  3535. PPCCARD_RESOURCE pPcData = (PPCCARD_RESOURCE)Buffer;
  3536. //
  3537. // verify passed in buffer size
  3538. //
  3539. ReqPartialCount = RANGE_COUNT(pReqDes, pLastAddr);
  3540. if (BufferLen < sizeof(PCCARD_RESOURCE)) {
  3541. Status = CR_BUFFER_SMALL;
  3542. goto Clean0;
  3543. }
  3544. //
  3545. // copy IO_RESOURCE_DESCRIPTOR info to PCCARD_DES format
  3546. //
  3547. pPcData->PcCard_Header.PCD_Reserved[0] = 0;
  3548. pPcData->PcCard_Header.PCD_Reserved[1] = 0;
  3549. pPcData->PcCard_Header.PCD_Reserved[2] = 0;
  3550. pPcData->PcCard_Header.PCD_ConfigIndex = PCMRES_GET_CONFIG_INDEX(pReqDes);
  3551. pPcData->PcCard_Header.PCD_MemoryCardBase1 = PCMRES_GET_MEMORY_CARDBASE(pReqDes, 0);
  3552. pPcData->PcCard_Header.PCD_MemoryCardBase2 = PCMRES_GET_MEMORY_CARDBASE(pReqDes, 1);
  3553. if (PCMRES_GET_IO_FLAG(pReqDes, 0, PCMRESF_IO_16BIT_ACCESS)) {
  3554. pPcData->PcCard_Header.PCD_Flags = fPCD_IO_16;
  3555. } else {
  3556. pPcData->PcCard_Header.PCD_Flags = fPCD_IO_8;
  3557. }
  3558. if (PCMRES_GET_MEMORY_FLAG(pReqDes, 0, PCMRESF_MEM_16BIT_ACCESS)) {
  3559. pPcData->PcCard_Header.PCD_Flags |= fPCD_MEM_16;
  3560. } else {
  3561. pPcData->PcCard_Header.PCD_Flags |= fPCD_MEM_8;
  3562. }
  3563. break;
  3564. }
  3565. default:
  3566. break;
  3567. }
  3568. Clean0:
  3569. return Status;
  3570. } // NtRequirementsToResDes
  3571. //-------------------------------------------------------------------
  3572. // Routines to map flags between ConfigMgr and NT types
  3573. //-------------------------------------------------------------------
  3574. USHORT MapToNtMemoryFlags(IN DWORD CmMemoryFlags)
  3575. {
  3576. USHORT NtMemoryFlags = 0x0;
  3577. if (((CmMemoryFlags & mMD_MemoryType) == fMD_ROM) &&
  3578. ((CmMemoryFlags & mMD_Readable) == fMD_ReadAllowed)) {
  3579. NtMemoryFlags |= CM_RESOURCE_MEMORY_READ_ONLY;
  3580. }
  3581. else if (((CmMemoryFlags & mMD_MemoryType) == fMD_RAM) &&
  3582. ((CmMemoryFlags & mMD_Readable) == fMD_ReadDisallowed)) {
  3583. NtMemoryFlags |= CM_RESOURCE_MEMORY_WRITE_ONLY;
  3584. }
  3585. else {
  3586. NtMemoryFlags |= CM_RESOURCE_MEMORY_READ_WRITE;
  3587. }
  3588. if ((CmMemoryFlags & mMD_32_24) == fMD_24) {
  3589. NtMemoryFlags |= CM_RESOURCE_MEMORY_24;
  3590. }
  3591. if ((CmMemoryFlags & mMD_Prefetchable) == fMD_PrefetchAllowed) {
  3592. NtMemoryFlags |= CM_RESOURCE_MEMORY_PREFETCHABLE;
  3593. }
  3594. if ((CmMemoryFlags & mMD_CombinedWrite) == fMD_CombinedWriteAllowed) {
  3595. NtMemoryFlags |= CM_RESOURCE_MEMORY_COMBINEDWRITE;
  3596. }
  3597. if ((CmMemoryFlags & mMD_Cacheable) == fMD_Cacheable) {
  3598. NtMemoryFlags |= CM_RESOURCE_MEMORY_CACHEABLE;
  3599. }
  3600. return NtMemoryFlags;
  3601. }
  3602. DWORD MapFromNtMemoryFlags(IN USHORT NtMemoryFlags)
  3603. {
  3604. DWORD CmMemoryFlags = 0x0;
  3605. if (NtMemoryFlags & CM_RESOURCE_MEMORY_READ_ONLY) {
  3606. CmMemoryFlags |= (fMD_ReadAllowed | fMD_ROM);
  3607. }
  3608. else if (NtMemoryFlags & CM_RESOURCE_MEMORY_WRITE_ONLY) {
  3609. CmMemoryFlags |= (fMD_ReadDisallowed | fMD_RAM);
  3610. }
  3611. else {
  3612. CmMemoryFlags |= (fMD_ReadAllowed | fMD_RAM);
  3613. }
  3614. if (NtMemoryFlags & CM_RESOURCE_MEMORY_PREFETCHABLE) {
  3615. CmMemoryFlags |= fMD_PrefetchAllowed;
  3616. }
  3617. if (NtMemoryFlags & CM_RESOURCE_MEMORY_COMBINEDWRITE) {
  3618. CmMemoryFlags |= fMD_CombinedWriteAllowed;
  3619. }
  3620. if (NtMemoryFlags & CM_RESOURCE_MEMORY_CACHEABLE) {
  3621. CmMemoryFlags |= fMD_Cacheable;
  3622. }
  3623. if (!(NtMemoryFlags & CM_RESOURCE_MEMORY_24)) {
  3624. CmMemoryFlags |= fMD_32;
  3625. }
  3626. return CmMemoryFlags;
  3627. }
  3628. USHORT MapToNtPortFlags(IN DWORD CmPortFlags, IN DWORD CmAlias)
  3629. {
  3630. USHORT NtFlags = 0;
  3631. if ((CmPortFlags & fIOD_PortType) == fIOD_Memory) {
  3632. NtFlags |= CM_RESOURCE_PORT_MEMORY;
  3633. } else {
  3634. NtFlags |= CM_RESOURCE_PORT_IO;
  3635. }
  3636. //
  3637. // CmAlias uses the following rule:
  3638. //
  3639. // Positive Decode = 0xFF
  3640. // 10-bit decode = 0x0004 (2 ^ 2)
  3641. // 12-bit decode = 0x0010 (2 ^ 4)
  3642. // 16-bit decode = 0x0000 (2 ^ 8 = 0x0100, but since it's a byte, use 0)
  3643. //
  3644. // if CmAlias is zero, use flags to specify decode (new method)
  3645. //
  3646. if (CmAlias == 0) {
  3647. //
  3648. // use CM_RESOURCE_PORT_xxx related flags
  3649. //
  3650. // note that we need to mirror *ALL* flags from
  3651. // CM_RESOURCE_PORT_xxxx to fIOD_xxxx
  3652. // however bits need not be same
  3653. // not doing this will cause at least resource conflicts to fail
  3654. // see also MapFromNtPortFlags
  3655. //
  3656. if (CmPortFlags & fIOD_10_BIT_DECODE) {
  3657. NtFlags |= CM_RESOURCE_PORT_10_BIT_DECODE;
  3658. }
  3659. if (CmPortFlags & fIOD_12_BIT_DECODE) {
  3660. NtFlags |= CM_RESOURCE_PORT_12_BIT_DECODE;
  3661. }
  3662. if (CmPortFlags & fIOD_16_BIT_DECODE) {
  3663. NtFlags |= CM_RESOURCE_PORT_16_BIT_DECODE;
  3664. }
  3665. if (CmPortFlags & fIOD_POSITIVE_DECODE) {
  3666. NtFlags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
  3667. }
  3668. }
  3669. else if (CmAlias == IO_ALIAS_POSITIVE_DECODE) {
  3670. NtFlags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
  3671. } else if (CmAlias == IO_ALIAS_10_BIT_DECODE) {
  3672. NtFlags |= CM_RESOURCE_PORT_10_BIT_DECODE;
  3673. } else if (CmAlias == IO_ALIAS_12_BIT_DECODE) {
  3674. NtFlags |= CM_RESOURCE_PORT_12_BIT_DECODE;
  3675. } else if (CmAlias == IO_ALIAS_16_BIT_DECODE) {
  3676. NtFlags |= CM_RESOURCE_PORT_16_BIT_DECODE;
  3677. }
  3678. //
  3679. // these have no mirror in cmAlias, and can be combined
  3680. //
  3681. if (CmPortFlags & fIOD_PASSIVE_DECODE) {
  3682. NtFlags |= CM_RESOURCE_PORT_PASSIVE_DECODE;
  3683. }
  3684. if (CmPortFlags & fIOD_WINDOW_DECODE) {
  3685. NtFlags |= CM_RESOURCE_PORT_WINDOW_DECODE;
  3686. }
  3687. return NtFlags;
  3688. }
  3689. DWORD MapFromNtPortFlags(IN USHORT NtPortFlags)
  3690. {
  3691. DWORD Flags = 0;
  3692. if ((NtPortFlags & (CM_RESOURCE_PORT_MEMORY|CM_RESOURCE_PORT_IO)) == CM_RESOURCE_PORT_MEMORY) {
  3693. Flags |=fIOD_Memory;
  3694. } else {
  3695. Flags |=fIOD_IO;
  3696. }
  3697. //
  3698. // note that we need to mirror *ALL* flags from
  3699. // CM_RESOURCE_PORT_xxxx to fIOD_xxxx
  3700. // however bits need not be same
  3701. // not doing this will cause at least resource conflicts to fail
  3702. // see also MapToNtPortFlags
  3703. //
  3704. if (NtPortFlags & CM_RESOURCE_PORT_10_BIT_DECODE) {
  3705. Flags |= fIOD_10_BIT_DECODE;
  3706. }
  3707. if (NtPortFlags & CM_RESOURCE_PORT_12_BIT_DECODE) {
  3708. Flags |= fIOD_12_BIT_DECODE;
  3709. }
  3710. if (NtPortFlags & CM_RESOURCE_PORT_16_BIT_DECODE) {
  3711. Flags |= fIOD_16_BIT_DECODE;
  3712. }
  3713. if (NtPortFlags & CM_RESOURCE_PORT_POSITIVE_DECODE) {
  3714. Flags |= fIOD_POSITIVE_DECODE;
  3715. }
  3716. if (NtPortFlags & CM_RESOURCE_PORT_PASSIVE_DECODE) {
  3717. Flags |= fIOD_PASSIVE_DECODE;
  3718. }
  3719. if (NtPortFlags & CM_RESOURCE_PORT_WINDOW_DECODE) {
  3720. Flags |= fIOD_WINDOW_DECODE;
  3721. }
  3722. return Flags;
  3723. }
  3724. DWORD MapAliasFromNtPortFlags(IN USHORT NtPortFlags)
  3725. {
  3726. DWORD Alias = 0;
  3727. if (NtPortFlags & CM_RESOURCE_PORT_10_BIT_DECODE) {
  3728. Alias = IO_ALIAS_10_BIT_DECODE;
  3729. } else if (NtPortFlags & CM_RESOURCE_PORT_12_BIT_DECODE) {
  3730. Alias = IO_ALIAS_12_BIT_DECODE;
  3731. } else if (NtPortFlags & CM_RESOURCE_PORT_16_BIT_DECODE) {
  3732. Alias = IO_ALIAS_16_BIT_DECODE;
  3733. } else if (NtPortFlags & CM_RESOURCE_PORT_POSITIVE_DECODE) {
  3734. Alias = IO_ALIAS_POSITIVE_DECODE;
  3735. }
  3736. return Alias;
  3737. }
  3738. ULONG MapToNtAlignment(IN DWORDLONG CmPortAlign)
  3739. {
  3740. return (ULONG)(~CmPortAlign + 1);
  3741. }
  3742. DWORDLONG MapFromNtAlignment(IN ULONG NtPortAlign)
  3743. {
  3744. return (DWORDLONG)(~((DWORDLONG)NtPortAlign - 1));
  3745. }
  3746. USHORT MapToNtDmaFlags(IN DWORD CmDmaFlags)
  3747. {
  3748. USHORT NtDmaFlags;
  3749. if ((CmDmaFlags & mDD_Width) == fDD_DWORD) {
  3750. NtDmaFlags = CM_RESOURCE_DMA_32;
  3751. } else if ((CmDmaFlags & mDD_Width) == fDD_WORD) {
  3752. NtDmaFlags = CM_RESOURCE_DMA_16;
  3753. } else if ((CmDmaFlags & mDD_Width) == fDD_BYTE_AND_WORD) {
  3754. NtDmaFlags = CM_RESOURCE_DMA_8_AND_16;
  3755. } else {
  3756. NtDmaFlags = CM_RESOURCE_DMA_8; //default
  3757. }
  3758. if ((CmDmaFlags & mDD_BusMaster) == fDD_BusMaster) {
  3759. NtDmaFlags |= CM_RESOURCE_DMA_BUS_MASTER;
  3760. }
  3761. if ((CmDmaFlags & mDD_Type) == fDD_TypeA) {
  3762. NtDmaFlags |= CM_RESOURCE_DMA_TYPE_A;
  3763. } else if ((CmDmaFlags & mDD_Type) == fDD_TypeB) {
  3764. NtDmaFlags |= CM_RESOURCE_DMA_TYPE_B;
  3765. } else if ((CmDmaFlags & mDD_Type) == fDD_TypeF) {
  3766. NtDmaFlags |= CM_RESOURCE_DMA_TYPE_F;
  3767. }
  3768. return NtDmaFlags;
  3769. }
  3770. DWORD MapFromNtDmaFlags(IN USHORT NtDmaFlags)
  3771. {
  3772. DWORD CmDmaFlags;
  3773. if (NtDmaFlags & CM_RESOURCE_DMA_32) {
  3774. CmDmaFlags = fDD_DWORD;
  3775. } else if (NtDmaFlags & CM_RESOURCE_DMA_8_AND_16) {
  3776. CmDmaFlags = fDD_BYTE_AND_WORD;
  3777. } else if (NtDmaFlags & CM_RESOURCE_DMA_16) {
  3778. CmDmaFlags = fDD_WORD;
  3779. } else {
  3780. CmDmaFlags = fDD_BYTE;
  3781. }
  3782. if (NtDmaFlags & CM_RESOURCE_DMA_BUS_MASTER) {
  3783. CmDmaFlags |= fDD_BusMaster;
  3784. }
  3785. if (NtDmaFlags & CM_RESOURCE_DMA_TYPE_A) {
  3786. CmDmaFlags |= fDD_TypeA;
  3787. } else if (NtDmaFlags & CM_RESOURCE_DMA_TYPE_B) {
  3788. CmDmaFlags |= fDD_TypeB;
  3789. } else if (NtDmaFlags & CM_RESOURCE_DMA_TYPE_F) {
  3790. CmDmaFlags |= fDD_TypeF;
  3791. }
  3792. return CmDmaFlags;
  3793. }
  3794. USHORT MapToNtIrqFlags(IN DWORD CmIrqFlags)
  3795. {
  3796. if ((CmIrqFlags & mIRQD_Edge_Level) == fIRQD_Level) {
  3797. return CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
  3798. } else {
  3799. return CM_RESOURCE_INTERRUPT_LATCHED;
  3800. }
  3801. }
  3802. DWORD MapFromNtIrqFlags(IN USHORT NtIrqFlags)
  3803. {
  3804. if (NtIrqFlags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE) {
  3805. return fIRQD_Level;
  3806. } else {
  3807. return fIRQD_Edge;
  3808. }
  3809. }
  3810. #if 0
  3811. UCHAR MapToNtDisposition(IN DWORD CmFlags, IN BOOL bIrq)
  3812. {
  3813. UCHAR disposition;
  3814. DWORD flag = CmFlags & mD_ShareDisposition;
  3815. if (flag == fD_ShareDeviceExclusive) {
  3816. disposition = CmResourceShareDeviceExclusive;
  3817. } else if (flag == fD_ShareDriverExclusive) {
  3818. disposition = CmResourceShareDriverExclusive;
  3819. } else if (flag == fD_ShareShared) {
  3820. disposition = CmResourceShareShared;
  3821. } else if (flag == fD_ShareUndetermined) {
  3822. //
  3823. // if undetermined, also check for the old irq specific
  3824. // share flags
  3825. //
  3826. if ((CmFlags & mIRQD_Share) == fIRQD_Share) {
  3827. disposition = CmResourceShareShared;
  3828. } else {
  3829. disposition = CmResourceShareUndetermined;
  3830. }
  3831. }
  3832. return disposition;
  3833. }
  3834. DWORD MapFromNtDisposition(IN UCHAR NtDisposition, IN BOOL bIrq)
  3835. {
  3836. DWORD flag = 0;
  3837. if (NtDisposition == CmResourceShareUndetermined) {
  3838. flag = fD_ShareUndetermined;
  3839. } else if (NtDisposition == CmResourceShareDeviceExclusive) {
  3840. flag = fD_ShareDeviceExclusive;
  3841. } else if (NtDisposition == CmResourceShareDriverExclusive) {
  3842. flag = fD_ShareDriverExclusive;
  3843. } else if (NtDisposition == CmResourceShareShared) {
  3844. flag = fD_ShareShared;
  3845. }
  3846. if (bIrq) {
  3847. //
  3848. // also set the irq specific shared/exclusive bit, this is for
  3849. // backwards compatibility, new apps should look at the new bits.
  3850. //
  3851. if (flag == fD_ShareShared) {
  3852. flag |= fIRQD_Share;
  3853. } else {
  3854. flag |= fIRQD_Exclusive;
  3855. }
  3856. }
  3857. return flag;
  3858. }
  3859. #endif
  3860. UCHAR MapToNtIrqShare(IN DWORD CmIrqFlags)
  3861. {
  3862. if ((CmIrqFlags & mIRQD_Share) == fIRQD_Exclusive) {
  3863. return CmResourceShareDeviceExclusive;
  3864. } else {
  3865. return CmResourceShareShared;
  3866. }
  3867. }
  3868. DWORD MapFromNtIrqShare(IN UCHAR NtIrqShare)
  3869. {
  3870. if (NtIrqShare == CmResourceShareDeviceExclusive) {
  3871. return fIRQD_Exclusive;
  3872. }
  3873. else if (NtIrqShare == CmResourceShareDriverExclusive) {
  3874. return fIRQD_Exclusive;
  3875. }
  3876. else return fIRQD_Share;
  3877. }
  3878. #define CM_RESOURCE_BUSNUMBER_SUBALLOCATE_FIRST_VALUE 0x0001
  3879. #define mBUSD_SubAllocFirst (0x1) // Bitmask, whether SubAlloc first value allowed
  3880. #define fBUSD_SubAllocFirst_Allowed (0x0) // Suballoc from first value
  3881. #define fBUSD_SubAllocFirst_Disallowed (0x1) // Don't suballoc from first value