Manually applying Gunnars patch because it's easier this way - and a good chance...
[reactos.git] / reactos / lib / kernel32 / file / curdir.c
index d161e93..9c68c5a 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* $Id: curdir.c,v 1.33 2002/11/07 02:52:37 robd Exp $
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * FILE:            lib/kernel32/file/curdir.c
 
 /* INCLUDES ******************************************************************/
 
+#include <ddk/ntddk.h>
+#include <ntdll/rtl.h>
 #include <windows.h>
-#include <wchar.h>
-#include <ctype.h>
-#include <string.h>
 
-//#define NDEBUG
+#define NDEBUG
 #include <kernel32/kernel32.h>
+#include <kernel32/error.h>
 
-/* GLOBALS *******************************************************************/
 
-#define MAX_DOS_DRIVES 26
+/* GLOBAL VARIABLES **********************************************************/
 
-static HANDLE hCurrentDirectory = NULL;
-static ULONG CurrentDrive = 0;
+UNICODE_STRING SystemDirectory;
+UNICODE_STRING WindowsDirectory;
 
-static WCHAR DriveDirectoryW[MAX_DOS_DRIVES][MAX_PATH] = {{0}};
-
-static WCHAR SystemDirectoryW[MAX_PATH];
-static WCHAR WindowsDirectoryW[MAX_PATH];
-
-WINBOOL STDCALL SetCurrentDirectoryW(LPCWSTR lpPathName);
 
 /* FUNCTIONS *****************************************************************/
 
-DWORD STDCALL GetCurrentDriveW(DWORD nBufferLength, PWSTR lpBuffer)
+DWORD
+STDCALL
+GetCurrentDirectoryA (
+       DWORD   nBufferLength,
+       LPSTR   lpBuffer
+       )
 {
-   lpBuffer[0] = 'A' + CurrentDrive;
-   lpBuffer[1] = ':';
-   lpBuffer[2] = '\\';
-   lpBuffer[3] = 0;
-   return(4);
+       ANSI_STRING AnsiString;
+       UNICODE_STRING UnicodeString;
+
+       /* initialize ansi string */
+       AnsiString.Length = 0;
+       AnsiString.MaximumLength = nBufferLength;
+       AnsiString.Buffer = lpBuffer;
+
+       /* allocate buffer for unicode string */
+       UnicodeString.Length = 0;
+       UnicodeString.MaximumLength = nBufferLength * sizeof(WCHAR);
+       UnicodeString.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
+                                               0,
+                                               UnicodeString.MaximumLength);
+
+       /* get current directory */
+       UnicodeString.Length = RtlGetCurrentDirectory_U (UnicodeString.MaximumLength,
+                                                        UnicodeString.Buffer);
+       DPRINT("UnicodeString.Buffer %S\n", UnicodeString.Buffer);
+
+       /* convert unicode string to ansi (or oem) */
+       if (bIsFileApiAnsi)
+               RtlUnicodeStringToAnsiString (&AnsiString,
+                                             &UnicodeString,
+                                             FALSE);
+       else
+               RtlUnicodeStringToOemString (&AnsiString,
+                                            &UnicodeString,
+                                            FALSE);
+       DPRINT("AnsiString.Buffer %s\n", AnsiString.Buffer);
+
+       /* free unicode string */
+       RtlFreeHeap (RtlGetProcessHeap (),
+                    0,
+                    UnicodeString.Buffer);
+
+       return AnsiString.Length;
 }
 
