2015年1月23日 星期五

[C/C++] 存取記憶體所需瞭解的對齊問題

寫程式對記憶體存取時,需要瞭解兩件事:1. Little Endian與Big Endian在記憶體裡存放的差別;2.  記憶體資料的對齊問題。此篇文章所要探討的即是對齊問題,以現有的計算機(computer)來說,許多計算機均有能力去存取對齊和不對齊在記憶體位址上的資料,計算機結構-計量方法這本書就解釋得非常清楚,現有一個大小為N的資料存放在某一記憶體位址
A上,只要此位址A除以N且可以被整除的話,就代表此資料是對齊的(aligned):反之就是不對齊的(misaligned),以計算機結構裡的圖可以讓人簡單明瞭 (註:從白算盤到計算機結構主要都是以MIPS架構作為主題,書中的word代表32位元,但是在x86/x64架構下word則是代表16位元):

Fig.1 Aligned and misaligned address.
由於計算機是以位元組定址,所以byte存放在任何位址上均是對齊在byte boundary上,但若是half word, word或double world的話,就會有對齊和不對齊的問題,若要能夠存取非對齊的資料,計算機的設計也會變得比較複雜。既然有些計算機均可存取對齊和不對齊的資料,那對不對齊又有何差別? 答案當然是有差別的,以不對齊的資料來說,計算機會存取的比已經對齊好的資料還要慢,所以編譯器通常會將程式碼的資料做對齊處理,為了讓人有更深入的感受,在此宣告一結構說明:
struct AlignedStruct{
    uint8_t         uint8Var1; 
    uint64_t        uint64Var2;
    uint8_t         uint8Var3; 
    uint16_t        uint16Var4;
    uint8_t         uint8Var5;
    uint32_t        uint32Var6;
    uint64_t        uint64Var7;
    uint32_t        uint32Var8;
};

uint64_t getAlignedAddress(uint64_t currentElementAddr,uint16_t currentElementSize,uint16_t nextElementSize){
    uint64_t address = currentElementAddr + currentElementSize;

    for(;;){
        if((address%nextElementSize) == 0)
            break;
        else
            address ++;
    }
    return address;
}

getAlignedAddress()是根據上述說明,用來計算下一筆資料的對齊位址,第二行算出下一筆資料的起始位址,由於無法肯定此位址是不是對齊好的位址,所以第四到第九行用來計算下一筆資料的實際對齊位址。因此AlignedStruct結構在記憶體裡的排放方式如Fig. 2所顯示的樣子:
Fig.2 Struct layout in the memory space.
目前為止都是根據理論來說明,下例的程式碼用來確認實際上的狀況:

待補...

2015年1月15日 星期四

[C/C++] Function Pointer

Every variables you declare in the program are stored in memory. In other words, there is an unique memory address for every variables. It is as same as the function even main function. Every functions have their own memory address.

For example:
void KeyFuncForA(char *OutputString)
{
 printf("A: %s\n", OutputString);
}
If we can use variable pointers to access memory to get the variables' value, we can also use function pointers to access memory to do a function call. And there are three important things you should know.
  1. The function return type.
  2. The parameter type.
  3. The number of parameter.
Above are used to declare a function pointer correctly. That's say if we want to declare a function pointer pointing to a function called "TestFunc". And the prototype of the function "TestFunc" is as below:
int TestFunc (unsigned char *ucPtr, char *String); // Prototype of function "TestFunc".

Now, we declare a function pointer called "FuncPtr" to point the function "Test Func":
int (*FuncPtr)(unsigned char*, char *); // Function pointer declaration.

After that, we can use the function pointer "FuncPtr" to point the function we want to use it, and this is how we can do:
FuncPtr = TestFunc; // Make "FuncPtr" point to function "TestFunc".
FuncPtr(0xFF, "Hello!"); // Make a function call. 
To be continue...

2015年1月5日 星期一

[UEFI/EDK II Sample Code] SATA/sSATA Hard Disk Drive (HDD) Information

This sample demonstrates how to  read the model name of the SATA/sSATA HDD and calculate the capacity of the HDD. There's no need to direct use ATA/ATAPI command any more.

HDDinfo.inf

##
[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = HDDinfo
  FILE_GUID                      = 4aA8A36E-ED34-44db-AE97-1FA5E4ED7776
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = UefiMain

[Sources]  
 HDDinfo.c

  
[Packages]
  MdePkg/MdePkg.dec
  ShellPkg/ShellPkg.dec
  MdeModulePkg/MdeModulePkg.dec
  
[LibraryClasses]
  UefiBootServicesTableLib
  UefiLib
  UefiRuntimeServicesTableLib
  UefiApplicationEntryPoint
  PrintLib
  DebugLib
  
[Protocols]
  gEfiDiskInfoProtocolGuid

HDDinfo.c

#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h> 
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Protocol/DiskInfo.h>
#include <Protocol/IdeControllerInit.h>
#include <Include/Base.h>

#define MODEL_NAME_SIZE      40
#define SECTOR_SIZE       512
#define BYTE_SIZE       8
#define MILLION        1000000
#define KILOBYTE       1024
#define MEGABYTE       (1024*1024)
#define GIGABYTE       (1024*1024*1024)
#define TERABYTE       (1024*1024*1024*1024)
#define MAX_VALUE_48_BIT_ADDRESSING   0x0FFFFFFFFFFFF

typedef enum {SATADrive,sSATADrive,SASDrive,OtherDrive} Storage_Drive_Type;
typedef struct{
 //I didn't implement a function to identify the current port number in this sample.
 UINT8    PortNumber;
 //I didn't implement a function to identify the Storage_Drive_Type in this sample.
 Storage_Drive_Type  DriveType;  
 CHAR16    DriveName[40];
 UINTN               DriveCapacity;  //Byte
} Storage_Drive_Information;


VOID
AsciiToUnicode (CHAR8 *AsciiString,CHAR16 *UnicodeString)
{
  UINT8 i;

  i = 0;
  while (AsciiString[i] != 0) {
    UnicodeString[i] = (CHAR16) AsciiString[i];
    i++;
  }
  UnicodeString[i] = '\0';
}

VOID Swap(UINT8* a,UINT8* b)
{
 UINT8 temp;
 temp = *b;
 *b = *a;
 *a = temp;
}

VOID InitIdentifyDriveInformation(EFI_DISK_INFO_PROTOCOL *DiskInfo,EFI_IDENTIFY_DATA *IdentifyDriveInfo)
{
 UINT32    Size = sizeof (EFI_IDENTIFY_DATA);
 EFI_STATUS    Status;
 Status = DiskInfo->Identify (
                DiskInfo,
                IdentifyDriveInfo,
                &Size
                );
 ASSERT_EFI_ERROR(Status);
}

VOID GetStorageDeviceName(EFI_IDENTIFY_DATA *IdentifyDriveInfo,Storage_Drive_Information* DriveInfo)
{
 UINTN     i;
 
 for(i = 0;i < sizeof(IdentifyDriveInfo->AtaData.ModelName);i += 2)
  Swap(&IdentifyDriveInfo->AtaData.ModelName[i],&IdentifyDriveInfo->AtaData.ModelName[i+1]);
 AsciiToUnicode ((CHAR8 *) &IdentifyDriveInfo->AtaData.ModelName, DriveInfo->DriveName);
 
 for(i = 0;i < MODEL_NAME_SIZE; i++)
  if(DriveInfo->DriveName[i]==0x20 && DriveInfo->DriveName[i+1]==0x20){
   DriveInfo->DriveName[i] = '\0';
   break;
 }
}

UINTN GetStorageDeviceSize(EFI_IDENTIFY_DATA  *IdentifyDriveInfo)
{
 UINTN                  DriveCapacity = 0;
 UINTN       offset;
 UINTN       ShiftCount;
 //Devices that conform to this standard shall clear bit 15 to zero.
 if ((IdentifyDriveInfo->AtaData.config & BIT15) == 0) {
  //48-bit Address feature set is supported
  if (IdentifyDriveInfo->AtaData.command_set_supported_83 & BIT10) {
   ShiftCount = sizeof(IdentifyDriveInfo->AtaData.maximum_lba_for_48bit_addressing[0]) * BYTE_SIZE;
   DriveCapacity = IdentifyDriveInfo->AtaData.maximum_lba_for_48bit_addressing[0];
   for (offset = 1; offset < (sizeof(IdentifyDriveInfo->AtaData.maximum_lba_for_48bit_addressing)/ 
       sizeof(IdentifyDriveInfo->AtaData.maximum_lba_for_48bit_addressing[0])); offset++) { 
    DriveCapacity |= (UINTN)IdentifyDriveInfo->AtaData.maximum_lba_for_48bit_addressing[offset] <<
        (ShiftCount * offset);
   }
   DriveCapacity = (DriveCapacity&MAX_VALUE_48_BIT_ADDRESSING) * SECTOR_SIZE;
  } 
  else {
   ShiftCount = sizeof(IdentifyDriveInfo->AtaData.user_addressable_sectors_hi) * BYTE_SIZE;
   DriveCapacity =(IdentifyDriveInfo->AtaData.user_addressable_sectors_hi << ShiftCount) |
       IdentifyDriveInfo->AtaData.user_addressable_sectors_lo * SECTOR_SIZE;
  } 
 }
 return DriveCapacity;
}

EFI_STATUS
EFIAPI
UefiMain (
          IN EFI_HANDLE        ImageHandle,
          IN EFI_SYSTEM_TABLE  *SystemTable
          ) 
{    
 EFI_STATUS      Status;
 EFI_IDENTIFY_DATA   *IdentifyDriveInfo = NULL;
 UINTN                    HandleCount;
 EFI_HANDLE               *HandleBuffer;
 EFI_DISK_INFO_PROTOCOL   *DiskInfo;
 UINTN                    Index;
 Storage_Drive_Information *DriveInfo;

 Status = gBS->LocateHandleBuffer (
   ByProtocol,
   &gEfiDiskInfoProtocolGuid,
   NULL,
   &HandleCount,
   &HandleBuffer
   );
 ASSERT_EFI_ERROR(Status);
 
 DriveInfo = AllocatePool (sizeof(Storage_Drive_Information)*HandleCount);
 for (Index = 0; Index < HandleCount; Index++) {
  Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDiskInfoProtocolGuid, &DiskInfo);
  ASSERT_EFI_ERROR(Status); 
  IdentifyDriveInfo = AllocatePool (sizeof (EFI_IDENTIFY_DATA));
  InitIdentifyDriveInformation(DiskInfo,IdentifyDriveInfo);
  GetStorageDeviceName(IdentifyDriveInfo,&DriveInfo[Index]);
  DriveInfo[Index].DriveCapacity  = GetStorageDeviceSize(IdentifyDriveInfo);
  gBS->FreePool (IdentifyDriveInfo);
 }
 for(Index = 0; Index < HandleCount;Index ++)
 {
  Print(L"Drive Model Name: %s , ",DriveInfo[Index].DriveName);
  Print(L"Drive Size: %d GB\n",DriveInfo[Index].DriveCapacity/GIGABYTE);
 }
 
 gBS->FreePool(DriveInfo);
    return EFI_SUCCESS;
}

Execution Result:
Fig. 1. Result.
 Q: How to read the current port number and identify the drive type?
 A: Please check the chipset  Spec. of your platform and use EFI_DISK_INFO_PROTOCOL (WhichIde() function) as well as EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

 Reference:
 1. ATA_IDENTIFY_DATA Struct Reference
 2. AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
 3. UEFI/PI Spec

[UEFI/EDK II Sample Code] PCI and PCI-E Device Scan

This sample demonstrates how to scan all PCI and PCI-E device.

LsPciDev.inf
##

[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = LsPciDev
  FILE_GUID                      = 8cfdb267-ceed-4e72-b541-a44ce670c037
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = UefiMain

[Sources]  
  LsPciDev.c
  PciVenInfo.h
  PciClassInfo.h
  
[Packages]
  MdePkg/MdePkg.dec
  ShellPkg/ShellPkg.dec
  MdeModulePkg/MdeModulePkg.dec
  StdLib/StdLib.dec
  EdkCompatibilityPkg/EdkCompatibilityPkg.dec
  IntelFrameworkPkg/IntelFrameworkPkg.dec
  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec 
  
[LibraryClasses]
  UefiBootServicesTableLib
  UefiLib
  UefiApplicationEntryPoint
  PrintLib
  DebugLib
  ShellLib
  
[Protocols]
  gEfiPciRootBridgeIoProtocolGuid #metohd 1

LsPciDev.c
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Protocol/PciIo.h>
#include <Protocol/PciRootBridgeIo.h>
#include <IndustryStandard/Pci22.h>
#include <Library/ShellLib.h>
#include <Library/UefiShellDebug1CommandsLib/Pci.h>
#include "PciVenInfo.h"
#include "PciClassInfo.h"

#define DID_OFFSET          2
#define Rev_ID_OFFSET       8
#define CLASS_CODE_OFFSET   9
#define HEADER_TYPE_OFFSET  0xE
#define CAP_POINTER         0x34
#define PCIE_DEVICE         0x10

UINT32 __inline SerachVenTable(UINT32 LowIndex,UINT32 HighIndex,PCI_VENTABLE SortedArray[],UINT16 TargetVID)
{   UINT32 Low,High,Mid;
    Low = LowIndex;
    High = HighIndex;
    Mid = (Low + High)/2;

    if(SortedArray[Mid].VenId == TargetVID)
        return Mid;
    else{
        if(TargetVID > SortedArray[Mid].VenId)
            Low = Mid + 1;
        else
            High = Mid - 1;
        if(High < Low)
            return 0xffffffff; //PCI_Ven_Info.h should be updated.
        else
   return SerachVenTable(Low,High,SortedArray,TargetVID);
    }
}

UINT32 __inline SerachPciClassTable(UINT32 LowIndex,UINT32 HighIndex,PCI_CLASSCODETABLE SortedArray[],UINT32 TargetClassCode)
{   UINT32 Low,High,Mid,ToClassCode;
    Low = LowIndex;
    High = HighIndex;
    Mid = (Low + High)/2;
 ToClassCode = 0x00000000 | PciClassCodeTable[Mid].BaseClass << 16 |
                  PciClassCodeTable[Mid].SubClass << 8 | PciClassCodeTable[Mid].ProgIf;
    if(ToClassCode == TargetClassCode)
        return Mid;
    else{
        if(TargetClassCode > ToClassCode)
            Low = Mid + 1;
        else
            High = Mid - 1;
        if(High < Low)
            return 0xffffffff; //PciClassInfo.h should be updated.
        else
   return SerachPciClassTable(Low,High,SortedArray,TargetClassCode);
    }
}

BOOLEAN __inline IsRoot(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,UINTN PciAddress){
 UINT8 CFGValue8;
 
 PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint8,PciAddress | HEADER_TYPE_OFFSET,1,&CFGValue8);
 if(CFGValue8 & PCI_BIT_0)
  return TRUE;
 else
  return FALSE;
}

