Revert r66580 and r66579.
[reactos.git] / reactos / dll / win32 / kernel32 / client / vista.c
1 /*
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>
6 */
7
8 /* INCLUDES *******************************************************************/
9
10 #include <k32.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 #if _WIN32_WINNT >= 0x600
16
17 /* FIXME: Move these RTL declarations to the NDK */
18 NTSTATUS
19 NTAPI
20 RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
21 IN OUT PRTL_CRITICAL_SECTION CriticalSection,
22 IN PLARGE_INTEGER TimeOut OPTIONAL);
23
24 NTSTATUS
25 NTAPI
26 RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
27 IN OUT PRTL_SRWLOCK SRWLock,
28 IN PLARGE_INTEGER TimeOut OPTIONAL,
29 IN ULONG Flags);
30
31 /* PUBLIC FUNCTIONS ***********************************************************/
32
33 /*
34 * @implemented
35 */
36 BOOL
37 WINAPI
38 SleepConditionVariableCS(IN OUT PCONDITION_VARIABLE ConditionVariable,
39 IN OUT PCRITICAL_SECTION CriticalSection,
40 IN DWORD dwMilliseconds)
41 {
42 NTSTATUS Status = 0;
43 LARGE_INTEGER TimeOut;
44 PLARGE_INTEGER TimeOutPtr = NULL;
45
46 if (dwMilliseconds != INFINITE)
47 {
48 TimeOut.QuadPart = dwMilliseconds * -10000LL;
49 TimeOutPtr = &TimeOut;
50 }
51
52 #if 0
53 Status = RtlSleepConditionVariableCS((PRTL_CONDITION_VARIABLE)ConditionVariable,
54 (PRTL_CRITICAL_SECTION)CriticalSection,
55 TimeOutPtr);
56 #endif
57 if (!NT_SUCCESS(Status))
58 {
59 BaseSetLastNTError(Status);
60 return FALSE;
61 }
62
63 return TRUE;
64 }
65
66
67 /*
68 * @implemented
69 */
70 BOOL
71 WINAPI
72 SleepConditionVariableSRW(IN OUT PCONDITION_VARIABLE ConditionVariable,
73 IN OUT PSRWLOCK SRWLock,
74 IN DWORD dwMilliseconds,
75 IN ULONG Flags)
76 {
77 NTSTATUS Status = 0;
78 LARGE_INTEGER TimeOut;
79 PLARGE_INTEGER TimeOutPtr = NULL;
80
81 if (dwMilliseconds != INFINITE)
82 {
83 TimeOut.QuadPart = dwMilliseconds * -10000LL;
84 TimeOutPtr = &TimeOut;
85 }
86
87 #if 0
88 Status = RtlSleepConditionVariableSRW((PRTL_CONDITION_VARIABLE)ConditionVariable,
89 (PRTL_SRWLOCK)SRWLock,
90 TimeOutPtr,
91 Flags);
92 #endif
93 if (!NT_SUCCESS(Status))
94 {
95 BaseSetLastNTError(Status);
96 return FALSE;
97 }
98
99 return TRUE;
100 }
101
102
103 /*
104 * @implemented
105 */
106 BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection,
107 IN DWORD dwSpinCount,
108 IN DWORD flags)
109 {
110 NTSTATUS Status;
111
112 /* FIXME: Flags ignored */
113
114 /* Initialize the critical section */
115 Status = RtlInitializeCriticalSectionAndSpinCount(
116 (PRTL_CRITICAL_SECTION)lpCriticalSection,
117 dwSpinCount);
118 if (!NT_SUCCESS(Status))
119 {
120 /* Set failure code */
121 BaseSetLastNTError(Status);
122 return FALSE;
123 }
124
125 /* Success */
126 return TRUE;
127 }
128
129
130 /*
131 * @implemented
132 */
133 BOOL
134 WINAPI
135 QueryFullProcessImageNameW(HANDLE hProcess,
136 DWORD dwFlags,
137 LPWSTR lpExeName,
138 PDWORD pdwSize)
139 {
140 BYTE Buffer[sizeof(UNICODE_STRING) + MAX_PATH * sizeof(WCHAR)];
141 UNICODE_STRING *DynamicBuffer = NULL;
142 UNICODE_STRING *Result = NULL;
143 NTSTATUS Status;
144 DWORD Needed;
145
146 Status = NtQueryInformationProcess(hProcess,
147 ProcessImageFileName,
148 Buffer,
149 sizeof(Buffer) - sizeof(WCHAR),
150 &Needed);
151 if (Status == STATUS_INFO_LENGTH_MISMATCH)
152 {
153 DynamicBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Needed + sizeof(WCHAR));
154 if (!DynamicBuffer)
155 {
156 BaseSetLastNTError(STATUS_NO_MEMORY);
157 return FALSE;
158 }
159
160 Status = NtQueryInformationProcess(hProcess,
161 ProcessImageFileName,
162 (LPBYTE)DynamicBuffer,
163 Needed,
164 &Needed);
165 Result = DynamicBuffer;
166 }
167 else Result = (PUNICODE_STRING)Buffer;
168
169 if (!NT_SUCCESS(Status)) goto Cleanup;
170
171 if (Result->Length / sizeof(WCHAR) + 1 > *pdwSize)
172 {
173 Status = STATUS_BUFFER_TOO_SMALL;
174 goto Cleanup;
175 }
176
177 *pdwSize = Result->Length / sizeof(WCHAR);
178 memcpy(lpExeName, Result->Buffer, Result->Length);
179 lpExeName[*pdwSize] = 0;
180
181 Cleanup:
182 RtlFreeHeap(RtlGetProcessHeap(), 0, DynamicBuffer);
183
184 if (!NT_SUCCESS(Status))
185 {
186 BaseSetLastNTError(Status);
187 }
188
189 return !Status;
190 }
191
192
193 /*
194 * @implemented
195 */
196 BOOL
197 WINAPI
198 QueryFullProcessImageNameA(HANDLE hProcess,
199 DWORD dwFlags,
200 LPSTR lpExeName,
201 PDWORD pdwSize)
202 {
203 DWORD pdwSizeW = *pdwSize;
204 BOOL Result;
205 LPWSTR lpExeNameW;
206
207 lpExeNameW = RtlAllocateHeap(RtlGetProcessHeap(),
208 HEAP_ZERO_MEMORY,
209 *pdwSize * sizeof(WCHAR));
210 if (!lpExeNameW)
211 {
212 BaseSetLastNTError(STATUS_NO_MEMORY);
213 return FALSE;
214 }
215
216 Result = QueryFullProcessImageNameW(hProcess, dwFlags, lpExeNameW, &pdwSizeW);
217
218 if (Result)
219 Result = (0 != WideCharToMultiByte(CP_ACP, 0,
220 lpExeNameW,
221 -1,
222 lpExeName,
223 *pdwSize,
224 NULL, NULL));
225
226 if (Result)
227 *pdwSize = strlen(lpExeName);
228
229 RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW);
230 return Result;
231 }
232
233
234 /*
235 * @unimplemented
236 */
237 HRESULT
238 WINAPI
239 GetApplicationRecoveryCallback(IN HANDLE hProcess,
240 OUT APPLICATION_RECOVERY_CALLBACK* pRecoveryCallback,
241 OUT PVOID* ppvParameter,
242 PDWORD dwPingInterval,
243 PDWORD dwFlags)
244 {
245 UNIMPLEMENTED;
246 return E_FAIL;
247 }
248
249
250 /*
251 * @unimplemented
252 */
253 HRESULT
254 WINAPI
255 GetApplicationRestart(IN HANDLE hProcess,
256 OUT PWSTR pwzCommandline OPTIONAL,
257 IN OUT PDWORD pcchSize,
258 OUT PDWORD pdwFlags OPTIONAL)
259 {
260 UNIMPLEMENTED;
261 return E_FAIL;
262 }
263
264
265 /*
266 * @unimplemented
267 */
268 VOID
269 WINAPI
270 RecoveryFinished(IN BOOL bSuccess)
271 {
272 UNIMPLEMENTED;
273 }
274
275
276 /*
277 * @unimplemented
278 */
279 HRESULT
280 WINAPI
281 RecoveryInProgress(OUT PBOOL pbCancelled)
282 {
283 UNIMPLEMENTED;
284 return E_FAIL;
285 }
286
287
288 /*
289 * @unimplemented
290 */
291 HRESULT
292 WINAPI
293 RegisterApplicationRecoveryCallback(IN APPLICATION_RECOVERY_CALLBACK pRecoveyCallback,
294 IN PVOID pvParameter OPTIONAL,
295 DWORD dwPingInterval,
296 DWORD dwFlags)
297 {
298 UNIMPLEMENTED;
299 return E_FAIL;
300 }
301
302
303 /*
304 * @unimplemented
305 */
306 HRESULT
307 WINAPI
308 RegisterApplicationRestart(IN PCWSTR pwzCommandline OPTIONAL,
309 IN DWORD dwFlags)
310 {
311 UNIMPLEMENTED;
312 return E_FAIL;
313 }
314
315
316 /*
317 * @implemented
318 */
319 BOOLEAN
320 WINAPI
321 CreateSymbolicLinkW(IN LPCWSTR lpSymlinkFileName,
322 IN LPCWSTR lpTargetFileName,
323 IN DWORD dwFlags)
324 {
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;
332 SIZE_T cbPrintName;
333 SIZE_T cbReparseData;
334 PREPARSE_DATA_BUFFER pReparseData = NULL;
335 PBYTE pBufTail;
336 NTSTATUS Status;
337 ULONG dwCreateOptions;
338 DWORD dwErr;
339
340 if(!lpSymlinkFileName || !lpTargetFileName || (dwFlags | SYMBOLIC_LINK_FLAG_DIRECTORY) != SYMBOLIC_LINK_FLAG_DIRECTORY)
341 {
342 SetLastError(ERROR_INVALID_PARAMETER);
343 return FALSE;
344 }
345
346 if(dwFlags & SYMBOLIC_LINK_FLAG_DIRECTORY)
347 dwCreateOptions = FILE_DIRECTORY_FILE;
348 else
349 dwCreateOptions = FILE_NON_DIRECTORY_FILE;
350
351 switch(RtlDetermineDosPathNameType_U(lpTargetFileName))
352 {
353 case RtlPathTypeUnknown:
354 case RtlPathTypeRooted:
355 case RtlPathTypeRelative:
356 bRelativePath = TRUE;
357 RtlInitUnicodeString(&TargetFileName, lpTargetFileName);
358 break;
359
360 case RtlPathTypeDriveRelative:
361 {
362 LPWSTR FilePart;
363 SIZE_T cchTargetFullFileName;
364
365 cchTargetFullFileName = GetFullPathNameW(lpTargetFileName, 0, NULL, &FilePart);
366
367 if(cchTargetFullFileName == 0)
368 {
369 dwErr = GetLastError();
370 goto Cleanup;
371 }
372
373 lpTargetFullFileName = RtlAllocateHeap(RtlGetProcessHeap(), 0, cchTargetFullFileName * sizeof(WCHAR));
374
375 if(lpTargetFullFileName == NULL)
376 {
377 dwErr = ERROR_NOT_ENOUGH_MEMORY;
378 goto Cleanup;
379 }
380
381 if(GetFullPathNameW(lpTargetFileName, cchTargetFullFileName, lpTargetFullFileName, &FilePart) == 0)
382 {
383 dwErr = GetLastError();
384 goto Cleanup;
385 }
386 }
387
388 lpTargetFileName = lpTargetFullFileName;
389
390 // fallthrough
391
392 case RtlPathTypeUncAbsolute:
393 case RtlPathTypeDriveAbsolute:
394 case RtlPathTypeLocalDevice:
395 case RtlPathTypeRootLocalDevice:
396 default:
397 if(!RtlDosPathNameToNtPathName_U(lpTargetFileName, &TargetFileName, NULL, NULL))
398 {
399 bAllocatedTarget = TRUE;
400 dwErr = ERROR_INVALID_PARAMETER;
401 goto Cleanup;
402 }
403 }
404
405 cbPrintName = wcslen(lpTargetFileName) * sizeof(WCHAR);
406 cbReparseData = FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + TargetFileName.Length + cbPrintName;
407 pReparseData = RtlAllocateHeap(RtlGetProcessHeap(), 0, cbReparseData);
408
409 if(pReparseData == NULL)
410 {
411 dwErr = ERROR_NOT_ENOUGH_MEMORY;
412 goto Cleanup;
413 }
414
415 pBufTail = (PBYTE)(pReparseData->SymbolicLinkReparseBuffer.PathBuffer);
416
417 pReparseData->ReparseTag = (ULONG)IO_REPARSE_TAG_SYMLINK;
418 pReparseData->ReparseDataLength = (USHORT)cbReparseData - REPARSE_DATA_BUFFER_HEADER_SIZE;
419 pReparseData->Reserved = 0;
420
421 pReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
422 pReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength = TargetFileName.Length;
423 pBufTail += pReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset;
424 RtlCopyMemory(pBufTail, TargetFileName.Buffer, TargetFileName.Length);
425
426 pReparseData->SymbolicLinkReparseBuffer.PrintNameOffset = pReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength;
427 pReparseData->SymbolicLinkReparseBuffer.PrintNameLength = (USHORT)cbPrintName;
428 pBufTail += pReparseData->SymbolicLinkReparseBuffer.PrintNameOffset;
429 RtlCopyMemory(pBufTail, lpTargetFileName, cbPrintName);
430
431 pReparseData->SymbolicLinkReparseBuffer.Flags = 0;
432
433 if(bRelativePath)
434 pReparseData->SymbolicLinkReparseBuffer.Flags |= 1; // TODO! give this lone flag a name
435
436 if(!RtlDosPathNameToNtPathName_U(lpSymlinkFileName, &SymlinkFileName, NULL, NULL))
437 {
438 dwErr = ERROR_PATH_NOT_FOUND;
439 goto Cleanup;
440 }
441
442 InitializeObjectAttributes(&ObjectAttributes, &SymlinkFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
443
444 Status = NtCreateFile
445 (
446 &hSymlink,
447 FILE_WRITE_ATTRIBUTES | DELETE | SYNCHRONIZE,
448 &ObjectAttributes,
449 &IoStatusBlock,
450 NULL,
451 FILE_ATTRIBUTE_NORMAL,
452 0,
453 FILE_CREATE,
454 FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT | dwCreateOptions,
455 NULL,
456 0
457 );
458
459 if(!NT_SUCCESS(Status))
460 {
461 dwErr = RtlNtStatusToDosError(Status);
462 goto Cleanup;
463 }
464
465 Status = NtFsControlFile
466 (
467 hSymlink,
468 NULL,
469 NULL,
470 NULL,
471 &IoStatusBlock,
472 FSCTL_SET_REPARSE_POINT,
473 pReparseData,
474 cbReparseData,
475 NULL,
476 0
477 );
478
479 if(!NT_SUCCESS(Status))
480 {
481 FILE_DISPOSITION_INFORMATION DispInfo;
482 DispInfo.DeleteFile = TRUE;
483 NtSetInformationFile(hSymlink, &IoStatusBlock, &DispInfo, sizeof(DispInfo), FileDispositionInformation);
484
485 dwErr = RtlNtStatusToDosError(Status);
486 goto Cleanup;
487 }
488
489 dwErr = NO_ERROR;
490
491 Cleanup:
492 if(hSymlink)
493 NtClose(hSymlink);
494
495 RtlFreeUnicodeString(&SymlinkFileName);
496 if (bAllocatedTarget)
497 {
498 RtlFreeHeap(RtlGetProcessHeap(),
499 0,
500 TargetFileName.Buffer);
501 }
502
503 if(lpTargetFullFileName)
504 RtlFreeHeap(RtlGetProcessHeap(), 0, lpTargetFullFileName);
505
506 if(pReparseData)
507 RtlFreeHeap(RtlGetProcessHeap(), 0, pReparseData);
508
509 if(dwErr)
510 {
511 SetLastError(dwErr);
512 return FALSE;
513 }
514
515 return TRUE;
516 }
517
518
519 /*
520 * @implemented
521 */
522 BOOLEAN
523 NTAPI
524 CreateSymbolicLinkA(IN LPCSTR lpSymlinkFileName,
525 IN LPCSTR lpTargetFileName,
526 IN DWORD dwFlags)
527 {
528 PWCHAR SymlinkW, TargetW;
529 BOOLEAN Ret;
530
531 if(!lpSymlinkFileName || !lpTargetFileName)
532 {
533 SetLastError(ERROR_INVALID_PARAMETER);
534 return FALSE;
535 }
536
537 if (!(SymlinkW = FilenameA2W(lpSymlinkFileName, FALSE)))
538 return FALSE;
539
540 if (!(TargetW = FilenameA2W(lpTargetFileName, TRUE)))
541 return FALSE;
542
543 Ret = CreateSymbolicLinkW(SymlinkW,
544 TargetW,
545 dwFlags);
546
547 RtlFreeHeap(RtlGetProcessHeap(), 0, SymlinkW);
548 RtlFreeHeap(RtlGetProcessHeap(), 0, TargetW);
549
550 return Ret;
551 }
552
553
554 /*
555 * @unimplemented
556 */
557 DWORD
558 WINAPI
559 GetFinalPathNameByHandleW(IN HANDLE hFile,
560 OUT LPWSTR lpszFilePath,
561 IN DWORD cchFilePath,
562 IN DWORD dwFlags)
563 {
564 if (dwFlags & ~(VOLUME_NAME_DOS | VOLUME_NAME_GUID | VOLUME_NAME_NT |
565 VOLUME_NAME_NONE | FILE_NAME_NORMALIZED | FILE_NAME_OPENED))
566 {
567 SetLastError(ERROR_INVALID_PARAMETER);
568 return 0;
569 }
570
571 UNIMPLEMENTED;
572 return 0;
573 }
574
575
576 /*
577 * @implemented
578 */
579 DWORD
580 WINAPI
581 GetFinalPathNameByHandleA(IN HANDLE hFile,
582 OUT LPSTR lpszFilePath,
583 IN DWORD cchFilePath,
584 IN DWORD dwFlags)
585 {
586 WCHAR FilePathW[MAX_PATH];
587 UNICODE_STRING FilePathU;
588 DWORD PrevLastError;
589 DWORD Ret = 0;
590
591 if (cchFilePath != 0 &&
592 cchFilePath > sizeof(FilePathW) / sizeof(FilePathW[0]))
593 {
594 FilePathU.Length = 0;
595 FilePathU.MaximumLength = (USHORT)cchFilePath * sizeof(WCHAR);
596 FilePathU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
597 0,
598 FilePathU.MaximumLength);
599 if (FilePathU.Buffer == NULL)
600 {
601 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
602 return 0;
603 }
604 }
605 else
606 {
607 FilePathU.Length = 0;
608 FilePathU.MaximumLength = sizeof(FilePathW);
609 FilePathU.Buffer = FilePathW;
610 }
611
612 /* save the last error code */
613 PrevLastError = GetLastError();
614 SetLastError(ERROR_SUCCESS);
615
616 /* call the unicode version that does all the work */
617 Ret = GetFinalPathNameByHandleW(hFile,
618 FilePathU.Buffer,
619 cchFilePath,
620 dwFlags);
621
622 if (GetLastError() == ERROR_SUCCESS)
623 {
624 /* no error, restore the last error code and convert the string */
625 SetLastError(PrevLastError);
626
627 Ret = FilenameU2A_FitOrFail(lpszFilePath,
628 cchFilePath,
629 &FilePathU);
630 }
631
632 /* free allocated memory if necessary */
633 if (FilePathU.Buffer != FilePathW)
634 {
635 RtlFreeHeap(RtlGetProcessHeap(),
636 0,
637 FilePathU.Buffer);
638 }
639
640 return Ret;
641 }
642
643
644 /*
645 * @unimplemented
646 */
647 BOOL
648 WINAPI
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)
655 {
656 UNIMPLEMENTED;
657 return FALSE;
658 }
659
660
661 /*
662 * @unimplemented
663 */
664 BOOL
665 WINAPI
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)
672 {
673 UNIMPLEMENTED;
674 return FALSE;
675 }
676
677
678 /*
679 * @unimplemented
680 */
681 BOOL
682 WINAPI
683 SetFileCompletionNotificationModes(IN HANDLE FileHandle,
684 IN UCHAR Flags)
685 {
686 if (Flags & ~(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS | FILE_SKIP_SET_EVENT_ON_HANDLE))
687 {
688 SetLastError(ERROR_INVALID_PARAMETER);
689 return FALSE;
690 }
691
692 UNIMPLEMENTED;
693 return FALSE;
694 }
695
696
697 /*
698 * @unimplemented
699 */
700 HANDLE
701 WINAPI
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,
707 IN DWORD dwFlags)
708 {
709 UNIMPLEMENTED;
710 return INVALID_HANDLE_VALUE;
711 }
712
713
714 /*
715 * @implemented
716 */
717 ULONGLONG
718 WINAPI
719 GetTickCount64(VOID)
720 {
721 ULARGE_INTEGER TickCount;
722
723 while (TRUE)
724 {
725 TickCount.HighPart = (ULONG)SharedUserData->TickCount.High1Time;
726 TickCount.LowPart = SharedUserData->TickCount.LowPart;
727
728 if (TickCount.HighPart == (ULONG)SharedUserData->TickCount.High2Time) break;
729
730 YieldProcessor();
731 }
732
733 return (UInt32x32To64(TickCount.LowPart, SharedUserData->TickCountMultiplier) >> 24) +
734 (UInt32x32To64(TickCount.HighPart, SharedUserData->TickCountMultiplier) << 8);
735 }
736
737 #endif
738
739 /*
740 Vista+ MUI support functions
741
742 References:
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
745
746 More info:
747 http://msdn.microsoft.com/en-us/goglobal/bb978454.aspx
748 http://msdn.microsoft.com/en-us/library/dd319074.aspx
749 */
750
751 /* FUNCTIONS *****************************************************************/
752
753 BOOL
754 WINAPI
755 GetFileMUIInfo(
756 DWORD dwFlags,
757 PCWSTR pcwszFilePath,
758 PFILEMUIINFO pFileMUIInfo,
759 DWORD *pcbFileMUIInfo)
760 {
761 DPRINT1("%x %p %p %p\n", dwFlags, pcwszFilePath, pFileMUIInfo, pcbFileMUIInfo);
762 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
763 return FALSE;
764 }
765
766 /*
767 * @unimplemented
768 */
769 BOOL
770 WINAPI
771 GetFileMUIPath(
772 DWORD dwFlags,
773 PCWSTR pcwszFilePath,
774 PWSTR pwszLanguage,
775 PULONG pcchLanguage,
776 PWSTR pwszFileMUIPath,
777 PULONG pcchFileMUIPath,
778 PULONGLONG pululEnumerator)
779 {
780 DPRINT1("%x %p %p %p %p %p\n", dwFlags, pcwszFilePath, pwszLanguage, pwszFileMUIPath, pcchFileMUIPath, pululEnumerator);
781 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
782 return FALSE;
783 }
784
785 /*
786 * @unimplemented
787 */
788 BOOL
789 WINAPI
790 GetProcessPreferredUILanguages(
791 DWORD dwFlags,
792 PULONG pulNumLanguages,
793 PZZWSTR pwszLanguagesBuffer,
794 PULONG pcchLanguagesBuffer)
795 {
796 DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
797 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
798 return FALSE;
799 }
800
801 /*
802 * @unimplemented
803 */
804 BOOL
805 WINAPI
806 GetSystemPreferredUILanguages(
807 DWORD dwFlags,
808 PULONG pulNumLanguages,
809 PZZWSTR pwszLanguagesBuffer,
810 PULONG pcchLanguagesBuffer)
811 {
812 DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
813 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
814 return FALSE;
815 }
816
817 /*
818 * @unimplemented
819 */
820 BOOL
821 WINAPI
822 GetThreadPreferredUILanguages(
823 DWORD dwFlags,
824 PULONG pulNumLanguages,
825 PZZWSTR pwszLanguagesBuffer,
826 PULONG pcchLanguagesBuffer)
827 {
828 DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
829 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
830 return FALSE;
831 }
832
833 /*
834 * @unimplemented
835 */
836 LANGID
837 WINAPI
838 GetThreadUILanguage(VOID)
839 {
840 UNIMPLEMENTED;
841 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
842 return 0;
843 }
844
845 /*
846 * @unimplemented
847 */
848 BOOL
849 WINAPI
850 GetUILanguageInfo(
851 DWORD dwFlags,
852 PCZZWSTR pwmszLanguage,
853 PZZWSTR pwszFallbackLanguages,
854 PDWORD pcchFallbackLanguages,
855 PDWORD pdwAttributes)
856 {
857 DPRINT1("%x %p %p %p %p\n", dwFlags, pwmszLanguage, pwszFallbackLanguages, pcchFallbackLanguages, pdwAttributes);
858 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
859 return FALSE;
860 }
861
862
863 /*
864 * @unimplemented
865 */
866 BOOL
867 WINAPI
868 GetUserPreferredUILanguages(
869 DWORD dwFlags,
870 PULONG pulNumLanguages,
871 PZZWSTR pwszLanguagesBuffer,
872 PULONG pcchLanguagesBuffer)
873 {
874 DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
875 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
876 return FALSE;
877 }
878
879 /*
880 * @unimplemented
881 */
882 BOOL
883 WINAPI
884 SetProcessPreferredUILanguages(
885 DWORD dwFlags,
886 PCZZWSTR pwszLanguagesBuffer,
887 PULONG pulNumLanguages)
888 {
889 DPRINT1("%x %p %p\n", dwFlags, pwszLanguagesBuffer, pulNumLanguages);
890 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
891 return FALSE;
892 }
893
894
895 /*
896 * @unimplemented
897 */
898 BOOL
899 WINAPI
900 SetThreadPreferredUILanguages(
901 DWORD dwFlags,
902 PCZZWSTR pwszLanguagesBuffer,
903 PULONG pulNumLanguages
904 )
905 {
906 DPRINT1("%x %p %p\n", dwFlags, pwszLanguagesBuffer, pulNumLanguages);
907 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
908 return FALSE;
909 }
910