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.

589 lines
13 KiB

  1. /*++
  2. Copyright (c) 1995-2001 Microsoft Corporation
  3. Module Name:
  4. rmisc.c
  5. Abstract:
  6. This module contains the server-side misc configuration manager routines.
  7. PNP_GetVersion
  8. PNP_GetVersionInternal
  9. PNP_GetGlobalState
  10. PNP_SetActiveService
  11. PNP_QueryArbitratorFreeData
  12. PNP_QueryArbitratorFreeSize
  13. PNP_RunDetection
  14. PNP_Connect
  15. PNP_Disconnect
  16. PNP_GetBlockedDriverInfo
  17. The following routines are used by the RPC server stubs to allocate and free memory.
  18. MIDL_user_allocate
  19. MIDL_user_free
  20. Author:
  21. Paula Tomlinson (paulat) 6-28-1995
  22. Environment:
  23. User-mode only.
  24. Revision History:
  25. 28-June-1995 paulat
  26. Creation and initial implementation.
  27. --*/
  28. //
  29. // includes
  30. //
  31. #include "precomp.h"
  32. #include "umpnpi.h"
  33. #include "umpnpdat.h"
  34. //
  35. // global data
  36. //
  37. extern DWORD CurrentServiceState; // current state of the PlugPlay service - DO NOT MODIFY
  38. CONFIGRET
  39. PNP_GetVersion(
  40. IN handle_t hBinding,
  41. IN OUT WORD * pVersion
  42. )
  43. /*++
  44. Routine Description:
  45. This is the RPC server entry point, it returns the version
  46. number for the server-side component.
  47. Arguments:
  48. hBinding Not used.
  49. Return Value:
  50. Return the version number, with the major version in the high byte and
  51. the minor version number in the low byte.
  52. --*/
  53. {
  54. CONFIGRET Status = CR_SUCCESS;
  55. UNREFERENCED_PARAMETER(hBinding);
  56. try {
  57. *pVersion = (WORD)PNP_VERSION;
  58. } except(EXCEPTION_EXECUTE_HANDLER) {
  59. Status = CR_FAILURE;
  60. }
  61. return Status;
  62. } // PNP_GetVersion
  63. CONFIGRET
  64. PNP_GetVersionInternal(
  65. IN handle_t hBinding,
  66. IN OUT WORD * pwVersion
  67. )
  68. /*++
  69. Routine Description:
  70. This is the RPC server entry point, it returns the internal version
  71. number for the server-side component.
  72. Arguments:
  73. hBinding Not used.
  74. pwVersion Receives the internal cfgmgr32 version number, returns the
  75. internal server version number, with the major version in the
  76. high byte and the minor version number in the low byte.
  77. Return Value:
  78. Return CR_SUCCESS if the function succeeds, otherwise it returns one
  79. of the CR_* errors.
  80. --*/
  81. {
  82. CONFIGRET Status = CR_SUCCESS;
  83. UNREFERENCED_PARAMETER(hBinding);
  84. try {
  85. *pwVersion = (WORD)PNP_VERSION_INTERNAL;
  86. } except(EXCEPTION_EXECUTE_HANDLER) {
  87. Status = CR_FAILURE;
  88. }
  89. return Status;
  90. } // PNP_GetVersionInternal
  91. CONFIGRET
  92. PNP_GetGlobalState(
  93. IN handle_t hBinding,
  94. OUT PULONG pulState,
  95. IN ULONG ulFlags
  96. )
  97. /*++
  98. Routine Description:
  99. This is the RPC server entry point, it returns the Global State of the
  100. Configuration Manager.
  101. Arguments:
  102. hBinding Not used.
  103. pulState Returns the current global state.
  104. ulFlags Not used, must be zero.
  105. Return Value:
  106. Return CR_SUCCESS if the function succeeds, otherwise it returns one
  107. of the CR_* errors.
  108. --*/
  109. {
  110. CONFIGRET Status = CR_SUCCESS;
  111. UNREFERENCED_PARAMETER(hBinding);
  112. if (INVALID_FLAGS(ulFlags, 0)) {
  113. return CR_INVALID_FLAG;
  114. }
  115. try {
  116. *pulState =
  117. CM_GLOBAL_STATE_CAN_DO_UI |
  118. CM_GLOBAL_STATE_SERVICES_AVAILABLE;
  119. if ((CurrentServiceState == SERVICE_STOP_PENDING) ||
  120. (CurrentServiceState == SERVICE_STOPPED)) {
  121. *pulState |= CM_GLOBAL_STATE_SHUTTING_DOWN;
  122. }
  123. } except(EXCEPTION_EXECUTE_HANDLER) {
  124. Status = CR_FAILURE;
  125. }
  126. return Status;
  127. } // PNP_GetGlobalState
  128. CONFIGRET
  129. PNP_SetActiveService(
  130. IN handle_t hBinding,
  131. IN LPCWSTR pszService,
  132. IN ULONG ulFlags
  133. )
  134. /*++
  135. Routine Description:
  136. This routine is currently not an rpc routine, it is called directly
  137. and privately by the service controller.
  138. Arguments:
  139. hBinding RPC binding handle, not used.
  140. pszService Specifies the service name.
  141. ulFlags Either PNP_SERVICE_STARTED or PNP_SERVICE_STOPPED.
  142. Return Value:
  143. Return CR_SUCCESS if the function succeeds, otherwise it returns one
  144. of the CR_* errors.
  145. --*/
  146. {
  147. CONFIGRET Status = CR_SUCCESS;
  148. ULONG ulSize = 0, ulStatus = 0;
  149. LPWSTR pDeviceList = NULL, pszDevice = NULL;
  150. HKEY hKey = NULL, hControlKey = NULL;
  151. WCHAR RegStr[MAX_PATH];
  152. UNREFERENCED_PARAMETER(hBinding);
  153. try {
  154. //
  155. // validate parameters
  156. //
  157. if (pszService == NULL) {
  158. Status = CR_INVALID_POINTER;
  159. goto Clean0;
  160. }
  161. if ((ulFlags != PNP_SERVICE_STOPPED) &&
  162. (ulFlags != PNP_SERVICE_STARTED)) {
  163. Status = CR_INVALID_FLAG;
  164. goto Clean0;
  165. }
  166. //
  167. // not handling stops right now, everything beyond here assumes
  168. // the service is starting (or at least it attempted to start)
  169. //
  170. if (ulFlags == PNP_SERVICE_STOPPED) {
  171. goto Clean0; // not handling this right now
  172. }
  173. //
  174. // retreive the list of devices that this service is controlling
  175. //
  176. Status = PNP_GetDeviceListSize(NULL, pszService, &ulSize,
  177. CM_GETIDLIST_FILTER_SERVICE);
  178. if (Status != CR_SUCCESS) {
  179. goto Clean0;
  180. }
  181. pDeviceList = HeapAlloc(ghPnPHeap, 0, ulSize * sizeof(WCHAR));
  182. if (pDeviceList == NULL) {
  183. Status = CR_OUT_OF_MEMORY;
  184. goto Clean0;
  185. }
  186. Status = PNP_GetDeviceList(NULL, pszService, pDeviceList, &ulSize,
  187. CM_GETIDLIST_FILTER_SERVICE);
  188. if (Status != CR_SUCCESS) {
  189. goto Clean0;
  190. }
  191. //
  192. // set the ActiveService value for each device
  193. //
  194. for (pszDevice = pDeviceList;
  195. *pszDevice;
  196. pszDevice += lstrlen(pszDevice) + 1) {
  197. wsprintf(RegStr, TEXT("%s\\%s"),
  198. pszRegPathEnum,
  199. pszDevice);
  200. //
  201. // open the device instance key
  202. //
  203. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegStr, 0, KEY_ALL_ACCESS,
  204. &hKey) == ERROR_SUCCESS) {
  205. //
  206. // open/create the volatile Control key
  207. //
  208. if (RegCreateKeyEx(hKey, pszRegKeyDeviceControl, 0, NULL,
  209. REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL,
  210. &hControlKey, NULL) == ERROR_SUCCESS) {
  211. RegSetValueEx(hControlKey, pszRegValueActiveService,
  212. 0, REG_SZ, (LPBYTE)pszService,
  213. (lstrlen(pszService) + 1) * sizeof(WCHAR));
  214. //
  215. // set the statusflag to DN_STARTED
  216. //
  217. SetDeviceStatus(pszDevice, DN_STARTED, 0);
  218. RegCloseKey(hControlKey);
  219. hControlKey = NULL;
  220. }
  221. RegCloseKey(hKey);
  222. hKey = NULL;
  223. }
  224. }
  225. Clean0:
  226. NOTHING;
  227. } except(EXCEPTION_EXECUTE_HANDLER) {
  228. Status = CR_FAILURE;
  229. }
  230. if (pDeviceList != NULL) {
  231. HeapFree(ghPnPHeap, 0, pDeviceList);
  232. }
  233. if (hKey != NULL) {
  234. RegCloseKey(hKey);
  235. }
  236. return Status;
  237. } // PNP_SetActiveService
  238. //--------------------------------------------------------------------
  239. // Stub server side CM routines - not implemented yet
  240. //--------------------------------------------------------------------
  241. CONFIGRET
  242. PNP_QueryArbitratorFreeData(
  243. IN handle_t hBinding,
  244. OUT LPBYTE pData,
  245. IN ULONG ulDataLen,
  246. IN LPCWSTR pszDeviceID,
  247. IN RESOURCEID ResourceID,
  248. IN ULONG ulFlags
  249. )
  250. {
  251. UNREFERENCED_PARAMETER(hBinding);
  252. UNREFERENCED_PARAMETER(pData);
  253. UNREFERENCED_PARAMETER(ulDataLen);
  254. UNREFERENCED_PARAMETER(pszDeviceID);
  255. UNREFERENCED_PARAMETER(ResourceID);
  256. UNREFERENCED_PARAMETER(ulFlags);
  257. return CR_CALL_NOT_IMPLEMENTED;
  258. } // PNP_QueryArbitratorFreeData
  259. CONFIGRET
  260. PNP_QueryArbitratorFreeSize(
  261. IN handle_t hBinding,
  262. OUT PULONG pulSize,
  263. IN LPCWSTR pszDeviceID,
  264. IN RESOURCEID ResourceID,
  265. IN ULONG ulFlags
  266. )
  267. {
  268. UNREFERENCED_PARAMETER(hBinding);
  269. UNREFERENCED_PARAMETER(pszDeviceID);
  270. UNREFERENCED_PARAMETER(ResourceID);
  271. UNREFERENCED_PARAMETER(ulFlags);
  272. try {
  273. if (ARGUMENT_PRESENT(pulSize)) {
  274. *pulSize = 0;
  275. }
  276. } except(EXCEPTION_EXECUTE_HANDLER) {
  277. NOTHING;
  278. }
  279. return CR_CALL_NOT_IMPLEMENTED;
  280. } // PNP_QueryArbitratorFreeSize
  281. CONFIGRET
  282. PNP_RunDetection(
  283. IN handle_t hBinding,
  284. IN ULONG ulFlags
  285. )
  286. {
  287. UNREFERENCED_PARAMETER(hBinding);
  288. UNREFERENCED_PARAMETER(ulFlags);
  289. return CR_CALL_NOT_IMPLEMENTED;
  290. } // PNP_RunDetection
  291. CONFIGRET
  292. PNP_Connect(
  293. IN PNP_HANDLE UNCServerName
  294. )
  295. {
  296. UNREFERENCED_PARAMETER(UNCServerName);
  297. return CR_SUCCESS;
  298. } // PNP_Connect
  299. CONFIGRET
  300. PNP_Disconnect(
  301. IN PNP_HANDLE UNCServerName
  302. )
  303. {
  304. UNREFERENCED_PARAMETER(UNCServerName);
  305. return CR_SUCCESS;
  306. } // PNP_Disconnect
  307. CONFIGRET
  308. PNP_GetBlockedDriverInfo(
  309. IN handle_t hBinding,
  310. OUT LPBYTE Buffer,
  311. OUT PULONG pulTransferLen,
  312. IN OUT PULONG pulLength,
  313. IN ULONG ulFlags
  314. )
  315. /*++
  316. Routine Description:
  317. This is the RPC server entry point for the CMP_GetBlockedDriverInfo routine.
  318. Arguments:
  319. hBinding - RPC binding handle, not used.
  320. Buffer - Supplies the address of the buffer that receives the
  321. list. Can be NULL when simply retrieving data size.
  322. pulTransferLen - Used by stubs, indicates how much data (in bytes) to
  323. copy back into user buffer.
  324. pulLength - Parameter passed in by caller, on entry it contains the
  325. size (in bytes) of the buffer, on exit it contains either
  326. the number of bytes transferred to the caller's buffer (if
  327. a transfer occured) or else the size of buffer required to
  328. hold the list.
  329. ulFlags Not used, must be zero.
  330. Return Value:
  331. Return CR_SUCCESS if the function succeeds, otherwise it returns one of the
  332. CR_* errors.
  333. --*/
  334. {
  335. CONFIGRET Status = CR_SUCCESS;
  336. NTSTATUS ntStatus;
  337. PLUGPLAY_CONTROL_BLOCKED_DRIVER_DATA controlData;
  338. UNREFERENCED_PARAMETER(hBinding);
  339. try {
  340. //
  341. // Validate parameters
  342. //
  343. if ((!ARGUMENT_PRESENT(pulTransferLen)) ||
  344. (!ARGUMENT_PRESENT(pulLength))) {
  345. Status = CR_INVALID_POINTER;
  346. goto Clean0;
  347. }
  348. if ((!ARGUMENT_PRESENT(Buffer)) && (*pulLength != 0)) {
  349. Status = CR_INVALID_POINTER;
  350. goto Clean0;
  351. }
  352. if (INVALID_FLAGS(ulFlags, 0)) {
  353. Status = CR_INVALID_FLAG;
  354. goto Clean0;
  355. }
  356. //
  357. // We should never have both arguments pointing to the same memory...
  358. //
  359. ASSERT(pulTransferLen != pulLength);
  360. //
  361. // ...but if we do, fail the call.
  362. //
  363. if (pulTransferLen == pulLength) {
  364. Status = CR_INVALID_POINTER;
  365. goto Clean0;
  366. }
  367. //
  368. // Retrieve the blocked driver list via kernel-mode.
  369. //
  370. memset(&controlData, 0, sizeof(PLUGPLAY_CONTROL_BLOCKED_DRIVER_DATA));
  371. controlData.Buffer = Buffer;
  372. controlData.BufferLength = *pulLength;
  373. controlData.Flags = ulFlags;
  374. ntStatus = NtPlugPlayControl(PlugPlayControlGetBlockedDriverList,
  375. &controlData,
  376. sizeof(controlData));
  377. if (NT_SUCCESS(ntStatus)) {
  378. *pulTransferLen = *pulLength; // Transfer everything back
  379. *pulLength = controlData.BufferLength; // Length of valid data
  380. } else if (ntStatus == STATUS_BUFFER_TOO_SMALL) {
  381. *pulTransferLen = 0; // Nothing to transfer
  382. *pulLength = controlData.BufferLength;
  383. Status = CR_BUFFER_SMALL;
  384. } else {
  385. *pulLength = *pulTransferLen = 0; // Nothing to transfer
  386. Status = MapNtStatusToCmError(ntStatus);
  387. }
  388. Clean0:
  389. NOTHING;
  390. } except(EXCEPTION_EXECUTE_HANDLER) {
  391. Status = CR_FAILURE;
  392. }
  393. return Status;
  394. } // PNP_GetBlockedDriverInfo
  395. void __RPC_FAR * __RPC_USER
  396. MIDL_user_allocate(
  397. size_t cBytes
  398. )
  399. {
  400. return HeapAlloc(ghPnPHeap, 0, cBytes);
  401. } // MIDL_user_allocate
  402. void __RPC_USER
  403. MIDL_user_free(
  404. void __RPC_FAR * pBuffer
  405. )
  406. {
  407. HeapFree(ghPnPHeap, 0, pBuffer);
  408. } // MIDL_user_free