[KERNEL32]: Show some love to Get/SetCurrent/Windows/SystemDirectoryA/W. Only SearchPathW and loader stuff remains to be fixed. Also handle SetCurrentDirectory when directory is already current.

[KERNEL32]: Rewrite the tape APIs to use a single generic function, and in the process support pending I/O now, which wasn't handled before.
[KERNEL32]: Moved the interlocked APIs to synch.c instead of dllmain.c

svn path=/trunk/; revision=54334
This commit is contained in:
Alex Ionescu 2011-11-07 07:41:52 +00:00
parent b7ad8c6fb9
commit 40b0836010
5 changed files with 540 additions and 483 deletions

View file

@ -19,9 +19,6 @@
/* GLOBALS *******************************************************************/
extern UNICODE_STRING SystemDirectory;
extern UNICODE_STRING WindowsDirectory;
PBASE_STATIC_SERVER_DATA BaseStaticServerData;
BOOLEAN BaseRunningInServerProcess;
@ -34,7 +31,6 @@ HMODULE kernel32_handle = NULL;
PPEB Peb;
ULONG SessionId;
BOOL ConsoleInitialized = FALSE;
UNICODE_STRING BaseWindowsDirectory, BaseWindowsSystemDirectory;
static BOOL DllInitialized = FALSE;
BOOL WINAPI
@ -271,12 +267,10 @@ DllMain(HANDLE hDll,
/* Set the directories */
BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory;
BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory;
SystemDirectory = BaseWindowsSystemDirectory;
WindowsDirectory = BaseWindowsDirectory;
/* Construct the default path (using the static buffer) */
_snwprintf(BaseDefaultPathBuffer, sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR),
L".;%wZ;%wZ\\system;%wZ;", &SystemDirectory, &WindowsDirectory, &WindowsDirectory);
L".;%wZ;%wZ\\system;%wZ;", &BaseWindowsSystemDirectory, &BaseWindowsDirectory, &BaseWindowsDirectory);
BaseDefaultPath.Buffer = BaseDefaultPathBuffer;
BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR);
@ -337,50 +331,4 @@ DllMain(HANDLE hDll,
return TRUE;
}
#undef InterlockedIncrement
#undef InterlockedDecrement
#undef InterlockedExchange
#undef InterlockedExchangeAdd
#undef InterlockedCompareExchange
LONG
WINAPI
InterlockedIncrement(IN OUT LONG volatile *lpAddend)
{
return _InterlockedIncrement(lpAddend);
}
LONG
WINAPI
InterlockedDecrement(IN OUT LONG volatile *lpAddend)
{
return _InterlockedDecrement(lpAddend);
}
#undef InterlockedExchange
LONG
WINAPI
InterlockedExchange(IN OUT LONG volatile *Target,
IN LONG Value)
{
return _InterlockedExchange(Target, Value);
}
LONG
WINAPI
InterlockedExchangeAdd(IN OUT LONG volatile *Addend,
IN LONG Value)
{
return _InterlockedExchangeAdd(Addend, Value);
}
LONG
WINAPI
InterlockedCompareExchange(IN OUT LONG volatile *Destination,
IN LONG Exchange,
IN LONG Comperand)
{
return _InterlockedCompareExchange(Destination, Exchange, Comperand);
}
/* EOF */

View file

