svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r22205:22290
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #ifdef WIN32
36
37 #include <stdlib.h>
38 #include <stdio.h>
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_util.h"
44 #define WIN32_SKIP_HKEY_PROTECTION              // need to use HKEY
45 #include "BLI_winstuff.h"
46
47 #include "BKE_utildefines.h" /* FILE_MAXDIR + FILE_MAXFILE */
48
49 int BLI_getInstallationDir( char * str ) {
50         char dir[FILE_MAXDIR];
51         char file[FILE_MAXFILE];
52         int a;
53         
54         GetModuleFileName(NULL,str,FILE_MAXDIR+FILE_MAXFILE);
55         BLI_split_dirfile(str,dir,file); /* shouldn't be relative */
56         a = strlen(dir);
57         if(dir[a-1] == '\\') dir[a-1]=0;
58         
59         strcpy(str,dir);
60         
61         return 1;
62 }
63
64
65 void RegisterBlendExtension(char * str) {
66         LONG lresult;
67         HKEY hkey = 0;
68         DWORD dwd = 0;
69         char buffer[128];
70         
71         lresult = RegCreateKeyEx(HKEY_CLASSES_ROOT, "blendfile\\shell\\open\\command", 0,
72                 "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
73
74         if (lresult == ERROR_SUCCESS) {
75                 sprintf(buffer, "\"%s\" \"%%1\"", str);
76                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, buffer, strlen(buffer) + 1);
77                 RegCloseKey(hkey);
78         }
79
80         lresult = RegCreateKeyEx(HKEY_CLASSES_ROOT, "blendfile\\DefaultIcon", 0,
81                 "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
82
83         if (lresult == ERROR_SUCCESS) {
84                 sprintf(buffer, "\"%s\",1", str);
85                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, buffer, strlen(buffer) + 1);
86                 RegCloseKey(hkey);
87         }
88
89         lresult = RegCreateKeyEx(HKEY_CLASSES_ROOT, ".blend", 0,
90                 "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
91
92         if (lresult == ERROR_SUCCESS) {
93                 sprintf(buffer, "%s", "blendfile");
94                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, buffer, strlen(buffer) + 1);
95                 RegCloseKey(hkey);
96         }
97 }
98
99 DIR *opendir (const char *path) {
100         if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) {
101                 DIR *newd= MEM_mallocN(sizeof(DIR), "opendir");
102
103                 newd->handle = INVALID_HANDLE_VALUE;
104                 sprintf(newd->path, "%s\\*",path);
105                 
106                 newd->direntry.d_ino= 0;
107                 newd->direntry.d_off= 0;
108                 newd->direntry.d_reclen= 0;
109                 newd->direntry.d_name= NULL;
110                 
111                 return newd;
112         } else {
113                 return NULL;
114         }
115 }
116
117 struct dirent *readdir(DIR *dp) {
118         if (dp->direntry.d_name) {
119                 MEM_freeN(dp->direntry.d_name);
120                 dp->direntry.d_name= NULL;
121         }
122                 
123         if (dp->handle==INVALID_HANDLE_VALUE) {
124                 dp->handle= FindFirstFile(dp->path, &(dp->data));
125                 if (dp->handle==INVALID_HANDLE_VALUE)
126                         return NULL;
127                         
128                 dp->direntry.d_name= BLI_strdup(dp->data.cFileName);
129
130                 return &dp->direntry;
131         } else if (FindNextFile (dp->handle, &(dp->data))) {
132                 dp->direntry.d_name= BLI_strdup(dp->data.cFileName);
133
134                 return &dp->direntry;
135         } else {
136                 return NULL;
137         }
138 }
139
140 int closedir (DIR *dp) {
141         if (dp->direntry.d_name) MEM_freeN(dp->direntry.d_name);
142         if (dp->handle!=INVALID_HANDLE_VALUE) FindClose(dp->handle);
143
144         MEM_freeN(dp);
145         
146         return 0;
147 }
148
149 void get_default_root(char* root) {
150         char str[MAX_PATH+1];
151         
152         /* the default drive to resolve a directory without a specified drive 
153            should be the Windows installation drive, since this was what the OS
154            assumes. */
155         if (GetWindowsDirectory(str,MAX_PATH+1)) {
156                 root[0] = str[0];
157                 root[1] = ':';
158                 root[2] = '\\';
159                 root[3] = '\0';
160         } else {                
161                 /* if GetWindowsDirectory fails, something has probably gone wrong, 
162                    we are trying the blender install dir though */
163                 if (GetModuleFileName(NULL,str,MAX_PATH+1)) {
164                         printf("Error! Could not get the Windows Directory - Defaulting to Blender installation Dir!");
165                         root[0] = str[0];
166                         root[1] = ':';
167                         root[2] = '\\';
168                         root[3] = '\0';
169                 } else {
170                         DWORD tmp;
171                         int i;
172                         int rc = 0;
173                         /* now something has gone really wrong - still trying our best guess */
174                         printf("Error! Could not get the Windows Directory - Defaulting to first valid drive! Path might be invalid!");
175                         tmp= GetLogicalDrives();
176                         for (i=2; i < 26; i++) {
177                                 if ((tmp>>i) & 1) {
178                                         root[0] = 'a'+i;
179                                         root[1] = ':';
180                                         root[2] = '\\';
181                                         root[3] = '\0';
182                                         if (GetFileAttributes(root) != 0xFFFFFFFF) {
183                                                 rc = i;
184                                                 break;                  
185                                         }
186                                 }
187                         }
188                         if (0 == rc) {
189                                 printf("ERROR in 'get_default_root': can't find a valid drive!");
190                                 root[0] = 'C';
191                                 root[1] = ':';
192                                 root[2] = '\\';
193                                 root[3] = '\0';
194                         }
195                 }               
196         }
197 }
198
199 int check_file_chars(char *filename)
200 {
201         char *p = filename;
202         while (*p) {
203                 switch (*p) {
204                         case ':':
205                         case '?':
206                         case '*':
207                         case '|':
208                         case '\\':
209                         case '/':
210                         case '\"':
211                                 return 0;
212                                 break;
213                 }
214
215                 p++;
216         }
217         return 1;
218 }
219
220 #else
221
222 /* intentionally empty for UNIX */
223
224 #endif