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, &ustrFile, 0, NULL, NULL); 56 57 Status = ZwCreateFile(&hFile, 58 dwDesiredAccess, 59 &ObjectAttributes, 60 &IoStatusBlock, 61 NULL, 62 FILE_ATTRIBUTE_NORMAL, 63 0, 64 FILE_OPEN, 65 FILE_NON_DIRECTORY_FILE, 66 NULL, 67 0); 68 if (!NT_SUCCESS(Status)) 69 { 70 SetLastNtError(Status); 71 hFile = NULL; 72 } 73 74 DPRINT("Leaving W32kOpenFile, Status=0x%lx, hFile=0x%p\n", Status, hFile); 75 return hFile; 76 } 77 78 HANDLE 79 NTAPI 80 W32kCreateFileSection(HANDLE hFile, 81 ULONG flAllocation, 82 DWORD flPageProtection, 83 ULONGLONG ullMaxSize) 84 { 85 NTSTATUS Status; 86 HANDLE hSection; 87 ACCESS_MASK amDesiredAccess; 88 89 /* Set access mask */ 90 amDesiredAccess = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ; 91 92 /* Check if write access is requested */ 93 if (flPageProtection == PAGE_READWRITE) 94 { 95 /* Add it to access mask */ 96 amDesiredAccess |= SECTION_MAP_WRITE; 97 } 98 99 /* Now create the actual section */ 100 Status = ZwCreateSection(&hSection, 101 amDesiredAccess, 102 NULL, 103 NULL, 104 flPageProtection, 105 flAllocation, 106 hFile); 107 if (!NT_SUCCESS(Status)) 108 { 109 SetLastNtError(Status); 110 hSection = NULL; 111 } 112 113 DPRINT("Leaving W32kCreateFileSection, Status=0x%lx, hSection=0x%p\n", Status, hSection); 114 115 /* Return section handle */ 116 return hSection; 117 } 118 119 PVOID 120 NTAPI 121 W32kMapViewOfSection( 122 HANDLE hSection, 123 DWORD dwPageProtect, 124 ULONG_PTR ulSectionOffset) 125 { 126 NTSTATUS Status; 127 LARGE_INTEGER liSectionOffset; 128 ULONG_PTR ulViewSize; 129 PVOID pvBase = NULL; 130 131 liSectionOffset.QuadPart = ulViewSize = ulSectionOffset; 132 Status = ZwMapViewOfSection(hSection, 133 NtCurrentProcess(), 134 &pvBase, 135 0, 136 0, 137 &liSectionOffset, 138 &ulViewSize, 139 ViewShare, 140 0, 141 dwPageProtect); 142 if (!NT_SUCCESS(Status)) 143 { 144 SetLastNtError(Status); 145 pvBase = NULL; 146 } 147 148 DPRINT("Leaving W32kMapViewOfSection, Status=0x%lx, pvBase=0x%p\n", Status, pvBase); 149 150 return pvBase; 151 } 152 153 HBITMAP 154 NTAPI 155 UserLoadImage(PCWSTR pwszName) 156 { 157 NTSTATUS Status = STATUS_SUCCESS; 158 HANDLE hFile, hSection; 159 BITMAPFILEHEADER *pbmfh; 160 LPBITMAPINFO pbmi; 161 PVOID pvBits; 162 HBITMAP hbmp = 0; 163 164 DPRINT("Enter UserLoadImage(%ls)\n", pwszName); 165 166 /* Open the file */ 167 hFile = W32kOpenFile(pwszName, FILE_READ_DATA); 168 if (!hFile) 169 { 170 return NULL; 171 } 172 173 /* Create a section */ 174 hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0); 175 ZwClose(hFile); 176 if (!hSection) 177 { 178 return NULL; 179 } 180 181 /* Map the section */ 182 pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0); 183 ZwClose(hSection); 184 if (!pbmfh) 185 { 186 return NULL; 187 } 188 189 /* Get a pointer to the BITMAPINFO */ 190 pbmi = (LPBITMAPINFO)(pbmfh + 1); 191 192 _SEH2_TRY 193 { 194 ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1); 195 ProbeForRead(pbmfh, pbmfh->bfSize, 1); 196 } 197 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 198 { 199 Status = _SEH2_GetExceptionCode(); 200 } 201 _SEH2_END 202 203 if(!NT_SUCCESS(Status)) 204 { 205 DPRINT1("Bad File?\n"); 206 goto leave; 207 } 208 209 if (pbmfh->bfType == 0x4D42 /* 'BM' */) 210 { 211 /* Could be BITMAPCOREINFO */ 212 BITMAPINFO* pConvertedInfo; 213 HDC hdc; 214 215 pvBits = (PVOID)((PCHAR)pbmfh + pbmfh->bfOffBits); 216 217 pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS); 218 if(!pConvertedInfo) 219 { 220 DPRINT1("Unable to convert the bitmap Info\n"); 221 goto leave; 222 } 223 224 hdc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE); 225 226 hbmp = GreCreateDIBitmapInternal(hdc, 227 pConvertedInfo->bmiHeader.biWidth, 228 pConvertedInfo->bmiHeader.biHeight, 229 CBM_INIT, 230 pvBits, 231 pConvertedInfo, 232 DIB_RGB_COLORS, 233 0, 234 pbmfh->bfSize - pbmfh->bfOffBits, 235 0); 236 237 NtGdiDeleteObjectApp(hdc); 238 DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi, -1); 239 } 240 else 241 { 242 DPRINT1("Unknown file type!\n"); 243 } 244 245 leave: 246 /* Unmap our section, we don't need it anymore */ 247 ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh); 248 249 DPRINT("Leaving UserLoadImage, hbmp = %p\n", hbmp); 250 return hbmp; 251 } 252