[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 *******************************************************************/ /* GLOBALS *******************************************************************/
extern UNICODE_STRING SystemDirectory;
extern UNICODE_STRING WindowsDirectory;
PBASE_STATIC_SERVER_DATA BaseStaticServerData; PBASE_STATIC_SERVER_DATA BaseStaticServerData;
BOOLEAN BaseRunningInServerProcess; BOOLEAN BaseRunningInServerProcess;
@ -34,7 +31,6 @@ HMODULE kernel32_handle = NULL;
PPEB Peb; PPEB Peb;
ULONG SessionId; ULONG SessionId;
BOOL ConsoleInitialized = FALSE; BOOL ConsoleInitialized = FALSE;
UNICODE_STRING BaseWindowsDirectory, BaseWindowsSystemDirectory;
static BOOL DllInitialized = FALSE; static BOOL DllInitialized = FALSE;
BOOL WINAPI BOOL WINAPI
@ -271,12 +267,10 @@ DllMain(HANDLE hDll,
/* Set the directories */ /* Set the directories */
BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory; BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory;
BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory; BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory;
SystemDirectory = BaseWindowsSystemDirectory;
WindowsDirectory = BaseWindowsDirectory;
/* Construct the default path (using the static buffer) */ /* Construct the default path (using the static buffer) */
_snwprintf(BaseDefaultPathBuffer, sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR), _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.Buffer = BaseDefaultPathBuffer;
BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR); BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR);
@ -337,50 +331,4 @@ DllMain(HANDLE hDll,
return TRUE; 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 */ /* EOF */

View file

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

View file

@ -15,12 +15,13 @@
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
UNICODE_STRING BaseDllDirectory;
UNICODE_STRING NoDefaultCurrentDirectoryInExePath = RTL_CONSTANT_STRING(L"NoDefaultCurrentDirectoryInExePath"); UNICODE_STRING NoDefaultCurrentDirectoryInExePath = RTL_CONSTANT_STRING(L"NoDefaultCurrentDirectoryInExePath");
UNICODE_STRING SystemDirectory;
UNICODE_STRING WindowsDirectory; UNICODE_STRING BaseWindowsSystemDirectory, BaseWindowsDirectory;
UNICODE_STRING BaseDefaultPathAppend; UNICODE_STRING BaseDefaultPathAppend, BaseDefaultPath, BaseDllDirectory;
UNICODE_STRING BaseDefaultPath;
PVOID gpTermsrvGetWindowsDirectoryA;
PVOID gpTermsrvGetWindowsDirectoryW;
/* This is bitmask for each illegal filename character */ /* This is bitmask for each illegal filename character */
/* If someone has time, please feel free to use 0b notation */ /* If someone has time, please feel free to use 0b notation */
@ -34,6 +35,41 @@ DWORD IllegalMask[4] =
/* PRIVATE FUNCTIONS **********************************************************/ /* 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 * Why not use RtlIsNameLegalDOS8Dot3? In fact the actual algorithm body is
* identical (other than the Rtl can optionally check for spaces), however the * 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] == '\\')); return (name[1] == '.' && (name[2] == '/' || name[2] == '\\'));
} }
/* /*
* @implemented * @implemented
*/ */
@ -1476,81 +1511,6 @@ Quickie:
return ReturnLength; 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 * @implemented
* *
@ -1637,6 +1597,143 @@ GetTempPathW(IN DWORD count,
return ret; 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 * @implemented
*/ */
@ -1645,7 +1742,26 @@ WINAPI
GetSystemDirectoryA(IN LPSTR lpBuffer, GetSystemDirectoryA(IN LPSTR lpBuffer,
IN UINT uSize) 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, GetSystemDirectoryW(IN LPWSTR lpBuffer,
IN UINT uSize) IN UINT uSize)
{ {
ULONG Length; ULONG ReturnLength;
Length = SystemDirectory.Length / sizeof (WCHAR); ReturnLength = BaseWindowsSystemDirectory.MaximumLength;
if ((uSize * sizeof(WCHAR)) >= ReturnLength)
if (lpBuffer == NULL) return Length + 1;
if (uSize > Length)
{ {
memmove(lpBuffer, SystemDirectory.Buffer, SystemDirectory.Length); RtlCopyMemory(lpBuffer,
lpBuffer[Length] = 0; 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, GetWindowsDirectoryA(IN LPSTR lpBuffer,
IN UINT uSize) 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, GetWindowsDirectoryW(IN LPWSTR lpBuffer,
IN UINT uSize) IN UINT uSize)
{ {
ULONG Length; /* Is this a TS installation? */
if (gpTermsrvGetWindowsDirectoryW) UNIMPLEMENTED;
Length = WindowsDirectory.Length / sizeof (WCHAR); /* Otherwise, call the System API */
return GetSystemWindowsDirectoryW(lpBuffer, uSize);
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
} }
/* /*
@ -1717,7 +1826,26 @@ WINAPI
GetSystemWindowsDirectoryA(IN LPSTR lpBuffer, GetSystemWindowsDirectoryA(IN LPSTR lpBuffer,
IN UINT uSize) 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, GetSystemWindowsDirectoryW(IN LPWSTR lpBuffer,
IN UINT uSize) 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 #define NDEBUG
#include <debug.h> #include <debug.h>
#undef InterlockedIncrement
#undef InterlockedDecrement
#undef InterlockedExchange
#undef InterlockedExchangeAdd
#undef InterlockedCompareExchange
/* FUNCTIONS *****************************************************************/ /* 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 * @implemented
*/ */

View file

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