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