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 16 extern "C" { 17 #endif 18 /* So that we can link */ 19 DEFINE_GUID(CLSID_WICImagingFactory, 0xcacaf262,0x9370,0x4615,0xa1,0x3b,0x9f,0x55,0x39,0xda,0x4c,0x0a); 20 21 /* Copied from ntoskrnl_vista */ 22 NTSTATUS 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 */ 157 FILE_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 */ 166 DWORD 167 BaseSetLastNTError(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 */ 176 BOOL 177 WINAPI 178 SetFileInformationByHandle(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 217