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
28 #include "wine/debug.h"
29 #include "wine/heap.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(kernelbase
);
35 /*************************************************************
38 BOOL WINAPI
DllMainCRTStartup( HANDLE inst
, DWORD reason
, LPVOID reserved
)
44 /***********************************************************************
45 * AppPolicyGetProcessTerminationMethod (KERNELBASE.@)
47 LONG WINAPI
AppPolicyGetProcessTerminationMethod(HANDLE token
, AppPolicyProcessTerminationMethod
*policy
)
49 FIXME("%p, %p\n", token
, policy
);
52 *policy
= AppPolicyProcessTerminationMethod_ExitProcess
;
57 /***********************************************************************
58 * AppPolicyGetThreadInitializationType (KERNELBASE.@)
60 LONG WINAPI
AppPolicyGetThreadInitializationType(HANDLE token
, AppPolicyThreadInitializationType
*policy
)
62 FIXME("%p, %p\n", token
, policy
);
65 *policy
= AppPolicyThreadInitializationType_None
;
70 /***********************************************************************
71 * AppPolicyGetShowDeveloperDiagnostic (KERNELBASE.@)
73 LONG WINAPI
AppPolicyGetShowDeveloperDiagnostic(HANDLE token
, AppPolicyShowDeveloperDiagnostic
*policy
)
75 FIXME("%p, %p\n", token
, policy
);
78 *policy
= AppPolicyShowDeveloperDiagnostic_ShowUI
;
83 /***********************************************************************
84 * AppPolicyGetWindowingModel (KERNELBASE.@)
86 LONG WINAPI
AppPolicyGetWindowingModel(HANDLE token
, AppPolicyWindowingModel
*policy
)
88 FIXME("%p, %p\n", token
, policy
);
91 *policy
= AppPolicyWindowingModel_ClassicDesktop
;
96 /***********************************************************************
97 * QuirkIsEnabled (KERNELBASE.@)
99 BOOL WINAPI
QuirkIsEnabled(void *arg
)
101 FIXME("(%p): stub\n", arg
);
105 /***********************************************************************
106 * QuirkIsEnabled3 (KERNELBASE.@)
108 BOOL WINAPI
QuirkIsEnabled3(void *unk1
, void *unk2
)
113 FIXME("(%p, %p) stub!\n", unk1
, unk2
);
118 /***********************************************************************
119 * WaitOnAddress (KERNELBASE.@)
121 BOOL WINAPI
WaitOnAddress(volatile void *addr
, void *cmp
, SIZE_T size
, DWORD timeout
)
126 if (timeout
!= INFINITE
)
128 to
.QuadPart
= -(LONGLONG
)timeout
* 10000;
129 status
= RtlWaitOnAddress((const void *)addr
, cmp
, size
, &to
);
132 status
= RtlWaitOnAddress((const void *)addr
, cmp
, size
, NULL
);
134 if (status
!= STATUS_SUCCESS
)
136 SetLastError( RtlNtStatusToDosError(status
) );
143 HRESULT WINAPI
QISearch(void *base
, const QITAB
*table
, REFIID riid
, void **obj
)
148 TRACE("%p, %p, %s, %p\n", base
, table
, debugstr_guid(riid
), obj
);
153 for (ptr
= table
; ptr
->piid
; ++ptr
)
155 TRACE("trying (offset %d) %s\n", ptr
->dwOffset
, debugstr_guid(ptr
->piid
));
156 if (IsEqualIID(riid
, ptr
->piid
))
158 unk
= (IUnknown
*)((BYTE
*)base
+ ptr
->dwOffset
);
159 TRACE("matched, returning (%p)\n", unk
);
161 IUnknown_AddRef(unk
);
166 if (IsEqualIID(riid
, &IID_IUnknown
))
168 unk
= (IUnknown
*)((BYTE
*)base
+ table
->dwOffset
);
169 TRACE("returning first for IUnknown (%p)\n", unk
);
171 IUnknown_AddRef(unk
);
175 WARN("Not found %s.\n", debugstr_guid(riid
));
177 return E_NOINTERFACE
;
180 HRESULT WINAPI
GetAcceptLanguagesA(LPSTR langbuf
, DWORD
*buflen
)
182 DWORD buflenW
, convlen
;
186 TRACE("%p, %p, *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
188 if (!langbuf
|| !buflen
|| !*buflen
)
192 langbufW
= heap_alloc(sizeof(WCHAR
) * buflenW
);
193 hr
= GetAcceptLanguagesW(langbufW
, &buflenW
);
197 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
, *buflen
, NULL
, NULL
);
198 convlen
--; /* do not count the terminating 0 */
200 else /* copy partial string anyway */
202 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, *buflen
, langbuf
, *buflen
, NULL
, NULL
);
203 if (convlen
< *buflen
)
205 langbuf
[convlen
] = 0;
206 convlen
--; /* do not count the terminating 0 */
213 *buflen
= buflenW
? convlen
: 0;
219 static HRESULT
lcid_to_rfc1766(LCID lcid
, WCHAR
*rfc1766
, INT len
)
221 WCHAR buffer
[6 /* MAX_RFC1766_NAME */];
222 INT n
= GetLocaleInfoW(lcid
, LOCALE_SISO639LANGNAME
, buffer
, ARRAY_SIZE(buffer
));
227 i
= PRIMARYLANGID(lcid
);
228 if ((((i
== LANG_ENGLISH
) || (i
== LANG_CHINESE
) || (i
== LANG_ARABIC
)) &&
229 (SUBLANGID(lcid
) == SUBLANG_DEFAULT
)) ||
230 (SUBLANGID(lcid
) > SUBLANG_DEFAULT
)) {
233 i
= GetLocaleInfoW(lcid
, LOCALE_SISO3166CTRYNAME
, buffer
+ n
, ARRAY_SIZE(buffer
) - n
);
235 buffer
[n
- 1] = '\0';
240 LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
, buffer
, n
+ i
, rfc1766
, len
);
241 return ((n
+ i
) > len
) ? E_INVALIDARG
: S_OK
;
246 HRESULT WINAPI
GetAcceptLanguagesW(WCHAR
*langbuf
, DWORD
*buflen
)
248 static const WCHAR keyW
[] = {
249 'S','o','f','t','w','a','r','e','\\',
250 'M','i','c','r','o','s','o','f','t','\\',
251 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
252 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
253 static const WCHAR valueW
[] = {'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
254 DWORD mystrlen
, mytype
;
261 TRACE("%p, %p, *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
263 if (!langbuf
|| !buflen
|| !*buflen
)
266 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
267 len
= mystrlen
* sizeof(WCHAR
);
268 mystr
= heap_alloc(len
);
270 RegOpenKeyW(HKEY_CURRENT_USER
, keyW
, &mykey
);
271 lres
= RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &len
);
273 len
= lstrlenW(mystr
);
275 if (!lres
&& (*buflen
> len
))
277 lstrcpyW(langbuf
, mystr
);
283 /* Did not find a value in the registry or the user buffer is too small */
284 mylcid
= GetUserDefaultLCID();
285 lcid_to_rfc1766(mylcid
, mystr
, mystrlen
);
286 len
= lstrlenW(mystr
);
288 memcpy(langbuf
, mystr
, min(*buflen
, len
+ 1)*sizeof(WCHAR
));
298 return E_NOT_SUFFICIENT_BUFFER
;