Example #1
0
static void
bus_data_free (void *data)
{
  BusData *bd = data;
  
  if (bd->is_well_known)
    {
      int i;
      _DBUS_LOCK (bus);
      /* We may be stored in more than one slot */
      i = 0;
      while (i < N_BUS_TYPES)
        {
          if (bus_connections[i] == bd->connection)
            bus_connections[i] = NULL;
          
          ++i;
        }
      _DBUS_UNLOCK (bus);
    }
  
  dbus_free (bd->unique_name);
  dbus_free (bd);

  dbus_connection_free_data_slot (&bus_data_slot);
}
Example #2
0
/**
 * Frees the members of info
 * (but not info itself)
 * @param info the user info struct
 */
void
_dbus_user_info_free (DBusUserInfo *info)
{
  dbus_free (info->group_ids);
  dbus_free (info->username);
  dbus_free (info->homedir);
}
Example #3
0
static void
bus_data_free (void *data)
{
  BusData *bd = data;
  
  if (bd->is_well_known)
    {
      int i;
      _DBUS_LOCK (bus);
      /* We may be stored in more than one slot */
      /* This should now be impossible - these slots are supposed to
       * be cleared on disconnect, so should not need to be cleared on
       * finalize
       */
      i = 0;
      while (i < N_BUS_TYPES)
        {
          if (bus_connections[i] == bd->connection)
            bus_connections[i] = NULL;
          
          ++i;
        }
      _DBUS_UNLOCK (bus);
    }
  
  dbus_free (bd->unique_name);
  dbus_free (bd);

  dbus_connection_free_data_slot (&bus_data_slot);
}
BOOL
MoveFileA (LPCSTR lpExistingFileName, LPCSTR lpNewFileName)
{
  wchar_t *existing_filename;
  wchar_t *new_filename;
  BOOL result;
  int err;

  existing_filename = _dbus_win_utf8_to_utf16 (lpExistingFileName, NULL);
  if (! existing_filename)
    return FALSE;

  new_filename = _dbus_win_utf8_to_utf16 (lpNewFileName, NULL);
  if (! new_filename)
    {
      dbus_free (existing_filename);
      return FALSE;
    }

  result = MoveFileW (existing_filename, new_filename);

  err = GetLastError ();
  dbus_free (existing_filename);
  dbus_free (new_filename);
  SetLastError (err);
  return result;
}
dbus_bool_t
_dbus_directory_get_next_file (DBusDirIter      *iter,
                               DBusString       *filename,
                               DBusError        *error)
{
  struct dirent *d, *ent;
  size_t buf_size;
  int err;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
  if (!dirent_buf_size (iter->d, &buf_size))
    {
      dbus_set_error (error, DBUS_ERROR_FAILED,
                      "Can't calculate buffer size when reading directory");
      return FALSE;
    }

  d = (struct dirent *)dbus_malloc (buf_size);
  if (!d)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
                      "No memory to read directory entry");
      return FALSE;
    }

 again:
  err = readdir_r (iter->d, d, &ent);
  if (err || !ent)
    {
      if (err != 0)
        dbus_set_error (error,
                        _dbus_error_from_errno (err),
                        "%s", _dbus_strerror (err));

      dbus_free (d);
      return FALSE;
    }
  else if (ent->d_name[0] == '.' &&
           (ent->d_name[1] == '\0' ||
            (ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
    goto again;
  else
    {
      _dbus_string_set_length (filename, 0);
      if (!_dbus_string_append (filename, ent->d_name))
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
                          "No memory to read directory entry");
          dbus_free (d);
          return FALSE;
        }
      else
        {
          dbus_free (d);
          return TRUE;
        }
    }
}
Example #6
0
static bool properties_to_info(DBusMessage* properties, SynceInfo* info)
{
  DBusMessageIter iter;
  DBusMessageIter iter_dict;

  dbus_message_iter_init(properties, &iter);

  for (dbus_message_iter_init_dict_iterator(&iter, &iter_dict);
      ;
      dbus_message_iter_next(&iter_dict))
  {
    char* str_value = NULL;
    char* key      = dbus_message_iter_get_dict_key(&iter_dict);
    int   type     = dbus_message_iter_get_arg_type(&iter_dict);
    int   int_value;

    synce_debug("Key = %s", key);

    if (!key)
      continue;

    switch (type)
    {
      case DBUS_TYPE_STRING:
        str_value = dbus_message_iter_get_string(&iter_dict);

        if (STR_EQUAL(key, "address"))
          info->ip = STRDUP(str_value);
        else if (STR_EQUAL(key, "password"))
          info->password = STRDUP(str_value);

        /* TODO: handle more string properties */

        dbus_free(str_value);
        break;

      case DBUS_TYPE_INT32:
        int_value = dbus_message_iter_get_int32(&iter_dict);

        if (STR_EQUAL(key, "key"))
          info->key = int_value;

        /* TODO: handle more int32 properties */

        break;
    }

    dbus_free(key);

    if (!dbus_message_iter_has_next(&iter_dict))
      break;
  }

  /* Fake dccm PID! */
  info->dccm_pid = getpid();

  return info->ip != NULL;
}
/* this is safe to call on a partially-allocated socket set */
static void
socket_set_poll_free (DBusSocketSet *set)
{
  DBusSocketSetPoll *self = socket_set_poll_cast (set);

  dbus_free (self->fds);
  dbus_free (self);
  _dbus_verbose ("freed socket set %p\n", self);
}
Example #8
0
int supplicant_dbus_method_call(const char *path,
				const char *interface, const char *method,
				supplicant_dbus_setup_function setup,
				supplicant_dbus_result_function function,
							void *user_data)
{
	struct method_call_data *data;
	DBusMessage *message;
	DBusMessageIter iter;
	DBusPendingCall *call;

	if (connection == NULL)
		return -EINVAL;

	if (path == NULL || interface == NULL || method == NULL)
		return -EINVAL;

	data = dbus_malloc0(sizeof(*data));
	if (data == NULL)
		return -ENOMEM;

	message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
							interface, method);
	if (message == NULL) {
		dbus_free(data);
		return -ENOMEM;
	}

	dbus_message_set_auto_start(message, FALSE);

	dbus_message_iter_init_append(message, &iter);
	if (setup != NULL)
		setup(&iter, user_data);

	if (dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT) == FALSE) {
		dbus_message_unref(message);
		dbus_free(data);
		return -EIO;
	}

	if (call == NULL) {
		dbus_message_unref(message);
		dbus_free(data);
		return -EIO;
	}

	data->function = function;
	data->user_data = user_data;

	dbus_pending_call_set_notify(call, method_call_reply,
							data, dbus_free);

	dbus_message_unref(message);

	return 0;
}
Example #9
0
static dbus_bool_t
parse_section_start (BusDesktopFileParser *parser, DBusError *error)
{
  int line_end, eol_len;
  char *section_name;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    
  if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len))
    line_end = parser->len;
  
  if (line_end - parser->pos <= 2 ||
      _dbus_string_get_byte (&parser->data, line_end - 1) != ']')
    {
      report_error (parser, "Invalid syntax for section header", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
      parser_free (parser);
      return FALSE;
    }

  section_name = unescape_string (parser,
                                  &parser->data, parser->pos + 1, line_end - 1,
                                  error);

  if (section_name == NULL)
    {
      parser_free (parser);
      return FALSE;
    }

  if (!is_valid_section_name (section_name))
    {
      report_error (parser, "Invalid characters in section name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error);
      parser_free (parser);
      dbus_free (section_name);
      return FALSE;
    }

  if (open_section (parser, section_name) == NULL)
    {
      dbus_free (section_name);
      parser_free (parser);
      BUS_SET_OOM (error);
      return FALSE;
    }

  if (line_end == parser->len)
    parser->pos = parser->len;
  else
    parser->pos = line_end + eol_len;
  
  parser->line_num += 1;

  dbus_free (section_name);
  
  return TRUE;
}
Example #10
0
int supplicant_dbus_property_get(const char *path, const char *interface,
				const char *method,
				supplicant_dbus_property_function function,
							void *user_data)
{
	struct property_get_data *data;
	DBusMessage *message;
	DBusPendingCall *call;

	if (connection == NULL)
		return -EINVAL;

	if (path == NULL || interface == NULL || method == NULL)
		return -EINVAL;

	data = dbus_malloc0(sizeof(*data));
	if (data == NULL)
		return -ENOMEM;

	message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
					DBUS_INTERFACE_PROPERTIES, "Get");

	if (message == NULL) {
		dbus_free(data);
		return -ENOMEM;
	}

	dbus_message_set_auto_start(message, FALSE);

	dbus_message_append_args(message, DBUS_TYPE_STRING, &interface,
					DBUS_TYPE_STRING, &method, NULL);

	if (dbus_connection_send_with_reply(connection, message,
						&call, TIMEOUT) == FALSE) {
		dbus_message_unref(message);
		dbus_free(data);
		return -EIO;
	}

	if (call == NULL) {
		dbus_message_unref(message);
		dbus_free(data);
		return -EIO;
	}

	data->function = function;
	data->user_data = user_data;

	dbus_pending_call_set_notify(call, property_get_reply,
							data, dbus_free);

	dbus_message_unref(message);

	return 0;
}
Example #11
0
static dbus_bool_t
launch_bus_name (const char *bus_name, BusConfigParser *parser, int alias_depth, DBusError *error)
{
  BusDesktopFile *desktop_file;
  char *exec, *user, *alias;
  dbus_bool_t retval;

  exec = NULL;
  user = NULL;
  alias = NULL;
  retval = FALSE;

  /* get the correct service file for the name we are trying to activate */
  desktop_file = desktop_file_for_name (parser, bus_name, error);
  if (desktop_file == NULL)
    return FALSE;

  /* get exec and user for service name */
  if (!get_parameters_for_service (desktop_file, bus_name, &exec, &user, &alias, error))
    goto finish;

  _dbus_verbose ("dbus-daemon-activation-helper: Name='%s'\n", bus_name);
  if (alias == NULL)
    {
      _dbus_verbose ("dbus-daemon-activation-helper: Exec='%s'\n", exec);
      _dbus_verbose ("dbus-daemon-activation-helper: User='******'\n", user);

      /* actually execute */
      if (!exec_for_correct_user (exec, user, alias, error))
        goto finish;
    }
  else
    {
      _dbus_verbose ("dbus-daemon-activation-helper: Alias='%s'\n", alias);
      if (alias_depth >= DBUS_ACTIVATION_MAX_ALIAS_DEPTH)
        {
          dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED,
                          "Maximum recursion of aliased services reached.");
          goto finish;
        }

      /* execute the aliased service */
      if (!run_launch_helper (alias, alias_depth, error))
        goto finish;
    }

  retval = TRUE;

