#include <ndk/cmfuncs.h>
#include <pseh/pseh2.h>
+#include "reg.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(reg);
/* DEFINES ******************************************************************/
static NTSTATUS
-OpenClassesRootKey(PHANDLE KeyHandle)
+OpenClassesRootKey(_Out_ PHANDLE KeyHandle)
{
OBJECT_ATTRIBUTES Attributes;
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\CLASSES");
+ NTSTATUS Status;
TRACE("OpenClassesRootKey()\n");
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
- return NtOpenKey(KeyHandle,
- MAXIMUM_ALLOWED,
- &Attributes);
+ Status = NtOpenKey(KeyHandle,
+ MAXIMUM_ALLOWED,
+ &Attributes);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* Mark it as HKCR */
+ MakeHKCRKey((HKEY*)KeyHandle);
+
+ return Status;
}
* @implemented
*/
LONG WINAPI
-RegCreateKeyExA(HKEY hKey,
- LPCSTR lpSubKey,
- DWORD Reserved,
- LPSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition)
+RegCreateKeyExA(
+ _In_ HKEY hKey,
+ _In_ LPCSTR lpSubKey,
+ _In_ DWORD Reserved,
+ _In_ LPSTR lpClass,
+ _In_ DWORD dwOptions,
+ _In_ REGSAM samDesired,
+ _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ _Out_ PHKEY phkResult,
+ _Out_ LPDWORD lpdwDisposition)
{
UNICODE_STRING SubKeyString;
UNICODE_STRING ClassString;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE ParentKey;
- ULONG Attributes = OBJ_CASE_INSENSITIVE;
- NTSTATUS Status;
-
- TRACE("RegCreateKeyExA() called\n");
+ DWORD ErrorCode;
- if (lpSecurityAttributes && lpSecurityAttributes->nLength != sizeof(SECURITY_ATTRIBUTES))
- return ERROR_INVALID_USER_BUFFER;
+ RtlInitEmptyUnicodeString(&ClassString, NULL, 0);
+ RtlInitEmptyUnicodeString(&SubKeyString, NULL, 0);
- /* get the real parent key */
- Status = MapDefaultKey(&ParentKey,
- hKey);
- if (!NT_SUCCESS(Status))
+ if (lpClass)
{
- return RtlNtStatusToDosError(Status);
+ if (!RtlCreateUnicodeStringFromAsciiz(&ClassString, lpClass))
+ {
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ goto Exit;
+ }
}
- TRACE("ParentKey %p\n", ParentKey);
-
- if (lpClass != NULL)
+ if (lpSubKey)
{
- RtlCreateUnicodeStringFromAsciiz(&ClassString,
- lpClass);
+ if (!RtlCreateUnicodeStringFromAsciiz(&SubKeyString, lpSubKey))
+ {
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ goto Exit;
+ }
}
- if (dwOptions & REG_OPTION_OPEN_LINK)
- Attributes |= OBJ_OPENLINK;
+ ErrorCode = RegCreateKeyExW(
+ hKey,
+ SubKeyString.Buffer,
+ Reserved,
+ ClassString.Buffer,
+ dwOptions,
+ samDesired,
+ lpSecurityAttributes,
+ phkResult,
+ lpdwDisposition);
- RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
- (LPSTR)lpSubKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &SubKeyString,
- Attributes,
- (HANDLE)ParentKey,
- lpSecurityAttributes ? (PSECURITY_DESCRIPTOR)lpSecurityAttributes->lpSecurityDescriptor : NULL);
- Status = CreateNestedKey(phkResult,
- &ObjectAttributes,
- (lpClass == NULL)? NULL : &ClassString,
- dwOptions,
- samDesired,
- lpdwDisposition);
+Exit:
RtlFreeUnicodeString(&SubKeyString);
- if (lpClass != NULL)
- {
- RtlFreeUnicodeString(&ClassString);
- }
+ RtlFreeUnicodeString(&ClassString);
- ClosePredefKey(ParentKey);
-
- TRACE("Status %x\n", Status);
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
-
- return ERROR_SUCCESS;
+ return ErrorCode;
}
*
* @implemented
*/
-LONG WINAPI
-RegCreateKeyExW(HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD Reserved,
- LPWSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition)
+LONG
+WINAPI
+RegCreateKeyExW(
+ _In_ HKEY hKey,
+ _In_ LPCWSTR lpSubKey,
+ _In_ DWORD Reserved,
+ _In_opt_ LPWSTR lpClass,
+ _In_ DWORD dwOptions,
+ _In_ REGSAM samDesired,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ _Out_ PHKEY phkResult,
+ _Out_opt_ LPDWORD lpdwDisposition)
{
UNICODE_STRING SubKeyString;
UNICODE_STRING ClassString;
TRACE("ParentKey %p\n", ParentKey);
+ if (IsHKCRKey(ParentKey))
+ {
+ LONG ErrorCode = CreateHKCRKey(
+ ParentKey,
+ lpSubKey,
+ Reserved,
+ lpClass,
+ dwOptions,
+ samDesired,
+ lpSecurityAttributes,
+ phkResult,
+ lpdwDisposition);
+ ClosePredefKey(ParentKey);
+ return ErrorCode;
+ }
+
if (dwOptions & REG_OPTION_OPEN_LINK)
Attributes |= OBJ_OPENLINK;
*
* @implemented
*/
-LONG WINAPI
-RegDeleteKeyA(HKEY hKey,
- LPCSTR lpSubKey)
+LONG
+WINAPI
+RegDeleteKeyA(
+ _In_ HKEY hKey,
+ _In_ LPCSTR lpSubKey)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING SubKeyName;
- HANDLE ParentKey;
- HANDLE TargetKey;
- NTSTATUS Status;
-
- /* Make sure we got a subkey */
- if (!lpSubKey)
- {
- /* Fail */
- return ERROR_INVALID_PARAMETER;
- }
-
- Status = MapDefaultKey(&ParentKey,
- hKey);
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
-
- RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
- (LPSTR)lpSubKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &SubKeyName,
- OBJ_CASE_INSENSITIVE,
- ParentKey,
- NULL);
-
- Status = NtOpenKey(&TargetKey,
- DELETE,
- &ObjectAttributes);
- RtlFreeUnicodeString(&SubKeyName);
- if (!NT_SUCCESS(Status))
- {
- goto Cleanup;
- }
-
- Status = NtDeleteKey(TargetKey);
- NtClose (TargetKey);
-
-Cleanup:
- ClosePredefKey(ParentKey);
-
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
-
- return ERROR_SUCCESS;
+ return RegDeleteKeyExA(hKey, lpSubKey, 0, 0);
}
*
* @implemented
*/
-LONG WINAPI
-RegDeleteKeyW(HKEY hKey,
- LPCWSTR lpSubKey)
+LONG
+WINAPI
+RegDeleteKeyW(
+ _In_ HKEY hKey,
+ _In_ LPCWSTR lpSubKey)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING SubKeyName;
- HANDLE ParentKey;
- HANDLE TargetKey;
- NTSTATUS Status;
-
- /* Make sure we got a subkey */
- if (!lpSubKey)
- {
- /* Fail */
- return ERROR_INVALID_PARAMETER;
- }
-
- Status = MapDefaultKey(&ParentKey,
- hKey);
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
-
- RtlInitUnicodeString(&SubKeyName,
- (LPWSTR)lpSubKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &SubKeyName,
- OBJ_CASE_INSENSITIVE,
- ParentKey,
- NULL);
- Status = NtOpenKey(&TargetKey,
- DELETE,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- goto Cleanup;
- }
-
- Status = NtDeleteKey(TargetKey);
- NtClose(TargetKey);
-
-Cleanup:
- ClosePredefKey(ParentKey);
-
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
-
- return ERROR_SUCCESS;
+ return RegDeleteKeyExW(hKey, lpSubKey, 0, 0);
}
*/
LONG
WINAPI
-RegDeleteKeyExA(HKEY hKey,
- LPCSTR lpSubKey,
- REGSAM samDesired,
- DWORD Reserved)
+RegDeleteKeyExA(
+ _In_ HKEY hKey,
+ _In_ LPCSTR lpSubKey,
+ _In_ REGSAM samDesired,
+ _In_ DWORD Reserved)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
+ LONG ErrorCode;
UNICODE_STRING SubKeyName;
- HANDLE ParentKey;
- HANDLE TargetKey;
- NTSTATUS Status;
-
- /* Make sure we got a subkey */
- if (!lpSubKey)
- {
- /* Fail */
- return ERROR_INVALID_PARAMETER;
- }
- Status = MapDefaultKey(&ParentKey,
- hKey);
- if (!NT_SUCCESS(Status))
+ if (lpSubKey)
{
- return RtlNtStatusToDosError(Status);
+ if (!RtlCreateUnicodeStringFromAsciiz(&SubKeyName, lpSubKey))
+ return ERROR_NOT_ENOUGH_MEMORY;
}
+ else
+ RtlInitEmptyUnicodeString(&SubKeyName, NULL, 0);
- if (samDesired & KEY_WOW64_32KEY)
- ERR("Wow64 not yet supported!\n");
-
- if (samDesired & KEY_WOW64_64KEY)
- ERR("Wow64 not yet supported!\n");
+ ErrorCode = RegDeleteKeyExW(hKey, SubKeyName.Buffer, samDesired, Reserved);
- RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
- (LPSTR)lpSubKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &SubKeyName,
- OBJ_CASE_INSENSITIVE,
- ParentKey,
- NULL);
-
- Status = NtOpenKey(&TargetKey,
- DELETE,
- &ObjectAttributes);
RtlFreeUnicodeString(&SubKeyName);
- if (!NT_SUCCESS(Status))
- {
- goto Cleanup;
- }
- Status = NtDeleteKey(TargetKey);
- NtClose (TargetKey);
-
-Cleanup:
- ClosePredefKey(ParentKey);
-
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
-
- return ERROR_SUCCESS;
+ return ErrorCode;
}
*/
LONG
WINAPI
-RegDeleteKeyExW(HKEY hKey,
- LPCWSTR lpSubKey,
- REGSAM samDesired,
- DWORD Reserved)
+RegDeleteKeyExW(
+ _In_ HKEY hKey,
+ _In_ LPCWSTR lpSubKey,
+ _In_ REGSAM samDesired,
+ _In_ DWORD Reserved)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyName;
return RtlNtStatusToDosError(Status);
}
+ if (IsHKCRKey(ParentKey))
+ return DeleteHKCRKey(ParentKey, lpSubKey, samDesired, Reserved);
+
if (samDesired & KEY_WOW64_32KEY)
ERR("Wow64 not yet supported!\n");
UNICODE_STRING KeyName;
LONG ErrorCode;
- RtlCreateUnicodeStringFromAsciiz(&KeyName,
- (LPSTR)lpSubKey);
- RtlCreateUnicodeStringFromAsciiz(&FileName,
- (LPSTR)lpFile);
+ RtlInitEmptyUnicodeString(&KeyName, NULL, 0);
+ RtlInitEmptyUnicodeString(&FileName, NULL, 0);
+
+ if (lpSubKey)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&KeyName, lpSubKey))
+ {
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ goto Exit;
+ }
+ }
+
+ if (lpFile)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFile))
+ {
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ goto Exit;
+ }
+ }
ErrorCode = RegLoadKeyW(hKey,
KeyName.Buffer,
FileName.Buffer);
+Exit:
RtlFreeUnicodeString(&FileName);
RtlFreeUnicodeString(&KeyName);
* @implemented
*/
LONG WINAPI
-RegOpenKeyExA(HKEY hKey,
- LPCSTR lpSubKey,
- DWORD ulOptions,
- REGSAM samDesired,
- PHKEY phkResult)
+RegOpenKeyExA(
+ _In_ HKEY hKey,
+ _In_ LPCSTR lpSubKey,
+ _In_ DWORD ulOptions,
+ _In_ REGSAM samDesired,
+ _Out_ PHKEY phkResult)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString;
- HANDLE KeyHandle;
- NTSTATUS Status;
- ULONG Attributes = OBJ_CASE_INSENSITIVE;
- LONG ErrorCode = ERROR_SUCCESS;
+ LONG ErrorCode;
TRACE("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
hKey, lpSubKey, ulOptions, samDesired, phkResult);
- if (!phkResult)
- {
- return ERROR_INVALID_PARAMETER;
- }
- Status = MapDefaultKey(&KeyHandle,
- hKey);
- if (!NT_SUCCESS(Status))
+ if (lpSubKey)
{
- return RtlNtStatusToDosError(Status);
+ if (!RtlCreateUnicodeStringFromAsciiz(&SubKeyString, lpSubKey))
+ return ERROR_NOT_ENOUGH_MEMORY;
}
+ else
+ RtlInitEmptyUnicodeString(&SubKeyString, NULL, 0);
- if (ulOptions & REG_OPTION_OPEN_LINK)
- Attributes |= OBJ_OPENLINK;
+ ErrorCode = RegOpenKeyExW(hKey, SubKeyString.Buffer, ulOptions, samDesired, phkResult);
- RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
- (LPSTR)lpSubKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &SubKeyString,
- Attributes,
- KeyHandle,
- NULL);
-
- Status = NtOpenKey((PHANDLE)phkResult,
- samDesired,
- &ObjectAttributes);
RtlFreeUnicodeString(&SubKeyString);
- if (!NT_SUCCESS(Status))
- {
- ErrorCode = RtlNtStatusToDosError(Status);
- }
-
- ClosePredefKey(KeyHandle);
return ErrorCode;
}
return RtlNtStatusToDosError(Status);
}
+ if (IsHKCRKey(KeyHandle))
+ return OpenHKCRKey(KeyHandle, lpSubKey, ulOptions, samDesired, phkResult);
+
if (ulOptions & REG_OPTION_OPEN_LINK)
Attributes |= OBJ_OPENLINK;
Status = NtOpenKey((PHANDLE)phkResult,
samDesired,
&ObjectAttributes);
+
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
}
+
ClosePredefKey(KeyHandle);
return ErrorCode;
*/
LONG
WINAPI
-RegQueryValueExA(HKEY hkeyorg,
- LPCSTR name,
- LPDWORD reserved,
- LPDWORD type,
- LPBYTE data,
- LPDWORD count)
+RegQueryValueExA(
+ _In_ HKEY hkeyorg,
+ _In_ LPCSTR name,
+ _In_ LPDWORD reserved,
+ _Out_opt_ LPDWORD type,
+ _Out_opt_ LPBYTE data,
+ _Inout_opt_ LPDWORD count)
{
- HANDLE hkey;
- NTSTATUS status;
- ANSI_STRING nameA;
UNICODE_STRING nameW;
- DWORD total_size, datalen = 0;
- char buffer[256], *buf_ptr = buffer;
- KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
- static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data );
+ DWORD DataLength;
+ DWORD ErrorCode;
+ DWORD BufferSize = 0;
+ WCHAR* Buffer;
+ CHAR* DataStr = (CHAR*)data;
+ DWORD LocalType;
- TRACE("(%p,%s,%p,%p,%p,%p=%d)\n",
- hkeyorg, debugstr_a(name), reserved, type, data, count, count ? *count : 0 );
+ /* Validate those parameters, the rest will be done with the first RegQueryValueExW call */
+ if ((data && !count) || reserved)
+ return ERROR_INVALID_PARAMETER;
- if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
- status = MapDefaultKey(&hkey, hkeyorg);
- if (!NT_SUCCESS(status))
+ if (name)
{
- return RtlNtStatusToDosError(status);
+ if (!RtlCreateUnicodeStringFromAsciiz(&nameW, name))
+ return ERROR_NOT_ENOUGH_MEMORY;
}
+ else
+ RtlInitEmptyUnicodeString(&nameW, NULL, 0);
- if (count) datalen = *count;
- if (!data && count) *count = 0;
+ ErrorCode = RegQueryValueExW(hkeyorg, nameW.Buffer, NULL, &LocalType, NULL, &BufferSize);
+ if (ErrorCode != ERROR_SUCCESS)
+ {
+ if (!data)
+ *count = 0;
+ RtlFreeUnicodeString(&nameW);
+ return ErrorCode;
+ }
- RtlInitAnsiString( &nameA, name );
- if ((status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE )))
+ /* See if we can directly handle the call without caring for conversion */
+ if (!is_string(LocalType) || !count)
{
- ClosePredefKey(hkey);
- return RtlNtStatusToDosError(status);
+ ErrorCode = RegQueryValueExW(hkeyorg, nameW.Buffer, reserved, type, data, count);
+ RtlFreeUnicodeString(&nameW);
+ return ErrorCode;
}
- status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
- buffer, sizeof(buffer), &total_size );
- if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+ /* Allocate a unicode string to get the data */
+ Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
+ if (!Buffer)
+ {
+ RtlFreeUnicodeString(&nameW);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
- /* we need to fetch the contents for a string type even if not requested,
- * because we need to compute the length of the ASCII string. */
- if (data || is_string(info->Type))
+ ErrorCode = RegQueryValueExW(hkeyorg, nameW.Buffer, reserved, type, (LPBYTE)Buffer, &BufferSize);
+ if (ErrorCode != ERROR_SUCCESS)
{
- /* retry with a dynamically allocated buffer */
- while (status == STATUS_BUFFER_OVERFLOW)
- {
- if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
- if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
- {
- status = STATUS_NO_MEMORY;
- goto done;
- }
- info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
- status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
- buf_ptr, total_size, &total_size );
- }
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+ RtlFreeUnicodeString(&nameW);
+ return ErrorCode;
+ }
- if (status) goto done;
+ /* We don't need this anymore */
+ RtlFreeUnicodeString(&nameW);
- if (is_string(info->Type))
- {
- DWORD len;
+ DataLength = *count;
+ RtlUnicodeToMultiByteSize(count, Buffer, BufferSize);
- RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info_size),
- total_size - info_size );
- if (data && len)
- {
- if (len > datalen) status = STATUS_BUFFER_OVERFLOW;
- else
- {
- RtlUnicodeToMultiByteN( (char*)data, len, NULL, (WCHAR *)(buf_ptr + info_size),
- total_size - info_size );
- /* if the type is REG_SZ and data is not 0-terminated
- * and there is enough space in the buffer NT appends a \0 */
- if (len < datalen && data[len-1]) data[len] = 0;
- }
- }
- total_size = len + info_size;
- }
- else if (data)
- {
- if (total_size - info_size > datalen) status = STATUS_BUFFER_OVERFLOW;
- else memcpy( data, buf_ptr + info_size, total_size - info_size );
- }
+ if ((!data) || (DataLength < *count))
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+ return data ? ERROR_MORE_DATA : ERROR_SUCCESS;
}
- else status = STATUS_SUCCESS;
- if (type) *type = info->Type;
- if (count) *count = total_size - info_size;
+ /* We can finally do the conversion */
+ RtlUnicodeToMultiByteN(DataStr, DataLength, NULL, Buffer, BufferSize);
- done:
- if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
- RtlFreeUnicodeString( &nameW );
- ClosePredefKey(hkey);
- return RtlNtStatusToDosError(status);
+ /* NULL-terminate if there is enough room */
+ if ((DataLength > *count) && (DataStr[*count - 1] != '\0'))
+ DataStr[*count] = '\0';
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+
+ return ERROR_SUCCESS;
}
*/
LONG
WINAPI
-RegQueryValueExW(HKEY hkeyorg,
- LPCWSTR name,
- LPDWORD reserved,
- LPDWORD type,
- LPBYTE data,
- LPDWORD count)
+RegQueryValueExW(
+ _In_ HKEY hkeyorg,
+ _In_ LPCWSTR name,
+ _In_ LPDWORD reserved,
+ _In_ LPDWORD type,
+ _In_ LPBYTE data,
+ _In_ LPDWORD count)
{
HANDLE hkey;
NTSTATUS status;
return RtlNtStatusToDosError(status);
}
+ if (IsHKCRKey(hkey))
+ {
+ LONG ErrorCode = QueryHKCRValue(hkey, name, reserved, type, data, count);
+ ClosePredefKey(hkey);
+ return ErrorCode;
+ }
+
RtlInitUnicodeString( &name_str, name );
if (data) total_size = min( sizeof(buffer), *count + info_size );
UNICODE_STRING OldFile;
LONG ErrorCode;
- RtlCreateUnicodeStringFromAsciiz(&SubKey,
- (PCSZ)lpSubKey);
- RtlCreateUnicodeStringFromAsciiz(&OldFile,
- (PCSZ)lpOldFile);
- RtlCreateUnicodeStringFromAsciiz(&NewFile,
- (PCSZ)lpNewFile);
+ RtlInitEmptyUnicodeString(&SubKey, NULL, 0);
+ RtlInitEmptyUnicodeString(&OldFile, NULL, 0);
+ RtlInitEmptyUnicodeString(&NewFile, NULL, 0);
+
+ if (lpSubKey)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&SubKey, lpSubKey))
+ {
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ goto Exit;
+ }
+ }
+
+ if (lpOldFile)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&OldFile, lpOldFile))
+ {
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ goto Exit;
+ }
+ }
+
+ if (lpNewFile)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&NewFile, lpNewFile))
+ {
+ ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ goto Exit;
+ }
+ }
ErrorCode = RegReplaceKeyW(hKey,
SubKey.Buffer,
NewFile.Buffer,
OldFile.Buffer);
+Exit:
RtlFreeUnicodeString(&OldFile);
RtlFreeUnicodeString(&NewFile);
RtlFreeUnicodeString(&SubKey);
UNICODE_STRING FileName;
LONG ErrorCode;
- RtlCreateUnicodeStringFromAsciiz(&FileName,
- (PCSZ)lpFile);
+ if (lpFile)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFile))
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else
+ RtlInitEmptyUnicodeString(&FileName, NULL, 0);
ErrorCode = RegRestoreKeyW(hKey,
FileName.Buffer,
UNICODE_STRING FileName;
LONG ErrorCode;
- RtlCreateUnicodeStringFromAsciiz(&FileName,
- (LPSTR)lpFile);
+ if (lpFile)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFile))
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else
+ RtlInitEmptyUnicodeString(&FileName, NULL, 0);
+
ErrorCode = RegSaveKeyW(hKey,
FileName.Buffer,
lpSecurityAttributes);
UNICODE_STRING FileName;
LONG ErrorCode;
- RtlCreateUnicodeStringFromAsciiz(&FileName,
- (LPSTR)lpFile);
+ if (lpFile)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFile))
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else
+ RtlInitEmptyUnicodeString(&FileName, NULL, 0);
+
ErrorCode = RegSaveKeyExW(hKey,
FileName.Buffer,
lpSecurityAttributes,
*
* @implemented
*/
-LONG WINAPI
-RegSetValueExW(HKEY hKey,
- LPCWSTR lpValueName,
- DWORD Reserved,
- DWORD dwType,
- CONST BYTE* lpData,
- DWORD cbData)
+LONG
+WINAPI
+RegSetValueExW(
+ _In_ HKEY hKey,
+ _In_ LPCWSTR lpValueName,
+ _In_ DWORD Reserved,
+ _In_ DWORD dwType,
+ _In_ CONST BYTE* lpData,
+ _In_ DWORD cbData)
{
UNICODE_STRING ValueName;
HANDLE KeyHandle;
NTSTATUS Status;
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ if (IsHKCRKey(KeyHandle))
+ {
+ LONG ErrorCode = SetHKCRValue(KeyHandle, lpValueName, Reserved, dwType, lpData, cbData);
+ ClosePredefKey(KeyHandle);
+ return ErrorCode;
+ }
+
if (is_string(dwType) && (cbData != 0))
{
PWSTR pwsData = (PWSTR)lpData;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- _SEH2_YIELD(return ERROR_NOACCESS);
+ ClosePredefKey(KeyHandle);
+ return ERROR_NOACCESS;
}
_SEH2_END;
}
- Status = MapDefaultKey(&KeyHandle,
- hKey);
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
-
RtlInitUnicodeString(&ValueName, lpValueName);
Status = NtSetValueKey(KeyHandle,
UNICODE_STRING KeyName;
DWORD ErrorCode;
- RtlCreateUnicodeStringFromAsciiz(&KeyName,
- (LPSTR)lpSubKey);
+ if (lpSubKey)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&KeyName, lpSubKey))
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else
+ RtlInitEmptyUnicodeString(&KeyName, NULL, 0);
ErrorCode = RegUnLoadKeyW(hKey,
KeyName.Buffer);