1fcd83242STimo Kreuzer /*
2fcd83242STimo Kreuzer  * COPYRIGHT:       See COPYING in the top level directory
3fcd83242STimo Kreuzer  * PROJECT:         ReactOS system libraries
4fcd83242STimo Kreuzer  * FILE:            dll/win32/kernel32/client/file/fileutils.c
5fcd83242STimo Kreuzer  * PURPOSE:         File utility function shared with kernel32_vista
6fcd83242STimo Kreuzer  * PROGRAMMER:      Taken from wine
7fcd83242STimo Kreuzer  */
8fcd83242STimo Kreuzer 
9fcd83242STimo Kreuzer /* INCLUDES *****************************************************************/
10fcd83242STimo Kreuzer 
11fcd83242STimo Kreuzer #include <k32.h>
12fcd83242STimo Kreuzer #define NDEBUG
13fcd83242STimo Kreuzer #include <debug.h>
14fcd83242STimo Kreuzer 
15fcd83242STimo Kreuzer /* FUNCTIONS ****************************************************************/
16fcd83242STimo Kreuzer 
17fcd83242STimo Kreuzer PWCHAR
FilenameA2W(LPCSTR NameA,BOOL alloc)18fcd83242STimo Kreuzer FilenameA2W(LPCSTR NameA, BOOL alloc)
19fcd83242STimo Kreuzer {
20fcd83242STimo Kreuzer    ANSI_STRING str;
21fcd83242STimo Kreuzer    UNICODE_STRING strW;
22fcd83242STimo Kreuzer    PUNICODE_STRING pstrW;
23fcd83242STimo Kreuzer    NTSTATUS Status;
24fcd83242STimo Kreuzer 
25fcd83242STimo Kreuzer    //ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
26fcd83242STimo Kreuzer    ASSERT(NtCurrentTeb()->StaticUnicodeString.MaximumLength == sizeof(NtCurrentTeb()->StaticUnicodeBuffer));
27fcd83242STimo Kreuzer 
28fcd83242STimo Kreuzer    RtlInitAnsiString(&str, NameA);
29fcd83242STimo Kreuzer    pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
30fcd83242STimo Kreuzer 
31*d8b5c00cSTimo Kreuzer    if (AreFileApisANSI())
32fcd83242STimo Kreuzer         Status= RtlAnsiStringToUnicodeString( pstrW, &str, (BOOLEAN)alloc );
33fcd83242STimo Kreuzer    else
34fcd83242STimo Kreuzer         Status= RtlOemStringToUnicodeString( pstrW, &str, (BOOLEAN)alloc );
35fcd83242STimo Kreuzer 
36fcd83242STimo Kreuzer     if (NT_SUCCESS(Status))
37fcd83242STimo Kreuzer        return pstrW->Buffer;
38fcd83242STimo Kreuzer 
39fcd83242STimo Kreuzer     if (Status== STATUS_BUFFER_OVERFLOW)
40fcd83242STimo Kreuzer         SetLastError( ERROR_FILENAME_EXCED_RANGE );
41fcd83242STimo Kreuzer     else
42fcd83242STimo Kreuzer         BaseSetLastNTError(Status);
43fcd83242STimo Kreuzer 
44fcd83242STimo Kreuzer     return NULL;
45fcd83242STimo Kreuzer }
46fcd83242STimo Kreuzer 
47fcd83242STimo Kreuzer 
48fcd83242STimo Kreuzer /*
49fcd83242STimo Kreuzer No copy/conversion is done if the dest. buffer is too small.
50fcd83242STimo Kreuzer 
51fcd83242STimo Kreuzer Returns:
52fcd83242STimo Kreuzer    Success: number of TCHARS copied into dest. buffer NOT including nullterm
53fcd83242STimo Kreuzer    Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
54fcd83242STimo Kreuzer */
55fcd83242STimo Kreuzer DWORD
FilenameU2A_FitOrFail(LPSTR DestA,INT destLen,PUNICODE_STRING SourceU)56fcd83242STimo Kreuzer FilenameU2A_FitOrFail(
57fcd83242STimo Kreuzer    LPSTR  DestA,
58fcd83242STimo Kreuzer    INT destLen, /* buffer size in TCHARS incl. nullchar */
59fcd83242STimo Kreuzer    PUNICODE_STRING SourceU
60fcd83242STimo Kreuzer    )
61fcd83242STimo Kreuzer {
62fcd83242STimo Kreuzer    DWORD ret;
63fcd83242STimo Kreuzer 
64fcd83242STimo Kreuzer    /* destLen should never exceed MAX_PATH */
65fcd83242STimo Kreuzer    if (destLen > MAX_PATH) destLen = MAX_PATH;
66fcd83242STimo Kreuzer 
67*d8b5c00cSTimo Kreuzer    ret = AreFileApisANSI() ? RtlUnicodeStringToAnsiSize(SourceU) : RtlUnicodeStringToOemSize(SourceU);
68fcd83242STimo Kreuzer    /* ret incl. nullchar */
69fcd83242STimo Kreuzer 
70fcd83242STimo Kreuzer    if (DestA && (INT)ret <= destLen)
71fcd83242STimo Kreuzer    {
72fcd83242STimo Kreuzer       ANSI_STRING str;
73fcd83242STimo Kreuzer 
74fcd83242STimo Kreuzer       str.Buffer = DestA;
75fcd83242STimo Kreuzer       str.MaximumLength = (USHORT)destLen;
76fcd83242STimo Kreuzer 
77fcd83242STimo Kreuzer 
78*d8b5c00cSTimo Kreuzer       if (AreFileApisANSI())
79fcd83242STimo Kreuzer          RtlUnicodeStringToAnsiString(&str, SourceU, FALSE );
80fcd83242STimo Kreuzer       else
81fcd83242STimo Kreuzer          RtlUnicodeStringToOemString(&str, SourceU, FALSE );
82fcd83242STimo Kreuzer 
83fcd83242STimo Kreuzer       ret = str.Length;  /* SUCCESS: length without terminating 0 */
84fcd83242STimo Kreuzer    }
85fcd83242STimo Kreuzer 
86fcd83242STimo Kreuzer    return ret;
87fcd83242STimo Kreuzer }
88fcd83242STimo Kreuzer 
89fcd83242STimo Kreuzer 
90fcd83242STimo Kreuzer /*
91fcd83242STimo Kreuzer No copy/conversion is done if the dest. buffer is too small.
92fcd83242STimo Kreuzer 
93fcd83242STimo Kreuzer Returns:
94fcd83242STimo Kreuzer    Success: number of TCHARS copied into dest. buffer NOT including nullterm
95fcd83242STimo Kreuzer    Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
96fcd83242STimo Kreuzer */
97fcd83242STimo Kreuzer DWORD
FilenameW2A_FitOrFail(LPSTR DestA,INT destLen,LPCWSTR SourceW,INT sourceLen)98fcd83242STimo Kreuzer FilenameW2A_FitOrFail(
99fcd83242STimo Kreuzer    LPSTR  DestA,
100fcd83242STimo Kreuzer    INT destLen, /* buffer size in TCHARS incl. nullchar */
101fcd83242STimo Kreuzer    LPCWSTR SourceW,
102fcd83242STimo Kreuzer    INT sourceLen /* buffer size in TCHARS incl. nullchar */
103fcd83242STimo Kreuzer    )
104fcd83242STimo Kreuzer {
105fcd83242STimo Kreuzer    UNICODE_STRING strW;
106fcd83242STimo Kreuzer 
107fcd83242STimo Kreuzer    if (sourceLen < 0) sourceLen = wcslen(SourceW) + 1;
108fcd83242STimo Kreuzer 
109fcd83242STimo Kreuzer    strW.Buffer = (PWCHAR)SourceW;
110fcd83242STimo Kreuzer    strW.MaximumLength = sourceLen * sizeof(WCHAR);
111fcd83242STimo Kreuzer    strW.Length = strW.MaximumLength - sizeof(WCHAR);
112fcd83242STimo Kreuzer 
113fcd83242STimo Kreuzer    return FilenameU2A_FitOrFail(DestA, destLen, &strW);
114fcd83242STimo Kreuzer }
115fcd83242STimo Kreuzer 
116fcd83242STimo Kreuzer 
117fcd83242STimo Kreuzer /*
118fcd83242STimo Kreuzer Return: num. TCHARS copied into dest including nullterm
119fcd83242STimo Kreuzer */
120fcd83242STimo Kreuzer DWORD
FilenameA2W_N(LPWSTR dest,INT destlen,LPCSTR src,INT srclen)121fcd83242STimo Kreuzer FilenameA2W_N(
122fcd83242STimo Kreuzer    LPWSTR dest,
123fcd83242STimo Kreuzer    INT destlen, /* buffer size in TCHARS incl. nullchar */
124fcd83242STimo Kreuzer    LPCSTR src,
125fcd83242STimo Kreuzer    INT srclen /* buffer size in TCHARS incl. nullchar */
126fcd83242STimo Kreuzer    )
127fcd83242STimo Kreuzer {
128fcd83242STimo Kreuzer     DWORD ret;
129fcd83242STimo Kreuzer 
130fcd83242STimo Kreuzer     if (srclen < 0) srclen = strlen( src ) + 1;
131fcd83242STimo Kreuzer 
132*d8b5c00cSTimo Kreuzer     if (AreFileApisANSI())
133fcd83242STimo Kreuzer         RtlMultiByteToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen  );
134fcd83242STimo Kreuzer     else
135fcd83242STimo Kreuzer         RtlOemToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen );
136fcd83242STimo Kreuzer 
137fcd83242STimo Kreuzer     if (ret) dest[(ret/sizeof(WCHAR))-1]=0;
138fcd83242STimo Kreuzer 
139fcd83242STimo Kreuzer     return ret/sizeof(WCHAR);
140fcd83242STimo Kreuzer }
141fcd83242STimo Kreuzer 
142fcd83242STimo Kreuzer /*
143fcd83242STimo Kreuzer Return: num. TCHARS copied into dest including nullterm
144fcd83242STimo Kreuzer */
145fcd83242STimo Kreuzer DWORD
FilenameW2A_N(LPSTR dest,INT destlen,LPCWSTR src,INT srclen)146fcd83242STimo Kreuzer FilenameW2A_N(
147fcd83242STimo Kreuzer    LPSTR dest,
148fcd83242STimo Kreuzer    INT destlen, /* buffer size in TCHARS incl. nullchar */
149fcd83242STimo Kreuzer    LPCWSTR src,
150fcd83242STimo Kreuzer    INT srclen /* buffer size in TCHARS incl. nullchar */
151fcd83242STimo Kreuzer    )
152fcd83242STimo Kreuzer {
153fcd83242STimo Kreuzer     DWORD ret;
154fcd83242STimo Kreuzer 
155fcd83242STimo Kreuzer     if (srclen < 0) srclen = wcslen( src ) + 1;
156fcd83242STimo Kreuzer 
157*d8b5c00cSTimo Kreuzer     if (AreFileApisANSI())
158fcd83242STimo Kreuzer         RtlUnicodeToMultiByteN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR));
159fcd83242STimo Kreuzer     else
160fcd83242STimo Kreuzer         RtlUnicodeToOemN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR) );
161fcd83242STimo Kreuzer 
162fcd83242STimo Kreuzer     if (ret) dest[ret-1]=0;
163fcd83242STimo Kreuzer 
164fcd83242STimo Kreuzer     return ret;
165fcd83242STimo Kreuzer }
166fcd83242STimo Kreuzer 
167fcd83242STimo Kreuzer /* EOF */
168