Microsoft Product Key Viewer (Delphi 5-7)

UNIT MSProdKey;

{
**************************************************************************************
* Unit MSProdKey v2.2                                                                *
*                                                                                    *
*  Description: Decode and View the Product Key, Product ID and Product Name used to *
*               install: Windows 2000, XP, Server 2003, Office XP, 2003.             *
*               *Updated* Now works for users with Non-Administrative Rights.        *
*               Code cleanup and changes, Commented.                                 *
*                                                                                    *
*  Usage: Add MSProdKey to your Application's uses clause.                           *
*                                                                                    *
*  Example 1:                                                                        *
*                                                                                    *
* procedure TForm1.Button1Click(Sender: TObject);                                    *
* begin                                                                              *
*   if not IS_WinVerMin2K then // If the Windows version isn't at least Windows 2000 *
*   Edit1.Text := 'Windows 2000 or Higher Required!' // Display this message         *
*   else // If the Windows version is at least Windows 2000                          *
*   Edit1.Text := View_Win_Key; // View the Windows Product Key                      *
*   Label1.Caption := PN; // View the Windows Product Name                           *
*   Label2.Caption := PID; // View the Windows Product ID                            *
* end;                                                                               *
*                                                                                    *
*  Example 2:                                                                        *
* procedure TForm1.Button2Click(Sender: TObject);                                    *
* begin                                                                              *
*   if not IS_OXP_Installed then // If Office XP isn't installed                     *
*   Edit1.Text := 'Office XP Required!' // Display this message                      *
*   else // If Office XP is installed                                                *
*   Edit1.Text := View_OXP_Key; // View the Office XP Product Key                    *
*   Label1.Caption := DN; // View the Office XP Product Name                         *
*   Label2.Caption := PID; // View the Office XP Product ID                          *
* end;                                                                               *
*                                                                                    *
*  Example 3:                                                                        *
* procedure TForm1.Button3Click(Sender: TObject);                                    *
* begin                                                                              *
*   if not IS_O2K3_Installed then // If Office 2003 isn't installed                  *
*   Edit1.Text := 'Office 2003 Required!' // Display this message                    *
*   else // If Office 2003 is installed                                              *
*   Edit1.Text := View_O2K3_Key; // View the Office 2003 Product Key                 *
*   Label1.Caption := DN; // View the Office 2003 Product Name                       *
*   Label2.Caption := PID; // View the Office 2003 Product ID                        *
* end;                                                                               *
*                                                                                    *
* Copyright © 2004 Chuck D                                                           *
**************************************************************************************
}

INTERFACE

USES Registry, Windows, SysUtils, Classes;

FUNCTION IS_WinVerMin2K: BOOLEAN; // Check OS for Win 2000 or higher
FUNCTION View_Win_Key: STRING; // View the Windows Product Key
FUNCTION IS_OXP_Installed: BOOLEAN;  // Check if Office XP is installed
FUNCTION View_OXP_Key: STRING;  // View the Office XP Product Key
FUNCTION IS_O2K3_Installed: BOOLEAN; // Check if Office 2003 is installed
FUNCTION View_O2K3_Key: STRING; // View the Office 2003 Product Key
FUNCTION DecodeProductKey(CONST HexSrc: ARRAY OF BYTE): STRING;  // Decodes the Product Key(s) from the Registry

VAR
  Reg: TRegistry;
  binarySize: INTEGER;
  HexBuf: ARRAY OF BYTE;
  temp: TStringlist;
  KeyName, KeyName2, SubKeyName, PN, PID, DN: STRING;

IMPLEMENTATION

FUNCTION IS_WinVerMin2K: BOOLEAN;
VAR
  OS: TOSVersionInfo;
BEGIN 
  ZeroMemory(@OS, SizeOf(OS));
  OS.dwOSVersionInfoSize := SizeOf(OS);
  GetVersionEx(OS);
  Result := (OS.dwMajorVersion >= 5) AND
       (OS.dwPlatformId = VER_PLATFORM_WIN32_NT);
  PN := ''; // Holds the Windows Product Name
  PID := ''; // Holds the Windows Product ID
END; 


FUNCTION View_Win_Key: STRING;
BEGIN
  Reg := TRegistry.Create;
  TRY
       Reg.RootKey := HKEY_LOCAL_MACHINE;
       IF Reg.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows NT\CurrentVersion') THEN
        BEGIN
            IF Reg.GetDataType('DigitalProductId') = rdBinary THEN
             BEGIN
                 PN := (Reg.ReadString('ProductName'));
                 PID := (Reg.ReadString('ProductID'));
                 binarySize := Reg.GetDataSize('DigitalProductId');
                 SetLength(HexBuf, binarySize);
                 IF binarySize > 0 THEN
                  BEGIN
                      Reg.ReadBinaryData('DigitalProductId', HexBuf[0], binarySize);
                  END;
             END;
        END;
  FINALLY
       FreeAndNil(Reg);
   END;

  Result := '';
  Result := DecodeProductKey(HexBuf);
END;

FUNCTION IS_OXP_Installed: BOOLEAN;
VAR
  Reg: TRegistry;
BEGIN
  Reg := TRegistry.Create;
  TRY
       Reg.RootKey := HKEY_LOCAL_MACHINE;
       Result := Reg.KeyExists('SOFTWARE\MICROSOFT\Office\10.0\Registration');
  FINALLY
       Reg.CloseKey;
       Reg.Free;
   END;
  DN := ''; // Holds the Office XP Product Display Name
  PID := ''; // Holds the Office XP Product ID
END;

