windowscodecs: Handle TIFF's with RowsPerStrip greater than Height.
[wine] / dlls / shell32 / tests / brsfolder.c
1 /*
2  * Unit test of the SHBrowseForFolder function.
3  *
4  * Copyright 2009 Michael Mc Donnell
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 #include <windows.h>
21 #include <shlobj.h>
22 #include <shobjidl.h>
23 #include <string.h>
24
25 #include "wine/test.h"
26 #define IDD_MAKENEWFOLDER 0x3746 /* From "../shresdef.h" */
27
28 /*
29  * Returns the number of folders in a folder.
30  */
31 static int get_number_of_folders(LPCSTR path)
32 {
33     int number_of_folders = 0;
34     char path_search_string[MAX_PATH];
35     WIN32_FIND_DATA find_data;
36     HANDLE find_handle;
37
38     strncpy(path_search_string, path, MAX_PATH);
39     strncat(path_search_string, "*", 1);
40
41     find_handle = FindFirstFile(path_search_string, &find_data);
42     if (find_handle == INVALID_HANDLE_VALUE)
43         return -1;
44
45     do
46     {
47         if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
48             strcmp(find_data.cFileName, ".") != 0 &&
49             strcmp(find_data.cFileName, "..") != 0)
50         {
51             number_of_folders++;
52         }
53     }
54     while (FindNextFile(find_handle, &find_data) != 0);
55
56     return number_of_folders;
57 }
58
59 static BOOL does_folder_or_file_exist(LPCSTR folder_path)
60 {
61     DWORD file_attributes = GetFileAttributesA(folder_path);
62     return !(file_attributes == INVALID_FILE_ATTRIBUTES);
63 }
64
65 /*
66  * Callback used by test_click_make_new_folder_button for SHBrowseForFolder
67  * dialog box. It clicks the "Make New Folder" button and then closes the dialog
68  * box.
69  */
70 static int CALLBACK create_new_folder_callback(HWND hwnd, UINT uMsg,
71                                                LPARAM lParam, LPARAM lpData)
72 {
73     switch (uMsg)
74     {
75     case BFFM_INITIALIZED:
76         /* Click "Make New Folder" button */
77         SendMessage(hwnd, WM_COMMAND, IDD_MAKENEWFOLDER, 0);
78         /* Close dialog box */
79         SendMessage(hwnd, WM_COMMAND, IDCANCEL, 0);
80         return TRUE;
81     default:
82         return FALSE;
83     }
84 }
85
86 /*
87  * Tests if clicking the "Make New Folder" button in a SHBrowseForFolder
88  * dialog box creates a new folder. (Bug 17986).
89  *
90  * The algorithm is:
91  * 1. Check that there is no "test_click_make_new_folder_button" folder.
92  * 2. Create a test folder called "test_click_make_new_folder_button".
93  * 3. Use the test folder as root for SHBrowseForFolder dialog box.
94  * 3. Hook up SHBrowseForFolder dialog box with callback.
95  * 4. Display SHBrowseForFolder dialog box.
96  * 5. Callback clicks "Make New Folder" button (by sending a message).
97  * 6. Callback closes SHBrowseForFolder dialog box.
98  * 7. Check that there is a new folder inside the test folder.
99  * 8. Remove the test folder and any subfolders.
100  */
101 static void test_click_make_new_folder_button(void)
102 {
103     HRESULT resCoInit;
104     BROWSEINFO bi;
105     LPITEMIDLIST pidl = NULL;
106     LPITEMIDLIST test_folder_pidl;
107     IShellFolder *test_folder_object;
108     char test_folder_path[MAX_PATH];
109     WCHAR test_folder_pathW[MAX_PATH];
110     char selected_folder[MAX_PATH];
111     const CHAR title[] = "test_click_make_new_folder_button";
112     int number_of_folders = -1;
113     SHFILEOPSTRUCT shfileop;
114
115     if (does_folder_or_file_exist(title))
116     {
117         skip("The test folder already exists.\n");
118         return;
119     }
120
121     /* Must initialize COM if using the NEWDIAlOGSTYLE according to MSDN. */
122     resCoInit = CoInitialize(NULL);
123     if(!(resCoInit == S_OK || resCoInit == S_FALSE))
124     {
125         skip("COM could not be initialized %u\n", GetLastError());
126         return;
127     }
128
129     /* Leave room for concatenating title, two backslashes, and an extra NULL. */
130     if (!GetCurrentDirectoryA(MAX_PATH-strlen(title)-3, test_folder_path))
131     {
132         skip("GetCurrentDirectoryA failed %u\n", GetLastError());
133     }
134     strncat(test_folder_path, "\\", 1);
135     strncat(test_folder_path, title, MAX_PATH-1);
136     strncat(test_folder_path, "\\", 1);
137
138     /* Avoid conflicts by creating a test folder. */
139     if (!CreateDirectoryA(title, NULL))
140     {
141         skip("CreateDirectoryA failed %u\n", GetLastError());
142         return;
143     }
144
145     /* Initialize browse info struct for SHBrowseForFolder */
146     bi.hwndOwner = NULL;
147     bi.pszDisplayName = (LPTSTR) &selected_folder;
148     bi.lpszTitle = (LPTSTR) title;
149     bi.ulFlags = BIF_NEWDIALOGSTYLE;
150     bi.lpfn = create_new_folder_callback;
151     /* Use test folder as the root folder for dialog box */
152     MultiByteToWideChar(CP_UTF8, 0, test_folder_path, MAX_PATH,
153         test_folder_pathW, MAX_PATH*sizeof(WCHAR));
154     SHGetDesktopFolder(&test_folder_object);
155     test_folder_object->lpVtbl->ParseDisplayName(test_folder_object, NULL, NULL,
156         test_folder_pathW, 0UL, &test_folder_pidl, 0UL);
157     bi.pidlRoot = test_folder_pidl;
158
159     /* Display dialog box and let callback click the buttons */
160     pidl = SHBrowseForFolder(&bi);
161
162     number_of_folders = get_number_of_folders(test_folder_path);
163     todo_wine ok(number_of_folders == 1 || broken(number_of_folders == 0) /* W98, W2K */,
164         "Clicking \"Make New Folder\" button did not result in a new folder.\n");
165
166     /* Remove test folder and any subfolders created in this test */
167     shfileop.hwnd = NULL;
168     shfileop.wFunc = FO_DELETE;
169     /* Path must be double NULL terminated */
170     test_folder_path[strlen(test_folder_path)+1] = '\0';
171     shfileop.pFrom = test_folder_path;
172     shfileop.pTo = NULL;
173     shfileop.fFlags = FOF_NOCONFIRMATION|FOF_NOERRORUI|FOF_SILENT;
174     SHFileOperation(&shfileop);
175
176     if (pidl)
177         CoTaskMemFree(pidl);
178     if (test_folder_pidl)
179         CoTaskMemFree(test_folder_pidl);
180     if (test_folder_object)
181         test_folder_object->lpVtbl->Release(test_folder_object);
182
183     CoUninitialize();
184 }
185
186 START_TEST(brsfolder)
187 {
188     test_click_make_new_folder_button();
189 }