Archive for October 2009

How to make a nice quote field with a different background color in your WordPress blog post?

How to make a nice quote field with a different background color in your WordPress blog post?

It is simple. Use a div section.

<div style="width:500px;background-color:#363636;color:#ffffff;border-style:ridge;border-width:5px;padding:10px;">
Any text you want here.

More lines...

More lines...

</div>

This will make a nice box like this:

Any text you want here.

More lines…

More lines…

Change the colors as you want.

Hope this helps you.

Also, this is not for code posts. If you want to post code, see this post:
How to post code in a wordpress blog so it maintains its formatting?

How to restart the AUTOINCREMENT number for a table in Microsoft SQL 2008?

Ok, so I am in the middle of developing a database tool and so I populate a bunch of data, (by adding a bunch of rows), to a column that is AUTOINCREMENT.

So I have 3725 rows for a feature that is working. Now I am developing other features and debuggin them and so I want to reset the database to the same point it was before I started debugging.

So I am deleting all the rows above 3725, however my next AUTOINCREMENT number continues to go up.

I have this handy little SQL statement that should fix that:

To set the table back to 0.

DBCC CHECKIDENT (MyTable, RESEED, 0)

Now, if I set the table back to 0 that can be a problem if you still have rows in it.

The next row you try to insert will give you an error.

Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint ‘PK_Person’. Cannot insert duplicate key in object ‘dbo.Person’.
The statement has been terminated.

So if you have rows, try this:

DECLARE @size int
SET @size=(SELECT COUNT(*) From MyTable)
DBCC CHECKIDENT (MyTable, RESEED, @size)

Happy day, it works!!

Windows 7 64 bit VPN Client – ShrewSoft

Ok, so I couldn’t get Cisco’s VPN client to work for Windows 7 64 bit. So I went in search of another VPN solution that would be more compatible.

(UPDATE: I got ShrewSoft’s VPN Client working, so keep reading down below.)

I came across ShrewSoft’s VPN Client a while ago, but it originally blue screened my Windows 7 box, but it was a version that didn’t support Windows 7. However they have a new version that is out that is for Windows 7 64 bit. Actually they now have a release version on their download site but there is a beta of the next version (Update 3/05/2010)2.1.6-beta-6 that your may want to use (or a later version if you are reading this well after I wrote or updated it). See the comments on why.

I installed it and it requested a reboot so I rebooted, and the first good news is that I didn’t blue screen when my workstation booted up. Horray!!!

After installing, I tested undocking my laptop from its docking station and then docking my laptop, and again, no blue screens, so I think it is good to go. Now I just have to figure out how to configure it to connect here at work.

I like the license, they say:

The Shrew Soft Client for Windows is free for both commercial and private use. Please read below for complete license details. Click here…

Stay tuned for more testing….

Ok…I am back for more notes.

At work we are using a Cisco VPN solution, so it turns out that when my Cisco VPN would install on a 32 bit machine, it used a .pcf file. Well, guess what is awesome about ShrewSoft’s VPN Client? It can import a .pcf file.

I imported the .pcf file and I appear to connect, then disconnect. Not sure what is going on. I am at work, but I should be able to connect to the VPN while at work, at least that is what my IT staff said.

So hopefully it connects when I am at home.

Here is my log:

config loaded for site ‘MyConfig.pcf’
configuring client settings …
attached to key daemon …
peer configured
iskamp proposal configured
esp proposal configured
client configured
local id configured
pre-shared key configured
bringing up tunnel …
network device configured
tunnel enabled
session terminated by gateway
tunnel disabled
detached from key daemon …

I will try to debug later…

All right I am back again and I am trying to debug. I found this post:

http://lists.shrew.net/pipermail/vpn-help/2009-October/002282.html

There is a program under Start | All Programs | Shrew Soft VPN Client called “Trace Utility” that is installed with the Shrew Soft VPN Client can be used for debugging. However, it wouldn’t work for me. The buttons weren’t enabled.

