mirror of
https://github.com/UzixLS/KernelEx.git
synced 2025-07-18 23:11:19 +03:00
114 lines
3.1 KiB
C
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;
|
|
}
|