X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-sysdeps-util-win.c;h=71ed8b79c3711a03c20894f291e6faa68a40b1f6;hb=b7a91bfd463fdef233cc48c7e1b09793e7fe56a7;hp=fa622010764476beec38878975a8d0a5d8b0f93f;hpb=3410f135ae3d50d2244f8c3acdb62925e9726ab5;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c index fa62201..71ed8b7 100644 --- a/dbus/dbus-sysdeps-util-win.c +++ b/dbus/dbus-sysdeps-util-win.c @@ -1,4 +1,4 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-sysdeps-util.c Would be in dbus-sysdeps.c, but not used in libdbus * * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. @@ -18,20 +18,11 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ -/* #define ENABLE_DBUSGROUPINFO */ - -#ifdef ENABLE_DBUSGROUPINFO -typedef struct { - int gid; - char *groupname; -} DBusGroupInfo; -#endif - -#undef open +#include #define STRSAFE_NO_DEPRECATE @@ -41,50 +32,38 @@ typedef struct { #include "dbus-string.h" #include "dbus-sysdeps.h" #include "dbus-sysdeps-win.h" +#include "dbus-sockets-win.h" #include "dbus-memory.h" - -#include -#include -#include +#include "dbus-pipe.h" #include #include -#include +#if HAVE_ERRNO_H #include +#endif +#include // WSA error codes -#if defined __MINGW32__ || (defined _MSC_VER && _MSC_VER <= 1310) -/* save string functions version - using DBusString needs to much time because of uncommon api -*/ -#define errno_t int - -errno_t strcat_s(char *dest, size_t size, char *src) -{ - _dbus_assert(strlen(dest) + strlen(src) +1 <= size); - strcat(dest,src); - return 0; -} - -errno_t strcpy_s(char *dest, size_t size, char *src) -{ - _dbus_assert(strlen(src) +1 <= size); - strcpy(dest,src); - return 0; -} +#ifndef DBUS_WINCE +#include +#include +#include #endif + /** * Does the chdir, fork, setsid, etc. to become a daemon process. * * @param pidfile #NULL, or pidfile to create - * @param print_pid_fd file descriptor to print daemon's pid to, or -1 for none + * @param print_pid_pipe file descriptor to print daemon's pid to, or -1 for none * @param error return location for errors + * @param keep_umask #TRUE to keep the original umask * @returns #FALSE on failure */ dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, DBusPipe *print_pid_pipe, - DBusError *error) + DBusError *error, + dbus_bool_t keep_umask) { return TRUE; } @@ -97,48 +76,76 @@ _dbus_become_daemon (const DBusString *pidfile, * @param error return location for errors * @returns #FALSE on failure */ -dbus_bool_t +static dbus_bool_t _dbus_write_pid_file (const DBusString *filename, unsigned long pid, DBusError *error) { const char *cfilename; - DBusFile file; - FILE *f; + HANDLE hnd; + char pidstr[20]; + int total; + int bytes_to_write; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); cfilename = _dbus_string_get_const_data (filename); - if (!_dbus_file_open(&file, cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644)) + hnd = CreateFileA (cfilename, GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, + INVALID_HANDLE_VALUE); + if (hnd == INVALID_HANDLE_VALUE) { - dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to open \"%s\": %s", cfilename, - _dbus_strerror (errno)); + char *emsg = _dbus_win_error_string (GetLastError ()); + dbus_set_error (error, _dbus_win_error_from_last_error (), + "Could not create PID file %s: %s", + cfilename, emsg); + _dbus_win_free_error_string (emsg); return FALSE; } - if ((f = fdopen (file.FDATA, "w")) == NULL) + if (snprintf (pidstr, sizeof (pidstr), "%lu\n", pid) < 0) { - dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to fdopen fd %d: %s", file.FDATA, _dbus_strerror (errno)); - _dbus_file_close (&file, NULL); + dbus_set_error (error, _dbus_error_from_system_errno (), + "Failed to format PID for \"%s\": %s", cfilename, + _dbus_strerror_from_errno ()); + CloseHandle (hnd); return FALSE; } - if (fprintf (f, "%lu\n", pid) < 0) + total = 0; + bytes_to_write = strlen (pidstr);; + + while (total < bytes_to_write) { - dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to write to \"%s\": %s", cfilename, - _dbus_strerror (errno)); + DWORD bytes_written; + BOOL res; - fclose (f); - return FALSE; + res = WriteFile (hnd, pidstr + total, bytes_to_write - total, + &bytes_written, NULL); + + if (res == 0 || bytes_written <= 0) + { + char *emsg = _dbus_win_error_string (GetLastError ()); + dbus_set_error (error, _dbus_win_error_from_last_error (), + "Could not write to %s: %s", cfilename, emsg); + _dbus_win_free_error_string (emsg); + CloseHandle (hnd); + return FALSE; + } + + total += bytes_written; } - if (fclose (f) == EOF) + if (CloseHandle (hnd) == 0) { - dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to close \"%s\": %s", cfilename, - _dbus_strerror (errno)); + char *emsg = _dbus_win_error_string (GetLastError ()); + dbus_set_error (error, _dbus_win_error_from_last_error (), + "Could not close file %s: %s", + cfilename, emsg); + _dbus_win_free_error_string (emsg); + return FALSE; } @@ -146,6 +153,84 @@ _dbus_write_pid_file (const DBusString *filename, } /** + * Writes the given pid_to_write to a pidfile (if non-NULL) and/or to a + * pipe (if non-NULL). Does nothing if pidfile and print_pid_pipe are both + * NULL. + * + * @param pidfile the file to write to or #NULL + * @param print_pid_pipe the pipe to write to or #NULL + * @param pid_to_write the pid to write out + * @param error error on failure + * @returns FALSE if error is set + */ +dbus_bool_t +_dbus_write_pid_to_file_and_pipe (const DBusString *pidfile, + DBusPipe *print_pid_pipe, + dbus_pid_t pid_to_write, + DBusError *error) +{ + if (pidfile) + { + _dbus_verbose ("writing pid file %s\n", _dbus_string_get_const_data (pidfile)); + if (!_dbus_write_pid_file (pidfile, + pid_to_write, + error)) + { + _dbus_verbose ("pid file write failed\n"); + _DBUS_ASSERT_ERROR_IS_SET(error); + return FALSE; + } + } + else + { + _dbus_verbose ("No pid file requested\n"); + } + + if (print_pid_pipe != NULL && _dbus_pipe_is_valid (print_pid_pipe)) + { + DBusString pid; + int bytes; + + _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd); + + if (!_dbus_string_init (&pid)) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + if (!_dbus_string_append_int (&pid, pid_to_write) || + !_dbus_string_append (&pid, "\n")) + { + _dbus_string_free (&pid); + _DBUS_SET_OOM (error); + return FALSE; + } + + bytes = _dbus_string_get_length (&pid); + if (_dbus_pipe_write (print_pid_pipe, &pid, 0, bytes, error) != bytes) + { + /* _dbus_pipe_write sets error only on failure, not short write */ + if (error != NULL && !dbus_error_is_set(error)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Printing message bus PID: did not write enough bytes\n"); + } + _dbus_string_free (&pid); + return FALSE; + } + + _dbus_string_free (&pid); + } + else + { + _dbus_verbose ("No pid pipe to write to\n"); + } + + return TRUE; +} + +/** * Verify that after the fork we can successfully change to this user. * * @param user the username given in the daemon configuration @@ -171,133 +256,64 @@ _dbus_change_to_daemon_user (const char *user, return TRUE; } -/** - * Changes the user and group the bus is running as. - * - * @param uid the new user ID - * @param gid the new group ID - * @param error return location for errors - * @returns #FALSE on failure - */ -dbus_bool_t -_dbus_change_identity (dbus_uid_t uid, - dbus_gid_t gid, - DBusError *error) +void +_dbus_request_file_descriptor_limit (unsigned int limit) { - return TRUE; } -/** Checks if user is at the console -* -* @param username user to check -* @param error return location for errors -* @returns #TRUE is the user is at the consolei and there are no errors -*/ -dbus_bool_t -_dbus_user_at_console(const char *username, - DBusError *error) +void +_dbus_init_system_log (dbus_bool_t is_daemon) { -#ifdef DBUS_WINCE - return TRUE; -#else - dbus_bool_t retval = FALSE; - wchar_t *wusername; - DWORD sid_length; - PSID user_sid, console_user_sid; - HWINSTA winsta; - - wusername = _dbus_win_utf8_to_utf16 (username, error); - if (!wusername) - return FALSE; - - if (!_dbus_win_account_to_sid (wusername, &user_sid, error)) - goto out0; - - /* Now we have the SID for username. Get the SID of the - * user at the "console" (window station WinSta0) - */ - if (!(winsta = OpenWindowStation ("WinSta0", FALSE, READ_CONTROL))) - { - _dbus_win_set_error_from_win_error (error, GetLastError ()); - goto out2; - } - - sid_length = 0; - GetUserObjectInformation (winsta, UOI_USER_SID, - NULL, 0, &sid_length); - if (sid_length == 0) - { - /* Nobody is logged on */ - goto out2; - } - - if (sid_length < 0 || sid_length > 1000) - { - dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID length"); - goto out3; - } - - console_user_sid = dbus_malloc (sid_length); - if (!console_user_sid) - { - _DBUS_SET_OOM (error); - goto out3; - } - - if (!GetUserObjectInformation (winsta, UOI_USER_SID, - console_user_sid, sid_length, &sid_length)) - { - _dbus_win_set_error_from_win_error (error, GetLastError ()); - goto out4; - } - - if (!IsValidSid (console_user_sid)) - { - dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID"); - goto out4; - } - - retval = EqualSid (user_sid, console_user_sid); - -out4: - dbus_free (console_user_sid); -out3: - CloseWindowStation (winsta); -out2: - dbus_free (user_sid); -out0: - dbus_free (wusername); - - return retval; -#endif //DBUS_WINCE + /* OutputDebugStringA doesn't need any special initialization, do nothing */ } /** - * Removes a directory; Directory must be empty - * - * @param filename directory filename - * @param error initialized error object - * @returns #TRUE on success + * Log a message to the system log file (e.g. syslog on Unix). + * + * @param severity a severity value + * @param msg a printf-style format string */ -dbus_bool_t -_dbus_delete_directory (const DBusString *filename, - DBusError *error) +void +_dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...) { - const char *filename_c; + va_list args; - _DBUS_ASSERT_ERROR_IS_CLEAR (error); + va_start (args, msg); - filename_c = _dbus_string_get_const_data (filename); + _dbus_system_logv (severity, msg, args); - if (rmdir (filename_c) != 0) - { - dbus_set_error (error, DBUS_ERROR_FAILED, - "Failed to remove directory %s: %s\n", - filename_c, _dbus_strerror (errno)); - return FALSE; - } + va_end (args); +} - return TRUE; +/** + * Log a message to the system log file (e.g. syslog on Unix). + * + * @param severity a severity value + * @param msg a printf-style format string + * @param args arguments for the format string + * + * If the FATAL severity is given, this function will terminate the program + * with an error code. + */ +void +_dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args) +{ + char *s = ""; + char buf[1024]; + + switch(severity) + { + case DBUS_SYSTEM_LOG_INFO: s = "info"; break; + case DBUS_SYSTEM_LOG_SECURITY: s = "security"; break; + case DBUS_SYSTEM_LOG_FATAL: s = "fatal"; break; + } + + sprintf(buf,"%s%s",s,msg); + vsprintf(buf,buf,args); + OutputDebugStringA(buf); + + if (severity == DBUS_SYSTEM_LOG_FATAL) + exit (1); } /** Installs a signal handler @@ -312,34 +328,6 @@ _dbus_set_signal_handler (int sig, _dbus_verbose ("_dbus_set_signal_handler() has to be implemented\n"); } -/** Checks if a file exists -* -* @param file full path to the file -* @returns #TRUE if file exists -*/ -dbus_bool_t -_dbus_file_exists (const char *file) -{ - HANDLE h = CreateFile( - file, /* LPCTSTR lpFileName*/ - 0, /* DWORD dwDesiredAccess */ - 0, /* DWORD dwShareMode*/ - NULL, /* LPSECURITY_ATTRIBUTES lpSecurityAttributes */ - OPEN_EXISTING, /* DWORD dwCreationDisposition */ - FILE_ATTRIBUTE_NORMAL, /* DWORD dwFlagsAndAttributes */ - NULL /* HANDLE hTemplateFile */ - ); - - /* file not found, use local copy of session.conf */ - if (h != INVALID_HANDLE_VALUE && GetLastError() != ERROR_PATH_NOT_FOUND) - { - CloseHandle(h); - return TRUE; - } - else - return FALSE; -} - /** * stat() wrapper. * @@ -353,28 +341,16 @@ _dbus_stat(const DBusString *filename, DBusStat *statbuf, DBusError *error) { -#ifdef DBUS_WINCE - return TRUE; - //TODO -#else const char *filename_c; -#if !defined(DBUS_WIN) && !defined(DBUS_WINCE) - - struct stat sb; -#else - WIN32_FILE_ATTRIBUTE_DATA wfad; char *lastdot; DWORD rc; - PSID owner_sid, group_sid; - PSECURITY_DESCRIPTOR sd; -#endif _DBUS_ASSERT_ERROR_IS_CLEAR (error); filename_c = _dbus_string_get_const_data (filename); - if (!GetFileAttributesEx (filename_c, GetFileExInfoStandard, &wfad)) + if (!GetFileAttributesExA (filename_c, GetFileExInfoStandard, &wfad)) { _dbus_win_set_error_from_win_error (error, GetLastError ()); return FALSE; @@ -398,25 +374,36 @@ _dbus_stat(const DBusString *filename, statbuf->nlink = 1; - sd = NULL; - rc = GetNamedSecurityInfo ((char *) filename_c, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION, - &owner_sid, &group_sid, - NULL, NULL, - &sd); - if (rc != ERROR_SUCCESS) - { - _dbus_win_set_error_from_win_error (error, rc); - if (sd != NULL) - LocalFree (sd); - return FALSE; - } - - statbuf->uid = _dbus_win_sid_to_uid_t (owner_sid); - statbuf->gid = _dbus_win_sid_to_uid_t (group_sid); +#ifdef ENABLE_UID_TO_SID + { + PSID owner_sid, group_sid; + PSECURITY_DESCRIPTOR sd; + + sd = NULL; + rc = GetNamedSecurityInfo ((char *) filename_c, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION, + &owner_sid, &group_sid, + NULL, NULL, + &sd); + if (rc != ERROR_SUCCESS) + { + _dbus_win_set_error_from_win_error (error, rc); + if (sd != NULL) + LocalFree (sd); + return FALSE; + } + + /* FIXME */ + statbuf->uid = _dbus_win_sid_to_uid_t (owner_sid); + statbuf->gid = _dbus_win_sid_to_uid_t (group_sid); - LocalFree (sd); + LocalFree (sd); + } +#else + statbuf->uid = DBUS_UID_UNSET; + statbuf->gid = DBUS_GID_UNSET; +#endif statbuf->size = ((dbus_int64_t) wfad.nFileSizeHigh << 32) + wfad.nFileSizeLow; @@ -433,27 +420,9 @@ _dbus_stat(const DBusString *filename, wfad.ftCreationTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000); return TRUE; -#endif //DBUS_WINCE } -#ifdef HAVE_DIRENT_H - -// mingw ships with dirent.h -#include -#define _dbus_opendir opendir -#define _dbus_readdir readdir -#define _dbus_closedir closedir - -#else - -#ifdef HAVE_IO_H -#include // win32 file functions -#endif - -#include -#include - /* This file is part of the KDE project Copyright (C) 2000 Werner Almesberger @@ -493,10 +462,10 @@ struct dirent /* typedef DIR - not the same as Unix */ typedef struct { - long handle; /* _findfirst/_findnext handle */ - short offset; /* offset into directory */ + HANDLE handle; /* FindFirst/FindNext handle */ + short offset; /* offset into directory */ short finished; /* 1 if there are not more files */ - struct _finddata_t fileinfo; /* from _findfirst/_findnext */ + WIN32_FIND_DATAA fileinfo; /* from FindFirst/FindNext */ char *dir; /* the dir we are reading */ struct dirent dent; /* the dirent to return */ } @@ -512,14 +481,16 @@ DIR; * The dirent struct is compatible with Unix, except that d_ino is * always 1 and d_off is made up as we go along. * +* Error codes are not available with errno but GetLastError. +* * The DIR typedef is not compatible with Unix. **********************************************************************/ -DIR * _dbus_opendir(const char *dir) +static DIR * _dbus_opendir(const char *dir) { DIR *dp; char *filespec; - long handle; + HANDLE handle; int index; filespec = malloc(strlen(dir) + 2 + 1); @@ -534,9 +505,10 @@ DIR * _dbus_opendir(const char *dir) dp->finished = 0; dp->dir = strdup(dir); - if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) + handle = FindFirstFileA(filespec, &(dp->fileinfo)); + if (handle == INVALID_HANDLE_VALUE) { - if (errno == ENOENT) + if (GetLastError() == ERROR_NO_MORE_FILES) dp->finished = 1; else return NULL; @@ -548,36 +520,41 @@ DIR * _dbus_opendir(const char *dir) return dp; } -struct dirent * _dbus_readdir(DIR *dp) - { - if (!dp || dp->finished) - return NULL; - - if (dp->offset != 0) - { - if (_findnext(dp->handle, &(dp->fileinfo)) < 0) - { - dp->finished = 1; - errno = 0; - return NULL; - } - } - dp->offset++; +static struct dirent * _dbus_readdir(DIR *dp) +{ + int saved_err = GetLastError(); - strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME); - dp->dent.d_ino = 1; - dp->dent.d_reclen = strlen(dp->dent.d_name); - dp->dent.d_off = dp->offset; + if (!dp || dp->finished) + return NULL; - return &(dp->dent); - } + if (dp->offset != 0) + { + if (FindNextFileA(dp->handle, &(dp->fileinfo)) == 0) + { + if (GetLastError() == ERROR_NO_MORE_FILES) + { + SetLastError(saved_err); + dp->finished = 1; + } + return NULL; + } + } + dp->offset++; + + strncpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME); + dp->dent.d_ino = 1; + dp->dent.d_reclen = strlen(dp->dent.d_name); + dp->dent.d_off = dp->offset; + + return &(dp->dent); +} -int _dbus_closedir(DIR *dp) +static int _dbus_closedir(DIR *dp) { if (!dp) return 0; - _findclose(dp->handle); + FindClose(dp->handle); if (dp->dir) free(dp->dir); if (dp) @@ -586,7 +563,6 @@ int _dbus_closedir(DIR *dp) return 0; } -#endif //#ifdef HAVE_DIRENT_H /** * Internals of directory iterator @@ -619,10 +595,11 @@ _dbus_directory_open (const DBusString *filename, d = _dbus_opendir (filename_c); if (d == NULL) { - dbus_set_error (error, _dbus_error_from_errno (errno), + char *emsg = _dbus_win_error_string (GetLastError ()); + dbus_set_error (error, _dbus_win_error_from_last_error (), "Failed to read directory \"%s\": %s", - filename_c, - _dbus_strerror (errno)); + filename_c, emsg); + _dbus_win_free_error_string (emsg); return NULL; } iter = dbus_new0 (DBusDirIter, 1); @@ -662,14 +639,17 @@ _dbus_directory_get_next_file (DBusDirIter *iter, _DBUS_ASSERT_ERROR_IS_CLEAR (error); again: - errno = 0; + SetLastError (0); ent = _dbus_readdir (iter->d); if (ent == NULL) { - if (errno != 0) - dbus_set_error (error, - _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + if (GetLastError() != 0) + { + char *emsg = _dbus_win_error_string (GetLastError ()); + dbus_set_error (error, _dbus_win_error_from_last_error (), + "Failed to get next in directory: %s", emsg); + _dbus_win_free_error_string (emsg); + } return FALSE; } else if (ent->d_name[0] == '.' && @@ -700,136 +680,6 @@ _dbus_directory_close (DBusDirIter *iter) dbus_free (iter); } -/** - * Checks whether the filename is an absolute path - * - * @param filename the filename - * @returns #TRUE if an absolute path - */ -dbus_bool_t -_dbus_path_is_absolute (const DBusString *filename) -{ - if (_dbus_string_get_length (filename) > 0) - return _dbus_string_get_byte (filename, 1) == ':' - || _dbus_string_get_byte (filename, 0) == '\\' - || _dbus_string_get_byte (filename, 0) == '/'; - else - return FALSE; -} - -#ifdef ENABLE_DBUSGROPINFO -static dbus_bool_t -fill_group_info(DBusGroupInfo *info, - dbus_gid_t gid, - const DBusString *groupname, - DBusError *error) -{ - const char *group_c_str; - - _dbus_assert (groupname != NULL || gid != DBUS_GID_UNSET); - _dbus_assert (groupname == NULL || gid == DBUS_GID_UNSET); - - if (groupname) - group_c_str = _dbus_string_get_const_data (groupname); - else - group_c_str = NULL; - - if (group_c_str) - { - PSID group_sid; - wchar_t *wgroupname = _dbus_win_utf8_to_utf16 (group_c_str, error); - - if (!wgroupname) - return FALSE; - - if (!_dbus_win_account_to_sid (wgroupname, &group_sid, error)) - { - dbus_free (wgroupname); - return FALSE; - } - - info->gid = _dbus_win_sid_to_uid_t (group_sid); - info->groupname = _dbus_strdup (group_c_str); - - dbus_free (group_sid); - dbus_free (wgroupname); - - return TRUE; - } - else - { - dbus_bool_t retval = FALSE; - wchar_t *wname, *wdomain; - char *name, *domain; - - info->gid = gid; - - if (!_dbus_win_sid_to_name_and_domain (gid, &wname, &wdomain, error)) - return FALSE; - - name = _dbus_win_utf16_to_utf8 (wname, error); - if (!name) - goto out0; - - domain = _dbus_win_utf16_to_utf8 (wdomain, error); - if (!domain) - goto out1; - - info->groupname = dbus_malloc (strlen (domain) + 1 + strlen (name) + 1); - - strcpy (info->groupname, domain); - strcat (info->groupname, "\\"); - strcat (info->groupname, name); - - retval = TRUE; - - dbus_free (domain); -out1: - dbus_free (name); -out0: - dbus_free (wname); - dbus_free (wdomain); - - return retval; - } -} - -/** - * Initializes the given DBusGroupInfo struct - * with information about the given group ID. - * - * @param info the group info struct - * @param gid group ID - * @param error the error return - * @returns #FALSE if error is set - */ -dbus_bool_t -_dbus_group_info_fill_gid (DBusGroupInfo *info, - dbus_gid_t gid, - DBusError *error) -{ - return fill_group_info (info, gid, NULL, error); -} - -/** - * Initializes the given DBusGroupInfo struct - * with information about the given group name. - * - * @param info the group info struct - * @param groupname name of group - * @param error the error return - * @returns #FALSE if error is set - */ -dbus_bool_t -_dbus_group_info_fill (DBusGroupInfo *info, - const DBusString *groupname, - DBusError *error) -{ - return fill_group_info (info, DBUS_GID_UNSET, - groupname, error); -} -#endif - /** @} */ /* End of DBusInternalsUtils functions */ /** @@ -917,6 +767,11 @@ _dbus_unix_user_is_process_owner (dbus_uid_t uid) return FALSE; } +dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid) +{ + return TRUE; +} + /*===================================================================== unix emulation functions - should be removed sometime in the future =====================================================================*/ @@ -934,6 +789,8 @@ dbus_bool_t _dbus_unix_user_is_at_console (dbus_uid_t uid, DBusError *error) { + dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, + "UNIX user IDs not supported on Windows\n"); return FALSE; } @@ -991,3 +848,683 @@ _dbus_unix_groups_from_uid (dbus_uid_t uid, /** @} */ /* DBusString stuff */ +/************************************************************************ + + error handling + + ************************************************************************/ + + + + + +/* lan manager error codes */ +const char* +_dbus_lm_strerror(int error_number) +{ +#ifdef DBUS_WINCE + // TODO + return "unknown"; +#else + const char *msg; + switch (error_number) + { + case NERR_NetNotStarted: + return "The workstation driver is not installed."; + case NERR_UnknownServer: + return "The server could not be located."; + case NERR_ShareMem: + return "An internal error occurred. The network cannot access a shared memory segment."; + case NERR_NoNetworkResource: + return "A network resource shortage occurred."; + case NERR_RemoteOnly: + return "This operation is not supported on workstations."; + case NERR_DevNotRedirected: + return "The device is not connected."; + case NERR_ServerNotStarted: + return "The Server service is not started."; + case NERR_ItemNotFound: + return "The queue is empty."; + case NERR_UnknownDevDir: + return "The device or directory does not exist."; + case NERR_RedirectedPath: + return "The operation is invalid on a redirected resource."; + case NERR_DuplicateShare: + return "The name has already been shared."; + case NERR_NoRoom: + return "The server is currently out of the requested resource."; + case NERR_TooManyItems: + return "Requested addition of items exceeds the maximum allowed."; + case NERR_InvalidMaxUsers: + return "The Peer service supports only two simultaneous users."; + case NERR_BufTooSmall: + return "The API return buffer is too small."; + case NERR_RemoteErr: + return "A remote API error occurred."; + case NERR_LanmanIniError: + return "An error occurred when opening or reading the configuration file."; + case NERR_NetworkError: + return "A general network error occurred."; + case NERR_WkstaInconsistentState: + return "The Workstation service is in an inconsistent state. Restart the computer before restarting the Workstation service."; + case NERR_WkstaNotStarted: + return "The Workstation service has not been started."; + case NERR_BrowserNotStarted: + return "The requested information is not available."; + case NERR_InternalError: + return "An internal error occurred."; + case NERR_BadTransactConfig: + return "The server is not configured for transactions."; + case NERR_InvalidAPI: + return "The requested API is not supported on the remote server."; + case NERR_BadEventName: + return "The event name is invalid."; + case NERR_DupNameReboot: + return "The computer name already exists on the network. Change it and restart the computer."; + case NERR_CfgCompNotFound: + return "The specified component could not be found in the configuration information."; + case NERR_CfgParamNotFound: + return "The specified parameter could not be found in the configuration information."; + case NERR_LineTooLong: + return "A line in the configuration file is too long."; + case NERR_QNotFound: + return "The printer does not exist."; + case NERR_JobNotFound: + return "The print job does not exist."; + case NERR_DestNotFound: + return "The printer destination cannot be found."; + case NERR_DestExists: + return "The printer destination already exists."; + case NERR_QExists: + return "The printer queue already exists."; + case NERR_QNoRoom: + return "No more printers can be added."; + case NERR_JobNoRoom: + return "No more print jobs can be added."; + case NERR_DestNoRoom: + return "No more printer destinations can be added."; + case NERR_DestIdle: + return "This printer destination is idle and cannot accept control operations."; + case NERR_DestInvalidOp: + return "This printer destination request contains an invalid control function."; + case NERR_ProcNoRespond: + return "The print processor is not responding."; + case NERR_SpoolerNotLoaded: + return "The spooler is not running."; + case NERR_DestInvalidState: + return "This operation cannot be performed on the print destination in its current state."; + case NERR_QInvalidState: + return "This operation cannot be performed on the printer queue in its current state."; + case NERR_JobInvalidState: + return "This operation cannot be performed on the print job in its current state."; + case NERR_SpoolNoMemory: + return "A spooler memory allocation failure occurred."; + case NERR_DriverNotFound: + return "The device driver does not exist."; + case NERR_DataTypeInvalid: + return "The data type is not supported by the print processor."; + case NERR_ProcNotFound: + return "The print processor is not installed."; + case NERR_ServiceTableLocked: + return "The service database is locked."; + case NERR_ServiceTableFull: + return "The service table is full."; + case NERR_ServiceInstalled: + return "The requested service has already been started."; + case NERR_ServiceEntryLocked: + return "The service does not respond to control actions."; + case NERR_ServiceNotInstalled: + return "The service has not been started."; + case NERR_BadServiceName: + return "The service name is invalid."; + case NERR_ServiceCtlTimeout: + return "The service is not responding to the control function."; + case NERR_ServiceCtlBusy: + return "The service control is busy."; + case NERR_BadServiceProgName: + return "The configuration file contains an invalid service program name."; + case NERR_ServiceNotCtrl: + return "The service could not be controlled in its present state."; + case NERR_ServiceKillProc: + return "The service ended abnormally."; + case NERR_ServiceCtlNotValid: + return "The requested pause or stop is not valid for this service."; + case NERR_NotInDispatchTbl: + return "The service control dispatcher could not find the service name in the dispatch table."; + case NERR_BadControlRecv: + return "The service control dispatcher pipe read failed."; + case NERR_ServiceNotStarting: + return "A thread for the new service could not be created."; + case NERR_AlreadyLoggedOn: + return "This workstation is already logged on to the local-area network."; + case NERR_NotLoggedOn: + return "The workstation is not logged on to the local-area network."; + case NERR_BadUsername: + return "The user name or group name parameter is invalid."; + case NERR_BadPassword: + return "The password parameter is invalid."; + case NERR_UnableToAddName_W: + return "@W The logon processor did not add the message alias."; + case NERR_UnableToAddName_F: + return "The logon processor did not add the message alias."; + case NERR_UnableToDelName_W: + return "@W The logoff processor did not delete the message alias."; + case NERR_UnableToDelName_F: + return "The logoff processor did not delete the message alias."; + case NERR_LogonsPaused: + return "Network logons are paused."; + case NERR_LogonServerConflict: + return "A centralized logon-server conflict occurred."; + case NERR_LogonNoUserPath: + return "The server is configured without a valid user path."; + case NERR_LogonScriptError: + return "An error occurred while loading or running the logon script."; + case NERR_StandaloneLogon: + return "The logon server was not specified. Your computer will be logged on as STANDALONE."; + case NERR_LogonServerNotFound: + return "The logon server could not be found."; + case NERR_LogonDomainExists: + return "There is already a logon domain for this computer."; + case NERR_NonValidatedLogon: + return "The logon server could not validate the logon."; + case NERR_ACFNotFound: + return "The security database could not be found."; + case NERR_GroupNotFound: + return "The group name could not be found."; + case NERR_UserNotFound: + return "The user name could not be found."; + case NERR_ResourceNotFound: + return "The resource name could not be found."; + case NERR_GroupExists: + return "The group already exists."; + case NERR_UserExists: + return "The user account already exists."; + case NERR_ResourceExists: + return "The resource permission list already exists."; + case NERR_NotPrimary: + return "This operation is only allowed on the primary domain controller of the domain."; + case NERR_ACFNotLoaded: + return "The security database has not been started."; + case NERR_ACFNoRoom: + return "There are too many names in the user accounts database."; + case NERR_ACFFileIOFail: + return "A disk I/O failure occurred."; + case NERR_ACFTooManyLists: + return "The limit of 64 entries per resource was exceeded."; + case NERR_UserLogon: + return "Deleting a user with a session is not allowed."; + case NERR_ACFNoParent: + return "The parent directory could not be located."; + case NERR_CanNotGrowSegment: + return "Unable to add to the security database session cache segment."; + case NERR_SpeGroupOp: + return "This operation is not allowed on this special group."; + case NERR_NotInCache: + return "This user is not cached in user accounts database session cache."; + case NERR_UserInGroup: + return "The user already belongs to this group."; + case NERR_UserNotInGroup: + return "The user does not belong to this group."; + case NERR_AccountUndefined: + return "This user account is undefined."; + case NERR_AccountExpired: + return "This user account has expired."; + case NERR_InvalidWorkstation: + return "The user is not allowed to log on from this workstation."; + case NERR_InvalidLogonHours: + return "The user is not allowed to log on at this time."; + case NERR_PasswordExpired: + return "The password of this user has expired."; + case NERR_PasswordCantChange: + return "The password of this user cannot change."; + case NERR_PasswordHistConflict: + return "This password cannot be used now."; + case NERR_PasswordTooShort: + return "The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements."; + case NERR_PasswordTooRecent: + return "The password of this user is too recent to change."; + case NERR_InvalidDatabase: + return "The security database is corrupted."; + case NERR_DatabaseUpToDate: + return "No updates are necessary to this replicant network/local security database."; + case NERR_SyncRequired: + return "This replicant database is outdated; synchronization is required."; + case NERR_UseNotFound: + return "The network connection could not be found."; + case NERR_BadAsgType: + return "This asg_type is invalid."; + case NERR_DeviceIsShared: + return "This device is currently being shared."; + case NERR_NoComputerName: + return "The computer name could not be added as a message alias. The name may already exist on the network."; + case NERR_MsgAlreadyStarted: + return "The Messenger service is already started."; + case NERR_MsgInitFailed: + return "The Messenger service failed to start."; + case NERR_NameNotFound: + return "The message alias could not be found on the network."; + case NERR_AlreadyForwarded: + return "This message alias has already been forwarded."; + case NERR_AddForwarded: + return "This message alias has been added but is still forwarded."; + case NERR_AlreadyExists: + return "This message alias already exists locally."; + case NERR_TooManyNames: + return "The maximum number of added message aliases has been exceeded."; + case NERR_DelComputerName: + return "The computer name could not be deleted."; + case NERR_LocalForward: + return "Messages cannot be forwarded back to the same workstation."; + case NERR_GrpMsgProcessor: + return "An error occurred in the domain message processor."; + case NERR_PausedRemote: + return "The message was sent, but the recipient has paused the Messenger service."; + case NERR_BadReceive: + return "The message was sent but not received."; + case NERR_NameInUse: + return "The message alias is currently in use. Try again later."; + case NERR_MsgNotStarted: + return "The Messenger service has not been started."; + case NERR_NotLocalName: + return "The name is not on the local computer."; + case NERR_NoForwardName: + return "The forwarded message alias could not be found on the network."; + case NERR_RemoteFull: + return "The message alias table on the remote station is full."; + case NERR_NameNotForwarded: + return "Messages for this alias are not currently being forwarded."; + case NERR_TruncatedBroadcast: + return "The broadcast message was truncated."; + case NERR_InvalidDevice: + return "This is an invalid device name."; + case NERR_WriteFault: + return "A write fault occurred."; + case NERR_DuplicateName: + return "A duplicate message alias exists on the network."; + case NERR_DeleteLater: + return "@W This message alias will be deleted later."; + case NERR_IncompleteDel: + return "The message alias was not successfully deleted from all networks."; + case NERR_MultipleNets: + return "This operation is not supported on computers with multiple networks."; + case NERR_NetNameNotFound: + return "This shared resource does not exist."; + case NERR_DeviceNotShared: + return "This device is not shared."; + case NERR_ClientNameNotFound: + return "A session does not exist with that computer name."; + case NERR_FileIdNotFound: + return "There is not an open file with that identification number."; + case NERR_ExecFailure: + return "A failure occurred when executing a remote administration command."; + case NERR_TmpFile: + return "A failure occurred when opening a remote temporary file."; + case NERR_TooMuchData: + return "The data returned from a remote administration command has been truncated to 64K."; + case NERR_DeviceShareConflict: + return "This device cannot be shared as both a spooled and a non-spooled resource."; + case NERR_BrowserTableIncomplete: + return "The information in the list of servers may be incorrect."; + case NERR_NotLocalDomain: + return "The computer is not active in this domain."; +#ifdef NERR_IsDfsShare + + case NERR_IsDfsShare: + return "The share must be removed from the Distributed File System before it can be deleted."; +#endif + + case NERR_DevInvalidOpCode: + return "The operation is invalid for this device."; + case NERR_DevNotFound: + return "This device cannot be shared."; + case NERR_DevNotOpen: + return "This device was not open."; + case NERR_BadQueueDevString: + return "This device name list is invalid."; + case NERR_BadQueuePriority: + return "The queue priority is invalid."; + case NERR_NoCommDevs: + return "There are no shared communication devices."; + case NERR_QueueNotFound: + return "The queue you specified does not exist."; + case NERR_BadDevString: + return "This list of devices is invalid."; + case NERR_BadDev: + return "The requested device is invalid."; + case NERR_InUseBySpooler: + return "This device is already in use by the spooler."; + case NERR_CommDevInUse: + return "This device is already in use as a communication device."; + case NERR_InvalidComputer: + return "This computer name is invalid."; + case NERR_MaxLenExceeded: + return "The string and prefix specified are too long."; + case NERR_BadComponent: + return "This path component is invalid."; + case NERR_CantType: + return "Could not determine the type of input."; + case NERR_TooManyEntries: + return "The buffer for types is not big enough."; + case NERR_ProfileFileTooBig: + return "Profile files cannot exceed 64K."; + case NERR_ProfileOffset: + return "The start offset is out of range."; + case NERR_ProfileCleanup: + return "The system cannot delete current connections to network resources."; + case NERR_ProfileUnknownCmd: + return "The system was unable to parse the command line in this file."; + case NERR_ProfileLoadErr: + return "An error occurred while loading the profile file."; + case NERR_ProfileSaveErr: + return "@W Errors occurred while saving the profile file. The profile was partially saved."; + case NERR_LogOverflow: + return "Log file %1 is full."; + case NERR_LogFileChanged: + return "This log file has changed between reads."; + case NERR_LogFileCorrupt: + return "Log file %1 is corrupt."; + case NERR_SourceIsDir: + return "The source path cannot be a directory."; + case NERR_BadSource: + return "The source path is illegal."; + case NERR_BadDest: + return "The destination path is illegal."; + case NERR_DifferentServers: + return "The source and destination paths are on different servers."; + case NERR_RunSrvPaused: + return "The Run server you requested is paused."; + case NERR_ErrCommRunSrv: + return "An error occurred when communicating with a Run server."; + case NERR_ErrorExecingGhost: + return "An error occurred when starting a background process."; + case NERR_ShareNotFound: + return "The shared resource you are connected to could not be found."; + case NERR_InvalidLana: + return "The LAN adapter number is invalid."; + case NERR_OpenFiles: + return "There are open files on the connection."; + case NERR_ActiveConns: + return "Active connections still exist."; + case NERR_BadPasswordCore: + return "This share name or password is invalid."; + case NERR_DevInUse: + return "The device is being accessed by an active process."; + case NERR_LocalDrive: + return "The drive letter is in use locally."; + case NERR_AlertExists: + return "The specified client is already registered for the specified event."; + case NERR_TooManyAlerts: + return "The alert table is full."; + case NERR_NoSuchAlert: + return "An invalid or nonexistent alert name was raised."; + case NERR_BadRecipient: + return "The alert recipient is invalid."; + case NERR_AcctLimitExceeded: + return "A user's session with this server has been deleted."; + case NERR_InvalidLogSeek: + return "The log file does not contain the requested record number."; + case NERR_BadUasConfig: + return "The user accounts database is not configured correctly."; + case NERR_InvalidUASOp: + return "This operation is not permitted when the Netlogon service is running."; + case NERR_LastAdmin: + return "This operation is not allowed on the last administrative account."; + case NERR_DCNotFound: + return "Could not find domain controller for this domain."; + case NERR_LogonTrackingError: + return "Could not set logon information for this user."; + case NERR_NetlogonNotStarted: + return "The Netlogon service has not been started."; + case NERR_CanNotGrowUASFile: + return "Unable to add to the user accounts database."; + case NERR_TimeDiffAtDC: + return "This server's clock is not synchronized with the primary domain controller's clock."; + case NERR_PasswordMismatch: + return "A password mismatch has been detected."; + case NERR_NoSuchServer: + return "The server identification does not specify a valid server."; + case NERR_NoSuchSession: + return "The session identification does not specify a valid session."; + case NERR_NoSuchConnection: + return "The connection identification does not specify a valid connection."; + case NERR_TooManyServers: + return "There is no space for another entry in the table of available servers."; + case NERR_TooManySessions: + return "The server has reached the maximum number of sessions it supports."; + case NERR_TooManyConnections: + return "The server has reached the maximum number of connections it supports."; + case NERR_TooManyFiles: + return "The server cannot open more files because it has reached its maximum number."; + case NERR_NoAlternateServers: + return "There are no alternate servers registered on this server."; + case NERR_TryDownLevel: + return "Try down-level (remote admin protocol) version of API instead."; + case NERR_UPSDriverNotStarted: + return "The UPS driver could not be accessed by the UPS service."; + case NERR_UPSInvalidConfig: + return "The UPS service is not configured correctly."; + case NERR_UPSInvalidCommPort: + return "The UPS service could not access the specified Comm Port."; + case NERR_UPSSignalAsserted: + return "The UPS indicated a line fail or low battery situation. Service not started."; + case NERR_UPSShutdownFailed: + return "The UPS service failed to perform a system shut down."; + case NERR_BadDosRetCode: + return "The program below returned an MS-DOS error code:"; + case NERR_ProgNeedsExtraMem: + return "The program below needs more memory:"; + case NERR_BadDosFunction: + return "The program below called an unsupported MS-DOS function:"; + case NERR_RemoteBootFailed: + return "The workstation failed to boot."; + case NERR_BadFileCheckSum: + return "The file below is corrupt."; + case NERR_NoRplBootSystem: + return "No loader is specified in the boot-block definition file."; + case NERR_RplLoadrNetBiosErr: + return "NetBIOS returned an error: The NCB and SMB are dumped above."; + case NERR_RplLoadrDiskErr: + return "A disk I/O error occurred."; + case NERR_ImageParamErr: + return "Image parameter substitution failed."; + case NERR_TooManyImageParams: + return "Too many image parameters cross disk sector boundaries."; + case NERR_NonDosFloppyUsed: + return "The image was not generated from an MS-DOS diskette formatted with /S."; + case NERR_RplBootRestart: + return "Remote boot will be restarted later."; + case NERR_RplSrvrCallFailed: + return "The call to the Remoteboot server failed."; + case NERR_CantConnectRplSrvr: + return "Cannot connect to the Remoteboot server."; + case NERR_CantOpenImageFile: + return "Cannot open image file on the Remoteboot server."; + case NERR_CallingRplSrvr: + return "Connecting to the Remoteboot server..."; + case NERR_StartingRplBoot: + return "Connecting to the Remoteboot server..."; + case NERR_RplBootServiceTerm: + return "Remote boot service was stopped; check the error log for the cause of the problem."; + case NERR_RplBootStartFailed: + return "Remote boot startup failed; check the error log for the cause of the problem."; + case NERR_RPL_CONNECTED: + return "A second connection to a Remoteboot resource is not allowed."; + case NERR_BrowserConfiguredToNotRun: + return "The browser service was configured with MaintainServerList=No."; + case NERR_RplNoAdaptersStarted: + return "Service failed to start since none of the network adapters started with this service."; + case NERR_RplBadRegistry: + return "Service failed to start due to bad startup information in the registry."; + case NERR_RplBadDatabase: + return "Service failed to start because its database is absent or corrupt."; + case NERR_RplRplfilesShare: + return "Service failed to start because RPLFILES share is absent."; + case NERR_RplNotRplServer: + return "Service failed to start because RPLUSER group is absent."; + case NERR_RplCannotEnum: + return "Cannot enumerate service records."; + case NERR_RplWkstaInfoCorrupted: + return "Workstation record information has been corrupted."; + case NERR_RplWkstaNotFound: + return "Workstation record was not found."; + case NERR_RplWkstaNameUnavailable: + return "Workstation name is in use by some other workstation."; + case NERR_RplProfileInfoCorrupted: + return "Profile record information has been corrupted."; + case NERR_RplProfileNotFound: + return "Profile record was not found."; + case NERR_RplProfileNameUnavailable: + return "Profile name is in use by some other profile."; + case NERR_RplProfileNotEmpty: + return "There are workstations using this profile."; + case NERR_RplConfigInfoCorrupted: + return "Configuration record information has been corrupted."; + case NERR_RplConfigNotFound: + return "Configuration record was not found."; + case NERR_RplAdapterInfoCorrupted: + return "Adapter ID record information has been corrupted."; + case NERR_RplInternal: + return "An internal service error has occurred."; + case NERR_RplVendorInfoCorrupted: + return "Vendor ID record information has been corrupted."; + case NERR_RplBootInfoCorrupted: + return "Boot block record information has been corrupted."; + case NERR_RplWkstaNeedsUserAcct: + return "The user account for this workstation record is missing."; + case NERR_RplNeedsRPLUSERAcct: + return "The RPLUSER local group could not be found."; + case NERR_RplBootNotFound: + return "Boot block record was not found."; + case NERR_RplIncompatibleProfile: + return "Chosen profile is incompatible with this workstation."; + case NERR_RplAdapterNameUnavailable: + return "Chosen network adapter ID is in use by some other workstation."; + case NERR_RplConfigNotEmpty: + return "There are profiles using this configuration."; + case NERR_RplBootInUse: + return "There are workstations, profiles, or configurations using this boot block."; + case NERR_RplBackupDatabase: + return "Service failed to backup Remoteboot database."; + case NERR_RplAdapterNotFound: + return "Adapter record was not found."; + case NERR_RplVendorNotFound: + return "Vendor record was not found."; + case NERR_RplVendorNameUnavailable: + return "Vendor name is in use by some other vendor record."; + case NERR_RplBootNameUnavailable: + return "(boot name, vendor ID) is in use by some other boot block record."; + case NERR_RplConfigNameUnavailable: + return "Configuration name is in use by some other configuration."; + case NERR_DfsInternalCorruption: + return "The internal database maintained by the Dfs service is corrupt."; + case NERR_DfsVolumeDataCorrupt: + return "One of the records in the internal Dfs database is corrupt."; + case NERR_DfsNoSuchVolume: + return "There is no DFS name whose entry path matches the input Entry Path."; + case NERR_DfsVolumeAlreadyExists: + return "A root or link with the given name already exists."; + case NERR_DfsAlreadyShared: + return "The server share specified is already shared in the Dfs."; + case NERR_DfsNoSuchShare: + return "The indicated server share does not support the indicated DFS namespace."; + case NERR_DfsNotALeafVolume: + return "The operation is not valid on this portion of the namespace."; + case NERR_DfsLeafVolume: + return "The operation is not valid on this portion of the namespace."; + case NERR_DfsVolumeHasMultipleServers: + return "The operation is ambiguous because the link has multiple servers."; + case NERR_DfsCantCreateJunctionPoint: + return "Unable to create a link."; + case NERR_DfsServerNotDfsAware: + return "The server is not Dfs Aware."; + case NERR_DfsBadRenamePath: + return "The specified rename target path is invalid."; + case NERR_DfsVolumeIsOffline: + return "The specified DFS link is offline."; + case NERR_DfsNoSuchServer: + return "The specified server is not a server for this link."; + case NERR_DfsCyclicalName: + return "A cycle in the Dfs name was detected."; + case NERR_DfsNotSupportedInServerDfs: + return "The operation is not supported on a server-based Dfs."; + case NERR_DfsDuplicateService: + return "This link is already supported by the specified server-share."; + case NERR_DfsCantRemoveLastServerShare: + return "Can't remove the last server-share supporting this root or link."; + case NERR_DfsVolumeIsInterDfs: + return "The operation is not supported for an Inter-DFS link."; + case NERR_DfsInconsistent: + return "The internal state of the Dfs Service has become inconsistent."; + case NERR_DfsServerUpgraded: + return "The Dfs Service has been installed on the specified server."; + case NERR_DfsDataIsIdentical: + return "The Dfs data being reconciled is identical."; + case NERR_DfsCantRemoveDfsRoot: + return "The DFS root cannot be deleted. Uninstall DFS if required."; + case NERR_DfsChildOrParentInDfs: + return "A child or parent directory of the share is already in a Dfs."; + case NERR_DfsInternalError: + return "Dfs internal error."; + /* the following are not defined in mingw */ +#if 0 + + case NERR_SetupAlreadyJoined: + return "This machine is already joined to a domain."; + case NERR_SetupNotJoined: + return "This machine is not currently joined to a domain."; + case NERR_SetupDomainController: + return "This machine is a domain controller and cannot be unjoined from a domain."; + case NERR_DefaultJoinRequired: + return "The destination domain controller does not support creating machine accounts in OUs."; + case NERR_InvalidWorkgroupName: + return "The specified workgroup name is invalid."; + case NERR_NameUsesIncompatibleCodePage: + return "The specified computer name is incompatible with the default language used on the domain controller."; + case NERR_ComputerAccountNotFound: + return "The specified computer account could not be found."; + case NERR_PersonalSku: + return "This version of Windows cannot be joined to a domain."; + case NERR_PasswordMustChange: + return "The password must change at the next logon."; + case NERR_AccountLockedOut: + return "The account is locked out."; + case NERR_PasswordTooLong: + return "The password is too long."; + case NERR_PasswordNotComplexEnough: + return "The password does not meet the complexity policy."; + case NERR_PasswordFilterError: + return "The password does not meet the requirements of the password filter DLLs."; +#endif + + } + msg = strerror (error_number); + if (msg == NULL) + msg = "unknown"; + + return msg; +#endif //DBUS_WINCE +} + +/** + * Get a printable string describing the command used to execute + * the process with pid. This string should only be used for + * informative purposes such as logging; it may not be trusted. + * + * The command is guaranteed to be printable ASCII and no longer + * than max_len. + * + * @param pid Process id + * @param str Append command to this string + * @param max_len Maximum length of returned command + * @param error return location for errors + * @returns #FALSE on error + */ +dbus_bool_t +_dbus_command_for_pid (unsigned long pid, + DBusString *str, + int max_len, + DBusError *error) +{ + // FIXME + return FALSE; +}