/* -*- Mode: C; c-basic-offset: 2; tab-width: 4; indent-tabs-mode: nil; -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is MOZCE Lib. * * The Initial Developer of the Original Code is Doug Turner . * Portions created by the Initial Developer are Copyright (C) 2005 * the Initial Developer. All Rights Reserved. * * Contributor(s): * John Wolfe * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* environment.h and environment.cpp are also included by app update */ // WINCE_SKIP_SHUNT_INCLUDE is used by app update to prevent including of // mozce_shunt.h when it includes environment.cpp #ifndef WINCE_SKIP_SHUNT_INCLUDE #include "include/mozce_shunt.h" #endif #include "include/environment.h" #include "time_conversions.h" #include #include "Windows.h" //////////////////////////////////////////////////////// // Environment Variable Stuff //////////////////////////////////////////////////////// typedef struct env_entry env_entry; #define ENV_IS_STATIC 0 #define ENV_FREE_KEY 1 #define ENV_FREE_BOTH 2 struct env_entry { char *key; char *value; int flag; env_entry *next; }; static bool env_ready = false; static env_entry *env_head = NULL; static env_entry * env_find_key(const char *key) { env_entry *entry = env_head; while (entry) { if (strcmp(entry->key, key) == 0) return entry; entry = entry->next; } return NULL; } static void putenv_internal(char *key, char *value, int flag) { env_entry *entry = env_find_key(key); if (entry) { // get rid of old key/value; if flag is set, then // they're static strings and we don't touch them if (entry->flag == ENV_FREE_BOTH) free (entry->value); if (entry->flag == ENV_FREE_KEY) free (entry->key); } else { entry = new env_entry; entry->next = env_head; env_head = entry; } entry->key = key; entry->value = value; entry->flag = flag; } static void init_initial_env() { env_ready = true; putenv_internal("NSS_DEFAULT_DB_TYPE", "sql", ENV_IS_STATIC); putenv_internal("NSPR_FD_CACHE_SIZE_LOW", "10", ENV_IS_STATIC); putenv_internal("NSPR_FD_CACHE_SIZE_HIGH", "30", ENV_IS_STATIC); putenv_internal("XRE_PROFILE_NAME", "default", ENV_IS_STATIC); putenv_internal("tmp", "/Temp", ENV_IS_STATIC); } void putenv_copy(const char *k, const char *v) { if (!env_ready) init_initial_env(); putenv_internal(strdup(k), strdup(v), ENV_FREE_BOTH); } int putenv(const char *envstr) { if (!env_ready) init_initial_env(); char *key = strdup(envstr); char *value = strchr(key, '='); if (!value) { free(key); return -1; } *value++ = '\0'; putenv_internal(key, value, ENV_FREE_KEY); return 0; } char * getenv(const char* name) { if (!env_ready) init_initial_env(); env_entry *entry = env_find_key(name); if (entry && entry->value[0] != 0) { return entry->value; } return NULL; } char GetEnvironmentVariableW(const WCHAR* lpName, WCHAR* lpBuffer, unsigned long nSize) { char key[256]; int rv = WideCharToMultiByte(CP_ACP, 0, lpName, -1, key, 255, NULL, NULL); if (rv <= 0) return 0; key[rv] = 0; char* val = getenv(key); if (!val) return 0; // strlen(val)+1, let MBTWC convert the nul byte for us return MultiByteToWideChar(CP_ACP, 0, val, strlen(val)+1, lpBuffer, nSize); } char SetEnvironmentVariableW(const WCHAR* name, const WCHAR* value) { char key[256]; char val[256]; int rv; rv = WideCharToMultiByte(CP_ACP, 0, name, -1, key, 255, NULL, NULL); if (rv < 0) return rv; key[rv] = 0; rv = WideCharToMultiByte(CP_ACP, 0, value, -1, val, 255, NULL, NULL); if (rv < 0) return rv; val[rv] = 0; putenv_copy(key, val); return 0; } unsigned int ExpandEnvironmentStringsW(const WCHAR* lpSrc, WCHAR* lpDst, unsigned int nSize) { if ( NULL == lpDst ) return 0; unsigned int size = 0; unsigned int index = 0; unsigned int origLen = wcslen(lpSrc); const WCHAR *pIn = lpSrc; WCHAR *pOut = lpDst; while ( index < origLen ) { if (*pIn != L'%') { // Regular char, copy over if ( size++ < nSize ) *pOut = *pIn, pOut++; index++, pIn++; continue; } // Have a starting '%' - look for matching '%' int envlen = 0; const WCHAR *pTmp = pIn + 1; while ( *pTmp != L'%' && *pTmp != L' ' ) { envlen++, pTmp++; if ( origLen < index + envlen ) { // Ran past end of original while ( envlen-- ) { if ( size++ < nSize ) *pOut = *pIn, pOut++; index++, pIn++; } break; } } if ( *pTmp == L' ' ) { // Need to append through space while ( envlen-- ) { if ( size++ < nSize ) *pOut = *pIn, pOut++; index++, pIn++; } continue; } pIn++; // Move past original % if ( 0 == envlen ) { // Encountered a "%%" - mapping to "%" if ( size++ < nSize ) *pOut = *pIn, pOut++; index += 2, pIn++; } else { // Encountered a "%something%" - mapping "something" char key[256]; int k = WideCharToMultiByte(CP_ACP, 0, pIn, envlen, key, 255, NULL, NULL); key[k] = 0; char *pC = getenv(key); if ( NULL != pC ) { int n = MultiByteToWideChar( CP_ACP, 0, pC, -1, pOut, nSize - size ); if ( n > 0 ) { size += n - 1; // Account for trailing zero pOut += n - 1; } } index += envlen + 2; pIn = ++pTmp; } } if ( size < nSize ) lpDst[size] = 0; return size; } WCHAR * mozce_GetEnvironmentCL() { env_entry *entry = env_head; int len = 0; while (entry) { if (entry->flag == ENV_IS_STATIC) { entry = entry->next; continue; } len += strlen(entry->key); len += strlen(entry->value); // for each env var, 11 chars of " --environ:", 3 chars of '"="', and a null at the end len += 11 + 3 + 1; entry = entry->next; } if (len == 0) { return wcsdup(L""); } wchar_t *env = (wchar_t*) malloc(sizeof(wchar_t) * (len+1)); if (!env) return NULL; entry = env_head; int pos = 0; while (entry) { if (entry->flag == ENV_IS_STATIC) { entry = entry->next; continue; } if (strchr(entry->key, '"') || strchr(entry->value, '"')) { // argh, we don't have a good way of encoding the ", so let's just // ignore this var for now RETAILMSG(1, (L"Skipping environment variable with quote marks in key or value! %S -> %s\r\n", entry->key, entry->value)); entry = entry->next; continue; } wcscpy (env+pos, L" --environ:\""); pos += 12; pos += MultiByteToWideChar(CP_ACP, 0, entry->key, strlen(entry->key), env+pos, len-pos); env[pos++] = '='; pos += MultiByteToWideChar(CP_ACP, 0, entry->value, strlen(entry->value), env+pos, len-pos); env[pos++] = '\"'; entry = entry->next; } env[pos] = '\0'; return env; }