856de99015dd8a4ec41cf0c2cb7276379dfbe874
[reactos.git] / subsystems / win32 / win32k / misc / file.c
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: subsystem/win32/win32k/misc/registry.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%x, hFile=0x%x\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 = NULL;
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 }
111
112 DPRINT("Leaving W32kCreateFileSection, Status=0x%x, hSection=0x%x\n", Status, hSection);
113
114 /* Return section handle */
115 return hSection;
116 }
117
118 PVOID
119 NTAPI
120 W32kMapViewOfSection(
121 HANDLE hSection,
122 DWORD dwPageProtect,
123 ULONG_PTR ulSectionOffset)
124 {
125 NTSTATUS Status;
126 LARGE_INTEGER liSectionOffset;
127 ULONG_PTR ulViewSize;
128 PVOID pvBase = 0;
129
130 ulViewSize =
131 liSectionOffset.QuadPart = 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 }
146
147 DPRINT("Leaving W32kMapViewOfSection, Status=0x%x, pvBase=0x%x\n", Status, pvBase);
148
149 return pvBase;
150 }
151
152 HBITMAP
153 NTAPI
154 UserLoadImage(PCWSTR pwszName)
155 {
156 NTSTATUS Status = STATUS_SUCCESS;
157 HANDLE hFile, hSection;
158 BITMAPFILEHEADER *pbmfh;
159 LPBITMAPINFO pbmi;
160 PVOID pvBits;
161 HBITMAP hbmp = 0;
162
163 DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
164
165 /* Open the file */
166 hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
167 if (!hFile)
168 {
169 return NULL;
170 }
171
172 /* Create a section */
173 hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
174 ZwClose(hFile);
175 if (!hSection)
176 {
177 return NULL;
178 }
179
180 /* Map the section */
181 pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
182 ZwClose(hSection);
183 if (!pbmfh)
184 {
185 return NULL;
186 }
187
188 /* Get a pointer to the BITMAPINFO */
189 pbmi = (LPBITMAPINFO)(pbmfh + 1);
190
191 _SEH2_TRY
192 {
193 ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1);
194 ProbeForRead(pbmfh, pbmfh->bfSize, 1);
195 }
196 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
197 {
198 Status = _SEH2_GetExceptionCode();
199 }
200 _SEH2_END
201
202 if(!NT_SUCCESS(Status))
203 {
204 DPRINT1("Bad File?\n");
205 goto leave;
206 }
207
208 if (pbmfh->bfType == 0x4D42 /* 'BM' */)
209 {
210 /* Could be BITMAPCOREINFO */
211 BITMAPINFO* pConvertedInfo;
212 HDC hdc;
213
214 pvBits = (PVOID)((PCHAR)pbmfh + pbmfh->bfOffBits);
215
216 pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS);
217 if(!pConvertedInfo)
218 {
219 DPRINT1("Unable to convert the bitmap Info\n");
220 goto leave;
221 }
222
223 hdc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
224
225 hbmp = GreCreateDIBitmapInternal(hdc,
226 pConvertedInfo->bmiHeader.biWidth,
227 pConvertedInfo->bmiHeader.biHeight,
228 CBM_INIT,
229 pvBits,
230 pConvertedInfo,
231 DIB_RGB_COLORS,
232 0,
233 0);
234
235 NtGdiDeleteObjectApp(hdc);
236 DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi);
237 }
238 else
239 {
240 DPRINT1("Unknown file type!\n");
241 }
242
243 leave:
244 /* Unmap our section, we don't need it anymore */
245 ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
246
247 DPRINT("Leaving UserLoadImage, hbmp = %p\n", hbmp);
248 return hbmp;
249 }