1424 lines
32 KiB
C++
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;
|
||
|
}
|
||
|
|