[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,404 +9,311 @@
* 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
* @implemented WINAPI
*/ BasepDoTapeOperation(IN HANDLE DeviceHandle,
DWORD WINAPI IN ULONG Ioctl,
CreateTapePartition (HANDLE hDevice, IN PVOID Input,
DWORD dwPartitionMethod, IN ULONG InputLength,
DWORD dwCount, IN PVOID Output,
DWORD dwSize) IN ULONG OutputLength)
{ {
TAPE_CREATE_PARTITION TapeCreatePartition; HANDLE TapeEvent;
IO_STATUS_BLOCK IoStatusBlock; DWORD ErrorCode;
DWORD ErrorCode; NTSTATUS Status;
NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock;
TapeCreatePartition.Method = dwPartitionMethod; /* Create the wait event */
TapeCreatePartition.Count = dwCount; TapeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
TapeCreatePartition.Size = dwSize; if (!TapeEvent) return GetLastError();
Status = NtDeviceIoControlFile (hDevice, /* Send the IOCTL */
NULL, Status = NtDeviceIoControlFile(DeviceHandle,
NULL, TapeEvent,
NULL, 0,
&IoStatusBlock, 0,
IOCTL_TAPE_CREATE_PARTITION, &IoStatusBlock,
&TapeCreatePartition, Ioctl,
sizeof(TAPE_CREATE_PARTITION), Input,
NULL, InputLength,
0); Output,
if (!NT_SUCCESS(Status)) OutputLength);
if (Status == STATUS_PENDING)
{ {
ErrorCode = RtlNtStatusToDosError(Status); /* Wait for its completion */
SetLastError (ErrorCode); WaitForSingleObject(TapeEvent, INFINITE);
return ErrorCode; 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 * @implemented
*/ */
DWORD WINAPI DWORD
EraseTape (HANDLE hDevice, WINAPI
DWORD dwEraseType, CreateTapePartition(IN HANDLE hDevice,
BOOL bImmediate) IN DWORD dwPartitionMethod,
IN DWORD dwCount,
IN DWORD dwSize)
{ {
TAPE_ERASE TapeErase; TAPE_CREATE_PARTITION TapeCreatePartition;
IO_STATUS_BLOCK IoStatusBlock;
DWORD ErrorCode;
NTSTATUS Status;
TapeErase.Type = dwEraseType; TapeCreatePartition.Method = dwPartitionMethod;
TapeErase.Immediate = (BOOLEAN)bImmediate; TapeCreatePartition.Count = dwCount;
TapeCreatePartition.Size = dwSize;
Status = NtDeviceIoControlFile (hDevice, return BasepDoTapeOperation(hDevice,
NULL, IOCTL_TAPE_CREATE_PARTITION,
NULL, &TapeCreatePartition,
NULL, sizeof(TapeCreatePartition),
&IoStatusBlock, NULL,
IOCTL_TAPE_ERASE, 0);
&TapeErase,
sizeof(TAPE_ERASE),
NULL,
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, EraseTape(IN HANDLE hDevice,
LPDWORD lpdwSize, IN DWORD dwEraseType,
LPVOID lpTapeInformation) IN BOOL bImmediate)
{ {
IO_STATUS_BLOCK IoStatusBlock; TAPE_ERASE TapeErase;
DWORD ErrorCode;
NTSTATUS Status;
if (dwOperation == GET_TAPE_MEDIA_INFORMATION) TapeErase.Type = dwEraseType;
{ TapeErase.Immediate = (BOOLEAN)bImmediate;
if (*lpdwSize < sizeof(TAPE_GET_MEDIA_PARAMETERS)) return BasepDoTapeOperation(hDevice,
{ IOCTL_TAPE_ERASE,
*lpdwSize = sizeof(TAPE_GET_MEDIA_PARAMETERS); &TapeErase,
return ERROR_MORE_DATA; sizeof(TapeErase),
} NULL,
0);
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;
} }
/* /*
* @implemented * @implemented
*/ */
DWORD WINAPI DWORD
GetTapePosition (HANDLE hDevice, WINAPI
DWORD dwPositionType, GetTapeParameters(IN HANDLE hDevice,
LPDWORD lpdwPartition, IN DWORD dwOperation,
LPDWORD lpdwOffsetLow, IN LPDWORD lpdwSize,
LPDWORD lpdwOffsetHigh) IN LPVOID lpTapeInformation)
{ {
TAPE_GET_POSITION TapeGetPosition; if (dwOperation == GET_TAPE_MEDIA_INFORMATION)
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))
{ {
*lpdwPartition = 0; if (*lpdwSize < sizeof(TAPE_GET_MEDIA_PARAMETERS))
*lpdwOffsetLow = 0; {
*lpdwOffsetHigh = 0; *lpdwSize = sizeof(TAPE_GET_MEDIA_PARAMETERS);
return ERROR_MORE_DATA;
}
ErrorCode = RtlNtStatusToDosError(Status); return BasepDoTapeOperation(hDevice,
SetLastError (ErrorCode); IOCTL_TAPE_GET_MEDIA_PARAMS,
return ErrorCode; 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; return ERROR_INVALID_FUNCTION;
*lpdwOffsetLow = TapeGetPosition.Offset.u.LowPart;
*lpdwOffsetHigh = TapeGetPosition.Offset.u.HighPart;
return ERROR_SUCCESS;
} }
/* /*
* @implemented * @implemented
*/ */
DWORD WINAPI DWORD
GetTapeStatus (HANDLE hDevice) WINAPI
GetTapePosition(IN HANDLE hDevice,
IN DWORD dwPositionType,
IN LPDWORD lpdwPartition,
IN LPDWORD lpdwOffsetLow,
IN LPDWORD lpdwOffsetHigh)
{ {
IO_STATUS_BLOCK IoStatusBlock; TAPE_GET_POSITION TapeGetPosition;
DWORD ErrorCode; DWORD Result;
NTSTATUS Status;
Status = NtDeviceIoControlFile (hDevice, TapeGetPosition.Type = dwPositionType;
NULL, Result = BasepDoTapeOperation(hDevice,
NULL, IOCTL_TAPE_GET_POSITION,
NULL, &TapeGetPosition,
&IoStatusBlock, sizeof(TapeGetPosition),
IOCTL_TAPE_GET_STATUS, &TapeGetPosition,
NULL, sizeof(TapeGetPosition));
0,
NULL, if (Result)
0);
if (!NT_SUCCESS(Status))
{ {
ErrorCode = RtlNtStatusToDosError(Status); *lpdwPartition = 0;
SetLastError (ErrorCode); *lpdwOffsetLow = 0;
return ErrorCode; *lpdwOffsetHigh = 0;
}
else
{
*lpdwPartition = TapeGetPosition.Partition;
*lpdwOffsetLow = TapeGetPosition.Offset.u.LowPart;
*lpdwOffsetHigh = TapeGetPosition.Offset.u.HighPart;
} }
return ERROR_SUCCESS; return Result;
} }
/* /*
* @implemented * @implemented
*/ */
DWORD WINAPI DWORD
PrepareTape (HANDLE hDevice, WINAPI
DWORD dwOperation, GetTapeStatus(IN HANDLE hDevice)
BOOL bImmediate)
{ {
TAPE_PREPARE TapePrepare; return BasepDoTapeOperation(hDevice,
IO_STATUS_BLOCK IoStatusBlock; IOCTL_TAPE_GET_STATUS,
DWORD ErrorCode; NULL,
NTSTATUS Status; 0,
NULL,
TapePrepare.Operation = dwOperation; 0);
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;
} }
/* /*
* @implemented * @implemented
*/ */
DWORD WINAPI DWORD
SetTapeParameters (HANDLE hDevice, WINAPI
DWORD dwOperation, PrepareTape(IN HANDLE hDevice,
LPVOID lpTapeInformation) IN DWORD dwOperation,
IN BOOL bImmediate)
{ {
IO_STATUS_BLOCK IoStatusBlock; TAPE_PREPARE TapePrepare;
DWORD ErrorCode;
NTSTATUS Status;
if (dwOperation == SET_TAPE_MEDIA_INFORMATION) TapePrepare.Operation = dwOperation;
{ TapePrepare.Immediate = (BOOLEAN)bImmediate;
Status = NtDeviceIoControlFile (hDevice, return BasepDoTapeOperation(hDevice,
NULL, IOCTL_TAPE_PREPARE,
NULL, &TapePrepare,
NULL, sizeof(TapePrepare),
&IoStatusBlock, NULL,
IOCTL_TAPE_SET_MEDIA_PARAMS, 0);
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;
} }
/* /*
* @implemented * @implemented
*/ */
DWORD WINAPI DWORD
SetTapePosition (HANDLE hDevice, WINAPI
DWORD dwPositionMethod, SetTapeParameters(IN HANDLE hDevice,
DWORD dwPartition, IN DWORD dwOperation,
DWORD dwOffsetLow, IN LPVOID lpTapeInformation)
DWORD dwOffsetHigh,
BOOL bImmediate)
{ {
TAPE_SET_POSITION TapeSetPosition; if (dwOperation == SET_TAPE_MEDIA_INFORMATION)
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))
{ {
ErrorCode = RtlNtStatusToDosError(Status); return BasepDoTapeOperation(hDevice,
SetLastError (ErrorCode); IOCTL_TAPE_SET_MEDIA_PARAMS,
return ErrorCode; 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 * @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, IOCTL_TAPE_WRITE_MARKS,
NULL, &TapeWriteMarks,
NULL, sizeof(TapeWriteMarks),
NULL, NULL,
&IoStatusBlock, 0);
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;
} }
/* 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