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