BOOLEAN __inline IsPCIE(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, UINTN PciAddress){
 UINT8 CFGValue8 = 0xff;
 UINT16 Offset = CAP_POINTER;
 UINTN TempPciAddress = PciAddress | Offset;
 
 PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint8,TempPciAddress,1,&CFGValue8);
 Offset = CFGValue8;
 while(CFGValue8){
  TempPciAddress = PciAddress | Offset;
  PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint8,TempPciAddress,1,&CFGValue8);
  if(CFGValue8 != PCIE_DEVICE){
   TempPciAddress += 1;
   PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint8,TempPciAddress,1,&CFGValue8);
   Offset = CFGValue8;
  }
  else
   return TRUE;
 }
 return FALSE;
}

VOID __inline PrintDeviceInfo(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,UINTN PciAddress){
 UINT16 VID,DID;
 UINT32 ClassCode,Result;
 
 PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint16,PciAddress,1,&VID);
 PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint16,PciAddress | DID_OFFSET,1,&DID);
 PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint32,PciAddress | Rev_ID_OFFSET,1,&ClassCode);
 ClassCode = ClassCode >> 8; //get class code
 
 if(IsPCIE(PciRootBridgeIo,PciAddress))
  Print(L"PCIE "); 
 if(IsRoot(PciRootBridgeIo,PciAddress))
  Print(L"Root Bridge ");
 
 Result = SerachVenTable(0,PCI_VENTABLE_LEN-1,PciVenTable,VID);
 if(Result != 0xffffffff)
  Print(L"%s (%04x) ",PciVenTable[Result].VenStr,VID);
 else
  Print(L"Unknown Vendor (%4x)",VID);
  
 Print(L"Device ID: %04x Class Code: %06x\n",DID,ClassCode); 
 Result = SerachPciClassTable(0,PCI_CLASSCODETABLE_LEN-1,PciClassCodeTable,ClassCode);
 if(Result != 0xffffffff){
  Print(L"Name: %s %s %s\n",PciClassCodeTable[Result].BaseDesc,\
  PciClassCodeTable[Result].SubDesc,PciClassCodeTable[Result].ProgDesc);
  
 }
 else{
  Print(L"Name: %s %s %s\n",PciClassCodeTable[PCI_CLASSCODETABLE_LEN-1].BaseDesc,\
  PciClassCodeTable[PCI_CLASSCODETABLE_LEN-1].SubDesc,PciClassCodeTable[PCI_CLASSCODETABLE_LEN-1].ProgDesc);
 }
}

VOID __inline ScanPCIDevices(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo){
 UINTN Bus,Fun,Dev;
 UINTN PciAddress;
 UINT16 VID;
 UINT8 CFGValue8;
 CFGValue8 = 0;
 
 for(Bus = 0; Bus <= PCI_MAX_BUS;Bus++){
  for(Dev = 0;Dev <= PCI_MAX_DEVICE;Dev++){
   for(Fun = 0;Fun <= PCI_MAX_FUNC;Fun++){
    PciAddress = CALC_EFI_PCI_ADDRESS(Bus,Dev,Fun,0);
    PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint16,PciAddress,1,&VID);
    
    if(VID == 0xFFFF)
     continue;
    
    PrintDeviceInfo(PciRootBridgeIo,PciAddress);
     
    if(Fun == 0){
     //is multi-function?
     PciRootBridgeIo->Pci.Read(PciRootBridgeIo,EfiPciWidthUint8,PciAddress| HEADER_TYPE_OFFSET,1,&CFGValue8);
     if((CFGValue8 & PCI_BIT_7) == 0)
      break; //no
    }    
   }
  }
 }
}

EFI_STATUS
EFIAPI
UefiMain (
          IN EFI_HANDLE        ImageHandle,
          IN EFI_SYSTEM_TABLE  *SystemTable
          )
{    
 EFI_STATUS        Status;
 UINTN                      HandleCount;
 EFI_HANDLE                 *HandleBuffer;
 UINTN                      i;
 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo;
 
 //A lot of M.B. not includes Shell 2.0 into the UEFI so far.
 //Thus, this App will crash when calling beLow protocol under old shell environment.
 //gEfiShellProtocol->EnablePageBreak();
 //How to solve it: compile shell 2.0 (ShellPkg) and 
 //execute the shell.efi under your old shell.
 //However, there are a lot of bug in the Shell 2.0 (ShellPkg) now.
 
 //Method 1: Using EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
 Status = gBS->LocateHandleBuffer (
    ByProtocol,
    &gEfiPciRootBridgeIoProtocolGuid,
    NULL,
    &HandleCount,
    &HandleBuffer
   );
 ASSERT_EFI_ERROR(Status);
 
 //Method 2: Using EFI_PCI_IO_PROTOCOL
 //Note: this sample only shows you how to use the method 1.
 
 Print(L"Number of PCI Root Bridge: %d\n",HandleCount);

 for (i = 0; i < HandleCount; i++) {
 
  Status = gBS->HandleProtocol (HandleBuffer[i], &gEfiPciRootBridgeIoProtocolGuid, &PciRootBridgeIo);
  ASSERT_EFI_ERROR(Status); 
  ScanPCIDevices(PciRootBridgeIo);
 }
 
    return EFI_SUCCESS;
}


PciVenInfo.h
#ifndef _PCI_VEN_INFO_H_
#define _PCI_VEN_INFO_H_

typedef struct _PCI_VENTABLE
{
 UINT16  VenId;
 UINT16  *VenStr;
}PCI_VENTABLE, *PPCI_VENTABLE;

