📄 irclass.c
字号:
/*****************************************************************************
*
* Copyright (c) 1998-1999 Microsoft Corporation
*
* @doc
* @module IRCLASS.C
* @comm
*
*-----------------------------------------------------------------------------
*
* Date: 1/26/1998 (created)
*
* Contents: CoClassInstaller and Property Pages for IRSIR
*
*****************************************************************************/
#include <objbase.h>
#include <windows.h>
#include <tchar.h>
#include <cfgmgr32.h>
#include <setupapi.h>
#include <regstr.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stddef.h>
#include <stdarg.h>
#include "irclass.h"
//
// Instantiate device class GUIDs (we need infrared class GUID).
//
#include <initguid.h>
#include <devguid.h>
HANDLE ghDllInst = NULL;
TCHAR gszTitle[40];
TCHAR gszOutOfMemory[512];
TCHAR gszHelpFile[40];
TCHAR *BaudTable[] = {
TEXT("2400"),
TEXT("9600"),
TEXT("19200"),
TEXT("38400"),
TEXT("57600"),
TEXT("115200")
};
#define NUM_BAUD_RATES (sizeof(BaudTable)/sizeof(TCHAR*))
#define DEFAULT_MAX_CONNECT_RATE BaudTable[NUM_BAUD_RATES-1]
TCHAR szHelpFile[] = TEXT("INFRARED.HLP");
#define IDH_DEVICE_MAXIMUM_CONNECT_RATE 1201
#define IDH_DEVICE_COMMUNICATIONS_PORT 1202
const DWORD HelpIDs[] =
{
IDC_MAX_CONNECT, IDH_DEVICE_MAXIMUM_CONNECT_RATE,
IDC_RATE_TEXT, IDH_DEVICE_MAXIMUM_CONNECT_RATE,
IDC_PORT, IDH_DEVICE_COMMUNICATIONS_PORT,
IDC_SELECT_PORT_TEXT, IDH_DEVICE_COMMUNICATIONS_PORT,
IDC_PORT_TEXT, IDH_DEVICE_COMMUNICATIONS_PORT,
IDC_DEVICE_DESC, -1,
IDC_PORT_BOX, -1,
IDC_IRDA_ICON, -1,
0, 0
};
void InitStrings(HINSTANCE hInst)
/*++
Routine Description: InitStrings
Loads default strings from resource table
Arguments:
hInst - DLL Instance
Return Value: NONE
--*/
{
LoadString(hInst, IDS_TITLE, gszTitle, sizeof(gszTitle)/sizeof(gszTitle[0]));
LoadString(hInst, IDS_MEM_ERROR, gszOutOfMemory, sizeof(gszOutOfMemory)/sizeof(gszOutOfMemory[0]));
}
//==========================================================================
// Dll Entry Point
//==========================================================================
BOOL APIENTRY LibMain( HANDLE hDll, DWORD dwReason, LPVOID lpReserved )
{
switch ( dwReason )
{
case DLL_PROCESS_ATTACH:
ghDllInst = hDll;
InitStrings(ghDllInst);
DisableThreadLibraryCalls(ghDllInst);
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
default:
break;
}
return TRUE;
}
int MyLoadString(HINSTANCE hInst, UINT uID, LPTSTR *ppBuffer)
/*++
Routine Description: MyLoadString
LoadString wrapper which allocs properly sized buffer and loads
string from resource table
Arguments:
hInst - DLL Instanace
uID - Resource ID
ppBuffer - returns allocated buffer containing string.
Return Value:
ERROR_SUCCESS on success
ERROR_* on failure.
--*/
{
UINT Length = 8;
int LoadResult = 0;
HLOCAL hLocal = NULL;
do
{
Length <<= 1;
if (hLocal)
{
LocalFree(hLocal);
}
hLocal = LocalAlloc(LMEM_FIXED, Length*sizeof(TCHAR));
if (hLocal)
{
LoadResult = LoadString(hInst, uID, (LPTSTR)hLocal, Length);
}
else
{
MessageBox(GetFocus(), OUT_OF_MEMORY_MB);
}
} while ( (UINT)LoadResult==Length-1 && Length<4096 && hLocal);
if (LoadResult==0 && hLocal)
{
LocalFree(hLocal);
hLocal = NULL;
}
*ppBuffer = (LPTSTR)hLocal;
return LoadResult;
}
int MyMessageBox(HWND hWnd, UINT uText, UINT uCaption, UINT uType)
/*++
Routine Description: MyMessageBox
MessageBox wrapper which takes string resource IDs as parameters
Arguments:
hWnd - Parent window
uText - Message box body text ID
uCaption - Message box caption ID
uType - As in MessageBox()
Return Value:
Result of MessageBox call
--*/
{
LPTSTR szText, szCaption;
int Result = 0;
if (MyLoadString(ghDllInst, uText, &szText))
{
if (MyLoadString(ghDllInst, uCaption, &szCaption))
{
Result = MessageBox(hWnd, szText, szCaption, uType);
LocalFree(szCaption);
}
LocalFree(szText);
}
return Result;
}
LONG
MyRegQueryValueEx(
IN HKEY hKey,
IN LPCTSTR Value,
IN LPDWORD lpdwReserved,
IN LPDWORD lpdwType,
OUT LPBYTE *lpbpData,
OUT LPDWORD lpcbLength)
/*++
Routine Description:
RegQueryValueEx wrapper which automatically queries data size and
LocalAllocs a buffer.
Arguments:
hKey - handle of open key
Value - text name of value
lpdwReserved - Must be NULL
lpdwType - Returns type of value queried
lpbpData - Returns alloced buffer containing query data
lpcbLength - Returns length of data returned/size of buffer alloced.
Return Value:
ERROR_SUCCESS
ERROR_OUTOFMEMORY on failure to alloc buffer
result of RegQueryValueEx call
--*/
{
LONG Result;
*lpcbLength = 0;
Result = RegQueryValueEx(hKey,
Value,
lpdwReserved,
lpdwType,
NULL,
lpcbLength);
if (Result==ERROR_SUCCESS)
{
*lpbpData = LocalAlloc(LMEM_FIXED, *lpcbLength);
if (!*lpbpData)
{
Result = ERROR_OUTOFMEMORY;
}
else
{
Result = RegQueryValueEx(hKey,
Value,
lpdwReserved,
lpdwType,
*lpbpData,
lpcbLength);
}
}
return Result;
}
LPTSTR GetDIFString(IN DI_FUNCTION Func)
/*++
Routine Description:
Given a DI_FUNCTION value, returns a text representation.
Arguments:
Func - DI_FUNCTON value
Return Value:
Text string if value is known. Hex representation if not.
--*/
{
static TCHAR buf[32];
#define MakeCase(d) case d: return TEXT(#d)
switch (Func)
{
MakeCase(DIF_SELECTDEVICE);
MakeCase(DIF_INSTALLDEVICE);
MakeCase(DIF_ASSIGNRESOURCES);
MakeCase(DIF_PROPERTIES);
MakeCase(DIF_REMOVE);
MakeCase(DIF_FIRSTTIMESETUP);
MakeCase(DIF_FOUNDDEVICE);
MakeCase(DIF_SELECTCLASSDRIVERS);
MakeCase(DIF_VALIDATECLASSDRIVERS);
MakeCase(DIF_INSTALLCLASSDRIVERS);
MakeCase(DIF_CALCDISKSPACE);
MakeCase(DIF_DESTROYPRIVATEDATA);
MakeCase(DIF_VALIDATEDRIVER);
MakeCase(DIF_MOVEDEVICE);
MakeCase(DIF_DETECT);
MakeCase(DIF_INSTALLWIZARD);
MakeCase(DIF_DESTROYWIZARDDATA);
MakeCase(DIF_PROPERTYCHANGE);
MakeCase(DIF_ENABLECLASS);
MakeCase(DIF_DETECTVERIFY);
MakeCase(DIF_INSTALLDEVICEFILES);
MakeCase(DIF_UNREMOVE);
MakeCase(DIF_SELECTBESTCOMPATDRV);
MakeCase(DIF_ALLOW_INSTALL);
MakeCase(DIF_REGISTERDEVICE);
MakeCase(DIF_INSTALLINTERFACES);
MakeCase(DIF_DETECTCANCEL);
MakeCase(DIF_REGISTER_COINSTALLERS);
MakeCase(DIF_NEWDEVICEWIZARD_FINISHINSTALL);
default:
wsprintf(buf, TEXT("%x"), Func);
return buf;
}
}
void EnumValues(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData
)
/*++
Routine Description:
Function mainly for debugging purposes which will print to debugger
a list of values found in the device's Class/{GUID}/Instance key.
Arguments:
DeviceInfoSet - As passed in to IrSIRClassCoInstaller
DeviceInfoData - As passed in to IrSIRClassCoInstaller
Return Value:
NONE
--*/
{
HKEY hKey;
DWORD i, dwReserved = 0, dwType;
TCHAR Value[MAX_PATH];
TCHAR Data[MAX_PATH];
DWORD ValueLength = sizeof(Value);
DWORD DataLength = sizeof(Data);
TCHAR buf[100];
hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
DeviceInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DEV,
KEY_READ);
if (hKey == INVALID_HANDLE_VALUE)
{
#if DBG
OutputDebugString(TEXT("IrSIRCoClassInstaller:EnumValues:SetupDiOpenDevRegKey failed\n"));
#endif
return;
}
for (i=0,
dwType=REG_SZ;
RegEnumValue(hKey,
i,
Value,
&ValueLength,
NULL,
&dwType,
(LPBYTE)Data,
&DataLength
)==ERROR_SUCCESS;
i++, dwType==REG_SZ
)
{
#if DBG
if (dwType==REG_SZ)
{
wsprintf(buf, TEXT("Value(%d):%s Data:%s\n"), i, Value, Data);
OutputDebugString(buf);
}
#endif
ValueLength = sizeof(Value);
DataLength = sizeof(Data);
}
RegCloseKey(hKey);
}
LONG
EnumSerialDevices(
IN PPROPPAGEPARAMS pPropParams,
IN HWND hDlg,
OUT PULONG pNumFound
)
/*++
Routine Description:
Function which fills in the IDC_PORT control of the dialiog box with
valid COM names.
Arguments:
pPropParams - Context data
hDlg - Dialog box containing IDC_PORT
pNumFound - Count of COM names added to IDC_PORT
Return Value:
ERROR_SUCCESS or failure code
--*/
{
LRESULT lResult;
LONG Result = ERROR_SUCCESS, tmpResult;
HKEY hKey = INVALID_HANDLE_VALUE;
HKEY hkSerialComm = INVALID_HANDLE_VALUE;
TCHAR Buf[100];
LPTSTR CurrentPort = NULL;
DWORD dwLength, dwType, dwDisposition;
HDEVINFO hPorts;
SP_DEVINFO_DATA PortData;
*pNumFound = 0;
hKey = SetupDiOpenDevRegKey(pPropParams->DeviceInfoSet,
pPropParams->DeviceInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DRV,
KEY_ALL_ACCESS);
if (hKey == INVALID_HANDLE_VALUE)
{
#if DBG
OutputDebugString(TEXT("IrSIRCoClassInstaller:EnumSerial:SetupDiOpenDevRegKey failed\n"));
#endif
Result = GetLastError();
}
else
{
// Read the current port. If it's empty, we'll start with an empty value.
// Failure is ok.
(void)MyRegQueryValueEx(hKey,
TEXT("Port"),
NULL,
NULL,
(LPBYTE*)&CurrentPort,
&dwLength);
Result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
0,
KEY_ALL_ACCESS,
&hkSerialComm);
}
if (Result != ERROR_SUCCESS)
{
#if DBG
OutputDebugString(TEXT("IrSIRCoClassInstaller:RegOpenKeyEx on SERIALCOMM failed\n"));
#endif
}
else
{
DWORD i, dwReserved = 0, dwType;
TCHAR Value[MAX_PATH];
TCHAR Data[MAX_PATH];
DWORD ValueLength = sizeof(Value);
DWORD DataLength = sizeof(Data);
for (i=0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -