-/*
+/* $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 */