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.

173 lines
3.6 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. dllreg.c
  5. Abstract:
  6. This module implements POSIX registry APIs
  7. Author:
  8. Matthew Bradburn (mattbr) 13-Dec-1995
  9. Revision History:
  10. --*/
  11. #include <sys\utsname.h>
  12. #include <unistd.h>
  13. #include <string.h>
  14. #include <stdarg.h>
  15. #include "psxdll.h"
  16. //
  17. // First guess for value size.
  18. //
  19. #define KEY_WORK_AREA 256
  20. int
  21. __cdecl
  22. getreg(char *path, int *type, void *data, size_t *size)
  23. {
  24. NTSTATUS Status;
  25. UNICODE_STRING Key_U, Value_U;
  26. ANSI_STRING Key_A, Value_A;
  27. OBJECT_ATTRIBUTES ObjA;
  28. HANDLE hKey = NULL;
  29. CHAR *pch;
  30. PKEY_VALUE_PARTIAL_INFORMATION pInfo = NULL;
  31. UCHAR Buffer[KEY_WORK_AREA];
  32. ULONG RequestLength, ResultLength;
  33. int r = 0;
  34. Key_U.Buffer = NULL;
  35. Value_U.Buffer = NULL;
  36. if (strlen(path) > PATH_MAX) {
  37. errno = ENAMETOOLONG;
  38. return -1;
  39. }
  40. //
  41. // Split the path into key and value.
  42. //
  43. pch = strrchr(path, '\\');
  44. if (NULL == pch) {
  45. errno = ENOENT;
  46. return -1;
  47. }
  48. Value_A.Buffer = pch + 1;
  49. Value_A.Length = (USHORT)strlen(Value_A.Buffer);
  50. Value_A.MaximumLength = Value_A.Length + 1;
  51. Key_A.Buffer = path;
  52. Key_A.Length = (USHORT)(pch - path);
  53. Key_A.MaximumLength = Key_A.Length + 1;
  54. Status = RtlAnsiStringToUnicodeString(&Key_U, &Key_A, TRUE);
  55. if (!NT_SUCCESS(Status)) {
  56. errno = PdxStatusToErrno(Status);
  57. r = -1;
  58. goto out;
  59. }
  60. Status = RtlAnsiStringToUnicodeString(&Value_U, &Value_A, TRUE);
  61. if (!NT_SUCCESS(Status)) {
  62. errno = PdxStatusToErrno(Status);
  63. r = -1;
  64. goto out;
  65. }
  66. InitializeObjectAttributes(&ObjA, &Key_U, OBJ_CASE_INSENSITIVE, NULL, NULL);
  67. Status = NtOpenKey(&hKey, KEY_READ, &ObjA);
  68. if (!NT_SUCCESS(Status)) {
  69. KdPrint(("PSXDLL: NtOpenKey: 0x%x\n", Status));
  70. errno = PdxStatusToErrno(Status);
  71. r = -1;
  72. goto out;
  73. }
  74. RequestLength = KEY_WORK_AREA;
  75. pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
  76. for (;;) {
  77. Status = NtQueryValueKey(hKey, &Value_U, KeyValuePartialInformation,
  78. (PVOID)pInfo, RequestLength, &ResultLength);
  79. if (Status == STATUS_BUFFER_OVERFLOW) {
  80. //
  81. // Try to get a bigger buffer.
  82. //
  83. if (pInfo != (PKEY_VALUE_PARTIAL_INFORMATION)Buffer) {
  84. RtlFreeHeap(PdxHeap, 0, pInfo);
  85. }
  86. RequestLength += 512;
  87. pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)
  88. RtlAllocateHeap(PdxHeap, 0, RequestLength);
  89. if (NULL == pInfo) {
  90. errno = ENOMEM;
  91. r = -1;
  92. goto out;
  93. }
  94. } else {
  95. break;
  96. }
  97. }
  98. if (!NT_SUCCESS(Status)) {
  99. r = -1;
  100. errno = PdxStatusToErrno(Status);
  101. } else {
  102. if (pInfo->DataLength > *size) {
  103. *size = pInfo->DataLength;
  104. *type = 0;
  105. errno = E2BIG;
  106. r = -1;
  107. } else {
  108. *size = pInfo->DataLength;
  109. *type = pInfo->Type;
  110. memcpy(data, pInfo->Data, pInfo->DataLength);
  111. }
  112. }
  113. out:
  114. if (pInfo != NULL && pInfo != (PKEY_VALUE_PARTIAL_INFORMATION)Buffer) {
  115. RtlFreeHeap(PdxHeap, 0, pInfo);
  116. }
  117. if (Key_U.Buffer != NULL) {
  118. RtlFreeUnicodeString(&Key_U);
  119. }
  120. if (Value_U.Buffer != NULL) {
  121. RtlFreeUnicodeString(&Value_U);
  122. }
  123. if (hKey != NULL) {
  124. NtClose(hKey);
  125. }
  126. if (pInfo != NULL) {
  127. RtlFreeHeap(PdxHeap, 0, (PVOID)pInfo);
  128. }
  129. return r;
  130. }