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