D-Bus  1.10.12
dbus-sysdeps-util-win.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-sysdeps-util.c Would be in dbus-sysdeps.c, but not used in libdbus
00003  * 
00004  * Copyright (C) 2002, 2003, 2004, 2005  Red Hat, Inc.
00005  * Copyright (C) 2003 CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 
00027 #define STRSAFE_NO_DEPRECATE
00028 
00029 #include "dbus-sysdeps.h"
00030 #include "dbus-internals.h"
00031 #include "dbus-protocol.h"
00032 #include "dbus-string.h"
00033 #include "dbus-sysdeps.h"
00034 #include "dbus-sysdeps-win.h"
00035 #include "dbus-sockets-win.h"
00036 #include "dbus-memory.h"
00037 #include "dbus-pipe.h"
00038 
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #if HAVE_ERRNO_H
00042 #include <errno.h>
00043 #endif
00044 #include <winsock2.h>   // WSA error codes
00045 
00046 #ifndef DBUS_WINCE
00047 #include <io.h>
00048 #include <lm.h>
00049 #include <sys/stat.h>
00050 #endif
00051 
00052 
00062 dbus_bool_t
00063 _dbus_become_daemon (const DBusString *pidfile,
00064                      DBusPipe         *print_pid_pipe,
00065                      DBusError        *error,
00066                      dbus_bool_t       keep_umask)
00067 {
00068   dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00069                   "Cannot daemonize on Windows");
00070   return FALSE;
00071 }
00072 
00081 static dbus_bool_t
00082 _dbus_write_pid_file (const DBusString *filename,
00083                       unsigned long     pid,
00084                       DBusError        *error)
00085 {
00086   const char *cfilename;
00087   HANDLE hnd;
00088   char pidstr[20];
00089   int total;
00090   int bytes_to_write;
00091 
00092   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00093 
00094   cfilename = _dbus_string_get_const_data (filename);
00095 
00096   hnd = CreateFileA (cfilename, GENERIC_WRITE,
00097                      FILE_SHARE_READ | FILE_SHARE_WRITE,
00098                      NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
00099                      INVALID_HANDLE_VALUE);
00100   if (hnd == INVALID_HANDLE_VALUE)
00101     {
00102       char *emsg = _dbus_win_error_string (GetLastError ());
00103       dbus_set_error (error, _dbus_win_error_from_last_error (),
00104                       "Could not create PID file %s: %s",
00105                       cfilename, emsg);
00106       _dbus_win_free_error_string (emsg);
00107       return FALSE;
00108     }
00109 
00110   if (snprintf (pidstr, sizeof (pidstr), "%lu\n", pid) < 0)
00111     {
00112       dbus_set_error (error, _dbus_error_from_system_errno (),
00113                       "Failed to format PID for \"%s\": %s", cfilename,
00114                       _dbus_strerror_from_errno ());
00115       CloseHandle (hnd);
00116       return FALSE;
00117     }
00118 
00119   total = 0;
00120   bytes_to_write = strlen (pidstr);;
00121 
00122   while (total < bytes_to_write)
00123     {
00124       DWORD bytes_written;
00125       BOOL res;
00126 
00127       res = WriteFile (hnd, pidstr + total, bytes_to_write - total,
00128                        &bytes_written, NULL);
00129 
00130       if (res == 0 || bytes_written <= 0)
00131         {
00132           char *emsg = _dbus_win_error_string (GetLastError ());
00133           dbus_set_error (error, _dbus_win_error_from_last_error (),
00134                            "Could not write to %s: %s", cfilename, emsg);
00135           _dbus_win_free_error_string (emsg);
00136           CloseHandle (hnd);
00137           return FALSE;
00138         }
00139 
00140       total += bytes_written;
00141     }
00142 
00143   if (CloseHandle (hnd) == 0)
00144     {
00145       char *emsg = _dbus_win_error_string (GetLastError ());
00146       dbus_set_error (error, _dbus_win_error_from_last_error (),
00147                        "Could not close file %s: %s",
00148                       cfilename, emsg);
00149       _dbus_win_free_error_string (emsg);
00150 
00151       return FALSE;
00152     }
00153 
00154   return TRUE;
00155 }
00156 
00168 dbus_bool_t
00169 _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
00170                                   DBusPipe         *print_pid_pipe,
00171                                   dbus_pid_t        pid_to_write,
00172                                   DBusError        *error)
00173 {
00174   if (pidfile)
00175     {
00176       _dbus_verbose ("writing pid file %s\n", _dbus_string_get_const_data (pidfile));
00177       if (!_dbus_write_pid_file (pidfile,
00178                                  pid_to_write,
00179                                  error))
00180         {
00181           _dbus_verbose ("pid file write failed\n");
00182           _DBUS_ASSERT_ERROR_IS_SET(error);
00183           return FALSE;
00184         }
00185     }
00186   else
00187     {
00188       _dbus_verbose ("No pid file requested\n");
00189     }
00190 
00191   if (print_pid_pipe != NULL && _dbus_pipe_is_valid (print_pid_pipe))
00192     {
00193       DBusString pid;
00194       int bytes;
00195 
00196       _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd);
00197 
00198       if (!_dbus_string_init (&pid))
00199         {
00200           _DBUS_SET_OOM (error);
00201           return FALSE;
00202         }
00203 
00204       if (!_dbus_string_append_int (&pid, pid_to_write) ||
00205           !_dbus_string_append (&pid, "\n"))
00206         {
00207           _dbus_string_free (&pid);
00208           _DBUS_SET_OOM (error);
00209           return FALSE;
00210         }
00211 
00212       bytes = _dbus_string_get_length (&pid);
00213       if (_dbus_pipe_write (print_pid_pipe, &pid, 0, bytes, error) != bytes)
00214         {
00215           /* _dbus_pipe_write sets error only on failure, not short write */
00216           if (error != NULL && !dbus_error_is_set(error))
00217             {
00218               dbus_set_error (error, DBUS_ERROR_FAILED,
00219                               "Printing message bus PID: did not write enough bytes\n");
00220             }
00221           _dbus_string_free (&pid);
00222           return FALSE;
00223         }
00224 
00225       _dbus_string_free (&pid);
00226     }
00227   else
00228     {
00229       _dbus_verbose ("No pid pipe to write to\n");
00230     }
00231 
00232   return TRUE;
00233 }
00234 
00241 dbus_bool_t
00242 _dbus_verify_daemon_user (const char *user)
00243 {
00244   return TRUE;
00245 }
00246 
00254 dbus_bool_t
00255 _dbus_change_to_daemon_user  (const char    *user,
00256                               DBusError     *error)
00257 {
00258   return TRUE;
00259 }
00260 
00261 static void
00262 fd_limit_not_supported (DBusError *error)
00263 {
00264   dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00265                   "cannot change fd limit on this platform");
00266 }
00267 
00268 DBusRLimit *
00269 _dbus_rlimit_save_fd_limit (DBusError *error)
00270 {
00271   fd_limit_not_supported (error);
00272   return NULL;
00273 }
00274 
00275 dbus_bool_t
00276 _dbus_rlimit_raise_fd_limit_if_privileged (unsigned int  desired,
00277                                            DBusError    *error)
00278 {
00279   fd_limit_not_supported (error);
00280   return FALSE;
00281 }
00282 
00283 dbus_bool_t
00284 _dbus_rlimit_restore_fd_limit (DBusRLimit *saved,
00285                                DBusError  *error)
00286 {
00287   fd_limit_not_supported (error);
00288   return FALSE;
00289 }
00290 
00291 void
00292 _dbus_rlimit_free (DBusRLimit *lim)
00293 {
00294   /* _dbus_rlimit_save_fd_limit() cannot return non-NULL on Windows
00295    * so there cannot be anything to free */
00296   _dbus_assert (lim == NULL);
00297 }
00298 
00299 void
00300 _dbus_init_system_log (dbus_bool_t is_daemon)
00301 {
00302   /* OutputDebugStringA doesn't need any special initialization, do nothing */
00303 }
00304 
00311 void
00312 _dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...)
00313 {
00314   va_list args;
00315 
00316   va_start (args, msg);
00317 
00318   _dbus_system_logv (severity, msg, args);
00319 
00320   va_end (args);
00321 }
00322 
00333 void
00334 _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args)
00335 {
00336   char *s = "";
00337   char buf[1024];
00338   char format[1024];
00339 
00340   switch(severity) 
00341    {
00342      case DBUS_SYSTEM_LOG_INFO: s = "info"; break;
00343      case DBUS_SYSTEM_LOG_WARNING: s = "warning"; break;
00344      case DBUS_SYSTEM_LOG_SECURITY: s = "security"; break;
00345      case DBUS_SYSTEM_LOG_FATAL: s = "fatal"; break;
00346    }
00347    
00348   snprintf(format, sizeof(format), "%s%s", s ,msg);
00349   vsnprintf(buf, sizeof(buf), format, args);
00350   OutputDebugStringA(buf);
00351   
00352   if (severity == DBUS_SYSTEM_LOG_FATAL)
00353     exit (1);
00354 }
00355 
00361 void
00362 _dbus_set_signal_handler (int               sig,
00363                           DBusSignalHandler handler)
00364 {
00365   _dbus_verbose ("_dbus_set_signal_handler() has to be implemented\n");
00366 }
00367 
00376 dbus_bool_t
00377 _dbus_stat(const DBusString *filename,
00378            DBusStat         *statbuf,
00379            DBusError        *error)
00380 {
00381   const char *filename_c;
00382   WIN32_FILE_ATTRIBUTE_DATA wfad;
00383   char *lastdot;
00384 
00385   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00386 
00387   filename_c = _dbus_string_get_const_data (filename);
00388 
00389   if (!GetFileAttributesExA (filename_c, GetFileExInfoStandard, &wfad))
00390     {
00391       _dbus_win_set_error_from_win_error (error, GetLastError ());
00392       return FALSE;
00393     }
00394 
00395   if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00396     statbuf->mode = _S_IFDIR;
00397   else
00398     statbuf->mode = _S_IFREG;
00399 
00400   statbuf->mode |= _S_IREAD;
00401   if (wfad.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
00402     statbuf->mode |= _S_IWRITE;
00403 
00404   lastdot = strrchr (filename_c, '.');
00405   if (lastdot && stricmp (lastdot, ".exe") == 0)
00406     statbuf->mode |= _S_IEXEC;
00407 
00408   statbuf->mode |= (statbuf->mode & 0700) >> 3;
00409   statbuf->mode |= (statbuf->mode & 0700) >> 6;
00410 
00411   statbuf->nlink = 1;
00412 
00413 #ifdef ENABLE_UID_TO_SID
00414   {
00415     PSID owner_sid, group_sid;
00416     PSECURITY_DESCRIPTOR sd;
00417 
00418     sd = NULL;
00419     rc = GetNamedSecurityInfo ((char *) filename_c, SE_FILE_OBJECT,
00420                                OWNER_SECURITY_INFORMATION |
00421                                GROUP_SECURITY_INFORMATION,
00422                                &owner_sid, &group_sid,
00423                                NULL, NULL,
00424                                &sd);
00425     if (rc != ERROR_SUCCESS)
00426       {
00427         _dbus_win_set_error_from_win_error (error, rc);
00428         if (sd != NULL)
00429           LocalFree (sd);
00430         return FALSE;
00431       }
00432     
00433     /* FIXME */
00434     statbuf->uid = _dbus_win_sid_to_uid_t (owner_sid);
00435     statbuf->gid = _dbus_win_sid_to_uid_t (group_sid);
00436 
00437     LocalFree (sd);
00438   }
00439 #else
00440   statbuf->uid = DBUS_UID_UNSET;
00441   statbuf->gid = DBUS_GID_UNSET;
00442 #endif
00443 
00444   statbuf->size = ((dbus_int64_t) wfad.nFileSizeHigh << 32) + wfad.nFileSizeLow;
00445 
00446   statbuf->atime =
00447     (((dbus_int64_t) wfad.ftLastAccessTime.dwHighDateTime << 32) +
00448      wfad.ftLastAccessTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
00449 
00450   statbuf->mtime =
00451     (((dbus_int64_t) wfad.ftLastWriteTime.dwHighDateTime << 32) +
00452      wfad.ftLastWriteTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
00453 
00454   statbuf->ctime =
00455     (((dbus_int64_t) wfad.ftCreationTime.dwHighDateTime << 32) +
00456      wfad.ftCreationTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
00457 
00458   return TRUE;
00459 }
00460 
00464 struct DBusDirIter
00465   {
00466     HANDLE handle;
00467     WIN32_FIND_DATAA fileinfo;  /* from FindFirst/FindNext */
00468     dbus_bool_t finished;       /* true if there are no more entries */
00469     int offset;
00470   };
00471 
00479 DBusDirIter*
00480 _dbus_directory_open (const DBusString *filename,
00481                       DBusError        *error)
00482 {
00483   DBusDirIter *iter;
00484   DBusString filespec;
00485 
00486   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00487 
00488   if (!_dbus_string_init_from_string (&filespec, filename))
00489     {
00490       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00491                       "Could not allocate memory for directory filename copy");
00492       return NULL;
00493     }
00494 
00495   if (_dbus_string_ends_with_c_str (&filespec, "/") || _dbus_string_ends_with_c_str (&filespec, "\\") )
00496     {
00497       if (!_dbus_string_append (&filespec, "*"))
00498         {
00499           dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00500                           "Could not append filename wildcard");
00501           return NULL;
00502         }
00503     }
00504   else if (!_dbus_string_ends_with_c_str (&filespec, "*"))
00505     {
00506       if (!_dbus_string_append (&filespec, "\\*"))
00507         {
00508           dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00509                           "Could not append filename wildcard 2");
00510           return NULL;
00511         }
00512     }
00513 
00514   iter = dbus_new0 (DBusDirIter, 1);
00515   if (iter == NULL)
00516     {
00517       _dbus_string_free (&filespec);
00518       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00519                       "Could not allocate memory for directory iterator");
00520       return NULL;
00521     }
00522 
00523   iter->finished = FALSE;
00524   iter->offset = 0;
00525   iter->handle = FindFirstFileA (_dbus_string_get_const_data (&filespec), &(iter->fileinfo));
00526   if (iter->handle == INVALID_HANDLE_VALUE)
00527     {
00528       if (GetLastError () == ERROR_NO_MORE_FILES)
00529         iter->finished = TRUE;
00530       else
00531         {
00532           char *emsg = _dbus_win_error_string (GetLastError ());
00533           dbus_set_error (error, _dbus_win_error_from_last_error (),
00534                           "Failed to read directory \"%s\": %s",
00535                           _dbus_string_get_const_data (filename), emsg);
00536           _dbus_win_free_error_string (emsg);
00537           dbus_free ( iter );
00538           _dbus_string_free (&filespec);
00539           return NULL;
00540         }
00541     }
00542   _dbus_string_free (&filespec);
00543   return iter;
00544 }
00545 
00556 dbus_bool_t
00557 _dbus_directory_get_next_file (DBusDirIter      *iter,
00558                                DBusString       *filename,
00559                                DBusError        *error)
00560 {
00561   int saved_err = GetLastError();
00562 
00563   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00564 
00565 again:
00566   SetLastError (0);
00567 
00568   if (!iter || iter->finished)
00569       return FALSE;
00570 
00571   if (iter->offset > 0)
00572     {
00573       if (FindNextFileA (iter->handle, &(iter->fileinfo)) == 0)
00574         {
00575           if (GetLastError() == ERROR_NO_MORE_FILES)
00576             {
00577               SetLastError(saved_err);
00578               iter->finished = 1;
00579             }
00580           else
00581             {
00582               char *emsg = _dbus_win_error_string (GetLastError ());
00583               dbus_set_error (error, _dbus_win_error_from_last_error (),
00584                              "Failed to get next in directory: %s", emsg);
00585               _dbus_win_free_error_string (emsg);
00586               return FALSE;
00587             }
00588         }
00589     }
00590 
00591   iter->offset++;
00592 
00593   if (iter->finished)
00594       return FALSE;
00595 
00596   if (iter->fileinfo.cFileName[0] == '.' &&
00597      (iter->fileinfo.cFileName[1] == '\0' ||
00598         (iter->fileinfo.cFileName[1] == '.' && iter->fileinfo.cFileName[2] == '\0')))
00599       goto again;
00600 
00601   _dbus_string_set_length (filename, 0);
00602   if (!_dbus_string_append (filename, iter->fileinfo.cFileName))
00603     {
00604       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00605                       "No memory to read directory entry");
00606       return FALSE;
00607     }
00608 
00609   return TRUE;
00610 }
00611 
00615 void
00616 _dbus_directory_close (DBusDirIter *iter)
00617 {
00618   if (!iter)
00619       return;
00620   FindClose(iter->handle);
00621   dbus_free (iter);
00622 }
00623  /* End of DBusInternalsUtils functions */
00625 
00637 dbus_bool_t
00638 _dbus_string_get_dirname(const DBusString *filename,
00639                          DBusString       *dirname)
00640 {
00641   int sep;
00642 
00643   _dbus_assert (filename != dirname);
00644   _dbus_assert (filename != NULL);
00645   _dbus_assert (dirname != NULL);
00646 
00647   /* Ignore any separators on the end */
00648   sep = _dbus_string_get_length (filename);
00649   if (sep == 0)
00650     return _dbus_string_append (dirname, "."); /* empty string passed in */
00651 
00652   while (sep > 0 &&
00653          (_dbus_string_get_byte (filename, sep - 1) == '/' ||
00654           _dbus_string_get_byte (filename, sep - 1) == '\\'))
00655     --sep;
00656 
00657   _dbus_assert (sep >= 0);
00658 
00659   if (sep == 0 ||
00660       (sep == 2 &&
00661        _dbus_string_get_byte (filename, 1) == ':' &&
00662        isalpha (_dbus_string_get_byte (filename, 0))))
00663     return _dbus_string_copy_len (filename, 0, sep + 1,
00664                                   dirname, _dbus_string_get_length (dirname));
00665 
00666   {
00667     int sep1, sep2;
00668     _dbus_string_find_byte_backward (filename, sep, '/', &sep1);
00669     _dbus_string_find_byte_backward (filename, sep, '\\', &sep2);
00670 
00671     sep = MAX (sep1, sep2);
00672   }
00673   if (sep < 0)
00674     return _dbus_string_append (dirname, ".");
00675 
00676   while (sep > 0 &&
00677          (_dbus_string_get_byte (filename, sep - 1) == '/' ||
00678           _dbus_string_get_byte (filename, sep - 1) == '\\'))
00679     --sep;
00680 
00681   _dbus_assert (sep >= 0);
00682 
00683   if ((sep == 0 ||
00684        (sep == 2 &&
00685         _dbus_string_get_byte (filename, 1) == ':' &&
00686         isalpha (_dbus_string_get_byte (filename, 0))))
00687       &&
00688       (_dbus_string_get_byte (filename, sep) == '/' ||
00689        _dbus_string_get_byte (filename, sep) == '\\'))
00690     return _dbus_string_copy_len (filename, 0, sep + 1,
00691                                   dirname, _dbus_string_get_length (dirname));
00692   else
00693     return _dbus_string_copy_len (filename, 0, sep - 0,
00694                                   dirname, _dbus_string_get_length (dirname));
00695 }
00696 
00697 
00705 dbus_bool_t
00706 _dbus_unix_user_is_process_owner (dbus_uid_t uid)
00707 {
00708   return FALSE;
00709 }
00710 
00711 dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid)
00712 {
00713   return TRUE;
00714 }
00715 
00716 /*=====================================================================
00717   unix emulation functions - should be removed sometime in the future
00718  =====================================================================*/
00719 
00729 dbus_bool_t
00730 _dbus_unix_user_is_at_console (dbus_uid_t         uid,
00731                                DBusError         *error)
00732 {
00733   dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00734                   "UNIX user IDs not supported on Windows\n");
00735   return FALSE;
00736 }
00737 
00738 
00747 dbus_bool_t
00748 _dbus_parse_unix_group_from_config (const DBusString  *groupname,
00749                                     dbus_gid_t        *gid_p)
00750 {
00751   return FALSE;
00752 }
00753 
00762 dbus_bool_t
00763 _dbus_parse_unix_user_from_config (const DBusString  *username,
00764                                    dbus_uid_t        *uid_p)
00765 {
00766   return FALSE;
00767 }
00768 
00769 
00780 dbus_bool_t
00781 _dbus_unix_groups_from_uid (dbus_uid_t            uid,
00782                             dbus_gid_t          **group_ids,
00783                             int                  *n_group_ids)
00784 {
00785   return FALSE;
00786 }
00787 
00788 
00789  /* DBusString stuff */
00791 
00792 /************************************************************************
00793  
00794  error handling
00795  
00796  ************************************************************************/
00797 
00798 
00799 
00800 
00801 
00802 /* lan manager error codes */
00803 const char*
00804 _dbus_lm_strerror(int error_number)
00805 {
00806 #ifdef DBUS_WINCE
00807   // TODO
00808   return "unknown";
00809 #else
00810   const char *msg;
00811   switch (error_number)
00812     {
00813     case NERR_NetNotStarted:
00814       return "The workstation driver is not installed.";
00815     case NERR_UnknownServer:
00816       return "The server could not be located.";
00817     case NERR_ShareMem:
00818       return "An internal error occurred. The network cannot access a shared memory segment.";
00819     case NERR_NoNetworkResource:
00820       return "A network resource shortage occurred.";
00821     case NERR_RemoteOnly:
00822       return "This operation is not supported on workstations.";
00823     case NERR_DevNotRedirected:
00824       return "The device is not connected.";
00825     case NERR_ServerNotStarted:
00826       return "The Server service is not started.";
00827     case NERR_ItemNotFound:
00828       return "The queue is empty.";
00829     case NERR_UnknownDevDir:
00830       return "The device or directory does not exist.";
00831     case NERR_RedirectedPath:
00832       return "The operation is invalid on a redirected resource.";
00833     case NERR_DuplicateShare:
00834       return "The name has already been shared.";
00835     case NERR_NoRoom:
00836       return "The server is currently out of the requested resource.";
00837     case NERR_TooManyItems:
00838       return "Requested addition of items exceeds the maximum allowed.";
00839     case NERR_InvalidMaxUsers:
00840       return "The Peer service supports only two simultaneous users.";
00841     case NERR_BufTooSmall:
00842       return "The API return buffer is too small.";
00843     case NERR_RemoteErr:
00844       return "A remote API error occurred.";
00845     case NERR_LanmanIniError:
00846       return "An error occurred when opening or reading the configuration file.";
00847     case NERR_NetworkError:
00848       return "A general network error occurred.";
00849     case NERR_WkstaInconsistentState:
00850       return "The Workstation service is in an inconsistent state. Restart the computer before restarting the Workstation service.";
00851     case NERR_WkstaNotStarted:
00852       return "The Workstation service has not been started.";
00853     case NERR_BrowserNotStarted:
00854       return "The requested information is not available.";
00855     case NERR_InternalError:
00856       return "An internal error occurred.";
00857     case NERR_BadTransactConfig:
00858       return "The server is not configured for transactions.";
00859     case NERR_InvalidAPI:
00860       return "The requested API is not supported on the remote server.";
00861     case NERR_BadEventName:
00862       return "The event name is invalid.";
00863     case NERR_DupNameReboot:
00864       return "The computer name already exists on the network. Change it and restart the computer.";
00865     case NERR_CfgCompNotFound:
00866       return "The specified component could not be found in the configuration information.";
00867     case NERR_CfgParamNotFound:
00868       return "The specified parameter could not be found in the configuration information.";
00869     case NERR_LineTooLong:
00870       return "A line in the configuration file is too long.";
00871     case NERR_QNotFound:
00872       return "The printer does not exist.";
00873     case NERR_JobNotFound:
00874       return "The print job does not exist.";
00875     case NERR_DestNotFound:
00876       return "The printer destination cannot be found.";
00877     case NERR_DestExists:
00878       return "The printer destination already exists.";
00879     case NERR_QExists:
00880       return "The printer queue already exists.";
00881     case NERR_QNoRoom:
00882       return "No more printers can be added.";
00883     case NERR_JobNoRoom:
00884       return "No more print jobs can be added.";
00885     case NERR_DestNoRoom:
00886       return "No more printer destinations can be added.";
00887     case NERR_DestIdle:
00888       return "This printer destination is idle and cannot accept control operations.";
00889     case NERR_DestInvalidOp:
00890       return "This printer destination request contains an invalid control function.";
00891     case NERR_ProcNoRespond:
00892       return "The print processor is not responding.";
00893     case NERR_SpoolerNotLoaded:
00894       return "The spooler is not running.";
00895     case NERR_DestInvalidState:
00896       return "This operation cannot be performed on the print destination in its current state.";
00897     case NERR_QInvalidState:
00898       return "This operation cannot be performed on the printer queue in its current state.";
00899     case NERR_JobInvalidState:
00900       return "This operation cannot be performed on the print job in its current state.";
00901     case NERR_SpoolNoMemory:
00902       return "A spooler memory allocation failure occurred.";
00903     case NERR_DriverNotFound:
00904       return "The device driver does not exist.";
00905     case NERR_DataTypeInvalid:
00906       return "The data type is not supported by the print processor.";
00907     case NERR_ProcNotFound:
00908       return "The print processor is not installed.";
00909     case NERR_ServiceTableLocked:
00910       return "The service database is locked.";
00911     case NERR_ServiceTableFull:
00912       return "The service table is full.";
00913     case NERR_ServiceInstalled:
00914       return "The requested service has already been started.";
00915     case NERR_ServiceEntryLocked:
00916       return "The service does not respond to control actions.";
00917     case NERR_ServiceNotInstalled:
00918       return "The service has not been started.";
00919     case NERR_BadServiceName:
00920       return "The service name is invalid.";
00921     case NERR_ServiceCtlTimeout:
00922       return "The service is not responding to the control function.";
00923     case NERR_ServiceCtlBusy:
00924       return "The service control is busy.";
00925     case NERR_BadServiceProgName:
00926       return "The configuration file contains an invalid service program name.";
00927     case NERR_ServiceNotCtrl:
00928       return "The service could not be controlled in its present state.";
00929     case NERR_ServiceKillProc:
00930       return "The service ended abnormally.";
00931     case NERR_ServiceCtlNotValid:
00932       return "The requested pause or stop is not valid for this service.";
00933     case NERR_NotInDispatchTbl:
00934       return "The service control dispatcher could not find the service name in the dispatch table.";
00935     case NERR_BadControlRecv:
00936       return "The service control dispatcher pipe read failed.";
00937     case NERR_ServiceNotStarting:
00938       return "A thread for the new service could not be created.";
00939     case NERR_AlreadyLoggedOn:
00940       return "This workstation is already logged on to the local-area network.";
00941     case NERR_NotLoggedOn:
00942       return "The workstation is not logged on to the local-area network.";
00943     case NERR_BadUsername:
00944       return "The user name or group name parameter is invalid.";
00945     case NERR_BadPassword:
00946       return "The password parameter is invalid.";
00947     case NERR_UnableToAddName_W:
00948       return "@W The logon processor did not add the message alias.";
00949     case NERR_UnableToAddName_F:
00950       return "The logon processor did not add the message alias.";
00951     case NERR_UnableToDelName_W:
00952       return "@W The logoff processor did not delete the message alias.";
00953     case NERR_UnableToDelName_F:
00954       return "The logoff processor did not delete the message alias.";
00955     case NERR_LogonsPaused:
00956       return "Network logons are paused.";
00957     case NERR_LogonServerConflict:
00958       return "A centralized logon-server conflict occurred.";
00959     case NERR_LogonNoUserPath:
00960       return "The server is configured without a valid user path.";
00961     case NERR_LogonScriptError:
00962       return "An error occurred while loading or running the logon script.";
00963     case NERR_StandaloneLogon:
00964       return "The logon server was not specified. Your computer will be logged on as STANDALONE.";
00965     case NERR_LogonServerNotFound:
00966       return "The logon server could not be found.";
00967     case NERR_LogonDomainExists:
00968       return "There is already a logon domain for this computer.";
00969     case NERR_NonValidatedLogon:
00970       return "The logon server could not validate the logon.";
00971     case NERR_ACFNotFound:
00972       return "The security database could not be found.";
00973     case NERR_GroupNotFound:
00974       return "The group name could not be found.";
00975     case NERR_UserNotFound:
00976       return "The user name could not be found.";
00977     case NERR_ResourceNotFound:
00978       return "The resource name could not be found.";
00979     case NERR_GroupExists:
00980       return "The group already exists.";
00981     case NERR_UserExists:
00982       return "The user account already exists.";
00983     case NERR_ResourceExists:
00984       return "The resource permission list already exists.";
00985     case NERR_NotPrimary:
00986       return "This operation is only allowed on the primary domain controller of the domain.";
00987     case NERR_ACFNotLoaded:
00988       return "The security database has not been started.";
00989     case NERR_ACFNoRoom:
00990       return "There are too many names in the user accounts database.";
00991     case NERR_ACFFileIOFail:
00992       return "A disk I/O failure occurred.";
00993     case NERR_ACFTooManyLists:
00994       return "The limit of 64 entries per resource was exceeded.";
00995     case NERR_UserLogon:
00996       return "Deleting a user with a session is not allowed.";
00997     case NERR_ACFNoParent:
00998       return "The parent directory could not be located.";
00999     case NERR_CanNotGrowSegment:
01000       return "Unable to add to the security database session cache segment.";
01001     case NERR_SpeGroupOp:
01002       return "This operation is not allowed on this special group.";
01003     case NERR_NotInCache:
01004       return "This user is not cached in user accounts database session cache.";
01005     case NERR_UserInGroup:
01006       return "The user already belongs to this group.";
01007     case NERR_UserNotInGroup:
01008       return "The user does not belong to this group.";
01009     case NERR_AccountUndefined:
01010       return "This user account is undefined.";
01011     case NERR_AccountExpired:
01012       return "This user account has expired.";
01013     case NERR_InvalidWorkstation:
01014       return "The user is not allowed to log on from this workstation.";
01015     case NERR_InvalidLogonHours:
01016       return "The user is not allowed to log on at this time.";
01017     case NERR_PasswordExpired:
01018       return "The password of this user has expired.";
01019     case NERR_PasswordCantChange:
01020       return "The password of this user cannot change.";
01021     case NERR_PasswordHistConflict:
01022       return "This password cannot be used now.";
01023     case NERR_PasswordTooShort:
01024       return "The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements.";
01025     case NERR_PasswordTooRecent:
01026       return "The password of this user is too recent to change.";
01027     case NERR_InvalidDatabase:
01028       return "The security database is corrupted.";
01029     case NERR_DatabaseUpToDate:
01030       return "No updates are necessary to this replicant network/local security database.";
01031     case NERR_SyncRequired:
01032       return "This replicant database is outdated; synchronization is required.";
01033     case NERR_UseNotFound:
01034       return "The network connection could not be found.";
01035     case NERR_BadAsgType:
01036       return "This asg_type is invalid.";
01037     case NERR_DeviceIsShared:
01038       return "This device is currently being shared.";
01039     case NERR_NoComputerName:
01040       return "The computer name could not be added as a message alias. The name may already exist on the network.";
01041     case NERR_MsgAlreadyStarted:
01042       return "The Messenger service is already started.";
01043     case NERR_MsgInitFailed:
01044       return "The Messenger service failed to start.";
01045     case NERR_NameNotFound:
01046       return "The message alias could not be found on the network.";
01047     case NERR_AlreadyForwarded:
01048       return "This message alias has already been forwarded.";
01049     case NERR_AddForwarded:
01050       return "This message alias has been added but is still forwarded.";
01051     case NERR_AlreadyExists:
01052       return "This message alias already exists locally.";
01053     case NERR_TooManyNames:
01054       return "The maximum number of added message aliases has been exceeded.";
01055     case NERR_DelComputerName:
01056       return "The computer name could not be deleted.";
01057     case NERR_LocalForward:
01058       return "Messages cannot be forwarded back to the same workstation.";
01059     case NERR_GrpMsgProcessor:
01060       return "An error occurred in the domain message processor.";
01061     case NERR_PausedRemote:
01062       return "The message was sent, but the recipient has paused the Messenger service.";
01063     case NERR_BadReceive:
01064       return "The message was sent but not received.";
01065     case NERR_NameInUse:
01066       return "The message alias is currently in use. Try again later.";
01067     case NERR_MsgNotStarted:
01068       return "The Messenger service has not been started.";
01069     case NERR_NotLocalName:
01070       return "The name is not on the local computer.";
01071     case NERR_NoForwardName:
01072       return "The forwarded message alias could not be found on the network.";
01073     case NERR_RemoteFull:
01074       return "The message alias table on the remote station is full.";
01075     case NERR_NameNotForwarded:
01076       return "Messages for this alias are not currently being forwarded.";
01077     case NERR_TruncatedBroadcast:
01078       return "The broadcast message was truncated.";
01079     case NERR_InvalidDevice:
01080       return "This is an invalid device name.";
01081     case NERR_WriteFault:
01082       return "A write fault occurred.";
01083     case NERR_DuplicateName:
01084       return "A duplicate message alias exists on the network.";
01085     case NERR_DeleteLater:
01086       return "@W This message alias will be deleted later.";
01087     case NERR_IncompleteDel:
01088       return "The message alias was not successfully deleted from all networks.";
01089     case NERR_MultipleNets:
01090       return "This operation is not supported on computers with multiple networks.";
01091     case NERR_NetNameNotFound:
01092       return "This shared resource does not exist.";
01093     case NERR_DeviceNotShared:
01094       return "This device is not shared.";
01095     case NERR_ClientNameNotFound:
01096       return "A session does not exist with that computer name.";
01097     case NERR_FileIdNotFound:
01098       return "There is not an open file with that identification number.";
01099     case NERR_ExecFailure:
01100       return "A failure occurred when executing a remote administration command.";
01101     case NERR_TmpFile:
01102       return "A failure occurred when opening a remote temporary file.";
01103     case NERR_TooMuchData:
01104       return "The data returned from a remote administration command has been truncated to 64K.";
01105     case NERR_DeviceShareConflict:
01106       return "This device cannot be shared as both a spooled and a non-spooled resource.";
01107     case NERR_BrowserTableIncomplete:
01108       return "The information in the list of servers may be incorrect.";
01109     case NERR_NotLocalDomain:
01110       return "The computer is not active in this domain.";
01111 #ifdef NERR_IsDfsShare
01112 
01113     case NERR_IsDfsShare:
01114       return "The share must be removed from the Distributed File System before it can be deleted.";
01115 #endif
01116 
01117     case NERR_DevInvalidOpCode:
01118       return "The operation is invalid for this device.";
01119     case NERR_DevNotFound:
01120       return "This device cannot be shared.";
01121     case NERR_DevNotOpen:
01122       return "This device was not open.";
01123     case NERR_BadQueueDevString:
01124       return "This device name list is invalid.";
01125     case NERR_BadQueuePriority:
01126       return "The queue priority is invalid.";
01127     case NERR_NoCommDevs:
01128       return "There are no shared communication devices.";
01129     case NERR_QueueNotFound:
01130       return "The queue you specified does not exist.";
01131     case NERR_BadDevString:
01132       return "This list of devices is invalid.";
01133     case NERR_BadDev:
01134       return "The requested device is invalid.";
01135     case NERR_InUseBySpooler:
01136       return "This device is already in use by the spooler.";
01137     case NERR_CommDevInUse:
01138       return "This device is already in use as a communication device.";
01139     case NERR_InvalidComputer:
01140       return "This computer name is invalid.";
01141     case NERR_MaxLenExceeded:
01142       return "The string and prefix specified are too long.";
01143     case NERR_BadComponent:
01144       return "This path component is invalid.";
01145     case NERR_CantType:
01146       return "Could not determine the type of input.";
01147     case NERR_TooManyEntries:
01148       return "The buffer for types is not big enough.";
01149     case NERR_ProfileFileTooBig:
01150       return "Profile files cannot exceed 64K.";
01151     case NERR_ProfileOffset:
01152       return "The start offset is out of range.";
01153     case NERR_ProfileCleanup:
01154       return "The system cannot delete current connections to network resources.";
01155     case NERR_ProfileUnknownCmd:
01156       return "The system was unable to parse the command line in this file.";
01157     case NERR_ProfileLoadErr:
01158       return "An error occurred while loading the profile file.";
01159     case NERR_ProfileSaveErr:
01160       return "@W Errors occurred while saving the profile file. The profile was partially saved.";
01161     case NERR_LogOverflow:
01162       return "Log file %1 is full.";
01163     case NERR_LogFileChanged:
01164       return "This log file has changed between reads.";
01165     case NERR_LogFileCorrupt:
01166       return "Log file %1 is corrupt.";
01167     case NERR_SourceIsDir:
01168       return "The source path cannot be a directory.";
01169     case NERR_BadSource:
01170       return "The source path is illegal.";
01171     case NERR_BadDest:
01172       return "The destination path is illegal.";
01173     case NERR_DifferentServers:
01174       return "The source and destination paths are on different servers.";
01175     case NERR_RunSrvPaused:
01176       return "The Run server you requested is paused.";
01177     case NERR_ErrCommRunSrv:
01178       return "An error occurred when communicating with a Run server.";
01179     case NERR_ErrorExecingGhost:
01180       return "An error occurred when starting a background process.";
01181     case NERR_ShareNotFound:
01182       return "The shared resource you are connected to could not be found.";
01183     case NERR_InvalidLana:
01184       return "The LAN adapter number is invalid.";
01185     case NERR_OpenFiles:
01186       return "There are open files on the connection.";
01187     case NERR_ActiveConns:
01188       return "Active connections still exist.";
01189     case NERR_BadPasswordCore:
01190       return "This share name or password is invalid.";
01191     case NERR_DevInUse:
01192       return "The device is being accessed by an active process.";
01193     case NERR_LocalDrive:
01194       return "The drive letter is in use locally.";
01195     case NERR_AlertExists:
01196       return "The specified client is already registered for the specified event.";
01197     case NERR_TooManyAlerts:
01198       return "The alert table is full.";
01199     case NERR_NoSuchAlert:
01200       return "An invalid or nonexistent alert name was raised.";
01201     case NERR_BadRecipient:
01202       return "The alert recipient is invalid.";
01203     case NERR_AcctLimitExceeded:
01204       return "A user's session with this server has been deleted.";
01205     case NERR_InvalidLogSeek:
01206       return "The log file does not contain the requested record number.";
01207     case NERR_BadUasConfig:
01208       return "The user accounts database is not configured correctly.";
01209     case NERR_InvalidUASOp:
01210       return "This operation is not permitted when the Netlogon service is running.";
01211     case NERR_LastAdmin:
01212       return "This operation is not allowed on the last administrative account.";
01213     case NERR_DCNotFound:
01214       return "Could not find domain controller for this domain.";
01215     case NERR_LogonTrackingError:
01216       return "Could not set logon information for this user.";
01217     case NERR_NetlogonNotStarted:
01218       return "The Netlogon service has not been started.";
01219     case NERR_CanNotGrowUASFile:
01220       return "Unable to add to the user accounts database.";
01221     case NERR_TimeDiffAtDC:
01222       return "This server's clock is not synchronized with the primary domain controller's clock.";
01223     case NERR_PasswordMismatch:
01224       return "A password mismatch has been detected.";
01225     case NERR_NoSuchServer:
01226       return "The server identification does not specify a valid server.";
01227     case NERR_NoSuchSession:
01228       return "The session identification does not specify a valid session.";
01229     case NERR_NoSuchConnection:
01230       return "The connection identification does not specify a valid connection.";
01231     case NERR_TooManyServers:
01232       return "There is no space for another entry in the table of available servers.";
01233     case NERR_TooManySessions:
01234       return "The server has reached the maximum number of sessions it supports.";
01235     case NERR_TooManyConnections:
01236       return "The server has reached the maximum number of connections it supports.";
01237     case NERR_TooManyFiles:
01238       return "The server cannot open more files because it has reached its maximum number.";
01239     case NERR_NoAlternateServers:
01240       return "There are no alternate servers registered on this server.";
01241     case NERR_TryDownLevel:
01242       return "Try down-level (remote admin protocol) version of API instead.";
01243     case NERR_UPSDriverNotStarted:
01244       return "The UPS driver could not be accessed by the UPS service.";
01245     case NERR_UPSInvalidConfig:
01246       return "The UPS service is not configured correctly.";
01247     case NERR_UPSInvalidCommPort:
01248       return "The UPS service could not access the specified Comm Port.";
01249     case NERR_UPSSignalAsserted:
01250       return "The UPS indicated a line fail or low battery situation. Service not started.";
01251     case NERR_UPSShutdownFailed:
01252       return "The UPS service failed to perform a system shut down.";
01253     case NERR_BadDosRetCode:
01254       return "The program below returned an MS-DOS error code:";
01255     case NERR_ProgNeedsExtraMem:
01256       return "The program below needs more memory:";
01257     case NERR_BadDosFunction:
01258       return "The program below called an unsupported MS-DOS function:";
01259     case NERR_RemoteBootFailed:
01260       return "The workstation failed to boot.";
01261     case NERR_BadFileCheckSum:
01262       return "The file below is corrupt.";
01263     case NERR_NoRplBootSystem:
01264       return "No loader is specified in the boot-block definition file.";
01265     case NERR_RplLoadrNetBiosErr:
01266       return "NetBIOS returned an error:      The NCB and SMB are dumped above.";
01267     case NERR_RplLoadrDiskErr:
01268       return "A disk I/O error occurred.";
01269     case NERR_ImageParamErr:
01270       return "Image parameter substitution failed.";
01271     case NERR_TooManyImageParams:
01272       return "Too many image parameters cross disk sector boundaries.";
01273     case NERR_NonDosFloppyUsed:
01274       return "The image was not generated from an MS-DOS diskette formatted with /S.";
01275     case NERR_RplBootRestart:
01276       return "Remote boot will be restarted later.";
01277     case NERR_RplSrvrCallFailed:
01278       return "The call to the Remoteboot server failed.";
01279     case NERR_CantConnectRplSrvr:
01280       return "Cannot connect to the Remoteboot server.";
01281     case NERR_CantOpenImageFile:
01282       return "Cannot open image file on the Remoteboot server.";
01283     case NERR_CallingRplSrvr:
01284       return "Connecting to the Remoteboot server...";
01285     case NERR_StartingRplBoot:
01286       return "Connecting to the Remoteboot server...";
01287     case NERR_RplBootServiceTerm:
01288       return "Remote boot service was stopped; check the error log for the cause of the problem.";
01289     case NERR_RplBootStartFailed:
01290       return "Remote boot startup failed; check the error log for the cause of the problem.";
01291     case NERR_RPL_CONNECTED:
01292       return "A second connection to a Remoteboot resource is not allowed.";
01293     case NERR_BrowserConfiguredToNotRun:
01294       return "The browser service was configured with MaintainServerList=No.";
01295     case NERR_RplNoAdaptersStarted:
01296       return "Service failed to start since none of the network adapters started with this service.";
01297     case NERR_RplBadRegistry:
01298       return "Service failed to start due to bad startup information in the registry.";
01299     case NERR_RplBadDatabase:
01300       return "Service failed to start because its database is absent or corrupt.";
01301     case NERR_RplRplfilesShare:
01302       return "Service failed to start because RPLFILES share is absent.";
01303     case NERR_RplNotRplServer:
01304       return "Service failed to start because RPLUSER group is absent.";
01305     case NERR_RplCannotEnum:
01306       return "Cannot enumerate service records.";
01307     case NERR_RplWkstaInfoCorrupted:
01308       return "Workstation record information has been corrupted.";
01309     case NERR_RplWkstaNotFound:
01310       return "Workstation record was not found.";
01311     case NERR_RplWkstaNameUnavailable:
01312       return "Workstation name is in use by some other workstation.";
01313     case NERR_RplProfileInfoCorrupted:
01314       return "Profile record information has been corrupted.";
01315     case NERR_RplProfileNotFound:
01316       return "Profile record was not found.";
01317     case NERR_RplProfileNameUnavailable:
01318       return "Profile name is in use by some other profile.";
01319     case NERR_RplProfileNotEmpty:
01320       return "There are workstations using this profile.";
01321     case NERR_RplConfigInfoCorrupted:
01322       return "Configuration record information has been corrupted.";
01323     case NERR_RplConfigNotFound:
01324       return "Configuration record was not found.";
01325     case NERR_RplAdapterInfoCorrupted:
01326       return "Adapter ID record information has been corrupted.";
01327     case NERR_RplInternal:
01328       return "An internal service error has occurred.";
01329     case NERR_RplVendorInfoCorrupted:
01330       return "Vendor ID record information has been corrupted.";
01331     case NERR_RplBootInfoCorrupted:
01332       return "Boot block record information has been corrupted.";
01333     case NERR_RplWkstaNeedsUserAcct:
01334       return "The user account for this workstation record is missing.";
01335     case NERR_RplNeedsRPLUSERAcct:
01336       return "The RPLUSER local group could not be found.";
01337     case NERR_RplBootNotFound:
01338       return "Boot block record was not found.";
01339     case NERR_RplIncompatibleProfile:
01340       return "Chosen profile is incompatible with this workstation.";
01341     case NERR_RplAdapterNameUnavailable:
01342       return "Chosen network adapter ID is in use by some other workstation.";
01343     case NERR_RplConfigNotEmpty:
01344       return "There are profiles using this configuration.";
01345     case NERR_RplBootInUse:
01346       return "There are workstations, profiles, or configurations using this boot block.";
01347     case NERR_RplBackupDatabase:
01348       return "Service failed to backup Remoteboot database.";
01349     case NERR_RplAdapterNotFound:
01350       return "Adapter record was not found.";
01351     case NERR_RplVendorNotFound:
01352       return "Vendor record was not found.";
01353     case NERR_RplVendorNameUnavailable:
01354       return "Vendor name is in use by some other vendor record.";
01355     case NERR_RplBootNameUnavailable:
01356       return "(boot name, vendor ID) is in use by some other boot block record.";
01357     case NERR_RplConfigNameUnavailable:
01358       return "Configuration name is in use by some other configuration.";
01359     case NERR_DfsInternalCorruption:
01360       return "The internal database maintained by the Dfs service is corrupt.";
01361     case NERR_DfsVolumeDataCorrupt:
01362       return "One of the records in the internal Dfs database is corrupt.";
01363     case NERR_DfsNoSuchVolume:
01364       return "There is no DFS name whose entry path matches the input Entry Path.";
01365     case NERR_DfsVolumeAlreadyExists:
01366       return "A root or link with the given name already exists.";
01367     case NERR_DfsAlreadyShared:
01368       return "The server share specified is already shared in the Dfs.";
01369     case NERR_DfsNoSuchShare:
01370       return "The indicated server share does not support the indicated DFS namespace.";
01371     case NERR_DfsNotALeafVolume:
01372       return "The operation is not valid on this portion of the namespace.";
01373     case NERR_DfsLeafVolume:
01374       return "The operation is not valid on this portion of the namespace.";
01375     case NERR_DfsVolumeHasMultipleServers:
01376       return "The operation is ambiguous because the link has multiple servers.";
01377     case NERR_DfsCantCreateJunctionPoint:
01378       return "Unable to create a link.";
01379     case NERR_DfsServerNotDfsAware:
01380       return "The server is not Dfs Aware.";
01381     case NERR_DfsBadRenamePath:
01382       return "The specified rename target path is invalid.";
01383     case NERR_DfsVolumeIsOffline:
01384       return "The specified DFS link is offline.";
01385     case NERR_DfsNoSuchServer:
01386       return "The specified server is not a server for this link.";
01387     case NERR_DfsCyclicalName:
01388       return "A cycle in the Dfs name was detected.";
01389     case NERR_DfsNotSupportedInServerDfs:
01390       return "The operation is not supported on a server-based Dfs.";
01391     case NERR_DfsDuplicateService:
01392       return "This link is already supported by the specified server-share.";
01393     case NERR_DfsCantRemoveLastServerShare:
01394       return "Can't remove the last server-share supporting this root or link.";
01395     case NERR_DfsVolumeIsInterDfs:
01396       return "The operation is not supported for an Inter-DFS link.";
01397     case NERR_DfsInconsistent:
01398       return "The internal state of the Dfs Service has become inconsistent.";
01399     case NERR_DfsServerUpgraded:
01400       return "The Dfs Service has been installed on the specified server.";
01401     case NERR_DfsDataIsIdentical:
01402       return "The Dfs data being reconciled is identical.";
01403     case NERR_DfsCantRemoveDfsRoot:
01404       return "The DFS root cannot be deleted. Uninstall DFS if required.";
01405     case NERR_DfsChildOrParentInDfs:
01406       return "A child or parent directory of the share is already in a Dfs.";
01407     case NERR_DfsInternalError:
01408       return "Dfs internal error.";
01409       /* the following are not defined in mingw */
01410 #if 0
01411 
01412     case NERR_SetupAlreadyJoined:
01413       return "This machine is already joined to a domain.";
01414     case NERR_SetupNotJoined:
01415       return "This machine is not currently joined to a domain.";
01416     case NERR_SetupDomainController:
01417       return "This machine is a domain controller and cannot be unjoined from a domain.";
01418     case NERR_DefaultJoinRequired:
01419       return "The destination domain controller does not support creating machine accounts in OUs.";
01420     case NERR_InvalidWorkgroupName:
01421       return "The specified workgroup name is invalid.";
01422     case NERR_NameUsesIncompatibleCodePage:
01423       return "The specified computer name is incompatible with the default language used on the domain controller.";
01424     case NERR_ComputerAccountNotFound:
01425       return "The specified computer account could not be found.";
01426     case NERR_PersonalSku:
01427       return "This version of Windows cannot be joined to a domain.";
01428     case NERR_PasswordMustChange:
01429       return "The password must change at the next logon.";
01430     case NERR_AccountLockedOut:
01431       return "The account is locked out.";
01432     case NERR_PasswordTooLong:
01433       return "The password is too long.";
01434     case NERR_PasswordNotComplexEnough:
01435       return "The password does not meet the complexity policy.";
01436     case NERR_PasswordFilterError:
01437       return "The password does not meet the requirements of the password filter DLLs.";
01438 #endif
01439 
01440     }
01441   msg = strerror (error_number);
01442   if (msg == NULL)
01443     msg = "unknown";
01444 
01445   return msg;
01446 #endif //DBUS_WINCE
01447 }
01448 
01463 dbus_bool_t
01464 _dbus_command_for_pid (unsigned long  pid,
01465                        DBusString    *str,
01466                        int            max_len,
01467                        DBusError     *error)
01468 {
01469   // FIXME
01470   return FALSE;
01471 }
01472 
01473 /*
01474  * replaces the term DBUS_PREFIX in configure_time_path by the
01475  * current dbus installation directory. On unix this function is a noop
01476  *
01477  * @param configure_time_path
01478  * @return real path
01479  */
01480 const char *
01481 _dbus_replace_install_prefix (const char *configure_time_path)
01482 {
01483 #ifndef DBUS_PREFIX
01484   return configure_time_path;
01485 #else
01486   static char retval[1000];
01487   static char runtime_prefix[1000];
01488   int len = 1000;
01489   int i;
01490 
01491   if (!configure_time_path)
01492     return NULL;
01493 
01494   if ((!_dbus_get_install_root(runtime_prefix, len) ||
01495        strncmp (configure_time_path, DBUS_PREFIX "/",
01496                 strlen (DBUS_PREFIX) + 1))) {
01497      strncpy (retval, configure_time_path, sizeof (retval) - 1);
01498      /* strncpy does not guarantee to 0-terminate the string */
01499      retval[sizeof (retval) - 1] = '\0';
01500   } else {
01501      size_t remaining;
01502 
01503      strncpy (retval, runtime_prefix, sizeof (retval) - 1);
01504      retval[sizeof (retval) - 1] = '\0';
01505      remaining = sizeof (retval) - 1 - strlen (retval);
01506      strncat (retval,
01507          configure_time_path + strlen (DBUS_PREFIX) + 1,
01508          remaining);
01509   }
01510 
01511   /* Somehow, in some situations, backslashes get collapsed in the string.
01512    * Since windows C library accepts both forward and backslashes as
01513    * path separators, convert all backslashes to forward slashes.
01514    */
01515 
01516   for(i = 0; retval[i] != '\0'; i++) {
01517     if(retval[i] == '\\')
01518       retval[i] = '/';
01519   }
01520   return retval;
01521 #endif
01522 }
01523 
01530 static const char *
01531 _dbus_windows_get_datadir (void)
01532 {
01533         return _dbus_replace_install_prefix(DBUS_DATADIR);
01534 }
01535 
01536 #undef DBUS_DATADIR
01537 #define DBUS_DATADIR _dbus_windows_get_datadir ()
01538 
01539 
01540 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
01541 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
01542 
01559 dbus_bool_t
01560 _dbus_get_standard_session_servicedirs (DBusList **dirs)
01561 {
01562   const char *common_progs;
01563   DBusString servicedir_path;
01564 
01565   if (!_dbus_string_init (&servicedir_path))
01566     return FALSE;
01567 
01568 #ifdef DBUS_WINCE
01569   {
01570     /* On Windows CE, we adjust datadir dynamically to installation location.  */
01571     const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
01572 
01573     if (data_dir != NULL)
01574       {
01575         if (!_dbus_string_append (&servicedir_path, data_dir))
01576           goto oom;
01577 
01578         if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
01579           goto oom;
01580       }
01581   }
01582 #else
01583 /*
01584  the code for accessing services requires absolute base pathes
01585  in case DBUS_DATADIR is relative make it absolute
01586 */
01587 #ifdef DBUS_WIN
01588   {
01589     DBusString p;
01590 
01591     _dbus_string_init_const (&p, DBUS_DATADIR);
01592 
01593     if (!_dbus_path_is_absolute (&p))
01594       {
01595         char install_root[1000];
01596         if (_dbus_get_install_root (install_root, sizeof(install_root)))
01597           if (!_dbus_string_append (&servicedir_path, install_root))
01598             goto oom;
01599       }
01600   }
01601 #endif
01602   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
01603     goto oom;
01604 
01605   if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
01606     goto oom;
01607 #endif
01608 
01609   common_progs = _dbus_getenv ("CommonProgramFiles");
01610 
01611   if (common_progs != NULL)
01612     {
01613       if (!_dbus_string_append (&servicedir_path, common_progs))
01614         goto oom;
01615 
01616       if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
01617         goto oom;
01618     }
01619 
01620   if (!_dbus_split_paths_and_append (&servicedir_path,
01621                                DBUS_STANDARD_SESSION_SERVICEDIR,
01622                                dirs))
01623     goto oom;
01624 
01625   _dbus_string_free (&servicedir_path);
01626   return TRUE;
01627 
01628  oom:
01629   _dbus_string_free (&servicedir_path);
01630   return FALSE;
01631 }
01632 
01651 dbus_bool_t
01652 _dbus_get_standard_system_servicedirs (DBusList **dirs)
01653 {
01654   *dirs = NULL;
01655   return TRUE;
01656 }
01657 
01658 static dbus_bool_t
01659 _dbus_get_config_file_name (DBusString *str,
01660                             const char *basename)
01661 {
01662   DBusString tmp;
01663 
01664   if (!_dbus_string_append (str, _dbus_windows_get_datadir ()))
01665     return FALSE;
01666 
01667   _dbus_string_init_const (&tmp, "dbus-1");
01668 
01669   if (!_dbus_concat_dir_and_file (str, &tmp))
01670     return FALSE;
01671 
01672   _dbus_string_init_const (&tmp, basename);
01673 
01674   if (!_dbus_concat_dir_and_file (str, &tmp))
01675     return FALSE;
01676 
01677   return TRUE;
01678 }
01679 
01688 dbus_bool_t
01689 _dbus_append_system_config_file (DBusString *str)
01690 {
01691   return _dbus_get_config_file_name(str, "system.conf");
01692 }
01693 
01700 dbus_bool_t
01701 _dbus_append_session_config_file (DBusString *str)
01702 {
01703   return _dbus_get_config_file_name(str, "session.conf");
01704 }