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.
745 lines
22 KiB
745 lines
22 KiB
/********************************************************************/
|
|
/** Microsoft LAN Manager **/
|
|
/** Copyright(c) Microsoft Corp., 1987-1992 **/
|
|
/********************************************************************/
|
|
|
|
|
|
/*
|
|
** Routines to log messages
|
|
**
|
|
** If message logging is off, all messages are buffered. Further,
|
|
** even if messages are being logged, multi-block messages must
|
|
** be buffered since they must be spooled to the logging file or
|
|
** device. Since there is only one message buffer in which to
|
|
** buffer all messages, this buffer must be managed as a heap.
|
|
** Also, messages are logged in a first-in-first-out manner,
|
|
** so messages in the buffer must be kept in a queue. In order
|
|
** to meet these goals, the following message blocks are defined:
|
|
**
|
|
** SBM - single-block message
|
|
**
|
|
** length - length of entire block (2 bytes)
|
|
** code - identifies block as single-block message (1 byte)
|
|
** link - link to next message in message queue (2 bytes)
|
|
** date - date message received (2 bytes)
|
|
** time - time message received (2 bytes)
|
|
** from - name of sender (null-terminated string)
|
|
** to - name of recipient (null-terminated string)
|
|
** text - text of message (remainder of block)
|
|
**
|
|
** MBB - multi-block message header
|
|
**
|
|
** length - length of entire block (2 bytes)
|
|
** code - identifies block as multi-block message header (1 byte)
|
|
** link - link to next message in message queue (2 bytes)
|
|
** date - date message received (2 bytes)
|
|
** time - time message received (2 bytes)
|
|
** btext - link to last text block (2 bytes)
|
|
** ftext - link to first text block (2 bytes)
|
|
** error - error flag (1 byte)
|
|
** from - name of sender (null-terminated string)
|
|
** to - name of recipient (null-terminated string)
|
|
**
|
|
** MBT - multi-block message text block
|
|
**
|
|
** length - length of entire block (2 bytes)
|
|
** code - identifies block a multi-block message text (1 byte)
|
|
** link - link to next text block (2 bytes)
|
|
** text - text of message (remainder of block)
|
|
**/
|
|
|
|
//
|
|
// Includes
|
|
//
|
|
|
|
#include "msrv.h"
|
|
|
|
#include <string.h> // memcpy
|
|
#include <tstring.h> // Unicode string macros
|
|
#include <netdebug.h> // NetpAssert
|
|
|
|
#include <lmalert.h> // Alert stuff
|
|
|
|
#include <netlib.h> // UNUSED macro
|
|
#include <netlibnt.h> // NetpNtStatusToApiStatus
|
|
#include <smbtypes.h> // needed for smb.h
|
|
#include <smb.h> // Server Message Block definitions
|
|
#include <lmerrlog.h> // NELOG_ messages
|
|
#include <smbgtpt.h> // SMB field manipulation macros
|
|
|
|
#include <winuser.h> // MessageBox
|
|
#include <winsock2.h> // Windows sockets
|
|
|
|
#include "msgdbg.h" // MSG_LOG
|
|
#include "msgdata.h"
|
|
|
|
//
|
|
// Defines for Hex Dump Function
|
|
//
|
|
#ifndef MIN
|
|
#define MIN(a,b) ( ( (a) < (b) ) ? (a) : (b) )
|
|
#endif
|
|
|
|
#define DWORDS_PER_LINE 4
|
|
#define BYTES_PER_LINE (DWORDS_PER_LINE * sizeof(DWORD))
|
|
#define SPACE_BETWEEN_BYTES NetpKdPrint((" "))
|
|
#define SPACE_BETWEEN_DWORDS NetpKdPrint((" "))
|
|
//
|
|
// Local Functions
|
|
//
|
|
|
|
NET_API_STATUS
|
|
MsgOutputMsg (
|
|
USHORT AlertLength,
|
|
LPSTR AlertBuffer,
|
|
ULONG SessionId,
|
|
SYSTEMTIME BigTime
|
|
);
|
|
|
|
|
|
//
|
|
// Data
|
|
//
|
|
|
|
PSTD_ALERT alert_buf_ptr; // Pointer to DosAlloc'ed alert buffer
|
|
USHORT alert_len; // Currently used length of alert buffer
|
|
|
|
//
|
|
// Defines
|
|
//
|
|
#define ERROR_LOG_SIZE 1024
|
|
|
|
|
|
/*
|
|
** Msglogmbb - log a multi-block message header
|
|
**
|
|
** This function is called to log a multi-block message header.
|
|
** The message header is placed in the message buffer which resides
|
|
** in the shared data area.
|
|
**
|
|
** This function stores the from and to information in the shared data
|
|
** buffer and initializes the multi-block message header. Then it puts
|
|
** a pointer to the multi-block header into the shared data pointer
|
|
** location for that net index and name index.
|
|
**
|
|
** logmbb (from, to, net, ncbi)
|
|
**
|
|
** ENTRY
|
|
** from - sender name
|
|
** to - recipient name
|
|
** net - network index
|
|
** ncbi - Network Control Block index
|
|
**
|
|
** RETURN
|
|
** zero if successful, non-zero if unable to buffer the message header
|
|
**
|
|
** SIDE EFFECTS
|
|
**
|
|
** Calls heapalloc() to obtain buffer space.
|
|
**/
|
|
|
|
DWORD
|
|
Msglogmbb(
|
|
LPSTR from, // Name of sender
|
|
LPSTR to, // Name of recipient
|
|
DWORD net, // Which network ?
|
|
DWORD ncbi // Network Control Block index
|
|
)
|
|
|
|
{
|
|
DWORD i; // Heap index
|
|
LPSTR fcp; // Far character pointer
|
|
LONG ipAddress;
|
|
struct hostent *pHostEntry;
|
|
|
|
//
|
|
// Synchronize with Pnp configuration routine
|
|
//
|
|
MsgConfigurationLock(MSG_GET_SHARED,"Msglogmbb");
|
|
|
|
//
|
|
// Block until the shared database is free
|
|
//
|
|
MsgDatabaseLock(MSG_GET_EXCLUSIVE,"logmbb");
|
|
|
|
//
|
|
// Check whether the recipient name needs to be formatted
|
|
//
|
|
|
|
ipAddress = inet_addr( to );
|
|
if (ipAddress != INADDR_NONE) {
|
|
pHostEntry = gethostbyaddr( (char *)&ipAddress,sizeof( LONG ),AF_INET);
|
|
if (pHostEntry) {
|
|
to = pHostEntry->h_name;
|
|
} else {
|
|
MSG_LOG2(ERROR,"Msglogmbb: could not lookup addr %s, error %d\n",
|
|
to, WSAGetLastError());
|
|
}
|
|
}
|
|
|
|
//
|
|
// Allocate space for header
|
|
//
|
|
i = Msgheapalloc(sizeof(MBB) + strlen(from) + strlen(to) + 2);
|
|
|
|
if(i == INULL) { // If no buffer space
|
|
//
|
|
// Unlock the shared database
|
|
//
|
|
|
|
MsgDatabaseLock(MSG_RELEASE,"logmbb");
|
|
MsgConfigurationLock(MSG_RELEASE,"Msglogmbb");
|
|
|
|
return((int) i); // Log fails
|
|
}
|
|
|
|
//
|
|
// Multi-block message
|
|
//
|
|
MBB_CODE(*MBBPTR(i)) = SMB_COM_SEND_START_MB_MESSAGE;
|
|
MBB_NEXT(*MBBPTR(i)) = INULL; // Last message in buffer
|
|
GetLocalTime(&MBB_BIGTIME(*MBBPTR(i))); // Time of message
|
|
MBB_BTEXT(*MBBPTR(i)) = INULL; // No text yet
|
|
MBB_FTEXT(*MBBPTR(i)) = INULL; // No text yet
|
|
MBB_STATE(*MBBPTR(i)) = MESCONT; // Message in progress
|
|
fcp = CPTR(i + sizeof(MBB)); // Get far pointer into buffer
|
|
strcpy(fcp, from); // Copy the sender name
|
|
fcp += strlen(from) + 1; // Increment pointer
|
|
strcpy(fcp, to); // Copy the recipient name
|
|
SD_MESPTR(net,ncbi) = i; // Save index to this record
|
|
|
|
//
|
|
// Unlock the shared database
|
|
//
|
|
|
|
MsgDatabaseLock(MSG_RELEASE,"logmbb");
|
|
MsgConfigurationLock(MSG_RELEASE,"Msglogmbb");
|
|
|
|
return(0); // Message logged successfully
|
|
}
|
|
|
|
/*
|
|
** Msglogmbe - log end of a multi-block message
|
|
**
|
|
** This function is called to log a multi-block message end.
|
|
** The message is marked as finished, and if logging is enabled,
|
|
** an attempt is made to write the message to the log file. If
|
|
** this attempt fails, or if logging is disabled, then the message
|
|
** is placed in the message queue in the message buffer.
|
|
**
|
|
** The message is gathered up and placed in the alert buffer and an alert
|
|
** is raised.
|
|
**
|
|
** logmbe (state, net,ncbi)
|
|
**
|
|
** ENTRY
|
|
** state - final state of message
|
|
** net - Network index
|
|
** ncbi - Network Control Block index
|
|
**
|
|
** RETURN
|
|
** int - BUFFERED if the message is left in the buffer
|
|
** int - LOGGED if the message is written to the log file
|
|
**
|
|
** FOR NT:
|
|
** SMB_ERR_SUCCESS - success in alerting
|
|
** SMB_ERR_... - an error occured
|
|
**
|
|
**
|
|
**
|
|
** SIDE EFFECTS
|
|
**
|
|
** Calls mbmprint() to print the message if logging is enabled. Calls
|
|
** mbmfree() to free the message if logging succeeds.
|
|
**/
|
|
|
|
UCHAR
|
|
Msglogmbe(
|
|
DWORD state, // Final state of message
|
|
DWORD net, // Which network?
|
|
DWORD ncbi // Network Control Block index
|
|
)
|
|
{
|
|
DWORD i; // Heap index
|
|
DWORD error; // Error code
|
|
DWORD meslog; // Message logging status
|
|
DWORD alert_flag; // Alert buffer allocated flag
|
|
DWORD status; // Dos error for error log
|
|
DWORD bufSize; // Buffer Size
|
|
SYSTEMTIME bigtime; // Date and time of message
|
|
|
|
PMSG_SESSION_ID_ITEM pItem;
|
|
PLIST_ENTRY pHead;
|
|
PLIST_ENTRY pList;
|
|
|
|
//
|
|
// Synchronize with Pnp configuration routine
|
|
//
|
|
MsgConfigurationLock(MSG_GET_SHARED,"Msglogmbe");
|
|
|
|
//
|
|
// Block until the shared database is free
|
|
//
|
|
MsgDatabaseLock(MSG_GET_EXCLUSIVE,"logmbe");
|
|
|
|
pHead = &(SD_SIDLIST(net,ncbi));
|
|
pList = pHead;
|
|
|
|
//
|
|
// First get a buffer for an alert
|
|
//
|
|
|
|
bufSize = sizeof( STD_ALERT) +
|
|
ALERT_MAX_DISPLAYED_MSG_SIZE +
|
|
(2*TXTMAX) + 2;
|
|
|
|
alert_buf_ptr = (PSTD_ALERT)LocalAlloc(LMEM_ZEROINIT, bufSize);
|
|
|
|
if (alert_buf_ptr == NULL) {
|
|
MSG_LOG(ERROR,"logmbe:Local Alloc failed\n",0);
|
|
alert_flag = 0xffffffff; // No alerting if Alloc failed
|
|
}
|
|
else {
|
|
alert_flag = 0; // File and alerting
|
|
alert_len = 0;
|
|
|
|
}
|
|
|
|
error = 0; // Assume no error
|
|
i = SD_MESPTR(net,ncbi); // Get index to message header
|
|
MBB_STATE(*MBBPTR(i)) = state; // Record final state
|
|
|
|
//
|
|
// If logging now disabled ...
|
|
//
|
|
|
|
if(!SD_MESLOG())
|
|
{
|
|
if( alert_flag == 0)
|
|
{
|
|
//
|
|
// Format the message and put it in the alert buffer.
|
|
//
|
|
// Alert only. alert_flag is only modified if Msgmbmprint
|
|
// returns success and we should skip the message (i.e.,
|
|
// it's a print notification from a pre-Whistler machine).
|
|
//
|
|
if (Msgmbmprint(1,i,0, &alert_flag))
|
|
{
|
|
alert_flag = 0xffffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add message to buffer queue if logging is off,
|
|
// or if the attempt to log the message failed.
|
|
//
|
|
|
|
meslog = SD_MESLOG(); // Get logging status
|
|
|
|
if(!meslog)
|
|
{ // If logging disabled
|
|
Msgmbmfree(i);
|
|
}
|
|
|
|
if(error != 0)
|
|
{
|
|
//
|
|
// We should never get here
|
|
//
|
|
|
|
NetpAssert(error == 0);
|
|
}
|
|
|
|
//
|
|
// Now alert and free up alert buffer if it was successfully allocated
|
|
//
|
|
|
|
if( alert_flag == 0) {
|
|
//
|
|
// There is an alert buffer, output it.
|
|
//
|
|
GetLocalTime(&bigtime); // Get the time
|
|
|
|
if (g_IsTerminalServer)
|
|
{
|
|
//
|
|
// Output the message for all the sessions sharing that name
|
|
//
|
|
|
|
while (pList->Flink != pHead) // loop all over the list
|
|
{
|
|
pList = pList->Flink;
|
|
pItem = CONTAINING_RECORD(pList, MSG_SESSION_ID_ITEM, List);
|
|
MsgOutputMsg(alert_len, (LPSTR)alert_buf_ptr, pItem->SessionId, bigtime);
|
|
}
|
|
}
|
|
else // regular NT
|
|
{
|
|
MsgOutputMsg(alert_len, (LPSTR)alert_buf_ptr, 0, bigtime);
|
|
}
|
|
}
|
|
|
|
LocalFree(alert_buf_ptr);
|
|
|
|
//
|
|
// Unlock the shared database
|
|
//
|
|
|
|
MsgDatabaseLock(MSG_RELEASE,"logmbe");
|
|
|
|
MsgConfigurationLock(MSG_RELEASE,"Msglogmbe");
|
|
|
|
return(SMB_ERR_SUCCESS); // Message arrived
|
|
}
|
|
|
|
/*
|
|
** Msglogmbt - log a multi-block message text block
|
|
**
|
|
** This function is called to log a multi-block message text block.
|
|
** The text block is placed in the message buffer which resides
|
|
** in the shared data area. If there is insufficient room in the
|
|
** buffer, logmbt() removes the header and any previous blocks of
|
|
** the message from the buffer.
|
|
**
|
|
** This function gets the current message from the message pointer in
|
|
** the shared data (for that net & name index). It looks in the header
|
|
** to see if there are any text blocks already there. If so, it adds
|
|
** this new one to the list and fixes the last block pointer to point to
|
|
** it.
|
|
**
|
|
** logmbt (text, net, ncbi)
|
|
**
|
|
** ENTRY
|
|
** text - text header
|
|
** net - Network index
|
|
** ncbi - Network Control Block index
|
|
**
|
|
** RETURN
|
|
** zero if successful, non-zero if unable to buffer the message header
|
|
**
|
|
** SIDE EFFECTS
|
|
**
|
|
** Calls heapalloc() to obtain buffer space. Calls mbmfree() if a call to
|
|
** heapalloc() fails.
|
|
**/
|
|
|
|
DWORD
|
|
Msglogmbt(
|
|
LPSTR text, // Text of message
|
|
DWORD net, // Which network?
|
|
DWORD ncbi // Network Control Block index
|
|
)
|
|
{
|
|
DWORD i; // Heap index
|
|
DWORD j; // Heap index
|
|
DWORD k; // Heap index
|
|
USHORT length; // Length of text
|
|
|
|
//
|
|
// Synchronize with Pnp configuration routine
|
|
//
|
|
MsgConfigurationLock(MSG_GET_SHARED,"Msglogmbt");
|
|
|
|
// *ALIGNMENT*
|
|
length = SmbGetUshort( (PUSHORT)text); // Get length of text block
|
|
// length = *((PSHORT) text); // Get length of text block
|
|
text += sizeof(short); // Skip over length word
|
|
|
|
//
|
|
// Block until the shared database is free
|
|
//
|
|
|
|
MsgDatabaseLock(MSG_GET_EXCLUSIVE,"logmbt");
|
|
|
|
i = Msgheapalloc(sizeof(MBT) + length); // Allocate space for block
|
|
|
|
//
|
|
// If buffer space is available
|
|
//
|
|
|
|
if(i != INULL) {
|
|
|
|
//
|
|
// Multi-block message text
|
|
//
|
|
MBT_CODE(*MBTPTR(i)) = SMB_COM_SEND_TEXT_MB_MESSAGE;
|
|
|
|
MBT_NEXT(*MBTPTR(i)) = INULL; // Last text block so far
|
|
|
|
MBT_COUNT(*MBTPTR(i)) = (DWORD)length; // *ALIGNMENT2*
|
|
|
|
memcpy(CPTR(i + sizeof(MBT)), text, length);
|
|
|
|
// Copy text into buffer
|
|
j = SD_MESPTR(net, ncbi); // Get index to current message
|
|
|
|
if(MBB_FTEXT(*MBBPTR(j)) != INULL) {
|
|
//
|
|
// If there is text already, Get pointer to last block and
|
|
// add new block
|
|
//
|
|
k = MBB_BTEXT(*MBBPTR(j)); // Get pointer to last block
|
|
MBT_NEXT(*MBTPTR(k)) = i; // Add new block
|
|
}
|
|
else {
|
|
MBB_FTEXT(*MBBPTR(j)) = i; // Else set front pointer
|
|
}
|
|
|
|
MBB_BTEXT(*MBBPTR(j)) = i; // Set back pointer
|
|
i = 0; // Success
|
|
}
|
|
else {
|
|
Msgmbmfree(SD_MESPTR(net,ncbi)); // Else deallocate the message
|
|
}
|
|
|
|
//
|
|
// Unlock the shared database
|
|
//
|
|
|
|
MsgDatabaseLock(MSG_RELEASE,"logmbt");
|
|
|
|
MsgConfigurationLock(MSG_RELEASE,"Msglogmbt");
|
|
|
|
return((int) i); // Return status
|
|
}
|
|
|
|
|
|
/*
|
|
** Msglogsbm - log a single-block message
|
|
**
|
|
** This function is called to log a single-block message. If
|
|
** logging is enabled, the message is written directly to the
|
|
** logging file or device. If logging is disabled or if the
|
|
** attempt to log the message fails, the message is placed in
|
|
** the message buffer which resides in the shared data area.
|
|
**
|
|
** logsbm (from, to, text)
|
|
**
|
|
** ENTRY
|
|
** from - sender name
|
|
** to - recipient name
|
|
** text - text of message
|
|
**
|
|
** RETURN
|
|
** zero if successful, non-zero if unable to log the message
|
|
**
|
|
** SIDE EFFECTS
|
|
**
|
|
** Calls hdrprint(), txtprint(), and endprint() to print the message if
|
|
** logging is enabled. Calls heapalloc() to obtain buffer space if
|
|
** the message must be buffered.
|
|
**/
|
|
|
|
DWORD
|
|
Msglogsbm(
|
|
LPSTR from, // Name of sender
|
|
LPSTR to, // Name of recipient
|
|
LPSTR text, // Text of message
|
|
ULONG SessionId // Session Id
|
|
)
|
|
{
|
|
DWORD i; // Heap index
|
|
DWORD error; // Error code
|
|
SHORT length; // Length of text
|
|
DWORD meslog; // Message logging status
|
|
DWORD alert_flag; // Alert buffer allocated flag
|
|
DWORD status; // DOS error from mespeint functions
|
|
SYSTEMTIME bigtime; // Date and time of message
|
|
DWORD bufSize; // Buffer Size
|
|
|
|
//
|
|
// Synchronize with Pnp configuration routine
|
|
//
|
|
MsgConfigurationLock(MSG_GET_SHARED,"Msglogsbm");
|
|
|
|
//
|
|
// Block until the shared database is free
|
|
//
|
|
MsgDatabaseLock(MSG_GET_EXCLUSIVE,"logsbm");
|
|
|
|
//
|
|
// First get a buffer for an alert
|
|
//
|
|
|
|
bufSize = sizeof( STD_ALERT) +
|
|
ALERT_MAX_DISPLAYED_MSG_SIZE +
|
|
(2*TXTMAX) + 2;
|
|
|
|
alert_buf_ptr = (PSTD_ALERT)LocalAlloc(LMEM_ZEROINIT, bufSize);
|
|
|
|
if (alert_buf_ptr == NULL) {
|
|
MSG_LOG(ERROR,"Msglogsbm:Local Alloc failed\n",0);
|
|
alert_flag = 0xffffffff; // No alerting if Alloc failed
|
|
}
|
|
else {
|
|
alert_flag = 0; // File and alerting
|
|
alert_len = 0;
|
|
}
|
|
|
|
// *ALIGNMENT*
|
|
length = SmbGetUshort( (PUSHORT)text); // Get length of text block
|
|
text += sizeof(short); // Skip over length word
|
|
error = 0; // Assume no errors
|
|
|
|
//
|
|
// Hack to drop messages sent by pre-Whistler Spoolers. As of
|
|
// Whistler, print notifications are done as shell balloon tips
|
|
// so don't display print alerts sent from the server as well.
|
|
//
|
|
// This check is also made in Msgmbmprint to catch multi-block messages.
|
|
//
|
|
|
|
if ((g_lpAlertSuccessMessage
|
|
&&
|
|
_strnicmp(text, g_lpAlertSuccessMessage, g_dwAlertSuccessLen) == 0)
|
|
||
|
|
(g_lpAlertFailureMessage
|
|
&&
|
|
_strnicmp(text, g_lpAlertFailureMessage, g_dwAlertFailureLen) == 0))
|
|
{
|
|
MsgDatabaseLock(MSG_RELEASE,"logsbm");
|
|
MsgConfigurationLock(MSG_RELEASE,"Msglogsbm");
|
|
return 0;
|
|
}
|
|
|
|
GetLocalTime(&bigtime); // Get the time
|
|
|
|
|
|
if (!SD_MESLOG()) // If logging disabled
|
|
{
|
|
if( alert_flag == 0) // If alert buf is valid
|
|
{
|
|
if (!Msghdrprint(1,from, to, bigtime,0))
|
|
{
|
|
if (Msgtxtprint(1, text,length,0))
|
|
{
|
|
alert_flag = 0xffffffff;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
alert_flag = 0xffffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
meslog = SD_MESLOG(); // Get logging status
|
|
i = 0; // No way to fail if not logging
|
|
|
|
if(error != 0)
|
|
{
|
|
DbgPrint("meslog.c:logsbm(before ErrorLogWrite): We should never get here\n");
|
|
NetpAssert(0);
|
|
}
|
|
|
|
// Now alert and free up alert buffer if it was successfully allocated
|
|
|
|
if( alert_flag == 0) { // There is an alert buffer
|
|
|
|
//
|
|
// There is an alert buffer, output it.
|
|
//
|
|
MsgOutputMsg(alert_len, (LPSTR)alert_buf_ptr, SessionId, bigtime);
|
|
}
|
|
|
|
LocalFree(alert_buf_ptr);
|
|
|
|
//
|
|
// Unlock the shared database
|
|
//
|
|
|
|
MsgDatabaseLock(MSG_RELEASE,"logsbm");
|
|
|
|
MsgConfigurationLock(MSG_RELEASE,"Msglogsbm");
|
|
|
|
return((int) i); // Return status
|
|
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
MsgOutputMsg (
|
|
USHORT AlertLength,
|
|
LPSTR AlertBuffer,
|
|
ULONG SessionId,
|
|
SYSTEMTIME BigTime
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function translates the alert buffer from an Ansi String to a
|
|
Unicode String and outputs the buffer to whereever it is to go.
|
|
Currently this just becomes a DbgPrint.
|
|
|
|
Arguments:
|
|
|
|
AlertLength - The number of bytes in the AlertBuffer.
|
|
|
|
AlertBuffer - This is a pointer to the buffer that contains the message
|
|
that is to be output. The buffer is expected to contain a
|
|
NUL Terminated Ansi String.
|
|
|
|
BigTime - The SYSTEMTIME that indicates the time the end of the
|
|
messsage was received.
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
UNICODE_STRING unicodeString;
|
|
OEM_STRING ansiString;
|
|
|
|
NTSTATUS ntStatus;
|
|
|
|
//
|
|
// NUL Terminate the message.
|
|
// Translate the Ansi message to a Unicode Message.
|
|
//
|
|
AlertBuffer[AlertLength++] = '\0';
|
|
|
|
ansiString.Length = AlertLength;
|
|
ansiString.MaximumLength = AlertLength;
|
|
ansiString.Buffer = AlertBuffer;
|
|
|
|
ntStatus = RtlOemStringToUnicodeString(
|
|
&unicodeString, // Destination
|
|
&ansiString, // Source
|
|
TRUE); // Allocate the destination.
|
|
|
|
if (!NT_SUCCESS(ntStatus)) {
|
|
MSG_LOG(ERROR,
|
|
"MsgOutputMsg:RtlOemStringToUnicodeString Failed rc=%X\n",
|
|
ntStatus);
|
|
|
|
//
|
|
// EXPLANATION OF WHY IT RETURNS SUCCESS HERE.
|
|
// Returning success even though the alert is not raised is
|
|
// consistent with the LM2.0 code which doesn't check the
|
|
// return code for the NetAlertRaise API anyway. Returning
|
|
// anything else would require a re-design of how errors are
|
|
// handled by the caller of this routine.
|
|
//
|
|
return(NERR_Success);
|
|
}
|
|
|
|
//*******************************************************************
|
|
//
|
|
// PUT THE MESSAGE IN THE DISPLAY QUEUE
|
|
//
|
|
|
|
MsgDisplayQueueAdd( AlertBuffer, (DWORD)AlertLength, SessionId, BigTime);
|
|
|
|
//
|
|
//
|
|
//*******************************************************************
|
|
|
|
RtlFreeUnicodeString(&unicodeString);
|
|
return(NERR_Success);
|
|
}
|