Blender  V2.59
winstuff.c
Go to the documentation of this file.
00001 /*
00002  * $Id: winstuff.c 36426 2011-05-02 08:07:24Z jesterking $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  * Windows-posix compatibility layer, windows-specific functions.
00029  */
00030 
00036 #ifdef WIN32
00037 
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <conio.h>
00041 
00042 #include "MEM_guardedalloc.h"
00043 #include "BLI_path_util.h"
00044 #include "BLI_string.h"
00045 
00046 #include "BKE_utildefines.h"
00047 #include "BKE_global.h"
00048 
00049 #define WIN32_SKIP_HKEY_PROTECTION              // need to use HKEY
00050 #include "BLI_winstuff.h"
00051 
00052  /* FILE_MAXDIR + FILE_MAXFILE */
00053 
00054 int BLI_getInstallationDir( char * str ) {
00055         char dir[FILE_MAXDIR];
00056         char file[FILE_MAXFILE];
00057         int a;
00058         
00059         GetModuleFileName(NULL,str,FILE_MAXDIR+FILE_MAXFILE);
00060         BLI_split_dirfile(str,dir,file); /* shouldn't be relative */
00061         a = strlen(dir);
00062         if(dir[a-1] == '\\') dir[a-1]=0;
00063         
00064         strcpy(str,dir);
00065         
00066         return 1;
00067 }
00068 
00069 void RegisterBlendExtension_Fail(HKEY root)
00070 {
00071         printf("failed\n");
00072         if (root)
00073                 RegCloseKey(root);
00074         if (!G.background)
00075                 MessageBox(0,"Could not register file extension.","Blender error",MB_OK|MB_ICONERROR);
00076         TerminateProcess(GetCurrentProcess(),1);
00077 }
00078 
00079 void RegisterBlendExtension(void) {
00080         LONG lresult;
00081         HKEY hkey = 0;
00082         HKEY root = 0;
00083         BOOL usr_mode = FALSE;
00084         DWORD dwd = 0;
00085         char buffer[256];
00086 
00087         char BlPath[MAX_PATH];
00088         char InstallDir[FILE_MAXDIR];
00089         char SysDir[FILE_MAXDIR];
00090         const char* ThumbHandlerDLL;
00091         char RegCmd[MAX_PATH*2];
00092         char MBox[256];
00093         BOOL IsWOW64;
00094 
00095         printf("Registering file extension...");
00096         GetModuleFileName(0,BlPath,MAX_PATH);
00097 
00098         // root is HKLM by default
00099         lresult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
00100         if (lresult != ERROR_SUCCESS)
00101         {
00102                 // try HKCU on failure
00103                 usr_mode = TRUE;
00104                 lresult = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
00105                 if (lresult != ERROR_SUCCESS)
00106                         RegisterBlendExtension_Fail(0);
00107         }
00108 
00109         lresult = RegCreateKeyEx(root, "blendfile", 0,
00110                 NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
00111         if (lresult == ERROR_SUCCESS) {
00112                 sprintf(buffer,"%s","Blender File");
00113                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE*)buffer, strlen(buffer) + 1);
00114                 RegCloseKey(hkey);
00115         }
00116         if (lresult != ERROR_SUCCESS)
00117                 RegisterBlendExtension_Fail(root);
00118 
00119         lresult = RegCreateKeyEx(root, "blendfile\\shell\\open\\command", 0,
00120                 NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
00121         if (lresult == ERROR_SUCCESS) {
00122                 sprintf(buffer, "\"%s\" \"%%1\"", BlPath);
00123                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE*)buffer, strlen(buffer) + 1);
00124                 RegCloseKey(hkey);
00125         }
00126         if (lresult != ERROR_SUCCESS)
00127                 RegisterBlendExtension_Fail(root);
00128 
00129         lresult = RegCreateKeyEx(root, "blendfile\\DefaultIcon", 0,
00130                 NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
00131         if (lresult == ERROR_SUCCESS) {
00132                 sprintf(buffer, "\"%s\",1", BlPath);
00133                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE*)buffer, strlen(buffer) + 1);
00134                 RegCloseKey(hkey);
00135         }
00136         if (lresult != ERROR_SUCCESS)
00137                 RegisterBlendExtension_Fail(root);
00138 
00139         lresult = RegCreateKeyEx(root, ".blend", 0,
00140                 NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
00141         if (lresult == ERROR_SUCCESS) {
00142                 sprintf(buffer, "%s", "blendfile");
00143                 lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE*)buffer, strlen(buffer) + 1);
00144                 RegCloseKey(hkey);
00145         }
00146         if (lresult != ERROR_SUCCESS)
00147                 RegisterBlendExtension_Fail(root);
00148         
00149         BLI_getInstallationDir(InstallDir);
00150         GetSystemDirectory(SysDir,FILE_MAXDIR);
00151 #ifdef WIN64
00152         ThumbHandlerDLL = "BlendThumb64.dll";
00153 #else
00154         IsWow64Process(GetCurrentProcess(),&IsWOW64);
00155         if (IsWOW64 == TRUE)
00156                 ThumbHandlerDLL = "BlendThumb64.dll";
00157         else
00158                 ThumbHandlerDLL = "BlendThumb.dll";
00159 #endif  
00160         snprintf(RegCmd,MAX_PATH*2,"%s\\regsvr32 /s \"%s\\%s\"",SysDir,InstallDir,ThumbHandlerDLL);
00161         system(RegCmd);
00162 
00163         RegCloseKey(root);
00164         printf("success (%s)\n",usr_mode ? "user" : "system");
00165         if (!G.background)
00166         {
00167                 sprintf(MBox,"File extension registered for %s.",usr_mode ? "the current user. To register for all users, run as an administrator" : "all users");
00168                 MessageBox(0,MBox,"Blender",MB_OK|MB_ICONINFORMATION);
00169         }
00170         TerminateProcess(GetCurrentProcess(),0);
00171 }
00172 
00173 DIR *opendir (const char *path) {
00174         if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) {
00175                 DIR *newd= MEM_mallocN(sizeof(DIR), "opendir");
00176 
00177                 newd->handle = INVALID_HANDLE_VALUE;
00178                 sprintf(newd->path, "%s\\*",path);
00179                 
00180                 newd->direntry.d_ino= 0;
00181                 newd->direntry.d_off= 0;
00182                 newd->direntry.d_reclen= 0;
00183                 newd->direntry.d_name= NULL;
00184                 
00185                 return newd;
00186         } else {
00187                 return NULL;
00188         }
00189 }
00190 
00191 struct dirent *readdir(DIR *dp) {
00192         if (dp->direntry.d_name) {
00193                 MEM_freeN(dp->direntry.d_name);
00194                 dp->direntry.d_name= NULL;
00195         }
00196                 
00197         if (dp->handle==INVALID_HANDLE_VALUE) {
00198                 dp->handle= FindFirstFile(dp->path, &(dp->data));
00199                 if (dp->handle==INVALID_HANDLE_VALUE)
00200                         return NULL;
00201                         
00202                 dp->direntry.d_name= BLI_strdup(dp->data.cFileName);
00203 
00204                 return &dp->direntry;
00205         } else if (FindNextFile (dp->handle, &(dp->data))) {
00206                 dp->direntry.d_name= BLI_strdup(dp->data.cFileName);
00207 
00208                 return &dp->direntry;
00209         } else {
00210                 return NULL;
00211         }
00212 }
00213 
00214 int closedir (DIR *dp) {
00215         if (dp->direntry.d_name) MEM_freeN(dp->direntry.d_name);
00216         if (dp->handle!=INVALID_HANDLE_VALUE) FindClose(dp->handle);
00217 
00218         MEM_freeN(dp);
00219         
00220         return 0;
00221 }
00222 
00223 void get_default_root(char* root) {
00224         char str[MAX_PATH+1];
00225         
00226         /* the default drive to resolve a directory without a specified drive 
00227            should be the Windows installation drive, since this was what the OS
00228            assumes. */
00229         if (GetWindowsDirectory(str,MAX_PATH+1)) {
00230                 root[0] = str[0];
00231                 root[1] = ':';
00232                 root[2] = '\\';
00233                 root[3] = '\0';
00234         } else {                
00235                 /* if GetWindowsDirectory fails, something has probably gone wrong, 
00236                    we are trying the blender install dir though */
00237                 if (GetModuleFileName(NULL,str,MAX_PATH+1)) {
00238                         printf("Error! Could not get the Windows Directory - Defaulting to Blender installation Dir!");
00239                         root[0] = str[0];
00240                         root[1] = ':';
00241                         root[2] = '\\';
00242                         root[3] = '\0';
00243                 } else {
00244                         DWORD tmp;
00245                         int i;
00246                         int rc = 0;
00247                         /* now something has gone really wrong - still trying our best guess */
00248                         printf("Error! Could not get the Windows Directory - Defaulting to first valid drive! Path might be invalid!");
00249                         tmp= GetLogicalDrives();
00250                         for (i=2; i < 26; i++) {
00251                                 if ((tmp>>i) & 1) {
00252                                         root[0] = 'a'+i;
00253                                         root[1] = ':';
00254                                         root[2] = '\\';
00255                                         root[3] = '\0';
00256                                         if (GetFileAttributes(root) != 0xFFFFFFFF) {
00257                                                 rc = i;
00258                                                 break;                  
00259                                         }
00260                                 }
00261                         }
00262                         if (0 == rc) {
00263                                 printf("ERROR in 'get_default_root': can't find a valid drive!");
00264                                 root[0] = 'C';
00265                                 root[1] = ':';
00266                                 root[2] = '\\';
00267                                 root[3] = '\0';
00268                         }
00269                 }               
00270         }
00271 }
00272 
00273 int check_file_chars(char *filename)
00274 {
00275         char *p = filename;
00276         while (*p) {
00277                 switch (*p) {
00278                         case ':':
00279                         case '?':
00280                         case '*':
00281                         case '|':
00282                         case '\\':
00283                         case '/':
00284                         case '\"':
00285                                 return 0;
00286                                 break;
00287                 }
00288 
00289                 p++;
00290         }
00291         return 1;
00292 }
00293 
00294 /* Copied from http://sourceware.org/ml/newlib/2005/msg00248.html */
00295 /* Copyright 2005 Shaun Jackman
00296  * Permission to use, copy, modify, and distribute this software
00297  * is freely granted, provided that this notice is preserved.
00298  */
00299 #include <string.h>
00300 char* dirname(char *path)
00301 {
00302         char *p;
00303         if( path == NULL || *path == '\0' )
00304         return ".";
00305         p = path + strlen(path) - 1;
00306         while( *p == '/' ) {
00307                 if( p == path )
00308                         return path;
00309                 *p-- = '\0';
00310         }
00311         while( p >= path && *p != '/' )
00312         p--;
00313         return
00314         p < path ? "." :
00315         p == path ? "/" :
00316         (*p = '\0', path);
00317 }
00318 /* End of copied part */
00319 
00320 #else
00321 
00322 /* intentionally empty for UNIX */
00323 
00324 #endif