shell32/tests: Add tests for SHGet/SetKnownFolderPath utilities.
[wine] / dlls / shell32 / appbar.c
1 /*
2  * SHAppBarMessage implementation
3  *
4  * Copyright 2008 Vincent Povirk for CodeWeavers
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "shellapi.h"
32 #include "winuser.h"
33
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(appbar);
38
39 struct appbar_data_msg  /* platform-independent data */
40 {
41     ULONG     hWnd;
42     UINT      uCallbackMessage;
43     UINT      uEdge;
44     RECT      rc;
45     ULONGLONG lParam;
46 };
47
48 struct appbar_cmd
49 {
50     ULONG  return_map;
51     DWORD  return_process;
52     struct appbar_data_msg abd;
53 };
54
55 struct appbar_response
56 {
57     ULONGLONG result;
58     struct appbar_data_msg abd;
59 };
60
61 /*************************************************************************
62  * SHAppBarMessage            [SHELL32.@]
63  */
64 UINT_PTR WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data)
65 {
66     struct appbar_cmd command;
67     struct appbar_response* response;
68     HANDLE return_map;
69     LPVOID return_view;
70     HWND appbarmsg_window;
71     COPYDATASTRUCT cds;
72     DWORD_PTR msg_result;
73     static const WCHAR classname[] = {'W','i','n','e','A','p','p','B','a','r',0};
74
75     UINT_PTR ret = 0;
76
77     TRACE("msg=%d, data={cb=%d, hwnd=%p}\n", msg, data->cbSize, data->hWnd);
78
79     /* These members are message dependent */
80     switch(msg)
81     {
82     case ABM_NEW:
83         TRACE("callback: %x\n", data->uCallbackMessage);
84         break;
85
86     case ABM_GETAUTOHIDEBAR:
87         TRACE("edge: %d\n", data->uEdge);
88         break;
89
90     case ABM_QUERYPOS:
91     case ABM_SETPOS:
92         TRACE("edge: %d, rc: %s\n", data->uEdge, wine_dbgstr_rect(&data->rc));
93         break;
94
95     case ABM_GETTASKBARPOS:
96         TRACE("rc: %s\n", wine_dbgstr_rect(&data->rc));
97         break;
98
99     case ABM_SETAUTOHIDEBAR:
100         TRACE("edge: %d, lParam: %lx\n", data->uEdge, data->lParam);
101         break;
102
103     default:
104         FIXME("unknown msg: %d\n", msg);
105         break;
106     }
107
108     if (data->cbSize < sizeof(APPBARDATA))
109     {
110         WARN("data at %p is too small\n", data);
111         return FALSE;
112     }
113
114     command.abd.hWnd = HandleToLong( data->hWnd );
115     command.abd.uCallbackMessage = data->uCallbackMessage;
116     command.abd.uEdge = data->uEdge;
117     command.abd.rc = data->rc;
118     command.abd.lParam = data->lParam;
119
120     return_map = CreateFileMappingW(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(struct appbar_response), NULL);
121     if (return_map == NULL)
122     {
123         ERR("couldn't create file mapping\n");
124         return 0;
125     }
126     command.return_map = HandleToUlong( return_map );
127
128     command.return_process = GetCurrentProcessId();
129
130     appbarmsg_window = FindWindowW(classname, NULL);
131     if (appbarmsg_window == NULL)
132     {
133         ERR("couldn't find appbar window\n");
134         CloseHandle(return_map);
135         return 0;
136     }
137
138     cds.dwData = msg;
139     cds.cbData = sizeof(command);
140     cds.lpData = &command;
141
142     SendMessageTimeoutW(appbarmsg_window, WM_COPYDATA, (WPARAM)data->hWnd, (LPARAM)&cds, SMTO_BLOCK, INFINITE, &msg_result);
143
144     return_view = MapViewOfFile(return_map, FILE_MAP_READ, 0, 0, sizeof(struct appbar_response));
145     if (return_view == NULL)
146     {
147         ERR("MapViewOfFile failed\n");
148         CloseHandle(return_map);
149         return 0;
150     }
151
152     response = return_view;
153
154     ret = response->result;
155     if (ret)
156     {
157         data->hWnd = UlongToHandle( response->abd.hWnd );
158         data->uCallbackMessage = response->abd.uCallbackMessage;
159         data->uEdge = response->abd.uEdge;
160         data->rc = response->abd.rc;
161         data->lParam = response->abd.lParam;
162     }
163     UnmapViewOfFile(return_view);
164
165     CloseHandle(return_map);
166
167     return ret;
168 }