//--------------------------------------------------------------------------; // // File: dsvxd.c // // Copyright (c) 1995 Microsoft Corporation. All Rights Reserved. // // Abstract: // // Contents: // // History: // 06/15/95 FrankYe // //--------------------------------------------------------------------------; #define WANTVXDWRAPS #define INITGUID #include extern "C" { #include #include #include #include #include #include } #define NODSOUNDWRAPS #include #include #include #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; }