Is this really right? I haven't checked the call chain in Windows, but 'A' functions generally call their 'W' counterpart to do the work.
Ged.
-----Original Message----- From: ros-diffs-bounces@reactos.org [mailto:ros-diffs-bounces@reactos.org] On Behalf Of cwittich@svn.reactos.org Sent: 24 May 2009 09:45 To: ros-diffs@reactos.org Subject: [ros-diffs] [cwittich] 41093: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Author: cwittich Date: Sun May 24 12:45:05 2009 New Revision: 41093
URL: http://svn.reactos.org/svn/reactos?rev=41093&view=rev Log: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg.... ============================================================================== --- trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] Sun May 24 12:45:05 2009 @@ -3964,110 +3964,96 @@ * * @implemented */ -LONG WINAPI -RegQueryValueExA(HKEY hKey, - LPCSTR lpValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData) -{ - UNICODE_STRING ValueName; - UNICODE_STRING ValueData; - ANSI_STRING AnsiString; - LONG ErrorCode; - DWORD Length; - DWORD Type; - - TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n", - hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0); - - if (lpData != NULL && lpcbData == NULL) - { - return ERROR_INVALID_PARAMETER; - } - - if (lpData) - { - ValueData.Length = 0; - ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR); - ValueData.Buffer = RtlAllocateHeap(ProcessHeap, - 0, - ValueData.MaximumLength); - if (!ValueData.Buffer) - { - return ERROR_OUTOFMEMORY; - } - } - else - { - ValueData.Buffer = NULL; - ValueData.Length = 0; - ValueData.MaximumLength = 0; - - if (lpcbData) - *lpcbData = 0; - } - - RtlCreateUnicodeStringFromAsciiz(&ValueName, - (LPSTR)lpValueName); - - Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR); - ErrorCode = RegQueryValueExW(hKey, - ValueName.Buffer, - lpReserved, - &Type, - (lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer, - &Length); - TRACE("ErrorCode %lu\n", ErrorCode); - RtlFreeUnicodeString(&ValueName); - - if (ErrorCode == ERROR_SUCCESS || - ErrorCode == ERROR_MORE_DATA) - { - if (lpType != NULL) - { - *lpType = Type; - } - - if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) - { - if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL) +LSTATUS WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWORD type, + LPBYTE data, LPDWORD count ) +{ + NTSTATUS status; + ANSI_STRING nameA; + 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 ); + + TRACE("(%p,%s,%p,%p,%p,%p=%d)\n", + hkey, debugstr_a(name), reserved, type, data, count, count ? *count : 0 ); + + if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER; + + status = MapDefaultKey( (PHANDLE)&hkey, hkey); + if (!NT_SUCCESS(status)) + { + return RtlNtStatusToDosError(status); + } + + if (count) datalen = *count; + if (!data && count) *count = 0; + + /* this matches Win9x behaviour - NT sets *type to a random value */ + if (type) *type = REG_NONE; + + RtlInitAnsiString( &nameA, name ); + if ((status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString, + &nameA, FALSE ))) + return RtlNtStatusToDosError(status); + + status = NtQueryValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString, + KeyValuePartialInformation, buffer, sizeof(buffer), &total_size ); + if (status && status != STATUS_BUFFER_OVERFLOW) goto done; + + /* 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)) + { + /* 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 ))) { - RtlInitAnsiString(&AnsiString, NULL); - AnsiString.Buffer = (LPSTR)lpData; - AnsiString.MaximumLength = *lpcbData; - ValueData.Length = Length; - ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR); - RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE); + status = STATUS_NO_MEMORY; + goto done; } - - Length = Length / sizeof(WCHAR); - } - else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL) - { - if (*lpcbData < Length) + info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr; + status = NtQueryValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString, + KeyValuePartialInformation, buf_ptr, total_size, &total_size ); + } + + if (status) goto done; + + if (is_string(info->Type)) + { + DWORD len; + + RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info_size), + total_size - info_size ); + if (data && len) { - ErrorCode = ERROR_MORE_DATA; + 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; + } } - else - { - RtlMoveMemory(lpData, ValueData.Buffer, Length); - } - } - - if (lpcbData != NULL) - { - *lpcbData = Length; - } - } - - if (ValueData.Buffer != NULL) - { - RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer); - } - - return ErrorCode; + 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 ); + } + } + else status = STATUS_SUCCESS; + + if (type) *type = info->Type; + if (count) *count = total_size - info_size; + + done: + if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr ); + return RtlNtStatusToDosError(status); }
@@ -4098,7 +4084,6 @@ (count && data) ? *count : 0 );
if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER; - //if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
status = MapDefaultKey(&hkey, hkeyorg); if (!NT_SUCCESS(status)) @@ -4162,93 +4147,27 @@ * * @implemented */ -LONG WINAPI -RegQueryValueA(HKEY hKey, - LPCSTR lpSubKey, - LPSTR lpValue, - PLONG lpcbValue) -{ - WCHAR SubKeyNameBuffer[MAX_PATH+1]; - UNICODE_STRING SubKeyName; - UNICODE_STRING Value; - ANSI_STRING AnsiString; - LONG ValueSize; - LONG ErrorCode; - - TRACE("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n", - hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0); - - if (lpValue != NULL && - lpcbValue == NULL) - { - return ERROR_INVALID_PARAMETER; - } - - RtlInitUnicodeString(&SubKeyName, - NULL); - RtlInitUnicodeString(&Value, - NULL); - if (lpSubKey != NULL && - strlen(lpSubKey) != 0) - { - RtlInitAnsiString(&AnsiString, - (LPSTR)lpSubKey); - SubKeyName.Buffer = &SubKeyNameBuffer[0]; - SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer); - RtlAnsiStringToUnicodeString(&SubKeyName, - &AnsiString, - FALSE); - } - - if (lpValue != NULL) - { - ValueSize = *lpcbValue * sizeof(WCHAR); - Value.MaximumLength = ValueSize; - Value.Buffer = RtlAllocateHeap(ProcessHeap, - 0, - ValueSize); - if (Value.Buffer == NULL) - { - return ERROR_OUTOFMEMORY; - } - } - else - { - ValueSize = 0; - } - - ErrorCode = RegQueryValueW(hKey, - (LPCWSTR)SubKeyName.Buffer, - Value.Buffer, - &ValueSize); - if (ErrorCode == ERROR_SUCCESS) - { - if (lpValue != NULL) - { - Value.Length = ValueSize; - RtlInitAnsiString(&AnsiString, - NULL); - AnsiString.Buffer = lpValue; - AnsiString.MaximumLength = *lpcbValue; - RtlUnicodeStringToAnsiString(&AnsiString, - &Value, - FALSE); - *lpcbValue = ValueSize; - } - else if (lpcbValue != NULL) - { - *lpcbValue = ValueSize; - } - } - - if (Value.Buffer != NULL) - { - RtlFreeHeap(ProcessHeap, - 0, - Value.Buffer); - } - - return ErrorCode; +LSTATUS WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG count ) +{ + DWORD ret; + HKEY subkey = hkey; + + TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_a(name), data, count ? *count : 0 ); + + if (name && name[0]) + { + if ((ret = RegOpenKeyA( hkey, name, &subkey )) != ERROR_SUCCESS) return ret; + } + ret = RegQueryValueExA( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count ); + if (subkey != hkey) RegCloseKey( subkey ); + if (ret == ERROR_FILE_NOT_FOUND) + { + /* return empty string if default value not found */ + if (data) *data = 0; + if (count) *count = 1; + ret = ERROR_SUCCESS; + } + return ret; }
@@ -4257,75 +4176,42 @@ * * @implemented */ -LONG WINAPI -RegQueryValueW(HKEY hKey, - LPCWSTR lpSubKey, - LPWSTR lpValue, - PLONG lpcbValue) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING SubKeyString; - HANDLE KeyHandle; - HANDLE RealKey; - LONG ErrorCode; - BOOL CloseRealKey; - NTSTATUS Status; - - TRACE("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n", - hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0); - if (hKey == NULL) +LSTATUS WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count ) +{ + DWORD ret; + HKEY subkey = hkey; + + TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_w(name), data, count ? *count : 0 ); + if (hkey == NULL) { return ERROR_INVALID_HANDLE; } - Status = MapDefaultKey(&KeyHandle, - hKey); - if (!NT_SUCCESS(Status)) - { - return RtlNtStatusToDosError(Status); - } - - if (lpSubKey != NULL && - wcslen(lpSubKey) != 0) - { - RtlInitUnicodeString(&SubKeyString, - (LPWSTR)lpSubKey); - InitializeObjectAttributes(&ObjectAttributes, - &SubKeyString, - OBJ_CASE_INSENSITIVE, - KeyHandle, - NULL); - Status = NtOpenKey(&RealKey, - KEY_QUERY_VALUE, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - ErrorCode = RtlNtStatusToDosError(Status); - goto Cleanup; - } - - CloseRealKey = TRUE; - } - else - { - RealKey = hKey; - CloseRealKey = FALSE; - } - - ErrorCode = RegQueryValueExW(RealKey, - NULL, - NULL, - NULL, - (LPBYTE)lpValue, - (LPDWORD)lpcbValue); - if (CloseRealKey) - { - NtClose(RealKey); - } - -Cleanup: - ClosePredefKey(KeyHandle); - - return ErrorCode; + if (name && name[0]) + { + ret = RegOpenKeyW( hkey, name, &subkey); + if (ret != ERROR_SUCCESS) + { + return ret; + } + } + + ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count ); + + if (subkey != hkey) + { + RegCloseKey( subkey ); + } + + if (ret == ERROR_FILE_NOT_FOUND) + { + /* return empty string if default value not found */ + if (data) + *data = 0; + if (count) + *count = sizeof(WCHAR); + ret = ERROR_SUCCESS; + } + return ret; }
@@ -4806,86 +4692,43 @@ * * @implemented */ -LONG WINAPI -RegSetValueExA(HKEY hKey, - LPCSTR lpValueName, - DWORD Reserved, - DWORD dwType, - CONST BYTE* lpData, - DWORD cbData) -{ - UNICODE_STRING ValueName; - LPWSTR pValueName; - ANSI_STRING AnsiString; - UNICODE_STRING Data; - LONG ErrorCode; - LPBYTE pData; - DWORD DataSize; - - if (lpValueName != NULL && - strlen(lpValueName) != 0) - { - RtlCreateUnicodeStringFromAsciiz(&ValueName, - (PSTR)lpValueName); - } - else - { - ValueName.Buffer = NULL; - } - - pValueName = (LPWSTR)ValueName.Buffer; - - if (((dwType == REG_SZ) || - (dwType == REG_MULTI_SZ) || - (dwType == REG_EXPAND_SZ)) && - (cbData != 0)) - { - /* NT adds one if the caller forgot the NULL-termination character */ - if (lpData[cbData - 1] != '\0') - { - cbData++; - } - - RtlInitAnsiString(&AnsiString, - NULL); - AnsiString.Buffer = (PSTR)lpData; - AnsiString.Length = cbData - 1; - AnsiString.MaximumLength = cbData; - RtlAnsiStringToUnicodeString(&Data, - &AnsiString, - TRUE); - pData = (LPBYTE)Data.Buffer; - DataSize = cbData * sizeof(WCHAR); - } - else - { - RtlInitUnicodeString(&Data, - NULL); - pData = (LPBYTE)lpData; - DataSize = cbData; - } - - ErrorCode = RegSetValueExW(hKey, - pValueName, - Reserved, - dwType, - pData, - DataSize); - if (pValueName != NULL) - { - RtlFreeHeap(ProcessHeap, - 0, - ValueName.Buffer); - } - - if (Data.Buffer != NULL) - { - RtlFreeHeap(ProcessHeap, - 0, - Data.Buffer); - } - - return ErrorCode; +LSTATUS WINAPI RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved, DWORD type, + CONST BYTE *data, DWORD count ) +{ + ANSI_STRING nameA; + WCHAR *dataW = NULL; + NTSTATUS status; + + if (count && is_string(type)) + { + /* if user forgot to count terminating null, add it (yes NT does this) */ + if (data[count-1] && !data[count]) count++; + } + + status = MapDefaultKey( (PHANDLE)&hkey, hkey); + if (!NT_SUCCESS(status)) + { + return RtlNtStatusToDosError(status); + } + + if (is_string( type )) /* need to convert to Unicode */ + { + DWORD lenW; + RtlMultiByteToUnicodeSize( &lenW, (const char *)data, count ); + if (!(dataW = HeapAlloc( GetProcessHeap(), 0, lenW ))) return ERROR_OUTOFMEMORY; + RtlMultiByteToUnicodeN( dataW, lenW, NULL, (const char *)data, count ); + count = lenW; + data = (BYTE *)dataW; + } + + RtlInitAnsiString( &nameA, name ); + if (!(status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString, + &nameA, FALSE ))) + { + status = NtSetValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString, 0, type, (PVOID)data, count ); + } + HeapFree( GetProcessHeap(), 0, dataW ); + return RtlNtStatusToDosError( status ); }
Lol, Ged...this is Wine, remember?
It works like this:
Ntoskrnl calls user32, which calls kernel32, which calls ntdll, which then calls msi.
Msi's A function then calls ntoskrnl's W function, which calls back into gdi32's A function (after converting all the parameters).
Best regards, Alex Ionescu
On Sun, May 24, 2009 at 3:35 PM, Ged gedmurphy@gmail.com wrote:
Is this really right? I haven't checked the call chain in Windows, but 'A' functions generally call their 'W' counterpart to do the work.
Ged.
-----Original Message----- From: ros-diffs-bounces@reactos.org [mailto:ros-diffs-bounces@reactos.org] On Behalf Of cwittich@svn.reactos.org Sent: 24 May 2009 09:45 To: ros-diffs@reactos.org Subject: [ros-diffs] [cwittich] 41093: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Author: cwittich Date: Sun May 24 12:45:05 2009 New Revision: 41093
URL: http://svn.reactos.org/svn/reactos?rev=41093&view=rev Log: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg.... ============================================================================== --- trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] Sun May 24 12:45:05 2009 @@ -3964,110 +3964,96 @@ * * @implemented */ -LONG WINAPI -RegQueryValueExA(HKEY hKey,
- LPCSTR lpValueName,
- LPDWORD lpReserved,
- LPDWORD lpType,
- LPBYTE lpData,
- LPDWORD lpcbData)
-{
- UNICODE_STRING ValueName;
- UNICODE_STRING ValueData;
- ANSI_STRING AnsiString;
- LONG ErrorCode;
- DWORD Length;
- DWORD Type;
- TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
- hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
- if (lpData != NULL && lpcbData == NULL)
- {
- return ERROR_INVALID_PARAMETER;
- }
- if (lpData)
- {
- ValueData.Length = 0;
- ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR);
- ValueData.Buffer = RtlAllocateHeap(ProcessHeap,
- 0,
- ValueData.MaximumLength);
- if (!ValueData.Buffer)
- {
- return ERROR_OUTOFMEMORY;
- }
- }
- else
- {
- ValueData.Buffer = NULL;
- ValueData.Length = 0;
- ValueData.MaximumLength = 0;
- if (lpcbData)
- *lpcbData = 0;
- }
- RtlCreateUnicodeStringFromAsciiz(&ValueName,
- (LPSTR)lpValueName);
- Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
- ErrorCode = RegQueryValueExW(hKey,
- ValueName.Buffer,
- lpReserved,
- &Type,
- (lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer,
- &Length);
- TRACE("ErrorCode %lu\n", ErrorCode);
- RtlFreeUnicodeString(&ValueName);
- if (ErrorCode == ERROR_SUCCESS ||
- ErrorCode == ERROR_MORE_DATA)
- {
- if (lpType != NULL)
- {
- *lpType = Type;
- }
- if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
- {
- if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+LSTATUS WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWORD type,
- LPBYTE data, LPDWORD count )
+{
- NTSTATUS status;
- ANSI_STRING nameA;
- 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 );
- TRACE("(%p,%s,%p,%p,%p,%p=%d)\n",
- hkey, debugstr_a(name), reserved, type, data, count, count ? *count : 0 );
- if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
- status = MapDefaultKey( (PHANDLE)&hkey, hkey);
- if (!NT_SUCCESS(status))
- {
- return RtlNtStatusToDosError(status);
- }
- if (count) datalen = *count;
- if (!data && count) *count = 0;
- /* this matches Win9x behaviour - NT sets *type to a random value */
- if (type) *type = REG_NONE;
- RtlInitAnsiString( &nameA, name );
- if ((status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString,
- &nameA, FALSE )))
- return RtlNtStatusToDosError(status);
- status = NtQueryValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString,
- KeyValuePartialInformation, buffer, sizeof(buffer), &total_size );
- if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
- /* 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))
- {
- /* 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 )))
{
- RtlInitAnsiString(&AnsiString, NULL);
- AnsiString.Buffer = (LPSTR)lpData;
- AnsiString.MaximumLength = *lpcbData;
- ValueData.Length = Length;
- ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
- RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
- status = STATUS_NO_MEMORY;
- goto done;
}
- Length = Length / sizeof(WCHAR);
- }
- else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
- {
- if (*lpcbData < Length)
- info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
- status = NtQueryValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString,
- KeyValuePartialInformation, buf_ptr, total_size, &total_size );
- }
- if (status) goto done;
- if (is_string(info->Type))
- {
- DWORD len;
- RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info_size),
- total_size - info_size );
- if (data && len)
{
- ErrorCode = ERROR_MORE_DATA;
- 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;
- }
}
- else
- {
- RtlMoveMemory(lpData, ValueData.Buffer, Length);
- }
- }
- if (lpcbData != NULL)
- {
- *lpcbData = Length;
- }
- }
- if (ValueData.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
- }
- return ErrorCode;
- 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 );
- }
- }
- else status = STATUS_SUCCESS;
- if (type) *type = info->Type;
- if (count) *count = total_size - info_size;
- done:
- if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
- return RtlNtStatusToDosError(status);
}
@@ -4098,7 +4084,6 @@ (count && data) ? *count : 0 );
if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
- //if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
status = MapDefaultKey(&hkey, hkeyorg); if (!NT_SUCCESS(status)) @@ -4162,93 +4147,27 @@ * * @implemented */ -LONG WINAPI -RegQueryValueA(HKEY hKey,
- LPCSTR lpSubKey,
- LPSTR lpValue,
- PLONG lpcbValue)
-{
- WCHAR SubKeyNameBuffer[MAX_PATH+1];
- UNICODE_STRING SubKeyName;
- UNICODE_STRING Value;
- ANSI_STRING AnsiString;
- LONG ValueSize;
- LONG ErrorCode;
- TRACE("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n",
- hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
- if (lpValue != NULL &&
- lpcbValue == NULL)
- {
- return ERROR_INVALID_PARAMETER;
- }
- RtlInitUnicodeString(&SubKeyName,
- NULL);
- RtlInitUnicodeString(&Value,
- NULL);
- if (lpSubKey != NULL &&
- strlen(lpSubKey) != 0)
- {
- RtlInitAnsiString(&AnsiString,
- (LPSTR)lpSubKey);
- SubKeyName.Buffer = &SubKeyNameBuffer[0];
- SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
- RtlAnsiStringToUnicodeString(&SubKeyName,
- &AnsiString,
- FALSE);
- }
- if (lpValue != NULL)
- {
- ValueSize = *lpcbValue * sizeof(WCHAR);
- Value.MaximumLength = ValueSize;
- Value.Buffer = RtlAllocateHeap(ProcessHeap,
- 0,
- ValueSize);
- if (Value.Buffer == NULL)
- {
- return ERROR_OUTOFMEMORY;
- }
- }
- else
- {
- ValueSize = 0;
- }
- ErrorCode = RegQueryValueW(hKey,
- (LPCWSTR)SubKeyName.Buffer,
- Value.Buffer,
- &ValueSize);
- if (ErrorCode == ERROR_SUCCESS)
- {
- if (lpValue != NULL)
- {
- Value.Length = ValueSize;
- RtlInitAnsiString(&AnsiString,
- NULL);
- AnsiString.Buffer = lpValue;
- AnsiString.MaximumLength = *lpcbValue;
- RtlUnicodeStringToAnsiString(&AnsiString,
- &Value,
- FALSE);
- *lpcbValue = ValueSize;
- }
- else if (lpcbValue != NULL)
- {
- *lpcbValue = ValueSize;
- }
- }
- if (Value.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- Value.Buffer);
- }
- return ErrorCode;
+LSTATUS WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG count ) +{
- DWORD ret;
- HKEY subkey = hkey;
- TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_a(name), data, count ? *count : 0 );
- if (name && name[0])
- {
- if ((ret = RegOpenKeyA( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
- }
- ret = RegQueryValueExA( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
- if (subkey != hkey) RegCloseKey( subkey );
- if (ret == ERROR_FILE_NOT_FOUND)
- {
- /* return empty string if default value not found */
- if (data) *data = 0;
- if (count) *count = 1;
- ret = ERROR_SUCCESS;
- }
- return ret;
}
@@ -4257,75 +4176,42 @@ * * @implemented */ -LONG WINAPI -RegQueryValueW(HKEY hKey,
- LPCWSTR lpSubKey,
- LPWSTR lpValue,
- PLONG lpcbValue)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING SubKeyString;
- HANDLE KeyHandle;
- HANDLE RealKey;
- LONG ErrorCode;
- BOOL CloseRealKey;
- NTSTATUS Status;
- TRACE("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n",
- hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
- if (hKey == NULL)
+LSTATUS WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count ) +{
- DWORD ret;
- HKEY subkey = hkey;
- TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_w(name), data, count ? *count : 0 );
- if (hkey == NULL)
{ return ERROR_INVALID_HANDLE; }
- Status = MapDefaultKey(&KeyHandle,
- hKey);
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
- if (lpSubKey != NULL &&
- wcslen(lpSubKey) != 0)
- {
- RtlInitUnicodeString(&SubKeyString,
- (LPWSTR)lpSubKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &SubKeyString,
- OBJ_CASE_INSENSITIVE,
- KeyHandle,
- NULL);
- Status = NtOpenKey(&RealKey,
- KEY_QUERY_VALUE,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- ErrorCode = RtlNtStatusToDosError(Status);
- goto Cleanup;
- }
- CloseRealKey = TRUE;
- }
- else
- {
- RealKey = hKey;
- CloseRealKey = FALSE;
- }
- ErrorCode = RegQueryValueExW(RealKey,
- NULL,
- NULL,
- NULL,
- (LPBYTE)lpValue,
- (LPDWORD)lpcbValue);
- if (CloseRealKey)
- {
- NtClose(RealKey);
- }
-Cleanup:
- ClosePredefKey(KeyHandle);
- return ErrorCode;
- if (name && name[0])
- {
- ret = RegOpenKeyW( hkey, name, &subkey);
- if (ret != ERROR_SUCCESS)
- {
- return ret;
- }
- }
- ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
- if (subkey != hkey)
- {
- RegCloseKey( subkey );
- }
- if (ret == ERROR_FILE_NOT_FOUND)
- {
- /* return empty string if default value not found */
- if (data)
- *data = 0;
- if (count)
- *count = sizeof(WCHAR);
- ret = ERROR_SUCCESS;
- }
- return ret;
}
@@ -4806,86 +4692,43 @@ * * @implemented */ -LONG WINAPI -RegSetValueExA(HKEY hKey,
- LPCSTR lpValueName,
- DWORD Reserved,
- DWORD dwType,
- CONST BYTE* lpData,
- DWORD cbData)
-{
- UNICODE_STRING ValueName;
- LPWSTR pValueName;
- ANSI_STRING AnsiString;
- UNICODE_STRING Data;
- LONG ErrorCode;
- LPBYTE pData;
- DWORD DataSize;
- if (lpValueName != NULL &&
- strlen(lpValueName) != 0)
- {
- RtlCreateUnicodeStringFromAsciiz(&ValueName,
- (PSTR)lpValueName);
- }
- else
- {
- ValueName.Buffer = NULL;
- }
- pValueName = (LPWSTR)ValueName.Buffer;
- if (((dwType == REG_SZ) ||
- (dwType == REG_MULTI_SZ) ||
- (dwType == REG_EXPAND_SZ)) &&
- (cbData != 0))
- {
- /* NT adds one if the caller forgot the NULL-termination character */
- if (lpData[cbData - 1] != '\0')
- {
- cbData++;
- }
- RtlInitAnsiString(&AnsiString,
- NULL);
- AnsiString.Buffer = (PSTR)lpData;
- AnsiString.Length = cbData - 1;
- AnsiString.MaximumLength = cbData;
- RtlAnsiStringToUnicodeString(&Data,
- &AnsiString,
- TRUE);
- pData = (LPBYTE)Data.Buffer;
- DataSize = cbData * sizeof(WCHAR);
- }
- else
- {
- RtlInitUnicodeString(&Data,
- NULL);
- pData = (LPBYTE)lpData;
- DataSize = cbData;
- }
- ErrorCode = RegSetValueExW(hKey,
- pValueName,
- Reserved,
- dwType,
- pData,
- DataSize);
- if (pValueName != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- ValueName.Buffer);
- }
- if (Data.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- Data.Buffer);
- }
- return ErrorCode;
+LSTATUS WINAPI RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved, DWORD type,
- CONST BYTE *data, DWORD count )
+{
- ANSI_STRING nameA;
- WCHAR *dataW = NULL;
- NTSTATUS status;
- if (count && is_string(type))
- {
- /* if user forgot to count terminating null, add it (yes NT does this) */
- if (data[count-1] && !data[count]) count++;
- }
- status = MapDefaultKey( (PHANDLE)&hkey, hkey);
- if (!NT_SUCCESS(status))
- {
- return RtlNtStatusToDosError(status);
- }
- if (is_string( type )) /* need to convert to Unicode */
- {
- DWORD lenW;
- RtlMultiByteToUnicodeSize( &lenW, (const char *)data, count );
- if (!(dataW = HeapAlloc( GetProcessHeap(), 0, lenW ))) return ERROR_OUTOFMEMORY;
- RtlMultiByteToUnicodeN( dataW, lenW, NULL, (const char *)data, count );
- count = lenW;
- data = (BYTE *)dataW;
- }
- RtlInitAnsiString( &nameA, name );
- if (!(status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString,
- &nameA, FALSE )))
- {
- status = NtSetValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString, 0, type, (PVOID)data, count );
- }
- HeapFree( GetProcessHeap(), 0, dataW );
- return RtlNtStatusToDosError( status );
}
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
And somewhere in the middle of that there's an RPC call picked up by the linux host which calls a bash script to do the work.
I was initially worried about scenarios which may brake apps, for example an app hooks RegQueryValueEx and expects to pick up all calls to RegQueryValue(Ex|A|W) (stupid, but possible). I think it's important to keep the call chains as close to Windows as possible. Anyway, I've just checked the call chain and it seems both ansi and Unicode functions call a LocalBase* function to do the work, so this isn't so much of an issue.
I still disagree with this change though as we're doubling up on the code to do the same operation, meaning we now have 2 failure points instead of 1. This is one of the main reasons for getting A functions to call their W counterpart. If it's broken, you only have 1 code path to fix.
Ged.
-----Original Message----- From: ros-dev-bounces@reactos.org [mailto:ros-dev-bounces@reactos.org] On Behalf Of Alex Ionescu Sent: 24 May 2009 15:19 To: ReactOS Development List Subject: Re: [ros-dev] [ros-diffs] [cwittich] 41093: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Lol, Ged...this is Wine, remember?
It works like this:
Ntoskrnl calls user32, which calls kernel32, which calls ntdll, which then calls msi.
Msi's A function then calls ntoskrnl's W function, which calls back into gdi32's A function (after converting all the parameters).
Best regards, Alex Ionescu
On Sun, May 24, 2009 at 3:35 PM, Ged gedmurphy@gmail.com wrote:
Is this really right? I haven't checked the call chain in Windows, but 'A' functions generally
call their 'W' counterpart to do the work.
Ged.
-----Original Message----- From: ros-diffs-bounces@reactos.org [mailto:ros-diffs-bounces@reactos.org]
On Behalf Of cwittich@svn.reactos.org
Sent: 24 May 2009 09:45 To: ros-diffs@reactos.org Subject: [ros-diffs] [cwittich] 41093: sync RegQueryValueExA,
RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Author: cwittich Date: Sun May 24 12:45:05 2009 New Revision: 41093
URL: http://svn.reactos.org/svn/reactos?rev=41093&view=rev Log: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA
to wine
patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg. c?rev=41093&r1=41092&r2=41093&view=diff
============================================================================ ==
--- trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] Sun May 24
12:45:05 2009
@@ -3964,110 +3964,96 @@ * * @implemented */ -LONG WINAPI -RegQueryValueExA(HKEY hKey,
- LPCSTR lpValueName,
- LPDWORD lpReserved,
- LPDWORD lpType,
- LPBYTE lpData,
- LPDWORD lpcbData)
-{
- UNICODE_STRING ValueName;
- UNICODE_STRING ValueData;
- ANSI_STRING AnsiString;
- LONG ErrorCode;
- DWORD Length;
- DWORD Type;
- TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
- hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
- if (lpData != NULL && lpcbData == NULL)
- {
- return ERROR_INVALID_PARAMETER;
- }
- if (lpData)
- {
- ValueData.Length = 0;
- ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR);
- ValueData.Buffer = RtlAllocateHeap(ProcessHeap,
- 0,
- ValueData.MaximumLength);
- if (!ValueData.Buffer)
- {
- return ERROR_OUTOFMEMORY;
- }
- }
- else
- {
- ValueData.Buffer = NULL;
- ValueData.Length = 0;
- ValueData.MaximumLength = 0;
- if (lpcbData)
- *lpcbData = 0;
- }
- RtlCreateUnicodeStringFromAsciiz(&ValueName,
- (LPSTR)lpValueName);
- Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
- ErrorCode = RegQueryValueExW(hKey,
- ValueName.Buffer,
- lpReserved,
- &Type,
- (lpData == NULL) ? NULL :
(LPBYTE)ValueData.Buffer,
- &Length);
- TRACE("ErrorCode %lu\n", ErrorCode);
- RtlFreeUnicodeString(&ValueName);
- if (ErrorCode == ERROR_SUCCESS ||
- ErrorCode == ERROR_MORE_DATA)
- {
- if (lpType != NULL)
- {
- *lpType = Type;
- }
- if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type ==
REG_EXPAND_SZ))
- {
- if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+LSTATUS WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD
reserved, LPDWORD type,
- LPBYTE data, LPDWORD count )
+{
- NTSTATUS status;
- ANSI_STRING nameA;
- 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 );
- TRACE("(%p,%s,%p,%p,%p,%p=%d)\n",
- hkey, debugstr_a(name), reserved, type, data, count, count ?
*count : 0 );
- if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
- status = MapDefaultKey( (PHANDLE)&hkey, hkey);
- if (!NT_SUCCESS(status))
- {
- return RtlNtStatusToDosError(status);
- }
- if (count) datalen = *count;
- if (!data && count) *count = 0;
- /* this matches Win9x behaviour - NT sets *type to a random value */
- if (type) *type = REG_NONE;
- RtlInitAnsiString( &nameA, name );
- if ((status = RtlAnsiStringToUnicodeString(
&NtCurrentTeb()->StaticUnicodeString,
- &nameA, FALSE )))
- return RtlNtStatusToDosError(status);
- status = NtQueryValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString,
- KeyValuePartialInformation, buffer,
sizeof(buffer), &total_size );
- if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
- /* 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))
- {
- /* 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
)))
{
- RtlInitAnsiString(&AnsiString, NULL);
- AnsiString.Buffer = (LPSTR)lpData;
- AnsiString.MaximumLength = *lpcbData;
- ValueData.Length = Length;
- ValueData.MaximumLength = ValueData.Length +
sizeof(WCHAR);
- RtlUnicodeStringToAnsiString(&AnsiString, &ValueData,
FALSE);
- status = STATUS_NO_MEMORY;
- goto done;
}
- Length = Length / sizeof(WCHAR);
- }
- else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
- {
- if (*lpcbData < Length)
- info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
- status = NtQueryValueKey( hkey,
&NtCurrentTeb()->StaticUnicodeString,
- KeyValuePartialInformation, buf_ptr,
total_size, &total_size );
- }
- if (status) goto done;
- if (is_string(info->Type))
- {
- DWORD len;
- RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr +
info_size),
- total_size - info_size );
- if (data && len)
{
- ErrorCode = ERROR_MORE_DATA;
- 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;
- }
}
- else
- {
- RtlMoveMemory(lpData, ValueData.Buffer, Length);
- }
- }
- if (lpcbData != NULL)
- {
- *lpcbData = Length;
- }
- }
- if (ValueData.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
- }
- return ErrorCode;
- 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 );
- }
- }
- else status = STATUS_SUCCESS;
- if (type) *type = info->Type;
- if (count) *count = total_size - info_size;
- done:
- if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
- return RtlNtStatusToDosError(status);
}
@@ -4098,7 +4084,6 @@ (count && data) ? *count : 0 );
if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
- //if (!(hkey = get_special_root_hkey( hkey ))) return
ERROR_INVALID_HANDLE;
status = MapDefaultKey(&hkey, hkeyorg); if (!NT_SUCCESS(status)) @@ -4162,93 +4147,27 @@ * * @implemented */ -LONG WINAPI -RegQueryValueA(HKEY hKey,
- LPCSTR lpSubKey,
- LPSTR lpValue,
- PLONG lpcbValue)
-{
- WCHAR SubKeyNameBuffer[MAX_PATH+1];
- UNICODE_STRING SubKeyName;
- UNICODE_STRING Value;
- ANSI_STRING AnsiString;
- LONG ValueSize;
- LONG ErrorCode;
- TRACE("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n",
- hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
- if (lpValue != NULL &&
- lpcbValue == NULL)
- {
- return ERROR_INVALID_PARAMETER;
- }
- RtlInitUnicodeString(&SubKeyName,
- NULL);
- RtlInitUnicodeString(&Value,
- NULL);
- if (lpSubKey != NULL &&
- strlen(lpSubKey) != 0)
- {
- RtlInitAnsiString(&AnsiString,
- (LPSTR)lpSubKey);
- SubKeyName.Buffer = &SubKeyNameBuffer[0];
- SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
- RtlAnsiStringToUnicodeString(&SubKeyName,
- &AnsiString,
- FALSE);
- }
- if (lpValue != NULL)
- {
- ValueSize = *lpcbValue * sizeof(WCHAR);
- Value.MaximumLength = ValueSize;
- Value.Buffer = RtlAllocateHeap(ProcessHeap,
- 0,
- ValueSize);
- if (Value.Buffer == NULL)
- {
- return ERROR_OUTOFMEMORY;
- }
- }
- else
- {
- ValueSize = 0;
- }
- ErrorCode = RegQueryValueW(hKey,
- (LPCWSTR)SubKeyName.Buffer,
- Value.Buffer,
- &ValueSize);
- if (ErrorCode == ERROR_SUCCESS)
- {
- if (lpValue != NULL)
- {
- Value.Length = ValueSize;
- RtlInitAnsiString(&AnsiString,
- NULL);
- AnsiString.Buffer = lpValue;
- AnsiString.MaximumLength = *lpcbValue;
- RtlUnicodeStringToAnsiString(&AnsiString,
- &Value,
- FALSE);
- *lpcbValue = ValueSize;
- }
- else if (lpcbValue != NULL)
- {
- *lpcbValue = ValueSize;
- }
- }
- if (Value.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- Value.Buffer);
- }
- return ErrorCode;
+LSTATUS WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG
count )
+{
- DWORD ret;
- HKEY subkey = hkey;
- TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_a(name), data, count ? *count
: 0 );
- if (name && name[0])
- {
- if ((ret = RegOpenKeyA( hkey, name, &subkey )) != ERROR_SUCCESS)
return ret;
- }
- ret = RegQueryValueExA( subkey, NULL, NULL, NULL, (LPBYTE)data,
(LPDWORD)count );
- if (subkey != hkey) RegCloseKey( subkey );
- if (ret == ERROR_FILE_NOT_FOUND)
- {
- /* return empty string if default value not found */
- if (data) *data = 0;
- if (count) *count = 1;
- ret = ERROR_SUCCESS;
- }
- return ret;
}
@@ -4257,75 +4176,42 @@ * * @implemented */ -LONG WINAPI -RegQueryValueW(HKEY hKey,
- LPCWSTR lpSubKey,
- LPWSTR lpValue,
- PLONG lpcbValue)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING SubKeyString;
- HANDLE KeyHandle;
- HANDLE RealKey;
- LONG ErrorCode;
- BOOL CloseRealKey;
- NTSTATUS Status;
- TRACE("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n",
- hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
- if (hKey == NULL)
+LSTATUS WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data,
LPLONG count )
+{
- DWORD ret;
- HKEY subkey = hkey;
- TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_w(name), data, count ? *count
: 0 );
- if (hkey == NULL)
{ return ERROR_INVALID_HANDLE; }
- Status = MapDefaultKey(&KeyHandle,
- hKey);
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
- if (lpSubKey != NULL &&
- wcslen(lpSubKey) != 0)
- {
- RtlInitUnicodeString(&SubKeyString,
- (LPWSTR)lpSubKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &SubKeyString,
- OBJ_CASE_INSENSITIVE,
- KeyHandle,
- NULL);
- Status = NtOpenKey(&RealKey,
- KEY_QUERY_VALUE,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- ErrorCode = RtlNtStatusToDosError(Status);
- goto Cleanup;
- }
- CloseRealKey = TRUE;
- }
- else
- {
- RealKey = hKey;
- CloseRealKey = FALSE;
- }
- ErrorCode = RegQueryValueExW(RealKey,
- NULL,
- NULL,
- NULL,
- (LPBYTE)lpValue,
- (LPDWORD)lpcbValue);
- if (CloseRealKey)
- {
- NtClose(RealKey);
- }
-Cleanup:
- ClosePredefKey(KeyHandle);
- return ErrorCode;
- if (name && name[0])
- {
- ret = RegOpenKeyW( hkey, name, &subkey);
- if (ret != ERROR_SUCCESS)
- {
- return ret;
- }
- }
- ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data,
(LPDWORD)count );
- if (subkey != hkey)
- {
- RegCloseKey( subkey );
- }
- if (ret == ERROR_FILE_NOT_FOUND)
- {
- /* return empty string if default value not found */
- if (data)
- *data = 0;
- if (count)
- *count = sizeof(WCHAR);
- ret = ERROR_SUCCESS;
- }
- return ret;
}
@@ -4806,86 +4692,43 @@ * * @implemented */ -LONG WINAPI -RegSetValueExA(HKEY hKey,
- LPCSTR lpValueName,
- DWORD Reserved,
- DWORD dwType,
- CONST BYTE* lpData,
- DWORD cbData)
-{
- UNICODE_STRING ValueName;
- LPWSTR pValueName;
- ANSI_STRING AnsiString;
- UNICODE_STRING Data;
- LONG ErrorCode;
- LPBYTE pData;
- DWORD DataSize;
- if (lpValueName != NULL &&
- strlen(lpValueName) != 0)
- {
- RtlCreateUnicodeStringFromAsciiz(&ValueName,
- (PSTR)lpValueName);
- }
- else
- {
- ValueName.Buffer = NULL;
- }
- pValueName = (LPWSTR)ValueName.Buffer;
- if (((dwType == REG_SZ) ||
- (dwType == REG_MULTI_SZ) ||
- (dwType == REG_EXPAND_SZ)) &&
- (cbData != 0))
- {
- /* NT adds one if the caller forgot the NULL-termination
character */
- if (lpData[cbData - 1] != '\0')
- {
- cbData++;
- }
- RtlInitAnsiString(&AnsiString,
- NULL);
- AnsiString.Buffer = (PSTR)lpData;
- AnsiString.Length = cbData - 1;
- AnsiString.MaximumLength = cbData;
- RtlAnsiStringToUnicodeString(&Data,
- &AnsiString,
- TRUE);
- pData = (LPBYTE)Data.Buffer;
- DataSize = cbData * sizeof(WCHAR);
- }
- else
- {
- RtlInitUnicodeString(&Data,
- NULL);
- pData = (LPBYTE)lpData;
- DataSize = cbData;
- }
- ErrorCode = RegSetValueExW(hKey,
- pValueName,
- Reserved,
- dwType,
- pData,
- DataSize);
- if (pValueName != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- ValueName.Buffer);
- }
- if (Data.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- Data.Buffer);
- }
- return ErrorCode;
+LSTATUS WINAPI RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved,
DWORD type,
- CONST BYTE *data, DWORD count )
+{
- ANSI_STRING nameA;
- WCHAR *dataW = NULL;
- NTSTATUS status;
- if (count && is_string(type))
- {
- /* if user forgot to count terminating null, add it (yes NT does
this) */
- if (data[count-1] && !data[count]) count++;
- }
- status = MapDefaultKey( (PHANDLE)&hkey, hkey);
- if (!NT_SUCCESS(status))
- {
- return RtlNtStatusToDosError(status);
- }
- if (is_string( type )) /* need to convert to Unicode */
- {
- DWORD lenW;
- RtlMultiByteToUnicodeSize( &lenW, (const char *)data, count );
- if (!(dataW = HeapAlloc( GetProcessHeap(), 0, lenW ))) return
ERROR_OUTOFMEMORY;
- RtlMultiByteToUnicodeN( dataW, lenW, NULL, (const char *)data,
count );
- count = lenW;
- data = (BYTE *)dataW;
- }
- RtlInitAnsiString( &nameA, name );
- if (!(status = RtlAnsiStringToUnicodeString(
&NtCurrentTeb()->StaticUnicodeString,
- &nameA, FALSE )))
- {
- status = NtSetValueKey( hkey,
&NtCurrentTeb()->StaticUnicodeString, 0, type, (PVOID)data, count );
- }
- HeapFree( GetProcessHeap(), 0, dataW );
- return RtlNtStatusToDosError( status );
}
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
FYI, Local* or Base functions are typically always W.
Best regards, Alex Ionescu
On Sun, May 24, 2009 at 6:13 PM, Ged gedmurphy@gmail.com wrote:
And somewhere in the middle of that there's an RPC call picked up by the linux host which calls a bash script to do the work.
I was initially worried about scenarios which may brake apps, for example an app hooks RegQueryValueEx and expects to pick up all calls to RegQueryValue(Ex|A|W) (stupid, but possible). I think it's important to keep the call chains as close to Windows as possible. Anyway, I've just checked the call chain and it seems both ansi and Unicode functions call a LocalBase* function to do the work, so this isn't so much of an issue.
I still disagree with this change though as we're doubling up on the code to do the same operation, meaning we now have 2 failure points instead of 1. This is one of the main reasons for getting A functions to call their W counterpart. If it's broken, you only have 1 code path to fix.
Ged.
-----Original Message----- From: ros-dev-bounces@reactos.org [mailto:ros-dev-bounces@reactos.org] On Behalf Of Alex Ionescu Sent: 24 May 2009 15:19 To: ReactOS Development List Subject: Re: [ros-dev] [ros-diffs] [cwittich] 41093: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Lol, Ged...this is Wine, remember?
It works like this:
Ntoskrnl calls user32, which calls kernel32, which calls ntdll, which then calls msi.
Msi's A function then calls ntoskrnl's W function, which calls back into gdi32's A function (after converting all the parameters).
Best regards, Alex Ionescu
On Sun, May 24, 2009 at 3:35 PM, Ged gedmurphy@gmail.com wrote:
Is this really right? I haven't checked the call chain in Windows, but 'A' functions generally
call their 'W' counterpart to do the work.
Ged.
-----Original Message----- From: ros-diffs-bounces@reactos.org [mailto:ros-diffs-bounces@reactos.org]
On Behalf Of cwittich@svn.reactos.org
Sent: 24 May 2009 09:45 To: ros-diffs@reactos.org Subject: [ros-diffs] [cwittich] 41093: sync RegQueryValueExA,
RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Author: cwittich Date: Sun May 24 12:45:05 2009 New Revision: 41093
URL: http://svn.reactos.org/svn/reactos?rev=41093&view=rev Log: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA
to wine
patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg. c?rev=41093&r1=41092&r2=41093&view=diff
============================================================================
--- trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] Sun May 24
12:45:05 2009
@@ -3964,110 +3964,96 @@ * * @implemented */ -LONG WINAPI -RegQueryValueExA(HKEY hKey,
- LPCSTR lpValueName,
- LPDWORD lpReserved,
- LPDWORD lpType,
- LPBYTE lpData,
- LPDWORD lpcbData)
-{
- UNICODE_STRING ValueName;
- UNICODE_STRING ValueData;
- ANSI_STRING AnsiString;
- LONG ErrorCode;
- DWORD Length;
- DWORD Type;
- TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
- hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
- if (lpData != NULL && lpcbData == NULL)
- {
- return ERROR_INVALID_PARAMETER;
- }
- if (lpData)
- {
- ValueData.Length = 0;
- ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR);
- ValueData.Buffer = RtlAllocateHeap(ProcessHeap,
- 0,
- ValueData.MaximumLength);
- if (!ValueData.Buffer)
- {
- return ERROR_OUTOFMEMORY;
- }
- }
- else
- {
- ValueData.Buffer = NULL;
- ValueData.Length = 0;
- ValueData.MaximumLength = 0;
- if (lpcbData)
- *lpcbData = 0;
- }
- RtlCreateUnicodeStringFromAsciiz(&ValueName,
- (LPSTR)lpValueName);
- Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
- ErrorCode = RegQueryValueExW(hKey,
- ValueName.Buffer,
- lpReserved,
- &Type,
- (lpData == NULL) ? NULL :
(LPBYTE)ValueData.Buffer,
- &Length);
- TRACE("ErrorCode %lu\n", ErrorCode);
- RtlFreeUnicodeString(&ValueName);
- if (ErrorCode == ERROR_SUCCESS ||
- ErrorCode == ERROR_MORE_DATA)
- {
- if (lpType != NULL)
- {
- *lpType = Type;
- }
- if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type ==
REG_EXPAND_SZ))
- {
- if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+LSTATUS WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD
reserved, LPDWORD type,
- LPBYTE data, LPDWORD count )
+{
- NTSTATUS status;
- ANSI_STRING nameA;
- 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 );
- TRACE("(%p,%s,%p,%p,%p,%p=%d)\n",
- hkey, debugstr_a(name), reserved, type, data, count, count ?
*count : 0 );
- if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
- status = MapDefaultKey( (PHANDLE)&hkey, hkey);
- if (!NT_SUCCESS(status))
- {
- return RtlNtStatusToDosError(status);
- }
- if (count) datalen = *count;
- if (!data && count) *count = 0;
- /* this matches Win9x behaviour - NT sets *type to a random value */
- if (type) *type = REG_NONE;
- RtlInitAnsiString( &nameA, name );
- if ((status = RtlAnsiStringToUnicodeString(
&NtCurrentTeb()->StaticUnicodeString,
- &nameA, FALSE )))
- return RtlNtStatusToDosError(status);
- status = NtQueryValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString,
- KeyValuePartialInformation, buffer,
sizeof(buffer), &total_size );
- if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
- /* 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))
- {
- /* 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
)))
{
- RtlInitAnsiString(&AnsiString, NULL);
- AnsiString.Buffer = (LPSTR)lpData;
- AnsiString.MaximumLength = *lpcbData;
- ValueData.Length = Length;
- ValueData.MaximumLength = ValueData.Length +
sizeof(WCHAR);
- RtlUnicodeStringToAnsiString(&AnsiString, &ValueData,
FALSE);
- status = STATUS_NO_MEMORY;
- goto done;
}
- Length = Length / sizeof(WCHAR);
- }
- else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
- {
- if (*lpcbData < Length)
- info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
- status = NtQueryValueKey( hkey,
&NtCurrentTeb()->StaticUnicodeString,
- KeyValuePartialInformation, buf_ptr,
total_size, &total_size );
- }
- if (status) goto done;
- if (is_string(info->Type))
- {
- DWORD len;
- RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr +
info_size),
- total_size - info_size );
- if (data && len)
{
- ErrorCode = ERROR_MORE_DATA;
- 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;
- }
}
- else
- {
- RtlMoveMemory(lpData, ValueData.Buffer, Length);
- }
- }
- if (lpcbData != NULL)
- {
- *lpcbData = Length;
- }
- }
- if (ValueData.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
- }
- return ErrorCode;
- 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 );
- }
- }
- else status = STATUS_SUCCESS;
- if (type) *type = info->Type;
- if (count) *count = total_size - info_size;
- done:
- if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
- return RtlNtStatusToDosError(status);
}
@@ -4098,7 +4084,6 @@ (count && data) ? *count : 0 );
if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
- //if (!(hkey = get_special_root_hkey( hkey ))) return
ERROR_INVALID_HANDLE;
status = MapDefaultKey(&hkey, hkeyorg); if (!NT_SUCCESS(status)) @@ -4162,93 +4147,27 @@ * * @implemented */ -LONG WINAPI -RegQueryValueA(HKEY hKey,
- LPCSTR lpSubKey,
- LPSTR lpValue,
- PLONG lpcbValue)
-{
- WCHAR SubKeyNameBuffer[MAX_PATH+1];
- UNICODE_STRING SubKeyName;
- UNICODE_STRING Value;
- ANSI_STRING AnsiString;
- LONG ValueSize;
- LONG ErrorCode;
- TRACE("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n",
- hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
- if (lpValue != NULL &&
- lpcbValue == NULL)
- {
- return ERROR_INVALID_PARAMETER;
- }
- RtlInitUnicodeString(&SubKeyName,
- NULL);
- RtlInitUnicodeString(&Value,
- NULL);
- if (lpSubKey != NULL &&
- strlen(lpSubKey) != 0)
- {
- RtlInitAnsiString(&AnsiString,
- (LPSTR)lpSubKey);
- SubKeyName.Buffer = &SubKeyNameBuffer[0];
- SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
- RtlAnsiStringToUnicodeString(&SubKeyName,
- &AnsiString,
- FALSE);
- }
- if (lpValue != NULL)
- {
- ValueSize = *lpcbValue * sizeof(WCHAR);
- Value.MaximumLength = ValueSize;
- Value.Buffer = RtlAllocateHeap(ProcessHeap,
- 0,
- ValueSize);
- if (Value.Buffer == NULL)
- {
- return ERROR_OUTOFMEMORY;
- }
- }
- else
- {
- ValueSize = 0;
- }
- ErrorCode = RegQueryValueW(hKey,
- (LPCWSTR)SubKeyName.Buffer,
- Value.Buffer,
- &ValueSize);
- if (ErrorCode == ERROR_SUCCESS)
- {
- if (lpValue != NULL)
- {
- Value.Length = ValueSize;
- RtlInitAnsiString(&AnsiString,
- NULL);
- AnsiString.Buffer = lpValue;
- AnsiString.MaximumLength = *lpcbValue;
- RtlUnicodeStringToAnsiString(&AnsiString,
- &Value,
- FALSE);
- *lpcbValue = ValueSize;
- }
- else if (lpcbValue != NULL)
- {
- *lpcbValue = ValueSize;
- }
- }
- if (Value.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- Value.Buffer);
- }
- return ErrorCode;
+LSTATUS WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG
count )
+{
- DWORD ret;
- HKEY subkey = hkey;
- TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_a(name), data, count ? *count
: 0 );
- if (name && name[0])
- {
- if ((ret = RegOpenKeyA( hkey, name, &subkey )) != ERROR_SUCCESS)
return ret;
- }
- ret = RegQueryValueExA( subkey, NULL, NULL, NULL, (LPBYTE)data,
(LPDWORD)count );
- if (subkey != hkey) RegCloseKey( subkey );
- if (ret == ERROR_FILE_NOT_FOUND)
- {
- /* return empty string if default value not found */
- if (data) *data = 0;
- if (count) *count = 1;
- ret = ERROR_SUCCESS;
- }
- return ret;
}
@@ -4257,75 +4176,42 @@ * * @implemented */ -LONG WINAPI -RegQueryValueW(HKEY hKey,
- LPCWSTR lpSubKey,
- LPWSTR lpValue,
- PLONG lpcbValue)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING SubKeyString;
- HANDLE KeyHandle;
- HANDLE RealKey;
- LONG ErrorCode;
- BOOL CloseRealKey;
- NTSTATUS Status;
- TRACE("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n",
- hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
- if (hKey == NULL)
+LSTATUS WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data,
LPLONG count )
+{
- DWORD ret;
- HKEY subkey = hkey;
- TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_w(name), data, count ? *count
: 0 );
- if (hkey == NULL)
{ return ERROR_INVALID_HANDLE; }
- Status = MapDefaultKey(&KeyHandle,
- hKey);
- if (!NT_SUCCESS(Status))
- {
- return RtlNtStatusToDosError(Status);
- }
- if (lpSubKey != NULL &&
- wcslen(lpSubKey) != 0)
- {
- RtlInitUnicodeString(&SubKeyString,
- (LPWSTR)lpSubKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &SubKeyString,
- OBJ_CASE_INSENSITIVE,
- KeyHandle,
- NULL);
- Status = NtOpenKey(&RealKey,
- KEY_QUERY_VALUE,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- ErrorCode = RtlNtStatusToDosError(Status);
- goto Cleanup;
- }
- CloseRealKey = TRUE;
- }
- else
- {
- RealKey = hKey;
- CloseRealKey = FALSE;
- }
- ErrorCode = RegQueryValueExW(RealKey,
- NULL,
- NULL,
- NULL,
- (LPBYTE)lpValue,
- (LPDWORD)lpcbValue);
- if (CloseRealKey)
- {
- NtClose(RealKey);
- }
-Cleanup:
- ClosePredefKey(KeyHandle);
- return ErrorCode;
- if (name && name[0])
- {
- ret = RegOpenKeyW( hkey, name, &subkey);
- if (ret != ERROR_SUCCESS)
- {
- return ret;
- }
- }
- ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data,
(LPDWORD)count );
- if (subkey != hkey)
- {
- RegCloseKey( subkey );
- }
- if (ret == ERROR_FILE_NOT_FOUND)
- {
- /* return empty string if default value not found */
- if (data)
- *data = 0;
- if (count)
- *count = sizeof(WCHAR);
- ret = ERROR_SUCCESS;
- }
- return ret;
}
@@ -4806,86 +4692,43 @@ * * @implemented */ -LONG WINAPI -RegSetValueExA(HKEY hKey,
- LPCSTR lpValueName,
- DWORD Reserved,
- DWORD dwType,
- CONST BYTE* lpData,
- DWORD cbData)
-{
- UNICODE_STRING ValueName;
- LPWSTR pValueName;
- ANSI_STRING AnsiString;
- UNICODE_STRING Data;
- LONG ErrorCode;
- LPBYTE pData;
- DWORD DataSize;
- if (lpValueName != NULL &&
- strlen(lpValueName) != 0)
- {
- RtlCreateUnicodeStringFromAsciiz(&ValueName,
- (PSTR)lpValueName);
- }
- else
- {
- ValueName.Buffer = NULL;
- }
- pValueName = (LPWSTR)ValueName.Buffer;
- if (((dwType == REG_SZ) ||
- (dwType == REG_MULTI_SZ) ||
- (dwType == REG_EXPAND_SZ)) &&
- (cbData != 0))
- {
- /* NT adds one if the caller forgot the NULL-termination
character */
- if (lpData[cbData - 1] != '\0')
- {
- cbData++;
- }
- RtlInitAnsiString(&AnsiString,
- NULL);
- AnsiString.Buffer = (PSTR)lpData;
- AnsiString.Length = cbData - 1;
- AnsiString.MaximumLength = cbData;
- RtlAnsiStringToUnicodeString(&Data,
- &AnsiString,
- TRUE);
- pData = (LPBYTE)Data.Buffer;
- DataSize = cbData * sizeof(WCHAR);
- }
- else
- {
- RtlInitUnicodeString(&Data,
- NULL);
- pData = (LPBYTE)lpData;
- DataSize = cbData;
- }
- ErrorCode = RegSetValueExW(hKey,
- pValueName,
- Reserved,
- dwType,
- pData,
- DataSize);
- if (pValueName != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- ValueName.Buffer);
- }
- if (Data.Buffer != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- Data.Buffer);
- }
- return ErrorCode;
+LSTATUS WINAPI RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved,
DWORD type,
- CONST BYTE *data, DWORD count )
+{
- ANSI_STRING nameA;
- WCHAR *dataW = NULL;
- NTSTATUS status;
- if (count && is_string(type))
- {
- /* if user forgot to count terminating null, add it (yes NT does
this) */
- if (data[count-1] && !data[count]) count++;
- }
- status = MapDefaultKey( (PHANDLE)&hkey, hkey);
- if (!NT_SUCCESS(status))
- {
- return RtlNtStatusToDosError(status);
- }
- if (is_string( type )) /* need to convert to Unicode */
- {
- DWORD lenW;
- RtlMultiByteToUnicodeSize( &lenW, (const char *)data, count );
- if (!(dataW = HeapAlloc( GetProcessHeap(), 0, lenW ))) return
ERROR_OUTOFMEMORY;
- RtlMultiByteToUnicodeN( dataW, lenW, NULL, (const char *)data,
count );
- count = lenW;
- data = (BYTE *)dataW;
- }
- RtlInitAnsiString( &nameA, name );
- if (!(status = RtlAnsiStringToUnicodeString(
&NtCurrentTeb()->StaticUnicodeString,
- &nameA, FALSE )))
- {
- status = NtSetValueKey( hkey,
&NtCurrentTeb()->StaticUnicodeString, 0, type, (PVOID)data, count );
- }
- HeapFree( GetProcessHeap(), 0, dataW );
- return RtlNtStatusToDosError( status );
}
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
LOL!
Wonderfully example! wine'age coding principles 101! Then, ejecting a bash script into it as well, Good catch Ged!
Amazing!, James
On Sun, May 24, 2009 at 9:19 AM, Alex Ionescu ionucu@videotron.ca wrote:
Lol, Ged...this is Wine, remember?
It works like this:
Ntoskrnl calls user32, which calls kernel32, which calls ntdll, which then calls msi.
Msi's A function then calls ntoskrnl's W function, which calls back into gdi32's A function (after converting all the parameters).
Best regards, Alex Ionescu