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
29 #include "wine/debug.h"
30 #include "wine/heap.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(kernelbase
);
36 /*************************************************************
39 BOOL WINAPI
DllMainCRTStartup( HANDLE inst
, DWORD reason
, LPVOID reserved
)
45 /***********************************************************************
46 * AppPolicyGetProcessTerminationMethod (KERNELBASE.@)
48 LONG WINAPI
AppPolicyGetProcessTerminationMethod(HANDLE token
, AppPolicyProcessTerminationMethod
*policy
)
50 FIXME("%p, %p\n", token
, policy
);
53 *policy
= AppPolicyProcessTerminationMethod_ExitProcess
;
58 /***********************************************************************
59 * AppPolicyGetThreadInitializationType (KERNELBASE.@)
61 LONG WINAPI
AppPolicyGetThreadInitializationType(HANDLE token
, AppPolicyThreadInitializationType
*policy
)
63 FIXME("%p, %p\n", token
, policy
);
66 *policy
= AppPolicyThreadInitializationType_None
;
71 /***********************************************************************
72 * AppPolicyGetShowDeveloperDiagnostic (KERNELBASE.@)
74 LONG WINAPI
AppPolicyGetShowDeveloperDiagnostic(HANDLE token
, AppPolicyShowDeveloperDiagnostic
*policy
)
76 FIXME("%p, %p\n", token
, policy
);
79 *policy
= AppPolicyShowDeveloperDiagnostic_ShowUI
;
84 /***********************************************************************
85 * AppPolicyGetWindowingModel (KERNELBASE.@)
87 LONG WINAPI
AppPolicyGetWindowingModel(HANDLE token
, AppPolicyWindowingModel
*policy
)
89 FIXME("%p, %p\n", token
, policy
);
92 *policy
= AppPolicyWindowingModel_ClassicDesktop
;
97 /***********************************************************************
98 * PerfCreateInstance (KERNELBASE.@)
100 PPERF_COUNTERSET_INSTANCE WINAPI
PerfCreateInstance(HANDLE handle
, LPCGUID guid
,
101 const WCHAR
*name
, ULONG id
)
103 FIXME("%p %s %s %u: stub\n", handle
, debugstr_guid(guid
), debugstr_w(name
), id
);
107 /***********************************************************************
108 * PerfDeleteInstance (KERNELBASE.@)
110 ULONG WINAPI
PerfDeleteInstance(HANDLE provider
, PPERF_COUNTERSET_INSTANCE block
)
112 FIXME("%p %p: stub\n", provider
, block
);
113 return ERROR_CALL_NOT_IMPLEMENTED
;
116 /***********************************************************************
117 * PerfSetCounterSetInfo (KERNELBASE.@)
119 ULONG WINAPI
PerfSetCounterSetInfo(HANDLE handle
, PPERF_COUNTERSET_INFO
template, ULONG size
)
121 FIXME("%p %p %u: stub\n", handle
, template, size
);
122 return ERROR_CALL_NOT_IMPLEMENTED
;
125 /***********************************************************************
126 * PerfSetCounterRefValue (KERNELBASE.@)
128 ULONG WINAPI
PerfSetCounterRefValue(HANDLE provider
, PPERF_COUNTERSET_INSTANCE instance
,
129 ULONG counterid
, void *address
)
131 FIXME("%p %p %u %p: stub\n", provider
, instance
, counterid
, address
);
132 return ERROR_CALL_NOT_IMPLEMENTED
;
135 /***********************************************************************
136 * PerfStartProvider (KERNELBASE.@)
138 ULONG WINAPI
PerfStartProvider(GUID
*guid
, PERFLIBREQUEST callback
, HANDLE
*provider
)
140 FIXME("%s %p %p: stub\n", debugstr_guid(guid
), callback
, provider
);
141 return ERROR_CALL_NOT_IMPLEMENTED
;
144 /***********************************************************************
145 * PerfStartProviderEx (KERNELBASE.@)
147 ULONG WINAPI
PerfStartProviderEx(GUID
*guid
, PPERF_PROVIDER_CONTEXT context
, HANDLE
*provider
)
149 FIXME("%s %p %p: stub\n", debugstr_guid(guid
), context
, provider
);
150 return ERROR_CALL_NOT_IMPLEMENTED
;
153 /***********************************************************************
154 * PerfStopProvider (KERNELBASE.@)
156 ULONG WINAPI
PerfStopProvider(HANDLE handle
)
158 FIXME("%p: stub\n", handle
);
159 return ERROR_CALL_NOT_IMPLEMENTED
;
162 /***********************************************************************
163 * QuirkIsEnabled (KERNELBASE.@)
165 BOOL WINAPI
QuirkIsEnabled(void *arg
)
167 FIXME("(%p): stub\n", arg
);
171 /***********************************************************************
172 * QuirkIsEnabled3 (KERNELBASE.@)
174 BOOL WINAPI
QuirkIsEnabled3(void *unk1
, void *unk2
)
179 FIXME("(%p, %p) stub!\n", unk1
, unk2
);
184 /***********************************************************************
185 * WaitOnAddress (KERNELBASE.@)
187 BOOL WINAPI
WaitOnAddress(volatile void *addr
, void *cmp
, SIZE_T size
, DWORD timeout
)
192 if (timeout
!= INFINITE
)
194 to
.QuadPart
= -(LONGLONG
)timeout
* 10000;
195 status
= RtlWaitOnAddress((const void *)addr
, cmp
, size
, &to
);
198 status
= RtlWaitOnAddress((const void *)addr
, cmp
, size
, NULL
);
200 if (status
!= STATUS_SUCCESS
)
202 SetLastError( RtlNtStatusToDosError(status
) );
209 HRESULT WINAPI
QISearch(void *base
, const QITAB
*table
, REFIID riid
, void **obj
)
214 TRACE("%p, %p, %s, %p\n", base
, table
, debugstr_guid(riid
), obj
);
219 for (ptr
= table
; ptr
->piid
; ++ptr
)
221 TRACE("trying (offset %d) %s\n", ptr
->dwOffset
, debugstr_guid(ptr
->piid
));
222 if (IsEqualIID(riid
, ptr
->piid
))
224 unk
= (IUnknown
*)((BYTE
*)base
+ ptr
->dwOffset
);
225 TRACE("matched, returning (%p)\n", unk
);
227 IUnknown_AddRef(unk
);
232 if (IsEqualIID(riid
, &IID_IUnknown
))
234 unk
= (IUnknown
*)((BYTE
*)base
+ table
->dwOffset
);
235 TRACE("returning first for IUnknown (%p)\n", unk
);
237 IUnknown_AddRef(unk
);
241 WARN("Not found %s.\n", debugstr_guid(riid
));
243 return E_NOINTERFACE
;
246 HRESULT WINAPI
GetAcceptLanguagesA(LPSTR langbuf
, DWORD
*buflen
)
248 DWORD buflenW
, convlen
;
252 TRACE("%p, %p, *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
254 if (!langbuf
|| !buflen
|| !*buflen
)
258 langbufW
= heap_alloc(sizeof(WCHAR
) * buflenW
);
259 hr
= GetAcceptLanguagesW(langbufW
, &buflenW
);
263 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
, *buflen
, NULL
, NULL
);
264 convlen
--; /* do not count the terminating 0 */
266 else /* copy partial string anyway */
268 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, *buflen
, langbuf
, *buflen
, NULL
, NULL
);
269 if (convlen
< *buflen
)
271 langbuf
[convlen
] = 0;
272 convlen
--; /* do not count the terminating 0 */
279 *buflen
= buflenW
? convlen
: 0;
285 static HRESULT
lcid_to_rfc1766(LCID lcid
, WCHAR
*rfc1766
, INT len
)
287 WCHAR buffer
[6 /* MAX_RFC1766_NAME */];
288 INT n
= GetLocaleInfoW(lcid
, LOCALE_SISO639LANGNAME
, buffer
, ARRAY_SIZE(buffer
));
293 i
= PRIMARYLANGID(lcid
);
294 if ((((i
== LANG_ENGLISH
) || (i
== LANG_CHINESE
) || (i
== LANG_ARABIC
)) &&
295 (SUBLANGID(lcid
) == SUBLANG_DEFAULT
)) ||
296 (SUBLANGID(lcid
) > SUBLANG_DEFAULT
)) {
299 i
= GetLocaleInfoW(lcid
, LOCALE_SISO3166CTRYNAME
, buffer
+ n
, ARRAY_SIZE(buffer
) - n
);
301 buffer
[n
- 1] = '\0';
306 LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
, buffer
, n
+ i
, rfc1766
, len
);
307 return ((n
+ i
) > len
) ? E_INVALIDARG
: S_OK
;
312 HRESULT WINAPI
GetAcceptLanguagesW(WCHAR
*langbuf
, DWORD
*buflen
)
314 static const WCHAR keyW
[] = {
315 'S','o','f','t','w','a','r','e','\\',
316 'M','i','c','r','o','s','o','f','t','\\',
317 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
318 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
319 static const WCHAR valueW
[] = {'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
320 DWORD mystrlen
, mytype
;
327 TRACE("%p, %p, *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
329 if (!langbuf
|| !buflen
|| !*buflen
)
332 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
333 len
= mystrlen
* sizeof(WCHAR
);
334 mystr
= heap_alloc(len
);
336 RegOpenKeyExW(HKEY_CURRENT_USER
, keyW
, 0, KEY_QUERY_VALUE
, &mykey
);
337 lres
= RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &len
);
339 len
= lstrlenW(mystr
);
341 if (!lres
&& (*buflen
> len
))
343 lstrcpyW(langbuf
, mystr
);
349 /* Did not find a value in the registry or the user buffer is too small */
350 mylcid
= GetUserDefaultLCID();
351 lcid_to_rfc1766(mylcid
, mystr
, mystrlen
);
352 len
= lstrlenW(mystr
);
354 memcpy(langbuf
, mystr
, min(*buflen
, len
+ 1)*sizeof(WCHAR
));
364 return E_NOT_SUFFICIENT_BUFFER
;