-DWORD STDCALL GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer)
+
+DWORD
+STDCALL
+GetCurrentDirectoryW (
+       DWORD   nBufferLength,
+       LPWSTR  lpBuffer
+       )
 {
-   UINT uSize,i;
-   WCHAR TempDir[MAX_PATH];
-   
-   if ( lpBuffer == NULL ) 
-       return 0;
-   GetCurrentDirectoryW(MAX_PATH, TempDir);
-   uSize = lstrlenW(TempDir); 
-   if (nBufferLength > uSize) 
-     {
-       i = 0;
-       while (TempDir[i] != 0)
-       {
-          lpBuffer[i] = (unsigned char)TempDir[i];
-          i++;
-       }
-       lpBuffer[i] = 0;
-     }
-   return uSize;
+       ULONG Length;
+
+       Length = RtlGetCurrentDirectory_U (nBufferLength,
+                                          lpBuffer);
+
+       return (Length / sizeof (WCHAR));
 }
 
-DWORD STDCALL GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
+
+WINBOOL
+STDCALL
+SetCurrentDirectoryA (
+       LPCSTR  lpPathName
+       )
 {
-   UINT uSize;
-   
-   DPRINT("GetCurrentDirectoryW()\n");
-   
-   if ( lpBuffer == NULL ) 
-       return 0;
-   uSize = lstrlenW(DriveDirectoryW[CurrentDrive]) + 2;
-   if (nBufferLength > uSize)
-     {
-       lpBuffer[0] = 'A' + CurrentDrive;
-       lpBuffer[1] = ':';
-       lpBuffer[2] = 0;
-       lstrcpyW(&lpBuffer[2], DriveDirectoryW[CurrentDrive]);
-     }
-   if (uSize > 3 && lpBuffer[uSize - 1] == L'\\')
-     {
-        lpBuffer[uSize - 1] = 0;
-        uSize--;
-     }
-   DPRINT("GetCurrentDirectoryW() = '%w'\n",lpBuffer);
-   return uSize;
+       ANSI_STRING AnsiString;
+       UNICODE_STRING UnicodeString;
+       NTSTATUS Status;
+
+       RtlInitAnsiString (&AnsiString,
+                          (LPSTR)lpPathName);
+
+       /* convert ansi (or oem) to unicode */
+       if (bIsFileApiAnsi)
+               RtlAnsiStringToUnicodeString (&UnicodeString,
+                                             &AnsiString,
+                                             TRUE);
+       else
+               RtlOemStringToUnicodeString (&UnicodeString,
+                                            &AnsiString,
+                                            TRUE);
+
+       Status = RtlSetCurrentDirectory_U (&UnicodeString);
+
+       RtlFreeUnicodeString (&UnicodeString);
+
+       if (!NT_SUCCESS(Status))
+       {
+               SetLastErrorByStatus (Status);
+               return FALSE;
+       }
+
+       return TRUE;
 }
 
-WINBOOL STDCALL SetCurrentDirectoryA(LPCSTR lpPathName)
+
+WINBOOL
+STDCALL
+SetCurrentDirectoryW (
+       LPCWSTR lpPathName
+       )
 {
-   UINT i;
-   WCHAR PathNameW[MAX_PATH];
-   if ( lpPathName == NULL )
-     {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-     }
-
-   if ( lstrlen(lpPathName) > MAX_PATH )
-     {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        return FALSE;
-     }
-
-   i = 0;
-   while ((lpPathName[i])!=0 && i < MAX_PATH)
-     {
-        PathNameW[i] = (WCHAR)lpPathName[i];
-        i++;
-     }
-   PathNameW[i] = 0;
-
-   return SetCurrentDirectoryW(PathNameW);
+       UNICODE_STRING UnicodeString;
+       NTSTATUS Status;
+
+       RtlInitUnicodeString (&UnicodeString,
+                             lpPathName);
+
+       Status = RtlSetCurrentDirectory_U (&UnicodeString);
+       if (!NT_SUCCESS(Status))
+       {
+               SetLastErrorByStatus (Status);
+               return FALSE;
+       }
+
+       return TRUE;
 }
 
