/* Called for IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY. * Unmaps framebuffer previously mapped with IOCTL_VIDEO_SHARE_VIDEO_MEMORY. */ BOOLEAN VBoxMPUnshareVideoMemory(PVBOXMP_DEVEXT pExt, PVIDEO_SHARE_MEMORY pMem, PSTATUS_BLOCK pStatus) { LOGF_ENTER(); pStatus->Status = VideoPortUnmapMemory(pExt, pMem->RequestedVirtualAddress, pMem->ProcessHandle); LOGF_LEAVE(); return TRUE; }
/* Called for IOCTL_VIDEO_UNMAP_VIDEO_MEMORY. * Unmaps previously mapped FrameBuffer and video RAM from caller's virtual adress space. */ BOOLEAN VBoxMPUnmapVideoMemory(PVBOXMP_DEVEXT pExt, PVIDEO_MEMORY VideoMemory, PSTATUS_BLOCK pStatus) { LOGF_ENTER(); HGSMIAreaClear(&pExt->areaDisplay); pStatus->Status = VideoPortUnmapMemory(pExt, VideoMemory->RequestedVirtualAddress, NULL); LOGF_LEAVE(); return TRUE; }
BOOLEAN FASTCALL XboxVmpUnmapVideoMemory( PXBOXVMP_DEVICE_EXTENSION DeviceExtension, PVIDEO_MEMORY VideoMemory, PSTATUS_BLOCK StatusBlock) { VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress, NULL); return TRUE; }
BOOLEAN VGAUnmapVideoMemory(IN PVOID DeviceExtension, IN PVIDEO_MEMORY MemoryToUnmap, OUT PSTATUS_BLOCK StatusBlock) { if (VideoPortUnmapMemory(DeviceExtension, MemoryToUnmap->RequestedVirtualAddress, 0) == NO_ERROR) return TRUE; else return FALSE; }
void VBoxMPCmnUnmapAdapterMemory(PVBOXMP_COMMON pCommon, void **ppv) { LOGF_ENTER(); PVBOXMP_DEVEXT pPEXT = VBoxCommonToPrimaryExt(pCommon); if (*ppv) { #ifndef VBOX_WITH_WDDM VP_STATUS Status; Status = VideoPortUnmapMemory(pPEXT, *ppv, NULL); VBOXMP_WARN_VPS(Status); #else NTSTATUS ntStatus; ntStatus = pPEXT->u.primary.DxgkInterface.DxgkCbUnmapMemory(pPEXT->u.primary.DxgkInterface.DeviceHandle, *ppv); Assert(ntStatus == STATUS_SUCCESS); #endif } *ppv = NULL; LOGF_LEAVE(); }
BOOLEAN DGXStartIO( PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket ) /*++ Routine Description: This routine is the main execution routine for the miniport driver. It acceptss 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: --*/ { PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; VP_STATUS status; PVIDEO_MODE_INFORMATION modeInformation; PVIDEO_MEMORY_INFORMATION memoryInformation; ULONG inIoSpace, ulTemp; PVIDEO_CLUT clutBuffer; ULONG modeNumber; PVIDEO_SHARE_MEMORY pShareMemory; PVIDEO_SHARE_MEMORY_INFORMATION pShareMemoryInformation; PHYSICAL_ADDRESS shareAddress; PVOID virtualAddress; ULONG sharedViewSize; // // Switch on the IoContolCode in the RequestPacket. It indicates which // function must be performed by the driver. // switch (RequestPacket->IoControlCode) { case IOCTL_VIDEO_SHARE_VIDEO_MEMORY: VideoDebugPrint((2, "DGXStartIO - ShareVideoMemory\n")); if ( (RequestPacket->OutputBufferLength < sizeof(VIDEO_SHARE_MEMORY_INFORMATION)) || (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } pShareMemory = RequestPacket->InputBuffer; if ( (pShareMemory->ViewOffset > hwDeviceExtension->FrameLength) || ((pShareMemory->ViewOffset + pShareMemory->ViewSize) > hwDeviceExtension->FrameLength) ) { status = ERROR_INVALID_PARAMETER; break; } RequestPacket->StatusBlock->Information = sizeof(VIDEO_SHARE_MEMORY_INFORMATION); // // Beware: the input buffer and the output buffer are the same // buffer, and therefore data should not be copied from one to the // other // virtualAddress = pShareMemory->ProcessHandle; sharedViewSize = pShareMemory->ViewSize; inIoSpace = 0; // // NOTE: we are ignoring ViewOffset // shareAddress.QuadPart = hwDeviceExtension->PhysicalFrameAddress.QuadPart; status = VideoPortMapMemory(hwDeviceExtension, shareAddress, &sharedViewSize, &inIoSpace, &virtualAddress); pShareMemoryInformation = RequestPacket->OutputBuffer; pShareMemoryInformation->SharedViewOffset = pShareMemory->ViewOffset; pShareMemoryInformation->VirtualAddress = virtualAddress; pShareMemoryInformation->SharedViewSize = sharedViewSize; break; case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY: VideoDebugPrint((2, "DGXStartIO - UnshareVideoMemory\n")); if (RequestPacket->InputBufferLength < sizeof(VIDEO_SHARE_MEMORY)) { status = ERROR_INSUFFICIENT_BUFFER; break; } pShareMemory = RequestPacket->InputBuffer; status = VideoPortUnmapMemory(hwDeviceExtension, pShareMemory->RequestedVirtualAddress, pShareMemory->ProcessHandle); break; case IOCTL_VIDEO_MAP_VIDEO_MEMORY: VideoDebugPrint((2, "DGXStartIO - MapVideoMemory\n")); if ( (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION)) || (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } RequestPacket->StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION); memoryInformation = RequestPacket->OutputBuffer; memoryInformation->VideoRamBase = ((PVIDEO_MEMORY) (RequestPacket->InputBuffer))->RequestedVirtualAddress; memoryInformation->VideoRamLength = hwDeviceExtension->FrameLength; inIoSpace = 0; status = VideoPortMapMemory(hwDeviceExtension, hwDeviceExtension->PhysicalFrameAddress, &(memoryInformation->VideoRamLength), &inIoSpace, &(memoryInformation->VideoRamBase)); // // The frame buffer and virtual memory and equivalent in this // case. // memoryInformation->FrameBufferBase = memoryInformation->VideoRamBase; memoryInformation->FrameBufferLength = memoryInformation->VideoRamLength; break; case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: VideoDebugPrint((2, "DGXStartIO - UnMapVideoMemory\n")); if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) { status = ERROR_INSUFFICIENT_BUFFER; } else { status = VideoPortUnmapMemory(hwDeviceExtension, ((PVIDEO_MEMORY) (RequestPacket->InputBuffer))-> RequestedVirtualAddress, 0); } break; case IOCTL_VIDEO_QUERY_CURRENT_MODE: VideoDebugPrint((2, "DGXStartIO - QueryCurrentModes\n")); modeInformation = RequestPacket->OutputBuffer; if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION)) { status = ERROR_INSUFFICIENT_BUFFER; } else { RequestPacket->StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION); *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) = DGXModes[hwDeviceExtension->CurrentModeNumber].modeInformation; status = NO_ERROR; } break; case IOCTL_VIDEO_QUERY_AVAIL_MODES: { UCHAR i; VideoDebugPrint((2, "DGXStartIO - QueryAvailableModes\n")); if (RequestPacket->OutputBufferLength < hwDeviceExtension->NumValidModes * sizeof(VIDEO_MODE_INFORMATION)) { status = ERROR_INSUFFICIENT_BUFFER; } else { RequestPacket->StatusBlock->Information = hwDeviceExtension->NumValidModes * sizeof(VIDEO_MODE_INFORMATION); modeInformation = RequestPacket->OutputBuffer; for (i = 0; i < NumDGXModes; i++) { if (DGXModes[i].bValid) { *modeInformation = DGXModes[i].modeInformation; modeInformation++; } } status = NO_ERROR; } break; } case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: VideoDebugPrint((2, "DGXStartIO - QueryNumAvailableModes\n")); // // Find out the size of the data to be put in the the buffer and // return that in the status information (whether or not the // information is there). If the buffer passed in is not large // enough return an appropriate error code. // // WARNING: This must be changed to take into account which monitor // is present on the machine. // if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES)) { status = ERROR_INSUFFICIENT_BUFFER; } else { RequestPacket->StatusBlock->Information = sizeof(VIDEO_NUM_MODES); ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes = hwDeviceExtension->NumValidModes; ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION); status = NO_ERROR; } break; case IOCTL_VIDEO_SET_CURRENT_MODE: VideoDebugPrint((2, "DGXStartIO - SetCurrentMode\n")); // // verify data // WARNING: Make sure it is one of the valid modes on the list // calculated using the monitor information. // modeNumber = ((PVIDEO_MODE)(RequestPacket->InputBuffer))->RequestedMode; if ( (modeNumber >= hwDeviceExtension->NumValidModes) || (!DGXModes[modeNumber].bValid) ) { status = ERROR_INVALID_PARAMETER; break; } DevInitDGX(hwDeviceExtension, (PULONG)DGXModes[modeNumber].pVData, DGXModes[modeNumber].Count); if (DGXModes[modeNumber].modeInformation.BitsPerPlane == 16) { DevSet16BppPalette(hwDeviceExtension); } hwDeviceExtension->CurrentModeNumber = modeNumber; status = NO_ERROR; break; case IOCTL_VIDEO_SET_COLOR_REGISTERS: VideoDebugPrint((2, "DGXStartIO - SetColorRegs\n")); clutBuffer = RequestPacket->InputBuffer; // // Check if the size of the data in the input buffer is large enough. // if ( (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) - sizeof(ULONG)) || (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) + (sizeof(ULONG) * (clutBuffer->NumEntries - 1)) ) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } if (DGXModes[hwDeviceExtension->CurrentModeNumber]. modeInformation.BitsPerPlane == 8) { DevSetPalette(hwDeviceExtension, (PULONG)clutBuffer->LookupTable, clutBuffer->FirstEntry, clutBuffer->NumEntries); status = NO_ERROR; } break; case IOCTL_VIDEO_ENABLE_POINTER: VideoDebugPrint((2, "DGXStartIO - EnablePointer\n")); ulTemp = *hwDeviceExtension->pControlRegA; ulTemp &= ~DAC_DISABLEPOINTER; DacDelay(); *hwDeviceExtension->pControlRegA = ulTemp; status = NO_ERROR; break; case IOCTL_VIDEO_DISABLE_POINTER: VideoDebugPrint((2, "DGXStartIO - DisablePointer\n")); DevPointerOff(hwDeviceExtension); status = NO_ERROR; break; case IOCTL_VIDEO_SET_POINTER_POSITION: { PVIDEO_POINTER_POSITION pointerPosition; VideoDebugPrint((2, "DGXStartIO - SetpointerPostion\n")); pointerPosition = RequestPacket->InputBuffer; // // Check if the size of the data in the input buffer is large enough. // if (RequestPacket->InputBufferLength < sizeof(VIDEO_POINTER_POSITION)) { status = ERROR_INSUFFICIENT_BUFFER; } else { hwDeviceExtension->ulPointerX = (ULONG)pointerPosition->Row; hwDeviceExtension->ulPointerY = (ULONG)pointerPosition->Column; DevSetPointerPos(hwDeviceExtension, (ULONG)pointerPosition->Column, (ULONG)pointerPosition->Row); status = NO_ERROR; } break; } case IOCTL_VIDEO_QUERY_POINTER_POSITION: { PVIDEO_POINTER_POSITION pPointerPosition = RequestPacket->OutputBuffer; VideoDebugPrint((2, "DGXStartIO - QuerypointerPostion\n")); // // Make sure the output buffer is big enough. // if (RequestPacket->OutputBufferLength < sizeof(VIDEO_POINTER_POSITION)) { RequestPacket->StatusBlock->Information = 0; return ERROR_INSUFFICIENT_BUFFER; } // // Return the pointer position // RequestPacket->StatusBlock->Information = sizeof(VIDEO_POINTER_POSITION); pPointerPosition->Row = (SHORT)hwDeviceExtension->ulPointerX; pPointerPosition->Column = (SHORT)hwDeviceExtension->ulPointerY; status = NO_ERROR; break; } case IOCTL_VIDEO_SET_POINTER_ATTR: { PVIDEO_POINTER_ATTRIBUTES pointerAttributes; USHORT *pHWCursorShape; // Temp Buffer USHORT *pHWCursorAddr; // DAC buffer ULONG iCount = 512; VideoDebugPrint((2, "DGXStartIO - SetPointerAttributes\n")); pointerAttributes = RequestPacket->InputBuffer; // // Check if the size of the data in the input buffer is large enough. // if (RequestPacket->InputBufferLength < (sizeof(VIDEO_POINTER_ATTRIBUTES) + ((sizeof(UCHAR) * (CURSOR_WIDTH/8) * CURSOR_HEIGHT) * 2))) { status = ERROR_INSUFFICIENT_BUFFER; break; } // // If the specified cursor width or height is not valid, then // return an invalid parameter error. // if ((pointerAttributes->Width > CURSOR_WIDTH) || (pointerAttributes->Height > CURSOR_HEIGHT)) { status = ERROR_INVALID_PARAMETER; break; } // // Try to copy the pointer to our buffer. When we copy it // we convert it to our 2bpp format. If sucessfull, then // copy it to the DAC and set the position. // if (!(pointerAttributes->Flags & VIDEO_MODE_ANIMATE_UPDATE)) { DevPointerOff(hwDeviceExtension); } if (pointerAttributes->Flags & VIDEO_MODE_MONO_POINTER) { if (CopyMonoCursor(hwDeviceExtension, (PUCHAR)&pointerAttributes->Pixels[0])) { pHWCursorAddr = (USHORT *)hwDeviceExtension->pHardWareCursorAddr; pHWCursorShape = (USHORT *)&hwDeviceExtension->HardwareCursorShape[0]; while (iCount--) { *pHWCursorAddr++ = *pHWCursorShape++; pHWCursorAddr++; DacDelay(); } DevSetPointerPos(hwDeviceExtension, (ULONG)pointerAttributes->Column, (ULONG)pointerAttributes->Row); status = NO_ERROR; break; } } // // Something failed. Remove the current HW Cursor. // DevPointerOff(hwDeviceExtension); status = ERROR_INVALID_PARAMETER; break; } case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES: { PVIDEO_POINTER_CAPABILITIES pointerCaps = RequestPacket->OutputBuffer; VideoDebugPrint((2, "DGXStartIO - QueryPointerCapabilities\n")); if (RequestPacket->OutputBufferLength < sizeof(VIDEO_POINTER_CAPABILITIES)) { RequestPacket->StatusBlock->Information = 0; status = ERROR_INSUFFICIENT_BUFFER; } pointerCaps->Flags = VIDEO_MODE_ASYNC_POINTER | VIDEO_MODE_MONO_POINTER; pointerCaps->MaxWidth = CURSOR_WIDTH; pointerCaps->MaxHeight = CURSOR_HEIGHT; pointerCaps->HWPtrBitmapStart = 0; // No VRAM storage for pointer pointerCaps->HWPtrBitmapEnd = 0; // // Number of bytes we're returning. // RequestPacket->StatusBlock->Information = sizeof(VIDEO_POINTER_CAPABILITIES); status = NO_ERROR; break; } case IOCTL_VIDEO_RESET_DEVICE: VideoDebugPrint((2, "DGXStartIO - RESET_DEVICE\n")); DevDisableDGX(hwDeviceExtension); status = NO_ERROR; break; // // if we get here, an invalid IoControlCode was specified. // default: VideoDebugPrint((1, "Fell through DGX startIO routine - invalid command\n")); status = ERROR_INVALID_FUNCTION; break; } RequestPacket->StatusBlock->Status = status; return TRUE; } // end DGXStartIO() z
/* Main I/O request handler routine. */ BOOLEAN HwVidStartIO( PVOID HwDevExt, PVIDEO_REQUEST_PACKET ReqPkt ) { PHW_DEV_EXT pExt = HwDevExt; VP_STATUS status = NO_ERROR; PVIDEO_MODE_INFORMATION modeInfo; PVIDEO_MEMORY vidMem; PVIDEO_SHARE_MEMORY pShrMem; PVOID virtualAddress; ULONG inIoSpace; ULONG modeNumber; ULONG ulLen; ULONG i; VideoDebugPrint( (2, "videomp: HwVidStartIO: ") ); /* Process the VRP. Required requests are handled first. */ switch( ReqPkt->IoControlCode ) { case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: { PVIDEO_NUM_MODES numModes; VideoDebugPrint( (2, "QUERY_NUM_AVAIL_MODES\n") ); if( ReqPkt->OutputBufferLength < sizeof( VIDEO_NUM_MODES ) ) { status = ERROR_INSUFFICIENT_BUFFER; } else { ReqPkt->StatusBlock->Information = sizeof( VIDEO_NUM_MODES ); numModes = (PVIDEO_NUM_MODES)ReqPkt->OutputBuffer; numModes->ModeInformationLength = sizeof( VIDEO_MODE_INFORMATION ); numModes->NumModes = pExt->NumValidModes; } break; } case IOCTL_VIDEO_QUERY_AVAIL_MODES: VideoDebugPrint( (2, "QUERY_AVAIL_MODES\n") ); ulLen = pExt->NumValidModes * sizeof( VIDEO_MODE_INFORMATION ); if( ReqPkt->OutputBufferLength < ulLen ) { status = ERROR_INSUFFICIENT_BUFFER; } else { ReqPkt->StatusBlock->Information = ulLen; modeInfo = ReqPkt->OutputBuffer; for( i = 0; i < ulAllModes; ++i ) { if( VideoModes[i].bValid ) { vmpFillModeInfo( modeInfo, VideoModes[i].HorzRes, VideoModes[i].VertRes, VideoModes[i].Bpp ); modeInfo->ModeIndex = i; //VideoModes[i].modeInformation.ModeIndex; modeInfo++; } } } break; case IOCTL_VIDEO_QUERY_CURRENT_MODE: VideoDebugPrint( (2, "QUERY_CURRENT_MODE\n") ); if( ReqPkt->OutputBufferLength < sizeof( VIDEO_MODE_INFORMATION ) ) { status = ERROR_INSUFFICIENT_BUFFER; } else { ReqPkt->StatusBlock->Information = sizeof( VIDEO_MODE_INFORMATION ); modeInfo = ReqPkt->OutputBuffer; vmpFillModeInfo( modeInfo, VideoModes[pExt->CurrentModeNumber].HorzRes, VideoModes[pExt->CurrentModeNumber].VertRes, VideoModes[pExt->CurrentModeNumber].Bpp ); modeInfo->ModeIndex = pExt->CurrentModeNumber; //VideoModes[pExt->CurrentModeNumber].modeInformation.ModeIndex; } break; case IOCTL_VIDEO_SET_CURRENT_MODE: VideoDebugPrint( (2, "SET_CURRENT_MODE\n") ); /* Ensure the mode is valid. */ modeNumber = ((PVIDEO_MODE)(ReqPkt->InputBuffer))->RequestedMode; if( (modeNumber > ulAllModes) || (!VideoModes[modeNumber].bValid) ) { status = ERROR_INVALID_PARAMETER; break; } BOXV_ext_mode_set( pExt, VideoModes[modeNumber].HorzRes, VideoModes[modeNumber].VertRes, VideoModes[modeNumber].Bpp, VideoModes[modeNumber].HorzRes, VideoModes[modeNumber].VertRes ); pExt->CurrentModeNumber = modeNumber; break; case IOCTL_VIDEO_RESET_DEVICE: VideoDebugPrint( (2, "RESET_DEVICE\n") ); /* Not calling the following routine avoids some visual glitches. */ /* BOXV_ext_disable( pExt ); */ break; case IOCTL_VIDEO_MAP_VIDEO_MEMORY: { PVIDEO_MEMORY_INFORMATION memInfo; VideoDebugPrint( (2, "MAP_VIDEO_MEMORY\n") ); if( (ReqPkt->OutputBufferLength < sizeof( VIDEO_MEMORY_INFORMATION )) || (ReqPkt->InputBufferLength < sizeof( VIDEO_MEMORY )) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } ReqPkt->StatusBlock->Information = sizeof( VIDEO_MEMORY_INFORMATION ); vidMem = (PVIDEO_MEMORY)ReqPkt->InputBuffer; memInfo = ReqPkt->OutputBuffer; inIoSpace = FALSE; memInfo->VideoRamBase = vidMem->RequestedVirtualAddress; memInfo->VideoRamLength = pExt->FramebufLen; status = VideoPortMapMemory( pExt, pExt->PhysicalFrameAddress, &memInfo->VideoRamLength, &inIoSpace, &memInfo->VideoRamBase ); /* The framebuffer covers the entire video memory. */ memInfo->FrameBufferBase = memInfo->VideoRamBase; memInfo->FrameBufferLength = memInfo->VideoRamLength; break; } case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: VideoDebugPrint( (2, "UNMAP_VIDEO_MEMORY\n") ); if( ReqPkt->InputBufferLength < sizeof( VIDEO_MEMORY ) ) { status = ERROR_INSUFFICIENT_BUFFER; } else { vidMem = (PVIDEO_MEMORY)ReqPkt->InputBuffer; status = VideoPortUnmapMemory( pExt, vidMem->RequestedVirtualAddress, 0 ); } break; /* The following request is required for palettized modes. */ case IOCTL_VIDEO_SET_COLOR_REGISTERS: { PVIDEO_CLUT clutBuffer; VideoDebugPrint( (2, "SET_COLOR_REGISTERS\n") ); clutBuffer = ReqPkt->InputBuffer; if( (ReqPkt->InputBufferLength < sizeof( VIDEO_CLUT ) - sizeof( ULONG )) || (ReqPkt->InputBufferLength < sizeof( VIDEO_CLUT ) + (sizeof( ULONG ) * (clutBuffer->NumEntries - 1)) ) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } if( VideoModes[pExt->CurrentModeNumber].Bpp == 8 ) { BOXV_dac_set( pExt, clutBuffer->FirstEntry, clutBuffer->NumEntries, clutBuffer->LookupTable ); } break; } /* The following requests are optional. */ case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES: { PVIDEO_POINTER_CAPABILITIES ptrCaps = ReqPkt->OutputBuffer; VideoDebugPrint( (2, "QUERY_POINTER_CAPABILITIES\n") ); if( ReqPkt->OutputBufferLength < sizeof( VIDEO_POINTER_CAPABILITIES ) ) { ReqPkt->StatusBlock->Information = 0; status = ERROR_INSUFFICIENT_BUFFER; } ptrCaps->Flags = 0; /* Indicate no pointer support. */ ptrCaps->MaxWidth = ptrCaps->MaxHeight = 0; /* Documentation and sample code disagree on whether no display * memory for cursor is indicated by 0 or -1. */ ptrCaps->HWPtrBitmapStart = ptrCaps->HWPtrBitmapEnd = ~0; ReqPkt->StatusBlock->Information = sizeof( VIDEO_POINTER_CAPABILITIES ); break; } /* The share/unshare IOCTLs are new for NT 3.51. */ case IOCTL_VIDEO_SHARE_VIDEO_MEMORY: { PVIDEO_SHARE_MEMORY_INFORMATION pShrMemInfo; PHYSICAL_ADDRESS shareAddress; ULONG sharedViewSize; VideoDebugPrint( (2, "SHARE_VIDEO_MEMORY\n") ); if( (ReqPkt->OutputBufferLength < sizeof( VIDEO_SHARE_MEMORY_INFORMATION )) || (ReqPkt->InputBufferLength < sizeof( VIDEO_MEMORY )) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } pShrMem = ReqPkt->InputBuffer; if( (pShrMem->ViewOffset > pExt->FramebufLen) || ((pShrMem->ViewOffset + pShrMem->ViewSize) > pExt->FramebufLen) ) { status = ERROR_INVALID_PARAMETER; break; } ReqPkt->StatusBlock->Information = sizeof( VIDEO_SHARE_MEMORY_INFORMATION ); /* The input buffer is also the output buffer; remember the input. */ virtualAddress = pShrMem->ProcessHandle; sharedViewSize = pShrMem->ViewSize; inIoSpace = FALSE; /* NB: ViewOffset is not being taken into account. */ shareAddress.QuadPart = pExt->PhysicalFrameAddress.QuadPart; status = VideoPortMapMemory( pExt, shareAddress, &sharedViewSize, &inIoSpace, &virtualAddress ); pShrMemInfo = ReqPkt->OutputBuffer; pShrMemInfo->SharedViewOffset = pShrMem->ViewOffset; pShrMemInfo->VirtualAddress = virtualAddress; pShrMemInfo->SharedViewSize = sharedViewSize; break; } case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY: VideoDebugPrint( (2, "UNSHARE_VIDEO_MEMORY\n") ); if( ReqPkt->InputBufferLength < sizeof( VIDEO_SHARE_MEMORY ) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } pShrMem = ReqPkt->InputBuffer; status = VideoPortUnmapMemory( pExt, pShrMem->RequestedVirtualAddress, pShrMem->ProcessHandle ); break; /* The child state IOCTLs are new for NT 5.0 (Windows 2000). */ case IOCTL_VIDEO_GET_CHILD_STATE: { PULONG pChildIndex; PULONG pChildState; VideoDebugPrint( (2, "GET_CHILD_STATE\n") ); if( ReqPkt->InputBufferLength < sizeof( ULONG ) || ReqPkt->OutputBufferLength < sizeof( ULONG ) ) { status = ERROR_INSUFFICIENT_BUFFER; break; } pChildIndex = ReqPkt->InputBuffer; pChildState = ReqPkt->OutputBuffer; /* Always say the child is active. */ *pChildState = VIDEO_CHILD_ACTIVE; break; } /* Any other request is invalid and fails. */ default: VideoDebugPrint( (1, "Unhandled IoControlCode %08x!\n", ReqPkt->IoControlCode) ); status = ERROR_INVALID_FUNCTION; break; } ReqPkt->StatusBlock->Status = status; return( TRUE ); }