Fixing Master Boot Record (MBR) in Windows XP without the recovery console

April 18th, 2008

My laptop was set up to dual boot Windows and openSuse linux, but as I wasn’t really using openSuse at the moment and I needed the disk space I decided to delete the openSuse installation to free up the disk space. Should be easy, just format the linux partition using a file system that windows can handle, right?

So I used gParted to delete the linux partition and its swap partition and created a NTFS partition instead. But when I rebooted I was disappointed to see the GRUB (boot loader) prompt. Apparently the linux partition had held the configuration for the boot loader, which obviously I hadn’t thought of.

Booting into windows was not a problem, the following GRUB commands did the trick: (my windows partition is the second partition on the first and only hard drive)

rootnoverify (hd0,1)
chainloader +1
boot

Naturally, I didn’t want to type these commands every time I rebooted my computer though. The first thing I tried was fixing GRUB, but after a while of trial and error I decided that it was better to just use the default windows loader since windows was now the only OS installed. Again, a quick internet search told me that I should use a tool called “fixmbr” which is only available from the Windows Recovery Console. Unfortunately the Recovery Console is only available if you have the windows installation cd or have a directory named “I386″ on your hard drive. I didn’t have my windows cd available (it’s buried somewhere in a storage room) and no I386 directory on my disk, so I “borrowed” that directory from my girlfriends computer. No go – “wrong version” or something. Tried applying Windows XP Service Pack 2 to the borrowed I386 directory and got one step further, but also a couple of new error messages (“error reading netmap.inf”) and still couldn’t install the recovery console.

Time for a new approach and I remembered reading about the fdisk utility and that it should be able to fix the MBR, however it turned out that it was only included in earlier versions of Windows, so I couldn’t use that either. At this point I was getting pretty frustrated, how hard could this possibly be??

One last internet search to try to find an fdisk alternative for Windows XP returned a site mentioning a tool called MBRFix, and I decided to give it a try. It turned out that it could also do a backup of the MBR, so I did that before doing the “fixmbr”-thing, just in case. After running “MbrFix /drive 0 fixmbr” I rebooted in anticipation, and was very pleased to see the windows load screen again.

Bookmark and Share

Handling templates with output buffering

December 17th, 2007

I just read a blog entry by Arnold Daniels about handling templates in PHP using output buffering with a callback function.

I’ve previously used a somewhat similar approach to templating using output buffering and register_shutdown_function, but using a callback function when starting output buffering is an interesting concept I hadn’t thought of so I had to look into it.

I found his solution a little lacking, so I created my own version of it. After I had created my own version though, I read a follow-up article on the same blog with an improved version of his solution. It turned out that my version was almost identical to the version in the follow-up article (even to the point that we both implemented static methods/members which the first article didn’t do). I guess great minds really do think alike. ;)

The differences between mine and his are basically too few and unimportant to justify me blogging about it, but it’s a little late for that now.. I found his second article after doing some more research after I had started writing this post, and I might as well finish it now. I’ll be short though.

My version

  • implements the singleton pattern
  • have header and footer as separate options
  • does not implement the mark/endmark methods introduced in Daniels second version (which I’ve found no need for)

Anyway, here it is, with a very simple usage example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class OutputHandler
{
	private static $instance;
	private static $header;
	private static $footer;
	private static $templateVars = array();
	private function __construct () {}
	final private function __clone() {}
	public static function getInstance()
	{
		if (self::$instance instanceof self === false) {
			self::$instance = new self;
			$args = func_get_args();
			self::$header = (isset($args[0]) ? $args[0] : '');
			self::$footer = (isset($args[1]) ? $args[1] : '');
			ob_start(array(__CLASS__, 'callback'));
		}
		return self::$instance;
	}
	public static function callback ($buffer, $flags)
	{
		if ($flags & PHP_OUTPUT_HANDLER_END) {
			$buffer = self::parseTemplate(self::$header) . self::parseTemplate($buffer) . self::parseTemplate(self::$footer);
		}
		return $buffer;
	}
	private static function parseTemplate ($template)
	{
		return str_replace(array_keys(self::$templateVars), array_values(self::$templateVars), $template);
	}
	public static function setTemplateVar ($key, $var)
	{
		self::$templateVars[$key] = $var;
	}
}
 
OutputHandler::getInstance(file_get_contents('header.phtml'), file_get_contents('footer.phtml'));
OutputHandler::setTemplateVar('<!-- Title -->', 'Page title');
OutputHandler::setTemplateVar('<!-- The list -->', <<<ENDOUTPUT
<ul>
	<li>Item 1</li>
	<li>Item 2</li>
</ul>
ENDOUTPUT
);
 
echo '<p>Content, content, content!</p>';
echo '<p>Before the list</p>
	<!-- The list -->
	<p>After the list</p>';

When the script ends the above echo’ed lines will be output within the header and footer templates. The above echo’ed string “<!– The list –>” will be replaced with the unordered list defined with OutputHandler::setTemplateVar() and if the string “<!– Title –>” is found anywhere, including the header or footer templates, it will be replaced with “Page title”.

Bookmark and Share

Set include path for Zend Framework

December 13th, 2007

