You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
8.1 KiB
263 lines
8.1 KiB
// 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;
|
|
}
|
|
|