windows-nt/Source/XPSP1/NT/net/qos/tc/dll/oscode.c
2020-09-26 16:20:57 +08:00

553 lines
12 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
oscode.c
Abstract:
This module contains support routines for the traffic DLL.
Author:
Jim Stewart (jstew) August 14, 1996
Revision History:
--*/
#include "precomp.h"
//#pragma hdrstop
//#include "oscode.h"
//
// function pointers for NT functions to Open driver
//
FARPROC CreateFileNt = NULL;
FARPROC CloseNt = NULL;
FARPROC NtStatusToDosError = NULL;
FARPROC RtlInitUnicodeStringNt = NULL;
PTCHAR NTDLL = L"\\ntdll.dll";
extern PGPC_NOTIFY_REQUEST_RES GpcResCb;
DWORD
OpenDriver(
OUT HANDLE *pHandle,
IN LPCWSTR DriverName
)
/*++
Routine Description:
This function opens a specified drivers control channel.
Arguments:
pHandle - the handle to the opened driver
DriverName - name of the driver to be opened.
Return Value:
Windows Error Code.
--*/
{
NTSTATUS Status = NO_ERROR;
IO_STATUS_BLOCK ioStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING nameString;
(*RtlInitUnicodeStringNt)(&nameString,DriverName);
InitializeObjectAttributes( &objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
//
// Open a Handle to the driver.
//
Status = (NTSTATUS)(*CreateFileNt)( pHandle,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0);
if (Status == STATUS_SUCCESS) {
//
// send an IOCTL for driver notifications
//
// IOCTL is done when the first client registers
// with TC. This is done in another thread so that
// it can be cancelled when there are no clients
// IoRequestNotify(/*pGpcClient*/);
}
return (Status == STATUS_SUCCESS ? 0 : ERROR_OPEN_FAILED);
}
DWORD
DeviceControl(
IN HANDLE FileHandle,
IN HANDLE EventHandle,
IN PIO_APC_ROUTINE ApcRoutine,
IN PVOID ApcContext,
OUT PIO_STATUS_BLOCK pIoStatBlock,
IN ULONG Ioctl,
IN PVOID setBuffer,
IN ULONG setBufferSize,
IN PVOID OutBuffer,
IN ULONG OutBufferSize )
/*++
Routine Description:
This routine issues a device control request to the GPC
Arguments:
FileHandle - Open handle to the GPC driver
Ioctl - The IOCTL to pass to the stack
setBuffer - Data buffer containing the information to be set
setBufferSize - The size of the set data buffer.
Outbuffer - the returned buffer
OutBufferSize - the size
Return Value:
A winerror status value.
--*/
{
NTSTATUS NtStatus = NO_ERROR;
DWORD Status;
if (NTPlatform) {
IF_DEBUG(IOCTLS) {
WSPRINT(("==>DeviceIoControl: Ioctl= %x\n", Ioctl ));
}
NtStatus = NtDeviceIoControlFile( FileHandle,
EventHandle, // Event
ApcRoutine, // when completed
ApcContext, // for ApcRoutine
pIoStatBlock, // for ApcRoutine
Ioctl, // Control code
setBuffer, // Input buffer
setBufferSize, // Input buffer size
OutBuffer, // Output buffer
OutBufferSize ); // Output buffer size
if (ApcRoutine && NT_SUCCESS(NtStatus)) {
Status = ERROR_SIGNAL_PENDING;
IF_DEBUG(IOCTLS) {
WSPRINT(("DeviceIoControl: ApcRoutine defined Status=0x%X\n",
Status ));
}
} else {
Status = MapNtStatus2WinError(NtStatus);
IF_DEBUG(IOCTLS) {
WSPRINT(("DeviceIoControl: NtStatus=0x%X, Status=0x%X\n",
NtStatus, Status ));
}
#if DBG
if (EventHandle) {
IF_DEBUG(IOCTLS) {
WSPRINT(("DeviceIoControl: Event defined\n"));
}
}
#endif
}
} else {
// yoramb - not supporting other OSs for now.
WSPRINT(("DeviceControl: Only Windows NT supported at this time!\n"));
Status = ERROR_NOT_SUPPORTED;
}
IF_DEBUG(IOCTLS) {
WSPRINT(("<==DeviceIoControl: Returned=0x%X\n",
Status ));
}
return( Status );
}
DWORD
InitializeOsSpecific(VOID)
/*++
Routine Description:
Arguments:
status - status to convert:
Return Value:
status
--*/
{
DWORD Status;
OSVERSIONINFO VersionInfo;
//
// determine the type of system we are running on
//
Status = NO_ERROR;
NTPlatform = TRUE;
VersionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
if (GetVersionEx( &VersionInfo )) {
if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
NTPlatform = TRUE;
}
} else {
WSPRINT(("Could not get version\n"));
}
if (!NTPlatform) {
//
// Initially, only NT compatibility is required.
//
return(ERROR_SERVICE_DOES_NOT_EXIST);
} else {
HINSTANCE NtDll;
WCHAR wszNtDllPath[MAX_PATH];
DWORD dwPos = 0;
//
// get the function ptrs to NT specific routines that we need
//
//
// Obtain the path to the system directory.
//
dwPos = (DWORD) GetSystemDirectoryW(wszNtDllPath, MAX_PATH);
if ((dwPos <= 0) || (dwPos >= (MAX_PATH - wcslen(NTDLL) -1)))
{
//
// Either error or not enough room to write the path to ntdll.dll
//
WSPRINT(("InitializeOsSpecific: Failed to load ntdll.dll\n"));
return(FALSE);
}
//
// Concatenate the word "\NTDLL.DLL"
//
wcsncat(&wszNtDllPath[dwPos], NTDLL, wcslen(NTDLL));
//
// Terminate the string
//
wszNtDllPath[dwPos + wcslen(NTDLL)] = '\0';
//
// Finally, load the library.
//
NtDll = LoadLibraryExW(wszNtDllPath, NULL, 0);
if (NtDll == NULL) {
WSPRINT(("InitializeOsSpecific: Failed to load ntdll.dll\n"));
return(FALSE);
}
CreateFileNt = GetProcAddress(NtDll,"NtCreateFile" );
CloseNt = GetProcAddress( NtDll,"NtClose" );
RtlInitUnicodeStringNt = GetProcAddress( NtDll,"RtlInitUnicodeString" );
NtStatusToDosError = GetProcAddress( NtDll,"RtlNtStatusToDosError" );
if ( (CreateFileNt == NULL) ||
(CloseNt == NULL) ||
(RtlInitUnicodeStringNt == NULL) ||
(NtStatusToDosError == NULL) ) {
Status = ERROR_PATH_NOT_FOUND;
} else {
//
// open a handle to the GPC
//
Status = OpenDriver( &pGlobals->GpcFileHandle,
(LPWSTR)DD_GPC_DEVICE_NAME);
if (Status != NO_ERROR){
WSPRINT(("\tThis version of traffic.dll requires kernel traffic control components.\n"));
WSPRINT(("\tIt is unable to find these components.\n"));
WSPRINT(("\tDilithium crystals may be used in their place...\n"));
}
}
}
return( Status );
}
VOID
DeInitializeOsSpecific(VOID)
/*++
Routine Description:
This procedure closes the file handle passed in, in a platform dependent manner.
Arguments:
Handle - the handle to close
Return Value:
status
--*/
{
//
// only on NT do we close the handle, since on Win95,
// we don't actually open a file for Tcp, so there
// is no handle in that case
//
IF_DEBUG(SHUTDOWN) {
WSPRINT(( "DeInitializeOsSpecific: closing the GPC file handle\n" ));
}
if (NTPlatform && pGlobals->GpcFileHandle)
{
(*CloseNt)( pGlobals->GpcFileHandle );
}
IF_DEBUG(SHUTDOWN) {
WSPRINT(( "<==DeInitializeOsSpecific: exit...\n" ));
}
}
DWORD
MapNtStatus2WinError(
NTSTATUS NtStatus
)
/*++
Routine Description:
This procedure maps the ntstatus return codes Winerrors.
Arguments:
status - status to convert:
Return Value:
status
--*/
{
DWORD stat;
switch (NtStatus) {
case STATUS_SUCCESS:
stat = NO_ERROR;
break;
case STATUS_INSUFFICIENT_RESOURCES:
stat = ERROR_NO_SYSTEM_RESOURCES;
break;
case STATUS_BUFFER_OVERFLOW:
stat = ERROR_MORE_DATA;
break;
case STATUS_INVALID_PARAMETER:
stat = ERROR_INVALID_PARAMETER;
break;
case STATUS_TRANSACTION_TIMED_OUT:
stat = ERROR_TIMEOUT;
break;
case STATUS_REQUEST_NOT_ACCEPTED:
stat = ERROR_NETWORK_BUSY;
break;
case STATUS_NOT_SUPPORTED:
case STATUS_UNSUCCESSFUL:
stat = ERROR_NOT_SUPPORTED;
break;
case STATUS_BUFFER_TOO_SMALL:
stat = ERROR_INSUFFICIENT_BUFFER;
break;
case STATUS_PENDING:
stat = ERROR_SIGNAL_PENDING;
break;
case STATUS_OBJECT_NAME_NOT_FOUND:
stat = ERROR_PATH_NOT_FOUND;
break;
case STATUS_DEVICE_NOT_READY:
stat = ERROR_NOT_READY;
break;
case STATUS_NOT_FOUND:
stat = ERROR_NOT_FOUND;
break;
case STATUS_DUPLICATE_NAME:
stat = ERROR_DUPLICATE_FILTER;
break;
case STATUS_INVALID_HANDLE:
stat = ERROR_INVALID_HANDLE;
break;
case STATUS_DIRECTORY_NOT_EMPTY:
stat = ERROR_TC_SUPPORTED_OBJECTS_EXIST;
break;
case STATUS_TOO_MANY_OPENED_FILES:
stat = ERROR_TOO_MANY_OPEN_FILES;
break;
case STATUS_NOT_IMPLEMENTED:
stat = ERROR_CALL_NOT_IMPLEMENTED;
break;
case STATUS_DATA_ERROR:
stat = ERROR_INVALID_DATA;
break;
case NDIS_STATUS_INCOMPATABLE_QOS:
stat = ERROR_INCOMPATABLE_QOS;
break;
case QOS_STATUS_INVALID_SERVICE_TYPE:
stat = ERROR_INVALID_SERVICE_TYPE;
break;
case QOS_STATUS_INVALID_TOKEN_RATE:
stat = ERROR_INVALID_TOKEN_RATE;
break;
case QOS_STATUS_INVALID_PEAK_RATE:
stat = ERROR_INVALID_PEAK_RATE;
break;
case QOS_STATUS_INVALID_SD_MODE:
stat = ERROR_INVALID_SD_MODE;
break;
case QOS_STATUS_INVALID_QOS_PRIORITY:
stat = ERROR_INVALID_QOS_PRIORITY;
break;
case QOS_STATUS_INVALID_TRAFFIC_CLASS:
stat = ERROR_INVALID_TRAFFIC_CLASS;
break;
case QOS_STATUS_TC_OBJECT_LENGTH_INVALID:
stat = ERROR_TC_OBJECT_LENGTH_INVALID;
break;
case QOS_STATUS_INVALID_FLOW_MODE:
stat = ERROR_INVALID_FLOW_MODE;
break;
case QOS_STATUS_INVALID_DIFFSERV_FLOW:
stat = ERROR_INVALID_DIFFSERV_FLOW;
break;
case QOS_STATUS_DS_MAPPING_EXISTS:
stat = ERROR_DS_MAPPING_EXISTS;
break;
case QOS_STATUS_INVALID_SHAPE_RATE:
stat = ERROR_INVALID_SHAPE_RATE;
break;
case STATUS_NETWORK_UNREACHABLE:
stat = ERROR_NETWORK_UNREACHABLE;
break;
case QOS_STATUS_INVALID_DS_CLASS:
stat = ERROR_INVALID_DS_CLASS;
break;
case ERROR_TOO_MANY_OPEN_FILES:
stat = ERROR_TOO_MANY_CLIENTS;
break;
default:
stat = ERROR_GEN_FAILURE;
}
return stat;
}