diff options
| author | bunnei <bunneidev@gmail.com> | 2015-01-06 20:13:56 -0500 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2015-01-06 20:13:56 -0500 | 
| commit | 088863c9219df896b316244ad05452ef05b15ea4 (patch) | |
| tree | 66892c6362d7aae93b9349285234762e4e6ee189 | |
| parent | 0bf5a0bfc47cebb64dc2740c475a631d6fb13a2f (diff) | |
| parent | 8fbe5d2dcaa0f9330120210f5e009cb387cb4a0f (diff) | |
Merge pull request #376 from Subv/arc_reorder
Archives: Change the folder layout of some archives.
| -rw-r--r-- | src/common/common_paths.h | 37 | ||||
| -rw-r--r-- | src/common/file_util.cpp | 10 | ||||
| -rw-r--r-- | src/common/file_util.h | 5 | ||||
| -rw-r--r-- | src/core/file_sys/archive_extsavedata.cpp | 18 | ||||
| -rw-r--r-- | src/core/file_sys/archive_extsavedata.h | 2 | ||||
| -rw-r--r-- | src/core/file_sys/archive_savedata.cpp | 18 | ||||
| -rw-r--r-- | src/core/file_sys/archive_savedatacheck.cpp | 15 | ||||
| -rw-r--r-- | src/core/file_sys/archive_sdmc.cpp | 4 | ||||
| -rw-r--r-- | src/core/file_sys/archive_systemsavedata.cpp | 7 | ||||
| -rw-r--r-- | src/core/file_sys/archive_systemsavedata.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/cfg/cfg.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.cpp | 26 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/ptm_u.cpp | 6 | 
14 files changed, 93 insertions, 66 deletions
| diff --git a/src/common/common_paths.h b/src/common/common_paths.h index e692e5492..0ecf2d9de 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -35,26 +35,23 @@  #define JAP_DIR "JAP"  // Subdirs in the User dir returned by GetUserPath(D_USER_IDX) -#define CONFIG_DIR        "config" -#define GAMECONFIG_DIR    "game_config" -#define MAPS_DIR          "maps" -#define CACHE_DIR         "cache" -#define SDMC_DIR          "sdmc" -#define EXTSAVEDATA_DIR   "extsavedata" -#define SAVEDATA_DIR      "savedata" -#define SAVEDATACHECK_DIR "savedatacheck" -#define SYSDATA_DIR       "sysdata" -#define SYSSAVEDATA_DIR   "syssavedata" -#define SHADERCACHE_DIR   "shader_cache" -#define STATESAVES_DIR    "state_saves" -#define SCREENSHOTS_DIR   "screenShots" -#define DUMP_DIR          "dump" -#define DUMP_TEXTURES_DIR "textures" -#define DUMP_FRAMES_DIR   "frames" -#define DUMP_AUDIO_DIR    "audio" -#define LOGS_DIR          "logs" -#define SHADERS_DIR       "shaders" -#define SYSCONF_DIR       "sysconf" +#define CONFIG_DIR               "config" +#define GAMECONFIG_DIR           "game_config" +#define MAPS_DIR                 "maps" +#define CACHE_DIR                "cache" +#define SDMC_DIR                 "sdmc" +#define NAND_DIR                 "nand" +#define SYSDATA_DIR              "sysdata" +#define SHADERCACHE_DIR          "shader_cache" +#define STATESAVES_DIR           "state_saves" +#define SCREENSHOTS_DIR          "screenShots" +#define DUMP_DIR                 "dump" +#define DUMP_TEXTURES_DIR        "textures" +#define DUMP_FRAMES_DIR          "frames" +#define DUMP_AUDIO_DIR           "audio" +#define LOGS_DIR                 "logs" +#define SHADERS_DIR              "shaders" +#define SYSCONF_DIR              "sysconf"  // Filenames  // Files in the directory returned by GetUserPath(D_CONFIG_IDX) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 0a6cd80c8..706e7c842 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -676,11 +676,8 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new          paths[D_MAPS_IDX]           = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;          paths[D_CACHE_IDX]          = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;          paths[D_SDMC_IDX]           = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; -        paths[D_EXTSAVEDATA]        = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; -        paths[D_SAVEDATA_IDX]       = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; -        paths[D_SAVEDATACHECK_IDX]  = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP; +        paths[D_NAND_IDX]           = paths[D_USER_IDX] + NAND_DIR DIR_SEP;          paths[D_SYSDATA_IDX]        = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; -        paths[D_SYSSAVEDATA_IDX]    = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;          paths[D_SHADERCACHE_IDX]    = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;          paths[D_SHADERS_IDX]        = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;          paths[D_STATESAVES_IDX]     = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; @@ -722,10 +719,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new              paths[D_MAPS_IDX]           = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;              paths[D_CACHE_IDX]          = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;              paths[D_SDMC_IDX]           = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; -            paths[D_EXTSAVEDATA]        = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; -            paths[D_SAVEDATA_IDX]       = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; -            paths[D_SAVEDATACHECK_IDX]  = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP; -            paths[D_SYSSAVEDATA_IDX]    = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; +            paths[D_NAND_IDX]           = paths[D_USER_IDX] + NAND_DIR DIR_SEP;              paths[D_SHADERCACHE_IDX]    = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;              paths[D_SHADERS_IDX]        = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;              paths[D_STATESAVES_IDX]     = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; diff --git a/src/common/file_util.h b/src/common/file_util.h index c83ecd87d..86aab2e3d 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -27,11 +27,8 @@ enum {      D_STATESAVES_IDX,      D_SCREENSHOTS_IDX,      D_SDMC_IDX, -    D_EXTSAVEDATA, -    D_SAVEDATA_IDX, -    D_SAVEDATACHECK_IDX, +    D_NAND_IDX,      D_SYSDATA_IDX, -    D_SYSSAVEDATA_IDX,      D_HIRESTEXTURES_IDX,      D_DUMP_IDX,      D_DUMPFRAMES_IDX, diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 4759ef3ae..0805f42ae 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -9,6 +9,7 @@  #include "core/file_sys/archive_extsavedata.h"  #include "core/file_sys/disk_archive.h" +#include "core/hle/service/fs/archive.h"  #include "core/settings.h"  //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -19,15 +20,22 @@ namespace FileSys {  static std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path) {      std::vector<u8> vec_data = path.AsBinary();      const u32* data = reinterpret_cast<const u32*>(vec_data.data()); -    u32 media_type = data[0];      u32 save_low = data[1];      u32 save_high = data[2]; -    return Common::StringFromFormat("%s%s/%08X/%08X/", mount_point.c_str(), media_type == 0 ? "nand" : "sdmc", save_high, save_low); +    return Common::StringFromFormat("%s%08X/%08X/", mount_point.c_str(), save_high, save_low);  } -Archive_ExtSaveData::Archive_ExtSaveData(const std::string& mount_point) -        : DiskArchive(mount_point), concrete_mount_point(mount_point) { -    LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", this->mount_point.c_str()); +static std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) { +    if (shared) +        return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(), SYSTEM_ID.c_str()); +     +    return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(),  +            SYSTEM_ID.c_str(), SDCARD_ID.c_str()); +} + +Archive_ExtSaveData::Archive_ExtSaveData(const std::string& mount_location, bool shared) +        : DiskArchive(GetExtDataContainerPath(mount_location, shared)) { +    LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str());  }  bool Archive_ExtSaveData::Initialize() { diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index a3a144799..fb7f209d2 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -17,7 +17,7 @@ namespace FileSys {  /// File system interface to the ExtSaveData archive  class Archive_ExtSaveData final : public DiskArchive {  public: -    Archive_ExtSaveData(const std::string& mount_point); +    Archive_ExtSaveData(const std::string& mount_point, bool shared);      /**       * Initialize the archive. diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index 280d4ff5d..3baee5294 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -9,6 +9,7 @@  #include "core/file_sys/archive_savedata.h"  #include "core/file_sys/disk_archive.h" +#include "core/hle/service/fs/archive.h"  #include "core/settings.h"  //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -16,14 +17,25 @@  namespace FileSys { -Archive_SaveData::Archive_SaveData(const std::string& mount_point) -        : DiskArchive(mount_point) { +static std::string GetSaveDataContainerPath(const std::string& sdmc_directory) { +    return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(),  +            SYSTEM_ID.c_str(), SDCARD_ID.c_str()); +} + +static std::string GetSaveDataPath(const std::string& mount_location, u64 program_id) { +    u32 high = program_id >> 32; +    u32 low = program_id & 0xFFFFFFFF; +    return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, low); +} + +Archive_SaveData::Archive_SaveData(const std::string& sdmc_directory) +        : DiskArchive(GetSaveDataContainerPath(sdmc_directory)) {      LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str());  }  ResultCode Archive_SaveData::Open(const Path& path) {      if (concrete_mount_point.empty()) -        concrete_mount_point = Common::StringFromFormat("%s%016X", mount_point.c_str(), Kernel::g_program_id) + DIR_SEP; +        concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id);      if (!FileUtil::Exists(concrete_mount_point)) {          // When a SaveData archive is created for the first time, it is not yet formatted          // and the save file/directory structure expected by the game has not yet been initialized.  diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp index 233158a0c..a7a507536 100644 --- a/src/core/file_sys/archive_savedatacheck.cpp +++ b/src/core/file_sys/archive_savedatacheck.cpp @@ -5,13 +5,24 @@  #include "common/file_util.h"  #include "core/file_sys/archive_savedatacheck.h" +#include "core/hle/service/fs/archive.h"  ////////////////////////////////////////////////////////////////////////////////////////////////////  // FileSys namespace  namespace FileSys { -Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& mount_loc) : mount_point(mount_loc) { +static std::string GetSaveDataCheckContainerPath(const std::string& nand_directory) { +    return Common::StringFromFormat("%s%s/title/", nand_directory.c_str(), SYSTEM_ID.c_str()); +} + +static std::string GetSaveDataCheckPath(const std::string& mount_point, u32 high, u32 low) { +    return Common::StringFromFormat("%s%08x/%08x/content/00000000.app.romfs", +            mount_point.c_str(), high, low); +} + +Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& nand_directory) : +        mount_point(GetSaveDataCheckContainerPath(nand_directory)) {  }  ResultCode Archive_SaveDataCheck::Open(const Path& path) { @@ -23,7 +34,7 @@ ResultCode Archive_SaveDataCheck::Open(const Path& path) {      // this archive again with a different path, will corrupt the previously open file.      auto vec = path.AsBinary();      const u32* data = reinterpret_cast<u32*>(vec.data()); -    std::string file_path = Common::StringFromFormat("%s%08x%08x.bin", mount_point.c_str(), data[1], data[0]); +    std::string file_path = GetSaveDataCheckPath(mount_point, data[1], data[0]);      FileUtil::IOFile file(file_path, "rb");      std::fill(raw_data.begin(), raw_data.end(), 0); diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 1c1c170b6..26b03e82f 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -16,8 +16,8 @@  namespace FileSys { -Archive_SDMC::Archive_SDMC(const std::string& mount_point) : DiskArchive(mount_point) { -    LOG_INFO(Service_FS, "Directory %s set as SDMC.", mount_point.c_str()); +Archive_SDMC::Archive_SDMC(const std::string& sdmc_directory) : DiskArchive(sdmc_directory) { +    LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str());  }  bool Archive_SDMC::Initialize() { diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp index 0da32d510..c2a5d641a 100644 --- a/src/core/file_sys/archive_systemsavedata.cpp +++ b/src/core/file_sys/archive_systemsavedata.cpp @@ -9,6 +9,7 @@  #include "core/file_sys/archive_systemsavedata.h"  #include "core/file_sys/disk_archive.h" +#include "core/hle/service/fs/archive.h"  #include "core/settings.h"  //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -22,8 +23,12 @@ static std::string GetSystemSaveDataPath(const std::string& mount_point, u64 sav      return Common::StringFromFormat("%s%08X/%08X/", mount_point.c_str(), save_low, save_high);  } +static std::string GetSystemSaveDataContainerPath(const std::string& mount_point) { +    return Common::StringFromFormat("%sdata/%s/sysdata/", mount_point.c_str(), SYSTEM_ID.c_str()); +} +  Archive_SystemSaveData::Archive_SystemSaveData(const std::string& mount_point, u64 save_id) -        : DiskArchive(GetSystemSaveDataPath(mount_point, save_id)) { +        : DiskArchive(GetSystemSaveDataPath(GetSystemSaveDataContainerPath(mount_point), save_id)) {      LOG_INFO(Service_FS, "Directory %s set as SystemSaveData.", this->mount_point.c_str());  } diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index 55d85193c..c8f5845ca 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -15,8 +15,6 @@  namespace FileSys {  /// File system interface to the SystemSaveData archive -/// TODO(Subv): This archive should point to a location in the NAND, -/// specifically nand:/data/<ID0>/sysdata/<SaveID-Low>/<SaveID-High>  class Archive_SystemSaveData final : public DiskArchive {  public:      Archive_SystemSaveData(const std::string& mount_point, u64 save_id); diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 161aa8531..8812c49ef 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -161,9 +161,9 @@ ResultCode FormatConfig() {  void CFGInit() {      // TODO(Subv): In the future we should use the FS service to query this archive,       // currently it is not possible because you can only have one open archive of the same type at any time -    std::string syssavedata_directory = FileUtil::GetUserPath(D_SYSSAVEDATA_IDX); +    std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX);      cfg_system_save_data = Common::make_unique<FileSys::Archive_SystemSaveData>( -                           syssavedata_directory, CFG_SAVE_ID); +                           nand_directory, CFG_SAVE_ID);      if (!cfg_system_save_data->Initialize()) {          LOG_CRITICAL(Service_CFG, "Could not initialize SystemSaveData archive for the CFG:U service");          return; diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index f761c6ab9..958dd9344 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -36,6 +36,10 @@ namespace std {      };  } +/// TODO(Subv): Confirm length of these strings +const std::string SYSTEM_ID = "00000000000000000000000000000000"; +const std::string SDCARD_ID = "00000000000000000000000000000000"; +  namespace Service {  namespace FS { @@ -432,11 +436,11 @@ ResultCode FormatSaveData() {  void ArchiveInit() {      next_handle = 1; -    // TODO(Link Mauve): Add the other archive types (see here for the known types: -    // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes).  Currently the only half-finished -    // archive type is SDMC, so it is the only one getting exposed. +    // TODO(Subv): Add the other archive types (see here for the known types: +    // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes).      std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); +    std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX);      auto sdmc_archive = Common::make_unique<FileSys::Archive_SDMC>(sdmc_directory);      if (sdmc_archive->Initialize())          CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC); @@ -444,28 +448,24 @@ void ArchiveInit() {          LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str());      // Create the SaveData archive -    std::string savedata_directory = FileUtil::GetUserPath(D_SAVEDATA_IDX); -    auto savedata_archive = Common::make_unique<FileSys::Archive_SaveData>(savedata_directory); +    auto savedata_archive = Common::make_unique<FileSys::Archive_SaveData>(sdmc_directory);      CreateArchive(std::move(savedata_archive), ArchiveIdCode::SaveData); -    std::string extsavedata_directory = FileUtil::GetUserPath(D_EXTSAVEDATA); -    auto extsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(extsavedata_directory); +    auto extsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(sdmc_directory, false);      if (extsavedata_archive->Initialize())          CreateArchive(std::move(extsavedata_archive), ArchiveIdCode::ExtSaveData);      else -        LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_directory.c_str()); +        LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_archive->GetMountPoint().c_str()); -    std::string sharedextsavedata_directory = FileUtil::GetUserPath(D_EXTSAVEDATA); -    auto sharedextsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(sharedextsavedata_directory); +    auto sharedextsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(nand_directory, true);      if (sharedextsavedata_archive->Initialize())          CreateArchive(std::move(sharedextsavedata_archive), ArchiveIdCode::SharedExtSaveData);      else          LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",  -                  sharedextsavedata_directory.c_str()); +            sharedextsavedata_archive->GetMountPoint().c_str());      // Create the SaveDataCheck archive, basically a small variation of the RomFS archive -    std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX); -    auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(savedatacheck_directory); +    auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(nand_directory);      CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck);  } diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 9e9efa019..b3f2134f2 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -10,6 +10,11 @@  #include "core/hle/kernel/kernel.h"  #include "core/hle/result.h" +/// The unique system identifier hash, also known as ID0 +extern const std::string SYSTEM_ID; +/// The scrambled SD card CID, also known as ID1 +extern const std::string SDCARD_ID; +  namespace Service {  namespace FS { diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index 9cc700c46..fd79cd8ab 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp @@ -142,10 +142,10 @@ Interface::Interface() {      Register(FunctionTable, ARRAY_SIZE(FunctionTable));      // Create the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file      // TODO(Subv): In the future we should use the FS service to query this archive -    std::string extsavedata_directory = FileUtil::GetUserPath(D_EXTSAVEDATA); -    ptm_shared_extsavedata = Common::make_unique<FileSys::Archive_ExtSaveData>(extsavedata_directory); +    std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); +    ptm_shared_extsavedata = Common::make_unique<FileSys::Archive_ExtSaveData>(nand_directory, true);      if (!ptm_shared_extsavedata->Initialize()) { -        LOG_CRITICAL(Service_PTM, "Could not initialize ExtSaveData archive for the PTM:U service"); +        LOG_CRITICAL(Service_PTM, "Could not initialize SharedExtSaveData archive for the PTM:U service");          return;      }      FileSys::Path archive_path(ptm_shared_extdata_id); | 
