windows-nt/Source/XPSP1/NT/multimedia/directx/dsound/dsvxd/dsvxd.cpp
2020-09-26 16:20:57 +08:00

1424 lines
32 KiB
C++

//--------------------------------------------------------------------------;
//
// File: dsvxd.c
//
// Copyright (c) 1995 Microsoft Corporation. All Rights Reserved.
//
// Abstract:
//
// Contents:
//
// History:
// 06/15/95 FrankYe
//
//--------------------------------------------------------------------------;
#define WANTVXDWRAPS
#define INITGUID
#include <windows.h>
extern "C" {
#include <vmm.h>
#include <vxdldr.h>
#include <vwin32.h>
#include <vxdwraps.h>
#include <configmg.h>
#include <verinfo.h>
}
#define NODSOUNDWRAPS
#include <mmsystem.h>
#include <dsound.h>
#include <dsdrvi.h>
#include "dsvxd.h"
#include "dsvxdi.h"
#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG
//--------------------------------------------------------------------------;
//
// Why is there no wrapper for VMM's _lstrcmpi??? I'll make my own...
//
//--------------------------------------------------------------------------;
int VXDINLINE VMM_lstrcmpi(char *pString1, char *pString2)
{
int iReturn;
Touch_Register(eax);
Touch_Register(ecx);
Touch_Register(edx);
_asm push pString1;
_asm push pString2;
VMMCall(_lstrcmpi);
_asm add esp, 2*4;
_asm mov iReturn, eax;
return iReturn;
}
LPVOID VXDINLINE VMM_GetCurrentContext()
{
LPVOID pCD;
Touch_Register(eax);
VMMCall(_GetCurrentContext);
_asm mov pCD, eax;
return pCD;
}
BOOL VXDINLINE VMM_PageAttach(ULONG pagesrc, LPVOID hcontextsrc, ULONG pagedst, ULONG cpages)
{
int iReturn;
Touch_Register(eax);
Touch_Register(ecx);
Touch_Register(edx);
_asm push cpages;
_asm push pagedst;
_asm push hcontextsrc;
_asm push pagesrc;
VMMCall(_PageAttach);
_asm add esp, 4*4;
_asm mov iReturn, eax;
return (0 != iReturn);
}
BOOL VXDINLINE VMM_PageFree(PVOID pPage, ULONG flags)
{
return _PageFree(pPage, flags);
}
void VXDINLINE VMM_EnterMustComplete()
{
Touch_Register(eax);
Touch_Register(ecx);
Touch_Register(edx);
VMMCall(_EnterMustComplete);
return;
}
void VXDINLINE VMM_LeaveMustComplete()
{
Touch_Register(eax);
Touch_Register(ecx);
Touch_Register(edx);
VMMCall(_LeaveMustComplete);
return;
}
BOOL VXDINLINE VWIN32_CloseVxDHandle(DWORD vxdh)
{
int iReturn;
Touch_Register(ecx);
Touch_Register(edx);
_asm mov eax, vxdh;
VxDCall(_VWIN32_CloseVxDHandle);
_asm mov iReturn, eax;
return (0 != iReturn);
}
/*
BOOL VXDINLINE VMM_PageLock(ULONG pagestrt, ULONG cpages, ULONG dwflags)
{
int iReturn;
Touch_Register(eax);
Touch_Register(ecx);
Touch_Register(edx);
_asm push dwflags;
_asm push cpages;
_asm push pagestrt;
VMMCall(_LinPageLock);
_asm add esp, 3*4;
_asm mov iReturn, eax;
return (0 != iReturn);
}
BOOL VXDINLINE VMM_PageUnlock(ULONG pagestrt, ULONG cpages, ULONG dwflags)
{
int iReturn;
Touch_Register(eax);
Touch_Register(ecx);
Touch_Register(edx);
_asm push dwflags;
_asm push cpages;
_asm push pagestrt;
VMMCall(_LinPageUnlock);
_asm add esp, 3*4;
_asm mov iReturn, eax;
return (0 != iReturn);
}
*/
//--------------------------------------------------------------------------;
//
// Filescope data
//
//--------------------------------------------------------------------------;
static LPVOID gpGarbagePage = NULL;
//--------------------------------------------------------------------------;
//
// VxD Device control functions
//
//--------------------------------------------------------------------------;
int ctrlDynamicDeviceInit(void)
{
DPF(("ctrlDynamicDeviceInit"));
return ctrlDrvInit();
}
int ctrlDynamicDeviceExit(void)
{
DPF(("ctrlDynamicDeviceExit"));
return ctrlDrvExit();
}
#pragma VxD_PAGEABLE_CODE_SEG
#pragma VxD_PAGEABLE_DATA_SEG
//--------------------------------------------------------------------------;
//
// IOCTL handlers
//
//--------------------------------------------------------------------------;
int ioctlDsvxdInitialize(PDIOCPARAMETERS pdiocp)
{
DSVAL dsv;
IOSTART(0*4);
//
// The only thing we need to do is allocate one page of fixed
// memory to which we will commit alias buffer pointers when
// we don't want them to point at the real buffer anymore.
//
gpGarbagePage = _PageAllocate(1, PG_VM, Get_Sys_VM_Handle(), 0, 0, 0, 0, PAGEFIXED);
if (NULL != gpGarbagePage) {
dsv = DS_OK;
} else {
dsv = DSERR_OUTOFMEMORY;
}
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
int ioctlDsvxdShutdown(PDIOCPARAMETERS pdiocp)
{
DSVAL dsv;
IOSTART(0*4);
if (NULL != gpGarbagePage) _PageFree(gpGarbagePage, 0);
dsv = DS_OK;
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
int ioctlDsvxd_PageFile_Get_Version(PDIOCPARAMETERS pdiocp)
{
PDWORD pVersion;
PDWORD pMaxSize;
PDWORD pPagerType;
IOSTART(3*4);
IOINPUT(pVersion, PDWORD);
IOINPUT(pMaxSize, PDWORD);
IOINPUT(pPagerType, PDWORD);
Dsvxd_PageFile_Get_Version(pVersion, pMaxSize, pPagerType);
IORETURN;
return 0;
}
int ioctlDsvxd_VMM_Test_Debug_Installed(PDIOCPARAMETERS pdiocp)
{
BOOL fInstalled;
IOSTART(0*4);
fInstalled = Dsvxd_VMM_Test_Debug_Installed();
IOOUTPUT(fInstalled, BOOL);
IORETURN;
return 0;
}
int ioctlDsvxd_VMCPD_Get_Version(PDIOCPARAMETERS pdiocp)
{
PLONG pMajorVersion;
PLONG pMinorVersion;
PLONG pLevel;
IOSTART(3*4);
IOINPUT(pMajorVersion, PLONG);
IOINPUT(pMinorVersion, PLONG);
IOINPUT(pLevel, PLONG);
Dsvxd_VMCPD_Get_Version(pMajorVersion, pMinorVersion, pLevel);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlDrvGetNextDescFromGuid(PDIOCPARAMETERS pdiocp)
{
LPCGUID pGuidLast;
LPGUID pGuid;
PDSDRIVERDESC pDrvDesc;
HRESULT hr;
IOSTART(3*4);
IOINPUT(pGuidLast, LPCGUID);
IOINPUT(pGuid, LPGUID);
IOINPUT(pDrvDesc, PDSDRIVERDESC);
hr = CDrv::GetNextDescFromGuid(pGuidLast, pGuid, pDrvDesc);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
int ioctlDrvGetDescFromGuid(PDIOCPARAMETERS pdiocp)
{
LPCGUID pGuid;
PDSDRIVERDESC pDrvDesc;
DSVAL dsv;
IOSTART(2*4);
IOINPUT(pGuid, LPCGUID);
IOINPUT(pDrvDesc, PDSDRIVERDESC);
dsv = CDrv::GetDescFromGuid(*pGuid, pDrvDesc);
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
int ioctlDrvOpenFromGuid(PDIOCPARAMETERS pdiocp)
{
LPCGUID pGuid;
IDsDriver **ppIDsDriver;
HRESULT hr;
IOSTART(2*4);
IOINPUT(pGuid, LPCGUID);
IOINPUT(ppIDsDriver, IDsDriver**);
hr = CDrv::OpenFromGuid(*pGuid, ppIDsDriver);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIUnknown_QueryInterface(PDIOCPARAMETERS pdiocp)
{
LPUNKNOWN pIUnknown;
LPIID riid;
PVOID *ppv;
HRESULT hr;
IOSTART(3*4);
IOINPUT(pIUnknown, LPUNKNOWN);
IOINPUT(riid, LPIID);
IOINPUT(ppv, PVOID*);
hr = pIUnknown->QueryInterface((REFIID)(*riid), ppv);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIUnknown_AddRef(PDIOCPARAMETERS pdiocp)
{
LPUNKNOWN pIUnknown;
ULONG result;
IOSTART(1*4);
IOINPUT(pIUnknown, LPUNKNOWN);
result = pIUnknown->AddRef();
IOOUTPUT(result, ULONG);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIUnknown_Release(PDIOCPARAMETERS pdiocp)
{
LPUNKNOWN pIUnknown;
ULONG result;
IOSTART(1*4);
IOINPUT(pIUnknown, LPUNKNOWN);
result = pIUnknown->Release();
IOOUTPUT(result, ULONG);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
//
// This should really be ioctlIUnknown_QueryInterface, if I would take the time
// to fix up the IOCTLs to DSVXD
//
int ioctlIDsDriver_QueryInterface(PDIOCPARAMETERS pdiocp)
{
IDsDriver *pIDsDriver;
const IID *piid;
PVOID *ppv;
HRESULT hr;
IOSTART(3*4);
IOINPUT(pIDsDriver, IDsDriver*);
IOINPUT(piid, const IID *);
IOINPUT(ppv, PVOID*);
hr = pIDsDriver->QueryInterface((REFIID)(*piid), ppv);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIDsDriver_Close(PDIOCPARAMETERS pdiocp)
{
IDsDriver *pIDsDriver;
HRESULT hr;
IOSTART(1*4);
IOINPUT(pIDsDriver, IDsDriver*);
hr = pIDsDriver->Close();
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIDsDriver_GetCaps(PDIOCPARAMETERS pdiocp)
{
IDsDriver *pIDsDriver;
PDSDRIVERCAPS pDrvCaps;
HRESULT hr;
IOSTART(2*4);
IOINPUT(pIDsDriver, IDsDriver*);
IOINPUT(pDrvCaps, PDSDRIVERCAPS);
hr = pIDsDriver->GetCaps(pDrvCaps);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIDsDriver_CreateSoundBuffer(PDIOCPARAMETERS pdiocp)
{
IDsDriver *pIDsDriver;
LPWAVEFORMATEX pwfx;
DWORD dwFlags;
DWORD dwCardAddress;
LPDWORD pdwcbBufferSize;
LPBYTE *ppBuffer;
PVOID *ppvObj;
HRESULT hr;
IOSTART(7*4);
IOINPUT(pIDsDriver, IDsDriver*);
IOINPUT(pwfx, LPWAVEFORMATEX);
IOINPUT(dwFlags, DWORD);
IOINPUT(dwCardAddress, DWORD);
IOINPUT(pdwcbBufferSize, LPDWORD);
IOINPUT(ppBuffer, LPBYTE*);
IOINPUT(ppvObj, PVOID*);
hr = pIDsDriver->CreateSoundBuffer(pwfx, dwFlags, dwCardAddress,
pdwcbBufferSize, ppBuffer, ppvObj);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIDsDriver_DuplicateSoundBuffer(PDIOCPARAMETERS pdiocp)
{
IDsDriver *pIDsDriver;
IDsDriverBuffer *pIDsDriverBuffer;
PVOID *ppv;
HRESULT hr;
IOSTART(3*4);
IOINPUT(pIDsDriver, IDsDriver*);
IOINPUT(pIDsDriverBuffer, IDsDriverBuffer*);
IOINPUT(ppv, PVOID*);
hr = pIDsDriver->DuplicateSoundBuffer(pIDsDriverBuffer, ppv);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlBufferRelease(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
DSVAL dsv;
IOSTART(1*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
dsv = pBuf->Release();
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlBufferLock(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
LPVOID * ppvAudio1;
LPDWORD pdwLen1;
LPVOID * ppvAudio2;
LPDWORD pdwLen2;
DWORD dwWritePosition;
DWORD dwWriteBytes;
DWORD dwFlags;
DSVAL dsv;
IOSTART(8*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
IOINPUT(ppvAudio1, LPVOID *);
IOINPUT(pdwLen1, LPDWORD);
IOINPUT(ppvAudio2, LPVOID *);
IOINPUT(pdwLen2, LPDWORD);
IOINPUT(dwWritePosition, DWORD);
IOINPUT(dwWriteBytes, DWORD);
IOINPUT(dwFlags, DWORD);
dsv = pBuf->Lock( ppvAudio1,
pdwLen1,
ppvAudio2,
pdwLen2,
dwWritePosition,
dwWriteBytes,
dwFlags );
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
int ioctlBufferUnlock(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
PVOID pvAudio1;
DWORD dwLen1;
PVOID pvAudio2;
DWORD dwLen2;
DSVAL dsv;
IOSTART(5*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
IOINPUT(pvAudio1, PVOID);
IOINPUT(dwLen1, DWORD);
IOINPUT(pvAudio2, PVOID);
IOINPUT(dwLen2, DWORD);
dsv = pBuf->Unlock( pvAudio1,
dwLen1,
pvAudio2,
dwLen2 );
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlBufferSetFormat(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
LPWAVEFORMATEX pwfxToSet;
DSVAL dsv;
IOSTART(2*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
IOINPUT(pwfxToSet, LPWAVEFORMATEX);
dsv = pBuf->SetFormat(pwfxToSet);
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlBufferSetFrequency(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
DWORD dwFrequency;
DSVAL dsv;
IOSTART(2*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
IOINPUT(dwFrequency, DWORD);
dsv = pBuf->SetFrequency(dwFrequency);
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlBufferSetVolumePan(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
PDSVOLUMEPAN pVolPan;
DSVAL dsv;
IOSTART(2*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
IOINPUT(pVolPan, PDSVOLUMEPAN);
dsv = pBuf->SetVolumePan(pVolPan);
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlBufferSetPosition(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
DWORD dwNewPosition;
DSVAL dsv;
IOSTART(2*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
IOINPUT(dwNewPosition, DWORD);
dsv = pBuf->SetPosition(dwNewPosition);
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
int ioctlBufferGetPosition(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
LPDWORD lpdwCurrentPlayCursor;
LPDWORD lpdwCurrentWriteCursor;
DSVAL dsv;
IOSTART(3*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
IOINPUT(lpdwCurrentPlayCursor, LPDWORD);
IOINPUT(lpdwCurrentWriteCursor, LPDWORD);
dsv = pBuf->GetPosition( lpdwCurrentPlayCursor,
lpdwCurrentWriteCursor );
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlBufferPlay(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
DWORD dwReserved1;
DWORD dwReserved2;
DWORD dwFlags;
DSVAL dsv;
IOSTART(4*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
IOINPUT(dwReserved1, DWORD);
IOINPUT(dwReserved2, DWORD);
IOINPUT(dwFlags, DWORD);
dsv = pBuf->Play(dwReserved1, dwReserved2, dwFlags);
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
int ioctlBufferStop(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERBUFFER pBuf;
DSVAL dsv;
IOSTART(1*4);
IOINPUT(pBuf, PIDSDRIVERBUFFER);
dsv = pBuf->Stop();
IOOUTPUT(dsv, DSVAL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIDirectSoundPropertySet_GetProperty(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERPROPERTYSET pIDsPropertySet;
PDSPROPERTY pProperty;
PVOID pParams;
ULONG cbParams;
PVOID pData;
ULONG cbData;
PULONG pcbReturnedData;
HRESULT hr;
IOSTART(7*4);
IOINPUT(pIDsPropertySet, PIDSDRIVERPROPERTYSET);
IOINPUT(pProperty, PDSPROPERTY);
IOINPUT(pParams, PVOID);
IOINPUT(cbParams, ULONG);
IOINPUT(pData, PVOID);
IOINPUT(cbData, ULONG);
IOINPUT(pcbReturnedData, PULONG);
hr = pIDsPropertySet->Get(pProperty, pParams, cbParams, pData, cbData, pcbReturnedData);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIDirectSoundPropertySet_SetProperty(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERPROPERTYSET pIDsPropertySet;
PDSPROPERTY pProperty;
PVOID pParams;
ULONG cbParams;
PVOID pData;
ULONG cbData;
HRESULT hr;
IOSTART(6*4);
IOINPUT(pIDsPropertySet, PIDSDRIVERPROPERTYSET);
IOINPUT(pProperty, PDSPROPERTY);
IOINPUT(pParams, PVOID);
IOINPUT(cbParams, ULONG);
IOINPUT(pData, PVOID);
IOINPUT(cbData, ULONG);
hr = pIDsPropertySet->Set(pProperty, pParams, cbParams, pData, cbData);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlIDirectSoundPropertySet_QuerySupport(PDIOCPARAMETERS pdiocp)
{
PIDSDRIVERPROPERTYSET pIDsPropertySet;
LPGUID rPropSetId;
ULONG ulPropertyId;
PULONG pulSupport;
HRESULT hr;
IOSTART(4*4);
IOINPUT(pIDsPropertySet, PIDSDRIVERPROPERTYSET);
IOINPUT(rPropSetId, LPGUID);
IOINPUT(ulPropertyId, ULONG);
IOINPUT(pulSupport, PULONG);
hr = pIDsPropertySet->QuerySupport((REFGUID)(*rPropSetId), ulPropertyId, pulSupport);
IOOUTPUT(hr, HRESULT);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlEventScheduleWin32Event(PDIOCPARAMETERS pdiocp)
{
DWORD vxdhEvent;
DWORD dwDelay;
BOOL fReturn;
IOSTART(2*4);
IOINPUT(vxdhEvent, DWORD);
IOINPUT(dwDelay, DWORD);
fReturn = eventScheduleWin32Event(vxdhEvent, dwDelay);
// REMIND should implement something to cancel outstanding timeouts
// and events when we shutdown.
IOOUTPUT(fReturn, BOOL);
IORETURN;
return 0;
}
int ioctlEventCloseVxDHandle(PDIOCPARAMETERS pdiocp)
{
DWORD vxdh;
BOOL fReturn;
IOSTART(1*4);
IOINPUT(vxdh, DWORD);
fReturn = VWIN32_CloseVxDHandle(vxdh);
IOOUTPUT(fReturn, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
// ioctlMemReserveAlias
//
// Given a ptr to a buffer and length, this function will reserve linear
// address space to be used as an alias ptr to the same buffer. The reserved
// linear space does not have the buffer memory committed to it. That is done
// by ioctlMemCommitAlias.
//
//--------------------------------------------------------------------------;
int ioctlMemReserveAlias(PDIOCPARAMETERS pdiocp)
{
LPBYTE pBuffer;
DWORD cbBuffer;
LPBYTE pAlias;
LPBYTE pBufferAligned;
DWORD cbBufferAligned;
int cPages;
LPBYTE pAliasAligned;
IOSTART(2*4);
IOINPUT(pBuffer, LPBYTE);
IOINPUT(cbBuffer, DWORD);
DPF(("ioctlMemReserveAlias pBuffer=%08Xh cbBuffer=%d", pBuffer, cbBuffer));
pBufferAligned = (LPBYTE)(((DWORD)pBuffer) & ~(P_SIZE-1));
cPages = (pBuffer+cbBuffer - pBufferAligned+ P_SIZE-1) / P_SIZE;
cbBufferAligned = cPages * P_SIZE;
DPF((" pBufferAligned=%08Xh cPages=%d cbBufferAligned=%d",
pBufferAligned, cPages, cbBufferAligned));
//
// Reserve linear address space
//
pAliasAligned = (LPBYTE)_PageReserve(PR_SHARED, cPages, PR_FIXED);
if (((LPBYTE)(-1) == pAliasAligned) || (NULL == pAliasAligned)) {
pAlias = NULL;
} else {
pAlias = pAliasAligned + (pBuffer - pBufferAligned);
}
DPF((" pAliasAligned=%08Xh pAlias=%08Xh", pAliasAligned, pAlias));
IOOUTPUT(pAlias, LPBYTE);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlMemCommitAlias(PDIOCPARAMETERS pdiocp)
{
LPBYTE pAlias;
LPBYTE pBuffer;
DWORD cbBuffer;
BOOL fSuccess;
LPBYTE pBufferAligned;
LPBYTE pAliasAligned;
ULONG nPageBuffer;
ULONG nPageAlias;
int cPages;
IOSTART(3*4);
IOINPUT(pAlias, LPBYTE);
IOINPUT(pBuffer, LPBYTE);
IOINPUT(cbBuffer, DWORD);
// DPF(("ioctlMemCommitAlias pBuffer=%08Xh cbBuffer=%d pAlias=%08Xh",
// pBuffer, cbBuffer, pAlias));
pBufferAligned = (LPBYTE)(((DWORD)pBuffer) & ~(P_SIZE-1));
pAliasAligned = (LPBYTE)(((DWORD)pAlias) & ~(P_SIZE-1));
cPages = (pBuffer+cbBuffer - pBufferAligned+ P_SIZE-1) / P_SIZE;
nPageBuffer = ((ULONG)pBufferAligned) / P_SIZE;
nPageAlias = ((ULONG)pAliasAligned) / P_SIZE;
// DPF((" pBufferAligned=%08Xh pAliasAligned=%08Xh cPages=%d",
// pBufferAligned, pAliasAligned, cPages));
fSuccess = VMM_PageAttach(nPageBuffer, VMM_GetCurrentContext(),
nPageAlias, cPages);
IOOUTPUT(fSuccess, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlMemDecommitAlias(PDIOCPARAMETERS pdiocp)
{
LPBYTE pAlias;
DWORD cbBuffer;
BOOL fSuccess;
int cPages;
LPBYTE pAliasAligned;
LPBYTE pPageAlias;
ULONG nPageAlias;
IOSTART(2*4);
IOINPUT(pAlias, LPBYTE);
IOINPUT(cbBuffer, DWORD);
// DPF(("iocltMemDecommitAlias pAlias=%08Xh", pAlias));
pAliasAligned = (LPBYTE)(((DWORD)pAlias) & ~(P_SIZE-1));
cPages = (pAlias + cbBuffer - pAliasAligned+ P_SIZE-1) / P_SIZE;
pPageAlias = pAliasAligned;
nPageAlias = ((ULONG)pPageAlias) / P_SIZE;
// DPF((" nPageAlias=%08Xh nPages=%d", nPageAlias, cPages));
fSuccess = (0 != _PageDecommit(nPageAlias, cPages, 0));
ASSERT(fSuccess);
IOOUTPUT(fSuccess, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlMemRedirectAlias(PDIOCPARAMETERS pdiocp)
{
LPBYTE pAlias;
DWORD cbBuffer;
BOOL fSuccess;
LPBYTE pAliasAligned;
ULONG nPageAlias;
ULONG nPageGarbage;
int cPages;
IOSTART(2*4);
IOINPUT(pAlias, LPBYTE);
IOINPUT(cbBuffer, DWORD);
DPF(("ioctlMemRedirectAlias pAlias=%08Xh cbBuffer=%d", pAlias, cbBuffer));
pAliasAligned = (LPBYTE)(((DWORD)pAlias) & ~(P_SIZE-1));
cPages = (pAlias+cbBuffer - pAliasAligned + P_SIZE-1) / P_SIZE;
nPageAlias = ((ULONG)pAliasAligned) / P_SIZE;
nPageGarbage = ((ULONG)gpGarbagePage) / P_SIZE;
// DPF((" pAliasAligned=%08Xh cPages=%d pGarbagePage=%08Xh",
// pAliasAligned, cPages, gpGarbagePage));
// We point every alias page at the same garbage page. This is
// MustComplete since the app's thread that is using the alias
// pointer might not be this current thread and may be writing
// thru the alias pointer. We wouldn't want the app's thread to
// run while the alias pages are decommitted.
VMM_EnterMustComplete();
fSuccess = (0 != _PageDecommit(nPageAlias, cPages, 0));
while (fSuccess && cPages--) {
fSuccess = VMM_PageAttach(nPageGarbage, VMM_GetCurrentContext(),
nPageAlias++, 1);
}
VMM_LeaveMustComplete();
IOOUTPUT(fSuccess, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlMemFreeAlias(PDIOCPARAMETERS pdiocp)
{
LPBYTE pAlias;
DWORD cbBuffer;
BOOL fSuccess;
LPBYTE pAliasAligned;
LPBYTE pPageAlias;
IOSTART(2*4);
IOINPUT(pAlias, LPBYTE);
IOINPUT(cbBuffer, DWORD);
DPF(("iocltMemFreeAlias pAlias=%08Xh", pAlias));
pAliasAligned = (LPBYTE)(((DWORD)pAlias) & ~(P_SIZE-1));
pPageAlias = pAliasAligned;
DPF((" pPageAlias=%08Xh", pPageAlias));
fSuccess = VMM_PageFree(pPageAlias, 0);
ASSERT(fSuccess);
IOOUTPUT(fSuccess, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlMemPageLock(PDIOCPARAMETERS pdiocp)
{
LPBYTE pMem;
DWORD cbBuffer;
DWORD dwFlags;
BOOL fSuccess;
LPBYTE pMemAligned;
ULONG nPageMem;
int cPages;
LPDWORD pdwTable;
LPVOID *ppTable;
DWORD cPagesTable;
IOSTART(5*4);
IOINPUT(pMem, LPBYTE);
IOINPUT(cbBuffer, DWORD);
IOINPUT(dwFlags, DWORD);
IOINPUT(pdwTable, LPDWORD);
IOINPUT(ppTable, LPVOID*);
pMemAligned = (LPBYTE)(((DWORD)pMem) & ~(P_SIZE-1));
cPages = (pMem+cbBuffer - pMemAligned+ P_SIZE-1) / P_SIZE;
nPageMem = ((ULONG)pMemAligned) / P_SIZE;
// Allocate the physical table
cPagesTable = (cPages-1)/1024 + 1;
*pdwTable = 0;
// Make sure that it is contiguous (requires FIXED & USEALIGN)
*ppTable = _PageAllocate(cPagesTable, PG_SYS,
Get_Sys_VM_Handle(), 0, 0, 0xffffff, (LPVOID *) pdwTable,
dwFlags | PAGEUSEALIGN | PAGEFIXED | PAGECONTIG);
if (*pdwTable == 0)
fSuccess = 0;
else
fSuccess = 1;
if (fSuccess)
{
/*
* Mask off the stuff that Intel gives us in the page table's physical address
*/
*pdwTable = (*pdwTable) & 0xfffff000;
fSuccess = _LinPageLock(nPageMem, cPages, dwFlags);
if (!fSuccess)
{
_PageFree((LPVOID)*ppTable, 0);
*ppTable = 0;
*pdwTable = 0;
}
}
if (fSuccess)
{
fSuccess = _CopyPageTable(nPageMem, cPages, (LPDWORD)*ppTable, 0);
if (!fSuccess)
{
_LinPageUnLock(nPageMem, cPages, dwFlags);
_PageFree((LPVOID)*ppTable, 0);
*ppTable = 0;
*pdwTable = 0;
}
}
IOOUTPUT(fSuccess, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlMemPageUnlock(PDIOCPARAMETERS pdiocp)
{
LPBYTE pMem;
DWORD cbBuffer;
DWORD dwFlags;
BOOL fSuccess;
LPBYTE pMemAligned;
ULONG nPageMem;
int cPages;
LPDWORD pTable;
IOSTART(4*4);
IOINPUT(pMem, LPBYTE);
IOINPUT(cbBuffer, DWORD);
IOINPUT(dwFlags, DWORD);
IOINPUT(pTable, LPDWORD);
pMemAligned = (LPBYTE)(((DWORD)pMem) & ~(P_SIZE-1));
cPages = (pMem + cbBuffer - pMemAligned + P_SIZE-1) / P_SIZE;
nPageMem = ((ULONG)pMemAligned) / P_SIZE;
fSuccess = _LinPageUnLock(nPageMem, cPages, dwFlags);
if (fSuccess)
{
_PageFree((LPVOID)pTable, 0);
}
IOOUTPUT(fSuccess, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlMemCommitPhysAlias(PDIOCPARAMETERS pdiocp)
{
LPBYTE pAlias;
LPBYTE pBuffer;
DWORD cbBuffer;
BOOL fSuccess;
LPBYTE pBufferAligned;
LPBYTE pAliasAligned;
LPBYTE pEndOfBuffer;
ULONG nPageBuffer;
ULONG nPageAlias;
ULONG nPhysPage;
int cPages;
DWORD dwPTE;
IOSTART(3*4);
IOINPUT(pAlias, LPBYTE);
IOINPUT(pBuffer, LPBYTE);
IOINPUT(cbBuffer, DWORD);
DPF(("ioctlMemCommitAlias pBuffer=%08Xh cbBuffer=%d pAlias=%08Xh",
pBuffer, cbBuffer, pAlias));
pEndOfBuffer = pBuffer + cbBuffer;
pBufferAligned = (LPBYTE)(((DWORD)pBuffer) & ~(P_SIZE-1));
pAliasAligned = (LPBYTE)(((DWORD)pAlias) & ~(P_SIZE-1));
cPages = (pEndOfBuffer - pBufferAligned + P_SIZE-1) / P_SIZE;
nPageBuffer = ((ULONG)pBufferAligned) / P_SIZE;
nPageAlias = ((ULONG)pAliasAligned) / P_SIZE;
DPF((" pBufferAligned=%08Xh pAliasAligned=%08Xh cPages=%d",
pBufferAligned, pAliasAligned, cPages));
// ALERT: A really very nasty hack. We DO NOT want to commit the alias
// to the given memory if the memory really is system rather than video
// memory (the pages could change the physical pages and we will be left
// pointing at garbage). Therefore, we need to make sure this is physical
// memory outside the memory managers control and not system memory. The
// problem is how to do this. Well, we really want to test the internal
// memory manage PT_PHYS bit but this is undocumented so instead I try
// to simply use VMM_PageAttach() as we know this will fail if you give it
// physical pages. Hence if the PageAttach() works we have system memory
// and we do NOT want to commit the alias. However, if it fails all should
// be well and we can commit the memory.
//
// Told you it was ugly (CMcC)
fSuccess = VMM_PageAttach(nPageBuffer, VMM_GetCurrentContext(),
nPageAlias, cPages);
if (fSuccess)
{
DPF((" Heap memory is system memory. Not commiting the alias" ));
_PageDecommit(nPageAlias, cPages, 0);
IOOUTPUT(FALSE, BOOL);
IORETURN;
return 0;
}
VMM_EnterMustComplete();
fSuccess = TRUE;
while (fSuccess && cPages--) {
fSuccess = _CopyPageTable(nPageBuffer++, 1UL, &dwPTE, 0UL);
if (fSuccess) {
nPhysPage = (dwPTE >> 12UL) & 0x000FFFFF;
fSuccess = _PageCommitPhys(nPageAlias++, 1, nPhysPage, PC_USER | PC_WRITEABLE);
}
}
VMM_LeaveMustComplete();
IOOUTPUT(fSuccess, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlMemRedirectPhysAlias(PDIOCPARAMETERS pdiocp)
{
LPBYTE pAlias;
DWORD cbBuffer;
BOOL fSuccess;
LPBYTE pAliasAligned;
ULONG nPageAlias;
ULONG nPageGarbage;
int cPages;
IOSTART(2*4);
IOINPUT(pAlias, LPBYTE);
IOINPUT(cbBuffer, DWORD);
DPF(("ioctlMemRedirectPhysAlias pAlias=%08Xh cbBuffer=%d", pAlias, cbBuffer));
pAliasAligned = (LPBYTE)(((DWORD)pAlias) & ~(P_SIZE-1));
cPages = (pAlias+cbBuffer - pAliasAligned + P_SIZE-1) / P_SIZE;
nPageAlias = ((ULONG)pAliasAligned) / P_SIZE;
nPageGarbage = (ULONG)_GetNulPageHandle();
// DPF((" pAliasAligned=%08Xh cPages=%d pGarbagePage=%08Xh",
// pAliasAligned, cPages, gpGarbagePage));
// We point every alias page at the same garbage page. This is
// MustComplete since the app's thread that is using the alias
// pointer might not be this current thread and may be writing
// thru the alias pointer. We wouldn't want the app's thread to
// run while the alias pages are decommitted.
VMM_EnterMustComplete();
fSuccess = (0 != _PageDecommit(nPageAlias, cPages, 0));
if (fSuccess)
fSuccess = _PageCommitPhys(nPageAlias, cPages, nPageGarbage, PC_USER | PC_WRITEABLE);
VMM_LeaveMustComplete();
IOOUTPUT(fSuccess, BOOL);
IORETURN;
return 0;
}
//--------------------------------------------------------------------------;
//
//
//
//--------------------------------------------------------------------------;
int ioctlGetInternalVersionNumber(PDIOCPARAMETERS pdiocp)
{
#ifndef VER_PRODUCTVERSION_DW
#define VER_PRODUCTVERSION_DW MAKELONG(MAKEWORD(MANVERSION, MANREVISION), MAKEWORD(MANMINORREV, BUILD_NUMBER))
#endif // VER_PRODUCTVERSION_DW
IOSTART(0*4);
IOOUTPUT(VER_PRODUCTVERSION_DW, DWORD);
IORETURN;
return 0;
}