static enum install_res install_from_default_dir(void) { const char *data_dir, *package_dir; char *dir_buf = NULL; int len; enum install_res ret; if((data_dir = wine_get_data_dir())) { package_dir = data_dir; }else if((data_dir = wine_get_build_dir())) { len = strlen(data_dir); dir_buf = heap_alloc(len + sizeof("/../")); memcpy(dir_buf, data_dir, len); strcpy(dir_buf+len, "/../"); package_dir = dir_buf; }else { return INSTALL_NEXT; } ret = install_from_unix_file(package_dir, addon->subdir_name, addon->file_name); heap_free(dir_buf); if (ret == INSTALL_NEXT) ret = install_from_unix_file(INSTALL_DATADIR "/wine/", addon->subdir_name, addon->file_name); if (ret == INSTALL_NEXT && strcmp(INSTALL_DATADIR, "/usr/share")) ret = install_from_unix_file("/usr/share/wine/", addon->subdir_name, addon->file_name); return ret; }
/* try to load a pre-compiled fake dll */ static void *load_fake_dll( const WCHAR *name, SIZE_T *size ) { const char *build_dir = wine_get_build_dir(); const char *path; char *file, *ptr; void *data = NULL; unsigned int i, pos, len, namelen, maxlen = 0; WCHAR *p; int res = 0; if ((p = strrchrW( name, '\\' ))) name = p + 1; i = 0; len = strlenW( name ); if (build_dir) maxlen = strlen(build_dir) + sizeof("/programs/") + len; while ((path = wine_dll_enum_load_path( i++ ))) maxlen = max( maxlen, strlen(path) ); maxlen += sizeof("/fakedlls") + len + sizeof(".fake"); if (!(file = HeapAlloc( GetProcessHeap(), 0, maxlen ))) return NULL; pos = maxlen - len - sizeof(".fake"); if (!dll_name_WtoA( file + pos, name, len )) goto done; file[--pos] = '/'; if (build_dir) { strcpy( file + pos + len + 1, ".fake" ); /* try as a dll */ ptr = file + pos; namelen = len + 1; if (namelen > 4 && !memcmp( ptr + namelen - 4, ".dll", 4 )) namelen -= 4; ptr = prepend( ptr, ptr, namelen ); ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 ); ptr = prepend( ptr, build_dir, strlen(build_dir) ); if ((res = read_file( ptr, &data, size ))) goto done; /* now as a program */ ptr = file + pos; namelen = len + 1; if (namelen > 4 && !memcmp( ptr + namelen - 4, ".exe", 4 )) namelen -= 4; ptr = prepend( ptr, ptr, namelen ); ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 ); ptr = prepend( ptr, build_dir, strlen(build_dir) ); if ((res = read_file( ptr, &data, size ))) goto done; } file[pos + len + 1] = 0; for (i = 0; (path = wine_dll_enum_load_path( i )); i++) { ptr = prepend( file + pos, "/fakedlls", sizeof("/fakedlls") - 1 ); ptr = prepend( ptr, path, strlen(path) ); if ((res = read_file( ptr, &data, size ))) break; } done: HeapFree( GetProcessHeap(), 0, file ); if (res == 1) return data; return NULL; }
static BOOL install_from_default_dir(void) { const char *data_dir, *subdir; char *file_name; int len, len2; BOOL ret; if((data_dir = wine_get_data_dir())) subdir = "/gecko/"; else if((data_dir = wine_get_build_dir())) subdir = "/../gecko/"; else return FALSE; len = strlen(data_dir); len2 = strlen(subdir); file_name = heap_alloc(len+len2+sizeof(GECKO_FILE_NAME)); memcpy(file_name, data_dir, len); memcpy(file_name+len, subdir, len2); memcpy(file_name+len+len2, GECKO_FILE_NAME, sizeof(GECKO_FILE_NAME)); ret = install_from_unix_file(file_name); heap_free(file_name); if (!ret) ret = install_from_unix_file(INSTALL_DATADIR "/wine/gecko/" GECKO_FILE_NAME); if (!ret && strcmp(INSTALL_DATADIR, "/usr/share")) ret = install_from_unix_file("/usr/share/wine/gecko/" GECKO_FILE_NAME); return ret; }
/* build the dll load path from the WINEDLLPATH variable */ static void build_dll_path(void) { int len, count = 0; char *p, *path = getenv( "WINEDLLPATH" ); const char *dlldir = get_dlldir( &default_dlldir ); if (path) { /* count how many path elements we need */ path = strdup(path); p = path; while (*p) { while (*p == ':') p++; if (!*p) break; count++; while (*p && *p != ':') p++; } } dll_paths = malloc( (count+2) * sizeof(*dll_paths) ); nb_dll_paths = 0; if (dlldir) { dll_path_maxlen = strlen(dlldir); dll_paths[nb_dll_paths++] = dlldir; } else if ((build_dir = wine_get_build_dir())) { dll_path_maxlen = strlen(build_dir) + sizeof("/programs"); } if (count) { p = path; while (*p) { while (*p == ':') *p++ = 0; if (!*p) break; dll_paths[nb_dll_paths] = p; while (*p && *p != ':') p++; if (p - dll_paths[nb_dll_paths] > dll_path_maxlen) dll_path_maxlen = p - dll_paths[nb_dll_paths]; nb_dll_paths++; } } /* append default dll dir (if not empty) to path */ if ((len = strlen(default_dlldir)) > 0) { if (len > dll_path_maxlen) dll_path_maxlen = len; dll_paths[nb_dll_paths++] = default_dlldir; } }
static BOOL get_mono_path(LPWSTR path) { static const WCHAR subdir_mono[] = {'\\','m','o','n','o',0}; static const WCHAR sibling_mono[] = {'\\','.','.','\\','m','o','n','o',0}; WCHAR base_path[MAX_PATH]; const char *unix_data_dir; WCHAR *dos_data_dir; BOOL build_tree = FALSE; static WCHAR* (CDECL *wine_get_dos_file_name)(const char*); /* First try c:\windows\mono */ GetWindowsDirectoryW(base_path, MAX_PATH); strcatW(base_path, subdir_mono); if (get_mono_path_from_folder(base_path, path)) return TRUE; /* Next: /usr/share/wine/mono */ unix_data_dir = wine_get_data_dir(); if (!unix_data_dir) { unix_data_dir = wine_get_build_dir(); build_tree = TRUE; } if (unix_data_dir) { if (!wine_get_dos_file_name) wine_get_dos_file_name = (void*)GetProcAddress(GetModuleHandleA("kernel32"), "wine_get_dos_file_name"); if (wine_get_dos_file_name) { dos_data_dir = wine_get_dos_file_name(unix_data_dir); if (dos_data_dir) { strcpyW(base_path, dos_data_dir); strcatW(base_path, build_tree ? sibling_mono : subdir_mono); HeapFree(GetProcessHeap(), 0, dos_data_dir); if (get_mono_path_from_folder(base_path, path)) return TRUE; } } } /* Last: the registry */ return get_mono_path_from_registry(path); }
/* retrieve the (unix) path to the wine.inf file */ static char *get_wine_inf_path(void) { const char *build_dir, *data_dir; char *name = NULL; if ((data_dir = wine_get_data_dir())) { if (!(name = HeapAlloc( GetProcessHeap(), 0, strlen(data_dir) + sizeof("/wine.inf") ))) return NULL; strcpy( name, data_dir ); strcat( name, "/wine.inf" ); } else if ((build_dir = wine_get_build_dir())) { if (!(name = HeapAlloc( GetProcessHeap(), 0, strlen(build_dir) + sizeof("/tools/wine.inf") ))) return NULL; strcpy( name, build_dir ); strcat( name, "/tools/wine.inf" ); } return name; }
/* create fake dlls in dirname for all the files we can find */ static BOOL create_wildcard_dlls( const WCHAR *dirname ) { const char *build_dir = wine_get_build_dir(); const char *path; unsigned int i, maxlen = 0; char *file; WCHAR *dest; if (build_dir) maxlen = strlen(build_dir) + sizeof("/programs/"); for (i = 0; (path = wine_dll_enum_load_path(i)); i++) maxlen = max( maxlen, strlen(path) ); maxlen += 2 * max_dll_name_len + 2 + sizeof(".dll.fake"); if (!(file = HeapAlloc( GetProcessHeap(), 0, maxlen ))) return FALSE; if (!(dest = HeapAlloc( GetProcessHeap(), 0, (strlenW(dirname) + max_dll_name_len) * sizeof(WCHAR) ))) { HeapFree( GetProcessHeap(), 0, file ); return FALSE; } strcpyW( dest, dirname ); dest[strlenW(dest) - 1] = 0; /* remove wildcard */ if (build_dir) { strcpy( file, build_dir ); strcat( file, "/dlls" ); install_lib_dir( dest, file, ".dll" ); strcpy( file, build_dir ); strcat( file, "/programs" ); install_lib_dir( dest, file, ".exe" ); } for (i = 0; (path = wine_dll_enum_load_path( i )); i++) { strcpy( file, path ); strcat( file, "/fakedlls" ); install_lib_dir( dest, file, NULL ); } HeapFree( GetProcessHeap(), 0, file ); HeapFree( GetProcessHeap(), 0, dest ); return TRUE; }
/* load the list of available libraries */ static void load_library_list( HWND dialog ) { unsigned int i = 0; const char *path, *build_dir = wine_get_build_dir(); char item1[256], item2[256]; HCURSOR old_cursor = SetCursor( LoadCursorW(0, (LPWSTR)IDC_WAIT) ); if (build_dir) { char *dir = HeapAlloc( GetProcessHeap(), 0, strlen(build_dir) + sizeof("/dlls") ); strcpy( dir, build_dir ); strcat( dir, "/dlls" ); load_library_list_from_dir( dialog, dir, TRUE ); HeapFree( GetProcessHeap(), 0, dir ); } while ((path = wine_dll_enum_load_path( i++ ))) load_library_list_from_dir( dialog, path, FALSE ); /* get rid of duplicate entries */ SendDlgItemMessageA( dialog, IDC_DLLCOMBO, CB_GETLBTEXT, 0, (LPARAM)item1 ); i = 1; while (SendDlgItemMessageA( dialog, IDC_DLLCOMBO, CB_GETLBTEXT, i, (LPARAM)item2 ) >= 0) { if (!strcmp( item1, item2 )) { SendDlgItemMessageA( dialog, IDC_DLLCOMBO, CB_DELETESTRING, i, 0 ); } else { strcpy( item1, item2 ); i++; } } SetCursor( old_cursor ); }