[WIN32K]
[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 // FIXME: this should go to dibobj.c
153
154
155
156 HBITMAP
157 NTAPI
158 UserLoadImage(PCWSTR pwszName)
159 {
160 NTSTATUS Status = STATUS_SUCCESS;
161 HANDLE hFile, hSection;
162 BITMAPFILEHEADER *pbmfh;
163 LPBITMAPINFO pbmi;
164 PVOID pvBits;
165 HBITMAP hbmp = 0;
166
167 DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
168
169 /* Open the file */
170 hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
171 if (!hFile)
172 {
173 return NULL;
174 }
175
176 /* Create a section */
177 hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
178 ZwClose(hFile);
179 if (!hSection)
180 {
181 return NULL;
182 }
183
184 /* Map the section */
185 pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
186 ZwClose(hSection);
187 if (!pbmfh)
188 {
189 return NULL;
190 }
191
192 /* Get a pointer to the BITMAPINFO */
193 pbmi = (LPBITMAPINFO)(pbmfh + 1);
194
195 _SEH2_TRY
196 {
197 ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1);
198 ProbeForRead(pbmfh, pbmfh->bfSize, 1);
199 }
200 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
201 {
202 Status = _SEH2_GetExceptionCode();
203 }
204 _SEH2_END
205
206 if(!NT_SUCCESS(Status))
207 {
208 DPRINT1("Bad File?\n");
209 goto leave;
210 }
211
212 if (pbmfh->bfType == 0x4D42 /* 'BM' */)
213 {
214 /* Could be BITMAPCOREINFO */
215 BITMAPINFO* pConvertedInfo;
216
217 pvBits = (PVOID)((PCHAR)pbmi + pbmfh->bfOffBits);
218
219 pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS);
220 if(!pConvertedInfo)
221 {
222 DPRINT1("Unable to convert the bitmap Info\n");
223 goto leave;
224 }
225
226 // FIXME: use Gre... so that the BITMAPINFO doesn't get probed
227 hbmp = NtGdiCreateDIBitmapInternal(NULL,
228 pConvertedInfo->bmiHeader.biWidth,
229 pConvertedInfo->bmiHeader.biHeight,
230 CBM_INIT,
231 pvBits,
232 pbmi,
233 DIB_RGB_COLORS,
234 pConvertedInfo->bmiHeader.biSize,
235 pConvertedInfo->bmiHeader.biSizeImage,
236 0,
237 0);
238
239 DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi);
240 }
241 else
242 {
243 DPRINT1("Unknown file type!\n");
244 }
245
246 leave:
247 /* Unmap our section, we don't need it anymore */
248 ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
249
250 DPRINT("Leaving UserLoadImage, hbmp = %p\n", hbmp);
251 return hbmp;
252 }