1 /* 2 * Copyright (C) 2009 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "resource.h" 27 #include <shlwapi.h> 28 #include <tchar.h> 29 #include <windows.h> 30 31 static LPTSTR getStringValue(HKEY key, LPCTSTR valueName) 32 { 33 DWORD type = 0; 34 DWORD bufferSize = 0; 35 if (RegQueryValueEx(key, valueName, 0, &type, 0, &bufferSize) != ERROR_SUCCESS || type != REG_SZ) 36 return 0; 37 38 LPTSTR buffer = static_cast<LPTSTR>(malloc(bufferSize)); 39 if (RegQueryValueEx(key, valueName, 0, &type, reinterpret_cast<LPBYTE>(buffer), &bufferSize) != ERROR_SUCCESS) { 40 free(buffer); 41 return 0; 42 } 43 44 return buffer; 45 } 46 47 static LPTSTR applePathFromRegistry(LPCTSTR key, LPCTSTR value) 48 { 49 HKEY applePathKey = 0; 50 LONG error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &applePathKey); 51 if (error != ERROR_SUCCESS) 52 return 0; 53 LPTSTR path = getStringValue(applePathKey, value); 54 RegCloseKey(applePathKey); 55 return path; 56 } 57 58 static LPTSTR safariInstallDir() 59 { 60 return applePathFromRegistry(TEXT("SOFTWARE\\Apple Computer, Inc.\\Safari"), TEXT("InstallDir")); 61 } 62 63 static LPTSTR safariBrowserExe() 64 { 65 return applePathFromRegistry(TEXT("SOFTWARE\\Apple Computer, Inc.\\Safari"), TEXT("BrowserExe")); 66 } 67 68 int APIENTRY _tWinMain(HINSTANCE instance, HINSTANCE, LPTSTR commandLine, int) 69 { 70 LPTSTR path = safariInstallDir(); 71 LPTSTR browserExe = safariBrowserExe(); 72 if (!path || !browserExe) { 73 MessageBox(0, TEXT("Safari must be installed to run a WebKit nightly. You can download Safari from http://www.apple.com/safari/download"), TEXT("Safari not found"), MB_ICONSTOP); 74 return 1; 75 } 76 77 // Set WEBKITNIGHTLY environment variable to point to the nightly bits 78 TCHAR exePath[MAX_PATH]; 79 if (!GetModuleFileName(0, exePath, ARRAYSIZE(exePath))) 80 return 1; 81 if (!PathRemoveFileSpec(exePath)) 82 return 1; 83 SetEnvironmentVariable(TEXT("WEBKITNIGHTLY"), exePath); 84 85 // Launch Safari as a child process 86 STARTUPINFO startupInfo = {0}; 87 startupInfo.cb = sizeof(startupInfo); 88 PROCESS_INFORMATION processInfo = {0}; 89 if (!CreateProcess(browserExe, commandLine, 0, 0, FALSE, NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, 0, path, &startupInfo, &processInfo)) 90 MessageBox(0, TEXT("Safari could not be launched. Please make sure you have the latest version of Safari installed and try again. You can download Safari from http://www.apple.com/safari/download"), TEXT("Safari launch failed"), MB_ICONSTOP); 91 92 free(browserExe); 93 free(path); 94 return 0; 95 } 96