2 * Implementation of the OLEACC dll
4 * Copyright 2003 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "oleacc_private.h"
32 #include "wine/unicode.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(oleacc
);
37 static const WCHAR lresult_atom_prefix
[] = {'w','i','n','e','_','o','l','e','a','c','c',':'};
39 static HINSTANCE oleacc_handle
= 0;
41 const char *debugstr_variant(const VARIANT
*v
)
47 return wine_dbg_sprintf("{V_BYREF -> %s}", debugstr_variant(V_BYREF(v
)));
55 return wine_dbg_sprintf("{VT_I2: %d}", V_I2(v
));
57 return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v
));
59 return wine_dbg_sprintf("{VT_UI4: %u}", V_UI4(v
));
61 return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v
));
63 return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v
)));
65 return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v
));
67 return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v
));
69 return wine_dbg_sprintf("{vt %d}", V_VT(v
));
73 int convert_child_id(VARIANT
*v
)
79 FIXME("unhandled child ID variant type: %d\n", V_VT(v
));
84 HRESULT WINAPI
CreateStdAccessibleObject( HWND hwnd
, LONG idObject
,
85 REFIID riidInterface
, void** ppvObject
)
89 TRACE("%p %d %s %p\n", hwnd
, idObject
,
90 debugstr_guid( riidInterface
), ppvObject
);
91 if(GetClassNameW(hwnd
, class_name
, sizeof(class_name
)/sizeof(WCHAR
)))
92 FIXME("unhandled window class: %s\n", debugstr_w(class_name
));
96 return create_client_object(hwnd
, riidInterface
, ppvObject
);
98 return create_window_object(hwnd
, riidInterface
, ppvObject
);
100 FIXME("unhandled object id: %d\n", idObject
);
105 HRESULT WINAPI
ObjectFromLresult( LRESULT result
, REFIID riid
, WPARAM wParam
, void **ppObject
)
107 WCHAR atom_str
[sizeof(lresult_atom_prefix
)/sizeof(WCHAR
)+3*8+3];
108 HANDLE server_proc
, server_mapping
, mapping
;
116 TRACE("%ld %s %ld %p\n", result
, debugstr_guid(riid
), wParam
, ppObject
);
119 FIXME("unsupported wParam = %lx\n", wParam
);
125 if(result
!= (ATOM
)result
)
128 if(!GlobalGetAtomNameW(result
, atom_str
, sizeof(atom_str
)/sizeof(WCHAR
)))
130 if(memcmp(atom_str
, lresult_atom_prefix
, sizeof(lresult_atom_prefix
)))
132 p
= atom_str
+ sizeof(lresult_atom_prefix
)/sizeof(WCHAR
);
133 proc_id
= strtoulW(p
, &p
, 16);
136 server_mapping
= ULongToHandle( strtoulW(p
+1, &p
, 16) );
139 size
= strtoulW(p
+1, &p
, 16);
143 server_proc
= OpenProcess(PROCESS_DUP_HANDLE
, FALSE
, proc_id
);
147 if(!DuplicateHandle(server_proc
, server_mapping
, GetCurrentProcess(), &mapping
,
148 0, FALSE
, DUPLICATE_CLOSE_SOURCE
|DUPLICATE_SAME_ACCESS
))
150 CloseHandle(server_proc
);
151 GlobalDeleteAtom(result
);
153 view
= MapViewOfFile(mapping
, FILE_MAP_READ
, 0, 0, 0);
154 CloseHandle(mapping
);
158 data
= GlobalAlloc(GMEM_FIXED
, size
);
159 memcpy(data
, view
, size
);
160 UnmapViewOfFile(view
);
162 return E_OUTOFMEMORY
;
164 hr
= CreateStreamOnHGlobal(data
, TRUE
, &stream
);
170 hr
= CoUnmarshalInterface(stream
, riid
, ppObject
);
171 IStream_Release(stream
);
175 LRESULT WINAPI
LresultFromObject( REFIID riid
, WPARAM wParam
, LPUNKNOWN pAcc
)
177 static const WCHAR atom_fmt
[] = {'%','0','8','x',':','%','0','8','x',':','%','0','8','x',0};
178 static const LARGE_INTEGER seek_zero
= {{0}};
180 WCHAR atom_str
[sizeof(lresult_atom_prefix
)/sizeof(WCHAR
)+3*8+3];
188 TRACE("%s %ld %p\n", debugstr_guid(riid
), wParam
, pAcc
);
191 FIXME("unsupported wParam = %lx\n", wParam
);
196 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
200 hr
= CoMarshalInterface(stream
, riid
, pAcc
, MSHCTX_LOCAL
, NULL
, MSHLFLAGS_NORMAL
);
202 IStream_Release(stream
);
206 hr
= IStream_Seek(stream
, seek_zero
, STREAM_SEEK_SET
, NULL
);
208 IStream_Release(stream
);
212 hr
= IStream_Stat(stream
, &stat
, STATFLAG_NONAME
);
214 CoReleaseMarshalData(stream
);
215 IStream_Release(stream
);
217 }else if(stat
.cbSize
.u
.HighPart
) {
218 FIXME("stream size to big\n");
219 CoReleaseMarshalData(stream
);
220 IStream_Release(stream
);
224 mapping
= CreateFileMappingW(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
,
225 stat
.cbSize
.u
.HighPart
, stat
.cbSize
.u
.LowPart
, NULL
);
227 CoReleaseMarshalData(stream
);
228 IStream_Release(stream
);
232 view
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
234 CloseHandle(mapping
);
235 CoReleaseMarshalData(stream
);
236 IStream_Release(stream
);
240 hr
= IStream_Read(stream
, view
, stat
.cbSize
.u
.LowPart
, NULL
);
241 UnmapViewOfFile(view
);
243 CloseHandle(mapping
);
244 hr
= IStream_Seek(stream
, seek_zero
, STREAM_SEEK_SET
, NULL
);
246 CoReleaseMarshalData(stream
);
247 IStream_Release(stream
);
252 memcpy(atom_str
, lresult_atom_prefix
, sizeof(lresult_atom_prefix
));
253 sprintfW(atom_str
+sizeof(lresult_atom_prefix
)/sizeof(WCHAR
),
254 atom_fmt
, GetCurrentProcessId(), HandleToUlong(mapping
), stat
.cbSize
.u
.LowPart
);
255 atom
= GlobalAddAtomW(atom_str
);
257 CloseHandle(mapping
);
258 hr
= IStream_Seek(stream
, seek_zero
, STREAM_SEEK_SET
, NULL
);
260 CoReleaseMarshalData(stream
);
261 IStream_Release(stream
);
265 IStream_Release(stream
);
269 HRESULT WINAPI
AccessibleObjectFromPoint( POINT ptScreen
, IAccessible
** ppacc
, VARIANT
* pvarChild
)
271 FIXME("{%d,%d} %p %p: stub\n", ptScreen
.x
, ptScreen
.y
, ppacc
, pvarChild
);
275 HRESULT WINAPI
AccessibleObjectFromWindow( HWND hwnd
, DWORD dwObjectID
,
276 REFIID riid
, void** ppvObject
)
278 TRACE("%p %d %s %p\n", hwnd
, dwObjectID
,
279 debugstr_guid( riid
), ppvObject
);
288 lres
= SendMessageW(hwnd
, WM_GETOBJECT
, 0xffffffff, dwObjectID
);
292 return ObjectFromLresult(lres
, riid
, 0, ppvObject
);
295 return CreateStdAccessibleObject(hwnd
, dwObjectID
, riid
, ppvObject
);
298 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
,
301 TRACE("%p, %d, %p\n", hinstDLL
, fdwReason
, lpvReserved
);
305 case DLL_PROCESS_ATTACH
:
306 oleacc_handle
= hinstDLL
;
307 DisableThreadLibraryCalls(hinstDLL
);
313 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID iid
, void **ppv
)
315 FIXME("%s %s %p: stub\n", debugstr_guid(rclsid
), debugstr_guid(iid
), ppv
);
319 HRESULT WINAPI
DllRegisterServer(void)
325 HRESULT WINAPI
DllUnregisterServer(void)
331 void WINAPI
GetOleaccVersionInfo(DWORD
* pVersion
, DWORD
* pBuild
)
333 *pVersion
= MAKELONG(0,7); /* Windows 7 version of oleacc: 7.0.0.0 */
334 *pBuild
= MAKELONG(0,0);
337 HANDLE WINAPI
GetProcessHandleFromHwnd(HWND hwnd
)
343 if(!GetWindowThreadProcessId(hwnd
, &proc_id
))
345 return OpenProcess(PROCESS_DUP_HANDLE
| PROCESS_VM_OPERATION
|
346 PROCESS_VM_READ
| PROCESS_VM_WRITE
| SYNCHRONIZE
, TRUE
, proc_id
);
349 UINT WINAPI
GetRoleTextW(DWORD role
, LPWSTR lpRole
, UINT rolemax
)
354 TRACE("%u %p %u\n", role
, lpRole
, rolemax
);
356 /* return role text length */
358 return LoadStringW(oleacc_handle
, role
, (LPWSTR
)&resptr
, 0);
360 ret
= LoadStringW(oleacc_handle
, role
, lpRole
, rolemax
);
362 if(rolemax
> 0) lpRole
[0] = '\0';
369 UINT WINAPI
GetRoleTextA(DWORD role
, LPSTR lpRole
, UINT rolemax
)
374 TRACE("%u %p %u\n", role
, lpRole
, rolemax
);
376 if(lpRole
&& !rolemax
)
379 length
= GetRoleTextW(role
, NULL
, 0);
381 if(lpRole
&& rolemax
)
386 roletextW
= HeapAlloc(GetProcessHeap(), 0, (length
+ 1)*sizeof(WCHAR
));
390 GetRoleTextW(role
, roletextW
, length
+ 1);
392 length
= WideCharToMultiByte( CP_ACP
, 0, roletextW
, -1, NULL
, 0, NULL
, NULL
);
395 HeapFree(GetProcessHeap(), 0, roletextW
);
399 WideCharToMultiByte( CP_ACP
, 0, roletextW
, -1, lpRole
, rolemax
, NULL
, NULL
);
401 if(rolemax
< length
){
402 lpRole
[rolemax
-1] = '\0';
406 HeapFree(GetProcessHeap(), 0, roletextW
);
411 UINT WINAPI
GetStateTextW(DWORD state_bit
, WCHAR
*state_str
, UINT state_str_len
)
415 TRACE("%x %p %u\n", state_bit
, state_str
, state_str_len
);
417 if(state_bit
& ~(STATE_SYSTEM_VALID
| STATE_SYSTEM_HASPOPUP
)) {
418 if(state_str
&& state_str_len
)
423 state_id
= IDS_STATE_NORMAL
;
430 UINT ret
= LoadStringW(oleacc_handle
, state_id
, state_str
, state_str_len
);
431 if(!ret
&& state_str_len
)
436 return LoadStringW(oleacc_handle
, state_id
, (WCHAR
*)&tmp
, 0);
441 UINT WINAPI
GetStateTextA(DWORD state_bit
, CHAR
*state_str
, UINT state_str_len
)
445 TRACE("%x %p %u\n", state_bit
, state_str
, state_str_len
);
447 if(state_str
&& !state_str_len
)
450 if(state_bit
& ~(STATE_SYSTEM_VALID
| STATE_SYSTEM_HASPOPUP
)) {
451 if(state_str
&& state_str_len
)
456 state_id
= IDS_STATE_NORMAL
;
463 UINT ret
= LoadStringA(oleacc_handle
, state_id
, state_str
, state_str_len
);
464 if(!ret
&& state_str_len
)
469 return LoadStringA(oleacc_handle
, state_id
, tmp
, sizeof(tmp
));