Jason Shuler's Tech Blog
Rantings and musings of an IT handyman
Rantings and musings of an IT handyman
Aug 9th
Today I performed a p2v conversion of a Windows XP workstation into VMWare ESXi using the free VMware Converter. This tool is really wonderful, but sometimes it likes to leave windows in an inconsistent state – especially if you resize the partition.
This case is complicated by the fact that the source computer has the Dell recovery partition, which I decided to bring along as well. After conversion, I shut down the source PC, and power on the VM, only to get Error loading operating system.
The internets failed me. Plenty of people have had the problem, but most of the solutions involved Linux or Vista+ (or reformatting. Obviously not an option). Additionally, I have encountered this problem when performing a p2v on a Server 2008 box…
I tried using the windows XP cd recovery console with fixboot and fixmbr. It didn’t work. I fooled around with the UBCD. Again, didn’t work (and wasted a lot of time) Finally, I fell back on previous experience, and found my solution: use the server 2008 CD to fix windows XP! (This would probably work with the Vista or windows 7 images as well)
So here are the steps to fix the “Error loading operating system” issue (with Windows XP ONLY) caused by vmware converter:
If you still have a problem, my only other suggestion would be to use diskpart to ensure that the correct partition is active. If that diesn’t solve it, maybe the other Google results will
Good luck, and please leave a comment if this helped!
May 2nd
Shulerent.com is relaunched as Jason Shuler’s Tech Blog using WordPress (instead of Nucleus).
I have decided to venture outside the realm of obscurity, and join the community. Nucleus really wasn’t up to the challenge, and Shuler Enterprises is no real company… so a change of venue and name was in order. I will still need to go back through and perform some cleanup, since all previous posts were imported.
Stay tuned for more frequent updates and I attempt to integrate my online presence
-Jason
Feb 22nd
I’m working on an app that will monitor the number of GDI Objects of another process (in this case, the spooler)
To do this in VB.NET requires an API call to GetGuiResources. While testing, I was using Process.GetProcesses to get a list of all the available processes, passed the handle of each process to the API function, and writing the result to a textbox.
Problem was, all process that I did not own throw security errors, even when I set the app to run with elevated privs. The internet once again failed me, and I stumbled across the solution while browsing the system.diagnostics.process documentation on MSDN.
The solution is to call Process.EnterDebugMode() before getting your process list and calling the API, then calling Process.LeaveDebugMode() when you are done.
MSDN EnterDebugMode Documentation
Here is an example. remember to run with elevate privs, and create a multiline textbox called txtOut.
Public Class Form1
Declare Function GetGuiResources Lib "user32" (ByVal hProcess As Long, ByVal uiFlags As Long) As Long
' uiFlags: 0 - Count of GDI objects
' uiFlags: 1 - Count of USER objects
Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo.Click
Dim procList As Process()
Dim TYPE_GDI As UInteger = 0
Process.EnterDebugMode()
procList = Process.GetProcesses
For Each proc As Process In procList
Dim objCnt As Long
Try
objCnt = GetGuiResources(proc.Handle, TYPE_GDI)
Catch ex As Exception
objCnt = -1
End Try
txOut.AppendText(proc.ProcessName & vbTab & "GDI: " & objCnt.ToString & vbNewLine)
Next proc
Process.LeaveDebugMode()
End Sub
End Class
Feb 3rd
Don’t listen to the internet – getting account information from active directory for the current user is simple and easy in Visual Basic .NET – particularly if you are using Framework 3.5.
You don’t need to do any stinking LDAP queries, or lookups, or credential passings – it’s all made simple using System.DirectoryServices.AccountManagement. Observe.
First, go to the references tab in project properties, click add reference, and find “System.DirectoryServices.AccountManagement” – no need to add “System.DirectoryServices”.
Now, in your application, add the following lines:
Dim currentADUser As System.DirectoryServices.AccountManagement.UserPrincipal currentADUser = System.DirectoryServices.AccountManagement.UserPrincipal.Current
(It’s even simpler if you import the namespace)
Poof. That’s it! You are done.
currentADUser is a strongly typed object containing attributes for most of the active directory properties you need = such as display name, email address, primary group membership, exchange mailbox info, etc, etc.
Say you want to get the current user’s email address. You could do it like so (after the previous code):
Dim userEmail as string = currentADUser.EmailAddress
That’s it. 1 additional line.
How about a concrete example – here is the problem I wanted to solve. Send an email message from the current user for error reporting – Make sure to change the To: email address, and the smtp server name, and this should be a drop-in solution:
Private Sub report_error(ByVal errorMessage As String)
Dim currentADUser As System.DirectoryServices.AccountManagement.UserPrincipal
currentADUser = System.DirectoryServices.AccountManagement.UserPrincipal.Current
Dim mailClient As New System.Net.Mail.SmtpClient("smtpserver.company.local")
mailClient.Send(currentADUser.DisplayName & " <" & currentADUser.EmailAddress & ">", _
"notifications@company.com", _
"ERROR REPORT: Application error for " & currentADUser.DisplayName, _
errorMessage)
End Sub
Hope this helps!
Jan 31st
Sorry about the spam comments. Looks like I need to update nucleus. One of these days I will upgrade to wordpress…
Dec 6th
If you have purchased a Virgin Mobile Broadband2Go pay as you go aircard (actually a novatell wireless ovation MC760), and find that the driver installation hangs on Windows 7, you will also find that the internet is little help.
The solution is to disable USB Selective Suspending until Virgin Mobile releases a driver version later than 2.02.04.002
Here is the link to the release notes for the OQO drivers – which are newer that either the Virgin Mobile or Novatel generic drivers.
You disable USB selective suspend from the advanced power settings screen.
Nov 10th
If you need to install Vmware ESXi (or possibly ESX) 4 on a server without an optical drive – that is, install FROM a USB drive (not “to”), here is how to do in in Windows:
1. Download and extract syslinux: http://syslinux.zytor.com/wiki/index.php/Download
You will want syslinux-3.XX.zip – the latest at time of writing is syslinux-3.83.zip and it works fine.
Extract it somewhere – lets say c:\syslinux
2. Insert the USB drive if you have not already, make sure it is formatted fat32, and make note of the drive letter. For our example, we will use k:.
3. Open a command prompt. (In windows Vista or 7, make sure to Run as Administrator)
Change directory to the place you extracted syslinux \ win32.
cd c:\syslinux\win32
syslinux -m -f -a {drive}:
where {drive} is the drive letter of the USB drive.
4. Extract or copy the contents of the ESX iso image to the USB drive (you can use 7zip or winrar – no need to burn it)
5. rename ISOLINUX.CFG to SYSLINUX.CFG
That should do it.
This is based on info from the following sites – I didn’t really change anything except the version, so if this doesn’t work, they these:
http://www.squishnet.com/?p=17
http://www.vm-help.com/esx40i/ESXi_USB_install.php
Aug 21st
The following is my description of how I figured out how to decode the D-Link settings file. If you don’t care how I figured it out, skip to the end for VB.Net code samples and an executable.
I have a DIR-628 wireless router that is having issues. There is a firmware update available, but my issue is not mentioned in the readme for the firmware.
Normally when I upgrade the firmware, I will dump out a settings file, perform the upgrade, reload the settings file, and rejoice in the time saved not having to reconfigure. This time, though, I think I would like to have a clean slate – but there are some options that include passwords I don’t recall offhand, so I figure I can just dump out the settings file, and take a look at it to get all that info…
Wrong. The settings file is binary gobbledeygook.
The default file name is gateway_settings.gws, and the file is about 175k.
I gave Google a thorough searching, and had no luck – it looks like other people are searching for GWS format, or GWS file, but there were no meaningful pages that I could find.
Next I downloaded trid_w32 – a neat little utility for identifying file types. I thought maybe it was compressed or something…
No dice.
So I decided to use the reverse engineering method – make some changes, and observe the result in the file.
I created a firewall rule named “AAAAAAAAAAAA”, and saved the settings; then renamed the rule to “BBBBBBBBBBBB”, and use a nice binary comparison tool (HexCmp in this case) to see what my changes did.
The A’s within the file had become “78 79 7A 7B 7C 7D 7E…” – they were shifted, but that offset increased by 1 for each character. This I can fix!
I then decoded the character before the first A – it was a “>”. Could it be? Could this file really be XML??
Worked backwards a couple more characters and had “name>AAAA…” – yes indeed! The decoded file will be XML!!
The next question was where to begin – what will be the shift of the first character? If the file is xml, I can be pretty sure the first character is a “<" - and this is the first character of the .gws file.
After much fooling around in VB.net, and battling with modulus math, I had the encoder formula:
encodedByte = (positionNbr + CharacterCode) mod 256
Decoding was a bit trickier, because as long as (position mod 256) + characterCode is less than 256, you can just subtract. If it is greater than 256, you have to work a bit harder. If I had more time, I bet there is a way to write a single formula to restore the character code, but I was able to do it with an IF statement.
Here is the VB.net function for decoding a byte array containing the .gws file
Function decodeGWS(ByRef encodedGWS As Byte()) As String
Dim chrMax As UInteger
Dim decodedGWS As Char()
chrMax = encodedGWS.GetUpperBound(0)
ReDim decodedGWS(chrMax)
For i As UInteger = 0 To chrMax
If encodedGWS(i) < (i Mod 256) Then
decodedGWS(i) = Chr((256 + encodedGWS(i)) - (i Mod 256))
Else
decodedGWS(i) = Chr(encodedGWS(i) - (i Mod 256))
End If
Next i
Return decodedGWS
End Function
And it works like a charm. The file is actually a great big XML containing all the available options.
Here is the little utility I wrote to decode the file:
GWS Decoder Utility
For completeness sake, I included encoder functionality, and I have verified that the output is identical to the original file when no changes are made to the xml file, but I really don’t know what would happen if you tried to make changes to the XML and load it back onto your router. If you want to try it, don’t come crying to me when your router gives up it’s magic smoke, or your house burns down.
Hopefully somebody finds this helpful!