PCI_VENTABLE PciVenTable[] =
{
 {0x001A, L"scend Communications, Inc."},
 {0x003D, L"Martin-Marietta Corporation"},
 {0x0E11, L"Compaq"},
 {0x1000, L"Symbios Logic Inc."},
 {0x1002, L"ATI"},
 {0x1003, L"ULSI Systems"},
 {0x1004, L"VLSI Technologies"},
 {0x1005, L"Avance Logics (ADL)"},
 {0x1006, L"Reply Group"},
 {0x1007, L"Netframe Systems Inc."},
 {0x1008, L"Epson"},
 {0x100A, L"Phoenix Technologies"},
 {0x100B, L"National Semiconductor"},
 {0x100C, L"Tseng Labs"},
 {0x100D, L"AST Research"},
 {0x100E, L"Weitek"},
 {0x1010, L"Video Logic Ltd"},
 {0x1011, L"DEC"},
 {0x1012, L"Micronics Computers"},
 {0x1013, L"Cirrus Logic"},
 {0x1014, L"IBM"},
 {0x1015, L"LSI Logic Corp. of Canada"},
 {0x1016, L"ICL Personal Systems"},
 {0x1017, L"SPEA Software AG"},
 {0x1018, L"Unisys"},
 {0x1019, L"EliteGroup Computer Sys"},
 {0x101A, L"NCR/AT&ampT GIS"},
 {0x101B, L"Vitesse Semiconductor"},
 {0x101C, L"Western Digital"},
 {0x101E, L"AMI"},
 {0x101F, L"Picturetel"},
 {0x1020, L"Hitachi Computer Electronics"},
 {0x1021, L"Oki Electric Industry"},
 {0x1022, L"Advanced Micro Devices"},
 {0x1023, L"Trident Microsystems"},
 {0x1024, L"Zenith Data Systems"},
 {0x1025, L"Acer"},
 {0x1028, L"Dell Computer Corporation"},
 {0x1029, L"Siemens Nixdorf"},
 {0x102A, L"LSI Logic, Headland Division"},
 {0x102B, L"Matrox"},
 {0x102C, L"Chips & Technologies"},
 {0x102D, L"Wyse Technologies"},
 {0x102E, L"Olivetti Advanced Technology"},
 {0x102F, L"Toshiba America"},
 {0x1030, L"TMC Research"},
 {0x1031, L"Miro Computer Products AG"},
 {0x1032, L"Compaq"},
 {0x1033, L"NEC Corporation"},
 {0x1034, L"Burndy Corporation"},
 {0x1035, L"Computers and Communications Research Lab"},
 {0x1036, L"Future Domain"},
 {0x1037, L"Hitachi Micro Systems"},
 {0x1038, L"AMP Incorporated"},
 {0x1039, L"Silicon Integrated System (SIS)"},
 {0x103A, L"Seiko Epson Corporation"},
 {0x103B, L"Tatung Corp. of America"},
 {0x103C, L"Hewlett-Packard"},
 {0x103E, L"Solliday"},
 {0x103F, L"Logic Modeling"},
 {0x1040, L"Kubota Pacific"},
 {0x1041, L"Computrend"},
 {0x1042, L"PC Technology"},
 {0x1043, L"Asustek"},
 {0x1044, L"Distributed Processing Technology"},
 {0x1045, L"OPTi"},
 {0x1046, L"IPC Corporation, Ltd."},
 {0x1047, L"Genoa Systems Corp."},
 {0x1048, L"Elsa GmbH"},
 {0x1049, L"Fountain Technology"},
 {0x104A, L"SGS Thomson Microelectric"},
 {0x104B, L"BusLogic"},
 {0x104C, L"Texas Instruments"},
 {0x104D, L"Sony Corporation"},
 {0x104E, L"Oak Technology"},
 {0x104F, L"Co-Time Computer Ltd."},
 {0x1050, L"Winbond"},
 {0x1051, L"Anigma Corp."},
 {0x1052, L"Young Micro Systems"},
 {0x1054, L"Hitachi, Ltd."},
 {0x1055, L"EFAR Microsystems"},
 {0x1056, L"ICL"},
 {0x1057, L"Motorola"},
 {0x1058, L"Electronics and Telecommunications Research"},
 {0x1059, L"Teknor Microsystems"},
 {0x105A, L"Promise Technology"},
 {0x105B, L"Foxconn International"},
 {0x105C, L"Wipro Infotech Ltd."},
 {0x105D, L"Number 9 Computer Company"},
 {0x105E, L"VTech Engineering Canada, Ltd."},
 {0x105F, L"Infotronic America, Inc."},
 {0x1060, L"United Microelectronics (UMC)"},
 {0x1061, L"8x8 (X Tech)"},
 {0x1062, L"Maspar Computer Copr."},
 {0x1063, L"Ocean Office Automation"},
 {0x1064, L"Alcatel Cit"},
 {0x1065, L"Texas Microsystems"},
 {0x1066, L"PicoPower Technology"},
 {0x1067, L"Mitsubishi Electronics"},
 {0x1068, L"Diversified Technology"},
 {0x1069, L"Mylex Corporation"},
 {0x106A, L"Aten Research"},
 {0x106B, L"Apple Computer"},
 {0x106C, L"Hyundai Electronics America"},
 {0x106D, L"Sequent"},
 {0x106E, L"DFI Inc."},
 {0x106F, L"City Gate Development, Ltd."},
 {0x1070, L"Daewoo Telecom Ltd."},
 {0x1071, L"Mitac"},
 {0x1072, L"GIT Co., Ltd."},
 {0x1073, L"Yamaha Corporation"},
 {0x1074, L"NexGen Microsystems"},
 {0x1075, L"Advanced Integration Research"},
 {0x1076, L"Chaintech Computer Co. Ltd."},
 {0x1077, L"Q Logic"},
 {0x1078, L"Cyrix Corporation"},
 {0x1079, L"I-Bus"},
 {0x107A, L"Networth"},
 {0x107B, L"Gateway 2000"},
 {0x107C, L"Goldstar Co. Ltd."},
 {0x107D, L"Leadtek Research"},
 {0x107E, L"Interphase Corporation"},
 {0x107F, L"Data Technology Corporation (DTC)"},
 {0x1080, L"Contaq Microsystems"},
 {0x1081, L"Supermac Technology"},
 {0x1082, L"EFA Corporation of America"},
 {0x1083, L"Forex Computer Corporation"},
 {0x1084, L"Parador"},
 {0x1085, L"Tulip Computers Int'l BV"},
 {0x1086, L"J. Bond Computer Systems"},
 {0x1087, L"Cache Computer"},
 {0x1088, L"Microcomputer Systems (M) Son"},
 {0x1089, L"Data General Corporation"},
 {0x108A, L"Bit3 Computer"},
 {0x108C, L"Elonex PLC (Oakleigh Systems, Inc.)"},
 {0x108D, L"Olicom"},
 {0x108E, L"Sun Microsystems"},
 {0x108F, L"Systemsoft Corporation"},
 {0x1090, L"Encore Computer Corporation"},
 {0x1091, L"Intergraph Corporation"},
 {0x1092, L"Diamond Computer Systems"},
 {0x1093, L"National Instruments"},
 {0x1094, L"First International Computers (FIC)"},
 {0x1095, L"CMD Technology, Inc."},
 {0x1096, L"Alacron"},
 {0x1097, L"Appian Technology"},
 {0x1098, L"Vision / Quantum Designs Ltd"},
 {0x1099, L"Samsung Electronics Co. Ltd."},
 {0x109A, L"Packard Bell"},
 {0x109B, L"Gemlight Computer Ltd."},
 {0x109C, L"Megachips Corporation"},
 {0x109D, L"Zida Technologies"},
 {0x109E, L"Brooktree Corporation"},
 {0x109F, L"Trigem Computer Inc."},
 {0x10A0, L"Meidensha Corporation"},
 {0x10A1, L"Juko Electronics Inc. Ltd."},
 {0x10A2, L"Quantum Corporation"},
 {0x10A3, L"Everex Systems Inc."},
 {0x10A4, L"Globe Manufacturing Sales"},
 {0x10A5, L"Racal Interlan"},
 {0x10A6, L"Informtech Industrial Ltd."},
 {0x10A7, L"Benchmarq Microelectronics"},
 {0x10A8, L"Sierra Semiconductor"},
 {0x10A9, L"Silicon Graphics"},
 {0x10AA, L"ACC Microelectronics"},
 {0x10AB, L"Digicom"},
 {0x10AC, L"Honeywell IASD"},
 {0x10AD, L"Symphony Labs"},
 {0x10AE, L"Cornerstone Technology"},
 {0x10AF, L"Microcomputer Systems"},
 {0x10B0, L"CardExpert Technology"},
 {0x10B1, L"Cabletron Systems, Inc."},
 {0x10B2, L"Raytheon Company"},
 {0x10B3, L"Databook Inc."},
 {0x10B4, L"STB Systems"},
 {0x10B5, L"PLX Technology"},
 {0x10B6, L"Madge Networks"},
 {0x10B7, L"3com Corporation"},
 {0x10B8, L"Standard Microsystems Corporation (SMC)"},
 {0x10B9, L"Acer Labs Inc."},
 {0x10BA, L"Mitsubishi Electronics Corp."},
 {0x10BB, L"Dapha Electronics Corporation"},
 {0x10BC, L"Advanced Logic Research Inc. (ALR)"},
 {0x10BD, L"Surecom Technology"},
 {0x10BE, L"Tseng Labs International Corp."},
 {0x10BF, L"Most Inc."},
 {0x10C0, L"Boca Research Inc."},
 {0x10C1, L"ICM Corp. Ltd."},
 {0x10C2, L"Auspex Systems Inc."},
 {0x10C3, L"Samsung Semiconductors"},
 {0x10C4, L"Award Software International Inc."},
 {0x10C5, L"Xerox Corporation"},
 {0x10C6, L"Rambus Inc."},
 {0x10C7, L"Media Vision"},
 {0x10C8, L"Neomagic Corporation"},
 {0x10C9, L"DataExpert Corporation"},
 {0x10CA, L"Fujitsu"},
 {0x10CB, L"Omron Corporation"},
 {0x10CC, L"Mentor Arc Inc."},
 {0x10CD, L"Advanced System Products"},
 {0x10CE, L"Radius Inc."},
 {0x10CF, L"Citicorp TTI"},
 {0x10D0, L"Fujitsu Limited"},
 {0x10D1, L"Future+ Systems"},
 {0x10D2, L"Molex Incorporated"},
 {0x10D3, L"Jabil Circuit Inc."},
 {0x10D4, L"Hualon Microelectronics"},
 {0x10D5, L"Autologic Inc."},
 {0x10D6, L"Cetia"},
 {0x10D7, L"BCM Advanced Research"},
 {0x10D8, L"Advanced Peripherals Labs"},
 {0x10D9, L"Macronix International Co. Ltd"},
 {0x10DA, L"Thomas-Conrad Corporation"},
 {0x10DB, L"Rohm Research"},
 {0x10DC, L"CERN/ECP/EDU"},
 {0x10DD, L"Evans & Sutherland"},
 {0x10DE, L"NVIDIA Corporation"},
 {0x10DF, L"Emulex Corporation"},
 {0x10E0, L"Integrated Micro Solutions (IMS)"},
 {0x10E1, L"TekRAM Technology Corporation Ltd."},
 {0x10E2, L"Aptix Corporation"},
 {0x10E3, L"Newbridge Microsystems"},
 {0x10E4, L"Tandem Computers"},
 {0x10E5, L"Micro Industries"},
 {0x10E6, L"Gainbery Computer Products Inc."},
 {0x10E7, L"Vadem"},
 {0x10E8, L"Applied Micro Circuits Corp."},
 {0x10E9, L"Alps Electronic Corp. Ltd."},
 {0x10EA, L"Integraphics Systems"},
 {0x10EB, L"Artist Graphics"},
 {0x10EC, L"Realtek Semiconductor"},
 {0x10ED, L"ASCII Corporation"},
 {0x10EE, L"Xilinx Corporation"},
 {0x10EF, L"Racore Computer Products"},
 {0x10F0, L"Peritek Corporation"},
 {0x10F1, L"Tyan Computer"},
 {0x10F2, L"Achme Computer Inc."},
 {0x10F3, L"Alaris Inc."},
 {0x10F4, L"S-MOS Systems"},
 {0x10F5, L"NKK Corporation"},
 {0x10F6, L"Creative Electronic Systems SA"},
 {0x10F7, L"Matsushita Electric Industrial Corp. Ltd."},
 {0x10F8, L"Altos India Ltd."},
 {0x10F9, L"PC Direct"},
 {0x10FA, L"Truevision"},
 {0x10FB, L"Thesys Ges. f?r Microelektronik mbH"},
 {0x10FC, L"I/O Data Device Inc."},
 {0x10FD, L"Soyo Technology Corp. Ltd."},
 {0x10FE, L"Fast Electronic GmbH"},
 {0x10FF, L"N-Cube"},
 {0x1100, L"Jazz Multimedia"},
 {0x1101, L"Initio Corporation"},
 {0x1102, L"Creative Labs"},
 {0x1103, L"Triones Technologies Inc."},
 {0x1104, L"Rasterops"},
 {0x1105, L"Sigma Designs, Inc."},
 {0x1106, L"VIA Technologies"},
 {0x1107, L"Stratus Computer"},
 {0x1108, L"Proteon Inc."},
 {0x1109, L"Cogent Data Technologies"},
 {0x110A, L"Siemens AG / Siemens Nixdorf AG"},
 {0x110B, L"Xenon Microsystems / Chromatic Research, Inc."},
 {0x110C, L"Mini-Max Technology Inc."},
 {0x110D, L"ZNyX Corporation"},
 {0x110E, L"CPU Technology"},
 {0x110F, L"Ross Technology"},
 {0x1110, L"Powerhouse Systems"},
 {0x1111, L"Santa Cruz Operation (SCO)"},
 {0x1112, L"Rockwell / RNS division of Meret Communications Inc."},
 {0x1113, L"Accton Technology Corporation"},
 {0x1114, L"Atmel Corporation"},
 {0x1115, L"DuPont Pixel Systems"},
 {0x1116, L"Data Translation / Media 100, Inc."},
 {0x1117, L"Datacube Inc."},
 {0x1118, L"Berg Electronics"},
 {0x1119, L"Vortex Computersysteme GmbH"},
 {0x111A, L"Efficient Networks, Inc."},
 {0x111B, L"Teledyne Electronic Systems"},
 {0x111C, L"Tricord Systems, Inc."},
 {0x111D, L"Integrated Device Technology"},
 {0x111E, L"Eldec Corporation"},
 {0x111F, L"Precision Digital Images"},
 {0x1120, L"EMC Corporation"},
 {0x1121, L"Zilog"},
 {0x1122, L"Multi-tech Systems, Inc."},
 {0x1123, L"Excellent Design, Inc."},
 {0x1124, L"Leutron Vision AG"},
 {0x1125, L"Eurocore"},
 {0x1126, L"Vigra"},
 {0x1127, L"FORE Systems"},
 {0x1128, L"???"},
 {0x1129, L"Firmworks"},
 {0x112A, L"Hermes Electronics Co."},
 {0x112B, L"Linotype - Hell AG"},
 {0x112D, L"Ravicad"},
 {0x112E, L"Infomedia MicroElectronics Inc"},
 {0x112F, L"Imaging Technology"},
 {0x1130, L"Computervision"},
 {0x1131, L"Philips Semiconductors"},
 {0x1132, L"Mitel Corp"},
 {0x1133, L"Eicon Technology Corporation"},
 {0x1134, L"Mercury Computer Systems Inc"},
 {0x1135, L"Fuji Xerox Co Ltd"},
 {0x1136, L"Momentum Data Systems"},
 {0x1137, L"Cisco Systems Inc"},
 {0x1138, L"Ziatech Corporation"},
 {0x1139, L"Dynamic Pictures Inc"},
 {0x113A, L"FWB Inc"},
 {0x113C, L"Cyclone Microsystems (PLX)"},
 {0x113D, L"Leading Edge Products Inc"},
 {0x113E, L"Sanyo Electric Co. - Computer Engineering Dept."},
 {0x113F, L"Equinox Systems"},
 {0x1140, L"Intervoice Inc"},
 {0x1141, L"Crest Microsystem Inc"},
 {0x1142, L"Alliance Semiconductor Corp"},
 {0x1143, L"Netpower, Inc."},
 {0x1144, L"Cincinnati Milacron / Vickers Inc. Electronic Systems"},
 {0x1145, L"Workbit Corp"},
 {0x1146, L"Force Computers"},
 {0x1147, L"Interface Corp."},
 {0x1148, L"Schneider & Koch Co. / Syskonnect"},
 {0x1149, L"Win System Corporation"},
 {0x114A, L"VMIC"},
 {0x114B, L"Canopus Co."},
 {0x114C, L"Annabooks"},
 {0x114D, L"IC Corporation"},
 {0x114E, L"Nikon Systems Inc"},
 {0x114F, L"Digi International / Stargate"},
 {0x1150, L"Thinking Machines Corp."},
 {0x1151, L"JAE Electronics Inc."},
 {0x1152, L"Megatek"},
 {0x1153, L"Land Win Electronic Corp."},
 {0x1154, L"Melco Inc."},
 {0x1155, L"Pine Technology Ltd."},
 {0x1156, L"Periscope Engineering"},
 {0x1157, L"Avsys Corporation"},
 {0x1158, L"Voarx R&ampD Inc."},
 {0x1159, L"MuTech"},
 {0x115A, L"Harleguin Ltd."},
 {0x115B, L"Parallax Graphics"},
 {0x115C, L"Photron, Ltd."},
 {0x115D, L"Xircom"},
 {0x115E, L"Peer Protocols Inc."},
 {0x1160, L"Megasoft Inc."},
 {0x1161, L"PFU Ltd."},
 {0x1162, L"OA Laboratory Co Ltd."},
 {0x1163, L"Creative Labs / Rendition"},
 {0x1164, L"Advanced Peripherals Tech"},
 {0x1165, L"Imagraph Corporation"},
 {0x1166, L"Pequr Technology Inc. / Relience Computer"},
 {0x1167, L"Mutoh Industries, Inc."},
 {0x1168, L"Thine Electronics Inc"},
 {0x1169, L"Centre for Development of Advanced Computing"},
 {0x116A, L"Polaris Communications"},
 {0x116B, L"Connectware Inc"},
 {0x116F, L"Workstation Technology"},
 {0x1170, L"Inventec Corporation"},
 {0x1171, L"Loughborough Sound Images"},
 {0x1172, L"Altera Corporation"},
 {0x1173, L"Adobe Systems"},
 {0x1174, L"Bridgeport Machines"},
 {0x1175, L"Mitron Computer Inc."},
 {0x1176, L"SBE"},
 {0x1177, L"Silicon Engineering"},
 {0x1178, L"Alfa Inc"},
 {0x1179, L"Toshiba America Info Systems"},
 {0x117A, L"A-Trend Technology"},
 {0x117B, L"LG Electronics Inc."},
 {0x117C, L"Atto Technology"},
 {0x117E, L"T/R Systems"},
 {0x1180, L"Ricoh Co Ltd"},
 {0x1181, L"Telmatics International"},
 {0x1183, L"Fujikura Ltd"},
 {0x1184, L"Forks Inc"},
 {0x1185, L"Dataworld"},
 {0x1186, L"D-Link System Inc"},
 {0x1187, L"Advanced Technology Laboratories"},
 {0x1188, L"Shima Seiki Manufacturing Ltd."},
 {0x1189, L"Matsushita Electronics"},
 {0x118A, L"Hilevel Technology"},
 {0x118C, L"Corollary Inc."},
 {0x118D, L"BitFlow Inc. L"},
 {0x118E, L"Hermstedt GmbH"},
 {0x1191, L"Artop Electric / Acard Technology Corp. L"},
 {0x1192, L"Densan Co. Ltd"},
 {0x1193, L"Zeitnet Inc."},
 {0x1194, L"Toucan Technology"},
 {0x1195, L"Ratoc System Inc."},
 {0x1196, L"Hytec Electronics Ltd"},
 {0x1197, L"Gage Applied Sciences Inc."},
 {0x1198, L"Lambda Systems Inc."},
 {0x1199, L"Digital Communications Associates Inc,"},
 {0x119A, L"Mind Share Inc."},
 {0x119B, L"Omega Micro Inc."},
 {0x119C, L"Information Technology Inst."},
 {0x119D, L"Bug Sapporo Japan"},
 {0x119E, L"Fujitsu"},
 {0x119F, L"Bull Hn Information Systems"},
 {0x11A0, L"Convex Computer Corporation"},
 {0x11A1, L"Hamamatsu Photonics K.K."},
 {0x11A2, L"Sierra Research and Technology"},
 {0x11A3, L"Deuretzbacher GmbH & Co. Eng. KG"},
 {0x11A4, L"Barco"},
 {0x11A5, L"MicroUnity Systems Engineering, Inc."},
 {0x11A6, L"Pure Data"},
 {0x11A7, L"Power Computing Corp."},
 {0x11A9, L"InnoSys Inc."},
 {0x11AA, L"Actel"},
 {0x11AB, L"Galileo Technology Ltd."},
 {0x11AC, L"Canon Information Systems"},
 {0x11AD, L"Lite-On Communications Inc."},
 {0x11AE, L"Scitex Corporation Ltd."},
 {0x11AF, L"Pro-Log Corporation / Avid Technology Corp."},
 {0x11B0, L"V3 Semiconductor Inc."},
 {0x11B1, L"Apricot Computers"},
 {0x11B2, L"Eastman Kodak"},
 {0x11B3, L"Barr Systems Inc."},
 {0x11B4, L"Leitch Technology International"},
 {0x11B5, L"Radstone Technology Plc"},
 {0x11B6, L"United Video Corp"},
 {0x11B7, L"Motorola"},
 {0x11B8, L"Xpoint Technologies Inc."},
 {0x11B9, L"Pathlight Technology Inc."},
 {0x11BA, L"Videotron Corp"},
 {0x11BB, L"Pyramid Technology"},
 {0x11BC, L"Network Peripherals Inc."},
 {0x11BD, L"Pinnacle Systems Inc."},
 {0x11BE, L"International Microcircuits Inc."},
 {0x11BF, L"Astrodesign, Inc."},
 {0x11C3, L"NEC Corporation"},
 {0x11C4, L"Document Technologies Ind."},
 {0x11C5, L"Shiva Corporatin"},
 {0x11C6, L"Dainippon Screen Mfg. Co., Ltd."},
 {0x11C7, L"D.C.M. Data Systems"},
 {0x11C8, L"Dolphin Interconnect Solutions"},
 {0x11C9, L"MAGMA"},
 {0x11CA, L"LSI Systems Inc."},
 {0x11CB, L"Specialix International, Ltd."},
 {0x11CC, L"Michels & Kleberhoff Computer GmbH"},
 {0x11CD, L"HAL Computer Systems Inc."},
 {0x11CE, L"Netaccess"},
 {0x11D0, L"Lockheed Martin Federal Systems-Manassas"},
 {0x11D2, L"Intercom, Inc."},
 {0x11D4, L"Analog Devices"},
 {0x11D5, L"Ikon Corp."},
 {0x11D9, L"TEC Corp."},
 {0x11DA, L"Novell"},
 {0x11DB, L"Sega Enterprises, Ltd."},
 {0x11DE, L"Zoran Corporation"},
 {0x11DF, L"New Wave PDG"},
 {0x11E1, L"GEC Plessey Semi Inc."},
 {0x11E2, L"Samsung Information Systems Americ"},
 {0x11E3, L"Quicklogic Corporation"},
 {0x11E4, L"Second Wave Inc."},
 {0x11E5, L"IIX Consulting"},
 {0x11E6, L"Mitsui-Zosen System Research"},
 {0x11E8, L"Digital Processing Systems Inc."},
 {0x11EA, L"Elsag Bailey"},
 {0x11EB, L"Formation Inc."},
 {0x11EC, L"Coreco Inc."},
 {0x11ED, L"Mediamatics"},
 {0x11EE, L"Dome Imaging Systems Inc."},
 {0x11EF, L"Nicolet Technologies B.V."},
 {0x11F0, L"Compu-Shack GmbH"},
 {0x11F1, L"Symbios Logic Inc."},
 {0x11F2, L"Picture Tel Japan K.K."},
 {0x11F3, L"Keithley Metrabyte"},
 {0x11F4, L"Kinetic Systems Corporation"},
 {0x11F5, L"Computing Devices International"},
 {0x11F6, L"Powermatic Data Systems Ltd."},
 {0x11F6, L"Compex USA, Inc."},
 {0x11F7, L"Scientific Atlanta"},
 {0x11F8, L"PMC-Sierra Inc."},
 {0x11F9, L"I-Cube, Inc."},
 {0x1201, L"Vista Controls Corp."},
 {0x1203, L"Bayer Corp., AGFA division"},
 {0x1204, L"Lattice Semiconductor Corp."},
 {0x1205, L"Array Corp."},
 {0x1206, L"Amdahl Corp."},
 {0x120E, L"Cyclades"},
 {0x1216, L"PURUP Eskofot A/S"},
 {0x1217, L"O2Micro, Inc."},
 {0x121A, L"3DFX Interactive, Inc."},
 {0x121B, L"Advanced Telecomm Modules"},
 {0x1220, L"Ariel Corporation"},
 {0x1221, L"Contec Co., Ltd."},
 {0x1222, L"Ancor Communications, Inc."},
 {0x1223, L"Heurikon/Computer Products"},
 {0x1224, L"Interactive Images"},
 {0x1225, L"Power I/O, Inc."},
 {0x1227, L"Tech-Source"},
 {0x1228, L"Norsk Elektro Optikk A/S"},
 {0x1229, L"Data Kinesis Inc."},
 {0x122A, L"Integrated Telecom"},
 {0x122B, L"LG Industrial Systems Co. Ltd."},
 {0x122C, L"Sican GmbH"},
 {0x122D, L"Aztech Systems Ltd"},
 {0x122E, L"Xyratex"},
 {0x122F, L"Andrew Corporation"},
 {0x1230, L"Fishcamp Engineering"},
 {0x1231, L"Woodward McCoach, Inc."},
 {0x1232, L"GPT Limited"},
 {0x1233, L"Bus-Tech, Inc."},
 {0x1234, L"Technical Corp."},
 {0x1235, L"Risq Modular Systems, Inc. / Smart Modular Technologies, Inc."},
 {0x1236, L"Sigma Designs Corporation"},
 {0x1237, L"Alta Technology Corporation"},
 {0x1238, L"Adtran"},
 {0x1239, L"The 3DO Company"},
 {0x123A, L"Visicom Laboratories, Inc."},
 {0x123B, L"Seeq Technology, Inc."},
 {0x123C, L"Century Systems, Inc."},
 {0x123D, L"Engineering Design Team, Inc."},
 {0x123E, L"Sumutech, Inc."},
 {0x123F, L"C-Cube Microsystems"},
 {0x1240, L"Marathon Technologies Corp."},
 {0x1241, L"DSC Communications"},
 {0x1243, L"Delphax"},
 {0x1244, L"AVM Audiovisuelles Mktg & Computer GmbH"},
 {0x1245, L"A.P.D., S.A."},
 {0x1246, L"Dipix Technologies, Inc."},
 {0x1247, L"Xylon Research, Inc."},
 {0x1248, L"Central Data Corporation"},
 {0x1249, L"Samsung Electronics Co., Ltd."},
 {0x124A, L"AEG Electrocom GmbH"},
 {0x124B, L"SBS/Greenspring Modular I/O"},
 {0x124C, L"Solitron Technologies, Inc."},
 {0x124D, L"Stallion Technologies"},
 {0x124E, L"Cylink"},
 {0x124F, L"Infortrend Technology, Inc."},
 {0x1250, L"Hitachi Microcomputer System, Ltd."},
 {0x1251, L"VLSI Solution Oy"},
 {0x1253, L"Guzik Technical Enterprises"},
 {0x1254, L"Linear Systems Ltd."},
 {0x1255, L"Optibase Ltd."},
 {0x1256, L"Perceptive Solutions, Inc."},
 {0x1257, L"Vertex Networks, Inc."},
 {0x1258, L"Gilbarco, Inc."},
 {0x1259, L"Allied telesyn International"},
 {0x125A, L"ABB Power Systems"},
 {0x125B, L"Asix Electronics Corporation"},
 {0x125C, L"Aurora Technologies, Inc."},
 {0x125D, L"ESS Technology"},
 {0x125E, L"SpecialVideo Engineering SRL"},
 {0x125F, L"Concurrent Technologies, Inc."},
 {0x1260, L"Harris Semiconductor"},
 {0x1261, L"Matsushita-Kotobuki Electronics Industries"},
 {0x1262, L"ES Computer Company, Ltd."},
 {0x1263, L"Sonic Solutions"},
 {0x1264, L"Aval Nagasaki Corporation"},
 {0x1265, L"Casio Computer Co., Ltd."},
 {0x1266, L"Microdyne Corporation"},
 {0x1267, L"S.A. Telecommunications"},
 {0x1268, L"Tektronix"},
 {0x1269, L"Thomson-CSF/TTM"},
 {0x126A, L"Lexmark International, Inc."},
 {0x126B, L"Adax, Inc."},
 {0x126C, L"Northern Telecom"},
 {0x126D, L"Splash Technology, Inc."},
 {0x126E, L"Sumitomo Metal Industries, Ltd."},
 {0x126F, L"Silicon Motion, Inc."},
 {0x1270, L"Olympus Optical Co., Ltd."},
 {0x1271, L"GW Instruments"},
 {0x1272, L"Telematics International"},
 {0x1273, L"Hughes Network Systems"},
 {0x1274, L"Ensoniq"},
 {0x1275, L"Network Appliance Corporation"},
 {0x1276, L"Switched Network Tecnologies, Inc."},
 {0x1277, L"Comstream"},
 {0x1278, L"Transtech Parallel Systems Ltd."},
 {0x1279, L"Transmeta Corporation"},
 {0x127A, L"Rockwell Semiconductor Systems"},
 {0x127B, L"Pixera Corporation"},
 {0x127C, L"Crosspoint Solutions, Inc."},
 {0x127D, L"Vela Research"},
 {0x127E, L"Winnov, L.P."},
 {0x127F, L"Fujifilm"},
 {0x1280, L"Photoscript Group Ltd."},
 {0x1281, L"Yokogawa Electric Corporation"},
 {0x1282, L"Davicom Semiconductor, Inc."},
 {0x1283, L"Integrated Technology Express, Inc."},
 {0x1284, L"Sahara Networks, Inc."},
 {0x1285, L"Platform Technologies, Inc."},
 {0x1286, L"Mazet GmbH"},
 {0x1287, L"M-Pact, Inc. / Luxsonor, Inc."},
 {0x1288, L"Timestep Corporation"},
 {0x1289, L"AVC Technology, Inc."},
 {0x128A, L"Asante Technologies, Inc."},
 {0x128B, L"Transwitch Corporation"},
 {0x128C, L"Retix Corporation / Sonoma Systems, Inc."},
 {0x128D, L"G2 Networks, Inc."},
 {0x128C, L"Retix Corp"},
 {0x128D, L"???"},
 {0x128E, L"Samho Multi Tech Ltd. / Hoon Tech Co., Ltd."},
 {0x128F, L"Tateno Dennou, Inc."},
 {0x1290, L"Sord Computer Corporation"},
 {0x1291, L"NCS Computer Italia"},
 {0x1292, L"Tritech Microelectronics, Inc."},
 {0x1293, L"Media Reality Technology"},
 {0x1294, L"Rhetorex, Inc."},
 {0x1295, L"Imagenation Corporation"},
 {0x1296, L"Kofax Image Products"},
 {0x1297, L"Holco Ent Co, Ltd / Shuttle Computer"},
 {0x1298, L"Spellcaster Telecommunications Inc."},
 {0x1299, L"Knowledge Technology Lab."},
 {0x129A, L"VMetro, Inc."},
 {0x129B, L"Image Access"},
 {0x129C, L"Jaycor / Xantel Corporation"},
 {0x129D, L"Compcore Multimedia, Inc."},
 {0x129E, L"Victor Company of Japan, Ltd."},
 {0x129F, L"OEC Medical Systems, Inc."},
 {0x12A0, L"Allen-Bradley Company"},
 {0x12A1, L"Simpact Associates, Inc."},
 {0x12A2, L"Newgen Systems Corporation"},
 {0x12A3, L"Lucent Technologies"},
 {0x12A4, L"NTT Electronics Technology Company"},
 {0x12A5, L"Vision Dynamics Ltd."},
 {0x12A6, L"Scalable Networks, Inc."},
 {0x12A7, L"AMO GmbH"},
 {0x12A8, L"News Datacom"},
 {0x12A9, L"Xiotech Corporation"},
 {0x12AA, L"SDL Communications, Inc."},
 {0x12AB, L"Yuan Yuan Enterprise Co., Ltd."},
 {0x12AC, L"MeasureX Corporation"},
 {0x12AD, L"Multidata GmbH"},
 {0x12AE, L"Alteon Networks, inc."},
 {0x12AF, L"TDK USA Corporation"},
 {0x12B0, L"Jorge Scientific Corporation"},
 {0x12B1, L"GammaLink"},
 {0x12B2, L"General Signal Networks"},
 {0x12B3, L"Inter-Face Co. Ltd."},
 {0x12B4, L"FutureTel Inc."},
 {0x12B5, L"Granite Systems Inc."},
 {0x12B6, L"Natural Microsystems"},
 {0x12B7, L"Acumen"},
 {0x12B8, L"Korg"},
 {0x12B9, L"US Robotics / 3com Corporation"},
 {0x12BA, L"PMC Sierra"},
 {0x12BB, L"Nippon Unisoft Corporation"},
 {0x12BC, L"Array Microsystems"},
 {0x12BD, L"Computerm Corp."},
 {0x12BE, L"Anchor Chips"},
 {0x12BF, L"Fujifilm Microdevices"},
 {0x12C0, L"InfiMed"},
 {0x12C1, L"GMM Research Corp."},
 {0x12C2, L"Mentec Limited"},
 {0x12C3, L"Holtek Microelectronics Inc."},
 {0x12C4, L"Connect Tech Inc."},
 {0x12C5, L"Picture Elements, Inc."},
 {0x12C6, L"Mitani Corporation"},
 {0x12C7, L"Dialogic Corporation"},
 {0x12C8, L"G Force Co, Ltd."},
 {0x12C9, L"Gigi Operations"},
 {0x12CA, L"Integrated Computing Engines"},
 {0x12CB, L"Antex Electronics Corporation"},
 {0x12CC, L"Pluto Technologies International"},
 {0x12CD, L"Aims Lab"},
 {0x12CE, L"Netspeed, Inc."},
 {0x12CF, L"Prophet Systems, Inc."},
 {0x12D0, L"GDE Systems, Inc."},
 {0x12D1, L"Psitech"},
 {0x12D2, L"NVIDIA / SGS Thomson"},
 {0x12D3, L"Vingmed Sound A/S"},
 {0x12D4, L"DGM&ampS"},
 {0x12D5, L"Equator Technologies"},
 {0x12D6, L"Analogic Corporation"},
 {0x12D7, L"Biotronic SRL"},
 {0x12D8, L"Pericom Semiconductor"},
 {0x12D9, L"Aculab PLC"},
 {0x12DA, L"True Time"},
 {0x12DB, L"Annapolis Micro Systems, Inc."},
 {0x12DC, L"Symicron Computer Communication Ltd."},
 {0x12DD, L"Management Graphics"},
 {0x12DE, L"Rainbow Technologies"},
 {0x12DF, L"SBS Technologies Inc."},
 {0x12E0, L"Chase Research"},
 {0x12E1, L"Nintendo Co, Ltd."},
 {0x12E2, L"Datum Inc, Bancomm-Timing Division"},
 {0x12E3, L"Imation Corp - Medical Imaging Systems"},
 {0x12E4, L"Brooktrout Technology Inc."},
 {0x12E5, L"Apex Inc / XCD Inc."},
 {0x12E6, L"Cirel Systems"},
 {0x12E7, L"Sunsgroup Corporation / Sebring Systems"},
 {0x12E8, L"CRISC Corporation"},
 {0x12E9, L"GE Spacenet"},
 {0x12EA, L"Zuken / Real Vision, Inc."},
 {0x12EB, L"Aureal Semiconductor"},
 {0x12EC, L"3A International, Inc."},
 {0x12ED, L"Optivision Inc."},
 {0x12EE, L"Orange Micro"},
 {0x12EF, L"Vienna Systems"},
 {0x12F0, L"Pentek"},
 {0x12F1, L"Sorenson Vision Inc."},
 {0x12F2, L"GammaGraphx, Inc."},
 {0x12F3, L"XING, Inc."},
 {0x12F4, L"Megatel"},
 {0x12F5, L"Forks"},
 {0x12F6, L"Dawson France"},
 {0x12F7, L"Cognex"},
 {0x12F8, L"Electronic-Design GmbH"},
 {0x12F9, L"FourFold Technologies"},
 {0x12FB, L"Spectrum Signal Processing"},
 {0x12FC, L"Capital Equipment Corp."},
 {0x12FD, L"i2S"},
 {0x12FE, L"ESD Electronic System Design GmbH"},
 {0x12FF, L"Lexicon"},
 {0x1300, L"Harman International Industries, Inc."},
 {0x1302, L"Computer Sciences Corp."},
 {0x1303, L"Innovative Integration"},
 {0x1304, L"Juniper Networks"},
 {0x1305, L"NetPhone, Inc."},
 {0x1306, L"Duet Technologies"},
 {0x1307, L"Computer Boards"},
 {0x1308, L"Jato Technologies, Inc."},
 {0x1309, L"AB Semicon, Ltd."},
 {0x130A, L"Mitsubishi Electric MicroComputer"},
 {0x130B, L"Colorgraphic Communications Corp."},
 {0x130C, L"AMBEX Technologies, Inc."},
 {0x130D, L"Accelerix, Inc."},
 {0x130E, L"Yamatake-Honeywell Co., Ltd."},
 {0x130F, L"Advanet, Inc."},
 {0x1310, L"GESPAC"},
 {0x1311, L"VideoServer, Inc."},
 {0x1312, L"Acuity Imaging, Inc."},
 {0x1313, L"Yaskawa Electric Co."},
 {0x1316, L"Teradyne, Inc."},
 {0x1317, L"Bridgecom, Inc."},
 {0x1318, L"Packet Engines, Inc."},
 {0x1319, L"ForteMedia, Inc."},
 {0x131A, L"Finisar Corp."},
 {0x131C, L"Nippon Electro-Sensory Devices Corp."},
 {0x131D, L"Sysmic, Inc."},
 {0x131E, L"Xinex Networks, Inc."},
 {0x131F, L"SIIG, Inc."},
 {0x1320, L"Crypto AG"},
 {0x1321, L"Arcobel Graphics BV"},
 {0x1322, L"MTT Co., Ltd."},
 {0x1323, L"DOME, Inc."},
 {0x1324, L"Sphere Communications"},
 {0x1325, L"Salix Technologies, Inc."},
 {0x1326, L"SeaChange International"},
 {0x1327, L"Voss Scientific"},
 {0x1328, L"Quadrant International"},
 {0x1329, L"Productivity Enhancement"},
 {0x132A, L"Microcom, Inc."},
 {0x132B, L"BroadBand Technologies"},
 {0x132C, L"Micrel, Inc."},
 {0x132D, L"Integrated Silicon Solution, Inc."},
 {0x1330, L"MMC Networks"},
 {0x1331, L"RadiSys Corporation"},
 {0x1332, L"Micro Memory"},
 {0x1333, L"???"},
 {0x1334, L"Redcreek Communications, Inc."},
 {0x1335, L"Videomail, Inc."},
 {0x1336, L"???"},
 {0x1337, L"Third Planet Publishing"},
 {0x1338, L"BT Electronics"},
 {0x133A, L"VTEL Corp."},
 {0x133B, L"Softcom Microsystems"},
 {0x133C, L"Holontech Corp."},
 {0x133D, L"S S Technologies"},
 {0x133E, L"Virtual Computer Corp."},
 {0x133F, L"SCM Microsystems"},
 {0x1340, L"Atalla Corp."},
 {0x1341, L"Kyoto Microcomputer Co."},
 {0x1342, L"Promax Systems Inc."},
 {0x1343, L"Phylon Communications, Inc."},
 {0x1344, L"Crucial Technology"},
 {0x1345, L"Arescom, Inc."},
 {0x1346, L"???"},
 {0x1347, L"Odetics"},
 {0x1348, L"???"},
 {0x1349, L"Sumitomo Electric Industries, Ltd."},
 {0x134A, L"DTC Technology Corp."},
 {0x134B, L"Ark Research Corp."},
 {0x134C, L"Chori Joho System Co., Ltd."},
 {0x134D, L"Pctel, Inc."},
 {0x134E, L"CSTI"},
 {0x134F, L"Algo System Co., Ltd."},
 {0x1350, L"Systec Co., Ltd."},
 {0x1351, L"Sonix, Inc."},
 {0x1353, L"Dassault A.T."},
 {0x1354, L"dWave System, Inc."},
 {0x1355, L"Kratos Analytical, Ltd."},
 {0x1356, L"The Logical Co."},
 {0x1359, L"Prisa Networks"},
 {0x135A, L"Brain Boxes"},
 {0x135B, L"Giganet, Inc."},
 {0x135C, L"Quatech, Inc."},
 {0x135D, L"ABB Network Partner AB"},
 {0x135E, L"Sealevel Systems, Inc."},
 {0x135F, L"I-Data International A-S"},
 {0x1360, L"Meinberg Funkuhren"},
 {0x1361, L"Soliton Systems K.K."},
 {0x1362, L"Fujifacom Corp."},
 {0x1363, L"Phoenix Technology, Ltd."},
 {0x1364, L"ATM Communications, Inc."},
 {0x1365, L"Hypercope Corp."},
 {0x1366, L"Teijin Seiki Co., Ltd."},
 {0x1367, L"Hitachi Zosen Corp."},
 {0x1368, L"Skyware Corp."},
 {0x1369, L"Digigram"},
 {0x136A, L"High Soft Tech"},
 {0x136B, L"Kawasaki Steel Corp."},
 {0x136C, L"Adtek System Science Co., Ltd."},
 {0x136D, L"Gigalabs, Ltd."},
 {0x136F, L"Applied Magic, Inc."},
 {0x1370, L"ATL Products"},
 {0x1371, L"CNET Technology, Inc."},
 {0x1373, L"Silicon Vision, Inc."},
 {0x1374, L"Silicom, Ltd."},
 {0x1375, L"Argosystems, Inc."},
 {0x1376, L"LMC"},
 {0x1377, L"Electronic Equipment Production"},
 {0x1378, L"Telemann Co., Ltd."},
 {0x1379, L"Asahi Kasei Microsystems Co., Ltd."},
 {0x137A, L"Mark Of The Unicorn, Inc."},
 {0x137B, L"PPT Vision"},
 {0x137C, L"Iwatsu Electric Co., Ltd."},
 {0x137D, L"Dynachip Corp."},
 {0x137E, L"Patriot Scientific Corp."},
 {0x137F, L"Japan Satellite Systems, Inc."},
 {0x1380, L"Sanritz Automation Co., Ltd."},
 {0x1381, L"Brains Co., Ltd."},
 {0x1382, L"Marian - Electronic & Software"},
 {0x1383, L"Controlnet, Inc."},
 {0x1384, L"Reality Simulation Systems, Inc."},
 {0x1385, L"Netgear"},
 {0x1386, L"Video Domain Technologies"},
 {0x1387, L"Systran Corp."},
 {0x1388, L"Hitachi Information Technology Co., Ltd."},
 {0x1389, L"Applicom International"},
 {0x138A, L"Fusion Micromedia Corp."},
 {0x138B, L"Tokimec, Inc."},
 {0x138C, L"Silicon Reality"},
 {0x138D, L"Future Techno Designs Pte., Ltd."},
 {0x138E, L"Basler GmbH"},
 {0x138F, L"Patapsco Designs, Inc."},
 {0x1390, L"Concept Development, Inc."},
 {0x1391, L"Development Concepts, Inc."},
 {0x1392, L"Medialight, Inc."},
 {0x1394, L"Level One Communications"},
 {0x1395, L"Ambicom, Inc."},
 {0x1396, L"Cipher Systems, Inc."},
 {0x1397, L"Cologne Chip Designs GmbH"},
 {0x1398, L"Clarion Co., Ltd."},
 {0x1399, L"Rios Systems Co., Ltd."},
 {0x139A, L"Alacritech, Inc."},
 {0x139B, L"Mediasonic Multimedia Systems, Ltd."},
 {0x139C, L"Quantum 3D, Inc."},
 {0x139D, L"EPL, Ltd."},
 {0x139E, L"Media4"},
 {0x139F, L"Aethra S.R.L."},
 {0x13A0, L"Crystal Group, Inc."},
 {0x13A1, L"Kawasaki Heavy Industries, Ltd."},
 {0x13A2, L"Ositech Communications, Inc."},
 {0x13A3, L"HI-FN"},
 {0x13A4, L"Rascom, Inc."},
 {0x13A5, L"Audio Digital Imaging, Inc."},
 {0x13A6, L"Videonics, Inc."},
 {0x13A7, L"Teles AG"},
 {0x13A8, L"Exar Corp."},
 {0x13A9, L"Ultrasound Group"},
 {0x13AA, L"Broadband Networks, Inc."},
 {0x13AB, L"Arcom Control Systems, Ltd."},
 {0x13AC, L"Motion Media Technology, Ltd."},
 {0x13AD, L"Nexus, Inc."},
 {0x13AE, L"ALD Technology, Ltd."},
 {0x13AF, L"T.Sqware"},
 {0x13B0, L"Maxspeed Corp."},
 {0x13B1, L"Tamura Corp."},
 {0x13B2, L"Techno Chips Co., Ltd."},
 {0x13B3, L"Lanart Corp."},
 {0x13B4, L"Wellbean Co, Inc."},
 {0x13B5, L"ARM"},
 {0x13B6, L"DLoG GmbH"},
 {0x13B7, L"LOGIC Devices, Inc."},
 {0x13B8, L"Nokia Telecommunications Oy"},
 {0x13B9, L"Elecom Co., Ltd."},
 {0x13BA, L"Oxford Instruments"},
 {0x13BB, L"Sanyo Technosound Co., Ltd."},
 {0x13BC, L"Bitran Corp."},
 {0x13BD, L"Sharp Corp."},
 {0x13BE, L"Miroku Jyoho Service Co., Ltd."},
 {0x13BF, L"Sharewave., Inc."},
 {0x13C0, L"Microgate Corp."},
 {0x13C1, L"3ware Inc."},
 {0x13C2, L"Technotrend Systemtechnik GmbH"},
 {0x13C3, L"Janz Computer AG"},
 {0x13C4, L"Phase Metrics"},
 {0x13C5, L"Alphi Technology Corp."},
 {0x13C6, L"Condor Engineering, Inc."},
 {0x13C7, L"Blue Chip Technology, Ltd."},
 {0x13C8, L"Apptech, Inc."},
 {0x13C9, L"Eaton Corp."},
 {0x13CA, L"IOMEGA Corp."},
 {0x13CB, L"Yano Electric Co., Ltd."},
 {0x13CC, L"Metheus Corp."},
 {0x13CD, L"Compatible Systems Corp."},
 {0x13CE, L"Cocom A/S"},
 {0x13CF, L"Studio Audio & Video, Ltd."},
 {0x13D0, L"Techsan Electronics Co., Ltd."},
 {0x13D1, L"Abocom Systems, Inc."},
 {0x13D2, L"Shark Multimedia, Inc."},
 {0x13D3, L"IMC Networks"},
 {0x13D4, L"Graphics Microsystems, Inc."},
 {0x13D5, L"Media 100, Inc."},
 {0x13D6, L"K.I. Technology Co., Inc."},
 {0x13D7, L"Toshiba Engineering Corp."},
 {0x13D8, L"Phobos Corp."},
 {0x13D9, L"Apex PC Solutions, Inc."},
 {0x13DA, L"Intresource Systems Pte., Ltd."},
 {0x13DB, L"Janich & Klass Computertechnik GmbH"},
 {0x13DC, L"Netboost Corp."},
 {0x13DD, L"Multimedia Bundle, Inc."},
 {0x13DE, L"ABB Robotics Products AB"},
 {0x13DF, L"E-Tech, Inc."},
 {0x13E0, L"GVC Corp."},
 {0x13E1, L"Silicom Multimedia Systems, Inc."},
 {0x13E2, L"Dynamics Research Corp."},
 {0x13E3, L"Nest, Inc."},
 {0x13E4, L"Calculex, Inc."},
 {0x13E5, L"Telesoft Design, Ltd."},
 {0x13E6, L"Argosy Research, Inc."},
 {0x13E7, L"NAC, Inc."},
 {0x13E8, L"Chip Express Corp."},
 {0x13E9, L"Intraserver Technology, Inc."},
 {0x13EA, L"Dallas Semiconductor"},
 {0x13EB, L"Hauppauge Computer Works, Inc."},
 {0x13EC, L"Zydacron, Inc."},
 {0x13ED, L"Raytheion E-Systems"},
 {0x13EE, L"Hayes Microcomputer Products, Inc."},
 {0x13F0, L"Sundance Technology, Inc."},
 {0x13F1, L"Oce' - Technologies B.V."},
 {0x13F2, L"Ford Microelectronics, Inc."},
 {0x13F3, L"McData Corp."},
 {0x13F4, L"Troika Design, Inc."},
 {0x13F5, L"Kansai Electric Co., Ltd."},
 {0x13F6, L"C-Media Electronics, Inc."},
 {0x13F7, L"Wildfire Communications"},
 {0x13F8, L"Ad Lib Multimedia, Inc."},
 {0x13F9, L"NTT Advanced Technology Corp."},
 {0x13FA, L"Pentland Systems, Ltd."},
 {0x13FB, L"Aydin Corp."},
 {0x13FC, L"Computer Peripherals International"},
 {0x13FD, L"Micro Science, Inc."},
 {0x13FE, L"Advantech Co., Ltd."},
 {0x13FF, L"Silicon Spice, Inc."},
 {0x1400, L"ARTX, Inc."},
 {0x1401, L"CR-Systems A/S"},
 {0x1402, L"Meilhaus Electronic GmbH"},
 {0x1403, L"Ascor, Inc."},
 {0x1404, L"Fundamental Software, Inc."},
 {0x1405, L"Excalibur Systems, Inc."},
 {0x1406, L"Oce' Printing Systems GmbH"},
 {0x1407, L"Lava Computer Mfg., Inc."},
 {0x1408, L"Aloka Co., Ltd."},
 {0x1409, L"Timedia Technology Co., Ltd."},
 {0x140A, L"DSP Research, Inc."},
 {0x140B, L"Ramix, Inc."},
 {0x140C, L"Elmic Systems, Inc."},
 {0x140D, L"Matsushita Electrics Works, Ltd."},
 {0x140E, L"Goepel Electronic GmbH"},
 {0x140F, L"Salient Systems Corp."},
 {0x1410, L"Midas Lab, Inc."},
 {0x1411, L"Ikos Systems, Inc."},
 {0x1412, L"IC Ensemble, Inc."},
 {0x1413, L"Addonics"},
 {0x1414, L"Microsoft"},
 {0x1415, L"Oxford Semiconductor, Ltd."},
 {0x1416, L"Multiwave Innovation Pte, Ltd."},
 {0x1417, L"Convergenet Technologies, Inc."},
 {0x1418, L"Kyushu Electronics Systems, Inc."},
 {0x1419, L"Excel Switching Corp."},
 {0x141A, L"Apache Micro Peripherals, Inc."},
 {0x141B, L"Zoom Telephonics, Inc."},
 {0x141D, L"Digitan Systems, Inc."},
 {0x141E, L"Fanuc, Ltd."},
 {0x141F, L"Visiontech, Ltd."},
 {0x1420, L"Psion Dacom PLC"},
 {0x1421, L"ADS Technologies, Inc."},
 {0x1422, L"Ygrec Systems Co., Ltd."},
 {0x1423, L"Custom Technology Corp."},
 {0x1424, L"Vidoeserver Connections"},
 {0x1425, L"ASIC Designers, Inc."},
 {0x1426, L"Storage Technology Corp."},
 {0x1427, L"Better On-line Solutions"},
 {0x1428, L"EDEC Co., Ltd."},
 {0x1429, L"UNEX Technology Corp."},
 {0x142A, L"Kingmax Technology, Inc."},
 {0x142B, L"RadioLAN"},
 {0x142C, L"Minton Optic Industry Co., Ltd."},
 {0x142D, L"Pix Stream, Inc."},
 {0x142E, L"Vitec Multimedia"},
 {0x142F, L"Radicom Research, Inc."},
 {0x1430, L"ITT Aerospace/Communications Division"},
 {0x1431, L"Gilat Satellite Networks"},
 {0x1432, L"Edimax Computer Co."},
 {0x1433, L"Eltec Elektronik GmbH"},
 {0x1435, L"Real Time Devices US, Inc."},
 {0x1436, L"CIS Technology, Inc."},
 {0x1437, L"Nissin Co Inc"},
 {0x1438, L"Atmel-Dream"},
 {0x1439, L"Outsource Engineering & Mfg. Inc"},
 {0x143A, L"Stargate Solutions Inc"},
 {0x143B, L"Canon Research Center, America"},
 {0x143C, L"Amlogic Inc"},
 {0x143D, L"Tamarack Microelectronics Inc"},
 {0x143F, L"Lightwell Co Ltd - Zax Division"},
 {0x1440, L"Algol Corp"},
 {0x1441, L"AGIE LTD"},
 {0x1442, L"Phoenix Contact Co GmbH"},
 {0x1443, L"Unibrain S.A."},
 {0x1444, L"TRW"},
 {0x1445, L"Logical do Ltd"},
 {0x1447, L"AIM GmbH"},
 {0x1448, L"Alesis Studio"},
 {0x1449, L"TUT Systems Inc"},
 {0x144A, L"Adlink Technology"},
 {0x144B, L"Loronix Information Systems Inc"},
 {0x144C, L"Catalina Research Inc"},
 {0x144E, L"Olitec"},
 {0x144F, L"Askey Computer Corp"},
 {0x1450, L"Nexus Systems Inc"},
 {0x1451, L"SP3D Chip Design GmbH"},
 {0x1453, L"Mycom Inc"},
 {0x1454, L"Altiga Networks"},
 {0x1455, L"Logic Plus Plus Inc"},
 {0x1456, L"Advanced Hardware"},
 {0x1457, L"Nuera Communications Inc"},
 {0x1458, L"Giga-Byte Technology"},
 {0x1459, L"Dooin Electronics"},
 {0x145A, L"Escalate Networks Inc"},
 {0x145B, L"Praim SRL"},
 {0x145C, L"Cryptek"},
 {0x145D, L"Gallant Computer Inc"},
 {0x145E, L"Aashima Technology B.V."},
 {0x145F, L"Baldor Electric Company"},
 {0x1460, L"Dynarc Inc"},
 {0x1461, L"Avermedia Technologies Inc"},
 {0x1462, L"Micro-Star International Co Ltd"},
 {0x1463, L"Fast Corp"},
 {0x1464, L"Interactive Circuits & Systems Ltd"},
 {0x1465, L"GN Nettest Telecom Div."},
 {0x1466, L"Designpro Inc"},
 {0x1467, L"Digicom SPA"},
 {0x1468, L"Ambit microsystem Corp"},
 {0x1469, L"Cleveland Motion Controls"},
 {0x146A, L"IFR Ltd"},
 {0x146B, L"Parascan Technologies Ltd"},
 {0x146C, L"Ruby Tech Corp"},
 {0x146D, L"Tachyon Inc"},
 {0x146E, L"Williams Electronic Games Inc"},
 {0x146F, L"Multi Dimensional Consulting Inc"},
 {0x1470, L"Bay Networks"},
 {0x1471, L"Integrated Telecom Express Inc"},
 {0x1472, L"Daikin Indistries Ltd"},
 {0x1473, L"Zapex Technologies Inc"},
 {0x1474, L"Doug Carson & Associates"},
 {0x1475, L"Picazo Communications"},
 {0x1476, L"Mortara Instrument Inc"},
 {0x1477, L"Net Insight"},
 {0x1478, L"Diatrend Corp"},
 {0x1479, L"Toray Industries Inc"},
 {0x147A, L"Formosa Industrial Computing"},
 {0x147B, L"Abit Computer Corp"},
 {0x147C, L"Aware Inc"},
 {0x147D, L"Interworks Computer Products"},
 {0x147E, L"Matsushita Graphic Communication Systems Inc"},
 {0x147F, L"Nihon Unisys Ltd"},
 {0x1480, L"SCII Telecom"},
 {0x1481, L"Biopac Systems Inc"},
 {0x1482, L"ISYTEC"},
 {0x1483, L"Labway Corp"},
 {0x1668, L"Action Tec Electronics, Inc."},
 {0x1A03, L"ASPEED Technology Inc."},
 {0x1A08, L"Sierra Semiconductor"},
 {0x1B13, L"Jaton Corp."},
 {0x1C1C, L"Symphony"},
 {0x1D44, L"DPT"},
 {0x1DE1, L"TekRAM"},
 {0x21C3, L"21st Century Computer Corp."},
 {0x2348, L"Racore"},
 {0x270B, L"Xantel Corp."},
 {0x270F, L"Chaintech Computer Co., Ltd."},
 {0x3000, L"Hansol Electronics Inc."},
 {0x3142, L"Post Impression Systems"},
 {0x3388, L"Hint Corp."},
 {0x3D3D, L"3DLabs"},
 {0x4005, L"Avance Logic, Inc."},
 {0x4444, L"Internext Compression, Inc."},
 {0x4468, L"BRIDGEPORT MACHINES"},
 {0x4594, L"Cogetec Informatique Inc."},
 {0x4680, L"UMAX Computer Corp."},
 {0x4843, L"Hercules Computer Technology, Inc."},
 {0x4942, L"???"},
 {0x4943, L"Growth Networks"},
 {0x4978, L"Axil Computer, Inc."},
 {0x4A14, L"NetVin"},
 {0x4B10, L"Buslogic Inc."},
 {0x4C48, L"Lung Hwa Electronics"},
 {0x4D51, L"Mediaq Inc"},
 {0x4DDC, L"ILC data Device Corp."},
 {0x5053, L"Voyetra Technologies"},
 {0x5143, L"Qualcomm, Inc."},
 {0x5333, L"S3"},
 {0x5455, L"Technische Universit?t Berlin"},
 {0x5519, L"Cnet Technologies, Inc."},
 {0x5555, L"Genroco Inc"},
 {0x5700, L"Netpower"},
 {0x6356, L"UltraStor"},
 {0x6374, L"c't Magazin fuer Computertechnik"},
 {0x6409, L"Logitec Corp"},
 {0x6666, L"Decision Computer International Co."},
 {0x7604, L"O.N. Electric Co Ltd"},
 {0x8008, L"Quancom Electronic GmbH L"},
 {0x8086, L"Intel"},
 {0x8800, L"Trigem Computer L"},
 {0x8866, L"T-Square Design Inc"},
 {0x8888, L"Silicon Magic"},
 {0x8E0E, L"Computone Corporation"},
 {0x8E2E, L"KTI"},
 {0x9004, L"Adaptec"},
 {0x9005, L"Adaptec"},
 {0x907F, L"Atronics"},
 {0x9412, L"Holtek"},
 {0xA200, L"NEC Corp."},
 {0xA259, L"Hewlett Packard"},
 {0xA25B, L"Hewlett Packard GmbH PL24-MKT"},
 {0xA304, L"Sony"},
 {0xA727, L"3com Corp."},
 {0xAA42, L"Scitex Digital Video"},
 {0xB1B3, L"Shiva Europe, Ltd."},
 {0xC001, L"TSI Telsys"},
 {0xC0A9, L"Micron/Crucial Technology"},
 {0xC0DE, L"Motorola"},
 {0xC0FE, L"Motion Engineering, Inc."},
 {0xCAFE, L"Chrysalis-ITS"},
 {0xD4D4, L"DY4 Systems Inc."},
 {0xE159, L"Tiger Jet Network Inc."},
 {0xE000, L"Winbond"},
 {0xE159, L"Tiger Jet Network Inc."},
 {0xECC0, L"Echo Corp."},
 {0xEDD8, L"Ark Logic Inc."},
 {0xFEDA, L"Epigram Inc."},
};

//Use this value for loop control during searching:
#define PCI_VENTABLE_LEN (sizeof(PciVenTable) / sizeof(PCI_VENTABLE))

#endif


PciClassInfo.h
#ifndef _PCI_CLASS_INFO_H_
#define _PCI_CLASS_INFO_H_

typedef struct _PCI_CLASSCODETABLE
{
 UINT8   BaseClass;
 UINT8   SubClass;
 UINT8  ProgIf;
 UINT16  *BaseDesc;
 UINT16  *SubDesc;
 UINT16  *ProgDesc;
}PCI_CLASSCODETABLE, *PPCI_CLASSCODETABLE;

PCI_CLASSCODETABLE PciClassCodeTable [] =
{
 { 0x00, 0x00, 0x00, L"Pre-2.0 PCI", L"Non-VGA",L"" } ,
 { 0x00, 0x01, 0x00, L"Pre-2.0 PCI", L"VGA Compatible", L"" } ,

 { 0x01, 0x00, 0x00, L"Mass Storage", L"SCSI", L"" } ,
 { 0x01, 0x01, 0x00, L"Mass Storage", L"IDE", L"" } ,
 { 0x01, 0x02, 0x00, L"Mass Storage", L"Floppy", L"" } ,
 { 0x01, 0x03, 0x00, L"Mass Storage", L"IPI", L"" } ,
 { 0x01, 0x04, 0x00, L"Mass Storage", L"RAID", L"" } ,
 { 0x01, 0x05, 0x20, L"Mass Storage", L"ATA controller with single DMA", L"" } , 
 { 0x01, 0x05, 0x30, L"Mass Storage", L"ATA controller with chained DMA", L"" } ,
 { 0x01, 0x06, 0x00, L"Mass Storage", L"Vendor specific", L"" } ,
 { 0x01, 0x06, 0x01, L"Mass Storage", L"AHCI 1.0", L"" } ,
 { 0x01, 0x07, 0x00, L"Mass Storage", L"Serial Attached SCSI", L"" } ,
 { 0x01, 0x08, 0x00, L"Mass Storage", L"NVM", L"" } ,
 { 0x01, 0x80, 0x00, L"Mass Storage", L"Other", L"" } ,

 { 0x02, 0x00, 0x00, L"Network Controller", L"Ethernet", L"" } ,
 { 0x02, 0x01, 0x00, L"Network Controller", L"Token Ring", L"" } ,
 { 0x02, 0x02, 0x00, L"Network Controller", L"FDDI", L"" } ,
 { 0x02, 0x03, 0x00, L"Network Controller", L"ATM", L"" } ,
 { 0x02, 0x04, 0x00, L"Network Controller", L"ISDN", L"" } ,
 { 0x02, 0x05, 0x00, L"Network Controller", L"WorldFip", L"" } ,
 { 0x02, 0x06, 0x00, L"Network Controller", L"PICMG 2.14 Nulti Computing", L"" } ,
 { 0x02, 0x80, 0x00, L"Network Controller", L"Other", L"" } ,

 { 0x03, 0x00, 0x00, L"Display Controller", L"PC Compatible", L"VGA" } ,
 { 0x03, 0x00, 0x01, L"Display Controller", L"PC Compatible", L"8514" } ,
 { 0x03, 0x01, 0x00, L"Display Controller", L"XGA", L"" } ,
 { 0x03, 0x02, 0x00, L"Display Controller", L"3D Controller", L"" } ,
 { 0x03, 0x80, 0x00, L"Display Controller", L"Other", L"" } ,

 { 0x04, 0x00, 0x00, L"Multimedia Device", L"Video", L"" } ,
 { 0x04, 0x01, 0x00, L"Multimedia Device", L"Audio", L"" } ,
 { 0x04, 0x02, 0x00, L"Multimedia Device", L"Computer Telephony Device", L"" } ,
 { 0x04, 0x03, 0x00, L"Multimedia Device", L"Audio Device", L"" } ,
 { 0x04, 0x80, 0x00, L"Multimedia Device", L"Other", L"" } ,

 { 0x05, 0x00, 0x00, L"Memory Controller", L"RAM", L"" } ,
 { 0x05, 0x01, 0x00, L"Memory Controller", L"Flash", L"" } ,
 { 0x05, 0x80, 0x00, L"Memory Controller", L"Other", L"" } ,

 { 0x06, 0x00, 0x00, L"Bridge Device", L"Host Bridge", L"" } ,
 { 0x06, 0x01, 0x00, L"Bridge Device", L"ISA Bridge", L"" } ,
 { 0x06, 0x02, 0x00, L"Bridge Device", L"EISA Bridge", L"" } ,
 { 0x06, 0x03, 0x00, L"Bridge Device", L"MCA Bridge", L"" } ,
 { 0x06, 0x04, 0x00, L"Bridge Device", L"PCI-to-PCI Bridge", L"" } ,
 { 0x06, 0x04, 0x01, L"Bridge Device", L"PCI-to-PCI Bridge", L"Subtractive Decode" } ,
 { 0x06, 0x05, 0x00, L"Bridge Device", L"PCMCIA Bridge", L"" } ,
 { 0x06, 0x06, 0x00, L"Bridge Device", L"NuBus Bridge", L"" } ,
 { 0x06, 0x07, 0x00, L"Bridge Device", L"CardBus Bridge", L"" } ,
 { 0x06, 0x08, 0x00, L"Bridge Device", L"RACEway Bridge", L"" } ,
 { 0x06, 0x09, 0x40, L"Bridge Device", L"PCI-to-PCI Bridge", L"Primary" } ,
 { 0x06, 0x09, 0x80, L"Bridge Device", L"PCI-to-PCI Bridge", L"Secondary" } ,
 { 0x06, 0x0A, 0x00, L"Bridge Device", L"InfiniBrand-to-PCI Host Bridge", L"" } ,
 { 0x06, 0x80, 0x00, L"Bridge Device", L"Other", L"" } ,

 { 0x07, 0x00, 0x00, L"Simple Communications", L"Serial", L"Generic XT Compatible" } ,
 { 0x07, 0x00, 0x01, L"Simple Communications", L"Serial", L"16450 Compatible" } ,
 { 0x07, 0x00, 0x02, L"Simple Communications", L"Serial", L"16550 Compatible" } ,
 { 0x07, 0x00, 0x03, L"Simple Communications", L"Serial", L"16650 Compatible" } ,
 { 0x07, 0x00, 0x04, L"Simple Communications", L"Serial", L"16750 Compatible" } ,
 { 0x07, 0x00, 0x05, L"Simple Communications", L"Serial", L"16850 Compatible" } ,
 { 0x07, 0x00, 0x06, L"Simple Communications", L"Serial", L"16950 Compatible" } ,
 { 0x07, 0x01, 0x00, L"Simple Communications", L"Parallel", L"Standard" } ,
 { 0x07, 0x01, 0x01, L"Simple Communications", L"Parallel", L"Bi-Directional" } ,
 { 0x07, 0x01, 0x02, L"Simple Communications", L"Parallel", L"ECP 1.X Compliant" } ,
 { 0x07, 0x01, 0x03, L"Simple Communications", L"Parallel", L"IEEE 1284 Controller" } ,
 { 0x07, 0x01, 0xFE, L"Simple Communications", L"Parallel", L"IEEE 1284 Target Device" } ,
 { 0x07, 0x02, 0x00, L"Simple Communications", L"Multiport Serial Controller", L"" } ,
 { 0x07, 0x03, 0x00, L"Simple Communications", L"Generic Modem", L"" } ,
 { 0x07, 0x03, 0x01, L"Simple Communications", L"Hayes Compatible Modem", L"16450 Compatible" } ,
 { 0x07, 0x03, 0x02, L"Simple Communications", L"Hayes Compatible Modem", L"16550 Compatible" } ,
 { 0x07, 0x03, 0x03, L"Simple Communications", L"Hayes Compatible Modem", L"16650 Compatible" } ,
 { 0x07, 0x03, 0x04, L"Simple Communications", L"Hayes Compatible Modem", L"16750 Compatible" } ,
 { 0x07, 0x04, 0x00, L"Simple Communications", L"IEEE 488.1/2 (GPIB)", L"" } ,
 { 0x07, 0x05, 0x00, L"Simple Communications", L"Smart Card", L"" } ,
 { 0x07, 0x80, 0x02, L"Simple Communications", L"Other", L"" } ,

 { 0x08, 0x00, 0x00, L"Base Systems Peripheral", L"PIC (Programmable Interrupt Controller)", L"Generic 8259" } ,
 { 0x08, 0x00, 0x01, L"Base Systems Peripheral", L"PIC (Programmable Interrupt Controller)", L"ISA" } ,
 { 0x08, 0x00, 0x02, L"Base Systems Peripheral", L"PIC (Programmable Interrupt Controller)", L"PCI" } ,
 { 0x08, 0x00, 0x10, L"Base Systems Peripheral", L"I/O APIC Interrupt Controller", L"" } ,
 { 0x08, 0x00, 0x20, L"Base Systems Peripheral", L"I/O(x) APIC Interrupt Controller", L"" } ,
 { 0x08, 0x01, 0x00, L"Base Systems Peripheral", L"DMA (Direct Memory Access)", L"Generic 8259" } ,
 { 0x08, 0x01, 0x01, L"Base Systems Peripheral", L"DMA (Direct Memory Access)", L"ISA" } ,
 { 0x08, 0x01, 0x02, L"Base Systems Peripheral", L"DMA (Direct Memory Access)", L"EISA" } ,
 { 0x08, 0x02, 0x00, L"Base Systems Peripheral", L"System Timer", L"Generic 8259" } ,
 { 0x08, 0x02, 0x01, L"Base Systems Peripheral", L"System Timer", L"ISA" } ,
 { 0x08, 0x02, 0x02, L"Base Systems Peripheral", L"System Timer", L"EISA" } ,
 { 0x08, 0x03, 0x00, L"Base Systems Peripheral", L"RTC (Real Time Clock)", L"Generic" } ,
 { 0x08, 0x03, 0x01, L"Base Systems Peripheral", L"RTC (Real Time Clock)", L"ISA" } ,
 { 0x08, 0x04, 0x00, L"Base Systems Peripheral", L"Generic PCI Hot-Plug Controller", L"" } ,
 { 0x08, 0x05, 0x00, L"Base Systems Peripheral", L"SD Host Controller", L"" } ,
 { 0x08, 0x06, 0x00, L"Base Systems Peripheral", L"IOMMU", L"" } ,
 { 0x08, 0x80, 0x00, L"Base Systems Peripheral", L"Other", L"" } ,

 { 0x09, 0x00, 0x00, L"Input Device", L"Keyboard", L"" } ,
 { 0x09, 0x01, 0x00, L"Input Device", L"Digitizer (Pen)", L"" } ,
 { 0x09, 0x02, 0x00, L"Input Device", L"Mouse", L"" } ,
 { 0x09, 0x03, 0x00, L"Input Device", L"Scanner", L"" } ,
 { 0x09, 0x04, 0x00, L"Input Device", L"Gameport", L"Generic" } ,
 { 0x09, 0x04, 0x01, L"Input Device", L"Gameport", L"Legacy" } ,
 { 0x09, 0x80, 0x00, L"Input Device", L"Other", L"" } ,

 { 0x0A, 0x00, 0x00, L"Docking Station", L"Generic", L"" } ,
 { 0x0A, 0x80, 0x00, L"Docking Station", L"Other", L"" } ,

 { 0x0B, 0x00, 0x00, L"Processor", L"i386", L"" } ,
 { 0x0B, 0x01, 0x00, L"Processor", L"i486", L"" } ,
 { 0x0B, 0x02, 0x00, L"Processor", L"Pentium", L"" } ,
 { 0x0B, 0x10, 0x00, L"Processor", L"Alpha", L"" } ,
 { 0x0B, 0x20, 0x00, L"Processor", L"Power PC", L"" } ,
 { 0x0B, 0x30, 0x00, L"Processor", L"MIPS", L"" } ,
 { 0x0B, 0x40, 0x00, L"Processor", L"Co-processor", L"" } ,

 { 0x0C, 0x00, 0x00, L"Serial Bus", L"Firewire (IEEE 1394)", L"Generic" } ,
 { 0x0C, 0x00, 0x10, L"Serial Bus", L"Firewire (IEEE 1394)", L"OHCI" } ,
 { 0x0C, 0x01, 0x00, L"Serial Bus", L"ACCESS.bus", L"" } ,
 { 0x0C, 0x02, 0x00, L"Serial Bus", L"SSA (Serial Storage Archetecture)", L"" } ,
 { 0x0C, 0x03, 0x00, L"Serial Bus", L"USB controller", L"UHCI" } ,
 { 0x0C, 0x03, 0x10, L"Serial Bus", L"USB controller", L"OHCI" } ,
 { 0x0C, 0x03, 0x20, L"Serial Bus", L"USB controller", L"EHCI" } ,
 { 0x0C, 0x03, 0x30, L"Serial Bus", L"USB controller", L"XHCI" } ,
 { 0x0C, 0x03, 0x30, L"Serial Bus", L"USB controller", L"Unspecified" } ,
 { 0x0C, 0x03, 0xFE, L"Serial Bus", L"USB controller", L"USB Device" } ,
 { 0x0C, 0x04, 0x00, L"Serial Bus", L"Fibre Channel", L"" } ,
 { 0x0C, 0x05, 0x00, L"Serial Bus", L"SMBus", L"" } ,
 { 0x0C, 0x06, 0x00, L"Serial Bus", L"InfiniBand", L"" } ,
 { 0x0C, 0x07, 0x00, L"Serial Bus", L"IPMI SMIC Interface", L"" } ,
 { 0x0C, 0x08, 0x00, L"Serial Bus", L"SERCOS Interface", L"" } ,
 { 0x0C, 0x09, 0x00, L"Serial Bus", L"CANBUS", L"" } ,

 { 0x0D, 0x00, 0x00, L"Wireless Controllers", L"iRDA Compatible Controller", L""},
 { 0x0D, 0x01, 0x00, L"Wireless Controllers", L"Consumer IR Controller", L""},
 { 0x0D, 0x10, 0x00, L"Wireless Controllers", L"RF Controller", L""},
 { 0x0D, 0x11, 0x00, L"Wireless Controllers", L"Bluetooth Controller", L""},
 { 0x0D, 0x12, 0x00, L"Wireless Controllers", L"Broadband Controller", L""},
 { 0x0D, 0x20, 0x00, L"Wireless Controllers", L"Ethernet Controller (802.11a)", L""},
 { 0x0D, 0x21, 0x00, L"Wireless Controllers", L"Ethernet Controller (802.11b)", L""},
 { 0x0D, 0x80, 0x00, L"Wireless Controllers", L"Other Wireless Controller", L""},

 { 0x0E, 0x00, 0x00, L"Intelligent I/O Controllers", L"I20 Architecture", L""},

 { 0x0F, 0x01, 0x00, L"Satellite Communication", L"TV Controller", L""},
 { 0x0F, 0x02, 0x00, L"Satellite Communication", L"Audio Controller", L""},
 { 0x0F, 0x03, 0x00, L"Satellite Communication", L"Video Controller", L""},
 { 0x0F, 0x04, 0x00, L"Satellite Communication", L"Data Controller", L""},

 { 0x10, 0x00, 0x00, L"Encryption/Decryption", L"Network and Computing Encrpytion/Decryption", L""},
 { 0x10, 0x10, 0x00, L"Encryption/Decryption", L"Entertainment Encrpytion/Decryption", L""},
 { 0x10, 0x80, 0x00, L"Encryption/Decryption", L"Other Encrpytion/Decryption", L""},

 { 0x11, 0x00, 0x00, L"Data Acquisition & Signal Processing", L"DPIO Modules", L""},
 { 0x11, 0x01, 0x00, L"Data Acquisition & Signal Processing", L"Performance Counters", L""},
 { 0x11, 0x10, 0x00, L"Data Acquisition & Signal Processing", L"Communications Syncrhonization", L""},
 { 0x11, 0x20, 0x00, L"Data Acquisition & Signal Processing", L"Signal processing Management", L""},
 { 0x11, 0x80, 0x00, L"Data Acquisition & Signal Processing", L"Signal Processing Controller", L""},

 { 0xFF, 0x00, 0x00, L"Unknown", L"Device Does Not Fit In Class Codes", L"UDF" } ,
};