When using Zend Framework, its library must be present in the PHP directive ‘include_path‘, so a common thing to do when using ZF is to set the include_path inside the app and include a directory where the ZF library is supposed to be installed.

Here’s my problem: Instead of hard-coding a path to a directory that may or may not contain the framework, I wanted a simple way to configure include_path without having to override the global setting through php.ini, .htaccess, etc. Naturally I can’t use Zend_Config which I’d otherwise use for configurations.

The directory structure I’m using is based on the structure suggested in the tutorial Getting Started with the Zend Framework by Rob Allen. This means that I have 3 directories in the application root directory, ‘app’ for application files, ‘lib’ for libraries (such as Zend Framework) and ‘pub’ for public files (css, js, images, etc). I could just ship my application with a copy of Zend Framework inside the lib-directory and leave it at that, but I don’t want that since people may already have a copy of the framework on their servers and may not want another copy for storage reasons or just simplicity.

The solution I came up with was to create simple text-files in my applications lib-directory containing paths to include in include_path. My app would then scan this directory and extract the contents of all files matching a given extension before setting include_path using these extracted values. The extension I went with for these simple config-files was ‘.libp’, short for ‘lib-path’.

In my application object constructor, I now have

define('DS', DIRECTORY_SEPARATOR);
define('PS', PATH_SEPARATOR);
define('AR', realpath(dirname(__FILE__) . '/..')); # application root

try
{
	self::_set_include_path();
	if(!@include_once('Zend/Loader.php'))
	{
		throw new Exception('Failed to load Zend Framework. This is a required library and must be installed.');
	}
}
catch(Exception $e)
{
	echo $e->getMessage();
	exit;
}

I think the code is fairly obvious, so I won’t waste time commenting it further.

Later in the same class, I have these methods

private static function _set_include_path ()
{
	$customLibPaths = '';
	$libPath = self::getPath('lib');
	# filter out non-regular files, files starting with a punctuation mark and files not ending with .libp
	foreach (array_filter(scandir($libPath), create_function('$file', 'return (strpos($file, \'.\') === 0 || !is_file(\'' . addslashes($libPath . DS) . '\' . $file) || pathinfo($file, PATHINFO_EXTENSION) !== \'libp\' ? false : true);')) as $file)
	{
		$tmpPath = trim(file_get_contents($libPath . DS . $file));
		if (empty($tmpPath))
		{
			continue;
		}
		if (!is_dir($tmpPath))
		{
			throw new Exception(sprintf('"%s" is not an existing directory, please change %s to contain a real include path. If you don\'t want to set a new include path in this file, you may either delete it or empty it.', $tmpPath, $libPath . DS . $file));
			continue;
		}
		$customLibPaths .= PS . $tmpPath;
	}
	set_include_path(
		AR
		. PS . AR . DS . 'lib'
		. $customLibPaths
		. PS . get_include_path()
		);
}
 
/**
 * Get absolute path to a directory or file by passing any number of path entities (directories/files) relative from the application root
 */
public static function getPath ()
{
	$args = func_get_args(); # Can't be used as a function parameter directly, must be assigned to a variable
	return AR . DS . implode(DS, $args);
}

The lib-directory contains files such as zend-framework.libp, holding a simple string each with the path to the respective libraries. When trying to include files, PHP will now first check the application root, then the lib directory, any custom lib-paths and finally the default include_path.

If I ever want to implement some sort of plugin system for my app, any plugins relying on external libraries may add a file in the lib-directory to configure the include path instead of modifying main application files. I can also use this myself of course if I at a later point want to make use of further third party libraries and allow end-users to easily configure the paths to those libraries.

Bookmark and Share

Trac 0.11 beta coming soon

December 8th, 2007

In case you didn’t know, Trac is an open source software project management tool.

According to the Trac roadmap, they’re about to release a beta version of the long-awaited 0.11 release. On that occasion, they ask that people help them make a fool-proof release by downloading and testing the latest revision (trunk) from the subversion repository.

The 0.11 release has been in development for over a year now and it closes more than 400 tickets in their issue tracker. Most issues were defects but there are also several enhancements. Some of the highlights are the integrated web-admin plugin, configurable workflow and easier installation procedure. See the release notes for 0.11 in the Trac wiki for much more info on what’s new. I installed the latest trunk yesterday, and so far it looks really good. Even for a one-man private project, this is a tool that makes a difference.

Bookmark and Share

Blog update

December 8th, 2007

I just added OpenID support to this blog and finally allowed people to register and post comments too. Apparently there was a switch in the Wordpress admin, “Anyone can register”, that was turned off.

Bookmark and Share

Moved site to new host

November 28th, 2007

The last couple of days I have been moving my site over to my new web host, but now all should be in place. Let me know if you see any irregular behaviour. :)

Bookmark and Share

Data Manager – PHP ETL?

November 25th, 2007

Project Data Manager was started in march 2005, and in the beginning it was intended to be an add-on for Zen Cart, a shopping cart system in PHP. At the beginning of the project I was just starting out in the world of programming and PHP, and the project has been my own programming training course, so to speak. Development has been periodically sporadic, due to interest and time.

I’ve dedicated enormous amounts of time and energy into this project, but will it ever become ready for a public release or will it forever remain only on my personal computer as a programming exercise?
Read the rest of this entry »

Bookmark and Share