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