Janitorial dlls/advapi32/registry.c W->A cleanup

Dmitry Timoshkov dmitry at baikal.ru
Fri Mar 7 00:18:53 CST 2003


"Tony Lambregts" <tony_lambregts at telusplanet.net> wrote:

> For the benefit of those of us who are a little thick could someone 
> explain what that means. I understand that the TEB has TlsSlots for 
> local storage but.. there is so much I do not understand. A little help...

The TEB (see include/thread.h) has a specially reserved buffer (StaticUnicodeBuffer)
with the size of MAX_PATH+1 unicode characters and UNICODE_STRING structure
(StaticUnicodeString) pointing to that buffer. That space could be used for
in order to speed up things by avoiding memory allocation.

Here is a sample implementation of CreateDirectoryA that uses TEB static
unicode buffer. I have created a helper function asciiz_to_unicode which
takes an ASCIIZ string, converts it to unicode and returns a pointer to
the UNICODE_STRING structure (i.e. it also returns the size of the resulting
unicode string). I think that using a helper can save a bit of memory
isolating a commonly used code into a single place, and makes it simpler
 to modify the code if we will later decide to change the implementation.

Feel free to use it as a guide for converting ANSI file APIs to use
that scheme.

#include "winbase.h"
#include "winerror.h"
#include "winternl.h"
#include "thread.h"

/*
 * asciiz_to_unicode (internal)
 * Does not check for NULL. This is a duty of a higher level API.
 */
UNICODE_STRING *asciiz_to_unicode(LPCSTR src)
{
    UNICODE_STRING *unicode = &NtCurrentTeb()->StaticUnicodeString;
    STRING ansi;
    NTSTATUS status;

    RtlInitAnsiString(&ansi, src);
    status = RtlAnsiStringToUnicodeString(unicode, &ansi, FALSE);
    if (!status) return unicode;

    if (status == STATUS_BUFFER_OVERFLOW)
        SetLastError(ERROR_FILENAME_EXCED_RANGE);
    else
        SetLastError(RtlNtStatusToDosError(status));
    return NULL;
}

/***********************************************************************
 *           CreateDirectoryA   (KERNEL32.@)
 */
BOOL WINAPI CreateDirectoryA( LPCSTR path,
                                  LPSECURITY_ATTRIBUTES lpsecattribs )
{
    UNICODE_STRING *pathW;

    if (!path || !*path)
    {
        SetLastError(ERROR_PATH_NOT_FOUND);
        return FALSE;
    }

    pathW = asciiz_to_unicode(path);
    if (pathW) return CreateDirectoryW(pathW->Buffer, lpsecattribs);
    return FALSE;
}

-- 
Dmitry.






More information about the wine-devel mailing list