|
|
/////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (c) 1996, 1997 Microsoft Corporation
//
//
// Module Name:
// test.c
//
// Abstract:
//
// This file is a test to find out if dual binding to NDIS and KS works
//
// Author:
//
// P Porzuczek
//
// Environment:
//
// Revision History:
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef DWORD
#define DWORD ULONG
#endif
#include <forward.h>
#include <wdm.h>
#include <link.h>
#include <ipsink.h>
#include "device.h"
#include "main.h"
VOID vUnload(IN PDRIVER_OBJECT pDriverObject);
//////////////////////////////////////////////////////////////////////////////
//
//
NTSTATUS RegisterDevice( IN PVOID NdisWrapperHandle, IN UNICODE_STRING *DeviceName, IN UNICODE_STRING *SymbolicName, IN PDRIVER_DISPATCH MajorFunctions[], OUT PDEVICE_OBJECT *pDeviceObject, OUT PVOID *NdisDeviceHandle );
//////////////////////////////////////////////////////////////////////////////
NTSTATUS ntDispatchOpenClose( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ) //////////////////////////////////////////////////////////////////////////////
{ NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpSp = NULL;
//
// Make sure status information is consistent every time.
//
IoMarkIrpPending (pIrp); pIrp->IoStatus.Status = STATUS_PENDING; pIrp->IoStatus.Information = 0;
//
// Get a pointer to the current stack location in the IRP. This is where
// the function codes and parameters are stored.
//
pIrpSp = IoGetCurrentIrpStackLocation (pIrp);
//
// Case on the function that is being performed by the requestor. If the
// operation is a valid one for this device, then make it look like it was
// successfully completed, where possible.
//
switch (pIrpSp->MajorFunction) {
//
// The Create function opens a transport object (either address or
// connection). Access checking is performed on the specified
// address to ensure security of transport-layer addresses.
//
case IRP_MJ_CREATE: status = STATUS_SUCCESS; break;
case IRP_MJ_CLEANUP: status = STATUS_SUCCESS; break;
case IRP_MJ_CLOSE: status = STATUS_SUCCESS; break;
default: status = STATUS_INVALID_DEVICE_REQUEST;
}
if (status != STATUS_PENDING) { pIrpSp->Control &= ~SL_PENDING_RETURNED; pIrp->IoStatus.Status = status; IoCompleteRequest (pIrp, IO_NETWORK_INCREMENT); }
return status; }
//////////////////////////////////////////////////////////////////////////////
NTSTATUS ntDispatchInternal ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ) //////////////////////////////////////////////////////////////////////////////
{ NTSTATUS ntStatus = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpSp = NULL;
ULONG ulIoctl = 0L; ULONG ulInputLen = 0L; ULONG ulOutputLen = 0L; PVOID pvInputBuffer = NULL; PVOID pvOutputBuffer = NULL;
PIPSINK_NDIS_COMMAND pCmd = NULL;
//
// Make sure status information is consistent every time.
//
IoMarkIrpPending (pIrp); pIrp->IoStatus.Status = STATUS_PENDING; pIrp->IoStatus.Information = 0;
//
// Get a pointer to the current stack location in the IRP. This is where
// the function codes and parameters are stored.
//
pIrpSp = IoGetCurrentIrpStackLocation (pIrp);
ulIoctl = pIrpSp->Parameters.DeviceIoControl.IoControlCode; ulInputLen = pIrpSp->Parameters.DeviceIoControl.InputBufferLength; ulOutputLen = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength; pvInputBuffer = pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
//
// Case on the function that is being performed by the requestor. If the
// operation is a valid one for this device, then make it look like it was
// successfully completed, where possible.
//
switch (pIrpSp->MajorFunction) {
case IRP_MJ_CREATE: TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal called, IRP_MJ_CREATE\n")); TEST_DEBUG (TEST_DBG_TRACE, (" FileObject: %08X\n", pIrpSp->FileObject)); ntStatus = STATUS_SUCCESS; break;
case IRP_MJ_CLEANUP: TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal called, IRP_MJ_CLEANUP\n")); ntStatus = STATUS_SUCCESS; break;
case IRP_MJ_CLOSE: TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal called, IRP_MJ_CLOSE\n")); ntStatus = STATUS_SUCCESS; break;
case IRP_MJ_INTERNAL_DEVICE_CONTROL: TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal called, IRP_MJ_INTERNAL_DEVICE_CONTROL\n"));
switch (pIrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_GET_INTERFACE: TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal control code: IOCTL_GET_NDIS_INTERFACE\n"));
pCmd = (PIPSINK_NDIS_COMMAND) pvInputBuffer;
switch (pCmd->ulCommandID) { case CMD_QUERY_INTERFACE: TEST_DEBUG (TEST_DBG_TRACE, ("ntDispatchInternal control code: QueryInterface Command\n"));
//
// Define paramters we're returning to the streaming component
//
pCmd->Parameter.Query.pNdisAdapter = (PVOID) global_pAdapter;
//
// Save a pointer to the Streaming components vtable
//
global_pAdapter->pFilter = (PIPSINK_FILTER) pCmd->Parameter.Query.pStreamAdapter;
//
// Increment the reference count for the filter
//
global_pAdapter->pFilter->lpVTable->AddRef (global_pAdapter->pFilter);
ntStatus = STATUS_SUCCESS; break;
default: ntStatus = STATUS_INVALID_DEVICE_REQUEST; break; } break;
default: ntStatus = STATUS_INVALID_DEVICE_REQUEST; break; } break;
default: ntStatus = STATUS_INVALID_DEVICE_REQUEST; break;
}
//ret:
if (ntStatus != STATUS_PENDING) { pIrpSp->Control &= ~SL_PENDING_RETURNED; pIrp->IoStatus.Status = ntStatus; IoCompleteRequest (pIrp, IO_NETWORK_INCREMENT); }
return ntStatus; }
//////////////////////////////////////////////////////////////////////////////
NTSTATUS ntInitializeDeviceObject( IN PVOID nhWrapperHandle, IN PADAPTER pAdapter, OUT PDEVICE_OBJECT *pndisDriverObject, OUT PVOID *pndisDeviceHandle ) //////////////////////////////////////////////////////////////////////////////
{ NTSTATUS status = 0l; PDEVICE_OBJECT pDeviceObject = NULL; PVOID ndisDeviceHandle = NULL; UNICODE_STRING DeviceName; UNICODE_STRING SymbolicName; PDRIVER_DISPATCH pDispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1] = {NULL}; //wdm defines IRP_MJ_MAXIMUM_FUNCTION = IRP_MJ_PNP
//
// Set the dispatch entries we are interested in.
//
pDispatchTable[IRP_MJ_CREATE] = ntDispatchOpenClose; pDispatchTable[IRP_MJ_CLOSE] = ntDispatchOpenClose; pDispatchTable[IRP_MJ_CLEANUP] = ntDispatchOpenClose; pDispatchTable[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ntDispatchInternal; pDispatchTable[IRP_MJ_DEVICE_CONTROL] = NULL; pDispatchTable[IRP_MJ_FLUSH_BUFFERS] = NULL; pDispatchTable[IRP_MJ_PNP] = NULL; pDispatchTable[IRP_MJ_POWER] = NULL; pDispatchTable[IRP_MJ_QUERY_INFORMATION] = NULL; pDispatchTable[IRP_MJ_READ] = NULL; pDispatchTable[IRP_MJ_SET_INFORMATION] = NULL; pDispatchTable[IRP_MJ_SHUTDOWN] = NULL; pDispatchTable[IRP_MJ_SYSTEM_CONTROL] = NULL; pDispatchTable[IRP_MJ_WRITE] = NULL;
//
// Initialize the device, dosdevice and symbolic names.
//
RtlInitUnicodeString(&DeviceName, BDA_NDIS_MINIPORT); RtlInitUnicodeString(&SymbolicName, BDA_NDIS_SYMBOLIC_NAME);
status = RegisterDevice (nhWrapperHandle, &DeviceName, &SymbolicName, pDispatchTable, &pDeviceObject, &ndisDeviceHandle);
if (status == STATUS_SUCCESS) { *pndisDeviceHandle = ndisDeviceHandle; *pndisDriverObject = pDeviceObject; }
CTL_CODE(FILE_DEVICE_UNKNOWN,IOCTL_GET_INTERFACE,METHOD_BUFFERED,FILE_READ_ACCESS); return status; }
#ifdef WIN9X
//////////////////////////////////////////////////////////////////////////////
NTSTATUS ntCreateDeviceContext( IN PDRIVER_OBJECT pDriverObject ) //////////////////////////////////////////////////////////////////////////////
{ NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_OBJECT pDeviceObject; UNICODE_STRING DeviceName; UNICODE_STRING dosdeviceName; UNICODE_STRING symbolicName;
//
// Create the device object for the sample transport, allowing
// room at the end for the device name to be stored (for use
// in logging errors).
//
RtlInitUnicodeString(&DeviceName, BDA_NDIS_MINIPORT); ntStatus = IoCreateDevice( pDriverObject, 0, &DeviceName, 0x00000022, // FILE_DEVICE_UNKNOWN
0, FALSE, &pDeviceObject);
CTL_CODE(FILE_DEVICE_UNKNOWN,IOCTL_GET_INTERFACE,METHOD_BUFFERED,FILE_READ_ACCESS);
if (ntStatus != STATUS_SUCCESS) { goto ret; }
//
// Set device flag(s).
//
pDeviceObject->Flags |= DO_DIRECT_IO;
//
// Create Symbolic Link
//
RtlInitUnicodeString(&dosdeviceName, BDA_NDIS_MINIPORT); RtlInitUnicodeString(&symbolicName, BDA_NDIS_SYMBOLIC_NAME);
ntStatus = IoCreateSymbolicLink( &symbolicName, &dosdeviceName );
if (ntStatus != STATUS_SUCCESS) { ASSERT (FALSE); }
pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
ret:
return ntStatus; }
//////////////////////////////////////////////////////////////////////////////
NTSTATUS ntInitializeDriverObject( PDRIVER_OBJECT *ppDriverObject ) //////////////////////////////////////////////////////////////////////////////
{ NTSTATUS ntStatus = 0l; UNICODE_STRING objectName; PDRIVER_OBJECT pDriverObject = *ppDriverObject;
//
// In case we did not create this driver object, set our global variable
// equal to the one supplied.
//
pGlobalDriverObject = pDriverObject; *ppDriverObject = pDriverObject;
//
// Create a device object and symbolic name.
//
ntStatus = ntCreateDeviceContext(pDriverObject); if(ntStatus) { goto ret; }
ret:
return ntStatus; }
//////////////////////////////////////////////////////////////////////////////
VOID vSetDriverDispatchTable( PDRIVER_OBJECT pDriverObject ) //////////////////////////////////////////////////////////////////////////////
{
//
// Initialize the driver object with this driver's entry points.
//
pDriverObject->MajorFunction [IRP_MJ_CREATE] = ntDispatchOpenClose; pDriverObject->MajorFunction [IRP_MJ_CLOSE] = ntDispatchOpenClose; pDriverObject->MajorFunction [IRP_MJ_CLEANUP] = ntDispatchOpenClose; pDriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] = ntDispatchInternal; pDriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = NULL; pDriverObject->DriverUnload = vUnload;
}
#endif
|