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[MaximumFileInfoByHandleClass] = 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 < MaximumFileInfoByHandleClass) 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 216