Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenutils.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS system libraries 00004 * FILE: lib/kernel32/misc/utils.c 00005 * PURPOSE: Utility and Support Functions 00006 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 00007 * Pierre Schweitzer (pierre.schweitzer@reactos.org) 00008 */ 00009 00010 /* INCLUDES ******************************************************************/ 00011 00012 #include <k32.h> 00013 #ifdef _M_IX86 00014 #include "i386/ketypes.h" 00015 #elif defined _M_AMD64 00016 #include "amd64/ketypes.h" 00017 #endif 00018 00019 #define NDEBUG 00020 #include <debug.h> 00021 00022 /* GLOBALS ********************************************************************/ 00023 00024 UNICODE_STRING Restricted = RTL_CONSTANT_STRING(L"Restricted"); 00025 BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem 00026 PRTL_CONVERT_STRING Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString; 00027 PRTL_CONVERT_STRINGA BasepUnicodeStringTo8BitString = RtlUnicodeStringToAnsiString; 00028 PRTL_COUNT_STRING BasepUnicodeStringTo8BitSize = BasepUnicodeStringToAnsiSize; 00029 PRTL_COUNT_STRINGA Basep8BitStringToUnicodeSize = BasepAnsiStringToUnicodeSize; 00030 00031 /* FUNCTIONS ******************************************************************/ 00032 00033 ULONG 00034 NTAPI 00035 BasepUnicodeStringToOemSize(IN PUNICODE_STRING String) 00036 { 00037 return RtlUnicodeStringToOemSize(String); 00038 } 00039 00040 ULONG 00041 NTAPI 00042 BasepOemStringToUnicodeSize(IN PANSI_STRING String) 00043 { 00044 return RtlOemStringToUnicodeSize(String); 00045 } 00046 00047 ULONG 00048 NTAPI 00049 BasepUnicodeStringToAnsiSize(IN PUNICODE_STRING String) 00050 { 00051 return RtlUnicodeStringToAnsiSize(String); 00052 } 00053 00054 ULONG 00055 NTAPI 00056 BasepAnsiStringToUnicodeSize(IN PANSI_STRING String) 00057 { 00058 return RtlAnsiStringToUnicodeSize(String); 00059 } 00060 00061 HANDLE 00062 WINAPI 00063 BaseGetNamedObjectDirectory(VOID) 00064 { 00065 OBJECT_ATTRIBUTES ObjectAttributes; 00066 NTSTATUS Status; 00067 HANDLE DirHandle, BnoHandle, Token, NewToken; 00068 00069 if (BaseNamedObjectDirectory) return BaseNamedObjectDirectory; 00070 00071 if (NtCurrentTeb()->IsImpersonating) 00072 { 00073 Status = NtOpenThreadToken(NtCurrentThread(), 00074 TOKEN_IMPERSONATE, 00075 TRUE, 00076 &Token); 00077 if (!NT_SUCCESS(Status)) return BaseNamedObjectDirectory; 00078 00079 NewToken = NULL; 00080 Status = NtSetInformationThread(NtCurrentThread(), 00081 ThreadImpersonationToken, 00082 &NewToken, 00083 sizeof(HANDLE)); 00084 if (!NT_SUCCESS (Status)) 00085 { 00086 NtClose(Token); 00087 return BaseNamedObjectDirectory; 00088 } 00089 } 00090 else 00091 { 00092 Token = NULL; 00093 } 00094 00095 RtlAcquirePebLock(); 00096 if (BaseNamedObjectDirectory) goto Quickie; 00097 00098 InitializeObjectAttributes(&ObjectAttributes, 00099 &BaseStaticServerData->NamedObjectDirectory, 00100 OBJ_CASE_INSENSITIVE, 00101 NULL, 00102 NULL); 00103 00104 Status = NtOpenDirectoryObject(&BnoHandle, 00105 DIRECTORY_QUERY | 00106 DIRECTORY_TRAVERSE | 00107 DIRECTORY_CREATE_OBJECT | 00108 DIRECTORY_CREATE_SUBDIRECTORY, 00109 &ObjectAttributes); 00110 if (!NT_SUCCESS(Status)) 00111 { 00112 Status = NtOpenDirectoryObject(&DirHandle, 00113 DIRECTORY_TRAVERSE, 00114 &ObjectAttributes); 00115 00116 if (NT_SUCCESS(Status)) 00117 { 00118 InitializeObjectAttributes(&ObjectAttributes, 00119 (PUNICODE_STRING)&Restricted, 00120 OBJ_CASE_INSENSITIVE, 00121 DirHandle, 00122 NULL); 00123 00124 Status = NtOpenDirectoryObject(&BnoHandle, 00125 DIRECTORY_QUERY | 00126 DIRECTORY_TRAVERSE | 00127 DIRECTORY_CREATE_OBJECT | 00128 DIRECTORY_CREATE_SUBDIRECTORY, 00129 &ObjectAttributes); 00130 NtClose(DirHandle); 00131 00132 } 00133 } 00134 00135 if (NT_SUCCESS(Status)) BaseNamedObjectDirectory = BnoHandle; 00136 00137 Quickie: 00138 00139 RtlReleasePebLock(); 00140 00141 if (Token) 00142 { 00143 NtSetInformationThread(NtCurrentThread(), 00144 ThreadImpersonationToken, 00145 &Token, 00146 sizeof(Token)); 00147 00148 NtClose(Token); 00149 } 00150 00151 return BaseNamedObjectDirectory; 00152 } 00153 00154 VOID 00155 NTAPI 00156 BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry, 00157 IN PVOID Context, 00158 OUT BOOLEAN *StopEnumeration) 00159 { 00160 /* Make sure we get Entry, Context and valid StopEnumeration pointer */ 00161 ASSERT(Entry); 00162 ASSERT(Context); 00163 ASSERT(StopEnumeration); 00164 00165 /* If entry is already found - signal to stop */ 00166 if (BasepExeLdrEntry) 00167 { 00168 *StopEnumeration = TRUE; 00169 return; 00170 } 00171 00172 /* Otherwise keep enumerating until we find a match */ 00173 if (Entry->DllBase == Context) 00174 { 00175 /* It matches, so remember the ldr entry */ 00176 BasepExeLdrEntry = Entry; 00177 00178 /* And stop enumeration */ 00179 *StopEnumeration = TRUE; 00180 } 00181 } 00182 00183 /* 00184 * Converts an ANSI or OEM String to the TEB StaticUnicodeString 00185 */ 00186 PUNICODE_STRING 00187 WINAPI 00188 Basep8BitStringToStaticUnicodeString(IN LPCSTR String) 00189 { 00190 PUNICODE_STRING StaticString = &(NtCurrentTeb()->StaticUnicodeString); 00191 ANSI_STRING AnsiString; 00192 NTSTATUS Status; 00193 00194 /* Initialize an ANSI String */ 00195 Status = RtlInitAnsiStringEx(&AnsiString, String); 00196 if (!NT_SUCCESS(Status)) 00197 { 00198 Status = STATUS_BUFFER_OVERFLOW; 00199 } 00200 else 00201 { 00202 /* Convert it */ 00203 Status = Basep8BitStringToUnicodeString(StaticString, &AnsiString, FALSE); 00204 } 00205 00206 if (NT_SUCCESS(Status)) return StaticString; 00207 00208 if (Status == STATUS_BUFFER_OVERFLOW) 00209 { 00210 SetLastError(ERROR_FILENAME_EXCED_RANGE); 00211 } 00212 else 00213 { 00214 BaseSetLastNTError(Status); 00215 } 00216 00217 return NULL; 00218 } 00219 00220 /* 00221 * Allocates space from the Heap and converts an Unicode String into it 00222 */ 00223 BOOLEAN 00224 WINAPI 00225 Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, 00226 IN LPCSTR String) 00227 { 00228 ANSI_STRING AnsiString; 00229 NTSTATUS Status; 00230 00231 /* Initialize an ANSI String */ 00232 Status = RtlInitAnsiStringEx(&AnsiString, String); 00233 if (!NT_SUCCESS(Status)) 00234 { 00235 Status = STATUS_BUFFER_OVERFLOW; 00236 } 00237 else 00238 { 00239 /* Convert it */ 00240 Status = Basep8BitStringToUnicodeString(UnicodeString, &AnsiString, TRUE); 00241 } 00242 00243 if (NT_SUCCESS(Status)) return TRUE; 00244 00245 if (Status == STATUS_BUFFER_OVERFLOW) 00246 { 00247 SetLastError(ERROR_FILENAME_EXCED_RANGE); 00248 } 00249 else 00250 { 00251 BaseSetLastNTError(Status); 00252 } 00253 00254 return FALSE; 00255 } 00256 00257 /* 00258 * Allocates space from the Heap and converts an Ansi String into it 00259 */ 00260 /*NOTE: API IS A HACK */ 00261 VOID 00262 WINAPI 00263 BasepAnsiStringToHeapUnicodeString(IN LPCSTR AnsiString, 00264 OUT LPWSTR* UnicodeString) 00265 { 00266 ANSI_STRING AnsiTemp; 00267 UNICODE_STRING UnicodeTemp; 00268 00269 DPRINT("BasepAnsiStringToHeapUnicodeString\n"); 00270 00271 /* First create the ANSI_STRING */ 00272 RtlInitAnsiString(&AnsiTemp, AnsiString); 00273 00274 if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeTemp, 00275 &AnsiTemp, 00276 TRUE))) 00277 { 00278 *UnicodeString = UnicodeTemp.Buffer; 00279 } 00280 else 00281 { 00282 *UnicodeString = NULL; 00283 } 00284 } 00285 00286 PLARGE_INTEGER 00287 WINAPI 00288 BaseFormatTimeOut(OUT PLARGE_INTEGER Timeout, 00289 IN DWORD dwMilliseconds) 00290 { 00291 /* Check if this is an infinite wait, which means no timeout argument */ 00292 if (dwMilliseconds == INFINITE) return NULL; 00293 00294 /* Otherwise, convert the time to NT Format */ 00295 Timeout->QuadPart = UInt32x32To64(dwMilliseconds, -10000); 00296 return Timeout; 00297 } 00298 00299 /* 00300 * Converts lpSecurityAttributes + Object Name into ObjectAttributes. 00301 */ 00302 POBJECT_ATTRIBUTES 00303 WINAPI 00304 BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes, 00305 IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL, 00306 IN PUNICODE_STRING ObjectName) 00307 { 00308 ULONG Attributes; 00309 HANDLE RootDirectory; 00310 PVOID SecurityDescriptor; 00311 DPRINT("BaseFormatObjectAttributes. Security: %p, Name: %p\n", 00312 SecurityAttributes, ObjectName); 00313 00314 /* Get the attributes if present */ 00315 if (SecurityAttributes) 00316 { 00317 Attributes = SecurityAttributes->bInheritHandle ? OBJ_INHERIT : 0; 00318 SecurityDescriptor = SecurityAttributes->lpSecurityDescriptor; 00319 } 00320 else 00321 { 00322 if (!ObjectName) return NULL; 00323 Attributes = 0; 00324 SecurityDescriptor = NULL; 00325 } 00326 00327 if (ObjectName) 00328 { 00329 Attributes |= OBJ_OPENIF; 00330 RootDirectory = BaseGetNamedObjectDirectory(); 00331 } 00332 else 00333 { 00334 RootDirectory = NULL; 00335 } 00336 00337 /* Create the Object Attributes */ 00338 InitializeObjectAttributes(ObjectAttributes, 00339 ObjectName, 00340 Attributes, 00341 RootDirectory, 00342 SecurityDescriptor); 00343 DPRINT("Attributes: %lx, RootDirectory: %lx, SecurityDescriptor: %p\n", 00344 Attributes, RootDirectory, SecurityDescriptor); 00345 return ObjectAttributes; 00346 } 00347 00348 /* 00349 * Creates a stack for a thread or fiber 00350 */ 00351 NTSTATUS 00352 WINAPI 00353 BaseCreateStack(HANDLE hProcess, 00354 SIZE_T StackReserve, 00355 SIZE_T StackCommit, 00356 PINITIAL_TEB InitialTeb) 00357 { 00358 NTSTATUS Status; 00359 PIMAGE_NT_HEADERS Headers; 00360 ULONG_PTR Stack; 00361 BOOLEAN UseGuard; 00362 ULONG PageSize, Dummy, AllocationGranularity; 00363 SIZE_T StackReserveHeader, StackCommitHeader, GuardPageSize, GuaranteedStackCommit; 00364 DPRINT("BaseCreateStack (hProcess: %lx, Max: %lx, Current: %lx)\n", 00365 hProcess, StackReserve, StackCommit); 00366 00367 /* Read page size */ 00368 PageSize = BaseStaticServerData->SysInfo.PageSize; 00369 AllocationGranularity = BaseStaticServerData->SysInfo.AllocationGranularity; 00370 00371 /* Get the Image Headers */ 00372 Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); 00373 if (!Headers) return STATUS_INVALID_IMAGE_FORMAT; 00374 00375 StackCommitHeader = Headers->OptionalHeader.SizeOfStackCommit; 00376 StackReserveHeader = Headers->OptionalHeader.SizeOfStackReserve; 00377 00378 if (!StackReserve) StackReserve = StackReserveHeader; 00379 00380 if (!StackCommit) 00381 { 00382 StackCommit = StackCommitHeader; 00383 } 00384 else if (StackCommit >= StackReserve) 00385 { 00386 StackReserve = ROUND_UP(StackCommit, 1024 * 1024); 00387 } 00388 00389 StackCommit = ROUND_UP(StackCommit, PageSize); 00390 StackReserve = ROUND_UP(StackReserve, AllocationGranularity); 00391 00392 GuaranteedStackCommit = NtCurrentTeb()->GuaranteedStackBytes; 00393 if ((GuaranteedStackCommit) && (StackCommit < GuaranteedStackCommit)) 00394 { 00395 StackCommit = GuaranteedStackCommit; 00396 } 00397 00398 if (StackCommit >= StackReserve) 00399 { 00400 StackReserve = ROUND_UP(StackCommit, 1024 * 1024); 00401 } 00402 00403 StackCommit = ROUND_UP(StackCommit, PageSize); 00404 StackReserve = ROUND_UP(StackReserve, AllocationGranularity); 00405 00406 /* ROS Hack until we support guard page stack expansion */ 00407 StackCommit = StackReserve; 00408 00409 /* Reserve memory for the stack */ 00410 Stack = 0; 00411 Status = NtAllocateVirtualMemory(hProcess, 00412 (PVOID*)&Stack, 00413 0, 00414 &StackReserve, 00415 MEM_RESERVE, 00416 PAGE_READWRITE); 00417 if (!NT_SUCCESS(Status)) 00418 { 00419 DPRINT1("Failure to reserve stack: %lx\n", Status); 00420 return Status; 00421 } 00422 00423 /* Now set up some basic Initial TEB Parameters */ 00424 InitialTeb->AllocatedStackBase = (PVOID)Stack; 00425 InitialTeb->StackBase = (PVOID)(Stack + StackReserve); 00426 InitialTeb->PreviousStackBase = NULL; 00427 InitialTeb->PreviousStackLimit = NULL; 00428 00429 /* Update the Stack Position */ 00430 Stack += StackReserve - StackCommit; 00431 00432 /* Check if we will need a guard page */ 00433 if (StackReserve > StackCommit) 00434 { 00435 Stack -= PageSize; 00436 StackCommit += PageSize; 00437 UseGuard = TRUE; 00438 } 00439 else 00440 { 00441 UseGuard = FALSE; 00442 } 00443 00444 /* Allocate memory for the stack */ 00445 Status = NtAllocateVirtualMemory(hProcess, 00446 (PVOID*)&Stack, 00447 0, 00448 &StackCommit, 00449 MEM_COMMIT, 00450 PAGE_READWRITE); 00451 if (!NT_SUCCESS(Status)) 00452 { 00453 DPRINT1("Failure to allocate stack\n"); 00454 GuardPageSize = 0; 00455 NtFreeVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, MEM_RELEASE); 00456 return Status; 00457 } 00458 00459 /* Now set the current Stack Limit */ 00460 InitialTeb->StackLimit = (PVOID)Stack; 00461 00462 /* Create a guard page */ 00463 if (UseGuard) 00464 { 00465 /* Set the guard page */ 00466 GuardPageSize = PAGE_SIZE; 00467 Status = NtProtectVirtualMemory(hProcess, 00468 (PVOID*)&Stack, 00469 &GuardPageSize, 00470 PAGE_GUARD | PAGE_READWRITE, 00471 &Dummy); 00472 if (!NT_SUCCESS(Status)) 00473 { 00474 DPRINT1("Failure to set guard page\n"); 00475 return Status; 00476 } 00477 00478 /* Update the Stack Limit keeping in mind the Guard Page */ 00479 InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit + 00480 GuardPageSize); 00481 } 00482 00483 /* We are done! */ 00484 return STATUS_SUCCESS; 00485 } 00486 00487 VOID 00488 WINAPI 00489 BaseFreeThreadStack(IN HANDLE hProcess, 00490 IN PINITIAL_TEB InitialTeb) 00491 { 00492 SIZE_T Dummy = 0; 00493 00494 /* Free the Stack */ 00495 NtFreeVirtualMemory(hProcess, 00496 &InitialTeb->AllocatedStackBase, 00497 &Dummy, 00498 MEM_RELEASE); 00499 } 00500 00501 /* 00502 * Creates the Initial Context for a Thread or Fiber 00503 */ 00504 VOID 00505 WINAPI 00506 BaseInitializeContext(IN PCONTEXT Context, 00507 IN PVOID Parameter, 00508 IN PVOID StartAddress, 00509 IN PVOID StackAddress, 00510 IN ULONG ContextType) 00511 { 00512 #ifdef _M_IX86 00513 ULONG ContextFlags; 00514 DPRINT("BaseInitializeContext: %p\n", Context); 00515 00516 /* Setup the Initial Win32 Thread Context */ 00517 Context->Eax = (ULONG)StartAddress; 00518 Context->Ebx = (ULONG)Parameter; 00519 Context->Esp = (ULONG)StackAddress; 00520 /* The other registers are undefined */ 00521 00522 /* Setup the Segments */ 00523 Context->SegFs = KGDT_R3_TEB; 00524 Context->SegEs = KGDT_R3_DATA; 00525 Context->SegDs = KGDT_R3_DATA; 00526 Context->SegCs = KGDT_R3_CODE; 00527 Context->SegSs = KGDT_R3_DATA; 00528 Context->SegGs = 0; 00529 00530 /* Set the Context Flags */ 00531 ContextFlags = Context->ContextFlags; 00532 Context->ContextFlags = CONTEXT_FULL; 00533 00534 /* Give it some room for the Parameter */ 00535 Context->Esp -= sizeof(PVOID); 00536 00537 /* Set the EFLAGS */ 00538 Context->EFlags = 0x3000; /* IOPL 3 */ 00539 00540 /* What kind of context is being created? */ 00541 if (ContextType == 1) 00542 { 00543 /* For Threads */ 00544 Context->Eip = (ULONG)BaseThreadStartupThunk; 00545 } 00546 else if (ContextType == 2) 00547 { 00548 /* This is a fiber: make space for the return address */ 00549 Context->Esp -= sizeof(PVOID); 00550 *((PVOID*)Context->Esp) = BaseFiberStartup; 00551 00552 /* Is FPU state required? */ 00553 Context->ContextFlags |= ContextFlags; 00554 if (ContextFlags == CONTEXT_FLOATING_POINT) 00555 { 00556 /* Set an initial state */ 00557 Context->FloatSave.ControlWord = 0x27F; 00558 Context->FloatSave.StatusWord = 0; 00559 Context->FloatSave.TagWord = 0xFFFF; 00560 Context->FloatSave.ErrorOffset = 0; 00561 Context->FloatSave.ErrorSelector = 0; 00562 Context->FloatSave.DataOffset = 0; 00563 Context->FloatSave.DataSelector = 0; 00564 if (SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE]) 00565 Context->Dr6 = 0x1F80; 00566 } 00567 } 00568 else 00569 { 00570 /* For first thread in a Process */ 00571 Context->Eip = (ULONG)BaseProcessStartThunk; 00572 } 00573 00574 #elif defined(_M_AMD64) 00575 DPRINT("BaseInitializeContext: %p\n", Context); 00576 00577 /* Setup the Initial Win32 Thread Context */ 00578 Context->Rax = (ULONG_PTR)StartAddress; 00579 Context->Rbx = (ULONG_PTR)Parameter; 00580 Context->Rsp = (ULONG_PTR)StackAddress; 00581 /* The other registers are undefined */ 00582 00583 /* Setup the Segments */ 00584 Context->SegGs = KGDT64_R3_DATA | RPL_MASK; 00585 Context->SegEs = KGDT64_R3_DATA | RPL_MASK; 00586 Context->SegDs = KGDT64_R3_DATA | RPL_MASK; 00587 Context->SegCs = KGDT64_R3_CODE | RPL_MASK; 00588 Context->SegSs = KGDT64_R3_DATA | RPL_MASK; 00589 Context->SegFs = KGDT64_R3_CMTEB | RPL_MASK; 00590 00591 /* Set the EFLAGS */ 00592 Context->EFlags = 0x3000; /* IOPL 3 */ 00593 00594 if (ContextType == 1) /* For Threads */ 00595 { 00596 Context->Rip = (ULONG_PTR)BaseThreadStartupThunk; 00597 } 00598 else if (ContextType == 2) /* For Fibers */ 00599 { 00600 Context->Rip = (ULONG_PTR)BaseFiberStartup; 00601 } 00602 else /* For first thread in a Process */ 00603 { 00604 Context->Rip = (ULONG_PTR)BaseProcessStartThunk; 00605 } 00606 00607 /* Set the Context Flags */ 00608 Context->ContextFlags = CONTEXT_FULL; 00609 00610 /* Give it some room for the Parameter */ 00611 Context->Rsp -= sizeof(PVOID); 00612 #else 00613 #warning Unknown architecture 00614 UNIMPLEMENTED; 00615 DbgBreakPoint(); 00616 #endif 00617 } 00618 00619 /* 00620 * Checks if the privilege for Real-Time Priority is there 00621 */ 00622 PVOID 00623 WINAPI 00624 BasepIsRealtimeAllowed(IN BOOLEAN Keep) 00625 { 00626 ULONG Privilege = SE_INC_BASE_PRIORITY_PRIVILEGE; 00627 PVOID State; 00628 NTSTATUS Status; 00629 00630 Status = RtlAcquirePrivilege(&Privilege, TRUE, FALSE, &State); 00631 if (!NT_SUCCESS(Status)) return NULL; 00632 00633 if (Keep) 00634 { 00635 RtlReleasePrivilege(State); 00636 State = (PVOID)TRUE; 00637 } 00638 00639 return State; 00640 } 00641 00642 /* 00643 * Maps an image file into a section 00644 */ 00645 NTSTATUS 00646 WINAPI 00647 BasepMapFile(IN LPCWSTR lpApplicationName, 00648 OUT PHANDLE hSection, 00649 IN PUNICODE_STRING ApplicationName) 00650 { 00651 RTL_RELATIVE_NAME_U RelativeName; 00652 OBJECT_ATTRIBUTES ObjectAttributes; 00653 NTSTATUS Status; 00654 HANDLE hFile = NULL; 00655 IO_STATUS_BLOCK IoStatusBlock; 00656 00657 DPRINT("BasepMapFile\n"); 00658 00659 /* Zero out the Relative Directory */ 00660 RelativeName.ContainingDirectory = NULL; 00661 00662 /* Find the application name */ 00663 if (!RtlDosPathNameToNtPathName_U(lpApplicationName, 00664 ApplicationName, 00665 NULL, 00666 &RelativeName)) 00667 { 00668 return STATUS_OBJECT_PATH_NOT_FOUND; 00669 } 00670 00671 DPRINT("ApplicationName %wZ\n", ApplicationName); 00672 DPRINT("RelativeName %wZ\n", &RelativeName.RelativeName); 00673 00674 /* Did we get a relative name? */ 00675 if (RelativeName.RelativeName.Length) 00676 { 00677 ApplicationName = &RelativeName.RelativeName; 00678 } 00679 00680 /* Initialize the Object Attributes */ 00681 InitializeObjectAttributes(&ObjectAttributes, 00682 ApplicationName, 00683 OBJ_CASE_INSENSITIVE, 00684 RelativeName.ContainingDirectory, 00685 NULL); 00686 00687 /* Try to open the executable */ 00688 Status = NtOpenFile(&hFile, 00689 SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA, 00690 &ObjectAttributes, 00691 &IoStatusBlock, 00692 FILE_SHARE_DELETE | FILE_SHARE_READ, 00693 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); 00694 if (!NT_SUCCESS(Status)) 00695 { 00696 DPRINT1("Failed to open file\n"); 00697 BaseSetLastNTError(Status); 00698 return Status; 00699 } 00700 00701 /* Create a section for this file */ 00702 Status = NtCreateSection(hSection, 00703 SECTION_ALL_ACCESS, 00704 NULL, 00705 NULL, 00706 PAGE_EXECUTE, 00707 SEC_IMAGE, 00708 hFile); 00709 NtClose(hFile); 00710 00711 /* Return status */ 00712 DPRINT("Section: %lx for file: %lx\n", *hSection, hFile); 00713 return Status; 00714 } 00715 00716 /* 00717 * @implemented 00718 */ 00719 BOOLEAN 00720 WINAPI 00721 Wow64EnableWow64FsRedirection(IN BOOLEAN Wow64EnableWow64FsRedirection) 00722 { 00723 NTSTATUS Status; 00724 BOOL Result; 00725 00726 Status = RtlWow64EnableFsRedirection(Wow64EnableWow64FsRedirection); 00727 if (NT_SUCCESS(Status)) 00728 { 00729 Result = TRUE; 00730 } 00731 else 00732 { 00733 BaseSetLastNTError(Status); 00734 Result = FALSE; 00735 } 00736 return Result; 00737 } 00738 00739 /* 00740 * @implemented 00741 */ 00742 BOOL 00743 WINAPI 00744 Wow64DisableWow64FsRedirection(IN PVOID *OldValue) 00745 { 00746 NTSTATUS Status; 00747 BOOL Result; 00748 00749 Status = RtlWow64EnableFsRedirectionEx((PVOID)TRUE, OldValue); 00750 if (NT_SUCCESS(Status)) 00751 { 00752 Result = TRUE; 00753 } 00754 else 00755 { 00756 BaseSetLastNTError(Status); 00757 Result = FALSE; 00758 } 00759 return Result; 00760 } 00761 00762 /* 00763 * @implemented 00764 */ 00765 BOOL 00766 WINAPI 00767 Wow64RevertWow64FsRedirection(IN PVOID OldValue) 00768 { 00769 NTSTATUS Status; 00770 BOOL Result; 00771 00772 Status = RtlWow64EnableFsRedirectionEx(OldValue, &OldValue); 00773 if (NT_SUCCESS(Status)) 00774 { 00775 Result = TRUE; 00776 } 00777 else 00778 { 00779 BaseSetLastNTError(Status); 00780 Result = FALSE; 00781 } 00782 return Result; 00783 } 00784 00785 /* 00786 * @implemented 00787 */ 00788 VOID 00789 WINAPI 00790 SetFileApisToOEM(VOID) 00791 { 00792 /* Set the correct Base Api */ 00793 Basep8BitStringToUnicodeString = (PRTL_CONVERT_STRING)RtlOemStringToUnicodeString; 00794 BasepUnicodeStringTo8BitString = RtlUnicodeStringToOemString; 00795 BasepUnicodeStringTo8BitSize = BasepUnicodeStringToOemSize; 00796 Basep8BitStringToUnicodeSize = BasepOemStringToUnicodeSize; 00797 00798 /* FIXME: Old, deprecated way */ 00799 bIsFileApiAnsi = FALSE; 00800 } 00801 00802 00803 /* 00804 * @implemented 00805 */ 00806 VOID 00807 WINAPI 00808 SetFileApisToANSI(VOID) 00809 { 00810 /* Set the correct Base Api */ 00811 Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString; 00812 BasepUnicodeStringTo8BitString = RtlUnicodeStringToAnsiString; 00813 BasepUnicodeStringTo8BitSize = BasepUnicodeStringToAnsiSize; 00814 Basep8BitStringToUnicodeSize = BasepAnsiStringToUnicodeSize; 00815 00816 /* FIXME: Old, deprecated way */ 00817 bIsFileApiAnsi = TRUE; 00818 } 00819 00820 /* 00821 * @implemented 00822 */ 00823 BOOL 00824 WINAPI 00825 AreFileApisANSI(VOID) 00826 { 00827 return Basep8BitStringToUnicodeString == RtlAnsiStringToUnicodeString; 00828 } 00829 00830 /* 00831 * @implemented 00832 */ 00833 VOID 00834 WINAPI 00835 BaseMarkFileForDelete(IN HANDLE FileHandle, 00836 IN ULONG FileAttributes) 00837 { 00838 IO_STATUS_BLOCK IoStatusBlock; 00839 FILE_BASIC_INFORMATION FileBasicInfo; 00840 FILE_DISPOSITION_INFORMATION FileDispositionInfo; 00841 00842 /* If no attributes were given, get them */ 00843 if (!FileAttributes) 00844 { 00845 FileBasicInfo.FileAttributes = 0; 00846 NtQueryInformationFile(FileHandle, 00847 &IoStatusBlock, 00848 &FileBasicInfo, 00849 sizeof(FileBasicInfo), 00850 FileBasicInformation); 00851 FileAttributes = FileBasicInfo.FileAttributes; 00852 } 00853 00854 /* If file is marked as RO, reset its attributes */ 00855 if (FileAttributes & FILE_ATTRIBUTE_READONLY) 00856 { 00857 RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo)); 00858 FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; 00859 NtSetInformationFile(FileHandle, 00860 &IoStatusBlock, 00861 &FileBasicInfo, 00862 sizeof(FileBasicInfo), 00863 FileBasicInformation); 00864 } 00865 00866 /* Finally, mark the file for deletion */ 00867 FileDispositionInfo.DeleteFile = TRUE; 00868 NtSetInformationFile(FileHandle, 00869 &IoStatusBlock, 00870 &FileDispositionInfo, 00871 sizeof(FileDispositionInfo), 00872 FileDispositionInformation); 00873 } 00874 00875 /* 00876 * @unimplemented 00877 */ 00878 BOOL 00879 WINAPI 00880 BaseCheckRunApp(IN DWORD Unknown1, 00881 IN DWORD Unknown2, 00882 IN DWORD Unknown3, 00883 IN DWORD Unknown4, 00884 IN DWORD Unknown5, 00885 IN DWORD Unknown6, 00886 IN DWORD Unknown7, 00887 IN DWORD Unknown8, 00888 IN DWORD Unknown9, 00889 IN DWORD Unknown10) 00890 { 00891 STUB; 00892 return FALSE; 00893 } 00894 00895 /* 00896 * @unimplemented 00897 */ 00898 NTSTATUS 00899 WINAPI 00900 BasepCheckWinSaferRestrictions(IN HANDLE UserToken, 00901 IN LPWSTR ApplicationName, 00902 IN HANDLE FileHandle, 00903 OUT PBOOLEAN InJob, 00904 OUT PHANDLE NewToken, 00905 OUT PHANDLE JobHandle) 00906 { 00907 NTSTATUS Status; 00908 00909 /* Validate that there's a name */ 00910 if ((ApplicationName) && *(ApplicationName)) 00911 { 00912 /* Validate that the required output parameters are there */ 00913 if ((InJob) && (NewToken) && (JobHandle)) 00914 { 00915 /* Do the work (one day...) */ 00916 UNIMPLEMENTED; 00917 Status = STATUS_SUCCESS; 00918 } 00919 else 00920 { 00921 /* Act as if SEH hit this */ 00922 Status = STATUS_ACCESS_VIOLATION; 00923 } 00924 } 00925 else 00926 { 00927 /* Input is invalid */ 00928 Status = STATUS_INVALID_PARAMETER; 00929 } 00930 00931 /* Return the status */ 00932 return Status; 00933 } Generated on Sun May 27 2012 04:22:16 for ReactOS by
1.7.6.1
|