1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 * Windows-posix compatibility layer, windows-specific functions.
19 */
20
21 /** \file
22 * \ingroup bli
23 */
24
25 #ifdef WIN32
26
27 # include <conio.h>
28 # include <stdio.h>
29 # include <stdlib.h>
30
31 # include "MEM_guardedalloc.h"
32
33 # define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
34 # include "BLI_path_util.h"
35 # include "BLI_string.h"
36 # include "BLI_utildefines.h"
37 # include "BLI_winstuff.h"
38
39 # include "utf_winfunc.h"
40 # include "utfconv.h"
41
42 /* FILE_MAXDIR + FILE_MAXFILE */
43
BLI_windows_get_executable_dir(char * str)44 int BLI_windows_get_executable_dir(char *str)
45 {
46 char dir[FILE_MAXDIR];
47 int a;
48 /*change to utf support*/
49 GetModuleFileName(NULL, str, FILE_MAX);
50 BLI_split_dir_part(str, dir, sizeof(dir)); /* shouldn't be relative */
51 a = strlen(dir);
52 if (dir[a - 1] == '\\') {
53 dir[a - 1] = 0;
54 }
55
56 strcpy(str, dir);
57
58 return 1;
59 }
60
register_blend_extension_failed(HKEY root,const bool background)61 static void register_blend_extension_failed(HKEY root, const bool background)
62 {
63 printf("failed\n");
64 if (root) {
65 RegCloseKey(root);
66 }
67 if (!background) {
68 MessageBox(0, "Could not register file extension.", "Blender error", MB_OK | MB_ICONERROR);
69 }
70 TerminateProcess(GetCurrentProcess(), 1);
71 }
72
BLI_windows_register_blend_extension(const bool background)73 void BLI_windows_register_blend_extension(const bool background)
74 {
75 LONG lresult;
76 HKEY hkey = 0;
77 HKEY root = 0;
78 BOOL usr_mode = false;
79 DWORD dwd = 0;
80 char buffer[256];
81
82 char BlPath[MAX_PATH];
83 char InstallDir[FILE_MAXDIR];
84 char SysDir[FILE_MAXDIR];
85 const char *ThumbHandlerDLL;
86 char RegCmd[MAX_PATH * 2];
87 char MBox[256];
88 char *blender_app;
89 # ifndef _WIN64
90 BOOL IsWOW64;
91 # endif
92
93 printf("Registering file extension...");
94 GetModuleFileName(0, BlPath, MAX_PATH);
95
96 /* Replace the actual app name with the wrapper. */
97 blender_app = strstr(BlPath, "blender-app.exe");
98 if (blender_app != NULL) {
99 strcpy(blender_app, "blender.exe");
100 }
101
102 /* root is HKLM by default */
103 lresult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
104 if (lresult != ERROR_SUCCESS) {
105 /* try HKCU on failure */
106 usr_mode = true;
107 lresult = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
108 if (lresult != ERROR_SUCCESS) {
109 register_blend_extension_failed(0, background);
110 }
111 }
112
113 lresult = RegCreateKeyEx(
114 root, "blendfile", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
115 if (lresult == ERROR_SUCCESS) {
116 strcpy(buffer, "Blender File");
117 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
118 RegCloseKey(hkey);
119 }
120 if (lresult != ERROR_SUCCESS) {
121 register_blend_extension_failed(root, background);
122 }
123
124 lresult = RegCreateKeyEx(root,
125 "blendfile\\shell\\open\\command",
126 0,
127 NULL,
128 REG_OPTION_NON_VOLATILE,
129 KEY_ALL_ACCESS,
130 NULL,
131 &hkey,
132 &dwd);
133 if (lresult == ERROR_SUCCESS) {
134 sprintf(buffer, "\"%s\" \"%%1\"", BlPath);
135 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
136 RegCloseKey(hkey);
137 }
138 if (lresult != ERROR_SUCCESS) {
139 register_blend_extension_failed(root, background);
140 }
141
142 lresult = RegCreateKeyEx(root,
143 "blendfile\\DefaultIcon",
144 0,
145 NULL,
146 REG_OPTION_NON_VOLATILE,
147 KEY_ALL_ACCESS,
148 NULL,
149 &hkey,
150 &dwd);
151 if (lresult == ERROR_SUCCESS) {
152 sprintf(buffer, "\"%s\", 1", BlPath);
153 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
154 RegCloseKey(hkey);
155 }
156 if (lresult != ERROR_SUCCESS) {
157 register_blend_extension_failed(root, background);
158 }
159
160 lresult = RegCreateKeyEx(
161 root, ".blend", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
162 if (lresult == ERROR_SUCCESS) {
163 strcpy(buffer, "blendfile");
164 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
165 RegCloseKey(hkey);
166 }
167 if (lresult != ERROR_SUCCESS) {
168 register_blend_extension_failed(root, background);
169 }
170
171 BLI_windows_get_executable_dir(InstallDir);
172 GetSystemDirectory(SysDir, FILE_MAXDIR);
173 ThumbHandlerDLL = "BlendThumb.dll";
174 snprintf(
175 RegCmd, MAX_PATH * 2, "%s\\regsvr32 /s \"%s\\%s\"", SysDir, InstallDir, ThumbHandlerDLL);
176 system(RegCmd);
177
178 RegCloseKey(root);
179 printf("success (%s)\n", usr_mode ? "user" : "system");
180 if (!background) {
181 sprintf(MBox,
182 "File extension registered for %s.",
183 usr_mode ? "the current user. To register for all users, run as an administrator" :
184 "all users");
185 MessageBox(0, MBox, "Blender", MB_OK | MB_ICONINFORMATION);
186 }
187 TerminateProcess(GetCurrentProcess(), 0);
188 }
189
BLI_windows_get_default_root_dir(char * root)190 void BLI_windows_get_default_root_dir(char *root)
191 {
192 char str[MAX_PATH + 1];
193
194 /* the default drive to resolve a directory without a specified drive
195 * should be the Windows installation drive, since this was what the OS
196 * assumes. */
197 if (GetWindowsDirectory(str, MAX_PATH + 1)) {
198 root[0] = str[0];
199 root[1] = ':';
200 root[2] = '\\';
201 root[3] = '\0';
202 }
203 else {
204 /* if GetWindowsDirectory fails, something has probably gone wrong,
205 * we are trying the blender install dir though */
206 if (GetModuleFileName(NULL, str, MAX_PATH + 1)) {
207 printf(
208 "Error! Could not get the Windows Directory - "
209 "Defaulting to Blender installation Dir!\n");
210 root[0] = str[0];
211 root[1] = ':';
212 root[2] = '\\';
213 root[3] = '\0';
214 }
215 else {
216 DWORD tmp;
217 int i;
218 int rc = 0;
219 /* now something has gone really wrong - still trying our best guess */
220 printf(
221 "Error! Could not get the Windows Directory - "
222 "Defaulting to first valid drive! Path might be invalid!\n");
223 tmp = GetLogicalDrives();
224 for (i = 2; i < 26; i++) {
225 if ((tmp >> i) & 1) {
226 root[0] = 'a' + i;
227 root[1] = ':';
228 root[2] = '\\';
229 root[3] = '\0';
230 if (GetFileAttributes(root) != 0xFFFFFFFF) {
231 rc = i;
232 break;
233 }
234 }
235 }
236 if (0 == rc) {
237 printf("ERROR in 'BLI_windows_get_default_root_dir': can't find a valid drive!\n");
238 root[0] = 'C';
239 root[1] = ':';
240 root[2] = '\\';
241 root[3] = '\0';
242 }
243 }
244 }
245 }
246
247 #else
248
249 /* intentionally empty for UNIX */
250
251 #endif
252