174 lines
3.6 KiB
C
174 lines
3.6 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1995 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
dllreg.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module implements POSIX registry APIs
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Matthew Bradburn (mattbr) 13-Dec-1995
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <sys\utsname.h>
|
||
|
#include <unistd.h>
|
||
|
#include <string.h>
|
||
|
#include <stdarg.h>
|
||
|
#include "psxdll.h"
|
||
|
|
||
|
|
||
|
//
|
||
|
// First guess for value size.
|
||
|
//
|
||
|
|
||
|
#define KEY_WORK_AREA 256
|
||
|
|
||
|
int
|
||
|
__cdecl
|
||
|
getreg(char *path, int *type, void *data, size_t *size)
|
||
|
{
|
||
|
NTSTATUS Status;
|
||
|
UNICODE_STRING Key_U, Value_U;
|
||
|
ANSI_STRING Key_A, Value_A;
|
||
|
OBJECT_ATTRIBUTES ObjA;
|
||
|
HANDLE hKey = NULL;
|
||
|
CHAR *pch;
|
||
|
PKEY_VALUE_PARTIAL_INFORMATION pInfo = NULL;
|
||
|
UCHAR Buffer[KEY_WORK_AREA];
|
||
|
ULONG RequestLength, ResultLength;
|
||
|
int r = 0;
|
||
|
|
||
|
Key_U.Buffer = NULL;
|
||
|
Value_U.Buffer = NULL;
|
||
|
|
||
|
if (strlen(path) > PATH_MAX) {
|
||
|
errno = ENAMETOOLONG;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Split the path into key and value.
|
||
|
//
|
||
|
|
||
|
pch = strrchr(path, '\\');
|
||
|
if (NULL == pch) {
|
||
|
errno = ENOENT;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
Value_A.Buffer = pch + 1;
|
||
|
Value_A.Length = (USHORT)strlen(Value_A.Buffer);
|
||
|
Value_A.MaximumLength = Value_A.Length + 1;
|
||
|
|
||
|
Key_A.Buffer = path;
|
||
|
Key_A.Length = (USHORT)(pch - path);
|
||
|
Key_A.MaximumLength = Key_A.Length + 1;
|
||
|
|
||
|
Status = RtlAnsiStringToUnicodeString(&Key_U, &Key_A, TRUE);
|
||
|
if (!NT_SUCCESS(Status)) {
|
||
|
errno = PdxStatusToErrno(Status);
|
||
|
r = -1;
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
Status = RtlAnsiStringToUnicodeString(&Value_U, &Value_A, TRUE);
|
||
|
if (!NT_SUCCESS(Status)) {
|
||
|
errno = PdxStatusToErrno(Status);
|
||
|
r = -1;
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
InitializeObjectAttributes(&ObjA, &Key_U, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||
|
|
||
|
Status = NtOpenKey(&hKey, KEY_READ, &ObjA);
|
||
|
if (!NT_SUCCESS(Status)) {
|
||
|
KdPrint(("PSXDLL: NtOpenKey: 0x%x\n", Status));
|
||
|
errno = PdxStatusToErrno(Status);
|
||
|
r = -1;
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
RequestLength = KEY_WORK_AREA;
|
||
|
pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
|
||
|
|
||
|
for (;;) {
|
||
|
|
||
|
Status = NtQueryValueKey(hKey, &Value_U, KeyValuePartialInformation,
|
||
|
(PVOID)pInfo, RequestLength, &ResultLength);
|
||
|
|
||
|
if (Status == STATUS_BUFFER_OVERFLOW) {
|
||
|
|
||
|
//
|
||
|
// Try to get a bigger buffer.
|
||
|
//
|
||
|
|
||
|
if (pInfo != (PKEY_VALUE_PARTIAL_INFORMATION)Buffer) {
|
||
|
|
||
|
RtlFreeHeap(PdxHeap, 0, pInfo);
|
||
|
}
|
||
|
|
||
|
RequestLength += 512;
|
||
|
pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)
|
||
|
RtlAllocateHeap(PdxHeap, 0, RequestLength);
|
||
|
|
||
|
if (NULL == pInfo) {
|
||
|
errno = ENOMEM;
|
||
|
r = -1;
|
||
|
goto out;
|
||
|
}
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!NT_SUCCESS(Status)) {
|
||
|
|
||
|
r = -1;
|
||
|
errno = PdxStatusToErrno(Status);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
if (pInfo->DataLength > *size) {
|
||
|
*size = pInfo->DataLength;
|
||
|
*type = 0;
|
||
|
errno = E2BIG;
|
||
|
r = -1;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
*size = pInfo->DataLength;
|
||
|
*type = pInfo->Type;
|
||
|
memcpy(data, pInfo->Data, pInfo->DataLength);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
out:
|
||
|
|
||
|
if (pInfo != NULL && pInfo != (PKEY_VALUE_PARTIAL_INFORMATION)Buffer) {
|
||
|
RtlFreeHeap(PdxHeap, 0, pInfo);
|
||
|
}
|
||
|
|
||
|
if (Key_U.Buffer != NULL) {
|
||
|
RtlFreeUnicodeString(&Key_U);
|
||
|
}
|
||
|
if (Value_U.Buffer != NULL) {
|
||
|
RtlFreeUnicodeString(&Value_U);
|
||
|
}
|
||
|
if (hKey != NULL) {
|
||
|
NtClose(hKey);
|
||
|
}
|
||
|
if (pInfo != NULL) {
|
||
|
RtlFreeHeap(PdxHeap, 0, (PVOID)pInfo);
|
||
|
}
|
||
|
|
||
|
return r;
|
||
|
}
|