// Use this value for loop control during searching:
#define PCI_CLASSCODETABLE_LEN  (sizeof(PciClassCodeTable) / sizeof(PCI_CLASSCODETABLE))

#endif


Execution result shows the vendor, vendor ID, device ID and device information:
Fig. 1. Result.


Note: I typed the LsPciDev.efi > LsPciDev.txt command under shell. Thus, I just open the LsPciDev.txt to show the result for you.

Reference:
1. PCI_Configuration_Space
2. UEFI Spec.

2014年12月23日 星期二

[C/C++] A Clock Program by Reading CMOS RAM

The sample code as shown in the below. Please note that the syntax of inline assembly are based on the compiler which you used. This sample code is developed using Watcom and I have complied and executed this sample under Window XP. If you want to compile this sample by using GCC or VC compiler, please check their syntax of inline assembly first (you also can write your assembly into a module such that it can be called in your .c flile. However, you must use assembler to compile you assembly module and link it with your object file manually).
This sample read and show the system date and time from the CMOS. The program will terminate when user press any key from the key board.

timer.h

#ifndef TIMER_H
#define TIMER_H

#define SecIndex              0
#define AlarmSecIndex         1
#define MinIndex              2
#define AlarmMinIndex         3
#define HourIndex             4
#define AlarmHourIndex        5
#define DayIndex              7
#define MonthIndex            8
#define YearIndex             9

