~ubuntu-branches/ubuntu/maverick/dbus/maverick-security

« back to all changes in this revision

Viewing changes to dbus/dbus-sysdeps-util-win.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-27 13:06:32 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20100927130632-bqs145trvchd2lmf
Tags: 1.4.0-0ubuntu1
* New upstream release
 - Fixes https://bugs.freedesktop.org/show_bug.cgi?id=17754 Race condition in protected_change_timeout
 - Requested by various upstream KDE developers http://lists.kde.org/?t=128514970000004&r=1&w=2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 
2
/* dbus-sysdeps-util.c Would be in dbus-sysdeps.c, but not used in libdbus
 
3
 * 
 
4
 * Copyright (C) 2002, 2003, 2004, 2005  Red Hat, Inc.
 
5
 * Copyright (C) 2003 CodeFactory AB
 
6
 *
 
7
 * Licensed under the Academic Free License version 2.1
 
8
 * 
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 2 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 * 
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
22
 *
 
23
 */
 
24
 
 
25
#include <config.h>
 
26
 
 
27
#define STRSAFE_NO_DEPRECATE
 
28
 
 
29
#include "dbus-sysdeps.h"
 
30
#include "dbus-internals.h"
 
31
#include "dbus-protocol.h"
 
32
#include "dbus-string.h"
 
33
#include "dbus-sysdeps.h"
 
34
#include "dbus-sysdeps-win.h"
 
35
#include "dbus-sockets-win.h"
 
36
#include "dbus-memory.h"
 
37
#include "dbus-pipe.h"
 
38
 
 
39
#include <stdio.h>
 
40
#include <stdlib.h>
 
41
#if HAVE_ERRNO_H
 
42
#include <errno.h>
 
43
#endif
 
44
#include <winsock2.h>   // WSA error codes
 
45
 
 
46
#ifndef DBUS_WINCE
 
47
#include <io.h>
 
48
#include <lm.h>
 
49
#include <sys/stat.h>
 
50
#endif
 
51
 
 
52
 
 
53
/**
 
54
 * Does the chdir, fork, setsid, etc. to become a daemon process.
 
55
 *
 
56
 * @param pidfile #NULL, or pidfile to create
 
57
 * @param print_pid_fd file descriptor to print daemon's pid to, or -1 for none
 
58
 * @param error return location for errors
 
59
 * @param keep_umask #TRUE to keep the original umask
 
60
 * @returns #FALSE on failure
 
61
 */
 
62
dbus_bool_t
 
63
_dbus_become_daemon (const DBusString *pidfile,
 
64
                     DBusPipe         *print_pid_pipe,
 
65
                     DBusError        *error,
 
66
                     dbus_bool_t       keep_umask)
 
67
{
 
68
  return TRUE;
 
69
}
 
70
 
 
71
/**
 
72
 * Creates a file containing the process ID.
 
73
 *
 
74
 * @param filename the filename to write to
 
75
 * @param pid our process ID
 
76
 * @param error return location for errors
 
77
 * @returns #FALSE on failure
 
78
 */
 
79
static dbus_bool_t
 
80
_dbus_write_pid_file (const DBusString *filename,
 
81
                      unsigned long     pid,
 
82
                      DBusError        *error)
 
83
{
 
84
  const char *cfilename;
 
85
  HANDLE hnd;
 
86
  char pidstr[20];
 
87
  int total;
 
88
  int bytes_to_write;
 
89
 
 
90
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
91
 
 
92
  cfilename = _dbus_string_get_const_data (filename);
 
93
 
 
94
  hnd = CreateFileA (cfilename, GENERIC_WRITE,
 
95
                     FILE_SHARE_READ | FILE_SHARE_WRITE,
 
96
                     NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
 
97
                     INVALID_HANDLE_VALUE);
 
98
  if (hnd == INVALID_HANDLE_VALUE)
 
99
    {
 
100
      char *emsg = _dbus_win_error_string (GetLastError ());
 
101
      dbus_set_error (error, _dbus_win_error_from_last_error (),
 
102
                      "Could not create PID file %s: %s",
 
103
                      cfilename, emsg);
 
104
      _dbus_win_free_error_string (emsg);
 
105
      return FALSE;
 
106
    }
 
107
 
 
108
  if (snprintf (pidstr, sizeof (pidstr), "%lu\n", pid) < 0)
 
109
    {
 
110
      dbus_set_error (error, _dbus_error_from_system_errno (),
 
111
                      "Failed to format PID for \"%s\": %s", cfilename,
 
112
                      _dbus_strerror_from_errno ());
 
113
      CloseHandle (hnd);
 
114
      return FALSE;
 
115
    }
 
116
 
 
117
  total = 0;
 
118
  bytes_to_write = strlen (pidstr);;
 
119
 
 
120
  while (total < bytes_to_write)
 
121
    {
 
122
      DWORD bytes_written;
 
123
      BOOL res;
 
124
 
 
125
      res = WriteFile (hnd, pidstr + total, bytes_to_write - total,
 
126
                       &bytes_written, NULL);
 
127
 
 
128
      if (res == 0 || bytes_written <= 0)
 
129
        {
 
130
          char *emsg = _dbus_win_error_string (GetLastError ());
 
131
          dbus_set_error (error, _dbus_win_error_from_last_error (),
 
132
                           "Could not write to %s: %s", cfilename, emsg);
 
133
          _dbus_win_free_error_string (emsg);
 
134
          CloseHandle (hnd);
 
135
          return FALSE;
 
136
        }
 
137
 
 
138
      total += bytes_written;
 
139
    }
 
140
 
 
141
  if (CloseHandle (hnd) == 0)
 
142
    {
 
143
      char *emsg = _dbus_win_error_string (GetLastError ());
 
144
      dbus_set_error (error, _dbus_win_error_from_last_error (),
 
145
                       "Could not close file %s: %s",
 
146
                      cfilename, emsg);
 
147
      _dbus_win_free_error_string (emsg);
 
148
 
 
149
      return FALSE;
 
150
    }
 
151
 
 
152
  return TRUE;
 
153
}
 
154
 
 
155
/**
 
156
 * Writes the given pid_to_write to a pidfile (if non-NULL) and/or to a
 
157
 * pipe (if non-NULL). Does nothing if pidfile and print_pid_pipe are both
 
158
 * NULL.
 
159
 *
 
160
 * @param pidfile the file to write to or #NULL
 
161
 * @param print_pid_pipe the pipe to write to or #NULL
 
162
 * @param pid_to_write the pid to write out
 
163
 * @param error error on failure
 
164
 * @returns FALSE if error is set
 
165
 */
 
166
dbus_bool_t
 
167
_dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
 
168
                                  DBusPipe         *print_pid_pipe,
 
169
                                  dbus_pid_t        pid_to_write,
 
170
                                  DBusError        *error)
 
171
{
 
172
  if (pidfile)
 
173
    {
 
174
      _dbus_verbose ("writing pid file %s\n", _dbus_string_get_const_data (pidfile));
 
175
      if (!_dbus_write_pid_file (pidfile,
 
176
                                 pid_to_write,
 
177
                                 error))
 
178
        {
 
179
          _dbus_verbose ("pid file write failed\n");
 
180
          _DBUS_ASSERT_ERROR_IS_SET(error);
 
181
          return FALSE;
 
182
        }
 
183
    }
 
184
  else
 
185
    {
 
186
      _dbus_verbose ("No pid file requested\n");
 
187
    }
 
188
 
 
189
  if (print_pid_pipe != NULL && _dbus_pipe_is_valid (print_pid_pipe))
 
190
    {
 
191
      DBusString pid;
 
192
      int bytes;
 
193
 
 
194
      _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd_or_handle);
 
195
 
 
196
      if (!_dbus_string_init (&pid))
 
197
        {
 
198
          _DBUS_SET_OOM (error);
 
199
          return FALSE;
 
200
        }
 
201
 
 
202
      if (!_dbus_string_append_int (&pid, pid_to_write) ||
 
203
          !_dbus_string_append (&pid, "\n"))
 
204
        {
 
205
          _dbus_string_free (&pid);
 
206
          _DBUS_SET_OOM (error);
 
207
          return FALSE;
 
208
        }
 
209
 
 
210
      bytes = _dbus_string_get_length (&pid);
 
211
      if (_dbus_pipe_write (print_pid_pipe, &pid, 0, bytes, error) != bytes)
 
212
        {
 
213
          /* _dbus_pipe_write sets error only on failure, not short write */
 
214
          if (error != NULL && !dbus_error_is_set(error))
 
215
            {
 
216
              dbus_set_error (error, DBUS_ERROR_FAILED,
 
217
                              "Printing message bus PID: did not write enough bytes\n");
 
218
            }
 
219
          _dbus_string_free (&pid);
 
220
          return FALSE;
 
221
        }
 
222
 
 
223
      _dbus_string_free (&pid);
 
224
    }
 
