2 * Copyright 2016 Michael Müller
3 * Copyright 2017 Andrey Gusev
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define WIN32_NO_STATUS
30 #include "wine/debug.h"
31 #include "kernelbase.h"
32 #include "wine/heap.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(kernelbase
);
37 BOOL is_wow64
= FALSE
;
39 /***********************************************************************
42 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
44 if (reason
== DLL_PROCESS_ATTACH
)
46 DisableThreadLibraryCalls( hinst
);
47 IsWow64Process( GetCurrentProcess(), &is_wow64
);
49 init_startup_info( NtCurrentTeb()->Peb
->ProcessParameters
);
55 /*************************************************************
58 BOOL WINAPI
DllMainCRTStartup( HANDLE inst
, DWORD reason
, LPVOID reserved
)
60 return DllMain( inst
, reason
, reserved
);
64 /***********************************************************************
65 * AppPolicyGetProcessTerminationMethod (KERNELBASE.@)
67 LONG WINAPI
AppPolicyGetProcessTerminationMethod(HANDLE token
, AppPolicyProcessTerminationMethod
*policy
)
69 FIXME("%p, %p\n", token
, policy
);
72 *policy
= AppPolicyProcessTerminationMethod_ExitProcess
;
77 /***********************************************************************
78 * AppPolicyGetThreadInitializationType (KERNELBASE.@)
80 LONG WINAPI
AppPolicyGetThreadInitializationType(HANDLE token
, AppPolicyThreadInitializationType
*policy
)
82 FIXME("%p, %p\n", token
, policy
);
85 *policy
= AppPolicyThreadInitializationType_None
;
90 /***********************************************************************
91 * AppPolicyGetShowDeveloperDiagnostic (KERNELBASE.@)
93 LONG WINAPI
AppPolicyGetShowDeveloperDiagnostic(HANDLE token
, AppPolicyShowDeveloperDiagnostic
*policy
)
95 FIXME("%p, %p\n", token
, policy
);
98 *policy
= AppPolicyShowDeveloperDiagnostic_ShowUI
;
100 return ERROR_SUCCESS
;
103 /***********************************************************************
104 * AppPolicyGetWindowingModel (KERNELBASE.@)
106 LONG WINAPI
AppPolicyGetWindowingModel(HANDLE token
, AppPolicyWindowingModel
*policy
)
108 FIXME("%p, %p\n", token
, policy
);
111 *policy
= AppPolicyWindowingModel_ClassicDesktop
;
113 return ERROR_SUCCESS
;
116 /***********************************************************************
117 * PerfCreateInstance (KERNELBASE.@)
119 PPERF_COUNTERSET_INSTANCE WINAPI
PerfCreateInstance(HANDLE handle
, LPCGUID guid
,
120 const WCHAR
*name
, ULONG id
)
122 FIXME("%p %s %s %u: stub\n", handle
, debugstr_guid(guid
), debugstr_w(name
), id
);
126 /***********************************************************************
127 * PerfDeleteInstance (KERNELBASE.@)
129 ULONG WINAPI
PerfDeleteInstance(HANDLE provider
, PPERF_COUNTERSET_INSTANCE block
)
131 FIXME("%p %p: stub\n", provider
, block
);
132 return ERROR_CALL_NOT_IMPLEMENTED
;
135 /***********************************************************************
136 * PerfSetCounterSetInfo (KERNELBASE.@)
138 ULONG WINAPI
PerfSetCounterSetInfo(HANDLE handle
, PPERF_COUNTERSET_INFO
template, ULONG size
)
140 FIXME("%p %p %u: stub\n", handle
, template, size
);
141 return ERROR_CALL_NOT_IMPLEMENTED
;
144 /***********************************************************************
145 * PerfSetCounterRefValue (KERNELBASE.@)
147 ULONG WINAPI
PerfSetCounterRefValue(HANDLE provider
, PPERF_COUNTERSET_INSTANCE instance
,
148 ULONG counterid
, void *address
)
150 FIXME("%p %p %u %p: stub\n", provider
, instance
, counterid
, address
);
151 return ERROR_CALL_NOT_IMPLEMENTED
;
154 /***********************************************************************
155 * PerfStartProvider (KERNELBASE.@)
157 ULONG WINAPI
PerfStartProvider(GUID
*guid
, PERFLIBREQUEST callback
, HANDLE
*provider
)
159 FIXME("%s %p %p: stub\n", debugstr_guid(guid
), callback
, provider
);
160 return ERROR_CALL_NOT_IMPLEMENTED
;
163 /***********************************************************************
164 * PerfStartProviderEx (KERNELBASE.@)
166 ULONG WINAPI
PerfStartProviderEx(GUID
*guid
, PPERF_PROVIDER_CONTEXT context
, HANDLE
*provider
)
168 FIXME("%s %p %p: stub\n", debugstr_guid(guid
), context
, provider
);
169 return ERROR_CALL_NOT_IMPLEMENTED
;
172 /***********************************************************************
173 * PerfStopProvider (KERNELBASE.@)
175 ULONG WINAPI
PerfStopProvider(HANDLE handle
)
177 FIXME("%p: stub\n", handle
);
178 return ERROR_CALL_NOT_IMPLEMENTED
;
181 /***********************************************************************
182 * QuirkIsEnabled (KERNELBASE.@)
184 BOOL WINAPI
QuirkIsEnabled(void *arg
)
186 FIXME("(%p): stub\n", arg
);
190 /***********************************************************************
191 * QuirkIsEnabled3 (KERNELBASE.@)
193 BOOL WINAPI
QuirkIsEnabled3(void *unk1
, void *unk2
)
198 FIXME("(%p, %p) stub!\n", unk1
, unk2
);
203 /***********************************************************************
204 * WaitOnAddress (KERNELBASE.@)
206 BOOL WINAPI
WaitOnAddress(volatile void *addr
, void *cmp
, SIZE_T size
, DWORD timeout
)
210 if (timeout
!= INFINITE
)
212 to
.QuadPart
= -(LONGLONG
)timeout
* 10000;
213 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, &to
));
215 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, NULL
));
218 HRESULT WINAPI
QISearch(void *base
, const QITAB
*table
, REFIID riid
, void **obj
)
223 TRACE("%p, %p, %s, %p\n", base
, table
, debugstr_guid(riid
), obj
);
228 for (ptr
= table
; ptr
->piid
; ++ptr
)
230 TRACE("trying (offset %d) %s\n", ptr
->dwOffset
, debugstr_guid(ptr
->piid
));
231 if (IsEqualIID(riid
, ptr
->piid
))
233 unk
= (IUnknown
*)((BYTE
*)base
+ ptr
->dwOffset
);
234 TRACE("matched, returning (%p)\n", unk
);
236 IUnknown_AddRef(unk
);
241 if (IsEqualIID(riid
, &IID_IUnknown
))
243 unk
= (IUnknown
*)((BYTE
*)base
+ table
->dwOffset
);
244 TRACE("returning first for IUnknown (%p)\n", unk
);
246 IUnknown_AddRef(unk
);
250 WARN("Not found %s.\n", debugstr_guid(riid
));
252 return E_NOINTERFACE
;
255 HRESULT WINAPI
GetAcceptLanguagesA(LPSTR langbuf
, DWORD
*buflen
)
257 DWORD buflenW
, convlen
;
261 TRACE("%p, %p, *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
263 if (!langbuf
|| !buflen
|| !*buflen
)
267 langbufW
= heap_alloc(sizeof(WCHAR
) * buflenW
);
268 hr
= GetAcceptLanguagesW(langbufW
, &buflenW
);
272 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
, *buflen
, NULL
, NULL
);
273 convlen
--; /* do not count the terminating 0 */
275 else /* copy partial string anyway */
277 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, *buflen
, langbuf
, *buflen
, NULL
, NULL
);
278 if (convlen
< *buflen
)
280 langbuf
[convlen
] = 0;
281 convlen
--; /* do not count the terminating 0 */
288 *buflen
= buflenW
? convlen
: 0;
294 static HRESULT
lcid_to_rfc1766(LCID lcid
, WCHAR
*rfc1766
, INT len
)
296 WCHAR buffer
[6 /* MAX_RFC1766_NAME */];
297 INT n
= GetLocaleInfoW(lcid
, LOCALE_SISO639LANGNAME
, buffer
, ARRAY_SIZE(buffer
));
302 i
= PRIMARYLANGID(lcid
);
303 if ((((i
== LANG_ENGLISH
) || (i
== LANG_CHINESE
) || (i
== LANG_ARABIC
)) &&
304 (SUBLANGID(lcid
) == SUBLANG_DEFAULT
)) ||
305 (SUBLANGID(lcid
) > SUBLANG_DEFAULT
)) {
308 i
= GetLocaleInfoW(lcid
, LOCALE_SISO3166CTRYNAME
, buffer
+ n
, ARRAY_SIZE(buffer
) - n
);
310 buffer
[n
- 1] = '\0';
315 LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
, buffer
, n
+ i
, rfc1766
, len
);
316 return ((n
+ i
) > len
) ? E_INVALIDARG
: S_OK
;
321 HRESULT WINAPI
GetAcceptLanguagesW(WCHAR
*langbuf
, DWORD
*buflen
)
323 DWORD mystrlen
, mytype
;
330 TRACE("%p, %p, *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
332 if (!langbuf
|| !buflen
|| !*buflen
)
335 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
336 len
= mystrlen
* sizeof(WCHAR
);
337 mystr
= heap_alloc(len
);
339 RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Internet Explorer\\International",
340 0, KEY_QUERY_VALUE
, &mykey
);
341 lres
= RegQueryValueExW(mykey
, L
"AcceptLanguage", 0, &mytype
, (PBYTE
)mystr
, &len
);
343 len
= lstrlenW(mystr
);
345 if (!lres
&& (*buflen
> len
))
347 lstrcpyW(langbuf
, mystr
);
353 /* Did not find a value in the registry or the user buffer is too small */
354 mylcid
= GetUserDefaultLCID();
355 lcid_to_rfc1766(mylcid
, mystr
, mystrlen
);
356 len
= lstrlenW(mystr
);
358 memcpy(langbuf
, mystr
, min(*buflen
, len
+ 1)*sizeof(WCHAR
));
368 return E_NOT_SUFFICIENT_BUFFER
;