mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:45:53 +00:00
[KERNEL32]: Implement BasepComputeProcessPath.
[KERNEL32]: Replace BasepGetDllPath with BasepComputeProcessDllPath. Paths now work right. This is step 1. SearchPatchW is next (BasepComputeProcessPath), followed by CreateProcessInternalW (BasepComputeProcessExePath). Then all paths will work right. svn path=/trunk/; revision=54592
This commit is contained in:
parent
6764aa97c8
commit
37dc00b136
4 changed files with 502 additions and 330 deletions
|
@ -69,105 +69,6 @@ BasepMapModuleHandle(HMODULE hModule, BOOLEAN AsDataFile)
|
||||||
return hModule;
|
return hModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @name GetDllLoadPath
|
|
||||||
*
|
|
||||||
* Internal function to compute the load path to use for a given dll.
|
|
||||||
*
|
|
||||||
* @remarks Returned pointer must be freed by caller.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LPWSTR
|
|
||||||
GetDllLoadPath(LPCWSTR lpModule)
|
|
||||||
{
|
|
||||||
ULONG Pos = 0, Length = 4, Tmp;
|
|
||||||
PWCHAR EnvironmentBufferW = NULL;
|
|
||||||
LPCWSTR lpModuleEnd = NULL;
|
|
||||||
UNICODE_STRING ModuleName;
|
|
||||||
DWORD LastError = GetLastError(); /* GetEnvironmentVariable changes LastError */
|
|
||||||
|
|
||||||
// FIXME: This function is used only by SearchPathW, and is deprecated and will be deleted ASAP.
|
|
||||||
|
|
||||||
if (lpModule != NULL && wcslen(lpModule) > 2 && lpModule[1] == ':')
|
|
||||||
{
|
|
||||||
lpModuleEnd = lpModule + wcslen(lpModule);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ModuleName = NtCurrentPeb()->ProcessParameters->ImagePathName;
|
|
||||||
lpModule = ModuleName.Buffer;
|
|
||||||
lpModuleEnd = lpModule + (ModuleName.Length / sizeof(WCHAR));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpModule != NULL)
|
|
||||||
{
|
|
||||||
while (lpModuleEnd > lpModule && *lpModuleEnd != L'/' &&
|
|
||||||
*lpModuleEnd != L'\\' && *lpModuleEnd != L':')
|
|
||||||
{
|
|
||||||
--lpModuleEnd;
|
|
||||||
}
|
|
||||||
Length = (lpModuleEnd - lpModule) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Length += GetCurrentDirectoryW(0, NULL);
|
|
||||||
Length += GetDllDirectoryW(0, NULL);
|
|
||||||
Length += GetSystemDirectoryW(NULL, 0);
|
|
||||||
Length += GetWindowsDirectoryW(NULL, 0);
|
|
||||||
Length += GetEnvironmentVariableW(L"PATH", NULL, 0);
|
|
||||||
|
|
||||||
EnvironmentBufferW = RtlAllocateHeap(RtlGetProcessHeap(), 0,
|
|
||||||
(Length + 1) * sizeof(WCHAR));
|
|
||||||
if (EnvironmentBufferW == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpModule)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(EnvironmentBufferW, lpModule,
|
|
||||||
(lpModuleEnd - lpModule) * sizeof(WCHAR));
|
|
||||||
Pos += lpModuleEnd - lpModule;
|
|
||||||
EnvironmentBufferW[Pos++] = L';';
|
|
||||||
}
|
|
||||||
|
|
||||||
Tmp = GetCurrentDirectoryW(Length, EnvironmentBufferW + Pos);
|
|
||||||
if(Tmp > 0 && Tmp < Length - Pos)
|
|
||||||
{
|
|
||||||
Pos += Tmp;
|
|
||||||
if(Pos < Length) EnvironmentBufferW[Pos++] = L';';
|
|
||||||
}
|
|
||||||
|
|
||||||
Tmp = GetDllDirectoryW(Length - Pos, EnvironmentBufferW + Pos);
|
|
||||||
if(Tmp > 0 && Tmp < Length - Pos)
|
|
||||||
{
|
|
||||||
Pos += Tmp;
|
|
||||||
if(Pos < Length) EnvironmentBufferW[Pos++] = L';';
|
|
||||||
}
|
|
||||||
|
|
||||||
Tmp = GetSystemDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
|
|
||||||
if(Tmp > 0 && Tmp < Length - Pos)
|
|
||||||
{
|
|
||||||
Pos += Tmp;
|
|
||||||
if(Pos < Length) EnvironmentBufferW[Pos++] = L';';
|
|
||||||
}
|
|
||||||
|
|
||||||
Tmp = GetWindowsDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
|
|
||||||
if(Tmp > 0 && Tmp < Length - Pos)
|
|
||||||
{
|
|
||||||
Pos += Tmp;
|
|
||||||
if(Pos < Length) EnvironmentBufferW[Pos++] = L';';
|
|
||||||
}
|
|
||||||
|
|
||||||
Tmp = GetEnvironmentVariableW(L"PATH", EnvironmentBufferW + Pos, Length - Pos);
|
|
||||||
|
|
||||||
/* Make sure buffer is null terminated */
|
|
||||||
EnvironmentBufferW[Pos++] = UNICODE_NULL;
|
|
||||||
|
|
||||||
|
|
||||||
SetLastError(LastError);
|
|
||||||
return EnvironmentBufferW;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -421,9 +322,9 @@ LoadLibraryExW(LPCWSTR lpLibFileName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the load path */
|
/* Compute the load path */
|
||||||
SearchPath = BasepGetDllPath((dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) ? (LPWSTR)lpLibFileName : NULL,
|
SearchPath = BaseComputeProcessDllPath((dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) ?
|
||||||
|
DllName.Buffer : NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!SearchPath)
|
if (!SearchPath)
|
||||||
{
|
{
|
||||||
/* Getting DLL path failed, so set last error, free mem and return */
|
/* Getting DLL path failed, so set last error, free mem and return */
|
||||||
|
@ -766,10 +667,13 @@ GetModuleHandleForUnicodeString(PUNICODE_STRING ModuleName)
|
||||||
if (NT_SUCCESS(Status)) return Module;
|
if (NT_SUCCESS(Status)) return Module;
|
||||||
|
|
||||||
/* If not, then the path should be computed */
|
/* If not, then the path should be computed */
|
||||||
DllPath = BasepGetDllPath(NULL, 0);
|
DllPath = BaseComputeProcessDllPath(NULL, 0);
|
||||||
|
if (!DllPath)
|
||||||
/* Call LdrGetHandle() again providing the computed DllPath
|
{
|
||||||
and wrapped into SEH */
|
Status = STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
Status = LdrGetDllHandle(DllPath, NULL, ModuleName, &Module);
|
Status = LdrGetDllHandle(DllPath, NULL, ModuleName, &Module);
|
||||||
|
@ -780,6 +684,7 @@ GetModuleHandleForUnicodeString(PUNICODE_STRING ModuleName)
|
||||||
Status = _SEH2_GetExceptionCode();
|
Status = _SEH2_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
|
||||||
/* Free the DllPath */
|
/* Free the DllPath */
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath);
|
||||||
|
|
|
@ -33,7 +33,7 @@ DWORD IllegalMask[4] =
|
||||||
0x10000000 // 7C not allowed
|
0x10000000 // 7C not allowed
|
||||||
};
|
};
|
||||||
|
|
||||||
BASE_SEARCH_PATH_TYPE BaseDllOrderCurrent[BaseCurrentDirMax][BaseSearchPathMax] =
|
BASE_SEARCH_PATH_TYPE BaseDllOrderCurrent[BaseCurrentDirPlacementMax][BaseSearchPathMax] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
BaseSearchPathApp,
|
BaseSearchPathApp,
|
||||||
|
@ -78,15 +78,313 @@ BASE_SEARCH_PATH_TYPE BaseProcessOrder[BaseSearchPathMax] =
|
||||||
BaseSearchPathInvalid
|
BaseSearchPathInvalid
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BASE_CURRENT_DIR_PLACEMENT BasepDllCurrentDirPlacement = BaseCurrentDirPlacementInvalid;
|
||||||
|
|
||||||
|
extern UNICODE_STRING BasePathVariableName;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
PWCHAR
|
||||||
|
WINAPI
|
||||||
|
BasepEndOfDirName(IN PWCHAR FileName)
|
||||||
|
{
|
||||||
|
PWCHAR FileNameEnd, FileNameSeparator;
|
||||||
|
|
||||||
|
/* Find the first slash */
|
||||||
|
FileNameSeparator = wcschr(FileName, OBJ_NAME_PATH_SEPARATOR);
|
||||||
|
if (FileNameSeparator)
|
||||||
|
{
|
||||||
|
/* Find the last one */
|
||||||
|
FileNameEnd = wcsrchr(FileNameSeparator, OBJ_NAME_PATH_SEPARATOR);
|
||||||
|
ASSERT(FileNameEnd);
|
||||||
|
|
||||||
|
/* Handle the case where they are one and the same */
|
||||||
|
if (FileNameEnd == FileNameSeparator) FileNameEnd++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No directory was specified */
|
||||||
|
FileNameEnd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return where the directory ends and the filename starts */
|
||||||
|
return FileNameEnd;
|
||||||
|
}
|
||||||
|
|
||||||
LPWSTR
|
LPWSTR
|
||||||
WINAPI
|
WINAPI
|
||||||
BasepComputeProcessPath(IN PBASE_SEARCH_PATH_TYPE PathOrder,
|
BasepComputeProcessPath(IN PBASE_SEARCH_PATH_TYPE PathOrder,
|
||||||
IN LPWSTR AppName,
|
IN LPWSTR AppName,
|
||||||
IN LPVOID Environment)
|
IN LPVOID Environment)
|
||||||
{
|
{
|
||||||
return NULL;
|
PWCHAR PathBuffer, Buffer, AppNameEnd, PathCurrent;
|
||||||
|
ULONG PathLengthInBytes;
|
||||||
|
NTSTATUS Status;
|
||||||
|
UNICODE_STRING EnvPath;
|
||||||
|
PBASE_SEARCH_PATH_TYPE Order;
|
||||||
|
|
||||||
|
/* Initialize state */
|
||||||
|
AppNameEnd = Buffer = PathBuffer = NULL;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
PathLengthInBytes = 0;
|
||||||
|
|
||||||
|
/* Loop the ordering array */
|
||||||
|
for (Order = PathOrder; *Order != BaseSearchPathInvalid; Order++) {
|
||||||
|
switch (*Order)
|
||||||
|
{
|
||||||
|
/* Compute the size of the DLL path */
|
||||||
|
case BaseSearchPathDll:
|
||||||
|
|
||||||
|
/* This path only gets called if SetDllDirectory was called */
|
||||||
|
ASSERT(BaseDllDirectory.Buffer != NULL);
|
||||||
|
|
||||||
|
/* Make sure there's a DLL directory size */
|
||||||
|
if (BaseDllDirectory.Length)
|
||||||
|
{
|
||||||
|
/* Add it, plus the separator */
|
||||||
|
PathLengthInBytes += BaseDllDirectory.Length + sizeof(L';');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Compute the size of the current path */
|
||||||
|
case BaseSearchPathCurrent:
|
||||||
|
|
||||||
|
/* Add ".;" */
|
||||||
|
PathLengthInBytes += (2 * sizeof(WCHAR));
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Compute the size of the "PATH" environment variable */
|
||||||
|
case BaseSearchPathEnv:
|
||||||
|
|
||||||
|
/* Grab PEB lock if one wasn't passed in */
|
||||||
|
if (!Environment) RtlAcquirePebLock();
|
||||||
|
|
||||||
|
/* Query the size first */
|
||||||
|
EnvPath.MaximumLength = 0;
|
||||||
|
Status = RtlQueryEnvironmentVariable_U(Environment,
|
||||||
|
&BasePathVariableName,
|
||||||
|
&EnvPath);
|
||||||
|
if (Status == STATUS_BUFFER_TOO_SMALL)
|
||||||
|
{
|
||||||
|
/* Compute the size we'll need for the environment */
|
||||||
|
EnvPath.MaximumLength = EnvPath.Length + sizeof(WCHAR);
|
||||||
|
if ((EnvPath.Length + sizeof(WCHAR)) > UNICODE_STRING_MAX_BYTES)
|
||||||
|
{
|
||||||
|
/* Don't let it overflow */
|
||||||
|
EnvPath.MaximumLength = EnvPath.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the environment buffer */
|
||||||
|
Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
EnvPath.MaximumLength);
|
||||||
|
if (Buffer)
|
||||||
|
{
|
||||||
|
/* Now query the PATH environment variable */
|
||||||
|
EnvPath.Buffer = Buffer;
|
||||||
|
Status = RtlQueryEnvironmentVariable_U(Environment,
|
||||||
|
&BasePathVariableName,
|
||||||
|
&EnvPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Failure case */
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the PEB lock from above */
|
||||||
|
if (!Environment) RtlReleasePebLock();
|
||||||
|
|
||||||
|
/* There might not be a PATH */
|
||||||
|
if (Status == STATUS_VARIABLE_NOT_FOUND)
|
||||||
|
{
|
||||||
|
/* In this case, skip this PathOrder */
|
||||||
|
EnvPath.Length = EnvPath.MaximumLength = 0;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* An early failure, go to exit code */
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Add the length of the PATH variable */
|
||||||
|
ASSERT(!(EnvPath.Length & 1));
|
||||||
|
PathLengthInBytes += (EnvPath.Length + sizeof(L';'));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Compute the size of the default search path */
|
||||||
|
case BaseSearchPathDefault:
|
||||||
|
|
||||||
|
/* Just add it... it already has a ';' at the end */
|
||||||
|
ASSERT(!(BaseDefaultPath.Length & 1));
|
||||||
|
PathLengthInBytes += BaseDefaultPath.Length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Compute the size of the current app directory */
|
||||||
|
case BaseSearchPathApp:
|
||||||
|
/* Find out where the app name ends, to get only the directory */
|
||||||
|
if (AppName) AppNameEnd = BasepEndOfDirName(AppName);
|
||||||
|
|
||||||
|
/* Check if there was no application name passed in */
|
||||||
|
if (!(AppName) || !(AppNameEnd))
|
||||||
|
{
|
||||||
|
/* Do we have a per-thread CURDIR to use? */
|
||||||
|
if (NtCurrentTeb()->NtTib.SubSystemTib)
|
||||||
|
{
|
||||||
|
/* This means someone added RTL_PERTHREAD_CURDIR */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
while (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We do not. Do we have the LDR_ENTRY for the executable? */
|
||||||
|
if (!BasepExeLdrEntry)
|
||||||
|
{
|
||||||
|
/* We do not. Grab it */
|
||||||
|
LdrEnumerateLoadedModules(0,
|
||||||
|
BasepLocateExeLdrEntry,
|
||||||
|
NtCurrentPeb()->ImageBaseAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now do we have it? */
|
||||||
|
if (BasepExeLdrEntry)
|
||||||
|
{
|
||||||
|
/* Yes, so read the name out of it */
|
||||||
|
AppName = BasepExeLdrEntry->FullDllName.Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find out where the app name ends, to get only the directory */
|
||||||
|
if (AppName) AppNameEnd = BasepEndOfDirName(AppName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* So, do we have an application name and its directory? */
|
||||||
|
if ((AppName) && (AppNameEnd))
|
||||||
|
{
|
||||||
|
/* Add the size of the app's directory, plus the separator */
|
||||||
|
PathLengthInBytes += ((AppNameEnd - AppName) * sizeof(WCHAR)) + sizeof(L';');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bam, all done, we now have the final path size */
|
||||||
|
ASSERT(PathLengthInBytes > 0);
|
||||||
|
ASSERT(!(PathLengthInBytes & 1));
|
||||||
|
|
||||||
|
/* Allocate the buffer to hold it */
|
||||||
|
PathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathLengthInBytes);
|
||||||
|
if (!PathBuffer)
|
||||||
|
{
|
||||||
|
/* Failure path */
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we loop again, this time to copy the data */
|
||||||
|
PathCurrent = PathBuffer;
|
||||||
|
for (Order = PathOrder; *Order != BaseSearchPathInvalid; Order++) {
|
||||||
|
switch (*Order)
|
||||||
|
{
|
||||||
|
/* Add the DLL path */
|
||||||
|
case BaseSearchPathDll:
|
||||||
|
if (BaseDllDirectory.Length)
|
||||||
|
{
|
||||||
|
/* Copy it in the buffer, ASSERT there's enough space */
|
||||||
|
ASSERT((((PathCurrent - PathBuffer + 1) * sizeof(WCHAR)) + BaseDllDirectory.Length) <= PathLengthInBytes);
|
||||||
|
RtlCopyMemory(PathCurrent,
|
||||||
|
BaseDllDirectory.Buffer,
|
||||||
|
BaseDllDirectory.Length);
|
||||||
|
|
||||||
|
/* Update the current pointer, add a separator */
|
||||||
|
PathCurrent += (BaseDllDirectory.Length / sizeof(WCHAR));
|
||||||
|
*PathCurrent++ = ';';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Add the current applicaiton path */
|
||||||
|
case BaseSearchPathApp:
|
||||||
|
if ((AppName) && (AppNameEnd))
|
||||||
|
{
|
||||||
|
/* Copy it in the buffer, ASSERT there's enough space */
|
||||||
|
ASSERT(((PathCurrent - PathBuffer + 1 + (AppNameEnd - AppName)) * sizeof(WCHAR)) <= PathLengthInBytes);
|
||||||
|
RtlCopyMemory(PathCurrent,
|
||||||
|
AppName,
|
||||||
|
(AppNameEnd - AppName) * sizeof(WCHAR));
|
||||||
|
|
||||||
|
/* Update the current pointer, add a separator */
|
||||||
|
PathCurrent += AppNameEnd - AppName;
|
||||||
|
*PathCurrent++ = ';';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Add the default search path */
|
||||||
|
case BaseSearchPathDefault:
|
||||||
|
/* Copy it in the buffer, ASSERT there's enough space */
|
||||||
|
ASSERT((((PathCurrent - PathBuffer) * sizeof(WCHAR)) + BaseDefaultPath.Length) <= PathLengthInBytes);
|
||||||
|
RtlCopyMemory(PathCurrent, BaseDefaultPath.Buffer, BaseDefaultPath.Length);
|
||||||
|
|
||||||
|
/* Update the current pointer. The default path already has a ";" */
|
||||||
|
PathCurrent += (BaseDefaultPath.Length / sizeof(WCHAR));
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Add the path in the PATH environment variable */
|
||||||
|
case BaseSearchPathEnv:
|
||||||
|
if (EnvPath.Length)
|
||||||
|
{
|
||||||
|
/* Copy it in the buffer, ASSERT there's enough space */
|
||||||
|
ASSERT((((PathCurrent - PathBuffer + 1) * sizeof(WCHAR)) + EnvPath.Length) <= PathLengthInBytes);
|
||||||
|
RtlCopyMemory(PathCurrent, EnvPath.Buffer, EnvPath.Length);
|
||||||
|
|
||||||
|
/* Update the current pointer, add a separator */
|
||||||
|
PathCurrent += (EnvPath.Length / sizeof(WCHAR));
|
||||||
|
*PathCurrent++ = ';';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Add the current dierctory */
|
||||||
|
case BaseSearchPathCurrent:
|
||||||
|
|
||||||
|
/* Copy it in the buffer, ASSERT there's enough space */
|
||||||
|
ASSERT(((PathCurrent - PathBuffer + 2) * sizeof(WCHAR)) <= PathLengthInBytes);
|
||||||
|
*PathCurrent++ = '.';
|
||||||
|
|
||||||
|
/* Add the path separator */
|
||||||
|
*PathCurrent++ = ';';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Everything should've perfectly fit in there */
|
||||||
|
ASSERT((PathCurrent - PathBuffer) * sizeof(WCHAR) == PathLengthInBytes);
|
||||||
|
ASSERT(PathCurrent > PathBuffer);
|
||||||
|
|
||||||
|
/* Terminate the whole thing */
|
||||||
|
PathCurrent[-1] = UNICODE_NULL;
|
||||||
|
|
||||||
|
Quickie:
|
||||||
|
/* Exit path: free our buffers */
|
||||||
|
if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
if (PathBuffer)
|
||||||
|
{
|
||||||
|
/* This only gets freed in the failure path, since caller wants it */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
|
||||||
|
PathBuffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the path! */
|
||||||
|
return PathBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPWSTR
|
LPWSTR
|
||||||
|
@ -120,7 +418,14 @@ BaseComputeProcessDllPath(IN LPWSTR FullPath,
|
||||||
IN PVOID Environment)
|
IN PVOID Environment)
|
||||||
{
|
{
|
||||||
LPWSTR DllPath = NULL;
|
LPWSTR DllPath = NULL;
|
||||||
DPRINT1("Computing DLL path: %wZ with BaseDll: %wZ\n", FullPath, &BaseDllDirectory);
|
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager");
|
||||||
|
UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SafeDllSearchMode");
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes = RTL_CONSTANT_OBJECT_ATTRIBUTES(&KeyName, OBJ_CASE_INSENSITIVE);
|
||||||
|
KEY_VALUE_PARTIAL_INFORMATION PartialInfo;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG ResultLength;
|
||||||
|
BASE_CURRENT_DIR_PLACEMENT CurrentDirPlacement, OldCurrentDirPlacement;
|
||||||
|
|
||||||
/* Acquire DLL directory lock */
|
/* Acquire DLL directory lock */
|
||||||
RtlEnterCriticalSection(&BaseDllDirectoryLock);
|
RtlEnterCriticalSection(&BaseDllDirectoryLock);
|
||||||
|
@ -141,8 +446,65 @@ BaseComputeProcessDllPath(IN LPWSTR FullPath,
|
||||||
/* Release DLL directory lock */
|
/* Release DLL directory lock */
|
||||||
RtlLeaveCriticalSection(&BaseDllDirectoryLock);
|
RtlLeaveCriticalSection(&BaseDllDirectoryLock);
|
||||||
|
|
||||||
/* There is no base DLL directory */
|
/* Read the current placement */
|
||||||
UNIMPLEMENTED;
|
CurrentDirPlacement = BasepDllCurrentDirPlacement;
|
||||||
|
if (CurrentDirPlacement == BaseCurrentDirPlacementInvalid)
|
||||||
|
{
|
||||||
|
/* Open the configuration key */
|
||||||
|
Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &ObjectAttributes);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Query if safe search is enabled */
|
||||||
|
Status = NtQueryValueKey(KeyHandle,
|
||||||
|
&ValueName,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
&PartialInfo,
|
||||||
|
sizeof(PartialInfo),
|
||||||
|
&ResultLength);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Read the value if the size is OK */
|
||||||
|
if (ResultLength == sizeof(PartialInfo))
|
||||||
|
{
|
||||||
|
CurrentDirPlacement = *(PULONG)PartialInfo.Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the handle */
|
||||||
|
NtClose(KeyHandle);
|
||||||
|
|
||||||
|
/* Validate the registry value */
|
||||||
|
if ((CurrentDirPlacement <= BaseCurrentDirPlacementInvalid) ||
|
||||||
|
(CurrentDirPlacement >= BaseCurrentDirPlacementMax))
|
||||||
|
{
|
||||||
|
/* Default to safe search */
|
||||||
|
CurrentDirPlacement = BaseCurrentDirPlacementSafe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the placement and read the old one */
|
||||||
|
OldCurrentDirPlacement = InterlockedCompareExchange((PLONG)&BasepDllCurrentDirPlacement,
|
||||||
|
CurrentDirPlacement,
|
||||||
|
BaseCurrentDirPlacementInvalid);
|
||||||
|
if (OldCurrentDirPlacement != BaseCurrentDirPlacementInvalid)
|
||||||
|
{
|
||||||
|
/* If there already was a placement, use it */
|
||||||
|
CurrentDirPlacement = OldCurrentDirPlacement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the placement is invalid or not set */
|
||||||
|
if ((CurrentDirPlacement <= BaseCurrentDirPlacementInvalid) ||
|
||||||
|
(CurrentDirPlacement >= BaseCurrentDirPlacementMax))
|
||||||
|
{
|
||||||
|
/* Default to safe search */
|
||||||
|
CurrentDirPlacement = BaseCurrentDirPlacementSafe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the process path using either normal or safe search */
|
||||||
|
DllPath = BasepComputeProcessPath(BaseDllOrderCurrent[CurrentDirPlacement],
|
||||||
|
FullPath,
|
||||||
|
Environment);
|
||||||
|
|
||||||
/* Return dll path */
|
/* Return dll path */
|
||||||
return DllPath;
|
return DllPath;
|
||||||
|
@ -939,6 +1301,105 @@ ContainsPath(LPCWSTR name)
|
||||||
return (name[1] == '.' && (name[2] == '/' || name[2] == '\\'));
|
return (name[1] == '.' && (name[2] == '/' || name[2] == '\\'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GetDllLoadPath
|
||||||
|
*
|
||||||
|
* Internal function to compute the load path to use for a given dll.
|
||||||
|
*
|
||||||
|
* @remarks Returned pointer must be freed by caller.
|
||||||
|
*/
|
||||||
|
|
||||||
|
LPWSTR
|
||||||
|
GetDllLoadPath(LPCWSTR lpModule)
|
||||||
|
{
|
||||||
|
ULONG Pos = 0, Length = 4, Tmp;
|
||||||
|
PWCHAR EnvironmentBufferW = NULL;
|
||||||
|
LPCWSTR lpModuleEnd = NULL;
|
||||||
|
UNICODE_STRING ModuleName;
|
||||||
|
DWORD LastError = GetLastError(); /* GetEnvironmentVariable changes LastError */
|
||||||
|
|
||||||
|
// FIXME: This function is used only by SearchPathW, and is deprecated and will be deleted ASAP.
|
||||||
|
|
||||||
|
if (lpModule != NULL && wcslen(lpModule) > 2 && lpModule[1] == ':')
|
||||||
|
{
|
||||||
|
lpModuleEnd = lpModule + wcslen(lpModule);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ModuleName = NtCurrentPeb()->ProcessParameters->ImagePathName;
|
||||||
|
lpModule = ModuleName.Buffer;
|
||||||
|
lpModuleEnd = lpModule + (ModuleName.Length / sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpModule != NULL)
|
||||||
|
{
|
||||||
|
while (lpModuleEnd > lpModule && *lpModuleEnd != L'/' &&
|
||||||
|
*lpModuleEnd != L'\\' && *lpModuleEnd != L':')
|
||||||
|
{
|
||||||
|
--lpModuleEnd;
|
||||||
|
}
|
||||||
|
Length = (lpModuleEnd - lpModule) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Length += GetCurrentDirectoryW(0, NULL);
|
||||||
|
Length += GetDllDirectoryW(0, NULL);
|
||||||
|
Length += GetSystemDirectoryW(NULL, 0);
|
||||||
|
Length += GetWindowsDirectoryW(NULL, 0);
|
||||||
|
Length += GetEnvironmentVariableW(L"PATH", NULL, 0);
|
||||||
|
|
||||||
|
EnvironmentBufferW = RtlAllocateHeap(RtlGetProcessHeap(), 0,
|
||||||
|
(Length + 1) * sizeof(WCHAR));
|
||||||
|
if (EnvironmentBufferW == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpModule)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(EnvironmentBufferW, lpModule,
|
||||||
|
(lpModuleEnd - lpModule) * sizeof(WCHAR));
|
||||||
|
Pos += lpModuleEnd - lpModule;
|
||||||
|
EnvironmentBufferW[Pos++] = L';';
|
||||||
|
}
|
||||||
|
|
||||||
|
Tmp = GetCurrentDirectoryW(Length, EnvironmentBufferW + Pos);
|
||||||
|
if(Tmp > 0 && Tmp < Length - Pos)
|
||||||
|
{
|
||||||
|
Pos += Tmp;
|
||||||
|
if(Pos < Length) EnvironmentBufferW[Pos++] = L';';
|
||||||
|
}
|
||||||
|
|
||||||
|
Tmp = GetDllDirectoryW(Length - Pos, EnvironmentBufferW + Pos);
|
||||||
|
if(Tmp > 0 && Tmp < Length - Pos)
|
||||||
|
{
|
||||||
|
Pos += Tmp;
|
||||||
|
if(Pos < Length) EnvironmentBufferW[Pos++] = L';';
|
||||||
|
}
|
||||||
|
|
||||||
|
Tmp = GetSystemDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
|
||||||
|
if(Tmp > 0 && Tmp < Length - Pos)
|
||||||
|
{
|
||||||
|
Pos += Tmp;
|
||||||
|
if(Pos < Length) EnvironmentBufferW[Pos++] = L';';
|
||||||
|
}
|
||||||
|
|
||||||
|
Tmp = GetWindowsDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
|
||||||
|
if(Tmp > 0 && Tmp < Length - Pos)
|
||||||
|
{
|
||||||
|
Pos += Tmp;
|
||||||
|
if(Pos < Length) EnvironmentBufferW[Pos++] = L';';
|
||||||
|
}
|
||||||
|
|
||||||
|
Tmp = GetEnvironmentVariableW(L"PATH", EnvironmentBufferW + Pos, Length - Pos);
|
||||||
|
|
||||||
|
/* Make sure buffer is null terminated */
|
||||||
|
EnvironmentBufferW[Pos++] = UNICODE_NULL;
|
||||||
|
|
||||||
|
|
||||||
|
SetLastError(LastError);
|
||||||
|
return EnvironmentBufferW;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -375,201 +375,6 @@ BasepDuplicateAndWriteHandle(IN HANDLE ProcessHandle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LPWSTR
|
|
||||||
WINAPI
|
|
||||||
BasepGetProcessPath(DWORD Reserved,
|
|
||||||
LPWSTR FullPath,
|
|
||||||
PVOID Environment)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
LPWSTR AllocatedPath = NULL, ch;
|
|
||||||
ULONG DefaultLength = BaseDefaultPath.Length;
|
|
||||||
ULONG AppLength = 0;
|
|
||||||
UNICODE_STRING EnvPath;
|
|
||||||
LPWSTR NamePtr;
|
|
||||||
LPWSTR PathBuffer;
|
|
||||||
BOOLEAN SecondAttempt = FALSE;
|
|
||||||
PPEB Peb = NtCurrentPeb();
|
|
||||||
|
|
||||||
if (!Environment) RtlAcquirePebLock();
|
|
||||||
|
|
||||||
/* Query PATH env var into append path */
|
|
||||||
Status = RtlQueryEnvironmentVariable_U(Environment,
|
|
||||||
&BasePathVariableName,
|
|
||||||
&BaseDefaultPathAppend);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* Add up PATH environment length */
|
|
||||||
DefaultLength += BaseDefaultPathAppend.Length;
|
|
||||||
}
|
|
||||||
else if (Status == STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
/* We have to allocate path dynamically */
|
|
||||||
AllocatedPath = RtlAllocateHeap(RtlGetProcessHeap(), 0, BaseDefaultPathAppend.Length + sizeof(UNICODE_NULL));
|
|
||||||
|
|
||||||
if (AllocatedPath)
|
|
||||||
{
|
|
||||||
/* Set up EnvPath */
|
|
||||||
EnvPath.Buffer = AllocatedPath;
|
|
||||||
EnvPath.Length = BaseDefaultPathAppend.Length + sizeof(UNICODE_NULL);
|
|
||||||
EnvPath.MaximumLength = EnvPath.Length;
|
|
||||||
|
|
||||||
/* Query PATH env var into newly allocated path */
|
|
||||||
Status = RtlQueryEnvironmentVariable_U(Environment,
|
|
||||||
&BasePathVariableName,
|
|
||||||
&EnvPath);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DefaultLength += EnvPath.Length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Free newly allocated path, it didn't work */
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPath);
|
|
||||||
AllocatedPath = NULL;
|
|
||||||
Status = STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
secondattempt:
|
|
||||||
if (!FullPath)
|
|
||||||
{
|
|
||||||
/* Initialize BasepExeLdrEntry if necessary */
|
|
||||||
if (!BasepExeLdrEntry)
|
|
||||||
LdrEnumerateLoadedModules(0, BasepLocateExeLdrEntry, Peb->ImageBaseAddress);
|
|
||||||
|
|
||||||
DPRINT("Found BasepExeLdrEntry %wZ\n", &BasepExeLdrEntry->FullDllName);
|
|
||||||
|
|
||||||
/* Set name pointer to the full dll path */
|
|
||||||
NamePtr = BasepExeLdrEntry->FullDllName.Buffer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set name pointer to the provided path */
|
|
||||||
NamePtr = FullPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine application path length */
|
|
||||||
if (NamePtr)
|
|
||||||
{
|
|
||||||
ch = NamePtr;
|
|
||||||
while (*ch)
|
|
||||||
{
|
|
||||||
/* Check if there is a slash */
|
|
||||||
if (*ch == L'\\')
|
|
||||||
{
|
|
||||||
/* Update app length */
|
|
||||||
AppLength = (ULONG_PTR)ch - (ULONG_PTR)NamePtr + sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
ch++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now check, if we found a valid path in the provided full path */
|
|
||||||
if (!AppLength && FullPath && !SecondAttempt)
|
|
||||||
{
|
|
||||||
/* We were provided with a bad full path, retry again using just this app's path */
|
|
||||||
FullPath = NULL;
|
|
||||||
SecondAttempt = TRUE;
|
|
||||||
goto secondattempt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate the path buffer */
|
|
||||||
PathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DefaultLength + AppLength + 2*sizeof(WCHAR));
|
|
||||||
if (!PathBuffer)
|
|
||||||
{
|
|
||||||
/* Fail */
|
|
||||||
if (!Environment) RtlReleasePebLock();
|
|
||||||
if (AllocatedPath) RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPath);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy contents there */
|
|
||||||
if (AppLength)
|
|
||||||
{
|
|
||||||
/* Remove trailing slashes if it's not root dir */
|
|
||||||
if (AppLength != 3*sizeof(WCHAR))
|
|
||||||
AppLength -= sizeof(WCHAR);
|
|
||||||
|
|
||||||
/* Copy contents */
|
|
||||||
RtlMoveMemory(PathBuffer, NamePtr, AppLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the lock */
|
|
||||||
if (!Environment) RtlReleasePebLock();
|
|
||||||
|
|
||||||
/* Finish preparing the path string */
|
|
||||||
NamePtr = &PathBuffer[AppLength / sizeof(WCHAR)];
|
|
||||||
|
|
||||||
/* Put a separating ";" if something was added */
|
|
||||||
if (AppLength)
|
|
||||||
{
|
|
||||||
*NamePtr = L';';
|
|
||||||
NamePtr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AllocatedPath)
|
|
||||||
{
|
|
||||||
/* Dynamically allocated env path, copy from the static buffer,
|
|
||||||
concatenate with dynamic buffer and free it */
|
|
||||||
RtlMoveMemory(NamePtr, BaseDefaultPath.Buffer, BaseDefaultPath.Length);
|
|
||||||
RtlMoveMemory(&NamePtr[BaseDefaultPath.Length / sizeof(WCHAR)], AllocatedPath, EnvPath.Length);
|
|
||||||
|
|
||||||
/* Free it */
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Static env path string, copy directly from BaseDefaultPath */
|
|
||||||
RtlMoveMemory(NamePtr, BaseDefaultPath.Buffer, DefaultLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Null terminate the string */
|
|
||||||
NamePtr[DefaultLength / sizeof(WCHAR)] = 0;
|
|
||||||
|
|
||||||
return PathBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPWSTR
|
|
||||||
WINAPI
|
|
||||||
BasepGetDllPath(LPWSTR FullPath,
|
|
||||||
PVOID Environment)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
LPWSTR DllPath = NULL;
|
|
||||||
|
|
||||||
/* Acquire DLL directory lock */
|
|
||||||
RtlEnterCriticalSection(&BaseDllDirectoryLock);
|
|
||||||
|
|
||||||
/* Check if we have a base dll directory */
|
|
||||||
if (BaseDllDirectory.Buffer)
|
|
||||||
{
|
|
||||||
/* Then get process path */
|
|
||||||
DllPath = BasepGetProcessPath(0, FullPath, Environment);
|
|
||||||
|
|
||||||
/* Release DLL directory lock */
|
|
||||||
RtlLeaveCriticalSection(&BaseDllDirectoryLock);
|
|
||||||
|
|
||||||
/* Return dll path */
|
|
||||||
return DllPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release DLL directory lock */
|
|
||||||
RtlLeaveCriticalSection(&BaseDllDirectoryLock);
|
|
||||||
|
|
||||||
/* There is no base DLL directory */
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
|
||||||
/* Return dll path */
|
|
||||||
return DllPath;
|
|
||||||
#else
|
|
||||||
return BasepGetProcessPath(0, FullPath, Environment);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
WINAPI
|
WINAPI
|
||||||
BasepCopyHandles(IN PRTL_USER_PROCESS_PARAMETERS Params,
|
BasepCopyHandles(IN PRTL_USER_PROCESS_PARAMETERS Params,
|
||||||
|
@ -631,7 +436,9 @@ BasePushProcessParameters(IN HANDLE ProcessHandle,
|
||||||
if ((Size) && (Size <= (MAX_PATH + 4)))
|
if ((Size) && (Size <= (MAX_PATH + 4)))
|
||||||
{
|
{
|
||||||
/* Get the DLL Path */
|
/* Get the DLL Path */
|
||||||
DllPathString = BasepGetDllPath(ApplicationPathName, Environment);
|
DllPathString = BaseComputeProcessDllPath(ApplicationPathName,
|
||||||
|
Environment);
|
||||||
|
if (!DllPathString) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
/* Initialize Strings */
|
/* Initialize Strings */
|
||||||
RtlInitUnicodeString(&DllPath, DllPathString);
|
RtlInitUnicodeString(&DllPath, DllPathString);
|
||||||
|
@ -640,7 +447,8 @@ BasePushProcessParameters(IN HANDLE ProcessHandle,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Get the DLL Path */
|
/* Get the DLL Path */
|
||||||
DllPathString = BasepGetDllPath(FullPath, Environment);
|
DllPathString = BaseComputeProcessDllPath(FullPath, Environment);
|
||||||
|
if (!DllPathString) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
/* Initialize Strings */
|
/* Initialize Strings */
|
||||||
RtlInitUnicodeString(&DllPath, DllPathString);
|
RtlInitUnicodeString(&DllPath, DllPathString);
|
||||||
|
|
|
@ -88,14 +88,6 @@ typedef struct tagLOADPARMS32 {
|
||||||
DWORD dwReserved;
|
DWORD dwReserved;
|
||||||
} LOADPARMS32;
|
} LOADPARMS32;
|
||||||
|
|
||||||
typedef enum _BASE_CURRENT_DIR_PRIORITY
|
|
||||||
{
|
|
||||||
BaseCurrentDirInvalid = -1,
|
|
||||||
BaseCurrentDirFirst,
|
|
||||||
BaseCurrentDirLast,
|
|
||||||
BaseCurrentDirMax
|
|
||||||
} BASE_CURRENT_DIR_PRIORITY;
|
|
||||||
|
|
||||||
typedef enum _BASE_SEARCH_PATH_TYPE
|
typedef enum _BASE_SEARCH_PATH_TYPE
|
||||||
{
|
{
|
||||||
BaseSearchPathInvalid,
|
BaseSearchPathInvalid,
|
||||||
|
@ -107,6 +99,14 @@ typedef enum _BASE_SEARCH_PATH_TYPE
|
||||||
BaseSearchPathMax
|
BaseSearchPathMax
|
||||||
} BASE_SEARCH_PATH_TYPE, *PBASE_SEARCH_PATH_TYPE;
|
} BASE_SEARCH_PATH_TYPE, *PBASE_SEARCH_PATH_TYPE;
|
||||||
|
|
||||||
|
typedef enum _BASE_CURRENT_DIR_PLACEMENT
|
||||||
|
{
|
||||||
|
BaseCurrentDirPlacementInvalid = -1,
|
||||||
|
BaseCurrentDirPlacementDefault,
|
||||||
|
BaseCurrentDirPlacementSafe,
|
||||||
|
BaseCurrentDirPlacementMax
|
||||||
|
} BASE_CURRENT_DIR_PLACEMENT;
|
||||||
|
|
||||||
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR 1
|
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR 1
|
||||||
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS 2
|
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS 2
|
||||||
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE 3
|
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE 3
|
||||||
|
@ -289,17 +289,15 @@ BasepMapFile(IN LPCWSTR lpApplicationName,
|
||||||
OUT PHANDLE hSection,
|
OUT PHANDLE hSection,
|
||||||
IN PUNICODE_STRING ApplicationName);
|
IN PUNICODE_STRING ApplicationName);
|
||||||
|
|
||||||
LPWSTR
|
|
||||||
WINAPI
|
|
||||||
BasepGetDllPath(LPWSTR FullPath,
|
|
||||||
PVOID Environment);
|
|
||||||
|
|
||||||
|
|
||||||
PCODEPAGE_ENTRY FASTCALL
|
PCODEPAGE_ENTRY FASTCALL
|
||||||
IntGetCodePageEntry(UINT CodePage);
|
IntGetCodePageEntry(UINT CodePage);
|
||||||
|
|
||||||
LPWSTR
|
LPWSTR
|
||||||
GetDllLoadPath(LPCWSTR lpModule);
|
WINAPI
|
||||||
|
BaseComputeProcessDllPath(
|
||||||
|
IN LPWSTR FullPath,
|
||||||
|
IN PVOID Environment
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
WINAPI
|
WINAPI
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue