503 lines
12 KiB
C
503 lines
12 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1993 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
vwdll.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
ntVdm netWare (Vw) IPX/SPX Functions
|
|||
|
|
|||
|
Vw: The peoples' network
|
|||
|
|
|||
|
VDD functions for DOS/WOW IPX/SPX support
|
|||
|
|
|||
|
Contents:
|
|||
|
VwDllEntryPoint
|
|||
|
VwInitialize
|
|||
|
VWinInitialize
|
|||
|
VwDispatcher
|
|||
|
VwInvalidFunction
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Richard L Firth (rfirth) 30-Sep-1993
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
User-mode Win32
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
30-Sep-1993 rfirth
|
|||
|
Created
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "vw.h"
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
//
|
|||
|
// private prototypes
|
|||
|
//
|
|||
|
|
|||
|
PRIVATE
|
|||
|
VOID
|
|||
|
VwInvalidFunction(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// private data
|
|||
|
//
|
|||
|
|
|||
|
PRIVATE
|
|||
|
VOID
|
|||
|
(*VwDispatchTable[])(VOID) = {
|
|||
|
VwIPXOpenSocket, // 0x00
|
|||
|
VwIPXCloseSocket, // 0x01
|
|||
|
VwIPXGetLocalTarget, // 0x02
|
|||
|
VwIPXSendPacket, // 0x03
|
|||
|
VwIPXListenForPacket, // 0x04
|
|||
|
VwIPXScheduleIPXEvent, // 0x05
|
|||
|
VwIPXCancelEvent, // 0x06
|
|||
|
VwIPXScheduleAESEvent, // 0x07
|
|||
|
VwIPXGetIntervalMarker, // 0x08
|
|||
|
VwIPXGetInternetworkAddress, // 0x09
|
|||
|
VwIPXRelinquishControl, // 0x0A
|
|||
|
VwIPXDisconnectFromTarget, // 0x0B
|
|||
|
VwInvalidFunction, // 0x0C
|
|||
|
VwInvalidFunction, // 0x0D old-style GetMaxPacketSize
|
|||
|
VwInvalidFunction, // 0x0E
|
|||
|
VwInvalidFunction, // 0x0F internal send packet function
|
|||
|
VwSPXInitialize, // 0x10
|
|||
|
VwSPXEstablishConnection, // 0x11
|
|||
|
VwSPXListenForConnection, // 0x12
|
|||
|
VwSPXTerminateConnection, // 0x13
|
|||
|
VwSPXAbortConnection, // 0x14
|
|||
|
VwSPXGetConnectionStatus, // 0x15
|
|||
|
VwSPXSendSequencedPacket, // 0x16
|
|||
|
VwSPXListenForSequencedPacket, // 0x17
|
|||
|
VwInvalidFunction, // 0x18
|
|||
|
VwInvalidFunction, // 0x19
|
|||
|
VwIPXGetMaxPacketSize, // 0x1A
|
|||
|
VwInvalidFunction, // 0x1B
|
|||
|
VwInvalidFunction, // 0x1C
|
|||
|
VwInvalidFunction, // 0x1D
|
|||
|
VwInvalidFunction, // 0x1E
|
|||
|
VwIPXGetInformation, // 0x1F
|
|||
|
VwIPXSendWithChecksum, // 0x20
|
|||
|
VwIPXGenerateChecksum, // 0x21
|
|||
|
VwIPXVerifyChecksum // 0x22
|
|||
|
};
|
|||
|
|
|||
|
#define MAX_IPXSPX_FUNCTION LAST_ELEMENT(VwDispatchTable)
|
|||
|
|
|||
|
WSADATA WsaData = {0};
|
|||
|
HANDLE hAesThread = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// global data
|
|||
|
//
|
|||
|
|
|||
|
SOCKADDR_IPX MyInternetAddress;
|
|||
|
WORD MyMaxPacketSize;
|
|||
|
int Ica;
|
|||
|
BYTE IcaLine;
|
|||
|
|
|||
|
//
|
|||
|
// not-really-global data
|
|||
|
//
|
|||
|
|
|||
|
extern CRITICAL_SECTION SerializationCritSec;
|
|||
|
extern CRITICAL_SECTION AsyncCritSec;
|
|||
|
|
|||
|
//
|
|||
|
// functions
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
VwDllEntryPoint(
|
|||
|
IN PVOID DllHandle,
|
|||
|
IN ULONG Reason,
|
|||
|
IN PCONTEXT Context OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called when the process attaches (LoadLibrary/init) and detaches (FreeLibrary/
|
|||
|
process termination) from this DLL
|
|||
|
|
|||
|
Attach:
|
|||
|
initialize Winsock DLL
|
|||
|
get internet address for this station
|
|||
|
get maximum packet size supported by transport (IPX)
|
|||
|
create AES thread
|
|||
|
|
|||
|
Detach:
|
|||
|
terminate Winsock DLL
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DllHandle - unused
|
|||
|
Reason - checked for process attach/detach
|
|||
|
Context - unused
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD aesThreadId; // unused outside of this function
|
|||
|
|
|||
|
static BOOL CriticalSectionsAreInitialized = FALSE;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER(DllHandle);
|
|||
|
UNREFERENCED_PARAMETER(Context);
|
|||
|
|
|||
|
IPXDBGSTART();
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_INFO,
|
|||
|
"VwDllEntryPoint: %s\n",
|
|||
|
Reason == DLL_PROCESS_ATTACH ? "DLL_PROCESS_ATTACH"
|
|||
|
: Reason == DLL_PROCESS_DETACH ? "DLL_PROCESS_DETACH"
|
|||
|
: Reason == DLL_THREAD_ATTACH ? "DLL_THREAD_ATTACH"
|
|||
|
: Reason == DLL_THREAD_DETACH ? "DLL_THREAD_DETACH"
|
|||
|
: "?"
|
|||
|
));
|
|||
|
|
|||
|
if (Reason == DLL_PROCESS_ATTACH) {
|
|||
|
|
|||
|
int err;
|
|||
|
|
|||
|
//
|
|||
|
// BUGBUG: get ICA values from new VDD service. Right now we grab
|
|||
|
// line 4 on the slave (base = 0x70, modifier = 0x03)
|
|||
|
//
|
|||
|
|
|||
|
Ica = ICA_SLAVE;
|
|||
|
IcaLine = 3;
|
|||
|
|
|||
|
err = WSAStartup(MAKEWORD(1, 1), &WsaData);
|
|||
|
if (err) {
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_FATAL,
|
|||
|
"VwDllEntryPoint: WSAStartup() returns %d\n",
|
|||
|
err
|
|||
|
));
|
|||
|
|
|||
|
return FALSE;
|
|||
|
} else {
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_INFO,
|
|||
|
"VwDllEntryPoint: WsaData:\n"
|
|||
|
"\twVersion : 0x%04x\n"
|
|||
|
"\twHighVersion : 0x%04x\n"
|
|||
|
"\tszDescription : \"%s\"\n"
|
|||
|
"\tszSystemStatus : \"%s\"\n"
|
|||
|
"\tiMaxSockets : %d\n"
|
|||
|
"\tiMaxUdpDg : %d\n"
|
|||
|
"\tlpVendorInfo : 0x%08x\n",
|
|||
|
WsaData.wVersion,
|
|||
|
WsaData.wHighVersion,
|
|||
|
WsaData.szDescription,
|
|||
|
WsaData.szSystemStatus,
|
|||
|
WsaData.iMaxSockets,
|
|||
|
WsaData.iMaxUdpDg,
|
|||
|
WsaData.lpVendorInfo
|
|||
|
));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// retrieve the internet address for this station. Used in
|
|||
|
// IPXGetInternetworkAddress() and IPXSendPacket()
|
|||
|
//
|
|||
|
|
|||
|
err = GetInternetAddress(&MyInternetAddress);
|
|||
|
if (err) {
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_FATAL,
|
|||
|
"VwDllEntryPoint: GetInternetAddress() returns %d\n",
|
|||
|
WSAGetLastError()
|
|||
|
));
|
|||
|
|
|||
|
goto attach_error_exit;
|
|||
|
} else {
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_INFO,
|
|||
|
"VwDllEntryPoint: MyInternetAddress:\n"
|
|||
|
"\tNet : %02.2x-%02.2x-%02.2x-%02.2x\n"
|
|||
|
"\tNode : %02.2x-%02.2x-%02.2x-%02.2x-%02.2x-%02.2x\n",
|
|||
|
MyInternetAddress.sa_netnum[0] & 0xff,
|
|||
|
MyInternetAddress.sa_netnum[1] & 0xff,
|
|||
|
MyInternetAddress.sa_netnum[2] & 0xff,
|
|||
|
MyInternetAddress.sa_netnum[3] & 0xff,
|
|||
|
MyInternetAddress.sa_nodenum[0] & 0xff,
|
|||
|
MyInternetAddress.sa_nodenum[1] & 0xff,
|
|||
|
MyInternetAddress.sa_nodenum[2] & 0xff,
|
|||
|
MyInternetAddress.sa_nodenum[3] & 0xff,
|
|||
|
MyInternetAddress.sa_nodenum[4] & 0xff,
|
|||
|
MyInternetAddress.sa_nodenum[5] & 0xff
|
|||
|
));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// get the maximum packet size supported by IPX. Used in
|
|||
|
// IPXGetMaxPacketSize()
|
|||
|
//
|
|||
|
|
|||
|
err = GetMaxPacketSize(&MyMaxPacketSize);
|
|||
|
if (err) {
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_FATAL,
|
|||
|
"VwDllEntryPoint: GetMaxPacketSize() returns %d\n",
|
|||
|
WSAGetLastError()
|
|||
|
));
|
|||
|
|
|||
|
goto attach_error_exit;
|
|||
|
} else {
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_INFO,
|
|||
|
"VwDllEntryPoint: GetMaxPacketSize: %04x (%d)\n",
|
|||
|
MyMaxPacketSize,
|
|||
|
MyMaxPacketSize
|
|||
|
));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
hAesThread = CreateThread(NULL,
|
|||
|
0,
|
|||
|
(LPTHREAD_START_ROUTINE)VwAesThread,
|
|||
|
NULL,
|
|||
|
0,
|
|||
|
&aesThreadId
|
|||
|
);
|
|||
|
if (hAesThread == NULL) {
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_FATAL,
|
|||
|
"VwDllEntryPoint: CreateThread() returns %d\n",
|
|||
|
GetLastError()
|
|||
|
));
|
|||
|
|
|||
|
goto attach_error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// finally initialize any critical sections
|
|||
|
//
|
|||
|
|
|||
|
InitializeCriticalSection(&SerializationCritSec);
|
|||
|
InitializeCriticalSection(&AsyncCritSec);
|
|||
|
CriticalSectionsAreInitialized = TRUE;
|
|||
|
} else if (Reason == DLL_PROCESS_DETACH) {
|
|||
|
if (hAesThread != NULL) {
|
|||
|
WaitForSingleObject(hAesThread, ONE_TICK * 2);
|
|||
|
CloseHandle(hAesThread);
|
|||
|
}
|
|||
|
|
|||
|
WSACleanup();
|
|||
|
|
|||
|
if (CriticalSectionsAreInitialized) {
|
|||
|
DeleteCriticalSection(&SerializationCritSec);
|
|||
|
DeleteCriticalSection(&AsyncCritSec);
|
|||
|
}
|
|||
|
|
|||
|
IPXDBGEND();
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
|
|||
|
attach_error_exit:
|
|||
|
|
|||
|
//
|
|||
|
// here if any fatal errors on process attach after successfully performing
|
|||
|
// WSAStartup
|
|||
|
//
|
|||
|
|
|||
|
WSACleanup();
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
BYTE
|
|||
|
VWinInitialize(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called by interface when nwipxspx.dll is loaded. We
|
|||
|
return the IRQ value.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The IRQ value.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return 0x73;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
VwInitialize(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called by VDD interface when DLL loaded via call to RegisterModule. We
|
|||
|
get the IRQ value and return it as an interrupt vector in BX
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_INFO,
|
|||
|
"VwInitialize\n"
|
|||
|
));
|
|||
|
|
|||
|
//
|
|||
|
// only lines on slave PIC are available. Currently, lines 3, 4 and 7 are
|
|||
|
// not used. We'll grab line 3 here, but in the future we expect a function
|
|||
|
// to return the available IRQ line
|
|||
|
//
|
|||
|
|
|||
|
setBX( VWinInitialize() );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
VwDispatcher(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Branches to relevant IPX/SPX handler for DOS calls, based on contents of
|
|||
|
VDM BX register.
|
|||
|
|
|||
|
Control transfered here from 16-bit entry point, either as result of call
|
|||
|
to far address returned from INT 2Fh/AH=7A or INT 7Ah
|
|||
|
|
|||
|
Special: we use BX = 0xFFFF to indicate that the app is terminating. The
|
|||
|
TSR hooks INT 0x2F/AX=0x1122 (IFSResetEnvironment)
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD dispatchIndex;
|
|||
|
|
|||
|
dispatchIndex = (DWORD)getBX() & 0x7fff;
|
|||
|
|
|||
|
if (dispatchIndex <= MAX_IPXSPX_FUNCTION) {
|
|||
|
VwDispatchTable[dispatchIndex]();
|
|||
|
} else if (dispatchIndex == 0x7FFE) {
|
|||
|
EsrCallback();
|
|||
|
} else if (dispatchIndex == 0x7FFF) {
|
|||
|
VwTerminateProgram();
|
|||
|
} else {
|
|||
|
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_ERROR,
|
|||
|
"ERROR: VwDispatcher: dispatchIndex = %x\n",
|
|||
|
dispatchIndex
|
|||
|
));
|
|||
|
|
|||
|
//
|
|||
|
// BUGBUG - what's the correct error code to return in this situation?
|
|||
|
// (will it ever arise?)
|
|||
|
//
|
|||
|
|
|||
|
setAX(ERROR_INVALID_FUNCTION);
|
|||
|
setCF(1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
PRIVATE
|
|||
|
VOID
|
|||
|
VwInvalidFunction(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Just alerts us to the fact that an invalid function request was made.
|
|||
|
Useful if any app makes a bad call, or we miss out a required function
|
|||
|
during design/implementation
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|||
|
FUNCTION_ANY,
|
|||
|
IPXDBG_LEVEL_INFO,
|
|||
|
"VwInvalidFunction: BX=%04x\n",
|
|||
|
getBX()
|
|||
|
));
|
|||
|
}
|