Source code of Windows XP (NT5)
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.

293 lines
8.4 KiB

  1. //================================================================================
  2. // Copyright (C) 1997 Microsoft Corporation
  3. // Author: RameshV
  4. // Description: implements the basic structures for a list of class defintitions
  5. // ThreadSafe: no
  6. // Locks: none
  7. // Please read stdinfo.txt for programming style.
  8. //================================================================================
  9. #include <mm.h>
  10. #include <array.h>
  11. #include <wchar.h>
  12. //BeginExport(typedef)
  13. typedef struct _M_CLASSDEF {
  14. DWORD RefCount;
  15. DWORD ClassId;
  16. BOOL IsVendor;
  17. DWORD Type;
  18. LPWSTR Name;
  19. LPWSTR Comment;
  20. DWORD nBytes;
  21. LPBYTE ActualBytes;
  22. } M_CLASSDEF, *PM_CLASSDEF, *LPM_CLASSDEF;
  23. typedef struct _M_CLASSDEFLIST {
  24. ARRAY ClassDefArray;
  25. } M_CLASSDEFLIST, *PM_CLASSDEFLIST, *LPM_CLASSDEFLIST;
  26. //EndExport(typedef)
  27. //BeginExport(inline)
  28. DWORD _inline
  29. MemClassDefListInit(
  30. IN OUT PM_CLASSDEFLIST ClassDefList
  31. ) {
  32. return MemArrayInit(&ClassDefList->ClassDefArray);
  33. }
  34. //EndExport(inline)
  35. //BeginExport(inline)
  36. DWORD _inline
  37. MemClassDefListCleanup(
  38. IN OUT PM_CLASSDEFLIST ClassDefList
  39. ) {
  40. return MemArrayCleanup(&ClassDefList->ClassDefArray);
  41. }
  42. //EndExport(inline)
  43. //BeginExport(function)
  44. DWORD
  45. MemClassDefListFindClassDefInternal( // dont use this fn outside of classdefl.c
  46. IN PM_CLASSDEFLIST ClassDefList,
  47. IN DWORD ClassId,
  48. IN LPWSTR Name,
  49. IN LPBYTE ActualBytes,
  50. IN DWORD nBytes,
  51. IN LPBOOL pIsVendor,
  52. OUT PARRAY_LOCATION Location
  53. ) //EndExport(function)
  54. {
  55. DWORD Error;
  56. PM_CLASSDEF ThisClassDef;
  57. for( Error = MemArrayInitLoc(&ClassDefList->ClassDefArray, Location)
  58. ; ERROR_FILE_NOT_FOUND != Error ;
  59. Error = MemArrayNextLoc(&ClassDefList->ClassDefArray, Location)
  60. ) {
  61. Require(ERROR_SUCCESS == Error);
  62. Error = MemArrayGetElement(
  63. &ClassDefList->ClassDefArray,
  64. Location,
  65. (LPVOID *)&ThisClassDef
  66. );
  67. Require(ERROR_SUCCESS == Error && ThisClassDef);
  68. if( pIsVendor != NULL && ThisClassDef->IsVendor != *pIsVendor)
  69. continue;
  70. if( ThisClassDef->ClassId == ClassId ) {
  71. return ERROR_SUCCESS;
  72. }
  73. if( nBytes == ThisClassDef->nBytes ) {
  74. if( 0 == memcmp(ActualBytes, ThisClassDef->ActualBytes, nBytes)) {
  75. return ERROR_SUCCESS;
  76. }
  77. }
  78. if( Name && 0 == wcscmp(ThisClassDef->Name, Name) ) {
  79. return ERROR_SUCCESS;
  80. }
  81. }
  82. return ERROR_FILE_NOT_FOUND;
  83. }
  84. //BeginExport(inline)
  85. DWORD _inline
  86. MemClassDefListFindOptDef( // search either by ClassId or by Actual bytes and fill matched stuff
  87. IN PM_CLASSDEFLIST ClassDefList,
  88. IN DWORD ClassId,
  89. IN LPWSTR Name,
  90. IN LPBYTE ActualBytes,
  91. IN DWORD nBytes,
  92. OUT PM_CLASSDEF *ClassDef // NULL or valid matching class def
  93. ) {
  94. ARRAY_LOCATION Location;
  95. DWORD Error;
  96. AssertRet(ClassDef, ERROR_INVALID_PARAMETER);
  97. Error = MemClassDefListFindClassDefInternal(
  98. ClassDefList,
  99. ClassId,
  100. Name,
  101. ActualBytes,
  102. nBytes,
  103. NULL,
  104. &Location
  105. );
  106. if( ERROR_SUCCESS != Error) return Error;
  107. Error = MemArrayGetElement(
  108. &ClassDefList->ClassDefArray,
  109. &Location,
  110. (LPVOID*)ClassDef
  111. );
  112. Require(ERROR_SUCCESS == Error);
  113. return Error;
  114. }
  115. //BeginExport(function)
  116. DWORD
  117. MemClassDefListAddClassDef( // Add or replace option
  118. IN OUT PM_CLASSDEFLIST ClassDefList,
  119. IN DWORD ClassId,
  120. IN BOOL IsVendor,
  121. IN DWORD Type,
  122. IN LPWSTR Name,
  123. IN LPWSTR Comment,
  124. IN LPBYTE ActualBytes,
  125. IN DWORD nBytes
  126. ) //EndExport(function)
  127. {
  128. ARRAY_LOCATION Location;
  129. DWORD Error;
  130. DWORD Size;
  131. PM_CLASSDEF ThisClassDef;
  132. PM_CLASSDEF OldClassDef;
  133. AssertRet(ClassDefList && ClassId && Name && ActualBytes && nBytes, ERROR_INVALID_PARAMETER );
  134. Error = MemClassDefListFindClassDefInternal(
  135. ClassDefList,
  136. ClassId,
  137. Name,
  138. ActualBytes,
  139. nBytes,
  140. &IsVendor,
  141. &Location
  142. );
  143. Size = sizeof(M_CLASSDEF)+nBytes;
  144. Size = ROUND_UP_COUNT(Size, ALIGN_WORST);
  145. Size += (1+wcslen(Name))*sizeof(WCHAR);
  146. if( Comment ) Size += (1+wcslen(Comment))*sizeof(WCHAR);
  147. ThisClassDef = MemAlloc(Size);
  148. if( NULL == ThisClassDef ) return ERROR_NOT_ENOUGH_MEMORY;
  149. ThisClassDef->RefCount = 1;
  150. ThisClassDef->ClassId = ClassId;
  151. ThisClassDef->IsVendor = IsVendor;
  152. ThisClassDef->Type = Type;
  153. ThisClassDef->nBytes = nBytes;
  154. ThisClassDef->ActualBytes = sizeof(M_CLASSDEF) + (LPBYTE)ThisClassDef;
  155. memcpy(ThisClassDef->ActualBytes, ActualBytes, nBytes);
  156. ThisClassDef->Name = (LPWSTR)(ROUND_UP_COUNT(sizeof(M_CLASSDEF)+nBytes, ALIGN_WORST) + (LPBYTE)ThisClassDef);
  157. wcscpy(ThisClassDef->Name, Name);
  158. if( Comment ) {
  159. ThisClassDef->Comment = 1 + wcslen(Name) + ThisClassDef->Name;
  160. wcscpy(ThisClassDef->Comment, Comment);
  161. } else {
  162. ThisClassDef->Comment = NULL;
  163. }
  164. if( ERROR_SUCCESS == Error ) {
  165. DebugPrint2("Overwriting class definition for class-id 0x%lx\n", ClassId);
  166. Error = MemArrayGetElement(
  167. &ClassDefList->ClassDefArray,
  168. &Location,
  169. (LPVOID *)&OldClassDef
  170. );
  171. Require(ERROR_SUCCESS == Error);
  172. MemFree(OldClassDef);
  173. Error = MemArraySetElement(
  174. &ClassDefList->ClassDefArray,
  175. &Location,
  176. ThisClassDef
  177. );
  178. Require(ERROR_SUCCESS == Error);
  179. return Error;
  180. }
  181. Error = MemArrayAddElement(
  182. &ClassDefList->ClassDefArray,
  183. ThisClassDef
  184. );
  185. if( ERROR_SUCCESS != Error ) MemFree(ThisClassDef);
  186. return Error;
  187. }
  188. //BeginExport(inline)
  189. DWORD _inline
  190. MemClassDefListDelClassDef(
  191. IN OUT PM_CLASSDEFLIST ClassDefList,
  192. IN DWORD ClassId,
  193. IN LPWSTR Name,
  194. IN LPBYTE ActualBytes,
  195. IN DWORD nBytes
  196. ) {
  197. ARRAY_LOCATION Location;
  198. DWORD Error;
  199. PM_CLASSDEF ThisClassDef;
  200. Error = MemClassDefListFindClassDefInternal(
  201. ClassDefList,
  202. ClassId,
  203. Name,
  204. ActualBytes,
  205. nBytes,
  206. NULL,
  207. &Location
  208. );
  209. if( ERROR_SUCCESS != Error ) return Error;
  210. Error = MemArrayDelElement(
  211. &ClassDefList->ClassDefArray,
  212. &Location,
  213. &ThisClassDef
  214. );
  215. Require(ERROR_SUCCESS == Error && ThisClassDef);
  216. MemFree(ThisClassDef);
  217. return ERROR_SUCCESS;
  218. }
  219. //EndExport(inline)
  220. //BeginExport(inline)
  221. DWORD _inline
  222. MemClassDefListGetRefCount(
  223. IN PM_CLASSDEF ThisClassDef
  224. ) {
  225. return ThisClassDef->RefCount;
  226. }
  227. //EndExport(inline)
  228. //BeginExport(inline)
  229. DWORD _inline
  230. MemClassDefListIncRefCount( // return increased by one value
  231. IN PM_CLASSDEF ThisClassDef
  232. ) {
  233. return ++ThisClassDef->RefCount;
  234. }
  235. //EndExport(inline)
  236. //BeginExport(inline)
  237. DWORD _inline
  238. MemClassDefListDecRefCount( // return decreased by one value
  239. IN PM_CLASSDEF ThisClassDef
  240. ) {
  241. return --ThisClassDef->RefCount;
  242. }
  243. //EndExport(inline)
  244. ULONG ClassIdRunningCount = 100;
  245. //BeginExport(function)
  246. DWORD
  247. MemNewClassId(
  248. VOID
  249. ) //EndExport(function)
  250. {
  251. return InterlockedIncrement(&ClassIdRunningCount);
  252. }
  253. //================================================================================
  254. // end of file
  255. //================================================================================