420 lines
11 KiB
C
420 lines
11 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
msgnbios.c
|
||
|
||
Abstract:
|
||
|
||
This file contains Routines used by the messenger to make netbios
|
||
calls and to obtain the computer and user names.
|
||
The following functions are included:
|
||
|
||
MsgInit_NetBios
|
||
Msgsendncb
|
||
MsgAddUserNames
|
||
MsgAddAlreadyLoggedOnUserNames (HYDRA specific)
|
||
|
||
|
||
NT_NOTE:
|
||
|
||
We need some way to determine which NCB's have unanswered listens
|
||
pending. For these, we need to send an NCBCANCEL command via
|
||
another NetBios call. The buffer will contain a pointer to the
|
||
listening NCB. Also, listens that are in the process of being
|
||
serviced must either be hung up, or allowed to complete.
|
||
|
||
All this is done during the MsgrShutdown.
|
||
|
||
Author:
|
||
|
||
Dan Lafferty (danl) 27-Jun-1991
|
||
|
||
Environment:
|
||
|
||
User Mode -Win32
|
||
|
||
Notes:
|
||
|
||
NetBios3.0 is not a handle-based api. Therefore, there is no open or
|
||
close associated with it. In order to shut down properly, the
|
||
messenger will have to hangup or complete listens that are being
|
||
serviced. And it will have to send a cancel NCB for each listen
|
||
that is pending.
|
||
|
||
Revision History:
|
||
|
||
08-Apr-1994 danl
|
||
MsgAddUserNames: If call to NetWkstaUserEnum failed, this function
|
||
was still attempting to free the buffer that was returned.
|
||
Since no buffer is allocated in a failure case, the free mem
|
||
call in the path is being removed.
|
||
27-Jun-1991 danl
|
||
ported from LM2.0
|
||
|
||
--*/
|
||
|
||
|
||
#include "msrv.h"
|
||
|
||
#include "msgdbg.h" // MSG_LOG
|
||
|
||
#include <tstring.h> // Unicode string macros
|
||
#include <icanon.h> // I_NetNameCanonicalize
|
||
#include <netlib.h> // UNUSED macro
|
||
|
||
#include <lmwksta.h> // NetWorkstation API prototypes
|
||
#include <lmapibuf.h> // NetApiBufferFree
|
||
#include <netdebug.h> // NetpAssert, FORMAT_ equates.
|
||
#include "msgdata.h"
|
||
#include "apiutil.h" // MsgMapNetError
|
||
|
||
//
|
||
// Note: we use the internal entrypoints to the apis because this
|
||
// file is shared by the message apis, which cannot call the net
|
||
// bios apis because of different required permissions.
|
||
//
|
||
|
||
|
||
|
||
NET_API_STATUS
|
||
MsgInit_NetBios(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function fills the global array called net_lana_num with the
|
||
lan adapter numbers retrieved from A NetBios Enum call
|
||
|
||
NOTE: This assumes that space for the array is already set up.
|
||
|
||
The LM2.0 version of this also filled an array of NetBios Handles.
|
||
In LM2.0, the loopback driver was not included unless it was the only
|
||
network installed.
|
||
|
||
Arguments:
|
||
|
||
none
|
||
|
||
Return Value:
|
||
|
||
TRUE - No Error.
|
||
FALSE - An error occured.
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD count=0;
|
||
NCB ncb;
|
||
LANA_ENUM lanaBuffer;
|
||
unsigned char i;
|
||
unsigned char nbStatus;
|
||
|
||
|
||
//
|
||
// Find the number of networks by sending an enum request via Netbios.
|
||
//
|
||
|
||
clearncb(&ncb);
|
||
ncb.ncb_command = NCBENUM; // Enumerate LANA nums (wait)
|
||
ncb.ncb_buffer = (char FAR *)&lanaBuffer;
|
||
ncb.ncb_length = sizeof(LANA_ENUM);
|
||
|
||
nbStatus = Netbios(&ncb);
|
||
|
||
if (nbStatus != NRC_GOODRET)
|
||
{
|
||
MSG_LOG(ERROR, "Netbios LanaEnum failed rc=%d\n",nbStatus);
|
||
return MsgMapNetError(nbStatus);
|
||
}
|
||
|
||
//
|
||
// Move the Adapter Numbers (lana) into the array that will contain them.
|
||
//
|
||
for (i=0; i < lanaBuffer.length; i++)
|
||
{
|
||
MSG_LOG(TRACE,"adapter %d",i);
|
||
MSG_LOG(TRACE,"\b\b\b\b\b\b lananum= %d \n", lanaBuffer.lana[i]);
|
||
GETNETLANANUM(count) = lanaBuffer.lana[i];
|
||
count++;
|
||
|
||
//
|
||
// Internal consistancy check. Make sure the arrays are only
|
||
// SD_NUMNETS long.
|
||
//
|
||
if (count > SD_NUMNETS())
|
||
{
|
||
MSG_LOG(ERROR,
|
||
"NumNets from NetBios greater than value from Wksta count=%d\n",
|
||
count);
|
||
|
||
return NERR_WkstaInconsistentState;
|
||
}
|
||
}
|
||
|
||
//
|
||
// Internal consistancy check again. We better not have opened
|
||
// more nets than the messenger thinks there are.
|
||
//
|
||
|
||
if (count != SD_NUMNETS())
|
||
{
|
||
return NERR_WkstaInconsistentState;
|
||
}
|
||
|
||
return NERR_Success;
|
||
|
||
}
|
||
|
||
UCHAR
|
||
Msgsendncb(
|
||
PNCB NCB_ptr,
|
||
DWORD neti)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
This function performs a DosDevIOCtl call to send an NCB to the
|
||
net bios via a previously openned redirector and netbios handle.
|
||
|
||
Arguments:
|
||
|
||
NCB_ptr - Points to the NCB to send to the net bios.
|
||
neti - Network index. Which netbios to submit it to?
|
||
|
||
|
||
Return Value:
|
||
|
||
|
||
Error code from Net bios.
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// NOTE: The new Netbios call doesn't use any handles, so the neti
|
||
// info is not used.
|
||
//
|
||
|
||
UNUSED (neti);
|
||
return (Netbios(NCB_ptr));
|
||
|
||
#ifdef remove
|
||
return( NetBiosSubmit( NetBios_Hdl[neti], 0, (NCB far *) NCB_ptr));
|
||
#endif
|
||
}
|
||
|
||
|
||
VOID
|
||
MsgAddUserNames(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function used to get it's information about the username and
|
||
computername from the workstation service. Now, in NT, the username
|
||
is added when the user logs on. It is not automatically added by the
|
||
messenger.
|
||
|
||
Arguments:
|
||
|
||
|
||
CompName - Pointer to buf for computer name. (must be NCBNAMSZ+1)
|
||
CompNameSize - Size in bytes of the buffer to receive the name.
|
||
|
||
UserName - Pointer to buffer for user name. (must be UNLEN+1)
|
||
UserNameSize - Size in bytes of the buffer to receive the name.
|
||
|
||
Return Value:
|
||
|
||
NERR_Success - Aways returned. (Names are returned as NUL strings).
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
TCHAR UserName[UNLEN+1];
|
||
DWORD UserNameSize = sizeof(UserName);
|
||
DWORD i;
|
||
LPWKSTA_USER_INFO_0 userInfo0;
|
||
DWORD entriesRead;
|
||
DWORD totalEntries;
|
||
NET_API_STATUS status;
|
||
|
||
*UserName = TEXT('\0');
|
||
|
||
status = NetWkstaUserEnum(
|
||
NULL,
|
||
0,
|
||
(LPBYTE *)&userInfo0,
|
||
0xffffffff, // PreferredMaximiumLength
|
||
&entriesRead,
|
||
&totalEntries,
|
||
NULL); // resume handle
|
||
|
||
if (status != NERR_Success) {
|
||
MSG_LOG(ERROR,"GetWkstaNames:NetWkstaUserEnum FAILURE %X/n",status);
|
||
return;
|
||
}
|
||
|
||
for (i=0; i<entriesRead; i++ ) {
|
||
|
||
if (entriesRead == 0) {
|
||
//
|
||
// There are no users logged on at the time of this query.
|
||
//
|
||
MSG_LOG(TRACE,
|
||
"GetWkstaNames:NetWkstaUserEnum entriesRead=%d\n",
|
||
entriesRead);
|
||
}
|
||
|
||
if(userInfo0[i].wkui0_username != NULL) {
|
||
status = I_NetNameCanonicalize(
|
||
NULL,
|
||
userInfo0[i].wkui0_username,
|
||
UserName,
|
||
UserNameSize,
|
||
NAMETYPE_USER,
|
||
0);
|
||
if (status != NERR_Success) {
|
||
MSG_LOG(ERROR,"I_NetNameCanonicalize failed %X\n",status);
|
||
}
|
||
}
|
||
|
||
if( *UserName != TEXT('\0')) { // Set up in GetWkstaNames */
|
||
MSG_LOG(TRACE, "Calling MsgAddName\n",0);
|
||
|
||
status = MsgAddName(UserName,0);
|
||
|
||
if (status != NERR_Success) {
|
||
MSG_LOG(
|
||
TRACE,
|
||
"MsgAddUserNames,MessageAddName FAILURE " FORMAT_API_STATUS
|
||
"\n",
|
||
status);
|
||
}
|
||
}
|
||
}
|
||
NetApiBufferFree(userInfo0);
|
||
}
|
||
|
||
|
||
VOID
|
||
MsgAddAlreadyLoggedOnUserNames(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function is used to get information about the previously logged on usernames
|
||
by calling WinStationEnumerate and WinStationQueryInformationW, instead of NetWkstaUserEnum.
|
||
(same job as MsgAddUserNames, adapted for multi-user)
|
||
|
||
Note: It could (should ?) be located elsewhere than in msgnbios. I kept it here just because
|
||
MsgAddUserName itself was already here. (NicolasBD)
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
NERR_Success - Always returned.
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
TCHAR UserName[NCBNAMSZ+1];
|
||
DWORD UserNameSize = sizeof(UserName);
|
||
UINT WdCount, i;
|
||
PLOGONID pWd, pWdTmp;
|
||
ULONG AmountRet;
|
||
WINSTATIONINFORMATIONW QueryBuffer;
|
||
NET_API_STATUS status;
|
||
|
||
*UserName = TEXT('\0');
|
||
|
||
// Enumerate the Sessions
|
||
|
||
if ( gpfnWinStationEnumerate( SERVERNAME_CURRENT, &pWd, &WdCount ) )
|
||
{
|
||
// Success; get all the previously logged on user names and session ids
|
||
|
||
pWdTmp = pWd;
|
||
for( i=0; i < WdCount; i++ ) {
|
||
|
||
if( ((pWdTmp->State == State_Connected) ||
|
||
(pWdTmp->State == State_Active) ||
|
||
(pWdTmp->State == State_Disconnected)))
|
||
{
|
||
if( !gpfnWinStationQueryInformation( SERVERNAME_CURRENT,
|
||
pWdTmp->LogonId,
|
||
WinStationInformation,
|
||
&QueryBuffer,
|
||
sizeof(QueryBuffer),
|
||
&AmountRet ) )
|
||
{
|
||
// Error
|
||
MSG_LOG(ERROR, "MsgAddAlreadyLoggedOnUserNames: Error in QueryInfo %d\n",GetLastError());
|
||
}
|
||
else
|
||
{
|
||
if (QueryBuffer.UserName != NULL)
|
||
{
|
||
MSG_LOG(TRACE,"MsgAddAlreadyLoggedOnUserNames: calling I_NetNameCanonicalize for %ws\n",QueryBuffer.UserName);
|
||
|
||
status = I_NetNameCanonicalize(
|
||
NULL,
|
||
QueryBuffer.UserName,
|
||
UserName,
|
||
UserNameSize,
|
||
NAMETYPE_USER,
|
||
0);
|
||
if (status != NERR_Success)
|
||
{
|
||
MSG_LOG(ERROR,"I_NetNameCanonicalize failed %X\n",status);
|
||
}
|
||
}
|
||
|
||
if( *UserName != TEXT('\0'))
|
||
{
|
||
MSG_LOG(TRACE,"MsgAddAlreadyLoggedOnUserNames: Calling MsgAddName for Session %x \n", pWdTmp->LogonId);
|
||
status = MsgAddName(UserName, pWdTmp->LogonId);
|
||
|
||
if (status != NERR_Success)
|
||
{
|
||
MSG_LOG(TRACE, "MsgAddAlreadyLoggedOnUserNames,MessageAddName FAILURE " FORMAT_API_STATUS "\n", status);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
pWdTmp++;
|
||
}
|
||
|
||
// Free enumeration memory
|
||
|
||
gpfnWinStationFreeMemory(pWd);
|
||
|
||
}
|
||
else
|
||
{
|
||
MSG_LOG (ERROR, "MsgAddAlreadyLoggedOnUserNames: WinStationEnumerate failed, error = %d:\n",GetLastError());
|
||
}
|
||
|
||
return;
|
||
}
|
||
|