Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: dll/win32/kernel32/client/utils.c * PURPOSE: Utility and Support Functions * PROGRAMMER: Alex Ionescu (alex@relsoft.net) * Pierre Schweitzer (pierre.schweitzer@reactos.org) */
/* INCLUDES ******************************************************************/
#include <k32.h>#ifdef _M_IX86#include "i386/ketypes.h"#elif defined _M_AMD64#include "amd64/ketypes.h"#endif
#define NDEBUG#include <debug.h>
/* GLOBALS ********************************************************************/
UNICODE_STRING Restricted = RTL_CONSTANT_STRING(L"Restricted");BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
PRTL_CONVERT_STRING Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;PRTL_CONVERT_STRINGA BasepUnicodeStringTo8BitString = RtlUnicodeStringToAnsiString;PRTL_COUNT_STRING BasepUnicodeStringTo8BitSize = BasepUnicodeStringToAnsiSize;PRTL_COUNT_STRINGA Basep8BitStringToUnicodeSize = BasepAnsiStringToUnicodeSize;
/* FUNCTIONS ******************************************************************/
ULONGNTAPIBasepUnicodeStringToOemSize(IN PUNICODE_STRING String){ return RtlUnicodeStringToOemSize(String);}
ULONGNTAPIBasepOemStringToUnicodeSize(IN PANSI_STRING String){ return RtlOemStringToUnicodeSize(String);}
ULONGNTAPIBasepUnicodeStringToAnsiSize(IN PUNICODE_STRING String){ return RtlUnicodeStringToAnsiSize(String);}
ULONGNTAPIBasepAnsiStringToUnicodeSize(IN PANSI_STRING String){ return RtlAnsiStringToUnicodeSize(String);}
HANDLEWINAPIBaseGetNamedObjectDirectory(VOID){ OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE DirHandle, BnoHandle, Token, NewToken;
if (BaseNamedObjectDirectory) return BaseNamedObjectDirectory;
if (NtCurrentTeb()->IsImpersonating) { Status = NtOpenThreadToken(NtCurrentThread(), TOKEN_IMPERSONATE, TRUE, &Token); if (!NT_SUCCESS(Status)) return BaseNamedObjectDirectory;
NewToken = NULL; Status = NtSetInformationThread(NtCurrentThread(), ThreadImpersonationToken, &NewToken, sizeof(HANDLE)); if (!NT_SUCCESS (Status)) { NtClose(Token); return BaseNamedObjectDirectory; } } else { Token = NULL; }
RtlAcquirePebLock(); if (BaseNamedObjectDirectory) goto Quickie;
InitializeObjectAttributes(&ObjectAttributes, &BaseStaticServerData->NamedObjectDirectory, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = NtOpenDirectoryObject(&BnoHandle, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY, &ObjectAttributes); if (!NT_SUCCESS(Status)) { Status = NtOpenDirectoryObject(&DirHandle, DIRECTORY_TRAVERSE, &ObjectAttributes);
if (NT_SUCCESS(Status)) { InitializeObjectAttributes(&ObjectAttributes, (PUNICODE_STRING)&Restricted, OBJ_CASE_INSENSITIVE, DirHandle, NULL);
Status = NtOpenDirectoryObject(&BnoHandle, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY, &ObjectAttributes); NtClose(DirHandle);
} }
if (NT_SUCCESS(Status)) BaseNamedObjectDirectory = BnoHandle;
Quickie:
RtlReleasePebLock();
if (Token) { NtSetInformationThread(NtCurrentThread(), ThreadImpersonationToken, &Token, sizeof(Token));
NtClose(Token); }
return BaseNamedObjectDirectory;}
VOIDNTAPIBasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry, IN PVOID Context, OUT BOOLEAN *StopEnumeration){ /* Make sure we get Entry, Context and valid StopEnumeration pointer */ ASSERT(Entry); ASSERT(Context); ASSERT(StopEnumeration);
/* If entry is already found - signal to stop */ if (BasepExeLdrEntry) { *StopEnumeration = TRUE; return; }
/* Otherwise keep enumerating until we find a match */ if (Entry->DllBase == Context) { /* It matches, so remember the ldr entry */ BasepExeLdrEntry = Entry;
/* And stop enumeration */ *StopEnumeration = TRUE; }}
/* * Converts an ANSI or OEM String to the TEB StaticUnicodeString */PUNICODE_STRINGWINAPIBasep8BitStringToStaticUnicodeString(IN LPCSTR String){ PUNICODE_STRING StaticString = &(NtCurrentTeb()->StaticUnicodeString); ANSI_STRING AnsiString; NTSTATUS Status;
/* Initialize an ANSI String */ Status = RtlInitAnsiStringEx(&AnsiString, String); if (!NT_SUCCESS(Status)) { Status = STATUS_BUFFER_OVERFLOW; } else { /* Convert it */ Status = Basep8BitStringToUnicodeString(StaticString, &AnsiString, FALSE); }
if (NT_SUCCESS(Status)) return StaticString;
if (Status == STATUS_BUFFER_OVERFLOW) { SetLastError(ERROR_FILENAME_EXCED_RANGE); } else { BaseSetLastNTError(Status); }
return NULL;}
/* * Allocates space from the Heap and converts an Unicode String into it */BOOLEANWINAPIBasep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String){ ANSI_STRING AnsiString; NTSTATUS Status;
/* Initialize an ANSI String */ Status = RtlInitAnsiStringEx(&AnsiString, String); if (!NT_SUCCESS(Status)) { Status = STATUS_BUFFER_OVERFLOW; } else { /* Convert it */ Status = Basep8BitStringToUnicodeString(UnicodeString, &AnsiString, TRUE); }
if (NT_SUCCESS(Status)) return TRUE;
if (Status == STATUS_BUFFER_OVERFLOW) { SetLastError(ERROR_FILENAME_EXCED_RANGE); } else { BaseSetLastNTError(Status); }
return FALSE;}
/* * Allocates space from the Heap and converts an Ansi String into it */ /*NOTE: API IS A HACK */VOIDWINAPIBasepAnsiStringToHeapUnicodeString(IN LPCSTR AnsiString, OUT LPWSTR* UnicodeString){ ANSI_STRING AnsiTemp; UNICODE_STRING UnicodeTemp;
DPRINT("BasepAnsiStringToHeapUnicodeString\n");
/* First create the ANSI_STRING */ RtlInitAnsiString(&AnsiTemp, AnsiString);
if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeTemp, &AnsiTemp, TRUE))) { *UnicodeString = UnicodeTemp.Buffer; } else { *UnicodeString = NULL; }}
PLARGE_INTEGERWINAPIBaseFormatTimeOut(OUT PLARGE_INTEGER Timeout, IN DWORD dwMilliseconds){ /* Check if this is an infinite wait, which means no timeout argument */ if (dwMilliseconds == INFINITE) return NULL;
/* Otherwise, convert the time to NT Format */ Timeout->QuadPart = dwMilliseconds * -10000LL; return Timeout;}
/* * Converts lpSecurityAttributes + Object Name into ObjectAttributes. */POBJECT_ATTRIBUTESWINAPIBaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes, IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL, IN PUNICODE_STRING ObjectName){ ULONG Attributes; HANDLE RootDirectory; PVOID SecurityDescriptor; DPRINT("BaseFormatObjectAttributes. Security: %p, Name: %p\n", SecurityAttributes, ObjectName);
/* Get the attributes if present */ if (SecurityAttributes) { Attributes = SecurityAttributes->bInheritHandle ? OBJ_INHERIT : 0; SecurityDescriptor = SecurityAttributes->lpSecurityDescriptor; } else { if (!ObjectName) return NULL; Attributes = 0; SecurityDescriptor = NULL; }
if (ObjectName) { Attributes |= OBJ_OPENIF; RootDirectory = BaseGetNamedObjectDirectory(); } else { RootDirectory = NULL; }
/* Create the Object Attributes */ InitializeObjectAttributes(ObjectAttributes, ObjectName, Attributes, RootDirectory, SecurityDescriptor); DPRINT("Attributes: %lx, RootDirectory: %p, SecurityDescriptor: %p\n", Attributes, RootDirectory, SecurityDescriptor); return ObjectAttributes;}
/* * Creates a stack for a thread or fiber. * NOTE: Adapted from sdk/lib/rtl/thread.c:RtlpCreateUserStack(). */NTSTATUSWINAPIBaseCreateStack( _In_ HANDLE hProcess, _In_opt_ SIZE_T StackCommit, _In_opt_ SIZE_T StackReserve, _Out_ PINITIAL_TEB InitialTeb){ NTSTATUS Status; PIMAGE_NT_HEADERS Headers; ULONG_PTR Stack; BOOLEAN UseGuard; ULONG PageSize, AllocationGranularity, Dummy; SIZE_T MinimumStackCommit, GuardPageSize;
DPRINT("BaseCreateStack(hProcess: 0x%p, Max: 0x%lx, Current: 0x%lx)\n", hProcess, StackReserve, StackCommit);
/* Read page size */ PageSize = BaseStaticServerData->SysInfo.PageSize; AllocationGranularity = BaseStaticServerData->SysInfo.AllocationGranularity;
/* Get the Image Headers */ Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); if (!Headers) return STATUS_INVALID_IMAGE_FORMAT;
if (StackReserve == 0) StackReserve = Headers->OptionalHeader.SizeOfStackReserve;
if (StackCommit == 0) { StackCommit = Headers->OptionalHeader.SizeOfStackCommit; } /* Check if the commit is higher than the reserve */ else if (StackCommit >= StackReserve) { /* Grow the reserve beyond the commit, up to 1MB alignment */ StackReserve = ROUND_UP(StackCommit, 1024 * 1024); }
/* Align everything to Page Size */ StackCommit = ROUND_UP(StackCommit, PageSize); StackReserve = ROUND_UP(StackReserve, AllocationGranularity);
MinimumStackCommit = NtCurrentPeb()->MinimumStackCommit; if ((MinimumStackCommit != 0) && (StackCommit < MinimumStackCommit)) { StackCommit = MinimumStackCommit; }
/* Check if the commit is higher than the reserve */ if (StackCommit >= StackReserve) { /* Grow the reserve beyond the commit, up to 1MB alignment */ StackReserve = ROUND_UP(StackCommit, 1024 * 1024); }
/* Align everything to Page Size */ StackCommit = ROUND_UP(StackCommit, PageSize); StackReserve = ROUND_UP(StackReserve, AllocationGranularity);
/* Reserve memory for the stack */ Stack = 0; Status = NtAllocateVirtualMemory(hProcess, (PVOID*)&Stack, 0, &StackReserve, MEM_RESERVE, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failure to reserve stack: %lx\n", Status); return Status; }
/* Now set up some basic Initial TEB Parameters */ InitialTeb->AllocatedStackBase = (PVOID)Stack; InitialTeb->StackBase = (PVOID)(Stack + StackReserve); InitialTeb->PreviousStackBase = NULL; InitialTeb->PreviousStackLimit = NULL;
/* Update the stack position */ Stack += StackReserve - StackCommit;
/* Check if we can add a guard page */ if (StackReserve >= StackCommit + PageSize) { Stack -= PageSize; StackCommit += PageSize; UseGuard = TRUE; } else { UseGuard = FALSE; }
/* Allocate memory for the stack */ Status = NtAllocateVirtualMemory(hProcess, (PVOID*)&Stack, 0, &StackCommit, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failure to allocate stack\n"); GuardPageSize = 0; NtFreeVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, MEM_RELEASE); return Status; }
/* Now set the current Stack Limit */ InitialTeb->StackLimit = (PVOID)Stack;
/* Create a guard page if needed */ if (UseGuard) { GuardPageSize = PageSize; Status = NtProtectVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, PAGE_GUARD | PAGE_READWRITE, &Dummy); if (!NT_SUCCESS(Status)) { DPRINT1("Failure to set guard page\n"); return Status; }
/* Update the Stack Limit keeping in mind the Guard Page */ InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit + GuardPageSize); }
/* We are done! */ return STATUS_SUCCESS;}
/* * NOTE: Adapted from sdk/lib/rtl/thread.c:RtlpFreeUserStack(). */VOIDWINAPIBaseFreeThreadStack( _In_ HANDLE hProcess, _In_ PINITIAL_TEB InitialTeb){ SIZE_T Dummy = 0;
/* Free the Stack */ NtFreeVirtualMemory(hProcess, &InitialTeb->AllocatedStackBase, &Dummy, MEM_RELEASE);}
/* * Creates the Initial Context for a Thread or Fiber */VOIDWINAPIBaseInitializeContext(IN PCONTEXT Context, IN PVOID Parameter, IN PVOID StartAddress, IN PVOID StackAddress, IN ULONG ContextType){#ifdef _M_IX86 ULONG ContextFlags; DPRINT("BaseInitializeContext: %p\n", Context);
/* Setup the Initial Win32 Thread Context */ Context->Eax = (ULONG)StartAddress; Context->Ebx = (ULONG)Parameter; Context->Esp = (ULONG)StackAddress; /* The other registers are undefined */
/* Setup the Segments */ Context->SegFs = KGDT_R3_TEB; Context->SegEs = KGDT_R3_DATA; Context->SegDs = KGDT_R3_DATA; Context->SegCs = KGDT_R3_CODE; Context->SegSs = KGDT_R3_DATA; Context->SegGs = 0;
/* Set the Context Flags */ ContextFlags = Context->ContextFlags; Context->ContextFlags = CONTEXT_FULL;
/* Give it some room for the Parameter */ Context->Esp -= sizeof(PVOID);
/* Set the EFLAGS */ Context->EFlags = 0x3000; /* IOPL 3 */
/* What kind of context is being created? */ if (ContextType == 1) { /* For Threads */ Context->Eip = (ULONG)BaseThreadStartupThunk; } else if (ContextType == 2) { /* This is a fiber: make space for the return address */ Context->Esp -= sizeof(PVOID); *((PVOID*)Context->Esp) = BaseFiberStartup;
/* Is FPU state required? */ Context->ContextFlags |= ContextFlags; if ((ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) { /* Set an initial state */ Context->FloatSave.ControlWord = 0x27F; Context->FloatSave.StatusWord = 0; Context->FloatSave.TagWord = 0xFFFF; Context->FloatSave.ErrorOffset = 0; Context->FloatSave.ErrorSelector = 0; Context->FloatSave.DataOffset = 0; Context->FloatSave.DataSelector = 0; if (SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE]) Context->Dr6 = 0x1F80; } } else { /* For first thread in a Process */ Context->Eip = (ULONG)BaseProcessStartThunk; }
#elif defined(_M_AMD64) DPRINT("BaseInitializeContext: %p\n", Context); ASSERT(((ULONG_PTR)StackAddress & 15) == 0);
RtlZeroMemory(Context, sizeof(*Context));
/* Setup the Initial Win32 Thread Context */ Context->Rcx = (ULONG_PTR)StartAddress; Context->Rdx = (ULONG_PTR)Parameter; Context->Rsp = (ULONG_PTR)StackAddress - 5 * sizeof(PVOID);
/* Setup the Segments */ Context->SegGs = KGDT64_R3_DATA | RPL_MASK; Context->SegEs = KGDT64_R3_DATA | RPL_MASK; Context->SegDs = KGDT64_R3_DATA | RPL_MASK; Context->SegCs = KGDT64_R3_CODE | RPL_MASK; Context->SegSs = KGDT64_R3_DATA | RPL_MASK; Context->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
/* Set the EFLAGS */ Context->EFlags = 0x3000 | EFLAGS_INTERRUPT_MASK; /* IOPL 3 */
/* Set MXCSR */ Context->MxCsr = INITIAL_MXCSR;
if (ContextType == 1) /* For Threads */ { Context->Rip = (ULONG_PTR)BaseThreadStartup; } else if (ContextType == 2) /* For Fibers */ { Context->Rip = (ULONG_PTR)BaseFiberStartup; } else /* For first thread in a Process */ { Context->Rip = (ULONG_PTR)BaseProcessStartup; }
/* Set the Context Flags */ Context->ContextFlags = CONTEXT_FULL;#elif defined(_M_ARM) DPRINT("BaseInitializeContext: %p\n", Context);
// FIXME: check if this is correct! /* Setup the Initial Win32 Thread Context */ Context->R0 = (ULONG_PTR)StartAddress; Context->R1 = (ULONG_PTR)Parameter; Context->Sp = (ULONG_PTR)StackAddress;
if (ContextType == 1) /* For Threads */ { Context->Pc = (ULONG_PTR)BaseThreadStartupThunk; } else if (ContextType == 2) /* For Fibers */ { Context->Pc = (ULONG_PTR)BaseFiberStartup; } else /* For first thread in a Process */ { Context->Pc = (ULONG_PTR)BaseProcessStartThunk; }
/* Set the Context Flags */ Context->ContextFlags = CONTEXT_FULL;
/* Give it some room for the Parameter */ Context->Sp -= sizeof(PVOID);#else#warning Unknown architecture UNIMPLEMENTED; DbgBreakPoint();#endif}
/* * Checks if the privilege for Real-Time Priority is there * Beware about this function behavior: * - In case Keep is set to FALSE, then the function will only check * whether real time is allowed and won't grant the privilege. In that case * it will return TRUE if allowed, FALSE otherwise. Not a state! * It means you don't have to release privilege when calling with FALSE. */PVOIDWINAPIBasepIsRealtimeAllowed(IN BOOLEAN Keep){ ULONG Privilege = SE_INC_BASE_PRIORITY_PRIVILEGE; PVOID State; NTSTATUS Status;
Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State); if (!NT_SUCCESS(Status)) return NULL;
if (!Keep) { RtlReleasePrivilege(State); State = (PVOID)TRUE; }
return State;}
/* * Maps an image file into a section */NTSTATUSWINAPIBasepMapFile(IN LPCWSTR lpApplicationName, OUT PHANDLE hSection, IN PUNICODE_STRING ApplicationName){ RTL_RELATIVE_NAME_U RelativeName; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE hFile = NULL; IO_STATUS_BLOCK IoStatusBlock;
DPRINT("BasepMapFile\n");
/* Zero out the Relative Directory */ RelativeName.ContainingDirectory = NULL;
/* Find the application name */ if (!RtlDosPathNameToNtPathName_U(lpApplicationName, ApplicationName, NULL, &RelativeName)) { return STATUS_OBJECT_PATH_NOT_FOUND; }
DPRINT("ApplicationName %wZ\n", ApplicationName); DPRINT("RelativeName %wZ\n", &RelativeName.RelativeName);
/* Did we get a relative name? */ if (RelativeName.RelativeName.Length) { ApplicationName = &RelativeName.RelativeName; }
/* Initialize the Object Attributes */ InitializeObjectAttributes(&ObjectAttributes, ApplicationName, OBJ_CASE_INSENSITIVE, RelativeName.ContainingDirectory, NULL);
/* Try to open the executable */ Status = NtOpenFile(&hFile, SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_DELETE | FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open file\n"); BaseSetLastNTError(Status); return Status; }
/* Create a section for this file */ Status = NtCreateSection(hSection, SECTION_ALL_ACCESS, NULL, NULL, PAGE_EXECUTE, SEC_IMAGE, hFile); NtClose(hFile);
/* Return status */ DPRINT("Section: %p for file: %p\n", *hSection, hFile); return Status;}
/* * @implemented */BOOLEANWINAPIWow64EnableWow64FsRedirection(IN BOOLEAN Wow64EnableWow64FsRedirection){ NTSTATUS Status; BOOL Result;
Status = RtlWow64EnableFsRedirection(Wow64EnableWow64FsRedirection); if (NT_SUCCESS(Status)) { Result = TRUE; } else { BaseSetLastNTError(Status); Result = FALSE; } return Result;}
/* * @implemented */BOOLWINAPIWow64DisableWow64FsRedirection(IN PVOID *OldValue){ NTSTATUS Status; BOOL Result;
Status = RtlWow64EnableFsRedirectionEx((PVOID)TRUE, OldValue); if (NT_SUCCESS(Status)) { Result = TRUE; } else { BaseSetLastNTError(Status); Result = FALSE; } return Result;}
/* * @implemented */BOOLWINAPIWow64RevertWow64FsRedirection(IN PVOID OldValue){ NTSTATUS Status; BOOL Result;
Status = RtlWow64EnableFsRedirectionEx(OldValue, &OldValue); if (NT_SUCCESS(Status)) { Result = TRUE; } else { BaseSetLastNTError(Status); Result = FALSE; } return Result;}
/* * @implemented */VOIDWINAPISetFileApisToOEM(VOID){ /* Set the correct Base Api */ Basep8BitStringToUnicodeString = (PRTL_CONVERT_STRING)RtlOemStringToUnicodeString; BasepUnicodeStringTo8BitString = RtlUnicodeStringToOemString; BasepUnicodeStringTo8BitSize = BasepUnicodeStringToOemSize; Basep8BitStringToUnicodeSize = BasepOemStringToUnicodeSize;
/* FIXME: Old, deprecated way */ bIsFileApiAnsi = FALSE;}
/* * @implemented */VOIDWINAPISetFileApisToANSI(VOID){ /* Set the correct Base Api */ Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString; BasepUnicodeStringTo8BitString = RtlUnicodeStringToAnsiString; BasepUnicodeStringTo8BitSize = BasepUnicodeStringToAnsiSize; Basep8BitStringToUnicodeSize = BasepAnsiStringToUnicodeSize;
/* FIXME: Old, deprecated way */ bIsFileApiAnsi = TRUE;}
/* * @implemented */BOOLWINAPIAreFileApisANSI(VOID){ return Basep8BitStringToUnicodeString == RtlAnsiStringToUnicodeString;}
/* * @implemented */VOIDWINAPIBaseMarkFileForDelete(IN HANDLE FileHandle, IN ULONG FileAttributes){ IO_STATUS_BLOCK IoStatusBlock; FILE_BASIC_INFORMATION FileBasicInfo; FILE_DISPOSITION_INFORMATION FileDispositionInfo;
/* If no attributes were given, get them */ if (!FileAttributes) { FileBasicInfo.FileAttributes = 0; NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileBasicInfo, sizeof(FileBasicInfo), FileBasicInformation); FileAttributes = FileBasicInfo.FileAttributes; }
/* If file is marked as RO, reset its attributes */ if (FileAttributes & FILE_ATTRIBUTE_READONLY) { RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo)); FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; NtSetInformationFile(FileHandle, &IoStatusBlock, &FileBasicInfo, sizeof(FileBasicInfo), FileBasicInformation); }
/* Finally, mark the file for deletion */ FileDispositionInfo.DeleteFile = TRUE; NtSetInformationFile(FileHandle, &IoStatusBlock, &FileDispositionInfo, sizeof(FileDispositionInfo), FileDispositionInformation);}
/* * @unimplemented */NTSTATUSWINAPIBasepCheckWinSaferRestrictions(IN HANDLE UserToken, IN LPWSTR ApplicationName, IN HANDLE FileHandle, OUT PBOOLEAN InJob, OUT PHANDLE NewToken, OUT PHANDLE JobHandle){ NTSTATUS Status;
/* Validate that there's a name */ if ((ApplicationName) && *(ApplicationName)) { /* Validate that the required output parameters are there */ if ((InJob) && (NewToken) && (JobHandle)) { /* Do the work (one day...) */ DPRINT("BasepCheckWinSaferRestrictions is UNIMPLEMENTED\n"); Status = STATUS_SUCCESS; } else { /* Act as if SEH hit this */ Status = STATUS_ACCESS_VIOLATION; } } else { /* Input is invalid */ Status = STATUS_INVALID_PARAMETER; }
/* Return the status */ return Status;}