Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / dll / shellext / shellbtrfs / reactos.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: BtrFS FSD for ReactOS
4 * FILE: dll/shellext/shellbtrfs/reactos.cpp
5 * PURPOSE: ReactOS glue for Win8.1
6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7 */
8
9 #include "shellext.h"
10 #include <initguid.h>
11 #include <ntddstor.h>
12 #include <ndk/rtlfuncs.h>
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 /* So that we can link */
18 DEFINE_GUID(CLSID_WICImagingFactory, 0xcacaf262,0x9370,0x4615,0xa1,0x3b,0x9f,0x55,0x39,0xda,0x4c,0x0a);
19
20 /* Copied from ntoskrnl_vista */
21 NTSTATUS WINAPI RtlUTF8ToUnicodeN(PWSTR uni_dest, ULONG uni_bytes_max,
22 PULONG uni_bytes_written,
23 PCCH utf8_src, ULONG utf8_bytes)
24 {
25 NTSTATUS status;
26 ULONG i, j;
27 ULONG written;
28 ULONG ch;
29 ULONG utf8_trail_bytes;
30 WCHAR utf16_ch[3];
31 ULONG utf16_ch_len;
32
33 if (!utf8_src)
34 return STATUS_INVALID_PARAMETER_4;
35 if (!uni_bytes_written)
36 return STATUS_INVALID_PARAMETER;
37
38 written = 0;
39 status = STATUS_SUCCESS;
40
41 for (i = 0; i < utf8_bytes; i++)
42 {
43 /* read UTF-8 lead byte */
44 ch = (BYTE)utf8_src[i];
45 utf8_trail_bytes = 0;
46 if (ch >= 0xf5)
47 {
48 ch = 0xfffd;
49 status = STATUS_SOME_NOT_MAPPED;
50 }
51 else if (ch >= 0xf0)
52 {
53 ch &= 0x07;
54 utf8_trail_bytes = 3;
55 }
56 else if (ch >= 0xe0)
57 {
58 ch &= 0x0f;
59 utf8_trail_bytes = 2;
60 }
61 else if (ch >= 0xc2)
62 {
63 ch &= 0x1f;
64 utf8_trail_bytes = 1;
65 }
66 else if (ch >= 0x80)
67 {
68 /* overlong or trail byte */
69 ch = 0xfffd;
70 status = STATUS_SOME_NOT_MAPPED;
71 }
72
73 /* read UTF-8 trail bytes */
74 if (i + utf8_trail_bytes < utf8_bytes)
75 {
76 for (j = 0; j < utf8_trail_bytes; j++)
77 {
78 if ((utf8_src[i + 1] & 0xc0) == 0x80)
79 {
80 ch <<= 6;
81 ch |= utf8_src[i + 1] & 0x3f;
82 i++;
83 }
84 else
85 {
86 ch = 0xfffd;
87 utf8_trail_bytes = 0;
88 status = STATUS_SOME_NOT_MAPPED;
89 break;
90 }
91 }
92 }
93 else
94 {
95 ch = 0xfffd;
96 utf8_trail_bytes = 0;
97 status = STATUS_SOME_NOT_MAPPED;
98 i = utf8_bytes;
99 }
100
101 /* encode ch as UTF-16 */
102 if ((ch > 0x10ffff) ||
103 (ch >= 0xd800 && ch <= 0xdfff) ||
104 (utf8_trail_bytes == 2 && ch < 0x00800) ||
105 (utf8_trail_bytes == 3 && ch < 0x10000))
106 {
107 /* invalid codepoint or overlong encoding */
108 utf16_ch[0] = 0xfffd;
109 utf16_ch[1] = 0xfffd;
110 utf16_ch[2] = 0xfffd;
111 utf16_ch_len = utf8_trail_bytes;
112 status = STATUS_SOME_NOT_MAPPED;
113 }
114 else if (ch >= 0x10000)
115 {
116 /* surrogate pair */
117 ch -= 0x010000;
118 utf16_ch[0] = 0xd800 + (ch >> 10 & 0x3ff);
119 utf16_ch[1] = 0xdc00 + (ch >> 0 & 0x3ff);
120 utf16_ch_len = 2;
121 }
122 else
123 {
124 /* single unit */
125 utf16_ch[0] = ch;
126 utf16_ch_len = 1;
127 }
128
129 if (!uni_dest)
130 {
131 written += utf16_ch_len;
132 continue;
133 }
134
135 for (j = 0; j < utf16_ch_len; j++)
136 {
137 if (uni_bytes_max >= sizeof(WCHAR))
138 {
139 *uni_dest++ = utf16_ch[j];
140 uni_bytes_max -= sizeof(WCHAR);
141 written++;
142 }
143 else
144 {
145 uni_bytes_max = 0;
146 status = STATUS_BUFFER_TOO_SMALL;
147 }
148 }
149 }
150
151 *uni_bytes_written = written * sizeof(WCHAR);
152 return status;
153 }
154
155 /* Quick and dirty table for conversion */
156 FILE_INFORMATION_CLASS ConvertToFileInfo[MaximumFileInfoByHandlesClass] =
157 {
158 FileBasicInformation, FileStandardInformation, FileNameInformation, FileRenameInformation,
159 FileDispositionInformation, FileAllocationInformation, FileEndOfFileInformation, FileStreamInformation,
160 FileCompressionInformation, FileAttributeTagInformation, FileIdBothDirectoryInformation, (FILE_INFORMATION_CLASS)-1,
161 FileIoPriorityHintInformation, FileRemoteProtocolInformation
162 };
163
164 /* Taken from kernel32 */
165 DWORD
166 BaseSetLastNTError(IN NTSTATUS Status)
167 {
168 DWORD dwErrCode;
169 dwErrCode = RtlNtStatusToDosError(Status);
170 SetLastError(dwErrCode);
171 return dwErrCode;
172 }
173
174 /* Quick implementation, still going farther than Wine implementation */
175 BOOL
176 WINAPI
177 SetFileInformationByHandle(HANDLE hFile,
178 FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
179 LPVOID lpFileInformation,
180 DWORD dwBufferSize)
181 {
182 NTSTATUS Status;
183 IO_STATUS_BLOCK IoStatusBlock;
184 FILE_INFORMATION_CLASS FileInfoClass;
185
186 FileInfoClass = (FILE_INFORMATION_CLASS)-1;
187
188 /* Attempt to convert the class */
189 if (FileInformationClass < MaximumFileInfoByHandlesClass)
190 {
191 FileInfoClass = ConvertToFileInfo[FileInformationClass];
192 }
193
194 /* If wrong, bail out */
195 if (FileInfoClass == -1)
196 {
197 SetLastError(ERROR_INVALID_PARAMETER);
198 return FALSE;
199 }
200
201 /* And set the information */
202 Status = NtSetInformationFile(hFile, &IoStatusBlock, lpFileInformation,
203 dwBufferSize, FileInfoClass);
204
205 if (!NT_SUCCESS(Status))
206 {
207 BaseSetLastNTError(Status);
208 return FALSE;
209 }
210
211 return TRUE;
212 }
213 #ifdef __cplusplus
214 }
215 #endif