From b6ffa766b21fe2c985437aa80824a3cd4c384de8 Mon Sep 17 00:00:00 2001
From: Benjamin Dobell <benjamin.dobell@glassechidna.com.au>
Date: Wed, 6 Jul 2011 02:58:28 +1000
Subject: Major 1.3 updates

---
 libpit/Source/libpit.cpp      | 256 +++++++++++++++++++++++++++++++
 libpit/Source/libpit.h        | 346 ++++++++++++++++++++++++++++++++++++++++++
 libpit/libpit.vcxproj         | 119 +++++++++++++++
 libpit/libpit.vcxproj.filters |  19 +++
 4 files changed, 740 insertions(+)
 create mode 100755 libpit/Source/libpit.cpp
 create mode 100755 libpit/Source/libpit.h
 create mode 100755 libpit/libpit.vcxproj
 create mode 100755 libpit/libpit.vcxproj.filters

(limited to 'libpit')

diff --git a/libpit/Source/libpit.cpp b/libpit/Source/libpit.cpp
new file mode 100755
index 0000000..030a80b
--- /dev/null
+++ b/libpit/Source/libpit.cpp
@@ -0,0 +1,256 @@
+/* Copyright (c) 2010 Benjamin Dobell, Glass Echidna
+ 
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ 
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ 
+ 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
+ AUTHORS OR COPYRIGHT HOLDERS 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.*/
+
+// libpit
+#include "libpit.h"
+
+using namespace libpit;
+
+PitEntry::PitEntry()
+{
+	unused = false;
+	partitionType = 0;
+	partitionIdentifier = 0;
+	partitionFlags = 0;
+	unknown1 = 0;
+	partitionBlockSize = 0;
+	partitionBlockCount = 0;
+	unknown2 = 0;
+	unknown3 = 0;
+
+	memset(partitionName, 0, 32);
+	memset(filename, 0, 64);
+}
+
+PitEntry::~PitEntry()
+{
+}
+
+
+
+PitData::PitData()
+{
+	entryCount = 0;
+
+	unknown1 = 0;
+	unknown2 = 0;
+
+	unknown3 = 0;
+	unknown4 = 0;
+
+	unknown5 = 0;
+	unknown6 = 0;
+
+	unknown7 = 0;
+	unknown8 = 0;
+}
+
+PitData::~PitData()
+{
+	for (unsigned int i = 0; i < entries.size(); i++)
+		delete entries[i];
+}
+
+bool PitData::Unpack(const unsigned char *data)
+{
+	if (PitData::UnpackInteger(data, 0) != PitData::kFileIdentifier)
+		return (false);
+
+	// Remove existing entries
+	for (unsigned int i = 0; i < entries.size(); i++)
+		delete entries[i];
+
+	entryCount = PitData::UnpackInteger(data, 4);
+
+	entries.resize(entryCount);
+
+	unknown1 = PitData::UnpackInteger(data, 8);
+	unknown2 = PitData::UnpackInteger(data, 12);
+
+	unknown3 = PitData::UnpackShort(data, 16);
+	unknown4 = PitData::UnpackShort(data, 18);
+
+	unknown5 = PitData::UnpackShort(data, 20);
+	unknown6 = PitData::UnpackShort(data, 22);
+
+	unknown7 = PitData::UnpackShort(data, 24);
+	unknown8 = PitData::UnpackShort(data, 26);
+
+	unsigned int integerValue;
+	unsigned int entryOffset;
+
+	for (unsigned int i = 0; i < entryCount; i++)
+	{
+		entryOffset = PitData::kHeaderDataSize + i * PitEntry::kDataSize;
+
+		entries[i] = new PitEntry();
+
+		integerValue = PitData::UnpackInteger(data, entryOffset);
+		entries[i]->SetUnused((integerValue != 0) ? true : false);
+
+		integerValue = PitData::UnpackInteger(data, entryOffset + 4);
+		entries[i]->SetPartitionType(integerValue);
+
+		integerValue = PitData::UnpackInteger(data, entryOffset + 8);
+		entries[i]->SetPartitionIdentifier(integerValue);
+
+		integerValue = PitData::UnpackInteger(data, entryOffset + 12);
+		entries[i]->SetPartitionFlags(integerValue);
+
+		integerValue = PitData::UnpackInteger(data, entryOffset + 16);
+		entries[i]->SetUnknown1(integerValue);
+
+		integerValue = PitData::UnpackInteger(data, entryOffset + 20);
+		entries[i]->SetPartitionBlockSize(integerValue);
+
+		integerValue = PitData::UnpackInteger(data, entryOffset + 24);
+		entries[i]->SetPartitionBlockCount(integerValue);
+
+		integerValue = PitData::UnpackInteger(data, entryOffset + 28);
+		entries[i]->SetUnknown2(integerValue);
+
+		integerValue = PitData::UnpackInteger(data, entryOffset + 32);
+		entries[i]->SetUnknown3(integerValue);
+
+		entries[i]->SetPartitionName((const char *)data + entryOffset + 36);
+		entries[i]->SetFilename((const char *)data + entryOffset + 36 + PitEntry::kPartitionNameMaxLength);
+	}
+
+	return (true);
+}
+
+void PitData::Pack(unsigned char *data) const
+{
+	PitData::PackInteger(data, 0, PitData::kFileIdentifier);
+
+	PitData::PackInteger(data, 4, entryCount);
+
+	PitData::PackInteger(data, 8, unknown1);
+	PitData::PackInteger(data, 12, unknown2);
+
+	PitData::PackShort(data, 16, unknown3);
+	PitData::PackShort(data, 18, unknown4);
+
+	PitData::PackShort(data, 20, unknown5);
+	PitData::PackShort(data, 22, unknown6);
+
+	PitData::PackShort(data, 24, unknown7);
+	PitData::PackShort(data, 26, unknown8);
+
+	int entryOffset;
+
+	for (unsigned int i = 0; i < entryCount; i++)
+	{
+		entryOffset = PitData::kHeaderDataSize + i * PitEntry::kDataSize;
+
+		PitData::PackInteger(data, entryOffset, (entries[i]->GetUnused()) ? 1 : 0);
+
+		PitData::PackInteger(data, entryOffset + 4, entries[i]->GetPartitionType());
+		PitData::PackInteger(data, entryOffset + 8, entries[i]->GetPartitionIdentifier());
+		PitData::PackInteger(data, entryOffset + 12, entries[i]->GetPartitionFlags());
+
+		PitData::PackInteger(data, entryOffset + 16, entries[i]->GetUnknown1());
+
+		PitData::PackInteger(data, entryOffset + 20, entries[i]->GetPartitionBlockSize());
+		PitData::PackInteger(data, entryOffset + 24, entries[i]->GetPartitionBlockCount());
+
+		PitData::PackInteger(data, entryOffset + 28, entries[i]->GetUnknown2());
+		PitData::PackInteger(data, entryOffset + 32, entries[i]->GetUnknown3());
+
+		memcpy(data + entryOffset + 36, entries[i]->GetPartitionName(), PitEntry::kPartitionNameMaxLength);
+		memcpy(data + entryOffset + 36 + PitEntry::kPartitionNameMaxLength, entries[i]->GetPartitionName(), PitEntry::kFilenameMaxLength);
+	}
+}
+
+void PitData::Clear(void)
+{
+	entryCount = 0;
+
+	unknown1 = 0;
+	unknown2 = 0;
+
+	unknown3 = 0;
+	unknown4 = 0;
+
+	unknown5 = 0;
+	unknown6 = 0;
+
+	unknown7 = 0;
+	unknown8 = 0;
+
+	for (unsigned int i = 0; i < entries.size(); i++)
+		delete entries[i];
+
+	entries.clear();
+}
+
+PitEntry *PitData::GetEntry(unsigned int index)
+{
+	return (entries[index]);
+}
+
+const PitEntry *PitData::GetEntry(unsigned int index) const
+{
+	return (entries[index]);
+}
+
+PitEntry *PitData::FindEntry(const char *partitionName)
+{
+	for (unsigned int i = 0; i < entries.size(); i++)
+	{
+		if (!entries[i]->GetUnused() && strcmp(entries[i]->GetPartitionName(), partitionName) == 0)
+			return (entries[i]);
+	}
+
+	return (nullptr);
+}
+
+const PitEntry *PitData::FindEntry(const char *partitionName) const
+{
+	for (unsigned int i = 0; i < entries.size(); i++)
+	{
+		if (!entries[i]->GetUnused() && strcmp(entries[i]->GetPartitionName(), partitionName) == 0)
+			return (entries[i]);
+	}
+
+	return (nullptr);
+}
+
+PitEntry *PitData::FindEntry(unsigned int partitionIdentifier)
+{
+	for (unsigned int i = 0; i < entries.size(); i++)
+	{
+		if (!entries[i]->GetUnused() && entries[i]->GetPartitionIdentifier() == partitionIdentifier)
+			return (entries[i]);
+	}
+
+	return (nullptr);
+}
+
+const PitEntry *PitData::FindEntry(unsigned int partitionIdentifier) const
+{
+	for (unsigned int i = 0; i < entries.size(); i++)
+	{
+		if (!entries[i]->GetUnused() && entries[i]->GetPartitionIdentifier() == partitionIdentifier)
+			return (entries[i]);
+	}
+
+	return (nullptr);
+}
diff --git a/libpit/Source/libpit.h b/libpit/Source/libpit.h
new file mode 100755
index 0000000..636f1e1
--- /dev/null
+++ b/libpit/Source/libpit.h
@@ -0,0 +1,346 @@
+/* Copyright (c) 2010 Benjamin Dobell, Glass Echidna
+ 
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ 
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ 
+ 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
+ AUTHORS OR COPYRIGHT HOLDERS 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.*/
+
+#ifndef LIBPIT_H
+#define LIBPIT_H
+
+// C Standard Library
+#include <string.h>
+#include <vector>
+
+namespace libpit
+{
+	class PitEntry
+	{
+		public:
+
+			enum
+			{
+				kDataSize = 132,
+				kPartitionNameMaxLength = 32,
+				kFilenameMaxLength = 64
+			};
+
+			enum
+			{
+				kPartitionTypeRfs       = 0,
+				kPartitionTypeBlank     = 1, // ?
+				kPartitionTypeExt4      = 2
+			};
+
+			enum
+			{
+				kPartitionFlagWrite     = 1 << 1
+			};
+
+		private:
+
+			bool unused;
+
+			unsigned int partitionType;
+			unsigned int partitionIdentifier;
+			unsigned int partitionFlags;
+
+			unsigned int unknown1;
+
+			unsigned int partitionBlockSize;
+			unsigned int partitionBlockCount;
+
+			unsigned int unknown2;
+			unsigned int unknown3;
+
+			char partitionName[kPartitionNameMaxLength];
+			char filename[kFilenameMaxLength];
+
+		public:
+
+			PitEntry();
+			~PitEntry();
+
+			bool GetUnused(void) const
+			{
+				return unused;
+			}
+
+			void SetUnused(bool unused)
+			{
+				this->unused = unused;
+			}
+
+			unsigned int GetPartitionType(void) const
+			{
+				return partitionType;
+			}
+
+			void SetPartitionType(unsigned int partitionType)
+			{
+				this->partitionType = partitionType;
+			}
+
+			unsigned int GetPartitionIdentifier(void) const
+			{
+				return partitionIdentifier;
+			}
+
+			void SetPartitionIdentifier(unsigned int partitionIdentifier)
+			{
+				this->partitionIdentifier = partitionIdentifier;
+			}
+
+			unsigned int GetPartitionFlags(void) const
+			{
+				return partitionFlags;
+			}
+
+			void SetPartitionFlags(unsigned int partitionFlags)
+			{
+				this->partitionFlags = partitionFlags;
+			}
+
+			unsigned int GetUnknown1(void) const
+			{
+				return unknown1;
+			}
+
+			void SetUnknown1(unsigned int unknown1)
+			{
+				this->unknown1 = unknown1;
+			}
+
+			unsigned int GetPartitionBlockSize(void) const
+			{
+				return partitionBlockSize;
+			}
+
+			void SetPartitionBlockSize(unsigned int partitionBlockSize)
+			{
+				this->partitionBlockSize = partitionBlockSize;
+			}
+
+			unsigned int GetPartitionBlockCount(void) const
+			{
+				return partitionBlockCount;
+			}
+
+			void SetPartitionBlockCount(unsigned int partitionBlockCount)
+			{
+				this->partitionBlockCount = partitionBlockCount;
+			}
+
+			unsigned int GetUnknown2(void) const
+			{
+				return unknown2;
+			}
+
+			void SetUnknown2(unsigned int unknown2)
+			{
+				this->unknown2 = unknown2;
+			}
+
+			unsigned int GetUnknown3(void) const
+			{
+				return unknown3;
+			}
+
+			void SetUnknown3(unsigned int unknown3)
+			{
+				this->unknown3 = unknown3;
+			}
+
+			const char *GetPartitionName(void) const
+			{
+				return partitionName;
+			}
+
+			void SetPartitionName(const char *partitionName)
+			{
+				// This isn't strictly necessary but ensures no junk is left in our PIT file.
+				memset(this->partitionName, 0, 64);
+
+				if (strlen(partitionName) < 64)
+					strcpy(this->partitionName, partitionName);
+				else
+					memcpy(this->partitionName, partitionName, 63);
+			}
+
+			const char *GetFilename(void) const
+			{
+				return filename;
+			}
+
+			void SetFilename(const char *filename)
+			{
+				// This isn't strictly necessary but ensures no junk is left in our PIT file.
+				memset(this->filename, 0, 32);
+
+				if (strlen(partitionName) < 32)
+					strcpy(this->filename, filename);
+				else
+					memcpy(this->filename, filename, 31);
+			}
+	};
+
+	class PitData
+	{
+		public:
+
+			enum
+			{
+				kFileIdentifier = 0x12349876,
+				kHeaderDataSize = 28
+			};
+
+		private:
+
+			unsigned int entryCount; // 0x04
+			unsigned int unknown1;   // 0x08
+			unsigned int unknown2;   // 0x0C
+
+			unsigned short unknown3; // 0x10 (7508 = I9000, 7703 = I9100 & P1000)?
+			unsigned short unknown4; // 0x12 (Always 65, probably flags of some sort)
+
+			unsigned short unknown5; // 0x14
+			unsigned short unknown6; // 0x16
+
+			unsigned short unknown7; // 0x18
+			unsigned short unknown8; // 0x1A
+
+			// Entries start at 0x1C
+			std::vector<PitEntry *> entries;
+
+			static int UnpackInteger(const unsigned char *data, unsigned int offset)
+			{
+#ifdef WORDS_BIGENDIAN
+				int value = (data[offset] << 24) | (data[offset + 1] << 16) |
+					(data[offset + 2] << 8) | data[offset + 3];
+#else
+				// Flip endianness
+				int value = data[offset] | (data[offset + 1] << 8) |
+					(data[offset + 2] << 16) | (data[offset + 3] << 24);
+#endif
+				return (value);
+			}
+
+			static int UnpackShort(const unsigned char *data, unsigned int offset)
+			{
+#ifdef WORDS_BIGENDIAN
+				short value = (data[offset] << 8) | data[offset + 1];
+#else
+				// Flip endianness
+				short value = data[offset] | (data[offset + 1] << 8);
+#endif
+				return (value);
+			}
+
+			static void PackInteger(unsigned char *data, unsigned int offset, unsigned int value)
+			{
+#ifdef WORDS_BIGENDIAN
+				data[offset] = (value & 0xFF000000) >> 24;
+				data[offset + 1] = (value & 0x00FF0000) >> 16;
+				data[offset + 2] = (value & 0x0000FF00) >> 8;
+				data[offset + 3] = value & 0x000000FF;
+#else
+				// Flip endianness
+				data[offset] = value & 0x000000FF;
+				data[offset + 1] = (value & 0x0000FF00) >> 8;
+				data[offset + 2] = (value & 0x00FF0000) >> 16;
+				data[offset + 3] = (value & 0xFF000000) >> 24;
+#endif
+			}
+
+			static void PackShort(unsigned char *data, unsigned int offset, unsigned short value)
+			{
+#ifdef WORDS_BIGENDIAN
+				data[offset] = (value & 0xFF00) >> 8;
+				data[offset + 1] = value & 0x00FF;
+#else
+				// Flip endianness
+				data[offset] = value & 0x00FF;
+				data[offset + 1] = (value & 0xFF00) >> 8;
+#endif
+			}
+
+		public:
+
+			PitData();
+			~PitData();
+
+			bool Unpack(const unsigned char *data);
+			void Pack(unsigned char *data) const;
+
+			void Clear(void);
+
+			PitEntry *GetEntry(unsigned int index);
+			const PitEntry *GetEntry(unsigned int index) const;
+
+			PitEntry *FindEntry(const char *partitionName);
+			const PitEntry *FindEntry(const char *partitionName) const;
+
+			PitEntry *FindEntry(unsigned int partitionIdentifier);
+			const PitEntry *FindEntry(unsigned int partitionIdentifier) const;
+
+			unsigned int GetEntryCount(void) const
+			{
+				return entryCount;
+			}
+
+			unsigned int GetUnknown1(void) const
+			{
+				return unknown1;
+			}
+
+			unsigned int GetUnknown2(void) const
+			{
+				return unknown2;
+			}
+
+			unsigned short GetUnknown3(void) const
+			{
+				return unknown3;
+			}
+
+			unsigned short GetUnknown4(void) const
+			{
+				return unknown4;
+			}
+
+			unsigned short GetUnknown5(void) const
+			{
+				return unknown5;
+			}
+
+			unsigned short GetUnknown6(void) const
+			{
+				return unknown6;
+			}
+
+			unsigned short GetUnknown7(void) const
+			{
+				return unknown7;
+			}
+
+			unsigned short GetUnknown8(void) const
+			{
+				return unknown8;
+			}
+	};
+}
+
+#endif
diff --git a/libpit/libpit.vcxproj b/libpit/libpit.vcxproj
new file mode 100755
index 0000000..af828bc
--- /dev/null
+++ b/libpit/libpit.vcxproj
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release - Static MSVC|Win32">
+      <Configuration>Release - Static MSVC</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Source\libpit.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Source\libpit.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{9506FFE4-3A78-4BEE-A15E-62C5A138E61D}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>libpit</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Static MSVC|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Static MSVC|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\lib\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\lib\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Static MSVC|Win32'">
+    <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\lib\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Static MSVC|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/libpit/libpit.vcxproj.filters b/libpit/libpit.vcxproj.filters
new file mode 100755
index 0000000..c9ea499
--- /dev/null
+++ b/libpit/libpit.vcxproj.filters
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Source\libpit.h">
+      <Filter>Source</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Source\libpit.cpp">
+      <Filter>Source</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
-- 
cgit v1.1