This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/blenlib/intern/winstuff.c

363 lines
9.2 KiB
C
Raw Normal View History

/*
* ***** BEGIN GPL LICENSE BLOCK *****
2002-10-12 11:37:38 +00:00
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
2002-10-12 11:37:38 +00:00
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
2010-02-12 13:34:04 +00:00
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2002-10-12 11:37:38 +00:00
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
2002-10-12 11:37:38 +00:00
* Windows-posix compatibility layer, windows-specific functions.
*/
2011-02-27 20:37:56 +00:00
/** \file blender/blenlib/intern/winstuff.c
* \ingroup bli
*/
2002-10-12 11:37:38 +00:00
#ifdef WIN32
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
2002-10-12 11:37:38 +00:00
#include "MEM_guardedalloc.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
2012-05-12 15:13:06 +00:00
#define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
2002-10-12 11:37:38 +00:00
#include "BLI_winstuff.h"
#include "BLI_utildefines.h"
2002-10-12 11:37:38 +00:00
#include "utf_winfunc.h"
#include "utfconv.h"
2012-05-12 15:13:06 +00:00
/* FILE_MAXDIR + FILE_MAXFILE */
2012-05-12 15:13:06 +00:00
int BLI_getInstallationDir(char *str)
{
char dir[FILE_MAXDIR];
int a;
/*change to utf support*/
2012-04-29 15:47:02 +00:00
GetModuleFileName(NULL, str, FILE_MAX);
BLI_split_dir_part(str, dir, sizeof(dir)); /* shouldn't be relative */
a = strlen(dir);
2012-05-12 15:13:06 +00:00
if (dir[a - 1] == '\\') dir[a - 1] = 0;
2012-04-29 15:47:02 +00:00
strcpy(str, dir);
return 1;
}
void RegisterBlendExtension_Fail(HKEY root)
{
printf("failed\n");
if (root)
RegCloseKey(root);
if (!G.background)
2012-05-12 15:13:06 +00:00
MessageBox(0, "Could not register file extension.", "Blender error", MB_OK | MB_ICONERROR);
2012-04-29 15:47:02 +00:00
TerminateProcess(GetCurrentProcess(), 1);
}
2002-10-12 11:37:38 +00:00
void RegisterBlendExtension(void)
{
2002-10-12 11:37:38 +00:00
LONG lresult;
HKEY hkey = 0;
HKEY root = 0;
BOOL usr_mode = FALSE;
2002-10-12 11:37:38 +00:00
DWORD dwd = 0;
char buffer[256];
char BlPath[MAX_PATH];
char InstallDir[FILE_MAXDIR];
char SysDir[FILE_MAXDIR];
const char *ThumbHandlerDLL;
2012-05-12 15:13:06 +00:00
char RegCmd[MAX_PATH * 2];
char MBox[256];
BOOL IsWOW64;
printf("Registering file extension...");
2012-04-29 15:47:02 +00:00
GetModuleFileName(0, BlPath, MAX_PATH);
// root is HKLM by default
lresult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
2012-03-07 04:53:43 +00:00
if (lresult != ERROR_SUCCESS) {
// try HKCU on failure
usr_mode = TRUE;
lresult = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
if (lresult != ERROR_SUCCESS)
RegisterBlendExtension_Fail(0);
}
2002-10-12 11:37:38 +00:00
lresult = RegCreateKeyEx(root, "blendfile", 0,
2012-05-12 15:13:06 +00:00
NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
2002-10-12 11:37:38 +00:00
if (lresult == ERROR_SUCCESS) {
2012-04-29 15:47:02 +00:00
strcpy(buffer, "Blender File");
2012-05-12 15:13:06 +00:00
lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
2002-10-12 11:37:38 +00:00
RegCloseKey(hkey);
}
if (lresult != ERROR_SUCCESS)
RegisterBlendExtension_Fail(root);
2002-10-12 11:37:38 +00:00
lresult = RegCreateKeyEx(root, "blendfile\\shell\\open\\command", 0,
2012-05-12 15:13:06 +00:00
NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
2002-10-12 11:37:38 +00:00
if (lresult == ERROR_SUCCESS) {
sprintf(buffer, "\"%s\" \"%%1\"", BlPath);
2012-05-12 15:13:06 +00:00
lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
2002-10-12 11:37:38 +00:00
RegCloseKey(hkey);
}
if (lresult != ERROR_SUCCESS)
RegisterBlendExtension_Fail(root);
2002-10-12 11:37:38 +00:00
lresult = RegCreateKeyEx(root, "blendfile\\DefaultIcon", 0,
2012-05-12 15:13:06 +00:00
NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
if (lresult == ERROR_SUCCESS) {
2012-04-29 15:47:02 +00:00
sprintf(buffer, "\"%s\", 1", BlPath);
2012-05-12 15:13:06 +00:00
lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
RegCloseKey(hkey);
}
if (lresult != ERROR_SUCCESS)
RegisterBlendExtension_Fail(root);
2002-10-12 11:37:38 +00:00
lresult = RegCreateKeyEx(root, ".blend", 0,
2012-05-12 15:13:06 +00:00
NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
2002-10-12 11:37:38 +00:00
if (lresult == ERROR_SUCCESS) {
sprintf(buffer, "%s", "blendfile");
2012-05-12 15:13:06 +00:00
lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
2002-10-12 11:37:38 +00:00
RegCloseKey(hkey);
}
if (lresult != ERROR_SUCCESS)
RegisterBlendExtension_Fail(root);
BLI_getInstallationDir(InstallDir);
2012-04-29 15:47:02 +00:00
GetSystemDirectory(SysDir, FILE_MAXDIR);
#ifdef WIN64
ThumbHandlerDLL = "BlendThumb64.dll";
#else
2012-04-29 15:47:02 +00:00
IsWow64Process(GetCurrentProcess(), &IsWOW64);
if (IsWOW64 == TRUE)
ThumbHandlerDLL = "BlendThumb64.dll";
else
ThumbHandlerDLL = "BlendThumb.dll";
2012-05-19 13:55:54 +00:00
#endif
2012-05-12 15:13:06 +00:00
snprintf(RegCmd, MAX_PATH * 2, "%s\\regsvr32 /s \"%s\\%s\"", SysDir, InstallDir, ThumbHandlerDLL);
system(RegCmd);
RegCloseKey(root);
2012-04-29 15:47:02 +00:00
printf("success (%s)\n", usr_mode ? "user" : "system");
2012-03-07 04:53:43 +00:00
if (!G.background) {
2012-04-29 15:47:02 +00:00
sprintf(MBox, "File extension registered for %s.", usr_mode ? "the current user. To register for all users, run as an administrator" : "all users");
2012-05-12 15:13:06 +00:00
MessageBox(0, MBox, "Blender", MB_OK | MB_ICONINFORMATION);
}
2012-04-29 15:47:02 +00:00
TerminateProcess(GetCurrentProcess(), 0);
2002-10-12 11:37:38 +00:00
}
2012-05-12 15:13:06 +00:00
DIR *opendir(const char *path)
{
wchar_t *path_16 = alloc_utf16_from_8(path, 0);
if (GetFileAttributesW(path_16) & FILE_ATTRIBUTE_DIRECTORY) {
2012-05-12 15:13:06 +00:00
DIR *newd = MEM_mallocN(sizeof(DIR), "opendir");
2002-10-12 11:37:38 +00:00
newd->handle = INVALID_HANDLE_VALUE;
2012-04-29 15:47:02 +00:00
sprintf(newd->path, "%s\\*", path);
2002-10-12 11:37:38 +00:00
2012-05-12 15:13:06 +00:00
newd->direntry.d_ino = 0;
newd->direntry.d_off = 0;
newd->direntry.d_reclen = 0;
newd->direntry.d_name = NULL;
2002-10-12 11:37:38 +00:00
free(path_16);
2002-10-12 11:37:38 +00:00
return newd;
}
else {
free(path_16);
2002-10-12 11:37:38 +00:00
return NULL;
}
}
static char *BLI_alloc_utf_8_from_16(wchar_t *in16, size_t add)
{
size_t bsize = count_utf_8_from_16(in16);
char *out8 = NULL;
if (!bsize) return NULL;
2012-05-12 15:13:06 +00:00
out8 = (char *)MEM_mallocN(sizeof(char) * (bsize + add), "UTF-8 String");
2012-04-29 15:47:02 +00:00
conv_utf_16_to_8(in16, out8, bsize);
return out8;
}
2012-05-12 15:13:06 +00:00
static wchar_t *UNUSED_FUNCTION(BLI_alloc_utf16_from_8) (char *in8, size_t add)
{
size_t bsize = count_utf_16_from_8(in8);
wchar_t *out16 = NULL;
if (!bsize) return NULL;
2012-05-12 15:13:06 +00:00
out16 = (wchar_t *) MEM_mallocN(sizeof(wchar_t) * (bsize + add), "UTF-16 String");
2012-04-29 15:47:02 +00:00
conv_utf_8_to_16(in8, out16, bsize);
return out16;
}
2012-05-17 23:21:11 +00:00
struct dirent *readdir(DIR *dp)
{
2002-10-12 11:37:38 +00:00
if (dp->direntry.d_name) {
MEM_freeN(dp->direntry.d_name);
2012-05-12 15:13:06 +00:00
dp->direntry.d_name = NULL;
2002-10-12 11:37:38 +00:00
}
2012-05-12 15:13:06 +00:00
if (dp->handle == INVALID_HANDLE_VALUE) {
wchar_t *path_16 = alloc_utf16_from_8(dp->path, 0);
dp->handle = FindFirstFileW(path_16, &(dp->data));
free(path_16);
2012-05-12 15:13:06 +00:00
if (dp->handle == INVALID_HANDLE_VALUE)
2002-10-12 11:37:38 +00:00
return NULL;
2012-05-12 15:13:06 +00:00
dp->direntry.d_name = BLI_alloc_utf_8_from_16(dp->data.cFileName, 0);
2002-10-12 11:37:38 +00:00
return &dp->direntry;
}
2012-05-12 15:13:06 +00:00
else if (FindNextFileW(dp->handle, &(dp->data))) {
dp->direntry.d_name = BLI_alloc_utf_8_from_16(dp->data.cFileName, 0);
2002-10-12 11:37:38 +00:00
return &dp->direntry;
}
else {
2002-10-12 11:37:38 +00:00
return NULL;
}
}
int closedir(DIR *dp)
{
2002-10-12 11:37:38 +00:00
if (dp->direntry.d_name) MEM_freeN(dp->direntry.d_name);
2012-05-12 15:13:06 +00:00
if (dp->handle != INVALID_HANDLE_VALUE) FindClose(dp->handle);
2002-10-12 11:37:38 +00:00
MEM_freeN(dp);
return 0;
}
void get_default_root(char *root)
{
2012-05-12 15:13:06 +00:00
char str[MAX_PATH + 1];
/* the default drive to resolve a directory without a specified drive
* should be the Windows installation drive, since this was what the OS
* assumes. */
2012-05-12 15:13:06 +00:00
if (GetWindowsDirectory(str, MAX_PATH + 1)) {
root[0] = str[0];
root[1] = ':';
root[2] = '\\';
root[3] = '\0';
}
else {
/* if GetWindowsDirectory fails, something has probably gone wrong,
* we are trying the blender install dir though */
2012-05-12 15:13:06 +00:00
if (GetModuleFileName(NULL, str, MAX_PATH + 1)) {
printf("Error! Could not get the Windows Directory - Defaulting to Blender installation Dir!");
root[0] = str[0];
root[1] = ':';
root[2] = '\\';
root[3] = '\0';
}
else {
DWORD tmp;
int i;
int rc = 0;
/* now something has gone really wrong - still trying our best guess */
printf("Error! Could not get the Windows Directory - Defaulting to first valid drive! Path might be invalid!");
2012-05-12 15:13:06 +00:00
tmp = GetLogicalDrives();
for (i = 2; i < 26; i++) {
if ((tmp >> i) & 1) {
root[0] = 'a' + i;
root[1] = ':';
root[2] = '\\';
root[3] = '\0';
if (GetFileAttributes(root) != 0xFFFFFFFF) {
rc = i;
break;
}
}
}
if (0 == rc) {
printf("ERROR in 'get_default_root': can't find a valid drive!");
root[0] = 'C';
root[1] = ':';
root[2] = '\\';
root[3] = '\0';
}
}
}
}
int check_file_chars(char *filename)
{
char *p = filename;
while (*p) {
switch (*p) {
case ':':
case '?':
case '*':
case '|':
case '\\':
case '/':
case '\"':
return 0;
break;
}
p++;
}
return 1;
}
/* Copied from http://sourceware.org/ml/newlib/2005/msg00248.html */
/* Copyright 2005 Shaun Jackman
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
#include <string.h>
const char *dirname(char *path)
{
char *p;
2012-05-12 15:13:06 +00:00
if (path == NULL || *path == '\0')
return ".";
p = path + strlen(path) - 1;
2012-05-12 15:13:06 +00:00
while (*p == '/') {
if (p == path)
return path;
*p-- = '\0';
}
2012-05-12 15:13:06 +00:00
while (p >= path && *p != '/')
p--;
return
2012-05-12 15:13:06 +00:00
p < path ? "." :
p == path ? "/" :
(*p = '\0', path);
}
/* End of copied part */
2002-10-12 11:37:38 +00:00
#else
2009-01-17 00:51:42 +00:00
/* intentionally empty for UNIX */
2002-10-12 11:37:38 +00:00
#endif