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_vista.h>
11
12 #if _WIN32_WINNT != _WIN32_WINNT_VISTA
13 #error "This file must be compiled with _WIN32_WINNT == _WIN32_WINNT_VISTA"
14 #endif
15
16 // This is defined only in ntifs.h
17 #define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
18
19 #define NDEBUG
20 #include <debug.h>
21
22 /* PUBLIC FUNCTIONS ***********************************************************/
23
24 /*
25 * @implemented
26 */
27 BOOL
28 WINAPI
QueryFullProcessImageNameW(HANDLE hProcess,DWORD dwFlags,LPWSTR lpExeName,PDWORD pdwSize)29 QueryFullProcessImageNameW(HANDLE hProcess,
30 DWORD dwFlags,
31 LPWSTR lpExeName,
32 PDWORD pdwSize)
33 {
34 BYTE Buffer[sizeof(UNICODE_STRING) + MAX_PATH * sizeof(WCHAR)];
35 UNICODE_STRING *DynamicBuffer = NULL;
36 UNICODE_STRING *Result = NULL;
37 NTSTATUS Status;
38 DWORD Needed;
39
40 Status = NtQueryInformationProcess(hProcess,
41 ProcessImageFileName,
42 Buffer,
43 sizeof(Buffer) - sizeof(WCHAR),
44 &Needed);
45 if (Status == STATUS_INFO_LENGTH_MISMATCH)
46 {
47 DynamicBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Needed + sizeof(WCHAR));
48 if (!DynamicBuffer)
49 {
50 BaseSetLastNTError(STATUS_NO_MEMORY);
51 return FALSE;
52 }
53
54 Status = NtQueryInformationProcess(hProcess,
55 ProcessImageFileName,
56 (LPBYTE)DynamicBuffer,
57 Needed,
58 &Needed);
59 Result = DynamicBuffer;
60 }
61 else Result = (PUNICODE_STRING)Buffer;
62
63 if (!NT_SUCCESS(Status)) goto Cleanup;
64
65 if (Result->Length / sizeof(WCHAR) + 1 > *pdwSize)
66 {
67 Status = STATUS_BUFFER_TOO_SMALL;
68 goto Cleanup;
69 }
70
71 *pdwSize = Result->Length / sizeof(WCHAR);
72 memcpy(lpExeName, Result->Buffer, Result->Length);
73 lpExeName[*pdwSize] = 0;
74
75 Cleanup:
76 RtlFreeHeap(RtlGetProcessHeap(), 0, DynamicBuffer);
77
78 if (!NT_SUCCESS(Status))
79 {
80 BaseSetLastNTError(Status);
81 }
82
83 return !Status;
84 }
85
86
87 /*
88 * @implemented
89 */
90 BOOL
91 WINAPI
QueryFullProcessImageNameA(HANDLE hProcess,DWORD dwFlags,LPSTR lpExeName,PDWORD pdwSize)92 QueryFullProcessImageNameA(HANDLE hProcess,
93 DWORD dwFlags,
94 LPSTR lpExeName,
95 PDWORD pdwSize)
96 {
97 DWORD pdwSizeW = *pdwSize;
98 BOOL Result;
99 LPWSTR lpExeNameW;
100
101 lpExeNameW = RtlAllocateHeap(RtlGetProcessHeap(),
102 HEAP_ZERO_MEMORY,
103 *pdwSize * sizeof(WCHAR));
104 if (!lpExeNameW)
105 {
106 BaseSetLastNTError(STATUS_NO_MEMORY);
107 return FALSE;
108 }
109
110 Result = QueryFullProcessImageNameW(hProcess, dwFlags, lpExeNameW, &pdwSizeW);
111
112 if (Result)
113 Result = (0 != WideCharToMultiByte(CP_ACP, 0,
114 lpExeNameW,
115 -1,
116 lpExeName,
117 *pdwSize,
118 NULL, NULL));
119
120 if (Result)
121 *pdwSize = strlen(lpExeName);
122
123 RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW);
124 return Result;
125 }
126
127
128 /*
129 * @unimplemented
130 */
131 HRESULT
132 WINAPI
GetApplicationRecoveryCallback(IN HANDLE hProcess,OUT APPLICATION_RECOVERY_CALLBACK * pRecoveryCallback,OUT PVOID * ppvParameter,PDWORD dwPingInterval,PDWORD dwFlags)133 GetApplicationRecoveryCallback(IN HANDLE hProcess,
134 OUT APPLICATION_RECOVERY_CALLBACK* pRecoveryCallback,
135 OUT PVOID* ppvParameter,
136 PDWORD dwPingInterval,
137 PDWORD dwFlags)
138 {
139 UNIMPLEMENTED;
140 return E_FAIL;
141 }
142
143
144 /*
145 * @unimplemented
146 */
147 HRESULT
148 WINAPI
GetApplicationRestart(IN HANDLE hProcess,OUT PWSTR pwzCommandline OPTIONAL,IN OUT PDWORD pcchSize,OUT PDWORD pdwFlags OPTIONAL)149 GetApplicationRestart(IN HANDLE hProcess,
150 OUT PWSTR pwzCommandline OPTIONAL,
151 IN OUT PDWORD pcchSize,
152 OUT PDWORD pdwFlags OPTIONAL)
153 {
154 UNIMPLEMENTED;
155 return E_FAIL;
156 }
157
158
159 /*
160 * @unimplemented
161 */
162 VOID
163 WINAPI
ApplicationRecoveryFinished(IN BOOL bSuccess)164 ApplicationRecoveryFinished(IN BOOL bSuccess)
165 {
166 UNIMPLEMENTED;
167 }
168
169
170 /*
171 * @unimplemented
172 */
173 HRESULT
174 WINAPI
ApplicationRecoveryInProgress(OUT PBOOL pbCancelled)175 ApplicationRecoveryInProgress(OUT PBOOL pbCancelled)
176 {
177 UNIMPLEMENTED;
178 return E_FAIL;
179 }
180
181
182 /*
183 * @unimplemented
184 */
185 HRESULT
186 WINAPI
RegisterApplicationRecoveryCallback(IN APPLICATION_RECOVERY_CALLBACK pRecoveryCallback,IN PVOID pvParameter OPTIONAL,DWORD dwPingInterval,DWORD dwFlags)187 RegisterApplicationRecoveryCallback(IN APPLICATION_RECOVERY_CALLBACK pRecoveryCallback,
188 IN PVOID pvParameter OPTIONAL,
189 DWORD dwPingInterval,
190 DWORD dwFlags)
191 {
192 UNIMPLEMENTED;
193 return E_FAIL;
194 }
195
196
197 /*
198 * @unimplemented
199 */
200 HRESULT
201 WINAPI
RegisterApplicationRestart(IN PCWSTR pwzCommandline OPTIONAL,IN DWORD dwFlags)202 RegisterApplicationRestart(IN PCWSTR pwzCommandline OPTIONAL,
203 IN DWORD dwFlags)
204 {
205 UNIMPLEMENTED;
206 return E_FAIL;
207 }
208
209
210 /*
211 * @implemented
212 */
213 BOOLEAN
214 WINAPI
CreateSymbolicLinkW(IN LPCWSTR lpSymlinkFileName,IN LPCWSTR lpTargetFileName,IN DWORD dwFlags)215 CreateSymbolicLinkW(IN LPCWSTR lpSymlinkFileName,
216 IN LPCWSTR lpTargetFileName,
217 IN DWORD dwFlags)
218 {
219 IO_STATUS_BLOCK IoStatusBlock;
220 OBJECT_ATTRIBUTES ObjectAttributes;
221 HANDLE hSymlink = NULL;
222 UNICODE_STRING SymlinkFileName = { 0, 0, NULL };
223 UNICODE_STRING TargetFileName = { 0, 0, NULL };
224 BOOLEAN bAllocatedTarget = FALSE, bRelativePath = FALSE;
225 LPWSTR lpTargetFullFileName = NULL;
226 SIZE_T cbPrintName;
227 SIZE_T cbReparseData;
228 PREPARSE_DATA_BUFFER pReparseData = NULL;
229 PBYTE pBufTail;
230 NTSTATUS Status;
231 ULONG dwCreateOptions;
232 DWORD dwErr;
233
234 if(!lpSymlinkFileName || !lpTargetFileName || (dwFlags | SYMBOLIC_LINK_FLAG_DIRECTORY) != SYMBOLIC_LINK_FLAG_DIRECTORY)
235 {
236 SetLastError(ERROR_INVALID_PARAMETER);
237 return FALSE;
238 }
239
240 if(dwFlags & SYMBOLIC_LINK_FLAG_DIRECTORY)
241 dwCreateOptions = FILE_DIRECTORY_FILE;
242 else
243 dwCreateOptions = FILE_NON_DIRECTORY_FILE;
244
245 switch(RtlDetermineDosPathNameType_U(lpTargetFileName))
246 {
247 case RtlPathTypeUnknown:
248 case RtlPathTypeRooted:
249 case RtlPathTypeRelative:
250 bRelativePath = TRUE;
251 RtlInitUnicodeString(&TargetFileName, lpTargetFileName);
252 break;
253
254 case RtlPathTypeDriveRelative:
255 {
256 LPWSTR FilePart;
257 SIZE_T cchTargetFullFileName;
258
259 cchTargetFullFileName = GetFullPathNameW(lpTargetFileName, 0, NULL, &FilePart);
260
261 if(cchTargetFullFileName == 0)
262 {
263 dwErr = GetLastError();
264 goto Cleanup;
265 }
266
267 lpTargetFullFileName = RtlAllocateHeap(RtlGetProcessHeap(), 0, cchTargetFullFileName * sizeof(WCHAR));
268
269 if(lpTargetFullFileName == NULL)
270 {
271 dwErr = ERROR_NOT_ENOUGH_MEMORY;
272 goto Cleanup;
273 }
274
275 if(GetFullPathNameW(lpTargetFileName, cchTargetFullFileName, lpTargetFullFileName, &FilePart) == 0)
276 {
277 dwErr = GetLastError();
278 goto Cleanup;
279 }
280 }
281
282 lpTargetFileName = lpTargetFullFileName;
283
284 // fallthrough
285
286 case RtlPathTypeUncAbsolute:
287 case RtlPathTypeDriveAbsolute:
288 case RtlPathTypeLocalDevice:
289 case RtlPathTypeRootLocalDevice:
290 default:
291 if(!RtlDosPathNameToNtPathName_U(lpTargetFileName, &TargetFileName, NULL, NULL))
292 {
293 bAllocatedTarget = TRUE;
294 dwErr = ERROR_INVALID_PARAMETER;
295 goto Cleanup;
296 }
297 }
298
299 cbPrintName = wcslen(lpTargetFileName) * sizeof(WCHAR);
300 cbReparseData = FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + TargetFileName.Length + cbPrintName;
301 pReparseData = RtlAllocateHeap(RtlGetProcessHeap(), 0, cbReparseData);
302
303 if(pReparseData == NULL)
304 {
305 dwErr = ERROR_NOT_ENOUGH_MEMORY;
306 goto Cleanup;
307 }
308
309 pBufTail = (PBYTE)(pReparseData->SymbolicLinkReparseBuffer.PathBuffer);
310
311 pReparseData->ReparseTag = (ULONG)IO_REPARSE_TAG_SYMLINK;
312 pReparseData->ReparseDataLength = (USHORT)cbReparseData - REPARSE_DATA_BUFFER_HEADER_SIZE;
313 pReparseData->Reserved = 0;
314
315 pReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
316 pReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength = TargetFileName.Length;
317 pBufTail += pReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset;
318 RtlCopyMemory(pBufTail, TargetFileName.Buffer, TargetFileName.Length);
319
320 pReparseData->SymbolicLinkReparseBuffer.PrintNameOffset = pReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength;
321 pReparseData->SymbolicLinkReparseBuffer.PrintNameLength = (USHORT)cbPrintName;
322 pBufTail += pReparseData->SymbolicLinkReparseBuffer.PrintNameOffset;
323 RtlCopyMemory(pBufTail, lpTargetFileName, cbPrintName);
324
325 pReparseData->SymbolicLinkReparseBuffer.Flags = 0;
326
327 if(bRelativePath)
328 pReparseData->SymbolicLinkReparseBuffer.Flags |= 1; // TODO! give this lone flag a name
329
330 if(!RtlDosPathNameToNtPathName_U(lpSymlinkFileName, &SymlinkFileName, NULL, NULL))
331 {
332 dwErr = ERROR_PATH_NOT_FOUND;
333 goto Cleanup;
334 }
335
336 InitializeObjectAttributes(&ObjectAttributes, &SymlinkFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
337
338 Status = NtCreateFile
339 (
340 &hSymlink,
341 FILE_WRITE_ATTRIBUTES | DELETE | SYNCHRONIZE,
342 &ObjectAttributes,
343 &IoStatusBlock,
344 NULL,
345 FILE_ATTRIBUTE_NORMAL,
346 0,
347 FILE_CREATE,
348 FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT | dwCreateOptions,
349 NULL,
350 0
351 );
352
353 if(!NT_SUCCESS(Status))
354 {
355 dwErr = RtlNtStatusToDosError(Status);
356 goto Cleanup;
357 }
358
359 Status = NtFsControlFile
360 (
361 hSymlink,
362 NULL,
363 NULL,
364 NULL,
365 &IoStatusBlock,
366 FSCTL_SET_REPARSE_POINT,
367 pReparseData,
368 cbReparseData,
369 NULL,
370 0
371 );
372
373 if(!NT_SUCCESS(Status))
374 {
375 FILE_DISPOSITION_INFORMATION DispInfo;
376 DispInfo.DeleteFile = TRUE;
377 NtSetInformationFile(hSymlink, &IoStatusBlock, &DispInfo, sizeof(DispInfo), FileDispositionInformation);
378
379 dwErr = RtlNtStatusToDosError(Status);
380 goto Cleanup;
381 }
382
383 dwErr = NO_ERROR;
384
385 Cleanup:
386 if(hSymlink)
387 NtClose(hSymlink);
388
389 RtlFreeUnicodeString(&SymlinkFileName);
390 if (bAllocatedTarget)
391 {
392 RtlFreeHeap(RtlGetProcessHeap(),
393 0,
394 TargetFileName.Buffer);
395 }
396
397 if(lpTargetFullFileName)
398 RtlFreeHeap(RtlGetProcessHeap(), 0, lpTargetFullFileName);
399
400 if(pReparseData)
401 RtlFreeHeap(RtlGetProcessHeap(), 0, pReparseData);
402
403 if(dwErr)
404 {
405 SetLastError(dwErr);
406 return FALSE;
407 }
408
409 return TRUE;
410 }
411
412
413 /*
414 * @implemented
415 */
416 BOOLEAN
417 NTAPI
CreateSymbolicLinkA(IN LPCSTR lpSymlinkFileName,IN LPCSTR lpTargetFileName,IN DWORD dwFlags)418 CreateSymbolicLinkA(IN LPCSTR lpSymlinkFileName,
419 IN LPCSTR lpTargetFileName,
420 IN DWORD dwFlags)
421 {
422 PWCHAR SymlinkW, TargetW;
423 BOOLEAN Ret;
424
425 if(!lpSymlinkFileName || !lpTargetFileName)
426 {
427 SetLastError(ERROR_INVALID_PARAMETER);
428 return FALSE;
429 }
430
431 if (!(SymlinkW = FilenameA2W(lpSymlinkFileName, FALSE)))
432 return FALSE;
433
434 if (!(TargetW = FilenameA2W(lpTargetFileName, TRUE)))
435 return FALSE;
436
437 Ret = CreateSymbolicLinkW(SymlinkW,
438 TargetW,
439 dwFlags);
440
441 RtlFreeHeap(RtlGetProcessHeap(), 0, SymlinkW);
442 RtlFreeHeap(RtlGetProcessHeap(), 0, TargetW);
443
444 return Ret;
445 }
446
447
448 /*
449 * @unimplemented
450 */
451 DWORD
452 WINAPI
GetFinalPathNameByHandleW(IN HANDLE hFile,OUT LPWSTR lpszFilePath,IN DWORD cchFilePath,IN DWORD dwFlags)453 GetFinalPathNameByHandleW(IN HANDLE hFile,
454 OUT LPWSTR lpszFilePath,
455 IN DWORD cchFilePath,
456 IN DWORD dwFlags)
457 {
458 if (dwFlags & ~(VOLUME_NAME_DOS | VOLUME_NAME_GUID | VOLUME_NAME_NT |
459 VOLUME_NAME_NONE | FILE_NAME_NORMALIZED | FILE_NAME_OPENED))
460 {
461 SetLastError(ERROR_INVALID_PARAMETER);
462 return 0;
463 }
464
465 UNIMPLEMENTED;
466 return 0;
467 }
468
469
470 /*
471 * @implemented
472 */
473 DWORD
474 WINAPI
GetFinalPathNameByHandleA(IN HANDLE hFile,OUT LPSTR lpszFilePath,IN DWORD cchFilePath,IN DWORD dwFlags)475 GetFinalPathNameByHandleA(IN HANDLE hFile,
476 OUT LPSTR lpszFilePath,
477 IN DWORD cchFilePath,
478 IN DWORD dwFlags)
479 {
480 WCHAR FilePathW[MAX_PATH];
481 UNICODE_STRING FilePathU;
482 DWORD PrevLastError;
483 DWORD Ret = 0;
484
485 if (cchFilePath != 0 &&
486 cchFilePath > sizeof(FilePathW) / sizeof(FilePathW[0]))
487 {
488 FilePathU.Length = 0;
489 FilePathU.MaximumLength = (USHORT)cchFilePath * sizeof(WCHAR);
490 FilePathU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
491 0,
492 FilePathU.MaximumLength);
493 if (FilePathU.Buffer == NULL)
494 {
495 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
496 return 0;
497 }
498 }
499 else
500 {
501 FilePathU.Length = 0;
502 FilePathU.MaximumLength = sizeof(FilePathW);
503 FilePathU.Buffer = FilePathW;
504 }
505
506 /* save the last error code */
507 PrevLastError = GetLastError();
508 SetLastError(ERROR_SUCCESS);
509
510 /* call the unicode version that does all the work */
511 Ret = GetFinalPathNameByHandleW(hFile,
512 FilePathU.Buffer,
513 cchFilePath,
514 dwFlags);
515
516 if (GetLastError() == ERROR_SUCCESS)
517 {
518 /* no error, restore the last error code and convert the string */
519 SetLastError(PrevLastError);
520
521 Ret = FilenameU2A_FitOrFail(lpszFilePath,
522 cchFilePath,
523 &FilePathU);
524 }
525
526 /* free allocated memory if necessary */
527 if (FilePathU.Buffer != FilePathW)
528 {
529 RtlFreeHeap(RtlGetProcessHeap(),
530 0,
531 FilePathU.Buffer);
532 }
533
534 return Ret;
535 }
536
537
538 /*
539 * @unimplemented
540 */
541 BOOL
542 WINAPI
SetFileBandwidthReservation(IN HANDLE hFile,IN DWORD nPeriodMilliseconds,IN DWORD nBytesPerPeriod,IN BOOL bDiscardable,OUT LPDWORD lpTransferSize,OUT LPDWORD lpNumOutstandingRequests)543 SetFileBandwidthReservation(IN HANDLE hFile,
544 IN DWORD nPeriodMilliseconds,
545 IN DWORD nBytesPerPeriod,
546 IN BOOL bDiscardable,
547 OUT LPDWORD lpTransferSize,
548 OUT LPDWORD lpNumOutstandingRequests)
549 {
550 UNIMPLEMENTED;
551 return FALSE;
552 }
553
554
555 /*
556 * @unimplemented
557 */
558 BOOL
559 WINAPI
GetFileBandwidthReservation(IN HANDLE hFile,OUT LPDWORD lpPeriodMilliseconds,OUT LPDWORD lpBytesPerPeriod,OUT LPBOOL pDiscardable,OUT LPDWORD lpTransferSize,OUT LPDWORD lpNumOutstandingRequests)560 GetFileBandwidthReservation(IN HANDLE hFile,
561 OUT LPDWORD lpPeriodMilliseconds,
562 OUT LPDWORD lpBytesPerPeriod,
563 OUT LPBOOL pDiscardable,
564 OUT LPDWORD lpTransferSize,
565 OUT LPDWORD lpNumOutstandingRequests)
566 {
567 UNIMPLEMENTED;
568 return FALSE;
569 }
570
571
572 /*
573 * @unimplemented
574 */
575 HANDLE
576 WINAPI
OpenFileById(IN HANDLE hFile,IN LPFILE_ID_DESCRIPTOR lpFileID,IN DWORD dwDesiredAccess,IN DWORD dwShareMode,IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL,IN DWORD dwFlags)577 OpenFileById(IN HANDLE hFile,
578 IN LPFILE_ID_DESCRIPTOR lpFileID,
579 IN DWORD dwDesiredAccess,
580 IN DWORD dwShareMode,
581 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL,
582 IN DWORD dwFlags)
583 {
584 UNIMPLEMENTED;
585 return INVALID_HANDLE_VALUE;
586 }
587
588
589
590 /*
591 Vista+ MUI support functions
592
593 References:
594 Evolution of MUI Support across Windows Versions: http://msdn.microsoft.com/en-US/library/ee264317.aspx
595 Comparing Windows XP Professional Multilingual Options: http://technet.microsoft.com/en-us/library/bb457045.aspx
596
597 More info:
598 http://msdn.microsoft.com/en-us/goglobal/bb978454.aspx
599 http://msdn.microsoft.com/en-us/library/dd319074.aspx
600 */
601
602 /* FUNCTIONS *****************************************************************/
603
604 BOOL
605 WINAPI
GetFileMUIInfo(DWORD dwFlags,PCWSTR pcwszFilePath,PFILEMUIINFO pFileMUIInfo,DWORD * pcbFileMUIInfo)606 GetFileMUIInfo(
607 DWORD dwFlags,
608 PCWSTR pcwszFilePath,
609 PFILEMUIINFO pFileMUIInfo,
610 DWORD *pcbFileMUIInfo)
611 {
612 DPRINT1("%x %p %p %p\n", dwFlags, pcwszFilePath, pFileMUIInfo, pcbFileMUIInfo);
613 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
614 return FALSE;
615 }
616
617 /*
618 * @unimplemented
619 */
620 BOOL
621 WINAPI
GetFileMUIPath(DWORD dwFlags,PCWSTR pcwszFilePath,PWSTR pwszLanguage,PULONG pcchLanguage,PWSTR pwszFileMUIPath,PULONG pcchFileMUIPath,PULONGLONG pululEnumerator)622 GetFileMUIPath(
623 DWORD dwFlags,
624 PCWSTR pcwszFilePath,
625 PWSTR pwszLanguage,
626 PULONG pcchLanguage,
627 PWSTR pwszFileMUIPath,
628 PULONG pcchFileMUIPath,
629 PULONGLONG pululEnumerator)
630 {
631 DPRINT1("%x %p %p %p %p %p\n", dwFlags, pcwszFilePath, pwszLanguage, pwszFileMUIPath, pcchFileMUIPath, pululEnumerator);
632 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
633 return FALSE;
634 }
635
636 /*
637 * @unimplemented
638 */
639 #if 0 // This is Windows 7+
640 BOOL
641 WINAPI
642 GetProcessPreferredUILanguages(
643 DWORD dwFlags,
644 PULONG pulNumLanguages,
645 PZZWSTR pwszLanguagesBuffer,
646 PULONG pcchLanguagesBuffer)
647 {
648 DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
649 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
650 return FALSE;
651 }
652 #endif
653
654 /*
655 * @unimplemented
656 */
657 BOOL
658 WINAPI
GetSystemPreferredUILanguages(DWORD dwFlags,PULONG pulNumLanguages,PZZWSTR pwszLanguagesBuffer,PULONG pcchLanguagesBuffer)659 GetSystemPreferredUILanguages(
660 DWORD dwFlags,
661 PULONG pulNumLanguages,
662 PZZWSTR pwszLanguagesBuffer,
663 PULONG pcchLanguagesBuffer)
664 {
665 DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
666 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
667 return FALSE;
668 }
669
670 /*
671 * @unimplemented
672 */
673 BOOL
674 WINAPI
GetThreadPreferredUILanguages(DWORD dwFlags,PULONG pulNumLanguages,PZZWSTR pwszLanguagesBuffer,PULONG pcchLanguagesBuffer)675 GetThreadPreferredUILanguages(
676 DWORD dwFlags,
677 PULONG pulNumLanguages,
678 PZZWSTR pwszLanguagesBuffer,
679 PULONG pcchLanguagesBuffer)
680 {
681 DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
682 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
683 return FALSE;
684 }
685
686 /*
687 * @unimplemented
688 */
689 LANGID
690 WINAPI
GetThreadUILanguage(VOID)691 GetThreadUILanguage(VOID)
692 {
693 UNIMPLEMENTED;
694 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
695 return 0;
696 }
697
698 /*
699 * @unimplemented
700 */
701 BOOL
702 WINAPI
GetUILanguageInfo(DWORD dwFlags,PCZZWSTR pwmszLanguage,PZZWSTR pwszFallbackLanguages,PDWORD pcchFallbackLanguages,PDWORD pdwAttributes)703 GetUILanguageInfo(
704 DWORD dwFlags,
705 PCZZWSTR pwmszLanguage,
706 PZZWSTR pwszFallbackLanguages,
707 PDWORD pcchFallbackLanguages,
708 PDWORD pdwAttributes)
709 {
710 DPRINT1("%x %p %p %p %p\n", dwFlags, pwmszLanguage, pwszFallbackLanguages, pcchFallbackLanguages, pdwAttributes);
711 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
712 return FALSE;
713 }
714
715
716 /*
717 * @unimplemented
718 */
719 BOOL
720 WINAPI
GetUserPreferredUILanguages(DWORD dwFlags,PULONG pulNumLanguages,PZZWSTR pwszLanguagesBuffer,PULONG pcchLanguagesBuffer)721 GetUserPreferredUILanguages(
722 DWORD dwFlags,
723 PULONG pulNumLanguages,
724 PZZWSTR pwszLanguagesBuffer,
725 PULONG pcchLanguagesBuffer)
726 {
727 DPRINT1("%x %p %p %p\n", dwFlags, pulNumLanguages, pwszLanguagesBuffer, pcchLanguagesBuffer);
728 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
729 return FALSE;
730 }
731
732 /*
733 * @unimplemented
734 */
735 #if 0 // Tis is Windows 7+
736 BOOL
737 WINAPI
738 SetProcessPreferredUILanguages(
739 DWORD dwFlags,
740 PCZZWSTR pwszLanguagesBuffer,
741 PULONG pulNumLanguages)
742 {
743 DPRINT1("%x %p %p\n", dwFlags, pwszLanguagesBuffer, pulNumLanguages);
744 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
745 return FALSE;
746 }
747 #endif
748
749 /*
750 * @unimplemented
751 */
752 BOOL
753 WINAPI
SetThreadPreferredUILanguages(DWORD dwFlags,PCZZWSTR pwszLanguagesBuffer,PULONG pulNumLanguages)754 SetThreadPreferredUILanguages(
755 DWORD dwFlags,
756 PCZZWSTR pwszLanguagesBuffer,
757 PULONG pulNumLanguages
758 )
759 {
760 DPRINT1("%x %p %p\n", dwFlags, pwszLanguagesBuffer, pulNumLanguages);
761 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
762 return FALSE;
763 }
764
765