[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;
161 HANDLE hFile, hSection;
162 BITMAPFILEHEADER *pbmfh;
163 LPBITMAPINFO pbmi;
164 ULONG cjInfoSize;
165 PVOID pvBits;
166 HBITMAP hbmp = 0;
167 BITMAPV5INFO bmiLocal;
168
169 DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
170
171 /* Open the file */
172 hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
173 if (!hFile)
174 {
175 return NULL;
176 }
177
178 /* Create a section */
179 hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
180 ZwClose(hFile);
181 if (!hSection)
182 {
183 return NULL;
184 }
185
186 /* Map the section */
187 pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
188 ZwClose(hSection);
189 if (!pbmfh)
190 {
191 return NULL;
192 }
193
194 /* Get a pointer to the BITMAPINFO */
195 pbmi = (LPBITMAPINFO)(pbmfh + 1);
196
197 /* Create a normalized local BITMAPINFO */
198 _SEH2_TRY
199 {
200 Status = ProbeAndConvertToBitmapV5Info(&bmiLocal,
201 pbmi,
202 DIB_RGB_COLORS,
203 0);
204 }
205 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
206 {
207 Status = _SEH2_GetExceptionCode();
208 }
209 _SEH2_END
210
211 if (NT_SUCCESS(Status))
212 {
213 cjInfoSize = bmiLocal.bmiHeader.bV5Size +
214 bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD);
215 pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize);
216
217 // FIXME: use Gre... so that the BITMAPINFO doesn't get probed
218 hbmp = NtGdiCreateDIBitmapInternal(NULL,
219 bmiLocal.bmiHeader.bV5Width,
220 bmiLocal.bmiHeader.bV5Height,
221 CBM_INIT,
222 pvBits,
223 pbmi,
224 DIB_RGB_COLORS,
225 bmiLocal.bmiHeader.bV5Size,
226 bmiLocal.bmiHeader.bV5SizeImage,
227 0,
228 0);
229 }
230
231 /* Unmap our section, we don't need it anymore */
232 ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
233
234 DPRINT("Leaving UserLoadImage, hbmp = %p\n", hbmp);
235 return hbmp;
236 }