mirror of
https://github.com/reactos/reactos.git
synced 2024-08-20 02:13:29 +00:00
892 lines
22 KiB
C
892 lines
22 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS system libraries
|
|
* PURPOSE: Vista functions
|
|
* PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include <k32.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
#if _WIN32_WINNT >= 0x600
|
|
|
|
/* FIXME: Move these RTL declarations to the NDK */
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
|
|
IN OUT PRTL_CRITICAL_SECTION CriticalSection,
|
|
IN PLARGE_INTEGER TimeOut OPTIONAL);
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
|
|
IN OUT PRTL_SRWLOCK SRWLock,
|
|
IN PLARGE_INTEGER TimeOut OPTIONAL,
|
|
IN ULONG Flags);
|
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
SleepConditionVariableCS(IN OUT PCONDITION_VARIABLE ConditionVariable,
|
|
IN OUT PCRITICAL_SECTION CriticalSection,
|
|
IN DWORD dwMilliseconds)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
#if 0
|
|
LARGE_INTEGER TimeOut;
|
|
PLARGE_INTEGER TimeOutPtr = NULL;
|
|
|
|
if (dwMilliseconds != INFINITE)
|
|
{
|
|
TimeOut.QuadPart = dwMilliseconds * -10000LL;
|
|
TimeOutPtr = &TimeOut;
|
|
}
|
|
|
|
Status = RtlSleepConditionVariableCS((PRTL_CONDITION_VARIABLE)ConditionVariable,
|
|
(PRTL_CRITICAL_SECTION)CriticalSection,
|
|
TimeOutPtr);
|
|
#endif
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
SleepConditionVariableSRW(IN OUT PCONDITION_VARIABLE ConditionVariable,
|
|
IN OUT PSRWLOCK SRWLock,
|
|
IN DWORD dwMilliseconds,
|
|
IN ULONG Flags)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
#if 0
|
|
LARGE_INTEGER TimeOut;
|
|
PLARGE_INTEGER TimeOutPtr = NULL;
|
|
|
|
if (dwMilliseconds != INFINITE)
|
|
{
|
|
TimeOut.QuadPart = dwMilliseconds * -10000LL;
|
|
TimeOutPtr = &TimeOut;
|
|
}
|
|
|
|
Status = RtlSleepConditionVariableSRW((PRTL_CONDITION_VARIABLE)ConditionVariable,
|
|
(PRTL_SRWLOCK)SRWLock,
|
|
TimeOutPtr,
|
|
Flags);
|
|
#endif
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection,
|
|
IN DWORD dwSpinCount,
|
|
IN DWORD flags)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
/* FIXME: Flags ignored */
|
|
|
|
/* Initialize the critical section */
|
|
Status = RtlInitializeCriticalSectionAndSpinCount(
|
|
(PRTL_CRITICAL_SECTION)lpCriticalSection,
|
|
dwSpinCount);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* Set failure code */
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Success */
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
QueryFullProcessImageNameW(HANDLE hProcess,
|
|
DWORD dwFlags,
|
|
LPWSTR lpExeName,
|
|
PDWORD pdwSize)
|
|
{
|
|
BYTE Buffer[sizeof(UNICODE_STRING) + MAX_PATH * sizeof(WCHAR)];
|
|
UNICODE_STRING *DynamicBuffer = NULL;
|
|
UNICODE_STRING *Result = NULL;
|
|
NTSTATUS Status;
|
|
DWORD Needed;
|
|
|
|
Status = NtQueryInformationProcess(hProcess,
|
|
ProcessImageFileName,
|
|
Buffer,
|
|
sizeof(Buffer) - sizeof(WCHAR),
|
|
&Needed);
|
|
if (Status == STATUS_INFO_LENGTH_MISMATCH)
|
|
{
|
|
DynamicBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Needed + sizeof(WCHAR));
|
|
if (!DynamicBuffer)
|
|
{
|
|
BaseSetLastNTError(STATUS_NO_MEMORY);
|
|
return FALSE;
|
|
}
|
|
|
|
Status = NtQueryInformationProcess(hProcess,
|
|
ProcessImageFileName,
|
|
(LPBYTE)DynamicBuffer,
|
|
Needed,
|
|
&Needed);
|
|
Result = DynamicBuffer;
|
|
}
|
|
else Result = (PUNICODE_STRING)Buffer;
|
|
|
|
if (!NT_SUCCESS(Status)) goto Cleanup;
|
|
|
|
if (Result->Length / sizeof(WCHAR) + 1 > *pdwSize)
|
|
{
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
*pdwSize = Result->Length / sizeof(WCHAR);
|
|
memcpy(lpExeName, Result->Buffer, Result->Length);
|
|
lpExeName[*pdwSize] = 0;
|
|
|
|
Cleanup:
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, DynamicBuffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
BaseSetLastNTError(Status);
|
|
}
|
|
|
|
return !Status;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
QueryFullProcessImageNameA(HANDLE hProcess,
|
|
DWORD dwFlags,
|
|
LPSTR lpExeName,
|
|
PDWORD pdwSize)
|
|
{
|
|
DWORD pdwSizeW = *pdwSize;
|
|
BOOL Result;
|
|
LPWSTR lpExeNameW;
|
|
|
|
lpExeNameW = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
*pdwSize * sizeof(WCHAR));
|
|
if (!lpExeNameW)
|
|
{
|
|
BaseSetLastNTError(STATUS_NO_MEMORY);
|
|
return FALSE;
|
|
}
|
|
|
|
Result = QueryFullProcessImageNameW(hProcess, dwFlags, lpExeNameW, &pdwSizeW);
|
|
|
|
if (Result)
|
|
Result = (0 != WideCharToMultiByte(CP_ACP, 0,
|
|
lpExeNameW,
|
|
-1,
|
|
lpExeName,
|
|
*pdwSize,
|
|
NULL, NULL));
|
|
|
|
if (Result)
|
|
*pdwSize = strlen(lpExeName);
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW);
|
|
return Result;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
HRESULT
|
|
WINAPI
|
|
GetApplicationRecoveryCallback(IN HANDLE hProcess,
|
|
OUT APPLICATION_RECOVERY_CALLBACK* pRecoveryCallback,
|
|
OUT PVOID* ppvParameter,
|
|
PDWORD dwPingInterval,
|
|
PDWORD dwFlags)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
HRESULT
|
|
WINAPI
|
|
GetApplicationRestart(IN HANDLE hProcess,
|
|
OUT PWSTR pwzCommandline OPTIONAL,
|
|
IN OUT PDWORD pcchSize,
|
|
OUT PDWORD pdwFlags OPTIONAL)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
VOID
|
|
WINAPI
|
|
RecoveryFinished(IN BOOL bSuccess)
|
|
{
|
|
UNIMPLEMENTED;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
HRESULT
|
|
WINAPI
|
|
RecoveryInProgress(OUT PBOOL pbCancelled)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
HRESULT
|
|
WINAPI
|
|
RegisterApplicationRecoveryCallback(IN APPLICATION_RECOVERY_CALLBACK pRecoveryCallback,
|
|
IN PVOID pvParameter OPTIONAL,
|
|
DWORD dwPingInterval,
|
|
DWORD dwFlags)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
HRESULT
|
|
WINAPI
|
|
RegisterApplicationRestart(IN PCWSTR pwzCommandline OPTIONAL,
|
|
IN DWORD dwFlags)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOLEAN
|
|
WINAPI
|
|
CreateSymbolicLinkW(IN LPCWSTR lpSymlinkFileName,
|
|
IN LPCWSTR lpTargetFileName,
|
|
IN DWORD dwFlags)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE hSymlink = NULL;
|
|
UNICODE_STRING SymlinkFileName = { 0, 0, NULL };
|
|
UNICODE_STRING TargetFileName = { 0, 0, NULL };
|
|
BOOLEAN bAllocatedTarget = FALSE, bRelativePath = FALSE;
|
|
LPWSTR lpTargetFullFileName = NULL;
|
|
SIZE_T cbPrintName;
|
|
SIZE_T cbReparseData;
|
|
PREPARSE_DATA_BUFFER pReparseData = NULL;
|
|
PBYTE pBufTail;
|
|
NTSTATUS Status;
|
|
ULONG dwCreateOptions;
|
|
DWORD dwErr;
|
|
|
|
if(!lpSymlinkFileName || !lpTargetFileName || (dwFlags | SYMBOLIC_LINK_FLAG_DIRECTORY) != SYMBOLIC_LINK_FLAG_DIRECTORY)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
if(dwFlags & SYMBOLIC_LINK_FLAG_DIRECTORY)
|
|
dwCreateOptions = FILE_DIRECTORY_FILE;
|
|
else
|
|
dwCreateOptions = FILE_NON_DIRECTORY_FILE;
|
|
|
|
switch(RtlDetermineDosPathNameType_U(lpTargetFileName))
|
|
{
|
|
case RtlPathTypeUnknown:
|
|
case RtlPathTypeRooted:
|
|
case RtlPathTypeRelative:
|
|
bRelativePath = TRUE;
|
|
RtlInitUnicodeString(&TargetFileName, lpTargetFileName);
|
|
break;
|
|
|
|
case RtlPathTypeDriveRelative:
|
|
{
|
|
LPWSTR FilePart;
|
|
SIZE_T cchTargetFullFileName;
|
|
|
|
cchTargetFullFileName = GetFullPathNameW(lpTargetFileName, 0, NULL, &FilePart);
|
|
|
|
if(cchTargetFullFileName == 0)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto Cleanup;
|
|
}
|
|
|
|
lpTargetFullFileName = RtlAllocateHeap(RtlGetProcessHeap(), 0, cchTargetFullFileName * sizeof(WCHAR));
|
|
|
|
if(lpTargetFullFileName == NULL)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
if(GetFullPathNameW(lpTargetFileName, cchTargetFullFileName, lpTargetFullFileName, &FilePart) == 0)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
lpTargetFileName = lpTargetFullFileName;
|
|
|
|
// fallthrough
|
|
|
|
case RtlPathTypeUncAbsolute:
|
|
case RtlPathTypeDriveAbsolute:
|
|
case RtlPathTypeLocalDevice:
|
|
case RtlPathTypeRootLocalDevice:
|
|
default:
|
|
if(!RtlDosPathNameToNtPathName_U(lpTargetFileName, &TargetFileName, NULL, NULL))
|
|
{
|
|
bAllocatedTarget = TRUE;
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
cbPrintName = wcslen(lpTargetFileName) * sizeof(WCHAR);
|
|
cbReparseData = FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + TargetFileName.Length + cbPrintName;
|
|
pReparseData = RtlAllocateHeap(RtlGetProcessHeap(), 0, cbReparseData);
|
|
|
|
if(pReparseData == NULL)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
pBufTail = (PBYTE)(pReparseData->SymbolicLinkReparseBuffer.PathBuffer);
|
|
|
|
pReparseData->ReparseTag = (ULONG)IO_REPARSE_TAG_SYMLINK;
|
|
pReparseData->ReparseDataLength = (USHORT)cbReparseData - REPARSE_DATA_BUFFER_HEADER_SIZE;
|
|
pReparseData->Reserved = 0;
|
|
|
|
pReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
|
|
pReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength = TargetFileName.Length;
|
|
pBufTail += pReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset;
|
|
RtlCopyMemory(pBufTail, TargetFileName.Buffer, TargetFileName.Length);
|
|
|
|
pReparseData->SymbolicLinkReparseBuffer.PrintNameOffset = pReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength;
|
|
pReparseData->SymbolicLinkReparseBuffer.PrintNameLength = (USHORT)cbPrintName;
|
|
pBufTail += pReparseData->SymbolicLinkReparseBuffer.PrintNameOffset;
|
|
RtlCopyMemory(pBufTail, lpTargetFileName, cbPrintName);
|
|
|
|
pReparseData->SymbolicLinkReparseBuffer.Flags = 0;
|
|
|
|
if(bRelativePath)
|
|
pReparseData->SymbolicLinkReparseBuffer.Flags |= 1; // TODO! give this lone flag a name
|
|
|
|
if(!RtlDosPathNameToNtPathName_U(lpSymlinkFileName, &SymlinkFileName, NULL, NULL))
|
|
{
|
|
dwErr = ERROR_PATH_NOT_FOUND;
|
|
goto Cleanup;
|
|
}
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes, &SymlinkFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
|
|
|
Status = NtCreateFile
|
|
(
|
|
&hSymlink,
|
|
FILE_WRITE_ATTRIBUTES | DELETE | SYNCHRONIZE,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
NULL,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
0,
|
|
FILE_CREATE,
|
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT | dwCreateOptions,
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
{
|
|
dwErr = RtlNtStatusToDosError(Status);
|
|
goto Cleanup;
|
|
}
|
|
|
|
Status = NtFsControlFile
|
|
(
|
|
hSymlink,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
FSCTL_SET_REPARSE_POINT,
|
|
pReparseData,
|
|
cbReparseData,
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
{
|
|
FILE_DISPOSITION_INFORMATION DispInfo;
|
|
DispInfo.DeleteFile = TRUE;
|
|
NtSetInformationFile(hSymlink, &IoStatusBlock, &DispInfo, sizeof(DispInfo), FileDispositionInformation);
|
|
|
|
dwErr = RtlNtStatusToDosError(Status);
|
|
goto Cleanup;
|
|
}
|
|
|
|
dwErr = NO_ERROR;
|
|
|
|
Cleanup:
|
|
if(hSymlink)
|
|
NtClose(hSymlink);
|
|
|
|
RtlFreeUnicodeString(&SymlinkFileName);
|
|
if (bAllocatedTarget)
|
|
{
|
|
RtlFreeHeap(RtlGetProcessHeap(),
|
|
0,
|
|
TargetFileName.Buffer);
|
|
}
|
|
|
|
if(lpTargetFullFileName)
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, lpTargetFullFileName);
|
|
|
|
if(pReparseData)
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pReparseData);
|
|
|
|
if(dwErr)
|
|
{
|
|
SetLastError(dwErr);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOLEAN
|
|
NTAPI
|
|
CreateSymbolicLinkA(IN LPCSTR lpSymlinkFileName,
|
|
IN LPCSTR lpTargetFileName,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PWCHAR SymlinkW, TargetW;
|
|
BOOLEAN Ret;
|
|
|
|
if(!lpSymlinkFileName || !lpTargetFileName)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!(SymlinkW = FilenameA2W(lpSymlinkFileName, FALSE)))
|
|
return FALSE;
|
|
|
|
if (!(TargetW = FilenameA2W(lpTargetFileName, TRUE)))
|
|
return FALSE;
|
|
|
|
Ret = CreateSymbolicLinkW(SymlinkW,
|
|
TargetW,
|
|
dwFlags);
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, SymlinkW);
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, TargetW);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
GetFinalPathNameByHandleW(IN HANDLE hFile,
|
|
OUT LPWSTR lpszFilePath,
|
|
IN DWORD cchFilePath,
|
|
IN DWORD dwFlags)
|
|
{
|
|
if (dwFlags & ~(VOLUME_NAME_DOS | VOLUME_NAME_GUID | VOLUME_NAME_NT |
|
|
VOLUME_NAME_NONE | FILE_NAME_NORMALIZED | FILE_NAME_OPENED))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return 0;
|
|
}
|
|
|
|
UNIMPLEMENTED;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
GetFinalPathNameByHandleA(IN HANDLE hFile,
|
|
OUT LPSTR lpszFilePath,
|
|
IN DWORD cchFilePath,
|
|
IN DWORD dwFlags)
|
|
{
|
|
WCHAR FilePathW[MAX_PATH];
|
|
UNICODE_STRING FilePathU;
|
|
DWORD PrevLastError;
|
|
DWORD Ret = 0;
|
|
|
|
if (cchFilePath != 0 &&
|
|
cchFilePath > sizeof(FilePathW) / sizeof(FilePathW[0]))
|
|
{
|
|
FilePathU.Length = 0;
|
|
FilePathU.MaximumLength = (USHORT)cchFilePath * sizeof(WCHAR);
|
|
FilePathU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
0,
|
|
FilePathU.MaximumLength);
|
|
if (FilePathU.Buffer == NULL)
|
|
{
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FilePathU.Length = 0;
|
|
FilePathU.MaximumLength = sizeof(FilePathW);
|
|
FilePathU.Buffer = FilePathW;
|
|
}
|
|
|
|
/* save the last error code */
|
|
PrevLastError = GetLastError();
|
|
SetLastError(ERROR_SUCCESS);
|
|
|
|
/* call the unicode version that does all the work */
|
|
Ret = GetFinalPathNameByHandleW(hFile,
|
|
FilePathU.Buffer,
|
|
cchFilePath,
|
|
dwFlags);
|
|
|
|
if (GetLastError() == ERROR_SUCCESS)
|
|
{
|
|
/* no error, restore the last error code and convert the string */
|
|
SetLastError(PrevLastError);
|
|
|
|
Ret = FilenameU2A_FitOrFail(lpszFilePath,
|
|
cchFilePath,
|
|
&FilePathU);
|
|
}
|
|
|
|
/* free allocated memory if necessary */
|
|
if (FilePathU.Buffer != FilePathW)
|
|
{
|
|
RtlFreeHeap(RtlGetProcessHeap(),
|
|
0,
|
|
FilePathU.Buffer);
|
|
}
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
SetFileBandwidthReservation(IN HANDLE hFile,
|
|
IN DWORD nPeriodMilliseconds,
|
|
IN DWORD nBytesPerPeriod,
|
|
IN BOOL bDiscardable,
|
|
OUT LPDWORD lpTransferSize,
|
|
OUT LPDWORD lpNumOutstandingRequests)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetFileBandwidthReservation(IN HANDLE hFile,
|
|
OUT LPDWORD lpPeriodMilliseconds,
|
|
OUT LPDWORD lpBytesPerPeriod,
|
|
OUT LPBOOL pDiscardable,
|
|
OUT LPDWORD lpTransferSize,
|
|
OUT LPDWORD lpNumOutstandingRequests)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
HANDLE
|
|
WINAPI
|
|
OpenFileById(IN HANDLE hFile,
|
|
IN LPFILE_ID_DESCRIPTOR lpFileID,
|
|
IN DWORD dwDesiredAccess,
|
|
IN DWORD dwShareMode,
|
|
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL,
|
|
IN DWORD dwFlags)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
ULONGLONG
|
|
WINAPI
|
|
GetTickCount64(VOID)
|
|
{
|
|
ULARGE_INTEGER TickCount;
|
|
|
|
while (TRUE)
|
|
{
|
|
TickCount.HighPart = (ULONG)SharedUserData->TickCount.High1Time;
|
|
TickCount.LowPart = SharedUserData->TickCount.LowPart;
|
|
|
|
if (TickCount.HighPart == (ULONG)SharedUserData->TickCount.High2Time) break;
|
|
|
|
YieldProcessor();
|
|
}
|
|
|
|
return (UInt32x32To64(TickCount.LowPart, SharedUserData->TickCountMultiplier) >> 24) +
|
|
(UInt32x32To64(TickCount.HighPart, SharedUserData->TickCountMultiplier) << 8);
|
|
}
|
|
|
|
#endif
|
|
|
|
/*
|
|
Vista+ MUI support functions
|
|
|
|
References:
|
|
Evolution of MUI Support across Windows Versions: http://msdn.microsoft.com/en-US/library/ee264317.aspx
|
|
Comparing Windows XP Professional Multilingual Options: http://technet.microsoft.com/en-us/library/bb457045.aspx
|
|
|
|
More info:
|
|
http://msdn.microsoft.com/en-us/goglobal/bb978454.aspx
|
|
http://msdn.microsoft.com/en-us/library/dd319074.aspx
|
|
*/
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
BOOL
|
|
WINAPI
|
|
GetFileMUIInfo(
|
|
DWORD dwFlags,
|
|
PCWSTR pcwszFilePath,
|
|
PFILEMUIINFO pFileMUIInfo,
|
|
DWORD *pcbFileMUIInfo)
|
|
{
|
|
DPRINT1("%x %p %p %p\n", dwFlags, pcwszFilePath, pFileMUIInfo, pcbFileMUIInfo);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetFileMUIPath(
|
|
DWORD dwFlags,
|
|
PCWSTR pcwszFilePath,
|
|
PWSTR pwszLanguage,
|
|
PULONG pcchLanguage,
|
|
PWSTR pwszFileMUIPath,
|
|
PULONG pcchFileMUIPath,
|
|
PULONGLONG pululEnumerator)
|
|
{
|
|
DPRINT1("%x %p %p %p %p %p\n", dwFlags, pcwszFilePath, pwszLanguage, pwszFileMUIPath, pcchFileMUIPath, pululEnumerator);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetProcessPreferredUILanguages(
|
|
DWORD dwFlags,
|
|
PULONG pulNumLanguages,
|
|
PZZWSTR pwszLanguagesBuffer,
|
|
PULONG pcchLanguagesBuffer)
|
|
{
|
|
DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetSystemPreferredUILanguages(
|
|
DWORD dwFlags,
|
|
PULONG pulNumLanguages,
|
|
PZZWSTR pwszLanguagesBuffer,
|
|
PULONG pcchLanguagesBuffer)
|
|
{
|
|
DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetThreadPreferredUILanguages(
|
|
DWORD dwFlags,
|
|
PULONG pulNumLanguages,
|
|
PZZWSTR pwszLanguagesBuffer,
|
|
PULONG pcchLanguagesBuffer)
|
|
{
|
|
DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
LANGID
|
|
WINAPI
|
|
GetThreadUILanguage(VOID)
|
|
{
|
|
UNIMPLEMENTED;
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetUILanguageInfo(
|
|
DWORD dwFlags,
|
|
PCZZWSTR pwmszLanguage,
|
|
PZZWSTR pwszFallbackLanguages,
|
|
PDWORD pcchFallbackLanguages,
|
|
PDWORD pdwAttributes)
|
|
{
|
|
DPRINT1("%x %p %p %p %p\n", dwFlags, pwmszLanguage, pwszFallbackLanguages, pcchFallbackLanguages, pdwAttributes);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetUserPreferredUILanguages(
|
|
DWORD dwFlags,
|
|
PULONG pulNumLanguages,
|
|
PZZWSTR pwszLanguagesBuffer,
|
|
PULONG pcchLanguagesBuffer)
|
|
{
|
|
DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
SetProcessPreferredUILanguages(
|
|
DWORD dwFlags,
|
|
PCZZWSTR pwszLanguagesBuffer,
|
|
PULONG pulNumLanguages)
|
|
{
|
|
DPRINT1("%x %p %p\n", dwFlags, pwszLanguagesBuffer, pulNumLanguages);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
SetThreadPreferredUILanguages(
|
|
DWORD dwFlags,
|
|
PCZZWSTR pwszLanguagesBuffer,
|
|
PULONG pulNumLanguages
|
|
)
|
|
{
|
|
DPRINT1("%x %p %p\n", dwFlags, pwszLanguagesBuffer, pulNumLanguages);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|