[PATCH 0 of 2] Windows shellext Unicode porting etc.

12 views
Skip to first unread message

Toshi MARUYAMA

unread,
Aug 17, 2010, 3:22:19 AM8/17/10
to thg...@googlegroups.com

Because thg supports win32mbcs and fixutf8 extension at revision c376099c233e,
I want to push Windows shellext Unicode porting.

As described at http://bitbucket.org/tortoisehg/stable/issue/672
I maintain it at http://bitbucket.org/marutosi/tortoisehg .
Because I merged and resolved conflicts several times, revision tree is complicated.
So, I squashed Marco Lizza's and Tinyfish's jobs.

Toshi MARUYAMA

unread,
Aug 17, 2010, 3:22:20 AM8/17/10
to thg...@googlegroups.com
# HG changeset patch
# User Toshi MARUYAMA <marut...@gmail.com>
# Date 1282029306 -32400
# Node ID 9f13dd64213e31e3ef79a5635788faf63837fec0
# Parent 72b581ed7f9e88b1e484925c2860804bc0fa7e8a
win32shellext: Unicode porting and context-menu disabled on special folders (e.g. start-menu)

Issue #672 and #1241.

Merge squashed following jobs.

* Marco Lizza's patches exclude tortoisehg_rev6547.patch (Msi.lib).
http://groups.google.com/group/thg-dev/browse_thread/thread/8580c791fe5b52b2

* Tinyfish's Unicode porting.
http://bitbucket.org/tinyfish/tortoisehg.winutf8/changeset/cdce65b00f1e

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/CShellExtCMenu.cpp
--- a/win32/shellext/CShellExtCMenu.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/CShellExtCMenu.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -13,154 +13,164 @@
#include "Msi.h"

#include <map>
+#include <tchar.h>

#include "CShellExtCMenu.h"

+#define THG_FILENAME L"thg"
+
+#define LISTFILE_OPT L" --listfile "
+#define LISTFILE_CP CP_ACP

struct MenuDescription
{
- std::string name;
+ std::wstring name;
std::wstring menuText;
std::wstring helpText;
- std::string iconName;
+ std::wstring iconName;
UINT idCmd;
};

+const std::wstring TortoiseHgMenuEntryString = L"TortoiseHg";
+
// According to http://msdn.microsoft.com/en-us/library/bb776094%28VS.85%29.aspx
// the help texts for the commands should be reasonably short (under 40 characters)

MenuDescription menuDescList[] =
{
- {"commit", L"Commit...",
+ {L"commit", L"Commit...",
L"Commit changes in repository",
- "menucommit.ico", 0},
- {"init", L"Create Repository Here",
+ L"menucommit.ico", 0},
+ {L"init", L"Create Repository Here",
L"Create a new repository",
- "menucreaterepos.ico", 0},
- {"clone", L"Clone...",
+ L"menucreaterepos.ico", 0},
+ {L"clone", L"Clone...",
L"Create clone here from source",
- "menuclone.ico", 0},
- {"status", L"View File Status",
+ L"menuclone.ico", 0},
+ {L"status", L"View File Status",
L"Repository status & changes",
- "menushowchanged.ico", 0},
- {"shelve", L"Shelve Changes",
+ L"menushowchanged.ico", 0},
+ {L"shelve", L"Shelve Changes",
L"Shelve or unshelve file changes",
- "shelve.ico", 0},
- {"add", L"Add Files...",
+ L"shelve.ico", 0},
+ {L"add", L"Add Files...",
L"Add files to version control",
- "menuadd.ico", 0},
- {"revert", L"Revert Files...",
+ L"menuadd.ico", 0},
+ {L"revert", L"Revert Files...",
L"Revert file changes",
- "menurevert.ico", 0},
- {"remove", L"Remove Files...",
+ L"menurevert.ico", 0},
+ {L"remove", L"Remove Files...",
L"Remove files from version control",
- "menudelete.ico", 0},
- {"rename", L"Rename File...",
+ L"menudelete.ico", 0},
+ {L"rename", L"Rename File...",
L"Rename file or directory",
- "general.ico", 0},
- {"log", L"Repository Explorer",
+ L"general.ico", 0},
+ {L"log", L"Repository Explorer",
L"View change history in repository",
- "menulog.ico", 0},
- {"synch", L"Synchronize",
+ L"menulog.ico", 0},
+ {L"synch", L"Synchronize",
L"Synchronize with remote repository",
- "menusynch.ico", 0},
- {"serve", L"Web Server",
+ L"menusynch.ico", 0},
+ {L"serve", L"Web Server",
L"Start web server for this repository",
- "proxy.ico", 0},
- {"update", L"Update...",
+ L"proxy.ico", 0},
+ {L"update", L"Update...",
L"Update working directory",
- "menucheckout.ico", 0},
- {"recover", L"Recovery...",
+ L"menucheckout.ico", 0},
+ {L"recover", L"Recovery...",
L"Repair and recovery of repository",
- "general.ico", 0},
- {"thgstatus", L"Update Icons",
+ L"general.ico", 0},
+ {L"thgstatus", L"Update Icons",
L"Update icons for this repository",
- "refresh_overlays.ico", 0},
- {"userconf", L"Global Settings",
+ L"refresh_overlays.ico", 0},
+ {L"userconf", L"Global Settings",
L"Configure user wide settings",
- "settings_user.ico", 0},
- {"repoconf", L"Repository Settings",
+ L"settings_user.ico", 0},
+ {L"repoconf", L"Repository Settings",
L"Configure repository settings",
- "settings_repo.ico", 0},
- {"about", L"About TortoiseHg",
+ L"settings_repo.ico", 0},
+ {L"about", L"About TortoiseHg",
L"Show About Dialog",
- "menuabout.ico", 0},
- {"datamine", L"Annotate Files",
+ L"menuabout.ico", 0},
+ {L"datamine", L"Annotate Files",
L"Changeset information per file line",
- "menublame.ico", 0},
- {"vdiff", L"Visual Diff",
+ L"menublame.ico", 0},
+ {L"vdiff", L"Visual Diff",
L"View changes using GUI diff tool",
- "TortoiseMerge.ico", 0},
- {"hgignore", L"Edit Ignore Filter",
+ L"TortoiseMerge.ico", 0},
+ {L"hgignore", L"Edit Ignore Filter",
L"Edit repository ignore filter",
- "ignore.ico", 0},
- {"guess", L"Guess Renames",
+ L"ignore.ico", 0},
+ {L"guess", L"Guess Renames",
L"Detect renames and copies",
- "detect_rename.ico", 0},
- {"grep", L"Search History",
+ L"detect_rename.ico", 0},
+ {L"grep", L"Search History",
L"Search file revisions for patterns",
- "menurepobrowse.ico", 0},
- {"forget", L"Forget Files...",
+ L"menurepobrowse.ico", 0},
+ {L"forget", L"Forget Files...",
L"Remove files from version control",
- "menudelete.ico", 0},
- {"shellconf", L"Explorer Extension Settings",
+ L"menudelete.ico", 0},
+ {L"shellconf", L"Explorer Extension Settings",
L"Configure Explorer extension",
- "settings_repo.ico", 0},
+ L"settings_repo.ico", 0},
+ {L"tortoisehg", TortoiseHgMenuEntryString,
+ L"Tortoise Hg",
+ L"hg.ico", 0},

/* Add new items here */

// template
- //{"", L"", L"", ".ico", 0},
+ //{L"", L"", L"", ".ico", 0},
};

-const char* const RepoNoFilesMenu =
- "commit status shelve vdiff sep"
- " add revert rename forget remove sep"
- " log update grep sep"
- " synch serve clone init thgstatus sep"
- " hgignore guess recover sep"
- " shellconf repoconf userconf sep"
- " about"
+const wchar_t* const RepoNoFilesMenu =
+ L"commit status shelve vdiff sep"
+ L" add revert rename forget remove sep"
+ L" log update grep sep"
+ L" synch serve clone init thgstatus sep"
+ L" hgignore guess recover sep"
+ L" shellconf repoconf userconf sep"
+ L" about"
;

-const char* const RepoFilesMenu =
- "commit status vdiff sep"
- " add revert rename forget remove sep"
- " log datamine sep"
- " about"
+const wchar_t* const RepoFilesMenu =
+ L"commit status vdiff sep"
+ L" add revert rename forget remove sep"
+ L" log datamine sep"
+ L" about"
;

-const char* const NoRepoMenu =
- "clone init shellconf userconf thgstatus sep"
- " about"
+const wchar_t* const NoRepoMenu =
+ L"clone init shellconf userconf thgstatus sep"
+ L" about"
;


-typedef std::map<std::string, MenuDescription> MenuDescriptionMap;
+typedef std::map<std::wstring, MenuDescription> MenuDescriptionMap;
typedef std::map<UINT, MenuDescription> MenuIdCmdMap;

MenuDescriptionMap MenuDescMap;
MenuIdCmdMap MenuIdMap;


-void AddMenuList(UINT idCmd, const std::string& name)
+void AddMenuList(UINT idCmd, const std::wstring& name)
{
- TDEBUG_TRACE("AddMenuList: idCmd = " << idCmd << " name = " << name);
+ TDEBUG_TRACEW(L"AddMenuList: idCmd = " << idCmd << L" name = " << name);
MenuIdMap[idCmd] = MenuDescMap[name];
}


void GetCMenuTranslation(
- const std::string& lang,
- const std::string& name,
+ const std::wstring& lang,
+ const std::wstring& name,
std::wstring& menuText,
std::wstring& helpText
)
{
std::wstring subkey = L"Software\\TortoiseHg\\CMenu\\";
- subkey += _WCSTR(lang.c_str());
+ subkey += lang;
subkey += L"\\";
- subkey += _WCSTR(name.c_str());
+ subkey += name;

TDEBUG_TRACEW(L"GetCMenuTranslation: " << subkey);

@@ -190,8 +200,8 @@
{
if (MenuDescMap.empty())
{
- std::string lang;
- GetRegistryConfig("CMenuLang", lang);
+ std::wstring lang;
+ GetRegistryConfig(L"CMenuLang", lang);

std::size_t sz = sizeof(menuDescList) / sizeof(MenuDescription);
for (std::size_t i = 0; i < sz; i++)
@@ -200,11 +210,11 @@

if (md.name.size() == 0)
{
- TDEBUG_TRACE("**** InitMenuMaps: ignoring entry with empty name");
+ TDEBUG_TRACEW(L"**** InitMenuMaps: ignoring entry with empty name");
break;
}

- TDEBUG_TRACE("InitMenuMaps: adding " << md.name);
+ TDEBUG_TRACEW(L"InitMenuMaps: adding " << md.name);

// Look for translation of menu and help text
if (lang.size())
@@ -220,7 +230,7 @@

void InsertMenuItemWithIcon1(
HMENU hMenu, UINT indexMenu, UINT idCmd,
- const std::wstring& menuText, const std::string& iconName)
+ const std::wstring& menuText, const std::wstring& iconName)
{
// MFT_STRING is obsolete and should not be used (replaced by MIIM_STRING
// from Win2K onward)
@@ -242,7 +252,7 @@
}
else
{
- TDEBUG_TRACE(" ***** InsertMenuItemWithIcon1: can't find " + iconName);
+ TDEBUG_TRACEW(L" ***** InsertMenuItemWithIcon1: can't find " + iconName);
}
}
else
@@ -256,7 +266,7 @@
}
else
{
- TDEBUG_TRACE(" ***** InsertMenuItemWithIcon1: can't find " + iconName);
+ TDEBUG_TRACEW(L" ***** InsertMenuItemWithIcon1: can't find " + iconName);
}
}
InsertMenuItemW(hMenu, indexMenu, TRUE, &mi);
@@ -268,7 +278,7 @@

void InsertSubMenuItemWithIcon2(
HMENU hMenu, HMENU hSubMenu, UINT indexMenu, UINT idCmd,
- const std::wstring& menuText, const std::string& iconName)
+ const std::wstring& menuText, const std::wstring& iconName)
{
// MFT_STRING is obsolete and should not be used (replaced by MIIM_STRING
// from Win2K onward)
@@ -291,7 +301,7 @@
}
else
{
- TDEBUG_TRACE(" ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
+ TDEBUG_TRACEW(L" ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
}
}
else
@@ -305,25 +315,25 @@
}
else
{
- TDEBUG_TRACE(" ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
+ TDEBUG_TRACEW(L" ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
}
}

InsertMenuItemW(hMenu, indexMenu, TRUE, &mi);

TDEBUG_TRACEW(
- L"InsertMenuItemWithIcon2(\"" << menuText << L"\") finished");
+ L"InsertSubMenuItemWithIcon2(\"" << menuText << L"\") finished");
}


void InsertMenuItemByName(
- HMENU hMenu, const std::string& name, UINT indexMenu,
+ HMENU hMenu, const std::wstring& name, UINT indexMenu,
UINT idCmd, UINT idCmdFirst, const std::wstring& prefix)
{
MenuDescriptionMap::iterator iter = MenuDescMap.find(name);
if (iter == MenuDescMap.end())
{
- TDEBUG_TRACE("***** InsertMenuItemByName: can't find menu info for " << name);
+ TDEBUG_TRACEW(L"***** InsertMenuItemByName: can't find menu info for " << name);
return;
}

@@ -333,8 +343,23 @@
hMenu, indexMenu, idCmd, prefix + md.menuText, md.iconName);
}

+void InsertSubMenuItemByName(
+ HMENU hMenu, HMENU hSubMenu, const std::wstring& name, UINT indexMenu,
+ UINT idCmd, UINT idCmdFirst)
+{
+ MenuDescriptionMap::iterator iter = MenuDescMap.find(name);
+ if (iter == MenuDescMap.end())
+ {
+ TDEBUG_TRACEW(L"***** InsertSubMenuItemByName: can't find menu info for " << name);
+ return;
+ }

-const std::wstring TortoiseHgMenuEntryString = L"TortoiseHg";
+ MenuDescription md = iter->second;
+ AddMenuList(idCmd - idCmdFirst, name);
+ InsertSubMenuItemWithIcon2(hMenu, hSubMenu, indexMenu, idCmd,
+ md.menuText, md.iconName);
+}
+

int HasTortoiseMenu(HMENU hMenu, bool& hasmenu)
// returns -1 on error, 0 otherwise
@@ -344,7 +369,7 @@
const int count = ::GetMenuItemCount(hMenu);
if (count == -1)
{
- TDEBUG_TRACE("***** HasTortoiseMenu: GetMenuItemCount returned -1");
+ TDEBUG_TRACEW(L"***** HasTortoiseMenu: GetMenuItemCount returned -1");
return -1;
}