struct Time
{
    unsigned char sec;
    unsigned char min;
    unsigned char hr;
};

struct Date
{
    unsigned long year;
    unsigned char month;
    unsigned char day;
};

void readTime(struct Time *getTime);
void readDate(struct Date *getDate);
unsigned char readCmos(unsigned char _cmosIndex);
unsigned char BCDtoInt(unsigned char BCDNum);
void wait();

#endif
timer.c

#include "timer.h"

void readTime(struct Time *getTime)
{
    getTime->sec = readCmos(SecIndex);
    getTime->min = readCmos(MinIndex);
    getTime->hr = readCmos(HourIndex);
}

void readDate(struct Date *getDate)
{
    getDate->year = readCmos(YearIndex);
    getDate->month = readCmos(MonthIndex);
    getDate->day = readCmos(DayIndex);
}

unsigned char readCmos(unsigned char _cmosIndex)
{
    unsigned char _getByte,UIP;
    UIP = 1;

    /*
    Status Register A (Hex 00A)
    +--------------------------------------------------------+
    |  7   |  6   |   5   |   4   |  3  |  2  |   1  |   0   |
    |------+--------------+-------+--------------------------|
    | UIP  |    SDIV      |  BC   |            Rate          |
    +--------------------------------------------------------+
     UIP:     Update in progress
    SDIV:    Select divider
     BC:      Bank control
    */
    /*
    When the UIP bit is 1, an update is in progress.
    When it is set to 0, the current date and time can be read.
    */
    while(UIP)
    {
        _asm
        {
            mov  al, 0ah
            out  70h, al
            out  0edh, al ;delay a moment to avoid the error.
            in   al, 71h
            test al, 80h
            jz   Set
            jmp  Exit

         Set:
            mov  UIP, 0

         Exit:
        };
    }
    _asm
    {
         mov al, _cmosIndex
         out 70h, al ;output the index to the index port.
         out 0edh, al ;delay a moment to avoid the error.
         in al, 71h ;read the data from the cmos data port.
         mov _getByte, al
    };
    return _getByte;
}

