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/loader.c?rev=54592&r1=54591&r2=54592&view=diff
==============================================================================
--- 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/path.c?rev=54592&r1=54591&r2=54592&view=diff
==============================================================================
--- 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/proc.c?rev=54592&r1=54591&r2=54592&view=diff
==============================================================================
--- 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/kernel32.h?rev=54592&r1=54591&r2=54592&view=diff
==============================================================================
--- 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


Reply via email to