-WINBOOL STDCALL SetCurrentDirectoryW(LPCWSTR lpPathName)
+
+DWORD
+STDCALL
+GetTempPathA (
+       DWORD   nBufferLength,
+       LPSTR   lpBuffer
+       )
 {
-   ULONG len;
-   WCHAR PathName[MAX_PATH];
-   HANDLE hDir;
-   
-   DPRINT("SetCurrentDirectoryW(lpPathName %w)\n",lpPathName);
-   
-   if (lpPathName == NULL)
-     {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-     }
-   
-   len = lstrlenW(lpPathName);
-   if (len > MAX_PATH)
-     {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        return FALSE;
-     }
-
-   if (!GetFullPathNameW (lpPathName, MAX_PATH, PathName, NULL))
-     {
-        SetLastError(ERROR_BAD_PATHNAME);
-        return FALSE;
-     }
-
-   /* Drive letter MUST be capitalized */
-   PathName[0] = towupper (PathName[0]);
-
-   DPRINT("PathName %w\n",PathName);
-
-   hDir = CreateFileW(PathName,
-                     GENERIC_READ,
-                     FILE_SHARE_READ,
-                     NULL,
-                     OPEN_EXISTING,
-                     FILE_ATTRIBUTE_DIRECTORY,
-                     NULL);
-   if (hDir == INVALID_HANDLE_VALUE)
-     {
-       DPRINT("Failed to open directory\n");
-        SetLastError(ERROR_BAD_PATHNAME);
-        return FALSE;
-     }
-
-   if (hCurrentDirectory != NULL)
-     {
-       CloseHandle(hCurrentDirectory);
-     }
-
-   hCurrentDirectory = hDir;
-   
-   DPRINT("PathName %w\n",PathName);
-       
-   CurrentDrive = toupper((UCHAR)PathName[0]) - 'A';
-   wcscpy(DriveDirectoryW[CurrentDrive],&PathName[2]);
-   len = lstrlenW(DriveDirectoryW[CurrentDrive]);
-   if (DriveDirectoryW[CurrentDrive][len-1] != '\\')
-     {
-        DriveDirectoryW[CurrentDrive][len] = '\\';
-        DriveDirectoryW[CurrentDrive][len+1] = 0;
-     }
-
-   return TRUE;
+       UNICODE_STRING UnicodeString;
+       ANSI_STRING AnsiString;
+
+       AnsiString.Length = 0;
+       AnsiString.MaximumLength = nBufferLength;
+       AnsiString.Buffer = lpBuffer;
+
+       /* initialize allocate unicode string */
+       UnicodeString.Length = 0;
+       UnicodeString.MaximumLength = nBufferLength * sizeof(WCHAR);
+       UnicodeString.Buffer = RtlAllocateHeap (RtlGetProcessHeap(),
+                                               0,
+                                               UnicodeString.MaximumLength);
+
+       UnicodeString.Length = GetTempPathW (nBufferLength,
+                                            UnicodeString.Buffer) * sizeof(WCHAR);
+
+       /* convert unicode string to ansi (or oem) */
+       if (bIsFileApiAnsi)
+               RtlUnicodeStringToAnsiString (&AnsiString,
+                                             &UnicodeString,
+                                             FALSE);
+       else
+               RtlUnicodeStringToOemString (&AnsiString,
+                                            &UnicodeString,
+                                            FALSE);
+
+       /* free unicode string buffer */
+       RtlFreeHeap (RtlGetProcessHeap (),
+                    0,
+                    UnicodeString.Buffer);
+
+       return AnsiString.Length;
 }
 
