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.

283 lines
8.6 KiB

  1. #include "stdafx.h"
  2. #include "ndispnpevent.h"
  3. //+---------------------------------------------------------------------------
  4. // Function: HrSendNdisHandlePnpEvent
  5. //
  6. // Purpose: Send to Ndis a HandlePnpEvent notification
  7. //
  8. // Parameters:
  9. // uiLayer - either NDIS or TDI
  10. // uiOperation - either BIND, RECONFIGURE, or UNBIND
  11. // pszUpper - a WIDE string containing the upper component name
  12. // pszLower - a WIDE string containing the lower component name
  13. // This is one of the Export names from that component
  14. // The values NULL and c_szEmpty are both supported
  15. // pmszBindList - a WIDE string containing the NULL terminiated list of strings
  16. // representing the bindlist, vaid only for reconfigure
  17. // The values NULL and c_szEmpty are both supported
  18. // pvData - Pointer to ndis component notification data. Content
  19. // determined by each component.
  20. // dwSizeData - Count of bytes in pvData
  21. //
  22. // Returns: HRESULT S_OK on success, HrFromLastWin32Error otherwise
  23. //
  24. // Notes: Do not use this routine directly, see...
  25. // HrSendNdisPnpBindOrderChange,
  26. // HrSendNdisPnpReconfig
  27. //
  28. HRESULT
  29. HrSendNdisHandlePnpEvent (
  30. UINT uiLayer,
  31. UINT uiOperation,
  32. PCWSTR pszUpper,
  33. PCWSTR pszLower,
  34. PCWSTR pmszBindList,
  35. PVOID pvData,
  36. DWORD dwSizeData)
  37. {
  38. UNICODE_STRING umstrBindList;
  39. UNICODE_STRING ustrLower;
  40. UNICODE_STRING ustrUpper;
  41. UINT nRet;
  42. HRESULT hr = S_OK;
  43. /* ASSERT(NULL != pszUpper);
  44. ASSERT((NDIS == uiLayer)||(TDI == uiLayer));
  45. ASSERT( (BIND == uiOperation) || (RECONFIGURE == uiOperation) ||
  46. (UNBIND == uiOperation) || (UNLOAD == uiOperation) ||
  47. (REMOVE_DEVICE == uiOperation));
  48. AssertSz( FImplies( ((NULL != pmszBindList) && (0 != lstrlenW( pmszBindList ))),
  49. (RECONFIGURE == uiOperation) &&
  50. (TDI == uiLayer) &&
  51. (0 == lstrlenW( pszLower ))),
  52. "bind order change requires a bind list, no lower, only for TDI, "
  53. "and with Reconfig for the operation" );*/
  54. // optional strings must be sent as empty strings
  55. //
  56. if (NULL == pszLower)
  57. {
  58. pszLower = c_szEmpty;
  59. }
  60. if (NULL == pmszBindList)
  61. {
  62. pmszBindList = c_szEmpty;
  63. }
  64. // build UNICDOE_STRINGs
  65. SetUnicodeMultiString( &umstrBindList, pmszBindList );
  66. SetUnicodeString( &ustrUpper, pszUpper );
  67. SetUnicodeString( &ustrLower, pszLower );
  68. /* TraceTag(ttidNetCfgPnp,
  69. "HrSendNdisHandlePnpEvent( layer- %d, op- %d, upper- %S, lower- %S, &bindlist- %08lx, &data- %08lx, sizedata- %d )",
  70. uiLayer,
  71. uiOperation,
  72. pszUpper,
  73. pszLower,
  74. pmszBindList,
  75. pvData,
  76. dwSizeData );*/
  77. // Now submit the notification
  78. nRet = NdisHandlePnPEvent( uiLayer,
  79. uiOperation,
  80. &ustrLower,
  81. &ustrUpper,
  82. &umstrBindList,
  83. (PVOID)pvData,
  84. dwSizeData );
  85. if (!nRet)
  86. {
  87. hr = HRESULT_FROM_WIN32(GetLastError());
  88. // If the transport is not started, ERROR_FILE_NOT_FOUND is expected
  89. // when the NDIS layer is notified. If the components of the TDI
  90. // layer aren't started, we get ERROR_GEN_FAILURE. We need to map
  91. // these to one consistent error
  92. if ((HRESULT_FROM_WIN32(ERROR_GEN_FAILURE) == hr) && (TDI == uiLayer))
  93. {
  94. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  95. }
  96. }
  97. // TraceError( "HrSendNdisHandlePnpEvent",
  98. // HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr ? S_OK : hr );
  99. return hr;
  100. }
  101. //+---------------------------------------------------------------------------
  102. // Function: HrSendNdisPnpReconfig
  103. //
  104. // Purpose: Send to Ndis a HandlePnpEvent reconfig notification
  105. //
  106. // Parameters: uiLayer - either NDIS or TDI
  107. // pszUpper - a WIDE string containing the upper component name
  108. // (typically a protocol)
  109. // pszLower - a WIDE string containing the lower component name
  110. // (typically an adapter bindname) The values NULL and
  111. // c_szEmpty are both supported
  112. // pvData - Pointer to ndis component notification data. Content
  113. // determined by each component.
  114. // dwSizeData - Count of bytes in pvData
  115. //
  116. // Returns: HRESULT S_OK on success, HrFromLastWin32Error otherwise
  117. //
  118. HRESULT
  119. HrSendNdisPnpReconfig (
  120. UINT uiLayer,
  121. PCWSTR pszUpper,
  122. PCWSTR pszLower,
  123. PVOID pvData,
  124. DWORD dwSizeData)
  125. {
  126. //ASSERT(NULL != pszUpper);
  127. //ASSERT((NDIS == uiLayer) || (TDI == uiLayer));
  128. HRESULT hr;
  129. tstring strLower;
  130. // If a lower component is specified, prefix with "\Device\" else
  131. // strLower's default of an empty string will be used.
  132. if (pszLower && *pszLower)
  133. {
  134. strLower = c_szDevice;
  135. strLower += pszLower;
  136. }
  137. hr = HrSendNdisHandlePnpEvent(
  138. uiLayer,
  139. RECONFIGURE,
  140. pszUpper,
  141. strLower.c_str(),
  142. c_szEmpty,
  143. pvData,
  144. dwSizeData);
  145. // TraceError("HrSendNdisPnpReconfig",
  146. // (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ? S_OK : hr);
  147. return hr;
  148. }
  149. //+---------------------------------------------------------------------------
  150. // Function: SetUnicodeString
  151. //
  152. // Purpose: given a UNICODE_STRING initialize it to the given WSTR
  153. //
  154. // Parameters:
  155. // pustr - the UNICODE_STRING to initialize
  156. // psz - the WSTR to use to initialize the UNICODE_STRING
  157. //
  158. // Notes: This differs from the RtlInitUnicodeString in that the
  159. // MaximumLength value contains the terminating null
  160. //
  161. void
  162. SetUnicodeString (
  163. OUT UNICODE_STRING* pustr,
  164. IN PCWSTR psz )
  165. {
  166. //Assert(pustr);
  167. //Assert(psz);
  168. pustr->Buffer = const_cast<PWSTR>(psz);
  169. pustr->Length = wcslen(psz) * sizeof(WCHAR);
  170. pustr->MaximumLength = pustr->Length + sizeof(WCHAR);
  171. }
  172. //+---------------------------------------------------------------------------
  173. // Function: SetUnicodeMultiString
  174. //
  175. // Purpose: given a UNICODE_STRING initialize it to the given WSTR
  176. // multi string buffer
  177. //
  178. // Parameters:
  179. // pustr - the UNICODE_STRING to initialize
  180. // pmsz - the multi sz WSTR to use to initialize the UNICODE_STRING
  181. //
  182. void
  183. SetUnicodeMultiString (
  184. OUT UNICODE_STRING* pustr,
  185. IN PCWSTR pmsz )
  186. {
  187. //AssertSz( pustr != NULL, "Invalid Argument" );
  188. //AssertSz( pmsz != NULL, "Invalid Argument" );
  189. pustr->Buffer = const_cast<PWSTR>(pmsz);
  190. ULONG cb = CchOfMultiSzAndTermSafe(pustr->Buffer) * sizeof(WCHAR);
  191. //Assert (cb <= USHRT_MAX);
  192. pustr->Length = (USHORT)cb;
  193. pustr->MaximumLength = pustr->Length;
  194. }
  195. //+---------------------------------------------------------------------------
  196. //
  197. // Function: CchOfMultiSzAndTermSafe
  198. //
  199. // Purpose: Count the number of characters of a double NULL terminated
  200. // multi-sz, including all NULLs.
  201. //
  202. // Arguments:
  203. // pmsz [in] The multi-sz to count characters for.
  204. //
  205. // Returns: The count of characters.
  206. //
  207. // Author: tongl 17 June 1997
  208. //
  209. // Notes:
  210. //
  211. ULONG
  212. CchOfMultiSzAndTermSafe (
  213. IN PCWSTR pmsz)
  214. {
  215. // NULL strings have zero length by definition.
  216. if (!pmsz)
  217. return 0;
  218. // Return the count of characters plus room for the
  219. // extra null terminator.
  220. return CchOfMultiSzSafe (pmsz) + 1;
  221. }
  222. //+---------------------------------------------------------------------------
  223. //
  224. // Function: CchOfMultiSzSafe
  225. //
  226. // Purpose: Count the number of characters of a double NULL terminated
  227. // multi-sz, including all NULLs except for the final terminating
  228. // NULL.
  229. //
  230. // Arguments:
  231. // pmsz [in] The multi-sz to count characters for.
  232. //
  233. // Returns: The count of characters.
  234. //
  235. // Author: tongl 17 June 1997
  236. //
  237. // Notes:
  238. //
  239. ULONG
  240. CchOfMultiSzSafe (
  241. IN PCWSTR pmsz)
  242. {
  243. // NULL strings have zero length by definition.
  244. if (!pmsz)
  245. return 0;
  246. ULONG cchTotal = 0;
  247. ULONG cch;
  248. while (*pmsz)
  249. {
  250. cch = wcslen (pmsz) + 1;
  251. cchTotal += cch;
  252. pmsz += cch;
  253. }
  254. // Return the count of characters.
  255. return cchTotal;
  256. }