1 /**
2  * WinPR: Windows Portable Runtime
3  * Windows Native System Services
4  *
5  * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  * Copyright 2013 Thincast Technologies GmbH
7  * Copyright 2013 Norbert Federa <norbert.federa@thincast.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *     http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <winpr/crt.h>
27 #include <winpr/library.h>
28 #include <winpr/wlog.h>
29 #include <winpr/nt.h>
30 #include <winpr/endian.h>
31 
32 #include "../log.h"
33 #define TAG WINPR_TAG("nt")
34 
35 /**
36  * NtXxx Routines:
37  * http://msdn.microsoft.com/en-us/library/windows/hardware/ff557720/
38  */
39 
40 /**
41  * InitializeObjectAttributes macro
42  * http://msdn.microsoft.com/en-us/library/windows/hardware/ff547804/
43  */
44 
_InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,PUNICODE_STRING ObjectName,ULONG Attributes,HANDLE RootDirectory,PSECURITY_DESCRIPTOR SecurityDescriptor)45 VOID _InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,
46                                  PUNICODE_STRING ObjectName, ULONG Attributes, HANDLE RootDirectory,
47                                  PSECURITY_DESCRIPTOR SecurityDescriptor)
48 {
49 #if defined(_WIN32) && !defined(_UWP)
50 	InitializeObjectAttributes(InitializedAttributes, ObjectName, Attributes, RootDirectory,
51 	                           SecurityDescriptor);
52 #else
53 	InitializedAttributes->Length = sizeof(OBJECT_ATTRIBUTES);
54 	InitializedAttributes->ObjectName = ObjectName;
55 	InitializedAttributes->Attributes = Attributes;
56 	InitializedAttributes->RootDirectory = RootDirectory;
57 	InitializedAttributes->SecurityDescriptor = SecurityDescriptor;
58 	InitializedAttributes->SecurityQualityOfService = NULL;
59 #endif
60 }
61 
62 #ifndef _WIN32
63 
64 #include <pthread.h>
65 #include <winpr/crt.h>
66 
67 #include "../handle/handle.h"
68 
69 struct winpr_nt_file
70 {
71 	WINPR_HANDLE_DEF();
72 
73 	ACCESS_MASK DesiredAccess;
74 	OBJECT_ATTRIBUTES ObjectAttributes;
75 	ULONG FileAttributes;
76 	ULONG ShareAccess;
77 	ULONG CreateDisposition;
78 	ULONG CreateOptions;
79 };
80 typedef struct winpr_nt_file WINPR_NT_FILE;
81 
82 static pthread_once_t _TebOnceControl = PTHREAD_ONCE_INIT;
83 static pthread_key_t _TebKey;
84 
_TebDestruct(void * teb)85 static void _TebDestruct(void* teb)
86 {
87 	free(teb);
88 }
89 
_TebInitOnce(void)90 static void _TebInitOnce(void)
91 {
92 	pthread_key_create(&_TebKey, _TebDestruct);
93 }
94 
NtCurrentTeb(void)95 PTEB NtCurrentTeb(void)
96 {
97 	PTEB teb = NULL;
98 
99 	if (pthread_once(&_TebOnceControl, _TebInitOnce) == 0)
100 	{
101 		if ((teb = pthread_getspecific(_TebKey)) == NULL)
102 		{
103 			teb = calloc(1, sizeof(TEB));
104 			if (teb)
105 				pthread_setspecific(_TebKey, teb);
106 		}
107 	}
108 	return teb;
109 }
110 
111 /**
112  * RtlInitAnsiString routine:
113  * http://msdn.microsoft.com/en-us/library/windows/hardware/ff561918/
114  */
115 
_RtlInitAnsiString(PANSI_STRING DestinationString,PCSZ SourceString)116 VOID _RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
117 {
118 	DestinationString->Buffer = (PCHAR)SourceString;
119 
120 	if (!SourceString)
121 	{
122 		DestinationString->Length = 0;
123 		DestinationString->MaximumLength = 0;
124 	}
125 	else
126 	{
127 		USHORT length = (USHORT)strlen(SourceString);
128 		DestinationString->Length = length;
129 		DestinationString->MaximumLength = length + 1;
130 	}
131 }
132 
133 /**
134  * RtlInitUnicodeString routine:
135  * http://msdn.microsoft.com/en-us/library/windows/hardware/ff561934/
136  */
137 
_RtlInitUnicodeString(PUNICODE_STRING DestinationString,PCWSTR SourceString)138 VOID _RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
139 {
140 	DestinationString->Buffer = (PWSTR)SourceString;
141 
142 	if (!SourceString)
143 	{
144 		DestinationString->Length = 0;
145 		DestinationString->MaximumLength = 0;
146 	}
147 	else
148 	{
149 		USHORT length = (USHORT)_wcslen(SourceString);
150 		DestinationString->Length = length * 2;
151 		DestinationString->MaximumLength = (length + 1) * 2;
152 	}
153 }
154 
155 /**
156  * RtlAnsiStringToUnicodeString function:
157  * http://msdn.microsoft.com/en-us/library/ms648413/
158  */
159 
_RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString,PCANSI_STRING SourceString,BOOLEAN AllocateDestinationString)160 NTSTATUS _RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString,
161                                        PCANSI_STRING SourceString,
162                                        BOOLEAN AllocateDestinationString)
163 {
164 	int index;
165 
166 	if (!SourceString)
167 		return STATUS_INVALID_PARAMETER;
168 
169 	if (AllocateDestinationString)
170 	{
171 		PWSTR wbuf = NULL;
172 
173 		if (SourceString->MaximumLength)
174 		{
175 			if (!(wbuf = (PWSTR)calloc(SourceString->MaximumLength, 2)))
176 				return STATUS_NO_MEMORY;
177 		}
178 
179 		DestinationString->MaximumLength = SourceString->MaximumLength * 2;
180 		DestinationString->Buffer = wbuf;
181 	}
182 	else
183 	{
184 		if (DestinationString->MaximumLength < SourceString->MaximumLength * 2)
185 			return STATUS_BUFFER_OVERFLOW;
186 	}
187 
188 	for (index = 0; index < SourceString->MaximumLength; index++)
189 	{
190 		Data_Write_UINT16(&DestinationString->Buffer[index], SourceString->Buffer[index]);
191 	}
192 
193 	DestinationString->Length = SourceString->Length * 2;
194 
195 	return STATUS_SUCCESS;
196 }
197 
198 /**
199  * RtlFreeUnicodeString function:
200  * http://msdn.microsoft.com/en-us/library/ms648418/
201  */
202 
_RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)203 VOID _RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
204 {
205 	if (UnicodeString)
206 	{
207 		free(UnicodeString->Buffer);
208 
209 		UnicodeString->Length = 0;
210 		UnicodeString->MaximumLength = 0;
211 	}
212 }
213 
214 /**
215  * RtlNtStatusToDosError function:
216  * http://msdn.microsoft.com/en-us/library/windows/desktop/ms680600/
217  */
218 
_RtlNtStatusToDosError(NTSTATUS status)219 ULONG _RtlNtStatusToDosError(NTSTATUS status)
220 {
221 	return status;
222 }
223 
224 /**
225  * NtCreateFile function:
226  * http://msdn.microsoft.com/en-us/library/bb432380/
227  */
228 
_NtCreateFile(PHANDLE FileHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PIO_STATUS_BLOCK IoStatusBlock,PLARGE_INTEGER AllocationSize,ULONG FileAttributes,ULONG ShareAccess,ULONG CreateDisposition,ULONG CreateOptions,PVOID EaBuffer,ULONG EaLength)229 NTSTATUS _NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess,
230                        POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock,
231                        PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess,
232                        ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength)
233 {
234 #if 1
235 	WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
236 	return STATUS_NOT_SUPPORTED;
237 #else
238 	WINPR_NT_FILE* pFileHandle;
239 
240 	pFileHandle = (WINPR_NT_FILE*)calloc(1, sizeof(WINPR_NT_FILE));
241 	if (!pFileHandle)
242 		return STATUS_NO_MEMORY;
243 
244 	pFileHandle->DesiredAccess = DesiredAccess;
245 	pFileHandle->FileAttributes = FileAttributes;
246 	pFileHandle->ShareAccess = ShareAccess;
247 	pFileHandle->CreateDisposition = CreateDisposition;
248 	pFileHandle->CreateOptions = CreateOptions;
249 
250 	*((PULONG_PTR)FileHandle) = (ULONG_PTR)pFileHandle;
251 
252 	// STATUS_ACCESS_DENIED
253 	// STATUS_OBJECT_NAME_INVALID
254 	// STATUS_OBJECT_PATH_NOT_FOUND
255 	// STATUS_OBJECT_NAME_NOT_FOUND
256 
257 	return STATUS_SUCCESS;
258 #endif
259 }
260 
261 /**
262  * NtOpenFile function:
263  * http://msdn.microsoft.com/en-us/library/bb432381/
264  */
265 
_NtOpenFile(PHANDLE FileHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PIO_STATUS_BLOCK IoStatusBlock,ULONG ShareAccess,ULONG OpenOptions)266 NTSTATUS _NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess,
267                      POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock,
268                      ULONG ShareAccess, ULONG OpenOptions)
269 {
270 #if 1
271 	WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
272 	return STATUS_NOT_SUPPORTED;
273 #else
274 	WINPR_NT_FILE* pFileHandle;
275 
276 	pFileHandle = (WINPR_NT_FILE*)calloc(1, sizeof(WINPR_NT_FILE));
277 
278 	if (!pFileHandle)
279 		return STATUS_NO_MEMORY;
280 
281 	pFileHandle->DesiredAccess = DesiredAccess;
282 	pFileHandle->ShareAccess = ShareAccess;
283 
284 	*((PULONG_PTR)FileHandle) = (ULONG_PTR)pFileHandle;
285 
286 	return STATUS_SUCCESS;
287 #endif
288 }
289 
290 /**
291  * NtReadFile function:
292  * http://msdn.microsoft.com/en-us/library/windows/hardware/ff567072/
293  */
294 
_NtReadFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,PVOID Buffer,ULONG Length,PLARGE_INTEGER ByteOffset,PULONG Key)295 NTSTATUS _NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
296                      PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length,
297                      PLARGE_INTEGER ByteOffset, PULONG Key)
298 {
299 #if 1
300 	WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
301 	return STATUS_NOT_SUPPORTED;
302 #else
303 	return STATUS_SUCCESS;
304 #endif
305 }
306 
307 /**
308  * NtWriteFile function:
309  * http://msdn.microsoft.com/en-us/library/windows/hardware/ff567121/
310  */
311 
_NtWriteFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,PVOID Buffer,ULONG Length,PLARGE_INTEGER ByteOffset,PULONG Key)312 NTSTATUS _NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
313                       PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length,
314                       PLARGE_INTEGER ByteOffset, PULONG Key)
315 {
316 #if 1
317 	WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
318 	return STATUS_NOT_SUPPORTED;
319 #else
320 	return STATUS_SUCCESS;
321 #endif
322 }
323 
324 /**
325  * NtDeviceIoControlFile function:
326  * http://msdn.microsoft.com/en-us/library/ms648411/
327  */
328 
_NtDeviceIoControlFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,ULONG IoControlCode,PVOID InputBuffer,ULONG InputBufferLength,PVOID OutputBuffer,ULONG OutputBufferLength)329 NTSTATUS _NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine,
330                                 PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock,
331                                 ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength,
332                                 PVOID OutputBuffer, ULONG OutputBufferLength)
333 {
334 #if 1
335 	WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
336 	return STATUS_NOT_SUPPORTED;
337 #else
338 	return STATUS_SUCCESS;
339 #endif
340 }
341 
342 /**
343  * NtClose function:
344  * http://msdn.microsoft.com/en-us/library/ms648410/
345  */
346 
_NtClose(HANDLE Handle)347 NTSTATUS _NtClose(HANDLE Handle)
348 {
349 #if 1
350 	WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
351 	return STATUS_NOT_SUPPORTED;
352 #else
353 	WINPR_NT_FILE* pFileHandle;
354 
355 	if (!Handle)
356 		return STATUS_SUCCESS;
357 
358 	pFileHandle = (WINPR_NT_FILE*)Handle;
359 
360 	free(pFileHandle);
361 
362 	return STATUS_SUCCESS;
363 #endif
364 }
365 
366 /**
367  * NtWaitForSingleObject function:
368  * http://msdn.microsoft.com/en-us/library/ms648412/
369  */
370 
_NtWaitForSingleObject(HANDLE Handle,BOOLEAN Alertable,PLARGE_INTEGER Timeout)371 NTSTATUS _NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout)
372 {
373 #if 1
374 	WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
375 	return STATUS_NOT_SUPPORTED;
376 #else
377 	return STATUS_SUCCESS;
378 #endif
379 }
380 
381 #else
382 
383 #include <winpr/synch.h>
384 
385 typedef VOID(WINAPI* RTL_INIT_ANSI_STRING_FN)(PANSI_STRING DestinationString, PCSZ SourceString);
386 
387 typedef VOID(WINAPI* RTL_INIT_UNICODE_STRING_FN)(PUNICODE_STRING DestinationString,
388                                                  PCWSTR SourceString);
389 
390 typedef NTSTATUS(WINAPI* RTL_ANSI_STRING_TO_UNICODE_STRING_FN)(PUNICODE_STRING DestinationString,
391                                                                PCANSI_STRING SourceString,
392                                                                BOOLEAN AllocateDestinationString);
393 
394 typedef VOID(WINAPI* RTL_FREE_UNICODE_STRING_FN)(PUNICODE_STRING UnicodeString);
395 
396 typedef ULONG(WINAPI* RTL_NT_STATUS_TO_DOS_ERROR_FN)(NTSTATUS status);
397 
398 typedef NTSTATUS(WINAPI* NT_CREATE_FILE_FN)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess,
399                                             POBJECT_ATTRIBUTES ObjectAttributes,
400                                             PIO_STATUS_BLOCK IoStatusBlock,
401                                             PLARGE_INTEGER AllocationSize, ULONG FileAttributes,
402                                             ULONG ShareAccess, ULONG CreateDisposition,
403                                             ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength);
404 
405 typedef NTSTATUS(WINAPI* NT_OPEN_FILE_FN)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess,
406                                           POBJECT_ATTRIBUTES ObjectAttributes,
407                                           PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess,
408                                           ULONG OpenOptions);
409 
410 typedef NTSTATUS(WINAPI* NT_READ_FILE_FN)(HANDLE FileHandle, HANDLE Event,
411                                           PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
412                                           PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer,
413                                           ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
414 
415 typedef NTSTATUS(WINAPI* NT_WRITE_FILE_FN)(HANDLE FileHandle, HANDLE Event,
416                                            PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
417                                            PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer,
418                                            ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
419 
420 typedef NTSTATUS(WINAPI* NT_DEVICE_IO_CONTROL_FILE_FN)(HANDLE FileHandle, HANDLE Event,
421                                                        PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
422                                                        PIO_STATUS_BLOCK IoStatusBlock,
423                                                        ULONG IoControlCode, PVOID InputBuffer,
424                                                        ULONG InputBufferLength, PVOID OutputBuffer,
425                                                        ULONG OutputBufferLength);
426 
427 typedef NTSTATUS(WINAPI* NT_CLOSE_FN)(HANDLE Handle);
428 
429 typedef NTSTATUS(WINAPI* NT_WAIT_FOR_SINGLE_OBJECT_FN)(HANDLE Handle, BOOLEAN Alertable,
430                                                        PLARGE_INTEGER Timeout);
431 
432 static RTL_INIT_ANSI_STRING_FN pRtlInitAnsiString = NULL;
433 static RTL_INIT_UNICODE_STRING_FN pRtlInitUnicodeString = NULL;
434 static RTL_ANSI_STRING_TO_UNICODE_STRING_FN pRtlAnsiStringToUnicodeString = NULL;
435 static RTL_FREE_UNICODE_STRING_FN pRtlFreeUnicodeString = NULL;
436 static RTL_NT_STATUS_TO_DOS_ERROR_FN pRtlNtStatusToDosError = NULL;
437 static NT_CREATE_FILE_FN pNtCreateFile = NULL;
438 static NT_OPEN_FILE_FN pNtOpenFile = NULL;
439 static NT_READ_FILE_FN pNtReadFile = NULL;
440 static NT_WRITE_FILE_FN pNtWriteFile = NULL;
441 static NT_DEVICE_IO_CONTROL_FILE_FN pNtDeviceIoControlFile = NULL;
442 static NT_CLOSE_FN pNtClose = NULL;
443 static NT_WAIT_FOR_SINGLE_OBJECT_FN pNtWaitForSingleObject = NULL;
444 
445 static INIT_ONCE ntdllInitOnce = INIT_ONCE_STATIC_INIT;
446 
NtdllModuleInit(PINIT_ONCE once,PVOID param,PVOID * context)447 static BOOL CALLBACK NtdllModuleInit(PINIT_ONCE once, PVOID param, PVOID* context)
448 {
449 	HMODULE NtdllModule = LoadLibraryA("ntdll.dll");
450 
451 	if (NtdllModule)
452 	{
453 		pRtlInitAnsiString =
454 		    (RTL_INIT_ANSI_STRING_FN)GetProcAddress(NtdllModule, "RtlInitAnsiString");
455 		pRtlInitUnicodeString =
456 		    (RTL_INIT_UNICODE_STRING_FN)GetProcAddress(NtdllModule, "RtlInitUnicodeString");
457 		pRtlAnsiStringToUnicodeString = (RTL_ANSI_STRING_TO_UNICODE_STRING_FN)GetProcAddress(
458 		    NtdllModule, "RtlAnsiStringToUnicodeString");
459 		pRtlFreeUnicodeString =
460 		    (RTL_FREE_UNICODE_STRING_FN)GetProcAddress(NtdllModule, "RtlFreeUnicodeString");
461 		pRtlNtStatusToDosError =
462 		    (RTL_NT_STATUS_TO_DOS_ERROR_FN)GetProcAddress(NtdllModule, "RtlNtStatusToDosError");
463 		pNtCreateFile = (NT_CREATE_FILE_FN)GetProcAddress(NtdllModule, "NtCreateFile");
464 		pNtOpenFile = (NT_OPEN_FILE_FN)GetProcAddress(NtdllModule, "NtOpenFile");
465 		pNtReadFile = (NT_READ_FILE_FN)GetProcAddress(NtdllModule, "NtReadFile");
466 		pNtWriteFile = (NT_WRITE_FILE_FN)GetProcAddress(NtdllModule, "NtWriteFile");
467 		pNtDeviceIoControlFile =
468 		    (NT_DEVICE_IO_CONTROL_FILE_FN)GetProcAddress(NtdllModule, "NtDeviceIoControlFile");
469 		pNtClose = (NT_CLOSE_FN)GetProcAddress(NtdllModule, "NtClose");
470 		pNtWaitForSingleObject =
471 		    (NT_WAIT_FOR_SINGLE_OBJECT_FN)GetProcAddress(NtdllModule, "NtWaitForSingleObject");
472 	}
473 	return TRUE;
474 }
475 
_RtlInitAnsiString(PANSI_STRING DestinationString,PCSZ SourceString)476 VOID _RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
477 {
478 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
479 
480 	if (!pRtlInitAnsiString)
481 		return;
482 
483 	pRtlInitAnsiString(DestinationString, SourceString);
484 }
485 
_RtlInitUnicodeString(PUNICODE_STRING DestinationString,PCWSTR SourceString)486 VOID _RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
487 {
488 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
489 
490 	if (!pRtlInitUnicodeString)
491 		return;
492 
493 	pRtlInitUnicodeString(DestinationString, SourceString);
494 }
495 
_RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString,PCANSI_STRING SourceString,BOOLEAN AllocateDestinationString)496 NTSTATUS _RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString,
497                                        PCANSI_STRING SourceString,
498                                        BOOLEAN AllocateDestinationString)
499 {
500 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
501 
502 	if (!pRtlAnsiStringToUnicodeString)
503 		return STATUS_INTERNAL_ERROR;
504 
505 	return pRtlAnsiStringToUnicodeString(DestinationString, SourceString,
506 	                                     AllocateDestinationString);
507 }
508 
_RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)509 VOID _RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
510 {
511 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
512 
513 	if (!pRtlFreeUnicodeString)
514 		return;
515 
516 	pRtlFreeUnicodeString(UnicodeString);
517 }
518 
_RtlNtStatusToDosError(NTSTATUS status)519 ULONG _RtlNtStatusToDosError(NTSTATUS status)
520 {
521 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
522 
523 	if (!pRtlNtStatusToDosError)
524 		return status;
525 
526 	return pRtlNtStatusToDosError(status);
527 }
528 
_NtCreateFile(PHANDLE FileHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PIO_STATUS_BLOCK IoStatusBlock,PLARGE_INTEGER AllocationSize,ULONG FileAttributes,ULONG ShareAccess,ULONG CreateDisposition,ULONG CreateOptions,PVOID EaBuffer,ULONG EaLength)529 NTSTATUS _NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess,
530                        POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock,
531                        PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess,
532                        ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength)
533 {
534 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
535 
536 	if (!pNtCreateFile)
537 		return STATUS_INTERNAL_ERROR;
538 
539 	return pNtCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize,
540 	                     FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer,
541 	                     EaLength);
542 }
543 
_NtOpenFile(PHANDLE FileHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PIO_STATUS_BLOCK IoStatusBlock,ULONG ShareAccess,ULONG OpenOptions)544 NTSTATUS _NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess,
545                      POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock,
546                      ULONG ShareAccess, ULONG OpenOptions)
547 {
548 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
549 
550 	if (!pNtOpenFile)
551 		return STATUS_INTERNAL_ERROR;
552 
553 	return pNtOpenFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, ShareAccess,
554 	                   OpenOptions);
555 }
556 
_NtReadFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,PVOID Buffer,ULONG Length,PLARGE_INTEGER ByteOffset,PULONG Key)557 NTSTATUS _NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
558                      PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length,
559                      PLARGE_INTEGER ByteOffset, PULONG Key)
560 {
561 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
562 
563 	if (!pNtReadFile)
564 		return STATUS_INTERNAL_ERROR;
565 
566 	return pNtReadFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length,
567 	                   ByteOffset, Key);
568 }
569 
_NtWriteFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,PVOID Buffer,ULONG Length,PLARGE_INTEGER ByteOffset,PULONG Key)570 NTSTATUS _NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
571                       PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length,
572                       PLARGE_INTEGER ByteOffset, PULONG Key)
573 {
574 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
575 
576 	if (!pNtWriteFile)
577 		return STATUS_INTERNAL_ERROR;
578 
579 	return pNtWriteFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length,
580 	                    ByteOffset, Key);
581 }
582 
_NtDeviceIoControlFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,ULONG IoControlCode,PVOID InputBuffer,ULONG InputBufferLength,PVOID OutputBuffer,ULONG OutputBufferLength)583 NTSTATUS _NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine,
584                                 PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock,
585                                 ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength,
586                                 PVOID OutputBuffer, ULONG OutputBufferLength)
587 {
588 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
589 
590 	if (!pNtDeviceIoControlFile)
591 		return STATUS_INTERNAL_ERROR;
592 
593 	return pNtDeviceIoControlFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock,
594 	                              IoControlCode, InputBuffer, InputBufferLength, OutputBuffer,
595 	                              OutputBufferLength);
596 }
597 
_NtClose(HANDLE Handle)598 NTSTATUS _NtClose(HANDLE Handle)
599 {
600 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
601 
602 	if (!pNtClose)
603 		return STATUS_INTERNAL_ERROR;
604 
605 	return pNtClose(Handle);
606 }
607 
_NtWaitForSingleObject(HANDLE Handle,BOOLEAN Alertable,PLARGE_INTEGER Timeout)608 NTSTATUS _NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout)
609 {
610 	InitOnceExecuteOnce(&ntdllInitOnce, NtdllModuleInit, NULL, NULL);
611 
612 	if (!pNtWaitForSingleObject)
613 		return STATUS_INTERNAL_ERROR;
614 
615 	return pNtWaitForSingleObject(Handle, Alertable, Timeout);
616 }
617 
618 #endif
619