converted more mixed tab/space indentations to tabs. only whitespace changes.
[blender.git] / source / blender / blenlib / intern / winstuff.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Windows-posix compatibility layer, windows-specific functions.
29  */
30
31 /** \file blender/blenlib/intern/winstuff.c
32  *  \ingroup bli
33  */
34
35
36 #ifdef WIN32
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <conio.h>
41
42 #include "MEM_guardedalloc.h"
43 #include "BLI_path_util.h"
44 #include "BLI_string.h"
45
46 #include "BKE_utildefines.h"
47 #include "BKE_global.h"
48
49 #define WIN32_SKIP_HKEY_PROTECTION              // need to use HKEY
50 #include "BLI_winstuff.h"
51
52  /* FILE_MAXDIR + FILE_MAXFILE */
53
54 int BLI_getInstallationDir( char * str ) {
55         char dir[FILE_MAXDIR];
56         char file[FILE_MAXFILE];
57         int a;
58         
59         GetModuleFileName(NULL,str,FILE_MAXDIR+FILE_MAXFILE);
60         BLI_split_dirfile(str,dir,file); /* shouldn't be relative */
61         a = strlen(dir);
62         if(dir[a-1] == '\\') dir[a-1]=0;
63         
64         strcpy(str,dir);
65         
66         return 1;
67 }
68
69 int IsConsoleEmpty(void)
70 {
71         CONSOLE_SCREEN_BUFFER_INFO csbi = {{0}};
72         HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
73
74         return GetConsoleScreenBufferInfo(hStdOutput, &csbi) && csbi.dwCursorPosition.X == 0 && csbi.dwCursorPosition.Y == 0;
75 }
76
77 void RegisterBlendExtension_Fail(HKEY root)
78 {
79         printf("failed\n");
80         if (root)
81                 RegCloseKey(root);
82         if (!G.background)
83                 MessageBox(0,"Could not register file extension.","Blender error",MB_OK|MB_ICONERROR);
84         TerminateProcess(GetCurrentProcess(),1);
85 }
86
87 void RegisterBlendExtension(void) {
88         LONG lresult;
89         HKEY hkey = 0;
90         HKEY root = 0;
91         BOOL usr_mode = FALSE;
92         DWORD dwd = 0;
93         char buffer[256];
94
95         char BlPath[MAX_PATH];
96         char InstallDir[FILE_MAXDIR];
97         char SysDir[FILE_MAXDIR];
98         const char* ThumbHandlerDLL;
99         char RegCmd[MAX_PATH*2];
100         char MBox[256];
101         BOOL IsWOW64;
102
103         printf("Registering file extension...");
104         GetModuleFileName(0,BlPath,MAX_PATH);
105
106         // root is HKLM by default
107         lresult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
108         if (lresult != ERROR_SUCCESS)
109         {
110                 // try HKCU on failure
111                 usr_mode = TRUE;
112                 lresult = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
113                 if (lresult != ERROR_SUCCESS)
114                         RegisterBlendExtension_Fail(0);
115         }
116
117         lresult = RegCreateKeyEx(root, "blendfile", 0,
118                 NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
119         if (lresult == ERROR_SUCCESS) {
120                 sprintf(buffer,"%s","Blender File");
121                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE*)buffer, strlen(buffer) + 1);
122                 RegCloseKey(hkey);
123         }
124         if (lresult != ERROR_SUCCESS)
125                 RegisterBlendExtension_Fail(root);
126
127         lresult = RegCreateKeyEx(root, "blendfile\\shell\\open\\command", 0,
128                 NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
129         if (lresult == ERROR_SUCCESS) {
130                 sprintf(buffer, "\"%s\" \"%%1\"", BlPath);
131                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE*)buffer, strlen(buffer) + 1);
132                 RegCloseKey(hkey);
133         }
134         if (lresult != ERROR_SUCCESS)
135                 RegisterBlendExtension_Fail(root);
136
137         lresult = RegCreateKeyEx(root, "blendfile\\DefaultIcon", 0,
138                 NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
139         if (lresult == ERROR_SUCCESS) {
140                 sprintf(buffer, "\"%s\",1", BlPath);
141                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE*)buffer, strlen(buffer) + 1);
142                 RegCloseKey(hkey);
143         }
144         if (lresult != ERROR_SUCCESS)
145                 RegisterBlendExtension_Fail(root);
146
147         lresult = RegCreateKeyEx(root, ".blend", 0,
148                 NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
149         if (lresult == ERROR_SUCCESS) {
150                 sprintf(buffer, "%s", "blendfile");
151                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE*)buffer, strlen(buffer) + 1);
152                 RegCloseKey(hkey);
153         }
154         if (lresult != ERROR_SUCCESS)
155                 RegisterBlendExtension_Fail(root);
156         
157         BLI_getInstallationDir(InstallDir);
158         GetSystemDirectory(SysDir,FILE_MAXDIR);
159 #ifdef WIN64
160         ThumbHandlerDLL = "BlendThumb64.dll";
161 #else
162         IsWow64Process(GetCurrentProcess(),&IsWOW64);
163         if (IsWOW64 == TRUE)
164                 ThumbHandlerDLL = "BlendThumb64.dll";
165         else
166                 ThumbHandlerDLL = "BlendThumb.dll";
167 #endif  
168         snprintf(RegCmd,MAX_PATH*2,"%s\\regsvr32 /s \"%s\\%s\"",SysDir,InstallDir,ThumbHandlerDLL);
169         system(RegCmd);
170
171         RegCloseKey(root);
172         printf("success (%s)\n",usr_mode ? "user" : "system");
173         if (!G.background)
174         {
175                 sprintf(MBox,"File extension registered for %s.",usr_mode ? "the current user. To register for all users, run as an administrator" : "all users");
176                 MessageBox(0,MBox,"Blender",MB_OK|MB_ICONINFORMATION);
177         }
178         TerminateProcess(GetCurrentProcess(),0);
179 }
180
181 DIR *opendir (const char *path) {
182         if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) {
183                 DIR *newd= MEM_mallocN(sizeof(DIR), "opendir");
184
185                 newd->handle = INVALID_HANDLE_VALUE;
186                 sprintf(newd->path, "%s\\*",path);
187                 
188                 newd->direntry.d_ino= 0;
189                 newd->direntry.d_off= 0;
190                 newd->direntry.d_reclen= 0;
191                 newd->direntry.d_name= NULL;
192                 
193                 return newd;
194         } else {
195                 return NULL;
196         }
197 }
198
199 struct dirent *readdir(DIR *dp) {
200         if (dp->direntry.d_name) {
201                 MEM_freeN(dp->direntry.d_name);
202                 dp->direntry.d_name= NULL;
203         }
204                 
205         if (dp->handle==INVALID_HANDLE_VALUE) {
206                 dp->handle= FindFirstFile(dp->path, &(dp->data));
207                 if (dp->handle==INVALID_HANDLE_VALUE)
208                         return NULL;
209                         
210                 dp->direntry.d_name= BLI_strdup(dp->data.cFileName);
211
212                 return &dp->direntry;
213         } else if (FindNextFile (dp->handle, &(dp->data))) {
214                 dp->direntry.d_name= BLI_strdup(dp->data.cFileName);
215
216                 return &dp->direntry;
217         } else {
218                 return NULL;
219         }
220 }
221
222 int closedir (DIR *dp) {
223         if (dp->direntry.d_name) MEM_freeN(dp->direntry.d_name);
224         if (dp->handle!=INVALID_HANDLE_VALUE) FindClose(dp->handle);
225
226         MEM_freeN(dp);
227         
228         return 0;
229 }
230
231 void get_default_root(char* root) {
232         char str[MAX_PATH+1];
233         
234         /* the default drive to resolve a directory without a specified drive 
235            should be the Windows installation drive, since this was what the OS
236            assumes. */
237         if (GetWindowsDirectory(str,MAX_PATH+1)) {
238                 root[0] = str[0];
239                 root[1] = ':';
240                 root[2] = '\\';
241                 root[3] = '\0';
242         } else {                
243                 /* if GetWindowsDirectory fails, something has probably gone wrong, 
244                    we are trying the blender install dir though */
245                 if (GetModuleFileName(NULL,str,MAX_PATH+1)) {
246                         printf("Error! Could not get the Windows Directory - Defaulting to Blender installation Dir!");
247                         root[0] = str[0];
248                         root[1] = ':';
249                         root[2] = '\\';
250                         root[3] = '\0';
251                 } else {
252                         DWORD tmp;
253                         int i;
254                         int rc = 0;
255                         /* now something has gone really wrong - still trying our best guess */
256                         printf("Error! Could not get the Windows Directory - Defaulting to first valid drive! Path might be invalid!");
257                         tmp= GetLogicalDrives();
258                         for (i=2; i < 26; i++) {
259                                 if ((tmp>>i) & 1) {
260                                         root[0] = 'a'+i;
261                                         root[1] = ':';
262                                         root[2] = '\\';
263                                         root[3] = '\0';
264                                         if (GetFileAttributes(root) != 0xFFFFFFFF) {
265                                                 rc = i;
266                                                 break;                  
267                                         }
268                                 }
269                         }
270                         if (0 == rc) {
271                                 printf("ERROR in 'get_default_root': can't find a valid drive!");
272                                 root[0] = 'C';
273                                 root[1] = ':';
274                                 root[2] = '\\';
275                                 root[3] = '\0';
276                         }
277                 }               
278         }
279 }
280
281 int check_file_chars(char *filename)
282 {
283         char *p = filename;
284         while (*p) {
285                 switch (*p) {
286                         case ':':
287                         case '?':
288                         case '*':
289                         case '|':
290                         case '\\':
291                         case '/':
292                         case '\"':
293                                 return 0;
294                                 break;
295                 }
296
297                 p++;
298         }
299         return 1;
300 }
301
302 /* Copied from http://sourceware.org/ml/newlib/2005/msg00248.html */
303 /* Copyright 2005 Shaun Jackman
304  * Permission to use, copy, modify, and distribute this software
305  * is freely granted, provided that this notice is preserved.
306  */
307 #include <string.h>
308 char* dirname(char *path)
309 {
310         char *p;
311         if( path == NULL || *path == '\0' )
312         return ".";
313         p = path + strlen(path) - 1;
314         while( *p == '/' ) {
315                 if( p == path )
316                         return path;
317                 *p-- = '\0';
318         }
319         while( p >= path && *p != '/' )
320         p--;
321         return
322         p < path ? "." :
323         p == path ? "/" :
324         (*p = '\0', path);
325 }
326 /* End of copied part */
327
328 #else
329
330 /* intentionally empty for UNIX */
331
332 #endif