225
  else
 
226
    {
 
227
      _dbus_verbose ("No pid pipe to write to\n");
 
228
    }
 
229
 
 
230
  return TRUE;
 
231
}
 
232
 
 
233
/**
 
234
 * Verify that after the fork we can successfully change to this user.
 
235
 *
 
236
 * @param user the username given in the daemon configuration
 
237
 * @returns #TRUE if username is valid
 
238
 */
 
239
dbus_bool_t
 
240
_dbus_verify_daemon_user (const char *user)
 
241
{
 
242
  return TRUE;
 
243
}
 
244
 
 
245
/**
 
246
 * Changes the user and group the bus is running as.
 
247
 *
 
248
 * @param user the user to become
 
249
 * @param error return location for errors
 
250
 * @returns #FALSE on failure
 
251
 */
 
252
dbus_bool_t
 
253
_dbus_change_to_daemon_user  (const char    *user,
 
254
                              DBusError     *error)
 
255
{
 
256
  return TRUE;
 
257
}
 
258
 
 
259
void
 
260
_dbus_init_system_log (void)
 
261
{
 
262
    // FIXME!
 
263
}
 
264
 
 
265
/**
 
266
 * Log a message to the system log file (e.g. syslog on Unix).
 
267
 *
 
268
 * @param severity a severity value
 
269
 * @param msg a printf-style format string
 
270
 * @param args arguments for the format string
 
271
 *
 
272
 */
 
273
void
 
274
_dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...)
 
275
{
 
276
  va_list args;
 
277
 
 
278
  va_start (args, msg);
 
279
 
 
280
  _dbus_system_logv (severity, msg, args);
 
281
 
 
282
  va_end (args);
 
283
}
 
284
 
 
285
/**
 
286
 * Log a message to the system log file (e.g. syslog on Unix).
 
287
 *
 
288
 * @param severity a severity value
 
289
 * @param msg a printf-style format string
 
290
 * @param args arguments for the format string
 
291
 *
 
292
 * If the FATAL severity is given, this function will terminate the program
 
293
 * with an error code.
 
294
 */
 
295
void
 
296
_dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args)
 
297
{
 
298
  char *s = "";
 
299
  char buf[1024];
 
300
  
 
301
  switch(severity) 
 
302
   {
 
303
     case DBUS_SYSTEM_LOG_INFO: s = "info"; break;
 
304
     case DBUS_SYSTEM_LOG_SECURITY: s = "security"; break;
 
305
     case DBUS_SYSTEM_LOG_FATAL: s = "fatal"; break;
 
306
   }
 
307
   
 
308
  sprintf(buf,"%s%s",s,msg);
 
309
  vsprintf(buf,buf,args);
 
310
  OutputDebugStringA(buf);
 
311
  
 
312
  if (severity == DBUS_SYSTEM_LOG_FATAL)
 
313
    exit (1);
 
314
}
 
315
 
 
316
/** Installs a signal handler
 
317
 *
 
318
 * @param sig the signal to handle
 
319
 * @param handler the handler
 
320
 */
 
321
void
 
322
_dbus_set_signal_handler (int               sig,
 
323
                          DBusSignalHandler handler)
 
324
{
 
325
  _dbus_verbose ("_dbus_set_signal_handler() has to be implemented\n");
 
326
}
 
327
 
 
328
/**
 
329
 * stat() wrapper.
 
330
 *
 
331
 * @param filename the filename to stat
 
332
 * @param statbuf the stat info to fill in
 
333
 * @param error return location for error
 
334
 * @returns #FALSE if error was set
 
335
 */
 
336
dbus_bool_t
 
337
_dbus_stat(const DBusString *filename,
 
338
           DBusStat         *statbuf,
 
339
           DBusError        *error)
 
