Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

924 lines
26 KiB

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. rhwprof.c
  5. Abstract:
  6. This module contains the server-side hardware profile APIs.
  7. PNP_IsDockStationPresent
  8. PNP_RequestEjectPC
  9. PNP_HwProfFlags
  10. PNP_GetHwProfInfo
  11. PNP_SetHwProf
  12. Author:
  13. Paula Tomlinson (paulat) 7-18-1995
  14. Environment:
  15. User-mode only.
  16. Revision History:
  17. 18-July-1995 paulat
  18. Creation and initial implementation.
  19. --*/
  20. //
  21. // includes
  22. //
  23. #include "precomp.h"
  24. #include "umpnpi.h"
  25. #include "umpnpdat.h"
  26. #include <profiles.h>
  27. //
  28. // private prototypes
  29. //
  30. BOOL
  31. IsCurrentProfile(
  32. ULONG ulProfile
  33. );
  34. CONFIGRET
  35. PNP_IsDockStationPresent(
  36. IN handle_t hBinding,
  37. OUT PBOOL Present
  38. )
  39. /*++
  40. Routine Description:
  41. This routine determines whether a docking station is currently present.
  42. Parameters:
  43. hBinding RPC binding handle, not used.
  44. Present Supplies the address of a boolean variable that is set
  45. upon successful return to indicate whether or not a
  46. docking station is currently present.
  47. Return Value:
  48. If the function succeeds, the return value is CR_SUCCESS.
  49. If the function fails, the return value is a CR failure code.
  50. --*/
  51. {
  52. CONFIGRET status = CR_SUCCESS;
  53. ULONG regStatus = ERROR_SUCCESS;
  54. HKEY hCurrentDockInfo = NULL, hIDConfigDB = NULL;
  55. DWORD dataType;
  56. ULONG dockingState;
  57. ULONG ejectableDocks;
  58. ULONG size;
  59. UNREFERENCED_PARAMETER(hBinding);
  60. try {
  61. //
  62. // Validate parameters.
  63. //
  64. if (!ARGUMENT_PRESENT(Present)) {
  65. status = CR_FAILURE;
  66. goto Clean0;
  67. }
  68. *Present = FALSE;
  69. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  70. pszRegPathIDConfigDB,
  71. 0,
  72. KEY_READ,
  73. &hIDConfigDB) != ERROR_SUCCESS) {
  74. status = CR_REGISTRY_ERROR;
  75. hIDConfigDB = NULL;
  76. goto Clean0;
  77. }
  78. if (RegOpenKeyEx(hIDConfigDB,
  79. pszRegKeyCurrentDockInfo,
  80. 0,
  81. KEY_READ,
  82. &hCurrentDockInfo) != ERROR_SUCCESS) {
  83. status = CR_REGISTRY_ERROR;
  84. hCurrentDockInfo = NULL;
  85. goto Clean0;
  86. }
  87. size = sizeof (dockingState);
  88. if ((RegQueryValueEx(hCurrentDockInfo,
  89. pszRegValueDockingState,
  90. 0,
  91. &dataType,
  92. (PUCHAR) &dockingState,
  93. &size) != ERROR_SUCCESS) ||
  94. (dataType != REG_DWORD) ||
  95. (size != sizeof (ULONG))) {
  96. status = CR_REGISTRY_ERROR;
  97. goto Clean0;
  98. }
  99. if ((dockingState & HW_PROFILE_DOCKSTATE_UNKNOWN) ==
  100. HW_PROFILE_DOCKSTATE_DOCKED) {
  101. size = sizeof(ejectableDocks);
  102. if ((RegQueryValueEx(hCurrentDockInfo,
  103. pszRegValueEjectableDocks,
  104. 0,
  105. &dataType,
  106. (PUCHAR) &ejectableDocks,
  107. &size) == ERROR_SUCCESS) &&
  108. (dataType == REG_DWORD) &&
  109. (size == sizeof(ULONG)) &&
  110. (ejectableDocks > 0)) {
  111. *Present = TRUE;
  112. }
  113. }
  114. Clean0:
  115. NOTHING;
  116. } except(EXCEPTION_EXECUTE_HANDLER) {
  117. status = CR_FAILURE;
  118. }
  119. if (hIDConfigDB) {
  120. RegCloseKey(hIDConfigDB);
  121. }
  122. if (hCurrentDockInfo) {
  123. RegCloseKey(hCurrentDockInfo);
  124. }
  125. return status;
  126. } // PNP_IsDockStationPresent
  127. CONFIGRET
  128. PNP_RequestEjectPC(
  129. IN handle_t hBinding
  130. )
  131. /*++
  132. Routine Description:
  133. This routine requests that the PC be ejected (i.e., undocked).
  134. Parameters:
  135. hBinding RPC binding handle.
  136. Return Value:
  137. If the function succeeds, the return value is CR_SUCCESS.
  138. If the function fails, the return value is a CR failure code.
  139. --*/
  140. {
  141. CONFIGRET Status = CR_SUCCESS;
  142. NTSTATUS ntStatus;
  143. WCHAR szDockDevInst[MAX_DEVICE_ID_LEN + 1];
  144. PLUGPLAY_CONTROL_RETRIEVE_DOCK_DATA dockData;
  145. try {
  146. dockData.DeviceInstance = szDockDevInst;
  147. dockData.DeviceInstanceLength = MAX_DEVICE_ID_LEN;
  148. ntStatus = NtPlugPlayControl(PlugPlayControlRetrieveDock,
  149. &dockData,
  150. sizeof(PLUGPLAY_CONTROL_RETRIEVE_DOCK_DATA));
  151. if (NT_SUCCESS(ntStatus)) {
  152. Status = PNP_RequestDeviceEject(hBinding,
  153. szDockDevInst,
  154. NULL, // pVetoType
  155. NULL, // pszVetoName
  156. 0, // ulNameLength
  157. 0); // ulFlags
  158. } else {
  159. Status = MapNtStatusToCmError(ntStatus);
  160. }
  161. } except(EXCEPTION_EXECUTE_HANDLER) {
  162. Status = CR_FAILURE;
  163. }
  164. return Status;
  165. } // PNP_RequestEjectPC
  166. CONFIGRET
  167. PNP_HwProfFlags(
  168. IN handle_t hBinding,
  169. IN ULONG ulAction,
  170. IN LPCWSTR pDeviceID,
  171. IN ULONG ulConfig,
  172. IN OUT PULONG pulValue,
  173. OUT PPNP_VETO_TYPE pVetoType,
  174. OUT LPWSTR pszVetoName,
  175. IN ULONG ulNameLength,
  176. IN ULONG ulFlags
  177. )
  178. /*++
  179. Routine Description:
  180. This is the RPC server entry point for the ConfigManager routines that
  181. get and set the hardware profile flags.
  182. Arguments:
  183. hBinding RPC binding handle.
  184. ulAction Specified whether to get or set the flag. Can be one
  185. of the PNP_*_HWPROFFLAGS values.
  186. pDeviceID Device instance to get/set the hw profile flag for.
  187. ulConfig Specifies which profile to get/set the flag for. A
  188. value of zero indicates to use the current profile.
  189. pulValue If setting the flag, then this value on entry contains
  190. the value to set the hardware profile flag to. If
  191. getting the flag, then this value will return the
  192. current hardware profile flag.
  193. pVetoType Buffer to receive the type of veto. If this is NULL
  194. then no veto information will be received and the OS wil
  195. display the veto information.
  196. pszVetoName Buffer to receive the veto information. If this is NULL
  197. then no veto information will be received and the OS will
  198. display the veto information.
  199. ulNameLength Size of the pszVetoName buffer.
  200. ulFlags Depends on the action being performed.
  201. For PNP_GET_HWPROFFLAGS, no flags are valid.
  202. For PNP_SET_HWPROFFLAGS, may be CM_SET_HW_PROF_FLAGS_BITS.
  203. Return Value:
  204. If the function succeeds it returns CR_SUCCESS. Otherwise it returns one
  205. of the CR_* values.
  206. --*/
  207. {
  208. CONFIGRET Status = CR_SUCCESS;
  209. ULONG RegStatus = ERROR_SUCCESS;
  210. WCHAR RegStr[MAX_CM_PATH];
  211. HKEY hKey = NULL, hDevKey = NULL;
  212. ULONG ulValueSize = sizeof(ULONG);
  213. ULONG ulCurrentValue, ulChange, ulDisposition;
  214. BOOL AffectsCurrentProfile;
  215. //
  216. // NOTE: The device is not checked for presense or not, this flag is
  217. // always just set or retrieved directly from the registry, as it is
  218. // done on Windows 95
  219. //
  220. try {
  221. //
  222. // validate parameters
  223. //
  224. if ((ulAction != PNP_GET_HWPROFFLAGS) &&
  225. (ulAction != PNP_SET_HWPROFFLAGS)) {
  226. Status = CR_INVALID_DATA;
  227. goto Clean0;
  228. }
  229. if (!ARGUMENT_PRESENT(pulValue)) {
  230. Status = CR_INVALID_POINTER;
  231. goto Clean0;
  232. }
  233. if (ulAction == PNP_GET_HWPROFFLAGS) {
  234. //
  235. // Validate flags for PNP_GET_HWPROFFLAGS
  236. //
  237. if (INVALID_FLAGS(ulFlags, 0)) {
  238. Status = CR_INVALID_FLAG;
  239. goto Clean0;
  240. }
  241. } else if (ulAction == PNP_SET_HWPROFFLAGS) {
  242. //
  243. // Validate flags and value for PNP_SET_HWPROFFLAGS
  244. //
  245. if (INVALID_FLAGS(ulFlags, CM_SET_HW_PROF_FLAGS_BITS)) {
  246. Status = CR_INVALID_FLAG;
  247. goto Clean0;
  248. }
  249. if (INVALID_FLAGS(*pulValue, CSCONFIGFLAG_BITS)) {
  250. Status = CR_INVALID_DATA;
  251. goto Clean0;
  252. }
  253. }
  254. if (!IsLegalDeviceId(pDeviceID)) {
  255. Status = CR_INVALID_DEVNODE;
  256. goto Clean0;
  257. }
  258. //
  259. // a configuration value of zero implies to use the current config
  260. //
  261. if (ulConfig == 0) {
  262. wsprintf(RegStr, TEXT("%s\\%s\\%s"),
  263. pszRegPathHwProfiles, // System\CCC\Hardware Profiles
  264. pszRegKeyCurrent, // Current
  265. pszRegPathEnum); // System\Enum
  266. } else {
  267. wsprintf(RegStr, TEXT("%s\\%04u\\%s"),
  268. pszRegPathHwProfiles, // System\CCC\Hardware Profiles
  269. ulConfig, // xxxx (profile id)
  270. pszRegPathEnum); // System\Enum
  271. }
  272. //----------------------------------------------------
  273. // caller wants to retrieve the hw profile flag value
  274. //----------------------------------------------------
  275. if (ulAction == PNP_GET_HWPROFFLAGS) {
  276. //
  277. // open the profile specific enum key
  278. //
  279. RegStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE, RegStr, 0,
  280. KEY_QUERY_VALUE, &hKey);
  281. if (RegStatus != ERROR_SUCCESS) {
  282. *pulValue = 0; // success,this is what Win95 does
  283. goto Clean0;
  284. }
  285. //
  286. // open the enum\device-instance key under the profile key
  287. //
  288. RegStatus = RegOpenKeyEx( hKey, pDeviceID, 0, KEY_QUERY_VALUE, &hDevKey);
  289. if (RegStatus != ERROR_SUCCESS) {
  290. *pulValue = 0; // success,this is what Win95 does
  291. goto Clean0;
  292. }
  293. //
  294. // query the profile flag
  295. //
  296. ulValueSize = sizeof(ULONG);
  297. RegStatus = RegQueryValueEx( hDevKey, pszRegValueCSConfigFlags,
  298. NULL, NULL, (LPBYTE)pulValue,
  299. &ulValueSize);
  300. if (RegStatus != ERROR_SUCCESS) {
  301. *pulValue = 0;
  302. if (RegStatus != ERROR_CANTREAD && RegStatus != ERROR_FILE_NOT_FOUND) {
  303. Status = CR_REGISTRY_ERROR;
  304. goto Clean0;
  305. }
  306. }
  307. }
  308. //----------------------------------------------
  309. // caller wants to set the hw profile flag value
  310. //----------------------------------------------
  311. else if (ulAction == PNP_SET_HWPROFFLAGS) {
  312. if (!VerifyClientAccess(hBinding, &gLuidLoadDriverPrivilege)) {
  313. Status = CR_ACCESS_DENIED;
  314. goto Clean0;
  315. }
  316. //
  317. // open the profile specific enum key.
  318. //
  319. // note that we may actually end up creating a Hardware Profile key
  320. // here for the specified profile id, even if no such profile
  321. // exists. ideally, we should check that such a profile exists, but
  322. // we've been doing this for too long to change it now. the
  323. // consolation here is that the client must have appropriate
  324. // privilege to actually do this.
  325. //
  326. RegStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE, RegStr, 0, NULL,
  327. REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE,
  328. NULL, &hKey, &ulDisposition);
  329. if (RegStatus != ERROR_SUCCESS) {
  330. Status = CR_REGISTRY_ERROR;
  331. goto Clean0;
  332. }
  333. //
  334. // open the enum\device-instance key under the profile key
  335. //
  336. RegStatus = RegCreateKeyEx( hKey, pDeviceID, 0, NULL,
  337. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
  338. NULL, &hDevKey, NULL);
  339. if (RegStatus != ERROR_SUCCESS) {
  340. Status = CR_REGISTRY_ERROR;
  341. goto Clean0;
  342. }
  343. //
  344. // before setting, query the current profile flag
  345. //
  346. ulValueSize = sizeof(ulCurrentValue);
  347. RegStatus = RegQueryValueEx( hDevKey, pszRegValueCSConfigFlags,
  348. NULL, NULL, (LPBYTE)&ulCurrentValue,
  349. &ulValueSize);
  350. if (RegStatus == ERROR_CANTREAD || RegStatus == ERROR_FILE_NOT_FOUND) {
  351. ulCurrentValue = 0; // success,this is what Win95 does
  352. } else if (RegStatus != ERROR_SUCCESS) {
  353. Status = CR_REGISTRY_ERROR;
  354. goto Clean0;
  355. }
  356. //
  357. // if requested flags different than current, write out to registry
  358. //
  359. ulChange = ulCurrentValue ^ *pulValue;
  360. if (ulChange) {
  361. AffectsCurrentProfile = (BOOL)(ulConfig == 0 || IsCurrentProfile(ulConfig));
  362. //
  363. // we're about to change the disable bit on the current profile,
  364. // try and disable the device in the process
  365. //
  366. if ((ulChange & CSCONFIGFLAG_DISABLED) &&
  367. (*pulValue & CSCONFIGFLAG_DISABLED) && AffectsCurrentProfile) {
  368. //
  369. // disable the devnode
  370. //
  371. Status = DisableDevInst(pDeviceID,
  372. pVetoType,
  373. pszVetoName,
  374. ulNameLength);
  375. if (Status != CR_SUCCESS) {
  376. if (Status == CR_NOT_DISABLEABLE) {
  377. //
  378. // we got refused!
  379. // (note that this error also implies *NO* changes to the registry entry)
  380. //
  381. goto Clean0;
  382. } else {
  383. //
  384. // we can go ahead and disable after restart
  385. //
  386. Status = CR_NEED_RESTART;
  387. }
  388. }
  389. }
  390. //
  391. // assume Status is valid and typically CR_SUCCESS or CR_NEED_RESTART
  392. //
  393. //
  394. // now update the registry
  395. //
  396. RegStatus = RegSetValueEx( hDevKey, pszRegValueCSConfigFlags, 0,
  397. REG_DWORD, (LPBYTE)pulValue,
  398. sizeof(ULONG));
  399. if (RegStatus != ERROR_SUCCESS) {
  400. Status = CR_REGISTRY_ERROR;
  401. goto Clean0;
  402. }
  403. if (Status == CR_NEED_RESTART) {
  404. //
  405. // we have to RESTART due to not being able to disable device immediately
  406. //
  407. goto Clean0;
  408. }
  409. //
  410. // If this doesn't effect the current config, then we're done.
  411. //
  412. if (!AffectsCurrentProfile) {
  413. goto Clean0;
  414. }
  415. //
  416. // are we enabling the device?
  417. //
  418. if ((ulChange & CSCONFIGFLAG_DISABLED) && !(*pulValue & CSCONFIGFLAG_DISABLED)) {
  419. //
  420. // enable the devnode
  421. //
  422. EnableDevInst(pDeviceID);
  423. }
  424. //
  425. // did the do-not-create bit change?
  426. //
  427. if (ulChange & CSCONFIGFLAG_DO_NOT_CREATE) {
  428. if (*pulValue & CSCONFIGFLAG_DO_NOT_CREATE) {
  429. //
  430. // if subtree can be removed, remove it now
  431. //
  432. if (QueryAndRemoveSubTree( pDeviceID,
  433. pVetoType,
  434. pszVetoName,
  435. ulNameLength,
  436. PNP_QUERY_AND_REMOVE_NO_RESTART) != CR_SUCCESS) {
  437. Status = CR_NEED_RESTART;
  438. goto Clean0;
  439. }
  440. }
  441. else {
  442. //
  443. // The DO_NOT_CREATE flag was turned off, reenumerate the devnode
  444. //
  445. ReenumerateDevInst(pDeviceID, TRUE, 0);
  446. }
  447. }
  448. }
  449. }
  450. Clean0:
  451. NOTHING;
  452. } except(EXCEPTION_EXECUTE_HANDLER) {
  453. Status = CR_FAILURE;
  454. }
  455. if (hKey != NULL) {
  456. RegCloseKey(hKey);
  457. }
  458. if (hDevKey != NULL) {
  459. RegCloseKey(hDevKey);
  460. }
  461. return Status;
  462. } // PNP_HwProfFlags
  463. CONFIGRET
  464. PNP_GetHwProfInfo(
  465. IN handle_t hBinding,
  466. IN ULONG ulIndex,
  467. OUT PHWPROFILEINFO pHWProfileInfo,
  468. IN ULONG ulProfileInfoSize,
  469. IN ULONG ulFlags
  470. )
  471. /*++
  472. Routine Description:
  473. This is the RPC server entry point for the ConfigManager routine
  474. CM_Get_Hardware_Profile_Info. It returns a structure of info for
  475. the specified hardware profile.
  476. Arguments:
  477. hBinding RPC binding handle, not used.
  478. ulIndex Specifies which profile to use. A value of 0xFFFFFFFF
  479. indicates to use the current profile.
  480. pHWProfileInfo Pointer to HWPROFILEINFO struct, returns profile info
  481. ulProfileInfoSize Specifies the size of the HWPROFILEINFO struct
  482. ulFlags Not used, must be zero.
  483. Return Value:
  484. If the function succeeds it returns CR_SUCCESS. Otherwise it returns one
  485. of the CR_* values.
  486. --*/
  487. {
  488. CONFIGRET Status = CR_SUCCESS;
  489. ULONG RegStatus = ERROR_SUCCESS;
  490. WCHAR RegStr[MAX_CM_PATH];
  491. HKEY hKey = NULL, hDockKey = NULL, hCfgKey = NULL;
  492. ULONG ulSize, ulDisposition;
  493. ULONG enumIndex, targetIndex;
  494. UNREFERENCED_PARAMETER(hBinding);
  495. try {
  496. //
  497. // validate parameters
  498. //
  499. if (INVALID_FLAGS(ulFlags, 0)) {
  500. Status = CR_INVALID_FLAG;
  501. goto Clean0;
  502. }
  503. //
  504. // validate the size of the HWPROFILEINFO struct
  505. //
  506. if (ulProfileInfoSize != sizeof(HWPROFILEINFO)) {
  507. Status = CR_INVALID_DATA;
  508. goto Clean0;
  509. }
  510. //
  511. // initialize the HWPROFILEINFO struct fields
  512. //
  513. pHWProfileInfo->HWPI_ulHWProfile = 0;
  514. pHWProfileInfo->HWPI_szFriendlyName[0] = '\0';
  515. pHWProfileInfo->HWPI_dwFlags = 0;
  516. //
  517. // open a key to IDConfigDB (create if it doesn't already exist
  518. //
  519. RegStatus = RegCreateKeyEx(HKEY_LOCAL_MACHINE, pszRegPathIDConfigDB, 0,
  520. NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE,
  521. NULL, &hKey, &ulDisposition);
  522. if (RegStatus != ERROR_SUCCESS) {
  523. Status = CR_REGISTRY_ERROR;
  524. goto Clean0;
  525. }
  526. //
  527. // open a key to Hardware Profiles (create if it doesn't already exist)
  528. //
  529. RegStatus = RegCreateKeyEx(hKey, pszRegKeyKnownDockingStates, 0,
  530. NULL, REG_OPTION_NON_VOLATILE,
  531. KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, NULL,
  532. &hDockKey, &ulDisposition);
  533. if (RegStatus != ERROR_SUCCESS) {
  534. Status = CR_REGISTRY_ERROR;
  535. goto Clean0;
  536. }
  537. //
  538. // a configuration value of 0xFFFFFFFF implies to use the current config
  539. //
  540. if (ulIndex == 0xFFFFFFFF) {
  541. //
  542. // get the current profile index stored under IDConfigDB
  543. //
  544. ulSize = sizeof(ULONG);
  545. RegStatus = RegQueryValueEx(
  546. hKey, pszRegValueCurrentConfig, NULL, NULL,
  547. (LPBYTE)&pHWProfileInfo->HWPI_ulHWProfile, &ulSize);
  548. if (RegStatus != ERROR_SUCCESS) {
  549. Status = CR_REGISTRY_ERROR;
  550. pHWProfileInfo->HWPI_ulHWProfile = 0;
  551. goto Clean0;
  552. }
  553. }
  554. //
  555. // values other than 0xFFFFFFFF mean that we're essentially
  556. // enumerating profiles (the value is an enumeration index)
  557. //
  558. else {
  559. //
  560. // enumerate the profile keys under Known Docking States
  561. //
  562. Status = CR_SUCCESS;
  563. enumIndex = 0;
  564. targetIndex = ulIndex;
  565. while(enumIndex <= targetIndex) {
  566. ulSize = MAX_CM_PATH;
  567. RegStatus = RegEnumKeyEx(hDockKey,
  568. enumIndex,
  569. RegStr,
  570. &ulSize,
  571. NULL,
  572. NULL,
  573. NULL,
  574. NULL);
  575. if (RegStatus == ERROR_NO_MORE_ITEMS) {
  576. Status = CR_NO_MORE_HW_PROFILES;
  577. goto Clean0;
  578. } else if (RegStatus != ERROR_SUCCESS) {
  579. Status = CR_REGISTRY_ERROR;
  580. goto Clean0;
  581. }
  582. if (_wtoi(RegStr) == 0) {
  583. //
  584. // we found the pristine amidst the profiles we're enumerating.
  585. // enumerate one extra key to make up for it.
  586. //
  587. targetIndex++;
  588. }
  589. if (enumIndex == targetIndex) {
  590. //
  591. // this is the one we want.
  592. //
  593. pHWProfileInfo->HWPI_ulHWProfile = _wtoi(RegStr);
  594. Status = CR_SUCCESS;
  595. break;
  596. }
  597. enumIndex++;
  598. }
  599. }
  600. //
  601. // open the key for this profile
  602. //
  603. wsprintf(RegStr, TEXT("%04u"),
  604. pHWProfileInfo->HWPI_ulHWProfile);
  605. RegStatus = RegOpenKeyEx(
  606. hDockKey, RegStr, 0, KEY_QUERY_VALUE, &hCfgKey);
  607. if (RegStatus != ERROR_SUCCESS) {
  608. Status = CR_REGISTRY_ERROR;
  609. goto Clean0;
  610. }
  611. //
  612. // retrieve the friendly name
  613. //
  614. ulSize = MAX_PROFILE_LEN * sizeof(WCHAR);
  615. RegStatus = RegQueryValueEx(
  616. hCfgKey, pszRegValueFriendlyName, NULL, NULL,
  617. (LPBYTE)(pHWProfileInfo->HWPI_szFriendlyName),
  618. &ulSize);
  619. //
  620. // retrieve the DockState
  621. //
  622. #if 0
  623. //
  624. // KENRAY
  625. // This is the wrong way to determine docking state caps
  626. // You must instead check the alias tables
  627. //
  628. wsprintf(RegStr, TEXT("%04u"), pHWProfileInfo->HWPI_ulHWProfile);
  629. ulSize = sizeof(SYSTEM_DOCK_STATE);
  630. RegStatus = RegQueryValueEx(
  631. hCfgKey, pszRegValueDockState, NULL, NULL,
  632. (LPBYTE)&DockState, &ulSize);
  633. if (RegStatus != ERROR_SUCCESS) {
  634. pHWProfileInfo->HWPI_dwFlags = CM_HWPI_NOT_DOCKABLE;
  635. }
  636. else {
  637. //
  638. // map SYSTEM_DOCK_STATE enumerated types into CM_HWPI_ flags
  639. //
  640. if (DockState == SystemDocked) {
  641. pHWProfileInfo->HWPI_dwFlags = CM_HWPI_DOCKED;
  642. }
  643. else if (DockState == SystemUndocked) {
  644. pHWProfileInfo->HWPI_dwFlags = CM_HWPI_UNDOCKED;
  645. }
  646. else {
  647. pHWProfileInfo->HWPI_dwFlags = CM_HWPI_NOT_DOCKABLE;
  648. }
  649. }
  650. #endif
  651. Clean0:
  652. NOTHING;
  653. } except(EXCEPTION_EXECUTE_HANDLER) {
  654. Status = CR_FAILURE;
  655. }
  656. if (hKey != NULL) {
  657. RegCloseKey(hKey);
  658. }
  659. if (hDockKey != NULL) {
  660. RegCloseKey(hDockKey);
  661. }
  662. if (hCfgKey != NULL) {
  663. RegCloseKey(hCfgKey);
  664. }
  665. return Status;
  666. } // PNP_GetHwProfInfo
  667. CONFIGRET
  668. PNP_SetHwProf(
  669. IN handle_t hBinding,
  670. IN ULONG ulHardwareProfile,
  671. IN ULONG ulFlags
  672. )
  673. {
  674. UNREFERENCED_PARAMETER(hBinding);
  675. UNREFERENCED_PARAMETER(ulHardwareProfile);
  676. UNREFERENCED_PARAMETER(ulFlags);
  677. return CR_CALL_NOT_IMPLEMENTED;
  678. } // PNP_SetHwProf
  679. //-------------------------------------------------------------------
  680. // Private utility routines
  681. //-------------------------------------------------------------------
  682. BOOL
  683. IsCurrentProfile(
  684. ULONG ulProfile
  685. )
  686. /*++
  687. Routine Description:
  688. This routine determines if the specified profile matches the current
  689. profile.
  690. Arguments:
  691. ulProfile Profile id value (value from 1 - 9999).
  692. Return Value:
  693. Return TRUE if this is the current profile, FALSE if it isn't.
  694. --*/
  695. {
  696. HKEY hKey;
  697. ULONG ulSize, ulCurrentProfile;
  698. //
  699. // open a key to IDConfigDB
  700. //
  701. if (RegOpenKeyEx(
  702. HKEY_LOCAL_MACHINE, pszRegPathIDConfigDB, 0,
  703. KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) {
  704. return FALSE;
  705. }
  706. //
  707. // get the current profile index stored under IDConfigDB
  708. //
  709. ulSize = sizeof(ULONG);
  710. if (RegQueryValueEx(
  711. hKey, pszRegValueCurrentConfig, NULL, NULL,
  712. (LPBYTE)&ulCurrentProfile, &ulSize) != ERROR_SUCCESS) {
  713. RegCloseKey(hKey);
  714. return FALSE;
  715. }
  716. RegCloseKey(hKey);
  717. if (ulCurrentProfile == ulProfile) {
  718. return TRUE;
  719. }
  720. return FALSE;
  721. } // IsCurrentProfile