@@ -358,7 +383,7 @@
mii.fMask = MIIM_STRING;
BOOL res = ::GetMenuItemInfoW(hMenu, i, true, &mii);
if (res == 0) {
- TDEBUG_TRACE("HasTortoiseMenu: "
+ TDEBUG_TRACEW(L"HasTortoiseMenu: "
<< "first GetMenuItemInfo returned 0");
continue;
}
@@ -377,7 +402,7 @@
++mii.cch; // size of buffer is one more than length of string
res = ::GetMenuItemInfoW(hMenu, i, true, &mii);
if (res == 0) {
- TDEBUG_TRACE("HasTortoiseMenu: "
+ TDEBUG_TRACEW(L"HasTortoiseMenu: "
<< "second GetMenuItemInfo returned 0");
continue;
}
@@ -388,24 +413,73 @@

if (menuitemtext == TortoiseHgMenuEntryString)
{
- TDEBUG_TRACE("HasTortoiseMenu: FOUND TortoiseHg menu entry");
+ TDEBUG_TRACEW(L"HasTortoiseMenu: FOUND TortoiseHg menu entry");
hasmenu = true;
return 0;
}
}

- TDEBUG_TRACE("HasTortoiseMenu: TortoiseHg menu entry NOT found");
+ TDEBUG_TRACEW(L"HasTortoiseMenu: TortoiseHg menu entry NOT found");
return 0;
}

#define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i)))

