windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/msgsvc/client/msg.c

473 lines
11 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1990-1992 Microsoft Corporation
Module Name:
MSG.C
Abstract:
Test Routines for the Service Controller.
Author:
Dan Lafferty (danl) 08-May-1991
Environment:
User Mode - Win32
Revision History:
08-May-1991 danl
created
--*/
//
// INCLUDES
//
#include <nt.h> // DbgPrint prototype
#include <ntrtl.h> // DbgPrint prototype
#include <nturtl.h> // needed for winbase.h
#include <stdlib.h> // atoi
#include <stdio.h> // printf
#include <string.h> // strcmp
#include <windows.h> // win32 typedefs
#include <lmerr.h> // NERR_ error codes
#include <windef.h> // win32 typedefs
#include <lmcons.h>
#include <lmmsg.h>
#include <tstring.h> // Unicode
//
// FUNCTION PROTOTYPES
//
VOID
DisplayStatus (
IN LPBYTE InfoStruct2,
IN DWORD level
);
BOOL
ConvertToUnicode(
OUT LPWSTR *UnicodeOut,
IN LPSTR AnsiIn
);
BOOL
MakeArgsUnicode (
DWORD argc,
PUCHAR argv[]
);
/****************************************************************************/
VOID __cdecl
main (
int argc,
PUCHAR argvA[]
)
/*++
Routine Description:
Allows manual testing of the Messenger Service by typing commands on
the command line such as:
msg add danl - adds a name (danl).
msg del danl - deletes a name (danl).
msg enum - enumerates the names (level 1)
msg enum -l1 - enumerates the names (level 1)
msg enum -l0 - enumerates the names (level 0)
msg enum rh= 2 - enum with resume handle =2 (level1)
msg enum maxlen= 50 - Does an enum with a 50 byte buffer.
msg query danl - gets info on danl. (level 1)
msg query danl -l0 - gets info on danl. (level 0)
Arguments:
Return Value:
--*/
{
NET_API_STATUS status;
LPBYTE InfoStruct;
DWORD entriesRead;
DWORD totalEntries;
DWORD resumeHandle;
DWORD prefMaxLen;
DWORD level;
DWORD specialFlag = FALSE;
DWORD i;
WCHAR name[50];
LPWSTR *argv;
LPWSTR pServerName;
LPTSTR *FixArgv;
INT argIndex;
if (argc <2) {
printf("ERROR: no command was given! (add, del, enum, query)\n");
return;
}
//
// Make the arguments unicode if necessary.
//
argv = (LPWSTR *)argvA;
#ifdef UNICODE
if (!MakeArgsUnicode(argc, (PUCHAR *)argv)) {
return;
}
#endif
FixArgv = (LPTSTR *)argv;
pServerName = NULL;
argIndex = 1;
if (STRNCMP (FixArgv[1], TEXT("\\\\"), 2) == 0) {
pServerName = FixArgv[1];
argIndex = 2;
}
if (_wcsicmp (FixArgv[argIndex], L"enum" ) == 0 ) {
resumeHandle = 0;
level = 1;
prefMaxLen = 0xffffffff;
if (argc > argIndex+1) {
if (_wcsicmp (FixArgv[argIndex+1], L"rh=") == 0) {
specialFlag = TRUE;
if (argc > argIndex+2) {
resumeHandle = wtol(FixArgv[argIndex+2]);
}
}
if (_wcsicmp (FixArgv[argIndex+1], L"-l0") == 0) {
specialFlag = TRUE;
level = 0;
}
if (_wcsicmp (FixArgv[argIndex+1], L"-l2") == 0) {
specialFlag = TRUE;
level = 2;
}
if (_wcsicmp (FixArgv[argIndex+1], L"-l3") == 0) {
specialFlag = TRUE;
level = 3;
}
if (_wcsicmp (FixArgv[argIndex+1], L"maxlen=") == 0) {
specialFlag = TRUE;
if (argc > argIndex+2) {
prefMaxLen = wtol(FixArgv[argIndex+2]);
}
}
}
if ( (argc < argIndex+2) ||
(specialFlag == TRUE) && (argc < argIndex+4) ) {
status = NetMessageNameEnum (
pServerName, // ServerName - Local version
level, // Level
&InfoStruct, // return status buffer pointer
prefMaxLen, // preferred max length
&entriesRead, // entries read
&totalEntries, // total entries
&resumeHandle); // resume handle
if ( (status == NERR_Success) ||
(status == ERROR_MORE_DATA) ){
printf("Enum: entriesRead = %d\n", entriesRead);
printf("Enum: totalEntries = %d\n", totalEntries);
printf("Enum: resumeHandle = %d\n", resumeHandle);
for (i=0; i<entriesRead; i++) {
DisplayStatus(InfoStruct,level);
switch(level) {
case 0:
InfoStruct += sizeof(MSG_INFO_0);
break;
case 1:
InfoStruct += sizeof(MSG_INFO_1);
break;
default:
printf("Bad InfoLevel\n");
}
}
}
else {
printf("[msg] NetServiceEnum FAILED, rc = %ld\n", status);
if (InfoStruct != NULL) {
DisplayStatus(InfoStruct,level);
}
}
}
}
else if (_wcsicmp (FixArgv[argIndex], L"query") == 0) {
level = 1;
if (argc > argIndex+1 ) {
wcscpy(name, FixArgv[argIndex+1]);
}
if (argc > argIndex+2) {
if (_wcsicmp (FixArgv[argIndex+2], TEXT("-l0")) ==0) {
level = 0;
}
}
status = NetMessageNameGetInfo (
pServerName, // ServerName Local version
name, // MessageName
level, // level
&InfoStruct); // buffer pointer
if (status == NERR_Success) {
DisplayStatus((LPBYTE)InfoStruct, level);
}
else {
printf("[msg] NetMessageNameGetInfo FAILED, rc = %ld\n", status);
}
}
else if (_wcsicmp (FixArgv[argIndex], L"add") == 0) {
if (argc < argIndex+2) {
printf("ERROR: no name given for add (msg add <name>)\n");
return;
}
wcscpy(name, FixArgv[argIndex+1]);
status = NetMessageNameAdd (
pServerName, // ServerName Local version
name); // Name to add
if (status == NERR_Success) {
printf("name added successfully\n");
}
else {
printf("[msg] NetMessageNameAdd FAILED, rc = %ld\n", status);
}
}
else if (_wcsicmp (FixArgv[argIndex], L"del") == 0) {
if (argc < argIndex+2) {
printf("ERROR: no name given for add (msg add <name>)\n");
return;
}
wcscpy(name, FixArgv[argIndex+1]);
status = NetMessageNameDel (
pServerName, // ServerName Local version
name); // Name to add
if (status == NERR_Success) {
printf("name deleted successfully\n");
}
else {
printf("[msg] NetMessageNameDel FAILED, rc = %ld\n", status);
}
}
else {
printf("[msg] Unrecognized Command\n");
}
return;
}
/****************************************************************************/
VOID
DisplayStatus (
IN LPBYTE InfoStruct,
IN DWORD level
)
/*++
Routine Description:
Displays the returned info buffer.
Arguments:
InfoStruct2 - This is a pointer to a SERVICE_INFO_2 structure from which
information is to be displayed.
Return Value:
none.
--*/
{
LPMSG_INFO_0 InfoStruct0;
LPMSG_INFO_1 InfoStruct1;
switch(level) {
case 0:
InfoStruct0 = (LPMSG_INFO_0)InfoStruct;
printf("\nNAME: %ws\n", InfoStruct0->msgi0_name);
break;
case 1:
InfoStruct1 = (LPMSG_INFO_1)InfoStruct;
printf("\nNAME: %ws\n", InfoStruct1->msgi1_name);
printf(" FWD_FLAG: %ld\n", InfoStruct1->msgi1_forward_flag);
printf(" FWD_STRING: %ws\n", InfoStruct1->msgi1_forward );
break;
default:
printf("DisplayStatus: illegal level\n");
}
return;
}
BOOL
MakeArgsUnicode (
DWORD argc,
PUCHAR argv[]
)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
DWORD i;
//
// ScConvertToUnicode allocates storage for each string.
// We will rely on process termination to free the memory.
//
for(i=0; i<argc; i++) {
if(!ConvertToUnicode( (LPWSTR *)&(argv[i]), argv[i])) {
printf("Couldn't convert argv[%d] to unicode\n",i);
return(FALSE);
}
}
return(TRUE);
}
BOOL
ConvertToUnicode(
OUT LPWSTR *UnicodeOut,
IN LPSTR AnsiIn
)
/*++
Routine Description:
This function translates an AnsiString into a Unicode string.
A new string buffer is created by this function. If the call to
this function is successful, the caller must take responsibility for
the unicode string buffer that was allocated by this function.
The allocated buffer should be free'd with a call to LocalFree.
NOTE: This function allocates memory for the Unicode String.
Arguments:
AnsiIn - This is a pointer to an ansi string that is to be converted.
UnicodeOut - This is a pointer to a location where the pointer to the
unicode string is to be placed.
Return Value:
TRUE - The conversion was successful.
FALSE - The conversion was unsuccessful. In this case a buffer for
the unicode string was not allocated.
--*/
{
NTSTATUS ntStatus;
DWORD bufSize;
UNICODE_STRING unicodeString;
OEM_STRING ansiString;
//
// Allocate a buffer for the unicode string.
//
bufSize = (strlen(AnsiIn)+1) * sizeof(WCHAR);
*UnicodeOut = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, bufSize);
if (*UnicodeOut == NULL) {
printf("ScConvertToUnicode:LocalAlloc Failure %ld\n",GetLastError());
return(FALSE);
}
//
// Initialize the string structures
//
NetpInitOemString( &ansiString, AnsiIn);
unicodeString.Buffer = *UnicodeOut;
unicodeString.MaximumLength = (USHORT)bufSize;
unicodeString.Length = 0;
//
// Call the conversion function.
//
ntStatus = RtlOemStringToUnicodeString (
&unicodeString, // Destination
&ansiString, // Source
FALSE); // Allocate the destination
if (!NT_SUCCESS(ntStatus)) {
printf("ScConvertToUnicode:RtlOemStringToUnicodeString Failure %lx\n",
ntStatus);
return(FALSE);
}
//
// Fill in the pointer location with the unicode string buffer pointer.
//
*UnicodeOut = unicodeString.Buffer;
return(TRUE);
}