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.

310 lines
10 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C P N P . C P P
  7. //
  8. // Contents: Common code for PnP.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 10 Oct 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include "ncbase.h"
  18. #include "ncdebug.h"
  19. #include "ncpnp.h"
  20. #include "ncstring.h"
  21. #include "ncsvc.h"
  22. extern const WCHAR c_szDevice[];
  23. //+---------------------------------------------------------------------------
  24. // Function: HrSendServicePnpEvent
  25. //
  26. // Purpose: Send to the service one of the net pnp control codes
  27. //
  28. // Parameters:
  29. // pszService - the service name to send the notification to
  30. // dwControl - the control code to send
  31. //
  32. // Returns: HRESULT S_OK on success, HrFromLastWin32Error otherwise
  33. //
  34. // Notes: the following control codes are only allowed
  35. // SERVICE_CONTROL_PARAMCHANGE
  36. // Informs the service that service-specific parameters that it reads
  37. // when it starts have changed, and requests it to re-read its startup
  38. // parameters from whatever location they are stored in. The hService
  39. // handle must have SERVICE_CHANGE_PARAM access.
  40. //
  41. // SERVICE_CONTROL_NETBINDADD
  42. // Informs a network service that a new component has been added to the
  43. // set of components that it should bind to, and requests it to re-read
  44. // its binding information and bind to the new component. The hService
  45. // handle must have SERVICE_CHANGE_PARAM access.
  46. //
  47. // SERVICE_CONTROL_NETBINDREMOVE
  48. // Informs a network service that a component has been removed from the
  49. // set of components that it should bind to, and requests it to re-read
  50. // its binding information and unbind from the removed component. The
  51. // hService handle must have SERVICE_CHANGE_PARAM access.
  52. //
  53. // SERVICE_CONTROL_NETBINDENABLE
  54. // Informs a network service that one of its previously disabled bindings
  55. // has been enabled, and requests it to re-read its binding information and
  56. // add the new binding. The hService handle must have SERVICE_CHANGE_PARAM access.
  57. //
  58. // SERVICE_CONTROL_NETBINDDISABLE
  59. // Informs a network service that one of its bindings has been disabled, and
  60. // requests it to re-read its binding information and unbind the disabled
  61. // binding. The hService handle must have SERVICE_CHANGE_PARAM access.
  62. // (Note: There is nothing network-specific about the Win32 service APIs today.
  63. // This would be the first network-specific thing appearing in the docs.
  64. // I think that's OK.)
  65. //
  66. HRESULT
  67. HrSendServicePnpEvent (
  68. PCWSTR pszService,
  69. DWORD dwControl )
  70. {
  71. Assert( pszService && 0 < lstrlen( pszService ) );
  72. Assert( (dwControl == SERVICE_CONTROL_PARAMCHANGE) ||
  73. (dwControl == SERVICE_CONTROL_NETBINDADD) ||
  74. (dwControl == SERVICE_CONTROL_NETBINDREMOVE) ||
  75. (dwControl == SERVICE_CONTROL_NETBINDENABLE) ||
  76. (dwControl == SERVICE_CONTROL_NETBINDDISABLE) );
  77. CServiceManager scm;
  78. CService service;
  79. HRESULT hr = scm.HrOpenService(&service, pszService, NO_LOCK, STANDARD_RIGHTS_READ | STANDARD_RIGHTS_WRITE | SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_QUERY_LOCK_STATUS, STANDARD_RIGHTS_READ | STANDARD_RIGHTS_WRITE | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE | SERVICE_PAUSE_CONTINUE | SERVICE_USER_DEFINED_CONTROL);
  80. if (S_OK == hr)
  81. {
  82. TraceTag(ttidNetCfgPnp,
  83. "HrSendServicePnpEvent( service- %S, control- %d )",
  84. pszService,
  85. dwControl );
  86. hr = service.HrControl( dwControl );
  87. }
  88. TraceError( "HrSendServicePnpEvent", hr );
  89. return hr;
  90. }
  91. //+---------------------------------------------------------------------------
  92. // Function: SetUnicodeString
  93. //
  94. // Purpose: given a UNICODE_STRING initialize it to the given WSTR
  95. //
  96. // Parameters:
  97. // pustr - the UNICODE_STRING to initialize
  98. // psz - the WSTR to use to initialize the UNICODE_STRING
  99. //
  100. // Notes: This differs from the RtlInitUnicodeString in that the
  101. // MaximumLength value contains the terminating null
  102. //
  103. void
  104. SetUnicodeString (
  105. OUT UNICODE_STRING* pustr,
  106. IN PCWSTR psz )
  107. {
  108. Assert(pustr);
  109. Assert(psz);
  110. pustr->Buffer = const_cast<PWSTR>(psz);
  111. pustr->Length = wcslen(psz) * sizeof(WCHAR);
  112. pustr->MaximumLength = pustr->Length + sizeof(WCHAR);
  113. }
  114. //+---------------------------------------------------------------------------
  115. // Function: SetUnicodeMultiString
  116. //
  117. // Purpose: given a UNICODE_STRING initialize it to the given WSTR
  118. // multi string buffer
  119. //
  120. // Parameters:
  121. // pustr - the UNICODE_STRING to initialize
  122. // pmsz - the multi sz WSTR to use to initialize the UNICODE_STRING
  123. //
  124. void
  125. SetUnicodeMultiString (
  126. OUT UNICODE_STRING* pustr,
  127. IN PCWSTR pmsz )
  128. {
  129. AssertSz( pustr != NULL, "Invalid Argument" );
  130. AssertSz( pmsz != NULL, "Invalid Argument" );
  131. pustr->Buffer = const_cast<PWSTR>(pmsz);
  132. ULONG cb = CchOfMultiSzAndTermSafe(pustr->Buffer) * sizeof(WCHAR);
  133. Assert (cb <= USHRT_MAX);
  134. pustr->Length = (USHORT)cb;
  135. pustr->MaximumLength = pustr->Length;
  136. }
  137. //+---------------------------------------------------------------------------
  138. // Function: HrSendNdisHandlePnpEvent
  139. //
  140. // Purpose: Send to Ndis a HandlePnpEvent notification
  141. //
  142. // Parameters:
  143. // uiLayer - either NDIS or TDI
  144. // uiOperation - either BIND, RECONFIGURE, or UNBIND
  145. // pszUpper - a WIDE string containing the upper component name
  146. // pszLower - a WIDE string containing the lower component name
  147. // This is one of the Export names from that component
  148. // The values NULL and c_szEmpty are both supported
  149. // pmszBindList - a WIDE string containing the NULL terminiated list of strings
  150. // representing the bindlist, vaid only for reconfigure
  151. // The values NULL and c_szEmpty are both supported
  152. // pvData - Pointer to ndis component notification data. Content
  153. // determined by each component.
  154. // dwSizeData - Count of bytes in pvData
  155. //
  156. // Returns: HRESULT S_OK on success, HrFromLastWin32Error otherwise
  157. //
  158. // Notes: Do not use this routine directly, see...
  159. // HrSendNdisPnpBindOrderChange,
  160. // HrSendNdisPnpReconfig
  161. //
  162. HRESULT
  163. HrSendNdisHandlePnpEvent (
  164. UINT uiLayer,
  165. UINT uiOperation,
  166. PCWSTR pszUpper,
  167. PCWSTR pszLower,
  168. PCWSTR pmszBindList,
  169. PVOID pvData,
  170. DWORD dwSizeData)
  171. {
  172. UNICODE_STRING umstrBindList;
  173. UNICODE_STRING ustrLower;
  174. UNICODE_STRING ustrUpper;
  175. UINT nRet;
  176. HRESULT hr = S_OK;
  177. Assert(NULL != pszUpper);
  178. Assert((NDIS == uiLayer)||(TDI == uiLayer));
  179. Assert( (BIND == uiOperation) || (RECONFIGURE == uiOperation) ||
  180. (UNBIND == uiOperation) || (UNLOAD == uiOperation) ||
  181. (REMOVE_DEVICE == uiOperation));
  182. AssertSz( FImplies( ((NULL != pmszBindList) && (0 != lstrlenW( pmszBindList ))),
  183. (RECONFIGURE == uiOperation) &&
  184. (TDI == uiLayer) &&
  185. (0 == lstrlenW( pszLower ))),
  186. "bind order change requires a bind list, no lower, only for TDI, "
  187. "and with Reconfig for the operation" );
  188. // optional strings must be sent as empty strings
  189. //
  190. if (NULL == pszLower)
  191. {
  192. pszLower = c_szEmpty;
  193. }
  194. if (NULL == pmszBindList)
  195. {
  196. pmszBindList = c_szEmpty;
  197. }
  198. // build UNICDOE_STRINGs
  199. SetUnicodeMultiString( &umstrBindList, pmszBindList );
  200. SetUnicodeString( &ustrUpper, pszUpper );
  201. SetUnicodeString( &ustrLower, pszLower );
  202. TraceTag(ttidNetCfgPnp,
  203. "HrSendNdisHandlePnpEvent( layer- %d, op- %d, upper- %S, lower- %S, &bindlist- %08lx, &data- %08lx, sizedata- %d )",
  204. uiLayer,
  205. uiOperation,
  206. pszUpper,
  207. pszLower,
  208. pmszBindList,
  209. pvData,
  210. dwSizeData );
  211. // Now submit the notification
  212. nRet = NdisHandlePnPEvent( uiLayer,
  213. uiOperation,
  214. &ustrLower,
  215. &ustrUpper,
  216. &umstrBindList,
  217. (PVOID)pvData,
  218. dwSizeData );
  219. if (!nRet)
  220. {
  221. hr = HrFromLastWin32Error();
  222. // If the transport is not started, ERROR_FILE_NOT_FOUND is expected
  223. // when the NDIS layer is notified. If the components of the TDI
  224. // layer aren't started, we get ERROR_GEN_FAILURE. We need to map
  225. // these to one consistent error
  226. if ((HRESULT_FROM_WIN32(ERROR_GEN_FAILURE) == hr) && (TDI == uiLayer))
  227. {
  228. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  229. }
  230. }
  231. TraceError( "HrSendNdisHandlePnpEvent",
  232. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr ? S_OK : hr );
  233. return hr;
  234. }
  235. //+---------------------------------------------------------------------------
  236. // Function: HrSendNdisPnpReconfig
  237. //
  238. // Purpose: Send to Ndis a HandlePnpEvent reconfig notification
  239. //
  240. // Parameters: uiLayer - either NDIS or TDI
  241. // pszUpper - a WIDE string containing the upper component name
  242. // (typically a protocol)
  243. // pszLower - a WIDE string containing the lower component name
  244. // (typically an adapter bindname) The values NULL and
  245. // c_szEmpty are both supported
  246. // pvData - Pointer to ndis component notification data. Content
  247. // determined by each component.
  248. // dwSizeData - Count of bytes in pvData
  249. //
  250. // Returns: HRESULT S_OK on success, HrFromLastWin32Error otherwise
  251. //
  252. HRESULT
  253. HrSendNdisPnpReconfig (
  254. UINT uiLayer,
  255. PCWSTR pszUpper,
  256. PCWSTR pszLower,
  257. PVOID pvData,
  258. DWORD dwSizeData)
  259. {
  260. Assert(NULL != pszUpper);
  261. Assert((NDIS == uiLayer) || (TDI == uiLayer));
  262. HRESULT hr;
  263. tstring strLower;
  264. // If a lower component is specified, prefix with "\Device\" else
  265. // strLower's default of an empty string will be used.
  266. if (pszLower && *pszLower)
  267. {
  268. strLower = c_szDevice;
  269. strLower += pszLower;
  270. }
  271. hr = HrSendNdisHandlePnpEvent(
  272. uiLayer,
  273. RECONFIGURE,
  274. pszUpper,
  275. strLower.c_str(),
  276. c_szEmpty,
  277. pvData,
  278. dwSizeData);
  279. TraceError("HrSendNdisPnpReconfig",
  280. (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ? S_OK : hr);
  281. return hr;
  282. }