[REISERFS]
[reactos.git] / reactos / drivers / filesystems / reiserfs / src / misc.c
1 /*
2 * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3 * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
4 * FILE: misc.c
5 * PURPOSE:
6 * PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
7 * HOMEPAGE:
8 * UPDATE HISTORY:
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include "rfsd.h"
14
15 /* GLOBALS ***************************************************************/
16
17 extern PRFSD_GLOBAL RfsdGlobal;
18
19 /* DEFINITIONS *************************************************************/
20
21 #ifdef ALLOC_PRAGMA
22 #pragma alloc_text(PAGE, RfsdLog2)
23 #pragma alloc_text(PAGE, RfsdSysTime)
24 #pragma alloc_text(PAGE, RfsdInodeTime)
25 #pragma alloc_text(PAGE, RfsdOEMToUnicode)
26 #pragma alloc_text(PAGE, RfsdUnicodeToOEM)
27 #endif
28
29 ULONG
30 RfsdLog2(ULONG Value)
31 {
32 ULONG Order = 0;
33
34 PAGED_CODE();
35
36 ASSERT(Value > 0);
37
38 while (Value) {
39 Order++;
40 Value >>= 1;
41 }
42
43 return (Order - 1);
44 }
45
46 LARGE_INTEGER
47 RfsdSysTime (IN ULONG i_time)
48 {
49 LARGE_INTEGER SysTime;
50
51 PAGED_CODE();
52
53 RtlSecondsSince1970ToTime(i_time, &SysTime);
54
55 return SysTime;
56 }
57
58 ULONG
59 RfsdInodeTime (IN LARGE_INTEGER SysTime)
60 {
61 ULONG RfsdTime;
62
63 PAGED_CODE();
64
65 RtlTimeToSecondsSince1970(&SysTime, &RfsdTime);
66
67 return RfsdTime;
68 }
69
70 ULONG
71 RfsdMbsToUnicode(
72 IN OUT PUNICODE_STRING Unicode,
73 IN PANSI_STRING Mbs )
74 {
75 ULONG Length = 0;
76 int i, mbc = 0;
77 WCHAR uc;
78
79 /* Count the length of the resulting Unicode. */
80 for (i = 0; i < Mbs->Length; i += mbc) {
81
82 mbc = PAGE_TABLE->char2uni(
83 (PUCHAR)&(Mbs->Buffer[i]),
84 Mbs->Length - i,
85 &uc
86 );
87
88 if (mbc <= 0) {
89
90 /* Invalid character. */
91 return 0;
92 }
93
94 Length += 2;
95 }
96
97 if (Unicode) {
98 if (Unicode->MaximumLength < Length) {
99
100 DbgBreak();
101 return 0;
102 }
103
104 Unicode->Length = 0;
105 mbc = 0;
106
107 for (i = 0; i < Mbs->Length; i += mbc) {
108
109 mbc = PAGE_TABLE->char2uni(
110 (PUCHAR)&(Mbs->Buffer[i]),
111 Mbs->Length - i,
112 &uc
113 );
114 Unicode->Buffer[Unicode->Length/2] = uc;
115
116 Unicode->Length += 2;
117 }
118 }
119
120 return Length;
121 }
122
123 ULONG
124 RfsdUnicodeToMbs (
125 IN OUT PANSI_STRING Mbs,
126 IN PUNICODE_STRING Unicode)
127 {
128 ULONG Length = 0;
129 UCHAR mbs[0x10];
130 int i, mbc;
131
132 /* Count the length of the resulting mbc-8. */
133 for (i = 0; i < (Unicode->Length / 2); i++) {
134
135 RtlZeroMemory(mbs, 0x10);
136 mbc = PAGE_TABLE->uni2char(
137 Unicode->Buffer[i],
138 mbs,
139 0x10
140 );
141
142 if (mbc <= 0) {
143
144 /* Invalid character. */
145 return 0;
146 }
147
148 Length += mbc;
149 }
150
151 if (Mbs) {
152
153 if (Mbs->MaximumLength < Length) {
154
155 DbgBreak();
156 return 0;
157 }
158
159 Mbs->Length = 0;
160
161 for (i = 0; i < (Unicode->Length / 2); i++) {
162
163 mbc = PAGE_TABLE->uni2char(
164 Unicode->Buffer[i],
165 mbs,
166 0x10
167 );
168
169 RtlCopyMemory(
170 (PUCHAR)&(Mbs->Buffer[Mbs->Length]),
171 &mbs[0],
172 mbc
173 );
174
175 Mbs->Length += (USHORT)mbc;
176 }
177 }
178
179 return Length;
180 }
181
182 ULONG
183 RfsdOEMToUnicodeSize(
184 IN PANSI_STRING Oem
185 )
186 {
187 if (PAGE_TABLE) {
188 return RfsdMbsToUnicode(NULL, Oem);
189 }
190
191 return RtlOemStringToCountedUnicodeSize(Oem);
192 }
193
194 NTSTATUS
195 RfsdOEMToUnicode(
196 IN OUT PUNICODE_STRING Unicode,
197 IN POEM_STRING Oem )
198 {
199 NTSTATUS Status;
200
201 PAGED_CODE();
202
203 if (PAGE_TABLE) {
204 Status = RfsdMbsToUnicode(Unicode, Oem);
205
206 if (Status == Unicode->Length) {
207 Status = STATUS_SUCCESS;
208 } else {
209 Status = STATUS_UNSUCCESSFUL;
210 }
211
212 goto errorout;
213 }
214
215
216 Status = RtlOemStringToUnicodeString(
217 Unicode,
218 Oem,
219 FALSE );
220
221 if (!NT_SUCCESS(Status))
222 {
223 DbgBreak();
224 goto errorout;
225 }
226
227 errorout:
228
229 return Status;
230 }
231
232 ULONG
233 RfsdUnicodeToOEMSize(
234 IN PUNICODE_STRING Unicode
235 )
236 {
237 if (PAGE_TABLE) {
238
239 return RfsdUnicodeToMbs(NULL, Unicode);
240 }
241
242 return RtlxUnicodeStringToOemSize(Unicode);
243 }
244
245 NTSTATUS
246 RfsdUnicodeToOEM (
247 IN OUT POEM_STRING Oem,
248 IN PUNICODE_STRING Unicode)
249 {
250 NTSTATUS Status;
251
252 PAGED_CODE();
253
254 if (PAGE_TABLE) {
255
256 Status = RfsdUnicodeToMbs(Oem, Unicode);
257
258 if (Status == Oem->Length) {
259 Status = STATUS_SUCCESS;
260 } else {
261 Status = STATUS_UNSUCCESSFUL;
262 }
263
264 goto errorout;
265 }
266
267 Status = RtlUnicodeStringToOemString(
268 Oem,
269 Unicode,
270 FALSE );
271
272 if (!NT_SUCCESS(Status))
273 {
274 DbgBreak();
275 goto errorout;
276 }
277
278 errorout:
279
280 return Status;
281 }