FYI, Local* or Base functions are typically always W.

Best regards,
Alex Ionescu



On Sun, May 24, 2009 at 6:13 PM, Ged <[email protected]> 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: [email protected] [mailto:[email protected]] 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 <[email protected]> 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: [email protected] [mailto:[email protected]]
> On Behalf Of [email protected]
>> Sent: 24 May 2009 09:45
>> To: [email protected]
>> 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
>> [email protected]
>> http://www.reactos.org/mailman/listinfo/ros-dev
>>
>
> _______________________________________________
> Ros-dev mailing list
> [email protected]
> http://www.reactos.org/mailman/listinfo/ros-dev
>
>
> _______________________________________________
> Ros-dev mailing list
> [email protected]
> http://www.reactos.org/mailman/listinfo/ros-dev
>

_______________________________________________
Ros-dev mailing list
[email protected]
http://www.reactos.org/mailman/listinfo/ros-dev

Reply via email to