Revision: 9547 https://osdn.net/projects/ttssh2/scm/svn/commits/9547 Author: zmatsuo Date: 2021-11-27 22:49:15 +0900 (Sat, 27 Nov 2021) Log Message: ----------- セッションの複製が動作しなかったので修正 - セッション複製部分を別ファイルに分離 - ttcmn_dup.cpp, h - プロジェクトファイル修正 Modified Paths: -------------- trunk/teraterm/ttpcmn/CMakeLists.txt trunk/teraterm/ttpcmn/ttcmn.c trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj.filters trunk/teraterm/ttpcmn/ttpcmn.v8.vcproj Added Paths: ----------- trunk/teraterm/ttpcmn/ttcmn_dup.cpp trunk/teraterm/ttpcmn/ttcmn_dup.h -------------- next part -------------- Modified: trunk/teraterm/ttpcmn/CMakeLists.txt =================================================================== --- trunk/teraterm/ttpcmn/CMakeLists.txt 2021-11-27 13:48:57 UTC (rev 9546) +++ trunk/teraterm/ttpcmn/CMakeLists.txt 2021-11-27 13:49:15 UTC (rev 9547) @@ -8,8 +8,11 @@ language.c language.h ttcmn.c + ttcmn_cominfo.c + ttcmn_cominfo.h + ttcmn_dup.cpp + ttcmn_dup.h ttcmn_notify.cpp - ttcmn_cominfo.c ttpcmn-version.rc ttpcmn.def ${COMMON_SRC} Modified: trunk/teraterm/ttpcmn/ttcmn.c =================================================================== --- trunk/teraterm/ttpcmn/ttcmn.c 2021-11-27 13:48:57 UTC (rev 9546) +++ trunk/teraterm/ttpcmn/ttcmn.c 2021-11-27 13:49:15 UTC (rev 9547) @@ -49,6 +49,8 @@ #include "compat_win.h" #include "asprintf.h" +#include "ttcmn_dup.h" + #define DllExport __declspec(dllexport) #include "ttcommon.h" @@ -56,8 +58,6 @@ typedef struct { size_t size_tmap; /* sizeof TMap */ size_t size_tttset; /* sizeof TTTSet */ - /* Setup information from "teraterm.ini" */ - TTTSet ts; // Window list int NWin; HWND WinList[MAXNWIN]; @@ -71,6 +71,9 @@ WINDOWPLACEMENT WinPrevRect[MAXNWIN]; BOOL WinUndoFlag; int WinUndoStyle; + // Duplicate Teraterm data + HANDLE DuplicateDataHandle; + DWORD DuplicateDataSizeLow; } TMap; typedef TMap *PMap; @@ -96,17 +99,38 @@ WIN_SIDEBYSIDE, }; +static const char DupDataName[] = "dupdata"; void WINAPI CopyShmemToTTSet(PTTSet ts) { - // \x8C\xBB\x8D݂̐ݒ\xE8\x82\xF0\x8B\xA4\x97L\x83\x81\x83\x82\x83\x8A\x82\xA9\x82\xE7\x83R\x83s\x81[\x82\xB7\x82\xE9 - memcpy(ts, &pm->ts, sizeof(TTTSet)); + DWORD size = pm->DuplicateDataSizeLow; + HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, DupDataName); + void *ptr = (void *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0); + TTCMNUnserialize(ptr, (size_t)size, ts); + UnmapViewOfFile(ptr); + CloseHandle(handle); + pm->DuplicateDataSizeLow = 0; } void WINAPI CopyTTSetToShmem(PTTSet ts) { - // \x8C\xBB\x8D݂̐ݒ\xE8\x82\xF0\x8B\xA4\x97L\x83\x81\x83\x82\x83\x8A\x82փR\x83s\x81[\x82\xB7\x82\xE9 - memcpy(&pm->ts, ts, sizeof(TTTSet)); + size_t size; + void *ptr = TTCMNSerialize(ts, &size); + if (ptr != NULL) { + HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)size, DupDataName); + void *dest = (void *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS,0,0,0); + memcpy(dest, ptr, size); + UnmapViewOfFile(dest); + //CloseHandle(handle); do not close, \x8Eg\x97p\x82\xB5\x82Ȃ\xA2\x8F\xF3\x91ԂɂȂ\xE9\x82ƂȂ\xAD\x82Ȃ\xC1\x82Ă\xB5\x82܂\xA4 + + if (pm->DuplicateDataHandle != NULL) { + // 1\x89\xF1\x91O\x82̏\xEE\x95\xF1\x82\xF0\x8D폜\x82\xB7\x82\xE9 + CloseHandle(pm->DuplicateDataHandle); + } + pm->DuplicateDataHandle = handle; + pm->DuplicateDataSizeLow = (DWORD)size; + free(ptr); + } } static void CopyFiles(const wchar_t *file_list[], const wchar_t *src_dir, const wchar_t *dest_dir) @@ -146,14 +170,12 @@ } else { /* only the first instance uses saved position */ - pm->ts.VTPos.x = CW_USEDEFAULT; - pm->ts.VTPos.y = CW_USEDEFAULT; - pm->ts.TEKPos.x = CW_USEDEFAULT; - pm->ts.TEKPos.y = CW_USEDEFAULT; + ts->VTPos.x = CW_USEDEFAULT; + ts->VTPos.y = CW_USEDEFAULT; + ts->TEKPos.x = CW_USEDEFAULT; + ts->TEKPos.y = CW_USEDEFAULT; } - memcpy(ts,&(pm->ts),sizeof(TTTSet)); - // if (FirstInstance) { \x82̕\x94\x95\xAA\x82\xA9\x82\xE7\x88ړ\xAE (2008.3.13 maya) // \x8BN\x93\xAE\x8E\x9E\x82ɂ́A\x8B\xA4\x97L\x83\x81\x83\x82\x83\x8A\x82\xCC HomeDir \x82\xC6 SetupFName \x82͋\xF3\x82ɂȂ\xE9 /* Get home directory (ttermpro.exe\x82̃t\x83H\x83\x8B\x83_) */ Added: trunk/teraterm/ttpcmn/ttcmn_dup.cpp =================================================================== --- trunk/teraterm/ttpcmn/ttcmn_dup.cpp (rev 0) +++ trunk/teraterm/ttpcmn/ttcmn_dup.cpp 2021-11-27 13:49:15 UTC (rev 9547) @@ -0,0 +1,280 @@ +/* + * Copyright (C) 1994-1998 T. Teranishi + * (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <direct.h> +#include <string.h> +#include <stdio.h> +#include <windows.h> +#include <assert.h> +#include <crtdbg.h> +#include <wchar.h> +#if (defined(_MSC_VER) && (_MSC_VER >= 1600)) || !defined(_MSC_VER) +#include <stdint.h> +#endif + +#include "teraterm.h" +#include "tttypes.h" +#include "ttlib.h" +#include "tt_res.h" +#include "codeconv.h" +#include "compat_win.h" +#include "asprintf.h" +#include "ttcommon.h" + +#include "ttcmn_dup.h" + +#if defined(_MSC_VER) && (_MSC_VER < 1600) +typedef unsigned char uint8_t; +#endif + +/** + * \x83f\x81[\x83^\x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x8F\xEE\x95\xF1\x8D\\x91\xA2\x91\xCC + */ +typedef struct { + int size; // \x83f\x81[\x83^\x82̃T\x83C\x83Y(0\x82ŏI\x97\xB9) + int offset; // \x90擪\x82\xA9\x82\xE7\x82̃I\x83t\x83Z\x83b\x83g + enum { + COPY = 0, // \x83f\x81[\x83^\x82\xF0\x83R\x83s\x81[\x82\xB7\x82\xE9 + MALLOCED_WSTRING = 1, // malloc\x82\xB5\x82\xBD\x97̈\xE6\x82\xCC + } type; +} TSerializeInfo; + +/** + * \x83f\x81[\x83^\x82\xF0\x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x82\xB7\x82\xE9 + * + * @param data \x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x82\xB7\x82\xE9\x83f\x81[\x83^ + * @param info \x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x8F\xEE\x95\xF1 + * @param[out] size_ \x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x82\xB5\x82\xBDblob\x83T\x83C\x83Y(byte) + * @return \x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x82\xB5\x82\xBDblob\x83f\x81[\x83^\x82ւ̃|\x83C\x83\x93\x83^ + * \x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7free()\x82\xB7\x82邱\x82\xC6 + */ +static uint8_t *SerializeData(const void *data, const TSerializeInfo *info, size_t *size_) +{ + const unsigned char *src = (unsigned char *)data; + uint8_t *blob = NULL; + size_t size = 0; + while (info->size != 0) { + switch (info->type) { + default: + assert(FALSE); + // fall torught + case TSerializeInfo::COPY: { + const size_t l = info->size; + unsigned char *d; + const unsigned char *s = (unsigned char *)src + info->offset; + blob = (uint8_t *)realloc(blob, size + l); + d = blob + size; + memcpy(d, s, l); + size += l; + break; + } + case TSerializeInfo::MALLOCED_WSTRING: { + wchar_t **s = (wchar_t **)((unsigned char *)src + info->offset); + const wchar_t *src_str = *s; + size_t str_len = 0; + if (src_str != NULL) { + str_len = wcslen(src_str) + 1; + } + const size_t str_len_byte = str_len * sizeof(wchar_t); + const size_t alloc_len = sizeof(size_t) + str_len_byte; + blob = (uint8_t *)realloc(blob, size + alloc_len); + uint8_t *d = blob + size; + *(size_t *)d = str_len; + d += sizeof(size_t); + wmemcpy((wchar_t *)d, src_str, str_len); + size += alloc_len; + break; + } + } + info++; + } + *size_ = size; + return blob; +} + +/** + * \x83A\x83\x93\x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x82\xB7\x82\xE9 + * + * @param blob \x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x82\xB3\x82ꂽ\x83f\x81[\x83^\x82ւ̃|\x83C\x83\x93\x83^ + * @param size \x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x82\xB3\x82ꂽ\x83f\x81[\x83^\x82̃T\x83C\x83Y + * @param info \x83V\x83\x8A\x83A\x83\x89\x83C\x83Y\x8F\xEE\x95\xF1 + * @param[out] data \x8F\x91\x82\xAB\x96߂\xB7\x83f\x81[\x83^ + */ +static void UnserializeData(const void *blob, size_t size, const TSerializeInfo *info, + void *data) +{ + const unsigned char *src = (const unsigned char *)blob; + const unsigned char *end = src + size; + while (info->size != 0) { + switch (info->type) { + default: + assert(FALSE); + break; + case TSerializeInfo::COPY: { + unsigned char *d = (unsigned char *)data + info->offset; + const size_t l = info->size; + memcpy(d, src, l); + src += l; + break; + } + case TSerializeInfo::MALLOCED_WSTRING: { + wchar_t **d = (wchar_t **)((unsigned char *)data + info->offset); + assert(info->size == sizeof(wchar_t *)); + const size_t l = *(size_t *)src; + src += sizeof(size_t); + if (l == 0) { + *d = NULL; + } + else { + const size_t byte_len = l * sizeof(wchar_t); + wchar_t *str = (wchar_t *)malloc(byte_len); + wmemcpy(str, (wchar_t *)src, l); + *d = str; + src += byte_len; + } + break; + } + }; + if (src > end) { + // \x83f\x81[\x83^\x82\xAA\x82\xA8\x82\xA9\x82\xB5\x82\xA2? + assert(FALSE); + break; + } + info++; + } +} + +static const uint8_t signature[] = { + 'T', 'E', 'R', 'A', 'T' , 'E', 'R', 'M', + TT_VERSION_MAJOR, + TT_VERSION_MINOR, + sizeof(void *), // 4 or 8 = 32bit or 64bit + 0, // reserver + (uint8_t)((sizeof(TTTSet) >> (8 * 0)) & 0xff), + (uint8_t)((sizeof(TTTSet) >> (8 * 1)) & 0xff), + (uint8_t)((sizeof(TTTSet) >> (8 * 2)) & 0xff), + (uint8_t)((sizeof(TTTSet) >> (8 * 3)) & 0xff), +}; + +/** + * @return 0\x88ȊO \x83X\x83L\x83b\x83v\x82\xB7\x82\xE9\x83T\x83C\x83Y + * 0 error(\x88قȂ\xC1\x82\xBD) + */ +static uint8_t *MakeSignature(size_t *size) +{ + uint8_t *p = (uint8_t *)malloc(sizeof(signature)); + memcpy(p, signature, sizeof(signature)); + *size = sizeof(signature); + return p; +} + +/** + * @return 0\x88ȊO \x83X\x83L\x83b\x83v\x82\xB7\x82\xE9\x83T\x83C\x83Y + * 0 error(\x88قȂ\xC1\x82\xBD) + */ +static size_t CheckSignature(const uint8_t *ptr, size_t size) +{ + if (size < sizeof(signature)) { + return 0; + } + if (memcmp(ptr, signature, sizeof(signature)) != 0) { + return 0; + } + return sizeof(signature); +} + +#if defined(_MSC_VER) && (_MSC_VER < 1600) +#define offsetof(s,m) ((size_t)&(((s*)0)->m)) +#endif + +#define MALLOCED_WSTRING_INFO(st, member) \ + sizeof(((st *)0)->member), \ + offsetof(st, member), \ + TSerializeInfo::MALLOCED_WSTRING + +/** + * TTTset\x82\xF01\x82̃o\x83C\x83i\x83\x8A\x82ɂ\xB7\x82邽\x82߂̏\xEE\x95\xF1 + * \x95\xFB\x90j + * - \x91S\x91̂\xF0\x83R\x83s\x81[ + * - \x93\xAE\x93I\x8Am\x95ۂ\xB3\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x92lj\xC1 + */ +static const TSerializeInfo serialize_info[] = { + { sizeof(TTTSet), 0, TSerializeInfo::COPY}, // \x91S\x91̂\xF0\x83R\x83s\x81[ + { MALLOCED_WSTRING_INFO(TTTSet, HomeDirW) }, + { MALLOCED_WSTRING_INFO(TTTSet, SetupFNameW) }, + { MALLOCED_WSTRING_INFO(TTTSet, KeyCnfFNW) }, + { MALLOCED_WSTRING_INFO(TTTSet, LogFNW) }, + { MALLOCED_WSTRING_INFO(TTTSet, MacroFNW) }, + { MALLOCED_WSTRING_INFO(TTTSet, UILanguageFileW) }, + { MALLOCED_WSTRING_INFO(TTTSet, UILanguageFileW_ini) }, + { MALLOCED_WSTRING_INFO(TTTSet, ExeDirW) }, + { MALLOCED_WSTRING_INFO(TTTSet, LogDirW) }, + { 0, 0, TSerializeInfo::COPY }, +}; + +/** + * TTTSet \x8D\\x91\xA2\x91̂\xF0\x83o\x83C\x83i\x83\x8A\x83f\x81[\x83^\x82ɕϊ\xB7 + * + * @param ts TTTSet\x8D\\x91\xA2\x91̂ւ̃|\x83C\x83\x93\x83^ + * @return \x83o\x83C\x83i\x83\x8A\x82ւ̃f\x81[\x83^\x82̃T\x83C\x83Y + * @return \x83o\x83C\x83i\x83\x8A\x82ւ̃f\x81[\x83^\x82փ|\x83C\x83\x93\x83^ + */ +void *TTCMNSerialize(const TTTSet *ts, size_t *size) +{ + size_t signature_size; + uint8_t *signature_data = MakeSignature(&signature_size); + size_t data_size; + uint8_t *data = SerializeData(ts, serialize_info, &data_size); + + uint8_t *dest = (uint8_t *)malloc(signature_size + data_size); + memcpy(dest, signature_data, signature_size); + memcpy(dest + signature_size, data, data_size); + free(data); + free(signature_data); + *size = signature_size + data_size; + return dest; +} + +/** + * \x83o\x83C\x83i\x83\x8A\x83f\x81[\x83^\x82\xF0TTTSet \x8D\\x91\xA2\x91̂ɕϊ\xB7\x81A + * + * @param[in] ptr \x83o\x83C\x83i\x83\x8A\x83f\x81[\x83^\x82ւ̃|\x83C\x83\x93\x83^ + * @param[in] size \x83o\x83C\x83i\x83\x8A\x83f\x81[\x83^\x82̃T\x83C\x83Y + * @param[out] ts TTTSet\x8D\\x91\xA2\x91̂ւ̃|\x83C\x83\x93\x83^ + */ +void TTCMNUnserialize(const void *ptr, size_t size, TTTSet *ts) +{ + const uint8_t *data = (uint8_t *)ptr; + size_t signature_size = CheckSignature(data, size); + if (signature_size != 0) { + data += signature_size; + size -= signature_size; + UnserializeData(data, size, serialize_info, ts); + } +} Added: trunk/teraterm/ttpcmn/ttcmn_dup.h =================================================================== --- trunk/teraterm/ttpcmn/ttcmn_dup.h (rev 0) +++ trunk/teraterm/ttpcmn/ttcmn_dup.h 2021-11-27 13:49:15 UTC (rev 9547) @@ -0,0 +1,45 @@ +/* + * Copyright (C) 1994-1998 T. Teranishi + * (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <windows.h> + +#include "tttypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void *TTCMNSerialize(const TTTSet *ts, size_t *size); +void TTCMNUnserialize(const void *ptr, size_t size, TTTSet *ts); + +#ifdef __cplusplus +} +#endif Modified: trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj =================================================================== --- trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj 2021-11-27 13:48:57 UTC (rev 9546) +++ trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj 2021-11-27 13:49:15 UTC (rev 9547) @@ -137,6 +137,7 @@ <ClCompile Include="language.c" /> <ClCompile Include="ttcmn.c" /> <ClCompile Include="ttcmn_cominfo.c" /> + <ClCompile Include="ttcmn_dup.cpp" /> <ClCompile Include="ttcmn_notify.cpp" /> </ItemGroup> <ItemGroup> @@ -147,6 +148,8 @@ <ClInclude Include="..\common\servicenames.h" /> <ClInclude Include="..\common\ttlib.h" /> <ClInclude Include="language.h" /> + <ClInclude Include="ttcmn_cominfo.h" /> + <ClInclude Include="ttcmn_dup.h" /> </ItemGroup> <ItemGroup> <None Include="ttpcmn.def" /> Modified: trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj.filters =================================================================== --- trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj.filters 2021-11-27 13:48:57 UTC (rev 9546) +++ trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj.filters 2021-11-27 13:49:15 UTC (rev 9547) @@ -40,6 +40,9 @@ <ClCompile Include="ttcmn_cominfo.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="ttcmn_dup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\common\i18n.h"> @@ -63,6 +66,12 @@ <ClInclude Include="..\common\devpkey_teraterm.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="ttcmn_dup.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ttcmn_cominfo.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="ttpcmn.def"> Modified: trunk/teraterm/ttpcmn/ttpcmn.v8.vcproj =================================================================== --- trunk/teraterm/ttpcmn/ttpcmn.v8.vcproj 2021-11-27 13:48:57 UTC (rev 9546) +++ trunk/teraterm/ttpcmn/ttpcmn.v8.vcproj 2021-11-27 13:49:15 UTC (rev 9547) @@ -231,6 +231,10 @@ > </File> <File + RelativePath=".\ttcmn_dup.cpp" + > + </File> + <File RelativePath=".\ttcmn_notify.cpp" > </File> @@ -268,6 +272,14 @@ > </File> <File + RelativePath=".\ttcmn_cominfo.h" + > + </File> + <File + RelativePath=".\ttcmn_dup.h" + > + </File> + <File RelativePath="..\common\ttlib.h" > </File>