From 07165f73c4a93540df1c0af46e49e68935bf3e33 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 20 Jun 2012 15:36:14 -0500 Subject: Add launcher source and resources --- PC/launcher.c | 1377 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ PC/launcher.ico | Bin 0 -> 19790 bytes PC/pylauncher.rc | 3 + 3 files changed, 1380 insertions(+) create mode 100644 PC/launcher.c create mode 100644 PC/launcher.ico create mode 100644 PC/pylauncher.rc diff --git a/PC/launcher.c b/PC/launcher.c new file mode 100644 index 0000000..22d2974 --- /dev/null +++ b/PC/launcher.c @@ -0,0 +1,1377 @@ +/* + * Copyright (C) 2011-2012 Vinay Sajip. All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Based on the work of: + * + * Mark Hammond (original author of Python version) + * Curt Hagenlocher (job management) + */ + +#include +#include +#include +#include + +#define BUFSIZE 256 +#define MSGSIZE 1024 + +/* Build options. */ +#define SKIP_PREFIX +/* #define SEARCH_PATH */ + +/* Just for now - static definition */ + +static FILE * log_fp = NULL; + +static wchar_t * +skip_whitespace(wchar_t * p) +{ + while (*p && isspace(*p)) + ++p; + return p; +} + +/* + * This function is here to minimise Visual Studio + * warnings about security implications of getenv, and to + * treat blank values as if they are absent. + */ +static wchar_t * get_env(wchar_t * key) +{ + wchar_t * result = _wgetenv(key); + + if (result) { + result = skip_whitespace(result); + if (*result == L'\0') + result = NULL; + } + return result; +} + +static void +debug(wchar_t * format, ...) +{ + va_list va; + + if (log_fp != NULL) { + va_start(va, format); + vfwprintf_s(log_fp, format, va); + } +} + +static void +winerror(int rc, wchar_t * message, int size) +{ + FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + message, size, NULL); +} + +static void +error(int rc, wchar_t * format, ... ) +{ + va_list va; + wchar_t message[MSGSIZE]; + wchar_t win_message[MSGSIZE]; + int len; + + va_start(va, format); + len = _vsnwprintf_s(message, MSGSIZE, _TRUNCATE, format, va); + + if (rc == 0) { /* a Windows error */ + winerror(GetLastError(), win_message, MSGSIZE); + if (len >= 0) { + _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %s", + win_message); + } + } + +#if !defined(_WINDOWS) + fwprintf(stderr, L"%s\n", message); +#else + MessageBox(NULL, message, TEXT("Python Launcher is sorry to say ..."), MB_OK); +#endif + ExitProcess(rc); +} + +#if defined(_WINDOWS) + +#define PYTHON_EXECUTABLE L"pythonw.exe" + +#else + +#define PYTHON_EXECUTABLE L"python.exe" + +#endif + +#define RC_NO_STD_HANDLES 100 +#define RC_CREATE_PROCESS 101 +#define RC_BAD_VIRTUAL_PATH 102 +#define RC_NO_PYTHON 103 + +#define MAX_VERSION_SIZE 4 + +typedef struct { + wchar_t version[MAX_VERSION_SIZE]; /* m.n */ + int bits; /* 32 or 64 */ + wchar_t executable[MAX_PATH]; +} INSTALLED_PYTHON; + +/* + * To avoid messing about with heap allocations, just assume we can allocate + * statically and never have to deal with more versions than this. + */ +#define MAX_INSTALLED_PYTHONS 100 + +static INSTALLED_PYTHON installed_pythons[MAX_INSTALLED_PYTHONS]; + +static size_t num_installed_pythons = 0; + +/* to hold SOFTWARE\Python\PythonCore\X.Y\InstallPath */ +#define IP_BASE_SIZE 40 +#define IP_SIZE (IP_BASE_SIZE + MAX_VERSION_SIZE) +#define CORE_PATH L"SOFTWARE\\Python\\PythonCore" + +static wchar_t * location_checks[] = { + L"\\", + L"\\PCBuild\\", + L"\\PCBuild\\amd64\\", + NULL +}; + +static INSTALLED_PYTHON * +find_existing_python(wchar_t * path) +{ + INSTALLED_PYTHON * result = NULL; + size_t i; + INSTALLED_PYTHON * ip; + + for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++, ip++) { + if (_wcsicmp(path, ip->executable) == 0) { + result = ip; + break; + } + } + return result; +} + +static void +locate_pythons_for_key(HKEY root, REGSAM flags) +{ + HKEY core_root, ip_key; + LSTATUS status = RegOpenKeyExW(root, CORE_PATH, 0, flags, &core_root); + wchar_t message[MSGSIZE]; + DWORD i; + size_t n; + BOOL ok; + DWORD type, data_size, attrs; + INSTALLED_PYTHON * ip, * pip; + wchar_t ip_path[IP_SIZE]; + wchar_t * check; + wchar_t ** checkp; + wchar_t *key_name = (root == HKEY_LOCAL_MACHINE) ? L"HKLM" : L"HKCU"; + + if (status != ERROR_SUCCESS) + debug(L"locate_pythons_for_key: unable to open PythonCore key in %s\n", + key_name); + else { + ip = &installed_pythons[num_installed_pythons]; + for (i = 0; num_installed_pythons < MAX_INSTALLED_PYTHONS; i++) { + status = RegEnumKeyW(core_root, i, ip->version, MAX_VERSION_SIZE); + if (status != ERROR_SUCCESS) { + if (status != ERROR_NO_MORE_ITEMS) { + /* unexpected error */ + winerror(status, message, MSGSIZE); + debug(L"Can't enumerate registry key for version %s: %s\n", + ip->version, message); + } + break; + } + else { + _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE, + L"%s\\%s\\InstallPath", CORE_PATH, ip->version); + status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key); + if (status != ERROR_SUCCESS) { + winerror(status, message, MSGSIZE); + // Note: 'message' already has a trailing \n + debug(L"%s\\%s: %s", key_name, ip_path, message); + continue; + } + data_size = sizeof(ip->executable) - 1; + status = RegQueryValueEx(ip_key, NULL, NULL, &type, + (LPBYTE) ip->executable, &data_size); + RegCloseKey(ip_key); + if (status != ERROR_SUCCESS) { + winerror(status, message, MSGSIZE); + debug(L"%s\\%s: %s\n", key_name, ip_path, message); + continue; + } + if (type == REG_SZ) { + data_size = data_size / sizeof(wchar_t) - 1; /* for NUL */ + if (ip->executable[data_size - 1] == L'\\') + --data_size; /* reg value ended in a backslash */ + /* ip->executable is data_size long */ + for (checkp = location_checks; *checkp; ++checkp) { + check = *checkp; + _snwprintf_s(&ip->executable[data_size], + MAX_PATH - data_size, + MAX_PATH - data_size, + L"%s%s", check, PYTHON_EXECUTABLE); + attrs = GetFileAttributesW(ip->executable); + if (attrs == INVALID_FILE_ATTRIBUTES) { + winerror(GetLastError(), message, MSGSIZE); + debug(L"locate_pythons_for_key: %s: %s", + ip->executable, message); + } + else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { + debug(L"locate_pythons_for_key: '%s' is a \ +directory\n", + ip->executable, attrs); + } + else if (find_existing_python(ip->executable)) { + debug(L"locate_pythons_for_key: %s: already \ +found: %s\n", ip->executable); + } + else { + /* check the executable type. */ + ok = GetBinaryTypeW(ip->executable, &attrs); + if (!ok) { + debug(L"Failure getting binary type: %s\n", + ip->executable); + } + else { + if (attrs == SCS_64BIT_BINARY) + ip->bits = 64; + else if (attrs == SCS_32BIT_BINARY) + ip->bits = 32; + else + ip->bits = 0; + if (ip->bits == 0) { + debug(L"locate_pythons_for_key: %s: \ +invalid binary type: %X\n", + ip->executable, attrs); + } + else { + if (wcschr(ip->executable, L' ') != NULL) { + /* has spaces, so quote */ + n = wcslen(ip->executable); + memmove(&ip->executable[1], + ip->executable, n * sizeof(wchar_t)); + ip->executable[0] = L'\"'; + ip->executable[n + 1] = L'\"'; + ip->executable[n + 2] = L'\0'; + } + debug(L"locate_pythons_for_key: %s \ +is a %dbit executable\n", + ip->executable, ip->bits); + ++num_installed_pythons; + pip = ip++; + if (num_installed_pythons >= + MAX_INSTALLED_PYTHONS) + break; + /* Copy over the attributes for the next */ + *ip = *pip; + } + } + } + } + } + } + } + RegCloseKey(core_root); + } +} + +static int +compare_pythons(const void * p1, const void * p2) +{ + INSTALLED_PYTHON * ip1 = (INSTALLED_PYTHON *) p1; + INSTALLED_PYTHON * ip2 = (INSTALLED_PYTHON *) p2; + /* note reverse sorting on version */ + int result = wcscmp(ip2->version, ip1->version); + + if (result == 0) + result = ip2->bits - ip1->bits; /* 64 before 32 */ + return result; +} + +static void +locate_all_pythons() +{ +#if defined(_M_X64) + // If we are a 64bit process, first hit the 32bit keys. + debug(L"locating Pythons in 32bit registry\n"); + locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_32KEY); + locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_32KEY); +#else + // If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. + BOOL f64 = FALSE; + if (IsWow64Process(GetCurrentProcess(), &f64) && f64) { + debug(L"locating Pythons in 64bit registry\n"); + locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_64KEY); + locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_64KEY); + } +#endif + // now hit the "native" key for this process bittedness. + debug(L"locating Pythons in native registry\n"); + locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ); + locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ); + qsort(installed_pythons, num_installed_pythons, sizeof(INSTALLED_PYTHON), + compare_pythons); +} + +static INSTALLED_PYTHON * +find_python_by_version(wchar_t const * wanted_ver) +{ + INSTALLED_PYTHON * result = NULL; + INSTALLED_PYTHON * ip = installed_pythons; + size_t i, n; + size_t wlen = wcslen(wanted_ver); + int bits = 0; + + if (wcsstr(wanted_ver, L"-32")) + bits = 32; + for (i = 0; i < num_installed_pythons; i++, ip++) { + n = wcslen(ip->version); + if (n > wlen) + n = wlen; + if ((wcsncmp(ip->version, wanted_ver, n) == 0) && + /* bits == 0 => don't care */ + ((bits == 0) || (ip->bits == bits))) { + result = ip; + break; + } + } + return result; +} + + +static wchar_t appdata_ini_path[MAX_PATH]; +static wchar_t launcher_ini_path[MAX_PATH]; + +/* + * Get a value either from the environment or a configuration file. + * The key passed in will either be "python", "python2" or "python3". + */ +static wchar_t * +get_configured_value(wchar_t * key) +{ +/* + * Note: this static value is used to return a configured value + * obtained either from the environment or configuration file. + * This should be OK since there wouldn't be any concurrent calls. + */ + static wchar_t configured_value[MSGSIZE]; + wchar_t * result = NULL; + wchar_t * found_in = L"environment"; + DWORD size; + + /* First, search the environment. */ + _snwprintf_s(configured_value, MSGSIZE, _TRUNCATE, L"py_%s", key); + result = get_env(configured_value); + if (result == NULL && appdata_ini_path[0]) { + /* Not in environment: check local configuration. */ + size = GetPrivateProfileStringW(L"defaults", key, NULL, + configured_value, MSGSIZE, + appdata_ini_path); + if (size > 0) { + result = configured_value; + found_in = appdata_ini_path; + } + } + if (result == NULL && launcher_ini_path[0]) { + /* Not in environment or local: check global configuration. */ + size = GetPrivateProfileStringW(L"defaults", key, NULL, + configured_value, MSGSIZE, + launcher_ini_path); + if (size > 0) { + result = configured_value; + found_in = launcher_ini_path; + } + } + if (result) { + debug(L"found configured value '%s=%s' in %s\n", + key, result, found_in ? found_in : L"(unknown)"); + } else { + debug(L"found no configured value for '%s'\n", key); + } + return result; +} + +static INSTALLED_PYTHON * +locate_python(wchar_t * wanted_ver) +{ + static wchar_t config_key [] = { L"pythonX" }; + static wchar_t * last_char = &config_key[sizeof(config_key) / + sizeof(wchar_t) - 2]; + INSTALLED_PYTHON * result = NULL; + size_t n = wcslen(wanted_ver); + wchar_t * configured_value; + + if (num_installed_pythons == 0) + locate_all_pythons(); + + if (n == 1) { /* just major version specified */ + *last_char = *wanted_ver; + configured_value = get_configured_value(config_key); + if (configured_value != NULL) + wanted_ver = configured_value; + } + if (*wanted_ver) { + result = find_python_by_version(wanted_ver); + debug(L"search for Python version '%s' found ", wanted_ver); + if (result) { + debug(L"'%s'\n", result->executable); + } else { + debug(L"no interpreter\n"); + } + } + else { + *last_char = L'\0'; /* look for an overall default */ + configured_value = get_configured_value(config_key); + if (configured_value) + result = find_python_by_version(configured_value); + if (result == NULL) + result = find_python_by_version(L"2"); + if (result == NULL) + result = find_python_by_version(L"3"); + debug(L"search for default Python found "); + if (result) { + debug(L"version %s at '%s'\n", + result->version, result->executable); + } else { + debug(L"no interpreter\n"); + } + } + return result; +} + +/* + * Process creation code + */ + +static BOOL +safe_duplicate_handle(HANDLE in, HANDLE * pout) +{ + BOOL ok; + HANDLE process = GetCurrentProcess(); + DWORD rc; + + *pout = NULL; + ok = DuplicateHandle(process, in, process, pout, 0, TRUE, + DUPLICATE_SAME_ACCESS); + if (!ok) { + rc = GetLastError(); + if (rc == ERROR_INVALID_HANDLE) { + debug(L"DuplicateHandle returned ERROR_INVALID_HANDLE\n"); + ok = TRUE; + } + else { + debug(L"DuplicateHandle returned %d\n", rc); + } + } + return ok; +} + +static BOOL WINAPI +ctrl_c_handler(DWORD code) +{ + return TRUE; /* We just ignore all control events. */ +} + +static void +run_child(wchar_t * cmdline) +{ + HANDLE job; + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + DWORD rc; + BOOL ok; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + + debug(L"run_child: about to run '%s'\n", cmdline); + job = CreateJobObject(NULL, NULL); + ok = QueryInformationJobObject(job, JobObjectExtendedLimitInformation, + &info, sizeof(info), &rc); + if (!ok || (rc != sizeof(info)) || !job) + error(RC_CREATE_PROCESS, L"Job information querying failed"); + info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | + JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; + ok = SetInformationJobObject(job, JobObjectExtendedLimitInformation, &info, + sizeof(info)); + if (!ok) + error(RC_CREATE_PROCESS, L"Job information setting failed"); + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + ok = safe_duplicate_handle(GetStdHandle(STD_INPUT_HANDLE), &si.hStdInput); + if (!ok) + error(RC_NO_STD_HANDLES, L"stdin duplication failed"); + ok = safe_duplicate_handle(GetStdHandle(STD_OUTPUT_HANDLE), &si.hStdOutput); + if (!ok) + error(RC_NO_STD_HANDLES, L"stdout duplication failed"); + ok = safe_duplicate_handle(GetStdHandle(STD_ERROR_HANDLE), &si.hStdError); + if (!ok) + error(RC_NO_STD_HANDLES, L"stderr duplication failed"); + + ok = SetConsoleCtrlHandler(ctrl_c_handler, TRUE); + if (!ok) + error(RC_CREATE_PROCESS, L"control handler setting failed"); + + si.dwFlags = STARTF_USESTDHANDLES; + ok = CreateProcessW(NULL, cmdline, NULL, NULL, TRUE, + 0, NULL, NULL, &si, &pi); + if (!ok) + error(RC_CREATE_PROCESS, L"Unable to create process using '%s'", cmdline); + AssignProcessToJobObject(job, pi.hProcess); + CloseHandle(pi.hThread); + WaitForSingleObject(pi.hProcess, INFINITE); + ok = GetExitCodeProcess(pi.hProcess, &rc); + if (!ok) + error(RC_CREATE_PROCESS, L"Failed to get exit code of process"); + debug(L"child process exit code: %d\n", rc); + ExitProcess(rc); +} + +static void +invoke_child(wchar_t * executable, wchar_t * suffix, wchar_t * cmdline) +{ + wchar_t * child_command; + size_t child_command_size; + BOOL no_suffix = (suffix == NULL) || (*suffix == L'\0'); + BOOL no_cmdline = (*cmdline == L'\0'); + + if (no_suffix && no_cmdline) + run_child(executable); + else { + if (no_suffix) { + /* add 2 for space separator + terminating NUL. */ + child_command_size = wcslen(executable) + wcslen(cmdline) + 2; + } + else { + /* add 3 for 2 space separators + terminating NUL. */ + child_command_size = wcslen(executable) + wcslen(suffix) + + wcslen(cmdline) + 3; + } + child_command = calloc(child_command_size, sizeof(wchar_t)); + if (child_command == NULL) + error(RC_CREATE_PROCESS, L"unable to allocate %d bytes for child command.", + child_command_size); + if (no_suffix) + _snwprintf_s(child_command, child_command_size, + child_command_size - 1, L"%s %s", + executable, cmdline); + else + _snwprintf_s(child_command, child_command_size, + child_command_size - 1, L"%s %s %s", + executable, suffix, cmdline); + run_child(child_command); + free(child_command); + } +} + +static wchar_t * builtin_virtual_paths [] = { + L"/usr/bin/env python", + L"/usr/bin/python", + L"/usr/local/bin/python", + L"python", + NULL +}; + +/* For now, a static array of commands. */ + +#define MAX_COMMANDS 100 + +typedef struct { + wchar_t key[MAX_PATH]; + wchar_t value[MSGSIZE]; +} COMMAND; + +static COMMAND commands[MAX_COMMANDS]; +static int num_commands = 0; + +#if defined(SKIP_PREFIX) + +static wchar_t * builtin_prefixes [] = { + /* These must be in an order that the longest matches should be found, + * i.e. if the prefix is "/usr/bin/env ", it should match that entry + * *before* matching "/usr/bin/". + */ + L"/usr/bin/env ", + L"/usr/bin/", + L"/usr/local/bin/", + NULL +}; + +static wchar_t * skip_prefix(wchar_t * name) +{ + wchar_t ** pp = builtin_prefixes; + wchar_t * result = name; + wchar_t * p; + size_t n; + + for (; p = *pp; pp++) { + n = wcslen(p); + if (_wcsnicmp(p, name, n) == 0) { + result += n; /* skip the prefix */ + if (p[n - 1] == L' ') /* No empty strings in table, so n > 1 */ + result = skip_whitespace(result); + break; + } + } + return result; +} + +#endif + +#if defined(SEARCH_PATH) + +static COMMAND path_command; + +static COMMAND * find_on_path(wchar_t * name) +{ + wchar_t * pathext; + size_t varsize; + wchar_t * context = NULL; + wchar_t * extension; + COMMAND * result = NULL; + DWORD len; + errno_t rc; + + wcscpy_s(path_command.key, MAX_PATH, name); + if (wcschr(name, L'.') != NULL) { + /* assume it has an extension. */ + len = SearchPathW(NULL, name, NULL, MSGSIZE, path_command.value, NULL); + if (len) { + result = &path_command; + } + } + else { + /* No extension - search using registered extensions. */ + rc = _wdupenv_s(&pathext, &varsize, L"PATHEXT"); + if (rc == 0) { + extension = wcstok_s(pathext, L";", &context); + while (extension) { + len = SearchPathW(NULL, name, extension, MSGSIZE, path_command.value, NULL); + if (len) { + result = &path_command; + break; + } + extension = wcstok_s(NULL, L";", &context); + } + free(pathext); + } + } + return result; +} + +#endif + +static COMMAND * find_command(wchar_t * name) +{ + COMMAND * result = NULL; + COMMAND * cp = commands; + int i; + + for (i = 0; i < num_commands; i++, cp++) { + if (_wcsicmp(cp->key, name) == 0) { + result = cp; + break; + } + } +#if defined(SEARCH_PATH) + if (result == NULL) + result = find_on_path(name); +#endif + return result; +} + +static void +update_command(COMMAND * cp, wchar_t * name, wchar_t * cmdline) +{ + wcsncpy_s(cp->key, MAX_PATH, name, _TRUNCATE); + wcsncpy_s(cp->value, MSGSIZE, cmdline, _TRUNCATE); +} + +static void +add_command(wchar_t * name, wchar_t * cmdline) +{ + if (num_commands >= MAX_COMMANDS) { + debug(L"can't add %s = '%s': no room\n", name, cmdline); + } + else { + COMMAND * cp = &commands[num_commands++]; + + update_command(cp, name, cmdline); + } +} + +static void +read_config_file(wchar_t * config_path) +{ + wchar_t keynames[MSGSIZE]; + wchar_t value[MSGSIZE]; + DWORD read; + wchar_t * key; + COMMAND * cp; + wchar_t * cmdp; + + read = GetPrivateProfileStringW(L"commands", NULL, NULL, keynames, MSGSIZE, + config_path); + if (read == MSGSIZE - 1) { + debug(L"read_commands: %s: not enough space for names\n", config_path); + } + key = keynames; + while (*key) { + read = GetPrivateProfileStringW(L"commands", key, NULL, value, MSGSIZE, + config_path); + if (read == MSGSIZE - 1) { + debug(L"read_commands: %s: not enough space for %s\n", + config_path, key); + } + cmdp = skip_whitespace(value); + if (*cmdp) { + cp = find_command(key); + if (cp == NULL) + add_command(key, value); + else + update_command(cp, key, value); + } + key += wcslen(key) + 1; + } +} + +static void read_commands() +{ + if (launcher_ini_path[0]) + read_config_file(launcher_ini_path); + if (appdata_ini_path[0]) + read_config_file(appdata_ini_path); +} + +static BOOL +parse_shebang(wchar_t * shebang_line, int nchars, wchar_t ** command, + wchar_t ** suffix) +{ + BOOL rc = FALSE; + wchar_t ** vpp; + size_t plen; + wchar_t * p; + wchar_t zapped; + wchar_t * endp = shebang_line + nchars - 1; + COMMAND * cp; + wchar_t * skipped; + + *command = NULL; /* failure return */ + *suffix = NULL; + + if ((*shebang_line++ == L'#') && (*shebang_line++ == L'!')) { + shebang_line = skip_whitespace(shebang_line); + if (*shebang_line) { + *command = shebang_line; + for (vpp = builtin_virtual_paths; *vpp; ++vpp) { + plen = wcslen(*vpp); + if (wcsncmp(shebang_line, *vpp, plen) == 0) { + rc = TRUE; + /* We can do this because all builtin commands contain + * "python". + */ + *command = wcsstr(shebang_line, L"python"); + break; + } + } + if (*vpp == NULL) { + /* + * Not found in builtins - look in customised commands. + * + * We can't permanently modify the shebang line in case + * it's not a customised command, but we can temporarily + * stick a NUL after the command while searching for it, + * then put back the char we zapped. + */ +#if defined(SKIP_PREFIX) + skipped = skip_prefix(shebang_line); +#else + skipped = shebang_line; +#endif + p = wcspbrk(skipped, L" \t\r\n"); + if (p != NULL) { + zapped = *p; + *p = L'\0'; + } + cp = find_command(skipped); + if (p != NULL) + *p = zapped; + if (cp != NULL) { + *command = cp->value; + if (p != NULL) + *suffix = skip_whitespace(p); + } + } + /* remove trailing whitespace */ + while ((endp > shebang_line) && isspace(*endp)) + --endp; + if (endp > shebang_line) + endp[1] = L'\0'; + } + } + return rc; +} + +/* #define CP_UTF8 65001 defined in winnls.h */ +#define CP_UTF16LE 1200 +#define CP_UTF16BE 1201 +#define CP_UTF32LE 12000 +#define CP_UTF32BE 12001 + +typedef struct { + int length; + char sequence[4]; + UINT code_page; +} BOM; + +/* + * Strictly, we don't need to handle UTF-16 anf UTF-32, since Python itself + * doesn't. Never mind, one day it might - there's no harm leaving it in. + */ +static BOM BOMs[] = { + { 3, { 0xEF, 0xBB, 0xBF }, CP_UTF8 }, /* UTF-8 - keep first */ + { 2, { 0xFF, 0xFE }, CP_UTF16LE }, /* UTF-16LE */ + { 2, { 0xFE, 0xFF }, CP_UTF16BE }, /* UTF-16BE */ + { 4, { 0xFF, 0xFE, 0x00, 0x00 }, CP_UTF32LE }, /* UTF-32LE */ + { 4, { 0x00, 0x00, 0xFE, 0xFF }, CP_UTF32BE }, /* UTF-32BE */ + { 0 } /* sentinel */ +}; + +static BOM * +find_BOM(char * buffer) +{ +/* + * Look for a BOM in the input and return a pointer to the + * corresponding structure, or NULL if not found. + */ + BOM * result = NULL; + BOM *bom; + + for (bom = BOMs; bom->length; bom++) { + if (strncmp(bom->sequence, buffer, bom->length) == 0) { + result = bom; + break; + } + } + return result; +} + +static char * +find_terminator(char * buffer, int len, BOM *bom) +{ + char * result = NULL; + char * end = buffer + len; + char * p; + char c; + int cp; + + for (p = buffer; p < end; p++) { + c = *p; + if (c == '\r') { + result = p; + break; + } + if (c == '\n') { + result = p; + break; + } + } + if (result != NULL) { + cp = bom->code_page; + + /* adjustments to include all bytes of the char */ + /* no adjustment needed for UTF-8 or big endian */ + if (cp == CP_UTF16LE) + ++result; + else if (cp == CP_UTF32LE) + result += 3; + ++result; /* point just past terminator */ + } + return result; +} + +static BOOL +validate_version(wchar_t * p) +{ + BOOL result = TRUE; + + if (!isdigit(*p)) /* expect major version */ + result = FALSE; + else if (*++p) { /* more to do */ + if (*p != L'.') /* major/minor separator */ + result = FALSE; + else { + ++p; + if (!isdigit(*p)) /* expect minor version */ + result = FALSE; + else { + ++p; + if (*p) { /* more to do */ + if (*p != L'-') + result = FALSE; + else { + ++p; + if ((*p != '3') && (*++p != '2') && !*++p) + result = FALSE; + } + } + } + } + } + return result; +} + +typedef struct { + unsigned short min; + unsigned short max; + wchar_t version[MAX_VERSION_SIZE]; +} PYC_MAGIC; + +static PYC_MAGIC magic_values[] = { + { 0xc687, 0xc687, L"2.0" }, + { 0xeb2a, 0xeb2a, L"2.1" }, + { 0xed2d, 0xed2d, L"2.2" }, + { 0xf23b, 0xf245, L"2.3" }, + { 0xf259, 0xf26d, L"2.4" }, + { 0xf277, 0xf2b3, L"2.5" }, + { 0xf2c7, 0xf2d1, L"2.6" }, + { 0xf2db, 0xf303, L"2.7" }, + { 0x0bb8, 0x0c3b, L"3.0" }, + { 0x0c45, 0x0c4f, L"3.1" }, + { 0x0c58, 0x0c6c, L"3.2" }, + { 0x0c76, 0x0c76, L"3.3" }, + { 0 } +}; + +static INSTALLED_PYTHON * +find_by_magic(unsigned short magic) +{ + INSTALLED_PYTHON * result = NULL; + PYC_MAGIC * mp; + + for (mp = magic_values; mp->min; mp++) { + if ((magic >= mp->min) && (magic <= mp->max)) { + result = locate_python(mp->version); + if (result != NULL) + break; + } + } + return result; +} + +static void +maybe_handle_shebang(wchar_t ** argv, wchar_t * cmdline) +{ +/* + * Look for a shebang line in the first argument. If found + * and we spawn a child process, this never returns. If it + * does return then we process the args "normally". + * + * argv[0] might be a filename with a shebang. + */ + FILE * fp; + errno_t rc = _wfopen_s(&fp, *argv, L"rb"); + unsigned char buffer[BUFSIZE]; + wchar_t shebang_line[BUFSIZE + 1]; + size_t read; + char *p; + char * start; + char * shebang_alias = (char *) shebang_line; + BOM* bom; + int i, j, nchars = 0; + int header_len; + BOOL is_virt; + wchar_t * command; + wchar_t * suffix; + INSTALLED_PYTHON * ip; + + if (rc == 0) { + read = fread(buffer, sizeof(char), BUFSIZE, fp); + debug(L"maybe_handle_shebang: read %d bytes\n", read); + fclose(fp); + + if ((read >= 4) && (buffer[3] == '\n') && (buffer[2] == '\r')) { + ip = find_by_magic((buffer[1] << 8 | buffer[0]) & 0xFFFF); + if (ip != NULL) { + debug(L"script file is compiled against Python %s\n", + ip->version); + invoke_child(ip->executable, NULL, cmdline); + } + } + /* Look for BOM */ + bom = find_BOM(buffer); + if (bom == NULL) { + start = buffer; + debug(L"maybe_handle_shebang: BOM not found, using UTF-8\n"); + bom = BOMs; /* points to UTF-8 entry - the default */ + } + else { + debug(L"maybe_handle_shebang: BOM found, code page %d\n", + bom->code_page); + start = &buffer[bom->length]; + } + p = find_terminator(start, BUFSIZE, bom); + /* + * If no CR or LF was found in the heading, + * we assume it's not a shebang file. + */ + if (p == NULL) { + debug(L"maybe_handle_shebang: No line terminator found\n"); + } + else { + /* + * Found line terminator - parse the shebang. + * + * Strictly, we don't need to handle UTF-16 anf UTF-32, + * since Python itself doesn't. + * Never mind, one day it might. + */ + header_len = (int) (p - start); + switch(bom->code_page) { + case CP_UTF8: + nchars = MultiByteToWideChar(bom->code_page, + 0, + start, header_len, shebang_line, + BUFSIZE); + break; + case CP_UTF16BE: + if (header_len % 2 != 0) { + debug(L"maybe_handle_shebang: UTF-16BE, but an odd number \ +of bytes: %d\n", header_len); + /* nchars = 0; Not needed - initialised to 0. */ + } + else { + for (i = header_len; i > 0; i -= 2) { + shebang_alias[i - 1] = start[i - 2]; + shebang_alias[i - 2] = start[i - 1]; + } + nchars = header_len / sizeof(wchar_t); + } + break; + case CP_UTF16LE: + if ((header_len % 2) != 0) { + debug(L"UTF-16LE, but an odd number of bytes: %d\n", + header_len); + /* nchars = 0; Not needed - initialised to 0. */ + } + else { + /* no actual conversion needed. */ + memcpy(shebang_line, start, header_len); + nchars = header_len / sizeof(wchar_t); + } + break; + case CP_UTF32BE: + if (header_len % 4 != 0) { + debug(L"UTF-32BE, but not divisible by 4: %d\n", + header_len); + /* nchars = 0; Not needed - initialised to 0. */ + } + else { + for (i = header_len, j = header_len / 2; i > 0; i -= 4, + j -= 2) { + shebang_alias[j - 1] = start[i - 2]; + shebang_alias[j - 2] = start[i - 1]; + } + nchars = header_len / sizeof(wchar_t); + } + break; + case CP_UTF32LE: + if (header_len % 4 != 0) { + debug(L"UTF-32LE, but not divisible by 4: %d\n", + header_len); + /* nchars = 0; Not needed - initialised to 0. */ + } + else { + for (i = header_len, j = header_len / 2; i > 0; i -= 4, + j -= 2) { + shebang_alias[j - 1] = start[i - 3]; + shebang_alias[j - 2] = start[i - 4]; + } + nchars = header_len / sizeof(wchar_t); + } + break; + } + if (nchars > 0) { + shebang_line[--nchars] = L'\0'; + is_virt = parse_shebang(shebang_line, nchars, &command, + &suffix); + if (command != NULL) { + debug(L"parse_shebang: found command: %s\n", command); + if (!is_virt) { + invoke_child(command, suffix, cmdline); + } + else { + suffix = wcschr(command, L' '); + if (suffix != NULL) { + *suffix++ = L'\0'; + suffix = skip_whitespace(suffix); + } + if (wcsncmp(command, L"python", 6)) + error(RC_BAD_VIRTUAL_PATH, L"Unknown virtual \ +path '%s'", command); + command += 6; /* skip past "python" */ + if (*command && !validate_version(command)) + error(RC_BAD_VIRTUAL_PATH, L"Invalid version \ +specification: '%s'.\nIn the first line of the script, 'python' needs to be \ +followed by a valid version specifier.\nPlease check the documentation.", + command); + /* TODO could call validate_version(command) */ + ip = locate_python(command); + if (ip == NULL) { + error(RC_NO_PYTHON, L"Requested Python version \ +(%s) is not installed", command); + } + else { + invoke_child(ip->executable, suffix, cmdline); + } + } + } + } + } + } +} + +static wchar_t * +skip_me(wchar_t * cmdline) +{ + BOOL quoted; + wchar_t c; + wchar_t * result = cmdline; + + quoted = cmdline[0] == L'\"'; + if (!quoted) + c = L' '; + else { + c = L'\"'; + ++result; + } + result = wcschr(result, c); + if (result == NULL) /* when, for example, just exe name on command line */ + result = L""; + else { + ++result; /* skip past space or closing quote */ + result = skip_whitespace(result); + } + return result; +} + +static DWORD version_high = 0; +static DWORD version_low = 0; + +static void +get_version_info(wchar_t * version_text, size_t size) +{ + WORD maj, min, rel, bld; + + if (!version_high && !version_low) + wcsncpy_s(version_text, size, L"0.1", _TRUNCATE); /* fallback */ + else { + maj = HIWORD(version_high); + min = LOWORD(version_high); + rel = HIWORD(version_low); + bld = LOWORD(version_low); + _snwprintf_s(version_text, size, _TRUNCATE, L"%d.%d.%d.%d", maj, + min, rel, bld); + } +} + +static int +process(int argc, wchar_t ** argv) +{ + wchar_t * wp; + wchar_t * command; + wchar_t * p; + int rc = 0; + size_t plen; + INSTALLED_PYTHON * ip; + BOOL valid; + DWORD size, attrs; + HRESULT hr; + wchar_t message[MSGSIZE]; + wchar_t version_text [MAX_PATH]; + void * version_data; + VS_FIXEDFILEINFO * file_info; + UINT block_size; + + wp = get_env(L"PYLAUNCH_DEBUG"); + if ((wp != NULL) && (*wp != L'\0')) + log_fp = stderr; + +#if defined(_M_X64) + debug(L"launcher build: 64bit\n"); +#else + debug(L"launcher build: 32bit\n"); +#endif +#if defined(_WINDOWS) + debug(L"launcher executable: Windows\n"); +#else + debug(L"launcher executable: Console\n"); +#endif + /* Get the local appdata folder (non-roaming) */ + hr = SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, + NULL, 0, appdata_ini_path); + if (hr != S_OK) { + debug(L"SHGetFolderPath failed: %X\n", hr); + appdata_ini_path[0] = L'\0'; + } + else { + plen = wcslen(appdata_ini_path); + p = &appdata_ini_path[plen]; + wcsncpy_s(p, MAX_PATH - plen, L"\\py.ini", _TRUNCATE); + attrs = GetFileAttributesW(appdata_ini_path); + if (attrs == INVALID_FILE_ATTRIBUTES) { + debug(L"File '%s' non-existent\n", appdata_ini_path); + appdata_ini_path[0] = L'\0'; + } else { + debug(L"Using local configuration file '%s'\n", appdata_ini_path); + } + } + plen = GetModuleFileNameW(NULL, launcher_ini_path, MAX_PATH); + size = GetFileVersionInfoSizeW(launcher_ini_path, &size); + if (size == 0) { + winerror(GetLastError(), message, MSGSIZE); + debug(L"GetFileVersionInfoSize failed: %s\n", message); + } + else { + version_data = malloc(size); + if (version_data) { + valid = GetFileVersionInfoW(launcher_ini_path, 0, size, + version_data); + if (!valid) + debug(L"GetFileVersionInfo failed: %X\n", GetLastError()); + else { + valid = VerQueryValueW(version_data, L"\\", &file_info, + &block_size); + if (!valid) + debug(L"VerQueryValue failed: %X\n", GetLastError()); + else { + version_high = file_info->dwFileVersionMS; + version_low = file_info->dwFileVersionLS; + } + } + free(version_data); + } + } + p = wcsrchr(launcher_ini_path, L'\\'); + if (p == NULL) { + debug(L"GetModuleFileNameW returned value has no backslash: %s\n", + launcher_ini_path); + launcher_ini_path[0] = L'\0'; + } + else { + wcsncpy_s(p, MAX_PATH - (p - launcher_ini_path), L"\\py.ini", + _TRUNCATE); + attrs = GetFileAttributesW(launcher_ini_path); + if (attrs == INVALID_FILE_ATTRIBUTES) { + debug(L"File '%s' non-existent\n", launcher_ini_path); + launcher_ini_path[0] = L'\0'; + } else { + debug(L"Using global configuration file '%s'\n", launcher_ini_path); + } + } + + command = skip_me(GetCommandLineW()); + debug(L"Called with command line: %s", command); + if (argc <= 1) { + valid = FALSE; + p = NULL; + } + else { + p = argv[1]; + plen = wcslen(p); + if (p[0] != L'-') { + read_commands(); + maybe_handle_shebang(&argv[1], command); + } + /* No file with shebang, or an unrecognised shebang. + * Is the first arg a special version qualifier? + */ + valid = (*p == L'-') && validate_version(&p[1]); + if (valid) { + ip = locate_python(&p[1]); + if (ip == NULL) + error(RC_NO_PYTHON, L"Requested Python version (%s) not \ +installed", &p[1]); + command += wcslen(p); + command = skip_whitespace(command); + } + } + if (!valid) { + ip = locate_python(L""); + if (ip == NULL) + error(RC_NO_PYTHON, L"Can't find a default Python."); + if ((argc == 2) && (!_wcsicmp(p, L"-h") || !_wcsicmp(p, L"--help"))) { +#if defined(_M_X64) + BOOL canDo64bit = TRUE; +#else + // If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. + BOOL canDo64bit = FALSE; + IsWow64Process(GetCurrentProcess(), &canDo64bit); +#endif + + get_version_info(version_text, MAX_PATH); + fwprintf(stdout, L"\ +Python Launcher for Windows Version %s\n\n", version_text); + fwprintf(stdout, L"\ +usage: %s [ launcher-arguments ] script [ script-arguments ]\n\n", argv[0]); + fputws(L"\ +Launcher arguments:\n\n\ +-2 : Launch the latest Python 2.x version\n\ +-3 : Launch the latest Python 3.x version\n\ +-X.Y : Launch the specified Python version\n", stdout); + if (canDo64bit) { + fputws(L"\ +-X.Y-32: Launch the specified 32bit Python version", stdout); + } + fputws(L"\n\nThe following help text is from Python:\n\n", stdout); + fflush(stdout); + } + } + invoke_child(ip->executable, NULL, command); + return rc; +} + +#if defined(_WINDOWS) + +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPWSTR lpstrCmd, int nShow) +{ + return process(__argc, __wargv); +} + +#else + +int cdecl wmain(int argc, wchar_t ** argv) +{ + return process(argc, argv); +} + +#endif \ No newline at end of file diff --git a/PC/launcher.ico b/PC/launcher.ico new file mode 100644 index 0000000..dad7d57 Binary files /dev/null and b/PC/launcher.ico differ diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc new file mode 100644 index 0000000..fadc5df --- /dev/null +++ b/PC/pylauncher.rc @@ -0,0 +1,3 @@ +IDI_ICON1 ICON "launcher.ico" +IDI_ICON2 ICON "py.ico" +IDI_ICON3 ICON "pyc.ico" \ No newline at end of file -- cgit v0.12 From 765dd1159698a296575a965c48c20a45694588de Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 20 Jun 2012 15:37:24 -0500 Subject: Initial changes to get the py launcher building --- PCbuild/pcbuild.sln | 14 +++++++ PCbuild/pylauncher.vcxproj | 83 ++++++++++++++++++++++++++++++++++++++ PCbuild/pylauncher.vcxproj.filters | 32 +++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 PCbuild/pylauncher.vcxproj create mode 100644 PCbuild/pylauncher.vcxproj.filters diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 3109225..811133c 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -68,6 +68,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcxp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer.vcxproj", "{A2697BD3-28C1-4AEC-9106-8B748639FD16}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vcxproj", "{7B2727B5-5A3F-40EE-A866-43A13CD31446}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -565,6 +567,18 @@ Global {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj new file mode 100644 index 0000000..82880c1 --- /dev/null +++ b/PCbuild/pylauncher.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7B2727B5-5A3F-40EE-A866-43A13CD31446} + pylauncher + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + py_d + + + + Level3 + Disabled + _CONSOLE;%(PreprocessorDefinitions) + + + true + version.lib;%(AdditionalDependencies) + false + Console + $(OutDir)py_d.exe + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pylauncher.vcxproj.filters b/PCbuild/pylauncher.vcxproj.filters new file mode 100644 index 0000000..e4b23d2 --- /dev/null +++ b/PCbuild/pylauncher.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file -- cgit v0.12 From a7de612a483164ed6a88d6d4309532f355867ba6 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 20 Jun 2012 15:45:12 -0500 Subject: Support 32-bit release building: --- PCbuild/pylauncher.vcxproj | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj index 82880c1..ba19fcf 100644 --- a/PCbuild/pylauncher.vcxproj +++ b/PCbuild/pylauncher.vcxproj @@ -36,11 +36,16 @@ + + py_d + + py + Level3 @@ -52,7 +57,7 @@ version.lib;%(AdditionalDependencies) false Console - $(OutDir)py_d.exe + $(OutDir)$(TargetName)_d$(TargetExt) @@ -61,11 +66,15 @@ MaxSpeed true true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) true true true + false + version.lib;%(AdditionalDependencies) + Console -- cgit v0.12 From d029e5dc8c79545aeef41a3de7872a949395bb89 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 20 Jun 2012 15:55:04 -0500 Subject: Get 64-bit building --- PCbuild/pcbuild.sln | 6 ++-- PCbuild/pylauncher.vcxproj | 70 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 811133c..0531f41 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -569,7 +569,8 @@ Global {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.ActiveCfg = Debug|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.Build.0 = Debug|x64 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|Win32 @@ -578,7 +579,8 @@ Global {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj index ba19fcf..c97bb82 100644 --- a/PCbuild/pylauncher.vcxproj +++ b/PCbuild/pylauncher.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446} @@ -20,12 +28,23 @@ true MultiByte + + Application + true + MultiByte + Application false true MultiByte + + Application + false + true + MultiByte + @@ -34,18 +53,36 @@ + + + + + + + + + + + + py_d + + py_d + py + + py + Level3 @@ -57,7 +94,21 @@ version.lib;%(AdditionalDependencies) false Console - $(OutDir)$(TargetName)_d$(TargetExt) + $(OutDir)$(TargetName)$(TargetExt) + + + + + Level3 + Disabled + _CONSOLE;%(PreprocessorDefinitions) + + + true + version.lib;%(AdditionalDependencies) + false + Console + $(OutDir)$(TargetName)$(TargetExt) @@ -77,6 +128,23 @@ Console + + + Level3 + MaxSpeed + true + true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + + + true + true + true + false + version.lib;%(AdditionalDependencies) + Console + + -- cgit v0.12 From 22bf8cbb5f21f9a240a5adf4187747b28fee9f7b Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 20 Jun 2012 16:11:08 -0500 Subject: Add the pyw launcher --- PCbuild/pcbuild.sln | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 0531f41..441c2d8 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -70,6 +70,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vcxproj", "{7B2727B5-5A3F-40EE-A866-43A13CD31446}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -581,6 +583,20 @@ Global {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE -- cgit v0.12 From 4bca28616048bff8a690d997ab3a39d03207d4c3 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 20 Jun 2012 16:11:39 -0500 Subject: Add pywlauncher project --- PCbuild/pywlauncher.vcxproj | 160 ++++++++++++++++++++++++++++++++++++ PCbuild/pywlauncher.vcxproj.filters | 32 ++++++++ 2 files changed, 192 insertions(+) create mode 100644 PCbuild/pywlauncher.vcxproj create mode 100644 PCbuild/pywlauncher.vcxproj.filters diff --git a/PCbuild/pywlauncher.vcxproj b/PCbuild/pywlauncher.vcxproj new file mode 100644 index 0000000..2df8a0c --- /dev/null +++ b/PCbuild/pywlauncher.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6} + pywlauncher + + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pyw_d + + + pyw_d + + + pyw + + + pyw + + + + Level3 + Disabled + _WINDOWS;%(PreprocessorDefinitions) + + + true + version.lib;%(AdditionalDependencies) + false + Windows + $(OutDir)$(TargetName)$(TargetExt) + + + + + Level3 + Disabled + _WINDOWS;%(PreprocessorDefinitions) + + + true + version.lib;%(AdditionalDependencies) + false + Windows + $(OutDir)$(TargetName)$(TargetExt) + + + + + Level3 + MaxSpeed + true + true + _WINDOWS;NDEBUG;%(PreprocessorDefinitions) + + + true + true + true + false + version.lib;%(AdditionalDependencies) + Windows + + + + + Level3 + MaxSpeed + true + true + _WINDOWS;NDEBUG;%(PreprocessorDefinitions) + + + true + true + true + false + version.lib;%(AdditionalDependencies) + Windows + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pywlauncher.vcxproj.filters b/PCbuild/pywlauncher.vcxproj.filters new file mode 100644 index 0000000..e4b23d2 --- /dev/null +++ b/PCbuild/pywlauncher.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file -- cgit v0.12 From 9698bde3c2a523a3a64fb1e1d0bb48dc02d217a5 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 20 Jun 2012 22:48:54 -0500 Subject: Add associator --- PC/associator.c | 731 ++++++++++++++++++ PC/associator.h | 1480 ++++++++++++++++++++++++++++++++++++ PC/associator.rc | 97 +++ PCbuild/associator.vcxproj | 84 ++ PCbuild/associator.vcxproj.filters | 32 + PCbuild/pcbuild.sln | 14 + 6 files changed, 2438 insertions(+) create mode 100644 PC/associator.c create mode 100644 PC/associator.h create mode 100644 PC/associator.rc create mode 100644 PCbuild/associator.vcxproj create mode 100644 PCbuild/associator.vcxproj.filters diff --git a/PC/associator.c b/PC/associator.c new file mode 100644 index 0000000..21dc3ff --- /dev/null +++ b/PC/associator.c @@ -0,0 +1,731 @@ +/* + * Copyright (C) 2011-2012 Vinay Sajip. All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include "associator.h" + +#define PYTHON_EXECUTABLE L"python.exe" + +#define MSGSIZE 1024 +#define MAX_VERSION_SIZE 4 + +typedef struct { + wchar_t version[MAX_VERSION_SIZE]; /* m.n */ + int bits; /* 32 or 64 */ + wchar_t executable[MAX_PATH]; +} INSTALLED_PYTHON; + +/* + * To avoid messing about with heap allocations, just assume we can allocate + * statically and never have to deal with more versions than this. + */ +#define MAX_INSTALLED_PYTHONS 100 + +static INSTALLED_PYTHON installed_pythons[MAX_INSTALLED_PYTHONS]; + +static size_t num_installed_pythons = 0; + +/* to hold SOFTWARE\Python\PythonCore\X.Y\InstallPath */ +#define IP_BASE_SIZE 40 +#define IP_SIZE (IP_BASE_SIZE + MAX_VERSION_SIZE) +#define CORE_PATH L"SOFTWARE\\Python\\PythonCore" + +static wchar_t * location_checks[] = { + L"\\", +/* + L"\\PCBuild\\", + L"\\PCBuild\\amd64\\", + */ + NULL +}; + +static wchar_t * +skip_whitespace(wchar_t * p) +{ + while (*p && isspace(*p)) + ++p; + return p; +} + +/* + * This function is here to minimise Visual Studio + * warnings about security implications of getenv, and to + * treat blank values as if they are absent. + */ +static wchar_t * get_env(wchar_t * key) +{ + wchar_t * result = _wgetenv(key); + + if (result) { + result = skip_whitespace(result); + if (*result == L'\0') + result = NULL; + } + return result; +} + +static FILE * log_fp = NULL; + +static void +debug(wchar_t * format, ...) +{ + va_list va; + + if (log_fp != NULL) { + va_start(va, format); + vfwprintf_s(log_fp, format, va); + } +} + +static void winerror(int rc, wchar_t * message, int size) +{ + FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + message, size, NULL); +} + +static INSTALLED_PYTHON * +find_existing_python(wchar_t * path) +{ + INSTALLED_PYTHON * result = NULL; + size_t i; + INSTALLED_PYTHON * ip; + + for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++, ip++) { + if (_wcsicmp(path, ip->executable) == 0) { + result = ip; + break; + } + } + return result; +} + +static void +locate_pythons_for_key(HKEY root, REGSAM flags) +{ + HKEY core_root, ip_key; + LSTATUS status = RegOpenKeyExW(root, CORE_PATH, 0, flags, &core_root); + wchar_t message[MSGSIZE]; + DWORD i; + size_t n; + BOOL ok; + DWORD type, data_size, attrs; + INSTALLED_PYTHON * ip, * pip; + wchar_t ip_path[IP_SIZE]; + wchar_t * check; + wchar_t ** checkp; + wchar_t *key_name = (root == HKEY_LOCAL_MACHINE) ? L"HKLM" : L"HKCU"; + + if (status != ERROR_SUCCESS) + debug(L"locate_pythons_for_key: unable to open PythonCore key in %s\n", + key_name); + else { + ip = &installed_pythons[num_installed_pythons]; + for (i = 0; num_installed_pythons < MAX_INSTALLED_PYTHONS; i++) { + status = RegEnumKeyW(core_root, i, ip->version, MAX_VERSION_SIZE); + if (status != ERROR_SUCCESS) { + if (status != ERROR_NO_MORE_ITEMS) { + /* unexpected error */ + winerror(status, message, MSGSIZE); + debug(L"Can't enumerate registry key for version %s: %s\n", + ip->version, message); + } + break; + } + else { + _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE, + L"%s\\%s\\InstallPath", CORE_PATH, ip->version); + status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key); + if (status != ERROR_SUCCESS) { + winerror(status, message, MSGSIZE); + // Note: 'message' already has a trailing \n + debug(L"%s\\%s: %s", key_name, ip_path, message); + continue; + } + data_size = sizeof(ip->executable) - 1; + status = RegQueryValueEx(ip_key, NULL, NULL, &type, + (LPBYTE) ip->executable, &data_size); + RegCloseKey(ip_key); + if (status != ERROR_SUCCESS) { + winerror(status, message, MSGSIZE); + debug(L"%s\\%s: %s\n", key_name, ip_path, message); + continue; + } + if (type == REG_SZ) { + data_size = data_size / sizeof(wchar_t) - 1; /* for NUL */ + if (ip->executable[data_size - 1] == L'\\') + --data_size; /* reg value ended in a backslash */ + /* ip->executable is data_size long */ + for (checkp = location_checks; *checkp; ++checkp) { + check = *checkp; + _snwprintf_s(&ip->executable[data_size], + MAX_PATH - data_size, + MAX_PATH - data_size, + L"%s%s", check, PYTHON_EXECUTABLE); + attrs = GetFileAttributesW(ip->executable); + if (attrs == INVALID_FILE_ATTRIBUTES) { + winerror(GetLastError(), message, MSGSIZE); + debug(L"locate_pythons_for_key: %s: %s", + ip->executable, message); + } + else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { + debug(L"locate_pythons_for_key: '%s' is a \ +directory\n", + ip->executable, attrs); + } + else if (find_existing_python(ip->executable)) { + debug(L"locate_pythons_for_key: %s: already \ +found: %s\n", ip->executable); + } + else { + /* check the executable type. */ + ok = GetBinaryTypeW(ip->executable, &attrs); + if (!ok) { + debug(L"Failure getting binary type: %s\n", + ip->executable); + } + else { + if (attrs == SCS_64BIT_BINARY) + ip->bits = 64; + else if (attrs == SCS_32BIT_BINARY) + ip->bits = 32; + else + ip->bits = 0; + if (ip->bits == 0) { + debug(L"locate_pythons_for_key: %s: \ +invalid binary type: %X\n", + ip->executable, attrs); + } + else { + if (wcschr(ip->executable, L' ') != NULL) { + /* has spaces, so quote */ + n = wcslen(ip->executable); + memmove(&ip->executable[1], + ip->executable, n * sizeof(wchar_t)); + ip->executable[0] = L'\"'; + ip->executable[n + 1] = L'\"'; + ip->executable[n + 2] = L'\0'; + } + debug(L"locate_pythons_for_key: %s \ +is a %dbit executable\n", + ip->executable, ip->bits); + ++num_installed_pythons; + pip = ip++; + if (num_installed_pythons >= + MAX_INSTALLED_PYTHONS) + break; + /* Copy over the attributes for the next */ + *ip = *pip; + } + } + } + } + } + } + } + RegCloseKey(core_root); + } +} + +static int +compare_pythons(const void * p1, const void * p2) +{ + INSTALLED_PYTHON * ip1 = (INSTALLED_PYTHON *) p1; + INSTALLED_PYTHON * ip2 = (INSTALLED_PYTHON *) p2; + /* note reverse sorting on version */ + int result = wcscmp(ip2->version, ip1->version); + + if (result == 0) + result = ip2->bits - ip1->bits; /* 64 before 32 */ + return result; +} + +static void +locate_all_pythons() +{ +#if defined(_M_X64) + // If we are a 64bit process, first hit the 32bit keys. + debug(L"locating Pythons in 32bit registry\n"); + locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_32KEY); + locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_32KEY); +#else + // If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. + BOOL f64 = FALSE; + if (IsWow64Process(GetCurrentProcess(), &f64) && f64) { + debug(L"locating Pythons in 64bit registry\n"); + locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_64KEY); + locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_64KEY); + } +#endif + // now hit the "native" key for this process bittedness. + debug(L"locating Pythons in native registry\n"); + locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ); + locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ); + qsort(installed_pythons, num_installed_pythons, sizeof(INSTALLED_PYTHON), + compare_pythons); +} + +typedef struct { + wchar_t * path; + wchar_t * key; + wchar_t * value; +} REGISTRY_ENTRY; + +static REGISTRY_ENTRY registry_entries[] = { + { L".py", NULL, L"Python.File" }, + { L".pyc", NULL, L"Python.CompiledFile" }, + { L".pyo", NULL, L"Python.CompiledFile" }, + { L".pyw", NULL, L"Python.NoConFile" }, + + { L"Python.CompiledFile", NULL, L"Compiled Python File" }, + { L"Python.CompiledFile\\DefaultIcon", NULL, L"pyc.ico" }, + { L"Python.CompiledFile\\shell\\open", NULL, L"Open" }, + { L"Python.CompiledFile\\shell\\open\\command", NULL, L"python.exe" }, + + { L"Python.File", NULL, L"Python File" }, + { L"Python.File\\DefaultIcon", NULL, L"py.ico" }, + { L"Python.File\\shell\\open", NULL, L"Open" }, + { L"Python.File\\shell\\open\\command", NULL, L"python.exe" }, + + { L"Python.NoConFile", NULL, L"Python File (no console)" }, + { L"Python.NoConFile\\DefaultIcon", NULL, L"py.ico" }, + { L"Python.NoConFile\\shell\\open", NULL, L"Open" }, + { L"Python.NoConFile\\shell\\open\\command", NULL, L"pythonw.exe" }, + + { NULL } +}; + +static BOOL +do_association(INSTALLED_PYTHON * ip) +{ + LONG rc; + BOOL result = TRUE; + REGISTRY_ENTRY * rp = registry_entries; + wchar_t value[MAX_PATH]; + wchar_t root[MAX_PATH]; + wchar_t message[MSGSIZE]; + wchar_t * pvalue; + HKEY hKey; + DWORD len; + + wcsncpy_s(root, MAX_PATH, ip->executable, _TRUNCATE); + pvalue = wcsrchr(root, '\\'); + if (pvalue) + *pvalue = L'\0'; + + for (; rp->path; ++rp) { + if (wcsstr(rp->path, L"DefaultIcon")) { + pvalue = value; + _snwprintf_s(value, MAX_PATH, _TRUNCATE, + L"%s\\DLLs\\%s", root, rp->value); + } + else if (wcsstr(rp->path, L"open\\command")) { + pvalue = value; + _snwprintf_s(value, MAX_PATH, _TRUNCATE, + L"%s\\%s \"%%1\" %%*", root, rp->value); + } + else { + pvalue = rp->value; + } + /* use rp->path, rp->key, pvalue */ + /* NOTE: size is in bytes */ + len = (DWORD) ((1 + wcslen(pvalue)) * sizeof(wchar_t)); + rc = RegOpenKeyEx(HKEY_CLASSES_ROOT, rp->path, 0, KEY_SET_VALUE, &hKey); + if (rc == ERROR_SUCCESS) { + rc = RegSetValueExW(hKey, rp->key, 0, REG_SZ, (LPBYTE) pvalue, len); + RegCloseKey(hKey); + } + if (rc != ERROR_SUCCESS) { + winerror(rc, message, MSGSIZE); + MessageBoxW(NULL, message, L"Unable to set file associations", MB_OK | MB_ICONSTOP); + result = FALSE; + break; + } + } + return result; +} + +static BOOL +associations_exist() +{ + BOOL result = FALSE; + REGISTRY_ENTRY * rp = registry_entries; + wchar_t buffer[MSGSIZE]; + LONG csize = MSGSIZE * sizeof(wchar_t); + LONG rc; + + /* Currently, if any is found, we assume they're all there. */ + + for (; rp->path; ++rp) { + LONG size = csize; + rc = RegQueryValueW(HKEY_CLASSES_ROOT, rp->path, buffer, &size); + if (rc == ERROR_SUCCESS) { + result = TRUE; + break; + } + } + return result; +} + +/* --------------------------------------------------------------------*/ + +static BOOL CALLBACK +find_by_title(HWND hwnd, LPARAM lParam) +{ + wchar_t buffer[MSGSIZE]; + BOOL not_found = TRUE; + + wchar_t * p = (wchar_t *) GetWindowTextW(hwnd, buffer, MSGSIZE); + if (wcsstr(buffer, L"Python Launcher") == buffer) { + not_found = FALSE; + *((HWND *) lParam) = hwnd; + } + return not_found; +} + +static HWND +find_installer_window() +{ + HWND result = NULL; + BOOL found = EnumWindows(find_by_title, (LPARAM) &result); + + return result; +} + +static void +centre_window_in_front(HWND hwnd) +{ + HWND hwndParent; + RECT rect, rectP; + int width, height; + int screenwidth, screenheight; + int x, y; + + //make the window relative to its parent + + screenwidth = GetSystemMetrics(SM_CXSCREEN); + screenheight = GetSystemMetrics(SM_CYSCREEN); + + hwndParent = GetParent(hwnd); + + GetWindowRect(hwnd, &rect); + if (hwndParent) { + GetWindowRect(hwndParent, &rectP); + } + else { + rectP.left = rectP.top = 0; + rectP.right = screenwidth; + rectP.bottom = screenheight; + } + + width = rect.right - rect.left; + height = rect.bottom - rect.top; + + x = ((rectP.right-rectP.left) - width) / 2 + rectP.left; + y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top; + + + //make sure that the dialog box never moves outside of + //the screen + + if (x < 0) + x = 0; + + if (y < 0) + y = 0; + + if (x + width > screenwidth) + x = screenwidth - width; + if (y + height > screenheight) + y = screenheight - height; + + SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, SWP_SHOWWINDOW); +} + +static void +init_list(HWND hList) +{ + LVCOLUMNW column; + LVITEMW item; + int colno = 0; + int width = 0; + int row; + size_t i; + INSTALLED_PYTHON * ip; + RECT r; + LPARAM style; + + GetClientRect(hList, &r); + + style = SendMessage(hList, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0); + SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, + 0, style | LVS_EX_FULLROWSELECT); + + /* First set up the columns */ + memset(&column, 0, sizeof(column)); + column.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + column.pszText = L"Version"; + column.cx = 60; + width += column.cx; + SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column); +#if defined(_M_X64) + column.pszText = L"Bits"; + column.cx = 40; + column.iSubItem = colno; + SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column); + width += column.cx; +#endif + column.pszText = L"Path"; + column.cx = r.right - r.top - width; + column.iSubItem = colno; + SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column); + + /* Then insert the rows */ + memset(&item, 0, sizeof(item)); + item.mask = LVIF_TEXT; + for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++,ip++) { + item.iItem = (int) i; + item.iSubItem = 0; + item.pszText = ip->version; + colno = 0; + row = (int) SendMessage(hList, LVM_INSERTITEM, 0, (LPARAM) &item); +#if defined(_M_X64) + item.iSubItem = ++colno; + item.pszText = (ip->bits == 64) ? L"64": L"32"; + SendMessage(hList, LVM_SETITEM, row, (LPARAM) &item); +#endif + item.iSubItem = ++colno; + item.pszText = ip->executable; + SendMessage(hList, LVM_SETITEM, row, (LPARAM) &item); + } +} + +/* ----------------------------------------------------------------*/ + +typedef int (__stdcall *MSGBOXWAPI)(IN HWND hWnd, + IN LPCWSTR lpText, IN LPCWSTR lpCaption, + IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds); + +int MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText, + IN LPCWSTR lpCaption, IN UINT uType, + IN WORD wLanguageId, IN DWORD dwMilliseconds); + +#define MB_TIMEDOUT 32000 + +int MessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText, + LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds) +{ + static MSGBOXWAPI MsgBoxTOW = NULL; + + if (!MsgBoxTOW) { + HMODULE hUser32 = GetModuleHandleW(L"user32.dll"); + if (hUser32) + MsgBoxTOW = (MSGBOXWAPI)GetProcAddress(hUser32, + "MessageBoxTimeoutW"); + else { + //stuff happened, add code to handle it here + //(possibly just call MessageBox()) + return 0; + } + } + + if (MsgBoxTOW) + return MsgBoxTOW(hWnd, lpText, lpCaption, uType, wLanguageId, + dwMilliseconds); + + return 0; +} +/* ----------------------------------------------------------------*/ + +static INT_PTR CALLBACK +DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND hList; + HWND hChild; + static int selected_index = -1; + WORD low = LOWORD(wParam); + wchar_t confirmation[MSGSIZE]; + BOOL result = FALSE; + + debug(L"DialogProc entry: 0x%02X\n", message); + switch (message) { + case WM_INITDIALOG: + hList = GetDlgItem(hDlg, IDC_LIST1); + init_list(hList); + SetFocus(hList); + result = TRUE; + break; + case WM_COMMAND: + if((low == IDOK) || (low == IDCANCEL)) { + HMODULE hUser32 = LoadLibraryW(L"user32.dll"); + + if (low == IDCANCEL) + wcsncpy_s(confirmation, MSGSIZE, L"No association was \ +performed.", _TRUNCATE); + else { + if (selected_index < 0) { + /* should never happen */ + wcsncpy_s(confirmation, MSGSIZE, L"The Python version to \ +associate with couldn't be determined.", _TRUNCATE); + } + else { + INSTALLED_PYTHON * ip = &installed_pythons[selected_index]; + + /* Do the association and set the message. */ + do_association(ip); + _snwprintf_s(confirmation, MSGSIZE, _TRUNCATE, + L"Associated Python files with the Python %s \ +found at '%s'", ip->version, ip->executable); + } + } + + if (hUser32) { + MessageBoxTimeoutW(hDlg, + confirmation, + L"Association Status", + MB_OK | MB_SETFOREGROUND | + MB_ICONINFORMATION, + 0, 2000); + FreeLibrary(hUser32); + } + PostQuitMessage(0); + EndDialog(hDlg, 0); + result = TRUE; + } + break; + case WM_NOTIFY: + if (low == IDC_LIST1) { + NMLISTVIEW * p = (NMLISTVIEW *) lParam; + + if ((p->hdr.code == LVN_ITEMCHANGED) && + (p->uNewState & LVIS_SELECTED)) { + hChild = GetDlgItem(hDlg, IDOK); + selected_index = p->iItem; + EnableWindow(hChild, selected_index >= 0); + } + result = TRUE; + } + break; + case WM_DESTROY: + PostQuitMessage(0); + result = TRUE; + break; + case WM_CLOSE: + DestroyWindow(hDlg); + result = TRUE; + break; + } + debug(L"DialogProc exit: %d\n", result); + return result; +} + +int WINAPI wWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPWSTR lpCmdLine, int nShow) +{ + MSG msg; + HWND hDialog = 0; + HICON hIcon; + HWND hParent; + int status; + DWORD dw; + INITCOMMONCONTROLSEX icx; + wchar_t * wp; + + wp = get_env(L"PYASSOC_DEBUG"); + if ((wp != NULL) && (*wp != L'\0')) { + fopen_s(&log_fp, "c:\\temp\\associator.log", "w"); + } + + if (!lpCmdLine) { + debug(L"No command line specified.\n"); + return 0; + } + if (!wcsstr(lpCmdLine, L"nocheck") && + associations_exist()) /* Could have been restored by uninstall. */ + return 0; + + locate_all_pythons(); + + if (num_installed_pythons == 0) + return 0; + + debug(L"%d pythons found.\n", num_installed_pythons); + + /* + * OK, now there's something to do. + * + * We need to find the installer window to be the parent of + * our dialog, otherwise our dialog will be behind it. + * + * First, initialize common controls. If you don't - on + * some machines it works fine, on others the dialog never + * appears! + */ + + icx.dwSize = sizeof(icx); + icx.dwICC = ICC_LISTVIEW_CLASSES; + InitCommonControlsEx(&icx); + + hParent = find_installer_window(); + debug(L"installer window: %X\n", hParent); + hDialog = CreateDialogW(hInstance, MAKEINTRESOURCE(DLG_MAIN), hParent, + DialogProc); + dw = GetLastError(); + debug(L"dialog created: %X: error: %X\n", hDialog, dw); + + if (!hDialog) + { + wchar_t buf [100]; + _snwprintf_s(buf, 100, _TRUNCATE, L"Error 0x%x", GetLastError()); + MessageBoxW(0, buf, L"CreateDialog", MB_ICONEXCLAMATION | MB_OK); + return 1; + } + + centre_window_in_front(hDialog); + hIcon = LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(DLG_ICON)); + if( hIcon ) + { + SendMessage(hDialog, WM_SETICON, ICON_BIG, (LPARAM) hIcon); + SendMessage(hDialog, WM_SETICON, ICON_SMALL, (LPARAM) hIcon); + DestroyIcon(hIcon); + } + + while ((status = GetMessage (& msg, 0, 0, 0)) != 0) + { + if (status == -1) + return -1; + if (!IsDialogMessage(hDialog, & msg)) + { + TranslateMessage( & msg ); + DispatchMessage( & msg ); + } + } + + return (int) msg.wParam; +} diff --git a/PC/associator.h b/PC/associator.h new file mode 100644 index 0000000..a2c1cde --- /dev/null +++ b/PC/associator.h @@ -0,0 +1,1480 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by main.rc +// +#define SW_HIDE 0 +#define HIDE_WINDOW 0 +#define WM_NULL 0x0000 +#define WA_INACTIVE 0 +#define HTNOWHERE 0 +#define SMTO_NORMAL 0x0000 +#define ICON_SMALL 0 +#define SIZE_RESTORED 0 +#define BN_CLICKED 0 +#define BST_UNCHECKED 0x0000 +#define HDS_HORZ 0x0000 +#define TBSTYLE_BUTTON 0x0000 +#define TBS_HORZ 0x0000 +#define TBS_BOTTOM 0x0000 +#define TBS_RIGHT 0x0000 +#define LVS_ICON 0x0000 +#define LVS_ALIGNTOP 0x0000 +#define TCS_TABS 0x0000 +#define TCS_SINGLELINE 0x0000 +#define TCS_RIGHTJUSTIFY 0x0000 +#define DTS_SHORTDATEFORMAT 0x0000 +#define PGS_VERT 0x00000000 +#define LANG_NEUTRAL 0x00 +#define SUBLANG_NEUTRAL 0x00 +#define SORT_DEFAULT 0x0 +#define SORT_JAPANESE_XJIS 0x0 +#define SORT_CHINESE_BIG5 0x0 +#define SORT_CHINESE_PRCP 0x0 +#define SORT_KOREAN_KSC 0x0 +#define SORT_HUNGARIAN_DEFAULT 0x0 +#define SORT_GEORGIAN_TRADITIONAL 0x0 +#define _USE_DECLSPECS_FOR_SAL 0 +#define SW_SHOWNORMAL 1 +#define SW_NORMAL 1 +#define SHOW_OPENWINDOW 1 +#define SW_PARENTCLOSING 1 +#define VK_LBUTTON 0x01 +#define WM_CREATE 0x0001 +#define WA_ACTIVE 1 +#define PWR_OK 1 +#define PWR_SUSPENDREQUEST 1 +#define NFR_ANSI 1 +#define UIS_SET 1 +#define UISF_HIDEFOCUS 0x1 +#define XBUTTON1 0x0001 +#define WMSZ_LEFT 1 +#define HTCLIENT 1 +#define SMTO_BLOCK 0x0001 +#define MA_ACTIVATE 1 +#define ICON_BIG 1 +#define SIZE_MINIMIZED 1 +#define MK_LBUTTON 0x0001 +#define TME_HOVER 0x00000001 +#define CS_VREDRAW 0x0001 +#define CF_TEXT 1 +#define SCF_ISSECURE 0x00000001 +#define IDOK 1 +#define BN_PAINT 1 +#define BST_CHECKED 0x0001 +#define TBSTYLE_SEP 0x0001 +#define TTS_ALWAYSTIP 0x01 +#define TBS_AUTOTICKS 0x0001 +#define UDS_WRAP 0x0001 +#define PBS_SMOOTH 0x01 +#define LWS_TRANSPARENT 0x0001 +#define LVS_REPORT 0x0001 +#define TVS_HASBUTTONS 0x0001 +#define TCS_SCROLLOPPOSITE 0x0001 +#define ACS_CENTER 0x0001 +#define MCS_DAYSTATE 0x0001 +#define DTS_UPDOWN 0x0001 +#define PGS_HORZ 0x00000001 +#define NFS_EDIT 0x0001 +#define BCSIF_GLYPH 0x0001 +#define BCSS_NOSPLIT 0x0001 +#define LANG_ARABIC 0x01 +#define SUBLANG_DEFAULT 0x01 +#define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01 +#define SUBLANG_ALBANIAN_ALBANIA 0x01 +#define SUBLANG_ALSATIAN_FRANCE 0x01 +#define SUBLANG_AMHARIC_ETHIOPIA 0x01 +#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01 +#define SUBLANG_ARMENIAN_ARMENIA 0x01 +#define SUBLANG_ASSAMESE_INDIA 0x01 +#define SUBLANG_AZERI_LATIN 0x01 +#define SUBLANG_BASHKIR_RUSSIA 0x01 +#define SUBLANG_BASQUE_BASQUE 0x01 +#define SUBLANG_BELARUSIAN_BELARUS 0x01 +#define SUBLANG_BENGALI_INDIA 0x01 +#define SUBLANG_BRETON_FRANCE 0x01 +#define SUBLANG_BULGARIAN_BULGARIA 0x01 +#define SUBLANG_CATALAN_CATALAN 0x01 +#define SUBLANG_CHINESE_TRADITIONAL 0x01 +#define SUBLANG_CORSICAN_FRANCE 0x01 +#define SUBLANG_CZECH_CZECH_REPUBLIC 0x01 +#define SUBLANG_CROATIAN_CROATIA 0x01 +#define SUBLANG_DANISH_DENMARK 0x01 +#define SUBLANG_DARI_AFGHANISTAN 0x01 +#define SUBLANG_DIVEHI_MALDIVES 0x01 +#define SUBLANG_DUTCH 0x01 +#define SUBLANG_ENGLISH_US 0x01 +#define SUBLANG_ESTONIAN_ESTONIA 0x01 +#define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01 +#define SUBLANG_FILIPINO_PHILIPPINES 0x01 +#define SUBLANG_FINNISH_FINLAND 0x01 +#define SUBLANG_FRENCH 0x01 +#define SUBLANG_FRISIAN_NETHERLANDS 0x01 +#define SUBLANG_GALICIAN_GALICIAN 0x01 +#define SUBLANG_GEORGIAN_GEORGIA 0x01 +#define SUBLANG_GERMAN 0x01 +#define SUBLANG_GREEK_GREECE 0x01 +#define SUBLANG_GREENLANDIC_GREENLAND 0x01 +#define SUBLANG_GUJARATI_INDIA 0x01 +#define SUBLANG_HAUSA_NIGERIA_LATIN 0x01 +#define SUBLANG_HEBREW_ISRAEL 0x01 +#define SUBLANG_HINDI_INDIA 0x01 +#define SUBLANG_HUNGARIAN_HUNGARY 0x01 +#define SUBLANG_ICELANDIC_ICELAND 0x01 +#define SUBLANG_IGBO_NIGERIA 0x01 +#define SUBLANG_INDONESIAN_INDONESIA 0x01 +#define SUBLANG_INUKTITUT_CANADA 0x01 +#define SUBLANG_ITALIAN 0x01 +#define SUBLANG_JAPANESE_JAPAN 0x01 +#define SUBLANG_KANNADA_INDIA 0x01 +#define SUBLANG_KAZAK_KAZAKHSTAN 0x01 +#define SUBLANG_KHMER_CAMBODIA 0x01 +#define SUBLANG_KICHE_GUATEMALA 0x01 +#define SUBLANG_KINYARWANDA_RWANDA 0x01 +#define SUBLANG_KONKANI_INDIA 0x01 +#define SUBLANG_KOREAN 0x01 +#define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01 +#define SUBLANG_LAO_LAO 0x01 +#define SUBLANG_LATVIAN_LATVIA 0x01 +#define SUBLANG_LITHUANIAN 0x01 +#define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01 +#define SUBLANG_MACEDONIAN_MACEDONIA 0x01 +#define SUBLANG_MALAY_MALAYSIA 0x01 +#define SUBLANG_MALAYALAM_INDIA 0x01 +#define SUBLANG_MALTESE_MALTA 0x01 +#define SUBLANG_MAORI_NEW_ZEALAND 0x01 +#define SUBLANG_MAPUDUNGUN_CHILE 0x01 +#define SUBLANG_MARATHI_INDIA 0x01 +#define SUBLANG_MOHAWK_MOHAWK 0x01 +#define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01 +#define SUBLANG_NEPALI_NEPAL 0x01 +#define SUBLANG_NORWEGIAN_BOKMAL 0x01 +#define SUBLANG_OCCITAN_FRANCE 0x01 +#define SUBLANG_ORIYA_INDIA 0x01 +#define SUBLANG_PASHTO_AFGHANISTAN 0x01 +#define SUBLANG_PERSIAN_IRAN 0x01 +#define SUBLANG_POLISH_POLAND 0x01 +#define SUBLANG_PORTUGUESE_BRAZILIAN 0x01 +#define SUBLANG_PUNJABI_INDIA 0x01 +#define SUBLANG_QUECHUA_BOLIVIA 0x01 +#define SUBLANG_ROMANIAN_ROMANIA 0x01 +#define SUBLANG_ROMANSH_SWITZERLAND 0x01 +#define SUBLANG_RUSSIAN_RUSSIA 0x01 +#define SUBLANG_SAMI_NORTHERN_NORWAY 0x01 +#define SUBLANG_SANSKRIT_INDIA 0x01 +#define SUBLANG_SERBIAN_CROATIA 0x01 +#define SUBLANG_SINDHI_INDIA 0x01 +#define SUBLANG_SINHALESE_SRI_LANKA 0x01 +#define SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA 0x01 +#define SUBLANG_SLOVAK_SLOVAKIA 0x01 +#define SUBLANG_SLOVENIAN_SLOVENIA 0x01 +#define SUBLANG_SPANISH 0x01 +#define SUBLANG_SWAHILI_KENYA 0x01 +#define SUBLANG_SWEDISH 0x01 +#define SUBLANG_SYRIAC_SYRIA 0x01 +#define SUBLANG_TAJIK_TAJIKISTAN 0x01 +#define SUBLANG_TAMIL_INDIA 0x01 +#define SUBLANG_TATAR_RUSSIA 0x01 +#define SUBLANG_TELUGU_INDIA 0x01 +#define SUBLANG_THAI_THAILAND 0x01 +#define SUBLANG_TIBETAN_PRC 0x01 +#define SUBLANG_TSWANA_SOUTH_AFRICA 0x01 +#define SUBLANG_TURKISH_TURKEY 0x01 +#define SUBLANG_TURKMEN_TURKMENISTAN 0x01 +#define SUBLANG_UIGHUR_PRC 0x01 +#define SUBLANG_UKRAINIAN_UKRAINE 0x01 +#define SUBLANG_UPPER_SORBIAN_GERMANY 0x01 +#define SUBLANG_URDU_PAKISTAN 0x01 +#define SUBLANG_UZBEK_LATIN 0x01 +#define SUBLANG_VIETNAMESE_VIETNAM 0x01 +#define SUBLANG_WELSH_UNITED_KINGDOM 0x01 +#define SUBLANG_WOLOF_SENEGAL 0x01 +#define SUBLANG_XHOSA_SOUTH_AFRICA 0x01 +#define SUBLANG_YAKUT_RUSSIA 0x01 +#define SUBLANG_YI_PRC 0x01 +#define SUBLANG_YORUBA_NIGERIA 0x01 +#define SUBLANG_ZULU_SOUTH_AFRICA 0x01 +#define SORT_INVARIANT_MATH 0x1 +#define SORT_JAPANESE_UNICODE 0x1 +#define SORT_CHINESE_UNICODE 0x1 +#define SORT_KOREAN_UNICODE 0x1 +#define SORT_GERMAN_PHONE_BOOK 0x1 +#define SORT_HUNGARIAN_TECHNICAL 0x1 +#define SORT_GEORGIAN_MODERN 0x1 +#define VS_VERSION_INFO 1 +#define VFFF_ISSHAREDFILE 0x0001 +#define VFF_CURNEDEST 0x0001 +#define VIFF_FORCEINSTALL 0x0001 +#define SW_SHOWMINIMIZED 2 +#define SHOW_ICONWINDOW 2 +#define SW_OTHERZOOM 2 +#define VK_RBUTTON 0x02 +#define WM_DESTROY 0x0002 +#define WA_CLICKACTIVE 2 +#define PWR_SUSPENDRESUME 2 +#define NFR_UNICODE 2 +#define UIS_CLEAR 2 +#define UISF_HIDEACCEL 0x2 +#define XBUTTON2 0x0002 +#define WMSZ_RIGHT 2 +#define HTCAPTION 2 +#define SMTO_ABORTIFHUNG 0x0002 +#define MA_ACTIVATEANDEAT 2 +#define ICON_SMALL2 2 +#define SIZE_MAXIMIZED 2 +#define MK_RBUTTON 0x0002 +#define TME_LEAVE 0x00000002 +#define CS_HREDRAW 0x0002 +#define CF_BITMAP 2 +#define IDCANCEL 2 +#define BN_HILITE 2 +#define BST_INDETERMINATE 0x0002 +#define HDS_BUTTONS 0x0002 +#define TBSTYLE_CHECK 0x0002 +#define TTS_NOPREFIX 0x02 +#define TBS_VERT 0x0002 +#define UDS_SETBUDDYINT 0x0002 +#define LWS_IGNORERETURN 0x0002 +#define LVS_SMALLICON 0x0002 +#define TVS_HASLINES 0x0002 +#define TVS_EX_MULTISELECT 0x0002 +#define TCS_BOTTOM 0x0002 +#define TCS_RIGHT 0x0002 +#define ACS_TRANSPARENT 0x0002 +#define MCS_MULTISELECT 0x0002 +#define DTS_SHOWNONE 0x0002 +#define PGS_AUTOSCROLL 0x00000002 +#define NFS_STATIC 0x0002 +#define BCSIF_IMAGE 0x0002 +#define BCSS_STRETCH 0x0002 +#define LANG_BULGARIAN 0x02 +#define SUBLANG_SYS_DEFAULT 0x02 +#define SUBLANG_ARABIC_IRAQ 0x02 +#define SUBLANG_AZERI_CYRILLIC 0x02 +#define SUBLANG_BENGALI_BANGLADESH 0x02 +#define SUBLANG_CHINESE_SIMPLIFIED 0x02 +#define SUBLANG_DUTCH_BELGIAN 0x02 +#define SUBLANG_ENGLISH_UK 0x02 +#define SUBLANG_FRENCH_BELGIAN 0x02 +#define SUBLANG_GERMAN_SWISS 0x02 +#define SUBLANG_INUKTITUT_CANADA_LATIN 0x02 +#define SUBLANG_IRISH_IRELAND 0x02 +#define SUBLANG_ITALIAN_SWISS 0x02 +#define SUBLANG_KASHMIRI_SASIA 0x02 +#define SUBLANG_KASHMIRI_INDIA 0x02 +#define SUBLANG_LOWER_SORBIAN_GERMANY 0x02 +#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 +#define SUBLANG_MONGOLIAN_PRC 0x02 +#define SUBLANG_NEPALI_INDIA 0x02 +#define SUBLANG_NORWEGIAN_NYNORSK 0x02 +#define SUBLANG_PORTUGUESE 0x02 +#define SUBLANG_QUECHUA_ECUADOR 0x02 +#define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02 +#define SUBLANG_SERBIAN_LATIN 0x02 +#define SUBLANG_SINDHI_PAKISTAN 0x02 +#define SUBLANG_SINDHI_AFGHANISTAN 0x02 +#define SUBLANG_SPANISH_MEXICAN 0x02 +#define SUBLANG_SWEDISH_FINLAND 0x02 +#define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02 +#define SUBLANG_TIGRIGNA_ERITREA 0x02 +#define SUBLANG_URDU_INDIA 0x02 +#define SUBLANG_UZBEK_CYRILLIC 0x02 +#define SORT_CHINESE_PRC 0x2 +#define VFF_FILEINUSE 0x0002 +#define VIFF_DONTDELETEOLD 0x0002 +#define SW_SHOWMAXIMIZED 3 +#define SW_MAXIMIZE 3 +#define SHOW_FULLSCREEN 3 +#define SW_PARENTOPENING 3 +#define VK_CANCEL 0x03 +#define WM_MOVE 0x0003 +#define PWR_CRITICALRESUME 3 +#define NF_QUERY 3 +#define UIS_INITIALIZE 3 +#define WMSZ_TOP 3 +#define HTSYSMENU 3 +#define MA_NOACTIVATE 3 +#define SIZE_MAXSHOW 3 +#define CF_METAFILEPICT 3 +#define IDABORT 3 +#define BN_UNHILITE 3 +#define LVS_LIST 0x0003 +#define LVS_TYPEMASK 0x0003 +#define LANG_CATALAN 0x03 +#define SUBLANG_CUSTOM_DEFAULT 0x03 +#define SUBLANG_ARABIC_EGYPT 0x03 +#define SUBLANG_CHINESE_HONGKONG 0x03 +#define SUBLANG_ENGLISH_AUS 0x03 +#define SUBLANG_FRENCH_CANADIAN 0x03 +#define SUBLANG_GERMAN_AUSTRIAN 0x03 +#define SUBLANG_QUECHUA_PERU 0x03 +#define SUBLANG_SAMI_NORTHERN_FINLAND 0x03 +#define SUBLANG_SERBIAN_CYRILLIC 0x03 +#define SUBLANG_SPANISH_MODERN 0x03 +#define SORT_CHINESE_BOPOMOFO 0x3 +#define SW_SHOWNOACTIVATE 4 +#define SHOW_OPENNOACTIVATE 4 +#define SW_OTHERUNZOOM 4 +#define VK_MBUTTON 0x04 +#define NF_REQUERY 4 +#define UISF_ACTIVE 0x4 +#define WMSZ_TOPLEFT 4 +#define HTGROWBOX 4 +#define MA_NOACTIVATEANDEAT 4 +#define SIZE_MAXHIDE 4 +#define MK_SHIFT 0x0004 +#define CF_SYLK 4 +#define IDRETRY 4 +#define BN_DISABLE 4 +#define BST_PUSHED 0x0004 +#define HDS_HOTTRACK 0x0004 +#define TBSTYLE_GROUP 0x0004 +#define TBS_TOP 0x0004 +#define TBS_LEFT 0x0004 +#define UDS_ALIGNRIGHT 0x0004 +#define PBS_VERTICAL 0x04 +#define LWS_NOPREFIX 0x0004 +#define LVS_SINGLESEL 0x0004 +#define TVS_LINESATROOT 0x0004 +#define TVS_EX_DOUBLEBUFFER 0x0004 +#define TCS_MULTISELECT 0x0004 +#define ACS_AUTOPLAY 0x0004 +#define MCS_WEEKNUMBERS 0x0004 +#define DTS_LONGDATEFORMAT 0x0004 +#define PGS_DRAGNDROP 0x00000004 +#define NFS_LISTCOMBO 0x0004 +#define BCSIF_STYLE 0x0004 +#define BCSS_ALIGNLEFT 0x0004 +#define LANG_CHINESE 0x04 +#define LANG_CHINESE_SIMPLIFIED 0x04 +#define SUBLANG_CUSTOM_UNSPECIFIED 0x04 +#define SUBLANG_ARABIC_LIBYA 0x04 +#define SUBLANG_CHINESE_SINGAPORE 0x04 +#define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04 +#define SUBLANG_ENGLISH_CAN 0x04 +#define SUBLANG_FRENCH_SWISS 0x04 +#define SUBLANG_GERMAN_LUXEMBOURG 0x04 +#define SUBLANG_SAMI_LULE_NORWAY 0x04 +#define SUBLANG_SPANISH_GUATEMALA 0x04 +#define SORT_JAPANESE_RADICALSTROKE 0x4 +#define VFF_BUFFTOOSMALL 0x0004 +#define SW_SHOW 5 +#define VK_XBUTTON1 0x05 +#define WM_SIZE 0x0005 +#define WMSZ_TOPRIGHT 5 +#define HTMENU 5 +#define CF_DIF 5 +#define IDIGNORE 5 +#define BN_DOUBLECLICKED 5 +#define LANG_CZECH 0x05 +#define SUBLANG_UI_CUSTOM_DEFAULT 0x05 +#define SUBLANG_ARABIC_ALGERIA 0x05 +#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05 +#define SUBLANG_CHINESE_MACAU 0x05 +#define SUBLANG_ENGLISH_NZ 0x05 +#define SUBLANG_FRENCH_LUXEMBOURG 0x05 +#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05 +#define SUBLANG_SAMI_LULE_SWEDEN 0x05 +#define SUBLANG_SPANISH_COSTA_RICA 0x05 +#define SW_MINIMIZE 6 +#define VK_XBUTTON2 0x06 +#define WM_ACTIVATE 0x0006 +#define WMSZ_BOTTOM 6 +#define HTHSCROLL 6 +#define CF_TIFF 6 +#define IDYES 6 +#define BN_SETFOCUS 6 +#define LANG_DANISH 0x06 +#define SUBLANG_ARABIC_MOROCCO 0x06 +#define SUBLANG_ENGLISH_EIRE 0x06 +#define SUBLANG_FRENCH_MONACO 0x06 +#define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06 +#define SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN 0x06 +#define SUBLANG_SPANISH_PANAMA 0x06 +#define SW_SHOWMINNOACTIVE 7 +#define WM_SETFOCUS 0x0007 +#define WMSZ_BOTTOMLEFT 7 +#define HTVSCROLL 7 +#define CF_OEMTEXT 7 +#define IDNO 7 +#define BN_KILLFOCUS 7 +#define LANG_GERMAN 0x07 +#define SUBLANG_ARABIC_TUNISIA 0x07 +#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07 +#define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07 +#define SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x07 +#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07 +#define SW_SHOWNA 8 +#define VK_BACK 0x08 +#define WM_KILLFOCUS 0x0008 +#define WMSZ_BOTTOMRIGHT 8 +#define HTMINBUTTON 8 +#define SMTO_NOTIMEOUTIFNOTHUNG 0x0008 +#define MK_CONTROL 0x0008 +#define CS_DBLCLKS 0x0008 +#define CF_DIB 8 +#define IDCLOSE 8 +#define BST_FOCUS 0x0008 +#define HDS_HIDDEN 0x0008 +#define TBSTYLE_DROPDOWN 0x0008 +#define TBS_BOTH 0x0008 +#define UDS_ALIGNLEFT 0x0008 +#define PBS_MARQUEE 0x08 +#define LWS_USEVISUALSTYLE 0x0008 +#define LVS_SHOWSELALWAYS 0x0008 +#define TVS_EDITLABELS 0x0008 +#define TVS_EX_NOINDENTSTATE 0x0008 +#define TCS_FLATBUTTONS 0x0008 +#define ACS_TIMER 0x0008 +#define MCS_NOTODAYCIRCLE 0x0008 +#define NFS_BUTTON 0x0008 +#define BCSIF_SIZE 0x0008 +#define BCSS_IMAGE 0x0008 +#define LANG_GREEK 0x08 +#define SUBLANG_ARABIC_OMAN 0x08 +#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08 +#define SUBLANG_ENGLISH_JAMAICA 0x08 +#define SUBLANG_SAMI_SKOLT_FINLAND 0x08 +#define SUBLANG_SPANISH_VENEZUELA 0x08 +#define SW_RESTORE 9 +#define VK_TAB 0x09 +#define HTMAXBUTTON 9 +#define CF_PALETTE 9 +#define IDHELP 9 +#define DTS_TIMEFORMAT 0x0009 +#define LANG_ENGLISH 0x09 +#define SUBLANG_ARABIC_YEMEN 0x09 +#define SUBLANG_ENGLISH_CARIBBEAN 0x09 +#define SUBLANG_SAMI_INARI_FINLAND 0x09 +#define SUBLANG_SPANISH_COLOMBIA 0x09 +#define SW_SHOWDEFAULT 10 +#define WM_ENABLE 0x000A +#define HTLEFT 10 +#define CF_PENDATA 10 +#define IDTRYAGAIN 10 +#define HELP_CONTEXTMENU 0x000a +#define LANG_SPANISH 0x0a +#define SUBLANG_ARABIC_SYRIA 0x0a +#define SUBLANG_ENGLISH_BELIZE 0x0a +#define SUBLANG_SPANISH_PERU 0x0a +#define SW_FORCEMINIMIZE 11 +#define SW_MAX 11 +#define WM_SETREDRAW 0x000B +#define HTRIGHT 11 +#define CF_RIFF 11 +#define IDCONTINUE 11 +#define HELP_FINDER 0x000b +#define LANG_FINNISH 0x0b +#define SUBLANG_ARABIC_JORDAN 0x0b +#define SUBLANG_ENGLISH_TRINIDAD 0x0b +#define SUBLANG_SPANISH_ARGENTINA 0x0b +#define VK_CLEAR 0x0C +#define WM_SETTEXT 0x000C +#define HTTOP 12 +#define CF_WAVE 12 +#define HELP_WM_HELP 0x000c +#define DTS_SHORTDATECENTURYFORMAT 0x000C +#define LANG_FRENCH 0x0c +#define SUBLANG_ARABIC_LEBANON 0x0c +#define SUBLANG_ENGLISH_ZIMBABWE 0x0c +#define SUBLANG_SPANISH_ECUADOR 0x0c +#define VK_RETURN 0x0D +#define WM_GETTEXT 0x000D +#define HTTOPLEFT 13 +#define CF_UNICODETEXT 13 +#define HELP_SETPOPUP_POS 0x000d +#define LANG_HEBREW 0x0d +#define SUBLANG_ARABIC_KUWAIT 0x0d +#define SUBLANG_ENGLISH_PHILIPPINES 0x0d +#define SUBLANG_SPANISH_CHILE 0x0d +#define WM_GETTEXTLENGTH 0x000E +#define HTTOPRIGHT 14 +#define CF_ENHMETAFILE 14 +#define LANG_HUNGARIAN 0x0e +#define SUBLANG_ARABIC_UAE 0x0e +#define SUBLANG_SPANISH_URUGUAY 0x0e +#define WM_PAINT 0x000F +#define HTBOTTOM 15 +#define CF_HDROP 15 +#define LANG_ICELANDIC 0x0f +#define SUBLANG_ARABIC_BAHRAIN 0x0f +#define SUBLANG_SPANISH_PARAGUAY 0x0f +#define VK_SHIFT 0x10 +#define WM_CLOSE 0x0010 +#define HTBOTTOMLEFT 16 +#define WVR_ALIGNTOP 0x0010 +#define MK_MBUTTON 0x0010 +#define TME_NONCLIENT 0x00000010 +#define CF_LOCALE 16 +#define HELP_TCARD_DATA 0x0010 +#define TBSTYLE_AUTOSIZE 0x0010 +#define TTS_NOANIMATE 0x10 +#define TBS_NOTICKS 0x0010 +#define UDS_AUTOBUDDY 0x0010 +#define PBS_SMOOTHREVERSE 0x10 +#define LWS_USECUSTOMTEXT 0x0010 +#define LVS_SORTASCENDING 0x0010 +#define TVS_DISABLEDRAGDROP 0x0010 +#define TVS_EX_RICHTOOLTIP 0x0010 +#define TCS_FORCEICONLEFT 0x0010 +#define MCS_NOTODAY 0x0010 +#define DTS_APPCANPARSE 0x0010 +#define NFS_ALL 0x0010 +#define LANG_ITALIAN 0x10 +#define SUBLANG_ARABIC_QATAR 0x10 +#define SUBLANG_ENGLISH_INDIA 0x10 +#define SUBLANG_SPANISH_BOLIVIA 0x10 +#define VK_CONTROL 0x11 +#define WM_QUERYENDSESSION 0x0011 +#define HTBOTTOMRIGHT 17 +#define CF_DIBV5 17 +#define HELP_TCARD_OTHER_CALLER 0x0011 +#define LANG_JAPANESE 0x11 +#define SUBLANG_ENGLISH_MALAYSIA 0x11 +#define SUBLANG_SPANISH_EL_SALVADOR 0x11 +#define VK_MENU 0x12 +#define WM_QUIT 0x0012 +#define HTBORDER 18 +#define CF_MAX 18 +#define LANG_KOREAN 0x12 +#define SUBLANG_ENGLISH_SINGAPORE 0x12 +#define SUBLANG_SPANISH_HONDURAS 0x12 +#define VK_PAUSE 0x13 +#define WM_QUERYOPEN 0x0013 +#define HTOBJECT 19 +#define LANG_DUTCH 0x13 +#define SUBLANG_SPANISH_NICARAGUA 0x13 +#define VK_CAPITAL 0x14 +#define WM_ERASEBKGND 0x0014 +#define HTCLOSE 20 +#define LANG_NORWEGIAN 0x14 +#define SUBLANG_SPANISH_PUERTO_RICO 0x14 +#define VK_KANA 0x15 +#define VK_HANGEUL 0x15 +#define VK_HANGUL 0x15 +#define WM_SYSCOLORCHANGE 0x0015 +#define HTHELP 21 +#define LANG_POLISH 0x15 +#define SUBLANG_SPANISH_US 0x15 +#define WM_ENDSESSION 0x0016 +#define LANG_PORTUGUESE 0x16 +#define VK_JUNJA 0x17 +#define LANG_ROMANSH 0x17 +#define VK_FINAL 0x18 +#define WM_SHOWWINDOW 0x0018 +#define LANG_ROMANIAN 0x18 +#define VK_HANJA 0x19 +#define VK_KANJI 0x19 +#define LANG_RUSSIAN 0x19 +#define WM_WININICHANGE 0x001A +#define LANG_BOSNIAN 0x1a +#define LANG_CROATIAN 0x1a +#define LANG_SERBIAN 0x1a +#define VK_ESCAPE 0x1B +#define WM_DEVMODECHANGE 0x001B +#define LANG_SLOVAK 0x1b +#define VK_CONVERT 0x1C +#define WM_ACTIVATEAPP 0x001C +#define LANG_ALBANIAN 0x1c +#define VK_NONCONVERT 0x1D +#define WM_FONTCHANGE 0x001D +#define LANG_SWEDISH 0x1d +#define VK_ACCEPT 0x1E +#define WM_TIMECHANGE 0x001E +#define LANG_THAI 0x1e +#define VK_MODECHANGE 0x1F +#define WM_CANCELMODE 0x001F +#define LANG_TURKISH 0x1f +#define VK_SPACE 0x20 +#define WM_SETCURSOR 0x0020 +#define SMTO_ERRORONEXIT 0x0020 +#define WVR_ALIGNLEFT 0x0020 +#define MK_XBUTTON1 0x0020 +#define CS_OWNDC 0x0020 +#define TBSTYLE_NOPREFIX 0x0020 +#define TTS_NOFADE 0x20 +#define TBS_ENABLESELRANGE 0x0020 +#define UDS_ARROWKEYS 0x0020 +#define LWS_RIGHT 0x0020 +#define LVS_SORTDESCENDING 0x0020 +#define TVS_SHOWSELALWAYS 0x0020 +#define TVS_EX_AUTOHSCROLL 0x0020 +#define TCS_FORCELABELLEFT 0x0020 +#define DTS_RIGHTALIGN 0x0020 +#define NFS_USEFONTASSOC 0x0020 +#define LANG_URDU 0x20 +#define VK_PRIOR 0x21 +#define WM_MOUSEACTIVATE 0x0021 +#define LANG_INDONESIAN 0x21 +#define VK_NEXT 0x22 +#define WM_CHILDACTIVATE 0x0022 +#define LANG_UKRAINIAN 0x22 +#define VK_END 0x23 +#define WM_QUEUESYNC 0x0023 +#define LANG_BELARUSIAN 0x23 +#define VK_HOME 0x24 +#define WM_GETMINMAXINFO 0x0024 +#define LANG_SLOVENIAN 0x24 +#define VK_LEFT 0x25 +#define LANG_ESTONIAN 0x25 +#define VK_UP 0x26 +#define WM_PAINTICON 0x0026 +#define LANG_LATVIAN 0x26 +#define VK_RIGHT 0x27 +#define WM_ICONERASEBKGND 0x0027 +#define LANG_LITHUANIAN 0x27 +#define VK_DOWN 0x28 +#define WM_NEXTDLGCTL 0x0028 +#define LANG_TAJIK 0x28 +#define VK_SELECT 0x29 +#define LANG_FARSI 0x29 +#define LANG_PERSIAN 0x29 +#define VK_PRINT 0x2A +#define WM_SPOOLERSTATUS 0x002A +#define LANG_VIETNAMESE 0x2a +#define VK_EXECUTE 0x2B +#define WM_DRAWITEM 0x002B +#define LANG_ARMENIAN 0x2b +#define VK_SNAPSHOT 0x2C +#define WM_MEASUREITEM 0x002C +#define LANG_AZERI 0x2c +#define VK_INSERT 0x2D +#define WM_DELETEITEM 0x002D +#define LANG_BASQUE 0x2d +#define VK_DELETE 0x2E +#define WM_VKEYTOITEM 0x002E +#define LANG_LOWER_SORBIAN 0x2e +#define LANG_UPPER_SORBIAN 0x2e +#define VK_HELP 0x2F +#define WM_CHARTOITEM 0x002F +#define LANG_MACEDONIAN 0x2f +#define WM_SETFONT 0x0030 +#define WM_GETFONT 0x0031 +#define WM_SETHOTKEY 0x0032 +#define LANG_TSWANA 0x32 +#define WM_GETHOTKEY 0x0033 +#define LANG_XHOSA 0x34 +#define LANG_ZULU 0x35 +#define LANG_AFRIKAANS 0x36 +#define WM_QUERYDRAGICON 0x0037 +#define LANG_GEORGIAN 0x37 +#define LANG_FAEROESE 0x38 +#define WM_COMPAREITEM 0x0039 +#define LANG_HINDI 0x39 +#define LANG_MALTESE 0x3a +#define LANG_SAMI 0x3b +#define LANG_IRISH 0x3c +#define WM_GETOBJECT 0x003D +#define LANG_MALAY 0x3e +#define LANG_KAZAK 0x3f +#define WVR_ALIGNBOTTOM 0x0040 +#define MK_XBUTTON2 0x0040 +#define CS_CLASSDC 0x0040 +#define HDS_DRAGDROP 0x0040 +#define BTNS_SHOWTEXT 0x0040 +#define TTS_BALLOON 0x40 +#define TBS_FIXEDLENGTH 0x0040 +#define UDS_HORZ 0x0040 +#define LVS_SHAREIMAGELISTS 0x0040 +#define TVS_RTLREADING 0x0040 +#define TVS_EX_FADEINOUTEXPANDOS 0x0040 +#define TCS_HOTTRACK 0x0040 +#define MCS_NOTRAILINGDATES 0x0040 +#define LANG_KYRGYZ 0x40 +#define WM_COMPACTING 0x0041 +#define LANG_SWAHILI 0x41 +#define LANG_TURKMEN 0x42 +#define LANG_UZBEK 0x43 +#define WM_COMMNOTIFY 0x0044 +#define LANG_TATAR 0x44 +#define LANG_BENGALI 0x45 +#define WM_WINDOWPOSCHANGING 0x0046 +#define LANG_PUNJABI 0x46 +#define WM_WINDOWPOSCHANGED 0x0047 +#define LANG_GUJARATI 0x47 +#define WM_POWER 0x0048 +#define LANG_ORIYA 0x48 +#define LANG_TAMIL 0x49 +#define WM_COPYDATA 0x004A +#define LANG_TELUGU 0x4a +#define WM_CANCELJOURNAL 0x004B +#define LANG_KANNADA 0x4b +#define LANG_MALAYALAM 0x4c +#define LANG_ASSAMESE 0x4d +#define WM_NOTIFY 0x004E +#define LANG_MARATHI 0x4e +#define LANG_SANSKRIT 0x4f +#define WM_INPUTLANGCHANGEREQUEST 0x0050 +#define LANG_MONGOLIAN 0x50 +#define WM_INPUTLANGCHANGE 0x0051 +#define LANG_TIBETAN 0x51 +#define WM_TCARD 0x0052 +#define LANG_WELSH 0x52 +#define WM_HELP 0x0053 +#define LANG_KHMER 0x53 +#define WM_USERCHANGED 0x0054 +#define LANG_LAO 0x54 +#define WM_NOTIFYFORMAT 0x0055 +#define LANG_GALICIAN 0x56 +#define LANG_KONKANI 0x57 +#define LANG_MANIPURI 0x58 +#define LANG_SINDHI 0x59 +#define LANG_SYRIAC 0x5a +#define VK_LWIN 0x5B +#define LANG_SINHALESE 0x5b +#define VK_RWIN 0x5C +#define VK_APPS 0x5D +#define LANG_INUKTITUT 0x5d +#define LANG_AMHARIC 0x5e +#define VK_SLEEP 0x5F +#define LANG_TAMAZIGHT 0x5f +#define VK_NUMPAD0 0x60 +#define LANG_KASHMIRI 0x60 +#define VK_NUMPAD1 0x61 +#define LANG_NEPALI 0x61 +#define VK_NUMPAD2 0x62 +#define LANG_FRISIAN 0x62 +#define VK_NUMPAD3 0x63 +#define LANG_PASHTO 0x63 +#define VK_NUMPAD4 0x64 +#define LANG_FILIPINO 0x64 +#define VS_USER_DEFINED 100 +#define VK_NUMPAD5 0x65 +#define LANG_DIVEHI 0x65 +#define VK_NUMPAD6 0x66 +#define VK_NUMPAD7 0x67 +#define VK_NUMPAD8 0x68 +#define LANG_HAUSA 0x68 +#define VK_NUMPAD9 0x69 +#define VK_MULTIPLY 0x6A +#define LANG_YORUBA 0x6a +#define VK_ADD 0x6B +#define LANG_QUECHUA 0x6b +#define VK_SEPARATOR 0x6C +#define LANG_SOTHO 0x6c +#define VK_SUBTRACT 0x6D +#define LANG_BASHKIR 0x6d +#define VK_DECIMAL 0x6E +#define LANG_LUXEMBOURGISH 0x6e +#define VK_DIVIDE 0x6F +#define LANG_GREENLANDIC 0x6f +#define VK_F1 0x70 +#define LANG_IGBO 0x70 +#define VK_F2 0x71 +#define VK_F3 0x72 +#define VK_F4 0x73 +#define LANG_TIGRIGNA 0x73 +#define VK_F5 0x74 +#define VK_F6 0x75 +#define VK_F7 0x76 +#define VK_F8 0x77 +#define VK_F9 0x78 +#define WHEEL_DELTA 120 +#define LANG_YI 0x78 +#define VK_F10 0x79 +#define VK_F11 0x7A +#define LANG_MAPUDUNGUN 0x7a +#define VK_F12 0x7B +#define WM_CONTEXTMENU 0x007B +#define VK_F13 0x7C +#define WM_STYLECHANGING 0x007C +#define LANG_MOHAWK 0x7c +#define VK_F14 0x7D +#define WM_STYLECHANGED 0x007D +#define VK_F15 0x7E +#define WM_DISPLAYCHANGE 0x007E +#define LANG_BRETON 0x7e +#define VK_F16 0x7F +#define WM_GETICON 0x007F +#define LANG_INVARIANT 0x7f +#define VK_F17 0x80 +#define WM_SETICON 0x0080 +#define WVR_ALIGNRIGHT 0x0080 +#define CS_PARENTDC 0x0080 +#define CF_OWNERDISPLAY 0x0080 +#define HDS_FULLDRAG 0x0080 +#define BTNS_WHOLEDROPDOWN 0x0080 +#define TTS_CLOSE 0x80 +#define TBS_NOTHUMB 0x0080 +#define UDS_NOTHOUSANDS 0x0080 +#define LVS_NOLABELWRAP 0x0080 +#define TVS_NOTOOLTIPS 0x0080 +#define TVS_EX_PARTIALCHECKBOXES 0x0080 +#define TCS_VERTICAL 0x0080 +#define MCS_SHORTDAYSOFWEEK 0x0080 +#define LANG_UIGHUR 0x80 +#define VK_F18 0x81 +#define WM_NCCREATE 0x0081 +#define CF_DSPTEXT 0x0081 +#define LANG_MAORI 0x81 +#define VK_F19 0x82 +#define WM_NCDESTROY 0x0082 +#define CF_DSPBITMAP 0x0082 +#define LANG_OCCITAN 0x82 +#define VK_F20 0x83 +#define WM_NCCALCSIZE 0x0083 +#define CF_DSPMETAFILEPICT 0x0083 +#define LANG_CORSICAN 0x83 +#define VK_F21 0x84 +#define WM_NCHITTEST 0x0084 +#define LANG_ALSATIAN 0x84 +#define VK_F22 0x85 +#define WM_NCPAINT 0x0085 +#define LANG_YAKUT 0x85 +#define VK_F23 0x86 +#define WM_NCACTIVATE 0x0086 +#define LANG_KICHE 0x86 +#define VK_F24 0x87 +#define WM_GETDLGCODE 0x0087 +#define LANG_KINYARWANDA 0x87 +#define WM_SYNCPAINT 0x0088 +#define LANG_WOLOF 0x88 +#define LANG_DARI 0x8c +#define CF_DSPENHMETAFILE 0x008E +#define VK_NUMLOCK 0x90 +#define VK_SCROLL 0x91 +#define VK_OEM_NEC_EQUAL 0x92 +#define VK_OEM_FJ_JISHO 0x92 +#define VK_OEM_FJ_MASSHOU 0x93 +#define VK_OEM_FJ_TOUROKU 0x94 +#define VK_OEM_FJ_LOYA 0x95 +#define VK_OEM_FJ_ROYA 0x96 +#define VK_LSHIFT 0xA0 +#define WM_NCMOUSEMOVE 0x00A0 +#define VK_RSHIFT 0xA1 +#define WM_NCLBUTTONDOWN 0x00A1 +#define VK_LCONTROL 0xA2 +#define WM_NCLBUTTONUP 0x00A2 +#define VK_RCONTROL 0xA3 +#define WM_NCLBUTTONDBLCLK 0x00A3 +#define VK_LMENU 0xA4 +#define WM_NCRBUTTONDOWN 0x00A4 +#define VK_RMENU 0xA5 +#define WM_NCRBUTTONUP 0x00A5 +#define VK_BROWSER_BACK 0xA6 +#define WM_NCRBUTTONDBLCLK 0x00A6 +#define VK_BROWSER_FORWARD 0xA7 +#define WM_NCMBUTTONDOWN 0x00A7 +#define VK_BROWSER_REFRESH 0xA8 +#define WM_NCMBUTTONUP 0x00A8 +#define VK_BROWSER_STOP 0xA9 +#define WM_NCMBUTTONDBLCLK 0x00A9 +#define VK_BROWSER_SEARCH 0xAA +#define VK_BROWSER_FAVORITES 0xAB +#define WM_NCXBUTTONDOWN 0x00AB +#define VK_BROWSER_HOME 0xAC +#define WM_NCXBUTTONUP 0x00AC +#define VK_VOLUME_MUTE 0xAD +#define WM_NCXBUTTONDBLCLK 0x00AD +#define VK_VOLUME_DOWN 0xAE +#define VK_VOLUME_UP 0xAF +#define VK_MEDIA_NEXT_TRACK 0xB0 +#define EM_GETSEL 0x00B0 +#define VK_MEDIA_PREV_TRACK 0xB1 +#define EM_SETSEL 0x00B1 +#define VK_MEDIA_STOP 0xB2 +#define EM_GETRECT 0x00B2 +#define VK_MEDIA_PLAY_PAUSE 0xB3 +#define EM_SETRECT 0x00B3 +#define VK_LAUNCH_MAIL 0xB4 +#define EM_SETRECTNP 0x00B4 +#define VK_LAUNCH_MEDIA_SELECT 0xB5 +#define EM_SCROLL 0x00B5 +#define VK_LAUNCH_APP1 0xB6 +#define EM_LINESCROLL 0x00B6 +#define VK_LAUNCH_APP2 0xB7 +#define EM_SCROLLCARET 0x00B7 +#define EM_GETMODIFY 0x00B8 +#define EM_SETMODIFY 0x00B9 +#define VK_OEM_1 0xBA +#define EM_GETLINECOUNT 0x00BA +#define VK_OEM_PLUS 0xBB +#define EM_LINEINDEX 0x00BB +#define VK_OEM_COMMA 0xBC +#define EM_SETHANDLE 0x00BC +#define VK_OEM_MINUS 0xBD +#define EM_GETHANDLE 0x00BD +#define VK_OEM_PERIOD 0xBE +#define EM_GETTHUMB 0x00BE +#define VK_OEM_2 0xBF +#define VK_OEM_3 0xC0 +#define EM_LINELENGTH 0x00C1 +#define EM_REPLACESEL 0x00C2 +#define EM_GETLINE 0x00C4 +#define EM_LIMITTEXT 0x00C5 +#define EM_CANUNDO 0x00C6 +#define EM_UNDO 0x00C7 +#define EM_FMTLINES 0x00C8 +#define DLG_MAIN 200 +#define EM_LINEFROMCHAR 0x00C9 +#define EM_SETTABSTOPS 0x00CB +#define EM_SETPASSWORDCHAR 0x00CC +#define EM_EMPTYUNDOBUFFER 0x00CD +#define EM_GETFIRSTVISIBLELINE 0x00CE +#define EM_SETREADONLY 0x00CF +#define EM_SETWORDBREAKPROC 0x00D0 +#define EM_GETWORDBREAKPROC 0x00D1 +#define EM_GETPASSWORDCHAR 0x00D2 +#define EM_SETMARGINS 0x00D3 +#define EM_GETMARGINS 0x00D4 +#define EM_GETLIMITTEXT 0x00D5 +#define EM_POSFROMCHAR 0x00D6 +#define EM_CHARFROMPOS 0x00D7 +#define EM_SETIMESTATUS 0x00D8 +#define EM_GETIMESTATUS 0x00D9 +#define VK_OEM_4 0xDB +#define VK_OEM_5 0xDC +#define VK_OEM_6 0xDD +#define VK_OEM_7 0xDE +#define VK_OEM_8 0xDF +#define VK_OEM_AX 0xE1 +#define VK_OEM_102 0xE2 +#define VK_ICO_HELP 0xE3 +#define VK_ICO_00 0xE4 +#define VK_PROCESSKEY 0xE5 +#define VK_ICO_CLEAR 0xE6 +#define VK_PACKET 0xE7 +#define VK_OEM_RESET 0xE9 +#define VK_OEM_JUMP 0xEA +#define VK_OEM_PA1 0xEB +#define VK_OEM_PA2 0xEC +#define VK_OEM_PA3 0xED +#define VK_OEM_WSCTRL 0xEE +#define VK_OEM_CUSEL 0xEF +#define VK_OEM_ATTN 0xF0 +#define BM_GETCHECK 0x00F0 +#define VK_OEM_FINISH 0xF1 +#define BM_SETCHECK 0x00F1 +#define VK_OEM_COPY 0xF2 +#define BM_GETSTATE 0x00F2 +#define VK_OEM_AUTO 0xF3 +#define BM_SETSTATE 0x00F3 +#define VK_OEM_ENLW 0xF4 +#define BM_SETSTYLE 0x00F4 +#define VK_OEM_BACKTAB 0xF5 +#define BM_CLICK 0x00F5 +#define VK_ATTN 0xF6 +#define BM_GETIMAGE 0x00F6 +#define VK_CRSEL 0xF7 +#define BM_SETIMAGE 0x00F7 +#define VK_EXSEL 0xF8 +#define BM_SETDONTCLICK 0x00F8 +#define VK_EREOF 0xF9 +#define VK_PLAY 0xFA +#define VK_ZOOM 0xFB +#define VK_NONAME 0xFC +#define VK_PA1 0xFD +#define VK_OEM_CLEAR 0xFE +#define WM_INPUT_DEVICE_CHANGE 0x00FE +#define SUBVERSION_MASK 0x000000FF +#define WM_INPUT 0x00FF +#define WM_KEYFIRST 0x0100 +#define WM_KEYDOWN 0x0100 +#define WVR_HREDRAW 0x0100 +#define HDS_FILTERBAR 0x0100 +#define TBSTYLE_TOOLTIPS 0x0100 +#define RBS_TOOLTIPS 0x00000100 +#define TTS_USEVISUALSTYLE 0x100 +#define SBARS_SIZEGRIP 0x0100 +#define TBS_TOOLTIPS 0x0100 +#define UDS_HOTTRACK 0x0100 +#define LVS_AUTOARRANGE 0x0100 +#define TVS_CHECKBOXES 0x0100 +#define TVS_EX_EXCLUSIONCHECKBOXES 0x0100 +#define TCS_BUTTONS 0x0100 +#define MCS_NOSELCHANGEONNAV 0x0100 +#define WM_KEYUP 0x0101 +#define WM_CHAR 0x0102 +#define WM_DEADCHAR 0x0103 +#define WM_SYSKEYDOWN 0x0104 +#define WM_SYSKEYUP 0x0105 +#define WM_SYSCHAR 0x0106 +#define WM_SYSDEADCHAR 0x0107 +#define WM_UNICHAR 0x0109 +#define WM_IME_STARTCOMPOSITION 0x010D +#define WM_IME_ENDCOMPOSITION 0x010E +#define WM_IME_COMPOSITION 0x010F +#define WM_IME_KEYLAST 0x010F +#define WM_INITDIALOG 0x0110 +#define WM_COMMAND 0x0111 +#define WM_SYSCOMMAND 0x0112 +#define WM_TIMER 0x0113 +#define WM_HSCROLL 0x0114 +#define WM_VSCROLL 0x0115 +#define WM_INITMENU 0x0116 +#define WM_INITMENUPOPUP 0x0117 +#define WM_MENUSELECT 0x011F +#define WM_MENUCHAR 0x0120 +#define WM_ENTERIDLE 0x0121 +#define WM_MENURBUTTONUP 0x0122 +#define WM_MENUDRAG 0x0123 +#define WM_MENUGETOBJECT 0x0124 +#define WM_UNINITMENUPOPUP 0x0125 +#define WM_MENUCOMMAND 0x0126 +#define WM_CHANGEUISTATE 0x0127 +#define WM_UPDATEUISTATE 0x0128 +#define WM_QUERYUISTATE 0x0129 +#define DLG_ICON 300 +#define WM_CTLCOLORMSGBOX 0x0132 +#define WM_CTLCOLOREDIT 0x0133 +#define WM_CTLCOLORLISTBOX 0x0134 +#define WM_CTLCOLORBTN 0x0135 +#define WM_CTLCOLORDLG 0x0136 +#define WM_CTLCOLORSCROLLBAR 0x0137 +#define WM_CTLCOLORSTATIC 0x0138 +#define MN_GETHMENU 0x01E1 +#define _WIN32_IE_IE20 0x0200 +#define WM_MOUSEFIRST 0x0200 +#define WM_MOUSEMOVE 0x0200 +#define WVR_VREDRAW 0x0200 +#define CS_NOCLOSE 0x0200 +#define CF_PRIVATEFIRST 0x0200 +#define HDS_FLAT 0x0200 +#define TBSTYLE_WRAPABLE 0x0200 +#define RBS_VARHEIGHT 0x00000200 +#define TBS_REVERSED 0x0200 +#define LVS_EDITLABELS 0x0200 +#define TVS_TRACKSELECT 0x0200 +#define TVS_EX_DIMMEDCHECKBOXES 0x0200 +#define TCS_MULTILINE 0x0200 +#define WM_LBUTTONDOWN 0x0201 +#define WM_LBUTTONUP 0x0202 +#define WM_LBUTTONDBLCLK 0x0203 +#define WM_RBUTTONDOWN 0x0204 +#define WM_RBUTTONUP 0x0205 +#define WM_RBUTTONDBLCLK 0x0206 +#define WM_MBUTTONDOWN 0x0207 +#define WM_MBUTTONUP 0x0208 +#define WM_MBUTTONDBLCLK 0x0209 +#define WM_MOUSEWHEEL 0x020A +#define WM_XBUTTONDOWN 0x020B +#define WM_XBUTTONUP 0x020C +#define WM_XBUTTONDBLCLK 0x020D +#define WM_MOUSEHWHEEL 0x020E +#define WM_PARENTNOTIFY 0x0210 +#define WM_ENTERMENULOOP 0x0211 +#define WM_EXITMENULOOP 0x0212 +#define WM_NEXTMENU 0x0213 +#define WM_SIZING 0x0214 +#define WM_CAPTURECHANGED 0x0215 +#define WM_MOVING 0x0216 +#define WM_POWERBROADCAST 0x0218 +#define WM_DEVICECHANGE 0x0219 +#define WM_MDICREATE 0x0220 +#define WM_MDIDESTROY 0x0221 +#define WM_MDIACTIVATE 0x0222 +#define WM_MDIRESTORE 0x0223 +#define WM_MDINEXT 0x0224 +#define WM_MDIMAXIMIZE 0x0225 +#define WM_MDITILE 0x0226 +#define WM_MDICASCADE 0x0227 +#define WM_MDIICONARRANGE 0x0228 +#define WM_MDIGETACTIVE 0x0229 +#define WM_MDISETMENU 0x0230 +#define WM_ENTERSIZEMOVE 0x0231 +#define WM_EXITSIZEMOVE 0x0232 +#define WM_DROPFILES 0x0233 +#define WM_MDIREFRESHMENU 0x0234 +#define WM_IME_SETCONTEXT 0x0281 +#define WM_IME_NOTIFY 0x0282 +#define WM_IME_CONTROL 0x0283 +#define WM_IME_COMPOSITIONFULL 0x0284 +#define WM_IME_SELECT 0x0285 +#define WM_IME_CHAR 0x0286 +#define WM_IME_REQUEST 0x0288 +#define WM_IME_KEYDOWN 0x0290 +#define WM_IME_KEYUP 0x0291 +#define WM_NCMOUSEHOVER 0x02A0 +#define WM_MOUSEHOVER 0x02A1 +#define WM_NCMOUSELEAVE 0x02A2 +#define WM_MOUSELEAVE 0x02A3 +#define WM_WTSSESSION_CHANGE 0x02B1 +#define WM_TABLET_FIRST 0x02c0 +#define WM_TABLET_LAST 0x02df +#define CF_PRIVATELAST 0x02FF +#define _WIN32_IE_IE30 0x0300 +#define WM_CUT 0x0300 +#define CF_GDIOBJFIRST 0x0300 +#define WM_COPY 0x0301 +#define _WIN32_IE_IE302 0x0302 +#define WM_PASTE 0x0302 +#define WM_CLEAR 0x0303 +#define WM_UNDO 0x0304 +#define WM_RENDERFORMAT 0x0305 +#define WM_RENDERALLFORMATS 0x0306 +#define WM_DESTROYCLIPBOARD 0x0307 +#define WM_DRAWCLIPBOARD 0x0308 +#define WM_PAINTCLIPBOARD 0x0309 +#define WM_VSCROLLCLIPBOARD 0x030A +#define WM_SIZECLIPBOARD 0x030B +#define WM_ASKCBFORMATNAME 0x030C +#define WM_CHANGECBCHAIN 0x030D +#define WM_HSCROLLCLIPBOARD 0x030E +#define WM_QUERYNEWPALETTE 0x030F +#define WM_PALETTEISCHANGING 0x0310 +#define WM_PALETTECHANGED 0x0311 +#define WM_HOTKEY 0x0312 +#define WM_PRINT 0x0317 +#define WM_PRINTCLIENT 0x0318 +#define WM_APPCOMMAND 0x0319 +#define WM_THEMECHANGED 0x031A +#define WM_CLIPBOARDUPDATE 0x031D +#define WM_DWMCOMPOSITIONCHANGED 0x031E +#define WM_DWMNCRENDERINGCHANGED 0x031F +#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 +#define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321 +#define WM_GETTITLEBARINFOEX 0x033F +#define WM_HANDHELDFIRST 0x0358 +#define WM_HANDHELDLAST 0x035F +#define WM_AFXFIRST 0x0360 +#define WM_AFXLAST 0x037F +#define WM_PENWINFIRST 0x0380 +#define WM_PENWINLAST 0x038F +#define WM_DDE_FIRST 0x03E0 +#define IDC_STATUS 1000 +#define IDC_LIST1 1000 +#define IDC_LEFT 1001 +#define IDC_RIGHT 1002 +#define IDC_TOP 1003 +#define IDC_MIDDLE 1004 +#define IDC_BOTTOM 1005 +#define IDC_EDIT 1010 +#define IDC_CLEAR 1011 +#define CF_GDIOBJLAST 0x03FF +#define _WIN32_WINNT_NT4 0x0400 +#define _WIN32_IE_IE40 0x0400 +#define WM_USER 0x0400 +#define WVR_VALIDRECTS 0x0400 +#define HDS_CHECKBOXES 0x0400 +#define TBSTYLE_ALTDRAG 0x0400 +#define RBS_BANDBORDERS 0x00000400 +#define TBS_DOWNISLEFT 0x0400 +#define LVS_OWNERDRAWFIXED 0x0400 +#define TVS_SINGLEEXPAND 0x0400 +#define TVS_EX_DRAWIMAGEASYNC 0x0400 +#define TCS_FIXEDWIDTH 0x0400 +#define ctlFirst 0x0400 +#define psh1 0x0400 +#define _WIN32_IE_IE401 0x0401 +#define psh2 0x0401 +#define psh3 0x0402 +#define psh4 0x0403 +#define psh5 0x0404 +#define psh6 0x0405 +#define psh7 0x0406 +#define psh8 0x0407 +#define psh9 0x0408 +#define psh10 0x0409 +#define psh11 0x040a +#define psh12 0x040b +#define psh13 0x040c +#define psh14 0x040d +#define psh15 0x040e +#define psh16 0x040f +#define _WIN32_WINDOWS 0x0410 +#define chx1 0x0410 +#define chx2 0x0411 +#define chx3 0x0412 +#define chx4 0x0413 +#define chx5 0x0414 +#define chx6 0x0415 +#define chx7 0x0416 +#define chx8 0x0417 +#define chx9 0x0418 +#define chx10 0x0419 +#define chx11 0x041a +#define chx12 0x041b +#define chx13 0x041c +#define chx14 0x041d +#define chx15 0x041e +#define chx16 0x041f +#define rad1 0x0420 +#define rad2 0x0421 +#define rad3 0x0422 +#define rad4 0x0423 +#define rad5 0x0424 +#define rad6 0x0425 +#define rad7 0x0426 +#define rad8 0x0427 +#define rad9 0x0428 +#define rad10 0x0429 +#define rad11 0x042a +#define rad12 0x042b +#define rad13 0x042c +#define rad14 0x042d +#define rad15 0x042e +#define rad16 0x042f +#define grp1 0x0430 +#define grp2 0x0431 +#define grp3 0x0432 +#define grp4 0x0433 +#define frm1 0x0434 +#define frm2 0x0435 +#define frm3 0x0436 +#define frm4 0x0437 +#define rct1 0x0438 +#define rct2 0x0439 +#define rct3 0x043a +#define rct4 0x043b +#define ico1 0x043c +#define ico2 0x043d +#define ico3 0x043e +#define ico4 0x043f +#define stc1 0x0440 +#define stc2 0x0441 +#define stc3 0x0442 +#define stc4 0x0443 +#define stc5 0x0444 +#define stc6 0x0445 +#define stc7 0x0446 +#define stc8 0x0447 +#define stc9 0x0448 +#define stc10 0x0449 +#define stc11 0x044a +#define stc12 0x044b +#define stc13 0x044c +#define stc14 0x044d +#define stc15 0x044e +#define stc16 0x044f +#define stc17 0x0450 +#define stc18 0x0451 +#define stc19 0x0452 +#define stc20 0x0453 +#define stc21 0x0454 +#define stc22 0x0455 +#define stc23 0x0456 +#define stc24 0x0457 +#define stc25 0x0458 +#define stc26 0x0459 +#define stc27 0x045a +#define stc28 0x045b +#define stc29 0x045c +#define stc30 0x045d +#define stc31 0x045e +#define stc32 0x045f +#define lst1 0x0460 +#define lst2 0x0461 +#define lst3 0x0462 +#define lst4 0x0463 +#define lst5 0x0464 +#define lst6 0x0465 +#define lst7 0x0466 +#define lst8 0x0467 +#define lst9 0x0468 +#define lst10 0x0469 +#define lst11 0x046a +#define lst12 0x046b +#define lst13 0x046c +#define lst14 0x046d +#define lst15 0x046e +#define lst16 0x046f +#define cmb1 0x0470 +#define cmb2 0x0471 +#define cmb3 0x0472 +#define cmb4 0x0473 +#define cmb5 0x0474 +#define cmb6 0x0475 +#define cmb7 0x0476 +#define cmb8 0x0477 +#define cmb9 0x0478 +#define cmb10 0x0479 +#define cmb11 0x047a +#define cmb12 0x047b +#define cmb13 0x047c +#define cmb14 0x047d +#define cmb15 0x047e +#define cmb16 0x047f +#define edt1 0x0480 +#define edt2 0x0481 +#define edt3 0x0482 +#define edt4 0x0483 +#define edt5 0x0484 +#define edt6 0x0485 +#define edt7 0x0486 +#define edt8 0x0487 +#define edt9 0x0488 +#define edt10 0x0489 +#define edt11 0x048a +#define edt12 0x048b +#define edt13 0x048c +#define edt14 0x048d +#define edt15 0x048e +#define edt16 0x048f +#define scr1 0x0490 +#define scr2 0x0491 +#define scr3 0x0492 +#define scr4 0x0493 +#define scr5 0x0494 +#define scr6 0x0495 +#define scr7 0x0496 +#define scr8 0x0497 +#define ctl1 0x04A0 +#define ctlLast 0x04ff +#define _WIN32_WINNT_WIN2K 0x0500 +#define _WIN32_IE_IE50 0x0500 +#define _WIN32_WINNT_WINXP 0x0501 +#define _WIN32_IE_IE501 0x0501 +#define _WIN32_WINNT_WS03 0x0502 +#define _WIN32_IE_IE55 0x0550 +#define _WIN32_WINNT_LONGHORN 0x0600 +#define _WIN32_IE_IE60 0x0600 +#define FILEOPENORD 1536 +#define _WIN32_IE_IE60SP1 0x0601 +#define MULTIFILEOPENORD 1537 +#define _WIN32_IE_WS03 0x0602 +#define PRINTDLGORD 1538 +#define _WIN32_IE_IE60SP2 0x0603 +#define PRNSETUPDLGORD 1539 +#define FINDDLGORD 1540 +#define REPLACEDLGORD 1541 +#define FONTDLGORD 1542 +#define FORMATDLGORD31 1543 +#define FORMATDLGORD30 1544 +#define RUNDLGORD 1545 +#define PAGESETUPDLGORD 1546 +#define NEWFILEOPENORD 1547 +#define PRINTDLGEXORD 1549 +#define PAGESETUPDLGORDMOTIF 1550 +#define COLORMGMTDLGORD 1551 +#define NEWFILEOPENV2ORD 1552 +#define NEWFILEOPENV3ORD 1553 +#define _WIN32_IE_IE70 0x0700 +#define CS_SAVEBITS 0x0800 +#define HDS_NOSIZING 0x0800 +#define TBSTYLE_FLAT 0x0800 +#define RBS_FIXEDORDER 0x00000800 +#define SBARS_TOOLTIPS 0x0800 +#define SBT_TOOLTIPS 0x0800 +#define TBS_NOTIFYBEFOREMOVE 0x0800 +#define LVS_ALIGNLEFT 0x0800 +#define TVS_INFOTIP 0x0800 +#define TCS_RAGGEDRIGHT 0x0800 +#define LVS_ALIGNMASK 0x0c00 +#define CS_BYTEALIGNCLIENT 0x1000 +#define HDS_OVERFLOW 0x1000 +#define TBSTYLE_LIST 0x1000 +#define RBS_REGISTERDROP 0x00001000 +#define TBS_TRANSPARENTBKGND 0x1000 +#define LVS_OWNERDATA 0x1000 +#define TVS_FULLROWSELECT 0x1000 +#define TCS_FOCUSONBUTTONDOWN 0x1000 +#define CS_BYTEALIGNWINDOW 0x2000 +#define TBSTYLE_CUSTOMERASE 0x2000 +#define RBS_AUTOSIZE 0x00002000 +#define LVS_NOSCROLL 0x2000 +#define TVS_NOSCROLL 0x2000 +#define TCS_OWNERDRAWFIXED 0x2000 +#define CS_GLOBALCLASS 0x4000 +#define TBSTYLE_REGISTERDROP 0x4000 +#define RBS_VERTICALGRIPPER 0x00004000 +#define LVS_NOCOLUMNHEADER 0x4000 +#define TVS_NONEVENHEIGHT 0x4000 +#define TCS_TOOLTIPS 0x4000 +#define IDH_NO_HELP 28440 +#define IDH_MISSING_CONTEXT 28441 +#define IDH_GENERIC_HELP_BUTTON 28442 +#define IDH_OK 28443 +#define IDH_CANCEL 28444 +#define IDH_HELP 28445 +#define LANG_BOSNIAN_NEUTRAL 0x781a +#define LANG_CHINESE_TRADITIONAL 0x7c04 +#define LANG_SERBIAN_NEUTRAL 0x7c1a +#define IDTIMEOUT 32000 +#define OCR_NORMAL 32512 +#define OIC_SAMPLE 32512 +#define OCR_IBEAM 32513 +#define OIC_HAND 32513 +#define OCR_WAIT 32514 +#define OIC_QUES 32514 +#define OCR_CROSS 32515 +#define OIC_BANG 32515 +#define OCR_UP 32516 +#define OIC_NOTE 32516 +#define OIC_WINLOGO 32517 +#define OIC_SHIELD 32518 +#define OCR_SIZE 32640 +#define OCR_ICON 32641 +#define OCR_SIZENWSE 32642 +#define OCR_SIZENESW 32643 +#define OCR_SIZEWE 32644 +#define OCR_SIZENS 32645 +#define OCR_SIZEALL 32646 +#define OCR_ICOCUR 32647 +#define OCR_NO 32648 +#define OCR_HAND 32649 +#define OCR_APPSTARTING 32650 +#define OBM_LFARROWI 32734 +#define OBM_RGARROWI 32735 +#define OBM_DNARROWI 32736 +#define OBM_UPARROWI 32737 +#define OBM_COMBO 32738 +#define OBM_MNARROW 32739 +#define OBM_LFARROWD 32740 +#define OBM_RGARROWD 32741 +#define OBM_DNARROWD 32742 +#define OBM_UPARROWD 32743 +#define OBM_RESTORED 32744 +#define OBM_ZOOMD 32745 +#define OBM_REDUCED 32746 +#define OBM_RESTORE 32747 +#define OBM_ZOOM 32748 +#define OBM_REDUCE 32749 +#define OBM_LFARROW 32750 +#define OBM_RGARROW 32751 +#define OBM_DNARROW 32752 +#define OBM_UPARROW 32753 +#define OBM_CLOSE 32754 +#define OBM_OLD_RESTORE 32755 +#define OBM_OLD_ZOOM 32756 +#define OBM_OLD_REDUCE 32757 +#define OBM_BTNCORNERS 32758 +#define OBM_CHECKBOXES 32759 +#define OBM_CHECK 32760 +#define OBM_BTSIZE 32761 +#define OBM_OLD_LFARROW 32762 +#define OBM_OLD_RGARROW 32763 +#define OBM_OLD_DNARROW 32764 +#define OBM_OLD_UPARROW 32765 +#define OBM_SIZE 32766 +#define OBM_OLD_CLOSE 32767 +#define WM_APP 0x8000 +#define HELP_TCARD 0x8000 +#define TBSTYLE_TRANSPARENT 0x8000 +#define RBS_DBLCLKTOGGLE 0x00008000 +#define LVS_NOSORTHEADER 0x8000 +#define TVS_NOHSCROLL 0x8000 +#define TCS_FOCUSNEVER 0x8000 +#define SC_SIZE 0xF000 +#define SC_SEPARATOR 0xF00F +#define SC_MOVE 0xF010 +#define SC_MINIMIZE 0xF020 +#define SC_MAXIMIZE 0xF030 +#define SC_NEXTWINDOW 0xF040 +#define SC_PREVWINDOW 0xF050 +#define SC_CLOSE 0xF060 +#define SC_VSCROLL 0xF070 +#define SC_HSCROLL 0xF080 +#define SC_MOUSEMENU 0xF090 +#define SC_KEYMENU 0xF100 +#define SC_ARRANGE 0xF110 +#define SC_RESTORE 0xF120 +#define SC_TASKLIST 0xF130 +#define SC_SCREENSAVE 0xF140 +#define SC_HOTKEY 0xF150 +#define SC_DEFAULT 0xF160 +#define SC_MONITORPOWER 0xF170 +#define SC_CONTEXTHELP 0xF180 +#define LVS_TYPESTYLEMASK 0xfc00 +#define SPVERSION_MASK 0x0000FF00 +#define UNICODE_NOCHAR 0xFFFF +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/PC/associator.rc b/PC/associator.rc new file mode 100644 index 0000000..374a3b8 --- /dev/null +++ b/PC/associator.rc @@ -0,0 +1,97 @@ +// Microsoft Visual C++ generated resource script. +// +#include "associator.h" +#include "winuser.h" +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +DLG_ICON ICON "launcher.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +DLG_MAIN DIALOGEX 20, 40, 236, 183 +// Make the dialog visible after positioning at centre +STYLE DS_SETFONT | DS_3DLOOK | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_NOPARENTNOTIFY +CAPTION "Python File Associations Have Ceased To Be!" +FONT 10, "Arial", 400, 0, 0x0 +BEGIN + LTEXT "You've uninstalled the Python Launcher, so now there are no applications associated with Python files.",IDC_STATIC,7,7,225,18 + LTEXT "You may wish to associate Python files with one of the Python versions installed on your machine, listed below:",IDC_STATIC,7,27,225,18 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,6,49,224,105 + PUSHBUTTON "&Associate with selected Python",IDOK,6,164,117,14,WS_DISABLED + PUSHBUTTON "Do&n't associate Python files",IDCANCEL,128,164,102,14 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + DLG_MAIN, DIALOG + BEGIN + RIGHTMARGIN, 238 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/PCbuild/associator.vcxproj b/PCbuild/associator.vcxproj new file mode 100644 index 0000000..595b2ce --- /dev/null +++ b/PCbuild/associator.vcxproj @@ -0,0 +1,84 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {023B3CDA-59C8-45FD-95DC-F8973322ED34} + associator + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + true + comctl32.lib;%(AdditionalDependencies) + false + + + + + Level3 + MaxSpeed + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + true + true + true + comctl32.lib;%(AdditionalDependencies) + false + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/associator.vcxproj.filters b/PCbuild/associator.vcxproj.filters new file mode 100644 index 0000000..0846afa --- /dev/null +++ b/PCbuild/associator.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + + + Header Files + + + \ No newline at end of file diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 441c2d8..ed7c444 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -72,6 +72,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vc EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "associator", "associator.vcxproj", "{023B3CDA-59C8-45FD-95DC-F8973322ED34}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -597,6 +599,18 @@ Global {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Debug|Win32.ActiveCfg = Debug|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Debug|Win32.Build.0 = Debug|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Debug|x64.ActiveCfg = Debug|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.PGInstrument|Win32.Build.0 = Release|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.PGInstrument|x64.ActiveCfg = Release|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.PGUpdate|Win32.Build.0 = Release|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.PGUpdate|x64.ActiveCfg = Release|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Release|Win32.ActiveCfg = Release|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Release|Win32.Build.0 = Release|Win32 + {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE -- cgit v0.12 From 56bf6f82021a842d3619e76a9c9d67f54b56fe6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 21 Jun 2012 16:27:58 +0200 Subject: Add version resource. --- PC/pylauncher.rc | 52 ++++++++++++++++++++++++++++++++++++++++++++-- PCbuild/pylauncher.vcxproj | 5 +++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc index fadc5df..df5824a 100644 --- a/PC/pylauncher.rc +++ b/PC/pylauncher.rc @@ -1,3 +1,51 @@ +#include + +#define MS_WINDOWS +#include "..\Include\modsupport.h" +#include "..\Include\patchlevel.h" +#ifdef _DEBUG +# include "pythonnt_rc_d.h" +#else +# include "pythonnt_rc.h" +#endif + +#define PYTHON_VERSION PY_VERSION "\0" +#define PYVERSION64 PY_MAJOR_VERSION, PY_MINOR_VERSION, FIELD3, PYTHON_API_VERSION + +VS_VERSION_INFO VERSIONINFO + FILEVERSION PYVERSION64 + PRODUCTVERSION PYVERSION64 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "Comments", "Python Launcher for Windows" + VALUE "CompanyName", "Python Software Foundation" + VALUE "FileDescription", "Python Launcher for Windows (Console)" + VALUE "FileVersion", PYTHON_VERSION + VALUE "InternalName", "py" + VALUE "LegalCopyright", "Copyright (C) 2011-2012 Python Software Foundation" + VALUE "OriginalFilename", "py" + VALUE "ProductName", "Python Launcher for Windows" + VALUE "ProductVersion", PYTHON_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END + IDI_ICON1 ICON "launcher.ico" -IDI_ICON2 ICON "py.ico" -IDI_ICON3 ICON "pyc.ico" \ No newline at end of file + + diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj index c97bb82..25cc245 100644 --- a/PCbuild/pylauncher.vcxproj +++ b/PCbuild/pylauncher.vcxproj @@ -154,6 +154,11 @@ + + + {f0e0541e-f17d-430b-97c4-93adf0dd284e} + + -- cgit v0.12 From f36d65c7c87234814867661f5089e903ae7319e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 21 Jun 2012 16:33:09 +0200 Subject: Use GetEnvironmentVariableW instead of _wgetenv to silence VC warnings. --- PC/launcher.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/PC/launcher.c b/PC/launcher.c index 22d2974..5792d1b 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -54,22 +54,31 @@ skip_whitespace(wchar_t * p) } /* - * This function is here to minimise Visual Studio - * warnings about security implications of getenv, and to - * treat blank values as if they are absent. + * This function is here to simplify memory management + * and to treat blank values as if they are absent. */ static wchar_t * get_env(wchar_t * key) { - wchar_t * result = _wgetenv(key); - - if (result) { - result = skip_whitespace(result); - if (*result == L'\0') - result = NULL; + /* This is not thread-safe, just like getenv */ + static wchar_t buf[256]; + DWORD result = GetEnvironmentVariableW(key, buf, 256); + + if (result > 256) { + /* Large environment variable. Accept some leakage */ + wchar_t *buf2 = (wchar_t*)malloc(sizeof(wchar_t) * (result+1)); + GetEnvironmentVariableW(key, buf2, result); + return buf2; } - return result; + + if (result == 0) + /* Either some error, e.g. ERROR_ENVVAR_NOT_FOUND, + or an empty environment variable. */ + return NULL; + + return buf; } + static void debug(wchar_t * format, ...) { -- cgit v0.12 From 7dae234e78ef14dae06fe7c5de6612cda26c116c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 21 Jun 2012 17:36:05 +0200 Subject: Package the launcher. --- Tools/msi/msi.py | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py index b2482df..1e9e2e8 100644 --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -286,7 +286,7 @@ def remove_old_versions(db): None, migrate_features, None, "REMOVEOLDSNAPSHOT")]) props = "REMOVEOLDSNAPSHOT;REMOVEOLDVERSION" - props += ";TARGETDIR;DLLDIR" + props += ";TARGETDIR;DLLDIR;LAUNCHERDIR" # Installer collects the product codes of the earlier releases in # these properties. In order to allow modification of the properties, # they must be declared as secure. See "SecureCustomProperties Property" @@ -426,6 +426,8 @@ def add_ui(db): "[WindowsVolume]Python%s%s" % (major, minor)), ("SetDLLDirToTarget", 307, "DLLDIR", "[TARGETDIR]"), ("SetDLLDirToSystem32", 307, "DLLDIR", SystemFolderName), + ("SetLauncherDirToTarget", 307, "LAUNCHERDIR", "[TARGETDIR]"), + ("SetLauncherDirToWindows", 307, "LAUNCHERDIR", "[WindowsFolder]"), # msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile # See "Custom Action Type 18" ("CompilePyc", 18, "python.exe", compileargs), @@ -442,6 +444,8 @@ def add_ui(db): # In the user interface, assume all-users installation if privileged. ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751), ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752), + ("SetLauncherDirToWindows", 'LAUNCHERDIR="" and ' + sys32cond, 753), + ("SetLauncherDirToTarget", 'LAUNCHERDIR="" and not ' + sys32cond, 754), ("SelectDirectoryDlg", "Not Installed", 1230), # XXX no support for resume installations yet #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240), @@ -450,6 +454,7 @@ def add_ui(db): add_data(db, "AdminUISequence", [("InitialTargetDir", 'TARGETDIR=""', 750), ("SetDLLDirToTarget", 'DLLDIR=""', 751), + ("SetLauncherDirToTarget", 'LAUNCHERDIR=""', 752), ]) # Prepend TARGETDIR to the system path, and remove it on uninstall. @@ -461,6 +466,8 @@ def add_ui(db): [("InitialTargetDir", 'TARGETDIR=""', 750), ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751), ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752), + ("SetLauncherDirToWindows", 'LAUNCHERDIR="" and ' + sys32cond, 753), + ("SetLauncherDirToTarget", 'LAUNCHERDIR="" and not ' + sys32cond, 754), ("UpdateEditIDLE", None, 1050), ("CompilePyc", "COMPILEALL", 6800), ("CompilePyo", "COMPILEALL", 6801), @@ -469,6 +476,7 @@ def add_ui(db): add_data(db, "AdminExecuteSequence", [("InitialTargetDir", 'TARGETDIR=""', 750), ("SetDLLDirToTarget", 'DLLDIR=""', 751), + ("SetLauncherDirToTarget", 'LAUNCHERDIR=""', 752), ("CompilePyc", "COMPILEALL", 6800), ("CompilePyo", "COMPILEALL", 6801), ("CompileGrammar", "COMPILEALL", 6802), @@ -904,7 +912,7 @@ def generate_license(): dirs = glob.glob(srcdir+"/../"+pat) if not dirs: raise ValueError, "Could not find "+srcdir+"/../"+pat - if len(dirs) > 2: + if len(dirs) > 2 and not snapshot: raise ValueError, "Multiple copies of "+pat dir = dirs[0] shutil.copyfileobj(open(os.path.join(dir, file)), out) @@ -939,6 +947,7 @@ def hgmanifest(): # See "File Table", "Component Table", "Directory Table", # "FeatureComponents Table" def add_files(db): + installer = msilib.MakeInstaller() hgfiles = hgmanifest() cab = CAB("python") tmpfiles = [] @@ -958,11 +967,26 @@ def add_files(db): # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table" dlldir = PyDirectory(db, cab, root, srcdir, "DLLDIR", ".") + launcherdir = PyDirectory(db, cab, root, srcdir, "LAUNCHERDIR", ".") + + # msidbComponentAttributes64bit = 256; this disables registry redirection + # to allow setting the SharedDLLs key in the 64-bit portion even for a + # 32-bit installer. + # XXX does this still allow to install the component on a 32-bit system? + launcher = os.path.join(srcdir, PCBUILD, "py.exe") + launcherdir.start_component("launcher", flags = 8+256, keyfile="py.exe") + launcherdir.add_file("%s/py.exe" % PCBUILD, + version=installer.FileVersion(launcher, 0), + language=installer.FileVersion(launcher, 1)) + launcherw = os.path.join(srcdir, PCBUILD, "pyw.exe") + launcherdir.start_component("launcherw", flags = 8+256, keyfile="pyw.exe") + launcherdir.add_file("%s/pyw.exe" % PCBUILD, + version=installer.FileVersion(launcherw, 0), + language=installer.FileVersion(launcherw, 1)) pydll = "python%s%s.dll" % (major, minor) pydllsrc = os.path.join(srcdir, PCBUILD, pydll) dlldir.start_component("DLLDIR", flags = 8, keyfile = pydll, uuid = pythondll_uuid) - installer = msilib.MakeInstaller() pyversion = installer.FileVersion(pydllsrc, 0) if not snapshot: # For releases, the Python DLL has the same version as the @@ -1211,11 +1235,11 @@ def add_registry(db): "text/plain", "REGISTRY.def"), #Verbs ("py.open", -1, pat % (testprefix, "", "open"), "", - r'"[TARGETDIR]python.exe" "%1" %*', "REGISTRY.def"), + r'"[LAUNCHERDIR]py.exe" "%1" %*', "REGISTRY.def"), ("pyw.open", -1, pat % (testprefix, "NoCon", "open"), "", - r'"[TARGETDIR]pythonw.exe" "%1" %*', "REGISTRY.def"), + r'"[LAUNCHERDIR]pyw.exe" "%1" %*', "REGISTRY.def"), ("pyc.open", -1, pat % (testprefix, "Compiled", "open"), "", - r'"[TARGETDIR]python.exe" "%1" %*', "REGISTRY.def"), + r'"[LAUNCHERDIR]py.exe" "%1" %*', "REGISTRY.def"), ] + tcl_verbs + [ #Icons ("py.icon", -1, pat2 % (testprefix, ""), "", -- cgit v0.12 From 91a3468f459ab429992bf4409a8794a758a0314f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 21 Jun 2012 17:36:15 +0200 Subject: Fix off-by-one error. --- PC/launcher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/launcher.c b/PC/launcher.c index 5792d1b..516d235 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -63,7 +63,7 @@ static wchar_t * get_env(wchar_t * key) static wchar_t buf[256]; DWORD result = GetEnvironmentVariableW(key, buf, 256); - if (result > 256) { + if (result > 255) { /* Large environment variable. Accept some leakage */ wchar_t *buf2 = (wchar_t*)malloc(sizeof(wchar_t) * (result+1)); GetEnvironmentVariableW(key, buf2, result); -- cgit v0.12 From af21ebb4249ab09feaa03560cebc85226438b8c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 21 Jun 2012 18:15:54 +0200 Subject: Fix UNICODE glitch. --- PC/launcher.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PC/launcher.c b/PC/launcher.c index 516d235..60222c4 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -230,8 +230,8 @@ locate_pythons_for_key(HKEY root, REGSAM flags) continue; } data_size = sizeof(ip->executable) - 1; - status = RegQueryValueEx(ip_key, NULL, NULL, &type, - (LPBYTE) ip->executable, &data_size); + status = RegQueryValueExW(ip_key, NULL, NULL, &type, + (LPBYTE)ip->executable, &data_size); RegCloseKey(ip_key); if (status != ERROR_SUCCESS) { winerror(status, message, MSGSIZE); -- cgit v0.12 From 8559b3cecf1ecc142ef82c50308672b06b19b931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 21 Jun 2012 18:24:32 +0200 Subject: Build and bundle the 32-bit launcher in all configurations. --- PCbuild/pcbuild.sln | 16 ++++++++-------- Tools/msi/msi.py | 5 +++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index ed7c444..17bfe96 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -583,22 +583,22 @@ Global {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|Win32 {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Debug|Win32.ActiveCfg = Debug|Win32 {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Debug|Win32.Build.0 = Debug|Win32 {023B3CDA-59C8-45FD-95DC-F8973322ED34}.Debug|x64.ActiveCfg = Debug|Win32 diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py index 1e9e2e8..889649a 100644 --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -973,12 +973,13 @@ def add_files(db): # to allow setting the SharedDLLs key in the 64-bit portion even for a # 32-bit installer. # XXX does this still allow to install the component on a 32-bit system? - launcher = os.path.join(srcdir, PCBUILD, "py.exe") + # Pick up 32-bit binary always + launcher = os.path.join(srcdir, "PCBuild", "py.exe") launcherdir.start_component("launcher", flags = 8+256, keyfile="py.exe") launcherdir.add_file("%s/py.exe" % PCBUILD, version=installer.FileVersion(launcher, 0), language=installer.FileVersion(launcher, 1)) - launcherw = os.path.join(srcdir, PCBUILD, "pyw.exe") + launcherw = os.path.join(srcdir, "PCBuild", "pyw.exe") launcherdir.start_component("launcherw", flags = 8+256, keyfile="pyw.exe") launcherdir.add_file("%s/pyw.exe" % PCBUILD, version=installer.FileVersion(launcherw, 0), -- cgit v0.12 From 6a8ca3edfd84b5923a667c61c20ffac3c6c71b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 21 Jun 2012 19:29:37 +0200 Subject: Remove the original license, as this was contributed under Vinay Sajip's agreement. --- PC/associator.c | 25 ++----------------------- PC/launcher.c | 25 ++----------------------- 2 files changed, 4 insertions(+), 46 deletions(-) diff --git a/PC/associator.c b/PC/associator.c index 21dc3ff..317e0c8 100644 --- a/PC/associator.c +++ b/PC/associator.c @@ -1,27 +1,6 @@ /* - * Copyright (C) 2011-2012 Vinay Sajip. All rights reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Copyright (C) 2011-2012 Vinay Sajip. + * Licensed to PSF under a contributor agreement. */ #include #include diff --git a/PC/launcher.c b/PC/launcher.c index 60222c4..dfad44a 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -1,27 +1,6 @@ /* - * Copyright (C) 2011-2012 Vinay Sajip. All rights reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Copyright (C) 2011-2012 Vinay Sajip. + * Licensed to PSF under a contributor agreement. * * Based on the work of: * -- cgit v0.12 From 6b2cf01744b06717f3082c97db235b66e9c7d1ba Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Thu, 21 Jun 2012 16:35:12 -0500 Subject: Remove associator project - it's not needed --- PC/associator.c | 731 ------------------ PC/associator.h | 1480 ------------------------------------ PC/associator.rc | 97 --- PCbuild/associator.vcxproj | 84 -- PCbuild/associator.vcxproj.filters | 32 - PCbuild/pcbuild.sln | 2 - 6 files changed, 2426 deletions(-) delete mode 100644 PC/associator.c delete mode 100644 PC/associator.h delete mode 100644 PC/associator.rc delete mode 100644 PCbuild/associator.vcxproj delete mode 100644 PCbuild/associator.vcxproj.filters diff --git a/PC/associator.c b/PC/associator.c deleted file mode 100644 index 21dc3ff..0000000 --- a/PC/associator.c +++ /dev/null @@ -1,731 +0,0 @@ -/* - * Copyright (C) 2011-2012 Vinay Sajip. All rights reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include "associator.h" - -#define PYTHON_EXECUTABLE L"python.exe" - -#define MSGSIZE 1024 -#define MAX_VERSION_SIZE 4 - -typedef struct { - wchar_t version[MAX_VERSION_SIZE]; /* m.n */ - int bits; /* 32 or 64 */ - wchar_t executable[MAX_PATH]; -} INSTALLED_PYTHON; - -/* - * To avoid messing about with heap allocations, just assume we can allocate - * statically and never have to deal with more versions than this. - */ -#define MAX_INSTALLED_PYTHONS 100 - -static INSTALLED_PYTHON installed_pythons[MAX_INSTALLED_PYTHONS]; - -static size_t num_installed_pythons = 0; - -/* to hold SOFTWARE\Python\PythonCore\X.Y\InstallPath */ -#define IP_BASE_SIZE 40 -#define IP_SIZE (IP_BASE_SIZE + MAX_VERSION_SIZE) -#define CORE_PATH L"SOFTWARE\\Python\\PythonCore" - -static wchar_t * location_checks[] = { - L"\\", -/* - L"\\PCBuild\\", - L"\\PCBuild\\amd64\\", - */ - NULL -}; - -static wchar_t * -skip_whitespace(wchar_t * p) -{ - while (*p && isspace(*p)) - ++p; - return p; -} - -/* - * This function is here to minimise Visual Studio - * warnings about security implications of getenv, and to - * treat blank values as if they are absent. - */ -static wchar_t * get_env(wchar_t * key) -{ - wchar_t * result = _wgetenv(key); - - if (result) { - result = skip_whitespace(result); - if (*result == L'\0') - result = NULL; - } - return result; -} - -static FILE * log_fp = NULL; - -static void -debug(wchar_t * format, ...) -{ - va_list va; - - if (log_fp != NULL) { - va_start(va, format); - vfwprintf_s(log_fp, format, va); - } -} - -static void winerror(int rc, wchar_t * message, int size) -{ - FormatMessageW( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - message, size, NULL); -} - -static INSTALLED_PYTHON * -find_existing_python(wchar_t * path) -{ - INSTALLED_PYTHON * result = NULL; - size_t i; - INSTALLED_PYTHON * ip; - - for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++, ip++) { - if (_wcsicmp(path, ip->executable) == 0) { - result = ip; - break; - } - } - return result; -} - -static void -locate_pythons_for_key(HKEY root, REGSAM flags) -{ - HKEY core_root, ip_key; - LSTATUS status = RegOpenKeyExW(root, CORE_PATH, 0, flags, &core_root); - wchar_t message[MSGSIZE]; - DWORD i; - size_t n; - BOOL ok; - DWORD type, data_size, attrs; - INSTALLED_PYTHON * ip, * pip; - wchar_t ip_path[IP_SIZE]; - wchar_t * check; - wchar_t ** checkp; - wchar_t *key_name = (root == HKEY_LOCAL_MACHINE) ? L"HKLM" : L"HKCU"; - - if (status != ERROR_SUCCESS) - debug(L"locate_pythons_for_key: unable to open PythonCore key in %s\n", - key_name); - else { - ip = &installed_pythons[num_installed_pythons]; - for (i = 0; num_installed_pythons < MAX_INSTALLED_PYTHONS; i++) { - status = RegEnumKeyW(core_root, i, ip->version, MAX_VERSION_SIZE); - if (status != ERROR_SUCCESS) { - if (status != ERROR_NO_MORE_ITEMS) { - /* unexpected error */ - winerror(status, message, MSGSIZE); - debug(L"Can't enumerate registry key for version %s: %s\n", - ip->version, message); - } - break; - } - else { - _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE, - L"%s\\%s\\InstallPath", CORE_PATH, ip->version); - status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key); - if (status != ERROR_SUCCESS) { - winerror(status, message, MSGSIZE); - // Note: 'message' already has a trailing \n - debug(L"%s\\%s: %s", key_name, ip_path, message); - continue; - } - data_size = sizeof(ip->executable) - 1; - status = RegQueryValueEx(ip_key, NULL, NULL, &type, - (LPBYTE) ip->executable, &data_size); - RegCloseKey(ip_key); - if (status != ERROR_SUCCESS) { - winerror(status, message, MSGSIZE); - debug(L"%s\\%s: %s\n", key_name, ip_path, message); - continue; - } - if (type == REG_SZ) { - data_size = data_size / sizeof(wchar_t) - 1; /* for NUL */ - if (ip->executable[data_size - 1] == L'\\') - --data_size; /* reg value ended in a backslash */ - /* ip->executable is data_size long */ - for (checkp = location_checks; *checkp; ++checkp) { - check = *checkp; - _snwprintf_s(&ip->executable[data_size], - MAX_PATH - data_size, - MAX_PATH - data_size, - L"%s%s", check, PYTHON_EXECUTABLE); - attrs = GetFileAttributesW(ip->executable); - if (attrs == INVALID_FILE_ATTRIBUTES) { - winerror(GetLastError(), message, MSGSIZE); - debug(L"locate_pythons_for_key: %s: %s", - ip->executable, message); - } - else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { - debug(L"locate_pythons_for_key: '%s' is a \ -directory\n", - ip->executable, attrs); - } - else if (find_existing_python(ip->executable)) { - debug(L"locate_pythons_for_key: %s: already \ -found: %s\n", ip->executable); - } - else { - /* check the executable type. */ - ok = GetBinaryTypeW(ip->executable, &attrs); - if (!ok) { - debug(L"Failure getting binary type: %s\n", - ip->executable); - } - else { - if (attrs == SCS_64BIT_BINARY) - ip->bits = 64; - else if (attrs == SCS_32BIT_BINARY) - ip->bits = 32; - else - ip->bits = 0; - if (ip->bits == 0) { - debug(L"locate_pythons_for_key: %s: \ -invalid binary type: %X\n", - ip->executable, attrs); - } - else { - if (wcschr(ip->executable, L' ') != NULL) { - /* has spaces, so quote */ - n = wcslen(ip->executable); - memmove(&ip->executable[1], - ip->executable, n * sizeof(wchar_t)); - ip->executable[0] = L'\"'; - ip->executable[n + 1] = L'\"'; - ip->executable[n + 2] = L'\0'; - } - debug(L"locate_pythons_for_key: %s \ -is a %dbit executable\n", - ip->executable, ip->bits); - ++num_installed_pythons; - pip = ip++; - if (num_installed_pythons >= - MAX_INSTALLED_PYTHONS) - break; - /* Copy over the attributes for the next */ - *ip = *pip; - } - } - } - } - } - } - } - RegCloseKey(core_root); - } -} - -static int -compare_pythons(const void * p1, const void * p2) -{ - INSTALLED_PYTHON * ip1 = (INSTALLED_PYTHON *) p1; - INSTALLED_PYTHON * ip2 = (INSTALLED_PYTHON *) p2; - /* note reverse sorting on version */ - int result = wcscmp(ip2->version, ip1->version); - - if (result == 0) - result = ip2->bits - ip1->bits; /* 64 before 32 */ - return result; -} - -static void -locate_all_pythons() -{ -#if defined(_M_X64) - // If we are a 64bit process, first hit the 32bit keys. - debug(L"locating Pythons in 32bit registry\n"); - locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_32KEY); - locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_32KEY); -#else - // If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. - BOOL f64 = FALSE; - if (IsWow64Process(GetCurrentProcess(), &f64) && f64) { - debug(L"locating Pythons in 64bit registry\n"); - locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_64KEY); - locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_64KEY); - } -#endif - // now hit the "native" key for this process bittedness. - debug(L"locating Pythons in native registry\n"); - locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ); - locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ); - qsort(installed_pythons, num_installed_pythons, sizeof(INSTALLED_PYTHON), - compare_pythons); -} - -typedef struct { - wchar_t * path; - wchar_t * key; - wchar_t * value; -} REGISTRY_ENTRY; - -static REGISTRY_ENTRY registry_entries[] = { - { L".py", NULL, L"Python.File" }, - { L".pyc", NULL, L"Python.CompiledFile" }, - { L".pyo", NULL, L"Python.CompiledFile" }, - { L".pyw", NULL, L"Python.NoConFile" }, - - { L"Python.CompiledFile", NULL, L"Compiled Python File" }, - { L"Python.CompiledFile\\DefaultIcon", NULL, L"pyc.ico" }, - { L"Python.CompiledFile\\shell\\open", NULL, L"Open" }, - { L"Python.CompiledFile\\shell\\open\\command", NULL, L"python.exe" }, - - { L"Python.File", NULL, L"Python File" }, - { L"Python.File\\DefaultIcon", NULL, L"py.ico" }, - { L"Python.File\\shell\\open", NULL, L"Open" }, - { L"Python.File\\shell\\open\\command", NULL, L"python.exe" }, - - { L"Python.NoConFile", NULL, L"Python File (no console)" }, - { L"Python.NoConFile\\DefaultIcon", NULL, L"py.ico" }, - { L"Python.NoConFile\\shell\\open", NULL, L"Open" }, - { L"Python.NoConFile\\shell\\open\\command", NULL, L"pythonw.exe" }, - - { NULL } -}; - -static BOOL -do_association(INSTALLED_PYTHON * ip) -{ - LONG rc; - BOOL result = TRUE; - REGISTRY_ENTRY * rp = registry_entries; - wchar_t value[MAX_PATH]; - wchar_t root[MAX_PATH]; - wchar_t message[MSGSIZE]; - wchar_t * pvalue; - HKEY hKey; - DWORD len; - - wcsncpy_s(root, MAX_PATH, ip->executable, _TRUNCATE); - pvalue = wcsrchr(root, '\\'); - if (pvalue) - *pvalue = L'\0'; - - for (; rp->path; ++rp) { - if (wcsstr(rp->path, L"DefaultIcon")) { - pvalue = value; - _snwprintf_s(value, MAX_PATH, _TRUNCATE, - L"%s\\DLLs\\%s", root, rp->value); - } - else if (wcsstr(rp->path, L"open\\command")) { - pvalue = value; - _snwprintf_s(value, MAX_PATH, _TRUNCATE, - L"%s\\%s \"%%1\" %%*", root, rp->value); - } - else { - pvalue = rp->value; - } - /* use rp->path, rp->key, pvalue */ - /* NOTE: size is in bytes */ - len = (DWORD) ((1 + wcslen(pvalue)) * sizeof(wchar_t)); - rc = RegOpenKeyEx(HKEY_CLASSES_ROOT, rp->path, 0, KEY_SET_VALUE, &hKey); - if (rc == ERROR_SUCCESS) { - rc = RegSetValueExW(hKey, rp->key, 0, REG_SZ, (LPBYTE) pvalue, len); - RegCloseKey(hKey); - } - if (rc != ERROR_SUCCESS) { - winerror(rc, message, MSGSIZE); - MessageBoxW(NULL, message, L"Unable to set file associations", MB_OK | MB_ICONSTOP); - result = FALSE; - break; - } - } - return result; -} - -static BOOL -associations_exist() -{ - BOOL result = FALSE; - REGISTRY_ENTRY * rp = registry_entries; - wchar_t buffer[MSGSIZE]; - LONG csize = MSGSIZE * sizeof(wchar_t); - LONG rc; - - /* Currently, if any is found, we assume they're all there. */ - - for (; rp->path; ++rp) { - LONG size = csize; - rc = RegQueryValueW(HKEY_CLASSES_ROOT, rp->path, buffer, &size); - if (rc == ERROR_SUCCESS) { - result = TRUE; - break; - } - } - return result; -} - -/* --------------------------------------------------------------------*/ - -static BOOL CALLBACK -find_by_title(HWND hwnd, LPARAM lParam) -{ - wchar_t buffer[MSGSIZE]; - BOOL not_found = TRUE; - - wchar_t * p = (wchar_t *) GetWindowTextW(hwnd, buffer, MSGSIZE); - if (wcsstr(buffer, L"Python Launcher") == buffer) { - not_found = FALSE; - *((HWND *) lParam) = hwnd; - } - return not_found; -} - -static HWND -find_installer_window() -{ - HWND result = NULL; - BOOL found = EnumWindows(find_by_title, (LPARAM) &result); - - return result; -} - -static void -centre_window_in_front(HWND hwnd) -{ - HWND hwndParent; - RECT rect, rectP; - int width, height; - int screenwidth, screenheight; - int x, y; - - //make the window relative to its parent - - screenwidth = GetSystemMetrics(SM_CXSCREEN); - screenheight = GetSystemMetrics(SM_CYSCREEN); - - hwndParent = GetParent(hwnd); - - GetWindowRect(hwnd, &rect); - if (hwndParent) { - GetWindowRect(hwndParent, &rectP); - } - else { - rectP.left = rectP.top = 0; - rectP.right = screenwidth; - rectP.bottom = screenheight; - } - - width = rect.right - rect.left; - height = rect.bottom - rect.top; - - x = ((rectP.right-rectP.left) - width) / 2 + rectP.left; - y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top; - - - //make sure that the dialog box never moves outside of - //the screen - - if (x < 0) - x = 0; - - if (y < 0) - y = 0; - - if (x + width > screenwidth) - x = screenwidth - width; - if (y + height > screenheight) - y = screenheight - height; - - SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, SWP_SHOWWINDOW); -} - -static void -init_list(HWND hList) -{ - LVCOLUMNW column; - LVITEMW item; - int colno = 0; - int width = 0; - int row; - size_t i; - INSTALLED_PYTHON * ip; - RECT r; - LPARAM style; - - GetClientRect(hList, &r); - - style = SendMessage(hList, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0); - SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, - 0, style | LVS_EX_FULLROWSELECT); - - /* First set up the columns */ - memset(&column, 0, sizeof(column)); - column.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; - column.pszText = L"Version"; - column.cx = 60; - width += column.cx; - SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column); -#if defined(_M_X64) - column.pszText = L"Bits"; - column.cx = 40; - column.iSubItem = colno; - SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column); - width += column.cx; -#endif - column.pszText = L"Path"; - column.cx = r.right - r.top - width; - column.iSubItem = colno; - SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column); - - /* Then insert the rows */ - memset(&item, 0, sizeof(item)); - item.mask = LVIF_TEXT; - for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++,ip++) { - item.iItem = (int) i; - item.iSubItem = 0; - item.pszText = ip->version; - colno = 0; - row = (int) SendMessage(hList, LVM_INSERTITEM, 0, (LPARAM) &item); -#if defined(_M_X64) - item.iSubItem = ++colno; - item.pszText = (ip->bits == 64) ? L"64": L"32"; - SendMessage(hList, LVM_SETITEM, row, (LPARAM) &item); -#endif - item.iSubItem = ++colno; - item.pszText = ip->executable; - SendMessage(hList, LVM_SETITEM, row, (LPARAM) &item); - } -} - -/* ----------------------------------------------------------------*/ - -typedef int (__stdcall *MSGBOXWAPI)(IN HWND hWnd, - IN LPCWSTR lpText, IN LPCWSTR lpCaption, - IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds); - -int MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText, - IN LPCWSTR lpCaption, IN UINT uType, - IN WORD wLanguageId, IN DWORD dwMilliseconds); - -#define MB_TIMEDOUT 32000 - -int MessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText, - LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds) -{ - static MSGBOXWAPI MsgBoxTOW = NULL; - - if (!MsgBoxTOW) { - HMODULE hUser32 = GetModuleHandleW(L"user32.dll"); - if (hUser32) - MsgBoxTOW = (MSGBOXWAPI)GetProcAddress(hUser32, - "MessageBoxTimeoutW"); - else { - //stuff happened, add code to handle it here - //(possibly just call MessageBox()) - return 0; - } - } - - if (MsgBoxTOW) - return MsgBoxTOW(hWnd, lpText, lpCaption, uType, wLanguageId, - dwMilliseconds); - - return 0; -} -/* ----------------------------------------------------------------*/ - -static INT_PTR CALLBACK -DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND hList; - HWND hChild; - static int selected_index = -1; - WORD low = LOWORD(wParam); - wchar_t confirmation[MSGSIZE]; - BOOL result = FALSE; - - debug(L"DialogProc entry: 0x%02X\n", message); - switch (message) { - case WM_INITDIALOG: - hList = GetDlgItem(hDlg, IDC_LIST1); - init_list(hList); - SetFocus(hList); - result = TRUE; - break; - case WM_COMMAND: - if((low == IDOK) || (low == IDCANCEL)) { - HMODULE hUser32 = LoadLibraryW(L"user32.dll"); - - if (low == IDCANCEL) - wcsncpy_s(confirmation, MSGSIZE, L"No association was \ -performed.", _TRUNCATE); - else { - if (selected_index < 0) { - /* should never happen */ - wcsncpy_s(confirmation, MSGSIZE, L"The Python version to \ -associate with couldn't be determined.", _TRUNCATE); - } - else { - INSTALLED_PYTHON * ip = &installed_pythons[selected_index]; - - /* Do the association and set the message. */ - do_association(ip); - _snwprintf_s(confirmation, MSGSIZE, _TRUNCATE, - L"Associated Python files with the Python %s \ -found at '%s'", ip->version, ip->executable); - } - } - - if (hUser32) { - MessageBoxTimeoutW(hDlg, - confirmation, - L"Association Status", - MB_OK | MB_SETFOREGROUND | - MB_ICONINFORMATION, - 0, 2000); - FreeLibrary(hUser32); - } - PostQuitMessage(0); - EndDialog(hDlg, 0); - result = TRUE; - } - break; - case WM_NOTIFY: - if (low == IDC_LIST1) { - NMLISTVIEW * p = (NMLISTVIEW *) lParam; - - if ((p->hdr.code == LVN_ITEMCHANGED) && - (p->uNewState & LVIS_SELECTED)) { - hChild = GetDlgItem(hDlg, IDOK); - selected_index = p->iItem; - EnableWindow(hChild, selected_index >= 0); - } - result = TRUE; - } - break; - case WM_DESTROY: - PostQuitMessage(0); - result = TRUE; - break; - case WM_CLOSE: - DestroyWindow(hDlg); - result = TRUE; - break; - } - debug(L"DialogProc exit: %d\n", result); - return result; -} - -int WINAPI wWinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPWSTR lpCmdLine, int nShow) -{ - MSG msg; - HWND hDialog = 0; - HICON hIcon; - HWND hParent; - int status; - DWORD dw; - INITCOMMONCONTROLSEX icx; - wchar_t * wp; - - wp = get_env(L"PYASSOC_DEBUG"); - if ((wp != NULL) && (*wp != L'\0')) { - fopen_s(&log_fp, "c:\\temp\\associator.log", "w"); - } - - if (!lpCmdLine) { - debug(L"No command line specified.\n"); - return 0; - } - if (!wcsstr(lpCmdLine, L"nocheck") && - associations_exist()) /* Could have been restored by uninstall. */ - return 0; - - locate_all_pythons(); - - if (num_installed_pythons == 0) - return 0; - - debug(L"%d pythons found.\n", num_installed_pythons); - - /* - * OK, now there's something to do. - * - * We need to find the installer window to be the parent of - * our dialog, otherwise our dialog will be behind it. - * - * First, initialize common controls. If you don't - on - * some machines it works fine, on others the dialog never - * appears! - */ - - icx.dwSize = sizeof(icx); - icx.dwICC = ICC_LISTVIEW_CLASSES; - InitCommonControlsEx(&icx); - - hParent = find_installer_window(); - debug(L"installer window: %X\n", hParent); - hDialog = CreateDialogW(hInstance, MAKEINTRESOURCE(DLG_MAIN), hParent, - DialogProc); - dw = GetLastError(); - debug(L"dialog created: %X: error: %X\n", hDialog, dw); - - if (!hDialog) - { - wchar_t buf [100]; - _snwprintf_s(buf, 100, _TRUNCATE, L"Error 0x%x", GetLastError()); - MessageBoxW(0, buf, L"CreateDialog", MB_ICONEXCLAMATION | MB_OK); - return 1; - } - - centre_window_in_front(hDialog); - hIcon = LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(DLG_ICON)); - if( hIcon ) - { - SendMessage(hDialog, WM_SETICON, ICON_BIG, (LPARAM) hIcon); - SendMessage(hDialog, WM_SETICON, ICON_SMALL, (LPARAM) hIcon); - DestroyIcon(hIcon); - } - - while ((status = GetMessage (& msg, 0, 0, 0)) != 0) - { - if (status == -1) - return -1; - if (!IsDialogMessage(hDialog, & msg)) - { - TranslateMessage( & msg ); - DispatchMessage( & msg ); - } - } - - return (int) msg.wParam; -} diff --git a/PC/associator.h b/PC/associator.h deleted file mode 100644 index a2c1cde..0000000 --- a/PC/associator.h +++ /dev/null @@ -1,1480 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by main.rc -// -#define SW_HIDE 0 -#define HIDE_WINDOW 0 -#define WM_NULL 0x0000 -#define WA_INACTIVE 0 -#define HTNOWHERE 0 -#define SMTO_NORMAL 0x0000 -#define ICON_SMALL 0 -#define SIZE_RESTORED 0 -#define BN_CLICKED 0 -#define BST_UNCHECKED 0x0000 -#define HDS_HORZ 0x0000 -#define TBSTYLE_BUTTON 0x0000 -#define TBS_HORZ 0x0000 -#define TBS_BOTTOM 0x0000 -#define TBS_RIGHT 0x0000 -#define LVS_ICON 0x0000 -#define LVS_ALIGNTOP 0x0000 -#define TCS_TABS 0x0000 -#define TCS_SINGLELINE 0x0000 -#define TCS_RIGHTJUSTIFY 0x0000 -#define DTS_SHORTDATEFORMAT 0x0000 -#define PGS_VERT 0x00000000 -#define LANG_NEUTRAL 0x00 -#define SUBLANG_NEUTRAL 0x00 -#define SORT_DEFAULT 0x0 -#define SORT_JAPANESE_XJIS 0x0 -#define SORT_CHINESE_BIG5 0x0 -#define SORT_CHINESE_PRCP 0x0 -#define SORT_KOREAN_KSC 0x0 -#define SORT_HUNGARIAN_DEFAULT 0x0 -#define SORT_GEORGIAN_TRADITIONAL 0x0 -#define _USE_DECLSPECS_FOR_SAL 0 -#define SW_SHOWNORMAL 1 -#define SW_NORMAL 1 -#define SHOW_OPENWINDOW 1 -#define SW_PARENTCLOSING 1 -#define VK_LBUTTON 0x01 -#define WM_CREATE 0x0001 -#define WA_ACTIVE 1 -#define PWR_OK 1 -#define PWR_SUSPENDREQUEST 1 -#define NFR_ANSI 1 -#define UIS_SET 1 -#define UISF_HIDEFOCUS 0x1 -#define XBUTTON1 0x0001 -#define WMSZ_LEFT 1 -#define HTCLIENT 1 -#define SMTO_BLOCK 0x0001 -#define MA_ACTIVATE 1 -#define ICON_BIG 1 -#define SIZE_MINIMIZED 1 -#define MK_LBUTTON 0x0001 -#define TME_HOVER 0x00000001 -#define CS_VREDRAW 0x0001 -#define CF_TEXT 1 -#define SCF_ISSECURE 0x00000001 -#define IDOK 1 -#define BN_PAINT 1 -#define BST_CHECKED 0x0001 -#define TBSTYLE_SEP 0x0001 -#define TTS_ALWAYSTIP 0x01 -#define TBS_AUTOTICKS 0x0001 -#define UDS_WRAP 0x0001 -#define PBS_SMOOTH 0x01 -#define LWS_TRANSPARENT 0x0001 -#define LVS_REPORT 0x0001 -#define TVS_HASBUTTONS 0x0001 -#define TCS_SCROLLOPPOSITE 0x0001 -#define ACS_CENTER 0x0001 -#define MCS_DAYSTATE 0x0001 -#define DTS_UPDOWN 0x0001 -#define PGS_HORZ 0x00000001 -#define NFS_EDIT 0x0001 -#define BCSIF_GLYPH 0x0001 -#define BCSS_NOSPLIT 0x0001 -#define LANG_ARABIC 0x01 -#define SUBLANG_DEFAULT 0x01 -#define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01 -#define SUBLANG_ALBANIAN_ALBANIA 0x01 -#define SUBLANG_ALSATIAN_FRANCE 0x01 -#define SUBLANG_AMHARIC_ETHIOPIA 0x01 -#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01 -#define SUBLANG_ARMENIAN_ARMENIA 0x01 -#define SUBLANG_ASSAMESE_INDIA 0x01 -#define SUBLANG_AZERI_LATIN 0x01 -#define SUBLANG_BASHKIR_RUSSIA 0x01 -#define SUBLANG_BASQUE_BASQUE 0x01 -#define SUBLANG_BELARUSIAN_BELARUS 0x01 -#define SUBLANG_BENGALI_INDIA 0x01 -#define SUBLANG_BRETON_FRANCE 0x01 -#define SUBLANG_BULGARIAN_BULGARIA 0x01 -#define SUBLANG_CATALAN_CATALAN 0x01 -#define SUBLANG_CHINESE_TRADITIONAL 0x01 -#define SUBLANG_CORSICAN_FRANCE 0x01 -#define SUBLANG_CZECH_CZECH_REPUBLIC 0x01 -#define SUBLANG_CROATIAN_CROATIA 0x01 -#define SUBLANG_DANISH_DENMARK 0x01 -#define SUBLANG_DARI_AFGHANISTAN 0x01 -#define SUBLANG_DIVEHI_MALDIVES 0x01 -#define SUBLANG_DUTCH 0x01 -#define SUBLANG_ENGLISH_US 0x01 -#define SUBLANG_ESTONIAN_ESTONIA 0x01 -#define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01 -#define SUBLANG_FILIPINO_PHILIPPINES 0x01 -#define SUBLANG_FINNISH_FINLAND 0x01 -#define SUBLANG_FRENCH 0x01 -#define SUBLANG_FRISIAN_NETHERLANDS 0x01 -#define SUBLANG_GALICIAN_GALICIAN 0x01 -#define SUBLANG_GEORGIAN_GEORGIA 0x01 -#define SUBLANG_GERMAN 0x01 -#define SUBLANG_GREEK_GREECE 0x01 -#define SUBLANG_GREENLANDIC_GREENLAND 0x01 -#define SUBLANG_GUJARATI_INDIA 0x01 -#define SUBLANG_HAUSA_NIGERIA_LATIN 0x01 -#define SUBLANG_HEBREW_ISRAEL 0x01 -#define SUBLANG_HINDI_INDIA 0x01 -#define SUBLANG_HUNGARIAN_HUNGARY 0x01 -#define SUBLANG_ICELANDIC_ICELAND 0x01 -#define SUBLANG_IGBO_NIGERIA 0x01 -#define SUBLANG_INDONESIAN_INDONESIA 0x01 -#define SUBLANG_INUKTITUT_CANADA 0x01 -#define SUBLANG_ITALIAN 0x01 -#define SUBLANG_JAPANESE_JAPAN 0x01 -#define SUBLANG_KANNADA_INDIA 0x01 -#define SUBLANG_KAZAK_KAZAKHSTAN 0x01 -#define SUBLANG_KHMER_CAMBODIA 0x01 -#define SUBLANG_KICHE_GUATEMALA 0x01 -#define SUBLANG_KINYARWANDA_RWANDA 0x01 -#define SUBLANG_KONKANI_INDIA 0x01 -#define SUBLANG_KOREAN 0x01 -#define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01 -#define SUBLANG_LAO_LAO 0x01 -#define SUBLANG_LATVIAN_LATVIA 0x01 -#define SUBLANG_LITHUANIAN 0x01 -#define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01 -#define SUBLANG_MACEDONIAN_MACEDONIA 0x01 -#define SUBLANG_MALAY_MALAYSIA 0x01 -#define SUBLANG_MALAYALAM_INDIA 0x01 -#define SUBLANG_MALTESE_MALTA 0x01 -#define SUBLANG_MAORI_NEW_ZEALAND 0x01 -#define SUBLANG_MAPUDUNGUN_CHILE 0x01 -#define SUBLANG_MARATHI_INDIA 0x01 -#define SUBLANG_MOHAWK_MOHAWK 0x01 -#define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01 -#define SUBLANG_NEPALI_NEPAL 0x01 -#define SUBLANG_NORWEGIAN_BOKMAL 0x01 -#define SUBLANG_OCCITAN_FRANCE 0x01 -#define SUBLANG_ORIYA_INDIA 0x01 -#define SUBLANG_PASHTO_AFGHANISTAN 0x01 -#define SUBLANG_PERSIAN_IRAN 0x01 -#define SUBLANG_POLISH_POLAND 0x01 -#define SUBLANG_PORTUGUESE_BRAZILIAN 0x01 -#define SUBLANG_PUNJABI_INDIA 0x01 -#define SUBLANG_QUECHUA_BOLIVIA 0x01 -#define SUBLANG_ROMANIAN_ROMANIA 0x01 -#define SUBLANG_ROMANSH_SWITZERLAND 0x01 -#define SUBLANG_RUSSIAN_RUSSIA 0x01 -#define SUBLANG_SAMI_NORTHERN_NORWAY 0x01 -#define SUBLANG_SANSKRIT_INDIA 0x01 -#define SUBLANG_SERBIAN_CROATIA 0x01 -#define SUBLANG_SINDHI_INDIA 0x01 -#define SUBLANG_SINHALESE_SRI_LANKA 0x01 -#define SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA 0x01 -#define SUBLANG_SLOVAK_SLOVAKIA 0x01 -#define SUBLANG_SLOVENIAN_SLOVENIA 0x01 -#define SUBLANG_SPANISH 0x01 -#define SUBLANG_SWAHILI_KENYA 0x01 -#define SUBLANG_SWEDISH 0x01 -#define SUBLANG_SYRIAC_SYRIA 0x01 -#define SUBLANG_TAJIK_TAJIKISTAN 0x01 -#define SUBLANG_TAMIL_INDIA 0x01 -#define SUBLANG_TATAR_RUSSIA 0x01 -#define SUBLANG_TELUGU_INDIA 0x01 -#define SUBLANG_THAI_THAILAND 0x01 -#define SUBLANG_TIBETAN_PRC 0x01 -#define SUBLANG_TSWANA_SOUTH_AFRICA 0x01 -#define SUBLANG_TURKISH_TURKEY 0x01 -#define SUBLANG_TURKMEN_TURKMENISTAN 0x01 -#define SUBLANG_UIGHUR_PRC 0x01 -#define SUBLANG_UKRAINIAN_UKRAINE 0x01 -#define SUBLANG_UPPER_SORBIAN_GERMANY 0x01 -#define SUBLANG_URDU_PAKISTAN 0x01 -#define SUBLANG_UZBEK_LATIN 0x01 -#define SUBLANG_VIETNAMESE_VIETNAM 0x01 -#define SUBLANG_WELSH_UNITED_KINGDOM 0x01 -#define SUBLANG_WOLOF_SENEGAL 0x01 -#define SUBLANG_XHOSA_SOUTH_AFRICA 0x01 -#define SUBLANG_YAKUT_RUSSIA 0x01 -#define SUBLANG_YI_PRC 0x01 -#define SUBLANG_YORUBA_NIGERIA 0x01 -#define SUBLANG_ZULU_SOUTH_AFRICA 0x01 -#define SORT_INVARIANT_MATH 0x1 -#define SORT_JAPANESE_UNICODE 0x1 -#define SORT_CHINESE_UNICODE 0x1 -#define SORT_KOREAN_UNICODE 0x1 -#define SORT_GERMAN_PHONE_BOOK 0x1 -#define SORT_HUNGARIAN_TECHNICAL 0x1 -#define SORT_GEORGIAN_MODERN 0x1 -#define VS_VERSION_INFO 1 -#define VFFF_ISSHAREDFILE 0x0001 -#define VFF_CURNEDEST 0x0001 -#define VIFF_FORCEINSTALL 0x0001 -#define SW_SHOWMINIMIZED 2 -#define SHOW_ICONWINDOW 2 -#define SW_OTHERZOOM 2 -#define VK_RBUTTON 0x02 -#define WM_DESTROY 0x0002 -#define WA_CLICKACTIVE 2 -#define PWR_SUSPENDRESUME 2 -#define NFR_UNICODE 2 -#define UIS_CLEAR 2 -#define UISF_HIDEACCEL 0x2 -#define XBUTTON2 0x0002 -#define WMSZ_RIGHT 2 -#define HTCAPTION 2 -#define SMTO_ABORTIFHUNG 0x0002 -#define MA_ACTIVATEANDEAT 2 -#define ICON_SMALL2 2 -#define SIZE_MAXIMIZED 2 -#define MK_RBUTTON 0x0002 -#define TME_LEAVE 0x00000002 -#define CS_HREDRAW 0x0002 -#define CF_BITMAP 2 -#define IDCANCEL 2 -#define BN_HILITE 2 -#define BST_INDETERMINATE 0x0002 -#define HDS_BUTTONS 0x0002 -#define TBSTYLE_CHECK 0x0002 -#define TTS_NOPREFIX 0x02 -#define TBS_VERT 0x0002 -#define UDS_SETBUDDYINT 0x0002 -#define LWS_IGNORERETURN 0x0002 -#define LVS_SMALLICON 0x0002 -#define TVS_HASLINES 0x0002 -#define TVS_EX_MULTISELECT 0x0002 -#define TCS_BOTTOM 0x0002 -#define TCS_RIGHT 0x0002 -#define ACS_TRANSPARENT 0x0002 -#define MCS_MULTISELECT 0x0002 -#define DTS_SHOWNONE 0x0002 -#define PGS_AUTOSCROLL 0x00000002 -#define NFS_STATIC 0x0002 -#define BCSIF_IMAGE 0x0002 -#define BCSS_STRETCH 0x0002 -#define LANG_BULGARIAN 0x02 -#define SUBLANG_SYS_DEFAULT 0x02 -#define SUBLANG_ARABIC_IRAQ 0x02 -#define SUBLANG_AZERI_CYRILLIC 0x02 -#define SUBLANG_BENGALI_BANGLADESH 0x02 -#define SUBLANG_CHINESE_SIMPLIFIED 0x02 -#define SUBLANG_DUTCH_BELGIAN 0x02 -#define SUBLANG_ENGLISH_UK 0x02 -#define SUBLANG_FRENCH_BELGIAN 0x02 -#define SUBLANG_GERMAN_SWISS 0x02 -#define SUBLANG_INUKTITUT_CANADA_LATIN 0x02 -#define SUBLANG_IRISH_IRELAND 0x02 -#define SUBLANG_ITALIAN_SWISS 0x02 -#define SUBLANG_KASHMIRI_SASIA 0x02 -#define SUBLANG_KASHMIRI_INDIA 0x02 -#define SUBLANG_LOWER_SORBIAN_GERMANY 0x02 -#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 -#define SUBLANG_MONGOLIAN_PRC 0x02 -#define SUBLANG_NEPALI_INDIA 0x02 -#define SUBLANG_NORWEGIAN_NYNORSK 0x02 -#define SUBLANG_PORTUGUESE 0x02 -#define SUBLANG_QUECHUA_ECUADOR 0x02 -#define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02 -#define SUBLANG_SERBIAN_LATIN 0x02 -#define SUBLANG_SINDHI_PAKISTAN 0x02 -#define SUBLANG_SINDHI_AFGHANISTAN 0x02 -#define SUBLANG_SPANISH_MEXICAN 0x02 -#define SUBLANG_SWEDISH_FINLAND 0x02 -#define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02 -#define SUBLANG_TIGRIGNA_ERITREA 0x02 -#define SUBLANG_URDU_INDIA 0x02 -#define SUBLANG_UZBEK_CYRILLIC 0x02 -#define SORT_CHINESE_PRC 0x2 -#define VFF_FILEINUSE 0x0002 -#define VIFF_DONTDELETEOLD 0x0002 -#define SW_SHOWMAXIMIZED 3 -#define SW_MAXIMIZE 3 -#define SHOW_FULLSCREEN 3 -#define SW_PARENTOPENING 3 -#define VK_CANCEL 0x03 -#define WM_MOVE 0x0003 -#define PWR_CRITICALRESUME 3 -#define NF_QUERY 3 -#define UIS_INITIALIZE 3 -#define WMSZ_TOP 3 -#define HTSYSMENU 3 -#define MA_NOACTIVATE 3 -#define SIZE_MAXSHOW 3 -#define CF_METAFILEPICT 3 -#define IDABORT 3 -#define BN_UNHILITE 3 -#define LVS_LIST 0x0003 -#define LVS_TYPEMASK 0x0003 -#define LANG_CATALAN 0x03 -#define SUBLANG_CUSTOM_DEFAULT 0x03 -#define SUBLANG_ARABIC_EGYPT 0x03 -#define SUBLANG_CHINESE_HONGKONG 0x03 -#define SUBLANG_ENGLISH_AUS 0x03 -#define SUBLANG_FRENCH_CANADIAN 0x03 -#define SUBLANG_GERMAN_AUSTRIAN 0x03 -#define SUBLANG_QUECHUA_PERU 0x03 -#define SUBLANG_SAMI_NORTHERN_FINLAND 0x03 -#define SUBLANG_SERBIAN_CYRILLIC 0x03 -#define SUBLANG_SPANISH_MODERN 0x03 -#define SORT_CHINESE_BOPOMOFO 0x3 -#define SW_SHOWNOACTIVATE 4 -#define SHOW_OPENNOACTIVATE 4 -#define SW_OTHERUNZOOM 4 -#define VK_MBUTTON 0x04 -#define NF_REQUERY 4 -#define UISF_ACTIVE 0x4 -#define WMSZ_TOPLEFT 4 -#define HTGROWBOX 4 -#define MA_NOACTIVATEANDEAT 4 -#define SIZE_MAXHIDE 4 -#define MK_SHIFT 0x0004 -#define CF_SYLK 4 -#define IDRETRY 4 -#define BN_DISABLE 4 -#define BST_PUSHED 0x0004 -#define HDS_HOTTRACK 0x0004 -#define TBSTYLE_GROUP 0x0004 -#define TBS_TOP 0x0004 -#define TBS_LEFT 0x0004 -#define UDS_ALIGNRIGHT 0x0004 -#define PBS_VERTICAL 0x04 -#define LWS_NOPREFIX 0x0004 -#define LVS_SINGLESEL 0x0004 -#define TVS_LINESATROOT 0x0004 -#define TVS_EX_DOUBLEBUFFER 0x0004 -#define TCS_MULTISELECT 0x0004 -#define ACS_AUTOPLAY 0x0004 -#define MCS_WEEKNUMBERS 0x0004 -#define DTS_LONGDATEFORMAT 0x0004 -#define PGS_DRAGNDROP 0x00000004 -#define NFS_LISTCOMBO 0x0004 -#define BCSIF_STYLE 0x0004 -#define BCSS_ALIGNLEFT 0x0004 -#define LANG_CHINESE 0x04 -#define LANG_CHINESE_SIMPLIFIED 0x04 -#define SUBLANG_CUSTOM_UNSPECIFIED 0x04 -#define SUBLANG_ARABIC_LIBYA 0x04 -#define SUBLANG_CHINESE_SINGAPORE 0x04 -#define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04 -#define SUBLANG_ENGLISH_CAN 0x04 -#define SUBLANG_FRENCH_SWISS 0x04 -#define SUBLANG_GERMAN_LUXEMBOURG 0x04 -#define SUBLANG_SAMI_LULE_NORWAY 0x04 -#define SUBLANG_SPANISH_GUATEMALA 0x04 -#define SORT_JAPANESE_RADICALSTROKE 0x4 -#define VFF_BUFFTOOSMALL 0x0004 -#define SW_SHOW 5 -#define VK_XBUTTON1 0x05 -#define WM_SIZE 0x0005 -#define WMSZ_TOPRIGHT 5 -#define HTMENU 5 -#define CF_DIF 5 -#define IDIGNORE 5 -#define BN_DOUBLECLICKED 5 -#define LANG_CZECH 0x05 -#define SUBLANG_UI_CUSTOM_DEFAULT 0x05 -#define SUBLANG_ARABIC_ALGERIA 0x05 -#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05 -#define SUBLANG_CHINESE_MACAU 0x05 -#define SUBLANG_ENGLISH_NZ 0x05 -#define SUBLANG_FRENCH_LUXEMBOURG 0x05 -#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05 -#define SUBLANG_SAMI_LULE_SWEDEN 0x05 -#define SUBLANG_SPANISH_COSTA_RICA 0x05 -#define SW_MINIMIZE 6 -#define VK_XBUTTON2 0x06 -#define WM_ACTIVATE 0x0006 -#define WMSZ_BOTTOM 6 -#define HTHSCROLL 6 -#define CF_TIFF 6 -#define IDYES 6 -#define BN_SETFOCUS 6 -#define LANG_DANISH 0x06 -#define SUBLANG_ARABIC_MOROCCO 0x06 -#define SUBLANG_ENGLISH_EIRE 0x06 -#define SUBLANG_FRENCH_MONACO 0x06 -#define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06 -#define SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN 0x06 -#define SUBLANG_SPANISH_PANAMA 0x06 -#define SW_SHOWMINNOACTIVE 7 -#define WM_SETFOCUS 0x0007 -#define WMSZ_BOTTOMLEFT 7 -#define HTVSCROLL 7 -#define CF_OEMTEXT 7 -#define IDNO 7 -#define BN_KILLFOCUS 7 -#define LANG_GERMAN 0x07 -#define SUBLANG_ARABIC_TUNISIA 0x07 -#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07 -#define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07 -#define SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x07 -#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07 -#define SW_SHOWNA 8 -#define VK_BACK 0x08 -#define WM_KILLFOCUS 0x0008 -#define WMSZ_BOTTOMRIGHT 8 -#define HTMINBUTTON 8 -#define SMTO_NOTIMEOUTIFNOTHUNG 0x0008 -#define MK_CONTROL 0x0008 -#define CS_DBLCLKS 0x0008 -#define CF_DIB 8 -#define IDCLOSE 8 -#define BST_FOCUS 0x0008 -#define HDS_HIDDEN 0x0008 -#define TBSTYLE_DROPDOWN 0x0008 -#define TBS_BOTH 0x0008 -#define UDS_ALIGNLEFT 0x0008 -#define PBS_MARQUEE 0x08 -#define LWS_USEVISUALSTYLE 0x0008 -#define LVS_SHOWSELALWAYS 0x0008 -#define TVS_EDITLABELS 0x0008 -#define TVS_EX_NOINDENTSTATE 0x0008 -#define TCS_FLATBUTTONS 0x0008 -#define ACS_TIMER 0x0008 -#define MCS_NOTODAYCIRCLE 0x0008 -#define NFS_BUTTON 0x0008 -#define BCSIF_SIZE 0x0008 -#define BCSS_IMAGE 0x0008 -#define LANG_GREEK 0x08 -#define SUBLANG_ARABIC_OMAN 0x08 -#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08 -#define SUBLANG_ENGLISH_JAMAICA 0x08 -#define SUBLANG_SAMI_SKOLT_FINLAND 0x08 -#define SUBLANG_SPANISH_VENEZUELA 0x08 -#define SW_RESTORE 9 -#define VK_TAB 0x09 -#define HTMAXBUTTON 9 -#define CF_PALETTE 9 -#define IDHELP 9 -#define DTS_TIMEFORMAT 0x0009 -#define LANG_ENGLISH 0x09 -#define SUBLANG_ARABIC_YEMEN 0x09 -#define SUBLANG_ENGLISH_CARIBBEAN 0x09 -#define SUBLANG_SAMI_INARI_FINLAND 0x09 -#define SUBLANG_SPANISH_COLOMBIA 0x09 -#define SW_SHOWDEFAULT 10 -#define WM_ENABLE 0x000A -#define HTLEFT 10 -#define CF_PENDATA 10 -#define IDTRYAGAIN 10 -#define HELP_CONTEXTMENU 0x000a -#define LANG_SPANISH 0x0a -#define SUBLANG_ARABIC_SYRIA 0x0a -#define SUBLANG_ENGLISH_BELIZE 0x0a -#define SUBLANG_SPANISH_PERU 0x0a -#define SW_FORCEMINIMIZE 11 -#define SW_MAX 11 -#define WM_SETREDRAW 0x000B -#define HTRIGHT 11 -#define CF_RIFF 11 -#define IDCONTINUE 11 -#define HELP_FINDER 0x000b -#define LANG_FINNISH 0x0b -#define SUBLANG_ARABIC_JORDAN 0x0b -#define SUBLANG_ENGLISH_TRINIDAD 0x0b -#define SUBLANG_SPANISH_ARGENTINA 0x0b -#define VK_CLEAR 0x0C -#define WM_SETTEXT 0x000C -#define HTTOP 12 -#define CF_WAVE 12 -#define HELP_WM_HELP 0x000c -#define DTS_SHORTDATECENTURYFORMAT 0x000C -#define LANG_FRENCH 0x0c -#define SUBLANG_ARABIC_LEBANON 0x0c -#define SUBLANG_ENGLISH_ZIMBABWE 0x0c -#define SUBLANG_SPANISH_ECUADOR 0x0c -#define VK_RETURN 0x0D -#define WM_GETTEXT 0x000D -#define HTTOPLEFT 13 -#define CF_UNICODETEXT 13 -#define HELP_SETPOPUP_POS 0x000d -#define LANG_HEBREW 0x0d -#define SUBLANG_ARABIC_KUWAIT 0x0d -#define SUBLANG_ENGLISH_PHILIPPINES 0x0d -#define SUBLANG_SPANISH_CHILE 0x0d -#define WM_GETTEXTLENGTH 0x000E -#define HTTOPRIGHT 14 -#define CF_ENHMETAFILE 14 -#define LANG_HUNGARIAN 0x0e -#define SUBLANG_ARABIC_UAE 0x0e -#define SUBLANG_SPANISH_URUGUAY 0x0e -#define WM_PAINT 0x000F -#define HTBOTTOM 15 -#define CF_HDROP 15 -#define LANG_ICELANDIC 0x0f -#define SUBLANG_ARABIC_BAHRAIN 0x0f -#define SUBLANG_SPANISH_PARAGUAY 0x0f -#define VK_SHIFT 0x10 -#define WM_CLOSE 0x0010 -#define HTBOTTOMLEFT 16 -#define WVR_ALIGNTOP 0x0010 -#define MK_MBUTTON 0x0010 -#define TME_NONCLIENT 0x00000010 -#define CF_LOCALE 16 -#define HELP_TCARD_DATA 0x0010 -#define TBSTYLE_AUTOSIZE 0x0010 -#define TTS_NOANIMATE 0x10 -#define TBS_NOTICKS 0x0010 -#define UDS_AUTOBUDDY 0x0010 -#define PBS_SMOOTHREVERSE 0x10 -#define LWS_USECUSTOMTEXT 0x0010 -#define LVS_SORTASCENDING 0x0010 -#define TVS_DISABLEDRAGDROP 0x0010 -#define TVS_EX_RICHTOOLTIP 0x0010 -#define TCS_FORCEICONLEFT 0x0010 -#define MCS_NOTODAY 0x0010 -#define DTS_APPCANPARSE 0x0010 -#define NFS_ALL 0x0010 -#define LANG_ITALIAN 0x10 -#define SUBLANG_ARABIC_QATAR 0x10 -#define SUBLANG_ENGLISH_INDIA 0x10 -#define SUBLANG_SPANISH_BOLIVIA 0x10 -#define VK_CONTROL 0x11 -#define WM_QUERYENDSESSION 0x0011 -#define HTBOTTOMRIGHT 17 -#define CF_DIBV5 17 -#define HELP_TCARD_OTHER_CALLER 0x0011 -#define LANG_JAPANESE 0x11 -#define SUBLANG_ENGLISH_MALAYSIA 0x11 -#define SUBLANG_SPANISH_EL_SALVADOR 0x11 -#define VK_MENU 0x12 -#define WM_QUIT 0x0012 -#define HTBORDER 18 -#define CF_MAX 18 -#define LANG_KOREAN 0x12 -#define SUBLANG_ENGLISH_SINGAPORE 0x12 -#define SUBLANG_SPANISH_HONDURAS 0x12 -#define VK_PAUSE 0x13 -#define WM_QUERYOPEN 0x0013 -#define HTOBJECT 19 -#define LANG_DUTCH 0x13 -#define SUBLANG_SPANISH_NICARAGUA 0x13 -#define VK_CAPITAL 0x14 -#define WM_ERASEBKGND 0x0014 -#define HTCLOSE 20 -#define LANG_NORWEGIAN 0x14 -#define SUBLANG_SPANISH_PUERTO_RICO 0x14 -#define VK_KANA 0x15 -#define VK_HANGEUL 0x15 -#define VK_HANGUL 0x15 -#define WM_SYSCOLORCHANGE 0x0015 -#define HTHELP 21 -#define LANG_POLISH 0x15 -#define SUBLANG_SPANISH_US 0x15 -#define WM_ENDSESSION 0x0016 -#define LANG_PORTUGUESE 0x16 -#define VK_JUNJA 0x17 -#define LANG_ROMANSH 0x17 -#define VK_FINAL 0x18 -#define WM_SHOWWINDOW 0x0018 -#define LANG_ROMANIAN 0x18 -#define VK_HANJA 0x19 -#define VK_KANJI 0x19 -#define LANG_RUSSIAN 0x19 -#define WM_WININICHANGE 0x001A -#define LANG_BOSNIAN 0x1a -#define LANG_CROATIAN 0x1a -#define LANG_SERBIAN 0x1a -#define VK_ESCAPE 0x1B -#define WM_DEVMODECHANGE 0x001B -#define LANG_SLOVAK 0x1b -#define VK_CONVERT 0x1C -#define WM_ACTIVATEAPP 0x001C -#define LANG_ALBANIAN 0x1c -#define VK_NONCONVERT 0x1D -#define WM_FONTCHANGE 0x001D -#define LANG_SWEDISH 0x1d -#define VK_ACCEPT 0x1E -#define WM_TIMECHANGE 0x001E -#define LANG_THAI 0x1e -#define VK_MODECHANGE 0x1F -#define WM_CANCELMODE 0x001F -#define LANG_TURKISH 0x1f -#define VK_SPACE 0x20 -#define WM_SETCURSOR 0x0020 -#define SMTO_ERRORONEXIT 0x0020 -#define WVR_ALIGNLEFT 0x0020 -#define MK_XBUTTON1 0x0020 -#define CS_OWNDC 0x0020 -#define TBSTYLE_NOPREFIX 0x0020 -#define TTS_NOFADE 0x20 -#define TBS_ENABLESELRANGE 0x0020 -#define UDS_ARROWKEYS 0x0020 -#define LWS_RIGHT 0x0020 -#define LVS_SORTDESCENDING 0x0020 -#define TVS_SHOWSELALWAYS 0x0020 -#define TVS_EX_AUTOHSCROLL 0x0020 -#define TCS_FORCELABELLEFT 0x0020 -#define DTS_RIGHTALIGN 0x0020 -#define NFS_USEFONTASSOC 0x0020 -#define LANG_URDU 0x20 -#define VK_PRIOR 0x21 -#define WM_MOUSEACTIVATE 0x0021 -#define LANG_INDONESIAN 0x21 -#define VK_NEXT 0x22 -#define WM_CHILDACTIVATE 0x0022 -#define LANG_UKRAINIAN 0x22 -#define VK_END 0x23 -#define WM_QUEUESYNC 0x0023 -#define LANG_BELARUSIAN 0x23 -#define VK_HOME 0x24 -#define WM_GETMINMAXINFO 0x0024 -#define LANG_SLOVENIAN 0x24 -#define VK_LEFT 0x25 -#define LANG_ESTONIAN 0x25 -#define VK_UP 0x26 -#define WM_PAINTICON 0x0026 -#define LANG_LATVIAN 0x26 -#define VK_RIGHT 0x27 -#define WM_ICONERASEBKGND 0x0027 -#define LANG_LITHUANIAN 0x27 -#define VK_DOWN 0x28 -#define WM_NEXTDLGCTL 0x0028 -#define LANG_TAJIK 0x28 -#define VK_SELECT 0x29 -#define LANG_FARSI 0x29 -#define LANG_PERSIAN 0x29 -#define VK_PRINT 0x2A -#define WM_SPOOLERSTATUS 0x002A -#define LANG_VIETNAMESE 0x2a -#define VK_EXECUTE 0x2B -#define WM_DRAWITEM 0x002B -#define LANG_ARMENIAN 0x2b -#define VK_SNAPSHOT 0x2C -#define WM_MEASUREITEM 0x002C -#define LANG_AZERI 0x2c -#define VK_INSERT 0x2D -#define WM_DELETEITEM 0x002D -#define LANG_BASQUE 0x2d -#define VK_DELETE 0x2E -#define WM_VKEYTOITEM 0x002E -#define LANG_LOWER_SORBIAN 0x2e -#define LANG_UPPER_SORBIAN 0x2e -#define VK_HELP 0x2F -#define WM_CHARTOITEM 0x002F -#define LANG_MACEDONIAN 0x2f -#define WM_SETFONT 0x0030 -#define WM_GETFONT 0x0031 -#define WM_SETHOTKEY 0x0032 -#define LANG_TSWANA 0x32 -#define WM_GETHOTKEY 0x0033 -#define LANG_XHOSA 0x34 -#define LANG_ZULU 0x35 -#define LANG_AFRIKAANS 0x36 -#define WM_QUERYDRAGICON 0x0037 -#define LANG_GEORGIAN 0x37 -#define LANG_FAEROESE 0x38 -#define WM_COMPAREITEM 0x0039 -#define LANG_HINDI 0x39 -#define LANG_MALTESE 0x3a -#define LANG_SAMI 0x3b -#define LANG_IRISH 0x3c -#define WM_GETOBJECT 0x003D -#define LANG_MALAY 0x3e -#define LANG_KAZAK 0x3f -#define WVR_ALIGNBOTTOM 0x0040 -#define MK_XBUTTON2 0x0040 -#define CS_CLASSDC 0x0040 -#define HDS_DRAGDROP 0x0040 -#define BTNS_SHOWTEXT 0x0040 -#define TTS_BALLOON 0x40 -#define TBS_FIXEDLENGTH 0x0040 -#define UDS_HORZ 0x0040 -#define LVS_SHAREIMAGELISTS 0x0040 -#define TVS_RTLREADING 0x0040 -#define TVS_EX_FADEINOUTEXPANDOS 0x0040 -#define TCS_HOTTRACK 0x0040 -#define MCS_NOTRAILINGDATES 0x0040 -#define LANG_KYRGYZ 0x40 -#define WM_COMPACTING 0x0041 -#define LANG_SWAHILI 0x41 -#define LANG_TURKMEN 0x42 -#define LANG_UZBEK 0x43 -#define WM_COMMNOTIFY 0x0044 -#define LANG_TATAR 0x44 -#define LANG_BENGALI 0x45 -#define WM_WINDOWPOSCHANGING 0x0046 -#define LANG_PUNJABI 0x46 -#define WM_WINDOWPOSCHANGED 0x0047 -#define LANG_GUJARATI 0x47 -#define WM_POWER 0x0048 -#define LANG_ORIYA 0x48 -#define LANG_TAMIL 0x49 -#define WM_COPYDATA 0x004A -#define LANG_TELUGU 0x4a -#define WM_CANCELJOURNAL 0x004B -#define LANG_KANNADA 0x4b -#define LANG_MALAYALAM 0x4c -#define LANG_ASSAMESE 0x4d -#define WM_NOTIFY 0x004E -#define LANG_MARATHI 0x4e -#define LANG_SANSKRIT 0x4f -#define WM_INPUTLANGCHANGEREQUEST 0x0050 -#define LANG_MONGOLIAN 0x50 -#define WM_INPUTLANGCHANGE 0x0051 -#define LANG_TIBETAN 0x51 -#define WM_TCARD 0x0052 -#define LANG_WELSH 0x52 -#define WM_HELP 0x0053 -#define LANG_KHMER 0x53 -#define WM_USERCHANGED 0x0054 -#define LANG_LAO 0x54 -#define WM_NOTIFYFORMAT 0x0055 -#define LANG_GALICIAN 0x56 -#define LANG_KONKANI 0x57 -#define LANG_MANIPURI 0x58 -#define LANG_SINDHI 0x59 -#define LANG_SYRIAC 0x5a -#define VK_LWIN 0x5B -#define LANG_SINHALESE 0x5b -#define VK_RWIN 0x5C -#define VK_APPS 0x5D -#define LANG_INUKTITUT 0x5d -#define LANG_AMHARIC 0x5e -#define VK_SLEEP 0x5F -#define LANG_TAMAZIGHT 0x5f -#define VK_NUMPAD0 0x60 -#define LANG_KASHMIRI 0x60 -#define VK_NUMPAD1 0x61 -#define LANG_NEPALI 0x61 -#define VK_NUMPAD2 0x62 -#define LANG_FRISIAN 0x62 -#define VK_NUMPAD3 0x63 -#define LANG_PASHTO 0x63 -#define VK_NUMPAD4 0x64 -#define LANG_FILIPINO 0x64 -#define VS_USER_DEFINED 100 -#define VK_NUMPAD5 0x65 -#define LANG_DIVEHI 0x65 -#define VK_NUMPAD6 0x66 -#define VK_NUMPAD7 0x67 -#define VK_NUMPAD8 0x68 -#define LANG_HAUSA 0x68 -#define VK_NUMPAD9 0x69 -#define VK_MULTIPLY 0x6A -#define LANG_YORUBA 0x6a -#define VK_ADD 0x6B -#define LANG_QUECHUA 0x6b -#define VK_SEPARATOR 0x6C -#define LANG_SOTHO 0x6c -#define VK_SUBTRACT 0x6D -#define LANG_BASHKIR 0x6d -#define VK_DECIMAL 0x6E -#define LANG_LUXEMBOURGISH 0x6e -#define VK_DIVIDE 0x6F -#define LANG_GREENLANDIC 0x6f -#define VK_F1 0x70 -#define LANG_IGBO 0x70 -#define VK_F2 0x71 -#define VK_F3 0x72 -#define VK_F4 0x73 -#define LANG_TIGRIGNA 0x73 -#define VK_F5 0x74 -#define VK_F6 0x75 -#define VK_F7 0x76 -#define VK_F8 0x77 -#define VK_F9 0x78 -#define WHEEL_DELTA 120 -#define LANG_YI 0x78 -#define VK_F10 0x79 -#define VK_F11 0x7A -#define LANG_MAPUDUNGUN 0x7a -#define VK_F12 0x7B -#define WM_CONTEXTMENU 0x007B -#define VK_F13 0x7C -#define WM_STYLECHANGING 0x007C -#define LANG_MOHAWK 0x7c -#define VK_F14 0x7D -#define WM_STYLECHANGED 0x007D -#define VK_F15 0x7E -#define WM_DISPLAYCHANGE 0x007E -#define LANG_BRETON 0x7e -#define VK_F16 0x7F -#define WM_GETICON 0x007F -#define LANG_INVARIANT 0x7f -#define VK_F17 0x80 -#define WM_SETICON 0x0080 -#define WVR_ALIGNRIGHT 0x0080 -#define CS_PARENTDC 0x0080 -#define CF_OWNERDISPLAY 0x0080 -#define HDS_FULLDRAG 0x0080 -#define BTNS_WHOLEDROPDOWN 0x0080 -#define TTS_CLOSE 0x80 -#define TBS_NOTHUMB 0x0080 -#define UDS_NOTHOUSANDS 0x0080 -#define LVS_NOLABELWRAP 0x0080 -#define TVS_NOTOOLTIPS 0x0080 -#define TVS_EX_PARTIALCHECKBOXES 0x0080 -#define TCS_VERTICAL 0x0080 -#define MCS_SHORTDAYSOFWEEK 0x0080 -#define LANG_UIGHUR 0x80 -#define VK_F18 0x81 -#define WM_NCCREATE 0x0081 -#define CF_DSPTEXT 0x0081 -#define LANG_MAORI 0x81 -#define VK_F19 0x82 -#define WM_NCDESTROY 0x0082 -#define CF_DSPBITMAP 0x0082 -#define LANG_OCCITAN 0x82 -#define VK_F20 0x83 -#define WM_NCCALCSIZE 0x0083 -#define CF_DSPMETAFILEPICT 0x0083 -#define LANG_CORSICAN 0x83 -#define VK_F21 0x84 -#define WM_NCHITTEST 0x0084 -#define LANG_ALSATIAN 0x84 -#define VK_F22 0x85 -#define WM_NCPAINT 0x0085 -#define LANG_YAKUT 0x85 -#define VK_F23 0x86 -#define WM_NCACTIVATE 0x0086 -#define LANG_KICHE 0x86 -#define VK_F24 0x87 -#define WM_GETDLGCODE 0x0087 -#define LANG_KINYARWANDA 0x87 -#define WM_SYNCPAINT 0x0088 -#define LANG_WOLOF 0x88 -#define LANG_DARI 0x8c -#define CF_DSPENHMETAFILE 0x008E -#define VK_NUMLOCK 0x90 -#define VK_SCROLL 0x91 -#define VK_OEM_NEC_EQUAL 0x92 -#define VK_OEM_FJ_JISHO 0x92 -#define VK_OEM_FJ_MASSHOU 0x93 -#define VK_OEM_FJ_TOUROKU 0x94 -#define VK_OEM_FJ_LOYA 0x95 -#define VK_OEM_FJ_ROYA 0x96 -#define VK_LSHIFT 0xA0 -#define WM_NCMOUSEMOVE 0x00A0 -#define VK_RSHIFT 0xA1 -#define WM_NCLBUTTONDOWN 0x00A1 -#define VK_LCONTROL 0xA2 -#define WM_NCLBUTTONUP 0x00A2 -#define VK_RCONTROL 0xA3 -#define WM_NCLBUTTONDBLCLK 0x00A3 -#define VK_LMENU 0xA4 -#define WM_NCRBUTTONDOWN 0x00A4 -#define VK_RMENU 0xA5 -#define WM_NCRBUTTONUP 0x00A5 -#define VK_BROWSER_BACK 0xA6 -#define WM_NCRBUTTONDBLCLK 0x00A6 -#define VK_BROWSER_FORWARD 0xA7 -#define WM_NCMBUTTONDOWN 0x00A7 -#define VK_BROWSER_REFRESH 0xA8 -#define WM_NCMBUTTONUP 0x00A8 -#define VK_BROWSER_STOP 0xA9 -#define WM_NCMBUTTONDBLCLK 0x00A9 -#define VK_BROWSER_SEARCH 0xAA -#define VK_BROWSER_FAVORITES 0xAB -#define WM_NCXBUTTONDOWN 0x00AB -#define VK_BROWSER_HOME 0xAC -#define WM_NCXBUTTONUP 0x00AC -#define VK_VOLUME_MUTE 0xAD -#define WM_NCXBUTTONDBLCLK 0x00AD -#define VK_VOLUME_DOWN 0xAE -#define VK_VOLUME_UP 0xAF -#define VK_MEDIA_NEXT_TRACK 0xB0 -#define EM_GETSEL 0x00B0 -#define VK_MEDIA_PREV_TRACK 0xB1 -#define EM_SETSEL 0x00B1 -#define VK_MEDIA_STOP 0xB2 -#define EM_GETRECT 0x00B2 -#define VK_MEDIA_PLAY_PAUSE 0xB3 -#define EM_SETRECT 0x00B3 -#define VK_LAUNCH_MAIL 0xB4 -#define EM_SETRECTNP 0x00B4 -#define VK_LAUNCH_MEDIA_SELECT 0xB5 -#define EM_SCROLL 0x00B5 -#define VK_LAUNCH_APP1 0xB6 -#define EM_LINESCROLL 0x00B6 -#define VK_LAUNCH_APP2 0xB7 -#define EM_SCROLLCARET 0x00B7 -#define EM_GETMODIFY 0x00B8 -#define EM_SETMODIFY 0x00B9 -#define VK_OEM_1 0xBA -#define EM_GETLINECOUNT 0x00BA -#define VK_OEM_PLUS 0xBB -#define EM_LINEINDEX 0x00BB -#define VK_OEM_COMMA 0xBC -#define EM_SETHANDLE 0x00BC -#define VK_OEM_MINUS 0xBD -#define EM_GETHANDLE 0x00BD -#define VK_OEM_PERIOD 0xBE -#define EM_GETTHUMB 0x00BE -#define VK_OEM_2 0xBF -#define VK_OEM_3 0xC0 -#define EM_LINELENGTH 0x00C1 -#define EM_REPLACESEL 0x00C2 -#define EM_GETLINE 0x00C4 -#define EM_LIMITTEXT 0x00C5 -#define EM_CANUNDO 0x00C6 -#define EM_UNDO 0x00C7 -#define EM_FMTLINES 0x00C8 -#define DLG_MAIN 200 -#define EM_LINEFROMCHAR 0x00C9 -#define EM_SETTABSTOPS 0x00CB -#define EM_SETPASSWORDCHAR 0x00CC -#define EM_EMPTYUNDOBUFFER 0x00CD -#define EM_GETFIRSTVISIBLELINE 0x00CE -#define EM_SETREADONLY 0x00CF -#define EM_SETWORDBREAKPROC 0x00D0 -#define EM_GETWORDBREAKPROC 0x00D1 -#define EM_GETPASSWORDCHAR 0x00D2 -#define EM_SETMARGINS 0x00D3 -#define EM_GETMARGINS 0x00D4 -#define EM_GETLIMITTEXT 0x00D5 -#define EM_POSFROMCHAR 0x00D6 -#define EM_CHARFROMPOS 0x00D7 -#define EM_SETIMESTATUS 0x00D8 -#define EM_GETIMESTATUS 0x00D9 -#define VK_OEM_4 0xDB -#define VK_OEM_5 0xDC -#define VK_OEM_6 0xDD -#define VK_OEM_7 0xDE -#define VK_OEM_8 0xDF -#define VK_OEM_AX 0xE1 -#define VK_OEM_102 0xE2 -#define VK_ICO_HELP 0xE3 -#define VK_ICO_00 0xE4 -#define VK_PROCESSKEY 0xE5 -#define VK_ICO_CLEAR 0xE6 -#define VK_PACKET 0xE7 -#define VK_OEM_RESET 0xE9 -#define VK_OEM_JUMP 0xEA -#define VK_OEM_PA1 0xEB -#define VK_OEM_PA2 0xEC -#define VK_OEM_PA3 0xED -#define VK_OEM_WSCTRL 0xEE -#define VK_OEM_CUSEL 0xEF -#define VK_OEM_ATTN 0xF0 -#define BM_GETCHECK 0x00F0 -#define VK_OEM_FINISH 0xF1 -#define BM_SETCHECK 0x00F1 -#define VK_OEM_COPY 0xF2 -#define BM_GETSTATE 0x00F2 -#define VK_OEM_AUTO 0xF3 -#define BM_SETSTATE 0x00F3 -#define VK_OEM_ENLW 0xF4 -#define BM_SETSTYLE 0x00F4 -#define VK_OEM_BACKTAB 0xF5 -#define BM_CLICK 0x00F5 -#define VK_ATTN 0xF6 -#define BM_GETIMAGE 0x00F6 -#define VK_CRSEL 0xF7 -#define BM_SETIMAGE 0x00F7 -#define VK_EXSEL 0xF8 -#define BM_SETDONTCLICK 0x00F8 -#define VK_EREOF 0xF9 -#define VK_PLAY 0xFA -#define VK_ZOOM 0xFB -#define VK_NONAME 0xFC -#define VK_PA1 0xFD -#define VK_OEM_CLEAR 0xFE -#define WM_INPUT_DEVICE_CHANGE 0x00FE -#define SUBVERSION_MASK 0x000000FF -#define WM_INPUT 0x00FF -#define WM_KEYFIRST 0x0100 -#define WM_KEYDOWN 0x0100 -#define WVR_HREDRAW 0x0100 -#define HDS_FILTERBAR 0x0100 -#define TBSTYLE_TOOLTIPS 0x0100 -#define RBS_TOOLTIPS 0x00000100 -#define TTS_USEVISUALSTYLE 0x100 -#define SBARS_SIZEGRIP 0x0100 -#define TBS_TOOLTIPS 0x0100 -#define UDS_HOTTRACK 0x0100 -#define LVS_AUTOARRANGE 0x0100 -#define TVS_CHECKBOXES 0x0100 -#define TVS_EX_EXCLUSIONCHECKBOXES 0x0100 -#define TCS_BUTTONS 0x0100 -#define MCS_NOSELCHANGEONNAV 0x0100 -#define WM_KEYUP 0x0101 -#define WM_CHAR 0x0102 -#define WM_DEADCHAR 0x0103 -#define WM_SYSKEYDOWN 0x0104 -#define WM_SYSKEYUP 0x0105 -#define WM_SYSCHAR 0x0106 -#define WM_SYSDEADCHAR 0x0107 -#define WM_UNICHAR 0x0109 -#define WM_IME_STARTCOMPOSITION 0x010D -#define WM_IME_ENDCOMPOSITION 0x010E -#define WM_IME_COMPOSITION 0x010F -#define WM_IME_KEYLAST 0x010F -#define WM_INITDIALOG 0x0110 -#define WM_COMMAND 0x0111 -#define WM_SYSCOMMAND 0x0112 -#define WM_TIMER 0x0113 -#define WM_HSCROLL 0x0114 -#define WM_VSCROLL 0x0115 -#define WM_INITMENU 0x0116 -#define WM_INITMENUPOPUP 0x0117 -#define WM_MENUSELECT 0x011F -#define WM_MENUCHAR 0x0120 -#define WM_ENTERIDLE 0x0121 -#define WM_MENURBUTTONUP 0x0122 -#define WM_MENUDRAG 0x0123 -#define WM_MENUGETOBJECT 0x0124 -#define WM_UNINITMENUPOPUP 0x0125 -#define WM_MENUCOMMAND 0x0126 -#define WM_CHANGEUISTATE 0x0127 -#define WM_UPDATEUISTATE 0x0128 -#define WM_QUERYUISTATE 0x0129 -#define DLG_ICON 300 -#define WM_CTLCOLORMSGBOX 0x0132 -#define WM_CTLCOLOREDIT 0x0133 -#define WM_CTLCOLORLISTBOX 0x0134 -#define WM_CTLCOLORBTN 0x0135 -#define WM_CTLCOLORDLG 0x0136 -#define WM_CTLCOLORSCROLLBAR 0x0137 -#define WM_CTLCOLORSTATIC 0x0138 -#define MN_GETHMENU 0x01E1 -#define _WIN32_IE_IE20 0x0200 -#define WM_MOUSEFIRST 0x0200 -#define WM_MOUSEMOVE 0x0200 -#define WVR_VREDRAW 0x0200 -#define CS_NOCLOSE 0x0200 -#define CF_PRIVATEFIRST 0x0200 -#define HDS_FLAT 0x0200 -#define TBSTYLE_WRAPABLE 0x0200 -#define RBS_VARHEIGHT 0x00000200 -#define TBS_REVERSED 0x0200 -#define LVS_EDITLABELS 0x0200 -#define TVS_TRACKSELECT 0x0200 -#define TVS_EX_DIMMEDCHECKBOXES 0x0200 -#define TCS_MULTILINE 0x0200 -#define WM_LBUTTONDOWN 0x0201 -#define WM_LBUTTONUP 0x0202 -#define WM_LBUTTONDBLCLK 0x0203 -#define WM_RBUTTONDOWN 0x0204 -#define WM_RBUTTONUP 0x0205 -#define WM_RBUTTONDBLCLK 0x0206 -#define WM_MBUTTONDOWN 0x0207 -#define WM_MBUTTONUP 0x0208 -#define WM_MBUTTONDBLCLK 0x0209 -#define WM_MOUSEWHEEL 0x020A -#define WM_XBUTTONDOWN 0x020B -#define WM_XBUTTONUP 0x020C -#define WM_XBUTTONDBLCLK 0x020D -#define WM_MOUSEHWHEEL 0x020E -#define WM_PARENTNOTIFY 0x0210 -#define WM_ENTERMENULOOP 0x0211 -#define WM_EXITMENULOOP 0x0212 -#define WM_NEXTMENU 0x0213 -#define WM_SIZING 0x0214 -#define WM_CAPTURECHANGED 0x0215 -#define WM_MOVING 0x0216 -#define WM_POWERBROADCAST 0x0218 -#define WM_DEVICECHANGE 0x0219 -#define WM_MDICREATE 0x0220 -#define WM_MDIDESTROY 0x0221 -#define WM_MDIACTIVATE 0x0222 -#define WM_MDIRESTORE 0x0223 -#define WM_MDINEXT 0x0224 -#define WM_MDIMAXIMIZE 0x0225 -#define WM_MDITILE 0x0226 -#define WM_MDICASCADE 0x0227 -#define WM_MDIICONARRANGE 0x0228 -#define WM_MDIGETACTIVE 0x0229 -#define WM_MDISETMENU 0x0230 -#define WM_ENTERSIZEMOVE 0x0231 -#define WM_EXITSIZEMOVE 0x0232 -#define WM_DROPFILES 0x0233 -#define WM_MDIREFRESHMENU 0x0234 -#define WM_IME_SETCONTEXT 0x0281 -#define WM_IME_NOTIFY 0x0282 -#define WM_IME_CONTROL 0x0283 -#define WM_IME_COMPOSITIONFULL 0x0284 -#define WM_IME_SELECT 0x0285 -#define WM_IME_CHAR 0x0286 -#define WM_IME_REQUEST 0x0288 -#define WM_IME_KEYDOWN 0x0290 -#define WM_IME_KEYUP 0x0291 -#define WM_NCMOUSEHOVER 0x02A0 -#define WM_MOUSEHOVER 0x02A1 -#define WM_NCMOUSELEAVE 0x02A2 -#define WM_MOUSELEAVE 0x02A3 -#define WM_WTSSESSION_CHANGE 0x02B1 -#define WM_TABLET_FIRST 0x02c0 -#define WM_TABLET_LAST 0x02df -#define CF_PRIVATELAST 0x02FF -#define _WIN32_IE_IE30 0x0300 -#define WM_CUT 0x0300 -#define CF_GDIOBJFIRST 0x0300 -#define WM_COPY 0x0301 -#define _WIN32_IE_IE302 0x0302 -#define WM_PASTE 0x0302 -#define WM_CLEAR 0x0303 -#define WM_UNDO 0x0304 -#define WM_RENDERFORMAT 0x0305 -#define WM_RENDERALLFORMATS 0x0306 -#define WM_DESTROYCLIPBOARD 0x0307 -#define WM_DRAWCLIPBOARD 0x0308 -#define WM_PAINTCLIPBOARD 0x0309 -#define WM_VSCROLLCLIPBOARD 0x030A -#define WM_SIZECLIPBOARD 0x030B -#define WM_ASKCBFORMATNAME 0x030C -#define WM_CHANGECBCHAIN 0x030D -#define WM_HSCROLLCLIPBOARD 0x030E -#define WM_QUERYNEWPALETTE 0x030F -#define WM_PALETTEISCHANGING 0x0310 -#define WM_PALETTECHANGED 0x0311 -#define WM_HOTKEY 0x0312 -#define WM_PRINT 0x0317 -#define WM_PRINTCLIENT 0x0318 -#define WM_APPCOMMAND 0x0319 -#define WM_THEMECHANGED 0x031A -#define WM_CLIPBOARDUPDATE 0x031D -#define WM_DWMCOMPOSITIONCHANGED 0x031E -#define WM_DWMNCRENDERINGCHANGED 0x031F -#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 -#define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321 -#define WM_GETTITLEBARINFOEX 0x033F -#define WM_HANDHELDFIRST 0x0358 -#define WM_HANDHELDLAST 0x035F -#define WM_AFXFIRST 0x0360 -#define WM_AFXLAST 0x037F -#define WM_PENWINFIRST 0x0380 -#define WM_PENWINLAST 0x038F -#define WM_DDE_FIRST 0x03E0 -#define IDC_STATUS 1000 -#define IDC_LIST1 1000 -#define IDC_LEFT 1001 -#define IDC_RIGHT 1002 -#define IDC_TOP 1003 -#define IDC_MIDDLE 1004 -#define IDC_BOTTOM 1005 -#define IDC_EDIT 1010 -#define IDC_CLEAR 1011 -#define CF_GDIOBJLAST 0x03FF -#define _WIN32_WINNT_NT4 0x0400 -#define _WIN32_IE_IE40 0x0400 -#define WM_USER 0x0400 -#define WVR_VALIDRECTS 0x0400 -#define HDS_CHECKBOXES 0x0400 -#define TBSTYLE_ALTDRAG 0x0400 -#define RBS_BANDBORDERS 0x00000400 -#define TBS_DOWNISLEFT 0x0400 -#define LVS_OWNERDRAWFIXED 0x0400 -#define TVS_SINGLEEXPAND 0x0400 -#define TVS_EX_DRAWIMAGEASYNC 0x0400 -#define TCS_FIXEDWIDTH 0x0400 -#define ctlFirst 0x0400 -#define psh1 0x0400 -#define _WIN32_IE_IE401 0x0401 -#define psh2 0x0401 -#define psh3 0x0402 -#define psh4 0x0403 -#define psh5 0x0404 -#define psh6 0x0405 -#define psh7 0x0406 -#define psh8 0x0407 -#define psh9 0x0408 -#define psh10 0x0409 -#define psh11 0x040a -#define psh12 0x040b -#define psh13 0x040c -#define psh14 0x040d -#define psh15 0x040e -#define psh16 0x040f -#define _WIN32_WINDOWS 0x0410 -#define chx1 0x0410 -#define chx2 0x0411 -#define chx3 0x0412 -#define chx4 0x0413 -#define chx5 0x0414 -#define chx6 0x0415 -#define chx7 0x0416 -#define chx8 0x0417 -#define chx9 0x0418 -#define chx10 0x0419 -#define chx11 0x041a -#define chx12 0x041b -#define chx13 0x041c -#define chx14 0x041d -#define chx15 0x041e -#define chx16 0x041f -#define rad1 0x0420 -#define rad2 0x0421 -#define rad3 0x0422 -#define rad4 0x0423 -#define rad5 0x0424 -#define rad6 0x0425 -#define rad7 0x0426 -#define rad8 0x0427 -#define rad9 0x0428 -#define rad10 0x0429 -#define rad11 0x042a -#define rad12 0x042b -#define rad13 0x042c -#define rad14 0x042d -#define rad15 0x042e -#define rad16 0x042f -#define grp1 0x0430 -#define grp2 0x0431 -#define grp3 0x0432 -#define grp4 0x0433 -#define frm1 0x0434 -#define frm2 0x0435 -#define frm3 0x0436 -#define frm4 0x0437 -#define rct1 0x0438 -#define rct2 0x0439 -#define rct3 0x043a -#define rct4 0x043b -#define ico1 0x043c -#define ico2 0x043d -#define ico3 0x043e -#define ico4 0x043f -#define stc1 0x0440 -#define stc2 0x0441 -#define stc3 0x0442 -#define stc4 0x0443 -#define stc5 0x0444 -#define stc6 0x0445 -#define stc7 0x0446 -#define stc8 0x0447 -#define stc9 0x0448 -#define stc10 0x0449 -#define stc11 0x044a -#define stc12 0x044b -#define stc13 0x044c -#define stc14 0x044d -#define stc15 0x044e -#define stc16 0x044f -#define stc17 0x0450 -#define stc18 0x0451 -#define stc19 0x0452 -#define stc20 0x0453 -#define stc21 0x0454 -#define stc22 0x0455 -#define stc23 0x0456 -#define stc24 0x0457 -#define stc25 0x0458 -#define stc26 0x0459 -#define stc27 0x045a -#define stc28 0x045b -#define stc29 0x045c -#define stc30 0x045d -#define stc31 0x045e -#define stc32 0x045f -#define lst1 0x0460 -#define lst2 0x0461 -#define lst3 0x0462 -#define lst4 0x0463 -#define lst5 0x0464 -#define lst6 0x0465 -#define lst7 0x0466 -#define lst8 0x0467 -#define lst9 0x0468 -#define lst10 0x0469 -#define lst11 0x046a -#define lst12 0x046b -#define lst13 0x046c -#define lst14 0x046d -#define lst15 0x046e -#define lst16 0x046f -#define cmb1 0x0470 -#define cmb2 0x0471 -#define cmb3 0x0472 -#define cmb4 0x0473 -#define cmb5 0x0474 -#define cmb6 0x0475 -#define cmb7 0x0476 -#define cmb8 0x0477 -#define cmb9 0x0478 -#define cmb10 0x0479 -#define cmb11 0x047a -#define cmb12 0x047b -#define cmb13 0x047c -#define cmb14 0x047d -#define cmb15 0x047e -#define cmb16 0x047f -#define edt1 0x0480 -#define edt2 0x0481 -#define edt3 0x0482 -#define edt4 0x0483 -#define edt5 0x0484 -#define edt6 0x0485 -#define edt7 0x0486 -#define edt8 0x0487 -#define edt9 0x0488 -#define edt10 0x0489 -#define edt11 0x048a -#define edt12 0x048b -#define edt13 0x048c -#define edt14 0x048d -#define edt15 0x048e -#define edt16 0x048f -#define scr1 0x0490 -#define scr2 0x0491 -#define scr3 0x0492 -#define scr4 0x0493 -#define scr5 0x0494 -#define scr6 0x0495 -#define scr7 0x0496 -#define scr8 0x0497 -#define ctl1 0x04A0 -#define ctlLast 0x04ff -#define _WIN32_WINNT_WIN2K 0x0500 -#define _WIN32_IE_IE50 0x0500 -#define _WIN32_WINNT_WINXP 0x0501 -#define _WIN32_IE_IE501 0x0501 -#define _WIN32_WINNT_WS03 0x0502 -#define _WIN32_IE_IE55 0x0550 -#define _WIN32_WINNT_LONGHORN 0x0600 -#define _WIN32_IE_IE60 0x0600 -#define FILEOPENORD 1536 -#define _WIN32_IE_IE60SP1 0x0601 -#define MULTIFILEOPENORD 1537 -#define _WIN32_IE_WS03 0x0602 -#define PRINTDLGORD 1538 -#define _WIN32_IE_IE60SP2 0x0603 -#define PRNSETUPDLGORD 1539 -#define FINDDLGORD 1540 -#define REPLACEDLGORD 1541 -#define FONTDLGORD 1542 -#define FORMATDLGORD31 1543 -#define FORMATDLGORD30 1544 -#define RUNDLGORD 1545 -#define PAGESETUPDLGORD 1546 -#define NEWFILEOPENORD 1547 -#define PRINTDLGEXORD 1549 -#define PAGESETUPDLGORDMOTIF 1550 -#define COLORMGMTDLGORD 1551 -#define NEWFILEOPENV2ORD 1552 -#define NEWFILEOPENV3ORD 1553 -#define _WIN32_IE_IE70 0x0700 -#define CS_SAVEBITS 0x0800 -#define HDS_NOSIZING 0x0800 -#define TBSTYLE_FLAT 0x0800 -#define RBS_FIXEDORDER 0x00000800 -#define SBARS_TOOLTIPS 0x0800 -#define SBT_TOOLTIPS 0x0800 -#define TBS_NOTIFYBEFOREMOVE 0x0800 -#define LVS_ALIGNLEFT 0x0800 -#define TVS_INFOTIP 0x0800 -#define TCS_RAGGEDRIGHT 0x0800 -#define LVS_ALIGNMASK 0x0c00 -#define CS_BYTEALIGNCLIENT 0x1000 -#define HDS_OVERFLOW 0x1000 -#define TBSTYLE_LIST 0x1000 -#define RBS_REGISTERDROP 0x00001000 -#define TBS_TRANSPARENTBKGND 0x1000 -#define LVS_OWNERDATA 0x1000 -#define TVS_FULLROWSELECT 0x1000 -#define TCS_FOCUSONBUTTONDOWN 0x1000 -#define CS_BYTEALIGNWINDOW 0x2000 -#define TBSTYLE_CUSTOMERASE 0x2000 -#define RBS_AUTOSIZE 0x00002000 -#define LVS_NOSCROLL 0x2000 -#define TVS_NOSCROLL 0x2000 -#define TCS_OWNERDRAWFIXED 0x2000 -#define CS_GLOBALCLASS 0x4000 -#define TBSTYLE_REGISTERDROP 0x4000 -#define RBS_VERTICALGRIPPER 0x00004000 -#define LVS_NOCOLUMNHEADER 0x4000 -#define TVS_NONEVENHEIGHT 0x4000 -#define TCS_TOOLTIPS 0x4000 -#define IDH_NO_HELP 28440 -#define IDH_MISSING_CONTEXT 28441 -#define IDH_GENERIC_HELP_BUTTON 28442 -#define IDH_OK 28443 -#define IDH_CANCEL 28444 -#define IDH_HELP 28445 -#define LANG_BOSNIAN_NEUTRAL 0x781a -#define LANG_CHINESE_TRADITIONAL 0x7c04 -#define LANG_SERBIAN_NEUTRAL 0x7c1a -#define IDTIMEOUT 32000 -#define OCR_NORMAL 32512 -#define OIC_SAMPLE 32512 -#define OCR_IBEAM 32513 -#define OIC_HAND 32513 -#define OCR_WAIT 32514 -#define OIC_QUES 32514 -#define OCR_CROSS 32515 -#define OIC_BANG 32515 -#define OCR_UP 32516 -#define OIC_NOTE 32516 -#define OIC_WINLOGO 32517 -#define OIC_SHIELD 32518 -#define OCR_SIZE 32640 -#define OCR_ICON 32641 -#define OCR_SIZENWSE 32642 -#define OCR_SIZENESW 32643 -#define OCR_SIZEWE 32644 -#define OCR_SIZENS 32645 -#define OCR_SIZEALL 32646 -#define OCR_ICOCUR 32647 -#define OCR_NO 32648 -#define OCR_HAND 32649 -#define OCR_APPSTARTING 32650 -#define OBM_LFARROWI 32734 -#define OBM_RGARROWI 32735 -#define OBM_DNARROWI 32736 -#define OBM_UPARROWI 32737 -#define OBM_COMBO 32738 -#define OBM_MNARROW 32739 -#define OBM_LFARROWD 32740 -#define OBM_RGARROWD 32741 -#define OBM_DNARROWD 32742 -#define OBM_UPARROWD 32743 -#define OBM_RESTORED 32744 -#define OBM_ZOOMD 32745 -#define OBM_REDUCED 32746 -#define OBM_RESTORE 32747 -#define OBM_ZOOM 32748 -#define OBM_REDUCE 32749 -#define OBM_LFARROW 32750 -#define OBM_RGARROW 32751 -#define OBM_DNARROW 32752 -#define OBM_UPARROW 32753 -#define OBM_CLOSE 32754 -#define OBM_OLD_RESTORE 32755 -#define OBM_OLD_ZOOM 32756 -#define OBM_OLD_REDUCE 32757 -#define OBM_BTNCORNERS 32758 -#define OBM_CHECKBOXES 32759 -#define OBM_CHECK 32760 -#define OBM_BTSIZE 32761 -#define OBM_OLD_LFARROW 32762 -#define OBM_OLD_RGARROW 32763 -#define OBM_OLD_DNARROW 32764 -#define OBM_OLD_UPARROW 32765 -#define OBM_SIZE 32766 -#define OBM_OLD_CLOSE 32767 -#define WM_APP 0x8000 -#define HELP_TCARD 0x8000 -#define TBSTYLE_TRANSPARENT 0x8000 -#define RBS_DBLCLKTOGGLE 0x00008000 -#define LVS_NOSORTHEADER 0x8000 -#define TVS_NOHSCROLL 0x8000 -#define TCS_FOCUSNEVER 0x8000 -#define SC_SIZE 0xF000 -#define SC_SEPARATOR 0xF00F -#define SC_MOVE 0xF010 -#define SC_MINIMIZE 0xF020 -#define SC_MAXIMIZE 0xF030 -#define SC_NEXTWINDOW 0xF040 -#define SC_PREVWINDOW 0xF050 -#define SC_CLOSE 0xF060 -#define SC_VSCROLL 0xF070 -#define SC_HSCROLL 0xF080 -#define SC_MOUSEMENU 0xF090 -#define SC_KEYMENU 0xF100 -#define SC_ARRANGE 0xF110 -#define SC_RESTORE 0xF120 -#define SC_TASKLIST 0xF130 -#define SC_SCREENSAVE 0xF140 -#define SC_HOTKEY 0xF150 -#define SC_DEFAULT 0xF160 -#define SC_MONITORPOWER 0xF170 -#define SC_CONTEXTHELP 0xF180 -#define LVS_TYPESTYLEMASK 0xfc00 -#define SPVERSION_MASK 0x0000FF00 -#define UNICODE_NOCHAR 0xFFFF -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1002 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/PC/associator.rc b/PC/associator.rc deleted file mode 100644 index 374a3b8..0000000 --- a/PC/associator.rc +++ /dev/null @@ -1,97 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "associator.h" -#include "winuser.h" -///////////////////////////////////////////////////////////////////////////// -// English (U.K.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -DLG_ICON ICON "launcher.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -DLG_MAIN DIALOGEX 20, 40, 236, 183 -// Make the dialog visible after positioning at centre -STYLE DS_SETFONT | DS_3DLOOK | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_NOPARENTNOTIFY -CAPTION "Python File Associations Have Ceased To Be!" -FONT 10, "Arial", 400, 0, 0x0 -BEGIN - LTEXT "You've uninstalled the Python Launcher, so now there are no applications associated with Python files.",IDC_STATIC,7,7,225,18 - LTEXT "You may wish to associate Python files with one of the Python versions installed on your machine, listed below:",IDC_STATIC,7,27,225,18 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,6,49,224,105 - PUSHBUTTON "&Associate with selected Python",IDOK,6,164,117,14,WS_DISABLED - PUSHBUTTON "Do&n't associate Python files",IDCANCEL,128,164,102,14 -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - DLG_MAIN, DIALOG - BEGIN - RIGHTMARGIN, 238 - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (U.K.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/PCbuild/associator.vcxproj b/PCbuild/associator.vcxproj deleted file mode 100644 index 595b2ce..0000000 --- a/PCbuild/associator.vcxproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {023B3CDA-59C8-45FD-95DC-F8973322ED34} - associator - - - - Application - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - - - - - - - Level3 - Disabled - _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - true - comctl32.lib;%(AdditionalDependencies) - false - - - - - Level3 - MaxSpeed - true - true - NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - true - true - true - comctl32.lib;%(AdditionalDependencies) - false - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/associator.vcxproj.filters b/PCbuild/associator.vcxproj.filters deleted file mode 100644 index 0846afa..0000000 --- a/PCbuild/associator.vcxproj.filters +++ /dev/null @@ -1,32 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - - - Resource Files - - - - - Header Files - - - \ No newline at end of file diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 17bfe96..add8d1a 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -72,8 +72,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vc EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "associator", "associator.vcxproj", "{023B3CDA-59C8-45FD-95DC-F8973322ED34}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 -- cgit v0.12