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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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