-DWORD STDCALL GetTempPathA(DWORD nBufferLength, LPSTR lpBuffer)
+
+DWORD
+STDCALL
+GetTempPathW (
+       DWORD   nBufferLength,
+       LPWSTR  lpBuffer
+       )
 {
-       WCHAR BufferW[MAX_PATH];
-       DWORD retCode;
-       UINT i;
-       retCode = GetTempPathW(nBufferLength,BufferW);
-       i = 0;
-       while ((BufferW[i])!=0 && i < MAX_PATH)
-       {
-               lpBuffer[i] = (unsigned char)BufferW[i];
-               i++;
-       }
-       lpBuffer[i] = 0;
-       return retCode;
+       UNICODE_STRING Name;
+       UNICODE_STRING Value;
+       NTSTATUS Status;
+
+       Value.Length = 0;
+       Value.MaximumLength = (nBufferLength - 1) * sizeof(WCHAR);
+       Value.Buffer = lpBuffer;
+
+       RtlInitUnicodeStringFromLiteral (&Name,
+                             L"TMP");
+
+       Status = RtlQueryEnvironmentVariable_U (NULL,
+                                               &Name,
+                                               &Value);
+       if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+       {
+               RtlInitUnicodeStringFromLiteral (&Name,
+                                     L"TEMP");
+
+               Status = RtlQueryEnvironmentVariable_U (NULL,
+                                                       &Name,
+                                                       &Value);
+
+               if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+               {
+                       Value.Length = RtlGetCurrentDirectory_U (Value.MaximumLength,
+                                                                Value.Buffer);
+               }
+       }
+
+       if (NT_SUCCESS(Status))
+       {
+               lpBuffer[Value.Length / sizeof(WCHAR)] = L'\\';
+               lpBuffer[Value.Length / sizeof(WCHAR) + 1] = 0;
+       }
+
+       return Value.Length / sizeof(WCHAR) + 1;
 }
 
-DWORD STDCALL GetTempPathW(DWORD nBufferLength, LPWSTR lpBuffer)
+
+UINT
+STDCALL
+GetSystemDirectoryA (
+       LPSTR   lpBuffer,
+       UINT    uSize
+       )
 {
-       WCHAR EnvironmentBufferW[MAX_PATH];
-       UINT i;
+       ANSI_STRING String;
+       ULONG Length;
+       NTSTATUS Status;
 
-       EnvironmentBufferW[0] = 0;
-       i = GetEnvironmentVariableW(L"TMP",EnvironmentBufferW,MAX_PATH);
-       if ( i==0 )
-               i = GetEnvironmentVariableW(L"TEMP",EnvironmentBufferW,MAX_PATH);
-               if ( i==0 )
-                       i = GetCurrentDirectoryW(MAX_PATH,EnvironmentBufferW);
+       if (lpBuffer == NULL)
+               return 0;
 
-       return i;
-}
+       Length = RtlUnicodeStringToAnsiSize (&SystemDirectory);   //len of ansi str incl. nullchar
 
-UINT STDCALL GetSystemDirectoryA(LPSTR lpBuffer, UINT uSize)
-{
-   UINT uPathSize,i;
-   if ( lpBuffer == NULL ) 
-       return 0;
-   uPathSize = lstrlenW(SystemDirectoryW); 
-   if ( uSize > uPathSize ) {
-       i = 0;
-       while ((SystemDirectoryW[i])!=0 && i < uSize)
-       {
-               lpBuffer[i] = (unsigned char)SystemDirectoryW[i];
-               i++;
-       }
-       lpBuffer[i] = 0;
-   }
-   
-   return uPathSize;
+       if (uSize >= Length){
+               String.Length = 0;
+               String.MaximumLength = uSize;
+               String.Buffer = lpBuffer;
+
+               /* convert unicode string to ansi (or oem) */
+               if (bIsFileApiAnsi)
+                       Status = RtlUnicodeStringToAnsiString (&String,
+                                                     &SystemDirectory,
+                                                     FALSE);
+               else
+                       Status = RtlUnicodeStringToOemString (&String,
+                                                    &SystemDirectory,
+                                                    FALSE);
+               if (!NT_SUCCESS(Status) )
+                       return 0;
+
+               return Length-1;  //good: ret chars excl. nullchar
+
+       }
+
+       return Length;   //bad: ret space needed incl. nullchar
 }
 
