mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[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:
parent
b7ad8c6fb9
commit
40b0836010
5 changed files with 540 additions and 483 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue