[Box Backup-dev] COMMIT r381 - in box/chris/win32/vc2005-compile-fixes: bin/bbackupquery lib/win32
boxbackup-dev@fluffy.co.uk
boxbackup-dev@fluffy.co.uk
Sat, 4 Feb 2006 19:51:28 +0000 (GMT)
Author: chris
Date: 2006-02-04 19:51:22 +0000 (Sat, 04 Feb 2006)
New Revision: 381
Modified:
box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/BackupQueries.cpp
box/chris/win32/vc2005-compile-fixes/lib/win32/emu.cpp
box/chris/win32/vc2005-compile-fixes/lib/win32/emu.h
Log:
* lib/win32/emu.cpp, lib/win32/emu.h, bin/bbackupquery/BackupQueries.cpp
- First pass at listing files with wide characters on Win32
Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/BackupQueries.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/BackupQueries.cpp 2006-02-04 15:42:05 UTC (rev 380)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/BackupQueries.cpp 2006-02-04 19:51:22 UTC (rev 381)
@@ -335,7 +335,16 @@
rootDir = FindDirectoryObjectID(args[0], opts[LIST_OPTION_ALLOWOLD], opts[LIST_OPTION_ALLOWDELETED]);
if(rootDir == 0)
{
- printf("Directory %s not found on store\n", args[0].c_str());
+ char* pMsg = "Directory '%s' not found on store\n";
+#ifdef WIN32
+ WCHAR* pMsgBuffer = ConvertUtf8ToMultiByte(pMsg);
+ WCHAR* pNameBuffer = ConvertUtf8ToMultiByte(args[0].c_str());
+ wprintf(pMsgBuffer, pNameBuffer);
+ delete [] pNameBuffer;
+ delete [] pMsgBuffer;
+#else
+ printf(msg, args[0].c_str());
+#endif
return;
}
}
@@ -379,19 +388,16 @@
{
// Display this entry
BackupStoreFilenameClear clear(en->GetName());
- std::string line;
// Object ID?
if(!opts[LIST_OPTION_NOOBJECTID])
{
// add object ID to line
- char oid[32];
-#ifdef WIN32
- sprintf(oid, "%08I64x ", en->GetObjectID());
+#ifdef _MSC_VER
+ printf("%08I64x ", (int64_t)en->GetObjectID());
#else
- sprintf(oid, "%08llx ", en->GetObjectID());
+ printf("%08llx ", (long long)en->GetObjectID());
#endif
- line += oid;
}
// Flags?
@@ -418,58 +424,71 @@
// terminate
*(f++) = ' ';
*(f++) = '\0';
- line += displayflags;
+ printf(displayflags);
+
if(en_flags != 0)
{
- line += "[ERROR: Entry has additional flags set] ";
+ printf("[ERROR: Entry has additional flags set] ");
}
}
if(opts[LIST_OPTION_TIMES])
{
// Show times...
- line += BoxTimeToISO8601String(en->GetModificationTime());
- line += ' ';
+ printf("%s ", BoxTimeToISO8601String(en->GetModificationTime()));
}
if(opts[LIST_OPTION_DISPLAY_HASH])
{
- char hash[64];
-#ifdef WIN32
- ::sprintf(hash, "%016I64x ", en->GetAttributesHash());
+#ifdef _MSC_VER
+ printf("%016I64x ", (int64_t)en->GetAttributesHash());
#else
- ::sprintf(hash, "%016llx ", en->GetAttributesHash());
+ printf("%016llx ", (long long)en->GetAttributesHash());
#endif
- line += hash;
}
if(opts[LIST_OPTION_SIZEINBLOCKS])
{
- char num[32];
-#ifdef WIN32
- sprintf(num, "%05I64d ", en->GetSizeInBlocks());
+#ifdef _MSC_VER
+ printf("%05I64d ", (int64_t)en->GetSizeInBlocks());
#else
- sprintf(num, "%05lld ", en->GetSizeInBlocks());
+ printf("%05lld ", (long long)en->GetSizeInBlocks());
#endif
- line += num;
}
// add name
if(!FirstLevel)
{
- line += rListRoot;
- line += '/';
+#ifdef WIN32
+ pMsgBuffer = ConvertUtf8ToMultiByte("%s");
+ pNameBuffer = ConvertUtf8ToMultiByte(rListRoot);
+ wprintf(pMsgBuffer, pNameBuffer);
+ delete [] pNameBuffer;
+ delete [] pMsgBuffer;
+ printf("/");
+#else
+ printf("%s/", rListRoot.c_str());
+#endif
}
- line += clear.GetClearFilename().c_str();
+#ifdef WIN32
+ {
+ pMsgBuffer = ConvertUtf8ToMultiByte("%s");
+ pNameBuffer = ConvertUtf8ToMultiByte(
+ clear.GetClearFilename().c_str());
+ wprintf(pMsgBuffer, pNameBuffer);
+ delete [] pNameBuffer;
+ delete [] pMsgBuffer;
+ }
+#else
+ printf("%s", clear.GetClearFilename().c_str());
+#endif
+
if(!en->GetName().IsEncrypted())
{
- line += "[FILENAME NOT ENCRYPTED]";
+ printf("[FILENAME NOT ENCRYPTED]");
}
- // print line
- printf("%s\n", line.c_str());
-
// Directory?
if((en->GetFlags() & BackupStoreDirectory::Entry::Flags_Dir) != 0)
{
@@ -1715,8 +1734,3 @@
// Undelete
mrConnection.QueryUndeleteDirectory(dirID);
}
-
-
-
-
-
Modified: box/chris/win32/vc2005-compile-fixes/lib/win32/emu.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/win32/emu.cpp 2006-02-04 15:42:05 UTC (rev 380)
+++ box/chris/win32/vc2005-compile-fixes/lib/win32/emu.cpp 2006-02-04 19:51:22 UTC (rev 381)
@@ -203,131 +203,177 @@
// --------------------------------------------------------------------------
//
// Function
-// Name: openfile
-// Purpose: replacement for any open calls - handles unicode filenames - supplied in utf8
-// Created: 25th October 2004
+// Name: ConvertUtf8ToMultiByte
+// Purpose: Converts a string from UTF-8 to multibyte characters (MBCS).
+// Returns a buffer which MUST be freed by the caller with delete[].
+// In case of fire, logs the error and returns NULL.
+// Created: 4th February 2006
//
// --------------------------------------------------------------------------
-HANDLE openfile(const char *filename, int flags, int mode)
+WCHAR* ConvertUtf8ToMultiByte(const char* pName)
{
- try
- {
- wchar_t *buffer;
- std::string fileN(filename);
+ int strlen = MultiByteToWideChar(
+ CP_UTF8, // source code page
+ 0, // character-type options
+ pName, // string to map
+ strlen(pName), // number of bytes in string
+ NULL, // wide-character buffer
+ 0 // size of buffer - work out
+ // how much space we need
+ );
- std::string tmpStr("\\\\?\\");
- //is the path relative or otherwise
- if ( fileN[1] != ':' )
- {
- //we need to get the current directory
- char wd[PATH_MAX];
- if(::getcwd(wd, PATH_MAX) == 0)
- {
- return NULL;
- }
- tmpStr += wd;
- if (tmpStr[tmpStr.length()] != '\\')
- {
- tmpStr += '\\';
- }
- }
- tmpStr += filename;
+ WCHAR* buffer = new WCHAR[strlen+1];
- int strlen = MultiByteToWideChar(
- CP_UTF8, // code page
- 0, // character-type options
- tmpStr.c_str(), // string to map
- (int)tmpStr.length(), // number of bytes in string
- NULL, // wide-character buffer
- 0 // size of buffer - work out how much space we need
- );
+ if (buffer == NULL)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to convert string to multibyte: '%s': "
+ "out of memory", pName);
+ errno = ENOMEM;
+ return NULL;
+ }
- buffer = new wchar_t[strlen+1];
- if ( buffer == NULL )
- {
- ::syslog(LOG_WARNING, "Failed to allocate buffer "
- "for converting file name: %s",
- tmpStr.c_str());
- return NULL;
- }
+ strlen = MultiByteToWideChar(
+ CP_UTF8, // source code page
+ 0, // character-type options
+ pName, // string to map
+ strlen(pName), // number of bytes in string
+ buffer, // wide-character buffer
+ strlen // size of buffer
+ );
- strlen = MultiByteToWideChar(
- CP_UTF8, // code page
- 0, // character-type options
- tmpStr.c_str(), // string to map
- (int)tmpStr.length(), // number of bytes in string
- buffer, // wide-character buffer
- strlen // size of buffer
- );
+ if (strlen == 0)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to convert string to multibyte: '%s': "
+ "error %i", pName, GetLastError());
+ errno = EACCES;
+ delete [] buffer;
+ return NULL;
+ }
- if ( strlen == 0 )
- {
- ::syslog(LOG_WARNING, "Failed to convert filename "
- "to unicode: %s (error %i)",
- tmpStr.c_str(), GetLastError());
- delete [] buffer;
- return NULL;
- }
+ buffer[strlen] = L'\0';
- buffer[strlen] = L'\0';
+ return buffer;
+}
- //flags could be O_WRONLY | O_CREAT | O_RDONLY
- DWORD createDisposition = OPEN_EXISTING;
- DWORD shareMode = FILE_SHARE_READ;
- DWORD accessRights = FILE_READ_ATTRIBUTES | FILE_LIST_DIRECTORY | FILE_READ_EA;
-
- if (flags & O_WRONLY)
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ConvertPathToAbsoluteUnicode
+// Purpose: Converts relative paths to absolute (with unicode marker)
+// Created: 4th February 2006
+//
+// --------------------------------------------------------------------------
+std::string ConvertPathToAbsoluteUnicode(const char *filename)
+{
+ std::string tmpStr("\\\\?\\");
+
+ // Is the path relative or absolute?
+ // Absolute paths on Windows are always a drive letter
+ // followed by ':'
+
+ if (fileN[1] != ':')
+ {
+ // Must be relative. We need to get the
+ // current directory to make it absolute.
+
+ char wd[PATH_MAX];
+ if (::getcwd(wd, PATH_MAX) == 0)
{
- shareMode = FILE_SHARE_WRITE;
+ ::syslog(LOG_WARNING,
+ "Failed to open '%s': path too long", pName);
+ errno = ENAMETOOLONG;
+ tmpStr = "";
+ return tmpStr;
}
- if (flags & O_RDWR)
+
+ tmpStr += wd;
+ if (tmpStr[tmpStr.length()] != '\\')
{
- shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ tmpStr += '\\';
}
- if (flags & O_CREAT)
- {
- createDisposition = OPEN_ALWAYS;
- shareMode |= FILE_SHARE_WRITE;
- accessRights |= FILE_WRITE_ATTRIBUTES
- | FILE_WRITE_DATA | FILE_WRITE_EA
- | FILE_ALL_ACCESS;
- }
- if (flags & O_TRUNC)
- {
- createDisposition = CREATE_ALWAYS;
- }
- if (flags & O_EXCL)
- {
- shareMode = 0;
- }
+ }
+
+ tmpStr += filename;
+ return tmpStr;
+}
- HANDLE hdir = CreateFileW(buffer,
- accessRights,
- shareMode,
- NULL,
- createDisposition,
- FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: openfile
+// Purpose: replacement for any open calls - handles unicode filenames - supplied in utf8
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+HANDLE openfile(const char *pFileName, int flags, int mode)
+{
+ std::string AbsPathWithUnicode = ConvertPathToAbsoluteUnicode(pFileName);
+
+ if (AbsPathWithUnicode.size() == 0)
+ {
+ // error already logged by ConvertPathToAbsoluteUnicode()
+ return NULL;
+ }
+
+ WCHAR* pBuffer = ConvertUtf8ToMultiByte(AbsPathWithUnicode.c_str());
+ // We are responsible for freeing pBuffer
+
+ if (pBuffer == NULL)
+ {
+ // error already logged by ConvertUtf8ToMultiByte()
+ return NULL;
+ }
- if ( hdir == INVALID_HANDLE_VALUE )
- {
- DWORD err = GetLastError();
- ::syslog(LOG_WARNING, "Failed to open file %s: "
- "error %i", filename, err);
- delete [] buffer;
- return NULL;
- }
+ // flags could be O_WRONLY | O_CREAT | O_RDONLY
+ DWORD createDisposition = OPEN_EXISTING;
+ DWORD shareMode = FILE_SHARE_READ;
+ DWORD accessRights = FILE_READ_ATTRIBUTES | FILE_LIST_DIRECTORY | FILE_READ_EA;
- delete [] buffer;
- return hdir;
-
+ if (flags & O_WRONLY)
+ {
+ shareMode = FILE_SHARE_WRITE;
}
- catch(...)
+ if (flags & O_RDWR)
{
- ::syslog(LOG_ERR, "Caught openfile: %s", filename);
+ shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
}
- return NULL;
+ if (flags & O_CREAT)
+ {
+ createDisposition = OPEN_ALWAYS;
+ shareMode |= FILE_SHARE_WRITE;
+ accessRights |= FILE_WRITE_ATTRIBUTES
+ | FILE_WRITE_DATA | FILE_WRITE_EA
+ | FILE_ALL_ACCESS;
+ }
+ if (flags & O_TRUNC)
+ {
+ createDisposition = CREATE_ALWAYS;
+ }
+ if (flags & O_EXCL)
+ {
+ shareMode = 0;
+ }
+ HANDLE hdir = CreateFileW(pBuffer,
+ accessRights,
+ shareMode,
+ NULL,
+ createDisposition,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+
+ delete [] pBuffer;
+
+ if (hdir == INVALID_HANDLE_VALUE)
+ {
+ ::syslog(LOG_WARNING, "Failed to open file %s: "
+ "error %i", pFileName, GetLastError());
+ return NULL;
+ }
+
+ return hdir;
}
// MinGW provides a getopt implementation
@@ -427,76 +473,26 @@
// Created: 10th December 2004
//
// --------------------------------------------------------------------------
-HANDLE OpenFileByNameUtf8(const char* pName)
+HANDLE OpenFileByNameUtf8(const char* pFileName)
{
- //some string thing - required by ms to indicate long/unicode filename
- std::string tmpStr("\\\\?\\");
-
- // is the path relative or otherwise
- std::string fileN(pName);
- if (fileN[1] != ':')
+ std::string AbsPathWithUnicode = ConvertPathToAbsoluteUnicode(pFileName);
+
+ if (AbsPathWithUnicode.size() == 0)
{
- // we need to get the current directory
- char wd[PATH_MAX];
- if(::getcwd(wd, PATH_MAX) == 0)
- {
- ::syslog(LOG_WARNING,
- "Failed to open '%s': path too long", pName);
- errno = ENAMETOOLONG;
- return NULL;
- }
-
- tmpStr += wd;
- if (tmpStr[tmpStr.length()] != '\\')
- {
- tmpStr += '\\';
- }
- }
-
- tmpStr += fileN;
-
- int strlen = MultiByteToWideChar(
- CP_UTF8, // code page
- 0, // character-type options
- tmpStr.c_str(), // string to map
- (int)tmpStr.length(), // number of bytes in string
- NULL, // wide-character buffer
- 0 // size of buffer - work out
- // how much space we need
- );
-
- wchar_t* buffer = new wchar_t[strlen+1];
-
- if (buffer == NULL)
- {
- ::syslog(LOG_WARNING,
- "Failed to open '%s': out of memory", pName);
- errno = ENOMEM;
+ // error already logged by ConvertPathToAbsoluteUnicode()
return NULL;
}
-
- strlen = MultiByteToWideChar(
- CP_UTF8, // code page
- 0, // character-type options
- tmpStr.c_str(), // string to map
- (int)tmpStr.length(), // number of bytes in string
- buffer, // wide-character buffer
- strlen // size of buffer
- );
-
- if (strlen == 0)
+
+ WCHAR* pBuffer = ConvertUtf8ToMultiByte(AbsPathWithUnicode.c_str());
+ // We are responsible for freeing pBuffer
+
+ if (pBuffer == NULL)
{
- ::syslog(LOG_WARNING,
- "Failed to open '%s': could not convert "
- "file name to Unicode", pName);
- errno = EACCES;
- delete [] buffer;
+ // error already logged by ConvertUtf8ToMultiByte()
return NULL;
}
- buffer[strlen] = L'\0';
-
- HANDLE handle = CreateFileW(buffer,
+ HANDLE handle = CreateFileW(pBuffer,
FILE_READ_ATTRIBUTES | FILE_LIST_DIRECTORY | FILE_READ_EA,
FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
NULL,
@@ -510,7 +506,7 @@
// open in this mode - to get the inode information
// at least one process must have the file open -
// in this case someone else does.
- handle = CreateFileW(buffer,
+ handle = CreateFileW(pBuffer,
0,
FILE_SHARE_READ,
NULL,
@@ -532,7 +528,7 @@
else
{
::syslog(LOG_WARNING,
- "Failed to open '%s': error %d", pName);
+ "Failed to open '%s': error %d", pFileName, err);
errno = EACCES;
}
@@ -630,105 +626,50 @@
// --------------------------------------------------------------------------
DIR *opendir(const char *name)
{
- try
+ if (!name || !name[0])
{
- DIR *dir = 0;
- std::string dirName(name);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ std::string dirName(name);
- //append a '\' win32 findfirst is sensitive to this
- if ( dirName[dirName.size()] != '\\' || dirName[dirName.size()] != '/' )
- {
- dirName += '\\';
- }
+ //append a '\' win32 findfirst is sensitive to this
+ if ( dirName[dirName.size()] != '\\' || dirName[dirName.size()] != '/' )
+ {
+ dirName += '\\';
+ }
- //what is the search string? - everything
- dirName += '*';
+ // what is the search string? - everything
+ dirName += '*';
- if(name && name[0])
- {
- if ( ( dir = new DIR ) != 0 )
- {
- //mbstowcs(dir->name, dirName.c_str(),100);
- //wcscpy((wchar_t*)dir->name, (const wchar_t*)dirName.c_str());
- //mbstowcs(dir->name, dirName.c_str(), dirName.size()+1);
- //wchar_t *buffer;
+ DIR *pDir = new DIR;
+ if (pDir == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
- int strlen = MultiByteToWideChar(
- CP_UTF8, // code page
- 0, // character-type options
- dirName.c_str(), // string to map
- (int)dirName.length(), // number of bytes in string
- NULL, // wide-character buffer
- 0 // size of buffer - work out how much space we need
- );
+ pDir->name = ConvertUtf8ToMultiByte(dirName.c_str());
+ // We are responsible for freeing dir->name
+
+ if (pDir->name == NULL)
+ {
+ delete pDir;
+ return NULL;
+ }
- dir->name = new wchar_t[strlen+1];
+ pDir->fd = _wfindfirst((const wchar_t*)pDir->name, &(pDir->info));
- if (dir->name == NULL)
- {
- delete dir;
- dir = 0;
- errno = ENOMEM;
- return NULL;
- }
-
- strlen = MultiByteToWideChar(
- CP_UTF8, // code page
- 0, // character-type options
- dirName.c_str(), // string to map
- (int)dirName.length(), // number of bytes in string
- dir->name, // wide-character buffer
- strlen // size of buffer
- );
-
- if (strlen == 0)
- {
- delete dir->name;
- delete dir;
- dir = 0;
- errno = ENOMEM;
- return NULL;
- }
-
- dir->name[strlen] = L'\0';
-
-
- dir->fd = _wfindfirst(
- (const wchar_t*)dir->name,
- &dir->info);
-
- if (dir->fd != -1)
- {
- dir->result.d_name = 0;
- }
- else // go back
- {
- delete [] dir->name;
- delete dir;
- dir = 0;
- }
- }
- else // backwards again
- {
- delete dir;
- dir = 0;
- errno = ENOMEM;
- }
- }
- else
- {
- errno = EINVAL;
- }
-
- return dir;
-
- }
- catch(...)
+ if (pDir->fd == -1)
{
- printf("Caught opendir");
+ delete [] pDir->name;
+ delete pDir;
+ return NULL;
}
-
- return NULL;
+
+ pDir->result.d_name = 0;
+ return pDir;
}
// this kinda makes it not thread friendly!
@@ -915,19 +856,18 @@
break;
}
-
- //taken from MSDN
+ // taken from MSDN
int sixfourpos;
while ( (sixfourpos = (int)sixfour.find("%ll")) != -1 )
{
- //maintain portability - change the 64 bit formater...
+ // maintain portability - change the 64 bit formater...
std::string temp = sixfour.substr(0,sixfourpos);
temp += "%I64";
temp += sixfour.substr(sixfourpos+3, sixfour.length());
sixfour = temp;
}
- //printf("parsed string is:%s\r\n", sixfour.c_str());
+ // printf("parsed string is:%s\r\n", sixfour.c_str());
va_list args;
va_start(args, frmt);
@@ -939,16 +879,16 @@
LPCSTR strings[] = { buffer, NULL };
- if (!ReportEvent(gSyslogH, // event log handle
- errinfo, // event type
- 0, // category zero
- MSG_ERR_EXIST, // event identifier -
- // we will call them all the same
- NULL, // no user security identifier
- 1, // one substitution string
- 0, // no data
- strings, // pointer to string array
- NULL)) // pointer to data
+ if (!ReportEvent(gSyslogH, // event log handle
+ errinfo, // event type
+ 0, // category zero
+ MSG_ERR_EXIST, // event identifier -
+ // we will call them all the same
+ NULL, // no user security identifier
+ 1, // one substitution string
+ 0, // no data
+ strings, // pointer to string array
+ NULL)) // pointer to data
{
DWORD err = GetLastError();
Modified: box/chris/win32/vc2005-compile-fixes/lib/win32/emu.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/win32/emu.h 2006-02-04 15:42:05 UTC (rev 380)
+++ box/chris/win32/vc2005-compile-fixes/lib/win32/emu.h 2006-02-04 19:51:22 UTC (rev 381)
@@ -428,6 +428,10 @@
int poll (struct pollfd *ufds, unsigned long nfds, int timeout);
bool EnableBackupRights( void );
+// caller must free the returned buffer from ConvertUtf8ToMultiByte()
+// with delete[]
+WCHAR* ConvertUtf8ToMultiByte(const char* pName);
+
//
// MessageId: MSG_ERR_EXIST
// MessageText: