|
|
/****************************************************************************/ /* nmpapi.c */ /* */ /* RDP Miniport API Functions */ /* */ /* Copyright(c) Microsoft 1998 */ /****************************************************************************/
#define _NTDRIVER_
#ifndef FAR
#define FAR
#endif
#include "dderror.h"
#include "ntosp.h"
#include "stdarg.h"
#include "stdio.h"
#include "zwapi.h"
#undef PAGED_CODE
#include "ntddvdeo.h"
#include "video.h"
#include "nmpapi.h"
// #define TRC_FILE "nmpapi"
// #include <adcgbtyp.h>
// #include <adcgmcro.h>
// #include <atrcapi.h>
/****************************************************************************/ /* Function Prototypes */ /****************************************************************************/ ULONG DriverEntry( PVOID Context1, PVOID Context2 );
VP_STATUS MPFindAdapter( PVOID HwDeviceExtension, PVOID HwContext, PWSTR ArgumentString, PVIDEO_PORT_CONFIG_INFO ConfigInfo, PUCHAR Again );
BOOLEAN MPInitialize( PVOID HwDeviceExtension );
BOOLEAN MPStartIO( PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket );
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(PAGE,DriverEntry)
#pragma alloc_text(PAGE,MPFindAdapter)
#pragma alloc_text(PAGE,MPInitialize)
#pragma alloc_text(PAGE,MPStartIO)
#endif
/****************************************************************************/ /* */ /* DriverEntry */ /* */ /* Routine Description: */ /* */ /* Installable driver initialization entry point. */ /* This entry point is called directly by the I/O system. */ /* */ /* Arguments: */ /* */ /* Context1 - First context value passed by the operating system. */ /* This is the value with which the miniport driver */ /* calls VideoPortInitialize(). */ /* */ /* Context2 - Second context value passed by the operating system. */ /* This is the value with which the miniport driver */ /* calls VideoPortInitialize(). */ /* */ /* Return Value: */ /* */ /* Status from VideoPortInitialize() */ /* */ /****************************************************************************/ ULONG DriverEntry ( PVOID Context1, PVOID Context2 ) {
VIDEO_HW_INITIALIZATION_DATA hwInitData; ULONG status; ULONG initializationStatus; ULONG regValue = 0;
/************************************************************************/ /* first up, ensure that the DD will NOT get attached to the desktop at */ /* boot time. This might happen if the registry changes were made and */ /* then the machine got powered off rather than shut down cleanly */ /* */ /* @@@ Is it OK to just hard code this path? I notice that this _is_ */ /* done elsewhere! */ /************************************************************************/ RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Hardware Profiles\\Current\\System" L"\\CurrentControlSet\\Services\\RDPCDD\\DEVICE0", L"Attach.ToDesktop", REG_DWORD, ®Value, sizeof(ULONG));
RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Hardware Profiles\\Current\\System" L"\\CurrentControlSet\\Control\\Video" L"\\{DEB039CC-B704-4F53-B43E-9DD4432FA2E9}\\0000", L"Attach.ToDesktop", REG_DWORD, ®Value, sizeof(ULONG));
/************************************************************************/ /* Zero out structure. */ /************************************************************************/ VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
/************************************************************************/ /* Specify sizes of structure and extension. */ /************************************************************************/ hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
/************************************************************************/ /* Set entry points. */ /************************************************************************/ hwInitData.HwFindAdapter = MPFindAdapter; hwInitData.HwInitialize = MPInitialize; hwInitData.HwInterrupt = NULL; hwInitData.HwStartIO = MPStartIO;
/************************************************************************/ /* Determine the size we require for the device extension. */ /************************************************************************/ hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
/************************************************************************/ /* Once all the relevant information has been stored, call the video */ /* port driver to do the initialization. */ /* */ /* Since we don't actually have any hardware, just claim its on the PCI */ /* bus */ /************************************************************************/ hwInitData.AdapterInterfaceType = PCIBus;
return (VideoPortInitialize(Context1, Context2, &hwInitData, NULL));
} /* DriverEntry() */
/****************************************************************************/ /* */ /* MPFindAdapter */ /* */ /* Routine Description: */ /* */ /* This routine is called to determine if the adapter for this driver */ /* is present in the system. */ /* If it is present, the function fills out some information describing */ /* the adapter. */ /* */ /* Arguments: */ /* */ /* HwDeviceExtension - Supplies the miniport driver's adapter storage. */ /* This storage is initialized to zero before this call. */ /* */ /* HwContext - Supplies the context value which was passed to */ /* VideoPortInitialize(). */ /* */ /* ArgumentString - Suuplies a NULL terminated ASCII string. This string */ /* originates from the user. */ /* */ /* ConfigInfo - Returns the configuration information structure which is */ /* filled by the miniport driver. This structure is initialized with */ /* any knwon configuration information (such as SystemIoBusNumber) by */ /* the port driver. Where possible, drivers should have one set of */ /* defaults which do not require any supplied configuration */ /* information. */ /* */ /* Again - Indicates if the miniport driver wants the port driver to call */ /* its VIDEO_HW_FIND_ADAPTER function again with a new device */ /* extension and the same config info. This is used by the miniport */ /* drivers which can search for several adapters on a bus. */ /* */ /* Return Value: */ /* */ /* This routine must return: */ /* */ /* NO_ERROR - Indicates a host adapter was found and the */ /* configuration information was successfully determined. */ /* */ /* ERROR_INVALID_PARAMETER - Indicates an adapter was found but there */ /* was an error obtaining the configuration information. If */ /* possible an error should be logged. */ /* */ /* ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the */ /* supplied configuration information. */ /* */ /****************************************************************************/ VP_STATUS MPFindAdapter( PVOID HwDeviceExtension, PVOID HwContext, PWSTR ArgumentString, PVIDEO_PORT_CONFIG_INFO ConfigInfo, PUCHAR Again) {
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; NTSTATUS Status; HANDLE SectionHandle; ACCESS_MASK SectionAccess; ULONGLONG SectionSize = 0x100000;
/************************************************************************/ /* Make sure the size of the structure is at least as large as what we */ /* are expecting (check version of the config info structure). */ /************************************************************************/ if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) { return ERROR_INVALID_PARAMETER; }
/************************************************************************/ /* Only create a device once. */ /************************************************************************/ if (mpLoaded++) { return ERROR_DEV_NOT_EXIST; }
/************************************************************************/ /* Clear out the Emulator entries and the state size since this driver */ /* does not support them. */ /************************************************************************/ ConfigInfo->NumEmulatorAccessEntries = 0; ConfigInfo->EmulatorAccessEntries = NULL; ConfigInfo->EmulatorAccessEntriesContext = 0; ConfigInfo->HardwareStateSize = 0;
ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000; ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000; ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;
/************************************************************************/ /* Initialize the current mode number. */ /************************************************************************/ hwDeviceExtension->CurrentModeNumber = 0;
/************************************************************************/ /* Indicate we do not wish to be called over */ /************************************************************************/ *Again = 0;
/************************************************************************/ /* Indicate a successful completion status. */ /************************************************************************/ return NO_ERROR;
} /* MPFindAdapter() */
/****************************************************************************/ /* MPInitialize */ /* */ /* Routine Description: */ /* */ /* This routine does one time initialization of the device. */ /* */ /* Arguments: */ /* */ /* HwDeviceExtension - Supplies a pointer to the miniport's device */ /* extension. */ /* */ /* Return Value: */ /* */ /* Always returns TRUE since this routine can never fail. */ /* */ /****************************************************************************/ BOOLEAN MPInitialize( PVOID HwDeviceExtension ) { ULONG i;
/************************************************************************/ /* Walk through the list of modes and mark the indexes properly */ /************************************************************************/ for (i = 0; i < mpNumModes; i++) { mpModes[i].ModeIndex = i; }
return TRUE;
} /* MPInitialize() */
/****************************************************************************/ /* */ /* MPStartIO */ /* */ /* Routine Description: */ /* */ /* This routine is the main execution routine for the miniport driver. */ /* It accepts a Video Request Packet, performs the request, and then */ /* returns with the appropriate status. */ /* */ /* Arguments: */ /* */ /* HwDeviceExtension - Supplies a pointer to the miniport's device */ /* extension. */ /* */ /* RequestPacket - Pointer to the video request packet. This */ /* structure contains all the parameters passed to the */ /* VideoIoControl function. */ /* */ /* Return Value: */ /* */ /* */ /****************************************************************************/
BOOLEAN MPStartIO( PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket ) { PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; VP_STATUS status = NO_ERROR; PVIDEO_MODE_INFORMATION modeInformation; PVIDEO_MEMORY_INFORMATION memoryInformation; PVIDEO_SHARE_MEMORY pShareMemory; PVIDEO_SHARE_MEMORY_INFORMATION pShareMemoryInformation; ULONG ulTemp; NTSTATUS ntStatus; ULONG ViewSize; PVOID ViewBase; LARGE_INTEGER ViewOffset; HANDLE sectionHandle;
// DC_BEGIN_FN("MPStartIO");
if ((RequestPacket == NULL) || (HwDeviceExtension == NULL)) return FALSE;
/************************************************************************/ /* Switch on the IoContolCode in the RequestPacket. It indicates which */ /* function must be performed by the driver. */ /************************************************************************/
switch (RequestPacket->IoControlCode) {
case IOCTL_VIDEO_QUERY_CURRENT_MODE: { /****************************************************************/ /* return the current mode */ /****************************************************************/ // TRC_DBG((TB, "MPStartIO - QueryCurrentModes"));
modeInformation = RequestPacket->OutputBuffer;
RequestPacket->StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION); if (RequestPacket->OutputBufferLength < RequestPacket->StatusBlock->Information) { status = ERROR_INSUFFICIENT_BUFFER; } else { *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) = mpModes[hwDeviceExtension->CurrentModeNumber]; status = NO_ERROR; }
} break;
case IOCTL_VIDEO_QUERY_AVAIL_MODES: { /****************************************************************/ /* return the mode information */ /****************************************************************/ UCHAR i;
// TRC_DBG((TB, "MPStartIO - QueryAvailableModes"));
/****************************************************************/ /* check for space */ /****************************************************************/ RequestPacket->StatusBlock->Information = mpNumModes * sizeof(VIDEO_MODE_INFORMATION); if (RequestPacket->OutputBufferLength < RequestPacket->StatusBlock->Information) { status = ERROR_INSUFFICIENT_BUFFER; } else { modeInformation = RequestPacket->OutputBuffer;
for (i = 0; i < mpNumModes; i++) { *modeInformation = mpModes[i]; modeInformation++; }
status = NO_ERROR; } } break;
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: { /****************************************************************/ /* return the number of modes we support - which we claim to be */ /* zero */ /****************************************************************/ // TRC_DBG((TB, "MPStartIO - QueryNumAvailableModes"));
if (RequestPacket->OutputBufferLength < (RequestPacket->StatusBlock->Information = sizeof(VIDEO_NUM_MODES)) ) { status = ERROR_INSUFFICIENT_BUFFER; } else { ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes = 0; ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer) ->ModeInformationLength = 0; status = NO_ERROR; }
} break;
case IOCTL_VIDEO_SET_CURRENT_MODE: { /****************************************************************/ /* sets the current mode */ /****************************************************************/ // TRC_DBG((TB, "MPStartIO - SetCurrentMode"));
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE)) { status = ERROR_INSUFFICIENT_BUFFER; }
hwDeviceExtension->CurrentModeNumber = ((PVIDEO_MODE) (RequestPacket->InputBuffer))->RequestedMode;
status = NO_ERROR;
} break;
case IOCTL_VIDEO_SET_COLOR_REGISTERS: { // TRC_DBG((TB, "MPStartIO - SetColorRegs"));
status = NO_ERROR; } break;
case IOCTL_VIDEO_RESET_DEVICE: { // TRC_DBG((TB, "MPStartIO - RESET_DEVICE"));
status = NO_ERROR; } break;
case IOCTL_VIDEO_MAP_VIDEO_MEMORY: case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: case IOCTL_VIDEO_SHARE_VIDEO_MEMORY: case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY: { /****************************************************************/ /* might get these, but shouldn't */ /****************************************************************/ // TRC_ALT((TB, "Unexpected IOCtl %x",RequestPacket->IoControlCode));
status = ERROR_INVALID_FUNCTION; } break;
default: { /****************************************************************/ /* definitely shouldn't get here */ /****************************************************************/ // TRC_DBG((TB, "Fell through MP startIO routine - invalid command"));
status = ERROR_INVALID_FUNCTION; } break; }
RequestPacket->StatusBlock->Status = status;
// DC_END_FN();
return TRUE;
} /* MPStartIO() */
|