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 <gedmur...@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-boun...@reactos.org [mailto:ros-diffs-boun...@reactos.org] On 
> Behalf Of cwitt...@svn.reactos.org
> Sent: 24 May 2009 09:45
> To: ros-di...@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

Reply via email to