I had to right-click on the “Trace Utility” shortcut and choose “Run as administrator” then I was able to turn on debugging.

Positives for Shrew Soft VPN Client
- It has a debugging utility.
- It supports Windows 7 64 bit
- It imports cisco .pcf files.
- There is a lot of documentation.

Negatives for Shrew Soft VPN Client
- I don’t have it working yet
- There is not really any clear failure reason for a user.

So I will keep at it. I think I am about going to email the developer, but I sure don’t want to bug him.

Hopefully for some of you, it worked first time for you when you imported the .pcf file.

Got it working

Another positive. The developer has a mailing list, as you saw with one of my links above. I found this link:

http://lists.shrew.net/pipermail/vpn-help/2009-October/002275.html

The key piece of information I needed was this:

If it gets to the ‘tunnel enabled’ point, that means you completed phase1, Xauth and modecfg negotiations. Its probably a phase2 option. As I mentioned to others on the list, try playing with the PFS setting or enabling the cisco-udp NAT-T option.

In the tool, after importing my .pcf file, I only had to make one configuration change. I had to change the PFS setting to “group 2″. See this screen shot.

VPN Setting

So I have this working now.

I have to say that I am very impressed with Shrew Soft. It took me some time to figure it out, but it works. Now the only question time will tell is how stable it is. Expect an update in a week or two about whether I think the Shrew Soft VPN Client is stable.

The steps are easy for me to connect to my VPN at work. Now every VPN is different so I am sorry if these steps don’t work for you:

  1. Use the correct (and latest) version: 2.1.6-beta-6 or later
  2. Install Shrew Soft VPN Client
  3. Reboot.
  4. Import the .pcf file.
  5. Modify the configuration and change the PFS setting to “group 2″.
  6. Apply the configuration.
  7. Click connect.
  8. Enter your domain user and password and you will connect.

Success!!!!

Also, I exported my configuration as a Shrew Soft VPN Client export, which is a .VPN file. When I import it, I don’t have to make a configuration change like I did with the Cisco .pcf file.

Key words: cisco vpn window 7 64 bit

Evaluating Google Voice…

So I just got an invite for a Google voice number.

I think it is pretty cool so far.

It is supposed to have some cool features:
I can set up many phones it links to and supposedly if someone calls my google number, all the other phones will ring.
I can block people from calling me.
I can have it change what it does based on the time or day.

So I will let you know when I use a feature and how well it works.

Adding a SQL 2008 Server as a DataSource to JasperServer

Ok, so at work I installed JasperServer and spent quite a lot of time in their documentation and could find the basic information of how to connect to a Microsoft SQL 2008 server.

JasperSoft has a nice installer that installs everything for you: JasperServer, Tomcat, Java, MySQL, etc…

The first problem was I had a 2008 R2 64 bit VM that I thought I would use that OS and their installer just crashed with MySQL errors. So I installed MySQL myself, and then reinstalled JasperServer and pointed to my MySQL install and it appeared to work better but there were still a lot of errors in normal use that I couldn’t find documentation on. So I am now using a 2003 R2 SP2 server and everything installed just fine, first time.

I thought Microsoft was really friendly about deploying their JDBC driver for SQL 2005/2008 and that anyone could distribute it as long as they just told Microsoft first, (maybe I am wrong and maybe MS charges to distribute it). Anyway, I expected JasperServer to install the JDBC driver for me (included in their all-encompassing package) but to my dismay, the driver wasn’t there. So that is fine, I was certain there would be a quick and easy document on how add SQL 2008 as a database. Yeah, three days later, still no documentation found….

