294 lines
8.4 KiB
C
294 lines
8.4 KiB
C
|
//================================================================================
|
||
|
// Copyright (C) 1997 Microsoft Corporation
|
||
|
// Author: RameshV
|
||
|
// Description: implements the basic structures for a list of class defintitions
|
||
|
// ThreadSafe: no
|
||
|
// Locks: none
|
||
|
// Please read stdinfo.txt for programming style.
|
||
|
//================================================================================
|
||
|
#include <mm.h>
|
||
|
#include <array.h>
|
||
|
#include <wchar.h>
|
||
|
|
||
|
//BeginExport(typedef)
|
||
|
typedef struct _M_CLASSDEF {
|
||
|
DWORD RefCount;
|
||
|
DWORD ClassId;
|
||
|
BOOL IsVendor;
|
||
|
DWORD Type;
|
||
|
LPWSTR Name;
|
||
|
LPWSTR Comment;
|
||
|
DWORD nBytes;
|
||
|
LPBYTE ActualBytes;
|
||
|
} M_CLASSDEF, *PM_CLASSDEF, *LPM_CLASSDEF;
|
||
|
|
||
|
typedef struct _M_CLASSDEFLIST {
|
||
|
ARRAY ClassDefArray;
|
||
|
} M_CLASSDEFLIST, *PM_CLASSDEFLIST, *LPM_CLASSDEFLIST;
|
||
|
//EndExport(typedef)
|
||
|
|
||
|
//BeginExport(inline)
|
||
|
DWORD _inline
|
||
|
MemClassDefListInit(
|
||
|
IN OUT PM_CLASSDEFLIST ClassDefList
|
||
|
) {
|
||
|
return MemArrayInit(&ClassDefList->ClassDefArray);
|
||
|
}
|
||
|
//EndExport(inline)
|
||
|
|
||
|
//BeginExport(inline)
|
||
|
DWORD _inline
|
||
|
MemClassDefListCleanup(
|
||
|
IN OUT PM_CLASSDEFLIST ClassDefList
|
||
|
) {
|
||
|
return MemArrayCleanup(&ClassDefList->ClassDefArray);
|
||
|
}
|
||
|
//EndExport(inline)
|
||
|
|
||
|
//BeginExport(function)
|
||
|
DWORD
|
||
|
MemClassDefListFindClassDefInternal( // dont use this fn outside of classdefl.c
|
||
|
IN PM_CLASSDEFLIST ClassDefList,
|
||
|
IN DWORD ClassId,
|
||
|
IN LPWSTR Name,
|
||
|
IN LPBYTE ActualBytes,
|
||
|
IN DWORD nBytes,
|
||
|
IN LPBOOL pIsVendor,
|
||
|
OUT PARRAY_LOCATION Location
|
||
|
) //EndExport(function)
|
||
|
{
|
||
|
DWORD Error;
|
||
|
PM_CLASSDEF ThisClassDef;
|
||
|
|
||
|
for( Error = MemArrayInitLoc(&ClassDefList->ClassDefArray, Location)
|
||
|
; ERROR_FILE_NOT_FOUND != Error ;
|
||
|
Error = MemArrayNextLoc(&ClassDefList->ClassDefArray, Location)
|
||
|
) {
|
||
|
Require(ERROR_SUCCESS == Error);
|
||
|
|
||
|
Error = MemArrayGetElement(
|
||
|
&ClassDefList->ClassDefArray,
|
||
|
Location,
|
||
|
(LPVOID *)&ThisClassDef
|
||
|
);
|
||
|
Require(ERROR_SUCCESS == Error && ThisClassDef);
|
||
|
|
||
|
if( pIsVendor != NULL && ThisClassDef->IsVendor != *pIsVendor)
|
||
|
continue;
|
||
|
|
||
|
if( ThisClassDef->ClassId == ClassId ) {
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
if( nBytes == ThisClassDef->nBytes ) {
|
||
|
if( 0 == memcmp(ActualBytes, ThisClassDef->ActualBytes, nBytes)) {
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( Name && 0 == wcscmp(ThisClassDef->Name, Name) ) {
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ERROR_FILE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
//BeginExport(inline)
|
||
|
DWORD _inline
|
||
|
MemClassDefListFindOptDef( // search either by ClassId or by Actual bytes and fill matched stuff
|
||
|
IN PM_CLASSDEFLIST ClassDefList,
|
||
|
IN DWORD ClassId,
|
||
|
IN LPWSTR Name,
|
||
|
IN LPBYTE ActualBytes,
|
||
|
IN DWORD nBytes,
|
||
|
OUT PM_CLASSDEF *ClassDef // NULL or valid matching class def
|
||
|
) {
|
||
|
ARRAY_LOCATION Location;
|
||
|
DWORD Error;
|
||
|
|
||
|
AssertRet(ClassDef, ERROR_INVALID_PARAMETER);
|
||
|
|
||
|
Error = MemClassDefListFindClassDefInternal(
|
||
|
ClassDefList,
|
||
|
ClassId,
|
||
|
Name,
|
||
|
ActualBytes,
|
||
|
nBytes,
|
||
|
NULL,
|
||
|
&Location
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Error) return Error;
|
||
|
|
||
|
Error = MemArrayGetElement(
|
||
|
&ClassDefList->ClassDefArray,
|
||
|
&Location,
|
||
|
(LPVOID*)ClassDef
|
||
|
);
|
||
|
Require(ERROR_SUCCESS == Error);
|
||
|
|
||
|
return Error;
|
||
|
}
|
||
|
|
||
|
//BeginExport(function)
|
||
|
DWORD
|
||
|
MemClassDefListAddClassDef( // Add or replace option
|
||
|
IN OUT PM_CLASSDEFLIST ClassDefList,
|
||
|
IN DWORD ClassId,
|
||
|
IN BOOL IsVendor,
|
||
|
IN DWORD Type,
|
||
|
IN LPWSTR Name,
|
||
|
IN LPWSTR Comment,
|
||
|
IN LPBYTE ActualBytes,
|
||
|
IN DWORD nBytes
|
||
|
) //EndExport(function)
|
||
|
{
|
||
|
ARRAY_LOCATION Location;
|
||
|
DWORD Error;
|
||
|
DWORD Size;
|
||
|
PM_CLASSDEF ThisClassDef;
|
||
|
PM_CLASSDEF OldClassDef;
|
||
|
|
||
|
AssertRet(ClassDefList && ClassId && Name && ActualBytes && nBytes, ERROR_INVALID_PARAMETER );
|
||
|
|
||
|
Error = MemClassDefListFindClassDefInternal(
|
||
|
ClassDefList,
|
||
|
ClassId,
|
||
|
Name,
|
||
|
ActualBytes,
|
||
|
nBytes,
|
||
|
&IsVendor,
|
||
|
&Location
|
||
|
);
|
||
|
|
||
|
Size = sizeof(M_CLASSDEF)+nBytes;
|
||
|
Size = ROUND_UP_COUNT(Size, ALIGN_WORST);
|
||
|
Size += (1+wcslen(Name))*sizeof(WCHAR);
|
||
|
if( Comment ) Size += (1+wcslen(Comment))*sizeof(WCHAR);
|
||
|
|
||
|
ThisClassDef = MemAlloc(Size);
|
||
|
if( NULL == ThisClassDef ) return ERROR_NOT_ENOUGH_MEMORY;
|
||
|
|
||
|
ThisClassDef->RefCount = 1;
|
||
|
ThisClassDef->ClassId = ClassId;
|
||
|
ThisClassDef->IsVendor = IsVendor;
|
||
|
ThisClassDef->Type = Type;
|
||
|
ThisClassDef->nBytes = nBytes;
|
||
|
ThisClassDef->ActualBytes = sizeof(M_CLASSDEF) + (LPBYTE)ThisClassDef;
|
||
|
memcpy(ThisClassDef->ActualBytes, ActualBytes, nBytes);
|
||
|
ThisClassDef->Name = (LPWSTR)(ROUND_UP_COUNT(sizeof(M_CLASSDEF)+nBytes, ALIGN_WORST) + (LPBYTE)ThisClassDef);
|
||
|
wcscpy(ThisClassDef->Name, Name);
|
||
|
if( Comment ) {
|
||
|
ThisClassDef->Comment = 1 + wcslen(Name) + ThisClassDef->Name;
|
||
|
wcscpy(ThisClassDef->Comment, Comment);
|
||
|
} else {
|
||
|
ThisClassDef->Comment = NULL;
|
||
|
}
|
||
|
|
||
|
if( ERROR_SUCCESS == Error ) {
|
||
|
DebugPrint2("Overwriting class definition for class-id 0x%lx\n", ClassId);
|
||
|
Error = MemArrayGetElement(
|
||
|
&ClassDefList->ClassDefArray,
|
||
|
&Location,
|
||
|
(LPVOID *)&OldClassDef
|
||
|
);
|
||
|
Require(ERROR_SUCCESS == Error);
|
||
|
MemFree(OldClassDef);
|
||
|
|
||
|
Error = MemArraySetElement(
|
||
|
&ClassDefList->ClassDefArray,
|
||
|
&Location,
|
||
|
ThisClassDef
|
||
|
);
|
||
|
Require(ERROR_SUCCESS == Error);
|
||
|
return Error;
|
||
|
}
|
||
|
|
||
|
Error = MemArrayAddElement(
|
||
|
&ClassDefList->ClassDefArray,
|
||
|
ThisClassDef
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Error ) MemFree(ThisClassDef);
|
||
|
|
||
|
return Error;
|
||
|
}
|
||
|
|
||
|
|
||
|
//BeginExport(inline)
|
||
|
DWORD _inline
|
||
|
MemClassDefListDelClassDef(
|
||
|
IN OUT PM_CLASSDEFLIST ClassDefList,
|
||
|
IN DWORD ClassId,
|
||
|
IN LPWSTR Name,
|
||
|
IN LPBYTE ActualBytes,
|
||
|
IN DWORD nBytes
|
||
|
) {
|
||
|
ARRAY_LOCATION Location;
|
||
|
DWORD Error;
|
||
|
PM_CLASSDEF ThisClassDef;
|
||
|
|
||
|
Error = MemClassDefListFindClassDefInternal(
|
||
|
ClassDefList,
|
||
|
ClassId,
|
||
|
Name,
|
||
|
ActualBytes,
|
||
|
nBytes,
|
||
|
NULL,
|
||
|
&Location
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Error ) return Error;
|
||
|
|
||
|
Error = MemArrayDelElement(
|
||
|
&ClassDefList->ClassDefArray,
|
||
|
&Location,
|
||
|
&ThisClassDef
|
||
|
);
|
||
|
Require(ERROR_SUCCESS == Error && ThisClassDef);
|
||
|
|
||
|
MemFree(ThisClassDef);
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
//EndExport(inline)
|
||
|
|
||
|
//BeginExport(inline)
|
||
|
DWORD _inline
|
||
|
MemClassDefListGetRefCount(
|
||
|
IN PM_CLASSDEF ThisClassDef
|
||
|
) {
|
||
|
return ThisClassDef->RefCount;
|
||
|
}
|
||
|
//EndExport(inline)
|
||
|
|
||
|
//BeginExport(inline)
|
||
|
DWORD _inline
|
||
|
MemClassDefListIncRefCount( // return increased by one value
|
||
|
IN PM_CLASSDEF ThisClassDef
|
||
|
) {
|
||
|
return ++ThisClassDef->RefCount;
|
||
|
}
|
||
|
//EndExport(inline)
|
||
|
|
||
|
//BeginExport(inline)
|
||
|
DWORD _inline
|
||
|
MemClassDefListDecRefCount( // return decreased by one value
|
||
|
IN PM_CLASSDEF ThisClassDef
|
||
|
) {
|
||
|
return --ThisClassDef->RefCount;
|
||
|
}
|
||
|
//EndExport(inline)
|
||
|
|
||
|
ULONG ClassIdRunningCount = 100;
|
||
|
|
||
|
//BeginExport(function)
|
||
|
DWORD
|
||
|
MemNewClassId(
|
||
|
VOID
|
||
|
) //EndExport(function)
|
||
|
{
|
||
|
return InterlockedIncrement(&ClassIdRunningCount);
|
||
|
}
|
||
|
|
||
|
//================================================================================
|
||
|
// end of file
|
||
|
//================================================================================
|