1 /* 2 * COPYRIGHT: GPL, see COPYING in the top level directory 3 * PROJECT: ReactOS win32 kernel mode subsystem server 4 * PURPOSE: File access support routines 5 * FILE: win32ss/user/ntuser/misc/file.c 6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) 7 */ 8 9 #include <win32k.h> 10 11 #define NDEBUG 12 #include <debug.h> 13 14 BOOL 15 NTAPI 16 W32kDosPathNameToNtPathName( 17 IN PCWSTR pwszDosPathName, 18 OUT PUNICODE_STRING pustrNtPathName) 19 { 20 NTSTATUS Status; 21 22 /* Prepend "\??\" */ 23 pustrNtPathName->Length = 0; 24 Status = RtlAppendUnicodeToString(pustrNtPathName, L"\\??\\"); 25 if (!NT_SUCCESS(Status)) 26 { 27 return FALSE; 28 } 29 30 /* Append the dos name */ 31 Status = RtlAppendUnicodeToString(pustrNtPathName, pwszDosPathName); 32 if (!NT_SUCCESS(Status)) 33 { 34 return FALSE; 35 } 36 37 return TRUE; 38 } 39 40 41 HANDLE 42 NTAPI 43 W32kOpenFile(PCWSTR pwszFileName, DWORD dwDesiredAccess) 44 { 45 UNICODE_STRING ustrFile; 46 OBJECT_ATTRIBUTES ObjectAttributes; 47 IO_STATUS_BLOCK IoStatusBlock; 48 HANDLE hFile = INVALID_HANDLE_VALUE; 49 NTSTATUS Status; 50 51 DPRINT("W32kOpenFile(%S)\n", pwszFileName); 52 53 RtlInitUnicodeString(&ustrFile, pwszFileName); 54 55 InitializeObjectAttributes(&ObjectAttributes, 56 &ustrFile, 57 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 58 NULL, 59 NULL); 60 61 Status = ZwCreateFile(&hFile, 62 dwDesiredAccess, 63 &ObjectAttributes, 64 &IoStatusBlock, 65 NULL, 66 FILE_ATTRIBUTE_NORMAL, 67 0, 68 FILE_OPEN, 69 FILE_NON_DIRECTORY_FILE, 70 NULL, 71 0); 72 if (!NT_SUCCESS(Status)) 73 { 74 SetLastNtError(Status); 75 hFile = NULL; 76 } 77 78 DPRINT("Leaving W32kOpenFile, Status=0x%lx, hFile=0x%p\n", Status, hFile); 79 return hFile; 80 } 81 82 HANDLE 83 NTAPI 84 W32kCreateFileSection(HANDLE hFile, 85 ULONG flAllocation, 86 DWORD flPageProtection, 87 ULONGLONG ullMaxSize) 88 { 89 NTSTATUS Status; 90 HANDLE hSection; 91 ACCESS_MASK amDesiredAccess; 92 93 /* Set access mask */ 94 amDesiredAccess = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ; 95 96 /* Check if write access is requested */ 97 if (flPageProtection == PAGE_READWRITE) 98 { 99 /* Add it to access mask */ 100 amDesiredAccess |= SECTION_MAP_WRITE; 101 } 102 103 /* Now create the actual section */ 104 Status = ZwCreateSection(&hSection, 105 amDesiredAccess, 106 NULL, 107 NULL, 108 flPageProtection, 109 flAllocation, 110 hFile); 111 if (!NT_SUCCESS(Status)) 112 { 113 SetLastNtError(Status); 114 hSection = NULL; 115 } 116 117 DPRINT("Leaving W32kCreateFileSection, Status=0x%lx, hSection=0x%p\n", Status, hSection); 118 119 /* Return section handle */ 120 return hSection; 121 } 122 123 PVOID 124 NTAPI 125 W32kMapViewOfSection( 126 HANDLE hSection, 127 DWORD dwPageProtect, 128 ULONG_PTR ulSectionOffset) 129 { 130 NTSTATUS Status; 131 LARGE_INTEGER liSectionOffset; 132 ULONG_PTR ulViewSize; 133 PVOID pvBase = NULL; 134 135 liSectionOffset.QuadPart = ulViewSize = ulSectionOffset; 136 Status = ZwMapViewOfSection(hSection, 137 NtCurrentProcess(), 138 &pvBase, 139 0, 140 0, 141 &liSectionOffset, 142 &ulViewSize, 143 ViewShare, 144 0, 145 dwPageProtect); 146 if (!NT_SUCCESS(Status)) 147 { 148 SetLastNtError(Status); 149 pvBase = NULL; 150 } 151 152 DPRINT("Leaving W32kMapViewOfSection, Status=0x%lx, pvBase=0x%p\n", Status, pvBase); 153 154 return pvBase; 155 } 156 157 HBITMAP 158 NTAPI 159 UserLoadImage(PCWSTR pwszName) 160 { 161 NTSTATUS Status = STATUS_SUCCESS; 162 HANDLE hFile, hSection; 163 BITMAPFILEHEADER *pbmfh; 164 LPBITMAPINFO pbmi; 165 PVOID pvBits; 166 HBITMAP hbmp = 0; 167 168 DPRINT("Enter UserLoadImage(%ls)\n", pwszName); 169 170 /* Open the file */ 171 hFile = W32kOpenFile(pwszName, FILE_READ_DATA); 172 if (!hFile) 173 { 174 return NULL; 175 } 176 177 /* Create a section */ 178 hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0); 179 ZwClose(hFile); 180 if (!hSection) 181 { 182 return NULL; 183 } 184 185 /* Map the section */ 186 pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0); 187 ZwClose(hSection); 188 if (!pbmfh) 189 { 190 return NULL; 191 } 192 193 /* Get a pointer to the BITMAPINFO */ 194 pbmi = (LPBITMAPINFO)(pbmfh + 1); 195 196 _SEH2_TRY 197 { 198 ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1); 199 ProbeForRead(pbmfh, pbmfh->bfSize, 1); 200 } 201 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 202 { 203 Status = _SEH2_GetExceptionCode(); 204 } 205 _SEH2_END 206 207 if(!NT_SUCCESS(Status)) 208 { 209 DPRINT1("Bad File?\n"); 210 goto leave; 211 } 212 213 if (pbmfh->bfType == 0x4D42 /* 'BM' */) 214 { 215 /* Could be BITMAPCOREINFO */ 216 BITMAPINFO* pConvertedInfo; 217 HDC hdc; 218 219 pvBits = (PVOID)((PCHAR)pbmfh + pbmfh->bfOffBits); 220 221 pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS); 222 if(!pConvertedInfo) 223 { 224 DPRINT1("Unable to convert the bitmap Info\n"); 225 goto leave; 226 } 227 228 hdc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE); 229 230 hbmp = GreCreateDIBitmapInternal(hdc, 231 pConvertedInfo->bmiHeader.biWidth, 232 pConvertedInfo->bmiHeader.biHeight, 233 CBM_INIT, 234 pvBits, 235 pConvertedInfo, 236 DIB_RGB_COLORS, 237 0, 238 pbmfh->bfSize - pbmfh->bfOffBits, 239 0); 240 241 NtGdiDeleteObjectApp(hdc); 242 DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi, -1); 243 } 244 else 245 { 246 DPRINT1("Unknown file type!\n"); 247 } 248 249 leave: 250 /* Unmap our section, we don't need it anymore */ 251 ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh); 252 253 DPRINT("Leaving UserLoadImage, hbmp = %p\n", hbmp); 254 return hbmp; 255 } 256