1 /*
2  * ATL test program
3  *
4  * Copyright 2010 Marcus Meissner
5  *
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 #include <stdio.h>
24 
25 #define COBJMACROS
26 
27 #include <wine/atlbase.h>
28 #include <wine/atlwin.h>
29 
30 #include <wine/test.h>
31 
32 #define MAXSIZE 512
33 static void test_StructSize(void)
34 {
35     _ATL_MODULEW *tst;
36     HRESULT hres;
37     int i;
38 
39     tst = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAXSIZE);
40 
41     for (i=0;i<MAXSIZE;i++) {
42         tst->cbSize = i;
43         hres = AtlModuleInit(tst, NULL, NULL);
44 
45         switch (i)  {
46         case FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer):
47         case sizeof(_ATL_MODULEW):
48 #ifdef _WIN64
49         case sizeof(_ATL_MODULEW) + sizeof(void *):
50 #endif
51             ok (hres == S_OK, "AtlModuleInit with %d failed (0x%x).\n", i, (int)hres);
52             break;
53         default:
54             ok (FAILED(hres), "AtlModuleInit with %d succeeded? (0x%x).\n", i, (int)hres);
55             break;
56         }
57     }
58 
59     HeapFree (GetProcessHeap(), 0, tst);
60 }
61 
62 static void test_winmodule(void)
63 {
64     _AtlCreateWndData create_data[3];
65     _ATL_MODULEW winmod;
66     void *p;
67     HRESULT hres;
68 
69     winmod.cbSize = sizeof(winmod);
70     winmod.m_pCreateWndList = (void*)0xdeadbeef;
71     winmod.m_csWindowCreate.LockCount = 0xdeadbeef;
72     hres = AtlModuleInit(&winmod, NULL, NULL);
73     ok(hres == S_OK, "AtlModuleInit failed: %08x\n", hres);
74     ok(!winmod.m_pCreateWndList, "winmod.m_pCreateWndList = %p\n", winmod.m_pCreateWndList);
75     ok(winmod.m_csWindowCreate.LockCount == -1, "winmod.m_csWindowCreate.LockCount = %d\n",
76        winmod.m_csWindowCreate.LockCount);
77 
78     AtlModuleAddCreateWndData(&winmod, create_data, (void*)0xdead0001);
79     ok(winmod.m_pCreateWndList == create_data, "winmod.m_pCreateWndList != create_data\n");
80     ok(create_data[0].m_pThis == (void*)0xdead0001, "unexpected create_data[0].m_pThis %p\n", create_data[0].m_pThis);
81     ok(create_data[0].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[0].m_dwThreadID %x\n",
82        create_data[0].m_dwThreadID);
83     ok(!create_data[0].m_pNext, "unexpected create_data[0].m_pNext %p\n", create_data[0].m_pNext);
84 
85     AtlModuleAddCreateWndData(&winmod, create_data+1, (void*)0xdead0002);
86     ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
87     ok(create_data[1].m_pThis == (void*)0xdead0002, "unexpected create_data[1].m_pThis %p\n", create_data[1].m_pThis);
88     ok(create_data[1].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[1].m_dwThreadID %x\n",
89        create_data[1].m_dwThreadID);
90     ok(create_data[1].m_pNext == create_data, "unexpected create_data[1].m_pNext %p\n", create_data[1].m_pNext);
91 
92     AtlModuleAddCreateWndData(&winmod, create_data+2, (void*)0xdead0003);
93     ok(winmod.m_pCreateWndList == create_data+2, "winmod.m_pCreateWndList != create_data\n");
94     ok(create_data[2].m_pThis == (void*)0xdead0003, "unexpected create_data[2].m_pThis %p\n", create_data[2].m_pThis);
95     ok(create_data[2].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[2].m_dwThreadID %x\n",
96        create_data[2].m_dwThreadID);
97     ok(create_data[2].m_pNext == create_data+1, "unexpected create_data[2].m_pNext %p\n", create_data[2].m_pNext);
98 
99     p = AtlModuleExtractCreateWndData(&winmod);
100     ok(p == (void*)0xdead0003, "unexpected AtlModuleExtractCreateWndData result %p\n", p);
101     ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
102     ok(create_data[2].m_pNext == create_data+1, "unexpected create_data[2].m_pNext %p\n", create_data[2].m_pNext);
103 
104     create_data[1].m_dwThreadID = 0xdeadbeef;
105 
106     p = AtlModuleExtractCreateWndData(&winmod);
107     ok(p == (void*)0xdead0001, "unexpected AtlModuleExtractCreateWndData result %p\n", p);
108     ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
109     ok(!create_data[0].m_pNext, "unexpected create_data[0].m_pNext %p\n", create_data[0].m_pNext);
110     ok(!create_data[1].m_pNext, "unexpected create_data[1].m_pNext %p\n", create_data[1].m_pNext);
111 
112     p = AtlModuleExtractCreateWndData(&winmod);
113     ok(!p, "unexpected AtlModuleExtractCreateWndData result %p\n", p);
114     ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
115 }
116 
117 static void test_winclassinfo(void)
118 {
119     _ATL_MODULEW winmod;
120     HRESULT hres;
121     int len, expectedLen;
122     ATOM atom;
123     WNDPROC wndProc;
124     _ATL_WNDCLASSINFOW wci =
125     {
126         /* .m_wc = */
127         {
128             sizeof(WNDCLASSEXW),
129             CS_VREDRAW | CS_HREDRAW,
130             DefWindowProcW,
131             0,
132             0,
133             NULL,
134             NULL,
135             LoadCursorW(NULL, (LPCWSTR)IDC_ARROW),
136             (HBRUSH)(COLOR_BTNFACE + 1),
137             NULL,
138             NULL,   /* LPCSTR lpszClassName; <-- We force ATL class name generation */
139             NULL
140         },
141         /* .m_lpszOrigName  = */ NULL,
142         /* .pWndProc        = */ NULL,
143         /* .m_lpszCursorID  = */ (LPCWSTR)IDC_ARROW,
144         /* .m_bSystemCursor = */ TRUE,
145         /* .m_atom          = */ 0,
146         /* .m_szAutoName    = */ L""
147     };
148 
149     winmod.cbSize = sizeof(winmod);
150     winmod.m_pCreateWndList = (void*)0xdeadbeef;
151     hres = AtlModuleInit(&winmod, NULL, NULL);
152     ok(hres == S_OK, "AtlModuleInit failed: %08x\n", hres);
153     ok(!winmod.m_pCreateWndList, "winmod.m_pCreateWndList = %p\n", winmod.m_pCreateWndList);
154 
155     atom = AtlModuleRegisterWndClassInfoW(&winmod, &wci, &wndProc);
156     ok(atom, "AtlModuleRegisterWndClassInfoA failed: %08x\n", atom);
157     ok(atom == wci.m_atom, "(atom = %08x) is != than (wci.m_atom = %08x)\n", atom, wci.m_atom);
158 
159     ok(wcsncmp(wci.m_szAutoName, L"ATL:", 4) == 0, "wci.m_szAutoName = '%ls', expected starting with 'ATL:'\n", wci.m_szAutoName);
160 
161     len = wcslen(wci.m_szAutoName);
162     expectedLen = sizeof("ATL:") + sizeof(void *) * 2 - 1;
163     ok(len == expectedLen, "wci.m_szAutoName has length %d, expected length %d\n", len, expectedLen);
164 }
165 
166 static DWORD_PTR cb_val;
167 
168 static void WINAPI term_callback(DWORD_PTR dw)
169 {
170     cb_val = dw;
171 }
172 
173 static void test_term(void)
174 {
175     _ATL_MODULEW test;
176     ULONG_PTR ex;
177     HRESULT hres;
178 
179     ex = (ULONG_PTR)-37;
180 
181     test.cbSize = sizeof(_ATL_MODULEW);
182 
183     hres = AtlModuleInit(&test, NULL, NULL);
184     ok (hres == S_OK, "AtlModuleInit failed (0x%x).\n", hres);
185 
186     hres = AtlModuleAddTermFunc(&test, term_callback, ex);
187     ok (hres == S_OK, "AtlModuleAddTermFunc failed (0x%x).\n", hres);
188 
189     cb_val = 0xdeadbeef;
190     hres = AtlModuleTerm(&test);
191     ok (hres == S_OK, "AtlModuleTerm failed (0x%x).\n", hres);
192     ok (cb_val == ex, "wrong callback value (0x%lx).\n", cb_val);
193 
194     test.cbSize = FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer);
195 
196     hres = AtlModuleInit(&test, NULL, NULL);
197     ok (hres == S_OK, "AtlModuleInit failed (0x%x).\n", hres);
198 
199     hres = AtlModuleAddTermFunc(&test, term_callback, 0x23);
200     ok (hres == S_OK, "AtlModuleAddTermFunc failed (0x%x).\n", hres);
201 
202     cb_val = 0xdeadbeef;
203     hres = AtlModuleTerm(&test);
204     ok (hres == S_OK, "AtlModuleTerm failed (0x%x).\n", hres);
205     ok (cb_val == 0xdeadbeef, "wrong callback value (0x%lx).\n", cb_val);
206 }
207 
208 START_TEST(module)
209 {
210     test_StructSize();
211     test_winmodule();
212     test_winclassinfo();
213     test_term();
214 }
215