<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>BoxedApp Blog</title>
	<atom:link href="http://boxedapp.com/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://boxedapp.com/blog</link>
	<description>BoxedApp: Tips'n'Tricks, Examples, Use Cases etc.</description>
	<pubDate>Tue, 16 Jun 2009 15:31:51 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>BoxedApp SDK 2.1, BoxedApp Packer 2.2</title>
		<link>http://boxedapp.com/blog/2009/06/16/boxedapp-sdk-21-boxedapp-packer-22/</link>
		<comments>http://boxedapp.com/blog/2009/06/16/boxedapp-sdk-21-boxedapp-packer-22/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 15:31:51 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[BoxedApp Packer]]></category>

		<category><![CDATA[BoxedApp Packer Release]]></category>

		<category><![CDATA[BoxedApp SDK]]></category>

		<category><![CDATA[BoxedApp SDK Release]]></category>

		<category><![CDATA[C++]]></category>

		<category><![CDATA[Delphi]]></category>

		<category><![CDATA[examples]]></category>

		<category><![CDATA[use cases]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=14</guid>
		<description><![CDATA[Released new versions of products of the BoxedApp series: BoxedApp SDK 2.1, BoxedApp Packer 2.2.
[ Download demo versions ]


Briefly on what has been done:

Virtual registry editor in BoxedApp Packer
API for intercepting functions
Minor improvements


Virtual registry editor in BoxedApp Packer
Formerly, all virtual registry operations were carried out in users’ plugins. If it was required to create even [...]]]></description>
			<content:encoded><![CDATA[<p>Released new versions of products of the BoxedApp series: BoxedApp SDK 2.1, BoxedApp Packer 2.2.<br />
<a href = "/download.html" target = "_blank"><b>[ Download demo versions ]</b></a><br />
<a name = "post_begin"></a><br />
<span id="more-14"></span><br />
Briefly on what has been done:</p>
<ul>
<li><a href = "#virtual_registry_editor">Virtual registry editor in BoxedApp Packer</a></li>
<li><a href = "#hooks">API for intercepting functions</a></li>
<li><a href = "#minor_changes">Minor improvements</a></li>
</ul>
<p><a name = "virtual_registry_editor"></a><br />
<h2>Virtual registry editor in BoxedApp Packer</h2>
<p>Formerly, all virtual registry operations were carried out in users’ plugins. If it was required to create even a single virtual registry key, one needed to create a plugin, which would use <a href = "http://boxedapp.com/boxedapppacker/help/index/plugin_api.html" target = "_blank">the BoxedApp SDK functions</a>.</p>
<p>Now BoxedApp Packer contains a full-fledged virtual registry editor. Literally with a couple of mouse clicks you can create the virtual keys you need and specify the parameter values.</p>
<p><small><a href = "#post_begin">[ back to top ]</a></small><br />
<a name = "hooks"></a><br />
<h2>API for intercepting functions</h2>
<p>To create a virtual file system / registry, BoxedApp SDK (this, by the way, is exactly what applications created with BoxedApp Packer use) uses the interception of system functions technique. A number of original ideas have allowed us to create an interception system compatible with any environment, and now the part of SDK that is in charge of the interception has become accessible to developers – SDK users.</p>
<p>Now BoxedApp SDK can be considered as a full-value alternative to <a href = "http://research.microsoft.com/en-us/projects/detours/" target = "_blank">Microsoft’s Detours</a>.</p>
<p>Be reminded that BoxedApp SDK supports 32-bit and 64-bit environments and also can be statically linked to applications that use VC++ / Delphi of any versions. And, of course, SDK can be used in any development environment that supports the use of DLL.</p>
<p>A couple of examples in C++ and Delphi that disable creating and opening the file named &#8220;1.txt&#8221;:</p>
<pre name="code" class="cpp" cols="35" rows="10">
typedef HANDLE (WINAPI *P_CreateFileW)(
	LPCWSTR lpFileName,
	DWORD dwDesiredAccess,
	DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttributes,
	HANDLE hTemplateFile);
P_CreateFileW g_pCreateFileW;

HANDLE WINAPI My_CreateFileW(
	LPCWSTR lpFileName,
	DWORD dwDesiredAccess,
	DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttributes,
	HANDLE hTemplateFile)
{
	if (0 == lstrcmpiW(lpFileName, L"1.txt"))
	{
		SetLastError(ERROR_FILE_EXISTS);
		return INVALID_HANDLE_VALUE;
	}
	else
		return g_pCreateFileW(
				lpFileName,
				dwDesiredAccess,
				dwShareMode,
				lpSecurityAttributes,
				dwCreationDisposition,
				dwFlagsAndAttributes,
				hTemplateFile);
}
...
BoxedAppSDK_Init();

PVOID pCreateFileW = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "CreateFileW");

HANDLE hHook__CreateFileW = BoxedAppSDK_HookFunction(pCreateFileW, &#038;My_CreateFileW, TRUE);

g_pCreateFileW = (P_CreateFileW)BoxedAppSDK_GetOriginalFunction(hHook__CreateFileW);

FILE* f = fopen("1.txt", "r");

// f is NULL
...

BoxedAppSDK_UnhookFunction(hHook__CreateFileW);
</pre>
<p>Delphi version of the same idea:</p>
<pre name="code" class="delphi" cols="35" rows="10">
type
TCreateFileW = 
   function(lpFileName: PWideChar;
            dwDesiredAccess, dwShareMode: Integer;
            lpSecurityAttributes: PSecurityAttributes;
            dwCreationDisposition, dwFlagsAndAttributes: DWORD;
            hTemplateFile: THandle): THandle; stdcall;

var
   OriginalCreateFileW: TCreateFileW;

function My_CreateFileW(
         lpFileName: PWideChar;
         dwDesiredAccess, dwShareMode: Integer;
         lpSecurityAttributes: PSecurityAttributes;
         dwCreationDisposition, dwFlagsAndAttributes: DWORD;
         hTemplateFile: THandle): THandle; stdcall;
begin
   if 0 = lstrcmpiW(lpFileName, '1.txt') then
   begin
      Result := INVALID_HANDLE_VALUE;
      SetLastError(ERROR_ALREADY_EXISTS);
   end
   else
      Result := 
        OriginalCreateFileW(
           lpFileName, 
           dwDesiredAccess,
           dwShareMode, 
           lpSecurityAttributes, 
           dwCreationDisposition, 
           dwFlagsAndAttributes, 
           hTemplateFile);
end;

var
   pCreateFileW: Pointer;
   hHook__CreateFileW: THandle;

begin
  Application.Initialize;

  BoxedAppSDK_Init;

  pCreateFileW := GetProcAddress(GetModuleHandle('kernel32.dll'), 'CreateFileW');
  hHook__CreateFileW := BoxedAppSDK_HookFunction(pCreateFileW, @My_CreateFileW, TRUE);
  OriginalCreateFileW := BoxedAppSDK_GetOriginalFunction(hHook__CreateFileW);

  // This line produces an exception because we prevent creating / opening '1.txt'
  TFileStream.Create('1.txt', fmCreate or fmOpenRead);

  BoxedAppSDK_UnhookFunction(hHook__CreateFileW);
end.
</pre>
<p><small><a href = "#post_begin">[ back to top ]</a></small><br />
<a name = "minor_changes"></a><br />
<h2>Minor improvements</h2>
<ul>
<li>Added support for the FILE_FLAG_DELETE_ON_CLOSE flag for virtual files</li>
<li>Fixed minor problems with launching virtual executable files created with Delphi</li>
<li>Created a more flexible system for storing virtual files in the memory</li>
</ul>
<p><small><a href = "#post_begin">[ back to top ]</a></small></p>
<p><a href = "/download.html" target = "_blank"><b>[ Download demo versions ]</b></a></p>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2009/06/16/boxedapp-sdk-21-boxedapp-packer-22/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Packing Entire MS PowerPoint Presentation into a Single EXE</title>
		<link>http://boxedapp.com/blog/2009/05/27/packing-entire-ms-powerpoint-presentation-into-a-single-exe/</link>
		<comments>http://boxedapp.com/blog/2009/05/27/packing-entire-ms-powerpoint-presentation-into-a-single-exe/#comments</comments>
		<pubDate>Wed, 27 May 2009 07:26:44 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[BoxedApp Packer]]></category>

		<category><![CDATA[examples]]></category>

		<category><![CDATA[use cases]]></category>

		<category><![CDATA[powerpoint]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=13</guid>
		<description><![CDATA[MS PowerPoint allows creating presentations viewable on any computer, even those that do not have the PowerPoint application installed. But what makes it really inconvenient is the necessity to click on the &#8220;Accept&#8221; button every time you open a file; besides, the number of files is so great&#8230; How nice would it be to turn [...]]]></description>
			<content:encoded><![CDATA[<p>MS PowerPoint allows creating presentations viewable on any computer, even those that do not have the PowerPoint application installed. But what makes it really inconvenient is the necessity to click on the &#8220;Accept&#8221; button every time you open a file; besides, the number of files is so great&#8230; How nice would it be to turn this whole set into a single executable file! <span id="more-13"></span></p>
<p>So, on the main menu, select: File -> Prepare for CD and then click on the &#8220;Copy to Folder&#8230;&#8221; button.</p>
<p>You should get a set of files similar to this one:</p>
<p><i><br />
gdiplus.dll<br />
intldate.dll<br />
play.bat<br />
playlist.txt<br />
pptview.exe<br />
ppvwintl.dll<br />
saext.dll<br />
unicows.dll<br />
presenation.ppt<br />
</i></p>
<p>To launch the presentation, you will need to use the play.bat file, which contains the command:</p>
<p><i>@pptview.exe /L &#8220;playlist.txt&#8221;</i></p>
<p>The content of playlist.txt file is:</p>
<p><i>presenation.ppt</i></p>
<p>Launch BoxedApp Packer, add the files, configure the command line<br />
parameters:</p>
<p><img src='/blog/wp-content/uploads/2009/05/pptview_files.png' alt='Files' class='alignnone' /></p>
<p>You can also make it the way that it would skip showing the prompt screen when the application starts:</p>
<p><img src='/blog/wp-content/uploads/2009/05/pptview_registry.png' alt='Registry' class='alignnone' /></p>
<p>Now click &#8220;Generate EXE&#8230;&#8221; and get a single packed file that doesn&#8217;t need any other files. When it is run, it will start demonstrating the slide show right off.</p>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2009/05/27/packing-entire-ms-powerpoint-presentation-into-a-single-exe/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Launching .NET Applications From Memory</title>
		<link>http://boxedapp.com/blog/2009/04/10/launching-net-applications-from-memory/</link>
		<comments>http://boxedapp.com/blog/2009/04/10/launching-net-applications-from-memory/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 12:38:01 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[BoxedApp Packer]]></category>

		<category><![CDATA[BoxedApp Packer Release]]></category>

		<category><![CDATA[BoxedApp SDK]]></category>

		<category><![CDATA[BoxedApp SDK Release]]></category>

		<category><![CDATA[C++]]></category>

		<category><![CDATA[examples]]></category>

		<category><![CDATA[use cases]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=12</guid>
		<description><![CDATA[We&#8217;ve issued new update of the BoxedApp SDK and BoxedApp Packer, which includes new function BoxedAppSDK_ExecuteDotNetApplication:

DWORD BoxedAppSDK_ExecuteDotNetApplication(LPCTSTR szPath, LPCTSTR szArgs);

[ Download demo version ]
You can launch .net applications from a virtual location (from a real file too, of course). One customer needed to launch FxCop from a memory. We&#8217;ve fixed a issue related with FxCop [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve issued new update of the BoxedApp SDK and BoxedApp Packer, which includes <span id="more-12"></span>new function <a href = "http://boxedapp.com/boxedappsdk/help/index/functions/boxedappsdk_executedotnetapplication.html" target = "_blank">BoxedAppSDK_ExecuteDotNetApplication</a>:</p>
<pre name="code" class="cpp" cols="35" rows="10">
DWORD BoxedAppSDK_ExecuteDotNetApplication(LPCTSTR szPath, LPCTSTR szArgs);
</pre>
<p><a href = "/download.html" target = "_blank"><b>[ Download demo version ]</b></a></p>
<p>You can launch .net applications from a virtual location (from a real file too, of course). <a href = "http://boxedapp.com/forum/viewtopic.php?f=3&#038;t=41" target = "_blank">One customer needed</a> to launch <a href = "http://www.microsoft.com/downloads/details.aspx?familyid=3389F7E4-0E55-4A4D-BC74-4AEABB17997B&#038;displaylang=en" target = "_blank">FxCop</a> from a memory. We&#8217;ve fixed a issue related with FxCop and&#8230; and we decided to provide a special function that runs a .net application within current process, BoxedAppSDK_ExecuteDotNetApplication.</p>
<p>Here a simple example of how to launch FxCop from a virtual location in C++:</p>
<pre name="code" class="cpp" cols="35" rows="10">
   BoxedAppSDK_Init();

   HANDLE
   hFile = 
   BoxedAppSDK_CreateVirtualFile( 
      _T("Z:\\FxCop\\FxCop.exe"), 
      GENERIC_WRITE, 
      FILE_SHARE_READ, 
      NULL, 
      CREATE_ALWAYS, 
      0, 
      NULL 
   );
#define DEF_COPY(name) CopyFileA("C:\\Program Files\\Microsoft FxCop 1.36\\" #name ,\
"Z:\\FxCop\\" #name , FALSE);
   DEF_COPY(CustomDictionary.xml);
   DEF_COPY(FxCop.exe);
   DEF_COPY(FxCop.exe.config);
   DEF_COPY(FxCopCmd.exe);
   DEF_COPY(FxCopCmd.exe.config);
   DEF_COPY(FxCopCommon.dll);
   DEF_COPY(FxCopSdk.dll);
   DEF_COPY(FxCopUI.dll);
   DEF_COPY(Microsoft.Cci.dll);
   DEF_COPY(MSSp3en.lex);
   DEF_COPY(MSSp3ena.lex);
   DEF_COPY(MSSpell3.dll);

   hFile = 
   BoxedAppSDK_CreateVirtualFile( 
      _T("Z:\\FxCop\\Engines\\IntrospectionAnalysisEngine.dll"), 
      GENERIC_WRITE, 
      FILE_SHARE_READ, 
      NULL, 
      CREATE_ALWAYS, 
      0, 
      NULL 
   );
#define DEF_COPY(name) \ 
CopyFileA("C:\\Program Files\\Microsoft FxCop 1.36\\Engines\\" #name ,\
 "Z:\\FxCop\\Engines\\" #name , FALSE);
   DEF_COPY(IntrospectionAnalysisEngine.dll);
   DEF_COPY(IntrospectionForms.dll);

   hFile = 
   BoxedAppSDK_CreateVirtualFile( 
      _T("Z:\\FxCop\\Repository\\system32.bin"), 
      GENERIC_WRITE, 
      FILE_SHARE_READ, 
      NULL, 
      CREATE_ALWAYS, 
      0, 
      NULL 
   );
#define DEF_COPY(name) \
CopyFileA("C:\\Program Files\\Microsoft FxCop 1.36\\Repository\\" #name ,\
 "Z:\\FxCop\\Repository\\" #name , FALSE);
   DEF_COPY(system32.bin);

   hFile = 
   BoxedAppSDK_CreateVirtualFile( 
      _T("Z:\\FxCop\\Repository\\Compatibility\\Desktop2.0.xml"), 
      GENERIC_WRITE, 
      FILE_SHARE_READ, 
      NULL, 
      CREATE_ALWAYS, 
      0, 
      NULL 
   );
#define DEF_COPY(name) \
CopyFileA("C:\\Program Files\\Microsoft FxCop 1.36\\Repository\\Compatibility\\" #name ,\
 "Z:\\FxCop\\Repository\\Compatibility\\" #name , FALSE);
   DEF_COPY(Desktop2.0.xml);
   DEF_COPY(Desktop2.0SP1.xml);
   DEF_COPY(Desktop2.0SP2.xml);
   DEF_COPY(Desktop3.0.xml);
   DEF_COPY(Desktop3.0SP1.xml);
   DEF_COPY(Desktop3.0SP2.xml);
   DEF_COPY(Desktop3.5.xml);
   DEF_COPY(Desktop3.5SP1.xml);

   hFile = 
   BoxedAppSDK_CreateVirtualFile( 
      _T("Z:\\FxCop\\Rules\\DesignRules.dll"), 
      GENERIC_WRITE, 
      FILE_SHARE_READ, 
      NULL, 
      CREATE_ALWAYS, 
      0, 
      NULL 
   );
#define DEF_COPY(name) \
CopyFileA("C:\\Program Files\\Microsoft FxCop 1.36\\Rules\\" #name , "Z:\\FxCop\\Rules\\" #name , FALSE);
   DEF_COPY(DesignRules.dll);
   DEF_COPY(GlobalizationRules.dll);
   DEF_COPY(InteroperabilityRules.dll);
   DEF_COPY(MobilityRules.dll);
   DEF_COPY(NamingRules.dll);
   DEF_COPY(PerformanceRules.dll);
   DEF_COPY(PortabilityRules.dll);
   DEF_COPY(SecurityRules.dll);
   DEF_COPY(UsageRules.dll);

   hFile = 
   BoxedAppSDK_CreateVirtualFile( 
      _T("Z:\\FxCop\\Xml\\CodeAnalysisReport.xsl"), 
      GENERIC_WRITE, 
      FILE_SHARE_READ, 
      NULL, 
      CREATE_ALWAYS, 
      0, 
      NULL 
   );
#define DEF_COPY(name) \
CopyFileA("C:\\Program Files\\Microsoft FxCop 1.36\\Xml\\" #name , "Z:\\FxCop\\Xml\\" #name , FALSE);
   DEF_COPY(CodeAnalysisReport.xsl);
   DEF_COPY(FxCopReport.xsd);
   DEF_COPY(FxCopReport.xsl);
   DEF_COPY(FxCopReportExcludes.xsl);
   DEF_COPY(FxCopRichConsoleOutput.xsl);
   DEF_COPY(VSConsoleOutput.xsl);

BoxedAppSDK_ExecuteDotNetApplication(_T("Z:\\FxCop\\FxCopCmd.exe"), _T("/o:out.txt /p:FxCopProject.FxCop"));
</pre>
<p><a href = "/download.html" target = "_blank"><b>[ Download demo version ]</b></a></p>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2009/04/10/launching-net-applications-from-memory/feed/</wfw:commentRss>
		</item>
		<item>
		<title>BoxedApp SDK 2.0.1, BoxedApp Packer 2.1.1</title>
		<link>http://boxedapp.com/blog/2009/01/31/boxedapp-sdk-201-boxedapp-packer-211/</link>
		<comments>http://boxedapp.com/blog/2009/01/31/boxedapp-sdk-201-boxedapp-packer-211/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 11:29:58 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[BoxedApp Packer]]></category>

		<category><![CDATA[BoxedApp Packer Release]]></category>

		<category><![CDATA[BoxedApp SDK]]></category>

		<category><![CDATA[BoxedApp SDK Release]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=11</guid>
		<description><![CDATA[We&#8217;ve tested BoxedApp under new Windows from MS, Windows 7. A few issues found and fixed.
[FIXED] ShellExecute doesn&#8217;t run virtual EXE under Windows 7
[FIXED] ActiveX registering in a virtual registry may not work properly under Windows 7
A small fix for all Windows:
[FIXED] Launching a lot of child processes cause memory and handles leak
New feature of [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve tested BoxedApp under new Windows from MS, Windows 7. A few issues found and fixed.</p>
<p>[FIXED] ShellExecute doesn&#8217;t run virtual EXE under Windows 7<br />
[FIXED] ActiveX registering in a virtual registry may not work properly under Windows 7</p>
<p>A small fix for all Windows:</p>
<p>[FIXED] Launching a lot of child processes cause memory and handles leak</p>
<p>New feature of the BoxedApp Packer:</p>
<p>[NEW] <a href = "/boxedapppacker/help/index/overview/virtual_path.html" target = "_blank">Environment variables are supported in a virtual path.</a></p>
<p><a href = "/download.html" target = "_blank"><b>[ Download demo version ]</b></a></p>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2009/01/31/boxedapp-sdk-201-boxedapp-packer-211/feed/</wfw:commentRss>
		</item>
		<item>
		<title>BoxedApp SDK 2.0, BoxedApp Packer 2.1</title>
		<link>http://boxedapp.com/blog/2009/01/28/boxedapp-sdk-20-boxedapp-packer-21/</link>
		<comments>http://boxedapp.com/blog/2009/01/28/boxedapp-sdk-20-boxedapp-packer-21/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 14:19:20 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[BoxedApp Packer]]></category>

		<category><![CDATA[BoxedApp Packer Release]]></category>

		<category><![CDATA[BoxedApp SDK]]></category>

		<category><![CDATA[BoxedApp SDK Release]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=10</guid>
		<description><![CDATA[Finally, we have made available the new releases with two extremely interesting features:

launching a virtual file-based process
shared virtual file system for several processes



Launching a virtual file-based process
Briefly, having created a virtual file with an embedded exe, you can launch a process upon that file:

BoxedAppSDK_Init();

HMODULE hModule = GetModuleHandle(NULL);
HRSRC hResInfo = FindResource(hModule, _T("BIN1"), _T("BIN"));
HGLOBAL hResData = LoadResource(hModule, [...]]]></description>
			<content:encoded><![CDATA[<p>Finally, we have made available the new releases with two extremely interesting features:</p>
<ul>
<li><a href = "#virtual_process">launching a virtual file-based process</a></li>
<li><a href = "#shared_env">shared virtual file system for several processes</a></li>
</ul>
<p><span id="more-10"></span></p>
<p><a name = "virtual_process"></a></p>
<h3>Launching a virtual file-based process</h3>
<p>Briefly, having created a virtual file with an embedded exe, you can launch a process upon that file:</p>
<pre name="code" class="cpp" cols="35" rows="10">
BoxedAppSDK_Init();

HMODULE hModule = GetModuleHandle(NULL);
HRSRC hResInfo = FindResource(hModule, _T("BIN1"), _T("BIN"));
HGLOBAL hResData = LoadResource(hModule, hResInfo);
LPVOID lpData = LockResource(hResData);
DWORD dwSize = SizeofResource(hModule, hResInfo);

HANDLE hFile = 
   BoxedAppSDK_CreateVirtualFile(
      _T("app1.exe"), 
      GENERIC_WRITE, 
      FILE_SHARE_READ, 
      NULL, 
      CREATE_NEW, 
      0, 
      NULL);

DWORD temp;
WriteFile(hFile, lpData, dwSize, &#038;temp, NULL);

CloseHandle(hFile);

ShellExecute(NULL, NULL, _T("app1.exe"), NULL, NULL, SW_SHOW);
</pre>
</p>
<p><a name = "shared_env"></a></p>
<h3>Shared virtual file system for several processes</h3>
<p>Prior to this, BoxedApp SDK was limited by a single process; however, we have received numerous requests, the summarized idea of which was to allow third-party applications to access the virtual files created in the original process.</p>
<p>We have improved BoxedApp, by having added the <a href = "http://boxedapp.com/boxedappsdk/help/index/functions/boxedappsdk_attachtoprocess.html" target = "_blank">BoxedAppSDK_AttachToProcess</a> function, which embeds BoxedApp in the process. Once has been embedded, the process can see all virtual files, which have been or are being created in the main process. It can modify them, etc. In other words, the both processes have the full access to the shared virtual file system. BoxedAppSDK_AttachToProcess can be called for several processes at once, and all of them would have the same file system.</p>
<p>Besides that, we have added the DEF_BOXEDAPPSDK_OPTION__EMBED_BOXEDAPP_IN_CHILD_PROCESSES option, which specifies whether or not BoxedApp is to be embedded in each child process (<b>by default this option is disabled</b>) created in the application:</p>
<pre name="code" class="cpp" cols="35" rows="10">
// yes, embed in child processes
BoxedAppSDK_EnableOption(DEF_BOXEDAPPSDK_OPTION__EMBED_BOXEDAPP_IN_CHILD_PROCESSES, TRUE);
...
// no, do not embed in child processes
BoxedAppSDK_EnableOption(DEF_BOXEDAPPSDK_OPTION__EMBED_BOXEDAPP_IN_CHILD_PROCESSES, FALSE);
</pre>
</p>
<p><a href = "/download.html" target = "_blank"><b>[ Download the DEMO versions ]</b></a></p>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2009/01/28/boxedapp-sdk-20-boxedapp-packer-21/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A virtual file based on IStream</title>
		<link>http://boxedapp.com/blog/2008/12/02/a-virtual-file-based-on-istream/</link>
		<comments>http://boxedapp.com/blog/2008/12/02/a-virtual-file-based-on-istream/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 10:32:02 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C++]]></category>

		<category><![CDATA[examples]]></category>

		<category><![CDATA[use cases]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=9</guid>
		<description><![CDATA[Briefly
A new function, BoxedAppSDK_CreateVirtualFileBasedOnIStream, has been added to BoxedApp SDK.
What For?
To provide even greater flexibility, BoxedApp SDK now allows creating virtual files based upon IStream, the standard COM interface. A programmer can now solely define the behavior of a virtual file.
The new function is declared as follows:

HANDLE BoxedAppSDK_CreateVirtualFileBasedOnIStream(   
    LPCTSTR [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Briefly</strong></p>
<p>A new function, <a href = "http://boxedapp.com/boxedappsdk/help/index/functions/boxedappsdk_createvirtualfilebasedonistream.html" target = "_blank">BoxedAppSDK_CreateVirtualFileBasedOnIStream</a>, has been added to BoxedApp SDK.</p>
<p><strong>What For?</strong></p>
<p>To provide even greater flexibility, BoxedApp SDK now allows creating virtual files based upon IStream, the standard COM interface. <span id="more-9"></span>A programmer can now solely define the behavior of a virtual file.</p>
<p>The new function is declared as follows:</p>
<pre name="code" class="cpp" cols="35" rows="10">
HANDLE BoxedAppSDK_CreateVirtualFileBasedOnIStream(   
    LPCTSTR szPath,    
    DWORD dwDesiredAccess,   
    DWORD dwShareMode,   
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,   
    DWORD dwCreationDisposition,   
    DWORD dwFlagsAndAttributes,   
    HANDLE hTemplateFile,    
  
    LPSTREAM pStream   
);
</pre>
<p>All, except the last, arguments repeat the arguments of the standard CreateFile function. The last argument is a pointer to IStream.</p>
<p>To check out BoxedApp SDK in action, download the demo version:<br />
<a href="http://boxedapp.com/download/boxedappsdk__demo.zip"  onClick="javascript: pageTracker._trackPageview('/tracker/boxedappsdk__download');" target = "_blank"><b><strong>[ Download demo version ]</strong></b></a><br />
Included are examples for C++, C#, VB.Net, Delphi, VB6.</p>
<p><strong>How does BoxedApp handle IStream data passed to it?</strong></p>
<p>For reading, it will call IStream::Write; for writing, that will be IStream::Read.<br />
Changing current position in a file &#8212; IStream::Seek. Please note: Obtaining file size is also implemented via IStream::Seek; approximately as follows:</p>
<pre name="code" class="cpp" cols="35" rows="10">
IStream* pStream;
...
LARGE_INTEGER liZero = { 0 };
ULARGE_INTEGER CurPos;

// Save current position
pStream->Seek(liZero, STREAM_SEEK_CUR, &#038;CurPos);

// Move to the end
ULARGE_INTEGER SizeOfFile;
pStream->Seek(liZero, STREAM_SEEK_END, &#038;SizeOfFile);

// Restore the file pointer
LARGE_INTEGER Pos;
Pos.Quad = CurPos.Quad;

ULARGE_INTEGER temp;
pStream->Seek(Pos, STREAM_SEEK_SET, &#038;temp);
</pre>
<p>For creating a new HANDLE of an IStream-based virtual file, IStream::Clone is to be called. The implementation of the method is to create a new instance of IStream, which would have its own pointer in the file.</p>
<p><strong>Example One. C++. Implementation of IStream on the base of a static buffer.</strong></p>
<p>Click on the &#8220;+ expand source&#8221; to the complete source code.</p>
<pre name="code" class="cpp:collapse" cols="35" rows="10">
class CVirtualFilePointer;
class CMemoryFile;

class CMemoryFileLock
{
private:
	CMemoryFile* m_pMemoryFile;
public:
	CMemoryFileLock(CMemoryFile* pMemoryFile);
	~CMemoryFileLock();
};

// A file based on fixed memory block
class CMemoryFile
{
	friend class CVirtualFilePointer;
	friend class CMemoryFileLock;

private:
	LONG m_nRefCount;
	PBYTE m_p;
	DWORD m_dwSize;
	CRITICAL_SECTION m_cs;

private:
	CMemoryFile(PVOID p, DWORD size);
	~CMemoryFile();

	IStream* CreateStream();
	void AddRef();
	void Release();
public:
	static IStream* Create(PVOID p, DWORD size);
};

class CVirtualFilePointer : public IStream
{
	friend class CVirtualFile;

private:
	LONG m_nRefCount;
	CMemoryFile* m_pFile;
	DWORD m_dwPosition;

public:
	CVirtualFilePointer(CMemoryFile* pMemoryFile) : 
		m_nRefCount(1), 
		m_dwPosition(0)
	{
		m_pFile = pMemoryFile;
		m_pFile->AddRef();
	}

	virtual ~CVirtualFilePointer()
	{
		m_pFile->Release();
	}

protected:
	// IUnknown
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
	{
		*ppvObject = NULL;

		if (IsEqualIID(IID_IUnknown, riid))
			*ppvObject = this;
		else if (IsEqualIID(IID_IStream, riid))
			*ppvObject = this;
		else if (IsEqualIID(IID_ISequentialStream, riid))
			*ppvObject = this;

		if (NULL != *ppvObject)
		{
			AddRef();
			return S_OK;
		}
		else
			return E_NOINTERFACE;
	}
    
    virtual ULONG STDMETHODCALLTYPE AddRef()
	{
		InterlockedIncrement(&#038;m_nRefCount);
		return m_nRefCount;
	}
    
    virtual ULONG STDMETHODCALLTYPE Release()
	{
		InterlockedDecrement(&#038;m_nRefCount);

		LONG nRefCount = m_nRefCount;

		if (0 == m_nRefCount)
			delete this;

		return nRefCount;
	}

	// ISequentialStream
    virtual HRESULT STDMETHODCALLTYPE Read(void* pv, ULONG cb, ULONG* pcbRead)
	{
		CMemoryFileLock lock(m_pFile);

		DWORD dwBytesToRead;

		if (m_dwPosition < 0 || m_dwPosition > m_pFile->m_dwSize)
			dwBytesToRead = 0;
		else
			dwBytesToRead = cb < m_pFile->m_dwSize - m_dwPosition ? 
cb : m_pFile->m_dwSize - m_dwPosition;

		CopyMemory(pv, m_pFile->m_p + m_dwPosition, dwBytesToRead);

		m_dwPosition += dwBytesToRead;

		if (NULL != pcbRead)
			*pcbRead = dwBytesToRead;

		return S_OK;
	}
    
    virtual HRESULT STDMETHODCALLTYPE Write(const void* pv, ULONG cb, ULONG* pcbWritten)
	{
		CMemoryFileLock lock(m_pFile);

		DWORD dwBytesToWrite;
		
		if (m_dwPosition < 0 || m_dwPosition > m_pFile->m_dwSize)
			dwBytesToWrite = 0;
		else
			dwBytesToWrite = cb < m_pFile->m_dwSize - m_dwPosition ? 
cb : m_pFile->m_dwSize - m_dwPosition;

		CopyMemory(m_pFile->m_p + m_dwPosition, pv, dwBytesToWrite);

		m_dwPosition += dwBytesToWrite;

		if (NULL != pcbWritten)
			*pcbWritten = dwBytesToWrite;

		return S_OK;
	}

	// IStream
    virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
	{
		CMemoryFileLock lock(m_pFile);

		// Note: new position can be more than m_dwSize

		switch (dwOrigin)
		{
			case STREAM_SEEK_CUR:
			{
				m_dwPosition += dlibMove.QuadPart;
				break;
			}
			case STREAM_SEEK_END:
			{
				m_dwPosition = m_pFile->m_dwSize + dlibMove.QuadPart;
				break;
			}
			case STREAM_SEEK_SET:
			{
				m_dwPosition = dlibMove.QuadPart;
				break;
			}
			default:
			{
				return E_FAIL;
			}
		}

		if (NULL != plibNewPosition)
			plibNewPosition->QuadPart = m_dwPosition;

		return S_OK;
	}
    
    virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize)
	{
		// TODO:

		return E_NOTIMPL;
	}

    virtual HRESULT STDMETHODCALLTYPE Clone(IStream** ppstm)
	{
		*ppstm = m_pFile->CreateStream();
		return S_OK;
	}
    
    virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten){return E_NOTIMPL;}    
    virtual HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags){return E_NOTIMPL;}
    virtual HRESULT STDMETHODCALLTYPE Revert(){return E_NOTIMPL;}    
    virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType){return E_NOTIMPL;}    
    virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType){return E_NOTIMPL;}    
    virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pstatstg, DWORD grfStatFlag){return E_NOTIMPL;}
};

CMemoryFileLock::CMemoryFileLock(CMemoryFile* pMemoryFile) : 
	m_pMemoryFile(pMemoryFile)
{
	EnterCriticalSection(&#038;pMemoryFile->m_cs);
}

CMemoryFileLock::~CMemoryFileLock()
{
	LeaveCriticalSection(&#038;m_pMemoryFile->m_cs);
}

CMemoryFile::CMemoryFile(PVOID p, DWORD size) : 
	m_p((PBYTE)p), 
	m_dwSize(size), 
	m_nRefCount(0)
{
	InitializeCriticalSection(&#038;m_cs);
}

CMemoryFile::~CMemoryFile()
{
	DeleteCriticalSection(&#038;m_cs);
}

IStream* CMemoryFile::CreateStream()
{
	return new CVirtualFilePointer(this);
}

void CMemoryFile::AddRef()
{
	InterlockedIncrement(&#038;m_nRefCount);
}

void CMemoryFile::Release()
{
	InterlockedDecrement(&#038;m_nRefCount);

	if (0 == m_nRefCount)
		delete this;
}

IStream* CMemoryFile::Create(PVOID p, DWORD size)
{
	CMemoryFile* pMemoryFile = new CMemoryFile(p, size);
	return pMemoryFile->CreateStream();
}
</pre>
<p><strong>Example Two. C#. A virtual file as a part of the source file.</strong></p>
<p>To check out this example in action, download the demo version:<br />
<a href="http://boxedapp.com/download/boxedappsdk__demo.zip"  onClick="javascript: pageTracker._trackPageview('/tracker/boxedappsdk__download');" target = "_blank"><b><strong>[ Download demo version ]</strong></b></a></p>
<p>The example is located in the samples\C#\Sample3_CustomVirtualFileSystem folder.</p>
<p>Click on the &#8220;+ expand source&#8221; to the complete source code.</p>
<pre name="code" class="c-sharp:collapse" cols="35" rows="10">
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.IO;

namespace Sample3_CustomVirtualFileSystem
{
    class CustomFileStream : IStream
    {
        private long _Offset;
        private long _Length;
        private string _FilePath;
        private Stream _Stream;

        public CustomFileStream(string FilePath, long Offset, long Length)
        {
            _FilePath = FilePath;
            _Stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            _Offset = Offset;
            _Length = Length;
        }

        public CustomFileStream(string FilePath, long Offset)
        {
            _FilePath = FilePath;
            _Stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            _Offset = Offset;
            _Length = _Stream.Length - _Offset;
        }

        #region IStream Members

        public void Read(byte[] pv, int cb, IntPtr pcbRead)
        {
            if (_Stream.Position > _Offset + _Length)
                cb = 0;
            else if (_Stream.Position + cb > _Offset + _Length)
                cb = (int)(_Offset + _Length - _Stream.Position);

            int nReadBytes = _Stream.Read(pv, 0, cb);

            if (IntPtr.Zero != pcbRead)
                Marshal.WriteIntPtr(pcbRead, new IntPtr(nReadBytes));
        }

        public void Write(byte[] pv, int cb, IntPtr pcbWritten)
        {
            if (_Stream.Position > _Offset + _Length)
                cb = 0;
            else if (_Stream.Position + cb > _Offset + _Length)
                cb = (int)(_Offset + _Length - _Stream.Position);

            int nWrittenBytes = _Stream.Read(pv, 0, cb);

            if (IntPtr.Zero != pcbWritten)
                Marshal.WriteIntPtr(pcbWritten, new IntPtr(nWrittenBytes));
        }

        public void Clone(out IStream ppstm)
        {
            ppstm = new CustomFileStream(_FilePath, _Offset, _Length);
        }

        public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
        {
            SeekOrigin Origin = (SeekOrigin)dwOrigin;
            long NewPosition = 0;

            switch (Origin)
            {
                case SeekOrigin.Begin:
                    {
                        NewPosition = _Stream.Seek(_Offset + dlibMove, Origin);

                        break;
                    }
                case SeekOrigin.Current:
                    {
                        NewPosition = _Stream.Seek(dlibMove, Origin);

                        break;
                    }
                case SeekOrigin.End:
                    {
                        NewPosition = _Stream.Seek(_Offset + _Length + dlibMove, SeekOrigin.Begin);

                        break;
                    }
            }

            NewPosition -= _Offset;

            if (NewPosition < 0)
                NewPosition = 0;
            else if (NewPosition > _Length)
                NewPosition = _Length;

            if (IntPtr.Zero != plibNewPosition)
                Marshal.WriteInt64(plibNewPosition, NewPosition);
        }

        public void Commit(int grfCommitFlags)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void LockRegion(long libOffset, long cb, int dwLockType)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void Revert()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void SetSize(long libNewSize)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void UnlockRegion(long libOffset, long cb, int dwLockType)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}
</pre>
<p>To check out this example in action, download the demo version:<br />
<a href="http://boxedapp.com/download/boxedappsdk__demo.zip"  onClick="javascript: pageTracker._trackPageview('/tracker/boxedappsdk__download');" target = "_blank"><b><strong>[ Download demo version ]</strong></b></a></p>
<p>Included are examples for C++, C#, VB.Net, Delphi, VB6.</p>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2008/12/02/a-virtual-file-based-on-istream/feed/</wfw:commentRss>
		</item>
		<item>
		<title>C++ / CLI - How To Use Managed C++ DLL when Microsoft Visual C++ Redistributable is not installed?</title>
		<link>http://boxedapp.com/blog/2008/07/16/c-cli-how-to-use-managed-c-dll-when-microsoft-visual-c-redistributable-is-not-installed/</link>
		<comments>http://boxedapp.com/blog/2008/07/16/c-cli-how-to-use-managed-c-dll-when-microsoft-visual-c-redistributable-is-not-installed/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 14:34:49 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C++]]></category>

		<category><![CDATA[examples]]></category>

		<category><![CDATA[use cases]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=7</guid>
		<description><![CDATA[If your .NET application uses components written in Managed C++, you face the necessity to distribute Microsoft Visual C++ Redistributable with it. If one attempts to launch such application in a system that doesn’t have the corresponding Microsoft Visual C++ Redistributable installed, the user will get a warning &#8220;This application has failed to start because [...]]]></description>
			<content:encoded><![CDATA[<p>If your .NET application uses components written in Managed C++, you face the necessity to distribute Microsoft Visual C++ Redistributable with it. If one attempts to launch such application in a system that doesn’t have the corresponding Microsoft Visual C++ Redistributable installed, the user will get a warning &#8220;This application has failed to start because the application configuration is incorrect&#8221;. <span id="more-7"></span> Why this happens, and can that be done without installing Microsoft Visual C++ Redistributable?</p>
<p>With the common approach, a DLL written in Managed C++ has a dependency from Microsoft Visual C++ Runtime, DLL files from which cannot be linked statically. The traditional solution is the inclusion of Microsoft Visual C++ Redistributable in the setup file.</p>
<p>With BoxedApp SDK, you can emulate the availability of Microsoft Visual C++ Runtime. Right after the application is launched, before using the components compiled in Managed C++, create the files, from which the Managed C++ DLL depends (<a href = "#how_to_find_dependency">how to find paths to dependencies</a>):</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;

namespace WindowsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();

            string PathOfWinSxS = 
                Directory.GetParent(Environment.SystemDirectory).FullName + 
                @"\WinSxS";

            if (!Directory.Exists(PathOfWinSxS))
                // Win2k
                PathOfWinSxS = Application.StartupPath;

            Stream fromStream =
                Assembly.
                GetExecutingAssembly().
                GetManifestResourceStream("WindowsApplication1.res.msvcm80d.dll");

            CreateDLLInMemory(
                PathOfWinSxS + 
                @"\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\msvcm80d.dll",
                fromStream);

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());

            BoxedAppSDK.NativeMethods.BoxedAppSDK_Exit();
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr hObject);

        static void CreateDLLInMemory(string strVirtualPath, Stream stream)
        {
            const int BufferSize = 1024;
            byte[] buffer = new byte[BufferSize];

            IntPtr hHandle =
                BoxedAppSDK.NativeMethods.BoxedAppSDK_CreateVirtualFile(
                strVirtualPath,
                BoxedAppSDK.NativeMethods.EFileAccess.GenericWrite,
                BoxedAppSDK.NativeMethods.EFileShare.Read,
                IntPtr.Zero,
                BoxedAppSDK.NativeMethods.ECreationDisposition.New,
                BoxedAppSDK.NativeMethods.EFileAttributes.Normal,
                IntPtr.Zero);
            CloseHandle(hHandle);

            int nReadBytes;

            using (FileStream VirtualFileStream = new FileStream(strVirtualPath, FileMode.Open))
            {
                while ((nReadBytes = stream.Read(buffer, 0, BufferSize)) > 0)
                    VirtualFileStream.Write(buffer, 0, nReadBytes);
            }
        }
    }
}
</pre>
<p><a name = "how_to_find_dependency"></a>To find out, which exact DLL files does your Managed C++ DLL has dependencies from, use the depends.exe application from Visual Studio setup. Open your Managed C++ DLL in depends.exe, and you will easily find, which VC++ Runtime components it depends from:</p>
<p><a href='http://boxedapp.com/blog/wp-content/uploads/2008/07/depends.png' target = "_blank"><img src="http://boxedapp.com/blog/wp-content/uploads/2008/07/depends.png" alt="" title="depends" width="500" height="400" class="aligncenter size-full wp-image-8" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2008/07/16/c-cli-how-to-use-managed-c-dll-when-microsoft-visual-c-redistributable-is-not-installed/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Use ActiveX components without registration</title>
		<link>http://boxedapp.com/blog/2008/06/29/use-activex-components-without-registration/</link>
		<comments>http://boxedapp.com/blog/2008/06/29/use-activex-components-without-registration/#comments</comments>
		<pubDate>Sun, 29 Jun 2008 16:55:55 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[activex]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=6</guid>
		<description><![CDATA[Many applications use ActiveX and COM components. But all ActiveXs should be registered in the system registry to be used properly. This is a problem:

registration in the registry requires admin rights
sometimes registration influences to other applications
for example, your application uses Flash 7, but another application requires Flash 9
your application should register an ActiveX at startup [...]]]></description>
			<content:encoded><![CDATA[<p>Many applications use ActiveX and COM components. But all ActiveXs should be registered in the system registry to be used properly. This is a problem:</p>
<ul>
<li>registration in the registry requires admin rights</li>
<li>sometimes registration influences to other applications<br />
<i>for example, your application uses Flash 7, but another application requires Flash 9</i></p>
<li>your application should register an ActiveX at startup and unregister it when ActiveX is not needed anymore<br />
<i>for example, your application is so-called <a href = "http://en.wikipedia.org/wiki/Portable_application" target = "_blank">portable application</a></i>
</li>
</ul>
<p><span id="more-6"></span>How to solve the task using BoxedApp?</p>
<p>BoxedApp provides a very interesting function <a href = "http://www.boxedapp.com/boxedappsdk/help/index/functions/boxedappsdk_registercomlibraryinvirtualregistry.html" target = "_blank">BoxedAppSDK_RegisterCOMLibraryInVirtualRegistry</a>. This function does the same things as <a href = "http://en.wikipedia.org/wiki/Regsvr32" target = "_blank">regsvr32</a> does.  BoxedAppSDK_RegisterCOMLibraryInVirtualRegistry loads a file (virtual or real) and calls <a href = "http://msdn.microsoft.com/en-us/library/ms682162(VS.85).aspx" target = "_blank">DllRegisterServer</a>. What&#8217;s important: <b>all changes of the registry save in virtual registry, not real!</b></p>
<p>So, when an application creates an ActiveX, COM subsystem finds all what it needs in virtual registry.</p>
<p>As a result, the system registry remains unchanged, and COM subsystem &#8220;thinks&#8221; that the ActiveX is really registered in the system.</p>
<p><a href="/download/boxedappsdk__demo.zip" onClick="javascript: pageTracker._trackPageview('/tracker/boxedappsdk__download');"></b><strong>Want to see in action! Download BoxedApp SDK right now!</strong></b></a></p>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2008/06/29/use-activex-components-without-registration/feed/</wfw:commentRss>
		</item>
		<item>
		<title>.NET Runtime Embedding</title>
		<link>http://boxedapp.com/blog/2008/06/11/net-runtime-embedding/</link>
		<comments>http://boxedapp.com/blog/2008/06/11/net-runtime-embedding/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 08:22:54 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[examples]]></category>

		<category><![CDATA[use cases]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=5</guid>
		<description><![CDATA[If you are into developing .NET applications, you are likely to know that it requires .NET Runtime to have the success running them. If the runtime suite is not installed, whenever the program attempts to launch, it shows an ugly messagebox notifying you that mscoree.dll could not be found.
So, we&#8217;ve got a .net application WindowsApplication1.exe, [...]]]></description>
			<content:encoded><![CDATA[<p>If you are into developing .NET applications, you are likely to know that it requires .NET Runtime to have the success running them. <span id="more-5"></span>If the runtime suite is not installed, whenever the program attempts to launch, it shows an ugly messagebox notifying you that mscoree.dll could not be found.</p>
<p>So, we&#8217;ve got a .net application WindowsApplication1.exe, which displays a simple form with a progress bar and a couple of links. Now we are to create the environment where WindowsApplication1.exe would successfully launch on systems that don&#8217;t have .net runtime.</p>
<p>BoxedApp SDK creates the infrastructure of a virtual file system and a virtual registry; so once the corresponding virtual kes and virtual files are created, the .NET application can be launched successfully.</p>
<p>It is known that the hive HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework contains the key InstallRoot that points to the folder with subfolders with different versions of.net runtime. For instance, on my computer the key contains the value  содержит значение &#8220;C:\WINDOWS\Microsoft.NET\Framework&#8221;. That folder includes the following runtime versions:</p>
<p>v1.0.3705<br />
v1.1.4322<br />
v2.0.50727<br />
v3.0<br />
v3.5</p>
<p>In this example, we assume that our runtime version is 2.0.50727. For the folder for storing our runtime files, let&#8217;s choose some path; e.g., C:\DotNet. Next, let&#8217;s create the virtual files within that folder, and the application will see it as if .net runtime was actually installed on the computer.</p>
<p>So, let&#8217;s create our virtual key:</p>
<pre name="code" class="cpp" cols="35" rows="10">
// Initialize BoxedAppSDK
BoxedAppSDK_Init();

tstring strDotNetRoot = _T("C:\\DotNet");

DWORD dwDisposition;
HKEY hKey__DotNet;
LONG lRes = 
BoxedAppSDK_CreateVirtualRegKey(
	HKEY_LOCAL_MACHINE, 
	_T("SOFTWARE\\Microsoft\\.NETFramework"), 
	0, 
	NULL, 
	REG_OPTION_NON_VOLATILE, 
	KEY_ALL_ACCESS, 
	NULL, 
	&#038;hKey__DotNet, 
	&#038;dwDisposition);

LPCTSTR szValue = _T("C:\\DotNet\\");
RegSetValueEx(hKey__DotNet, _T("InstallRoot"), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));
</pre>
<p>We will need paths to the system folders:</p>
<pre name="code" class="cpp" cols="35" rows="10">
TCHAR szWinDir[MAX_PATH] = { 0 };
GetWindowsDirectory(szWinDir, MAX_PATH);
tstring strWinDir = szWinDir;

TCHAR szSystemDir[MAX_PATH] = { 0 };
GetSystemDirectory(szSystemDir, MAX_PATH);
tstring strSystemDir = szSystemDir;
</pre>
<p>In the resource file, specify which files are to be embedded in the application. We are going to embed both .net runtime and the WindowsApplication1.exe files, plus the AppLauncher.dll assembly, which we&#8217;re going to cover a bit further:</p>
<pre name="code" class="cpp" cols="35" rows="10">
WindowsApplication1.exe BIN "WindowsApplication1.exe"
AppLauncher.dll BIN "AppLauncher.dll"

mscoree.dll BIN "system32\\mscoree.dll"
mscorjit.dll BIN "v2.0.50727\\mscorjit.dll"
mscorwks.dll BIN "v2.0.50727\\mscorwks.dll"
comctl32.dll BIN "WinSxS\\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2982_x-ww_ac3f9c03\\comctl32.dll"
msvcr80.dll BIN "WinSxS\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2\\msvcr80.dll"
msvcr80d.dll BIN "WinSxS\\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\\msvcr80d.dll"
System.Windows.Forms.dll BIN "assembly\\GAC_MSIL\\System.Windows.Forms\\2.0.0.0__b77a5c561934e089\\System.Windows.Forms.dll"
mscorlib.dll BIN "assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\mscorlib.dll"
mscorrc.dll BIN "v2.0.50727\\mscorrc.dll"
sorttbls.nlp BIN "assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\sorttbls.nlp"
sortkey.nlp BIN "assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\sortkey.nlp"
System.dll BIN "v2.0.50727\\System.dll"
System.Data.dll BIN "v2.0.50727\\System.Data.dll"
System.Drawing.dll BIN "v2.0.50727\\System.Drawing.dll"
Culture.dll BIN "v2.0.50727\\Culture.dll"
Accessibility.dll BIN "v2.0.50727\\Accessibility.dll"
GdiPlus.dll BIN "system32\\GdiPlus.dll"
</pre>
<p>In the properties of the rc file (right-click on the rc file and then select Properties, Configuration Properties -> Resources -> General, Additional Include Directories), specify the additional folders to be searched for the files:</p>
<p><code><br />
"$(FrameworkDir)";"$(SystemRoot)";"..\WindowsApplication1\bin\x86\$(ConfigurationName)";"..\AppLauncher\bin\x86\$(ConfigurationName)"<br />
</code></p>
<p>Here&#8217;s a light helper function for handling resources:</p>
<pre name="code" class="cpp" cols="35" rows="10">
void LoadResourceHelper( /* in */ LPCTSTR lpszName, 
                         /* in */ LPCTSTR lpszType, 
                         /* out */ LPVOID&#038; lpData, 
                         /* out */ DWORD&#038; dwSize)
{
    HMODULE hModule = GetModuleHandle(NULL);
    HRSRC hResInfo = FindResource(hModule, lpszName, lpszType);
    HGLOBAL hResData = LoadResource(hModule, hResInfo);
    lpData = LockResource(hResData);
    dwSize = SizeofResource(hModule, hResInfo);
}
</pre>
<p>And here&#8217;s the function for creating a virtual file; the content will be taken from the specified resource:</p>
<pre name="code" class="cpp" cols="35" rows="10">
void CreateVirtualFileFromResource(LPCTSTR szVirtualPath, LPCTSTR szResName, LPCTSTR szResType)
{
	DWORD temp;

	LPVOID pData;
	DWORD dwSize;

	LoadResourceHelper(szResName, szResType, pData, dwSize);

	HANDLE hFile = BoxedAppSDK_CreateVirtualFile(szVirtualPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, 0, NULL);
	WriteFile(hFile, pData, dwSize, &#038;temp, NULL);
	CloseHandle(hFile);
}
</pre>
<p>Now we can create the virtual files, required for the successful performance of the .net runtime:</p>
<pre name="code" class="cpp" cols="35" rows="10">
struct SFileResInfo
{
	tstring strVirtualPath;
	LPCTSTR szResName;
};

const SFileResInfo ResInfo[] = 
{
		{ strSystemDir + _T("\\mscoree.dll"), _T("mscoree.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\mscorjit.dll"), _T("mscorjit.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\mscorwks.dll"), _T("mscorwks.dll") }, 

		{ strWinDir + _T("\\WinSxS\\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2982_x-ww_ac3f9c03\\comctl32.dll"), _T("comctl32.dll") }, 
		{ strSystemDir + _T("\\comctl32.dll"), _T("comctl32.dll") }, 

		{ strWinDir + _T("\\WinSxS\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2\\msvcr80.dll"), _T("msvcr80.dll") }, 
		{ strSystemDir + _T("\\msvcr80.dll"), _T("msvcr80.dll") }, 

		{ strWinDir + _T("\\assembly\\GAC_MSIL\\System.Windows.Forms\\2.0.0.0__b77a5c561934e089\\System.Windows.Forms.dll"), _T("System.Windows.Forms.dll") }, 

		{ strWinDir + _T("\\assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\mscorlib.dll"), _T("mscorlib.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\mscorrc.dll"), _T("mscorrc.dll") }, 

		{ strWinDir + _T("\\assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\sorttbls.nlp"), _T("sorttbls.nlp") }, 
		{ strWinDir + _T("\\assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\sortkey.nlp"), _T("sortkey.nlp") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\System.dll"), _T("System.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\System.Data.dll"), _T("System.Data.dll") }, 
		{ strDotNetRoot + _T("\\v2.0.50727\\System.Drawing.dll"), _T("System.Drawing.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\Culture.dll"), _T("Culture.dll") }, 

		{ strWinDir + _T("\\assembly\\GAC_MSIL\\System\\2.0.0.0__b77a5c561934e089\\System.dll"), _T("System.dll") }, 
		{ strWinDir + _T("\\assembly\\GAC_MSIL\\System.Drawing\\2.0.0.0__b03f5f7f11d50a3a\\System.Drawing.dll"), _T("System.Drawing.dll") }, 

		{ strWinDir + _T("\\Microsoft.NET\\Framework\\v2.0.50727\\Accessibility.dll"), _T("Accessibility.dll") }, 
		{ strWinDir + _T("\\assembly\\GAC_MSIL\\Accessibility\\2.0.0.0__b03f5f7f11d50a3a\\Accessibility.dll"), _T("Accessibility.dll") }, 

		{ strSystemDir + _T("\\GdiPlus.dll"), _T("GdiPlus.dll") }, 


		{ _T("C:\\AppLauncher.dll"), _T("AppLauncher.dll") }, 
		{ _T("C:\\WindowsApplication1.exe"), _T("WindowsApplication1.exe") }
};

for (int i = 0; i < sizeof(ResInfo) / sizeof(ResInfo[0]); i++)
	CreateVirtualFileFromResource(ResInfo[i].strVirtualPath.c_str(), ResInfo[i].szResName, _T("BIN"));
</pre>
<p>To get along with .net runtime, we&#8217;re going to use the mscoree.dll library (please note that mscoree.dll is embedded in the application). mscoree.dll exports the function CorBindToRuntimeEx, which will give us the interface ICLRRuntimeHost. The method ICLRRuntimeHost::ExecuteInDefaultAppDomain loads the assembly and calls the specified method. However, that method is to have a very specific signature; you cannot call just any method, but we&#8217;re going to cover this later. So, here&#8217;s our ICLRRuntimeHost:</p>
<pre name="code" class="cpp" cols="35" rows="10">
HMODULE hMSCoree = LoadLibrary((strSystemDir + _T("\\mscoree.dll")).c_str());

typedef HRESULT (__stdcall *P_CorBindToRuntimeEx)(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
P_CorBindToRuntimeEx pCorBindToRuntimeEx = (P_CorBindToRuntimeEx)GetProcAddress(hMCoree, "CorBindToRuntimeEx");

ICLRRuntimeHost* pCLRRuntimeHost = NULL;
pCorBindToRuntimeEx(L"v2.0.50727", NULL, 0, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (void**)&#038;pCLRRuntimeHost);
</pre>
<p>ICLRRuntimeHost::ExecuteInDefaultAppDomain can be called only by a method with the following signature:</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
int SomeMethod (string Argument);
</pre>
<p>Now, our job is to load the assembly of the .net application and call its point of entry. However, the point of entry has a different signature:</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
static void Main();
</pre>
<p>Therefore, we&#8217;re going to create another assembly, which will be a class with a static method, which in its turn will load the assembly of the main application and call its point of entry:</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
using System;
using System.Reflection;
using System.Text;

namespace AppLauncher
{
    public class Launcher
    {
        public static int Launch(string strPath)
        {
            Assembly assembly = Assembly.LoadFile(strPath);
            assembly.EntryPoint.Invoke(null, null);

            return 0;
        }
    }
}
</pre>
<p>Now we&#8217;ve got everything ready for running the application:</p>
<pre name="code" class="cpp" cols="35" rows="10">
pCLRRuntimeHost->Start();

DWORD nRetValue;
pCLRRuntimeHost->ExecuteInDefaultAppDomain(
	L"C:\\AppLauncher.dll", 
	L"AppLauncher.Launcher", 
	L"Launch", 
	L"C:\\WindowsApplication1.exe", 
	&#038;nRetValue);

pCLRRuntimeHost->Stop();

pCLRRuntimeHost->Release();

FreeLibrary(hMSCoree);
</pre>
<p>Related links:</p>
<ul>
<li><a href = "http://boxedapp.com/download/boxedappsdk__demo.zip" target = "_blank">Download example; see the folder samples\Misc\DotNetEmbedding</a></li>
<li><a href = "http://msdn.microsoft.com/en-us/library/99sz37yh(VS.71).aspx" target = "_blank">Description of CorBindToRuntimeEx</a></li>
<li><a href = "http://boxedapp.com/boxedappsdk/help/index/functions/boxedappsdk_createvirtualregkey.html" target = "_blank">BoxedAppSDK_CreateVirtualRegKey</a></li>
<li><a href = "http://boxedapp.com/boxedappsdk/help/index/functions/boxedappsdk_createvirtualfile.html" target = "_blank">BoxedAppSDK_CreateVirtualFile</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2008/06/11/net-runtime-embedding/feed/</wfw:commentRss>
		</item>
		<item>
		<title>.NET Applications: How to Hide Assemblies And Unmanaged DLLs</title>
		<link>http://boxedapp.com/blog/2008/06/11/net-applications-how-to-hide-assembly-and-unmanaged-dlls/</link>
		<comments>http://boxedapp.com/blog/2008/06/11/net-applications-how-to-hide-assembly-and-unmanaged-dlls/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 08:21:32 +0000</pubDate>
		<dc:creator>Artem A. Razin</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[examples]]></category>

		<category><![CDATA[use cases]]></category>

		<guid isPermaLink="false">http://boxedapp.com/blog/?p=4</guid>
		<description><![CDATA[One interesting task I&#8217;ve heard from one of our first customers is hidding assemblies and unmanaged DLLs. The target language is C#. Let&#8217;s explore how to solve this task with BoxedApp SDK.
At the first, decide how to store an assembly. In this example, I keep an assembly in static array. To create C# code with [...]]]></description>
			<content:encoded><![CDATA[<p>One interesting task I&#8217;ve heard from one of our first customers is hidding assemblies and unmanaged DLLs. The target language is C#. <span id="more-4"></span>Let&#8217;s explore how to solve this task with BoxedApp SDK.</p>
<p>At the first, decide how to store an assembly. In this example, I keep an assembly in static array. To create C# code with such array, I use the following code:</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ConvertBinToSharpCode
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] data = File.ReadAllBytes(args[0]);

            Console.Write("namespace BinData\n{\n\tpublic class Data1\n\t\t{\n\n\t\tpublic static byte[] data = \n{\n");

            foreach (byte b in data)
            {
                Console.Write(b.ToString() + ",");
            }

            Console.Write("};\n}\n}\n");
        }
    }
}
</pre>
<p>It takes one argument (path to an assembly) and outputs C# code, save it as data.cs, for example:</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
namespace BinData
{
	public class Data1
		{

		public static byte[] data = 
{
77,90,144,0,3,0 .......
}
}
</pre>
<p>Include it to the main solution.</p>
<p>Now, how to create a virtual file with assembly and fill it from the BinData.Data1.data:</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
static void CreateAssemblyInMemory(
   string strVirtualPath, 
   byte[] data)
{
   IntPtr hHandle =
      BoxedAppSDK.NativeMethods.BoxedAppSDK_CreateVirtualFile(
         strVirtualPath,
         BoxedAppSDK.NativeMethods.EFileAccess.GenericWrite,
         BoxedAppSDK.NativeMethods.EFileShare.Read,
         IntPtr.Zero,
         BoxedAppSDK.NativeMethods.ECreationDisposition.New,
         BoxedAppSDK.NativeMethods.EFileAttributes.Normal,
         IntPtr.Zero);
   CloseHandle(hHandle);

   using (FileStream VirtualFileStream = 
            new FileStream(strVirtualPath, FileMode.Open))
   {
      VirtualFileStream.Write(data, 0, (int)data.Length);
   }
}
</pre>
<p>Now how to create an assembly into memory:</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
CreateAssemblyInMemory(@"Z:\myclass.dll", BinData.Data1.data);

Assembly assembly = Assembly.LoadFrom(@"Z:\myclass.dll");
object o = assembly.CreateInstance("myclass.Class1");
o.GetType().GetMethod("SomeMethod").Invoke(o, null);
</pre>
<p>Another option, when your application uses some assembly and you would like to keep this assembly in memory. In this case, you write:</p>
<pre name="code" class="c-sharp" cols="35" rows="10">
static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();

        // Creates a virtual file with assembly
        // before using the assembly, in 
        // other words, the assembly is not 
        // loaded yet
        CreateAssemblyInMemory(
           Application.StartupPath + @"\\Assembly1.dll", 
           BinData.Data1.data);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // The Form1 will be created, 
        // Form1 loads the assembly Assembly1.dll, 
        // BoxedApp SDK provides it from memory
        Application.Run(new Form1());

        BoxedAppSDK.NativeMethods.BoxedAppSDK_Exit();
   }
...
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://boxedapp.com/blog/2008/06/11/net-applications-how-to-hide-assembly-and-unmanaged-dlls/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
