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