Leaked source code of windows server 2003
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.

695 lines
15 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. memdbex.c
  5. Abstract:
  6. Extensions to use the memdb tree like a relational database
  7. Author:
  8. Jim Schmidt (jimschm) 2-Dec-1996
  9. Revision History:
  10. jimschm 23-Sep-1998 Expanded user flags to 24 bits (from
  11. 12 bits), removed AnsiFromUnicode
  12. jimschm 21-Oct-1997 Cleaned up a little
  13. marcw 09-Apr-1997 Added MemDbGetOffset* functions.
  14. jimschm 17-Jan-1997 All string params can be NULL now
  15. jimschm 18-Dec-1996 Added GetEndpointValue functions
  16. --*/
  17. #include "pch.h"
  18. #include "memdbp.h"
  19. VOID
  20. MemDbBuildKeyA (
  21. OUT PSTR Buffer,
  22. IN PCSTR Category,
  23. IN PCSTR Item,
  24. IN PCSTR Field,
  25. IN PCSTR Data
  26. )
  27. {
  28. PSTR p;
  29. static CHAR Wack[] = "\\";
  30. p = Buffer;
  31. *p = 0;
  32. if (Category)
  33. p = _mbsappend (p, Category);
  34. if (Item) {
  35. if (p != Buffer)
  36. p = _mbsappend (p, Wack);
  37. p = _mbsappend (p, Item);
  38. }
  39. if (Field) {
  40. if (p != Buffer)
  41. p = _mbsappend (p, Wack);
  42. p = _mbsappend (p, Field);
  43. }
  44. if (Data) {
  45. if (p != Buffer)
  46. p = _mbsappend (p, Wack);
  47. p = _mbsappend (p, Data);
  48. }
  49. }
  50. VOID
  51. MemDbBuildKeyW (
  52. OUT PWSTR Buffer,
  53. IN PCWSTR Category,
  54. IN PCWSTR Item,
  55. IN PCWSTR Field,
  56. IN PCWSTR Data
  57. )
  58. {
  59. PWSTR p;
  60. static WCHAR Wack[] = L"\\";
  61. p = Buffer;
  62. *p = 0;
  63. if (Category)
  64. p = _wcsappend (p, Category);
  65. if (Item) {
  66. if (p != Buffer)
  67. p = _wcsappend (p, Wack);
  68. p = _wcsappend (p, Item);
  69. }
  70. if (Field) {
  71. if (p != Buffer)
  72. p = _wcsappend (p, Wack);
  73. p = _wcsappend (p, Field);
  74. }
  75. if (Data) {
  76. if (p != Buffer)
  77. p = _wcsappend (p, Wack);
  78. p = _wcsappend (p, Data);
  79. }
  80. }
  81. BOOL
  82. MemDbSetValueExA (
  83. IN PCSTR Category,
  84. IN PCSTR Item, OPTIONAL
  85. IN PCSTR Field, OPTIONAL
  86. IN PCSTR Data, OPTIONAL
  87. IN DWORD Val,
  88. OUT PDWORD Offset OPTIONAL
  89. )
  90. {
  91. CHAR Key[MEMDB_MAX];
  92. MemDbBuildKeyA (Key, Category, Item, Field, Data);
  93. return PrivateMemDbSetValueA (Key, Val, 0, 0, Offset);
  94. }
  95. BOOL
  96. MemDbSetValueExW (
  97. IN PCWSTR Category,
  98. IN PCWSTR Item, OPTIONAL
  99. IN PCWSTR Field, OPTIONAL
  100. IN PCWSTR Data, OPTIONAL
  101. IN DWORD Val,
  102. OUT PDWORD Offset OPTIONAL
  103. )
  104. {
  105. WCHAR Key[MEMDB_MAX];
  106. MemDbBuildKeyW (Key, Category, Item, Field, Data);
  107. return PrivateMemDbSetValueW (Key, Val, 0, 0, Offset);
  108. }
  109. BOOL
  110. MemDbSetBinaryValueExA (
  111. IN PCSTR Category,
  112. IN PCSTR Item, OPTIONAL
  113. IN PCSTR Field, OPTIONAL
  114. IN PCBYTE BinaryData,
  115. IN DWORD DataSize,
  116. OUT PDWORD Offset OPTIONAL
  117. )
  118. {
  119. CHAR Key[MEMDB_MAX];
  120. MemDbBuildKeyA (Key, Category, Item, Field, NULL);
  121. return PrivateMemDbSetBinaryValueA (Key, BinaryData, DataSize, Offset);
  122. }
  123. BOOL
  124. MemDbSetBinaryValueExW (
  125. IN PCWSTR Category,
  126. IN PCWSTR Item, OPTIONAL
  127. IN PCWSTR Field, OPTIONAL
  128. IN PCBYTE BinaryData,
  129. IN DWORD DataSize,
  130. OUT PDWORD Offset OPTIONAL
  131. )
  132. {
  133. WCHAR Key[MEMDB_MAX];
  134. MemDbBuildKeyW (Key, Category, Item, Field, NULL);
  135. return PrivateMemDbSetBinaryValueW (Key, BinaryData, DataSize, Offset);
  136. }
  137. /*++
  138. Routine Description:
  139. MemDbBuildKeyFromOffset and MemDbBuildKeyFromOffsetEx create a key
  140. string given the offset to the key, copying the string into the
  141. supplied buffer. If a value pointer or user flag pointer is
  142. provided, it is filled with the value or flag stored at the offset.
  143. These functions also allow trimming from the beginning of the string.
  144. By specifying a start level, the function will skip a number of
  145. levels before building the string. For example, if an offset points
  146. to the string mycat\foo\bar, and StartLevel is 1, the function will
  147. return foo\bar in Buffer.
  148. Arguments:
  149. Offset - Specifies the offset to the key as returned by MemDbSetValueEx.
  150. Buffer - Specifies a MEMDB_MAX buffer.
  151. StartLevel - Specifies a zero-based starting level, where zero represents
  152. the complete string, one represents the string starting after
  153. the first backslash, and so on.
  154. ValPtr - Specifies a variable that receives the value stored for the key
  155. Return Value:
  156. TRUE if the offset is valid and the function completed successfully, or
  157. FALSE if the offset is not valid or an internal memory corruption was detected.
  158. --*/
  159. BOOL
  160. MemDbBuildKeyFromOffsetA (
  161. IN DWORD Offset,
  162. OUT PSTR Buffer, OPTIONAL
  163. IN DWORD StartLevel,
  164. OUT PDWORD ValPtr OPTIONAL
  165. )
  166. {
  167. WCHAR WideBuffer[MEMDB_MAX];
  168. BOOL b;
  169. b = MemDbBuildKeyFromOffsetW (
  170. Offset,
  171. WideBuffer,
  172. StartLevel,
  173. ValPtr
  174. );
  175. if (b) {
  176. KnownSizeWtoA (Buffer, WideBuffer);
  177. }
  178. return b;
  179. }
  180. BOOL
  181. MemDbBuildKeyFromOffsetW (
  182. IN DWORD Offset,
  183. OUT PWSTR Buffer, OPTIONAL
  184. IN DWORD StartLevel,
  185. OUT PDWORD ValPtr OPTIONAL
  186. )
  187. {
  188. return MemDbBuildKeyFromOffsetExW (
  189. Offset,
  190. Buffer,
  191. NULL,
  192. StartLevel,
  193. ValPtr,
  194. NULL
  195. );
  196. }
  197. /*++
  198. Routine Description:
  199. MemDbBuildKeyFromOffset and MemDbBuildKeyFromOffsetEx create a key
  200. string given the offset to the key, copying the string into the
  201. supplied buffer. If a value pointer or user flag pointer is
  202. provided, it is filled with the value or flag stored at the offset.
  203. These functions also allow trimming from the beginning of the string.
  204. By specifying a start level, the function will skip a number of
  205. levels before building the string. For example, if an offset points
  206. to the string mycat\foo\bar, and StartLevel is 1, the function will
  207. return foo\bar in Buffer.
  208. Arguments:
  209. Offset - Specifies the offset to the key as returned by MemDbSetValueEx.
  210. Buffer - Specifies a MEMDB_MAX buffer.
  211. BufferLen - Receives the length of the string in characters, excluding the
  212. terminating nul. If caller is using this for buffer allocation
  213. size, double BufferLen.
  214. StartLevel - Specifies a zero-based starting level, where zero represents
  215. the complete string, one represents the string starting after
  216. the first backslash, and so on.
  217. ValPtr - Specifies a variable that receives the value stored for the key
  218. UserFlagPtr - Specifies a variable that receives the user flags stored for the
  219. key
  220. Return Value:
  221. TRUE if the offset is valid and the function completed successfully, or
  222. FALSE if the offset is not valid or an internal memory corruption was detected.
  223. --*/
  224. BOOL
  225. MemDbBuildKeyFromOffsetExA (
  226. IN DWORD Offset,
  227. OUT PSTR Buffer, OPTIONAL
  228. OUT PDWORD BufferLen, OPTIONAL
  229. IN DWORD StartLevel,
  230. OUT PDWORD ValPtr, OPTIONAL
  231. OUT PDWORD UserFlagPtr OPTIONAL
  232. )
  233. {
  234. WCHAR WideBuffer[MEMDB_MAX];
  235. BOOL b;
  236. b = MemDbBuildKeyFromOffsetExW (
  237. Offset,
  238. WideBuffer,
  239. BufferLen,
  240. StartLevel,
  241. ValPtr,
  242. UserFlagPtr
  243. );
  244. if (b) {
  245. KnownSizeWtoA (Buffer, WideBuffer);
  246. }
  247. return b;
  248. }
  249. BOOL
  250. MemDbBuildKeyFromOffsetExW (
  251. IN DWORD Offset,
  252. OUT PWSTR Buffer, OPTIONAL
  253. OUT PDWORD BufferLen, OPTIONAL
  254. IN DWORD StartLevel,
  255. OUT PDWORD ValPtr, OPTIONAL
  256. OUT PDWORD UserFlagPtr OPTIONAL
  257. )
  258. {
  259. PWSTR p,s;
  260. BYTE newDb = (BYTE) (Offset >> RESERVED_BITS);
  261. if (Offset == INVALID_OFFSET) {
  262. return FALSE;
  263. }
  264. SelectDatabase (newDb);
  265. p = Buffer;
  266. if (newDb != 0) {
  267. if (StartLevel == 0) {
  268. if (Buffer) {
  269. s = g_db->Hive;
  270. while (*s) {
  271. *p++ = *s++;
  272. }
  273. *p++ = L'\\';
  274. }
  275. }
  276. else {
  277. StartLevel --;
  278. }
  279. }
  280. return PrivateBuildKeyFromOffset (
  281. StartLevel,
  282. Offset & OFFSET_MASK,
  283. p,
  284. ValPtr,
  285. UserFlagPtr,
  286. BufferLen
  287. );
  288. }
  289. BOOL
  290. MemDbEnumItemsA (
  291. OUT PMEMDB_ENUMA pEnum,
  292. IN PCSTR Category
  293. )
  294. {
  295. CHAR Pattern[MEMDB_MAX];
  296. if (!Category)
  297. return FALSE;
  298. wsprintfA (Pattern, "%s\\*", Category);
  299. return MemDbEnumFirstValueA (pEnum, Pattern, MEMDB_THIS_LEVEL_ONLY, NO_FLAGS);
  300. }
  301. BOOL
  302. MemDbEnumItemsW (
  303. OUT PMEMDB_ENUMW pEnum,
  304. IN PCWSTR Category
  305. )
  306. {
  307. WCHAR Pattern[MEMDB_MAX];
  308. if (!Category)
  309. return FALSE;
  310. wsprintfW (Pattern, L"%s\\*", Category);
  311. return MemDbEnumFirstValueW (pEnum, Pattern, MEMDB_THIS_LEVEL_ONLY, NO_FLAGS);
  312. }
  313. BOOL
  314. MemDbEnumFieldsA (
  315. OUT PMEMDB_ENUMA pEnum,
  316. IN PCSTR Category,
  317. IN PCSTR Item OPTIONAL
  318. )
  319. {
  320. CHAR Pattern[MEMDB_MAX];
  321. if (!Category)
  322. return MemDbEnumItemsA (pEnum, Item);
  323. if (!Item)
  324. return MemDbEnumItemsA (pEnum, Category);
  325. wsprintfA (Pattern, "%s\\%s\\*", Category, Item);
  326. return MemDbEnumFirstValueA (pEnum, Pattern, MEMDB_THIS_LEVEL_ONLY, NO_FLAGS);
  327. }
  328. BOOL
  329. MemDbEnumFieldsW (
  330. OUT PMEMDB_ENUMW pEnum,
  331. IN PCWSTR Category,
  332. IN PCWSTR Item OPTIONAL
  333. )
  334. {
  335. WCHAR Pattern[MEMDB_MAX];
  336. if (!Category)
  337. return MemDbEnumItemsW (pEnum, Item);
  338. if (!Item)
  339. return MemDbEnumItemsW (pEnum, Category);
  340. wsprintfW (Pattern, L"%s\\%s\\*", Category, Item);
  341. return MemDbEnumFirstValueW (pEnum, Pattern, MEMDB_THIS_LEVEL_ONLY, NO_FLAGS);
  342. }
  343. BOOL
  344. MemDbGetValueExA (
  345. OUT PMEMDB_ENUMA pEnum,
  346. IN PCSTR Category,
  347. IN PCSTR Item, OPTIONAL
  348. IN PCSTR Field OPTIONAL
  349. )
  350. {
  351. CHAR Pattern[MEMDB_MAX];
  352. MemDbBuildKeyA (Pattern, Category, Item, Field, NULL);
  353. if (*Pattern) {
  354. AppendWackA (Pattern);
  355. }
  356. StringCatA (Pattern, "*");
  357. return MemDbEnumFirstValueA (pEnum, Pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY);
  358. }
  359. BOOL
  360. MemDbGetValueExW (
  361. OUT PMEMDB_ENUMW pEnum,
  362. IN PCWSTR Category,
  363. IN PCWSTR Item, OPTIONAL
  364. IN PCWSTR Field OPTIONAL
  365. )
  366. {
  367. WCHAR Pattern[MEMDB_MAX];
  368. MemDbBuildKeyW (Pattern, Category, Item, Field, NULL);
  369. if (*Pattern) {
  370. AppendWackW (Pattern);
  371. }
  372. StringCatW (Pattern, L"*");
  373. return MemDbEnumFirstValueW (pEnum, Pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY);
  374. }
  375. BOOL
  376. MemDbGetEndpointValueA (
  377. IN PCSTR Pattern,
  378. IN PCSTR Item, OPTIONAL // used as the first variable arg to wsprintfA
  379. OUT PSTR Buffer
  380. )
  381. {
  382. CHAR Path[MEMDB_MAX];
  383. MEMDB_ENUMA memdb_enum;
  384. if (!Pattern) {
  385. if (!Item)
  386. return FALSE;
  387. StringCopyA (Path, Item);
  388. }
  389. else {
  390. if (!Item)
  391. StringCopyA (Path, Pattern);
  392. else
  393. wsprintfA (Path, Pattern, Item);
  394. }
  395. if (!MemDbEnumFirstValueA (&memdb_enum, Path,
  396. MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  397. Buffer[0] = 0;
  398. return FALSE;
  399. }
  400. StringCopyA (Buffer, memdb_enum.szName);
  401. return TRUE;
  402. }
  403. BOOL
  404. MemDbGetEndpointValueW (
  405. IN PCWSTR Pattern,
  406. IN PCWSTR Item, OPTIONAL
  407. OUT PWSTR Buffer
  408. )
  409. {
  410. WCHAR Path[MEMDB_MAX];
  411. MEMDB_ENUMW memdb_enum;
  412. if (!Pattern) {
  413. if (!Item)
  414. return FALSE;
  415. StringCopyW (Path, Item);
  416. }
  417. else {
  418. if (!Item)
  419. StringCopyW (Path, Pattern);
  420. else
  421. wsprintfW (Path, Pattern, Item);
  422. }
  423. if (!MemDbEnumFirstValueW (&memdb_enum, Path,
  424. MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  425. Buffer[0] = 0;
  426. return FALSE;
  427. }
  428. StringCopyW (Buffer, memdb_enum.szName);
  429. return TRUE;
  430. }
  431. BOOL
  432. MemDbGetEndpointValueExA (
  433. IN PCSTR Category,
  434. IN PCSTR Item, OPTIONAL
  435. IN PCSTR Field, OPTIONAL
  436. OUT PSTR Buffer
  437. )
  438. {
  439. CHAR Path[MEMDB_MAX];
  440. MEMDB_ENUMA memdb_enum;
  441. MemDbBuildKeyA (Path, Category, Item, Field, NULL);
  442. if (*Path) {
  443. AppendWackA (Path);
  444. }
  445. StringCatA (Path, "*");
  446. if (!MemDbEnumFirstValueA (&memdb_enum, Path,
  447. MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  448. Buffer[0] = 0;
  449. return FALSE;
  450. }
  451. strcpy (Buffer, memdb_enum.szName);
  452. return TRUE;
  453. }
  454. BOOL
  455. MemDbGetEndpointValueExW (
  456. IN PCWSTR Category,
  457. IN PCWSTR Item, OPTIONAL
  458. IN PCWSTR Field, OPTIONAL
  459. OUT PWSTR Buffer
  460. )
  461. {
  462. WCHAR Path[MEMDB_MAX];
  463. MEMDB_ENUMW memdb_enum;
  464. MemDbBuildKeyW (Path, Category, Item, Field, NULL);
  465. if (*Path) {
  466. AppendWackW (Path);
  467. }
  468. StringCatW (Path, L"*");
  469. if (!MemDbEnumFirstValueW (&memdb_enum, Path,
  470. MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  471. Buffer[0] = 0;
  472. return FALSE;
  473. }
  474. StringCopyW (Buffer, memdb_enum.szName);
  475. return TRUE;
  476. }
  477. BOOL
  478. MemDbGetOffsetW(
  479. IN PCWSTR Key,
  480. OUT PDWORD Offset
  481. )
  482. {
  483. BOOL b;
  484. DWORD keyOffset;
  485. keyOffset = FindKey (Key);
  486. if (keyOffset == INVALID_OFFSET) {
  487. b = FALSE;
  488. }
  489. else {
  490. b = TRUE;
  491. *Offset = keyOffset;
  492. }
  493. return b;
  494. }
  495. BOOL
  496. MemDbGetOffsetA (
  497. IN PCSTR Key,
  498. OUT PDWORD Offset
  499. )
  500. {
  501. PCWSTR wstr;
  502. BOOL b;
  503. wstr = ConvertAtoW (Key);
  504. if (wstr) {
  505. b = MemDbGetOffsetW (wstr,Offset);
  506. FreeConvertedStr (wstr);
  507. }
  508. else {
  509. b = FALSE;
  510. }
  511. return b;
  512. }
  513. BOOL
  514. MemDbGetOffsetExW (
  515. IN PCWSTR Category,
  516. IN PCWSTR Item, OPTIONAL
  517. IN PCWSTR Field, OPTIONAL
  518. IN PCWSTR Data, OPTIONAL
  519. OUT PDWORD Offset OPTIONAL
  520. )
  521. {
  522. WCHAR Key[MEMDB_MAX];
  523. MemDbBuildKeyW(Key,Category,Item,Field,Data);
  524. return MemDbGetOffsetW(Key,Offset);
  525. }
  526. BOOL
  527. MemDbGetOffsetExA (
  528. IN PCSTR Category,
  529. IN PCSTR Item, OPTIONAL
  530. IN PCSTR Field, OPTIONAL
  531. IN PCSTR Data, OPTIONAL
  532. OUT PDWORD Offset OPTIONAL
  533. )
  534. {
  535. CHAR Key[MEMDB_MAX];
  536. MemDbBuildKeyA(Key,Category,Item,Field,Data);
  537. return MemDbGetOffsetA(Key,Offset);
  538. }