|
|
// agfxc.cpp : Client side code for agfx.
//
// Created by FrankYe on 7/3/2000
//
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <mmsystem.h>
#include <mmsysp.h>
#include <tchar.h>
#include <regstr.h>
#include <ks.h>
#include <ksmedia.h>
#include "agfxp.h"
#include "audiosrv.h"
#include "audiosrvc.h"
// ISSUE-2000/09/25-FrankYe TODO list
// - move heap helpers somewhere else
// - remove ClientUpdatePnpInfo, and hHeap extern definitions
extern "C" void ClientUpdatePnpInfo(void); extern "C" HANDLE hHeap;
//
// This global variable tracks the most device interfaces contained in any
// DEVICEINTERFACELIST structure created by these functions. This helps
// validate the input to gfxDestroyDeviceInterfaceList
//
LONG gcMostDeviceInterfaces = 0;
#define RPC_CALL_START RpcTryExcept {
#define RPC_CALL_END_(status) } RpcExcept(1) { status = RpcExceptionCode(); } RpcEndExcept
#define RPC_CALL_END } RpcExcept(1) { RpcExceptionCode(); } RpcEndExcept
//=============================================================================
//=== Heap helpers ===
//=============================================================================
static BOOL HeapFreeIfNotNull(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) { return lpMem ? HeapFree(hHeap, dwFlags, lpMem) : TRUE; }
//=============================================================================
//=== gfx API ===
//=============================================================================
WINMMAPI LONG WINAPI gfxModifyGfx(DWORD Id, ULONG Order) { LONG status; ClientUpdatePnpInfo(); RPC_CALL_START; status = s_gfxModifyGfx(Id, Order); RPC_CALL_END_(status); return status; }
WINMMAPI LONG WINAPI gfxAddGfx(IN PCWSTR ZoneFactoryDi, IN PCWSTR GfxFactoryDi, IN ULONG Type, IN ULONG Order, OUT PULONG pNewId) { LONG status; if (IsBadStringPtr(ZoneFactoryDi, (UINT_PTR)(-1))) return ERROR_INVALID_PARAMETER; if (IsBadStringPtr(GfxFactoryDi, (UINT_PTR)(-1))) return ERROR_INVALID_PARAMETER; if (IsBadWritePtr(pNewId, sizeof(*pNewId))) return ERROR_INVALID_PARAMETER; ClientUpdatePnpInfo(); RPC_CALL_START; status = s_gfxAddGfx((PWSTR)ZoneFactoryDi, (PWSTR)GfxFactoryDi, Type, Order, pNewId); RPC_CALL_END_(status); return status; }
WINMMAPI LONG WINAPI gfxRemoveGfx(DWORD Id) { LONG status; ClientUpdatePnpInfo(); RPC_CALL_START; status = s_gfxRemoveGfx(Id); RPC_CALL_END_(status); return status; }
WINMMAPI LONG WINAPI gfxDestroyDeviceInterfaceList(PDEVICEINTERFACELIST pDiList) { LONG Count; PTSTR *ppDi; LONG result;
if (IsBadReadPtr(&pDiList->Count, sizeof(pDiList->Count))) return ERROR_INVALID_PARAMETER; Count = pDiList->Count; if (Count < 0 || Count > gcMostDeviceInterfaces) return ERROR_INVALID_PARAMETER; if (IsBadWritePtr(pDiList, (PBYTE)&pDiList->DeviceInterface[Count] - (PBYTE)pDiList)) return ERROR_INVALID_PARAMETER; ppDi = &pDiList->DeviceInterface[0]; while (Count-- > 0) if (IsBadStringPtr(*ppDi, (UINT_PTR)(-1))) return ERROR_INVALID_PARAMETER;
// Now we are reasonably confident that we have good input
// parameters. We design the following logic to return the
// first error encountered, if any.
ClientUpdatePnpInfo(); result = NO_ERROR; Count = pDiList->Count; ppDi = &pDiList->DeviceInterface[0]; while (Count-- > 0) if (!HeapFree(hHeap, 0, *(ppDi++)) && (NO_ERROR == result)) result = GetLastError(); if ((!HeapFree(hHeap, 0, pDiList)) && (NO_ERROR == result)) result = GetLastError();
SetLastError(result); return result; }
WINMMAPI LONG WINAPI gfxEnumerateGfxs(PCWSTR ZoneFactoryDi, GFXENUMCALLBACK pGfxEnumCallback, PVOID Context) { LONG lresult; UNIQUE_PGFXLIST pGfxList = NULL;
if (IsBadStringPtr(ZoneFactoryDi, (UINT_PTR)(-1))) return ERROR_INVALID_PARAMETER; if (IsBadCodePtr((FARPROC)pGfxEnumCallback)) return ERROR_INVALID_PARAMETER;
ClientUpdatePnpInfo(); RPC_CALL_START; lresult = s_gfxCreateGfxList((PWSTR)ZoneFactoryDi, &pGfxList); RPC_CALL_END_(lresult); // ISSUE-2000/09/25-FrankYe Should not have to check for pGfxList != NULL. Fix this interface
if (!lresult && pGfxList) { if (pGfxList->Count > 0) { int i = 0;
while (i < pGfxList->Count) { if (!lresult) lresult = pGfxEnumCallback(Context, pGfxList->Gfx[i].Id, pGfxList->Gfx[i].GfxFactoryDi, *(LPCLSID)(&pGfxList->Gfx[i].Clsid), pGfxList->Gfx[i].Type, pGfxList->Gfx[i].Order); HeapFree(hHeap, 0, pGfxList->Gfx[i].GfxFactoryDi); i++; } }
HeapFree(hHeap, 0, pGfxList); }
return lresult; }
WINMMAPI LONG WINAPI gfxCreateGfxFactoriesList(PCWSTR ZoneFactoryDi, OUT PDEVICEINTERFACELIST *ppDiList) { LONG lresult; UNIQUE_PDILIST pDiList = NULL;
if (IsBadWritePtr(ppDiList, sizeof(*ppDiList))) return ERROR_INVALID_PARAMETER;
ClientUpdatePnpInfo(); RPC_CALL_START; lresult = s_gfxCreateGfxFactoriesList((PWSTR)ZoneFactoryDi, &pDiList); RPC_CALL_END_(lresult);
if (!lresult) { gcMostDeviceInterfaces = max(gcMostDeviceInterfaces, pDiList->Count); *ppDiList = (PDEVICEINTERFACELIST)pDiList; } return lresult; }
WINMMAPI LONG WINAPI gfxCreateZoneFactoriesList(OUT PDEVICEINTERFACELIST *ppDiList) { LONG lresult; UNIQUE_PDILIST pDiList = NULL;
if (IsBadWritePtr(ppDiList, sizeof(*ppDiList))) return ERROR_INVALID_PARAMETER;
ClientUpdatePnpInfo(); RPC_CALL_START; lresult = s_gfxCreateZoneFactoriesList(&pDiList); RPC_CALL_END_(lresult);
if (!lresult) { gcMostDeviceInterfaces = max(gcMostDeviceInterfaces, pDiList->Count); *ppDiList = (PDEVICEINTERFACELIST)pDiList; } return lresult; }
WINMMAPI LONG WINAPI gfxBatchChange(PGFXREMOVEREQUEST paGfxRemoveRequests, ULONG cGfxRemoveRequests, PGFXMODIFYREQUEST paGfxModifyRequests, ULONG cGfxModifyRequests, PGFXADDREQUEST paGfxAddRequests, ULONG cGfxAddRequests) { ULONG Index; LONG Error;
if ((cGfxRemoveRequests > 0) && IsBadWritePtr(paGfxRemoveRequests, cGfxRemoveRequests * sizeof(*paGfxRemoveRequests))) return ERROR_INVALID_PARAMETER; if ((cGfxModifyRequests > 0) && IsBadWritePtr(paGfxModifyRequests, cGfxModifyRequests * sizeof(*paGfxModifyRequests))) return ERROR_INVALID_PARAMETER; if ((cGfxAddRequests > 0) && IsBadWritePtr(paGfxAddRequests, cGfxAddRequests * sizeof(*paGfxAddRequests))) return ERROR_INVALID_PARAMETER;
ClientUpdatePnpInfo(); Error = ERROR_SUCCESS; for (Index = 0; Index < cGfxRemoveRequests && ERROR_SUCCESS == Error; Index++) { Error = gfxRemoveGfx(paGfxRemoveRequests[Index].IdToRemove); paGfxRemoveRequests[Index].Error = Error; }
for (Index = 0; Index < cGfxModifyRequests && ERROR_SUCCESS == Error; Index++) { Error = gfxModifyGfx(paGfxModifyRequests[Index].IdToModify, paGfxModifyRequests[Index].NewOrder); paGfxModifyRequests[Index].Error = Error; }
for (Index = 0; Index < cGfxAddRequests && ERROR_SUCCESS == Error; Index++) { Error = gfxAddGfx(paGfxAddRequests[Index].ZoneFactoryDi, paGfxAddRequests[Index].GfxFactoryDi, paGfxAddRequests[Index].Type, paGfxAddRequests[Index].Order, &paGfxAddRequests[Index].NewId); paGfxAddRequests[Index].Error = Error; }
return Error; }
WINMMAPI LONG WINAPI gfxOpenGfx(DWORD dwGfxId, PHANDLE pFileHandle) { LONG status; ClientUpdatePnpInfo(); RPC_CALL_START; status = s_gfxOpenGfx(GetCurrentProcessId(), dwGfxId, (RHANDLE*)pFileHandle); RPC_CALL_END_(status); return status; }
WINMMAPI void WINAPI gfxLogon(DWORD dwProcessId) { ClientUpdatePnpInfo(); RPC_CALL_START; s_gfxLogon(AudioSrv_IfHandle, dwProcessId); RPC_CALL_END; }
WINMMAPI void WINAPI gfxLogoff(void) { ClientUpdatePnpInfo(); RPC_CALL_START; s_gfxLogoff(); RPC_CALL_END; }
|