//DevUtil.h
// LSPrinterUtil.cpp: implementation of the CLSPrinterUtil class.
//
//
#include "stdafx.h"
#include "LSPrinterUtil.h"
//
// Construction/Destruction
//
CLSPrinterUtil::CLSPrinterUtil()
{
}
CLSPrinterUtil::~CLSPrinterUtil()
{
}
HLOCAL CLSPrinterUtil::AllocMem(const UINT uBytes)
{
HLOCAL hMem = NULL;
hMem = LocalAlloc(LPTR, uBytes);
if (hMem == NULL)
{
ThrowException(_T("LocalAlloc"));
}
return hMem;
}
void CLSPrinterUtil::FreeMem(HLOCAL hMem)
{
if (hMem != NULL)
{
if ( LocalFree(hMem) != NULL )
{
ThrowException(_T("LocalFree"));
}
else
{
hMem = NULL;
}
}
}
void CLSPrinterUtil::PrintPortInfo(PPORT_INFO_2 pPortInfo, DWORD dwPortCount)
{
for (DWORD dwIndex = 0; dwIndex < dwPortCount; dwIndex++)
{
TRACE("PortName: %s/n",pPortInfo[dwIndex].pPortName);
TRACE("MonitorName: %s/n",pPortInfo[dwIndex].pMonitorName);
TRACE("Description: %s/n",pPortInfo[dwIndex].pDescription);
TRACE("PortType: %d/n",pPortInfo[dwIndex].fPortType);
TRACE("/n/n");
}
}
void CLSPrinterUtil::PrintPrinterInfo(LPPRINTER_INFO_2 pPrinterInfo, DWORD dwIndex)
{
TRACE("ServerName: %s/n", pPrinterInfo[dwIndex].pServerName);
TRACE("PrinterName: %s/n", pPrinterInfo[dwIndex].pPrinterName);
TRACE("ShareName: %s/n", pPrinterInfo[dwIndex].pShareName);
TRACE("PortName: %s/n", pPrinterInfo[dwIndex].pPortName);
TRACE("DriverName: %s/n", pPrinterInfo[dwIndex].pDriverName);
TRACE("Comment: %s/n", pPrinterInfo[dwIndex].pComment);
TRACE("Location: %s/n", pPrinterInfo[dwIndex].pLocation);
TRACE("SepFile: %s/n", pPrinterInfo[dwIndex].pSepFile);
TRACE("PrintProcessor: %s/n", pPrinterInfo[dwIndex].pPrintProcessor);
TRACE("DataType: %s/n", pPrinterInfo[dwIndex].pDatatype);
TRACE("Parameters: %s/n", pPrinterInfo[dwIndex].pParameters);
TRACE("Attributes: %d/n", pPrinterInfo[dwIndex].Attributes);
TRACE("Priority: %d/n", pPrinterInfo[dwIndex].Priority);
TRACE("DefaultPriority: %d/n", pPrinterInfo[dwIndex].DefaultPriority);
TRACE("UntilTime: %d/n", pPrinterInfo[dwIndex].UntilTime);
TRACE("Status: %d/n", pPrinterInfo[dwIndex].Status);
TRACE("cJobs: %d/n", pPrinterInfo[dwIndex].cJobs);
TRACE("AveragerPPM: %d/n", pPrinterInfo[dwIndex].AveragePPM);
TRACE("/n/n");
}
PRINTER_TYPE_ENUM CLSPrinterUtil::GetPrinterType(DWORD dwAttribute, DWORD dwPortType)
{
PRINTER_TYPE_ENUM enumPrinterType;
if (dwAttribute & PRINTER_ATTRIBUTE_NETWORK)
{
enumPrinterType = NETWORK_PRINTER;
if ( dwAttribute & PRINTER_ATTRIBUTE_SHARED)
enumPrinterType = SHARE_PRINTER;
}
if (dwAttribute & PRINTER_ATTRIBUTE_LOCAL)
{
enumPrinterType = LOCAL_PRINTER;
//此处判断虚拟打印机
//if ();
}
return enumPrinterType;
}
BOOL CLSPrinterUtil::GetRegString(CString strValueName, CString &strValue)
{
BOOL bReturn = FALSE;
DWORD dwSize = MAX_PATH;
char szString[MAX_PATH];
long lReturn = m_reg.QueryValue(szString, strValueName, &dwSize);
if (lReturn == ERROR_MORE_DATA)
{
char * szNewString = new char[dwSize];
lReturn = m_reg.QueryValue(szNewString, strValueName, &dwSize);
if(ERROR_SUCCESS == lReturn)
{
strValue = szNewString;
delete [] szNewString;
bReturn = TRUE;
}
}
else if(lReturn == ERROR_SUCCESS)
{
strValue = szString;
bReturn = TRUE;
}
return bReturn;
}
BOOL CLSPrinterUtil::GetRegDWORD(CString strValueName, DWORD &dwValue)
{
long lReturn = m_reg.QueryValue(dwValue, strValueName);
if(lReturn==ERROR_SUCCESS)
{
return TRUE;
}
return FALSE;
}
BOOL CLSPrinterUtil::GetAllPrintersInfo(PRINTER_MAP &mPrinter)
{
DWORD dwPortCbNeeded = 0;
DWORD dwPortCount = 0;
PPORT_INFO_2 pPortInfo = NULL;
BOOL bStatus;
EnumPorts(NULL, 2, NULL, 0, &dwPortCbNeeded, &dwPortCount);
pPortInfo = (PPORT_INFO_2)AllocMem(dwPortCbNeeded);
bStatus = EnumPorts(NULL, 2, (LPBYTE)pPortInfo, dwPortCbNeeded, &dwPortCbNeeded, &dwPortCount);
if (!bStatus)
{
FreeMem(pPortInfo);
TRACE("EnumPorts 失败/n");
return bStatus;
}
PrintPortInfo(pPortInfo, dwPortCount);
LPPRINTER_INFO_2 pPrinterInfo = NULL;
DWORD dwPrinterCbNeeded = 0;
DWORD dwPrinterCount = 0;
EnumPrinters( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
NULL,
2,
NULL,
0,
&dwPrinterCbNeeded,
&dwPrinterCount );
pPrinterInfo = (LPPRINTER_INFO_2)AllocMem(dwPrinterCbNeeded);
bStatus = EnumPrinters( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
NULL,
2,
(LPBYTE)pPrinterInfo,
dwPrinterCbNeeded,
&dwPrinterCbNeeded,
&dwPrinterCount );
if (!bStatus)
{
FreeMem(pPortInfo);
FreeMem(pPrinterInfo);
TRACE("EnumPrinters 失败/n");
return bStatus;
}
for (DWORD i = 0; i < dwPrinterCount; ++i)
{
PRINTER_INFO_WRAPPER_ST stPrinterInfo;
stPrinterInfo.strPrinterName = pPrinterInfo[i].pPrinterName;
stPrinterInfo.strServerName = pPrinterInfo[i].pServerName;
stPrinterInfo.strShareName = pPrinterInfo[i].pShareName;
stPrinterInfo.strPortName = pPrinterInfo[i].pPortName;
stPrinterInfo.strDriverName = pPrinterInfo[i].pDriverName;
stPrinterInfo.strPrintProcessor = pPrinterInfo[i].pPrintProcessor;
stPrinterInfo.dwAttribute = pPrinterInfo[i].Attributes;
stPrinterInfo.dwStatus = pPrinterInfo[i].Status;
for (DWORD dwIndex = 0; dwIndex < dwPortCount; dwIndex++)
{
if (stPrinterInfo.strPortName.CompareNoCase(pPortInfo[dwIndex].pPortName) == 0)
{
stPrinterInfo.dwPortType = pPortInfo[dwIndex].fPortType;
stPrinterInfo.strPortDesc = pPortInfo[dwIndex].pDescription;
stPrinterInfo.bInit = TRUE;
if ((stPrinterInfo.dwPortType & PORT_TYPE_NET_ATTACHED) && stPrinterInfo.strServerName.IsEmpty())
{
CString strPath;
strPath.Format("SYSTEM//CurrentControlSet//Control//Print//Monitors//%s//Ports//%s",
stPrinterInfo.strPortDesc, stPrinterInfo.strPortName);
if (m_reg.Open(HKEY_LOCAL_MACHINE, strPath) == ERROR_SUCCESS)
{
CString strServerIp;
DWORD dwPortNumber;
GetRegString(_T("IPAddress"), strServerIp);
GetRegDWORD(_T("PortNumber"), dwPortNumber);
if (!strServerIp.IsEmpty())
{
stPrinterInfo.strServerName.Format("%s:%d", strServerIp, dwPortNumber);
}
m_reg.Close();
}
}
break;
}
}
if (mPrinter.find(pPrinterInfo[i].pPrinterName) == mPrinter.end())
{
mPrinter.insert(make_pair(pPrinterInfo[i].pPrinterName, stPrinterInfo));
}
PrintPrinterInfo(pPrinterInfo, i);
}
FreeMem(pPortInfo);
FreeMem(pPrinterInfo);
return bStatus;
}
BOOL CLSPrinterUtil::GetPrinterInfo(const CString strPrinterName, PRINTER_INFO_WRAPPER_ST& stPrinterInfo)
{
BOOL bStatus = FALSE;
DWORD dwPortCbNeeded = 0;
DWORD dwPortCount = 0;
DWORD dwPrinterCbNeeded = 0;
PPORT_INFO_2 pPortInfo = NULL;
LPPRINTER_INFO_2 pPrinterInfo = NULL;
HANDLE hPrinter = NULL;
if (strPrinterName.IsEmpty())
return bStatus;
EnumPorts(NULL, 2, NULL, 0, &dwPortCbNeeded, &dwPortCount);
pPortInfo = (PPORT_INFO_2)AllocMem(dwPortCbNeeded);
bStatus = EnumPorts(NULL, 2, (LPBYTE)pPortInfo, dwPortCbNeeded, &dwPortCbNeeded, &dwPortCount);
if (!bStatus)
{
FreeMem(pPortInfo);
TRACE("EnumPorts 失败/n");
return bStatus;
}
bStatus = OpenPrinter((char *)(LPCTSTR)strPrinterName, &hPrinter, NULL);
if (!bStatus)
{
FreeMem(pPortInfo);
TRACE("OpenPrinter 失败/n");
return bStatus;
}
GetPrinter(hPrinter, 2, NULL, 0, &dwPrinterCbNeeded);
pPrinterInfo = (LPPRINTER_INFO_2)AllocMem(dwPrinterCbNeeded);
bStatus = GetPrinter(hPrinter, 2, (LPBYTE)pPrinterInfo, dwPrinterCbNeeded, &dwPrinterCbNeeded);
if (!bStatus)
{
FreeMem(pPortInfo);
FreeMem(pPrinterInfo);
TRACE("GetPrinter 失败/n");
return bStatus;
}
stPrinterInfo.strPrinterName = pPrinterInfo->pPrinterName;
stPrinterInfo.strServerName = pPrinterInfo->pServerName;
stPrinterInfo.strShareName = pPrinterInfo->pShareName;
stPrinterInfo.strPortName = pPrinterInfo->pPortName;
stPrinterInfo.strDriverName = pPrinterInfo->pDriverName;
stPrinterInfo.strPrintProcessor = pPrinterInfo->pPrintProcessor;
stPrinterInfo.dwAttribute = pPrinterInfo->Attributes;
stPrinterInfo.dwStatus = pPrinterInfo->Status;
for (DWORD dwIndex = 0; dwIndex < dwPortCount; dwIndex++)
{
if (stPrinterInfo.strPortName.CompareNoCase(pPortInfo[dwIndex].pPortName) == 0)
{
stPrinterInfo.dwPortType = pPortInfo[dwIndex].fPortType;
stPrinterInfo.strPortDesc = pPortInfo[dwIndex].pDescription;
stPrinterInfo.bInit = TRUE;
if((stPrinterInfo.dwPortType & PORT_TYPE_NET_ATTACHED) && stPrinterInfo.strServerName.IsEmpty())
{
CString strPath;
strPath.Format("SYSTEM//CurrentControlSet//Control//Print//Monitors//%s//Ports//%s",
stPrinterInfo.strPortDesc, stPrinterInfo.strPortName);
if (m_reg.Open(HKEY_LOCAL_MACHINE, strPath) == ERROR_SUCCESS)
{
CString strServerIp;
DWORD dwPortNumber;
GetRegString(_T("IPAddress"), strServerIp);
GetRegDWORD(_T("PortNumber"), dwPortNumber);
if (!strServerIp.IsEmpty())
{
stPrinterInfo.strServerName.Format("%s:%d", strServerIp, dwPortNumber);
}
m_reg.Close();
}
}
break;
}
}
FreeMem(pPortInfo);
FreeMem(pPrinterInfo);
return bStatus;
}
BOOL CLSPrinterUtil::IsPrinterHandle(HANDLE hPrinter)
{
DWORD dwCbNeeded;
DWORD dwError;
BOOL bRet;
bRet = GetPrinter(hPrinter, 2, (LPBYTE)NULL, 0, &dwCbNeeded);
if (!bRet)
{
dwError = GetLastError();
if( dwError == ERROR_INSUFFICIENT_BUFFER )
{
bRet = TRUE;
}
}
return bRet;
}
CString CLSPrinterUtil::GetJobStatusStr(DWORD dwStatus)
{
DWORD dwClearWord = 0;
CString strJobStatus;
//由状态位构造状态字符串,当处理完所有的位标识结束
while (dwStatus)
{
//由分割符分割多个状态字符串
if (dwClearWord)
strJobStatus += "-";
if (JOB_STATUS_SPOOLING & dwStatus)
{
strJobStatus += "正在进行后台打印";
dwClearWord |= JOB_STATUS_SPOOLING;
}
else if (JOB_STATUS_ERROR & dwStatus)
{
strJobStatus += "错误";
dwClearWord |= JOB_STATUS_ERROR;
}
else if (JOB_STATUS_PRINTING & dwStatus)
{
strJobStatus += "正在打印";
dwClearWord |= JOB_STATUS_PRINTING;
}
else if (JOB_STATUS_DELETING & dwStatus)
{
strJobStatus += "正在删除";
dwClearWord |= JOB_STATUS_DELETING;
}
else if (JOB_STATUS_PAUSED & dwStatus)
{
strJobStatus += "暂停";
dwClearWord |= JOB_STATUS_PAUSED;
}
else if (JOB_STATUS_PRINTED & dwStatus)
{
strJobStatus += "已打印";
dwClearWord |= JOB_STATUS_PRINTED;
}
else if (JOB_STATUS_DELETED & dwStatus)
{
strJobStatus += "已删除";
dwClearWord |= JOB_STATUS_DELETED;
}
else if (JOB_STATUS_OFFLINE & dwStatus)
{
strJobStatus += "脱机";
dwClearWord |= JOB_STATUS_OFFLINE;
}
else if (JOB_STATUS_PAPEROUT & dwStatus)
{
strJobStatus += "缺纸";
dwClearWord |= JOB_STATUS_PAPEROUT;
}
else if (JOB_STATUS_BLOCKED_DEVQ & dwStatus)
{
strJobStatus += "无法打印";
dwClearWord |= JOB_STATUS_BLOCKED_DEVQ;
}
else if (JOB_STATUS_USER_INTERVENTION & dwStatus)
{
strJobStatus += "需要手动参与";
dwClearWord |= JOB_STATUS_USER_INTERVENTION;
}
else if (JOB_STATUS_RESTART & dwStatus)
{
strJobStatus += "重新启动";
dwClearWord |= JOB_STATUS_RESTART;
}
else
{
strJobStatus += "未知状态";
dwClearWord = dwStatus;
}
//清楚已经处理的标识位
dwStatus = dwStatus & ~dwClearWord;
}
return strJobStatus;
}
DevUtil.CPP
#include "StdAfx.h"
#include "DevUtil.h"
#pragma comment(lib, "Setupapi.lib")
// #pragma comment(lib, "Iphlpapi.lib")
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define SCSIOP_TEST_UNIT_READY 0x00
#define SCSIOP_REZERO_UNIT 0x01
#define SCSIOP_REWIND 0x01
#define SCSIOP_REQUEST_BLOCK_ADDR 0x02
#define SCSIOP_REQUEST_SENSE 0x03
#define SCSIOP_FORMAT_UNIT 0x04
#define SCSIOP_READ_BLOCK_LIMITS 0x05
#define SCSIOP_REASSIGN_BLOCKS 0x07
#define SCSIOP_READ6 0x08
#define SCSIOP_RECEIVE 0x08
#define SCSIOP_WRITE6 0x0A
#define SCSIOP_PRINT 0x0A
#define SCSIOP_SEND 0x0A
#define SCSIOP_SEEK6 0x0B
#define SCSIOP_TRACK_SELECT 0x0B
#define SCSIOP_SLEW_PRINT 0x0B
#define SCSIOP_SEEK_BLOCK 0x0C
#define SCSIOP_PARTITION 0x0D
#define SCSIOP_READ_REVERSE 0x0F
#define SCSIOP_WRITE_FILEMARKS 0x10
#define SCSIOP_FLUSH_BUFFER 0x10
#define SCSIOP_SPACE 0x11
#define SCSIOP_INQUIRY 0x12
#define SCSIOP_VERIFY6 0x13
#define SCSIOP_RECOVER_BUF_DATA 0x14
#define SCSIOP_MODE_SELECT 0x15
#define SCSIOP_RESERVE_UNIT 0x16
#define SCSIOP_RELEASE_UNIT 0x17
#define SCSIOP_COPY 0x18
#define SCSIOP_ERASE 0x19
#define SCSIOP_MODE_SENSE 0x1A
#define SCSIOP_START_STOP_UNIT 0x1B
#define SCSIOP_STOP_PRINT 0x1B
#define SCSIOP_LOAD_UNLOAD 0x1B
#define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C
#define SCSIOP_SEND_DIAGNOSTIC 0x1D
#define SCSIOP_MEDIUM_REMOVAL 0x1E
#define SCSIOP_READ_CAPACITY 0x25
#define SCSIOP_READ 0x28
#define SCSIOP_WRITE 0x2A
#define SCSIOP_SEEK 0x2B
#define SCSIOP_LOCATE 0x2B
#define SCSIOP_WRITE_VERIFY 0x2E
#define SCSIOP_VERIFY 0x2F
#define SCSIOP_SEARCH_DATA_HIGH 0x30
#define SCSIOP_SEARCH_DATA_EQUAL 0x31
#define SCSIOP_SEARCH_DATA_LOW 0x32
#define SCSIOP_SET_LIMITS 0x33
#define SCSIOP_READ_POSITION 0x34
#define SCSIOP_SYNCHRONIZE_CACHE 0x35
#define SCSIOP_COMPARE 0x39
#define SCSIOP_COPY_COMPARE 0x3A
#define SCSIOP_WRITE_DATA_BUFF 0x3B
#define SCSIOP_READ_DATA_BUFF 0x3C
#define SCSIOP_CHANGE_DEFINITION 0x40
#define SCSIOP_READ_SUB_CHANNEL 0x42
#define SCSIOP_READ_TOC 0x43
#define SCSIOP_READ_HEADER 0x44
#define SCSIOP_PLAY_AUDIO 0x45
#define SCSIOP_PLAY_AUDIO_MSF 0x47
#define SCSIOP_PLAY_TRACK_INDEX 0x48
#define SCSIOP_PLAY_TRACK_RELATIVE 0x49
#define SCSIOP_PAUSE_RESUME 0x4B
#define SCSIOP_LOG_SELECT 0x4C
#define SCSIOP_LOG_SENSE 0x4D
#define MODE_PAGE_CAPABILITIES 0x2A
#define NET_CARD_KEY "System//CurrentControlSet//Control//Network//{4D36E972-E325-11CE-BFC1-08002BE10318}"
#define LSS_DEVICE_NAME_DELIMITER ";"
#define CDB6GENERIC_LENGTH 6
#define CDB10GENERIC_LENGTH 10
CDeviceUtil::CDeviceUtil()
{
m_hDevInfo = NULL;
m_mDevGuid[DEVICE_NETCARD_TYPE] = GuidToString(GUID_DEVCLASS_NET);
m_mDevGuid[DEVICE_PORT_TYPE] = GuidToString(GUID_DEVCLASS_PORTS);
m_mDevGuid[DEVICE_USB_STORAGE_TYPE] = GuidToString(GUID_DEVCLASS_USB);
m_mDevGuid[DEVICE_ROM_TYPE] = GuidToString(GUID_DEVCLASS_CDROM);
m_mDevGuid[DEVICE_PCMCIA_TYPE] = GuidToString(GUID_DEVCLASS_PCMCIA);
m_mDevGuid[DEVICE_SMARTCARD_TYPE] = GuidToString(GUID_DEVCLASS_SMARTCARDREADER);
m_mDevGuid[DEVICE_INFRARED_TYPE] = GuidToString(GUID_DEVCLASS_INFRARED);
// m_mDevGuid[DEVICE_BLUETOOTH_TYPE] = GuidToString(GUID_DEVCLASS_BLUETOOTH);
//从注册表中读取第三方厂商的蓝牙设备类别。
m_mDevGuid[DEVICE_BLUETOOTH_IVT_TYPE] = "{F12D3CF8-B11D-457E-8641-BE2AF2D6D204}";
m_mDevGuid[DEVICE_BLUETOOTH_WCDM_TYPE] = "{95C7A0A0-3094-11D7-A202-00508B9D7D5A}";
m_mDevGuid[DEVICE_MODEM_TYPE] = GuidToString(GUID_DEVCLASS_MODEM);
m_mDevGuid[DEVICE_FLOPPY_TYPE] = GuidToString(GUID_DEVCLASS_FDC);
m_mDevGuid[DEVICE_1394_TYPE] = GuidToString(GUID_DEVCLASS_1394);
m_mDevGuid[DEVICE_GRAPHIC_TYPE] = GuidToString(GUID_DEVCLASS_IMAGE);
m_mDevGuid[DEVICE_USB_HOSTCTL_TYPE] = GuidToString(GUID_DEVCLASS_USB);
}
CDeviceUtil::~CDeviceUtil()
{
if (m_hDevInfo != NULL)
{
SetupDiDestroyDeviceInfoList(m_hDevInfo);
m_hDevInfo = NULL;
}
}
CString CDeviceUtil::GuidToString(GUID guid)
{
char buf[64] = {0};
CString strGuid;
_snprintf( buf,
sizeof(buf),
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid.Data1,
guid.Data2,
guid.Data3,
guid.Data4[0], guid.Data4[1],
guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5],
guid.Data4[6], guid.Data4[7]);
strGuid = buf;
return strGuid;
}
void CDeviceUtil::GetDeviceinfo(const GUID* classGuid, DWORD dwFlag)
{
SP_DEVINFO_DATA hDeviceInfoData;
m_vDeviceInfo.clear();
if (m_hDevInfo != NULL)
{
SetupDiDestroyDeviceInfoList(m_hDevInfo);
m_hDevInfo = NULL;
}
m_hDevInfo = SetupDiGetClassDevs( classGuid, // All Classes
0,
0,
dwFlag );
if (m_hDevInfo == INVALID_HANDLE_VALUE)
return ;
hDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(m_hDevInfo, i, &hDeviceInfoData); i++)
{
DEVICE_INFO_ST stDeviceInfo;
stDeviceInfo.strDesc = GetDeviceProperty(hDeviceInfoData, SPDRP_DEVICEDESC);
stDeviceInfo.strClassGuid = GetDeviceProperty(hDeviceInfoData, SPDRP_CLASSGUID);
stDeviceInfo.strDriver = GetDeviceProperty(hDeviceInfoData, SPDRP_DRIVER);
stDeviceInfo.strFName = GetDeviceProperty(hDeviceInfoData, SPDRP_FRIENDLYNAME);
stDeviceInfo.strHID = GetDeviceProperty(hDeviceInfoData, SPDRP_HARDWAREID);
stDeviceInfo.hDeviceInfoData = hDeviceInfoData;
m_vDeviceInfo.push_back(stDeviceInfo);
}
}
CString CDeviceUtil::GetDeviceProperty(SP_DEVINFO_DATA &hDeviceInfoData, DWORD dwProperty)
{
CString strProperty;
DWORD dwData;
DWORD dwSize = 4096;
LPTSTR buffer = (char *)LocalAlloc(LPTR, dwSize);
while (!SetupDiGetDeviceRegistryProperty( m_hDevInfo,
&hDeviceInfoData,
dwProperty,
&dwData,
(PBYTE)buffer,
dwSize,
&dwSize ))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer != NULL)
LocalFree(buffer);
buffer = (char *)LocalAlloc(LPTR, dwSize*2);
}
else
{
break;
}
}
strProperty = buffer;
if (buffer != NULL)
LocalFree(buffer);
return strProperty;
}
BOOL CDeviceUtil::IsDeviceForbid(SP_DEVINFO_DATA hDeviceInfoData)
{
DWORD dwStatus = -1;
DWORD dwProblenNumber = -1;
DWORD dwResult;
BOOL bReturn = FALSE;
dwResult = CM_Get_DevNode_Status(&dwStatus, &dwProblenNumber, hDeviceInfoData.DevInst, 0);
if (CR_SUCCESS == dwResult)
{
if (dwProblenNumber == CM_PROB_DISABLED || (dwStatus & DN_HAS_PROBLEM) != 0)
bReturn = TRUE;
}
return bReturn;
}
BOOL CDeviceUtil::ChangeDeviceState(SP_DEVINFO_DATA hDeviceInfoData, DWORD dwState)
{
try{
BOOL bResult = FALSE;
SP_PROPCHANGE_PARAMS pcpParams;
pcpParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
pcpParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
pcpParams.StateChange = dwState;
pcpParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
pcpParams.HwProfile = 0;
bResult = SetupDiSetClassInstallParams( m_hDevInfo,
&hDeviceInfoData,
(PSP_CLASSINSTALL_HEADER)&pcpParams,
sizeof(pcpParams) );
if(bResult == FALSE)
return bResult;
bResult = SetupDiChangeState(m_hDevInfo, &hDeviceInfoData);
return bResult;
}
catch (...)
{
return FALSE;
}
}
BOOL CDeviceUtil::StringPatternMatch(const char *szText, const char *szPattern)
{
char c;
for ( ; ; )
{
c = *szPattern++;
if (c == '/0')
{
return *szText == '/0';
}
else if (c == '?')
{
if (*szText == '/0' || *szText == '//')
{
return FALSE;
}
szText++;
}
else if (c == '*')
{
const char *s;
if (*szPattern == '/0')
{
return TRUE;
}
s = szText;
while (*s != '/0')
{
if (toupper(*s) == toupper(*szPattern) && StringPatternMatch(s, szPattern))
{
return TRUE;
}
if (*s == '//')
{
break;
}
s++;
}
}
else if (c == '//')
{
if (*szText != '//')
{
return FALSE;
}
while(*szText == '//')
{
szText++;
}
}
else
{
if (toupper(*szText++) != toupper(c))
{
return FALSE;
}
}
}
return FALSE;
}
BOOL CDeviceUtil::IsRedundantNetCard(const CString &strDeviceDesc, const CString &strAdapterName)
{
BOOL ret = FALSE;
for (vector<NETWORK_MAC_INFO_ST>::iterator it = m_vNetworkMacInfo.begin();
it != m_vNetworkMacInfo.end();
it++)
{
if (strDeviceDesc.CompareNoCase(it->strDeviceDesc) == 0)
{
CString strAdap = it->strAdapterName;
if (strAdapterName.CompareNoCase(it->strAdapterName) != 0)
{
ret = TRUE;
}
break;
}
}
return ret;
}
BOOL CDeviceUtil::IsWirelessNetCard(const CString &strDeviceDesc, const CString &strAdapterName)
{
BOOL ret = FALSE;
CString strDesc;
strDesc = NetDesChinToEng(strDeviceDesc); //由于在win7上 设备描述不匹配 所以中文名称转换成相应的英文名称
//如果没有匹配 则不进行转换
for (vector<NETWORK_MAC_INFO_ST>::iterator it = m_vNetworkMacInfo.begin();
it != m_vNetworkMacInfo.end();
it++)
{
if (strDesc.CompareNoCase(it->strDeviceDesc) == 0)
{
if (it->IsWireless)
{
if (strAdapterName.CompareNoCase(it->strAdapterName) != 0)
{
ret = TRUE;
}
break;
}
}
}
return ret;
}
BOOL CDeviceUtil::IsCdromRecorder(const CString &strDeviceFName)
{
BOOL ret = FALSE;
for (vector<CDROM_INFO_ST>::iterator it = m_vCDRomInfo.begin();
it != m_vCDRomInfo.end();
it++)
{
if (strDeviceFName.CompareNoCase(it->strDeviceFName) == 0)
{
if (it->isCdRecorder || it->isDvdRecorder)
{
ret = TRUE;
}
break;
}
}
return ret;
}
void CDeviceUtil::SetBindAdapterGUID(CString strBindAdapterGUID)
{
m_strBindAdapterGUID = strBindAdapterGUID;
}
BOOL CDeviceUtil::HandleDevice(DEVICE_TYPE_ENUM enDeviceType,
DWORD dwType,
DEVICE_RESPONSE_INFO_VECTOR &vDevRespInfo,
DEVICE_TYPE_ENUM enSubDeviceType )
{
BOOL bFind = FALSE;
BOOL bReturn = FALSE;
for (vector<DEVICE_INFO_ST>::iterator it = m_vDeviceInfo.begin(); it != m_vDeviceInfo.end(); ++it)
{
if (enDeviceType == DEVICE_BLUETOOTH_TYPE) //特殊处理蓝牙设备
{
if (it->strClassGuid.CompareNoCase(m_mDevGuid[DEVICE_BLUETOOTH_TYPE]) == 0 ||
it->strClassGuid.CompareNoCase(m_mDevGuid[DEVICE_BLUETOOTH_IVT_TYPE]) == 0 ||
it->strClassGuid.CompareNoCase(m_mDevGuid[DEVICE_BLUETOOTH_WCDM_TYPE]) == 0)
bFind = TRUE;
else if (it->strDesc.Find("Bluetooth ") ==0)
bFind = TRUE;
}
else if (it->strClassGuid.CompareNoCase(m_mDevGuid[enDeviceType]) == 0)
{
switch (enDeviceType)
{
case DEVICE_NETCARD_TYPE:
{
switch (enSubDeviceType)
{
case DEVICE_WIRELESS_NETCARD_TYPE:
{
if (IsWirelessNetCard(it->strDesc, m_strBindAdapterGUID))
{
bFind = TRUE;
}
}
break;
case DEVICE_MULTI_NETCARD_TYPE:
{
if (IsRedundantNetCard(it->strDesc, m_strBindAdapterGUID))
{
bFind = TRUE;
}
}
break;
}
}
break;
case DEVICE_USB_STORAGE_TYPE:
{
if (it->strDesc.CompareNoCase("USB Mass Storage Device") == 0 ||
it->strDesc.CompareNoCase("USB 大容量存储设备") == 0)
{
if (it->strFName.Find("SUFD_CBM") == -1) //判断设备是否为 圣博润的U盘驱动,是的话不禁止
{
bFind = TRUE;
}
}
}
break;
case DEVICE_USB_HOSTCTL_TYPE:
{
if (it->strDesc.Find("Host Controller") != -1)
{
bFind = TRUE;
}
}
case DEVICE_ROM_TYPE:
{
switch (enSubDeviceType)
{
case DEVICE_CDROM_TYPE:
{
if (!IsCdromRecorder(it->strFName))
bFind = TRUE;
}
break;
case DEVICE_CDRW_TYPE:
{
if (IsCdromRecorder(it->strFName))
bFind = TRUE;
}
break;
}
}
break;
case DEVICE_PORT_TYPE:
{
int iIndex;
switch (enSubDeviceType)
{
case DEVICE_LPT_PORT_TYPE:
{
iIndex = it->strDesc.Find("打印机端口");
if (iIndex >= 0)
bFind = TRUE;
else
{
if (StringPatternMatch((LPCTSTR)it->strFName, "*(LPT*)"))
{
bFind = TRUE;
}
}
}
break;
case DEVICE_COM_PORT_TYPE:
{
iIndex = it->strDesc.Find("通讯端口");
if (iIndex >= 0)
bFind = TRUE;
else
{
if (StringPatternMatch((LPCTSTR)it->strFName, "*(COM*)"))
{
bFind = TRUE;
}
}
}
break;
}
}
break;
case DEVICE_INFRARED_TYPE:
case DEVICE_MODEM_TYPE:
case DEVICE_FLOPPY_TYPE:
case DEVICE_PCMCIA_TYPE:
case DEVICE_SMARTCARD_TYPE:
case DEVICE_1394_TYPE:
case DEVICE_GRAPHIC_TYPE:
{
bFind = TRUE;
}
break;
default:
break;
}
}
if (bFind)
{
switch (dwType)
{
case 0: //禁用
{
if (!IsDeviceForbid(it->hDeviceInfoData))
{
if (ChangeDeviceState(it->hDeviceInfoData, DICS_DISABLE))
{
DEVICE_RESPONSE_INFO_ST stDevRespInfo;
stDevRespInfo.strDeviceDesc = it->strDesc;
stDevRespInfo.strDeviceFName = it->strFName;
stDevRespInfo.strDeviceID = it->strHID;
vDevRespInfo.push_back(stDevRespInfo);
bReturn = TRUE;
}
}
}
break;
case 2: //强制启用
{
if (IsDeviceForbid(it->hDeviceInfoData))
{
if (ChangeDeviceState(it->hDeviceInfoData, DICS_ENABLE))
{
DEVICE_RESPONSE_INFO_ST stDevRespInfo;
stDevRespInfo.strDeviceDesc = it->strDesc;
stDevRespInfo.strDeviceFName = it->strFName;
stDevRespInfo.strDeviceID = it->strHID;
vDevRespInfo.push_back(stDevRespInfo);
bReturn = TRUE;
}
}
}
break;
}
bFind = FALSE;
}
}
return bReturn;
}
BOOL CDeviceUtil::SetDeviceState( DEVICE_TYPE_ENUM enDeviceType,
DWORD dwType,
DEVICE_RESPONSE_INFO_VECTOR &vDevRespInfo)
{
BOOL bReturn = FALSE;
if (vDevRespInfo.size())
vDevRespInfo.clear();
switch (enDeviceType)
{
case DEVICE_MULTI_NETCARD_TYPE:
case DEVICE_WIRELESS_NETCARD_TYPE:
{
bReturn = HandleDevice(DEVICE_NETCARD_TYPE, dwType, vDevRespInfo, enDeviceType);
}
break;
case DEVICE_CDROM_TYPE:
case DEVICE_CDRW_TYPE:
{
bReturn = HandleDevice(DEVICE_ROM_TYPE, dwType, vDevRespInfo, enDeviceType);
}
break;
case DEVICE_COM_PORT_TYPE:
case DEVICE_LPT_PORT_TYPE:
{
bReturn = HandleDevice(DEVICE_PORT_TYPE, dwType, vDevRespInfo, enDeviceType);
}
break;
case DEVICE_BLUETOOTH_TYPE:
case DEVICE_USB_STORAGE_TYPE:
case DEVICE_INFRARED_TYPE:
case DEVICE_MODEM_TYPE:
case DEVICE_FLOPPY_TYPE:
case DEVICE_PCMCIA_TYPE:
case DEVICE_SMARTCARD_TYPE:
case DEVICE_1394_TYPE:
case DEVICE_GRAPHIC_TYPE:
case DEVICE_USB_HOSTCTL_TYPE:
{
bReturn = HandleDevice(enDeviceType, dwType, vDevRespInfo);
}
break;
default:
break;
}
return bReturn;
}
BOOL CDeviceUtil::GetAllCdromInfo()
{
vector<DEVICE_INFO_ST>::iterator itor;
CDROM_INFO_ST stCDRominfo;
BOOL bReturn = TRUE;
m_vCDRomInfo.clear();
for( itor = m_vDeviceInfo.begin(); itor != m_vDeviceInfo.end(); itor++ )
{
if( itor->strClassGuid.CompareNoCase(m_mDevGuid[DEVICE_ROM_TYPE]) == 0 )
{
stCDRominfo.hDeviceInfoData = itor->hDeviceInfoData;
if( IsDeviceForbid(itor->hDeviceInfoData) )
{
stCDRominfo.isInitStop = TRUE;
bReturn = ChangeDeviceState(itor->hDeviceInfoData, DICS_ENABLE);
if( bReturn == FALSE )
break;
}
else
{
stCDRominfo.isInitStop = FALSE;
}
if( !((itor->strFName).IsEmpty()) )
{
CString strDeviceFName;
strDeviceFName = itor->strFName;
stCDRominfo.strDeviceFName = strDeviceFName;
stCDRominfo.strDeviceId = itor->strHID;
stCDRominfo.strDriver = itor->strDriver;
strDeviceFName.TrimLeft();
strDeviceFName.TrimRight();
strDeviceFName.Replace(" ",";");
stCDRominfo.filterDeviceName = FilterDeviceName(strDeviceFName);
stCDRominfo.isCdRecorder = FALSE;
stCDRominfo.isDvdRecorder = FALSE;
m_vCDRomInfo.push_back(stCDRominfo);
}
}
}
SetCdromRecorder();
vector<CDROM_INFO_ST>::iterator itorCD;
for( itorCD = m_vCDRomInfo.begin(); itorCD != m_vCDRomInfo.end(); itorCD++ )
{
if( itorCD->isInitStop == TRUE )
{
bReturn = ChangeDeviceState(itorCD->hDeviceInfoData, DICS_DISABLE);
}
}
return bReturn;
}
void CDeviceUtil::GetAllNetCardInfo()
{
// m_vNetworkMacInfo.clear();
//
// PIP_ADAPTER_INFO pInfo=NULL,pInfoTemp=NULL;
// ULONG ulSize=0;
// GetAdaptersInfo(pInfo,&ulSize);//第一次调用,获取缓冲区大小
// pInfoTemp=pInfo=(PIP_ADAPTER_INFO)new(char[ulSize]);
// GetAdaptersInfo(pInfo,&ulSize);
//
// //遍历每一张网卡
// while(pInfo)
// {
// NETWORK_MAC_INFO_ST stNetInfo;
// stNetInfo.strAdapterName = pInfo->AdapterName;
// stNetInfo.strDeviceDesc = pInfo->Description;
//
// if ( IsWirelessAdapter(stNetInfo.strAdapterName) )
// stNetInfo.IsWireless = TRUE;
// else
// stNetInfo.IsWireless = FALSE;
//
// m_vNetworkMacInfo.push_back(stNetInfo);
//
// pInfo=pInfo->Next;
//
// }
// delete pInfoTemp;//回收无用内存
}
CString CDeviceUtil::NetDesChinToEng(const CString& strDescrption)
{
CString strEngDescrp = strDescrption;
CString strFindWirless = "无线";
CString strFindConnection = "网络连接";
if( strDescrption.Find(strFindWirless) == -1)
return strEngDescrp;
strEngDescrp.Replace(strFindWirless, "Wireless");
strEngDescrp.Replace(strFindConnection, "Network Connection");
return strEngDescrp;
}
BOOL CDeviceUtil::RemoveDevManagePrivilege()
{
try
{
SECURITY_QUALITY_OF_SERVICE sqos;
LSA_OBJECT_ATTRIBUTES lsaOA;
LSA_HANDLE hPolicy;
NTSTATUS ntsResult;
sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
sqos.ImpersonationLevel = SecurityImpersonation;
sqos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
sqos.EffectiveOnly = FALSE;
lsaOA.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
lsaOA.RootDirectory = NULL;
lsaOA.ObjectName = NULL;
lsaOA.Attributes = 0;
lsaOA.SecurityDescriptor = NULL;
lsaOA.SecurityQualityOfService = &sqos;
ntsResult = LsaOpenPolicy( NULL,
&lsaOA,
POLICY_ALL_ACCESS,
&hPolicy );
if (ntsResult != 0)
{
return FALSE;
}
LSA_UNICODE_STRING lucPrivilege;
InitLsaString(&lucPrivilege, L"SeLoadDriverPrivilege");
PLSA_ENUMERATION_INFORMATION pLsaEnumInfo;
DWORD dw;
LsaEnumerateAccountsWithUserRight(hPolicy, &lucPrivilege, (void **)&pLsaEnumInfo, &dw);
for (DWORD i =0 ; i<dw;i++)
{
ntsResult = LsaRemoveAccountRights(hPolicy, pLsaEnumInfo->Sid, FALSE, &lucPrivilege, 1);
if (ntsResult != STATUS_SUCCESS)
{
LsaClose(hPolicy);
return FALSE;
}
pLsaEnumInfo++;
}
LsaClose(hPolicy);
return TRUE;
}
catch(...)
{
return FALSE;
}
}
BOOL CDeviceUtil::AddDevManagePrivilege()
{
try
{
SECURITY_QUALITY_OF_SERVICE sqos;
LSA_OBJECT_ATTRIBUTES lsaOA;
LSA_HANDLE hPolicy;
NTSTATUS ntsResult;
sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
sqos.ImpersonationLevel = SecurityImpersonation;
sqos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
sqos.EffectiveOnly = FALSE;
lsaOA.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
lsaOA.RootDirectory = NULL;
lsaOA.ObjectName = NULL;
lsaOA.Attributes = 0;
lsaOA.SecurityDescriptor = NULL;
lsaOA.SecurityQualityOfService = &sqos;
ntsResult = LsaOpenPolicy( NULL,
&lsaOA,
POLICY_ALL_ACCESS,
&hPolicy );
if (ntsResult != 0)
{
return FALSE;
}
LSA_UNICODE_STRING lucPrivilege;
// Create an LSA_UNICODE_STRING for the privilege name(s).
InitLsaString(&lucPrivilege, L"SeLoadDriverPrivilege");
SID * adminSID[2];
GetSid((const unsigned short *)"Administrators", (void **)&adminSID[0]);
ntsResult = LsaAddAccountRights( hPolicy, // An open policy handle.
adminSID[0], // The target SID.
&lucPrivilege, // The privilege(s).
1 ); // Number of privileges.
if (ntsResult == STATUS_SUCCESS)
{
LsaClose(hPolicy);
return TRUE;
}
else
{
wprintf(L"Privilege was not added - %lu /n", LsaNtStatusToWinError(ntsResult));
LsaClose(hPolicy);
return FALSE;
}
}
catch(...)
{
return FALSE;
}
}
void CDeviceUtil::InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String)
{
try
{
USHORT StringLength;
if (String == NULL)
{
LsaString->Buffer = NULL;
LsaString->Length = 0;
LsaString->MaximumLength = 0;
return;
}
// Get the length of the string without the null terminator.
StringLength = wcslen(String);
// Store the string.
LsaString->Buffer = String;
LsaString->Length = StringLength * sizeof(WCHAR);
LsaString->MaximumLength= (StringLength+1) * sizeof(WCHAR);
}
catch(...)
{
return;
}
}
BOOL CDeviceUtil::GetSid(LPCWSTR wszAccName, PSID *ppSid)
{
try
{
// Create buffers that may be large enough.
// If a buffer is too small, the count parameter will be set to the size needed.
const DWORD INITIAL_SIZE = 32;
DWORD cbSid = 0;
DWORD dwSidBufferSize = INITIAL_SIZE;
DWORD cchDomainName = 0;
DWORD dwDomainBufferSize = INITIAL_SIZE;
WCHAR *wszDomainName = NULL;
SID_NAME_USE eSidType;
DWORD dwErrorCode = 0;
// Create buffers for the SID and the domain name.
*ppSid = (PSID) new BYTE[dwSidBufferSize];
if (*ppSid == NULL)
{
return FALSE;
}
memset(*ppSid, 0, dwSidBufferSize);
wszDomainName = new WCHAR[dwDomainBufferSize];
if (wszDomainName == NULL)
{
return FALSE;
}
memset(wszDomainName, 0, dwDomainBufferSize*sizeof(WCHAR));
// Obtain the SID for the account name passed.
for ( ; ; )
{
// Set the count variables to the buffer sizes and retrieve the SID.
cbSid = dwSidBufferSize;
cchDomainName = dwDomainBufferSize;
if (LookupAccountNameW( NULL, // Computer name. NULL for the local computer
L"Administrators",
*ppSid, // Pointer to the SID buffer. Use NULL to get the size needed,
&cbSid, // Size of the SID buffer needed.
wszDomainName, // wszDomainName,
&cchDomainName,
&eSidType ))
{
if (!IsValidSid(*ppSid))
{
wprintf(L"The SID for %s is invalid./n", wszAccName);
}
break;
}
dwErrorCode = GetLastError();
// Check if one of the buffers was too small.
if (dwErrorCode == ERROR_INSUFFICIENT_BUFFER)
{
if (cbSid > dwSidBufferSize)
{
// Reallocate memory for the SID buffer.
wprintf(L"The SID buffer was too small. It will be reallocated./n");
FreeSid(*ppSid);
*ppSid = (PSID) new BYTE[cbSid];
if (*ppSid == NULL)
{
return FALSE;
}
memset(*ppSid, 0, cbSid);
dwSidBufferSize = cbSid;
}
if (cchDomainName > dwDomainBufferSize)
{
// Reallocate memory for the domain name buffer.
wprintf(L"The domain name buffer was too small. It will be reallocated./n");
delete [] wszDomainName;
wszDomainName = new WCHAR[cchDomainName];
if (wszDomainName == NULL)
{
return FALSE;
}
memset(wszDomainName, 0, cchDomainName*sizeof(WCHAR));
dwDomainBufferSize = cchDomainName;
}
}
else
{
wprintf(L"LookupAccountNameW failed. GetLastError returned: %d/n", dwErrorCode);
break;
}
}
delete [] wszDomainName;
return TRUE;
}
catch (...)
{
return FALSE;
}
}
BOOL CDeviceUtil::IsWirelessAdapter(const CString &pAdapterName)
{
BOOL ret_value = FALSE;
char szDataBuf[MAX_PATH+1];
HKEY hNetKey = NULL;
HKEY hLocalNet = NULL;
DWORD dwType;
DWORD dwSize=sizeof(DWORD);
DWORD dwDest =0;
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, NET_CARD_KEY, 0, KEY_READ, &hNetKey))
return ret_value;
sprintf(szDataBuf, "%s//Connection", pAdapterName);
if (ERROR_SUCCESS != RegOpenKeyEx(hNetKey ,szDataBuf ,0 ,KEY_READ, &hLocalNet))
{
RegCloseKey(hNetKey);
return ret_value;
}
if (ERROR_SUCCESS != RegQueryValueEx(hLocalNet, "MediaSubType", 0, &dwType, (BYTE *)&dwDest, &dwSize))
{
RegCloseKey(hLocalNet);
RegCloseKey(hNetKey);
return ret_value;
}
if (dwDest == 0x02)
ret_value = TRUE;
RegCloseKey(hLocalNet);
RegCloseKey(hNetKey);
return ret_value;
}
BOOL CDeviceUtil::SetCdromRecorder()
{
CString cdRomDevicePath;
SP_DEVICE_INTERFACE_DATA interfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData = NULL;
SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
HANDLE hDevice;
BOOL status;
ULONG length = 0,returned = 0,cdType = 0;
DWORD interfaceDetailDataSize,reqSize,errorCode,j;
// 获取光驱interface device集合
HDEVINFO hIntDevInfo = SetupDiGetClassDevs ( (LPGUID)&CdRomClassGuid,
NULL,
NULL,
(DIGCF_PRESENT | DIGCF_INTERFACEDEVICE ));
if ( hIntDevInfo == INVALID_HANDLE_VALUE )
{
return FALSE;
}
interfaceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);
// 枚举光驱设备
for ( j = 0;
SetupDiEnumDeviceInterfaces ( hIntDevInfo, // Interface Device Info handle
0, // Device Info data
(LPGUID)&CdRomClassGuid, // Interface registered by driver
j, // Member
&interfaceData); // Device Interface Data
j++ )
{
// 初始
BOOL bIsCdWriter = FALSE;
BOOL bIsDvdWriter = FALSE;
//
// Find out required buffer size, so pass NULL
//
status = SetupDiGetDeviceInterfaceDetail ( hIntDevInfo, // Interface Device info handle
&interfaceData, // Interface data for the event class
NULL, // Checking for buffer size
0, // Checking for buffer size
&reqSize, // Buffer size required to get the detail data
NULL ); // Checking for buffer size
//
// This call returns ERROR_INSUFFICIENT_BUFFER with reqSize
// set to the required buffer size. Ignore the above error and
// pass a bigger buffer to get the detail data
//
if (!status)
{
errorCode = GetLastError();
if ( errorCode != ERROR_INSUFFICIENT_BUFFER )
{
return FALSE;
}
}
//
// Allocate memory to get the interface detail data
// This contains the devicepath we need to open the device
//
interfaceDetailDataSize = reqSize;
interfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) GlobalAlloc(GPTR, interfaceDetailDataSize);
if (interfaceDetailData == NULL)
{
return FALSE;
}
interfaceDetailData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);
status = SetupDiGetDeviceInterfaceDetail( hIntDevInfo, // Interface Device info handle
&interfaceData, // Interface data for the event class
interfaceDetailData, // Interface detail data
interfaceDetailDataSize, // Interface detail data size
&reqSize, // Buffer size required to get the detail data
NULL ); // Interface device info
if (!status)
{
return FALSE;
}
//
// Now we have the device path. Open the device interface
// to send Pass Through command
cdRomDevicePath = interfaceDetailData->DevicePath;
hDevice = CreateFile( interfaceDetailData->DevicePath, // device interface name
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDistribution
0, // dwFlagsAndAttributes
NULL ); // hTemplateFile
//
// We have the handle to talk to the device.
// So we can release the interfaceDetailData buffer
//
GlobalFree (interfaceDetailData);
if (hDevice == INVALID_HANDLE_VALUE)
{
return FALSE;
}
ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH);
sptwb.Spt.PathId = 0;
sptwb.Spt.TargetId = 1;
sptwb.Spt.Lun = 0;
sptwb.Spt.CdbLength = CDB6GENERIC_LENGTH;
sptwb.Spt.SenseInfoLength = 24;
sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN;
sptwb.Spt.DataTransferLength = 192;
sptwb.Spt.TimeOutValue = 2;
sptwb.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,DataBuf);
sptwb.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,SenseBuf);
sptwb.Spt.Cdb[0] = SCSIOP_INQUIRY;
sptwb.Spt.Cdb[4] = 192;
length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,DataBuf) + sptwb.Spt.DataTransferLength;
status = DeviceIoControl( hDevice,
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH),
&sptwb,
length,
&returned,
FALSE );
// If device supports SCSI-3, then we can get the CD drive capabilities, i.e. ability to
// read/write to CD-ROM/R/RW or/and read/write to DVD-ROM/R/RW.
// Use the previous spti structure, only modify the command to "mode sense"
sptwb.Spt.Cdb[0] = SCSIOP_MODE_SENSE;
sptwb.Spt.Cdb[1] = 0x08; // target shall not return any block descriptors
sptwb.Spt.Cdb[2] = MODE_PAGE_CAPABILITIES;
status = DeviceIoControl( hDevice,
IOCTL_SCSI_PASS_THROUGH,
&sptwb,
sizeof(SCSI_PASS_THROUGH),
&sptwb,
length,
&returned,
FALSE );
// 开始判断cd可写光驱或者dvd可写光驱
UCHAR CDwriter, DVDwriter;
if (!status )
{
return FALSE;
}
if (sptwb.Spt.ScsiStatus)
{
return FALSE;
}
else
{
if (CDwriter=((sptwb.DataBuf[7] & 0x01)||(sptwb.DataBuf[7] & 0x02)))
{
bIsCdWriter = TRUE;
}
else
{
bIsCdWriter = FALSE;
}
if (DVDwriter=((sptwb.DataBuf[7] & 0x10)||(sptwb.DataBuf[7] & 0x20)))
{
bIsDvdWriter = TRUE;
}
else
{
bIsDvdWriter = FALSE;
}
}
// m_cdRomIsRecorder设置设备路径、是否cd刻录机,是否dvd刻录机
if (j<m_vCDRomInfo.size())
{
m_vCDRomInfo[j].strDevicePath = cdRomDevicePath;
m_vCDRomInfo[j].isCdRecorder = bIsCdWriter;
m_vCDRomInfo[j].isDvdRecorder = bIsDvdWriter;
}
CloseHandle(hDevice);
}
if (hIntDevInfo != NULL)
{
SetupDiDestroyDeviceInfoList(hIntDevInfo);
hIntDevInfo = NULL;
}
return TRUE;
}
vector<CString> CDeviceUtil::FilterDeviceName(const CString &strDeviceName)
{
vector <CString> VFilterDeviceName;
CStringArray szArr;
CString szTemp;
int nArrSize = 0;
nArrSize = SplitStringWithEx(strDeviceName, szArr, LSS_DEVICE_NAME_DELIMITER);
for(int i = 0; i < nArrSize; i++)
{
szTemp = szArr[i];
if (szTemp.IsEmpty())
{
continue;
}
szTemp.MakeLower();
VFilterDeviceName.push_back(szTemp);
}
return VFilterDeviceName;
}
int CDeviceUtil::SplitStringWithEx(const CString &strTarget, CStringArray &strArray, const CString &strTag)
{
int iCount = 0;
if (strTarget.IsEmpty())
{
return 0;
}
try
{
CString strTemp = strTarget;
int nPos = strTemp.Find(strTag);
if (nPos > 0)
{
while (nPos > 0)
{
CString strSubString=strTemp.Left(nPos);
strSubString.TrimLeft();
strSubString.TrimRight();
if ( !strSubString.IsEmpty())
{
strArray.Add(strSubString);
iCount++;
}
strTemp = strTarget.Right(strTemp.GetLength()-nPos-strTag.GetLength());
nPos =strTemp.Find(strTag);
}
strTemp.TrimRight();
strTemp.TrimLeft();
if ( !strTemp.IsEmpty() ) // added by LML 08.8.20
{
strArray.Add(strTemp);
iCount++;
}
}
else
{
strTemp.TrimRight();
strTemp.TrimLeft();
if ( !strTemp.IsEmpty() ) // added by LML 08.8.20
{
strArray.Add(strTemp);
iCount++;
}
}
}
catch(...)
{
return 0;
}
return iCount;
}
CString CDeviceUtil::GetDeviceDriveVersion(DWORDLONG dlVersion)
{
DWORDLONG dlBaseNumber = 0xFFFF;
CString strDriveVersion ;
DWORDLONG dlFormattemp = 0L;
CString strTemp;
for( int offset = 48; offset >= 0; offset -= 16 )
{
dlFormattemp = (dlVersion >> offset) & dlBaseNumber;
strTemp.Format("%d", dlFormattemp);
if( offset > 0)
strTemp += ".";
strDriveVersion += strTemp;
}
return strDriveVersion;
}
CString CDeviceUtil::GetDeviceDriveDay(FILETIME fileTime)
{
FILETIME fLocalFileTime;
SYSTEMTIME systemFileTime;
CString strLocalTime;
BOOL bRet ;
bRet = FileTimeToLocalFileTime(&fileTime, &fLocalFileTime);
if( bRet == TRUE )
{
bRet = FileTimeToSystemTime(&fLocalFileTime,&systemFileTime);
if( bRet == TRUE )
{
strLocalTime.Format("%d年:%d月:%d日:%d时",
systemFileTime.wYear,
systemFileTime.wMonth,
systemFileTime.wDay,
systemFileTime.wHour);
}
}
return strLocalTime;
}
CString CDeviceUtil::GetDeviceProperty(HDEVINFO hDevInfo, SP_DEVINFO_DATA &hDeviceInfoData, DWORD dwProperty)
{
CString strProperty;
DWORD dwData;
DWORD dwSize = 4096;
LPTSTR buffer = (char *)LocalAlloc(LPTR, dwSize);
while (!SetupDiGetDeviceRegistryProperty( hDevInfo,
&hDeviceInfoData,
dwProperty,
&dwData,
(PBYTE)buffer,
dwSize,
&dwSize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer != NULL)
LocalFree(buffer);
buffer = (char *)LocalAlloc(LPTR, dwSize*2);
}
else
{
break;
}
}
strProperty = buffer;
if (buffer != NULL)
LocalFree(buffer);
return strProperty;
}
BOOL CDeviceUtil::ChangeDeviceState(HDEVINFO hDevInfo, SP_DEVINFO_DATA hDeviceInfoData, DWORD dwState)
{
try{
BOOL bResult = FALSE;
SP_PROPCHANGE_PARAMS pcpParams;
pcpParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
pcpParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
pcpParams.StateChange = dwState;
pcpParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
pcpParams.HwProfile = 0;
bResult = SetupDiSetClassInstallParams( hDevInfo,
&hDeviceInfoData,
(PSP_CLASSINSTALL_HEADER)&pcpParams,
sizeof(pcpParams) );
if(bResult == FALSE)
return bResult;
bResult = SetupDiChangeState(hDevInfo, &hDeviceInfoData);
return bResult;
}
catch (...)
{
return FALSE;
}
}
int CDeviceUtil::EnumDeviceInfo(vector<DEVICE_INFO_ST>& vOutDeviceInfo)
{
SP_DEVINFO_DATA hDeviceInfoData;
SP_DRVINFO_DATA hDriveInfoData;
PSP_DRVINFO_DETAIL_DATA pDriveInfoDataDetial;
DWORD detailBuf[2048];
CString strDriverVersion;
CString strDriverDay;
if( vOutDeviceInfo.size() > 0 )
vOutDeviceInfo.clear();
HDEVINFO hDevInfo = SetupDiGetClassDevs( NULL, // All Classes
0,
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES );
if (hDevInfo == INVALID_HANDLE_VALUE)
return FALSE;
hDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
hDriveInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &hDeviceInfoData); i++)
{
DEVICE_INFO_ST stDeviceInfo;
stDeviceInfo.strClass = GetDeviceProperty(hDevInfo, hDeviceInfoData, SPDRP_CLASS); // 设备安装类名称 用来构建树 系统设备、显示卡
stDeviceInfo.strClassGuid = GetDeviceProperty(hDevInfo, hDeviceInfoData, SPDRP_CLASSGUID); // 设备安装类的GUID
stDeviceInfo.strDesc = GetDeviceProperty(hDevInfo, hDeviceInfoData, SPDRP_DEVICEDESC); // 设备描述
stDeviceInfo.strFName = GetDeviceProperty(hDevInfo,hDeviceInfoData, SPDRP_FRIENDLYNAME); // 友好(易读)名称
stDeviceInfo.strHID = GetDeviceProperty(hDevInfo, hDeviceInfoData, SPDRP_HARDWAREID); // 硬件设备ID
stDeviceInfo.strDriver = GetDeviceProperty(hDevInfo, hDeviceInfoData, SPDRP_DRIVER); // 返回驱动信息在注册表中的位置
stDeviceInfo.strManufacturer = GetDeviceProperty(hDevInfo, hDeviceInfoData, SPDRP_MFG); // 设备制造商
if( stDeviceInfo.strFName.IsEmpty() )
stDeviceInfo.strFName = stDeviceInfo.strDesc;
if( SetupDiBuildDriverInfoList( hDevInfo,
&hDeviceInfoData,
SPDIT_COMPATDRIVER ) == TRUE )
{
if( SetupDiEnumDriverInfo(hDevInfo, &hDeviceInfoData, SPDIT_COMPATDRIVER,
0, &hDriveInfoData) == TRUE )
{
stDeviceInfo.strDriverProvider = hDriveInfoData.ProviderName;
// 获得驱动日期
stDeviceInfo.strDriverDay = GetDeviceDriveDay(hDriveInfoData.DriverDate);
// 获得驱动的版本
stDeviceInfo.strDriverVersion = GetDeviceDriveVersion(hDriveInfoData.DriverVersion);
pDriveInfoDataDetial = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
pDriveInfoDataDetial->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
if( SetupDiGetDriverInfoDetail( hDevInfo, &hDeviceInfoData,
&hDriveInfoData, pDriveInfoDataDetial,
sizeof(detailBuf), NULL) == TRUE )
{
stDeviceInfo.strDriveInfFilePath = pDriveInfoDataDetial->InfFileName;
}
}
}
if( !stDeviceInfo.strHID.IsEmpty() )
vOutDeviceInfo.push_back(stDeviceInfo);
}
if( hDevInfo)
SetupDiDestroyDeviceInfoList(hDevInfo);
return vOutDeviceInfo.size();
}
BOOL CDeviceUtil::StopDevice(CString HID )
{
SP_DEVINFO_DATA hDeviceInfoData;
BOOL bRet = FALSE;
if( HID.IsEmpty() )
return bRet;
HDEVINFO hDevInfo = SetupDiGetClassDevs( NULL, // All Classes
0,
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (hDevInfo == INVALID_HANDLE_VALUE)
return NULL;
hDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &hDeviceInfoData); i++)
{
if( GetDeviceProperty(hDevInfo,hDeviceInfoData, SPDRP_HARDWAREID).CompareNoCase(HID) == 0 )
{
bRet = ChangeDeviceState(hDevInfo,hDeviceInfoData, DICS_DISABLE);
break;
}
}
if( hDevInfo)
SetupDiDestroyDeviceInfoList(hDevInfo);
return bRet;
}
BOOL CDeviceUtil::StartDevice(CString HID)
{
SP_DEVINFO_DATA hDeviceInfoData;
BOOL bRet = FALSE;
if( HID.IsEmpty() )
return bRet;
HDEVINFO hDevInfo = SetupDiGetClassDevs( NULL, // All Classes
0,
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES );
if (hDevInfo == INVALID_HANDLE_VALUE)
return NULL;
hDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &hDeviceInfoData); i++)
{
if( GetDeviceProperty(hDevInfo,hDeviceInfoData, SPDRP_HARDWAREID).CompareNoCase(HID) == 0 )
{
bRet = ChangeDeviceState(hDevInfo, hDeviceInfoData, DICS_ENABLE);
break;
}
}
if( hDevInfo)
SetupDiDestroyDeviceInfoList(hDevInfo);
return bRet;
}