Manually applying Gunnars patch because it's easier this way - and a good chance...
[reactos.git] / reactos / lib / kernel32 / file / curdir.c
index 2e0c613..9c68c5a 100644 (file)
@@ -1,9 +1,9 @@
-/*
+/* $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
  * PURPOSE:         Current directory functions
- * PROGRAMMER:      David Welch (welch@mcmail.com)
  * UPDATE HISTORY:
  *                  Created 30/09/98
  */
 
 /* INCLUDES ******************************************************************/
 
+#include <ddk/ntddk.h>
+#include <ntdll/rtl.h>
 #include <windows.h>
 
-/* GLOBALS *******************************************************************/
+#define NDEBUG
+#include <kernel32/kernel32.h>
+#include <kernel32/error.h>
 
 
-static unsigned short CurrentDirectoryW[MAX_PATH];
+/* GLOBAL VARIABLES **********************************************************/
 
-static unsigned short SystemDirectoryW[MAX_PATH];
+UNICODE_STRING SystemDirectory;
+UNICODE_STRING WindowsDirectory;
 
-static unsigned short WindowsDirectoryW[MAX_PATH];
 
 /* FUNCTIONS *****************************************************************/
-DWORD 
+
+DWORD
 STDCALL
-GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer)
+GetCurrentDirectoryA (
+       DWORD   nBufferLength,
+       LPSTR   lpBuffer
+       )
 {
-   UINT uSize,i;
-   if ( lpBuffer == NULL ) 
-       return 0;
-   uSize = lstrlenW(CurrentDirectoryW); 
-   if ( nBufferLength > uSize ) {
-       i = 0;
-       while ((CurrentDirectoryW[i])!=0 && i < MAX_PATH)
-       {
-               lpBuffer[i] = (unsigned char)CurrentDirectoryW[i];
-               i++;
-       }
-       lpBuffer[i] = 0;
-   }
-   return uSize;
+       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
-GetCurrentDirectoryW(
-    DWORD nBufferLength,
-    LPWSTR lpBuffer
-    )
+GetCurrentDirectoryW (
+       DWORD   nBufferLength,
+       LPWSTR  lpBuffer
+       )
 {
-   UINT uSize;
-   if ( lpBuffer == NULL ) 
-       return 0;
-   uSize = lstrlenW(CurrentDirectoryW); 
-   if ( nBufferLength > uSize )
-       lstrcpynW(lpBuffer,CurrentDirectoryW,uSize);
-   
-   return uSize;
+       ULONG Length;
+
+       Length = RtlGetCurrentDirectory_U (nBufferLength,
+                                          lpBuffer);
+
+       return (Length / sizeof (WCHAR));
 }
 
-BOOL 
+
+WINBOOL
 STDCALL
-SetCurrentDirectoryA(LPCSTR lpPathName)
+SetCurrentDirectoryA (
+       LPCSTR  lpPathName
+       )
 {
-   UINT i;
-
-   if ( lpPathName == NULL ); 
-       return FALSE;
-   if ( lstrlenA(lpPathName) > MAX_PATH ); 
-       return FALSE;
-   i = 0;
-   while ((lpPathName[i])!=0 && i < MAX_PATH)
-   {
-       CurrentDirectoryW[i] = (unsigned short)lpPathName[i];
-       i++;
-   }
-   CurrentDirectoryW[i] = 0;
-
-   return(TRUE);
+       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
-SetCurrentDirectoryW(
-    LPCWSTR lpPathName
-    )
+SetCurrentDirectoryW (
+       LPCWSTR lpPathName
+       )
 {
-   if ( lpPathName == NULL ); 
-       return FALSE;
-   if ( lstrlenW(lpPathName) > MAX_PATH ); 
-       return FALSE;
-   lstrcpyW(CurrentDirectoryW,lpPathName);
-   return(TRUE);
+       UNICODE_STRING UnicodeString;
+       NTSTATUS Status;
+
+       RtlInitUnicodeString (&UnicodeString,
+                             lpPathName);
+
+       Status = RtlSetCurrentDirectory_U (&UnicodeString);
+       if (!NT_SUCCESS(Status))
+       {
+               SetLastErrorByStatus (Status);
+               return FALSE;
+       }
+
+       return TRUE;
 }
 
+
 DWORD
 STDCALL
-GetTempPathA(
-    DWORD nBufferLength,
-    LPSTR lpBuffer
-    )
+GetTempPathA (
+       DWORD   nBufferLength,
+       LPSTR   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 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
-GetTempPathW(
-    DWORD nBufferLength,
-    LPWSTR lpBuffer
-    )
+GetTempPathW (
+       DWORD   nBufferLength,
+       LPWSTR  lpBuffer
+       )
 {
+       UNICODE_STRING Name;
+       UNICODE_STRING Value;
+       NTSTATUS Status;
+
+       Value.Length = 0;
+       Value.MaximumLength = (nBufferLength - 1) * sizeof(WCHAR);
+       Value.Buffer = lpBuffer;
 
-       WCHAR EnvironmentBufferW[MAX_PATH];
-       UINT i;
+       RtlInitUnicodeStringFromLiteral (&Name,
+                             L"TMP");
 
-       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);
+       Status = RtlQueryEnvironmentVariable_U (NULL,
+                                               &Name,
+                                               &Value);
+       if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+       {
+               RtlInitUnicodeStringFromLiteral (&Name,
+                                     L"TEMP");
 
-       return i;
+               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;
 }
 
+
 UINT
 STDCALL
-GetSystemDirectoryA(
-    LPSTR lpBuffer,
-    UINT uSize
-    )
+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;
+       ANSI_STRING String;
+       ULONG Length;
+       NTSTATUS Status;
+
+       if (lpBuffer == NULL)
+               return 0;
+
+       Length = RtlUnicodeStringToAnsiSize (&SystemDirectory);   //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,
+                                                     &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
-    )
+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;
-}
\ No newline at end of file
+       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 */