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.

753 lines
13 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. memdbp.h
  5. Abstract:
  6. internal functions for memdb operations
  7. Author:
  8. Matthew Vanderzee (mvander) 13-Aug-1999
  9. Revision History:
  10. --*/
  11. //
  12. // Constants
  13. //
  14. #define INVALID_OFFSET (~((UINT)0))
  15. //
  16. // database types
  17. //
  18. #define DB_NOTHING 0x00
  19. #define DB_PERMANENT 0x01
  20. #define DB_TEMPORARY 0x02
  21. #ifdef DEBUG
  22. #define PTR_WAS_INVALIDATED(x) (x=NULL)
  23. #else
  24. #define PTR_WAS_INVALIDATED(x)
  25. #endif
  26. //
  27. // signatures for different memory structures.
  28. //
  29. #define KEYSTRUCT_SIGNATURE ('K'+('E'<<8)+('E'<<16)+('Y'<<24))
  30. #define DATABLOCK_SIGNATURE ('B'+('L'<<8)+('O'<<16)+('K'<<24))
  31. #define NODESTRUCT_SIGNATURE ('N'+('O'<<8)+('D'<<16)+('E'<<24))
  32. #define BINTREE_SIGNATURE ('T'+('R'<<8)+('E'<<16)+('E'<<24))
  33. #define LISTELEM_SIGNATURE ('L'+('I'<<8)+('S'<<16)+('T'<<24))
  34. #define MEMDB_VERBOSE 0
  35. //
  36. // KEYSTRUCT flags
  37. //
  38. #define KSF_ENDPOINT 0x01
  39. #define KSF_DATABLOCK 0x02
  40. //
  41. // we only need this flag for easier checking
  42. // of keys, in FindKeyStructInDatabase()
  43. //
  44. #ifdef DEBUG
  45. #define KSF_DELETED 0x04
  46. #endif
  47. //
  48. // database allocation parameters
  49. //
  50. #define ALLOC_TOLERANCE 32
  51. #define MAX_HIVE_NAME 64
  52. //
  53. // Typedefs
  54. //
  55. typedef struct {
  56. UINT Size;
  57. UINT End;
  58. UINT FreeHead;
  59. PBYTE Buf;
  60. } MEMDBHASH, *PMEMDBHASH;
  61. //
  62. //
  63. // The DATABASE structure holds all pieces of information necessary
  64. // to maintain a portion of the overall memory database. There are
  65. // two DATABASE structures, a permanent and a temporary one.
  66. //
  67. typedef struct {
  68. UINT AllocSize;
  69. UINT End;
  70. UINT FirstLevelTree;
  71. UINT FirstKeyDeleted; // this stores the Offset of the key, not the Index
  72. UINT FirstBinTreeDeleted;
  73. UINT FirstBinTreeNodeDeleted;
  74. UINT FirstBinTreeListElemDeleted;
  75. BOOL AllocFailed;
  76. PMEMDBHASH HashTable;
  77. GROWBUFFER OffsetBuffer;
  78. UINT OffsetBufferFirstDeletedIndex;
  79. BYTE Buf[];
  80. } DATABASE, *PDATABASE;
  81. //
  82. // Globals - defined in database.c
  83. //
  84. extern PDATABASE g_CurrentDatabase;
  85. extern BYTE g_CurrentDatabaseIndex;
  86. extern CRITICAL_SECTION g_MemDbCs;
  87. #ifdef DEBUG
  88. extern BOOL g_UseDebugStructs;
  89. #endif
  90. #define OFFSET_TO_PTR(Offset) (g_CurrentDatabase->Buf+(Offset))
  91. #define PTR_TO_OFFSET(Ptr) (UINT)((UBINT)(Ptr)-(UBINT)(g_CurrentDatabase->Buf))
  92. //
  93. // GET_EXTERNAL_INDEX converts an internal index and converts it to a key or data handle (has database number as top byte).
  94. // GET_DATABASE takes a key or data handle and returns the database number byte
  95. // GET_INDEX takes a key or data handle and returns the index without the database number
  96. //
  97. #define GET_EXTERNAL_INDEX(Index) ((Index) | ((UINT)(g_CurrentDatabaseIndex) << (8*sizeof(UINT)-8)))
  98. #define GET_DATABASE(Index) ((BYTE)((Index) >> (8*sizeof(UINT)-8)))
  99. #define GET_INDEX(Index) ((Index) & (INVALID_OFFSET>>8))
  100. //
  101. // a KEYSTRUCT holds each piece of a memdb entry. A single KEYSTRUCT
  102. // holds a portion of a key (delimited by a backslash), and the
  103. // KEYSTRUCTs are organized into a binary tree. Each KEYSTRUCT
  104. // can also contain additional binary trees. This is what makes
  105. // memdb so versatile--many relationships can be established by
  106. // formatting key strings in various ways.
  107. //
  108. // when changing offset of KeyName in KEYSTRUCT (by adding new members
  109. // or resizing or reordering, etc) be sure to change constant in
  110. // GetDataStr macro below (currently (3*sizeof(UINT)+4)).
  111. typedef struct {
  112. #ifdef DEBUG
  113. DWORD Signature;
  114. #endif
  115. union {
  116. UINT Value; // value of key
  117. UINT DataSize; // size of the actual data (if this is a data structure
  118. UINT NextDeleted; // for deleted items, we keep a list of free blocks
  119. };
  120. UINT Flags; // key flags
  121. UINT DataStructIndex; // offset of Data structure holding the binary data
  122. UINT NextLevelTree; // offset of bintree holding next level keystructs
  123. UINT PrevLevelIndex; // index of previous level keystruct
  124. UINT Size; // size of block (maybe not all of it is used)
  125. BYTE KeyFlags;
  126. BYTE DataFlags;
  127. union {
  128. WCHAR KeyName[]; // name of key (just this level, not full key)
  129. BYTE Data[]; // Binary data stored in this keystruct
  130. };
  131. } KEYSTRUCT, *PKEYSTRUCT;
  132. #define KEYSTRUCT_SIZE_MAIN ((WORD)(5*sizeof(UINT) + sizeof(UINT) + 2*sizeof(BYTE)))
  133. #ifdef DEBUG
  134. #define KEYSTRUCT_HEADER_SIZE sizeof(DWORD)
  135. #define KEYSTRUCT_SIZE (KEYSTRUCT_SIZE_MAIN + \
  136. (WORD)(g_UseDebugStructs ? KEYSTRUCT_HEADER_SIZE : 0))
  137. #else
  138. #define KEYSTRUCT_SIZE KEYSTRUCT_SIZE_MAIN
  139. #endif
  140. //
  141. // GetDataStr is used by the bintree.c functions to get
  142. // the data string inside a data element, to be used for
  143. // ordering in the tree. For us, the data type is
  144. // a KeyStruct.
  145. //
  146. #define GetDataStr(DataIndex) ((PWSTR)(OFFSET_TO_PTR(KeyIndexToOffset(DataIndex)+KEYSTRUCT_SIZE)))
  147. //
  148. // hash.c routines
  149. //
  150. PMEMDBHASH
  151. CreateHashBlock (
  152. VOID
  153. );
  154. VOID
  155. FreeHashBlock (
  156. IN PMEMDBHASH pHashTable
  157. );
  158. BOOL
  159. ReadHashBlock (
  160. IN PMEMDBHASH pHashTable,
  161. IN OUT PBYTE *Buf
  162. );
  163. BOOL
  164. WriteHashBlock (
  165. IN PMEMDBHASH pHashTable,
  166. IN OUT PBYTE *Buf
  167. );
  168. UINT
  169. GetHashTableBlockSize (
  170. IN PMEMDBHASH pHashTable
  171. );
  172. BOOL
  173. AddHashTableEntry (
  174. IN PMEMDBHASH pHashTable,
  175. IN PCWSTR FullString,
  176. IN UINT Offset
  177. );
  178. UINT
  179. FindStringInHashTable (
  180. IN PMEMDBHASH pHashTable,
  181. IN PCWSTR FullString
  182. );
  183. BOOL
  184. RemoveHashTableEntry (
  185. IN PMEMDBHASH pHashTable,
  186. IN PCWSTR FullString
  187. );
  188. //
  189. // memdbfile.c
  190. //
  191. BOOL
  192. SetSizeOfFile (
  193. HANDLE hFile,
  194. LONGLONG Size
  195. );
  196. PBYTE
  197. MapFileFromHandle (
  198. HANDLE hFile,
  199. PHANDLE hMap
  200. );
  201. #define UnmapFileFromHandle(Buf, hMap) UnmapFile(Buf, hMap, INVALID_HANDLE_VALUE)
  202. //
  203. // database.c
  204. //
  205. BOOL
  206. DatabasesInitializeA (
  207. IN PCSTR DatabasePath OPTIONAL
  208. );
  209. BOOL
  210. DatabasesInitializeW (
  211. IN PCWSTR DatabasePath OPTIONAL
  212. );
  213. PCSTR
  214. DatabasesGetBasePath (
  215. VOID
  216. );
  217. VOID
  218. DatabasesTerminate (
  219. IN BOOL EraseDatabasePath
  220. );
  221. BOOL
  222. SizeDatabaseBuffer (
  223. IN BYTE DatabaseIndex,
  224. IN UINT NewSize
  225. );
  226. UINT
  227. DatabaseAllocBlock (
  228. IN UINT Size
  229. );
  230. BOOL
  231. SelectDatabase (
  232. IN BYTE DatabaseIndex
  233. );
  234. PCWSTR
  235. SelectHiveW (
  236. IN PCWSTR FullKeyStr
  237. );
  238. BYTE
  239. GetCurrentDatabaseIndex (
  240. VOID
  241. );
  242. #ifdef DEBUG
  243. BOOL
  244. CheckDatabase (
  245. IN UINT Level
  246. );
  247. #endif
  248. //
  249. // offsetbuf.c
  250. //
  251. VOID
  252. RedirectKeyIndex (
  253. IN UINT Index,
  254. IN UINT TargetIndex
  255. );
  256. UINT
  257. KeyIndexToOffset (
  258. IN UINT Index
  259. );
  260. UINT
  261. AddKeyOffsetToBuffer(
  262. IN UINT Offset
  263. );
  264. VOID
  265. RemoveKeyOffsetFromBuffer(
  266. IN UINT Index
  267. );
  268. VOID
  269. MarkIndexList (
  270. PUINT IndexList,
  271. UINT IndexListSize
  272. );
  273. BOOL
  274. ReadOffsetBlock (
  275. OUT PGROWBUFFER pOffsetBuffer,
  276. IN OUT PBYTE *Buf
  277. );
  278. BOOL
  279. WriteOffsetBlock (
  280. IN PGROWBUFFER pOffsetBuffer,
  281. IN OUT PBYTE *Buf
  282. );
  283. UINT GetOffsetBufferBlockSize (
  284. IN PGROWBUFFER pOffsetBuffer
  285. );
  286. //
  287. // pastring.c
  288. // Pascal-style string: wide characters, first char
  289. // is number of characters, no null-termination
  290. //
  291. typedef WCHAR * PPASTR;
  292. typedef WCHAR const * PCPASTR;
  293. //
  294. // these convert a WSTR in place from null-terminated
  295. // to Pascal-style strings
  296. //
  297. PPASTR StringPasConvertTo (PWSTR str);
  298. PWSTR StringPasConvertFrom (PPASTR str);
  299. //
  300. // these convert a WSTR from null-terminated
  301. // to Pascal-style strings in new string buffer
  302. //
  303. PPASTR StringPasCopyConvertTo (PPASTR str1, PCWSTR str2);
  304. PWSTR StringPasCopyConvertFrom (PWSTR str1, PCPASTR str2);
  305. PPASTR StringPasCopy (PPASTR str1, PCPASTR str2);
  306. UINT StringPasCharCount (PCPASTR str);
  307. INT StringPasCompare (PCPASTR str1, PCPASTR str2);
  308. BOOL StringPasMatch (PCPASTR str1, PCPASTR str2);
  309. INT StringPasICompare (PCPASTR str1, PCPASTR str2);
  310. BOOL StringPasIMatch (PCPASTR str1, PCPASTR str2);
  311. //
  312. // keystrct.c
  313. //
  314. #ifdef DEBUG
  315. PKEYSTRUCT
  316. GetKeyStructFromOffset (
  317. UINT Offset
  318. );
  319. PKEYSTRUCT
  320. GetKeyStruct (
  321. UINT Index
  322. );
  323. #else
  324. #define GetKeyStructFromOffset(Offset) ((Offset==INVALID_OFFSET) ? \
  325. NULL : \
  326. (PKEYSTRUCT)OFFSET_TO_PTR(Offset))
  327. #define GetKeyStruct(Index) ((Index==INVALID_OFFSET) ? \
  328. NULL : \
  329. GetKeyStructFromOffset(KeyIndexToOffset(Index)))
  330. #endif
  331. UINT
  332. GetFirstIndex (
  333. IN UINT TreeOffset,
  334. OUT PUINT pTreeEnum
  335. );
  336. UINT
  337. GetNextIndex (
  338. IN OUT PUINT pTreeEnum
  339. );
  340. UINT
  341. NewKey (
  342. IN PCWSTR KeyStr
  343. );
  344. UINT
  345. NewEmptyKey (
  346. IN PCWSTR KeyStr
  347. );
  348. BOOL
  349. PrivateDeleteKeyByIndex (
  350. IN UINT Index
  351. );
  352. BOOL
  353. DeleteKey (
  354. IN PCWSTR KeyStr,
  355. IN UINT TreeOffset,
  356. IN BOOL MustMatch
  357. );
  358. BOOL
  359. PrivateBuildKeyFromIndex (
  360. IN UINT StartLevel, // zero-based
  361. IN UINT TailIndex,
  362. OUT PWSTR Buffer, OPTIONAL
  363. OUT PUINT ValPtr, OPTIONAL
  364. OUT PUINT UserFlagsPtr, OPTIONAL
  365. OUT PUINT SizeInChars OPTIONAL
  366. );
  367. BOOL
  368. KeyStructSetInsertionOrdered (
  369. IN PKEYSTRUCT Key
  370. );
  371. UINT KeyStructGetChildCount (
  372. IN PKEYSTRUCT pKey
  373. );
  374. UINT
  375. FindKeyStructInTree (
  376. IN UINT TreeOffset,
  377. IN PWSTR KeyName,
  378. IN BOOL IsPascalString
  379. );
  380. #ifdef DEBUG
  381. BOOL
  382. CheckLevel(UINT TreeOffset,
  383. UINT PrevLevelIndex
  384. );
  385. #endif
  386. //
  387. // keyfind.c
  388. //
  389. UINT
  390. FindKeyStruct(
  391. IN PCWSTR Key
  392. );
  393. UINT
  394. FindKey (
  395. IN PCWSTR FullKeyPath
  396. );
  397. UINT
  398. FindKeyStructUsingTreeOffset (
  399. IN UINT TreeOffset,
  400. IN OUT PUINT pTreeEnum,
  401. IN PCWSTR KeyStr
  402. );
  403. #ifdef DEBUG
  404. BOOL
  405. FindKeyStructInDatabase(
  406. UINT KeyOffset
  407. );
  408. #endif
  409. //
  410. // keydata.c
  411. //
  412. BOOL
  413. KeyStructSetValue (
  414. IN UINT KeyIndex,
  415. IN UINT Value
  416. );
  417. BOOL
  418. KeyStructSetFlags (
  419. IN UINT KeyIndex,
  420. IN BOOL ReplaceFlags,
  421. IN UINT SetFlags,
  422. IN UINT ClearFlags
  423. );
  424. UINT
  425. KeyStructAddBinaryData (
  426. IN UINT KeyIndex,
  427. IN BYTE Type,
  428. IN BYTE Instance,
  429. IN PCBYTE Data,
  430. IN UINT DataSize
  431. );
  432. UINT
  433. KeyStructGrowBinaryData (
  434. IN UINT KeyIndex,
  435. IN BYTE Type,
  436. IN BYTE Instance,
  437. IN PCBYTE Data,
  438. IN UINT DataSize
  439. );
  440. UINT
  441. KeyStructGrowBinaryDataByIndex (
  442. IN UINT OldIndex,
  443. IN PCBYTE Data,
  444. IN UINT DataSize
  445. );
  446. BOOL
  447. KeyStructDeleteBinaryData (
  448. IN UINT KeyIndex,
  449. IN BYTE Type,
  450. IN BYTE Instance
  451. );
  452. BOOL
  453. KeyStructDeleteBinaryDataByIndex (
  454. IN UINT DataIndex
  455. );
  456. UINT
  457. KeyStructReplaceBinaryDataByIndex (
  458. IN UINT OldIndex,
  459. IN PCBYTE Data,
  460. IN UINT DataSize
  461. );
  462. PBYTE
  463. KeyStructGetBinaryData (
  464. IN UINT KeyIndex,
  465. IN BYTE Type,
  466. IN BYTE Instance,
  467. OUT PUINT DataSize,
  468. OUT PUINT DataIndex //OPTIONAL
  469. );
  470. PBYTE
  471. KeyStructGetBinaryDataByIndex (
  472. IN UINT DataIndex,
  473. OUT PUINT DataSize
  474. );
  475. UINT
  476. KeyStructGetDataIndex (
  477. IN UINT KeyIndex,
  478. IN BYTE Type,
  479. IN BYTE Instance
  480. );
  481. DATAHANDLE
  482. KeyStructAddLinkage (
  483. IN UINT KeyIndex,
  484. IN BYTE Type,
  485. IN BYTE Instance,
  486. IN UINT Linkage,
  487. IN BOOL AllowDuplicates
  488. );
  489. DATAHANDLE
  490. KeyStructAddLinkageByIndex (
  491. IN UINT DataIndex,
  492. IN UINT Linkage,
  493. IN BOOL AllowDuplicates
  494. );
  495. BOOL
  496. KeyStructDeleteLinkage (
  497. IN UINT KeyIndex,
  498. IN BYTE Type,
  499. IN BYTE Instance,
  500. IN UINT Linkage,
  501. IN BOOL FirstOnly
  502. );
  503. BOOL
  504. KeyStructDeleteLinkageByIndex (
  505. IN UINT DataIndex,
  506. IN UINT Linkage,
  507. IN BOOL FirstOnly
  508. );
  509. BOOL
  510. KeyStructTestLinkage (
  511. IN UINT KeyIndex,
  512. IN BYTE Type,
  513. IN BYTE Instance,
  514. IN KEYHANDLE Linkage
  515. );
  516. BOOL
  517. KeyStructTestLinkageByIndex (
  518. IN UINT DataIndex,
  519. IN UINT Linkage
  520. );
  521. BOOL
  522. KeyStructGetValue (
  523. IN PKEYSTRUCT KeyStruct,
  524. OUT PUINT Value
  525. );
  526. BOOL
  527. KeyStructGetFlags (
  528. IN PKEYSTRUCT KeyStruct,
  529. OUT PUINT Flags
  530. );
  531. VOID
  532. KeyStructFreeAllData (
  533. PKEYSTRUCT KeyStruct
  534. );
  535. //
  536. // bintree.c
  537. //
  538. #ifdef DEBUG
  539. //
  540. // violating code hiding for easier debugging.
  541. // (only database.c should see bintree functions)
  542. //
  543. UINT
  544. BinTreeGetSizeOfStruct(
  545. DWORD Signature
  546. );
  547. BOOL
  548. BinTreeFindStructInDatabase(
  549. DWORD Sig,
  550. UINT Offset
  551. );
  552. #endif