Source code of Windows XP (NT5)
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.

976 lines
26 KiB

  1. /********************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1987-1992 **/
  4. /********************************************************************/
  5. /*
  6. ** Routines to log messages
  7. **
  8. ** If message logging is off, all messages are buffered. Further,
  9. ** even if messages are being logged, multi-block messages must
  10. ** be buffered since they must be spooled to the logging file or
  11. ** device. Since there is only one message buffer in which to
  12. ** buffer all messages, this buffer must be managed as a heap.
  13. ** Also, messages are logged in a first-in-first-out manner,
  14. ** so messages in the buffer must be kept in a queue. In order
  15. ** to meet these goals, the following message blocks are defined:
  16. **
  17. ** SBM - single-block message
  18. **
  19. ** length - length of entire block (2 bytes)
  20. ** code - identifies block as single-block message (1 byte)
  21. ** link - link to next message in message queue (2 bytes)
  22. ** date - date message received (2 bytes)
  23. ** time - time message received (2 bytes)
  24. ** from - name of sender (null-terminated string)
  25. ** to - name of recipient (null-terminated string)
  26. ** text - text of message (remainder of block)
  27. **
  28. ** MBB - multi-block message header
  29. **
  30. ** length - length of entire block (2 bytes)
  31. ** code - identifies block as multi-block message header (1 byte)
  32. ** link - link to next message in message queue (2 bytes)
  33. ** date - date message received (2 bytes)
  34. ** time - time message received (2 bytes)
  35. ** btext - link to last text block (2 bytes)
  36. ** ftext - link to first text block (2 bytes)
  37. ** error - error flag (1 byte)
  38. ** from - name of sender (null-terminated string)
  39. ** to - name of recipient (null-terminated string)
  40. **
  41. ** MBT - multi-block message text block
  42. **
  43. ** length - length of entire block (2 bytes)
  44. ** code - identifies block a multi-block message text (1 byte)
  45. ** link - link to next text block (2 bytes)
  46. ** text - text of message (remainder of block)
  47. **/
  48. //
  49. // Includes
  50. //
  51. #include "msrv.h"
  52. #include <string.h> // memcpy
  53. #include <tstring.h> // Unicode string macros
  54. #include <netdebug.h> // NetpAssert
  55. #include <lmalert.h> // Alert stuff
  56. #include <netlib.h> // UNUSED macro
  57. #include <netlibnt.h> // NetpNtStatusToApiStatus
  58. #include <netdebug.h> // NetpDbgHexDump
  59. #include <smbtypes.h> // needed for smb.h
  60. #include <smb.h> // Server Message Block definitions
  61. #include <lmerrlog.h> // NELOG_ messages
  62. #include <smbgtpt.h> // SMB field manipulation macros
  63. #include <winuser.h> // MessageBox
  64. #include <winsock2.h> // Windows sockets
  65. #include "msgdbg.h" // MSG_LOG
  66. #include "msgdata.h"
  67. //
  68. // Defines for Hex Dump Function
  69. //
  70. #ifndef MIN
  71. #define MIN(a,b) ( ( (a) < (b) ) ? (a) : (b) )
  72. #endif
  73. #define DWORDS_PER_LINE 4
  74. #define BYTES_PER_LINE (DWORDS_PER_LINE * sizeof(DWORD))
  75. #define SPACE_BETWEEN_BYTES NetpKdPrint((" "))
  76. #define SPACE_BETWEEN_DWORDS NetpKdPrint((" "))
  77. //
  78. // Local Functions
  79. //
  80. NET_API_STATUS
  81. MsgOutputMsg (
  82. USHORT AlertLength,
  83. LPSTR AlertBuffer,
  84. ULONG SessionId,
  85. SYSTEMTIME BigTime
  86. );
  87. #if DBG
  88. VOID
  89. MsgDbgHexDumpLine(
  90. IN LPBYTE StartAddr,
  91. IN DWORD BytesInThisLine
  92. );
  93. VOID
  94. MsgDbgHexDump(
  95. IN LPBYTE StartAddr,
  96. IN DWORD Length
  97. );
  98. #endif //DBG
  99. //
  100. // Data
  101. //
  102. PSTD_ALERT alert_buf_ptr; // Pointer to DosAlloc'ed alert buffer
  103. USHORT alert_len; // Currently used length of alert buffer
  104. //
  105. // Defines
  106. //
  107. #define ERROR_LOG_SIZE 1024
  108. /*
  109. ** Msglogmbb - log a multi-block message header
  110. **
  111. ** This function is called to log a multi-block message header.
  112. ** The message header is placed in the message buffer which resides
  113. ** in the shared data area.
  114. **
  115. ** This function stores the from and to information in the shared data
  116. ** buffer and initializes the multi-block message header. Then it puts
  117. ** a pointer to the multi-block header into the shared data pointer
  118. ** location for that net index and name index.
  119. **
  120. ** logmbb (from, to, net, ncbi)
  121. **
  122. ** ENTRY
  123. ** from - sender name
  124. ** to - recipient name
  125. ** net - network index
  126. ** ncbi - Network Control Block index
  127. **
  128. ** RETURN
  129. ** zero if successful, non-zero if unable to buffer the message header
  130. **
  131. ** SIDE EFFECTS
  132. **
  133. ** Calls heapalloc() to obtain buffer space.
  134. **/
  135. DWORD
  136. Msglogmbb(
  137. LPSTR from, // Name of sender
  138. LPSTR to, // Name of recipient
  139. DWORD net, // Which network ?
  140. DWORD ncbi // Network Control Block index
  141. )
  142. {
  143. DWORD i; // Heap index
  144. LPSTR fcp; // Far character pointer
  145. LONG ipAddress;
  146. struct hostent *pHostEntry;
  147. //
  148. // Synchronize with Pnp configuration routine
  149. //
  150. MsgConfigurationLock(MSG_GET_SHARED,"Msglogmbb");
  151. //
  152. // Block until the shared database is free
  153. //
  154. MsgDatabaseLock(MSG_GET_EXCLUSIVE,"logmbb");
  155. //
  156. // Check whether the recipient name needs to be formatted
  157. //
  158. ipAddress = inet_addr( to );
  159. if (ipAddress != INADDR_NONE) {
  160. pHostEntry = gethostbyaddr( (char *)&ipAddress,sizeof( LONG ),AF_INET);
  161. if (pHostEntry) {
  162. to = pHostEntry->h_name;
  163. } else {
  164. MSG_LOG2(ERROR,"Msglogmbb: could not lookup addr %s, error %d\n",
  165. to, WSAGetLastError());
  166. }
  167. }
  168. //
  169. // Allocate space for header
  170. //
  171. i = Msgheapalloc(sizeof(MBB) + strlen(from) + strlen(to) + 2);
  172. if(i == INULL) { // If no buffer space
  173. //
  174. // Unlock the shared database
  175. //
  176. MsgDatabaseLock(MSG_RELEASE,"logmbb");
  177. MsgConfigurationLock(MSG_RELEASE,"Msglogmbb");
  178. return((int) i); // Log fails
  179. }
  180. //
  181. // Multi-block message
  182. //
  183. MBB_CODE(*MBBPTR(i)) = SMB_COM_SEND_START_MB_MESSAGE;
  184. MBB_NEXT(*MBBPTR(i)) = INULL; // Last message in buffer
  185. GetLocalTime(&MBB_BIGTIME(*MBBPTR(i))); // Time of message
  186. MBB_BTEXT(*MBBPTR(i)) = INULL; // No text yet
  187. MBB_FTEXT(*MBBPTR(i)) = INULL; // No text yet
  188. MBB_STATE(*MBBPTR(i)) = MESCONT; // Message in progress
  189. fcp = CPTR(i + sizeof(MBB)); // Get far pointer into buffer
  190. strcpy(fcp, from); // Copy the sender name
  191. fcp += strlen(from) + 1; // Increment pointer
  192. strcpy(fcp, to); // Copy the recipient name
  193. SD_MESPTR(net,ncbi) = i; // Save index to this record
  194. //
  195. // Unlock the shared database
  196. //
  197. MsgDatabaseLock(MSG_RELEASE,"logmbb");
  198. MsgConfigurationLock(MSG_RELEASE,"Msglogmbb");
  199. return(0); // Message logged successfully
  200. }
  201. /*
  202. ** Msglogmbe - log end of a multi-block message
  203. **
  204. ** This function is called to log a multi-block message end.
  205. ** The message is marked as finished, and if logging is enabled,
  206. ** an attempt is made to write the message to the log file. If
  207. ** this attempt fails, or if logging is disabled, then the message
  208. ** is placed in the message queue in the message buffer.
  209. **
  210. ** The message is gathered up and placed in the alert buffer and an alert
  211. ** is raised.
  212. **
  213. ** logmbe (state, net,ncbi)
  214. **
  215. ** ENTRY
  216. ** state - final state of message
  217. ** net - Network index
  218. ** ncbi - Network Control Block index
  219. **
  220. ** RETURN
  221. ** int - BUFFERED if the message is left in the buffer
  222. ** int - LOGGED if the message is written to the log file
  223. **
  224. ** FOR NT:
  225. ** SMB_ERR_SUCCESS - success in alerting
  226. ** SMB_ERR_... - an error occured
  227. **
  228. **
  229. **
  230. ** SIDE EFFECTS
  231. **
  232. ** Calls mbmprint() to print the message if logging is enabled. Calls
  233. ** mbmfree() to free the message if logging succeeds.
  234. **/
  235. UCHAR
  236. Msglogmbe(
  237. DWORD state, // Final state of message
  238. DWORD net, // Which network?
  239. DWORD ncbi // Network Control Block index
  240. )
  241. {
  242. DWORD i; // Heap index
  243. DWORD error; // Error code
  244. DWORD meslog; // Message logging status
  245. DWORD alert_flag; // Alert buffer allocated flag
  246. DWORD status; // Dos error for error log
  247. DWORD bufSize; // Buffer Size
  248. SYSTEMTIME bigtime; // Date and time of message
  249. PMSG_SESSION_ID_ITEM pItem;
  250. PLIST_ENTRY pHead;
  251. PLIST_ENTRY pList;
  252. //
  253. // Synchronize with Pnp configuration routine
  254. //
  255. MsgConfigurationLock(MSG_GET_SHARED,"Msglogmbe");
  256. //
  257. // Block until the shared database is free
  258. //
  259. MsgDatabaseLock(MSG_GET_EXCLUSIVE,"logmbe");
  260. pHead = &(SD_SIDLIST(net,ncbi));
  261. pList = pHead;
  262. //
  263. // First get a buffer for an alert
  264. //
  265. bufSize = sizeof( STD_ALERT) +
  266. ALERT_MAX_DISPLAYED_MSG_SIZE +
  267. (2*TXTMAX) + 2;
  268. alert_buf_ptr = (PSTD_ALERT)LocalAlloc(LMEM_ZEROINIT, bufSize);
  269. if (alert_buf_ptr == NULL) {
  270. MSG_LOG(ERROR,"logmbe:Local Alloc failed\n",0);
  271. alert_flag = 0xffffffff; // No alerting if Alloc failed
  272. }
  273. else {
  274. alert_flag = 0; // File and alerting
  275. alert_len = 0;
  276. }
  277. error = 0; // Assume no error
  278. i = SD_MESPTR(net,ncbi); // Get index to message header
  279. MBB_STATE(*MBBPTR(i)) = state; // Record final state
  280. //
  281. // If logging now disabled ...
  282. //
  283. if(!SD_MESLOG())
  284. {
  285. if( alert_flag == 0)
  286. {
  287. //
  288. // Format the message and put it in the alert buffer.
  289. //
  290. // Alert only. alert_flag is only modified if Msgmbmprint
  291. // returns success and we should skip the message (i.e.,
  292. // it's a print notification from a pre-Whistler machine).
  293. //
  294. if (Msgmbmprint(1,i,0, &alert_flag))
  295. {
  296. alert_flag = 0xffffffff;
  297. }
  298. }
  299. }
  300. //
  301. // Add message to buffer queue if logging is off,
  302. // or if the attempt to log the message failed.
  303. //
  304. meslog = SD_MESLOG(); // Get logging status
  305. if(!meslog) { // If logging disabled
  306. Msgmbmfree(i);
  307. }
  308. if(error != 0) {
  309. //
  310. // Report to error log
  311. //
  312. NetpAssert(0); // NT code should never get here.
  313. MsgErrorLogWrite(
  314. error,
  315. SERVICE_MESSENGER,
  316. (LPBYTE)&status,
  317. sizeof(DWORD),
  318. NULL,
  319. 0);
  320. }
  321. //
  322. // Now alert and free up alert buffer if it was successfully allocated
  323. //
  324. if( alert_flag == 0) {
  325. //
  326. // There is an alert buffer, output it.
  327. //
  328. GetLocalTime(&bigtime); // Get the time
  329. if (g_IsTerminalServer)
  330. {
  331. //
  332. // Output the message for all the sessions sharing that name
  333. //
  334. while (pList->Flink != pHead) // loop all over the list
  335. {
  336. pList = pList->Flink;
  337. pItem = CONTAINING_RECORD(pList, MSG_SESSION_ID_ITEM, List);
  338. MsgOutputMsg(alert_len, (LPSTR)alert_buf_ptr, pItem->SessionId, bigtime);
  339. }
  340. }
  341. else // regular NT
  342. {
  343. MsgOutputMsg(alert_len, (LPSTR)alert_buf_ptr, 0, bigtime);
  344. }
  345. }
  346. LocalFree(alert_buf_ptr);
  347. //
  348. // Unlock the shared database
  349. //
  350. MsgDatabaseLock(MSG_RELEASE,"logmbe");
  351. MsgConfigurationLock(MSG_RELEASE,"Msglogmbe");
  352. return(SMB_ERR_SUCCESS); // Message arrived
  353. }
  354. /*
  355. ** Msglogmbt - log a multi-block message text block
  356. **
  357. ** This function is called to log a multi-block message text block.
  358. ** The text block is placed in the message buffer which resides
  359. ** in the shared data area. If there is insufficient room in the
  360. ** buffer, logmbt() removes the header and any previous blocks of
  361. ** the message from the buffer.
  362. **
  363. ** This function gets the current message from the message pointer in
  364. ** the shared data (for that net & name index). It looks in the header
  365. ** to see if there are any text blocks already there. If so, it adds
  366. ** this new one to the list and fixes the last block pointer to point to
  367. ** it.
  368. **
  369. ** logmbt (text, net, ncbi)
  370. **
  371. ** ENTRY
  372. ** text - text header
  373. ** net - Network index
  374. ** ncbi - Network Control Block index
  375. **
  376. ** RETURN
  377. ** zero if successful, non-zero if unable to buffer the message header
  378. **
  379. ** SIDE EFFECTS
  380. **
  381. ** Calls heapalloc() to obtain buffer space. Calls mbmfree() if a call to
  382. ** heapalloc() fails.
  383. **/
  384. DWORD
  385. Msglogmbt(
  386. LPSTR text, // Text of message
  387. DWORD net, // Which network?
  388. DWORD ncbi // Network Control Block index
  389. )
  390. {
  391. DWORD i; // Heap index
  392. DWORD j; // Heap index
  393. DWORD k; // Heap index
  394. USHORT length; // Length of text
  395. //
  396. // Synchronize with Pnp configuration routine
  397. //
  398. MsgConfigurationLock(MSG_GET_SHARED,"Msglogmbt");
  399. // *ALIGNMENT*
  400. length = SmbGetUshort( (PUSHORT)text); // Get length of text block
  401. // length = *((PSHORT) text); // Get length of text block
  402. text += sizeof(short); // Skip over length word
  403. //
  404. // Block until the shared database is free
  405. //
  406. MsgDatabaseLock(MSG_GET_EXCLUSIVE,"logmbt");
  407. i = Msgheapalloc(sizeof(MBT) + length); // Allocate space for block
  408. //
  409. // If buffer space is available
  410. //
  411. if(i != INULL) {
  412. //
  413. // Multi-block message text
  414. //
  415. MBT_CODE(*MBTPTR(i)) = SMB_COM_SEND_TEXT_MB_MESSAGE;
  416. MBT_NEXT(*MBTPTR(i)) = INULL; // Last text block so far
  417. MBT_COUNT(*MBTPTR(i)) = (DWORD)length; // *ALIGNMENT2*
  418. memcpy(CPTR(i + sizeof(MBT)), text, length);
  419. // Copy text into buffer
  420. j = SD_MESPTR(net, ncbi); // Get index to current message
  421. if(MBB_FTEXT(*MBBPTR(j)) != INULL) {
  422. //
  423. // If there is text already, Get pointer to last block and
  424. // add new block
  425. //
  426. k = MBB_BTEXT(*MBBPTR(j)); // Get pointer to last block
  427. MBT_NEXT(*MBTPTR(k)) = i; // Add new block
  428. }
  429. else {
  430. MBB_FTEXT(*MBBPTR(j)) = i; // Else set front pointer
  431. }
  432. MBB_BTEXT(*MBBPTR(j)) = i; // Set back pointer
  433. i = 0; // Success
  434. }
  435. else {
  436. Msgmbmfree(SD_MESPTR(net,ncbi)); // Else deallocate the message
  437. }
  438. //
  439. // Unlock the shared database
  440. //
  441. MsgDatabaseLock(MSG_RELEASE,"logmbt");
  442. MsgConfigurationLock(MSG_RELEASE,"Msglogmbt");
  443. return((int) i); // Return status
  444. }
  445. /*
  446. ** Msglogsbm - log a single-block message
  447. **
  448. ** This function is called to log a single-block message. If
  449. ** logging is enabled, the message is written directly to the
  450. ** logging file or device. If logging is disabled or if the
  451. ** attempt to log the message fails, the message is placed in
  452. ** the message buffer which resides in the shared data area.
  453. **
  454. ** logsbm (from, to, text)
  455. **
  456. ** ENTRY
  457. ** from - sender name
  458. ** to - recipient name
  459. ** text - text of message
  460. **
  461. ** RETURN
  462. ** zero if successful, non-zero if unable to log the message
  463. **
  464. ** SIDE EFFECTS
  465. **
  466. ** Calls hdrprint(), txtprint(), and endprint() to print the message if
  467. ** logging is enabled. Calls heapalloc() to obtain buffer space if
  468. ** the message must be buffered.
  469. **/
  470. DWORD
  471. Msglogsbm(
  472. LPSTR from, // Name of sender
  473. LPSTR to, // Name of recipient
  474. LPSTR text, // Text of message
  475. ULONG SessionId // Session Id
  476. )
  477. {
  478. DWORD i; // Heap index
  479. DWORD error; // Error code
  480. SHORT length; // Length of text
  481. DWORD meslog; // Message logging status
  482. DWORD alert_flag; // Alert buffer allocated flag
  483. DWORD status; // DOS error from mespeint functions
  484. SYSTEMTIME bigtime; // Date and time of message
  485. DWORD bufSize; // Buffer Size
  486. //
  487. // Synchronize with Pnp configuration routine
  488. //
  489. MsgConfigurationLock(MSG_GET_SHARED,"Msglogsbm");
  490. //
  491. // Block until the shared database is free
  492. //
  493. MsgDatabaseLock(MSG_GET_EXCLUSIVE,"logsbm");
  494. //
  495. // First get a buffer for an alert
  496. //
  497. bufSize = sizeof( STD_ALERT) +
  498. ALERT_MAX_DISPLAYED_MSG_SIZE +
  499. (2*TXTMAX) + 2;
  500. alert_buf_ptr = (PSTD_ALERT)LocalAlloc(LMEM_ZEROINIT, bufSize);
  501. if (alert_buf_ptr == NULL) {
  502. MSG_LOG(ERROR,"Msglogsbm:Local Alloc failed\n",0);
  503. alert_flag = 0xffffffff; // No alerting if Alloc failed
  504. }
  505. else {
  506. alert_flag = 0; // File and alerting
  507. alert_len = 0;
  508. }
  509. // *ALIGNMENT*
  510. length = SmbGetUshort( (PUSHORT)text); // Get length of text block
  511. text += sizeof(short); // Skip over length word
  512. error = 0; // Assume no errors
  513. //
  514. // Hack to drop messages sent by pre-Whistler Spoolers. As of
  515. // Whistler, print notifications are done as shell balloon tips
  516. // so don't display print alerts sent from the server as well.
  517. //
  518. // This check is also made in Msgmbmprint to catch multi-block messages.
  519. //
  520. if ((g_lpAlertSuccessMessage
  521. &&
  522. _strnicmp(text, g_lpAlertSuccessMessage, g_dwAlertSuccessLen) == 0)
  523. ||
  524. (g_lpAlertFailureMessage
  525. &&
  526. _strnicmp(text, g_lpAlertFailureMessage, g_dwAlertFailureLen) == 0))
  527. {
  528. MsgDatabaseLock(MSG_RELEASE,"logsbm");
  529. MsgConfigurationLock(MSG_RELEASE,"Msglogsbm");
  530. return 0;
  531. }
  532. GetLocalTime(&bigtime); // Get the time
  533. if(!SD_MESLOG()) // If logging disabled
  534. {
  535. if( alert_flag == 0) // If alert buf is valid
  536. {
  537. if (!Msghdrprint(1,from, to, bigtime,0))
  538. {
  539. if (Msgtxtprint(1, text,length,0))
  540. {
  541. alert_flag = 0xffffffff;
  542. }
  543. }
  544. else
  545. {
  546. alert_flag = 0xffffffff;
  547. }
  548. }
  549. }
  550. meslog = SD_MESLOG(); // Get logging status
  551. i = 0; // No way to fail if not logging
  552. if(error != 0) {
  553. DbgPrint("meslog.c:logsbm(before ErrorLogWrite): We should never get here\n");
  554. NetpAssert(0);
  555. MsgErrorLogWrite( // Report to error log
  556. error,
  557. SERVICE_MESSENGER,
  558. (LPBYTE)&status,
  559. sizeof(DWORD),
  560. NULL,
  561. 0);
  562. }
  563. // Now alert and free up alert buffer if it was successfully allocated
  564. if( alert_flag == 0) { // There is an alert buffer
  565. //
  566. // There is an alert buffer, output it.
  567. //
  568. MsgOutputMsg(alert_len, (LPSTR)alert_buf_ptr, SessionId, bigtime);
  569. }
  570. LocalFree(alert_buf_ptr);
  571. //
  572. // Unlock the shared database
  573. //
  574. MsgDatabaseLock(MSG_RELEASE,"logsbm");
  575. MsgConfigurationLock(MSG_RELEASE,"Msglogsbm");
  576. return((int) i); // Return status
  577. }
  578. NET_API_STATUS
  579. MsgErrorLogWrite(
  580. IN DWORD Code,
  581. IN LPTSTR Component,
  582. IN LPBYTE Buffer,
  583. IN DWORD BufferSize,
  584. IN LPSTR Strings,
  585. IN DWORD NumStrings
  586. )
  587. /*++
  588. Routine Description:
  589. Writes an entry to the event manager on the local computer.
  590. This function needs to get the error message text out of the message
  591. file and send it to the event logger.
  592. Arguments:
  593. Code - Specifies the code of the error that occured.
  594. Component - Points to a NUL terminated string that specifies which
  595. component encountered the error. UNICODE STRING.
  596. Buffer - Points to a string of raw data associated with the error
  597. condition.
  598. BufferSize - size (in bytes) of the buffer.
  599. Strings - NOT USED.
  600. Points to NUL terminated strings that contain the
  601. error message. ANSI STRINGS.
  602. NumStrings - NOT USED.
  603. Specifies how many concatenated NUL terminated strings
  604. are stored in Strings.
  605. Return Value:
  606. --*/
  607. {
  608. DWORD status;
  609. WORD msglen=0;
  610. LPBYTE msgBuf;
  611. //
  612. // Get a message associated with the message code from the message
  613. // file.
  614. //
  615. msgBuf = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, ERROR_LOG_SIZE);
  616. if (msgBuf == NULL) {
  617. status = GetLastError();
  618. MSG_LOG(ERROR,"MsgErrorLogWrite: LocalAlloc FAILURE %X\n",
  619. status);
  620. return(status);
  621. }
  622. //
  623. // TODO ITEM:
  624. // If we actually used strings, then they must be converted to unicode.
  625. // However, since they are never used, this isn't very important.
  626. //
  627. status = DosGetMessage (
  628. &Strings, // String substitution table
  629. (USHORT)NumStrings, // Num Entries in table above
  630. msgBuf, // Buffer receiving message
  631. ERROR_LOG_SIZE, // size of buffer receiving msg
  632. (USHORT)Code, // message num to retrieve
  633. MessageFileName, // Name of message file
  634. &msglen); // Num bytes returned
  635. if (status != NERR_Success) {
  636. LocalFree(msgBuf);
  637. return(status);
  638. }
  639. #if DBG
  640. DbgPrint("MsgErrorLogWrite: COMPONENT = %ws\n",Component);
  641. DbgPrint("MsgErrorLogWrite: %s\n",msgBuf);
  642. if ( Buffer != NULL )
  643. {
  644. MsgDbgHexDump( (LPBYTE)Buffer, BufferSize);
  645. }
  646. #endif //DBG
  647. UNREFERENCED_PARAMETER(Buffer);
  648. UNREFERENCED_PARAMETER(BufferSize);
  649. LocalFree(msgBuf);
  650. return(NERR_Success);
  651. }
  652. NET_API_STATUS
  653. MsgOutputMsg (
  654. USHORT AlertLength,
  655. LPSTR AlertBuffer,
  656. ULONG SessionId,
  657. SYSTEMTIME BigTime
  658. )
  659. /*++
  660. Routine Description:
  661. This function translates the alert buffer from an Ansi String to a
  662. Unicode String and outputs the buffer to whereever it is to go.
  663. Currently this just becomes a DbgPrint.
  664. Arguments:
  665. AlertLength - The number of bytes in the AlertBuffer.
  666. AlertBuffer - This is a pointer to the buffer that contains the message
  667. that is to be output. The buffer is expected to contain a
  668. NUL Terminated Ansi String.
  669. BigTime - The SYSTEMTIME that indicates the time the end of the
  670. messsage was received.
  671. Return Value:
  672. --*/
  673. {
  674. UNICODE_STRING unicodeString;
  675. OEM_STRING ansiString;
  676. NTSTATUS ntStatus;
  677. //
  678. // NUL Terminate the message.
  679. // Translate the Ansi message to a Unicode Message.
  680. //
  681. AlertBuffer[AlertLength++] = '\0';
  682. ansiString.Length = AlertLength;
  683. ansiString.MaximumLength = AlertLength;
  684. ansiString.Buffer = AlertBuffer;
  685. ntStatus = RtlOemStringToUnicodeString(
  686. &unicodeString, // Destination
  687. &ansiString, // Source
  688. TRUE); // Allocate the destination.
  689. if (!NT_SUCCESS(ntStatus)) {
  690. MSG_LOG(ERROR,
  691. "MsgOutputMsg:RtlOemStringToUnicodeString Failed rc=%X\n",
  692. ntStatus);
  693. //
  694. // EXPLANATION OF WHY IT RETURNS SUCCESS HERE.
  695. // Returning success even though the alert is not raised is
  696. // consistent with the LM2.0 code which doesn't check the
  697. // return code for the NetAlertRaise API anyway. Returning
  698. // anything else would require a re-design of how errors are
  699. // handled by the caller of this routine.
  700. //
  701. return(NERR_Success);
  702. }
  703. //*******************************************************************
  704. //
  705. // PUT THE MESSAGE IN THE DISPLAY QUEUE
  706. //
  707. MsgDisplayQueueAdd( AlertBuffer, (DWORD)AlertLength, SessionId, BigTime);
  708. //
  709. //
  710. //*******************************************************************
  711. RtlFreeUnicodeString(&unicodeString);
  712. return(NERR_Success);
  713. }
  714. #if DBG
  715. VOID
  716. MsgDbgHexDumpLine(
  717. IN LPBYTE StartAddr,
  718. IN DWORD BytesInThisLine
  719. )
  720. /*++
  721. Routine Description:
  722. Arguments:
  723. Return Value:
  724. --*/
  725. {
  726. LPBYTE BytePtr;
  727. DWORD BytesDone;
  728. DWORD HexPosition;
  729. DbgPrint(FORMAT_LPVOID " ", (LPVOID) StartAddr);
  730. BytePtr = StartAddr;
  731. BytesDone = 0;
  732. while (BytesDone < BytesInThisLine) {
  733. DbgPrint("%02X", *BytePtr); // space for "xx" (see pad below).
  734. SPACE_BETWEEN_BYTES;
  735. ++BytesDone;
  736. if ( (BytesDone % sizeof(DWORD)) == 0) {
  737. SPACE_BETWEEN_DWORDS;
  738. }
  739. ++BytePtr;
  740. }
  741. HexPosition = BytesDone;
  742. while (HexPosition < BYTES_PER_LINE) {
  743. DbgPrint(" "); // space for "xx" (see byte above).
  744. SPACE_BETWEEN_BYTES;
  745. ++HexPosition;
  746. if ( (HexPosition % sizeof(DWORD)) == 0) {
  747. SPACE_BETWEEN_DWORDS;
  748. }
  749. }
  750. BytePtr = StartAddr;
  751. BytesDone = 0;
  752. while (BytesDone < BytesInThisLine) {
  753. if (isprint(*BytePtr)) {
  754. DbgPrint( FORMAT_CHAR, (CHAR) *BytePtr );
  755. } else {
  756. DbgPrint( "." );
  757. }
  758. ++BytesDone;
  759. ++BytePtr;
  760. }
  761. DbgPrint("\n");
  762. } // MsgDbgHexDumpLine
  763. VOID
  764. MsgDbgHexDump(
  765. IN LPBYTE StartAddr,
  766. IN DWORD Length
  767. )
  768. /*++
  769. Routine Description:
  770. MsgDbgHexDump: do a hex dump of some number of bytes to the debug
  771. terminal or whatever. This is a no-op in a nondebug build.
  772. Arguments:
  773. Return Value:
  774. --*/
  775. {
  776. DWORD BytesLeft = Length;
  777. LPBYTE LinePtr = StartAddr;
  778. DWORD LineSize;
  779. while (BytesLeft > 0) {
  780. LineSize = MIN(BytesLeft, BYTES_PER_LINE);
  781. MsgDbgHexDumpLine( LinePtr, LineSize );
  782. BytesLeft -= LineSize;
  783. LinePtr += LineSize;
  784. }
  785. } // NetpDbgHexDump
  786. #endif // DBG