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