+bool IsSpecialFolder(const std::wstring &folder)
+{
+ static int pCSIDL[] =
+ {
+ CSIDL_BITBUCKET,
+ CSIDL_CDBURN_AREA,
+ CSIDL_COMMON_STARTMENU,
+ CSIDL_COMPUTERSNEARME,
+ CSIDL_CONNECTIONS,
+ CSIDL_CONTROLS,
+ CSIDL_COOKIES,
+ CSIDL_FONTS,
+ CSIDL_HISTORY,
+ CSIDL_INTERNET,
+ CSIDL_INTERNET_CACHE,
+ CSIDL_NETHOOD,
+ CSIDL_NETWORK,
+ CSIDL_PRINTERS,
+ CSIDL_PRINTHOOD,
+ CSIDL_RECENT,
+ CSIDL_SENDTO,
+ CSIDL_STARTMENU,
+ 0
+ };
+
+ TDEBUG_TRACEW(L"IsSpecialFolder");
+ for (int i = 0; pCSIDL[i] != 0; i++)
+ {
+ LPITEMIDLIST pIDL = NULL;
+ if (SHGetSpecialFolderLocation(NULL, pCSIDL[i], &pIDL) != S_OK)
+ continue;
+
+ TCHAR tszPath[MAX_PATH + 1] = { _T('\0') };
+ BOOL bResult = SHGetPathFromIDList(pIDL, tszPath);
+
+ CoTaskMemFree(pIDL);
+
+ if ((bResult == FALSE) || (tszPath[0] == _T('\0')))
+ continue;
+
+ if (_tcsicmp(tszPath, folder.c_str())==0)
+ {
+ TDEBUG_TRACEW(L" folder '" << folder << L"' is special");
+ return true;
+ }
+ }
+ return false;
+}
+
// IContextMenu
STDMETHODIMP
CShellExtCMenu::QueryContextMenu(
HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
- TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu");
+ TDEBUG_TRACEW(L"CShellExtCMenu::QueryContextMenu");

UINT idCmd = idCmdFirst;
BOOL bAppendItems = TRUE;
@@ -425,26 +499,26 @@
bool hasthgmenu = false;
if (HasTortoiseMenu(hMenu, hasthgmenu) == 0 && hasthgmenu)
{
- TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu: "
+ TDEBUG_TRACEW(L"CShellExtCMenu::QueryContextMenu: "
<< "TortoiseHg menu entry already in menu -> skipping");
return S_OK;
}

InitMenuMaps();

- typedef std::vector<std::string> entriesT;
+ typedef std::vector<std::wstring> entriesT;
typedef entriesT::const_iterator entriesIter;

- std::string promoted_string = "commit,log"; // default value if key not found
- GetRegistryConfig("PromotedItems", promoted_string);
+ std::wstring promoted_string = L"commit,log"; // default value if key not found
+ GetRegistryConfig(L"PromotedItems", promoted_string);

entriesT promoted;
- Tokenize(promoted_string, promoted, ",");
+ Tokenize(promoted_string, promoted, L",");

// Select menu to show
bool fileMenu = myFiles.size() > 0;
bool isHgrepo = false;
- std::string cwd;
+ std::wstring cwd;
if (!myFolder.empty())
{
cwd = myFolder;
@@ -454,10 +528,16 @@
cwd = IsDirectory(myFiles[0])? myFiles[0] : DirName(myFiles[0]);
}

+ if (IsSpecialFolder(cwd)) {
+ // disable context menu if in a special folder
+ TDEBUG_TRACEW(L" shell-extension not available in this folder");
+ return S_OK;
+ }
+
if (!cwd.empty())
{
// check if target directory is a Mercurial repository
- std::string root = GetHgRepoRoot(cwd);
+ std::wstring root = GetHgRepoRoot(cwd);
isHgrepo = !root.empty();
if (myFiles.size() == 1 && root == myFiles[0])
{
@@ -467,13 +547,13 @@
}
}

- TDEBUG_TRACE(
- "CShellExtCMenu::QueryContextMenu: isHgrepo = "
- << isHgrepo << ", fileMenu = " << fileMenu
+ TDEBUG_TRACEW(
+ L"CShellExtCMenu::QueryContextMenu: isHgrepo = "
+ << isHgrepo << L", fileMenu = " << fileMenu
);

/* We have three menu types: files-selected, no-files-selected, no-repo */
- const char* entries_string = 0;
+ const wchar_t* entries_string = 0;
if (isHgrepo)
if (fileMenu)
entries_string = RepoFilesMenu;
@@ -486,11 +566,11 @@
InsertMenu(hMenu, indexMenu++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);

entriesT entries;
- Tokenize(entries_string, entries, " ");
+ Tokenize(entries_string, entries, L" ");

for (entriesIter i = entries.begin(); i != entries.end(); i++)
{
- std::string name = *i;
+ std::wstring name = *i;
if (contains(promoted, name))
{
InsertMenuItemByName(
@@ -507,8 +587,8 @@
bool isSeparator = true;
for (entriesIter i = entries.begin(); i != entries.end(); i++)
{
- std::string name = *i;
- if (name == "sep")
+ std::wstring name = *i;
+ if (name == L"sep")
{
if (!isSeparator)
{
@@ -548,9 +628,8 @@
}
}

- TDEBUG_TRACE(" CShellExtCMenu::QueryContextMenu: adding main THG menu");
- InsertSubMenuItemWithIcon2(hMenu, hSubMenu, indexMenu++, idCmd++,
- TortoiseHgMenuEntryString, "hg.ico");
+ TDEBUG_TRACEW(L" CShellExtCMenu::QueryContextMenu: adding main THG menu");
+ InsertSubMenuItemByName(hMenu, hSubMenu, L"tortoisehg", indexMenu++, idCmd++, idCmdFirst);

InsertMenu(hMenu, indexMenu++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);

@@ -576,13 +655,13 @@
STDMETHODIMP
CShellExtCMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
- TDEBUG_TRACE("CShellExtCMenu::InvokeCommand");
+ TDEBUG_TRACEW(L"CShellExtCMenu::InvokeCommand");

HRESULT hr = E_INVALIDARG;
if (!HIWORD(lpcmi->lpVerb))
{
UINT idCmd = LOWORD(lpcmi->lpVerb);
- TDEBUG_TRACE("CShellExtCMenu::InvokeCommand: idCmd = " << idCmd);
+ TDEBUG_TRACEW(L"CShellExtCMenu::InvokeCommand: idCmd = " << idCmd);
MenuIdCmdMap::iterator iter = MenuIdMap.find(idCmd);
if (iter != MenuIdMap.end())
{
@@ -591,8 +670,8 @@
}
else
{
- TDEBUG_TRACE(
- "***** CShellExtCMenu::InvokeCommand: action not found for idCmd "
+ TDEBUG_TRACEW(
+ L"***** CShellExtCMenu::InvokeCommand: action not found for idCmd "
<< idCmd
);
}
@@ -613,38 +692,38 @@
const char* psz = "";
const wchar_t* pszw = 0;

- std::string sflags = "?";
+ std::wstring sflags = L"?";
switch (uFlags)
{
case GCS_HELPTEXTW:
- sflags = "GCS_HELPTEXTW"; break;
+ sflags = L"GCS_HELPTEXTW"; break;
case GCS_HELPTEXTA:
- sflags = "GCS_HELPTEXTA"; break;
+ sflags = L"GCS_HELPTEXTA"; break;
case GCS_VALIDATEW:
- sflags = "GCS_VALIDATEW"; break;
+ sflags = L"GCS_VALIDATEW"; break;
case GCS_VALIDATEA:
- sflags = "GCS_VALIDATEA"; break;
+ sflags = L"GCS_VALIDATEA"; break;
case GCS_VERBW:
- sflags = "GCS_VERBW"; break;
+ sflags = L"GCS_VERBW"; break;
case GCS_VERBA:
- sflags = "GCS_VERBA"; break;
+ sflags = L"GCS_VERBA"; break;
}

- TDEBUG_TRACE(
- "CShellExtCMenu::GetCommandString: idCmd = " << idCmd
- << ", uFlags = " << uFlags << " (" << sflags << ")"
- << ", cchMax = " << cchMax
+ TDEBUG_TRACEW(
+ L"CShellExtCMenu::GetCommandString: idCmd = " << idCmd
+ << L", uFlags = " << uFlags << L" (" << sflags << L")"
+ << L", cchMax = " << cchMax
);

MenuIdCmdMap::iterator iter = MenuIdMap.find(static_cast<UINT>(idCmd));
if (iter == MenuIdMap.end())
{
- TDEBUG_TRACE("***** CShellExtCMenu::GetCommandString: idCmd not found");
+ TDEBUG_TRACEW(L"***** CShellExtCMenu::GetCommandString: idCmd not found");
}
else
{
- TDEBUG_TRACE(
- "CShellExtCMenu::GetCommandString: name = \"" << iter->second.name << "\"");
+ TDEBUG_TRACEW(
+ L"CShellExtCMenu::GetCommandString: name = \"" << iter->second.name << L"\"");

if (uFlags == GCS_HELPTEXTW)
{
@@ -654,10 +733,10 @@
size_t size = iter->second.helpText.size();
if (size >= 40)
{
- TDEBUG_TRACE(
- "***** CShellExtCMenu::GetCommandString: warning:"
- << " length of help text is " << size
- << ", which is not reasonably short (<40)");
+ TDEBUG_TRACEW(
+ L"***** CShellExtCMenu::GetCommandString: warning:"
+ << L" length of help text is " << size
+ << L", which is not reasonably short (<40)");
}
}
else if (uFlags == GCS_HELPTEXTA)
@@ -684,7 +763,7 @@

if (cchMax < 1)
{
- TDEBUG_TRACE("CShellExtCMenu::GetCommandString: cchMax = "
+ TDEBUG_TRACEW(L"CShellExtCMenu::GetCommandString: cchMax = "
<< cchMax << " (is <1)");
return res;
}
@@ -694,7 +773,8 @@
if (uFlags & GCS_UNICODE)
{
wchar_t* const dest = reinterpret_cast<wchar_t*>(pszName);
- const wchar_t* const src = pszw ? pszw : _WCSTR(psz);
+ std::wstring ws_src = MultibyteToWide(psz, CP_ACP, 0) ;
+ const wchar_t* const src = pszw ? pszw : ws_src.c_str();

wcsncpy(dest, src, cchMax-1);
*(dest + cchMax-1) = 0;
@@ -711,15 +791,15 @@

size = strlen(psz);

- TDEBUG_TRACE("CShellExtCMenu::GetCommandString: res = " << int(res)
+ TDEBUG_TRACEW(L"CShellExtCMenu::GetCommandString: res = " << int(res)
<< ", pszName = \"" << psz << "\"");
}

if (size > cchMax-1)
{
- TDEBUG_TRACE(
- "***** CShellExtCMenu::GetCommandString: string was truncated: size = "
- << size << ", cchMax = " << cchMax);
+ TDEBUG_TRACEW(
+ L"***** CShellExtCMenu::GetCommandString: string was truncated: size = "
+ << size << L", cchMax = " << cchMax);
}

return res;
@@ -785,33 +865,33 @@
}


-void CShellExtCMenu::RunDialog(const std::string &cmd)
+void CShellExtCMenu::RunDialog(const std::wstring &cmd)
{
- std::string dir = GetTHgProgRoot();
+ std::wstring dir = GetTHgProgRoot();
if (dir.empty())
{
- TDEBUG_TRACE("RunDialog: THG root is empty");
+ TDEBUG_TRACEW(L"RunDialog: THG root is empty");
return;
}
- std::string hgcmd = dir + "\\thg.exe";

- WIN32_FIND_DATAA data;
- HANDLE hfind = FindFirstFileA(hgcmd.c_str(), &data);
+ std::wstring hgcmd = dir + L"\\" + THG_FILENAME + L".exe";
+
+ WIN32_FIND_DATA data;
+ HANDLE hfind = FindFirstFile(hgcmd.c_str(), &data);
if (hfind == INVALID_HANDLE_VALUE)
{
- hgcmd = dir + "\\hgtk.exe";
- hfind = FindFirstFileA(hgcmd.c_str(), &data);
+ hfind = FindFirstFile(hgcmd.c_str(), &data);
if (hfind == INVALID_HANDLE_VALUE)
- hgcmd = dir + "\\thg.cmd";
+ hgcmd = dir + L"\\" + THG_FILENAME + L".cmd";
else
FindClose(hfind);
}
else
FindClose(hfind);

- hgcmd = Quote(hgcmd) + " --nofork " + cmd;
+ hgcmd = Quote(hgcmd) + L" --nofork " + cmd;

- std::string cwd;
+ std::wstring cwd;
if (!myFolder.empty())
{
cwd = myFolder;
@@ -822,52 +902,56 @@
}
else
{
- TDEBUG_TRACE("***** RunDialog: can't get cwd");
+ TDEBUG_TRACEW(L"***** RunDialog: can't get cwd");
return;
}

+ UINT CodePage = LISTFILE_CP ;
+ std::wstring listfile_opt = LISTFILE_OPT ;

if (!myFiles.empty())
{
- const std::string tempfile = GetTemporaryFile();
+ const std::wstring tempfile = GetTemporaryFile();
+
if (tempfile.empty())
{
- TDEBUG_TRACE("***** RunDialog: error: GetTemporaryFile returned empty string");
+ TDEBUG_TRACEW(L"***** RunDialog: error: GetTemporaryFile returned empty string");
return;
}

- TDEBUG_TRACE("RunDialog: temp file = " << tempfile);
- HANDLE tempfileHandle = CreateFileA(
+ TDEBUG_TRACEW(L"RunDialog: temp file = " << tempfile);
+ HANDLE tempfileHandle = CreateFile(
tempfile.c_str(), GENERIC_WRITE,
FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
);

if (tempfileHandle == INVALID_HANDLE_VALUE)
{
- TDEBUG_TRACE("***** RunDialog: error: failed to create file " << tempfile);
+ TDEBUG_TRACEW(L"***** RunDialog: error: failed to create file " << tempfile);
return;
}

- typedef std::vector<std::string>::size_type ST;
+ typedef std::vector<std::wstring>::size_type ST;
for (ST i = 0; i < myFiles.size(); i++)
{
DWORD dwWritten;
- TDEBUG_TRACE("RunDialog: temp file adding " << myFiles[i]);
+ std::string str_file = WideToMultibyte(myFiles[i], CodePage);
+ TDEBUG_TRACEW(L"RunDialog: temp file adding " << myFiles[i]);
WriteFile(
- tempfileHandle, myFiles[i].c_str(),
- static_cast<DWORD>(myFiles[i].size()), &dwWritten, 0
+ tempfileHandle, str_file.c_str(),
+ static_cast<DWORD>(str_file.size()), &dwWritten, 0
);
- WriteFile(tempfileHandle, "\n", 1, &dwWritten, 0);
+ WriteFile(tempfileHandle, "\n", sizeof(char), &dwWritten, 0);
}
CloseHandle(tempfileHandle);
- hgcmd += " --listfile " + Quote(tempfile);
+ hgcmd += listfile_opt + Quote(tempfile);
}

- if (cmd == "thgstatus")
+ if (cmd == L"thgstatus")
{
if (Thgstatus::remove(cwd) != 0)
{
- std::string p = dir + "\\TortoiseHgOverlayServer.exe";
+ std::wstring p = dir + L"\\TortoiseHgOverlayServer.exe";
LaunchCommand(Quote(p), cwd);
}
InitStatus::check();
@@ -884,27 +968,27 @@
{
TCHAR name[MAX_PATH+1];

- TDEBUG_TRACE("CShellExtCMenu::Initialize");
+ TDEBUG_TRACEW(L"CShellExtCMenu::Initialize");

// get installed MSI product id (for debugging purposes for now)
#ifdef _M_X64
- const char* shellexid = "{59FD2A49-BA62-40CC-B155-D11DB11EE611}";
+ const wchar_t* shellexid = L"{59FD2A49-BA62-40CC-B155-D11DB11EE611}";
#else
- const char* shellexid = "{1126CF42-3994-428B-A746-464E1BC680F3}";
+ const wchar_t* shellexid = L"{1126CF42-3994-428B-A746-464E1BC680F3}";
#endif
- std::vector<char> product_id(50, 0);
- UINT msires = ::MsiGetProductCodeA(shellexid, &product_id[0]);
- TDEBUG_TRACE("MSI shellexid: " << shellexid);
- TDEBUG_TRACE("MSI msires: " << msires);
- TDEBUG_TRACE("MSI installed product id: " << &product_id[0]);
+ std::vector<wchar_t> product_id(50, 0);
+ UINT msires = ::MsiGetProductCode(shellexid, &product_id[0]);
+ TDEBUG_TRACEW(L"MSI shellexid: " << shellexid);
+ TDEBUG_TRACEW(L"MSI msires: " << msires);
+ TDEBUG_TRACEW(L"MSI installed product id: " << &product_id[0]);

TDEBUG_TRACEW(
L"---- TortoiseHg shell extension version "
<< ThgVersion::get() << L"----"
);

- TDEBUG_TRACE(" pIDFolder: " << pIDFolder);
- TDEBUG_TRACE(" pDataObj: " << pDataObj);
+ TDEBUG_TRACEW(L" pIDFolder: " << pIDFolder);
+ TDEBUG_TRACEW(L" pDataObj: " << pDataObj);

myFolder.clear();
myFiles.clear();
@@ -913,56 +997,54 @@
{
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
- if (SUCCEEDED(pDataObj->GetData(&fmt, &stg)) && stg.hGlobal)
+ if (SUCCEEDED(pDataObj->GetData(&fmt, &stg)))
{
HDROP hDrop = (HDROP) GlobalLock(stg.hGlobal);

if (hDrop)
{
UINT uNumFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
- TDEBUG_TRACE(" hDrop uNumFiles = " << uNumFiles);
+ TDEBUG_TRACEW(L" hDrop uNumFiles = " << uNumFiles);
for (UINT i = 0; i < uNumFiles; ++i) {
if (DragQueryFile(hDrop, i, name, MAX_PATH) > 0)
{
- TDEBUG_TRACE(" DragQueryFile [" << i << "] = " << name);
+ TDEBUG_TRACEW(L" DragQueryFile [" << i << "] = " << name);
myFiles.push_back(name);
}
}
}
- else
- {
- TDEBUG_TRACE(" hDrop is NULL ");
- }

GlobalUnlock(stg.hGlobal);
- if (stg.pUnkForRelease)
+ ReleaseStgMedium(&stg);
+
+ if (hDrop == NULL)
{
- IUnknown* relInterface = (IUnknown*) stg.pUnkForRelease;
- relInterface->Release();
+ TDEBUG_TRACEW(L" hDrop is NULL ");
+ return E_INVALIDARG;
}
}
else
{
- TDEBUG_TRACE(" pDataObj->GetData failed");
+ TDEBUG_TRACEW(L" pDataObj->GetData failed");
+ return E_INVALIDARG;
}
}

// if a directory background
if (pIDFolder)
{
- SHGetPathFromIDList(pIDFolder, name);
- TDEBUG_TRACE(" Folder " << name);
- myFolder = name;
+ if (SHGetPathFromIDList(pIDFolder, name) == TRUE)
+ {
+ TDEBUG_TRACEW(L" Folder " << name);
+ myFolder = name;
+ }
+ else
+ {
+ TDEBUG_TRACEW(L" SHGetPathFromIDList() failed");
+ return E_INVALIDARG;
+ }
}
-
- // disable context menu if neither the folder nor the files
- // have been found
- if (myFolder.empty() && myFiles.empty()) {
- TDEBUG_TRACE(" shell extension not available on this object");
- return E_FAIL;
- } else {
- return S_OK;
- }
+ return S_OK;
}


diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/CShellExtCMenu.h
--- a/win32/shellext/CShellExtCMenu.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/CShellExtCMenu.h Tue Aug 17 16:15:06 2010 +0900
@@ -9,11 +9,11 @@
{
ULONG m_cRef;

- LPTSTR* m_ppszFileUserClickedOn; // [MAX_PATH]
- std::vector<std::string> myFiles;
- std::string myFolder;
+ LPWSTR* m_ppszFileUserClickedOn; // [MAX_PATH]
+ std::vector<std::wstring> myFiles;
+ std::wstring myFolder;

- void RunDialog(const std::string&);
+ void RunDialog(const std::wstring&);

public:
explicit CShellExtCMenu(char dummy);
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/CShellExtOverlay.cpp
--- a/win32/shellext/CShellExtOverlay.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/CShellExtOverlay.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -12,7 +12,7 @@
STDMETHODIMP CShellExtOverlay::GetOverlayInfo(
LPWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags)
{
- TDEBUG_TRACE("CShellExtOverlay::GetOverlayInfo: myTortoiseClass = " << myTortoiseClass);
+ TDEBUG_TRACEW(L"CShellExtOverlay::GetOverlayInfo: myTortoiseClass = " << myTortoiseClass);
// icons are determined by TortoiseOverlays shim
*pIndex = 0;
*pdwFlags = 0;
@@ -32,8 +32,8 @@
{
ThgCriticalSection cs(CShellExt::GetCriticalSection());

- std::string cval;
- if (GetRegistryConfig("EnableOverlays", cval) != 0 && cval == "0")
+ std::wstring cval;
+ if (GetRegistryConfig(L"EnableOverlays", cval) != 0 && cval == L"0")
return S_FALSE;

// This overlay handler processes all filenames in lowercase, so that a path
@@ -43,13 +43,13 @@
std::wstring lowerpath(pwszPath);
::CharLowerW(const_cast<wchar_t*>(lowerpath.c_str()));

- std::string path = WideToMultibyte(lowerpath.c_str());
+ std::wstring path = lowerpath; //WideToMultibyte(lowerpath.c_str());

- if (GetRegistryConfig("LocalDisksOnly", cval) != 0 && cval != "0"
+ if (GetRegistryConfig(L"LocalDisksOnly", cval) != 0 && cval != L"0"
&& PathIsNetworkPath(path.c_str()))
return S_FALSE;

- char filterStatus = 0;
+ wchar_t filterStatus = 0;
if (myTortoiseClass == 'A')
filterStatus = 'A';

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Directory.cpp
--- a/win32/shellext/Directory.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Directory.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -15,16 +15,16 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

+#include "stdafx.h"
+
#include <time.h>

-#include "stdafx.h"
-
#include "Directory.h"
#include "Winstat.h"


Directory::Directory(
- Directory* p, const std::string& n, const std::string& basepath
+ Directory* p, const std::wstring& n, const std::wstring& basepath
):
parent_(p), name_(n)
{
@@ -33,7 +33,7 @@
else if (basepath.empty())
path_ = n;
else
- path_ = basepath + '/' + n;
+ path_ = basepath + L'/' + n;
}


@@ -46,13 +46,13 @@
}


-int splitbase(const std::string& n, std::string& base, std::string& rest)
+int splitbase(const std::wstring& n, std::wstring& base, std::wstring& rest)
{
if (n.empty())
return 0;

- size_t x = n.find_first_of ('/');
- if (x == std::string::npos)
+ size_t x = n.find_first_of (L'/');
+ if (x == std::wstring::npos)
{
base.clear();
rest = n;
@@ -69,19 +69,19 @@
}


-int Directory::add(const std::string& n_in, Direntry& e)
+int Directory::add(const std::wstring& n_in, Direntry& e)
{
- std::string base;
- std::string rest;
+ std::wstring base;
+ std::wstring rest;

- std::string n = n_in;
+ std::wstring n = n_in;
Directory* cur = this;

for (;;)
{

if (!splitbase(n, base, rest)) {
- TDEBUG_TRACE("Directory(" << path() << ")::add(" << n_in
+ TDEBUG_TRACEW(L"Directory(" << path() << ")::add(" << n_in
<< "): splitbase returned 0");
return 0;
}
@@ -115,12 +115,12 @@
}


-const Direntry* Directory::get(const std::string& n_in) const
+const Direntry* Directory::get(const std::wstring& n_in) const
{
- std::string base;
- std::string rest;
+ std::wstring base;
+ std::wstring rest;

- std::string n = n_in;
+ std::wstring n = n_in;
const Directory* cur = this;

for (;;)
@@ -129,7 +129,7 @@

if (!splitbase(n, base, rest))
{
- TDEBUG_TRACE("Directory(" << path() << ")::get("
+ TDEBUG_TRACEW(L"Directory(" << path() << ")::get("
<< n_in << "): splitbase returned 0");
return 0;
}
@@ -161,12 +161,12 @@
}


-Directory* Directory::getdir(const std::string& n_in)
+Directory* Directory::getdir(const std::wstring& n_in)
{
- std::string base;
- std::string rest;
+ std::wstring base;
+ std::wstring rest;

- std::string n = n_in;
+ std::wstring n = n_in;
const Directory* cur = this;

for (;;)
@@ -175,13 +175,13 @@

if (!splitbase(n, base, rest))
{
- TDEBUG_TRACE("Directory(" << path() << ")::getdir("
+ TDEBUG_TRACEW(L"Directory(" << path() << ")::getdir("
<< n_in << "): splitbase returned 0");
return 0;
}

const bool leaf = base.empty();
- const std::string& searchstr = (leaf ? n : base);
+ const std::wstring& searchstr = (leaf ? n : base);

for (DirsT::const_iterator i = cur->subdirs_.begin();
i != cur->subdirs_.end(); ++i)
@@ -208,32 +208,32 @@
const Directory* d = *i;
if (!d)
{
- TDEBUG_TRACE("Directory(" << path() << ")::print: error: d is 0");
+ TDEBUG_TRACEW(L"Directory(" << path() << ")::print: error: d is 0");
return;
}
d->print();
}

- std::string base = path();
+ std::wstring base = path();

time_t t;
- std::string s;
- char* ctime_res = 0;
+ std::wstring s;
+ wchar_t* ctime_res = 0;

for (FilesT::const_iterator i = files_.begin(); i != files_.end(); ++i)
{
- std::string p = (!base.empty() ? base + "/" + i->name : i->name);
+ std::wstring p = (!base.empty() ? base + L"/" + i->name : i->name);
t = i->mtime;
- ctime_res = ctime(&t);
+ ctime_res = _wctime(&t);
if (ctime_res) {
s = ctime_res;
s.resize(s.size() - 1); // strip ending '\n'
}
else {
- s = "unset";
+ s = L"unset";
}
- printf(
- "%c %6o %10u %-24s %s\n",
+ wprintf(
+ L"%c %6o %10u %-24s %s\n",
i->state, i->mode, i->size, s.c_str(), p.c_str()
);
}
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Directory.h
--- a/win32/shellext/Directory.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Directory.h Tue Aug 17 16:15:06 2010 +0900
@@ -30,22 +30,22 @@
typedef std::vector<Direntry> FilesT;

Directory* const parent_;
- const std::string name_;
- std::string path_;
+ const std::wstring name_;
+ std::wstring path_;

DirsT subdirs_;
FilesT files_;

public:
- Directory(Directory* p, const std::string& n, const std::string& basepath);
+ Directory(Directory* p, const std::wstring& n, const std::wstring& basepath);
~Directory();

- const std::string& path() const { return path_; }
+ const std::wstring& path() const { return path_; }

- int add(const std::string& relpath, Direntry& e);
+ int add(const std::wstring& relpath, Direntry& e);

- const Direntry* get(const std::string& relpath) const;
- Directory* getdir(const std::string& n);
+ const Direntry* get(const std::wstring& relpath) const;
+ Directory* getdir(const std::wstring& n);

void print() const;
};
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/DirectoryStatus.cpp
--- a/win32/shellext/DirectoryStatus.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/DirectoryStatus.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -21,13 +21,13 @@
#include "TortoiseUtils.h"


-char DirectoryStatus::status(const std::string& relpath_) const
+wchar_t DirectoryStatus::status(const std::wstring& relpath_) const
{
- char res = 'C';
+ wchar_t res = L'C';
bool added = false;
bool modified = false;

- const std::string relpath = relpath_ + '/';
+ const std::wstring relpath = relpath_ + L'/';

for (V::const_iterator i = v_.begin(); i != v_.end(); ++i)
{
@@ -56,18 +56,18 @@
}


-int DirectoryStatus::read(const std::string& hgroot, const std::string& cwd)
+int DirectoryStatus::read(const std::wstring& hgroot, const std::wstring& cwd)
{
v_.clear();
noicons_ = false;

- std::string p = hgroot + "\\.hg\\thgstatus";
+ std::wstring p = hgroot + L"\\.hg\\thgstatus";

FILE *f = fopenReadRenameAllowed(p.c_str());
if (!f)
{
- TDEBUG_TRACE("DirectoryStatus::read: can't open '" << p << "'");
- std::string p = (cwd.size() < hgroot.size() ? hgroot : cwd);
+ TDEBUG_TRACEW(L"DirectoryStatus::read: can't open '" << p << L"'");
+ std::wstring p = (cwd.size() < hgroot.size() ? hgroot : cwd);
Thgstatus::update(p);
return 0;
}
@@ -75,20 +75,20 @@
DirectoryStatus::E e;

int res = 1;
- const std::string noicons = "@@noicons";
+ const std::wstring noicons = L"@@noicons";

- std::vector<char> vline(200);
+ std::vector<wchar_t> vline(200);

for (;;)
{
vline.clear();
- char t;
+ wchar_t t;

for (;;)
{
if (fread(&t, sizeof(t), 1, f) != 1)
goto close;
- if (t == '\n')
+ if (t == L'\n')
break;
vline.push_back(t);
if (vline.size() > 1000)
@@ -99,7 +99,7 @@
}
vline.push_back(0);

- std::string line = &vline[0];
+ std::wstring line = &vline[0];

if (line.substr(0, noicons.size()) == noicons)
{
@@ -112,11 +112,11 @@

e.status_ = line[0];

- std::string path;
+ std::wstring path;
if (line.size() > 1)
{
path = line.c_str() + 1;
- ::CharLower(const_cast<char*>(path.c_str()));
+ ::CharLower(const_cast<wchar_t*>(path.c_str()));
}
path.push_back('/');

@@ -128,7 +128,7 @@
close:
fclose(f);

- TDEBUG_TRACE("DirectoryStatus::read(" << hgroot << "): done. "
+ TDEBUG_TRACEW(L"DirectoryStatus::read(" << hgroot << "): done. "
<< v_.size() << " entries read. noicons_ = " << noicons_ );

return res;
@@ -137,7 +137,7 @@

struct CacheEntry
{
- std::string hgroot_;
+ std::wstring hgroot_;
DirectoryStatus ds_;
bool readfailed_;
unsigned tickcount_;
@@ -147,7 +147,7 @@


DirectoryStatus* DirectoryStatus::get(
- const std::string& hgroot, const std::string& cwd)
+ const std::wstring& hgroot, const std::wstring& cwd)
{
static CacheEntry ce;

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/DirectoryStatus.h
--- a/win32/shellext/DirectoryStatus.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/DirectoryStatus.h Tue Aug 17 16:15:06 2010 +0900
@@ -22,8 +22,8 @@
{
struct E
{
- std::string path_;
- char status_;
+ std::wstring path_;
+ wchar_t status_;

E(): status_(0) {}
};
@@ -36,10 +36,10 @@
DirectoryStatus(): noicons_(false) {}

static DirectoryStatus* get(
- const std::string& hgroot, const std::string& cwd);
- char status(const std::string& relpath) const;
+ const std::wstring& hgroot, const std::wstring& cwd);
+ wchar_t status(const std::wstring& relpath) const;
bool noicons() const { return noicons_; }

private:
- int read(const std::string& hgroot, const std::string& cwd);
+ int read(const std::wstring& hgroot, const std::wstring& cwd);
};
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Direntry.cpp
--- a/win32/shellext/Direntry.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Direntry.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -42,8 +42,6 @@
fread(&relpath[0], sizeof(char), length, f);
relpath[length] = 0;

- ::CharLowerBuff(&relpath[0], length);
-
return 1;
}

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Direntry.h
--- a/win32/shellext/Direntry.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Direntry.h Tue Aug 17 16:15:06 2010 +0900
@@ -35,7 +35,7 @@
unsigned size;
unsigned mtime;

- std::string name;
+ std::wstring name;

int read(FILE* f, std::vector<char>& relpath);
char status(const Winstat& stat) const;
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Dirstatecache.cpp
--- a/win32/shellext/Dirstatecache.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Dirstatecache.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -31,7 +31,7 @@


Dirstate* Dirstatecache::get(
- const std::string& hgroot, const std::string& cwd, bool& unset)
+ const std::wstring& hgroot, const std::wstring& cwd, bool& unset)
{
unset = false;

@@ -45,7 +45,7 @@
}

Winstat64 stat;
- std::string path = hgroot + "\\.hg\\dirstate";
+ std::wstring path = hgroot + L"\\.hg\\dirstate";

unsigned tc = GetTickCount();
bool new_stat = false;
@@ -54,15 +54,15 @@
{
if (stat.lstat(path.c_str()) != 0)
{
- TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") failed");
+ TDEBUG_TRACEW(L"Dirstatecache::get: lstat(" << path <<") failed");
return 0;
}
- TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") ok ");
+ TDEBUG_TRACEW(L"Dirstatecache::get: lstat(" << path <<") ok ");
new_stat = true;

if (cache().size() >= 10)
{
- TDEBUG_TRACE("Dirstatecache::get: dropping "
+ TDEBUG_TRACEW(L"Dirstatecache::get: dropping "
<< cache().back().hgroot);
delete cache().back().dstate;
cache().back().dstate = 0;
@@ -80,15 +80,15 @@
{
if (0 != stat.lstat(path.c_str()))
{
- TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") failed");
- TDEBUG_TRACE("Dirstatecache::get: dropping " << iter->hgroot);
+ TDEBUG_TRACEW(L"Dirstatecache::get: lstat(" << path <<") failed");
+ TDEBUG_TRACEW(L"Dirstatecache::get: dropping " << iter->hgroot);
delete iter->dstate;
iter->dstate = 0;
cache().erase(iter);
return 0;
}
iter->tickcount = tc;
- TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") ok ");
+ TDEBUG_TRACEW(L"Dirstatecache::get: lstat(" << path <<") ok ");
new_stat = true;
}

@@ -105,11 +105,11 @@
return iter->dstate;
}

- TDEBUG_TRACE("Dirstatecache::get: refreshing " << hgroot);
+ TDEBUG_TRACEW(L"Dirstatecache::get: refreshing " << hgroot);
}
else
{
- TDEBUG_TRACE("Dirstatecache::get: reading " << hgroot);
+ TDEBUG_TRACEW(L"Dirstatecache::get: reading " << hgroot);
}

unset = false;
@@ -123,13 +123,13 @@
{
if (iter->unset)
{
- TDEBUG_TRACE(
- "Dirstatecache::get: **** old and new have unset entries");
+ TDEBUG_TRACEW(
+ L"Dirstatecache::get: **** old and new have unset entries");
request_thgstatus_update = false;
}
else
{
- TDEBUG_TRACE("Dirstatecache::get: new has unset entries");
+ TDEBUG_TRACEW(L"Dirstatecache::get: new has unset entries");
}
}

@@ -139,7 +139,7 @@
iter->dstate = ds.release();

unsigned delta = tc1 - tc0;
- TDEBUG_TRACE("Dirstatecache::get: read done in " << delta << " ticks, "
+ TDEBUG_TRACEW(L"Dirstatecache::get: read done in " << delta << " ticks, "
<< cache().size() << " repos in cache");

iter->dstate_mtime = stat.mtime;
@@ -147,19 +147,19 @@

if (request_thgstatus_update)
{
- TDEBUG_TRACE("Dirstatecache::get: calling Thgstatus::update");
+ TDEBUG_TRACEW(L"Dirstatecache::get: calling Thgstatus::update");
Thgstatus::update(cwd);
}
else
{
- TDEBUG_TRACE("Dirstatecache::get: omitting Thgstatus::update");
+ TDEBUG_TRACEW(L"Dirstatecache::get: omitting Thgstatus::update");
}

return iter->dstate;
}


-void Dirstatecache::invalidate(const std::string& hgroot)
+void Dirstatecache::invalidate(const std::wstring& hgroot)
{
typedef std::list<E>::iterator Iter;

@@ -173,7 +173,7 @@
delete i->dstate;
i->dstate = 0;
cache().erase(i);
- TDEBUG_TRACE("Dirstatecache::invalidate(" << hgroot << ")");
+ TDEBUG_TRACEW(L"Dirstatecache::invalidate(" << hgroot << ")");
break;
}
}
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Dirstatecache.h
--- a/win32/shellext/Dirstatecache.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Dirstatecache.h Tue Aug 17 16:15:06 2010 +0900
@@ -31,7 +31,7 @@
__int64 dstate_mtime;
__int64 dstate_size;

- std::string hgroot;
+ std::wstring hgroot;
unsigned tickcount;
bool unset;

@@ -48,8 +48,8 @@

public:
static Dirstate* get(
- const std::string& hgroot, const std::string& cwd, bool& unset);
- static void invalidate(const std::string& hgroot);
+ const std::wstring& hgroot, const std::wstring& cwd, bool& unset);
+ static void invalidate(const std::wstring& hgroot);
};

#endif
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/IconBitmapUtils.cpp
--- a/win32/shellext/IconBitmapUtils.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/IconBitmapUtils.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -110,7 +110,7 @@

if (pfnBeginBufferedPaint == NULL || pfnEndBufferedPaint == NULL || pfnGetBufferedPaintBits == NULL)
{
- TDEBUG_TRACE(" IconBitmapUtils::IconToBitmapPARGB32: Theme functions not found, returns NULL");
+ TDEBUG_TRACEW(L" IconBitmapUtils::IconToBitmapPARGB32: Theme functions not found, returns NULL");
return NULL;
}

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/InitStatus.cpp
--- a/win32/shellext/InitStatus.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/InitStatus.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -27,34 +27,34 @@
}


-void InitStatus::add(std::string& s, const char* missing)
+void InitStatus::add(std::wstring& s, const wchar_t* missing)
{
if (!s.empty())
- s += ", ";
+ s += L", ";
s += missing;
}


-std::string InitStatus::check()
+std::wstring InitStatus::check()
{
const InitStatus& self = inst();
- std::string missing;
+ std::wstring missing;

if (self.unchanged_ == 0)
- add(missing, "unchanged");
+ add(missing, L"unchanged");
if (self.added_ == 0)
- add(missing, "added");
+ add(missing, L"added");
if (self.modified_ == 0)
- add(missing, "modified");
+ add(missing, L"modified");
if (self.notinrepo_ == 0)
- add(missing, "notinrepo");
+ add(missing, L"notinrepo");

if (missing.empty())
- return "";
+ return L"";

- std::string reason = "uninitialized handlers: " + missing;
+ std::wstring reason = L"uninitialized handlers: " + missing;
Thgstatus::error(reason);
- std::string res = "InitStatus: error: " + reason;
- TDEBUG_TRACE("***** " << res);
+ std::wstring res = L"InitStatus: error: " + reason;
+ TDEBUG_TRACEW(L"***** " << res);
return res;
}
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/InitStatus.h
--- a/win32/shellext/InitStatus.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/InitStatus.h Tue Aug 17 16:15:06 2010 +0900
@@ -25,11 +25,11 @@
int notinrepo_;

static InitStatus& inst();
- static std::string check();
+ static std::wstring check();

private:
InitStatus()
: unchanged_(0), added_(0), modified_(0), notinrepo_(0) {}

- static void add(std::string& s, const char* missing);
+ static void add(std::wstring& s, const wchar_t* missing);
};
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Makefile.nmake
--- a/win32/shellext/Makefile.nmake Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Makefile.nmake Tue Aug 17 16:15:06 2010 +0900
@@ -26,6 +26,7 @@

OBJECTS_TERMINATE = Thgstatus.obj \
RegistryConfig.obj \
+ StringUtils.obj \
ThgDebug.obj

LIBS = shlwapi.lib gdiplus.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Msi.lib
@@ -34,7 +35,7 @@

# /MT = statically linked runtime libraries /MD = dynamically linked
# THG_EXTRA_CPPFLAGS is taken from environment (may be undefined)
-CPPFLAGS = /nologo /Ox /W2 /EHsc /MT /DAPPMAIN /DTHG_DEBUG $(THG_EXTRA_CPPFLAGS)
+CPPFLAGS = /D "_UNICODE" /D "UNICODE" /nologo /Ox /W2 /EHsc /MT /DAPPMAIN /DTHG_DEBUG $(THG_EXTRA_CPPFLAGS)
BASE_LDFLAGS = /nologo /INCREMENTAL:NO /MANIFEST $(LIBS)
LDFLAGS_THGSHELL = $(BASE_LDFLAGS) /DLL /DEF:$(DEFFILE)
LDFLAGS_DIRSTATE = $(BASE_LDFLAGS) /SUBSYSTEM:CONSOLE
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/QueryDirstate.cpp
--- a/win32/shellext/QueryDirstate.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/QueryDirstate.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -31,28 +31,28 @@
class QueryState
{
public:
- std::string path;
+ std::wstring path;
bool isdir;
- std::string basedir;
- std::string hgroot;
+ std::wstring basedir;
+ std::wstring hgroot;

- char status;
+ wchar_t status;
unsigned tickcount;

QueryState(): isdir(false), status('0'), tickcount(0) {}
};


-bool hasHgDir(char cls, const std::string& path, unsigned& ticks)
+bool hasHgDir(wchar_t cls, const std::wstring& path, unsigned& ticks)
{
ticks = 0;

bool res = false;

- if (path.empty() || path == "\\")
+ if (path.empty() || path == L"\\")
return res;

- const std::string p = path + "\\.hg";
+ const std::wstring p = path + L"\\.hg";

if (::PathIsUNCServerShare(p.c_str()))
return res;
@@ -66,9 +66,9 @@
if (ticks > 5 /* ms */)
{
// trace slower PathIsDirectory calls (untypical on local discs)
- TDEBUG_TRACE(
- "[" << cls << "] hasHgDir: PathIsDirectory(\"" << p << "\")" <<
- " -> " << res << ", in " << ticks << " ticks"
+ TDEBUG_TRACEW(
+ L"[" << cls << L"] hasHgDir: PathIsDirectory(\"" << p << L"\")" <<
+ L" -> " << res << L", in " << ticks << L" ticks"
);
}

@@ -76,14 +76,14 @@
}


-int findHgRoot(char cls, QueryState& cur, QueryState& last, bool outdated)
+int findHgRoot(wchar_t cls, QueryState& cur, QueryState& last, bool outdated)
{
- std::string dp = "["; dp += cls; dp += "] findHgRoot";
+ std::wstring dp = L"["; dp += cls; dp += L"] findHgRoot";

{
- std::string p = cur.path;
- p.push_back('\\');
- if (p.find("\\.hg\\") != std::string::npos)
+ std::wstring p = cur.path;
+ p.push_back(L'\\');
+ if (p.find(L"\\.hg\\") != std::wstring::npos)
{
// ignore files and dirs named '.hg'
last = cur;
@@ -93,7 +93,7 @@

if (!outdated && !last.hgroot.empty()
&& cur.path.size() >= last.hgroot.size()
- && StartsWith(cur.path, last.hgroot + "\\"))
+ && StartsWith(cur.path, last.hgroot + L"\\"))
{
cur.hgroot = last.hgroot;
return 1;
@@ -117,7 +117,7 @@
if (has_hg)
{
cur.hgroot = cur.path;
- TDEBUG_TRACE(dp << "(" << cur.path << "): hgroot = cur.path");
+ TDEBUG_TRACEW(dp << L"(" << cur.path << L"): hgroot = cur.path");
return 1;
}
}
@@ -130,12 +130,12 @@
return 1;
}

- for (std::string p = cur.basedir;;)
+ for (std::wstring p = cur.basedir;;)
{
bool has_hg = hasHgDir(cls, p, ticks);
if (ticks > 5000 /* ms */)
{
- const std::string reason = "ignoring slow \"" + p + "\"";
+ const std::wstring reason = L"ignoring slow \"" + p + L"\"";
Thgstatus::error(reason);
file_access_is_unacceptably_slow = true;
goto exit;
@@ -144,13 +144,13 @@
if (has_hg)
{
cur.hgroot = p;
- TDEBUG_TRACE(
- dp << "(" << cur.path << "): hgroot = '" << cur.hgroot
- << "' (found repo)"
+ TDEBUG_TRACEW(
+ dp << L"(" << cur.path << L"): hgroot = '" << cur.hgroot
+ << L"' (found repo)"
);
return 1;
}
- std::string p2 = DirName(p);
+ std::wstring p2 = DirName(p);
if (p2.size() == p.size())
break;
p.swap(p2);
@@ -159,13 +159,13 @@
exit:
if (file_access_is_unacceptably_slow)
{
- TDEBUG_TRACE(
- "******" << dp << "(" << cur.path << "): ignored, "
- << "call took too long (" << ticks << " ticks)");
+ TDEBUG_TRACEW(
+ L"******" << dp << L"(" << cur.path << L"): ignored, "
+ << L"call took too long (" << ticks << L" ticks)");
}
else
{
- TDEBUG_TRACE(dp << "(" << cur.path << "): NO repo found");
+ TDEBUG_TRACEW(dp << L"(" << cur.path << L"): NO repo found");
}
last = cur;
return 0;
@@ -173,9 +173,9 @@


int get_relpath(
- const std::string& hgroot,
- const std::string& path,
- std::string& res
+ const std::wstring& hgroot,
+ const std::wstring& path,
+ std::wstring& res
)
{
size_t offset = hgroot.size();
@@ -185,10 +185,10 @@
if (offset > path.size())
return 0;

- if (path[offset] == '\\')
+ if (path[offset] == L'\\')
offset++;
-
- const char* relpathptr = path.c_str() + offset;
+
+ const wchar_t* relpathptr = path.c_str() + offset;

res = relpathptr;
return 1;
@@ -197,12 +197,12 @@

int HgQueryDirstate(
const char cls,
- const std::string& path,
- const char& filterStatus,
+ const std::wstring& path,
+ const wchar_t& filterStatus,
char& outStatus
)
{
- std::string dp = "["; dp += cls; dp += "] HgQueryDirstate: ";
+ std::wstring dp = L"["; dp += cls; dp += L"] HgQueryDirstate: ";

static QueryState last;

@@ -241,16 +241,16 @@
return 0;
}

- if (path[offset] == '\\')
+ if (path[offset] == L'\\')
offset++;
- const char* relpathptr = path.c_str() + offset;
+ const wchar_t* relpathptr = path.c_str() + offset;

- std::string relpath = relpathptr;
+ std::wstring relpath = relpathptr;

for (size_t i = 0; i < relpath.size(); ++i)
{
- if (relpath[i] == '\\')
- relpath[i] = '/';
+ if (relpath[i] == L'\\')
+ relpath[i] = L'/';
}

DirectoryStatus* pdirsta = DirectoryStatus::get(cur.hgroot, cur.basedir);
@@ -274,9 +274,9 @@
Dirstate* pds = Dirstatecache::get(cur.hgroot, cur.basedir, unset);
if (!pds)
{
- TDEBUG_TRACE(
- dp << "Dirstatecache::get(" << cur.hgroot
- << ") returns no Dirstate"
+ TDEBUG_TRACEW(
+ dp << L"Dirstatecache::get(" << cur.hgroot
+ << L") returns no Dirstate"
);
last = cur;
return 0;
@@ -285,7 +285,7 @@
Winstat stat;
if (0 != stat.lstat(path.c_str()))
{
- TDEBUG_TRACE(dp << "lstat(" << path << ") failed");
+ TDEBUG_TRACEW(dp << L"lstat(" << path << L") failed");
last = cur;
return 0;
}
@@ -328,19 +328,19 @@

if (outStatus == 'M')
{
- std::string relbase;
+ std::wstring relbase;
if (pdirsta && get_relpath(cur.hgroot, cur.basedir, relbase))
{
- TDEBUG_TRACE(dp << "relbase = '" << relbase << "'");
+ TDEBUG_TRACEW(dp << L"relbase = '" << relbase << L"'");

- char basedir_status = pdirsta->status(relbase);
- TDEBUG_TRACE(dp << "basedir_status = " << basedir_status);
+ wchar_t basedir_status = pdirsta->status(relbase);
+ TDEBUG_TRACEW(dp << L"basedir_status = " << basedir_status);

- if (basedir_status != 'M')
+ if (basedir_status != L'M')
update = true;
- }
+ }
}
- else if (outStatus == 'P')
+ else if (outStatus == L'P')
{
static unsigned lasttickcount;

@@ -353,19 +353,19 @@
lasttickcount = tc;
}

- TDEBUG_TRACE(dp << "outStatus is 'P'");
+ TDEBUG_TRACEW(dp << L"outStatus is 'P'");
}

if (update)
{
- TDEBUG_TRACE(dp << "calling Thgstatus::update");
+ TDEBUG_TRACEW(dp << L"calling Thgstatus::update");
Thgstatus::update(path);
}

exit:
cur.status = outStatus;
- if (outStatus == 'P')
- outStatus = 'M';
+ if (outStatus == L'P')
+ outStatus = L'M';
cur.tickcount = ::GetTickCount();
last = cur;
return 1;
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/QueryDirstate.h
--- a/win32/shellext/QueryDirstate.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/QueryDirstate.h Tue Aug 17 16:15:06 2010 +0900
@@ -5,8 +5,8 @@

int HgQueryDirstate(
const char myClass,
- const std::string& path,
- const char& filterStatus,
+ const std::wstring& path,
+ const wchar_t& filterStatus,
char& outStatus
);

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/RegistryConfig.cpp
--- a/win32/shellext/RegistryConfig.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/RegistryConfig.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -1,27 +1,27 @@
#include "stdafx.h"
#include "RegistryConfig.h"

-int GetRegistryConfig(const std::string& name, std::string& res)
+int GetRegistryConfig(const std::wstring& name, std::wstring& res)
{
- const char* const subkey = "Software\\TortoiseHg";
+ const wchar_t* const subkey = L"Software\\TortoiseHg";

HKEY hkey = 0;
- LONG rv = RegOpenKeyExA(
+ LONG rv = RegOpenKeyEx(
HKEY_CURRENT_USER, subkey, 0, KEY_READ, &hkey);

if (rv != ERROR_SUCCESS || hkey == 0)
return 0;

- BYTE Data[MAX_PATH] = "";
+ BYTE Data[MAX_PATH * 2] = {0};
DWORD cbData = MAX_PATH * sizeof(BYTE);

- rv = RegQueryValueExA(
+ rv = RegQueryValueEx(
hkey, name.c_str(), 0, 0, Data, &cbData);

int ret = 0;
if (rv == ERROR_SUCCESS)
{
- res = reinterpret_cast<const char*>(&Data);
+ res = reinterpret_cast<const wchar_t*>(&Data);
ret = 1;
}

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/RegistryConfig.h
--- a/win32/shellext/RegistryConfig.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/RegistryConfig.h Tue Aug 17 16:15:06 2010 +0900
@@ -3,6 +3,6 @@

#include <string>

-int GetRegistryConfig(const std::string& name, std::string& res);
+int GetRegistryConfig(const std::wstring& name, std::wstring& res);

#endif
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/ShellExt.cpp
--- a/win32/shellext/ShellExt.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/ShellExt.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -43,14 +43,14 @@
{
if (dwReason == DLL_PROCESS_ATTACH)
{
- TDEBUG_TRACE("DllMain: DLL_PROCESS_ATTACH");
+ TDEBUG_TRACEW(L"DllMain: DLL_PROCESS_ATTACH");
g_hmodThisDll = hInstance;
::InitializeCriticalSection(&g_critical_section);
_LoadResources();
}
else if (dwReason == DLL_PROCESS_DETACH)
{
- TDEBUG_TRACE("DllMain: DLL_PROCESS_ATTACH");
+ TDEBUG_TRACEW(L"DllMain: DLL_PROCESS_ATTACH");
::DeleteCriticalSection(&g_critical_section);
_UnloadResources();
}
@@ -61,7 +61,7 @@

STDAPI DllCanUnloadNow(void)
{
- TDEBUG_TRACE("DllCanUnloadNow");
+ TDEBUG_TRACEW(L"DllCanUnloadNow");
return (g_cRefThisDll == 0 ? S_OK : S_FALSE);
}

@@ -76,11 +76,11 @@
::CoTaskMemFree(ptr);
}

- TDEBUG_TRACEW("DllGetClassObject clsid = " << clsid);
+ TDEBUG_TRACEW(L"DllGetClassObject clsid = " << clsid);

if (ppvOut == 0)
{
- TDEBUG_TRACE("**** DllGetClassObject: error: ppvOut is 0");
+ TDEBUG_TRACEW(L"**** DllGetClassObject: error: ppvOut is 0");
return E_POINTER;
}

@@ -92,34 +92,34 @@
if (clsid == CLSID_TortoiseHgCmenu)
{
FactCmenu *pcf = new FactCmenu(0);
- TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgCmenu");
+ TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgCmenu");
return pcf->QueryInterface(riid, ppvOut);
}
else if (clsid == CLSID_TortoiseHgNormal)
{
FactOvl *pcf = new FactOvl('C'); // clean
- TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgNormal");
+ TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgNormal");
++InitStatus::inst().unchanged_;
return pcf->QueryInterface(riid, ppvOut);
}
else if (clsid == CLSID_TortoiseHgAdded)
{
FactOvl *pcf = new FactOvl('A'); // added
- TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgAdded");
+ TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgAdded");
++InitStatus::inst().added_;
return pcf->QueryInterface(riid, ppvOut);
}
else if (clsid == CLSID_TortoiseHgModified)
{
FactOvl *pcf = new FactOvl('M'); // modified
- TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgModified");
+ TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgModified");
++InitStatus::inst().modified_;
return pcf->QueryInterface(riid, ppvOut);
}
else if (clsid == CLSID_TortoiseHgUnversioned)
{
FactOvl *pcf = new FactOvl('?'); // not in repo
- TDEBUG_TRACE("DllGetClassObject clsname = " << "CLSID_TortoiseHgUnversioned");
+ TDEBUG_TRACEW(L"DllGetClassObject clsname = " << L"CLSID_TortoiseHgUnversioned");
++InitStatus::inst().notinrepo_;
return pcf->QueryInterface(riid, ppvOut);
}
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/StringUtils.cpp
--- a/win32/shellext/StringUtils.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/StringUtils.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -15,15 +15,16 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

+#include "stdafx.h"
#include "StringUtils.h"

#include <vector>


// Quotes a string
-std::string Quote(const std::string& str)
+std::wstring Quote(const std::wstring& str)
{
- std::string sResult = "\"" + str + "\"";
+ std::wstring sResult = L"\"" + str + L"\"";
return sResult;
}

@@ -37,7 +38,7 @@
NULL, 0, NULL, NULL
);

- std::vector<CHAR> narrow(ret + 1);
+ std::vector<char> narrow(ret + 1);

ret = WideCharToMultiByte(
CodePage, 0, wide.c_str(), static_cast<int>(wide.length()),
@@ -50,13 +51,15 @@


// Convert multibyte string to Unicode string
-std::wstring MultibyteToWide(const std::string& multibyte, UINT CodePage)
+std::wstring MultibyteToWide(const std::string& multibyte, UINT CodePage, DWORD dwFlags)
{
int ret = MultiByteToWideChar(
- CodePage, 0, multibyte.c_str(),
+ CodePage, dwFlags, multibyte.c_str(),
static_cast<int>(multibyte.length()), 0, 0
);

+ if ( ret == 0 ) { return L"" ; }
+
std::vector<wchar_t> wide(ret + 1);

ret = MultiByteToWideChar(
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/StringUtils.h
--- a/win32/shellext/StringUtils.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/StringUtils.h Tue Aug 17 16:15:06 2010 +0900
@@ -22,13 +22,13 @@
#include <windows.h>

// Quotes a string
-std::string Quote(const std::string& str);
+std::wstring Quote(const std::wstring& str);

// Convert Unicode string to multibyte string
std::string WideToMultibyte(const std::wstring& wide, UINT CodePage = CP_ACP);

// Convert multibyte string to Unicode string
-std::wstring MultibyteToWide(const std::string& multibyte, UINT CodePage = CP_ACP);
+std::wstring MultibyteToWide(const std::string& multibyte, UINT CodePage, DWORD dwFlags);


#endif
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/ThgDebug.cpp
--- a/win32/shellext/ThgDebug.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/ThgDebug.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -6,13 +6,14 @@
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.

+#include "stdafx.h"
#include "ThgDebug.h"
#include "RegistryConfig.h"

bool ThgDebug::regDebugShellExt()
{
- std::string val;
- return GetRegistryConfig("DebugShellExt", val) != 0 && val == "1";
+ std::wstring val;
+ return GetRegistryConfig(L"DebugShellExt", val) != 0 && val == L"1";
}

bool ThgDebug::enabled()
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/ThgVersion.cpp
--- a/win32/shellext/ThgVersion.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/ThgVersion.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -1,3 +1,4 @@
+#include "stdafx.h"
#include "ThgVersion.h"
#include "parentid.h"

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Thgstatus.cpp
--- a/win32/shellext/Thgstatus.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Thgstatus.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -17,38 +17,59 @@
#include "stdafx.h"

#include "Thgstatus.h"
+#include "StringUtils.h"

#include <vector>


-std::string GetPipeName()
+std::wstring GetPipeName()
{
DWORD size = 260;
- std::vector<char> buf(size);
- if (!::GetUserNameA(&buf[0], &size))
- return "";
- std::string res = "\\\\.\\pipe\\TortoiseHgRpcServer-bc0c27107423-";
+ std::vector<wchar_t> buf(size);
+ if (!::GetUserName(&buf[0], &size))
+ return L"";
+ std::wstring res = L"\\\\.\\pipe\\TortoiseHgRpcServer-bc0c27107423-";
res += &buf[0];
return res;
}

+#define PIPE_W 0

-int Thgstatus::SendRequest(const std::string& request)
+int Thgstatus::SendRequest(const std::wstring& request)
{
- static const std::string pname = GetPipeName();
+ static const std::wstring pname = GetPipeName();
+ static const std::string pname_a = WideToMultibyte(pname,CP_ACP);
+ std::string request_a;

if (pname.empty())
+ {
return 0;
+ }
+
+ if (! PIPE_W)
+ {
+ request_a = WideToMultibyte(request,CP_ACP);
+ }

BOOL fSuccess;
DWORD cbRead;

- TDEBUG_TRACE("Thgstatus::update: sending '" << request << "' to " << pname);
+ TDEBUG_TRACEW(L"Thgstatus::update: sending '" << request << "' to " << pname);

- fSuccess = ::CallNamedPipeA(
- pname.c_str(), (void*)request.c_str(), request.size(), 0, 0, &cbRead,
- NMPWAIT_NOWAIT
- );
+ if (PIPE_W)
+ {
+ fSuccess = ::CallNamedPipe(
+ pname.c_str(), (void*)request.c_str(), sizeof(wchar_t) * request.size(), 0, 0, &cbRead,
+ NMPWAIT_NOWAIT
+ );
+ }
+ else
+ {
+ fSuccess = ::CallNamedPipeA(
+ pname_a.c_str(), (void*)request_a.c_str(), request_a.size(), 0, 0, &cbRead,
+ NMPWAIT_NOWAIT
+ );
+ }

DWORD err = GetLastError();
if (fSuccess || err == ERROR_MORE_DATA || err == ERROR_PIPE_NOT_CONNECTED)
@@ -57,14 +78,14 @@
}
else if (err == ERROR_PIPE_BUSY)
{
- TDEBUG_TRACE("Thgstatus::update: CallNamedPipeA failed. "
- "ERROR_PIPE_BUSY");
+ TDEBUG_TRACEW(L"Thgstatus::update: CallNamedPipe failed. "
+ L"ERROR_PIPE_BUSY");
return -1;
}
else
{
- TDEBUG_TRACE("Thgstatus::update: CallNamedPipeA failed ("
- << err << ")");
+ TDEBUG_TRACEW(L"Thgstatus::update: CallNamedPipe failed ("
+ << err << L")");
return -1;
}
}
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Thgstatus.h
--- a/win32/shellext/Thgstatus.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Thgstatus.h Tue Aug 17 16:15:06 2010 +0900
@@ -21,20 +21,20 @@

class Thgstatus
{
- static int SendRequest(const std::string& request);
+ static int SendRequest(const std::wstring& request);

public:
- static int update(const std::string& path) {
- return SendRequest("update|" + path);
+ static int update(const std::wstring& path) {
+ return SendRequest(L"update|" + path);
}
- static int remove(const std::string& path) {
- return SendRequest("remove|" + path);
+ static int remove(const std::wstring& path) {
+ return SendRequest(L"remove|" + path);
}
- static int error(const std::string& text) {
- return SendRequest("error|" + text);
+ static int error(const std::wstring& text) {
+ return SendRequest(L"error|" + text);
}
static int terminate() {
- return SendRequest("terminate|");
+ return SendRequest(L"terminate|");
}
};

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/TortoiseIconBitmap.cpp
--- a/win32/shellext/TortoiseIconBitmap.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/TortoiseIconBitmap.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -6,10 +6,10 @@
#include "IconBitmapUtils.h"


-HBITMAP GetTortoiseIconBitmap(const std::string& iconname)
+HBITMAP GetTortoiseIconBitmap(const std::wstring& iconname)
{
IconBitmapUtils bmpUtils;
- typedef std::map<std::string, HBITMAP> BitmapCacheT;
+ typedef std::map<std::wstring, HBITMAP> BitmapCacheT;
static BitmapCacheT bmpcache_;

BitmapCacheT::const_iterator i = bmpcache_.find(iconname);
@@ -18,7 +18,7 @@

if (bmpcache_.size() > 200)
{
- TDEBUG_TRACE("**** GetTortoiseIconBitmap: error: too many bitmaps in cache");
+ TDEBUG_TRACEW(L"**** GetTortoiseIconBitmap: error: too many bitmaps in cache");
return 0;
}

@@ -29,15 +29,15 @@
HBITMAP hBmp = bmpUtils.IconToBitmapPARGB32(hIcon);
if (!hBmp)
{
- TDEBUG_TRACE("**** GetTortoiseIconBitmap: error: something wrong in bmpUtils.ConvertToPARGB32(hIcon)");
+ TDEBUG_TRACEW(L"**** GetTortoiseIconBitmap: error: something wrong in bmpUtils.ConvertToPARGB32(hIcon)");
return 0;
}

bmpcache_[iconname] = hBmp;

- TDEBUG_TRACE(
- "GetTortoiseIconBitmap: added '" << iconname << "' to bmpcache_"
- " (" << bmpcache_.size() << " bitmaps in cache)"
+ TDEBUG_TRACEW(
+ L"GetTortoiseIconBitmap: added '" << iconname << L"' to bmpcache_"
+ L" (" << bmpcache_.size() << L" bitmaps in cache)"
);

return hBmp;
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/TortoiseIconBitmap.h
--- a/win32/shellext/TortoiseIconBitmap.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/TortoiseIconBitmap.h Tue Aug 17 16:15:06 2010 +0900
@@ -4,6 +4,6 @@
#include <windows.h>
#include <string>

-HBITMAP GetTortoiseIconBitmap(const std::string& iconname);
+HBITMAP GetTortoiseIconBitmap(const std::wstring& iconname);

#endif
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/TortoiseUtils.cpp
--- a/win32/shellext/TortoiseUtils.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/TortoiseUtils.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -10,38 +10,15 @@

#include "shlwapi.h"

-
-LPWSTR hf_mbtowc(LPWSTR lpw, LPCSTR lpa, int nChars)
+std::wstring GetTHgProgRoot()
{
- assert(lpa != NULL);
- assert(lpw != NULL);
-
- lpw[0] = '\0';
- MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars);
- return lpw;
-}
-
-
-LPSTR hf_wctomb(LPSTR lpa, LPCWSTR lpw, int nChars)
-{
- assert(lpw != NULL);
- assert(lpa != NULL);
-
- lpa[0] = '\0';
- WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL);
- return lpa;
-}
-
-
-std::string GetTHgProgRoot()
-{
- LPCSTR regname = "Software\\TortoiseHg";
+ LPCWSTR regname = L"Software\\TortoiseHg";
HKEY key = HKEY_LOCAL_MACHINE;
- TCHAR lpszValue[MAX_PATH] = "";
+ TCHAR lpszValue[MAX_PATH] = L"";
LONG lpcbLonger = MAX_PATH * sizeof(TCHAR);

if (RegQueryValue(key, regname, lpszValue, &lpcbLonger) != ERROR_SUCCESS)
- return "";
+ return L"";

return lpszValue;
}
@@ -51,32 +28,32 @@
// Note: if the command is a batch file and the [full] path to the
// batch contains spaces, the path must be double-quoted.
// (see http://www.encocoservices.com/createprocess.html)
-bool LaunchCommand(const std::string& command, const std::string& cwd)
+bool LaunchCommand(const std::wstring& command, const std::wstring& cwd)
{
- TDEBUG_TRACE("LaunchCommand: " << command);
- TDEBUG_TRACE("LaunchCommand: in " << cwd);
+ TDEBUG_TRACEW(L"LaunchCommand: " << command);
+ TDEBUG_TRACEW(L"LaunchCommand: in " << cwd);
PROCESS_INFORMATION processInfo;
memset(&processInfo, 0, sizeof(processInfo));

- STARTUPINFOA startupInfo;
+ STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(startupInfo));

- int res = CreateProcessA(
+ int res = CreateProcess(
NULL, // No module name, use command line
- const_cast<char*>(command.c_str()),
+ const_cast<wchar_t*>(command.c_str()),
NULL, // Process handle not inherited
NULL, // Thread handle not inherited
FALSE,
CREATE_NO_WINDOW,
NULL, // use parent's environment
- const_cast<char*>(cwd.c_str()),
+ const_cast<wchar_t*>(cwd.c_str()),
&startupInfo,
&processInfo
);

if (res == 0)
{
- TDEBUG_TRACE("LaunchCommand: failed to launch");
+ TDEBUG_TRACEW(L"LaunchCommand: failed to launch");
return false;
}

@@ -85,14 +62,14 @@
return true;
}

-std::string GetTemporaryFile(LPCTSTR prefix)
+std::wstring GetTemporaryFile(LPCWSTR prefix)
{
- char tempDir[MAX_PATH + 1];
- char tempFile[MAX_PATH + 1];
+ wchar_t tempDir[MAX_PATH + 1];
+ wchar_t tempFile[MAX_PATH + 1];

if (GetTempPath(MAX_PATH, tempDir) == 0)
{
- TDEBUG_TRACE("GetTemporaryFile: Failed to find temporary path");
+ TDEBUG_TRACEW(L"GetTemporaryFile: Failed to find temporary path");
}
else if (GetTempFileName(tempDir, prefix, 0, tempFile) != 0)
{
@@ -100,57 +77,57 @@
}
else
{
- TDEBUG_TRACE("GetTemporaryFile: Failed to get temporary file");
+ TDEBUG_TRACEW(L"GetTemporaryFile: Failed to get temporary file");
}

- return "";
+ return L"";
}


-bool IsDirectory(const std::string& filename)
+bool IsDirectory(const std::wstring& filename)
{
return ::PathIsDirectory(filename.c_str()) != 0;
}


-std::string DirName(const std::string& filename)
+std::wstring DirName(const std::wstring& filename)
{
if (filename.empty())
return filename;
- std::string::size_type pos = filename.find_last_of("\\");
- if (pos == std::string::npos)
- return "";
- std::string myfilename = filename.substr(0, pos);
- if (myfilename.size() > 0 && myfilename[myfilename.size()-1] == ':')
- myfilename.push_back('\\');
+ std::wstring::size_type pos = filename.find_last_of(L"\\");
+ if (pos == std::wstring::npos)
+ return L"";
+ std::wstring myfilename = filename.substr(0, pos);
+ if (myfilename.size() > 0 && myfilename[myfilename.size()-1] == L':')
+ myfilename.push_back(L'\\');
return myfilename;
}

-std::string BaseName(const std::string& filename)
+std::wstring BaseName(const std::wstring& filename)
{
if (filename.empty())
return filename;
- std::string::size_type pos = filename.find_last_of("\\");
- if (pos == std::string::npos)
+ std::wstring::size_type pos = filename.find_last_of(L"\\");
+ if (pos == std::wstring::npos)
return filename;
return filename.substr(pos+1);
}


// not reentrant
-HICON GetTortoiseIcon(const std::string& iconname)
+HICON GetTortoiseIcon(const std::wstring& iconname)
{
- typedef std::map<std::string, HICON> IconCacheT;
+ typedef std::map<std::wstring, HICON> IconCacheT;
static IconCacheT iconcache_;

- std::string thgdir = GetTHgProgRoot();
+ std::wstring thgdir = GetTHgProgRoot();
if (thgdir.empty())
{
- TDEBUG_TRACE("GetTortoiseIcon: THG root is empty");
+ TDEBUG_TRACEW(L"GetTortoiseIcon: THG root is empty");
return 0;
}

- const std::string iconpath = thgdir + "\\icons\\" + iconname;
+ const std::wstring iconpath = thgdir + L"\\icons\\" + iconname;

IconCacheT::const_iterator i = iconcache_.find(iconpath);
if (i != iconcache_.end())
@@ -158,48 +135,48 @@

if (iconcache_.size() > 200)
{
- TDEBUG_TRACE("**** GetTortoiseIcon: error: too many icons in cache");
+ TDEBUG_TRACEW(L"**** GetTortoiseIcon: error: too many icons in cache");
return 0;
}

- HICON h = (HICON) LoadImageA(0, iconpath.c_str(), IMAGE_ICON,
+ HICON h = (HICON) LoadImage(0, iconpath.c_str(), IMAGE_ICON,
16, 16, LR_LOADFROMFILE);
if (!h)
{
- TDEBUG_TRACE("GetTortoiseIcon: can't find " + iconpath);
+ TDEBUG_TRACEW(L"GetTortoiseIcon: can't find " + iconpath);
return 0;
}

iconcache_[iconpath] = h;

- TDEBUG_TRACE(
- "GetTortoiseIcon: added '" << iconpath << "' to iconcache_"
- " (" << iconcache_.size() << " icons in cache)"
+ TDEBUG_TRACEW(
+ L"GetTortoiseIcon: added '" << iconpath << L"' to iconcache_"
+ L" (" << iconcache_.size() << L" icons in cache)"
);

return h;
}


-std::string GetHgRepoRoot(const std::string& path)
+std::wstring GetHgRepoRoot(const std::wstring& path)
{
- TDEBUG_TRACE("GetHgRepoRoot('" << path << "')");
+ TDEBUG_TRACEW(L"GetHgRepoRoot('" << path << "')");

- std::string p =
+ std::wstring p =
(::PathIsUNCServerShare(path.c_str()) || IsDirectory(path))
? path : DirName(path);
for (;;)
{
- std::string tdir = p + "\\.hg";
+ std::wstring tdir = p + L"\\.hg";
if (::PathIsUNCServerShare(tdir.c_str()))
{
- TDEBUG_TRACE("GetHgRepoRoot: tdir is UNC share '" << tdir << "'");
+ TDEBUG_TRACEW(L"GetHgRepoRoot: tdir is UNC share '" << tdir << "'");
p.clear();
break;
}
else if (IsDirectory(tdir))
break;
- std::string oldp = p;
+ std::wstring oldp = p;
p = DirName(p);
if (p == oldp)
{
@@ -208,12 +185,12 @@
}
}

- TDEBUG_TRACE("GetHgRepoRoot: returning '" << p << "'");
+ TDEBUG_TRACEW(L"GetHgRepoRoot: returning '" << p << "'");
return p;
}


-bool IsHgRepo(const std::string& path)
+bool IsHgRepo(const std::wstring& path)
{
return !GetHgRepoRoot(path).empty();
}
@@ -221,9 +198,9 @@

// open a file for reading, allowing renames and deletes by other
// processes while we have it open
-FILE* fopenReadRenameAllowed(const char* path)
+FILE* fopenReadRenameAllowed(const wchar_t* path)
{
- HANDLE fh = ::CreateFileA(
+ HANDLE fh = ::CreateFile(
path, GENERIC_READ,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
0, OPEN_EXISTING, 0, 0
@@ -236,7 +213,7 @@
int fd = ::_open_osfhandle((intptr_t)fh, _O_RDONLY);
if (fd == -1)
{
- TDEBUG_TRACE("fopenReadRenameAllowed: _open_osfhandle failed");
+ TDEBUG_TRACEW(L"fopenReadRenameAllowed: _open_osfhandle failed");
::CloseHandle(fh);
return 0;
}
@@ -245,7 +222,7 @@
FILE* f = ::_fdopen(fd, "r");
if (f == 0)
{
- TDEBUG_TRACE("fopenReadRenameAllowed: _fdopen failed");
+ TDEBUG_TRACEW(L"fopenReadRenameAllowed: _fdopen failed");
::_close(fd);
return 0;
}
@@ -255,28 +232,28 @@


// read string value from registry
-int GetRegSZValue(HKEY hkey, const char* name, std::string& res)
-{
- res = "";
-
- if (!hkey)
- return 0;
-
- std::vector<BYTE> Data(300);
- DWORD cbData = Data.size();
-
- LONG rv = ::RegQueryValueExA(hkey, name, 0, 0, &Data[0], &cbData);
-
- if (rv == ERROR_SUCCESS)
- {
- res = reinterpret_cast<char*>(&Data[0]);
- return 1;
- }
-
- TDEBUG_TRACE("GetRegSZValue(" << name << ") failed");
-
- return 0;
-}
+//int GetRegSZValue(HKEY hkey, const char* name, std::string& res)
+//{
+// res = "";
+//
+// if (!hkey)
+// return 0;
+//
+// std::vector<BYTE> Data(300);
+// DWORD cbData = Data.size();
+//
+// LONG rv = ::RegQueryValueExA(hkey, name, 0, 0, &Data[0], &cbData);
+//
+// if (rv == ERROR_SUCCESS)
+// {
+// res = reinterpret_cast<char*>(&Data[0]);
+// return 1;
+// }
+//
+// TDEBUG_TRACEW(L"GetRegSZValue(" << name << ") failed");
+//
+// return 0;
+//}

// read string value from registry, wide version
int GetRegSZValueW(HKEY hkey, const wchar_t* name, std::wstring& res)
@@ -304,7 +281,7 @@


// true if a starts with b
-bool StartsWith(const std::string& a, const std::string& b)
+bool StartsWith(const std::wstring& a, const std::wstring& b)
{
if (a.empty() || b.empty())
return false;
@@ -312,7 +289,7 @@
if (b.size() > a.size())
return false;

- for (std::string::size_type i = 0; i < b.size(); ++i)
+ for (std::wstring::size_type i = 0; i < b.size(); ++i)
{
if (a[i] != b[i])
return false;
@@ -322,10 +299,10 @@
}


-void Tokenize(const std::string& str, std::vector<std::string>& tokens,
- const std::string& delimiters)
+void Tokenize(const std::wstring& str, std::vector<std::wstring>& tokens,
+ const std::wstring& delimiters)
{
- typedef std::string S;
+ typedef std::wstring S;
S::size_type lastpos = str.find_first_not_of(delimiters, 0);
S::size_type pos = str.find_first_of(delimiters, lastpos);

diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/TortoiseUtils.h
--- a/win32/shellext/TortoiseUtils.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/TortoiseUtils.h Tue Aug 17 16:15:06 2010 +0900
@@ -6,27 +6,21 @@
#include <string>
#include <vector>

-#define _MBSTR(wstr) hf_wctomb((LPSTR)alloca(wcslen(wstr) + 1), (wstr),wcslen(wstr) + 1)
-#define _WCSTR(str) hf_mbtowc((LPWSTR)alloca((strlen(str) + 1) * sizeof(WCHAR)),(str),strlen(str) + 1)
-
-LPWSTR hf_mbtowc(LPWSTR lpw, LPCSTR lpa, int nChars);
-LPSTR hf_wctomb(LPSTR lpa, LPCWSTR lpw, int nChars);
-
-std::string GetTHgProgRoot();
-std::string GetTemporaryFile(LPCSTR prefix="THG");
-bool IsDirectory(const std::string&);
-std::string DirName(const std::string&);
-std::string BaseName(const std::string&);
-bool LaunchCommand(const std::string& command, const std::string& cwd);
-HICON GetTortoiseIcon(const std::string & iconname);
-std::string GetHgRepoRoot(const std::string& path);
-bool IsHgRepo(const std::string& path);
-FILE* fopenReadRenameAllowed(const char* path);
-int GetRegSZValue(HKEY hkey, const char* name, std::string& res);
+std::wstring GetTHgProgRoot();
+std::wstring GetTemporaryFile(LPCWSTR prefix=L"THG");
+bool IsDirectory(const std::wstring&);
+std::wstring DirName(const std::wstring&);
+std::wstring BaseName(const std::wstring&);
+bool LaunchCommand(const std::wstring& command, const std::wstring& cwd);
+HICON GetTortoiseIcon(const std::wstring & iconname);
+std::wstring GetHgRepoRoot(const std::wstring& path);
+bool IsHgRepo(const std::wstring& path);
+FILE* fopenReadRenameAllowed(const wchar_t* path);
+//int GetRegSZValue(HKEY hkey, const char* name, std::string& res);
int GetRegSZValueW(HKEY hkey, const wchar_t* name, std::wstring& res);
-bool StartsWith(const std::string& a, const std::string& b);
-void Tokenize(const std::string& str, std::vector<std::string>& tokens,
- const std::string& delimiters = " ");
+bool StartsWith(const std::wstring& a, const std::wstring& b);
+void Tokenize(const std::wstring& str, std::vector<std::wstring>& tokens,
+ const std::wstring& delimiters = std::wstring(L" "));

template <typename C, typename T>
bool contains(const C& c, const T& t)
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Winstat.cpp
--- a/win32/shellext/Winstat.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Winstat.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -19,16 +19,16 @@
#include "Winstat.h"


-int Winstat::lstat(const char* file)
+int Winstat::lstat(const wchar_t* file)
{
const __int64 days_between_epochs = 134774L; /* days between 1.1.1601 and 1.1.1970 */
const __int64 secs_between_epochs = (__int64)days_between_epochs * 86400L;
const __int64 divisor = 10000000L;

- WIN32_FIND_DATAA data;
+ WIN32_FIND_DATA data;
HANDLE hfind;

- hfind = FindFirstFileA(file, &data);
+ hfind = FindFirstFile(file, &data);
if (hfind == INVALID_HANDLE_VALUE)
return -1;
FindClose(hfind);
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Winstat.h
--- a/win32/shellext/Winstat.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Winstat.h Tue Aug 17 16:15:06 2010 +0900
@@ -24,7 +24,7 @@
unsigned mtime;
bool isdir;

- int lstat(const char* file);
+ int lstat(const wchar_t* file);
};

#endif
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Winstat64.cpp
--- a/win32/shellext/Winstat64.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Winstat64.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -18,12 +18,12 @@

#include "Winstat64.h"

-int Winstat64::lstat(const char* path)
+int Winstat64::lstat(const wchar_t* path)
{
- WIN32_FIND_DATAA data;
+ WIN32_FIND_DATA data;
HANDLE hfind;

- hfind = FindFirstFileA(path, &data);
+ hfind = FindFirstFile(path, &data);
if (hfind == INVALID_HANDLE_VALUE)
return -1;
FindClose(hfind);
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/Winstat64.h
--- a/win32/shellext/Winstat64.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/Winstat64.h Tue Aug 17 16:15:06 2010 +0900
@@ -21,7 +21,7 @@
{
__int64 mtime;
__int64 size;
- int lstat(const char* path);
+ int lstat(const wchar_t* path);
};

#endif
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/dirstate.cpp
--- a/win32/shellext/dirstate.cpp Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/dirstate.cpp Tue Aug 17 16:15:06 2010 +0900
@@ -19,16 +19,19 @@

#include "dirstate.h"
#include "TortoiseUtils.h"
+#include "StringUtils.h"

+#define DIRSTATE_UTF8 1
+#define DIRSTATE_DEBUG 0

-std::auto_ptr<Dirstate> Dirstate::read(const std::string& path, bool& unset)
+std::auto_ptr<Dirstate> Dirstate::read(const std::wstring& path, bool& unset)
{
unset = false;

FILE *f = fopenReadRenameAllowed(path.c_str());
if (!f)
{
- TDEBUG_TRACE("Dirstate::read: can't open " << path);
+ TDEBUG_TRACEW(L"Dirstate::read: can't open " << path);
return std::auto_ptr<Dirstate>(0);
}

@@ -38,20 +41,48 @@
fread(&pd->parent2, sizeof(char), HASH_LENGTH, f);

Direntry e;
- std::vector<char> relpath(MAX_PATH + 10, 0);
+ std::vector<char> relpath(MAX_PATH + 10, 0); // UTF-8 if fixutf8 enabled
while (e.read(f, relpath))
{
if (e.unset())
+ {
unset = true;
+ }
+ if (e.state == 'a')
+ {
+ ++pd->num_added_;
+ }

- if (e.state == 'a')
- ++pd->num_added_;
+ std::wstring urelpath = L"" ;
+ if (DIRSTATE_UTF8)
+ {
+ urelpath = MultibyteToWide(&relpath[0], CP_UTF8, MB_ERR_INVALID_CHARS);
+ if (DIRSTATE_DEBUG)
+ {
+ if ( urelpath == L"" )
+ {
+ TDEBUG_TRACEW(L"Dirstate UTF-8 INVALID");
+ }
+ else
+ {
+ TDEBUG_TRACEW(L"Dirstate UTF-8: " << urelpath);
+ }
+ }
+ }
+ if ( urelpath == L"" )
+ {
+ urelpath = MultibyteToWide(&relpath[0], CP_ACP, 0);
+ if (DIRSTATE_DEBUG)
+ {
+ TDEBUG_TRACEW(L"Dirstate CP_ACP: " << urelpath);
+ }
+ }

- pd->add(&relpath[0], e);
+ ::CharLowerBuff(&urelpath[0], urelpath.length());
+ pd->add(urelpath, e);
}

fclose(f);
-
return pd;
}

@@ -74,13 +105,13 @@
void testread()
{
bool unset;
- std::auto_ptr<Dirstate> pd = Dirstate::read(".hg/dirstate", unset);
+ std::auto_ptr<Dirstate> pd = Dirstate::read(L".hg/dirstate", unset);
if (!pd.get()) {
printf("error: could not read .hg/dirstate\n");
return;
}
time_t t;
- char *s;
+ wchar_t *s;
unsigned ix;
printf("parent1: %s\n", revhash_string(pd->parent1));
printf("parent2: %s\n", revhash_string(pd->parent2));
@@ -91,7 +122,7 @@


#ifdef APPMAIN
-int main(int argc, char *argv[])
+int main(int argc, wchar_t *argv[])
{
testread();
return 0;
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/dirstate.h
--- a/win32/shellext/dirstate.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/dirstate.h Tue Aug 17 16:15:06 2010 +0900
@@ -36,11 +36,11 @@
char parent1[HASH_LENGTH];
char parent2[HASH_LENGTH];

- static std::auto_ptr<Dirstate> read(const std::string& path, bool& unset);
+ static std::auto_ptr<Dirstate> read(const std::wstring& path, bool& unset);

Directory& root() { return root_; }

- void add(const std::string& relpath, Direntry& e) {
+ void add(const std::wstring& relpath, Direntry& e) {
root_.add(relpath, e);
++num_entries_;
}
@@ -50,7 +50,7 @@

private:
Dirstate()
- : root_(0, "", ""), num_added_(0), num_entries_(0) {}
+ : root_(0, L"", L""), num_added_(0), num_entries_(0) {}
};

#endif
diff -r 72b581ed7f9e -r 9f13dd64213e win32/shellext/stdafx.h
--- a/win32/shellext/stdafx.h Sun Aug 15 20:14:21 2010 -0700
+++ b/win32/shellext/stdafx.h Tue Aug 17 16:15:06 2010 +0900
@@ -31,15 +31,6 @@
#define THG_PREFIXL L"[THGx86] "
#endif

- // TDEBUG_TRACE() prints debugging messages to Windows' debugger display.
- // The messages can be viewed with Sysinternals DebugView, which may be
- // downloaded from Microsoft TechNet.
- #define TDEBUG_TRACE(s) if (ThgDebug::enabled()) { \
- std::stringstream _the_msg; \
- _the_msg << THG_PREFIX << s; \
- std::string _the_str = _the_msg.str(); \
- OutputDebugStringA(_the_str.c_str()); \
- }
#define TDEBUG_TRACEW(s) if (ThgDebug::enabled()) { \
std::basic_stringstream<wchar_t> _the_msg; \
_the_msg << THG_PREFIXL << s; \

Toshi MARUYAMA

unread,
Aug 17, 2010, 3:22:21 AM8/17/10
to thg...@googlegroups.com
# HG changeset patch
# User Toshi MARUYAMA <marut...@gmail.com>
# Date 1282029306 -32400
# Node ID a18db4999076c5d4511b81db0614c6dcb4824da3
# Parent 9f13dd64213e31e3ef79a5635788faf63837fec0
win32shellext: change option of calling thg from --listfile to --listfileutf8.

diff -r 9f13dd64213e -r a18db4999076 win32/shellext/CShellExtCMenu.cpp
--- a/win32/shellext/CShellExtCMenu.cpp Tue Aug 17 16:15:06 2010 +0900


+++ b/win32/shellext/CShellExtCMenu.cpp Tue Aug 17 16:15:06 2010 +0900

@@ -19,8 +19,13 @@

#define THG_FILENAME L"thg"

+/*
#define LISTFILE_OPT L" --listfile "
#define LISTFILE_CP CP_ACP
+*/
+
+#define LISTFILE_OPT L" --listfileutf8 "
+#define LISTFILE_CP CP_UTF8

struct MenuDescription
{

Adrian Buehlmann

unread,
Aug 17, 2010, 4:22:55 AM8/17/10
to thg...@googlegroups.com
On 17.08.2010 09:22, Toshi MARUYAMA wrote:
> # HG changeset patch
> # User Toshi MARUYAMA <marut...@gmail.com>
> # Date 1282029306 -32400
> # Node ID 9f13dd64213e31e3ef79a5635788faf63837fec0
> # Parent 72b581ed7f9e88b1e484925c2860804bc0fa7e8a
> win32shellext: Unicode porting and context-menu disabled on special folders (e.g. start-menu)

Sticking cmenu and overlay changes in a single giant patch makes things
very difficult to review

What's the point of changing the return value type to wide char?

Is fread now reading wide chars?

> - if (t == '\n')
> + if (t == L'\n')
> break;
> vline.push_back(t);
> if (vline.size() > 1000)
> @@ -99,7 +99,7 @@
> }
> vline.push_back(0);
>
> - std::string line = &vline[0];
> + std::wstring line = &vline[0];
>
> if (line.substr(0, noicons.size()) == noicons)

the thgstatus file now suddenly contains wide chars?

> {
> @@ -112,11 +112,11 @@
>
> e.status_ = line[0];
>
> - std::string path;
> + std::wstring path;
> if (line.size() > 1)
> {
> path = line.c_str() + 1;
> - ::CharLower(const_cast<char*>(path.c_str()));
> + ::CharLower(const_cast<wchar_t*>(path.c_str()));

/me wonders if this is calling the correct function

> }
> path.push_back('/');

...probably would need a L'/' ?

How is this supposed to work if you simply remove that call?

Huh? Commenting out a complete function?

I don't understand this part. How is this supposed to work?

Toshi MARUYAMA

unread,
Aug 17, 2010, 4:38:09 AM8/17/10
to thg...@googlegroups.com
Adrian Buehlmann wrote (2010/08/17 17:22):
> On 17.08.2010 09:22, Toshi MARUYAMA wrote:
>> # HG changeset patch
>> # User Toshi MARUYAMA<marut...@gmail.com>
>> # Date 1282029306 -32400
>> # Node ID 9f13dd64213e31e3ef79a5635788faf63837fec0
>> # Parent 72b581ed7f9e88b1e484925c2860804bc0fa7e8a
>> win32shellext: Unicode porting and context-menu disabled on special folders (e.g. start-menu)
>
> Sticking cmenu and overlay changes in a single giant patch makes things
> very difficult to review
>

Sorry, I made MQ at http://bitbucket.org/marutosi/tortoisehg-shellext-mq .

Adrian Buehlmann

unread,
Aug 17, 2010, 5:05:26 AM8/17/10
to thg...@googlegroups.com

And what about the comments and questions I posted?


Toshi MARUYAMA

unread,
Aug 17, 2010, 5:26:25 AM8/17/10
to TortoiseHg Developers

On 8/17, 6:05 PM JST, Adrian Buehlmann <adr...@cadifra.com> wrote:
> On 17.08.2010 10:38, Toshi MARUYAMA wrote:
>
> > Adrian Buehlmann wrote (2010/08/17 17:22):
> >> On 17.08.2010 09:22, Toshi MARUYAMA wrote:
> >>> # HG changeset patch
> >>> # User Toshi MARUYAMA<marutosi...@gmail.com>
> >>> # Date 1282029306 -32400
> >>> # Node ID 9f13dd64213e31e3ef79a5635788faf63837fec0
> >>> # Parent  72b581ed7f9e88b1e484925c2860804bc0fa7e8a
> >>> win32shellext: Unicode porting and context-menu disabled on special folders (e.g. start-menu)
>
> >> Sticking cmenu and overlay changes in a single giant patch makes things
> >> very difficult to review
>
> > Sorry, I made MQ athttp://bitbucket.org/marutosi/tortoisehg-shellext-mq.
>
> And what about the comments and questions I posted?

Is your post http://groups.google.com/group/thg-dev/browse_thread/thread/91ef2fbf4bf4ac73
?
I am waiting Marco Lizza publishes his job. But there is no progress.
If there is no problem, I will convert only win32 directory and update
thg-winbuild.

Adrian Buehlmann

unread,
Aug 17, 2010, 5:42:30 AM8/17/10
to thg...@googlegroups.com
On 17.08.2010 11:26, Toshi MARUYAMA wrote:
>
> On 8/17, 6:05 PM JST, Adrian Buehlmann <adr...@cadifra.com> wrote:
>> On 17.08.2010 10:38, Toshi MARUYAMA wrote:
>>
>>> Adrian Buehlmann wrote (2010/08/17 17:22):
>>>> On 17.08.2010 09:22, Toshi MARUYAMA wrote:
>>>>> # HG changeset patch
>>>>> # User Toshi MARUYAMA<marutosi...@gmail.com>
>>>>> # Date 1282029306 -32400
>>>>> # Node ID 9f13dd64213e31e3ef79a5635788faf63837fec0
>>>>> # Parent 72b581ed7f9e88b1e484925c2860804bc0fa7e8a
>>>>> win32shellext: Unicode porting and context-menu disabled on special folders (e.g. start-menu)
>>
>>>> Sticking cmenu and overlay changes in a single giant patch makes things
>>>> very difficult to review
>>
>>> Sorry, I made MQ athttp://bitbucket.org/marutosi/tortoisehg-shellext-mq.
>>
>> And what about the comments and questions I posted?
>
> Is your post http://groups.google.com/group/thg-dev/browse_thread/thread/91ef2fbf4bf4ac73
> ?

No. Scroll down in my first reply ("Adrian Buehlmann wrote (2010/08/17
17:22)") to your own email of today.

I posted some inline comments and questions, which you seem to have
overlooked.

> I am waiting Marco Lizza publishes his job. But there is no progress.
> If there is no problem, I will convert only win32 directory and update
> thg-winbuild.

There *are* problems, as I noted in my first reply of today.

Marco Lizza

unread,
Aug 18, 2010, 4:12:07 AM8/18/10
to TortoiseHg Developers
On 17 Ago, 11:42, Adrian Buehlmann <adr...@cadifra.com> wrote:

> > I am waiting Marco Lizza publishes his job. But there is no progress.
> > If there is no problem, I will convert only win32 directory and update
> > thg-winbuild.

> There *are* problems, as I noted in my first reply of today.

I totally agree with Adrian.

Sorry for not writing lately.

I'm currently working on other (personal and professional) projects
I'm involved *but* I'm willing to implement some of the features I
proposed weeks ago in the near future.

However, I reconsidered the need to "refactor" the shellex component
and I'll wait for the next stable version to add *some* of the
features. As soon as I can I'll write to everybody for an opinion on
what to add first.


Marco

Toshi MARUYAMA

unread,
Aug 18, 2010, 9:06:14 AM8/18/10
to thg...@googlegroups.com
>> L"Repository status& changes",
>> + if (SHGetSpecialFolderLocation(NULL, pCSIDL[i],&pIDL) != S_OK)
>> if (HasTortoiseMenu(hMenu, hasthgmenu) == 0&& hasthgmenu)
>> if (myFiles.size() == 1&& root == myFiles[0])
>> if (uFlags& GCS_UNICODE)
>> - static_cast<DWORD>(myFiles[i].size()),&dwWritten, 0
>> + tempfileHandle, str_file.c_str(),
>> + static_cast<DWORD>(str_file.size()),&dwWritten, 0
>> );
>> - WriteFile(tempfileHandle, "\n", 1,&dwWritten, 0);
>> + WriteFile(tempfileHandle, "\n", sizeof(char),&dwWritten, 0);

>> }
>> CloseHandle(tempfileHandle);
>> - hgcmd += " --listfile " + Quote(tempfile);
>> + hgcmd += listfile_opt + Quote(tempfile);
>> }
>>
>> - if (cmd == "thgstatus")
>> + if (cmd == L"thgstatus")
>> {
>> if (Thgstatus::remove(cwd) != 0)
>> {
>> - std::string p = dir + "\\TortoiseHgOverlayServer.exe";
>> + std::wstring p = dir + L"\\TortoiseHgOverlayServer.exe";
>> LaunchCommand(Quote(p), cwd);
>> }
>> InitStatus::check();
>> @@ -884,27 +968,27 @@
>> {
>> TCHAR name[MAX_PATH+1];
>>
>> - TDEBUG_TRACE("CShellExtCMenu::Initialize");
>> + TDEBUG_TRACEW(L"CShellExtCMenu::Initialize");
>>
>> // get installed MSI product id (for debugging purposes for now)
>> #ifdef _M_X64
>> - const char* shellexid = "{59FD2A49-BA62-40CC-B155-D11DB11EE611}";
>> + const wchar_t* shellexid = L"{59FD2A49-BA62-40CC-B155-D11DB11EE611}";
>> #else
>> - const char* shellexid = "{1126CF42-3994-428B-A746-464E1BC680F3}";
>> + const wchar_t* shellexid = L"{1126CF42-3994-428B-A746-464E1BC680F3}";
>> #endif
>> - std::vector<char> product_id(50, 0);
>> - UINT msires = ::MsiGetProductCodeA(shellexid,&product_id[0]);

>> - TDEBUG_TRACE("MSI shellexid: "<< shellexid);
>> - TDEBUG_TRACE("MSI msires: "<< msires);
>> - TDEBUG_TRACE("MSI installed product id: "<< &product_id[0]);
>> + std::vector<wchar_t> product_id(50, 0);
>> + UINT msires = ::MsiGetProductCode(shellexid,&product_id[0]);
>> - if (myFolder.empty()&& myFiles.empty()) {
>> - if (GetRegistryConfig("EnableOverlays", cval) != 0&& cval == "0")
>> + std::wstring cval;
>> + if (GetRegistryConfig(L"EnableOverlays", cval) != 0&& cval == L"0")

>> return S_FALSE;
>>
>> // This overlay handler processes all filenames in lowercase, so that a path
>> @@ -43,13 +43,13 @@
>> std::wstring lowerpath(pwszPath);
>> ::CharLowerW(const_cast<wchar_t*>(lowerpath.c_str()));
>>
>> - std::string path = WideToMultibyte(lowerpath.c_str());
>> + std::wstring path = lowerpath; //WideToMultibyte(lowerpath.c_str());
>>
>> - if (GetRegistryConfig("LocalDisksOnly", cval) != 0&& cval != "0"
>> + if (GetRegistryConfig(L"LocalDisksOnly", cval) != 0&& cval != L"0"

== 1 ==

>
> What's the point of changing the return value type to wide char?
>

DirectoryStatus::status is wchar_t at
http://bitbucket.org/marutosi/tortoisehg/src/d3160c05d2b4/win32/shellext/DirectoryStatus.h#cl-25

And I fixed and pushed adding L prefix at
http://bitbucket.org/marutosi/tortoisehg/changeset/d3160c05d2b4 .

== 2 ==


>
> Is fread now reading wide chars?
>

Sorry, I checked .hg/thgstatus is written in CP_ACP or utf-8.
I will fix it.

>> - if (t == '\n')
>> + if (t == L'\n')
>> break;
>> vline.push_back(t);
>> if (vline.size()> 1000)
>> @@ -99,7 +99,7 @@
>> }
>> vline.push_back(0);
>>

>> - std::string line =&vline[0];
>> + std::wstring line =&vline[0];


>>
>> if (line.substr(0, noicons.size()) == noicons)

== 3 ==

>
> the thgstatus file now suddenly contains wide chars?
>

Sorry, I checked .hg/thgstatus is written in CP_ACP or utf-8.
I will fix it.

>> {
>> @@ -112,11 +112,11 @@
>>
>> e.status_ = line[0];
>>
>> - std::string path;
>> + std::wstring path;
>> if (line.size()> 1)
>> {
>> path = line.c_str() + 1;
>> - ::CharLower(const_cast<char*>(path.c_str()));
>> + ::CharLower(const_cast<wchar_t*>(path.c_str()));


== 4 ==

>
> /me wonders if this is calling the correct function
>

I will fix it.


>> }
>> path.push_back('/');


== 5 ==

>
> ...probably would need a L'/' ?
>

I will fix it.

== 6 ==

>
> How is this supposed to work if you simply remove that call?
>

.hg/dirstate written in CP_ACP or utf-8 with fixutf8 extension.
utf-8 is broken with ::CharLowerBuff().
So I call after convert to widechar at
http://bitbucket.org/marutosi/tortoisehg/src/638edeb2a719/win32/shellext/dirstate.cpp#cl-80 .

>> if (!outdated&& !last.hgroot.empty()


>> && cur.path.size()>= last.hgroot.size()
>> -&& StartsWith(cur.path, last.hgroot + "\\"))

>> +&& StartsWith(cur.path, last.hgroot + L"\\"))

>> if (pdirsta&& get_relpath(cur.hgroot, cur.basedir, relbase))

>> - return GetRegistryConfig("DebugShellExt", val) != 0&& val == "1";
>> + std::wstring val;
>> + return GetRegistryConfig(L"DebugShellExt", val) != 0&& val == L"1";

>> res +=&buf[0];

>> if (RegQueryValue(key, regname, lpszValue,&lpcbLonger) != ERROR_SUCCESS)

>> - if (myfilename.size()> 0&& myfilename[myfilename.size()-1] == ':')


>> - myfilename.push_back('\\');
>> + std::wstring::size_type pos = filename.find_last_of(L"\\");
>> + if (pos == std::wstring::npos)
>> + return L"";
>> + std::wstring myfilename = filename.substr(0, pos);

>> + if (myfilename.size()> 0&& myfilename[myfilename.size()-1] == L':')

== 7 ==

>
> Huh? Commenting out a complete function?
>

Tinyfish replaces all GetRegSZValue to GetRegSZValueW.
So I remove this comment out at
http://bitbucket.org/marutosi/tortoisehg/changeset/638edeb2a719 .

>> -HICON GetTortoiseIcon(const std::string& iconname);


>> -std::string GetHgRepoRoot(const std::string& path);
>> -bool IsHgRepo(const std::string& path);
>> -FILE* fopenReadRenameAllowed(const char* path);
>> -int GetRegSZValue(HKEY hkey, const char* name, std::string& res);
>> +std::wstring GetTHgProgRoot();
>> +std::wstring GetTemporaryFile(LPCWSTR prefix=L"THG");
>> +bool IsDirectory(const std::wstring&);
>> +std::wstring DirName(const std::wstring&);
>> +std::wstring BaseName(const std::wstring&);
>> +bool LaunchCommand(const std::wstring& command, const std::wstring& cwd);

>> +HICON GetTortoiseIcon(const std::wstring& iconname);

== 8 ==

>
> I don't understand this part. How is this supposed to work?
>

At http://bitbucket.org/marutosi/tortoisehg/src/638edeb2a719/win32/shellext/StringUtils.cpp#cl-54
MultiByteToWideChar() calls.

.hg/dirstate is written in CP_ACP or utf-8.
Firstly, it tries to convert from utf-8 with MB_ERR_INVALID_CHARS flag.
If it is success, path is utf-8.
If it is fail, convert from CP_ACP.

Toshi MARUYAMA

unread,
Aug 20, 2010, 7:57:14 AM8/20/10
to thg...@googlegroups.com
Adrian Buehlmann wrote (2010/08/17 18:42):
>
> I posted some inline comments and questions, which you seem to have
> overlooked.
>
>> I am waiting Marco Lizza publishes his job. But there is no progress.
>> If there is no problem, I will convert only win32 directory and update
>> thg-winbuild.
>
> There *are* problems, as I noted in my first reply of today.

I reflected your comments and questions and finished to fix.

Normal changeset
http://bitbucket.org/marutosi/tortoisehg/changeset/87aab2f57d1b

MQ
http://bitbucket.org/marutosi/tortoisehg-shellext-mq/changeset/e2274765240a

I posted images at http://bitbucket.org/tortoisehg/stable/issue/672 .

These images are fixutf8 extension enabled repository which contains
Japanese and Korean named files and fixutf8 extension disabled repository.

fixutf8 extension enabled
https://bitbucket-assetroot.s3.amazonaws.com/tortoisehg/stable/20100820/672/fixutf8-thg-shellext.png
fixutf8 extension disabled
https://bitbucket-assetroot.s3.amazonaws.com/tortoisehg/stable/20100820/672/CP_ACP-thg-shellext.png

Toshi MARUYAMA

unread,
Aug 20, 2010, 8:08:01 AM8/20/10
to thg...@googlegroups.com
Toshi MARUYAMA wrote (2010/08/20 20:57):
> Adrian Buehlmann wrote (2010/08/17 18:42):
>>
>> I posted some inline comments and questions, which you seem to have
>> overlooked.
>>
>>> I am waiting Marco Lizza publishes his job. But there is no progress.
>>> If there is no problem, I will convert only win32 directory and update
>>> thg-winbuild.
>>
>> There *are* problems, as I noted in my first reply of today.
>
> I reflected your comments and questions and finished to fix.
>
> Normal changeset
> http://bitbucket.org/marutosi/tortoisehg/changeset/87aab2f57d1b
>
> MQ
> http://bitbucket.org/marutosi/tortoisehg-shellext-mq/changeset/e2274765240a
>

I forget to push MQ. Newest MQ is
http://bitbucket.org/marutosi/tortoisehg-shellext-mq/changeset/a156f63b82bb

Reply all
Reply to author
Forward
0 new messages