Kern Sibbald
General:
+29Apr06
+- Integrate Howard's VSS patch. Tweak it a bit. VSS now
+ works in the MinGW build with the exception that there
+ is a problem with accented characters -- i.e. there is
+ some mapping problem with wide characters.
+- The code no longer compiles with Microsoft VC++.
28Apr06
- Start implementing Christopher's St.Bernard code.
- Add Christopher's mods for opening files.
#else
extern int rl_catch_signals;
#endif
+#ifdef HAVE_MINGW
+/* Remove when we have real lib in src/lib */
+int enable_vss;
+#endif
/* Imported functions */
int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
#undef VERSION
#define VERSION "1.39.10"
-#define BDATE "28 April 2006"
-#define LSMDATE "28Apr06"
+#define BDATE "29 April 2006"
+#define LSMDATE "29Apr06"
/* Debug flags */
#undef DEBUG
INCLUDE_BACULA = -I .. -I ./compat
INCLUDE_PTHREADS = -I$(DEPKGS)/pthreads
INCLUDE_ZLIB = -I$(DEPKGS)/zlib
-INCLUDE_ATL = -I$(CROSSTOOLS)/atlmfc/include
+#INCLUDE_ATL = -I$(CROSSTOOLS)/atlmfc/include
INCLUDE_VSS = -I$(CROSSTOOLS)
INCLUDE_ICONS = -I ../filed/win32
-INCLUDE_OPENSSL = -I$(CROSSTOOLS)/openssl/include
+INCLUDE_OPENSSL = -I$(DEPKGS)/openssl/include
LIB_MINGW = $(MINGW)/mingw32/lib
LIB_PTHREADS = $(DEPKGS)/pthreads/pthreadGCE.dll
$(INCLUDE_PTHREADS) \
$(INCLUDE_BACULA) \
$(INCLUDE_ZLIB) \
+ $(INCLUDE_VSS) \
$(INCLUDE_ICONS)
-# $(INCLUDE_VSS) \
# $(INCLUDE_ATL) \
# $(INCLUDE_OPENSSL)
-DHAVE_MINGW \
-DHAVE_ZLIB_H \
-DHAVE_LIBZ \
+ -DWIN32_VSS \
-DHAVE_WIN32
-# -DWIN32_VSS \
# -DHAVE_OPENSSL \
# -DHAVE_TLS \
vss.o: ./compat/vss.cpp
$(CXX) -c ./compat/vss.cpp -o $(OBJDIR)/vss.o
-vss_xp.o: ./compat/vss_XP.cpp
+vss_xp.o: ./compat/vss_XP.cpp ./compat/vss_generic.cpp
$(CXX) -c ./compat/vss_XP.cpp -o $(OBJDIR)/vss_xp.o
-vss_w2k3.o: ./compat/vss_W2K3.cpp
+vss_w2k3.o: ./compat/vss_W2K3.cpp ./compat/vss_generic.cpp
$(CXX) -c ./compat/vss_W2K3.cpp -o $(OBJDIR)/vss_w2k3.o
######################################################################
bacula-fd.exe: $(FD_OBJS)
$(CXX) $(FD_OBJS) $(FD_LIBS) -o $(OBJDIR)/bacula-fd.exe
cp -f $(DEPKGS)/pthreads/pthreadGCE.dll .
+ cp -f $(MINGW)/mingw32/bin/mingwm10.dll .
# Link the File daemon executable ...
bconsole.exe: $(CONS_OBJS)
$(CXX) $(CONS_OBJS) $(CONS_LIBS) -o $(OBJDIR)/bconsole.exe
cp -f $(DEPKGS)/pthreads/pthreadGCE.dll .
+ cp -f $(MINGW)/mingw32/bin/mingwm10.dll .
The above only needs to be done once unless we change the cross-tools
version. In general, you can run the script multiple times with no
problem. For it to work, you must have a valid gcc compiler installed on
-your system as well as wget. There may be other dependencies.
+your system as well as wget and texinfo. There may be other dependencies.
After building the cross-tools, you can proceed to build the depkgs-win32
packages, which must use the cross-tools compiler.
make
if all goes well, you will end with bacula-fd.exe, bconsole.exe,
-and pthreadGCE.dll in the current directory.
+pthreadGCE.dll, and mingwm10.dll in the current directory.
Items to be done:
- Get VSS builds to work
// Copyright transferred from Raider Solutions, Inc to
// Kern Sibbald and John Walker by express permission.
//
-// Copyright (C) 2004-2005 Kern Sibbald
+// Copyright (C) 2004-2006 Kern Sibbald
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// $Id$
#include "bacula.h"
+#include "compat.h"
#define b_errno_win32 (1<<29)
#include "vss.h"
// from MicroSoft SDK (KES) is the diff between Jan 1 1601 and Jan 1 1970
#ifdef HAVE_MINGW
-#define WIN32_FILETIME_ADJUST 0x19DB1DED53E8000ULL //Not sure it works
+#define WIN32_FILETIME_ADJUST 0x19DB1DED53E8000ULL
#else
#define WIN32_FILETIME_ADJUST 0x19DB1DED53E8000I64
#endif
{
/* created 02/27/2006 Thorsten Engel
- This function expects an UCS-encoded standard WCHAR in pszUCSPath and
+ This function expects an UCS-encoded standard wchar_t in pszUCSPath and
will complete the input path to an absolue path of the form \\?\c:\path\file
With this trick, it is possible to have 32K characters long paths.
if (!p_GetCurrentDirectoryW)
return pszUCSPath;
- WCHAR* name = (WCHAR*) pszUCSPath;
+ wchar_t * name = (wchar_t *) pszUCSPath;
/* if it has already the desired form, exit without changes */
if (wcslen(name) > 3 && wcsncmp (name, L"\\\\?\\", 4) == 0)
/* get buffer with enough size (name+max 6. wchars+1 null terminator */
DWORD dwBufCharsNeeded = (wcslen(name)+7);
- pwszBuf = check_pool_memory_size(pwszBuf, dwBufCharsNeeded*sizeof(WCHAR));
+ pwszBuf = check_pool_memory_size(pwszBuf, dwBufCharsNeeded*sizeof(wchar_t));
/* add \\?\ to support 32K long filepaths
it is important to make absolute paths, so we add drive and
/* add 4 bytes header */
if (bAddPrefix) {
nParseOffset = 4;
- wcscpy ((WCHAR*) pwszBuf,L"\\\\?\\");
+ wcscpy ((wchar_t *) pwszBuf,L"\\\\?\\");
}
/* get current path if needed */
dwCurDirPathSize = p_GetCurrentDirectoryW(0, NULL);
if (dwCurDirPathSize > 0) {
/* get directory into own buffer as it may either return c:\... or \\?\C:\.... */
- pwszCurDirBuf = check_pool_memory_size(pwszCurDirBuf, (dwCurDirPathSize+1)*sizeof(WCHAR));
- p_GetCurrentDirectoryW(dwCurDirPathSize,(WCHAR*)pwszCurDirBuf);
+ pwszCurDirBuf = check_pool_memory_size(pwszCurDirBuf, (dwCurDirPathSize+1)*sizeof(wchar_t));
+ p_GetCurrentDirectoryW(dwCurDirPathSize,(wchar_t *)pwszCurDirBuf);
}
else
{
/* add drive if needed */
if (bAddDrive && !bAddCurrentPath) {
- WCHAR szDrive[3];
+ wchar_t szDrive[3];
- if (dwCurDirPathSize > 3 && wcsncmp ((LPCWSTR)pwszCurDirBuf, L"\\\\?\\", 4) == 0)
+ if (dwCurDirPathSize > 3 && wcsncmp((LPCWSTR)pwszCurDirBuf, L"\\\\?\\", 4) == 0)
/* copy drive character */
- wcsncpy ((WCHAR*) szDrive, (LPCWSTR)pwszCurDirBuf+4,2);
+ wcsncpy((wchar_t *) szDrive, (LPCWSTR)pwszCurDirBuf+4,2);
else
/* copy drive character */
- wcsncpy ((WCHAR*) szDrive, (LPCWSTR)pwszCurDirBuf,2);
+ wcsncpy((wchar_t *) szDrive, (LPCWSTR)pwszCurDirBuf,2);
szDrive[2] = 0;
- wcscat ((WCHAR*) pwszBuf, szDrive);
+ wcscat((wchar_t *) pwszBuf, szDrive);
nParseOffset +=2;
}
if (bAddCurrentPath) {
/* the 1 add. character is for the eventually added backslash */
dwBufCharsNeeded += dwCurDirPathSize+1;
- pwszBuf = check_pool_memory_size(pwszBuf, dwBufCharsNeeded*sizeof(WCHAR));
+ pwszBuf = check_pool_memory_size(pwszBuf, dwBufCharsNeeded*sizeof(wchar_t));
/* get directory into own buffer as it may either return c:\... or \\?\C:\.... */
if (dwCurDirPathSize > 3 && wcsncmp ((LPCWSTR)pwszCurDirBuf, L"\\\\?\\", 4) == 0)
/* copy complete string */
- wcscpy ((WCHAR*) pwszBuf, (LPCWSTR)pwszCurDirBuf);
+ wcscpy((wchar_t *) pwszBuf, (LPCWSTR)pwszCurDirBuf);
else
/* append path */
- wcscat ((WCHAR*) pwszBuf, (LPCWSTR)pwszCurDirBuf);
+ wcscat((wchar_t *) pwszBuf, (LPCWSTR)pwszCurDirBuf);
nParseOffset = wcslen ((LPCWSTR) pwszBuf);
/* check if path ends with backslash, if not, add one */
- if (*((WCHAR*) pwszBuf+nParseOffset-1) != L'\\') {
- wcscat ((WCHAR*) pwszBuf, L"\\");
+ if (*((wchar_t *) pwszBuf+nParseOffset-1) != L'\\') {
+ wcscat((wchar_t *) pwszBuf, L"\\");
nParseOffset++;
}
}
- WCHAR* win32_name = (WCHAR*) pwszBuf+nParseOffset;
+ wchar_t * win32_name = (wchar_t *)pwszBuf+nParseOffset;
while (*name) {
/* Check for Unix separator and convert to Win32 */
*/
if (g_pVSSClient && enable_vss && g_pVSSClient->IsInitialized()) {
/* is output buffer large enough? */
- pwszBuf = check_pool_memory_size(pwszBuf, (dwBufCharsNeeded+MAX_PATH)*sizeof(WCHAR));
+ pwszBuf = check_pool_memory_size(pwszBuf, (dwBufCharsNeeded+MAX_PATH)*sizeof(wchar_t));
/* create temp. buffer */
- POOLMEM* pszBuf = get_pool_memory (PM_FNAME);
- pszBuf = check_pool_memory_size(pszBuf, (dwBufCharsNeeded+MAX_PATH)*sizeof(WCHAR));
+ POOLMEM* pszBuf = get_pool_memory(PM_FNAME);
+ pszBuf = check_pool_memory_size(pszBuf, (dwBufCharsNeeded+MAX_PATH)*sizeof(wchar_t));
if (bAddPrefix)
nParseOffset = 4;
else
nParseOffset = 0;
- wcsncpy ((WCHAR*) pszBuf, (WCHAR*) pwszBuf+nParseOffset, wcslen((WCHAR*)pwszBuf)+1-nParseOffset);
- g_pVSSClient->GetShadowPathW((WCHAR*)pszBuf,(WCHAR*)pwszBuf,dwBufCharsNeeded+MAX_PATH);
+ wcsncpy((wchar_t *) pszBuf, (wchar_t *) pwszBuf+nParseOffset, wcslen((wchar_t *)pwszBuf)+1-nParseOffset);
+ g_pVSSClient->GetShadowPathW((wchar_t *)pszBuf,(wchar_t *)pwszBuf,dwBufCharsNeeded+MAX_PATH);
free_pool_memory(pszBuf);
}
#endif
}
int
-wchar_2_UTF8(char *pszUTF, const WCHAR *pszUCS, int cchChar)
+wchar_2_UTF8(char *pszUTF, const wchar_t *pszUCS, int cchChar)
{
/* the return value is the number of bytes written to the buffer.
The number includes the byte for the null terminator. */
if (p_MultiByteToWideChar) {
/* strlen of UTF8 +1 is enough */
DWORD cchSize = (strlen(pszUTF)+1);
- *ppszUCS = check_pool_memory_size(*ppszUCS, cchSize*sizeof (WCHAR));
+ *ppszUCS = check_pool_memory_size(*ppszUCS, cchSize*sizeof (wchar_t));
int nRet = p_MultiByteToWideChar(CP_UTF8, 0, pszUTF, -1, (LPWSTR) *ppszUCS,cchSize);
ASSERT (nRet > 0);
void
-wchar_win32_path(const char *name, WCHAR *win32_name)
+wchar_win32_path(const char *name, wchar_t *win32_name)
{
const char *fname = name;
while (*name) {
rval->spec = tspec;
- // convert to WCHAR
+ // convert to wchar_t
if (p_FindFirstFileW) {
POOLMEM* pwcBuf = get_pool_memory(PM_FNAME);;
make_win32_path_UTF8_2_wchar(&pwcBuf,rval->spec);
if (p_GetCurrentDirectoryW) {
POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
- pwszBuf = check_pool_memory_size (pwszBuf, maxlen*sizeof(WCHAR));
+ pwszBuf = check_pool_memory_size (pwszBuf, maxlen*sizeof(wchar_t));
n = p_GetCurrentDirectoryW(maxlen, (LPWSTR) pwszBuf);
if (n!=0)
- n = wchar_2_UTF8 (buf, (WCHAR*)pwszBuf, maxlen)-1;
+ n = wchar_2_UTF8 (buf, (wchar_t *)pwszBuf, maxlen)-1;
free_pool_memory(pwszBuf);
} else if (p_GetCurrentDirectoryA)
HANDLE hIn = GetStdHandle (STD_INPUT_HANDLE);
if (hIn && (hIn != INVALID_HANDLE_VALUE) && p_WideCharToMultiByte && p_MultiByteToWideChar) {
DWORD dwRead;
- WCHAR wszBuf[1024];
+ wchar_t wszBuf[1024];
char szBuf[1024];
/* nt and unicode conversion */
dwRead --;
}
- /* convert from ansii to WCHAR */
+ /* convert from ansii to wchar_t */
p_MultiByteToWideChar(GetConsoleCP(), 0, szBuf, -1, wszBuf,1024);
- /* convert from WCHAR to UTF-8 */
+ /* convert from wchar_t to UTF-8 */
if (wchar_2_UTF8(buffer, wszBuf, len))
return buffer;
}
#include <sys/types.h>
#include <process.h>
#include <direct.h>
+#include <wchar.h>
#include <winsock2.h>
#include <windows.h>
#include <wincon.h>
public:
/* Attribute(s) ... */
- T* p;
+ T* p;
/* Creation ... */
- CComPtr()
- {
- p = NULL;
- }
-
+ CComPtr()
+ {
+ p = NULL;
+ }
+
/* Destructor ... */
- ~CComPtr()
- {
- if (p)
- p->Release();
- }
+ ~CComPtr()
+ {
+ if (p)
+ p->Release();
+ }
};
class CComBSTR
public:
- BSTR p;
+ BSTR p;
/* Creation ... */
- CComBSTR()
- {
- p = NULL;
- }
+ CComBSTR()
+ {
+ p = NULL;
+ }
/* Destructor ... */
- ~CComBSTR()
- {
- ::SysFreeString(p);
- }
+ ~CComBSTR()
+ {
+ ::SysFreeString(p);
+ }
/* Address-of operator */
- BSTR* operator&()
- {
- return &p;
- }
+ BSTR* operator&()
+ {
+ return &p;
+ }
};
#pragma comment(lib,"atlsd.lib")
-
// Constructor
VSSClient::VSSClient()
{
return FALSE;
}
-BOOL VSSClient::GetShadowPathW(const WCHAR *szFilePath, WCHAR *szShadowPath, int nBuflen)
+BOOL VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
{
if (!m_bBackupIsInitialized)
return FALSE;
while (!pS->empty())
pS->pop();
}
+
#endif
// Copyright transferred from MATRIX-Computer GmbH to
// Kern Sibbald by express permission.
//
-// Copyright (C) 2005 Kern Sibbald
+// Copyright (C) 2005-2006 Kern Sibbald
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
virtual BOOL CloseBackup() = 0;
virtual const char* GetDriverName() = 0;
BOOL GetShadowPath (const char* szFilePath, char* szShadowPath, int nBuflen);
- BOOL GetShadowPathW (const WCHAR* szFilePath, WCHAR* szShadowPath, int nBuflen); /* nBuflen in characters */
+ BOOL GetShadowPathW (const wchar_t* szFilePath, wchar_t* szShadowPath, int nBuflen); /* nBuflen in characters */
const size_t GetWriterCount();
const char* GetWriterInfo(int nIndex);
BOOL m_bBackupIsInitialized;
// drive A will be stored on position 0,Z on pos. 25
- WCHAR m_wszUniqueVolumeName[26][MAX_PATH]; // approx. 7 KB
- WCHAR m_szShadowCopyName[26][MAX_PATH]; // approx. 7 KB
+ wchar_t m_wszUniqueVolumeName[26][MAX_PATH]; // approx. 7 KB
+ wchar_t m_szShadowCopyName[26][MAX_PATH]; // approx. 7 KB
void* m_pAlistWriterState;
void* m_pAlistWriterInfoText;
switch between different headers to include.
*/
+#ifdef WIN32_VSS
#define B_VSS_W2K3
#include "vss_generic.cpp"
-
-
-
+#endif
+#ifdef WIN32_VSS
#define B_VSS_XP
#include "vss_generic.cpp"
-
+#endif
#ifdef WIN32_VSS
-#include <stdio.h>
-#include <basetsd.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <process.h>
-#include <direct.h>
-#include <winsock2.h>
-#include <windows.h>
-#include <wincon.h>
-#include <winbase.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <conio.h>
-#include <process.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <signal.h>
-#include <malloc.h>
-#include <setjmp.h>
-#include <direct.h>
-#include <ctype.h>
-#include <fcntl.h>
+#include "compat.h"
// STL includes
#include <vector>
#include <fstream>
using namespace std;
-#include <atlcomcli.h>
+#include "ms_atl.h"
#include <objbase.h>
+#ifdef HAVE_STRSAFE_H
// Used for safe string manipulation
#include <strsafe.h>
+#endif
#include "../../lib/winapi.h"
+class IXMLDOMDocument;
+
#ifdef B_VSS_XP
#pragma message("compile VSS for Windows XP")
#define VSSClientGeneric VSSClientXP
// Get the unique volume name for the given path
inline wstring GetUniqueVolumeNameForPath(wstring path)
{
- _ASSERTE(path.length() > 0);
+ if (!path.length() > 0) {
+ return L"";
+ }
// Add the backslash termination, if needed
path = AppendBackslash(path);
// Get the root path of the volume
- WCHAR volumeRootPath[MAX_PATH];
- WCHAR volumeName[MAX_PATH];
- WCHAR volumeUniqueName[MAX_PATH];
+ wchar_t volumeRootPath[MAX_PATH];
+ wchar_t volumeName[MAX_PATH];
+ wchar_t volumeUniqueName[MAX_PATH];
if (!p_GetVolumePathNameW || !p_GetVolumePathNameW((LPCWSTR)path.c_str(), volumeRootPath, MAX_PATH))
return L"";
// Convert a writer status into a string
-inline const WCHAR* GetStringFromWriterStatus(VSS_WRITER_STATE eWriterStatus)
+inline const wchar_t* GetStringFromWriterStatus(VSS_WRITER_STATE eWriterStatus)
{
switch (eWriterStatus) {
CHECK_CASE_FOR_CONSTANT(VSS_WS_STABLE);
CComPtr<IVssAsync> pAsync1;
// 3. GatherWriterMetaData
- hr = ((IVssBackupComponents*) m_pVssObject)->GatherWriterMetadata(&pAsync1);
+ hr = ((IVssBackupComponents*) m_pVssObject)->GatherWriterMetadata(&pAsync1.p);
if (FAILED(hr)) {
errno = b_errno_win32;
return FALSE;
}
// Waits for the async operation to finish and checks the result
- WaitAndCheckForAsyncOperation(pAsync1);
+ WaitAndCheckForAsyncOperation(pAsync1.p);
}
#ifdef DEBUG
// Check if the async operation succeeded...
if(hrReturned != VSS_S_ASYNC_FINISHED) {
- PWCHAR pwszBuffer = NULL;
+ Pwchar_t pwszBuffer = NULL;
DWORD dwRet = ::FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
/* AddToSnapshotSet */
- WCHAR szDrive[3];
+ wchar_t szDrive[3];
szDrive[1] = ':';
szDrive[2] = 0;
}
/* PrepareForBackup */
- if (FAILED(pVss->PrepareForBackup(&pAsync1))) {
+ if (FAILED(pVss->PrepareForBackup(&pAsync1.p))) {
return FALSE;
}
// Waits for the async operation to finish and checks the result
- WaitAndCheckForAsyncOperation(pAsync1);
+ WaitAndCheckForAsyncOperation(pAsync1.p);
/* get latest info about writer status */
if (!CheckWriterStatus()) {
}
/* DoSnapShotSet */
- if (FAILED(pVss->DoSnapshotSet(&pAsync2))) {
+ if (FAILED(pVss->DoSnapshotSet(&pAsync2.p))) {
return FALSE;
}
// Waits for the async operation to finish and checks the result
- WaitAndCheckForAsyncOperation(pAsync2);
+ WaitAndCheckForAsyncOperation(pAsync2.p);
/* query snapshot info */
QuerySnapshotSet(m_uidCurrentSnapshotSet);
m_bBackupIsInitialized = false;
- if (SUCCEEDED(pVss->BackupComplete(&pAsync))) {
+ if (SUCCEEDED(pVss->BackupComplete(&pAsync.p))) {
// Waits for the async operation to finish and checks the result
- WaitAndCheckForAsyncOperation(pAsync);
+ WaitAndCheckForAsyncOperation(pAsync.p);
bRet = TRUE;
} else {
errno = b_errno_win32;
HRESULT hr = pVss->Query( GUID_NULL,
VSS_OBJECT_NONE,
VSS_OBJECT_SNAPSHOT,
- &pIEnumSnapshots );
+ (IVssEnumObject**)(&pIEnumSnapshots) );
// If there are no shadow copies, just return
if (FAILED(hr)) {
while (true) {
// Get the next element
ULONG ulFetched;
- hr = pIEnumSnapshots->Next( 1, &Prop, &ulFetched );
+ hr = (pIEnumSnapshots.p)->Next( 1, &Prop, &ulFetched );
// We reached the end of list
if (ulFetched == 0)
// Gather writer status to detect potential errors
CComPtr<IVssAsync> pAsync;
- HRESULT hr = pVss->GatherWriterStatus(&pAsync);
+ HRESULT hr = pVss->GatherWriterStatus(&pAsync.p);
if (FAILED(hr)) {
errno = b_errno_win32;
return FALSE;
}
// Waits for the async operation to finish and checks the result
- WaitAndCheckForAsyncOperation(pAsync);
+ WaitAndCheckForAsyncOperation(pAsync.p);
unsigned cWriters = 0;
nState = 1;
}
}
-
/* store text info */
- CComBSTR str;
- char szBuf[16];
- itoa(eWriterStatus, szBuf, 16);
-
- str = "\"";
- str.Append (bstrWriterName);
- str.Append ("\", State: 0x");
- str.Append (szBuf);
- str.Append (" (");
- str.Append (GetStringFromWriterStatus(eWriterStatus));
- str.Append (")");
-
- AppendWriterInfo(nState, CW2A(str));
+ char str[1000];
+ char szBuf[200];
+ itoa(eWriterStatus, szBuf, sizeof(szBuf));
+ strcpy(str, "\"");
+ wchar_2_UTF8(szBuf, bstrWriterName.p, sizeof(szBuf));
+ strcat(str, szBuf);
+ strcat(str, "\", State: 0x");
+ strcat(str, szBuf);
+ strcat(str, " (");
+ wchar_2_UTF8(szBuf, GetStringFromWriterStatus(eWriterStatus), sizeof(szBuf));
+ strcat(str, szBuf);
+ strcat(str, ")");
+
+ AppendWriterInfo(nState, (const char *)str);
// SysFreeString (bstrWriterName);
}
#define HOST_OS "Linux"
#define DISTNAME "Cross-compile"
-#define DISTVER "1"
+#define DISTVER "Win32"
#else
extern char WIN_VERSION_LONG[];