2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Vista functions
5 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
8 /* INCLUDES *******************************************************************/
15 #if _WIN32_WINNT >= 0x600
17 /* FIXME: Move these RTL declarations to the NDK */
20 RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable
,
21 IN OUT PRTL_CRITICAL_SECTION CriticalSection
,
22 IN PLARGE_INTEGER TimeOut OPTIONAL
);
26 RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable
,
27 IN OUT PRTL_SRWLOCK SRWLock
,
28 IN PLARGE_INTEGER TimeOut OPTIONAL
,
31 /* PUBLIC FUNCTIONS ***********************************************************/
38 SleepConditionVariableCS(IN OUT PCONDITION_VARIABLE ConditionVariable
,
39 IN OUT PCRITICAL_SECTION CriticalSection
,
40 IN DWORD dwMilliseconds
)
43 LARGE_INTEGER TimeOut
;
44 PLARGE_INTEGER TimeOutPtr
= NULL
;
46 if (dwMilliseconds
!= INFINITE
)
48 TimeOut
.QuadPart
= dwMilliseconds
* -10000LL;
49 TimeOutPtr
= &TimeOut
;
53 Status
= RtlSleepConditionVariableCS((PRTL_CONDITION_VARIABLE
)ConditionVariable
,
54 (PRTL_CRITICAL_SECTION
)CriticalSection
,
57 if (!NT_SUCCESS(Status
))
59 BaseSetLastNTError(Status
);
72 SleepConditionVariableSRW(IN OUT PCONDITION_VARIABLE ConditionVariable
,
73 IN OUT PSRWLOCK SRWLock
,
74 IN DWORD dwMilliseconds
,
78 LARGE_INTEGER TimeOut
;
79 PLARGE_INTEGER TimeOutPtr
= NULL
;
81 if (dwMilliseconds
!= INFINITE
)
83 TimeOut
.QuadPart
= dwMilliseconds
* -10000LL;
84 TimeOutPtr
= &TimeOut
;
88 Status
= RtlSleepConditionVariableSRW((PRTL_CONDITION_VARIABLE
)ConditionVariable
,
89 (PRTL_SRWLOCK
)SRWLock
,
93 if (!NT_SUCCESS(Status
))
95 BaseSetLastNTError(Status
);
106 BOOL WINAPI
InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection
,
107 IN DWORD dwSpinCount
,
112 /* FIXME: Flags ignored */
114 /* Initialize the critical section */
115 Status
= RtlInitializeCriticalSectionAndSpinCount(
116 (PRTL_CRITICAL_SECTION
)lpCriticalSection
,
118 if (!NT_SUCCESS(Status
))
120 /* Set failure code */
121 BaseSetLastNTError(Status
);
135 QueryFullProcessImageNameW(HANDLE hProcess
,
140 BYTE Buffer
[sizeof(UNICODE_STRING
) + MAX_PATH
* sizeof(WCHAR
)];
141 UNICODE_STRING
*DynamicBuffer
= NULL
;
142 UNICODE_STRING
*Result
= NULL
;
146 Status
= NtQueryInformationProcess(hProcess
,
147 ProcessImageFileName
,
149 sizeof(Buffer
) - sizeof(WCHAR
),
151 if (Status
== STATUS_INFO_LENGTH_MISMATCH
)
153 DynamicBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Needed
+ sizeof(WCHAR
));
156 BaseSetLastNTError(STATUS_NO_MEMORY
);
160 Status
= NtQueryInformationProcess(hProcess
,
161 ProcessImageFileName
,
162 (LPBYTE
)DynamicBuffer
,
165 Result
= DynamicBuffer
;
167 else Result
= (PUNICODE_STRING
)Buffer
;
169 if (!NT_SUCCESS(Status
)) goto Cleanup
;
171 if (Result
->Length
/ sizeof(WCHAR
) + 1 > *pdwSize
)
173 Status
= STATUS_BUFFER_TOO_SMALL
;
177 *pdwSize
= Result
->Length
/ sizeof(WCHAR
);
178 memcpy(lpExeName
, Result
->Buffer
, Result
->Length
);
179 lpExeName
[*pdwSize
] = 0;
182 RtlFreeHeap(RtlGetProcessHeap(), 0, DynamicBuffer
);
184 if (!NT_SUCCESS(Status
))
186 BaseSetLastNTError(Status
);
198 QueryFullProcessImageNameA(HANDLE hProcess
,
203 DWORD pdwSizeW
= *pdwSize
;
207 lpExeNameW
= RtlAllocateHeap(RtlGetProcessHeap(),
209 *pdwSize
* sizeof(WCHAR
));
212 BaseSetLastNTError(STATUS_NO_MEMORY
);
216 Result
= QueryFullProcessImageNameW(hProcess
, dwFlags
, lpExeNameW
, &pdwSizeW
);
219 Result
= (0 != WideCharToMultiByte(CP_ACP
, 0,
227 *pdwSize
= strlen(lpExeName
);
229 RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW
);
239 GetApplicationRecoveryCallback(IN HANDLE hProcess
,
240 OUT APPLICATION_RECOVERY_CALLBACK
* pRecoveryCallback
,
241 OUT PVOID
* ppvParameter
,
242 PDWORD dwPingInterval
,
255 GetApplicationRestart(IN HANDLE hProcess
,
256 OUT PWSTR pwzCommandline OPTIONAL
,
257 IN OUT PDWORD pcchSize
,
258 OUT PDWORD pdwFlags OPTIONAL
)
270 RecoveryFinished(IN BOOL bSuccess
)
281 RecoveryInProgress(OUT PBOOL pbCancelled
)
293 RegisterApplicationRecoveryCallback(IN APPLICATION_RECOVERY_CALLBACK pRecoveyCallback
,
294 IN PVOID pvParameter OPTIONAL
,
295 DWORD dwPingInterval
,
308 RegisterApplicationRestart(IN PCWSTR pwzCommandline OPTIONAL
,
321 CreateSymbolicLinkW(IN LPCWSTR lpSymlinkFileName
,
322 IN LPCWSTR lpTargetFileName
,
325 IO_STATUS_BLOCK IoStatusBlock
;
326 OBJECT_ATTRIBUTES ObjectAttributes
;
327 HANDLE hSymlink
= NULL
;
328 UNICODE_STRING SymlinkFileName
= { 0, 0, NULL
};
329 UNICODE_STRING TargetFileName
= { 0, 0, NULL
};
330 BOOLEAN bAllocatedTarget
= FALSE
, bRelativePath
= FALSE
;
331 LPWSTR lpTargetFullFileName
= NULL
;
333 SIZE_T cbReparseData
;
334 PREPARSE_DATA_BUFFER pReparseData
= NULL
;
337 ULONG dwCreateOptions
;
340 if(!lpSymlinkFileName
|| !lpTargetFileName
|| (dwFlags
| SYMBOLIC_LINK_FLAG_DIRECTORY
) != SYMBOLIC_LINK_FLAG_DIRECTORY
)
342 SetLastError(ERROR_INVALID_PARAMETER
);
346 if(dwFlags
& SYMBOLIC_LINK_FLAG_DIRECTORY
)
347 dwCreateOptions
= FILE_DIRECTORY_FILE
;
349 dwCreateOptions
= FILE_NON_DIRECTORY_FILE
;
351 switch(RtlDetermineDosPathNameType_U(lpTargetFileName
))
353 case RtlPathTypeUnknown
:
354 case RtlPathTypeRooted
:
355 case RtlPathTypeRelative
:
356 bRelativePath
= TRUE
;
357 RtlInitUnicodeString(&TargetFileName
, lpTargetFileName
);
360 case RtlPathTypeDriveRelative
:
363 SIZE_T cchTargetFullFileName
;
365 cchTargetFullFileName
= GetFullPathNameW(lpTargetFileName
, 0, NULL
, &FilePart
);
367 if(cchTargetFullFileName
== 0)
369 dwErr
= GetLastError();
373 lpTargetFullFileName
= RtlAllocateHeap(RtlGetProcessHeap(), 0, cchTargetFullFileName
* sizeof(WCHAR
));
375 if(lpTargetFullFileName
== NULL
)
377 dwErr
= ERROR_NOT_ENOUGH_MEMORY
;
381 if(GetFullPathNameW(lpTargetFileName
, cchTargetFullFileName
, lpTargetFullFileName
, &FilePart
) == 0)
383 dwErr
= GetLastError();
388 lpTargetFileName
= lpTargetFullFileName
;
392 case RtlPathTypeUncAbsolute
:
393 case RtlPathTypeDriveAbsolute
:
394 case RtlPathTypeLocalDevice
:
395 case RtlPathTypeRootLocalDevice
:
397 if(!RtlDosPathNameToNtPathName_U(lpTargetFileName
, &TargetFileName
, NULL
, NULL
))
399 bAllocatedTarget
= TRUE
;
400 dwErr
= ERROR_INVALID_PARAMETER
;
405 cbPrintName
= wcslen(lpTargetFileName
) * sizeof(WCHAR
);
406 cbReparseData
= FIELD_OFFSET(REPARSE_DATA_BUFFER
, SymbolicLinkReparseBuffer
.PathBuffer
) + TargetFileName
.Length
+ cbPrintName
;
407 pReparseData
= RtlAllocateHeap(RtlGetProcessHeap(), 0, cbReparseData
);
409 if(pReparseData
== NULL
)
411 dwErr
= ERROR_NOT_ENOUGH_MEMORY
;
415 pBufTail
= (PBYTE
)(pReparseData
->SymbolicLinkReparseBuffer
.PathBuffer
);
417 pReparseData
->ReparseTag
= (ULONG
)IO_REPARSE_TAG_SYMLINK
;
418 pReparseData
->ReparseDataLength
= (USHORT
)cbReparseData
- REPARSE_DATA_BUFFER_HEADER_SIZE
;
419 pReparseData
->Reserved
= 0;
421 pReparseData
->SymbolicLinkReparseBuffer
.SubstituteNameOffset
= 0;
422 pReparseData
->SymbolicLinkReparseBuffer
.SubstituteNameLength
= TargetFileName
.Length
;
423 pBufTail
+= pReparseData
->SymbolicLinkReparseBuffer
.SubstituteNameOffset
;
424 RtlCopyMemory(pBufTail
, TargetFileName
.Buffer
, TargetFileName
.Length
);
426 pReparseData
->SymbolicLinkReparseBuffer
.PrintNameOffset
= pReparseData
->SymbolicLinkReparseBuffer
.SubstituteNameLength
;
427 pReparseData
->SymbolicLinkReparseBuffer
.PrintNameLength
= (USHORT
)cbPrintName
;
428 pBufTail
+= pReparseData
->SymbolicLinkReparseBuffer
.PrintNameOffset
;
429 RtlCopyMemory(pBufTail
, lpTargetFileName
, cbPrintName
);
431 pReparseData
->SymbolicLinkReparseBuffer
.Flags
= 0;
434 pReparseData
->SymbolicLinkReparseBuffer
.Flags
|= 1; // TODO! give this lone flag a name
436 if(!RtlDosPathNameToNtPathName_U(lpSymlinkFileName
, &SymlinkFileName
, NULL
, NULL
))
438 dwErr
= ERROR_PATH_NOT_FOUND
;
442 InitializeObjectAttributes(&ObjectAttributes
, &SymlinkFileName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
444 Status
= NtCreateFile
447 FILE_WRITE_ATTRIBUTES
| DELETE
| SYNCHRONIZE
,
451 FILE_ATTRIBUTE_NORMAL
,
454 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_OPEN_REPARSE_POINT
| dwCreateOptions
,
459 if(!NT_SUCCESS(Status
))
461 dwErr
= RtlNtStatusToDosError(Status
);
465 Status
= NtFsControlFile
472 FSCTL_SET_REPARSE_POINT
,
479 if(!NT_SUCCESS(Status
))
481 FILE_DISPOSITION_INFORMATION DispInfo
;
482 DispInfo
.DeleteFile
= TRUE
;
483 NtSetInformationFile(hSymlink
, &IoStatusBlock
, &DispInfo
, sizeof(DispInfo
), FileDispositionInformation
);
485 dwErr
= RtlNtStatusToDosError(Status
);
495 RtlFreeUnicodeString(&SymlinkFileName
);
496 if (bAllocatedTarget
)
498 RtlFreeHeap(RtlGetProcessHeap(),
500 TargetFileName
.Buffer
);
503 if(lpTargetFullFileName
)
504 RtlFreeHeap(RtlGetProcessHeap(), 0, lpTargetFullFileName
);
507 RtlFreeHeap(RtlGetProcessHeap(), 0, pReparseData
);
524 CreateSymbolicLinkA(IN LPCSTR lpSymlinkFileName
,
525 IN LPCSTR lpTargetFileName
,
528 PWCHAR SymlinkW
, TargetW
;
531 if(!lpSymlinkFileName
|| !lpTargetFileName
)
533 SetLastError(ERROR_INVALID_PARAMETER
);
537 if (!(SymlinkW
= FilenameA2W(lpSymlinkFileName
, FALSE
)))
540 if (!(TargetW
= FilenameA2W(lpTargetFileName
, TRUE
)))
543 Ret
= CreateSymbolicLinkW(SymlinkW
,
547 RtlFreeHeap(RtlGetProcessHeap(), 0, SymlinkW
);
548 RtlFreeHeap(RtlGetProcessHeap(), 0, TargetW
);
559 GetFinalPathNameByHandleW(IN HANDLE hFile
,
560 OUT LPWSTR lpszFilePath
,
561 IN DWORD cchFilePath
,
564 if (dwFlags
& ~(VOLUME_NAME_DOS
| VOLUME_NAME_GUID
| VOLUME_NAME_NT
|
565 VOLUME_NAME_NONE
| FILE_NAME_NORMALIZED
| FILE_NAME_OPENED
))
567 SetLastError(ERROR_INVALID_PARAMETER
);
581 GetFinalPathNameByHandleA(IN HANDLE hFile
,
582 OUT LPSTR lpszFilePath
,
583 IN DWORD cchFilePath
,
586 WCHAR FilePathW
[MAX_PATH
];
587 UNICODE_STRING FilePathU
;
591 if (cchFilePath
!= 0 &&
592 cchFilePath
> sizeof(FilePathW
) / sizeof(FilePathW
[0]))
594 FilePathU
.Length
= 0;
595 FilePathU
.MaximumLength
= (USHORT
)cchFilePath
* sizeof(WCHAR
);
596 FilePathU
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
598 FilePathU
.MaximumLength
);
599 if (FilePathU
.Buffer
== NULL
)
601 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
607 FilePathU
.Length
= 0;
608 FilePathU
.MaximumLength
= sizeof(FilePathW
);
609 FilePathU
.Buffer
= FilePathW
;
612 /* save the last error code */
613 PrevLastError
= GetLastError();
614 SetLastError(ERROR_SUCCESS
);
616 /* call the unicode version that does all the work */
617 Ret
= GetFinalPathNameByHandleW(hFile
,
622 if (GetLastError() == ERROR_SUCCESS
)
624 /* no error, restore the last error code and convert the string */
625 SetLastError(PrevLastError
);
627 Ret
= FilenameU2A_FitOrFail(lpszFilePath
,
632 /* free allocated memory if necessary */
633 if (FilePathU
.Buffer
!= FilePathW
)
635 RtlFreeHeap(RtlGetProcessHeap(),
649 SetFileBandwidthReservation(IN HANDLE hFile
,
650 IN DWORD nPeriodMilliseconds
,
651 IN DWORD nBytesPerPeriod
,
652 IN BOOL bDiscardable
,
653 OUT LPDWORD lpTransferSize
,
654 OUT LPDWORD lpNumOutstandingRequests
)
666 GetFileBandwidthReservation(IN HANDLE hFile
,
667 OUT LPDWORD lpPeriodMilliseconds
,
668 OUT LPDWORD lpBytesPerPeriod
,
669 OUT LPBOOL pDiscardable
,
670 OUT LPDWORD lpTransferSize
,
671 OUT LPDWORD lpNumOutstandingRequests
)
683 SetFileCompletionNotificationModes(IN HANDLE FileHandle
,
686 if (Flags
& ~(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
| FILE_SKIP_SET_EVENT_ON_HANDLE
))
688 SetLastError(ERROR_INVALID_PARAMETER
);
702 OpenFileById(IN HANDLE hFile
,
703 IN LPFILE_ID_DESCRIPTOR lpFileID
,
704 IN DWORD dwDesiredAccess
,
705 IN DWORD dwShareMode
,
706 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL
,
710 return INVALID_HANDLE_VALUE
;
721 ULARGE_INTEGER TickCount
;
725 TickCount
.HighPart
= (ULONG
)SharedUserData
->TickCount
.High1Time
;
726 TickCount
.LowPart
= SharedUserData
->TickCount
.LowPart
;
728 if (TickCount
.HighPart
== (ULONG
)SharedUserData
->TickCount
.High2Time
) break;
733 return (UInt32x32To64(TickCount
.LowPart
, SharedUserData
->TickCountMultiplier
) >> 24) +
734 (UInt32x32To64(TickCount
.HighPart
, SharedUserData
->TickCountMultiplier
) << 8);
740 Vista+ MUI support functions
743 Evolution of MUI Support across Windows Versions: http://msdn.microsoft.com/en-US/library/ee264317.aspx
744 Comparing Windows XP Professional Multilingual Options: http://technet.microsoft.com/en-us/library/bb457045.aspx
747 http://msdn.microsoft.com/en-us/goglobal/bb978454.aspx
748 http://msdn.microsoft.com/en-us/library/dd319074.aspx
751 /* FUNCTIONS *****************************************************************/
757 PCWSTR pcwszFilePath
,
758 PFILEMUIINFO pFileMUIInfo
,
759 DWORD
*pcbFileMUIInfo
)
761 DPRINT1("%x %p %p %p\n", dwFlags
, pcwszFilePath
, pFileMUIInfo
, pcbFileMUIInfo
);
762 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
773 PCWSTR pcwszFilePath
,
776 PWSTR pwszFileMUIPath
,
777 PULONG pcchFileMUIPath
,
778 PULONGLONG pululEnumerator
)
780 DPRINT1("%x %p %p %p %p %p\n", dwFlags
, pcwszFilePath
, pwszLanguage
, pwszFileMUIPath
, pcchFileMUIPath
, pululEnumerator
);
781 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
790 GetProcessPreferredUILanguages(
792 PULONG pulNumLanguages
,
793 PZZWSTR pwszLanguagesBuffer
,
794 PULONG pcchLanguagesBuffer
)
796 DPRINT1("%x %p %p %p\n", dwFlags
, pulNumLanguages
, pwszLanguagesBuffer
, pcchLanguagesBuffer
);
797 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
806 GetSystemPreferredUILanguages(
808 PULONG pulNumLanguages
,
809 PZZWSTR pwszLanguagesBuffer
,
810 PULONG pcchLanguagesBuffer
)
812 DPRINT1("%x %p %p %p\n", dwFlags
, pulNumLanguages
, pwszLanguagesBuffer
, pcchLanguagesBuffer
);
813 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
822 GetThreadPreferredUILanguages(
824 PULONG pulNumLanguages
,
825 PZZWSTR pwszLanguagesBuffer
,
826 PULONG pcchLanguagesBuffer
)
828 DPRINT1("%x %p %p %p\n", dwFlags
, pulNumLanguages
, pwszLanguagesBuffer
, pcchLanguagesBuffer
);
829 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
838 GetThreadUILanguage(VOID
)
841 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
852 PCZZWSTR pwmszLanguage
,
853 PZZWSTR pwszFallbackLanguages
,
854 PDWORD pcchFallbackLanguages
,
855 PDWORD pdwAttributes
)
857 DPRINT1("%x %p %p %p %p\n", dwFlags
, pwmszLanguage
, pwszFallbackLanguages
, pcchFallbackLanguages
, pdwAttributes
);
858 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
868 GetUserPreferredUILanguages(
870 PULONG pulNumLanguages
,
871 PZZWSTR pwszLanguagesBuffer
,
872 PULONG pcchLanguagesBuffer
)
874 DPRINT1("%x %p %p %p\n", dwFlags
, pulNumLanguages
, pwszLanguagesBuffer
, pcchLanguagesBuffer
);
875 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
884 SetProcessPreferredUILanguages(
886 PCZZWSTR pwszLanguagesBuffer
,
887 PULONG pulNumLanguages
)
889 DPRINT1("%x %p %p\n", dwFlags
, pwszLanguagesBuffer
, pulNumLanguages
);
890 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
900 SetThreadPreferredUILanguages(
902 PCZZWSTR pwszLanguagesBuffer
,
903 PULONG pulNumLanguages
906 DPRINT1("%x %p %p\n", dwFlags
, pwszLanguagesBuffer
, pulNumLanguages
);
907 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);