From 8dcf348d06b24de2191ed0b502c0b15bfdc3d0df Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 16 Mar 2010 15:51:53 +0100 Subject: [PATCH 4/9] Add support for Windows CE to the code base. --- dbus/Makefile.am | 7 + dbus/dbus-sysdeps-win.c | 35 ++- dbus/dbus-sysdeps-wince-glue.c | 1004 ++++++++++++++++++++++++++++++++++++++++ dbus/dbus-sysdeps-wince-glue.h | 173 +++++++ dbus/dbus-sysdeps.c | 4 + dbus/dbus-sysdeps.h | 6 + 6 files changed, 1227 insertions(+), 2 deletions(-) create mode 100644 dbus/dbus-sysdeps-wince-glue.c create mode 100644 dbus/dbus-sysdeps-wince-glue.h diff --git a/dbus/Makefile.am b/dbus/Makefile.am index 5afb4f0..e763002 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -76,7 +76,14 @@ DBUS_LIB_arch_sources = \ dbus-server-win.c \ dbus-server-win.h +if DBUS_WINCE +wince_source = dbus-sysdeps-wince-glue.h dbus-sysdeps-wince-glue.c +else +wince_source = +endif + DBUS_SHARED_arch_sources = \ + $(wince_source) \ dbus-file-win.c \ dbus-pipe-win.c \ dbus-sockets-win.h \ diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index faf5df2..7d78b71 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -89,7 +89,11 @@ typedef int socklen_t; void _dbus_win_set_errno (int err) { +#if DBUS_WINCE + SetLastError (err); +#else errno = err; +#endif } @@ -655,6 +659,8 @@ _dbus_pid_for_log (void) return _dbus_getpid (); } + +#ifndef DBUS_WINCE /** Gets our SID * @param points to sid buffer, need to be freed with LocalFree() * @returns process sid @@ -702,6 +708,7 @@ failed: _dbus_verbose("_dbus_getsid() returns %d\n",retval); return retval; } +#endif /************************************************************************ @@ -1986,7 +1993,7 @@ _dbus_delete_file (const DBusString *filename, #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS) -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(DBUS_WINCE) # ifdef BACKTRACES # undef BACKTRACES # endif @@ -2618,8 +2625,24 @@ _dbus_get_standard_session_servicedirs (DBusList **dirs) if (!_dbus_string_init (&servicedir_path)) return FALSE; +#ifdef DBUS_WINCE + { + /* On Windows CE, we adjust datadir dynamically to installation location. */ + const char *data_dir = _dbus_getenv ("DBUS_DATADIR"); + + if (data_dir != NULL) + { + if (!_dbus_string_append (&servicedir_path, data_dir)) + goto oom; + + if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR)) + goto oom; + } + } +#else if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR _DBUS_PATH_SEPARATOR)) goto oom; +#endif common_progs = _dbus_getenv ("CommonProgramFiles"); @@ -2942,7 +2965,15 @@ _dbus_append_keyring_directory_for_credentials (DBusString *directory, } #endif - _dbus_string_init_const (&dotdir, ".dbus-keyrings"); +#ifdef DBUS_WINCE + /* It's not possible to create a .something directory in Windows CE + using the file explorer. */ +#define KEYRING_DIR "dbus-keyrings" +#else +#define KEYRING_DIR ".dbus-keyrings" +#endif + + _dbus_string_init_const (&dotdir, KEYRING_DIR); if (!_dbus_concat_dir_and_file (&homedir, &dotdir)) goto failed; diff --git a/dbus/dbus-sysdeps-wince-glue.c b/dbus/dbus-sysdeps-wince-glue.c new file mode 100644 index 0000000..a2d6626 --- /dev/null +++ b/dbus/dbus-sysdeps-wince-glue.c @@ -0,0 +1,1004 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sysdeps-wince-glue.c Wrappers for Windows CE around system/libc features (internal to D-BUS implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * Copyright (C) 2005 Novell, Inc. + * Copyright (C) 2006 Ralf Habacker + * Copyright (C) 2006 Peter Kümmel + * Copyright (C) 2006 Christian Ehrlicher + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "dbus-internals.h" +#include "dbus-sysdeps.h" +#include "dbus-sysdeps-win.h" + +#include +#include + +/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ +static char * +stpcpy (char *dest, const char *src) +{ + char *d = dest; + const char *s = src; + + do + *d++ = *s; + while (*s++ != '\0'); + + return d - 1; +} + +/* Return a string from the W32 Registry or NULL in case of error. + Caller must release the return value. A NULL for root is an alias + for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */ +static char * +read_w32_registry_string (const char *root, const char *dir, const char *name) +{ + HKEY root_key, key_handle; + DWORD n1, nbytes, type; + char *result = NULL; + + if ( !root ) + root_key = HKEY_CURRENT_USER; + else if ( !strcmp( root, "HKEY_CLASSES_ROOT" ) ) + root_key = HKEY_CLASSES_ROOT; + else if ( !strcmp( root, "HKEY_CURRENT_USER" ) ) + root_key = HKEY_CURRENT_USER; + else if ( !strcmp( root, "HKEY_LOCAL_MACHINE" ) ) + root_key = HKEY_LOCAL_MACHINE; + else if ( !strcmp( root, "HKEY_USERS" ) ) + root_key = HKEY_USERS; + else if ( !strcmp( root, "HKEY_PERFORMANCE_DATA" ) ) + root_key = HKEY_PERFORMANCE_DATA; + else if ( !strcmp( root, "HKEY_CURRENT_CONFIG" ) ) + root_key = HKEY_CURRENT_CONFIG; + else + return NULL; + + if (RegOpenKeyExA (root_key, dir, 0, KEY_READ, &key_handle)) + { + if (root) + return NULL; /* no need for a RegClose, so return direct */ + /* It seems to be common practise to fall back to HKLM. */ + if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle)) + return NULL; /* still no need for a RegClose, so return direct */ + } + + nbytes = 1; + if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) + { + if (root) + goto leave; + /* Try to fallback to HKLM also for a missing value. */ + RegCloseKey (key_handle); + if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle)) + return NULL; /* Nope. */ + if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) + goto leave; + } + n1 = nbytes + 1; + result = malloc (n1); + if (!result) + goto leave; + if (RegQueryValueExA (key_handle, name, 0, &type, result, &n1)) + { + free(result); + result = NULL; + goto leave; + } + result[nbytes] = 0; /* Make sure it is really a string. */ + + leave: + RegCloseKey (key_handle); + return result; +} + + +static char * +find_inst_dir () +{ + return read_w32_registry_string ("HKEY_LOCAL_MACHINE", + "Software\\freedesktop\\DBus", + "Install Directory"); +} + + +static char * +find_env_in_registry (const char *name) +{ + return read_w32_registry_string ("HKEY_LOCAL_MACHINE", + "Software\\freedesktop\\DBus", + name); +} + + +static char * +find_program_in_inst_dir (const char *name) +{ + char *result = NULL; + char *tmp; + + tmp = find_inst_dir (); + if (!tmp) + return NULL; + + result = malloc (strlen (tmp) + 5 + strlen (name) + 1); + if (!result) + { + free (tmp); + return NULL; + } + + strcpy (stpcpy (stpcpy (result, tmp), "\\bin\\"), name); + free (tmp); + + return result; +} + + +static char * +find_inst_subdir (const char *name) +{ + char *result = NULL; + char *tmp; + + tmp = find_inst_dir (); + if (!tmp) + return NULL; + + result = malloc (strlen (tmp) + 1 + strlen (name) + 1); + if (!result) + { + free (tmp); + return NULL; + } + + strcpy (stpcpy (stpcpy (result, tmp), "\\"), name); + free (tmp); + + return result; +} + + +static char * +find_my_documents_folder () +{ + char dir[MAX_PATH]; + char *result; + + dir[0] = '\0'; + /* May return false even if successful. */ + SHGetSpecialFolderPathA (0, dir, CSIDL_PERSONAL, 0); + if (dir[0] == '\0') + return NULL; + + result = malloc (strlen (dir) + 1); + if (!result) + return NULL; + strcpy (result, dir); + return result; +} + + +#define MAX_ENV 30 + +char *environ[MAX_ENV + 1]; + +char * +getenv (const char *name) +{ + static char *past_result; + char **envp; + int idx; + + if (past_result) + { + free (past_result); + past_result = NULL; + } + + if (! strcmp (name, "DBUS_VERBOSE")) + return past_result = find_env_in_registry ("Verbose"); + else if (! strcmp (name, "HOMEPATH")) + return past_result = find_my_documents_folder (); + else if (! strcmp (name, "DBUS_DATADIR")) + return past_result = find_inst_subdir ("share"); + + for (envp = environ; *envp != 0; envp++) + { + const char *varp = name; + char *ep = *envp; + int same_name = 0; + + while (*varp == *ep && *varp != '\0') + { + ++ep; + ++varp; + }; + + if (*varp == '\0' && *ep == '=') + return ep + 1; + } + + return NULL; +} + + +int +putenv (char *str) +{ + char **envp; + int idx; + for (envp = environ; *envp != 0; envp++) + { + char *varp = str; + char *ep = *envp; + int same_name = 0; + + while (*varp == *ep && *varp != '\0') + { + if (*varp == '=') + same_name = 1; + ++ep; + ++varp; + }; + + if (*varp == *ep && *varp == '\0') + return 0; + if (same_name) + { + *envp = str; + return 0; + } + } + + idx = envp - environ; + if (idx > MAX_ENV) + { + _dbus_win_set_errno (ENOMEM); + return -1; + } + + environ[idx] = str; + return 0; +} + + +clock_t +clock (void) +{ + return GetTickCount (); +} + + +void +GetSystemTimeAsFileTime (LPFILETIME ftp) +{ + SYSTEMTIME st; + GetSystemTime (&st); + SystemTimeToFileTime (&st, ftp); +} + + +unsigned char* +_mbsrchr (const unsigned char* str, unsigned int ch) +{ + /* FIXME. This is not multi-byte safe. */ + return strrchr (str, ch); +} + + +HANDLE OpenFileMappingA(DWORD dwDesiredAccess, + BOOL bInheritHandle, + LPCSTR lpName) +{ + DWORD flProtect = 0; + HANDLE hMapping; + + if (dwDesiredAccess & FILE_MAP_READ) + flProtect |= PAGE_READONLY; + + if (dwDesiredAccess & FILE_MAP_WRITE) + flProtect |= PAGE_READWRITE; + + SetLastError (0); + hMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, + NULL, flProtect, 0, 0, lpName); + if (hMapping != INVALID_HANDLE_VALUE) + { + /* Just in case Windows CE changes its behaviour, we check for + the right error value here. */ + if (GetLastError () != ERROR_ALREADY_EXISTS) + { + CloseHandle(hMapping); + hMapping = INVALID_HANDLE_VALUE; + } + } + return hMapping; +} + + +BOOL +MoveFileExA (LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags) +{ + _dbus_assert (dwFlags == MOVEFILE_REPLACE_EXISTING); + + if (_dbus_file_exists (lpNewFileName)) + { + BOOL result = DeleteFileA (lpNewFileName); + if (result == 0) + return FALSE; + } + return MoveFileA (lpExistingFileName, lpNewFileName); +} + + +BOOL +SetHandleInformation (HANDLE hObject, DWORD dwMask, DWORD dwFlags) +{ + _dbus_assert (dwMask == (HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE)); + + /* Not supported on Windows CE, this will throw a warning. If the + warning is obnoxious, we may have to disable it. */ + return 0; +} + + +DWORD +SearchPathA (LPCSTR lpPath, LPCSTR lpFileName, LPCSTR lpExtension, + DWORD nBufferLength, LPSTR lpBuffer, LPSTR* lpFilePart) +{ + char *filename; + char *filepart; + int filename_len; + + _dbus_assert (lpPath == NULL); + _dbus_assert (lpExtension == NULL); + + filename = find_program_in_inst_dir (lpFileName); + if (!filename) + { + SetLastError (ERROR_FILE_NOT_FOUND); + return 0; + } + + filename_len = strlen (filename) + 1; + if (filename_len > nBufferLength) + { + free (filename); + return filename_len; + } + + strcpy (lpBuffer, filename); + free (filename); + + filepart = _mbsrchr (lpBuffer, '\\'); + if (!filepart) + filepart = lpBuffer; + *lpFilePart = filepart; + + return filename_len - 1; +} + + +/** Gets our SID + * @param points to sid buffer, need to be freed with LocalFree() + * @returns process sid + */ +dbus_bool_t +_dbus_getsid(char **sid) +{ + /* There is nothing like this on Windows CE, so we fake it. */ + static const char asid[] = "S-1-5-21-515967899-920026266-1708537768-1000"; + char *buf = LocalAlloc (LMEM_FIXED, sizeof (asid)); + if (!buf) + { + _dbus_win_warn_win_error ("LocalAlloc failed", GetLastError ()); + return FALSE; + } + + memcpy (buf, asid, sizeof (asid)); + *sid = buf; + return TRUE; + +} + + +HANDLE +CreateFileA (LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSharedMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + wchar_t *filename; + HANDLE result; + int err; + + filename = _dbus_win_utf8_to_utf16 (lpFileName, NULL); + if (!filename) + return INVALID_HANDLE_VALUE; + + result = CreateFileW (filename, dwDesiredAccess, dwSharedMode, + lpSecurityAttributes, dwCreationDisposition, + dwFlagsAndAttributes, hTemplateFile); + + err = GetLastError (); + dbus_free (filename); + SetLastError (err); + return result; +} + + +BOOL +DeleteFileA (LPCSTR lpFileName) +{ + wchar_t *filename; + BOOL result; + int err; + + filename = _dbus_win_utf8_to_utf16 (lpFileName, NULL); + if (!filename) + return FALSE; + + result = DeleteFileW (filename); + + err = GetLastError (); + dbus_free (filename); + SetLastError (err); + return result; +} + + +BOOL +MoveFileA (LPCSTR lpExistingFileName, LPCSTR lpNewFileName) +{ + wchar_t *existing_filename; + wchar_t *new_filename; + BOOL result; + int err; + + existing_filename = _dbus_win_utf8_to_utf16 (lpExistingFileName, NULL); + if (! existing_filename) + return FALSE; + + new_filename = _dbus_win_utf8_to_utf16 (lpNewFileName, NULL); + if (! new_filename) + { + dbus_free (existing_filename); + return FALSE; + } + + result = MoveFileW (existing_filename, new_filename); + + err = GetLastError (); + dbus_free (existing_filename); + dbus_free (new_filename); + SetLastError (err); + return result; +} + + +DWORD +GetFileAttributesA(LPCSTR lpFileName) +{ + wchar_t *filename; + DWORD result; + int err; + + filename = _dbus_win_utf8_to_utf16 (lpFileName, NULL); + if (!filename) + return INVALID_FILE_ATTRIBUTES; + + result = GetFileAttributesW (filename); + + err = GetLastError (); + dbus_free (filename); + SetLastError (err); + return result; +} + + +BOOL +GetFileAttributesExA (LPCSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, + PVOID lpFileInformation) +{ + wchar_t *filename; + DWORD result; + int err; + + filename = _dbus_win_utf8_to_utf16 (lpFileName, NULL); + if (!filename) + return INVALID_FILE_ATTRIBUTES; + + result = GetFileAttributesExW (filename, fInfoLevelId, lpFileInformation); + + err = GetLastError (); + dbus_free (filename); + SetLastError (err); + return result; +} + + +HANDLE +CreateFileMappingA (HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes, + DWORD flProtect, DWORD dwMaximumSizeHigh, + DWORD dwMaximumSizeLow, LPCSTR lpName) +{ + wchar_t *name; + HANDLE result; + int err; + + if (lpName) + { + name = _dbus_win_utf8_to_utf16 (lpName, NULL); + if (!name) + return INVALID_HANDLE_VALUE; + } + else + name = NULL; + + result = CreateFileMappingW (hFile, lpAttributes, flProtect, + dwMaximumSizeHigh, dwMaximumSizeLow, + name); + + err = GetLastError (); + dbus_free (name); + SetLastError (err); + return result; +} + + +BOOL +CreateDirectoryA (LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes) +{ + wchar_t *pathname; + BOOL result; + int err; + + pathname = _dbus_win_utf8_to_utf16 (lpPathName, NULL); + if (!pathname) + return FALSE; + + result = CreateDirectoryW (pathname, lpSecurityAttributes); + + err = GetLastError (); + dbus_free (pathname); + SetLastError (err); + return result; +} + + +BOOL +RemoveDirectoryA (LPCSTR lpPathName) +{ + wchar_t *pathname; + BOOL result; + int err; + + pathname = _dbus_win_utf8_to_utf16 (lpPathName, NULL); + if (!pathname) + return FALSE; + + result = RemoveDirectoryW (pathname); + + err = GetLastError (); + dbus_free (pathname); + SetLastError (err); + return result; +} + + +static BOOL +convert_find_data (LPWIN32_FIND_DATAW fdw, LPWIN32_FIND_DATAA fda) +{ + char *filename; + int len; + + fda->dwFileAttributes = fdw->dwFileAttributes; + fda->ftCreationTime = fdw->ftCreationTime; + fda->ftLastAccessTime = fdw->ftLastAccessTime; + fda->ftLastWriteTime = fdw->ftLastWriteTime; + fda->nFileSizeHigh = fdw->nFileSizeHigh; + fda->nFileSizeLow = fdw->nFileSizeLow; + + filename = _dbus_win_utf16_to_utf8 (fdw->cFileName, NULL); + if (!filename) + return FALSE; + + len = sizeof (fda->cFileName); + strncpy (fda->cFileName, filename, len); + fda->cFileName[len - 1] = '\0'; + + return TRUE; +} + + +HANDLE +FindFirstFileA (LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) +{ + wchar_t *pathname; + WIN32_FIND_DATAW find_file_data; + HANDLE result; + int err; + + pathname = _dbus_win_utf8_to_utf16 (lpFileName, NULL); + if (!pathname) + return INVALID_HANDLE_VALUE; + + result = FindFirstFileW (pathname, &find_file_data); + if (result != INVALID_HANDLE_VALUE) + { + BOOL res = convert_find_data (&find_file_data, lpFindFileData); + if (! res) + { + err = GetLastError (); + FindClose (result); + SetLastError (err); + result = INVALID_HANDLE_VALUE; + } + } + + err = GetLastError (); + dbus_free (pathname); + SetLastError (err); + return result; +} + + +BOOL +FindNextFileA (HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData) +{ + WIN32_FIND_DATAW find_file_data; + BOOL result; + int err; + + result = FindNextFileW (hFindFile, &find_file_data); + if (result) + result = convert_find_data (&find_file_data, lpFindFileData); + + return result; +} + + +HANDLE +CreateMutexA (LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, + LPCSTR lpName) +{ + wchar_t *name; + HANDLE result; + int err; + + if (lpName) + { + name = _dbus_win_utf8_to_utf16 (lpName, NULL); + if (!name) + return INVALID_HANDLE_VALUE; + } + else + name = NULL; + + result = CreateMutexW (lpMutexAttributes, bInitialOwner, name); + + err = GetLastError (); + dbus_free (name); + SetLastError (err); + return result; +} + + +BOOL +CreateProcessA (LPCSTR pszImageName, LPSTR pszCmdLine, + LPSECURITY_ATTRIBUTES psaProcess, + LPSECURITY_ATTRIBUTES psaThread, BOOL fInheritHandles, + DWORD fdwCreate, PVOID pvEnvironment, LPCSTR pszCurDir, + LPSTARTUPINFOA psiStartInfo, + LPPROCESS_INFORMATION pProcInfo) +{ + wchar_t *image_name = NULL; + wchar_t *cmd_line = NULL; + BOOL result; + int err; + + _dbus_assert (psaProcess == NULL); + _dbus_assert (psaThread == NULL); + _dbus_assert (fInheritHandles == FALSE); + _dbus_assert (pvEnvironment == NULL); + _dbus_assert (pszCurDir == NULL); + /* psiStartInfo is generally not NULL. */ + + if (pszImageName) + { + image_name = _dbus_win_utf8_to_utf16 (pszImageName, NULL); + if (!image_name) + return 0; + } + if (pszCmdLine) + { + cmd_line = _dbus_win_utf8_to_utf16 (pszCmdLine, NULL); + if (!cmd_line) + { + if (image_name) + dbus_free (image_name); + return 0; + } + } + + result = CreateProcessW (image_name, cmd_line, NULL, NULL, FALSE, + fdwCreate, NULL, NULL, NULL, pProcInfo); + + err = GetLastError (); + dbus_free (image_name); + dbus_free (cmd_line); + SetLastError (err); + return result; +} + + +LONG +RegOpenKeyExA (HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, + REGSAM samDesired, PHKEY phkResult) +{ + wchar_t *subkey; + LONG result; + int err; + + if (lpSubKey) + { + subkey = _dbus_win_utf8_to_utf16 (lpSubKey, NULL); + if (!subkey) + return 0; + } + else + subkey = NULL; + + result = RegOpenKeyEx (hKey, subkey, ulOptions, samDesired, phkResult); + + err = GetLastError (); + dbus_free (subkey); + SetLastError (err); + return result; +} + + +LONG +RegQueryValueExA (HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, + LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) +{ + wchar_t *name; + LONG err; + BYTE *data; + DWORD data_len; + DWORD type; + + if (lpValueName) + { + name = _dbus_win_utf8_to_utf16 (lpValueName, NULL); + if (!name) + return GetLastError (); + } + else + name = NULL; + + data_len = 0; + err = RegQueryValueExW (hKey, name, lpReserved, lpType, NULL, &data_len); + if (err || !lpcbData) + { + dbus_free (name); + return err; + } + + data = malloc (data_len + sizeof (wchar_t)); + if (!data) + { + dbus_free (name); + return ERROR_NOT_ENOUGH_MEMORY; + } + + err = RegQueryValueExW (hKey, name, lpReserved, &type, data, &data_len); + if (lpType) + *lpType = type; + dbus_free (name); + /* If err is ERROR_MORE_DATA, there probably was a race condition. + We can punt this to the caller just as well. */ + if (err) + return err; + + /* NOTE: REG_MULTI_SZ and REG_EXPAND_SZ not supported, because they + are not needed in this module. */ + if (type == REG_SZ) + { + char *data_c; + int data_c_len; + + /* This is valid since we allocated one more above. */ + data[data_len] = '\0'; + data[data_len + 1] = '\0'; + + data_c = _dbus_win_utf16_to_utf8 ((wchar_t*) data, NULL); + if (!data_c) + return GetLastError(); + + data_c_len = strlen (data_c) + 1; + _dbus_assert (data_c_len <= data_len + sizeof (wchar_t)); + memcpy (data, data_c, data_c_len); + data_len = data_c_len; + dbus_free (data_c); + } + + /* DATA and DATA_LEN now contain the result. */ + if (lpData) + { + if (data_len > *lpcbData) + err = ERROR_MORE_DATA; + else + memcpy (lpData, data, data_len); + } + *lpcbData = data_len; + return err; +} + + +DWORD +FormatMessageA (DWORD dwFlags, PCVOID lpSource, DWORD dwMessageId, + DWORD dwLanguageId, LPSTR lpBuffer, DWORD nSize, + va_list* Arguments) +{ + LPWSTR buffer_w = NULL; + LPSTR buffer_c; + DWORD len; + char *buffer_new; + DWORD buffer_new_len; + BOOL buffer_w_free; + + len = FormatMessageW (dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, + lpSource, dwMessageId, dwLanguageId, + (LPWSTR) &buffer_w, 0, Arguments); + if (len == 0) + return 0; + + buffer_c = _dbus_win_utf16_to_utf8 (buffer_w, NULL); + if (! buffer_c) + { + LocalFree (buffer_w); + return 0; + } + + if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) + { + /* We need to return a buffer that's freeable with LocalFree. */ + buffer_new = (char *) buffer_w; + buffer_new_len = sizeof (wchar_t) * (len + 1); + buffer_w_free = FALSE; + /* Avoid alignment issue by using memcpy. */ + memcpy (lpBuffer, &buffer_new, sizeof (buffer_new)); + } + else + { + buffer_new = lpBuffer; + buffer_new_len = nSize; + buffer_w_free = TRUE; + } + + strncpy (buffer_new, buffer_c, buffer_new_len); + dbus_free (buffer_c); + buffer_new[buffer_new_len - 1] = '\0'; + if (buffer_w_free) + LocalFree (buffer_w); + + /* strlen is correct (not _mbstrlen), because we want storage and + not string length. */ + return strlen (buffer_new); +} + + +DWORD +GetModuleFileNameA (HINSTANCE hModule, LPSTR lpFilename, DWORD nSize) +{ + wchar_t filename_w[nSize]; + char *filename_c; + DWORD len; + + len = GetModuleFileNameW (hModule, filename_w, nSize); + if (len == 0) + return 0; + + filename_w[nSize - 1] = '\0'; + filename_c = _dbus_win_utf16_to_utf8 (filename_w, NULL); + if (! filename_c) + return 0; + + strncpy (lpFilename, filename_c, nSize); + dbus_free (filename_c); + lpFilename[nSize - 1] = '\0'; + /* strlen is correct (not _mbstrlen), because we want storage and + not string length. */ + return strlen (lpFilename); +} + + +DWORD +GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer) +{ + wchar_t dummy[1]; + DWORD len; + + len = GetTempPathW (0, dummy); + if (len == 0) + return 0; + + /* Better be safe than sorry. MSDN doesn't say if len is with or + without terminating 0. */ + len++; + + { + wchar_t buffer_w[len]; + DWORD len_w; + char *buffer_c; + DWORD len_c; + + len_w = GetTempPathW (len, buffer_w); + /* Give up if we still can't get at it. */ + if (len_w == 0 || len_w >= len) + return 0; + + /* Better be really safe. */ + buffer_w[len_w] = '\0'; + + buffer_c = _dbus_win_utf16_to_utf8 (buffer_w, NULL); + if (! buffer_c) + return 0; + + /* strlen is correct (not _mbstrlen), because we want storage and + not string length. */ + len_c = strlen (buffer_c) + 1; + if (len_c > nBufferLength) + return len_c; + + strcpy (lpBuffer, buffer_c); + dbus_free (buffer_c); + return len_c - 1; + } +} + + +BOOL +SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder, + BOOL fCreate) +{ + wchar_t path[MAX_PATH]; + char *path_c; + BOOL result; + + path[0] = (wchar_t) 0; + result = SHGetSpecialFolderPathW (hwndOwner, path, nFolder, fCreate); + /* Note: May return false even if succeeds. */ + + path[MAX_PATH - 1] = (wchar_t) 0; + path_c = _dbus_win_utf16_to_utf8 (path, NULL); + if (! path_c) + return 0; + + strncpy (lpszPath, path_c, MAX_PATH); + dbus_free (path_c); + lpszPath[MAX_PATH - 1] = '\0'; + return result; +} diff --git a/dbus/dbus-sysdeps-wince-glue.h b/dbus/dbus-sysdeps-wince-glue.h new file mode 100644 index 0000000..da600ca --- /dev/null +++ b/dbus/dbus-sysdeps-wince-glue.h @@ -0,0 +1,173 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sysdeps-wince-glue.h Emulation of system/libc features for Windows CE (internal to D-Bus implementation) + * + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_SYSDEPS_WINCE_GLUE_H +#define DBUS_SYSDEPS_WINCE_GLUE_H + +#include +#include + +#include +#undef interface +/* shlobj.h declares these only for _WIN32_IE that we don't want to define. + In any case, with mingw32ce we only get a SHGetSpecialFolderPath. */ +#define SHGetSpecialFolderPathW SHGetSpecialFolderPath +BOOL WINAPI SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL); +BOOL WINAPI SHGetSpecialFolderPathW(HWND,LPWSTR,int,BOOL); + + +DBUS_BEGIN_DECLS + +/* Seriously. Windows CE does not have errno. Don't you hate it when + that happens? */ +#define errno (GetLastError ()) + +#define ENOENT ERROR_FILE_NOT_FOUND +#define EMFILE ERROR_TOO_MANY_OPEN_FILES +#define EACCES ERROR_ACCESS_DENIED +#define EBADF ERROR_INVALID_HANDLE +#define ENOMEM ERROR_NOT_ENOUGH_MEMORY +#define EXDEV ERROR_NOT_SAME_DEVICE +#define ENFILE ERROR_NO_MORE_FILES +#define EROFS ERROR_WRITE_PROTECT +#define ENOLCK ERROR_SHARING_BUFFER_EXCEEDED +#define ENOSYS ERROR_NOT_SUPPORTED +#define EEXIST ERROR_FILE_EXISTS +#define EPERM ERROR_CANNOT_MAKE +#define EINVAL ERROR_INVALID_PARAMETER +#define EINTR ERROR_INVALID_AT_INTERRUPT_TIME +#define EPIPE ERROR_BROKEN_PIPE +#define ENOSPC ERROR_DISK_FULL +#define ENOTEMPTY ERROR_DIR_NOT_EMPTY +#define EBUSY ERROR_BUSY +#define ENAMETOOLONG ERROR_FILENAME_EXCED_RANGE +#define EAGAIN ERROR_MORE_DATA +#define ENOTDIR ERROR_DIRECTORY +#define ERANGE ERROR_ARITHMETIC_OVERFLOW +#define ENXIO ERROR_FILE_INVALID +#define EFAULT ERROR_PROCESS_ABORTED +#define EIO ERROR_IO_DEVICE +#define EDEADLOCK ERROR_POSSIBLE_DEADLOCK +#define ENODEV ERROR_BAD_DEVICE + +/* Windows CE is missing more stuff that is pretty standard. */ + +#define environ _dbus_wince_environ +extern char *environ[]; + +#define getenv _dbus_wince_getenv +char *getenv (const char *name); + +#define putenv _dbus_wince_putenv +int putenv (char *str); + +#define clock _dbus_wince_clock +clock_t clock (void); + + +/* Windows CE is missing some Windows functions that we want. */ + +#define GetSystemTimeAsFileTime _dbus_wince_GetSystemTimeAsFileTime +void GetSystemTimeAsFileTime (LPFILETIME ftp); + +#define _mbsrchr _dbus_wince_mbsrchr +unsigned char* _mbsrchr (const unsigned char*, unsigned int); + +#define OpenFileMappingA _dbus_wince_OpenFileMappingA +HANDLE OpenFileMappingA(DWORD,BOOL,LPCSTR); + +#define MoveFileExA _dbus_wince_MoveFileExA +BOOL MoveFileExA(LPCSTR,LPCSTR,DWORD); + +#define SetHandleInformation _dbus_wince_SetHandleInformation +BOOL SetHandleInformation(HANDLE,DWORD,DWORD); + +#define SearchPathA _dbus_wince_SearchPathA +DWORD SearchPathA(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*); + +/* Instead of emulating all functions needed for this, we replace the + whole thing. */ +dbus_bool_t _dbus_getsid(char **sid); + + +/* Windows CE does only have the UNICODE interfaces (FooW), but we + want to use the ASCII interfaces (FooA). We implement them + here. */ + +#define CreateFileA _dbus_wince_CreateFileA +HANDLE CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE); + +#define DeleteFileA _dbus_wince_DeleteFileA +BOOL DeleteFileA(LPCSTR); + +#define GetFileAttributesA _dbus_wince_GetFileAttributesA +DWORD GetFileAttributesA(LPCSTR); + +#define GetFileAttributesExA _dbus_wince_GetFileAttributesExA +BOOL GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,PVOID); + +#define CreateFileMappingA _dbus_wince_CreateFileMappingA +HANDLE CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR); + +#define CreateDirectoryA _dbus_wince_CreateDirectoryA +BOOL CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES); + +#define RemoveDirectoryA _dbus_wince_RemoveDirectoryA +BOOL RemoveDirectoryA(LPCSTR); + +#define FindFirstFileA _dbus_wince_FindFirstFileA +HANDLE FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA); + +#define FindNextFileA _dbus_wince_FindNextFileA +BOOL FindNextFileA(HANDLE,LPWIN32_FIND_DATAA); + +#define CreateMutexA _dbus_wince_CreateMutexA +HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR); + +#define CreateProcessA _dbus_wince_CreateProcessA +BOOL CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION); + +#define RegOpenKeyExA _dbus_wince_RegOpenKeyExA +LONG RegOpenKeyExA(HKEY,LPCSTR,DWORD,REGSAM,PHKEY); + +#define RegQueryValueExA _dbus_wince_RegQueryValueExA +LONG WINAPI RegQueryValueExA(HKEY,LPCSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); + + +#define FormatMessageA _dbus_wince_FormatMessageA +DWORD FormatMessageA(DWORD,PCVOID,DWORD,DWORD,LPSTR,DWORD,va_list*); + +#define GetModuleFileNameA _dbus_wince_GetModuleFileNameA +DWORD GetModuleFileNameA(HINSTANCE,LPSTR,DWORD); + +#define GetTempPathA _dbus_wince_GetTempPathA +DWORD GetTempPathA(DWORD,LPSTR); + +#define SHGetSpecialFolderPathA _dbus_wince_SHGetSpecialFolderPathA +BOOL SHGetSpecialFolderPathA(HWND,LPSTR,int,BOOL); + + +DBUS_END_DECLS + +#endif /* DBUS_SYSDEPS_WINCE_GLUE_H */ diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index a22989d..bdf33c5 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -1009,7 +1009,11 @@ _dbus_error_from_system_errno (void) void _dbus_set_errno_to_zero (void) { +#if DBUS_WINCE + SetLastError (0); +#else errno = 0; +#endif } /** diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 33130f8..9729d1b 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -47,6 +47,12 @@ #include #endif +#ifdef DBUS_WINCE +/* Windows CE lacks some system functions (such as errno and clock). + We bring them in here. */ +#include "dbus-sysdeps-wince-glue.h" +#endif + DBUS_BEGIN_DECLS #ifdef DBUS_WIN -- 1.6.3.3