340
{
 
341
  const char *filename_c;
 
342
  WIN32_FILE_ATTRIBUTE_DATA wfad;
 
343
  char *lastdot;
 
344
  DWORD rc;
 
345
 
 
346
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
347
 
 
348
  filename_c = _dbus_string_get_const_data (filename);
 
349
 
 
350
  if (!GetFileAttributesExA (filename_c, GetFileExInfoStandard, &wfad))
 
351
    {
 
352
      _dbus_win_set_error_from_win_error (error, GetLastError ());
 
353
      return FALSE;
 
354
    }
 
355
 
 
356
  if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 
357
    statbuf->mode = _S_IFDIR;
 
358
  else
 
359
    statbuf->mode = _S_IFREG;
 
360
 
 
361
  statbuf->mode |= _S_IREAD;
 
362
  if (wfad.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
 
363
    statbuf->mode |= _S_IWRITE;
 
364
 
 
365
  lastdot = strrchr (filename_c, '.');
 
366
  if (lastdot && stricmp (lastdot, ".exe") == 0)
 
367
    statbuf->mode |= _S_IEXEC;
 
368
 
 
369
  statbuf->mode |= (statbuf->mode & 0700) >> 3;
 
370
  statbuf->mode |= (statbuf->mode & 0700) >> 6;
 
371
 
 
372
  statbuf->nlink = 1;
 
373
 
 
374
#ifdef ENABLE_UID_TO_SID
 
375
  {
 
376
    PSID owner_sid, group_sid;
 
377
    PSECURITY_DESCRIPTOR sd;
 
378
 
 
379
    sd = NULL;
 
380
    rc = GetNamedSecurityInfo ((char *) filename_c, SE_FILE_OBJECT,
 
381
                               OWNER_SECURITY_INFORMATION |
 
382
                               GROUP_SECURITY_INFORMATION,
 
383
                               &owner_sid, &group_sid,
 
384
                               NULL, NULL,
 
385
                               &sd);
 
386
    if (rc != ERROR_SUCCESS)
 
387
      {
 
388
        _dbus_win_set_error_from_win_error (error, rc);
 
389
        if (sd != NULL)
 
390
          LocalFree (sd);
 
391
        return FALSE;
 
392
      }
 
393
    
 
394
    /* FIXME */
 
395
    statbuf->uid = _dbus_win_sid_to_uid_t (owner_sid);
 
396
    statbuf->gid = _dbus_win_sid_to_uid_t (group_sid);
 
397
 
 
398
    LocalFree (sd);
 
399
  }
 
400
#else
 
401
  statbuf->uid = DBUS_UID_UNSET;
 
402
  statbuf->gid = DBUS_GID_UNSET;
 
403
#endif
 
404
 
 
405
  statbuf->size = ((dbus_int64_t) wfad.nFileSizeHigh << 32) + wfad.nFileSizeLow;
 
406
 
 
407
  statbuf->atime =
 
408
    (((dbus_int64_t) wfad.ftLastAccessTime.dwHighDateTime << 32) +
 
409
     wfad.ftLastAccessTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
 
410
 
 
411
  statbuf->mtime =
 
412
    (((dbus_int64_t) wfad.ftLastWriteTime.dwHighDateTime << 32) +
 
413
     wfad.ftLastWriteTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
 
414
 
 
415
  statbuf->ctime =
 
416
    (((dbus_int64_t) wfad.ftCreationTime.dwHighDateTime << 32) +
 
417
     wfad.ftCreationTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
 
418
 
 
419
  return TRUE;
 
420
}
 
421
 
 
422
 
 
423
/* This file is part of the KDE project
 
424
Copyright (C) 2000 Werner Almesberger
 
425
 
 
426
libc/sys/linux/sys/dirent.h - Directory entry as returned by readdir
 
427
 
 
428
This program is free software; you can redistribute it and/or
 
429
modify it under the terms of the GNU Library General Public
 
430
License as published by the Free Software Foundation; either
 
431
version 2 of the License, or (at your option) any later version.
 
432
 
 
433
This program is distributed in the hope that it will be useful,
 
434
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
435
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
436
Library General Public License for more details.
 
437
 
 
438
You should have received a copy of the GNU Library General Public License
 
439
along with this program; see the file COPYING.  If not, write to
 
440
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
441
Boston, MA 02110-1301, USA.
 
442
*/
 
443
#define HAVE_NO_D_NAMLEN        /* no struct dirent->d_namlen */
 
444
#define HAVE_DD_LOCK            /* have locking mechanism */
 
445
 
 
446
#define MAXNAMLEN 255           /* sizeof(struct dirent.d_name)-1 */
 
447
 
 
448
#define __dirfd(dir) (dir)->dd_fd
 
449
 
 
450
/* struct dirent - same as Unix */
 
451
struct dirent
 
452
  {
 
453
    long d_ino;                    /* inode (always 1 in WIN32) */
 
454
    off_t d_off;                /* offset to this dirent */
 
455
    unsigned short d_reclen;    /* length of d_name */
 
456
    char d_name[_MAX_FNAME+1];    /* filename (null terminated) */
 
457
  };
 
458
 
 
459
/* typedef DIR - not the same as Unix */
 
460
typedef struct
 
461
  {
 
462
    HANDLE handle;              /* FindFirst/FindNext handle */
 
463
    short offset;               /* offset into directory */
 
464
    short finished;             /* 1 if there are not more files */
 
465
    WIN32_FIND_DATAA fileinfo;  /* from FindFirst/FindNext */
 
466
    char *dir;                  /* the dir we are reading */
 
467
    struct dirent dent;         /* the dirent to return */
 
468
  }
 
469
DIR;
 
470
 
 
471
/**********************************************************************
 
472
* Implement dirent-style opendir/readdir/closedir on Window 95/NT
 
473
*
 
474
* Functions defined are opendir(), readdir() and closedir() with the
 
475
* same prototypes as the normal dirent.h implementation.
 
476
*
 
477
* Does not implement telldir(), seekdir(), rewinddir() or scandir().
 
478
* The dirent struct is compatible with Unix, except that d_ino is
 
479
* always 1 and d_off is made up as we go along.
 
480
*
 
481
* Error codes are not available with errno but GetLastError.
 
482
*
 
483
* The DIR typedef is not compatible with Unix.
 
484
**********************************************************************/
 
485
 
 
486
static DIR * _dbus_opendir(const char *dir)
 
487
{
 
488
  DIR *dp;
 
489
  char *filespec;
 
490
  HANDLE handle;
 
491
  int index;
 
492
 
 
493
  filespec = malloc(strlen(dir) + 2 + 1);
 
494
  strcpy(filespec, dir);
 
495
  index = strlen(filespec) - 1;
 
496
  if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
 
497
    filespec[index] = '\0';
 
498
  strcat(filespec, "\\*");
 
499
 
 
500
  dp = (DIR *)malloc(sizeof(DIR));
 
501
  dp->offset = 0;
 
502
  dp->finished = 0;
 
503
  dp->dir = strdup(dir);
 
504
 
 
505
  handle = FindFirstFileA(filespec, &(dp->fileinfo));
 
506
  if (handle == INVALID_HANDLE_VALUE)
 
507
    {
 
508
      if (GetLastError() == ERROR_NO_MORE_FILES)
 
509
        dp->finished = 1;
 
510
      else
 
511
        return NULL;
 
512
    }
 
513
 
 
514
  dp->handle = handle;
 
515
  free(filespec);
 
516
 
 
517
  return dp;
 
518
}
 
519
 
 
520
static struct dirent * _dbus_readdir(DIR *dp)
 
521
{
 
522
  int saved_err = GetLastError();
 
523
 
 
524
  if (!dp || dp->finished)
 
525
    return NULL;
 
526
 
 
527
  if (dp->offset != 0)
 
528
    {
 
529
      if (FindNextFileA(dp->handle, &(dp->fileinfo)) == 0)
 
530
        {
 
531
          if (GetLastError() == ERROR_NO_MORE_FILES)
 
532
            {
 
533
              SetLastError(saved_err);
 
534
              dp->finished = 1;
 
535
            }
 
536
          return NULL;
 
537
        }
 
538
    }
 
539
  dp->offset++;
 
540
  
 
541
  strncpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME);
 
542
  dp->dent.d_ino = 1;
 
543
  dp->dent.d_reclen = strlen(dp->dent.d_name);
 
544
  dp->dent.d_off = dp->offset;
 
545
  
 
546
  return &(dp->dent);
 
547
}
 
548
 
 
549
 
 
550
static int _dbus_closedir(DIR *dp)
 
551
{
 
552
  if (!dp)
 
553
    return 0;
 
554
  FindClose(dp->handle);
 
555
  if (dp->dir)
 
556
    free(dp->dir);
 
557
  if (dp)
 
558
    free(dp);
 
559
 
 
560
  return 0;
 
561
}
 
562
 
 
563
 
 
564
/**
 
565
 * Internals of directory iterator
 
566
 */
 
567
struct DBusDirIter
 
568
  {
 
569
    DIR *d; /**< The DIR* from opendir() */
 
570
 
 
571
  };
 
572
 
 
573
/**
 
574
 * Open a directory to iterate over.
 
575
 *
 
576
 * @param filename the directory name
 
577
 * @param error exception return object or #NULL
 
578
 * @returns new iterator, or #NULL on error
 
579
 */
 
580
DBusDirIter*
 
581
_dbus_directory_open (const DBusString *filename,
 
582
                      DBusError        *error)
 
583
{
 
584
  DIR *d;
 
585
  DBusDirIter *iter;
 
586
  const char *filename_c;
 
587
 
 
588
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
589
 
 
590
  filename_c = _dbus_string_get_const_data (filename);
 
591
 
 
592
  d = _dbus_opendir (filename_c);
 
593
  if (d == NULL)
 
594
    {
 
595
      char *emsg = _dbus_win_error_string (GetLastError ());
 
596
      dbus_set_error (error, _dbus_win_error_from_last_error (),
 
597
                      "Failed to read directory \"%s\": %s",
 
598
                      filename_c, emsg);
 
599
      _dbus_win_free_error_string (emsg);
 
600
      return NULL;
 
601
    }
 
602
  iter = dbus_new0 (DBusDirIter, 1);
 
603
  if (iter == NULL)
 
604
    {
 
605
      _dbus_closedir (d);
 
606
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
 
607
                      "Could not allocate memory for directory iterator");
 
608
      return NULL;
 
609
    }
 
610
 
 
611
  iter->d = d;
 
612
 
 
613
  return iter;
 
614
}
 
615
 
 
616
/**
 
617
 * Get next file in the directory. Will not return "." or ".."  on
 
618
 * UNIX. If an error occurs, the contents of "filename" are
 
619
 * undefined. The error is never set if the function succeeds.
 
620
 *
 
621
 * @todo for thread safety, I think we have to use
 
622
 * readdir_r(). (GLib has the same issue, should file a bug.)
 
623
 *
 
624
 * @param iter the iterator
 
625
 * @param filename string to be set to the next file in the dir
 
626
 * @param error return location for error
 
627
 * @returns #TRUE if filename was filled in with a new filename
 
628
 */
 
629
dbus_bool_t
 
630
_dbus_directory_get_next_file (DBusDirIter      *iter,
 
631
                               DBusString       *filename,
 
632
                               DBusError        *error)
 
633
{
 
634
  struct dirent *ent;
 
635
 
 
636
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
637
 
 
638
again:
 
639
  SetLastError (0);
 
640
  ent = _dbus_readdir (iter->d);
 
641
  if (ent == NULL)
 
642
    {
 
643
      if (GetLastError() != 0)
 
644
        {
 
645
          char *emsg = _dbus_win_error_string (GetLastError ());
 
646
          dbus_set_error (error, _dbus_win_error_from_last_error (),
 
647
                          "Failed to get next in directory: %s", emsg);
 
648
          _dbus_win_free_error_string (emsg);
 
649
        }
 
650
      return FALSE;
 
651
    }
 
652
  else if (ent->d_name[0] == '.' &&
 
653
           (ent->d_name[1] == '\0' ||
 
654
            (ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
 
655
    goto again;
 
656
  else
 
657
    {
 
658
      _dbus_string_set_length (filename, 0);
 
659
      if (!_dbus_string_append (filename, ent->d_name))
 
660
        {
 
661
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
 
662
                          "No memory to read directory entry");
 
663
          return FALSE;
 
664
        }
 
665
      else
 
666
        return TRUE;
 
667
    }
 
668
}
 
669
 
 
670
/**
 
671
 * Closes a directory iteration.
 
672
 */
 
673
void
 
674
_dbus_directory_close (DBusDirIter *iter)
 
675
{
 
676
  _dbus_closedir (iter->d);
 
677
  dbus_free (iter);
 
678
}
 
679
 
 
680
/**
 
681
 * Checks whether the filename is an absolute path
 
682
 *
 
683
 * @param filename the filename
 
684
 * @returns #TRUE if an absolute path
 
685
 */
 
686
dbus_bool_t
 
687
_dbus_path_is_absolute (const DBusString *filename)
 
688
{
 
689
  if (_dbus_string_get_length (filename) > 0)
 
690
    return _dbus_string_get_byte (filename, 1) == ':'
 
691
           || _dbus_string_get_byte (filename, 0) == '\\'
 
692
           || _dbus_string_get_byte (filename, 0) == '/';
 
693
  else
 
694
    return FALSE;
 
695
}
 
696
 
 
697
/** @} */ /* End of DBusInternalsUtils functions */
 
698
 
 
699
/**
 
700
 * @addtogroup DBusString
 
701
 *
 
702
 * @{
 
703
 */
 
704
/**
 
705
 * Get the directory name from a complete filename
 
706
 * @param filename the filename
 
707
 * @param dirname string to append directory name to
 
708
 * @returns #FALSE if no memory
 
709
 */
 
710
dbus_bool_t
 
711
_dbus_string_get_dirname(const DBusString *filename,
 
712
                         DBusString       *dirname)
 
713
{
 
714
  int sep;
 
715
 
 
716
  _dbus_assert (filename != dirname);
 
717
  _dbus_assert (filename != NULL);
 
718
  _dbus_assert (dirname != NULL);
 
719
 
 
720
  /* Ignore any separators on the end */
 
721
  sep = _dbus_string_get_length (filename);
 
722
  if (sep == 0)
 
723
    return _dbus_string_append (dirname, "."); /* empty string passed in */
 
724
 
 
725
  while (sep > 0 &&
 
726
         (_dbus_string_get_byte (filename, sep - 1) == '/' ||
 
727
          _dbus_string_get_byte (filename, sep - 1) == '\\'))
 
728
    --sep;
 
729
 
 
730
  _dbus_assert (sep >= 0);
 
731
 
 
732
  if (sep == 0 ||
 
733
      (sep == 2 &&
 
734
       _dbus_string_get_byte (filename, 1) == ':' &&
 
735
       isalpha (_dbus_string_get_byte (filename, 0))))
 
736
    return _dbus_string_copy_len (filename, 0, sep + 1,
 
737
                                  dirname, _dbus_string_get_length (dirname));
 
738
 
 
739
  {
 
740
    int sep1, sep2;
 
741
    _dbus_string_find_byte_backward (filename, sep, '/', &sep1);
 
742
    _dbus_string_find_byte_backward (filename, sep, '\\', &sep2);
 
743
 
 
744
    sep = MAX (sep1, sep2);
 
745
  }
 
746
  if (sep < 0)
 
747
    return _dbus_string_append (dirname, ".");
 
748
 
 
749
  while (sep > 0 &&
 
750
         (_dbus_string_get_byte (filename, sep - 1) == '/' ||
 
751
          _dbus_string_get_byte (filename, sep - 1) == '\\'))
 
752
    --sep;
 
753
 
 
754
  _dbus_assert (sep >= 0);
 
755
 
 
756
  if ((sep == 0 ||
 
757
       (sep == 2 &&
 
758
        _dbus_string_get_byte (filename, 1) == ':' &&
 
759
        isalpha (_dbus_string_get_byte (filename, 0))))
 
760
      &&
 
761
      (_dbus_string_get_byte (filename, sep) == '/' ||
 
762
       _dbus_string_get_byte (filename, sep) == '\\'))
 
763
    return _dbus_string_copy_len (filename, 0, sep + 1,
 
764
                                  dirname, _dbus_string_get_length (dirname));
 
765
  else
 
766
    return _dbus_string_copy_len (filename, 0, sep - 0,
 
767
                                  dirname, _dbus_string_get_length (dirname));
 
768
}
 
769
 
 
770
 
 
771
/**
 
772
 * Checks to see if the UNIX user ID matches the UID of
 
773
 * the process. Should always return #FALSE on Windows.
 
774
 *
 
775
 * @param uid the UNIX user ID
 
776
 * @returns #TRUE if this uid owns the process.
 
777
 */
 
778
dbus_bool_t
 
779
_dbus_unix_user_is_process_owner (dbus_uid_t uid)
 
780
{
 
781
  return FALSE;
 
782
}
 
783
 
 
784
dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid)
 
785
{
 
786
  return TRUE;
 
787
}
 
788
 
 
789
/*=====================================================================
 
790
  unix emulation functions - should be removed sometime in the future
 
791
 =====================================================================*/
 
792
 
 
793
/**
 
794
 * Checks to see if the UNIX user ID is at the console.
 
795
 * Should always fail on Windows (set the error to
 
796
 * #DBUS_ERROR_NOT_SUPPORTED).
 
797
 *
 
798
 * @param uid UID of person to check 
 
799
 * @param error return location for errors
 
800
 * @returns #TRUE if the UID is the same as the console user and there are no errors
 
801
 */
 
802
dbus_bool_t
 
803
_dbus_unix_user_is_at_console (dbus_uid_t         uid,
 
804
                               DBusError         *error)
 
805
{
 
806
  dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
 
807
                  "UNIX user IDs not supported on Windows\n");
 
808
  return FALSE;
 
809
}
 
810
 
 
811
 
 
812
/**
 
813
 * Parse a UNIX group from the bus config file. On Windows, this should
 
814
 * simply always fail (just return #FALSE).
 
815
 *
 
816
 * @param groupname the groupname text
 
817
 * @param gid_p place to return the gid
 
818
 * @returns #TRUE on success
 
819
 */
 
820
dbus_bool_t
 
821
_dbus_parse_unix_group_from_config (const DBusString  *groupname,
 
822
                                    dbus_gid_t        *gid_p)
 
823
{
 
824
  return FALSE;
 
825
}
 
826
 
 
827
/**
 
828
 * Parse a UNIX user from the bus config file. On Windows, this should
 
829
 * simply always fail (just return #FALSE).
 
830
 *
 
831
 * @param username the username text
 
832
 * @param uid_p place to return the uid
 
833
 * @returns #TRUE on success
 
834
 */
 
835
dbus_bool_t
 
836
_dbus_parse_unix_user_from_config (const DBusString  *username,
 
837
                                   dbus_uid_t        *uid_p)
 
838
{
 
839
  return FALSE;
 
840
}
 
841
 
 
842
 
 
843
/**
 
844
 * Gets all groups corresponding to the given UNIX user ID. On UNIX,
 
845
 * just calls _dbus_groups_from_uid(). On Windows, should always
 
846
 * fail since we don't know any UNIX groups.
 
847
 *
 
848
 * @param uid the UID
 
849
 * @param group_ids return location for array of group IDs
 
850
 * @param n_group_ids return location for length of returned array
 
851
 * @returns #TRUE if the UID existed and we got some credentials
 
852
 */
 
853
dbus_bool_t
 
854
_dbus_unix_groups_from_uid (dbus_uid_t            uid,
 
855
                            dbus_gid_t          **group_ids,
 
856
                            int                  *n_group_ids)
 
857
{
 
858
  return FALSE;
 
859
}
 
860
 
 
861
 
 
862
 
 
863
/** @} */ /* DBusString stuff */
 
864
 
 
865
/************************************************************************
 
866
 
 
867
 error handling
 
868
 
 
869
 ************************************************************************/
 
870
 
 
871
 
 
872
 
 
873
 
 
874
 
 
875
/* lan manager error codes */
 
876
const char*
 
877
_dbus_lm_strerror(int error_number)
 
878
{
 
879
#ifdef DBUS_WINCE
 
880
  // TODO
 
881
  return "unknown";
 
882
#else
 
883
  const char *msg;
 
884
  switch (error_number)
 
885
    {
 
886
    case NERR_NetNotStarted:
 
887
      return "The workstation driver is not installed.";
 
888
    case NERR_UnknownServer:
 
889
      return "The server could not be located.";
 
890
    case NERR_ShareMem:
 
891
      return "An internal error occurred. The network cannot access a shared memory segment.";
 
892
    case NERR_NoNetworkResource:
 
893
      return "A network resource shortage occurred.";
 
894
    case NERR_RemoteOnly:
 
895
      return "This operation is not supported on workstations.";
 
896
    case NERR_DevNotRedirected:
 
897
      return "The device is not connected.";
 
898
    case NERR_ServerNotStarted:
 
899
      return "The Server service is not started.";
 
900
    case NERR_ItemNotFound:
 
901
      return "The queue is empty.";
 
902
    case NERR_UnknownDevDir:
 
903
      return "The device or directory does not exist.";
 
904
    case NERR_RedirectedPath:
 
905
      return "The operation is invalid on a redirected resource.";
 
906
    case NERR_DuplicateShare:
 
907
      return "The name has already been shared.";
 
908
    case NERR_NoRoom:
 
909
      return "The server is currently out of the requested resource.";
 
910
    case NERR_TooManyItems:
 
911
      return "Requested addition of items exceeds the maximum allowed.";
 
912
    case NERR_InvalidMaxUsers:
 
913
      return "The Peer service supports only two simultaneous users.";
 
914
    case NERR_BufTooSmall:
 
915
      return "The API return buffer is too small.";
 
916
    case NERR_RemoteErr:
 
917
      return "A remote API error occurred.";
 
918
    case NERR_LanmanIniError:
 
919
      return "An error occurred when opening or reading the configuration file.";
 
920
    case NERR_NetworkError:
 
921
      return "A general network error occurred.";
 
922
    case NERR_WkstaInconsistentState:
 
923
      return "The Workstation service is in an inconsistent state. Restart the computer before restarting the Workstation service.";
 
924
    case NERR_WkstaNotStarted:
 
925
      return "The Workstation service has not been started.";
 
926
    case NERR_BrowserNotStarted:
 
927
      return "The requested information is not available.";
 
928
    case NERR_InternalError:
 
929
      return "An internal error occurred.";
 
930
    case NERR_BadTransactConfig:
 
931
      return "The server is not configured for transactions.";
 
932
    case NERR_InvalidAPI:
 
933
      return "The requested API is not supported on the remote server.";
 
934
    case NERR_BadEventName:
 
935
      return "The event name is invalid.";
 
936
    case NERR_DupNameReboot:
 
937
      return "The computer name already exists on the network. Change it and restart the computer.";
 
938
    case NERR_CfgCompNotFound:
 
939
      return "The specified component could not be found in the configuration information.";
 
940
    case NERR_CfgParamNotFound:
 
941
      return "The specified parameter could not be found in the configuration information.";
 
942
    case NERR_LineTooLong:
 
943
      return "A line in the configuration file is too long.";
 
944
    case NERR_QNotFound:
 
945
      return "The printer does not exist.";
 
946
    case NERR_JobNotFound:
 
947
      return "The print job does not exist.";
 
948
    case NERR_DestNotFound:
 
949
      return "The printer destination cannot be found.";
 
950
    case NERR_DestExists:
 
951
      return "The printer destination already exists.";
 
952
    case NERR_QExists:
 
953
      return "The printer queue already exists.";
 
954
    case NERR_QNoRoom:
 
955
      return "No more printers can be added.";
 
956
    case NERR_JobNoRoom:
 
957
      return "No more print jobs can be added.";
 
958
    case NERR_DestNoRoom:
 
959
      return "No more printer destinations can be added.";
 
960
    case NERR_DestIdle:
 
961
      return "This printer destination is idle and cannot accept control operations.";
 
962
    case NERR_DestInvalidOp:
 
963
      return "This printer destination request contains an invalid control function.";
 
964
    case NERR_ProcNoRespond:
 
965
      return "The print processor is not responding.";
 
966
    case NERR_SpoolerNotLoaded:
 
967
      return "The spooler is not running.";
 
968
    case NERR_DestInvalidState:
 
969
      return "This operation cannot be performed on the print destination in its current state.";
 
970
    case NERR_QInvalidState:
 
971
      return "This operation cannot be performed on the printer queue in its current state.";
 
972
    case NERR_JobInvalidState:
 
973
      return "This operation cannot be performed on the print job in its current state.";
 
974
    case NERR_SpoolNoMemory:
 
975
      return "A spooler memory allocation failure occurred.";
 
976
    case NERR_DriverNotFound:
 
977
      return "The device driver does not exist.";
 
978
    case NERR_DataTypeInvalid:
 
979
      return "The data type is not supported by the print processor.";
 
980
    case NERR_ProcNotFound:
 
981
      return "The print processor is not installed.";
 
982
    case NERR_ServiceTableLocked:
 
983
      return "The service database is locked.";
 
984
    case NERR_ServiceTableFull:
 
985
      return "The service table is full.";
 
986
    case NERR_ServiceInstalled:
 
987
      return "The requested service has already been started.";
 
988
    case NERR_ServiceEntryLocked:
 
989
      return "The service does not respond to control actions.";
 
990
    case NERR_ServiceNotInstalled:
 
991
      return "The service has not been started.";
 
992
    case NERR_BadServiceName:
 
993
      return "The service name is invalid.";
 
994
    case NERR_ServiceCtlTimeout:
 
995
      return "The service is not responding to the control function.";
 
996
    case NERR_ServiceCtlBusy:
 
997
      return "The service control is busy.";
 
998
    case NERR_BadServiceProgName:
 
999
      return "The configuration file contains an invalid service program name.";
 
1000
    case NERR_ServiceNotCtrl:
 
1001
      return "The service could not be controlled in its present state.";
 
1002
    case NERR_ServiceKillProc:
 
1003
      return "The service ended abnormally.";
 
1004
    case NERR_ServiceCtlNotValid:
 
1005
      return "The requested pause or stop is not valid for this service.";
 
1006
    case NERR_NotInDispatchTbl:
 
1007
      return "The service control dispatcher could not find the service name in the dispatch table.";
 
1008
    case NERR_BadControlRecv:
 
1009
      return "The service control dispatcher pipe read failed.";
 
1010
    case NERR_ServiceNotStarting:
 
1011
      return "A thread for the new service could not be created.";
 
1012
    case NERR_AlreadyLoggedOn:
 
1013
      return "This workstation is already logged on to the local-area network.";
 
1014
    case NERR_NotLoggedOn:
 
1015
      return "The workstation is not logged on to the local-area network.";
 
1016
    case NERR_BadUsername:
 
1017
      return "The user name or group name parameter is invalid.";
 
1018
    case NERR_BadPassword:
 
1019
      return "The password parameter is invalid.";
 
1020
    case NERR_UnableToAddName_W:
 
1021
      return "@W The logon processor did not add the message alias.";
 
1022
    case NERR_UnableToAddName_F:
 
1023
      return "The logon processor did not add the message alias.";
 
1024
    case NERR_UnableToDelName_W:
 
1025
      return "@W The logoff processor did not delete the message alias.";
 
1026
    case NERR_UnableToDelName_F:
 
1027
      return "The logoff processor did not delete the message alias.";
 
1028
    case NERR_LogonsPaused:
 
1029
      return "Network logons are paused.";
 
1030
    case NERR_LogonServerConflict:
 
1031
      return "A centralized logon-server conflict occurred.";
 
1032
    case NERR_LogonNoUserPath:
 
1033
      return "The server is configured without a valid user path.";
 
1034
    case NERR_LogonScriptError:
 
1035
      return "An error occurred while loading or running the logon script.";
 
1036
    case NERR_StandaloneLogon:
 
1037
      return "The logon server was not specified. Your computer will be logged on as STANDALONE.";
 
1038
    case NERR_LogonServerNotFound:
 
1039
      return "The logon server could not be found.";
 
1040
    case NERR_LogonDomainExists:
 
1041
      return "There is already a logon domain for this computer.";
 
1042
    case NERR_NonValidatedLogon:
 
1043
      return "The logon server could not validate the logon.";
 
1044
    case NERR_ACFNotFound:
 
1045
      return "The security database could not be found.";
 
1046
    case NERR_GroupNotFound:
 
1047
      return "The group name could not be found.";
 
1048
    case NERR_UserNotFound:
 
1049
      return "The user name could not be found.";
 
1050
    case NERR_ResourceNotFound:
 
1051
      return "The resource name could not be found.";
 
1052
    case NERR_GroupExists:
 
1053
      return "The group already exists.";
 
1054
    case NERR_UserExists:
 
1055
      return "The user account already exists.";
 
1056
    case NERR_ResourceExists:
 
1057
      return "The resource permission list already exists.";
 
1058
    case NERR_NotPrimary:
 
1059
      return "This operation is only allowed on the primary domain controller of the domain.";
 
1060
    case NERR_ACFNotLoaded:
 
1061
      return "The security database has not been started.";
 
1062
    case NERR_ACFNoRoom:
 
1063
      return "There are too many names in the user accounts database.";
 
1064
    case NERR_ACFFileIOFail:
 
1065
      return "A disk I/O failure occurred.";
 
1066
    case NERR_ACFTooManyLists:
 
1067
      return "The limit of 64 entries per resource was exceeded.";
 
1068
    case NERR_UserLogon:
 
1069
      return "Deleting a user with a session is not allowed.";
 
1070
    case NERR_ACFNoParent:
 
1071
      return "The parent directory could not be located.";
 
1072
    case NERR_CanNotGrowSegment:
 
1073
      return "Unable to add to the security database session cache segment.";
 
1074
    case NERR_SpeGroupOp:
 
1075
      return "This operation is not allowed on this special group.";
 
1076
    case NERR_NotInCache:
 
1077
      return "This user is not cached in user accounts database session cache.";
 
1078
    case NERR_UserInGroup:
 
1079
      return "The user already belongs to this group.";
 
1080
    case NERR_UserNotInGroup:
 
1081
      return "The user does not belong to this group.";
 
1082
    case NERR_AccountUndefined:
 
1083
      return "This user account is undefined.";
 
1084
    case NERR_AccountExpired:
 
1085
      return "This user account has expired.";
 
1086
    case NERR_InvalidWorkstation:
 
1087
      return "The user is not allowed to log on from this workstation.";
 
1088
    case NERR_InvalidLogonHours:
 
1089
      return "The user is not allowed to log on at this time.";
 
1090
    case NERR_PasswordExpired:
 
1091
      return "The password of this user has expired.";
 
1092
    case NERR_PasswordCantChange:
 
1093
      return "The password of this user cannot change.";
 
1094
    case NERR_PasswordHistConflict:
 
1095
      return "This password cannot be used now.";
 
1096
    case NERR_PasswordTooShort:
 
1097
      return "The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements.";
 
1098
    case NERR_PasswordTooRecent:
 
1099
      return "The password of this user is too recent to change.";
 
1100
    case NERR_InvalidDatabase:
 
1101
      return "The security database is corrupted.";
 
1102
    case NERR_DatabaseUpToDate:
 
1103
      return "No updates are necessary to this replicant network/local security database.";
 
1104
    case NERR_SyncRequired:
 
1105
      return "This replicant database is outdated; synchronization is required.";
 
1106
    case NERR_UseNotFound:
 
1107
      return "The network connection could not be found.";
 
1108
    case NERR_BadAsgType:
 
1109
      return "This asg_type is invalid.";
 
1110
    case NERR_DeviceIsShared:
 
1111
      return "This device is currently being shared.";
 
1112
    case NERR_NoComputerName:
 
1113
      return "The computer name could not be added as a message alias. The name may already exist on the network.";
 
1114
    case NERR_MsgAlreadyStarted:
 
1115
      return "The Messenger service is already started.";
 
1116
    case NERR_MsgInitFailed:
 
1117
      return "The Messenger service failed to start.";
 
1118
    case NERR_NameNotFound:
 
1119
      return "The message alias could not be found on the network.";
 
1120
    case NERR_AlreadyForwarded:
 
1121
      return "This message alias has already been forwarded.";
 
1122
    case NERR_AddForwarded:
 
1123
      return "This message alias has been added but is still forwarded.";
 
1124
    case NERR_AlreadyExists:
 
1125
      return "This message alias already exists locally.";
 
1126
    case NERR_TooManyNames:
 
1127
      return "The maximum number of added message aliases has been exceeded.";
 
1128
    case NERR_DelComputerName:
 
1129
      return "The computer name could not be deleted.";
 
1130
    case NERR_LocalForward:
 
1131
      return "Messages cannot be forwarded back to the same workstation.";
 
1132
    case NERR_GrpMsgProcessor:
 
1133
      return "An error occurred in the domain message processor.";
 
1134
    case NERR_PausedRemote:
 
1135
      return "The message was sent, but the recipient has paused the Messenger service.";
 
1136
    case NERR_BadReceive:
 
1137
      return "The message was sent but not received.";
 
1138
    case NERR_NameInUse:
 
1139
      return "The message alias is currently in use. Try again later.";
 
1140
    case NERR_MsgNotStarted:
 
1141
      return "The Messenger service has not been started.";
 
1142
    case NERR_NotLocalName:
 
1143
      return "The name is not on the local computer.";
 
1144
    case NERR_NoForwardName:
 
1145
      return "The forwarded message alias could not be found on the network.";
 
1146
    case NERR_RemoteFull:
 
1147
      return "The message alias table on the remote station is full.";
 
1148
    case NERR_NameNotForwarded:
 
1149
      return "Messages for this alias are not currently being forwarded.";
 
1150
    case NERR_TruncatedBroadcast:
 
1151
      return "The broadcast message was truncated.";
 
1152
    case NERR_InvalidDevice:
 
1153
      return "This is an invalid device name.";
 
1154
    case NERR_WriteFault:
 
1155
      return "A write fault occurred.";
 
1156
    case NERR_DuplicateName:
 
1157
      return "A duplicate message alias exists on the network.";
 
1158
    case NERR_DeleteLater:
 
1159
      return "@W This message alias will be deleted later.";
 
1160
    case NERR_IncompleteDel:
 
1161
      return "The message alias was not successfully deleted from all networks.";
 
1162
    case NERR_MultipleNets:
 
1163
      return "This operation is not supported on computers with multiple networks.";
 
1164
    case NERR_NetNameNotFound:
 
1165
      return "This shared resource does not exist.";
 
1166
    case NERR_DeviceNotShared:
 
1167
      return "This device is not shared.";
 
1168
    case NERR_ClientNameNotFound:
 
1169
      return "A session does not exist with that computer name.";
 
1170
    case NERR_FileIdNotFound:
 
1171
      return "There is not an open file with that identification number.";
 
1172
    case NERR_ExecFailure:
 
1173
      return "A failure occurred when executing a remote administration command.";
 
1174
    case NERR_TmpFile:
 
1175
      return "A failure occurred when opening a remote temporary file.";
 
1176
    case NERR_TooMuchData:
 
1177
      return "The data returned from a remote administration command has been truncated to 64K.";
 
1178
    case NERR_DeviceShareConflict:
 
1179
      return "This device cannot be shared as both a spooled and a non-spooled resource.";
 
1180
    case NERR_BrowserTableIncomplete:
 
1181
      return "The information in the list of servers may be incorrect.";
 
1182
    case NERR_NotLocalDomain:
 
1183
      return "The computer is not active in this domain.";
 
1184
#ifdef NERR_IsDfsShare
 
1185
 
 
1186
    case NERR_IsDfsShare:
 
1187
      return "The share must be removed from the Distributed File System before it can be deleted.";
 
1188
#endif
 
1189
 
 
1190
    case NERR_DevInvalidOpCode:
 
1191
      return "The operation is invalid for this device.";
 
1192
    case NERR_DevNotFound:
 
1193
      return "This device cannot be shared.";
 
1194
    case NERR_DevNotOpen:
 
1195
      return "This device was not open.";
 
1196
    case NERR_BadQueueDevString:
 
1197
      return "This device name list is invalid.";
 
1198
    case NERR_BadQueuePriority:
 
1199
      return "The queue priority is invalid.";
 
1200
    case NERR_NoCommDevs:
 
1201
      return "There are no shared communication devices.";
 
1202
    case NERR_QueueNotFound:
 
1203
      return "The queue you specified does not exist.";
 
1204
    case NERR_BadDevString:
 
1205
      return "This list of devices is invalid.";
 
1206
    case NERR_BadDev:
 
1207
      return "The requested device is invalid.";
 
1208
    case NERR_InUseBySpooler:
 
1209
      return "This device is already in use by the spooler.";
 
1210
    case NERR_CommDevInUse:
 
1211
      return "This device is already in use as a communication device.";
 
1212
    case NERR_InvalidComputer:
 
1213
      return "This computer name is invalid.";
 
1214
    case NERR_MaxLenExceeded:
 
1215
      return "The string and prefix specified are too long.";
 
1216
    case NERR_BadComponent:
 
1217
      return "This path component is invalid.";
 
1218
    case NERR_CantType:
 
1219
      return "Could not determine the type of input.";
 
1220
    case NERR_TooManyEntries:
 
1221
      return "The buffer for types is not big enough.";
 
1222
    case NERR_ProfileFileTooBig:
 
1223
      return "Profile files cannot exceed 64K.";
 
1224
    case NERR_ProfileOffset:
 
1225
      return "The start offset is out of range.";
 
1226
    case NERR_ProfileCleanup:
 
1227
      return "The system cannot delete current connections to network resources.";
 
1228
    case NERR_ProfileUnknownCmd:
 
1229
      return "The system was unable to parse the command line in this file.";
 
1230
    case NERR_ProfileLoadErr:
 
1231
      return "An error occurred while loading the profile file.";
 
1232
    case NERR_ProfileSaveErr:
 
1233
      return "@W Errors occurred while saving the profile file. The profile was partially saved.";
 
1234
    case NERR_LogOverflow:
 
1235
      return "Log file %1 is full.";
 
1236
    case NERR_LogFileChanged:
 
1237
      return "This log file has changed between reads.";
 
1238
    case NERR_LogFileCorrupt:
 
1239
      return "Log file %1 is corrupt.";
 
1240
    case NERR_SourceIsDir:
 
1241
      return "The source path cannot be a directory.";
 
1242
    case NERR_BadSource:
 
1243
      return "The source path is illegal.";
 
1244
    case NERR_BadDest:
 
1245
      return "The destination path is illegal.";
 
1246
    case NERR_DifferentServers:
 
1247
      return "The source and destination paths are on different servers.";
 
1248
    case NERR_RunSrvPaused:
 
1249
      return "The Run server you requested is paused.";
 
1250
    case NERR_ErrCommRunSrv:
 
1251
      return "An error occurred when communicating with a Run server.";
 
1252
    case NERR_ErrorExecingGhost:
 
1253
      return "An error occurred when starting a background process.";
 
1254
    case NERR_ShareNotFound:
 
1255
      return "The shared resource you are connected to could not be found.";
 
1256
    case NERR_InvalidLana:
 
1257
      return "The LAN adapter number is invalid.";
 
1258
    case NERR_OpenFiles:
 
1259
      return "There are open files on the connection.";
 
1260
    case NERR_ActiveConns:
 
1261
      return "Active connections still exist.";
 
1262
    case NERR_BadPasswordCore:
 
1263
      return "This share name or password is invalid.";
 
1264
    case NERR_DevInUse:
 
1265
      return "The device is being accessed by an active process.";
 
1266
    case NERR_LocalDrive:
 
1267
      return "The drive letter is in use locally.";
 
1268
    case NERR_AlertExists:
 
1269
      return "The specified client is already registered for the specified event.";
 
1270
    case NERR_TooManyAlerts:
 
1271
      return "The alert table is full.";
 
1272
    case NERR_NoSuchAlert:
 
1273
      return "An invalid or nonexistent alert name was raised.";
 
1274
    case NERR_BadRecipient:
 
1275
      return "The alert recipient is invalid.";
 
1276
    case NERR_AcctLimitExceeded:
 
1277
      return "A user's session with this server has been deleted.";
 
1278
    case NERR_InvalidLogSeek:
 
1279
      return "The log file does not contain the requested record number.";
 
1280
    case NERR_BadUasConfig:
 
1281
      return "The user accounts database is not configured correctly.";
 
1282
    case NERR_InvalidUASOp:
 
1283
      return "This operation is not permitted when the Netlogon service is running.";
 
1284
    case NERR_LastAdmin:
 
1285
      return "This operation is not allowed on the last administrative account.";
 
1286
    case NERR_DCNotFound:
 
1287
      return "Could not find domain controller for this domain.";
 
1288
    case NERR_LogonTrackingError:
 
1289
      return "Could not set logon information for this user.";
 
1290
    case NERR_NetlogonNotStarted:
 
1291
      return "The Netlogon service has not been started.";
 
1292
    case NERR_CanNotGrowUASFile:
 
1293
      return "Unable to add to the user accounts database.";
 
1294
    case NERR_TimeDiffAtDC:
 
1295
      return "This server's clock is not synchronized with the primary domain controller's clock.";
 
1296
    case NERR_PasswordMismatch:
 
1297
      return "A password mismatch has been detected.";
 
1298
    case NERR_NoSuchServer:
 
1299
      return "The server identification does not specify a valid server.";
 
1300
    case NERR_NoSuchSession:
 
1301
      return "The session identification does not specify a valid session.";
 
1302
    case NERR_NoSuchConnection:
 
1303
      return "The connection identification does not specify a valid connection.";
 
1304
    case NERR_TooManyServers:
 
1305
      return "There is no space for another entry in the table of available servers.";
 
1306
    case NERR_TooManySessions:
 
1307
      return "The server has reached the maximum number of sessions it supports.";
 
1308
    case NERR_TooManyConnections:
 
1309
      return "The server has reached the maximum number of connections it supports.";
 
1310
    case NERR_TooManyFiles:
 
1311
      return "The server cannot open more files because it has reached its maximum number.";
 
1312
    case NERR_NoAlternateServers:
 
1313
      return "There are no alternate servers registered on this server.";
 
1314
    case NERR_TryDownLevel:
 
1315
      return "Try down-level (remote admin protocol) version of API instead.";
 
1316
    case NERR_UPSDriverNotStarted:
 
1317
      return "The UPS driver could not be accessed by the UPS service.";
 
1318
    case NERR_UPSInvalidConfig:
 
1319
      return "The UPS service is not configured correctly.";
 
1320
    case NERR_UPSInvalidCommPort:
 
1321
      return "The UPS service could not access the specified Comm Port.";
 
1322
    case NERR_UPSSignalAsserted:
 
1323
      return "The UPS indicated a line fail or low battery situation. Service not started.";
 
1324
    case NERR_UPSShutdownFailed:
 
1325
      return "The UPS service failed to perform a system shut down.";
 
1326
    case NERR_BadDosRetCode:
 
1327
      return "The program below returned an MS-DOS error code:";
 
1328
    case NERR_ProgNeedsExtraMem:
 
1329
      return "The program below needs more memory:";
 
1330
    case NERR_BadDosFunction:
 
1331
      return "The program below called an unsupported MS-DOS function:";
 
1332
    case NERR_RemoteBootFailed:
 
1333
      return "The workstation failed to boot.";
 
1334
    case NERR_BadFileCheckSum:
 
1335
      return "The file below is corrupt.";
 
1336
    case NERR_NoRplBootSystem:
 
1337
      return "No loader is specified in the boot-block definition file.";
 
1338
    case NERR_RplLoadrNetBiosErr:
 
1339
      return "NetBIOS returned an error:      The NCB and SMB are dumped above.";
 
1340
    case NERR_RplLoadrDiskErr:
 
1341
      return "A disk I/O error occurred.";
 
1342
    case NERR_ImageParamErr:
 
1343
      return "Image parameter substitution failed.";
 
1344
    case NERR_TooManyImageParams:
 
1345
      return "Too many image parameters cross disk sector boundaries.";
 
1346
    case NERR_NonDosFloppyUsed:
 
1347
      return "The image was not generated from an MS-DOS diskette formatted with /S.";
 
1348
    case NERR_RplBootRestart:
 
1349
      return "Remote boot will be restarted later.";
 
1350
    case NERR_RplSrvrCallFailed:
 
1351
      return "The call to the Remoteboot server failed.";
 
1352
    case NERR_CantConnectRplSrvr:
 
1353
      return "Cannot connect to the Remoteboot server.";
 
1354
    case NERR_CantOpenImageFile:
 
1355
      return "Cannot open image file on the Remoteboot server.";
 
1356
    case NERR_CallingRplSrvr:
 
1357
      return "Connecting to the Remoteboot server...";
 
1358
    case NERR_StartingRplBoot:
 
1359
      return "Connecting to the Remoteboot server...";
 
1360
    case NERR_RplBootServiceTerm:
 
1361
      return "Remote boot service was stopped; check the error log for the cause of the problem.";
 
1362
    case NERR_RplBootStartFailed:
 
1363
      return "Remote boot startup failed; check the error log for the cause of the problem.";
 
1364
    case NERR_RPL_CONNECTED:
 
1365
      return "A second connection to a Remoteboot resource is not allowed.";
 
1366
    case NERR_BrowserConfiguredToNotRun:
 
1367
      return "The browser service was configured with MaintainServerList=No.";
 
1368
    case NERR_RplNoAdaptersStarted:
 
1369
      return "Service failed to start since none of the network adapters started with this service.";
 
1370
    case NERR_RplBadRegistry:
 
1371
      return "Service failed to start due to bad startup information in the registry.";
 
1372
    case NERR_RplBadDatabase:
 
1373
      return "Service failed to start because its database is absent or corrupt.";
 
1374
    case NERR_RplRplfilesShare:
 
1375
      return "Service failed to start because RPLFILES share is absent.";
 
1376
    case NERR_RplNotRplServer:
 
1377
      return "Service failed to start because RPLUSER group is absent.";
 
1378
    case NERR_RplCannotEnum:
 
1379
      return "Cannot enumerate service records.";
 
1380
    case NERR_RplWkstaInfoCorrupted:
 
1381
      return "Workstation record information has been corrupted.";
 
1382
    case NERR_RplWkstaNotFound:
 
1383
      return "Workstation record was not found.";
 
1384
    case NERR_RplWkstaNameUnavailable:
 
1385
      return "Workstation name is in use by some other workstation.";
 
1386
    case NERR_RplProfileInfoCorrupted:
 
1387
      return "Profile record information has been corrupted.";
 
1388
    case NERR_RplProfileNotFound:
 
1389
      return "Profile record was not found.";
 
1390
    case NERR_RplProfileNameUnavailable:
 
1391
      return "Profile name is in use by some other profile.";
 
1392
    case NERR_RplProfileNotEmpty:
 
1393
      return "There are workstations using this profile.";
 
1394
    case NERR_RplConfigInfoCorrupted:
 
1395
      return "Configuration record information has been corrupted.";
 
1396
    case NERR_RplConfigNotFound:
 
1397
      return "Configuration record was not found.";
 
1398
    case NERR_RplAdapterInfoCorrupted:
 
1399
      return "Adapter ID record information has been corrupted.";
 
1400
    case NERR_RplInternal:
 
1401
      return "An internal service error has occurred.";
 
1402
    case NERR_RplVendorInfoCorrupted:
 
1403
      return "Vendor ID record information has been corrupted.";
 
1404
    case NERR_RplBootInfoCorrupted:
 
1405
      return "Boot block record information has been corrupted.";
 
1406
    case NERR_RplWkstaNeedsUserAcct:
 
1407
      return "The user account for this workstation record is missing.";
 
1408
    case NERR_RplNeedsRPLUSERAcct:
 
1409
      return "The RPLUSER local group could not be found.";
 
1410
    case NERR_RplBootNotFound:
 
1411
      return "Boot block record was not found.";
 
1412
    case NERR_RplIncompatibleProfile:
 
1413
      return "Chosen profile is incompatible with this workstation.";
 
1414
    case NERR_RplAdapterNameUnavailable:
 
1415
      return "Chosen network adapter ID is in use by some other workstation.";
 
1416
    case NERR_RplConfigNotEmpty:
 
1417
      return "There are profiles using this configuration.";
 
1418
    case NERR_RplBootInUse:
 
1419
      return "There are workstations, profiles, or configurations using this boot block.";
 
1420
    case NERR_RplBackupDatabase:
 
1421
      return "Service failed to backup Remoteboot database.";
 
1422
    case NERR_RplAdapterNotFound:
 
1423
      return "Adapter record was not found.";
 
1424
    case NERR_RplVendorNotFound:
 
1425
      return "Vendor record was not found.";
 
1426
    case NERR_RplVendorNameUnavailable:
 
1427
      return "Vendor name is in use by some other vendor record.";
 
1428
    case NERR_RplBootNameUnavailable:
 
1429
      return "(boot name, vendor ID) is in use by some other boot block record.";
 
1430
    case NERR_RplConfigNameUnavailable:
 
1431
      return "Configuration name is in use by some other configuration.";
 
1432
    case NERR_DfsInternalCorruption:
 
1433
      return "The internal database maintained by the Dfs service is corrupt.";
 
1434
    case NERR_DfsVolumeDataCorrupt:
 
1435
      return "One of the records in the internal Dfs database is corrupt.";
 
1436
    case NERR_DfsNoSuchVolume:
 
1437
      return "There is no DFS name whose entry path matches the input Entry Path.";
 
1438
    case NERR_DfsVolumeAlreadyExists:
 
1439
      return "A root or link with the given name already exists.";
 
1440
    case NERR_DfsAlreadyShared:
 
1441
      return "The server share specified is already shared in the Dfs.";
 
1442
    case NERR_DfsNoSuchShare:
 
1443
      return "The indicated server share does not support the indicated DFS namespace.";
 
1444
    case NERR_DfsNotALeafVolume:
 
1445
      return "The operation is not valid on this portion of the namespace.";
 
1446
    case NERR_DfsLeafVolume:
 
1447
      return "The operation is not valid on this portion of the namespace.";
 
1448
    case NERR_DfsVolumeHasMultipleServers:
 
1449
      return "The operation is ambiguous because the link has multiple servers.";
 
1450
    case NERR_DfsCantCreateJunctionPoint:
 
1451
      return "Unable to create a link.";
 
1452
    case NERR_DfsServerNotDfsAware:
 
1453
      return "The server is not Dfs Aware.";
 
1454
    case NERR_DfsBadRenamePath:
 
1455
      return "The specified rename target path is invalid.";
 
1456
    case NERR_DfsVolumeIsOffline:
 
1457
      return "The specified DFS link is offline.";
 
1458
    case NERR_DfsNoSuchServer:
 
1459
      return "The specified server is not a server for this link.";
 
1460
    case NERR_DfsCyclicalName:
 
1461
      return "A cycle in the Dfs name was detected.";
 
1462
    case NERR_DfsNotSupportedInServerDfs:
 
1463
      return "The operation is not supported on a server-based Dfs.";
 
1464
    case NERR_DfsDuplicateService:
 
1465
      return "This link is already supported by the specified server-share.";
 
1466
    case NERR_DfsCantRemoveLastServerShare:
 
1467
      return "Can't remove the last server-share supporting this root or link.";
 
1468
    case NERR_DfsVolumeIsInterDfs:
 
1469
      return "The operation is not supported for an Inter-DFS link.";
 
1470
    case NERR_DfsInconsistent:
 
1471
      return "The internal state of the Dfs Service has become inconsistent.";
 
1472
    case NERR_DfsServerUpgraded:
 
1473
      return "The Dfs Service has been installed on the specified server.";
 
1474
    case NERR_DfsDataIsIdentical:
 
1475
      return "The Dfs data being reconciled is identical.";
 
1476
    case NERR_DfsCantRemoveDfsRoot:
 
1477
      return "The DFS root cannot be deleted. Uninstall DFS if required.";
 
1478
    case NERR_DfsChildOrParentInDfs:
 
1479
      return "A child or parent directory of the share is already in a Dfs.";
 
1480
    case NERR_DfsInternalError:
 
1481
      return "Dfs internal error.";
 
1482
      /* the following are not defined in mingw */
 
1483
#if 0
 
1484
 
 
1485
    case NERR_SetupAlreadyJoined:
 
1486
      return "This machine is already joined to a domain.";
 
1487
    case NERR_SetupNotJoined:
 
1488
      return "This machine is not currently joined to a domain.";
 
1489
    case NERR_SetupDomainController:
 
1490
      return "This machine is a domain controller and cannot be unjoined from a domain.";
 
1491
    case NERR_DefaultJoinRequired:
 
1492
      return "The destination domain controller does not support creating machine accounts in OUs.";
 
1493
    case NERR_InvalidWorkgroupName:
 
1494
      return "The specified workgroup name is invalid.";
 
1495
    case NERR_NameUsesIncompatibleCodePage:
 
1496
      return "The specified computer name is incompatible with the default language used on the domain controller.";
 
1497
    case NERR_ComputerAccountNotFound:
 
1498
      return "The specified computer account could not be found.";
 
1499
    case NERR_PersonalSku:
 
1500
      return "This version of Windows cannot be joined to a domain.";
 
1501
    case NERR_PasswordMustChange:
 
1502
      return "The password must change at the next logon.";
 
1503
    case NERR_AccountLockedOut:
 
1504
      return "The account is locked out.";
 
1505
    case NERR_PasswordTooLong:
 
1506
      return "The password is too long.";
 
1507
    case NERR_PasswordNotComplexEnough:
 
1508
      return "The password does not meet the complexity policy.";
 
1509
    case NERR_PasswordFilterError:
 
1510
      return "The password does not meet the requirements of the password filter DLLs.";
 
1511
#endif
 
1512
 
 
1513
    }
 
1514
  msg = strerror (error_number);
 
1515
  if (msg == NULL)
 
1516
    msg = "unknown";
 
1517
 
 
1518
  return msg;
 
1519
#endif //DBUS_WINCE
 
1520
}
 
1521
 
 
1522
/**
 
1523
 * Get a printable string describing the command used to execute
 
1524
 * the process with pid.  This string should only be used for
 
1525
 * informative purposes such as logging; it may not be trusted.
 
1526
 *
 
1527
 * The command is guaranteed to be printable ASCII and no longer
 
1528
 * than max_len.
 
1529
 *
 
1530
 * @param pid Process id
 
1531
 * @param str Append command to this string
 
1532
 * @param max_len Maximum length of returned command
 
1533
 * @param error return location for errors
 
1534
 * @returns #FALSE on error
 
1535
 */
 
1536
dbus_bool_t
 
1537
_dbus_command_for_pid (unsigned long  pid,
 
1538
                       DBusString    *str,
 
1539
                       int            max_len,
 
1540
                       DBusError     *error)
 
1541
{
 
1542
  // FIXME
 
1543
  return FALSE;
 
1544
}