void writeCmos(unsigned char _cmosIndex,unsigned char _byteData)
{
    _asm
    {
        mov al, _cmosIndex
        out 70h, al ;output the index to the index port.
        out 0edh, al ;this is used to delay a moment to avoid the error.
        mov al, _byteData
        out 71h, al ;write the data to the cmos through the data port.
    }
}

unsigned char BCDtoInt(unsigned char BCDNum)
{
    unsigned char intNum;
    intNum = ((BCDNum >> 4) * 10) + (BCDNum & 0x0f);
    return intNum;
}

unsigned char intToBCD(unsigned char intNum)
{
    unsigned BCDNum;
    BCDNum = ((intNum / 10) << 4) + (intNum % 10);
    return BCDNum;
}

void wait()
{
        struct Time currentTime, nextTime;
        readTime(&currentTime);
        readTime(&nextTime);
        while(nextTime.sec == currentTime.sec)
            readTime(&nextTime);
}
main.c

#include "timer.h"
#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct Time cmosTime;
    struct Date cmosDate;
    char _keyin = 0;
    
    readDate(&cmosDate);
    readTime(&cmosTime);
    printf("20%02d/%02d/%02d %02d:%02d:%02d\n",\
    BCDtoInt(cmosDate.year),BCDtoInt(cmosDate.month),BCDtoInt(cmosDate.day),BCDtoInt(cmosTime.hr),\
    BCDtoInt(cmosTime.min),BCDtoInt(cmosTime.sec));
    while(1)
    {
        wait();
        system("cls");
        readDate(&cmosDate);
        readTime(&cmosTime);
        printf("CMOS Time: 20%02d/%02d/%02d %02d:%02d:%02d\n",\
        BCDtoInt(cmosDate.year),BCDtoInt(cmosDate.month),BCDtoInt(cmosDate.day),BCDtoInt(cmosTime.hr),\
        BCDtoInt(cmosTime.min),BCDtoInt(cmosTime.sec));
        printf("Press Any Key to Exit\n");
        //detect keyboard
        _asm
        {
            mov  ah, 06h
            mov  dl, -1
            int  21h; maybe this interrupt will not available in the future.  
            mov  _keyin, al
        }
        if(_keyin)
            break;
    }
    return 0;
}

