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.

398 lines
10 KiB

  1. /*****************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1990 **/
  4. /*****************************************************************/
  5. // data.c
  6. //
  7. // This file contains most of the data declarations and set up routines
  8. // used by the messenger service.
  9. //
  10. //
  11. // Revision History:
  12. // 02-Sep-1993 wlees
  13. // Provide synchronization between rpc routines and Pnp reconfiguration
  14. #include "msrv.h" // Message server declarations
  15. #include <rpc.h> // RPC_HANDLE
  16. #include <winsvc.h> // Defines for using service API
  17. #include <smbtypes.h> // needed for smb.h
  18. #include <smb.h> // Server Message Block definition
  19. #include <netlib.h> // UNUSED macro
  20. #include <align.h> // ROUND_UP_POINTER
  21. #include "msgdbg.h" // MSG_LOG
  22. #include <svcs.h> // Intrinsic service data
  23. GLOBAL_DATA GlobalData;
  24. HANDLE wakeupEvent; // Master copy of wakeup event
  25. HANDLE GrpMailslotHandle = INVALID_HANDLE_VALUE; // Event to signal mailslot has data
  26. PHANDLE wakeupSem; // Semaphores to clear on NCB completion
  27. HANDLE AddrChangeEvent;
  28. OVERLAPPED AddrChangeOverlapped;
  29. //
  30. // Other Global Data
  31. //
  32. // The other misc. global data that the messenger uses.
  33. //
  34. DWORD MsgsvcDebugLevel; // Debug level flag used by MSG_LOG
  35. LPTSTR MessageFileName;
  36. //
  37. // The local machine name and length/
  38. //
  39. TCHAR machineName[NCBNAMSZ+sizeof(TCHAR)];
  40. SHORT MachineNameLen;
  41. SHORT mgid; // The message group i.d. counter
  42. //
  43. // The following is used to keep store the state of the messenger service
  44. // Either it is RUNNING or STOPPING.
  45. //
  46. DWORD MsgrState;
  47. //
  48. // Handle returned by RegisterServiceCtrlHandle and needed to
  49. // set the service status via SetServiceStatus
  50. //
  51. SERVICE_STATUS_HANDLE MsgrStatusHandle;
  52. //
  53. // This string is used to mark the location of the time string in
  54. // a message header so that the display thread can find after it reads
  55. // it from the queue.
  56. //
  57. LPSTR GlobalTimePlaceHolder = "***";
  58. LPWSTR GlobalTimePlaceHolderUnicode = L"***";
  59. //
  60. // This is the string used in the title bar of the Message Box used
  61. // to display messages.
  62. // GlobalMessageBoxTitle will either point to the default string, or
  63. // to the string allocated in the FormatMessage Function.
  64. //
  65. WCHAR DefaultMessageBoxTitle[]= L"Messenger Service";
  66. LPWSTR GlobalAllocatedMsgTitle=NULL;
  67. LPWSTR GlobalMessageBoxTitle=DefaultMessageBoxTitle;
  68. //
  69. // This is where well-known SIDs and pointers to RpcServer routines are
  70. // stored.
  71. //
  72. PSVCHOST_GLOBAL_DATA MsgsvcGlobalData;
  73. //
  74. // Functions
  75. //
  76. // The following routines are defined for creating and destroying the
  77. // data (arrays, etc.) defined above.
  78. //
  79. /* MsgInitSupportSeg
  80. *
  81. * Allocates and initializes the segment containing the Support
  82. * arrays.
  83. *
  84. */
  85. NET_API_STATUS
  86. MsgInitSupportSeg(VOID)
  87. {
  88. unsigned int size;
  89. DWORD i;
  90. char far * memPtr;
  91. DWORD status;
  92. //
  93. // Calculate the buffer size.
  94. // *ALIGNMENT* (Note the extra four bytes for alignment)
  95. //
  96. size = ((SD_NUMNETS() + 1) * sizeof(HANDLE));
  97. wakeupSem = (PHANDLE) LocalAlloc(LMEM_ZEROINIT, size);
  98. if (wakeupSem == NULL) {
  99. status = GetLastError();
  100. MSG_LOG(ERROR,"[MSG]InitSupportSeg:LocalAlloc Failure %X\n", status);
  101. return(status);
  102. }
  103. return (NERR_Success);
  104. }
  105. VOID
  106. MsgFreeSupportSeg(VOID)
  107. {
  108. HANDLE status;
  109. status = LocalFree (wakeupSem);
  110. if (status != 0) {
  111. MSG_LOG(ERROR,"FreeSupportSeg:LocalFree Failed %X\n",
  112. GetLastError());
  113. }
  114. wakeupSem = NULL;
  115. return;
  116. }
  117. BOOL
  118. MsgDatabaseLock(
  119. IN MSG_LOCK_REQUEST request,
  120. IN LPSTR idString
  121. )
  122. /*++
  123. Routine Description:
  124. This routine handles all access to the Messenger Service database
  125. lock. This lock is used to protect access in the shared data segment.
  126. Reading the Database is handled with shared access. This allows several
  127. threads to read the database at the same time.
  128. Writing (or modifying) the database is handled with exclusive access.
  129. This access is not granted if other threads have read access. However,
  130. shared access can be made into exclusive access as long as no other
  131. threads have shared or exclusive access.
  132. Arguments:
  133. request - This indicates what should be done with the lock. Lock
  134. requests are listed in dataman.h
  135. idString - This is a string that identifies who is requesting the lock.
  136. This is used for debugging purposes so I can see where in the code
  137. a request is coming from.
  138. Return Value:
  139. none:
  140. --*/
  141. {
  142. BOOL fRet = TRUE;
  143. NTSTATUS status;
  144. static RTL_RESOURCE MSG_DatabaseLock;
  145. static BOOL s_fInitialized;
  146. switch(request) {
  147. case MSG_INITIALIZE:
  148. if (!s_fInitialized)
  149. {
  150. status = MsgInitResource(&MSG_DatabaseLock);
  151. if (!NT_SUCCESS(status))
  152. {
  153. MSG_LOG1(ERROR,
  154. "MsgDatabaseLock: MsgInitResource failed %#x\n",
  155. status);
  156. fRet = FALSE;
  157. }
  158. else
  159. {
  160. s_fInitialized = TRUE;
  161. }
  162. }
  163. break;
  164. case MSG_GET_SHARED:
  165. MSG_LOG(LOCKS,"%s:Asking for MSG Database Lock shared...\n",idString);
  166. fRet = RtlAcquireResourceShared( &MSG_DatabaseLock, TRUE );
  167. MSG_LOG(LOCKS,"%s:Acquired MSG Database Lock shared\n",idString);
  168. break;
  169. case MSG_GET_EXCLUSIVE:
  170. MSG_LOG(LOCKS,"%s:Asking for MSG Database Lock exclusive...\n",idString);
  171. fRet = RtlAcquireResourceExclusive( &MSG_DatabaseLock, TRUE );
  172. MSG_LOG(LOCKS,"%s:Acquired MSG Database Lock exclusive\n",idString);
  173. break;
  174. case MSG_RELEASE:
  175. MSG_LOG(LOCKS,"%s:Releasing MSG Database Lock...\n",idString);
  176. RtlReleaseResource( &MSG_DatabaseLock );
  177. MSG_LOG(LOCKS,"%s:Released MSG Database Lock\n",idString);
  178. break;
  179. default:
  180. break;
  181. }
  182. return fRet;
  183. }
  184. BOOL
  185. MsgConfigurationLock(
  186. IN MSG_LOCK_REQUEST request,
  187. IN LPSTR idString
  188. )
  189. /*++
  190. Routine Description:
  191. This routine handles all access to the Messenger Service Pnp Configuration
  192. lock. This lock is used to protect access in the shared data segment.
  193. Reading the Database is handled with shared access. This allows several
  194. threads to read the database at the same time.
  195. Writing (or modifying) the database is handled with exclusive access.
  196. This access is not granted if other threads have read access. However,
  197. shared access can be made into exclusive access as long as no other
  198. threads have shared or exclusive access.
  199. Arguments:
  200. request - This indicates what should be done with the lock. Lock
  201. requests are listed in dataman.h
  202. idString - This is a string that identifies who is requesting the lock.
  203. This is used for debugging purposes so I can see where in the code
  204. a request is coming from.
  205. Return Value:
  206. none:
  207. --*/
  208. {
  209. BOOL fRet = TRUE;
  210. NTSTATUS status;
  211. static RTL_RESOURCE MSG_ConfigurationLock;
  212. static BOOL s_fInitialized;
  213. switch(request) {
  214. case MSG_INITIALIZE:
  215. if (!s_fInitialized)
  216. {
  217. status = MsgInitResource(&MSG_ConfigurationLock);
  218. if (!NT_SUCCESS(status))
  219. {
  220. MSG_LOG1(ERROR,
  221. "MsgConfigurationLock: MsgInitResource failed %#x\n",
  222. status);
  223. fRet = FALSE;
  224. }
  225. else
  226. {
  227. s_fInitialized = TRUE;
  228. }
  229. }
  230. break;
  231. case MSG_GET_SHARED:
  232. MSG_LOG(LOCKS,"%s:Asking for MSG Configuration Lock shared...\n",idString);
  233. fRet = RtlAcquireResourceShared( &MSG_ConfigurationLock, TRUE );
  234. MSG_LOG(LOCKS,"%s:Acquired MSG Configuration Lock shared\n",idString);
  235. break;
  236. case MSG_GET_EXCLUSIVE:
  237. MSG_LOG(LOCKS,"%s:Asking for MSG Configuration Lock exclusive...\n",idString);
  238. fRet = RtlAcquireResourceExclusive( &MSG_ConfigurationLock, TRUE );
  239. MSG_LOG(LOCKS,"%s:Acquired MSG Configuration Lock exclusive\n",idString);
  240. break;
  241. case MSG_RELEASE:
  242. MSG_LOG(LOCKS,"%s:Releasing MSG Configuration Lock...\n",idString);
  243. RtlReleaseResource( &MSG_ConfigurationLock );
  244. MSG_LOG(LOCKS,"%s:Released MSG Configuration Lock\n",idString);
  245. break;
  246. default:
  247. break;
  248. }
  249. return fRet;
  250. }
  251. NTSTATUS
  252. MsgInitCriticalSection(
  253. PRTL_CRITICAL_SECTION pCritsec
  254. )
  255. {
  256. NTSTATUS ntStatus;
  257. //
  258. // RtlInitializeCriticalSection will raise an exception
  259. // if it runs out of resources
  260. //
  261. try
  262. {
  263. ntStatus = RtlInitializeCriticalSection(pCritsec);
  264. if (!NT_SUCCESS(ntStatus))
  265. {
  266. MSG_LOG1(ERROR,
  267. "MsgInitCriticalSection: RtlInitializeCriticalSection failed %#x\n",
  268. ntStatus);
  269. }
  270. }
  271. except(EXCEPTION_EXECUTE_HANDLER)
  272. {
  273. MSG_LOG1(ERROR,
  274. "MsgInitCriticalSection: Exception %#x caught initializing critsec\n",
  275. GetExceptionCode());
  276. ntStatus = STATUS_NO_MEMORY;
  277. }
  278. return ntStatus;
  279. }
  280. NTSTATUS
  281. MsgInitResource(
  282. PRTL_RESOURCE pResource
  283. )
  284. {
  285. NTSTATUS ntStatus = STATUS_SUCCESS;
  286. //
  287. // RtlInitializeResource will raise an exception
  288. // if it runs out of resources
  289. //
  290. try
  291. {
  292. RtlInitializeResource(pResource);
  293. }
  294. except(EXCEPTION_EXECUTE_HANDLER)
  295. {
  296. MSG_LOG1(ERROR,
  297. "MsgInitResource: Exception %#x caught initializing resource\n",
  298. GetExceptionCode());
  299. ntStatus = STATUS_NO_MEMORY;
  300. }
  301. return ntStatus;
  302. }