finish:
  dbus_free (exec);
  dbus_free (user);
  dbus_free (alias);
  bus_desktop_file_free (desktop_file);
  return retval;
}
static void
bus_desktop_file_section_free (BusDesktopFileSection *section)
{
  int i;

  for (i = 0; i < section->n_lines; i++)
    bus_desktop_file_line_free (&section->lines[i]);

  dbus_free (section->lines);
  dbus_free (section->section_name);
}
void
bus_desktop_file_free (BusDesktopFile *desktop_file)
{
  int i;

  for (i = 0; i < desktop_file->n_sections; i++)
    bus_desktop_file_section_free (&desktop_file->sections[i]);
  dbus_free (desktop_file->sections);

  dbus_free (desktop_file);
}
Example #14
0
/**
 * Clear all credentials in the object.
 * 
 * @param credentials the object
 */
void
_dbus_credentials_clear (DBusCredentials    *credentials)
{
  credentials->pid = DBUS_PID_UNSET;
  credentials->unix_uid = DBUS_UID_UNSET;
  dbus_free (credentials->windows_sid);
  credentials->windows_sid = NULL;
  dbus_free (credentials->adt_audit_data);
  credentials->adt_audit_data = NULL;
  credentials->adt_audit_data_size = 0;
}
static void
debug_finalize (DBusServer *server)
{
    DBusServerDebugPipe *debug_server = (DBusServerDebugPipe*) server;

    pipe_hash_unref ();

    _dbus_server_finalize_base (server);

    dbus_free (debug_server->name);
    dbus_free (server);
}
Example #16
0
/**
 * Decrement refcount on credentials.
 *
 * @param credentials the object
 */
