获取计算机硬件信息的类

//头文件 

#pragma once
#include <stdio.h>
#include <tchar.h>
//#include <afx.h>
#include <iostream>
//#include <winioctl.h>
#include <Windows.h>
#include <string>
#include <map>
//#include <WinSock2.h>
#include <IPHlpApi.h>
using namespace std;
#pragma comment(lib, "Iphlpapi.lib")

#define FILE_DEVICE_SCSI       0x0000001b
#define IOCTL_SCSI_MINIPORT_IDENTIFY  ( ( FILE_DEVICE_SCSI << 16 ) + 0x0501 )
#define IOCTL_SCSI_MINIPORT    0x0004D008 // see NTDDSCSI.H for definition
#define IDENTIFY_BUFFER_SIZE   512
#define SENDIDLENGTH          (sizeof( SENDCMDOUTPARAMS )+IDENTIFY_BUFFER_SIZE )
#define IDE_ATAPI_IDENTIFY     0xA1 // Returns ID sector for ATAPI.
#define IDE_ATA_IDENTIFY       0xEC // Returns ID sector for ATA.
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088

typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef unsigned short WORD;

//用到的结构予定义
typedef struct _IDSECTOR
{
 USHORT wGenConfig;
 USHORT wNumCyls;
 USHORT wReserved;
 USHORT wNumHeads;
 USHORT wBytesPerTrack;
 USHORT wBytesPerSector;
 USHORT wSectorsPerTrack;
 USHORT wVendorUnique[3];
 CHAR sSerialNumber[20];
 USHORT wBufferType;
 USHORT wBufferSize;
 USHORT wECCSize;
 CHAR sFirmwareRev[8];
 CHAR sModelNumber[40];
 USHORT wMoreVendorUnique;
 USHORT wDoubleWordIO;
 USHORT wCapabilities;
 USHORT wReserved1;
 USHORT wPIOTiming;
 USHORT wDMATiming;
 USHORT wBS;
 USHORT wNumCurrentCyls;
 USHORT wNumCurrentHeads;
 USHORT wNumCurrentSectorsPerTrack;
 ULONG ulCurrentSectorCapacity;
 USHORT wMultSectorStuff;
 ULONG ulTotalAddressableSectors;
 USHORT wSingleWordDMA;
 USHORT wMultiWordDMA;
 BYTE bReserved[128];
} IDSECTOR, *PIDSECTOR;

typedef struct _DRIVERSTATUS DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;


typedef struct _SRB_IO_CONTROL
{
 ULONG HeaderLength;
 UCHAR Signature[8];
 ULONG Timeout;
 ULONG ControlCode;
 ULONG ReturnCode;
 ULONG Length;
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;


typedef struct _IDEREGS IDEREGS, *PIDEREGS, *LPIDEREGS;

typedef struct _SENDCMDINPARAMS SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;

typedef struct _GETVERSIONOUTPARAMS
{
 BYTE bVersion;   // Binary driver version.
 BYTE bRevision;   // Binary driver revision.
 BYTE bReserved;   // Not used.
 BYTE bIDEDeviceMap; // Bit map of IDE devices.
 DWORD fCapabilities; // Bit mask of driver capabilities.
 DWORD dwReserved[4]; // For future use.
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
//
//结构定义
typedef struct _UNICODE_STRING
{
 unsigned short Length;//长度
 unsigned short MaximumLength;//最大长度
 PWSTR  Buffer;//缓存指针
} UNICODE_STRING,*PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES
{
 ULONG Length;//长度 18h
 HANDLE RootDirectory;// 00000000
 PUNICODE_STRING ObjectName;//指向对象名的指针
 ULONG Attributes;//对象属性00000040h
 PVOID SecurityDescriptor;    // Points to type SECURITY_DESCRIPTOR,0
 PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE,0
} OBJECT_ATTRIBUTES;

typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
//函数指针变量类型
typedef DWORD (__stdcall *ZWOS )( PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);
typedef DWORD (__stdcall *ZWMV )( HANDLE,HANDLE,PVOID,ULONG,ULONG,PLARGE_INTEGER,PSIZE_T,DWORD,ULONG,ULONG);
typedef DWORD (__stdcall *ZWUMV )( HANDLE,PVOID);


//---------cpuinfo

#ifndef CPUID_H
#define CPUID_H


// Cache Information
struct CacheInfo
{
 int level;    // level
 int size;    // size
 int way;    // way
 int linesize;   // linesize

 CacheInfo()    // constructor
 {
  level = 0;
  size = 0;
  way = 0;
  linesize = 0;
 }

 CacheInfo(int clevel, int csize, int cway, int clinesize) //constructor
 {
  level = clevel;
  size = csize;
  way = cway;
  linesize = clinesize;
 }
};

// CPU SerialNumber
// comprise 6 WORD nibble, fommatting xxxx-xxxx-xxxx-xxxx-xxxx-xxxx
/*struct  CpuSerialNumber
{
 WORD nibble[6];   // 6 WORD nibble;

 void SerialNumber()   //constructor
 {
  memset(nibble, 0, sizeof(nibble));
 }
};

*/
// singleton class CPUID
// Get CPU information


class computerInfo
{
 
public:
 computerInfo(void);
 ~computerInfo(void);
public:
 std::string GetMacAddress( );
 std::string GetDiskID( );
 std::string  GetBiosID();

 string GetVID();       // Get Vender ID String
 string GetBrand();       // Get Brand String

 //bool GetSerialNumber(CpuSerialNumber& serial); // Get CPU Serial Number

 bool IsHyperThreading();     // Check if hyper-threading is supported
 bool IsEST();        // Check if Enhanced Speed Step is supported
 bool IsMMX();        // Check if MMX is supported

 // Get cache information
 DWORD GetCacheInfo(CacheInfo& L1, CacheInfo& L2, CacheInfo& L3);

 //BOOL WinNTHDSerialNumAsScsiRead(BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen);
 //BOOL DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
 // PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
 // PDWORD lpcbBytesReturned);
 //BOOL WinNTHDSerialNumAsPhysicalRead(BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen);
 UINT FindAwardBios( BYTE** ppBiosAddr);
 UINT FindAmiBios(BYTE** ppBiosAddr);
 UINT FindPhoenixBios( BYTE** ppBiosAddr );

 std::string  WCharToChar(UINT PageCode, std::wstring strWChar);
 std::wstring  CharToWChar(UINT PageCode, std::string strChar);
private:

 DWORD m_eax;  // value eax after cpuid
 DWORD m_ebx;  // value ebx after cpuid
 DWORD m_ecx;  // value ecx after cpuid
 DWORD m_edx;  // value edx after cpuid

 map<int, CacheInfo> m_cache; // Cache information table

 void Executecpuid(DWORD eax); // Execute cpuid
};
#endif

/

//CPP文件


#include "computerInfo.h"
using namespace std;
computerInfo::computerInfo(void)
:m_eax(0)
,m_ebx(0)
,m_ecx(0)
,m_edx(0)
{
 m_cache[0x06] =  CacheInfo(1, 8, 4, 32);
 m_cache[0x08] =  CacheInfo(1, 16, 4, 32);
 m_cache[0x0a] =  CacheInfo(1, 8, 2, 32);
 m_cache[0x0c] =  CacheInfo(1, 16, 4, 32);
 m_cache[0x2c] =  CacheInfo(1, 32, 8, 64);
 m_cache[0x30] =  CacheInfo(1, 32, 8, 64);
 m_cache[0x60] =  CacheInfo(1, 16, 8, 64);
 m_cache[0x66] =  CacheInfo(1, 8, 4, 64);
 m_cache[0x67] =  CacheInfo(1, 16, 4, 64);
 m_cache[0x68] =  CacheInfo(1, 32, 4, 64);

 m_cache[0x39] =  CacheInfo(2, 128, 4, 64);
 m_cache[0x3b] =  CacheInfo(2, 128, 2, 64);
 m_cache[0x3c] =  CacheInfo(2, 256, 4, 64);
 m_cache[0x41] =  CacheInfo(2, 128, 4, 32);
 m_cache[0x42] =  CacheInfo(2, 256, 4, 32);
 m_cache[0x43] =  CacheInfo(2, 512, 4, 32);
 m_cache[0x44] =  CacheInfo(2, 1024, 4, 32);
 m_cache[0x45] =  CacheInfo(2, 2048, 4, 32);
 m_cache[0x79] =  CacheInfo(2, 128, 8, 64);
 m_cache[0x7a] =  CacheInfo(2, 256, 8, 64);
 m_cache[0x7b] =  CacheInfo(2, 512, 8, 64);
 m_cache[0x7c] =  CacheInfo(2, 1024, 8, 64);
 m_cache[0x82] =  CacheInfo(2, 256, 8, 32);
 m_cache[0x83] =  CacheInfo(2, 512, 8, 32);
 m_cache[0x84] =  CacheInfo(2, 1024, 8, 32);
 m_cache[0x85] =  CacheInfo(2, 2048, 8, 32);
 m_cache[0x86] =  CacheInfo(2, 512, 4, 64);
 m_cache[0x87] =  CacheInfo(2, 1024, 8, 64);

 m_cache[0x22] =  CacheInfo(3, 512, 4, 64);
 m_cache[0x23] =  CacheInfo(3, 1024, 8, 64);
 m_cache[0x25] =  CacheInfo(3, 2048, 8, 64);
 m_cache[0x29] =  CacheInfo(3, 4096, 8, 64);
}

computerInfo::~computerInfo(void)
{
}
//以下代码可以取得系统特征码(网卡MAC、硬盘序列号、CPU ID、BIOS编号)


// 网卡 MAC 地址,注意: MAC 地址是可以在注册表中修改的

std::string computerInfo::GetMacAddress()
{
 BYTE szMacAddress[128];
 memset(szMacAddress,0,sizeof(szMacAddress));
 UINT uMacAddressLen=0;
 UINT uErrorCode = 0;
 IP_ADAPTER_INFO iai;
 ULONG uSize = 0;
 DWORD dwResult = GetAdaptersInfo( &iai, &uSize );
 if( dwResult == ERROR_BUFFER_OVERFLOW )
 {
  IP_ADAPTER_INFO* piai = ( IP_ADAPTER_INFO* )HeapAlloc( GetProcessHeap( ),0, uSize );
  if( piai != NULL )
  {
   dwResult = GetAdaptersInfo( piai, &uSize );
   if( ERROR_SUCCESS == dwResult )
   {
    IP_ADAPTER_INFO* piai2 = piai;
    while( piai2 != NULL && ( uMacAddressLen + piai2->AddressLength ) < 4096U )
    {
     CopyMemory( szMacAddress + uMacAddressLen, piai2->Address, piai2->AddressLength );
     uMacAddressLen += piai2->AddressLength;
     piai2 = piai2->Next;                       
    }
    
   }
   else
   {
    uErrorCode = 0xF0000000U + dwResult;
   }
   //VERIFY( HeapFree( GetProcessHeap( ), 0, piai ) );
  }
  else
  {
   return "/0";
  }
 }
 else
 {
  uErrorCode = 0xE0000000U + dwResult;
 }
 if( uErrorCode != 0U )
 {
  return "/0";
 }

 char *buf=new char[2];
 std::string strMacAddress;

 
  for(UINT i=0;i<uMacAddressLen;i++)
  {
   if (szMacAddress[i]==0)
   {
    strMacAddress+="00";
   }
   else
   {
    itoa(szMacAddress[i],buf,16);//得到的MAC为10进制数,要转换成16进制
   
    if (szMacAddress[i]<10)//小于10的要补0
    {
     strMacAddress+='0';
    }
    strMacAddress+=buf;

   }

  }
 
 return strMacAddress;
}

 


// 硬盘序列号,注意:有的硬盘没有序列号

std::string  computerInfo::GetDiskID( )
{
 
 LPCTSTR lpRootPathName=_T("c://"); //取C盘
 LPTSTR lpVolumeNameBuffer=new WCHAR[12];//磁盘卷标
 DWORD nVolumeNameSize=12;// 卷标的字符串长度
 DWORD VolumeSerialNumber;//硬盘序列号
 DWORD MaximumComponentLength;// 最大的文件长度
 LPTSTR lpFileSystemNameBuffer=new WCHAR[10];// 存储所在盘符的分区类型的长指针变量
 DWORD nFileSystemNameSize=10;// 分区类型的长指针变量所指向的字符串长度
 DWORD FileSystemFlags;// 文件系统的一此标志
 ::GetVolumeInformation(lpRootPathName,
  lpVolumeNameBuffer, nVolumeNameSize,
  &VolumeSerialNumber, &MaximumComponentLength,
  &FileSystemFlags,
  lpFileSystemNameBuffer, nFileSystemNameSize);

// string str=(string)VolumeSerialNumber;
 //str.Format(_T("%lx "),VolumeSerialNumber);
 //AfxMessageBox(str);

 std::string strDiskID;
 char s_tmp[20];
 sprintf(s_tmp,"%u",VolumeSerialNumber);
 strDiskID=strDiskID+s_tmp;
// strDiskID=WCharToChar( CP_ACP, str.GetBuffer());//Unicode 下 CString转string
 //str.ReleaseBuffer();


 return strDiskID;
}

 


// BIOS 编号,支持 AMI, AWARD, PHOENIX
 std::string  computerInfo::GetBiosID()
{
 BYTE szBiosID[100];
 UINT uBiosIDLen=0;
 SIZE_T ssize;

 LARGE_INTEGER so;
 so.LowPart=0x000f0000;
 so.HighPart=0x00000000;
 ssize=0xffff;
 WCHAR strPH[30]=_T("L//device//physicalmemory");

 DWORD ba=0;

 UNICODE_STRING struniph;
 struniph.Buffer=strPH;
 struniph.Length=0x2c;
 struniph.MaximumLength =0x2e;

 OBJECT_ATTRIBUTES obj_ar;
 obj_ar.Attributes =64;
 obj_ar.Length =24;
 obj_ar.ObjectName=&struniph;
 obj_ar.RootDirectory=0;
 obj_ar.SecurityDescriptor=0;
 obj_ar.SecurityQualityOfService =0;

 HMODULE hinstLib = LoadLibrary(_T("ntdll.dll"));
 ZWOS ZWopenS=(ZWOS)GetProcAddress(hinstLib,"ZwOpenSection");
 ZWMV ZWmapV=(ZWMV)GetProcAddress(hinstLib,"ZwMapViewOfSection");
 ZWUMV ZWunmapV=(ZWUMV)GetProcAddress(hinstLib,"ZwUnmapViewOfSection");

 //调用函数,对物理内存进行映射
 HANDLE hSection;
 if( 0 == ZWopenS(&hSection,4,&obj_ar) &&
  0 == ZWmapV(
  ( HANDLE )hSection,   //打开Section时得到的句柄
  ( HANDLE )0xFFFFFFFF, //将要映射进程的句柄,
  &ba,                  //映射的基址
  0,
  0xFFFF,               //分配的大小
  &so,                  //物理内存的地址
  &ssize,               //指向读取内存块大小的指针
  1,                    //子进程的可继承性设定
  0,                    //分配类型
  2                     //保护类型
  ) )
  //执行后会在当前进程的空间开辟一段64k的空间,并把f000:0000到f000:ffff处的内容映射到这里
  //映射的基址由ba返回,如果映射不再有用,应该用ZwUnmapViewOfSection断开映射
 {
  BYTE* pBiosSerial = ( BYTE* )ba;
  UINT uBiosSerialLen = FindAwardBios( &pBiosSerial );
  if( uBiosSerialLen == 0U )
  {
   uBiosSerialLen = FindAmiBios( &pBiosSerial );
   if( uBiosSerialLen == 0U )
   {
    uBiosSerialLen = FindPhoenixBios( &pBiosSerial );
   }
  }
  if( uBiosSerialLen != 0U )
  {
   CopyMemory( szBiosID + uBiosIDLen, pBiosSerial, uBiosSerialLen );
   uBiosIDLen += uBiosSerialLen;
  }
  ZWunmapV( ( HANDLE )0xFFFFFFFF, ( void* )ba );
 }

 char *buf=new char[2];
 std::string strBiosID;


 for(UINT i=0;i<uBiosIDLen;i++)
 {
  
   itoa(szBiosID[i],buf,16);//得到的MAC为10进制数,要转换成16进制
   strBiosID+=buf;  

 }
 return strBiosID;
}

 

UINT computerInfo::FindAwardBios( BYTE** ppBiosAddr )
{
 BYTE* pBiosAddr = * ppBiosAddr + 0xEC71;
 BYTE szBiosData[128];
 CopyMemory( szBiosData, pBiosAddr, 127 );
 szBiosData[127] = 0;
 int iLen = lstrlen( ( LPCWSTR )szBiosData );
 if( iLen > 0 && iLen < 128 )
 {
  //AWard: 07/08/2002-i845G-ITE8712-JF69VD0CC-00
  //Phoenix-Award: 03/12/2002-sis645-p4s333
  if( szBiosData[2] == '/' && szBiosData[5] == '/' )
  {
   BYTE* p = szBiosData;
   while( * p )
   {
    if( * p < ' ' || * p >= 127 )
    {
     break;
    }
    ++ p;
   }
   if( * p == 0 )
   {
    * ppBiosAddr = pBiosAddr;
    return ( UINT )iLen;
   }
  }
 }
 return 0;
}

UINT computerInfo::FindAmiBios( BYTE** ppBiosAddr )
{
 BYTE* pBiosAddr = * ppBiosAddr + 0xF478;
 BYTE szBiosData[128];
 CopyMemory( szBiosData, pBiosAddr, 127 );
 szBiosData[127] = 0;
 int iLen = lstrlen( (LPCWSTR )szBiosData );
 if( iLen > 0 && iLen < 128 )
 {
  // Example: "AMI: 51-2300-000000-00101111-030199-"
  if( szBiosData[2] == '-' && szBiosData[7] == '-' )
  {
   BYTE* p = szBiosData;
   while( * p )
   {
    if( * p < ' ' || * p >= 127 )
    {
     break;
    }
    ++ p;
   }
   if( * p == 0 )
   {
    * ppBiosAddr = pBiosAddr;
    return ( UINT )iLen;
   }
  }
 }
 return 0;
}

UINT computerInfo::FindPhoenixBios( BYTE** ppBiosAddr )
{
 UINT uOffset[3] = { 0x6577, 0x7196, 0x7550 };
 for( UINT i = 0; i < 3; ++ i )
 {
  BYTE* pBiosAddr = * ppBiosAddr + uOffset[i];
  BYTE szBiosData[128];
  CopyMemory( szBiosData, pBiosAddr, 127 );
  szBiosData[127] = 0;
  int iLen = lstrlen( (LPCWSTR )szBiosData );

  if( iLen > 0 && iLen < 128 )
  {
   // Example: Phoenix "NITELT0.86B.0044.P11.9910111055"
   if( szBiosData[7] == '.' && szBiosData[11] == '.' )
   {
    BYTE* p = szBiosData;
    while( * p )
    {
     if( * p < ' ' || * p >= 127 )
     {
      break;
     }
     ++ p;
    }
    if( * p == 0 )
    {
     * ppBiosAddr = pBiosAddr;
     return ( UINT )iLen;
    }
   }
  }
 }
 return 0;
}

 

 

string computerInfo::GetVID()
{
 char cVID[13];    // Store Vender ID String, contain 12 chars
 memset(cVID, 0, 13);  // Initialize all chars to 0
 Executecpuid(0);   // Execute cpuid instruction with eax = 0
 memcpy(cVID, &m_ebx, 4); // ebx contains the first 4 chars
 memcpy(cVID+4, &m_edx, 4); // edx contains the middle 4 chars
 memcpy(cVID+8, &m_ecx, 4); // ecx contains the last 4 chars;

 return string(cVID);  // convert to string and return
}

string computerInfo::GetBrand()
{
 const DWORD BRANDID = 0x80000002;  // brand parameter start at 0x80000002
 char cBrand[49];      // Store Brand String, contain 48 chars
 memset(cBrand, 0, 49);     // Initialize all chars to 0

 for (DWORD i = 0; i < 3; i++)   // Execute cpuid instruction with
 {          // eax = 0x80000002 to 0x80000004
  Executecpuid(BRANDID + i);   
  memcpy(cBrand + i*16, &m_eax, 16); // eax, ebx, ecx, edx contain the brand string
 }

 return string(cBrand);  // convert to string and return
}

DWORD computerInfo::GetCacheInfo(CacheInfo& L1, CacheInfo& L2, CacheInfo& L3)
{
 BYTE cValues[16];      // Totally 16 byte information
 DWORD result = 0;      // Cache number
 Executecpuid(2);      // Execute cpuid instruction with eax = 2
 memcpy(cValues, &m_eax, 16);   // copy return value

 for (int i = 1; i < 16; i++)
 {
  if (m_cache.find(cValues[i]) != m_cache.end()) // if this information is about cache
  {
   switch (m_cache[cValues[i]].level)   // Get cache information from table
   {
   case 1:  // L1 cache
    L1 = m_cache[cValues[i]];
    break;
   case 2:  // L2 cache
    L2 = m_cache[cValues[i]];
    break;
   case 3:  // L3 cache
    L3 = m_cache[cValues[i]];
    break;
   default:
    break;
   }
   result++;
  }

 }

 return result;
}
/*
bool computerInfo::GetSerialNumber(CpuSerialNumber& serial)
{
 Executecpuid(1); // Execute cpuid instruction with eax = 1
 bool isSupport = m_edx & (1<<18); // Check if Serial Number is supported
 if (false == isSupport) // not support
 {
  return false;
 }
 memcpy(&serial.nibble[4], &m_eax, 4); // eax is the higher 2 nibble

 Executecpuid(3); // Execute cpuid instruction with eax = 3
 memcpy(&serial.nibble[0], &m_ecx, 8); // ecx and edx constains the middle and first 4 nibble

 return true;
}
*/
void computerInfo::Executecpuid(DWORD veax)
{
 // The following 4 DWORD variable store the four registers values after cpuid
 DWORD deax;
 DWORD debx;
 DWORD decx;
 DWORD dedx;

 __asm
 {
  mov eax, veax
   cpuid
   mov deax, eax
   mov debx, ebx
   mov decx, ecx
   mov dedx, edx
 }

 m_eax = deax; // store in class member
 m_ebx = debx;
 m_ecx = decx;
 m_edx = dedx;
}

bool computerInfo::IsHyperThreading()
{
 Executecpuid(1);   // Execute cpuid instruction with eax = 1

 return m_edx & (1<<28);  // bit 28 be set represent hyper-threading is supported
}

bool computerInfo::IsEST()
{
 Executecpuid(1);   // Execute cpuid instruction with eax = 1

 return m_ecx & (1<<7);  // bit 7 be set represent Enhanced Speed Step is supported
}

bool computerInfo::IsMMX()
{
 Executecpuid(1);   // Execute cpuid instruction with eax = 1

 return m_edx & (1<<23);  // bit 28 be set represent MMX is supported
}
std::string computerInfo::WCharToChar(UINT PageCode, std::wstring strWChar)
{
 std::string strChar="";
 strChar.clear();
 int ret = 0;
 int nSize = (int)strWChar.length()*2;
 static char pszDest[1024*10];
 if( pszDest )
 {
  memset( pszDest, 0, nSize+1 );
  ret = WideCharToMultiByte(PageCode,NULL,strWChar.c_str(),-1,pszDest,nSize,NULL,FALSE);
  pszDest[nSize] = '/0';
  strChar = pszDest;
 }
 return strChar;

}

std::wstring computerInfo::CharToWChar(UINT PageCode, std::string strChar)
{
 std::wstring strWChar=_T("");
 strWChar.clear();
 int ret = 0;
 //wchar_t *pszDest = new wchar_t[strChar.length()+1];
 static wchar_t pszDest[1024*10];
 if( pszDest )
 {
  memset( pszDest, 0, (strChar.length()+1)*sizeof(wchar_t) );
  ret = MultiByteToWideChar(PageCode, 0, strChar.c_str(), -1, pszDest, (int)strChar.length());
  pszDest[strChar.length()] = L'/0';
  strWChar = pszDest;
 }
 return strWChar;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值