-UINT STDCALL GetWindowsDirectoryA(LPSTR lpBuffer, UINT uSize)
+
+UINT
+STDCALL
+GetSystemDirectoryW (
+       LPWSTR  lpBuffer,
+       UINT    uSize
+       )
 {
-   UINT uPathSize,i;
-   if ( lpBuffer == NULL ) 
-       return 0;
-   uPathSize = lstrlenW(WindowsDirectoryW); 
-   if ( uSize > uPathSize ) {
-       i = 0;
-       while ((WindowsDirectoryW[i])!=0 && i < uSize)
-       {
-               lpBuffer[i] = (unsigned char)WindowsDirectoryW[i];
-               i++;
-       }
-       lpBuffer[i] = 0;
-   }
-   return uPathSize;
+       ULONG Length;
+
+       if (lpBuffer == NULL)
+               return 0;
+
+       Length = SystemDirectory.Length / sizeof (WCHAR);
+       if (uSize > Length)     {
+               memmove (lpBuffer,
+                        SystemDirectory.Buffer,
+                        SystemDirectory.Length);
+               lpBuffer[Length] = 0;
+
+               return Length;    //good: ret chars excl. nullchar
+       }
+
+       return Length+1;         //bad: ret space needed incl. nullchar
 }
 
+
 UINT
 STDCALL
-GetSystemDirectoryW(
-    LPWSTR lpBuffer,
-    UINT uSize
-    )
+GetWindowsDirectoryA (
+       LPSTR   lpBuffer,
+       UINT    uSize
+       )
 {
-   UINT uPathSize;
-   if ( lpBuffer == NULL ) 
-       return 0;
-   uPathSize = lstrlenW(SystemDirectoryW); 
-   if ( uSize > uPathSize ) 
-       lstrcpynW(lpBuffer,SystemDirectoryW,uPathSize);
-
-   return uPathSize;
+       ANSI_STRING String;
+       ULONG Length;
+       NTSTATUS Status;
+
+       if (lpBuffer == NULL)
+               return 0;
+
+       Length = RtlUnicodeStringToAnsiSize (&WindowsDirectory); //len of ansi str incl. nullchar
+       
+       if (uSize >= Length){
+
+               String.Length = 0;
+               String.MaximumLength = uSize;
+               String.Buffer = lpBuffer;
+
+               /* convert unicode string to ansi (or oem) */
+               if (bIsFileApiAnsi)
+                       Status = RtlUnicodeStringToAnsiString (&String,
+                                                     &WindowsDirectory,
+                                                     FALSE);
+               else
+                       Status = RtlUnicodeStringToOemString (&String,
+                                                    &WindowsDirectory,
+                                                    FALSE);
+
+               if (!NT_SUCCESS(Status))
+                       return 0;
+
+               return Length-1;        //good: ret chars excl. nullchar
+       }
+
+       return Length;  //bad: ret space needed incl. nullchar
 }
 
+
 UINT
 STDCALL
-GetWindowsDirectoryW(
-    LPWSTR lpBuffer,
-    UINT uSize
-    )
+GetWindowsDirectoryW (
+       LPWSTR  lpBuffer,
+       UINT    uSize
+       )
 {
-   UINT uPathSize;
-   if ( lpBuffer == NULL ) 
-       return 0;
-   uPathSize = lstrlenW(WindowsDirectoryW); 
-   if ( uSize > uPathSize );
-       lstrcpynW(lpBuffer,WindowsDirectoryW,uPathSize);
-
-   return uPathSize;
+       ULONG Length;
+
+       if (lpBuffer == NULL)
+               return 0;
+
+       Length = WindowsDirectory.Length / sizeof (WCHAR);
+       if (uSize > Length)
+       {
+               memmove (lpBuffer,
+                        WindowsDirectory.Buffer,
+                        WindowsDirectory.Length);
+               lpBuffer[Length] = 0;
+
+               return Length;    //good: ret chars excl. nullchar
+       }
+
+       return Length+1;        //bad: ret space needed incl. nullchar
 }
 
+/* EOF */