Finally, with almost no help from the JasperServer documentation, I figured out that really it was Tomcat that needed the JDBC driver, not JasperServer. Well, it turns out that Tomcat no longer uses the CLASSPATH environment variable, so I just had to copy the SQL 2008 JDBC .jar file to a directory Tomcat did look at and I was done. It was simple.

  1. Download the Microsoft JDBC driver: Microsoft SQL Server JDBC Driver
  2. Extract to a good location. I chose c:\program files to extract to.
  3. Copy the sqljdbc4.jar to your installation directory which by default is:
    c:\program files\jasperserver-pro-3.5.1\apache-tomcat\webapps\jasperserver-pro\WEB-INF\lib

  4. Restart JasperServer (there is a shortcut in the start menu to restart it).
  5. Log into JasperServer’s web site. http://YourServer:8080/jasperserver-pro
  6. Go to View | Repository.
  7. Click the second icon called Add Resource and select Data Source.
  8. Choose JDBC Data Source and click next.
  9. Provide any Name, Label, and Description.
  10. For the driver put this:
    com.microsoft.sqlserver.jdbc.SQLServerDriver

  11. For the URL put this:
    jdbc:sqlserver://ServerName:1433:databaseName=MyDatabase;

  12. Enter the username and password.
  13. Select a time zone.
  14. Click Test and it should succeed.
  15. Troubleshooting: If it doesn’t succeed, save anyway and restart the JasperServer and watch for any exceptions.

Wow that was easy once I figured it out. Too bad that the lack of good documentation resulted in me spending three days to figure out that I just needed to spend three seconds to copy a file.

JasperServer score card