Fig.1 Execution Result

Note: you can read CMOS through 70,71,72 and 73 (72, 73's content may same as 70, 71's, it's depend on  your system BIOS) port.

Reference:
1. Open Watcom Download
2. Open Watcom C/C++ User's Guide
3. CMOS Registers

2014年12月22日 星期一

[Android Sample Code] 利用GPS定位

Android提供下列定位方式的API:
1. GPS定位
2. Wi-Fi訊號/基地台訊號定位

由於GPS是透過衛星定位所以只能用於戶外環境,跟其它兩種方法比它的精確度最高但是缺點是比較耗電而且回傳位置資訊的速度較慢,相較之下Wi-Fi和基地台定位室內、室外都可以使用但是精確度較差,不過和GPS相比較不耗電,回傳位置資訊的速度也較快,總結如下表:

                                  TABLE I

GPS
Wi-Fi訊號/基地台訊號定位
可應用環境
室內
室內/室外
精確度
較差
回傳位置資訊所需時間
較長
較短
耗電量
較高
較低

想要使用這幾種定位方式的其中一種的話,必須在AndroidManifest.xml裡添加下列這行App權限設定:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

其中"android.permission.ACCESS_COARSE_LOCATION"是讓App能透過Wi-Fi/基地台訊號存取大概的位置資訊;而"android.permission.ACCESS_FINE_LOCATION" 則是能讓App透過GPS和Wi-Fi/基地台訊號精確的存取Android裝置的位置。

要寫定位的App,需用到以下物件:
1. LocationManager: 用來取得與更新目前裝置的資訊,透過呼叫LocationManagerrequestLocationUpdates()並傳入實作LocationListener介面(Interface)之call back object來達成。
2. 實作LocationListener

利用GPS取得經緯度的範例程式如下所示,App的外觀僅添加一TextView用來顯示所取得之位置資訊,在寫定位App時不需實體化LocationManager物件,而是透過呼叫Context (由Activity繼承的父類別)的getSystemService()方法 (Method)回傳一LocationManager的參照 (Reference)給App,如第36行所示,傳入參數Context.LOCATION_SERVICE給getSystemService()即會回傳一LocationManager參照,接下來第37行只需要呼叫LocationManagerrequestLocationUpdates方法並註冊監聽者-LocationListener即可,第一個參數式指定想要使用哪一種定位服務,可以選用GPS_PROVIDER或是NETWORK_PROVIDER, 第二和第三個參數則是設定更新位置資訊的最小時間週期 (單位是毫秒)以及更新資訊所需之最短距離 (單位為公尺),都設0則是代表請求盡快回傳位置的資訊,最後一個參數則是傳入所實作之call back object,即locationListener
第15到29行實作了LocationListener的介面,本範例僅實作onStatusChanged()方法,當位置資訊一更新時,locationListener call back物件就會被其它物件呼叫,然後onLocationChanged()方法就會被執行並呼叫updateWithNewLocation()方法顯示目前位置的經緯度到螢幕上,參數location即為被更新位置的資訊。
package com.example.locationtest;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
 TextView positionTextView;
 LocationManager locationManager;
 
 LocationListener locationListener = new LocationListener(){
  @Override
     public void onLocationChanged(Location location){
      //implementation 
      updateWithNewLocation(location);
     }
  
     @Override
     public void onStatusChanged(String provider,int status,Bundle extras){}
     
     @Override
     public void onProviderEnabled(String provider){}
     @Override
     public void onProviderDisabled(String provider){}
    }; 
    
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        positionTextView = (TextView) findViewById(R.id.PositionTextView);
        locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, locationListener);
        //you also can register LocationManager.NETWORK_PROVIDER in the same time and handle information 
        //from these provider in the Locationlistener.
        //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, loctionListener);
        //You also can call below method to get the cached location.
       //Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
       //or
       //Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
       //updateWithNewLocation(location);
    }
    
 private void updateWithNewLocation(Location location) {
  if (location != null) {
   double lat = location.getLatitude();
   double lng = location.getLongitude();
   String latLongString = "Latitude:" + lat + "\nLongitude:" + lng;
   positionTextView.setText("Your Current Position is:\n" + latLongString);
  } 
 }
}


要讓App可以正確的獲取位置資訊必須開啟下圖的設定,「存取我的地點」和「GPS衛星定位都必須開啟」。
Fig. 1 啟用裝置上的位置資訊服務


執行結果:
Fig. 2. 執行結果

2014年12月2日 星期二

[Experience] 程式語言裡的goto真有這麼可怕!?

這幾天看到網路上又有人在吵goto的問題,這讓我想起之前工作同事間的爭執,A同事在他改的程式碼裡使用goto做錯誤處理, B同事看到A改的程式碼就要求A把goto的程式碼全改掉,理由是別人都說不要用所以不該這樣寫, 但是B卻說不出不該用的原因所以兩人就發生了激辯,其實goto也沒那麼恐怖而且也不是不能用。

以下節錄EFI1.10 Driver Writer's Guide的內容 (3.11.7):
In general, the goto construct is not used. However, it is acceptable to use goto for error handling and thus exiting a routine in an error case. A goto allows the error exit code to be contained in one place at the end of a routine. This location reduces software life cycle maintenance issues, as there can be one copy of error cleanup code per routine. If a goto is not used for this case, then the error cleanup code tends to get replicated multiple times, which tends to induce errors in code maintenance.

另外不該使用goto的原因和正確的使用時機clean code這本書也說得很清楚:
 Some programmers follow Edsger Dijkstra’s rules of structured programming. Dijkstra said that every function, and every block within a function, should have one entry and one exit. Following these rules means that there should only be one return statement in a function, no break or continue statements in a loop, and never, ever, any goto statements. While we are sympathetic to the goals and disciplines of structured programming, those rules serve little benefit when functions are very small. It is only in larger functions that such rules provide significant benefit. So if you keep your functions small, then the occasional multiple return, break, or continue statement does no harm and can sometimes even be more expressive than the single- entry, single-exit rule. On the other hand, goto only makes sense in large functions, so it should be avoided.