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.

252 lines
6.9 KiB

  1. /*
  2. File netnum.cpp
  3. Private helper functions for setting the internal network number.
  4. We talk to ndis directly to set this number.
  5. Paul Mayfield, 1/5/98
  6. */
  7. #include <nt.h>
  8. #include <ntrtl.h>
  9. #include <nturtl.h>
  10. #include <windows.h>
  11. #include <winsvc.h>
  12. #include <ndispnp.h>
  13. extern "C" {
  14. DWORD OutputDebugger (LPSTR pszError, ...);
  15. };
  16. //$ REVIEW - Start - This is moving to private\inc\ipxpnp.h
  17. #define IPX_RECONFIG_VERSION 0x1
  18. #define RECONFIG_AUTO_DETECT 1
  19. #define RECONFIG_MANUAL 2
  20. #define RECONFIG_PREFERENCE_1 3
  21. #define RECONFIG_NETWORK_NUMBER_1 4
  22. #define RECONFIG_PREFERENCE_2 5
  23. #define RECONFIG_NETWORK_NUMBER_2 6
  24. #define RECONFIG_PREFERENCE_3 7
  25. #define RECONFIG_NETWORK_NUMBER_3 8
  26. #define RECONFIG_PREFERENCE_4 9
  27. #define RECONFIG_NETWORK_NUMBER_4 10
  28. #define RECONFIG_PARAMETERS 10
  29. //
  30. // Main configuration structure.
  31. //
  32. typedef struct _RECONFIG {
  33. unsigned long ulVersion;
  34. BOOLEAN InternalNetworkNumber;
  35. BOOLEAN AdapterParameters[RECONFIG_PARAMETERS];
  36. } RECONFIG, *PRECONFIG;
  37. //$ REVIEW - End - This is moving to private\inc\ipxpnp.h
  38. static const TCHAR c_szIpx[] = TEXT("nwlnkipx");
  39. static const TCHAR c_szEmpty[] = TEXT("");
  40. static const TCHAR c_szVirtualNetworkNumber[] = TEXT("VirtualNetworkNumber");
  41. static const TCHAR c_szIpxParameters[] = TEXT("System\\CurrentControlSet\\Services\\NwlnkIpx\\Parameters");
  42. static const TCHAR c_szDevice[] = TEXT("\\Device\\");
  43. ULONG
  44. CchMsz (
  45. LPCTSTR pmsz)
  46. {
  47. ULONG cchTotal = 0;
  48. ULONG cch;
  49. // NULL strings have zero length by definition.
  50. if (!pmsz)
  51. return 0;
  52. while (*pmsz)
  53. {
  54. cch = lstrlen (pmsz) + 1;
  55. cchTotal += cch;
  56. pmsz += cch;
  57. }
  58. // Return the count of characters so far plus room for the
  59. // extra null terminator.
  60. return cchTotal + 1;
  61. }
  62. void
  63. SetUnicodeMultiString (
  64. IN OUT UNICODE_STRING* pustr,
  65. IN LPCWSTR pmsz )
  66. {
  67. //AssertSz( pustr != NULL, "Invalid Argument" );
  68. //AssertSz( pmsz != NULL, "Invalid Argument" );
  69. pustr->Buffer = const_cast<PWSTR>(pmsz);
  70. pustr->Length = (USHORT) (CchMsz(pustr->Buffer) * sizeof(WCHAR));
  71. pustr->MaximumLength = pustr->Length;
  72. }
  73. void
  74. SetUnicodeString (
  75. IN OUT UNICODE_STRING* pustr,
  76. IN LPCWSTR psz )
  77. {
  78. //AssertSz( pustr != NULL, "Invalid Argument" );
  79. //AssertSz( psz != NULL, "Invalid Argument" );
  80. pustr->Buffer = const_cast<PWSTR>(psz);
  81. pustr->Length = (USHORT)(lstrlenW(pustr->Buffer) * sizeof(WCHAR));
  82. pustr->MaximumLength = pustr->Length + sizeof(WCHAR);
  83. }
  84. HRESULT
  85. HrSendNdisHandlePnpEvent (
  86. UINT uiLayer,
  87. UINT uiOperation,
  88. LPCWSTR pszUpper,
  89. LPCWSTR pszLower,
  90. LPCWSTR pmszBindList,
  91. PVOID pvData,
  92. DWORD dwSizeData)
  93. {
  94. UNICODE_STRING umstrBindList;
  95. UNICODE_STRING ustrLower;
  96. UNICODE_STRING ustrUpper;
  97. UINT nRet;
  98. HRESULT hr = S_OK;
  99. //Assert(NULL != pszUpper);
  100. //Assert((NDIS == uiLayer)||(TDI == uiLayer));
  101. //Assert( (BIND == uiOperation) || (RECONFIGURE == uiOperation) || (UNBIND == uiOperation) );
  102. //AssertSz( FImplies( ((NULL != pmszBindList) && (0 != lstrlenW( pmszBindList ))),
  103. // (RECONFIGURE == uiOperation) &&
  104. // (TDI == uiLayer) &&
  105. // (0 == lstrlenW( pszLower ))),
  106. // "bind order change requires a bind list, no lower, only for TDI, and with Reconfig for the operation" );
  107. // optional strings must be sent as empty strings
  108. //
  109. if (NULL == pszLower)
  110. {
  111. pszLower = c_szEmpty;
  112. }
  113. if (NULL == pmszBindList)
  114. {
  115. pmszBindList = c_szEmpty;
  116. }
  117. // build UNICDOE_STRINGs
  118. SetUnicodeMultiString( &umstrBindList, pmszBindList );
  119. SetUnicodeString( &ustrUpper, pszUpper );
  120. SetUnicodeString( &ustrLower, pszLower );
  121. // Now submit the notification
  122. nRet = NdisHandlePnPEvent( uiLayer,
  123. uiOperation,
  124. &ustrLower,
  125. &ustrUpper,
  126. &umstrBindList,
  127. (PVOID)pvData,
  128. dwSizeData );
  129. if (!nRet)
  130. {
  131. //hr = HrFromLastWin32Error();
  132. hr = GetLastError();
  133. }
  134. return( hr );
  135. }
  136. HRESULT
  137. HrSendNdisPnpReconfig (
  138. UINT uiLayer,
  139. LPCWSTR wszUpper,
  140. LPCWSTR wszLower,
  141. PVOID pvData,
  142. DWORD dwSizeData)
  143. {
  144. //Assert(NULL != wszUpper);
  145. //Assert((NDIS == uiLayer)||(TDI == uiLayer));
  146. //tstring strLower;
  147. WCHAR strLower[512];
  148. BOOL bSendNull = FALSE;
  149. if (NULL == wszLower)
  150. {
  151. wszLower = c_szEmpty;
  152. }
  153. // If a lower component is specified, prefix with "\Device\" else
  154. // strLower's default of an empty string will be used.
  155. if ( wszLower && lstrlenW(wszLower))
  156. {
  157. //strLower = c_szDevice;
  158. //strLower += wszLower;
  159. wcscpy(strLower, c_szDevice);
  160. wcscat(strLower, wszLower);
  161. }
  162. else
  163. bSendNull = TRUE;
  164. HRESULT hr = HrSendNdisHandlePnpEvent(uiLayer,
  165. RECONFIGURE,
  166. wszUpper,
  167. //strLower.c_str(),
  168. (bSendNull) ? NULL : strLower,
  169. c_szEmpty,
  170. pvData,
  171. dwSizeData);
  172. OutputDebugger( "HrSendNdisHandlePnpEvent: %x\n", hr);
  173. return hr;
  174. }
  175. HRESULT HrSetIpxVirtualNetNum(DWORD dwValue)
  176. {
  177. RECONFIG Config;
  178. HKEY hkey;
  179. HRESULT hr;
  180. // Open the registry key
  181. LONG lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szIpxParameters, 0,
  182. KEY_ALL_ACCESS, &hkey);
  183. hr = HRESULT_FROM_WIN32(lr);
  184. if (SUCCEEDED(hr))
  185. {
  186. // Splat the data
  187. lr = RegSetValueEx(hkey, c_szVirtualNetworkNumber, 0,
  188. REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  189. hr = HRESULT_FROM_WIN32(lr);
  190. if (SUCCEEDED(hr))
  191. {
  192. memset(&Config, 0, sizeof(RECONFIG));
  193. Config.ulVersion = IPX_RECONFIG_VERSION;
  194. Config.InternalNetworkNumber = TRUE;
  195. // Workstation or server?
  196. // Paul, Normally I only send this notification for servers. I
  197. // Assume you'll be able to distinguish
  198. // Now submit the global reconfig notification
  199. hr = HrSendNdisPnpReconfig(NDIS, c_szIpx, c_szEmpty, &Config, sizeof(RECONFIG));
  200. }
  201. RegCloseKey(hkey);
  202. }
  203. return hr;
  204. }
  205. // Here's the function we want -- it sets the ipx internal network number
  206. // programatically.
  207. EXTERN_C
  208. DWORD SetIpxInternalNetNumber(DWORD dwNetNum) {
  209. return HrSetIpxVirtualNetNum(dwNetNum);
  210. }