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.

295 lines
7.1 KiB

  1. /*++
  2. Copyright (c) 1991-92 Microsoft Corporation
  3. Module Name:
  4. alconfig.c
  5. Abstract:
  6. This module contains the Alerter service configuration routines.
  7. Author:
  8. Rita Wong (ritaw) 16-July-1991
  9. Revision History:
  10. --*/
  11. #include "alconfig.h"
  12. #include <tstr.h> // STRCPY(), etc.
  13. STATIC
  14. NET_API_STATUS
  15. AlGetLocalComputerName(
  16. VOID
  17. );
  18. //-------------------------------------------------------------------//
  19. // //
  20. // Global variables //
  21. // //
  22. //-------------------------------------------------------------------//
  23. //
  24. // Alert names
  25. //
  26. LPSTR AlertNamesA; // For inclusion into message text (space-separated)
  27. LPTSTR AlertNamesW; // For sending message to (NULL-separated)
  28. //
  29. // Local computer name
  30. //
  31. LPSTR AlLocalComputerNameA;
  32. LPTSTR AlLocalComputerNameW;
  33. NET_API_STATUS
  34. AlGetAlerterConfiguration(
  35. VOID
  36. )
  37. /*++
  38. Routine Description:
  39. This routine reads in alerter configuration info which is the alert names.
  40. If a failure occurs, or alert names could not be found, the error is
  41. logged but it will not prevent the Alerter service from starting up.
  42. Arguments:
  43. AlUicCode - Supplies the termination code to the Service Controller.
  44. Return Value:
  45. NERR_Success or error getting the computer name.
  46. --*/
  47. {
  48. NET_API_STATUS status;
  49. LPNET_CONFIG_HANDLE AlerterSection;
  50. LPTSTR UnicodeAlertNames;
  51. LPSTR AnsiAlertNames;
  52. #ifdef UNICODE
  53. LPSTR Name; // for conversion from Unicode to ANSI
  54. #endif
  55. DWORD AlertNamesSize;
  56. LPWSTR SubString[1];
  57. TCHAR StatusString[25];
  58. AlertNamesA = NULL;
  59. AlertNamesW = NULL;
  60. //
  61. // Get the computer name.
  62. //
  63. if ((status = AlGetLocalComputerName()) != NERR_Success) {
  64. return status;
  65. }
  66. //
  67. // Open config file and get handle to the Alerter section
  68. //
  69. if ((status = NetpOpenConfigData(
  70. &AlerterSection,
  71. NULL, // local server
  72. SECT_NT_ALERTER,
  73. TRUE // read-only
  74. )) != NERR_Success) {
  75. NetpKdPrint(("[Alerter] Could not open config section %lu\n", status));
  76. SubString[0] = ultow(status, StatusString, 10);
  77. AlLogEvent(
  78. NELOG_Build_Name,
  79. 1,
  80. SubString
  81. );
  82. return NO_ERROR;
  83. }
  84. //
  85. // Get the alert names from the configuration file
  86. //
  87. if ((status = NetpGetConfigTStrArray(
  88. AlerterSection,
  89. ALERTER_KEYWORD_ALERTNAMES,
  90. &AlertNamesW // alloc and set ptr
  91. )) != NERR_Success) {
  92. NetpKdPrint(("[Alerter] Could not get alert names %lu\n", status));
  93. SubString[0] = ultow(status, StatusString, 10);
  94. AlLogEvent(
  95. NELOG_Build_Name,
  96. 1,
  97. SubString
  98. );
  99. AlertNamesW = NULL;
  100. goto CloseConfigFile;
  101. }
  102. AlertNamesSize = NetpTStrArraySize(AlertNamesW) / sizeof(TCHAR) * sizeof(CHAR);
  103. if ((AlertNamesA = (LPSTR) LocalAlloc(
  104. LMEM_ZEROINIT,
  105. AlertNamesSize
  106. )) == NULL) {
  107. NetpKdPrint(("[Alerter] Error allocating AlertNamesA %lu\n", GetLastError()));
  108. NetApiBufferFree(AlertNamesW);
  109. AlertNamesW = NULL;
  110. goto CloseConfigFile;
  111. }
  112. AnsiAlertNames = AlertNamesA;
  113. UnicodeAlertNames = AlertNamesW;
  114. //
  115. // Canonicalize alert names, and convert the unicode names to ANSI
  116. //
  117. while (*UnicodeAlertNames != TCHAR_EOS) {
  118. AlCanonicalizeMessageAlias(UnicodeAlertNames);
  119. #ifdef UNICODE
  120. Name = NetpAllocStrFromWStr(UnicodeAlertNames);
  121. if (Name != NULL) {
  122. (void) strcpy(AnsiAlertNames, Name);
  123. AnsiAlertNames += (strlen(AnsiAlertNames) + 1);
  124. }
  125. (void) NetApiBufferFree(Name);
  126. #else
  127. (void) strcpy(AnsiAlertNames, UnicodeAlertNames);
  128. AnsiAlertNames += (strlen(AnsiAlertNames) + 1);
  129. #endif
  130. UnicodeAlertNames += (STRLEN(UnicodeAlertNames) + 1);
  131. }
  132. //
  133. // Substitute the NULL terminators, which separate the alert names,
  134. // in AlertNamesA with spaces. There's a space after the last alert
  135. // name.
  136. //
  137. AnsiAlertNames = AlertNamesA;
  138. while (*AnsiAlertNames != AL_NULL_CHAR) {
  139. AnsiAlertNames = strchr(AnsiAlertNames, AL_NULL_CHAR);
  140. *AnsiAlertNames++ = AL_SPACE_CHAR;
  141. }
  142. CloseConfigFile:
  143. (void) NetpCloseConfigData( AlerterSection );
  144. //
  145. // Errors from reading AlertNames should be ignored so we always
  146. // return success here.
  147. //
  148. return NERR_Success;
  149. }
  150. STATIC
  151. NET_API_STATUS
  152. AlGetLocalComputerName(
  153. VOID
  154. )
  155. /*++
  156. Routine Description:
  157. This function gets the local computer name and stores both the ANSI
  158. and Unicode versions of it.
  159. Arguments:
  160. None. Sets the global pointers AlLocalComputerNameA and
  161. AlLocalComputerNameW.
  162. Return Value:
  163. NERR_Success or error getting the local computer name.
  164. --*/
  165. {
  166. NET_API_STATUS status;
  167. AlLocalComputerNameA = NULL;
  168. AlLocalComputerNameW = NULL;
  169. if ((status = NetpGetComputerName(
  170. &AlLocalComputerNameW
  171. )) != NERR_Success) {
  172. AlLocalComputerNameW = NULL;
  173. return status;
  174. }
  175. AlCanonicalizeMessageAlias(AlLocalComputerNameW);
  176. //
  177. // Convert the computer name into ANSI
  178. //
  179. #ifdef UNICODE
  180. AlLocalComputerNameA = NetpAllocStrFromWStr(AlLocalComputerNameW);
  181. if (AlLocalComputerNameA == NULL) {
  182. status = ERROR_NOT_ENOUGH_MEMORY;
  183. }
  184. #else
  185. status = NetApiBufferAllocate(
  186. STRSIZE(AlLocalComputerNameW),
  187. &AlLocalComputerNameA
  188. );
  189. if (status == NERR_Success) {
  190. (void) strcpy(AlLocalComputerNameA, AlLocalComputerNameW);
  191. }
  192. else {
  193. AlLocalComputerNameA = NULL;
  194. }
  195. #endif
  196. return status;
  197. }
  198. VOID
  199. AlLogEvent(
  200. DWORD MessageId,
  201. DWORD NumberOfSubStrings,
  202. LPWSTR *SubStrings
  203. )
  204. {
  205. HANDLE LogHandle;
  206. LogHandle = RegisterEventSourceW (
  207. NULL,
  208. SERVICE_ALERTER
  209. );
  210. if (LogHandle == NULL) {
  211. NetpKdPrint(("[Alerter] RegisterEventSourceW failed %lu\n",
  212. GetLastError()));
  213. return;
  214. }
  215. (void) ReportEventW(
  216. LogHandle,
  217. EVENTLOG_ERROR_TYPE,
  218. 0, // event category
  219. MessageId,
  220. (PSID) NULL, // no SID
  221. (WORD)NumberOfSubStrings,
  222. 0,
  223. SubStrings,
  224. (PVOID) NULL
  225. );
  226. DeregisterEventSource(LogHandle);
  227. }