xref: /reactos/win32ss/user/ntuser/misc/file.c (revision 40462c92)
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