FUNCTION View_OXP_Key: STRING;
BEGIN
  TRY
       Reg := TRegistry.Create;
       Reg.RootKey := HKEY_LOCAL_MACHINE;
       KeyName := 'SOFTWARE\MICROSOFT\Office\10.0\Registration\';
       Reg.OpenKeyReadOnly(KeyName);
       temp := TStringList.Create;
       Reg.GetKeyNames(temp); // Enumerate and hold the Office XP Product(s) Key Name(s)
       Reg.CloseKey;
       SubKeyName := temp.Strings[0]; // Hold the first Office XP Product Key Name
       Reg := TRegistry.Create;
       Reg.RootKey := HKEY_LOCAL_MACHINE;
       KeyName2 := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\';
       Reg.OpenKeyReadOnly(KeyName2 + SubKeyName);
       DN := (Reg.ReadString('DisplayName'));
       Reg.CloseKey;
  EXCEPT on E: EStringListError DO
            Exit
   END;
  TRY
       IF Reg.OpenKeyReadOnly(KeyName + SubKeyName) THEN
        BEGIN
            IF Reg.GetDataType('DigitalProductId') = rdBinary THEN
             BEGIN
                 PID := (Reg.ReadString('ProductID'));
                 binarySize := Reg.GetDataSize('DigitalProductId');
                 SetLength(HexBuf, binarySize);
                 IF binarySize > 0 THEN
                  BEGIN
                      Reg.ReadBinaryData('DigitalProductId', HexBuf[0], binarySize);
                  END;
             END;
        END;
  FINALLY
       FreeAndNil(Reg);
   END;

  Result := '';
  Result := DecodeProductKey(HexBuf);
END;

FUNCTION IS_O2K3_Installed: BOOLEAN;
VAR
  Reg: TRegistry;
BEGIN
  Reg := TRegistry.Create;
  TRY
       Reg.RootKey := HKEY_LOCAL_MACHINE;
       Result := Reg.KeyExists('SOFTWARE\MICROSOFT\Office\11.0\Registration');
  FINALLY
       Reg.CloseKey;
       Reg.Free;
   END;
  DN := ''; // Holds the Office 2003 Product Display Name
  PID := ''; // Holds the Office 2003 Product ID
END;

FUNCTION View_O2K3_Key: STRING;
BEGIN
  TRY
       Reg := TRegistry.Create;
       Reg.RootKey := HKEY_LOCAL_MACHINE;
       KeyName := 'SOFTWARE\MICROSOFT\Office\11.0\Registration\';
       Reg.OpenKeyReadOnly(KeyName);
       temp := TStringList.Create;
       Reg.GetKeyNames(temp); // Enumerate and hold the Office 2003 Product(s) Key Name(s)
       Reg.CloseKey;
       SubKeyName := temp.Strings[0]; // Hold the first Office 2003 Product Key Name
       Reg := TRegistry.Create;
       Reg.RootKey := HKEY_LOCAL_MACHINE;
       KeyName2 := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\';
       Reg.OpenKeyReadOnly(KeyName2 + SubKeyName);
       DN := (Reg.ReadString('DisplayName'));
       Reg.CloseKey;
  EXCEPT on E: EStringListError DO
            Exit
   END;
  TRY
       IF Reg.OpenKeyReadOnly(KeyName + SubKeyName) THEN
        BEGIN
            IF Reg.GetDataType('DigitalProductId') = rdBinary THEN
             BEGIN
                 PID := (Reg.ReadString('ProductID'));
                 binarySize := Reg.GetDataSize('DigitalProductId');
                 SetLength(HexBuf, binarySize);
                 IF binarySize > 0 THEN
                  BEGIN
                      Reg.ReadBinaryData('DigitalProductId', HexBuf[0], binarySize);
                  END;
             END;
        END;
  FINALLY
       FreeAndNil(Reg);
   END;

  Result := '';
  Result := DecodeProductKey(HexBuf);
END;

FUNCTION DecodeProductKey(CONST HexSrc: ARRAY OF BYTE): STRING;
CONST
  StartOffset: INTEGER = $34; { //Offset 34 = Array[52] }
  EndOffset: INTEGER = $34 + 15; { //Offset 34 + 15(Bytes) = Array[64] }
  Digits: ARRAY[0..23] OF CHAR = ('B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R', 'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9');
  dLen: INTEGER = 29; { //Length of Decoded Product Key }
  sLen: INTEGER = 15; { //Length of Encoded Product Key in Bytes (An total of 30 in chars) }
VAR
  HexDigitalPID: ARRAY OF CARDINAL;
  Des: ARRAY OF CHAR;
  I, N: INTEGER;
  HN, Value: CARDINAL;
BEGIN
  SetLength(HexDigitalPID, dLen);
  FOR I := StartOffset TO EndOffset DO
   BEGIN
       HexDigitalPID[I - StartOffSet] := HexSrc[I];
   END;

  SetLength(Des, dLen + 1);

  FOR I := dLen - 1 DOWNTO 0 DO
   BEGIN
       IF (((I + 1) MOD 6) = 0) THEN
        BEGIN
            Des[I] := '-';
        END
       ELSE
        BEGIN
            HN := 0;
            FOR N := sLen - 1 DOWNTO 0 DO
             BEGIN
                 Value := (HN SHL 8) OR HexDigitalPID[N];
                 HexDigitalPID[N] := value DIV 24;
                 HN := Value MOD 24;
             END;
            Des[I] := Digits[HN];
        END;
   END;
  Des[dLen] := Chr(0);

  FOR I := 0 TO Length(Des) DO
   BEGIN
       Result := Result + Des[I];
   END;
END;

END.

Download MSProdKey.pas