Thursday, September 1, 2011

Let's hear it for Recuva!

A friend of mine lost all his family recordings off his Sony HDD camera. Major crisis!

A quick probe resulted in estimates of up to 10K USD to recover the lost video commercially. A quick google search resulted in Recuva being a likely candidate for a fix. Luckily the owner kept his wits, did not take any additional video. 10 minutes later every video sequence was back on disk, and camera back with its (now) very happy owner :D

So, lets hear it for Recuva!

Tuesday, August 16, 2011

Empty SxS <assembly> tag from VS2008

Symptoms
VS2008 sometimes manages to embed empty manifest into the binaries it builds. Normally this will give you some (at first) strange SxS error when you attempt to run your newly built binary.

Investigation
Using mt.exe we can check out the embedded manifest in the binary
mt.exe -inputresource:myapp.exe -out:foo


Output
In the failing case resulting in this short blurp in foo:

<!--?xml version="1.0" encoding="UTF-8" standalone="yes"?-->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestversion="1.0"></assembly>

Expected output
You would, however, expect the embedded manifest to look something like the following

<!--?xml version="1.0" encoding="UTF-8" standalone="yes"?-->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestversion="1.0">
<trustinfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedprivileges>
<requestedexecutionlevel level="asInvoker" uiaccess="false"></requestedexecutionlevel>
</requestedprivileges>
</security>
</trustinfo>
<dependency>
<dependentassembly>
<assemblyidentity type="win32" name="Microsoft.VC90.CRT" version="9.0.nnnnn.mmmmm" processorarchitecture="x86" publickeytoken="1fc8b3b9a1e18e3b"></assemblyidentity>
</dependentassembly>
</dependency>
</assembly>

Examination
This seems to happen only when building files on a networked drive (long story short - I need to). Typically this means your build folders will be on the same networked drive too. As a result, so will the myapp.embed.manifest file that we try to embed.

There's various reasons if you read around on the net, but it all relates to
  1. Incremental linking
  2. and a FAT32 optimization in VS2008 gone haywire
  3. with BIND_TO_CURRENT_CRT
  4. when project files are on a networked drive
I haven't investigated if not using BIND_TO_CURRENT_CRT makes a difference or not, but it might.

Options
There's a few options to avoid this, not all of which may be applicable nor desirable

1. Don't do incremental linking
Will only work for smaller projects.

2. Place cmake files on local disk
Might not be desirable, for various reasons. Dependencies to other projects would be one.

3. Manually embed the correct manifest
Having cmake do a POST_BUILD step, where it runs the cmake equivalent of
mt.exe -verbose  -manifest myapp.embed.manifest  -outputresource:myapp.exe


is really the only safe option IMHO.

So help VS2008 along the way and manually embed your manifest, and you hopefully won't be bothered by that SxS error again...

Friday, February 18, 2011

_access() doesn't work!?

HELP!

The _access() CRT call does not work on Windows - at least not in the way you'd expect coming from unix or linux. The underscored function found in the Windows C runtime library appears to be a Windows equivalent of the Posix function access() reading the MSDN docs.

But appearances can be deceiving.

The unix and linux variants will throw EACCES when accessing a directory/folder where you have no read access. The windows _access() does not. Help! In fact, _access() only proves usable for checking existence of a given path, and nothing else.

How, then, do you get a proper access() function on Windows? Turns out CreateFile() will do what we need:
DWORD dwAccess = GENERIC_READ; // or GENERIC_WRITE, or both |'d
hFile = CreateFile(fname,
dwAccess,
FILE_SHARE_READ|FILE_SHARE_WRITE, // attempt to open with shared read/write access
NULL, // no security needed for probe
OPEN_EXISTING, // check existing files and folders only
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, //both needed for directory probe
NULL); // template file not needed for probe

if (hFile == INVALID_HANDLE_VALUE){
// do whatever you need to handle EACCES
}
CloseHandle(hFile);
...
Hope this can save you a few cycles...

Saturday, January 29, 2011

That dreaded cygwin "Device or Resource busy"...

If you've ever attempted to do any serious work on a Windows box configured with cygwin and a sshd, you've probably already come across the dreaded error message as you attempt to remove a file or folder

"Device or Resource busy"

If, not you probably will - sooner or later. You can't rm the files or folders, your compile is stuck as it can't write objs to disk - or whatever else your file access scenario may be.

SysInternals Handle to the rescue!

Handle will merrily show you what process is holding a handle to the specified file or folder. Once the perpetrator is located, taskkill /PID n, makes for the easy solution.

Simple, yet extremely effective trick for the toolbox...

(In all fairness, the latest 1.7.7 cygwin is a lot better than the previous versions :))