[SDK][KERNEL32] Add defines for PEB.AppCompatFlags CORE-12768 #resolve
[reactos.git] / reactos / dll / win32 / kernel32 / client / path.c
index a1cce70..7d91c05 100644 (file)
@@ -210,9 +210,13 @@ BasepComputeProcessPath(IN PBASE_SEARCH_PATH_TYPE PathOrder,
             }
             else
             {
-                /* Add the length of the PATH variable */
+                /* Add the length of the PATH variable unless it's empty */
                 ASSERT(!(EnvPath.Length & 1));
-                PathLengthInBytes += (EnvPath.Length + sizeof(L';'));
+                if (EnvPath.Length)
+                {
+                    /* Reserve space for the variable and a semicolon */
+                    PathLengthInBytes += (EnvPath.Length + sizeof(L';'));
+                }
             }
             break;
 
@@ -346,7 +350,7 @@ BasepComputeProcessPath(IN PBASE_SEARCH_PATH_TYPE PathOrder,
             }
             break;
 
-        /* Add the current dierctory */
+        /* Add the current directory */
         case BaseSearchPathCurrent:
 
             /* Copy it in the buffer, ASSERT there's enough space */
@@ -401,7 +405,7 @@ WINAPI
 BaseComputeProcessExePath(IN LPWSTR FullPath)
 {
     PBASE_SEARCH_PATH_TYPE PathOrder;
-    DPRINT1("Computing EXE path: %wZ\n", FullPath);
+    DPRINT("Computing EXE path: %S\n", FullPath);
 
     /* Check if we should use the current directory */
     PathOrder = NeedCurrentDirectoryForExePathW(FullPath) ?
@@ -557,7 +561,7 @@ IsShortName_U(IN PWCHAR Name,
               IN ULONG Length)
 {
     BOOLEAN HasExtension;
-    WCHAR c;
+    UCHAR c;
     NTSTATUS Status;
     UNICODE_STRING UnicodeName;
     ANSI_STRING AnsiName;
@@ -568,7 +572,7 @@ IsShortName_U(IN PWCHAR Name,
     /* What do you think 8.3 means? */
     if (Length > 12) return FALSE;
 
-    /* Sure, any emtpy name is a short name */
+    /* Sure, any empty name is a short name */
     if (!Length) return TRUE;
 
     /* This could be . or .. or something else */
@@ -587,7 +591,7 @@ IsShortName_U(IN PWCHAR Name,
 
     /* Initialize our two strings */
     RtlInitEmptyAnsiString(&AnsiName, AnsiBuffer, MAX_PATH);
-    RtlInitEmptyUnicodeString(&UnicodeName, Name, Length * sizeof(WCHAR));
+    RtlInitEmptyUnicodeString(&UnicodeName, Name, (USHORT)Length * sizeof(WCHAR));
     UnicodeName.Length = UnicodeName.MaximumLength;
 
     /* Now do the conversion */
@@ -740,6 +744,19 @@ SkipPathTypeIndicator_U(IN LPWSTR Path)
     /* Check what kind of path this is and how many slashes to skip */
     switch (RtlDetermineDosPathNameType_U(Path))
     {
+        case RtlPathTypeUncAbsolute:
+        case RtlPathTypeLocalDevice:
+        {
+            /* Keep going until we bypass the path indicators */
+            for (ReturnPath = Path + 2, i = 2; (i > 0) && (*ReturnPath); ReturnPath++)
+            {
+                /* We look for 2 slashes, so keep at it until we find them */
+                if ((*ReturnPath == L'\\') || (*ReturnPath == L'/')) i--;
+            }
+
+            return ReturnPath;
+        }
+
         case RtlPathTypeDriveAbsolute:
             return Path + 3;
 
@@ -755,18 +772,6 @@ SkipPathTypeIndicator_U(IN LPWSTR Path)
         case RtlPathTypeRootLocalDevice:
         default:
             return NULL;
-
-        case RtlPathTypeUncAbsolute:
-        case RtlPathTypeLocalDevice:
-
-            /* Keep going until we bypass the path indicators */
-            for (ReturnPath = Path + 2, i = 2; (i > 0) && (*ReturnPath); ReturnPath++)
-            {
-                /* We look for 2 slashes, so keep at it until we find them */
-                if ((*ReturnPath == L'\\') || (*ReturnPath == L'/')) i--;
-            }
-
-            return ReturnPath;
     }
 }
 
@@ -913,7 +918,7 @@ GetDllDirectoryA(IN DWORD nBufferLength,
     ANSI_STRING AnsiDllDirectory;
     ULONG Length;
 
-    RtlInitEmptyAnsiString(&AnsiDllDirectory, lpBuffer, nBufferLength);
+    RtlInitEmptyAnsiString(&AnsiDllDirectory, lpBuffer, (USHORT)nBufferLength);
 
     RtlEnterCriticalSection(&BaseDllDirectoryLock);
 
@@ -990,7 +995,7 @@ GetFullPathNameA(IN LPCSTR lpFileName,
                  OUT LPSTR *lpFilePart)
 {
     NTSTATUS Status;
-    PWCHAR Buffer;
+    PWCHAR Buffer = NULL;
     ULONG PathSize, FilePartSize;
     ANSI_STRING AnsiString;
     UNICODE_STRING FileNameString, UniString;
@@ -1114,12 +1119,12 @@ GetFullPathNameW(IN LPCWSTR lpFileName,
  */
 DWORD
 WINAPI
-SearchPathA(IN LPCSTR lpPath,
+SearchPathA(IN LPCSTR lpPath OPTIONAL,
             IN LPCSTR lpFileName,
-            IN LPCSTR lpExtension,
+            IN LPCSTR lpExtension OPTIONAL,
             IN DWORD nBufferLength,
-            IN LPSTR lpBuffer,
-            OUT LPSTR *lpFilePart)
+            OUT LPSTR lpBuffer,
+            OUT LPSTR *lpFilePart OPTIONAL)
 {
     PUNICODE_STRING FileNameString;
     UNICODE_STRING PathString, ExtensionString;
@@ -1188,7 +1193,7 @@ SearchPathA(IN LPCSTR lpPath,
             goto Quickie;
         }
 
-        /* If the correct ANSI size is too big, return requird length plus a NULL */
+        /* If the correct ANSI size is too big, return required length plus a NULL */
         if (AnsiLength >= nBufferLength)
         {
             PathSize = AnsiLength + 1;
@@ -1289,12 +1294,12 @@ Quickie:
  */
 DWORD
 WINAPI
-SearchPathW(IN LPCWSTR lpPath,
+SearchPathW(IN LPCWSTR lpPath OPTIONAL,
             IN LPCWSTR lpFileName,
-            IN LPCWSTR lpExtension,
+            IN LPCWSTR lpExtension OPTIONAL,
             IN DWORD nBufferLength,
-            IN LPWSTR lpBuffer,
-            OUT LPWSTR *lpFilePart)
+            OUT LPWSTR lpBuffer,
+            OUT LPWSTR *lpFilePart OPTIONAL)
 {
     UNICODE_STRING FileNameString, ExtensionString, PathString, CallerBuffer;
     ULONG Flags, LengthNeeded, FilePartSize;
@@ -1362,7 +1367,7 @@ SearchPathW(IN LPCWSTR lpPath,
         }
 
         /* Set the path size now that we have it */
-        PathString.MaximumLength = PathString.Length = LengthNeeded * sizeof(WCHAR);
+        PathString.MaximumLength = PathString.Length = (USHORT)LengthNeeded * sizeof(WCHAR);
 
         /* Request SxS isolation from RtlDosSearchPath_Ustr */
         Flags |= 1;
@@ -1376,7 +1381,7 @@ SearchPathW(IN LPCWSTR lpPath,
     if (nBufferLength <= UNICODE_STRING_MAX_CHARS)
     {
         /* Add it into the string */
-        CallerBuffer.MaximumLength = nBufferLength * sizeof(WCHAR);
+        CallerBuffer.MaximumLength = (USHORT)nBufferLength * sizeof(WCHAR);
     }
     else
     {
@@ -1447,7 +1452,7 @@ Quickie:
 DWORD
 WINAPI
 GetLongPathNameW(IN LPCWSTR lpszShortPath,
-                 IN LPWSTR lpszLongPath,
+                 OUT LPWSTR lpszLongPath,
                  IN DWORD cchBuffer)
 {
     PWCHAR Path, Original, First, Last, Buffer, Src, Dst;
@@ -1663,7 +1668,7 @@ Quickie:
 DWORD
 WINAPI
 GetLongPathNameA(IN LPCSTR lpszShortPath,
-                 IN LPSTR lpszLongPath,
+                 OUT LPSTR lpszLongPath,
                  IN DWORD cchBuffer)
 {
     ULONG Result, PathLength;
@@ -1706,9 +1711,9 @@ GetLongPathNameA(IN LPCSTR lpszShortPath,
 
     if (!PathLength) goto Quickie;
 
-    ShortPathUni.MaximumLength = PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+    ShortPathUni.MaximumLength = (USHORT)PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
     LongPathUni.Buffer = LongPath;
-    LongPathUni.Length = PathLength * sizeof(WCHAR);
+    LongPathUni.Length = (USHORT)PathLength * sizeof(WCHAR);
 
     Status = BasepUnicodeStringTo8BitString(&LongPathAnsi, &LongPathUni, TRUE);
     if (!NT_SUCCESS(Status))
@@ -1744,7 +1749,7 @@ Quickie:
 DWORD
 WINAPI
 GetShortPathNameA(IN LPCSTR lpszLongPath,
-                  IN LPSTR lpszShortPath,
+                  OUT LPSTR lpszShortPath,
                   IN DWORD cchBuffer)
 {
     ULONG Result, PathLength;
@@ -1787,9 +1792,9 @@ GetShortPathNameA(IN LPCSTR lpszLongPath,
 
     if (!PathLength) goto Quickie;
 
-    LongPathUni.MaximumLength = PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+    LongPathUni.MaximumLength = (USHORT)PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
     ShortPathUni.Buffer = ShortPath;
-    ShortPathUni.Length = PathLength * sizeof(WCHAR);
+    ShortPathUni.Length = (USHORT)PathLength * sizeof(WCHAR);
 
     Status = BasepUnicodeStringTo8BitString(&ShortPathAnsi, &ShortPathUni, TRUE);
     if (!NT_SUCCESS(Status))
@@ -1825,7 +1830,7 @@ Quickie:
 DWORD
 WINAPI
 GetShortPathNameW(IN LPCWSTR lpszLongPath,
-                  IN LPWSTR lpszShortPath,
+                  OUT LPWSTR lpszShortPath,
                   IN DWORD cchBuffer)
 {
     PWCHAR Path, Original, First, Last, Buffer, Src, Dst;
@@ -1856,7 +1861,7 @@ GetShortPathNameW(IN LPCWSTR lpszLongPath,
     if (GetFileAttributesW(lpszLongPath) == INVALID_FILE_ATTRIBUTES)
     {
         /* Windows checks for an application compatibility flag to allow this */
-        if (!(NtCurrentPeb()) || !(NtCurrentPeb()->AppCompatFlags.LowPart & 1))
+        if (!(NtCurrentPeb()) || !(NtCurrentPeb()->AppCompatFlags.LowPart & GetShortPathNameNT4))
         {
             /* It doesn't, so fail */
             ReturnLength = 0;
@@ -2047,7 +2052,7 @@ Quickie:
 DWORD
 WINAPI
 GetTempPathA(IN DWORD nBufferLength,
-             IN LPSTR lpBuffer)
+             OUT LPSTR lpBuffer)
 {
    WCHAR BufferW[MAX_PATH];
    DWORD ret;
@@ -2073,7 +2078,7 @@ GetTempPathA(IN DWORD nBufferLength,
 DWORD
 WINAPI
 GetTempPathW(IN DWORD count,
-             IN LPWSTR path)
+             OUT LPWSTR path)
 {
     static const WCHAR tmp[]  = { 'T', 'M', 'P', 0 };
     static const WCHAR temp[] = { 'T', 'E', 'M', 'P', 0 };
@@ -2115,13 +2120,18 @@ GetTempPathW(IN DWORD count,
 
     ret++; /* add space for terminating 0 */
 
-    if (count)
+    if (count >= ret)
     {
         lstrcpynW(path, full_tmp_path, count);
-        if (count >= ret)
-            ret--; /* return length without 0 */
-        else if (count < 4)
-            path[0] = 0; /* avoid returning ambiguous "X:" */
+        /* the remaining buffer must be zeroed up to 32766 bytes in XP or 32767
+         * bytes after it, we will assume the > XP behavior for now */
+        memset(path + ret, 0, (min(count, 32767) - ret) * sizeof(WCHAR));
+        ret--; /* return length without 0 */
+    }
+    else if (count)
+    {
+        /* the buffer must be cleared if contents will not fit */
+        memset(path, 0, count * sizeof(WCHAR));
     }
 
     DPRINT("GetTempPathW returning %u, %S\n", ret, path);
@@ -2134,7 +2144,7 @@ GetTempPathW(IN DWORD count,
 DWORD
 WINAPI
 GetCurrentDirectoryA(IN DWORD nBufferLength,
-                     IN LPSTR lpBuffer)
+                     OUT LPSTR lpBuffer)
 {
     ANSI_STRING AnsiString;
     NTSTATUS Status;
@@ -2149,8 +2159,8 @@ GetCurrentDirectoryA(IN DWORD nBufferLength,
         MaxLength = UNICODE_STRING_MAX_BYTES - 1;
     }
 
-    StaticString->Length = RtlGetCurrentDirectory_U(StaticString->MaximumLength,
-                                                    StaticString->Buffer);
+    StaticString->Length = (USHORT)RtlGetCurrentDirectory_U(StaticString->MaximumLength,
+                                                            StaticString->Buffer);
     Status = RtlUnicodeToMultiByteSize(&nBufferLength,
                                        StaticString->Buffer,
                                        StaticString->Length);
@@ -2166,7 +2176,7 @@ GetCurrentDirectoryA(IN DWORD nBufferLength,
     }
 
     AnsiString.Buffer = lpBuffer;
-    AnsiString.MaximumLength = MaxLength;
+    AnsiString.MaximumLength = (USHORT)MaxLength;
     Status = BasepUnicodeStringTo8BitString(&AnsiString, StaticString, FALSE);
     if (!NT_SUCCESS(Status))
     {
@@ -2183,7 +2193,7 @@ GetCurrentDirectoryA(IN DWORD nBufferLength,
 DWORD
 WINAPI
 GetCurrentDirectoryW(IN DWORD nBufferLength,
-                     IN LPWSTR lpBuffer)
+                     OUT LPWSTR lpBuffer)
 {
     return RtlGetCurrentDirectory_U(nBufferLength * sizeof(WCHAR), lpBuffer) / sizeof(WCHAR);
 }
@@ -2270,7 +2280,7 @@ SetCurrentDirectoryW(IN LPCWSTR lpPathName)
  */
 UINT
 WINAPI
-GetSystemDirectoryA(IN LPSTR lpBuffer,
+GetSystemDirectoryA(OUT LPSTR lpBuffer,
                     IN UINT uSize)
 {
     ANSI_STRING AnsiString;
@@ -2300,7 +2310,7 @@ GetSystemDirectoryA(IN LPSTR lpBuffer,
  */
 UINT
 WINAPI
-GetSystemDirectoryW(IN LPWSTR lpBuffer,
+GetSystemDirectoryW(OUT LPWSTR lpBuffer,
                     IN UINT uSize)
 {
     ULONG ReturnLength;
@@ -2324,7 +2334,7 @@ GetSystemDirectoryW(IN LPWSTR lpBuffer,
  */
 UINT
 WINAPI
-GetWindowsDirectoryA(IN LPSTR lpBuffer,
+GetWindowsDirectoryA(OUT LPSTR lpBuffer,
                      IN UINT uSize)
 {
     /* Is this a TS installation? */
@@ -2339,7 +2349,7 @@ GetWindowsDirectoryA(IN LPSTR lpBuffer,
  */
 UINT
 WINAPI
-GetWindowsDirectoryW(IN LPWSTR lpBuffer,
+GetWindowsDirectoryW(OUT LPWSTR lpBuffer,
                      IN UINT uSize)
 {
     /* Is this a TS installation? */
@@ -2354,7 +2364,7 @@ GetWindowsDirectoryW(IN LPWSTR lpBuffer,
  */
 UINT
 WINAPI
-GetSystemWindowsDirectoryA(IN LPSTR lpBuffer,
+GetSystemWindowsDirectoryA(OUT LPSTR lpBuffer,
                            IN UINT uSize)
 {
     ANSI_STRING AnsiString;
@@ -2384,7 +2394,7 @@ GetSystemWindowsDirectoryA(IN LPSTR lpBuffer,
  */
 UINT
 WINAPI
-GetSystemWindowsDirectoryW(IN LPWSTR lpBuffer,
+GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer,
                            IN UINT uSize)
 {
     ULONG ReturnLength;
@@ -2408,7 +2418,7 @@ GetSystemWindowsDirectoryW(IN LPWSTR lpBuffer,
  */
 UINT
 WINAPI
-GetSystemWow64DirectoryW(IN LPWSTR lpBuffer,
+GetSystemWow64DirectoryW(OUT LPWSTR lpBuffer,
                          IN UINT uSize)
 {
 #ifdef _WIN64
@@ -2425,7 +2435,7 @@ GetSystemWow64DirectoryW(IN LPWSTR lpBuffer,
  */
 UINT
 WINAPI
-GetSystemWow64DirectoryA(IN LPSTR lpBuffer,
+GetSystemWow64DirectoryA(OUT LPSTR lpBuffer,
                          IN UINT uSize)
 {
 #ifdef _WIN64