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.

334 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. svcsnb.c
  5. Abstract:
  6. NetBios support for services in svchost.exe.
  7. Background:
  8. In order to put the messenger service and the workstation service
  9. together in the same process, it became necessary to synchronize
  10. their use of NetBios. If NetSend did a reset and added the
  11. computername via netbios, it isn't desirable for the messenger
  12. to then do a reset, and destroy that computername.
  13. Purpose:
  14. These functions help to synchronize the use of netbios. A service
  15. that uses NetBios should first call the SvcsOpenNetBios function,
  16. then call SvcsResetNetBios. The open causes a use count to be
  17. incremented. The SvcsResetNetBios will only actually cause a
  18. NetBios reset if that Lan Adapter has not been reset yet.
  19. When the service stops it is necessary for it to call
  20. SvcsCloseNetBios. Thus when the last service using NetBios
  21. terminates, we clear all the state flags, and allow the next
  22. call to SvcsResetNetBios to actually do a reset.
  23. Author:
  24. Dan Lafferty (danl) 08-Nov-1993
  25. Environment:
  26. User Mode -Win32
  27. Revision History:
  28. 08-Nov-1993 danl
  29. created
  30. --*/
  31. //
  32. // INCLUDES
  33. //
  34. #include "pch.h"
  35. #pragma hdrstop
  36. #include <windows.h>
  37. #include <nb30.h> // NetBIOS 3.0 definitions
  38. #include <lmerr.h> // NERR_
  39. #include <svcsnb.h> // SvcNetBios prototypes
  40. //
  41. // DEFINES & MACROS
  42. //
  43. #define NUM_DWORD_BITS (sizeof(DWORD)*8)
  44. #define LANA_NUM_DWORDS ((MAX_LANA/NUM_DWORD_BITS)+1)
  45. //
  46. // These values correspond to the constants defined in ntos\netbios\nbconst.h
  47. // MAX_NUM_OF_SESSIONS=MAXIMUM_CONNECTION
  48. // MAX_NUM_OF_NAMES=MAXIMUM_ADDRESS -2
  49. //
  50. #define MAX_NUM_OF_SESSIONS 254
  51. #define MAX_NUM_OF_NAMES 253
  52. //
  53. // GLOBALS
  54. //
  55. CRITICAL_SECTION SvcNetBiosCritSec={0};
  56. DWORD LanaFlags[LANA_NUM_DWORDS]={0};
  57. DWORD GlobalNetBiosUseCount=0;
  58. //
  59. // LOCAL FUNCTIONS
  60. //
  61. DWORD
  62. SvcNetBiosStatusToApiStatus(
  63. UCHAR NetBiosStatus
  64. );
  65. VOID
  66. SetLanaFlag(
  67. UCHAR uCharLanaNum
  68. );
  69. BOOL
  70. LanaFlagIsSet(
  71. UCHAR uCharLanaNum
  72. );
  73. VOID
  74. SvcNetBiosInit(
  75. VOID
  76. )
  77. /*++
  78. Routine Description:
  79. Initializes a critical section and the global variable that it protects.
  80. Arguments:
  81. none
  82. Return Value:
  83. none
  84. --*/
  85. {
  86. DWORD i;
  87. InitializeCriticalSection(&SvcNetBiosCritSec);
  88. for (i=0;i<LANA_NUM_DWORDS ;i++ ) {
  89. LanaFlags[i] = 0;
  90. }
  91. GlobalNetBiosUseCount = 0;
  92. }
  93. VOID
  94. SvcNetBiosOpen(
  95. VOID
  96. )
  97. /*++
  98. Routine Description:
  99. This function is called by a service that will be making NetBios calls
  100. sometime in the future. It increments a use count for NetBios usage.
  101. This allows us to keep track of the services using NetBios.
  102. When the last service is done using it, then all the Lan Adapters can
  103. be marked as being re-settable.
  104. Arguments:
  105. Return Value:
  106. --*/
  107. {
  108. EnterCriticalSection(&SvcNetBiosCritSec);
  109. GlobalNetBiosUseCount++;
  110. LeaveCriticalSection(&SvcNetBiosCritSec);
  111. return;
  112. }
  113. VOID
  114. SvcNetBiosClose(
  115. VOID
  116. )
  117. /*++
  118. Routine Description:
  119. This function is called when the service is terminating and is
  120. no longer going to make any netbios calls.
  121. The UseCount for NetBios is decremented. It it becomes zero (meaning
  122. that no services are using NetBios any longer), then the array of
  123. LanaFlags is re-initialized to 0. Thus indicating that any of the
  124. Lan Adapters can now be reset.
  125. Arguments:
  126. Return Value:
  127. none.
  128. --*/
  129. {
  130. EnterCriticalSection(&SvcNetBiosCritSec);
  131. if (GlobalNetBiosUseCount > 0) {
  132. GlobalNetBiosUseCount--;
  133. if (GlobalNetBiosUseCount == 0) {
  134. DWORD i;
  135. for (i=0;i<LANA_NUM_DWORDS ;i++ ) {
  136. LanaFlags[i] = 0;
  137. }
  138. }
  139. }
  140. LeaveCriticalSection(&SvcNetBiosCritSec);
  141. return;
  142. }
  143. DWORD
  144. SvcNetBiosReset (
  145. UCHAR LanAdapterNumber
  146. )
  147. /*++
  148. Routine Description:
  149. This function will cause a NetBios Reset to occur on the specified
  150. LanAdapter if that adapter is marked as having never been reset.
  151. When the adapter is reset, then the LanaFlag for that adapter is
  152. set to 1 indicating that it has been reset. Future calls to reset that
  153. adapter will not cause a NetBios reset.
  154. Arguments:
  155. LanAdapterNumber - This indicates which LanAdapter the reset should affect.
  156. Return Value:
  157. Mapped response from NetBiosReset. If the NetBios Reset has already
  158. been accomplished, then NO_ERROR is returned.
  159. --*/
  160. {
  161. DWORD status = NO_ERROR;
  162. EnterCriticalSection(&SvcNetBiosCritSec);
  163. if (!LanaFlagIsSet(LanAdapterNumber)) {
  164. NCB Ncb;
  165. UCHAR NcbStatus;
  166. RtlZeroMemory((PVOID) &Ncb, sizeof(NCB));
  167. Ncb.ncb_command = NCBRESET;
  168. Ncb.ncb_lsn = 0;
  169. Ncb.ncb_callname[0] = MAX_NUM_OF_SESSIONS;
  170. Ncb.ncb_callname[1] = 0;
  171. Ncb.ncb_callname[2] = MAX_NUM_OF_NAMES;
  172. Ncb.ncb_callname[3] = 0;
  173. Ncb.ncb_lana_num = LanAdapterNumber;
  174. NcbStatus = Netbios(&Ncb);
  175. status = SvcNetBiosStatusToApiStatus(NcbStatus);
  176. if (status == NO_ERROR) {
  177. SetLanaFlag(LanAdapterNumber);
  178. }
  179. }
  180. LeaveCriticalSection(&SvcNetBiosCritSec);
  181. return(status);
  182. }
  183. DWORD
  184. SvcNetBiosStatusToApiStatus(
  185. UCHAR NetBiosStatus
  186. )
  187. {
  188. //
  189. // Slight optimization
  190. //
  191. if (NetBiosStatus == NRC_GOODRET) {
  192. return NERR_Success;
  193. }
  194. switch (NetBiosStatus) {
  195. case NRC_NORES: return NERR_NoNetworkResource;
  196. case NRC_DUPNAME: return NERR_AlreadyExists;
  197. case NRC_NAMTFUL: return NERR_TooManyNames;
  198. case NRC_ACTSES: return NERR_DeleteLater;
  199. case NRC_REMTFUL: return ERROR_REM_NOT_LIST;
  200. case NRC_NOCALL: return NERR_NameNotFound;
  201. case NRC_NOWILD:
  202. case NRC_NAMERR:
  203. return ERROR_INVALID_PARAMETER;
  204. case NRC_INUSE:
  205. case NRC_NAMCONF:
  206. return NERR_DuplicateName;
  207. default: return NERR_NetworkError;
  208. }
  209. }
  210. VOID
  211. SetLanaFlag(
  212. UCHAR uCharLanaNum
  213. )
  214. {
  215. DWORD LanaNum = (DWORD)uCharLanaNum;
  216. DWORD BitMask=1;
  217. DWORD DwordOffset;
  218. DWORD BitShift;
  219. DwordOffset = LanaNum / NUM_DWORD_BITS;
  220. if (DwordOffset > LANA_NUM_DWORDS) {
  221. return;
  222. }
  223. BitShift = LanaNum - (DwordOffset * NUM_DWORD_BITS);
  224. BitMask = BitMask << BitShift;
  225. LanaFlags[DwordOffset] |= BitMask;
  226. }
  227. BOOL
  228. LanaFlagIsSet(
  229. UCHAR uCharLanaNum
  230. )
  231. {
  232. DWORD LanaNum = (DWORD)uCharLanaNum;
  233. DWORD BitMask=1;
  234. DWORD DwordOffset;
  235. DWORD BitShift;
  236. DwordOffset = LanaNum / NUM_DWORD_BITS;
  237. if (DwordOffset > LANA_NUM_DWORDS) {
  238. return(FALSE);
  239. }
  240. BitShift = LanaNum - (DwordOffset * NUM_DWORD_BITS);
  241. BitMask = BitMask << BitShift;
  242. return ((BOOL) LanaFlags[DwordOffset] & BitMask );
  243. }