273 lines
7 KiB
C
273 lines
7 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1991-92 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
Alert.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file contains NetAlertRaise().
|
||
|
for the NetAlert API.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Rogers (JohnRo) 03-Apr-1992
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
User Mode - Win32
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
04-Apr-1992 JohnRo
|
||
|
Created NetAlertRaise() API from RitaW's AlTest (alerter svc test).
|
||
|
06-Apr-1992 JohnRo
|
||
|
Added/improved error checking.
|
||
|
08-May-1992 JohnRo
|
||
|
Quiet normal debug output.
|
||
|
08-May-1992 JohnRo
|
||
|
Use <prefix.h> equates.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
// These must be included first:
|
||
|
|
||
|
#include <windows.h> // DWORD, CreateFile(), etc.
|
||
|
#include <lmcons.h> // IN, NET_API_STATUS, etc.
|
||
|
|
||
|
// These may be included in any order:
|
||
|
|
||
|
#include <lmalert.h> // My prototype, ALERTER_MAILSLOT, LPSTD_ALERT, etc.
|
||
|
#include <lmerr.h> // NO_ERROR, NERR_NoRoom, etc.
|
||
|
#include <netdebug.h> // NetpKdPrint(()), FORMAT_ equates, etc.
|
||
|
#include <prefix.h> // PREFIX_ equates.
|
||
|
#include <string.h> // memcpy().
|
||
|
#include <strucinf.h> // NetpAlertStructureInfo().
|
||
|
#include <timelib.h> // time_now().
|
||
|
#include <tstr.h> // TCHAR_EOS.
|
||
|
|
||
|
|
||
|
#if DBG
|
||
|
#define IF_DEBUG( anything ) if (FALSE)
|
||
|
#else
|
||
|
#define IF_DEBUG( anything ) if (FALSE)
|
||
|
#endif
|
||
|
|
||
|
|
||
|
NET_API_STATUS NET_API_FUNCTION
|
||
|
NetAlertRaise(
|
||
|
IN LPCWSTR AlertType,
|
||
|
IN LPVOID Buffer,
|
||
|
IN DWORD BufferSize
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine raises an alert to notify the Alerter service by writing to
|
||
|
the Alerter service mailslot.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
AlertType - Supplies the name of the alert event which could be one
|
||
|
of the three the Alerter service supports: ADMIN, USER, or PRINTING.
|
||
|
The ALERT_xxx_EVENT equates are used to provide these strings.
|
||
|
|
||
|
Buffer - Supplies the data to be written to the alert mailslot.
|
||
|
This must begin with a STD_ALERT structure.
|
||
|
|
||
|
BufferSize - Supplies the size in number of bytes of Buffer.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
NET_API_STATUS - NO_ERROR or reason for failure.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NET_API_STATUS ApiStatus;
|
||
|
HANDLE FileHandle;
|
||
|
DWORD MaxTotalSize;
|
||
|
DWORD NumberOfBytesWritten;
|
||
|
DWORD RequiredFixedSize;
|
||
|
|
||
|
//
|
||
|
// Check for caller errors.
|
||
|
//
|
||
|
if (AlertType == NULL) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
} else if ( (*AlertType) == TCHAR_EOS ) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
} else if (Buffer == NULL) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
}
|
||
|
|
||
|
ApiStatus = NetpAlertStructureInfo(
|
||
|
(LPWSTR)AlertType,
|
||
|
& MaxTotalSize,
|
||
|
& RequiredFixedSize);
|
||
|
|
||
|
if (ApiStatus != NO_ERROR) {
|
||
|
return (ApiStatus);
|
||
|
}
|
||
|
if (BufferSize < ( sizeof(STD_ALERT) + RequiredFixedSize) ) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
} else if (BufferSize > MaxTotalSize) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Open the Alerter mailslot to write to it.
|
||
|
//
|
||
|
FileHandle = CreateFile(
|
||
|
ALERTER_MAILSLOT,
|
||
|
GENERIC_WRITE,
|
||
|
FILE_SHARE_WRITE | FILE_SHARE_READ,
|
||
|
(LPSECURITY_ATTRIBUTES) NULL,
|
||
|
OPEN_EXISTING,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
NULL ); // no template file.
|
||
|
|
||
|
if (FileHandle == INVALID_HANDLE_VALUE) {
|
||
|
|
||
|
ApiStatus = (NET_API_STATUS) GetLastError();
|
||
|
IF_DEBUG( ALERT ) {
|
||
|
NetpKdPrint(( PREFIX_NETAPI
|
||
|
"NetAlertRaise: Problem with opening mailslot "
|
||
|
FORMAT_API_STATUS "\n", ApiStatus ));
|
||
|
}
|
||
|
return (ApiStatus);
|
||
|
}
|
||
|
|
||
|
IF_DEBUG( ALERT ) {
|
||
|
NetpKdPrint(( PREFIX_NETAPI "NetAlertRaise: "
|
||
|
"Successfully opened the mailslot. Message (partial) is:\n"));
|
||
|
NetpDbgHexDump( Buffer, NetpDbgReasonable(BufferSize) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Write alert notification to mailslot to be read by Alerter service.
|
||
|
//
|
||
|
if (WriteFile(
|
||
|
FileHandle,
|
||
|
Buffer,
|
||
|
BufferSize,
|
||
|
&NumberOfBytesWritten,
|
||
|
NULL // no overlapped structure.
|
||
|
) == FALSE) {
|
||
|
|
||
|
ApiStatus = (NET_API_STATUS) GetLastError();
|
||
|
NetpKdPrint(( PREFIX_NETAPI "NetAlertRaise: Error " FORMAT_API_STATUS
|
||
|
" writing to mailslot.\n", ApiStatus ));
|
||
|
} else {
|
||
|
|
||
|
NetpAssert( NumberOfBytesWritten == BufferSize );
|
||
|
IF_DEBUG(ALERT) {
|
||
|
NetpKdPrint(( PREFIX_NETAPI "NetAlertRaise: "
|
||
|
"Successful in writing to mailslot; length "
|
||
|
FORMAT_DWORD ", bytes written " FORMAT_DWORD "\n",
|
||
|
BufferSize, NumberOfBytesWritten));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
(VOID) CloseHandle(FileHandle);
|
||
|
return (NO_ERROR);
|
||
|
|
||
|
} // NetAlertRaise
|
||
|
|
||
|
|
||
|
|
||
|
NET_API_STATUS NET_API_FUNCTION
|
||
|
NetAlertRaiseEx(
|
||
|
IN LPCWSTR AlertType,
|
||
|
IN LPVOID VariableInfo,
|
||
|
IN DWORD VariableInfoSize,
|
||
|
IN LPCWSTR ServiceName
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine raises an alert to notify the Alerter service by writing to
|
||
|
the Alerter service mailslot.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
AlertType - Supplies the name of the alert event which could be one
|
||
|
of the three the Alerter service supports: ADMIN, USER, or PRINTING.
|
||
|
The ALERT_xxx_EVENT equates are used to provide these strings.
|
||
|
|
||
|
VariableInfo - Supplies the variable length portion of the alert
|
||
|
notification.
|
||
|
|
||
|
VariableInfoSize - Supplies the size in number of bytes of the variable
|
||
|
portion of the notification.
|
||
|
|
||
|
ServiceName - Supplies the name of the service which raised the alert.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
NET_API_STATUS - NO_ERROR or reason for failure.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
#define TEMP_VARIABLE_SIZE (512-sizeof(STD_ALERT))
|
||
|
|
||
|
BYTE AlertMailslotBuffer[TEMP_VARIABLE_SIZE + sizeof(STD_ALERT)];
|
||
|
LPSTD_ALERT Alert = (LPSTD_ALERT) AlertMailslotBuffer;
|
||
|
NET_API_STATUS ApiStatus;
|
||
|
DWORD DataSize = VariableInfoSize + sizeof(STD_ALERT);
|
||
|
|
||
|
//
|
||
|
// Check for caller errors.
|
||
|
//
|
||
|
if (AlertType == NULL) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
} else if ( (*AlertType) == TCHAR_EOS ) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
} else if (VariableInfo == NULL) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
} else if (VariableInfoSize > TEMP_VARIABLE_SIZE) {
|
||
|
return (NERR_NoRoom);
|
||
|
} else if (ServiceName == NULL) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
} else if ( (*ServiceName) == TCHAR_EOS ) {
|
||
|
return (ERROR_INVALID_PARAMETER);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Copy variable portion to end of our buffer.
|
||
|
//
|
||
|
(VOID) memcpy(ALERT_OTHER_INFO(Alert), VariableInfo, VariableInfoSize);
|
||
|
|
||
|
//
|
||
|
// Store current time in seconds since 1970.
|
||
|
//
|
||
|
Alert->alrt_timestamp = (DWORD) time_now();
|
||
|
|
||
|
//
|
||
|
// Put alert event name into AlertMailslotBuffer
|
||
|
//
|
||
|
(VOID) STRCPY(Alert->alrt_eventname, AlertType);
|
||
|
|
||
|
//
|
||
|
// Put service name into AlertMailslotBuffer
|
||
|
//
|
||
|
(VOID) STRCPY(Alert->alrt_servicename, ServiceName);
|
||
|
|
||
|
//
|
||
|
// Write alert notification to mailslot to be read by Alerter service
|
||
|
//
|
||
|
ApiStatus = NetAlertRaise(
|
||
|
AlertType,
|
||
|
Alert, // buffer
|
||
|
DataSize ); // buffer size
|
||
|
|
||
|
return (ApiStatus);
|
||
|
|
||
|
} // NetAlertRaiseEx
|