318 lines
7.3 KiB
C
318 lines
7.3 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
error.c
|
||
|
||
Abstract:
|
||
|
||
This module contains code which defines the NetBIOS driver's
|
||
translation between Netbios error codes and NTSTATUS codes.
|
||
|
||
Author:
|
||
|
||
Colin Watson (ColinW) 28-Mar-1991
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "nb.h"
|
||
struct {
|
||
unsigned char NbError;
|
||
NTSTATUS NtStatus;
|
||
} Nb_Error_Map[] = {
|
||
{ NRC_GOODRET , STATUS_SUCCESS},
|
||
{ NRC_PENDING , STATUS_PENDING},
|
||
{ NRC_ILLCMD , STATUS_INVALID_DEVICE_REQUEST},
|
||
{ NRC_BUFLEN , STATUS_INVALID_PARAMETER},
|
||
{ NRC_CMDTMO , STATUS_IO_TIMEOUT},
|
||
{ NRC_INCOMP , STATUS_BUFFER_OVERFLOW},
|
||
{ NRC_INCOMP , STATUS_BUFFER_TOO_SMALL},
|
||
{ NRC_SNUMOUT , STATUS_INVALID_HANDLE},
|
||
{ NRC_NORES , STATUS_INSUFFICIENT_RESOURCES},
|
||
{ NRC_CMDCAN , STATUS_CANCELLED},
|
||
{ NRC_INUSE , STATUS_DUPLICATE_NAME},
|
||
{ NRC_NAMTFUL , STATUS_TOO_MANY_NAMES},
|
||
{ NRC_LOCTFUL , STATUS_TOO_MANY_SESSIONS},
|
||
{ NRC_REMTFUL , STATUS_REMOTE_NOT_LISTENING},
|
||
{ NRC_NOCALL , STATUS_BAD_NETWORK_PATH},
|
||
{ NRC_NOCALL , STATUS_HOST_UNREACHABLE},
|
||
{ NRC_NOCALL , STATUS_CONNECTION_REFUSED},
|
||
{ NRC_LOCKFAIL , STATUS_WORKING_SET_QUOTA},
|
||
{ NRC_SABORT , STATUS_REMOTE_DISCONNECT},
|
||
{ NRC_SABORT , STATUS_CONNECTION_RESET},
|
||
{ NRC_SCLOSED , STATUS_LOCAL_DISCONNECT},
|
||
{ NRC_SABORT , STATUS_LINK_FAILED},
|
||
{ NRC_DUPNAME , STATUS_SHARING_VIOLATION},
|
||
{ NRC_SYSTEM , STATUS_UNSUCCESSFUL},
|
||
{ NRC_BUFLEN , STATUS_ACCESS_VIOLATION},
|
||
{ NRC_ILLCMD , STATUS_NONEXISTENT_EA_ENTRY}
|
||
};
|
||
|
||
#define NUM_NB_ERRORS sizeof(Nb_Error_Map) / sizeof(Nb_Error_Map[0])
|
||
|
||
unsigned char
|
||
NbMakeNbError(
|
||
IN NTSTATUS Error
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine converts the NTSTATUS to and NBCB error.
|
||
|
||
Arguments:
|
||
|
||
Error - Supplies the NTSTATUS to be converted.
|
||
|
||
Return Value:
|
||
|
||
The mapped error.
|
||
|
||
--*/
|
||
{
|
||
int i;
|
||
|
||
for (i=0;i<NUM_NB_ERRORS;i++) {
|
||
if (Nb_Error_Map[i].NtStatus == Error) {
|
||
|
||
IF_NBDBG (NB_DEBUG_ERROR_MAP) {
|
||
NbPrint( ("NbMakeNbError %X becomes %x\n",
|
||
Error,
|
||
Nb_Error_Map[i].NbError));
|
||
}
|
||
|
||
return Nb_Error_Map[i].NbError;
|
||
}
|
||
}
|
||
IF_NBDBG (NB_DEBUG_ERROR_MAP) {
|
||
NbPrint( ("NbMakeNbError %X becomes %x\n", Error, NRC_SYSTEM ));
|
||
}
|
||
|
||
return NRC_SYSTEM;
|
||
|
||
}
|
||
|
||
NTSTATUS
|
||
NbLanStatusAlert(
|
||
IN PDNCB pdncb,
|
||
IN PIRP Irp,
|
||
IN PIO_STACK_LOCATION IrpSp
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is used to save a lan_status_alert NCB for a
|
||
particular network adapter.
|
||
|
||
Arguments:
|
||
|
||
pdncb - Pointer to the NCB.
|
||
|
||
Irp - Pointer to the request packet representing the I/O request.
|
||
|
||
IrpSp - Pointer to current IRP stack frame.
|
||
|
||
Return Value:
|
||
|
||
The function value is the status of the operation.
|
||
|
||
--*/
|
||
|
||
{
|
||
PFCB pfcb = IrpSp->FileObject->FsContext2;
|
||
PLANA_INFO plana;
|
||
KIRQL OldIrql; // Used when SpinLock held.
|
||
|
||
IF_NBDBG (NB_DEBUG_LANSTATUS) {
|
||
NbPrint(( "\n****** Start of NbLanStatusAlert ****** pdncb %lx\n", pdncb ));
|
||
}
|
||
|
||
LOCK( pfcb, OldIrql );
|
||
|
||
if ( pdncb->ncb_lana_num > pfcb->MaxLana ) {
|
||
|
||
UNLOCK( pfcb, OldIrql );
|
||
NCB_COMPLETE( pdncb, NRC_BRIDGE );
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
if (( pfcb->ppLana[pdncb->ncb_lana_num] == (LANA_INFO *) NULL ) ||
|
||
( pfcb->ppLana[pdncb->ncb_lana_num]->Status != NB_INITIALIZED) ) {
|
||
|
||
UNLOCK( pfcb, OldIrql );
|
||
IF_NBDBG (NB_DEBUG_LANSTATUS) {
|
||
NbPrint( (" not found\n"));
|
||
}
|
||
|
||
NCB_COMPLETE( pdncb, NRC_SNUMOUT );
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
plana = pfcb->ppLana[pdncb->ncb_lana_num];
|
||
|
||
QueueRequest(&plana->LanAlertList, pdncb, Irp, pfcb, OldIrql, FALSE);
|
||
|
||
return STATUS_PENDING;
|
||
}
|
||
|
||
VOID
|
||
CancelLanAlert(
|
||
IN PFCB pfcb,
|
||
IN PDNCB pdncb
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is used to cancel a lan_status_alert NCB for a
|
||
particular network adapter.
|
||
|
||
Arguments:
|
||
|
||
pfcb - Supplies a pointer to the Fcb that the NCB refers to.
|
||
|
||
pdncb - Pointer to the NCB.
|
||
|
||
Return Value:
|
||
|
||
none.
|
||
|
||
--*/
|
||
|
||
{
|
||
PLANA_INFO plana;
|
||
PLIST_ENTRY Entry;
|
||
PLIST_ENTRY NextEntry;
|
||
|
||
IF_NBDBG (NB_DEBUG_LANSTATUS) {
|
||
NbPrint(( "\n****** Start of CancelLanAlert ****** pdncb %lx\n", pdncb ));
|
||
}
|
||
|
||
if ( pdncb->ncb_lana_num > pfcb->MaxLana ) {
|
||
NCB_COMPLETE( pdncb, NRC_BRIDGE );
|
||
return;
|
||
}
|
||
|
||
if (( pfcb->ppLana[pdncb->ncb_lana_num] == NULL ) ||
|
||
( pfcb->ppLana[pdncb->ncb_lana_num]->Status != NB_INITIALIZED) ) {
|
||
|
||
NCB_COMPLETE( pdncb, NRC_SNUMOUT );
|
||
return;
|
||
}
|
||
|
||
plana = pfcb->ppLana[pdncb->ncb_lana_num];
|
||
|
||
for (Entry = plana->LanAlertList.Flink ;
|
||
Entry != &plana->LanAlertList ;
|
||
Entry = NextEntry) {
|
||
PDNCB pAnotherNcb;
|
||
|
||
NextEntry = Entry->Flink;
|
||
|
||
pAnotherNcb = CONTAINING_RECORD( Entry, DNCB, ncb_next);
|
||
IF_NBDBG (NB_DEBUG_LANSTATUS) {
|
||
NbDisplayNcb( pAnotherNcb );
|
||
}
|
||
|
||
if ( (PUCHAR)pAnotherNcb->users_ncb == pdncb->ncb_buffer) {
|
||
// Found the request to cancel
|
||
PIRP Irp;
|
||
|
||
IF_NBDBG (NB_DEBUG_LANSTATUS) {
|
||
NbPrint(( "Found request to cancel\n" ));
|
||
}
|
||
RemoveEntryList( &pAnotherNcb->ncb_next );
|
||
|
||
Irp = pAnotherNcb->irp;
|
||
|
||
IoAcquireCancelSpinLock(&Irp->CancelIrql);
|
||
|
||
//
|
||
// Remove the cancel request for this IRP. If its cancelled then its
|
||
// ok to just process it because we will be returning it to the caller.
|
||
//
|
||
|
||
Irp->Cancel = FALSE;
|
||
|
||
IoSetCancelRoutine(Irp, NULL);
|
||
|
||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||
|
||
NCB_COMPLETE( pAnotherNcb, NRC_CMDCAN );
|
||
|
||
Irp->IoStatus.Information = FIELD_OFFSET( DNCB, ncb_cmd_cplt );
|
||
|
||
NbCompleteRequest( Irp, STATUS_SUCCESS );
|
||
|
||
NCB_COMPLETE( pdncb, NRC_GOODRET );
|
||
|
||
return;
|
||
}
|
||
}
|
||
NCB_COMPLETE( pdncb, NRC_CANOCCR );
|
||
|
||
return;
|
||
}
|
||
|
||
NTSTATUS
|
||
NbTdiErrorHandler (
|
||
IN PVOID Context,
|
||
IN NTSTATUS Status
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called on any error indications passed back from the
|
||
transport. It implements LAN_STATUS_ALERT.
|
||
|
||
Arguments:
|
||
|
||
IN PVOID Context - Supplies the pfcb for the address.
|
||
|
||
IN NTSTATUS Status - Supplies the error.
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Status of event indication
|
||
|
||
--*/
|
||
|
||
{
|
||
PLANA_INFO plana = (PLANA_INFO) Context;
|
||
PDNCB pdncb;
|
||
|
||
IF_NBDBG (NB_DEBUG_LANSTATUS) {
|
||
NbPrint( ("NbTdiErrorHandler PLANA: %lx, Status %X\n", plana, Status));
|
||
}
|
||
|
||
ASSERT( plana->Signature == LANA_INFO_SIGNATURE);
|
||
|
||
while ( (pdncb = DequeueRequest( &plana->LanAlertList)) != NULL ) {
|
||
|
||
IF_NBDBG (NB_DEBUG_LANSTATUS) {
|
||
NbPrint( ("NbTdiErrorHandler complete pdncb: %lx\n", pdncb ));
|
||
}
|
||
|
||
NCB_COMPLETE( pdncb, NbMakeNbError( Status) );
|
||
|
||
pdncb->irp->IoStatus.Information = FIELD_OFFSET( DNCB, ncb_cmd_cplt );
|
||
|
||
NbCheckAndCompleteIrp32(pdncb->irp);
|
||
|
||
NbCompleteRequest( pdncb->irp, STATUS_SUCCESS );
|
||
}
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|