@ -9,404 +9,311 @@
* Created 01/11/98
*/
/* INCLUDES *****************************************************************/
/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ****************************************************************/
/* PRIVATE FUNCTIONS **********************************************************/
/*
* @implemented
*/
DWORD WINAPI
CreateTapePartition (HANDLE hDevice,
DWORD dwPartitionMethod,
DWORD dwCount,
DWORD dwSize)
DWORD
WINAPI
BasepDoTapeOperation(IN HANDLE DeviceHandle,
IN ULONG Ioctl,
IN PVOID Input,
IN ULONG InputLength,
IN PVOID Output,
IN ULONG OutputLength)
{
TAPE_CREATE_PARTITION TapeCreatePartition;
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
HANDLE TapeEvent;
DWORD ErrorCode;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
TapeCreatePartition.Method = dwPartitionMethod;
TapeCreatePartition.Count = dwCount;
TapeCreatePartition.Size = dwSize;
/* Create the wait event */
TapeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!TapeEvent) return GetLastError();
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_CREATE_PARTITION,
&TapeCreatePartition,
sizeof(TAPE_CREATE_PARTITION),
NULL,
0);
if (!NT_SUCCESS(Status))
/* Send the IOCTL */
Status = NtDeviceIoControlFile(DeviceHandle,
TapeEvent,
0,
0,
&IoStatusBlock,
Ioctl,
Input,
InputLength,
Output,
OutputLength);
if (Status == STATUS_PENDING)
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
/* Wait for its completion */
WaitForSingleObject(TapeEvent, INFINITE);
Status = IoStatusBlock.Status;
}
return ERROR_SUCCESS;
/* Get rid of the wait event and check status */
CloseHandle(TapeEvent);
if (!NT_SUCCESS(Status))
{
/* Convert to Win32 */
BaseSetLastNTError(Status);
ErrorCode = GetLastError();
}
else
{
/* Set sucess */
ErrorCode = ERROR_SUCCESS;
}
/* Return the Win32 error code */
return ErrorCode;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* @implemented
*/
DWORD WINAPI
EraseTape (HANDLE hDevice,
DWORD dwEraseType,
BOOL bImmediate)
DWORD
WINAPI
CreateTapePartition(IN HANDLE hDevice,
IN DWORD dwPartitionMethod,
IN DWORD dwCount,
IN DWORD dwSize)
{
TAPE_ERASE TapeErase;
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TAPE_CREATE_PARTITION TapeCreatePartition;
TapeErase.Type = dwEraseType;
TapeErase.Immediate = (BOOLEAN)bImmediate;
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_ERASE,
&TapeErase,
sizeof(TAPE_ERASE),
NULL,
0);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
TapeCreatePartition.Method = dwPartitionMethod;
TapeCreatePartition.Count = dwCount;
TapeCreatePartition.Size = dwSize;
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_CREATE_PARTITION,
&TapeCreatePartition,
sizeof(TapeCreatePartition),
NULL,
0);
}
/*
* @implemented
*/
DWORD WINAPI
GetTapeParameters (HANDLE hDevice,
DWORD dwOperation,
LPDWORD lpdwSize,
LPVOID lpTapeInformation)
DWORD
WINAPI
EraseTape(IN HANDLE hDevice,
IN DWORD dwEraseType,
IN BOOL bImmediate)
{
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TAPE_ERASE TapeErase;
if (dwOperation == GET_TAPE_MEDIA_INFORMATION)
{
if (*lpdwSize < sizeof(TAPE_GET_MEDIA_PARAMETERS))
{
*lpdwSize = sizeof(TAPE_GET_MEDIA_PARAMETERS);
return ERROR_MORE_DATA;
}
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_GET_MEDIA_PARAMS,
NULL,
0,
lpTapeInformation,
sizeof(TAPE_GET_MEDIA_PARAMETERS));
}
else if (dwOperation == GET_TAPE_DRIVE_INFORMATION)
{
if (*lpdwSize < sizeof(TAPE_GET_DRIVE_PARAMETERS))
{
*lpdwSize = sizeof(TAPE_GET_DRIVE_PARAMETERS);
return ERROR_MORE_DATA;
}
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_GET_DRIVE_PARAMS,
NULL,
0,
lpTapeInformation,
sizeof(TAPE_GET_DRIVE_PARAMETERS));
}
else
{
return ERROR_INVALID_FUNCTION;
}
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
TapeErase.Type = dwEraseType;
TapeErase.Immediate = (BOOLEAN)bImmediate;
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_ERASE,
&TapeErase,
sizeof(TapeErase),
NULL,
0);
}
/*
* @implemented
*/
DWORD WINAPI
GetTapePosition (HANDLE hDevice,
DWORD dwPositionType,
LPDWORD lpdwPartition,
LPDWORD lpdwOffsetLow,
LPDWORD lpdwOffsetHigh)
DWORD
WINAPI
GetTapeParameters(IN HANDLE hDevice,
IN DWORD dwOperation,
IN LPDWORD lpdwSize,
IN LPVOID lpTapeInformation)
{
TAPE_GET_POSITION TapeGetPosition;
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TapeGetPosition.Type = dwPositionType;
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_GET_POSITION,
&TapeGetPosition,
sizeof(TAPE_GET_POSITION),
&TapeGetPosition,
sizeof(TAPE_GET_POSITION));
if (!NT_SUCCESS(Status))
if (dwOperation == GET_TAPE_MEDIA_INFORMATION)
{
*lpdwPartition = 0;
*lpdwOffsetLow = 0;
*lpdwOffsetHigh = 0;
if (*lpdwSize < sizeof(TAPE_GET_MEDIA_PARAMETERS))
{
*lpdwSize = sizeof(TAPE_GET_MEDIA_PARAMETERS);
return ERROR_MORE_DATA;
}
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_GET_MEDIA_PARAMS,
NULL,
0,
lpTapeInformation,
sizeof(TAPE_GET_MEDIA_PARAMETERS));
}
else if (dwOperation == GET_TAPE_DRIVE_INFORMATION)
{
if (*lpdwSize < sizeof(TAPE_GET_DRIVE_PARAMETERS))
{
*lpdwSize = sizeof(TAPE_GET_DRIVE_PARAMETERS);
return ERROR_MORE_DATA;
}
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_GET_DRIVE_PARAMS,
NULL,
0,
lpTapeInformation,
sizeof(TAPE_GET_DRIVE_PARAMETERS));
}
*lpdwPartition = TapeGetPosition.Partition;
*lpdwOffsetLow = TapeGetPosition.Offset.u.LowPart;
*lpdwOffsetHigh = TapeGetPosition.Offset.u.HighPart;
return ERROR_SUCCESS;
return ERROR_INVALID_FUNCTION;
}
/*
* @implemented
*/
DWORD WINAPI
GetTapeStatus (HANDLE hDevice)
DWORD
WINAPI
GetTapePosition(IN HANDLE hDevice,
IN DWORD dwPositionType,
IN LPDWORD lpdwPartition,
IN LPDWORD lpdwOffsetLow,
IN LPDWORD lpdwOffsetHigh)
{
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TAPE_GET_POSITION TapeGetPosition;
DWORD Result;
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_GET_STATUS,
NULL,
0,
NULL,
0);
if (!NT_SUCCESS(Status))
TapeGetPosition.Type = dwPositionType;
Result = BasepDoTapeOperation(hDevice,
IOCTL_TAPE_GET_POSITION,
&TapeGetPosition,
sizeof(TapeGetPosition),
&TapeGetPosition,
sizeof(TapeGetPosition));
if (Result)
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
*lpdwPartition = 0;
*lpdwOffsetLow = 0;
*lpdwOffsetHigh = 0;
}
else
{
*lpdwPartition = TapeGetPosition.Partition;
*lpdwOffsetLow = TapeGetPosition.Offset.u.LowPart;
*lpdwOffsetHigh = TapeGetPosition.Offset.u.HighPart;
}
return ERROR_SUCCESS;
return Result;
}
/*
* @implemented
*/
DWORD WINAPI
PrepareTape (HANDLE hDevice,
DWORD dwOperation,
BOOL bImmediate)
DWORD
WINAPI
GetTapeStatus(IN HANDLE hDevice)
{
TAPE_PREPARE TapePrepare;
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TapePrepare.Operation = dwOperation;
TapePrepare.Immediate = (BOOLEAN)bImmediate;
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_PREPARE,
&TapePrepare,
sizeof(TAPE_PREPARE),
NULL,
0);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_GET_STATUS,
NULL,
0,
NULL,
0);
}
/*
* @implemented
*/
DWORD WINAPI
SetTapeParameters (HANDLE hDevice,
DWORD dwOperation,
LPVOID lpTapeInformation)
DWORD
WINAPI
PrepareTape(IN HANDLE hDevice,
IN DWORD dwOperation,
IN BOOL bImmediate)
{
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TAPE_PREPARE TapePrepare;
if (dwOperation == SET_TAPE_MEDIA_INFORMATION)
{
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_SET_MEDIA_PARAMS,
lpTapeInformation,
sizeof(TAPE_SET_MEDIA_PARAMETERS),
NULL,
0);
}
else if (dwOperation == SET_TAPE_DRIVE_INFORMATION)
{
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_SET_DRIVE_PARAMS,
lpTapeInformation,
sizeof(TAPE_SET_DRIVE_PARAMETERS),
NULL,
0);
}
else
{
return ERROR_INVALID_FUNCTION;
}
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
TapePrepare.Operation = dwOperation;
TapePrepare.Immediate = (BOOLEAN)bImmediate;
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_PREPARE,
&TapePrepare,
sizeof(TapePrepare),
NULL,
0);
}
/*
* @implemented
*/
DWORD WINAPI
SetTapePosition (HANDLE hDevice,
DWORD dwPositionMethod,
DWORD dwPartition,
DWORD dwOffsetLow,
DWORD dwOffsetHigh,
BOOL bImmediate)
DWORD
WINAPI
SetTapeParameters(IN HANDLE hDevice,
IN DWORD dwOperation,
IN LPVOID lpTapeInformation)
{
TAPE_SET_POSITION TapeSetPosition;
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TapeSetPosition.Method = dwPositionMethod;
TapeSetPosition.Partition = dwPartition;
TapeSetPosition.Offset.u.LowPart = dwOffsetLow;
TapeSetPosition.Offset.u.HighPart = dwOffsetHigh;
TapeSetPosition.Immediate = (BOOLEAN)bImmediate;
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_SET_POSITION,
&TapeSetPosition,
sizeof(TAPE_SET_POSITION),
NULL,
0);
if (!NT_SUCCESS(Status))
if (dwOperation == SET_TAPE_MEDIA_INFORMATION)
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_SET_MEDIA_PARAMS,
lpTapeInformation,
sizeof(TAPE_SET_MEDIA_PARAMETERS),
NULL,
0);
}
else if (dwOperation == SET_TAPE_DRIVE_INFORMATION)
{
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_SET_DRIVE_PARAMS,
lpTapeInformation,
sizeof(TAPE_SET_DRIVE_PARAMETERS),
NULL,
0);
}
return ERROR_SUCCESS;
return ERROR_INVALID_FUNCTION;
}
/*
* @implemented
*/
DWORD
WINAPI
SetTapePosition(IN HANDLE hDevice,
IN DWORD dwPositionMethod,
IN DWORD dwPartition,
IN DWORD dwOffsetLow,
IN DWORD dwOffsetHigh,
IN BOOL bImmediate)
{
TAPE_SET_POSITION TapeSetPosition;
TapeSetPosition.Method = dwPositionMethod;
TapeSetPosition.Partition = dwPartition;
TapeSetPosition.Offset.u.LowPart = dwOffsetLow;
TapeSetPosition.Offset.u.HighPart = dwOffsetHigh;
TapeSetPosition.Immediate = (BOOLEAN)bImmediate;
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_SET_POSITION,
&TapeSetPosition,
sizeof(TapeSetPosition),
NULL,
0);
}
/*
* @implemented
*/
DWORD WINAPI
WriteTapemark (HANDLE hDevice,
DWORD dwTapemarkType,
DWORD dwTapemarkCount,
BOOL bImmediate)
DWORD
WINAPI
WriteTapemark(IN HANDLE hDevice,
IN DWORD dwTapemarkType,
IN DWORD dwTapemarkCount,
IN BOOL bImmediate)
{
TAPE_WRITE_MARKS TapeWriteMarks;
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TAPE_WRITE_MARKS TapeWriteMarks;
TapeWriteMarks.Type = dwTapemarkType;
TapeWriteMarks.Count = dwTapemarkCount;
TapeWriteMarks.Immediate = (BOOLEAN)bImmediate;
Status = NtDeviceIoControlFile (hDevice,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TAPE_WRITE_MARKS,
&TapeWriteMarks,
sizeof(TAPE_WRITE_MARKS),
NULL,
0);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError(Status);
SetLastError (ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
TapeWriteMarks.Type = dwTapemarkType;
TapeWriteMarks.Count = dwTapemarkCount;
TapeWriteMarks.Immediate = (BOOLEAN)bImmediate;
return BasepDoTapeOperation(hDevice,
IOCTL_TAPE_WRITE_MARKS,
&TapeWriteMarks,
sizeof(TapeWriteMarks),
NULL,
0);
}
/* EOF */

View file

@ -15,12 +15,13 @@
/* GLOBALS ********************************************************************/
UNICODE_STRING BaseDllDirectory;
UNICODE_STRING NoDefaultCurrentDirectoryInExePath = RTL_CONSTANT_STRING(L"NoDefaultCurrentDirectoryInExePath");
UNICODE_STRING SystemDirectory;
UNICODE_STRING WindowsDirectory;
UNICODE_STRING BaseDefaultPathAppend;
UNICODE_STRING BaseDefaultPath;
UNICODE_STRING BaseWindowsSystemDirectory, BaseWindowsDirectory;
UNICODE_STRING BaseDefaultPathAppend, BaseDefaultPath, BaseDllDirectory;
PVOID gpTermsrvGetWindowsDirectoryA;
PVOID gpTermsrvGetWindowsDirectoryW;
/* This is bitmask for each illegal filename character */
/* If someone has time, please feel free to use 0b notation */
@ -34,6 +35,41 @@ DWORD IllegalMask[4] =
/* PRIVATE FUNCTIONS **********************************************************/
BOOLEAN
WINAPI
CheckForSameCurdir(IN PUNICODE_STRING DirName)
{
PUNICODE_STRING CurDir;
USHORT CurLength;
BOOLEAN Result;
UNICODE_STRING CurDirCopy;
CurDir = &NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath;
CurLength = CurDir->Length;
if (CurDir->Length <= 6)
{
if (CurLength != DirName->Length) return FALSE;
}
else
{
if ((CurLength - 2) != DirName->Length) return FALSE;
}
RtlAcquirePebLock();
CurDirCopy = *CurDir;
if (CurDirCopy.Length > 6) CurDirCopy.Length -= 2;
Result = 0;
if (RtlEqualUnicodeString(&CurDirCopy, DirName, TRUE)) Result = TRUE;
RtlReleasePebLock();
return Result;
}
/*
* Why not use RtlIsNameLegalDOS8Dot3? In fact the actual algorithm body is
* identical (other than the Rtl can optionally check for spaces), however the
@ -790,7 +826,6 @@ ContainsPath(LPCWSTR name)
return (name[1] == '.' && (name[2] == '/' || name[2] == '\\'));
}
/*
* @implemented
*/
@ -1476,81 +1511,6 @@ Quickie:
return ReturnLength;
}
/*
* @implemented
*/
DWORD
WINAPI
GetCurrentDirectoryA(IN DWORD nBufferLength,
IN LPSTR lpBuffer)
{
WCHAR BufferW[MAX_PATH];
DWORD ret;
ret = GetCurrentDirectoryW(MAX_PATH, BufferW);
if (!ret) return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
return FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
}
/*
* @implemented
*/
DWORD
WINAPI
GetCurrentDirectoryW(IN DWORD nBufferLength,
IN LPWSTR lpBuffer)
{
ULONG Length;
Length = RtlGetCurrentDirectory_U (nBufferLength * sizeof(WCHAR), lpBuffer);
return (Length / sizeof (WCHAR));
}
/*
* @implemented
*/
BOOL
WINAPI
SetCurrentDirectoryA(IN LPCSTR lpPathName)
{
PWCHAR PathNameW;
DPRINT("setcurrdir: %s\n",lpPathName);
if (!(PathNameW = FilenameA2W(lpPathName, FALSE))) return FALSE;
return SetCurrentDirectoryW(PathNameW);
}
/*
* @implemented
*/
BOOL
WINAPI
SetCurrentDirectoryW(IN LPCWSTR lpPathName)
{
UNICODE_STRING UnicodeString;
NTSTATUS Status;
RtlInitUnicodeString(&UnicodeString, lpPathName);
Status = RtlSetCurrentDirectory_U(&UnicodeString);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError (Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*
@ -1637,6 +1597,143 @@ GetTempPathW(IN DWORD count,
return ret;
}
/*
* @implemented
*/
DWORD
WINAPI
GetCurrentDirectoryA(IN DWORD nBufferLength,
IN LPSTR lpBuffer)
{
ANSI_STRING AnsiString;
NTSTATUS Status;
PUNICODE_STRING StaticString;
ULONG MaxLength;
StaticString = &NtCurrentTeb()->StaticUnicodeString;
MaxLength = nBufferLength;
if (nBufferLength >= UNICODE_STRING_MAX_BYTES)
{
MaxLength = UNICODE_STRING_MAX_BYTES - 1;
}
StaticString->Length = RtlGetCurrentDirectory_U(StaticString->MaximumLength,
StaticString->Buffer);
Status = RtlUnicodeToMultiByteSize(&nBufferLength,
StaticString->Buffer,
StaticString->Length);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return 0;
}
if (MaxLength <= nBufferLength)
{
return nBufferLength + 1;
}
AnsiString.Buffer = lpBuffer;
AnsiString.MaximumLength = MaxLength;
Status = BasepUnicodeStringTo8BitString(&AnsiString, StaticString, FALSE);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return 0;
}
return AnsiString.Length;
}
/*
* @implemented
*/
DWORD
WINAPI
GetCurrentDirectoryW(IN DWORD nBufferLength,
IN LPWSTR lpBuffer)
{
return RtlGetCurrentDirectory_U(nBufferLength * sizeof(WCHAR), lpBuffer) / sizeof(WCHAR);
}
/*
* @implemented
*/
BOOL
WINAPI
SetCurrentDirectoryA(IN LPCSTR lpPathName)
{
PUNICODE_STRING DirName;
NTSTATUS Status;
if (!lpPathName)
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return FALSE;
}
DirName = Basep8BitStringToStaticUnicodeString(lpPathName);
if (!DirName) return FALSE;
if (CheckForSameCurdir(DirName)) return FALSE;
Status = RtlSetCurrentDirectory_U(DirName);
if (NT_SUCCESS(Status)) return TRUE;
if ((*DirName->Buffer != L'"') || (DirName->Length <= 2))
{
BaseSetLastNTError(Status);
return 0;
}
DirName = Basep8BitStringToStaticUnicodeString(lpPathName + 1);
if (!DirName) return FALSE;
Status = RtlSetCurrentDirectory_U(DirName);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL
WINAPI
SetCurrentDirectoryW(IN LPCWSTR lpPathName)
{
NTSTATUS Status;
UNICODE_STRING UnicodeString;
if (!lpPathName)
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return FALSE;
}
Status = RtlInitUnicodeStringEx(&UnicodeString, lpPathName);
if (NT_SUCCESS(Status))
{
if (!CheckForSameCurdir(&UnicodeString))
{
Status = RtlSetCurrentDirectory_U(&UnicodeString);
}
}
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
@ -1645,7 +1742,26 @@ WINAPI
GetSystemDirectoryA(IN LPSTR lpBuffer,
IN UINT uSize)
{
return FilenameU2A_FitOrFail(lpBuffer, uSize, &SystemDirectory);
ANSI_STRING AnsiString;
NTSTATUS Status;
ULONG AnsiLength;
/* Get the correct size of the Unicode Base directory */
Status = RtlUnicodeToMultiByteSize(&AnsiLength,
BaseWindowsSystemDirectory.Buffer,
BaseWindowsSystemDirectory.MaximumLength);
if (!NT_SUCCESS(Status)) return 0;
if (uSize < AnsiLength) return AnsiLength;
RtlInitEmptyAnsiString(&AnsiString, lpBuffer, uSize);
Status = BasepUnicodeStringTo8BitString(&AnsiString,
&BaseWindowsSystemDirectory,
FALSE);
if (!NT_SUCCESS(Status)) return 0;
return AnsiString.Length;
}
/*
@ -1656,21 +1772,20 @@ WINAPI
GetSystemDirectoryW(IN LPWSTR lpBuffer,
IN UINT uSize)
{
ULONG Length;
ULONG ReturnLength;
Length = SystemDirectory.Length / sizeof (WCHAR);
if (lpBuffer == NULL) return Length + 1;
if (uSize > Length)
ReturnLength = BaseWindowsSystemDirectory.MaximumLength;
if ((uSize * sizeof(WCHAR)) >= ReturnLength)
{
memmove(lpBuffer, SystemDirectory.Buffer, SystemDirectory.Length);
lpBuffer[Length] = 0;
RtlCopyMemory(lpBuffer,
BaseWindowsSystemDirectory.Buffer,
BaseWindowsSystemDirectory.Length);
lpBuffer[BaseWindowsSystemDirectory.Length / sizeof(WCHAR)] = ANSI_NULL;
return Length; //good: ret chars excl. nullchar
ReturnLength = BaseWindowsSystemDirectory.Length;
}
return Length+1; //bad: ret space needed incl. nullchar
return ReturnLength / sizeof(WCHAR);
}
/*
@ -1681,7 +1796,11 @@ WINAPI
GetWindowsDirectoryA(IN LPSTR lpBuffer,
IN UINT uSize)
{
return FilenameU2A_FitOrFail(lpBuffer, uSize, &WindowsDirectory);
/* Is this a TS installation? */
if (gpTermsrvGetWindowsDirectoryA) UNIMPLEMENTED;
/* Otherwise, call the System API */
return GetSystemWindowsDirectoryA(lpBuffer, uSize);
}
/*
@ -1692,21 +1811,11 @@ WINAPI
GetWindowsDirectoryW(IN LPWSTR lpBuffer,
IN UINT uSize)
{
ULONG Length;
/* Is this a TS installation? */
if (gpTermsrvGetWindowsDirectoryW) UNIMPLEMENTED;
Length = WindowsDirectory.Length / sizeof (WCHAR);
if (lpBuffer == NULL) return Length + 1;
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
/* Otherwise, call the System API */
return GetSystemWindowsDirectoryW(lpBuffer, uSize);
}
/*
@ -1717,7 +1826,26 @@ WINAPI
GetSystemWindowsDirectoryA(IN LPSTR lpBuffer,
IN UINT uSize)
{
return GetWindowsDirectoryA(lpBuffer, uSize);
ANSI_STRING AnsiString;
NTSTATUS Status;
ULONG AnsiLength;
/* Get the correct size of the Unicode Base directory */
Status = RtlUnicodeToMultiByteSize(&AnsiLength,
BaseWindowsDirectory.Buffer,
BaseWindowsDirectory.MaximumLength);
if (!NT_SUCCESS(Status)) return 0;
if (uSize < AnsiLength) return AnsiLength;
RtlInitEmptyAnsiString(&AnsiString, lpBuffer, uSize);
Status = BasepUnicodeStringTo8BitString(&AnsiString,
&BaseWindowsDirectory,
FALSE);
if (!NT_SUCCESS(Status)) return 0;
return AnsiString.Length;
}
/*
@ -1728,7 +1856,20 @@ WINAPI
GetSystemWindowsDirectoryW(IN LPWSTR lpBuffer,
IN UINT uSize)
{
return GetWindowsDirectoryW(lpBuffer, uSize);
ULONG ReturnLength;
ReturnLength = BaseWindowsDirectory.MaximumLength;
if ((uSize * sizeof(WCHAR)) >= ReturnLength)
{
RtlCopyMemory(lpBuffer,
BaseWindowsDirectory.Buffer,
BaseWindowsDirectory.Length);
lpBuffer[BaseWindowsDirectory.Length / sizeof(WCHAR)] = ANSI_NULL;
ReturnLength = BaseWindowsDirectory.Length;
}
return ReturnLength / sizeof(WCHAR);
}
/*

View file

@ -12,8 +12,68 @@
#define NDEBUG
#include <debug.h>
#undef InterlockedIncrement
#undef InterlockedDecrement
#undef InterlockedExchange
#undef InterlockedExchangeAdd
#undef InterlockedCompareExchange
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
LONG
WINAPI
InterlockedIncrement(IN OUT LONG volatile *lpAddend)
{
return _InterlockedIncrement(lpAddend);
}
/*
* @implemented
*/
LONG
WINAPI
InterlockedDecrement(IN OUT LONG volatile *lpAddend)
{
return _InterlockedDecrement(lpAddend);
}
/*
* @implemented
*/
LONG
WINAPI
InterlockedExchange(IN OUT LONG volatile *Target,
IN LONG Value)
{
return _InterlockedExchange(Target, Value);
}
/*
* @implemented
*/
LONG
WINAPI
InterlockedExchangeAdd(IN OUT LONG volatile *Addend,
IN LONG Value)
{
return _InterlockedExchangeAdd(Addend, Value);
}
/*
* @implemented
*/
LONG
WINAPI
InterlockedCompareExchange(IN OUT LONG volatile *Destination,
IN LONG Exchange,
IN LONG Comperand)
{
return _InterlockedCompareExchange(Destination, Exchange, Comperand);
}
/*
* @implemented
*/

View file

@ -258,6 +258,7 @@ extern PRTL_CONVERT_STRINGA BasepUnicodeStringTo8BitString;
extern PRTL_COUNT_STRING BasepUnicodeStringTo8BitSize;
extern PRTL_COUNT_STRINGA Basep8BitStringToUnicodeSize;
extern UNICODE_STRING BaseWindowsDirectory, BaseWindowsSystemDirectory;
extern HANDLE BaseNamedObjectDirectory;
HANDLE