Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/toolkit/mozapps/update/common/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 4 kB image not shown  

Quelle  updateutils_win.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "updateutils_win.h"
#include <errno.h>
#include <shlwapi.h>
#include <string.h>

#ifdef MOZ_CLANG_PLUGIN
#  define MOZ_RUNINIT __attribute__((annotate("moz_global_var")))
#else
#  define MOZ_RUNINIT
#endif

/**
 * Note: The reason that these functions are separated from those in
 *       updatehelper.h/updatehelper.cpp is that those functions are strictly
 *       used within the updater, whereas changing functions in updateutils_win
 *       will have effects reaching beyond application update.
 */


// This section implements the minimum set of dirent APIs used by updater.cpp on
// Windows.  If updater.cpp is modified to use more of this API, we need to
// implement those parts here too.
MOZ_RUNINIT static dirent gDirEnt;

DIR::DIR(const WCHAR* path) : findHandle(INVALID_HANDLE_VALUE) {
  memset(name, 0, sizeof(name));
  wcsncpy(name, path, sizeof(name) / sizeof(name[0]));
  wcsncat(name, L"\\*"sizeof(name) / sizeof(name[0]) - wcslen(name) - 1);
}

DIR::~DIR() {
  if (findHandle != INVALID_HANDLE_VALUE) {
    FindClose(findHandle);
  }
}

dirent::dirent() { d_name[0] = L'\0'; }

DIR* opendir(const WCHAR* path) { return new DIR(path); }

int closedir(DIR* dir) {
  delete dir;
  return 0;
}

dirent* readdir(DIR* dir) {
  WIN32_FIND_DATAW data;
  if (dir->findHandle != INVALID_HANDLE_VALUE) {
    BOOL result = FindNextFileW(dir->findHandle, &data);
    if (!result) {
      if (GetLastError() != ERROR_NO_MORE_FILES) {
        errno = ENOENT;
      }
      return 0;
    }
  } else {
    // Reading the first directory entry
    dir->findHandle = FindFirstFileW(dir->name, &data);
    if (dir->findHandle == INVALID_HANDLE_VALUE) {
      if (GetLastError() == ERROR_FILE_NOT_FOUND) {
        errno = ENOENT;
      } else {
        errno = EBADF;
      }
      return 0;
    }
  }
  size_t direntBufferLength =
      sizeof(gDirEnt.d_name) / sizeof(gDirEnt.d_name[0]);
  wcsncpy(gDirEnt.d_name, data.cFileName, direntBufferLength);
  // wcsncpy does not guarantee a null-terminated string if the source string is
  // too long.
  gDirEnt.d_name[direntBufferLength - 1] = '\0';
  return &gDirEnt;
}

/**
 * Joins a base directory path with a filename.
 *
 * @param  base  The base directory path of size MAX_PATH + 1
 * @param  extra The filename to append
 * @return TRUE if the file name was successful appended to base
 */

BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra) {
  if (wcslen(base) + wcslen(extra) >= MAX_PATH) {
    return FALSE;
  }

  return PathAppendW(base, extra);
}

/**
 * Obtains a uuid as a wide string.
 *
 * @param  outBuf
 *         A buffer of size MAX_PATH + 1 to store the result.
 * @return TRUE if successful
 */

BOOL GetUUIDString(LPWSTR outBuf) {
  UUID uuid;
  RPC_WSTR uuidString = nullptr;

  // Note: the return value of UuidCreate should always be RPC_S_OK on systems
  // after Win2K / Win2003 due to the network hardware address no longer being
  // used to create the UUID.
  if (UuidCreate(&uuid) != RPC_S_OK) {
    return FALSE;
  }
  if (UuidToStringW(&uuid, &uuidString) != RPC_S_OK) {
    return FALSE;
  }
  if (!uuidString) {
    return FALSE;
  }

  if (wcslen(reinterpret_cast<LPCWSTR>(uuidString)) > MAX_PATH) {
    return FALSE;
  }
  wcsncpy(outBuf, reinterpret_cast<LPCWSTR>(uuidString), MAX_PATH + 1);
  RpcStringFreeW(&uuidString);

  return TRUE;
}

/**
 * Build a temporary file path whose name component is a UUID.
 *
 * @param  basePath  The base directory path for the temp file
 * @param  prefix    Optional prefix for the beginning of the file name
 * @param  tmpPath   Output full path, with the base directory and the file
 * name. Must already have been allocated with size >= MAX_PATH.
 * @return TRUE if tmpPath was successfully filled in, FALSE on errors
 */

BOOL GetUUIDTempFilePath(LPCWSTR basePath, LPCWSTR prefix, LPWSTR tmpPath) {
  WCHAR filename[MAX_PATH + 1] = {L"\0"};
  if (prefix) {
    if (wcslen(prefix) > MAX_PATH) {
      return FALSE;
    }
    wcsncpy(filename, prefix, MAX_PATH + 1);
  }

  WCHAR tmpFileNameString[MAX_PATH + 1] = {L"\0"};
  if (!GetUUIDString(tmpFileNameString)) {
    return FALSE;
  }

  size_t tmpFileNameStringLen = wcslen(tmpFileNameString);
  if (wcslen(filename) + tmpFileNameStringLen > MAX_PATH) {
    return FALSE;
  }
  wcsncat(filename, tmpFileNameString, tmpFileNameStringLen);

  size_t basePathLen = wcslen(basePath);
  if (basePathLen > MAX_PATH) {
    return FALSE;
  }
  // Use basePathLen + 1 so wcsncpy will add null termination and if a caller
  // doesn't allocate MAX_PATH + 1 for tmpPath this won't fail when there is
  // actually enough space allocated.
  wcsncpy(tmpPath, basePath, basePathLen + 1);
  if (!PathAppendSafe(tmpPath, filename)) {
    return FALSE;
  }

  return TRUE;
}

Messung V0.5
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.