1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS system libraries
3 * PURPOSE: Vista functions
4 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
12 #if _WIN32_WINNT >= 0x600
14 /* FIXME: Move these RTL declarations to the NDK */
17 RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable
,
18 IN OUT PRTL_CRITICAL_SECTION CriticalSection
,
19 IN PLARGE_INTEGER TimeOut OPTIONAL
);
23 RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable
,
24 IN OUT PRTL_SRWLOCK SRWLock
,
25 IN PLARGE_INTEGER TimeOut OPTIONAL
,
28 /* PUBLIC FUNCTIONS ***********************************************************/
35 SleepConditionVariableCS(IN OUT PCONDITION_VARIABLE ConditionVariable
,
36 IN OUT PCRITICAL_SECTION CriticalSection
,
37 IN DWORD dwMilliseconds
)
40 LARGE_INTEGER TimeOut
;
41 PLARGE_INTEGER TimeOutPtr
= NULL
;
43 if (dwMilliseconds
!= INFINITE
)
45 TimeOut
.QuadPart
= UInt32x32To64(-10000, dwMilliseconds
);
46 TimeOutPtr
= &TimeOut
;
50 Status
= RtlSleepConditionVariableCS((PRTL_CONDITION_VARIABLE
)ConditionVariable
,
51 (PRTL_CRITICAL_SECTION
)CriticalSection
,
54 if (!NT_SUCCESS(Status
))
56 BaseSetLastNTError(Status
);
69 SleepConditionVariableSRW(IN OUT PCONDITION_VARIABLE ConditionVariable
,
70 IN OUT PSRWLOCK SRWLock
,
71 IN DWORD dwMilliseconds
,
75 LARGE_INTEGER TimeOut
;
76 PLARGE_INTEGER TimeOutPtr
= NULL
;
78 if (dwMilliseconds
!= INFINITE
)
80 TimeOut
.QuadPart
= UInt32x32To64(-10000, dwMilliseconds
);
81 TimeOutPtr
= &TimeOut
;
85 Status
= RtlSleepConditionVariableSRW((PRTL_CONDITION_VARIABLE
)ConditionVariable
,
86 (PRTL_SRWLOCK
)SRWLock
,
90 if (!NT_SUCCESS(Status
))
92 BaseSetLastNTError(Status
);
103 BOOL WINAPI
InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection
,
104 IN DWORD dwSpinCount
,
109 /* FIXME: Flags ignored */
111 /* Initialize the critical section */
112 Status
= RtlInitializeCriticalSectionAndSpinCount(
113 (PRTL_CRITICAL_SECTION
)lpCriticalSection
,
115 if (!NT_SUCCESS(Status
))
117 /* Set failure code */
118 BaseSetLastNTError(Status
);
133 QueryFullProcessImageNameW(HANDLE hProcess
,
138 BYTE Buffer
[sizeof(UNICODE_STRING
) + MAX_PATH
* sizeof(WCHAR
)];
139 UNICODE_STRING
*DynamicBuffer
= NULL
;
140 UNICODE_STRING
*Result
= NULL
;
144 Status
= NtQueryInformationProcess(hProcess
,
145 ProcessImageFileName
,
147 sizeof(Buffer
) - sizeof(WCHAR
),
149 if (Status
== STATUS_INFO_LENGTH_MISMATCH
)
151 DynamicBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Needed
+ sizeof(WCHAR
));
154 BaseSetLastNTError(STATUS_NO_MEMORY
);
158 Status
= NtQueryInformationProcess(hProcess
,
159 ProcessImageFileName
,
160 (LPBYTE
)DynamicBuffer
,
163 Result
= DynamicBuffer
;
165 else Result
= (PUNICODE_STRING
)Buffer
;
167 if (!NT_SUCCESS(Status
)) goto Cleanup
;
169 if (Result
->Length
/ sizeof(WCHAR
) + 1 > *pdwSize
)
171 Status
= STATUS_BUFFER_TOO_SMALL
;
175 *pdwSize
= Result
->Length
/ sizeof(WCHAR
);
176 memcpy(lpExeName
, Result
->Buffer
, Result
->Length
);
177 lpExeName
[*pdwSize
] = 0;
180 RtlFreeHeap(RtlGetProcessHeap(), 0, DynamicBuffer
);
182 if (!NT_SUCCESS(Status
))
184 BaseSetLastNTError(Status
);
196 QueryFullProcessImageNameA(HANDLE hProcess
,
201 DWORD pdwSizeW
= *pdwSize
;
205 lpExeNameW
= RtlAllocateHeap(RtlGetProcessHeap(),
207 *pdwSize
* sizeof(WCHAR
));
210 BaseSetLastNTError(STATUS_NO_MEMORY
);
214 Result
= QueryFullProcessImageNameW(hProcess
, dwFlags
, lpExeNameW
, &pdwSizeW
);
217 Result
= (0 != WideCharToMultiByte(CP_ACP
, 0,
225 *pdwSize
= strlen(lpExeName
);
227 RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW
);
236 GetApplicationRecoveryCallback(IN HANDLE hProcess
,
237 OUT APPLICATION_RECOVERY_CALLBACK
* pRecoveryCallback
,
238 OUT PVOID
* ppvParameter
,
239 PDWORD dwPingInterval
,
252 GetApplicationRestart(IN HANDLE hProcess
,
253 OUT PWSTR pwzCommandline OPTIONAL
,
254 IN OUT PDWORD pcchSize
,
255 OUT PDWORD pdwFlags OPTIONAL
)
267 RecoveryFinished(IN BOOL bSuccess
)
278 RecoveryInProgress(OUT PBOOL pbCancelled
)
290 RegisterApplicationRecoveryCallback(IN APPLICATION_RECOVERY_CALLBACK pRecoveyCallback
,
291 IN PVOID pvParameter OPTIONAL
,
292 DWORD dwPingInterval
,
305 RegisterApplicationRestart(IN PCWSTR pwzCommandline OPTIONAL
,
312 /*--------------------------------------------------------------
313 * GetConsoleHistoryInfo
319 GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo
)
321 CSR_API_MESSAGE Request
;
322 ULONG CsrRequest
= MAKE_CSR_API(GET_HISTORY_INFO
, CSR_CONSOLE
);
324 if (lpConsoleHistoryInfo
->cbSize
!= sizeof(CONSOLE_HISTORY_INFO
))
326 SetLastError(ERROR_INVALID_PARAMETER
);
329 Status
= CsrClientCallServer(&Request
, NULL
, CsrRequest
, sizeof(CSR_API_MESSAGE
));
330 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Request
.Status
))
332 BaseSetLastNTError(Status
);
335 lpConsoleHistoryInfo
->HistoryBufferSize
= Request
.Data
.GetHistoryInfo
.HistoryBufferSize
;
336 lpConsoleHistoryInfo
->NumberOfHistoryBuffers
= Request
.Data
.GetHistoryInfo
.NumberOfHistoryBuffers
;
337 lpConsoleHistoryInfo
->dwFlags
= Request
.Data
.GetHistoryInfo
.dwFlags
;
342 /*--------------------------------------------------------------
343 * SetConsoleHistoryInfo
349 SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo
)
351 CSR_API_MESSAGE Request
;
352 ULONG CsrRequest
= MAKE_CSR_API(GET_HISTORY_INFO
, CSR_CONSOLE
);
354 if (lpConsoleHistoryInfo
->cbSize
!= sizeof(CONSOLE_HISTORY_INFO
))
356 SetLastError(ERROR_INVALID_PARAMETER
);
359 Request
.Data
.SetHistoryInfo
.HistoryBufferSize
= lpConsoleHistoryInfo
->HistoryBufferSize
;
360 Request
.Data
.SetHistoryInfo
.NumberOfHistoryBuffers
= lpConsoleHistoryInfo
->NumberOfHistoryBuffers
;
361 Request
.Data
.SetHistoryInfo
.dwFlags
= lpConsoleHistoryInfo
->dwFlags
;
362 Status
= CsrClientCallServer(&Request
, NULL
, CsrRequest
, sizeof(CSR_API_MESSAGE
));
363 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Request
.Status
))
365 BaseSetLastNTError(Status
);
372 /*--------------------------------------------------------------
373 * GetConsoleOriginalTitleW
379 GetConsoleOriginalTitleW(OUT LPWSTR lpConsoleTitle
,
382 DPRINT1("GetConsoleOriginalTitleW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle
, nSize
);
383 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
388 /*--------------------------------------------------------------
389 * GetConsoleOriginalTitleA
395 GetConsoleOriginalTitleA(OUT LPSTR lpConsoleTitle
,
398 DPRINT1("GetConsoleOriginalTitleA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle
, nSize
);
399 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
404 /*--------------------------------------------------------------
405 * GetConsoleScreenBufferInfoEx
411 GetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput
,
412 OUT PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx
)
414 DPRINT1("GetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput
, lpConsoleScreenBufferInfoEx
);
415 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
420 /*--------------------------------------------------------------
421 * SetConsoleScreenBufferInfoEx
427 SetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput
,
428 IN PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx
)
430 DPRINT1("SetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput
, lpConsoleScreenBufferInfoEx
);
431 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
436 /*--------------------------------------------------------------
437 * GetCurrentConsoleFontEx
443 GetCurrentConsoleFontEx(IN HANDLE hConsoleOutput
,
444 IN BOOL bMaximumWindow
,
445 OUT PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx
)
447 DPRINT1("GetCurrentConsoleFontEx(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput
, bMaximumWindow
, lpConsoleCurrentFontEx
);
448 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
458 CreateSymbolicLinkW(IN LPCWSTR lpSymlinkFileName
,
459 IN LPCWSTR lpTargetFileName
,
462 IO_STATUS_BLOCK IoStatusBlock
;
463 OBJECT_ATTRIBUTES ObjectAttributes
;
464 HANDLE hSymlink
= NULL
;
465 UNICODE_STRING SymlinkFileName
= { 0, 0, NULL
};
466 UNICODE_STRING TargetFileName
= { 0, 0, NULL
};
467 BOOLEAN bAllocatedTarget
= FALSE
, bRelativePath
= FALSE
;
468 LPWSTR lpTargetFullFileName
= NULL
;
470 SIZE_T cbReparseData
;
471 PREPARSE_DATA_BUFFER pReparseData
= NULL
;
474 ULONG dwCreateOptions
;
477 if(!lpSymlinkFileName
|| !lpTargetFileName
|| (dwFlags
| SYMBOLIC_LINK_FLAG_DIRECTORY
) != SYMBOLIC_LINK_FLAG_DIRECTORY
)
479 SetLastError(ERROR_INVALID_PARAMETER
);
483 if(dwFlags
& SYMBOLIC_LINK_FLAG_DIRECTORY
)
484 dwCreateOptions
= FILE_DIRECTORY_FILE
;
486 dwCreateOptions
= FILE_NON_DIRECTORY_FILE
;
488 switch(RtlDetermineDosPathNameType_U(lpTargetFileName
))
490 case RtlPathTypeUnknown
:
491 case RtlPathTypeRooted
:
492 case RtlPathTypeRelative
:
493 bRelativePath
= TRUE
;
494 RtlInitUnicodeString(&TargetFileName
, lpTargetFileName
);
497 case RtlPathTypeDriveRelative
:
500 SIZE_T cchTargetFullFileName
;
502 cchTargetFullFileName
= GetFullPathNameW(lpTargetFileName
, 0, NULL
, &FilePart
);
504 if(cchTargetFullFileName
== 0)
506 dwErr
= GetLastError();
510 lpTargetFullFileName
= RtlAllocateHeap(RtlGetProcessHeap(), 0, cchTargetFullFileName
* sizeof(WCHAR
));
512 if(lpTargetFullFileName
== NULL
)
514 dwErr
= ERROR_NOT_ENOUGH_MEMORY
;
518 if(GetFullPathNameW(lpTargetFileName
, cchTargetFullFileName
, lpTargetFullFileName
, &FilePart
) == 0)
520 dwErr
= GetLastError();
525 lpTargetFileName
= lpTargetFullFileName
;
529 case RtlPathTypeUncAbsolute
:
530 case RtlPathTypeDriveAbsolute
:
531 case RtlPathTypeLocalDevice
:
532 case RtlPathTypeRootLocalDevice
:
534 if(!RtlDosPathNameToNtPathName_U(lpTargetFileName
, &TargetFileName
, NULL
, NULL
))
536 bAllocatedTarget
= TRUE
;
537 dwErr
= ERROR_INVALID_PARAMETER
;
542 cbPrintName
= wcslen(lpTargetFileName
) * sizeof(WCHAR
);
543 cbReparseData
= FIELD_OFFSET(REPARSE_DATA_BUFFER
, SymbolicLinkReparseBuffer
.PathBuffer
) + TargetFileName
.Length
+ cbPrintName
;
544 pReparseData
= RtlAllocateHeap(RtlGetProcessHeap(), 0, cbReparseData
);
546 if(pReparseData
== NULL
)
548 dwErr
= ERROR_NOT_ENOUGH_MEMORY
;
552 pBufTail
= (PBYTE
)(pReparseData
->SymbolicLinkReparseBuffer
.PathBuffer
);
554 pReparseData
->ReparseTag
= (ULONG
)IO_REPARSE_TAG_SYMLINK
;
555 pReparseData
->ReparseDataLength
= (USHORT
)cbReparseData
- REPARSE_DATA_BUFFER_HEADER_SIZE
;
556 pReparseData
->Reserved
= 0;
558 pReparseData
->SymbolicLinkReparseBuffer
.SubstituteNameOffset
= 0;
559 pReparseData
->SymbolicLinkReparseBuffer
.SubstituteNameLength
= TargetFileName
.Length
;
560 pBufTail
+= pReparseData
->SymbolicLinkReparseBuffer
.SubstituteNameOffset
;
561 RtlCopyMemory(pBufTail
, TargetFileName
.Buffer
, TargetFileName
.Length
);
563 pReparseData
->SymbolicLinkReparseBuffer
.PrintNameOffset
= pReparseData
->SymbolicLinkReparseBuffer
.SubstituteNameLength
;
564 pReparseData
->SymbolicLinkReparseBuffer
.PrintNameLength
= (USHORT
)cbPrintName
;
565 pBufTail
+= pReparseData
->SymbolicLinkReparseBuffer
.PrintNameOffset
;
566 RtlCopyMemory(pBufTail
, lpTargetFileName
, cbPrintName
);
568 pReparseData
->SymbolicLinkReparseBuffer
.Flags
= 0;
571 pReparseData
->SymbolicLinkReparseBuffer
.Flags
|= 1; // TODO! give this lone flag a name
573 if(!RtlDosPathNameToNtPathName_U(lpSymlinkFileName
, &SymlinkFileName
, NULL
, NULL
))
575 dwErr
= ERROR_PATH_NOT_FOUND
;
579 InitializeObjectAttributes(&ObjectAttributes
, &SymlinkFileName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
581 Status
= NtCreateFile
584 FILE_WRITE_ATTRIBUTES
| DELETE
| SYNCHRONIZE
,
588 FILE_ATTRIBUTE_NORMAL
,
591 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_OPEN_REPARSE_POINT
| dwCreateOptions
,
596 if(!NT_SUCCESS(Status
))
598 dwErr
= RtlNtStatusToDosError(Status
);
602 Status
= NtFsControlFile
609 FSCTL_SET_REPARSE_POINT
,
616 if(!NT_SUCCESS(Status
))
618 FILE_DISPOSITION_INFORMATION DispInfo
;
619 DispInfo
.DeleteFile
= TRUE
;
620 NtSetInformationFile(hSymlink
, &IoStatusBlock
, &DispInfo
, sizeof(DispInfo
), FileDispositionInformation
);
622 dwErr
= RtlNtStatusToDosError(Status
);
632 RtlFreeUnicodeString(&SymlinkFileName
);
633 if (bAllocatedTarget
)
635 RtlFreeHeap(RtlGetProcessHeap(),
637 TargetFileName
.Buffer
);
640 if(lpTargetFullFileName
)
641 RtlFreeHeap(RtlGetProcessHeap(), 0, lpTargetFullFileName
);
644 RtlFreeHeap(RtlGetProcessHeap(), 0, pReparseData
);
661 CreateSymbolicLinkA(IN LPCSTR lpSymlinkFileName
,
662 IN LPCSTR lpTargetFileName
,
665 PWCHAR SymlinkW
, TargetW
;
668 if(!lpSymlinkFileName
|| !lpTargetFileName
)
670 SetLastError(ERROR_INVALID_PARAMETER
);
674 if (!(SymlinkW
= FilenameA2W(lpSymlinkFileName
, FALSE
)))
677 if (!(TargetW
= FilenameA2W(lpTargetFileName
, TRUE
)))
680 Ret
= CreateSymbolicLinkW(SymlinkW
,
684 RtlFreeHeap(RtlGetProcessHeap(), 0, SymlinkW
);
685 RtlFreeHeap(RtlGetProcessHeap(), 0, TargetW
);
695 GetFinalPathNameByHandleW(IN HANDLE hFile
,
696 OUT LPWSTR lpszFilePath
,
697 IN DWORD cchFilePath
,
700 if (dwFlags
& ~(VOLUME_NAME_DOS
| VOLUME_NAME_GUID
| VOLUME_NAME_NT
|
701 VOLUME_NAME_NONE
| FILE_NAME_NORMALIZED
| FILE_NAME_OPENED
))
703 SetLastError(ERROR_INVALID_PARAMETER
);
716 GetFinalPathNameByHandleA(IN HANDLE hFile
,
717 OUT LPSTR lpszFilePath
,
718 IN DWORD cchFilePath
,
721 WCHAR FilePathW
[MAX_PATH
];
722 UNICODE_STRING FilePathU
;
726 if (cchFilePath
!= 0 &&
727 cchFilePath
> sizeof(FilePathW
) / sizeof(FilePathW
[0]))
729 FilePathU
.Length
= 0;
730 FilePathU
.MaximumLength
= (USHORT
)cchFilePath
* sizeof(WCHAR
);
731 FilePathU
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
733 FilePathU
.MaximumLength
);
734 if (FilePathU
.Buffer
== NULL
)
736 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
742 FilePathU
.Length
= 0;
743 FilePathU
.MaximumLength
= sizeof(FilePathW
);
744 FilePathU
.Buffer
= FilePathW
;
747 /* save the last error code */
748 PrevLastError
= GetLastError();
749 SetLastError(ERROR_SUCCESS
);
751 /* call the unicode version that does all the work */
752 Ret
= GetFinalPathNameByHandleW(hFile
,
757 if (GetLastError() == ERROR_SUCCESS
)
759 /* no error, restore the last error code and convert the string */
760 SetLastError(PrevLastError
);
762 Ret
= FilenameU2A_FitOrFail(lpszFilePath
,
767 /* free allocated memory if necessary */
768 if (FilePathU
.Buffer
!= FilePathW
)
770 RtlFreeHeap(RtlGetProcessHeap(),
783 SetFileBandwidthReservation(IN HANDLE hFile
,
784 IN DWORD nPeriodMilliseconds
,
785 IN DWORD nBytesPerPeriod
,
786 IN BOOL bDiscardable
,
787 OUT LPDWORD lpTransferSize
,
788 OUT LPDWORD lpNumOutstandingRequests
)
800 GetFileBandwidthReservation(IN HANDLE hFile
,
801 OUT LPDWORD lpPeriodMilliseconds
,
802 OUT LPDWORD lpBytesPerPeriod
,
803 OUT LPBOOL pDiscardable
,
804 OUT LPDWORD lpTransferSize
,
805 OUT LPDWORD lpNumOutstandingRequests
)
817 SetFileCompletionNotificationModes(IN HANDLE FileHandle
,
820 if (Flags
& ~(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
| FILE_SKIP_SET_EVENT_ON_HANDLE
))
822 SetLastError(ERROR_INVALID_PARAMETER
);
836 OpenFileById(IN HANDLE hFile
,
837 IN LPFILE_ID_DESCRIPTOR lpFileID
,
838 IN DWORD dwDesiredAccess
,
839 IN DWORD dwShareMode
,
840 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL
,
844 return INVALID_HANDLE_VALUE
;
856 ULARGE_INTEGER TickCount
;
860 TickCount
.HighPart
= (ULONG
)SharedUserData
->TickCount
.High1Time
;
861 TickCount
.LowPart
= SharedUserData
->TickCount
.LowPart
;
863 if (TickCount
.HighPart
== (ULONG
)SharedUserData
->TickCount
.High2Time
) break;
868 return (UInt32x32To64(TickCount
.LowPart
, SharedUserData
->TickCountMultiplier
) >> 24) +
869 (UInt32x32To64(TickCount
.HighPart
, SharedUserData
->TickCountMultiplier
) << 8);