void
_dbus_credentials_unref (DBusCredentials    *credentials)
{
  _dbus_assert (credentials->refcount > 0);

  credentials->refcount -= 1;
  if (credentials->refcount == 0)
    {
      dbus_free (credentials->windows_sid);
      dbus_free (credentials->adt_audit_data);
      dbus_free (credentials);
    }
}
Example #17
0
dbus_bool_t
_dbus_server_test (void)
{
    const char *valid_addresses[] = {
        "tcp:port=1234",
        "tcp:host=localhost,port=1234",
        "tcp:host=localhost,port=1234;tcp:port=5678",
#ifdef DBUS_UNIX
        "unix:path=./boogie",
        "tcp:port=1234;unix:path=./boogie",
#endif
    };

    DBusServer *server;
    int i;

    for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++)
    {
        DBusError error = DBUS_ERROR_INIT;
        char *address;
        char *id;

        server = dbus_server_listen (valid_addresses[i], &error);
        if (server == NULL)
        {
            _dbus_warn ("server listen error: %s: %s\n", error.name, error.message);
            dbus_error_free (&error);
            _dbus_assert_not_reached ("Failed to listen for valid address.");
        }

        id = dbus_server_get_id (server);
        _dbus_assert (id != NULL);
        address = dbus_server_get_address (server);
        _dbus_assert (address != NULL);

        if (strstr (address, id) == NULL)
        {
            _dbus_warn ("server id '%s' is not in the server address '%s'\n",
                        id, address);
            _dbus_assert_not_reached ("bad server id or address");
        }

        dbus_free (id);
        dbus_free (address);

        dbus_server_disconnect (server);
        dbus_server_unref (server);
    }

    return TRUE;
}
Example #18
0
static dbus_bool_t
get_parameters_for_service (BusDesktopFile *desktop_file,
                            const char     *service_name,
                            char          **exec,
                            char          **user,
                            DBusError      *error)
{
    char *exec_tmp;
    char *user_tmp;

    exec_tmp = NULL;
    user_tmp = NULL;

    /* check the name of the service */
    if (!check_service_name (desktop_file, service_name, error))
        goto failed;

    /* get the complete path of the executable */
    if (!bus_desktop_file_get_string (desktop_file,
                                      DBUS_SERVICE_SECTION,
                                      DBUS_SERVICE_EXEC,
                                      &exec_tmp,
                                      error))
    {
        _DBUS_ASSERT_ERROR_IS_SET (error);
        goto failed;
    }

    /* get the user that should run this service - user is compulsary for system activation */
    if (!bus_desktop_file_get_string (desktop_file,
                                      DBUS_SERVICE_SECTION,
                                      DBUS_SERVICE_USER,
                                      &user_tmp,
                                      error))
    {
        _DBUS_ASSERT_ERROR_IS_SET (error);
        goto failed;
    }

    /* only assign if all the checks passed */
    *exec = exec_tmp;
    *user = user_tmp;
    return TRUE;

failed:
    dbus_free (exec_tmp);
    dbus_free (user_tmp);
    return FALSE;
}
Example #19
0
static dbus_bool_t
check_service_name (BusDesktopFile *desktop_file,
                    const char     *service_name,
                    DBusError      *error)
{
  char *name_tmp;
  dbus_bool_t retval;

  retval = FALSE;

  /* try to get Name */
  if (!bus_desktop_file_get_string (desktop_file,
                                    DBUS_SERVICE_SECTION,
                                    DBUS_SERVICE_NAME,
                                    &name_tmp,
                                    error))
    goto failed;

  /* verify that the name is the same as the file service name */
  if (strcmp (service_name, name_tmp) != 0)
    {
      dbus_set_error (error, DBUS_ERROR_SPAWN_FILE_INVALID,
                      "Service '%s' does not match expected value", name_tmp);
      goto failed_free;
    }

  retval = TRUE;

failed_free:
  /* we don't return the name, so free it here */
  dbus_free (name_tmp);
failed:
  return retval;
}
Example #20
0
//! Splits signature into atomic DBus object signatures
PyObject *
script_signature_each(const char *signature)
{
    PyObject *py_list = PyList_New(0);

    DBusError error;
    DBusSignatureIter iter;

    dbus_signature_iter_init(&iter, signature);
    while (dbus_signature_iter_get_current_type(&iter) != DBUS_TYPE_INVALID) {
        char *sign = dbus_signature_iter_get_signature(&iter);

        dbus_error_init(&error);
        dbus_signature_validate(sign, &error);
        if (dbus_error_is_set(&error)) {
            dbus_error_free(&error);
            return NULL;
        }
        else {
            PyList_Append(py_list, PyString_FromString(sign));
        }

        dbus_free(sign);
        dbus_signature_iter_next(&iter);
    }

    return py_list;
}
Example #21
0
static dbus_bool_t
add_cancel_ownership_to_transaction (BusTransaction *transaction,
                                     BusService     *service,
                                     BusOwner       *owner)
{
  OwnershipCancelData *d;

  d = dbus_new (OwnershipCancelData, 1);
  if (d == NULL)
    return FALSE;
  
  d->service = service;
  d->owner = owner;

  if (!bus_transaction_add_cancel_hook (transaction, cancel_ownership, d,
                                        free_ownership_cancel_data))
    {
      dbus_free (d);
      return FALSE;
    }

  bus_service_ref (d->service);
  bus_owner_ref (owner);
  dbus_connection_ref (d->owner->conn);
 
  return TRUE;
}
Example #22
0
/**
 * Unit test for dbus-userdb.c.
 * 
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_userdb_test (const char *test_data_dir)
{
  const DBusString *username;
  const DBusString *homedir;
  dbus_uid_t uid;
  unsigned long *group_ids;
  int n_group_ids, i;

  if (!_dbus_username_from_current_process (&username))
    _dbus_assert_not_reached ("didn't get username");

  if (!_dbus_homedir_from_current_process (&homedir))
    _dbus_assert_not_reached ("didn't get homedir");  

  if (!_dbus_get_user_id (username, &uid))
    _dbus_assert_not_reached ("didn't get uid");

  if (!_dbus_groups_from_uid (uid, &group_ids, &n_group_ids))
    _dbus_assert_not_reached ("didn't get groups");

  printf ("    Current user: %s homedir: %s gids:",
          _dbus_string_get_const_data (username),
          _dbus_string_get_const_data (homedir));

  for (i=0; i<n_group_ids; i++)
      printf(" %ld", group_ids[i]);

  printf ("\n");
 
  dbus_free (group_ids);

  return TRUE;
}
Example #23
0
File: bus.c Project: kobolabs/dbus
static void
free_server_data (void *data)
{
  BusServerData *bd = data;

  dbus_free (bd);
}
Example #24
0
static void
add_basic_env(DBusMessageIter *iter, const gchar *udi) {
  struct utsname un;
  char *server_addr;

  if (hald_is_verbose) {
    add_env(iter, "HALD_VERBOSE", "1");
  }
  if (hald_is_initialising) {
    add_env(iter, "HALD_STARTUP", "1");
  }
  if (hald_use_syslog) {
    add_env(iter, "HALD_USE_SYSLOG", "1");
  }
  add_env(iter, "UDI", udi);
  server_addr = hald_dbus_local_server_addr();
  add_env(iter, "HALD_DIRECT_ADDR", server_addr);
  dbus_free (server_addr);
#ifdef HAVE_POLKIT
  add_env(iter, "HAVE_POLKIT", "1");
#endif

  if (uname(&un) >= 0) {
    char *sysname;

    sysname = g_ascii_strdown(un.sysname, -1);
    add_env(iter, "HALD_UNAME_S", sysname);
    g_free(sysname);
  }
}
Example #25
0
/**
 * Finalizes the members of the DBusServer base class.
 * Chained up to by subclass finalizers.
 *
 * @param server the server.
 */
