Author: ion Date: Sun Dec 4 19:30:12 2011 New Revision: 54592
URL: http://svn.reactos.org/svn/reactos?rev=54592&view=rev Log: [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.
Modified: trunk/reactos/dll/win32/kernel32/client/loader.c trunk/reactos/dll/win32/kernel32/client/path.c trunk/reactos/dll/win32/kernel32/client/proc.c trunk/reactos/dll/win32/kernel32/include/kernel32.h
Modified: trunk/reactos/dll/win32/kernel32/client/loader.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/l... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/loader.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/loader.c [iso-8859-1] Sun Dec 4 19:30:12 2011 @@ -67,105 +67,6 @@
/* It'a a normal DLL, just return its handle */ 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; }
/* @@ -421,9 +322,9 @@ }
/* Compute the load path */ - SearchPath = BasepGetDllPath((dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) ? (LPWSTR)lpLibFileName : NULL, - NULL); - + SearchPath = BaseComputeProcessDllPath((dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) ? + DllName.Buffer : NULL, + NULL); if (!SearchPath) { /* Getting DLL path failed, so set last error, free mem and return */ @@ -766,20 +667,24 @@ if (NT_SUCCESS(Status)) return Module;
/* If not, then the path should be computed */ - DllPath = BasepGetDllPath(NULL, 0); - - /* Call LdrGetHandle() again providing the computed DllPath - and wrapped into SEH */ - _SEH2_TRY - { - Status = LdrGetDllHandle(DllPath, NULL, ModuleName, &Module); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Fail with the SEH error */ - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; + DllPath = BaseComputeProcessDllPath(NULL, 0); + if (!DllPath) + { + Status = STATUS_NO_MEMORY; + } + else + { + _SEH2_TRY + { + Status = LdrGetDllHandle(DllPath, NULL, ModuleName, &Module); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + }
/* Free the DllPath */ RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath);
Modified: trunk/reactos/dll/win32/kernel32/client/path.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/p... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/path.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/path.c [iso-8859-1] Sun Dec 4 19:30:12 2011 @@ -33,7 +33,7 @@ 0x10000000 // 7C not allowed };
-BASE_SEARCH_PATH_TYPE BaseDllOrderCurrent[BaseCurrentDirMax][BaseSearchPathMax] = +BASE_SEARCH_PATH_TYPE BaseDllOrderCurrent[BaseCurrentDirPlacementMax][BaseSearchPathMax] = { { BaseSearchPathApp, @@ -78,7 +78,38 @@ BaseSearchPathInvalid };
+BASE_CURRENT_DIR_PLACEMENT BasepDllCurrentDirPlacement = BaseCurrentDirPlacementInvalid; + +extern UNICODE_STRING BasePathVariableName; + /* 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 WINAPI @@ -86,7 +117,274 @@ IN LPWSTR AppName, 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 @@ -94,7 +392,7 @@ BaseComputeProcessSearchPath(VOID) { DPRINT1("Computing Process Search path\n"); - + /* Compute the path using default process order */ return BasepComputeProcessPath(BaseProcessOrder, NULL, NULL); } @@ -120,7 +418,14 @@ IN PVOID Environment) { 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 */ RtlEnterCriticalSection(&BaseDllDirectoryLock); @@ -141,8 +446,65 @@ /* Release DLL directory lock */ RtlLeaveCriticalSection(&BaseDllDirectoryLock);
- /* There is no base DLL directory */ - UNIMPLEMENTED; + /* Read the current placement */ + 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 DllPath; @@ -939,6 +1301,105 @@ 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 */
Modified: trunk/reactos/dll/win32/kernel32/client/proc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/p... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] Sun Dec 4 19:30:12 2011 @@ -373,201 +373,6 @@ sizeof(HANDLE), &Dummy); } -} - -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 @@ -631,7 +436,9 @@ if ((Size) && (Size <= (MAX_PATH + 4))) { /* Get the DLL Path */ - DllPathString = BasepGetDllPath(ApplicationPathName, Environment); + DllPathString = BaseComputeProcessDllPath(ApplicationPathName, + Environment); + if (!DllPathString) return STATUS_NO_MEMORY;
/* Initialize Strings */ RtlInitUnicodeString(&DllPath, DllPathString); @@ -640,7 +447,8 @@ else { /* Get the DLL Path */ - DllPathString = BasepGetDllPath(FullPath, Environment); + DllPathString = BaseComputeProcessDllPath(FullPath, Environment); + if (!DllPathString) return STATUS_NO_MEMORY;
/* Initialize Strings */ RtlInitUnicodeString(&DllPath, DllPathString);
Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include/... ============================================================================== --- trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Sun Dec 4 19:30:12 2011 @@ -88,14 +88,6 @@ DWORD dwReserved; } LOADPARMS32;
-typedef enum _BASE_CURRENT_DIR_PRIORITY -{ - BaseCurrentDirInvalid = -1, - BaseCurrentDirFirst, - BaseCurrentDirLast, - BaseCurrentDirMax -} BASE_CURRENT_DIR_PRIORITY; - typedef enum _BASE_SEARCH_PATH_TYPE { BaseSearchPathInvalid, @@ -107,6 +99,14 @@ BaseSearchPathMax } 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_SUCCESS 2 #define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE 3 @@ -289,17 +289,15 @@ OUT PHANDLE hSection, IN PUNICODE_STRING ApplicationName);
-LPWSTR -WINAPI -BasepGetDllPath(LPWSTR FullPath, - PVOID Environment); - - PCODEPAGE_ENTRY FASTCALL IntGetCodePageEntry(UINT CodePage);
LPWSTR -GetDllLoadPath(LPCWSTR lpModule); +WINAPI +BaseComputeProcessDllPath( + IN LPWSTR FullPath, + IN PVOID Environment +);
VOID WINAPI