1
0
mirror of https://github.com/UzixLS/KernelEx.git synced 2025-07-18 23:11:19 +03:00
Files
KernelEx/apilibs/kexbases/Advapi32/uniadvapi32.c
2018-11-03 16:20:02 +03:00

114 lines
3.1 KiB
C

/*
* KernelEx
* Copyright (C) 2008, Xeno86
*
* This file is part of KernelEx source code.
*
* KernelEx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; version 2 of the License.
*
* KernelEx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "common.h"
//MAKE_EXPORT RegQueryValueExW_new=RegQueryValueExW
LONG WINAPI RegQueryValueExW_new(HKEY hKey, LPCWSTR lpValueNameW, LPDWORD lpReserved,
LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
{
LONG ret;
DWORD type;
BYTE stackbuf[256];
BYTE* ptr = stackbuf;
BYTE* heapbuf = NULL;
DWORD bufsize = sizeof(stackbuf);
if ((lpData && !lpcbData) || lpReserved) return ERROR_INVALID_PARAMETER;
if (!lpData && lpcbData) *lpcbData = 0;
//try with stack buffer first
if (lpValueNameW)
{
ALLOC_WtoA(lpValueName);
ret = RegQueryValueExA(hKey, lpValueNameA, lpReserved, &type, ptr, &bufsize);
if (lpType) *lpType = type;
if (lpcbData && type != REG_SZ && bufsize > *lpcbData)
{
*lpcbData = bufsize;
return ERROR_MORE_DATA;
}
//retry with dynamic buffer
if (ret == ERROR_MORE_DATA)
{
ptr = heapbuf = (BYTE*) HeapAlloc(GetProcessHeap(), 0, bufsize);
if (!heapbuf)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
ret = RegQueryValueExA(hKey, lpValueNameA, lpReserved, &type, ptr, &bufsize);
}
}
else
{
ret = RegQueryValueExA(hKey, 0, lpReserved, &type, ptr, &bufsize);
if (lpType) *lpType = type;
if (lpcbData && type != REG_SZ && bufsize > *lpcbData)
{
*lpcbData = bufsize;
return ERROR_MORE_DATA;
}
//retry with dynamic buffer
if (ret == ERROR_MORE_DATA)
{
ptr = heapbuf = (BYTE*) HeapAlloc(GetProcessHeap(), 0, bufsize);
if (!heapbuf)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
ret = RegQueryValueExA(hKey, 0, lpReserved, &type, ptr, &bufsize);
}
}
if (ret != ERROR_SUCCESS) goto _end;
if (type == REG_SZ)
{
if (lpcbData)
{
DWORD gle = GetLastError();
int written = MultiByteToWideChar(CP_ACP, 0, (LPSTR) ptr, -1,
(LPWSTR)lpData, lpData ? (*lpcbData >> 1) : 0);
if (!written)
{
ret = GetLastError();
if (ret == ERROR_INSUFFICIENT_BUFFER)
{
*lpcbData = MultiByteToWideChar(CP_ACP, 0, (LPSTR) ptr,
-1, NULL, 0) << 1;
ret = ERROR_MORE_DATA;
}
SetLastError(gle);
goto _end;
}
*lpcbData = written << 1;
}
}
else
{
if (lpData) memcpy(lpData, ptr, bufsize);
if (lpcbData) *lpcbData = bufsize;
}
_end:
if (heapbuf) HeapFree(GetProcessHeap(), 0, heapbuf);
return ret;
}