void
_dbus_server_finalize_base (DBusServer *server)
{
    /* We don't have the lock, but nobody should be accessing
     * concurrently since they don't have a ref
     */
#ifndef DBUS_DISABLE_CHECKS
    _dbus_assert (!server->have_server_lock);
#endif
    _dbus_assert (server->disconnected);

    /* calls out to application code... */
    _dbus_data_slot_list_free (&server->slot_list);

    dbus_server_set_new_connection_function (server, NULL, NULL, NULL);

    _dbus_watch_list_free (server->watches);
    _dbus_timeout_list_free (server->timeouts);

    _dbus_rmutex_free_at_location (&server->mutex);

    dbus_free (server->address);

    dbus_free_string_array (server->auth_mechanisms);

    _dbus_string_free (&server->guid_hex);
}
Example #26
0
int
main (int argc, char *argv[])
{
  DBusServer *server;
  DBusError error;
  DBusLoop *loop;
  DBusConnection *session;
  TestServiceData *testdata;

  dbus_error_init (&error);

  loop = _dbus_loop_new ();

  testdata = dbus_new (TestServiceData, 1);
  testdata->loop = loop;

  session = dbus_bus_get (DBUS_BUS_SESSION, &error);
  if (!session)
    die ("couldn't access session bus");

  test_connection_setup (loop, session);

  dbus_bus_request_name (session, "org.freedesktop.DBus.TestSuite.PrivServer", 0, &error);
  if (dbus_error_is_set (&error))
    die ("couldn't request name: %s", error.message);

  if (!dbus_connection_add_filter (session, filter_session_message, testdata, NULL))
    die ("couldn't add filter");

#ifdef DBUS_CMAKE
  server = dbus_server_listen (TEST_LISTEN, &error);
#else
  server = dbus_server_listen ("unix:tmpdir=/tmp", &error);
#endif
  if (!server)
    die ("%s", error.message);
  testdata->private_addr = dbus_server_get_address (server);
  fprintf (stderr, "test server listening on %s\n", testdata->private_addr);

  dbus_server_set_new_connection_function (server, new_connection_callback,
                                           testdata, NULL);

  test_server_setup (loop, server);

  fprintf (stderr, "server running mainloop\n");
  _dbus_loop_run (loop);
  fprintf (stderr, "server mainloop quit\n");

  test_server_shutdown (loop, server);

  test_connection_shutdown (loop, session);

  dbus_connection_unref (session);

  _dbus_loop_unref (loop);

  dbus_free (testdata);

  return 0;
}
Example #27
0
/**
 * @ingroup DBusMemoryInternals
 * Unit test for DBusMemory
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_memory_test (void)
{
  dbus_bool_t old_guards;
  void *p;
  size_t size;

  old_guards = guards;
  guards = TRUE;
  p = dbus_malloc (4);
  if (p == NULL)
    _dbus_assert_not_reached ("no memory");
  for (size = 4; size < 256; size += 4)
    {
      p = dbus_realloc (p, size);
      if (p == NULL)
	_dbus_assert_not_reached ("no memory");
    }
  for (size = 256; size != 0; size -= 4)
    {
      p = dbus_realloc (p, size);
      if (p == NULL)
	_dbus_assert_not_reached ("no memory");
    }
  dbus_free (p);
  guards = old_guards;
  return TRUE;
}
HANDLE
CreateFileMappingA (HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes,
		    DWORD flProtect, DWORD dwMaximumSizeHigh,
		    DWORD dwMaximumSizeLow, LPCSTR lpName)
{
  wchar_t *name;
  HANDLE result;
  int err;

  if (lpName)
    {
      name = _dbus_win_utf8_to_utf16 (lpName, NULL);
      if (!name)
	return INVALID_HANDLE_VALUE;
    }
  else
    name = NULL;

  result = CreateFileMappingW (hFile, lpAttributes, flProtect,
			       dwMaximumSizeHigh, dwMaximumSizeLow,
			       name);

  err = GetLastError ();
  dbus_free (name);
  SetLastError (err);
  return result;
}
HANDLE
FindFirstFileA (LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
{
  wchar_t *pathname;
  WIN32_FIND_DATAW find_file_data;
  HANDLE result;
  int err;

  pathname = _dbus_win_utf8_to_utf16 (lpFileName, NULL);
  if (!pathname)
    return INVALID_HANDLE_VALUE;

  result = FindFirstFileW (pathname, &find_file_data);
  if (result != INVALID_HANDLE_VALUE)
    {
      BOOL res = convert_find_data (&find_file_data, lpFindFileData);
      if (! res)
        {
          err = GetLastError ();
          FindClose (result);
          SetLastError (err);
          result = INVALID_HANDLE_VALUE;
        }
    }

  err = GetLastError ();
  dbus_free (pathname);
  SetLastError (err);
  return result;
}
static BusDesktopFileSection* 
new_section (BusDesktopFile *desktop_file,
             const char     *name)
{
  int n;
  char *name_copy;
  
  if (desktop_file->n_allocated_sections == desktop_file->n_sections)
    {
      if (!grow_sections (desktop_file))
        return NULL;
    }

  name_copy = _dbus_strdup (name);
  if (name_copy == NULL)
    return NULL;

  n = desktop_file->n_sections;
  desktop_file->sections[n].section_name = name_copy;

  desktop_file->sections[n].n_lines = 0;
  desktop_file->sections[n].lines = NULL;
  desktop_file->sections[n].n_allocated_lines = 0;

  if (!grow_lines_in_section (&desktop_file->sections[n]))
    {
      dbus_free (desktop_file->sections[n].section_name);
      desktop_file->sections[n].section_name = NULL;
      return NULL;
    }

  desktop_file->n_sections += 1;
  
  return &desktop_file->sections[n];  
}