Install = 8 (Minus two points for not working Server 2008 R2 64 bit)
Documentation = 0 (no points as so far I have not found a document that has been helpful yet.

Also I note that the JasperForge (the opensource part of JasperSoft) has a wiki, but it is nothing but headers and the data is pretty much blank.

I am not trying to knock JasperSoft with this post, but I am just trying to make sure that someone who tries to do the same thing ends up finding my post and getting their SQL 2008 server added as a data source rather quickly, instead of wading through the lack of documentation for three days.

Even to show my good will towards open source projects, I documented my steps on their wiki for them.
http://jasperforge.org/plugins/mwiki/index.php/Jasperserver/DataSources#Adding_a_Microsoft_SQL_Server_2008_Database_as_a_Data_Source

How to get the size of an array in C++?

Ok, so for newbies, this is not exactly straight forward. While, C++ is not like other languages which have simple functions to get sizes of arrays, it does have replacements for arrays that are simple to use. The STL has a vector, which is a linked list that acts like an array but has more user friendly options such as an easily accessible size value (and an easy way to add a value and re-size the vector if needed).

The first question is this: Why do you need to get the size of the array? An array is always created with a size. You can always store it.

Of course you are going to have a reason why you are doing this or you wouldn’t be searching this. However, some of you are going to realize you have the value already and use it, but others are still going to try to dynamically get the array size.

So YES, you can get an array size usually. There are certain ways to do it and certain things to avoid.

  • An array cannot be created without using a constant size. So you should know it and so yes it is up to you to store the size.
  • You cannot create a dynamic array, there is no such thing. You can create a pointer to a new array but you have to pass in a size, so if you are passing in a size, you can also store the size you pass in, right? Yes you can.
  • Use a vector instead of an array.

Ok, you really want to try to get the size of an array without storing the size of the array yourself and without using a vector. Ok, we will give you some options but they have pitfalls, so know them and don’t fall in them.

There is a function called sizeof() that you should get to know. Here is a bit of code that will help you get to know the sizeof() function and how to use it to get array sizes. Load this into your favorite IDE and step through it or just compile and run it. Take time to read both the output and the comments in the code.

#include <iostream>
#include <cstdlib>
#include <ctime>

#define MAX_SIZE 20

using namespace std;

template <typename T, size_t arraySize >
size_t sizeOfArray( T const (&a)[arraySize] )
{
    return arraySize;
}

int main()
{
	// Static array.  The value must be a constant value.
	int intArray1[10]; // You have statically written 10, so you know this array is size 10
	cout << "intArray1 size is 10" << endl;
	cout << "sizeof(intArray1) = " << sizeof(intArray1)
		 << " (Obviously not the way to get an array size.)" << endl;
	cout << "sizeof(intArray1)/sizeof(intArray1[0]) = "
		 << sizeof(intArray1)/sizeof(intArray1[0]) << " (Appears to work in this instance.)"
		 << endl << endl;

	// Static array. The value must be a constant value, since this used a defined value,
	// MAX_SIZE, you know the size.
	int intArray2[MAX_SIZE];
	cout << "intArray2 size is " << MAX_SIZE << endl;
	cout << "sizeof(intArray2) = " << sizeof(intArray2)
		 << " (Obviously not the way to get an array size.)" << endl;
	cout << "sizeof(intArray2)/sizeof(intArray2[0]) = "
		 << sizeof(intArray2)/sizeof(intArray2[0]) << " (Appears to work in this instance.)"
		 << endl << endl;

	// So what if I don't know the size, because it is dynamic?

	// Lets create a random number between 1 and 100.
	srand ( (int)time(NULL) );
	int arraySize = rand() % 100;
	// You cannot use this as a static array size
	// int intArray3[arraySize]; <-- Compiler error: error C2057: expected constant expression

	// You can create a pointer to a new dynamicly sized array. But it is a pointer type not
	// an array[size].  T *t and T t[size] are different types.
	int * intPtrToArray = new int[arraySize];
	cout << "intPtrToArray size is " << arraySize << endl;
	cout << "sizeof(intPtrToArray) = " << sizeof(intPtrToArray)
		 << " (Obviously not the way to get an array size, it got the pointer size.)" << endl;
	cout << "sizeof(inArray2)/sizeof(intPtrToArray[0]) = "
		 << sizeof(intPtrToArray)/sizeof(intPtrToArray[0])
		 << " (Hey this didn't work this time? Why?)" << endl << endl;
	cout << "sizeof(*inArray2)/sizeof(intPtrToArray[0]) = "
		 << sizeof(*intPtrToArray)/sizeof(intPtrToArray[0])
		 << " (Trying do derefence the pointer still failed? Why?)" << endl << endl;
	// So how do you get the size you might ask?  Well, you already know it.  The size is the
	// value stored in the "arraySize" variable.  You had to pass something in when you
	// declared the dynamic array, new int[something], so you store something.

	// So it looks like sizeof(myArray)/sizeof(myArray[0]) works as long as I don't use a
	// pointer.  Is there a way to make the compiler check this for me?  Yes, that is what
	// the handy function above is for.

	cout << "Using template function" << endl << endl;

	int size1 = sizeOfArray(intArray1);
	cout << "intArray1 size is 10" << endl;
	cout << "sizeOfArray(intArray1) = " << size1 << endl << endl;

	int size2 = sizeOfArray(intArray2);
	cout << "intArray2 size is " << MAX_SIZE << endl;
	cout << "sizeOfArray(intArray2) = " << size2 << endl << endl;

	// int size3 = sizeOfArray(intPtrToArray); <-- Compiler error:
	// error C2784: 'size_t sizeOfArray(const T (&)[arraySize])' : could not deduce template
	// argument for 'const T (&)[arraySize]' from 'int *'
}

Now you know how you can use the sizeof(myArray)/sizeof(myArray[0]) statement. However, you also know that such a statement won’t work when dealing with pointers to dynamic arrays. And let’s face it you arrays are probably going to be dynamic most of the time. That means you should probably use a vector instead of an array.

Ok, lets say you don’t want to use a vector still. You want to use the sizeof(myArray)/sizeof(myArray[0]) statement anyway. Well, then you should at least do it in a way that make the compiler complain if you accidentally use a pointer to an array instead of an array. Here is some code that will cause the compiler to complain if you pass a pointer to an array instead of passing an array.

#include <iostream>
#include <cstdlib>
#include <ctime>

#define MAX_SIZE 20

using namespace std;

template <typename T, size_t arraySize >
size_t sizeOfArray( T const (&a)[arraySize] )
{
    return arraySize;
}

int main()
{
	int intArray1[10];
	int size1 = sizeOfArray(intArray1);
	cout << "intArray1 size is 10" << endl;
	cout << "sizeOfArray(intArray1) = " << size1 << endl << endl;

	int intArray2[MAX_SIZE];
	int size2 = sizeOfArray(intArray2);
	cout << "intArray2 size is " << MAX_SIZE << endl;
	cout << "sizeOfArray(intArray2) = " << size2 << endl << endl;

	srand ( (int)time(NULL) );
	int arraySize = rand() % 100;
	int * intPtrToArray = new int[arraySize];
	// int size3 = sizeOfArray(intPtrToArray); <-- Compiler error:
	// error C2784: 'size_t sizeOfArray(const T (&)[arraySize])' : could not deduce template
	// argument for 'const T (&)[arraySize]' from 'int *'
}

So this template function will help you avoid one pitfall of accidentally passing in a pointer to an array instead of an array by making the compiler complain if you do it. However, I am sure this template has some pitfalls that you may encounter as well.

Another gotcha is that passing an array in a function ends up being the equivalent of a pointer and so you cannot get the size:

So if we added the following function to our code above we would get the same compiler error we see when passing a pointer. We don’t even have to call the function in main().

void passMeAnArray(int inIntArray[])
{
	int i = sizeOfArray(inIntArray);
}

What is the problem? Well, even though we show the parameter passed to the function as int inIntArray[], it is really not an array, it is a pointer to an array and would be the same as writing int * inIntArray.

Are there more gotchas? You bet there are. There is so much more to learn. All my arrays are of type int in this example. Here are some questions to make you think…

What happens with other types?
What happens when the array is an array of objects not types?
What happens when the objects contain multiple pointers?
What happens if the object using for an array inherits another object?
What happens if the object using for an array is created using multiple inheritance?

Wow, this is getting more complex than it has to be. Why didn’t you just use a vector? See the code below to see how easy this is with a vector.

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>

using namespace std;

int main()
{
	vector<int> *intArray1 = new vector<int>(10); // Creates a vector with 10 items.
	cout << "intArray1 size is " << intArray1->size() << endl << endl;

	// Create a random number between 1 and 100 and add that many random elements.
	srand ( time(new time_t()) );
	vector<int> *intArray2 = new vector<int>();
	for (int i = 0; i < (rand() % 1000); i++)
	{
		intArray2->push_back(rand() % 1000);
	}
	cout << "intArray2 size is " << intArray2->size() << endl << endl;

}

I hope that you have been convinced to use a vector and if not you are doing everything you can to avoid common pitfalls.

How to convert a string to an int in C++? (Or to a float, double, etc)

Ok, so I already have a post on How to convert an int to a string in C++? (Also doubles, floats, etc…) and so I need a post on doing this in reverse.

So lets say you wanted to convert a string to an int. The code for a function would be simple: (Note updated to one that didn’t give errors on either windows or Linux)

int stringToInt( string inString )
{
	int retVal;
	stringstream ss;
	ss << inString;
	ss >> retVal;
	return retVal;
}

Now, you are going to want a function that handles more than just int types. You want it to handle int, float, doubles, etc… So lets use a template for this as well. However, since the return type is never going to be known, we will not have a return type. Instead, we will pass in a reference to a variable and that will be a generic.

template <class T>
void stringToAnyType(T& t, std::string inString)
{
	std::stringstream ss(inString);
	ss >> t;
}

At first it will appear that this code is all that is needed, and sure the code will work for int, float doubles, but not for 100% for char types because when converting to a char it only gets the first word. Here is a quick example of using the template code. Copy it over and run it with a debugger and look at the variable values.

Note: I am on Windows 7 64 bit (app compiled as 32 bit) using a Visual Studio 2008 C++ empty project. I wonder if the output is different on other platforms.

//#include <iostream>
#include <string>
#include <sstream>

template <class T>
void stringToAnyType(T& t, std::string inString)
{
	std::stringstream ss(inString);
	ss >> t;
}

using namespace std;

int main()
{
	string intAsString = "12345";
	int i;
	stringToAnyType(i, intAsString);

	string floatAsString1 = "12345.678";
	float f1;
	stringToAnyType(f1, floatAsString1);
	// Looks like this works

	string floatAsString2 = "99.99";
	float f2;
	stringToAnyType(f2, floatAsString2);
	// Hmmm...a little loss of precision: 99.989998

	string doubleAsString1 = "123456789.12345678";
	double d1;
	stringToAnyType(d1, doubleAsString1);
	// Perfect conversion

	string doubleAsString2 = "99.99";
	double d2;
	stringToAnyType(d2, doubleAsString2);
	// Hmmm...a little loss of precision: 99.989999999999995

	string charArrayAsString1 = "Hello";
	char c1[100];
	stringToAnyType(c1, charArrayAsString1);

	string charArrayAsString2 = "Hello world";
	char c2[100];
	stringToAnyType(c2, charArrayAsString2);
	// Ahhh! This didn't work.  Only the first word "Hello" is copied into c2

	string trueBoolAsString = "True";
	bool bTrue;
	stringToAnyType(bTrue, trueBoolAsString);
	// Did this really work?

	string falseBoolAsString = "false";
	bool bFalse;
	stringToAnyType(bFalse, falseBoolAsString);
	// Ahhh! This didn't work.  It is still true not false;

	string yesBoolAsString = "Yes";
	bool bYes;
	stringToAnyType(bTrue, yesBoolAsString);
	// Ahhh! This didn't work.  It is still true not false;

	string noBoolAsString = "NO";
	bool bNo;
	stringToAnyType(bFalse, noBoolAsString);
	// Ahhh! This didn't work.  It is still true not false;
}

So obviously there must be a better way that will also get bool conversions and to get the full string when converting a string to a char array, but for now this gets your basic number types and any string without characters such as a space. When I have a solution that works for char types as well, I will let you know.

Also, as you can see that there is a chance of a loss of precision with floats and doubles so be careful.

Back on track with my High School goal to be a Programmer

I had a goal to become a Computer Programmer when i was in High School.

So in high school I had a computer programming class my sophomore year (it was Basic on an Apple / MAC).

In my home town, there is a Utah State University (USU) extension across the street from the high school. So we didn’t have any Advanced Placement (AP) classes. Instead, we were just given release time from high school and we went and took a college course. My Junior year I was going to take a computer programming class at the USU extension but not enough people signed up so they canceled it and I ended up in a computer graphics course. I did get into College Algebra/Pre-calc. My senior there was still no programming class and somehow my counselors screwed up and pulled me out of Calculus because I supposedly didn’t have enough art credits, which it turns out I had plenty of because because I had taken computer graphics and they just “forgot” to count it towards art.

I went to the University of Utah (U of U) after I graduated, but again, things were stacked against me. None of my friends came with me. They ran out of room in the Freshman dorms and stuck me in the graduate dorm with the weird oriental guy who was four years older than me and smoked. The lowest level computer programming class was not exactly simple and didn’t teach programming. The class spent all lecture talking about true false theory and then without even an introduction to C++, told us to write some C++ programs. They didn’t even require a C++ book for the course and in 1995 I am not sure there was a Sams Teach Yourself C++ in 21 Days (5th Edition) or such books and so I had no idea where to even start. My Dad lost his work and then I wrecked my car and used both those reasons as an excuse to just do a full hardship withdrawal of my courses.

I got side-tracked writing fantasy for the next little while. I server two years as a missionay for my church in the Dominican Republic and came home having forgotten that I wanted to be a developer. My brother moved to Provo and I wanted to live with him when I got home so I moved to Provo too. Which led to me going to Brigham Young University (BYU) where I got a degree in English (emphasis in Creative Writing, technical writing and editing) and a Minor in Spanish. I kept trying to get a Minor in Computer Science but there were just no night classes at all in CS. To help me get my degree I had started by getting my MCSE by taking a night training course the fall of 1999. Then I got a job at Convergys where Microsoft outsourced there Windows 2000 support. I was a Technical Lead for a support team there. Then I moved to the Nortel Networks account (they also outsourced to Convergys) where I was a router support engineer, a L3 switch support engineer, a Load-balancer Layer 7 switch support engineer, then a Technical Trainer, and somewhere in there I became an expert at wireless networking, learned FreeBSD, learned php, and started an open source project using FreeBSD, Apache, Mysql, and PHP. Convergys provided a tuition reimbursement, so they reimbursed my tuition until I graduated with my English degree in August of 04. Did I mention that I was an Assistant Fiction Director at Leading Edge Magazine? Check out issue 46 where i am listed under “Staff” and issues 47 and 48 where I am listed as “Assistant Fiction Director”.

So as you can see, even thought I was working on an English degree and as a hobby writing poetry and fiction stories, I was still working with computers and as a second hobby learning FreeBSD, Apache, MySQL, PHP.

Well, in August of 2004 I not only graduated but I got married, got a new job with LANDesk and moved to a new apartment (with just my new wife and I, of course).

At LANDesk, it being a software company, I was exposed to development more and my desire to get back into it returned. I went through a few books all on my own:

Then I took some classes at Salt Lake Community College, which were mostly in Java.

I started doing some small development projects and completed two add-ons for LANDesk.

A development position opened in Support, working with our internal support tools, data warehousing, reporting, etc…I applied and some how, my work paid off and I got the position. Now as was my original high school goal, I am a developer. Official title: System Analyst / Developer.

I am loving it.

WinPE Add-on: Updated PEShell.exe for LDMS 8.7 or 8.8

Description

This article contains alternate version of PEShell.exe.

One is an enhanced version of the PEShell.exe that comes with LANDesk’s version of WinPE.  It includes some menu options that can be beneficia.

The other is a PEShell.exe has that no menu options at all, for environments that need more security in WinPE.

Both have only been tested with 8.8.

Download Link

PEShell.exe Exe Zip
PEShell.exe with Enhanced Menu PEShell.exe PEShell.zip
PEShell.exe with No Menu (for secure environments) PEShellNoMenu.exe PEShellNoMenu.zip

How do I install it?

There is really no need for an installer. It can be added to the LDVPE1.IMG on the Core Server or it can be added to the peboot.img file on the PXE Representative directly.

Adding the new PEShell.exe to the LDVPE1.IMG on the Core Server

  1. Download the new PEShell.exe to your Core Server.
  2. Browse to \ManagementSuite\LANDesk\Vboot and open LDVPE1.IMG using a tool such as Winimage (http://www.winimage.com).
  3. Inject the new PEShell.exe into the i386\System32 folder in your LDVPE1.IMG file. The old PEShell.exe will be overwritten.

Any PXE Representatives deployed after replacing the PEShell.exe in the LDVPE1.IMG file will have the new PEShell.exe.

Any Provisioning Boot Media created after replacing the PEShell.exe in the LDVPE1.IMG file will have the new PEShell.exe.

Adding the new PEShell.exe to the PEBOOT.IMG on the PXE Representative

  1. Download the new PEShell.exe to your PXE Representative.
  2. Browse to C:\Program Files\LANDesk\PXE\System\Images and open PEBOOT.IMG using a tool such as Winimage (http://www.winimage.com).
  3. Inject the new PEShell.exe into the i386\System32 folder in your PEBOOT.IMG file. The old PEShell.exe will be overwritten.

How to store a password in an XML file encrypted so it is not in clear text or how to encrypt any textstring?

Ok, so I have an application that needs to take a password and I need to remember that password. All the configuration is stored in XML, which is usually clear text. I want to store the password in the XML file, but I don’t want anyone to be able to open the XML file and be able to see the password in clear text.

So here is what I going to do.

I create a class called PasswordEncoder that is going to use DESCryptoServiceProvider, which is a C# function.

I found a few examples online that helped me create this, such as Microsoft’s site that explains this object and another users blog that shows an example, which I used but only slightly modified.

http://msdn.microsoft.com/en-us/library/system.security.cryptography.descryptoserviceprovider.aspx

http://www.dotnetspider.com/resources/21370-Password-Encryption-using-C.aspx

So here is my source. All you have to do is create your own class and copy in this code and you are ready to encrypt and decrypt passwords you store in XML.

Important! You must change the mInitializationVector and the mByteArray variable values to be your own values. Yes you can simply make up your own values.  We don’t want a everyone using the same keys.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace PasswordEncoder
{
    class PasswordEncoder
    {
        string mEncryptedPassword;
        // Change the two values below to be something other than the example.
        // Once changed and in use, do not change the value below again or you
        // won't be able to decrypt previously stored passwords.
        string mByteArray = "%$#>#%232s+as#l)URa0$!@";
        byte[] mInitializationVector = { 0x01, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xf7, 0xEF };

        public PasswordEncoder()
        {
        }

        public PasswordEncoder(string inPassword)
        {
            mEncryptedPassword = EncryptWithByteArray(inPassword, mByteArray);
        }

        public string EncryptWithByteArray(string inPassword)
        {
            mEncryptedPassword = EncryptWithByteArray(inPassword, mByteArray);
            return mEncryptedPassword;
        }

        private string EncryptWithByteArray(string inPassword, string inByteArray)
        {
            try
            {
                byte[] tmpKey = new byte[20];
                tmpKey = System.Text.Encoding.UTF8.GetBytes(inByteArray.Substring(0, 8));
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] inputArray = System.Text.Encoding.UTF8.GetBytes(inPassword);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(tmpKey, mInitializationVector), CryptoStreamMode.Write);
                cs.Write(inputArray, 0, inputArray.Length);
                cs.FlushFinalBlock();
                return Convert.ToBase64String(ms.ToArray());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string DecryptWithByteArray()
        {
            return DecryptWithByteArray(mEncryptedPassword, mByteArray);
        }

        private string DecryptWithByteArray(string strText, string strEncrypt)
        {
           try
           {
                byte[] tmpKey = new byte[20];
                tmpKey = System.Text.Encoding.UTF8.GetBytes(strEncrypt.Substring(0, 8));
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                Byte[] inputByteArray = inputByteArray = Convert.FromBase64String(strText);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(tmpKey, mInitializationVector), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                System.Text.Encoding encoding = System.Text.Encoding.UTF8;
                return encoding.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string EncryptedPassword
        {
            get { return mEncryptedPassword; }
            set { mEncryptedPassword = value; }
        }

        public string ByteArray
        {
            get { return mByteArray; }
            set { mByteArray = value; }
        }
    }
}

Here is a simple sample of how to use this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PasswordEncoder
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Enter a password: ");
            string password = Console.ReadLine();
            Console.WriteLine("You entered this password: " + password);

            PasswordEncoder pe = new PasswordEncoder();
            string encryptedPassword = pe.EncryptWithByteArray(password);
            Console.WriteLine("Your encrypted password string: " + encryptedPassword);

            string decryptedPassword = pe.DecryptWithByteArray();
            Console.WriteLine("Your decrypted password string: " + decryptedPassword);

            if (password.Equals(decryptedPassword))
            {
                Console.WriteLine("Good work, your password was successfully encrypted then decrypted.");
            }
            else
            {
                Console.WriteLine("Uh...what did you do wrong, these don't match.");
            }
        }
    }
}