summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/Makefile.am2
-rw-r--r--win32/common/Makefile.am2
-rw-r--r--win32/common/atlprsht.h915
-rw-r--r--win32/common/atlwinhk.h151
-rw-r--r--win32/common/droplet.cpp226
-rw-r--r--win32/common/droplet.h98
-rw-r--r--win32/common/errutil.cpp106
-rw-r--r--win32/common/errutil.h32
-rw-r--r--win32/common/mystring.h536
-rw-r--r--win32/common/rep.icobin0 -> 766 bytes
-rw-r--r--win32/common/rliberr.h136
-rw-r--r--win32/common/rliberr.mc106
-rw-r--r--win32/droplet/Makefile.am2
-rw-r--r--win32/droplet/droplet.dsp223
-rw-r--r--win32/droplet/droplet.rc197
-rw-r--r--win32/droplet/dropletmain.cpp76
-rw-r--r--win32/droplet/progressdlg.cpp211
-rw-r--r--win32/droplet/progressdlg.h92
-rw-r--r--win32/droplet/replace.cpp438
-rw-r--r--win32/droplet/replace.h73
-rw-r--r--win32/droplet/resource.h22
-rw-r--r--win32/droplet/rliberr.h136
-rw-r--r--win32/droplet/rliberr.rc2
-rw-r--r--win32/droplet/stdafx.cpp31
-rw-r--r--win32/droplet/stdafx.h39
-rw-r--r--win32/droplet/temp.cmpbin0 -> 186 bytes
-rw-r--r--win32/droplet/temp.rep24
-rw-r--r--win32/makedrop/MSG00001.binbin0 -> 512 bytes
-rw-r--r--win32/makedrop/Makefile.am2
-rw-r--r--win32/makedrop/dropsheet.cpp301
-rw-r--r--win32/makedrop/dropsheet.h72
-rw-r--r--win32/makedrop/makedrop.cpp74
-rw-r--r--win32/makedrop/makedrop.dsp203
-rw-r--r--win32/makedrop/makedrop.h1
-rw-r--r--win32/makedrop/makedrop.rc275
-rw-r--r--win32/makedrop/processpage.cpp239
-rw-r--r--win32/makedrop/processpage.h75
-rw-r--r--win32/makedrop/resource.h32
-rw-r--r--win32/makedrop/rliberr.h136
-rw-r--r--win32/makedrop/rliberr.rc2
-rw-r--r--win32/makedrop/settingspage.cpp100
-rw-r--r--win32/makedrop/settingspage.h65
-rw-r--r--win32/makedrop/stdafx.cpp27
-rw-r--r--win32/makedrop/stdafx.h40
-rw-r--r--win32/pcre/include/pcre.h113
-rw-r--r--win32/pcre/include/pcreposix.h88
-rw-r--r--win32/pcre/lib/libpcre-bcc.def21
-rw-r--r--win32/pcre/lib/libpcre-bcc.libbin0 -> 4096 bytes
-rw-r--r--win32/pcre/lib/libpcre.def20
-rw-r--r--win32/pcre/lib/libpcre.la32
-rw-r--r--win32/pcre/lib/libpcre.libbin0 -> 5116 bytes
-rw-r--r--win32/pcre/lib/libpcreposix.la32
-rw-r--r--win32/pcre/manifest/pcre-3.9-lib.mft13
-rw-r--r--win32/pcre/manifest/pcre-3.9-lib.ver2
54 files changed, 5841 insertions, 0 deletions
diff --git a/win32/Makefile.am b/win32/Makefile.am
new file mode 100644
index 0000000..144140f
--- /dev/null
+++ b/win32/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = common droplet makedrop
+
diff --git a/win32/common/Makefile.am b/win32/common/Makefile.am
new file mode 100644
index 0000000..e247bdb
--- /dev/null
+++ b/win32/common/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST = atlprsht.h atlwinhk.h droplet.cpp droplet.h errutil.cpp errutil.h mystring.h rep.ico rliberr.mc
+
diff --git a/win32/common/atlprsht.h b/win32/common/atlprsht.h
new file mode 100644
index 0000000..e5181ea
--- /dev/null
+++ b/win32/common/atlprsht.h
@@ -0,0 +1,915 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+// PropertyPage.h: interface for the CPropertyPage class.
+// Implements Property Pages and Sheets for ATL
+// By Stef 06/10/99
+//
+// This class uses an MFC type Interface (CPropertySheet, CPropertyPage)
+// the only difference being that many of the virtual notify functions
+// are left for you to define in your derived classes using your message map
+//
+// Notes for CPropertySheet:
+// 1. If you define a WM_INITDIALOG handler in your derived class make
+// sure to either call the base handler (OnInitDialog) or set
+// bHandled to false.
+//
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_PROPERTYPAGE_H__1508DAF4_7AD1_11D3_BF96_0020182B97FC__INCLUDED_)
+#define AFX_PROPERTYPAGE_H__1508DAF4_7AD1_11D3_BF96_0020182B97FC__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+#include <atlwin.h>
+#include <atlwinhk.h>
+#include <commctrl.h>
+
+
+// Property Sheet control id's (determined with Spy++)
+#define ID_APPLY_NOW 0x3021
+#define ID_WIZBACK 0x3023
+#define ID_WIZNEXT 0x3024
+#define ID_WIZFINISH 0x3025
+
+#define AFX_IDC_TAB_CONTROL 0x3020
+
+// determine number of elements in an array (not bytes)
+#define _countof(array) (sizeof(array)/sizeof(array[0]))
+
+template <class TBase> class CPropertySheetT;
+template <class TBase> class CPropertyPageT;
+
+const int _PropSheetIDs[] =
+ { ID_WIZNEXT, ID_WIZFINISH, ID_WIZBACK, IDCANCEL };
+const int _PropSheetButtons[] =
+ { IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP };
+
+////////////////////////////////////////////////////////////////////////
+// Implements one page of a Property Sheet
+template <class TBase = CWindow>
+class CPropertyPageT : public CDialogImplBaseT< TBase >
+{
+// Construction
+public:
+ CPropertyPageT(UINT IDD) : m_szCaption(NULL)
+ { Construct(IDD, _T("")); }
+
+ // Caption from Resource
+ CPropertyPageT(UINT IDD, UINT nIDCaption) : m_szCaption(NULL)
+ { Construct(IDD, nIDCaption); }
+
+ CPropertyPageT(UINT IDD, LPCTSTR szCaption) : m_szCaption(NULL)
+ { Construct(IDD, szCaption); }
+
+ void Construct(UINT IDD, LPCTSTR szCaption)
+ { CommonConstruct(IDD, szCaption); }
+
+ void Construct(UINT IDD, UINT nIDCaption)
+ {
+ ATLASSERT(nIDCaption != 0);
+ USES_CONVERSION;
+ CComBSTR bsCaption;
+ bsCaption.LoadString(nIDCaption);
+ CommonConstruct(IDD, OLE2T(bsCaption));
+ }
+
+ // All Construction ends up here
+ void CommonConstruct(UINT IDD, LPCTSTR szCaption);
+
+ ~CPropertyPageT()
+ { if(m_szCaption) delete[] m_szCaption; }
+
+// Operations
+ void CancelToClose();
+ void SetModified(bool bChanged);
+ void SetHelp(bool bHelp);
+ LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam);
+ bool IsButtonEnabled(int iButton);
+ void EndDialog(int nID);
+
+// Status
+ CPropertySheetT<TBase>* GetParentSheet();
+
+// Implementaition
+protected:
+ CPropertySheetT<TBase>* m_pSheet; // Pointer to Sheet
+ static UINT CALLBACK PropPageCallback(HWND hwnd, UINT uMsg,
+ LPPROPSHEETPAGE ppsp);
+
+// Data
+public:
+ PROPSHEETPAGE m_psp; // API Structure
+ LPTSTR m_szCaption; // Caption
+
+ friend class CPropertySheetT<TBase>;
+};
+
+// Common Construction
+template <class TBase>
+void CPropertyPageT<TBase>::CommonConstruct(UINT IDD, LPCTSTR szCaption)
+{
+ // Clear
+ memset(&m_psp, 0, sizeof(m_psp));
+
+ m_psp.dwSize = sizeof(m_psp);
+ m_psp.hInstance = _Module.m_hInstResource;
+ m_psp.pszTemplate = MAKEINTRESOURCE(IDD);
+ // Set to DialogProc
+ m_psp.pfnDlgProc = (DLGPROC)StartDialogProc;
+ // Use to hook up to ATL WndProc
+ m_psp.pfnCallback = PropPageCallback;
+ m_psp.dwFlags = PSP_USETITLE | PSP_USECALLBACK;
+ // Passed to PropPageCallback
+ m_psp.lParam = (LPARAM)this;
+
+ // Allocate String
+ if(m_szCaption && _tcslen(m_szCaption) < _tcslen(szCaption))
+ {
+ delete[] m_szCaption;
+ m_szCaption = NULL;
+ }
+
+ if(!m_szCaption)
+ m_szCaption = new TCHAR[_tcslen(szCaption) + 1];
+
+ _tcscpy(m_szCaption, szCaption);
+ m_psp.pszTitle = m_szCaption;
+
+ // Set by CPropertySheetT::AddPage
+ m_pSheet = NULL;
+
+}
+
+// Callback used during actual creation of page
+template <class TBase>
+UINT CALLBACK CPropertyPageT<TBase>::PropPageCallback(HWND hwnd, UINT uMsg,
+ LPPROPSHEETPAGE ppsp)
+{
+ switch (uMsg)
+ {
+ case PSPCB_CREATE:
+ {
+ // Get ready for hooking up to an ATL WndProc
+ CPropertyPageT<TBase>* pPage =
+ (CPropertyPageT<TBase>*)ppsp->lParam;
+ _Module.AddCreateWndData(&(pPage->m_thunk.cd), pPage);
+
+ return TRUE;
+ }
+ case PSPCB_RELEASE:
+ break;
+ }
+
+ return 0;
+}
+
+// Thin Wrapper
+template <class TBase>
+void CPropertyPageT<TBase>::CancelToClose()
+{
+ ATLASSERT(::IsWindow(m_hWnd));
+ ATLASSERT(GetParent() != NULL);
+
+ ::SendMessage(GetParent(), PSM_CANCELTOCLOSE, NULL, NULL);
+}
+
+// Thin Wrapper
+template <class TBase>
+void CPropertyPageT<TBase>::SetModified(bool bChanged)
+{
+ ATLASSERT(m_hWnd != NULL);
+ ATLASSERT(::IsWindow(m_hWnd));
+ ATLASSERT(GetParent() != NULL);
+
+ if (bChanged)
+ ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, NULL);
+ else
+ ::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, NULL);
+}
+
+// Thin Wrapper
+template <class TBase>
+LRESULT CPropertyPageT<TBase>::QuerySiblings(WPARAM wParam, LPARAM lParam)
+{
+ ATLASSERT(::IsWindow(m_hWnd));
+ ATLASSERT(GetParent() != NULL);
+
+ return ::SendMessage(GetParent(), PSM_QUERYSIBLINGS, wParam, lParam);
+}
+
+template <class TBase>
+void CPropertyPageT<TBase>::SetHelp(bool bHelp)
+{
+ if(bHelp)
+ m_psp.dwFlags |= PSP_HASHELP;
+ else
+ m_psp.dwFlags &= ~(PSP_HASHELP);
+}
+
+// Thin wrapper
+template <class TBase>
+bool CPropertyPageT<TBase>::IsButtonEnabled(int iButton)
+{
+ HWND hWnd = ::GetDlgItem(::GetParent(m_hWnd), iButton);
+ if (hWnd == NULL)
+ return false;
+ return ::IsWindowEnabled(hWnd) ? true : false;
+}
+
+// Routes EndDialog calls to the Sheet
+template <class TBase>
+void CPropertyPageT<TBase>::EndDialog(int nID)
+{
+ // Normally you shouldn't call EndDialog from a page. But in case it does
+ // happen during error situations, call CPropertySheetT::EndDialog instead.
+ CPropertySheetT<TBase>* pParent = GetParentSheet();
+ if (pParent != NULL)
+ pParent->EndDialog(nID);
+}
+
+// Return Sheet Pointer (which is initialized in CPropertySheetT::AddPage)
+template <class TBase>
+CPropertySheetT<TBase>* CPropertyPageT<TBase>::GetParentSheet()
+ { ATLASSERT(m_pSheet != NULL); return m_pSheet; }
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Implements and hooks into Actual Property Sheet Window
+template <class TBase = CWindow>
+class CPropertySheetT : public CWindowImplBaseT< TBase >
+{
+// Construction
+public:
+ CPropertySheetT() : m_szCaption(NULL)
+ { CommonConstruct(_T(""), 0); }
+
+ // Caption from Resource
+ CPropertySheetT(UINT nIDCaption, HWND hwndParent = NULL, UINT iSelectPage = 0)
+ : m_szCaption(NULL)
+ { Construct(nIDCaption, hwndParent, iSelectPage); }
+
+ CPropertySheetT(LPCTSTR pszCaption, HWND hwndParent = NULL, UINT iSelectPage = 0)
+ : m_szCaption(NULL)
+ { Construct(pszCaption, hwndParent, iSelectPage); }
+
+ // Caption from Resource
+ void Construct(UINT nIDCaption, HWND hwndParent = NULL, UINT iSelectPage = 0)
+ {
+ ATLASSERT(nIDCaption != 0);
+ USES_CONVERSION;
+ CComBSTR bsCaption;
+ bsCaption.LoadString(nIDCaption);
+ CommonConstruct(OLE2T(bsCaption), hwndParent, iSelectPage);
+ }
+
+ void Construct(LPCTSTR pszCaption, HWND hwndParent = NULL, UINT iSelectPage = 0)
+ { CommonConstruct(pszCaption, hwndParent, iSelectPage); }
+
+ // All actual initialization takes place here
+ void CommonConstruct(LPCTSTR sCaption, HWND hwndParent = NULL, UINT iSelectPage = 0);
+
+ virtual ~CPropertySheetT()
+ { if(m_szCaption) delete[] m_szCaption; }
+
+// Creation
+public:
+ // for modeless creation
+ // the default style, expressed by passing -1 as dwStyle, is actually:
+ // WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | WS_VISIBLE
+ bool Create(HWND hwndParent = NULL, DWORD dwStyle = (DWORD)-1, DWORD dwExStyle = 0);
+ int DoModal(HWND hwndParent = NULL, DWORD dwStyle = (DWORD)-1, DWORD dwExStyle = 0);
+
+// Operations
+public:
+ void AddPage(CPropertyPageT<TBase>* pPage);
+ void RemovePage(CPropertyPageT<TBase>* pPage);
+ void RemovePage(int nPage);
+ void EndDialog(int nEndID); // used to terminate a modal dialog
+ bool PressButton(int nButton);
+
+// Status and Settings
+public:
+ int GetPageCount() const;
+ int GetActiveIndex() const;
+ CPropertyPageT<TBase>* GetActivePage() const;
+ CPropertyPageT<TBase>* GetPage(int nPage) const;
+ int GetPageIndex(CPropertyPageT<TBase>* pPage);
+ HWND GetTabControl() const;
+ void SetWizardMode();
+ void SetHelp(bool bHelp);
+ void SetFinishText(LPCTSTR lpszText);
+ void SetWizardButtons(DWORD dwFlags);
+ void EnableStackedTabs(BOOL bStacked);
+ bool IsWizard() const;
+ bool SetActivePage(int nPage);
+ bool SetActivePage(CPropertyPageT<TBase>* pPage);
+ void SetTitle(LPCTSTR lpszText, UINT nStyle = 0);
+
+// Message Map
+protected:
+typedef CPropertySheetT<TBase> sheetClass;
+BEGIN_MSG_MAP(sheetClass)
+ MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
+ MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand)
+ MESSAGE_HANDLER(WM_CLOSE, OnClose)
+ COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnEndCode)
+ COMMAND_HANDLER(IDOK, BN_CLICKED, OnEndCode)
+ COMMAND_HANDLER(ID_WIZFINISH, BN_CLICKED, OnEndCode)
+END_MSG_MAP()
+
+// Message Handlers
+ LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnEndCode(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+
+
+// Implementation
+protected:
+ void BuildPropPageArray(); // Finalizes the Array of Pages
+
+ // Used during creation to set styles
+ static int CALLBACK PropSheetCallback(HWND, UINT nMsg, LPARAM lParam);
+
+ // For hooking into creation and subclassing the window
+ DECLARE_HOOK_AND_SUBCLASS(sheetClass);
+
+ // Style cache (used in PropSheetCallback)
+ DWORD m_dwCurStyle;
+ DWORD m_dwCurExStyle;
+
+// Data
+protected:
+ CSimpleArray< CPropertyPageT<TBase>* > m_pages; // array of CPropertyPageT pointers
+ LPTSTR m_szCaption; // caption of the pseudo-dialog
+ bool m_bStacked; // EnableStackedTabs sets this
+ bool m_bModeless; // TRUE when Create called instead of DoModal
+ int m_nDlgRet; // Result from EndDialog
+
+public:
+ PROPSHEETHEADER m_psh;
+};
+
+// All Initialization here
+template <class TBase>
+void CPropertySheetT<TBase>::CommonConstruct(LPCTSTR szCaption,
+ HWND hwndParent /*= NULL*/,
+ UINT iSelectPage /*= 0*/)
+{
+ // Clear
+ memset(&m_psh, 0, sizeof(m_psh));
+
+ m_psh.dwSize = sizeof(m_psh);
+ m_psh.dwFlags = PSH_PROPSHEETPAGE;
+ m_psh.nStartPage = iSelectPage;
+
+ // Allocate String
+ if(m_szCaption && _tcslen(m_szCaption) < _tcslen(szCaption))
+ {
+ delete[] m_szCaption;
+ m_szCaption = NULL;
+ }
+
+ if(!m_szCaption)
+ m_szCaption = new TCHAR[_tcslen(szCaption) + 1];
+
+ _tcscpy(m_szCaption, szCaption);
+ m_psh.pszCaption = m_szCaption;
+
+ m_bStacked = true; // Tab Control
+ m_bModeless = false;
+ m_dwCurStyle = 0;
+ m_dwCurExStyle = 0;
+ m_nDlgRet = 0;
+
+ // m_psh.hwndParent set in DoModal/create
+}
+
+// Callback used to set styles of Property Sheet
+template <class TBase>
+int CALLBACK CPropertySheetT<TBase>::PropSheetCallback(HWND hwnd, UINT nMsg,
+ LPARAM lParam)
+{
+ switch (nMsg)
+ {
+ case PSCB_PRECREATE:
+ {
+ // Extract Thunk Create (whatever) data
+ CPropertySheetT<TBase>* pThis = (CPropertySheetT<TBase>*)_Module.ExtractCreateWndData();
+ // We need it later in the proces so add it back again
+ _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis);
+
+ LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)lParam;
+ if (lpTemplate->style != pThis->m_dwCurStyle ||
+ lpTemplate->dwExtendedStyle != pThis->m_dwCurExStyle)
+ {
+
+ // Mark the dialog template as read-write.
+ DWORD dwOldProtect;
+ VirtualProtect(lpTemplate, sizeof(DLGTEMPLATE), PAGE_READWRITE,
+ &dwOldProtect);
+
+ // Ensure DS_SETFONT is set correctly.
+ lpTemplate->style = lpTemplate->style & DS_SETFONT ?
+ pThis->m_dwCurStyle | DS_SETFONT :
+ pThis->m_dwCurStyle & ~DS_SETFONT;
+
+ lpTemplate->dwExtendedStyle = pThis->m_dwCurExStyle;
+ }
+ return TRUE;
+ }
+ case PSCB_INITIALIZED:
+ return TRUE;
+
+ }
+
+ return 0;
+}
+
+// Creates a Modeless Property Sheet
+template <class TBase>
+bool CPropertySheetT<TBase>::Create(HWND hwndParent /*= NULL*/, DWORD dwStyle /*= (DWORD)-1*/,
+ DWORD dwExStyle /*= 0*/)
+{
+ // Calculate the default window style.
+ if (dwStyle == (DWORD)-1)
+ {
+ dwStyle = DS_MODALFRAME | DS_3DLOOK | DS_SETFONT | WS_POPUP |
+ WS_VISIBLE | WS_CAPTION;
+
+ // Wizards don't have WS_SYSMENU by default
+ if (!IsWizard())
+ dwStyle |= WS_SYSMENU;
+ }
+
+ // Cache the styles (for use in PropSheetCallback)
+ m_dwCurStyle = dwStyle;
+ m_dwCurExStyle = dwExStyle;
+
+ ATLASSERT(m_hWnd == NULL);
+
+ // finish building PROPSHEETHEADER structure
+ BuildPropPageArray();
+
+ // Some more settings
+ m_bModeless = true;
+ m_psh.dwFlags |= (PSH_MODELESS | PSH_USECALLBACK);
+ m_psh.pfnCallback = PropSheetCallback;
+ m_psh.hwndParent = hwndParent;
+
+ // Add Create Thunk whatever Data
+ _Module.AddCreateWndData(&m_thunk.cd, this);
+ // Hook into creation so we can subclass before any messages come in
+ HOOK_AND_SUBCLASS_NEXT();
+
+ // Do it!
+ HWND hWnd = (HWND)::PropertySheet((PROPSHEETHEADER*)&m_psh);
+
+ // Modeless so we return right away
+#ifdef _DEBUG
+ DWORD dwError = ::GetLastError();
+#endif
+
+ if (hWnd == NULL || hWnd == (HWND)-1)
+ {
+#ifdef _DEBUG
+ ATLTRACE("PropertySheet() failed: GetLastError returned %d\n", dwError);
+#endif
+ return false;
+ }
+
+ m_hWnd = hWnd;
+
+ return true;
+}
+
+// Create a Modal Dialog
+template <class TBase>
+int CPropertySheetT<TBase>::DoModal(HWND hwndParent /*= NULL*/, DWORD dwStyle /*= (DWORD)-1*/,
+ DWORD dwExStyle /*= 0*/)
+{
+ ATLASSERT(m_hWnd == NULL);
+
+ // Calculate the default window style.
+ if (dwStyle == (DWORD)-1)
+ {
+ dwStyle = DS_MODALFRAME | DS_3DLOOK | DS_SETFONT | WS_POPUP |
+ WS_VISIBLE | WS_CAPTION;
+
+ // Wizards don't have WS_SYSMENU by default
+ if (!IsWizard())
+ dwStyle |= WS_SYSMENU;
+ }
+
+ // Cache the styles (for use in PropSheetCallback)
+ m_dwCurStyle = dwStyle;
+ m_dwCurExStyle = dwExStyle;
+
+ // finish building PROPSHEETHEADER structure
+ BuildPropPageArray();
+
+ // Set options
+ m_bModeless = false;
+ m_nDlgRet = -1;
+ m_psh.dwFlags |= (PSH_USECALLBACK);
+ m_psh.pfnCallback = PropSheetCallback;
+ m_psh.hwndParent = hwndParent;
+
+ // Add Create Thunk whatever Data
+ _Module.AddCreateWndData(&m_thunk.cd, this);
+ // Hook into creation so we can subclass before any messages come in
+ HOOK_AND_SUBCLASS_NEXT();
+
+ // Do it. Doesn't come back until after the fact
+ int nRet = ::PropertySheet((PROPSHEETHEADER*)&m_psh);
+
+ if(nRet == -1)
+ return nRet;
+
+ return m_nDlgRet;
+}
+
+// Finalize the Array
+template <class TBase>
+void CPropertySheetT<TBase>::BuildPropPageArray()
+{
+ // delete existing prop page array
+ delete[] (PROPSHEETPAGE*)m_psh.ppsp;
+ m_psh.ppsp = NULL;
+
+ // build new prop page array
+ PROPSHEETPAGE* ppsp = new PROPSHEETPAGE[m_pages.GetSize()];
+ m_psh.ppsp = (PROPSHEETPAGE*)ppsp;
+ BOOL bWizard = (m_psh.dwFlags & (PSH_WIZARD));
+ for (int i = 0; i < m_pages.GetSize(); i++)
+ {
+ CPropertyPageT<TBase>* pPage = GetPage(i);
+ memcpy(&ppsp[i], &pPage->m_psp, sizeof(pPage->m_psp));
+// pPage->PreProcessPageTemplate((PROPSHEETPAGE&)ppsp[i], bWizard);
+ }
+ m_psh.nPages = m_pages.GetSize();
+}
+
+// Adds a Page (either before or after we're on the screen)
+template <class TBase>
+void CPropertySheetT<TBase>::AddPage(CPropertyPageT<TBase>* pPage)
+{
+ ATLASSERT(pPage != NULL);
+
+ // Add page to internal list
+ m_pages.Add(pPage);
+ pPage->m_pSheet = this;
+
+ // Add page externally
+ if (m_hWnd != NULL)
+ {
+ // build new prop page array
+ PROPSHEETPAGE* ppsp = new PROPSHEETPAGE[m_pages.GetSize()];
+ memcpy(ppsp, m_psh.ppsp, sizeof(PROPSHEETPAGE) * (m_pages.GetSize() - 1));
+ delete[] (PROPSHEETPAGE*)m_psh.ppsp;
+ m_psh.ppsp = ppsp;
+ ppsp += m_pages.GetSize() - 1;
+
+ // copy processed PROPSHEETPAGE struct to end
+ memcpy(ppsp, &(pPage->m_psp), sizeof(pPage->m_psp));
+// pPage->PreProcessPageTemplate((PROPSHEETPAGE&)*ppsp, IsWizard());
+ HPROPSHEETPAGE hPSP = CreatePropertySheetPage((PROPSHEETPAGE*)ppsp);
+ ATLASSERT(hPSP != NULL);
+
+ // Tray and add it
+ if (!SendMessage(PSM_ADDPAGE, 0, (LPARAM)hPSP))
+ {
+ DestroyPropertySheetPage(hPSP);
+ ATLASSERT(false);
+ }
+ }
+}
+
+// Removes a Page (either before or after we're on the screen)
+template <class TBase>
+void CPropertySheetT<TBase>::RemovePage(CPropertyPageT<TBase>* pPage)
+{
+ ATLASSERT(pPage != NULL);
+
+ // Get Index
+ int nPage = GetPageIndex(pPage);
+ pPage->m_pSheet = NULL;
+ ATLASSERT(nPage >= 0);
+
+ RemovePage(nPage);
+}
+
+// Removes a Page (either before or after we're on the screen)
+template <class TBase>
+void CPropertySheetT<TBase>::RemovePage(int nPage)
+{
+ // remove the page externally
+ if (m_hWnd != NULL)
+ SendMessage(PSM_REMOVEPAGE, nPage);
+
+ // remove the page from internal list
+ m_pages.RemoveAt(nPage);
+}
+
+// Closes the Property Sheet
+template <class TBase>
+void CPropertySheetT<TBase>::EndDialog(int nEndID)
+{
+ m_nDlgRet = nEndID;
+
+ if (m_bModeless)
+ DestroyWindow();
+ else
+ PostMessage(PSM_PRESSBUTTON, PSBTN_CANCEL);
+}
+
+// Need to handle WM_CLOSE for Modeless Property Sheets
+template <class TBase>
+LRESULT CPropertySheetT<TBase>::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ if (m_bModeless)
+ DestroyWindow();
+ else
+ bHandled = false;
+
+ return 0;
+}
+
+// Need to handle SC_CLOSE for Modeless Property Sheets
+template <class TBase>
+LRESULT CPropertySheetT<TBase>::OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ switch (wParam & 0xFFF0)
+ {
+ case SC_CLOSE:
+ if (m_bModeless)
+ {
+ SendMessage(WM_CLOSE);
+ return 0;
+ }
+ }
+ bHandled = false;
+ return 0;
+}
+
+// Returns number of Pages
+template <class TBase>
+int CPropertySheetT<TBase>::GetPageCount() const
+{
+ if (m_hWnd == NULL)
+ return m_pages.GetSize();
+
+ return TabCtrl_GetItemCount(GetTabControl());
+}
+
+// Returns Current Page
+template <class TBase>
+int CPropertySheetT<TBase>::GetActiveIndex() const
+{
+ if (m_hWnd == NULL)
+ return m_psh.nStartPage;
+
+ return TabCtrl_GetCurSel(GetTabControl());
+}
+
+// Moves to Page
+template <class TBase>
+bool CPropertySheetT<TBase>::SetActivePage(int nPage)
+{
+ if (m_hWnd == NULL)
+ {
+ m_psh.nStartPage = nPage;
+ return true;
+ }
+ return (bool)SendMessage(PSM_SETCURSEL, nPage);
+}
+
+// Moves to Page
+template <class TBase>
+bool CPropertySheetT<TBase>::SetActivePage(CPropertyPageT<TBase>* pPage)
+{
+ ATLASSERT(pPage != NULL);
+
+ int nPage = GetPageIndex(pPage);
+ ATLASSERT(pPage >= 0);
+
+ return SetActivePage(nPage);
+}
+
+// Gets number of Page
+template <class TBase>
+int CPropertySheetT<TBase>::GetPageIndex(CPropertyPageT<TBase>* pPage)
+{
+ ATLASSERT(pPage != NULL);
+ for (int i = 0; i < GetPageCount(); i++)
+ {
+ if (GetPage(i) == pPage)
+ return i;
+ }
+ return -1; // pPage not found
+}
+
+// Get a Page from Array
+template <class TBase>
+CPropertyPageT<TBase>* CPropertySheetT<TBase>::GetPage(int nPage) const
+ { return m_pages[nPage]; }
+
+// Initdialog: Complete creation and setup for modeless etc...
+template <class TBase>
+LRESULT CPropertySheetT<TBase>::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // Change tab style if scrolling tabs desired (stacked tabs are default)
+ if (!m_bStacked)
+ ((CWindow)GetTabControl()).ModifyStyle(TCS_MULTILINE, TCS_SINGLELINE, 0);
+
+ // For Property Sheets
+ if (!IsWizard())
+ {
+ // Resize the tab control so the layout is less restrictive
+ HWND hWndTab = ::GetDlgItem(m_hWnd, AFX_IDC_TAB_CONTROL);
+ ATLASSERT(hWndTab != NULL);
+ RECT rcOld;
+ ::GetWindowRect(hWndTab, &rcOld);
+ ScreenToClient(&rcOld);
+ RECT rcNew = {0, 0, 0, 32};
+ ::MapDialogRect(m_hWnd, &rcNew);
+ if (rcNew.bottom < rcNew.bottom)
+ {
+ // Move tab control
+ int cyDiff = (rcOld.bottom - rcOld.top) - rcNew.bottom;
+ ::SetWindowPos(hWndTab, NULL, 0, 0, rcOld.right - rcOld.left, rcNew.bottom,
+ SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+ // Move buttons by similar amount
+ for (int i = 0; i < _countof(_PropSheetButtons); i++)
+ {
+ HWND hWndBtn = ::GetDlgItem(m_hWnd, _PropSheetButtons[i]);
+ if (hWndBtn != NULL)
+ {
+ ::GetWindowRect(hWndBtn, &rcOld);
+ ScreenToClient(&rcOld);
+ ::SetWindowPos(hWndBtn, NULL,
+ rcOld.left, rcOld.top - cyDiff,
+ 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+ }
+
+ // Resize property sheet itself similarly
+ GetWindowRect(&rcOld);
+ SetWindowPos(NULL, 0, 0, rcOld.right - rcOld.left, (rcOld.bottom - rcOld.top) - cyDiff,
+ SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+ }
+
+ // For Modeless Sheets
+ if (m_bModeless && !IsWizard())
+ {
+ // Layout property sheet so button area is not accounted for
+ RECT rcWnd;
+ GetWindowRect(&rcWnd);
+ RECT rcBtn;
+ HWND hWndBtn = ::GetDlgItem(m_hWnd, IDOK);
+ ATLASSERT(hWndBtn != NULL);
+ ::GetWindowRect(hWndBtn, &rcBtn);
+ SetWindowPos(NULL, 0, 0,
+ rcWnd.right - rcWnd.left,
+ (rcBtn.top - rcWnd.top) + ::GetSystemMetrics(SM_CYBORDER),
+ SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+ // Remove standard buttons for modeless dialogs
+ for (int i = 0; i < _countof(_PropSheetButtons); i++)
+ {
+ hWndBtn = ::GetDlgItem(m_hWnd, _PropSheetButtons[i]);
+ if (hWndBtn != NULL)
+ {
+ ::ShowWindow(hWndBtn, SW_HIDE);
+ ::EnableWindow(hWndBtn, FALSE);
+ }
+ }
+ }
+
+ // Center the property sheet relative to the parent window
+ if (!(GetStyle() & WS_CHILD))
+ CenterWindow();
+
+ // API implementation probably needs this message
+ bHandled = FALSE;
+ return 1;
+}
+
+// Gets the return code for DoModal
+template <class TBase>
+LRESULT CPropertySheetT<TBase>::OnEndCode(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ // API implementation probably needs this message
+ bHandled = FALSE;
+ m_nDlgRet = wID;
+ return 0;
+}
+
+
+// Are we a wizard?
+template <class TBase>
+bool CPropertySheetT<TBase>::IsWizard() const
+ { return ((m_psh.dwFlags & PSH_WIZARD) != 0); }
+
+// Return HWND of Tab Control
+template <class TBase>
+HWND CPropertySheetT<TBase>::GetTabControl() const
+ { ATLASSERT(::IsWindow(m_hWnd)); return (HWND)::SendMessage(m_hWnd, PSM_GETTABCONTROL, 0, 0); }
+
+// Press Button on Property Sheet
+template <class TBase>
+bool CPropertySheetT<TBase>::PressButton(int nButton)
+ { ATLASSERT(::IsWindow(m_hWnd)); return ::SendMessage(m_hWnd, PSM_PRESSBUTTON, nButton, 0) ? true : false; }
+
+// Get the Active Page
+template <class TBase>
+CPropertyPageT<TBase>* CPropertySheetT<TBase>::GetActivePage() const
+ { return GetPage(GetActiveIndex()); }
+
+// Change the Title
+template <class TBase>
+void CPropertySheetT<TBase>::SetTitle(LPCTSTR lpszText, UINT nStyle)
+{
+ ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid
+
+ // Set Internal State
+ if(m_szCaption && _tcslen(m_szCaption) < _tcslen(lpszText))
+ {
+ delete[] m_szCaption;
+ m_szCaption = NULL;
+ }
+
+ if(!m_szCaption)
+ m_szCaption = new TCHAR[_tcslen(lpszText) + 1];
+
+ _tcscpy(m_szCaption, lpszText);
+ m_psh.pszCaption = m_szCaption;
+
+ // Set the options
+ m_psh.dwFlags &= ~PSH_PROPTITLE;
+ m_psh.dwFlags |= nStyle;
+
+ if (m_hWnd != NULL)
+ {
+ // set external state
+ SendMessage(PSM_SETTITLE, nStyle, (LPARAM)lpszText);
+ }
+}
+
+// Make us a Wizard
+template <class TBase>
+void CPropertySheetT<TBase>::SetWizardMode()
+ { m_psh.dwFlags |= PSH_WIZARD; }
+
+template <class TBase>
+void CPropertySheetT<TBase>::SetHelp(bool bHelp)
+{
+ if(bHelp)
+ m_psh.dwFlags |= PSH_HASHELP;
+ else
+ m_psh.dwFlags &= ~(PSH_HASHELP);
+}
+
+// Set Text of Finish Button
+template <class TBase>
+void CPropertySheetT<TBase>::SetFinishText(LPCTSTR lpszText)
+ { ATLASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, PSM_SETFINISHTEXT, 0, (LPARAM)lpszText); }
+
+// Choose which buttons to have in Wizard
+template <class TBase>
+void CPropertySheetT<TBase>::SetWizardButtons(DWORD dwFlags)
+ { ATLASSERT(::IsWindow(m_hWnd)); ::PostMessage(m_hWnd, PSM_SETWIZBUTTONS, 0, dwFlags); }
+
+// Stacked Tabs
+template <class TBase>
+void CPropertySheetT<TBase>::EnableStackedTabs(BOOL bStacked)
+ { m_bStacked = bStacked; }
+
+typedef CPropertySheetT<CWindow> CPropertySheet;
+typedef CPropertyPageT<CWindow> CPropertyPage;
+
+#endif // !defined(AFX_PROPERTYPAGE_H__1508DAF4_7AD1_11D3_BF96_0020182B97FC__INCLUDED_)
diff --git a/win32/common/atlwinhk.h b/win32/common/atlwinhk.h
new file mode 100644
index 0000000..4dddf82
--- /dev/null
+++ b/win32/common/atlwinhk.h
@@ -0,0 +1,151 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * VERSION
+ * 2.2.0b
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef __ATLWINHK_H__
+#define __ATLWINHK_H__
+
+/////////////////////////////////////////////////////////////////////////
+// Hooks an CWindowImpl to windows that the API or other code creates
+// By Stef: 06/10/99
+
+
+// Use this macro in the class definition and pass class name
+// as first param
+#define DECLARE_HOOK_AND_SUBCLASS(Class) \
+ HHOOK m_hHookCur; \
+ static LRESULT CALLBACK HookCreateProc(int nCode, \
+ WPARAM wParam, \
+ LPARAM lParam) \
+ { \
+ Class* pThis = (Class*) _Module.ExtractCreateWndData(); \
+ \
+ if (nCode != HCBT_CREATEWND) \
+ { \
+ /*Add it back again*/ \
+ _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis); \
+ /*wait for HCBT_CREATEWND just pass others on...*/ \
+ return CallNextHookEx(pThis->m_hHookCur, nCode, wParam, lParam); \
+ } \
+ \
+ pThis->SubclassWindow((HWND)wParam); \
+ \
+ UnhookWindowsHookEx(pThis->m_hHookCur); \
+ HHOOK hHookCur = pThis->m_hHookCur; \
+ pThis->m_hHookCur = NULL; \
+ \
+ return CallNextHookEx(hHookCur, nCode, wParam, lParam); \
+ }
+
+// Use this *immediately* before the code that creates the window
+// It will subclass the first window that's created by that thread
+// so add immediately before.
+#define HOOK_AND_SUBCLASS_NEXT() \
+ ((m_hHookCur = SetWindowsHookEx(WH_CBT, HookCreateProc, NULL, ::GetCurrentThreadId())) == NULL)
+
+const LPCTSTR kDialogClass = (LPCTSTR)0x00008002;
+
+template<class _Class>
+class CHookWindow
+{
+public:
+ CHookWindow()
+ {
+ m_hHookCur = NULL;
+ m_szHookClass = NULL;
+ m_szHookName = NULL;
+ }
+
+ bool SubclassNext(LPCTSTR szClass = NULL, LPCTSTR szName = NULL)
+ {
+ _Class* pThis = (_Class*)this;
+ _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis);
+
+ m_hHookCur = SetWindowsHookEx(WH_CBT, HookCreateProc, NULL, ::GetCurrentThreadId());
+
+ if(m_hHookCur)
+ {
+ m_szHookClass = szClass;
+ m_szHookName = szName;
+ }
+
+ return m_hHookCur == NULL;
+ }
+
+ static LRESULT CALLBACK HookCreateProc(int nCode, WPARAM wParam, LPARAM lParam)
+ {
+ _Class* pThis = (_Class*) _Module.ExtractCreateWndData();
+ HHOOK hHookCur = pThis->m_hHookCur;
+
+ bool bSkip = false;
+
+ if(nCode != HCBT_CREATEWND)
+ {
+ bSkip = true;
+ }
+ else
+ {
+ CBT_CREATEWND* pCreate = (CBT_CREATEWND*)lParam;
+
+ if(pThis->m_szHookClass)
+ {
+ // If it's not a pointer (for at least two bytes)
+ if(IsBadReadPtr(pCreate->lpcs->lpszClass, 2) || IsBadReadPtr(pThis->m_szHookClass, 2))
+ // Then just compare values
+ bSkip = pCreate->lpcs->lpszClass != pThis->m_szHookClass;
+
+ else
+ // Otherwise compare strings
+ bSkip = _tcsicmp(pCreate->lpcs->lpszClass, pThis->m_szHookClass) != 0;
+ }
+
+ if(pThis->m_szHookName)
+ {
+ if(IsBadReadPtr(pCreate->lpcs->lpszName, _tcslen(pThis->m_szHookName)) ||
+ _tcsicmp(pCreate->lpcs->lpszName, pThis->m_szHookName))
+ bSkip = true;
+ }
+ }
+
+ if(bSkip)
+ {
+ /*Add it back again*/
+ _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis);
+ }
+ else
+ {
+ pThis->SubclassWindow((HWND)wParam);
+
+ UnhookWindowsHookEx(pThis->m_hHookCur);
+ pThis->m_hHookCur = NULL;
+ }
+
+ return CallNextHookEx(hHookCur, nCode, wParam, lParam);
+ }
+
+protected:
+ HHOOK m_hHookCur;
+ LPCTSTR m_szHookName;
+ LPCTSTR m_szHookClass;
+};
+
+
+#endif //__ATLWINHK_H__
diff --git a/win32/common/droplet.cpp b/win32/common/droplet.cpp
new file mode 100644
index 0000000..e796f49
--- /dev/null
+++ b/win32/common/droplet.cpp
@@ -0,0 +1,226 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include <stdafx.h>
+#include "lib/rep.h"
+#include "common/binfile.h"
+#include "common/repfile.h"
+#include "Droplet.h"
+
+// (Con|De)struction: --------------------------------------------
+
+Droplet::Droplet()
+{
+ m_keepBackups = false;
+ memset(&m_ctx, 0, sizeof(m_ctx));
+}
+
+Droplet::~Droplet()
+{
+ repFree(&m_ctx);
+}
+
+
+// All error handling jumps to 'cleanup' where wrapping up loose
+// ends is done
+#define RETURN(v) { ret = v; goto cleanup; }
+
+
+// save: ---------------------------------------------------
+// Saves a droplet to a file. The file must already exist
+// and must be an executable
+
+bool Droplet::save(LPCTSTR fileName)
+{
+ HANDLE update = NULL;
+ void* data = NULL;
+ BFILE h = NULL;
+ bool ret = true;
+
+ {
+ if(!m_ctx.script.ops)
+ RETURN(false);
+
+ // Make the rep binfile
+ bfval val;
+ BFILE h = bfStartMem(NULL, 0, BF_REALLOC);
+ if(!h) RETURN(false);
+
+ // Write out the headers
+ repfWriteHeader(h);
+
+ // Write to it now
+ if(m_ctx.block != 0)
+ bfWriteInt(h, REPVAL_BUFSIZE, m_ctx.block);
+
+ bfWriteInt(h, DROPVAL_BACKUPS, m_keepBackups ? 1 : 0);
+
+ // Write the script out
+ val.id = REPVAL_SCRIPT;
+ val.len = m_ctx.script.len;
+ val.type = BINTYPE_DATA;
+ bfWriteValue(h, &val, m_ctx.script.ops);
+
+ if(!m_title.empty())
+ bfWriteString(h, DROPVAL_TITLE, m_title.c_str());
+
+ // Done
+ bfWriteEnd(h);
+ if(bfError(h)) RETURN(false);
+
+ size_t len = bfCount(h);
+ data = bfInternal(h);
+ bfClose(h);
+ h = NULL;
+
+ // Now actually modify the EXE
+ update = BeginUpdateResource(fileName, FALSE);
+ if(!update) RETURN(false);
+
+ if(!UpdateResource(update, DROP_RESOURCE_TYPE, DROP_RESOURCE_ID,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), data, len)
+ || !EndUpdateResource(update, FALSE))
+ RETURN(false);
+
+ update = NULL;
+ }
+
+cleanup:
+ while(data)
+ {
+ free(data);
+
+ if(h == NULL)
+ break;
+
+ data = bfInternal(h);
+ bfClose(h);
+ h = NULL;
+ }
+
+ if(update)
+ EndUpdateResource(update, TRUE);
+
+ return true;
+}
+
+
+// load: ---------------------------------------------------------------
+// Load a droplet from a file
+
+bool Droplet::load(LPCTSTR fileName)
+{
+ HMODULE module = LoadLibrary(fileName);
+ if(!module)
+ return false;
+
+ bool ret = load(GetModuleHandle(fileName));
+
+ FreeLibrary(module);
+
+ return ret;
+}
+
+
+// load: ---------------------------------------------------------------
+// Load a droplet from a loaded module
+
+bool Droplet::load(HMODULE module)
+{
+ bool ret = true;
+ BFILE h = NULL;
+
+ {
+ // In case we're called twice
+ repFree(&m_ctx);
+
+ // Load the resource
+ HRSRC hRsrc = FindResourceEx(module, DROP_RESOURCE_TYPE, DROP_RESOURCE_ID,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
+ if(!hRsrc) RETURN(false);
+
+ HGLOBAL hGlobal = LoadResource(module, hRsrc);
+ if(!hGlobal) RETURN(false);
+
+ void* data = LockResource(hGlobal);
+ if(!data) RETURN(false);
+
+ ::SetLastError(0);
+
+ // And now read it
+ h = bfStartMem(data, SizeofResource(module, hRsrc), 0);
+ if(!h) RETURN(false);
+
+ // Check the format
+ if(!repfReadHeader(h))
+ RETURN(false);
+
+ bfval val;
+
+ while(bfReadValueInfo(h, &val))
+ {
+ switch(val.id)
+ {
+ case REPVAL_BUFSIZE:
+ bfReadValueData(h, &val, &(m_ctx.block));
+ continue;
+
+ case DROPVAL_BACKUPS:
+ {
+ long value;
+ bfReadValueData(h, &val, &value);
+ m_keepBackups = value == 0 ? false : true;
+ }
+ continue;
+
+ case REPVAL_SCRIPT:
+ {
+ // Script must have some length
+ if(val.len == 0)
+ RETURN(false);
+
+ m_ctx.script.ops = (byte*)malloc(val.len);
+ if(!m_ctx.script.ops)
+ RETURN(false);
+
+ bfReadValueData(h, &val, m_ctx.script.ops);
+ m_ctx.script.len = val.len;
+ }
+ continue;
+
+ case DROPVAL_TITLE:
+ {
+ bfReadValueData(h, &val, m_title.get_buffer(val.len));
+ m_title.release_buffer();
+ }
+ continue;
+
+ }
+
+ bfSkipValueData(h, &val);
+ }
+ }
+
+cleanup:
+ if(h)
+ bfClose(h);
+
+ return ret;
+}
+
diff --git a/win32/common/droplet.h b/win32/common/droplet.h
new file mode 100644
index 0000000..e98725e
--- /dev/null
+++ b/win32/common/droplet.h
@@ -0,0 +1,98 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+
+#ifndef __DROPLET_H__
+#define __DROPLET_H__
+
+
+// The resources in the droplet
+#define DROP_RESOURCE_TYPE _T("REP")
+#define DROP_RESOURCE_ID _T("SCRIPT")
+#define DROP_RESOURCE_FILE _T("DROPLET")
+
+// Some extra binfile tags
+#define DROPVAL_TITLE 0x0101
+#define DROPVAL_BACKUPS 0x0102
+
+#include "lib/rlib.h"
+#include "lib/rep.h"
+
+
+// Droplet: ---------------------------------------------------------------
+// A droplet provides the saving/loading/loaded functionality of the
+// droplet. Replaces are not done here
+
+class Droplet
+{
+public:
+ Droplet();
+ ~Droplet();
+
+ // Load a droplet from a file
+ bool load(LPCTSTR fileName);
+
+ // Load a droplet from a loaded executable
+ bool load(HMODULE module);
+
+ // Save a droplet out to an existing executable
+ bool save(LPCTSTR fileName);
+
+
+ // Get the internal rlib stream
+ r_context& getContext()
+ { return m_ctx; }
+
+ // Is there a valid script loaded
+ bool hasScript()
+ { return m_ctx.script.ops != NULL; }
+
+ // Get dialog title stored in droplet
+ string getTitle()
+ { return m_title; }
+
+ // Set dialog title stored in droplet
+ void setTitle(astring& title)
+ { m_title = title; }
+
+ // Get the buffer size stored in droplet
+ // 0 = process entire file
+ size_t getBuffSize()
+ { return m_ctx.block; }
+
+ // Set the buffer size to be stored in droplet
+ void setBuffSize(size_t buffSize)
+ { m_ctx.block = buffSize; }
+
+ // Should backups be kept?
+ bool keepBackups()
+ { return m_keepBackups; }
+
+ // Set backup options for droplet
+ void setBackups(bool backups)
+ { m_keepBackups = backups; }
+
+protected:
+ r_context m_ctx;
+
+ astring m_title; // The dialog title
+ bool m_keepBackups; // Should backups be kept?
+};
+
+#endif //__DROPLET_H__ \ No newline at end of file
diff --git a/win32/common/errutil.cpp b/win32/common/errutil.cpp
new file mode 100644
index 0000000..302b4fa
--- /dev/null
+++ b/win32/common/errutil.cpp
@@ -0,0 +1,106 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include "stdafx.h"
+#include "rliberr.h"
+#include "errutil.h"
+
+// rlibError: -------------------------------------------------------------
+// Displays errors from rlib. Assumes we have the appropriate
+// error codes compiled in as resources
+
+HRESULT rlibError(HWND parent, int code, r_script* script)
+{
+ ASSERT(code < 0);
+ USES_CONVERSION;
+
+ LPVOID lpMsgBuf;
+ HRESULT hr = HRESULT_FROM_RLIB(code);
+ string message;
+
+ DWORD dwRet = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK, GetModuleHandle(NULL), hr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR)&lpMsgBuf, 0, NULL);
+ if(dwRet && lpMsgBuf)
+ {
+ message.append((LPTSTR)lpMsgBuf);
+
+ // Free the buffer.
+ ::LocalFree(lpMsgBuf);
+
+ // If there was a specific error message then tack that on
+ if(script->error)
+ {
+ message.append(_T("\n\n"));
+ message.append(A2T(script->error));
+ }
+
+ // If there's an error line then tack that on
+ if(script->errline != 0)
+ {
+ string line;
+ line.format(_T(" (near line %d)"), script->errline);
+ message.append(line);
+ }
+
+ MessageBox(parent, message.c_str(), _T("Rep Droplet"), MB_OK | MB_ICONSTOP);
+ }
+
+ return hr;
+}
+
+
+// errorMessage: -----------------------------------------------------------
+// Displays standard windows errors.
+
+HRESULT errorMessage(HWND parent, HRESULT hr, LPCTSTR format, ...)
+{
+ string message;
+
+ va_list ap;
+ va_start(ap, format);
+
+ message.format_v(format, ap);
+
+ va_end(ap);
+
+ if(FAILED(hr))
+ {
+ LPVOID lpMsgBuf;
+
+ DWORD dwRet = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, hr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf, 0, NULL);
+ if(dwRet && lpMsgBuf)
+ {
+ message.append(_T("\n\n"));
+ message.append((LPTSTR)lpMsgBuf);
+ message.resize(message.size() - 2); // Take off new line
+
+ // Free the buffer.
+ ::LocalFree(lpMsgBuf);
+ }
+ }
+
+ MessageBox(parent, message.c_str(), _T("Rep Droplet"), MB_OK | MB_ICONSTOP);
+
+ return hr == S_OK ? E_FAIL : hr;
+}
diff --git a/win32/common/errutil.h b/win32/common/errutil.h
new file mode 100644
index 0000000..0804149
--- /dev/null
+++ b/win32/common/errutil.h
@@ -0,0 +1,32 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef __ERRUTIL_H__
+#define __ERRUTIL_H__
+
+#include "lib/rlib.h"
+
+// Display a standard windows error message
+HRESULT errorMessage(HWND parent, HRESULT hr, LPCTSTR format, ...);
+
+// Display an rlib error message
+HRESULT rlibError(HWND parent, int code, r_script* script);
+
+
+#endif //__ERRUTIL_H__ \ No newline at end of file
diff --git a/win32/common/mystring.h b/win32/common/mystring.h
new file mode 100644
index 0000000..470ac3c
--- /dev/null
+++ b/win32/common/mystring.h
@@ -0,0 +1,536 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#if !defined(_MYSTRING_H_)
+#define _MYSTRING_H_
+
+//////////////////////////////////////////////////////////////////////////////
+
+#include <tchar.h>
+
+#include <stdarg.h>
+
+#include <string>
+#include <locale>
+
+#pragma warning(push)
+#pragma warning(disable:4786) // Disable warning for names > 256
+
+//////////////////////////////////////////////////////////////////////////////
+
+template<typename T>
+class stringT : public std::basic_string<T> // T should be either char or wchar_t
+{
+public:
+ // Constructors
+ stringT()
+ : std::basic_string<T>()
+ { }
+
+ stringT(const stringT<T>& strInput)
+ : std::basic_string<T>(strInput)
+ { }
+
+
+ stringT(const std::basic_string<T>& strInput)
+ : std::basic_string<T>(strInput)
+ { }
+
+ stringT(const std::basic_string<T>& strInput, size_type pos, size_type n)
+ : std::basic_string<T>(strInput, pos, n)
+ { }
+
+ stringT(const std::basic_string<T>::const_iterator first,
+ const std::basic_string<T>::const_iterator last)
+ : std::basic_string<T>(first, last)
+ { }
+
+
+ stringT(const T* strInput)
+ : std::basic_string<T>(strInput)
+ { }
+
+
+ stringT(const T* strInput, size_type n)
+ : std::basic_string<T>(strInput, n)
+ { }
+
+
+#ifdef _INC_COMDEF
+ stringT(_bstr_t bstr)
+ {
+ (*this) = (const T*)bstr;
+ }
+#endif
+
+ stringT(T ch, int nRepeat = 1)
+ : std::basic_string<T>(nRepeat, ch)
+ { }
+
+
+ // Other Conversions
+ stringT<T>& make_upper()
+ {
+ std::ctype<T> c;
+ T* p = get_buffer();
+ c.toupper(p, p + size());
+ release_buffer();
+ return *this;
+ }
+
+ stringT<T> upper() const
+ {
+ stringT<T> sTmp(*this);
+ sTmp.make_upper();
+ return sTmp;
+ }
+
+ stringT<T>& make_lower()
+ {
+ std::ctype<T> c;
+ T* p = get_buffer();
+ c.tolower(p, p + size());
+ release_buffer();
+ return *this;
+ }
+
+ stringT<T> lower() const
+ {
+ stringT<T> sTmp(*this);
+ sTmp.make_lower();
+ return sTmp;
+ }
+
+ void trim_left()
+ {
+ // TODO: Optimize
+ while(!empty() && _istspace(at(0)))
+ erase(0, 1);
+ }
+
+ void trim_right()
+ {
+ // TODO: Optimize
+ while(!empty() && _istspace(at(length()-1)))
+ erase(length() - 1, 1);
+ }
+
+ void trim()
+ {
+ trim_left();
+ trim_right();
+ }
+
+ const stringT<T>& format(const T* pszFormat, ...)
+ {
+ va_list vl;
+ va_start(vl, pszFormat);
+ format_v(pszFormat, vl);
+ va_end(vl);
+
+ return *this;
+ }
+
+#ifdef _WINDOWS_
+
+ const stringT<T>& format(HINSTANCE hInst, UINT nID, ... )
+ {
+ stringT<T> sTemp;
+ sTemp.load_string(hInst, nID);
+
+ va_list vl;
+ va_start(vl, nID);
+ format_v(sTemp, vl);
+ va_end(vl);
+
+ return *this;
+ }
+
+#ifdef __ATLBASE_H__
+ const stringT<T>& format(UINT nID, ... )
+ {
+ stringT<T> sTemp;
+ sTemp.load_string(nID);
+
+ va_list vl;
+ va_start(vl, nID);
+ format_v(sTemp, vl);
+ va_end(vl);
+
+ return *this;
+ }
+#endif // __ATLBASE_H__
+
+#endif
+
+ void format_v(const char* pszFormat, va_list vl)
+ {
+ // Copied Code....
+
+ // Doesn't have all the features of CString::Format()
+ T* pszTemp = NULL;
+ size_t nBufferSize = 32;
+ int nRetVal = -1;
+
+ do
+ {
+ // Double the buffer size for next time around
+ nBufferSize += nBufferSize;
+ delete [] pszTemp;
+ pszTemp = new T [nBufferSize];
+ nRetVal = _vsnprintf(pszTemp, nBufferSize, pszFormat, vl);
+ } while (nRetVal < 0);
+
+ *this = pszTemp;
+ delete [] pszTemp;
+
+ return;
+ }
+
+ void format_v(const wchar_t* pszFormat, va_list vl)
+ {
+ // Copied Code....
+
+ // Doesn't have all the features of CString::Format()
+ T* pszTemp = NULL;
+ size_t nBufferSize = 32;
+ int nRetVal = -1;
+
+ do
+ {
+ // Double the buffer size for next time around
+ nBufferSize += nBufferSize;
+ delete [] pszTemp;
+ pszTemp = new T [nBufferSize];
+ nRetVal = _vsnwprintf(pszTemp, nBufferSize, pszFormat, vl);
+ } while (nRetVal < 0);
+
+ *this = pszTemp;
+ delete [] pszTemp;
+
+ return;
+ }
+
+ int replace(const std::basic_string<T>& sFind, const std::basic_string<T>& sReplace, bool bMultiple = true, size_type nStart = 0)
+ {
+ stringT<T> sTemp = *this;
+ int nReplaced = 0;
+
+ if((nStart = sTemp.find(sFind, nStart)) != npos)
+ {
+ sTemp.erase(nStart, sFind.length());
+ sTemp.insert(nStart, sReplace);
+ nReplaced++;
+ }
+
+ while(bMultiple && (nStart = sTemp.find(sFind, nStart + 1)) != npos)
+ {
+ sTemp.erase(nStart, sFind.length());
+ sTemp.insert(nStart, sReplace);
+ nReplaced++;
+ }
+
+ *this = sTemp;
+ return nReplaced;
+ }
+
+ // Operators
+
+ T operator[](int nIndex) const
+ { return at(nIndex); };
+
+#ifdef _INC_COMDEF
+ operator _bstr_t() const
+ { return _bstr_t(c_str()); };
+#endif
+
+ operator const T*() const
+ { return c_str(); };
+
+
+ // Buffer Operations
+ // Derived code from MFC CString
+ T* get_buffer(size_t sz = npos)
+ {
+ if(sz == npos)
+ sz = size();
+
+ resize(sz + 1);
+ // Make sure we generate a write command
+ // so we have no extra references
+ // TODO: Does basic_string use reference counting?
+ // (much later) A: Yes it does! Reference is in the bytes before data
+ at(sz) = 0;
+ return const_cast<T*>(data());
+ }
+
+ void release_buffer()
+ {
+ if(!empty())
+ {
+ // Make sure we generate a write command
+ // Find the null terminated end
+ for(string::size_type i = 0; i < capacity() && i < size(); i++)
+ if(at(i) == 0)
+ break;
+
+ ASSERT(i != capacity());
+ resize(i);
+ }
+ }
+
+ void clear()
+ { resize(0); }
+
+#ifdef _WINDOWS_
+ bool load_string(HINSTANCE hInst, unsigned int nID)
+ {
+ string::size_type nSize = 0x80;
+ do
+ {
+ release_buffer();
+ nSize *= 2;
+ }
+ while(load_string(hInst, nID, get_buffer(nSize), nSize) == nSize);
+
+ release_buffer();
+ return nSize > 0;
+ }
+#endif // WIN32
+
+#ifdef __ATLBASE_H__
+ bool load_string(unsigned int nID)
+ {
+ string::size_type nSize = 0x80;
+ do
+ {
+ release_buffer();
+ nSize *= 2;
+ }
+ while(load_string(_Module.m_hInstResource, nID, get_buffer(nSize), nSize) == nSize);
+
+ release_buffer();
+ return nSize > 0;
+ }
+#endif // __ATLBASE_H__
+
+
+protected:
+
+#ifdef _WINDOWS_
+
+ static int load_string(HINSTANCE hInst, UINT nID, char* pBuff, size_t nSize)
+ {
+ return ::LoadStringA(hInst, nID, pBuff, nSize);
+ }
+
+ static int load_string(HINSTANCE hInst, UINT nID, wchar_t* pBuff, size_t nSize)
+ {
+#ifdef _UNICODE
+ return ::LoadStringW(hInst, nID, pBuff, nSize);
+#else
+ char* pABuff = new char[nSize];
+ if(!pABuff) return 0;
+
+ int nRet = load_string(hInst, nID, pABuff, nSize);
+ if(nRet)
+ {
+ pBuff[0] = L'\0';
+ MultiByteToWideChar(GetACP(), 0, pABuff, -1, pBuff, nSize);
+ }
+
+ return nRet;
+#endif
+ }
+
+
+
+#endif
+
+
+};
+
+ #ifndef _UNICODE
+ typedef stringT<char> string;
+ #else
+ typedef stringT<wchar_t> string;
+ #endif
+
+ typedef stringT<char> astring;
+ typedef stringT<wchar_t> wstring;
+
+
+template<typename T>
+class cstringT
+{
+public:
+ cstringT()
+ { clear(); };
+ cstringT(const T* ptr, size_t len)
+ { set(ptr, len); };
+
+ operator stringT<T>() const
+ {
+ if(_Ptr)
+ return stringT<T>(_Ptr, _Len);
+ else
+ return stringT<T>();
+ };
+
+ bool is_null() const
+ { return _Ptr ? false : true; }
+ // TODO: Maybe some validity checks
+ void set(const T* ptr, size_t len)
+ { _Ptr = ptr; _Len = len; }
+ void clear()
+ { _Ptr = 0; _Len = 0; }
+
+protected:
+ const T* _Ptr;
+ size_t _Len;
+};
+
+
+ #ifndef _UNICODE
+ typedef cstringT<char> cstring;
+ #else
+ typedef cstringT<wchar_t> cstring;
+ #endif
+
+ typedef cstringT<char> castring;
+ typedef cstringT<wchar_t> cwstring;
+
+
+
+#include <vector>
+#include <algorithm>
+
+template<typename S>
+class string_arrayT : public std::vector<S>
+{
+public:
+ string_arrayT(const std::vector<S> & x)
+ : std::vector<S>(x) {};
+ string_arrayT(string_arrayT & x)
+ : std::vector<S>(x) {};
+ string_arrayT(std::vector<S>::const_iterator first, std::vector<S>::const_iterator last, const std::vector<S>::allocator_type& al = std::vector<S>::allocator_type())
+ : std::vector<S>(first, last, al) {};
+ explicit string_arrayT(const const std::vector<S>::allocator_type& al = std::vector<S>::allocator_type())
+ : std::vector<S>(al) {};
+ explicit string_arrayT(std::vector<S>::size_type n, const std::vector<S>::value_type& v = std::vector<S>::value_type(), const std::vector<S>::allocator_type& al = std::vector<S>::allocator_type())
+ : std::vector<S>(n, v, al) {};
+
+ std::vector<S>::size_type split(S sIn, S sDelim, bool bTrim = false)
+ {
+ S::size_type start = 0;
+ S::size_type ed = 0;
+ std::vector<S>::size_type cnt = 0;
+ S::size_type lenDelim = sDelim.size();
+ S sTemp;
+
+ if(lenDelim == 0)
+ {
+ if(bTrim)
+ sIn.trim();
+ push_back(sIn);
+ return 1;
+ }
+
+ while(ed != string::npos)
+ {
+ ed = sIn.find(sDelim, start);
+ if(ed == string::npos)
+ sTemp = sIn.substr(start);
+ else
+ sTemp = sIn.substr(start, ed - start);
+
+ if(bTrim)
+ sTemp.trim();
+
+ push_back(sTemp);
+
+ cnt++;
+
+ start = ed + lenDelim;
+ }
+
+ return cnt;
+ }
+
+ S join(S sDelim) const
+ {
+ S sTemp;
+ const_iterator it = begin();
+ const_iterator ed = end();
+
+ while(it != ed)
+ {
+ sTemp += *it;
+ it++;
+ }
+
+ return sTemp;
+ }
+
+ class no_case
+ {
+ public:
+ no_case(const S& s) : _str(s)
+ { _str.make_lower(); }
+
+ bool operator()(const S& s)
+ { return s.lower() == _str; }
+ protected:
+ S _str;
+ };
+
+ bool has(S sVal, bool bCase = true) const
+ { return find(sVal, bCase) != end(); }
+
+ const_iterator find(S sVal, bool bCase = true) const
+ {
+ if(bCase)
+ return std::find(begin(), end(), sVal);
+ else
+ {
+ no_case fndr(sVal);
+ return std::find_if(begin(), end(), fndr);
+ }
+ }
+
+ iterator find(S sVal, bool bCase = true)
+ {
+ if(bCase)
+ return std::find(begin(), end(), sVal);
+ else
+ {
+ no_case fndr(sVal);
+ return std::find_if(begin(), end(), fndr);
+ }
+ }
+};
+
+typedef string_arrayT< string > string_array;
+typedef string_arrayT< wstring > wstring_array;
+
+//////////////////////////////////////////////////////////////////////////////
+
+#pragma warning( pop )
+
+#endif // !defined(_MYSTRING_H_)
diff --git a/win32/common/rep.ico b/win32/common/rep.ico
new file mode 100644
index 0000000..51cf5f8
--- /dev/null
+++ b/win32/common/rep.ico
Binary files differ
diff --git a/win32/common/rliberr.h b/win32/common/rliberr.h
new file mode 100644
index 0000000..8fe3a80
--- /dev/null
+++ b/win32/common/rliberr.h
@@ -0,0 +1,136 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * VERSION
+ * 2.2.0b
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef _RLIBERR_H_
+#define _RLIBERR_H_
+
+#ifndef _WINERROR_
+ #error Include winerror.h first.
+#endif
+
+#define HRESULT_FROM_RLIB(code) \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RLIB, abs(code))
+
+/* ------------------------------------------------------------------------ *\
+ Rlib Errors
+\* ------------------------------------------------------------------------ */
+//
+// Values are 32 bit values layed out as follows:
+//
+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +---+-+-+-----------------------+-------------------------------+
+// |Sev|C|R| Facility | Code |
+// +---+-+-+-----------------------+-------------------------------+
+//
+// where
+//
+// Sev - is the severity code
+//
+// 00 - Success
+// 01 - Informational
+// 10 - Warning
+// 11 - Error
+//
+// C - is the Customer code flag
+//
+// R - is a reserved bit
+//
+// Facility - is the facility code
+//
+// Code - is the facility's status code
+//
+//
+// Define the facility codes
+//
+#define FACILITY_RLIB 0x196
+
+
+//
+// Define the severity codes
+//
+
+
+//
+// MessageId: RLIB_E_NOMEM
+//
+// MessageText:
+//
+// Out of Memory.
+//
+#define RLIB_E_NOMEM ((HRESULT)0x81960001L)
+
+//
+// MessageId: RLIB_E_SYNTAX
+//
+// MessageText:
+//
+// Rep script syntax error.
+//
+#define RLIB_E_SYNTAX ((HRESULT)0x81960002L)
+
+//
+// MessageId: RLIB_E_REGEXP
+//
+// MessageText:
+//
+// Regular expression syntax error.
+//
+#define RLIB_E_REGEXP ((HRESULT)0x81960003L)
+
+//
+// MessageId: RLIB_E_LOOP
+//
+// MessageText:
+//
+// Rep encountered an endless loop.
+//
+#define RLIB_E_LOOP ((HRESULT)0x81960004L)
+
+//
+// MessageId: RLIB_E_USER
+//
+// MessageText:
+//
+// User defined error.
+//
+#define RLIB_E_USER ((HRESULT)0x81960005L)
+
+//
+// MessageId: RLIB_E_IOERR
+//
+// MessageText:
+//
+// There was an error reading or writing the data.
+//
+#define RLIB_E_IOERR ((HRESULT)0x81960006L)
+
+//
+// MessageId: RLIB_E_INVARG
+//
+// MessageText:
+//
+// Programmer Error: Invalid argument.
+//
+#define RLIB_E_INVARG ((HRESULT)0x8196000AL)
+
+#endif // _RLIBERR_H_ \ No newline at end of file
diff --git a/win32/common/rliberr.mc b/win32/common/rliberr.mc
new file mode 100644
index 0000000..50ac61f
--- /dev/null
+++ b/win32/common/rliberr.mc
@@ -0,0 +1,106 @@
+;/*
+; * AUTHOR
+; * N. Nielsen
+; *
+; * VERSION
+; * 2.2.0b
+; *
+; * LICENSE
+; * This software is in the public domain.
+; *
+; * The software is provided "as is", without warranty of any kind,
+; * express or implied, including but not limited to the warranties
+; * of merchantability, fitness for a particular purpose, and
+; * noninfringement. In no event shall the author(s) be liable for any
+; * claim, damages, or other liability, whether in an action of
+; * contract, tort, or otherwise, arising from, out of, or in connection
+; * with the software or the use or other dealings in the software.
+; *
+; * SUPPORT
+; * Send bug reports to: <nielsen@memberwebs.com>
+; */
+;
+;#ifndef _RLIBERR_H_
+;#define _RLIBERR_H_
+;
+;#ifndef _WINERROR_
+; #error Include winerror.h first.
+;#endif
+;
+;#define HRESULT_FROM_RLIB(code) \
+; MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RLIB, abs(code))
+;
+
+SeverityNames=(
+ Success=0x0
+ Error=0x2
+ )
+
+
+MessageIdTypedef=HRESULT
+FacilityNames=(
+ System=0FF
+ Rlib=406:FACILITY_RLIB
+ )
+
+;/* ------------------------------------------------------------------------ *\
+; Rlib Errors
+;\* ------------------------------------------------------------------------ */
+
+MessageId=1
+Severity=Error
+Facility=Rlib
+SymbolicName=RLIB_E_NOMEM
+Language=English
+Out of Memory.
+.
+
+MessageId=2
+Severity=Error
+Facility=Rlib
+SymbolicName=RLIB_E_SYNTAX
+Language=English
+Rep script syntax error.
+.
+
+MessageId=3
+Severity=Error
+Facility=Rlib
+SymbolicName=RLIB_E_REGEXP
+Language=English
+Regular expression syntax error.
+.
+
+MessageId=4
+Severity=Error
+Facility=Rlib
+SymbolicName=RLIB_E_LOOP
+Language=English
+Rep encountered an endless loop.
+.
+
+MessageId=5
+Severity=Error
+Facility=Rlib
+SymbolicName=RLIB_E_USER
+Language=English
+User defined error.
+.
+
+MessageId=6
+Severity=Error
+Facility=Rlib
+SymbolicName=RLIB_E_IOERR
+Language=English
+There was an error reading or writing the data.
+.
+
+MessageId=10
+Severity=Error
+Facility=Rlib
+SymbolicName=RLIB_E_INVARG
+Language=English
+Programmer Error: Invalid argument.
+.
+
+;#endif // _RLIBERR_H_ \ No newline at end of file
diff --git a/win32/droplet/Makefile.am b/win32/droplet/Makefile.am
new file mode 100644
index 0000000..5a5ca0a
--- /dev/null
+++ b/win32/droplet/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST = droplet.dsp droplet.rc dropletmain.cpp progressdlg.h progressdlg.cpp replace.cpp replace.h resource.h stdafx.h stdafx.cpp temp.rep
+
diff --git a/win32/droplet/droplet.dsp b/win32/droplet/droplet.dsp
new file mode 100644
index 0000000..579b546
--- /dev/null
+++ b/win32/droplet/droplet.dsp
@@ -0,0 +1,223 @@
+# Microsoft Developer Studio Project File - Name="droplet" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=droplet - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "droplet.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "droplet.mak" CFG="droplet - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "droplet - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "droplet - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "droplet - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../.." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libpcre.a kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x500000" /subsystem:windows /debug /machine:I386 /out:"../debug/droplet.exe" /pdbtype:sept /libpath:"..\win32\pcre\lib\\" /libpath:"..\pcre\lib\\"
+
+!ELSEIF "$(CFG)" == "droplet - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /W3 /GX /O1 /I "../.." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 libpcre.a kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x500000" /subsystem:windows /machine:I386 /out:"../release/droplet.exe" /libpath:"..\pcre\lib\\" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "droplet - Win32 Debug"
+# Name "droplet - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\common\droplet.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\droplet.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\dropletmain.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\common\errutil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ProgressDlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Replace.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\common\rliberr.mc
+
+!IF "$(CFG)" == "droplet - Win32 Debug"
+
+# Begin Custom Build
+InputPath=..\common\rliberr.mc
+InputName=rliberr
+
+"$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ mc $(InputPath)
+ copy $(InputName).h ..\Common
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "droplet - Win32 Release"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build
+InputPath=..\common\rliberr.mc
+InputName=rliberr
+
+"$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ mc $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\temp.rep
+
+!IF "$(CFG)" == "droplet - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\temp.rep
+
+"temp.cmp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ..\debug\repc.exe temp.rep temp.cmp
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "droplet - Win32 Release"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build
+InputPath=.\temp.rep
+
+"temp.cmp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ..\release\repc.exe temp.rep temp.cmp
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\common\droplet.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ProgressDlg.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Replace.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\MSG00001.bin
+# End Source File
+# Begin Source File
+
+SOURCE=..\common\rep.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\temp.cmp
+# End Source File
+# End Group
+# End Target
+# End Project
+# Section droplet : {00000000-0000-0000-0000-800000800000}
+# 1:15:IDD_PROGRESSDLG:101
+# End Section
diff --git a/win32/droplet/droplet.rc b/win32/droplet/droplet.rc
new file mode 100644
index 0000000..f0254d7
--- /dev/null
+++ b/win32/droplet/droplet.rc
@@ -0,0 +1,197 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// REP
+//
+
+SCRIPT REP DISCARDABLE "temp.cmp"
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,3,0,1
+ PRODUCTVERSION 2,3,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Nate Nielsen\0"
+ VALUE "FileDescription", "rep droplet\0"
+ VALUE "FileVersion", "2, 3, 0, 1\0"
+ VALUE "InternalName", "droplet\0"
+ VALUE "LegalCopyright", "Copyright 2002, Nate Nielsen \0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OLESelfRegister", "\0"
+ VALUE "OriginalFilename", "droplet.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "rep\0"
+ VALUE "ProductVersion", "2, 3, 0, 1\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_PROGRESSDLG DIALOG DISCARDABLE 0, 0, 219, 95
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Rep processing files..."
+FONT 8, "Tahoma"
+BEGIN
+ PUSHBUTTON "Cancel",2,162,74,50,14
+ LTEXT "Preparing...",IDC_FILENAME,7,51,205,8
+ LTEXT "",IDC_STATUS,7,62,205,8
+ CONTROL "",IDC_FLIP,"Static",SS_GRAYRECT,7,75,148,10
+ CONTROL "",IDC_STATIC,"Static",SS_GRAYFRAME,7,75,148,10
+ ICON IDI_REP,IDC_STATIC,14,14,20,20
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_PROGRESSDLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 212
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 11
+//
+
+1 11 DISCARDABLE "MSG00001.bin"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_REP ICON DISCARDABLE "..\\common\\rep.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROJNAME "droplet"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/win32/droplet/dropletmain.cpp b/win32/droplet/dropletmain.cpp
new file mode 100644
index 0000000..9610ce2
--- /dev/null
+++ b/win32/droplet/dropletmain.cpp
@@ -0,0 +1,76 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include "stdafx.h"
+#include "resource.h"
+#include <initguid.h>
+#include "replace.h"
+
+// ATL Support
+CComModule _Module;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+END_OBJECT_MAP()
+
+
+// _tWinMain: -------------------------------------------------------------
+// Our starting point. Silly name
+
+extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
+ HINSTANCE /*hPrevInstance*/, LPTSTR /* lpCmdLine */, int /*nShowCmd*/)
+{
+ // ATL support
+ HRESULT hRes = CoInitialize(NULL);
+ _ASSERTE(SUCCEEDED(hRes));
+ _Module.Init(ObjectMap, hInstance, NULL);
+ HRESULT hr = S_OK;
+
+ // Make sure we have something to process
+ if(__argc <= 1)
+ {
+ MessageBox(NULL, _T("Drag and drop files onto this droplet to process them."), _T("Rep Droplet"), MB_OK | MB_ICONINFORMATION);
+ hr = E_FAIL;
+ }
+
+ else
+ {
+ Replace replace;
+ if(SUCCEEDED(replace.initialize()))
+ {
+ for(int i = 1; i < __argc; i++)
+ {
+ // Process arguments appropriately
+ DWORD attrs = GetFileAttributes(__argv[i]);
+ if(attrs != 0xFFFFFFFF && attrs & FILE_ATTRIBUTE_DIRECTORY)
+ hr = replace.replaceFolder(__argv[i]);
+ else
+ hr = replace.replaceSingleFile(__argv[i]);
+
+ if(FAILED(hr))
+ break;
+ }
+
+ replace.terminate();
+ }
+ }
+
+ _Module.Term();
+ CoUninitialize();
+ return SUCCEEDED(hr) ? 0 : 1;
+}
diff --git a/win32/droplet/progressdlg.cpp b/win32/droplet/progressdlg.cpp
new file mode 100644
index 0000000..53f5e14
--- /dev/null
+++ b/win32/droplet/progressdlg.cpp
@@ -0,0 +1,211 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+// ProgressDlg.cpp : Implementation of CProgressDlg
+#include "stdafx.h"
+#include "ProgressDlg.h"
+
+// (Con|De)struction: -----------------------------------------------
+
+ProgressDlg::ProgressDlg()
+{
+ m_numFiles = 0;
+ m_numReplaces = 0;
+ m_flip = false;
+ m_hThread = NULL;
+ m_hEvent = NULL;
+ InitializeCriticalSection(&m_sec);
+}
+
+ProgressDlg::~ProgressDlg()
+{
+ DeleteCriticalSection(&m_sec);
+ if(m_hEvent)
+ CloseHandle(m_hEvent);
+}
+
+
+// threadProc: ---------------------------------------------------------
+// Runs the dialog in another thread
+static DWORD WINAPI threadProc(void* pv)
+{
+ ProgressDlg* dlg = (ProgressDlg*)pv;
+ return dlg->DoModal(NULL, NULL);
+}
+
+
+// startDialog: --------------------------------------------------------
+// Starts the dialog thread
+HRESULT ProgressDlg::startDialog()
+{
+ ASSERT(m_hThread == NULL);
+ HRESULT ret = S_OK;
+
+ if(m_hEvent)
+ CloseHandle(m_hEvent);
+
+ m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ DWORD threadID;
+ m_hThread = CreateThread(NULL, 0, threadProc, this, CREATE_SUSPENDED, &threadID);
+ if(!m_hThread)
+ ret = HRESULT_FROM_WIN32(::GetLastError());
+ else
+ ResumeThread(m_hThread);
+
+ // Wait for dialog to start up.
+ ::WaitForSingleObject(m_hEvent, 10000);
+ CloseHandle(m_hEvent);
+ m_hEvent = NULL;
+
+ return S_OK;
+}
+
+// stopDialog: ----------------------------------------------------------
+// Stops the dialog thread and closes the dialog
+int ProgressDlg::stopDialog()
+{
+ int ret = 0;
+
+ if(m_hThread && m_hWnd)
+ {
+ ::PostMessage(m_hWnd, WM_CLOSE, 0, 0);
+ WaitForSingleObject(m_hThread, INFINITE);
+ }
+ else if(m_hThread)
+ {
+ EnterCriticalSection(&m_sec);
+ TerminateThread(m_hThread, -1);
+ }
+
+ if(m_hThread)
+ {
+ DWORD code = 0;
+ GetExitCodeThread(m_hThread, &code);
+ CloseHandle(m_hThread);
+ m_hThread = NULL;
+ ret = (int)code;
+ }
+
+ return 0;
+}
+
+// isCancelled: -----------------------------------------------------------
+// Checks if user pressed cancel button
+bool ProgressDlg::isCancelled()
+{
+ bool ret = false;
+
+ EnterCriticalSection(&m_sec);
+ ret = m_isCancelled;
+ LeaveCriticalSection(&m_sec);
+
+ return ret;
+}
+
+// updateControls: --------------------------------------------------------
+// Update dialog status
+void ProgressDlg::updateControls()
+{
+ if(IsWindow())
+ {
+ string status;
+ status.format(_T("%d replaces in %d files"), m_numReplaces, m_numFiles);
+ SetDlgItemText(IDC_STATUS, status);
+ }
+}
+
+// onReplaced: -------------------------------------------------------------
+// Called when a new replacement was made
+void ProgressDlg::onReplaced()
+{
+ m_flip = !m_flip;
+ m_numReplaces++;
+
+ // Do flicker thing
+ if(IsWindow())
+ ::ShowWindow(GetDlgItem(IDC_FLIP), m_flip ? SW_SHOW : SW_HIDE);
+
+ updateControls();
+}
+
+// onNewFile: --------------------------------------------------------------
+// Called when a new file starts processing
+void ProgressDlg::onNewFile(LPCTSTR fileName)
+{
+ if(IsWindow())
+ SetDlgItemText(IDC_FILENAME, fileName);
+
+ m_numFiles++;
+
+ updateControls();
+}
+
+// setTitle: ---------------------------------------------------------------
+// Set the title. If no window then just store it
+void ProgressDlg::setTitle(const string& title)
+{
+ m_title = title;
+
+ if(IsWindow())
+ SetWindowText(title);
+}
+
+
+// onInitDialog: ------------------------------------------------------------
+// Dialog initialization. We clear the event that says we've
+// started up.
+LRESULT ProgressDlg::onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ EnterCriticalSection(&m_sec);
+
+ if(!m_title.empty())
+ SetWindowText(m_title.c_str());
+
+ if(m_hEvent)
+ SetEvent(m_hEvent);
+
+ CenterWindow(NULL);
+
+ LeaveCriticalSection(&m_sec);
+
+ return 1;
+}
+
+// onClose: ------------------------------------------------------------------
+// Dialog was closed
+LRESULT ProgressDlg::onClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // TODO: will this get called by NC area?
+ EndDialog(IDOK);
+ return 0;
+}
+
+// onCancel: ------------------------------------------------------------------
+// User clicked cancel, set flag
+LRESULT ProgressDlg::onCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ EnterCriticalSection(&m_sec);
+ m_isCancelled = true;
+ LeaveCriticalSection(&m_sec);
+
+ EndDialog(IDCANCEL);
+ return 0;
+}
+
diff --git a/win32/droplet/progressdlg.h b/win32/droplet/progressdlg.h
new file mode 100644
index 0000000..1e416a1
--- /dev/null
+++ b/win32/droplet/progressdlg.h
@@ -0,0 +1,92 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef __PROGRESSDLG_H_
+#define __PROGRESSDLG_H_
+
+#include "resource.h" // main symbols
+#include <atlhost.h>
+
+// ProgressDlg: --------------------------------------------------------
+// The status dialog which is run in another thread
+
+class ProgressDlg :
+ public CDialogImpl<ProgressDlg>
+{
+public:
+ ProgressDlg();
+ ~ProgressDlg();
+
+ enum { IDD = IDD_PROGRESSDLG };
+
+BEGIN_MSG_MAP(ProgressDlg)
+ MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog)
+ MESSAGE_HANDLER(WM_CLOSE, onClose)
+ COMMAND_ID_HANDLER(IDCANCEL, onCancel)
+END_MSG_MAP()
+
+public:
+ // Start dialog in another thread
+ HRESULT startDialog();
+
+ // Stop the dialog thread
+ int stopDialog();
+
+ // Called when a replacement is noted
+ void onReplaced();
+
+ // Called (by Replace::replaceSingleFile) when starting
+ // to process new file
+ void onNewFile(LPCTSTR fileName);
+
+ // Polled (by Replace::matchStatus) to check if user cancelled
+ bool isCancelled();
+
+ // Set the dialog title
+ void setTitle(const string& title);
+
+protected:
+ // Update status etc...
+ void updateControls();
+
+// The message handlers
+protected:
+ LRESULT onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+
+ // Handler prototypes:
+ // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+ // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
+
+protected:
+ HANDLE m_hThread; // The dialog thread
+ string m_title; // The dialog title
+
+ HANDLE m_hEvent; // dialog initialization event
+ CRITICAL_SECTION m_sec; // Used for syncing access to date below
+
+ bool m_isCancelled; // Set when user clicks cancel
+ uint m_numFiles; // Number of files processed
+ uint m_numReplaces; // Number of replaces seen
+ bool m_flip; // Used for flicker display
+};
+
+#endif //__PROGRESSDLG_H_
diff --git a/win32/droplet/replace.cpp b/win32/droplet/replace.cpp
new file mode 100644
index 0000000..8a7b51b
--- /dev/null
+++ b/win32/droplet/replace.cpp
@@ -0,0 +1,438 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include "stdafx.h"
+#include "Replace.h"
+#include "common/errutil.h"
+#include "common/rliberr.h"
+#include "common/mystring.h"
+
+
+// Error Macros: -------------------------------------------------
+// Display error messages and all that
+// Only valid in this context
+// Each of these jumps to the 'cleanup' label for wrapping
+// up any open objects.
+
+#define RETURN(v) \
+ { ret = (v); goto cleanup; }
+#define WINERR(f) \
+ { HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); RETURN(errorMessage(m_dlg.m_hWnd, hr, f)); }
+#define WINERR_1(f, a) \
+ { HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); RETURN(errorMessage(m_dlg.m_hWnd, hr, f, a)); }
+#define WINERR_E(e, f) \
+ { RETURN(errorMessage(m_dlg.m_hWnd, e, f)); }
+#define REPERR(c, s) \
+ { RETURN(rlibError(m_dlg.m_hWnd, c, s)); }
+
+
+// The extension appended to backup or temp files
+LPCTSTR kBackupExt = _T(".x_r");
+
+// (Con|De)struction: -------------------------------------------
+
+Replace::Replace()
+{
+ m_outFile = NULL;
+}
+
+Replace::~Replace()
+{
+ ASSERT(m_outFile == NULL);
+}
+
+
+// initialize: ---------------------------------------------------
+// Loads the script from resources and sets up dialog
+// in another thread
+
+HRESULT Replace::initialize()
+{
+ HRESULT ret = S_OK;
+
+ {
+ if(!m_droplet.load(GetModuleHandle(NULL)))
+ {
+ errorMessage(NULL, 0, _T("Couldn't access droplet rep script. The droplet is probably corrupted."));
+ RETURN(E_FAIL);
+ }
+
+ m_dlg.setTitle(m_droplet.getTitle());
+
+ r_context& ctx = m_droplet.getContext();
+
+ int r = repInit(&ctx);
+ if(r < 0)
+ REPERR(r, &(ctx.script));
+
+ // This starts the dialog in another thread
+ // in order to keep it responsive
+ m_dlg.startDialog();
+ }
+
+cleanup:
+ return ret;
+}
+
+
+// terminate: ----------------------------------------------------
+// Undoes above
+
+HRESULT Replace::terminate()
+{
+ m_dlg.stopDialog();
+ r_context& ctx = m_droplet.getContext();
+ repFree(&ctx);
+ return S_OK;
+}
+
+
+// writeFile: ----------------------------------------------------
+// The callback called from within rlib when data output
+// is required. The argument passed through the r_stream
+// is a pointer to the Replace object.
+
+int Replace::writeFile(r_stream* stream, byte* data, size_t len)
+{
+ Replace* replace = (Replace*)stream->arg;
+
+ // The m_outFile member should be set (and only set)
+ // whenever we're inside rlibRun
+ ASSERT(replace->m_outFile != NULL);
+ DWORD written = 0;
+
+ // Double check that everything was written
+ return WriteFile(replace->m_outFile, data, len, &written, NULL) && len == written;
+}
+
+// matchStatus: --------------------------------------------------
+// Callback whenever something is replaced in rlib
+// Updates the dialog.
+
+int Replace::matchStatus(r_stream* stream, r_replace* repl)
+{
+ Replace* replace = (Replace*)stream->arg;
+ ASSERT_PTR(replace);
+
+ replace->m_dlg.onReplaced();
+ return replace->m_dlg.isCancelled() ? 1 : 0;
+}
+
+
+// replaceFolder: ------------------------------------------------
+// Recursively processes a folder using replaceSingleFile
+
+HRESULT Replace::replaceFolder(LPCTSTR folder)
+{
+ HANDLE hFindFile = NULL;
+ WIN32_FIND_DATA findData;
+ TCHAR old[260]; // Save the current folder (as we'll change it)
+ HRESULT ret = S_FALSE;
+
+ {
+ // Backup the current directory
+ if(!GetCurrentDirectory(260, old))
+ WINERR("Couldn't get the current directory.");
+
+ if(!SetCurrentDirectory(folder))
+ WINERR_1("Couldn't change the current directory to %s", folder);
+
+ if(hFindFile = FindFirstFile(_T("*.*"), &findData))
+ {
+ // And for every file
+ do
+ {
+ HRESULT r = S_FALSE;
+ if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ if(findData.cFileName[0] == '.' &&
+ (findData.cFileName[1] == '.' || findData.cFileName[1] == '\0'))
+ continue;
+
+ r = replaceFolder(findData.cFileName);
+ }
+ else
+ {
+ r = replaceSingleFile(findData.cFileName);
+ }
+
+ if(FAILED(r))
+ RETURN(r);
+ if(r == S_OK)
+ ret = r;
+ }
+ while(FindNextFile(hFindFile, &findData));
+ }
+
+ // Make sure we didn't miss anything
+ if(::GetLastError() != 0 && ::GetLastError() != ERROR_NO_MORE_FILES)
+ WINERR_1("Couldn't list the directory %s", folder);
+
+ // Change directory back
+ SetCurrentDirectory(old);
+ }
+
+cleanup:
+ if(hFindFile)
+ FindClose(hFindFile);
+
+ return ret;
+}
+
+
+// replaceSingleFile: ----------------------------------------------
+// Process a file into a temp file or backup etc...
+// Calls replaceFilename for actual processing
+
+HRESULT Replace::replaceSingleFile(LPCTSTR fileName)
+{
+ HRESULT ret = S_FALSE;
+ string temp;
+ USES_CONVERSION;
+
+ r_context& ctx = m_droplet.getContext();
+
+ {
+ // Update the dialog display
+ m_dlg.onNewFile(fileName);
+
+ // This lets us use the filename from within the script
+ ret = rlibSetVar(&(ctx.stream), "FILENAME", T2CA(fileName));
+ if(ret < 0)
+ REPERR(ret, &(ctx.script));
+
+ // Make a temp/backup name
+ temp.assign(fileName);
+ temp.append(kBackupExt);
+
+ // Now we do this 2 ways, if we're keeping backups then...
+ if(m_droplet.keepBackups())
+ {
+ DeleteFile(temp);
+
+ // Rename the original file to the backup
+ if(!MoveFile(fileName, temp))
+ WINERR_1("There was an error while creating the backup file: %s", temp.c_str());
+
+ // Do a replacement operation back to the original
+ // from the backup
+ ret = replaceFilename(temp, fileName);
+
+ // If there were no replacements
+ if(ret != S_OK)
+ {
+ DeleteFile(fileName);
+
+ // And rename the backup file back
+ if(!MoveFile(temp, fileName))
+ WINERR_1("There was an error while renaming the file: %s", fileName);
+ }
+ }
+
+ // No backups, much faster (when there's no replacements)!
+ else
+ {
+ // Do a replacement operation to a temp file
+ ret = replaceFilename(fileName, temp);
+
+ // If there were replacements
+ if(ret == S_OK)
+ {
+ DeleteFile(fileName);
+
+ // Rename temp to original
+ if(!MoveFile(temp, fileName))
+ WINERR_1("There was an error while renaming the file: %s", fileName);
+ }
+
+ // If no replacements
+ else
+ {
+ // Remove temp file
+ DeleteFile(temp);
+ }
+ }
+ }
+
+cleanup:
+
+ return ret;
+}
+
+// replaceFilename: -------------------------------------------------
+// Process one file into another
+// Open the files and passes them to replaceFile
+
+HRESULT Replace::replaceFilename(LPCTSTR fileIn, LPCTSTR fileOut)
+{
+ HANDLE in = INVALID_HANDLE_VALUE;
+ HANDLE out = INVALID_HANDLE_VALUE;
+ HRESULT ret = S_FALSE;
+
+ {
+ // Basic readonly open
+ in = CreateFile(fileIn, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, NULL);
+ if(in == INVALID_HANDLE_VALUE)
+ WINERR_1("There was an error opening the file: %s", fileIn);
+
+ // We need to know whether we're NT or not below
+ OSVERSIONINFO os;
+ os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&os);
+
+ // This creates a new file for writing
+ // If we're running on NT, then use exactly the same
+ // attributes and permissions as original file
+ out = CreateFile(fileOut, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0,
+ os.dwPlatformId & VER_PLATFORM_WIN32_NT ? in : NULL);
+ if(out == INVALID_HANDLE_VALUE)
+ WINERR_1("There was an error opening the file: %s", fileIn);
+
+
+ // Do replacements!
+ ret = replaceFile(in, out);
+
+ }
+
+cleanup:
+
+ if(in != INVALID_HANDLE_VALUE)
+ CloseHandle(in);
+ if(out != INVALID_HANDLE_VALUE)
+ CloseHandle(out);
+
+ return ret;
+}
+
+
+// replaceFile: --------------------------------------------------------
+// Process one open file handle into another
+// This memory maps the input file and passes it to replaceBuffer
+
+HRESULT Replace::replaceFile(HANDLE in, HANDLE out)
+{
+ HANDLE mapping = NULL;
+ void* data = NULL;
+ HRESULT ret = S_FALSE;
+
+ {
+ // Memory map the input file
+ mapping = CreateFileMapping(in, NULL, PAGE_READONLY, 0, 0, NULL);
+ if(!mapping)
+ WINERR("There was an error reading the input file.");
+
+ data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
+ if(!data)
+ WINERR("There was an error reading the input file.");
+
+ size_t size = GetFileSize(in, NULL);
+ if(size == INVALID_FILE_SIZE)
+ WINERR("There was an error reading the input file.");
+
+ // And pass it on
+ ret = replaceBuffer((byte*)data, size, out);
+ }
+
+cleanup:
+
+ if(data)
+ UnmapViewOfFile(data);
+ if(mapping)
+ CloseHandle(mapping);
+
+ return ret;
+}
+
+
+// replaceBuffer: ----------------------------------------------------
+// Process a memory buffer into a file for output
+// Uses the rlib functions directly
+
+HRESULT Replace::replaceBuffer(byte* data, size_t size, HANDLE out)
+{
+ ASSERT(m_outFile == NULL);
+
+ size_t blockSize = m_droplet.getBuffSize() * 2; // Block size
+ size_t batchSize; // Current batch size
+ int r = R_IN;
+ bool dirty = false;
+ HRESULT ret = S_OK;
+
+ {
+ // If there's no blocksize then we process the
+ // entire file at once
+ if(blockSize == 0)
+ blockSize = size;
+
+ batchSize = blockSize;
+
+ // Setup the rlib stream
+ r_context& ctx = m_droplet.getContext();
+
+ ctx.stream.nextIn = data;
+ ctx.stream.availIn = blockSize;
+ ctx.stream.fWrite = writeFile;
+ ctx.stream.arg = this;
+ ctx.stream.fMatch = matchStatus;
+
+ // This is used by writeFile
+ m_outFile = out;
+
+ // While we have more data to put in ...
+ while(size > 0 || r == R_IN)
+ {
+ // If rlib wants data then give it
+ if(r == R_IN)
+ {
+ batchSize = (blockSize > size) ? size : blockSize;
+
+ ctx.stream.nextIn = data;
+ ctx.stream.availIn = batchSize;
+
+ }
+
+ // call rlib
+ r = rlibRun(&(ctx.stream), &(ctx.script), (size - batchSize) <= 0);
+
+ // Oops!
+ if(r < 0)
+ REPERR(r, &(ctx.script));
+
+ if(ctx.stream.total > 0)
+ dirty = true;
+
+ // Increment last batch
+ data += (batchSize - ctx.stream.availIn);
+ size -= (batchSize - ctx.stream.availIn);
+ }
+
+ // Clears and prepares for next file
+ rlibClear(&ctx.stream);
+ }
+
+cleanup:
+
+ m_outFile = NULL;
+
+ if(FAILED(ret))
+ return ret;
+
+ return dirty ? S_OK : S_FALSE;
+}
diff --git a/win32/droplet/replace.h b/win32/droplet/replace.h
new file mode 100644
index 0000000..b3c72c3
--- /dev/null
+++ b/win32/droplet/replace.h
@@ -0,0 +1,73 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef __REPLACE_H__
+#define __REPLACE_H__
+
+#include "ProgressDlg.h"
+#include "common/Droplet.h"
+#include "lib/rlib.h"
+
+// Replace: --------------------------------------------------------
+// Main processing class. Calls rlib for replacements
+
+class Replace
+{
+public:
+ Replace();
+ virtual ~Replace();
+
+ // Initialize processing (dialog, droplet etc...)
+ HRESULT initialize();
+
+ // Undo initialization
+ HRESULT terminate();
+
+ // Recursively process files in a folder
+ HRESULT replaceFolder(LPCTSTR folder);
+
+ // Process a single file into itself (maybe using backups)
+ HRESULT replaceSingleFile(LPCTSTR fileName);
+
+ // Process one file into another
+ HRESULT replaceFilename(LPCTSTR fileIn, LPCTSTR fileOut);
+
+ // Process one open file into another
+ HRESULT replaceFile(HANDLE in, HANDLE out);
+
+ // Process a memory buffer into an open file
+ HRESULT replaceBuffer(byte* data, size_t size, HANDLE out);
+
+
+private:
+ // Callback for rlib when data output is needed
+ static int writeFile(r_stream* stream, byte* data, size_t len);
+
+ // Callback for rlib status updates
+ static int matchStatus(r_stream* stream, r_replace* repl);
+
+protected:
+ Droplet m_droplet; // The droplet
+ ProgressDlg m_dlg; // The progress dialog
+
+private:
+ HANDLE m_outFile; // Open output file handle used by writeFile
+};
+
+#endif // __REPLACE_H__
diff --git a/win32/droplet/resource.h b/win32/droplet/resource.h
new file mode 100644
index 0000000..91516ec
--- /dev/null
+++ b/win32/droplet/resource.h
@@ -0,0 +1,22 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by droplet.rc
+//
+#define IDS_PROJNAME 100
+#define IDR_Droplet 100
+#define IDD_PROGRESSDLG 101
+#define IDC_FLIP 202
+#define IDC_STATUS 203
+#define IDI_REP 203
+#define IDC_FILENAME 204
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 204
+#define _APS_NEXT_COMMAND_VALUE 32768
+#define _APS_NEXT_CONTROL_VALUE 205
+#define _APS_NEXT_SYMED_VALUE 102
+#endif
+#endif
diff --git a/win32/droplet/rliberr.h b/win32/droplet/rliberr.h
new file mode 100644
index 0000000..8fe3a80
--- /dev/null
+++ b/win32/droplet/rliberr.h
@@ -0,0 +1,136 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * VERSION
+ * 2.2.0b
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef _RLIBERR_H_
+#define _RLIBERR_H_
+
+#ifndef _WINERROR_
+ #error Include winerror.h first.
+#endif
+
+#define HRESULT_FROM_RLIB(code) \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RLIB, abs(code))
+
+/* ------------------------------------------------------------------------ *\
+ Rlib Errors
+\* ------------------------------------------------------------------------ */
+//
+// Values are 32 bit values layed out as follows:
+//
+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +---+-+-+-----------------------+-------------------------------+
+// |Sev|C|R| Facility | Code |
+// +---+-+-+-----------------------+-------------------------------+
+//
+// where
+//
+// Sev - is the severity code
+//
+// 00 - Success
+// 01 - Informational
+// 10 - Warning
+// 11 - Error
+//
+// C - is the Customer code flag
+//
+// R - is a reserved bit
+//
+// Facility - is the facility code
+//
+// Code - is the facility's status code
+//
+//
+// Define the facility codes
+//
+#define FACILITY_RLIB 0x196
+
+
+//
+// Define the severity codes
+//
+
+
+//
+// MessageId: RLIB_E_NOMEM
+//
+// MessageText:
+//
+// Out of Memory.
+//
+#define RLIB_E_NOMEM ((HRESULT)0x81960001L)
+
+//
+// MessageId: RLIB_E_SYNTAX
+//
+// MessageText:
+//
+// Rep script syntax error.
+//
+#define RLIB_E_SYNTAX ((HRESULT)0x81960002L)
+
+//
+// MessageId: RLIB_E_REGEXP
+//
+// MessageText:
+//
+// Regular expression syntax error.
+//
+#define RLIB_E_REGEXP ((HRESULT)0x81960003L)
+
+//
+// MessageId: RLIB_E_LOOP
+//
+// MessageText:
+//
+// Rep encountered an endless loop.
+//
+#define RLIB_E_LOOP ((HRESULT)0x81960004L)
+
+//
+// MessageId: RLIB_E_USER
+//
+// MessageText:
+//
+// User defined error.
+//
+#define RLIB_E_USER ((HRESULT)0x81960005L)
+
+//
+// MessageId: RLIB_E_IOERR
+//
+// MessageText:
+//
+// There was an error reading or writing the data.
+//
+#define RLIB_E_IOERR ((HRESULT)0x81960006L)
+
+//
+// MessageId: RLIB_E_INVARG
+//
+// MessageText:
+//
+// Programmer Error: Invalid argument.
+//
+#define RLIB_E_INVARG ((HRESULT)0x8196000AL)
+
+#endif // _RLIBERR_H_ \ No newline at end of file
diff --git a/win32/droplet/rliberr.rc b/win32/droplet/rliberr.rc
new file mode 100644
index 0000000..0885a89
--- /dev/null
+++ b/win32/droplet/rliberr.rc
@@ -0,0 +1,2 @@
+LANGUAGE 0x9,0x1
+1 11 MSG00001.bin
diff --git a/win32/droplet/stdafx.cpp b/win32/droplet/stdafx.cpp
new file mode 100644
index 0000000..7ab5779
--- /dev/null
+++ b/win32/droplet/stdafx.cpp
@@ -0,0 +1,31 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// stdafx.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+#ifdef _ATL_STATIC_REGISTRY
+#include <statreg.h>
+#include <statreg.cpp>
+#endif
+
+#include <atlimpl.cpp>
diff --git a/win32/droplet/stdafx.h b/win32/droplet/stdafx.h
new file mode 100644
index 0000000..16885d5
--- /dev/null
+++ b/win32/droplet/stdafx.h
@@ -0,0 +1,39 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#if !defined(AFX_STDAFX_H__3607160A_967A_4E9D_A154_BC3CF029F2C2__INCLUDED_)
+#define AFX_STDAFX_H__3607160A_967A_4E9D_A154_BC3CF029F2C2__INCLUDED_
+
+#define STRICT
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+#define _ATL_APARTMENT_THREADED
+
+#include <atlbase.h>
+extern CComModule _Module;
+#include <atlcom.h>
+#include <atlwin.h>
+
+#include "config.win32.h"
+#include "common/compat.h"
+#include "common/usuals.h"
+#include <mystring.h>
+
+#endif // !defined(AFX_STDAFX_H__3607160A_967A_4E9D_A154_BC3CF029F2C2__INCLUDED)
diff --git a/win32/droplet/temp.cmp b/win32/droplet/temp.cmp
new file mode 100644
index 0000000..137c82e
--- /dev/null
+++ b/win32/droplet/temp.cmp
Binary files differ
diff --git a/win32/droplet/temp.rep b/win32/droplet/temp.rep
new file mode 100644
index 0000000..a2aaee4
--- /dev/null
+++ b/win32/droplet/temp.rep
@@ -0,0 +1,24 @@
+#
+# AUTHOR
+# N. Nielsen
+#
+# LICENSE
+# This software is in the public domain.
+#
+# The software is provided "as is", without warranty of any kind,
+# express or implied, including but not limited to the warranties
+# of merchantability, fitness for a particular purpose, and
+# noninfringement. In no event shall the author(s) be liable for any
+# claim, damages, or other liability, whether in an action of
+# contract, tort, or otherwise, arising from, out of, or in connection
+# with the software or the use or other dealings in the software.
+#
+# SUPPORT
+# Send bug reports to: <nielsen@memberwebs.com>
+#
+
+# This is a placeholder script for the one written
+# into the droplet
+
+match "yada"
+ replace "blah" \ No newline at end of file
diff --git a/win32/makedrop/MSG00001.bin b/win32/makedrop/MSG00001.bin
new file mode 100644
index 0000000..83bcd64
--- /dev/null
+++ b/win32/makedrop/MSG00001.bin
Binary files differ
diff --git a/win32/makedrop/Makefile.am b/win32/makedrop/Makefile.am
new file mode 100644
index 0000000..f79b2b5
--- /dev/null
+++ b/win32/makedrop/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST = dropsheet.cpp dropsheet.h makedrop.cpp makedrop.dsp makedrop.h makedrop.rc processpage.h processpage.cpp resource.h settingspage.cpp settingspage.h stdafx.h stdafx.cpp
+
diff --git a/win32/makedrop/dropsheet.cpp b/win32/makedrop/dropsheet.cpp
new file mode 100644
index 0000000..04801b4
--- /dev/null
+++ b/win32/makedrop/dropsheet.cpp
@@ -0,0 +1,301 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include "stdafx.h"
+#include "DropSheet.h"
+#include "common/errutil.h"
+
+
+// Error Macros: ----------------------------------------------------------
+// Context specific macros. Each one jumps to 'cleanup' so any wrapping
+// up can be performed
+
+#define RETURN(v) \
+ { ret = (v); goto cleanup; }
+#define WINERR(f) \
+ RETURN(errorMessage(m_hWnd, HRESULT_FROM_WIN32(::GetLastError()), f))
+#define WINERR_1(f, a) \
+ RETURN(errorMessage(m_hWnd, HRESULT_FROM_WIN32(::GetLastError()), f, a))
+#define WINERR_E(e, f) \
+ RETURN(errorMessage(m_hWnd, e, f));
+#define REPERR(c, s) \
+ RETURN(rlibError(m_hWnd, c, s));
+
+
+
+// (Con|De)struction: -------------------------------------------------------
+
+DropSheet::DropSheet() :
+ CPropertySheet(_T("Rep Droplet"))
+{
+ m_dirty = false;
+}
+
+DropSheet::~DropSheet()
+{
+
+}
+
+
+
+// CopyResourceToFile: -----------------------------------------------------
+// Dumps raw data from a resource to a file
+
+bool CopyResourceToFile(LPCTSTR type, LPCTSTR name, LPCTSTR fileName)
+{
+ // Open the Resource
+ HRSRC hRsrc = FindResource(_Module.GetResourceInstance(), name, type);
+ if(!hRsrc) return false;
+
+ HGLOBAL hGlobal = LoadResource(_Module.GetResourceInstance(), hRsrc);
+ if(!hRsrc) return false;
+
+ void* data = LockResource(hGlobal);
+ if(!data) return false;
+
+ // Open the file
+ HANDLE file = CreateFile(fileName, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, 0, NULL);
+ if(file == INVALID_HANDLE_VALUE) return false;
+
+ DWORD size = SizeofResource(_Module.GetResourceInstance(), hRsrc);
+
+ // Write it
+ DWORD written = 0;
+ bool ret = WriteFile(file, data, size, &written, NULL) ? true : false;
+
+ if(written != size)
+ ret = false;
+
+ CloseHandle(file);
+
+ return ret;
+}
+
+
+
+// saveDroplet: -------------------------------------------------------------
+// Gets property pages to save data, prompts user, saves etc...
+
+bool DropSheet::saveDroplet(bool force)
+{
+ HRESULT ret = S_OK;
+ bool noReturn = false;
+
+ {
+ // The return value is whether or not an exit can
+ // take place
+
+ if(!m_dirty && !force)
+ return true;
+
+ // Prompt the user and see if they want to save
+ if(m_dirty && !force)
+ {
+ switch(MessageBox(_T("You've made changes, would you like to save?"), _T("Rep Droplet"),
+ MB_YESNOCANCEL | MB_ICONQUESTION))
+ {
+ case IDYES:
+ break;
+ case IDNO:
+ return true;
+ case IDCANCEL:
+ return false;
+ }
+ }
+
+ // Clear the dirty flag here
+ m_dirty = false;
+
+ // Now get every page to apply theirs again
+ // if necessary
+ PressButton(PSBTN_APPLYNOW);
+
+ // If dirty is set now, then something failed
+ if(m_dirty)
+ return false;
+
+ // If the user hasn't saved/loaded yet then get a file name
+ if(m_fileName.empty())
+ {
+ OPENFILENAME ofn;
+ memset(&ofn, 0, sizeof(ofn));
+
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = m_hWnd;
+ ofn.lpstrFilter = _T("Droplet Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0\0");
+ ofn.lpstrFile = m_fileName.get_buffer(MAX_PATH);
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = _T("Save Droplet");
+ ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
+ ofn.lpstrDefExt = _T("exe");
+
+ if(GetSaveFileName(&ofn))
+ m_fileName.release_buffer();
+ else
+ return false;
+ }
+
+ // Okay now we copy out the droplet from our resources
+ if(!CopyResourceToFile(DROP_RESOURCE_TYPE, DROP_RESOURCE_FILE,
+ m_fileName))
+ WINERR_1("Couldn't write out droplet: %s", m_fileName.c_str());
+
+ noReturn = true;
+
+ // Now save our droplet data into the stock droplet
+ if(!m_droplet.save(m_fileName))
+ WINERR_1("Couldn't write out droplet: %s", m_fileName.c_str());
+ }
+
+cleanup:
+ // If failed and we already wrote out the stock
+ // droplet, then delete it
+ if(FAILED(ret) && noReturn &&
+ !m_fileName.empty())
+ DeleteFile(m_fileName);
+
+ return SUCCEEDED(ret);
+}
+
+
+// openDroplet: --------------------------------------------------------
+// Prompt user for file, open it and refresh property pages
+
+void DropSheet::openDroplet()
+{
+ HRESULT ret = S_OK;
+
+ {
+ string file;
+ OPENFILENAME ofn;
+ memset(&ofn, 0, sizeof(ofn));
+
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = m_hWnd;
+ ofn.lpstrFilter = _T("Droplet Files\0*.exe\0All Files\0*.*\0\0");
+ ofn.lpstrFile = file.get_buffer(MAX_PATH);
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = _T("Choose Rep Script");
+ ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST;
+ ofn.lpstrDefExt = _T("rep");;
+
+ if(GetOpenFileName(&ofn))
+ {
+ file.release_buffer();
+
+ if(!m_droplet.load(file))
+ WINERR_1("Couldn't read droplet: %s", file.c_str());
+
+ m_fileName = file;
+
+ // Send around a message to the property pages to reload
+ SendMessage(PSM_QUERYSIBLINGS);
+ }
+ }
+
+cleanup:
+ ;
+}
+
+
+// onInitDialog: ----------------------------------------------------------
+// Initialize basic Property sheet stuff and pass on message
+
+LRESULT DropSheet::onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // Add the menu
+ HMENU hMenu = LoadMenu(_Module.GetResourceInstance(),
+ MAKEINTRESOURCE(IDR_MENU));
+ SetMenu(hMenu);
+
+ SetIcon(::LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDI_REP)), TRUE);
+ SetIcon((HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDI_REP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR), FALSE);
+
+
+ // Base implementations need this message
+ bHandled = FALSE;
+ return 0;
+}
+
+
+// onClose: -----------------------------------------------------------------
+// Check if save is required, close
+
+LRESULT DropSheet::onClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // Make sure user saves first
+ if(!m_dirty || saveDroplet(false))
+ {
+ // Modeless dialog, so this is right
+ PostQuitMessage(0);
+ bHandled = FALSE;
+ }
+ else
+ bHandled = TRUE;
+
+ return 0;
+}
+
+
+// onChanged: ---------------------------------------------------------------
+// Catch message sent by property pages, so we can update our dirty flag
+
+LRESULT DropSheet::onChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ m_dirty = true;
+ bHandled = FALSE;
+ return 0;
+}
+
+
+// onOpen: ------------------------------------------------------------------
+// "Open" menu or keyboard accel
+
+LRESULT DropSheet::onOpen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ // Make sure user saves first
+ if(!m_dirty || saveDroplet(false))
+ {
+ openDroplet();
+ }
+
+ return 0;
+}
+
+
+// onSave: ------------------------------------------------------------------
+// "Save" menu or keyboard accel
+
+LRESULT DropSheet::onSave(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ // Force a save
+ saveDroplet(true);
+ return 0;
+}
+
+
+// onExit: ------------------------------------------------------------------
+// "Exit" menu or keyboard accel
+
+LRESULT DropSheet::onExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ onClose(WM_CLOSE, 0, 0, bHandled);
+ return 0;
+}
diff --git a/win32/makedrop/dropsheet.h b/win32/makedrop/dropsheet.h
new file mode 100644
index 0000000..48ec758
--- /dev/null
+++ b/win32/makedrop/dropsheet.h
@@ -0,0 +1,72 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef __DROPSHEET_H__
+#define __DROPSHEET_H__
+
+#include "resource.h"
+#include "common/droplet.h"
+
+// DropSheet: ------------------------------------------------------
+// The main window property sheet
+
+class DropSheet
+ : public CPropertySheet
+{
+public:
+ DropSheet();
+ virtual ~DropSheet();
+
+ BEGIN_MSG_MAP(DropSheet)
+ MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog)
+ COMMAND_ID_HANDLER(ID_FILE_OPEN, onOpen)
+ COMMAND_ID_HANDLER(ID_FILE_SAVE, onSave)
+ COMMAND_ID_HANDLER(ID_FILE_EXIT, onExit)
+ MESSAGE_HANDLER(PSM_CHANGED, onChanged)
+ MESSAGE_HANDLER(WM_CLOSE, onClose)
+ CHAIN_MSG_MAP(CPropertySheet)
+ END_MSG_MAP()
+
+ // Get the current internal droplet
+ Droplet& getDroplet()
+ { return m_droplet; }
+
+// Message Handlers
+protected:
+ LRESULT onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onOpen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+ LRESULT onSave(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+ LRESULT onExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+
+// Helper Functions
+protected:
+ // Save the droplet, prompt user if not force
+ bool saveDroplet(bool force);
+ // Open the a droplet
+ void openDroplet();
+
+protected:
+ Droplet m_droplet; // The internal loaded droplet
+ bool m_dirty; // Have changes been made?
+ string m_fileName; // The filename to save to
+};
+
+#endif // !defined(AFX_DROPSHEET_H__E3237E90_1FD0_4233_98EE_5991F4FB39F8__INCLUDED_)
diff --git a/win32/makedrop/makedrop.cpp b/win32/makedrop/makedrop.cpp
new file mode 100644
index 0000000..79a5b19
--- /dev/null
+++ b/win32/makedrop/makedrop.cpp
@@ -0,0 +1,74 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include "stdafx.h"
+#include "resource.h"
+#include <initguid.h>
+#include "DropSheet.h"
+#include "ProcessPage.h"
+#include "SettingsPage.h"
+
+// ATL Support stuff
+CComModule _Module;
+BEGIN_OBJECT_MAP(ObjectMap)
+END_OBJECT_MAP()
+
+
+// _tWinMain: ------------------------------------------------------------
+// Our application entry point
+extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
+ HINSTANCE /*hPrevInstance*/, LPTSTR /* lpCmdLine */, int /*nShowCmd*/)
+{
+ // ATL Support Stuff
+ HRESULT hRes = CoInitialize(NULL);
+ _ASSERTE(SUCCEEDED(hRes));
+ _Module.Init(ObjectMap, hInstance, NULL);
+
+ int nRet = 0;
+
+ // Create and start the property sheet
+ DropSheet sheet;
+ ProcessPage page1(sheet.getDroplet());
+ SettingsPage page2(sheet.getDroplet());
+ sheet.AddPage(&page1);
+ sheet.AddPage(&page2);
+ sheet.Create();
+
+ // Load the keyboard shortcuts
+ HACCEL accel = LoadAccelerators(_Module.GetResourceInstance(),
+ MAKEINTRESOURCE(IDR_ACCEL));
+
+ // Process messages
+ MSG msg;
+ while(GetMessage(&msg, NULL, 0, 0))
+ {
+ if(!accel || !TranslateAccelerator(sheet.m_hWnd, accel, &msg))
+ {
+ if(!sheet.IsWindow() || !sheet.IsDialogMessage(&msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+
+ _Module.Term();
+ CoUninitialize();
+ return nRet;
+}
diff --git a/win32/makedrop/makedrop.dsp b/win32/makedrop/makedrop.dsp
new file mode 100644
index 0000000..af603d3
--- /dev/null
+++ b/win32/makedrop/makedrop.dsp
@@ -0,0 +1,203 @@
+# Microsoft Developer Studio Project File - Name="makedrop" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=makedrop - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "makedrop.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "makedrop.mak" CFG="makedrop - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "makedrop - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "makedrop - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "makedrop - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\.." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libpcre.a comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x400000" /subsystem:windows /debug /machine:I386 /out:"../debug/makedrop.exe" /pdbtype:sept /libpath:"..\pcre\lib\\"
+
+!ELSEIF "$(CFG)" == "makedrop - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /W3 /GX /O1 /I "..\.." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 libpcre.a comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x400000" /subsystem:windows /machine:I386 /out:"../release/makedrop.exe" /libpath:"..\pcre\lib\\" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "makedrop - Win32 Debug"
+# Name "makedrop - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\common\droplet.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DropSheet.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\common\errutil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\makedrop.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\makedrop.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\ProcessPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\common\rliberr.mc
+
+!IF "$(CFG)" == "makedrop - Win32 Debug"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build
+InputPath=..\common\rliberr.mc
+InputName=rliberr
+
+"$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ mc $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "makedrop - Win32 Release"
+
+# PROP Ignore_Default_Tool 1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\SettingsPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\common\droplet.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DropSheet.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ProcessPage.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SettingsPage.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=..\debug\droplet.exe
+# End Source File
+# Begin Source File
+
+SOURCE=.\droplet.exe
+# End Source File
+# Begin Source File
+
+SOURCE=..\release\droplet.exe
+# End Source File
+# Begin Source File
+
+SOURCE=.\MSG00001.bin
+# End Source File
+# Begin Source File
+
+SOURCE=..\common\rep.ico
+# End Source File
+# End Group
+# End Target
+# End Project
+# Section makedrop : {00000000-0000-0000-0000-800000800000}
+# 1:14:IDD_DROPLETDLG:101
+# End Section
diff --git a/win32/makedrop/makedrop.h b/win32/makedrop/makedrop.h
new file mode 100644
index 0000000..1ef92a3
--- /dev/null
+++ b/win32/makedrop/makedrop.h
@@ -0,0 +1 @@
+/* MIDL: this ALWAYS GENERATED file contains the definitions for the interfaces */
diff --git a/win32/makedrop/makedrop.rc b/win32/makedrop/makedrop.rc
new file mode 100644
index 0000000..0b61072
--- /dev/null
+++ b/win32/makedrop/makedrop.rc
@@ -0,0 +1,275 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// REP
+//
+
+#if defined(APSTUDIO_INVOKED) || defined(NDEBUG)
+#if defined(APSTUDIO_INVOKED)
+DROPLET$(NDEBUG) REP DISCARDABLE "..\\release\\droplet.exe"
+#else
+DROPLET REP DISCARDABLE "..\\release\\droplet.exe"
+#endif
+#endif
+#if defined(APSTUDIO_INVOKED) || defined(_DEBUG)
+#if defined(APSTUDIO_INVOKED)
+DROPLET$(_DEBUG) REP DISCARDABLE "..\\debug\\droplet.exe"
+#else
+DROPLET REP DISCARDABLE "..\\debug\\droplet.exe"
+#endif
+#endif
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,2,0,1
+ PRODUCTVERSION 2,2,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Nate Nielsen\0"
+ VALUE "FileDescription", "Rep Droplet Maker\0"
+ VALUE "FileVersion", "2, 2, 0, 1\0"
+ VALUE "InternalName", "makedrop\0"
+ VALUE "LegalCopyright", "Copyright Nate Nielsen 2002\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OLESelfRegister", "\0"
+ VALUE "OriginalFilename", "makedrop.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "rep\0"
+ VALUE "ProductVersion", "2, 2, 0, 1\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 227, 210
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Settings"
+FONT 8, "Tahoma"
+BEGIN
+ LTEXT "This title is shown in the progress dialog for this droplet.",
+ IDC_STATIC,17,19,180,8
+ EDITTEXT IDC_TITLE,17,32,192,14,ES_AUTOHSCROLL
+ CONTROL "Backup replaced files.",IDC_BACKUP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,17,75,167,10
+ GROUPBOX "Backups",IDC_STATIC,7,61,213,75
+ LTEXT "If this option is checked, then this droplet will backup any files it modifies. It adds a 'x_r' extension to those files.\n\nWhen a backup already exists it is overwritten.",
+ IDC_STATIC,17,91,192,32
+ GROUPBOX "Title",IDC_STATIC,7,7,213,48
+END
+
+IDD_PROCESS DIALOG DISCARDABLE 0, 0, 227, 210
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Process"
+FONT 8, "Tahoma"
+BEGIN
+ CONTROL "Process entire file at once",IDC_USEFILE,"Button",
+ BS_AUTORADIOBUTTON,18,79,158,10
+ CONTROL "Process file in chunks",IDC_USECHUNK,"Button",
+ BS_AUTORADIOBUTTON,18,126,140,10
+ LTEXT "Largest match size:",IDC_STATIC,35,183,63,8
+ EDITTEXT IDC_CHUNK,104,182,57,14,ES_AUTOHSCROLL | ES_NUMBER
+ GROUPBOX "Chunks",IDC_STATIC,7,65,213,138
+ LTEXT "This runs replaces on all of the file at once. Although the most reliable method, it's slower, sometimes extremely so. ",
+ IDC_STATIC,18,94,191,22
+ LTEXT "This option breaks up the file into smaller blocks for processing. Processing is much faster in this mode. The largest expected match should be entered below; anything larger won't be replaced.",
+ IDC_STATIC,18,140,191,34
+ GROUPBOX "Script",IDC_STATIC,7,7,213,49
+ EDITTEXT IDC_SCRIPT,18,33,170,14,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_BROWSE,190,33,19,14
+ LTEXT "The rep script that will be compiled into the droplet. ",
+ IDC_STATIC,18,19,191,12
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_SETTINGS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 220
+ VERTGUIDE, 17
+ VERTGUIDE, 209
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 203
+ END
+
+ IDD_PROCESS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 220
+ VERTGUIDE, 18
+ VERTGUIDE, 209
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 203
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU MENU DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM "&Save...\tCtrl+S", ID_FILE_SAVE
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit\tCtrl+Q", ID_FILE_EXIT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_ACCEL ACCELERATORS DISCARDABLE
+BEGIN
+ "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
+ "Q", ID_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT
+ "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_REP ICON DISCARDABLE "..\\common\\rep.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 11
+//
+
+1 11 DISCARDABLE "MSG00001.bin"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROJNAME "makedrop"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/win32/makedrop/processpage.cpp b/win32/makedrop/processpage.cpp
new file mode 100644
index 0000000..be3951a
--- /dev/null
+++ b/win32/makedrop/processpage.cpp
@@ -0,0 +1,239 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include "stdafx.h"
+#include "ProcessPage.h"
+#include "common/errutil.h"
+#include "lib/rlib.h"
+#include "lib/rep.h"
+
+
+// Error Macros: ----------------------------------------------------------
+// Context specific macros. Each one jumps to 'cleanup' so any wrapping
+// up can be performed
+
+#define RETURN(v) \
+ { ret = (v); goto cleanup; }
+#define WINERR(f) \
+ RETURN(errorMessage(m_hWnd, HRESULT_FROM_WIN32(::GetLastError()), f))
+#define WINERR_1(f, a) \
+ RETURN(errorMessage(m_hWnd, HRESULT_FROM_WIN32(::GetLastError()), f, a))
+#define WINERR_E(e, f) \
+ RETURN(errorMessage(m_hWnd, e, f));
+#define REPERR(c, s) \
+ RETURN(rlibError(m_hWnd, c, s));
+#define CUSTERR(e, s) \
+ { errorMessage(m_hWnd, 0, s); RETURN(e); }
+#define CUSTERR_1(e, s, a) \
+ { errorMessage(m_hWnd, 0, s, a); RETURN(e); }
+
+
+// (Con|De)struction: ---------------------------------------------------------
+
+ProcessPage::ProcessPage(Droplet& droplet) :
+ CPropertyPage(IDD_PROCESS, _T("Script")),
+ m_droplet(droplet)
+{
+ m_inited = false;
+}
+
+// compileScript: ----------------------------------------------------------
+// Load and possibly compile a script from a file
+
+HRESULT ProcessPage::compileScript(const string& script)
+{
+ FILE* file = NULL;
+ HRESULT ret = S_OK;
+ int r = R_OK;
+
+ {
+ file = fopen(script, "rb");
+ if(!file)
+ CUSTERR_1(E_FAIL, "Couldn't open script file: %s", script.c_str());
+
+ r_context& ctx = m_droplet.getContext();
+
+ r = repLoad(&ctx, file);
+ if(r < 0)
+ REPERR(r, &(ctx.script));
+ }
+
+cleanup:
+ if(file)
+ fclose(file);
+
+ return ret;
+}
+
+
+// loadData: -------------------------------------------------------------
+// Load data from the droplet onto page
+
+void ProcessPage::loadData()
+{
+ m_inited = false;
+ size_t buffSize = m_droplet.getBuffSize();
+ CheckDlgButton(IDC_USEFILE, buffSize == 0);
+ CheckDlgButton(IDC_USECHUNK, buffSize != 0);
+ SetDlgItemInt(IDC_CHUNK, buffSize == 0 ? 2000 : buffSize, FALSE);
+
+ if(m_droplet.hasScript())
+ {
+ // By setting both to the same value we prevent rereading
+ // or compiling
+ m_script = _T("[compiled script]");
+ SetDlgItemText(IDC_SCRIPT, m_script);
+ }
+
+ m_inited = true;
+ updateControls();
+}
+
+
+// onInitDialog: -----------------------------------------------------------
+// Dialog initialization
+
+LRESULT ProcessPage::onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ loadData();
+ return 0;
+}
+
+
+// onInitDialog: -----------------------------------------------------------
+// Broadcast by sheet when required to reread droplet info
+
+LRESULT ProcessPage::onQuerySiblings(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ loadData();
+ return 0;
+}
+
+
+// onInitDialog: -----------------------------------------------------------
+// Save droplet data from page
+
+LRESULT ProcessPage::onApply(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
+{
+ string script;
+ GetDlgItemText(IDC_SCRIPT, script.get_buffer(MAX_PATH), MAX_PATH);
+ script.release_buffer();
+
+ // Make sure we have a script
+ if(script.empty())
+ {
+ errorMessage(m_hWnd, 0, _T("You need to provide the filename of a rep script."));
+ ::SetFocus(GetDlgItem(IDC_SCRIPT));
+ SetModified(TRUE);
+ return PSNRET_INVALID;
+ }
+
+ // If the the script changed
+ if(script != m_script)
+ {
+ // Then recompile it
+ if(SUCCEEDED(compileScript(script)))
+ {
+ m_script = script;
+ }
+ else
+ {
+ // By setting dirty we signal an error to sheet
+ SetModified(TRUE);
+ return PSNRET_INVALID;
+ }
+ }
+
+ // Do buffer thing
+ if(IsDlgButtonChecked(IDC_USEFILE))
+ {
+ // Process entire file at once
+ m_droplet.setBuffSize(0);
+ }
+ else
+ {
+ // Get the actual buffer size
+ BOOL translated;
+ UINT buffSize = GetDlgItemInt(IDC_CHUNK, &translated, FALSE);
+ if(buffSize < 16 || !translated)
+ {
+ errorMessage(m_hWnd, 0, _T("The chunk size must be a valid number greater than 16."));
+ ::SetFocus(GetDlgItem(IDC_CHUNK));
+ SetModified(TRUE);
+ return PSNRET_INVALID;
+ }
+
+ m_droplet.setBuffSize(buffSize);
+ }
+
+ return PSNRET_NOERROR;
+}
+
+
+// onChange: --------------------------------------------------------------
+// Signal dirty to parent sheet
+
+LRESULT ProcessPage::onChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ if(m_inited)
+ {
+ SetModified(TRUE);
+ updateControls();
+ }
+ return 0;
+}
+
+
+// updateControls: --------------------------------------------------------
+// Make sure page remains valid when changes happen
+
+void ProcessPage::updateControls()
+{
+ ::EnableWindow(GetDlgItem(IDC_CHUNK), IsDlgButtonChecked(IDC_USECHUNK));
+}
+
+
+// onBrowse: --------------------------------------------------------------
+// Browse for a script file
+
+LRESULT ProcessPage::onBrowse(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ string file;
+ OPENFILENAME ofn;
+ memset(&ofn, 0, sizeof(ofn));
+
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = m_hWnd;
+ ofn.lpstrFilter = _T("Rep Files (*.rep)\0*.rep\0All Files (*.*)\0*.*\0\0");
+ ofn.lpstrFile = file.get_buffer(MAX_PATH);
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = _T("Choose Rep Script");
+ ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST;
+ ofn.lpstrDefExt = _T("rep");;
+
+ if(GetOpenFileName(&ofn))
+ {
+ file.release_buffer();
+ SetDlgItemText(IDC_SCRIPT, file);
+ SetModified(TRUE);
+ updateControls();
+ }
+
+ return 0;
+}
diff --git a/win32/makedrop/processpage.h b/win32/makedrop/processpage.h
new file mode 100644
index 0000000..74ad6de
--- /dev/null
+++ b/win32/makedrop/processpage.h
@@ -0,0 +1,75 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef __PROCESSPAGE_H__
+#define __PROCESSPAGE_H__
+
+#include "resource.h" // main symbols
+#include <atlhost.h>
+#include "common/droplet.h"
+
+
+// ProcessPage: -------------------------------------------------------
+// Property page for script and buffer size
+
+class ProcessPage :
+ public CPropertyPage
+{
+public:
+ ProcessPage(Droplet& droplet);
+
+ BEGIN_MSG_MAP(ProcessPage)
+ MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog)
+ MESSAGE_HANDLER(PSM_QUERYSIBLINGS, onQuerySiblings)
+ COMMAND_ID_HANDLER(IDC_BROWSE, onBrowse)
+ COMMAND_CODE_HANDLER(BN_CLICKED, onChange)
+ COMMAND_CODE_HANDLER(EN_CHANGE, onChange)
+ NOTIFY_CODE_HANDLER(PSN_APPLY, onApply)
+ END_MSG_MAP()
+
+// Message Handlers
+protected:
+ LRESULT onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onQuerySiblings(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onApply(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
+ LRESULT onChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+ LRESULT onBrowse(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+
+// Helper Functions
+protected:
+ // Updates all status etc...
+ void updateControls();
+
+ // Load data from droplet to page
+ void loadData();
+
+ // Load an already compiled rep script
+ HRESULT compileAlready(FILE* f);
+
+ // Load and possibly compile a rep script
+ HRESULT compileScript(const string& script);
+
+protected:
+ Droplet& m_droplet; // Pointer to sheet's main droplet
+ string m_script; // The script file name last time it was saved
+ // Will not reload if the same
+ bool m_inited; // Have we finished being initialized (used by onChange)
+};
+
+#endif //__PROCESSPAGE_H__
diff --git a/win32/makedrop/resource.h b/win32/makedrop/resource.h
new file mode 100644
index 0000000..4783aae
--- /dev/null
+++ b/win32/makedrop/resource.h
@@ -0,0 +1,32 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by makedrop.rc
+//
+#define IDS_PROJNAME 100
+#define IDR_Makedrop 100
+#define IDC_TITLE 201
+#define IDR_MENU 201
+#define IDD_SETTINGS 202
+#define IDC_BACKUP 202
+#define IDR_ACCEL 202
+#define IDC_USEFILE 203
+#define IDD_PROCESS 203
+#define IDC_USECHUNK 204
+#define IDC_CHUNK 205
+#define IDC_SCRIPT 206
+#define IDC_BROWSE 207
+#define IDI_REP 208
+#define ID_FILE_OPEN 32768
+#define ID_FILE_SAVE 32769
+#define ID_FILE_EXIT 32770
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 210
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 208
+#define _APS_NEXT_SYMED_VALUE 102
+#endif
+#endif
diff --git a/win32/makedrop/rliberr.h b/win32/makedrop/rliberr.h
new file mode 100644
index 0000000..8fe3a80
--- /dev/null
+++ b/win32/makedrop/rliberr.h
@@ -0,0 +1,136 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * VERSION
+ * 2.2.0b
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef _RLIBERR_H_
+#define _RLIBERR_H_
+
+#ifndef _WINERROR_
+ #error Include winerror.h first.
+#endif
+
+#define HRESULT_FROM_RLIB(code) \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RLIB, abs(code))
+
+/* ------------------------------------------------------------------------ *\
+ Rlib Errors
+\* ------------------------------------------------------------------------ */
+//
+// Values are 32 bit values layed out as follows:
+//
+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +---+-+-+-----------------------+-------------------------------+
+// |Sev|C|R| Facility | Code |
+// +---+-+-+-----------------------+-------------------------------+
+//
+// where
+//
+// Sev - is the severity code
+//
+// 00 - Success
+// 01 - Informational
+// 10 - Warning
+// 11 - Error
+//
+// C - is the Customer code flag
+//
+// R - is a reserved bit
+//
+// Facility - is the facility code
+//
+// Code - is the facility's status code
+//
+//
+// Define the facility codes
+//
+#define FACILITY_RLIB 0x196
+
+
+//
+// Define the severity codes
+//
+
+
+//
+// MessageId: RLIB_E_NOMEM
+//
+// MessageText:
+//
+// Out of Memory.
+//
+#define RLIB_E_NOMEM ((HRESULT)0x81960001L)
+
+//
+// MessageId: RLIB_E_SYNTAX
+//
+// MessageText:
+//
+// Rep script syntax error.
+//
+#define RLIB_E_SYNTAX ((HRESULT)0x81960002L)
+
+//
+// MessageId: RLIB_E_REGEXP
+//
+// MessageText:
+//
+// Regular expression syntax error.
+//
+#define RLIB_E_REGEXP ((HRESULT)0x81960003L)
+
+//
+// MessageId: RLIB_E_LOOP
+//
+// MessageText:
+//
+// Rep encountered an endless loop.
+//
+#define RLIB_E_LOOP ((HRESULT)0x81960004L)
+
+//
+// MessageId: RLIB_E_USER
+//
+// MessageText:
+//
+// User defined error.
+//
+#define RLIB_E_USER ((HRESULT)0x81960005L)
+
+//
+// MessageId: RLIB_E_IOERR
+//
+// MessageText:
+//
+// There was an error reading or writing the data.
+//
+#define RLIB_E_IOERR ((HRESULT)0x81960006L)
+
+//
+// MessageId: RLIB_E_INVARG
+//
+// MessageText:
+//
+// Programmer Error: Invalid argument.
+//
+#define RLIB_E_INVARG ((HRESULT)0x8196000AL)
+
+#endif // _RLIBERR_H_ \ No newline at end of file
diff --git a/win32/makedrop/rliberr.rc b/win32/makedrop/rliberr.rc
new file mode 100644
index 0000000..0885a89
--- /dev/null
+++ b/win32/makedrop/rliberr.rc
@@ -0,0 +1,2 @@
+LANGUAGE 0x9,0x1
+1 11 MSG00001.bin
diff --git a/win32/makedrop/settingspage.cpp b/win32/makedrop/settingspage.cpp
new file mode 100644
index 0000000..953eebd
--- /dev/null
+++ b/win32/makedrop/settingspage.cpp
@@ -0,0 +1,100 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include "stdafx.h"
+#include "SettingsPage.h"
+
+// (Con|De)struction: ----------------------------------------------------
+
+SettingsPage::SettingsPage(Droplet& droplet) :
+ CPropertyPage(IDD_SETTINGS, _T("Settings")),
+ m_droplet(droplet)
+{
+ m_inited = false;
+}
+
+
+// loadData: -------------------------------------------------------------
+// Load info from droplet onto page
+
+void SettingsPage::loadData()
+{
+ m_inited = false;
+ SetDlgItemText(IDC_TITLE, m_droplet.getTitle());
+ CheckDlgButton(IDC_BACKUP, m_droplet.keepBackups());
+ m_inited = true;
+ updateControls();
+}
+
+
+// onQuerySiblings: ------------------------------------------------------
+// Broadcast from parent sheet when we have to reload droplet data
+
+LRESULT SettingsPage::onQuerySiblings(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ loadData();
+ return 0;
+}
+
+
+// onInitDialog: ---------------------------------------------------------
+// Page Initialization
+
+LRESULT SettingsPage::onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ loadData();
+ return 0;
+}
+
+
+// onApply: --------------------------------------------------------------
+// Save data to droplet
+
+LRESULT SettingsPage::onApply(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
+{
+ string title;
+ GetDlgItemText(IDC_TITLE, title.get_buffer(MAX_PATH), MAX_PATH);
+ title.release_buffer();
+ m_droplet.setTitle(title);
+
+ m_droplet.setBackups(IsDlgButtonChecked(IDC_BACKUP) ? true : false);
+ return PSNRET_NOERROR;
+}
+
+
+// onChange: -------------------------------------------------------------
+// Signal to parent when changes happen
+
+LRESULT SettingsPage::onChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ if(m_inited)
+ {
+ SetModified(TRUE);
+ updateControls();
+ }
+ return 0;
+}
+
+// updateControls: -------------------------------------------------------
+// Keep page status in sync
+
+void SettingsPage::updateControls()
+{
+
+} \ No newline at end of file
diff --git a/win32/makedrop/settingspage.h b/win32/makedrop/settingspage.h
new file mode 100644
index 0000000..f122963
--- /dev/null
+++ b/win32/makedrop/settingspage.h
@@ -0,0 +1,65 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#ifndef __SETTINGSPAGE_H_
+#define __SETTINGSPAGE_H_
+
+#include "resource.h" // main symbols
+#include <atlhost.h>
+#include "common/droplet.h"
+
+// SettingsPage: ----------------------------------------------------------
+// Property page for misc drop settings
+
+class SettingsPage :
+ public CPropertyPage
+{
+public:
+ SettingsPage(Droplet& droplet);
+
+ BEGIN_MSG_MAP(SettingsPage)
+ MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog)
+ MESSAGE_HANDLER(PSM_QUERYSIBLINGS, onQuerySiblings)
+ COMMAND_CODE_HANDLER(BN_CLICKED, onChange)
+ COMMAND_CODE_HANDLER(EN_CHANGE, onChange)
+ NOTIFY_CODE_HANDLER(PSN_APPLY, onApply)
+ END_MSG_MAP()
+
+// Message Handlers
+protected:
+ LRESULT onInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onQuerySiblings(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT onApply(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
+ LRESULT onChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+
+// Helper Functions
+protected:
+ // Updates all status etc...
+ void updateControls();
+
+ // Load data from droplet to page
+ void loadData();
+
+// Data
+protected:
+ Droplet& m_droplet; // The Property sheet's internal droplet
+ bool m_inited; // Have we been initialized (used by onChange)
+};
+
+#endif //__SETTINGSPAGE_H_
diff --git a/win32/makedrop/stdafx.cpp b/win32/makedrop/stdafx.cpp
new file mode 100644
index 0000000..ba86b3c
--- /dev/null
+++ b/win32/makedrop/stdafx.cpp
@@ -0,0 +1,27 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#include "stdafx.h"
+
+#ifdef _ATL_STATIC_REGISTRY
+#include <statreg.h>
+#include <statreg.cpp>
+#endif
+
+#include <atlimpl.cpp>
diff --git a/win32/makedrop/stdafx.h b/win32/makedrop/stdafx.h
new file mode 100644
index 0000000..2de0b77
--- /dev/null
+++ b/win32/makedrop/stdafx.h
@@ -0,0 +1,40 @@
+/*
+ * AUTHOR
+ * N. Nielsen
+ *
+ * LICENSE
+ * This software is in the public domain.
+ *
+ * The software is provided "as is", without warranty of any kind,
+ * express or implied, including but not limited to the warranties
+ * of merchantability, fitness for a particular purpose, and
+ * noninfringement. In no event shall the author(s) be liable for any
+ * claim, damages, or other liability, whether in an action of
+ * contract, tort, or otherwise, arising from, out of, or in connection
+ * with the software or the use or other dealings in the software.
+ *
+ * SUPPORT
+ * Send bug reports to: <nielsen@memberwebs.com>
+ */
+
+#if !defined(AFX_STDAFX_H__7FCAFA12_CBDF_41CC_98D1_56D72C99E1C5__INCLUDED_)
+#define AFX_STDAFX_H__7FCAFA12_CBDF_41CC_98D1_56D72C99E1C5__INCLUDED_
+
+#define STRICT
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+#define _ATL_APARTMENT_THREADED
+
+#include <atlbase.h>
+extern CComModule _Module;
+#include <atlcom.h>
+#include <atlwin.h>
+
+#include "config.win32.h"
+#include "common/compat.h"
+#include "common/usuals.h"
+#include "common/atlprsht.h"
+#include "common/mystring.h"
+
+#endif // !defined(AFX_STDAFX_H__7FCAFA12_CBDF_41CC_98D1_56D72C99E1C5__INCLUDED)
diff --git a/win32/pcre/include/pcre.h b/win32/pcre/include/pcre.h
new file mode 100644
index 0000000..d6c2393
--- /dev/null
+++ b/win32/pcre/include/pcre.h
@@ -0,0 +1,113 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* Copyright (c) 1997-2001 University of Cambridge */
+
+#ifndef _PCRE_H
+#define _PCRE_H
+
+/* The file pcre.h is build by "configure". Do not edit it; instead
+make changes to pcre.in. */
+
+#define PCRE_MAJOR 3
+#define PCRE_MINOR 9
+#define PCRE_DATE 02-Jan-2002
+
+/* Win32 uses DLL by default */
+
+#ifdef _WIN32
+# ifdef STATIC
+# define PCRE_DL_IMPORT
+# else
+# define PCRE_DL_IMPORT __declspec(dllimport)
+# endif
+#else
+# define PCRE_DL_IMPORT
+#endif
+
+/* Have to include stdlib.h in order to ensure that size_t is defined;
+it is needed here for malloc. */
+
+#include <stdlib.h>
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options */
+
+#define PCRE_CASELESS 0x0001
+#define PCRE_MULTILINE 0x0002
+#define PCRE_DOTALL 0x0004
+#define PCRE_EXTENDED 0x0008
+#define PCRE_ANCHORED 0x0010
+#define PCRE_DOLLAR_ENDONLY 0x0020
+#define PCRE_EXTRA 0x0040
+#define PCRE_NOTBOL 0x0080
+#define PCRE_NOTEOL 0x0100
+#define PCRE_UNGREEDY 0x0200
+#define PCRE_NOTEMPTY 0x0400
+#define PCRE_UTF8 0x0800
+
+/* Exec-time and get-time error codes */
+
+#define PCRE_ERROR_NOMATCH (-1)
+#define PCRE_ERROR_NULL (-2)
+#define PCRE_ERROR_BADOPTION (-3)
+#define PCRE_ERROR_BADMAGIC (-4)
+#define PCRE_ERROR_UNKNOWN_NODE (-5)
+#define PCRE_ERROR_NOMEMORY (-6)
+#define PCRE_ERROR_NOSUBSTRING (-7)
+
+/* Request types for pcre_fullinfo() */
+
+#define PCRE_INFO_OPTIONS 0
+#define PCRE_INFO_SIZE 1
+#define PCRE_INFO_CAPTURECOUNT 2
+#define PCRE_INFO_BACKREFMAX 3
+#define PCRE_INFO_FIRSTCHAR 4
+#define PCRE_INFO_FIRSTTABLE 5
+#define PCRE_INFO_LASTLITERAL 6
+
+/* Types */
+
+struct real_pcre; /* declaration; the definition is private */
+struct real_pcre_extra; /* declaration; the definition is private */
+
+typedef struct real_pcre pcre;
+typedef struct real_pcre_extra pcre_extra;
+
+/* Store get and free functions. These can be set to alternative malloc/free
+functions if required. Some magic is required for Win32 DLL; it is null on
+other OS. */
+
+PCRE_DL_IMPORT extern void *(*pcre_malloc)(size_t);
+PCRE_DL_IMPORT extern void (*pcre_free)(void *);
+
+#undef PCRE_DL_IMPORT
+
+/* Functions */
+
+extern pcre *pcre_compile(const char *, int, const char **, int *,
+ const unsigned char *);
+extern int pcre_copy_substring(const char *, int *, int, int, char *, int);
+extern int pcre_exec(const pcre *, const pcre_extra *, const char *,
+ int, int, int, int *, int);
+extern void pcre_free_substring(const char *);
+extern void pcre_free_substring_list(const char **);
+extern int pcre_get_substring(const char *, int *, int, int, const char **);
+extern int pcre_get_substring_list(const char *, int *, int, const char ***);
+extern int pcre_info(const pcre *, int *, int *);
+extern int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *);
+extern const unsigned char *pcre_maketables(void);
+extern pcre_extra *pcre_study(const pcre *, int, const char **);
+extern const char *pcre_version(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* End of pcre.h */
diff --git a/win32/pcre/include/pcreposix.h b/win32/pcre/include/pcreposix.h
new file mode 100644
index 0000000..e70af2d
--- /dev/null
+++ b/win32/pcre/include/pcreposix.h
@@ -0,0 +1,88 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* Copyright (c) 1997-2001 University of Cambridge */
+
+#ifndef _PCREPOSIX_H
+#define _PCREPOSIX_H
+
+/* This is the header for the POSIX wrapper interface to the PCRE Perl-
+Compatible Regular Expression library. It defines the things POSIX says should
+be there. I hope. */
+
+/* Have to include stdlib.h in order to ensure that size_t is defined. */
+
+#include <stdlib.h>
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options defined by POSIX. */
+
+#define REG_ICASE 0x01
+#define REG_NEWLINE 0x02
+#define REG_NOTBOL 0x04
+#define REG_NOTEOL 0x08
+
+/* These are not used by PCRE, but by defining them we make it easier
+to slot PCRE into existing programs that make POSIX calls. */
+
+#define REG_EXTENDED 0
+#define REG_NOSUB 0
+
+/* Error values. Not all these are relevant or used by the wrapper. */
+
+enum {
+ REG_ASSERT = 1, /* internal error ? */
+ REG_BADBR, /* invalid repeat counts in {} */
+ REG_BADPAT, /* pattern error */
+ REG_BADRPT, /* ? * + invalid */
+ REG_EBRACE, /* unbalanced {} */
+ REG_EBRACK, /* unbalanced [] */
+ REG_ECOLLATE, /* collation error - not relevant */
+ REG_ECTYPE, /* bad class */
+ REG_EESCAPE, /* bad escape sequence */
+ REG_EMPTY, /* empty expression */
+ REG_EPAREN, /* unbalanced () */
+ REG_ERANGE, /* bad range inside [] */
+ REG_ESIZE, /* expression too big */
+ REG_ESPACE, /* failed to get memory */
+ REG_ESUBREG, /* bad back reference */
+ REG_INVARG, /* bad argument */
+ REG_NOMATCH /* match failed */
+};
+
+
+/* The structure representing a compiled regular expression. */
+
+typedef struct {
+ void *re_pcre;
+ size_t re_nsub;
+ size_t re_erroffset;
+} regex_t;
+
+/* The structure in which a captured offset is returned. */
+
+typedef int regoff_t;
+
+typedef struct {
+ regoff_t rm_so;
+ regoff_t rm_eo;
+} regmatch_t;
+
+/* The functions */
+
+extern int regcomp(regex_t *, const char *, int);
+extern int regexec(regex_t *, const char *, size_t, regmatch_t *, int);
+extern size_t regerror(int, const regex_t *, char *, size_t);
+extern void regfree(regex_t *);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* End of pcreposix.h */
diff --git a/win32/pcre/lib/libpcre-bcc.def b/win32/pcre/lib/libpcre-bcc.def
new file mode 100644
index 0000000..ecdd5c2
--- /dev/null
+++ b/win32/pcre/lib/libpcre-bcc.def
@@ -0,0 +1,21 @@
+LIBRARY PCRE.DLL
+
+EXPORTS
+ _pcre_compile = pcre_compile ; pcre_compile
+ _pcre_copy_substring = pcre_copy_substring ; pcre_copy_substring
+ _pcre_exec = pcre_exec ; pcre_exec
+ _pcre_free = pcre_free ; pcre_free
+ _pcre_free_substring = pcre_free_substring ; pcre_free_substring
+ _pcre_free_substring_list = pcre_free_substring_list ; pcre_free_substring_list
+ _pcre_fullinfo = pcre_fullinfo ; pcre_fullinfo
+ _pcre_get_substring = pcre_get_substring ; pcre_get_substring
+ _pcre_get_substring_list = pcre_get_substring_list ; pcre_get_substring_list
+ _pcre_info = pcre_info ; pcre_info
+ _pcre_maketables = pcre_maketables ; pcre_maketables
+ _pcre_malloc = pcre_malloc ; pcre_malloc
+ _pcre_study = pcre_study ; pcre_study
+ _pcre_version = pcre_version ; pcre_version
+ _regcomp = regcomp ; regcomp
+ _regerror = regerror ; regerror
+ _regexec = regexec ; regexec
+ _regfree = regfree ; regfree
diff --git a/win32/pcre/lib/libpcre-bcc.lib b/win32/pcre/lib/libpcre-bcc.lib
new file mode 100644
index 0000000..e807b0e
--- /dev/null
+++ b/win32/pcre/lib/libpcre-bcc.lib
Binary files differ
diff --git a/win32/pcre/lib/libpcre.def b/win32/pcre/lib/libpcre.def
new file mode 100644
index 0000000..2db32cb
--- /dev/null
+++ b/win32/pcre/lib/libpcre.def
@@ -0,0 +1,20 @@
+; i:\MINGW\BIN\dlltool.exe -Cn -a -z libpcre.def --export-all-symbols DLLTMPDIR.libpcre.a/get.o DLLTMPDIR.libpcre.a/maketables.o DLLTMPDIR.libpcre.a/pcre.o DLLTMPDIR.libpcre.a/study.o DLLTMPDIR.libpcreposix.a/pcreposix.o
+EXPORTS
+ pcre_info @ 1 ;
+ pcre_copy_substring @ 2 ;
+ pcre_exec @ 3 ;
+ pcre_free @ 4 DATA ;
+ pcre_free_substring @ 5 ;
+ pcre_free_substring_list @ 6 ;
+ pcre_fullinfo @ 7 ;
+ pcre_get_substring @ 8 ;
+ pcre_get_substring_list @ 9 ;
+ pcre_compile @ 10 ;
+ pcre_maketables @ 11 ;
+ pcre_malloc @ 12 DATA ;
+ pcre_study @ 13 ;
+ pcre_version @ 14 ;
+ regcomp @ 15 ;
+ regerror @ 16 ;
+ regexec @ 17 ;
+ regfree @ 18 ;
diff --git a/win32/pcre/lib/libpcre.la b/win32/pcre/lib/libpcre.la
new file mode 100644
index 0000000..8072045
--- /dev/null
+++ b/win32/pcre/lib/libpcre.la
@@ -0,0 +1,32 @@
+# libpcre.la - a libtool library file
+# Generated by ltmain.sh - GNU libtool 1.4 (1.920 2001/04/24 23:26:18)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libpcre.a'
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Version information for libpcre.
+current=0
+age=0
+revision=1
+
+# Is this an already installed library?
+installed=yes
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='c:/progra~1/pcre/lib'
diff --git a/win32/pcre/lib/libpcre.lib b/win32/pcre/lib/libpcre.lib
new file mode 100644
index 0000000..7b8be59
--- /dev/null
+++ b/win32/pcre/lib/libpcre.lib
Binary files differ
diff --git a/win32/pcre/lib/libpcreposix.la b/win32/pcre/lib/libpcreposix.la
new file mode 100644
index 0000000..39ab321
--- /dev/null
+++ b/win32/pcre/lib/libpcreposix.la
@@ -0,0 +1,32 @@
+# libpcreposix.la - a libtool library file
+# Generated by ltmain.sh - GNU libtool 1.4 (1.920 2001/04/24 23:26:18)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libpcreposix.a'
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Version information for libpcreposix.
+current=0
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='c:/progra~1/pcre/lib'
diff --git a/win32/pcre/manifest/pcre-3.9-lib.mft b/win32/pcre/manifest/pcre-3.9-lib.mft
new file mode 100644
index 0000000..024ac72
--- /dev/null
+++ b/win32/pcre/manifest/pcre-3.9-lib.mft
@@ -0,0 +1,13 @@
+include/pcre.h
+include/pcreposix.h
+lib/libpcre-bcc.def
+lib/libpcre-bcc.lib
+lib/libpcre.a
+lib/libpcre.def
+lib/libpcre.dll.a
+lib/libpcre.la
+lib/libpcre.lib
+lib/libpcreposix.a
+lib/libpcreposix.la
+manifest/pcre-3.9-lib.mft
+manifest/pcre-3.9-lib.ver
diff --git a/win32/pcre/manifest/pcre-3.9-lib.ver b/win32/pcre/manifest/pcre-3.9-lib.ver
new file mode 100644
index 0000000..1bf9d6f
--- /dev/null
+++ b/win32/pcre/manifest/pcre-3.9-lib.ver
@@ -0,0 +1,2 @@
+Pcre 3.9: developer files
+Pcre: Perl-compatible regular-expression library