Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

415 lines
9.7 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
srvnet.c
Abstract:
Net related code.
Author:
Ofer Porat (oferp) 5-10-93
Revision History:
--*/
#include "os2srv.h"
#include "os2win.h"
#define CALLBACK
#include <nb30.h>
#include "nb30p.h"
static BOOLEAN Os2Netbios2Initialized = FALSE; // server nb 2.0 initialization flag
static HANDLE Os2NbDev; // holds handle to netbios device
static HANDLE Os2NbEvent; // holds event for issuing NCBs
static LANA_ENUM Os2LanaEnum; // holds enumeration of lana numbers in the system
static UCHAR Os2LanaState[MAX_LANA]; // indicates whether lana has been reset
NTSTATUS
Os2NetbiosDirect(
PNCB pNcb,
HANDLE hDev,
HANDLE hEvent
)
{
//
// a direct sync request. does not support chain sends.
//
IO_STATUS_BLOCK iosb;
NTSTATUS Status;
PVOID buffer;
ULONG length;
Status = NtResetEvent(
hEvent,
NULL);
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2NetbiosDirect: NtResetEvent failed, Status = %lx\n", Status));
}
#endif
return(Status);
}
pNcb->ncb_retcode = 0xff;
pNcb->ncb_cmd_cplt = 0xff;
buffer = (PVOID) pNcb->ncb_buffer;
length = (ULONG) pNcb->ncb_length;
Status = NtDeviceIoControlFile(
hDev,
hEvent, // private event
NULL, // APC Routine
NULL, // APC Context
&iosb, // IO Status block
IOCTL_NB_NCB,
pNcb, // InputBuffer
sizeof(NCB),
buffer, // Outputbuffer
length);
if (Status != STATUS_PENDING) {
pNcb->ncb_cmd_cplt = pNcb->ncb_retcode;
return(Status);
}
Status = NtWaitForSingleObject(
hEvent,
TRUE,
NULL);
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2NetbiosDirect: NtWaitForSingleObject failed, Status = %lx\n", Status));
}
#endif
return(Status);
}
pNcb->ncb_cmd_cplt = pNcb->ncb_retcode;
return(STATUS_SUCCESS);
}
NTSTATUS
Os2InitializeNetbios2(
VOID
)
{
//
// opens \device\netbios
// enumerates lana numbers
// zeros lanastate
//
NCB ncb;
PNCB pNcb = &ncb;
IO_STATUS_BLOCK iosb;
OBJECT_ATTRIBUTES objattr;
UNICODE_STRING unicode;
NTSTATUS Status;
HANDLE hDev;
HANDLE hEvent;
if (((ULONG)pNcb & 3) != 0) { // pointer must be DWORD aligned
return(STATUS_DATATYPE_MISALIGNMENT);
}
Status = NtCreateEvent(
&hEvent,
EVENT_ALL_ACCESS,
NULL,
NotificationEvent,
TRUE);
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2InitializeNetbios2: NtCreateEvent failed, Status = %lx\n", Status));
}
#endif
return(Status);
}
RtlInitUnicodeString( &unicode, NB_DEVICE_NAME);
InitializeObjectAttributes(
&objattr, // obj attr to initialize
&unicode, // string to use
OBJ_CASE_INSENSITIVE, // Attributes
NULL, // Root directory
NULL); // Security Descriptor
Status = NtCreateFile(
&hDev, // ptr to handle
GENERIC_READ // desired...
| GENERIC_WRITE, // ...access
&objattr, // name & attributes
&iosb, // I/O status block.
NULL, // alloc size.
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_DELETE // share...
| FILE_SHARE_READ
| FILE_SHARE_WRITE, // ...access
FILE_OPEN_IF, // create disposition
0, // ...options
NULL, // EA buffer
0L ); // Ea buffer len
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2InitializeNetbios2: NtCreateFile failed, Status = %lx\n", Status));
}
#endif
NtClose(hEvent);
return(Status);
}
RtlZeroMemory(pNcb, sizeof(NCB));
pNcb->ncb_command = NCBENUM;
pNcb->ncb_buffer = (PUCHAR) &Os2LanaEnum;
pNcb->ncb_length = sizeof(LANA_ENUM);
Status = Os2NetbiosDirect(pNcb, hDev, hEvent);
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2InitializeNetbios2: Lana enumeration failed, Status = %lx\n", Status));
}
#endif
NtClose(hDev);
NtClose(hEvent);
return(Status);
}
if (pNcb->ncb_retcode != NRC_GOODRET ||
Os2LanaEnum.length == 0) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2InitializeNetbios2: Lana enumeration failed, ncb_retcode = 0x%x, num of lanas = %d\n",
pNcb->ncb_retcode, Os2LanaEnum.length));
}
#endif
NtClose(hDev);
NtClose(hEvent);
return(STATUS_NETWORK_ACCESS_DENIED);
}
RtlZeroMemory(Os2LanaState, sizeof(Os2LanaState));
Os2NbEvent = hEvent;
Os2NbDev = hDev;
Os2Netbios2Initialized = TRUE;
return(STATUS_SUCCESS);
}
VOID
Os2Nb2InitUser(
IN HANDLE ClientProcess,
OUT POS2_NETBIOS_MSG a
)
{
NTSTATUS Status;
HANDLE TargetHandle;
a->LanaEnumLength = Os2LanaEnum.length;
RtlMoveMemory(a->LanaEnum, Os2LanaEnum.lana, MAX_LANA);
Status = NtDuplicateObject(
NtCurrentProcess(),
Os2NbDev,
ClientProcess,
&TargetHandle,
0L,
0L,
DUPLICATE_SAME_ACCESS
);
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2Nb2InitUser: NtDuplicateObject failed, Status = %lx\n", Status));
}
#endif
a->ReturnStatus = Status;
return;
}
a->hDev = TargetHandle;
return;
}
NTSTATUS
Os2ResetLana(
IN UCHAR LanaNum
)
{
NCB ncb;
PNCB pNcb = &ncb;
NTSTATUS Status;
if (LanaNum >= Os2LanaEnum.length) {
return(STATUS_INVALID_PARAMETER);
}
if (((ULONG)pNcb & 3) != 0) { // pointer must be DWORD aligned
return(STATUS_DATATYPE_MISALIGNMENT);
}
RtlZeroMemory(pNcb, sizeof(NCB));
pNcb->ncb_command = NCBRESET;
pNcb->ncb_callname[0] = 0xff;
pNcb->ncb_callname[1] = 0xff;
pNcb->ncb_callname[2] = 0xff;
pNcb->ncb_callname[3] = 1;
pNcb->ncb_lana_num = Os2LanaEnum.lana[LanaNum];
Status = Os2NetbiosDirect(pNcb, Os2NbDev, Os2NbEvent);
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2ResetLana: Os2NetbiosDirect failed, Status = %lx\n", Status));
}
#endif
return(Status);
}
if (pNcb->ncb_retcode != NRC_GOODRET) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2ResetLana: Os2NetbiosDirect failed, ncb_retcode = 0x%x\n", pNcb->ncb_retcode));
}
#endif
return(STATUS_NETWORK_ACCESS_DENIED);
}
Os2LanaState[LanaNum] = 0x1;
return(STATUS_SUCCESS);
}
VOID
Os2Nb2InitLana(
IN OUT POS2_NETBIOS_MSG a
)
{
UCHAR Net;
NTSTATUS Status;
if (a->NetNumber == 0) { // use default net ?
if (Os2LanaEnum.length >= DEFAULT_NET) {
Net = DEFAULT_NET - 1;
} else {
Net = 0;
}
} else {
if (Os2LanaEnum.length >= a->NetNumber) {
Net = a->NetNumber - 1;
} else {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2Nb2InitLana: Got request for invalid Net = %d\n", a->NetNumber));
}
#endif
a->RetCode = NB2ERR_INVALID_LANA;
return;
}
}
if (Os2LanaState[Net] == 0x1) {
//
// already reset
//
return;
}
Status = Os2ResetLana(Net);
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2Nb2InitLana: Os2ResetLana failed, Status = %lx\n", Status));
}
#endif
a->ReturnStatus = Status;
}
}
BOOLEAN
Os2Netbios2Request(
IN POS2_THREAD t,
IN POS2_API_MSG m
)
{
POS2_NETBIOS_MSG a = &m->u.Netbios2Request;
NTSTATUS Status;
a->RetCode = NB2ERR_SUCCESS;
a->ReturnStatus = STATUS_SUCCESS;
if (!Os2Netbios2Initialized) {
Status = Os2InitializeNetbios2();
if (!NT_SUCCESS(Status)) {
#if DBG
IF_OS2_DEBUG( NET ) {
KdPrint(("Os2Netbios2Request: Os2InitializeNetbios2 failed, Status = %lx\n", Status));
}
#endif
a->ReturnStatus = Status;
return(TRUE);
}
}
switch (a->RequestType) {
case NB2_INIT:
Os2Nb2InitUser(t->Process->ProcessHandle, a);
break;
case NB2_INIT_LANA:
Os2Nb2InitUser(t->Process->ProcessHandle, a);
if (NT_SUCCESS(a->ReturnStatus) &&
a->RetCode == NB2ERR_SUCCESS) {
Os2Nb2InitLana(a);
}
break;
case NB2_LANA:
Os2Nb2InitLana(a);
break;
default:
a->RetCode = NB2ERR_INVALID_REQUEST;
break;
}
return(TRUE);
}