Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

968 lines
25 KiB

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
hooks.c
Abstract:
This module implements verifier hooks for various
APIs that do not fall in any specific category.
Author:
Silviu Calinoiu (SilviuC) 3-Dec-2001
Revision History:
3-Dec-2001 (SilviuC): initial version.
--*/
#include "pch.h"
#include "verifier.h"
#include "support.h"
#include "faults.h"
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////// Wait APIs
/////////////////////////////////////////////////////////////////////
//WINBASEAPI
DWORD
WINAPI
AVrfpWaitForSingleObject(
IN HANDLE hHandle,
IN DWORD dwMilliseconds
)
{
typedef DWORD (WINAPI * FUNCTION_TYPE) (HANDLE, DWORD);
FUNCTION_TYPE Function;
DWORD Result;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_WAITFORSINGLEOBJECT);
BUMP_COUNTER (CNT_WAIT_SINGLE_CALLS);
if (dwMilliseconds != INFINITE && dwMilliseconds != 0) {
BUMP_COUNTER (CNT_WAIT_WITH_TIMEOUT_CALLS);
if (SHOULD_FAULT_INJECT(CLS_WAIT_APIS)) {
BUMP_COUNTER (CNT_WAIT_WITH_TIMEOUT_FAILS);
CHECK_BREAK (BRK_WAIT_WITH_TIMEOUT_FAIL);
return WAIT_TIMEOUT;
}
}
Result = (* Function) (hHandle, dwMilliseconds);
//
// No matter if it fails or not we will introduce a random delay
// in order to randomize the timings in the process.
//
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_RACE_CHECKS)) {
AVrfpCreateRandomDelay ();
}
return Result;
}
//WINBASEAPI
DWORD
WINAPI
AVrfpWaitForMultipleObjects(
IN DWORD nCount,
IN CONST HANDLE *lpHandles,
IN BOOL bWaitAll,
IN DWORD dwMilliseconds
)
{
typedef DWORD (WINAPI * FUNCTION_TYPE) (DWORD, CONST HANDLE *, BOOL, DWORD);
FUNCTION_TYPE Function;
DWORD Result;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_WAITFORMULTIPLEOBJECTS);
BUMP_COUNTER (CNT_WAIT_MULTIPLE_CALLS);
if (dwMilliseconds != INFINITE && dwMilliseconds != 0) {
BUMP_COUNTER (CNT_WAIT_WITH_TIMEOUT_CALLS);
if (SHOULD_FAULT_INJECT(CLS_WAIT_APIS)) {
BUMP_COUNTER (CNT_WAIT_WITH_TIMEOUT_FAILS);
CHECK_BREAK (BRK_WAIT_WITH_TIMEOUT_FAIL);
return WAIT_TIMEOUT;
}
}
Result = (* Function) (nCount, lpHandles, bWaitAll, dwMilliseconds);
//
// No matter if it fails or not we will introduce a random delay
// in order to randomize the timings in the process.
//
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_RACE_CHECKS)) {
AVrfpCreateRandomDelay ();
}
return Result;
}
//WINBASEAPI
DWORD
WINAPI
AVrfpWaitForSingleObjectEx(
IN HANDLE hHandle,
IN DWORD dwMilliseconds,
IN BOOL bAlertable
)
{
typedef DWORD (WINAPI * FUNCTION_TYPE) (HANDLE, DWORD, BOOL);
FUNCTION_TYPE Function;
DWORD Result;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_WAITFORSINGLEOBJECTEX);
BUMP_COUNTER (CNT_WAIT_SINGLEEX_CALLS);
if (dwMilliseconds != INFINITE && dwMilliseconds != 0) {
BUMP_COUNTER (CNT_WAIT_WITH_TIMEOUT_CALLS);
if (SHOULD_FAULT_INJECT(CLS_WAIT_APIS)) {
BUMP_COUNTER (CNT_WAIT_WITH_TIMEOUT_FAILS);
CHECK_BREAK (BRK_WAIT_WITH_TIMEOUT_FAIL);
return WAIT_TIMEOUT;
}
}
Result = (* Function) (hHandle, dwMilliseconds, bAlertable);
//
// No matter if it fails or not we will introduce a random delay
// in order to randomize the timings in the process.
//
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_RACE_CHECKS)) {
AVrfpCreateRandomDelay ();
}
return Result;
}
//WINBASEAPI
DWORD
WINAPI
AVrfpWaitForMultipleObjectsEx(
IN DWORD nCount,
IN CONST HANDLE *lpHandles,
IN BOOL bWaitAll,
IN DWORD dwMilliseconds,
IN BOOL bAlertable
)
{
typedef DWORD (WINAPI * FUNCTION_TYPE) (DWORD, CONST HANDLE *, BOOL, DWORD, BOOL);
FUNCTION_TYPE Function;
DWORD Result;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_WAITFORMULTIPLEOBJECTSEX);
BUMP_COUNTER (CNT_WAIT_MULTIPLEEX_CALLS);
if (dwMilliseconds != INFINITE && dwMilliseconds != 0) {
BUMP_COUNTER (CNT_WAIT_WITH_TIMEOUT_CALLS);
if (SHOULD_FAULT_INJECT(CLS_WAIT_APIS)) {
BUMP_COUNTER (CNT_WAIT_WITH_TIMEOUT_FAILS);
CHECK_BREAK (BRK_WAIT_WITH_TIMEOUT_FAIL);
return WAIT_TIMEOUT;
}
}
Result = (* Function) (nCount, lpHandles, bWaitAll, dwMilliseconds, bAlertable);
//
// No matter if it fails or not we will introduce a random delay
// in order to randomize the timings in the process.
//
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_RACE_CHECKS)) {
AVrfpCreateRandomDelay ();
}
return Result;
}
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtWaitForSingleObject(
IN HANDLE Handle,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Timeout OPTIONAL
)
{
NTSTATUS Status;
//
// Verify that it is legal to wait for this object
// in the current state. One example of illegal wait
// is waiting for a thread object while holding the
// loader lock. That thread will need the loader lock
// when calling ExitThread so it will most likely
// deadlock with the current thread.
//
AVrfpVerifyLegalWait (&Handle,
1,
TRUE);
//
// Call the original function.
//
Status = NtWaitForSingleObject (Handle,
Alertable,
Timeout);
return Status;
}
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtWaitForMultipleObjects(
IN ULONG Count,
IN HANDLE Handles[],
IN WAIT_TYPE WaitType,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Timeout OPTIONAL
)
{
NTSTATUS Status;
//
// Verify that it is legal to wait for these objects
// in the current state. One example of illegal wait
// is waiting for a thread object while holding the
// loader lock. That thread will need the loader lock
// when calling ExitThread so it will most likely
// deadlock with the current thread.
//
AVrfpVerifyLegalWait (Handles,
Count,
(WaitType == WaitAll));
//
// Call the original function.
//
Status = NtWaitForMultipleObjects (Count,
Handles,
WaitType,
Alertable,
Timeout);
return Status;
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////// File APIs
/////////////////////////////////////////////////////////////////////
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
)
{
NTSTATUS Status;
if (SHOULD_FAULT_INJECT(CLS_FILE_APIS)) {
CHECK_BREAK (BRK_CREATE_FILE_FAIL);
return STATUS_NO_MEMORY;
}
Status = NtCreateFile (FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocationSize,
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
EaBuffer,
EaLength);
return Status;
}
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
)
{
NTSTATUS Status;
if (SHOULD_FAULT_INJECT(CLS_FILE_APIS)) {
CHECK_BREAK (BRK_CREATE_FILE_FAIL);
return STATUS_NO_MEMORY;
}
Status = NtOpenFile (FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
ShareAccess,
OpenOptions);
return Status;
}
//WINBASEAPI
HANDLE
WINAPI
AVrfpCreateFileA(
IN LPCSTR lpFileName,
IN DWORD dwDesiredAccess,
IN DWORD dwShareMode,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
IN DWORD dwCreationDisposition,
IN DWORD dwFlagsAndAttributes,
IN HANDLE hTemplateFile
)
{
typedef HANDLE (WINAPI * FUNCTION_TYPE)
(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,
DWORD, DWORD, HANDLE);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_CREATEFILEA);
if (SHOULD_FAULT_INJECT(CLS_FILE_APIS)) {
CHECK_BREAK (BRK_CREATE_FILE_FAIL);
NtCurrentTeb()->LastErrorValue = ERROR_OUTOFMEMORY;
return INVALID_HANDLE_VALUE;
}
return (* Function) (lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
//WINBASEAPI
HANDLE
WINAPI
AVrfpCreateFileW(
IN LPCWSTR lpFileName,
IN DWORD dwDesiredAccess,
IN DWORD dwShareMode,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
IN DWORD dwCreationDisposition,
IN DWORD dwFlagsAndAttributes,
IN HANDLE hTemplateFile
)
{
typedef HANDLE (WINAPI * FUNCTION_TYPE)
(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,
DWORD, DWORD, HANDLE);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_CREATEFILEW);
if (SHOULD_FAULT_INJECT(CLS_FILE_APIS)) {
CHECK_BREAK (BRK_CREATE_FILE_FAIL);
NtCurrentTeb()->LastErrorValue = ERROR_OUTOFMEMORY;
return INVALID_HANDLE_VALUE;
}
return (* Function) (lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////// Registry APIs
/////////////////////////////////////////////////////////////////////
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtCreateKey(
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex,
IN PUNICODE_STRING Class OPTIONAL,
IN ULONG CreateOptions,
OUT PULONG Disposition OPTIONAL
)
{
NTSTATUS Status;
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return STATUS_NO_MEMORY;
}
Status = NtCreateKey (KeyHandle,
DesiredAccess,
ObjectAttributes,
TitleIndex,
Class,
CreateOptions,
Disposition);
return Status;
}
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtOpenKey(
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
)
{
NTSTATUS Status;
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return STATUS_NO_MEMORY;
}
Status = NtOpenKey (KeyHandle,
DesiredAccess,
ObjectAttributes);
return Status;
}
//WINADVAPI
LONG
APIENTRY
AVrfpRegCreateKeyA (
IN HKEY hKey,
IN LPCSTR lpSubKey,
OUT PHKEY phkResult
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCSTR, PHKEY);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGCREATEKEYA);
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return ERROR_OUTOFMEMORY;
}
return (* Function) (hKey, lpSubKey, phkResult);
}
//WINADVAPI
LONG
APIENTRY
AVrfpRegCreateKeyW (
IN HKEY hKey,
IN LPCWSTR lpSubKey,
OUT PHKEY phkResult
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCWSTR, PHKEY);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGCREATEKEYW);
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return ERROR_OUTOFMEMORY;
}
return (* Function) (hKey, lpSubKey, phkResult);
}
//WINADVAPI
LONG
APIENTRY
AVrfpRegCreateKeyExA (
IN HKEY hKey,
IN LPCSTR lpSubKey,
IN DWORD Reserved,
IN LPSTR lpClass,
IN DWORD dwOptions,
IN REGSAM samDesired,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
OUT PHKEY phkResult,
OUT LPDWORD lpdwDisposition
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCSTR, DWORD, LPSTR, DWORD,
REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGCREATEKEYEXA);
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return ERROR_OUTOFMEMORY;
}
return (* Function) (hKey,
lpSubKey,
Reserved,
lpClass,
dwOptions,
samDesired,
lpSecurityAttributes,
phkResult,
lpdwDisposition);
}
//WINADVAPI
LONG
APIENTRY
AVrfpRegCreateKeyExW (
IN HKEY hKey,
IN LPCWSTR lpSubKey,
IN DWORD Reserved,
IN LPWSTR lpClass,
IN DWORD dwOptions,
IN REGSAM samDesired,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
OUT PHKEY phkResult,
OUT LPDWORD lpdwDisposition
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCWSTR, DWORD, LPWSTR, DWORD,
REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGCREATEKEYEXW);
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return ERROR_OUTOFMEMORY;
}
return (* Function) (hKey,
lpSubKey,
Reserved,
lpClass,
dwOptions,
samDesired,
lpSecurityAttributes,
phkResult,
lpdwDisposition);
}
//WINADVAPI
LONG
APIENTRY
AVrfpRegOpenKeyA (
IN HKEY hKey,
IN LPCSTR lpSubKey,
OUT PHKEY phkResult
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCSTR, PHKEY);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGOPENKEYA);
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return ERROR_OUTOFMEMORY;
}
return (* Function)(hKey, lpSubKey, phkResult);
}
//WINADVAPI
LONG
APIENTRY
AVrfpRegOpenKeyW (
IN HKEY hKey,
IN LPCWSTR lpSubKey,
OUT PHKEY phkResult
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCWSTR, PHKEY);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGOPENKEYW);
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return ERROR_OUTOFMEMORY;
}
return (* Function)(hKey, lpSubKey, phkResult);
}
//WINADVAPI
LONG
APIENTRY
AVrfpRegOpenKeyExA (
IN HKEY hKey,
IN LPCSTR lpSubKey,
IN DWORD ulOptions,
IN REGSAM samDesired,
OUT PHKEY phkResult
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCSTR, DWORD, REGSAM, PHKEY);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGOPENKEYEXA);
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return ERROR_OUTOFMEMORY;
}
return (* Function) (hKey,
lpSubKey,
ulOptions,
samDesired,
phkResult);
}
//WINADVAPI
LONG
APIENTRY
AVrfpRegOpenKeyExW (
IN HKEY hKey,
IN LPCWSTR lpSubKey,
IN DWORD ulOptions,
IN REGSAM samDesired,
OUT PHKEY phkResult
)
{
typedef LONG (APIENTRY * FUNCTION_TYPE)
(HKEY, LPCWSTR, DWORD, REGSAM, PHKEY);
FUNCTION_TYPE Function;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpAdvapi32Thunks,
AVRF_INDEX_ADVAPI32_REGOPENKEYEXW);
if (SHOULD_FAULT_INJECT(CLS_REGISTRY_APIS)) {
CHECK_BREAK (BRK_CREATE_KEY_FAIL);
return ERROR_OUTOFMEMORY;
}
return (* Function) (hKey,
lpSubKey,
ulOptions,
samDesired,
phkResult);
}
/////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////// Read/Write File I/O
/////////////////////////////////////////////////////////////////////
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtReadFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
)
{
NTSTATUS Status;
//
// Fill the I/O buffer with garbage.
//
// silviuc: should we link this fill to some feature?
// In principle the operation of filling memory is peanuts
// compared with the time taken by the i/o operation.
//
RtlFillMemory (Buffer, Length, 0xFA);
//
// Call original API.
//
Status = NtReadFile (FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
Buffer,
Length,
ByteOffset,
Key);
//
// Asynchronous operations are delayed a bit. This conceivably
// has good chances to randomize timings in the process.
//
if (Status == STATUS_PENDING) {
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_RACE_CHECKS)) {
AVrfpCreateRandomDelay ();
}
}
return Status;
}
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtReadFileScatter(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PFILE_SEGMENT_ELEMENT SegmentArray,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
)
{
NTSTATUS Status;
//
// silviuc: we should fill these buffers with garbage too.
//
//
// Call original API.
//
Status = NtReadFileScatter (FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
SegmentArray,
Length,
ByteOffset,
Key);
//
// Asynchronous operations are delayed a bit. This conceivably
// has good chances to randomize timings in the process.
//
if (Status == STATUS_PENDING) {
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_RACE_CHECKS)) {
AVrfpCreateRandomDelay ();
}
}
return Status;
}
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
)
{
NTSTATUS Status;
//
// Call original API.
//
Status = NtWriteFile (FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
Buffer,
Length,
ByteOffset,
Key);
//
// Asynchronous operations are delayed a bit. This conceivably
// has good chances to randomize timings in the process.
//
if (Status == STATUS_PENDING) {
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_RACE_CHECKS)) {
AVrfpCreateRandomDelay ();
}
}
return Status;
}
//NTSYSCALLAPI
NTSTATUS
NTAPI
AVrfpNtWriteFileGather(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PFILE_SEGMENT_ELEMENT SegmentArray,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
)
{
NTSTATUS Status;
//
// Call original API.
//
Status = NtWriteFileGather (FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
SegmentArray,
Length,
ByteOffset,
Key);
//
// Asynchronous operations are delayed a bit. This conceivably
// has good chances to randomize timings in the process.
//
if (Status == STATUS_PENDING) {
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_RACE_CHECKS)) {
AVrfpCreateRandomDelay ();
}
}
return Status;
}
/////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////// Tick count overlap
/////////////////////////////////////////////////////////////////////
//
// Special value so that the counter will overlap in 5 mins.
//
DWORD AVrfpTickCountOffset = 0xFFFFFFFF - 5 * 60 * 1000;
//WINBASEAPI
DWORD
WINAPI
AVrfpGetTickCount(
VOID
)
{
typedef DWORD (WINAPI * FUNCTION_TYPE) (VOID);
FUNCTION_TYPE Function;
DWORD Result;
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
AVRF_INDEX_KERNEL32_GETTICKCOUNT);
Result = (* Function) ();
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_MISCELLANEOUS_CHECKS)) {
return Result + AVrfpTickCountOffset;
}
else {
return Result;
}
}